1use bytes::{Buf, BufMut, BytesMut};
2
3use crate::{InvalidInput, RtcpPacket, RtcpPacketType};
4
5#[derive(Clone)]
7pub struct ByePacket {
8 sources: Vec<u32>,
9}
10
11impl ByePacket {
12 #[inline]
17 pub fn new<T>(sources: T) -> Self
18 where
19 T: Into<Vec<u32>>,
20 {
21 let sources = sources.into();
22
23 assert!(sources.len() < 32);
24
25 Self { sources }
26 }
27
28 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
30 let header = packet.header();
31
32 let mut data = packet.stripped_payload();
33
34 if data.len() < ((header.item_count() as usize) << 2) {
35 return Err(InvalidInput);
36 }
37
38 let mut sources = Vec::with_capacity(header.item_count() as usize);
39
40 for _ in 0..header.item_count() {
41 sources.push(data.get_u32());
42 }
43
44 Ok(Self::new(sources))
45 }
46
47 pub fn encode(&self) -> RtcpPacket {
49 let mut payload = BytesMut::with_capacity(self.raw_size());
50
51 for ssrc in &self.sources {
52 payload.put_u32(*ssrc);
53 }
54
55 RtcpPacket::new(RtcpPacketType::BYE)
56 .with_item_count(self.sources.len() as u8)
57 .with_payload(payload.freeze(), 0)
58 }
59
60 #[inline]
62 pub fn sources(&self) -> &[u32] {
63 &self.sources
64 }
65
66 #[inline]
68 pub fn raw_size(&self) -> usize {
69 self.sources.len() << 2
70 }
71}