diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc index d4d24cda85..f31cfaac67 100644 --- a/media/base/fake_media_engine.cc +++ b/media/base/fake_media_engine.cc @@ -50,10 +50,11 @@ AudioSource* FakeVoiceMediaChannel::VoiceChannelAudioSink::source() const { return source_; } -FakeVoiceMediaChannel::FakeVoiceMediaChannel(FakeVoiceEngine* engine, +FakeVoiceMediaChannel::FakeVoiceMediaChannel(MediaChannel::Role role, + FakeVoiceEngine* engine, const AudioOptions& options, TaskQueueBase* network_thread) - : RtpHelper(network_thread), + : RtpHelper(role, network_thread), engine_(engine), max_bps_(-1) { output_scalings_[0] = 1.0; // For default channel. @@ -260,10 +261,11 @@ bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info, info.ssrc == ssrc); } -FakeVideoMediaChannel::FakeVideoMediaChannel(FakeVideoEngine* engine, +FakeVideoMediaChannel::FakeVideoMediaChannel(MediaChannel::Role role, + FakeVideoEngine* engine, const VideoOptions& options, TaskQueueBase* network_thread) - : RtpHelper(network_thread), + : RtpHelper(role, network_thread), engine_(engine), max_bps_(-1) { SetOptions(options); @@ -449,6 +451,7 @@ rtc::scoped_refptr FakeVoiceEngine::GetAudioState() const { return rtc::scoped_refptr(); } VoiceMediaChannel* FakeVoiceEngine::CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const AudioOptions& options, @@ -458,7 +461,7 @@ VoiceMediaChannel* FakeVoiceEngine::CreateMediaChannel( } FakeVoiceMediaChannel* ch = - new FakeVoiceMediaChannel(this, options, call->network_thread()); + new FakeVoiceMediaChannel(role, this, options, call->network_thread()); channels_.push_back(ch); return ch; } @@ -519,6 +522,7 @@ bool FakeVideoEngine::SetOptions(const VideoOptions& options) { return true; } VideoMediaChannel* FakeVideoEngine::CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, @@ -529,7 +533,7 @@ VideoMediaChannel* FakeVideoEngine::CreateMediaChannel( } FakeVideoMediaChannel* ch = - new FakeVideoMediaChannel(this, options, call->network_thread()); + new FakeVideoMediaChannel(role, this, options, call->network_thread()); channels_.emplace_back(ch); return ch; } diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index 082c7f37f9..7ec381844e 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -45,8 +45,9 @@ class FakeVoiceEngine; template class RtpHelper : public Base { public: - explicit RtpHelper(webrtc::TaskQueueBase* network_thread) - : Base(network_thread), + explicit RtpHelper(MediaChannel::Role role, + webrtc::TaskQueueBase* network_thread) + : Base(role, network_thread), sending_(false), playout_(false), fail_set_send_codecs_(false), @@ -125,6 +126,7 @@ class RtpHelper : public Base { virtual absl::optional GetUnsignaledSsrc() const { return absl::nullopt; } + virtual bool SetLocalSsrc(const StreamParams& sp) { return true; } virtual void OnDemuxerCriteriaUpdatePending() {} virtual void OnDemuxerCriteriaUpdateComplete() {} @@ -260,6 +262,14 @@ class RtpHelper : public Base { rtc::scoped_refptr frame_transformer) override {} + void SetInterface(MediaChannelNetworkInterface* iface) override { + network_interface_ = iface; + MediaChannel::SetInterface(iface); + } + bool HasNetworkInterface() const override { + return network_interface_ != nullptr; + } + protected: bool MuteStream(uint32_t ssrc, bool mute) { if (!HasSendStream(ssrc) && ssrc != 0) { @@ -337,6 +347,7 @@ class RtpHelper : public Base { int transport_overhead_per_packet_; rtc::NetworkRoute last_network_route_; int num_network_route_changes_; + MediaChannelNetworkInterface* network_interface_ = nullptr; }; class FakeVoiceMediaChannel : public RtpHelper { @@ -347,7 +358,8 @@ class FakeVoiceMediaChannel : public RtpHelper { int event_code; int duration; }; - FakeVoiceMediaChannel(FakeVoiceEngine* engine, + FakeVoiceMediaChannel(MediaChannel::Role role, + FakeVoiceEngine* engine, const AudioOptions& options, webrtc::TaskQueueBase* network_thread); ~FakeVoiceMediaChannel(); @@ -442,7 +454,8 @@ bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info, class FakeVideoMediaChannel : public RtpHelper { public: - FakeVideoMediaChannel(FakeVideoEngine* engine, + FakeVideoMediaChannel(MediaChannel::Role role, + FakeVideoEngine* engine, const VideoOptions& options, webrtc::TaskQueueBase* network_thread); @@ -520,6 +533,7 @@ class FakeVoiceEngine : public VoiceEngineInterface { rtc::scoped_refptr GetAudioState() const override; VoiceMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const AudioOptions& options, @@ -559,6 +573,7 @@ class FakeVideoEngine : public VideoEngineInterface { FakeVideoEngine(); bool SetOptions(const VideoOptions& options); VideoMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, diff --git a/media/base/media_channel.h b/media/base/media_channel.h index 43e09290bd..1191986a84 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -73,6 +73,7 @@ webrtc::RTCError InvokeSetParametersCallback(SetParametersCallback& callback, namespace cricket { class AudioSource; +class MediaChannel; // TODO(bugs.webrtc.org/13931): Delete when irrelevant class VideoCapturer; struct RtpHeader; struct VideoFormat; @@ -212,6 +213,17 @@ class MediaBaseChannelInterface { // worker_thread. virtual void SetExtmapAllowMixed(bool extmap_allow_mixed) = 0; virtual bool ExtmapAllowMixed() const = 0; + + // Sets the abstract interface class for sending RTP/RTCP data. + virtual void SetInterface(MediaChannelNetworkInterface* iface) = 0; + + // Returns `true` if a non-null MediaChannelNetworkInterface pointer is held. + // Must be called on the network thread. + virtual bool HasNetworkInterface() const = 0; + + // Get the underlying send/receive implementation channel for testing. + // TODO(bugs.webrtc.org/13931): Remove method and the fakes that depend on it. + virtual MediaChannel* ImplForTesting() = 0; }; class MediaSendChannelInterface @@ -263,14 +275,9 @@ class MediaReceiveChannelInterface public: virtual ~MediaReceiveChannelInterface() = default; - virtual VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() { - RTC_CHECK_NOTREACHED(); - return nullptr; - } - virtual VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() { - RTC_CHECK_NOTREACHED(); - return nullptr; - } + virtual VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() = 0; + virtual VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() = 0; + // Creates a new incoming media stream with SSRCs, CNAME as described // by sp. In the case of a sp without SSRCs, the unsignaled sp is cached // to be used later for unsignaled streams received. @@ -284,6 +291,9 @@ class MediaReceiveChannelInterface virtual void ResetUnsignaledRecvStream() = 0; // 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; + // 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.cc b/media/base/media_channel_impl.cc index a72b97413d..ca2a117fd1 100644 --- a/media/base/media_channel_impl.cc +++ b/media/base/media_channel_impl.cc @@ -57,8 +57,11 @@ VideoOptions::VideoOptions() : content_hint(VideoTrackInterface::ContentHint::kNone) {} VideoOptions::~VideoOptions() = default; -MediaChannel::MediaChannel(TaskQueueBase* network_thread, bool enable_dscp) - : enable_dscp_(enable_dscp), +MediaChannel::MediaChannel(Role role, + TaskQueueBase* network_thread, + bool enable_dscp) + : role_(role), + enable_dscp_(enable_dscp), network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()), network_thread_(network_thread) {} diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h index 8142dd45b6..f18670f825 100644 --- a/media/base/media_channel_impl.h +++ b/media/base/media_channel_impl.h @@ -71,10 +71,22 @@ class VideoMediaChannel; class MediaChannel : public MediaSendChannelInterface, public MediaReceiveChannelInterface { public: - explicit MediaChannel(webrtc::TaskQueueBase* network_thread, + // Role of the channel. Used to describe which interface it supports. + // This is temporary until we stop using the same implementation for both + // interfaces. + enum class Role { + kSend, + kReceive, + kBoth // Temporary value for non-converted test code + }; + + explicit MediaChannel(Role role, + webrtc::TaskQueueBase* network_thread, bool enable_dscp = false); virtual ~MediaChannel(); + Role role() { return role_; } + // Downcasting to the subclasses. virtual VideoMediaChannel* AsVideoChannel() { RTC_CHECK_NOTREACHED(); @@ -85,7 +97,6 @@ class MediaChannel : public MediaSendChannelInterface, RTC_CHECK_NOTREACHED(); return nullptr; } - // Must declare the methods inherited from the base interface template, // even when abstract, to tell the compiler that all instances of the name // referred to by subclasses of this share the same implementation. @@ -97,8 +108,6 @@ class MediaChannel : public MediaSendChannelInterface, const rtc::NetworkRoute& network_route) override = 0; - // Sets the abstract interface class for sending RTP/RTCP data. - virtual void SetInterface(MediaChannelNetworkInterface* iface); // Returns the absolute sendtime extension id value from media channel. virtual int GetRtpSendTimeExtnId() const; // Base method to send packet using MediaChannelNetworkInterface. @@ -119,9 +128,10 @@ class MediaChannel : public MediaSendChannelInterface, void SetExtmapAllowMixed(bool extmap_allow_mixed) override; bool ExtmapAllowMixed() const override; + void SetInterface(MediaChannelNetworkInterface* iface) override; // Returns `true` if a non-null MediaChannelNetworkInterface pointer is held. // Must be called on the network thread. - bool HasNetworkInterface() const; + bool HasNetworkInterface() const override; void SetFrameEncryptor(uint32_t ssrc, rtc::scoped_refptr @@ -170,6 +180,7 @@ class MediaChannel : public MediaSendChannelInterface, bool rtcp, const rtc::PacketOptions& options); + const Role role_; const bool enable_dscp_; const rtc::scoped_refptr network_safety_ RTC_PT_GUARDED_BY(network_thread_); @@ -187,9 +198,10 @@ class VideoMediaChannel : public MediaChannel, public VideoMediaSendChannelInterface, public VideoMediaReceiveChannelInterface { public: - explicit VideoMediaChannel(webrtc::TaskQueueBase* network_thread, + explicit VideoMediaChannel(MediaChannel::Role role, + webrtc::TaskQueueBase* network_thread, bool enable_dscp = false) - : MediaChannel(network_thread, enable_dscp) {} + : MediaChannel(role, network_thread, enable_dscp) {} ~VideoMediaChannel() override {} // Downcasting to the implemented interfaces. @@ -202,6 +214,10 @@ class VideoMediaChannel : public MediaChannel, VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override { return this; } + VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override { + RTC_CHECK_NOTREACHED(); + return nullptr; + } cricket::MediaType media_type() const override; // Downcasting to the subclasses. @@ -213,6 +229,12 @@ class VideoMediaChannel : public MediaChannel, bool ExtmapAllowMixed() const override { return MediaChannel::ExtmapAllowMixed(); } + void SetInterface(MediaChannelNetworkInterface* iface) override { + return MediaChannel::SetInterface(iface); + } + // Declared here in order to avoid "found by multiple paths" compile error + bool AddSendStream(const StreamParams& sp) override = 0; + // This fills the "bitrate parts" (rtx, video bitrate) of the // BandwidthEstimationInfo, since that part that isn't possible to get // through webrtc::Call::GetStats, as they are statistics of the send @@ -225,8 +247,6 @@ class VideoMediaChannel : public MediaChannel, // Gets quality stats for the channel. virtual bool GetSendStats(VideoMediaSendInfo* info) = 0; virtual bool GetReceiveStats(VideoMediaReceiveInfo* info) = 0; - // Enable network condition based codec switching. - void SetVideoCodecSwitchingEnabled(bool enabled) override; private: // Functions not implemented on this interface @@ -238,6 +258,16 @@ class VideoMediaChannel : public MediaChannel, RTC_CHECK_NOTREACHED(); return false; } + bool HasNetworkInterface() const override { + return MediaChannel::HasNetworkInterface(); + } + // Enable network condition based codec switching. + void SetVideoCodecSwitchingEnabled(bool enabled) override; + + MediaChannel* ImplForTesting() override { + // This class and its subclasses are not interface classes. + RTC_CHECK_NOTREACHED(); + } }; // Base class for implementation classes @@ -246,9 +276,10 @@ class VoiceMediaChannel : public MediaChannel, public VoiceMediaReceiveChannelInterface { public: MediaType media_type() const override; - VoiceMediaChannel(webrtc::TaskQueueBase* network_thread, + VoiceMediaChannel(MediaChannel::Role role, + webrtc::TaskQueueBase* network_thread, bool enable_dscp = false) - : MediaChannel(network_thread, enable_dscp) {} + : MediaChannel(role, network_thread, enable_dscp) {} ~VoiceMediaChannel() override {} // Downcasting to the implemented interfaces. @@ -264,6 +295,10 @@ class VoiceMediaChannel : public MediaChannel, RTC_CHECK_NOTREACHED(); return nullptr; } + VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override { + RTC_CHECK_NOTREACHED(); + return nullptr; + } void SetExtmapAllowMixed(bool mixed) override { MediaChannel::SetExtmapAllowMixed(mixed); @@ -271,6 +306,12 @@ class VoiceMediaChannel : public MediaChannel, bool ExtmapAllowMixed() const override { return MediaChannel::ExtmapAllowMixed(); } + void SetInterface(MediaChannelNetworkInterface* iface) override { + return MediaChannel::SetInterface(iface); + } + bool HasNetworkInterface() const override { + return MediaChannel::HasNetworkInterface(); + } // Gets quality stats for the channel. virtual bool GetSendStats(VoiceMediaSendInfo* info) = 0; @@ -288,6 +329,10 @@ class VoiceMediaChannel : public MediaChannel, RTC_CHECK_NOTREACHED(); return false; } + MediaChannel* ImplForTesting() override { + // This class and its subclasses are not interface classes. + RTC_CHECK_NOTREACHED(); + } }; // The externally exposed objects that support the Send and Receive interfaces. @@ -320,6 +365,12 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface { impl()->SetExtmapAllowMixed(extmap_allow_mixed); } bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); } + void SetInterface(MediaChannelNetworkInterface* iface) override { + return impl()->SetInterface(iface); + } + bool HasNetworkInterface() const override { + return impl()->HasNetworkInterface(); + } // Implementation of MediaSendChannelInterface bool AddSendStream(const StreamParams& sp) override { return impl()->AddSendStream(sp); @@ -372,6 +423,7 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface { bool GetStats(VoiceMediaSendInfo* info) override { return impl_->GetSendStats(info); } + MediaChannel* ImplForTesting() override { return impl_; } private: VoiceMediaSendChannelInterface* impl() { return impl_; } @@ -383,6 +435,14 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { public: explicit VoiceMediaReceiveChannel(VoiceMediaChannel* impl) : impl_(impl) {} virtual ~VoiceMediaReceiveChannel() {} + + VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override { + return this; + } + VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override { + RTC_DCHECK_NOTREACHED(); + return nullptr; + } // Implementation of MediaBaseChannelInterface cricket::MediaType media_type() const override { return MEDIA_TYPE_AUDIO; } void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override { @@ -400,6 +460,12 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { impl()->SetExtmapAllowMixed(extmap_allow_mixed); } bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); } + void SetInterface(MediaChannelNetworkInterface* iface) override { + return impl()->SetInterface(iface); + } + bool HasNetworkInterface() const override { + return impl()->HasNetworkInterface(); + } // Implementation of Delayable bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override { return impl()->SetBaseMinimumPlayoutDelayMs(ssrc, delay_ms); @@ -418,6 +484,9 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { void ResetUnsignaledRecvStream() override { return impl()->ResetUnsignaledRecvStream(); } + bool SetLocalSsrc(const StreamParams& sp) override { + return impl()->SetLocalSsrc(sp); + } absl::optional GetUnsignaledSsrc() const override { return impl()->GetUnsignaledSsrc(); } @@ -470,6 +539,7 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { bool GetStats(VoiceMediaReceiveInfo* info, bool reset_legacy) override { return impl_->GetReceiveStats(info, reset_legacy); } + MediaChannel* ImplForTesting() override { return impl_; } private: VoiceMediaReceiveChannelInterface* impl() { return impl_; } @@ -503,7 +573,13 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { void SetExtmapAllowMixed(bool extmap_allow_mixed) override { impl()->SetExtmapAllowMixed(extmap_allow_mixed); } + bool HasNetworkInterface() const override { + return impl()->HasNetworkInterface(); + } bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); } + void SetInterface(MediaChannelNetworkInterface* iface) override { + return impl()->SetInterface(iface); + } // Implementation of MediaSendChannelInterface bool AddSendStream(const StreamParams& sp) override { return impl()->AddSendStream(sp); @@ -566,6 +642,8 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { return impl_->FillBitrateInfo(bwe_info); } + MediaChannel* ImplForTesting() override { return impl_; } + private: VideoMediaSendChannelInterface* impl() { return impl_; } const VideoMediaSendChannelInterface* impl() const { return impl_; } @@ -575,6 +653,15 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { public: explicit VideoMediaReceiveChannel(VideoMediaChannel* impl) : impl_(impl) {} + + VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override { + return this; + } + VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override { + RTC_DCHECK_NOTREACHED(); + return nullptr; + } + // Implementation of MediaBaseChannelInterface cricket::MediaType media_type() const override { return MEDIA_TYPE_VIDEO; } void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override { @@ -592,6 +679,12 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { impl()->SetExtmapAllowMixed(extmap_allow_mixed); } bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); } + void SetInterface(MediaChannelNetworkInterface* iface) override { + return impl()->SetInterface(iface); + } + bool HasNetworkInterface() const override { + return impl()->HasNetworkInterface(); + } // Implementation of Delayable bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override { return impl()->SetBaseMinimumPlayoutDelayMs(ssrc, delay_ms); @@ -601,9 +694,6 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { return impl()->GetBaseMinimumPlayoutDelayMs(ssrc); } // Implementation of MediaReceiveChannelInterface - VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override { - return this; - } bool AddRecvStream(const StreamParams& sp) override { return impl()->AddRecvStream(sp); } @@ -616,6 +706,9 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { absl::optional GetUnsignaledSsrc() const override { return impl()->GetUnsignaledSsrc(); } + bool SetLocalSsrc(const StreamParams& sp) override { + return impl()->SetLocalSsrc(sp); + } void OnDemuxerCriteriaUpdatePending() override { impl()->OnDemuxerCriteriaUpdatePending(); } @@ -671,6 +764,7 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { bool GetStats(VideoMediaReceiveInfo* info) override { return impl_->GetReceiveStats(info); } + MediaChannel* ImplForTesting() override { return impl_; } private: VideoMediaReceiveChannelInterface* impl() { return impl_; } diff --git a/media/base/media_engine.h b/media/base/media_engine.h index cc7563a85e..8ab172fb0d 100644 --- a/media/base/media_engine.h +++ b/media/base/media_engine.h @@ -24,6 +24,7 @@ #include "call/audio_state.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/video_common.h" #include "rtc_base/system/file_wrapper.h" @@ -100,10 +101,25 @@ class VoiceEngineInterface : public RtpHeaderExtensionQueryInterface { // MediaChannel creation // Creates a voice media channel. Returns NULL on failure. virtual VoiceMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const AudioOptions& options, - const webrtc::CryptoOptions& crypto_options) = 0; + const webrtc::CryptoOptions& crypto_options) { + // TODO(bugs.webrtc.org/13931): Remove default implementation + // when downstream has migrated to new API. + RTC_CHECK_NOTREACHED(); + } + + // Backwards compatible version + [[deprecated("Use version with role parameter")]] virtual VoiceMediaChannel* + CreateMediaChannel(webrtc::Call* call, + const MediaConfig& config, + const AudioOptions& options, + const webrtc::CryptoOptions& crypto_options) { + return CreateMediaChannel(MediaChannel::Role::kBoth, call, config, options, + crypto_options); + } virtual const std::vector& send_codecs() const = 0; virtual const std::vector& recv_codecs() const = 0; @@ -129,15 +145,34 @@ class VideoEngineInterface : public RtpHeaderExtensionQueryInterface { VideoEngineInterface(const VideoEngineInterface&) = delete; VideoEngineInterface& operator=(const VideoEngineInterface&) = delete; - // Creates a video media channel, paired with the specified voice channel. + // Creates a video media channel. // Returns NULL on failure. virtual VideoMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, const webrtc::CryptoOptions& crypto_options, - webrtc::VideoBitrateAllocatorFactory* - video_bitrate_allocator_factory) = 0; + webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) { + // TODO(bugs.webrtc.org/13931): Remove default implementation + // when downstream has migrated. + RTC_CHECK_NOTREACHED(); + return nullptr; + } + + // Creates a video media channel. + // Returns NULL on failure. + // TODO(bugs.webrtc.org/13931): Stop downstream usage of this function. + [[deprecated("Please specify the role")]] virtual VideoMediaChannel* + CreateMediaChannel( + webrtc::Call* call, + const MediaConfig& config, + const VideoOptions& options, + const webrtc::CryptoOptions& crypto_options, + webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) { + return CreateMediaChannel(MediaChannel::Role::kBoth, call, config, options, + crypto_options, video_bitrate_allocator_factory); + } // Retrieve list of supported codecs. virtual std::vector send_codecs() const = 0; diff --git a/media/engine/null_webrtc_video_engine.h b/media/engine/null_webrtc_video_engine.h index ede0d1b52b..5efefd498f 100644 --- a/media/engine/null_webrtc_video_engine.h +++ b/media/engine/null_webrtc_video_engine.h @@ -51,6 +51,7 @@ class NullWebRtcVideoEngine : public VideoEngineInterface { } VideoMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 3791e1099b..edd6c3854c 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -600,13 +600,14 @@ WebRtcVideoEngine::~WebRtcVideoEngine() { } VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, const webrtc::CryptoOptions& crypto_options, webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) { RTC_LOG(LS_INFO) << "CreateMediaChannel. Options: " << options.ToString(); - return new WebRtcVideoChannel(call, config, options, crypto_options, + return new WebRtcVideoChannel(role, call, config, options, crypto_options, encoder_factory_.get(), decoder_factory_.get(), video_bitrate_allocator_factory); } @@ -664,6 +665,7 @@ WebRtcVideoEngine::GetRtpHeaderExtensions() const { } WebRtcVideoChannel::WebRtcVideoChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, @@ -671,7 +673,7 @@ WebRtcVideoChannel::WebRtcVideoChannel( webrtc::VideoEncoderFactory* encoder_factory, webrtc::VideoDecoderFactory* decoder_factory, webrtc::VideoBitrateAllocatorFactory* bitrate_allocator_factory) - : VideoMediaChannel(call->network_thread(), config.enable_dscp), + : VideoMediaChannel(role, call->network_thread(), config.enable_dscp), worker_thread_(call->worker_thread()), call_(call), default_sink_(nullptr), @@ -1326,6 +1328,9 @@ bool WebRtcVideoChannel::ValidateReceiveSsrcAvailability( bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) { RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK(role() == MediaChannel::Role::kSend || + role() == MediaChannel::Role::kBoth); + RTC_LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); if (!ValidateStreamParams(sp)) return false; @@ -1364,8 +1369,12 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) { RTC_DCHECK(ssrc != 0); send_streams_[ssrc] = stream; - if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { - SetReceiverReportSsrc(ssrc); + // 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); + } } if (sending_) { @@ -1554,6 +1563,15 @@ 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; @@ -1617,6 +1635,7 @@ bool WebRtcVideoChannel::GetSendStats(VideoMediaSendInfo* info) { log_stats = true; } + info->Clear(); FillSenderStats(info, log_stats); FillSendCodecStats(info); // TODO(holmer): We should either have rtt available as a metric on diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index ee22a7e25d..8a14ea42ec 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -74,6 +74,7 @@ class WebRtcVideoEngine : public VideoEngineInterface { ~WebRtcVideoEngine() override; VideoMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, @@ -105,6 +106,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::EncoderSwitchRequestCallback { public: WebRtcVideoChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, @@ -137,6 +139,7 @@ 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, diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 3cc1b3cfe4..272b800bc2 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -613,7 +613,8 @@ TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) { AddSupportedVideoCodecType("VP8"); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); auto send_channel = std::make_unique(channel.get()); @@ -629,7 +630,8 @@ TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) { AddSupportedVideoCodecType("VP8"); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); auto send_channel = std::make_unique(channel.get()); @@ -856,7 +858,8 @@ void WebRtcVideoEngineTest::AddSupportedVideoCodecType( VideoMediaChannel* WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() { VideoMediaChannel* channel = engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()); cricket::VideoSendParameters parameters; // We need to look up the codec in the engine to get the correct payload type. @@ -876,7 +879,8 @@ WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() { VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs( const std::vector& codecs) { VideoMediaChannel* channel = engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()); cricket::VideoRecvParameters parameters; parameters.codecs = codecs; @@ -913,8 +917,8 @@ TEST_F(WebRtcVideoEngineTest, SendsFeedbackAfterUnsignaledRtxPacket) { }), Return(true))); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), - video_bitrate_allocator_factory_.get())); + MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), VideoOptions(), + webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); cricket::VideoRecvParameters parameters; parameters.codecs = supported_codecs; const int kTransportSeqExtensionId = 1; @@ -952,8 +956,8 @@ TEST_F(WebRtcVideoEngineTest, UpdatesUnsignaledRtxSsrcAndRecoversPayload) { int rtx_payload_type = supported_codecs[1].id; std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), - video_bitrate_allocator_factory_.get())); + MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), VideoOptions(), + webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); cricket::VideoRecvParameters parameters; parameters.codecs = supported_codecs; ASSERT_TRUE(channel->SetRecvParameters(parameters)); @@ -1034,7 +1038,8 @@ TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) { rtc::kNumMicrosecsPerSec / 30); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); auto send_channel = std::make_unique(channel.get()); cricket::VideoSendParameters parameters; @@ -1067,7 +1072,8 @@ TEST_F(WebRtcVideoEngineTest, AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); auto send_channel = std::make_unique(channel.get()); cricket::VideoSendParameters parameters; @@ -1106,7 +1112,8 @@ TEST_F(WebRtcVideoEngineTest, AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); auto send_channel = std::make_unique(channel.get()); cricket::VideoSendParameters parameters; @@ -1140,7 +1147,8 @@ TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) { AddSupportedVideoCodecType("H264"); std::unique_ptr channel(engine_.CreateMediaChannel( - call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); auto send_channel = std::make_unique(channel.get()); @@ -1441,8 +1449,8 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) { // Create send channel. const int send_ssrc = 123; std::unique_ptr send_channel(engine.CreateMediaChannel( - call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), - rate_allocator_factory.get())); + cricket::MediaChannel::Role::kBoth, call.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), rate_allocator_factory.get())); auto send_send_channel = std::make_unique(send_channel.get()); @@ -1466,8 +1474,8 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) { // Create recv channel. const int recv_ssrc = 321; std::unique_ptr recv_channel(engine.CreateMediaChannel( - call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), - rate_allocator_factory.get())); + cricket::MediaChannel::Role::kBoth, call.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), rate_allocator_factory.get())); auto receive_channel = std::make_unique(recv_channel.get()); @@ -1592,6 +1600,7 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { field_trials_), channel_(absl::WrapUnique(static_cast( engine_.CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, call_.get(), cricket::MediaConfig(), cricket::VideoOptions(), @@ -1738,8 +1747,9 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { media_config.video.enable_cpu_adaptation = false; channel_.reset( static_cast(engine_.CreateMediaChannel( - call_.get(), media_config, cricket::VideoOptions(), - webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()))); + cricket::MediaChannel::Role::kBoth, call_.get(), media_config, + cricket::VideoOptions(), webrtc::CryptoOptions(), + video_bitrate_allocator_factory_.get()))); send_channel_ = std::make_unique(channel_.get()); receive_channel_ = std::make_unique(channel_.get()); @@ -2604,8 +2614,9 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { fake_call_.reset(new FakeCall(&field_trials_)); channel_.reset(engine_.CreateMediaChannel( - fake_call_.get(), GetMediaConfig(), VideoOptions(), - webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); + cricket::MediaChannel::Role::kBoth, fake_call_.get(), GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), + video_bitrate_allocator_factory_.get())); send_channel_ = std::make_unique(channel_.get()); receive_channel_ = @@ -3483,9 +3494,12 @@ TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) { media_config.video.suspend_below_min_bitrate = true; channel_.reset(engine_.CreateMediaChannel( - fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); send_channel_.reset(new VideoMediaSendChannel(channel_.get())); + receive_channel_ = + std::make_unique(channel_.get()); send_channel_->OnReadyToSend(true); channel_->SetSendParameters(send_parameters_); @@ -3495,9 +3509,12 @@ TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) { media_config.video.suspend_below_min_bitrate = false; channel_.reset(engine_.CreateMediaChannel( - fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); send_channel_.reset(new VideoMediaSendChannel(channel_.get())); + receive_channel_ = + std::make_unique(channel_.get()); send_channel_->OnReadyToSend(true); channel_->SetSendParameters(send_parameters_); @@ -4037,9 +4054,12 @@ TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) { MediaConfig media_config = GetMediaConfig(); media_config.video.enable_cpu_adaptation = true; channel_.reset(engine_.CreateMediaChannel( - fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); send_channel_.reset(new VideoMediaSendChannel(channel_.get())); + receive_channel_ = + std::make_unique(channel_.get()); send_channel_->OnReadyToSend(true); ASSERT_TRUE(channel_->SetSendParameters(parameters)); @@ -4089,9 +4109,12 @@ void WebRtcVideoChannelTest::TestDegradationPreference( MediaConfig media_config = GetMediaConfig(); media_config.video.enable_cpu_adaptation = true; channel_.reset(engine_.CreateMediaChannel( - fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); send_channel_.reset(new VideoMediaSendChannel(channel_.get())); + receive_channel_ = + std::make_unique(channel_.get()); send_channel_->OnReadyToSend(true); EXPECT_TRUE(channel_->SetSendParameters(parameters)); @@ -4123,9 +4146,12 @@ void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse, media_config.video.enable_cpu_adaptation = true; } channel_.reset(engine_.CreateMediaChannel( - fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())); send_channel_.reset(new VideoMediaSendChannel(channel_.get())); + receive_channel_ = + std::make_unique(channel_.get()); send_channel_->OnReadyToSend(true); EXPECT_TRUE(channel_->SetSendParameters(parameters)); @@ -5455,7 +5481,8 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) { channel.reset( static_cast(engine_.CreateMediaChannel( - call_.get(), config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()))); send_channel.reset(new VideoMediaSendChannel(channel_.get())); @@ -5469,7 +5496,8 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) { config.enable_dscp = true; channel.reset( static_cast(engine_.CreateMediaChannel( - call_.get(), config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()))); send_channel.reset(new VideoMediaSendChannel(channel.get())); channel->SetInterface(network_interface.get()); @@ -5502,7 +5530,8 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) { config.enable_dscp = false; channel.reset( static_cast(engine_.CreateMediaChannel( - call_.get(), config, VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, call_.get(), config, + VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()))); channel->SetInterface(network_interface.get()); EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp()); @@ -9401,7 +9430,8 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test { encoder_factory_->AddSupportedVideoCodecType("VP8"); decoder_factory_->AddSupportedVideoCodecType("VP8"); channel_.reset(engine_.CreateMediaChannel( - &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(), + cricket::MediaChannel::Role::kBoth, &fake_call_, GetMediaConfig(), + VideoOptions(), webrtc::CryptoOptions(), mock_rate_allocator_factory_.get())); send_channel_ = std::make_unique(channel_.get()); receive_channel_ = diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index e093c6f12d..3132cbcce3 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -409,13 +409,14 @@ rtc::scoped_refptr WebRtcVoiceEngine::GetAudioState() } VoiceMediaChannel* WebRtcVoiceEngine::CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options) { RTC_DCHECK_RUN_ON(call->worker_thread()); - return new WebRtcVoiceMediaChannel(this, config, options, crypto_options, - call); + return new WebRtcVoiceMediaChannel(role, this, config, options, + crypto_options, call); } void WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { @@ -1249,12 +1250,13 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { }; WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel( + MediaChannel::Role role, WebRtcVoiceEngine* engine, const MediaConfig& config, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, webrtc::Call* call) - : VoiceMediaChannel(call->network_thread(), config.enable_dscp), + : VoiceMediaChannel(role, call->network_thread(), config.enable_dscp), worker_thread_(call->worker_thread()), engine_(engine), call_(call), @@ -1822,6 +1824,8 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::AddSendStream"); RTC_DCHECK_RUN_ON(worker_thread_); RTC_LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); + RTC_DCHECK(role() == MediaChannel::Role::kSend || + role() == MediaChannel::Role::kBoth); uint32_t ssrc = sp.first_ssrc(); RTC_DCHECK(0 != ssrc); @@ -1840,14 +1844,19 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { call_, this, engine()->encoder_factory_, codec_pair_id_, nullptr, crypto_options_); send_streams_.insert(std::make_pair(ssrc, stream)); + if (role() == MediaChannel::Role::kBoth) { + // In legacy kBoth mode, the MediaChannel takes the responsibility for + // telling the receiver about the local SSRC. + // In kSend mode, this is the caller's responsibility. - // At this point the stream's local SSRC has been updated. If it is the first - // send stream, make sure that all the receive streams are updated with the - // same SSRC in order to send receiver reports. - if (send_streams_.size() == 1) { - receiver_reports_ssrc_ = ssrc; - for (auto& kv : recv_streams_) { - call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc); + // At this point the stream's local SSRC has been updated. If it is the + // first send stream, make sure that all the receive streams are updated + // with the same SSRC in order to send receiver reports. + if (send_streams_.size() == 1) { + receiver_reports_ssrc_ = ssrc; + for (auto& kv : recv_streams_) { + call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc); + } } } @@ -1884,6 +1893,8 @@ bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::AddRecvStream"); RTC_DCHECK_RUN_ON(worker_thread_); + RTC_DCHECK(role() == MediaChannel::Role::kReceive || + role() == MediaChannel::Role::kBoth); RTC_LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); if (!sp.has_ssrcs()) { @@ -1970,6 +1981,16 @@ 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(); + receiver_reports_ssrc_ = ssrc; + for (auto& kv : recv_streams_) { + call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc); + } + return true; +} + // Not implemented. // TODO(https://crbug.com/webrtc/12676): Implement a fix for the unsignalled // SSRC race that can happen when an m= section goes from receiving to not @@ -2282,7 +2303,10 @@ bool WebRtcVoiceMediaChannel::GetSendStats(VoiceMediaSendInfo* info) { RTC_DCHECK(info); // Get SSRC and stats for each sender. - RTC_DCHECK_EQ(info->senders.size(), 0U); + // With separate send and receive channels, we expect GetStats to be called on + // both, and accumulate info, but only one channel (the send one) should have + // senders. + RTC_DCHECK(info->senders.size() == 0U || send_streams_.size() == 0); for (const auto& stream : send_streams_) { webrtc::AudioSendStream::Stats stats = stream.second->GetStats(recv_streams_.size() > 0); diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 1c06183e44..8fa7d7de3e 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -69,6 +69,7 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { rtc::scoped_refptr GetAudioState() const override; VoiceMediaChannel* CreateMediaChannel( + MediaChannel::Role role, webrtc::Call* call, const MediaConfig& config, const AudioOptions& options, @@ -139,7 +140,8 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, public webrtc::Transport { public: - WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, + WebRtcVoiceMediaChannel(MediaChannel::Role role, + WebRtcVoiceEngine* engine, const MediaConfig& config, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, @@ -175,6 +177,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, 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; diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index 70b2cf8d52..70cc46159b 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -230,9 +230,9 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { } bool SetupChannel() { - channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), - cricket::AudioOptions(), - webrtc::CryptoOptions()); + channel_ = engine_->CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(), + cricket::AudioOptions(), webrtc::CryptoOptions()); send_channel_ = std::make_unique(channel_); receive_channel_ = std::make_unique(channel_); @@ -3029,9 +3029,9 @@ TEST_P(WebRtcVoiceEngineTestFake, InitRecordingOnSend) { EXPECT_CALL(*adm_, InitRecording()).Times(1); std::unique_ptr channel( - engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), - cricket::AudioOptions(), - webrtc::CryptoOptions())); + engine_->CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(), + cricket::AudioOptions(), webrtc::CryptoOptions())); channel->SetSend(true); } @@ -3045,7 +3045,8 @@ TEST_P(WebRtcVoiceEngineTestFake, SkipInitRecordingOnSend) { options.init_recording_on_send = false; std::unique_ptr channel( - engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), options, + engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, + cricket::MediaConfig(), options, webrtc::CryptoOptions())); channel->SetSend(true); @@ -3071,12 +3072,14 @@ TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) { std::unique_ptr channel1( static_cast( - engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), + engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, + &call_, cricket::MediaConfig(), cricket::AudioOptions(), webrtc::CryptoOptions()))); std::unique_ptr channel2( static_cast( - engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), + engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, + &call_, cricket::MediaConfig(), cricket::AudioOptions(), webrtc::CryptoOptions()))); @@ -3188,7 +3191,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) { webrtc::RtpParameters parameters; channel.reset(static_cast( - engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(), + engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, + config, cricket::AudioOptions(), webrtc::CryptoOptions()))); channel->SetInterface(&network_interface); // Default value when DSCP is disabled should be DSCP_DEFAULT. @@ -3197,7 +3201,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) { config.enable_dscp = true; channel.reset(static_cast( - engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(), + engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, + config, cricket::AudioOptions(), webrtc::CryptoOptions()))); channel->SetInterface(&network_interface); EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp()); @@ -3226,7 +3231,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) { // DiffServCodePoint. config.enable_dscp = false; channel.reset(static_cast( - engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(), + engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, + config, cricket::AudioOptions(), webrtc::CryptoOptions()))); channel->SetInterface(&network_interface); // Default value when DSCP is disabled should be DSCP_DEFAULT. @@ -3473,6 +3479,7 @@ TEST_P(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) { EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc); EXPECT_TRUE(send_channel_->AddSendStream( cricket::StreamParams::CreateLegacy(kSsrcW))); + EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc); EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc); } @@ -3636,8 +3643,8 @@ TEST(WebRtcVoiceEngineTest, StartupShutdown) { call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel( - call.get(), cricket::MediaConfig(), cricket::AudioOptions(), - webrtc::CryptoOptions()); + cricket::MediaChannel::Role::kBoth, call.get(), cricket::MediaConfig(), + cricket::AudioOptions(), webrtc::CryptoOptions()); EXPECT_TRUE(channel != nullptr); delete channel; } @@ -3667,7 +3674,8 @@ TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) { call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel( - call.get(), cricket::MediaConfig(), cricket::AudioOptions(), + cricket::MediaChannel::Role::kBoth, call.get(), + cricket::MediaConfig(), cricket::AudioOptions(), webrtc::CryptoOptions()); EXPECT_TRUE(channel != nullptr); delete channel; @@ -3756,7 +3764,8 @@ TEST(WebRtcVoiceEngineTest, Has32Channels) { size_t num_channels = 0; while (num_channels < arraysize(channels)) { cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel( - call.get(), cricket::MediaConfig(), cricket::AudioOptions(), + cricket::MediaChannel::Role::kBoth, call.get(), + cricket::MediaConfig(), cricket::AudioOptions(), webrtc::CryptoOptions()); if (!channel) break; @@ -3802,8 +3811,8 @@ TEST(WebRtcVoiceEngineTest, SetRecvCodecs) { call_config.task_queue_factory = task_queue_factory.get(); auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); cricket::WebRtcVoiceMediaChannel channel( - &engine, cricket::MediaConfig(), cricket::AudioOptions(), - webrtc::CryptoOptions(), call.get()); + cricket::MediaChannel::Role::kReceive, &engine, cricket::MediaConfig(), + cricket::AudioOptions(), webrtc::CryptoOptions(), call.get()); cricket::AudioRecvParameters parameters; parameters.codecs = engine.recv_codecs(); EXPECT_TRUE(channel.SetRecvParameters(parameters)); @@ -3835,9 +3844,9 @@ TEST(WebRtcVoiceEngineTest, SetRtpSendParametersMaxBitrate) { call_config.audio_state = webrtc::AudioState::Create(config); } auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); - cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(), - cricket::AudioOptions(), - webrtc::CryptoOptions(), call.get()); + cricket::WebRtcVoiceMediaChannel channel( + cricket::MediaChannel::Role::kSend, &engine, cricket::MediaConfig(), + cricket::AudioOptions(), webrtc::CryptoOptions(), call.get()); { cricket::AudioSendParameters params; params.codecs.push_back(cricket::AudioCodec(1, "opus", 48000, 32000, 2)); diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc index 27ad96aa3f..1635ea5135 100644 --- a/pc/channel_unittest.cc +++ b/pc/channel_unittest.cc @@ -151,9 +151,11 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { void CreateChannels(int flags1, int flags2) { CreateChannels(std::make_unique( - nullptr, typename T::Options(), network_thread_), + cricket::MediaChannel::Role::kBoth, nullptr, + typename T::Options(), network_thread_), std::make_unique( - nullptr, typename T::Options(), network_thread_), + cricket::MediaChannel::Role::kBoth, nullptr, + typename T::Options(), network_thread_), flags1, flags2); } void CreateChannels(std::unique_ptr ch1, diff --git a/pc/rtp_sender_receiver_unittest.cc b/pc/rtp_sender_receiver_unittest.cc index 04043437a7..bcca2da162 100644 --- a/pc/rtp_sender_receiver_unittest.cc +++ b/pc/rtp_sender_receiver_unittest.cc @@ -119,11 +119,13 @@ class RtpSenderReceiverTest // Create the channels, discard the result; we get them later. // Fake media channels are owned by the media engine. media_engine_->voice().CreateMediaChannel( - &fake_call_, cricket::MediaConfig(), cricket::AudioOptions(), - webrtc::CryptoOptions()); + cricket::MediaChannel::Role::kBoth, &fake_call_, cricket::MediaConfig(), + cricket::AudioOptions(), webrtc::CryptoOptions()); media_engine_->video().CreateMediaChannel( - &fake_call_, cricket::MediaConfig(), cricket::VideoOptions(), - webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()); + cricket::MediaChannel::Role::kBoth, &fake_call_, cricket::MediaConfig(), + cricket::VideoOptions(), webrtc::CryptoOptions(), + video_bitrate_allocator_factory_.get()); + // TODO(hta): Split into sender and receiver channels voice_media_channel_ = absl::WrapUnique(media_engine_->GetVoiceChannel(0)); video_media_channel_ = absl::WrapUnique(media_engine_->GetVideoChannel(0)); diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index 76549d1735..791eb8c643 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -211,7 +211,8 @@ RTCError RtpTransceiver::CreateChannel( cricket::VoiceMediaChannel* media_channel = media_engine()->voice().CreateMediaChannel( - call_ptr, media_config, audio_options, crypto_options); + cricket::MediaChannel::Role::kBoth, call_ptr, media_config, + audio_options, crypto_options); if (!media_channel) { return; } @@ -231,8 +232,8 @@ RTCError RtpTransceiver::CreateChannel( RTC_DCHECK_RUN_ON(context()->worker_thread()); cricket::VideoMediaChannel* media_channel = media_engine()->video().CreateMediaChannel( - call_ptr, media_config, video_options, crypto_options, - video_bitrate_allocator_factory); + cricket::MediaChannel::Role::kBoth, call_ptr, media_config, + video_options, crypto_options, video_bitrate_allocator_factory); if (!media_channel) { return; } diff --git a/pc/test/fake_peer_connection_for_stats.h b/pc/test/fake_peer_connection_for_stats.h index b771d45a0b..d1914fd708 100644 --- a/pc/test/fake_peer_connection_for_stats.h +++ b/pc/test/fake_peer_connection_for_stats.h @@ -30,7 +30,8 @@ namespace webrtc { class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { public: explicit FakeVoiceMediaChannelForStats(TaskQueueBase* network_thread) - : cricket::FakeVoiceMediaChannel(nullptr, + : cricket::FakeVoiceMediaChannel(MediaChannel::Role::kBoth, + nullptr, cricket::AudioOptions(), network_thread) {} @@ -70,7 +71,8 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel { public: explicit FakeVideoMediaChannelForStats(TaskQueueBase* network_thread) - : cricket::FakeVideoMediaChannel(nullptr, + : cricket::FakeVideoMediaChannel(MediaChannel::Role::kBoth, + nullptr, cricket::VideoOptions(), network_thread) {} diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h index 2e5a8b5801..71f7a18860 100644 --- a/pc/test/mock_voice_media_channel.h +++ b/pc/test/mock_voice_media_channel.h @@ -29,7 +29,7 @@ namespace cricket { class MockVoiceMediaChannel : public VoiceMediaChannel { public: explicit MockVoiceMediaChannel(webrtc::TaskQueueBase* network_thread) - : VoiceMediaChannel(network_thread) {} + : VoiceMediaChannel(MediaChannel::Role::kBoth, network_thread) {} MOCK_METHOD(void, SetInterface, @@ -49,6 +49,9 @@ class MockVoiceMediaChannel : public VoiceMediaChannel { (absl::string_view transport_name, const rtc::NetworkRoute& network_route), (override)); + MOCK_METHOD(void, SetExtmapAllowMixed, (bool extmap_allow_mixed), (override)); + MOCK_METHOD(bool, ExtmapAllowMixed, (), (const, override)); + MOCK_METHOD(bool, HasNetworkInterface, (), (const, override)); MOCK_METHOD(bool, AddSendStream, (const StreamParams& sp), (override)); MOCK_METHOD(bool, RemoveSendStream, (uint32_t ssrc), (override)); MOCK_METHOD(bool, AddRecvStream, (const StreamParams& sp), (override)); @@ -58,6 +61,7 @@ class MockVoiceMediaChannel : public VoiceMediaChannel { GetUnsignaledSsrc, (), (const, override)); + MOCK_METHOD(bool, SetLocalSsrc, (const StreamParams& sp), (override)); MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override)); MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override)); MOCK_METHOD(int, GetRtpSendTimeExtnId, (), (const, override)); diff --git a/pc/video_rtp_receiver_unittest.cc b/pc/video_rtp_receiver_unittest.cc index 3ec9a28295..5efd6df471 100644 --- a/pc/video_rtp_receiver_unittest.cc +++ b/pc/video_rtp_receiver_unittest.cc @@ -40,7 +40,10 @@ class VideoRtpReceiverTest : public testing::Test { cricket::FakeVideoEngine* engine, const cricket::VideoOptions& options, TaskQueueBase* network_thread = rtc::Thread::Current()) - : FakeVideoMediaChannel(engine, options, network_thread) {} + : FakeVideoMediaChannel(cricket::MediaChannel::Role::kBoth, + engine, + options, + network_thread) {} MOCK_METHOD(void, SetRecordableEncodedFrameCallback, (uint32_t, std::function),