From 17a87eafee2a77809dd3109dde8b920effbf8ef1 Mon Sep 17 00:00:00 2001 From: l1npengtul Date: Mon, 10 Oct 2022 12:21:42 +0900 Subject: [PATCH 1/3] experimental fix for MediaFoundation --- nokhwa-bindings-windows/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nokhwa-bindings-windows/src/lib.rs b/nokhwa-bindings-windows/src/lib.rs index 2862781..08c1f13 100644 --- a/nokhwa-bindings-windows/src/lib.rs +++ b/nokhwa-bindings-windows/src/lib.rs @@ -846,7 +846,7 @@ pub mod wmf { let mut receiver: MaybeUninit = MaybeUninit::uninit(); let mut ptr_receiver = receiver.as_mut_ptr(); if let Err(why) = self.source_reader.GetServiceForStream( - MEDIA_FOUNDATION_FIRST_VIDEO_STREAM, + MF_SOURCE_READER_MEDIASOURCE, &MF_MEDIASOURCE_SERVICE, &IMFMediaSource::IID, (&mut ptr_receiver as *mut *mut IMFMediaSource).cast::<*mut std::ffi::c_void>(), From 9ef8d8b25383e0dc858f5f2d860d30c4682187c3 Mon Sep 17 00:00:00 2001 From: Fabio Ferrari Date: Mon, 10 Oct 2022 13:41:01 -0300 Subject: [PATCH 2/3] control commands correction --- nokhwa-bindings-windows/Cargo.toml | 2 +- nokhwa-bindings-windows/src/lib.rs | 96 ++++++++++++++---------------- 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/nokhwa-bindings-windows/Cargo.toml b/nokhwa-bindings-windows/Cargo.toml index be44295..e3f3fff 100644 --- a/nokhwa-bindings-windows/Cargo.toml +++ b/nokhwa-bindings-windows/Cargo.toml @@ -18,4 +18,4 @@ lazy_static = "1.4.0" [target.'cfg(all(target_os = "windows", windows))'.dependencies.windows] version = "^0.28" -features = ["alloc", "Win32_Media_MediaFoundation", "Win32_System_Com", "Win32_Foundation", "Win32_Media_DirectShow"] \ No newline at end of file +features = ["alloc", "Win32_Media_MediaFoundation", "Win32_System_Com", "Win32_Foundation", "Win32_Media_DirectShow","Win32_Media_KernelStreaming"] \ No newline at end of file diff --git a/nokhwa-bindings-windows/src/lib.rs b/nokhwa-bindings-windows/src/lib.rs index 08c1f13..84b1ba3 100644 --- a/nokhwa-bindings-windows/src/lib.rs +++ b/nokhwa-bindings-windows/src/lib.rs @@ -383,6 +383,7 @@ pub mod wmf { Win32::{ Foundation::PWSTR, Media::{ + KernelStreaming::GUID_NULL, DirectShow::{ CameraControl_Exposure, CameraControl_Focus, CameraControl_Iris, CameraControl_Pan, CameraControl_Roll, CameraControl_Tilt, CameraControl_Zoom, @@ -398,7 +399,7 @@ pub mod wmf { MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, - MF_MEDIASOURCE_SERVICE, MF_MT_FRAME_RATE, MF_MT_FRAME_RATE_RANGE_MAX, + MF_MT_FRAME_RATE, MF_MT_FRAME_RATE_RANGE_MAX, MF_MT_FRAME_RATE_RANGE_MIN, MF_MT_FRAME_SIZE, MF_MT_SUBTYPE, MF_READWRITE_DISABLE_CONVERTERS, }, @@ -431,6 +432,7 @@ pub mod wmf { ); const MEDIA_FOUNDATION_FIRST_VIDEO_STREAM: u32 = 0xFFFF_FFFC; + const MF_SOURCE_READER_MEDIASOURCE: u32 = 0xFFFF_FFFF; const CAM_CTRL_AUTO: i32 = 0x0001; const CAM_CTRL_MANUAL: i32 = 0x0002; @@ -842,42 +844,39 @@ pub mod wmf { } pub fn control(&self, control: MediaFoundationControls) -> Result { - let media_source = unsafe { - let mut receiver: MaybeUninit = MaybeUninit::uninit(); - let mut ptr_receiver = receiver.as_mut_ptr(); + let camera_control = unsafe { + let mut receiver: MaybeUninit = MaybeUninit::uninit(); + let ptr_receiver = receiver.as_mut_ptr(); if let Err(why) = self.source_reader.GetServiceForStream( MF_SOURCE_READER_MEDIASOURCE, - &MF_MEDIASOURCE_SERVICE, - &IMFMediaSource::IID, - (&mut ptr_receiver as *mut *mut IMFMediaSource).cast::<*mut std::ffi::c_void>(), + &GUID_NULL, + &IAMCameraControl::IID, + (ptr_receiver as *mut IAMCameraControl).cast::<*mut std::ffi::c_void>(), ) { return Err(BindingError::GUIDSetError( - "MEDIA_FOUNDATION_FIRST_VIDEO_STREAM".to_string(), - "MF_MEDIASOURCE_SERVICE".to_string(), + "MF_SOURCE_READER_MEDIASOURCE".to_string(), + "IAMCameraControl".to_string(), why.to_string(), )); } receiver.assume_init() }; - - let camera_control = match media_source.cast::() { - Ok(cc) => cc, - Err(why) => { - return Err(BindingError::GUIDReadError( - "IAMCameraControl".to_string(), - why.to_string(), - )) - } - }; - - let video_proc_amp = match media_source.cast::() { - Ok(vpa) => vpa, - Err(why) => { - return Err(BindingError::GUIDReadError( + let video_proc_amp = unsafe { + let mut receiver: MaybeUninit = MaybeUninit::uninit(); + let ptr_receiver = receiver.as_mut_ptr(); + if let Err(why) = self.source_reader.GetServiceForStream( + MF_SOURCE_READER_MEDIASOURCE, + &GUID_NULL, + &IAMVideoProcAmp::IID, + (ptr_receiver as *mut IAMVideoProcAmp).cast::<*mut std::ffi::c_void>(), + ) { + return Err(BindingError::GUIDSetError( + "MF_SOURCE_READER_MEDIASOURCE".to_string(), "IAMVideoProcAmp".to_string(), why.to_string(), - )) + )); } + receiver.assume_init() }; let mut min = 0; @@ -1344,42 +1343,39 @@ pub mod wmf { } pub fn set_control(&mut self, control: MFControl) -> Result<(), BindingError> { - let media_source = unsafe { - let mut receiver: MaybeUninit = MaybeUninit::uninit(); - let mut ptr_receiver = receiver.as_mut_ptr(); + let camera_control = unsafe { + let mut receiver: MaybeUninit = MaybeUninit::uninit(); + let ptr_receiver = receiver.as_mut_ptr(); if let Err(why) = self.source_reader.GetServiceForStream( - MEDIA_FOUNDATION_FIRST_VIDEO_STREAM, - &MF_MEDIASOURCE_SERVICE, - &IMFMediaSource::IID, - (&mut ptr_receiver as *mut *mut IMFMediaSource).cast::<*mut std::ffi::c_void>(), + MF_SOURCE_READER_MEDIASOURCE, + &GUID_NULL, + &IAMCameraControl::IID, + (ptr_receiver as *mut IAMCameraControl).cast::<*mut std::ffi::c_void>(), ) { return Err(BindingError::GUIDSetError( - "MEDIA_FOUNDATION_FIRST_VIDEO_STREAM".to_string(), - "MF_MEDIASOURCE_SERVICE".to_string(), + "MF_SOURCE_READER_MEDIASOURCE".to_string(), + "IAMCameraControl".to_string(), why.to_string(), )); } receiver.assume_init() }; - - let camera_control = match media_source.cast::() { - Ok(cc) => cc, - Err(why) => { - return Err(BindingError::GUIDReadError( - "IAMCameraControl".to_string(), - why.to_string(), - )) - } - }; - - let video_proc_amp = match media_source.cast::() { - Ok(vpa) => vpa, - Err(why) => { - return Err(BindingError::GUIDReadError( + let video_proc_amp = unsafe { + let mut receiver: MaybeUninit = MaybeUninit::uninit(); + let ptr_receiver = receiver.as_mut_ptr(); + if let Err(why) = self.source_reader.GetServiceForStream( + MF_SOURCE_READER_MEDIASOURCE, + &GUID_NULL, + &IAMVideoProcAmp::IID, + (ptr_receiver as *mut IAMVideoProcAmp).cast::<*mut std::ffi::c_void>(), + ) { + return Err(BindingError::GUIDSetError( + "MF_SOURCE_READER_MEDIASOURCE".to_string(), "IAMVideoProcAmp".to_string(), why.to_string(), - )) + )); } + receiver.assume_init() }; let value = control.current; From d60fb877dee858186def662a76f550ed7a84bdba Mon Sep 17 00:00:00 2001 From: Fabio Ferrari Date: Mon, 10 Oct 2022 14:20:29 -0300 Subject: [PATCH 3/3] control need to be sent to the camera --- examples/setting/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/setting/src/main.rs b/examples/setting/src/main.rs index 4dc5f14..e9b9db5 100644 --- a/examples/setting/src/main.rs +++ b/examples/setting/src/main.rs @@ -5,4 +5,5 @@ fn main() { let known = camera.camera_controls_known_camera_controls().unwrap(); let mut control = *known.get(&KnownCameraControls::Gamma).unwrap(); control.set_value(101).unwrap(); + camera.set_camera_control(control).unwrap(); }