xref: /xiu/protocol/rtsp/src/rtp/rtcp/rtcp_header.rs (revision 13bac29a)
1 use super::errors::RtcpError;
2 use crate::rtp::utils::Marshal;
3 use crate::rtp::utils::Unmarshal;
4 use byteorder::BigEndian;
5 use bytes::BytesMut;
6 use bytesio::bytes_reader::BytesReader;
7 use bytesio::bytes_writer::BytesWriter;
8 
9 //  0                   1                   2                   3
10 //  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
11 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 // |V=2|P|    RC   |   PT          |             length            |
13 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14 #[derive(Debug, Clone, Default)]
15 pub struct RtcpHeader {
16     pub version: u8,      // 2 bits
17     pub padding_flag: u8, // 1 bit
18     pub report_count: u8, // 5 bit
19     pub payload_type: u8, // 8 bit
20     pub length: u16,      // 16 bits
21 }
22 
23 impl Unmarshal<&mut BytesReader, Result<Self, RtcpError>> for RtcpHeader {
unmarshal(reader: &mut BytesReader) -> Result<Self, RtcpError> where Self: Sized,24     fn unmarshal(reader: &mut BytesReader) -> Result<Self, RtcpError>
25     where
26         Self: Sized,
27     {
28         let mut rtcp_header = RtcpHeader::default();
29 
30         let byte_1st: u8 = reader.read_u8()?;
31         rtcp_header.version = byte_1st >> 6;
32         rtcp_header.padding_flag = (byte_1st >> 5) & 0x01;
33         rtcp_header.report_count = byte_1st & 0x1F;
34         rtcp_header.payload_type = reader.read_u8()?;
35         rtcp_header.length = reader.read_u16::<BigEndian>()?;
36 
37         Ok(rtcp_header)
38     }
39 }
40 
41 impl Marshal<Result<BytesMut, RtcpError>> for RtcpHeader {
marshal(&self) -> Result<BytesMut, RtcpError>42     fn marshal(&self) -> Result<BytesMut, RtcpError> {
43         let mut writer = BytesWriter::default();
44 
45         let byte_1st: u8 = (self.version << 6) | (self.padding_flag << 5) | self.report_count;
46 
47         writer.write_u8(byte_1st)?;
48         writer.write_u8(self.payload_type)?;
49         writer.write_u16::<BigEndian>(self.length)?;
50 
51         Ok(writer.extract_current_bytes())
52     }
53 }
54 
55 // 88
56 // 10 0 01000
57 // 81
58 // 10 0 00001
59