From 186cd0651249382e33f0f37e679428f51c9bee4f Mon Sep 17 00:00:00 2001 From: minyue Date: Fri, 16 Sep 2016 05:54:39 -0700 Subject: [PATCH] Adding DTX controller to audio network adaptor. BUG=webrtc:6303 Review-Url: https://codereview.webrtc.org/2320093002 Cr-Commit-Position: refs/heads/master@{#14260} --- webrtc/modules/BUILD.gn | 1 + webrtc/modules/audio_coding/BUILD.gn | 2 + .../audio_network_adaptor.gypi | 2 + .../audio_network_adaptor/dtx_controller.cc | 45 ++++++++++ .../audio_network_adaptor/dtx_controller.h | 45 ++++++++++ .../dtx_controller_unittest.cc | 86 +++++++++++++++++++ 6 files changed, 181 insertions(+) create mode 100644 webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.cc create mode 100644 webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h create mode 100644 webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn index 1ded309e34..89959340d9 100644 --- a/webrtc/modules/BUILD.gn +++ b/webrtc/modules/BUILD.gn @@ -248,6 +248,7 @@ if (rtc_include_tests) { "audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc", "audio_coding/audio_network_adaptor/channel_controller_unittest.cc", "audio_coding/audio_network_adaptor/controller_manager_unittest.cc", + "audio_coding/audio_network_adaptor/dtx_controller_unittest.cc", "audio_coding/audio_network_adaptor/mock/mock_controller.h", "audio_coding/audio_network_adaptor/mock/mock_controller_manager.h", "audio_coding/codecs/audio_decoder_factory_unittest.cc", diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index b25b97ab84..b6e2db3ac3 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -705,6 +705,8 @@ source_set("audio_network_adaptor") { "audio_network_adaptor/controller.h", "audio_network_adaptor/controller_manager.cc", "audio_network_adaptor/controller_manager.h", + "audio_network_adaptor/dtx_controller.cc", + "audio_network_adaptor/dtx_controller.h", "audio_network_adaptor/include/audio_network_adaptor.h", ] configs += [ "../..:common_config" ] diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi index 4538255a7b..6f20d61a72 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi +++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi @@ -20,6 +20,8 @@ 'controller.cc', 'controller_manager.cc', 'controller_manager.h', + 'dtx_controller.h', + 'dtx_controller.cc', 'include/audio_network_adaptor.h' ], # source }, diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.cc b/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.cc new file mode 100644 index 0000000000..30030d14be --- /dev/null +++ b/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 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/modules/audio_coding/audio_network_adaptor/dtx_controller.h" +#include "webrtc/base/checks.h" + +namespace webrtc { + +DtxController::Config::Config(bool initial_dtx_enabled, + int dtx_enabling_bandwidth_bps, + int dtx_disabling_bandwidth_bps) + : initial_dtx_enabled(initial_dtx_enabled), + dtx_enabling_bandwidth_bps(dtx_enabling_bandwidth_bps), + dtx_disabling_bandwidth_bps(dtx_disabling_bandwidth_bps) {} + +DtxController::DtxController(const Config& config) + : config_(config), dtx_enabled_(config_.initial_dtx_enabled) {} + +void DtxController::MakeDecision( + const NetworkMetrics& metrics, + AudioNetworkAdaptor::EncoderRuntimeConfig* config) { + // Decision on |enable_dtx| should not have been made. + RTC_DCHECK(!config->enable_dtx); + + if (metrics.uplink_bandwidth_bps) { + if (dtx_enabled_ && + *metrics.uplink_bandwidth_bps >= config_.dtx_disabling_bandwidth_bps) { + dtx_enabled_ = false; + } else if (!dtx_enabled_ && + *metrics.uplink_bandwidth_bps <= + config_.dtx_enabling_bandwidth_bps) { + dtx_enabled_ = true; + } + } + config->enable_dtx = rtc::Optional(dtx_enabled_); +} + +} // namespace webrtc diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h new file mode 100644 index 0000000000..bb8faf45d8 --- /dev/null +++ b/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 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 WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_ + +#include "webrtc/base/constructormagic.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h" + +namespace webrtc { + +class DtxController final : public Controller { + public: + struct Config { + Config(bool initial_dtx_enabled, + int dtx_enabling_bandwidth_bps, + int dtx_disabling_bandwidth_bps); + bool initial_dtx_enabled; + // Uplink bandwidth below which DTX should be switched on. + int dtx_enabling_bandwidth_bps; + // Uplink bandwidth above which DTX should be switched off. + int dtx_disabling_bandwidth_bps; + }; + + explicit DtxController(const Config& config); + + void MakeDecision(const NetworkMetrics& metrics, + AudioNetworkAdaptor::EncoderRuntimeConfig* config) override; + + private: + const Config config_; + bool dtx_enabled_; + RTC_DISALLOW_COPY_AND_ASSIGN(DtxController); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DTX_CONTROLLER_H_ diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc new file mode 100644 index 0000000000..e8fda9efe0 --- /dev/null +++ b/webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller_unittest.cc @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016 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 + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h" + +namespace webrtc { + +namespace { + +constexpr int kDtxEnablingBandwidthBps = 55000; +constexpr int kDtxDisablingBandwidthBps = 65000; +constexpr int kMediumBandwidthBps = + (kDtxEnablingBandwidthBps + kDtxDisablingBandwidthBps) / 2; + +std::unique_ptr CreateController(int initial_dtx_enabled) { + std::unique_ptr controller(new DtxController( + DtxController::Config(initial_dtx_enabled, kDtxEnablingBandwidthBps, + kDtxDisablingBandwidthBps))); + return controller; +} + +void CheckDecision(DtxController* controller, + const rtc::Optional& uplink_bandwidth_bps, + bool expected_dtx_enabled) { + AudioNetworkAdaptor::EncoderRuntimeConfig config; + Controller::NetworkMetrics metrics; + metrics.uplink_bandwidth_bps = uplink_bandwidth_bps; + controller->MakeDecision(metrics, &config); + EXPECT_EQ(rtc::Optional(expected_dtx_enabled), config.enable_dtx); +} + +} // namespace + +TEST(DtxControllerTest, OutputInitValueWhenUplinkBandwidthUnknown) { + constexpr bool kInitialDtxEnabled = true; + auto controller = CreateController(kInitialDtxEnabled); + CheckDecision(controller.get(), rtc::Optional(), kInitialDtxEnabled); +} + +TEST(DtxControllerTest, TurnOnDtxForLowUplinkBandwidth) { + auto controller = CreateController(false); + CheckDecision(controller.get(), rtc::Optional(kDtxEnablingBandwidthBps), + true); +} + +TEST(DtxControllerTest, TurnOffDtxForHighUplinkBandwidth) { + auto controller = CreateController(true); + CheckDecision(controller.get(), rtc::Optional(kDtxDisablingBandwidthBps), + false); +} + +TEST(DtxControllerTest, MaintainDtxOffForMediumUplinkBandwidth) { + auto controller = CreateController(false); + CheckDecision(controller.get(), rtc::Optional(kMediumBandwidthBps), + false); +} + +TEST(DtxControllerTest, MaintainDtxOnForMediumUplinkBandwidth) { + auto controller = CreateController(true); + CheckDecision(controller.get(), rtc::Optional(kMediumBandwidthBps), + true); +} + +TEST(DtxControllerTest, CheckBehaviorOnChangingUplinkBandwidth) { + auto controller = CreateController(false); + CheckDecision(controller.get(), rtc::Optional(kMediumBandwidthBps), + false); + CheckDecision(controller.get(), rtc::Optional(kDtxEnablingBandwidthBps), + true); + CheckDecision(controller.get(), rtc::Optional(kMediumBandwidthBps), + true); + CheckDecision(controller.get(), rtc::Optional(kDtxDisablingBandwidthBps), + false); +} + +} // namespace webrtc