From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../webrtc/sdp/rsdparsa_capi/src/attribute.rs | 1472 ++++++++++++++++++++ 1 file changed, 1472 insertions(+) create mode 100644 dom/media/webrtc/sdp/rsdparsa_capi/src/attribute.rs (limited to 'dom/media/webrtc/sdp/rsdparsa_capi/src/attribute.rs') diff --git a/dom/media/webrtc/sdp/rsdparsa_capi/src/attribute.rs b/dom/media/webrtc/sdp/rsdparsa_capi/src/attribute.rs new file mode 100644 index 0000000000..82483f151f --- /dev/null +++ b/dom/media/webrtc/sdp/rsdparsa_capi/src/attribute.rs @@ -0,0 +1,1472 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use libc::{c_float, size_t}; +use std::ptr; +use std::slice; + +use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; +use rsdparsa::attribute_type::*; +use rsdparsa::SdpSession; + +use network::{RustAddress, RustExplicitlyTypedAddress}; +use types::StringView; + +#[no_mangle] +pub unsafe extern "C" fn num_attributes(session: *const SdpSession) -> u32 { + (*session).attribute.len() as u32 +} + +#[no_mangle] +pub unsafe extern "C" fn get_attribute_ptr( + session: *const SdpSession, + index: u32, + ret: *mut *const SdpAttribute, +) -> nsresult { + match (*session).attribute.get(index as usize) { + Some(attribute) => { + *ret = attribute as *const SdpAttribute; + NS_OK + } + None => NS_ERROR_INVALID_ARG, + } +} + +fn count_attribute(attributes: &[SdpAttribute], search: SdpAttributeType) -> usize { + let mut count = 0; + for attribute in (*attributes).iter() { + if SdpAttributeType::from(attribute) == search { + count += 1; + } + } + count +} + +fn argsearch(attributes: &[SdpAttribute], attribute_type: SdpAttributeType) -> Option { + for (i, attribute) in (*attributes).iter().enumerate() { + if SdpAttributeType::from(attribute) == attribute_type { + return Some(i); + } + } + None +} + +pub unsafe fn has_attribute( + attributes: *const Vec, + attribute_type: SdpAttributeType, +) -> bool { + argsearch((*attributes).as_slice(), attribute_type).is_some() +} + +fn get_attribute( + attributes: &[SdpAttribute], + attribute_type: SdpAttributeType, +) -> Option<&SdpAttribute> { + argsearch(attributes, attribute_type).map(|i| &attributes[i]) +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub enum RustSdpAttributeDtlsMessageType { + Client, + Server, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeDtlsMessage { + pub role: u8, + pub value: StringView, +} + +impl<'a> From<&'a SdpAttributeDtlsMessage> for RustSdpAttributeDtlsMessage { + fn from(other: &SdpAttributeDtlsMessage) -> Self { + match other { + &SdpAttributeDtlsMessage::Client(ref x) => RustSdpAttributeDtlsMessage { + role: RustSdpAttributeDtlsMessageType::Client as u8, + value: StringView::from(x.as_str()), + }, + &SdpAttributeDtlsMessage::Server(ref x) => RustSdpAttributeDtlsMessage { + role: RustSdpAttributeDtlsMessageType::Server as u8, + value: StringView::from(x.as_str()), + }, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_dtls_message( + attributes: *const Vec, + ret: *mut RustSdpAttributeDtlsMessage, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::DtlsMessage); + if let Some(&SdpAttribute::DtlsMessage(ref dtls_message)) = attr { + *ret = RustSdpAttributeDtlsMessage::from(dtls_message); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_iceufrag( + attributes: *const Vec, + ret: *mut StringView, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IceUfrag); + if let Some(&SdpAttribute::IceUfrag(ref string)) = attr { + *ret = StringView::from(string.as_str()); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_icepwd( + attributes: *const Vec, + ret: *mut StringView, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IcePwd); + if let Some(&SdpAttribute::IcePwd(ref string)) = attr { + *ret = StringView::from(string.as_str()); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_identity( + attributes: *const Vec, + ret: *mut StringView, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Identity); + if let Some(&SdpAttribute::Identity(ref string)) = attr { + *ret = StringView::from(string.as_str()); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_iceoptions( + attributes: *const Vec, + ret: *mut *const Vec, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IceOptions); + if let Some(&SdpAttribute::IceOptions(ref options)) = attr { + *ret = options; + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_maxptime( + attributes: *const Vec, + ret: *mut u64, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::MaxPtime); + if let Some(&SdpAttribute::MaxPtime(ref max_ptime)) = attr { + *ret = *max_ptime; + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeFingerprint { + hash_algorithm: u16, + fingerprint: *const Vec, +} + +impl<'a> From<&'a SdpAttributeFingerprint> for RustSdpAttributeFingerprint { + fn from(other: &SdpAttributeFingerprint) -> Self { + RustSdpAttributeFingerprint { + hash_algorithm: other.hash_algorithm as u16, + fingerprint: &other.fingerprint, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_fingerprint_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Fingerprint) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_fingerprints( + attributes: *const Vec, + ret_size: size_t, + ret_fingerprints: *mut RustSdpAttributeFingerprint, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Fingerprint(ref data) = *x { + Some(RustSdpAttributeFingerprint::from(data)) + } else { + None + } + }) + .collect(); + let fingerprints = slice::from_raw_parts_mut(ret_fingerprints, ret_size); + fingerprints.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone)] +pub enum RustSdpAttributeSetup { + Active, + Actpass, + Holdconn, + Passive, +} + +impl<'a> From<&'a SdpAttributeSetup> for RustSdpAttributeSetup { + fn from(other: &SdpAttributeSetup) -> Self { + match *other { + SdpAttributeSetup::Active => RustSdpAttributeSetup::Active, + SdpAttributeSetup::Actpass => RustSdpAttributeSetup::Actpass, + SdpAttributeSetup::Holdconn => RustSdpAttributeSetup::Holdconn, + SdpAttributeSetup::Passive => RustSdpAttributeSetup::Passive, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_setup( + attributes: *const Vec, + ret: *mut RustSdpAttributeSetup, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Setup); + if let Some(&SdpAttribute::Setup(ref setup)) = attr { + *ret = RustSdpAttributeSetup::from(setup); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeSsrc { + pub id: u32, + pub attribute: StringView, + pub value: StringView, +} + +impl<'a> From<&'a SdpAttributeSsrc> for RustSdpAttributeSsrc { + fn from(other: &SdpAttributeSsrc) -> Self { + RustSdpAttributeSsrc { + id: other.id, + attribute: StringView::from(&other.attribute), + value: StringView::from(&other.value), + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_ssrc_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Ssrc) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_ssrcs( + attributes: *const Vec, + ret_size: size_t, + ret_ssrcs: *mut RustSdpAttributeSsrc, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Ssrc(ref data) = *x { + Some(RustSdpAttributeSsrc::from(data)) + } else { + None + } + }) + .collect(); + let ssrcs = slice::from_raw_parts_mut(ret_ssrcs, ret_size); + ssrcs.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub enum RustSdpSsrcGroupSemantic { + Duplication, + FlowIdentification, + ForwardErrorCorrection, + ForwardErrorCorrectionFr, + SIM, +} + +impl<'a> From<&'a SdpSsrcGroupSemantic> for RustSdpSsrcGroupSemantic { + fn from(other: &SdpSsrcGroupSemantic) -> Self { + match *other { + SdpSsrcGroupSemantic::Duplication => RustSdpSsrcGroupSemantic::Duplication, + SdpSsrcGroupSemantic::FlowIdentification => { + RustSdpSsrcGroupSemantic::FlowIdentification + } + SdpSsrcGroupSemantic::ForwardErrorCorrection => { + RustSdpSsrcGroupSemantic::ForwardErrorCorrection + } + SdpSsrcGroupSemantic::ForwardErrorCorrectionFr => { + RustSdpSsrcGroupSemantic::ForwardErrorCorrectionFr + } + SdpSsrcGroupSemantic::Sim => RustSdpSsrcGroupSemantic::SIM, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpSsrcGroup { + pub semantic: RustSdpSsrcGroupSemantic, + pub ssrcs: *const Vec, +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_ssrc_group_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::SsrcGroup) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_ssrc_groups( + attributes: *const Vec, + ret_size: size_t, + ret_ssrc_groups: *mut RustSdpSsrcGroup, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::SsrcGroup(ref semantic, ref ssrcs) = *x { + Some(RustSdpSsrcGroup { + semantic: RustSdpSsrcGroupSemantic::from(semantic), + ssrcs: ssrcs, + }) + } else { + None + } + }) + .collect(); + let ssrc_groups = slice::from_raw_parts_mut(ret_ssrc_groups, ret_size); + ssrc_groups.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeRtpmap { + pub payload_type: u8, + pub codec_name: StringView, + pub frequency: u32, + pub channels: u32, +} + +impl<'a> From<&'a SdpAttributeRtpmap> for RustSdpAttributeRtpmap { + fn from(other: &SdpAttributeRtpmap) -> Self { + RustSdpAttributeRtpmap { + payload_type: other.payload_type as u8, + codec_name: StringView::from(other.codec_name.as_str()), + frequency: other.frequency as u32, + channels: other.channels.unwrap_or(0), + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rtpmap_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Rtpmap) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rtpmaps( + attributes: *const Vec, + ret_size: size_t, + ret_rtpmaps: *mut RustSdpAttributeRtpmap, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Rtpmap(ref data) = *x { + Some(RustSdpAttributeRtpmap::from(data)) + } else { + None + } + }) + .collect(); + let rtpmaps = slice::from_raw_parts_mut(ret_rtpmaps, ret_size); + rtpmaps.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustRtxFmtpParameters { + pub apt: u8, + pub has_rtx_time: bool, + pub rtx_time: u32, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeFmtpParameters { + // H264 + pub packetization_mode: u32, + pub level_asymmetry_allowed: bool, + pub profile_level_id: u32, + pub max_fs: u32, + pub max_cpb: u32, + pub max_dpb: u32, + pub max_br: u32, + pub max_mbps: u32, + + // VP8 and VP9 + // max_fs, already defined in H264 + pub max_fr: u32, + + // Opus + pub maxplaybackrate: u32, + pub maxaveragebitrate: u32, + pub usedtx: bool, + pub stereo: bool, + pub useinbandfec: bool, + pub cbr: bool, + pub ptime: u32, + pub minptime: u32, + pub maxptime: u32, + + // telephone-event + pub dtmf_tones: StringView, + + // RTX + pub rtx: RustRtxFmtpParameters, + + // Red + pub encodings: *const Vec, + + // Unknown + pub unknown_tokens: *const Vec, +} + +impl<'a> From<&'a SdpAttributeFmtpParameters> for RustSdpAttributeFmtpParameters { + fn from(other: &SdpAttributeFmtpParameters) -> Self { + let rtx = if let Some(rtx) = other.rtx { + RustRtxFmtpParameters { + apt: rtx.apt, + has_rtx_time: rtx.rtx_time.is_some(), + rtx_time: rtx.rtx_time.unwrap_or(0), + } + } else { + RustRtxFmtpParameters { + apt: 0, + has_rtx_time: false, + rtx_time: 0, + } + }; + + RustSdpAttributeFmtpParameters { + packetization_mode: other.packetization_mode, + level_asymmetry_allowed: other.level_asymmetry_allowed, + profile_level_id: other.profile_level_id, + max_fs: other.max_fs, + max_cpb: other.max_cpb, + max_dpb: other.max_dpb, + max_br: other.max_br, + max_mbps: other.max_mbps, + usedtx: other.usedtx, + stereo: other.stereo, + useinbandfec: other.useinbandfec, + cbr: other.cbr, + max_fr: other.max_fr, + maxplaybackrate: other.maxplaybackrate, + maxaveragebitrate: other.maxaveragebitrate, + ptime: other.ptime, + minptime: other.minptime, + maxptime: other.maxptime, + dtmf_tones: StringView::from(other.dtmf_tones.as_str()), + rtx, + encodings: &other.encodings, + unknown_tokens: &other.unknown_tokens, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeFmtp { + pub payload_type: u8, + pub codec_name: StringView, + pub parameters: RustSdpAttributeFmtpParameters, +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_fmtp_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Fmtp) +} + +fn find_payload_type(attributes: &[SdpAttribute], payload_type: u8) -> Option<&SdpAttributeRtpmap> { + attributes + .iter() + .filter_map(|x| { + if let SdpAttribute::Rtpmap(ref data) = *x { + if data.payload_type == payload_type { + Some(data) + } else { + None + } + } else { + None + } + }) + .next() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_fmtp( + attributes: *const Vec, + ret_size: size_t, + ret_fmtp: *mut RustSdpAttributeFmtp, +) -> size_t { + let fmtps = (*attributes).iter().filter_map(|x| { + if let SdpAttribute::Fmtp(ref data) = *x { + Some(data) + } else { + None + } + }); + let mut rust_fmtps = Vec::new(); + for fmtp in fmtps { + if let Some(rtpmap) = find_payload_type((*attributes).as_slice(), fmtp.payload_type) { + rust_fmtps.push(RustSdpAttributeFmtp { + payload_type: fmtp.payload_type as u8, + codec_name: StringView::from(rtpmap.codec_name.as_str()), + parameters: RustSdpAttributeFmtpParameters::from(&fmtp.parameters), + }); + } + } + let fmtps = if ret_size <= rust_fmtps.len() { + slice::from_raw_parts_mut(ret_fmtp, ret_size) + } else { + slice::from_raw_parts_mut(ret_fmtp, rust_fmtps.len()) + }; + fmtps.copy_from_slice(rust_fmtps.as_slice()); + fmtps.len() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_ptime(attributes: *const Vec) -> i64 { + for attribute in (*attributes).iter() { + if let SdpAttribute::Ptime(time) = *attribute { + return time as i64; + } + } + -1 +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_max_msg_size(attributes: *const Vec) -> i64 { + for attribute in (*attributes).iter() { + if let SdpAttribute::MaxMessageSize(max_msg_size) = *attribute { + return max_msg_size as i64; + } + } + -1 +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_sctp_port(attributes: *const Vec) -> i64 { + for attribute in (*attributes).iter() { + if let SdpAttribute::SctpPort(port) = *attribute { + return port as i64; + } + } + -1 +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeFlags { + pub ice_lite: bool, + pub rtcp_mux: bool, + pub rtcp_rsize: bool, + pub bundle_only: bool, + pub end_of_candidates: bool, +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_attribute_flags( + attributes: *const Vec, +) -> RustSdpAttributeFlags { + let mut ret = RustSdpAttributeFlags { + ice_lite: false, + rtcp_mux: false, + rtcp_rsize: false, + bundle_only: false, + end_of_candidates: false, + }; + for attribute in (*attributes).iter() { + if let SdpAttribute::IceLite = *attribute { + ret.ice_lite = true; + } else if let SdpAttribute::RtcpMux = *attribute { + ret.rtcp_mux = true; + } else if let SdpAttribute::RtcpRsize = *attribute { + ret.rtcp_rsize = true; + } else if let SdpAttribute::BundleOnly = *attribute { + ret.bundle_only = true; + } else if let SdpAttribute::EndOfCandidates = *attribute { + ret.end_of_candidates = true; + } + } + ret +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_mid( + attributes: *const Vec, + ret: *mut StringView, +) -> nsresult { + for attribute in (*attributes).iter() { + if let SdpAttribute::Mid(ref data) = *attribute { + *ret = StringView::from(data.as_str()); + return NS_OK; + } + } + NS_ERROR_INVALID_ARG +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeMsid { + id: StringView, + appdata: StringView, +} + +impl<'a> From<&'a SdpAttributeMsid> for RustSdpAttributeMsid { + fn from(other: &SdpAttributeMsid) -> Self { + RustSdpAttributeMsid { + id: StringView::from(other.id.as_str()), + appdata: StringView::from(&other.appdata), + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_msid_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Msid) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_msids( + attributes: *const Vec, + ret_size: size_t, + ret_msids: *mut RustSdpAttributeMsid, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Msid(ref data) = *x { + Some(RustSdpAttributeMsid::from(data)) + } else { + None + } + }) + .collect(); + let msids = slice::from_raw_parts_mut(ret_msids, ret_size); + msids.copy_from_slice(attrs.as_slice()); +} + +// TODO: Finish msid attributes once parsing is changed upstream. +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeMsidSemantic { + pub semantic: StringView, + pub msids: *const Vec, +} + +impl<'a> From<&'a SdpAttributeMsidSemantic> for RustSdpAttributeMsidSemantic { + fn from(other: &SdpAttributeMsidSemantic) -> Self { + RustSdpAttributeMsidSemantic { + semantic: StringView::from(other.semantic.as_str()), + msids: &other.msids, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_msid_semantic_count( + attributes: *const Vec, +) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::MsidSemantic) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_msid_semantics( + attributes: *const Vec, + ret_size: size_t, + ret_msid_semantics: *mut RustSdpAttributeMsidSemantic, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::MsidSemantic(ref data) = *x { + Some(RustSdpAttributeMsidSemantic::from(data)) + } else { + None + } + }) + .collect(); + let msid_semantics = slice::from_raw_parts_mut(ret_msid_semantics, ret_size); + msid_semantics.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub enum RustSdpAttributeGroupSemantic { + LipSynchronization, + FlowIdentification, + SingleReservationFlow, + AlternateNetworkAddressType, + ForwardErrorCorrection, + DecodingDependency, + Bundle, +} + +impl<'a> From<&'a SdpAttributeGroupSemantic> for RustSdpAttributeGroupSemantic { + fn from(other: &SdpAttributeGroupSemantic) -> Self { + match *other { + SdpAttributeGroupSemantic::LipSynchronization => { + RustSdpAttributeGroupSemantic::LipSynchronization + } + SdpAttributeGroupSemantic::FlowIdentification => { + RustSdpAttributeGroupSemantic::FlowIdentification + } + SdpAttributeGroupSemantic::SingleReservationFlow => { + RustSdpAttributeGroupSemantic::SingleReservationFlow + } + SdpAttributeGroupSemantic::AlternateNetworkAddressType => { + RustSdpAttributeGroupSemantic::AlternateNetworkAddressType + } + SdpAttributeGroupSemantic::ForwardErrorCorrection => { + RustSdpAttributeGroupSemantic::ForwardErrorCorrection + } + SdpAttributeGroupSemantic::DecodingDependency => { + RustSdpAttributeGroupSemantic::DecodingDependency + } + SdpAttributeGroupSemantic::Bundle => RustSdpAttributeGroupSemantic::Bundle, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeGroup { + pub semantic: RustSdpAttributeGroupSemantic, + pub tags: *const Vec, +} + +impl<'a> From<&'a SdpAttributeGroup> for RustSdpAttributeGroup { + fn from(other: &SdpAttributeGroup) -> Self { + RustSdpAttributeGroup { + semantic: RustSdpAttributeGroupSemantic::from(&other.semantics), + tags: &other.tags, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_group_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Group) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_groups( + attributes: *const Vec, + ret_size: size_t, + ret_groups: *mut RustSdpAttributeGroup, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Group(ref data) = *x { + Some(RustSdpAttributeGroup::from(data)) + } else { + None + } + }) + .collect(); + let groups = slice::from_raw_parts_mut(ret_groups, ret_size); + groups.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +pub struct RustSdpAttributeRtcp { + pub port: u32, + pub unicast_addr: RustExplicitlyTypedAddress, + pub has_address: bool, +} + +impl<'a> From<&'a SdpAttributeRtcp> for RustSdpAttributeRtcp { + fn from(other: &SdpAttributeRtcp) -> Self { + match other.unicast_addr { + Some(ref address) => RustSdpAttributeRtcp { + port: other.port as u32, + unicast_addr: address.into(), + has_address: true, + }, + None => RustSdpAttributeRtcp { + port: other.port as u32, + unicast_addr: RustExplicitlyTypedAddress::default(), + has_address: false, + }, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rtcp( + attributes: *const Vec, + ret: *mut RustSdpAttributeRtcp, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Rtcp); + if let Some(&SdpAttribute::Rtcp(ref data)) = attr { + *ret = RustSdpAttributeRtcp::from(data); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeRtcpFb { + pub payload_type: u32, + pub feedback_type: u32, + pub parameter: StringView, + pub extra: StringView, +} + +impl<'a> From<&'a SdpAttributeRtcpFb> for RustSdpAttributeRtcpFb { + fn from(other: &SdpAttributeRtcpFb) -> Self { + RustSdpAttributeRtcpFb { + payload_type: match other.payload_type { + SdpAttributePayloadType::Wildcard => u32::max_value(), + SdpAttributePayloadType::PayloadType(x) => x as u32, + }, + feedback_type: other.feedback_type.clone() as u32, + parameter: StringView::from(other.parameter.as_str()), + extra: StringView::from(other.extra.as_str()), + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rtcpfb_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Rtcpfb) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rtcpfbs( + attributes: *const Vec, + ret_size: size_t, + ret_rtcpfbs: *mut RustSdpAttributeRtcpFb, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Rtcpfb(ref data) = *x { + Some(RustSdpAttributeRtcpFb::from(data)) + } else { + None + } + }) + .collect(); + let rtcpfbs = slice::from_raw_parts_mut(ret_rtcpfbs, ret_size); + rtcpfbs.clone_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeImageAttrXyRange { + // range + pub min: u32, + pub max: u32, + pub step: u32, + + // discrete values + pub discrete_values: *const Vec, +} + +impl<'a> From<&'a SdpAttributeImageAttrXyRange> for RustSdpAttributeImageAttrXyRange { + fn from(other: &SdpAttributeImageAttrXyRange) -> Self { + match other { + &SdpAttributeImageAttrXyRange::Range(min, max, step) => { + RustSdpAttributeImageAttrXyRange { + min, + max, + step: step.unwrap_or(1), + discrete_values: ptr::null(), + } + } + &SdpAttributeImageAttrXyRange::DiscreteValues(ref discrete_values) => { + RustSdpAttributeImageAttrXyRange { + min: 0, + max: 1, + step: 1, + discrete_values, + } + } + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeImageAttrSRange { + // range + pub min: c_float, + pub max: c_float, + + // discrete values + pub discrete_values: *const Vec, +} + +impl<'a> From<&'a SdpAttributeImageAttrSRange> for RustSdpAttributeImageAttrSRange { + fn from(other: &SdpAttributeImageAttrSRange) -> Self { + match other { + &SdpAttributeImageAttrSRange::Range(min, max) => RustSdpAttributeImageAttrSRange { + min, + max, + discrete_values: ptr::null(), + }, + &SdpAttributeImageAttrSRange::DiscreteValues(ref discrete_values) => { + RustSdpAttributeImageAttrSRange { + min: 0.0, + max: 1.0, + discrete_values, + } + } + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeImageAttrPRange { + pub min: c_float, + pub max: c_float, +} + +impl<'a> From<&'a SdpAttributeImageAttrPRange> for RustSdpAttributeImageAttrPRange { + fn from(other: &SdpAttributeImageAttrPRange) -> Self { + RustSdpAttributeImageAttrPRange { + min: other.min, + max: other.max, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeImageAttrSet { + pub x: RustSdpAttributeImageAttrXyRange, + pub y: RustSdpAttributeImageAttrXyRange, + + pub has_sar: bool, + pub sar: RustSdpAttributeImageAttrSRange, + + pub has_par: bool, + pub par: RustSdpAttributeImageAttrPRange, + + pub q: c_float, +} + +impl<'a> From<&'a SdpAttributeImageAttrSet> for RustSdpAttributeImageAttrSet { + fn from(other: &SdpAttributeImageAttrSet) -> Self { + RustSdpAttributeImageAttrSet { + x: RustSdpAttributeImageAttrXyRange::from(&other.x), + y: RustSdpAttributeImageAttrXyRange::from(&other.y), + + has_sar: other.sar.is_some(), + sar: match other.sar { + Some(ref x) => RustSdpAttributeImageAttrSRange::from(x), + // This is just any valid value accepted by rust, + // it might as well by uninitilized + None => RustSdpAttributeImageAttrSRange::from( + &SdpAttributeImageAttrSRange::DiscreteValues(vec![]), + ), + }, + + has_par: other.par.is_some(), + par: match other.par { + Some(ref x) => RustSdpAttributeImageAttrPRange::from(x), + // This is just any valid value accepted by rust, + // it might as well by uninitilized + None => RustSdpAttributeImageAttrPRange { min: 0.0, max: 1.0 }, + }, + + q: other.q.unwrap_or(0.5), + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeImageAttrSetList { + pub sets: *const Vec, +} + +impl<'a> From<&'a SdpAttributeImageAttrSetList> for RustSdpAttributeImageAttrSetList { + fn from(other: &SdpAttributeImageAttrSetList) -> Self { + match other { + &SdpAttributeImageAttrSetList::Wildcard => { + RustSdpAttributeImageAttrSetList { sets: ptr::null() } + } + &SdpAttributeImageAttrSetList::Sets(ref sets) => { + RustSdpAttributeImageAttrSetList { sets: sets } + } + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_imageattr_get_set_count( + sets: *const Vec, +) -> size_t { + (*sets).len() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_imageattr_get_sets( + sets: *const Vec, + ret_size: size_t, + ret: *mut RustSdpAttributeImageAttrSet, +) { + let rust_sets: Vec<_> = (*sets) + .iter() + .map(RustSdpAttributeImageAttrSet::from) + .collect(); + let sets = slice::from_raw_parts_mut(ret, ret_size); + sets.clone_from_slice(rust_sets.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeImageAttr { + pub pt: u32, + pub send: RustSdpAttributeImageAttrSetList, + pub recv: RustSdpAttributeImageAttrSetList, +} + +impl<'a> From<&'a SdpAttributeImageAttr> for RustSdpAttributeImageAttr { + fn from(other: &SdpAttributeImageAttr) -> Self { + RustSdpAttributeImageAttr { + pt: match other.pt { + SdpAttributePayloadType::Wildcard => u32::max_value(), + SdpAttributePayloadType::PayloadType(x) => x as u32, + }, + send: RustSdpAttributeImageAttrSetList::from(&other.send), + recv: RustSdpAttributeImageAttrSetList::from(&other.recv), + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_imageattr_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::ImageAttr) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_imageattrs( + attributes: *const Vec, + ret_size: size_t, + ret_attrs: *mut RustSdpAttributeImageAttr, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::ImageAttr(ref data) = *x { + Some(RustSdpAttributeImageAttr::from(data)) + } else { + None + } + }) + .collect(); + let imageattrs = slice::from_raw_parts_mut(ret_attrs, ret_size); + imageattrs.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeSctpmap { + pub port: u32, + pub channels: u32, +} + +impl<'a> From<&'a SdpAttributeSctpmap> for RustSdpAttributeSctpmap { + fn from(other: &SdpAttributeSctpmap) -> Self { + RustSdpAttributeSctpmap { + port: other.port as u32, + channels: other.channels, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_sctpmap_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Sctpmap) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_sctpmaps( + attributes: *const Vec, + ret_size: size_t, + ret_sctpmaps: *mut RustSdpAttributeSctpmap, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Sctpmap(ref data) = *x { + Some(RustSdpAttributeSctpmap::from(data)) + } else { + None + } + }) + .collect(); + let sctpmaps = slice::from_raw_parts_mut(ret_sctpmaps, ret_size); + sctpmaps.copy_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeSimulcastId { + pub id: StringView, + pub paused: bool, +} + +impl<'a> From<&'a SdpAttributeSimulcastId> for RustSdpAttributeSimulcastId { + fn from(other: &SdpAttributeSimulcastId) -> Self { + RustSdpAttributeSimulcastId { + id: StringView::from(other.id.as_str()), + paused: other.paused, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeSimulcastVersion { + pub ids: *const Vec, +} + +impl<'a> From<&'a SdpAttributeSimulcastVersion> for RustSdpAttributeSimulcastVersion { + fn from(other: &SdpAttributeSimulcastVersion) -> Self { + RustSdpAttributeSimulcastVersion { ids: &other.ids } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_simulcast_get_ids_count( + ids: *const Vec, +) -> size_t { + (*ids).len() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_simulcast_get_ids( + ids: *const Vec, + ret_size: size_t, + ret: *mut RustSdpAttributeSimulcastId, +) { + let rust_ids: Vec<_> = (*ids) + .iter() + .map(RustSdpAttributeSimulcastId::from) + .collect(); + let ids = slice::from_raw_parts_mut(ret, ret_size); + ids.clone_from_slice(rust_ids.as_slice()); +} + +#[repr(C)] +pub struct RustSdpAttributeSimulcast { + pub send: *const Vec, + pub receive: *const Vec, +} + +impl<'a> From<&'a SdpAttributeSimulcast> for RustSdpAttributeSimulcast { + fn from(other: &SdpAttributeSimulcast) -> Self { + RustSdpAttributeSimulcast { + send: &other.send, + receive: &other.receive, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_simulcast_get_version_count( + version_list: *const Vec, +) -> size_t { + (*version_list).len() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_simulcast_get_versions( + version_list: *const Vec, + ret_size: size_t, + ret: *mut RustSdpAttributeSimulcastVersion, +) { + let rust_versions_list: Vec<_> = (*version_list) + .iter() + .map(RustSdpAttributeSimulcastVersion::from) + .collect(); + let versions = slice::from_raw_parts_mut(ret, ret_size); + versions.clone_from_slice(rust_versions_list.as_slice()) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_simulcast( + attributes: *const Vec, + ret: *mut RustSdpAttributeSimulcast, +) -> nsresult { + let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Simulcast); + if let Some(&SdpAttribute::Simulcast(ref data)) = attr { + *ret = RustSdpAttributeSimulcast::from(data); + return NS_OK; + } + NS_ERROR_INVALID_ARG +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub enum RustDirection { + Recvonly, + Sendonly, + Sendrecv, + Inactive, +} + +impl<'a> From<&'a Option> for RustDirection { + fn from(other: &Option) -> Self { + match *other { + Some(ref direction) => match *direction { + SdpAttributeDirection::Recvonly => RustDirection::Recvonly, + SdpAttributeDirection::Sendonly => RustDirection::Sendonly, + SdpAttributeDirection::Sendrecv => RustDirection::Sendrecv, + }, + None => RustDirection::Inactive, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_direction(attributes: *const Vec) -> RustDirection { + for attribute in (*attributes).iter() { + match *attribute { + SdpAttribute::Recvonly => { + return RustDirection::Recvonly; + } + SdpAttribute::Sendonly => { + return RustDirection::Sendonly; + } + SdpAttribute::Sendrecv => { + return RustDirection::Sendrecv; + } + SdpAttribute::Inactive => { + return RustDirection::Inactive; + } + _ => (), + } + } + RustDirection::Sendrecv +} + +#[repr(C)] +pub struct RustSdpAttributeRemoteCandidate { + pub component: u32, + pub address: RustAddress, + pub port: u32, +} + +impl<'a> From<&'a SdpAttributeRemoteCandidate> for RustSdpAttributeRemoteCandidate { + fn from(other: &SdpAttributeRemoteCandidate) -> Self { + RustSdpAttributeRemoteCandidate { + component: other.component, + address: RustAddress::from(&other.address), + port: other.port, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_remote_candidate_count( + attributes: *const Vec, +) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::RemoteCandidate) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_remote_candidates( + attributes: *const Vec, + ret_size: size_t, + ret_candidates: *mut RustSdpAttributeRemoteCandidate, +) { + let attrs = (*attributes).iter().filter_map(|x| { + if let SdpAttribute::RemoteCandidate(ref data) = *x { + Some(RustSdpAttributeRemoteCandidate::from(data)) + } else { + None + } + }); + let candidates = slice::from_raw_parts_mut(ret_candidates, ret_size); + for (source, destination) in attrs.zip(candidates) { + *destination = source + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_candidate_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Candidate) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_candidates( + attributes: *const Vec, + _ret_size: size_t, + ret: *mut *const Vec, +) { + let attr_strings: Vec = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Candidate(ref attr) = *x { + // The serialized attribute starts with "candidate:...", this needs to be removed + Some(attr.to_string()) + } else { + None + } + }) + .collect(); + + *ret = Box::into_raw(Box::from(attr_strings)); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeRidParameters { + pub max_width: u32, + pub max_height: u32, + pub max_fps: u32, + pub max_fs: u32, + pub max_br: u32, + pub max_pps: u32, + pub unknown: *const Vec, +} + +impl<'a> From<&'a SdpAttributeRidParameters> for RustSdpAttributeRidParameters { + fn from(other: &SdpAttributeRidParameters) -> Self { + RustSdpAttributeRidParameters { + max_width: other.max_width, + max_height: other.max_height, + max_fps: other.max_fps, + max_fs: other.max_fs, + max_br: other.max_br, + max_pps: other.max_pps, + + unknown: &other.unknown, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeRid { + pub id: StringView, + pub direction: u32, + pub formats: *const Vec, + pub params: RustSdpAttributeRidParameters, + pub depends: *const Vec, +} + +impl<'a> From<&'a SdpAttributeRid> for RustSdpAttributeRid { + fn from(other: &SdpAttributeRid) -> Self { + RustSdpAttributeRid { + id: StringView::from(other.id.as_str()), + direction: other.direction.clone() as u32, + formats: &other.formats, + params: RustSdpAttributeRidParameters::from(&other.params), + depends: &other.depends, + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rid_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Rid) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_rids( + attributes: *const Vec, + ret_size: size_t, + ret_rids: *mut RustSdpAttributeRid, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Rid(ref data) = *x { + Some(RustSdpAttributeRid::from(data)) + } else { + None + } + }) + .collect(); + let rids = slice::from_raw_parts_mut(ret_rids, ret_size); + rids.clone_from_slice(attrs.as_slice()); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct RustSdpAttributeExtmap { + pub id: u16, + pub direction_specified: bool, + pub direction: RustDirection, + pub url: StringView, + pub extension_attributes: StringView, +} + +impl<'a> From<&'a SdpAttributeExtmap> for RustSdpAttributeExtmap { + fn from(other: &SdpAttributeExtmap) -> Self { + let dir = if other.direction.is_some() { + RustDirection::from(&other.direction) + } else { + RustDirection::from(&Some(SdpAttributeDirection::Sendrecv)) + }; + RustSdpAttributeExtmap { + id: other.id as u16, + direction_specified: other.direction.is_some(), + direction: dir, + url: StringView::from(other.url.as_str()), + extension_attributes: StringView::from(&other.extension_attributes), + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_extmap_count(attributes: *const Vec) -> size_t { + count_attribute((*attributes).as_slice(), SdpAttributeType::Extmap) +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_get_extmaps( + attributes: *const Vec, + ret_size: size_t, + ret_rids: *mut RustSdpAttributeExtmap, +) { + let attrs: Vec<_> = (*attributes) + .iter() + .filter_map(|x| { + if let SdpAttribute::Extmap(ref data) = *x { + Some(RustSdpAttributeExtmap::from(data)) + } else { + None + } + }) + .collect(); + let extmaps = slice::from_raw_parts_mut(ret_rids, ret_size); + extmaps.copy_from_slice(attrs.as_slice()); +} -- cgit v1.2.3