rtp_parse/rtcp/
rtcp_packet.rs1use std::fmt::LowerHex;
2
3use anyhow::{anyhow, bail, Context, Result};
4
5use crate::{
6 rtcp::{
7 rtcp_bye::read_rtcp_bye,
8 rtcp_fb_nack::read_rtcp_fb_nack,
9 rtcp_fb_tcc::{read_rtcp_fb_tcc, RtcpFbTccPacket},
10 rtcp_header::read_rtcp_header,
11 },
12 PacketBuffer,
13};
14
15use super::{
16 rtcp_bye::RtcpByePacket,
17 rtcp_fb_fir::{read_rtcp_fb_fir, RtcpFbFirPacket},
18 rtcp_fb_header::read_rtcp_fb_header,
19 rtcp_fb_nack::RtcpFbNackPacket,
20 rtcp_fb_packet::{RtcpFbPsPacket, RtcpFbTlPacket},
21 rtcp_fb_pli::{read_rtcp_fb_pli, RtcpFbPliPacket},
22 rtcp_header::RtcpHeader,
23 rtcp_rr::{read_rtcp_rr, RtcpRrPacket},
24 rtcp_sdes::{read_rtcp_sdes, RtcpSdesPacket},
25 rtcp_sr::{read_rtcp_sr, RtcpSrPacket},
26};
27
28#[derive(Debug)]
29pub enum SomeRtcpPacket {
30 CompoundRtcpPacket(Vec<SomeRtcpPacket>),
31 RtcpByePacket(RtcpByePacket),
32 RtcpSrPacket(RtcpSrPacket),
33 RtcpRrPacket(RtcpRrPacket),
34 RtcpSdesPacket(RtcpSdesPacket),
35 RtcpFbNackPacket(RtcpFbNackPacket),
36 RtcpFbFirPacket(RtcpFbFirPacket),
37 RtcpFbTccPacket(RtcpFbTccPacket),
38 RtcpFbPliPacket(RtcpFbPliPacket),
39 UnknownRtcpPacket {
40 header: RtcpHeader,
41 payload: Vec<u8>,
42 },
43}
44
45pub fn parse_rtcp_packet<B: PacketBuffer + LowerHex>(buf: &mut B) -> Result<SomeRtcpPacket> {
46 let mut packets: Vec<SomeRtcpPacket> = Vec::new();
47
48 let mut sub_packet_num = 1;
49 while buf.bytes_remaining() >= RtcpHeader::SIZE_BYTES {
51 let packet = parse_single_rtcp_packet(buf)
52 .with_context(|| format!("sub packet {sub_packet_num}"))?;
53 packets.push(packet);
54 sub_packet_num += 1;
55 }
56
57 match packets.len() {
58 0 => Err(anyhow!("No valid packets found")),
59 1 => Ok(packets.remove(0)),
60 _ => Ok(SomeRtcpPacket::CompoundRtcpPacket(packets)),
61 }
62}
63
64pub fn parse_single_rtcp_packet<B: PacketBuffer>(buf: &mut B) -> Result<SomeRtcpPacket> {
65 let header = read_rtcp_header(buf).context("rtcp header")?;
67 let payload_length = header
68 .payload_length_bytes()
69 .context("header length field")? as usize;
70 if payload_length > buf.bytes_remaining() {
71 bail!("Invalid RTCP packet, length {payload_length} bytes but buf has only {} bytes remaining", buf.bytes_remaining());
72 }
73 let payload_length_bits = payload_length * 8;
74 let mut payload_buffer = buf.sub_buffer(0..(payload_length * 8));
75
76 let result = match header.packet_type {
77 RtcpByePacket::PT => Ok(SomeRtcpPacket::RtcpByePacket(
78 read_rtcp_bye(&mut payload_buffer, header).context("rtcp bye")?,
79 )),
80 RtcpSrPacket::PT => Ok(SomeRtcpPacket::RtcpSrPacket(
81 read_rtcp_sr(&mut payload_buffer, header).context("rtcp sr")?,
82 )),
83 RtcpRrPacket::PT => Ok(SomeRtcpPacket::RtcpRrPacket(
84 read_rtcp_rr(&mut payload_buffer, header).context("rtcp sr")?,
85 )),
86 RtcpSdesPacket::PT => Ok(SomeRtcpPacket::RtcpSdesPacket(
87 read_rtcp_sdes(&mut payload_buffer, header).context("rtcp sdes")?,
88 )),
89 RtcpFbPsPacket::PT | RtcpFbTlPacket::PT => {
90 let fb_header = read_rtcp_fb_header(&mut payload_buffer).context("fb header")?;
91 match (header.packet_type, header.report_count) {
92 (RtcpFbPsPacket::PT, RtcpFbFirPacket::FMT) => Ok(SomeRtcpPacket::RtcpFbFirPacket(
93 read_rtcp_fb_fir(&mut payload_buffer, header, fb_header)
94 .context("rtcp fb fir")?,
95 )),
96 (RtcpFbPsPacket::PT, RtcpFbPliPacket::FMT) => Ok(SomeRtcpPacket::RtcpFbPliPacket(
97 read_rtcp_fb_pli(&mut payload_buffer, header, fb_header)
98 .context("rtcp fb pli")?,
99 )),
100 (RtcpFbTlPacket::PT, RtcpFbTccPacket::FMT) => Ok(SomeRtcpPacket::RtcpFbTccPacket(
101 read_rtcp_fb_tcc(&mut payload_buffer, header, fb_header)
102 .context("rtcp fb tcc")?,
103 )),
104 (RtcpFbTlPacket::PT, RtcpFbNackPacket::FMT) => {
105 Ok(SomeRtcpPacket::RtcpFbNackPacket(
106 read_rtcp_fb_nack(&mut payload_buffer, header, fb_header)
107 .context("rtcp fb nack")?,
108 ))
109 }
110 (pt, fmt) => bail!("Unsuppsorted RTCP FB packet, pt {pt} fmt {fmt}"),
111 }
112 }
113 pt => bail!("Unsupported packet type {pt}"),
114 };
115 drop(payload_buffer);
116 if result.is_ok() {
117 buf.seek(std::io::SeekFrom::Current(payload_length_bits as i64))?;
118 }
119 result
120}