mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-04 02:27:26 +00:00
filtere
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
use crate::frame_format::FrameFormat;
|
||||
use crate::types::{CameraFormat, Resolution};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::types::{ApiBackend, CameraFormat, Resolution};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||
|
||||
/// Tells the init function what camera format to pick.
|
||||
/// - `AbsoluteHighestResolution`: Pick the highest [`Resolution`], then pick the highest frame rate of those provided.
|
||||
/// - `AbsoluteHighestFrameRate`: Pick the highest frame rate, then the highest [`Resolution`].
|
||||
/// - `HighestResolution(Resolution)`: Pick the highest [`Resolution`] for the given framerate (the `Option<u32>`).
|
||||
/// - `HighestFrameRate(u32)`: Pick the highest frame rate for the given [`Resolution`] (the `Option<Resolution>`).
|
||||
/// - `Exact`: Pick the exact [`CameraFormat`] provided.
|
||||
/// - `Closest`: Pick the closest [`CameraFormat`] provided in order of [`FrameFormat`], [`Resolution`], and FPS.
|
||||
/// - `None`: Pick a random [`CameraFormat`]
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
@@ -16,10 +17,165 @@ pub enum RequestedFormatType {
|
||||
AbsoluteHighestFrameRate,
|
||||
HighestResolution(Resolution),
|
||||
HighestFrameRate(u32),
|
||||
Exact(CameraFormat),
|
||||
Closest(CameraFormat),
|
||||
None,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FormatFilter {
|
||||
filter_pref:
|
||||
filter_pref: RequestedFormatType,
|
||||
fcc_primary: BTreeSet<FrameFormat>,
|
||||
fcc_platform: BTreeMap<ApiBackend, BTreeSet<u128>>,
|
||||
}
|
||||
|
||||
impl FormatFilter {
|
||||
pub fn new(fmt_type: RequestedFormatType) -> Self {
|
||||
Self {
|
||||
filter_pref: fmt_type,
|
||||
fcc_primary: Default::default(),
|
||||
fcc_platform: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_allowed_frame_format(&mut self, frame_format: FrameFormat) {
|
||||
self.fcc_primary.insert(frame_format);
|
||||
}
|
||||
|
||||
pub fn add_allowed_frame_format_many(&mut self, frame_formats: impl AsRef<[FrameFormat]>) {
|
||||
self.fcc_primary.extend(frame_formats.as_ref().iter());
|
||||
}
|
||||
|
||||
pub fn add_allowed_platform_specific(&mut self, platform: ApiBackend, frame_format: u128) {
|
||||
match self.fcc_platform.get_mut(&platform) {
|
||||
Some(fccs) => fccs.push(frame_format),
|
||||
None => self
|
||||
.fcc_platform
|
||||
.insert(platform, BTreeSet::from([frame_format])),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn add_allowed_platform_specific_many(
|
||||
&mut self,
|
||||
platform_specifics: impl IntoPlatformSpecificMany,
|
||||
) {
|
||||
for (platform, frame_format) in platform_specifics.into_psm().into_iter() {
|
||||
match self.fcc_platform.get_mut(&platform) {
|
||||
Some(fccs) => fccs.push(frame_format),
|
||||
None => self
|
||||
.fcc_platform
|
||||
.insert(platform, BTreeSet::from([frame_format])),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_allowed_frame_format(mut self, frame_format: FrameFormat) -> Self {
|
||||
self.fcc_primary.insert(frame_format);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_allowed_frame_format_many(
|
||||
mut self,
|
||||
frame_formats: impl AsRef<[FrameFormat]>,
|
||||
) -> Self {
|
||||
self.fcc_primary.extend(frame_formats.as_ref().iter());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_allowed_platform_specific(
|
||||
mut self,
|
||||
platform: ApiBackend,
|
||||
frame_format: u128,
|
||||
) -> Self {
|
||||
match self.fcc_platform.get_mut(&platform) {
|
||||
Some(fccs) => fccs.push(frame_format),
|
||||
None => self
|
||||
.fcc_platform
|
||||
.insert(platform, BTreeSet::from([frame_format])),
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_allowed_platform_specific_many(
|
||||
mut self,
|
||||
platform_specifics: impl IntoPlatformSpecificMany,
|
||||
) -> Self {
|
||||
self.add_allowed_platform_specific_many(platform_specifics);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FormatFilter {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
filter_pref: RequestedFormatType::Closest(CameraFormat::new(
|
||||
Resolution::new(640, 480),
|
||||
FrameFormat::Yuv422,
|
||||
30,
|
||||
)),
|
||||
fcc_primary: BTreeSet::from([FrameFormat::Yuv422]),
|
||||
fcc_platform: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoPlatformSpecificMany {
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)>;
|
||||
}
|
||||
|
||||
impl<T> IntoPlatformSpecificMany for T
|
||||
where
|
||||
T: AsRef<(ApiBackend, u128)>,
|
||||
{
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)> {
|
||||
vec![*self.as_ref()]
|
||||
}
|
||||
}
|
||||
impl<T> IntoPlatformSpecificMany for T
|
||||
where
|
||||
T: AsRef<[(ApiBackend, u128)]>,
|
||||
{
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)> {
|
||||
self.as_ref().iter().collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPlatformSpecificMany for BTreeMap<ApiBackend, T>
|
||||
where
|
||||
T: AsRef<[u128]>,
|
||||
{
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)> {
|
||||
self.into_iter()
|
||||
.flat_map(|(backend, fourcc_lst)| fourcc_lst.as_ref().iter().map(|fcc| (backend, *fcc)))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPlatformSpecificMany for HashMap<ApiBackend, T>
|
||||
where
|
||||
T: AsRef<[u128]>,
|
||||
{
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)> {
|
||||
self.into_iter()
|
||||
.flat_map(|(backend, fourcc_lst)| fourcc_lst.as_ref().iter().map(|fcc| (backend, *fcc)))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPlatformSpecificMany for &T
|
||||
where
|
||||
T: IntoPlatformSpecificMany + Clone,
|
||||
{
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)> {
|
||||
self.clone().into_psm()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPlatformSpecificMany for &mut T
|
||||
where
|
||||
T: IntoPlatformSpecificMany + Clone,
|
||||
{
|
||||
fn into_psm(self) -> Vec<(ApiBackend, u128)> {
|
||||
self.clone().into_psm()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,3 +102,56 @@ impl Display for FrameFormat {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2022 l1npengtul <l1npengtul@protonmail.com> / 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use crate::buffer::Buffer;
|
||||
use crate::types::ApiBackend;
|
||||
use image::{ImageBuffer, Luma, LumaA, Primitive, Rgb, Rgba};
|
||||
use std::ops::Deref;
|
||||
|
||||
pub trait FormatDecoders: Send + Sync {
|
||||
const NAME: &'static str;
|
||||
|
||||
const PRIMARY: &'static [FrameFormat];
|
||||
|
||||
const PLATFORM_ACCEPTABLE: &'static [(ApiBackend, &'static [u128])];
|
||||
|
||||
type Primitive: Primitive;
|
||||
|
||||
type Container: Deref<Target = [Self::Primitive]>;
|
||||
}
|
||||
|
||||
pub trait RgbDecoder: FormatDecoders {
|
||||
fn decode_rgb(&self, buffer: &Buffer) -> ImageBuffer<Rgb<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
pub trait RgbADecoder: FormatDecoders {
|
||||
fn decode_rgba(&self, buffer: &Buffer) -> ImageBuffer<Rgba<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
pub trait LumaDecoder: FormatDecoders {
|
||||
fn decode_luma(&self, buffer: &Buffer) -> ImageBuffer<Luma<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
pub trait LumaADecoder: FormatDecoders {
|
||||
fn decode_luma_a(
|
||||
&self,
|
||||
buffer: &Buffer,
|
||||
) -> ImageBuffer<LumaA<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
// TODO: Wgpu Decoder
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 l1npengtul <l1npengtul@protonmail.com> / 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use crate::buffer::Buffer;
|
||||
use crate::frame_format::FrameFormat;
|
||||
use image::{ImageBuffer, Luma, LumaA, Primitive, Rgb, Rgba};
|
||||
use std::ops::Deref;
|
||||
|
||||
pub trait FormatDecoders: Send + Sync {
|
||||
const NAME: &'static str;
|
||||
|
||||
const PRIMARY: FrameFormat;
|
||||
|
||||
const ACCEPTABLE: &'static [FrameFormat];
|
||||
|
||||
const PLATFORM_ACCEPTABLE: &'static [(&'static str, &'static [u128])];
|
||||
|
||||
type Primitive: Primitive;
|
||||
|
||||
type Container: Deref<Target = [Self::Primitive]>;
|
||||
}
|
||||
|
||||
pub trait RgbDecoder: FormatDecoders {
|
||||
fn decode_rgb(&self, buffer: &Buffer) -> ImageBuffer<Rgb<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
pub trait RgbADecoder: FormatDecoders {
|
||||
fn decode_rgba(&self, buffer: &Buffer) -> ImageBuffer<Rgba<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
pub trait LumaDecoder: FormatDecoders {
|
||||
fn decode_luma(&self, buffer: &Buffer) -> ImageBuffer<Luma<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
pub trait LumaADecoder: FormatDecoders {
|
||||
fn decode_luma_a(
|
||||
&self,
|
||||
buffer: &Buffer,
|
||||
) -> ImageBuffer<LumaA<Self::Primitive>, Self::Container>;
|
||||
}
|
||||
|
||||
// TODO: Wgpu Decoder
|
||||
Reference in New Issue
Block a user