1 #[cfg(test)]
2 mod audio_level_extension_test;
3 
4 use crate::error::Error;
5 use serde::{Deserialize, Serialize};
6 use util::marshal::{Marshal, MarshalSize, Unmarshal};
7 
8 use bytes::{Buf, BufMut};
9 
10 // AUDIO_LEVEL_EXTENSION_SIZE One byte header size
11 pub const AUDIO_LEVEL_EXTENSION_SIZE: usize = 1;
12 
13 /// AudioLevelExtension is a extension payload format described in
14 /// https://tools.ietf.org/html/rfc6464
15 ///
16 /// Implementation based on:
17 /// https://chromium.googlesource.com/external/webrtc/+/e2a017725570ead5946a4ca8235af27470ca0df9/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc#49
18 ///
19 /// One byte format:
20 /// 0                   1
21 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
22 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23 /// |  ID   | len=0 |V| level       |
24 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25 ///
26 /// Two byte format:
27 /// 0                   1                   2                   3
28 /// 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
29 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 /// |      ID       |     len=1     |V|    level    |    0 (pad)    |
31 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 #[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Serialize, Deserialize)]
33 pub struct AudioLevelExtension {
34     pub level: u8,
35     pub voice: bool,
36 }
37 
38 impl Unmarshal for AudioLevelExtension {
39     /// Unmarshal parses the passed byte slice and stores the result in the members
unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error> where Self: Sized, B: Buf,40     fn unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error>
41     where
42         Self: Sized,
43         B: Buf,
44     {
45         if raw_packet.remaining() < AUDIO_LEVEL_EXTENSION_SIZE {
46             return Err(Error::ErrBufferTooSmall.into());
47         }
48 
49         let b = raw_packet.get_u8();
50 
51         Ok(AudioLevelExtension {
52             level: b & 0x7F,
53             voice: (b & 0x80) != 0,
54         })
55     }
56 }
57 
58 impl MarshalSize for AudioLevelExtension {
59     /// MarshalSize returns the size of the AudioLevelExtension once marshaled.
marshal_size(&self) -> usize60     fn marshal_size(&self) -> usize {
61         AUDIO_LEVEL_EXTENSION_SIZE
62     }
63 }
64 
65 impl Marshal for AudioLevelExtension {
66     /// MarshalTo serializes the members to buffer
marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error>67     fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error> {
68         if buf.remaining_mut() < AUDIO_LEVEL_EXTENSION_SIZE {
69             return Err(Error::ErrBufferTooSmall.into());
70         }
71         if self.level > 127 {
72             return Err(Error::AudioLevelOverflow.into());
73         }
74         let voice = if self.voice { 0x80u8 } else { 0u8 };
75 
76         buf.put_u8(voice | self.level);
77 
78         Ok(AUDIO_LEVEL_EXTENSION_SIZE)
79     }
80 }
81