| Index: webrtc/audio/test/audio_bwe_integration_test.cc | 
| diff --git a/webrtc/audio/test/audio_bwe_integration_test.cc b/webrtc/audio/test/audio_bwe_integration_test.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..bb5d9165436382b42fcbf0c6da7f705643d14c06 | 
| --- /dev/null | 
| +++ b/webrtc/audio/test/audio_bwe_integration_test.cc | 
| @@ -0,0 +1,146 @@ | 
| +/* | 
| + *  Copyright (c) 2017 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 "webrtc/audio/test/audio_bwe_integration_test.h" | 
| + | 
| +#include "webrtc/base/ptr_util.h" | 
| +#include "webrtc/common_audio/wav_file.h" | 
| +#include "webrtc/system_wrappers/include/sleep.h" | 
| +#include "webrtc/test/field_trial.h" | 
| +#include "webrtc/test/gtest.h" | 
| +#include "webrtc/test/testsupport/fileutils.h" | 
| + | 
| +namespace webrtc { | 
| +namespace test { | 
| + | 
| +AudioBweTest::AudioBweTest() : EndToEndTest(CallTest::kDefaultTimeoutMs) {} | 
| + | 
| +size_t AudioBweTest::GetNumVideoStreams() const { | 
| +  return 0; | 
| +} | 
| +size_t AudioBweTest::GetNumAudioStreams() const { | 
| +  return 1; | 
| +} | 
| +size_t AudioBweTest::GetNumFlexfecStreams() const { | 
| +  return 0; | 
| +} | 
| + | 
| +std::unique_ptr<test::FakeAudioDevice::Capturer> | 
| +AudioBweTest::CreateCapturer() { | 
| +  return test::FakeAudioDevice::CreateWavFileReader(AudioInputFile()); | 
| +} | 
| + | 
| +void AudioBweTest::OnFakeAudioDevicesCreated( | 
| +    test::FakeAudioDevice* send_audio_device, | 
| +    test::FakeAudioDevice* recv_audio_device) { | 
| +  send_audio_device_ = send_audio_device; | 
| +} | 
| + | 
| +test::PacketTransport* AudioBweTest::CreateSendTransport(Call* sender_call) { | 
| +  return new test::PacketTransport( | 
| +      sender_call, this, test::PacketTransport::kSender, | 
| +      test::CallTest::payload_type_map_, GetNetworkPipeConfig()); | 
| +} | 
| + | 
| +test::PacketTransport* AudioBweTest::CreateReceiveTransport() { | 
| +  return new test::PacketTransport( | 
| +      nullptr, this, test::PacketTransport::kReceiver, | 
| +      test::CallTest::payload_type_map_, GetNetworkPipeConfig()); | 
| +} | 
| + | 
| +void AudioBweTest::PerformTest() { | 
| +  send_audio_device_->WaitForRecordingEnd(); | 
| +  SleepMs(GetNetworkPipeConfig().queue_delay_ms); | 
| +} | 
| + | 
| +class StatsPollTask : public rtc::QueuedTask { | 
| + public: | 
| +  explicit StatsPollTask(Call* sender_call) : sender_call_(sender_call) {} | 
| + | 
| + private: | 
| +  bool Run() override { | 
| +    RTC_CHECK(sender_call_); | 
| +    Call::Stats call_stats = sender_call_->GetStats(); | 
| +    EXPECT_GT(call_stats.send_bandwidth_bps, 30000); | 
| +    rtc::TaskQueue::Current()->PostDelayedTask( | 
| +        std::unique_ptr<QueuedTask>(this), 100); | 
| +    return false; | 
| +  } | 
| +  Call* sender_call_; | 
| +}; | 
| + | 
| +class NoBandwidthDropAfterDtx : public AudioBweTest { | 
| + public: | 
| +  NoBandwidthDropAfterDtx() | 
| +      : sender_call_(nullptr), stats_poller_("stats poller task queue") {} | 
| + | 
| +  void ModifyAudioConfigs( | 
| +      AudioSendStream::Config* send_config, | 
| +      std::vector<AudioReceiveStream::Config>* receive_configs) override { | 
| +    send_config->send_codec_spec = | 
| +        rtc::Optional<AudioSendStream::Config::SendCodecSpec>( | 
| +            {test::CallTest::kAudioSendPayloadType, | 
| +             {"OPUS", | 
| +              48000, | 
| +              2, | 
| +              {{"ptime", "60"}, {"usedtx", "1"}, {"stereo", "1"}}}}); | 
| + | 
| +    send_config->min_bitrate_bps = 6000; | 
| +    send_config->max_bitrate_bps = 100000; | 
| +    send_config->rtp.extensions.push_back( | 
| +        RtpExtension(RtpExtension::kTransportSequenceNumberUri, | 
| +                     kTransportSequenceNumberExtensionId)); | 
| +    for (AudioReceiveStream::Config& recv_config : *receive_configs) { | 
| +      recv_config.rtp.transport_cc = true; | 
| +      recv_config.rtp.extensions = send_config->rtp.extensions; | 
| +      recv_config.rtp.remote_ssrc = send_config->rtp.ssrc; | 
| +    } | 
| +  } | 
| + | 
| +  std::string AudioInputFile() override { | 
| +    return test::ResourcePath("voice_engine/audio_dtx16", "wav"); | 
| +  } | 
| + | 
| +  FakeNetworkPipe::Config GetNetworkPipeConfig() override { | 
| +    FakeNetworkPipe::Config pipe_config; | 
| +    pipe_config.link_capacity_kbps = 50; | 
| +    pipe_config.queue_length_packets = 1500; | 
| +    pipe_config.queue_delay_ms = 300; | 
| +    return pipe_config; | 
| +  } | 
| + | 
| +  void OnCallsCreated(Call* sender_call, Call* receiver_call) override { | 
| +    sender_call_ = sender_call; | 
| +  } | 
| + | 
| +  void PerformTest() override { | 
| +    stats_poller_.PostDelayedTask( | 
| +        std::unique_ptr<rtc::QueuedTask>(new StatsPollTask(sender_call_)), 100); | 
| +    sender_call_->OnTransportOverheadChanged(webrtc::MediaType::AUDIO, 0); | 
| +    AudioBweTest::PerformTest(); | 
| +  } | 
| + | 
| + private: | 
| +  Call* sender_call_; | 
| +  rtc::TaskQueue stats_poller_; | 
| +}; | 
| + | 
| +using AudioBweIntegrationTest = CallTest; | 
| + | 
| +TEST_F(AudioBweIntegrationTest, NoBandwidthDropAfterDtx) { | 
| +  webrtc::test::ScopedFieldTrials override_field_trials( | 
| +      "WebRTC-Audio-SendSideBwe/Enabled/" | 
| +      "WebRTC-SendSideBwe-WithOverhead/Enabled/"); | 
| +  NoBandwidthDropAfterDtx test; | 
| +  RunBaseTest(&test); | 
| +} | 
| + | 
| +}  // namespace test | 
| +}  // namespace webrtc | 
|  |