use bytes::{Buf, BufMut, BytesMut};
use crate::{InvalidInput, RtcpPacket, RtcpPacketType};
#[derive(Clone)]
pub struct ByePacket {
sources: Vec<u32>,
}
impl ByePacket {
#[inline]
pub fn new<T>(sources: T) -> Self
where
T: Into<Vec<u32>>,
{
let sources = sources.into();
assert!(sources.len() < 32);
Self { sources }
}
pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
let header = packet.header();
let mut data = packet.stripped_payload();
if data.len() < ((header.item_count() as usize) << 2) {
return Err(InvalidInput::new());
}
let mut sources = Vec::with_capacity(header.item_count() as usize);
for _ in 0..header.item_count() {
sources.push(data.get_u32());
}
Ok(Self::new(sources))
}
pub fn encode(&self) -> RtcpPacket {
let mut payload = BytesMut::with_capacity(self.raw_size());
for ssrc in &self.sources {
payload.put_u32(*ssrc);
}
RtcpPacket::new(RtcpPacketType::BYE)
.with_item_count(self.sources.len() as u8)
.with_payload(payload.freeze(), 0)
}
#[inline]
pub fn sources(&self) -> &[u32] {
&self.sources
}
#[inline]
pub fn raw_size(&self) -> usize {
self.sources.len() << 2
}
}