blob: 30078eb837656d15bc1b95ef760f53a5fcae5495 [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,
Henrik Boströmf8bc1162023-03-09 11:51:5261 absl::optional<int> num_simulcast_streams,
62 absl::optional<int> num_spatial_streams,
sprang429600d2017-01-26 14:12:2663 int num_temporal_streams,
64 bool screenshare) {
65 config_ = VideoEncoderConfig();
Niels Möller259a4972018-04-05 13:36:5166 config_.codec_type = type;
67
sprang429600d2017-01-26 14:12:2668 if (screenshare) {
69 config_.min_transmit_bitrate_bps = kDefaultMinTransmitBitrateBps;
70 config_.content_type = VideoEncoderConfig::ContentType::kScreen;
71 }
72
Henrik Boström89e140c2023-03-10 09:43:1973 if (num_simulcast_streams.has_value()) {
Henrik Boströmf8bc1162023-03-09 11:51:5274 config_.number_of_streams = num_simulcast_streams.value();
Henrik Boström89e140c2023-03-10 09:43:1975 }
76 if (type == VideoCodecType::kVideoCodecVP8) {
77 ASSERT_FALSE(num_spatial_streams.has_value());
sprang429600d2017-01-26 14:12:2678 VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings();
79 vp8_settings.numberOfTemporalLayers = num_temporal_streams;
Tommi87f70902021-04-27 12:43:0880 config_.encoder_specific_settings = rtc::make_ref_counted<
sprang429600d2017-01-26 14:12:2681 webrtc::VideoEncoderConfig::Vp8EncoderSpecificSettings>(vp8_settings);
Sergey Silkin86684962018-03-28 17:32:3782 } else if (type == VideoCodecType::kVideoCodecVP9) {
Henrik Boströmf8bc1162023-03-09 11:51:5283 ASSERT_TRUE(num_spatial_streams.has_value());
Sergey Silkin86684962018-03-28 17:32:3784 VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
Henrik Boströmf8bc1162023-03-09 11:51:5285 vp9_settings.numberOfSpatialLayers = num_spatial_streams.value();
Sergey Silkin86684962018-03-28 17:32:3786 vp9_settings.numberOfTemporalLayers = num_temporal_streams;
Tommi87f70902021-04-27 12:43:0887 config_.encoder_specific_settings = rtc::make_ref_counted<
Sergey Silkin86684962018-03-28 17:32:3788 webrtc::VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings);
sprang429600d2017-01-26 14:12:2689 }
90 }
91
92 bool InitializeCodec() {
93 codec_out_ = VideoCodec();
Elad Aloncde8ab22019-03-20 10:56:2094 frame_buffer_controller_.reset();
Jiawei Ouc2ebe212018-11-08 18:02:5695 if (!VideoCodecInitializer::SetupCodec(config_, streams_, &codec_out_)) {
sprang429600d2017-01-26 14:12:2696 return false;
97 }
Jiawei Ouc2ebe212018-11-08 18:02:5698 bitrate_allocator_ = CreateBuiltinVideoBitrateAllocatorFactory()
99 ->CreateVideoBitrateAllocator(codec_out_);
100 RTC_CHECK(bitrate_allocator_);
Erik Språng82fad3d2018-03-21 08:57:23101
sprang429600d2017-01-26 14:12:26102 // Make sure temporal layers instances have been created.
103 if (codec_out_.codecType == VideoCodecType::kVideoCodecVP8) {
Elad Aloncde8ab22019-03-20 10:56:20104 Vp8TemporalLayersFactory factory;
Elad Alona2795842019-06-07 21:10:00105 const VideoEncoder::Settings settings(VideoEncoder::Capabilities(false),
106 1, 1000);
Elad Alon45befc52019-07-02 09:20:09107 frame_buffer_controller_ =
108 factory.Create(codec_out_, settings, &fec_controller_override_);
sprang429600d2017-01-26 14:12:26109 }
110 return true;
111 }
112
Henrik Boström89e140c2023-03-10 09:43:19113 VideoStream DefaultStream(
114 int width = kDefaultWidth,
115 int height = kDefaultHeight,
116 absl::optional<ScalabilityMode> scalability_mode = absl::nullopt) {
sprang429600d2017-01-26 14:12:26117 VideoStream stream;
Henrik Boström89e140c2023-03-10 09:43:19118 stream.width = width;
119 stream.height = height;
sprang429600d2017-01-26 14:12:26120 stream.max_framerate = kDefaultFrameRate;
121 stream.min_bitrate_bps = kDefaultMinBitrateBps;
122 stream.target_bitrate_bps = kDefaultTargetBitrateBps;
123 stream.max_bitrate_bps = kDefaultMaxBitrateBps;
124 stream.max_qp = kDefaultMaxQp;
Sergey Silkina796a7e2018-03-01 14:11:29125 stream.num_temporal_layers = 1;
Seth Hampson46e31ba2018-01-18 18:39:54126 stream.active = true;
Henrik Boström89e140c2023-03-10 09:43:19127 stream.scalability_mode = scalability_mode;
sprang429600d2017-01-26 14:12:26128 return stream;
129 }
130
131 VideoStream DefaultScreenshareStream() {
132 VideoStream stream = DefaultStream();
133 stream.min_bitrate_bps = 30000;
Florent Castellid3511012020-08-04 09:40:23134 stream.target_bitrate_bps = kScreenshareCodecTargetBitrateBps;
sprang429600d2017-01-26 14:12:26135 stream.max_bitrate_bps = 1000000;
136 stream.max_framerate = kScreenshareDefaultFramerate;
Sergey Silkina796a7e2018-03-01 14:11:29137 stream.num_temporal_layers = 2;
Seth Hampson46e31ba2018-01-18 18:39:54138 stream.active = true;
sprang429600d2017-01-26 14:12:26139 return stream;
140 }
141
Elad Alon45befc52019-07-02 09:20:09142 MockFecControllerOverride fec_controller_override_;
143
sprang429600d2017-01-26 14:12:26144 // Input settings.
145 VideoEncoderConfig config_;
sprang429600d2017-01-26 14:12:26146 std::vector<VideoStream> streams_;
sprang429600d2017-01-26 14:12:26147
148 // Output.
149 VideoCodec codec_out_;
Jiawei Ouc2ebe212018-11-08 18:02:56150 std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
Elad Aloncde8ab22019-03-20 10:56:20151 std::unique_ptr<Vp8FrameBufferController> frame_buffer_controller_;
sprang429600d2017-01-26 14:12:26152};
153
154TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
Henrik Boströmf8bc1162023-03-09 11:51:52155 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 1, true);
sprang429600d2017-01-26 14:12:26156 streams_.push_back(DefaultStream());
157 EXPECT_TRUE(InitializeCodec());
158
Florent Castelli8bbdb5b2019-08-02 13:16:28159 VideoBitrateAllocation bitrate_allocation =
160 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
161 kDefaultTargetBitrateBps, kDefaultFrameRate));
sprang429600d2017-01-26 14:12:26162 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
163 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
164 EXPECT_EQ(kDefaultTargetBitrateBps, bitrate_allocation.get_sum_bps());
165}
166
Seth Hampson46e31ba2018-01-18 18:39:54167TEST_F(VideoCodecInitializerTest, SingleStreamVp8ScreenshareInactive) {
Henrik Boströmf8bc1162023-03-09 11:51:52168 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 1, true);
Seth Hampson46e31ba2018-01-18 18:39:54169 VideoStream inactive_stream = DefaultStream();
170 inactive_stream.active = false;
171 streams_.push_back(inactive_stream);
172 EXPECT_TRUE(InitializeCodec());
173
Florent Castelli8bbdb5b2019-08-02 13:16:28174 VideoBitrateAllocation bitrate_allocation =
175 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
176 kDefaultTargetBitrateBps, kDefaultFrameRate));
Seth Hampson46e31ba2018-01-18 18:39:54177 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
178 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
179 EXPECT_EQ(0U, bitrate_allocation.get_sum_bps());
180}
181
Florent Castellid3511012020-08-04 09:40:23182TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8ScreenshareConference) {
Henrik Boströmf8bc1162023-03-09 11:51:52183 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 2, true);
Florent Castellid3511012020-08-04 09:40:23184 streams_.push_back(DefaultScreenshareStream());
185 EXPECT_TRUE(InitializeCodec());
186 bitrate_allocator_->SetLegacyConferenceMode(true);
187
188 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
189 EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
190 VideoBitrateAllocation bitrate_allocation =
191 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
192 kScreenshareCodecTargetBitrateBps, kScreenshareDefaultFramerate));
193 EXPECT_EQ(kScreenshareCodecTargetBitrateBps,
194 bitrate_allocation.get_sum_bps());
195 EXPECT_EQ(kScreenshareConferenceTl0BitrateBps,
196 bitrate_allocation.GetBitrate(0, 0));
197}
198
sprang429600d2017-01-26 14:12:26199TEST_F(VideoCodecInitializerTest, TemporalLayeredVp8Screenshare) {
Henrik Boströmf8bc1162023-03-09 11:51:52200 SetUpFor(VideoCodecType::kVideoCodecVP8, 1, absl::nullopt, 2, true);
sprang429600d2017-01-26 14:12:26201 streams_.push_back(DefaultScreenshareStream());
202 EXPECT_TRUE(InitializeCodec());
203
204 EXPECT_EQ(1u, codec_out_.numberOfSimulcastStreams);
205 EXPECT_EQ(2u, codec_out_.VP8()->numberOfTemporalLayers);
Florent Castelli8bbdb5b2019-08-02 13:16:28206 VideoBitrateAllocation bitrate_allocation =
207 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
208 kScreenshareCodecTargetBitrateBps, kScreenshareDefaultFramerate));
sprang429600d2017-01-26 14:12:26209 EXPECT_EQ(kScreenshareCodecTargetBitrateBps,
210 bitrate_allocation.get_sum_bps());
211 EXPECT_EQ(kScreenshareTl0BitrateBps, bitrate_allocation.GetBitrate(0, 0));
212}
213
Seth Hampson46e31ba2018-01-18 18:39:54214TEST_F(VideoCodecInitializerTest, SimulcastVp8Screenshare) {
Henrik Boströmf8bc1162023-03-09 11:51:52215 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, absl::nullopt, 1, true);
sprang429600d2017-01-26 14:12:26216 streams_.push_back(DefaultScreenshareStream());
217 VideoStream video_stream = DefaultStream();
218 video_stream.max_framerate = kScreenshareDefaultFramerate;
219 streams_.push_back(video_stream);
220 EXPECT_TRUE(InitializeCodec());
221
222 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
223 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
224 const uint32_t max_bitrate_bps =
225 streams_[0].target_bitrate_bps + streams_[1].max_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 13:16:28226 VideoBitrateAllocation bitrate_allocation =
227 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
228 max_bitrate_bps, kScreenshareDefaultFramerate));
sprang429600d2017-01-26 14:12:26229 EXPECT_EQ(max_bitrate_bps, bitrate_allocation.get_sum_bps());
230 EXPECT_EQ(static_cast<uint32_t>(streams_[0].target_bitrate_bps),
231 bitrate_allocation.GetSpatialLayerSum(0));
232 EXPECT_EQ(static_cast<uint32_t>(streams_[1].max_bitrate_bps),
233 bitrate_allocation.GetSpatialLayerSum(1));
234}
235
Seth Hampson46e31ba2018-01-18 18:39:54236// Tests that when a video stream is inactive, then the bitrate allocation will
237// be 0 for that stream.
238TEST_F(VideoCodecInitializerTest, SimulcastVp8ScreenshareInactive) {
Henrik Boströmf8bc1162023-03-09 11:51:52239 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, absl::nullopt, 1, true);
Seth Hampson46e31ba2018-01-18 18:39:54240 streams_.push_back(DefaultScreenshareStream());
241 VideoStream inactive_video_stream = DefaultStream();
242 inactive_video_stream.active = false;
243 inactive_video_stream.max_framerate = kScreenshareDefaultFramerate;
244 streams_.push_back(inactive_video_stream);
245 EXPECT_TRUE(InitializeCodec());
246
247 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
248 EXPECT_EQ(1u, codec_out_.VP8()->numberOfTemporalLayers);
249 const uint32_t target_bitrate =
250 streams_[0].target_bitrate_bps + streams_[1].target_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 13:16:28251 VideoBitrateAllocation bitrate_allocation =
252 bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
253 target_bitrate, kScreenshareDefaultFramerate));
Seth Hampson46e31ba2018-01-18 18:39:54254 EXPECT_EQ(static_cast<uint32_t>(streams_[0].max_bitrate_bps),
255 bitrate_allocation.get_sum_bps());
256 EXPECT_EQ(static_cast<uint32_t>(streams_[0].max_bitrate_bps),
257 bitrate_allocation.GetSpatialLayerSum(0));
258 EXPECT_EQ(0U, bitrate_allocation.GetSpatialLayerSum(1));
259}
260
261TEST_F(VideoCodecInitializerTest, HighFpsSimulcastVp8Screenshare) {
sprang429600d2017-01-26 14:12:26262 // Two simulcast streams, the lower one using legacy settings (two temporal
263 // streams, 5fps), the higher one using 3 temporal streams and 30fps.
Henrik Boströmf8bc1162023-03-09 11:51:52264 SetUpFor(VideoCodecType::kVideoCodecVP8, 2, absl::nullopt, 3, true);
sprang429600d2017-01-26 14:12:26265 streams_.push_back(DefaultScreenshareStream());
266 VideoStream video_stream = DefaultStream();
Sergey Silkina796a7e2018-03-01 14:11:29267 video_stream.num_temporal_layers = 3;
sprang429600d2017-01-26 14:12:26268 streams_.push_back(video_stream);
269 EXPECT_TRUE(InitializeCodec());
270
271 EXPECT_EQ(2u, codec_out_.numberOfSimulcastStreams);
272 EXPECT_EQ(3u, codec_out_.VP8()->numberOfTemporalLayers);
273 const uint32_t max_bitrate_bps =
274 streams_[0].target_bitrate_bps + streams_[1].max_bitrate_bps;
Florent Castelli8bbdb5b2019-08-02 13:16:28275 VideoBitrateAllocation bitrate_allocation = bitrate_allocator_->Allocate(
276 VideoBitrateAllocationParameters(max_bitrate_bps, kDefaultFrameRate));
sprang429600d2017-01-26 14:12:26277 EXPECT_EQ(max_bitrate_bps, bitrate_allocation.get_sum_bps());
278 EXPECT_EQ(static_cast<uint32_t>(streams_[0].target_bitrate_bps),
279 bitrate_allocation.GetSpatialLayerSum(0));
280 EXPECT_EQ(static_cast<uint32_t>(streams_[1].max_bitrate_bps),
281 bitrate_allocation.GetSpatialLayerSum(1));
282 EXPECT_EQ(kHighScreenshareTl0Bps, bitrate_allocation.GetBitrate(1, 0));
283 EXPECT_EQ(kHighScreenshareTl1Bps - kHighScreenshareTl0Bps,
284 bitrate_allocation.GetBitrate(1, 1));
285}
286
Sergey Silkin86684962018-03-28 17:32:37287TEST_F(VideoCodecInitializerTest, Vp9SvcDefaultLayering) {
Henrik Boströmf8bc1162023-03-09 11:51:52288 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
Sergey Silkin86684962018-03-28 17:32:37289 VideoStream stream = DefaultStream();
290 stream.num_temporal_layers = 3;
291 streams_.push_back(stream);
292
293 EXPECT_TRUE(InitializeCodec());
294 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3u);
295 EXPECT_EQ(codec_out_.VP9()->numberOfTemporalLayers, 3u);
296}
297
298TEST_F(VideoCodecInitializerTest, Vp9SvcAdjustedLayering) {
Henrik Boströmf8bc1162023-03-09 11:51:52299 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
Sergey Silkin86684962018-03-28 17:32:37300 VideoStream stream = DefaultStream();
301 stream.num_temporal_layers = 3;
302 // Set resolution which is only enough to produce 2 spatial layers.
Konrad Hofbauerd2cd8722021-12-09 08:43:56303 stream.width = kMinVp9SpatialLayerLongSideLength * 2;
304 stream.height = kMinVp9SpatialLayerShortSideLength * 2;
Sergey Silkin86684962018-03-28 17:32:37305
306 streams_.push_back(stream);
307
308 EXPECT_TRUE(InitializeCodec());
309 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2u);
310}
311
Sergey Silkinfafeac32018-04-13 14:36:39312TEST_F(VideoCodecInitializerTest,
313 Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrate) {
Henrik Boströmf8bc1162023-03-09 11:51:52314 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 1, 3, false);
Sergey Silkinfafeac32018-04-13 14:36:39315 VideoStream stream = DefaultStream();
316 stream.num_temporal_layers = 3;
317 streams_.push_back(stream);
318
319 EXPECT_TRUE(InitializeCodec());
320 EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate,
321 kDefaultMaxBitrateBps / 1000);
322}
323
Sergey Silkin33120922018-11-28 12:32:13324TEST_F(VideoCodecInitializerTest,
Åsa Persson014b2442023-03-21 08:49:32325 Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrateWithL1T1) {
326 SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 1, 1, false);
327 VideoStream stream = DefaultStream();
328 stream.num_temporal_layers = 1;
329 stream.scalability_mode = ScalabilityMode::kL1T1;
330 streams_.push_back(stream);
331
332 EXPECT_TRUE(InitializeCodec());
333 EXPECT_EQ(1u, codec_out_.VP9()->numberOfSpatialLayers);
334 EXPECT_EQ(codec_out_.spatialLayers[0].minBitrate,
335 kDefaultMinBitrateBps / 1000);
336 EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate,
337 kDefaultMaxBitrateBps / 1000);
338}
339
340TEST_F(VideoCodecInitializerTest,
Ilya Nikolaevskiy9ef5e052019-03-05 09:08:35341 Vp9SingleSpatialLayerTargetBitrateIsEqualToCodecMaxBitrate) {
Henrik Boströmf8bc1162023-03-09 11:51:52342 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 1, 1, true);
Ilya Nikolaevskiy9ef5e052019-03-05 09:08:35343 VideoStream stream = DefaultStream();
344 stream.num_temporal_layers = 1;
345 streams_.push_back(stream);
346
347 EXPECT_TRUE(InitializeCodec());
348 EXPECT_EQ(codec_out_.spatialLayers[0].targetBitrate,
349 kDefaultMaxBitrateBps / 1000);
350}
351
352TEST_F(VideoCodecInitializerTest,
Sergey Silkin33120922018-11-28 12:32:13353 Vp9KeepBitrateLimitsIfNumberOfSpatialLayersIsReducedToOne) {
354 // Request 3 spatial layers for 320x180 input. Actual number of layers will be
355 // reduced to 1 due to low input resolution but SVC bitrate limits should be
356 // applied.
Henrik Boströmf8bc1162023-03-09 11:51:52357 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
Sergey Silkin33120922018-11-28 12:32:13358 VideoStream stream = DefaultStream();
359 stream.width = 320;
360 stream.height = 180;
361 stream.num_temporal_layers = 3;
362 streams_.push_back(stream);
363
364 EXPECT_TRUE(InitializeCodec());
365 EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate,
366 kDefaultMaxBitrateBps / 1000);
367}
368
Åsa Persson014b2442023-03-21 08:49:32369TEST_F(VideoCodecInitializerTest,
370 Vp9KeepBitrateLimitsIfNumberOfSpatialLayersIsReducedToOneWithL3T1) {
371 // Request 3 spatial layers for 320x180 input. Actual number of layers will be
372 // reduced to 1 due to low input resolution but SVC bitrate limits should be
373 // applied.
374 SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 3, 1, false);
375 VideoStream stream = DefaultStream();
376 stream.width = 320;
377 stream.height = 180;
378 stream.num_temporal_layers = 1;
379 stream.scalability_mode = ScalabilityMode::kL3T1;
380 streams_.push_back(stream);
381
382 EXPECT_TRUE(InitializeCodec());
383 EXPECT_EQ(1u, codec_out_.VP9()->numberOfSpatialLayers);
384 EXPECT_LT(codec_out_.spatialLayers[0].minBitrate,
385 kDefaultMinBitrateBps / 1000);
386 EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate,
387 kDefaultMaxBitrateBps / 1000);
388}
389
Sergey Silkin8b9b5f92018-12-10 08:28:53390TEST_F(VideoCodecInitializerTest, Vp9DeactivateLayers) {
Henrik Boströmf8bc1162023-03-09 11:51:52391 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 1, false);
Sergey Silkin8b9b5f92018-12-10 08:28:53392 VideoStream stream = DefaultStream();
393 streams_.push_back(stream);
394
395 config_.simulcast_layers.resize(3);
396
397 // Activate all layers.
398 config_.simulcast_layers[0].active = true;
399 config_.simulcast_layers[1].active = true;
400 config_.simulcast_layers[2].active = true;
401 EXPECT_TRUE(InitializeCodec());
Ilya Nikolaevskiya945cda2020-09-22 13:55:23402 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
Sergey Silkin8b9b5f92018-12-10 08:28:53403 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
404 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
405 EXPECT_TRUE(codec_out_.spatialLayers[2].active);
406
407 // Deactivate top layer.
Ilya Nikolaevskiya945cda2020-09-22 13:55:23408 config_.simulcast_layers[0].active = true;
409 config_.simulcast_layers[1].active = true;
Ilya Nikolaevskiy72859e52020-02-05 16:31:00410 config_.simulcast_layers[2].active = false;
Sergey Silkin8b9b5f92018-12-10 08:28:53411 EXPECT_TRUE(InitializeCodec());
Ilya Nikolaevskiya945cda2020-09-22 13:55:23412 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
Sergey Silkin8b9b5f92018-12-10 08:28:53413 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
414 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
415 EXPECT_FALSE(codec_out_.spatialLayers[2].active);
416
417 // Deactivate middle layer.
Ilya Nikolaevskiya945cda2020-09-22 13:55:23418 config_.simulcast_layers[0].active = true;
Sergey Silkin8b9b5f92018-12-10 08:28:53419 config_.simulcast_layers[1].active = false;
Ilya Nikolaevskiya945cda2020-09-22 13:55:23420 config_.simulcast_layers[2].active = true;
Sergey Silkin8b9b5f92018-12-10 08:28:53421 EXPECT_TRUE(InitializeCodec());
Ilya Nikolaevskiya945cda2020-09-22 13:55:23422 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
Sergey Silkin8b9b5f92018-12-10 08:28:53423 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
424 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
425 EXPECT_TRUE(codec_out_.spatialLayers[2].active);
Ilya Nikolaevskiya945cda2020-09-22 13:55:23426
427 // Deactivate first layer.
428 config_.simulcast_layers[0].active = false;
429 config_.simulcast_layers[1].active = true;
430 config_.simulcast_layers[2].active = true;
431 EXPECT_TRUE(InitializeCodec());
432 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2);
433 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
434 EXPECT_TRUE(codec_out_.spatialLayers[1].active);
435
436 // HD singlecast.
437 config_.simulcast_layers[0].active = false;
438 config_.simulcast_layers[1].active = false;
439 config_.simulcast_layers[2].active = true;
440 EXPECT_TRUE(InitializeCodec());
441 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 1);
442 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
443
444 // VGA singlecast.
445 config_.simulcast_layers[0].active = false;
446 config_.simulcast_layers[1].active = true;
447 config_.simulcast_layers[2].active = false;
448 EXPECT_TRUE(InitializeCodec());
449 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2);
450 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
451 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
452
453 // QVGA singlecast.
454 config_.simulcast_layers[0].active = true;
455 config_.simulcast_layers[1].active = false;
456 config_.simulcast_layers[2].active = false;
457 EXPECT_TRUE(InitializeCodec());
458 EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 3);
459 EXPECT_TRUE(codec_out_.spatialLayers[0].active);
460 EXPECT_FALSE(codec_out_.spatialLayers[1].active);
461 EXPECT_FALSE(codec_out_.spatialLayers[2].active);
Sergey Silkin8b9b5f92018-12-10 08:28:53462}
463
Henrik Boströmf8bc1162023-03-09 11:51:52464TEST_F(VideoCodecInitializerTest, Vp9SvcResolutionAlignment) {
465 SetUpFor(VideoCodecType::kVideoCodecVP9, absl::nullopt, 3, 3, false);
466 VideoStream stream = DefaultStream();
467 stream.width = 1281;
468 stream.height = 721;
469 stream.num_temporal_layers = 3;
470 streams_.push_back(stream);
471
472 EXPECT_TRUE(InitializeCodec());
473 EXPECT_EQ(codec_out_.width, 1280);
474 EXPECT_EQ(codec_out_.height, 720);
475 EXPECT_EQ(codec_out_.numberOfSimulcastStreams, 1);
476 EXPECT_EQ(codec_out_.simulcastStream[0].width, 1280);
477 EXPECT_EQ(codec_out_.simulcastStream[0].height, 720);
478}
479
Henrik Boström89e140c2023-03-10 09:43:19480TEST_F(VideoCodecInitializerTest, Vp9SimulcastResolutions) {
481 // 3 x L1T3
482 SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 1, 3, false);
483 // Scalability mode has to be set on all layers to avoid legacy SVC paths.
484 streams_ = {DefaultStream(320, 180, ScalabilityMode::kL1T3),
485 DefaultStream(640, 360, ScalabilityMode::kL1T3),
486 DefaultStream(1280, 720, ScalabilityMode::kL1T3)};
487
488 EXPECT_TRUE(InitializeCodec());
489 // This is expected to be the largest layer.
490 EXPECT_EQ(codec_out_.width, 1280);
491 EXPECT_EQ(codec_out_.height, 720);
492 // `simulcastStream` is expected to be the same as the input (same order).
493 EXPECT_EQ(codec_out_.numberOfSimulcastStreams, 3);
494 EXPECT_EQ(codec_out_.simulcastStream[0].width, 320);
495 EXPECT_EQ(codec_out_.simulcastStream[0].height, 180);
496 EXPECT_EQ(codec_out_.simulcastStream[1].width, 640);
497 EXPECT_EQ(codec_out_.simulcastStream[1].height, 360);
498 EXPECT_EQ(codec_out_.simulcastStream[2].width, 1280);
499 EXPECT_EQ(codec_out_.simulcastStream[2].height, 720);
500}
501
Danil Chapovalovc27c0472021-05-04 11:06:29502TEST_F(VideoCodecInitializerTest, Av1SingleSpatialLayerBitratesAreConsistent) {
503 VideoEncoderConfig config;
504 config.codec_type = VideoCodecType::kVideoCodecAV1;
505 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13506 streams[0].scalability_mode = ScalabilityMode::kL1T2;
Danil Chapovalovc27c0472021-05-04 11:06:29507
508 VideoCodec codec;
509 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
510
511 EXPECT_GE(codec.spatialLayers[0].targetBitrate,
512 codec.spatialLayers[0].minBitrate);
513 EXPECT_LE(codec.spatialLayers[0].targetBitrate,
514 codec.spatialLayers[0].maxBitrate);
515}
516
517TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersBitratesAreConsistent) {
518 VideoEncoderConfig config;
519 config.codec_type = VideoCodecType::kVideoCodecAV1;
520 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13521 streams[0].scalability_mode = ScalabilityMode::kL2T2;
Danil Chapovalovc27c0472021-05-04 11:06:29522
523 VideoCodec codec;
524 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
525
526 EXPECT_GE(codec.spatialLayers[0].targetBitrate,
527 codec.spatialLayers[0].minBitrate);
528 EXPECT_LE(codec.spatialLayers[0].targetBitrate,
529 codec.spatialLayers[0].maxBitrate);
530
531 EXPECT_GE(codec.spatialLayers[1].targetBitrate,
532 codec.spatialLayers[1].minBitrate);
533 EXPECT_LE(codec.spatialLayers[1].targetBitrate,
534 codec.spatialLayers[1].maxBitrate);
535}
536
Erik Språngf86544482021-06-01 14:52:24537TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersActiveByDefault) {
538 VideoEncoderConfig config;
539 config.codec_type = VideoCodecType::kVideoCodecAV1;
540 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13541 streams[0].scalability_mode = ScalabilityMode::kL2T2;
Erik Språngf86544482021-06-01 14:52:24542 config.spatial_layers = {};
543
544 VideoCodec codec;
545 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
546
547 EXPECT_TRUE(codec.spatialLayers[0].active);
548 EXPECT_TRUE(codec.spatialLayers[1].active);
549}
550
551TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersOneDeactivated) {
552 VideoEncoderConfig config;
553 config.codec_type = VideoCodecType::kVideoCodecAV1;
554 std::vector<VideoStream> streams = {DefaultStream()};
Niels Möller79d566b2022-04-29 09:03:13555 streams[0].scalability_mode = ScalabilityMode::kL2T2;
Erik Språngf86544482021-06-01 14:52:24556 config.spatial_layers.resize(2);
557 config.spatial_layers[0].active = true;
558 config.spatial_layers[1].active = false;
559
560 VideoCodec codec;
561 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
562
563 EXPECT_TRUE(codec.spatialLayers[0].active);
564 EXPECT_FALSE(codec.spatialLayers[1].active);
565}
566
Åsa Persson014b2442023-03-21 08:49:32567TEST_F(VideoCodecInitializerTest, Vp9SingleSpatialLayerBitratesAreConsistent) {
568 VideoEncoderConfig config;
569 config.simulcast_layers.resize(3);
570 config.simulcast_layers[0].active = true;
571 config.simulcast_layers[1].active = false;
572 config.simulcast_layers[2].active = false;
573
574 config.codec_type = VideoCodecType::kVideoCodecVP9;
575 std::vector<VideoStream> streams = {DefaultStream()};
576 streams[0].scalability_mode = ScalabilityMode::kL1T2;
577
578 VideoCodec codec;
579 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
580
581 EXPECT_EQ(1u, codec.VP9()->numberOfSpatialLayers);
Henrik Boström9bbd95982023-04-03 12:21:15582 // Target is consistent with min and max (min <= target <= max).
Åsa Persson014b2442023-03-21 08:49:32583 EXPECT_GE(codec.spatialLayers[0].targetBitrate,
584 codec.spatialLayers[0].minBitrate);
585 EXPECT_LE(codec.spatialLayers[0].targetBitrate,
586 codec.spatialLayers[0].maxBitrate);
Henrik Boström9bbd95982023-04-03 12:21:15587 // In the single spatial layer case, the spatial layer bitrates are copied
588 // from the codec's bitrate which is the sum if VideoStream bitrates. In this
589 // case we only have a single VideoStream using default values.
590 EXPECT_EQ(codec.spatialLayers[0].minBitrate, kDefaultMinBitrateBps / 1000);
591 EXPECT_EQ(codec.spatialLayers[0].targetBitrate, kDefaultMaxBitrateBps / 1000);
592 EXPECT_EQ(codec.spatialLayers[0].maxBitrate, kDefaultMaxBitrateBps / 1000);
Åsa Persson014b2442023-03-21 08:49:32593}
594
595TEST_F(VideoCodecInitializerTest, Vp9TwoSpatialLayersBitratesAreConsistent) {
596 VideoEncoderConfig config;
597 config.simulcast_layers.resize(3);
598 config.simulcast_layers[0].active = true;
599 config.simulcast_layers[1].active = false;
600 config.simulcast_layers[2].active = false;
601
602 config.codec_type = VideoCodecType::kVideoCodecVP9;
603 std::vector<VideoStream> streams = {DefaultStream()};
604 streams[0].scalability_mode = ScalabilityMode::kL2T2;
605
606 VideoCodec codec;
607 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
608
609 EXPECT_EQ(2u, codec.VP9()->numberOfSpatialLayers);
610 EXPECT_GE(codec.spatialLayers[0].targetBitrate,
611 codec.spatialLayers[0].minBitrate);
612 EXPECT_LE(codec.spatialLayers[0].targetBitrate,
613 codec.spatialLayers[0].maxBitrate);
614 EXPECT_LT(codec.spatialLayers[0].minBitrate, kDefaultMinBitrateBps / 1000);
615
616 EXPECT_GE(codec.spatialLayers[1].targetBitrate,
617 codec.spatialLayers[1].minBitrate);
618 EXPECT_LE(codec.spatialLayers[1].targetBitrate,
619 codec.spatialLayers[1].maxBitrate);
620 EXPECT_GT(codec.spatialLayers[1].minBitrate,
621 codec.spatialLayers[0].maxBitrate);
622}
623
Åsa Persson1dccfeb2024-01-26 08:50:23624TEST_F(VideoCodecInitializerTest, UpdatesVp9SpecificFieldsWithScalabilityMode) {
625 VideoEncoderConfig config;
626 config.codec_type = VideoCodecType::kVideoCodecVP9;
627 std::vector<VideoStream> streams = {DefaultStream()};
628 streams[0].scalability_mode = ScalabilityMode::kL2T3_KEY;
629
630 VideoCodec codec;
631 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
632
633 EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 2u);
634 EXPECT_EQ(codec.VP9()->numberOfTemporalLayers, 3u);
635 EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOnKeyPic);
636
637 streams[0].scalability_mode = ScalabilityMode::kS3T1;
638 EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
639
640 EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 3u);
641 EXPECT_EQ(codec.VP9()->numberOfTemporalLayers, 1u);
642 EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOff);
643}
644
sprang429600d2017-01-26 14:12:26645} // namespace webrtc