Add 120ms frame ability to ANA

BUG=webrtc:7093

Review-Url: https://codereview.webrtc.org/2669733002
Cr-Commit-Position: refs/heads/master@{#16416}
This commit is contained in:
michaelt
2017-02-02 07:47:19 -08:00
committed by Commit bot
parent ed01647ea9
commit a55f021d43
8 changed files with 123 additions and 91 deletions

View File

@ -850,7 +850,7 @@ rtc_static_library("webrtc_opus") {
":webrtc_opus_c",
]
defines = []
defines = audio_codec_defines
if (rtc_opus_variable_complexity) {
defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=1" ]
} else {

View File

@ -51,6 +51,12 @@ message FrameLengthController {
// Uplink bandwidth above which frame length should switch from 60ms to 20ms.
optional int32 fl_60ms_to_20ms_bandwidth_bps = 4;
// Uplink bandwidth below which frame length can switch from 60ms to 120ms.
optional int32 fl_60ms_to_120ms_bandwidth_bps = 5;
// Uplink bandwidth above which frame length should switch from 120ms to 60ms.
optional int32 fl_120ms_to_60ms_bandwidth_bps = 6;
}
message ChannelController {

View File

@ -81,12 +81,28 @@ std::unique_ptr<FrameLengthController> CreateFrameLengthController(
RTC_CHECK(config.has_fl_20ms_to_60ms_bandwidth_bps());
RTC_CHECK(config.has_fl_60ms_to_20ms_bandwidth_bps());
std::map<FrameLengthController::Config::FrameLengthChange, int>
fl_changing_bandwidths_bps = {
{FrameLengthController::Config::FrameLengthChange(20, 60),
config.fl_20ms_to_60ms_bandwidth_bps()},
{FrameLengthController::Config::FrameLengthChange(60, 20),
config.fl_60ms_to_20ms_bandwidth_bps()}};
if (config.has_fl_60ms_to_120ms_bandwidth_bps() &&
config.has_fl_120ms_to_60ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(std::make_pair(
FrameLengthController::Config::FrameLengthChange(60, 120),
config.fl_60ms_to_120ms_bandwidth_bps()));
fl_changing_bandwidths_bps.insert(std::make_pair(
FrameLengthController::Config::FrameLengthChange(120, 60),
config.fl_120ms_to_60ms_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());
std::move(fl_changing_bandwidths_bps));
for (auto frame_length : encoder_frame_lengths_ms)
ctor_config.encoder_frame_lengths_ms.push_back(frame_length);

View File

@ -22,14 +22,12 @@ FrameLengthController::Config::Config(
int initial_frame_length_ms,
float fl_increasing_packet_loss_fraction,
float fl_decreasing_packet_loss_fraction,
int fl_20ms_to_60ms_bandwidth_bps,
int fl_60ms_to_20ms_bandwidth_bps)
std::map<FrameLengthChange, int> fl_changing_bandwidths_bps)
: encoder_frame_lengths_ms(encoder_frame_lengths_ms),
initial_frame_length_ms(initial_frame_length_ms),
fl_increasing_packet_loss_fraction(fl_increasing_packet_loss_fraction),
fl_decreasing_packet_loss_fraction(fl_decreasing_packet_loss_fraction),
fl_20ms_to_60ms_bandwidth_bps(fl_20ms_to_60ms_bandwidth_bps),
fl_60ms_to_20ms_bandwidth_bps(fl_60ms_to_20ms_bandwidth_bps) {}
fl_changing_bandwidths_bps(std::move(fl_changing_bandwidths_bps)) {}
FrameLengthController::Config::Config(const Config& other) = default;
@ -42,11 +40,6 @@ FrameLengthController::FrameLengthController(const Config& config)
config_.initial_frame_length_ms);
// |encoder_frame_lengths_ms| must contain |initial_frame_length_ms|.
RTC_DCHECK(frame_length_ms_ != config_.encoder_frame_lengths_ms.end());
frame_length_change_criteria_.insert(std::make_pair(
FrameLengthChange(20, 60), config_.fl_20ms_to_60ms_bandwidth_bps));
frame_length_change_criteria_.insert(std::make_pair(
FrameLengthChange(60, 20), config_.fl_60ms_to_20ms_bandwidth_bps));
}
FrameLengthController::~FrameLengthController() = default;
@ -72,15 +65,13 @@ void FrameLengthController::MakeDecision(
config->frame_length_ms = rtc::Optional<int>(*frame_length_ms_);
}
FrameLengthController::FrameLengthChange::FrameLengthChange(
FrameLengthController::Config::FrameLengthChange::FrameLengthChange(
int from_frame_length_ms,
int to_frame_length_ms)
: from_frame_length_ms(from_frame_length_ms),
to_frame_length_ms(to_frame_length_ms) {}
FrameLengthController::FrameLengthChange::~FrameLengthChange() = default;
bool FrameLengthController::FrameLengthChange::operator<(
bool FrameLengthController::Config::FrameLengthChange::operator<(
const FrameLengthChange& rhs) const {
return from_frame_length_ms < rhs.from_frame_length_ms ||
(from_frame_length_ms == rhs.from_frame_length_ms &&
@ -99,10 +90,10 @@ bool FrameLengthController::FrameLengthIncreasingDecision(
if (longer_frame_length_ms == config_.encoder_frame_lengths_ms.end())
return false;
auto increase_threshold = frame_length_change_criteria_.find(
FrameLengthChange(*frame_length_ms_, *longer_frame_length_ms));
auto increase_threshold = config_.fl_changing_bandwidths_bps.find(
Config::FrameLengthChange(*frame_length_ms_, *longer_frame_length_ms));
if (increase_threshold == frame_length_change_criteria_.end())
if (increase_threshold == config_.fl_changing_bandwidths_bps.end())
return false;
return (uplink_bandwidth_bps_ &&
@ -124,10 +115,10 @@ bool FrameLengthController::FrameLengthDecreasingDecision(
return false;
auto shorter_frame_length_ms = std::prev(frame_length_ms_);
auto decrease_threshold = frame_length_change_criteria_.find(
FrameLengthChange(*frame_length_ms_, *shorter_frame_length_ms));
auto decrease_threshold = config_.fl_changing_bandwidths_bps.find(
Config::FrameLengthChange(*frame_length_ms_, *shorter_frame_length_ms));
if (decrease_threshold == frame_length_change_criteria_.end())
if (decrease_threshold == config_.fl_changing_bandwidths_bps.end())
return false;
return (uplink_bandwidth_bps_ &&

View File

@ -24,12 +24,17 @@ namespace webrtc {
class FrameLengthController final : public Controller {
public:
struct Config {
struct FrameLengthChange {
FrameLengthChange(int from_frame_length_ms, int to_frame_length_ms);
bool operator<(const FrameLengthChange& rhs) const;
int from_frame_length_ms;
int to_frame_length_ms;
};
Config(const std::vector<int>& encoder_frame_lengths_ms,
int initial_frame_length_ms,
float fl_increasing_packet_loss_fraction,
float fl_decreasing_packet_loss_fraction,
int fl_20ms_to_60ms_bandwidth_bps,
int fl_60ms_to_20ms_bandwidth_bps);
std::map<FrameLengthChange, int> fl_changing_bandwidths_bps);
Config(const Config& other);
~Config();
std::vector<int> encoder_frame_lengths_ms;
@ -38,11 +43,7 @@ class FrameLengthController final : public Controller {
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;
std::map<FrameLengthChange, int> fl_changing_bandwidths_bps;
};
explicit FrameLengthController(const Config& config);
@ -54,16 +55,6 @@ class FrameLengthController final : public Controller {
void MakeDecision(AudioNetworkAdaptor::EncoderRuntimeConfig* config) override;
private:
friend class FrameLengthControllerForTest;
struct FrameLengthChange {
FrameLengthChange(int from_frame_length_ms, int to_frame_length_ms);
~FrameLengthChange();
bool operator<(const FrameLengthChange& rhs) const;
int from_frame_length_ms;
int to_frame_length_ms;
};
bool FrameLengthIncreasingDecision(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) const;
@ -74,8 +65,6 @@ class FrameLengthController final : public Controller {
std::vector<int>::const_iterator frame_length_ms_;
std::map<FrameLengthChange, int> frame_length_change_criteria_;
rtc::Optional<int> uplink_bandwidth_bps_;
rtc::Optional<float> uplink_packet_loss_fraction_;

View File

@ -20,24 +20,51 @@ namespace {
constexpr float kFlIncreasingPacketLossFraction = 0.04f;
constexpr float kFlDecreasingPacketLossFraction = 0.05f;
constexpr int kFl20msTo60msBandwidthBps = 22000;
constexpr int kFl60msTo20msBandwidthBps = 88000;
constexpr int kFl20msTo60msBandwidthBps = 40000;
constexpr int kFl60msTo20msBandwidthBps = 50000;
constexpr int kFl60msTo120msBandwidthBps = 30000;
constexpr int kFl120msTo60msBandwidthBps = 40000;
constexpr int kMediumBandwidthBps =
(kFl60msTo20msBandwidthBps + kFl20msTo60msBandwidthBps) / 2;
constexpr float kMediumPacketLossFraction =
(kFlDecreasingPacketLossFraction + kFlIncreasingPacketLossFraction) / 2;
std::unique_ptr<FrameLengthController> CreateController(
const std::map<FrameLengthController::Config::FrameLengthChange, int>&
frame_length_change_criteria,
const std::vector<int>& encoder_frame_lengths_ms,
int initial_frame_length_ms) {
std::unique_ptr<FrameLengthController> controller(
new FrameLengthController(FrameLengthController::Config(
encoder_frame_lengths_ms, initial_frame_length_ms,
kFlIncreasingPacketLossFraction, kFlDecreasingPacketLossFraction,
kFl20msTo60msBandwidthBps, kFl60msTo20msBandwidthBps)));
frame_length_change_criteria)));
return controller;
}
std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20msAnd60ms() {
return std::map<FrameLengthController::Config::FrameLengthChange, int>{
{FrameLengthController::Config::FrameLengthChange(20, 60),
kFl20msTo60msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 20),
kFl60msTo20msBandwidthBps}};
}
std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20ms60msAnd120ms() {
return std::map<FrameLengthController::Config::FrameLengthChange, int>{
{FrameLengthController::Config::FrameLengthChange(20, 60),
kFl20msTo60msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 20),
kFl60msTo20msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 120),
kFl60msTo120msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(120, 60),
kFl120msTo60msBandwidthBps}};
}
void UpdateNetworkMetrics(
FrameLengthController* controller,
const rtc::Optional<int>& uplink_bandwidth_bps,
@ -70,7 +97,8 @@ void CheckDecision(FrameLengthController* controller,
} // namespace
TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkBandwidth) {
auto controller = CreateController({20, 60}, 60);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kFl60msTo20msBandwidthBps),
rtc::Optional<float>());
@ -78,20 +106,23 @@ TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkBandwidth) {
}
TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkPacketLossFraction) {
auto controller = CreateController({20, 60}, 60);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
UpdateNetworkMetrics(controller.get(), rtc::Optional<int>(),
rtc::Optional<float>(kFlDecreasingPacketLossFraction));
CheckDecision(controller.get(), rtc::Optional<bool>(), 20);
}
TEST(FrameLengthControllerTest, DecreaseTo20MsWhenFecIsOn) {
auto controller = CreateController({20, 60}, 60);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
CheckDecision(controller.get(), rtc::Optional<bool>(true), 20);
}
TEST(FrameLengthControllerTest,
Maintain60MsIf20MsNotInReceiverFrameLengthRange) {
auto controller = CreateController({60}, 60);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {60}, 60);
// Set FEC on that would cause frame length to decrease if receiver frame
// length range included 20ms.
CheckDecision(controller.get(), rtc::Optional<bool>(true), 60);
@ -102,7 +133,8 @@ TEST(FrameLengthControllerTest, Maintain60MsOnMultipleConditions) {
// 1. |uplink_bandwidth_bps| is at medium level,
// 2. |uplink_packet_loss_fraction| is at medium,
// 3. FEC is not decided ON.
auto controller = CreateController({20, 60}, 60);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kMediumBandwidthBps),
rtc::Optional<float>(kMediumPacketLossFraction));
@ -115,7 +147,8 @@ TEST(FrameLengthControllerTest, IncreaseTo60MsOnMultipleConditions) {
// 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold
// AND
// 3. FEC is not decided or OFF.
auto controller = CreateController({20, 60}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kFl20msTo60msBandwidthBps),
rtc::Optional<float>(kFlIncreasingPacketLossFraction));
@ -130,7 +163,8 @@ TEST(FrameLengthControllerTest, UpdateMultipleNetworkMetricsAtOnce) {
// FrameLengthController::UpdateNetworkMetrics(...) can handle multiple
// network updates at once. This is, however, not a common use case in current
// audio_network_adaptor_impl.cc.
auto controller = CreateController({20, 60}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
Controller::NetworkMetrics network_metrics;
network_metrics.uplink_bandwidth_bps =
rtc::Optional<int>(kFl20msTo60msBandwidthBps);
@ -142,7 +176,8 @@ TEST(FrameLengthControllerTest, UpdateMultipleNetworkMetricsAtOnce) {
TEST(FrameLengthControllerTest,
Maintain20MsIf60MsNotInReceiverFrameLengthRange) {
auto controller = CreateController({20}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20}, 20);
// Use a low uplink bandwidth and a low uplink packet loss fraction that would
// cause frame length to increase if receiver frame length included 60ms.
UpdateNetworkMetrics(controller.get(),
@ -152,7 +187,8 @@ TEST(FrameLengthControllerTest,
}
TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkBandwidth) {
auto controller = CreateController({20, 60}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kMediumBandwidthBps),
rtc::Optional<float>(kFlIncreasingPacketLossFraction));
@ -160,7 +196,8 @@ TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkBandwidth) {
}
TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkPacketLossFraction) {
auto controller = CreateController({20, 60}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
// Use a low uplink bandwidth that would cause frame length to increase if
// uplink packet loss fraction was low.
UpdateNetworkMetrics(controller.get(),
@ -170,7 +207,8 @@ TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkPacketLossFraction) {
}
TEST(FrameLengthControllerTest, Maintain20MsWhenFecIsOn) {
auto controller = CreateController({20, 60}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
// Use a low uplink bandwidth and a low uplink packet loss fraction that would
// cause frame length to increase if FEC was not ON.
UpdateNetworkMetrics(controller.get(),
@ -179,40 +217,18 @@ TEST(FrameLengthControllerTest, Maintain20MsWhenFecIsOn) {
CheckDecision(controller.get(), rtc::Optional<bool>(true), 20);
}
namespace {
constexpr int kFl60msTo120msBandwidthBps = 18000;
constexpr int kFl120msTo60msBandwidthBps = 72000;
TEST(FrameLengthControllerTest, Maintain60MsWhenNo120msCriteriaIsSet) {
auto controller =
CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60, 120}, 60);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kFl60msTo120msBandwidthBps),
rtc::Optional<float>(kFlIncreasingPacketLossFraction));
CheckDecision(controller.get(), rtc::Optional<bool>(), 60);
}
class FrameLengthControllerForTest {
public:
// This class is to test multiple frame lengths. FrameLengthController is
// implemented to support this, but is not enabled for the default constructor
// for the time being. We use this class to test it.
FrameLengthControllerForTest(const std::vector<int>& encoder_frame_lengths_ms,
int initial_frame_length_ms)
: frame_length_controller_(
FrameLengthController::Config(encoder_frame_lengths_ms,
initial_frame_length_ms,
kFlIncreasingPacketLossFraction,
kFlDecreasingPacketLossFraction,
kFl20msTo60msBandwidthBps,
kFl60msTo20msBandwidthBps)) {
frame_length_controller_.frame_length_change_criteria_.insert(
std::make_pair(FrameLengthController::FrameLengthChange(60, 120),
kFl60msTo120msBandwidthBps));
frame_length_controller_.frame_length_change_criteria_.insert(
std::make_pair(FrameLengthController::FrameLengthChange(120, 60),
kFl120msTo60msBandwidthBps));
}
FrameLengthController* get() { return &frame_length_controller_; }
private:
FrameLengthController frame_length_controller_;
};
TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkBandwidth) {
FrameLengthControllerForTest controller({20, 60, 120}, 120);
auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
{20, 60, 120}, 120);
// It takes two steps for frame length to go from 120ms to 20ms.
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kFl60msTo20msBandwidthBps),
@ -226,7 +242,8 @@ TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkBandwidth) {
}
TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkPacketLossFraction) {
FrameLengthControllerForTest controller({20, 60, 120}, 120);
auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
{20, 60, 120}, 120);
// It takes two steps for frame length to go from 120ms to 20ms.
UpdateNetworkMetrics(controller.get(), rtc::Optional<int>(),
rtc::Optional<float>(kFlDecreasingPacketLossFraction));
@ -238,7 +255,8 @@ TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkPacketLossFraction) {
}
TEST(FrameLengthControllerTest, From120MsTo20MsWhenFecIsOn) {
FrameLengthControllerForTest controller({20, 60, 120}, 120);
auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
{20, 60, 120}, 120);
// It takes two steps for frame length to go from 120ms to 20ms.
CheckDecision(controller.get(), rtc::Optional<bool>(true), 60);
CheckDecision(controller.get(), rtc::Optional<bool>(true), 20);
@ -250,7 +268,8 @@ TEST(FrameLengthControllerTest, From20MsTo120MsOnMultipleConditions) {
// 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold
// AND
// 3. FEC is not decided or OFF.
FrameLengthControllerForTest controller({20, 60, 120}, 20);
auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
{20, 60, 120}, 20);
// It takes two steps for frame length to go from 20ms to 120ms.
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kFl60msTo120msBandwidthBps),
@ -263,7 +282,8 @@ TEST(FrameLengthControllerTest, From20MsTo120MsOnMultipleConditions) {
}
TEST(FrameLengthControllerTest, Stall60MsIf120MsNotInReceiverFrameLengthRange) {
FrameLengthControllerForTest controller({20, 60}, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(), {20, 60}, 20);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kFl60msTo120msBandwidthBps),
rtc::Optional<float>(kFlIncreasingPacketLossFraction));
@ -275,7 +295,8 @@ TEST(FrameLengthControllerTest, Stall60MsIf120MsNotInReceiverFrameLengthRange) {
}
TEST(FrameLengthControllerTest, CheckBehaviorOnChangingNetworkMetrics) {
FrameLengthControllerForTest controller({20, 60, 120}, 20);
auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
{20, 60, 120}, 20);
UpdateNetworkMetrics(controller.get(),
rtc::Optional<int>(kMediumBandwidthBps),
rtc::Optional<float>(kFlIncreasingPacketLossFraction));

View File

@ -35,7 +35,12 @@ constexpr int kSampleRateHz = 48000;
constexpr int kMinBitrateBps = 6000;
constexpr int kMaxBitrateBps = 512000;
#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
constexpr int kSupportedFrameLengths[] = {20, 60, 120};
#else
constexpr int kSupportedFrameLengths[] = {20, 60};
#endif
// PacketLossFractionSmoother uses an exponential filter with a time constant
// of -1.0 / ln(0.9999) = 10000 ms.