diff --git a/webrtc/api/call/audio_send_stream.cc b/webrtc/api/call/audio_send_stream.cc index 06cbc545d9..52c30f0987 100644 --- a/webrtc/api/call/audio_send_stream.cc +++ b/webrtc/api/call/audio_send_stream.cc @@ -34,6 +34,8 @@ AudioSendStream::Stats::Stats() = default; AudioSendStream::Config::Config(Transport* send_transport) : send_transport(send_transport) {} +AudioSendStream::Config::~Config() = default; + std::string AudioSendStream::Config::ToString() const { std::stringstream ss; ss << "{rtp: " << rtp.ToString(); @@ -82,6 +84,8 @@ std::string AudioSendStream::Config::SendCodecSpec::ToString() const { ss << ", opus_max_playback_rate: " << opus_max_playback_rate; ss << ", cng_payload_type: " << cng_payload_type; ss << ", cng_plfreq: " << cng_plfreq; + ss << ", min_ptime: " << min_ptime_ms; + ss << ", max_ptime: " << max_ptime_ms; ss << ", codec_inst: " << ::ToString(codec_inst); ss << '}'; return ss.str(); @@ -89,30 +93,16 @@ std::string AudioSendStream::Config::SendCodecSpec::ToString() const { bool AudioSendStream::Config::SendCodecSpec::operator==( const AudioSendStream::Config::SendCodecSpec& rhs) const { - if (nack_enabled != rhs.nack_enabled) { - return false; + if (nack_enabled == rhs.nack_enabled && + transport_cc_enabled == rhs.transport_cc_enabled && + enable_codec_fec == rhs.enable_codec_fec && + enable_opus_dtx == rhs.enable_opus_dtx && + opus_max_playback_rate == rhs.opus_max_playback_rate && + cng_payload_type == rhs.cng_payload_type && + cng_plfreq == rhs.cng_plfreq && max_ptime_ms == rhs.max_ptime_ms && + min_ptime_ms == rhs.min_ptime_ms && codec_inst == rhs.codec_inst) { + return true; } - if (transport_cc_enabled != rhs.transport_cc_enabled) { - return false; - } - if (enable_codec_fec != rhs.enable_codec_fec) { - return false; - } - if (enable_opus_dtx != rhs.enable_opus_dtx) { - return false; - } - if (opus_max_playback_rate != rhs.opus_max_playback_rate) { - return false; - } - if (cng_payload_type != rhs.cng_payload_type) { - return false; - } - if (cng_plfreq != rhs.cng_plfreq) { - return false; - } - if (codec_inst != rhs.codec_inst) { - return false; - } - return true; + return false; } } // namespace webrtc diff --git a/webrtc/api/call/audio_send_stream.h b/webrtc/api/call/audio_send_stream.h index 7ff791e62a..78ab8ec52e 100644 --- a/webrtc/api/call/audio_send_stream.h +++ b/webrtc/api/call/audio_send_stream.h @@ -55,6 +55,7 @@ class AudioSendStream { struct Config { Config() = delete; explicit Config(Transport* send_transport); + ~Config(); std::string ToString() const; // Send-stream specific RTP settings. @@ -92,6 +93,10 @@ class AudioSendStream { int min_bitrate_kbps = -1; int max_bitrate_kbps = -1; + // Defines whether to turn on audio network adaptor, and defines its config + // string. + rtc::Optional audio_network_adaptor_config; + struct SendCodecSpec { SendCodecSpec(); std::string ToString() const; @@ -108,6 +113,8 @@ class AudioSendStream { int opus_max_playback_rate = 0; int cng_payload_type = -1; int cng_plfreq = -1; + int max_ptime_ms = -1; + int min_ptime_ms = -1; webrtc::CodecInst codec_inst; } send_codec_spec; }; diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index 5c08c9b8a2..51f9073343 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -328,6 +328,20 @@ bool AudioSendStream::SetupSendCodec() { return false; } } + + if (config_.audio_network_adaptor_config) { + // Audio network adaptor is only allowed for Opus currently. + // |SetReceiverFrameLengthRange| needs to be called before + // |EnableAudioNetworkAdaptor|. + channel_proxy_->SetReceiverFrameLengthRange(send_codec_spec.min_ptime_ms, + send_codec_spec.max_ptime_ms); + channel_proxy_->EnableAudioNetworkAdaptor( + *config_.audio_network_adaptor_config); + LOG(LS_INFO) << "Audio network adaptor enabled on SSRC " + << config_.rtp.ssrc; + } else { + channel_proxy_->DisableAudioNetworkAdaptor(); + } } // Set the CN payloadtype and the VAD status. diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc index a2832ded00..3cfe13f10b 100644 --- a/webrtc/audio/audio_send_stream_unittest.cc +++ b/webrtc/audio/audio_send_stream_unittest.cc @@ -69,7 +69,6 @@ struct ConfigHelper { bitrate_allocator_(&limit_observer_), worker_queue_("ConfigHelper_worker_queue") { using testing::Invoke; - using testing::StrEq; EXPECT_CALL(voice_engine_, RegisterVoiceEngineObserver(_)).WillOnce(Return(0)); @@ -79,40 +78,15 @@ struct ConfigHelper { config.voice_engine = &voice_engine_; audio_state_ = AudioState::Create(config); + SetupDefaultChannelProxy(); + EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId)) .WillOnce(Invoke([this](int channel_id) { - EXPECT_FALSE(channel_proxy_); - channel_proxy_ = new testing::StrictMock(); - EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1); - EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1); - EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1); - EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 10)).Times(1); - EXPECT_CALL(*channel_proxy_, - SetSendAbsoluteSenderTimeStatus(true, kAbsSendTimeId)).Times(1); - EXPECT_CALL(*channel_proxy_, - SetSendAudioLevelIndicationStatus(true, kAudioLevelId)).Times(1); - EXPECT_CALL(*channel_proxy_, EnableSendTransportSequenceNumber( - kTransportSequenceNumberId)) - .Times(1); - EXPECT_CALL(*channel_proxy_, - RegisterSenderCongestionControlObjects( - congestion_controller_.pacer(), - congestion_controller_.GetTransportFeedbackObserver(), - congestion_controller_.packet_router())) - .Times(1); - EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()) - .Times(1); - EXPECT_CALL(*channel_proxy_, RegisterExternalTransport(nullptr)) - .Times(1); - EXPECT_CALL(*channel_proxy_, DeRegisterExternalTransport()) - .Times(1); - EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::NotNull())) - .Times(1); - EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull())) - .Times(1); // Destructor resets the event log return channel_proxy_; })); + SetupMockForSetupSendCodec(); + stream_config_.voe_channel_id = kChannelId; stream_config_.rtp.ssrc = kSsrc; stream_config_.rtp.nack.rtp_history_ms = 200; @@ -139,6 +113,36 @@ struct ConfigHelper { RtcEventLog* event_log() { return &event_log_; } MockVoiceEngine* voice_engine() { return &voice_engine_; } + void SetupDefaultChannelProxy() { + using testing::StrEq; + channel_proxy_ = new testing::StrictMock(); + EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1); + EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1); + EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1); + EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 10)).Times(1); + EXPECT_CALL(*channel_proxy_, + SetSendAbsoluteSenderTimeStatus(true, kAbsSendTimeId)) + .Times(1); + EXPECT_CALL(*channel_proxy_, + SetSendAudioLevelIndicationStatus(true, kAudioLevelId)) + .Times(1); + EXPECT_CALL(*channel_proxy_, + EnableSendTransportSequenceNumber(kTransportSequenceNumberId)) + .Times(1); + EXPECT_CALL(*channel_proxy_, + RegisterSenderCongestionControlObjects( + congestion_controller_.pacer(), + congestion_controller_.GetTransportFeedbackObserver(), + congestion_controller_.packet_router())) + .Times(1); + EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()).Times(1); + EXPECT_CALL(*channel_proxy_, RegisterExternalTransport(nullptr)).Times(1); + EXPECT_CALL(*channel_proxy_, DeRegisterExternalTransport()).Times(1); + EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::NotNull())).Times(1); + EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull())) + .Times(1); // Destructor resets the event log + } + void SetupMockForSetupSendCodec() { EXPECT_CALL(voice_engine_, SetVADStatus(kChannelId, false, _, _)) .WillOnce(Return(0)); @@ -228,6 +232,8 @@ TEST(AudioSendStreamTest, ConfigToString) { config.send_codec_spec.opus_max_playback_rate = 32000; config.send_codec_spec.cng_payload_type = 42; config.send_codec_spec.cng_plfreq = 56; + config.send_codec_spec.min_ptime_ms = 20; + config.send_codec_spec.max_ptime_ms = 60; config.send_codec_spec.codec_inst = kIsacCodec; EXPECT_EQ( "{rtp: {ssrc: 1234, extensions: [{uri: " @@ -236,9 +242,9 @@ TEST(AudioSendStreamTest, ConfigToString) { "voe_channel_id: 1, min_bitrate_kbps: 12, max_bitrate_kbps: 34, " "send_codec_spec: {nack_enabled: true, transport_cc_enabled: false, " "enable_codec_fec: true, enable_opus_dtx: false, opus_max_playback_rate: " - "32000, cng_payload_type: 42, cng_plfreq: 56, codec_inst: {pltype: " - "103, plname: \"isac\", plfreq: 16000, pacsize: 320, channels: 1, rate: " - "32000}}}", + "32000, cng_payload_type: 42, cng_plfreq: 56, min_ptime: 20, max_ptime: " + "60, codec_inst: {pltype: 103, plname: \"isac\", plfreq: 16000, pacsize: " + "320, channels: 1, rate: 32000}}}", config.ToString()); } @@ -331,6 +337,10 @@ TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { stream_config.send_codec_spec.opus_max_playback_rate = 12345; stream_config.send_codec_spec.cng_plfreq = 16000; stream_config.send_codec_spec.cng_payload_type = 105; + stream_config.send_codec_spec.min_ptime_ms = 10; + stream_config.send_codec_spec.max_ptime_ms = 60; + stream_config.audio_network_adaptor_config = + rtc::Optional("abced"); EXPECT_CALL(*helper.voice_engine(), SetFECStatus(kChannelId, true)) .WillOnce(Return(0)); EXPECT_CALL( @@ -347,6 +357,13 @@ TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { kChannelId, stream_config.send_codec_spec.cng_payload_type, webrtc::kFreq16000Hz)) .WillOnce(Return(0)); + EXPECT_CALL( + *helper.channel_proxy(), + SetReceiverFrameLengthRange(stream_config.send_codec_spec.min_ptime_ms, + stream_config.send_codec_spec.max_ptime_ms)); + EXPECT_CALL( + *helper.channel_proxy(), + EnableAudioNetworkAdaptor(*stream_config.audio_network_adaptor_config)); internal::AudioSendStream send_stream( stream_config, helper.audio_state(), helper.worker_queue(), helper.congestion_controller(), helper.bitrate_allocator(), diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index afad14cd9d..dc29b9fa61 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -167,6 +167,8 @@ struct AudioOptions { SetFrom(&recording_sample_rate, change.recording_sample_rate); SetFrom(&playout_sample_rate, change.playout_sample_rate); SetFrom(&combined_audio_video_bwe, change.combined_audio_video_bwe); + SetFrom(&audio_network_adaptor, change.audio_network_adaptor); + SetFrom(&audio_network_adaptor_config, change.audio_network_adaptor_config); SetFrom(&level_control_initial_peak_level_dbfs, change.level_control_initial_peak_level_dbfs); } @@ -197,6 +199,8 @@ struct AudioOptions { recording_sample_rate == o.recording_sample_rate && playout_sample_rate == o.playout_sample_rate && combined_audio_video_bwe == o.combined_audio_video_bwe && + audio_network_adaptor == o.audio_network_adaptor && + audio_network_adaptor_config == o.audio_network_adaptor_config && level_control_initial_peak_level_dbfs == o.level_control_initial_peak_level_dbfs; } @@ -232,6 +236,11 @@ struct AudioOptions { ost << ToStringIfSet("recording_sample_rate", recording_sample_rate); ost << ToStringIfSet("playout_sample_rate", playout_sample_rate); ost << ToStringIfSet("combined_audio_video_bwe", combined_audio_video_bwe); + ost << ToStringIfSet("audio_network_adaptor", audio_network_adaptor); + // The adaptor config is a serialized proto buffer and therefore not human + // readable. So we comment out the following line. + // ost << ToStringIfSet("audio_network_adaptor_config", + // audio_network_adaptor_config); ost << "}"; return ost.str(); } @@ -274,6 +283,10 @@ struct AudioOptions { // "googCombinedAudioVideoBwe", but not used anywhere. So delete it, // and check if any other AudioOptions members are unused. rtc::Optional combined_audio_video_bwe; + // Enable audio network adaptor. + rtc::Optional audio_network_adaptor; + // Config string for audio network adaptor. + rtc::Optional audio_network_adaptor_config; private: template diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index ebcd161394..21e7c8120f 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -186,6 +186,29 @@ bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) { return codec.GetParam(feature, &value) && value == 1; } +rtc::Optional GetAudioNetworkAdaptorConfig( + const AudioOptions& options) { + if (options.audio_network_adaptor && *options.audio_network_adaptor && + options.audio_network_adaptor_config) { + // Turn on audio network adaptor only when |options_.audio_network_adaptor| + // equals true and |options_.audio_network_adaptor_config| has a value. + return options.audio_network_adaptor_config; + } + return rtc::Optional(); +} + +// Returns integer parameter params[feature] if it is defined. Returns +// |default_value| otherwise. +int GetCodecFeatureInt(const AudioCodec& codec, + const char* feature, + int default_value) { + int value = 0; + if (codec.GetParam(feature, &value)) { + return value; + } + return default_value; +} + // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate // otherwise. If the value (either from params or codec.bitrate) <=0, use the // default configuration. If the value is beyond feasible bit rate of Opus, @@ -221,29 +244,33 @@ int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { return bitrate; } -// Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not -// defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. -int GetOpusMaxPlaybackRate(const AudioCodec& codec) { - int value; - if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { - return value; - } - return kOpusDefaultMaxPlaybackRate; -} - -void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, - bool* enable_codec_fec, int* max_playback_rate, - bool* enable_codec_dtx) { +void GetOpusConfig(const AudioCodec& codec, + webrtc::CodecInst* voe_codec, + bool* enable_codec_fec, + int* max_playback_rate, + bool* enable_codec_dtx, + int* min_ptime_ms, + int* max_ptime_ms) { *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); - *max_playback_rate = GetOpusMaxPlaybackRate(codec); + *max_playback_rate = GetCodecFeatureInt(codec, kCodecParamMaxPlaybackRate, + kOpusDefaultMaxPlaybackRate); + *max_ptime_ms = + GetCodecFeatureInt(codec, kCodecParamMaxPTime, kOpusDefaultMaxPTime); + *min_ptime_ms = + GetCodecFeatureInt(codec, kCodecParamMinPTime, kOpusDefaultMinPTime); + if (*max_ptime_ms < *min_ptime_ms) { + // If min ptime or max ptime defined by codec parameter is wrong, we use + // the default values. + *max_ptime_ms = kOpusDefaultMaxPTime; + *min_ptime_ms = kOpusDefaultMinPTime; + } // If OPUS, change what we send according to the "stereo" codec // parameter, and not the "channels" parameter. We set // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If // the bitrate is not specified, i.e. is <= zero, we set it to the // appropriate default value for mono or stereo Opus. - voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); } @@ -897,7 +924,6 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { LOG_RTCERR1(SetPlayoutSampleRate, *options.playout_sample_rate); } } - return true; } @@ -1151,6 +1177,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, const std::vector& extensions, int max_send_bitrate_bps, + const rtc::Optional& audio_network_adaptor_config, webrtc::Call* call, webrtc::Transport* send_transport) : voe_audio_transport_(voe_audio_transport), @@ -1166,6 +1193,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream config_.rtp.c_name = c_name; config_.voe_channel_id = ch; config_.rtp.extensions = extensions; + config_.audio_network_adaptor_config = audio_network_adaptor_config; RecreateAudioSendStream(send_codec_spec); } @@ -1182,7 +1210,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream config_.rtp.nack.rtp_history_ms = send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0; config_.send_codec_spec = send_codec_spec_; - auto send_rate = ComputeSendBitrate( max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, send_codec_spec.codec_inst); @@ -1201,6 +1228,16 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream RecreateAudioSendStream(); } + void RecreateAudioSendStream( + const rtc::Optional& audio_network_adaptor_config) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { + return; + } + config_.audio_network_adaptor_config = audio_network_adaptor_config; + RecreateAudioSendStream(); + } + bool SetMaxSendBitrate(int bps) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); auto send_rate = @@ -1722,6 +1759,13 @@ bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { "Failed to apply engine options during channel SetOptions."; return false; } + + rtc::Optional audio_network_adatptor_config = + GetAudioNetworkAdaptorConfig(options_); + for (auto& it : send_streams_) { + it.second->RecreateAudioSendStream(audio_network_adatptor_config); + } + LOG(LS_INFO) << "Set voice channel options. Current options: " << options_.ToString(); return true; @@ -1835,7 +1879,9 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( GetOpusConfig(*codec, &send_codec_spec.codec_inst, &send_codec_spec.enable_codec_fec, &send_codec_spec.opus_max_playback_rate, - &send_codec_spec.enable_opus_dtx); + &send_codec_spec.enable_opus_dtx, + &send_codec_spec.min_ptime_ms, + &send_codec_spec.max_ptime_ms); } // Set packet size if the AudioCodec param kCodecParamPTime is set. @@ -2011,9 +2057,12 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { webrtc::AudioTransport* audio_transport = engine()->voe()->base()->audio_transport(); + rtc::Optional audio_network_adaptor_config = + GetAudioNetworkAdaptorConfig(options_); WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( channel, audio_transport, ssrc, sp.cname, send_codec_spec_, - send_rtp_extensions_, max_send_bitrate_bps_, call_, this); + send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, + call_, this); send_streams_.insert(std::make_pair(ssrc, stream)); // At this point the stream's local SSRC has been updated. If it is the first diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index aa041dda37..6aedab2e02 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -209,10 +209,15 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_TRUE(channel_->SetSendParameters(params)); } - void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source) { + void SetAudioSend(uint32_t ssrc, bool enable, cricket::AudioSource* source, + const cricket::AudioOptions* options = nullptr) { EXPECT_CALL(apm_, set_output_will_be_muted(!enable)); ASSERT_TRUE(channel_); - EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, nullptr, source)); + if (enable && options) { + EXPECT_CALL(apm_, ApplyConfig(testing::_)); + EXPECT_CALL(apm_, SetExtraOptions(testing::_)); + } + EXPECT_TRUE(channel_->SetAudioSend(ssrc, enable, options, source)); } void TestInsertDtmf(uint32_t ssrc, bool caller) { @@ -320,6 +325,10 @@ class WebRtcVoiceEngineTestFake : public testing::Test { return GetSendStreamConfig(ssrc).send_codec_spec.codec_inst.pacsize; } + const rtc::Optional& GetAudioNetworkAdaptorConfig(int32_t ssrc) { + return GetSendStreamConfig(ssrc).audio_network_adaptor_config; + } + void SetAndExpectMaxBitrate(const cricket::AudioCodec& codec, int global_max, int stream_max, @@ -2367,6 +2376,53 @@ TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) { SetSendParameters(send_parameters_); } +TEST_F(WebRtcVoiceEngineTestFake, SetAudioNetworkAdaptorViaOptions) { + EXPECT_TRUE(SetupSendStream()); + send_parameters_.options.audio_network_adaptor = rtc::Optional(true); + send_parameters_.options.audio_network_adaptor_config = + rtc::Optional("1234"); + SetSendParameters(send_parameters_); + EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config, + GetAudioNetworkAdaptorConfig(kSsrc1)); +} + +TEST_F(WebRtcVoiceEngineTestFake, AudioSendResetAudioNetworkAdaptor) { + EXPECT_TRUE(SetupSendStream()); + send_parameters_.options.audio_network_adaptor = rtc::Optional(true); + send_parameters_.options.audio_network_adaptor_config = + rtc::Optional("1234"); + SetSendParameters(send_parameters_); + EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config, + GetAudioNetworkAdaptorConfig(kSsrc1)); + const int initial_num = call_.GetNumCreatedSendStreams(); + cricket::AudioOptions options; + options.audio_network_adaptor = rtc::Optional(false); + SetAudioSend(kSsrc1, true, nullptr, &options); + // AudioSendStream expected to be recreated. + EXPECT_EQ(initial_num + 1, call_.GetNumCreatedSendStreams()); + EXPECT_EQ(rtc::Optional(), GetAudioNetworkAdaptorConfig(kSsrc1)); +} + +TEST_F(WebRtcVoiceEngineTestFake, AudioNetworkAdaptorNotGetOverridden) { + EXPECT_TRUE(SetupSendStream()); + send_parameters_.options.audio_network_adaptor = rtc::Optional(true); + send_parameters_.options.audio_network_adaptor_config = + rtc::Optional("1234"); + SetSendParameters(send_parameters_); + EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config, + GetAudioNetworkAdaptorConfig(kSsrc1)); + const int initial_num = call_.GetNumCreatedSendStreams(); + cricket::AudioOptions options; + options.audio_network_adaptor = rtc::Optional(); + // Unvalued |options.audio_network_adaptor|.should not reset audio network + // adaptor. + SetAudioSend(kSsrc1, true, nullptr, &options); + // AudioSendStream not expected to be recreated. + EXPECT_EQ(initial_num, call_.GetNumCreatedSendStreams()); + EXPECT_EQ(send_parameters_.options.audio_network_adaptor_config, + GetAudioNetworkAdaptorConfig(kSsrc1)); +} + // Test that we can set the outgoing SSRC properly. // SSRC is set in SetupSendStream() by calling AddSendStream. TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) { diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder.h b/webrtc/modules/audio_coding/codecs/audio_encoder.h index 19dc332757..2c8d9ce5ec 100644 --- a/webrtc/modules/audio_coding/codecs/audio_encoder.h +++ b/webrtc/modules/audio_coding/codecs/audio_encoder.h @@ -185,7 +185,7 @@ class AudioEncoder { virtual void OnReceivedRtt(int rtt_ms); // To allow encoder to adapt its frame length, it must be provided the frame - // length range that receives can accept. + // length range that receivers can accept. virtual void SetReceiverFrameLengthRange(int min_frame_length_ms, int max_frame_length_ms); diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h index 1847cf4711..4cbe50933b 100644 --- a/webrtc/test/mock_voe_channel_proxy.h +++ b/webrtc/test/mock_voe_channel_proxy.h @@ -60,6 +60,11 @@ class MockVoEChannelProxy : public voe::ChannelProxy { MOCK_METHOD1(SetChannelOutputVolumeScaling, void(float scaling)); MOCK_METHOD1(SetRtcEventLog, void(RtcEventLog* event_log)); MOCK_METHOD1(SetBitrate, void(int bitrate_bps)); + MOCK_METHOD1(EnableAudioNetworkAdaptor, + void(const std::string& config_string)); + MOCK_METHOD0(DisableAudioNetworkAdaptor, void()); + MOCK_METHOD2(SetReceiverFrameLengthRange, + void(int min_frame_length_ms, int max_frame_length_ms)); }; } // namespace test } // namespace webrtc diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc index 982cf1db7f..67c7fe0cb4 100644 --- a/webrtc/voice_engine/channel_proxy.cc +++ b/webrtc/voice_engine/channel_proxy.cc @@ -214,6 +214,24 @@ void ChannelProxy::SetRtcEventLog(RtcEventLog* event_log) { channel()->SetRtcEventLog(event_log); } +void ChannelProxy::EnableAudioNetworkAdaptor(const std::string& config_string) { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + bool ret = channel()->EnableAudioNetworkAdaptor(config_string); + RTC_DCHECK(ret); +;} + +void ChannelProxy::DisableAudioNetworkAdaptor() { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + channel()->DisableAudioNetworkAdaptor(); +} + +void ChannelProxy::SetReceiverFrameLengthRange(int min_frame_length_ms, + int max_frame_length_ms) { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + channel()->SetReceiverFrameLengthRange(min_frame_length_ms, + max_frame_length_ms); +} + AudioMixer::Source::AudioFrameInfo ChannelProxy::GetAudioFrameWithInfo( int sample_rate_hz, AudioFrame* audio_frame) { diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h index a9ec8604ab..8bb452ba19 100644 --- a/webrtc/voice_engine/channel_proxy.h +++ b/webrtc/voice_engine/channel_proxy.h @@ -65,34 +65,31 @@ class ChannelProxy { virtual void RegisterReceiverCongestionControlObjects( PacketRouter* packet_router); virtual void ResetCongestionControlObjects(); - virtual CallStatistics GetRTCPStatistics() const; virtual std::vector GetRemoteRTCPReportBlocks() const; virtual NetworkStatistics GetNetworkStatistics() const; virtual AudioDecodingCallStats GetDecodingCallStatistics() const; virtual int32_t GetSpeechOutputLevelFullRange() const; virtual uint32_t GetDelayEstimate() const; - virtual bool SetSendTelephoneEventPayloadType(int payload_type); virtual bool SendTelephoneEventOutband(int event, int duration_ms); virtual void SetBitrate(int bitrate_bps); virtual void SetSink(std::unique_ptr sink); virtual void SetInputMute(bool muted); - virtual void RegisterExternalTransport(Transport* transport); virtual void DeRegisterExternalTransport(); virtual bool ReceivedRTPPacket(const uint8_t* packet, size_t length, const PacketTime& packet_time); virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length); - virtual const rtc::scoped_refptr& GetAudioDecoderFactory() const; - virtual void SetChannelOutputVolumeScaling(float scaling); - virtual void SetRtcEventLog(RtcEventLog* event_log); - + virtual void EnableAudioNetworkAdaptor(const std::string& config_string); + virtual void DisableAudioNetworkAdaptor(); + virtual void SetReceiverFrameLengthRange(int min_frame_length_ms, + int max_frame_length_ms); virtual AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo( int sample_rate_hz, AudioFrame* audio_frame);