diff options
Diffstat (limited to 'third_party/libwebrtc/webrtc/rtc_base/bitrateallocationstrategy.cc')
-rw-r--r-- | third_party/libwebrtc/webrtc/rtc_base/bitrateallocationstrategy.cc | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/third_party/libwebrtc/webrtc/rtc_base/bitrateallocationstrategy.cc b/third_party/libwebrtc/webrtc/rtc_base/bitrateallocationstrategy.cc new file mode 100644 index 0000000000..d2a06cd9ef --- /dev/null +++ b/third_party/libwebrtc/webrtc/rtc_base/bitrateallocationstrategy.cc @@ -0,0 +1,152 @@ +/* + * Copyright 2017 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/bitrateallocationstrategy.h" +#include <algorithm> +#include <utility> + +namespace rtc { + +// The purpose of this is to allow video streams to use extra bandwidth for FEC. +// TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in +// video send stream. Similar logic is implemented in BitrateAllocator. + +const int kTransmissionMaxBitrateMultiplier = 2; + +std::vector<uint32_t> BitrateAllocationStrategy::SetAllBitratesToMinimum( + const ArrayView<const 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); + } + return track_allocations; +} + +std::vector<uint32_t> BitrateAllocationStrategy::DistributeBitratesEvenly( + const ArrayView<const 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; + } + 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; + } + return track_allocations; + } else { + // If sum_min_bitrates < available_bitrate < sum_max_bitrates allocate + // bitrates evenly up to max_bitrate_bps starting from the track with the + // 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) { + max_bitrate_sorted_configs.insert( + std::make_pair((*track_configs_it)->max_bitrate_bps, + track_configs_it - track_configs.begin())); + } + uint32_t total_available_increase = available_bitrate - sum_min_bitrates; + int processed_configs = 0; + for (const auto& track_config_pair : max_bitrate_sorted_configs) { + uint32_t available_increase = + 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, + available_increase); + track_allocations[track_config_pair.second] += consumed_increase; + total_available_increase -= consumed_increase; + ++processed_configs; + } + return track_allocations; + } +} + +AudioPriorityBitrateAllocationStrategy::AudioPriorityBitrateAllocationStrategy( + std::string audio_track_id, + uint32_t sufficient_audio_bitrate) + : audio_track_id_(audio_track_id), + sufficient_audio_bitrate_(sufficient_audio_bitrate) {} + +std::vector<uint32_t> AudioPriorityBitrateAllocationStrategy::AllocateBitrates( + uint32_t available_bitrate, + const ArrayView<const TrackConfig*> track_configs) { + const TrackConfig* audio_track_config = NULL; + 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) { + sum_min_bitrates += track_config->min_bitrate_bps; + sum_max_bitrates += track_config->max_bitrate_bps; + if (track_config->track_id == audio_track_id_) { + audio_track_config = track_config; + audio_config_index = &track_config - &track_configs[0]; + } + } + 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; + } + } + return DistributeBitratesEvenly(increased_track_configs_ptr, + available_bitrate); + } + if (audio_track_config == nullptr) { + return DistributeBitratesEvenly(track_configs, available_bitrate); + } + auto safe_sufficient_audio_bitrate = std::min( + std::max(audio_track_config->min_bitrate_bps, sufficient_audio_bitrate_), + audio_track_config->max_bitrate_bps); + if (available_bitrate <= sum_min_bitrates) { + return SetAllBitratesToMinimum(track_configs); + } else { + if (available_bitrate <= sum_min_bitrates + safe_sufficient_audio_bitrate - + audio_track_config->min_bitrate_bps) { + std::vector<uint32_t> track_allocations = + SetAllBitratesToMinimum(track_configs); + track_allocations[audio_config_index] += + available_bitrate - sum_min_bitrates; + return track_allocations; + } else { + // 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; + std::vector<uint32_t> track_allocations = + DistributeBitratesEvenly(track_configs, available_bitrate); + return track_allocations; + } + } +} + +} // namespace rtc |