1use gosuto_webrtc_sys::{rtp_parameters as sys_rp, webrtc as sys_webrtc};
16
17use crate::rtp_parameters::*;
18
19impl From<sys_webrtc::ffi::Priority> for Priority {
20 fn from(value: sys_webrtc::ffi::Priority) -> Self {
21 match value {
22 sys_webrtc::ffi::Priority::VeryLow => Self::VeryLow,
23 sys_webrtc::ffi::Priority::Low => Self::Low,
24 sys_webrtc::ffi::Priority::Medium => Self::Medium,
25 sys_webrtc::ffi::Priority::High => Self::High,
26 _ => panic!("unknown Priority"),
27 }
28 }
29}
30
31impl From<sys_rp::ffi::RtpExtension> for RtpHeaderExtensionParameters {
32 fn from(value: sys_rp::ffi::RtpExtension) -> Self {
33 Self { uri: value.uri, id: value.id, encrypted: value.encrypt }
34 }
35}
36
37impl From<sys_rp::ffi::RtpParameters> for RtpParameters {
38 fn from(value: sys_rp::ffi::RtpParameters) -> Self {
39 Self {
40 codecs: value.codecs.into_iter().map(Into::into).collect(),
41 header_extensions: value.header_extensions.into_iter().map(Into::into).collect(),
42 rtcp: value.rtcp.into(),
43 }
44 }
45}
46
47impl From<sys_rp::ffi::RtpCodecParameters> for RtpCodecParameters {
48 fn from(value: sys_rp::ffi::RtpCodecParameters) -> Self {
49 Self {
50 mime_type: value.mime_type,
51 payload_type: value.payload_type as u8,
52 clock_rate: value.has_clock_rate.then_some(value.clock_rate as u64),
53 channels: value.has_num_channels.then_some(value.num_channels as u16),
54 }
55 }
56}
57
58impl From<sys_rp::ffi::RtcpParameters> for RtcpParameters {
59 fn from(value: sys_rp::ffi::RtcpParameters) -> Self {
60 Self { cname: value.cname, reduced_size: value.reduced_size }
61 }
62}
63
64impl From<sys_rp::ffi::RtpEncodingParameters> for RtpEncodingParameters {
65 fn from(value: sys_rp::ffi::RtpEncodingParameters) -> Self {
66 Self {
67 active: value.active,
68 max_bitrate: value.has_max_bitrate_bps.then_some(value.max_bitrate_bps as u64),
69 max_framerate: value.has_max_framerate.then_some(value.max_framerate),
70 priority: value.network_priority.into(),
71 rid: value.rid,
72 scale_resolution_down_by: value
73 .has_scale_resolution_down_by
74 .then_some(value.scale_resolution_down_by),
75 }
76 }
77}
78
79impl From<sys_rp::ffi::RtpCodecCapability> for RtpCodecCapability {
80 fn from(value: sys_rp::ffi::RtpCodecCapability) -> Self {
81 Self {
82 channels: value.has_num_channels.then_some(value.num_channels as u16),
83 mime_type: value.mime_type,
84 clock_rate: value.has_clock_rate.then_some(value.clock_rate as u64),
85 sdp_fmtp_line: {
86 let parameters: Vec<String> = value
87 .parameters
88 .into_iter()
89 .map(|key_value| {
90 if !key_value.key.is_empty() {
91 format!("{}={}", key_value.key, key_value.value)
92 } else {
93 key_value.value
94 }
95 })
96 .collect();
97
98 if !parameters.is_empty() {
99 Some(parameters.join(";"))
100 } else {
101 None
102 }
103 },
104 }
105 }
106}
107
108impl From<sys_rp::ffi::RtpHeaderExtensionCapability> for RtpHeaderExtensionCapability {
109 fn from(value: sys_rp::ffi::RtpHeaderExtensionCapability) -> Self {
110 Self { direction: value.direction.into(), uri: value.uri }
111 }
112}
113
114impl From<sys_rp::ffi::RtpCapabilities> for RtpCapabilities {
115 fn from(value: sys_rp::ffi::RtpCapabilities) -> Self {
116 Self {
117 codecs: value.codecs.into_iter().map(Into::into).collect(),
118 header_extensions: value.header_extensions.into_iter().map(Into::into).collect(),
119 }
120 }
121}
122
123impl From<Priority> for sys_webrtc::ffi::Priority {
124 fn from(value: Priority) -> Self {
125 match value {
126 Priority::VeryLow => Self::VeryLow,
127 Priority::Low => Self::Low,
128 Priority::Medium => Self::Medium,
129 Priority::High => Self::High,
130 }
131 }
132}
133
134impl From<RtpHeaderExtensionParameters> for sys_rp::ffi::RtpExtension {
135 fn from(value: RtpHeaderExtensionParameters) -> Self {
136 Self { uri: value.uri, id: value.id, encrypt: value.encrypted }
137 }
138}
139
140impl From<RtpParameters> for sys_rp::ffi::RtpParameters {
141 fn from(value: RtpParameters) -> Self {
142 Self {
143 codecs: value.codecs.into_iter().map(Into::into).collect(),
144 header_extensions: value.header_extensions.into_iter().map(Into::into).collect(),
145 encodings: Vec::new(),
146 rtcp: value.rtcp.into(),
147 transaction_id: "".to_string(),
148 mid: "".to_string(),
149 has_degradation_preference: false,
150 degradation_preference: sys_rp::ffi::DegradationPreference::Balanced,
151 }
152 }
153}
154
155impl From<RtpCodecParameters> for sys_rp::ffi::RtpCodecParameters {
156 fn from(value: RtpCodecParameters) -> Self {
157 Self {
158 payload_type: value.payload_type as i32,
159 mime_type: value.mime_type,
160 has_clock_rate: value.clock_rate.is_some(),
161 clock_rate: value.clock_rate.unwrap_or_default() as i32,
162 has_num_channels: value.channels.is_some(),
163 num_channels: value.channels.unwrap_or_default() as i32,
164 name: "".to_string(),
165 kind: sys_rp::ffi::MediaType::Audio,
166 has_max_ptime: false,
167 max_ptime: 0,
168 has_ptime: false,
169 ptime: 0,
170 rtcp_feedback: Vec::new(),
171 parameters: Vec::new(),
172 }
173 }
174}
175
176impl From<RtcpParameters> for sys_rp::ffi::RtcpParameters {
177 fn from(value: RtcpParameters) -> Self {
178 Self {
179 cname: value.cname,
180 reduced_size: value.reduced_size,
181 has_ssrc: false,
182 ssrc: 0,
183 mux: false,
184 }
185 }
186}
187
188impl From<RtpEncodingParameters> for sys_rp::ffi::RtpEncodingParameters {
189 fn from(value: RtpEncodingParameters) -> Self {
190 Self {
191 active: value.active,
192 has_max_bitrate_bps: value.max_bitrate.is_some(),
193 max_bitrate_bps: value.max_bitrate.unwrap_or_default() as i32,
194 has_max_framerate: value.max_framerate.is_some(),
195 max_framerate: value.max_framerate.unwrap_or_default(),
196 network_priority: value.priority.into(),
197 rid: value.rid,
198 has_scale_resolution_down_by: value.scale_resolution_down_by.is_some(),
199 scale_resolution_down_by: value.scale_resolution_down_by.unwrap_or_default(),
200 adaptive_ptime: false,
201 bitrate_priority: sys_rp::DEFAULT_BITRATE_PRIORITY,
202 has_min_bitrate_bps: false,
203 min_bitrate_bps: 0,
204 has_num_temporal_layers: false,
205 num_temporal_layers: 0,
206 has_scalability_mode: false,
207 scalability_mode: "".to_string(),
208 has_ssrc: false,
209 ssrc: 0,
210 }
211 }
212}
213
214impl From<RtpCodecCapability> for sys_rp::ffi::RtpCodecCapability {
215 fn from(value: RtpCodecCapability) -> Self {
216 let mime_type: Vec<&str> = value.mime_type.split('/').collect();
217 let kind = match mime_type[0] {
218 "audio" => sys_webrtc::ffi::MediaType::Audio,
219 "video" => sys_webrtc::ffi::MediaType::Video,
220 _ => panic!("invalid media type"),
221 };
222 let name = mime_type[1].to_string();
223
224 Self {
225 name,
226 kind,
227 has_clock_rate: value.clock_rate.is_some(),
228 clock_rate: value.clock_rate.unwrap_or_default() as i32,
229 has_num_channels: value.channels.is_some(),
230 num_channels: value.channels.unwrap_or_default() as i32,
231 parameters: {
232 value
233 .sdp_fmtp_line
234 .map(|sdp_fmtp_line| {
235 sdp_fmtp_line
236 .split(';')
237 .map(|v| {
238 let key_value: Vec<&str> = v.split('=').collect();
239 if key_value.len() == 2 {
240 sys_rp::ffi::StringKeyValue {
241 key: key_value[0].to_string(),
242 value: key_value[1].to_string(),
243 }
244 } else {
245 sys_rp::ffi::StringKeyValue {
246 key: "".to_string(),
247 value: key_value[0].to_string(),
248 }
249 }
250 })
251 .collect()
252 })
253 .unwrap_or_default()
254 },
255 mime_type: String::default(), has_preferred_payload_type: false,
258 preferred_payload_type: 0,
259 rtcp_feedback: Vec::default(),
260 }
261 }
262}