mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-04 02:27:26 +00:00
new frame rate type - update deps
This commit is contained in:
Generated
+527
-59
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ bytes = "1.3"
|
||||
paste = "1.0"
|
||||
|
||||
[dependencies.image]
|
||||
version = "0.24"
|
||||
version = "0.25"
|
||||
default-features = false
|
||||
|
||||
[dependencies.serde]
|
||||
@@ -35,16 +35,16 @@ features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.wgpu]
|
||||
version = "0.17"
|
||||
version = "0.19"
|
||||
optional = true
|
||||
|
||||
[dependencies.opencv]
|
||||
version = "0.84"
|
||||
version = "0.89.0"
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[dependencies.mozjpeg]
|
||||
version = "0.9"
|
||||
version = "0.10"
|
||||
optional = true
|
||||
|
||||
[dependencies.async-trait]
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use crate::frame_format::SourceFrameFormat;
|
||||
use crate::types::Range;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use crate::types::{FrameRate, Range};
|
||||
use crate::{
|
||||
frame_format::FrameFormat,
|
||||
types::{ApiBackend, CameraFormat, Resolution},
|
||||
types::{ CameraFormat, Resolution},
|
||||
};
|
||||
use paste::paste;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
macro_rules! range_set_fields {
|
||||
($(($range_type:ty, $name:ident),)*) => {
|
||||
@@ -136,7 +135,7 @@ macro_rules! range_set_fields {
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum CustomFormatRequestType {
|
||||
HighestFPS,
|
||||
HighestFrameRate,
|
||||
HighestResolution,
|
||||
Closest,
|
||||
}
|
||||
@@ -144,7 +143,7 @@ pub enum CustomFormatRequestType {
|
||||
#[derive(Clone, Debug, Default, PartialOrd, PartialEq)]
|
||||
pub struct FormatRequest {
|
||||
resolution: Option<Range<Resolution>>,
|
||||
frame_rate: Option<Range<u32>>,
|
||||
frame_rate: Option<Range<FrameRate>>,
|
||||
frame_format: Option<Vec<FrameFormat>>,
|
||||
req_type: Option<CustomFormatRequestType>,
|
||||
}
|
||||
@@ -205,14 +204,95 @@ impl FormatRequest {
|
||||
self.req_type = None;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn satisfied_by_format(&self, format: &CameraFormat) -> bool {
|
||||
// check resolution
|
||||
let resolution_satisfied = match self.resolution {
|
||||
Some(res_range) => res_range.in_range(format.resolution()),
|
||||
None => true,
|
||||
};
|
||||
|
||||
let frame_rate_satisfied = match self.frame_rate {
|
||||
Some(fps_range) => fps_range.in_range(format.frame_rate()),
|
||||
None => true,
|
||||
};
|
||||
|
||||
let frame_format_satisfied = match &self.frame_format {
|
||||
Some(frame_formats) => frame_formats.contains(&format.format()),
|
||||
None => true,
|
||||
};
|
||||
|
||||
// we ignore custom bc that only makes sense in multiple formats
|
||||
|
||||
resolution_satisfied && frame_rate_satisfied && frame_format_satisfied
|
||||
}
|
||||
|
||||
pub fn resolve(&self, list_of_formats: &[CameraFormat]) -> CameraFormat {
|
||||
let mut remaining_formats = list_of_formats.iter().filter(|x| self.satisfied_by_format(*x)).collect::<Vec<CameraFormat>>();
|
||||
match self.req_type {
|
||||
Some(request) => {
|
||||
match request {
|
||||
CustomFormatRequestType::HighestFrameRate => {
|
||||
remaining_formats.sort_by(|a, b| {
|
||||
a.frame_rate().cmp(&b.frame_rate())
|
||||
});
|
||||
remaining_formats[0]
|
||||
}
|
||||
CustomFormatRequestType::HighestResolution => {
|
||||
remaining_formats.sort_by(|a, b| {
|
||||
a.resolution().cmp(&b.resolution())
|
||||
});
|
||||
remaining_formats[0]
|
||||
}
|
||||
CustomFormatRequestType::Closest => {
|
||||
enum ClosestType {
|
||||
Resolution,
|
||||
FrameRate,
|
||||
Both,
|
||||
None,
|
||||
}
|
||||
let mut closest_type = ClosestType::Resolution;
|
||||
|
||||
if let None = self.resolution {
|
||||
closest_type = ClosestType::FrameRate
|
||||
}
|
||||
|
||||
if let None = self.frame_rate {
|
||||
if closest_type == ClosestType::FrameRate {
|
||||
closest_type = ClosestType::None;
|
||||
}
|
||||
closest_type = ClosestType::Resolution
|
||||
} else {
|
||||
if ClosestType::Resolution {
|
||||
closest_type = ClosestType::Both
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
match closest_type {
|
||||
ClosestType::Resolution => {
|
||||
let resolution_point = self.resolution.unwrap().preferred();
|
||||
}
|
||||
ClosestType::FrameRate => {
|
||||
let frame_rate_point = self.frame_rate.unwrap().preferred();
|
||||
}
|
||||
ClosestType::Both => {
|
||||
let resolution_point = self.resolution.unwrap().preferred();
|
||||
let frame_rate_point = self.frame_rate.unwrap().preferred();
|
||||
|
||||
}
|
||||
ClosestType::None => {
|
||||
remaining_formats[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
remaining_formats[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
range_set_fields!((Resolution, resolution), (u32, frame_rate),);
|
||||
|
||||
// tomorrow wont come for those without FRAME FORMATS
|
||||
pub fn resolve_format_request(
|
||||
request: FormatRequest,
|
||||
availible_formats: Vec<CameraFormat>,
|
||||
) -> CameraFormat {
|
||||
// filter out by parts first
|
||||
}
|
||||
range_set_fields!((Resolution, resolution), (FrameRate, frame_rate),);
|
||||
|
||||
@@ -52,6 +52,7 @@ pub enum FrameFormat {
|
||||
|
||||
// Grayscale Formats
|
||||
Luma8,
|
||||
Luma16,
|
||||
|
||||
// RGB Formats
|
||||
Rgb8,
|
||||
@@ -81,6 +82,7 @@ impl FrameFormat {
|
||||
FrameFormat::Nv21,
|
||||
FrameFormat::Yv12,
|
||||
FrameFormat::Luma8,
|
||||
FrameFormat::Luma16,
|
||||
FrameFormat::Rgb8,
|
||||
FrameFormat::RgbA8,
|
||||
];
|
||||
@@ -107,9 +109,34 @@ impl FrameFormat {
|
||||
FrameFormat::Yv12,
|
||||
];
|
||||
|
||||
pub const LUMA: &'static [FrameFormat] = &[FrameFormat::Luma8];
|
||||
pub const LUMA: &'static [FrameFormat] = &[FrameFormat::Luma8, FrameFormat::Luma16];
|
||||
|
||||
pub const RGB: &'static [FrameFormat] = &[FrameFormat::Rgb8, FrameFormat::RgbA8];
|
||||
|
||||
pub const COLOR_FORMATS: &'static [FrameFormat] = &[
|
||||
FrameFormat::H265,
|
||||
FrameFormat::H264,
|
||||
FrameFormat::H263,
|
||||
FrameFormat::Avc1,
|
||||
FrameFormat::Mpeg1,
|
||||
FrameFormat::Mpeg2,
|
||||
FrameFormat::Mpeg4,
|
||||
FrameFormat::MJpeg,
|
||||
FrameFormat::XVid,
|
||||
FrameFormat::VP8,
|
||||
FrameFormat::VP9,
|
||||
FrameFormat::Yuv422,
|
||||
FrameFormat::Uyv422,
|
||||
FrameFormat::Nv12,
|
||||
FrameFormat::Nv21,
|
||||
FrameFormat::Yv12,
|
||||
FrameFormat::Rgb8,
|
||||
FrameFormat::RgbA8,
|
||||
];
|
||||
|
||||
pub const GRAYSCALE: &'static [FrameFormat] = {
|
||||
FrameFormat::Luma8
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FrameFormat {
|
||||
|
||||
+26
-19
@@ -20,25 +20,25 @@ where
|
||||
lower_inclusive: bool,
|
||||
maximum: Option<T>,
|
||||
upper_inclusive: bool,
|
||||
preferred: T,
|
||||
preferred: Option<T>,
|
||||
}
|
||||
|
||||
impl<T> Range<T>
|
||||
where
|
||||
T: Copy + Clone + Debug + PartialOrd + PartialEq,
|
||||
{
|
||||
pub fn new(preferred: T, min: Option<T>, max: Option<T>) -> Self {
|
||||
pub fn new(preferred: Option<T>, min: Option<T>, max: Option<T>) -> Self {
|
||||
Self {
|
||||
minimum: min,
|
||||
lower_inclusive: true,
|
||||
maximum: max,
|
||||
upper_inclusive: false,
|
||||
upper_inclusive: true,
|
||||
preferred,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_inclusive(
|
||||
preferred: T,
|
||||
preferred: Option<T>,
|
||||
min: Option<T>,
|
||||
lower_inclusive: bool,
|
||||
max: Option<T>,
|
||||
@@ -58,14 +58,16 @@ where
|
||||
minimum: None,
|
||||
lower_inclusive: true,
|
||||
maximum: None,
|
||||
upper_inclusive: false,
|
||||
preferred,
|
||||
upper_inclusive: true,
|
||||
preferred: Some(preferred),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn does_fit(&self, item: T) -> bool {
|
||||
if item == self.preferred {
|
||||
true
|
||||
pub fn in_range(&self, item: T) -> bool {
|
||||
if let Some(pref) = self.preferred {
|
||||
if pref == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(min) = self.minimum {
|
||||
@@ -107,9 +109,12 @@ where
|
||||
self.upper_inclusive = upper_inclusive;
|
||||
}
|
||||
pub fn set_preferred(&mut self, preferred: T) {
|
||||
self.preferred = preferred;
|
||||
self.preferred = Some(preferred);
|
||||
}
|
||||
|
||||
pub fn reset_preferred(&mut self) {
|
||||
self.preferred = None
|
||||
}
|
||||
pub fn minimum(&self) -> Option<T> {
|
||||
self.minimum
|
||||
}
|
||||
@@ -122,7 +127,7 @@ where
|
||||
pub fn upper_inclusive(&self) -> bool {
|
||||
self.upper_inclusive
|
||||
}
|
||||
pub fn preferred(&self) -> T {
|
||||
pub fn preferred(&self) -> Option<T> {
|
||||
self.preferred
|
||||
}
|
||||
}
|
||||
@@ -136,12 +141,14 @@ where
|
||||
minimum: None,
|
||||
lower_inclusive: true,
|
||||
maximum: None,
|
||||
upper_inclusive: false,
|
||||
preferred: T::default(),
|
||||
upper_inclusive: true,
|
||||
preferred: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Describes the index of the camera.
|
||||
/// - Index: A numbered index
|
||||
/// - String: A string, used for `IPCameras`.
|
||||
@@ -337,16 +344,16 @@ impl FrameRate {
|
||||
|
||||
pub fn as_float(&self) -> f32 {
|
||||
match self {
|
||||
FrameRate::Integer(fps) => fps as f32,
|
||||
FrameRate::Integer(fps) => *fps as f32,
|
||||
FrameRate::Float(fps) => fps,
|
||||
FrameRate::Fraction { numerator, denominator } => (numerator as f32) / (denominator as f32)
|
||||
FrameRate::Fraction { numerator, denominator } => (*numerator as f32) / (*denominator as f32)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_u32(&self) -> u32 {
|
||||
match self {
|
||||
FrameRate::Integer(fps) => *fps,
|
||||
FrameRate::Float(fps) => fps as u32,
|
||||
FrameRate::Float(fps) => *fps as u32,
|
||||
FrameRate::Fraction { numerator, denominator } => numerator / denominator,
|
||||
}
|
||||
}
|
||||
@@ -536,7 +543,7 @@ impl CameraInfo {
|
||||
human_name: human_name.to_string(),
|
||||
description: description.to_string(),
|
||||
misc: misc.to_string(),
|
||||
index,
|
||||
index: index.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -919,8 +926,8 @@ impl ControlValueDescription {
|
||||
Some(v) => *v.0 >= max.0 && *v.1 >= max.1 && *v.2 >= max.2,
|
||||
None => false,
|
||||
},
|
||||
ControlValueDescription::StringList { value, availible } => {
|
||||
availible.contains(setter.as_str())
|
||||
ControlValueDescription::StringList { availible, .. } => {
|
||||
availible.contains(&(setter.as_str().unwrap_or("").to_string())) // what the fuck??
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user