diff --git a/media/BUILD.gn b/media/BUILD.gn index cf0f3d3bd8..37d07c1404 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -156,6 +156,7 @@ rtc_library("media_channel_impl") { "../api:frame_transformer_interface", "../api:media_stream_interface", "../api:rtc_error", + "../api:rtp_headers", "../api:rtp_parameters", "../api:rtp_sender_interface", "../api:scoped_refptr", @@ -429,43 +430,66 @@ rtc_library("rtc_audio_video") { ":media_channel", ":media_channel_impl", ":media_constants", + ":rid_description", ":rtc_media_base", + ":rtc_media_config", ":rtp_utils", ":stream_params", "../api:array_view", + "../api:audio_options_api", "../api:call_api", "../api:field_trials_view", + "../api:frame_transformer_interface", "../api:libjingle_peerconnection_api", + "../api:make_ref_counted", "../api:media_stream_interface", + "../api:priority", + "../api:rtc_error", + "../api:rtp_headers", "../api:rtp_parameters", + "../api:rtp_transceiver_direction", "../api:scoped_refptr", "../api:sequence_checker", "../api:transport_api", + "../api/audio:audio_frame_api", "../api/audio:audio_frame_processor", "../api/audio:audio_mixer_api", "../api/audio_codecs:audio_codecs_api", + "../api/crypto:frame_decryptor_interface", + "../api/crypto:frame_encryptor_interface", + "../api/crypto:options", "../api/task_queue", "../api/task_queue:pending_task_safety_flag", "../api/transport:bitrate_settings", "../api/transport:field_trial_based_config", "../api/transport/rtp:rtp_source", "../api/units:data_rate", + "../api/units:time_delta", + "../api/units:timestamp", + "../api/video:recordable_encoded_frame", + "../api/video:resolution", "../api/video:video_bitrate_allocation", "../api/video:video_bitrate_allocator_factory", "../api/video:video_codec_constants", "../api/video:video_frame", "../api/video:video_rtp_headers", + "../api/video:video_stream_encoder", "../api/video_codecs:rtc_software_fallback_wrappers", + "../api/video_codecs:scalability_mode", "../api/video_codecs:video_codecs_api", "../call", "../call:call_interfaces", + "../call:receive_stream_interface", + "../call:rtp_interfaces", "../call:video_stream_api", "../common_video", + "../common_video:frame_counts", "../modules/async_audio_processing:async_audio_processing", "../modules/audio_device", "../modules/audio_device:audio_device_impl", "../modules/audio_mixer:audio_mixer_impl", "../modules/audio_processing:api", + "../modules/audio_processing:audio_processing_statistics", "../modules/audio_processing/aec_dump", "../modules/audio_processing/agc:gain_control_interface", "../modules/rtp_rtcp:rtp_rtcp_format", @@ -479,6 +503,7 @@ rtc_library("rtc_audio_video") { "../rtc_base:byte_order", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", + "../rtc_base:dscp", "../rtc_base:event_tracer", "../rtc_base:ignore_wundef", "../rtc_base:logging", @@ -487,6 +512,7 @@ rtc_library("rtc_audio_video") { "../rtc_base:race_checker", "../rtc_base:rtc_task_queue", "../rtc_base:safe_conversions", + "../rtc_base:socket", "../rtc_base:ssl", "../rtc_base:stringutils", "../rtc_base:threading", @@ -495,15 +521,21 @@ rtc_library("rtc_audio_video") { "../rtc_base/experiments:min_video_bitrate_experiment", "../rtc_base/experiments:normalize_simulcast_size_experiment", "../rtc_base/experiments:rate_control_settings", + "../rtc_base/network:sent_packet", "../rtc_base/synchronization:mutex", + "../rtc_base/system:file_wrapper", "../rtc_base/system:no_unique_address", "../rtc_base/system:rtc_export", "../rtc_base/third_party/base64", "../system_wrappers", "../system_wrappers:metrics", + "../video/config:encoder_config", ] absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm", "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/container:inlined_vector", + "//third_party/abseil-cpp/absl/functional:any_invocable", "//third_party/abseil-cpp/absl/functional:bind_front", "//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/types:optional", diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index 28233a8640..f8527da966 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -126,6 +126,10 @@ class RtpHelper : public Base { virtual absl::optional GetUnsignaledSsrc() const { return absl::nullopt; } + void ChooseReceiverReportSsrc(const std::set& choices) override {} + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override {} + virtual bool SetLocalSsrc(const StreamParams& sp) { return true; } virtual void OnDemuxerCriteriaUpdatePending() {} virtual void OnDemuxerCriteriaUpdateComplete() {} @@ -519,6 +523,9 @@ class FakeVideoMediaChannel : public RtpHelper { } void SetSendCodecChangedCallback( absl::AnyInvocable callback) override {} + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override {} + bool SendCodecHasLntf() const override { return false; } bool SendCodecHasNack() const override { return false; } absl::optional SendCodecRtxTime() const override { diff --git a/media/base/media_channel.h b/media/base/media_channel.h index 5d13e6bdd4..08e33cd01a 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -267,6 +268,9 @@ class MediaSendChannelInterface webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) { } virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0; + // Called whenever the list of sending SSRCs changes. + virtual void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) = 0; }; class MediaReceiveChannelInterface @@ -292,8 +296,7 @@ class MediaReceiveChannelInterface // Gets the current unsignaled receive stream's SSRC, if there is one. virtual absl::optional GetUnsignaledSsrc() const = 0; // Sets the local SSRC for listening to incoming RTCP reports. - virtual bool SetLocalSsrc(const StreamParams& sp) = 0; - + virtual void ChooseReceiverReportSsrc(const std::set& choices) = 0; // This is currently a workaround because of the demuxer state being managed // across two separate threads. Once the state is consistently managed on // the same thread (network), this workaround can be removed. diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h index 23b557c82e..1be6c6ef01 100644 --- a/media/base/media_channel_impl.h +++ b/media/base/media_channel_impl.h @@ -16,10 +16,12 @@ #include #include +#include #include #include #include +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/audio_options.h" @@ -30,6 +32,7 @@ #include "api/frame_transformer_interface.h" #include "api/media_types.h" #include "api/rtc_error.h" +#include "api/rtp_headers.h" #include "api/rtp_parameters.h" #include "api/rtp_sender_interface.h" #include "api/scoped_refptr.h" @@ -235,6 +238,10 @@ class VideoMediaChannel : public MediaChannel, } // Declared here in order to avoid "found by multiple paths" compile error bool AddSendStream(const StreamParams& sp) override = 0; + void ChooseReceiverReportSsrc(const std::set& choices) override = 0; + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override = + 0; // This fills the "bitrate parts" (rtx, video bitrate) of the // BandwidthEstimationInfo, since that part that isn't possible to get @@ -305,6 +312,11 @@ class VoiceMediaChannel : public MediaChannel, return nullptr; } + // Declared here to avoid "found in multiple base-class subobjects" error + void ChooseReceiverReportSsrc(const std::set& choices) override = 0; + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override = + 0; void SetExtmapAllowMixed(bool mixed) override { MediaChannel::SetExtmapAllowMixed(mixed); } @@ -410,6 +422,10 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface { webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override { return impl()->GetRtpSendParameters(ssrc); } + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override { + impl()->SetSsrcListChangedCallback(std::move(callback)); + } // Implementation of VoiceMediaSendChannel bool SetSendParameters(const AudioSendParameters& params) override { return impl()->SetSendParameters(params); @@ -493,8 +509,8 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { void ResetUnsignaledRecvStream() override { return impl()->ResetUnsignaledRecvStream(); } - bool SetLocalSsrc(const StreamParams& sp) override { - return impl()->SetLocalSsrc(sp); + void ChooseReceiverReportSsrc(const std::set& choices) override { + return impl()->ChooseReceiverReportSsrc(choices); } absl::optional GetUnsignaledSsrc() const override { return impl()->GetUnsignaledSsrc(); @@ -665,6 +681,10 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { absl::optional SendCodecRtxTime() const override { return impl()->SendCodecRtxTime(); } + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override { + impl()->SetSsrcListChangedCallback(std::move(callback)); + } MediaChannel* ImplForTesting() override { return impl_; } @@ -730,8 +750,8 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { absl::optional GetUnsignaledSsrc() const override { return impl()->GetUnsignaledSsrc(); } - bool SetLocalSsrc(const StreamParams& sp) override { - return impl()->SetLocalSsrc(sp); + void ChooseReceiverReportSsrc(const std::set& choices) override { + return impl()->ChooseReceiverReportSsrc(choices); } void OnDemuxerCriteriaUpdatePending() override { impl()->OnDemuxerCriteriaUpdatePending(); diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index ee868de49c..095d151a83 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -14,33 +14,52 @@ #include #include +#include #include #include +#include #include #include "absl/algorithm/container.h" +#include "absl/container/inlined_vector.h" #include "absl/functional/bind_front.h" #include "absl/strings/match.h" #include "absl/types/optional.h" +#include "api/make_ref_counted.h" #include "api/media_stream_interface.h" -#include "api/video/video_codec_constants.h" +#include "api/media_types.h" +#include "api/priority.h" +#include "api/rtp_transceiver_direction.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" +#include "api/video/resolution.h" #include "api/video/video_codec_type.h" +#include "api/video_codecs/scalability_mode.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" #include "call/call.h" +#include "call/packet_receiver.h" +#include "call/receive_stream.h" +#include "call/rtp_transport_controller_send_interface.h" +#include "common_video/frame_counts.h" +#include "common_video/include/quality_limitation_reason.h" +#include "media/base/media_constants.h" +#include "media/base/rid_description.h" +#include "media/base/rtp_utils.h" #include "media/engine/webrtc_media_engine.h" -#include "media/engine/webrtc_voice_engine.h" +#include "modules/rtp_rtcp/include/report_block_data.h" +#include "modules/rtp_rtcp/include/rtcp_statistics.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_util.h" -#include "modules/video_coding/codecs/vp9/svc_config.h" #include "modules/video_coding/svc/scalability_mode_util.h" -#include "rtc_base/copy_on_write_buffer.h" +#include "rtc_base/checks.h" +#include "rtc_base/dscp.h" #include "rtc_base/experiments/field_trial_parser.h" -#include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/logging.h" -#include "rtc_base/numerics/safe_conversions.h" +#include "rtc_base/socket.h" #include "rtc_base/strings/string_builder.h" #include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" @@ -1284,6 +1303,22 @@ void WebRtcVideoChannel::SetReceiverReportSsrc(uint32_t ssrc) { receive_stream->SetLocalSsrc(ssrc); } +void WebRtcVideoChannel::ChooseReceiverReportSsrc( + const std::set& choices) { + RTC_DCHECK_RUN_ON(&thread_checker_); + // If we can continue using the current receiver report, do so. + if (choices.find(rtcp_receiver_report_ssrc_) != choices.end()) { + return; + } + // Go back to the default if list has been emptied. + if (choices.empty()) { + SetReceiverReportSsrc(kDefaultRtcpReceiverReportSsrc); + return; + } + // Any number is as good as any other. + SetReceiverReportSsrc(*choices.begin()); +} + bool WebRtcVideoChannel::GetSendCodec(VideoCodec* codec) { RTC_DCHECK_RUN_ON(&thread_checker_); if (!send_codec()) { @@ -1417,8 +1452,10 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) { // If legacy kBoth mode, tell my receiver part about its SSRC. // In kSend mode, this is the responsibility of the caller. if (role() == MediaChannel::Role::kBoth) { - if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { - SetReceiverReportSsrc(ssrc); + ChooseReceiverReportSsrc(send_ssrcs_); + } else { + if (ssrc_list_changed_callback_) { + ssrc_list_changed_callback_(send_ssrcs_); } } @@ -1446,9 +1483,12 @@ bool WebRtcVideoChannel::RemoveSendStream(uint32_t ssrc) { send_streams_.erase(it); // Switch receiver report SSRCs, the one in use is no longer valid. - if (rtcp_receiver_report_ssrc_ == ssrc) { - SetReceiverReportSsrc(send_streams_.empty() ? kDefaultRtcpReceiverReportSsrc - : send_streams_.begin()->first); + if (role() == MediaChannel::Role::kBoth) { + ChooseReceiverReportSsrc(send_ssrcs_); + } else { + if (ssrc_list_changed_callback_) { + ssrc_list_changed_callback_(send_ssrcs_); + } } delete removed_stream; @@ -1617,15 +1657,6 @@ void WebRtcVideoChannel::ResetUnsignaledRecvStream() { } } -bool WebRtcVideoChannel::SetLocalSsrc(const StreamParams& sp) { - RTC_DCHECK_RUN_ON(&thread_checker_); - RTC_DCHECK(role() == MediaChannel::Role::kReceive); - if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { - SetReceiverReportSsrc(sp.first_ssrc()); - } - return true; -} - absl::optional WebRtcVideoChannel::GetUnsignaledSsrc() const { RTC_DCHECK_RUN_ON(&thread_checker_); absl::optional ssrc; diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index d3c088c6d0..6e62945d7c 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -11,7 +11,10 @@ #ifndef MEDIA_ENGINE_WEBRTC_VIDEO_ENGINE_H_ #define MEDIA_ENGINE_WEBRTC_VIDEO_ENGINE_H_ +#include + #include +#include #include #include #include @@ -19,26 +22,54 @@ #include #include +#include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "api/array_view.h" #include "api/call/transport.h" +#include "api/crypto/crypto_options.h" +#include "api/crypto/frame_decryptor_interface.h" +#include "api/crypto/frame_encryptor_interface.h" +#include "api/field_trials_view.h" +#include "api/frame_transformer_interface.h" +#include "api/rtc_error.h" +#include "api/rtp_headers.h" +#include "api/rtp_parameters.h" +#include "api/rtp_sender_interface.h" +#include "api/scoped_refptr.h" #include "api/sequence_checker.h" #include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" +#include "api/transport/bitrate_settings.h" #include "api/transport/field_trial_based_config.h" +#include "api/transport/rtp/rtp_source.h" +#include "api/video/recordable_encoded_frame.h" #include "api/video/video_bitrate_allocator_factory.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" +#include "api/video/video_stream_encoder_settings.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder_factory.h" #include "call/call.h" #include "call/flexfec_receive_stream.h" +#include "call/rtp_config.h" #include "call/video_receive_stream.h" #include "call/video_send_stream.h" +#include "media/base/codec.h" +#include "media/base/media_channel.h" #include "media/base/media_channel_impl.h" +#include "media/base/media_config.h" #include "media/base/media_engine.h" +#include "media/base/stream_params.h" +#include "modules/rtp_rtcp/include/rtp_header_extension_map.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "rtc_base/network/sent_packet.h" #include "rtc_base/network_route.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/system/no_unique_address.h" #include "rtc_base/thread_annotations.h" +#include "video/config/video_encoder_config.h" namespace webrtc { class VideoDecoderFactory; @@ -141,7 +172,6 @@ class WebRtcVideoChannel : public VideoMediaChannel, bool RemoveRecvStream(uint32_t ssrc) override; void ResetUnsignaledRecvStream() override; absl::optional GetUnsignaledSsrc() const override; - bool SetLocalSsrc(const StreamParams& sp) override; void OnDemuxerCriteriaUpdatePending() override; void OnDemuxerCriteriaUpdateComplete() override; bool SetSink(uint32_t ssrc, @@ -191,6 +221,15 @@ class WebRtcVideoChannel : public VideoMediaChannel, send_codec_changed_callback_ = std::move(callback); } + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override { + ssrc_list_changed_callback_ = std::move(callback); + } + + // Choose one of the available SSRCs (or default if none) as the current + // receiver report SSRC. + void ChooseReceiverReportSsrc(const std::set& choices) override; + // Implemented for VideoMediaChannelTest. bool sending() const { RTC_DCHECK_RUN_ON(&thread_checker_); @@ -733,6 +772,9 @@ class WebRtcVideoChannel : public VideoMediaChannel, // Callback invoked whenever the send codec changes. // TODO(bugs.webrtc.org/13931): Remove again when coupling isn't needed. absl::AnyInvocable send_codec_changed_callback_; + // Callback invoked whenever the list of SSRCs changes. + absl::AnyInvocable&)> + ssrc_list_changed_callback_; }; } // namespace cricket diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 55cebbaa54..81c517ab31 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -12,20 +12,40 @@ #include #include +#include #include +#include +#include #include #include +#include #include #include +#include "absl/algorithm/algorithm.h" #include "absl/algorithm/container.h" #include "absl/functional/bind_front.h" #include "absl/strings/match.h" +#include "api/audio/audio_frame.h" #include "api/audio/audio_frame_processor.h" #include "api/audio_codecs/audio_codec_pair_id.h" +#include "api/audio_codecs/audio_encoder.h" #include "api/call/audio_sink.h" #include "api/field_trials_view.h" +#include "api/make_ref_counted.h" +#include "api/media_types.h" +#include "api/priority.h" +#include "api/rtp_headers.h" +#include "api/rtp_transceiver_direction.h" #include "api/task_queue/pending_task_safety_flag.h" +#include "api/transport/bitrate_settings.h" +#include "api/units/data_rate.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" +#include "call/audio_receive_stream.h" +#include "call/packet_receiver.h" +#include "call/rtp_config.h" +#include "call/rtp_transport_controller_send_interface.h" #include "media/base/audio_source.h" #include "media/base/media_constants.h" #include "media/base/stream_params.h" @@ -33,26 +53,25 @@ #include "media/engine/payload_type_mapper.h" #include "media/engine/webrtc_media_engine.h" #include "modules/async_audio_processing/async_audio_processing.h" -#include "modules/audio_device/audio_device_impl.h" #include "modules/audio_mixer/audio_mixer_impl.h" -#include "modules/audio_processing/aec_dump/aec_dump_factory.h" #include "modules/audio_processing/include/audio_processing.h" +#include "modules/audio_processing/include/audio_processing_statistics.h" +#include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_util.h" -#include "rtc_base/arraysize.h" -#include "rtc_base/byte_order.h" -#include "rtc_base/experiments/field_trial_parser.h" -#include "rtc_base/experiments/field_trial_units.h" +#include "rtc_base/checks.h" +#include "rtc_base/dscp.h" #include "rtc_base/experiments/struct_parameters_parser.h" -#include "rtc_base/helpers.h" #include "rtc_base/ignore_wundef.h" #include "rtc_base/logging.h" #include "rtc_base/race_checker.h" +#include "rtc_base/string_encode.h" #include "rtc_base/strings/audio_format_to_string.h" #include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_format.h" -#include "rtc_base/third_party/base64/base64.h" +#include "rtc_base/thread_annotations.h" +#include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/metrics.h" @@ -1992,14 +2011,26 @@ absl::optional WebRtcVoiceMediaChannel::GetUnsignaledSsrc() const { return unsignaled_recv_ssrcs_.back(); } -bool WebRtcVoiceMediaChannel::SetLocalSsrc(const StreamParams& sp) { - RTC_DCHECK(role() == MediaChannel::Role::kReceive); - uint32_t ssrc = sp.first_ssrc(); +void WebRtcVoiceMediaChannel::SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) { + ssrc_list_changed_callback_ = std::move(callback); +} + +void WebRtcVoiceMediaChannel::ChooseReceiverReportSsrc( + const std::set& choices) { + // Don't change SSRC if set is empty. Note that this differs from + // the behavior of video. + if (choices.empty()) { + return; + } + if (choices.find(receiver_reports_ssrc_) != choices.end()) { + return; + } + uint32_t ssrc = *(choices.begin()); receiver_reports_ssrc_ = ssrc; for (auto& kv : recv_streams_) { call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc); } - return true; } // Not implemented. diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index f5d8080723..48fb95a3e7 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -11,27 +11,60 @@ #ifndef MEDIA_ENGINE_WEBRTC_VOICE_ENGINE_H_ #define MEDIA_ENGINE_WEBRTC_VOICE_ENGINE_H_ +#include +#include + #include #include +#include #include #include +#include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "api/audio/audio_frame_processor.h" +#include "api/audio/audio_mixer.h" #include "api/audio_codecs/audio_codec_pair_id.h" +#include "api/audio_codecs/audio_decoder_factory.h" #include "api/audio_codecs/audio_encoder_factory.h" +#include "api/audio_codecs/audio_format.h" +#include "api/audio_options.h" +#include "api/call/audio_sink.h" +#include "api/call/transport.h" +#include "api/crypto/crypto_options.h" +#include "api/crypto/frame_decryptor_interface.h" +#include "api/crypto/frame_encryptor_interface.h" #include "api/field_trials_view.h" +#include "api/frame_transformer_interface.h" +#include "api/rtc_error.h" +#include "api/rtp_parameters.h" +#include "api/rtp_sender_interface.h" #include "api/scoped_refptr.h" #include "api/sequence_checker.h" #include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_factory.h" #include "api/transport/rtp/rtp_source.h" +#include "call/audio_send_stream.h" #include "call/audio_state.h" #include "call/call.h" +#include "media/base/codec.h" +#include "media/base/media_channel.h" #include "media/base/media_channel_impl.h" +#include "media/base/media_config.h" #include "media/base/media_engine.h" #include "media/base/rtp_utils.h" +#include "media/base/stream_params.h" #include "modules/async_audio_processing/async_audio_processing.h" +#include "modules/audio_device/include/audio_device.h" +#include "modules/audio_processing/include/audio_processing.h" +#include "modules/rtp_rtcp/include/rtp_header_extension_map.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "rtc_base/buffer.h" +#include "rtc_base/network/sent_packet.h" #include "rtc_base/network_route.h" +#include "rtc_base/system/file_wrapper.h" #include "rtc_base/task_queue.h" namespace webrtc { @@ -183,7 +216,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, void ResetUnsignaledRecvStream() override; absl::optional GetUnsignaledSsrc() const override; - bool SetLocalSsrc(const StreamParams& sp) override; + void ChooseReceiverReportSsrc(const std::set& choices) override; + void SetSsrcListChangedCallback( + absl::AnyInvocable&)> callback) override; void OnDemuxerCriteriaUpdatePending() override; void OnDemuxerCriteriaUpdateComplete() override; @@ -334,11 +369,13 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, uint32_t receiver_reports_ssrc_ = 0xFA17FA17u; class WebRtcAudioSendStream; + std::map send_streams_; std::vector send_rtp_extensions_; std::string mid_; class WebRtcAudioReceiveStream; + std::map recv_streams_; std::vector recv_rtp_extensions_; webrtc::RtpHeaderExtensionMap recv_rtp_extension_map_; @@ -360,6 +397,10 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, void FillSendCodecStats(VoiceMediaSendInfo* voice_media_info); void FillReceiveCodecStats(VoiceMediaReceiveInfo* voice_media_info); + + // Callback invoked whenever the list of SSRCs changes. + absl::AnyInvocable&)> + ssrc_list_changed_callback_; }; } // namespace cricket diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 48c8879145..a89e8a6908 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -1593,6 +1593,7 @@ rtc_library("rtp_transceiver") { ":session_description", "../api:array_view", "../api:audio_options_api", + "../api:field_trials_view", "../api:libjingle_peerconnection_api", "../api:rtc_error", "../api:rtp_parameters", @@ -1600,13 +1601,17 @@ rtc_library("rtp_transceiver") { "../api:rtp_transceiver_direction", "../api:scoped_refptr", "../api:sequence_checker", + "../api/audio_codecs:audio_codecs_api", + "../api/crypto:options", "../api/task_queue", "../api/task_queue:pending_task_safety_flag", "../api/video:video_bitrate_allocator_factory", "../media:codec", "../media:media_channel", + "../media:media_channel_impl", "../media:media_constants", "../media:rtc_media_base", + "../media:rtc_media_config", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:macromagic", diff --git a/pc/channel.cc b/pc/channel.cc index 58e3060b3e..d5c02f81b6 100644 --- a/pc/channel.cc +++ b/pc/channel.cc @@ -712,18 +712,6 @@ bool BaseChannel::UpdateLocalStreams_w(const std::vector& streams, if (media_send_channel()->AddSendStream(new_stream)) { RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0] << " into " << ToString(); - // Must also tell the corresponding receive stream to listen for - // RRs coming in on the new stream's SSRC - if (media_send_channel_impl_) { - if (all_streams.size() == 1) { - if (!media_receive_channel()->SetLocalSsrc(new_stream)) { - error_desc = StringFormat( - "Failed to set local ssrc: %u into m-section with mid='%s'", - new_stream.first_ssrc(), mid().c_str()); - ret = false; - } - } - } } else { error_desc = StringFormat( "Failed to add send stream ssrc: %u into m-section with mid='%s'", diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index 30a16256a5..594f2d1d53 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -10,18 +10,22 @@ #include "pc/rtp_transceiver.h" -#include +#include + #include +#include #include #include #include #include "absl/algorithm/container.h" #include "absl/memory/memory.h" -#include "api/peer_connection_interface.h" +#include "api/audio_codecs/audio_codec_pair_id.h" +#include "api/field_trials_view.h" #include "api/rtp_parameters.h" #include "api/sequence_checker.h" #include "media/base/codec.h" +#include "media/base/media_channel_impl.h" #include "media/base/media_constants.h" #include "media/base/media_engine.h" #include "pc/channel.h" @@ -230,6 +234,13 @@ RTCError RtpTransceiver::CreateChannel( if (!media_receive_channel) { return; } + // Note that this is safe because both sending and + // receiving channels will be deleted at the same time. + media_send_channel->SetSsrcListChangedCallback( + [receive_channel = media_receive_channel.get()]( + const std::set& choices) { + receive_channel->ChooseReceiverReportSsrc(choices); + }); new_channel = std::make_unique( context()->worker_thread(), context()->network_thread(), @@ -278,6 +289,13 @@ RTCError RtpTransceiver::CreateChannel( if (!media_receive_channel) { return; } + // Note that this is safe because both sending and + // receiving channels will be deleted at the same time. + media_send_channel->SetSsrcListChangedCallback( + [receive_channel = media_receive_channel.get()]( + const std::set& choices) { + receive_channel->ChooseReceiverReportSsrc(choices); + }); new_channel = std::make_unique( context()->worker_thread(), context()->network_thread(), diff --git a/pc/rtp_transceiver.h b/pc/rtp_transceiver.h index 4a9442e483..deda5d7d61 100644 --- a/pc/rtp_transceiver.h +++ b/pc/rtp_transceiver.h @@ -18,9 +18,11 @@ #include #include +#include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" #include "api/audio_options.h" +#include "api/crypto/crypto_options.h" #include "api/jsep.h" #include "api/media_types.h" #include "api/rtc_error.h" @@ -34,6 +36,8 @@ #include "api/task_queue/task_queue_base.h" #include "api/video/video_bitrate_allocator_factory.h" #include "media/base/media_channel.h" +#include "media/base/media_config.h" +#include "media/base/media_engine.h" #include "pc/channel_interface.h" #include "pc/connection_context.h" #include "pc/proxy.h" diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h index feab3c03f4..8748532205 100644 --- a/pc/test/mock_voice_media_channel.h +++ b/pc/test/mock_voice_media_channel.h @@ -11,6 +11,7 @@ #define PC_TEST_MOCK_VOICE_MEDIA_CHANNEL_H_ #include +#include #include #include @@ -62,7 +63,14 @@ class MockVoiceMediaChannel : public VoiceMediaChannel { GetUnsignaledSsrc, (), (const, override)); - MOCK_METHOD(bool, SetLocalSsrc, (const StreamParams& sp), (override)); + MOCK_METHOD(void, + ChooseReceiverReportSsrc, + (const std::set&), + (override)); + MOCK_METHOD(void, + SetSsrcListChangedCallback, + (absl::AnyInvocable&)>), + (override)); MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override)); MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override)); MOCK_METHOD(int, GetRtpSendTimeExtnId, (), (const, override));