Adds audio priority bitrate field trial parameter.

This replaces the functionality provided by
AudioPriorityBitrateAllocationStrategy, removing the need provide that
component via injection in all clients using audio bitrate priority.

Bug: webrtc:10286
Change-Id: I3bafab56d24459d9d27dc07abffdc8538440a346
Reviewed-on: https://webrtc-review.googlesource.com/c/121402
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26651}
This commit is contained in:
Sebastian Jansson 2019-02-12 13:32:32 +01:00 committed by Commit Bot
parent eb81b47123
commit 464a5576ea
8 changed files with 127 additions and 40 deletions

View File

@ -785,10 +785,11 @@ void AudioSendStream::ConfigureBitrateObserver(int min_bitrate_bps,
config_.bitrate_priority = bitrate_priority;
// This either updates the current observer or adds a new observer.
bitrate_allocator_->AddObserver(
this,
MediaStreamAllocationConfig{static_cast<uint32_t>(min_bitrate_bps),
static_cast<uint32_t>(max_bitrate_bps), 0,
true, config_.track_id, bitrate_priority});
this, MediaStreamAllocationConfig{
static_cast<uint32_t>(min_bitrate_bps),
static_cast<uint32_t>(max_bitrate_bps), 0,
allocation_settings_.DefaultPriorityBitrate().bps(), true,
config_.track_id, bitrate_priority});
thread_sync_event.Set();
});
thread_sync_event.Wait(rtc::Event::kForever);

View File

