Split WebRTC-UseShortVP8TL3Pattern field trial in two.
- WebRTC-UseShortVP8TL3Pattern: Use a temporal pattern of length 4. - WebRTC-UseBaseHeavyVP8TL3RateAllocation: Allocate 60/20/20 to the TLs. Bug: webrtc:9477 Change-Id: Ib22d74c9390273e6498d417354d2cd311d9439b9 Reviewed-on: https://webrtc-review.googlesource.com/102920 Commit-Queue: Rasmus Brandt <brandtr@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24924}
This commit is contained in:

committed by
Commit Bot

parent
9551375c02
commit
73d117f64e
@ -25,6 +25,9 @@ namespace cricket {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr char kUseBaseHeavyVP8TL3RateAllocationFieldTrial[] =
|
||||||
|
"WebRTC-UseBaseHeavyVP8TL3RateAllocation";
|
||||||
|
|
||||||
// Limits for legacy conference screensharing mode. Currently used for the
|
// Limits for legacy conference screensharing mode. Currently used for the
|
||||||
// lower of the two simulcast streams.
|
// lower of the two simulcast streams.
|
||||||
constexpr int kScreenshareDefaultTl0BitrateKbps = 200;
|
constexpr int kScreenshareDefaultTl0BitrateKbps = 200;
|
||||||
@ -257,15 +260,16 @@ std::vector<webrtc::VideoStream> GetNormalSimulcastLayers(
|
|||||||
layers[s].target_bitrate_bps = FindSimulcastTargetBitrateBps(width, height);
|
layers[s].target_bitrate_bps = FindSimulcastTargetBitrateBps(width, height);
|
||||||
int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false);
|
int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false);
|
||||||
if (s == 0) {
|
if (s == 0) {
|
||||||
// If alternative number temporal layers is selected, adjust the
|
// If alternative temporal rate allocation is selected, adjust the
|
||||||
// bitrate of the lowest simulcast stream so that absolute bitrate for
|
// bitrate of the lowest simulcast stream so that absolute bitrate for
|
||||||
// the base temporal layer matches the bitrate for the base temporal
|
// the base temporal layer matches the bitrate for the base temporal
|
||||||
// layer with the default 3 simulcast streams. Otherwise we risk a
|
// layer with the default 3 simulcast streams. Otherwise we risk a
|
||||||
// higher threshold for receiving a feed at all.
|
// higher threshold for receiving a feed at all.
|
||||||
float rate_factor = 1.0;
|
float rate_factor = 1.0;
|
||||||
if (num_temporal_layers == 3) {
|
if (num_temporal_layers == 3) {
|
||||||
if (webrtc::field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
|
if (webrtc::field_trial::IsEnabled(
|
||||||
// Shortened pattern increases TL0 bitrate from 40% to 60%.
|
kUseBaseHeavyVP8TL3RateAllocationFieldTrial)) {
|
||||||
|
// Base heavy allocation increases TL0 bitrate from 40% to 60%.
|
||||||
rate_factor = 0.4 / 0.6;
|
rate_factor = 0.4 / 0.6;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -341,7 +345,8 @@ std::vector<webrtc::VideoStream> GetScreenshareLayers(
|
|||||||
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
|
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
|
||||||
num_temporal_layers, 0));
|
num_temporal_layers, 0));
|
||||||
} else if (DefaultNumberOfTemporalLayers(1, true) != 3 ||
|
} else if (DefaultNumberOfTemporalLayers(1, true) != 3 ||
|
||||||
webrtc::field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
|
webrtc::field_trial::IsEnabled(
|
||||||
|
kUseBaseHeavyVP8TL3RateAllocationFieldTrial)) {
|
||||||
// Experimental temporal layer mode used, use increased max bitrate.
|
// Experimental temporal layer mode used, use increased max bitrate.
|
||||||
max_bitrate_bps = kScreenshareHighStreamMaxBitrateBps;
|
max_bitrate_bps = kScreenshareHighStreamMaxBitrateBps;
|
||||||
using_boosted_bitrate = true;
|
using_boosted_bitrate = true;
|
||||||
|
@ -108,6 +108,29 @@ TEST(SimulcastTest, GetConfig) {
|
|||||||
EXPECT_FALSE(streams[2].bitrate_priority);
|
EXPECT_FALSE(streams[2].bitrate_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SimulcastTest, GetConfigWithBaseHeavyVP8TL3RateAllocation) {
|
||||||
|
test::ScopedFieldTrials field_trials(
|
||||||
|
"WebRTC-UseBaseHeavyVP8TL3RateAllocation/Enabled/");
|
||||||
|
|
||||||
|
const std::vector<VideoStream> kExpected = GetSimulcastBitrates720p();
|
||||||
|
|
||||||
|
const size_t kMaxLayers = 3;
|
||||||
|
std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
|
||||||
|
kMaxLayers, 1280, 720, kMaxBitrateBps, kBitratePriority, kQpMax, kMaxFps,
|
||||||
|
!kScreenshare);
|
||||||
|
|
||||||
|
EXPECT_EQ(kExpected[0].min_bitrate_bps, streams[0].min_bitrate_bps);
|
||||||
|
EXPECT_EQ(static_cast<int>(0.4 * kExpected[0].target_bitrate_bps / 0.6),
|
||||||
|
streams[0].target_bitrate_bps);
|
||||||
|
EXPECT_EQ(static_cast<int>(0.4 * kExpected[0].max_bitrate_bps / 0.6),
|
||||||
|
streams[0].max_bitrate_bps);
|
||||||
|
for (size_t i = 1; i < streams.size(); ++i) {
|
||||||
|
EXPECT_EQ(kExpected[i].min_bitrate_bps, streams[i].min_bitrate_bps);
|
||||||
|
EXPECT_EQ(kExpected[i].target_bitrate_bps, streams[i].target_bitrate_bps);
|
||||||
|
EXPECT_EQ(kExpected[i].max_bitrate_bps, streams[i].max_bitrate_bps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(SimulcastTest, GetConfigWithLimitedMaxLayers) {
|
TEST(SimulcastTest, GetConfigWithLimitedMaxLayers) {
|
||||||
const size_t kMaxLayers = 2;
|
const size_t kMaxLayers = 2;
|
||||||
std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
|
std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
|
||||||
@ -221,7 +244,7 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) {
|
|||||||
|
|
||||||
constexpr int kScreenshareHighStreamMinBitrateBps = 600000;
|
constexpr int kScreenshareHighStreamMinBitrateBps = 600000;
|
||||||
constexpr int kScreenshareHighStreamMaxBitrateBps = 1250000;
|
constexpr int kScreenshareHighStreamMaxBitrateBps = 1250000;
|
||||||
constexpr int kMaxBirate960_540 = 900000;
|
constexpr int kMaxBitrate960_540 = 900000;
|
||||||
|
|
||||||
// Normal case, max bitrate not limited by resolution.
|
// Normal case, max bitrate not limited by resolution.
|
||||||
const size_t kMaxLayers = 2;
|
const size_t kMaxLayers = 2;
|
||||||
@ -238,7 +261,7 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) {
|
|||||||
kBitratePriority, kQpMax, kMaxFps,
|
kBitratePriority, kQpMax, kMaxFps,
|
||||||
kScreenshare);
|
kScreenshare);
|
||||||
EXPECT_EQ(kMaxLayers, streams.size());
|
EXPECT_EQ(kMaxLayers, streams.size());
|
||||||
EXPECT_EQ(streams[1].max_bitrate_bps, kMaxBirate960_540);
|
EXPECT_EQ(streams[1].max_bitrate_bps, kMaxBitrate960_540);
|
||||||
EXPECT_EQ(streams[1].min_bitrate_bps, kScreenshareHighStreamMinBitrateBps);
|
EXPECT_EQ(streams[1].min_bitrate_bps, kScreenshareHighStreamMinBitrateBps);
|
||||||
EXPECT_GE(streams[1].max_bitrate_bps, streams[1].min_bitrate_bps);
|
EXPECT_GE(streams[1].max_bitrate_bps, streams[1].min_bitrate_bps);
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ static const float
|
|||||||
{0.25f, 0.4f, 0.6f, 1.0f} // 4 layers {25%, 15%, 20%, 40%}
|
{0.25f, 0.4f, 0.6f, 1.0f} // 4 layers {25%, 15%, 20%, 40%}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const float kShort3TlRateAllocation[kMaxTemporalStreams] = {
|
static const float kBaseHeavy3TlRateAllocation[kMaxTemporalStreams] = {
|
||||||
0.6f, 0.8f, 1.0f, 1.0f // 3 layers {60%, 20%, 20%}
|
0.6f, 0.8f, 1.0f, 1.0f // 3 layers {60%, 20%, 20%}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,8 +74,8 @@ float SimulcastRateAllocator::GetTemporalRateAllocation(int num_layers,
|
|||||||
RTC_CHECK_GE(temporal_id, 0);
|
RTC_CHECK_GE(temporal_id, 0);
|
||||||
RTC_CHECK_LT(temporal_id, num_layers);
|
RTC_CHECK_LT(temporal_id, num_layers);
|
||||||
if (num_layers == 3 &&
|
if (num_layers == 3 &&
|
||||||
field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
|
field_trial::IsEnabled("WebRTC-UseBaseHeavyVP8TL3RateAllocation")) {
|
||||||
return kShort3TlRateAllocation[temporal_id];
|
return kBaseHeavy3TlRateAllocation[temporal_id];
|
||||||
}
|
}
|
||||||
return kLayerRateAllocation[num_layers - 1][temporal_id];
|
return kLayerRateAllocation[num_layers - 1][temporal_id];
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||||
|
|
||||||
|
#include "test/field_trial.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
@ -91,32 +92,45 @@ class SimulcastRateAllocatorTest : public ::testing::TestWithParam<bool> {
|
|||||||
allocator_.reset(new SimulcastRateAllocator(codec_));
|
allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupCodecThreeSimulcastStreams(
|
void SetupCodec3SL3TL(const std::vector<bool>& active_streams) {
|
||||||
const std::vector<bool>& active_streams) {
|
const size_t num_simulcast_layers = 3;
|
||||||
size_t num_streams = 3;
|
RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
|
||||||
RTC_DCHECK_GE(active_streams.size(), num_streams);
|
SetupCodec2SL3TL(active_streams);
|
||||||
SetupCodecTwoSimulcastStreams(active_streams);
|
codec_.numberOfSimulcastStreams = num_simulcast_layers;
|
||||||
codec_.numberOfSimulcastStreams = num_streams;
|
codec_.simulcastStream[2].numberOfTemporalLayers = 3;
|
||||||
codec_.simulcastStream[2].minBitrate = 2000;
|
|
||||||
codec_.simulcastStream[2].targetBitrate = 3000;
|
|
||||||
codec_.simulcastStream[2].maxBitrate = 4000;
|
codec_.simulcastStream[2].maxBitrate = 4000;
|
||||||
|
codec_.simulcastStream[2].targetBitrate = 3000;
|
||||||
|
codec_.simulcastStream[2].minBitrate = 2000;
|
||||||
codec_.simulcastStream[2].active = active_streams[2];
|
codec_.simulcastStream[2].active = active_streams[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupCodecTwoSimulcastStreams(const std::vector<bool>& active_streams) {
|
void SetupCodec2SL3TL(const std::vector<bool>& active_streams) {
|
||||||
size_t num_streams = 2;
|
const size_t num_simulcast_layers = 2;
|
||||||
RTC_DCHECK_GE(active_streams.size(), num_streams);
|
RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
|
||||||
codec_.numberOfSimulcastStreams = num_streams;
|
SetupCodec1SL3TL(active_streams);
|
||||||
codec_.maxBitrate = 0;
|
codec_.numberOfSimulcastStreams = num_simulcast_layers;
|
||||||
codec_.simulcastStream[0].minBitrate = 10;
|
codec_.simulcastStream[1].numberOfTemporalLayers = 3;
|
||||||
codec_.simulcastStream[0].targetBitrate = 100;
|
|
||||||
codec_.simulcastStream[0].maxBitrate = 500;
|
|
||||||
codec_.simulcastStream[1].minBitrate = 50;
|
|
||||||
codec_.simulcastStream[1].targetBitrate = 500;
|
|
||||||
codec_.simulcastStream[1].maxBitrate = 1000;
|
codec_.simulcastStream[1].maxBitrate = 1000;
|
||||||
for (size_t i = 0; i < num_streams; ++i) {
|
codec_.simulcastStream[1].targetBitrate = 500;
|
||||||
codec_.simulcastStream[i].active = active_streams[i];
|
codec_.simulcastStream[1].minBitrate = 50;
|
||||||
}
|
codec_.simulcastStream[1].active = active_streams[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupCodec1SL3TL(const std::vector<bool>& active_streams) {
|
||||||
|
const size_t num_simulcast_layers = 2;
|
||||||
|
RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
|
||||||
|
SetupCodec3TL();
|
||||||
|
codec_.numberOfSimulcastStreams = num_simulcast_layers;
|
||||||
|
codec_.simulcastStream[0].numberOfTemporalLayers = 3;
|
||||||
|
codec_.simulcastStream[0].maxBitrate = 500;
|
||||||
|
codec_.simulcastStream[0].targetBitrate = 100;
|
||||||
|
codec_.simulcastStream[0].minBitrate = 10;
|
||||||
|
codec_.simulcastStream[0].active = active_streams[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupCodec3TL() {
|
||||||
|
codec_.maxBitrate = 0;
|
||||||
|
codec_.VP8()->numberOfTemporalLayers = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBitrateAllocation GetAllocation(uint32_t target_bitrate) {
|
VideoBitrateAllocation GetAllocation(uint32_t target_bitrate) {
|
||||||
@ -219,6 +233,37 @@ TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SimulcastRateAllocatorTest, Regular3TLTemporalRateAllocation) {
|
||||||
|
SetupCodec3SL3TL({true, true, true});
|
||||||
|
CreateAllocator();
|
||||||
|
|
||||||
|
const VideoBitrateAllocation alloc = GetAllocation(kMinBitrateKbps);
|
||||||
|
// 40/20/40.
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(0.4 * kMinBitrateKbps),
|
||||||
|
alloc.GetBitrate(0, 0) / 1000);
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(0.2 * kMinBitrateKbps),
|
||||||
|
alloc.GetBitrate(0, 1) / 1000);
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(0.4 * kMinBitrateKbps),
|
||||||
|
alloc.GetBitrate(0, 2) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SimulcastRateAllocatorTest, BaseHeavy3TLTemporalRateAllocation) {
|
||||||
|
test::ScopedFieldTrials field_trials(
|
||||||
|
"WebRTC-UseBaseHeavyVP8TL3RateAllocation/Enabled/");
|
||||||
|
|
||||||
|
SetupCodec3SL3TL({true, true, true});
|
||||||
|
CreateAllocator();
|
||||||
|
|
||||||
|
const VideoBitrateAllocation alloc = GetAllocation(kMinBitrateKbps);
|
||||||
|
// 60/20/20.
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(0.6 * kMinBitrateKbps),
|
||||||
|
alloc.GetBitrate(0, 0) / 1000);
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(0.2 * kMinBitrateKbps),
|
||||||
|
alloc.GetBitrate(0, 1) / 1000);
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(0.2 * kMinBitrateKbps),
|
||||||
|
alloc.GetBitrate(0, 2) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastInactive) {
|
TEST_F(SimulcastRateAllocatorTest, SingleSimulcastInactive) {
|
||||||
codec_.numberOfSimulcastStreams = 1;
|
codec_.numberOfSimulcastStreams = 1;
|
||||||
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
|
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
|
||||||
@ -234,8 +279,7 @@ TEST_F(SimulcastRateAllocatorTest, SingleSimulcastInactive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
|
TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
|
||||||
const std::vector<bool> active_streams(3, true);
|
SetupCodec3SL3TL({true, true, true});
|
||||||
SetupCodecThreeSimulcastStreams(active_streams);
|
|
||||||
CreateAllocator();
|
CreateAllocator();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -326,8 +370,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
|
|||||||
// If three simulcast streams that are all inactive, none of them should be
|
// If three simulcast streams that are all inactive, none of them should be
|
||||||
// allocated bitrate.
|
// allocated bitrate.
|
||||||
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsInactive) {
|
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsInactive) {
|
||||||
const std::vector<bool> active_streams(3, false);
|
SetupCodec3SL3TL({false, false, false});
|
||||||
SetupCodecThreeSimulcastStreams(active_streams);
|
|
||||||
CreateAllocator();
|
CreateAllocator();
|
||||||
|
|
||||||
// Just enough to allocate the min.
|
// Just enough to allocate the min.
|
||||||
@ -352,8 +395,7 @@ TEST_F(SimulcastRateAllocatorTest, ThreeStreamsInactive) {
|
|||||||
// If there are two simulcast streams, we expect the high active stream to be
|
// If there are two simulcast streams, we expect the high active stream to be
|
||||||
// allocated as if it is a single active stream.
|
// allocated as if it is a single active stream.
|
||||||
TEST_F(SimulcastRateAllocatorTest, TwoStreamsLowInactive) {
|
TEST_F(SimulcastRateAllocatorTest, TwoStreamsLowInactive) {
|
||||||
const std::vector<bool> active_streams({false, true});
|
SetupCodec2SL3TL({false, true});
|
||||||
SetupCodecTwoSimulcastStreams(active_streams);
|
|
||||||
CreateAllocator();
|
CreateAllocator();
|
||||||
|
|
||||||
const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[1].minBitrate;
|
const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[1].minBitrate;
|
||||||
@ -385,8 +427,7 @@ TEST_F(SimulcastRateAllocatorTest, TwoStreamsLowInactive) {
|
|||||||
// If there are two simulcast streams, we expect the low active stream to be
|
// If there are two simulcast streams, we expect the low active stream to be
|
||||||
// allocated as if it is a single active stream.
|
// allocated as if it is a single active stream.
|
||||||
TEST_F(SimulcastRateAllocatorTest, TwoStreamsHighInactive) {
|
TEST_F(SimulcastRateAllocatorTest, TwoStreamsHighInactive) {
|
||||||
const std::vector<bool> active_streams({true, false});
|
SetupCodec2SL3TL({true, false});
|
||||||
SetupCodecTwoSimulcastStreams(active_streams);
|
|
||||||
CreateAllocator();
|
CreateAllocator();
|
||||||
|
|
||||||
const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[0].minBitrate;
|
const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[0].minBitrate;
|
||||||
@ -419,8 +460,7 @@ TEST_F(SimulcastRateAllocatorTest, TwoStreamsHighInactive) {
|
|||||||
// other two streams should be allocated bitrate the same as if they are two
|
// other two streams should be allocated bitrate the same as if they are two
|
||||||
// active simulcast streams.
|
// active simulcast streams.
|
||||||
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsMiddleInactive) {
|
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsMiddleInactive) {
|
||||||
const std::vector<bool> active_streams({true, false, true});
|
SetupCodec3SL3TL({true, false, true});
|
||||||
SetupCodecThreeSimulcastStreams(active_streams);
|
|
||||||
CreateAllocator();
|
CreateAllocator();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user