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
15pub 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 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}