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;
11pub mod audio_level_extension;
13pub mod playout_delay_extension;
15pub mod transport_cc_extension;
17pub mod video_orientation_extension;
19
20#[non_exhaustive]
22pub enum HeaderExtension {
23 AbsSendTime(abs_send_time_extension::AbsSendTimeExtension),
25 AudioLevel(audio_level_extension::AudioLevelExtension),
27 PlayoutDelay(playout_delay_extension::PlayoutDelayExtension),
29 TransportCc(transport_cc_extension::TransportCcExtension),
31 VideoOrientation(video_orientation_extension::VideoOrientationExtension),
33
34 Custom {
36 uri: Cow<'static, str>,
38 extension: Box<dyn Marshal + 'static>,
40 },
41}
42
43impl HeaderExtension {
44 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 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}