1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "video/config/simulcast.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include "api/transport/field_trial_based_config.h"
14*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_constants.h"
15*d9f75844SAndroid Build Coastguard Worker #include "test/field_trial.h"
16*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
19*d9f75844SAndroid Build Coastguard Worker namespace {
20*d9f75844SAndroid Build Coastguard Worker constexpr int kQpMax = 55;
21*d9f75844SAndroid Build Coastguard Worker constexpr double kBitratePriority = 2.0;
22*d9f75844SAndroid Build Coastguard Worker constexpr bool kScreenshare = true;
23*d9f75844SAndroid Build Coastguard Worker constexpr int kDefaultTemporalLayers = 3; // Value from simulcast.cc.
24*d9f75844SAndroid Build Coastguard Worker
25*d9f75844SAndroid Build Coastguard Worker // Values from kSimulcastConfigs in simulcast.cc.
GetSimulcastBitrates720p()26*d9f75844SAndroid Build Coastguard Worker const std::vector<VideoStream> GetSimulcastBitrates720p() {
27*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams(3);
28*d9f75844SAndroid Build Coastguard Worker streams[0].min_bitrate_bps = 30000;
29*d9f75844SAndroid Build Coastguard Worker streams[0].target_bitrate_bps = 150000;
30*d9f75844SAndroid Build Coastguard Worker streams[0].max_bitrate_bps = 200000;
31*d9f75844SAndroid Build Coastguard Worker streams[1].min_bitrate_bps = 150000;
32*d9f75844SAndroid Build Coastguard Worker streams[1].target_bitrate_bps = 500000;
33*d9f75844SAndroid Build Coastguard Worker streams[1].max_bitrate_bps = 700000;
34*d9f75844SAndroid Build Coastguard Worker streams[2].min_bitrate_bps = 600000;
35*d9f75844SAndroid Build Coastguard Worker streams[2].target_bitrate_bps = 2500000;
36*d9f75844SAndroid Build Coastguard Worker streams[2].max_bitrate_bps = 2500000;
37*d9f75844SAndroid Build Coastguard Worker return streams;
38*d9f75844SAndroid Build Coastguard Worker }
39*d9f75844SAndroid Build Coastguard Worker } // namespace
40*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,TotalMaxBitrateIsZeroForNoStreams)41*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, TotalMaxBitrateIsZeroForNoStreams) {
42*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams;
43*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, cricket::GetTotalMaxBitrate(streams).bps());
44*d9f75844SAndroid Build Coastguard Worker }
45*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetTotalMaxBitrateForSingleStream)46*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetTotalMaxBitrateForSingleStream) {
47*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams(1);
48*d9f75844SAndroid Build Coastguard Worker streams[0].max_bitrate_bps = 100000;
49*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100000, cricket::GetTotalMaxBitrate(streams).bps());
50*d9f75844SAndroid Build Coastguard Worker }
51*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetTotalMaxBitrateForMultipleStreams)52*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetTotalMaxBitrateForMultipleStreams) {
53*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams(3);
54*d9f75844SAndroid Build Coastguard Worker streams[0].target_bitrate_bps = 100000;
55*d9f75844SAndroid Build Coastguard Worker streams[1].target_bitrate_bps = 200000;
56*d9f75844SAndroid Build Coastguard Worker streams[2].max_bitrate_bps = 400000;
57*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(700000, cricket::GetTotalMaxBitrate(streams).bps());
58*d9f75844SAndroid Build Coastguard Worker }
59*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,BandwidthAboveTotalMaxBitrateGivenToHighestStream)60*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, BandwidthAboveTotalMaxBitrateGivenToHighestStream) {
61*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams(3);
62*d9f75844SAndroid Build Coastguard Worker streams[0].target_bitrate_bps = 100000;
63*d9f75844SAndroid Build Coastguard Worker streams[1].target_bitrate_bps = 200000;
64*d9f75844SAndroid Build Coastguard Worker streams[2].max_bitrate_bps = 400000;
65*d9f75844SAndroid Build Coastguard Worker
66*d9f75844SAndroid Build Coastguard Worker const webrtc::DataRate one_bps = webrtc::DataRate::BitsPerSec(1);
67*d9f75844SAndroid Build Coastguard Worker
68*d9f75844SAndroid Build Coastguard Worker // No bitrate above the total max to give to the highest stream.
69*d9f75844SAndroid Build Coastguard Worker const webrtc::DataRate max_total_bitrate =
70*d9f75844SAndroid Build Coastguard Worker cricket::GetTotalMaxBitrate(streams);
71*d9f75844SAndroid Build Coastguard Worker cricket::BoostMaxSimulcastLayer(max_total_bitrate, &streams);
72*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400000, streams[2].max_bitrate_bps);
73*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(max_total_bitrate, cricket::GetTotalMaxBitrate(streams));
74*d9f75844SAndroid Build Coastguard Worker
75*d9f75844SAndroid Build Coastguard Worker // The bitrate above the total max should be given to the highest stream.
76*d9f75844SAndroid Build Coastguard Worker cricket::BoostMaxSimulcastLayer(max_total_bitrate + one_bps, &streams);
77*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400000 + 1, streams[2].max_bitrate_bps);
78*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(max_total_bitrate + one_bps, cricket::GetTotalMaxBitrate(streams));
79*d9f75844SAndroid Build Coastguard Worker }
80*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfig)81*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfig) {
82*d9f75844SAndroid Build Coastguard Worker const std::vector<VideoStream> kExpected = GetSimulcastBitrates720p();
83*d9f75844SAndroid Build Coastguard Worker const FieldTrialBasedConfig trials;
84*d9f75844SAndroid Build Coastguard Worker
85*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
86*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
87*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
88*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 1280, 720, kBitratePriority, kQpMax,
89*d9f75844SAndroid Build Coastguard Worker !kScreenshare, true, trials);
90*d9f75844SAndroid Build Coastguard Worker
91*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
92*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(320u, streams[0].width);
93*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(180u, streams[0].height);
94*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(640u, streams[1].width);
95*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(360u, streams[1].height);
96*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1280u, streams[2].width);
97*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(720u, streams[2].height);
98*d9f75844SAndroid Build Coastguard Worker
99*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < streams.size(); ++i) {
100*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(size_t{kDefaultTemporalLayers}, streams[i].num_temporal_layers);
101*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(cricket::kDefaultVideoMaxFramerate, streams[i].max_framerate);
102*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kQpMax, streams[i].max_qp);
103*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[i].min_bitrate_bps, streams[i].min_bitrate_bps);
104*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[i].target_bitrate_bps, streams[i].target_bitrate_bps);
105*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[i].max_bitrate_bps, streams[i].max_bitrate_bps);
106*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(streams[i].active);
107*d9f75844SAndroid Build Coastguard Worker }
108*d9f75844SAndroid Build Coastguard Worker // Currently set on lowest stream.
109*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kBitratePriority, streams[0].bitrate_priority);
110*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(streams[1].bitrate_priority);
111*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(streams[2].bitrate_priority);
112*d9f75844SAndroid Build Coastguard Worker }
113*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithBaseHeavyVP8TL3RateAllocation)114*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithBaseHeavyVP8TL3RateAllocation) {
115*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
116*d9f75844SAndroid Build Coastguard Worker "WebRTC-UseBaseHeavyVP8TL3RateAllocation/Enabled/");
117*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
118*d9f75844SAndroid Build Coastguard Worker
119*d9f75844SAndroid Build Coastguard Worker const std::vector<VideoStream> kExpected = GetSimulcastBitrates720p();
120*d9f75844SAndroid Build Coastguard Worker
121*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
122*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
123*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
124*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 1280, 720, kBitratePriority, kQpMax,
125*d9f75844SAndroid Build Coastguard Worker !kScreenshare, true, trials);
126*d9f75844SAndroid Build Coastguard Worker
127*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[0].min_bitrate_bps, streams[0].min_bitrate_bps);
128*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(0.4 * kExpected[0].target_bitrate_bps / 0.6),
129*d9f75844SAndroid Build Coastguard Worker streams[0].target_bitrate_bps);
130*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(0.4 * kExpected[0].max_bitrate_bps / 0.6),
131*d9f75844SAndroid Build Coastguard Worker streams[0].max_bitrate_bps);
132*d9f75844SAndroid Build Coastguard Worker for (size_t i = 1; i < streams.size(); ++i) {
133*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[i].min_bitrate_bps, streams[i].min_bitrate_bps);
134*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[i].target_bitrate_bps, streams[i].target_bitrate_bps);
135*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kExpected[i].max_bitrate_bps, streams[i].max_bitrate_bps);
136*d9f75844SAndroid Build Coastguard Worker }
137*d9f75844SAndroid Build Coastguard Worker }
138*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithLimitedMaxLayers)139*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithLimitedMaxLayers) {
140*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
141*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 2;
142*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
143*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
144*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 1280, 720, kBitratePriority, kQpMax,
145*d9f75844SAndroid Build Coastguard Worker !kScreenshare, true, trials);
146*d9f75844SAndroid Build Coastguard Worker
147*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
148*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(640u, streams[0].width);
149*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(360u, streams[0].height);
150*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1280u, streams[1].width);
151*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(720u, streams[1].height);
152*d9f75844SAndroid Build Coastguard Worker }
153*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithLimitedMaxLayersForResolution)154*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithLimitedMaxLayersForResolution) {
155*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
156*d9f75844SAndroid Build Coastguard Worker "WebRTC-LegacySimulcastLayerLimit/Enabled/");
157*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
158*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
159*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
160*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
161*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 800, 600, kBitratePriority, kQpMax, !kScreenshare,
162*d9f75844SAndroid Build Coastguard Worker true, trials);
163*d9f75844SAndroid Build Coastguard Worker
164*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
165*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400u, streams[0].width);
166*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300u, streams[0].height);
167*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(800u, streams[1].width);
168*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(600u, streams[1].height);
169*d9f75844SAndroid Build Coastguard Worker }
170*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithLowResolutionScreenshare)171*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithLowResolutionScreenshare) {
172*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
173*d9f75844SAndroid Build Coastguard Worker "WebRTC-LegacySimulcastLayerLimit/Enabled/");
174*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
175*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
176*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
177*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
178*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 100, 100, kBitratePriority, kQpMax, kScreenshare,
179*d9f75844SAndroid Build Coastguard Worker true, trials);
180*d9f75844SAndroid Build Coastguard Worker
181*d9f75844SAndroid Build Coastguard Worker // Simulcast streams number is never decreased for screenshare,
182*d9f75844SAndroid Build Coastguard Worker // even for very low resolution.
183*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(streams.size(), 1u);
184*d9f75844SAndroid Build Coastguard Worker }
185*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithNotLimitedMaxLayersForResolution)186*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithNotLimitedMaxLayersForResolution) {
187*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
188*d9f75844SAndroid Build Coastguard Worker "WebRTC-LegacySimulcastLayerLimit/Disabled/");
189*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
190*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
191*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
192*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
193*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 800, 600, kBitratePriority, kQpMax, !kScreenshare,
194*d9f75844SAndroid Build Coastguard Worker true, trials);
195*d9f75844SAndroid Build Coastguard Worker
196*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
197*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200u, streams[0].width);
198*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(150u, streams[0].height);
199*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400u, streams[1].width);
200*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(300u, streams[1].height);
201*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(800u, streams[2].width);
202*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(600u, streams[2].height);
203*d9f75844SAndroid Build Coastguard Worker }
204*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithNormalizedResolution)205*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithNormalizedResolution) {
206*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
207*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
208*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 2;
209*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
210*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 640 + 1, 360 + 1, kBitratePriority, kQpMax,
211*d9f75844SAndroid Build Coastguard Worker !kScreenshare, true, trials);
212*d9f75844SAndroid Build Coastguard Worker
213*d9f75844SAndroid Build Coastguard Worker // Must be divisible by |2 ^ (num_layers - 1)|.
214*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
215*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(320u, streams[0].width);
216*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(180u, streams[0].height);
217*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(640u, streams[1].width);
218*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(360u, streams[1].height);
219*d9f75844SAndroid Build Coastguard Worker }
220*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithNormalizedResolutionDivisibleBy4)221*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithNormalizedResolutionDivisibleBy4) {
222*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
223*d9f75844SAndroid Build Coastguard Worker "WebRTC-NormalizeSimulcastResolution/Enabled-2/");
224*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
225*d9f75844SAndroid Build Coastguard Worker
226*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
227*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 2;
228*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
229*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 709, 501, kBitratePriority, kQpMax, !kScreenshare,
230*d9f75844SAndroid Build Coastguard Worker true, trials);
231*d9f75844SAndroid Build Coastguard Worker
232*d9f75844SAndroid Build Coastguard Worker // Must be divisible by |2 ^ 2|.
233*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
234*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(354u, streams[0].width);
235*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(250u, streams[0].height);
236*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(708u, streams[1].width);
237*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(500u, streams[1].height);
238*d9f75844SAndroid Build Coastguard Worker }
239*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigWithNormalizedResolutionDivisibleBy8)240*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigWithNormalizedResolutionDivisibleBy8) {
241*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
242*d9f75844SAndroid Build Coastguard Worker "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
243*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
244*d9f75844SAndroid Build Coastguard Worker
245*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
246*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 2;
247*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
248*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 709, 501, kBitratePriority, kQpMax, !kScreenshare,
249*d9f75844SAndroid Build Coastguard Worker true, trials);
250*d9f75844SAndroid Build Coastguard Worker
251*d9f75844SAndroid Build Coastguard Worker // Must be divisible by |2 ^ 3|.
252*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
253*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(352u, streams[0].width);
254*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(248u, streams[0].height);
255*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(704u, streams[1].width);
256*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(496u, streams[1].height);
257*d9f75844SAndroid Build Coastguard Worker }
258*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigForLegacyLayerLimit)259*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigForLegacyLayerLimit) {
260*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
261*d9f75844SAndroid Build Coastguard Worker "WebRTC-LegacySimulcastLayerLimit/Enabled/");
262*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
263*d9f75844SAndroid Build Coastguard Worker
264*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
265*d9f75844SAndroid Build Coastguard Worker const int kMaxLayers = 3;
266*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
267*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 320, 180, kBitratePriority, kQpMax, !kScreenshare,
268*d9f75844SAndroid Build Coastguard Worker true, trials);
269*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, streams.size());
270*d9f75844SAndroid Build Coastguard Worker
271*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 640, 360,
272*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
273*d9f75844SAndroid Build Coastguard Worker true, trials);
274*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
275*d9f75844SAndroid Build Coastguard Worker
276*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1920, 1080,
277*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
278*d9f75844SAndroid Build Coastguard Worker true, trials);
279*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
280*d9f75844SAndroid Build Coastguard Worker }
281*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigForLegacyLayerLimitWithRequiredHD)282*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigForLegacyLayerLimitWithRequiredHD) {
283*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
284*d9f75844SAndroid Build Coastguard Worker "WebRTC-LegacySimulcastLayerLimit/Enabled/");
285*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
286*d9f75844SAndroid Build Coastguard Worker
287*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 3; // "HD" layer must be present!
288*d9f75844SAndroid Build Coastguard Worker const int kMaxLayers = 3;
289*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
290*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 320, 180, kBitratePriority, kQpMax, !kScreenshare,
291*d9f75844SAndroid Build Coastguard Worker true, trials);
292*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
293*d9f75844SAndroid Build Coastguard Worker
294*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 640, 360,
295*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
296*d9f75844SAndroid Build Coastguard Worker true, trials);
297*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
298*d9f75844SAndroid Build Coastguard Worker
299*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 1920, 1080,
300*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
301*d9f75844SAndroid Build Coastguard Worker true, trials);
302*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
303*d9f75844SAndroid Build Coastguard Worker }
304*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigForScreenshareSimulcast)305*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigForScreenshareSimulcast) {
306*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
307*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
308*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
309*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
310*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 1400, 800, kBitratePriority, kQpMax, kScreenshare,
311*d9f75844SAndroid Build Coastguard Worker true, trials);
312*d9f75844SAndroid Build Coastguard Worker
313*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(streams.size(), 1u);
314*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < streams.size(); ++i) {
315*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1400u, streams[i].width) << "Screen content never scaled.";
316*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(800u, streams[i].height) << "Screen content never scaled.";
317*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kQpMax, streams[i].max_qp);
318*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(streams[i].active);
319*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(streams[i].num_temporal_layers, size_t{1});
320*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(streams[i].max_framerate, 0);
321*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(streams[i].min_bitrate_bps, 0);
322*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
323*d9f75844SAndroid Build Coastguard Worker EXPECT_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
324*d9f75844SAndroid Build Coastguard Worker }
325*d9f75844SAndroid Build Coastguard Worker }
326*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,GetConfigForScreenshareSimulcastWithLimitedMaxLayers)327*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, GetConfigForScreenshareSimulcastWithLimitedMaxLayers) {
328*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
329*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
330*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 1;
331*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
332*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 1400, 800, kBitratePriority, kQpMax, kScreenshare,
333*d9f75844SAndroid Build Coastguard Worker true, trials);
334*d9f75844SAndroid Build Coastguard Worker
335*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
336*d9f75844SAndroid Build Coastguard Worker }
337*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,AveragesBitratesForNonStandardResolution)338*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, AveragesBitratesForNonStandardResolution) {
339*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
340*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
341*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
342*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
343*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, 900, 800, kBitratePriority, kQpMax, !kScreenshare,
344*d9f75844SAndroid Build Coastguard Worker true, trials);
345*d9f75844SAndroid Build Coastguard Worker
346*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
347*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(900u, streams[2].width);
348*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(800u, streams[2].height);
349*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1850000, streams[2].max_bitrate_bps);
350*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1850000, streams[2].target_bitrate_bps);
351*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(475000, streams[2].min_bitrate_bps);
352*d9f75844SAndroid Build Coastguard Worker }
353*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,BitratesForCloseToStandardResolution)354*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, BitratesForCloseToStandardResolution) {
355*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
356*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
357*d9f75844SAndroid Build Coastguard Worker // Resolution very close to 720p in number of pixels
358*d9f75844SAndroid Build Coastguard Worker const size_t kWidth = 1280;
359*d9f75844SAndroid Build Coastguard Worker const size_t kHeight = 716;
360*d9f75844SAndroid Build Coastguard Worker const std::vector<VideoStream> kExpectedNear = GetSimulcastBitrates720p();
361*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
362*d9f75844SAndroid Build Coastguard Worker
363*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
364*d9f75844SAndroid Build Coastguard Worker kMinLayers, kMaxLayers, kWidth, kHeight, kBitratePriority, kQpMax,
365*d9f75844SAndroid Build Coastguard Worker !kScreenshare, true, trials);
366*d9f75844SAndroid Build Coastguard Worker
367*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kMaxLayers, streams.size());
368*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kWidth, streams[2].width);
369*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kHeight, streams[2].height);
370*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < streams.size(); ++i) {
371*d9f75844SAndroid Build Coastguard Worker EXPECT_NEAR(kExpectedNear[i].max_bitrate_bps, streams[i].max_bitrate_bps,
372*d9f75844SAndroid Build Coastguard Worker 20000);
373*d9f75844SAndroid Build Coastguard Worker EXPECT_NEAR(kExpectedNear[i].target_bitrate_bps,
374*d9f75844SAndroid Build Coastguard Worker streams[i].target_bitrate_bps, 20000);
375*d9f75844SAndroid Build Coastguard Worker EXPECT_NEAR(kExpectedNear[i].min_bitrate_bps, streams[i].min_bitrate_bps,
376*d9f75844SAndroid Build Coastguard Worker 20000);
377*d9f75844SAndroid Build Coastguard Worker }
378*d9f75844SAndroid Build Coastguard Worker }
379*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,MaxLayersWithRoundUpDisabled)380*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, MaxLayersWithRoundUpDisabled) {
381*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
382*d9f75844SAndroid Build Coastguard Worker "WebRTC-SimulcastLayerLimitRoundUp/max_ratio:0.0/");
383*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
384*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
385*d9f75844SAndroid Build Coastguard Worker const int kMaxLayers = 3;
386*d9f75844SAndroid Build Coastguard Worker
387*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams;
388*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 540,
389*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
390*d9f75844SAndroid Build Coastguard Worker true, trials);
391*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
392*d9f75844SAndroid Build Coastguard Worker // <960x540: 2 layers
393*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 539,
394*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
395*d9f75844SAndroid Build Coastguard Worker true, trials);
396*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
397*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270,
398*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
399*d9f75844SAndroid Build Coastguard Worker true, trials);
400*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
401*d9f75844SAndroid Build Coastguard Worker // <480x270: 1 layer
402*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 269,
403*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
404*d9f75844SAndroid Build Coastguard Worker true, trials);
405*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, streams.size());
406*d9f75844SAndroid Build Coastguard Worker }
407*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,MaxLayersWithDefaultRoundUpRatio)408*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, MaxLayersWithDefaultRoundUpRatio) {
409*d9f75844SAndroid Build Coastguard Worker // Default: "WebRTC-SimulcastLayerLimitRoundUp/max_ratio:0.1/"
410*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
411*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
412*d9f75844SAndroid Build Coastguard Worker const int kMaxLayers = 3;
413*d9f75844SAndroid Build Coastguard Worker
414*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams;
415*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 540,
416*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
417*d9f75844SAndroid Build Coastguard Worker true, trials);
418*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
419*d9f75844SAndroid Build Coastguard Worker // Lowest cropped height where max layers from higher resolution is used.
420*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 512,
421*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
422*d9f75844SAndroid Build Coastguard Worker true, trials);
423*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3u, streams.size());
424*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 960, 508,
425*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
426*d9f75844SAndroid Build Coastguard Worker true, trials);
427*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
428*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270,
429*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
430*d9f75844SAndroid Build Coastguard Worker true, trials);
431*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
432*d9f75844SAndroid Build Coastguard Worker // Lowest cropped height where max layers from higher resolution is used.
433*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 256,
434*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
435*d9f75844SAndroid Build Coastguard Worker true, trials);
436*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
437*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 254,
438*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
439*d9f75844SAndroid Build Coastguard Worker true, trials);
440*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, streams.size());
441*d9f75844SAndroid Build Coastguard Worker }
442*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,MaxLayersWithRoundUpRatio)443*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, MaxLayersWithRoundUpRatio) {
444*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
445*d9f75844SAndroid Build Coastguard Worker "WebRTC-SimulcastLayerLimitRoundUp/max_ratio:0.13/");
446*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
447*d9f75844SAndroid Build Coastguard Worker const size_t kMinLayers = 1;
448*d9f75844SAndroid Build Coastguard Worker const int kMaxLayers = 3;
449*d9f75844SAndroid Build Coastguard Worker
450*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams;
451*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 270,
452*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
453*d9f75844SAndroid Build Coastguard Worker true, trials);
454*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
455*d9f75844SAndroid Build Coastguard Worker // Lowest cropped height where max layers from higher resolution is used.
456*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 252,
457*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
458*d9f75844SAndroid Build Coastguard Worker true, trials);
459*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, streams.size());
460*d9f75844SAndroid Build Coastguard Worker streams = cricket::GetSimulcastConfig(kMinLayers, kMaxLayers, 480, 250,
461*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare,
462*d9f75844SAndroid Build Coastguard Worker true, trials);
463*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, streams.size());
464*d9f75844SAndroid Build Coastguard Worker }
465*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,BitratesInterpolatedForResBelow180p)466*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, BitratesInterpolatedForResBelow180p) {
467*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:12415): Remove when feature launches.
468*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
469*d9f75844SAndroid Build Coastguard Worker "WebRTC-LowresSimulcastBitrateInterpolation/Enabled/");
470*d9f75844SAndroid Build Coastguard Worker
471*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
472*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
473*d9f75844SAndroid Build Coastguard Worker
474*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
475*d9f75844SAndroid Build Coastguard Worker /* min_layers = */ 1, kMaxLayers, /* width = */ 960, /* height = */ 540,
476*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare, true, trials);
477*d9f75844SAndroid Build Coastguard Worker
478*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(streams.size(), kMaxLayers);
479*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(240u, streams[0].width);
480*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(135u, streams[0].height);
481*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].max_bitrate_bps, 112500);
482*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].target_bitrate_bps, 84375);
483*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].min_bitrate_bps, 30000);
484*d9f75844SAndroid Build Coastguard Worker }
485*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,BitratesConsistentForVerySmallRes)486*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest, BitratesConsistentForVerySmallRes) {
487*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:12415): Remove when feature launches.
488*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
489*d9f75844SAndroid Build Coastguard Worker "WebRTC-LowresSimulcastBitrateInterpolation/Enabled/");
490*d9f75844SAndroid Build Coastguard Worker
491*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
492*d9f75844SAndroid Build Coastguard Worker
493*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
494*d9f75844SAndroid Build Coastguard Worker /* min_layers = */ 1, /* max_layers = */ 3, /* width = */ 1,
495*d9f75844SAndroid Build Coastguard Worker /* height = */ 1, kBitratePriority, kQpMax, !kScreenshare, true, trials);
496*d9f75844SAndroid Build Coastguard Worker
497*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(!streams.empty());
498*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, streams[0].width);
499*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, streams[0].height);
500*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].max_bitrate_bps, 30000);
501*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].target_bitrate_bps, 30000);
502*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].min_bitrate_bps, 30000);
503*d9f75844SAndroid Build Coastguard Worker }
504*d9f75844SAndroid Build Coastguard Worker
TEST(SimulcastTest,BitratesNotInterpolatedForResBelow180pWhenDisabledTrialSet)505*d9f75844SAndroid Build Coastguard Worker TEST(SimulcastTest,
506*d9f75844SAndroid Build Coastguard Worker BitratesNotInterpolatedForResBelow180pWhenDisabledTrialSet) {
507*d9f75844SAndroid Build Coastguard Worker test::ScopedFieldTrials field_trials(
508*d9f75844SAndroid Build Coastguard Worker "WebRTC-LowresSimulcastBitrateInterpolation/Disabled/");
509*d9f75844SAndroid Build Coastguard Worker
510*d9f75844SAndroid Build Coastguard Worker const size_t kMaxLayers = 3;
511*d9f75844SAndroid Build Coastguard Worker FieldTrialBasedConfig trials;
512*d9f75844SAndroid Build Coastguard Worker
513*d9f75844SAndroid Build Coastguard Worker std::vector<VideoStream> streams = cricket::GetSimulcastConfig(
514*d9f75844SAndroid Build Coastguard Worker /* min_layers = */ 1, kMaxLayers, /* width = */ 960, /* height = */ 540,
515*d9f75844SAndroid Build Coastguard Worker kBitratePriority, kQpMax, !kScreenshare, true, trials);
516*d9f75844SAndroid Build Coastguard Worker
517*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(streams.size(), kMaxLayers);
518*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(240u, streams[0].width);
519*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(135u, streams[0].height);
520*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].max_bitrate_bps, 200000);
521*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].target_bitrate_bps, 150000);
522*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(streams[0].min_bitrate_bps, 30000);
523*d9f75844SAndroid Build Coastguard Worker }
524*d9f75844SAndroid Build Coastguard Worker
525*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
526