Fixes bug in AudioPriorityBitrateAllocationStrategy field trial.
Previously the rate limits weren't properly applied. This is fixed by
working on mutable copies of the TrackConfig.
Bug: webrtc:9718
Change-Id: I7438c59efa5d7e70fa3ce5e466e2c53a5a7ea9e2
Reviewed-on: https://webrtc-review.googlesource.com/c/107636
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25367}
diff --git a/call/bitrate_allocator.cc b/call/bitrate_allocator.cc
index 64d1a486..c13b7dc 100644
--- a/call/bitrate_allocator.cc
+++ b/call/bitrate_allocator.cc
@@ -301,14 +301,14 @@
return ObserverAllocation();
if (bitrate_allocation_strategy_ != nullptr) {
- std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
- track_configs(bitrate_observer_configs_.size());
- int i = 0;
- for (const auto& c : bitrate_observer_configs_) {
- track_configs[i++] = &c;
- }
+ // Note: This intentionally causes slicing, we only copy the fields in
+ // ObserverConfig that are inherited from TrackConfig.
+ std::vector<rtc::BitrateAllocationStrategy::TrackConfig> track_configs(
+ bitrate_observer_configs_.begin(), bitrate_observer_configs_.end());
+
std::vector<uint32_t> track_allocations =
- bitrate_allocation_strategy_->AllocateBitrates(bitrate, track_configs);
+ bitrate_allocation_strategy_->AllocateBitrates(
+ bitrate, std::move(track_configs));
// The strategy should return allocation for all tracks.
RTC_CHECK(track_allocations.size() == bitrate_observer_configs_.size());
ObserverAllocation allocation;
diff --git a/rtc_base/bitrateallocationstrategy.cc b/rtc_base/bitrateallocationstrategy.cc
index 3c41207..46e6674 100644
--- a/rtc_base/bitrateallocationstrategy.cc
+++ b/rtc_base/bitrateallocationstrategy.cc
@@ -43,31 +43,31 @@
const int kTransmissionMaxBitrateMultiplier = 2;
std::vector<uint32_t> BitrateAllocationStrategy::SetAllBitratesToMinimum(
- const ArrayView<const TrackConfig*> track_configs) {
+ const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs) {
std::vector<uint32_t> track_allocations;
- for (const auto* track_config : track_configs) {
- track_allocations.push_back(track_config->min_bitrate_bps);
+ for (const auto& track_config : track_configs) {
+ track_allocations.push_back(track_config.min_bitrate_bps);
}
return track_allocations;
}
std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly(
- const ArrayView<const TrackConfig*> track_configs,
+ const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs,
uint32_t available_bitrate) {
std::vector<uint32_t> track_allocations =
SetAllBitratesToMinimum(track_configs);
uint32_t sum_min_bitrates = 0;
uint32_t sum_max_bitrates = 0;
- for (const auto* track_config : track_configs) {
- sum_min_bitrates += track_config->min_bitrate_bps;
- sum_max_bitrates += track_config->max_bitrate_bps;
+ for (const auto& track_config : track_configs) {
+ sum_min_bitrates += track_config.min_bitrate_bps;
+ sum_max_bitrates += track_config.max_bitrate_bps;
}
if (sum_min_bitrates >= available_bitrate) {
return track_allocations;
} else if (available_bitrate >= sum_max_bitrates) {
auto track_allocations_it = track_allocations.begin();
- for (const auto* track_config : track_configs) {
- *track_allocations_it++ = track_config->max_bitrate_bps;
+ for (const auto& track_config : track_configs) {
+ *track_allocations_it++ = track_config.max_bitrate_bps;
}
return track_allocations;
} else {
@@ -76,11 +76,10 @@
// lowest max_bitrate_bps. Remainder of available bitrate split evenly among
// remaining tracks.
std::multimap<uint32_t, size_t> max_bitrate_sorted_configs;
- for (const TrackConfig** track_configs_it = track_configs.begin();
- track_configs_it != track_configs.end(); ++track_configs_it) {
+ for (const auto& track_config : track_configs) {
max_bitrate_sorted_configs.insert(
- std::make_pair((*track_configs_it)->max_bitrate_bps,
- track_configs_it - track_configs.begin()));
+ std::make_pair(track_config.max_bitrate_bps,
+ &track_config - &track_configs.front()));
}
uint32_t total_available_increase = available_bitrate - sum_min_bitrates;
int processed_configs = 0;
@@ -89,8 +88,8 @@
total_available_increase /
(static_cast<uint32_t>(track_configs.size() - processed_configs));
uint32_t consumed_increase =
- std::min(track_configs[track_config_pair.second]->max_bitrate_bps -
- track_configs[track_config_pair.second]->min_bitrate_bps,
+ std::min(track_configs[track_config_pair.second].max_bitrate_bps -
+ track_configs[track_config_pair.second].min_bitrate_bps,
available_increase);
track_allocations[track_config_pair.second] += consumed_increase;
total_available_increase -= consumed_increase;
@@ -99,7 +98,6 @@
return track_allocations;
}
}
-
AudioPriorityBitrateAllocationStrategy::AudioPriorityBitrateAllocationStrategy(
std::string audio_track_id,
uint32_t sufficient_audio_bitrate)
@@ -112,45 +110,32 @@
std::vector<uint32_t> AudioPriorityBitrateAllocationStrategy::AllocateBitrates(
uint32_t available_bitrate,
- const ArrayView<const TrackConfig*> track_configs) {
- absl::optional<TrackConfig> audio_track_config;
+ std::vector<BitrateAllocationStrategy::TrackConfig> track_configs) {
+ TrackConfig* audio_track_config = nullptr;
size_t audio_config_index = 0;
uint32_t sum_min_bitrates = 0;
uint32_t sum_max_bitrates = 0;
- for (const auto*& track_config : track_configs) {
- if (track_config->track_id == audio_track_id_) {
+ for (auto& track_config : track_configs) {
+ if (track_config.track_id == audio_track_id_) {
audio_config_index = &track_config - &track_configs[0];
- audio_track_config = *track_config;
+ audio_track_config = &track_config;
if (config_.min_rate)
audio_track_config->min_bitrate_bps = config_.min_rate->bps();
if (config_.max_rate)
audio_track_config->max_bitrate_bps = config_.max_rate->bps();
- sum_min_bitrates += audio_track_config->min_bitrate_bps;
- sum_max_bitrates += audio_track_config->max_bitrate_bps;
- } else {
- sum_min_bitrates += track_config->min_bitrate_bps;
- sum_max_bitrates += track_config->max_bitrate_bps;
}
+ sum_min_bitrates += track_config.min_bitrate_bps;
+ sum_max_bitrates += track_config.max_bitrate_bps;
}
if (sum_max_bitrates < available_bitrate) {
// Allow non audio streams to go above max upto
// kTransmissionMaxBitrateMultiplier * max_bitrate_bps
- size_t track_configs_size = track_configs.size();
- std::vector<TrackConfig> increased_track_configs(track_configs_size);
- std::vector<const TrackConfig*> increased_track_configs_ptr(
- track_configs_size);
- for (unsigned long i = 0; i < track_configs_size; i++) {
- increased_track_configs[i] = (*track_configs[i]);
- increased_track_configs_ptr[i] = &increased_track_configs[i];
- if (track_configs[i]->track_id != audio_track_id_) {
- increased_track_configs[i].max_bitrate_bps =
- track_configs[i]->max_bitrate_bps *
- kTransmissionMaxBitrateMultiplier;
- }
+ for (auto& track_config : track_configs) {
+ if (&track_config != audio_track_config)
+ track_config.max_bitrate_bps *= kTransmissionMaxBitrateMultiplier;
}
- return DistributeBitratesEvenly(increased_track_configs_ptr,
- available_bitrate);
+ return DistributeBitratesEvenly(track_configs, available_bitrate);
}
if (!audio_track_config) {
return DistributeBitratesEvenly(track_configs, available_bitrate);
@@ -172,9 +157,7 @@
// Setting audio track minimum to safe_sufficient_audio_bitrate will
// allow using DistributeBitratesEvenly to allocate at least sufficient
// bitrate for audio and the rest evenly.
- TrackConfig sufficient_track_config(*track_configs[audio_config_index]);
- sufficient_track_config.min_bitrate_bps = safe_sufficient_audio_bitrate;
- track_configs[audio_config_index] = &sufficient_track_config;
+ audio_track_config->min_bitrate_bps = safe_sufficient_audio_bitrate;
std::vector<uint32_t> track_allocations =
DistributeBitratesEvenly(track_configs, available_bitrate);
return track_allocations;
diff --git a/rtc_base/bitrateallocationstrategy.h b/rtc_base/bitrateallocationstrategy.h
index e68ea74..13a4eee 100644
--- a/rtc_base/bitrateallocationstrategy.h
+++ b/rtc_base/bitrateallocationstrategy.h
@@ -57,10 +57,12 @@
std::string track_id;
};
+ // These are only used by AudioPriorityBitrateAllocationStrategy. They are
+ // exposed here to they can be unit tested.
static std::vector<uint32_t> SetAllBitratesToMinimum(
- const ArrayView<const TrackConfig*> track_configs);
+ const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs);
static std::vector<uint32_t> DistributeBitratesEvenly(
- const ArrayView<const TrackConfig*> track_configs,
+ const std::vector<BitrateAllocationStrategy::TrackConfig>& track_configs,
uint32_t available_bitrate);
// Strategy is expected to allocate all available_bitrate up to the sum of
@@ -75,7 +77,7 @@
// available_bitrate decrease.
virtual std::vector<uint32_t> AllocateBitrates(
uint32_t available_bitrate,
- const ArrayView<const TrackConfig*> track_configs) = 0;
+ std::vector<BitrateAllocationStrategy::TrackConfig> track_configs) = 0;
virtual ~BitrateAllocationStrategy() = default;
};
@@ -105,7 +107,8 @@
uint32_t sufficient_audio_bitrate);
std::vector<uint32_t> AllocateBitrates(
uint32_t available_bitrate,
- const ArrayView<const TrackConfig*> track_configs) override;
+ std::vector<BitrateAllocationStrategy::TrackConfig> track_configs)
+ override;
private:
webrtc::AudioPriorityConfig config_;
diff --git a/rtc_base/bitrateallocationstrategy_unittest.cc b/rtc_base/bitrateallocationstrategy_unittest.cc
index bfc41f5..f4c7ee7 100644
--- a/rtc_base/bitrateallocationstrategy_unittest.cc
+++ b/rtc_base/bitrateallocationstrategy_unittest.cc
@@ -43,11 +43,8 @@
BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
max_other_bitrate, false, "")};
- std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
- track_config_ptrs = MakeTrackConfigPtrsVector(track_configs);
-
std::vector<uint32_t> allocations =
- BitrateAllocationStrategy::SetAllBitratesToMinimum(track_config_ptrs);
+ BitrateAllocationStrategy::SetAllBitratesToMinimum(track_configs);
EXPECT_EQ(min_audio_bitrate, allocations[0]);
EXPECT_EQ(min_video_bitrate, allocations[1]);
EXPECT_EQ(min_other_bitrate, allocations[2]);
@@ -76,11 +73,8 @@
BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
max_other_bitrate, false, "")};
- std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
- track_config_ptrs = MakeTrackConfigPtrsVector(track_configs);
-
std::vector<uint32_t> allocations =
- BitrateAllocationStrategy::DistributeBitratesEvenly(track_config_ptrs,
+ BitrateAllocationStrategy::DistributeBitratesEvenly(track_configs,
available_bitrate);
EXPECT_EQ(min_audio_bitrate + even_bitrate_increase, allocations[0]);
EXPECT_EQ(min_video_bitrate + even_bitrate_increase, allocations[1]);
@@ -108,11 +102,7 @@
BitrateAllocationStrategy::TrackConfig(min_other_bitrate,
max_other_bitrate, false, "")};
- std::vector<const rtc::BitrateAllocationStrategy::TrackConfig*>
- track_config_ptrs = MakeTrackConfigPtrsVector(track_configs);
-
- return allocation_strategy.AllocateBitrates(available_bitrate,
- track_config_ptrs);
+ return allocation_strategy.AllocateBitrates(available_bitrate, track_configs);
}
// Test that when the available bitrate is less than the sum of the minimum