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:
Florent Castelli
2019-01-21 14:33:02 +01:00
committed by Commit Bot
parent e6a4793b16
commit 1b761ca21a
6 changed files with 124 additions and 52 deletions

View File

@ -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

View File

@ -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(

View File

@ -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;