flowly_core/
frame.rs

1use crate::fourcc::Fourcc;
2
3use bitflags::bitflags;
4
5bitflags! {
6    #[repr(transparent)]
7    #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
8    pub struct FrameFlags: u32 {
9        const KEYFRAME         = 0b1 << 0;
10        const LAST             = 0b1 << 1;
11        const LIVE             = 0b1 << 2;
12        const TIME_SYNCED      = 0b1 << 3;
13        const HAS_PARAMS       = 0b1 << 4;
14        const HAS_TIMESTAMP    = 0b1 << 5;
15        const MULTICHANNEL     = 0b1 << 6;
16        const COMPRESSED       = 0b1 << 7;
17
18        const AUDIO_STREAM     = 0b1 << 16;
19        const VIDEO_STREAM     = 0b1 << 17;
20        const METADATA_STREAM  = 0b1 << 18;
21    }
22}
23
24pub trait Frame {
25    /// Decoding timestamp in microseconds (monotonic increasing timestamp starting from 0 (usually) at the first frame)
26    fn dts(&self) -> u64;
27
28    /// Presentation timestamp in microseconds - same as DTS, but with frame presentation offset correction
29    fn pts(&self) -> i64;
30
31    /// Fourcc signature of the payload type
32    fn codec(&self) -> Fourcc;
33
34    /// Frame Flags (keyframe, last, multitrack, live etc.)    
35    fn flags(&self) -> FrameFlags;
36
37    /// Track Number frame belongs to (always 0 for singletrack)
38    fn track(&self) -> u32;
39
40    /// The begging of translation timestamp (unixtimespamp in ms from 01:01:1970)
41    fn timestamp(&self) -> Option<u64>;
42
43    /// Iterator by NAL units of the parameters (for h264/h265 - VPS,SPS,PPS), without annexb prefix
44    fn params(&self) -> impl Iterator<Item = &[u8]>;
45
46    /// Iterator by NAL units without annexb prefix
47    fn units(&self) -> impl Iterator<Item = &[u8]>;
48
49    /// true if frame is IDR (not depends on other frames)
50    fn is_keyframe(&self) -> bool {
51        self.flags().contains(FrameFlags::KEYFRAME)
52    }
53
54    /// true if frame is part of multichannel translation
55    fn is_multichannel(&self) -> bool {
56        self.flags().contains(FrameFlags::KEYFRAME)
57    }
58
59    /// true if frame is compressed
60    fn is_compressed(&self) -> bool {
61        self.flags().contains(FrameFlags::COMPRESSED)
62    }
63
64    /// true if frame is last one in the seq
65    fn is_last(&self) -> bool {
66        self.flags().contains(FrameFlags::LAST)
67    }
68
69    /// frame needs updated decoding params
70    fn has_params(&self) -> bool {
71        self.flags().contains(FrameFlags::HAS_PARAMS)
72    }
73
74    /// live stream has timestamp of starting of the translation
75    fn has_timestamp(&self) -> bool {
76        self.flags().contains(FrameFlags::HAS_TIMESTAMP)
77    }
78
79    /// Audio Frame
80    fn is_audio(&self) -> bool {
81        self.flags().contains(FrameFlags::AUDIO_STREAM)
82    }
83
84    /// Video Frame
85    fn is_video(&self) -> bool {
86        self.flags().contains(FrameFlags::VIDEO_STREAM)
87    }
88
89    /// Metadata Frame
90    fn is_metadata(&self) -> bool {
91        self.flags().contains(FrameFlags::VIDEO_STREAM)
92    }
93
94    /// Iterator by NAL units of the parameters (for h264/h265 - VPS,SPS,PPS), with annexb prefix
95    fn units_annexb(&self) -> impl Iterator<Item = &[u8]> {
96        self.units().map(|x| [&[0, 0, 0, 1][..], &x[..]]).flatten()
97    }
98}