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 {
|
||||
|
||||
constexpr char kUseBaseHeavyVP8TL3RateAllocationFieldTrial[] =
|
||||
"WebRTC-UseBaseHeavyVP8TL3RateAllocation";
|
||||
|
||||
// Limits for legacy conference screensharing mode. Currently used for the
|
||||
// lower of the two simulcast streams.
|
||||
constexpr int kScreenshareDefaultTl0BitrateKbps = 200;
|
||||
@ -257,15 +260,16 @@ std::vector<webrtc::VideoStream> GetNormalSimulcastLayers(
|
||||
layers[s].target_bitrate_bps = FindSimulcastTargetBitrateBps(width, height);
|
||||
int num_temporal_layers = DefaultNumberOfTemporalLayers(s, false);
|
||||
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
|
||||
// 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.
|
||||
float rate_factor = 1.0;
|
||||
if (num_temporal_layers == 3) {
|
||||
if (webrtc::field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
|
||||
// Shortened pattern increases TL0 bitrate from 40% to 60%.
|
||||
if (webrtc::field_trial::IsEnabled(
|
||||
kUseBaseHeavyVP8TL3RateAllocationFieldTrial)) {
|
||||
// Base heavy allocation increases TL0 bitrate from 40% to 60%.
|
||||
rate_factor = 0.4 / 0.6;
|
||||
}
|
||||
} else {
|
||||
@ -341,7 +345,8 @@ std::vector<webrtc::VideoStream> GetScreenshareLayers(
|
||||
webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
|
||||
num_temporal_layers, 0));
|
||||
} 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.
|
||||
max_bitrate_bps = kScreenshareHighStreamMaxBitrateBps;
|
||||
using_boosted_bitrate = true;
|
||||
|
@ -108,6 +108,29 @@ TEST(SimulcastTest, GetConfig) {
|
||||
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) {
|
||||
const size_t kMaxLayers = 2;
|
||||
std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
|
||||
@ -221,7 +244,7 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) {
|
||||
|
||||
constexpr int kScreenshareHighStreamMinBitrateBps = 600000;
|
||||
constexpr int kScreenshareHighStreamMaxBitrateBps = 1250000;
|
||||
constexpr int kMaxBirate960_540 = 900000;
|
||||
constexpr int kMaxBitrate960_540 = 900000;
|
||||
|
||||
// Normal case, max bitrate not limited by resolution.
|
||||
const size_t kMaxLayers = 2;
|
||||
@ -238,7 +261,7 @@ TEST(SimulcastTest, SimulcastScreenshareMaxBitrateAdjustedForResolution) {
|
||||
kBitratePriority, kQpMax, kMaxFps,
|
||||
kScreenshare);
|
||||
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_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%}
|
||||
};
|
||||
|
||||
static const float kShort3TlRateAllocation[kMaxTemporalStreams] = {
|
||||
static const float kBaseHeavy3TlRateAllocation[kMaxTemporalStreams] = {
|
||||
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_LT(temporal_id, num_layers);
|
||||
if (num_layers == 3 &&
|
||||
field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
|
||||
return kShort3TlRateAllocation[temporal_id];
|
||||
field_trial::IsEnabled("WebRTC-UseBaseHeavyVP8TL3RateAllocation")) {
|
||||
return kBaseHeavy3TlRateAllocation[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 "test/field_trial.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
@ -91,32 +92,45 @@ class SimulcastRateAllocatorTest : public ::testing::TestWithParam<bool> {
|
||||
allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||
}
|
||||
|
||||
void SetupCodecThreeSimulcastStreams(
|
||||
const std::vector<bool>& active_streams) {
|
||||
size_t num_streams = 3;
|
||||
RTC_DCHECK_GE(active_streams.size(), num_streams);
|
||||
SetupCodecTwoSimulcastStreams(active_streams);
|
||||
codec_.numberOfSimulcastStreams = num_streams;
|
||||
codec_.simulcastStream[2].minBitrate = 2000;
|
||||
codec_.simulcastStream[2].targetBitrate = 3000;
|
||||
void SetupCodec3SL3TL(const std::vector<bool>& active_streams) {
|
||||
const size_t num_simulcast_layers = 3;
|
||||
RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
|
||||
SetupCodec2SL3TL(active_streams);
|
||||
codec_.numberOfSimulcastStreams = num_simulcast_layers;
|
||||
codec_.simulcastStream[2].numberOfTemporalLayers = 3;
|
||||
codec_.simulcastStream[2].maxBitrate = 4000;
|
||||
codec_.simulcastStream[2].targetBitrate = 3000;
|
||||
codec_.simulcastStream[2].minBitrate = 2000;
|
||||
codec_.simulcastStream[2].active = active_streams[2];
|
||||
}
|
||||
|
||||
void SetupCodecTwoSimulcastStreams(const std::vector<bool>& active_streams) {
|
||||
size_t num_streams = 2;
|
||||
RTC_DCHECK_GE(active_streams.size(), num_streams);
|
||||
codec_.numberOfSimulcastStreams = num_streams;
|
||||
codec_.maxBitrate = 0;
|
||||
codec_.simulcastStream[0].minBitrate = 10;
|
||||
codec_.simulcastStream[0].targetBitrate = 100;
|
||||
codec_.simulcastStream[0].maxBitrate = 500;
|
||||
codec_.simulcastStream[1].minBitrate = 50;
|
||||
codec_.simulcastStream[1].targetBitrate = 500;
|
||||
void SetupCodec2SL3TL(const std::vector<bool>& active_streams) {
|
||||
const size_t num_simulcast_layers = 2;
|
||||
RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
|
||||
SetupCodec1SL3TL(active_streams);
|
||||
codec_.numberOfSimulcastStreams = num_simulcast_layers;
|
||||
codec_.simulcastStream[1].numberOfTemporalLayers = 3;
|
||||
codec_.simulcastStream[1].maxBitrate = 1000;
|
||||
for (size_t i = 0; i < num_streams; ++i) {
|
||||
codec_.simulcastStream[i].active = active_streams[i];
|
||||
}
|
||||
codec_.simulcastStream[1].targetBitrate = 500;
|
||||
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) {
|
||||
@ -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) {
|
||||
codec_.numberOfSimulcastStreams = 1;
|
||||
codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
|
||||
@ -234,8 +279,7 @@ TEST_F(SimulcastRateAllocatorTest, SingleSimulcastInactive) {
|
||||
}
|
||||
|
||||
TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
|
||||
const std::vector<bool> active_streams(3, true);
|
||||
SetupCodecThreeSimulcastStreams(active_streams);
|
||||
SetupCodec3SL3TL({true, true, true});
|
||||
CreateAllocator();
|
||||
|
||||
{
|
||||
@ -326,8 +370,7 @@ TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
|
||||
// If three simulcast streams that are all inactive, none of them should be
|
||||
// allocated bitrate.
|
||||
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsInactive) {
|
||||
const std::vector<bool> active_streams(3, false);
|
||||
SetupCodecThreeSimulcastStreams(active_streams);
|
||||
SetupCodec3SL3TL({false, false, false});
|
||||
CreateAllocator();
|
||||
|
||||
// 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
|
||||
// allocated as if it is a single active stream.
|
||||
TEST_F(SimulcastRateAllocatorTest, TwoStreamsLowInactive) {
|
||||
const std::vector<bool> active_streams({false, true});
|
||||
SetupCodecTwoSimulcastStreams(active_streams);
|
||||
SetupCodec2SL3TL({false, true});
|
||||
CreateAllocator();
|
||||
|
||||
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
|
||||
// allocated as if it is a single active stream.
|
||||
TEST_F(SimulcastRateAllocatorTest, TwoStreamsHighInactive) {
|
||||
const std::vector<bool> active_streams({true, false});
|
||||
SetupCodecTwoSimulcastStreams(active_streams);
|
||||
SetupCodec2SL3TL({true, false});
|
||||
CreateAllocator();
|
||||
|
||||
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
|
||||
// active simulcast streams.
|
||||
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsMiddleInactive) {
|
||||
const std::vector<bool> active_streams({true, false, true});
|
||||
SetupCodecThreeSimulcastStreams(active_streams);
|
||||
SetupCodec3SL3TL({true, false, true});
|
||||
CreateAllocator();
|
||||
|
||||
{
|
||||
|
Reference in New Issue
Block a user