Skip to content

Commit

Permalink
add (simple) docs to all relevant functions/structs
Browse files Browse the repository at this point in the history
  • Loading branch information
ystreet committed Jan 14, 2024
1 parent c1da8a1 commit 6ce60b9
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,23 @@ impl<'a> App<'a> {
const SUBTYPE_MASK: u8 = Self::MAX_COUNT;
pub const NAME_LEN: usize = 4;

/// The (optional) padding used by this [`App`] packet
pub fn padding(&self) -> Option<u8> {
parser::parse_padding(self.data)
}

/// The SSRC this [`App`] packet refers to
pub fn ssrc(&self) -> u32 {
parser::parse_ssrc(self.data)
}

/// The `name` for this [`App`] packet. The `name` should be a sequence of 4 ASCII
/// characters.
pub fn name(&self) -> [u8; App::NAME_LEN] {
self.data[8..8 + Self::NAME_LEN].try_into().unwrap()
}

/// The `name` for this [`App`] as a string.
pub fn get_name_string(&self) -> Result<String, std::string::FromUtf8Error> {
// name is fixed length potentially zero terminated
String::from_utf8(Vec::from_iter(self.name().iter().map_while(|&b| {
Expand All @@ -57,6 +62,7 @@ impl<'a> App<'a> {
})))
}

/// The application specific data
pub fn data(&self) -> &[u8] {
&self.data[12..self.data.len() - self.padding().unwrap_or(0) as usize]
}
Expand Down Expand Up @@ -97,11 +103,13 @@ impl<'a> AppBuilder<'a> {
self
}

/// The subtype to use for this [`App`] packet
pub fn subtype(mut self, subtype: u8) -> Self {
self.subtype = subtype;
self
}

/// The data to use for this [`App`] packet
pub fn data(mut self, data: &'a [u8]) -> Self {
self.data = data;
self
Expand Down
5 changes: 5 additions & 0 deletions src/bye.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,19 @@ impl<'a> Bye<'a> {
const MAX_SOURCES: u8 = Self::MAX_COUNT;
const MAX_REASON_LEN: u8 = 0xff;

/// The (optional) padding used by this [`Bye`] packet
pub fn padding(&self) -> Option<u8> {
parser::parse_padding(self.data)
}

/// The list of ssrcs that this [`Bye`] packet refers to
pub fn ssrcs(&self) -> impl Iterator<Item = u32> + '_ {
self.data[4..4 + self.count() as usize * 4]
.chunks_exact(4)
.map(u32_from_be_bytes)
}

/// The (optional) reason for the [`Bye`] as raw data. The reason should be an ASCII string.
pub fn reason(&self) -> Option<&[u8]> {
let offset = self.count() as usize * 4 + 4;
let reason_aligned_len = self
Expand All @@ -78,10 +81,12 @@ impl<'a> Bye<'a> {
Some(&self.data[offset + 1..end])
}

/// The (optional) reason for the [`Bye`] as a string
pub fn get_reason_string(&self) -> Option<Result<String, std::string::FromUtf8Error>> {
self.reason().map(|r| String::from_utf8(r.into()))
}

/// Create a new [`ByeBuilder`]
pub fn builder() -> ByeBuilder<'a> {
ByeBuilder::new()
}
Expand Down
24 changes: 24 additions & 0 deletions src/compound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::{
RtcpPacket, RtcpParseError, RtcpWriteError,
};

/// A (currently) unknown RTCP packet type. Can also be used as a way to parse a custom RTCP packet
/// type.
#[derive(Debug, PartialEq, Eq)]
pub struct Unknown<'a> {
data: &'a [u8],
Expand Down Expand Up @@ -54,10 +56,13 @@ impl<'a> RtcpPacketParser<'a> for Unknown<'a> {
}

impl<'a> Unknown<'a> {
/// The data of this RTCP packet
pub fn data(&self) -> &[u8] {
self.data
}

/// Try to parse this unknown RTCP packet as a different RTCP packet. Can be used with an
/// external implementation of [`RtcpPacket`] to parse a custom RTCP packet.
pub fn try_as<P>(&'a self) -> Result<P, RtcpParseError>
where
P: RtcpPacket,
Expand All @@ -66,11 +71,14 @@ impl<'a> Unknown<'a> {
TryFrom::try_from(self)
}

/// The builder for an [`Unknown`] RTCP packet. The data does not include the 4 byte RTCP
/// header.
pub fn builder(type_: u8, data: &'a [u8]) -> UnknownBuilder<'a> {
UnknownBuilder::new(type_, data)
}
}

/// Unknown RTCP packet builder
#[derive(Debug)]
#[must_use = "The builder must be built to be used"]
pub struct UnknownBuilder<'a> {
Expand All @@ -81,6 +89,8 @@ pub struct UnknownBuilder<'a> {
}

impl<'a> UnknownBuilder<'a> {
/// Create a new builder for an [`Unknown`] RTCP packet. The data does not include the 4 byte RTCP
/// header.
pub fn new(type_: u8, data: &'a [u8]) -> UnknownBuilder<'a> {
UnknownBuilder {
padding: 0,
Expand All @@ -90,11 +100,14 @@ impl<'a> UnknownBuilder<'a> {
}
}

/// Sets the number of padding bytes to use for this Unknown packet
pub fn padding(mut self, padding: u8) -> Self {
self.padding = padding;
self
}

/// Set the count (or possibly type) field in the RTCP header. The exact interpretation of
/// this value is RTCP packet specific.
pub fn count(mut self, count: u8) -> Self {
self.count = count;
self
Expand Down Expand Up @@ -150,6 +163,8 @@ impl<'a> RtcpPacketWriter for UnknownBuilder<'a> {
}
}

/// A (closed) enum of all currently known RTCP packet types. The Unknown variant can be used to
/// parse a custom RTCP packet.
#[derive(Debug)]
pub enum Packet<'a> {
App(crate::App<'a>),
Expand Down Expand Up @@ -217,6 +232,7 @@ impl<'a> RtcpPacketParser<'a> for Packet<'a> {
}

impl<'a> Packet<'a> {
/// Try parsing this [`Packet`] as a particular [`RtcpPacket`] implementation.
pub fn try_as<P>(&'a self) -> Result<P, RtcpParseError>
where
P: RtcpPacket,
Expand All @@ -226,6 +242,7 @@ impl<'a> Packet<'a> {
}
}

/// A compound RTCP packet consisting of multiple RTCP packets one after the other
#[derive(Debug)]
pub struct Compound<'a> {
data: &'a [u8],
Expand All @@ -234,6 +251,9 @@ pub struct Compound<'a> {
}

impl<'a> Compound<'a> {
/// Parse data into a [`Compound`] RTCP packet.
///
/// This will validate that the length of each individual RTCP packet is valid upfront.
pub fn parse(data: &'a [u8]) -> Result<Self, RtcpParseError> {
let mut offset = 0;
let mut packet_length;
Expand Down Expand Up @@ -271,6 +291,7 @@ impl<'a> Compound<'a> {
})
}

/// Create a new [`CompoundBuilder`]
pub fn builder() -> CompoundBuilder<'a> {
CompoundBuilder::default()
}
Expand Down Expand Up @@ -300,6 +321,7 @@ impl<'a> Iterator for Compound<'a> {
}
}

/// A builder for a RTCP packet
#[derive(Debug)]
#[must_use = "The builder must be built to be used"]
pub enum PacketBuilder<'a> {
Expand Down Expand Up @@ -357,13 +379,15 @@ impl<'a> RtcpPacketWriter for PacketBuilder<'a> {
}
}

/// A builder for a [`Compound`] RTCP packet
#[derive(Default, Debug)]
#[must_use = "The builder must be built to be used"]
pub struct CompoundBuilder<'a> {
packets: Vec<Box<dyn RtcpPacketWriter + 'a>>,
}

impl<'a> CompoundBuilder<'a> {
/// Add a packet to the compound rtcp packet
pub fn add_packet(mut self, packet: impl RtcpPacketWriter + 'a) -> Self {
self.packets.push(Box::new(packet));
self
Expand Down
6 changes: 6 additions & 0 deletions src/feedback/fir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::prelude::*;
use crate::utils::u32_from_be_bytes;
use crate::{RtcpParseError, RtcpWriteError};

/// An entry in a Full Intra Refresh
#[derive(Debug, PartialEq, Eq)]
pub struct FirEntry {
ssrc: u32,
Expand All @@ -18,10 +19,12 @@ impl FirEntry {
Self { ssrc, sequence }
}

/// The SSRC for this FIR
pub fn ssrc(&self) -> u32 {
self.ssrc
}

/// The sequence count of the request. Intended for deduplication.
pub fn sequence(&self) -> u8 {
self.sequence
}
Expand Down Expand Up @@ -63,6 +66,7 @@ impl<'a> Fir<'a> {
FirParserEntryIter { parser: self, i: 0 }
}

/// Create a new [`FirBuilder`]
pub fn builder() -> FirBuilder {
FirBuilder::default()
}
Expand All @@ -83,12 +87,14 @@ impl<'a> FciParser<'a> for Fir<'a> {
}
}

/// Builder for a Full Intra Refresh packet
#[derive(Debug, Default)]
pub struct FirBuilder {
ssrc_seq: HashMap<u32, u8>,
}

impl FirBuilder {
/// Add an SSRC to this FIR packet. An existing SSRC will have their sequence number updated.
pub fn add_ssrc(mut self, ssrc: u32, sequence: u8) -> Self {
self.ssrc_seq
.entry(ssrc)
Expand Down
30 changes: 30 additions & 0 deletions src/feedback/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub mod pli;
pub mod rpsi;
pub mod sli;

/// The type of feedback packet. There is currently transport and payload values supported for
/// feedback packets.
#[derive(Debug, Default, PartialEq, Eq)]
pub struct FciFeedbackPacketType {
transport: bool,
Expand Down Expand Up @@ -109,18 +111,27 @@ impl<'a> TransportFeedback<'a> {
}
}

/// The (optional) padding used by this [`TransportFeedback`] packet
pub fn padding(&self) -> Option<u8> {
parser::parse_padding(self.data)
}

/// The SSRC of the sender sending this feedback
pub fn sender_ssrc(&self) -> u32 {
parser::parse_ssrc(self.data)
}

/// The SSRC of the media this packet refers to. May be unset (0) in some feedback types.
pub fn media_ssrc(&self) -> u32 {
parser::parse_ssrc(&self.data[4..])
}

/// Parse the Feedback Control Information into a concrete type.
///
/// Will fail if:
/// * The FCI does not support transport feedback,
/// * the feedback type does not match the FCI
/// * The FCI implementation fails to parse the contained data
pub fn parse_fci<F: FciParser<'a>>(&self) -> Result<F, RtcpParseError> {
if F::PACKET_TYPE & FciFeedbackPacketType::TRANSPORT == FciFeedbackPacketType::NONE {
return Err(RtcpParseError::WrongImplementation);
Expand All @@ -143,11 +154,14 @@ pub struct TransportFeedbackBuilder<'a> {
}

impl<'a> TransportFeedbackBuilder<'a> {
/// Set the SSRC this feedback packet is being sent from
pub fn sender_ssrc(mut self, sender_ssrc: u32) -> Self {
self.sender_ssrc = sender_ssrc;
self
}

/// Set the SSRC this feedback packet is being directed towards. May be 0 if the specific
/// feedback type allows.
pub fn media_ssrc(mut self, media_ssrc: u32) -> Self {
self.media_ssrc = media_ssrc;
self
Expand Down Expand Up @@ -293,18 +307,27 @@ impl<'a> PayloadFeedback<'a> {
}
}

/// The (optional) padding used by this [`PayloadFeedback`] packet
pub fn padding(&self) -> Option<u8> {
parser::parse_padding(self.data)
}

/// The SSRC of the sender sending this feedback
pub fn sender_ssrc(&self) -> u32 {
parser::parse_ssrc(self.data)
}

/// The SSRC of the media this packet refers to. May be unset (0) in some feedback types.
pub fn media_ssrc(&self) -> u32 {
parser::parse_ssrc(&self.data[4..])
}

/// Parse the Feedback Control Information into a concrete type.
///
/// Will fail if:
/// * The FCI does not support payload feedback,
/// * the feedback type does not match the FCI
/// * The FCI implementation fails to parse the contained data
pub fn parse_fci<F: FciParser<'a>>(&self) -> Result<F, RtcpParseError> {
if F::PACKET_TYPE & FciFeedbackPacketType::PAYLOAD == FciFeedbackPacketType::NONE {
return Err(RtcpParseError::WrongImplementation);
Expand All @@ -327,11 +350,14 @@ pub struct PayloadFeedbackBuilder<'a> {
}

impl<'a> PayloadFeedbackBuilder<'a> {
/// Set the SSRC this feedback packet is being sent from
pub fn sender_ssrc(mut self, sender_ssrc: u32) -> Self {
self.sender_ssrc = sender_ssrc;
self
}

/// Set the SSRC this feedback packet is being directed towards. May be 0 if the specific
/// feedback type allows.
pub fn media_ssrc(mut self, media_ssrc: u32) -> Self {
self.media_ssrc = media_ssrc;
self
Expand Down Expand Up @@ -392,6 +418,7 @@ impl<'a> RtcpPacketWriter for PayloadFeedbackBuilder<'a> {
}
}

/// Trait for parsing FCI data in [`TransportFeedback`] or [`PayloadFeedback`] packets
pub trait FciParser<'a>: Sized {
const PACKET_TYPE: FciFeedbackPacketType;
const FCI_FORMAT: u8;
Expand Down Expand Up @@ -446,8 +473,11 @@ impl<'a> std::ops::Deref for FciBuilderWrapper<'a> {
}
}

/// Trait for writing a particular FCI implementation with a [`TransportFeedbackBuilder`] or
/// [`PayloadFeedbackBuilder`].
pub trait FciBuilder<'a>: RtcpPacketWriter {
/// The format field value to place in the RTCP header
fn format(&self) -> u8;
/// The type of feedback packet this FCI data supports being placed in
fn supports_feedback_type(&self) -> FciFeedbackPacketType;
}
Loading

0 comments on commit 6ce60b9

Please sign in to comment.