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