diff --git a/examples/camera_demo.rs b/examples/camera_demo.rs index 182f48e..ca7fdb2 100644 --- a/examples/camera_demo.rs +++ b/examples/camera_demo.rs @@ -128,9 +128,23 @@ fn create_demo_config() -> Config { // 根据操作系统和设备类型自动选择合适的设备路径 let device = if is_raspberry_pi { - // 使用更简单的GStreamer pipeline,尝试不同配置方式和格式 - // 此pipeline尝试放宽限制,避免严格的格式约束 - "v4l2src ! videoconvert ! appsink".to_string() + // 尝试读取可用设备列表 + 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" { diff --git a/src/camera/controller.rs b/src/camera/controller.rs index 4d1f0b9..42383c6 100644 --- a/src/camera/controller.rs +++ b/src/camera/controller.rs @@ -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 diff --git a/src/camera/opencv.rs b/src/camera/opencv.rs index 4dbfb98..da8acb9 100644 --- a/src/camera/opencv.rs +++ b/src/camera/opencv.rs @@ -435,6 +435,28 @@ impl OpenCVCamera { Ok(()) } + /// 捕获一个测试帧(不创建单独的流) + pub fn capture_test_frame(&mut self) -> Result { + 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