前言

上一节的打断点
6-10 源码分析-SetLocalDescription之二 - 图1

  1. SdpOfferAnswerHandler::ApplyLocalDescription {
  2. SdpOfferAnswerHandler::PushdownTransportDescription
  3. SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
  4. SdpOfferAnswerHandler::UpdateSessionState
  5. }

6-10 源码分析-SetLocalDescription之二 - 图2

代码分析

都打上断点后,开始调试。

SdpOfferAnswerHandler::ApplyLocalDescription

  1. SdpOfferAnswerHandler::ApplyLocalDescription {
  2. // 创建各种Transport,里面根据是否是cricket::CS_LOCAL或CS_REMOTE来处理
  3. SdpOfferAnswerHandler::PushdownTransportDescription
  4. // 更新Transceivers 和 DataChannels
  5. SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
  6. SdpOfferAnswerHandler::UpdateSessionState
  7. }

SdpOfferAnswerHandler::PushdownTransportDescription

SdpOfferAnswerHandler::PushdownTransportDescription
->
JsepTransportController::SetLocalDescription
->
JsepTransportController::ApplyDescription_n
->
JsepTransportController::MaybeCreateJsepTransport
JsepTransport::SetLocalJsepTransportDescription

JsepTransportController::MaybeCreateJsepTransport

创建各种transport,并且打包在一起
image.png

  1. RTCError JsepTransportController::MaybeCreateJsepTransport(
  2. bool local,
  3. const cricket::ContentInfo& content_info,
  4. const cricket::SessionDescription& description) {
  5. cricket::JsepTransport* transport = GetJsepTransportByName(content_info.name);
  6. if (transport) {
  7. return RTCError::OK();
  8. }
  9. const cricket::MediaContentDescription* content_desc =
  10. content_info.media_description();
  11. if (certificate_ && !content_desc->cryptos().empty()) {
  12. return RTCError(RTCErrorType::INVALID_PARAMETER,
  13. "SDES and DTLS-SRTP cannot be enabled at the same time.");
  14. }
  15. 创建IceTransport
  16. rtc::scoped_refptr<webrtc::IceTransportInterface> ice =
  17. CreateIceTransport(content_info.name, /*rtcp=*/false);
  18. RTC_DCHECK(ice);
  19. 创建DtlsTransport
  20. std::unique_ptr<cricket::DtlsTransportInternal> rtp_dtls_transport =
  21. CreateDtlsTransport(content_info, ice->internal());
  22. std::unique_ptr<cricket::DtlsTransportInternal> rtcp_dtls_transport;
  23. std::unique_ptr<RtpTransport> unencrypted_rtp_transport;
  24. std::unique_ptr<SrtpTransport> sdes_transport;
  25. std::unique_ptr<DtlsSrtpTransport> dtls_srtp_transport;
  26. rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice;
  27. if (config_.rtcp_mux_policy !=
  28. PeerConnectionInterface::kRtcpMuxPolicyRequire &&
  29. content_info.type == cricket::MediaProtocolType::kRtp) {
  30. rtcp_ice = CreateIceTransport(content_info.name, /*rtcp=*/true);
  31. rtcp_dtls_transport =
  32. CreateDtlsTransport(content_info, rtcp_ice->internal());
  33. }
  34. if (config_.disable_encryption) {
  35. RTC_LOG(LS_INFO)
  36. << "Creating UnencryptedRtpTransport, becayse encryption is disabled.";
  37. unencrypted_rtp_transport = CreateUnencryptedRtpTransport(
  38. content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());
  39. } else if (!content_desc->cryptos().empty()) {
  40. sdes_transport = CreateSdesTransport(
  41. content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());
  42. RTC_LOG(LS_INFO) << "Creating SdesTransport.";
  43. } else {
  44. RTC_LOG(LS_INFO) << "Creating DtlsSrtpTransport.";
  45. dtls_srtp_transport = CreateDtlsSrtpTransport(
  46. content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());
  47. }
  48. std::unique_ptr<cricket::SctpTransportInternal> sctp_transport;
  49. if (config_.sctp_factory) {
  50. sctp_transport =
  51. config_.sctp_factory->CreateSctpTransport(rtp_dtls_transport.get());
  52. }
  53. // 将前面创建好的transport打包在一起
  54. std::unique_ptr<cricket::JsepTransport> jsep_transport =
  55. std::make_unique<cricket::JsepTransport>(
  56. content_info.name, certificate_, std::move(ice), std::move(rtcp_ice),
  57. std::move(unencrypted_rtp_transport), std::move(sdes_transport),
  58. std::move(dtls_srtp_transport), std::move(rtp_dtls_transport),
  59. std::move(rtcp_dtls_transport), std::move(sctp_transport));
  60. jsep_transport->rtp_transport()->SignalRtcpPacketReceived.connect(
  61. this, &JsepTransportController::OnRtcpPacketReceived_n);
  62. jsep_transport->SignalRtcpMuxActive.connect(
  63. this, &JsepTransportController::UpdateAggregateStates_n);
  64. SetTransportForMid(content_info.name, jsep_transport.get());
  65. jsep_transports_by_name_[content_info.name] = std::move(jsep_transport);
  66. UpdateAggregateStates_n();
  67. return RTCError::OK();
  68. }

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

  1. bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
  2. SdpType type,
  3. std::string* error_desc) {
  4. TRACE_EVENT0("webrtc", "BaseChannel::SetLocalContent");
  5. return InvokeOnWorker<bool>(RTC_FROM_HERE, [this, content, type, error_desc] {
  6. RTC_DCHECK_RUN_ON(worker_thread());
  7. return SetLocalContent_w(content, type, error_desc);
  8. });
  9. }

BaseChannel::SetLocalContent中使用了InvokeOnWorker,最后会根据SdpType类型,是调用
VideoChannel::SetLocalContent_w 还是 VoiceChannel::SetLocalContent_w 。