rtc_rtp/codecs/vp9/
mod.rs1#[cfg(test)]
2mod vp9_test;
3
4use crate::packetizer::{Depacketizer, Payloader};
5use shared::error::{Error, Result};
6
7use bytes::{Buf, BufMut, Bytes, BytesMut};
8use std::fmt;
9use std::sync::Arc;
10
11const VP9HEADER_SIZE: usize = 3;
13const MAX_SPATIAL_LAYERS: u8 = 5;
14const MAX_VP9REF_PICS: usize = 3;
15
16pub type InitialPictureIDFn = Arc<dyn (Fn() -> u16)>;
18
19#[derive(Default, Clone)]
21pub struct Vp9Payloader {
22 picture_id: u16,
23 initialized: bool,
24
25 pub initial_picture_id_fn: Option<InitialPictureIDFn>,
26}
27
28impl fmt::Debug for Vp9Payloader {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 f.debug_struct("Vp9Payloader")
31 .field("picture_id", &self.picture_id)
32 .field("initialized", &self.initialized)
33 .finish()
34 }
35}
36
37impl Payloader for Vp9Payloader {
38 fn payload(&mut self, mtu: usize, payload: &Bytes) -> Result<Vec<Bytes>> {
40 if payload.is_empty() || mtu == 0 {
79 return Ok(vec![]);
80 }
81
82 if !self.initialized {
83 if self.initial_picture_id_fn.is_none() {
84 self.initial_picture_id_fn =
85 Some(Arc::new(|| -> u16 { rand::random::<u16>() & 0x7FFF }));
86 }
87 self.picture_id = if let Some(f) = &self.initial_picture_id_fn {
88 f()
89 } else {
90 0
91 };
92 self.initialized = true;
93 }
94
95 let max_fragment_size = mtu as isize - VP9HEADER_SIZE as isize;
96 let mut payloads = vec![];
97 let mut payload_data_remaining = payload.len();
98 let mut payload_data_index = 0;
99
100 if std::cmp::min(max_fragment_size, payload_data_remaining as isize) <= 0 {
101 return Ok(vec![]);
102 }
103
104 while payload_data_remaining > 0 {
105 let current_fragment_size =
106 std::cmp::min(max_fragment_size as usize, payload_data_remaining);
107 let mut out = BytesMut::with_capacity(VP9HEADER_SIZE + current_fragment_size);
108 let mut buf = [0u8; VP9HEADER_SIZE];
109 buf[0] = 0x90; if payload_data_index == 0 {
111 buf[0] |= 0x08; }
113 if payload_data_remaining == current_fragment_size {
114 buf[0] |= 0x04; }
116 buf[1] = (self.picture_id >> 8) as u8 | 0x80;
117 buf[2] = (self.picture_id & 0xFF) as u8;
118
119 out.put(&buf[..]);
120
121 out.put(
122 &*payload.slice(payload_data_index..payload_data_index + current_fragment_size),
123 );
124
125 payloads.push(out.freeze());
126
127 payload_data_remaining -= current_fragment_size;
128 payload_data_index += current_fragment_size;
129 }
130
131 self.picture_id += 1;
132 self.picture_id &= 0x7FFF;
133
134 Ok(payloads)
135 }
136
137 fn clone_to(&self) -> Box<dyn Payloader> {
138 Box::new(self.clone())
139 }
140}
141
142#[derive(PartialEq, Eq, Debug, Default, Clone)]
144pub struct Vp9Packet {
145 pub i: bool,
147 pub p: bool,
149 pub l: bool,
151 pub f: bool,
153 pub b: bool,
155 pub e: bool,
157 pub v: bool,
159 pub z: bool,
161
162 pub picture_id: u16,
165
166 pub tid: u8,
169 pub u: bool,
171 pub sid: u8,
173 pub d: bool,
175
176 pub pdiff: Vec<u8>,
179 pub tl0picidx: u8,
181
182 pub ns: u8,
185 pub y: bool,
187 pub g: bool,
189 pub ng: u8,
191 pub width: Vec<u16>,
192 pub height: Vec<u16>,
193 pub pgtid: Vec<u8>,
195 pub pgu: Vec<bool>,
197 pub pgpdiff: Vec<Vec<u8>>,
199}
200
201impl Depacketizer for Vp9Packet {
202 fn depacketize(&mut self, packet: &Bytes) -> Result<Bytes> {
204 if packet.is_empty() {
205 return Err(Error::ErrShortPacket);
206 }
207
208 let reader = &mut packet.clone();
209 let b = reader.get_u8();
210
211 self.i = (b & 0x80) != 0;
212 self.p = (b & 0x40) != 0;
213 self.l = (b & 0x20) != 0;
214 self.f = (b & 0x10) != 0;
215 self.b = (b & 0x08) != 0;
216 self.e = (b & 0x04) != 0;
217 self.v = (b & 0x02) != 0;
218 self.z = (b & 0x01) != 0;
219
220 let mut payload_index = 1;
221
222 if self.i {
223 payload_index = self.parse_picture_id(reader, payload_index)?;
224 }
225
226 if self.l {
227 payload_index = self.parse_layer_info(reader, payload_index)?;
228 }
229
230 if self.f && self.p {
231 payload_index = self.parse_ref_indices(reader, payload_index)?;
232 }
233
234 if self.v {
235 payload_index = self.parse_ssdata(reader, payload_index)?;
236 }
237
238 Ok(packet.slice(payload_index..))
239 }
240
241 fn is_partition_head(&self, payload: &Bytes) -> bool {
243 if payload.is_empty() {
244 false
245 } else {
246 (payload[0] & 0x08) != 0
247 }
248 }
249
250 fn is_partition_tail(&self, marker: bool, _payload: &Bytes) -> bool {
251 marker
252 }
253}
254
255impl Vp9Packet {
256 fn parse_picture_id(
265 &mut self,
266 reader: &mut dyn Buf,
267 mut payload_index: usize,
268 ) -> Result<usize> {
269 if reader.remaining() == 0 {
270 return Err(Error::ErrShortPacket);
271 }
272 let b = reader.get_u8();
273 payload_index += 1;
274 if (b & 0x80) != 0 {
276 if reader.remaining() == 0 {
277 return Err(Error::ErrShortPacket);
278 }
279 self.picture_id = (((b & 0x7f) as u16) << 8) | (reader.get_u8() as u16);
281 payload_index += 1;
282 } else {
283 self.picture_id = (b & 0x7F) as u16;
284 }
285
286 Ok(payload_index)
287 }
288
289 fn parse_layer_info(
290 &mut self,
291 reader: &mut dyn Buf,
292 mut payload_index: usize,
293 ) -> Result<usize> {
294 payload_index = self.parse_layer_info_common(reader, payload_index)?;
295
296 if self.f {
297 Ok(payload_index)
298 } else {
299 self.parse_layer_info_non_flexible_mode(reader, payload_index)
300 }
301 }
302
303 fn parse_layer_info_common(
310 &mut self,
311 reader: &mut dyn Buf,
312 mut payload_index: usize,
313 ) -> Result<usize> {
314 if reader.remaining() == 0 {
315 return Err(Error::ErrShortPacket);
316 }
317 let b = reader.get_u8();
318 payload_index += 1;
319
320 self.tid = b >> 5;
321 self.u = b & 0x10 != 0;
322 self.sid = (b >> 1) & 0x7;
323 self.d = b & 0x01 != 0;
324
325 if self.sid >= MAX_SPATIAL_LAYERS {
326 Err(Error::ErrTooManySpatialLayers)
327 } else {
328 Ok(payload_index)
329 }
330 }
331
332 fn parse_layer_info_non_flexible_mode(
341 &mut self,
342 reader: &mut dyn Buf,
343 mut payload_index: usize,
344 ) -> Result<usize> {
345 if reader.remaining() == 0 {
346 return Err(Error::ErrShortPacket);
347 }
348 self.tl0picidx = reader.get_u8();
349 payload_index += 1;
350 Ok(payload_index)
351 }
352
353 fn parse_ref_indices(
361 &mut self,
362 reader: &mut dyn Buf,
363 mut payload_index: usize,
364 ) -> Result<usize> {
365 let mut b = 1u8;
366 while (b & 0x1) != 0 {
367 if reader.remaining() == 0 {
368 return Err(Error::ErrShortPacket);
369 }
370 b = reader.get_u8();
371 payload_index += 1;
372
373 self.pdiff.push(b >> 1);
374 if self.pdiff.len() >= MAX_VP9REF_PICS {
375 return Err(Error::ErrTooManyPDiff);
376 }
377 }
378
379 Ok(payload_index)
380 }
381
382 fn parse_ssdata(&mut self, reader: &mut dyn Buf, mut payload_index: usize) -> Result<usize> {
403 if reader.remaining() == 0 {
404 return Err(Error::ErrShortPacket);
405 }
406
407 let b = reader.get_u8();
408 payload_index += 1;
409
410 self.ns = b >> 5;
411 self.y = b & 0x10 != 0;
412 self.g = (b >> 1) & 0x7 != 0;
413
414 let ns = (self.ns + 1) as usize;
415 self.ng = 0;
416
417 if self.y {
418 if reader.remaining() < 4 * ns {
419 return Err(Error::ErrShortPacket);
420 }
421
422 self.width = vec![0u16; ns];
423 self.height = vec![0u16; ns];
424 for i in 0..ns {
425 self.width[i] = reader.get_u16();
426 self.height[i] = reader.get_u16();
427 }
428 payload_index += 4 * ns;
429 }
430
431 if self.g {
432 if reader.remaining() == 0 {
433 return Err(Error::ErrShortPacket);
434 }
435
436 self.ng = reader.get_u8();
437 payload_index += 1;
438 }
439
440 for i in 0..self.ng as usize {
441 if reader.remaining() == 0 {
442 return Err(Error::ErrShortPacket);
443 }
444 let b = reader.get_u8();
445 payload_index += 1;
446
447 self.pgtid.push(b >> 5);
448 self.pgu.push(b & 0x10 != 0);
449
450 let r = ((b >> 2) & 0x3) as usize;
451 if reader.remaining() < r {
452 return Err(Error::ErrShortPacket);
453 }
454
455 self.pgpdiff.push(vec![]);
456 for _ in 0..r {
457 let b = reader.get_u8();
458 payload_index += 1;
459
460 self.pgpdiff[i].push(b);
461 }
462 }
463
464 Ok(payload_index)
465 }
466}