Add experimental shortened 2-temporal-layer setting

Also adjust to base-layer fraction for the shortened 3-tl pattern to be
60%, just like the 2-tl setting.

This CL removes direct use of the allocation matrix and moves it behind
a static getter.

Bug: webrtc:9477
Change-Id: Ifd7d1edffa0555024fd252834357b926997d13b5
Reviewed-on: https://webrtc-review.googlesource.com/86681
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23834}
This commit is contained in:
Erik Språng 2018-07-04 10:07:40 +02:00 committed by Commit Bot
parent c05bd738d6
commit d92288f5ba
6 changed files with 105 additions and 46 deletions

View File

@ -245,13 +245,14 @@ std::vector<webrtc::VideoStream> GetNormalSimulcastLayers(
int num_temporal_layers = DefaultNumberOfTemporalLayers(s);
if (s == 0 && num_temporal_layers != 3) {
// If alternative number temporal layers is selected, adjust the
// bitrate of the lowest simulcast stream so that absolute bitrate for the
// base temporal layer matches the bitrate for the base temporal layer
// with the default 3 simulcast streams. Otherwise we risk a higher
// threshold for receiving a feed at all.
// bitrate of the lowest simulcast stream so that absolute bitrate for
// the base temporal layer matches the bitrate for the base temporal
// layer with the default 3 simulcast streams. Otherwise we risk a
// higher threshold for receiving a feed at all.
const float rate_factor =
webrtc::kLayerRateAllocation[3][0] /
webrtc::kLayerRateAllocation[num_temporal_layers][0];
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 0) /
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
num_temporal_layers, 0);
layers[s].max_bitrate_bps =
static_cast<int>(layers[s].max_bitrate_bps * rate_factor);
layers[s].target_bitrate_bps =

View File

@ -93,7 +93,11 @@ std::vector<bool> GetTemporalLayerSync(size_t num_layers) {
case 1:
return {false};
case 2:
return {false, true, false, false, false, false, false, false};
if (field_trial::IsEnabled("WebRTC-UseShortVP8TL2Pattern")) {
return {false, true, false, false};
} else {
return {false, true, false, false, false, false, false, false};
}
case 3:
if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
return {false, true, true, false};
@ -135,30 +139,55 @@ std::vector<TemporalLayers::FrameConfig> GetTemporalPattern(size_t num_layers) {
// that the 'alt' buffer reference is effectively the last keyframe.
// TL0 also references and updates the 'last' buffer.
// TL1 also references 'last' and references and updates 'golden'.
return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(
TemporalLayers::kReference, TemporalLayers::kReference,
TemporalLayers::kReference, TemporalLayers::kFreezeEntropy)};
if (field_trial::IsEnabled("WebRTC-UseShortVP8TL2Pattern")) {
// Shortened 4-frame pattern:
// 1---1 1---1 ...
// / / / /
// 0---0---0---0 ...
return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kReference,
TemporalLayers::kReference,
TemporalLayers::kFreezeEntropy)};
} else {
// "Default" 8-frame pattern:
// 1---1---1---1 1---1---1---1 ...
// / / / / / / / /
// 0---0---0---0---0---0---0---0 ...
return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate,
TemporalLayers::kNone,
TemporalLayers::kReference),
TemporalLayers::FrameConfig(TemporalLayers::kReference,
TemporalLayers::kReference,
TemporalLayers::kReference,
TemporalLayers::kFreezeEntropy)};
}
case 3:
if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
// This field trial is intended to check if it is worth using a shorter

View File

