Skip to main content

rtc_rtcp/payload_feedbacks/picture_loss_indication/
mod.rs

1#[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/// The PictureLossIndication packet informs the encoder about the loss of an undefined amount of coded video data belonging to one or more pictures
17#[derive(Debug, PartialEq, Eq, Default, Clone)]
18pub struct PictureLossIndication {
19    /// SSRC of sender
20    pub sender_ssrc: u32,
21    /// SSRC where the loss was experienced
22    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    /// Header returns the Header associated with this packet.
37    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    /// destination_ssrc returns an array of SSRC values that this packet refers to.
47    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        // align to 32-bit boundary
72        l + get_padding_size(l)
73    }
74}
75
76impl Marshal for PictureLossIndication {
77    /// Marshal encodes the PictureLossIndication in binary
78    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
79        /*
80         * PLI does not require parameters.  Therefore, the length field MUST be
81         * 2, and there MUST NOT be any Feedback Control Information.
82         *
83         * The semantics of this FB message is independent of the payload type.
84         */
85        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    /// Unmarshal decodes the PictureLossIndication from binary
106    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        /*h.padding &&*/
126        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}