flowly_core/
frame.rs

1use std::sync::Arc;
2
3use crate::{Chunked, MemBlock, Void, fourcc::Fourcc};
4
5use bitflags::bitflags;
6use bytes::Buf;
7
8bitflags! {
9    #[repr(transparent)]
10    #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
11    pub struct FrameFlags: u32 {
12        const KEYFRAME             = 0b1 << 0; // Stream can be split on that frame
13        const LAST                 = 0b1 << 1; // Last frame indicator
14        const LIVE                 = 0b1 << 2; // Is live stream (IP Camera)
15        const TIME_SYNCED          = 0b1 << 3; // Livestream timestamp synchronized with source
16        const HAS_PARAMS           = 0b1 << 4; // Has additional parameters
17        const HAS_START_TIMESTAMP  = 0b1 << 5; // Livesctream has TimeStamp of the start
18        const MULTICHANNEL         = 0b1 << 6; // Stream has more than one channel
19        const ENCODED              = 0b1 << 7; // Is encoded stream (h264, h265, etc.)
20        const DUMMY                = 0b1 << 8; // Generated, non-real video stream
21        const ANNEXB               = 0b1 << 9; // AnnexB prefixed
22
23        const AUDIO_STREAM         = 0b1 << 16;
24        const VIDEO_STREAM         = 0b1 << 17;
25        const METADATA_STREAM      = 0b1 << 18;
26    }
27}
28
29pub enum FrameSourceKind {
30    Unknown,
31    File,
32    Url,
33}
34
35pub trait FrameSource: Sync + Send + Default + Clone + PartialEq + 'static {
36    type Source: FrameSource;
37
38    fn source(&self) -> &Self::Source;
39
40    #[inline]
41    fn kind(&self) -> FrameSourceKind {
42        self.source().kind()
43    }
44
45    #[inline]
46    fn url(&self) -> &str {
47        self.source().url()
48    }
49
50    #[inline]
51    fn name(&self) -> &str {
52        self.source().name()
53    }
54}
55
56impl<T: FrameSource> FrameSource for Arc<T> {
57    type Source = T::Source;
58
59    fn kind(&self) -> FrameSourceKind {
60        (**self).kind()
61    }
62
63    fn url(&self) -> &str {
64        (**self).url()
65    }
66
67    fn name(&self) -> &str {
68        (**self).name()
69    }
70
71    fn source(&self) -> &Self::Source {
72        (**self).source()
73    }
74}
75
76impl FrameSource for () {
77    type Source = Void;
78
79    fn kind(&self) -> FrameSourceKind {
80        FrameSourceKind::Unknown
81    }
82
83    fn url(&self) -> &str {
84        ""
85    }
86
87    fn name(&self) -> &str {
88        ""
89    }
90
91    fn source(&self) -> &Self::Source {
92        unreachable!()
93    }
94}
95
96impl FrameSource for String {
97    type Source = Void;
98
99    fn kind(&self) -> FrameSourceKind {
100        FrameSourceKind::Unknown
101    }
102
103    fn url(&self) -> &str {
104        self
105    }
106
107    fn name(&self) -> &str {
108        self
109    }
110
111    fn source(&self) -> &Self::Source {
112        unreachable!()
113    }
114}
115
116/// Chunk of data in the stream
117pub trait DataFrame: Send + Clone {
118    type Source: FrameSource;
119    type Chunk: Send + MemBlock;
120
121    /// FrameSource - source info structure
122    fn source(&self) -> &Self::Source;
123    fn chunks(&self) -> impl Send + Iterator<Item = <Self::Chunk as MemBlock>::Ref<'_>>;
124    fn into_chunks(self) -> impl Send + Iterator<Item = Self::Chunk>;
125
126    fn put_into(self, chunks: &mut Chunked<Self::Chunk>)
127    where
128        Self::Chunk: Buf,
129    {
130        for chunk in self.into_chunks() {
131            chunks.put(chunk);
132        }
133    }
134}
135
136/// Frame of the data (related to some timestamp, codec and with some flags)
137pub trait Frame: DataFrame {
138    /// Timestamp in microseconds when frame should appear from start
139    fn timestamp(&self) -> u64;
140
141    /// Fourcc signature of the payload type
142    fn codec(&self) -> Fourcc;
143
144    /// Frame Flags (keyframe, last, multitrack, live etc.)    
145    fn flags(&self) -> FrameFlags;
146
147    /// Check the flag presence    
148    #[inline]
149    fn has_flag(&self, flag: FrameFlags) -> bool {
150        self.flags().contains(flag)
151    }
152
153    /// true if frame is IDR (not depends on other frames)
154    #[inline]
155    fn is_keyframe(&self) -> bool {
156        self.has_flag(FrameFlags::KEYFRAME)
157    }
158
159    /// true if frame is compressed
160    #[inline]
161    fn is_live(&self) -> bool {
162        self.has_flag(FrameFlags::LIVE)
163    }
164
165    /// true if frame is part of multichannel translation
166    #[inline]
167    fn is_multichannel(&self) -> bool {
168        self.has_flag(FrameFlags::MULTICHANNEL)
169    }
170
171    /// true if frame is compressed
172    #[inline]
173    fn is_encoded(&self) -> bool {
174        self.has_flag(FrameFlags::ENCODED)
175    }
176
177    /// true if frame is last one in the seq
178    #[inline]
179    fn is_last(&self) -> bool {
180        self.has_flag(FrameFlags::LAST)
181    }
182
183    /// frame needs updated decoding params
184    #[inline]
185    fn has_params(&self) -> bool {
186        self.has_flag(FrameFlags::HAS_PARAMS)
187    }
188
189    /// live stream has timestamp of starting of the translation
190    #[inline]
191    fn has_start_timestamp(&self) -> bool {
192        self.has_flag(FrameFlags::HAS_START_TIMESTAMP)
193    }
194
195    /// Audio Frame
196    #[inline]
197    fn is_audio(&self) -> bool {
198        self.has_flag(FrameFlags::AUDIO_STREAM)
199    }
200
201    /// Video Frame
202    #[inline]
203    fn is_video(&self) -> bool {
204        self.has_flag(FrameFlags::VIDEO_STREAM)
205    }
206
207    /// Metadata Frame
208    #[inline]
209    fn is_metadata(&self) -> bool {
210        self.has_flag(FrameFlags::METADATA_STREAM)
211    }
212}
213
214pub trait Live: Frame {
215    /// The begging of translation timestamp (unixtimespamp in ms from 01:01:1970)
216    fn timestamp(&self) -> u64;
217}
218
219pub trait EncodedFrame: Frame {
220    type Param: AsRef<[u8]>;
221
222    /// Decoding timestamp in microseconds (monotonic increasing timestamp starting from 0 (usually) at the first frame)
223    #[inline]
224    fn dts(&self) -> u64 {
225        self.timestamp()
226    }
227
228    /// Presentation timestamp in microseconds - same as DTS, but with frame presentation offset correction
229    fn pts(&self) -> i64;
230
231    /// Iterator by NAL units of the parameters (for h264/h265 - VPS,SPS,PPS)
232    fn params(&self) -> impl Iterator<Item = &Self::Param>;
233}
234
235pub trait Multichannel: Frame {
236    /// Track Number frame belongs to (always 0 for singletrack)
237    fn track(&self) -> u32;
238}
239
240pub trait VideoFrame: Frame {
241    /// Video Dimensions (Width, Height)
242    fn dimensions(&self) -> (u16, u16);
243
244    /// Bits per pixel (8, 10, 12)
245    fn bit_depth(&self) -> u8;
246}