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