rtc_rtcp/payload_feedbacks/picture_loss_indication/
mod.rs1#[cfg(test)]
2mod picture_loss_indication_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 PLI_LENGTH: usize = 2;
15
16#[derive(Debug, PartialEq, Eq, Default, Clone)]
18pub struct PictureLossIndication {
19 pub sender_ssrc: u32,
21 pub media_ssrc: u32,
23}
24
25impl fmt::Display for PictureLossIndication {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 write!(
28 f,
29 "PictureLossIndication {:x} {:x}",
30 self.sender_ssrc, self.media_ssrc
31 )
32 }
33}
34
35impl Packet for PictureLossIndication {
36 fn header(&self) -> Header {
38 Header {
39 padding: get_padding_size(self.raw_size()) != 0,
40 count: FORMAT_PLI,
41 packet_type: PacketType::PayloadSpecificFeedback,
42 length: ((self.marshal_size() / 4) - 1) as u16,
43 }
44 }
45
46 fn destination_ssrc(&self) -> Vec<u32> {
48 vec![self.media_ssrc]
49 }
50
51 fn raw_size(&self) -> usize {
52 HEADER_LENGTH + SSRC_LENGTH * 2
53 }
54
55 fn as_any(&self) -> &dyn Any {
56 self
57 }
58
59 fn equal(&self, other: &dyn Packet) -> bool {
60 other.as_any().downcast_ref::<PictureLossIndication>() == Some(self)
61 }
62
63 fn cloned(&self) -> Box<dyn Packet> {
64 Box::new(self.clone())
65 }
66}
67
68impl MarshalSize for PictureLossIndication {
69 fn marshal_size(&self) -> usize {
70 let l = self.raw_size();
71 l + get_padding_size(l)
73 }
74}
75
76impl Marshal for PictureLossIndication {
77 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
79 if buf.remaining_mut() < self.marshal_size() {
86 return Err(Error::BufferTooShort);
87 }
88
89 let h = self.header();
90 let n = h.marshal_to(buf)?;
91 buf = &mut buf[n..];
92
93 buf.put_u32(self.sender_ssrc);
94 buf.put_u32(self.media_ssrc);
95
96 if h.padding {
97 put_padding(buf, self.raw_size());
98 }
99
100 Ok(self.marshal_size())
101 }
102}
103
104impl Unmarshal for PictureLossIndication {
105 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
107 where
108 Self: Sized,
109 B: Buf,
110 {
111 let raw_packet_len = raw_packet.remaining();
112 if raw_packet_len < (HEADER_LENGTH + (SSRC_LENGTH * 2)) {
113 return Err(Error::PacketTooShort);
114 }
115
116 let h = Header::unmarshal(raw_packet)?;
117 if h.packet_type != PacketType::PayloadSpecificFeedback || h.count != FORMAT_PLI {
118 return Err(Error::WrongType);
119 }
120
121 let sender_ssrc = raw_packet.get_u32();
122 let media_ssrc = raw_packet.get_u32();
123
124 if
125 raw_packet.has_remaining() {
127 raw_packet.advance(raw_packet.remaining());
128 }
129
130 Ok(PictureLossIndication {
131 sender_ssrc,
132 media_ssrc,
133 })
134 }
135}