Skip to main content

rtc_rtp/extension/
mod.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use shared::{
5    error::Result,
6    marshal::{Marshal, MarshalSize},
7};
8
9/// Absolute send time, for one-way-delay based bandwidth estimation.
10pub mod abs_send_time_extension;
11/// Per-packet audio loudness and voice activity ([RFC 6464]).
12pub mod audio_level_extension;
13/// A requested playout-delay range, for latency/smoothness trade-offs.
14pub mod playout_delay_extension;
15/// The transport-wide sequence number that TWCC feedback refers to.
16pub mod transport_cc_extension;
17/// Camera direction and rotation (CVO), so a receiver can display video upright.
18pub mod video_orientation_extension;
19
20/// A generic RTP header extension.
21#[non_exhaustive]
22pub enum HeaderExtension {
23    /// The absolute-send-time extension.
24    AbsSendTime(abs_send_time_extension::AbsSendTimeExtension),
25    /// The audio-level extension.
26    AudioLevel(audio_level_extension::AudioLevelExtension),
27    /// The playout-delay extension.
28    PlayoutDelay(playout_delay_extension::PlayoutDelayExtension),
29    /// The transport-wide CC extension.
30    TransportCc(transport_cc_extension::TransportCcExtension),
31    /// The video-orientation extension.
32    VideoOrientation(video_orientation_extension::VideoOrientationExtension),
33
34    /// A custom extension
35    Custom {
36        /// The extension's canonical URI, which is what SDP negotiates ids against.
37        uri: Cow<'static, str>,
38        /// The extension value, erased so extensions of different types can be held together.
39        extension: Box<dyn Marshal + 'static>,
40    },
41}
42
43impl HeaderExtension {
44    /// The extension's URI.
45    pub fn uri(&self) -> Cow<'static, str> {
46        use HeaderExtension::*;
47
48        match self {
49            AbsSendTime(_) => "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time".into(),
50            AudioLevel(_) => "urn:ietf:params:rtp-hdrext:ssrc-audio-level".into(),
51            PlayoutDelay(_) => "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay".into(),
52            TransportCc(_) => {
53                "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01".into()
54            }
55            VideoOrientation(_) => "urn:3gpp:video-orientation".into(),
56            Custom { uri, .. } => uri.clone(),
57        }
58    }
59
60    /// Whether both refer to the same extension, comparing URIs rather than values.
61    pub fn is_same(&self, other: &Self) -> bool {
62        use HeaderExtension::*;
63        match (self, other) {
64            (AbsSendTime(_), AbsSendTime(_)) => true,
65            (AudioLevel(_), AudioLevel(_)) => true,
66            (TransportCc(_), TransportCc(_)) => true,
67            (VideoOrientation(_), VideoOrientation(_)) => true,
68            (Custom { uri, .. }, Custom { uri: other_uri, .. }) => uri == other_uri,
69            _ => false,
70        }
71    }
72}
73
74impl MarshalSize for HeaderExtension {
75    fn marshal_size(&self) -> usize {
76        use HeaderExtension::*;
77        match self {
78            AbsSendTime(ext) => ext.marshal_size(),
79            AudioLevel(ext) => ext.marshal_size(),
80            PlayoutDelay(ext) => ext.marshal_size(),
81            TransportCc(ext) => ext.marshal_size(),
82            VideoOrientation(ext) => ext.marshal_size(),
83            Custom { extension: ext, .. } => ext.marshal_size(),
84        }
85    }
86}
87
88impl Marshal for HeaderExtension {
89    fn marshal_to(&self, buf: &mut [u8]) -> Result<usize> {
90        use HeaderExtension::*;
91        match self {
92            AbsSendTime(ext) => ext.marshal_to(buf),
93            AudioLevel(ext) => ext.marshal_to(buf),
94            PlayoutDelay(ext) => ext.marshal_to(buf),
95            TransportCc(ext) => ext.marshal_to(buf),
96            VideoOrientation(ext) => ext.marshal_to(buf),
97            Custom { extension: ext, .. } => ext.marshal_to(buf),
98        }
99    }
100}
101
102impl fmt::Debug for HeaderExtension {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        use HeaderExtension::*;
105
106        match self {
107            AbsSendTime(ext) => f.debug_tuple("AbsSendTime").field(ext).finish(),
108            AudioLevel(ext) => f.debug_tuple("AudioLevel").field(ext).finish(),
109            PlayoutDelay(ext) => f.debug_tuple("PlayoutDelay").field(ext).finish(),
110            TransportCc(ext) => f.debug_tuple("TransportCc").field(ext).finish(),
111            VideoOrientation(ext) => f.debug_tuple("VideoOrientation").field(ext).finish(),
112            Custom { uri, extension: _ } => f.debug_struct("Custom").field("uri", uri).finish(),
113        }
114    }
115}