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.
21pub enum HeaderExtension {
22    /// The absolute-send-time extension.
23    AbsSendTime(abs_send_time_extension::AbsSendTimeExtension),
24    /// The audio-level extension.
25    AudioLevel(audio_level_extension::AudioLevelExtension),
26    /// The playout-delay extension.
27    PlayoutDelay(playout_delay_extension::PlayoutDelayExtension),
28    /// The transport-wide CC extension.
29    TransportCc(transport_cc_extension::TransportCcExtension),
30    /// The video-orientation extension.
31    VideoOrientation(video_orientation_extension::VideoOrientationExtension),
32
33    /// A custom extension
34    Custom {
35        /// The extension's canonical URI, which is what SDP negotiates ids against.
36        uri: Cow<'static, str>,
37        /// The extension value, erased so extensions of different types can be held together.
38        extension: Box<dyn Marshal + 'static>,
39    },
40}
41
42impl HeaderExtension {
43    /// The extension's URI.
44    pub fn uri(&self) -> Cow<'static, str> {
45        use HeaderExtension::*;
46
47        match self {
48            AbsSendTime(_) => "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time".into(),
49            AudioLevel(_) => "urn:ietf:params:rtp-hdrext:ssrc-audio-level".into(),
50            PlayoutDelay(_) => "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay".into(),
51            TransportCc(_) => {
52                "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01".into()
53            }
54            VideoOrientation(_) => "urn:3gpp:video-orientation".into(),
55            Custom { uri, .. } => uri.clone(),
56        }
57    }
58
59    /// Whether both refer to the same extension, comparing URIs rather than values.
60    pub fn is_same(&self, other: &Self) -> bool {
61        use HeaderExtension::*;
62        match (self, other) {
63            (AbsSendTime(_), AbsSendTime(_)) => true,
64            (AudioLevel(_), AudioLevel(_)) => true,
65            (TransportCc(_), TransportCc(_)) => true,
66            (VideoOrientation(_), VideoOrientation(_)) => true,
67            (Custom { uri, .. }, Custom { uri: other_uri, .. }) => uri == other_uri,
68            _ => false,
69        }
70    }
71}
72
73impl MarshalSize for HeaderExtension {
74    fn marshal_size(&self) -> usize {
75        use HeaderExtension::*;
76        match self {
77            AbsSendTime(ext) => ext.marshal_size(),
78            AudioLevel(ext) => ext.marshal_size(),
79            PlayoutDelay(ext) => ext.marshal_size(),
80            TransportCc(ext) => ext.marshal_size(),
81            VideoOrientation(ext) => ext.marshal_size(),
82            Custom { extension: ext, .. } => ext.marshal_size(),
83        }
84    }
85}
86
87impl Marshal for HeaderExtension {
88    fn marshal_to(&self, buf: &mut [u8]) -> Result<usize> {
89        use HeaderExtension::*;
90        match self {
91            AbsSendTime(ext) => ext.marshal_to(buf),
92            AudioLevel(ext) => ext.marshal_to(buf),
93            PlayoutDelay(ext) => ext.marshal_to(buf),
94            TransportCc(ext) => ext.marshal_to(buf),
95            VideoOrientation(ext) => ext.marshal_to(buf),
96            Custom { extension: ext, .. } => ext.marshal_to(buf),
97        }
98    }
99}
100
101impl fmt::Debug for HeaderExtension {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103        use HeaderExtension::*;
104
105        match self {
106            AbsSendTime(ext) => f.debug_tuple("AbsSendTime").field(ext).finish(),
107            AudioLevel(ext) => f.debug_tuple("AudioLevel").field(ext).finish(),
108            PlayoutDelay(ext) => f.debug_tuple("PlayoutDelay").field(ext).finish(),
109            TransportCc(ext) => f.debug_tuple("TransportCc").field(ext).finish(),
110            VideoOrientation(ext) => f.debug_tuple("VideoOrientation").field(ext).finish(),
111            Custom { uri, extension: _ } => f.debug_struct("Custom").field("uri", uri).finish(),
112        }
113    }
114}