前言
上一节的打断点
SdpOfferAnswerHandler::ApplyLocalDescription {SdpOfferAnswerHandler::PushdownTransportDescriptionSdpOfferAnswerHandler::UpdateTransceiversAndDataChannelsSdpOfferAnswerHandler::UpdateSessionState}
代码分析
SdpOfferAnswerHandler::ApplyLocalDescription
SdpOfferAnswerHandler::ApplyLocalDescription {// 创建各种Transport,里面根据是否是cricket::CS_LOCAL或CS_REMOTE来处理SdpOfferAnswerHandler::PushdownTransportDescription// 更新Transceivers 和 DataChannelsSdpOfferAnswerHandler::UpdateTransceiversAndDataChannelsSdpOfferAnswerHandler::UpdateSessionState}
SdpOfferAnswerHandler::PushdownTransportDescription
SdpOfferAnswerHandler::PushdownTransportDescription
->
JsepTransportController::SetLocalDescription
->
JsepTransportController::ApplyDescription_n
->
JsepTransportController::MaybeCreateJsepTransport
JsepTransport::SetLocalJsepTransportDescription
JsepTransportController::MaybeCreateJsepTransport
创建各种transport,并且打包在一起
RTCError JsepTransportController::MaybeCreateJsepTransport(bool local,const cricket::ContentInfo& content_info,const cricket::SessionDescription& description) {cricket::JsepTransport* transport = GetJsepTransportByName(content_info.name);if (transport) {return RTCError::OK();}const cricket::MediaContentDescription* content_desc =content_info.media_description();if (certificate_ && !content_desc->cryptos().empty()) {return RTCError(RTCErrorType::INVALID_PARAMETER,"SDES and DTLS-SRTP cannot be enabled at the same time.");}创建IceTransportrtc::scoped_refptr<webrtc::IceTransportInterface> ice =CreateIceTransport(content_info.name, /*rtcp=*/false);RTC_DCHECK(ice);创建DtlsTransportstd::unique_ptr<cricket::DtlsTransportInternal> rtp_dtls_transport =CreateDtlsTransport(content_info, ice->internal());std::unique_ptr<cricket::DtlsTransportInternal> rtcp_dtls_transport;std::unique_ptr<RtpTransport> unencrypted_rtp_transport;std::unique_ptr<SrtpTransport> sdes_transport;std::unique_ptr<DtlsSrtpTransport> dtls_srtp_transport;rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice;if (config_.rtcp_mux_policy !=PeerConnectionInterface::kRtcpMuxPolicyRequire &&content_info.type == cricket::MediaProtocolType::kRtp) {rtcp_ice = CreateIceTransport(content_info.name, /*rtcp=*/true);rtcp_dtls_transport =CreateDtlsTransport(content_info, rtcp_ice->internal());}if (config_.disable_encryption) {RTC_LOG(LS_INFO)<< "Creating UnencryptedRtpTransport, becayse encryption is disabled.";unencrypted_rtp_transport = CreateUnencryptedRtpTransport(content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());} else if (!content_desc->cryptos().empty()) {sdes_transport = CreateSdesTransport(content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());RTC_LOG(LS_INFO) << "Creating SdesTransport.";} else {RTC_LOG(LS_INFO) << "Creating DtlsSrtpTransport.";dtls_srtp_transport = CreateDtlsSrtpTransport(content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());}std::unique_ptr<cricket::SctpTransportInternal> sctp_transport;if (config_.sctp_factory) {sctp_transport =config_.sctp_factory->CreateSctpTransport(rtp_dtls_transport.get());}// 将前面创建好的transport打包在一起std::unique_ptr<cricket::JsepTransport> jsep_transport =std::make_unique<cricket::JsepTransport>(content_info.name, certificate_, std::move(ice), std::move(rtcp_ice),std::move(unencrypted_rtp_transport), std::move(sdes_transport),std::move(dtls_srtp_transport), std::move(rtp_dtls_transport),std::move(rtcp_dtls_transport), std::move(sctp_transport));jsep_transport->rtp_transport()->SignalRtcpPacketReceived.connect(this, &JsepTransportController::OnRtcpPacketReceived_n);jsep_transport->SignalRtcpMuxActive.connect(this, &JsepTransportController::UpdateAggregateStates_n);SetTransportForMid(content_info.name, jsep_transport.get());jsep_transports_by_name_[content_info.name] = std::move(jsep_transport);UpdateAggregateStates_n();return RTCError::OK();}
SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
->
SdpOfferAnswerHandler::UpdateTransceiverChannel
->
if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
SdpOfferAnswerHandler::CreateVoiceChannel(content.name);
} else {
SdpOfferAnswerHandler::CreateVideoChannel(content.name);
}
->
SdpOfferAnswerHandler::CreateVoiceChannel
->
ChannelManager::CreateVoiceChannel
->
WebRtcVoiceEngine::CreateMediaChannel(
webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options)
->
new WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel
SdpOfferAnswerHandler::UpdateSessionState
BaseChannel::SetLocalContent
bool BaseChannel::SetLocalContent(const MediaContentDescription* content,SdpType type,std::string* error_desc) {TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");return InvokeOnWorker<bool>(RTC_FROM_HERE, [this, content, type, error_desc] {RTC_DCHECK_RUN_ON(worker_thread());return SetLocalContent_w(content, type, error_desc);});}
BaseChannel::SetLocalContent中使用了InvokeOnWorker,最后会根据SdpType类型,是调用
VideoChannel::SetLocalContent_w 还是 VoiceChannel::SetLocalContent_w 。
