rtp/extension/playout_delay_extension/
mod.rs

1#[cfg(test)]
2mod playout_delay_extension_test;
3
4use bytes::BufMut;
5use util::marshal::{Marshal, MarshalSize, Unmarshal};
6
7use crate::error::Error;
8
9pub const PLAYOUT_DELAY_EXTENSION_SIZE: usize = 3;
10pub const PLAYOUT_DELAY_MAX_VALUE: u16 = (1 << 12) - 1;
11
12/// PlayoutDelayExtension is an extension payload format described in
13/// http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
14/// 0                   1                   2                   3
15/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
16/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17/// |  ID   | len=2 |       MIN delay       |       MAX delay       |
18/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19#[derive(PartialEq, Eq, Debug, Default, Copy, Clone)]
20pub struct PlayoutDelayExtension {
21    pub min_delay: u16,
22    pub max_delay: u16,
23}
24
25impl Unmarshal for PlayoutDelayExtension {
26    /// Unmarshal parses the passed byte slice and stores the result in the members.
27    fn unmarshal<B>(buf: &mut B) -> util::Result<Self>
28    where
29        Self: Sized,
30        B: bytes::Buf,
31    {
32        if buf.remaining() < PLAYOUT_DELAY_EXTENSION_SIZE {
33            return Err(Error::ErrBufferTooSmall.into());
34        }
35
36        let b0 = buf.get_u8();
37        let b1 = buf.get_u8();
38        let b2 = buf.get_u8();
39
40        let min_delay = u16::from_be_bytes([b0, b1]) >> 4;
41        let max_delay = u16::from_be_bytes([b1, b2]) & 0x0FFF;
42
43        Ok(PlayoutDelayExtension {
44            min_delay,
45            max_delay,
46        })
47    }
48}
49
50impl MarshalSize for PlayoutDelayExtension {
51    /// MarshalSize returns the size of the PlayoutDelayExtension once marshaled.
52    fn marshal_size(&self) -> usize {
53        PLAYOUT_DELAY_EXTENSION_SIZE
54    }
55}
56
57impl Marshal for PlayoutDelayExtension {
58    /// MarshalTo serializes the members to buffer
59    fn marshal_to(&self, mut buf: &mut [u8]) -> util::Result<usize> {
60        if buf.remaining_mut() < PLAYOUT_DELAY_EXTENSION_SIZE {
61            return Err(Error::ErrBufferTooSmall.into());
62        }
63        if self.min_delay > PLAYOUT_DELAY_MAX_VALUE || self.max_delay > PLAYOUT_DELAY_MAX_VALUE {
64            return Err(Error::PlayoutDelayOverflow.into());
65        }
66
67        buf.put_u8((self.min_delay >> 4) as u8);
68        buf.put_u8(((self.min_delay << 4) as u8) | (self.max_delay >> 8) as u8);
69        buf.put_u8(self.max_delay as u8);
70
71        Ok(PLAYOUT_DELAY_EXTENSION_SIZE)
72    }
73}
74
75impl PlayoutDelayExtension {
76    pub fn new(min_delay: u16, max_delay: u16) -> Self {
77        PlayoutDelayExtension {
78            min_delay,
79            max_delay,
80        }
81    }
82}