mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-20 00:08:52 +00:00
async decoder trait decl
This commit is contained in:
+2
-6
@@ -34,7 +34,6 @@ output-wgpu = ["wgpu", "nokhwa-core/wgpu-types"]
|
||||
#output-wasm = ["input-jscam"]
|
||||
output-threaded = []
|
||||
output-async = ["nokhwa-core/async", "async-trait"]
|
||||
small-wasm = []
|
||||
docs-only = ["input-native", "input-opencv", "input-jscam","output-wgpu", "output-threaded", "serialize"]
|
||||
docs-nolink = ["nokhwa-core/docs-features"]
|
||||
docs-features = []
|
||||
@@ -43,6 +42,7 @@ test-fail-warning = []
|
||||
[dependencies]
|
||||
thiserror = "1.0"
|
||||
paste = "1.0"
|
||||
dcv-color-primitives = "0.5"
|
||||
|
||||
[dependencies.nokhwa-core]
|
||||
version = "0.2"
|
||||
@@ -60,10 +60,6 @@ optional = true
|
||||
version = "0.24"
|
||||
default-features = false
|
||||
|
||||
[dependencies.v4l]
|
||||
version = "0.13"
|
||||
optional = true
|
||||
|
||||
[dependencies.usb_enumeration]
|
||||
version = "0.2"
|
||||
optional = true
|
||||
@@ -73,7 +69,7 @@ version = "0.16"
|
||||
optional = true
|
||||
|
||||
[dependencies.opencv]
|
||||
version = "0.80"
|
||||
version = "0.82"
|
||||
default-features = false
|
||||
features = ["videoio"]
|
||||
optional = true
|
||||
|
||||
@@ -17,17 +17,60 @@ pub trait Decoder {
|
||||
|
||||
/// Decode function.
|
||||
fn decode(&mut self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
|
||||
/// Decode to user-provided Buffer
|
||||
///
|
||||
/// Incase that the buffer is not large enough this should error.
|
||||
fn decode_buffer(&mut self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error>;
|
||||
|
||||
/// Decoder Predicted Size
|
||||
fn predicted_size_of_frame(&mut self, ) -> Option<usize>;
|
||||
}
|
||||
|
||||
/// Decoder that can be used statically (struct contains no state)
|
||||
///
|
||||
/// This is useful for times that a simple function is all that is required.
|
||||
///
|
||||
/// This is useful for times that a simple function is all that is required.
|
||||
pub trait StaticDecoder: Decoder {
|
||||
fn decode_static(buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
|
||||
fn decode_static_to_buffer(buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
/// Decoder that does not change its internal state.
|
||||
/// Decoder that does not change its internal state.
|
||||
pub trait IdemptDecoder: Decoder {
|
||||
fn decode_nm(buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
/// Decoder that does not change its internal state.
|
||||
fn decode_nm(&self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
|
||||
/// Decoder that does not change its internal state, decoding to a user provided buffer.
|
||||
fn decode_nm_to_buffer(&self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(feature = "async", async_trait::async_trait)]
|
||||
pub trait AsyncDecoder: Decoder {
|
||||
/// Asynchronous decoder
|
||||
async fn decode_async(&mut self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
|
||||
/// Asynchronous decoder to user buffer.
|
||||
async fn decode_buffer(&mut self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(feature = "async", async_trait::async_trait)]
|
||||
pub trait AsyncStaticDecoder: Decoder {
|
||||
/// Asynchronous decoder
|
||||
async fn decode_static_async(buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
|
||||
/// Asynchronous decoder to user buffer.
|
||||
async fn decode_static_buffer(buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(feature = "async", async_trait::async_trait)]
|
||||
pub trait AsyncIdemptDecoder: Decoder {
|
||||
/// Asynchronous decoder
|
||||
async fn decode_nm_async(&self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error>;
|
||||
|
||||
/// Asynchronous decoder to user buffer.
|
||||
async fn decode_nm_buffer(&self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
@@ -1318,15 +1318,6 @@ pub fn yuyv422_predicted_size(size: usize, rgba: bool) -> usize {
|
||||
(size / 4) * (2 * pixel_size)
|
||||
}
|
||||
|
||||
// For those maintaining this, I recommend you read: https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#yuy2
|
||||
// https://en.wikipedia.org/wiki/YUV#Converting_between_Y%E2%80%B2UV_and_RGB
|
||||
// and this too: https://stackoverflow.com/questions/16107165/convert-from-yuv-420-to-imagebgr-byte
|
||||
// The YUY2(Yuv422) format is a 16 bit format. We read 4 bytes at a time to get 6 bytes of RGB888.
|
||||
// First, the YUY2 is converted to YCbCr 4:4:4 (4:2:2 -> 4:4:4)
|
||||
// then it is converted to 6 bytes (2 pixels) of RGB888
|
||||
/// Converts a Yuv422 4:2:2 datastream to a RGB888 Stream. [For further reading](https://en.wikipedia.org/wiki/YUV#Converting_between_Y%E2%80%B2UV_and_RGB)
|
||||
/// # Errors
|
||||
/// This may error when the data stream size is not divisible by 4, a i32 -> u8 conversion fails, or it fails to read from a certain index.
|
||||
#[inline]
|
||||
pub fn yuyv422_to_rgb(data: &[u8], rgba: bool) -> Result<Vec<u8>, NokhwaError> {
|
||||
let capacity = yuyv422_predicted_size(data.len(), rgba);
|
||||
|
||||
+41
-1
@@ -1 +1,41 @@
|
||||
pub struct NV12Decoder {}
|
||||
use image::{ImageBuffer, Rgb};
|
||||
use nokhwa_core::buffer::Buffer;
|
||||
use nokhwa_core::decoder::{Decoder, IdemptDecoder, StaticDecoder};
|
||||
use nokhwa_core::frame_format::SourceFrameFormat;
|
||||
|
||||
pub struct NV12Decoder {}
|
||||
|
||||
impl Decoder for NV12Decoder {
|
||||
const ALLOWED_FORMATS: &'static [SourceFrameFormat] = &[];
|
||||
type Pixel = Rgb<u8>;
|
||||
type Container = Vec<u8>;
|
||||
type Error = ();
|
||||
|
||||
fn decode(&mut self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn decode_buffer(&mut self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn predicted_size_of_frame(&mut self) -> Option<usize> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticDecoder for NV12Decoder {
|
||||
fn decode_static(buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn decode_static_to_buffer(buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl IdemptDecoder for NV12Decoder {
|
||||
fn decode_nm(buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
+54
-1
@@ -1 +1,54 @@
|
||||
pub struct YUYVDecoder {}
|
||||
use image::ImageBuffer;
|
||||
use nokhwa_core::buffer::Buffer;
|
||||
use nokhwa_core::decoder::{Decoder, IdemptDecoder, StaticDecoder};
|
||||
use nokhwa_core::frame_format::SourceFrameFormat;
|
||||
|
||||
// For those maintaining this, I recommend you read: https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#yuy2
|
||||
// https://en.wikipedia.org/wiki/YUV#Converting_between_Y%E2%80%B2UV_and_RGB
|
||||
// and this too: https://stackoverflow.com/questions/16107165/convert-from-yuv-420-to-imagebgr-byte
|
||||
// The YUY2(Yuv422) format is a 16 bit format. We read 4 bytes at a time to get 6 bytes of RGB888.
|
||||
// First, the YUY2 is converted to YCbCr 4:4:4 (4:2:2 -> 4:4:4)
|
||||
// then it is converted to 6 bytes (2 pixels) of RGB888
|
||||
/// Converts a Yuv422 4:2:2 datastream to a RGB888 Stream. [For further reading](https://en.wikipedia.org/wiki/YUV#Converting_between_Y%E2%80%B2UV_and_RGB)
|
||||
/// # Errors
|
||||
/// This may error when the data stream size is not divisible by 4, a i32 -> u8 conversion fails, or it fails to read from a certain index.
|
||||
pub struct YUYVDecoder {}
|
||||
|
||||
impl Decoder for YUYVDecoder {
|
||||
const ALLOWED_FORMATS: &'static [SourceFrameFormat] = &[];
|
||||
type Pixel = ();
|
||||
type Container = ();
|
||||
type Error = ();
|
||||
|
||||
fn decode(&mut self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn decode_buffer(&mut self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn predicted_size_of_frame(&mut self) -> Option<usize> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticDecoder for YUYVDecoder {
|
||||
fn decode_static(buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn decode_static_to_buffer(buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl IdemptDecoder for YUYVDecoder {
|
||||
fn decode_nm(&self, buffer: Buffer) -> Result<ImageBuffer<Self::Pixel, Self::Container>, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn decode_nm_to_buffer(&self, buffer: &mut [Pixel::Subpixel]) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user