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