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; const LAST = 0b1 << 1; const LIVE = 0b1 << 2; const TIME_SYNCED = 0b1 << 3; const HAS_PARAMS = 0b1 << 4; const HAS_START_TIMESTAMP = 0b1 << 5; const MULTICHANNEL = 0b1 << 6; const ENCODED = 0b1 << 7; const DUMMY = 0b1 << 8; const ANNEXB = 0b1 << 9; 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
116pub trait DataFrame: Send + Clone {
118 type Source: FrameSource;
119 type Chunk: Send + MemBlock;
120
121 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
136pub trait Frame: DataFrame {
138 fn timestamp(&self) -> u64;
140
141 fn codec(&self) -> Fourcc;
143
144 fn flags(&self) -> FrameFlags;
146
147 #[inline]
149 fn has_flag(&self, flag: FrameFlags) -> bool {
150 self.flags().contains(flag)
151 }
152
153 #[inline]
155 fn is_keyframe(&self) -> bool {
156 self.has_flag(FrameFlags::KEYFRAME)
157 }
158
159 #[inline]
161 fn is_live(&self) -> bool {
162 self.has_flag(FrameFlags::LIVE)
163 }
164
165 #[inline]
167 fn is_multichannel(&self) -> bool {
168 self.has_flag(FrameFlags::MULTICHANNEL)
169 }
170
171 #[inline]
173 fn is_encoded(&self) -> bool {
174 self.has_flag(FrameFlags::ENCODED)
175 }
176
177 #[inline]
179 fn is_last(&self) -> bool {
180 self.has_flag(FrameFlags::LAST)
181 }
182
183 #[inline]
185 fn has_params(&self) -> bool {
186 self.has_flag(FrameFlags::HAS_PARAMS)
187 }
188
189 #[inline]
191 fn has_start_timestamp(&self) -> bool {
192 self.has_flag(FrameFlags::HAS_START_TIMESTAMP)
193 }
194
195 #[inline]
197 fn is_audio(&self) -> bool {
198 self.has_flag(FrameFlags::AUDIO_STREAM)
199 }
200
201 #[inline]
203 fn is_video(&self) -> bool {
204 self.has_flag(FrameFlags::VIDEO_STREAM)
205 }
206
207 #[inline]
209 fn is_metadata(&self) -> bool {
210 self.has_flag(FrameFlags::METADATA_STREAM)
211 }
212}
213
214pub trait Live: Frame {
215 fn timestamp(&self) -> u64;
217}
218
219pub trait EncodedFrame: Frame {
220 type Param: AsRef<[u8]>;
221
222 #[inline]
224 fn dts(&self) -> u64 {
225 self.timestamp()
226 }
227
228 fn pts(&self) -> i64;
230
231 fn params(&self) -> impl Iterator<Item = &Self::Param>;
233}
234
235pub trait Multichannel: Frame {
236 fn track(&self) -> u32;
238}
239
240pub trait VideoFrame: Frame {
241 fn dimensions(&self) -> (u16, u16);
243
244 fn bit_depth(&self) -> u8;
246}