前言

呼叫方调用SetLocalDescription ,被呼叫方调用 SetRemoteDescription 。
image.png
第一个都是处理音频。
注意是因为现在音频媒体协商确定后,才会调用AudioCodingModule::SetEncoder。之前只是收集编码器。
image.png
注意,最后是构建AudioEncoderOpusImpl,然后传到左边创建的AudioCodingModuleImpl,再调用AudioCodingModuleImpl::RegisterTransportCallback注册回调对象,这时候注册的回调对象就可以交给其他对象去处理了。
image.png

SdpOfferAnswerHandler::DoSetRemoteDescription

  1. SdpOfferAnswerHandler::DoSetRemoteDescription
  2. {
  3. SdpOfferAnswerHandler::FillInMissingRemoteMids
  4. SdpOfferAnswerHandler::ApplyRemoteDescription
  5. OnSetRemoteDescriptionComplete
  6. SdpOfferAnswerHandler::UpdateNegotiationNeeded
  7. }

SdpOfferAnswerHandler::ApplyRemoteDescription

  1. SdpOfferAnswerHandler::ApplyRemoteDescription
  2. {
  3. SdpOfferAnswerHandler::PushdownTransportDescription
  4. SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels
  5. SdpOfferAnswerHandler::UpdateSessionState
  6. CheckForRemoteIceRestart
  7. UpdateRemoteSendersList
  8. }

image.png

SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels

  1. SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels{
  2. SdpOfferAnswerHandler::AssociateTransceiver
  3. SdpOfferAnswerHandler::UpdateTransceiverChannel
  4. }
  5. SdpOfferAnswerHandler::UpdateTransceiverChannel
  6. {
  7. ***
  8. if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
  9. channel = CreateVoiceChannel(content.name);
  10. } else {
  11. RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, transceiver->media_type());
  12. channel = CreateVideoChannel(content.name);
  13. }
  14. ***
  15. }

JsepTransportController::SetRemoteDescription

  1. RTCError JsepTransportController::SetRemoteDescription(
  2. SdpType type,
  3. const cricket::SessionDescription* description) {
  4. if (!network_thread_->IsCurrent()) {
  5. return network_thread_->Invoke<RTCError>(
  6. RTC_FROM_HERE, [=] { return SetRemoteDescription(type, description); });
  7. }
  8. RTC_DCHECK_RUN_ON(network_thread_);
  9. return ApplyDescription_n(/*local=*/false, type, description);
  10. }

image.png

SdpOfferAnswerHandler::PushdownMediaDescription

image.png

  1. SdpOfferAnswerHandler::PushdownMediaDescription
  2. {
  3. ***
  4. // Push down the new SDP media section for each audio/video transceiver.
  5. for (const auto& transceiver : transceivers()->List()) {
  6. const ContentInfo* content_info =
  7. FindMediaSectionForTransceiver(transceiver, sdesc);
  8. cricket::ChannelInterface* channel = transceiver->internal()->channel();
  9. if (!channel || !content_info || content_info->rejected) {
  10. continue;
  11. }
  12. const MediaContentDescription* content_desc =
  13. content_info->media_description();
  14. if (!content_desc) {
  15. continue;
  16. }
  17. std::string error;
  18. bool success = (source == cricket::CS_LOCAL)
  19. ? channel->SetLocalContent(content_desc, type, &error)
  20. : channel->SetRemoteContent(content_desc, type, &error);
  21. if (!success) {
  22. LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, error);
  23. }
  24. }
  25. }
  26. ****
  27. -》
  28. bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
  29. SdpType type,
  30. std::string* error_desc) {
  31. TRACE_EVENT0("webrtc", "BaseChannel::SetRemoteContent");
  32. return InvokeOnWorker<bool>(RTC_FROM_HERE, [this, content, type, error_desc] {
  33. RTC_DCHECK_RUN_ON(worker_thread());
  34. return SetRemoteContent_w(content, type, error_desc);
  35. });
  36. }
  37. -》
  38. H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\pc\channel.cc
  39. VoiceChannel::SetRemoteContent_w

image.png
因为 channel->SetRemoteContent(content_desc, type, &error);,此时是音频,所以是VoiceChannel ,因为VoiceChannel 继承BaseChannel,所以会先调用父类的SetRemoteContent,然后再在工作线程中调用VoiceChannel::SetRemoteContent_w,举一反三视频的也一样。