use crate::format::{PixelFormat, SampleFormat};
use crate::subtitle::SubtitleCue;
use crate::time::TimeBase;
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum Frame {
Audio(AudioFrame),
Video(VideoFrame),
Subtitle(SubtitleCue),
}
impl Frame {
pub fn pts(&self) -> Option<i64> {
match self {
Self::Audio(a) => a.pts,
Self::Video(v) => v.pts,
Self::Subtitle(s) => Some(s.start_us),
}
}
pub fn time_base(&self) -> TimeBase {
match self {
Self::Audio(a) => a.time_base,
Self::Video(v) => v.time_base,
Self::Subtitle(_) => TimeBase::new(1, 1_000_000),
}
}
}
#[derive(Clone, Debug)]
pub struct AudioFrame {
pub format: SampleFormat,
pub channels: u16,
pub sample_rate: u32,
pub samples: u32,
pub pts: Option<i64>,
pub time_base: TimeBase,
pub data: Vec<Vec<u8>>,
}
impl AudioFrame {
pub fn planes(&self) -> usize {
if self.format.is_planar() {
self.channels as usize
} else {
1
}
}
}
#[derive(Clone, Debug)]
pub struct VideoFrame {
pub format: PixelFormat,
pub width: u32,
pub height: u32,
pub pts: Option<i64>,
pub time_base: TimeBase,
pub planes: Vec<VideoPlane>,
}
#[derive(Clone, Debug)]
pub struct VideoPlane {
pub stride: usize,
pub data: Vec<u8>,
}