调用堆栈

image.png

VideoChannel::SetLocalContent_w

image.png

  1. bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
  2. SdpType type,
  3. std::string* error_desc) {
  4. TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w");
  5. RTC_DCHECK_RUN_ON(worker_thread());
  6. RTC_LOG(LS_INFO) << "Setting local video description for " << ToString();
  7. RTC_DCHECK(content);
  8. if (!content) {
  9. SafeSetError("Can't find video content in local description.", error_desc);
  10. return false;
  11. }
  12. const VideoContentDescription* video = content->as_video();
  13. if (type == SdpType::kAnswer)
  14. SetNegotiatedHeaderExtensions_w(video->rtp_header_extensions());
  15. RtpHeaderExtensions rtp_header_extensions =
  16. GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
  17. UpdateRtpHeaderExtensionMap(rtp_header_extensions);
  18. media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
  19. VideoRecvParameters recv_params = last_recv_params_;
  20. RtpParametersFromMediaDescription(
  21. video, rtp_header_extensions,
  22. webrtc::RtpTransceiverDirectionHasRecv(video->direction()), &recv_params);
  23. VideoSendParameters send_params = last_send_params_;
  24. bool needs_send_params_update = false;
  25. if (type == SdpType::kAnswer || type == SdpType::kPrAnswer) {
  26. for (auto& send_codec : send_params.codecs) {
  27. auto* recv_codec = FindMatchingCodec(recv_params.codecs, send_codec);
  28. if (recv_codec) {
  29. if (!recv_codec->packetization && send_codec.packetization) {
  30. send_codec.packetization.reset();
  31. needs_send_params_update = true;
  32. } else if (recv_codec->packetization != send_codec.packetization) {
  33. SafeSetError(
  34. "Failed to set local answer due to invalid codec packetization "
  35. "specified in m-section with mid='" +
  36. content_name() + "'.",
  37. error_desc);
  38. return false;
  39. }
  40. }
  41. }
  42. }
  43. if (!media_channel()->SetRecvParameters(recv_params)) {
  44. SafeSetError(
  45. "Failed to set local video description recv parameters for m-section "
  46. "with mid='" +
  47. content_name() + "'.",
  48. error_desc);
  49. return false;
  50. }
  51. if (webrtc::RtpTransceiverDirectionHasRecv(video->direction())) {
  52. for (const VideoCodec& codec : video->codecs()) {
  53. MaybeAddHandledPayloadType(codec.id);
  54. }
  55. // Need to re-register the sink to update the handled payload.
  56. if (!RegisterRtpDemuxerSink_w()) {
  57. RTC_LOG(LS_ERROR) << "Failed to set up video demuxing for " << ToString();
  58. return false;
  59. }
  60. }
  61. last_recv_params_ = recv_params;
  62. if (needs_send_params_update) {
  63. if (!media_channel()->SetSendParameters(send_params)) {
  64. SafeSetError("Failed to set send parameters for m-section with mid='" +
  65. content_name() + "'.",
  66. error_desc);
  67. return false;
  68. }
  69. last_send_params_ = send_params;
  70. }
  71. // TODO(pthatcher): Move local streams into VideoSendParameters, and
  72. // only give it to the media channel once we have a remote
  73. // description too (without a remote description, we won't be able
  74. // to send them anyway).
  75. if (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {
  76. SafeSetError(
  77. "Failed to set local video description streams for m-section with "
  78. "mid='" +
  79. content_name() + "'.",
  80. error_desc);
  81. return false;
  82. }
  83. set_local_content_direction(content->direction());
  84. UpdateMediaSendRecvState_w();
  85. return true;
  86. }

BaseChannel::UpdateLocalStream_w

image.png

  1. bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
  2. SdpType type,
  3. std::string* error_desc) {
  4. // In the case of RIDs (where SSRCs are not negotiated), this method will
  5. // generate an SSRC for each layer in StreamParams. That representation will
  6. // be stored internally in |local_streams_|.
  7. // In subsequent offers, the same stream can appear in |streams| again
  8. // (without the SSRCs), so it should be looked up using RIDs (if available)
  9. // and then by primary SSRC.
  10. // In both scenarios, it is safe to assume that the media channel will be
  11. // created with a StreamParams object with SSRCs. However, it is not safe to
  12. // assume that |local_streams_| will always have SSRCs as there are scenarios
  13. // in which niether SSRCs or RIDs are negotiated.
  14. // Check for streams that have been removed.
  15. bool ret = true;
  16. for (const StreamParams& old_stream : local_streams_) {
  17. if (!old_stream.has_ssrcs() ||
  18. GetStream(streams, StreamFinder(&old_stream))) {
  19. continue;
  20. }
  21. if (!media_channel()->RemoveSendStream(old_stream.first_ssrc())) {
  22. rtc::StringBuilder desc;
  23. desc << "Failed to remove send stream with ssrc "
  24. << old_stream.first_ssrc() << " from m-section with mid='"
  25. << content_name() << "'.";
  26. SafeSetError(desc.str(), error_desc);
  27. ret = false;
  28. }
  29. }
  30. // Check for new streams.
  31. std::vector<StreamParams> all_streams;
  32. for (const StreamParams& stream : streams) {
  33. StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));
  34. if (existing) {
  35. // Parameters cannot change for an existing stream.
  36. all_streams.push_back(*existing);
  37. continue;
  38. }
  39. all_streams.push_back(stream);
  40. StreamParams& new_stream = all_streams.back();
  41. if (!new_stream.has_ssrcs() && !new_stream.has_rids()) {
  42. continue;
  43. }
  44. RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());
  45. if (new_stream.has_ssrcs() && new_stream.has_rids()) {
  46. rtc::StringBuilder desc;
  47. desc << "Failed to add send stream: " << new_stream.first_ssrc()
  48. << " into m-section with mid='" << content_name()
  49. << "'. Stream has both SSRCs and RIDs.";
  50. SafeSetError(desc.str(), error_desc);
  51. ret = false;
  52. continue;
  53. }
  54. // At this point we use the legacy simulcast group in StreamParams to
  55. // indicate that we want multiple layers to the media channel.
  56. if (!new_stream.has_ssrcs()) {
  57. // TODO(bugs.webrtc.org/10250): Indicate if flex is desired here.
  58. new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,
  59. /* flex_fec = */ false, ssrc_generator_);
  60. }
  61. if (media_channel()->AddSendStream(new_stream)) {
  62. RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0]
  63. << " into " << ToString();
  64. } else {
  65. rtc::StringBuilder desc;
  66. desc << "Failed to add send stream ssrc: " << new_stream.first_ssrc()
  67. << " into m-section with mid='" << content_name() << "'";
  68. SafeSetError(desc.str(), error_desc);
  69. ret = false;
  70. }
  71. }
  72. local_streams_ = all_streams;
  73. return ret;
  74. }

