mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-04 10:37:26 +00:00
make control api simpler, because most platforms arnt v4l2
This commit is contained in:
Generated
+2
-20
@@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph"
|
||||
@@ -2516,6 +2516,7 @@ dependencies = [
|
||||
"futures",
|
||||
"image 0.25.0",
|
||||
"num-rational 0.4.2",
|
||||
"num-traits",
|
||||
"opencv 0.93.1",
|
||||
"paste",
|
||||
"rgb",
|
||||
@@ -2524,16 +2525,6 @@ dependencies = [
|
||||
"wgpu 23.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nokhwa-decoder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dcv-color-primitives",
|
||||
"mozjpeg",
|
||||
"nokhwa-core",
|
||||
"yuvutils-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nokhwactl"
|
||||
version = "0.10.0"
|
||||
@@ -4745,15 +4736,6 @@ version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
|
||||
|
||||
[[package]]
|
||||
name = "yuvutils-rs"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b30a62ce6c5fbf13dbf8d92e7cd805d74574a7f84d0e81462ca3cb8192be5de2"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ repository = "https://github.com/l1npengtul/nokhwa"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[workspace]
|
||||
members = ["nokhwa-bindings-macos", "nokhwa-bindings-windows", "nokhwa-bindings-linux", "nokhwa-core", "examples/*", "nokhwa-decoder"]
|
||||
members = ["nokhwa-bindings-macos", "nokhwa-bindings-windows", "nokhwa-bindings-linux", "nokhwa-core", "examples/*"]
|
||||
exclude = ["examples/jscam"]
|
||||
|
||||
[lib]
|
||||
|
||||
Generated
+9
-9
@@ -5,11 +5,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1730958623,
|
||||
"narHash": "sha256-JwQZIGSYnRNOgDDoIgqKITrPVil+RMWHsZH1eE1VGN0=",
|
||||
"lastModified": 1733097829,
|
||||
"narHash": "sha256-9hbb1rqGelllb4kVUCZ307G2k3/UhmA8PPGBoyuWaSw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "85f7e662eda4fa3a995556527c87b2524b691933",
|
||||
"rev": "2c15aa59df0017ca140d9ba302412298ab4bf22a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -62,11 +62,11 @@
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731292155,
|
||||
"narHash": "sha256-fYVoUUtSadbOrH0z0epVQDsStBDS/S/fAK//0ECQAAI=",
|
||||
"lastModified": 1733193245,
|
||||
"narHash": "sha256-nwvKoPi3S6XyliqBRuC+01QFF0k94ZOvnoZtbGi/ObM=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "7c4cd99ed7604b79e8cb721099ac99c66f656b3a",
|
||||
"rev": "3458f7f946ba61d1a1069aedcc17d7b7616f23cd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -246,7 +246,7 @@ mod internal {
|
||||
ffi::{c_float, c_void, CStr},
|
||||
sync::Arc,
|
||||
};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueDescription, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueDescription, ControlValue, KnownCameraControl};
|
||||
|
||||
const UTF8_ENCODING: usize = 4;
|
||||
type CGFloat = c_float;
|
||||
@@ -1492,7 +1492,7 @@ mod internal {
|
||||
pub fn set_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
let rc = self.get_controls()?;
|
||||
let controls = rc
|
||||
|
||||
@@ -46,7 +46,7 @@ pub mod wmf {
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueDescription, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueDescription, ControlValue, KnownCameraControl};
|
||||
use windows::Win32::Media::DirectShow::{CameraControl_Flags_Auto, CameraControl_Flags_Manual};
|
||||
use windows::Win32::Media::MediaFoundation::{
|
||||
IMFMediaType, MFCreateSample, MF_SOURCE_READER_FIRST_VIDEO_STREAM,
|
||||
@@ -849,7 +849,7 @@ pub mod wmf {
|
||||
pub fn set_control(
|
||||
&mut self,
|
||||
control: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
let current_value = self.control(control)?;
|
||||
|
||||
@@ -897,8 +897,8 @@ pub mod wmf {
|
||||
})?;
|
||||
|
||||
let ctrl_value = match value {
|
||||
ControlValueSetter::Integer(i) => i as i32,
|
||||
ControlValueSetter::Boolean(b) => i32::from(b),
|
||||
ControlValue::Integer(i) => i as i32,
|
||||
ControlValue::Boolean(b) => i32::from(b),
|
||||
v => {
|
||||
return Err(NokhwaError::StructureError {
|
||||
structure: format!("ControlValueSetter {}", v),
|
||||
@@ -1229,7 +1229,7 @@ pub mod wmf {
|
||||
CameraFormat, CameraIndex, CameraInfo,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValue, KnownCameraControl};
|
||||
|
||||
pub fn initialize_mf() -> Result<(), NokhwaError> {
|
||||
Err(NokhwaError::NotImplementedError(
|
||||
@@ -1287,7 +1287,7 @@ pub mod wmf {
|
||||
pub fn set_control(
|
||||
&mut self,
|
||||
_control: KnownCameraControl,
|
||||
_value: ControlValueSetter,
|
||||
_value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
Err(NokhwaError::NotImplementedError(
|
||||
"Only on Windows".to_string(),
|
||||
|
||||
@@ -25,6 +25,7 @@ thiserror = "2.0"
|
||||
bytes = "1.3"
|
||||
paste = "1.0"
|
||||
flume = "0.11"
|
||||
num-traits = "0.2"
|
||||
|
||||
[dependencies.num-rational]
|
||||
version = "0.4"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::error::{NokhwaError, NokhwaResult};
|
||||
use crate::frame_buffer::FrameBuffer;
|
||||
use crate::frame_format::FrameFormat;
|
||||
use crate::properties::{CameraProperties, CameraPropertyId, CameraPropertyValue};
|
||||
use crate::types::{CameraFormat, CameraIndex, FrameRate, Resolution};
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::{error::NokhwaError, frame_buffer::FrameBuffer, frame_format::FrameFormat};
|
||||
use image::{ImageBuffer, Pixel};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{Debug, Display},
|
||||
ops::{ControlFlow, Deref},
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::{
|
||||
types::{CameraFormat, FrameRate, Resolution},
|
||||
};
|
||||
use std::cmp::Ordering;
|
||||
use crate::ranges::ValidatableRange;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
|
||||
enum ClosestType {
|
||||
@@ -60,24 +61,29 @@ impl FormatRequest {
|
||||
frame_rate,
|
||||
frame_format,
|
||||
} => {
|
||||
let resolution_point = resolution.map(|x| x.preferred())?;
|
||||
|
||||
let frame_rate_point = frame_rate.map(|x| x.preferred())?;
|
||||
let resolution_point = resolution.map(|x| x.preferred());
|
||||
let frame_rate_point = frame_rate.map(|x| x.preferred());
|
||||
// lets calcuate distance in 3 dimensions (add both resolution and frame_rate together)
|
||||
|
||||
let mut distances: Vec<(f32, CameraFormat)> = list_of_formats
|
||||
let mut distances = list_of_formats
|
||||
.iter()
|
||||
.filter(|x| frame_format.contains(&x.format()))
|
||||
.map(|fmt| {
|
||||
(
|
||||
(fmt.frame_rate() - frame_rate_point).abs()
|
||||
+ fmt.resolution().distance_from(&resolution_point) as f32,
|
||||
fmt,
|
||||
)
|
||||
let frame_rate_distance = match frame_rate_point {
|
||||
Some(f_point) => (fmt.frame_rate() - f_point).approximate_float().unwrap_or(f32::INFINITY).abs(),
|
||||
None => 0_f32,
|
||||
};
|
||||
|
||||
let resolution_point_distance = match resolution_point {
|
||||
Some(res_pt) => fmt.resolution().distance_from(&res_pt) as f32,
|
||||
None => 0_f32,
|
||||
};
|
||||
|
||||
(frame_rate_distance + resolution_point_distance, fmt)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.collect::<Vec<(f32, &CameraFormat)>>();
|
||||
distances.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal));
|
||||
distances.into_iter().map(|x| x.1).collect()
|
||||
distances.into_iter().map(|x| x.1).copied().collect()
|
||||
}
|
||||
FormatRequest::HighestFrameRate {
|
||||
frame_rate,
|
||||
@@ -86,7 +92,7 @@ impl FormatRequest {
|
||||
let mut formats = list_of_formats
|
||||
.iter()
|
||||
.filter(|x| {
|
||||
frame_format.contains(&x.format()) && frame_rate.in_range(x.frame_rate())
|
||||
frame_format.contains(&x.format()) && frame_rate.validate(&x.frame_rate()).is_ok()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
formats.sort();
|
||||
@@ -99,7 +105,7 @@ impl FormatRequest {
|
||||
let mut formats = list_of_formats
|
||||
.iter()
|
||||
.filter(|x| {
|
||||
frame_format.contains(&x.format()) && resolution.in_range(x.resolution())
|
||||
frame_format.contains(&x.format()) && resolution.validate(&x.resolution()).is_ok()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
formats.sort();
|
||||
|
||||
+73
-644
@@ -1,676 +1,105 @@
|
||||
use crate::error::NokhwaError;
|
||||
use crate::ranges::{ArrayRange, KeyValue, Options, Range, RangeValidationFailure, Simple, ValidatableRange};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt::{Display, Formatter},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use crate::ranges::Range;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub struct ControlValidationFailure;
|
||||
|
||||
impl From<RangeValidationFailure> for ControlValidationFailure {
|
||||
fn from(_: RangeValidationFailure) -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum CameraPropertyId {
|
||||
Brightness,
|
||||
Contrast,
|
||||
Hue,
|
||||
Saturation,
|
||||
Sharpness,
|
||||
Gamma,
|
||||
WhiteBalance,
|
||||
BacklightCompensation,
|
||||
ISO,
|
||||
Pan,
|
||||
Tilt,
|
||||
Zoom,
|
||||
Exposure,
|
||||
Iris,
|
||||
pub enum ControlId {
|
||||
Focus,
|
||||
Facing,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl Display for CameraPropertyId {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Replace Controls API with Properties. (this one)
|
||||
/// Properties of a Camera.
|
||||
///
|
||||
/// If the property is not supported, it is `None`.
|
||||
/// Custom or platform-specific properties go into `other`
|
||||
pub struct CameraProperties {
|
||||
props: HashMap<CameraPropertyId, CameraPropertyDescriptor>,
|
||||
}
|
||||
|
||||
macro_rules! def_camera_props {
|
||||
( $($property:ident, )* ) => {
|
||||
paste::paste! {
|
||||
impl CameraProperties {
|
||||
$(
|
||||
pub fn [<$property:snake>] (&self) -> Option<&CameraPropertyDescriptor> {
|
||||
self.props.get(&CameraPropertyId::$property)
|
||||
}
|
||||
|
||||
pub fn [<set_ $property:snake>] (&mut self, value: CameraPropertyValue) -> Result<(), NokhwaError> {
|
||||
self.set_property(&CameraPropertyId::$property, value)
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
def_camera_props!(
|
||||
Brightness,
|
||||
Contrast,
|
||||
Hue,
|
||||
Saturation,
|
||||
Sharpness,
|
||||
Gamma,
|
||||
WhiteBalance,
|
||||
BacklightCompensation,
|
||||
ISO,
|
||||
Pan,
|
||||
Tilt,
|
||||
Zoom,
|
||||
Exposure,
|
||||
Iris,
|
||||
Focus,
|
||||
Facing,
|
||||
);
|
||||
|
||||
impl CameraProperties {
|
||||
pub fn property(&self, property: &CameraPropertyId) -> Option<&CameraPropertyDescriptor> {
|
||||
self.props.get(property)
|
||||
WhiteBalance,
|
||||
Zoom,
|
||||
Lighting,
|
||||
Other(u64)
|
||||
}
|
||||
|
||||
pub fn set_property(
|
||||
&mut self,
|
||||
property: &CameraPropertyId,
|
||||
value: CameraPropertyValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
match self.props.get_mut(property) {
|
||||
Some(prop) => {
|
||||
prop.set_value(value)?;
|
||||
Ok(())
|
||||
}
|
||||
None => Err(NokhwaError::SetPropertyError {
|
||||
property: property.to_string(),
|
||||
value: value.to_string(),
|
||||
error: String::from("Is null."),
|
||||
}),
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ControlGroup {
|
||||
ModeMultipleValue(ModeAndValuesControl),
|
||||
Simple(SimpleControl),
|
||||
}
|
||||
|
||||
/// Describes an individual property.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CameraPropertyDescriptor {
|
||||
flags: HashSet<CameraPropertyFlag>,
|
||||
mode: CameraPropertyMode,
|
||||
range: CameraPropertyRange,
|
||||
value: CameraPropertyValue,
|
||||
value_type: CameraPropertyValueType,
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ModeAndValuesControl {
|
||||
id: ControlId,
|
||||
mode_id: u64,
|
||||
mode_body: ControlBody,
|
||||
values: HashMap<String, SimpleControl>
|
||||
}
|
||||
|
||||
impl CameraPropertyDescriptor {
|
||||
pub fn new(
|
||||
flags: &[CameraPropertyFlag],
|
||||
mode: CameraPropertyMode,
|
||||
range: CameraPropertyRange,
|
||||
value: CameraPropertyValue,
|
||||
value_type: CameraPropertyValueType,
|
||||
) -> Result<Self, NokhwaError> {
|
||||
if flags.contains(&CameraPropertyFlag::ReadOnly)
|
||||
&& flags.contains(&CameraPropertyFlag::WriteOnly)
|
||||
{
|
||||
return Err(NokhwaError::StructureError {
|
||||
structure: "CameraPropertyDescriptor".to_string(),
|
||||
error: "conflicting flags".to_string(),
|
||||
});
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SimpleControl {
|
||||
id: u64,
|
||||
body: ControlBody,
|
||||
}
|
||||
|
||||
Ok(CameraPropertyDescriptor {
|
||||
flags: HashSet::from(flags),
|
||||
mode,
|
||||
range,
|
||||
value,
|
||||
value_type,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_read_only(&self) -> bool {
|
||||
self.flags.contains(&CameraPropertyFlag::ReadOnly)
|
||||
}
|
||||
|
||||
pub fn is_write_only(&self) -> bool {
|
||||
self.flags.contains(&CameraPropertyFlag::WriteOnly)
|
||||
}
|
||||
|
||||
pub fn is_disabled(&self) -> Result<(), NokhwaError> {
|
||||
if self.flags.contains(&CameraPropertyFlag::Disabled) {
|
||||
return Err(NokhwaError::StructureError {
|
||||
structure: "CameraPropertyDescriptor".to_string(),
|
||||
error: "Disabled".to_string(),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn flags(&self) -> Result<&HashSet<CameraPropertyFlag>, NokhwaError> {
|
||||
self.is_disabled()?;
|
||||
Ok(&self.flags)
|
||||
}
|
||||
|
||||
pub fn mode(&self) -> CameraPropertyMode {
|
||||
self.mode
|
||||
}
|
||||
|
||||
pub fn value_type(&self) -> CameraPropertyValueType {
|
||||
self.value_type
|
||||
}
|
||||
|
||||
pub fn range(&self) -> &CameraPropertyRange {
|
||||
&self.range
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &CameraPropertyValue {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, value: CameraPropertyValue) -> Result<(), NokhwaError> {
|
||||
self.range
|
||||
.check_value(&value)
|
||||
.map_err(|_| NokhwaError::SetPropertyError {
|
||||
property: "CameraPropertyValue".to_string(),
|
||||
value: value.to_string(),
|
||||
error: "Bad Type".to_string(),
|
||||
})?;
|
||||
self.value = value;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform Specific Camera Property. This is not useful, unless you are manually dealing with
|
||||
/// camera properties in `other`.
|
||||
#[derive(Clone, Debug, Hash, PartialOrd, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
|
||||
pub enum CameraCustomPropertyPlatformId {
|
||||
String(String),
|
||||
LongInteger(i128),
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ControlBody {
|
||||
pub typ: ControlType,
|
||||
pub class: ControlClass,
|
||||
pub flags: Vec<ControlFlags>,
|
||||
pub descriptor: ControlValueDescriptor,
|
||||
pub value: Option<ControlValue>
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
|
||||
pub enum CameraPropertyMode {
|
||||
///
|
||||
None,
|
||||
/// Automatically Set
|
||||
Automatic,
|
||||
/// Manually Set
|
||||
Manual,
|
||||
/// Continuously Set
|
||||
Continuous,
|
||||
pub enum ControlType {
|
||||
Button,
|
||||
Integer,
|
||||
Menu,
|
||||
IntegerMenu,
|
||||
BinaryMenu,
|
||||
Bitmask,
|
||||
String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
|
||||
pub enum CameraPropertyValueType {
|
||||
/// Relative
|
||||
Relative,
|
||||
/// Absolute
|
||||
Absolute,
|
||||
/// Unknown/Unused/Not Applicable
|
||||
None,
|
||||
pub enum ControlClass {
|
||||
User,
|
||||
Camera,
|
||||
Other(u64),
|
||||
}
|
||||
|
||||
/// The flags that a camera property may have.
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
|
||||
pub enum CameraPropertyFlag {
|
||||
/// The value may only be read from - any attempts to change the value will error.
|
||||
ReadOnly,
|
||||
/// The value can only be written to.
|
||||
WriteOnly,
|
||||
/// May just randomly poof out of existance.
|
||||
// FIXME: where the fuck did i find this? replace above doc with actual info.
|
||||
Volatile,
|
||||
/// While the platform/driver supports this feature,
|
||||
/// your camera does not. Setting will be ignored.
|
||||
pub enum ControlFlags {
|
||||
Disabled,
|
||||
Busy,
|
||||
ReadOnly,
|
||||
CascadingUpdates,
|
||||
Inactive,
|
||||
Slider,
|
||||
WriteOnly,
|
||||
ContinuousChange,
|
||||
ExecuteOnWrite,
|
||||
}
|
||||
|
||||
impl Display for CameraPropertyFlag {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
/// Ranges (Available Options of a Camera
|
||||
#[non_exhaustive]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CameraPropertyRange {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ControlValueDescriptor {
|
||||
Null,
|
||||
Boolean(Simple<bool>),
|
||||
Integer(Range<i64>),
|
||||
LongInteger(Range<i128>),
|
||||
Float(Range<f32>),
|
||||
Double(Range<f64>),
|
||||
String(Simple<String>),
|
||||
Array(ArrayRange<Vec<CameraPropertyValue>>),
|
||||
Enumeration(Options<CameraPropertyValue>),
|
||||
Binary(Simple<Vec<u8>>),
|
||||
Pair(Range<f32>, Range<f32>),
|
||||
Triple(
|
||||
Range<f32>,
|
||||
Range<f32>,
|
||||
Range<f32>,
|
||||
),
|
||||
Quadruple(
|
||||
Range<f32>,
|
||||
Range<f32>,
|
||||
Range<f32>,
|
||||
Range<f32>,
|
||||
),
|
||||
KeyValuePair(KeyValue<String, CameraPropertyValue>),
|
||||
}
|
||||
|
||||
impl CameraPropertyRange {
|
||||
pub fn check_value(&self, value: &CameraPropertyValue) -> Result<(), ControlValidationFailure> {
|
||||
match self {
|
||||
CameraPropertyRange::Null => {
|
||||
if let CameraPropertyValue::Null = value {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Boolean(chk_b) => {
|
||||
if let CameraPropertyValue::Boolean(b) = value {
|
||||
chk_b.validate(b)?
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Integer(chk_i) => {
|
||||
if let CameraPropertyValue::Integer(i) = value {
|
||||
chk_i.validate(i)?
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::LongInteger(chk_long) => {
|
||||
if let CameraPropertyValue::LongInteger(long) = value {
|
||||
chk_long.validate(long)?
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Float(chk_float) => {
|
||||
if let CameraPropertyValue::Float(fl) = value {
|
||||
chk_float.validate(fl)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Double(chk_double) => {
|
||||
if let CameraPropertyValue::Double(dl) = value {
|
||||
chk_double.validate(dl)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::String(chk_string) => {
|
||||
if let CameraPropertyValue::String(st) = value {
|
||||
chk_string.validate(st)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Array(chk_array) => {
|
||||
if let CameraPropertyValue::Array(arr) = value {
|
||||
chk_array.validate(arr)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Enumeration(chk_enum) => {
|
||||
if let CameraPropertyValue::EnumValue(en) = value {
|
||||
chk_enum.validate(en)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Binary(chk_bin) => {
|
||||
if let CameraPropertyValue::Binary(bin) = value {
|
||||
chk_bin.validate(bin)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Pair(chk_a, chk_b) => {
|
||||
if let CameraPropertyValue::Pair(a, b) = value {
|
||||
chk_a.validate(a)?;
|
||||
chk_b.validate(b)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Triple(chk_x, chk_y, chk_z) => {
|
||||
if let CameraPropertyValue::Triple(x, y, z) = value {
|
||||
chk_x.validate(x)?;
|
||||
chk_y.validate(y)?;
|
||||
chk_z.validate(z)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::Quadruple(chk_x, chk_y, chk_z, chk_w) => {
|
||||
if let CameraPropertyValue::Quadruple(x, y, z, w) = value {
|
||||
chk_x.validate(x)?;
|
||||
chk_y.validate(y)?;
|
||||
chk_z.validate(z)?;
|
||||
chk_w.validate(w)?;
|
||||
}
|
||||
}
|
||||
CameraPropertyRange::KeyValuePair(kv) => {
|
||||
if let CameraPropertyValue::KeyValue(st, va) = value {
|
||||
if let Some(vk) = kv.by_key(st) {
|
||||
if vk.is_same_type(va) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => return Err(ControlValidationFailure),
|
||||
}
|
||||
Err(ControlValidationFailure)
|
||||
}
|
||||
}
|
||||
|
||||
/// A possible value of
|
||||
///
|
||||
/// IMPORTANT: Make sure to call [`check_self()`] BEFORE any other operations!
|
||||
#[derive(Clone, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum CameraPropertyValue {
|
||||
Null,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
LongInteger(i128),
|
||||
Float(f32),
|
||||
Double(f64),
|
||||
Bitmap(i64),
|
||||
Float(Range<i64>),
|
||||
String(String),
|
||||
Array(Vec<CameraPropertyValue>),
|
||||
EnumValue(Box<CameraPropertyValue>),
|
||||
Binary(Vec<u8>),
|
||||
Pair(f32, f32),
|
||||
Triple(f32, f32, f32),
|
||||
Quadruple(f32, f32, f32, f32),
|
||||
KeyValue(String, Box<CameraPropertyValue>),
|
||||
Boolean(bool),
|
||||
Array(Vec<ControlValuePrimitive>),
|
||||
Map(HashMap<String, ControlValuePrimitive>)
|
||||
}
|
||||
|
||||
impl CameraPropertyValue {
|
||||
pub fn is_same_type(&self, other: &CameraPropertyValue) -> bool {
|
||||
match (self, other) {
|
||||
(CameraPropertyValue::Null, CameraPropertyValue::Null) => true,
|
||||
(CameraPropertyValue::Boolean(_), CameraPropertyValue::Boolean(_)) => true,
|
||||
(CameraPropertyValue::Integer(_), CameraPropertyValue::Integer(_)) => true,
|
||||
(CameraPropertyValue::LongInteger(_), CameraPropertyValue::LongInteger(_)) => true,
|
||||
(CameraPropertyValue::Float(_), CameraPropertyValue::Float(_)) => true,
|
||||
(CameraPropertyValue::Double(_), CameraPropertyValue::Double(_)) => true,
|
||||
(CameraPropertyValue::String(_), CameraPropertyValue::String(_)) => true,
|
||||
(CameraPropertyValue::Array(_), CameraPropertyValue::Array(_)) => true,
|
||||
(CameraPropertyValue::EnumValue(_), CameraPropertyValue::EnumValue(_)) => true,
|
||||
(CameraPropertyValue::Binary(_), CameraPropertyValue::Binary(_)) => true,
|
||||
(CameraPropertyValue::Pair(..), CameraPropertyValue::Pair(..)) => true,
|
||||
(CameraPropertyValue::Triple(..), CameraPropertyValue::Triple(..)) => true,
|
||||
(CameraPropertyValue::Quadruple(..), CameraPropertyValue::Quadruple(..)) => true,
|
||||
(CameraPropertyValue::KeyValue(..), CameraPropertyValue::KeyValue(..)) => true,
|
||||
(_, _) => false,
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub enum ControlValuePrimitive {
|
||||
Null,
|
||||
Integer(i64),
|
||||
Bitmap(i64),
|
||||
Float(f64),
|
||||
String(String),
|
||||
Boolean(bool),
|
||||
}
|
||||
|
||||
impl PartialEq for CameraPropertyValue {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match &self {
|
||||
CameraPropertyValue::Null => {
|
||||
if let CameraPropertyValue::Null = other {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Boolean(b) => {
|
||||
if let CameraPropertyValue::Boolean(ob) = other {
|
||||
return b == ob;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Integer(i) => {
|
||||
if let CameraPropertyValue::Integer(oi) = other {
|
||||
return i == oi;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::LongInteger(i) => {
|
||||
if let CameraPropertyValue::LongInteger(oi) = other {
|
||||
return i == oi;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Float(f) => {
|
||||
if let CameraPropertyValue::Float(of) = other {
|
||||
return f == of;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Double(d) => {
|
||||
if let CameraPropertyValue::Double(od) = other {
|
||||
return d == od;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::String(s) => {
|
||||
if let CameraPropertyValue::String(os) = other {
|
||||
return s == os;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Array(a) => {
|
||||
if let CameraPropertyValue::Array(oa) = other {
|
||||
return a == oa;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::EnumValue(ev) => {
|
||||
if let CameraPropertyValue::EnumValue(oev) = other {
|
||||
return ev == oev;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Binary(bin) => {
|
||||
if let CameraPropertyValue::Binary(obin) = other {
|
||||
return bin == obin;
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Pair(a, b) => {
|
||||
if let CameraPropertyValue::Pair(oa, ob) = other {
|
||||
return (a == oa) && (b == ob);
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Triple(x, y, z) => {
|
||||
if let CameraPropertyValue::Triple(ox, oy, oz) = other {
|
||||
return (x == ox) && (y == oy) && (z == oz);
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::Quadruple(x, y, z, w) => {
|
||||
if let CameraPropertyValue::Quadruple(ox, oy, oz, ow) = other {
|
||||
return (x == ox) && (y == oy) && (z == oz) && (w == ow);
|
||||
}
|
||||
}
|
||||
CameraPropertyValue::KeyValue(k, v) => {
|
||||
if let CameraPropertyValue::KeyValue(ok, ov) = other {
|
||||
return (k == ok) && (v == ov);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for CameraPropertyValue {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match self {
|
||||
CameraPropertyValue::Null => match other {
|
||||
CameraPropertyValue::Null => Some(Ordering::Greater),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::Boolean(b) => match other {
|
||||
CameraPropertyValue::Null => Some(Ordering::Greater),
|
||||
CameraPropertyValue::Boolean(o) => {
|
||||
if o == b {
|
||||
Some(Ordering::Equal)
|
||||
} else if o {
|
||||
Some(Ordering::Less)
|
||||
} else {
|
||||
Some(Ordering::Greater)
|
||||
}
|
||||
}
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::Integer(int) => match other {
|
||||
CameraPropertyValue::Null | CameraPropertyValue::Boolean(_) => {
|
||||
Some(Ordering::Greater)
|
||||
}
|
||||
CameraPropertyValue::Integer(oth) => Some(int.cmp(oth)),
|
||||
CameraPropertyValue::LongInteger(li) => {
|
||||
let long = match i64::try_from(li) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return None,
|
||||
};
|
||||
Some(int.cmp(&long))
|
||||
}
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::LongInteger(long) => match other {
|
||||
CameraPropertyValue::Null | CameraPropertyValue::Boolean(_) => {
|
||||
Some(Ordering::Greater)
|
||||
}
|
||||
CameraPropertyValue::Integer(oth) => Some(long.cmp(&(i128::from(oth)))),
|
||||
CameraPropertyValue::LongInteger(o) => Some(long.cmp(o)),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::Float(fl) => match other {
|
||||
CameraPropertyValue::Null
|
||||
| CameraPropertyValue::Boolean(_)
|
||||
| CameraPropertyValue::Integer(_)
|
||||
| CameraPropertyValue::LongInteger(_) => Some(Ordering::Greater),
|
||||
CameraPropertyValue::Float(f) => fl.partial_cmp(f),
|
||||
CameraPropertyValue::Double(d) => f64::from(fl).partial_cmp(d),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::Double(d) => match other {
|
||||
CameraPropertyValue::Null
|
||||
| CameraPropertyValue::Boolean(_)
|
||||
| CameraPropertyValue::Integer(_)
|
||||
| CameraPropertyValue::LongInteger(_) => Some(Ordering::Greater),
|
||||
CameraPropertyValue::Float(f) => d.partial_cmp(&(f64::from(f))),
|
||||
CameraPropertyValue::Double(o) => d.partial_cmp(o),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::String(s) => match other {
|
||||
CameraPropertyValue::Null
|
||||
| CameraPropertyValue::Boolean(_)
|
||||
| CameraPropertyValue::Integer(_)
|
||||
| CameraPropertyValue::LongInteger(_)
|
||||
| CameraPropertyValue::Float(_)
|
||||
| CameraPropertyValue::Double(_) => Some(Ordering::Greater),
|
||||
CameraPropertyValue::String(os) => s.partial_cmp(os),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::Array(a) => match other {
|
||||
CameraPropertyValue::Null
|
||||
| CameraPropertyValue::Boolean(_)
|
||||
| CameraPropertyValue::Integer(_)
|
||||
| CameraPropertyValue::LongInteger(_)
|
||||
| CameraPropertyValue::Float(_)
|
||||
| CameraPropertyValue::Double(_)
|
||||
| CameraPropertyValue::String(_) => Some(Ordering::Greater),
|
||||
CameraPropertyValue::Array(oa) => a.partial_cmp(oa),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::EnumValue(_) => match other {
|
||||
CameraPropertyValue::Null
|
||||
| CameraPropertyValue::Boolean(_)
|
||||
| CameraPropertyValue::Integer(_)
|
||||
| CameraPropertyValue::LongInteger(_)
|
||||
| CameraPropertyValue::Float(_)
|
||||
| CameraPropertyValue::Double(_)
|
||||
| CameraPropertyValue::String(_)
|
||||
| CameraPropertyValue::Array(_) => Some(Ordering::Greater),
|
||||
CameraPropertyValue::EnumValue(_) => Some(Ordering::Equal),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
CameraPropertyValue::Binary(b) => match other {
|
||||
CameraPropertyValue::Null
|
||||
| CameraPropertyValue::Boolean(_)
|
||||
| CameraPropertyValue::Integer(_)
|
||||
| CameraPropertyValue::LongInteger(_)
|
||||
| CameraPropertyValue::Float(_)
|
||||
| CameraPropertyValue::Double(_)
|
||||
| CameraPropertyValue::String(_)
|
||||
| CameraPropertyValue::Array(_)
|
||||
| CameraPropertyValue::EnumValue(_) => Some(Ordering::Greater),
|
||||
CameraPropertyValue::Binary(ob) => b.partial_cmp(ob),
|
||||
_ => Some(Ordering::Less),
|
||||
},
|
||||
// FIXME: implement this lole
|
||||
CameraPropertyValue::Pair(_, _) => {
|
||||
// match other {
|
||||
// CameraPropertyValue::Null |
|
||||
// CameraPropertyValue::Boolean(_) |
|
||||
// CameraPropertyValue::Integer(_) |
|
||||
// CameraPropertyValue::LongInteger(_) |
|
||||
// CameraPropertyValue::Float(_) |
|
||||
// CameraPropertyValue::Double(_) |
|
||||
// CameraPropertyValue::String(_) |
|
||||
// CameraPropertyValue::Array(_) |
|
||||
// CameraPropertyValue::EnumValue(_) |
|
||||
// CameraPropertyValue::Binary(_) => Some(Ordering::Greater),
|
||||
// CameraPropertyValue::Pair(a, b) => {
|
||||
// match a.partial_cmp(b) {
|
||||
// Some(_) => {}
|
||||
// None => {}
|
||||
// }
|
||||
// }
|
||||
// _ => Some(Ordering::Less)
|
||||
// }
|
||||
Some(Ordering::Equal)
|
||||
}
|
||||
CameraPropertyValue::Triple(_, _, _) => Some(Ordering::Equal),
|
||||
CameraPropertyValue::Quadruple(_, _, _, _) => Some(Ordering::Equal),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for CameraPropertyValue {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_back_and_fourth_control {
|
||||
($id_type:ty, { $( $control:expr [ $mode:expr, $value_type:expr, $value:expr ] => $control_id:expr, )* }, $id_to_str:expr, $str_to_id:expr) => {
|
||||
pub struct ControlIntermediate {
|
||||
pub mode: Option<$id_type>,
|
||||
pub value_type: Option<$id_type>,
|
||||
pub value: $id_type,
|
||||
}
|
||||
|
||||
impl ControlIntermediate {
|
||||
pub fn
|
||||
}
|
||||
|
||||
// impl ControlIntermediate {
|
||||
// pub fn into_control(native_ctrl: $id_type) -> (crate::properties::CameraPropertyId, Option<crate::properties::CameraPropertyFlag>) {
|
||||
// match native_ctrl {
|
||||
// $(
|
||||
// $control_id => ($control, $flag)
|
||||
// )*
|
||||
// nc => (crate::properties::CameraPropertyId::Custom($id_to_str(nc)), None)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// pub fn into_native(property_id: &crate::properties::CameraPropertyId, flag: Option<crate::properties::CameraPropertyFlag>) -> Option<$id_type> {
|
||||
// match (property_id, flag) {
|
||||
// $(
|
||||
// ($control, $flag) => Some($control_id),
|
||||
// )*
|
||||
// (crate::properties::CameraPropertyId::Custom(str_id), _) => $str_to_id(str_id),
|
||||
// _ => None,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
};
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub enum ControlValue {
|
||||
Null,
|
||||
Integer(i64),
|
||||
Bitmap(i64),
|
||||
Float(f64),
|
||||
String(String),
|
||||
Boolean(bool),
|
||||
KeyValue(String, ControlValuePrimitive),
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::error::{NokhwaError, NokhwaResult};
|
||||
use crate::frame_buffer::FrameBuffer;
|
||||
use flume::Receiver;
|
||||
use futures::TryFutureExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait StreamInnerTrait {
|
||||
@@ -61,6 +60,8 @@ impl Stream {
|
||||
|
||||
#[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(),
|
||||
|
||||
@@ -13,6 +13,7 @@ use std::num::NonZeroI32;
|
||||
use std::ops::{Div, Rem};
|
||||
use num_rational::Rational32;
|
||||
use crate::ranges::{SimpleRangeItem};
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
/// Describes the index of the camera.
|
||||
/// - Index: A numbered index
|
||||
@@ -247,6 +248,17 @@ impl FrameRate {
|
||||
pub fn denominator(&self) -> &i32 {
|
||||
self.rational.denom()
|
||||
}
|
||||
|
||||
pub fn as_raw(&self) -> &Rational32 {
|
||||
&self.rational
|
||||
}
|
||||
|
||||
pub fn approximate_float(&self) -> Option<f32> {
|
||||
let numerator_float = f32::from_i32(*self.numerator())?;
|
||||
let denominator_float = f32::from_i32(*self.denominator())?;
|
||||
|
||||
Some(numerator_float / denominator_float)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FrameRate {
|
||||
@@ -299,7 +311,7 @@ impl From<Rational32> for FrameRate {
|
||||
|
||||
/// This is a convenience struct that holds all information about the format of a webcam stream.
|
||||
/// It consists of a [`Resolution`], [`FrameFormat`], and a [`FrameRate`].
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, PartialOrd)]
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, PartialOrd, Eq, Ord)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
|
||||
pub struct CameraFormat {
|
||||
resolution: Resolution,
|
||||
|
||||
@@ -34,7 +34,7 @@ use nokhwa_core::{
|
||||
use std::{ffi::CString, sync::Arc};
|
||||
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValue, KnownCameraControl};
|
||||
|
||||
/// The backend struct that interfaces with V4L2.
|
||||
/// To see what this does, please see [`CaptureTrait`].
|
||||
@@ -231,7 +231,7 @@ impl CaptureTrait for AVFoundationCaptureDevice {
|
||||
fn set_camera_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
self.device.lock()?;
|
||||
let res = self.device.set_control(id, value);
|
||||
@@ -463,7 +463,7 @@ impl CaptureTrait for AVFoundationCaptureDevice {
|
||||
fn set_camera_control(
|
||||
&mut self,
|
||||
_: KnownCameraControl,
|
||||
_: ControlValueSetter,
|
||||
_: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use serde::{de, Serialize};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{window, MediaDeviceInfo, MediaDevices, MediaStream, MediaStreamConstraints, MediaStreamTrack, MediaTrackConstraints, Navigator};
|
||||
use nokhwa_core::frame_buffer::FrameBuffer;
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueSetter, KnownCameraControl};
|
||||
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};
|
||||
@@ -360,7 +360,7 @@ impl CaptureTrait for BrowserCaptureDevice {
|
||||
fn set_camera_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
todo!()
|
||||
}
|
||||
@@ -414,7 +414,7 @@ impl AsyncCaptureTrait for BrowserCaptureDevice {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_camera_control_async(&mut self, id: KnownCameraControl, value: ControlValueSetter) -> Result<(), NokhwaError> {
|
||||
async fn set_camera_control_async(&mut self, id: KnownCameraControl, value: ControlValue) -> Result<(), NokhwaError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use nokhwa_core::{
|
||||
},
|
||||
};
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
use nokhwa_core::properties::{all_known_camera_controls, CameraControl, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{all_known_camera_controls, CameraControl, ControlValue, KnownCameraControl};
|
||||
|
||||
/// The backend that deals with Media Foundation on Windows.
|
||||
/// To see what this does, please see [`CaptureTrait`].
|
||||
@@ -229,7 +229,7 @@ impl CaptureTrait for MediaFoundationCaptureDevice {
|
||||
fn set_camera_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
self.inner.set_control(id, value)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ use opencv::{
|
||||
},
|
||||
};
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueDescription, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueDescription, ControlValue, KnownCameraControl};
|
||||
|
||||
/// Attempts to convert a [`KnownCameraControl`] into a `OpenCV` video capture property.
|
||||
/// If the associated control is not found, this will return `Err`
|
||||
@@ -434,12 +434,12 @@ impl CaptureTrait for OpenCvCaptureDevice {
|
||||
fn set_camera_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
let control_val = match value {
|
||||
ControlValueSetter::Integer(i) => i as f64,
|
||||
ControlValueSetter::Float(f) => f,
|
||||
ControlValueSetter::Boolean(b) => u8::from(b) as f64,
|
||||
ControlValue::Integer(i) => i as f64,
|
||||
ControlValue::Float(f) => f,
|
||||
ControlValue::Boolean(b) => u8::from(b) as f64,
|
||||
val => {
|
||||
return Err(NokhwaError::SetPropertyError {
|
||||
property: "Camera Control".to_string(),
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ use nokhwa_core::{
|
||||
},
|
||||
};
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValue, KnownCameraControl};
|
||||
|
||||
/// The main `Camera` struct. This is the struct that abstracts over all the backends, providing a simplified interface for use.
|
||||
pub struct Camera {
|
||||
@@ -123,7 +123,7 @@ impl CaptureTrait for Camera {
|
||||
fn set_camera_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
value: ControlValueSetter,
|
||||
value: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ use std::{
|
||||
Arc, Mutex,
|
||||
},
|
||||
};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValueSetter, KnownCameraControl};
|
||||
use nokhwa_core::properties::{CameraControl, ControlValue, KnownCameraControl};
|
||||
|
||||
type AtomicLock<T> = Arc<Mutex<T>>;
|
||||
pub type CallbackFn = fn(
|
||||
@@ -420,14 +420,14 @@ impl CallbackCamera {
|
||||
|
||||
/// Sets the control to `control` in the camera.
|
||||
/// Usually, the pipeline is calling [`camera_control()`](crate::camera_traits::CaptureTrait::camera_control), getting a camera control that way
|
||||
/// then calling [`value()`](nokhwa_core::properties::CameraControl::value()) to get a [`ControlValueSetter`](nokhwa_core::properties::ControlValueSetter) and setting the value that way.
|
||||
/// then calling [`value()`](nokhwa_core::properties::CameraControl::value()) to get a [`ControlValueSetter`](nokhwa_core::properties::ControlValue) and setting the value that way.
|
||||
/// # Errors
|
||||
/// If the `control` is not supported, the value is invalid (less than min, greater than max, not in step), or there was an error setting the control,
|
||||
/// this will error.
|
||||
pub fn set_camera_control(
|
||||
&mut self,
|
||||
id: KnownCameraControl,
|
||||
control: ControlValueSetter,
|
||||
control: ControlValue,
|
||||
) -> Result<(), NokhwaError> {
|
||||
self.camera
|
||||
.lock()
|
||||
|
||||
Reference in New Issue
Block a user