blob: 686396c51a8b63c8210f00ce3f969d3f2b9dec72 [file] [log] [blame]
sprang429600d2017-01-26 06:12:26 -08001/*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/video_coding/include/video_codec_initializer.h"
Yves Gerey3e707812018-11-28 16:47:49 +010012
13#include <stddef.h>
14#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
Yves Gerey3e707812018-11-28 16:47:49 +010016#include <memory>
17
18#include "absl/types/optional.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010019#include "api/scoped_refptr.h"
Elad Alon45befc52019-07-02 11:20:09 +020020#include "api/test/mock_fec_controller_override.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080021#include "api/video/builtin_video_bitrate_allocator_factory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "api/video/video_bitrate_allocation.h"
23#include "api/video/video_bitrate_allocator.h"
24#include "api/video/video_bitrate_allocator_factory.h"
Sergey Silkin86684962018-03-28 19:32:37 +020025#include "api/video_codecs/video_encoder.h"
Erik Språng4529fbc2018-10-12 10:30:31 +020026#include "api/video_codecs/vp8_temporal_layers.h"
Elad Aloncde8ab22019-03-20 11:56:20 +010027#include "api/video_codecs/vp8_temporal_layers_factory.h"
Sergey Silkin86684962018-03-28 19:32:37 +020028#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080029#include "rtc_base/checks.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/ref_counted_object.h"
Elad Alon45befc52019-07-02 11:20:09 +020031#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "test/gtest.h"
sprang429600d2017-01-26 06:12:26 -080033
34namespace webrtc {
35
36namespace {
sprang429600d2017-01-26 06:12:26 -080037static const int kDefaultWidth = 1280;
38static const int kDefaultHeight = 720;
39static const int kDefaultFrameRate = 30;
40static const uint32_t kDefaultMinBitrateBps = 60000;
41static const uint32_t kDefaultTargetBitrateBps = 2000000;
42static const uint32_t kDefaultMaxBitrateBps = 2000000;
43static const uint32_t kDefaultMinTransmitBitrateBps = 400000;
44static const int kDefaultMaxQp = 48;
Florent Castellid3511012020-08-04 11:40:23 +020045static const uint32_t kScreenshareTl0BitrateBps = 120000;
46static const uint32_t kScreenshareConferenceTl0BitrateBps = 200000;
sprang429600d2017-01-26 06:12:26 -080047static const uint32_t kScreenshareCodecTargetBitrateBps = 200000;
48static const uint32_t kScreenshareDefaultFramerate = 5;
49// Bitrates for the temporal layers of the higher screenshare simulcast stream.
50static const uint32_t kHighScreenshareTl0Bps = 800000;
51static const uint32_t kHighScreenshareTl1Bps = 1200000;
52} // namespace
53
sprang429600d2017-01-26 06:12:26 -080054// TODO(sprang): Extend coverage to handle the rest of the codec initializer.
55class VideoCodecInitializerTest : public ::testing::Test {
56 public:
Niels Möllerf1338562018-04-26 09:51:47 +020057 VideoCodecInitializerTest() {}
sprang429600d2017-01-26 06:12:26 -080058 virtual ~VideoCodecInitializerTest() {}
59
60 protected:
61 void SetUpFor(VideoCodecType type,
62 int num_spatial_streams,
63 int num_temporal_streams,
64 bool screenshare) {
65 config_ = VideoEncoderConfig();
Niels Möller259a4972018-04-05 15:36:51 +020066 config_.codec_type = type;
67
sprang429600d2017-01-26 06:12:26 -080068 if (screenshare) {
69 config_.min_transmit_bitrate_bps = kDefaultMinTransmitBitrateBps;
70 config_.content_type = VideoEncoderConfig::ContentType::kScreen;
71 }
72
73 if (type == VideoCodecType::kVideoCodecVP8) {
74 config_.number_of_streams = num_spatial_streams;
75 VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings();
76 vp8_settings.numberOfTemporalLayers = num_temporal_streams;
77 config_.encoder_specific_settings = new rtc::RefCountedObject<
78 webrtc::VideoEncoderConfig::Vp8EncoderSpecificSettings>(vp8_settings);
Sergey Silkin86684962018-03-28 19:32:37 +020079 } else if (type == VideoCodecType::kVideoCodecVP9) {
80 VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
81 vp9_settings.numberOfSpatialLayers = num_spatial_streams;
82 vp9_settings.numberOfTemporalLayers = num_temporal_streams;
83 config_.encoder_specific_settings = new rtc::RefCountedObject<
84 webrtc::VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings);
85 } else if (type != VideoCodecType::kVideoCodecMultiplex) {
sprang429600d2017-01-26 06:12:26 -080086 ADD_FAILURE() << "Unexpected codec type: " << type;
87 }
88 }
89
90 bool InitializeCodec() {
91 codec_out_ = VideoCodec();
Elad Aloncde8ab22019-03-20 11:56:20 +010092 frame_buffer_controller_.reset();
Jiawei Ouc2ebe212018-11-08 10:02:56 -080093 if (!VideoCodecInitializer::SetupCodec(config_, streams_, &codec_out_)) {
sprang429600d2017-01-26 06:12:26 -080094 return false;
95 }
Jiawei Ouc2ebe212018-11-08 10:02:56 -080096 bitrate_allocator_ = CreateBuiltinVideoBitrateAllocatorFactory()
97 ->CreateVideoBitrateAllocator(codec_out_);
98 RTC_CHECK(bitrate_allocator_);
Emircan Uysalerd7ae3c32018-01-25 13:01:09 -080099 if (codec_out_.codecType == VideoCodecType::kVideoCodecMultiplex)
Emircan Uysaler0a375472017-12-11 12:21:02 +0530100 return true;
Erik Språng82fad3d2018-03-21 09:57:23 +0100101
sprang429600d2017-01-26 06:12:26 -0800102 // Make sure temporal layers instances have been created.
103 if (codec_out_.codecType == VideoCodecType::kVideoCodecVP8) {
Elad Aloncde8ab22019-03-20 11:56:20 +0100104 Vp8TemporalLayersFactory factory;
Elad Alona2795842019-06-07 23:10:00 +0200105 const VideoEncoder::Settings settings(VideoEncoder::Capabilities(false),
106 1, 1000);
Elad Alon45befc52019-07-02 11:20:09 +0200107 frame_buffer_controller_ =
108 factory.Create(codec_out_, settings, &fec_controller_override_);
sprang429600d2017-01-26 06:12:26 -0800109 }
110 return true;
111 }
112
113 VideoStream DefaultStream() {
114 VideoStream stream;
115 stream.width = kDefaultWidth;
116 stream.height = kDefaultHeight;
117 stream.max_framerate = kDefaultFrameRate;
118 stream.min_bitrate_bps = kDefaultMinBitrateBps;
119 stream.target_bitrate_bps = kDefaultTargetBitrateBps;
120 stream.max_bitrate_bps = kDefaultMaxBitrateBps;
121 stream.max_qp = kDefaultMaxQp;
Sergey Silkina796a7e2018-03-01 15:11:29 +0100122 stream.num_temporal_layers = 1;
Seth Hampson46e31ba2018-01-18 10:39:54 -0800123 stream.active = true;
sprang429600d2017-01-26 06:12:26 -0800124 return stream;
125 }
126
127 VideoStream DefaultScreenshareStream() {
128 VideoStream stream = DefaultStream();
129 stream.min_bitrate_bps = 30000;
Florent Castellid3511012020-08-04 11:40:23 +0200130 stream.target_bitrate_bps = kScreenshareCodecTargetBitrateBps;
sprang429600d2017-01-26 06:12:26 -0800131 stream.max_bitrate_bps = 1000000;
132 stream.max_framerate = kScreenshareDefaultFramerate;
Sergey Silkina796a7e2018-03-01 15:11:29 +0100133 stream.num_temporal_layers = 2;
Seth Hampson46e31ba2018-01-18 10:39:54 -0800134 stream.active = true;
sprang429600d2017-01-26 06:12:26 -0800135 return stream;
136 }
137
Elad Alon45befc52019-07-02 11:20:09 +0200138 MockFecControllerOverride fec_controller_override_;
139
sprang429600d2017-01-26 06:12:26 -0800140 // Input settings.
141 VideoEncoderConfig config_;
sprang429600d2017-01-26 06:12:26 -0800142 std::vector<VideoStream> streams_;
sprang429600d2017-01-26 06:12:26 -0800143
144 // Output.
145 VideoCodec codec_out_;
Jiawei Ouc2ebe212018-11-08 10:02:56 -0800146 std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
Elad Aloncde8ab22019-03-20 11:56:20 +0100147 std::unique_ptr<Vp8FrameBufferController> frame_buffer_controller_;
sprang429600d2017-01-26 06:12:26 -0800148};
149
150TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
151 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 1, true);
152 streams_.push_back(DefaultStream());
153 EXPECT_TRUE(InitializeCodec());
154
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200155 VideoBitrateAllocation bitrate_allocation =
156 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
157 kDefaultTargetBitrateBps, kDefaultFrameRate));
sprang429600d2017-01-26 06:12:26 -0800158 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
159 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
160 EXPECT_EQ(kDefaultTargetBitrateBps, bitrate_allocation.get_sum_bps());
161}
162
Seth Hampson46e31ba2018-01-18 10:39:54 -0800163TEST_F(VideoCodecInitializerTest, SingleStreamVp8ScreenshareInactive) {
164 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 1, true);
165 VideoStream inactive_stream = DefaultStream();
166 inactive_stream.active = false;
167 streams_.push_back(inactive_stream);
168 EXPECT_TRUE(InitializeCodec());
169
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200170 VideoBitrateAllocation bitrate_allocation =
171 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
172 kDefaultTargetBitrateBps, kDefaultFrameRate));
Seth Hampson46e31ba2018-01-18 10:39:54 -0800173 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
174 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
175 EXPECT_EQ(0U, bitrate_allocation.get_sum_bps());
176}
177
Florent Castellid3511012020-08-04 11:40:23 +0200178TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8ScreenshareConference) {
179 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 2, true);
180 streams_.push_back(DefaultScreenshareStream());
181 EXPECT_TRUE(InitializeCodec());
182 bitrate_allocator_->SetLegacyConferenceMode(true);
183
184 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
185 EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
186 VideoBitrateAllocation bitrate_allocation =
187 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
188 kScreenshareCodecTargetBitrateBps, kScreenshareDefaultFramerate));
189 EXPECT_EQ(kScreenshareCodecTargetBitrateBps,
190 bitrate_allocation.get_sum_bps());
191 EXPECT_EQ(kScreenshareConferenceTl0BitrateBps,
192 bitrate_allocation.GetBitrate(0, 0));
193}
194
sprang429600d2017-01-26 06:12:26 -0800195TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8Screenshare) {
196 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 2, true);
197 streams_.push_back(DefaultScreenshareStream());
198 EXPECT_TRUE(InitializeCodec());
199
200 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
201 EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200202 VideoBitrateAllocation bitrate_allocation =
203 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
204 kScreenshareCodecTargetBitrateBps, kScreenshareDefaultFramerate));
sprang429600d2017-01-26 06:12:26 -0800205 EXPECT_EQ(kScreenshareCodecTargetBitrateBps,
206 bitrate_allocation.get_sum_bps());
207 EXPECT_EQ(kScreenshareTl0BitrateBps, bitrate_allocation.GetBitrate(0, 0));
208}
209
Seth Hampson46e31ba2018-01-18 10:39:54 -0800210TEST_F(VideoCodecInitializerTest, SimulcastVp8Screenshare) {
sprang429600d2017-01-26 06:12:26 -0800211 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, 1, true);
212 streams_.push_back(DefaultScreenshareStream());
213 VideoStream video_stream = DefaultStream();
214 video_stream.max_framerate = kScreenshareDefaultFramerate;
215 streams_.push_back(video_stream);
216 EXPECT_TRUE(InitializeCodec());
217
218 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
219 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
220 const uint32_t max_bitrate_bps =
221 streams_[0].target_bitrate_bps + streams_[1].max_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200222 VideoBitrateAllocation bitrate_allocation =
223 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
224 max_bitrate_bps, kScreenshareDefaultFramerate));
sprang429600d2017-01-26 06:12:26 -0800225 EXPECT_EQ(max_bitrate_bps, bitrate_allocation.get_sum_bps());
226 EXPECT_EQ(static_cast<uint32_t>(streams_[0].target_bitrate_bps),
227 bitrate_allocation.GetSpatialLayerSum(0));
228 EXPECT_EQ(static_cast<uint32_t>(streams_[1].max_bitrate_bps),
229 bitrate_allocation.GetSpatialLayerSum(1));
230}
231
Seth Hampson46e31ba2018-01-18 10:39:54 -0800232// Tests that when a video stream is inactive, then the bitrate allocation will
233// be 0 for that stream.
234TEST_F(VideoCodecInitializerTest, SimulcastVp8ScreenshareInactive) {
235 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, 1, true);
236 streams_.push_back(DefaultScreenshareStream());
237 VideoStream inactive_video_stream = DefaultStream();
238 inactive_video_stream.active = false;
239 inactive_video_stream.max_framerate = kScreenshareDefaultFramerate;
240 streams_.push_back(inactive_video_stream);
241 EXPECT_TRUE(InitializeCodec());
242
243 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
244 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
245 const uint32_t target_bitrate =
246 streams_[0].target_bitrate_bps + streams_[1].target_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200247 VideoBitrateAllocation bitrate_allocation =
248 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
249 target_bitrate, kScreenshareDefaultFramerate));
Seth Hampson46e31ba2018-01-18 10:39:54 -0800250 EXPECT_EQ(static_cast<uint32_t>(streams_[0].max_bitrate_bps),
251 bitrate_allocation.get_sum_bps());
252 EXPECT_EQ(static_cast<uint32_t>(streams_[0].max_bitrate_bps),
253 bitrate_allocation.GetSpatialLayerSum(0));
254 EXPECT_EQ(0U, bitrate_allocation.GetSpatialLayerSum(1));
255}
256
257TEST_F(VideoCodecInitializerTest, HighFpsSimulcastVp8Screenshare) {
sprang429600d2017-01-26 06:12:26 -0800258 // Two simulcast streams, the lower one using legacy settings (two temporal
259 // streams, 5fps), the higher one using 3 temporal streams and 30fps.
260 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, 3, true);
261 streams_.push_back(DefaultScreenshareStream());
262 VideoStream video_stream = DefaultStream();
Sergey Silkina796a7e2018-03-01 15:11:29 +0100263 video_stream.num_temporal_layers = 3;
sprang429600d2017-01-26 06:12:26 -0800264 streams_.push_back(video_stream);
265 EXPECT_TRUE(InitializeCodec());
266
267 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
268 EXPECT_EQ(3u, codec_out_.VP8()->numberOfTemporalLayers);
269 const uint32_t max_bitrate_bps =
270 streams_[0].target_bitrate_bps + streams_[1].max_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200271 VideoBitrateAllocation bitrate_allocation = bitrate_allocator_->Allocate(
272 VideoBitrateAllocationParameters(max_bitrate_bps, kDefaultFrameRate));
sprang429600d2017-01-26 06:12:26 -0800273 EXPECT_EQ(max_bitrate_bps, bitrate_allocation.get_sum_bps());
274 EXPECT_EQ(static_cast<uint32_t>(streams_[0].target_bitrate_bps),
275 bitrate_allocation.GetSpatialLayerSum(0));
276 EXPECT_EQ(static_cast<uint32_t>(streams_[1].max_bitrate_bps),
277 bitrate_allocation.GetSpatialLayerSum(1));
278 EXPECT_EQ(kHighScreenshareTl0Bps, bitrate_allocation.GetBitrate(1, 0));
279 EXPECT_EQ(kHighScreenshareTl1Bps - kHighScreenshareTl0Bps,
280 bitrate_allocation.GetBitrate(1, 1));
281}
282
Emircan Uysalerd7ae3c32018-01-25 13:01:09 -0800283TEST_F(VideoCodecInitializerTest, SingleStreamMultiplexCodec) {
284 SetUpFor(VideoCodecType::kVideoCodecMultiplex, 1, 1, true);
Emircan Uysaler0a375472017-12-11 12:21:02 +0530285 streams_.push_back(DefaultStream());
286 EXPECT_TRUE(InitializeCodec());
287}
288
Sergey Silkin86684962018-03-28 19:32:37 +0200289TEST_F(VideoCodecInitializerTest, Vp9SvcDefaultLayering) {
290 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false);
291 VideoStream stream = DefaultStream();
292 stream.num_temporal_layers = 3;
293 streams_.push_back(stream);
294
295 EXPECT_TRUE(InitializeCodec());
296 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3u);
297 EXPECT_EQ(codec_out_.VP9()->numberOfTemporalLayers, 3u);
298}
299
300TEST_F(VideoCodecInitializerTest, Vp9SvcAdjustedLayering) {
301 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false);
302 VideoStream stream = DefaultStream();
303 stream.num_temporal_layers = 3;
304 // Set resolution which is only enough to produce 2 spatial layers.
305 stream.width = kMinVp9SpatialLayerWidth * 2;
306 stream.height = kMinVp9SpatialLayerHeight * 2;
307
308 streams_.push_back(stream);
309
310 EXPECT_TRUE(InitializeCodec());
311 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2u);
312}
313
Sergey Silkinfafeac32018-04-13 16:36:39 +0200314TEST_F(VideoCodecInitializerTest,
315 Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrate) {
316 SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 3, false);
317 VideoStream stream = DefaultStream();
318 stream.num_temporal_layers = 3;
319 streams_.push_back(stream);
320
321 EXPECT_TRUE(InitializeCodec());
322 EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate,
323 kDefaultMaxBitrateBps / 1000);
324}
325
Sergey Silkin33120922018-11-28 13:32:13 +0100326TEST_F(VideoCodecInitializerTest,
Ilya Nikolaevskiy9ef5e052019-03-05 10:08:35 +0100327 Vp9SingleSpatialLayerTargetBitrateIsEqualToCodecMaxBitrate) {
328 SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 1, true);
329 VideoStream stream = DefaultStream();
330 stream.num_temporal_layers = 1;
331 streams_.push_back(stream);
332
333 EXPECT_TRUE(InitializeCodec());
334 EXPECT_EQ(codec_out_.spatialLayers[0].targetBitrate,
335 kDefaultMaxBitrateBps / 1000);
336}
337
338TEST_F(VideoCodecInitializerTest,
Sergey Silkin33120922018-11-28 13:32:13 +0100339 Vp9KeepBitrateLimitsIfNumberOfSpatialLayersIsReducedToOne) {
340 // Request 3 spatial layers for 320x180 input. Actual number of layers will be
341 // reduced to 1 due to low input resolution but SVC bitrate limits should be
342 // applied.
343 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false);
344 VideoStream stream = DefaultStream();
345 stream.width = 320;
346 stream.height = 180;
347 stream.num_temporal_layers = 3;
348 streams_.push_back(stream);
349
350 EXPECT_TRUE(InitializeCodec());
351 EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate,
352 kDefaultMaxBitrateBps / 1000);
353}
354
Sergey Silkin8b9b5f92018-12-10 09:28:53 +0100355TEST_F(VideoCodecInitializerTest, Vp9DeactivateLayers) {
356 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 1, false);
357 VideoStream stream = DefaultStream();
358 streams_.push_back(stream);
359
360 config_.simulcast_layers.resize(3);
361
362 // Activate all layers.
363 config_.simulcast_layers[0].active = true;
364 config_.simulcast_layers[1].active = true;
365 config_.simulcast_layers[2].active = true;
366 EXPECT_TRUE(InitializeCodec());
367 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
368 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
369 EXPECT_TRUE(codec_out_.spatialLayers[2].active);
370
371 // Deactivate top layer.
Ilya Nikolaevskiy72859e52020-02-05 17:31:00 +0100372 config_.simulcast_layers[2].active = false;
Sergey Silkin8b9b5f92018-12-10 09:28:53 +0100373 EXPECT_TRUE(InitializeCodec());
374 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
375 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
376 EXPECT_FALSE(codec_out_.spatialLayers[2].active);
377
378 // Deactivate middle layer.
Ilya Nikolaevskiy72859e52020-02-05 17:31:00 +0100379 config_.simulcast_layers[2].active = true;
Sergey Silkin8b9b5f92018-12-10 09:28:53 +0100380 config_.simulcast_layers[1].active = false;
381 EXPECT_TRUE(InitializeCodec());
382 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
383 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
384 EXPECT_TRUE(codec_out_.spatialLayers[2].active);
385}
386
sprang429600d2017-01-26 06:12:26 -0800387} // namespace webrtc