Remove simulcast constraints in SimulcastEncoderAdapter
The lowest and highest resolution layers are also identified instead of assuming they are the first and last ones. Bug: webrtc:10069 Change-Id: If9c76d647415c5065b79dc71850709db6bf16f61 Reviewed-on: https://webrtc-review.googlesource.com/c/114429 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Florent Castelli <orphis@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26343}
This commit is contained in:
committed by
Commit Bot
parent
e6a4793b16
commit
1b761ca21a
@ -13,7 +13,9 @@
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
@ -110,10 +112,21 @@ void SimulcastRateAllocator::DistributeAllocationToSimulcastLayers(
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort the layers by maxFramerate, they might not always be from smallest
|
||||
// to biggest
|
||||
std::vector<size_t> layer_index(codec_.numberOfSimulcastStreams);
|
||||
std::iota(layer_index.begin(), layer_index.end(), 0);
|
||||
std::stable_sort(layer_index.begin(), layer_index.end(),
|
||||
[this](size_t a, size_t b) {
|
||||
return std::tie(codec_.simulcastStream[a].maxBitrate) <
|
||||
std::tie(codec_.simulcastStream[b].maxBitrate);
|
||||
});
|
||||
|
||||
// Find the first active layer. We don't allocate to inactive layers.
|
||||
size_t active_layer = 0;
|
||||
for (; active_layer < codec_.numberOfSimulcastStreams; ++active_layer) {
|
||||
if (codec_.simulcastStream[active_layer].active) {
|
||||
if (codec_.simulcastStream[layer_index[active_layer]].active) {
|
||||
// Found the first active layer.
|
||||
break;
|
||||
}
|
||||
@ -127,7 +140,8 @@ void SimulcastRateAllocator::DistributeAllocationToSimulcastLayers(
|
||||
// active layer. Suspending below min bitrate is controlled outside the
|
||||
// codec implementation and is not overridden by this.
|
||||
left_to_allocate = std::max(
|
||||
codec_.simulcastStream[active_layer].minBitrate * 1000, left_to_allocate);
|
||||
codec_.simulcastStream[layer_index[active_layer]].minBitrate * 1000,
|
||||
left_to_allocate);
|
||||
|
||||
// Begin by allocating bitrate to simulcast streams, putting all bitrate in
|
||||
// temporal layer 0. We'll then distribute this bitrate, across potential
|
||||
@ -144,15 +158,16 @@ void SimulcastRateAllocator::DistributeAllocationToSimulcastLayers(
|
||||
size_t top_active_layer = active_layer;
|
||||
// Allocate up to the target bitrate for each active simulcast layer.
|
||||
for (; active_layer < codec_.numberOfSimulcastStreams; ++active_layer) {
|
||||
const SimulcastStream& stream = codec_.simulcastStream[active_layer];
|
||||
const SimulcastStream& stream =
|
||||
codec_.simulcastStream[layer_index[active_layer]];
|
||||
if (!stream.active) {
|
||||
stream_enabled_[active_layer] = false;
|
||||
stream_enabled_[layer_index[active_layer]] = false;
|
||||
continue;
|
||||
}
|
||||
// If we can't allocate to the current layer we can't allocate to higher
|
||||
// layers because they require a higher minimum bitrate.
|
||||
uint32_t min_bitrate = stream.minBitrate * 1000;
|
||||
if (!first_allocation && !stream_enabled_[active_layer]) {
|
||||
if (!first_allocation && !stream_enabled_[layer_index[active_layer]]) {
|
||||
min_bitrate = std::min(
|
||||
static_cast<uint32_t>(hysteresis_factor_ * min_bitrate + 0.5),
|
||||
stream.targetBitrate * 1000);
|
||||
@ -162,18 +177,19 @@ void SimulcastRateAllocator::DistributeAllocationToSimulcastLayers(
|
||||
}
|
||||
|
||||
// We are allocating to this layer so it is the current active allocation.
|
||||
top_active_layer = active_layer;
|
||||
stream_enabled_[active_layer] = true;
|
||||
top_active_layer = layer_index[active_layer];
|
||||
stream_enabled_[layer_index[active_layer]] = true;
|
||||
uint32_t allocation =
|
||||
std::min(left_to_allocate, stream.targetBitrate * 1000);
|
||||
allocated_bitrates_bps->SetBitrate(active_layer, 0, allocation);
|
||||
allocated_bitrates_bps->SetBitrate(layer_index[active_layer], 0,
|
||||
allocation);
|
||||
RTC_DCHECK_LE(allocation, left_to_allocate);
|
||||
left_to_allocate -= allocation;
|
||||
}
|
||||
|
||||
// All layers above this one are not active.
|
||||
for (; active_layer < codec_.numberOfSimulcastStreams; ++active_layer) {
|
||||
stream_enabled_[active_layer] = false;
|
||||
stream_enabled_[layer_index[active_layer]] = false;
|
||||
}
|
||||
|
||||
// Next, try allocate remaining bitrate, up to max bitrate, in top active
|
||||
|
||||
@ -212,7 +212,8 @@ void ConfigureStream(int width,
|
||||
void SimulcastTestFixtureImpl::DefaultSettings(
|
||||
VideoCodec* settings,
|
||||
const int* temporal_layer_profile,
|
||||
VideoCodecType codec_type) {
|
||||
VideoCodecType codec_type,
|
||||
bool reverse_layer_order) {
|
||||
RTC_CHECK(settings);
|
||||
memset(settings, 0, sizeof(VideoCodec));
|
||||
settings->codecType = codec_type;
|
||||
@ -227,26 +228,34 @@ void SimulcastTestFixtureImpl::DefaultSettings(
|
||||
settings->numberOfSimulcastStreams = kNumberOfSimulcastStreams;
|
||||
settings->active = true;
|
||||
ASSERT_EQ(3, kNumberOfSimulcastStreams);
|
||||
int layer_order[3] = {0, 1, 2};
|
||||
if (reverse_layer_order) {
|
||||
layer_order[0] = 2;
|
||||
layer_order[2] = 0;
|
||||
}
|
||||
settings->timing_frame_thresholds = {kDefaultTimingFramesDelayMs,
|
||||
kDefaultOutlierFrameSizePercent};
|
||||
ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, kMaxBitrates[0],
|
||||
kMinBitrates[0], kTargetBitrates[0],
|
||||
&settings->simulcastStream[0], temporal_layer_profile[0]);
|
||||
&settings->simulcastStream[layer_order[0]],
|
||||
temporal_layer_profile[0]);
|
||||
ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, kMaxBitrates[1],
|
||||
kMinBitrates[1], kTargetBitrates[1],
|
||||
&settings->simulcastStream[1], temporal_layer_profile[1]);
|
||||
&settings->simulcastStream[layer_order[1]],
|
||||
temporal_layer_profile[1]);
|
||||
ConfigureStream(kDefaultWidth, kDefaultHeight, kMaxBitrates[2],
|
||||
kMinBitrates[2], kTargetBitrates[2],
|
||||
&settings->simulcastStream[2], temporal_layer_profile[2]);
|
||||
if (codec_type == kVideoCodecVP8) {
|
||||
settings->VP8()->denoisingOn = true;
|
||||
settings->VP8()->automaticResizeOn = false;
|
||||
settings->VP8()->frameDroppingOn = true;
|
||||
settings->VP8()->keyFrameInterval = 3000;
|
||||
} else {
|
||||
settings->H264()->frameDroppingOn = true;
|
||||
settings->H264()->keyFrameInterval = 3000;
|
||||
}
|
||||
&settings->simulcastStream[layer_order[2]],
|
||||
temporal_layer_profile[2]);
|
||||
if (codec_type == kVideoCodecVP8) {
|
||||
settings->VP8()->denoisingOn = true;
|
||||
settings->VP8()->automaticResizeOn = false;
|
||||
settings->VP8()->frameDroppingOn = true;
|
||||
settings->VP8()->keyFrameInterval = 3000;
|
||||
} else {
|
||||
settings->H264()->frameDroppingOn = true;
|
||||
settings->H264()->keyFrameInterval = 3000;
|
||||
}
|
||||
}
|
||||
|
||||
SimulcastTestFixtureImpl::SimulcastTestFixtureImpl(
|
||||
|
||||
@ -55,7 +55,8 @@ class SimulcastTestFixtureImpl final : public SimulcastTestFixture {
|
||||
|
||||
static void DefaultSettings(VideoCodec* settings,
|
||||
const int* temporal_layer_profile,
|
||||
VideoCodecType codec_type);
|
||||
VideoCodecType codec_type,
|
||||
bool reverse_layer_order = false);
|
||||
|
||||
private:
|
||||
class TestEncodedImageCallback;
|
||||
|
||||
Reference in New Issue
Block a user