rtc_rtcp/transport_feedbacks/rapid_resynchronization_request/
mod.rs

1#[cfg(test)]
2mod rapid_resynchronization_request_test;
3
4use crate::{header::*, packet::*, util::*};
5use shared::{
6    error::{Error, Result},
7    marshal::{Marshal, MarshalSize, Unmarshal},
8};
9
10use bytes::{Buf, BufMut};
11use std::any::Any;
12use std::fmt;
13
14const RRR_LENGTH: usize = 2;
15const RRR_HEADER_LENGTH: usize = SSRC_LENGTH * 2;
16const RRR_MEDIA_OFFSET: usize = 4;
17
18/// The RapidResynchronizationRequest packet informs the encoder about the loss of an undefined amount of coded video data belonging to one or more pictures
19#[derive(Debug, PartialEq, Eq, Default, Clone)]
20pub struct RapidResynchronizationRequest {
21    /// SSRC of sender
22    pub sender_ssrc: u32,
23    /// SSRC of the media source
24    pub media_ssrc: u32,
25}
26
27impl fmt::Display for RapidResynchronizationRequest {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        write!(
30            f,
31            "RapidResynchronizationRequest {:x} {:x}",
32            self.sender_ssrc, self.media_ssrc
33        )
34    }
35}
36
37impl Packet for RapidResynchronizationRequest {
38    /// Header returns the Header associated with this packet.
39    fn header(&self) -> Header {
40        Header {
41            padding: get_padding_size(self.raw_size()) != 0,
42            count: FORMAT_RRR,
43            packet_type: PacketType::TransportSpecificFeedback,
44            length: ((self.marshal_size() / 4) - 1) as u16,
45        }
46    }
47
48    /// Destination SSRC returns an array of SSRC values that this packet refers to.
49    fn destination_ssrc(&self) -> Vec<u32> {
50        vec![self.media_ssrc]
51    }
52
53    fn raw_size(&self) -> usize {
54        HEADER_LENGTH + RRR_HEADER_LENGTH
55    }
56
57    fn as_any(&self) -> &dyn Any {
58        self
59    }
60
61    fn equal(&self, other: &dyn Packet) -> bool {
62        other
63            .as_any()
64            .downcast_ref::<RapidResynchronizationRequest>()
65            == Some(self)
66    }
67
68    fn cloned(&self) -> Box<dyn Packet> {
69        Box::new(self.clone())
70    }
71}
72
73impl MarshalSize for RapidResynchronizationRequest {
74    fn marshal_size(&self) -> usize {
75        let l = self.raw_size();
76        // align to 32-bit boundary
77        l + get_padding_size(l)
78    }
79}
80
81impl Marshal for RapidResynchronizationRequest {
82    /// Marshal encodes the RapidResynchronizationRequest in binary
83    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
84        /*
85         * RRR does not require parameters.  Therefore, the length field MUST be
86         * 2, and there MUST NOT be any Feedback Control Information.
87         *
88         * The semantics of this FB message is independent of the payload type.
89         */
90        if buf.remaining_mut() < self.marshal_size() {
91            return Err(Error::BufferTooShort);
92        }
93
94        let h = self.header();
95        let n = h.marshal_to(buf)?;
96        buf = &mut buf[n..];
97
98        buf.put_u32(self.sender_ssrc);
99        buf.put_u32(self.media_ssrc);
100
101        if h.padding {
102            put_padding(buf, self.raw_size());
103        }
104
105        Ok(self.marshal_size())
106    }
107}
108
109impl Unmarshal for RapidResynchronizationRequest {
110    /// Unmarshal decodes the RapidResynchronizationRequest from binary
111    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
112    where
113        Self: Sized,
114        B: Buf,
115    {
116        let raw_packet_len = raw_packet.remaining();
117        if raw_packet_len < (HEADER_LENGTH + (SSRC_LENGTH * 2)) {
118            return Err(Error::PacketTooShort);
119        }
120
121        let h = Header::unmarshal(raw_packet)?;
122
123        if h.packet_type != PacketType::TransportSpecificFeedback || h.count != FORMAT_RRR {
124            return Err(Error::WrongType);
125        }
126
127        let sender_ssrc = raw_packet.get_u32();
128        let media_ssrc = raw_packet.get_u32();
129
130        if
131        /*h.padding &&*/
132        raw_packet.has_remaining() {
133            raw_packet.advance(raw_packet.remaining());
134        }
135
136        Ok(RapidResynchronizationRequest {
137            sender_ssrc,
138            media_ssrc,
139        })
140    }
141}