pub(super) async fn generate_unmatched_sdp(
        &self,
        local_transceivers: Vec<Arc<RTCRtpTransceiver>>,
        use_identity: bool,
        sdp_semantics: RTCSdpSemantics,
    ) -> Result<SessionDescription> {
        let d = SessionDescription::new_jsep_session_description(use_identity);

        let ice_params = self.ice_gatherer.get_local_parameters().await?;

        let candidates = self.ice_gatherer.get_local_candidates().await?;

        let is_plan_b = sdp_semantics == RTCSdpSemantics::PlanB;
        let mut media_sections = vec![];

        // Needed for self.sctpTransport.dataChannelsRequested
        if is_plan_b {
            let mut video = vec![];
            let mut audio = vec![];

            for t in &local_transceivers {
                if t.kind == RTPCodecType::Video {
                    video.push(Arc::clone(t));
                } else if t.kind == RTPCodecType::Audio {
                    audio.push(Arc::clone(t));
                }
                if let Some(sender) = t.sender().await {
                    sender.set_negotiated();
                }
            }

            if !video.is_empty() {
                media_sections.push(MediaSection {
                    id: "video".to_owned(),
                    transceivers: video,
                    ..Default::default()
                })
            }
            if !audio.is_empty() {
                media_sections.push(MediaSection {
                    id: "audio".to_owned(),
                    transceivers: audio,
                    ..Default::default()
                });
            }

            if self
                .sctp_transport
                .data_channels_requested
                .load(Ordering::SeqCst)
                != 0
            {
                media_sections.push(MediaSection {
                    id: "data".to_owned(),
                    data: true,
                    ..Default::default()
                });
            }
        } else {
            {
                for t in &local_transceivers {
                    if let Some(sender) = t.sender().await {
                        sender.set_negotiated();
                    }
                    media_sections.push(MediaSection {
                        id: t.mid().await,
                        transceivers: vec![Arc::clone(t)],
                        ..Default::default()
                    });
                }
            }

            if self
                .sctp_transport
                .data_channels_requested
                .load(Ordering::SeqCst)
                != 0
            {
                media_sections.push(MediaSection {
                    id: format!("{}", media_sections.len()),
                    data: true,
                    ..Default::default()
                });
            }
        }

        let dtls_fingerprints = if let Some(cert) = self.dtls_transport.certificates.first() {
            cert.get_fingerprints()?
        } else {
            return Err(Error::ErrNonCertificate);
        };

        let params = PopulateSdpParams {
            is_plan_b,
            media_description_fingerprint: self.setting_engine.sdp_media_level_fingerprints,
            is_icelite: self.setting_engine.candidates.ice_lite,
            connection_role: DEFAULT_DTLS_ROLE_OFFER.to_connection_role(),
            ice_gathering_state: self.ice_gathering_state(),
        };
        populate_sdp(
            d,
            &dtls_fingerprints,
            &self.media_engine,
            &candidates,
            &ice_params,
            &media_sections,
            params,
        )
        .await
    }
/// generate_unmatched_sdp generates an SDP that doesn't take remote state into account
/// This is used for the initial call for CreateOffer
generate_unmatched_sdp generates an SDP that doesn't take remote state into account
This is used for the initial call for CreateOffer
generate_unmatched_sdp generates an SDP that doesn ' t take remote state into account This is used for the initial call for CreateOffer
pub(super) async fn generate_unmatched_sdp(
        &self,
        local_transceivers: Vec<Arc<RTCRtpTransceiver>>,
        use_identity: bool,
        sdp_semantics: RTCSdpSemantics,
    ) -> Result<SessionDescription> {
        let d = SessionDescription::new_jsep_session_description(use_identity);
        let ice_params = self.ice_gatherer.get_local_parameters().await?;
        let candidates = self.ice_gatherer.get_local_candidates().await?;
        let is_plan_b = sdp_semantics == RTCSdpSemantics::PlanB;
        let mut media_sections = vec![];
        // Needed for self.sctpTransport.dataChannelsRequested
        if is_plan_b {
            let mut video = vec![];
            let mut audio = vec![];
            for t in &local_transceivers {
                if t.kind == RTPCodecType::Video {
                    video.push(Arc::clone(t));
                } else if t.kind == RTPCodecType::Audio {
                    audio.push(Arc::clone(t));
                }
                if let Some(sender) = t.sender().await {
                    sender.set_negotiated();
                }
            }
            if !video.is_empty() {
                media_sections.push(MediaSection {
                    id: "video".to_owned(),
                    transceivers: video,
                    ..Default::default()
                })
            }
            if !audio.is_empty() {
                media_sections.push(MediaSection {
                    id: "audio".to_owned(),
                    transceivers: audio,
                    ..Default::default()
                });
            }
            if self
                .sctp_transport
                .data_channels_requested
                .load(Ordering::SeqCst)
                != 0
            {
                media_sections.push(MediaSection {
                    id: "data".to_owned(),
                    data: true,
                    ..Default::default()
                });
            }
        } else {
            {
                for t in &local_transceivers {
                    if let Some(sender) = t.sender().await {
                        sender.set_negotiated();
                    }
                    media_sections.push(MediaSection {
                        id: t.mid().await,
                        transceivers: vec![Arc::clone(t)],
                        ..Default::default()
                    });
                }
            }
            if self
                .sctp_transport
                .data_channels_requested
                .load(Ordering::SeqCst)
                != 0
            {
                media_sections.push(MediaSection {
                    id: format!("{}", media_sections.len()),
                    data: true,
                    ..Default::default()
                });
            }
        }
        let dtls_fingerprints = if let Some(cert) = self.dtls_transport.certificates.first() {
            cert.get_fingerprints()?
        } else {
            return Err(Error::ErrNonCertificate);
        };
        let params = PopulateSdpParams {
            is_plan_b,
            media_description_fingerprint: self.setting_engine.sdp_media_level_fingerprints,
            is_icelite: self.setting_engine.candidates.ice_lite,
            connection_role: DEFAULT_DTLS_ROLE_OFFER.to_connection_role(),
            ice_gathering_state: self.ice_gathering_state(),
        };
        populate_sdp(
            d,
            &dtls_fingerprints,
            &self.media_engine,
            &candidates,
            &ice_params,
            &media_sections,
            params,
        )
        .await
    }
