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