WebRtcVideoChannel::AddSendStream

image.png

  1. bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) {
  2. RTC_DCHECK_RUN_ON(&thread_checker_);
  3. RTC_LOG(LS_INFO) << "AddSendStream: " << sp.ToString();
  4. if (!ValidateStreamParams(sp))
  5. return false;
  6. if (!ValidateSendSsrcAvailability(sp))
  7. return false;
  8. for (uint32_t used_ssrc : sp.ssrcs)
  9. send_ssrcs_.insert(used_ssrc);
  10. webrtc::VideoSendStream::Config config(this);
  11. for (const RidDescription& rid : sp.rids()) {
  12. config.rtp.rids.push_back(rid.rid);
  13. }
  14. config.suspend_below_min_bitrate = video_config_.suspend_below_min_bitrate;
  15. config.periodic_alr_bandwidth_probing =
  16. video_config_.periodic_alr_bandwidth_probing;
  17. config.encoder_settings.experiment_cpu_load_estimator =
  18. video_config_.experiment_cpu_load_estimator;
  19. config.encoder_settings.encoder_factory = encoder_factory_;
  20. config.encoder_settings.bitrate_allocator_factory =
  21. bitrate_allocator_factory_;
  22. config.encoder_settings.encoder_switch_request_callback = this;
  23. config.crypto_options = crypto_options_;
  24. config.rtp.extmap_allow_mixed = ExtmapAllowMixed();
  25. config.rtcp_report_interval_ms = video_config_.rtcp_report_interval_ms;
  26. WebRtcVideoSendStream* stream = new WebRtcVideoSendStream(
  27. call_, sp, std::move(config), default_send_options_,
  28. video_config_.enable_cpu_adaptation, bitrate_config_.max_bitrate_bps,
  29. send_codec_, send_rtp_extensions_, send_params_);
  30. uint32_t ssrc = sp.first_ssrc();
  31. RTC_DCHECK(ssrc != 0);
  32. send_streams_[ssrc] = stream;
  33. if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) {
  34. rtcp_receiver_report_ssrc_ = ssrc;
  35. RTC_LOG(LS_INFO)
  36. << "SetLocalSsrc on all the receive streams because we added "
  37. "a send stream.";
  38. for (auto& kv : receive_streams_)
  39. kv.second->SetLocalSsrc(ssrc);
  40. }
  41. if (sending_) {
  42. stream->SetSend(true);
  43. }
  44. return true;
  45. }