Skip to main content

rff_core/
packet.rs

1//! A `Packet` is a chunk of *compressed* data for one stream — the unit that
2//! flows demuxer → decoder and encoder → muxer. Analogous to `AVPacket`.
3
4use crate::rational::Rational;
5
6/// Per-packet flags.
7#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
8pub struct PacketFlags {
9    /// This packet begins a keyframe (random-access point).
10    pub keyframe: bool,
11    /// The last packet of its logical stream (Ogg: the final packet of the
12    /// end-of-stream page). Audio decoders trim this packet's output so the
13    /// stream ends at its [`Packet::end_position`], as FFmpeg does.
14    pub end_of_stream: bool,
15}
16
17/// A compressed packet belonging to a single stream.
18#[derive(Debug, Clone, Default)]
19pub struct Packet {
20    /// Index of the stream this packet belongs to within its container.
21    pub stream_index: usize,
22    /// Presentation timestamp, in the stream's `time_base` units. `None` if unset.
23    pub pts: Option<i64>,
24    /// Decode timestamp, in the stream's `time_base` units. `None` if unset.
25    pub dts: Option<i64>,
26    /// Duration of this packet, in `time_base` units (0 if unknown).
27    pub duration: i64,
28    /// Where the stream's decoded output ENDS once this packet is decoded, in
29    /// `time_base` units, when the container records it — Ogg's granule
30    /// position, which sits on the last packet completing each page (`None`
31    /// on the others, and in containers without one). Unlike `pts` it marks an
32    /// end, not a start: decoders count samples from it to trim end padding
33    /// off the [`end_of_stream`](PacketFlags::end_of_stream) packet.
34    pub end_position: Option<i64>,
35    /// The stream time base these timestamps are expressed in.
36    pub time_base: Rational,
37    /// The compressed payload.
38    pub data: Vec<u8>,
39    /// Packet flags (keyframe, ...).
40    pub flags: PacketFlags,
41}
42
43impl Packet {
44    /// Construct an empty packet for the given stream.
45    pub fn new(stream_index: usize) -> Packet {
46        Packet {
47            stream_index,
48            time_base: Rational::new(1, 1000),
49            ..Default::default()
50        }
51    }
52
53    /// Construct a packet wrapping an existing payload.
54    pub fn from_data(stream_index: usize, data: Vec<u8>) -> Packet {
55        Packet {
56            data,
57            ..Packet::new(stream_index)
58        }
59    }
60
61    pub fn is_keyframe(&self) -> bool {
62        self.flags.keyframe
63    }
64}