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}
This commit is contained in:
Sebastian Jansson 2018-10-24 16:02:26 +02:00 committed by Commit Bot
parent c0e4d45ce0
commit e2754c95c5
4 changed files with 43 additions and 67 deletions

View File

@ -301,14 +301,14 @@ BitrateAllocator::ObserverAllocation BitrateAllocator::AllocateBitrates(
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;

View File

@ -43,31 +43,31 @@ namespace rtc {
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 @@ std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly(
// 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 @@ std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly(
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 @@ std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly(
return track_allocations;
}
}
AudioPriorityBitrateAllocationStrategy::AudioPriorityBitrateAllocationStrategy(
std::string audio_track_id,
uint32_t sufficient_audio_bitrate)
@ -112,45 +110,32 @@ AudioPriorityBitrateAllocationStrategy::AudioPriorityBitrateAllocationStrategy(
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 @@ std::vector<uint32_t> AudioPriorityBitrateAllocationStrategy::AllocateBitrates(
// 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;

View File

@ -57,10 +57,12 @@ class BitrateAllocationStrategy {
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 @@ class BitrateAllocationStrategy {
// 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 @@ class AudioPriorityBitrateAllocationStrategy
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_;

View File

@ -43,11 +43,8 @@ TEST(BitrateAllocationStrategyTest, SetAllBitratesToMinimum) {
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 @@ TEST(BitrateAllocationStrategyTest, DistributeBitratesEvenly) {
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 @@ std::vector<uint32_t> RunAudioPriorityAllocation(
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