fix: 树莓派gstreamer pipeline报错

This commit is contained in:
grabbit 2025-04-05 15:53:22 +08:00
parent 8733afc987
commit 5ccaca3743
3 changed files with 68 additions and 30 deletions

View File

@ -128,9 +128,23 @@ fn create_demo_config() -> Config {
// 根据操作系统和设备类型自动选择合适的设备路径
let device = if is_raspberry_pi {
// 使用更简单的GStreamer pipeline尝试不同配置方式和格式
// 此pipeline尝试放宽限制避免严格的格式约束
// 尝试读取可用设备列表
match std::process::Command::new("v4l2-ctl").arg("--list-devices").output() {
Ok(output) => {
let devices = String::from_utf8_lossy(&output.stdout);
info!("检测到视频设备:\n{}", devices);
// 根据输出查找最可能是摄像头的设备
if devices.contains("/dev/video0") {
// 使用USB摄像头优先选择video1而不是video0可能会更稳定
"v4l2src device=/dev/video0 ! videoconvert ! appsink".to_string()
} else {
// 回退到默认配置
"v4l2src ! videoconvert ! appsink".to_string()
}
},
Err(_) => "v4l2src ! videoconvert ! appsink".to_string()
}
} else if std::env::consts::OS == "linux" {
"/dev/video0".to_string()
} else if std::env::consts::OS == "macos" {

View File

@ -95,12 +95,20 @@ impl CameraController {
.context("Failed to lock focus at infinity")?;
}
// 给相机一点时间初始化
info!("Waiting for camera to stabilize...");
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
// 尝试拍摄测试帧以确保相机设置正确
info!("Testing camera by capturing a test frame...");
let mut test_stream = match camera.start_streaming() {
Ok(stream) => stream,
// 使用已打开的相机实例直接捕获一帧,而不是创建新的流
match camera.capture_test_frame() {
Ok(_) => {
info!("Successfully captured test frame - camera is working correctly");
},
Err(e) => {
error!("Failed to start test stream: {}", e);
error!("Failed to capture test frame: {}", e);
// 检查是否在树莓派上以及是否已经使用GStreamer
let is_raspberry_pi = std::fs::read_to_string("/proc/cpuinfo")
@ -124,17 +132,6 @@ impl CameraController {
return Err(anyhow::anyhow!("Camera initialization failed: {}", e));
}
};
// 尝试捕获测试帧
match test_stream.capture_frame() {
Ok(_) => {
info!("Successfully captured test frame - camera is working correctly");
},
Err(e) => {
error!("Failed to capture test frame: {}", e);
return Err(anyhow::anyhow!("Camera initialization failed: Unable to capture test frame"));
}
}
self.camera = Some(camera);
@ -165,7 +162,7 @@ impl CameraController {
info!("Starting camera streaming with device: {}", self.settings.device);
let stream_result = camera.start_streaming();
let stream = match stream_result {
let mut stream = match stream_result {
Ok(stream) => stream,
Err(e) => {
error!("Failed to start camera streaming: {}", e);
@ -211,20 +208,25 @@ impl CameraController {
}
};
// 先保存一个测试帧副本
let test_frame = match stream.capture_frame() {
Ok(frame) => {
info!("Successfully captured test frame from stream - camera stream is working correctly");
Some(frame)
},
Err(e) => {
error!("Test frame capture failed: {}", e);
return Err(anyhow::anyhow!("Camera stream test failed: {}", e));
}
};
// 现在可以安全地移动stream的所有权
self.stream = Some(stream);
self.is_running = true;
// 尝试捕获一个测试帧,确保流工作正常
if let Some(mut stream_test) = self.stream.as_mut() {
match stream_test.capture_frame() {
Ok(_) => info!("Successfully captured test frame - camera stream is working correctly"),
Err(e) => {
error!("Test frame capture failed: {}", e);
self.is_running = false;
self.stream = None;
return Err(anyhow::anyhow!("Camera stream test failed: {}", e));
}
}
// 如果有测试帧,则处理它(如果需要)
if test_frame.is_some() {
debug!("Test frame was successfully captured");
}
// Clone necessary values for the capture task

View File

@ -435,6 +435,28 @@ impl OpenCVCamera {
Ok(())
}
/// 捕获一个测试帧(不创建单独的流)
pub fn capture_test_frame(&mut self) -> Result<core::Mat> {
info!("Capturing test frame from main camera instance");
if !self.capture.is_opened()? {
return Err(anyhow!("Camera is not open"));
}
let mut frame = core::Mat::default();
// 尝试捕获帧
if self.capture.read(&mut frame)? {
if frame.empty() {
return Err(anyhow!("Captured frame is empty"));
}
info!("Successfully captured test frame, size: {}x{}", frame.cols(), frame.rows());
Ok(frame)
} else {
Err(anyhow!("Failed to capture test frame"))
}
}
/// Check if the camera is currently streaming
pub fn is_streaming(&self) -> bool {
self.is_streaming