New platform API to simply ApiBackend and allow for custom backends on the fly

This commit is contained in:
l1npengtul
2024-12-11 14:46:13 +09:00
parent 096880eb7e
commit 0e2d000842
18 changed files with 215 additions and 197 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ use nokhwa_core::properties::{CameraProperties, CameraPropertyFlag, CameraProper
use nokhwa_core::{define_back_and_fourth_control, define_back_and_fourth_frame_format};
use nokhwa_core::error::{NokhwaError, NokhwaResult};
use nokhwa_core::frame_format::FrameFormat;
use nokhwa_core::types::{CameraFormat, CameraIndex, CameraInfo, FrameRate, Resolution};
use nokhwa_core::types::{CameraFormat, CameraIndex, CameraInformation, FrameRate, Resolution};
const NULL_FCC: &'static [u8; 4] = &[0x00, 0x00, 0x00, 0x00];
+7 -7
View File
@@ -225,7 +225,7 @@ mod internal {
use nokhwa_core::{
error::NokhwaError,
types::{
ApiBackend, CameraFormat, CameraIndex, CameraInfo,
ApiBackend, CameraFormat, CameraIndex, CameraInformation,
FrameFormat,
KnownCameraControlFlag, Resolution,
},
@@ -509,7 +509,7 @@ mod internal {
}
// fuck it, use deprecated APIs
pub fn query_avfoundation() -> Result<Vec<CameraInfo>, NokhwaError> {
pub fn query_avfoundation() -> Result<Vec<CameraInformation>, NokhwaError> {
Ok(AVCaptureDeviceDiscoverySession::new(vec![
AVCaptureDeviceType::UltraWide,
AVCaptureDeviceType::WideAngle,
@@ -520,7 +520,7 @@ mod internal {
.devices())
}
pub fn get_raw_device_info(index: CameraIndex, device: *mut Object) -> CameraInfo {
pub fn get_raw_device_info(index: CameraIndex, device: *mut Object) -> CameraInformation {
let name = nsstr_to_str(unsafe { msg_send![device, localizedName] });
let manufacturer = nsstr_to_str(unsafe { msg_send![device, manufacturer] });
let position: AVCaptureDevicePosition = unsafe { msg_send![device, position] };
@@ -533,7 +533,7 @@ mod internal {
);
let misc = nsstr_to_str(unsafe { msg_send![device, uniqueID] });
CameraInfo::new(name.as_ref(), &description, misc.as_ref(), index)
CameraInformation::new(name.as_ref(), &description, misc.as_ref(), index)
}
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
@@ -818,7 +818,7 @@ mod internal {
])
}
pub fn devices(&self) -> Vec<CameraInfo> {
pub fn devices(&self) -> Vec<CameraInformation> {
let device_ns_array: *mut Object = unsafe { msg_send![self.inner, devices] };
let objects_len: NSUInteger = unsafe { NSArray::count(device_ns_array) };
let mut devices = Vec::with_capacity(objects_len as usize);
@@ -836,7 +836,7 @@ mod internal {
pub struct AVCaptureDevice {
inner: *mut Object,
device: CameraInfo,
device: CameraInformation,
locked: bool,
}
@@ -890,7 +890,7 @@ mod internal {
})
}
pub fn info(&self) -> &CameraInfo {
pub fn info(&self) -> &CameraInformation {
&self.device
}
+7 -7
View File
@@ -31,7 +31,7 @@
pub mod wmf {
use nokhwa_core::error::NokhwaError;
use nokhwa_core::types::{
ApiBackend, CameraFormat, CameraIndex, CameraInfo,
ApiBackend, CameraFormat, CameraIndex, CameraInformation,
FrameFormat, KnownCameraControlFlag, Resolution,
};
use once_cell::sync::Lazy;
@@ -295,7 +295,7 @@ pub mod wmf {
fn activate_to_descriptors(
index: CameraIndex,
imf_activate: &IMFActivate,
) -> Result<CameraInfo, NokhwaError> {
) -> Result<CameraInformation, NokhwaError> {
let mut pwstr_name = PWSTR(&mut 0_u16);
let mut len_pwstrname = 0;
let mut pwstr_symlink = PWSTR(&mut 0_u16);
@@ -357,7 +357,7 @@ pub mod wmf {
})?
};
Ok(CameraInfo::new(
Ok(CameraInformation::new(
&name,
"MediaFoundation Camera",
&symlink,
@@ -365,7 +365,7 @@ pub mod wmf {
))
}
pub fn query_media_foundation_descriptors() -> Result<Vec<CameraInfo>, NokhwaError> {
pub fn query_media_foundation_descriptors() -> Result<Vec<CameraInformation>, NokhwaError> {
let mut device_list = vec![];
for (index, activate_ptr) in query_activate_pointers()?.into_iter().enumerate() {
@@ -421,7 +421,7 @@ pub mod wmf {
pub struct MediaFoundationDevice {
is_open: Cell<bool>,
device_specifier: CameraInfo,
device_specifier: CameraInformation,
device_format: CameraFormat,
source_reader: IMFSourceReader,
}
@@ -1226,7 +1226,7 @@ pub mod wmf {
pub mod wmf {
use nokhwa_core::error::NokhwaError;
use nokhwa_core::types::{
CameraFormat, CameraIndex, CameraInfo,
CameraFormat, CameraIndex, CameraInformation,
};
use std::borrow::Cow;
use nokhwa_core::properties::{CameraControl, ControlValue, KnownCameraControl};
@@ -1243,7 +1243,7 @@ pub mod wmf {
))
}
pub fn query_msmf() -> Result<Vec<CameraInfo>, NokhwaError> {
pub fn query_msmf() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::NotImplementedError(
"Not on windows".to_string(),
))
+27 -49
View File
@@ -1,21 +1,10 @@
use crate::error::{NokhwaError, NokhwaResult};
use crate::error::{NokhwaError};
use crate::frame_format::FrameFormat;
use crate::properties::{ControlId, ControlValue, Properties};
use crate::types::{CameraFormat, CameraIndex, FrameRate, Resolution};
use crate::types::{CameraFormat, FrameRate, Resolution};
use std::collections::HashMap;
use crate::frame_buffer::FrameBuffer;
use crate::stream::Stream;
pub trait Open {
fn open(index: CameraIndex) -> NokhwaResult<Self> where Self: Sized;
}
#[cfg(feature = "async")]
pub trait AsyncOpen: Sized {
async fn open_async(index: CameraIndex) -> NokhwaResult<Self>;
}
pub trait Setting {
fn enumerate_formats(&self) -> Result<Vec<CameraFormat>, NokhwaError>;
@@ -35,53 +24,42 @@ pub trait Setting {
) -> Result<(), NokhwaError>;
}
// #[cfg(feature = "async")]
// pub trait AsyncSetting {
// async fn set_format_async(&self, camera_format: CameraFormat) -> Result<(), NokhwaError>;
//
// async fn set_property_async(
// &mut self,
// property: &CameraPropertyId,
// value: CameraPropertyValue,
// ) -> Result<(), NokhwaError>;
//
// def_camera_props_async!(
// Brightness,
// Contrast,
// Hue,
// Saturation,
// Sharpness,
// Gamma,
// WhiteBalance,
// BacklightCompensation,
// Pan,
// Tilt,
// Zoom,
// Exposure,
// Iris,
// Focus,
// Facing,
// );
// }
#[cfg(feature = "async")]
pub trait AsyncSetting {
async fn enumerate_formats_async(&self) -> Result<Vec<CameraFormat>, NokhwaError>;
async fn enumerate_resolution_and_frame_rates_async(
&self,
frame_format: FrameFormat,
) -> Result<HashMap<Resolution, Vec<FrameRate>>, NokhwaError>;
async fn set_format_async(&self, camera_format: CameraFormat) -> Result<(), NokhwaError>;
async fn properties_async(&self) -> &Properties;
async fn set_property_async(
&mut self,
property: &ControlId,
value: ControlValue,
) -> Result<(), NokhwaError>;
}
pub trait Capture {
// Implementations MUST guarantee that there can only ever be one stream open at once.
fn open_stream(&mut self) -> Result<Stream, NokhwaError>;
// Implementations MUST be multi-close tolerant.
fn close_stream(&mut self) -> Result<(), NokhwaError>;
}
#[cfg(feature = "async")]
pub trait AsyncStream {
async fn open_stream(&mut self) -> Result<(), NokhwaError>;
async fn open_stream_async(&mut self) -> Result<Stream, NokhwaError>;
async fn await_frame(&mut self) -> Result<FrameBuffer, NokhwaError>;
async fn close_stream(&mut self) -> Result<(), NokhwaError>;
async fn close_stream_async(&mut self) -> Result<(), NokhwaError>;
}
pub trait CameraVtable: Setting + Capture {}
pub trait Camera: Open + CameraVtable {}
pub trait Camera: Setting + Capture {}
#[cfg(feature = "async")]
pub trait AsyncCapture: Camera + AsyncOpen + AsyncStream {}
pub trait AsyncCamera: Camera + AsyncSetting + AsyncStream {}
+4 -1
View File
@@ -16,6 +16,7 @@
use crate::{frame_format::FrameFormat, types::ApiBackend};
use std::fmt::{Debug};
use thiserror::Error;
use crate::platform::Backends;
pub type NokhwaResult<T> = Result<T, NokhwaError>;
@@ -56,9 +57,11 @@ pub enum NokhwaError {
#[error("Could not stop stream: {0}")]
StreamShutdownError(String),
#[error("This operation is not supported by backend {0}.")]
UnsupportedOperationError(ApiBackend),
UnsupportedOperationError(Backends),
#[error("This operation is not implemented yet: {0}")]
NotImplementedError(String),
#[error("Failed To Convert: {0}")]
ConversionError(String),
#[error("Permission denied by user.")]
PermissionDenied,
}
+1
View File
@@ -35,3 +35,4 @@ pub mod traits;
pub mod types;
pub mod utils;
pub mod stream;
mod platform;
+39
View File
@@ -0,0 +1,39 @@
use crate::camera::{AsyncCamera, Camera};
use crate::error::NokhwaResult;
use crate::types::{CameraIndex, CameraInformation};
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum Backends {
Video4Linux2,
WebWASM,
AVFoundation,
MicrosoftMediaFoundation,
Custom(&'static str)
}
pub trait PlatformTrait {
const PLATFORM: Backends;
type Camera: Camera;
fn block_on_permission(&mut self) -> NokhwaResult<()>;
fn check_permission_given(&mut self) -> bool;
fn query(&mut self) -> NokhwaResult<Vec<CameraInformation>>;
fn open(&mut self, index: &CameraIndex) -> NokhwaResult<Self::Camera>;
}
#[cfg(feature = "async")]
pub trait AsyncPlatformTrait {
const PLATFORM: Backends;
type AsyncCamera: AsyncCamera;
async fn await_permission(&mut self) -> NokhwaResult<()>;
async fn query_async(&mut self) -> NokhwaResult<Vec<CameraInformation>>;
async fn open_async (&mut self, index: &CameraIndex) -> NokhwaResult<Self::AsyncCamera>;
}
-10
View File
@@ -1,10 +0,0 @@
use crate::error::NokhwaError;
use crate::types::CameraInfo;
pub trait Query {
fn query() -> Result<Vec<CameraInfo>, NokhwaError>;
}
pub trait AsyncQuery {
async fn query() -> Result<Vec<CameraInfo>, NokhwaError>;
}
+27 -20
View File
@@ -1,6 +1,6 @@
use crate::error::{NokhwaError, NokhwaResult};
use crate::frame_buffer::FrameBuffer;
use flume::Receiver;
use flume::{Receiver, TryRecvError};
use std::sync::Arc;
pub trait StreamInnerTrait {
@@ -26,12 +26,17 @@ impl Stream {
// }
// }
pub fn poll_frame(&self) -> NokhwaResult<FrameBuffer> {
pub fn check_disconnected(&self) -> NokhwaResult<()> {
if self.inner.receiver().is_disconnected() {
return Err(NokhwaError::ReadFrameError(
"stream is disconnected!".to_string(),
));
))
}
Ok(())
}
pub fn poll_frame(&self) -> NokhwaResult<FrameBuffer> {
self.check_disconnected()?;
self.inner
.receiver()
@@ -39,34 +44,36 @@ impl Stream {
.map_err(|why| NokhwaError::ReadFrameError(why.to_string()))
}
pub fn try_poll_frame(&self) -> Option<NokhwaResult<FrameBuffer>> {
if self.inner.receiver().is_disconnected() {
return Some(Err(NokhwaError::ReadFrameError(
"stream is disconnected!".to_string(),
)));
}
pub fn try_poll_frame(&self) -> NokhwaResult<Option<FrameBuffer>> {
self.check_disconnected()?;
if self.inner.receiver().is_empty() {
return None;
return Ok(None);
}
Some(
self.inner
let possible_frame = self.inner
.receiver()
.try_recv()
.map_err(|why| NokhwaError::ReadFrameError(why.to_string())),
)
.try_recv();
match possible_frame {
Ok(f) => Ok(Some(f)),
Err(why) => {
match why {
TryRecvError::Empty => Ok(None),
TryRecvError::Disconnected => Err(NokhwaError::ReadFrameError(
"stream is disconnected!".to_string(),
))
}
}
}
}
#[cfg(feature = "async")]
pub async fn await_frame(&self) -> NokhwaResult<FrameBuffer> {
use futures::TryFutureExt;
if self.inner.receiver().is_disconnected() {
return Err(NokhwaError::ReadFrameError(
"stream is disconnected!".to_string(),
));
}
self.check_disconnected()?;
self.inner
.receiver()
+53 -53
View File
@@ -414,23 +414,23 @@ impl Display for CameraFormat {
/// `index` is a camera's index given to it by (usually) the OS usually in the order it is known to the system.
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct CameraInfo {
pub struct CameraInformation {
human_name: String,
description: String,
misc: String,
index: CameraIndex,
}
impl CameraInfo {
/// Create a new [`CameraInfo`].
impl CameraInformation {
/// Create a new [`CameraInformation`].
/// # JS-WASM
/// This is exported as a constructor for [`CameraInfo`].
/// This is exported as a constructor for [`CameraInformation`].
#[must_use]
// OK, i just checkeed back on this code. WTF was I on when I wrote `&(impl AsRef<str> + ?Sized)` ????
// I need to get on the same shit that my previous self was on, because holy shit that stuff is strong as FUCK!
// Finally fixed this insanity. Hopefully I didnt torment anyone by actually putting this in a stable release.
pub fn new(human_name: String, description: String, misc: String, index: CameraIndex) -> Self {
CameraInfo {
CameraInformation {
human_name,
description,
misc,
@@ -520,7 +520,7 @@ impl CameraInfo {
// }
}
impl Display for CameraInfo {
impl Display for CameraInformation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
@@ -540,50 +540,50 @@ impl Display for CameraInfo {
// Ok(())
// }
/// The list of known capture backends to the library. <br>
/// - `Auto` - Use automatic selection.
/// - `AVFoundation` - Uses `AVFoundation` on `MacOSX`
/// - `Video4Linux` - `Video4Linux2`, a linux specific backend.
/// - `UniversalVideoClass` - ***DEPRECATED*** Universal Video Class (please check [libuvc](https://github.com/libuvc/libuvc)). Platform agnostic, although on linux it needs `sudo` permissions or similar to use.
/// - `MediaFoundation` - Microsoft Media Foundation, Windows only,
/// - `OpenCv` - Uses `OpenCV` to capture. Platform agnostic.
/// - `GStreamer` - ***DEPRECATED*** Uses `GStreamer` RTP to capture. Platform agnostic.
/// - `Browser` - Uses browser APIs to capture from a webcam.
pub enum SelectableBackend {
Auto,
Custom(&'static str),
AVFoundation,
Video4Linux,
UniversalVideoClass,
MediaFoundation,
OpenCv,
GStreamer,
Browser,
}
/// The list of known capture backends to the library. <br>
/// - `AVFoundation` - Uses `AVFoundation` on `MacOSX`
/// - `Video4Linux` - `Video4Linux2`, a linux specific backend.
/// - `UniversalVideoClass` - ***DEPRECATED*** Universal Video Class (please check [libuvc](https://github.com/libuvc/libuvc)). Platform agnostic, although on linux it needs `sudo` permissions or similar to use.
/// - `MediaFoundation` - Microsoft Media Foundation, Windows only,
/// - `OpenCv` - Uses `OpenCV` to capture. Platform agnostic.
/// - `GStreamer` - ***DEPRECATED*** Uses `GStreamer` RTP to capture. Platform agnostic.
/// - `Browser` - Uses browser APIs to capture from a webcam.
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum ApiBackend {
Custom(&'static str),
AVFoundation,
Video4Linux,
UniversalVideoClass,
MediaFoundation,
OpenCv,
GStreamer,
Browser,
}
impl Display for ApiBackend {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}
// /// The list of known capture backends to the library. <br>
// /// - `Auto` - Use automatic selection.
// /// - `AVFoundation` - Uses `AVFoundation` on `MacOSX`
// /// - `Video4Linux` - `Video4Linux2`, a linux specific backend.
// /// - `UniversalVideoClass` - ***DEPRECATED*** Universal Video Class (please check [libuvc](https://github.com/libuvc/libuvc)). Platform agnostic, although on linux it needs `sudo` permissions or similar to use.
// /// - `MediaFoundation` - Microsoft Media Foundation, Windows only,
// /// - `OpenCv` - Uses `OpenCV` to capture. Platform agnostic.
// /// - `GStreamer` - ***DEPRECATED*** Uses `GStreamer` RTP to capture. Platform agnostic.
// /// - `Browser` - Uses browser APIs to capture from a webcam.
// pub enum SelectableBackend {
// Auto,
// Custom(&'static str),
// AVFoundation,
// Video4Linux,
// UniversalVideoClass,
// MediaFoundation,
// OpenCv,
// GStreamer,
// Browser,
// }
//
// /// The list of known capture backends to the library. <br>
// /// - `AVFoundation` - Uses `AVFoundation` on `MacOSX`
// /// - `Video4Linux` - `Video4Linux2`, a linux specific backend.
// /// - `UniversalVideoClass` - ***DEPRECATED*** Universal Video Class (please check [libuvc](https://github.com/libuvc/libuvc)). Platform agnostic, although on linux it needs `sudo` permissions or similar to use.
// /// - `MediaFoundation` - Microsoft Media Foundation, Windows only,
// /// - `OpenCv` - Uses `OpenCV` to capture. Platform agnostic.
// /// - `GStreamer` - ***DEPRECATED*** Uses `GStreamer` RTP to capture. Platform agnostic.
// /// - `Browser` - Uses browser APIs to capture from a webcam.
// #[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
// #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
// pub enum ApiBackend {
// Custom(&'static str),
// AVFoundation,
// Video4Linux,
// UniversalVideoClass,
// MediaFoundation,
// OpenCv,
// GStreamer,
// Browser,
// }
//
// impl Display for ApiBackend {
// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
// write!(f, "{self:?}")
// }
// }
+4 -4
View File
@@ -26,7 +26,7 @@ use nokhwa_core::{
pixel_format::RgbFormat,
traits::CaptureTrait,
types::{
ApiBackend, CameraFormat, CameraIndex, CameraInfo,
ApiBackend, CameraFormat, CameraIndex, CameraInformation,
FrameFormat, RequestedFormat, RequestedFormatType, Resolution,
},
};
@@ -52,7 +52,7 @@ pub struct AVFoundationCaptureDevice {
session: Option<AVCaptureSession>,
data_out: Option<AVCaptureVideoDataOutput>,
data_collect: Option<AVCaptureVideoCallback>,
info: CameraInfo,
info: CameraInformation,
buffer_name: CString,
format: CameraFormat,
frame_buffer_receiver: Arc<Receiver<(Vec<u8>, FrameFormat)>>,
@@ -127,7 +127,7 @@ impl CaptureTrait for AVFoundationCaptureDevice {
ApiBackend::AVFoundation
}
fn camera_info(&self) -> &CameraInfo {
fn camera_info(&self) -> &CameraInformation {
&self.info
}
@@ -401,7 +401,7 @@ impl CaptureTrait for AVFoundationCaptureDevice {
todo!()
}
fn camera_info(&self) -> &CameraInfo {
fn camera_info(&self) -> &CameraInformation {
todo!()
}
+4 -4
View File
@@ -11,7 +11,7 @@ use nokhwa_core::properties::{CameraControl, ControlValue, KnownCameraControl};
use nokhwa_core::error::NokhwaError;
use nokhwa_core::frame_format::FrameFormat;
use nokhwa_core::traits::{AsyncCaptureTrait, AsyncOpenCaptureTrait, CaptureTrait, OpenCaptureTrait};
use nokhwa_core::types::{ApiBackend, CameraFormat, CameraIndex, CameraInfo, FrameRate, Resolution};
use nokhwa_core::types::{ApiBackend, CameraFormat, CameraIndex, CameraInformation, FrameRate, Resolution};
async fn resolve_to<T: JsCast>(promise: Promise) -> Result<T, NokhwaError> {
let future = JsFuture::from(promise);
@@ -91,7 +91,7 @@ pub enum BrowserCameraControls {
pub struct BrowserCaptureDevice {
info: CameraInfo,
info: CameraInformation,
group_id: String,
device_id: String,
format: CameraFormat,
@@ -131,7 +131,7 @@ impl BrowserCaptureDevice {
let info = match device_info {
Some(v) => {
CameraInfo::new(&v.label(), v.kind(), &v.device_id(), index)
CameraInformation::new(&v.label(), v.kind(), &v.device_id(), index)
}
None => return Err(NokhwaError::OpenDeviceError(index.to_string(), "failed to find MediaDeviceInfo".to_string())),
};
@@ -297,7 +297,7 @@ impl CaptureTrait for BrowserCaptureDevice {
ApiBackend::Browser
}
fn camera_info(&self) -> &CameraInfo {
fn camera_info(&self) -> &CameraInformation {
&self.info
}
+5 -5
View File
@@ -21,7 +21,7 @@ use nokhwa_core::{
traits::CaptureTrait,
types::{
ApiBackend, CameraFormat, CameraIndex,
CameraInfo, FrameFormat, RequestedFormat,
CameraInformation, FrameFormat, RequestedFormat,
RequestedFormatType, Resolution,
},
};
@@ -35,13 +35,13 @@ use nokhwa_core::properties::{all_known_camera_controls, CameraControl, ControlV
/// # Quirks
/// - This does build on non-windows platforms, however when you do the backend will be empty and will return an error for any given operation.
/// - Please check [`nokhwa-bindings-windows`](https://github.com/l1npengtul/nokhwa/tree/senpai/nokhwa-bindings-windows) source code to see the internal raw interface.
/// - The symbolic link for the device is listed in the `misc` attribute of the [`CameraInfo`].
/// - The symbolic link for the device is listed in the `misc` attribute of the [`CameraInformation`].
/// - The names may contain invalid characters since they were converted from UTF16.
/// - When you call new or drop the struct, `initialize`/`de_initialize` will automatically be called.
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-msmf")))]
pub struct MediaFoundationCaptureDevice {
inner: MediaFoundationDevice,
info: CameraInfo,
info: CameraInformation,
}
impl MediaFoundationCaptureDevice {
@@ -51,7 +51,7 @@ impl MediaFoundationCaptureDevice {
pub fn new(index: &CameraIndex, camera_fmt: RequestedFormat) -> Result<Self, NokhwaError> {
let mut mf_device = MediaFoundationDevice::new(index.clone())?;
let info = CameraInfo::new(
let info = CameraInformation::new(
&mf_device.name(),
"MediaFoundation Camera Device",
&mf_device.symlink(),
@@ -114,7 +114,7 @@ impl CaptureTrait for MediaFoundationCaptureDevice {
ApiBackend::MediaFoundation
}
fn camera_info(&self) -> &CameraInfo {
fn camera_info(&self) -> &CameraInformation {
&self.info
}
+6 -6
View File
@@ -20,7 +20,7 @@ use nokhwa_core::{
error::NokhwaError,
traits::CaptureTrait,
types::{
ApiBackend, CameraFormat, CameraIndex, CameraInfo,
ApiBackend, CameraFormat, CameraIndex, CameraInformation,
FrameFormat, RequestedFormat, Resolution,
},
};
@@ -71,14 +71,14 @@ pub fn known_camera_control_to_video_capture_property(
/// - If the [`OpenCvCaptureDevice`] is initialized as a `IPCamera`, the [`CameraFormat`]'s `index` value will be [`u32::MAX`](std::u32::MAX) (4294967295).
/// - `OpenCV` does not support camera querying. Camera Name and Camera supported resolution/fps/fourcc is a [`UnsupportedOperationError`](NokhwaError::UnsupportedOperationError).
/// Note: [`resolution()`](crate::camera_traits::CaptureTrait::resolution()), [`frame_format()`](crate::camera_traits::CaptureTrait::frame_format()), and [`frame_rate()`](crate::camera_traits::CaptureTrait::frame_rate()) is not affected.
/// - [`CameraInfo`]'s human name will be "`OpenCV` Capture Device {location}"
/// - [`CameraInfo`]'s description will contain the Camera's Index or IP.
/// - [`CameraInformation`]'s human name will be "`OpenCV` Capture Device {location}"
/// - [`CameraInformation`]'s description will contain the Camera's Index or IP.
/// - The API Preference order is the native OS API (linux => `v4l2`, mac => `AVFoundation`, windows => `MSMF`) than [`CAP_AUTO`](https://docs.opencv.org/4.5.2/d4/d15/group__videoio__flags__base.html#gga023786be1ee68a9105bf2e48c700294da77ab1fe260fd182f8ec7655fab27a31d)
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-opencv")))]
pub struct OpenCvCaptureDevice {
camera_format: CameraFormat,
camera_location: CameraIndex,
camera_info: CameraInfo,
camera_info: CameraInformation,
api_preference: i32,
video_capture: VideoCapture,
}
@@ -124,7 +124,7 @@ impl OpenCvCaptureDevice {
set_properties(&mut video_capture, camera_format)?;
let camera_info = CameraInfo::new(
let camera_info = CameraInformation::new(
format!("OpenCV Capture Device {index}").as_str(),
index.to_string().as_str(),
"",
@@ -289,7 +289,7 @@ impl CaptureTrait for OpenCvCaptureDevice {
ApiBackend::OpenCv
}
fn camera_info(&self) -> &CameraInfo {
fn camera_info(&self) -> &CameraInformation {
&self.camera_info
}
+3 -3
View File
@@ -17,12 +17,12 @@ use nokhwa_core::{
error::{NokhwaError, NokhwaResult},
frame_format::FrameFormat,
properties::CameraProperties,
types::{CameraFormat, CameraIndex, CameraInfo, FrameRate, Resolution}
types::{CameraFormat, CameraIndex, CameraInformation, FrameRate, Resolution}
};
pub struct V4L2CaptureDevice {
device_inner: Arc<DeviceInner>,
camera_info: CameraInfo,
camera_info: CameraInformation,
format: Option<CameraFormat>,
properties: Option<CameraProperties>,
stream_running: bool,
@@ -32,7 +32,7 @@ impl Open for V4L2CaptureDevice {
fn open(index: CameraIndex) -> NokhwaResult<Self> {
let device = DeviceInner::new(index.as_index()? as usize).map_err(|why| NokhwaError::OpenDeviceError(index.to_string(), why.to_string()))?;
let caps = device.inner().query_caps().map_err(|why| NokhwaError::OpenDeviceError(index.to_string(), why.to_string()))?;
let camera_info = CameraInfo::new(caps.card, caps.bus, caps.driver, index);
let camera_info = CameraInformation::new(caps.card, caps.bus, caps.driver, index);
Ok(Self {
device_inner: Arc::new(device),
camera_info,
+2 -2
View File
@@ -23,7 +23,7 @@ use nokhwa_core::{
pixel_format::FormatDecoder,
traits::CaptureTrait,
types::{
ApiBackend, CameraFormat, CameraIndex, CameraInfo
ApiBackend, CameraFormat, CameraIndex, CameraInformation
, RequestedFormatType, Resolution,
},
};
@@ -58,7 +58,7 @@ impl CaptureTrait for Camera {
todo!()
}
fn camera_info(&self) -> &CameraInfo {
fn camera_info(&self) -> &CameraInformation {
todo!()
}
+20 -20
View File
@@ -16,7 +16,7 @@
use nokhwa_core::{
error::NokhwaError,
types::{ApiBackend, CameraInfo},
types::{ApiBackend, CameraInformation},
};
/// Gets the native [`ApiBackend`]
@@ -34,15 +34,15 @@ pub fn native_api_backend() -> Option<ApiBackend> {
/// Query the system for a list of available devices. Please refer to the API Backends that support `Query`) <br>
/// Usually the order goes Native -> UVC -> Gstreamer.
/// # Quirks
/// - `Media Foundation`: The symbolic link for the device is listed in the `misc` attribute of the [`CameraInfo`].
/// - `Media Foundation`: The symbolic link for the device is listed in the `misc` attribute of the [`CameraInformation`].
/// - `Media Foundation`: The names may contain invalid characters since they were converted from UTF16.
/// - `AVFoundation`: The ID of the device is stored in the `misc` attribute of the [`CameraInfo`].
/// - `AVFoundation`: The ID of the device is stored in the `misc` attribute of the [`CameraInformation`].
/// - `AVFoundation`: There is lots of miscellaneous info in the `desc` attribute.
/// - `WASM`: The `misc` field contains the device ID and group ID are seperated by a space (' ')
/// # Errors
/// If you use an unsupported API (check the README or crate root for more info), incompatible backend for current platform, incompatible platform, or insufficient permissions, etc
/// this will error.
pub fn query(api: ApiBackend) -> Result<Vec<CameraInfo>, NokhwaError> {
pub fn query(api: ApiBackend) -> Result<Vec<CameraInformation>, NokhwaError> {
match api {
ApiBackend::Auto => {
// determine platform
@@ -108,19 +108,19 @@ pub fn query(api: ApiBackend) -> Result<Vec<CameraInfo>, NokhwaError> {
// TODO: More
#[cfg(all(feature = "input-v4l", target_os = "linux"))]
fn query_v4l() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_v4l() -> Result<Vec<CameraInformation>, NokhwaError> {
nokhwa_bindings_linux::query()
}
#[cfg(any(not(feature = "input-v4l"), not(target_os = "linux")))]
fn query_v4l() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_v4l() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::UnsupportedOperationError(
ApiBackend::Video4Linux,
))
}
#[cfg(feature = "input-uvc")]
fn query_uvc() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_uvc() -> Result<Vec<CameraInformation>, NokhwaError> {
use crate::CameraIndex;
use uvc::Device;
@@ -168,7 +168,7 @@ fn query_uvc() -> Result<Vec<CameraInfo>, NokhwaError> {
))
.clone();
camera_info_vec.push(CameraInfo::new(
camera_info_vec.push(CameraInformation::new(
name.clone(),
usb_dev
.description
@@ -193,14 +193,14 @@ fn query_uvc() -> Result<Vec<CameraInfo>, NokhwaError> {
#[cfg(not(feature = "input-uvc"))]
#[allow(deprecated)]
fn query_uvc() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_uvc() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::UnsupportedOperationError(
ApiBackend::UniversalVideoClass,
))
}
#[cfg(feature = "input-gst")]
fn query_gstreamer() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_gstreamer() -> Result<Vec<CameraInformation>, NokhwaError> {
use gstreamer::{
prelude::{DeviceExt, DeviceMonitorExt, DeviceMonitorExtManual},
Caps, DeviceMonitor,
@@ -241,14 +241,14 @@ fn query_gstreamer() -> Result<Vec<CameraInfo>, NokhwaError> {
)));
}
let mut counter = 0;
let devices: Vec<CameraInfo> = device_monitor
let devices: Vec<CameraInformation> = device_monitor
.devices()
.iter_mut()
.map(|gst_dev| {
let name = DeviceExt::display_name(gst_dev);
let class = DeviceExt::device_class(gst_dev);
counter += 1;
CameraInfo::new(&name, &class, "", CameraIndex::Index(counter - 1))
CameraInformation::new(&name, &class, "", CameraIndex::Index(counter - 1))
})
.collect();
device_monitor.stop();
@@ -257,7 +257,7 @@ fn query_gstreamer() -> Result<Vec<CameraInfo>, NokhwaError> {
#[cfg(not(feature = "input-gst"))]
#[allow(deprecated)]
fn query_gstreamer() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_gstreamer() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::UnsupportedOperationError(
ApiBackend::GStreamer,
))
@@ -265,12 +265,12 @@ fn query_gstreamer() -> Result<Vec<CameraInfo>, NokhwaError> {
// please refer to https://docs.microsoft.com/en-us/windows/win32/medfound/enumerating-video-capture-devices
#[cfg(all(feature = "input-msmf", target_os = "windows"))]
fn query_msmf() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_msmf() -> Result<Vec<CameraInformation>, NokhwaError> {
nokhwa_bindings_windows::wmf::query_media_foundation_descriptors()
}
#[cfg(any(not(feature = "input-msmf"), not(target_os = "windows")))]
fn query_msmf() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_msmf() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::UnsupportedOperationError(
ApiBackend::MediaFoundation,
))
@@ -280,26 +280,26 @@ fn query_msmf() -> Result<Vec<CameraInfo>, NokhwaError> {
feature = "input-avfoundation",
any(target_os = "macos", target_os = "ios")
))]
fn query_avfoundation() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_avfoundation() -> Result<Vec<CameraInformation>, NokhwaError> {
use nokhwa_bindings_macos::query_avfoundation;
Ok(query_avfoundation()?
.into_iter()
.collect::<Vec<CameraInfo>>())
.collect::<Vec<CameraInformation>>())
}
#[cfg(not(all(
feature = "input-avfoundation",
any(target_os = "macos", target_os = "ios")
)))]
fn query_avfoundation() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_avfoundation() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::UnsupportedOperationError(
ApiBackend::AVFoundation,
))
}
#[cfg(feature = "input-jscam")]
fn query_wasm() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_wasm() -> Result<Vec<CameraInformation>, NokhwaError> {
use crate::js_camera::query_js_cameras;
use wasm_rs_async_executor::single_threaded::block_on;
@@ -307,6 +307,6 @@ fn query_wasm() -> Result<Vec<CameraInfo>, NokhwaError> {
}
#[cfg(not(feature = "input-jscam"))]
fn query_wasm() -> Result<Vec<CameraInfo>, NokhwaError> {
fn query_wasm() -> Result<Vec<CameraInformation>, NokhwaError> {
Err(NokhwaError::UnsupportedOperationError(ApiBackend::Browser))
}
+4 -4
View File
@@ -19,7 +19,7 @@ use nokhwa_core::{
frame_buffer::FrameBuffer,
error::NokhwaError,
types::{
ApiBackend, CameraFormat, CameraIndex, CameraInfo,
ApiBackend, CameraFormat, CameraIndex, CameraInformation,
FrameFormat, RequestedFormat, RequestedFormatType, Resolution,
},
};
@@ -60,7 +60,7 @@ pub struct CallbackCamera {
frame_callback: HeldCallbackType,
last_frame_captured: AtomicLock<FrameBuffer>,
die_bool: Arc<AtomicBool>,
current_camera: CameraInfo,
current_camera: CameraInformation,
handle: AtomicLock<Option<JoinHandle<()>>>,
}
@@ -160,8 +160,8 @@ impl CallbackCamera {
.set_backend(new_backend)
}
/// Gets the camera information such as Name and Index as a [`CameraInfo`].
pub fn info(&self) -> &CameraInfo {
/// Gets the camera information such as Name and Index as a [`CameraInformation`].
pub fn info(&self) -> &CameraInformation {
&self.current_camera
}