@ -400,7 +400,9 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) {
int VCMFecMethod::BitsPerFrame(const VCMProtectionParameters* parameters) {
// When temporal layers are available FEC will only be applied on the base
// layer.
const float bitRateRatio = kLayerRateAllocation[parameters->numLayers - 1][0];
const float bitRateRatio =
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
parameters->numLayers, 0);
float frameRateRatio = powf(1 / 2.0, parameters->numLayers - 1);
float bitRate = parameters->bitRate * bitRateRatio;
float frameRate = parameters->frameRate * frameRateRatio;

View File

@ -17,8 +17,37 @@
#include "common_types.h" // NOLINT(build/include)
#include "rtc_base/checks.h"
#include "system_wrappers/include/field_trial.h"
namespace webrtc {
namespace {
// Ratio allocation between temporal streams:
// Values as required for the VP8 codec (accumulating).
static const float
kLayerRateAllocation[kMaxTemporalStreams][kMaxTemporalStreams] = {
{1.0f, 1.0f, 1.0f, 1.0f}, // 1 layer
{0.6f, 1.0f, 1.0f, 1.0f}, // 2 layers {60%, 40%}
{0.4f, 0.6f, 1.0f, 1.0f}, // 3 layers {40%, 20%, 40%}
{0.25f, 0.4f, 0.6f, 1.0f} // 4 layers {25%, 15%, 20%, 40%}
};
static const float kShort3TlRateAllocation[kMaxTemporalStreams] = {
0.6f, 0.8f, 1.0f, 1.0f // 3 layers {60%, 20%, 20%}
};
} // namespace
float SimulcastRateAllocator::GetTemporalRateAllocation(int num_layers,
int temporal_id) {
RTC_CHECK_GT(num_layers, 0);
RTC_CHECK_LE(num_layers, kMaxTemporalStreams);
RTC_CHECK_GE(temporal_id, 0);
RTC_CHECK_LT(temporal_id, num_layers);
if (num_layers == 3 &&
field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
return kShort3TlRateAllocation[temporal_id];
}
return kLayerRateAllocation[num_layers - 1][temporal_id];
}
SimulcastRateAllocator::SimulcastRateAllocator(const VideoCodec& codec)
: codec_(codec) {}
@ -190,7 +219,7 @@ std::vector<uint32_t> SimulcastRateAllocator::DefaultTemporalLayerAllocation(
std::vector<uint32_t> bitrates;
for (size_t i = 0; i < num_temporal_layers; ++i) {
float layer_bitrate =
bitrate_kbps * kLayerRateAllocation[num_temporal_layers - 1][i];
bitrate_kbps * GetTemporalRateAllocation(num_temporal_layers, i);
bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5));
}

View File

@ -24,16 +24,6 @@
namespace webrtc {
// Ratio allocation between temporal streams:
// Values as required for the VP8 codec (accumulating).
static const float
kLayerRateAllocation[kMaxSimulcastStreams][kMaxTemporalStreams] = {
{1.0f, 1.0f, 1.0f, 1.0f}, // 1 layer
{0.6f, 1.0f, 1.0f, 1.0f}, // 2 layers {60%, 40%}
{0.4f, 0.6f, 1.0f, 1.0f}, // 3 layers {40%, 20%, 40%}
{0.25f, 0.4f, 0.6f, 1.0f} // 4 layers {25%, 15%, 20%, 40%}
};
class SimulcastRateAllocator : public VideoBitrateAllocator {
public:
explicit SimulcastRateAllocator(const VideoCodec& codec);
@ -42,6 +32,8 @@ class SimulcastRateAllocator : public VideoBitrateAllocator {
uint32_t framerate) override;
const VideoCodec& GetCodec() const;
static float GetTemporalRateAllocation(int num_layers, int temporal_id);
private:
void DistributeAllocationToSimulcastLayers(
uint32_t total_bitrate_bps,

View File

@ -471,9 +471,15 @@ class TestVideoSenderWithVp8 : public TestVideoSender {
#define MAYBE_FixedTemporalLayersStrategy FixedTemporalLayersStrategy
#endif
TEST_F(TestVideoSenderWithVp8, MAYBE_FixedTemporalLayersStrategy) {
const int low_b = codec_bitrate_kbps_ * kLayerRateAllocation[2][0];
const int mid_b = codec_bitrate_kbps_ * kLayerRateAllocation[2][1];
const int high_b = codec_bitrate_kbps_ * kLayerRateAllocation[2][2];
const int low_b =
codec_bitrate_kbps_ *
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 0);
const int mid_b =
codec_bitrate_kbps_ *
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 1);
const int high_b =
codec_bitrate_kbps_ *
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 2);
{
Vp8StreamInfo expected = {{7.5, 15.0, 30.0}, {low_b, mid_b, high_b}};
EXPECT_THAT(SimulateWithFramerate(30.0), MatchesVp8StreamInfo(expected));