Allowing 40ms audio frame length.

Currently 20ms, 60ms and 120ms frame length are supported. The motivation is to better adapt audio bit rate to network conditions with more frame length choices.

This is continuation of https://webrtc-review.googlesource.com/c/src/+/146206, since crodbro is out of office, I created this commit for continuing the code review.

Bug: webrtc:10820
Change-Id: I0e35e91b524f63686bfdf767b7a95c51aeb24716
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146780
Reviewed-by: Minyue Li <minyue@webrtc.org>
Reviewed-by: Alex Narest <alexnarest@webrtc.org>
Reviewed-by: Bjorn Mellem <mellem@webrtc.org>
Commit-Queue: Ying Wang <yinwa@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28882}
This commit is contained in:
Ying Wang
2019-08-16 16:45:30 +02:00
committed by Commit Bot
parent 0ee431178f
commit 0e1a558fb3
4 changed files with 145 additions and 14 deletions

View File

@ -98,6 +98,22 @@ message FrameLengthController {
// Offset to apply to the per-packet overhead when decreasing frame length.
optional int32 fl_decrease_overhead_offset = 8;
// Uplink bandwidth below which frame length can switch from 20ms to 40ms. In
// current implementation, defining this will invalidate
// fl_20ms_to_60ms_bandwidth_bps.
optional int32 fl_20ms_to_40ms_bandwidth_bps = 9;
// Uplink bandwidth above which frame length should switch from 40ms to 20ms.
optional int32 fl_40ms_to_20ms_bandwidth_bps = 10;
// Uplink bandwidth below which frame length can switch from 40ms to 60ms.
optional int32 fl_40ms_to_60ms_bandwidth_bps = 11;
// Uplink bandwidth above which frame length should switch from 60ms to 40ms.
// In current implementation, defining this will invalidate
// fl_60ms_to_20ms_bandwidth_bps.
optional int32 fl_60ms_to_40ms_bandwidth_bps = 12;
}
message ChannelController {

View File

@ -118,21 +118,53 @@ std::unique_ptr<FrameLengthController> CreateFrameLengthController(
int min_encoder_bitrate_bps) {
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());
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()}};
fl_changing_bandwidths_bps;
if (config.has_fl_60ms_to_120ms_bandwidth_bps() &&
config.has_fl_120ms_to_60ms_bandwidth_bps()) {
if (config.has_fl_20ms_to_60ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(
std::make_pair(FrameLengthController::Config::FrameLengthChange(20, 60),
config.fl_20ms_to_60ms_bandwidth_bps()));
}
if (config.has_fl_60ms_to_20ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(
std::make_pair(FrameLengthController::Config::FrameLengthChange(60, 20),
config.fl_60ms_to_20ms_bandwidth_bps()));
}
if (config.has_fl_20ms_to_40ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(
std::make_pair(FrameLengthController::Config::FrameLengthChange(20, 40),
config.fl_20ms_to_40ms_bandwidth_bps()));
}
if (config.has_fl_40ms_to_20ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(
std::make_pair(FrameLengthController::Config::FrameLengthChange(40, 20),
config.fl_40ms_to_20ms_bandwidth_bps()));
}
if (config.has_fl_40ms_to_60ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(
std::make_pair(FrameLengthController::Config::FrameLengthChange(40, 60),
config.fl_40ms_to_60ms_bandwidth_bps()));
}
if (config.has_fl_60ms_to_40ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(
std::make_pair(FrameLengthController::Config::FrameLengthChange(60, 40),
config.fl_60ms_to_40ms_bandwidth_bps()));
}
if (config.has_fl_60ms_to_120ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(std::make_pair(
FrameLengthController::Config::FrameLengthChange(60, 120),
config.fl_60ms_to_120ms_bandwidth_bps()));
}
if (config.has_fl_120ms_to_60ms_bandwidth_bps()) {
fl_changing_bandwidths_bps.insert(std::make_pair(
FrameLengthController::Config::FrameLengthChange(120, 60),
config.fl_120ms_to_60ms_bandwidth_bps()));

View File

@ -249,8 +249,10 @@ void AddFrameLengthControllerConfig(
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);
controller_config->set_fl_20ms_to_40ms_bandwidth_bps(80000);
controller_config->set_fl_40ms_to_20ms_bandwidth_bps(88000);
controller_config->set_fl_40ms_to_60ms_bandwidth_bps(72000);
controller_config->set_fl_60ms_to_40ms_bandwidth_bps(80000);
auto scoring_point = controller_config_ext->mutable_scoring_point();
scoring_point->set_uplink_bandwidth_bps(kChracteristicBandwithBps[1]);

View File

@ -30,8 +30,13 @@ constexpr int kFl20msTo60msBandwidthBps = 40000;
constexpr int kFl60msTo20msBandwidthBps = 50000;
constexpr int kFl60msTo120msBandwidthBps = 30000;
constexpr int kFl120msTo60msBandwidthBps = 40000;
constexpr int kFl20msTo40msBandwidthBps = 45000;
constexpr int kFl40msTo20msBandwidthBps = 50000;
constexpr int kFl40msTo60msBandwidthBps = 40000;
constexpr int kFl60msTo40msBandwidthBps = 45000;
constexpr int kMediumBandwidthBps =
(kFl60msTo20msBandwidthBps + kFl20msTo60msBandwidthBps) / 2;
(kFl40msTo20msBandwidthBps + kFl20msTo40msBandwidthBps) / 2;
constexpr float kMediumPacketLossFraction =
(kFlDecreasingPacketLossFraction + kFlIncreasingPacketLossFraction) / 2;
const std::set<int> kDefaultEncoderFrameLengthsMs = {20, 40, 60, 120};
@ -65,6 +70,15 @@ CreateChangeCriteriaFor20msAnd60ms() {
kFl60msTo20msBandwidthBps}};
}
std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20msAnd40ms() {
return std::map<FrameLengthController::Config::FrameLengthChange, int>{
{FrameLengthController::Config::FrameLengthChange(20, 40),
kFl20msTo40msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(40, 20),
kFl40msTo20msBandwidthBps}};
}
std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20ms60msAnd120ms() {
return std::map<FrameLengthController::Config::FrameLengthChange, int>{
@ -78,6 +92,36 @@ CreateChangeCriteriaFor20ms60msAnd120ms() {
kFl120msTo60msBandwidthBps}};
}
std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20ms40ms60msAnd120ms() {
return std::map<FrameLengthController::Config::FrameLengthChange, int>{
{FrameLengthController::Config::FrameLengthChange(20, 60),
kFl20msTo60msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 20),
kFl60msTo20msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(20, 40),
kFl20msTo40msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(40, 20),
kFl40msTo20msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(40, 60),
kFl40msTo60msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 40),
kFl60msTo40msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 120),
kFl60msTo120msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(120, 60),
kFl120msTo60msBandwidthBps}};
}
std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor40msAnd60ms() {
return std::map<FrameLengthController::Config::FrameLengthChange, int>{
{FrameLengthController::Config::FrameLengthChange(40, 60),
kFl40msTo60msBandwidthBps},
{FrameLengthController::Config::FrameLengthChange(60, 40),
kFl60msTo40msBandwidthBps}};
}
void UpdateNetworkMetrics(
FrameLengthController* controller,
const absl::optional<int>& uplink_bandwidth_bps,
@ -138,6 +182,28 @@ TEST(FrameLengthControllerTest,
CheckDecision(controller.get(), 60);
}
TEST(FrameLengthControllerTest, IncreaseTo40MsOnMultipleConditions) {
// Increase to 40ms frame length if
// 1. |uplink_bandwidth_bps| is known to be smaller than a threshold AND
// 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold
// AND
// 3. FEC is not decided or OFF.
auto controller = CreateController(CreateChangeCriteriaFor20msAnd40ms(),
kDefaultEncoderFrameLengthsMs, 20);
UpdateNetworkMetrics(controller.get(), kFl20msTo40msBandwidthBps,
kFlIncreasingPacketLossFraction,
kOverheadBytesPerPacket);
CheckDecision(controller.get(), 40);
}
TEST(FrameLengthControllerTest, DecreaseTo40MsOnHighUplinkBandwidth) {
auto controller = CreateController(CreateChangeCriteriaFor40msAnd60ms(),
kDefaultEncoderFrameLengthsMs, 40);
UpdateNetworkMetrics(controller.get(), kFl60msTo40msBandwidthBps,
absl::nullopt, kOverheadBytesPerPacket);
CheckDecision(controller.get(), 40);
}
TEST(FrameLengthControllerTest, Maintain60MsOnMultipleConditions) {
// Maintain 60ms frame length if
// 1. |uplink_bandwidth_bps| is at medium level,
@ -328,13 +394,23 @@ TEST(FrameLengthControllerTest, Stall60MsIf120MsNotInReceiverFrameLengthRange) {
}
TEST(FrameLengthControllerTest, CheckBehaviorOnChangingNetworkMetrics) {
auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
kDefaultEncoderFrameLengthsMs, 20);
auto controller =
CreateController(CreateChangeCriteriaFor20ms40ms60msAnd120ms(),
kDefaultEncoderFrameLengthsMs, 20);
UpdateNetworkMetrics(controller.get(), kMediumBandwidthBps,
kFlIncreasingPacketLossFraction,
kOverheadBytesPerPacket);
CheckDecision(controller.get(), 20);
UpdateNetworkMetrics(controller.get(), kFl20msTo40msBandwidthBps,
kFlIncreasingPacketLossFraction,
kOverheadBytesPerPacket);
CheckDecision(controller.get(), 40);
UpdateNetworkMetrics(controller.get(), kFl60msTo40msBandwidthBps,
kMediumPacketLossFraction, kOverheadBytesPerPacket);
CheckDecision(controller.get(), 40);
UpdateNetworkMetrics(controller.get(), kFl20msTo60msBandwidthBps,
kFlIncreasingPacketLossFraction,
kOverheadBytesPerPacket);
@ -354,6 +430,11 @@ TEST(FrameLengthControllerTest, CheckBehaviorOnChangingNetworkMetrics) {
kOverheadBytesPerPacket);
CheckDecision(controller.get(), 60);
UpdateNetworkMetrics(controller.get(), kFl60msTo40msBandwidthBps,
kFlDecreasingPacketLossFraction,
kOverheadBytesPerPacket);
CheckDecision(controller.get(), 40);
UpdateNetworkMetrics(controller.get(), kMediumBandwidthBps,
kFlDecreasingPacketLossFraction,
kOverheadBytesPerPacket);