From d17fe466e96df0786fe38b0f8543a9776623e62c Mon Sep 17 00:00:00 2001 From: l1npengtul Date: Wed, 22 Jun 2022 18:00:22 +0900 Subject: [PATCH 1/5] add proper links to avfoundation #46 --- nokhwa-bindings-macos/src/lib.rs | 82 +++++++++++--------------------- 1 file changed, 27 insertions(+), 55 deletions(-) diff --git a/nokhwa-bindings-macos/src/lib.rs b/nokhwa-bindings-macos/src/lib.rs index 7523df1..76ce0a3 100644 --- a/nokhwa-bindings-macos/src/lib.rs +++ b/nokhwa-bindings-macos/src/lib.rs @@ -13,15 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#![cfg_attr( - any(target_os = "macos", target_os = "ios"), - link(name = "AVFoundation", kind = "framework") -)] -#![cfg_attr( - any(target_os = "macos", target_os = "ios"), - link(name = "CoreMedia", kind = "framework") -)] #![allow(clippy::not_unsafe_ptr_arg_deref)] #[cfg(any(target_os = "macos", target_os = "ios"))] @@ -60,14 +51,6 @@ pub enum AVFError { } #[cfg(any(target_os = "macos", target_os = "ios"))] -#[cfg_attr( - any(target_os = "macos", target_os = "ios"), - link(name = "CoreMedia", kind = "framework") -)] -#[cfg_attr( - any(target_os = "macos", target_os = "ios"), - link(name = "AVFoundation", kind = "framework") -)] #[allow(non_snake_case)] pub mod core_media { // all of this is stolen from bindgen @@ -115,20 +98,8 @@ pub mod core_media { pub type AVMediaType = NSString; - extern "C" { - pub static AVMediaTypeVideo: AVMediaType; - pub static AVMediaTypeAudio: AVMediaType; - pub static AVMediaTypeText: AVMediaType; - pub static AVMediaTypeClosedCaption: AVMediaType; - pub static AVMediaTypeSubtitle: AVMediaType; - pub static AVMediaTypeTimecode: AVMediaType; - pub static AVMediaTypeMetadata: AVMediaType; - pub static AVMediaTypeMuxed: AVMediaType; - pub static AVMediaTypeMetadataObject: AVMediaType; - pub static AVMediaTypeDepthData: AVMediaType; - } - #[allow(non_snake_case)] + #[link(name = "CoreMedia", kind = "framework")] extern "C" { pub fn CMVideoFormatDescriptionGetDimensions( videoDesc: CMFormatDescriptionRef, @@ -146,38 +117,16 @@ pub mod core_media { ) -> std::os::raw::c_int; pub fn CMSampleBufferGetDataBuffer(sbuf: CMSampleBufferRef) -> CMBlockBufferRef; - } - extern "C" { pub fn dispatch_queue_create( label: *const ::std::os::raw::c_char, attr: NSObject, ) -> NSObject; - } - extern "C" { pub fn dispatch_release(object: NSObject); - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct __CVBuffer { - _unused: [u8; 0], - } - pub type CVBufferRef = *mut __CVBuffer; - - #[allow(non_snake_case)] - extern "C" { pub fn CMSampleBufferGetImageBuffer(sbuf: CMSampleBufferRef) -> CVImageBufferRef; - } - pub type CVImageBufferRef = CVBufferRef; - pub type CVPixelBufferRef = CVImageBufferRef; - pub type CVPixelBufferLockFlags = u64; - pub type CVReturn = i32; - - #[allow(non_snake_case)] - extern "C" { pub fn CVPixelBufferLockBaseAddress( pixelBuffer: CVPixelBufferRef, lockFlags: CVPixelBufferLockFlags, @@ -193,14 +142,28 @@ pub mod core_media { pub fn CVPixelBufferGetBaseAddress( pixelBuffer: CVPixelBufferRef, ) -> *mut ::std::os::raw::c_void; + + pub fn CVPixelBufferGetPixelFormatType(pixelBuffer: CVPixelBufferRef) -> OSType; } - extern "C" { - pub static AVVideoCodecKey: NSString; + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct __CVBuffer { + _unused: [u8; 0], } + pub type CVBufferRef = *mut __CVBuffer; + + pub type CVImageBufferRef = CVBufferRef; + pub type CVPixelBufferRef = CVImageBufferRef; + pub type CVPixelBufferLockFlags = u64; + pub type CVReturn = i32; + pub type OSType = FourCharCode; pub type AVVideoCodecType = NSString; + + #[link(name = "AVFoundation", kind = "framework")] extern "C" { + pub static AVVideoCodecKey: NSString; pub static AVVideoCodecTypeHEVC: AVVideoCodecType; pub static AVVideoCodecTypeH264: AVVideoCodecType; pub static AVVideoCodecTypeJPEG: AVVideoCodecType; @@ -218,8 +181,17 @@ pub mod core_media { pub static AVVideoWidthKey: NSString; pub static AVVideoHeightKey: NSString; pub static AVVideoExpectedSourceFrameRateKey: NSString; - pub fn CVPixelBufferGetPixelFormatType(pixelBuffer: CVPixelBufferRef) -> OSType; + pub static AVMediaTypeVideo: AVMediaType; + pub static AVMediaTypeAudio: AVMediaType; + pub static AVMediaTypeText: AVMediaType; + pub static AVMediaTypeClosedCaption: AVMediaType; + pub static AVMediaTypeSubtitle: AVMediaType; + pub static AVMediaTypeTimecode: AVMediaType; + pub static AVMediaTypeMetadata: AVMediaType; + pub static AVMediaTypeMuxed: AVMediaType; + pub static AVMediaTypeMetadataObject: AVMediaType; + pub static AVMediaTypeDepthData: AVMediaType; } } From 4cc71ef37823e2387baf3e11ffe27909381552ff Mon Sep 17 00:00:00 2001 From: l1npengtul Date: Wed, 22 Jun 2022 18:24:22 +0900 Subject: [PATCH 2/5] camera trait adjustments --- src/backends/capture/avfoundation.rs | 44 +++++++++++++--------------- src/camera_traits.rs | 39 ++++++++++++------------ 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/backends/capture/avfoundation.rs b/src/backends/capture/avfoundation.rs index 34e4da7..37ea515 100644 --- a/src/backends/capture/avfoundation.rs +++ b/src/backends/capture/avfoundation.rs @@ -14,10 +14,7 @@ * limitations under the License. */ -use crate::{ - mjpeg_to_rgb, yuyv422_to_rgb, CameraControl, CameraFormat, CameraInfo, CaptureAPIBackend, - CaptureBackendTrait, FrameFormat, KnownCameraControl, NokhwaError, Resolution, -}; +use crate::{mjpeg_to_rgb, yuyv422_to_rgb, CameraControl, CameraFormat, CameraInfo, CaptureAPIBackend, CaptureBackendTrait, FrameFormat, KnownCameraControl, NokhwaError, Resolution, PixelFormat, ControlValueSetter}; use image::{ImageBuffer, Rgb}; use nokhwa_bindings_macos::avfoundation::{ query_avfoundation, AVCaptureDevice, AVCaptureDeviceInput, AVCaptureSession, @@ -97,6 +94,10 @@ impl AVFoundationCaptureDevice { } impl CaptureBackendTrait for AVFoundationCaptureDevice { + fn init(&mut self) -> Result { + todo!() + } + fn backend(&self) -> CaptureAPIBackend { CaptureAPIBackend::AVFoundation } @@ -105,6 +106,10 @@ impl CaptureBackendTrait for AVFoundationCaptureDevice { &self.info } + fn refresh_camera_format(&mut self) -> Result<(), NokhwaError> { + todo!() + } + fn camera_format(&self) -> CameraFormat { self.format } @@ -182,37 +187,23 @@ impl CaptureBackendTrait for AVFoundationCaptureDevice { self.set_camera_format(format) } - fn supported_camera_controls(&self) -> Result, NokhwaError> { - Err(NokhwaError::NotImplementedError( - "Not Implemented".to_string(), - )) - } - fn camera_control(&self, _: KnownCameraControl) -> Result { Err(NokhwaError::NotImplementedError( "Not Implemented".to_string(), )) } - fn set_camera_control(&mut self, _: CameraControl) -> Result<(), NokhwaError> { + fn camera_controls(&self) -> Result, NokhwaError> { Err(NokhwaError::NotImplementedError( "Not Implemented".to_string(), )) } - fn raw_supported_camera_controls(&self) -> Result>, NokhwaError> { - Err(NokhwaError::NotImplementedError( - "Not Implemented".to_string(), - )) - } - - fn raw_camera_control(&self, _: &dyn Any) -> Result, NokhwaError> { - Err(NokhwaError::NotImplementedError( - "Not Implemented".to_string(), - )) - } - - fn set_raw_camera_control(&mut self, _: &dyn Any, _: &dyn Any) -> Result<(), NokhwaError> { + fn set_camera_control( + &mut self, + _: KnownCameraControl, + _: ControlValueSetter, + ) -> Result<(), NokhwaError> { Err(NokhwaError::NotImplementedError( "Not Implemented".to_string(), )) @@ -268,6 +259,10 @@ impl CaptureBackendTrait for AVFoundationCaptureDevice { Ok(image_buf) } + fn frame_typed(&mut self) -> Result>, NokhwaError> { + todo!() + } + fn frame_raw(&mut self) -> Result, NokhwaError> { match &self.session { Some(session) => { @@ -295,6 +290,7 @@ impl CaptureBackendTrait for AVFoundationCaptureDevice { let data = match data.1 { AVFourCC::YUV2 => Cow::from(yuyv422_to_rgb(data.0.borrow(), false)), AVFourCC::MJPEG => Cow::from(mjpeg_to_rgb(data.0.borrow(), false)), + AVFourCC::GRAY8 => {} }; Ok(data) } diff --git a/src/camera_traits.rs b/src/camera_traits.rs index 3e8959c..8a8fc7f 100644 --- a/src/camera_traits.rs +++ b/src/camera_traits.rs @@ -20,7 +20,7 @@ use crate::{ utils::{ buf_mjpeg_to_rgb, buf_yuyv422_to_rgb, CameraFormat, CameraInfo, FrameFormat, Resolution, }, - Buffer, CameraControl, CaptureAPIBackend, KnownCameraControl, PixelFormat, + Buffer, CameraControl, CaptureAPIBackend, ControlValueSetter, KnownCameraControl, PixelFormat, }; use enum_dispatch::enum_dispatch; use image::{buffer::ConvertBuffer, ImageBuffer, RgbaImage}; @@ -82,23 +82,20 @@ pub trait CaptureBackendTrait { ) -> Result>, NokhwaError>; fn compatible_camera_formats(&mut self) -> Result, NokhwaError> { - let mut compatible_formats = vec![]; - frame_formats().map(|ff| { - if let Ok(mut fmts) = self.compatible_list_by_resolution(ff).map(|compatible| { - compatible + let compatible_formats = self + .compatible_fourcc()? + .into_iter() + .map(|ffmt| { + self.compatible_list_by_resolution(ffmt)? .into_iter() - .map(|(res, fps)| { - fps.into_iter().map(|rate| CameraFormat { - resolution: res, - format: ff, - frame_rate: rate, - }) + .map(|(resolution, fpses)| { + fpses + .into_iter() + .map(|fps| CameraFormat::new(resolution, ffmt, fps)) }) - .collect::>() - }) { - compatible_formats.append(&mut fmts) - } - }) + }) + .collect::>(); + Ok(compatible_formats) } /// A Vector of compatible [`FrameFormat`]s. Will only return 2 elements at most. @@ -227,9 +224,9 @@ pub trait CaptureBackendTrait { FrameFormat::GRAY8 => 1, }; if alpha { - return (resolution.width() * resolution.height() * (pxwidth + 1)) as usize; + return Ok((resolution.width() * resolution.height() * (pxwidth + 1)) as usize); } - (resolution.width() * resolution.height() * pxwidth) as usize + Ok((resolution.width() * resolution.height() * pxwidth) as usize) } /// Directly writes the current frame(RGB24) into said `buffer`. If `convert_rgba` is true, the buffer written will be written as an RGBA frame instead of a RGB frame. Returns the amount of bytes written on successful capture. @@ -243,9 +240,9 @@ pub trait CaptureBackendTrait { // FIXME: ?????? let cfmt = self.camera_format()?; let frame = self.frame_raw()?; - let data = match cfmt.format() { - FrameFormat::MJPEG => buf_mjpeg_to_rgb(&frame, buffer, write_alpha), - FrameFormat::YUYV => buf_yuyv422_to_rgb(&frame, buffer, write_alpha), + match cfmt.format() { + FrameFormat::MJPEG => buf_mjpeg_to_rgb(&frame, buffer, write_alpha)?, + FrameFormat::YUYV => buf_yuyv422_to_rgb(&frame, buffer, write_alpha)?, FrameFormat::GRAY8 => { let data = if write_alpha { frame From f3fb70d7f53607b12bf2170704a0ff8aea1628ca Mon Sep 17 00:00:00 2001 From: l1npengtul Date: Wed, 22 Jun 2022 18:26:35 +0900 Subject: [PATCH 3/5] adjust copyright notices --- examples/capture/src/main.rs | 2 +- examples/jscam/setup.sh | 2 +- examples/jscam/src/index.html | 2 +- examples/threaded-capture/src/main.rs | 2 +- make-npm.sh | 2 +- nokhwa-bindings-macos/build.rs | 2 +- nokhwa-bindings-macos/src/lib.rs | 2 +- nokhwa-bindings-windows/src/lib.rs | 2 +- src/backends/capture/avfoundation.rs | 12 +++++++++--- src/backends/capture/browser_backend.rs | 16 ++++++++++++++++ src/backends/capture/gst_backend.rs | 2 +- src/backends/capture/mod.rs | 2 +- src/backends/capture/msmf_backend.rs | 2 +- src/backends/capture/opencv_backend.rs | 2 +- src/backends/capture/uvc_backend.rs | 2 +- src/backends/capture/v4l2_backend.rs | 2 +- src/backends/mod.rs | 2 +- src/camera.rs | 2 +- src/camera_traits.rs | 2 +- src/error.rs | 2 +- src/init.rs | 2 +- src/js_camera.rs | 2 +- src/lib.rs | 2 +- src/network_camera.rs | 2 +- src/query.rs | 2 +- src/threaded.rs | 2 +- src/utils.rs | 2 +- 27 files changed, 50 insertions(+), 28 deletions(-) diff --git a/examples/capture/src/main.rs b/examples/capture/src/main.rs index fcf6328..00db445 100644 --- a/examples/capture/src/main.rs +++ b/examples/capture/src/main.rs @@ -1,5 +1,5 @@ /* - * Copyright 2021 l1npengtul / The Nokhwa Contributors + * Copyright 2022 l1npengtul / The Nokhwa Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/examples/jscam/setup.sh b/examples/jscam/setup.sh index 501ffa0..0178410 100644 --- a/examples/jscam/setup.sh +++ b/examples/jscam/setup.sh @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright 2021 l1npengtul / The Nokhwa Contributors +# Copyright 2022 l1npengtul / The Nokhwa Contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/examples/jscam/src/index.html b/examples/jscam/src/index.html index 0f6f3f0..e9a8a76 100644 --- a/examples/jscam/src/index.html +++ b/examples/jscam/src/index.html @@ -1,5 +1,5 @@