sdp_nom/
media_section.rs

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