use crate::audio::AudioFrame;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Rect {
pub x: i32,
pub y: i32,
pub width: u32,
pub height: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PixelFormat {
Bgra8888,
Rgba8888,
Rgb888,
Nv12,
I420,
}
impl PixelFormat {
pub fn bytes_per_pixel(self) -> Option<usize> {
match self {
PixelFormat::Bgra8888 | PixelFormat::Rgba8888 => Some(4),
PixelFormat::Rgb888 => Some(3),
PixelFormat::Nv12 | PixelFormat::I420 => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColorSpace {
Srgb,
DisplayP3,
Bt709,
Bt2020,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DmabufFrame {
pub fd: i32,
pub offset: u32,
pub size: u32,
pub stride: u32,
pub modifier: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CvPixelBufferHandle {
pub ptr: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct D3D11TextureHandle {
pub ptr: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FrameData {
Host(Vec<u8>),
Dmabuf(DmabufFrame),
CvPixelBuffer(CvPixelBufferHandle),
D3D11Texture(D3D11TextureHandle),
}
#[derive(Debug, Clone, PartialEq)]
pub struct VideoFrame {
pub stream_time_ns: i64,
pub sequence: u64,
pub width: u32,
pub height: u32,
pub stride: u32,
pub pixel_format: PixelFormat,
pub color_space: Option<ColorSpace>,
pub data: FrameData,
pub damage: Option<Vec<Rect>>,
}
impl VideoFrame {
pub fn to_tight_bytes(&self) -> Option<Vec<u8>> {
let FrameData::Host(buf) = &self.data else {
return None;
};
let bpp = self.pixel_format.bytes_per_pixel()?;
let row_bytes = self.width as usize * bpp;
if self.stride as usize == row_bytes {
return Some(buf.clone());
}
let mut out = Vec::with_capacity(row_bytes * self.height as usize);
for row in 0..self.height as usize {
let start = row * self.stride as usize;
out.extend_from_slice(&buf[start..start + row_bytes]);
}
Some(out)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GapReason {
Dropped,
FormatChanged,
BackendRestarted,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GapEvent {
pub stream_time_ns: i64,
pub reason: GapReason,
pub dropped_frames: Option<u32>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum CaptureEvent {
Video(VideoFrame),
Audio(AudioFrame),
Gap(GapEvent),
End,
}