rtc_rtp/extension/
mod.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use shared::{
5    error::Result,
6    marshal::{Marshal, MarshalSize},
7};
8
9pub mod abs_send_time_extension;
10pub mod audio_level_extension;
11pub mod playout_delay_extension;
12pub mod transport_cc_extension;
13pub mod video_orientation_extension;
14
15/// A generic RTP header extension.
16pub enum HeaderExtension {
17    AbsSendTime(abs_send_time_extension::AbsSendTimeExtension),
18    AudioLevel(audio_level_extension::AudioLevelExtension),
19    PlayoutDelay(playout_delay_extension::PlayoutDelayExtension),
20    TransportCc(transport_cc_extension::TransportCcExtension),
21    VideoOrientation(video_orientation_extension::VideoOrientationExtension),
22
23    /// A custom extension
24    Custom {
25        uri: Cow<'static, str>,
26        extension: Box<dyn Marshal + 'static>,
27    },
28}
29
30impl HeaderExtension {
31    pub fn uri(&self) -> Cow<'static, str> {
32        use HeaderExtension::*;
33
34        match self {
35            AbsSendTime(_) => "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time".into(),
36            AudioLevel(_) => "urn:ietf:params:rtp-hdrext:ssrc-audio-level".into(),
37            PlayoutDelay(_) => "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay".into(),
38            TransportCc(_) => {
39                "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01".into()
40            }
41            VideoOrientation(_) => "urn:3gpp:video-orientation".into(),
42            Custom { uri, .. } => uri.clone(),
43        }
44    }
45
46    pub fn is_same(&self, other: &Self) -> bool {
47        use HeaderExtension::*;
48        match (self, other) {
49            (AbsSendTime(_), AbsSendTime(_)) => true,
50            (AudioLevel(_), AudioLevel(_)) => true,
51            (TransportCc(_), TransportCc(_)) => true,
52            (VideoOrientation(_), VideoOrientation(_)) => true,
53            (Custom { uri, .. }, Custom { uri: other_uri, .. }) => uri == other_uri,
54            _ => false,
55        }
56    }
57}
58
59impl MarshalSize for HeaderExtension {
60    fn marshal_size(&self) -> usize {
61        use HeaderExtension::*;
62        match self {
63            AbsSendTime(ext) => ext.marshal_size(),
64            AudioLevel(ext) => ext.marshal_size(),
65            PlayoutDelay(ext) => ext.marshal_size(),
66            TransportCc(ext) => ext.marshal_size(),
67            VideoOrientation(ext) => ext.marshal_size(),
68            Custom { extension: ext, .. } => ext.marshal_size(),
69        }
70    }
71}
72
73impl Marshal for HeaderExtension {
74    fn marshal_to(&self, buf: &mut [u8]) -> Result<usize> {
75        use HeaderExtension::*;
76        match self {
77            AbsSendTime(ext) => ext.marshal_to(buf),
78            AudioLevel(ext) => ext.marshal_to(buf),
79            PlayoutDelay(ext) => ext.marshal_to(buf),
80            TransportCc(ext) => ext.marshal_to(buf),
81            VideoOrientation(ext) => ext.marshal_to(buf),
82            Custom { extension: ext, .. } => ext.marshal_to(buf),
83        }
84    }
85}
86
87impl fmt::Debug for HeaderExtension {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        use HeaderExtension::*;
90
91        match self {
92            AbsSendTime(ext) => f.debug_tuple("AbsSendTime").field(ext).finish(),
93            AudioLevel(ext) => f.debug_tuple("AudioLevel").field(ext).finish(),
94            PlayoutDelay(ext) => f.debug_tuple("PlayoutDelay").field(ext).finish(),
95            TransportCc(ext) => f.debug_tuple("TransportCc").field(ext).finish(),
96            VideoOrientation(ext) => f.debug_tuple("VideoOrientation").field(ext).finish(),
97            Custom { uri, extension: _ } => f.debug_struct("Custom").field("uri", uri).finish(),
98        }
99    }
100}