This commit is contained in:
l1npengtul
2023-02-12 23:21:48 +09:00
parent 14f857e720
commit d737d388c6
3 changed files with 214 additions and 59 deletions
+161 -5
View File
@@ -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()
}
}
+53
View File
@@ -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
-54
View File
@@ -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