use webrtc_sys::{rtp_parameters as sys_rp, webrtc as sys_webrtc};
use crate::rtp_parameters::*;
impl From<sys_webrtc::ffi::Priority> for Priority {
fn from(value: sys_webrtc::ffi::Priority) -> Self {
match value {
sys_webrtc::ffi::Priority::VeryLow => Self::VeryLow,
sys_webrtc::ffi::Priority::Low => Self::Low,
sys_webrtc::ffi::Priority::Medium => Self::Medium,
sys_webrtc::ffi::Priority::High => Self::High,
_ => panic!("unknown Priority"),
}
}
}
impl From<sys_rp::ffi::RtpExtension> for RtpHeaderExtensionParameters {
fn from(value: sys_rp::ffi::RtpExtension) -> Self {
Self { uri: value.uri, id: value.id, encrypted: value.encrypt }
}
}
impl From<sys_rp::ffi::RtpParameters> for RtpParameters {
fn from(value: sys_rp::ffi::RtpParameters) -> Self {
Self {
codecs: value.codecs.into_iter().map(Into::into).collect(),
header_extensions: value.header_extensions.into_iter().map(Into::into).collect(),
encodings: value.encodings.into_iter().map(Into::into).collect(),
rtcp: value.rtcp.into(),
transaction_id: value.transaction_id,
mid: value.mid,
has_degradation_preference: value.has_degradation_preference,
degradation_preference: value.degradation_preference.repr,
}
}
}
impl From<sys_rp::ffi::RtpCodecParameters> for RtpCodecParameters {
fn from(value: sys_rp::ffi::RtpCodecParameters) -> Self {
Self {
mime_type: value.mime_type,
payload_type: value.payload_type as u8,
clock_rate: value.has_clock_rate.then_some(value.clock_rate as u64),
channels: value.has_num_channels.then_some(value.num_channels as u16),
name: value.name,
kind: value.kind.repr,
has_max_ptime: value.has_max_ptime,
max_ptime: value.max_ptime,
has_ptime: value.has_ptime,
ptime: value.ptime,
rtcp_feedback: value
.rtcp_feedback
.into_iter()
.map(|f| CodecFeedback {
feedback_type: f.feedback_type.repr,
has_message_type: f.has_message_type,
message_type: f.message_type.repr,
})
.collect(),
parameters: value.parameters.into_iter().map(|kv| (kv.key, kv.value)).collect(),
}
}
}
impl From<sys_rp::ffi::RtcpParameters> for RtcpParameters {
fn from(value: sys_rp::ffi::RtcpParameters) -> Self {
Self {
cname: value.cname,
reduced_size: value.reduced_size,
mux: value.mux,
has_ssrc: value.has_ssrc,
ssrc: value.ssrc,
}
}
}
impl From<sys_rp::ffi::RtpEncodingParameters> for RtpEncodingParameters {
fn from(value: sys_rp::ffi::RtpEncodingParameters) -> Self {
Self {
active: value.active,
max_bitrate: value.has_max_bitrate_bps.then_some(value.max_bitrate_bps as u64),
max_framerate: value.has_max_framerate.then_some(value.max_framerate),
priority: value.network_priority.into(),
rid: value.rid,
scale_resolution_down_by: value
.has_scale_resolution_down_by
.then_some(value.scale_resolution_down_by),
scalability_mode: value.has_scalability_mode.then_some(value.scalability_mode),
has_ssrc: value.has_ssrc,
ssrc: value.ssrc,
}
}
}
impl From<sys_rp::ffi::RtpCodecCapability> for RtpCodecCapability {
fn from(value: sys_rp::ffi::RtpCodecCapability) -> Self {
Self {
channels: value.has_num_channels.then_some(value.num_channels as u16),
mime_type: value.mime_type,
clock_rate: value.has_clock_rate.then_some(value.clock_rate as u64),
sdp_fmtp_line: {
let parameters: Vec<String> = value
.parameters
.into_iter()
.map(|key_value| {
if !key_value.key.is_empty() {
format!("{}={}", key_value.key, key_value.value)
} else {
key_value.value
}
})
.collect();
if !parameters.is_empty() {
Some(parameters.join(";"))
} else {
None
}
},
}
}
}
impl From<sys_rp::ffi::RtpHeaderExtensionCapability> for RtpHeaderExtensionCapability {
fn from(value: sys_rp::ffi::RtpHeaderExtensionCapability) -> Self {
Self { direction: value.direction.into(), uri: value.uri }
}
}
impl From<sys_rp::ffi::RtpCapabilities> for RtpCapabilities {
fn from(value: sys_rp::ffi::RtpCapabilities) -> Self {
Self {
codecs: value.codecs.into_iter().map(Into::into).collect(),
header_extensions: value.header_extensions.into_iter().map(Into::into).collect(),
}
}
}
impl From<Priority> for sys_webrtc::ffi::Priority {
fn from(value: Priority) -> Self {
match value {
Priority::VeryLow => Self::VeryLow,
Priority::Low => Self::Low,
Priority::Medium => Self::Medium,
Priority::High => Self::High,
}
}
}
impl From<RtpHeaderExtensionParameters> for sys_rp::ffi::RtpExtension {
fn from(value: RtpHeaderExtensionParameters) -> Self {
Self { uri: value.uri, id: value.id, encrypt: value.encrypted }
}
}
impl From<RtpParameters> for sys_rp::ffi::RtpParameters {
fn from(value: RtpParameters) -> Self {
let degradation_preference =
sys_rp::ffi::DegradationPreference { repr: value.degradation_preference };
Self {
codecs: value.codecs.into_iter().map(Into::into).collect(),
header_extensions: value.header_extensions.into_iter().map(Into::into).collect(),
encodings: value.encodings.into_iter().map(Into::into).collect(),
rtcp: value.rtcp.into(),
transaction_id: value.transaction_id,
mid: value.mid,
has_degradation_preference: value.has_degradation_preference,
degradation_preference,
}
}
}
impl From<RtpCodecParameters> for sys_rp::ffi::RtpCodecParameters {
fn from(value: RtpCodecParameters) -> Self {
let kind = sys_webrtc::ffi::MediaType { repr: value.kind };
Self {
payload_type: value.payload_type as i32,
mime_type: value.mime_type,
has_clock_rate: value.clock_rate.is_some(),
clock_rate: value.clock_rate.unwrap_or_default() as i32,
has_num_channels: value.channels.is_some(),
num_channels: value.channels.unwrap_or_default() as i32,
name: value.name,
kind,
has_max_ptime: value.has_max_ptime,
max_ptime: value.max_ptime,
has_ptime: value.has_ptime,
ptime: value.ptime,
rtcp_feedback: value
.rtcp_feedback
.into_iter()
.map(|f| {
let feedback_type = sys_rp::ffi::RtcpFeedbackType { repr: f.feedback_type };
let message_type =
sys_rp::ffi::RtcpFeedbackMessageType { repr: f.message_type };
sys_rp::ffi::RtcpFeedback {
feedback_type,
has_message_type: f.has_message_type,
message_type,
}
})
.collect(),
parameters: value
.parameters
.into_iter()
.map(|(key, value)| sys_rp::ffi::StringKeyValue { key, value })
.collect(),
}
}
}
impl From<RtcpParameters> for sys_rp::ffi::RtcpParameters {
fn from(value: RtcpParameters) -> Self {
Self {
cname: value.cname,
reduced_size: value.reduced_size,
has_ssrc: value.has_ssrc,
ssrc: value.ssrc,
mux: value.mux,
}
}
}
impl From<RtpEncodingParameters> for sys_rp::ffi::RtpEncodingParameters {
fn from(value: RtpEncodingParameters) -> Self {
Self {
active: value.active,
has_max_bitrate_bps: value.max_bitrate.is_some(),
max_bitrate_bps: value.max_bitrate.unwrap_or_default() as i32,
has_max_framerate: value.max_framerate.is_some(),
max_framerate: value.max_framerate.unwrap_or_default(),
network_priority: value.priority.into(),
rid: value.rid,
has_scale_resolution_down_by: value.scale_resolution_down_by.is_some(),
scale_resolution_down_by: value.scale_resolution_down_by.unwrap_or_default(),
adaptive_ptime: false,
bitrate_priority: sys_rp::DEFAULT_BITRATE_PRIORITY,
has_min_bitrate_bps: false,
min_bitrate_bps: 0,
has_num_temporal_layers: false,
num_temporal_layers: 0,
has_scalability_mode: value.scalability_mode.is_some(),
scalability_mode: value.scalability_mode.unwrap_or_default(),
has_ssrc: value.has_ssrc,
ssrc: value.ssrc,
}
}
}
impl From<RtpCodecCapability> for sys_rp::ffi::RtpCodecCapability {
fn from(value: RtpCodecCapability) -> Self {
let mime_type: Vec<&str> = value.mime_type.split('/').collect();
let kind = match mime_type[0] {
"audio" => sys_webrtc::ffi::MediaType::Audio,
"video" => sys_webrtc::ffi::MediaType::Video,
_ => panic!("invalid media type"),
};
let name = mime_type[1].to_string();
Self {
name,
kind,
has_clock_rate: value.clock_rate.is_some(),
clock_rate: value.clock_rate.unwrap_or_default() as i32,
has_num_channels: value.channels.is_some(),
num_channels: value.channels.unwrap_or_default() as i32,
parameters: {
value
.sdp_fmtp_line
.map(|sdp_fmtp_line| {
sdp_fmtp_line
.split(';')
.map(|v| {
let key_value: Vec<&str> = v.split('=').collect();
if key_value.len() == 2 {
sys_rp::ffi::StringKeyValue {
key: key_value[0].to_string(),
value: key_value[1].to_string(),
}
} else {
sys_rp::ffi::StringKeyValue {
key: "".to_string(),
value: key_value[0].to_string(),
}
}
})
.collect()
})
.unwrap_or_default()
},
mime_type: String::default(), has_preferred_payload_type: false,
preferred_payload_type: 0,
rtcp_feedback: Vec::default(),
}
}
}