rtc_rtp/codec/av1/
depacketizer.rs1use bytes::{BufMut, Bytes, BytesMut};
7
8use crate::codec::av1::leb128::read_leb128;
9use crate::codec::av1::obu::{
10 OBU_HAS_SIZE_BIT, OBU_TYPE_MASK, OBU_TYPE_TEMPORAL_DELIMITER, OBU_TYPE_TILE_LIST,
11};
12use crate::packetizer::Depacketizer;
13use shared::error::{Error, Result};
14
15const AV1_Z_MASK: u8 = 0b1000_0000;
17const AV1_Y_MASK: u8 = 0b0100_0000;
18const AV1_W_MASK: u8 = 0b0011_0000;
19const AV1_N_MASK: u8 = 0b0000_1000;
20
21#[derive(Default, Debug, Clone)]
25pub struct Av1Depacketizer {
26 buffer: BytesMut,
28 pub z: bool,
30 pub y: bool,
32 pub n: bool,
34}
35
36impl Av1Depacketizer {
37 pub fn new() -> Self {
38 Self::default()
39 }
40}
41
42impl Depacketizer for Av1Depacketizer {
43 fn depacketize(&mut self, payload: &Bytes) -> Result<Bytes> {
47 if payload.len() <= 1 {
48 return Err(Error::ErrShortPacket);
49 }
50
51 let obu_z = (payload[0] & AV1_Z_MASK) != 0;
54 let obu_y = (payload[0] & AV1_Y_MASK) != 0;
55 let obu_count = (payload[0] & AV1_W_MASK) >> 4;
56 let obu_n = (payload[0] & AV1_N_MASK) != 0;
57
58 self.z = obu_z;
59 self.y = obu_y;
60 self.n = obu_n;
61
62 if obu_n {
64 self.buffer.clear();
65 }
66
67 if !obu_z && !self.buffer.is_empty() {
69 self.buffer.clear();
70 }
71
72 let mut result = BytesMut::new();
73 let mut offset = 1; let mut obu_offset = 0;
75
76 while offset < payload.len() {
77 let is_first = obu_offset == 0;
78 let is_last = obu_count != 0 && obu_offset == (obu_count - 1) as usize;
79
80 let (length_field, is_last) = if obu_count == 0 || !is_last {
82 let payload_slice = payload.slice(offset..);
84 let (len, n) = read_leb128(&payload_slice);
85 if n == 0 {
86 return Err(Error::ErrShortPacket);
87 }
88 offset += n;
89
90 let is_last_w0 = obu_count == 0 && offset + len as usize == payload.len();
92 (len as usize, is_last || is_last_w0)
93 } else {
94 (payload.len() - offset, true)
96 };
97
98 if offset + length_field > payload.len() {
99 return Err(Error::ErrShortPacket);
100 }
101
102 let obu_buffer = if is_first && obu_z {
104 if self.buffer.is_empty() {
106 if is_last {
108 break;
109 }
110 offset += length_field;
111 obu_offset += 1;
112 continue;
113 }
114
115 let mut combined = std::mem::take(&mut self.buffer);
117 combined.extend_from_slice(&payload[offset..offset + length_field]);
118 combined.freeze()
119 } else {
120 payload.slice(offset..offset + length_field)
121 };
122 offset += length_field;
123
124 if is_last && obu_y {
126 self.buffer = BytesMut::from(obu_buffer.as_ref());
127 break;
128 }
129
130 if obu_buffer.is_empty() {
132 if is_last {
133 break;
134 }
135 obu_offset += 1;
136 continue;
137 }
138
139 let obu_type = (obu_buffer[0] & OBU_TYPE_MASK) >> 3;
141
142 if obu_type == OBU_TYPE_TEMPORAL_DELIMITER || obu_type == OBU_TYPE_TILE_LIST {
144 if is_last {
145 break;
146 }
147 obu_offset += 1;
148 continue;
149 }
150
151 let has_size_field = (obu_buffer[0] & OBU_HAS_SIZE_BIT) != 0;
153 let has_extension = (obu_buffer[0] & 0x04) != 0;
154 let header_size = if has_extension { 2 } else { 1 };
155
156 if has_size_field {
157 let payload_slice = obu_buffer.slice(header_size..);
159 let (obu_size, leb_size) = read_leb128(&payload_slice);
160 if leb_size == 0 {
161 return Err(Error::ErrShortPacket);
162 }
163 let expected_size = header_size + leb_size + obu_size as usize;
164 let actual_size = if is_first && obu_z {
169 obu_buffer.len()
170 } else {
171 length_field
172 };
173 if actual_size != expected_size {
174 return Err(Error::ErrShortPacket);
175 }
176 result.extend_from_slice(&obu_buffer);
177 } else {
178 result.put_u8(obu_buffer[0] | OBU_HAS_SIZE_BIT);
181
182 if has_extension && obu_buffer.len() > 1 {
184 result.put_u8(obu_buffer[1]);
185 }
186
187 let payload_size = obu_buffer.len() - header_size;
189 write_leb128(&mut result, payload_size as u32);
190
191 if header_size < obu_buffer.len() {
193 result.extend_from_slice(&obu_buffer[header_size..]);
194 }
195 }
196
197 if is_last {
198 break;
199 }
200 obu_offset += 1;
201 }
202
203 if obu_count != 0 && obu_offset != (obu_count - 1) as usize && !self.y {
205 return Err(Error::ErrShortPacket);
206 }
207
208 Ok(result.freeze())
209 }
210
211 fn is_partition_head(&self, payload: &Bytes) -> bool {
213 if payload.is_empty() {
214 return false;
215 }
216 (payload[0] & AV1_Z_MASK) == 0
217 }
218
219 fn is_partition_tail(&self, marker: bool, _payload: &Bytes) -> bool {
221 marker
222 }
223}
224
225fn write_leb128(buf: &mut BytesMut, mut value: u32) {
227 loop {
228 let mut byte = (value & 0x7f) as u8;
229 value >>= 7;
230 if value != 0 {
231 byte |= 0x80;
232 }
233 buf.put_u8(byte);
234 if value == 0 {
235 break;
236 }
237 }
238}
239
240#[cfg(test)]
241mod tests {
242 use super::*;
243
244 #[test]
245 fn test_depacketizer_basic() {
246 let mut depacketizer = Av1Depacketizer::new();
247
248 let payload = Bytes::from(vec![
253 0x10, 0x30, 0x01, 0x02, 0x03, ]);
257
258 let result = depacketizer.depacketize(&payload).unwrap();
259 assert!(!result.is_empty());
260 assert_eq!(result[0] & OBU_HAS_SIZE_BIT, OBU_HAS_SIZE_BIT);
262 assert_eq!(result[1], 3);
264 assert_eq!(&result[2..], &[0x01, 0x02, 0x03]);
266 }
267
268 #[test]
269 fn test_depacketizer_with_w_zero() {
270 let mut depacketizer = Av1Depacketizer::new();
271
272 let payload = Bytes::from(vec![
277 0x00, 0x04, 0x30, 0x01, 0x02, 0x03, ]);
282
283 let result = depacketizer.depacketize(&payload).unwrap();
284 assert!(!result.is_empty());
285 assert_eq!(result[0] & OBU_HAS_SIZE_BIT, OBU_HAS_SIZE_BIT);
287 }
288
289 #[test]
290 fn test_is_partition_head() {
291 let depacketizer = Av1Depacketizer::new();
292
293 let payload = Bytes::from(vec![0x10, 0x30]);
295 assert!(depacketizer.is_partition_head(&payload));
296
297 let payload = Bytes::from(vec![0x90, 0x30]);
299 assert!(!depacketizer.is_partition_head(&payload));
300 }
301
302 #[test]
303 fn test_write_leb128() {
304 let mut buf = BytesMut::new();
305
306 write_leb128(&mut buf, 0);
308 assert_eq!(buf.as_ref(), &[0x00]);
309
310 buf.clear();
311 write_leb128(&mut buf, 127);
312 assert_eq!(buf.as_ref(), &[0x7f]);
313
314 buf.clear();
315 write_leb128(&mut buf, 128);
316 assert_eq!(buf.as_ref(), &[0x80, 0x01]);
317
318 buf.clear();
319 write_leb128(&mut buf, 16383);
320 assert_eq!(buf.as_ref(), &[0xff, 0x7f]);
321 }
322
323 #[test]
324 fn test_skip_temporal_delimiter() {
325 let mut depacketizer = Av1Depacketizer::new();
326
327 let payload = Bytes::from(vec![
329 0x10, 0x12, 0x00, ]);
333
334 let result = depacketizer.depacketize(&payload).unwrap();
335 assert!(result.is_empty());
337 }
338
339 #[test]
340 fn test_fragmented_obu_with_size_field() {
341 let mut depacketizer = Av1Depacketizer::new();
342
343 let mut obu = BytesMut::new();
345 obu.put_u8(0x32); let payload = vec![0xAB; 500];
347 write_leb128(&mut obu, payload.len() as u32);
348 obu.extend_from_slice(&payload);
349 let obu = obu.freeze();
350
351 let first_fragment_size = 400;
352 let p1 = Bytes::from_iter(
353 std::iter::once(0x50) .chain(obu[..first_fragment_size].iter().copied()),
355 );
356 let p2 = Bytes::from_iter(
357 std::iter::once(0x90) .chain(obu[first_fragment_size..].iter().copied()),
359 );
360
361 assert!(depacketizer.depacketize(&p1).unwrap().is_empty());
362 let result = depacketizer.depacketize(&p2).unwrap();
363 assert_eq!(result, obu);
364 }
365}