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:
Sebastian Jansson
2019-01-23 12:37:49 +01:00
committed by Commit Bot
parent 33b716f7dd
commit 470a5eae93
15 changed files with 294 additions and 125 deletions

View File

@ -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",

View File

@ -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();

View File

@ -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);
};

View File

@ -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",

View File

@ -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;

View File

@ -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_;

View File

@ -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);
}

View File

@ -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))) {

View File

@ -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_;

View File

@ -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;
}

View File

@ -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",

View File

@ -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

View 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

View 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_

View File

@ -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();
}