mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-20 00:08:52 +00:00
+7
-3
@@ -19,10 +19,10 @@ decoding = ["mozjpeg"]
|
||||
input-v4l = ["v4l", "v4l2-sys-mit"]
|
||||
input-msmf = ["nokhwa-bindings-windows"]
|
||||
input-avfoundation = ["nokhwa-bindings-macos"]
|
||||
input-uvc = ["uvc", "uvc/vendor", "ouroboros", "usb_enumeration"]
|
||||
input-uvc = ["uvc", "uvc/vendor", "ouroboros", "usb_enumeration", "lazy_static"]
|
||||
input-opencv = ["opencv", "opencv/clang-runtime"]
|
||||
input-ipcam = ["input-opencv"]
|
||||
input-gst = ["gstreamer", "glib", "gstreamer-app", "gstreamer-video", "regex"]
|
||||
input-gst = ["gstreamer", "glib", "gstreamer-app", "gstreamer-video", "regex", "parking_lot"]
|
||||
input-jscam = ["web-sys", "js-sys", "wasm-bindgen-futures", "wasm-bindgen", "wasm-rs-async-executor"]
|
||||
output-wgpu = ["wgpu"]
|
||||
output-wasm = ["input-jscam"]
|
||||
@@ -38,7 +38,7 @@ thiserror = "1.0.26"
|
||||
paste = "1.0.5"
|
||||
|
||||
[dependencies.flume]
|
||||
version = "0.10.8"
|
||||
version = "0.10.9"
|
||||
optional = true
|
||||
|
||||
[dependencies.image]
|
||||
@@ -153,6 +153,10 @@ optional = true
|
||||
version = "^0.11"
|
||||
optional = true
|
||||
|
||||
[dependencies.lazy_static]
|
||||
version = "^1.4"
|
||||
optional = true
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ use crate::{
|
||||
CaptureAPIBackend, CaptureBackendTrait, FrameFormat, KnownCameraControls, NokhwaError,
|
||||
Resolution,
|
||||
};
|
||||
use flume::Receiver;
|
||||
use glib::Quark;
|
||||
use gstreamer::{
|
||||
element_error,
|
||||
@@ -31,11 +30,11 @@ use gstreamer::{
|
||||
use gstreamer_app::{AppSink, AppSinkCallbacks};
|
||||
use gstreamer_video::{VideoFormat, VideoInfo};
|
||||
use image::{ImageBuffer, Rgb};
|
||||
use parking_lot::Mutex;
|
||||
use regex::Regex;
|
||||
use std::any::Any;
|
||||
use std::{borrow::Cow, collections::HashMap, str::FromStr};
|
||||
use std::{any::Any, borrow::Cow, collections::HashMap, str::FromStr, sync::Arc};
|
||||
|
||||
type PipelineGenRet = (Element, AppSink, Receiver<ImageBuffer<Rgb<u8>, Vec<u8>>>);
|
||||
type PipelineGenRet = (Element, AppSink, Arc<Mutex<ImageBuffer<Rgb<u8>, Vec<u8>>>>);
|
||||
|
||||
/// The backend struct that interfaces with `GStreamer`.
|
||||
/// To see what this does, please see [`CaptureBackendTrait`].
|
||||
@@ -48,7 +47,7 @@ pub struct GStreamerCaptureDevice<'a> {
|
||||
app_sink: AppSink,
|
||||
camera_format: CameraFormat,
|
||||
camera_info: CameraInfo<'a>,
|
||||
receiver: Receiver<ImageBuffer<Rgb<u8>, Vec<u8>>>,
|
||||
image_lock: Arc<Mutex<ImageBuffer<Rgb<u8>, Vec<u8>>>>,
|
||||
caps: Option<Caps>,
|
||||
}
|
||||
|
||||
@@ -131,7 +130,7 @@ impl<'a> GStreamerCaptureDevice<'a> {
|
||||
app_sink,
|
||||
camera_format,
|
||||
camera_info,
|
||||
receiver,
|
||||
image_lock: receiver,
|
||||
caps,
|
||||
})
|
||||
}
|
||||
@@ -175,7 +174,7 @@ impl<'a> CaptureBackendTrait for GStreamerCaptureDevice<'a> {
|
||||
generate_pipeline(new_fmt, self.camera_info.index_num()? as usize)?;
|
||||
self.pipeline = pipeline;
|
||||
self.app_sink = app_sink;
|
||||
self.receiver = receiver;
|
||||
self.image_lock = receiver;
|
||||
if reopen {
|
||||
self.open_stream()?;
|
||||
}
|
||||
@@ -549,15 +548,7 @@ impl<'a> CaptureBackendTrait for GStreamerCaptureDevice<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
match self.receiver.recv() {
|
||||
Ok(msg) => Ok(Cow::from(msg.to_vec())),
|
||||
Err(why) => {
|
||||
return Err(NokhwaError::ReadFrameError(format!(
|
||||
"Receiver Error: {}",
|
||||
why
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(Cow::from(self.image_lock.lock().to_vec()))
|
||||
}
|
||||
|
||||
fn stop_stream(&mut self) -> Result<(), NokhwaError> {
|
||||
@@ -659,7 +650,8 @@ fn generate_pipeline(fmt: CameraFormat, index: usize) -> Result<PipelineGenRet,
|
||||
|
||||
pipeline.set_state(State::Playing).unwrap();
|
||||
|
||||
let (sender, receiver) = flume::unbounded();
|
||||
let image_lock = Arc::new(Mutex::new(Default::default()));
|
||||
let img_lck_clone = image_lock.clone();
|
||||
|
||||
appsink.set_callbacks(
|
||||
AppSinkCallbacks::builder()
|
||||
@@ -825,13 +817,11 @@ fn generate_pipeline(fmt: CameraFormat, index: usize) -> Result<PipelineGenRet,
|
||||
}
|
||||
};
|
||||
|
||||
if sender.send(image_buffer).is_err() {
|
||||
return Err(FlowError::Error);
|
||||
}
|
||||
*img_lck_clone.lock() = image_buffer;
|
||||
|
||||
Ok(FlowSuccess::Ok)
|
||||
})
|
||||
.build(),
|
||||
);
|
||||
Ok((pipeline, appsink, receiver))
|
||||
Ok((pipeline, appsink, image_lock))
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ mod avfoundation;
|
||||
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-avfoundation")))]
|
||||
pub use avfoundation::AVFoundationCaptureDevice;
|
||||
// FIXME: Fix Lifetime Issues
|
||||
// #[cfg(feature = "input-uvc")]
|
||||
// mod uvc_backend;
|
||||
// #[cfg(feature = "input-uvc")]
|
||||
// #[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-uvc")))]
|
||||
// pub use uvc_backend::UVCCaptureDevice;
|
||||
#[cfg(feature = "input-uvc")]
|
||||
mod uvc_backend;
|
||||
#[cfg(feature = "input-uvc")]
|
||||
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-uvc")))]
|
||||
pub use uvc_backend::UVCCaptureDevice;
|
||||
#[cfg(feature = "input-gst")]
|
||||
mod gst_backend;
|
||||
#[cfg(feature = "input-gst")]
|
||||
|
||||
Reference in New Issue
Block a user