@ -174,10 +174,10 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
it->enforce_min_bitrate = config.enforce_min_bitrate;
it->bitrate_priority = config.bitrate_priority;
} else {
bitrate_observer_configs_.push_back(
ObserverConfig(observer, config.min_bitrate_bps, config.max_bitrate_bps,
config.pad_up_bitrate_bps, config.enforce_min_bitrate,
config.track_id, config.bitrate_priority));
bitrate_observer_configs_.push_back(ObserverConfig(
observer, config.min_bitrate_bps, config.max_bitrate_bps,
config.pad_up_bitrate_bps, config.priority_bitrate_bps,
config.enforce_min_bitrate, config.track_id, config.bitrate_priority));
}
if (last_target_bps_ > 0) {
@ -439,6 +439,21 @@ BitrateAllocator::ObserverAllocation BitrateAllocator::NormalRateAllocation(
}
bitrate -= sum_min_bitrates;
// TODO(srte): Implement fair sharing between prioritized streams, currently
// they are treated on a first come first serve basis.
for (const auto& observer_config : bitrate_observer_configs_) {
int64_t priority_margin = observer_config.priority_bitrate_bps -
allocation[observer_config.observer];
if (priority_margin > 0 && bitrate > 0) {
int64_t extra_bitrate = std::min<int64_t>(priority_margin, bitrate);
allocation[observer_config.observer] +=
rtc::dchecked_cast<int>(extra_bitrate);
observers_capacities[observer_config.observer] -= extra_bitrate;
bitrate -= extra_bitrate;
}
}
// From the remaining bitrate, allocate a proportional amount to each observer
// above the min bitrate already allocated.
if (bitrate > 0)

View File

@ -55,6 +55,7 @@ struct MediaStreamAllocationConfig {
uint32_t min_bitrate_bps;
uint32_t max_bitrate_bps;
uint32_t pad_up_bitrate_bps;
int64_t priority_bitrate_bps;
bool enforce_min_bitrate;
std::string track_id;
double bitrate_priority;
@ -128,6 +129,7 @@ class BitrateAllocator : public BitrateAllocatorInterface {
uint32_t min_bitrate_bps,
uint32_t max_bitrate_bps,
uint32_t pad_up_bitrate_bps,
int64_t priority_bitrate_bps,
bool enforce_min_bitrate,
std::string track_id,
double bitrate_priority)
@ -137,12 +139,14 @@ class BitrateAllocator : public BitrateAllocatorInterface {
track_id),
observer(observer),
pad_up_bitrate_bps(pad_up_bitrate_bps),
priority_bitrate_bps(priority_bitrate_bps),
allocated_bitrate_bps(-1),
media_ratio(1.0),
bitrate_priority(bitrate_priority) {}
BitrateAllocatorObserver* observer;
uint32_t pad_up_bitrate_bps;
int64_t priority_bitrate_bps;
int64_t allocated_bitrate_bps;
double media_ratio; // Part of the total bitrate used for media [0.0, 1.0].
// The amount of bitrate allocated to this observer relative to all other

View File

@ -100,13 +100,60 @@ class BitrateAllocatorTest : public ::testing::Test {
double bitrate_priority) {
allocator_->AddObserver(
observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps,
enforce_min_bitrate, track_id, bitrate_priority});
/* priority_bitrate */ 0, enforce_min_bitrate, track_id,
bitrate_priority});
}
MediaStreamAllocationConfig DefaultConfig() const {
MediaStreamAllocationConfig default_config;
default_config.min_bitrate_bps = 0;
default_config.max_bitrate_bps = 1500000;
default_config.pad_up_bitrate_bps = 0;
default_config.priority_bitrate_bps = 0;
default_config.enforce_min_bitrate = true;
default_config.track_id = "";
default_config.bitrate_priority = kDefaultBitratePriority;
return default_config;
}
NiceMock<MockLimitObserver> limit_observer_;
std::unique_ptr<BitrateAllocatorForTest> allocator_;
};
TEST_F(BitrateAllocatorTest, RespectsPriorityBitrate) {
TestBitrateObserver stream_a;
auto config_a = DefaultConfig();
config_a.min_bitrate_bps = 100000;
config_a.priority_bitrate_bps = 0;
allocator_->AddObserver(&stream_a, config_a);
TestBitrateObserver stream_b;
auto config_b = DefaultConfig();
config_b.min_bitrate_bps = 100000;
config_b.max_bitrate_bps = 300000;
config_b.priority_bitrate_bps = 300000;
allocator_->AddObserver(&stream_b, config_b);
allocator_->OnNetworkChanged(100000, 0, 0, 0);
EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
EXPECT_EQ(stream_b.last_bitrate_bps_, 100000u);
allocator_->OnNetworkChanged(200000, 0, 0, 0);
EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
EXPECT_EQ(stream_b.last_bitrate_bps_, 100000u);
allocator_->OnNetworkChanged(300000, 0, 0, 0);
EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
EXPECT_EQ(stream_b.last_bitrate_bps_, 200000u);
allocator_->OnNetworkChanged(400000, 0, 0, 0);
EXPECT_EQ(stream_a.last_bitrate_bps_, 100000u);
EXPECT_EQ(stream_b.last_bitrate_bps_, 300000u);
allocator_->OnNetworkChanged(800000, 0, 0, 0);
EXPECT_EQ(stream_a.last_bitrate_bps_, 500000u);
EXPECT_EQ(stream_b.last_bitrate_bps_, 300000u);
}
TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
TestBitrateObserver bitrate_observer;
const uint32_t kMinSendBitrateBps = 100000;
@ -232,7 +279,7 @@ class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
std::string track_id,
double bitrate_priority) {
allocator_->AddObserver(
observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps,
observer, {min_bitrate_bps, max_bitrate_bps, pad_up_bitrate_bps, 0,
enforce_min_bitrate, track_id, bitrate_priority});
}
NiceMock<MockLimitObserver> limit_observer_;
@ -404,9 +451,10 @@ TEST_F(BitrateAllocatorTest,
EXPECT_CALL(limit_observer_,
OnAllocationLimitsChanged(kMinBitrateBps, 0, kMaxBitrateBps))
.Times(1);
allocator_->AddObserver(
&bitrate_observer,
{kMinBitrateBps, kMaxBitrateBps, 0, true, "", kDefaultBitratePriority});
MediaStreamAllocationConfig allocation_config = DefaultConfig();
allocation_config.min_bitrate_bps = kMinBitrateBps;
allocation_config.max_bitrate_bps = kMaxBitrateBps;
allocator_->AddObserver(&bitrate_observer, allocation_config);
// Observer uses 20% of it's allocated bitrate for protection.
bitrate_observer.SetBitrateProtectionRatio(/*protection_ratio=*/0.2);

View File

@ -15,13 +15,18 @@ namespace {
// For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000.
const int kOpusMinBitrateBps = 6000;
const int kOpusBitrateFbBps = 32000;
// OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
} // 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") {
send_side_bwe_with_overhead_("Enabled"),
default_min_bitrate_("min", DataRate::bps(kOpusMinBitrateBps)),
default_max_bitrate_("max", DataRate::bps(kOpusBitrateFbBps)),
priority_bitrate_("prio", DataRate::Zero()) {
ParseFieldTrial({&audio_send_side_bwe_},
field_trial::FindFullName("WebRTC-Audio-SendSideBwe"));
ParseFieldTrial({&allocate_audio_without_feedback_},
@ -31,16 +36,17 @@ AudioAllocationSettings::AudioAllocationSettings()
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"));
ParseFieldTrial(
{&default_min_bitrate_, &default_max_bitrate_, &priority_bitrate_},
field_trial::FindFullName("WebRTC-Audio-Allocation"));
// 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;
}
}
@ -116,7 +122,7 @@ bool AudioAllocationSettings::IncludeAudioInAllocationOnReconfigure(
}
int AudioAllocationSettings::MinBitrateBps() const {
return kOpusMinBitrateBps + min_overhead_bps_;
return default_min_bitrate_->bps() + min_overhead_bps_;
}
int AudioAllocationSettings::MaxBitrateBps(
@ -133,6 +139,15 @@ int AudioAllocationSettings::MaxBitrateBps(
// 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_;
return default_max_bitrate_->bps() + min_overhead_bps_;
}
DataRate AudioAllocationSettings::DefaultPriorityBitrate() const {
DataRate max_overhead = DataRate::Zero();
if (send_side_bwe_with_overhead_) {
const TimeDelta kMinPacketDuration = TimeDelta::ms(20);
max_overhead = DataSize::bytes(kOverheadPerPacket) / kMinPacketDuration;
}
return priority_bitrate_.Get() + max_overhead;
}
} // namespace webrtc

View File

@ -75,6 +75,10 @@ class AudioAllocationSettings {
// 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;
// Indicates the default priority bitrate for audio streams. The bitrate
// allocator will prioritize audio until it reaches this bitrate and will
// divide bitrate evently between audio and video above this bitrate.
DataRate DefaultPriorityBitrate() const;
private:
FieldTrialFlag audio_send_side_bwe_;
@ -83,6 +87,11 @@ class AudioAllocationSettings {
FieldTrialFlag audio_feedback_to_improve_video_bwe_;
FieldTrialFlag send_side_bwe_with_overhead_;
int min_overhead_bps_ = 0;
// Default bitrates to use as range if there's no user configured
// bitrate range but audio bitrate allocation is enabled.
FieldTrialParameter<DataRate> default_min_bitrate_;
FieldTrialParameter<DataRate> default_max_bitrate_;
FieldTrialParameter<DataRate> priority_bitrate_;
};
} // namespace webrtc

View File

@ -385,13 +385,7 @@ void VideoSendStreamImpl::Start() {
void VideoSendStreamImpl::StartupVideoSendStream() {
RTC_DCHECK_RUN_ON(worker_queue_);
bitrate_allocator_->AddObserver(
this,
MediaStreamAllocationConfig{
static_cast<uint32_t>(encoder_min_bitrate_bps_),
encoder_max_bitrate_bps_, static_cast<uint32_t>(max_padding_bitrate_),
!config_->suspend_below_min_bitrate, config_->track_id,
encoder_bitrate_priority_});
bitrate_allocator_->AddObserver(this, GetAllocationConfig());
// Start monitoring encoder activity.
{
RTC_DCHECK(!check_encoder_activity_task_.Running());
@ -498,13 +492,18 @@ void VideoSendStreamImpl::OnBitrateAllocationUpdated(
void VideoSendStreamImpl::SignalEncoderActive() {
RTC_DCHECK_RUN_ON(worker_queue_);
RTC_LOG(LS_INFO) << "SignalEncoderActive, Encoder is active.";
bitrate_allocator_->AddObserver(
this,
MediaStreamAllocationConfig{
static_cast<uint32_t>(encoder_min_bitrate_bps_),
encoder_max_bitrate_bps_, static_cast<uint32_t>(max_padding_bitrate_),
!config_->suspend_below_min_bitrate, config_->track_id,
encoder_bitrate_priority_});
bitrate_allocator_->AddObserver(this, GetAllocationConfig());
}
MediaStreamAllocationConfig VideoSendStreamImpl::GetAllocationConfig() const {
return MediaStreamAllocationConfig{
static_cast<uint32_t>(encoder_min_bitrate_bps_),
encoder_max_bitrate_bps_,
static_cast<uint32_t>(max_padding_bitrate_),
/* priority_bitrate */ 0,
!config_->suspend_below_min_bitrate,
config_->track_id,
encoder_bitrate_priority_};
}
void VideoSendStreamImpl::OnEncoderConfigurationChanged(
@ -571,13 +570,7 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged(
if (rtp_video_sender_->IsActive()) {
// The send stream is started already. Update the allocator with new bitrate
// limits.
bitrate_allocator_->AddObserver(
this, MediaStreamAllocationConfig{
static_cast<uint32_t>(encoder_min_bitrate_bps_),
encoder_max_bitrate_bps_,
static_cast<uint32_t>(max_padding_bitrate_),
!config_->suspend_below_min_bitrate, config_->track_id,
encoder_bitrate_priority_});
bitrate_allocator_->AddObserver(this, GetAllocationConfig());
}
}

View File

@ -139,6 +139,8 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
void ConfigureSsrcs();
void SignalEncoderTimedOut();
void SignalEncoderActive();
MediaStreamAllocationConfig GetAllocationConfig() const
RTC_RUN_ON(worker_queue_);
const bool has_alr_probing_;
const PacingConfig pacing_config_;