From f2cecfbbd46783597a196c7c37d0adf62fda306e Mon Sep 17 00:00:00 2001 From: grabbit Date: Sat, 5 Apr 2025 16:29:21 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=20=E6=A0=91=E8=8E=93=E6=B4=BEgstre?= =?UTF-8?q?amer=20pipeline=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/camera/opencv.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/camera/opencv.rs b/src/camera/opencv.rs index e30bc50..8e07f44 100644 --- a/src/camera/opencv.rs +++ b/src/camera/opencv.rs @@ -63,7 +63,13 @@ impl OpenCVCamera { // For Linux device files like /dev/video0 if let Some(num_str) = path_str.strip_prefix("/dev/video") { if let Ok(device_index) = num_str.parse::() { - return Ok(videoio::VideoCapture::new(device_index, videoio::CAP_ANY)?); + // 在Linux下使用GStreamer pipeline + let pipeline = format!( + "v4l2src device={} ! videoconvert ! video/x-raw,format=BGR ! appsink", + path_str + ); + info!("Using GStreamer pipeline: {}", pipeline); + return Ok(videoio::VideoCapture::from_file(&pipeline, videoio::CAP_GSTREAMER)?); } else { return Err(anyhow!("Invalid device number in path: {}", path_str)); } @@ -193,6 +199,30 @@ impl OpenCVCamera { return Err(anyhow!("Camera is not open")); } + #[cfg(target_os = "linux")] + { + // 在Linux下创建一个使用GStreamer的流 + if self.device.starts_with("/dev/video") { + let pipeline = format!( + "v4l2src device={} ! videoconvert ! video/x-raw,width={},height={},format=BGR,framerate={}/1 ! appsink", + self.device, self.width, self.height, 30 // 使用固定的30fps,或者从设置获取 + ); + info!("Starting stream with GStreamer pipeline: {}", pipeline); + let stream_capture = videoio::VideoCapture::from_file(&pipeline, videoio::CAP_GSTREAMER)?; + if !stream_capture.is_opened()? { + return Err(anyhow!("Failed to open GStreamer camera stream")); + } + + self.is_streaming = true; + info!("Started camera streaming with GStreamer"); + + return Ok(OpenCVCaptureStream { + capture: stream_capture, + }); + } + } + + // For non-Linux platforms or if GStreamer approach fails, use regular approach // Create a separate VideoCapture for the stream to avoid concurrent access issues let device = self.device.clone(); let mut stream_capture = Self::create_capture_from_path(&device)?;