diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn index b3bfbac46f..86d46b730f 100644 --- a/webrtc/modules/BUILD.gn +++ b/webrtc/modules/BUILD.gn @@ -254,6 +254,10 @@ if (rtc_include_tests) { "//testing/gmock", "//testing/gtest", ] + if (rtc_enable_protobuf) { + deps += [ "audio_coding:ana_config_proto" ] + defines = [ "WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP" ] + } if (is_clang) { # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163). suppressed_configs += [ "//build/config/clang:find_bad_constructs" ] diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index bafeffb6a7..ef5ea96be2 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -701,6 +701,12 @@ if (rtc_enable_protobuf) { ] proto_out_dir = "webrtc/modules/audio_coding/audio_network_adaptor" } + proto_library("ana_config_proto") { + sources = [ + "audio_network_adaptor/config.proto", + ] + proto_out_dir = "webrtc/modules/audio_coding/audio_network_adaptor" + } } source_set("audio_network_adaptor") { @@ -733,6 +739,7 @@ source_set("audio_network_adaptor") { if (rtc_enable_protobuf) { deps = [ + ":ana_config_proto", ":ana_debug_dump_proto", ] defines = [ "WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP" ] 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 f29992d13d..7750276563 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 @@ -36,7 +36,10 @@ ], # sources 'conditions': [ ['enable_protobuf==1', { - 'dependencies': ['ana_debug_dump_proto'], + 'dependencies': [ + 'ana_config_proto', + 'ana_debug_dump_proto', + ], 'defines': ['WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP'], }], ], # conditions @@ -58,6 +61,18 @@ }, 'includes': ['../../../build/protoc.gypi',], }, + { 'target_name': 'ana_config_proto', + 'type': 'static_library', + 'sources': ['config.proto',], + 'variables': { + 'proto_in_dir': '.', + # Workaround to protect against gyp's pathname relativization when + # this file is included by modules.gyp. + 'proto_out_protected': 'webrtc/modules/audio_coding/audio_network_adaptor', + 'proto_out_dir': '<(proto_out_protected)', + }, + 'includes': ['../../../build/protoc.gypi',], + }, ], # targets }], ], # conditions diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.h index a8068db7b4..f363d3f3df 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.h @@ -20,7 +20,7 @@ namespace audio_network_adaptor { class BitrateController final : public Controller { public: struct Config { - Config(int initial_bitrate_bps, int frame_length_ms); + Config(int initial_bitrate_bps, int initial_frame_length_ms); ~Config(); int initial_bitrate_bps; int initial_frame_length_ms; diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/config.proto b/webrtc/modules/audio_coding/audio_network_adaptor/config.proto new file mode 100644 index 0000000000..3c678fc1b6 --- /dev/null +++ b/webrtc/modules/audio_coding/audio_network_adaptor/config.proto @@ -0,0 +1,108 @@ +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; +package webrtc.audio_network_adaptor.config; + +message FecController { + message Threshold { + // Threshold defines a curve in the bandwidth/packet-loss domain. The + // curve is characterized by the two conjunction points: A and B. + // + // packet ^ | + // loss | A| + // | \ A: (low_bandwidth_bps, low_bandwidth_packet_loss) + // | \ B: (high_bandwidth_bps, high_bandwidth_packet_loss) + // | B\________ + // |---------------> bandwidth + optional int32 low_bandwidth_bps = 1; + optional float low_bandwidth_packet_loss = 2; + optional int32 high_bandwidth_bps = 3; + optional float high_bandwidth_packet_loss = 4; + } + + // |fec_enabling_threshold| defines a curve, above which FEC should be + // enabled. |fec_disabling_threshold| defines a curve, under which FEC + // should be disabled. See below + // + // packet-loss ^ | | + // | | | FEC + // | \ \ ON + // | FEC \ \_______ fec_enabling_threshold + // | OFF \_________ fec_disabling_threshold + // |-----------------> bandwidth + optional Threshold fec_enabling_threshold = 1; + optional Threshold fec_disabling_threshold = 2; + + // |time_constant_ms| is the time constant for an exponential filter, which + // is used for smoothing the packet loss fraction. + optional int32 time_constant_ms = 3; +} + +message FrameLengthController { + // Uplink packet loss fraction below which frame length can increase. + optional float fl_increasing_packet_loss_fraction = 1; + + // Uplink packet loss fraction below which frame length should decrease. + optional float fl_decreasing_packet_loss_fraction = 2; + + // Uplink bandwidth below which frame length can switch from 20ms to 60ms. + optional int32 fl_20ms_to_60ms_bandwidth_bps = 3; + + // Uplink bandwidth above which frame length should switch from 60ms to 20ms. + optional int32 fl_60ms_to_20ms_bandwidth_bps = 4; +} + +message ChannelController { + // Uplink bandwidth above which the number of encoded channels should switch + // from 1 to 2. + optional int32 channel_1_to_2_bandwidth_bps = 1; + + // Uplink bandwidth below which the number of encoded channels should switch + // from 2 to 1. + optional int32 channel_2_to_1_bandwidth_bps = 2; +} + +message DtxController { + // Uplink bandwidth below which DTX should be switched on. + optional int32 dtx_enabling_bandwidth_bps = 1; + + // Uplink bandwidth above which DTX should be switched off. + optional int32 dtx_disabling_bandwidth_bps = 2; +} + +message BitrateController {} + +message Controller { + message ScoringPoint { + // |ScoringPoint| is a subspace of network condition. It is used for + // comparing the significance of controllers. + optional int32 uplink_bandwidth_bps = 1; + optional float uplink_packet_loss_fraction = 2; + } + + // The distance from |scoring_point| to a given network condition defines + // the significance of this controller with respect that network condition. + // Shorter distance means higher significance. The significances of + // controllers determine their order in the processing pipeline. Controllers + // without |scoring_point| follow their default order in + // |ControllerManager::controllers|. + optional ScoringPoint scoring_point = 1; + + oneof controller { + FecController fec_controller = 21; + FrameLengthController frame_length_controller = 22; + ChannelController channel_controller = 23; + DtxController dtx_controller = 24; + BitrateController bitrate_controller = 25; + } +} + +message ControllerManager { + repeated Controller controllers = 1; + + // Least time since last reordering for a new reordering to be made. + optional int32 min_reordering_time_ms = 2; + + // Least squared distance from last scoring point for a new reordering to be + // made. + optional float min_reordering_squared_distance = 3; +} \ No newline at end of file diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc index 9f05b7e735..5343acebd8 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc @@ -13,10 +13,123 @@ #include #include +#include "webrtc/base/ignore_wundef.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/bitrate_controller.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/channel_controller.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/dtx_controller.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h" +#include "webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h" #include "webrtc/system_wrappers/include/clock.h" +#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP +RTC_PUSH_IGNORING_WUNDEF() +#ifdef WEBRTC_ANDROID_PLATFORM_BUILD +#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h" +#else +#include "webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h" +#endif +RTC_POP_IGNORING_WUNDEF() +#endif + namespace webrtc { +namespace { + +#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP + +std::unique_ptr CreateFecController( + const audio_network_adaptor::config::FecController& config, + bool initial_fec_enabled, + const Clock* clock) { + RTC_CHECK(config.has_fec_enabling_threshold()); + RTC_CHECK(config.has_fec_disabling_threshold()); + RTC_CHECK(config.has_time_constant_ms()); + + auto& fec_enabling_threshold = config.fec_enabling_threshold(); + RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_bps()); + RTC_CHECK(fec_enabling_threshold.has_low_bandwidth_packet_loss()); + RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_bps()); + RTC_CHECK(fec_enabling_threshold.has_high_bandwidth_packet_loss()); + + auto& fec_disabling_threshold = config.fec_disabling_threshold(); + RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_bps()); + RTC_CHECK(fec_disabling_threshold.has_low_bandwidth_packet_loss()); + RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_bps()); + RTC_CHECK(fec_disabling_threshold.has_high_bandwidth_packet_loss()); + + return std::unique_ptr(new FecController(FecController::Config( + initial_fec_enabled, + FecController::Config::Threshold( + fec_enabling_threshold.low_bandwidth_bps(), + fec_enabling_threshold.low_bandwidth_packet_loss(), + fec_enabling_threshold.high_bandwidth_bps(), + fec_enabling_threshold.high_bandwidth_packet_loss()), + FecController::Config::Threshold( + fec_disabling_threshold.low_bandwidth_bps(), + fec_disabling_threshold.low_bandwidth_packet_loss(), + fec_disabling_threshold.high_bandwidth_bps(), + fec_disabling_threshold.high_bandwidth_packet_loss()), + config.has_time_constant_ms(), clock))); +} + +std::unique_ptr CreateFrameLengthController( + const audio_network_adaptor::config::FrameLengthController& config, + rtc::ArrayView encoder_frame_lengths_ms, + int initial_frame_length_ms) { + RTC_CHECK(config.has_fl_increasing_packet_loss_fraction()); + RTC_CHECK(config.has_fl_decreasing_packet_loss_fraction()); + RTC_CHECK(config.has_fl_20ms_to_60ms_bandwidth_bps()); + RTC_CHECK(config.has_fl_60ms_to_20ms_bandwidth_bps()); + + FrameLengthController::Config ctor_config( + std::vector(), initial_frame_length_ms, + config.fl_increasing_packet_loss_fraction(), + config.fl_decreasing_packet_loss_fraction(), + config.fl_20ms_to_60ms_bandwidth_bps(), + config.fl_60ms_to_20ms_bandwidth_bps()); + + for (auto frame_length : encoder_frame_lengths_ms) + ctor_config.encoder_frame_lengths_ms.push_back(frame_length); + + return std::unique_ptr( + new FrameLengthController(ctor_config)); +} + +std::unique_ptr CreateChannelController( + const audio_network_adaptor::config::ChannelController& config, + size_t num_encoder_channels, + size_t intial_channels_to_encode) { + RTC_CHECK(config.has_channel_1_to_2_bandwidth_bps()); + RTC_CHECK(config.has_channel_2_to_1_bandwidth_bps()); + + return std::unique_ptr(new ChannelController( + ChannelController::Config(num_encoder_channels, intial_channels_to_encode, + config.channel_1_to_2_bandwidth_bps(), + config.channel_2_to_1_bandwidth_bps()))); +} + +std::unique_ptr CreateDtxController( + const audio_network_adaptor::config::DtxController& dtx_config, + bool initial_dtx_enabled) { + RTC_CHECK(dtx_config.has_dtx_enabling_bandwidth_bps()); + RTC_CHECK(dtx_config.has_dtx_disabling_bandwidth_bps()); + + return std::unique_ptr(new DtxController(DtxController::Config( + initial_dtx_enabled, dtx_config.dtx_enabling_bandwidth_bps(), + dtx_config.dtx_disabling_bandwidth_bps()))); +} + +using audio_network_adaptor::BitrateController; +std::unique_ptr CreateBitrateController( + int initial_bitrate_bps, + int initial_frame_length_ms) { + return std::unique_ptr(new BitrateController( + BitrateController::Config(initial_bitrate_bps, initial_frame_length_ms))); +} +#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP + +} // namespace + ControllerManagerImpl::Config::Config(int min_reordering_time_ms, float min_reordering_squared_distance, const Clock* clock) @@ -26,6 +139,76 @@ ControllerManagerImpl::Config::Config(int min_reordering_time_ms, ControllerManagerImpl::Config::~Config() = default; +std::unique_ptr ControllerManagerImpl::Create( + const std::string& config_string, + size_t num_encoder_channels, + rtc::ArrayView encoder_frame_lengths_ms, + size_t intial_channels_to_encode, + int initial_frame_length_ms, + int initial_bitrate_bps, + bool initial_fec_enabled, + bool initial_dtx_enabled, + const Clock* clock) { +#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP + audio_network_adaptor::config::ControllerManager controller_manager_config; + controller_manager_config.ParseFromString(config_string); + + std::vector> controllers; + std::map> chracteristic_points; + + for (int i = 0; i < controller_manager_config.controllers_size(); ++i) { + auto& controller_config = controller_manager_config.controllers(i); + std::unique_ptr controller; + switch (controller_config.controller_case()) { + case audio_network_adaptor::config::Controller::kFecController: + controller = CreateFecController(controller_config.fec_controller(), + initial_fec_enabled, clock); + break; + case audio_network_adaptor::config::Controller::kFrameLengthController: + controller = CreateFrameLengthController( + controller_config.frame_length_controller(), + encoder_frame_lengths_ms, initial_frame_length_ms); + break; + case audio_network_adaptor::config::Controller::kChannelController: + controller = CreateChannelController( + controller_config.channel_controller(), num_encoder_channels, + intial_channels_to_encode); + break; + case audio_network_adaptor::config::Controller::kDtxController: + controller = CreateDtxController(controller_config.dtx_controller(), + initial_dtx_enabled); + break; + case audio_network_adaptor::config::Controller::kBitrateController: + controller = CreateBitrateController(initial_bitrate_bps, + initial_frame_length_ms); + break; + default: + RTC_NOTREACHED(); + } + if (controller_config.has_scoring_point()) { + auto& characteristic_point = controller_config.scoring_point(); + RTC_CHECK(characteristic_point.has_uplink_bandwidth_bps()); + RTC_CHECK(characteristic_point.has_uplink_packet_loss_fraction()); + chracteristic_points[controller.get()] = std::make_pair( + characteristic_point.uplink_bandwidth_bps(), + characteristic_point.uplink_packet_loss_fraction()); + } + controllers.push_back(std::move(controller)); + } + + RTC_CHECK(controller_manager_config.has_min_reordering_time_ms()); + RTC_CHECK(controller_manager_config.has_min_reordering_squared_distance()); + return std::unique_ptr(new ControllerManagerImpl( + ControllerManagerImpl::Config( + controller_manager_config.min_reordering_time_ms(), + controller_manager_config.min_reordering_squared_distance(), clock), + std::move(controllers), chracteristic_points)); +#else + RTC_NOTREACHED(); + return nullptr; +#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP +} + ControllerManagerImpl::ControllerManagerImpl(const Config& config) : ControllerManagerImpl( config, diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h index c2ac9e35ef..806042e501 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h @@ -40,11 +40,25 @@ class ControllerManagerImpl final : public ControllerManager { float min_reordering_squared_distance, const Clock* clock); ~Config(); + // Least time since last reordering for a new reordering to be made. int min_reordering_time_ms; + // Least squared distance from last scoring point for a new reordering to be + // made. float min_reordering_squared_distance; const Clock* clock; }; + static std::unique_ptr Create( + const std::string& config_string, + size_t num_encoder_channels, + rtc::ArrayView encoder_frame_lengths_ms, + size_t intial_channels_to_encode, + int initial_frame_length_ms, + int initial_bitrate_bps, + bool initial_fec_enabled, + bool initial_dtx_enabled, + const Clock* clock); + explicit ControllerManagerImpl(const Config& config); // Dependency injection for testing. diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc index a1759109b9..414aabf604 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc @@ -10,11 +10,22 @@ #include +#include "webrtc/base/ignore_wundef.h" #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h" #include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h" #include "webrtc/system_wrappers/include/clock.h" #include "webrtc/test/gtest.h" +#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP +RTC_PUSH_IGNORING_WUNDEF() +#ifdef WEBRTC_ANDROID_PLATFORM_BUILD +#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h" +#else +#include "webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h" +#endif +RTC_POP_IGNORING_WUNDEF() +#endif + namespace webrtc { using ::testing::NiceMock; @@ -190,4 +201,220 @@ TEST(ControllerManagerTest, DoNotReorderIfNetworkMetricsChangeTooSmall) { {kNumControllers - 2, kNumControllers - 1, 0, 1}); } +#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP + +namespace { + +void AddBitrateControllerConfig( + audio_network_adaptor::config::ControllerManager* config) { + config->add_controllers()->mutable_bitrate_controller(); +} + +void AddChannelControllerConfig( + audio_network_adaptor::config::ControllerManager* config) { + auto controller_config = + config->add_controllers()->mutable_channel_controller(); + controller_config->set_channel_1_to_2_bandwidth_bps(31000); + controller_config->set_channel_2_to_1_bandwidth_bps(29000); +} + +void AddDtxControllerConfig( + audio_network_adaptor::config::ControllerManager* config) { + auto controller_config = config->add_controllers()->mutable_dtx_controller(); + controller_config->set_dtx_enabling_bandwidth_bps(55000); + controller_config->set_dtx_disabling_bandwidth_bps(65000); +} + +void AddFecControllerConfig( + audio_network_adaptor::config::ControllerManager* config) { + auto controller_config_ext = config->add_controllers(); + auto controller_config = controller_config_ext->mutable_fec_controller(); + auto fec_enabling_threshold = + controller_config->mutable_fec_enabling_threshold(); + fec_enabling_threshold->set_low_bandwidth_bps(17000); + fec_enabling_threshold->set_low_bandwidth_packet_loss(0.1f); + fec_enabling_threshold->set_high_bandwidth_bps(64000); + fec_enabling_threshold->set_high_bandwidth_packet_loss(0.05f); + auto fec_disabling_threshold = + controller_config->mutable_fec_disabling_threshold(); + fec_disabling_threshold->set_low_bandwidth_bps(15000); + fec_disabling_threshold->set_low_bandwidth_packet_loss(0.08f); + fec_disabling_threshold->set_high_bandwidth_bps(64000); + fec_disabling_threshold->set_high_bandwidth_packet_loss(0.01f); + controller_config->set_time_constant_ms(500); + + auto scoring_point = controller_config_ext->mutable_scoring_point(); + scoring_point->set_uplink_bandwidth_bps(kChracteristicBandwithBps[0]); + scoring_point->set_uplink_packet_loss_fraction( + kChracteristicPacketLossFraction[0]); +} + +void AddFrameLengthControllerConfig( + audio_network_adaptor::config::ControllerManager* config) { + auto controller_config_ext = config->add_controllers(); + auto controller_config = + controller_config_ext->mutable_frame_length_controller(); + controller_config->set_fl_decreasing_packet_loss_fraction(0.05f); + controller_config->set_fl_increasing_packet_loss_fraction(0.04f); + controller_config->set_fl_20ms_to_60ms_bandwidth_bps(72000); + controller_config->set_fl_60ms_to_20ms_bandwidth_bps(88000); + + auto scoring_point = controller_config_ext->mutable_scoring_point(); + scoring_point->set_uplink_bandwidth_bps(kChracteristicBandwithBps[1]); + scoring_point->set_uplink_packet_loss_fraction( + kChracteristicPacketLossFraction[1]); +} + +constexpr int kInitialBitrateBps = 24000; +constexpr size_t kIntialChannelsToEncode = 1; +constexpr bool kInitialDtxEnabled = true; +constexpr bool kInitialFecEnabled = true; +constexpr int kInitialFrameLengthMs = 60; + +ControllerManagerStates CreateControllerManager( + const std::string& config_string) { + ControllerManagerStates states; + states.simulated_clock.reset(new SimulatedClock(kClockInitialTime)); + constexpr size_t kNumEncoderChannels = 2; + const std::vector encoder_frame_lengths_ms = {20, 60}; + states.controller_manager = ControllerManagerImpl::Create( + config_string, kNumEncoderChannels, encoder_frame_lengths_ms, + kIntialChannelsToEncode, kInitialFrameLengthMs, kInitialBitrateBps, + kInitialFecEnabled, kInitialDtxEnabled, states.simulated_clock.get()); + return states; +} + +enum class ControllerType : int8_t { + FEC, + CHANNEL, + DTX, + FRAME_LENGTH, + BIT_RATE +}; + +void CheckControllersOrder(const std::vector& controllers, + const std::vector& expected_types) { + ASSERT_EQ(expected_types.size(), controllers.size()); + + // We also check that the controllers follow the initial settings. + AudioNetworkAdaptor::EncoderRuntimeConfig encoder_config; + + // We do not check the internal logic of controllers. We only check that + // when no network metrics are known, controllers provide the initial values. + Controller::NetworkMetrics metrics; + + for (size_t i = 0; i < controllers.size(); ++i) { + AudioNetworkAdaptor::EncoderRuntimeConfig encoder_config; + // We check the order of |controllers| by judging their decisions. + controllers[i]->MakeDecision(metrics, &encoder_config); + switch (expected_types[i]) { + case ControllerType::FEC: + EXPECT_EQ(rtc::Optional(kInitialFecEnabled), + encoder_config.enable_fec); + break; + case ControllerType::CHANNEL: + EXPECT_EQ(rtc::Optional(kIntialChannelsToEncode), + encoder_config.num_channels); + break; + case ControllerType::DTX: + EXPECT_EQ(rtc::Optional(kInitialDtxEnabled), + encoder_config.enable_dtx); + break; + case ControllerType::FRAME_LENGTH: + EXPECT_EQ(rtc::Optional(kInitialFrameLengthMs), + encoder_config.frame_length_ms); + break; + case ControllerType::BIT_RATE: + EXPECT_EQ(rtc::Optional(kInitialBitrateBps), + encoder_config.bitrate_bps); + } + } +} + +} // namespace + +TEST(ControllerManagerTest, CreateFromConfigStringAndCheckDefaultOrder) { + audio_network_adaptor::config::ControllerManager config; + config.set_min_reordering_time_ms(kMinReorderingTimeMs); + config.set_min_reordering_squared_distance(kMinReorderingSquareDistance); + + AddFecControllerConfig(&config); + AddChannelControllerConfig(&config); + AddDtxControllerConfig(&config); + AddFrameLengthControllerConfig(&config); + AddBitrateControllerConfig(&config); + + std::string config_string; + config.SerializeToString(&config_string); + + auto states = CreateControllerManager(config_string); + Controller::NetworkMetrics metrics; + + auto controllers = states.controller_manager->GetSortedControllers(metrics); + CheckControllersOrder( + controllers, + std::vector{ + ControllerType::FEC, ControllerType::CHANNEL, ControllerType::DTX, + ControllerType::FRAME_LENGTH, ControllerType::BIT_RATE}); +} + +TEST(ControllerManagerTest, CreateFromConfigStringAndCheckReordering) { + audio_network_adaptor::config::ControllerManager config; + config.set_min_reordering_time_ms(kMinReorderingTimeMs); + config.set_min_reordering_squared_distance(kMinReorderingSquareDistance); + + AddChannelControllerConfig(&config); + + // Internally associated with characteristic point 0. + AddFecControllerConfig(&config); + + AddDtxControllerConfig(&config); + + // Internally associated with characteristic point 1. + AddFrameLengthControllerConfig(&config); + + AddBitrateControllerConfig(&config); + + std::string config_string; + config.SerializeToString(&config_string); + + auto states = CreateControllerManager(config_string); + + Controller::NetworkMetrics metrics; + metrics.uplink_bandwidth_bps = + rtc::Optional(kChracteristicBandwithBps[0]); + metrics.uplink_packet_loss_fraction = + rtc::Optional(kChracteristicPacketLossFraction[0]); + + auto controllers = states.controller_manager->GetSortedControllers(metrics); + CheckControllersOrder(controllers, + std::vector{ + ControllerType::FEC, ControllerType::FRAME_LENGTH, + ControllerType::CHANNEL, ControllerType::DTX, + ControllerType::BIT_RATE}); + + metrics.uplink_bandwidth_bps = + rtc::Optional(kChracteristicBandwithBps[1]); + metrics.uplink_packet_loss_fraction = + rtc::Optional(kChracteristicPacketLossFraction[1]); + states.simulated_clock->AdvanceTimeMilliseconds(kMinReorderingTimeMs - 1); + controllers = states.controller_manager->GetSortedControllers(metrics); + // Should not reorder since min reordering time is not met. + CheckControllersOrder(controllers, + std::vector{ + ControllerType::FEC, ControllerType::FRAME_LENGTH, + ControllerType::CHANNEL, ControllerType::DTX, + ControllerType::BIT_RATE}); + + states.simulated_clock->AdvanceTimeMilliseconds(1); + controllers = states.controller_manager->GetSortedControllers(metrics); + // Reorder now. + CheckControllersOrder(controllers, + std::vector{ + ControllerType::FRAME_LENGTH, ControllerType::FEC, + ControllerType::CHANNEL, ControllerType::DTX, + ControllerType::BIT_RATE}); +} +#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP + } // namespace webrtc diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc b/webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc index a2f258b766..7770e65a26 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc @@ -63,7 +63,7 @@ class DebugDumpWriterImpl final : public DebugDumpWriter { DebugDumpWriterImpl::DebugDumpWriterImpl(FILE* file_handle) : dump_file_(FileWrapper::Create()) { #ifndef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP - RTC_DCHECK(false); + RTC_NOTREACHED(); #endif dump_file_->OpenFromFileHandle(file_handle); RTC_CHECK(dump_file_->is_open()); diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.cc b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.cc index fcf19590f6..07495f0f85 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.cc @@ -30,7 +30,7 @@ FecController::Config::Config(bool initial_fec_enabled, const Threshold& fec_enabling_threshold, const Threshold& fec_disabling_threshold, int time_constant_ms, - Clock* clock) + const Clock* clock) : initial_fec_enabled(initial_fec_enabled), fec_enabling_threshold(fec_enabling_threshold), fec_disabling_threshold(fec_disabling_threshold), diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h index 17aa65f1e6..0c2388b2c6 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h @@ -56,12 +56,12 @@ class FecController final : public Controller { const Threshold& fec_enabling_threshold, const Threshold& fec_disabling_threshold, int time_constant_ms, - Clock* clock); + const Clock* clock); bool initial_fec_enabled; Threshold fec_enabling_threshold; Threshold fec_disabling_threshold; int time_constant_ms; - Clock* clock; + const Clock* clock; }; explicit FecController(const Config& config); diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h index 82baa60b8f..d19710254d 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/frame_length_controller.h @@ -34,9 +34,14 @@ class FrameLengthController final : public Controller { ~Config(); std::vector encoder_frame_lengths_ms; int initial_frame_length_ms; + // Uplink packet loss fraction below which frame length can increase. float fl_increasing_packet_loss_fraction; + // Uplink packet loss fraction below which frame length should decrease. float fl_decreasing_packet_loss_fraction; + // Uplink bandwidth below which frame length can switch from 20ms to 60ms. int fl_20ms_to_60ms_bandwidth_bps; + // Uplink bandwidth above which frame length should switch from 60ms to + // 20ms. int fl_60ms_to_20ms_bandwidth_bps; };