Introduces common AudioAllocationSettings class.
This class collects the field trial based configuration of audio allocation and bandwidth in one place. This makes it easier overview and prepares for future cleanup of the trials. Bug: webrtc:9718 Change-Id: I34a441c0165b423f1e2ee63894337484684146ac Reviewed-on: https://webrtc-review.googlesource.com/c/118282 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Oskar Sundbom <ossu@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26370}
This commit is contained in:

committed by
Commit Bot

parent
33b716f7dd
commit
470a5eae93
@ -78,6 +78,7 @@ rtc_static_library("audio") {
|
||||
"../rtc_base:rtc_base_approved",
|
||||
"../rtc_base:rtc_task_queue",
|
||||
"../rtc_base:safe_minmax",
|
||||
"../rtc_base/experiments:audio_allocation_settings",
|
||||
"../system_wrappers",
|
||||
"../system_wrappers:field_trial",
|
||||
"../system_wrappers:metrics",
|
||||
|
@ -206,6 +206,10 @@ AudioSendStream::ExtensionIds AudioSendStream::FindExtensionIds(
|
||||
return ids;
|
||||
}
|
||||
|
||||
int AudioSendStream::TransportSeqNumId(const AudioSendStream::Config& config) {
|
||||
return FindExtensionIds(config.rtp.extensions).transport_sequence_number;
|
||||
}
|
||||
|
||||
void AudioSendStream::ConfigureStream(
|
||||
webrtc::internal::AudioSendStream* stream,
|
||||
const webrtc::AudioSendStream::Config& new_config,
|
||||
@ -251,18 +255,16 @@ void AudioSendStream::ConfigureStream(
|
||||
}
|
||||
bool transport_seq_num_id_changed =
|
||||
new_ids.transport_sequence_number != old_ids.transport_sequence_number;
|
||||
if (first_time ||
|
||||
(transport_seq_num_id_changed &&
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC"))) {
|
||||
if (first_time || (transport_seq_num_id_changed &&
|
||||
!stream->allocation_settings_.ForceNoAudioFeedback())) {
|
||||
if (!first_time) {
|
||||
channel_send->ResetSenderCongestionControlObjects();
|
||||
}
|
||||
|
||||
RtcpBandwidthObserver* bandwidth_observer = nullptr;
|
||||
bool has_transport_sequence_number =
|
||||
new_ids.transport_sequence_number != 0 &&
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC");
|
||||
if (has_transport_sequence_number) {
|
||||
|
||||
if (stream->allocation_settings_.IncludeAudioInFeedback(
|
||||
new_ids.transport_sequence_number != 0)) {
|
||||
channel_send->EnableSendTransportSequenceNumber(
|
||||
new_ids.transport_sequence_number);
|
||||
// Probing in application limited region is only used in combination with
|
||||
@ -308,15 +310,9 @@ void AudioSendStream::Start() {
|
||||
return;
|
||||
}
|
||||
|
||||
bool has_transport_sequence_number =
|
||||
FindExtensionIds(config_.rtp.extensions).transport_sequence_number != 0 &&
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC");
|
||||
if (config_.min_bitrate_bps != -1 && config_.max_bitrate_bps != -1 &&
|
||||
!config_.has_dscp &&
|
||||
(has_transport_sequence_number ||
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe") ||
|
||||
webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC"))) {
|
||||
// Audio BWE is enabled.
|
||||
if (allocation_settings_.IncludeAudioInAllocationOnStart(
|
||||
config_.min_bitrate_bps, config_.max_bitrate_bps, config_.has_dscp,
|
||||
TransportSeqNumId(config_))) {
|
||||
rtp_transport_->packet_sender()->SetAccountForAudioPackets(true);
|
||||
rtp_rtcp_module_->SetAsPartOfAllocation(true);
|
||||
ConfigureBitrateObserver(config_.min_bitrate_bps, config_.max_bitrate_bps,
|
||||
@ -539,16 +535,11 @@ bool AudioSendStream::SetupSendCodec(AudioSendStream* stream,
|
||||
return false;
|
||||
}
|
||||
|
||||
// If other side does not support audio TWCC and WebRTC-Audio-ABWENoTWCC is
|
||||
// not enabled, do not update target audio bitrate if we are in
|
||||
// WebRTC-Audio-SendSideBwe-For-Video experiment
|
||||
const bool do_not_update_target_bitrate =
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC") &&
|
||||
webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe-For-Video") &&
|
||||
!FindExtensionIds(new_config.rtp.extensions).transport_sequence_number;
|
||||
// If a bitrate has been specified for the codec, use it over the
|
||||
// codec's default.
|
||||
if (!do_not_update_target_bitrate && spec.target_bitrate_bps) {
|
||||
if (stream->allocation_settings_.UpdateAudioTargetBitrate(
|
||||
TransportSeqNumId(new_config)) &&
|
||||
spec.target_bitrate_bps) {
|
||||
encoder->OnReceivedTargetAudioBitrate(*spec.target_bitrate_bps);
|
||||
}
|
||||
|
||||
@ -611,19 +602,13 @@ bool AudioSendStream::ReconfigureSendCodec(AudioSendStream* stream,
|
||||
return SetupSendCodec(stream, new_config);
|
||||
}
|
||||
|
||||
// If other side does not support audio TWCC and WebRTC-Audio-ABWENoTWCC is
|
||||
// not enabled, do not update target audio bitrate if we are in
|
||||
// WebRTC-Audio-SendSideBwe-For-Video experiment
|
||||
const bool do_not_update_target_bitrate =
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC") &&
|
||||
webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe-For-Video") &&
|
||||
!FindExtensionIds(new_config.rtp.extensions).transport_sequence_number;
|
||||
|
||||
const absl::optional<int>& new_target_bitrate_bps =
|
||||
new_config.send_codec_spec->target_bitrate_bps;
|
||||
// If a bitrate has been specified for the codec, use it over the
|
||||
// codec's default.
|
||||
if (!do_not_update_target_bitrate && new_target_bitrate_bps &&
|
||||
if (stream->allocation_settings_.UpdateAudioTargetBitrate(
|
||||
TransportSeqNumId(new_config)) &&
|
||||
new_target_bitrate_bps &&
|
||||
new_target_bitrate_bps !=
|
||||
old_config.send_codec_spec->target_bitrate_bps) {
|
||||
CallEncoder(stream->channel_send_, [&](AudioEncoder* encoder) {
|
||||
@ -711,27 +696,22 @@ void AudioSendStream::ReconfigureBitrateObserver(
|
||||
// allow us to configure the bitrate observer if the new config has bitrate
|
||||
// limits set, but would only have us call RemoveBitrateObserver if we were
|
||||
// previously configured with bitrate limits.
|
||||
int new_transport_seq_num_id =
|
||||
FindExtensionIds(new_config.rtp.extensions).transport_sequence_number;
|
||||
if (stream->config_.min_bitrate_bps == new_config.min_bitrate_bps &&
|
||||
stream->config_.max_bitrate_bps == new_config.max_bitrate_bps &&
|
||||
stream->config_.bitrate_priority == new_config.bitrate_priority &&
|
||||
(FindExtensionIds(stream->config_.rtp.extensions)
|
||||
.transport_sequence_number == new_transport_seq_num_id ||
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe"))) {
|
||||
(TransportSeqNumId(stream->config_) == TransportSeqNumId(new_config) ||
|
||||
stream->allocation_settings_.IgnoreSeqNumIdChange())) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool has_transport_sequence_number = new_transport_seq_num_id != 0;
|
||||
if (new_config.min_bitrate_bps != -1 && new_config.max_bitrate_bps != -1 &&
|
||||
!new_config.has_dscp &&
|
||||
(has_transport_sequence_number ||
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe"))) {
|
||||
if (stream->allocation_settings_.IncludeAudioInAllocationOnReconfigure(
|
||||
new_config.min_bitrate_bps, new_config.max_bitrate_bps,
|
||||
new_config.has_dscp, TransportSeqNumId(new_config))) {
|
||||
stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(true);
|
||||
stream->rtp_rtcp_module_->SetAsPartOfAllocation(true);
|
||||
stream->ConfigureBitrateObserver(new_config.min_bitrate_bps,
|
||||
new_config.max_bitrate_bps,
|
||||
new_config.bitrate_priority);
|
||||
stream->rtp_rtcp_module_->SetAsPartOfAllocation(true);
|
||||
} else {
|
||||
stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(false);
|
||||
stream->RemoveBitrateObserver();
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "call/bitrate_allocator.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
#include "rtc_base/experiments/audio_allocation_settings.h"
|
||||
#include "rtc_base/race_checker.h"
|
||||
#include "rtc_base/thread_checker.h"
|
||||
|
||||
@ -121,6 +122,7 @@ class AudioSendStream final : public webrtc::AudioSendStream,
|
||||
rtc::ThreadChecker pacer_thread_checker_;
|
||||
rtc::RaceChecker audio_capture_race_checker_;
|
||||
rtc::TaskQueue* worker_queue_;
|
||||
const AudioAllocationSettings allocation_settings_;
|
||||
webrtc::AudioSendStream::Config config_;
|
||||
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
|
||||
const std::unique_ptr<voe::ChannelSendInterface> channel_send_;
|
||||
@ -152,6 +154,7 @@ class AudioSendStream final : public webrtc::AudioSendStream,
|
||||
};
|
||||
static ExtensionIds FindExtensionIds(
|
||||
const std::vector<RtpExtension>& extensions);
|
||||
static int TransportSeqNumId(const Config& config);
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream);
|
||||
};
|
||||
|
@ -345,12 +345,6 @@ rtc_static_library("rtc_audio_video") {
|
||||
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
|
||||
if (rtc_opus_support_120ms_ptime) {
|
||||
defines += [ "WEBRTC_OPUS_SUPPORT_120MS_PTIME=1" ]
|
||||
} else {
|
||||
defines += [ "WEBRTC_OPUS_SUPPORT_120MS_PTIME=0" ]
|
||||
}
|
||||
|
||||
include_dirs = []
|
||||
|
||||
public_configs = []
|
||||
@ -391,6 +385,8 @@ rtc_static_library("rtc_audio_video") {
|
||||
"../rtc_base:rtc_base",
|
||||
"../rtc_base:rtc_task_queue",
|
||||
"../rtc_base:stringutils",
|
||||
"../rtc_base/experiments:audio_allocation_settings",
|
||||
"../rtc_base/experiments:field_trial_parser",
|
||||
"../rtc_base/experiments:normalize_simulcast_size_experiment",
|
||||
"../system_wrappers",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "rtc_base/arraysize.h"
|
||||
#include "rtc_base/byte_order.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
#include "rtc_base/experiments/field_trial_units.h"
|
||||
#include "rtc_base/helpers.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/race_checker.h"
|
||||
@ -54,10 +56,6 @@ constexpr size_t kMaxUnsignaledRecvStreams = 4;
|
||||
|
||||
constexpr int kNackRtpHistoryMs = 5000;
|
||||
|
||||
// For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000.
|
||||
const int kOpusMinBitrateBps = 6000;
|
||||
const int kOpusBitrateFbBps = 32000;
|
||||
|
||||
const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1)
|
||||
const int kMaxTelephoneEventCode = 255;
|
||||
|
||||
@ -564,8 +562,7 @@ RtpCapabilities WebRtcVoiceEngine::GetCapabilities() const {
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri,
|
||||
webrtc::RtpExtension::kAudioLevelDefaultId));
|
||||
if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe") &&
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC")) {
|
||||
if (allocation_settings_.EnableTransportSequenceNumberExtension()) {
|
||||
capabilities.header_extensions.push_back(webrtc::RtpExtension(
|
||||
webrtc::RtpExtension::kTransportSequenceNumberUri,
|
||||
webrtc::RtpExtension::kTransportSequenceNumberDefaultId));
|
||||
@ -729,8 +726,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
|
||||
const webrtc::CryptoOptions& crypto_options)
|
||||
: call_(call),
|
||||
config_(send_transport, media_transport),
|
||||
send_side_bwe_with_overhead_(
|
||||
webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
|
||||
max_send_bitrate_bps_(max_send_bitrate_bps),
|
||||
rtp_parameters_(CreateRtpParametersWithOneEncoding()) {
|
||||
RTC_DCHECK(call);
|
||||
@ -991,43 +986,10 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
|
||||
config_.send_codec_spec &&
|
||||
absl::EqualsIgnoreCase(config_.send_codec_spec->format.name,
|
||||
kOpusCodecName);
|
||||
if (is_opus && webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) {
|
||||
config_.min_bitrate_bps = kOpusMinBitrateBps;
|
||||
|
||||
// This means that when RtpParameters is reset, we may change the
|
||||
// encoder's bit rate immediately (through ReconfigureAudioSendStream()),
|
||||
// meanwhile change the cap to the output of BWE.
|
||||
config_.max_bitrate_bps =
|
||||
rtp_parameters_.encodings[0].max_bitrate_bps
|
||||
? *rtp_parameters_.encodings[0].max_bitrate_bps
|
||||
: kOpusBitrateFbBps;
|
||||
|
||||
// TODO(mflodman): Keep testing this and set proper values.
|
||||
// Note: This is an early experiment currently only supported by Opus.
|
||||
if (send_side_bwe_with_overhead_) {
|
||||
const int max_packet_size_ms =
|
||||
WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
|
||||
|
||||
// OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
|
||||
constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
|
||||
|
||||
int min_overhead_bps =
|
||||
kOverheadPerPacket * 8 * 1000 / max_packet_size_ms;
|
||||
|
||||
// We assume that |config_.max_bitrate_bps| before the next line is
|
||||
// a hard limit on the payload bitrate, so we add min_overhead_bps to
|
||||
// it to ensure that, when overhead is deducted, the payload rate
|
||||
// never goes beyond the limit.
|
||||
// Note: this also means that if a higher overhead is forced, we
|
||||
// cannot reach the limit.
|
||||
// TODO(minyue): Reconsider this when the signaling to BWE is done
|
||||
// through a dedicated API.
|
||||
config_.max_bitrate_bps += min_overhead_bps;
|
||||
|
||||
// In contrast to max_bitrate_bps, we let min_bitrate_bps always be
|
||||
// reachable.
|
||||
config_.min_bitrate_bps += min_overhead_bps;
|
||||
}
|
||||
if (is_opus && allocation_settings_.ConfigureRateAllocationRange()) {
|
||||
config_.min_bitrate_bps = allocation_settings_.MinBitrateBps();
|
||||
config_.max_bitrate_bps = allocation_settings_.MaxBitrateBps(
|
||||
rtp_parameters_.encodings[0].max_bitrate_bps);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1064,9 +1026,9 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
|
||||
|
||||
rtc::ThreadChecker worker_thread_checker_;
|
||||
rtc::RaceChecker audio_capture_race_checker_;
|
||||
const webrtc::AudioAllocationSettings allocation_settings_;
|
||||
webrtc::Call* call_ = nullptr;
|
||||
webrtc::AudioSendStream::Config config_;
|
||||
const bool send_side_bwe_with_overhead_;
|
||||
// The stream is owned by WebRtcAudioSendStream and may be reallocated if
|
||||
// configuration changes.
|
||||
webrtc::AudioSendStream* stream_ = nullptr;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "pc/channel.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
#include "rtc_base/experiments/audio_allocation_settings.h"
|
||||
#include "rtc_base/network_route.h"
|
||||
#include "rtc_base/scoped_ref_ptr.h"
|
||||
#include "rtc_base/task_queue.h"
|
||||
@ -106,6 +107,8 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface {
|
||||
rtc::ThreadChecker signal_thread_checker_;
|
||||
rtc::ThreadChecker worker_thread_checker_;
|
||||
|
||||
const webrtc::AudioAllocationSettings allocation_settings_;
|
||||
|
||||
// The audio device module.
|
||||
rtc::scoped_refptr<webrtc::AudioDeviceModule> adm_;
|
||||
rtc::scoped_refptr<webrtc::AudioEncoderFactory> encoder_factory_;
|
||||
|
@ -256,11 +256,11 @@ TEST_F(GoogCcNetworkControllerTest, OnNetworkRouteChanged) {
|
||||
|
||||
// If the bitrate is reset to -1, the new starting bitrate will be
|
||||
// the minimum default bitrate.
|
||||
const DataRate kDefaultMinBitrate = DataRate::bps(10000);
|
||||
const DataRate kDefaultMinBitrate = DataRate::kbps(5);
|
||||
update = controller_->OnNetworkRouteChange(CreateRouteChange());
|
||||
EXPECT_EQ(update.target_rate->target_rate, kDefaultMinBitrate);
|
||||
EXPECT_EQ(update.pacer_config->data_rate(),
|
||||
kDefaultMinBitrate * kDefaultPacingRate);
|
||||
EXPECT_NEAR(update.pacer_config->data_rate().bps<double>(),
|
||||
kDefaultMinBitrate.bps<double>() * kDefaultPacingRate, 10);
|
||||
EXPECT_EQ(update.probe_cluster_configs.size(), 2u);
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ PacedSender::PacedSender(const Clock* clock,
|
||||
drain_large_queues_(!field_trial::IsDisabled("WebRTC-Pacer-DrainQueue")),
|
||||
send_padding_if_silent_(
|
||||
field_trial::IsEnabled("WebRTC-Pacer-PadInSilence")),
|
||||
video_blocks_audio_(!field_trial::IsDisabled("WebRTC-Pacer-BlockAudio")),
|
||||
pace_audio_(!field_trial::IsDisabled("WebRTC-Pacer-BlockAudio")),
|
||||
min_packet_limit_ms_("", kDefaultMinPacketLimitMs),
|
||||
last_timestamp_ms_(clock_->TimeInMilliseconds()),
|
||||
paused_(false),
|
||||
@ -408,8 +408,7 @@ const RoundRobinPacketQueue::Packet* PacedSender::GetPendingPacket(
|
||||
// reinsert it if send fails.
|
||||
const RoundRobinPacketQueue::Packet* packet = &packets_.BeginPop();
|
||||
bool audio_packet = packet->priority == kHighPriority;
|
||||
bool apply_pacing =
|
||||
!audio_packet || account_for_audio_ || video_blocks_audio_;
|
||||
bool apply_pacing = !audio_packet || pace_audio_;
|
||||
if (apply_pacing && (Congested() || (media_budget_.bytes_remaining() == 0 &&
|
||||
pacing_info.probe_cluster_id ==
|
||||
PacedPacketInfo::kNotAProbe))) {
|
||||
|
@ -174,7 +174,7 @@ class PacedSender : public Pacer {
|
||||
|
||||
const bool drain_large_queues_;
|
||||
const bool send_padding_if_silent_;
|
||||
const bool video_blocks_audio_;
|
||||
const bool pace_audio_;
|
||||
FieldTrialParameter<int> min_packet_limit_ms_;
|
||||
|
||||
rtc::CriticalSection critsect_;
|
||||
|
@ -17,12 +17,7 @@ const char kBweTypeHistogram[] = "WebRTC.BWE.Types";
|
||||
|
||||
namespace congestion_controller {
|
||||
int GetMinBitrateBps() {
|
||||
constexpr int kAudioMinBitrateBps = 5000;
|
||||
constexpr int kMinBitrateBps = 10000;
|
||||
if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe") &&
|
||||
!webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe-For-Video")) {
|
||||
return kAudioMinBitrateBps;
|
||||
}
|
||||
constexpr int kMinBitrateBps = 5000;
|
||||
return kMinBitrateBps;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,24 @@ rtc_static_library("alr_experiment") {
|
||||
]
|
||||
}
|
||||
|
||||
rtc_static_library("audio_allocation_settings") {
|
||||
sources = [
|
||||
"audio_allocation_settings.cc",
|
||||
"audio_allocation_settings.h",
|
||||
]
|
||||
defines = []
|
||||
if (rtc_opus_support_120ms_ptime) {
|
||||
defines += [ "WEBRTC_OPUS_SUPPORT_120MS_PTIME=1" ]
|
||||
} else {
|
||||
defines += [ "WEBRTC_OPUS_SUPPORT_120MS_PTIME=0" ]
|
||||
}
|
||||
deps = [
|
||||
":field_trial_parser",
|
||||
"../:rtc_base_approved",
|
||||
"../../system_wrappers:field_trial",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_static_library("field_trial_parser") {
|
||||
sources = [
|
||||
"field_trial_parser.cc",
|
||||
|
@ -1,4 +1,5 @@
|
||||
per-file alr_experiment*=sprang@webrtc.org
|
||||
per-file audio_allocation_settings*=srte@webrtc.org
|
||||
per-file congestion_controller_experiment*=srte@webrtc.org
|
||||
per-file cpu_speed_experiment*=asapersson@webrtc.org
|
||||
per-file field_trial*=srte@webrtc.org
|
||||
|
138
rtc_base/experiments/audio_allocation_settings.cc
Normal file
138
rtc_base/experiments/audio_allocation_settings.cc
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2019 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 "rtc_base/experiments/audio_allocation_settings.h"
|
||||
#include "system_wrappers/include/field_trial.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
// For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000.
|
||||
const int kOpusMinBitrateBps = 6000;
|
||||
const int kOpusBitrateFbBps = 32000;
|
||||
} // namespace
|
||||
AudioAllocationSettings::AudioAllocationSettings()
|
||||
: audio_send_side_bwe_("Enabled"),
|
||||
allocate_audio_without_feedback_("Enabled"),
|
||||
force_no_audio_feedback_("Enabled"),
|
||||
audio_feedback_to_improve_video_bwe_("Enabled"),
|
||||
send_side_bwe_with_overhead_("Enabled") {
|
||||
ParseFieldTrial({&audio_send_side_bwe_},
|
||||
field_trial::FindFullName("WebRTC-Audio-SendSideBwe"));
|
||||
ParseFieldTrial({&allocate_audio_without_feedback_},
|
||||
field_trial::FindFullName("WebRTC-Audio-ABWENoTWCC"));
|
||||
ParseFieldTrial({&force_no_audio_feedback_},
|
||||
field_trial::FindFullName("WebRTC-Audio-ForceNoTWCC"));
|
||||
ParseFieldTrial(
|
||||
{&audio_feedback_to_improve_video_bwe_},
|
||||
field_trial::FindFullName("WebRTC-Audio-SendSideBwe-For-Video"));
|
||||
ParseFieldTrial({&send_side_bwe_with_overhead_},
|
||||
field_trial::FindFullName("WebRTC-SendSideBwe-WithOverhead"));
|
||||
|
||||
// TODO(mflodman): Keep testing this and set proper values.
|
||||
// Note: This is an early experiment currently only supported by Opus.
|
||||
if (send_side_bwe_with_overhead_) {
|
||||
constexpr int kMaxPacketSizeMs = WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;
|
||||
|
||||
// OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
|
||||
constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
|
||||
min_overhead_bps_ = kOverheadPerPacket * 8 * 1000 / kMaxPacketSizeMs;
|
||||
}
|
||||
}
|
||||
|
||||
AudioAllocationSettings::~AudioAllocationSettings() {}
|
||||
|
||||
bool AudioAllocationSettings::ForceNoAudioFeedback() const {
|
||||
return force_no_audio_feedback_;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::IgnoreSeqNumIdChange() const {
|
||||
return !audio_send_side_bwe_;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::ConfigureRateAllocationRange() const {
|
||||
return audio_send_side_bwe_;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::EnableTransportSequenceNumberExtension() const {
|
||||
// TODO(srte): Update this to be more accurate.
|
||||
return audio_send_side_bwe_ && !allocate_audio_without_feedback_;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::IncludeAudioInFeedback(
|
||||
int transport_seq_num_extension_header_id) const {
|
||||
if (force_no_audio_feedback_)
|
||||
return false;
|
||||
return transport_seq_num_extension_header_id != 0;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::UpdateAudioTargetBitrate(
|
||||
int transport_seq_num_extension_header_id) const {
|
||||
// If other side does not support audio TWCC and WebRTC-Audio-ABWENoTWCC is
|
||||
// not enabled, do not update target audio bitrate if we are in
|
||||
// WebRTC-Audio-SendSideBwe-For-Video experiment
|
||||
if (allocate_audio_without_feedback_ ||
|
||||
transport_seq_num_extension_header_id != 0)
|
||||
return true;
|
||||
if (audio_feedback_to_improve_video_bwe_)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::IncludeAudioInAllocationOnStart(
|
||||
int min_bitrate_bps,
|
||||
int max_bitrate_bps,
|
||||
bool has_dscp,
|
||||
int transport_seq_num_extension_header_id) const {
|
||||
if (has_dscp || min_bitrate_bps == -1 || max_bitrate_bps == -1)
|
||||
return false;
|
||||
if (transport_seq_num_extension_header_id != 0 && !force_no_audio_feedback_)
|
||||
return true;
|
||||
if (allocate_audio_without_feedback_)
|
||||
return true;
|
||||
if (audio_send_side_bwe_)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioAllocationSettings::IncludeAudioInAllocationOnReconfigure(
|
||||
int min_bitrate_bps,
|
||||
int max_bitrate_bps,
|
||||
bool has_dscp,
|
||||
int transport_seq_num_extension_header_id) const {
|
||||
// TODO(srte): Make this match include_audio_in_allocation_on_start.
|
||||
if (has_dscp || min_bitrate_bps == -1 || max_bitrate_bps == -1)
|
||||
return false;
|
||||
if (transport_seq_num_extension_header_id != 0)
|
||||
return true;
|
||||
if (audio_send_side_bwe_)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int AudioAllocationSettings::MinBitrateBps() const {
|
||||
return kOpusMinBitrateBps + min_overhead_bps_;
|
||||
}
|
||||
|
||||
int AudioAllocationSettings::MaxBitrateBps(
|
||||
absl::optional<int> rtp_parameter_max_bitrate_bps) const {
|
||||
// We assume that the max is a hard limit on the payload bitrate, so we add
|
||||
// min_overhead_bps to it to ensure that, when overhead is deducted, the
|
||||
// payload rate never goes beyond the limit. Note: this also means that if a
|
||||
// higher overhead is forced, we cannot reach the limit.
|
||||
// TODO(minyue): Reconsider this when the signaling to BWE is done
|
||||
// through a dedicated API.
|
||||
|
||||
// This means that when RtpParameters is reset, we may change the
|
||||
// encoder's bit rate immediately (through ReconfigureAudioSendStream()),
|
||||
// meanwhile change the cap to the output of BWE.
|
||||
if (rtp_parameter_max_bitrate_bps)
|
||||
return *rtp_parameter_max_bitrate_bps + min_overhead_bps_;
|
||||
return kOpusBitrateFbBps + min_overhead_bps_;
|
||||
}
|
||||
} // namespace webrtc
|
89
rtc_base/experiments/audio_allocation_settings.h
Normal file
89
rtc_base/experiments/audio_allocation_settings.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2019 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 RTC_BASE_EXPERIMENTS_AUDIO_ALLOCATION_SETTINGS_H_
|
||||
#define RTC_BASE_EXPERIMENTS_AUDIO_ALLOCATION_SETTINGS_H_
|
||||
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
#include "rtc_base/experiments/field_trial_units.h"
|
||||
namespace webrtc {
|
||||
// This class encapsulates the logic that controls how allocation of audio
|
||||
// bitrate is done. This is primarily based on field trials, but also on the
|
||||
// values of audio parameters.
|
||||
class AudioAllocationSettings {
|
||||
public:
|
||||
AudioAllocationSettings();
|
||||
~AudioAllocationSettings();
|
||||
// Returns true if audio feedback should be force disabled.
|
||||
bool ForceNoAudioFeedback() const;
|
||||
// Returns true if changes in transport sequence number id should be ignored
|
||||
// as a trigger for reconfiguration.
|
||||
bool IgnoreSeqNumIdChange() const;
|
||||
// Returns true if the bitrate allocation range should be configured.
|
||||
bool ConfigureRateAllocationRange() const;
|
||||
// Returns true if the transport sequence number extension should be enabled.
|
||||
bool EnableTransportSequenceNumberExtension() const;
|
||||
// Returns true if audio traffic should be included in transport wide feedback
|
||||
// packets.
|
||||
// |transport_seq_num_extension_header_id| the extension header id for
|
||||
// transport sequence numbers. Set to 0 if not the extension is not
|
||||
// configured.
|
||||
bool IncludeAudioInFeedback(int transport_seq_num_extension_header_id) const;
|
||||
// Returns true if target bitrate for audio streams should be updated.
|
||||
// |transport_seq_num_extension_header_id| the extension header id for
|
||||
// transport sequence numbers. Set to 0 if not the extension is not
|
||||
// configured.
|
||||
bool UpdateAudioTargetBitrate(
|
||||
int transport_seq_num_extension_header_id) const;
|
||||
// Returns true if audio should be added to rate allocation when the audio
|
||||
// stream is started.
|
||||
// |min_bitrate_bps| the configured min bitrate, set to -1 if unset.
|
||||
// |max_bitrate_bps| the configured max bitrate, set to -1 if unset.
|
||||
// |has_dscp| true is dscp is enabled.
|
||||
// |transport_seq_num_extension_header_id| the extension header id for
|
||||
// transport sequence numbers. Set to 0 if not the extension is not
|
||||
// configured.
|
||||
bool IncludeAudioInAllocationOnStart(
|
||||
int min_bitrate_bps,
|
||||
int max_bitrate_bps,
|
||||
bool has_dscp,
|
||||
int transport_seq_num_extension_header_id) const;
|
||||
// Returns true if audio should be added to rate allocation when the audio
|
||||
// stream is reconfigured.
|
||||
// |min_bitrate_bps| the configured min bitrate, set to -1 if unset.
|
||||
// |max_bitrate_bps| the configured max bitrate, set to -1 if unset.
|
||||
// |has_dscp| true is dscp is enabled.
|
||||
// |transport_seq_num_extension_header_id| the extension header id for
|
||||
// transport sequence numbers. Set to 0 if not the extension is not
|
||||
// configured.
|
||||
bool IncludeAudioInAllocationOnReconfigure(
|
||||
int min_bitrate_bps,
|
||||
int max_bitrate_bps,
|
||||
bool has_dscp,
|
||||
int transport_seq_num_extension_header_id) const;
|
||||
|
||||
// Returns the min bitrate for audio rate allocation, potentially including
|
||||
// overhead.
|
||||
int MinBitrateBps() const;
|
||||
// Returns the max bitrate for audio rate allocation, potentially including
|
||||
// overhead. |rtp_parameter_max_bitrate_bps| max bitrate as configured in rtp
|
||||
// parameters, excluding overhead.
|
||||
int MaxBitrateBps(absl::optional<int> rtp_parameter_max_bitrate_bps) const;
|
||||
|
||||
private:
|
||||
FieldTrialFlag audio_send_side_bwe_;
|
||||
FieldTrialFlag allocate_audio_without_feedback_;
|
||||
FieldTrialFlag force_no_audio_feedback_;
|
||||
FieldTrialFlag audio_feedback_to_improve_video_bwe_;
|
||||
FieldTrialFlag send_side_bwe_with_overhead_;
|
||||
int min_overhead_bps_ = 0;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // RTC_BASE_EXPERIMENTS_AUDIO_ALLOCATION_SETTINGS_H_
|
@ -109,22 +109,6 @@ SendAudioStream::SendAudioStream(
|
||||
min_rate = *config.encoder.min_rate;
|
||||
max_rate = *config.encoder.max_rate;
|
||||
}
|
||||
if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
|
||||
TimeDelta min_frame_length = TimeDelta::ms(20);
|
||||
// Note, depends on WEBRTC_OPUS_SUPPORT_120MS_PTIME being set, which is
|
||||
// the default.
|
||||
TimeDelta max_frame_length = TimeDelta::ms(120);
|
||||
DataSize rtp_overhead = DataSize::bytes(12);
|
||||
// Note that this does not include rtp extension overhead and will not
|
||||
// follow updates in the transport overhead over time.
|
||||
DataSize total_overhead =
|
||||
sender_->transport_.packet_overhead() + rtp_overhead;
|
||||
|
||||
min_rate += total_overhead / max_frame_length;
|
||||
// In WebRTCVoiceEngine the max rate is also based on the max frame
|
||||
// length.
|
||||
max_rate += total_overhead / min_frame_length;
|
||||
}
|
||||
send_config.min_bitrate_bps = min_rate.bps();
|
||||
send_config.max_bitrate_bps = max_rate.bps();
|
||||
}
|
||||
|
Reference in New Issue
Block a user