From b222f495a95b18f4bbf8765dd3376107955afbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Wed, 3 Oct 2018 16:50:08 +0200 Subject: [PATCH] Split ChannelProxy into send and receive classes. Bug: webrtc:9801 Change-Id: I21573ccc34f6da515d11b58fa6008807395d5dd1 Reviewed-on: https://webrtc-review.googlesource.com/c/103120 Commit-Queue: Niels Moller Reviewed-by: Fredrik Solenberg Cr-Commit-Position: refs/heads/master@{#24965} --- audio/BUILD.gn | 6 +- audio/audio_receive_stream.cc | 18 +- audio/audio_receive_stream.h | 6 +- audio/audio_receive_stream_unittest.cc | 10 +- audio/audio_send_stream.cc | 18 +- audio/audio_send_stream.h | 8 +- audio/audio_send_stream_unittest.cc | 8 +- audio/channel_proxy.cc | 331 ------------------ audio/channel_receive_proxy.cc | 201 +++++++++++ ...hannel_proxy.h => channel_receive_proxy.h} | 70 +--- audio/channel_send_proxy.cc | 201 +++++++++++ audio/channel_send_proxy.h | 107 ++++++ audio/mock_voe_channel_proxy.h | 68 ++-- 13 files changed, 606 insertions(+), 446 deletions(-) delete mode 100644 audio/channel_proxy.cc create mode 100644 audio/channel_receive_proxy.cc rename audio/{channel_proxy.h => channel_receive_proxy.h} (62%) create mode 100644 audio/channel_send_proxy.cc create mode 100644 audio/channel_send_proxy.h diff --git a/audio/BUILD.gn b/audio/BUILD.gn index 7d3d6b7436..e42a726ccd 100644 --- a/audio/BUILD.gn +++ b/audio/BUILD.gn @@ -26,8 +26,10 @@ rtc_static_library("audio") { "audio_transport_impl.h", "channel.cc", "channel.h", - "channel_proxy.cc", - "channel_proxy.h", + "channel_receive_proxy.cc", + "channel_receive_proxy.h", + "channel_send_proxy.cc", + "channel_send_proxy.h", "conversion.h", "null_audio_poller.cc", "null_audio_poller.h", diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc index b507afc167..e6c9b96c5a 100644 --- a/audio/audio_receive_stream.cc +++ b/audio/audio_receive_stream.cc @@ -16,7 +16,7 @@ #include "api/call/audio_sink.h" #include "audio/audio_send_stream.h" #include "audio/audio_state.h" -#include "audio/channel_proxy.h" +#include "audio/channel_receive_proxy.h" #include "audio/conversion.h" #include "call/rtp_stream_receiver_controller_interface.h" #include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" @@ -62,7 +62,7 @@ std::string AudioReceiveStream::Config::ToString() const { namespace internal { namespace { -std::unique_ptr CreateChannelAndProxy( +std::unique_ptr CreateChannelAndProxy( webrtc::AudioState* audio_state, ProcessThread* module_process_thread, const webrtc::AudioReceiveStream::Config& config, @@ -70,11 +70,13 @@ std::unique_ptr CreateChannelAndProxy( RTC_DCHECK(audio_state); internal::AudioState* internal_audio_state = static_cast(audio_state); - return absl::make_unique(absl::make_unique( - module_process_thread, internal_audio_state->audio_device_module(), - nullptr /* RtcpRttStats */, event_log, config.rtp.remote_ssrc, - config.jitter_buffer_max_packets, config.jitter_buffer_fast_accelerate, - config.decoder_factory, config.codec_pair_id)); + return absl::make_unique( + absl::make_unique( + module_process_thread, internal_audio_state->audio_device_module(), + nullptr /* RtcpRttStats */, event_log, config.rtp.remote_ssrc, + config.jitter_buffer_max_packets, + config.jitter_buffer_fast_accelerate, config.decoder_factory, + config.codec_pair_id)); } } // namespace @@ -101,7 +103,7 @@ AudioReceiveStream::AudioReceiveStream( const webrtc::AudioReceiveStream::Config& config, const rtc::scoped_refptr& audio_state, webrtc::RtcEventLog* event_log, - std::unique_ptr channel_proxy) + std::unique_ptr channel_proxy) : audio_state_(audio_state), channel_proxy_(std::move(channel_proxy)) { RTC_LOG(LS_INFO) << "AudioReceiveStream: " << config.rtp.remote_ssrc; RTC_DCHECK(receiver_controller); diff --git a/audio/audio_receive_stream.h b/audio/audio_receive_stream.h index 64552e35c0..e982b04d54 100644 --- a/audio/audio_receive_stream.h +++ b/audio/audio_receive_stream.h @@ -32,7 +32,7 @@ class RtpStreamReceiverControllerInterface; class RtpStreamReceiverInterface; namespace voe { -class ChannelProxy; +class ChannelReceiveProxy; } // namespace voe namespace internal { @@ -54,7 +54,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream, const webrtc::AudioReceiveStream::Config& config, const rtc::scoped_refptr& audio_state, webrtc::RtcEventLog* event_log, - std::unique_ptr channel_proxy); + std::unique_ptr channel_proxy); ~AudioReceiveStream() override; // webrtc::AudioReceiveStream implementation. @@ -101,7 +101,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream, rtc::ThreadChecker module_process_thread_checker_; webrtc::AudioReceiveStream::Config config_; rtc::scoped_refptr audio_state_; - std::unique_ptr channel_proxy_; + std::unique_ptr channel_proxy_; AudioSendStream* associated_send_stream_ = nullptr; bool playing_ RTC_GUARDED_BY(worker_thread_checker_) = false; diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc index eb93bd0aa5..59963da846 100644 --- a/audio/audio_receive_stream_unittest.cc +++ b/audio/audio_receive_stream_unittest.cc @@ -81,7 +81,7 @@ struct ConfigHelper { new rtc::RefCountedObject>(); audio_state_ = AudioState::Create(config); - channel_proxy_ = new testing::StrictMock(); + channel_proxy_ = new testing::StrictMock(); EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kLocalSsrc)).Times(1); EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 15)).Times(1); EXPECT_CALL(*channel_proxy_, @@ -112,12 +112,12 @@ struct ConfigHelper { new internal::AudioReceiveStream( &rtp_stream_receiver_controller_, &packet_router_, stream_config_, audio_state_, &event_log_, - std::unique_ptr(channel_proxy_))); + std::unique_ptr(channel_proxy_))); } AudioReceiveStream::Config& config() { return stream_config_; } rtc::scoped_refptr audio_mixer() { return audio_mixer_; } - MockVoEChannelProxy* channel_proxy() { return channel_proxy_; } + MockChannelReceiveProxy* channel_proxy() { return channel_proxy_; } void SetupMockForGetStats() { using testing::DoAll; @@ -148,7 +148,7 @@ struct ConfigHelper { rtc::scoped_refptr audio_state_; rtc::scoped_refptr audio_mixer_; AudioReceiveStream::Config stream_config_; - testing::StrictMock* channel_proxy_ = nullptr; + testing::StrictMock* channel_proxy_ = nullptr; RtpStreamReceiverController rtp_stream_receiver_controller_; }; @@ -364,7 +364,7 @@ TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) { kTransportSequenceNumberId + 1)); new_config.decoder_map.emplace(1, SdpAudioFormat("foo", 8000, 1)); - MockVoEChannelProxy& channel_proxy = *helper.channel_proxy(); + MockChannelReceiveProxy& channel_proxy = *helper.channel_proxy(); EXPECT_CALL(channel_proxy, SetLocalSSRC(kLocalSsrc + 1)).Times(1); EXPECT_CALL(channel_proxy, SetNACKStatus(true, 15 + 1)).Times(1); EXPECT_CALL(channel_proxy, SetReceiveCodecs(new_config.decoder_map)); diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index eb9e8dfa8d..8de7a71b9f 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -17,7 +17,7 @@ #include "absl/memory/memory.h" #include "audio/audio_state.h" -#include "audio/channel_proxy.h" +#include "audio/channel_send_proxy.h" #include "audio/conversion.h" #include "call/rtp_transport_controller_send_interface.h" #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h" @@ -38,7 +38,7 @@ constexpr size_t kPacketLossTrackerMaxWindowSizeMs = 15000; constexpr size_t kPacketLossRateMinNumAckedPackets = 50; constexpr size_t kRecoverablePacketLossRateMinNumAckedPairs = 40; -void CallEncoder(const std::unique_ptr& channel_proxy, +void CallEncoder(const std::unique_ptr& channel_proxy, rtc::FunctionView lambda) { channel_proxy->ModifyEncoder([&](std::unique_ptr* encoder_ptr) { RTC_DCHECK(encoder_ptr); @@ -46,7 +46,7 @@ void CallEncoder(const std::unique_ptr& channel_proxy, }); } -std::unique_ptr CreateChannelAndProxy( +std::unique_ptr CreateChannelAndProxy( webrtc::AudioState* audio_state, rtc::TaskQueue* worker_queue, ProcessThread* module_process_thread, @@ -55,9 +55,11 @@ std::unique_ptr CreateChannelAndProxy( RTC_DCHECK(audio_state); internal::AudioState* internal_audio_state = static_cast(audio_state); - return absl::make_unique(absl::make_unique( - worker_queue, module_process_thread, - internal_audio_state->audio_device_module(), rtcp_rtt_stats, event_log)); + return absl::make_unique( + absl::make_unique( + worker_queue, module_process_thread, + internal_audio_state->audio_device_module(), rtcp_rtt_stats, + event_log)); } } // namespace @@ -120,7 +122,7 @@ AudioSendStream::AudioSendStream( RtcpRttStats* rtcp_rtt_stats, const absl::optional& suspended_rtp_state, TimeInterval* overall_call_lifetime, - std::unique_ptr channel_proxy) + std::unique_ptr channel_proxy) : worker_queue_(worker_queue), config_(Config(nullptr)), audio_state_(audio_state), @@ -473,7 +475,7 @@ RtpState AudioSendStream::GetRtpState() const { return rtp_rtcp_module_->GetRtpState(); } -const voe::ChannelProxy& AudioSendStream::GetChannelProxy() const { +const voe::ChannelSendProxy& AudioSendStream::GetChannelProxy() const { RTC_DCHECK(channel_proxy_.get()); return *channel_proxy_.get(); } diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index ba87202bbe..1ea676b65d 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -31,7 +31,7 @@ class RtcpRttStats; class RtpTransportControllerSendInterface; namespace voe { -class ChannelProxy; +class ChannelSendProxy; } // namespace voe namespace internal { @@ -61,7 +61,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, RtcpRttStats* rtcp_rtt_stats, const absl::optional& suspended_rtp_state, TimeInterval* overall_call_lifetime, - std::unique_ptr channel_proxy); + std::unique_ptr channel_proxy); ~AudioSendStream() override; // webrtc::AudioSendStream implementation. @@ -96,7 +96,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, void SetTransportOverhead(int transport_overhead_per_packet); RtpState GetRtpState() const; - const voe::ChannelProxy& GetChannelProxy() const; + const voe::ChannelSendProxy& GetChannelProxy() const; private: class TimedTransport; @@ -133,7 +133,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, rtc::TaskQueue* worker_queue_; webrtc::AudioSendStream::Config config_; rtc::scoped_refptr audio_state_; - std::unique_ptr channel_proxy_; + std::unique_ptr channel_proxy_; RtcEventLog* const event_log_; int encoder_sample_rate_hz_ = 0; diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index a767e028a4..0fa2393325 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -169,7 +169,7 @@ struct ConfigHelper { stream_config_, audio_state_, &worker_queue_, &rtp_transport_, &bitrate_allocator_, &event_log_, &rtcp_rtt_stats_, absl::nullopt, &active_lifetime_, - std::unique_ptr(channel_proxy_))); + std::unique_ptr(channel_proxy_))); } AudioSendStream::Config& config() { return stream_config_; } @@ -177,7 +177,7 @@ struct ConfigHelper { return *static_cast( stream_config_.encoder_factory.get()); } - MockVoEChannelProxy* channel_proxy() { return channel_proxy_; } + MockChannelSendProxy* channel_proxy() { return channel_proxy_; } RtpTransportControllerSendInterface* transport() { return &rtp_transport_; } TimeInterval* active_lifetime() { return &active_lifetime_; } @@ -189,7 +189,7 @@ struct ConfigHelper { void SetupDefaultChannelProxy(bool audio_bwe_enabled) { EXPECT_TRUE(channel_proxy_ == nullptr); - channel_proxy_ = new testing::StrictMock(); + channel_proxy_ = new testing::StrictMock(); EXPECT_CALL(*channel_proxy_, GetRtpRtcp()).WillRepeatedly(Invoke([this]() { return &this->rtp_rtcp_; })); @@ -297,7 +297,7 @@ struct ConfigHelper { private: rtc::scoped_refptr audio_state_; AudioSendStream::Config stream_config_; - testing::StrictMock* channel_proxy_ = nullptr; + testing::StrictMock* channel_proxy_ = nullptr; rtc::scoped_refptr audio_processing_; AudioProcessingStats audio_processing_stats_; TimeInterval active_lifetime_; diff --git a/audio/channel_proxy.cc b/audio/channel_proxy.cc deleted file mode 100644 index 5e8181a703..0000000000 --- a/audio/channel_proxy.cc +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "audio/channel_proxy.h" - -#include - -#include "api/call/audio_sink.h" -#include "call/rtp_transport_controller_send_interface.h" -#include "rtc_base/checks.h" -#include "rtc_base/logging.h" -#include "rtc_base/numerics/safe_minmax.h" - -namespace webrtc { -namespace voe { -ChannelProxy::ChannelProxy() {} - -ChannelProxy::ChannelProxy(std::unique_ptr channel) - : channel_(std::move(channel)) { - RTC_DCHECK(channel_); - module_process_thread_checker_.DetachFromThread(); -} - -ChannelProxy::~ChannelProxy() {} - -bool ChannelProxy::SetEncoder(int payload_type, - std::unique_ptr encoder) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->SetEncoder(payload_type, std::move(encoder)); -} - -void ChannelProxy::ModifyEncoder( - rtc::FunctionView*)> modifier) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->ModifyEncoder(modifier); -} - -void ChannelProxy::SetRTCPStatus(bool enable) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetRTCPStatus(enable); -} - -void ChannelProxy::SetLocalSSRC(uint32_t ssrc) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - int error = channel_->SetLocalSSRC(ssrc); - RTC_DCHECK_EQ(0, error); -} - -void ChannelProxy::SetMid(const std::string& mid, int extension_id) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetMid(mid, extension_id); -} - -void ChannelProxy::SetRTCP_CNAME(const std::string& c_name) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - // Note: VoERTP_RTCP::SetRTCP_CNAME() accepts a char[256] array. - std::string c_name_limited = c_name.substr(0, 255); - int error = channel_->SetRTCP_CNAME(c_name_limited.c_str()); - RTC_DCHECK_EQ(0, error); -} - -void ChannelProxy::SetNACKStatus(bool enable, int max_packets) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetNACKStatus(enable, max_packets); -} - -void ChannelProxy::SetSendAudioLevelIndicationStatus(bool enable, int id) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - int error = channel_->SetSendAudioLevelIndicationStatus(enable, id); - RTC_DCHECK_EQ(0, error); -} - -void ChannelProxy::EnableSendTransportSequenceNumber(int id) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->EnableSendTransportSequenceNumber(id); -} - -void ChannelProxy::RegisterSenderCongestionControlObjects( - RtpTransportControllerSendInterface* transport, - RtcpBandwidthObserver* bandwidth_observer) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->RegisterSenderCongestionControlObjects(transport, - bandwidth_observer); -} - -void ChannelProxy::RegisterReceiverCongestionControlObjects( - PacketRouter* packet_router) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->RegisterReceiverCongestionControlObjects(packet_router); -} - -void ChannelProxy::ResetSenderCongestionControlObjects() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->ResetSenderCongestionControlObjects(); -} - -void ChannelProxy::ResetReceiverCongestionControlObjects() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->ResetReceiverCongestionControlObjects(); -} - -CallStatistics ChannelProxy::GetRTCPStatistics() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - CallStatistics stats = {0}; - int error = channel_->GetRTPStatistics(stats); - RTC_DCHECK_EQ(0, error); - return stats; -} - -std::vector ChannelProxy::GetRemoteRTCPReportBlocks() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - std::vector blocks; - int error = channel_->GetRemoteRTCPReportBlocks(&blocks); - RTC_DCHECK_EQ(0, error); - return blocks; -} - -NetworkStatistics ChannelProxy::GetNetworkStatistics() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - NetworkStatistics stats = {0}; - int error = channel_->GetNetworkStatistics(stats); - RTC_DCHECK_EQ(0, error); - return stats; -} - -AudioDecodingCallStats ChannelProxy::GetDecodingCallStatistics() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - AudioDecodingCallStats stats; - channel_->GetDecodingCallStatistics(&stats); - return stats; -} - -ANAStats ChannelProxy::GetANAStatistics() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->GetANAStatistics(); -} - -int ChannelProxy::GetSpeechOutputLevelFullRange() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->GetSpeechOutputLevelFullRange(); -} - -double ChannelProxy::GetTotalOutputEnergy() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->GetTotalOutputEnergy(); -} - -double ChannelProxy::GetTotalOutputDuration() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->GetTotalOutputDuration(); -} - -uint32_t ChannelProxy::GetDelayEstimate() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread() || - module_process_thread_checker_.CalledOnValidThread()); - return channel_->GetDelayEstimate(); -} - -bool ChannelProxy::SetSendTelephoneEventPayloadType(int payload_type, - int payload_frequency) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->SetSendTelephoneEventPayloadType(payload_type, - payload_frequency) == 0; -} - -bool ChannelProxy::SendTelephoneEventOutband(int event, int duration_ms) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->SendTelephoneEventOutband(event, duration_ms) == 0; -} - -void ChannelProxy::SetBitrate(int bitrate_bps, int64_t probing_interval_ms) { - // This method can be called on the worker thread, module process thread - // or on a TaskQueue via VideoSendStreamImpl::OnEncoderConfigurationChanged. - // TODO(solenberg): Figure out a good way to check this or enforce calling - // rules. - // RTC_DCHECK(worker_thread_checker_.CalledOnValidThread() || - // module_process_thread_checker_.CalledOnValidThread()); - channel_->SetBitRate(bitrate_bps, probing_interval_ms); -} - -void ChannelProxy::SetReceiveCodecs( - const std::map& codecs) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetReceiveCodecs(codecs); -} - -void ChannelProxy::SetSink(AudioSinkInterface* sink) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetSink(sink); -} - -void ChannelProxy::SetInputMute(bool muted) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetInputMute(muted); -} - -void ChannelProxy::RegisterTransport(Transport* transport) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->RegisterTransport(transport); -} - -void ChannelProxy::OnRtpPacket(const RtpPacketReceived& packet) { - // May be called on either worker thread or network thread. - channel_->OnRtpPacket(packet); -} - -bool ChannelProxy::ReceivedRTCPPacket(const uint8_t* packet, size_t length) { - // May be called on either worker thread or network thread. - return channel_->ReceivedRTCPPacket(packet, length) == 0; -} - -void ChannelProxy::SetChannelOutputVolumeScaling(float scaling) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetChannelOutputVolumeScaling(scaling); -} - -AudioMixer::Source::AudioFrameInfo ChannelProxy::GetAudioFrameWithInfo( - int sample_rate_hz, - AudioFrame* audio_frame) { - RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); - return channel_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame); -} - -int ChannelProxy::PreferredSampleRate() const { - RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); - return channel_->PreferredSampleRate(); -} - -void ChannelProxy::ProcessAndEncodeAudio( - std::unique_ptr audio_frame) { - RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); - return channel_->ProcessAndEncodeAudio(std::move(audio_frame)); -} - -void ChannelProxy::SetTransportOverhead(int transport_overhead_per_packet) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetTransportOverhead(transport_overhead_per_packet); -} - -void ChannelProxy::AssociateSendChannel( - const ChannelProxy& send_channel_proxy) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetAssociatedSendChannel(send_channel_proxy.channel_.get()); -} - -void ChannelProxy::DisassociateSendChannel() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->SetAssociatedSendChannel(nullptr); -} - -RtpRtcp* ChannelProxy::GetRtpRtcp() const { - RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); - return channel_->GetRtpRtcp(); -} - -absl::optional ChannelProxy::GetSyncInfo() const { - RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); - return channel_->GetSyncInfo(); -} - -uint32_t ChannelProxy::GetPlayoutTimestamp() const { - RTC_DCHECK_RUNS_SERIALIZED(&video_capture_thread_race_checker_); - unsigned int timestamp = 0; - int error = channel_->GetPlayoutTimestamp(timestamp); - RTC_DCHECK(!error || timestamp == 0); - return timestamp; -} - -void ChannelProxy::SetMinimumPlayoutDelay(int delay_ms) { - RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); - // Limit to range accepted by both VoE and ACM, so we're at least getting as - // close as possible, instead of failing. - delay_ms = rtc::SafeClamp(delay_ms, 0, 10000); - int error = channel_->SetMinimumPlayoutDelay(delay_ms); - if (0 != error) { - RTC_LOG(LS_WARNING) << "Error setting minimum playout delay."; - } -} - -bool ChannelProxy::GetRecCodec(CodecInst* codec_inst) const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->GetRecCodec(*codec_inst) == 0; -} - -void ChannelProxy::OnTwccBasedUplinkPacketLossRate(float packet_loss_rate) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->OnTwccBasedUplinkPacketLossRate(packet_loss_rate); -} - -void ChannelProxy::OnRecoverableUplinkPacketLossRate( - float recoverable_packet_loss_rate) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->OnRecoverableUplinkPacketLossRate(recoverable_packet_loss_rate); -} - -std::vector ChannelProxy::GetSources() const { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - return channel_->GetSources(); -} - -void ChannelProxy::StartSend() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - int error = channel_->StartSend(); - RTC_DCHECK_EQ(0, error); -} - -void ChannelProxy::StopSend() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - channel_->StopSend(); -} - -void ChannelProxy::StartPlayout() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - int error = channel_->StartPlayout(); - RTC_DCHECK_EQ(0, error); -} - -void ChannelProxy::StopPlayout() { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); - int error = channel_->StopPlayout(); - RTC_DCHECK_EQ(0, error); -} -} // namespace voe -} // namespace webrtc diff --git a/audio/channel_receive_proxy.cc b/audio/channel_receive_proxy.cc new file mode 100644 index 0000000000..c57bae063e --- /dev/null +++ b/audio/channel_receive_proxy.cc @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "audio/channel_receive_proxy.h" + +#include + +#include "api/call/audio_sink.h" +#include "audio/channel_send_proxy.h" +#include "call/rtp_transport_controller_send_interface.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_minmax.h" + +namespace webrtc { +namespace voe { +ChannelReceiveProxy::ChannelReceiveProxy() {} + +ChannelReceiveProxy::ChannelReceiveProxy(std::unique_ptr channel) + : channel_(std::move(channel)) { + RTC_DCHECK(channel_); + module_process_thread_checker_.DetachFromThread(); +} + +ChannelReceiveProxy::~ChannelReceiveProxy() {} + +void ChannelReceiveProxy::SetLocalSSRC(uint32_t ssrc) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + int error = channel_->SetLocalSSRC(ssrc); + RTC_DCHECK_EQ(0, error); +} + +void ChannelReceiveProxy::SetNACKStatus(bool enable, int max_packets) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetNACKStatus(enable, max_packets); +} + +CallStatistics ChannelReceiveProxy::GetRTCPStatistics() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + CallStatistics stats = {0}; + int error = channel_->GetRTPStatistics(stats); + RTC_DCHECK_EQ(0, error); + return stats; +} + +void ChannelReceiveProxy::RegisterTransport(Transport* transport) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->RegisterTransport(transport); +} + +bool ChannelReceiveProxy::ReceivedRTCPPacket(const uint8_t* packet, + size_t length) { + // May be called on either worker thread or network thread. + return channel_->ReceivedRTCPPacket(packet, length) == 0; +} + +void ChannelReceiveProxy::RegisterReceiverCongestionControlObjects( + PacketRouter* packet_router) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->RegisterReceiverCongestionControlObjects(packet_router); +} + +void ChannelReceiveProxy::ResetReceiverCongestionControlObjects() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->ResetReceiverCongestionControlObjects(); +} + +NetworkStatistics ChannelReceiveProxy::GetNetworkStatistics() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + NetworkStatistics stats = {0}; + int error = channel_->GetNetworkStatistics(stats); + RTC_DCHECK_EQ(0, error); + return stats; +} + +AudioDecodingCallStats ChannelReceiveProxy::GetDecodingCallStatistics() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + AudioDecodingCallStats stats; + channel_->GetDecodingCallStatistics(&stats); + return stats; +} + +int ChannelReceiveProxy::GetSpeechOutputLevelFullRange() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->GetSpeechOutputLevelFullRange(); +} + +double ChannelReceiveProxy::GetTotalOutputEnergy() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->GetTotalOutputEnergy(); +} + +double ChannelReceiveProxy::GetTotalOutputDuration() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->GetTotalOutputDuration(); +} + +uint32_t ChannelReceiveProxy::GetDelayEstimate() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread() || + module_process_thread_checker_.CalledOnValidThread()); + return channel_->GetDelayEstimate(); +} + +void ChannelReceiveProxy::SetReceiveCodecs( + const std::map& codecs) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetReceiveCodecs(codecs); +} + +void ChannelReceiveProxy::SetSink(AudioSinkInterface* sink) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetSink(sink); +} + +void ChannelReceiveProxy::OnRtpPacket(const RtpPacketReceived& packet) { + // May be called on either worker thread or network thread. + channel_->OnRtpPacket(packet); +} + +void ChannelReceiveProxy::SetChannelOutputVolumeScaling(float scaling) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetChannelOutputVolumeScaling(scaling); +} + +AudioMixer::Source::AudioFrameInfo ChannelReceiveProxy::GetAudioFrameWithInfo( + int sample_rate_hz, + AudioFrame* audio_frame) { + RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); + return channel_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame); +} + +int ChannelReceiveProxy::PreferredSampleRate() const { + RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); + return channel_->PreferredSampleRate(); +} + +void ChannelReceiveProxy::AssociateSendChannel( + const ChannelSendProxy& send_channel_proxy) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetAssociatedSendChannel(send_channel_proxy.GetChannel()); +} + +void ChannelReceiveProxy::DisassociateSendChannel() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetAssociatedSendChannel(nullptr); +} + +absl::optional ChannelReceiveProxy::GetSyncInfo() const { + RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); + return channel_->GetSyncInfo(); +} + +uint32_t ChannelReceiveProxy::GetPlayoutTimestamp() const { + RTC_DCHECK_RUNS_SERIALIZED(&video_capture_thread_race_checker_); + unsigned int timestamp = 0; + int error = channel_->GetPlayoutTimestamp(timestamp); + RTC_DCHECK(!error || timestamp == 0); + return timestamp; +} + +void ChannelReceiveProxy::SetMinimumPlayoutDelay(int delay_ms) { + RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); + // Limit to range accepted by both VoE and ACM, so we're at least getting as + // close as possible, instead of failing. + delay_ms = rtc::SafeClamp(delay_ms, 0, 10000); + int error = channel_->SetMinimumPlayoutDelay(delay_ms); + if (0 != error) { + RTC_LOG(LS_WARNING) << "Error setting minimum playout delay."; + } +} + +bool ChannelReceiveProxy::GetRecCodec(CodecInst* codec_inst) const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->GetRecCodec(*codec_inst) == 0; +} + +std::vector ChannelReceiveProxy::GetSources() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->GetSources(); +} + +void ChannelReceiveProxy::StartPlayout() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + int error = channel_->StartPlayout(); + RTC_DCHECK_EQ(0, error); +} + +void ChannelReceiveProxy::StopPlayout() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + int error = channel_->StopPlayout(); + RTC_DCHECK_EQ(0, error); +} +} // namespace voe +} // namespace webrtc diff --git a/audio/channel_proxy.h b/audio/channel_receive_proxy.h similarity index 62% rename from audio/channel_proxy.h rename to audio/channel_receive_proxy.h index f82c1fd281..9426968bd6 100644 --- a/audio/channel_proxy.h +++ b/audio/channel_receive_proxy.h @@ -8,16 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef AUDIO_CHANNEL_PROXY_H_ -#define AUDIO_CHANNEL_PROXY_H_ +#ifndef AUDIO_CHANNEL_RECEIVE_PROXY_H_ +#define AUDIO_CHANNEL_RECEIVE_PROXY_H_ #include #include -#include #include #include "api/audio/audio_mixer.h" -#include "api/audio_codecs/audio_encoder.h" #include "api/rtpreceiverinterface.h" #include "audio/channel.h" #include "call/rtp_packet_sink_interface.h" @@ -29,95 +27,63 @@ namespace webrtc { class AudioSinkInterface; class PacketRouter; -class RtcEventLog; -class RtcpBandwidthObserver; -class RtcpRttStats; -class RtpPacketSender; class RtpPacketReceived; -class RtpRtcp; -class RtpTransportControllerSendInterface; class Transport; -class TransportFeedbackObserver; namespace voe { +class ChannelSendProxy; + // This class provides the "view" of a voe::Channel that we need to implement -// webrtc::AudioSendStream and webrtc::AudioReceiveStream. It serves two -// purposes: +// webrtc::AudioReceiveStream. It serves two purposes: // 1. Allow mocking just the interfaces used, instead of the entire // voe::Channel class. // 2. Provide a refined interface for the stream classes, including assumptions // on return values and input adaptation. -class ChannelProxy : public RtpPacketSinkInterface { +class ChannelReceiveProxy : public RtpPacketSinkInterface { public: - ChannelProxy(); - explicit ChannelProxy(std::unique_ptr channel); - virtual ~ChannelProxy(); + ChannelReceiveProxy(); + explicit ChannelReceiveProxy(std::unique_ptr channel); + virtual ~ChannelReceiveProxy(); - virtual bool SetEncoder(int payload_type, - std::unique_ptr encoder); - virtual void ModifyEncoder( - rtc::FunctionView*)> modifier); - - virtual void SetRTCPStatus(bool enable); + // Shared with ChannelSendProxy virtual void SetLocalSSRC(uint32_t ssrc); - virtual void SetMid(const std::string& mid, int extension_id); - virtual void SetRTCP_CNAME(const std::string& c_name); virtual void SetNACKStatus(bool enable, int max_packets); - virtual void SetSendAudioLevelIndicationStatus(bool enable, int id); - virtual void EnableSendTransportSequenceNumber(int id); - virtual void RegisterSenderCongestionControlObjects( - RtpTransportControllerSendInterface* transport, - RtcpBandwidthObserver* bandwidth_observer); + virtual CallStatistics GetRTCPStatistics() const; + virtual void RegisterTransport(Transport* transport); + virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length); + virtual void RegisterReceiverCongestionControlObjects( PacketRouter* packet_router); - virtual void ResetSenderCongestionControlObjects(); virtual void ResetReceiverCongestionControlObjects(); - virtual CallStatistics GetRTCPStatistics() const; - virtual std::vector GetRemoteRTCPReportBlocks() const; virtual NetworkStatistics GetNetworkStatistics() const; virtual AudioDecodingCallStats GetDecodingCallStatistics() const; - virtual ANAStats GetANAStatistics() const; virtual int GetSpeechOutputLevelFullRange() const; // See description of "totalAudioEnergy" in the WebRTC stats spec: // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy virtual double GetTotalOutputEnergy() const; virtual double GetTotalOutputDuration() const; virtual uint32_t GetDelayEstimate() const; - virtual bool SetSendTelephoneEventPayloadType(int payload_type, - int payload_frequency); - virtual bool SendTelephoneEventOutband(int event, int duration_ms); - virtual void SetBitrate(int bitrate_bps, int64_t probing_interval_ms); virtual void SetReceiveCodecs(const std::map& codecs); virtual void SetSink(AudioSinkInterface* sink); - virtual void SetInputMute(bool muted); - virtual void RegisterTransport(Transport* transport); // Implements RtpPacketSinkInterface void OnRtpPacket(const RtpPacketReceived& packet) override; - virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length); + virtual void SetChannelOutputVolumeScaling(float scaling); virtual AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo( int sample_rate_hz, AudioFrame* audio_frame); virtual int PreferredSampleRate() const; - virtual void ProcessAndEncodeAudio(std::unique_ptr audio_frame); - virtual void SetTransportOverhead(int transport_overhead_per_packet); - virtual void AssociateSendChannel(const ChannelProxy& send_channel_proxy); + virtual void AssociateSendChannel(const ChannelSendProxy& send_channel_proxy); virtual void DisassociateSendChannel(); - virtual RtpRtcp* GetRtpRtcp() const; // Produces the transport-related timestamps; current_delay_ms is left unset. absl::optional GetSyncInfo() const; virtual uint32_t GetPlayoutTimestamp() const; virtual void SetMinimumPlayoutDelay(int delay_ms); virtual bool GetRecCodec(CodecInst* codec_inst) const; - virtual void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate); - virtual void OnRecoverableUplinkPacketLossRate( - float recoverable_packet_loss_rate); virtual std::vector GetSources() const; - virtual void StartSend(); - virtual void StopSend(); virtual void StartPlayout(); virtual void StopPlayout(); @@ -136,9 +102,9 @@ class ChannelProxy : public RtpPacketSinkInterface { rtc::RaceChecker video_capture_thread_race_checker_; std::unique_ptr channel_; - RTC_DISALLOW_COPY_AND_ASSIGN(ChannelProxy); + RTC_DISALLOW_COPY_AND_ASSIGN(ChannelReceiveProxy); }; } // namespace voe } // namespace webrtc -#endif // AUDIO_CHANNEL_PROXY_H_ +#endif // AUDIO_CHANNEL_RECEIVE_PROXY_H_ diff --git a/audio/channel_send_proxy.cc b/audio/channel_send_proxy.cc new file mode 100644 index 0000000000..43aac58039 --- /dev/null +++ b/audio/channel_send_proxy.cc @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "audio/channel_send_proxy.h" + +#include + +#include "api/call/audio_sink.h" +#include "call/rtp_transport_controller_send_interface.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_minmax.h" + +namespace webrtc { +namespace voe { +ChannelSendProxy::ChannelSendProxy() {} + +ChannelSendProxy::ChannelSendProxy(std::unique_ptr channel) + : channel_(std::move(channel)) { + RTC_DCHECK(channel_); + module_process_thread_checker_.DetachFromThread(); +} + +ChannelSendProxy::~ChannelSendProxy() {} + +void ChannelSendProxy::SetLocalSSRC(uint32_t ssrc) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + int error = channel_->SetLocalSSRC(ssrc); + RTC_DCHECK_EQ(0, error); +} + +void ChannelSendProxy::SetNACKStatus(bool enable, int max_packets) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetNACKStatus(enable, max_packets); +} + +CallStatistics ChannelSendProxy::GetRTCPStatistics() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + CallStatistics stats = {0}; + int error = channel_->GetRTPStatistics(stats); + RTC_DCHECK_EQ(0, error); + return stats; +} + +void ChannelSendProxy::RegisterTransport(Transport* transport) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->RegisterTransport(transport); +} + +bool ChannelSendProxy::ReceivedRTCPPacket(const uint8_t* packet, + size_t length) { + // May be called on either worker thread or network thread. + return channel_->ReceivedRTCPPacket(packet, length) == 0; +} + +bool ChannelSendProxy::SetEncoder(int payload_type, + std::unique_ptr encoder) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->SetEncoder(payload_type, std::move(encoder)); +} + +void ChannelSendProxy::ModifyEncoder( + rtc::FunctionView*)> modifier) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->ModifyEncoder(modifier); +} + +void ChannelSendProxy::SetRTCPStatus(bool enable) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetRTCPStatus(enable); +} + +void ChannelSendProxy::SetMid(const std::string& mid, int extension_id) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetMid(mid, extension_id); +} + +void ChannelSendProxy::SetRTCP_CNAME(const std::string& c_name) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + // Note: VoERTP_RTCP::SetRTCP_CNAME() accepts a char[256] array. + std::string c_name_limited = c_name.substr(0, 255); + int error = channel_->SetRTCP_CNAME(c_name_limited.c_str()); + RTC_DCHECK_EQ(0, error); +} + +void ChannelSendProxy::SetSendAudioLevelIndicationStatus(bool enable, int id) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + int error = channel_->SetSendAudioLevelIndicationStatus(enable, id); + RTC_DCHECK_EQ(0, error); +} + +void ChannelSendProxy::EnableSendTransportSequenceNumber(int id) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->EnableSendTransportSequenceNumber(id); +} + +void ChannelSendProxy::RegisterSenderCongestionControlObjects( + RtpTransportControllerSendInterface* transport, + RtcpBandwidthObserver* bandwidth_observer) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->RegisterSenderCongestionControlObjects(transport, + bandwidth_observer); +} + +void ChannelSendProxy::ResetSenderCongestionControlObjects() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->ResetSenderCongestionControlObjects(); +} + +std::vector ChannelSendProxy::GetRemoteRTCPReportBlocks() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + std::vector blocks; + int error = channel_->GetRemoteRTCPReportBlocks(&blocks); + RTC_DCHECK_EQ(0, error); + return blocks; +} + +ANAStats ChannelSendProxy::GetANAStatistics() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->GetANAStatistics(); +} + +bool ChannelSendProxy::SetSendTelephoneEventPayloadType(int payload_type, + int payload_frequency) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->SetSendTelephoneEventPayloadType(payload_type, + payload_frequency) == 0; +} + +bool ChannelSendProxy::SendTelephoneEventOutband(int event, int duration_ms) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel_->SendTelephoneEventOutband(event, duration_ms) == 0; +} + +void ChannelSendProxy::SetBitrate(int bitrate_bps, + int64_t probing_interval_ms) { + // This method can be called on the worker thread, module process thread + // or on a TaskQueue via VideoSendStreamImpl::OnEncoderConfigurationChanged. + // TODO(solenberg): Figure out a good way to check this or enforce calling + // rules. + // RTC_DCHECK(worker_thread_checker_.CalledOnValidThread() || + // module_process_thread_checker_.CalledOnValidThread()); + channel_->SetBitRate(bitrate_bps, probing_interval_ms); +} + +void ChannelSendProxy::SetInputMute(bool muted) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetInputMute(muted); +} + +void ChannelSendProxy::ProcessAndEncodeAudio( + std::unique_ptr audio_frame) { + RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); + return channel_->ProcessAndEncodeAudio(std::move(audio_frame)); +} + +void ChannelSendProxy::SetTransportOverhead(int transport_overhead_per_packet) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->SetTransportOverhead(transport_overhead_per_packet); +} + +RtpRtcp* ChannelSendProxy::GetRtpRtcp() const { + RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread()); + return channel_->GetRtpRtcp(); +} + +void ChannelSendProxy::OnTwccBasedUplinkPacketLossRate(float packet_loss_rate) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->OnTwccBasedUplinkPacketLossRate(packet_loss_rate); +} + +void ChannelSendProxy::OnRecoverableUplinkPacketLossRate( + float recoverable_packet_loss_rate) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->OnRecoverableUplinkPacketLossRate(recoverable_packet_loss_rate); +} + +void ChannelSendProxy::StartSend() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + int error = channel_->StartSend(); + RTC_DCHECK_EQ(0, error); +} + +void ChannelSendProxy::StopSend() { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + channel_->StopSend(); +} + +Channel* ChannelSendProxy::GetChannel() const { + return channel_.get(); +} + +} // namespace voe +} // namespace webrtc diff --git a/audio/channel_send_proxy.h b/audio/channel_send_proxy.h new file mode 100644 index 0000000000..88ce610f25 --- /dev/null +++ b/audio/channel_send_proxy.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef AUDIO_CHANNEL_SEND_PROXY_H_ +#define AUDIO_CHANNEL_SEND_PROXY_H_ + +#include +#include +#include + +#include "api/audio_codecs/audio_encoder.h" +#include "audio/channel.h" +#include "rtc_base/constructormagic.h" +#include "rtc_base/race_checker.h" +#include "rtc_base/thread_checker.h" + +namespace webrtc { + +class RtcpBandwidthObserver; +class RtpRtcp; +class RtpTransportControllerSendInterface; +class Transport; + +namespace voe { + +// This class provides the "view" of a voe::Channel that we need to implement +// webrtc::AudioSendStream. It serves two purposes: +// 1. Allow mocking just the interfaces used, instead of the entire +// voe::Channel class. +// 2. Provide a refined interface for the stream classes, including assumptions +// on return values and input adaptation. +class ChannelSendProxy { + public: + ChannelSendProxy(); + explicit ChannelSendProxy(std::unique_ptr channel); + virtual ~ChannelSendProxy(); + + // Shared with ChannelReceiveProxy + virtual void SetLocalSSRC(uint32_t ssrc); + virtual void SetNACKStatus(bool enable, int max_packets); + virtual CallStatistics GetRTCPStatistics() const; + virtual void RegisterTransport(Transport* transport); + virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length); + + virtual bool SetEncoder(int payload_type, + std::unique_ptr encoder); + virtual void ModifyEncoder( + rtc::FunctionView*)> modifier); + + virtual void SetRTCPStatus(bool enable); + virtual void SetMid(const std::string& mid, int extension_id); + virtual void SetRTCP_CNAME(const std::string& c_name); + virtual void SetSendAudioLevelIndicationStatus(bool enable, int id); + virtual void EnableSendTransportSequenceNumber(int id); + virtual void RegisterSenderCongestionControlObjects( + RtpTransportControllerSendInterface* transport, + RtcpBandwidthObserver* bandwidth_observer); + virtual void ResetSenderCongestionControlObjects(); + virtual std::vector GetRemoteRTCPReportBlocks() const; + virtual ANAStats GetANAStatistics() const; + virtual bool SetSendTelephoneEventPayloadType(int payload_type, + int payload_frequency); + virtual bool SendTelephoneEventOutband(int event, int duration_ms); + virtual void SetBitrate(int bitrate_bps, int64_t probing_interval_ms); + virtual void SetInputMute(bool muted); + + virtual void ProcessAndEncodeAudio(std::unique_ptr audio_frame); + virtual void SetTransportOverhead(int transport_overhead_per_packet); + virtual RtpRtcp* GetRtpRtcp() const; + + virtual void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate); + virtual void OnRecoverableUplinkPacketLossRate( + float recoverable_packet_loss_rate); + virtual void StartSend(); + virtual void StopSend(); + + // Needed by ChannelReceiveProxy::AssociateSendChannel. + virtual Channel* GetChannel() const; + + private: + // Thread checkers document and lock usage of some methods on voe::Channel to + // specific threads we know about. The goal is to eventually split up + // voe::Channel into parts with single-threaded semantics, and thereby reduce + // the need for locks. + rtc::ThreadChecker worker_thread_checker_; + rtc::ThreadChecker module_process_thread_checker_; + // Methods accessed from audio and video threads are checked for sequential- + // only access. We don't necessarily own and control these threads, so thread + // checkers cannot be used. E.g. Chromium may transfer "ownership" from one + // audio thread to another, but access is still sequential. + rtc::RaceChecker audio_thread_race_checker_; + rtc::RaceChecker video_capture_thread_race_checker_; + std::unique_ptr channel_; + + RTC_DISALLOW_COPY_AND_ASSIGN(ChannelSendProxy); +}; +} // namespace voe +} // namespace webrtc + +#endif // AUDIO_CHANNEL_SEND_PROXY_H_ diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h index f6a2637c42..9d122c6704 100644 --- a/audio/mock_voe_channel_proxy.h +++ b/audio/mock_voe_channel_proxy.h @@ -16,14 +16,51 @@ #include #include -#include "audio/channel_proxy.h" +#include "audio/channel_receive_proxy.h" +#include "audio/channel_send_proxy.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "test/gmock.h" namespace webrtc { namespace test { -class MockVoEChannelProxy : public voe::ChannelProxy { +class MockChannelReceiveProxy : public voe::ChannelReceiveProxy { + public: + MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc)); + MOCK_METHOD2(SetNACKStatus, void(bool enable, int max_packets)); + MOCK_METHOD1(RegisterReceiverCongestionControlObjects, + void(PacketRouter* packet_router)); + MOCK_METHOD0(ResetReceiverCongestionControlObjects, void()); + MOCK_CONST_METHOD0(GetRTCPStatistics, CallStatistics()); + MOCK_CONST_METHOD0(GetNetworkStatistics, NetworkStatistics()); + MOCK_CONST_METHOD0(GetDecodingCallStatistics, AudioDecodingCallStats()); + MOCK_CONST_METHOD0(GetSpeechOutputLevelFullRange, int()); + MOCK_CONST_METHOD0(GetTotalOutputEnergy, double()); + MOCK_CONST_METHOD0(GetTotalOutputDuration, double()); + MOCK_CONST_METHOD0(GetDelayEstimate, uint32_t()); + MOCK_METHOD1(SetSink, void(AudioSinkInterface* sink)); + MOCK_METHOD1(RegisterTransport, void(Transport* transport)); + MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived& packet)); + MOCK_METHOD2(ReceivedRTCPPacket, bool(const uint8_t* packet, size_t length)); + MOCK_METHOD1(SetChannelOutputVolumeScaling, void(float scaling)); + MOCK_METHOD2(GetAudioFrameWithInfo, + AudioMixer::Source::AudioFrameInfo(int sample_rate_hz, + AudioFrame* audio_frame)); + MOCK_CONST_METHOD0(PreferredSampleRate, int()); + MOCK_METHOD1(AssociateSendChannel, + void(const voe::ChannelSendProxy& send_channel_proxy)); + MOCK_METHOD0(DisassociateSendChannel, void()); + MOCK_CONST_METHOD0(GetPlayoutTimestamp, uint32_t()); + MOCK_METHOD1(SetMinimumPlayoutDelay, void(int delay_ms)); + MOCK_CONST_METHOD1(GetRecCodec, bool(CodecInst* codec_inst)); + MOCK_METHOD1(SetReceiveCodecs, + void(const std::map& codecs)); + MOCK_CONST_METHOD0(GetSources, std::vector()); + MOCK_METHOD0(StartPlayout, void()); + MOCK_METHOD0(StopPlayout, void()); +}; + +class MockChannelSendProxy : public voe::ChannelSendProxy { public: // GMock doesn't like move-only types, like std::unique_ptr. virtual bool SetEncoder(int payload_type, @@ -44,33 +81,17 @@ class MockVoEChannelProxy : public voe::ChannelProxy { MOCK_METHOD2(RegisterSenderCongestionControlObjects, void(RtpTransportControllerSendInterface* transport, RtcpBandwidthObserver* bandwidth_observer)); - MOCK_METHOD1(RegisterReceiverCongestionControlObjects, - void(PacketRouter* packet_router)); MOCK_METHOD0(ResetSenderCongestionControlObjects, void()); - MOCK_METHOD0(ResetReceiverCongestionControlObjects, void()); MOCK_CONST_METHOD0(GetRTCPStatistics, CallStatistics()); MOCK_CONST_METHOD0(GetRemoteRTCPReportBlocks, std::vector()); - MOCK_CONST_METHOD0(GetNetworkStatistics, NetworkStatistics()); - MOCK_CONST_METHOD0(GetDecodingCallStatistics, AudioDecodingCallStats()); MOCK_CONST_METHOD0(GetANAStatistics, ANAStats()); - MOCK_CONST_METHOD0(GetSpeechOutputLevelFullRange, int()); - MOCK_CONST_METHOD0(GetTotalOutputEnergy, double()); - MOCK_CONST_METHOD0(GetTotalOutputDuration, double()); - MOCK_CONST_METHOD0(GetDelayEstimate, uint32_t()); MOCK_METHOD2(SetSendTelephoneEventPayloadType, bool(int payload_type, int payload_frequency)); MOCK_METHOD2(SendTelephoneEventOutband, bool(int event, int duration_ms)); MOCK_METHOD2(SetBitrate, void(int bitrate_bps, int64_t probing_interval_ms)); - MOCK_METHOD1(SetSink, void(AudioSinkInterface* sink)); MOCK_METHOD1(SetInputMute, void(bool muted)); MOCK_METHOD1(RegisterTransport, void(Transport* transport)); - MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived& packet)); MOCK_METHOD2(ReceivedRTCPPacket, bool(const uint8_t* packet, size_t length)); - MOCK_METHOD1(SetChannelOutputVolumeScaling, void(float scaling)); - MOCK_METHOD2(GetAudioFrameWithInfo, - AudioMixer::Source::AudioFrameInfo(int sample_rate_hz, - AudioFrame* audio_frame)); - MOCK_CONST_METHOD0(PreferredSampleRate, int()); // GMock doesn't like move-only types, like std::unique_ptr. virtual void ProcessAndEncodeAudio(std::unique_ptr audio_frame) { ProcessAndEncodeAudioForMock(&audio_frame); @@ -78,23 +99,12 @@ class MockVoEChannelProxy : public voe::ChannelProxy { MOCK_METHOD1(ProcessAndEncodeAudioForMock, void(std::unique_ptr* audio_frame)); MOCK_METHOD1(SetTransportOverhead, void(int transport_overhead_per_packet)); - MOCK_METHOD1(AssociateSendChannel, - void(const ChannelProxy& send_channel_proxy)); - MOCK_METHOD0(DisassociateSendChannel, void()); MOCK_CONST_METHOD0(GetRtpRtcp, RtpRtcp*()); - MOCK_CONST_METHOD0(GetPlayoutTimestamp, uint32_t()); - MOCK_METHOD1(SetMinimumPlayoutDelay, void(int delay_ms)); - MOCK_CONST_METHOD1(GetRecCodec, bool(CodecInst* codec_inst)); - MOCK_METHOD1(SetReceiveCodecs, - void(const std::map& codecs)); MOCK_METHOD1(OnTwccBasedUplinkPacketLossRate, void(float packet_loss_rate)); MOCK_METHOD1(OnRecoverableUplinkPacketLossRate, void(float recoverable_packet_loss_rate)); - MOCK_CONST_METHOD0(GetSources, std::vector()); MOCK_METHOD0(StartSend, void()); MOCK_METHOD0(StopSend, void()); - MOCK_METHOD0(StartPlayout, void()); - MOCK_METHOD0(StopPlayout, void()); }; } // namespace test } // namespace webrtc