///|
pub(all) struct AudioLevelExtension {
level : Byte
voice : Bool
} derive(Debug, Eq)
///|
pub fn AudioLevelExtension::new(
level~ : Byte,
voice? : Bool = false,
) -> AudioLevelExtension raise RtpError {
if level > 127 {
raise InvalidExtension("RTP audio level exceeds 127")
}
{ level, voice, }
}
///|
pub fn AudioLevelExtension::level(self : AudioLevelExtension) -> Byte {
self.level
}
///|
pub fn AudioLevelExtension::voice(self : AudioLevelExtension) -> Bool {
self.voice
}
///|
pub fn AudioLevelExtension::marshal(
self : AudioLevelExtension,
) -> Bytes raise RtpError {
if self.level > 127 {
raise InvalidExtension("RTP audio level exceeds 127")
}
Bytes::from_array([self.level | (if self.voice { 0x80 } else { 0 })])
}
///|
pub fn AudioLevelExtension::unmarshal(
payload : Bytes,
) -> AudioLevelExtension raise RtpError {
if payload.length() != 1 {
raise InvalidExtension("RTP audio level extension must be one byte")
}
{ level: payload[0] & 0x7f, voice: (payload[0] & 0x80) != 0, }
}
///|
pub(all) struct TransportCcExtension {
transport_sequence : UInt16
} derive(Debug, Eq)
///|
pub fn TransportCcExtension::new(
transport_sequence~ : UInt16,
) -> TransportCcExtension {
{ transport_sequence, }
}
///|
pub fn TransportCcExtension::transport_sequence(
self : TransportCcExtension,
) -> UInt16 {
self.transport_sequence
}
///|
pub fn TransportCcExtension::marshal(self : TransportCcExtension) -> Bytes {
Bytes::from_array([
(self.transport_sequence >> 8).to_byte(),
self.transport_sequence.to_byte(),
])
}
///|
pub fn TransportCcExtension::unmarshal(
payload : Bytes,
) -> TransportCcExtension raise RtpError {
if payload.length() != 2 {
raise InvalidExtension("RTP transport-cc extension must be two bytes")
}
{
transport_sequence: ((payload[0].to_uint() << 8) | payload[1].to_uint()).to_uint16(),
}
}
///|
pub(all) struct AbsSendTimeExtension {
timestamp : UInt64
} derive(Debug, Eq)
///|
pub fn AbsSendTimeExtension::new(
send_time_ntp : UInt64,
) -> AbsSendTimeExtension {
{ timestamp: (send_time_ntp >> 14) & 0xffffffUL, }
}
///|
pub fn AbsSendTimeExtension::from_timestamp(
timestamp : UInt64,
) -> AbsSendTimeExtension raise RtpError {
if timestamp > 0xffffffUL {
raise InvalidExtension("absolute send time exceeds 24 bits")
}
{ timestamp, }
}
///|
pub fn AbsSendTimeExtension::timestamp(self : AbsSendTimeExtension) -> UInt64 {
self.timestamp
}
///|
pub fn AbsSendTimeExtension::estimate(
self : AbsSendTimeExtension,
receive_ntp : UInt64,
) -> UInt64 {
let mut ntp = (receive_ntp & 0xffffffc000000000UL) |
((self.timestamp & 0xffffffUL) << 14)
if receive_ntp < ntp {
ntp -= 0x1000000UL << 14
}
ntp
}
///|
pub fn AbsSendTimeExtension::marshal(
self : AbsSendTimeExtension,
) -> Bytes raise RtpError {
if self.timestamp > 0xffffffUL {
raise InvalidExtension("absolute send time exceeds 24 bits")
}
Bytes::from_array([
(self.timestamp >> 16).to_byte(),
(self.timestamp >> 8).to_byte(),
self.timestamp.to_byte(),
])
}
///|
pub fn AbsSendTimeExtension::unmarshal(
payload : Bytes,
) -> AbsSendTimeExtension raise RtpError {
if payload.length() != 3 {
raise InvalidExtension("absolute send time extension must be three bytes")
}
{
timestamp: (payload[0].to_uint64() << 16) |
(payload[1].to_uint64() << 8) |
payload[2].to_uint64(),
}
}
///|
pub(all) struct PlayoutDelayExtension {
min_delay : UInt16
max_delay : UInt16
} derive(Debug, Eq)
///|
pub fn PlayoutDelayExtension::new(
min_delay~ : UInt16,
max_delay~ : UInt16,
) -> PlayoutDelayExtension raise RtpError {
if min_delay > 0x0fff || max_delay > 0x0fff {
raise InvalidExtension("RTP playout delay exceeds 12 bits")
}
if min_delay > max_delay {
raise InvalidExtension("minimum playout delay exceeds maximum")
}
{ min_delay, max_delay, }
}
///|
pub fn PlayoutDelayExtension::min_delay(self : PlayoutDelayExtension) -> UInt16 {
self.min_delay
}
///|
pub fn PlayoutDelayExtension::max_delay(self : PlayoutDelayExtension) -> UInt16 {
self.max_delay
}
///|
pub fn PlayoutDelayExtension::marshal(
self : PlayoutDelayExtension,
) -> Bytes raise RtpError {
ignore(
PlayoutDelayExtension::new(
min_delay=self.min_delay,
max_delay=self.max_delay,
),
)
Bytes::from_array([
(self.min_delay >> 4).to_byte(),
((self.min_delay << 4) | (self.max_delay >> 8)).to_byte(),
self.max_delay.to_byte(),
])
}
///|
pub fn PlayoutDelayExtension::unmarshal(
payload : Bytes,
) -> PlayoutDelayExtension raise RtpError {
if payload.length() != 3 {
raise InvalidExtension("RTP playout delay extension must be three bytes")
}
let min_delay = ((payload[0].to_uint() << 4) | (payload[1].to_uint() >> 4)).to_uint16()
let max_delay = (((payload[1].to_uint() & 0x0f) << 8) | payload[2].to_uint()).to_uint16()
PlayoutDelayExtension::new(min_delay~, max_delay~)
}
///|
pub(all) enum CameraDirection {
Front
Back
} derive(Debug, Eq)
///|
pub(all) enum VideoRotation {
Degree0
Degree90
Degree180
Degree270
} derive(Debug, Eq)
///|
pub(all) struct VideoOrientationExtension {
direction : CameraDirection
flip : Bool
rotation : VideoRotation
} derive(Debug, Eq)
///|
pub fn VideoOrientationExtension::new(
direction? : CameraDirection = Front,
flip? : Bool = false,
rotation? : VideoRotation = Degree0,
) -> VideoOrientationExtension {
{ direction, flip, rotation, }
}
///|
pub fn VideoOrientationExtension::direction(
self : VideoOrientationExtension,
) -> CameraDirection {
self.direction
}
///|
pub fn VideoOrientationExtension::flip(
self : VideoOrientationExtension,
) -> Bool {
self.flip
}
///|
pub fn VideoOrientationExtension::rotation(
self : VideoOrientationExtension,
) -> VideoRotation {
self.rotation
}
///|
pub fn VideoOrientationExtension::marshal(
self : VideoOrientationExtension,
) -> Bytes {
let direction = match self.direction {
Front => 0
Back => 0x08
}
let rotation = match self.rotation {
Degree0 => 0
Degree90 => 1
Degree180 => 2
Degree270 => 3
}
Bytes::from_array([
(direction | (if self.flip { 0x04 } else { 0 }) | rotation).to_byte(),
])
}
///|
pub fn VideoOrientationExtension::unmarshal(
payload : Bytes,
) -> VideoOrientationExtension raise RtpError {
if payload.length() != 1 {
raise InvalidExtension("video orientation extension must be one byte")
}
if (payload[0] & 0xf0) != 0 {
raise InvalidExtension("video orientation reserved bits are nonzero")
}
let direction = if (payload[0] & 0x08) == 0 { Front } else { Back }
let rotation = match payload[0] & 0x03 {
0 => Degree0
1 => Degree90
2 => Degree180
_ => Degree270
}
{ direction, flip: (payload[0] & 0x04) != 0, rotation, }
}