Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit e359327

Browse files
author
Rain Liu
committed
add rle
1 parent 460da8d commit e359327

File tree

3 files changed

+104
-72
lines changed

3 files changed

+104
-72
lines changed

src/extended_report/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
mod extended_report_test;
33

44
pub mod dlrr;
5-
pub mod prt; /*
6-
pub mod rle;
5+
pub mod prt;
6+
pub mod rle; /*
77
pub mod rrt;
88
pub mod ssr;
99
pub mod vm;*/

src/extended_report/prt.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::*;
22

3-
const PACKET_RECEIPT_TIMES_REPORT_BLOCK_MIN_LENGTH: u16 = 9;
3+
const PRT_REPORT_BLOCK_MIN_LENGTH: u16 = 9;
44

55
/// PacketReceiptTimesReportBlock represents a Packet Receipt Times
66
/// report block, as described in RFC 3611 section 4.3.
@@ -58,9 +58,7 @@ impl Packet for PacketReceiptTimesReportBlock {
5858
}
5959

6060
fn raw_size(&self) -> usize {
61-
XR_HEADER_LENGTH
62-
+ PACKET_RECEIPT_TIMES_REPORT_BLOCK_MIN_LENGTH as usize
63-
+ self.receipt_time.len() * 4
61+
XR_HEADER_LENGTH + PRT_REPORT_BLOCK_MIN_LENGTH as usize + self.receipt_time.len() * 4
6462
}
6563