pub ( super ) async fn generate_unmatched_sdp ( & self , local_transceivers : Vec < Arc < RTCRtpTransceiver > > , use_identity : bool , sdp_semantics : RTCSdpSemantics , ) -> Result < SessionDescription > { let d = SessionDescription :: new_jsep_session_description ( use_identity ) ; let ice_params = self . ice_gatherer . get_local_parameters ( ) . await ? ; let candidates = self . ice_gatherer . get_local_candidates ( ) . await ? ; let is_plan_b = sdp_semantics == RTCSdpSemantics :: PlanB ; let mut media_sections = vec ! [ ] ; // Needed for self.sctpTransport.dataChannelsRequested if is_plan_b { let mut video = vec ! [ ] ; let mut audio = vec ! [ ] ; for t in & local_transceivers { if t . kind == RTPCodecType :: Video { video . push ( Arc :: clone ( t ) ) ; } else if t . kind == RTPCodecType :: Audio { audio . push ( Arc :: clone ( t ) ) ; } if let Some ( sender ) = t . sender ( ) . await { sender . set_negotiated ( ) ; } } if ! video . is_empty ( ) { media_sections . push ( MediaSection { id : " " . to_owned ( ) , transceivers : video , .. Default :: default ( ) } ) } if ! audio . is_empty ( ) { media_sections . push ( MediaSection { id : " " . to_owned ( ) , transceivers : audio , .. Default :: default ( ) } ) ; } if self . sctp_transport . data_channels_requested . load ( Ordering :: SeqCst ) != 0 { media_sections . push ( MediaSection { id : " " . to_owned ( ) , data : true , .. Default :: default ( ) } ) ; } } else { { for t in & local_transceivers { if let Some ( sender ) = t . sender ( ) . await { sender . set_negotiated ( ) ; } media_sections . push ( MediaSection { id : t . mid ( ) . await , transceivers : vec ! [ Arc clone ( t ) ] , .. Default :: default ( ) } ) ; } } if self . sctp_transport . data_channels_requested . load ( Ordering :: SeqCst ) != 0 { media_sections . push ( MediaSection { id : format ! ( " " media_sections len ( ) ) , data : true , .. Default :: default ( ) } ) ; } } let dtls_fingerprints = if let Some ( cert ) = self . dtls_transport . certificates . first ( ) { cert . get_fingerprints ( ) ? } else { return Err ( Error :: ErrNonCertificate ) ; } ; let params = PopulateSdpParams { is_plan_b , media_description_fingerprint : self . setting_engine . sdp_media_level_fingerprints , is_icelite : self . setting_engine . candidates . ice_lite , connection_role : DEFAULT_DTLS_ROLE_OFFER . to_connection_role ( ) , ice_gathering_state : self . ice_gathering_state ( ) , } ; populate_sdp ( d , & dtls_fingerprints , & self . media_engine , & candidates , & ice_params , & media_sections , params , ) . await }
generate_unmatched_sdp generates an SDP that doesn't take remote state into account
This is used for the initial call for CreateOffer
generate_unmatched_sdp generates an SDP that doesn ' t take remote state into account This is used for the initial call for CreateOffer
&self
local_transceivers
Vec<Arc<RTCRtpTransceiver>>
use_identity
bool
sdp_semantics
RTCSdpSemantics