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:
parent
c05bd738d6
commit
d92288f5ba
@ -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 =
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user