blob: 0e6f2dfca205bfc1ec95f5b410d57ab6e3145976 [file] [log] [blame]
sprang429600d2017-01-26 14:12:261/*
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 04:47:3111#include "modules/video_coding/include/video_codec_initializer.h"
Yves Gerey3e707812018-11-28 15:47:4912
13#include <stddef.h>
14#include <stdint.h>
Jonas Olssona4d87372019-07-05 17:08:3315
Yves Gerey3e707812018-11-28 15:47:4916#include <memory>
17
18#include "absl/types/optional.h"
Mirko Bonadeid9708072019-01-25 19:26:4819#include "api/scoped_refptr.h"
Elad Alon45befc52019-07-02 09:20:0920#include "api/test/mock_fec_controller_override.h"
Jiawei Ouc2ebe212018-11-08 18:02:5621#include "api/video/builtin_video_bitrate_allocator_factory.h"
Yves Gerey3e707812018-11-28 15:47:4922#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 17:32:3725#include "api/video_codecs/video_encoder.h"
Erik Språng4529fbc2018-10-12 08:30:3126#include "api/video_codecs/vp8_temporal_layers.h"
Elad Aloncde8ab22019-03-20 10:56:2027#include "api/video_codecs/vp8_temporal_layers_factory.h"
Sergey Silkin86684962018-03-28 17:32:3728#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
Jiawei Ouc2ebe212018-11-08 18:02:5629#include "rtc_base/checks.h"
Elad Alon45befc52019-07-02 09:20:0930#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3131#include "test/gtest.h"
sprang429600d2017-01-26 14:12:2632
33namespace webrtc {
34
35namespace {
sprang429600d2017-01-26 14:12:2636static const int kDefaultWidth = 1280;
37static const int kDefaultHeight = 720;
38static const int kDefaultFrameRate = 30;
39static const uint32_t kDefaultMinBitrateBps = 60000;
40static const uint32_t kDefaultTargetBitrateBps = 2000000;
41static const uint32_t kDefaultMaxBitrateBps = 2000000;
42static const uint32_t kDefaultMinTransmitBitrateBps = 400000;
43static const int kDefaultMaxQp = 48;
Florent Castellid3511012020-08-04 09:40:2344static const uint32_t kScreenshareTl0BitrateBps = 120000;
45static const uint32_t kScreenshareConferenceTl0BitrateBps = 200000;
sprang429600d2017-01-26 14:12:2646static const uint32_t kScreenshareCodecTargetBitrateBps = 200000;
47static const uint32_t kScreenshareDefaultFramerate = 5;
48// Bitrates for the temporal layers of the higher screenshare simulcast stream.
49static const uint32_t kHighScreenshareTl0Bps = 800000;
50static const uint32_t kHighScreenshareTl1Bps = 1200000;
51} // namespace
52
sprang429600d2017-01-26 14:12:2653// TODO(sprang): Extend coverage to handle the rest of the codec initializer.
54class VideoCodecInitializerTest : public ::testing::Test {
55 public:
Niels Möllerf1338562018-04-26 07:51:4756 VideoCodecInitializerTest() {}
sprang429600d2017-01-26 14:12:2657 virtual ~VideoCodecInitializerTest() {}
58
59 protected:
60 void SetUpFor(VideoCodecType type,
61 int num_spatial_streams,
62 int num_temporal_streams,
63 bool screenshare) {
64 config_ = VideoEncoderConfig();
Niels Möller259a4972018-04-05 13:36:5165 config_.codec_type = type;
66
sprang429600d2017-01-26 14:12:2667 if (screenshare) {
68 config_.min_transmit_bitrate_bps = kDefaultMinTransmitBitrateBps;
69 config_.content_type = VideoEncoderConfig::ContentType::kScreen;
70 }
71
72 if (type == VideoCodecType::kVideoCodecVP8) {
73 config_.number_of_streams = num_spatial_streams;
74 VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings();
75 vp8_settings.numberOfTemporalLayers = num_temporal_streams;
Tommi87f70902021-04-27 12:43:0876 config_.encoder_specific_settings = rtc::make_ref_counted<
sprang429600d2017-01-26 14:12:2677 webrtc::VideoEncoderConfig::Vp8EncoderSpecificSettings>(vp8_settings);
Sergey Silkin86684962018-03-28 17:32:3778 } else if (type == VideoCodecType::kVideoCodecVP9) {
79 VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
80 vp9_settings.numberOfSpatialLayers = num_spatial_streams;
81 vp9_settings.numberOfTemporalLayers = num_temporal_streams;
Tommi87f70902021-04-27 12:43:0882 config_.encoder_specific_settings = rtc::make_ref_counted<
Sergey Silkin86684962018-03-28 17:32:3783 webrtc::VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings);
84 } else if (type != VideoCodecType::kVideoCodecMultiplex) {
sprang429600d2017-01-26 14:12:2685 ADD_FAILURE() << "Unexpected codec type: " << type;
86 }
87 }
88
89 bool InitializeCodec() {
90 codec_out_ = VideoCodec();
Elad Aloncde8ab22019-03-20 10:56:2091 frame_buffer_controller_.reset();
Jiawei Ouc2ebe212018-11-08 18:02:5692 if (!VideoCodecInitializer::SetupCodec(config_, streams_, &codec_out_)) {
sprang429600d2017-01-26 14:12:2693 return false;
94 }
Jiawei Ouc2ebe212018-11-08 18:02:5695 bitrate_allocator_ = CreateBuiltinVideoBitrateAllocatorFactory()
96 ->CreateVideoBitrateAllocator(codec_out_);
97 RTC_CHECK(bitrate_allocator_);
Emircan Uysalerd7ae3c32018-01-25 21:01:0998 if (codec_out_.codecType == VideoCodecType::kVideoCodecMultiplex)
Emircan Uysaler0a375472017-12-11 06:51:0299 return true;
Erik Språng82fad3d2018-03-21 08:57:23100
sprang429600d2017-01-26 14:12:26101 // Make sure temporal layers instances have been created.
102 if (codec_out_.codecType == VideoCodecType::kVideoCodecVP8) {
Elad Aloncde8ab22019-03-20 10:56:20103 Vp8TemporalLayersFactory factory;
Elad Alona2795842019-06-07 21:10:00104 const VideoEncoder::Settings settings(VideoEncoder::Capabilities(false),
105 1, 1000);
Elad Alon45befc52019-07-02 09:20:09106 frame_buffer_controller_ =
107 factory.Create(codec_out_, settings, &fec_controller_override_);
sprang429600d2017-01-26 14:12:26108 }
109 return true;
110 }
111
112 VideoStream DefaultStream() {
113 VideoStream stream;
114 stream.width = kDefaultWidth;
115 stream.height = kDefaultHeight;
116 stream.max_framerate = kDefaultFrameRate;
117 stream.min_bitrate_bps = kDefaultMinBitrateBps;
118 stream.target_bitrate_bps = kDefaultTargetBitrateBps;
119 stream.max_bitrate_bps = kDefaultMaxBitrateBps;
120 stream.max_qp = kDefaultMaxQp;
Sergey Silkina796a7e2018-03-01 14:11:29121 stream.num_temporal_layers = 1;
Seth Hampson46e31ba2018-01-18 18:39:54122 stream.active = true;
sprang429600d2017-01-26 14:12:26123 return stream;
124 }
125
126 VideoStream DefaultScreenshareStream() {
127 VideoStream stream = DefaultStream();
128 stream.min_bitrate_bps = 30000;
Florent Castellid3511012020-08-04 09:40:23129 stream.target_bitrate_bps = kScreenshareCodecTargetBitrateBps;
sprang429600d2017-01-26 14:12:26130 stream.max_bitrate_bps = 1000000;
131 stream.max_framerate = kScreenshareDefaultFramerate;
Sergey Silkina796a7e2018-03-01 14:11:29132 stream.num_temporal_layers = 2;
Seth Hampson46e31ba2018-01-18 18:39:54133 stream.active = true;
sprang429600d2017-01-26 14:12:26134 return stream;
135 }
136
Elad Alon45befc52019-07-02 09:20:09137 MockFecControllerOverride fec_controller_override_;
138
sprang429600d2017-01-26 14:12:26139 // Input settings.
140 VideoEncoderConfig config_;
sprang429600d2017-01-26 14:12:26141 std::vector<VideoStream> streams_;
sprang429600d2017-01-26 14:12:26142
143 // Output.
144 VideoCodec codec_out_;
Jiawei Ouc2ebe212018-11-08 18:02:56145 std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
Elad Aloncde8ab22019-03-20 10:56:20146 std::unique_ptr<Vp8FrameBufferController> frame_buffer_controller_;
sprang429600d2017-01-26 14:12:26147};
148
149TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
150 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 1, true);
151 streams_.push_back(DefaultStream());
152 EXPECT_TRUE(InitializeCodec());
153
Florent Castelli8bbdb5b2019-08-02 13:16:28154 VideoBitrateAllocation bitrate_allocation =
155 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
156 kDefaultTargetBitrateBps, kDefaultFrameRate));
sprang429600d2017-01-26 14:12:26157 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
158 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
159 EXPECT_EQ(kDefaultTargetBitrateBps, bitrate_allocation.get_sum_bps());
160}
161
Seth Hampson46e31ba2018-01-18 18:39:54162TEST_F(VideoCodecInitializerTest, SingleStreamVp8ScreenshareInactive) {
163 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 1, true);
164 VideoStream inactive_stream = DefaultStream();
165 inactive_stream.active = false;
166 streams_.push_back(inactive_stream);
167 EXPECT_TRUE(InitializeCodec());
168
Florent Castelli8bbdb5b2019-08-02 13:16:28169 VideoBitrateAllocation bitrate_allocation =
170 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
171 kDefaultTargetBitrateBps, kDefaultFrameRate));
Seth Hampson46e31ba2018-01-18 18:39:54172 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
173 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
174 EXPECT_EQ(0U, bitrate_allocation.get_sum_bps());
175}
176
Florent Castellid3511012020-08-04 09:40:23177TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8ScreenshareConference) {
178 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 2, true);
179 streams_.push_back(DefaultScreenshareStream());
180 EXPECT_TRUE(InitializeCodec());
181 bitrate_allocator_->SetLegacyConferenceMode(true);
182
183 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
184 EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
185 VideoBitrateAllocation bitrate_allocation =
186 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
187 kScreenshareCodecTargetBitrateBps, kScreenshareDefaultFramerate));
188 EXPECT_EQ(kScreenshareCodecTargetBitrateBps,
189 bitrate_allocation.get_sum_bps());
190 EXPECT_EQ(kScreenshareConferenceTl0BitrateBps,
191 bitrate_allocation.GetBitrate(0, 0));
192}
193
sprang429600d2017-01-26 14:12:26194TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8Screenshare) {
195 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, 2, true);
196 streams_.push_back(DefaultScreenshareStream());
197 EXPECT_TRUE(InitializeCodec());
198
199 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
200 EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
Florent Castelli8bbdb5b2019-08-02 13:16:28201 VideoBitrateAllocation bitrate_allocation =
202 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
203 kScreenshareCodecTargetBitrateBps, kScreenshareDefaultFramerate));
sprang429600d2017-01-26 14:12:26204 EXPECT_EQ(kScreenshareCodecTargetBitrateBps,
205 bitrate_allocation.get_sum_bps());
206 EXPECT_EQ(kScreenshareTl0BitrateBps, bitrate_allocation.GetBitrate(0, 0));
207}
208
Seth Hampson46e31ba2018-01-18 18:39:54209TEST_F(VideoCodecInitializerTest, SimulcastVp8Screenshare) {
sprang429600d2017-01-26 14:12:26210 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, 1, true);
211 streams_.push_back(DefaultScreenshareStream());
212 VideoStream video_stream = DefaultStream();
213 video_stream.max_framerate = kScreenshareDefaultFramerate;
214 streams_.push_back(video_stream);
215 EXPECT_TRUE(InitializeCodec());
216
217 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
218 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
219 const uint32_t max_bitrate_bps =
220 streams_[0].target_bitrate_bps + streams_[1].max_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 13:16:28221 VideoBitrateAllocation bitrate_allocation =
222 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
223 max_bitrate_bps, kScreenshareDefaultFramerate));
sprang429600d2017-01-26 14:12:26224 EXPECT_EQ(max_bitrate_bps, bitrate_allocation.get_sum_bps());
225 EXPECT_EQ(static_cast<uint32_t>(streams_[0].target_bitrate_bps),
226 bitrate_allocation.GetSpatialLayerSum(0));
227 EXPECT_EQ(static_cast<uint32_t>(streams_[1].max_bitrate_bps),
228 bitrate_allocation.GetSpatialLayerSum(1));
229}
230
Seth Hampson46e31ba2018-01-18 18:39:54231// Tests that when a video stream is inactive, then the bitrate allocation will
232// be 0 for that stream.
233TEST_F(VideoCodecInitializerTest, SimulcastVp8ScreenshareInactive) {
234 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, 1, true);
235 streams_.push_back(DefaultScreenshareStream());
236 VideoStream inactive_video_stream = DefaultStream();
237 inactive_video_stream.active = false;
238 inactive_video_stream.max_framerate = kScreenshareDefaultFramerate;
239 streams_.push_back(inactive_video_stream);
240 EXPECT_TRUE(InitializeCodec());
241
242 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
243 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
244 const uint32_t target_bitrate =
245 streams_[0].target_bitrate_bps + streams_[1].target_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 13:16:28246 VideoBitrateAllocation bitrate_allocation =
247 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
248 target_bitrate, kScreenshareDefaultFramerate));
Seth Hampson46e31ba2018-01-18 18:39:54249 EXPECT_EQ(static_cast<uint32_t>(streams_[0].max_bitrate_bps),
250 bitrate_allocation.get_sum_bps());
251 EXPECT_EQ(static_cast<uint32_t>(streams_[0].max_bitrate_bps),
252 bitrate_allocation.GetSpatialLayerSum(0));
253 EXPECT_EQ(0U, bitrate_allocation.GetSpatialLayerSum(1));
254}
255
256TEST_F(VideoCodecInitializerTest, HighFpsSimulcastVp8Screenshare) {
sprang429600d2017-01-26 14:12:26257 // Two simulcast streams, the lower one using legacy settings (two temporal
258 // streams, 5fps), the higher one using 3 temporal streams and 30fps.
259 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, 3, true);
260 streams_.push_back(DefaultScreenshareStream());
261 VideoStream video_stream = DefaultStream();
Sergey Silkina796a7e2018-03-01 14:11:29262 video_stream.num_temporal_layers = 3;
sprang429600d2017-01-26 14:12:26263 streams_.push_back(video_stream);
264 EXPECT_TRUE(InitializeCodec());
265
266 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
267 EXPECT_EQ(3u, codec_out_.VP8()->numberOfTemporalLayers);
268 const uint32_t max_bitrate_bps =
269 streams_[0].target_bitrate_bps + streams_[1].max_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 13:16:28270 VideoBitrateAllocation bitrate_allocation = bitrate_allocator_->Allocate(
271 VideoBitrateAllocationParameters(max_bitrate_bps, kDefaultFrameRate));
sprang429600d2017-01-26 14:12:26272 EXPECT_EQ(max_bitrate_bps, bitrate_allocation.get_sum_bps());
273 EXPECT_EQ(static_cast<uint32_t>(streams_[0].target_bitrate_bps),
274 bitrate_allocation.GetSpatialLayerSum(0));
275 EXPECT_EQ(static_cast<uint32_t>(streams_[1].max_bitrate_bps),
276 bitrate_allocation.GetSpatialLayerSum(1));
277 EXPECT_EQ(kHighScreenshareTl0Bps, bitrate_allocation.GetBitrate(1, 0));
278 EXPECT_EQ(kHighScreenshareTl1Bps - kHighScreenshareTl0Bps,
279 bitrate_allocation.GetBitrate(1, 1));
280}
281
Emircan Uysalerd7ae3c32018-01-25 21:01:09282TEST_F(VideoCodecInitializerTest, SingleStreamMultiplexCodec) {
283 SetUpFor(VideoCodecType::kVideoCodecMultiplex, 1, 1, true);
Emircan Uysaler0a375472017-12-11 06:51:02284 streams_.push_back(DefaultStream());
285 EXPECT_TRUE(InitializeCodec());
286}
287
Sergey Silkin86684962018-03-28 17:32:37288TEST_F(VideoCodecInitializerTest, Vp9SvcDefaultLayering) {
289 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false);
290 VideoStream stream = DefaultStream();
291 stream.num_temporal_layers = 3;
292 streams_.push_back(stream);
293
294 EXPECT_TRUE(InitializeCodec());
295 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3u);
296 EXPECT_EQ(codec_out_.VP9()->numberOfTemporalLayers, 3u);
297}
298
299TEST_F(VideoCodecInitializerTest, Vp9SvcAdjustedLayering) {
300 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false);
301 VideoStream stream = DefaultStream();
302 stream.num_temporal_layers = 3;
303 // Set resolution which is only enough to produce 2 spatial layers.
Konrad Hofbauerd2cd8722021-12-09 08:43:56304 stream.width = kMinVp9SpatialLayerLongSideLength * 2;
305 stream.height = kMinVp9SpatialLayerShortSideLength * 2;
Sergey Silkin86684962018-03-28 17:32:37306
307 streams_.push_back(stream);
308
309 EXPECT_TRUE(InitializeCodec());
310 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2u);
311}
312
Sergey Silkinfafeac32018-04-13 14:36:39313TEST_F(VideoCodecInitializerTest,
314 Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrate) {
315 SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 3, false);
316 VideoStream stream = DefaultStream();
317 stream.num_temporal_layers = 3;
318 streams_.push_back(stream);
319
320 EXPECT_TRUE(InitializeCodec());
321 EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate,
322 kDefaultMaxBitrateBps / 1000);
323}
324
Sergey Silkin33120922018-11-28 12:32:13325TEST_F(VideoCodecInitializerTest,
Ilya Nikolaevskiy9ef5e052019-03-05 09:08:35326 Vp9SingleSpatialLayerTargetBitrateIsEqualToCodecMaxBitrate) {
327 SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 1, true);
328 VideoStream stream = DefaultStream();
329 stream.num_temporal_layers = 1;
330 streams_.push_back(stream);
331
332 EXPECT_TRUE(InitializeCodec());
333 EXPECT_EQ(codec_out_.spatialLayers[0].targetBitrate,
334 kDefaultMaxBitrateBps / 1000);
335}
336
337TEST_F(VideoCodecInitializerTest,
Sergey Silkin33120922018-11-28 12:32:13338 Vp9KeepBitrateLimitsIfNumberOfSpatialLayersIsReducedToOne) {
339 // Request 3 spatial layers for 320x180 input. Actual number of layers will be
340 // reduced to 1 due to low input resolution but SVC bitrate limits should be
341 // applied.
342 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false);
343 VideoStream stream = DefaultStream();
344 stream.width = 320;
345 stream.height = 180;
346 stream.num_temporal_layers = 3;
347 streams_.push_back(stream);
348
349 EXPECT_TRUE(InitializeCodec());
350 EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate,
351 kDefaultMaxBitrateBps / 1000);
352}
353
Sergey Silkin8b9b5f92018-12-10 08:28:53354TEST_F(VideoCodecInitializerTest, Vp9DeactivateLayers) {
355 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 1, false);
356 VideoStream stream = DefaultStream();
357 streams_.push_back(stream);
358
359 config_.simulcast_layers.resize(3);
360
361 // Activate all layers.
362 config_.simulcast_layers[0].active = true;
363 config_.simulcast_layers[1].active = true;
364 config_.simulcast_layers[2].active = true;
365 EXPECT_TRUE(InitializeCodec());
Ilya Nikolaevskiya945cda2020-09-22 13:55:23366 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
Sergey Silkin8b9b5f92018-12-10 08:28:53367 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 Nikolaevskiya945cda2020-09-22 13:55:23372 config_.simulcast_layers[0].active = true;
373 config_.simulcast_layers[1].active = true;
Ilya Nikolaevskiy72859e52020-02-05 16:31:00374 config_.simulcast_layers[2].active = false;
Sergey Silkin8b9b5f92018-12-10 08:28:53375 EXPECT_TRUE(InitializeCodec());
Ilya Nikolaevskiya945cda2020-09-22 13:55:23376 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
Sergey Silkin8b9b5f92018-12-10 08:28:53377 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
378 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
379 EXPECT_FALSE(codec_out_.spatialLayers[2].active);
380
381 // Deactivate middle layer.
Ilya Nikolaevskiya945cda2020-09-22 13:55:23382 config_.simulcast_layers[0].active = true;
Sergey Silkin8b9b5f92018-12-10 08:28:53383 config_.simulcast_layers[1].active = false;
Ilya Nikolaevskiya945cda2020-09-22 13:55:23384 config_.simulcast_layers[2].active = true;
Sergey Silkin8b9b5f92018-12-10 08:28:53385 EXPECT_TRUE(InitializeCodec());
Ilya Nikolaevskiya945cda2020-09-22 13:55:23386 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
Sergey Silkin8b9b5f92018-12-10 08:28:53387 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
388 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
389 EXPECT_TRUE(codec_out_.spatialLayers[2].active);
Ilya Nikolaevskiya945cda2020-09-22 13:55:23390
391 // Deactivate first layer.
392 config_.simulcast_layers[0].active = false;
393 config_.simulcast_layers[1].active = true;
394 config_.simulcast_layers[2].active = true;
395 EXPECT_TRUE(InitializeCodec());
396 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2);
397 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
398 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
399
400 // HD singlecast.
401 config_.simulcast_layers[0].active = false;
402 config_.simulcast_layers[1].active = false;
403 config_.simulcast_layers[2].active = true;
404 EXPECT_TRUE(InitializeCodec());
405 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 1);
406 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
407
408 // VGA singlecast.
409 config_.simulcast_layers[0].active = false;
410 config_.simulcast_layers[1].active = true;
411 config_.simulcast_layers[2].active = false;
412 EXPECT_TRUE(InitializeCodec());
413 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2);
414 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
415 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
416
417 // QVGA singlecast.
418 config_.simulcast_layers[0].active = true;
419 config_.simulcast_layers[1].active = false;
420 config_.simulcast_layers[2].active = false;
421 EXPECT_TRUE(InitializeCodec());
422 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
423 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
424 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
425 EXPECT_FALSE(codec_out_.spatialLayers[2].active);
Sergey Silkin8b9b5f92018-12-10 08:28:53426}
427
Danil Chapovalovc27c0472021-05-04 11:06:29428TEST_F(VideoCodecInitializerTest, Av1SingleSpatialLayerBitratesAreConsistent) {
429 VideoEncoderConfig config;
430 config.codec_type = VideoCodecType::kVideoCodecAV1;
431 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13432 streams[0].scalability_mode = ScalabilityMode::kL1T2;
Danil Chapovalovc27c0472021-05-04 11:06:29433
434 VideoCodec codec;
435 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
436
437 EXPECT_GE(codec.spatialLayers[0].targetBitrate,
438 codec.spatialLayers[0].minBitrate);
439 EXPECT_LE(codec.spatialLayers[0].targetBitrate,
440 codec.spatialLayers[0].maxBitrate);
441}
442
443TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersBitratesAreConsistent) {
444 VideoEncoderConfig config;
445 config.codec_type = VideoCodecType::kVideoCodecAV1;
446 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13447 streams[0].scalability_mode = ScalabilityMode::kL2T2;
Danil Chapovalovc27c0472021-05-04 11:06:29448
449 VideoCodec codec;
450 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
451
452 EXPECT_GE(codec.spatialLayers[0].targetBitrate,
453 codec.spatialLayers[0].minBitrate);
454 EXPECT_LE(codec.spatialLayers[0].targetBitrate,
455 codec.spatialLayers[0].maxBitrate);
456
457 EXPECT_GE(codec.spatialLayers[1].targetBitrate,
458 codec.spatialLayers[1].minBitrate);
459 EXPECT_LE(codec.spatialLayers[1].targetBitrate,
460 codec.spatialLayers[1].maxBitrate);
461}
462
Erik Språngf86544482021-06-01 14:52:24463TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersActiveByDefault) {
464 VideoEncoderConfig config;
465 config.codec_type = VideoCodecType::kVideoCodecAV1;
466 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13467 streams[0].scalability_mode = ScalabilityMode::kL2T2;
Erik Språngf86544482021-06-01 14:52:24468 config.spatial_layers = {};
469
470 VideoCodec codec;
471 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
472
473 EXPECT_TRUE(codec.spatialLayers[0].active);
474 EXPECT_TRUE(codec.spatialLayers[1].active);
475}
476
477TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersOneDeactivated) {
478 VideoEncoderConfig config;
479 config.codec_type = VideoCodecType::kVideoCodecAV1;
480 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13481 streams[0].scalability_mode = ScalabilityMode::kL2T2;
Erik Språngf86544482021-06-01 14:52:24482 config.spatial_layers.resize(2);
483 config.spatial_layers[0].active = true;
484 config.spatial_layers[1].active = false;
485
486 VideoCodec codec;
487 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
488
489 EXPECT_TRUE(codec.spatialLayers[0].active);
490 EXPECT_FALSE(codec.spatialLayers[1].active);
491}
492
sprang429600d2017-01-26 14:12:26493} // namespace webrtc