Add a simple frame length controller.
This will be used when adaptivePtime is enabled. Bug: chromium:1086942 Change-Id: I63c947c53a8c5b8e0825b78b847c3f7900197d6c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/177421 Reviewed-by: Minyue Li <minyue@webrtc.org> Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31544}
This commit is contained in:

committed by
Commit Bot

parent
c5c878b8ab
commit
f46902c540
@ -882,6 +882,8 @@ rtc_library("audio_network_adaptor") {
|
||||
"audio_network_adaptor/fec_controller_plr_based.h",
|
||||
"audio_network_adaptor/frame_length_controller.cc",
|
||||
"audio_network_adaptor/frame_length_controller.h",
|
||||
"audio_network_adaptor/frame_length_controller_v2.cc",
|
||||
"audio_network_adaptor/frame_length_controller_v2.h",
|
||||
"audio_network_adaptor/include/audio_network_adaptor.h",
|
||||
"audio_network_adaptor/util/threshold_curve.h",
|
||||
]
|
||||
@ -902,7 +904,10 @@ rtc_library("audio_network_adaptor") {
|
||||
"../../system_wrappers",
|
||||
"../../system_wrappers:field_trial",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
|
||||
if (rtc_enable_protobuf) {
|
||||
deps += [
|
||||
@ -1931,6 +1936,7 @@ if (rtc_include_tests) {
|
||||
"audio_network_adaptor/event_log_writer_unittest.cc",
|
||||
"audio_network_adaptor/fec_controller_plr_based_unittest.cc",
|
||||
"audio_network_adaptor/frame_length_controller_unittest.cc",
|
||||
"audio_network_adaptor/frame_length_controller_v2_unittest.cc",
|
||||
"audio_network_adaptor/util/threshold_curve_unittest.cc",
|
||||
"codecs/builtin_audio_decoder_factory_unittest.cc",
|
||||
"codecs/builtin_audio_encoder_factory_unittest.cc",
|
||||
|
@ -1,8 +1,10 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package webrtc.audio_network_adaptor.config;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
option java_package = "org.webrtc.AudioNetworkAdaptor";
|
||||
option java_outer_classname = "Config";
|
||||
package webrtc.audio_network_adaptor.config;
|
||||
|
||||
message FecController {
|
||||
message Threshold {
|
||||
@ -116,6 +118,19 @@ message FrameLengthController {
|
||||
optional int32 fl_60ms_to_40ms_bandwidth_bps = 12;
|
||||
}
|
||||
|
||||
message FrameLengthControllerV2 {
|
||||
// FrameLengthControllerV2 chooses the frame length by taking the target
|
||||
// bitrate and subtracting the overhead bitrate to obtain the remaining
|
||||
// bitrate for the payload. The chosen frame length is the shortest possible
|
||||
// where the payload bitrate is more than |min_payload_bitrate_bps|.
|
||||
optional int32 min_payload_bitrate_bps = 1;
|
||||
|
||||
// If true, uses the stable target bitrate to decide the frame length. This
|
||||
// will result in less frame length toggling but spending more time at longer
|
||||
// frame lengths compared to using the normal target bitrate.
|
||||
optional bool use_slow_adaptation = 2;
|
||||
}
|
||||
|
||||
message ChannelController {
|
||||
// Uplink bandwidth above which the number of encoded channels should switch
|
||||
// from 1 to 2.
|
||||
@ -164,6 +179,7 @@ message Controller {
|
||||
DtxController dtx_controller = 24;
|
||||
BitrateController bitrate_controller = 25;
|
||||
FecControllerRplrBased fec_controller_rplr_based = 26;
|
||||
FrameLengthControllerV2 frame_length_controller_v2 = 27;
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,4 +193,3 @@ message ControllerManager {
|
||||
// made.
|
||||
optional float min_reordering_squared_distance = 3;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "modules/audio_coding/audio_network_adaptor/controller_manager.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
@ -20,6 +21,7 @@
|
||||
#include "modules/audio_coding/audio_network_adaptor/dtx_controller.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/frame_length_controller.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/util/threshold_curve.h"
|
||||
#include "rtc_base/ignore_wundef.h"
|
||||
#include "rtc_base/logging.h"
|
||||
@ -197,6 +199,14 @@ std::unique_ptr<BitrateController> CreateBitrateController(
|
||||
initial_bitrate_bps, initial_frame_length_ms,
|
||||
fl_increase_overhead_offset, fl_decrease_overhead_offset)));
|
||||
}
|
||||
|
||||
std::unique_ptr<FrameLengthControllerV2> CreateFrameLengthControllerV2(
|
||||
const audio_network_adaptor::config::FrameLengthControllerV2& config,
|
||||
rtc::ArrayView<const int> encoder_frame_lengths_ms) {
|
||||
return std::make_unique<FrameLengthControllerV2>(
|
||||
encoder_frame_lengths_ms, config.min_payload_bitrate_bps(),
|
||||
config.use_slow_adaptation());
|
||||
}
|
||||
#endif // WEBRTC_ENABLE_PROTOBUF
|
||||
|
||||
} // namespace
|
||||
@ -277,6 +287,11 @@ std::unique_ptr<ControllerManager> ControllerManagerImpl::Create(
|
||||
controller_config.bitrate_controller(), initial_bitrate_bps,
|
||||
initial_frame_length_ms);
|
||||
break;
|
||||
case audio_network_adaptor::config::Controller::kFrameLengthControllerV2:
|
||||
controller = CreateFrameLengthControllerV2(
|
||||
controller_config.frame_length_controller_v2(),
|
||||
encoder_frame_lengths_ms);
|
||||
break;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
|
@ -260,6 +260,14 @@ void AddFrameLengthControllerConfig(
|
||||
kChracteristicPacketLossFraction[1]);
|
||||
}
|
||||
|
||||
void AddFrameLengthControllerV2Config(
|
||||
audio_network_adaptor::config::ControllerManager* config) {
|
||||
auto controller =
|
||||
config->add_controllers()->mutable_frame_length_controller_v2();
|
||||
controller->set_min_payload_bitrate_bps(16000);
|
||||
controller->set_use_slow_adaptation(true);
|
||||
}
|
||||
|
||||
constexpr int kInitialBitrateBps = 24000;
|
||||
constexpr size_t kIntialChannelsToEncode = 1;
|
||||
constexpr bool kInitialDtxEnabled = true;
|
||||
@ -464,6 +472,14 @@ TEST(ControllerManagerTest, CreateFromConfigStringAndCheckReordering) {
|
||||
ControllerType::CHANNEL, ControllerType::DTX,
|
||||
ControllerType::BIT_RATE});
|
||||
}
|
||||
|
||||
TEST(ControllerManagerTest, CreateFrameLengthControllerV2) {
|
||||
audio_network_adaptor::config::ControllerManager config;
|
||||
AddFrameLengthControllerV2Config(&config);
|
||||
auto states = CreateControllerManager(config.SerializeAsString());
|
||||
auto controllers = states.controller_manager->GetControllers();
|
||||
EXPECT_TRUE(controllers.size() == 1);
|
||||
}
|
||||
#endif // WEBRTC_ENABLE_PROTOBUF
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
int OverheadBps(int overhead_bytes_per_packet, int frame_length_ms) {
|
||||
return overhead_bytes_per_packet * 8 * 1000 / frame_length_ms;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FrameLengthControllerV2::FrameLengthControllerV2(
|
||||
rtc::ArrayView<const int> encoder_frame_lengths_ms,
|
||||
int min_payload_bitrate_bps,
|
||||
bool use_slow_adaptation)
|
||||
: encoder_frame_lengths_ms_(encoder_frame_lengths_ms.begin(),
|
||||
encoder_frame_lengths_ms.end()),
|
||||
min_payload_bitrate_bps_(min_payload_bitrate_bps),
|
||||
use_slow_adaptation_(use_slow_adaptation) {
|
||||
RTC_CHECK(!encoder_frame_lengths_ms_.empty());
|
||||
absl::c_sort(encoder_frame_lengths_ms_);
|
||||
}
|
||||
|
||||
void FrameLengthControllerV2::UpdateNetworkMetrics(
|
||||
const NetworkMetrics& network_metrics) {
|
||||
if (network_metrics.target_audio_bitrate_bps) {
|
||||
target_bitrate_bps_ = network_metrics.target_audio_bitrate_bps;
|
||||
}
|
||||
if (network_metrics.overhead_bytes_per_packet) {
|
||||
overhead_bytes_per_packet_ = network_metrics.overhead_bytes_per_packet;
|
||||
}
|
||||
if (network_metrics.uplink_bandwidth_bps) {
|
||||
uplink_bandwidth_bps_ = network_metrics.uplink_bandwidth_bps;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameLengthControllerV2::MakeDecision(AudioEncoderRuntimeConfig* config) {
|
||||
if (!target_bitrate_bps_ || !overhead_bytes_per_packet_ ||
|
||||
!uplink_bandwidth_bps_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto it =
|
||||
absl::c_find_if(encoder_frame_lengths_ms_, [&](int frame_length_ms) {
|
||||
int target = use_slow_adaptation_ ? *uplink_bandwidth_bps_
|
||||
: *target_bitrate_bps_;
|
||||
return target -
|
||||
OverheadBps(*overhead_bytes_per_packet_, frame_length_ms) >
|
||||
min_payload_bitrate_bps_;
|
||||
});
|
||||
|
||||
// Longest frame length is chosen if none match our criteria.
|
||||
config->frame_length_ms = it != encoder_frame_lengths_ms_.end()
|
||||
? *it
|
||||
: encoder_frame_lengths_ms_.back();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_V2_H_
|
||||
#define MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_V2_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/controller.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FrameLengthControllerV2 final : public Controller {
|
||||
public:
|
||||
FrameLengthControllerV2(rtc::ArrayView<const int> encoder_frame_lengths_ms,
|
||||
int min_payload_bitrate_bps,
|
||||
bool use_slow_adaptation);
|
||||
|
||||
void UpdateNetworkMetrics(const NetworkMetrics& network_metrics) override;
|
||||
|
||||
void MakeDecision(AudioEncoderRuntimeConfig* config) override;
|
||||
|
||||
private:
|
||||
std::vector<int> encoder_frame_lengths_ms_;
|
||||
const int min_payload_bitrate_bps_;
|
||||
const bool use_slow_adaptation_;
|
||||
|
||||
absl::optional<int> uplink_bandwidth_bps_;
|
||||
absl::optional<int> target_bitrate_bps_;
|
||||
absl::optional<int> overhead_bytes_per_packet_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_FRAME_LENGTH_CONTROLLER_V2_H_
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/audio_coding/audio_network_adaptor/frame_length_controller_v2.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "modules/audio_coding/audio_network_adaptor/controller.h"
|
||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
constexpr int kANASupportedFrameLengths[] = {20, 40, 60, 120};
|
||||
constexpr int kMinPayloadBitrateBps = 16000;
|
||||
|
||||
} // namespace
|
||||
|
||||
class FrameLengthControllerV2Test : public testing::Test {
|
||||
protected:
|
||||
AudioEncoderRuntimeConfig GetDecision() {
|
||||
AudioEncoderRuntimeConfig config;
|
||||
controller_->MakeDecision(&config);
|
||||
return config;
|
||||
}
|
||||
|
||||
void SetOverhead(int overhead_bytes_per_packet) {
|
||||
overhead_bytes_per_packet_ = overhead_bytes_per_packet;
|
||||
Controller::NetworkMetrics metrics;
|
||||
metrics.overhead_bytes_per_packet = overhead_bytes_per_packet;
|
||||
controller_->UpdateNetworkMetrics(metrics);
|
||||
}
|
||||
|
||||
void SetTargetBitrate(int target_audio_bitrate_bps) {
|
||||
target_audio_bitrate_bps_ = target_audio_bitrate_bps;
|
||||
Controller::NetworkMetrics metrics;
|
||||
metrics.target_audio_bitrate_bps = target_audio_bitrate_bps;
|
||||
controller_->UpdateNetworkMetrics(metrics);
|
||||
}
|
||||
|
||||
void SetUplinkBandwidth(int uplink_bandwidth_bps) {
|
||||
Controller::NetworkMetrics metrics;
|
||||
metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
|
||||
controller_->UpdateNetworkMetrics(metrics);
|
||||
}
|
||||
|
||||
void ExpectFrameLengthDecision(int expected_frame_length_ms) {
|
||||
auto config = GetDecision();
|
||||
EXPECT_EQ(*config.frame_length_ms, expected_frame_length_ms);
|
||||
}
|
||||
|
||||
std::unique_ptr<FrameLengthControllerV2> controller_ =
|
||||
std::make_unique<FrameLengthControllerV2>(kANASupportedFrameLengths,
|
||||
kMinPayloadBitrateBps,
|
||||
/*use_slow_adaptation=*/false);
|
||||
absl::optional<int> target_audio_bitrate_bps_;
|
||||
absl::optional<int> overhead_bytes_per_packet_;
|
||||
};
|
||||
|
||||
// Don't return any decision if we haven't received all required network
|
||||
// metrics.
|
||||
TEST_F(FrameLengthControllerV2Test, RequireNetworkMetrics) {
|
||||
auto config = GetDecision();
|
||||
EXPECT_FALSE(config.bitrate_bps);
|
||||
EXPECT_FALSE(config.frame_length_ms);
|
||||
|
||||
SetOverhead(30);
|
||||
config = GetDecision();
|
||||
EXPECT_FALSE(config.frame_length_ms);
|
||||
|
||||
SetTargetBitrate(32000);
|
||||
config = GetDecision();
|
||||
EXPECT_FALSE(config.frame_length_ms);
|
||||
|
||||
SetUplinkBandwidth(32000);
|
||||
config = GetDecision();
|
||||
EXPECT_TRUE(config.frame_length_ms);
|
||||
}
|
||||
|
||||
TEST_F(FrameLengthControllerV2Test, UseFastAdaptation) {
|
||||
SetOverhead(50);
|
||||
SetTargetBitrate(50000);
|
||||
SetUplinkBandwidth(50000);
|
||||
ExpectFrameLengthDecision(20);
|
||||
|
||||
SetTargetBitrate(20000);
|
||||
ExpectFrameLengthDecision(120);
|
||||
|
||||
SetTargetBitrate(30000);
|
||||
ExpectFrameLengthDecision(40);
|
||||
|
||||
SetTargetBitrate(25000);
|
||||
ExpectFrameLengthDecision(60);
|
||||
}
|
||||
|
||||
TEST_F(FrameLengthControllerV2Test, UseSlowAdaptation) {
|
||||
controller_ = std::make_unique<FrameLengthControllerV2>(
|
||||
kANASupportedFrameLengths, kMinPayloadBitrateBps,
|
||||
/*use_slow_adaptation=*/true);
|
||||
SetOverhead(50);
|
||||
SetTargetBitrate(50000);
|
||||
SetUplinkBandwidth(20000);
|
||||
ExpectFrameLengthDecision(120);
|
||||
|
||||
SetUplinkBandwidth(30000);
|
||||
ExpectFrameLengthDecision(40);
|
||||
|
||||
SetUplinkBandwidth(40000);
|
||||
ExpectFrameLengthDecision(20);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
Reference in New Issue
Block a user