From 2f5537063473ab9ffb5fb5306896b05d96c3304f Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 7 Mar 2023 10:10:03 +0000 Subject: [PATCH] Reland "Use two MediaChannels for 2 directions." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 18c869bc36b342cd4a79947067e52a93a04a7808. Reason for revert: Added a field trial that allows landing the code without affecting performance in prod. This CL also incorporates subsequent CLs that also had to be reverted. Original change's description: > Revert "Use two MediaChannels for 2 directions." > > This reverts commit 8981a6fac3d665beac4a58b9453e6c39988a024f. > > Reason for revert: Quality regression detected. > > Original change's description: > > Use two MediaChannels for 2 directions. > > > > This CL separates the two directions of MediaChannel into two separate objects that do not couple with each other. > > > > The notable API change is that receiver local SSRC now has to be set explicitly - before, it was done implicitly when the send-side MediaChannel had a stream added to it. > > > > Bug: webrtc:13931 > > Change-Id: I83c2e3c8e79f89872d5adda1bc2899f7049748b3 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/288400 > > Commit-Queue: Harald Alvestrand > > Reviewed-by: Henrik Boström > > Cr-Commit-Position: refs/heads/main@{#39340} > > No-Try: true > Bug: webrtc:13931 > Change-Id: I791997ad9eff75c3ac9cd2e4bbacf5bc6c3a3a79 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/295663 > Commit-Queue: Harald Alvestrand > Reviewed-by: Mirko Bonadei > Cr-Commit-Position: refs/heads/main@{#39445} Bug: webrtc:13931 Change-Id: I1318910a685188e2b846c9040e1efc04c2c894ac Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/296080 Reviewed-by: Tomas Gunnarsson Reviewed-by: Per Kjellander Commit-Queue: Harald Alvestrand Reviewed-by: Henrik Boström Cr-Commit-Position: refs/heads/main@{#39494} --- media/base/fake_media_engine.cc | 99 +++- media/base/fake_media_engine.h | 36 +- media/base/media_channel.h | 13 + media/base/media_channel_impl.h | 33 +- media/engine/webrtc_video_engine.cc | 46 +- media/engine/webrtc_video_engine.h | 43 ++ media/engine/webrtc_voice_engine.cc | 52 ++- media/engine/webrtc_voice_engine.h | 26 +- media/engine/webrtc_voice_engine_unittest.cc | 47 +- pc/audio_rtp_receiver_unittest.cc | 6 +- pc/channel.cc | 210 +++++++-- pc/channel.h | 60 ++- pc/channel_interface.h | 2 - pc/channel_unittest.cc | 448 ++++++++++--------- pc/legacy_stats_collector_unittest.cc | 43 +- pc/peer_connection_media_unittest.cc | 170 ++++--- pc/rtc_stats_collector_unittest.cc | 35 +- pc/rtp_sender_receiver_unittest.cc | 224 ++++++---- pc/rtp_transceiver.cc | 99 +++- pc/test/fake_peer_connection_for_stats.h | 129 ++++-- pc/test/mock_channel_interface.h | 1 - pc/test/mock_voice_media_channel.h | 9 +- 22 files changed, 1232 insertions(+), 599 deletions(-) diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc index 7a8a4094fd..b25288342a 100644 --- a/media/base/fake_media_engine.cc +++ b/media/base/fake_media_engine.cc @@ -463,14 +463,43 @@ VoiceMediaChannel* FakeVoiceEngine::CreateMediaChannel( FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(role, this, options, call->network_thread()); - channels_.push_back(ch); + switch (role) { + case MediaChannel::Role::kSend: + send_channels_.push_back(ch); + break; + case MediaChannel::Role::kReceive: + receive_channels_.push_back(ch); + break; + case MediaChannel::Role::kBoth: + send_channels_.push_back(ch); + receive_channels_.push_back(ch); + break; + default: + RTC_CHECK_NOTREACHED(); + } return ch; } -FakeVoiceMediaChannel* FakeVoiceEngine::GetChannel(size_t index) { - return (channels_.size() > index) ? channels_[index] : NULL; +FakeVoiceMediaChannel* FakeVoiceEngine::GetSendChannel(size_t index) { + return (send_channels_.size() > index) ? send_channels_[index] : NULL; +} +FakeVoiceMediaChannel* FakeVoiceEngine::GetReceiveChannel(size_t index) { + return (receive_channels_.size() > index) ? receive_channels_[index] : NULL; } void FakeVoiceEngine::UnregisterChannel(VoiceMediaChannel* channel) { - channels_.erase(absl::c_find(channels_, channel)); + switch (channel->role()) { + case MediaChannel::Role::kSend: + send_channels_.erase(absl::c_find(send_channels_, channel)); + break; + case MediaChannel::Role::kReceive: + receive_channels_.erase(absl::c_find(receive_channels_, channel)); + break; + case MediaChannel::Role::kBoth: + send_channels_.erase(absl::c_find(send_channels_, channel)); + receive_channels_.erase(absl::c_find(receive_channels_, channel)); + break; + default: + RTC_CHECK_NOTREACHED(); + } } const std::vector& FakeVoiceEngine::send_codecs() const { return send_codecs_; @@ -535,16 +564,52 @@ VideoMediaChannel* FakeVideoEngine::CreateMediaChannel( FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(role, this, options, call->network_thread()); - channels_.emplace_back(ch); + switch (role) { + case MediaChannel::Role::kSend: + send_channels_.emplace_back(ch); + break; + case MediaChannel::Role::kReceive: + receive_channels_.emplace_back(ch); + break; + case MediaChannel::Role::kBoth: + send_channels_.push_back(ch); + receive_channels_.push_back(ch); + break; + default: + RTC_CHECK_NOTREACHED(); + } return ch; } -FakeVideoMediaChannel* FakeVideoEngine::GetChannel(size_t index) { - return (channels_.size() > index) ? channels_[index] : nullptr; +FakeVideoMediaChannel* FakeVideoEngine::GetSendChannel(size_t index) { + return (send_channels_.size() > index) ? send_channels_[index] : nullptr; +} +FakeVideoMediaChannel* FakeVideoEngine::GetReceiveChannel(size_t index) { + return (receive_channels_.size() > index) ? receive_channels_[index] + : nullptr; } void FakeVideoEngine::UnregisterChannel(VideoMediaChannel* channel) { - auto it = absl::c_find(channels_, channel); - RTC_DCHECK(it != channels_.end()); - channels_.erase(it); + switch (channel->role()) { + case MediaChannel::Role::kSend: { + auto it = absl::c_find(send_channels_, channel); + RTC_DCHECK(it != send_channels_.end()); + send_channels_.erase(it); + } break; + case MediaChannel::Role::kReceive: { + auto it = absl::c_find(receive_channels_, channel); + RTC_DCHECK(it != receive_channels_.end()); + receive_channels_.erase(it); + } break; + case MediaChannel::Role::kBoth: { + auto it = absl::c_find(send_channels_, channel); + RTC_DCHECK(it != send_channels_.end()); + send_channels_.erase(it); + it = absl::c_find(receive_channels_, channel); + RTC_DCHECK(it != receive_channels_.end()); + receive_channels_.erase(it); + } break; + default: + RTC_CHECK_NOTREACHED(); + } } std::vector FakeVideoEngine::send_codecs(bool use_rtx) const { return send_codecs_; @@ -597,11 +662,17 @@ void FakeMediaEngine::SetVideoCodecs(const std::vector& codecs) { video_->SetRecvCodecs(codecs); } -FakeVoiceMediaChannel* FakeMediaEngine::GetVoiceChannel(size_t index) { - return voice_->GetChannel(index); +FakeVoiceMediaChannel* FakeMediaEngine::GetVoiceSendChannel(size_t index) { + return voice_->GetSendChannel(index); } -FakeVideoMediaChannel* FakeMediaEngine::GetVideoChannel(size_t index) { - return video_->GetChannel(index); +FakeVideoMediaChannel* FakeMediaEngine::GetVideoSendChannel(size_t index) { + return video_->GetSendChannel(index); +} +FakeVoiceMediaChannel* FakeMediaEngine::GetVoiceReceiveChannel(size_t index) { + return voice_->GetReceiveChannel(index); +} +FakeVideoMediaChannel* FakeMediaEngine::GetVideoReceiveChannel(size_t index) { + return video_->GetReceiveChannel(index); } void FakeMediaEngine::set_fail_create_channel(bool fail) { diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index 7e62877f74..34369e7679 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -408,6 +408,10 @@ class FakeVoiceMediaChannel : public RtpHelper { std::unique_ptr sink) override; std::vector GetSources(uint32_t ssrc) const override; + bool SenderNackEnabled() const override { return false; } + bool SenderNonSenderRttEnabled() const override { return false; } + void SetReceiveNackEnabled(bool enabled) {} + void SetReceiveNonSenderRttEnabled(bool enabled) {} private: class VoiceChannelAudioSink : public AudioSource::Sink { @@ -509,6 +513,20 @@ class FakeVideoMediaChannel : public RtpHelper { void RequestRecvKeyFrame(uint32_t ssrc) override; void GenerateSendKeyFrame(uint32_t ssrc, const std::vector& rids) override; + webrtc::RtcpMode SendCodecRtcpMode() const override { + return webrtc::RtcpMode::kCompound; + } + void SetSendCodecChangedCallback( + absl::AnyInvocable callback) override {} + bool SendCodecHasLntf() const override { return false; } + bool SendCodecHasNack() const override { return false; } + absl::optional SendCodecRtxTime() const override { + return absl::nullopt; + } + void SetReceiverFeedbackParameters(bool lntf_enabled, + bool nack_enabled, + webrtc::RtcpMode rtcp_mode, + absl::optional rtx_time) override {} private: bool SetRecvCodecs(const std::vector& codecs); @@ -539,7 +557,8 @@ class FakeVoiceEngine : public VoiceEngineInterface { const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, webrtc::AudioCodecPairId codec_pair_id) override; - FakeVoiceMediaChannel* GetChannel(size_t index); + FakeVoiceMediaChannel* GetSendChannel(size_t index); + FakeVoiceMediaChannel* GetReceiveChannel(size_t index); void UnregisterChannel(VoiceMediaChannel* channel); // TODO(ossu): For proper testing, These should either individually settable @@ -560,7 +579,8 @@ class FakeVoiceEngine : public VoiceEngineInterface { std::vector header_extensions); private: - std::vector channels_; + std::vector send_channels_; + std::vector receive_channels_; std::vector recv_codecs_; std::vector send_codecs_; bool fail_create_channel_; @@ -581,7 +601,8 @@ class FakeVideoEngine : public VideoEngineInterface { const webrtc::CryptoOptions& crypto_options, webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) override; - FakeVideoMediaChannel* GetChannel(size_t index); + FakeVideoMediaChannel* GetSendChannel(size_t index); + FakeVideoMediaChannel* GetReceiveChannel(size_t index); void UnregisterChannel(VideoMediaChannel* channel); std::vector send_codecs() const override { return send_codecs(true); @@ -600,7 +621,8 @@ class FakeVideoEngine : public VideoEngineInterface { std::vector header_extensions); private: - std::vector channels_; + std::vector send_channels_; + std::vector receive_channels_; std::vector send_codecs_; std::vector recv_codecs_; bool capture_; @@ -622,8 +644,10 @@ class FakeMediaEngine : public CompositeMediaEngine { void SetAudioSendCodecs(const std::vector& codecs); void SetVideoCodecs(const std::vector& codecs); - FakeVoiceMediaChannel* GetVoiceChannel(size_t index); - FakeVideoMediaChannel* GetVideoChannel(size_t index); + FakeVoiceMediaChannel* GetVoiceSendChannel(size_t index); + FakeVideoMediaChannel* GetVideoSendChannel(size_t index); + FakeVoiceMediaChannel* GetVoiceReceiveChannel(size_t index); + FakeVideoMediaChannel* GetVideoReceiveChannel(size_t index); void set_fail_create_channel(bool fail); diff --git a/media/base/media_channel.h b/media/base/media_channel.h index 1191986a84..571d661d45 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -888,6 +888,8 @@ class VoiceMediaSendChannelInterface : public MediaSendChannelInterface { // DTMF event 0-9, *, #, A-D. virtual bool InsertDtmf(uint32_t ssrc, int event, int duration) = 0; virtual bool GetStats(VoiceMediaSendInfo* stats) = 0; + virtual bool SenderNackEnabled() const = 0; + virtual bool SenderNonSenderRttEnabled() const = 0; }; class VoiceMediaReceiveChannelInterface : public MediaReceiveChannelInterface { @@ -912,6 +914,8 @@ class VoiceMediaReceiveChannelInterface : public MediaReceiveChannelInterface { virtual void SetDefaultRawAudioSink( std::unique_ptr sink) = 0; virtual bool GetStats(VoiceMediaReceiveInfo* stats, bool reset_legacy) = 0; + virtual void SetReceiveNackEnabled(bool enabled) = 0; + virtual void SetReceiveNonSenderRttEnabled(bool enabled) = 0; }; // TODO(deadbeef): Rename to VideoSenderParameters, since they're intended to @@ -955,6 +959,11 @@ class VideoMediaSendChannelInterface : public MediaSendChannelInterface { virtual void SetVideoCodecSwitchingEnabled(bool enabled) = 0; virtual bool GetStats(VideoMediaSendInfo* stats) = 0; virtual void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) = 0; + // Information queries to support SetReceiverFeedbackParameters + virtual webrtc::RtcpMode SendCodecRtcpMode() const = 0; + virtual bool SendCodecHasLntf() const = 0; + virtual bool SendCodecHasNack() const = 0; + virtual absl::optional SendCodecRtxTime() const = 0; }; class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface { @@ -984,6 +993,10 @@ class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface { // Clear recordable encoded frame callback for `ssrc` virtual void ClearRecordableEncodedFrameCallback(uint32_t ssrc) = 0; virtual bool GetStats(VideoMediaReceiveInfo* stats) = 0; + virtual void SetReceiverFeedbackParameters(bool lntf_enabled, + bool nack_enabled, + webrtc::RtcpMode rtcp_mode, + absl::optional rtx_time) = 0; }; // Info about data received in DataMediaChannel. For use in diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h index f18670f825..1887181a62 100644 --- a/media/base/media_channel_impl.h +++ b/media/base/media_channel_impl.h @@ -77,7 +77,8 @@ class MediaChannel : public MediaSendChannelInterface, enum class Role { kSend, kReceive, - kBoth // Temporary value for non-converted test code + kBoth // Temporary value for non-converted test and downstream code + // TODO(bugs.webrtc.org/13931): Remove kBoth when usage is removed. }; explicit MediaChannel(Role role, @@ -248,6 +249,10 @@ class VideoMediaChannel : public MediaChannel, virtual bool GetSendStats(VideoMediaSendInfo* info) = 0; virtual bool GetReceiveStats(VideoMediaReceiveInfo* info) = 0; + // TODO(bugs.webrtc.org/13931): Remove when configuration is more sensible + virtual void SetSendCodecChangedCallback( + absl::AnyInvocable callback) = 0; + private: // Functions not implemented on this interface bool GetStats(VideoMediaSendInfo* info) override { @@ -423,6 +428,10 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface { bool GetStats(VoiceMediaSendInfo* info) override { return impl_->GetSendStats(info); } + bool SenderNackEnabled() const override { return impl_->SenderNackEnabled(); } + bool SenderNonSenderRttEnabled() const override { + return impl_->SenderNonSenderRttEnabled(); + } MediaChannel* ImplForTesting() override { return impl_; } private: @@ -539,6 +548,12 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface { bool GetStats(VoiceMediaReceiveInfo* info, bool reset_legacy) override { return impl_->GetReceiveStats(info, reset_legacy); } + void SetReceiveNackEnabled(bool enabled) override { + impl_->SetReceiveNackEnabled(enabled); + } + void SetReceiveNonSenderRttEnabled(bool enabled) override { + impl_->SetReceiveNonSenderRttEnabled(enabled); + } MediaChannel* ImplForTesting() override { return impl_; } private: @@ -641,6 +656,15 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface { void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override { return impl_->FillBitrateInfo(bwe_info); } + // Information queries to support SetReceiverFeedbackParameters + webrtc::RtcpMode SendCodecRtcpMode() const override { + return impl()->SendCodecRtcpMode(); + } + bool SendCodecHasLntf() const override { return impl()->SendCodecHasLntf(); } + bool SendCodecHasNack() const override { return impl()->SendCodecHasNack(); } + absl::optional SendCodecRtxTime() const override { + return impl()->SendCodecRtxTime(); + } MediaChannel* ImplForTesting() override { return impl_; } @@ -764,6 +788,13 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface { bool GetStats(VideoMediaReceiveInfo* info) override { return impl_->GetReceiveStats(info); } + void SetReceiverFeedbackParameters(bool lntf_enabled, + bool nack_enabled, + webrtc::RtcpMode rtcp_mode, + absl::optional rtx_time) override { + impl()->SetReceiverFeedbackParameters(lntf_enabled, nack_enabled, rtcp_mode, + rtx_time); + } MediaChannel* ImplForTesting() override { return impl_; } private: diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 14c4979ca7..38e0467555 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -982,23 +982,45 @@ bool WebRtcVideoChannel::ApplyChangedParams( for (auto& kv : send_streams_) { kv.second->SetSendParameters(changed_params); } - if (changed_params.send_codec || changed_params.rtcp_mode) { - // Update receive feedback parameters from new codec or RTCP mode. - RTC_LOG(LS_INFO) - << "SetFeedbackParameters on all the receive streams because the send " - "codec or RTCP mode has changed."; - for (auto& kv : receive_streams_) { - RTC_DCHECK(kv.second != nullptr); - kv.second->SetFeedbackParameters( - HasLntf(send_codec_->codec), HasNack(send_codec_->codec), - send_params_.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize - : webrtc::RtcpMode::kCompound, - send_codec_->rtx_time); + if (role() == MediaChannel::Role::kBoth) { + if (changed_params.send_codec || changed_params.rtcp_mode) { + // Update receive feedback parameters from new codec or RTCP mode. + if (send_codec_) { + RTC_LOG(LS_INFO) << "SetFeedbackParameters on all the receive streams " + "because the send " + "codec or RTCP mode has changed."; + SetReceiverFeedbackParameters( + HasLntf(send_codec_->codec), HasNack(send_codec_->codec), + send_params_.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize + : webrtc::RtcpMode::kCompound, + send_codec_->rtx_time); + } + } + } else { + if (changed_params.send_codec || changed_params.rtcp_mode) { + send_codec_changed_callback_(); } } return true; } +void WebRtcVideoChannel::SetReceiverFeedbackParameters( + bool lntf_enabled, + bool nack_enabled, + webrtc::RtcpMode rtcp_mode, + absl::optional rtx_time) { + RTC_DCHECK_RUN_ON(&thread_checker_); + + RTC_DCHECK(role() == MediaChannel::Role::kReceive || + role() == MediaChannel::Role::kBoth); + // Update receive feedback parameters from new codec or RTCP mode. + for (auto& kv : receive_streams_) { + RTC_DCHECK(kv.second != nullptr); + kv.second->SetFeedbackParameters(lntf_enabled, nack_enabled, rtcp_mode, + rtx_time); + } +} + webrtc::RtpParameters WebRtcVideoChannel::GetRtpSendParameters( uint32_t ssrc) const { RTC_DCHECK_RUN_ON(&thread_checker_); diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 495de88e1b..e6c9c28586 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "absl/types/optional.h" @@ -184,6 +185,11 @@ class WebRtcVideoChannel : public VideoMediaChannel, absl::optional GetBaseMinimumPlayoutDelayMs( uint32_t ssrc) const override; + void SetSendCodecChangedCallback( + absl::AnyInvocable callback) override { + send_codec_changed_callback_ = std::move(callback); + } + // Implemented for VideoMediaChannelTest. bool sending() const { RTC_DCHECK_RUN_ON(&thread_checker_); @@ -231,6 +237,39 @@ class WebRtcVideoChannel : public VideoMediaChannel, rtc::scoped_refptr frame_transformer) override; + // Information queries to support SetReceiverFeedbackParameters + webrtc::RtcpMode SendCodecRtcpMode() const override { + RTC_DCHECK_RUN_ON(&thread_checker_); + return send_params_.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize + : webrtc::RtcpMode::kCompound; + } + + bool SendCodecHasLntf() const override { + RTC_DCHECK_RUN_ON(&thread_checker_); + if (!send_codec_) { + return false; + } + return HasLntf(send_codec_->codec); + } + bool SendCodecHasNack() const override { + RTC_DCHECK_RUN_ON(&thread_checker_); + if (!send_codec_) { + return false; + } + return HasNack(send_codec_->codec); + } + absl::optional SendCodecRtxTime() const override { + RTC_DCHECK_RUN_ON(&thread_checker_); + if (!send_codec_) { + return absl::nullopt; + } + return send_codec_->rtx_time; + } + void SetReceiverFeedbackParameters(bool lntf_enabled, + bool nack_enabled, + webrtc::RtcpMode rtcp_mode, + absl::optional rtx_time) override; + private: class WebRtcVideoReceiveStream; @@ -663,6 +702,10 @@ class WebRtcVideoChannel : public VideoMediaChannel, // of multiple negotiated codecs allows generic encoder fallback on failures. // Presence of EncoderSelector allows switching to specific encoders. bool allow_codec_switching_ = false; + + // 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_; }; } // namespace cricket diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 7bc6a8b470..ab9a3fc7b8 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -417,7 +417,7 @@ VoiceMediaChannel* WebRtcVoiceEngine::CreateMediaChannel( webrtc::AudioCodecPairId codec_pair_id) { RTC_DCHECK_RUN_ON(call->worker_thread()); return new WebRtcVoiceMediaChannel(role, this, config, options, - crypto_options, call); + crypto_options, call, codec_pair_id); } void WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { @@ -1256,12 +1256,14 @@ WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel( const MediaConfig& config, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, - webrtc::Call* call) + webrtc::Call* call, + webrtc::AudioCodecPairId codec_pair_id) : VoiceMediaChannel(role, call->network_thread(), config.enable_dscp), worker_thread_(call->worker_thread()), engine_(engine), call_(call), audio_config_(config.audio), + codec_pair_id_(codec_pair_id), crypto_options_(crypto_options) { network_thread_checker_.Detach(); RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; @@ -1735,30 +1737,42 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( } call_->GetTransportControllerSend()->SetSdpBitrateParameters(bitrate_config); - // Check if the NACK status has changed on the - // preferred send codec, and in that case reconfigure all receive streams. - if (recv_nack_enabled_ != send_codec_spec_->nack_enabled) { - RTC_LOG(LS_INFO) << "Changing NACK status on receive streams."; - recv_nack_enabled_ = send_codec_spec_->nack_enabled; - for (auto& kv : recv_streams_) { - kv.second->SetUseNack(recv_nack_enabled_); - } - } + // In legacy kBoth mode, the MediaChannel sets the NACK status. + // In other modes, this is done externally. - // Check if the receive-side RTT status has changed on the preferred send - // codec, in that case reconfigure all receive streams. - if (enable_non_sender_rtt_ != send_codec_spec_->enable_non_sender_rtt) { - RTC_LOG(LS_INFO) << "Changing receive-side RTT status on receive streams."; - enable_non_sender_rtt_ = send_codec_spec_->enable_non_sender_rtt; - for (auto& kv : recv_streams_) { - kv.second->SetNonSenderRttMeasurement(enable_non_sender_rtt_); - } + if (role() == MediaChannel::Role::kBoth) { + SetReceiveNackEnabled(send_codec_spec_->nack_enabled); + SetReceiveNonSenderRttEnabled(send_codec_spec_->enable_non_sender_rtt); } send_codecs_ = codecs; return true; } +void WebRtcVoiceMediaChannel::SetReceiveNackEnabled(bool enabled) { + // Check if the NACK status has changed on the + // preferred send codec, and in that case reconfigure all receive streams. + if (recv_nack_enabled_ != enabled) { + RTC_LOG(LS_INFO) << "Changing NACK status on receive streams."; + recv_nack_enabled_ = enabled; + for (auto& kv : recv_streams_) { + kv.second->SetUseNack(recv_nack_enabled_); + } + } +} + +void WebRtcVoiceMediaChannel::SetReceiveNonSenderRttEnabled(bool enabled) { + // Check if the receive-side RTT status has changed on the preferred send + // codec, in that case reconfigure all receive streams. + if (enable_non_sender_rtt_ != enabled) { + RTC_LOG(LS_INFO) << "Changing receive-side RTT status on receive streams."; + enable_non_sender_rtt_ = enabled; + for (auto& kv : recv_streams_) { + kv.second->SetNonSenderRttMeasurement(enable_non_sender_rtt_); + } + } +} + void WebRtcVoiceMediaChannel::SetPlayout(bool playout) { TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::SetPlayout"); RTC_DCHECK_RUN_ON(worker_thread_); diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 5f9eb5d730..6d25397e68 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -16,6 +16,7 @@ #include #include +#include "api/audio_codecs/audio_codec_pair_id.h" #include "api/audio_codecs/audio_encoder_factory.h" #include "api/field_trials_view.h" #include "api/scoped_refptr.h" @@ -74,8 +75,7 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { const MediaConfig& config, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, - webrtc::AudioCodecPairId codec_pair_id = - webrtc::AudioCodecPairId::Create()) override; + webrtc::AudioCodecPairId codec_pair_id) override; const std::vector& send_codecs() const override; const std::vector& recv_codecs() const override; @@ -147,7 +147,8 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, const MediaConfig& config, const AudioOptions& options, const webrtc::CryptoOptions& crypto_options, - webrtc::Call* call); + webrtc::Call* call, + webrtc::AudioCodecPairId codec_pair_id); WebRtcVoiceMediaChannel() = delete; WebRtcVoiceMediaChannel(const WebRtcVoiceMediaChannel&) = delete; @@ -248,6 +249,22 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool SendRtcp(const uint8_t* data, size_t len) override; + bool SenderNackEnabled() const override { + if (!send_codec_spec_) { + return false; + } + return send_codec_spec_->nack_enabled; + } + bool SenderNonSenderRttEnabled() const override { + if (!send_codec_spec_) { + return false; + } + return send_codec_spec_->enable_non_sender_rtt; + } + + void SetReceiveNackEnabled(bool enabled) override; + void SetReceiveNonSenderRttEnabled(bool enabled) override; + private: bool SetOptions(const AudioOptions& options); bool SetRecvCodecs(const std::vector& codecs); @@ -327,8 +344,7 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, send_codec_spec_; // TODO(kwiberg): Per-SSRC codec pair IDs? - const webrtc::AudioCodecPairId codec_pair_id_ = - webrtc::AudioCodecPairId::Create(); + const webrtc::AudioCodecPairId codec_pair_id_; // Per peer connection crypto options that last for the lifetime of the peer // connection. diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index 70cc46159b..1393d0b9af 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -232,7 +232,8 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { bool SetupChannel() { channel_ = engine_->CreateMediaChannel( cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(), - cricket::AudioOptions(), webrtc::CryptoOptions()); + cricket::AudioOptions(), webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create()); send_channel_ = std::make_unique(channel_); receive_channel_ = std::make_unique(channel_); @@ -3031,7 +3032,8 @@ TEST_P(WebRtcVoiceEngineTestFake, InitRecordingOnSend) { std::unique_ptr channel( engine_->CreateMediaChannel( cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(), - cricket::AudioOptions(), webrtc::CryptoOptions())); + cricket::AudioOptions(), webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create())); channel->SetSend(true); } @@ -3047,7 +3049,8 @@ TEST_P(WebRtcVoiceEngineTestFake, SkipInitRecordingOnSend) { std::unique_ptr channel( engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(), options, - webrtc::CryptoOptions())); + webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create())); channel->SetSend(true); } @@ -3072,16 +3075,16 @@ TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) { std::unique_ptr channel1( static_cast( - engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, - &call_, cricket::MediaConfig(), - cricket::AudioOptions(), - webrtc::CryptoOptions()))); + engine_->CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, &call_, + cricket::MediaConfig(), cricket::AudioOptions(), + webrtc::CryptoOptions(), webrtc::AudioCodecPairId::Create()))); std::unique_ptr channel2( static_cast( - engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, - &call_, cricket::MediaConfig(), - cricket::AudioOptions(), - webrtc::CryptoOptions()))); + engine_->CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, &call_, + cricket::MediaConfig(), cricket::AudioOptions(), + webrtc::CryptoOptions(), webrtc::AudioCodecPairId::Create()))); // Have to add a stream to make SetSend work. cricket::StreamParams stream1; @@ -3193,7 +3196,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) { channel.reset(static_cast( engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, config, cricket::AudioOptions(), - webrtc::CryptoOptions()))); + webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create()))); channel->SetInterface(&network_interface); // Default value when DSCP is disabled should be DSCP_DEFAULT. EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp()); @@ -3203,7 +3207,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) { channel.reset(static_cast( engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, config, cricket::AudioOptions(), - webrtc::CryptoOptions()))); + webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create()))); channel->SetInterface(&network_interface); EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp()); @@ -3233,7 +3238,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) { channel.reset(static_cast( engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_, config, cricket::AudioOptions(), - webrtc::CryptoOptions()))); + webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create()))); channel->SetInterface(&network_interface); // Default value when DSCP is disabled should be DSCP_DEFAULT. EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp()); @@ -3644,7 +3650,8 @@ TEST(WebRtcVoiceEngineTest, StartupShutdown) { auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel( cricket::MediaChannel::Role::kBoth, call.get(), cricket::MediaConfig(), - cricket::AudioOptions(), webrtc::CryptoOptions()); + cricket::AudioOptions(), webrtc::CryptoOptions(), + webrtc::AudioCodecPairId::Create()); EXPECT_TRUE(channel != nullptr); delete channel; } @@ -3676,7 +3683,7 @@ TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) { cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel( cricket::MediaChannel::Role::kBoth, call.get(), cricket::MediaConfig(), cricket::AudioOptions(), - webrtc::CryptoOptions()); + webrtc::CryptoOptions(), webrtc::AudioCodecPairId::Create()); EXPECT_TRUE(channel != nullptr); delete channel; } @@ -3766,7 +3773,7 @@ TEST(WebRtcVoiceEngineTest, Has32Channels) { cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel( cricket::MediaChannel::Role::kBoth, call.get(), cricket::MediaConfig(), cricket::AudioOptions(), - webrtc::CryptoOptions()); + webrtc::CryptoOptions(), webrtc::AudioCodecPairId::Create()); if (!channel) break; channels[num_channels++] = channel; @@ -3812,7 +3819,8 @@ TEST(WebRtcVoiceEngineTest, SetRecvCodecs) { auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); cricket::WebRtcVoiceMediaChannel channel( cricket::MediaChannel::Role::kReceive, &engine, cricket::MediaConfig(), - cricket::AudioOptions(), webrtc::CryptoOptions(), call.get()); + cricket::AudioOptions(), webrtc::CryptoOptions(), call.get(), + webrtc::AudioCodecPairId::Create()); cricket::AudioRecvParameters parameters; parameters.codecs = engine.recv_codecs(); EXPECT_TRUE(channel.SetRecvParameters(parameters)); @@ -3846,7 +3854,8 @@ TEST(WebRtcVoiceEngineTest, SetRtpSendParametersMaxBitrate) { auto call = absl::WrapUnique(webrtc::Call::Create(call_config)); cricket::WebRtcVoiceMediaChannel channel( cricket::MediaChannel::Role::kSend, &engine, cricket::MediaConfig(), - cricket::AudioOptions(), webrtc::CryptoOptions(), call.get()); + cricket::AudioOptions(), webrtc::CryptoOptions(), call.get(), + webrtc::AudioCodecPairId::Create()); { cricket::AudioSendParameters params; params.codecs.push_back(cricket::AudioCodec(1, "opus", 48000, 32000, 2)); diff --git a/pc/audio_rtp_receiver_unittest.cc b/pc/audio_rtp_receiver_unittest.cc index eb77212b2a..5a3383f94c 100644 --- a/pc/audio_rtp_receiver_unittest.cc +++ b/pc/audio_rtp_receiver_unittest.cc @@ -39,7 +39,8 @@ class AudioRtpReceiverTest : public ::testing::Test { std::string(), std::vector(), false)), - media_channel_(rtc::Thread::Current()) { + media_channel_(cricket::MediaChannel::Role::kReceive, + rtc::Thread::Current()) { EXPECT_CALL(media_channel_, SetRawAudioSink(kSsrc, _)); EXPECT_CALL(media_channel_, SetBaseMinimumPlayoutDelayMs(kSsrc, _)); } @@ -101,7 +102,8 @@ TEST_F(AudioRtpReceiverTest, VolumesSetBeforeStartingAreRespected) { TEST(AudioRtpReceiver, OnChangedNotificationsAfterConstruction) { webrtc::test::RunLoop loop; auto* thread = rtc::Thread::Current(); // Points to loop's thread. - cricket::MockVoiceMediaChannel media_channel(thread); + cricket::MockVoiceMediaChannel media_channel( + cricket::MediaChannel::Role::kReceive, thread); auto receiver = rtc::make_ref_counted( thread, std::string(), std::vector(), true, &media_channel); diff --git a/pc/channel.cc b/pc/channel.cc index 6d261ece98..21b8223ca8 100644 --- a/pc/channel.cc +++ b/pc/channel.cc @@ -110,15 +110,19 @@ void RtpSendParametersFromMediaDescription( send_params->extmap_allow_mixed = desc->extmap_allow_mixed(); } -BaseChannel::BaseChannel(rtc::Thread* worker_thread, - rtc::Thread* network_thread, - rtc::Thread* signaling_thread, - std::unique_ptr media_channel, - absl::string_view mid, - bool srtp_required, - webrtc::CryptoOptions crypto_options, - UniqueRandomIdGenerator* ssrc_generator) - : worker_thread_(worker_thread), +BaseChannel::BaseChannel( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr send_media_channel_impl, + std::unique_ptr receive_media_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + UniqueRandomIdGenerator* ssrc_generator) + : media_send_channel_impl_(std::move(send_media_channel_impl)), + media_receive_channel_impl_(std::move(receive_media_channel_impl)), + worker_thread_(worker_thread), network_thread_(network_thread), signaling_thread_(signaling_thread), alive_(PendingTaskSafetyFlag::Create()), @@ -127,11 +131,37 @@ BaseChannel::BaseChannel(rtc::Thread* worker_thread, crypto_options.srtp.enable_encrypted_rtp_header_extensions ? webrtc::RtpExtension::kPreferEncryptedExtension : webrtc::RtpExtension::kDiscardEncryptedExtension), - media_channel_(std::move(media_channel)), demuxer_criteria_(mid), ssrc_generator_(ssrc_generator) { RTC_DCHECK_RUN_ON(worker_thread_); - RTC_DCHECK(media_channel_); + RTC_DCHECK(media_send_channel_impl_); + RTC_DCHECK(media_receive_channel_impl_); + RTC_DCHECK(ssrc_generator_); + RTC_DLOG(LS_INFO) << "Created channel: " << ToString(); +} + +BaseChannel::BaseChannel(rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + UniqueRandomIdGenerator* ssrc_generator) + : media_channel_impl_(std::move(media_channel_impl)), + worker_thread_(worker_thread), + network_thread_(network_thread), + signaling_thread_(signaling_thread), + alive_(PendingTaskSafetyFlag::Create()), + srtp_required_(srtp_required), + extensions_filter_( + crypto_options.srtp.enable_encrypted_rtp_header_extensions + ? webrtc::RtpExtension::kPreferEncryptedExtension + : webrtc::RtpExtension::kDiscardEncryptedExtension), + demuxer_criteria_(mid), + ssrc_generator_(ssrc_generator) { + RTC_DCHECK_RUN_ON(worker_thread_); + RTC_DCHECK(media_channel_impl_); RTC_DCHECK(ssrc_generator_); RTC_DLOG(LS_INFO) << "Created channel: " << ToString(); } @@ -148,8 +178,15 @@ BaseChannel::~BaseChannel() { } std::string BaseChannel::ToString() const { - return StringFormat("{mid: %s, media_type: %s}", mid().c_str(), - MediaTypeToString(media_channel_->media_type()).c_str()); + if (media_send_channel_impl_) { + return StringFormat( + "{mid: %s, media_type: %s}", mid().c_str(), + MediaTypeToString(media_send_channel_impl_->media_type()).c_str()); + } else { + return StringFormat( + "{mid: %s, media_type: %s}", mid().c_str(), + MediaTypeToString(media_channel_impl_->media_type()).c_str()); + } } bool BaseChannel::ConnectToRtpTransport_n() { @@ -181,7 +218,8 @@ void BaseChannel::DisconnectFromRtpTransport_n() { rtp_transport_->SignalWritableState.disconnect(this); rtp_transport_->SignalSentPacket.disconnect(this); rtp_transport_ = nullptr; - media_channel_->SetInterface(nullptr); + media_send_channel()->SetInterface(nullptr); + media_receive_channel()->SetInterface(nullptr); } bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) { @@ -206,10 +244,12 @@ bool BaseChannel::SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) { return false; } - RTC_DCHECK(!media_channel_->HasNetworkInterface()); - media_channel_->SetInterface(this); + RTC_DCHECK(!media_send_channel()->HasNetworkInterface()); + RTC_DCHECK(!media_receive_channel()->HasNetworkInterface()); + media_send_channel()->SetInterface(this); + media_receive_channel()->SetInterface(this); - media_channel_->OnReadyToSend(rtp_transport_->IsReadyToSend()); + media_send_channel()->OnReadyToSend(rtp_transport_->IsReadyToSend()); UpdateWritableState_n(); // Set the cached socket options. @@ -338,7 +378,8 @@ void BaseChannel::OnNetworkRouteChanged( // use the same transport name and MediaChannel::OnNetworkRouteChanged cannot // work correctly. Intentionally leave it broken to simplify the code and // encourage the users to stop using non-muxing RTCP. - media_channel_->OnNetworkRouteChanged(transport_name(), new_route); + media_send_channel()->OnNetworkRouteChanged(transport_name(), new_route); + media_receive_channel()->OnNetworkRouteChanged(transport_name(), new_route); } void BaseChannel::SetFirstPacketReceivedCallback( @@ -358,7 +399,7 @@ void BaseChannel::SetFirstPacketReceivedCallback( void BaseChannel::OnTransportReadyToSend(bool ready) { RTC_DCHECK_RUN_ON(network_thread()); RTC_DCHECK(network_initialized()); - media_channel_->OnReadyToSend(ready); + media_send_channel()->OnReadyToSend(ready); } bool BaseChannel::SendPacket(bool rtcp, @@ -433,7 +474,7 @@ void BaseChannel::OnRtpPacket(const webrtc::RtpPacketReceived& parsed_packet) { << ToString(); return; } - media_channel_->OnPacketReceived(parsed_packet); + media_receive_channel()->OnPacketReceived(parsed_packet); } bool BaseChannel::MaybeUpdateDemuxerAndRtpExtensions_w( @@ -483,7 +524,7 @@ bool BaseChannel::MaybeUpdateDemuxerAndRtpExtensions_w( } bool BaseChannel::RegisterRtpDemuxerSink_w() { - media_channel_->OnDemuxerCriteriaUpdatePending(); + media_receive_channel()->OnDemuxerCriteriaUpdatePending(); // Copy demuxer criteria, since they're a worker-thread variable // and we want to pass them to the network thread bool ret = network_thread_->BlockingCall( @@ -501,7 +542,7 @@ bool BaseChannel::RegisterRtpDemuxerSink_w() { return rtp_transport_->RegisterRtpDemuxerSink(demuxer_criteria, this); }); - media_channel_->OnDemuxerCriteriaUpdateComplete(); + media_receive_channel()->OnDemuxerCriteriaUpdateComplete(); return ret; } @@ -671,6 +712,18 @@ 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'", @@ -807,24 +860,47 @@ void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) { media_send_channel()->OnPacketSent(sent_packet); } -VoiceChannel::VoiceChannel(rtc::Thread* worker_thread, - rtc::Thread* network_thread, - rtc::Thread* signaling_thread, - std::unique_ptr media_channel, - absl::string_view mid, - bool srtp_required, - webrtc::CryptoOptions crypto_options, - UniqueRandomIdGenerator* ssrc_generator) +VoiceChannel::VoiceChannel( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_send_channel_impl, + std::unique_ptr media_receive_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + UniqueRandomIdGenerator* ssrc_generator) : BaseChannel(worker_thread, network_thread, signaling_thread, - std::move(media_channel), + std::move(media_send_channel_impl), + std::move(media_receive_channel_impl), mid, srtp_required, crypto_options, ssrc_generator), - send_channel_(this->media_channel()->AsVoiceChannel()), - receive_channel_(this->media_channel()->AsVoiceChannel()) {} + send_channel_(media_send_channel_impl_->AsVoiceChannel()), + receive_channel_(media_receive_channel_impl_->AsVoiceChannel()) {} + +VoiceChannel::VoiceChannel( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + UniqueRandomIdGenerator* ssrc_generator) + : BaseChannel(worker_thread, + network_thread, + signaling_thread, + std::move(media_channel_impl), + mid, + srtp_required, + crypto_options, + ssrc_generator), + send_channel_(media_channel_impl_->AsVoiceChannel()), + receive_channel_(media_channel_impl_->AsVoiceChannel()) {} VoiceChannel::~VoiceChannel() { TRACE_EVENT0("webrtc", "VoiceChannel::~VoiceChannel"); @@ -928,29 +1004,69 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, mid().c_str()); return false; } + // Update Receive channel based on Send channel's codec information. + // TODO(bugs.webrtc.org/14911): This is silly. Stop doing it. + media_receive_channel()->SetReceiveNackEnabled( + media_send_channel()->SenderNackEnabled()); + media_receive_channel()->SetReceiveNonSenderRttEnabled( + media_send_channel()->SenderNonSenderRttEnabled()); last_send_params_ = send_params; return UpdateRemoteStreams_w(content, type, error_desc); } -VideoChannel::VideoChannel(rtc::Thread* worker_thread, - rtc::Thread* network_thread, - rtc::Thread* signaling_thread, - std::unique_ptr media_channel, - absl::string_view mid, - bool srtp_required, - webrtc::CryptoOptions crypto_options, - UniqueRandomIdGenerator* ssrc_generator) +VideoChannel::VideoChannel( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_send_channel_impl, + std::unique_ptr media_receive_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + UniqueRandomIdGenerator* ssrc_generator) : BaseChannel(worker_thread, network_thread, signaling_thread, - std::move(media_channel), + std::move(media_send_channel_impl), + std::move(media_receive_channel_impl), mid, srtp_required, crypto_options, ssrc_generator), - send_channel_(this->media_channel()->AsVideoChannel()), - receive_channel_(this->media_channel()->AsVideoChannel()) {} + send_channel_(media_send_channel_impl_->AsVideoChannel()), + receive_channel_(media_receive_channel_impl_->AsVideoChannel()) { + // TODO(bugs.webrtc.org/13931): Remove when values are set + // in a more sensible fashion + media_send_channel_impl_->AsVideoChannel()->SetSendCodecChangedCallback( + [this]() { + // Adjust receive streams based on send codec. + media_receive_channel()->SetReceiverFeedbackParameters( + media_send_channel()->SendCodecHasLntf(), + media_send_channel()->SendCodecHasNack(), + media_send_channel()->SendCodecRtcpMode(), + media_send_channel()->SendCodecRtxTime()); + }); +} +VideoChannel::VideoChannel( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + UniqueRandomIdGenerator* ssrc_generator) + : BaseChannel(worker_thread, + network_thread, + signaling_thread, + std::move(media_channel_impl), + mid, + srtp_required, + crypto_options, + ssrc_generator), + send_channel_(media_channel_impl_->AsVideoChannel()), + receive_channel_(media_channel_impl_->AsVideoChannel()) {} VideoChannel::~VideoChannel() { TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel"); @@ -1100,6 +1216,12 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, mid().c_str()); return false; } + // adjust receive streams based on send codec + media_receive_channel()->SetReceiverFeedbackParameters( + media_send_channel()->SendCodecHasLntf(), + media_send_channel()->SendCodecHasNack(), + media_send_channel()->SendCodecRtcpMode(), + media_send_channel()->SendCodecRtxTime()); last_send_params_ = send_params; if (needs_recv_params_update) { diff --git a/pc/channel.h b/pc/channel.h index b3020e377c..a84a8427a3 100644 --- a/pc/channel.h +++ b/pc/channel.h @@ -82,10 +82,23 @@ class BaseChannel : public ChannelInterface, // responsibility of the user to ensure it outlives this object. // TODO(zhihuang:) Create a BaseChannel::Config struct for the parameter lists // which will make it easier to change the constructor. + + // Constructor for use when the MediaChannels are split BaseChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, rtc::Thread* signaling_thread, - std::unique_ptr media_channel, + std::unique_ptr media_send_channel_impl, + std::unique_ptr media_receive_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + rtc::UniqueRandomIdGenerator* ssrc_generator); + // Constructor for use when the MediaChannel is not split + // TODO(bugs.webrtc.org/13931): Delete when split channel project is complete. + BaseChannel(rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_channel_impl, absl::string_view mid, bool srtp_required, webrtc::CryptoOptions crypto_options, @@ -158,8 +171,6 @@ class BaseChannel : public ChannelInterface, // RtpPacketSinkInterface overrides. void OnRtpPacket(const webrtc::RtpPacketReceived& packet) override; - MediaChannel* media_channel() override { return media_channel_.get(); } - VideoMediaSendChannelInterface* video_media_send_channel() override { RTC_CHECK(false) << "Attempt to fetch video channel from non-video"; return nullptr; @@ -203,7 +214,7 @@ class BaseChannel : public ChannelInterface, } bool network_initialized() RTC_RUN_ON(network_thread()) { - return media_channel_->HasNetworkInterface(); + return media_send_channel()->HasNetworkInterface(); } bool enabled() const RTC_RUN_ON(worker_thread()) { return enabled_; } @@ -304,6 +315,17 @@ class BaseChannel : public ChannelInterface, // Return description of media channel to facilitate logging std::string ToString() const; + // MediaChannel related members that should be accessed from the worker + // thread. These are used in initializing the subclasses and deleting + // the channels when exiting; they have no accessors. + // Either the media_channel_impl_ is set, or the media_send_channel_impl_ + // and the media_receive_channel_impl_ is set. + // TODO(bugs.webrtc.org/13931): Delete when split channel project is complete. + const std::unique_ptr media_channel_impl_; + + const std::unique_ptr media_send_channel_impl_; + const std::unique_ptr media_receive_channel_impl_; + private: bool ConnectToRtpTransport_n() RTC_RUN_ON(network_thread()); void DisconnectFromRtpTransport_n() RTC_RUN_ON(network_thread()); @@ -333,9 +355,6 @@ class BaseChannel : public ChannelInterface, // based on the supplied CryptoOptions. const webrtc::RtpExtension::Filter extensions_filter_; - // MediaChannel related members that should be accessed from the worker - // thread. - const std::unique_ptr media_channel_; // Currently the `enabled_` flag is accessed from the signaling thread as // well, but it can be changed only when signaling thread does a synchronous // call to the worker thread, so it should be safe. @@ -370,11 +389,23 @@ class VoiceChannel : public BaseChannel { VoiceChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, rtc::Thread* signaling_thread, - std::unique_ptr channel, + std::unique_ptr send_channel_impl, + std::unique_ptr receive_channel_impl, absl::string_view mid, bool srtp_required, webrtc::CryptoOptions crypto_options, rtc::UniqueRandomIdGenerator* ssrc_generator); + // Constructor for use when the MediaChannel is not split + // TODO(bugs.webrtc.org/13931): Delete when split channel project is complete. + VoiceChannel(rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + rtc::UniqueRandomIdGenerator* ssrc_generator); + ~VoiceChannel(); VideoChannel* AsVideoChannel() override { @@ -431,7 +462,18 @@ class VideoChannel : public BaseChannel { VideoChannel(rtc::Thread* worker_thread, rtc::Thread* network_thread, rtc::Thread* signaling_thread, - std::unique_ptr media_channel, + std::unique_ptr media_send_channel_impl, + std::unique_ptr media_receive_channel_impl, + absl::string_view mid, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + rtc::UniqueRandomIdGenerator* ssrc_generator); + // Constructor for use when the MediaChannel is not split + // TODO(bugs.webrtc.org/13931): Delete when split channel project is complete. + VideoChannel(rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr media_channel_impl, absl::string_view mid, bool srtp_required, webrtc::CryptoOptions crypto_options, diff --git a/pc/channel_interface.h b/pc/channel_interface.h index 783755e6fe..7495ad8931 100644 --- a/pc/channel_interface.h +++ b/pc/channel_interface.h @@ -53,8 +53,6 @@ class ChannelInterface { virtual VideoChannel* AsVideoChannel() = 0; virtual VoiceChannel* AsVoiceChannel() = 0; - // Temporary fix while MediaChannel is being reconstructed - virtual MediaChannel* media_channel() = 0; virtual MediaSendChannelInterface* media_send_channel() = 0; // Typecasts of media_channel(). Will cause an exception if the // channel is of the wrong type. diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc index 1635ea5135..c6ad9e896a 100644 --- a/pc/channel_unittest.cc +++ b/pc/channel_unittest.cc @@ -151,15 +151,23 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { void CreateChannels(int flags1, int flags2) { CreateChannels(std::make_unique( - cricket::MediaChannel::Role::kBoth, nullptr, + cricket::MediaChannel::Role::kSend, nullptr, typename T::Options(), network_thread_), std::make_unique( - cricket::MediaChannel::Role::kBoth, nullptr, + cricket::MediaChannel::Role::kReceive, nullptr, + typename T::Options(), network_thread_), + std::make_unique( + cricket::MediaChannel::Role::kSend, nullptr, + typename T::Options(), network_thread_), + std::make_unique( + cricket::MediaChannel::Role::kReceive, nullptr, typename T::Options(), network_thread_), flags1, flags2); } - void CreateChannels(std::unique_ptr ch1, - std::unique_ptr ch2, + void CreateChannels(std::unique_ptr ch1s, + std::unique_ptr ch1r, + std::unique_ptr ch2s, + std::unique_ptr ch2r, int flags1, int flags2) { RTC_DCHECK(!channel1_); @@ -237,10 +245,10 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { fake_rtp_dtls_transport2_.get(), fake_rtcp_dtls_transport2_.get(), flags2); - channel1_ = CreateChannel(worker_thread, network_thread_, std::move(ch1), - rtp_transport1_.get(), flags1); - channel2_ = CreateChannel(worker_thread, network_thread_, std::move(ch2), - rtp_transport2_.get(), flags2); + channel1_ = CreateChannel(worker_thread, network_thread_, std::move(ch1s), + std::move(ch1r), rtp_transport1_.get(), flags1); + channel2_ = CreateChannel(worker_thread, network_thread_, std::move(ch2s), + std::move(ch2r), rtp_transport2_.get(), flags2); CreateContent(flags1, kPcmuCodec, kH264Codec, &local_media_content1_); CreateContent(flags2, kPcmuCodec, kH264Codec, &local_media_content2_); CopyContent(local_media_content1_, &remote_media_content1_); @@ -263,7 +271,8 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { std::unique_ptr CreateChannel( rtc::Thread* worker_thread, rtc::Thread* network_thread, - std::unique_ptr ch, + std::unique_ptr ch_send, + std::unique_ptr ch_receive, webrtc::RtpTransportInternal* rtp_transport, int flags); @@ -439,7 +448,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { } void SendRtp1(rtc::Buffer data) { - SendRtp(media_channel1(), std::move(data)); + SendRtp(media_send_channel1_impl(), std::move(data)); } void SendRtp2() { @@ -447,7 +456,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { } void SendRtp2(rtc::Buffer data) { - SendRtp(media_channel2(), std::move(data)); + SendRtp(media_send_channel2_impl(), std::move(data)); } // Methods to send custom data. @@ -459,19 +468,21 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { } bool CheckRtp1() { - return media_channel1()->CheckRtp(rtp_packet_.data(), rtp_packet_.size()); + return media_receive_channel1_impl()->CheckRtp(rtp_packet_.data(), + rtp_packet_.size()); } bool CheckRtp2() { - return media_channel2()->CheckRtp(rtp_packet_.data(), rtp_packet_.size()); + return media_receive_channel2_impl()->CheckRtp(rtp_packet_.data(), + rtp_packet_.size()); } // Methods to check custom data. bool CheckCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) { rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type); - return media_channel1()->CheckRtp(data.data(), data.size()); + return media_receive_channel1_impl()->CheckRtp(data.data(), data.size()); } bool CheckCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) { rtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type); - return media_channel2()->CheckRtp(data.data(), data.size()); + return media_receive_channel2_impl()->CheckRtp(data.data(), data.size()); } rtc::Buffer CreateRtpData(uint32_t ssrc, int sequence_number, int pl_type) { rtc::Buffer data(rtp_packet_.data(), rtp_packet_.size()); @@ -484,8 +495,8 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { return data; } - bool CheckNoRtp1() { return media_channel1()->CheckNoRtp(); } - bool CheckNoRtp2() { return media_channel2()->CheckNoRtp(); } + bool CheckNoRtp1() { return media_send_channel1_impl()->CheckNoRtp(); } + bool CheckNoRtp2() { return media_send_channel2_impl()->CheckNoRtp(); } void CreateContent(int flags, const cricket::AudioCodec& audio_codec, @@ -567,18 +578,20 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { void TestInit() { CreateChannels(0, 0); EXPECT_FALSE(IsSrtpActive(channel1_)); - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); if (verify_playout_) { - EXPECT_FALSE(media_channel1()->playout()); + EXPECT_FALSE(media_receive_channel1_impl()->playout()); } - EXPECT_TRUE(media_channel1()->codecs().empty()); - EXPECT_TRUE(media_channel1()->recv_streams().empty()); - EXPECT_TRUE(media_channel1()->rtp_packets().empty()); + EXPECT_TRUE(media_send_channel1_impl()->codecs().empty()); + EXPECT_TRUE(media_receive_channel1_impl()->recv_streams().empty()); + EXPECT_TRUE(media_send_channel1_impl()->rtp_packets().empty()); // Basic sanity test for send and receive channel objects EXPECT_EQ(channel1_->media_send_channel()->media_type(), - media_channel1()->media_type()); + media_send_channel1_impl()->media_type()); EXPECT_EQ(channel1_->media_receive_channel()->media_type(), - media_channel1()->media_type()); + media_receive_channel1_impl()->media_type()); + EXPECT_EQ(channel1_->media_send_channel()->media_type(), + channel1_->media_receive_channel()->media_type()); } // Test that SetLocalContent and SetRemoteContent properly configure @@ -589,11 +602,11 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateContent(0, kPcmuCodec, kH264Codec, &content); std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err)); - EXPECT_EQ(0U, media_channel1()->codecs().size()); + EXPECT_EQ(0U, media_send_channel1_impl()->codecs().size()); EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err)); - ASSERT_EQ(1U, media_channel1()->codecs().size()); - EXPECT_TRUE( - CodecMatches(content.codecs()[0], media_channel1()->codecs()[0])); + ASSERT_EQ(1U, media_send_channel1_impl()->codecs().size()); + EXPECT_TRUE(CodecMatches(content.codecs()[0], + media_send_channel1_impl()->codecs()[0])); } // Test that SetLocalContent and SetRemoteContent properly configure @@ -611,7 +624,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err)); content.set_extmap_allow_mixed_enum(answer_enum); EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err)); - EXPECT_EQ(answer, media_send_channel1()->ExtmapAllowMixed()); + EXPECT_EQ(answer, media_send_channel1_impl()->ExtmapAllowMixed()); } void TestSetContentsExtmapAllowMixedCallee(bool offer, bool answer) { // For a callee, SetRemoteContent() is called first with an offer and next @@ -637,11 +650,11 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err)); CreateContent(0, kPcmuCodec, kH264Codec, &content); - EXPECT_EQ(0U, media_channel1()->codecs().size()); + EXPECT_EQ(0U, media_send_channel1_impl()->codecs().size()); EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err)); - ASSERT_EQ(1U, media_channel1()->codecs().size()); - EXPECT_TRUE( - CodecMatches(content.codecs()[0], media_channel1()->codecs()[0])); + ASSERT_EQ(1U, media_send_channel1_impl()->codecs().size()); + EXPECT_TRUE(CodecMatches(content.codecs()[0], + media_send_channel1_impl()->codecs()[0])); } // Test that SetLocalContent and SetRemoteContent properly set RTCP @@ -683,20 +696,20 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err)); channel1_->Enable(true); - EXPECT_EQ(1u, media_channel1()->send_streams().size()); + EXPECT_EQ(1u, media_send_channel1_impl()->send_streams().size()); EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err)); - EXPECT_EQ(1u, media_channel2()->recv_streams().size()); + EXPECT_EQ(1u, media_receive_channel2_impl()->recv_streams().size()); ConnectFakeTransports(); // Channel 2 do not send anything. typename T::Content content2; CreateContent(0, kPcmuCodec, kH264Codec, &content2); EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err)); - EXPECT_EQ(0u, media_channel1()->recv_streams().size()); + EXPECT_EQ(0u, media_receive_channel1_impl()->recv_streams().size()); EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err)); channel2_->Enable(true); - EXPECT_EQ(0u, media_channel2()->send_streams().size()); + EXPECT_EQ(0u, media_send_channel2_impl()->send_streams().size()); SendCustomRtp1(kSsrc1, 0); WaitForThreads(); @@ -707,21 +720,21 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateContent(0, kPcmuCodec, kH264Codec, &content3); content3.AddStream(stream2); EXPECT_TRUE(channel2_->SetLocalContent(&content3, SdpType::kOffer, err)); - ASSERT_EQ(1u, media_channel2()->send_streams().size()); - EXPECT_EQ(stream2, media_channel2()->send_streams()[0]); + ASSERT_EQ(1u, media_send_channel2_impl()->send_streams().size()); + EXPECT_EQ(stream2, media_send_channel2_impl()->send_streams()[0]); EXPECT_TRUE(channel1_->SetRemoteContent(&content3, SdpType::kOffer, err)); - ASSERT_EQ(1u, media_channel1()->recv_streams().size()); - EXPECT_EQ(stream2, media_channel1()->recv_streams()[0]); + ASSERT_EQ(1u, media_receive_channel1_impl()->recv_streams().size()); + EXPECT_EQ(stream2, media_receive_channel1_impl()->recv_streams()[0]); // Channel 1 replies but stop sending stream1. typename T::Content content4; CreateContent(0, kPcmuCodec, kH264Codec, &content4); EXPECT_TRUE(channel1_->SetLocalContent(&content4, SdpType::kAnswer, err)); - EXPECT_EQ(0u, media_channel1()->send_streams().size()); + EXPECT_EQ(0u, media_send_channel1_impl()->send_streams().size()); EXPECT_TRUE(channel2_->SetRemoteContent(&content4, SdpType::kAnswer, err)); - EXPECT_EQ(0u, media_channel2()->recv_streams().size()); + EXPECT_EQ(0u, media_receive_channel2_impl()->recv_streams().size()); SendCustomRtp2(kSsrc2, 0); WaitForThreads(); @@ -732,59 +745,59 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { void TestPlayoutAndSendingStates() { CreateChannels(0, 0); if (verify_playout_) { - EXPECT_FALSE(media_channel1()->playout()); + EXPECT_FALSE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); if (verify_playout_) { - EXPECT_FALSE(media_channel2()->playout()); + EXPECT_FALSE(media_receive_channel2_impl()->playout()); } - EXPECT_FALSE(media_channel2()->sending()); + EXPECT_FALSE(media_send_channel2_impl()->sending()); channel1_->Enable(true); FlushCurrentThread(); if (verify_playout_) { - EXPECT_FALSE(media_channel1()->playout()); + EXPECT_FALSE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_, SdpType::kOffer, err)); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); EXPECT_TRUE(channel2_->SetRemoteContent(&local_media_content1_, SdpType::kOffer, err)); if (verify_playout_) { - EXPECT_FALSE(media_channel2()->playout()); + EXPECT_FALSE(media_receive_channel2_impl()->playout()); } - EXPECT_FALSE(media_channel2()->sending()); + EXPECT_FALSE(media_send_channel2_impl()->sending()); EXPECT_TRUE(channel2_->SetLocalContent(&local_media_content2_, SdpType::kAnswer, err)); if (verify_playout_) { - EXPECT_FALSE(media_channel2()->playout()); + EXPECT_FALSE(media_receive_channel2_impl()->playout()); } - EXPECT_FALSE(media_channel2()->sending()); + EXPECT_FALSE(media_send_channel2_impl()->sending()); ConnectFakeTransports(); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); if (verify_playout_) { - EXPECT_FALSE(media_channel2()->playout()); + EXPECT_FALSE(media_receive_channel2_impl()->playout()); } - EXPECT_FALSE(media_channel2()->sending()); + EXPECT_FALSE(media_send_channel2_impl()->sending()); channel2_->Enable(true); FlushCurrentThread(); if (verify_playout_) { - EXPECT_TRUE(media_channel2()->playout()); + EXPECT_TRUE(media_receive_channel2_impl()->playout()); } - EXPECT_TRUE(media_channel2()->sending()); + EXPECT_TRUE(media_send_channel2_impl()->sending()); EXPECT_TRUE(channel1_->SetRemoteContent(&local_media_content2_, SdpType::kAnswer, err)); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_TRUE(media_channel1()->sending()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); } // Test that changing the MediaContentDirection in the local and remote @@ -802,13 +815,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { channel2_->Enable(true); FlushCurrentThread(); if (verify_playout_) { - EXPECT_FALSE(media_channel1()->playout()); + EXPECT_FALSE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); if (verify_playout_) { - EXPECT_FALSE(media_channel2()->playout()); + EXPECT_FALSE(media_receive_channel2_impl()->playout()); } - EXPECT_FALSE(media_channel2()->sending()); + EXPECT_FALSE(media_send_channel2_impl()->sending()); std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err)); @@ -819,13 +832,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { ConnectFakeTransports(); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); // remote InActive + EXPECT_FALSE(media_send_channel1_impl()->sending()); // remote InActive if (verify_playout_) { - EXPECT_FALSE(media_channel2()->playout()); // local InActive + EXPECT_FALSE(media_receive_channel2_impl()->playout()); // local InActive } - EXPECT_FALSE(media_channel2()->sending()); // local InActive + EXPECT_FALSE(media_send_channel2_impl()->sending()); // local InActive // Update `content2` to be RecvOnly. content2.set_direction(RtpTransceiverDirection::kRecvOnly); @@ -834,13 +847,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { channel1_->SetRemoteContent(&content2, SdpType::kPrAnswer, err)); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_TRUE(media_channel1()->sending()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); if (verify_playout_) { - EXPECT_TRUE(media_channel2()->playout()); // local RecvOnly + EXPECT_TRUE(media_receive_channel2_impl()->playout()); // local RecvOnly } - EXPECT_FALSE(media_channel2()->sending()); // local RecvOnly + EXPECT_FALSE(media_send_channel2_impl()->sending()); // local RecvOnly // Update `content2` to be SendRecv. content2.set_direction(RtpTransceiverDirection::kSendRecv); @@ -848,13 +861,13 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err)); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_TRUE(media_channel1()->sending()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); if (verify_playout_) { - EXPECT_TRUE(media_channel2()->playout()); + EXPECT_TRUE(media_receive_channel2_impl()->playout()); } - EXPECT_TRUE(media_channel2()->sending()); + EXPECT_TRUE(media_send_channel2_impl()->sending()); } // Tests that when the transport channel signals a candidate pair change @@ -870,14 +883,15 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateChannels(DTLS, DTLS); SendInitiate(); - typename T::MediaChannel* media_channel1 = this->media_channel1(); - ASSERT_TRUE(media_channel1); + typename T::MediaChannel* media_send_channel1_impl = + this->media_send_channel1_impl(); + ASSERT_TRUE(media_send_channel1_impl); // Need to wait for the threads before calling // `set_num_network_route_changes` because the network route would be set // when creating the channel. WaitForThreads(); - media_channel1->set_num_network_route_changes(0); + media_send_channel1_impl->set_num_network_route_changes(0); SendTask(network_thread_, [this] { rtc::NetworkRoute network_route; // The transport channel becomes disconnected. @@ -885,9 +899,9 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { absl::optional(network_route)); }); WaitForThreads(); - EXPECT_EQ(1, media_channel1->num_network_route_changes()); - EXPECT_FALSE(media_channel1->last_network_route().connected); - media_channel1->set_num_network_route_changes(0); + EXPECT_EQ(1, media_send_channel1_impl->num_network_route_changes()); + EXPECT_FALSE(media_send_channel1_impl->last_network_route().connected); + media_send_channel1_impl->set_num_network_route_changes(0); SendTask(network_thread_, [this] { rtc::NetworkRoute network_route; @@ -904,16 +918,19 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { absl::optional(network_route)); }); WaitForThreads(); - EXPECT_EQ(1, media_channel1->num_network_route_changes()); - EXPECT_TRUE(media_channel1->last_network_route().connected); - EXPECT_EQ(kLocalNetId, - media_channel1->last_network_route().local.network_id()); - EXPECT_EQ(kRemoteNetId, - media_channel1->last_network_route().remote.network_id()); - EXPECT_EQ(kLastPacketId, - media_channel1->last_network_route().last_sent_packet_id); + EXPECT_EQ(1, media_send_channel1_impl->num_network_route_changes()); + EXPECT_TRUE(media_send_channel1_impl->last_network_route().connected); + EXPECT_EQ( + kLocalNetId, + media_send_channel1_impl->last_network_route().local.network_id()); + EXPECT_EQ( + kRemoteNetId, + media_send_channel1_impl->last_network_route().remote.network_id()); + EXPECT_EQ( + kLastPacketId, + media_send_channel1_impl->last_network_route().last_sent_packet_id); EXPECT_EQ(kTransportOverheadPerPacket + kSrtpOverheadPerPacket, - media_channel1->transport_overhead_per_packet()); + media_send_channel1_impl->transport_overhead_per_packet()); } // Test setting up a call. @@ -922,18 +939,18 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { EXPECT_FALSE(IsSrtpActive(channel1_)); EXPECT_TRUE(SendInitiate()); if (verify_playout_) { - EXPECT_TRUE(media_channel1()->playout()); + EXPECT_TRUE(media_receive_channel1_impl()->playout()); } - EXPECT_FALSE(media_channel1()->sending()); + EXPECT_FALSE(media_send_channel1_impl()->sending()); EXPECT_TRUE(SendAccept()); EXPECT_FALSE(IsSrtpActive(channel1_)); - EXPECT_TRUE(media_channel1()->sending()); - EXPECT_EQ(1U, media_channel1()->codecs().size()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); + EXPECT_EQ(1U, media_send_channel1_impl()->codecs().size()); if (verify_playout_) { - EXPECT_TRUE(media_channel2()->playout()); + EXPECT_TRUE(media_receive_channel2_impl()->playout()); } - EXPECT_TRUE(media_channel2()->sending()); - EXPECT_EQ(1U, media_channel2()->codecs().size()); + EXPECT_TRUE(media_send_channel2_impl()->sending()); + EXPECT_EQ(1U, media_send_channel2_impl()->codecs().size()); } // Send voice RTP data to the other side and ensure it gets there. @@ -1060,7 +1077,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { // Regain writability SendTask(network_thread_, [this] { fake_rtp_dtls_transport1_->SetWritable(true); }); - EXPECT_TRUE(media_channel1()->sending()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); SendRtp1(); SendRtp2(); WaitForThreads(); @@ -1074,7 +1091,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { bool asymmetric = true; fake_rtp_dtls_transport1_->SetDestination(nullptr, asymmetric); }); - EXPECT_TRUE(media_channel1()->sending()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); // Should fail also. SendRtp1(); @@ -1090,7 +1107,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { fake_rtp_dtls_transport1_->SetDestination(fake_rtp_dtls_transport2_.get(), asymmetric); }); - EXPECT_TRUE(media_channel1()->sending()); + EXPECT_TRUE(media_send_channel1_impl()->sending()); SendRtp1(); SendRtp2(); WaitForThreads(); @@ -1143,17 +1160,17 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { std::unique_ptr content( CreateMediaContentWithStream(1)); - media_channel1()->set_fail_set_recv_codecs(true); + media_receive_channel1_impl()->set_fail_set_recv_codecs(true); EXPECT_FALSE( channel1_->SetLocalContent(content.get(), SdpType::kOffer, err)); EXPECT_FALSE( channel1_->SetLocalContent(content.get(), SdpType::kAnswer, err)); - media_channel1()->set_fail_set_send_codecs(true); + media_send_channel1_impl()->set_fail_set_send_codecs(true); EXPECT_FALSE( channel1_->SetRemoteContent(content.get(), SdpType::kOffer, err)); - media_channel1()->set_fail_set_send_codecs(true); + media_send_channel1_impl()->set_fail_set_send_codecs(true); EXPECT_FALSE( channel1_->SetRemoteContent(content.get(), SdpType::kAnswer, err)); } @@ -1166,14 +1183,14 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateMediaContentWithStream(1)); EXPECT_TRUE( channel1_->SetLocalContent(content1.get(), SdpType::kOffer, err)); - EXPECT_TRUE(media_channel1()->HasSendStream(1)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1)); std::unique_ptr content2( CreateMediaContentWithStream(2)); EXPECT_TRUE( channel1_->SetLocalContent(content2.get(), SdpType::kOffer, err)); - EXPECT_FALSE(media_channel1()->HasSendStream(1)); - EXPECT_TRUE(media_channel1()->HasSendStream(2)); + EXPECT_FALSE(media_send_channel1_impl()->HasSendStream(1)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(2)); } void TestReceiveTwoOffers() { @@ -1184,14 +1201,14 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateMediaContentWithStream(1)); EXPECT_TRUE( channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, err)); - EXPECT_TRUE(media_channel1()->HasRecvStream(1)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1)); std::unique_ptr content2( CreateMediaContentWithStream(2)); EXPECT_TRUE( channel1_->SetRemoteContent(content2.get(), SdpType::kOffer, err)); - EXPECT_FALSE(media_channel1()->HasRecvStream(1)); - EXPECT_TRUE(media_channel1()->HasRecvStream(2)); + EXPECT_FALSE(media_receive_channel1_impl()->HasRecvStream(1)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(2)); } void TestSendPrAnswer() { @@ -1203,24 +1220,24 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateMediaContentWithStream(1)); EXPECT_TRUE( channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, err)); - EXPECT_TRUE(media_channel1()->HasRecvStream(1)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1)); // Send PR answer std::unique_ptr content2( CreateMediaContentWithStream(2)); EXPECT_TRUE( channel1_->SetLocalContent(content2.get(), SdpType::kPrAnswer, err)); - EXPECT_TRUE(media_channel1()->HasRecvStream(1)); - EXPECT_TRUE(media_channel1()->HasSendStream(2)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(2)); // Send answer std::unique_ptr content3( CreateMediaContentWithStream(3)); EXPECT_TRUE( channel1_->SetLocalContent(content3.get(), SdpType::kAnswer, err)); - EXPECT_TRUE(media_channel1()->HasRecvStream(1)); - EXPECT_FALSE(media_channel1()->HasSendStream(2)); - EXPECT_TRUE(media_channel1()->HasSendStream(3)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1)); + EXPECT_FALSE(media_send_channel1_impl()->HasSendStream(2)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(3)); } void TestReceivePrAnswer() { @@ -1232,39 +1249,39 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { CreateMediaContentWithStream(1)); EXPECT_TRUE( channel1_->SetLocalContent(content1.get(), SdpType::kOffer, err)); - EXPECT_TRUE(media_channel1()->HasSendStream(1)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1)); // Receive PR answer std::unique_ptr content2( CreateMediaContentWithStream(2)); EXPECT_TRUE( channel1_->SetRemoteContent(content2.get(), SdpType::kPrAnswer, err)); - EXPECT_TRUE(media_channel1()->HasSendStream(1)); - EXPECT_TRUE(media_channel1()->HasRecvStream(2)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(2)); // Receive answer std::unique_ptr content3( CreateMediaContentWithStream(3)); EXPECT_TRUE( channel1_->SetRemoteContent(content3.get(), SdpType::kAnswer, err)); - EXPECT_TRUE(media_channel1()->HasSendStream(1)); - EXPECT_FALSE(media_channel1()->HasRecvStream(2)); - EXPECT_TRUE(media_channel1()->HasRecvStream(3)); + EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1)); + EXPECT_FALSE(media_receive_channel1_impl()->HasRecvStream(2)); + EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(3)); } void TestOnTransportReadyToSend() { CreateChannels(0, 0); - EXPECT_FALSE(media_channel1()->ready_to_send()); + EXPECT_FALSE(media_send_channel1_impl()->ready_to_send()); network_thread_->PostTask( [this] { channel1_->OnTransportReadyToSend(true); }); WaitForThreads(); - EXPECT_TRUE(media_channel1()->ready_to_send()); + EXPECT_TRUE(media_send_channel1_impl()->ready_to_send()); network_thread_->PostTask( [this] { channel1_->OnTransportReadyToSend(false); }); WaitForThreads(); - EXPECT_FALSE(media_channel1()->ready_to_send()); + EXPECT_FALSE(media_send_channel1_impl()->ready_to_send()); } bool SetRemoteContentWithBitrateLimit(int remote_limit) { @@ -1293,7 +1310,7 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_, SdpType::kOffer, err)); - EXPECT_EQ(media_channel1()->max_bps(), -1); + EXPECT_EQ(media_send_channel1_impl()->max_bps(), -1); VerifyMaxBitrate(media_send_channel1()->GetRtpSendParameters(kSsrc1), absl::nullopt); } @@ -1411,31 +1428,49 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> { ProcessThreadQueue(rtc::Thread::Current()); } + // Accessors that return the standard VideoMedia{Send|Receive}ChannelInterface + typename T::MediaSendChannel* media_send_channel1() { + return channel1_->media_send_channel(); + } + typename T::MediaSendChannel* media_send_channel2() { + return channel2_->media_send_channel(); + } + typename T::MediaReceiveChannel* media_receive_channel1() { + return channel1_->media_receive_channel(); + } + typename T::MediaReceiveChannel* media_receive_channel2() { + return channel2_->media_receive_channel(); + } + // Accessors that return the FakeMediaChannel object. // Note that these depend on getting the object back that was // passed to the channel constructor. - typename T::MediaChannel* media_channel1() { - RTC_DCHECK(channel1_); - RTC_DCHECK(channel1_->media_channel()); - return static_cast(channel1_->media_channel()); - } - - typename T::MediaChannel* media_channel2() { - RTC_DCHECK(channel2_); - RTC_DCHECK(channel2_->media_channel()); - return static_cast(channel2_->media_channel()); - } - - typename T::MediaSendChannel* media_send_channel1() { + // T::MediaChannel is either FakeVoiceMediaChannel or FakeVideoMediaChannel. + typename T::MediaChannel* media_send_channel1_impl() { RTC_DCHECK(channel1_); RTC_DCHECK(channel1_->media_send_channel()); - return channel1_->media_send_channel(); + return static_cast( + channel1_->media_send_channel()->ImplForTesting()); } - typename T::MediaSendChannel* media_send_channel2() { + typename T::MediaChannel* media_send_channel2_impl() { RTC_DCHECK(channel2_); RTC_DCHECK(channel2_->media_send_channel()); - return channel2_->media_send_channel(); + return static_cast( + channel2_->media_send_channel()->ImplForTesting()); + } + typename T::MediaChannel* media_receive_channel1_impl() { + RTC_DCHECK(channel1_); + RTC_DCHECK(channel1_->media_receive_channel()); + return static_cast( + channel1_->media_receive_channel()->ImplForTesting()); + } + + typename T::MediaChannel* media_receive_channel2_impl() { + RTC_DCHECK(channel2_); + RTC_DCHECK(channel2_->media_receive_channel()); + return static_cast( + channel2_->media_receive_channel()->ImplForTesting()); } rtc::AutoThread main_thread_; @@ -1476,14 +1511,15 @@ template <> std::unique_ptr ChannelTest::CreateChannel( rtc::Thread* worker_thread, rtc::Thread* network_thread, - std::unique_ptr ch, + std::unique_ptr send_ch, + std::unique_ptr receive_ch, webrtc::RtpTransportInternal* rtp_transport, int flags) { rtc::Thread* signaling_thread = rtc::Thread::Current(); auto channel = std::make_unique( - worker_thread, network_thread, signaling_thread, std::move(ch), - cricket::CN_AUDIO, (flags & DTLS) != 0, webrtc::CryptoOptions(), - &ssrc_generator_); + worker_thread, network_thread, signaling_thread, std::move(send_ch), + std::move(receive_ch), cricket::CN_AUDIO, (flags & DTLS) != 0, + webrtc::CryptoOptions(), &ssrc_generator_); SendTask(network_thread, [&]() { RTC_DCHECK_RUN_ON(channel->network_thread()); channel->SetRtpTransport(rtp_transport); @@ -1562,14 +1598,15 @@ template <> std::unique_ptr ChannelTest::CreateChannel( rtc::Thread* worker_thread, rtc::Thread* network_thread, - std::unique_ptr ch, + std::unique_ptr send_ch, + std::unique_ptr receive_ch, webrtc::RtpTransportInternal* rtp_transport, int flags) { rtc::Thread* signaling_thread = rtc::Thread::Current(); auto channel = std::make_unique( - worker_thread, network_thread, signaling_thread, std::move(ch), - cricket::CN_VIDEO, (flags & DTLS) != 0, webrtc::CryptoOptions(), - &ssrc_generator_); + worker_thread, network_thread, signaling_thread, std::move(send_ch), + std::move(receive_ch), cricket::CN_VIDEO, (flags & DTLS) != 0, + webrtc::CryptoOptions(), &ssrc_generator_); SendTask(network_thread, [&]() { RTC_DCHECK_RUN_ON(channel->network_thread()); channel->SetRtpTransport(rtp_transport); @@ -1624,8 +1661,8 @@ class VideoChannelDoubleThreadTest : public ChannelTest { TEST_F(VoiceChannelSingleThreadTest, TestInit) { Base::TestInit(); - EXPECT_FALSE(media_channel1()->IsStreamMuted(0)); - EXPECT_TRUE(media_channel1()->dtmf_info_queue().empty()); + EXPECT_FALSE(media_send_channel1_impl()->IsStreamMuted(0)); + EXPECT_TRUE(media_send_channel1_impl()->dtmf_info_queue().empty()); } TEST_F(VoiceChannelSingleThreadTest, TestDeinit) { @@ -1761,8 +1798,8 @@ TEST_F(VoiceChannelSingleThreadTest, SocketOptionsMergedOnSetTransport) { // VoiceChannelDoubleThreadTest TEST_F(VoiceChannelDoubleThreadTest, TestInit) { Base::TestInit(); - EXPECT_FALSE(media_channel1()->IsStreamMuted(0)); - EXPECT_TRUE(media_channel1()->dtmf_info_queue().empty()); + EXPECT_FALSE(media_send_channel1_impl()->IsStreamMuted(0)); + EXPECT_TRUE(media_send_channel1_impl()->dtmf_info_queue().empty()); } TEST_F(VoiceChannelDoubleThreadTest, TestDeinit) { @@ -2045,14 +2082,15 @@ TEST_F(VideoChannelSingleThreadTest, TestSetLocalOfferWithPacketization) { std::string err; EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, err)); - EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty()); - ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2)); - EXPECT_TRUE( - media_channel1()->recv_codecs()[0].Matches(kVp8Codec, &field_trials_)); - EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE( - media_channel1()->recv_codecs()[1].Matches(vp9_codec, &field_trials_)); - EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization, + EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::IsEmpty()); + ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(2)); + EXPECT_TRUE(media_receive_channel1_impl()->recv_codecs()[0].Matches( + kVp8Codec, &field_trials_)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization, + absl::nullopt); + EXPECT_TRUE(media_receive_channel1_impl()->recv_codecs()[1].Matches( + vp9_codec, &field_trials_)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[1].packetization, cricket::kPacketizationParamRaw); } @@ -2068,14 +2106,15 @@ TEST_F(VideoChannelSingleThreadTest, TestSetRemoteOfferWithPacketization) { std::string err; EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kOffer, err)); EXPECT_TRUE(err.empty()); - EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty()); - ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2)); - EXPECT_TRUE( - media_channel1()->send_codecs()[0].Matches(kVp8Codec, &field_trials_)); - EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE( - media_channel1()->send_codecs()[1].Matches(vp9_codec, &field_trials_)); - EXPECT_EQ(media_channel1()->send_codecs()[1].packetization, + EXPECT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::IsEmpty()); + ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(2)); + EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[0].Matches( + kVp8Codec, &field_trials_)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization, + absl::nullopt); + EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[1].Matches( + vp9_codec, &field_trials_)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[1].packetization, cricket::kPacketizationParamRaw); } @@ -2093,21 +2132,23 @@ TEST_F(VideoChannelSingleThreadTest, TestSetAnswerWithPacketization) { EXPECT_TRUE(err.empty()); EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kAnswer, err)); EXPECT_TRUE(err.empty()); - ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(2)); - EXPECT_TRUE( - media_channel1()->recv_codecs()[0].Matches(kVp8Codec, &field_trials_)); - EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE( - media_channel1()->recv_codecs()[1].Matches(vp9_codec, &field_trials_)); - EXPECT_EQ(media_channel1()->recv_codecs()[1].packetization, + ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(2)); + EXPECT_TRUE(media_receive_channel1_impl()->recv_codecs()[0].Matches( + kVp8Codec, &field_trials_)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization, + absl::nullopt); + EXPECT_TRUE(media_receive_channel1_impl()->recv_codecs()[1].Matches( + vp9_codec, &field_trials_)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[1].packetization, cricket::kPacketizationParamRaw); - EXPECT_THAT(media_channel1()->send_codecs(), testing::SizeIs(2)); - EXPECT_TRUE( - media_channel1()->send_codecs()[0].Matches(kVp8Codec, &field_trials_)); - EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); - EXPECT_TRUE( - media_channel1()->send_codecs()[1].Matches(vp9_codec, &field_trials_)); - EXPECT_EQ(media_channel1()->send_codecs()[1].packetization, + EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(2)); + EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[0].Matches( + kVp8Codec, &field_trials_)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization, + absl::nullopt); + EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[1].Matches( + vp9_codec, &field_trials_)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[1].packetization, cricket::kPacketizationParamRaw); } @@ -2125,10 +2166,12 @@ TEST_F(VideoChannelSingleThreadTest, TestSetLocalAnswerWithoutPacketization) { std::string err; EXPECT_TRUE(channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, err)); EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err)); - ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1)); - EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt); - ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1)); - EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); + ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization, + absl::nullopt); + ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization, + absl::nullopt); } TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) { @@ -2146,10 +2189,12 @@ TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) { EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, err)); EXPECT_TRUE( channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err)); - ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1)); - EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, absl::nullopt); - ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1)); - EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); + ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization, + absl::nullopt); + ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization, + absl::nullopt); } TEST_F(VideoChannelSingleThreadTest, @@ -2171,10 +2216,10 @@ TEST_F(VideoChannelSingleThreadTest, EXPECT_FALSE( channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err)); EXPECT_FALSE(err.empty()); - ASSERT_THAT(media_channel1()->recv_codecs(), testing::SizeIs(1)); - EXPECT_EQ(media_channel1()->recv_codecs()[0].packetization, + ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1)); + EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization, cricket::kPacketizationParamRaw); - EXPECT_THAT(media_channel1()->send_codecs(), testing::IsEmpty()); + EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::IsEmpty()); } TEST_F(VideoChannelSingleThreadTest, @@ -2194,9 +2239,10 @@ TEST_F(VideoChannelSingleThreadTest, EXPECT_TRUE(err.empty()); EXPECT_FALSE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err)); EXPECT_FALSE(err.empty()); - EXPECT_THAT(media_channel1()->recv_codecs(), testing::IsEmpty()); - ASSERT_THAT(media_channel1()->send_codecs(), testing::SizeIs(1)); - EXPECT_EQ(media_channel1()->send_codecs()[0].packetization, absl::nullopt); + EXPECT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::IsEmpty()); + ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1)); + EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization, + absl::nullopt); } // VideoChannelDoubleThreadTest diff --git a/pc/legacy_stats_collector_unittest.cc b/pc/legacy_stats_collector_unittest.cc index 3033172e95..6d3fd9f462 100644 --- a/pc/legacy_stats_collector_unittest.cc +++ b/pc/legacy_stats_collector_unittest.cc @@ -952,8 +952,9 @@ TEST_P(StatsCollectorTrackTest, AudioBandwidthEstimationInfoIsReported) { VoiceMediaInfo voice_info; voice_info.senders.push_back(voice_sender_info); - auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("audio", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); AddOutgoingAudioTrack(pc.get(), stats.get()); @@ -1526,8 +1527,9 @@ TEST_P(StatsCollectorTrackTest, FilterOutNegativeInitialValues) { voice_info.senders.push_back(voice_sender_info); voice_info.receivers.push_back(voice_receiver_info); - auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("voice", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); @@ -1578,8 +1580,9 @@ TEST_P(StatsCollectorTrackTest, GetStatsFromLocalAudioTrack) { VoiceMediaInfo voice_info; voice_info.senders.push_back(voice_sender_info); - auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("audio", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); StatsReports reports; // returned values. VerifyAudioTrackStats(audio_track_.get(), stats.get(), voice_info, &reports); @@ -1605,8 +1608,9 @@ TEST_P(StatsCollectorTrackTest, GetStatsFromRemoteStream) { VoiceMediaInfo voice_info; voice_info.receivers.push_back(voice_receiver_info); - auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("audio", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); StatsReports reports; // returned values. VerifyAudioTrackStats(audio_track_.get(), stats.get(), voice_info, &reports); @@ -1626,8 +1630,9 @@ TEST_P(StatsCollectorTrackTest, GetStatsAfterRemoveAudioStream) { VoiceMediaInfo voice_info; voice_info.senders.push_back(voice_sender_info); - auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("audio", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); stats->RemoveLocalAudioTrack(audio_track_.get(), kSsrcOfTrack); @@ -1688,8 +1693,9 @@ TEST_P(StatsCollectorTrackTest, LocalAndRemoteTracksWithSameSsrc) { voice_info.receivers.push_back(voice_receiver_info); // Instruct the session to return stats containing the transport channel. - auto* voice_media_channel = pc->AddVoiceChannel("audio", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("audio", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); @@ -1744,8 +1750,9 @@ TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) { VoiceMediaInfo voice_info; voice_info.senders.push_back(voice_sender_info); - auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("voice", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); StatsReports reports; // returned values. VerifyAudioTrackStats(audio_track_.get(), stats.get(), voice_info, &reports); @@ -1771,7 +1778,8 @@ TEST_P(StatsCollectorTrackTest, TwoLocalTracksWithSameSsrc) { &new_voice_sender_info, false); VoiceMediaInfo new_voice_info; new_voice_info.senders.push_back(new_voice_sender_info); - voice_media_channel->SetStats(new_voice_info); + voice_media_channels.first->SetStats(new_voice_info); + voice_media_channels.second->SetStats(new_voice_info); reports.clear(); VerifyAudioTrackStats(new_audio_track.get(), stats.get(), new_voice_info, @@ -1809,8 +1817,9 @@ TEST_P(StatsCollectorTrackTest, TwoLocalSendersWithSameTrack) { voice_info.senders.push_back(first_sender_info); voice_info.senders.push_back(second_sender_info); - auto* voice_media_channel = pc->AddVoiceChannel("voice", "transport"); - voice_media_channel->SetStats(voice_info); + auto voice_media_channels = pc->AddVoiceChannel("voice", "transport"); + voice_media_channels.first->SetStats(voice_info); + voice_media_channels.second->SetStats(voice_info); stats->UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc index 322540fa23..56ff8ffa35 100644 --- a/pc/peer_connection_media_unittest.cc +++ b/pc/peer_connection_media_unittest.cc @@ -75,6 +75,7 @@ using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions; using ::testing::Bool; using ::testing::Combine; using ::testing::ElementsAre; +using ::testing::NotNull; using ::testing::Values; class PeerConnectionWrapperForMediaTest : public PeerConnectionWrapper { @@ -289,28 +290,36 @@ TEST_P(PeerConnectionMediaTest, AudioVideoOfferAnswerCreateSendRecvStreams) { ASSERT_TRUE( caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal())); - auto* caller_voice = caller->media_engine()->GetVoiceChannel(0); - EXPECT_THAT(GetIds(caller_voice->recv_streams()), + auto* caller_voice_send = caller->media_engine()->GetVoiceSendChannel(0); + auto* caller_voice_receive = + caller->media_engine()->GetVoiceReceiveChannel(0); + EXPECT_THAT(GetIds(caller_voice_receive->recv_streams()), ElementsAre(kCalleeAudioId)); - EXPECT_THAT(GetIds(caller_voice->send_streams()), + EXPECT_THAT(GetIds(caller_voice_send->send_streams()), ElementsAre(kCallerAudioId)); - auto* caller_video = caller->media_engine()->GetVideoChannel(0); - EXPECT_THAT(GetIds(caller_video->recv_streams()), + auto* caller_video_send = caller->media_engine()->GetVideoSendChannel(0); + auto* caller_video_receive = + caller->media_engine()->GetVideoReceiveChannel(0); + EXPECT_THAT(GetIds(caller_video_receive->recv_streams()), ElementsAre(kCalleeVideoId)); - EXPECT_THAT(GetIds(caller_video->send_streams()), + EXPECT_THAT(GetIds(caller_video_send->send_streams()), ElementsAre(kCallerVideoId)); - auto* callee_voice = callee->media_engine()->GetVoiceChannel(0); - EXPECT_THAT(GetIds(callee_voice->recv_streams()), + auto* callee_voice_send = callee->media_engine()->GetVoiceSendChannel(0); + auto* callee_voice_receive = + callee->media_engine()->GetVoiceReceiveChannel(0); + EXPECT_THAT(GetIds(callee_voice_receive->recv_streams()), ElementsAre(kCallerAudioId)); - EXPECT_THAT(GetIds(callee_voice->send_streams()), + EXPECT_THAT(GetIds(callee_voice_send->send_streams()), ElementsAre(kCalleeAudioId)); - auto* callee_video = callee->media_engine()->GetVideoChannel(0); - EXPECT_THAT(GetIds(callee_video->recv_streams()), + auto* callee_video_send = callee->media_engine()->GetVideoSendChannel(0); + auto* callee_video_receive = + callee->media_engine()->GetVideoReceiveChannel(0); + EXPECT_THAT(GetIds(callee_video_receive->recv_streams()), ElementsAre(kCallerVideoId)); - EXPECT_THAT(GetIds(callee_video->send_streams()), + EXPECT_THAT(GetIds(callee_video_send->send_streams()), ElementsAre(kCalleeVideoId)); } @@ -333,8 +342,10 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); - ASSERT_FALSE(callee->media_engine()->GetVoiceChannel(0)); - ASSERT_FALSE(callee->media_engine()->GetVideoChannel(0)); + ASSERT_FALSE(callee->media_engine()->GetVoiceSendChannel(0)); + ASSERT_FALSE(callee->media_engine()->GetVideoSendChannel(0)); + ASSERT_FALSE(callee->media_engine()->GetVoiceReceiveChannel(0)); + ASSERT_FALSE(callee->media_engine()->GetVideoReceiveChannel(0)); } // Test that removing streams from a subsequent offer causes the receive streams @@ -354,12 +365,14 @@ TEST_F(PeerConnectionMediaTestPlanB, EmptyRemoteOfferRemovesRecvStreams) { ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); - auto callee_voice = callee->media_engine()->GetVoiceChannel(0); - auto callee_video = callee->media_engine()->GetVideoChannel(0); - EXPECT_EQ(1u, callee_voice->send_streams().size()); - EXPECT_EQ(0u, callee_voice->recv_streams().size()); - EXPECT_EQ(1u, callee_video->send_streams().size()); - EXPECT_EQ(0u, callee_video->recv_streams().size()); + auto callee_voice_send = callee->media_engine()->GetVoiceSendChannel(0); + auto callee_video_send = callee->media_engine()->GetVideoSendChannel(0); + auto callee_voice_receive = callee->media_engine()->GetVoiceReceiveChannel(0); + auto callee_video_receive = callee->media_engine()->GetVideoReceiveChannel(0); + EXPECT_EQ(1u, callee_voice_send->send_streams().size()); + EXPECT_EQ(0u, callee_voice_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_video_send->send_streams().size()); + EXPECT_EQ(0u, callee_video_receive->recv_streams().size()); } // Test enabling of simulcast with Plan B semantics. @@ -431,8 +444,8 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); - EXPECT_FALSE(callee->media_engine()->GetVoiceChannel(0)); - EXPECT_FALSE(callee->media_engine()->GetVideoChannel(0)); + EXPECT_FALSE(callee->media_engine()->GetVoiceReceiveChannel(0)); + EXPECT_FALSE(callee->media_engine()->GetVideoReceiveChannel(0)); } // Test that removing streams from a subsequent answer causes the send streams @@ -452,12 +465,14 @@ TEST_F(PeerConnectionMediaTestPlanB, EmptyLocalAnswerRemovesSendStreams) { ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); - auto callee_voice = callee->media_engine()->GetVoiceChannel(0); - auto callee_video = callee->media_engine()->GetVideoChannel(0); - EXPECT_EQ(0u, callee_voice->send_streams().size()); - EXPECT_EQ(1u, callee_voice->recv_streams().size()); - EXPECT_EQ(0u, callee_video->send_streams().size()); - EXPECT_EQ(1u, callee_video->recv_streams().size()); + auto callee_voice_send = callee->media_engine()->GetVoiceSendChannel(0); + auto callee_voice_receive = callee->media_engine()->GetVoiceReceiveChannel(0); + auto callee_video_send = callee->media_engine()->GetVideoSendChannel(0); + auto callee_video_receive = callee->media_engine()->GetVideoReceiveChannel(0); + EXPECT_EQ(0u, callee_voice_send->send_streams().size()); + EXPECT_EQ(1u, callee_voice_receive->recv_streams().size()); + EXPECT_EQ(0u, callee_video_send->send_streams().size()); + EXPECT_EQ(1u, callee_video_receive->recv_streams().size()); } // Test that a new stream in a subsequent offer causes a new receive stream to @@ -474,10 +489,10 @@ TEST_P(PeerConnectionMediaTest, NewStreamInRemoteOfferAddsRecvStreams) { ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); - auto a1 = callee->media_engine()->GetVoiceChannel(0); - auto a2 = callee->media_engine()->GetVoiceChannel(1); - auto v1 = callee->media_engine()->GetVideoChannel(0); - auto v2 = callee->media_engine()->GetVideoChannel(1); + auto a1 = callee->media_engine()->GetVoiceReceiveChannel(0); + auto a2 = callee->media_engine()->GetVoiceReceiveChannel(1); + auto v1 = callee->media_engine()->GetVideoReceiveChannel(0); + auto v2 = callee->media_engine()->GetVideoReceiveChannel(1); if (IsUnifiedPlan()) { ASSERT_TRUE(a1); EXPECT_EQ(1u, a1->recv_streams().size()); @@ -520,9 +535,9 @@ TEST_P(PeerConnectionMediaTest, NewStreamInLocalAnswerAddsSendStreams) { ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get(), offer_options, answer_options)); - auto callee_voice = callee->media_engine()->GetVoiceChannel(0); + auto callee_voice = callee->media_engine()->GetVoiceSendChannel(0); ASSERT_TRUE(callee_voice); - auto callee_video = callee->media_engine()->GetVideoChannel(0); + auto callee_video = callee->media_engine()->GetVideoSendChannel(0); ASSERT_TRUE(callee_video); if (IsUnifiedPlan()) { @@ -1095,11 +1110,12 @@ TEST_P(PeerConnectionMediaTest, TestAVOfferWithAudioOnlyAnswer) { ASSERT_TRUE(caller->SetRemoteDescription( callee->CreateAnswerAndSetAsLocal(options_reject_video))); - auto caller_voice = caller->media_engine()->GetVoiceChannel(0); - ASSERT_TRUE(caller_voice); - EXPECT_EQ(0u, caller_voice->recv_streams().size()); - EXPECT_EQ(1u, caller_voice->send_streams().size()); - auto caller_video = caller->media_engine()->GetVideoChannel(0); + auto caller_voice_send = caller->media_engine()->GetVoiceSendChannel(0); + auto caller_voice_receive = caller->media_engine()->GetVoiceReceiveChannel(0); + ASSERT_TRUE(caller_voice_send && caller_voice_receive); + EXPECT_EQ(0u, caller_voice_receive->recv_streams().size()); + EXPECT_EQ(1u, caller_voice_send->send_streams().size()); + auto caller_video = caller->media_engine()->GetVideoSendChannel(0); EXPECT_FALSE(caller_video); // Callee adds its own audio/video stream and offers to receive audio/video @@ -1110,14 +1126,16 @@ TEST_P(PeerConnectionMediaTest, TestAVOfferWithAudioOnlyAnswer) { ASSERT_TRUE( caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal())); - auto callee_voice = callee->media_engine()->GetVoiceChannel(0); - ASSERT_TRUE(callee_voice); - EXPECT_EQ(1u, callee_voice->recv_streams().size()); - EXPECT_EQ(1u, callee_voice->send_streams().size()); - auto callee_video = callee->media_engine()->GetVideoChannel(0); - ASSERT_TRUE(callee_video); - EXPECT_EQ(1u, callee_video->recv_streams().size()); - EXPECT_EQ(1u, callee_video->send_streams().size()); + auto callee_voice_send = callee->media_engine()->GetVoiceSendChannel(0); + auto callee_voice_receive = callee->media_engine()->GetVoiceReceiveChannel(0); + ASSERT_TRUE(callee_voice_send && callee_voice_receive); + EXPECT_EQ(1u, callee_voice_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_voice_send->send_streams().size()); + auto callee_video_send = callee->media_engine()->GetVideoSendChannel(0); + auto callee_video_receive = callee->media_engine()->GetVideoReceiveChannel(0); + ASSERT_TRUE(callee_video_send && callee_video_receive); + EXPECT_EQ(1u, callee_video_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_video_send->send_streams().size()); // Callee removes video but keeps audio and rejects the video once again. callee->pc()->RemoveTrackOrError(callee_video_track); @@ -1125,11 +1143,12 @@ TEST_P(PeerConnectionMediaTest, TestAVOfferWithAudioOnlyAnswer) { ASSERT_TRUE( callee->SetLocalDescription(callee->CreateAnswer(options_reject_video))); - callee_voice = callee->media_engine()->GetVoiceChannel(0); - ASSERT_TRUE(callee_voice); - EXPECT_EQ(1u, callee_voice->recv_streams().size()); - EXPECT_EQ(1u, callee_voice->send_streams().size()); - callee_video = callee->media_engine()->GetVideoChannel(0); + callee_voice_send = callee->media_engine()->GetVoiceSendChannel(0); + callee_voice_receive = callee->media_engine()->GetVoiceReceiveChannel(0); + ASSERT_TRUE(callee_voice_send && callee_voice_receive); + EXPECT_EQ(1u, callee_voice_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_voice_send->send_streams().size()); + auto callee_video = callee->media_engine()->GetVideoSendChannel(0); EXPECT_FALSE(callee_video); } @@ -1165,12 +1184,13 @@ TEST_P(PeerConnectionMediaTest, TestAVOfferWithVideoOnlyAnswer) { ASSERT_TRUE(caller->SetRemoteDescription( callee->CreateAnswerAndSetAsLocal(options_reject_audio))); - auto caller_voice = caller->media_engine()->GetVoiceChannel(0); + auto caller_voice = caller->media_engine()->GetVoiceSendChannel(0); EXPECT_FALSE(caller_voice); - auto caller_video = caller->media_engine()->GetVideoChannel(0); - ASSERT_TRUE(caller_video); - EXPECT_EQ(0u, caller_video->recv_streams().size()); - EXPECT_EQ(1u, caller_video->send_streams().size()); + auto caller_video_send = caller->media_engine()->GetVideoSendChannel(0); + auto caller_video_receive = caller->media_engine()->GetVideoReceiveChannel(0); + ASSERT_TRUE(caller_video_send && caller_video_receive); + EXPECT_EQ(0u, caller_video_receive->recv_streams().size()); + EXPECT_EQ(1u, caller_video_send->send_streams().size()); // Callee adds its own audio/video stream and offers to receive audio/video // too. @@ -1180,14 +1200,16 @@ TEST_P(PeerConnectionMediaTest, TestAVOfferWithVideoOnlyAnswer) { ASSERT_TRUE(caller->SetRemoteDescription( callee->CreateAnswerAndSetAsLocal(options_no_bundle))); - auto callee_voice = callee->media_engine()->GetVoiceChannel(0); - ASSERT_TRUE(callee_voice); - EXPECT_EQ(1u, callee_voice->recv_streams().size()); - EXPECT_EQ(1u, callee_voice->send_streams().size()); - auto callee_video = callee->media_engine()->GetVideoChannel(0); - ASSERT_TRUE(callee_video); - EXPECT_EQ(1u, callee_video->recv_streams().size()); - EXPECT_EQ(1u, callee_video->send_streams().size()); + auto callee_voice_send = callee->media_engine()->GetVoiceSendChannel(0); + auto callee_voice_receive = callee->media_engine()->GetVoiceReceiveChannel(0); + ASSERT_TRUE(callee_voice_send && callee_voice_receive); + EXPECT_EQ(1u, callee_voice_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_voice_send->send_streams().size()); + auto callee_video_send = callee->media_engine()->GetVideoSendChannel(0); + auto callee_video_receive = callee->media_engine()->GetVideoReceiveChannel(0); + ASSERT_TRUE(callee_video_send && callee_video_receive); + EXPECT_EQ(1u, callee_video_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_video_send->send_streams().size()); // Callee removes audio but keeps video and rejects the audio once again. callee->pc()->RemoveTrackOrError(callee_audio_track); @@ -1195,12 +1217,13 @@ TEST_P(PeerConnectionMediaTest, TestAVOfferWithVideoOnlyAnswer) { ASSERT_TRUE( callee->SetLocalDescription(callee->CreateAnswer(options_reject_audio))); - callee_voice = callee->media_engine()->GetVoiceChannel(0); + auto callee_voice = callee->media_engine()->GetVoiceReceiveChannel(0); EXPECT_FALSE(callee_voice); - callee_video = callee->media_engine()->GetVideoChannel(0); - ASSERT_TRUE(callee_video); - EXPECT_EQ(1u, callee_video->recv_streams().size()); - EXPECT_EQ(1u, callee_video->send_streams().size()); + callee_video_send = callee->media_engine()->GetVideoSendChannel(0); + callee_video_receive = callee->media_engine()->GetVideoReceiveChannel(0); + ASSERT_TRUE(callee_video_send && callee_video_receive); + EXPECT_EQ(1u, callee_video_receive->recv_streams().size()); + EXPECT_EQ(1u, callee_video_send->send_streams().size()); } // Tests that if the underlying video encoder fails to be initialized (signaled @@ -1212,7 +1235,7 @@ TEST_P(PeerConnectionMediaTest, MediaEngineErrorPropagatedToClients) { ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal())); - auto video_channel = caller->media_engine()->GetVideoChannel(0); + auto video_channel = caller->media_engine()->GetVideoSendChannel(0); video_channel->set_fail_set_send_codecs(true); std::string error; @@ -1235,7 +1258,7 @@ TEST_P(PeerConnectionMediaTest, ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal())); - auto video_channel = caller->media_engine()->GetVideoChannel(0); + auto video_channel = caller->media_engine()->GetVideoSendChannel(0); video_channel->set_fail_set_send_codecs(true); EXPECT_FALSE( @@ -1333,7 +1356,7 @@ TEST_P(PeerConnectionMediaTest, ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer())); - auto caller_voice = caller->media_engine()->GetVoiceChannel(0); + auto caller_voice = caller->media_engine()->GetVoiceSendChannel(0); ASSERT_TRUE(caller_voice); const cricket::AudioOptions& audio_options = caller_voice->options(); EXPECT_EQ(config.combined_audio_video_bwe, @@ -2236,6 +2259,7 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, EXPECT_TRUE(video_transceiver->SetCodecPreferences(capabilities.codecs).ok()); auto reoffer = caller->CreateOffer(options); + ASSERT_THAT(reoffer, NotNull()); EXPECT_FALSE(HasPayloadTypeConflict(reoffer->description())); // Sanity check that we got the primary codec and RTX. diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc index 8c161a2ee0..dded2831b6 100644 --- a/pc/rtc_stats_collector_unittest.cc +++ b/pc/rtc_stats_collector_unittest.cc @@ -814,6 +814,11 @@ class RTCStatsCollectorTest : public ::testing::Test { EXPECT_EQ(*outbound_rtp.codec_id, graph.send_codec_id); EXPECT_EQ(*outbound_rtp.track_id, graph.sender_track_id); EXPECT_EQ(*outbound_rtp.transport_id, graph.transport_id); + EXPECT_TRUE(graph.full_report->Get(graph.inbound_rtp_id)); + // We can't use an ASSERT in a function returning non-void, so just return. + if (!graph.full_report->Get(graph.inbound_rtp_id)) { + return graph; + } const auto& inbound_rtp = graph.full_report->Get(graph.inbound_rtp_id) ->cast_to(); EXPECT_EQ(*inbound_rtp.codec_id, graph.recv_codec_id); @@ -931,6 +936,11 @@ class RTCStatsCollectorTest : public ::testing::Test { EXPECT_EQ(*outbound_rtp.codec_id, graph.send_codec_id); EXPECT_EQ(*outbound_rtp.track_id, graph.sender_track_id); EXPECT_EQ(*outbound_rtp.transport_id, graph.transport_id); + EXPECT_TRUE(graph.full_report->Get(graph.inbound_rtp_id)); + // We can't use ASSERT in a function with a return value. + if (!graph.full_report->Get(graph.inbound_rtp_id)) { + return graph; + } const auto& inbound_rtp = graph.full_report->Get(graph.inbound_rtp_id) ->cast_to(); EXPECT_EQ(*inbound_rtp.codec_id, graph.recv_codec_id); @@ -1177,9 +1187,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCodecStatsOnlyIfReferenced) { outbound_video_info.codec_payload_type = 4; video_media_info.senders.push_back(outbound_video_info); - FakeVoiceMediaChannelForStats* audio_channel = + auto audio_channels = pc_->AddVoiceChannel("AudioMid", "TransportName", voice_media_info); - FakeVideoMediaChannelForStats* video_channel = + auto video_channels = pc_->AddVideoChannel("VideoMid", "TransportName", video_media_info); rtc::scoped_refptr report = stats_->GetStatsReport(); @@ -1244,10 +1254,12 @@ TEST_F(RTCStatsCollectorTest, CollectRTCCodecStatsOnlyIfReferenced) { // being exposed, despite `send_codecs` and `receive_codecs` still being set. voice_media_info.senders.clear(); voice_media_info.receivers.clear(); - audio_channel->SetStats(voice_media_info); + audio_channels.first->SetStats(voice_media_info); + audio_channels.second->SetStats(voice_media_info); video_media_info.senders.clear(); video_media_info.receivers.clear(); - video_channel->SetStats(video_media_info); + video_channels.first->SetStats(video_media_info); + video_channels.second->SetStats(video_media_info); stats_->stats_collector()->ClearCachedStatsReport(); report = stats_->GetStatsReport(); EXPECT_FALSE(report->Get(expected_inbound_audio_codec.id())); @@ -2495,7 +2507,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) { voice_media_info.receive_codecs.insert( std::make_pair(codec_parameters.payload_type, codec_parameters)); - auto* voice_media_channel = + auto voice_media_channels = pc_->AddVoiceChannel("AudioMid", "TransportName", voice_media_info); stats_->SetupRemoteTrackAndReceiver( cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID", "RemoteStreamId", 1); @@ -2561,7 +2573,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) { expected_audio.last_packet_received_timestamp = 3000.0; voice_media_info.receivers[0].estimated_playout_ntp_timestamp_ms = 4567; expected_audio.estimated_playout_timestamp = 4567; - voice_media_channel->SetStats(voice_media_info); + voice_media_channels.first->SetStats(voice_media_info); + voice_media_channels.second->SetStats(voice_media_info); report = stats_->GetFreshStatsReport(); @@ -2673,7 +2686,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) { video_media_info.receive_codecs.insert( std::make_pair(codec_parameters.payload_type, codec_parameters)); - auto* video_media_channel = + auto video_media_channels = pc_->AddVideoChannel("VideoMid", "TransportName", video_media_info); stats_->SetupRemoteTrackAndReceiver( cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID", "RemoteStreamId", 1); @@ -2743,7 +2756,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) { expected_video.decoder_implementation = "libfoodecoder"; video_media_info.receivers[0].power_efficient_decoder = true; expected_video.power_efficient_decoder = true; - video_media_channel->SetStats(video_media_info); + video_media_channels.first->SetStats(video_media_info); + video_media_channels.second->SetStats(video_media_info); report = stats_->GetFreshStatsReport(); @@ -2932,7 +2946,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) { video_media_info.send_codecs.insert( std::make_pair(codec_parameters.payload_type, codec_parameters)); - auto* video_media_channel = + auto video_media_channels = pc_->AddVideoChannel("VideoMid", "TransportName", video_media_info); stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID", 1, true, @@ -3002,7 +3016,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) { expected_video.encoder_implementation = "libfooencoder"; video_media_info.senders[0].power_efficient_encoder = true; expected_video.power_efficient_encoder = true; - video_media_channel->SetStats(video_media_info); + video_media_channels.first->SetStats(video_media_info); + video_media_channels.second->SetStats(video_media_info); report = stats_->GetFreshStatsReport(); diff --git a/pc/rtp_sender_receiver_unittest.cc b/pc/rtp_sender_receiver_unittest.cc index 5e7c1f65d7..8be3a0ac9d 100644 --- a/pc/rtp_sender_receiver_unittest.cc +++ b/pc/rtp_sender_receiver_unittest.cc @@ -119,45 +119,60 @@ 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( - cricket::MediaChannel::Role::kBoth, &fake_call_, cricket::MediaConfig(), + cricket::MediaChannel::Role::kSend, &fake_call_, cricket::MediaConfig(), cricket::AudioOptions(), webrtc::CryptoOptions(), webrtc::AudioCodecPairId::Create()); media_engine_->video().CreateMediaChannel( - cricket::MediaChannel::Role::kBoth, &fake_call_, cricket::MediaConfig(), + cricket::MediaChannel::Role::kSend, &fake_call_, cricket::MediaConfig(), cricket::VideoOptions(), webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()); - // TODO(hta): Split into sender and receiver channels + media_engine_->voice().CreateMediaChannel( + cricket::MediaChannel::Role::kReceive, &fake_call_, + cricket::MediaConfig(), cricket::AudioOptions(), + webrtc::CryptoOptions(), webrtc::AudioCodecPairId::Create()); + media_engine_->video().CreateMediaChannel( + cricket::MediaChannel::Role::kReceive, &fake_call_, + cricket::MediaConfig(), cricket::VideoOptions(), + webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()); - voice_media_channel_ = absl::WrapUnique(media_engine_->GetVoiceChannel(0)); - video_media_channel_ = absl::WrapUnique(media_engine_->GetVideoChannel(0)); + voice_media_send_channel_ = + absl::WrapUnique(media_engine_->GetVoiceSendChannel(0)); + video_media_send_channel_ = + absl::WrapUnique(media_engine_->GetVideoSendChannel(0)); + voice_media_receive_channel_ = + absl::WrapUnique(media_engine_->GetVoiceReceiveChannel(0)); + video_media_receive_channel_ = + absl::WrapUnique(media_engine_->GetVideoReceiveChannel(0)); - RTC_CHECK(voice_media_channel()); - RTC_CHECK(video_media_channel()); + RTC_CHECK(voice_media_send_channel()); + RTC_CHECK(video_media_send_channel()); + RTC_CHECK(voice_media_receive_channel()); + RTC_CHECK(video_media_receive_channel()); // Create sender channel objects - voice_send_channel_ = - std::make_unique(voice_media_channel()); - video_send_channel_ = - std::make_unique(video_media_channel()); + voice_send_channel_ = std::make_unique( + voice_media_send_channel()); + video_send_channel_ = std::make_unique( + video_media_send_channel()); // Create streams for predefined SSRCs. Streams need to exist in order // for the senders and receievers to apply parameters to them. // Normally these would be created by SetLocalDescription and // SetRemoteDescription. - voice_media_channel_->AddSendStream( + voice_media_send_channel_->AddSendStream( cricket::StreamParams::CreateLegacy(kAudioSsrc)); - voice_media_channel_->AddRecvStream( + voice_media_receive_channel_->AddRecvStream( cricket::StreamParams::CreateLegacy(kAudioSsrc)); - voice_media_channel_->AddSendStream( + voice_media_send_channel_->AddSendStream( cricket::StreamParams::CreateLegacy(kAudioSsrc2)); - voice_media_channel_->AddRecvStream( + voice_media_receive_channel_->AddRecvStream( cricket::StreamParams::CreateLegacy(kAudioSsrc2)); - video_media_channel_->AddSendStream( + video_media_send_channel_->AddSendStream( cricket::StreamParams::CreateLegacy(kVideoSsrc)); - video_media_channel_->AddRecvStream( + video_media_receive_channel_->AddRecvStream( cricket::StreamParams::CreateLegacy(kVideoSsrc)); - video_media_channel_->AddSendStream( + video_media_send_channel_->AddSendStream( cricket::StreamParams::CreateLegacy(kVideoSsrc2)); - video_media_channel_->AddRecvStream( + video_media_receive_channel_->AddRecvStream( cricket::StreamParams::CreateLegacy(kVideoSsrc2)); } @@ -185,7 +200,7 @@ class RtpSenderReceiverTest const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1); params.codecs.push_back(kTelephoneEventCodec); - voice_media_channel()->SetSendParameters(params); + voice_media_send_channel()->SetSendParameters(params); } void AddVideoTrack() { AddVideoTrack(false); } @@ -221,7 +236,7 @@ class RtpSenderReceiverTest audio_rtp_sender_ = AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr); audio_rtp_sender_->SetMediaChannel( - voice_media_channel()->AsVoiceSendChannel()); + voice_media_send_channel()->AsVoiceSendChannel()); } void CreateVideoRtpSender(uint32_t ssrc) { @@ -240,7 +255,7 @@ class RtpSenderReceiverTest } uint32_t CreateVideoRtpSender(const cricket::StreamParams& stream_params) { - video_media_channel_->AddSendStream(stream_params); + video_media_send_channel_->AddSendStream(stream_params); uint32_t primary_ssrc = stream_params.first_ssrc(); CreateVideoRtpSender(primary_ssrc); return primary_ssrc; @@ -274,7 +289,7 @@ class RtpSenderReceiverTest EXPECT_CALL(*set_streams_observer, OnSetStreams()); video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetMediaChannel( - video_media_channel()->AsVideoSendChannel()); + video_media_send_channel()->AsVideoSendChannel()); video_rtp_sender_->SetSsrc(ssrc); VerifyVideoChannelInput(ssrc); } @@ -282,7 +297,7 @@ class RtpSenderReceiverTest video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr); video_rtp_sender_->SetMediaChannel( - video_media_channel()->AsVideoSendChannel()); + video_media_send_channel()->AsVideoSendChannel()); } void DestroyAudioRtpSender() { @@ -301,7 +316,7 @@ class RtpSenderReceiverTest rtc::Thread::Current(), kAudioTrackId, streams, /*is_unified_plan=*/true); audio_rtp_receiver_->SetMediaChannel( - voice_media_channel()->AsVoiceReceiveChannel()); + voice_media_receive_channel()->AsVoiceReceiveChannel()); audio_rtp_receiver_->SetupMediaChannel(kAudioSsrc); audio_track_ = audio_rtp_receiver_->audio_track(); VerifyVoiceChannelOutput(); @@ -312,7 +327,7 @@ class RtpSenderReceiverTest video_rtp_receiver_ = rtc::make_ref_counted( rtc::Thread::Current(), kVideoTrackId, streams); video_rtp_receiver_->SetMediaChannel( - video_media_channel()->AsVideoReceiveChannel()); + video_media_receive_channel()->AsVideoReceiveChannel()); video_rtp_receiver_->SetupMediaChannel(kVideoSsrc); video_track_ = video_rtp_receiver_->video_track(); VerifyVideoChannelOutput(); @@ -327,13 +342,13 @@ class RtpSenderReceiverTest ssrcs.push_back(kVideoSsrcSimulcast + i); cricket::StreamParams stream_params = cricket::CreateSimStreamParams("cname", ssrcs); - video_media_channel_->AddRecvStream(stream_params); + video_media_receive_channel_->AddRecvStream(stream_params); uint32_t primary_ssrc = stream_params.first_ssrc(); video_rtp_receiver_ = rtc::make_ref_counted( rtc::Thread::Current(), kVideoTrackId, streams); video_rtp_receiver_->SetMediaChannel( - video_media_channel()->AsVideoReceiveChannel()); + video_media_receive_channel()->AsVideoReceiveChannel()); video_rtp_receiver_->SetupMediaChannel(primary_ssrc); video_track_ = video_rtp_receiver_->video_track(); } @@ -360,53 +375,55 @@ class RtpSenderReceiverTest void VerifyVoiceChannelInput(uint32_t ssrc) { // Verify that the media channel has an audio source, and the stream isn't // muted. - EXPECT_TRUE(voice_media_channel()->HasSource(ssrc)); - EXPECT_FALSE(voice_media_channel()->IsStreamMuted(ssrc)); + EXPECT_TRUE(voice_media_send_channel()->HasSource(ssrc)); + EXPECT_FALSE(voice_media_send_channel()->IsStreamMuted(ssrc)); } void VerifyVideoChannelInput() { VerifyVideoChannelInput(kVideoSsrc); } void VerifyVideoChannelInput(uint32_t ssrc) { // Verify that the media channel has a video source, - EXPECT_TRUE(video_media_channel_->HasSource(ssrc)); + EXPECT_TRUE(video_media_send_channel_->HasSource(ssrc)); } void VerifyVoiceChannelNoInput() { VerifyVoiceChannelNoInput(kAudioSsrc); } void VerifyVoiceChannelNoInput(uint32_t ssrc) { // Verify that the media channel's source is reset. - EXPECT_FALSE(voice_media_channel()->HasSource(ssrc)); + EXPECT_FALSE(voice_media_receive_channel()->HasSource(ssrc)); } void VerifyVideoChannelNoInput() { VerifyVideoChannelNoInput(kVideoSsrc); } void VerifyVideoChannelNoInput(uint32_t ssrc) { // Verify that the media channel's source is reset. - EXPECT_FALSE(video_media_channel_->HasSource(ssrc)); + EXPECT_FALSE(video_media_receive_channel_->HasSource(ssrc)); } void VerifyVoiceChannelOutput() { // Verify that the volume is initialized to 1. double volume; - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(1, volume); } void VerifyVideoChannelOutput() { // Verify that the media channel has a sink. - EXPECT_TRUE(video_media_channel_->HasSink(kVideoSsrc)); + EXPECT_TRUE(video_media_receive_channel_->HasSink(kVideoSsrc)); } void VerifyVoiceChannelNoOutput() { // Verify that the volume is reset to 0. double volume; - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(0, volume); } void VerifyVideoChannelNoOutput() { // Verify that the media channel's sink is reset. - EXPECT_FALSE(video_media_channel_->HasSink(kVideoSsrc)); + EXPECT_FALSE(video_media_receive_channel_->HasSink(kVideoSsrc)); } // Verifies that the encoding layers contain the specified RIDs. @@ -483,7 +500,8 @@ class RtpSenderReceiverTest RunDisableEncodingLayersTest(all_layers, disabled_layers, video_rtp_sender_.get()); - auto channel_parameters = video_media_channel_->GetRtpSendParameters(ssrc); + auto channel_parameters = + video_media_send_channel_->GetRtpSendParameters(ssrc); ASSERT_EQ(channel_parameters.encodings.size(), all_layers.size()); for (size_t i = 0; i < all_layers.size(); ++i) { EXPECT_EQ(all_layers[i], channel_parameters.encodings[i].rid); @@ -506,11 +524,17 @@ class RtpSenderReceiverTest } protected: - cricket::FakeVideoMediaChannel* video_media_channel() { - return video_media_channel_.get(); + cricket::FakeVideoMediaChannel* video_media_send_channel() { + return video_media_send_channel_.get(); } - cricket::FakeVoiceMediaChannel* voice_media_channel() { - return voice_media_channel_.get(); + cricket::FakeVoiceMediaChannel* voice_media_send_channel() { + return voice_media_send_channel_.get(); + } + cricket::FakeVideoMediaChannel* video_media_receive_channel() { + return video_media_receive_channel_.get(); + } + cricket::FakeVoiceMediaChannel* voice_media_receive_channel() { + return voice_media_receive_channel_.get(); } test::RunLoop run_loop_; @@ -526,8 +550,10 @@ class RtpSenderReceiverTest std::unique_ptr media_engine_; rtc::UniqueRandomIdGenerator ssrc_generator_; cricket::FakeCall fake_call_; - std::unique_ptr voice_media_channel_; - std::unique_ptr video_media_channel_; + std::unique_ptr voice_media_send_channel_; + std::unique_ptr video_media_send_channel_; + std::unique_ptr voice_media_receive_channel_; + std::unique_ptr video_media_receive_channel_; std::unique_ptr voice_send_channel_; std::unique_ptr video_send_channel_; rtc::scoped_refptr audio_rtp_sender_; @@ -585,7 +611,7 @@ TEST_F(RtpSenderReceiverTest, LocalAudioSourceOptionsApplied) { auto source = LocalAudioSource::Create(&options); CreateAudioRtpSender(source); - EXPECT_EQ(true, voice_media_channel()->options().echo_cancellation); + EXPECT_EQ(true, voice_media_send_channel()->options().echo_cancellation); DestroyAudioRtpSender(); } @@ -596,10 +622,10 @@ TEST_F(RtpSenderReceiverTest, LocalAudioTrackDisable) { CreateAudioRtpSender(); audio_track_->set_enabled(false); - EXPECT_TRUE(voice_media_channel()->IsStreamMuted(kAudioSsrc)); + EXPECT_TRUE(voice_media_send_channel()->IsStreamMuted(kAudioSsrc)); audio_track_->set_enabled(true); - EXPECT_FALSE(voice_media_channel()->IsStreamMuted(kAudioSsrc)); + EXPECT_FALSE(voice_media_send_channel()->IsStreamMuted(kAudioSsrc)); DestroyAudioRtpSender(); } @@ -610,19 +636,22 @@ TEST_F(RtpSenderReceiverTest, RemoteAudioTrackDisable) { CreateAudioRtpReceiver(); double volume; - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(1, volume); // Handling of enable/disable is applied asynchronously. audio_track_->set_enabled(false); run_loop_.Flush(); - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(0, volume); audio_track_->set_enabled(true); run_loop_.Flush(); - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(1, volume); DestroyAudioRtpReceiver(); @@ -677,7 +706,8 @@ TEST_F(RtpSenderReceiverTest, RemoteAudioTrackSetVolume) { double volume; audio_track_->GetSource()->SetVolume(0.5); run_loop_.Flush(); - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(0.5, volume); // Disable the audio track, this should prevent setting the volume. @@ -685,19 +715,22 @@ TEST_F(RtpSenderReceiverTest, RemoteAudioTrackSetVolume) { RTC_DCHECK_EQ(worker_thread_, run_loop_.task_queue()); run_loop_.Flush(); audio_track_->GetSource()->SetVolume(0.8); - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(0, volume); // When the track is enabled, the previously set volume should take effect. audio_track_->set_enabled(true); run_loop_.Flush(); - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(0.8, volume); // Try changing volume one more time. audio_track_->GetSource()->SetVolume(0.9); run_loop_.Flush(); - EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume)); + EXPECT_TRUE( + voice_media_receive_channel()->GetOutputVolume(kAudioSsrc, &volume)); EXPECT_EQ(0.9, volume); DestroyAudioRtpReceiver(); @@ -706,16 +739,16 @@ TEST_F(RtpSenderReceiverTest, RemoteAudioTrackSetVolume) { TEST_F(RtpSenderReceiverTest, AudioRtpReceiverDelay) { CreateAudioRtpReceiver(); VerifyRtpReceiverDelayBehaviour( - voice_media_channel()->AsVoiceReceiveChannel(), audio_rtp_receiver_.get(), - kAudioSsrc); + voice_media_receive_channel()->AsVoiceReceiveChannel(), + audio_rtp_receiver_.get(), kAudioSsrc); DestroyAudioRtpReceiver(); } TEST_F(RtpSenderReceiverTest, VideoRtpReceiverDelay) { CreateVideoRtpReceiver(); VerifyRtpReceiverDelayBehaviour( - video_media_channel()->AsVideoReceiveChannel(), video_rtp_receiver_.get(), - kVideoSsrc); + video_media_receive_channel()->AsVideoReceiveChannel(), + video_rtp_receiver_.get(), kVideoSsrc); DestroyVideoRtpReceiver(); } @@ -953,9 +986,9 @@ TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) { std::vector ssrcs(1, 1); cricket::StreamParams stream_params = cricket::CreateSimStreamParams("cname", ssrcs); - voice_media_channel()->AddSendStream(stream_params); + voice_media_send_channel()->AddSendStream(stream_params); audio_rtp_sender_->SetMediaChannel( - voice_media_channel()->AsVoiceSendChannel()); + voice_media_send_channel()->AsVoiceSendChannel()); audio_rtp_sender_->SetSsrc(1); params = audio_rtp_sender_->GetParameters(); @@ -1070,7 +1103,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCantSetUnimplementedRtpParameters) { TEST_F(RtpSenderReceiverTest, SetAudioMaxSendBitrate) { CreateAudioRtpSender(); - EXPECT_EQ(-1, voice_media_channel()->max_bps()); + EXPECT_EQ(-1, voice_media_send_channel()->max_bps()); webrtc::RtpParameters params = audio_rtp_sender_->GetParameters(); EXPECT_EQ(1U, params.encodings.size()); EXPECT_FALSE(params.encodings[0].max_bitrate_bps); @@ -1083,12 +1116,12 @@ TEST_F(RtpSenderReceiverTest, SetAudioMaxSendBitrate) { EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); // Verify that the audio channel received the new parameters. - params = voice_media_channel()->GetRtpSendParameters(kAudioSsrc); + params = voice_media_send_channel()->GetRtpSendParameters(kAudioSsrc); EXPECT_EQ(1U, params.encodings.size()); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); // Verify that the global bitrate limit has not been changed. - EXPECT_EQ(-1, voice_media_channel()->max_bps()); + EXPECT_EQ(-1, voice_media_send_channel()->max_bps()); DestroyAudioRtpSender(); } @@ -1108,7 +1141,7 @@ TEST_F(RtpSenderReceiverTest, SetAudioBitratePriority) { EXPECT_EQ(1U, params.encodings.size()); EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority); - params = voice_media_channel()->GetRtpSendParameters(kAudioSsrc); + params = voice_media_send_channel()->GetRtpSendParameters(kAudioSsrc); EXPECT_EQ(1U, params.encodings.size()); EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority); @@ -1207,9 +1240,9 @@ TEST_F(RtpSenderReceiverTest, VideoSenderInitParametersMovedAfterNegotiation) { ssrcs.push_back(kVideoSsrcSimulcast + i); cricket::StreamParams stream_params = cricket::CreateSimStreamParams("cname", ssrcs); - video_media_channel()->AddSendStream(stream_params); + video_media_send_channel()->AddSendStream(stream_params); video_rtp_sender_->SetMediaChannel( - video_media_channel()->AsVideoSendChannel()); + video_media_send_channel()->AsVideoSendChannel()); video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast); params = video_rtp_sender_->GetParameters(); @@ -1248,9 +1281,9 @@ TEST_F(RtpSenderReceiverTest, ssrcs.push_back(kVideoSsrcSimulcast + i); cricket::StreamParams stream_params = cricket::CreateSimStreamParams("cname", ssrcs); - video_media_channel()->AddSendStream(stream_params); + video_media_send_channel()->AddSendStream(stream_params); video_rtp_sender_->SetMediaChannel( - video_media_channel()->AsVideoSendChannel()); + video_media_send_channel()->AsVideoSendChannel()); video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast); params = video_rtp_sender_->GetParameters(); @@ -1292,9 +1325,9 @@ TEST_F(RtpSenderReceiverDeathTest, ssrcs.push_back(kVideoSsrcSimulcast + i); cricket::StreamParams stream_params = cricket::StreamParams::CreateLegacy(kVideoSsrc); - video_media_channel()->AddSendStream(stream_params); + video_media_send_channel()->AddSendStream(stream_params); video_rtp_sender_->SetMediaChannel( - video_media_channel()->AsVideoSendChannel()); + video_media_send_channel()->AsVideoSendChannel()); EXPECT_DEATH(video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast), ""); } #endif @@ -1525,7 +1558,7 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCantSetReadOnlyEncodingParameters) { TEST_F(RtpSenderReceiverTest, SetVideoMinMaxSendBitrate) { CreateVideoRtpSender(); - EXPECT_EQ(-1, video_media_channel()->max_bps()); + EXPECT_EQ(-1, video_media_send_channel()->max_bps()); webrtc::RtpParameters params = video_rtp_sender_->GetParameters(); EXPECT_EQ(1U, params.encodings.size()); EXPECT_FALSE(params.encodings[0].min_bitrate_bps); @@ -1541,13 +1574,13 @@ TEST_F(RtpSenderReceiverTest, SetVideoMinMaxSendBitrate) { EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); // Verify that the video channel received the new parameters. - params = video_media_channel()->GetRtpSendParameters(kVideoSsrc); + params = video_media_send_channel()->GetRtpSendParameters(kVideoSsrc); EXPECT_EQ(1U, params.encodings.size()); EXPECT_EQ(100, params.encodings[0].min_bitrate_bps); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); // Verify that the global bitrate limit has not been changed. - EXPECT_EQ(-1, video_media_channel()->max_bps()); + EXPECT_EQ(-1, video_media_send_channel()->max_bps()); DestroyVideoRtpSender(); } @@ -1565,7 +1598,8 @@ TEST_F(RtpSenderReceiverTest, SetVideoMinMaxSendBitrateSimulcast) { EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok()); // Verify that the video channel received the new parameters. - params = video_media_channel()->GetRtpSendParameters(kVideoSsrcSimulcast); + params = + video_media_send_channel()->GetRtpSendParameters(kVideoSsrcSimulcast); EXPECT_EQ(kVideoSimulcastLayerCount, params.encodings.size()); EXPECT_EQ(100, params.encodings[0].min_bitrate_bps); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); @@ -1590,7 +1624,7 @@ TEST_F(RtpSenderReceiverTest, SetVideoBitratePriority) { EXPECT_EQ(1U, params.encodings.size()); EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority); - params = video_media_channel()->GetRtpSendParameters(kVideoSsrc); + params = video_media_send_channel()->GetRtpSendParameters(kVideoSsrc); EXPECT_EQ(1U, params.encodings.size()); EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority); @@ -1644,23 +1678,23 @@ TEST_F(RtpSenderReceiverTest, PropagatesVideoTrackContentHint) { video_track_->set_enabled(true); // `video_track_` is not screencast by default. - EXPECT_EQ(false, video_media_channel()->options().is_screencast); + EXPECT_EQ(false, video_media_send_channel()->options().is_screencast); // No content hint should be set by default. EXPECT_EQ(VideoTrackInterface::ContentHint::kNone, video_track_->content_hint()); // Setting detailed should turn a non-screencast source into screencast mode. video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed); - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); // Removing the content hint should turn the track back into non-screencast // mode. video_track_->set_content_hint(VideoTrackInterface::ContentHint::kNone); - EXPECT_EQ(false, video_media_channel()->options().is_screencast); + EXPECT_EQ(false, video_media_send_channel()->options().is_screencast); // Setting fluid should remain in non-screencast mode (its default). video_track_->set_content_hint(VideoTrackInterface::ContentHint::kFluid); - EXPECT_EQ(false, video_media_channel()->options().is_screencast); + EXPECT_EQ(false, video_media_send_channel()->options().is_screencast); // Setting text should have the same effect as Detailed video_track_->set_content_hint(VideoTrackInterface::ContentHint::kText); - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); DestroyVideoRtpSender(); } @@ -1674,22 +1708,22 @@ TEST_F(RtpSenderReceiverTest, video_track_->set_enabled(true); // `video_track_` with a screencast source should be screencast by default. - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); // No content hint should be set by default. EXPECT_EQ(VideoTrackInterface::ContentHint::kNone, video_track_->content_hint()); // Setting fluid should turn a screencast source into non-screencast mode. video_track_->set_content_hint(VideoTrackInterface::ContentHint::kFluid); - EXPECT_EQ(false, video_media_channel()->options().is_screencast); + EXPECT_EQ(false, video_media_send_channel()->options().is_screencast); // Removing the content hint should turn the track back into screencast mode. video_track_->set_content_hint(VideoTrackInterface::ContentHint::kNone); - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); // Setting detailed should still remain in screencast mode (its default). video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed); - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); // Setting text should have the same effect as Detailed video_track_->set_content_hint(VideoTrackInterface::ContentHint::kText); - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); DestroyVideoRtpSender(); } @@ -1710,21 +1744,21 @@ TEST_F(RtpSenderReceiverTest, EXPECT_CALL(*set_streams_observer, OnSetStreams()); video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetMediaChannel( - video_media_channel()->AsVideoSendChannel()); + video_media_send_channel()->AsVideoSendChannel()); video_track_->set_enabled(true); // Sender is not ready to send (no SSRC) so no option should have been set. - EXPECT_EQ(absl::nullopt, video_media_channel()->options().is_screencast); + EXPECT_EQ(absl::nullopt, video_media_send_channel()->options().is_screencast); // Verify that the content hint is accounted for when video_rtp_sender_ does // get enabled. video_rtp_sender_->SetSsrc(kVideoSsrc); - EXPECT_EQ(true, video_media_channel()->options().is_screencast); + EXPECT_EQ(true, video_media_send_channel()->options().is_screencast); // And removing the hint should go back to false (to verify that false was // default correctly). video_track_->set_content_hint(VideoTrackInterface::ContentHint::kNone); - EXPECT_EQ(false, video_media_channel()->options().is_screencast); + EXPECT_EQ(false, video_media_send_channel()->options().is_screencast); DestroyVideoRtpSender(); } @@ -1763,22 +1797,22 @@ TEST_F(RtpSenderReceiverTest, InsertDtmf) { auto dtmf_sender = audio_rtp_sender_->GetDtmfSender(); ASSERT_NE(nullptr, dtmf_sender); - EXPECT_EQ(0U, voice_media_channel()->dtmf_info_queue().size()); + EXPECT_EQ(0U, voice_media_send_channel()->dtmf_info_queue().size()); // Insert DTMF const int expected_duration = 90; dtmf_sender->InsertDtmf("012", expected_duration, 100); // Verify - ASSERT_EQ_WAIT(3U, voice_media_channel()->dtmf_info_queue().size(), + ASSERT_EQ_WAIT(3U, voice_media_send_channel()->dtmf_info_queue().size(), kDefaultTimeout); const uint32_t send_ssrc = - voice_media_channel()->send_streams()[0].first_ssrc(); - EXPECT_TRUE(CompareDtmfInfo(voice_media_channel()->dtmf_info_queue()[0], + voice_media_send_channel()->send_streams()[0].first_ssrc(); + EXPECT_TRUE(CompareDtmfInfo(voice_media_send_channel()->dtmf_info_queue()[0], send_ssrc, 0, expected_duration)); - EXPECT_TRUE(CompareDtmfInfo(voice_media_channel()->dtmf_info_queue()[1], + EXPECT_TRUE(CompareDtmfInfo(voice_media_send_channel()->dtmf_info_queue()[1], send_ssrc, 1, expected_duration)); - EXPECT_TRUE(CompareDtmfInfo(voice_media_channel()->dtmf_info_queue()[2], + EXPECT_TRUE(CompareDtmfInfo(voice_media_send_channel()->dtmf_info_queue()[2], send_ssrc, 2, expected_duration)); } diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index 9bc24be63a..a0faf6eccc 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -197,6 +197,8 @@ RTCError RtpTransceiver::CreateChannel( return RTCError(RTCErrorType::INTERNAL_ERROR, "No media engine for mid=" + std::string(mid)); } + bool use_split_media_channel = + context()->field_trials().IsEnabled("WebRTC-SplitMediaChannel"); std::unique_ptr new_channel; if (media_type() == cricket::MEDIA_TYPE_AUDIO) { // TODO(bugs.webrtc.org/11992): CreateVideoChannel internally switches to @@ -210,18 +212,44 @@ RTCError RtpTransceiver::CreateChannel( context()->worker_thread()->BlockingCall([&] { RTC_DCHECK_RUN_ON(context()->worker_thread()); - cricket::VoiceMediaChannel* media_channel = - media_engine()->voice().CreateMediaChannel( - cricket::MediaChannel::Role::kBoth, call_ptr, media_config, - audio_options, crypto_options, AudioCodecPairId::Create()); - if (!media_channel) { - return; - } + AudioCodecPairId codec_pair_id = AudioCodecPairId::Create(); - new_channel = std::make_unique( - context()->worker_thread(), context()->network_thread(), - context()->signaling_thread(), absl::WrapUnique(media_channel), mid, - srtp_required, crypto_options, context()->ssrc_generator()); + if (use_split_media_channel) { + std::unique_ptr media_send_channel = + absl::WrapUnique(media_engine()->voice().CreateMediaChannel( + cricket::MediaChannel::Role::kSend, call_ptr, media_config, + audio_options, crypto_options, codec_pair_id)); + if (!media_send_channel) { + // TODO(bugs.webrtc.org/14912): Consider CHECK or reporting failure + return; + } + std::unique_ptr media_receive_channel = + absl::WrapUnique(media_engine()->voice().CreateMediaChannel( + cricket::MediaChannel::Role::kReceive, call_ptr, media_config, + audio_options, crypto_options, codec_pair_id)); + if (!media_receive_channel) { + return; + } + + new_channel = std::make_unique( + context()->worker_thread(), context()->network_thread(), + context()->signaling_thread(), std::move(media_send_channel), + std::move(media_receive_channel), mid, srtp_required, + crypto_options, context()->ssrc_generator()); + } else { + cricket::VoiceMediaChannel* media_channel = + media_engine()->voice().CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, call_ptr, media_config, + audio_options, crypto_options, AudioCodecPairId::Create()); + if (!media_channel) { + return; + } + + new_channel = std::make_unique( + context()->worker_thread(), context()->network_thread(), + context()->signaling_thread(), absl::WrapUnique(media_channel), mid, + srtp_required, crypto_options, context()->ssrc_generator()); + } }); } else { RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, media_type()); @@ -231,18 +259,45 @@ RTCError RtpTransceiver::CreateChannel( // simply be on the worker thread and use `call_` (update upstream code). context()->worker_thread()->BlockingCall([&] { RTC_DCHECK_RUN_ON(context()->worker_thread()); - cricket::VideoMediaChannel* media_channel = - media_engine()->video().CreateMediaChannel( - cricket::MediaChannel::Role::kBoth, call_ptr, media_config, - video_options, crypto_options, video_bitrate_allocator_factory); - if (!media_channel) { - return; - } - new_channel = std::make_unique( - context()->worker_thread(), context()->network_thread(), - context()->signaling_thread(), absl::WrapUnique(media_channel), mid, - srtp_required, crypto_options, context()->ssrc_generator()); + if (use_split_media_channel) { + std::unique_ptr media_send_channel = + absl::WrapUnique(media_engine()->video().CreateMediaChannel( + cricket::MediaChannel::Role::kSend, call_ptr, media_config, + video_options, crypto_options, + video_bitrate_allocator_factory)); + if (!media_send_channel) { + return; + } + + std::unique_ptr media_receive_channel = + absl::WrapUnique(media_engine()->video().CreateMediaChannel( + cricket::MediaChannel::Role::kReceive, call_ptr, media_config, + video_options, crypto_options, + video_bitrate_allocator_factory)); + if (!media_receive_channel) { + return; + } + + new_channel = std::make_unique( + context()->worker_thread(), context()->network_thread(), + context()->signaling_thread(), std::move(media_send_channel), + std::move(media_receive_channel), mid, srtp_required, + crypto_options, context()->ssrc_generator()); + } else { + cricket::VideoMediaChannel* media_channel = + media_engine()->video().CreateMediaChannel( + cricket::MediaChannel::Role::kBoth, call_ptr, media_config, + video_options, crypto_options, video_bitrate_allocator_factory); + if (!media_channel) { + return; + } + + new_channel = std::make_unique( + context()->worker_thread(), context()->network_thread(), + context()->signaling_thread(), absl::WrapUnique(media_channel), mid, + srtp_required, crypto_options, context()->ssrc_generator()); + } }); } if (!new_channel) { diff --git a/pc/test/fake_peer_connection_for_stats.h b/pc/test/fake_peer_connection_for_stats.h index 49f9dd64ad..8d703080f5 100644 --- a/pc/test/fake_peer_connection_for_stats.h +++ b/pc/test/fake_peer_connection_for_stats.h @@ -29,8 +29,9 @@ namespace webrtc { // Fake VoiceMediaChannel where the result of GetStats can be configured. class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { public: - explicit FakeVoiceMediaChannelForStats(TaskQueueBase* network_thread) - : cricket::FakeVoiceMediaChannel(MediaChannel::Role::kBoth, + explicit FakeVoiceMediaChannelForStats(MediaChannel::Role role, + TaskQueueBase* network_thread) + : cricket::FakeVoiceMediaChannel(role, nullptr, cricket::AudioOptions(), network_thread) {} @@ -47,6 +48,7 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { // VoiceMediaChannel overrides. bool GetSendStats(cricket::VoiceMediaSendInfo* info) override { + RTC_DCHECK(role() == MediaChannel::Role::kSend); if (send_stats_) { *info = *send_stats_; return true; @@ -55,6 +57,7 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { } bool GetReceiveStats(cricket::VoiceMediaReceiveInfo* info, bool get_and_clear_legacy_stats) override { + RTC_DCHECK(role() == MediaChannel::Role::kReceive); if (receive_stats_) { *info = *receive_stats_; return true; @@ -70,24 +73,35 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel { // Fake VideoMediaChannel where the result of GetStats can be configured. class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel { public: - explicit FakeVideoMediaChannelForStats(TaskQueueBase* network_thread) - : cricket::FakeVideoMediaChannel(MediaChannel::Role::kBoth, + explicit FakeVideoMediaChannelForStats(cricket::MediaChannel::Role role, + TaskQueueBase* network_thread) + : cricket::FakeVideoMediaChannel(role, nullptr, cricket::VideoOptions(), network_thread) {} void SetStats(const cricket::VideoMediaInfo& video_info) { - send_stats_ = cricket::VideoMediaSendInfo(); - send_stats_->senders = video_info.senders; - send_stats_->aggregated_senders = video_info.aggregated_senders; - send_stats_->send_codecs = video_info.send_codecs; - receive_stats_ = cricket::VideoMediaReceiveInfo(); - receive_stats_->receivers = video_info.receivers; - receive_stats_->receive_codecs = video_info.receive_codecs; + switch (role()) { + case MediaChannel::Role::kSend: + send_stats_ = cricket::VideoMediaSendInfo(); + send_stats_->senders = video_info.senders; + send_stats_->aggregated_senders = video_info.aggregated_senders; + send_stats_->send_codecs = video_info.send_codecs; + break; + case MediaChannel::Role::kReceive: + receive_stats_ = cricket::VideoMediaReceiveInfo(); + receive_stats_->receivers = video_info.receivers; + receive_stats_->receive_codecs = video_info.receive_codecs; + break; + default: + RTC_CHECK_NOTREACHED(); + } } // VideoMediaChannel overrides. bool GetSendStats(cricket::VideoMediaSendInfo* info) override { + RTC_DCHECK(role() == MediaChannel::Role::kSend); + if (send_stats_) { *info = *send_stats_; return true; @@ -95,6 +109,7 @@ class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel { return false; } bool GetReceiveStats(cricket::VideoMediaReceiveInfo* info) override { + RTC_DCHECK(role() == MediaChannel::Role::kReceive); if (receive_stats_) { *info = *receive_stats_; return true; @@ -112,19 +127,22 @@ constexpr bool kDefaultSrtpRequired = true; class VoiceChannelForTesting : public cricket::VoiceChannel { public: - VoiceChannelForTesting(rtc::Thread* worker_thread, - rtc::Thread* network_thread, - rtc::Thread* signaling_thread, - std::unique_ptr channel, - const std::string& content_name, - bool srtp_required, - webrtc::CryptoOptions crypto_options, - rtc::UniqueRandomIdGenerator* ssrc_generator, - std::string transport_name) + VoiceChannelForTesting( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr send_channel, + std::unique_ptr receive_channel, + const std::string& content_name, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + rtc::UniqueRandomIdGenerator* ssrc_generator, + std::string transport_name) : VoiceChannel(worker_thread, network_thread, signaling_thread, - std::move(channel), + std::move(send_channel), + std::move(receive_channel), content_name, srtp_required, std::move(crypto_options), @@ -141,19 +159,22 @@ class VoiceChannelForTesting : public cricket::VoiceChannel { class VideoChannelForTesting : public cricket::VideoChannel { public: - VideoChannelForTesting(rtc::Thread* worker_thread, - rtc::Thread* network_thread, - rtc::Thread* signaling_thread, - std::unique_ptr channel, - const std::string& content_name, - bool srtp_required, - webrtc::CryptoOptions crypto_options, - rtc::UniqueRandomIdGenerator* ssrc_generator, - std::string transport_name) + VideoChannelForTesting( + rtc::Thread* worker_thread, + rtc::Thread* network_thread, + rtc::Thread* signaling_thread, + std::unique_ptr send_channel, + std::unique_ptr receive_channel, + const std::string& content_name, + bool srtp_required, + webrtc::CryptoOptions crypto_options, + rtc::UniqueRandomIdGenerator* ssrc_generator, + std::string transport_name) : VideoChannel(worker_thread, network_thread, signaling_thread, - std::move(channel), + std::move(send_channel), + std::move(receive_channel), content_name, srtp_required, std::move(crypto_options), @@ -244,16 +265,23 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase { ->RemoveReceiver(receiver.get()); } - FakeVoiceMediaChannelForStats* AddVoiceChannel( + std::pair + AddVoiceChannel( const std::string& mid, const std::string& transport_name, cricket::VoiceMediaInfo initial_stats = cricket::VoiceMediaInfo()) { - auto voice_media_channel = - std::make_unique(network_thread_); - auto* voice_media_channel_ptr = voice_media_channel.get(); + auto voice_media_send_channel = + std::make_unique( + cricket::MediaChannel::Role::kSend, network_thread_); + auto voice_media_receive_channel = + std::make_unique( + cricket::MediaChannel::Role::kReceive, network_thread_); + auto* voice_media_send_channel_ptr = voice_media_send_channel.get(); + auto* voice_media_receive_channel_ptr = voice_media_receive_channel.get(); auto voice_channel = std::make_unique( worker_thread_, network_thread_, signaling_thread_, - std::move(voice_media_channel), mid, kDefaultSrtpRequired, + std::move(voice_media_send_channel), + std::move(voice_media_receive_channel), mid, kDefaultSrtpRequired, webrtc::CryptoOptions(), context_->ssrc_generator(), transport_name); auto transceiver = GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO) @@ -266,20 +294,29 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase { RTC_DCHECK(!transceiver->channel()); transceiver->SetChannel(std::move(voice_channel), [](const std::string&) { return nullptr; }); - voice_media_channel_ptr->SetStats(initial_stats); - return voice_media_channel_ptr; + voice_media_send_channel_ptr->SetStats(initial_stats); + voice_media_receive_channel_ptr->SetStats(initial_stats); + return std::make_pair(voice_media_send_channel_ptr, + voice_media_receive_channel_ptr); } - FakeVideoMediaChannelForStats* AddVideoChannel( + std::pair + AddVideoChannel( const std::string& mid, const std::string& transport_name, cricket::VideoMediaInfo initial_stats = cricket::VideoMediaInfo()) { - auto video_media_channel = - std::make_unique(network_thread_); - auto video_media_channel_ptr = video_media_channel.get(); + auto video_media_send_channel = + std::make_unique( + cricket::MediaChannel::Role::kSend, network_thread_); + auto video_media_receive_channel = + std::make_unique( + cricket::MediaChannel::Role::kReceive, network_thread_); + auto video_media_send_channel_ptr = video_media_send_channel.get(); + auto video_media_receive_channel_ptr = video_media_receive_channel.get(); auto video_channel = std::make_unique( worker_thread_, network_thread_, signaling_thread_, - std::move(video_media_channel), mid, kDefaultSrtpRequired, + std::move(video_media_send_channel), + std::move(video_media_receive_channel), mid, kDefaultSrtpRequired, webrtc::CryptoOptions(), context_->ssrc_generator(), transport_name); auto transceiver = GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO) @@ -292,8 +329,10 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase { RTC_DCHECK(!transceiver->channel()); transceiver->SetChannel(std::move(video_channel), [](const std::string&) { return nullptr; }); - video_media_channel_ptr->SetStats(initial_stats); - return video_media_channel_ptr; + video_media_send_channel_ptr->SetStats(initial_stats); + video_media_receive_channel_ptr->SetStats(initial_stats); + return std::make_pair(video_media_send_channel_ptr, + video_media_receive_channel_ptr); } void AddSctpDataChannel(const std::string& label) { diff --git a/pc/test/mock_channel_interface.h b/pc/test/mock_channel_interface.h index 41c142d5ba..3d82beb287 100644 --- a/pc/test/mock_channel_interface.h +++ b/pc/test/mock_channel_interface.h @@ -27,7 +27,6 @@ class MockChannelInterface : public cricket::ChannelInterface { MOCK_METHOD(cricket::MediaType, media_type, (), (const, override)); MOCK_METHOD(VideoChannel*, AsVideoChannel, (), (override)); MOCK_METHOD(VoiceChannel*, AsVoiceChannel, (), (override)); - MOCK_METHOD(MediaChannel*, media_channel, (), (override)); MOCK_METHOD(MediaChannel*, media_send_channel, (), (override)); MOCK_METHOD(VoiceMediaChannel*, voice_media_send_channel, (), (override)); MOCK_METHOD(VideoMediaChannel*, video_media_send_channel, (), (override)); diff --git a/pc/test/mock_voice_media_channel.h b/pc/test/mock_voice_media_channel.h index 71f7a18860..feab3c03f4 100644 --- a/pc/test/mock_voice_media_channel.h +++ b/pc/test/mock_voice_media_channel.h @@ -28,8 +28,9 @@ using ::testing::Mock; namespace cricket { class MockVoiceMediaChannel : public VoiceMediaChannel { public: - explicit MockVoiceMediaChannel(webrtc::TaskQueueBase* network_thread) - : VoiceMediaChannel(MediaChannel::Role::kBoth, network_thread) {} + MockVoiceMediaChannel(MediaChannel::Role role, + webrtc::TaskQueueBase* network_thread) + : VoiceMediaChannel(role, network_thread) {} MOCK_METHOD(void, SetInterface, @@ -161,6 +162,10 @@ class MockVoiceMediaChannel : public VoiceMediaChannel { GetBaseMinimumPlayoutDelayMs, (uint32_t ssrc), (const, override)); + MOCK_METHOD(bool, SenderNackEnabled, (), (const, override)); + MOCK_METHOD(bool, SenderNonSenderRttEnabled, (), (const, override)); + MOCK_METHOD(void, SetReceiveNackEnabled, (bool enabled), (override)); + MOCK_METHOD(void, SetReceiveNonSenderRttEnabled, (bool enabled), (override)); }; } // namespace cricket