前言
上一节的打断点
SdpOfferAnswerHandler::ApplyLocalDescription {
SdpOfferAnswerHandler::PushdownTransportDescription
SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
SdpOfferAnswerHandler::UpdateSessionState
}
代码分析
SdpOfferAnswerHandler::ApplyLocalDescription
SdpOfferAnswerHandler::ApplyLocalDescription {
// 创建各种Transport,里面根据是否是cricket::CS_LOCAL或CS_REMOTE来处理
SdpOfferAnswerHandler::PushdownTransportDescription
// 更新Transceivers 和 DataChannels
SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
SdpOfferAnswerHandler::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.");
}
创建IceTransport
rtc::scoped_refptr<webrtc::IceTransportInterface> ice =
CreateIceTransport(content_info.name, /*rtcp=*/false);
RTC_DCHECK(ice);
创建DtlsTransport
std::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 。