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