From 470a5eae9306f8b2b95613e5df9f64aa0438ebd1 Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Wed, 23 Jan 2019 12:37:49 +0100 Subject: [PATCH] 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 Reviewed-by: Karl Wiberg Reviewed-by: Oskar Sundbom Cr-Commit-Position: refs/heads/master@{#26370} --- audio/BUILD.gn | 1 + audio/audio_send_stream.cc | 68 +++------ audio/audio_send_stream.h | 3 + media/BUILD.gn | 8 +- media/engine/webrtc_voice_engine.cc | 54 +------ media/engine/webrtc_voice_engine.h | 3 + .../goog_cc_network_control_unittest.cc | 6 +- modules/pacing/paced_sender.cc | 5 +- modules/pacing/paced_sender.h | 2 +- .../remote_bitrate_estimator/bwe_defines.cc | 7 +- rtc_base/experiments/BUILD.gn | 18 +++ rtc_base/experiments/OWNERS | 1 + .../experiments/audio_allocation_settings.cc | 138 ++++++++++++++++++ .../experiments/audio_allocation_settings.h | 89 +++++++++++ test/scenario/audio_stream.cc | 16 -- 15 files changed, 294 insertions(+), 125 deletions(-) create mode 100644 rtc_base/experiments/audio_allocation_settings.cc create mode 100644 rtc_base/experiments/audio_allocation_settings.h diff --git a/audio/BUILD.gn b/audio/BUILD.gn index 999851df39..116385e6b7 100644 --- a/audio/BUILD.gn +++ b/audio/BUILD.gn @@ -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", diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index 99a237f722..544c936c8a 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -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& 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(); diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index 38cccd4f31..eb8c952f7f 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -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 audio_state_; const std::unique_ptr channel_send_; @@ -152,6 +154,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, }; static ExtensionIds FindExtensionIds( const std::vector& extensions); + static int TransportSeqNumId(const Config& config); RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream); }; diff --git a/media/BUILD.gn b/media/BUILD.gn index 40c843d99c..7d2c5f9f95 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -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", diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 9c84f7cf61..8089a0f267 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -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; diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 701942dd4e..335c47d4f8 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -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 adm_; rtc::scoped_refptr encoder_factory_; diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc index 5b9b7d06aa..56600b3774 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc @@ -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(), + kDefaultMinBitrate.bps() * kDefaultPacingRate, 10); EXPECT_EQ(update.probe_cluster_configs.size(), 2u); } diff --git a/modules/pacing/paced_sender.cc b/modules/pacing/paced_sender.cc index 1a160d854c..9ab8cdb585 100644 --- a/modules/pacing/paced_sender.cc +++ b/modules/pacing/paced_sender.cc @@ -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))) { diff --git a/modules/pacing/paced_sender.h b/modules/pacing/paced_sender.h index 1949dc00ed..0c7a90cc60 100644 --- a/modules/pacing/paced_sender.h +++ b/modules/pacing/paced_sender.h @@ -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 min_packet_limit_ms_; rtc::CriticalSection critsect_; diff --git a/modules/remote_bitrate_estimator/bwe_defines.cc b/modules/remote_bitrate_estimator/bwe_defines.cc index 91f3cd4050..e2b14b6476 100644 --- a/modules/remote_bitrate_estimator/bwe_defines.cc +++ b/modules/remote_bitrate_estimator/bwe_defines.cc @@ -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; } diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn index 5c0fee22bd..6b283b43b5 100644 --- a/rtc_base/experiments/BUILD.gn +++ b/rtc_base/experiments/BUILD.gn @@ -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", diff --git a/rtc_base/experiments/OWNERS b/rtc_base/experiments/OWNERS index 20d5d7906a..c31e0209ea 100644 --- a/rtc_base/experiments/OWNERS +++ b/rtc_base/experiments/OWNERS @@ -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 diff --git a/rtc_base/experiments/audio_allocation_settings.cc b/rtc_base/experiments/audio_allocation_settings.cc new file mode 100644 index 0000000000..51c859170a --- /dev/null +++ b/rtc_base/experiments/audio_allocation_settings.cc @@ -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 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 diff --git a/rtc_base/experiments/audio_allocation_settings.h b/rtc_base/experiments/audio_allocation_settings.h new file mode 100644 index 0000000000..a932c1334d --- /dev/null +++ b/rtc_base/experiments/audio_allocation_settings.h @@ -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 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_ diff --git a/test/scenario/audio_stream.cc b/test/scenario/audio_stream.cc index 2cbd37d723..20606aad55 100644 --- a/test/scenario/audio_stream.cc +++ b/test/scenario/audio_stream.cc @@ -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(); }