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:
@ -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 {
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user