Skip to main content

rff_core/
frame.rs

1//! A `Frame` is a chunk of *raw, decoded* data — pixels for video, samples for
2//! audio. It flows decoder → (filters) → encoder. Analogous to `AVFrame`.
3
4use crate::media::{PixelFormat, SampleFormat};
5
6/// A decoded raw video frame.
7#[derive(Debug, Clone)]
8pub struct VideoFrame {
9    pub width: u32,
10    pub height: u32,
11    pub format: PixelFormat,
12    /// Plane buffers (e.g. Y, U, V for planar YUV). Packed formats use one plane.
13    pub planes: Vec<Vec<u8>>,
14    /// Bytes per row for each plane (the "stride"; may exceed `width` for alignment).
15    pub strides: Vec<usize>,
16    /// Presentation timestamp in the source stream's time base. `None` if unset.
17    pub pts: Option<i64>,
18}
19
20/// A decoded raw audio frame (one block of samples across all channels).
21#[derive(Debug, Clone)]
22pub struct AudioFrame {
23    pub sample_rate: u32,
24    pub channels: u16,
25    pub format: SampleFormat,
26    /// Sample buffers. Interleaved formats use one buffer; planar formats use
27    /// one per channel.
28    pub planes: Vec<Vec<u8>>,
29    /// Number of samples *per channel* in this frame.
30    pub samples: usize,
31    /// Presentation timestamp in the source stream's time base. `None` if unset.
32    pub pts: Option<i64>,
33}
34
35/// Either a video or audio frame. Decoders emit these; encoders consume them.
36#[derive(Debug, Clone)]
37pub enum Frame {
38    Video(VideoFrame),
39    Audio(AudioFrame),
40}
41
42impl Frame {
43    pub fn pts(&self) -> Option<i64> {
44        match self {
45            Frame::Video(v) => v.pts,
46            Frame::Audio(a) => a.pts,
47        }
48    }
49}