blob: e219995b4b2803484306b022c2b152bb3fdc8ad5 [file] [log] [blame]
Sergey Silkind4311562023-11-13 14:48:251/*
2 * Copyright (c) 2022 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
11#include "test/video_codec_tester.h"
12
13#include <map>
14#include <memory>
15#include <string>
16#include <tuple>
17#include <utility>
18#include <vector>
19
Danil Chapovalovd213dd52024-01-25 14:48:2420#include "api/environment/environment.h"
21#include "api/environment/environment_factory.h"
Sergey Silkind4311562023-11-13 14:48:2522#include "api/test/mock_video_decoder.h"
23#include "api/test/mock_video_decoder_factory.h"
24#include "api/test/mock_video_encoder.h"
25#include "api/test/mock_video_encoder_factory.h"
26#include "api/units/data_rate.h"
Sergey Silkin66344ac2023-12-22 08:36:5927#include "api/units/data_size.h"
28#include "api/units/frequency.h"
Sergey Silkind4311562023-11-13 14:48:2529#include "api/units/time_delta.h"
30#include "api/video/i420_buffer.h"
31#include "api/video/video_frame.h"
Sergey Silkinb792d602024-06-03 14:16:0132#include "api/video_codecs/builtin_video_decoder_factory.h"
33#include "api/video_codecs/builtin_video_encoder_factory.h"
Sergey Silkin66344ac2023-12-22 08:36:5934#include "api/video_codecs/scalability_mode.h"
35#include "api/video_codecs/video_decoder.h"
36#include "api/video_codecs/video_encoder.h"
Sergey Silkind4311562023-11-13 14:48:2537#include "modules/video_coding/include/video_codec_interface.h"
38#include "modules/video_coding/svc/scalability_mode_util.h"
39#include "test/gmock.h"
40#include "test/gtest.h"
41#include "test/testsupport/file_utils.h"
42#include "third_party/libyuv/include/libyuv/planar_functions.h"
43
44namespace webrtc {
45namespace test {
46
47namespace {
48using ::testing::_;
49using ::testing::ElementsAre;
50using ::testing::Field;
Sergey Silkind4311562023-11-13 14:48:2551using ::testing::NiceMock;
52using ::testing::Return;
53using ::testing::SizeIs;
Sergey Silkin9e5c9792023-12-22 08:39:5654using ::testing::UnorderedElementsAreArray;
Sergey Silkin66344ac2023-12-22 08:36:5955using ::testing::Values;
Danil Chapovalovd213dd52024-01-25 14:48:2456using ::testing::WithoutArgs;
Sergey Silkind4311562023-11-13 14:48:2557
58using VideoCodecStats = VideoCodecTester::VideoCodecStats;
59using VideoSourceSettings = VideoCodecTester::VideoSourceSettings;
60using CodedVideoSource = VideoCodecTester::CodedVideoSource;
61using EncodingSettings = VideoCodecTester::EncodingSettings;
62using LayerSettings = EncodingSettings::LayerSettings;
63using LayerId = VideoCodecTester::LayerId;
64using DecoderSettings = VideoCodecTester::DecoderSettings;
65using EncoderSettings = VideoCodecTester::EncoderSettings;
66using PacingSettings = VideoCodecTester::PacingSettings;
67using PacingMode = PacingSettings::PacingMode;
68using Filter = VideoCodecStats::Filter;
69using Frame = VideoCodecTester::VideoCodecStats::Frame;
70using Stream = VideoCodecTester::VideoCodecStats::Stream;
71
72constexpr int kWidth = 2;
73constexpr int kHeight = 2;
Sergey Silkin5f3fc502024-05-08 08:37:4074const DataRate kBitrate = DataRate::BytesPerSec(100);
75const Frequency kFramerate = Frequency::Hertz(30);
Sergey Silkind4311562023-11-13 14:48:2576constexpr Frequency k90kHz = Frequency::Hertz(90000);
77
78rtc::scoped_refptr<I420Buffer> CreateYuvBuffer(uint8_t y = 0,
79 uint8_t u = 0,
80 uint8_t v = 0) {
81 rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create(2, 2));
82
83 libyuv::I420Rect(buffer->MutableDataY(), buffer->StrideY(),
84 buffer->MutableDataU(), buffer->StrideU(),
85 buffer->MutableDataV(), buffer->StrideV(), 0, 0,
86 buffer->width(), buffer->height(), y, u, v);
87 return buffer;
88}
89
Sergey Silkin9e5c9792023-12-22 08:39:5690// TODO(ssilkin): Wrap this into a class that removes file in dtor.
Sergey Silkind4311562023-11-13 14:48:2591std::string CreateYuvFile(int width, int height, int num_frames) {
92 std::string path = webrtc::test::TempFilename(webrtc::test::OutputPath(),
93 "video_codec_tester_unittest");
94 FILE* file = fopen(path.c_str(), "wb");
95 for (int frame_num = 0; frame_num < num_frames; ++frame_num) {
Sergey Silkin66344ac2023-12-22 08:36:5996 // For purposes of testing quality estimation, we need Y, U, V values in
97 // source and decoded video to be unique and deterministic. In source video
98 // we make them functions of frame number. The test decoder makes them
99 // functions of encoded frame size in decoded video.
100 uint8_t y = (frame_num * 3 + 0) & 255;
101 uint8_t u = (frame_num * 3 + 1) & 255;
102 uint8_t v = (frame_num * 3 + 2) & 255;
Sergey Silkind4311562023-11-13 14:48:25103 rtc::scoped_refptr<I420Buffer> buffer = CreateYuvBuffer(y, u, v);
104 fwrite(buffer->DataY(), 1, width * height, file);
105 int chroma_size_bytes = (width + 1) / 2 * (height + 1) / 2;
106 fwrite(buffer->DataU(), 1, chroma_size_bytes, file);
107 fwrite(buffer->DataV(), 1, chroma_size_bytes, file);
108 }
109 fclose(file);
110 return path;
111}
112
Sergey Silkin66344ac2023-12-22 08:36:59113class TestVideoEncoder : public MockVideoEncoder {
114 public:
115 TestVideoEncoder(ScalabilityMode scalability_mode,
116 std::vector<std::vector<Frame>> encoded_frames)
117 : scalability_mode_(scalability_mode), encoded_frames_(encoded_frames) {}
118 int32_t Encode(const VideoFrame& input_frame,
119 const std::vector<VideoFrameType>*) override {
120 for (const Frame& frame : encoded_frames_[num_encoded_frames_]) {
121 if (frame.frame_size.IsZero()) {
122 continue; // Frame drop.
Sergey Silkind4311562023-11-13 14:48:25123 }
Sergey Silkin66344ac2023-12-22 08:36:59124 EncodedImage encoded_frame;
125 encoded_frame._encodedWidth = frame.width;
126 encoded_frame._encodedHeight = frame.height;
127 encoded_frame.SetFrameType(frame.keyframe
128 ? VideoFrameType::kVideoFrameKey
129 : VideoFrameType::kVideoFrameDelta);
Per K0fa90882024-03-13 08:52:41130 encoded_frame.SetRtpTimestamp(input_frame.rtp_timestamp());
Sergey Silkin66344ac2023-12-22 08:36:59131 encoded_frame.SetSpatialIndex(frame.layer_id.spatial_idx);
132 encoded_frame.SetTemporalIndex(frame.layer_id.temporal_idx);
133 encoded_frame.SetEncodedData(
134 EncodedImageBuffer::Create(frame.frame_size.bytes()));
135 CodecSpecificInfo codec_specific_info;
136 codec_specific_info.scalability_mode = scalability_mode_;
137 callback_->OnEncodedImage(encoded_frame, &codec_specific_info);
Sergey Silkind4311562023-11-13 14:48:25138 }
Sergey Silkin66344ac2023-12-22 08:36:59139 ++num_encoded_frames_;
140 return WEBRTC_VIDEO_CODEC_OK;
Sergey Silkind4311562023-11-13 14:48:25141 }
142
Sergey Silkin66344ac2023-12-22 08:36:59143 int32_t RegisterEncodeCompleteCallback(
144 EncodedImageCallback* callback) override {
145 callback_ = callback;
146 return WEBRTC_VIDEO_CODEC_OK;
147 }
148
149 private:
150 ScalabilityMode scalability_mode_;
151 std::vector<std::vector<Frame>> encoded_frames_;
152 int num_encoded_frames_ = 0;
153 EncodedImageCallback* callback_;
154};
155
156class TestVideoDecoder : public MockVideoDecoder {
157 public:
158 int32_t Decode(const EncodedImage& encoded_frame, int64_t) {
159 uint8_t y = (encoded_frame.size() + 0) & 255;
160 uint8_t u = (encoded_frame.size() + 2) & 255;
161 uint8_t v = (encoded_frame.size() + 4) & 255;
162 rtc::scoped_refptr<I420Buffer> frame_buffer = CreateYuvBuffer(y, u, v);
163 VideoFrame decoded_frame =
164 VideoFrame::Builder()
165 .set_video_frame_buffer(frame_buffer)
Per K0fa90882024-03-13 08:52:41166 .set_rtp_timestamp(encoded_frame.RtpTimestamp())
Sergey Silkin66344ac2023-12-22 08:36:59167 .build();
168 callback_->Decoded(decoded_frame);
Sergey Silkin9e5c9792023-12-22 08:39:56169 frame_sizes_.push_back(DataSize::Bytes(encoded_frame.size()));
Sergey Silkin66344ac2023-12-22 08:36:59170 return WEBRTC_VIDEO_CODEC_OK;
171 }
172
173 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) {
174 callback_ = callback;
175 return WEBRTC_VIDEO_CODEC_OK;
176 }
177
Sergey Silkin9e5c9792023-12-22 08:39:56178 const std::vector<DataSize>& frame_sizes() const { return frame_sizes_; }
179
Sergey Silkin66344ac2023-12-22 08:36:59180 private:
181 DecodedImageCallback* callback_;
Sergey Silkin9e5c9792023-12-22 08:39:56182 std::vector<DataSize> frame_sizes_;
Sergey Silkin66344ac2023-12-22 08:36:59183};
184
185class VideoCodecTesterTest : public ::testing::Test {
186 public:
187 std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
188 std::string codec_type,
189 ScalabilityMode scalability_mode,
Sergey Silkinb792d602024-06-03 14:16:01190 std::vector<std::vector<Frame>> encoded_frames,
191 absl::optional<int> num_source_frames = absl::nullopt) {
Sergey Silkin66344ac2023-12-22 08:36:59192 int num_frames = encoded_frames.size();
Sergey Silkinb792d602024-06-03 14:16:01193 std::string yuv_path =
194 CreateYuvFile(kWidth, kHeight, num_source_frames.value_or(num_frames));
Sergey Silkin66344ac2023-12-22 08:36:59195 VideoSourceSettings video_source_settings{
196 .file_path = yuv_path,
197 .resolution = {.width = kWidth, .height = kHeight},
Sergey Silkin5f3fc502024-05-08 08:37:40198 .framerate = kFramerate};
Sergey Silkin66344ac2023-12-22 08:36:59199
200 NiceMock<MockVideoEncoderFactory> encoder_factory;
Danil Chapovalov329f0ea2024-03-08 13:30:54201 ON_CALL(encoder_factory, Create).WillByDefault(WithoutArgs([&] {
202 return std::make_unique<NiceMock<TestVideoEncoder>>(scalability_mode,
203 encoded_frames);
204 }));
Sergey Silkin66344ac2023-12-22 08:36:59205
206 NiceMock<MockVideoDecoderFactory> decoder_factory;
Danil Chapovalovd213dd52024-01-25 14:48:24207 ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([&] {
208 // Video codec tester destroyes decoder at the end of test. Test
209 // decoder collects stats which we need to access after test. To keep
210 // the decode alive we wrap it into a wrapper and pass the wrapper to
211 // the tester.
212 class DecoderWrapper : public TestVideoDecoder {
213 public:
214 explicit DecoderWrapper(TestVideoDecoder* decoder)
215 : decoder_(decoder) {}
216 int32_t Decode(const EncodedImage& encoded_frame,
217 int64_t render_time_ms) {
218 return decoder_->Decode(encoded_frame, render_time_ms);
219 }
220 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) {
221 return decoder_->RegisterDecodeCompleteCallback(callback);
222 }
223 TestVideoDecoder* decoder_;
224 };
225 decoders_.push_back(std::make_unique<NiceMock<TestVideoDecoder>>());
226 return std::make_unique<NiceMock<DecoderWrapper>>(decoders_.back().get());
227 }));
Sergey Silkin66344ac2023-12-22 08:36:59228
229 int num_spatial_layers =
230 ScalabilityModeToNumSpatialLayers(scalability_mode);
231 int num_temporal_layers =
232 ScalabilityModeToNumTemporalLayers(scalability_mode);
233 std::map<uint32_t, EncodingSettings> encoding_settings;
234 for (int frame_num = 0; frame_num < num_frames; ++frame_num) {
235 std::map<LayerId, LayerSettings> layers_settings;
236 for (int sidx = 0; sidx < num_spatial_layers; ++sidx) {
237 for (int tidx = 0; tidx < num_temporal_layers; ++tidx) {
238 layers_settings.emplace(
239 LayerId{.spatial_idx = sidx, .temporal_idx = tidx},
240 LayerSettings{
241 .resolution = {.width = kWidth, .height = kHeight},
Sergey Silkin5f3fc502024-05-08 08:37:40242 .framerate =
243 kFramerate / (1 << (num_temporal_layers - 1 - tidx)),
244 .bitrate = kBitrate});
Sergey Silkin66344ac2023-12-22 08:36:59245 }
246 }
247 encoding_settings.emplace(
248 encoded_frames[frame_num].front().timestamp_rtp,
249 EncodingSettings{.sdp_video_format = SdpVideoFormat(codec_type),
250 .scalability_mode = scalability_mode,
251 .layers_settings = layers_settings});
252 }
253
254 std::unique_ptr<VideoCodecStats> stats =
255 VideoCodecTester::RunEncodeDecodeTest(
Danil Chapovalovd213dd52024-01-25 14:48:24256 env_, video_source_settings, &encoder_factory, &decoder_factory,
Sergey Silkin66344ac2023-12-22 08:36:59257 EncoderSettings{}, DecoderSettings{}, encoding_settings);
258
259 remove(yuv_path.c_str());
260 return stats;
261 }
Sergey Silkin9e5c9792023-12-22 08:39:56262
263 protected:
Danil Chapovalovd213dd52024-01-25 14:48:24264 const Environment env_ = CreateEnvironment();
Sergey Silkin9e5c9792023-12-22 08:39:56265 std::vector<std::unique_ptr<TestVideoDecoder>> decoders_;
Sergey Silkin66344ac2023-12-22 08:36:59266};
Sergey Silkind4311562023-11-13 14:48:25267
268EncodedImage CreateEncodedImage(uint32_t timestamp_rtp) {
269 EncodedImage encoded_image;
270 encoded_image.SetRtpTimestamp(timestamp_rtp);
271 return encoded_image;
272}
273
274class MockCodedVideoSource : public CodedVideoSource {
275 public:
276 MockCodedVideoSource(int num_frames, Frequency framerate)
277 : num_frames_(num_frames), frame_num_(0), framerate_(framerate) {}
278
279 absl::optional<EncodedImage> PullFrame() override {
280 if (frame_num_ >= num_frames_) {
281 return absl::nullopt;
282 }
283 uint32_t timestamp_rtp = frame_num_ * k90kHz / framerate_;
284 ++frame_num_;
285 return CreateEncodedImage(timestamp_rtp);
286 }
287
288 private:
289 int num_frames_;
290 int frame_num_;
291 Frequency framerate_;
292};
293
294} // namespace
295
Sergey Silkin66344ac2023-12-22 08:36:59296TEST_F(VideoCodecTesterTest, Slice) {
297 std::unique_ptr<VideoCodecStats> stats =
Sergey Silkin0a01ffc2023-12-22 08:40:56298 RunEncodeDecodeTest("VP9", ScalabilityMode::kL2T2,
Sergey Silkin66344ac2023-12-22 08:36:59299 {{{.timestamp_rtp = 0,
300 .layer_id = {.spatial_idx = 0, .temporal_idx = 0},
301 .frame_size = DataSize::Bytes(1)},
302 {.timestamp_rtp = 0,
303 .layer_id = {.spatial_idx = 1, .temporal_idx = 0},
304 .frame_size = DataSize::Bytes(2)}},
305 {{.timestamp_rtp = 1,
306 .layer_id = {.spatial_idx = 0, .temporal_idx = 1},
307 .frame_size = DataSize::Bytes(3)}}});
Sergey Silkind4311562023-11-13 14:48:25308 std::vector<Frame> slice = stats->Slice(Filter{}, /*merge=*/false);
Sergey Silkin66344ac2023-12-22 08:36:59309 EXPECT_THAT(slice,
310 ElementsAre(Field(&Frame::frame_size, DataSize::Bytes(1)),
311 Field(&Frame::frame_size, DataSize::Bytes(2)),
Sergey Silkin0a01ffc2023-12-22 08:40:56312 Field(&Frame::frame_size, DataSize::Bytes(3)),
313 Field(&Frame::frame_size, DataSize::Bytes(0))));
Sergey Silkind4311562023-11-13 14:48:25314
315 slice = stats->Slice({.min_timestamp_rtp = 1}, /*merge=*/false);
Sergey Silkin66344ac2023-12-22 08:36:59316 EXPECT_THAT(slice,
Sergey Silkin0a01ffc2023-12-22 08:40:56317 ElementsAre(Field(&Frame::frame_size, DataSize::Bytes(3)),
318 Field(&Frame::frame_size, DataSize::Bytes(0))));
Sergey Silkind4311562023-11-13 14:48:25319
320 slice = stats->Slice({.max_timestamp_rtp = 0}, /*merge=*/false);
Sergey Silkin66344ac2023-12-22 08:36:59321 EXPECT_THAT(slice,
322 ElementsAre(Field(&Frame::frame_size, DataSize::Bytes(1)),
323 Field(&Frame::frame_size, DataSize::Bytes(2))));
Sergey Silkind4311562023-11-13 14:48:25324
325 slice = stats->Slice({.layer_id = {{.spatial_idx = 0, .temporal_idx = 0}}},
326 /*merge=*/false);
Sergey Silkin66344ac2023-12-22 08:36:59327 EXPECT_THAT(slice,
328 ElementsAre(Field(&Frame::frame_size, DataSize::Bytes(1))));
Sergey Silkind4311562023-11-13 14:48:25329
330 slice = stats->Slice({.layer_id = {{.spatial_idx = 0, .temporal_idx = 1}}},
331 /*merge=*/false);
Sergey Silkin66344ac2023-12-22 08:36:59332 EXPECT_THAT(slice,
333 ElementsAre(Field(&Frame::frame_size, DataSize::Bytes(1)),
334 Field(&Frame::frame_size, DataSize::Bytes(3))));
Sergey Silkind4311562023-11-13 14:48:25335}
336
Sergey Silkin66344ac2023-12-22 08:36:59337TEST_F(VideoCodecTesterTest, Merge) {
Sergey Silkind4311562023-11-13 14:48:25338 std::unique_ptr<VideoCodecStats> stats =
Sergey Silkin66344ac2023-12-22 08:36:59339 RunEncodeDecodeTest("VP8", ScalabilityMode::kL2T2_KEY,
340 {{{.timestamp_rtp = 0,
341 .layer_id = {.spatial_idx = 0, .temporal_idx = 0},
342 .frame_size = DataSize::Bytes(1),
343 .keyframe = true},
344 {.timestamp_rtp = 0,
345 .layer_id = {.spatial_idx = 1, .temporal_idx = 0},
346 .frame_size = DataSize::Bytes(2)}},
347 {{.timestamp_rtp = 1,
348 .layer_id = {.spatial_idx = 0, .temporal_idx = 1},
349 .frame_size = DataSize::Bytes(4)},
350 {.timestamp_rtp = 1,
351 .layer_id = {.spatial_idx = 1, .temporal_idx = 1},
352 .frame_size = DataSize::Bytes(8)}}});
Sergey Silkind4311562023-11-13 14:48:25353
354 std::vector<Frame> slice = stats->Slice(Filter{}, /*merge=*/true);
355 EXPECT_THAT(
356 slice,
357 ElementsAre(
358 AllOf(Field(&Frame::timestamp_rtp, 0), Field(&Frame::keyframe, true),
359 Field(&Frame::frame_size, DataSize::Bytes(3))),
360 AllOf(Field(&Frame::timestamp_rtp, 1), Field(&Frame::keyframe, false),
361 Field(&Frame::frame_size, DataSize::Bytes(12)))));
362}
363
364struct AggregationTestParameters {
365 Filter filter;
366 double expected_keyframe_sum;
367 double expected_encoded_bitrate_kbps;
368 double expected_encoded_framerate_fps;
369 double expected_bitrate_mismatch_pct;
370 double expected_framerate_mismatch_pct;
371};
372
373class VideoCodecTesterTestAggregation
Sergey Silkin66344ac2023-12-22 08:36:59374 : public VideoCodecTesterTest,
375 public ::testing::WithParamInterface<AggregationTestParameters> {};
Sergey Silkind4311562023-11-13 14:48:25376
377TEST_P(VideoCodecTesterTestAggregation, Aggregate) {
378 AggregationTestParameters test_params = GetParam();
379 std::unique_ptr<VideoCodecStats> stats =
Sergey Silkin66344ac2023-12-22 08:36:59380 RunEncodeDecodeTest("VP8", ScalabilityMode::kL2T2_KEY,
381 {{// L0T0
382 {.timestamp_rtp = 0,
383 .layer_id = {.spatial_idx = 0, .temporal_idx = 0},
384 .frame_size = DataSize::Bytes(1),
385 .keyframe = true},
386 // L1T0
387 {.timestamp_rtp = 0,
388 .layer_id = {.spatial_idx = 1, .temporal_idx = 0},
389 .frame_size = DataSize::Bytes(2)}},
390 // Emulate frame drop (frame_size = 0).
391 {{.timestamp_rtp = 3000,
392 .layer_id = {.spatial_idx = 0, .temporal_idx = 0},
393 .frame_size = DataSize::Zero()}},
394 {// L0T1
395 {.timestamp_rtp = 87000,
396 .layer_id = {.spatial_idx = 0, .temporal_idx = 1},
397 .frame_size = DataSize::Bytes(4)},
398 // L1T1
399 {.timestamp_rtp = 87000,
400 .layer_id = {.spatial_idx = 1, .temporal_idx = 1},
401 .frame_size = DataSize::Bytes(8)}}});
Sergey Silkind4311562023-11-13 14:48:25402
403 Stream stream = stats->Aggregate(test_params.filter);
404 EXPECT_EQ(stream.keyframe.GetSum(), test_params.expected_keyframe_sum);
405 EXPECT_EQ(stream.encoded_bitrate_kbps.GetAverage(),
406 test_params.expected_encoded_bitrate_kbps);
407 EXPECT_EQ(stream.encoded_framerate_fps.GetAverage(),
408 test_params.expected_encoded_framerate_fps);
409 EXPECT_EQ(stream.bitrate_mismatch_pct.GetAverage(),
410 test_params.expected_bitrate_mismatch_pct);
411 EXPECT_EQ(stream.framerate_mismatch_pct.GetAverage(),
412 test_params.expected_framerate_mismatch_pct);
413}
414
415INSTANTIATE_TEST_SUITE_P(
416 All,
417 VideoCodecTesterTestAggregation,
Sergey Silkin66344ac2023-12-22 08:36:59418 Values(
Sergey Silkind4311562023-11-13 14:48:25419 // No filtering.
420 AggregationTestParameters{
421 .filter = {},
422 .expected_keyframe_sum = 1,
423 .expected_encoded_bitrate_kbps =
424 DataRate::BytesPerSec(15).kbps<double>(),
425 .expected_encoded_framerate_fps = 2,
426 .expected_bitrate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40427 100 * (15.0 / (kBitrate.bytes_per_sec() * 4) - 1),
428 .expected_framerate_mismatch_pct = 100 *
429 (2.0 / kFramerate.hertz() - 1)},
Sergey Silkind4311562023-11-13 14:48:25430 // L0T0
431 AggregationTestParameters{
432 .filter = {.layer_id = {{.spatial_idx = 0, .temporal_idx = 0}}},
433 .expected_keyframe_sum = 1,
434 .expected_encoded_bitrate_kbps =
435 DataRate::BytesPerSec(1).kbps<double>(),
436 .expected_encoded_framerate_fps = 1,
437 .expected_bitrate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40438 100 * (1.0 / kBitrate.bytes_per_sec() - 1),
Sergey Silkind4311562023-11-13 14:48:25439 .expected_framerate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40440 100 * (1.0 / (kFramerate.hertz() / 2) - 1)},
Sergey Silkind4311562023-11-13 14:48:25441 // L0T1
442 AggregationTestParameters{
443 .filter = {.layer_id = {{.spatial_idx = 0, .temporal_idx = 1}}},
444 .expected_keyframe_sum = 1,
445 .expected_encoded_bitrate_kbps =
446 DataRate::BytesPerSec(5).kbps<double>(),
447 .expected_encoded_framerate_fps = 2,
448 .expected_bitrate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40449 100 * (5.0 / (kBitrate.bytes_per_sec() * 2) - 1),
450 .expected_framerate_mismatch_pct = 100 *
451 (2.0 / kFramerate.hertz() - 1)},
Sergey Silkind4311562023-11-13 14:48:25452 // L1T0
453 AggregationTestParameters{
454 .filter = {.layer_id = {{.spatial_idx = 1, .temporal_idx = 0}}},
455 .expected_keyframe_sum = 1,
456 .expected_encoded_bitrate_kbps =
457 DataRate::BytesPerSec(3).kbps<double>(),
458 .expected_encoded_framerate_fps = 1,
459 .expected_bitrate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40460 100 * (3.0 / kBitrate.bytes_per_sec() - 1),
Sergey Silkind4311562023-11-13 14:48:25461 .expected_framerate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40462 100 * (1.0 / (kFramerate.hertz() / 2) - 1)},
Sergey Silkind4311562023-11-13 14:48:25463 // L1T1
464 AggregationTestParameters{
465 .filter = {.layer_id = {{.spatial_idx = 1, .temporal_idx = 1}}},
466 .expected_keyframe_sum = 1,
467 .expected_encoded_bitrate_kbps =
468 DataRate::BytesPerSec(11).kbps<double>(),
469 .expected_encoded_framerate_fps = 2,
470 .expected_bitrate_mismatch_pct =
Sergey Silkin5f3fc502024-05-08 08:37:40471 100 * (11.0 / (kBitrate.bytes_per_sec() * 2) - 1),
472 .expected_framerate_mismatch_pct = 100 * (2.0 / kFramerate.hertz() -
473 1)}));
Sergey Silkind4311562023-11-13 14:48:25474
Sergey Silkin66344ac2023-12-22 08:36:59475TEST_F(VideoCodecTesterTest, Psnr) {
476 std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
477 "VP8", ScalabilityMode::kL1T1,
478 {{{.timestamp_rtp = 0, .frame_size = DataSize::Bytes(2)}},
479 {{.timestamp_rtp = 3000, .frame_size = DataSize::Bytes(6)}}});
Sergey Silkind4311562023-11-13 14:48:25480
481 std::vector<Frame> slice = stats->Slice(Filter{}, /*merge=*/false);
482 ASSERT_THAT(slice, SizeIs(2));
483 ASSERT_TRUE(slice[0].psnr.has_value());
484 ASSERT_TRUE(slice[1].psnr.has_value());
485 EXPECT_NEAR(slice[0].psnr->y, 42, 1);
486 EXPECT_NEAR(slice[0].psnr->u, 38, 1);
487 EXPECT_NEAR(slice[0].psnr->v, 36, 1);
488 EXPECT_NEAR(slice[1].psnr->y, 38, 1);
489 EXPECT_NEAR(slice[1].psnr->u, 36, 1);
490 EXPECT_NEAR(slice[1].psnr->v, 34, 1);
491}
492
Sergey Silkinb792d602024-06-03 14:16:01493TEST_F(VideoCodecTesterTest, ReversePlayback) {
494 std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
495 "VP8", ScalabilityMode::kL1T1,
496 {{{.timestamp_rtp = 0, .frame_size = DataSize::Bytes(1)}},
497 {{.timestamp_rtp = 1, .frame_size = DataSize::Bytes(1)}},
498 {{.timestamp_rtp = 2, .frame_size = DataSize::Bytes(1)}},
499 {{.timestamp_rtp = 3, .frame_size = DataSize::Bytes(1)}},
500 {{.timestamp_rtp = 4, .frame_size = DataSize::Bytes(1)}},
501 {{.timestamp_rtp = 5, .frame_size = DataSize::Bytes(1)}}},
502 /*num_source_frames=*/3);
503
504 std::vector<Frame> slice = stats->Slice(Filter{}, /*merge=*/false);
505 ASSERT_THAT(slice, SizeIs(6));
506 ASSERT_TRUE(slice[0].psnr.has_value());
507 ASSERT_TRUE(slice[1].psnr.has_value());
508 ASSERT_TRUE(slice[2].psnr.has_value());
509 ASSERT_TRUE(slice[3].psnr.has_value());
510 ASSERT_TRUE(slice[4].psnr.has_value());
511 ASSERT_TRUE(slice[5].psnr.has_value());
512 EXPECT_NEAR(slice[0].psnr->y, 48, 1);
513 EXPECT_NEAR(slice[1].psnr->y, 42, 1);
514 EXPECT_NEAR(slice[2].psnr->y, 34, 1);
515 EXPECT_NEAR(slice[3].psnr->y, 42, 1);
516 EXPECT_NEAR(slice[4].psnr->y, 48, 1);
517 EXPECT_NEAR(slice[5].psnr->y, 42, 1);
518}
519
Sergey Silkin9e5c9792023-12-22 08:39:56520struct ScalabilityTestParameters {
521 std::string codec_type;
522 ScalabilityMode scalability_mode;
523 // Temporal unit -> spatial layer -> frame size.
524 std::vector<std::map<int, DataSize>> encoded_frame_sizes;
525 std::vector<DataSize> expected_decode_frame_sizes;
526};
527
528class VideoCodecTesterTestScalability
529 : public VideoCodecTesterTest,
530 public ::testing::WithParamInterface<ScalabilityTestParameters> {};
531
532TEST_P(VideoCodecTesterTestScalability, EncodeDecode) {
533 ScalabilityTestParameters test_params = GetParam();
534 std::vector<std::vector<Frame>> frames;
535 for (size_t frame_num = 0; frame_num < test_params.encoded_frame_sizes.size();
536 ++frame_num) {
537 std::vector<Frame> temporal_unit;
538 for (auto [sidx, frame_size] : test_params.encoded_frame_sizes[frame_num]) {
539 temporal_unit.push_back(
540 Frame{.timestamp_rtp = static_cast<uint32_t>(3000 * frame_num),
541 .layer_id = {.spatial_idx = sidx, .temporal_idx = 0},
542 .frame_size = frame_size,
543 .keyframe = (frame_num == 0 && sidx == 0)});
544 }
545 frames.push_back(temporal_unit);
546 }
547 RunEncodeDecodeTest(test_params.codec_type, test_params.scalability_mode,
548 frames);
549
550 size_t num_spatial_layers =
551 ScalabilityModeToNumSpatialLayers(test_params.scalability_mode);
552 EXPECT_EQ(num_spatial_layers, decoders_.size());
553
554 // Collect input frame sizes from all decoders.
555 std::vector<DataSize> decode_frame_sizes;
556 for (const auto& decoder : decoders_) {
557 const auto& frame_sizes = decoder->frame_sizes();
558 decode_frame_sizes.insert(decode_frame_sizes.end(), frame_sizes.begin(),
559 frame_sizes.end());
560 }
561 EXPECT_THAT(decode_frame_sizes, UnorderedElementsAreArray(
562 test_params.expected_decode_frame_sizes));
563}
564
565INSTANTIATE_TEST_SUITE_P(
566 All,
567 VideoCodecTesterTestScalability,
Sergey Silkin0a01ffc2023-12-22 08:40:56568 Values(
569 ScalabilityTestParameters{
570 .codec_type = "VP8",
571 .scalability_mode = ScalabilityMode::kS2T1,
572 .encoded_frame_sizes = {{{0, DataSize::Bytes(1)},
573 {1, DataSize::Bytes(2)}},
574 {{0, DataSize::Bytes(4)},
575 // Emulate frame drop.
576 {1, DataSize::Bytes(0)}}},
577 .expected_decode_frame_sizes = {DataSize::Bytes(1),
578 DataSize::Bytes(2),
579 DataSize::Bytes(4)},
580 },
581 ScalabilityTestParameters{
582 .codec_type = "VP9",
583 .scalability_mode = ScalabilityMode::kL2T1,
584 .encoded_frame_sizes =
585 {{{0, DataSize::Bytes(1)}, {1, DataSize::Bytes(2)}},
586 {{0, DataSize::Bytes(4)}, {1, DataSize::Bytes(8)}},
587 {{0, DataSize::Bytes(16)},
588 // Emulate frame drop.
589 {1, DataSize::Bytes(0)}}},
590 .expected_decode_frame_sizes =
591 {DataSize::Bytes(1), DataSize::Bytes(3), DataSize::Bytes(4),
592 DataSize::Bytes(12), DataSize::Bytes(16), DataSize::Bytes(16)},
593 },
594 ScalabilityTestParameters{
595 .codec_type = "VP9",
596 .scalability_mode = ScalabilityMode::kL2T1_KEY,
597 .encoded_frame_sizes =
598 {{{0, DataSize::Bytes(1)}, {1, DataSize::Bytes(2)}},
599 {{0, DataSize::Bytes(4)}, {1, DataSize::Bytes(8)}},
600 {{0, DataSize::Bytes(16)},
601 // Emulate frame drop.
602 {1, DataSize::Bytes(0)}}},
603 .expected_decode_frame_sizes =
604 {DataSize::Bytes(1), DataSize::Bytes(3), DataSize::Bytes(4),
605 DataSize::Bytes(8), DataSize::Bytes(16)},
606 },
607 ScalabilityTestParameters{
608 .codec_type = "VP9",
609 .scalability_mode = ScalabilityMode::kS2T1,
610 .encoded_frame_sizes =
611 {{{0, DataSize::Bytes(1)}, {1, DataSize::Bytes(2)}},
612 {{0, DataSize::Bytes(4)}, {1, DataSize::Bytes(8)}},
613 {{0, DataSize::Bytes(16)},
614 // Emulate frame drop.
615 {1, DataSize::Bytes(0)}}},
616 .expected_decode_frame_sizes =
617 {DataSize::Bytes(1), DataSize::Bytes(2), DataSize::Bytes(4),
618 DataSize::Bytes(8), DataSize::Bytes(16)},
619 }));
Sergey Silkin9e5c9792023-12-22 08:39:56620
Sergey Silkind4311562023-11-13 14:48:25621class VideoCodecTesterTestPacing
622 : public ::testing::TestWithParam<std::tuple<PacingSettings, int>> {
623 public:
624 const int kSourceWidth = 2;
625 const int kSourceHeight = 2;
626 const int kNumFrames = 3;
Sergey Silkin5f3fc502024-05-08 08:37:40627 const Frequency kFramerate = Frequency::Hertz(10);
Sergey Silkind4311562023-11-13 14:48:25628
629 void SetUp() override {
Sergey Silkin66344ac2023-12-22 08:36:59630 source_yuv_file_path_ = CreateYuvFile(kSourceWidth, kSourceHeight, 1);
Sergey Silkind4311562023-11-13 14:48:25631 }
632
Sergey Silkin66344ac2023-12-22 08:36:59633 void TearDown() override { remove(source_yuv_file_path_.c_str()); }
634
Sergey Silkind4311562023-11-13 14:48:25635 protected:
Danil Chapovalovd213dd52024-01-25 14:48:24636 const Environment env_ = CreateEnvironment();
Sergey Silkind4311562023-11-13 14:48:25637 std::string source_yuv_file_path_;
638};
639
640TEST_P(VideoCodecTesterTestPacing, PaceEncode) {
641 auto [pacing_settings, expected_delta_ms] = GetParam();
Danil Chapovalov329f0ea2024-03-08 13:30:54642 const Environment env = CreateEnvironment();
Sergey Silkind4311562023-11-13 14:48:25643 VideoSourceSettings video_source{
644 .file_path = source_yuv_file_path_,
645 .resolution = {.width = kSourceWidth, .height = kSourceHeight},
Sergey Silkin5f3fc502024-05-08 08:37:40646 .framerate = kFramerate};
Sergey Silkind4311562023-11-13 14:48:25647
648 NiceMock<MockVideoEncoderFactory> encoder_factory;
Danil Chapovalov329f0ea2024-03-08 13:30:54649 ON_CALL(encoder_factory, Create).WillByDefault(WithoutArgs([] {
650 return std::make_unique<NiceMock<MockVideoEncoder>>();
651 }));
Sergey Silkind4311562023-11-13 14:48:25652
Sergey Silkin5f3fc502024-05-08 08:37:40653 EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
Danil Chapovalov179f96d2024-05-13 14:33:07654 env, "VP8", "L1T1", kSourceWidth, kSourceHeight, {kBitrate}, kFramerate);
Sergey Silkin5f3fc502024-05-08 08:37:40655 std::map<uint32_t, EncodingSettings> frame_settings =
656 VideoCodecTester::CreateFrameSettings(encoding_settings, kNumFrames);
Sergey Silkind4311562023-11-13 14:48:25657
658 EncoderSettings encoder_settings;
659 encoder_settings.pacing_settings = pacing_settings;
660 std::vector<Frame> frames =
Danil Chapovalov329f0ea2024-03-08 13:30:54661 VideoCodecTester::RunEncodeTest(env, video_source, &encoder_factory,
Sergey Silkin5f3fc502024-05-08 08:37:40662 encoder_settings, frame_settings)
Sergey Silkind4311562023-11-13 14:48:25663 ->Slice(/*filter=*/{}, /*merge=*/false);
664 ASSERT_THAT(frames, SizeIs(kNumFrames));
665 EXPECT_NEAR((frames[1].encode_start - frames[0].encode_start).ms(),
666 expected_delta_ms, 10);
667 EXPECT_NEAR((frames[2].encode_start - frames[1].encode_start).ms(),
668 expected_delta_ms, 10);
669}
670
671TEST_P(VideoCodecTesterTestPacing, PaceDecode) {
672 auto [pacing_settings, expected_delta_ms] = GetParam();
Sergey Silkin5f3fc502024-05-08 08:37:40673 MockCodedVideoSource video_source(kNumFrames, kFramerate);
Sergey Silkind4311562023-11-13 14:48:25674
675 NiceMock<MockVideoDecoderFactory> decoder_factory;
Danil Chapovalovd213dd52024-01-25 14:48:24676 ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([] {
677 return std::make_unique<NiceMock<MockVideoDecoder>>();
678 }));
Sergey Silkind4311562023-11-13 14:48:25679
680 DecoderSettings decoder_settings;
681 decoder_settings.pacing_settings = pacing_settings;
682 std::vector<Frame> frames =
Danil Chapovalovd213dd52024-01-25 14:48:24683 VideoCodecTester::RunDecodeTest(env_, &video_source, &decoder_factory,
Philipp Hanckebbff58d2024-02-27 11:18:33684 decoder_settings, SdpVideoFormat::VP8())
Sergey Silkind4311562023-11-13 14:48:25685 ->Slice(/*filter=*/{}, /*merge=*/false);
686 ASSERT_THAT(frames, SizeIs(kNumFrames));
687 EXPECT_NEAR((frames[1].decode_start - frames[0].decode_start).ms(),
688 expected_delta_ms, 10);
689 EXPECT_NEAR((frames[2].decode_start - frames[1].decode_start).ms(),
690 expected_delta_ms, 10);
691}
692
693INSTANTIATE_TEST_SUITE_P(
694 DISABLED_All,
695 VideoCodecTesterTestPacing,
Sergey Silkin66344ac2023-12-22 08:36:59696 Values(
Sergey Silkind4311562023-11-13 14:48:25697 // No pacing.
698 std::make_tuple(PacingSettings{.mode = PacingMode::kNoPacing},
699 /*expected_delta_ms=*/0),
700 // Real-time pacing.
701 std::make_tuple(PacingSettings{.mode = PacingMode::kRealTime},
702 /*expected_delta_ms=*/100),
703 // Pace with specified constant rate.
704 std::make_tuple(PacingSettings{.mode = PacingMode::kConstantRate,
705 .constant_rate = Frequency::Hertz(20)},
706 /*expected_delta_ms=*/50)));
Sergey Silkin64329702024-02-06 14:44:02707
708struct EncodingSettingsTestParameters {
709 std::string codec_type;
710 std::string scalability_mode;
Sergey Silkin5f3fc502024-05-08 08:37:40711 std::vector<DataRate> bitrate;
712 std::vector<DataRate> expected_bitrate;
Sergey Silkin64329702024-02-06 14:44:02713};
714
715class VideoCodecTesterTestEncodingSettings
716 : public ::testing::TestWithParam<EncodingSettingsTestParameters> {};
717
718TEST_P(VideoCodecTesterTestEncodingSettings, CreateEncodingSettings) {
719 EncodingSettingsTestParameters test_params = GetParam();
Sergey Silkin5f3fc502024-05-08 08:37:40720 EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
Danil Chapovalov179f96d2024-05-13 14:33:07721 CreateEnvironment(), test_params.codec_type, test_params.scalability_mode,
722 /*width=*/1280,
Sergey Silkin5f3fc502024-05-08 08:37:40723 /*height=*/720, test_params.bitrate, kFramerate);
Sergey Silkin64329702024-02-06 14:44:02724 const std::map<LayerId, LayerSettings>& layers_settings =
Sergey Silkin5f3fc502024-05-08 08:37:40725 encoding_settings.layers_settings;
726 std::vector<DataRate> configured_bitrate;
727 std::transform(
728 layers_settings.begin(), layers_settings.end(),
729 std::back_inserter(configured_bitrate),
730 [](const auto& layer_settings) { return layer_settings.second.bitrate; });
731 EXPECT_EQ(configured_bitrate, test_params.expected_bitrate);
Sergey Silkin64329702024-02-06 14:44:02732}
733
734INSTANTIATE_TEST_SUITE_P(
735 Vp8,
736 VideoCodecTesterTestEncodingSettings,
Sergey Silkin5f3fc502024-05-08 08:37:40737 Values(
738 EncodingSettingsTestParameters{
739 .codec_type = "VP8",
740 .scalability_mode = "L1T1",
741 .bitrate = {DataRate::KilobitsPerSec(1)},
742 .expected_bitrate = {DataRate::KilobitsPerSec(1)}},
743 EncodingSettingsTestParameters{
744 .codec_type = "VP8",
745 .scalability_mode = "L1T1",
746 .bitrate = {DataRate::KilobitsPerSec(10000)},
747 .expected_bitrate = {DataRate::KilobitsPerSec(10000)}},
748 EncodingSettingsTestParameters{
749 .codec_type = "VP8",
750 .scalability_mode = "L1T3",
751 .bitrate = {DataRate::KilobitsPerSec(1000)},
752 .expected_bitrate = {DataRate::KilobitsPerSec(400),
753 DataRate::KilobitsPerSec(200),
754 DataRate::KilobitsPerSec(400)}},
755 EncodingSettingsTestParameters{
756 .codec_type = "VP8",
757 .scalability_mode = "S3T3",
758 .bitrate = {DataRate::KilobitsPerSec(100)},
759 .expected_bitrate =
760 {DataRate::KilobitsPerSec(40), DataRate::KilobitsPerSec(20),
761 DataRate::KilobitsPerSec(40), DataRate::KilobitsPerSec(0),
762 DataRate::KilobitsPerSec(0), DataRate::KilobitsPerSec(0),
763 DataRate::KilobitsPerSec(0), DataRate::KilobitsPerSec(0),
764 DataRate::KilobitsPerSec(0)}},
765 EncodingSettingsTestParameters{
766 .codec_type = "VP8",
767 .scalability_mode = "S3T3",
768 .bitrate = {DataRate::KilobitsPerSec(10000)},
769 .expected_bitrate =
770 {DataRate::KilobitsPerSec(60), DataRate::KilobitsPerSec(30),
771 DataRate::KilobitsPerSec(60), DataRate::KilobitsPerSec(200),
772 DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
773 DataRate::KilobitsPerSec(1000), DataRate::KilobitsPerSec(500),
774 DataRate::KilobitsPerSec(1000)}},
775 EncodingSettingsTestParameters{
776 .codec_type = "VP8",
777 .scalability_mode = "S3T3",
778 .bitrate =
779 {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
780 DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400),
781 DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600),
782 DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800),
783 DataRate::KilobitsPerSec(900)},
784 .expected_bitrate = {
785 DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
786 DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400),
787 DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600),
788 DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800),
789 DataRate::KilobitsPerSec(900)}}));
Sergey Silkin64329702024-02-06 14:44:02790
791INSTANTIATE_TEST_SUITE_P(
792 Vp9,
793 VideoCodecTesterTestEncodingSettings,
Sergey Silkin5f3fc502024-05-08 08:37:40794 Values(
795 EncodingSettingsTestParameters{
796 .codec_type = "VP9",
797 .scalability_mode = "L1T1",
798 .bitrate = {DataRate::KilobitsPerSec(1)},
799 .expected_bitrate = {DataRate::KilobitsPerSec(1)}},
800 EncodingSettingsTestParameters{
801 .codec_type = "VP9",
802 .scalability_mode = "L1T1",
803 .bitrate = {DataRate::KilobitsPerSec(10000)},
804 .expected_bitrate = {DataRate::KilobitsPerSec(10000)}},
805 EncodingSettingsTestParameters{
806 .codec_type = "VP9",
807 .scalability_mode = "L1T3",
808 .bitrate = {DataRate::KilobitsPerSec(1000)},
809 .expected_bitrate = {DataRate::BitsPerSec(539811),
810 DataRate::BitsPerSec(163293),
811 DataRate::BitsPerSec(296896)}},
812 EncodingSettingsTestParameters{
813 .codec_type = "VP9",
814 .scalability_mode = "L3T3",
815 .bitrate = {DataRate::KilobitsPerSec(100)},
816 .expected_bitrate =
817 {DataRate::BitsPerSec(53981), DataRate::BitsPerSec(16329),
818 DataRate::BitsPerSec(29690), DataRate::BitsPerSec(0),
819 DataRate::BitsPerSec(0), DataRate::BitsPerSec(0),
820 DataRate::BitsPerSec(0), DataRate::BitsPerSec(0),
821 DataRate::BitsPerSec(0)}},
822 EncodingSettingsTestParameters{
823 .codec_type = "VP9",
824 .scalability_mode = "L3T3",
825 .bitrate = {DataRate::KilobitsPerSec(10000)},
826 .expected_bitrate =
827 {DataRate::BitsPerSec(76653), DataRate::BitsPerSec(23188),
828 DataRate::BitsPerSec(42159), DataRate::BitsPerSec(225641),
829 DataRate::BitsPerSec(68256), DataRate::BitsPerSec(124103),
830 DataRate::BitsPerSec(822672), DataRate::BitsPerSec(248858),
831 DataRate::BitsPerSec(452470)}},
832 EncodingSettingsTestParameters{
833 .codec_type = "VP9",
834 .scalability_mode = "L3T3",
835 .bitrate =
836 {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
837 DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400),
838 DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600),
839 DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800),
840 DataRate::KilobitsPerSec(900)},
841 .expected_bitrate = {
842 DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
843 DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400),
844 DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600),
845 DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800),
846 DataRate::KilobitsPerSec(900)}}));
Sergey Silkin64329702024-02-06 14:44:02847
848INSTANTIATE_TEST_SUITE_P(
849 Av1,
850 VideoCodecTesterTestEncodingSettings,
Sergey Silkin5f3fc502024-05-08 08:37:40851 Values(
852 EncodingSettingsTestParameters{
853 .codec_type = "AV1",
854 .scalability_mode = "L1T1",
855 .bitrate = {DataRate::KilobitsPerSec(1)},
856 .expected_bitrate = {DataRate::KilobitsPerSec(1)}},
857 EncodingSettingsTestParameters{
858 .codec_type = "AV1",
859 .scalability_mode = "L1T1",
860 .bitrate = {DataRate::KilobitsPerSec(10000)},
861 .expected_bitrate = {DataRate::KilobitsPerSec(10000)}},
862 EncodingSettingsTestParameters{
863 .codec_type = "AV1",
864 .scalability_mode = "L1T3",
865 .bitrate = {DataRate::KilobitsPerSec(1000)},
866 .expected_bitrate = {DataRate::BitsPerSec(539811),
867 DataRate::BitsPerSec(163293),
868 DataRate::BitsPerSec(296896)}},
869 EncodingSettingsTestParameters{
870 .codec_type = "AV1",
871 .scalability_mode = "L3T3",
872 .bitrate = {DataRate::KilobitsPerSec(100)},
873 .expected_bitrate =
874 {DataRate::BitsPerSec(53981), DataRate::BitsPerSec(16329),
875 DataRate::BitsPerSec(29690), DataRate::BitsPerSec(0),
876 DataRate::BitsPerSec(0), DataRate::BitsPerSec(0),
877 DataRate::BitsPerSec(0), DataRate::BitsPerSec(0),
878 DataRate::BitsPerSec(0)}},
879 EncodingSettingsTestParameters{
880 .codec_type = "AV1",
881 .scalability_mode = "L3T3",
882 .bitrate = {DataRate::KilobitsPerSec(10000)},
883 .expected_bitrate =
884 {DataRate::BitsPerSec(76653), DataRate::BitsPerSec(23188),
885 DataRate::BitsPerSec(42159), DataRate::BitsPerSec(225641),
886 DataRate::BitsPerSec(68256), DataRate::BitsPerSec(124103),
887 DataRate::BitsPerSec(822672), DataRate::BitsPerSec(248858),
888 DataRate::BitsPerSec(452470)}},
889 EncodingSettingsTestParameters{
890 .codec_type = "AV1",
891 .scalability_mode = "L3T3",
892 .bitrate =
893 {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
894 DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400),
895 DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600),
896 DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800),
897 DataRate::KilobitsPerSec(900)},
898 .expected_bitrate = {
899 DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200),
900 DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400),
901 DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600),
902 DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800),
903 DataRate::KilobitsPerSec(900)}}));
Sergey Silkin64329702024-02-06 14:44:02904
Sergey Silkinb792d602024-06-03 14:16:01905// TODO(webrtc:42225151): Add an IVF test stream and enable the test.
906TEST(VideoCodecTester, DISABLED_CompressedVideoSource) {
907 const Environment env = CreateEnvironment();
908 std::unique_ptr<VideoEncoderFactory> encoder_factory =
909 CreateBuiltinVideoEncoderFactory();
910 std::unique_ptr<VideoDecoderFactory> decoder_factory =
911 CreateBuiltinVideoDecoderFactory();
912
913 VideoSourceSettings source_settings{
914 .file_path = ".ivf",
915 .resolution = {.width = 320, .height = 180},
916 .framerate = Frequency::Hertz(30)};
917
918 EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings(
919 env, "AV1", "L1T1", 320, 180, {DataRate::KilobitsPerSec(128)},
920 Frequency::Hertz(30));
921
922 std::map<uint32_t, EncodingSettings> frame_settings =
923 VideoCodecTester::CreateFrameSettings(encoding_settings, 3);
924
925 std::unique_ptr<VideoCodecStats> stats =
926 VideoCodecTester::RunEncodeDecodeTest(
927 env, source_settings, encoder_factory.get(), decoder_factory.get(),
928 EncoderSettings{}, DecoderSettings{}, frame_settings);
929
930 std::vector<Frame> slice = stats->Slice(Filter{}, /*merge=*/false);
931 ASSERT_THAT(slice, SizeIs(3));
932 ASSERT_TRUE(slice[0].psnr.has_value());
933 ASSERT_TRUE(slice[1].psnr.has_value());
934 ASSERT_TRUE(slice[2].psnr.has_value());
935 EXPECT_NEAR(slice[0].psnr->y, 42, 1);
936 EXPECT_NEAR(slice[1].psnr->y, 38, 1);
937 EXPECT_NEAR(slice[1].psnr->v, 38, 1);
938}
939
Sergey Silkind4311562023-11-13 14:48:25940} // namespace test
941} // namespace webrtc