1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::borrow::Cow;
use derive_into_owned::IntoOwned;
use crate::{
attributes::{
candidate, dtls, extmap, ice::IceParameter, msid, rtcp, rtpmap, AttributeLine, BundleGroup,
Control, Direction, Fingerprint, Fmtp, Ice, RtcpOption, Rtp, Ssrc, SsrcGroup,
},
lines::{connection::Connection, media::Media, SessionLine},
SdpLine,
};
#[derive(Default, IntoOwned, PartialEq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct MediaSection<'a> {
pub r#type: Cow<'a, str>,
pub port: u32,
pub protocol: Vec<Cow<'a, str>>,
pub payloads: Vec<Cow<'a, str>>,
pub connection: Option<Connection>,
pub candidates: Vec<candidate::Candidate<'a>>,
pub ice: Ice<'a>,
pub mid: Option<Cow<'a, str>>,
pub msid_semantic: Option<msid::MsidSemantic<'a>>,
pub msid: Option<msid::Msid<'a>>,
pub rtp_map: Vec<rtpmap::RtpMap<'a>>,
pub p_time: Option<rtpmap::PTime>,
pub ssrc: Vec<Ssrc<'a>>,
pub bundle_group: Option<BundleGroup<'a>>,
pub bundle_only: bool,
pub ssrc_group: Option<SsrcGroup>,
pub fingerprint: Option<Fingerprint<'a>>,
pub direction: Option<Direction>,
pub rtp: Option<Rtp<'a>>,
pub rtcp: Option<rtcp::Rtcp>,
pub fmtp: Vec<Fmtp<'a>>,
pub rtcp_fb: Vec<rtcp::Fb<'a>>,
pub rtcp_option: Vec<RtcpOption>,
pub control: Option<Control<'a>>,
pub setup_role: Option<dtls::SetupRole>,
pub extmap: Vec<extmap::Extmap<'a>>,
pub attributes: Vec<AttributeLine<'a>>,
}
impl<'a> MediaSection<'a> {
pub fn media(&self) -> Media<'a> {
Media {
r#type: self.r#type.clone(),
port: self.port,
protocol: self.protocol.clone(),
payloads: self.payloads.clone(),
}
}
pub(crate) fn add_line(&mut self, line: SdpLine<'a>) {
use AttributeLine::*;
use SessionLine::*;
match line {
SdpLine::Session(Media(_)) => unreachable!(),
SdpLine::Session(SessionLine::Connection(conn)) => self.connection = Some(conn),
#[cfg(feature = "debug")]
SdpLine::Session(session) => eprintln!("🔥 {:#?}", session),
#[cfg(not(feature = "debug"))]
SdpLine::Session(session) => eprintln!("🔥 {}", crate::ufmt_to_string(&session)),
SdpLine::Attribute(Candidate(candidate)) => self.candidates.push(candidate),
SdpLine::Attribute(Ice(IceParameter::Options(o))) => self.ice.options = Some(o),
SdpLine::Attribute(Ice(IceParameter::Ufrag(o))) => self.ice.ufrag = Some(o),
SdpLine::Attribute(Ice(IceParameter::Pwd(o))) => self.ice.pwd = Some(o),
SdpLine::Attribute(attr @ Ice(_)) => self.attributes.push(attr),
SdpLine::Attribute(Mid(mid)) => self.mid = Some(mid.0),
SdpLine::Attribute(MsidSemantic(semantic)) => self.msid_semantic = Some(semantic),
SdpLine::Attribute(Msid(msid)) => self.msid = Some(msid),
SdpLine::Attribute(RtpMap(rtp_map)) => self.rtp_map.push(rtp_map),
SdpLine::Attribute(PTime(p_time)) => self.p_time = Some(p_time),
SdpLine::Attribute(Ssrc(ssrc)) => self.ssrc.push(ssrc),
SdpLine::Attribute(BundleGroup(bundle_group)) => self.bundle_group = Some(bundle_group),
SdpLine::Attribute(SsrcGroup(ssrc_group)) => self.ssrc_group = Some(ssrc_group),
SdpLine::Attribute(Fingerprint(fingerprint)) => self.fingerprint = Some(fingerprint),
SdpLine::Attribute(Direction(direction)) => self.direction = Some(direction),
SdpLine::Attribute(Rtp(rtp)) => self.rtp = Some(rtp),
SdpLine::Attribute(Rtcp(rtcp)) => self.rtcp = Some(rtcp),
SdpLine::Attribute(Fmtp(fmtp)) => self.fmtp.push(fmtp),
SdpLine::Attribute(RtcpFb(rtcp_fb)) => self.rtcp_fb.push(rtcp_fb),
SdpLine::Attribute(RtcpOption(rtcp_option)) => self.rtcp_option.push(rtcp_option),
SdpLine::Attribute(Control(control)) => self.control = Some(control),
SdpLine::Attribute(SetupRole(setup_role)) => self.setup_role = Some(setup_role),
SdpLine::Attribute(Extmap(extmap)) => self.extmap.push(extmap),
SdpLine::Attribute(AttributeLine::BundleOnly) => self.bundle_only = true,
SdpLine::Attribute(attr) => self.attributes.push(attr),
SdpLine::Comment(_) => {}
}
}
}
impl<'a> From<Media<'a>> for MediaSection<'a> {
fn from(mline: Media<'a>) -> Self {
Self {
r#type: mline.r#type,
port: mline.port,
protocol: mline.protocol,
payloads: mline.payloads,
..Default::default()
}
}
}