rtcp/transport_feedbacks/rapid_resynchronization_request/
mod.rs

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