6664
fn as_any(&self) -> &(dyn Any + Send + Sync) {
@@ -119,8 +117,8 @@ impl Unmarshal for PacketReceiptTimesReportBlock {
119117

120118
let xr_header = XRHeader::unmarshal(raw_packet)?;
121119

122-
if xr_header.block_length < PACKET_RECEIPT_TIMES_REPORT_BLOCK_MIN_LENGTH
123-
|| (xr_header.block_length - PACKET_RECEIPT_TIMES_REPORT_BLOCK_MIN_LENGTH) % 4 != 0
120+
if xr_header.block_length < PRT_REPORT_BLOCK_MIN_LENGTH
121+
|| (xr_header.block_length - PRT_REPORT_BLOCK_MIN_LENGTH) % 4 != 0
124122
|| raw_packet.remaining() < xr_header.block_length as usize
125123
{
126124
return Err(error::Error::PacketTooShort.into());
@@ -131,7 +129,7 @@ impl Unmarshal for PacketReceiptTimesReportBlock {
131129
let begin_seq = raw_packet.get_u16();
132130
let end_seq = raw_packet.get_u16();
133131

134-
let remaining = xr_header.block_length - PACKET_RECEIPT_TIMES_REPORT_BLOCK_MIN_LENGTH;
132+
let remaining = xr_header.block_length - PRT_REPORT_BLOCK_MIN_LENGTH;
135133
let mut receipt_time = vec![];
136134
for _ in 0..remaining / 4 {
137135
receipt_time.push(raw_packet.get_u32());

src/extended_report/rle.rs

Lines changed: 97 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use super::*;
22

3+
const RLE_REPORT_BLOCK_MIN_LENGTH: u16 = 9;
4+
35
/// ChunkType enumerates the three kinds of chunks described in RFC 3611 section 4.1.
46
#[derive(Debug, Copy, Clone, PartialEq)]
57
pub enum ChunkType {
@@ -46,7 +48,6 @@ impl fmt::Display for Chunk {
4648
}
4749
ChunkType::BitVector => write!(f, "[BitVector {:#b}", self.value()),
4850
ChunkType::TerminatingNull => write!(f, "[TerminatingNull]"),
49-
//_ => write!(f, "[{:#x}]", self.0),
5051
}
5152
}
5253
}
@@ -78,7 +79,6 @@ impl Chunk {
7879
ChunkType::RunLength => self.0 & 0x3FFF,
7980
ChunkType::BitVector => self.0 & 0x7FFF,
8081
ChunkType::TerminatingNull => 0,
81-
//_ => self.0,
8282
}
8383
}
8484
}
@@ -103,107 +103,141 @@ impl Chunk {
103103
/// | chunk n-1 | chunk n |
104104
/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105105
#[derive(Debug, Default, PartialEq, Clone)]
106-
pub struct RleReportBlock {
107-
pub xr_header: XRHeader,
106+
pub struct RLEReportBlock {
107+
pub is_loss_rle: bool,
108108
pub t: u8,
109109
pub ssrc: u32,
110110
pub begin_seq: u16,
111111
pub end_seq: u16,
112112
pub chunks: Vec<Chunk>,
113113
}
114114

115-
impl RleReportBlock {
116-
fn raw_size(&self) -> usize {
117-
4 + 1 + 4 + 2 + 2 + self.chunks.len() * 2
118-
}
119-
}
120-
121115
/// LossRLEReportBlock is used to report information about packet
122116
/// losses, as described in RFC 3611, section 4.1
123-
#[derive(Debug, Default, PartialEq, Clone)]
124-
pub struct LossRLEReportBlock(pub RleReportBlock);
117+
/// make sure to set is_loss_rle = true
118+
pub type LossRLEReportBlock = RLEReportBlock;
125119

126-
impl fmt::Display for LossRLEReportBlock {
127-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128-
write!(f, "{:?}", self)
120+
/// DuplicateRLEReportBlock is used to report information about packet
121+
/// duplication, as described in RFC 3611, section 4.1
122+
/// make sure to set is_loss_rle = false
123+
pub type DuplicateRLEReportBlock = RLEReportBlock;
124+
125+
impl RLEReportBlock {
126+
pub fn xr_header(&self) -> XRHeader {
127+
XRHeader {
128+
block_type: if self.is_loss_rle {
129+
BlockType::LossRLE
130+
} else {
131+
BlockType::DuplicateRLE
132+
},
133+
type_specific: self.t & 0x0F,
134+
block_length: (self.raw_size() / 4 - 1) as u16,
135+
}
129136
}
130137
}
131138

132-
impl ReportBlock for LossRLEReportBlock {
133-
/// destination_ssrc returns an array of ssrc values that this report block refers to.
134-
fn destination_ssrc(&self) -> Vec<u32> {
135-
vec![self.0.ssrc]
139+
impl fmt::Display for RLEReportBlock {
140+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141+
write!(f, "{:?}", self)
136142
}
143+
}
137144

138-
fn setup_block_header(&mut self) {
139-
self.0.xr_header.block_type = ReportBlockType::LossRLE;
140-
self.0.xr_header.type_specific = self.0.t & 0x0F;
141-
self.0.xr_header.block_length = (self.0.raw_size() / 4 - 1) as u16;
145+
impl Packet for RLEReportBlock {
146+
fn header(&self) -> Header {
147+
Header::default()
142148
}
143149

144-
fn unpack_block_header(&mut self) {
145-
self.0.t = (self.0.xr_header.type_specific) & 0x0F;
150+
/// destination_ssrc returns an array of ssrc values that this report block refers to.
151+
fn destination_ssrc(&self) -> Vec<u32> {
152+
vec![self.ssrc]
146153
}
147154

148155
fn raw_size(&self) -> usize {
149-
self.0.raw_size()
156+
XR_HEADER_LENGTH + RLE_REPORT_BLOCK_MIN_LENGTH as usize + self.chunks.len() * 2
150157
}
151158

152159
fn as_any(&self) -> &(dyn Any + Send + Sync) {
153160
self
154161
}
155-
fn equal(&self, other: &(dyn ReportBlock + Send + Sync)) -> bool {
162+
fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool {
156163
other
157164
.as_any()
158-
.downcast_ref::<LossRLEReportBlock>()
165+
.downcast_ref::<RLEReportBlock>()
159166
.map_or(false, |a| self == a)
160167
}
161-
fn cloned(&self) -> Box<dyn ReportBlock + Send + Sync> {
168+
fn cloned(&self) -> Box<dyn Packet + Send + Sync> {
162169
Box::new(self.clone())
163170
}
164171
}
165172

166-
/// DuplicateRLEReportBlock is used to report information about packet
167-
/// duplication, as described in RFC 3611, section 4.1
168-
#[derive(Debug, Default, PartialEq, Clone)]
169-
pub struct DuplicateRLEReportBlock(pub RleReportBlock);
170-
171-
impl fmt::Display for DuplicateRLEReportBlock {
172-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173-
write!(f, "{:?}", self)
173+
impl MarshalSize for RLEReportBlock {
174+
fn marshal_size(&self) -> usize {
175+
self.raw_size()
174176
}
175177
}
176178

177-
impl ReportBlock for DuplicateRLEReportBlock {
178-
/// destination_ssrc returns an array of ssrc values that this report block refers to.
179-
fn destination_ssrc(&self) -> Vec<u32> {
180-
vec![self.0.ssrc]
181-
}
179+
impl Marshal for RLEReportBlock {
180+
/// marshal_to encodes the RleReportBlock in binary
181+
fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
182+
if buf.remaining_mut() < self.marshal_size() {
183+
return Err(error::Error::BufferTooShort.into());
184+
}
182185

183-
fn setup_block_header(&mut self) {
184-
self.0.xr_header.block_type = ReportBlockType::DuplicateRLE;
185-
self.0.xr_header.type_specific = self.0.t & 0x0F;
186-
self.0.xr_header.block_length = (self.0.raw_size() / 4 - 1) as u16;
187-
}
186+
let h = self.xr_header();
187+
let n = h.marshal_to(buf)?;
188+
buf = &mut buf[n..];
188189

189-
fn unpack_block_header(&mut self) {
190-
self.0.t = (self.0.xr_header.type_specific) & 0x0F;
191-
}
190+
buf.put_u8(self.t);
191+
buf.put_u32(self.ssrc);
192+
buf.put_u16(self.begin_seq);
193+
buf.put_u16(self.end_seq);
194+
for chunk in &self.chunks {
195+
buf.put_u16(chunk.0);
196+
}
192197

193-
fn raw_size(&self) -> usize {
194-
self.0.raw_size()
198+
Ok(self.marshal_size())
195199
}
200+
}
196201

197-
fn as_any(&self) -> &(dyn Any + Send + Sync) {
198-
self
199-
}
200-
fn equal(&self, other: &(dyn ReportBlock + Send + Sync)) -> bool {
201-
other
202-
.as_any()
203-
.downcast_ref::<DuplicateRLEReportBlock>()
204-
.map_or(false, |a| self == a)
205-
}
206-
fn cloned(&self) -> Box<dyn ReportBlock + Send + Sync> {
207-
Box::new(self.clone())
202+
impl Unmarshal for RLEReportBlock {
203+
/// Unmarshal decodes the RleReportBlock from binary
204+
fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
205+
where
206+
Self: Sized,
207+
B: Buf,
208+
{
209+
if raw_packet.remaining() < XR_HEADER_LENGTH {
210+
return Err(error::Error::PacketTooShort.into());
211+
}
212+
213+
let xr_header = XRHeader::unmarshal(raw_packet)?;
214+
215+
if xr_header.block_length < RLE_REPORT_BLOCK_MIN_LENGTH
216+
|| (xr_header.block_length - RLE_REPORT_BLOCK_MIN_LENGTH) % 2 != 0
217+
|| raw_packet.remaining() < xr_header.block_length as usize
218+
{
219+
return Err(error::Error::PacketTooShort.into());
220+
}
221+
222+
let is_loss_rle = xr_header.block_type == BlockType::LossRLE;
223+
let t = raw_packet.get_u8();
224+
let ssrc = raw_packet.get_u32();
225+
let begin_seq = raw_packet.get_u16();
226+
let end_seq = raw_packet.get_u16();
227+
228+
let remaining = xr_header.block_length - RLE_REPORT_BLOCK_MIN_LENGTH;
229+
let mut chunks = vec![];
230+
for _ in 0..remaining / 2 {
231+
chunks.push(Chunk(raw_packet.get_u16()));
232+
}
233+
234+
Ok(RLEReportBlock {
235+
is_loss_rle,
236+
t,
237+
ssrc,
238+
begin_seq,
239+
end_seq,
240+
chunks,
241+
})
208242
}
209243
}

0 commit comments

Comments
 (0)