Creating controller manager from config string in audio network adaptor.
BUG=webrtc:6303 Review-Url: https://codereview.webrtc.org/2364403004 Cr-Commit-Position: refs/heads/master@{#14466}
This commit is contained in:
@ -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" ]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
108
webrtc/modules/audio_coding/audio_network_adaptor/config.proto
Normal file
108
webrtc/modules/audio_coding/audio_network_adaptor/config.proto
Normal file
@ -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;
|
||||
}
|
||||
@ -13,10 +13,123 @@
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
#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<FecController> 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<FecController>(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<FrameLengthController> CreateFrameLengthController(
|
||||
const audio_network_adaptor::config::FrameLengthController& config,
|
||||
rtc::ArrayView<const int> 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<int>(), 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<FrameLengthController>(
|
||||
new FrameLengthController(ctor_config));
|
||||
}
|
||||
|
||||
std::unique_ptr<ChannelController> 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<ChannelController>(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<DtxController> 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<DtxController>(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<BitrateController> CreateBitrateController(
|
||||
int initial_bitrate_bps,
|
||||
int initial_frame_length_ms) {
|
||||
return std::unique_ptr<BitrateController>(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<ControllerManager> ControllerManagerImpl::Create(
|
||||
const std::string& config_string,
|
||||
size_t num_encoder_channels,
|
||||
rtc::ArrayView<const int> 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<std::unique_ptr<Controller>> controllers;
|
||||
std::map<const Controller*, std::pair<int, float>> 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> 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<int, float>(
|
||||
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<ControllerManagerImpl>(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,
|
||||
|
||||
@ -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<ControllerManager> Create(
|
||||
const std::string& config_string,
|
||||
size_t num_encoder_channels,
|
||||
rtc::ArrayView<const int> 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.
|
||||
|
||||
@ -10,11 +10,22 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#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<int> 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<Controller*>& controllers,
|
||||
const std::vector<ControllerType>& 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<bool>(kInitialFecEnabled),
|
||||
encoder_config.enable_fec);
|
||||
break;
|
||||
case ControllerType::CHANNEL:
|
||||
EXPECT_EQ(rtc::Optional<size_t>(kIntialChannelsToEncode),
|
||||
encoder_config.num_channels);
|
||||
break;
|
||||
case ControllerType::DTX:
|
||||
EXPECT_EQ(rtc::Optional<bool>(kInitialDtxEnabled),
|
||||
encoder_config.enable_dtx);
|
||||
break;
|
||||
case ControllerType::FRAME_LENGTH:
|
||||
EXPECT_EQ(rtc::Optional<int>(kInitialFrameLengthMs),
|
||||
encoder_config.frame_length_ms);
|
||||
break;
|
||||
case ControllerType::BIT_RATE:
|
||||
EXPECT_EQ(rtc::Optional<int>(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>{
|
||||
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<int>(kChracteristicBandwithBps[0]);
|
||||
metrics.uplink_packet_loss_fraction =
|
||||
rtc::Optional<float>(kChracteristicPacketLossFraction[0]);
|
||||
|
||||
auto controllers = states.controller_manager->GetSortedControllers(metrics);
|
||||
CheckControllersOrder(controllers,
|
||||
std::vector<ControllerType>{
|
||||
ControllerType::FEC, ControllerType::FRAME_LENGTH,
|
||||
ControllerType::CHANNEL, ControllerType::DTX,
|
||||
ControllerType::BIT_RATE});
|
||||
|
||||
metrics.uplink_bandwidth_bps =
|
||||
rtc::Optional<int>(kChracteristicBandwithBps[1]);
|
||||
metrics.uplink_packet_loss_fraction =
|
||||
rtc::Optional<float>(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>{
|
||||
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>{
|
||||
ControllerType::FRAME_LENGTH, ControllerType::FEC,
|
||||
ControllerType::CHANNEL, ControllerType::DTX,
|
||||
ControllerType::BIT_RATE});
|
||||
}
|
||||
#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -34,9 +34,14 @@ class FrameLengthController final : public Controller {
|
||||
~Config();
|
||||
std::vector<int> 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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user