diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc index 73d7df61d1..67522b6434 100644 --- a/modules/video_coding/codecs/test/video_codec_test.cc +++ b/modules/video_coding/codecs/test/video_codec_test.cc @@ -60,9 +60,9 @@ ABSL_FLAG(std::vector, {"1024"}, "Encode target bitrate per layer (l0t0,l0t1,...l1t0,l1t1 and so on) " "in kbps."); -ABSL_FLAG(double, +ABSL_FLAG(absl::optional, framerate_fps, - 30.0, + absl::nullopt, "Encode target frame rate of the top temporal layer in fps."); ABSL_FLAG(bool, screencast, false, "Enable screen encoding mode."); ABSL_FLAG(bool, frame_drop, true, "Enable frame dropping."); @@ -314,13 +314,16 @@ TEST_P(SpatialQualityTest, SpatialQuality) { VideoSourceSettings source_settings = ToSourceSettings(video_info); - std::map frames_settings = - VideoCodecTester::CreateEncodingSettings( - codec_type, /*scalability_mode=*/"L1T1", width, height, - {bitrate_kbps}, framerate_fps, num_frames); + EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings( + codec_type, /*scalability_mode=*/"L1T1", width, height, + {DataRate::KilobitsPerSec(bitrate_kbps)}, + Frequency::Hertz(framerate_fps)); + + std::map frame_settings = + VideoCodecTester::CreateFrameSettings(encoding_settings, num_frames); std::unique_ptr stats = RunEncodeDecodeTest( - env, codec_impl, codec_impl, source_settings, frames_settings); + env, codec_impl, codec_impl, source_settings, frame_settings); VideoCodecStats::Stream stream; if (stats != nullptr) { @@ -390,29 +393,36 @@ TEST_P(BitrateAdaptationTest, BitrateAdaptation) { VideoSourceSettings source_settings = ToSourceSettings(video_info); - std::map encoding_settings = + EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings( + codec_type, /*scalability_mode=*/"L1T1", + /*width=*/640, /*height=*/360, + {DataRate::KilobitsPerSec(bitrate_kbps.first)}, + /*framerate=*/Frequency::Hertz(30)); + + EncodingSettings encoding_settings2 = VideoCodecTester::CreateEncodingSettings( codec_type, /*scalability_mode=*/"L1T1", - /*width=*/640, /*height=*/360, {bitrate_kbps.first}, - /*framerate_fps=*/30, num_frames); + /*width=*/640, /*height=*/360, + {DataRate::KilobitsPerSec(bitrate_kbps.second)}, + /*framerate=*/Frequency::Hertz(30)); - uint32_t initial_timestamp_rtp = - encoding_settings.rbegin()->first + k90kHz / Frequency::Hertz(30); + std::map frame_settings = + VideoCodecTester::CreateFrameSettings(encoding_settings, num_frames); - std::map encoding_settings2 = - VideoCodecTester::CreateEncodingSettings( - codec_type, /*scalability_mode=*/"L1T1", - /*width=*/640, /*height=*/360, {bitrate_kbps.second}, - /*framerate_fps=*/30, num_frames, initial_timestamp_rtp); + uint32_t timestamp_rtp = + frame_settings.rbegin()->first + k90kHz / Frequency::Hertz(30); + std::map frame_settings2 = + VideoCodecTester::CreateFrameSettings(encoding_settings2, num_frames, + timestamp_rtp); - encoding_settings.merge(encoding_settings2); + frame_settings.merge(frame_settings2); std::unique_ptr stats = RunEncodeTest( - env, codec_type, codec_impl, source_settings, encoding_settings); + env, codec_type, codec_impl, source_settings, frame_settings); VideoCodecStats::Stream stream; if (stats != nullptr) { - stream = stats->Aggregate({.min_timestamp_rtp = initial_timestamp_rtp}); + stream = stats->Aggregate({.min_timestamp_rtp = timestamp_rtp}); if (absl::GetFlag(FLAGS_webrtc_quick_perf_test)) { EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10); EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10); @@ -469,33 +479,39 @@ TEST_P(FramerateAdaptationTest, FramerateAdaptation) { VideoSourceSettings source_settings = ToSourceSettings(video_info); - std::map encoding_settings = + EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings( + codec_type, /*scalability_mode=*/"L1T1", + /*width=*/640, /*height=*/360, + /*bitrate=*/{DataRate::KilobitsPerSec(512)}, + Frequency::Hertz(framerate_fps.first)); + + EncodingSettings encoding_settings2 = VideoCodecTester::CreateEncodingSettings( codec_type, /*scalability_mode=*/"L1T1", /*width=*/640, /*height=*/360, - /*layer_bitrates_kbps=*/{512}, framerate_fps.first, - static_cast(duration_s * framerate_fps.first)); + /*bitrate=*/{DataRate::KilobitsPerSec(512)}, + Frequency::Hertz(framerate_fps.second)); - uint32_t initial_timestamp_rtp = - encoding_settings.rbegin()->first + - k90kHz / Frequency::Hertz(framerate_fps.first); + int num_frames = static_cast(duration_s * framerate_fps.first); + std::map frame_settings = + VideoCodecTester::CreateFrameSettings(encoding_settings, num_frames); - std::map encoding_settings2 = - VideoCodecTester::CreateEncodingSettings( - codec_type, /*scalability_mode=*/"L1T1", /*width=*/640, - /*height=*/360, - /*layer_bitrates_kbps=*/{512}, framerate_fps.second, - static_cast(duration_s * framerate_fps.second), - initial_timestamp_rtp); + uint32_t timestamp_rtp = frame_settings.rbegin()->first + + k90kHz / Frequency::Hertz(framerate_fps.first); - encoding_settings.merge(encoding_settings2); + num_frames = static_cast(duration_s * framerate_fps.second); + std::map frame_settings2 = + VideoCodecTester::CreateFrameSettings(encoding_settings2, num_frames, + timestamp_rtp); + + frame_settings.merge(frame_settings2); std::unique_ptr stats = RunEncodeTest( - env, codec_type, codec_impl, source_settings, encoding_settings); + env, codec_type, codec_impl, source_settings, frame_settings); VideoCodecStats::Stream stream; if (stats != nullptr) { - stream = stats->Aggregate({.min_timestamp_rtp = initial_timestamp_rtp}); + stream = stats->Aggregate({.min_timestamp_rtp = timestamp_rtp}); if (absl::GetFlag(FLAGS_webrtc_quick_perf_test)) { EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10); EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10); @@ -540,26 +556,27 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) { Frequency::Hertz(absl::GetFlag(FLAGS_input_framerate_fps))}; std::vector bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps); - std::vector bitrate_kbps; + std::vector bitrate; std::transform(bitrate_str.begin(), bitrate_str.end(), - std::back_inserter(bitrate_kbps), - [](const std::string& str) { return std::stoi(str); }); + std::back_inserter(bitrate), [](const std::string& str) { + return DataRate::KilobitsPerSec(std::stoi(str)); + }); - VideoCodecMode content_type = absl::GetFlag(FLAGS_screencast) - ? VideoCodecMode::kScreensharing - : VideoCodecMode::kRealtimeVideo; + EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings( + CodecNameToCodecType(absl::GetFlag(FLAGS_encoder)), + absl::GetFlag(FLAGS_scalability_mode), + absl::GetFlag(FLAGS_width).value_or(absl::GetFlag(FLAGS_input_width)), + absl::GetFlag(FLAGS_height).value_or(absl::GetFlag(FLAGS_input_height)), + {bitrate}, + Frequency::Hertz( + absl::GetFlag(FLAGS_framerate_fps) + .value_or(absl::GetFlag(FLAGS_input_framerate_fps))), + absl::GetFlag(FLAGS_screencast), absl::GetFlag(FLAGS_frame_drop)); - std::map frames_settings = - VideoCodecTester::CreateEncodingSettings( - CodecNameToCodecType(absl::GetFlag(FLAGS_encoder)), - absl::GetFlag(FLAGS_scalability_mode), - absl::GetFlag(FLAGS_width).value_or(absl::GetFlag(FLAGS_input_width)), - absl::GetFlag(FLAGS_height) - .value_or(absl::GetFlag(FLAGS_input_height)), - {bitrate_kbps}, absl::GetFlag(FLAGS_framerate_fps), - absl::GetFlag(FLAGS_num_frames), - /*first_timestamp_rtp=*/90000, content_type, - absl::GetFlag(FLAGS_frame_drop)); + std::map frame_settings = + VideoCodecTester::CreateFrameSettings(encoding_settings, + absl::GetFlag(FLAGS_num_frames), + /*timestamp_rtp=*/90000); // TODO(webrtc:14852): Pass encoder and decoder names directly, and update // logged test name (implies lossing history in the chromeperf dashboard). @@ -567,7 +584,7 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) { std::unique_ptr stats = RunEncodeDecodeTest( env, CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)), CodecNameToCodecImpl(absl::GetFlag(FLAGS_decoder)), source_settings, - frames_settings); + frame_settings); ASSERT_NE(nullptr, stats); // Log unsliced metrics. diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc index d46b5d13f3..78ed83c51b 100644 --- a/test/video_codec_tester.cc +++ b/test/video_codec_tester.cc @@ -1301,36 +1301,32 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, ScalabilityMode scalability_mode, int width, int height, - std::vector bitrates_kbps, - double framerate_fps, + std::vector layer_bitrate, + Frequency framerate, VideoCodecMode content_type) { int num_spatial_layers = ScalabilityModeToNumSpatialLayers(scalability_mode); int num_temporal_layers = ScalabilityModeToNumTemporalLayers(scalability_mode); - int num_bitrates = static_cast(bitrates_kbps.size()); + int num_bitrates = static_cast(layer_bitrate.size()); RTC_CHECK(num_bitrates == 1 || num_bitrates == num_spatial_layers || num_bitrates == num_spatial_layers * num_temporal_layers); if (num_bitrates == num_spatial_layers * num_temporal_layers) { - std::vector bitrates; - for (const auto& bitrate_kbps : bitrates_kbps) { - bitrates.push_back(DataRate::KilobitsPerSec(bitrate_kbps)); - } - return std::make_tuple(bitrates, scalability_mode); + return std::make_tuple(layer_bitrate, scalability_mode); } - int total_bitrate_kbps = - std::accumulate(bitrates_kbps.begin(), bitrates_kbps.end(), 0); + DataRate total_bitrate = std::accumulate( + layer_bitrate.begin(), layer_bitrate.end(), DataRate::Zero()); VideoCodec vc; vc.codecType = PayloadStringToCodecType(codec_type); vc.width = width; vc.height = height; - vc.startBitrate = total_bitrate_kbps; - vc.maxBitrate = total_bitrate_kbps; + vc.startBitrate = total_bitrate.kbps(); + vc.maxBitrate = total_bitrate.kbps(); vc.minBitrate = 0; - vc.maxFramerate = static_cast(framerate_fps); + vc.maxFramerate = framerate.hertz(); vc.numberOfSimulcastStreams = 0; vc.mode = content_type; vc.SetScalabilityMode(scalability_mode); @@ -1348,8 +1344,8 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, ss->height = height >> (num_spatial_layers - sidx - 1); ss->maxFramerate = vc.maxFramerate; ss->numberOfTemporalLayers = num_temporal_layers; - ss->maxBitrate = bitrates_kbps[sidx]; - ss->targetBitrate = bitrates_kbps[sidx]; + ss->maxBitrate = layer_bitrate[sidx].kbps(); + ss->targetBitrate = layer_bitrate[sidx].kbps(); ss->minBitrate = 0; ss->qpMax = 0; ss->active = true; @@ -1363,8 +1359,8 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, ss->height = height >> (num_spatial_layers - sidx - 1); ss->maxFramerate = vc.maxFramerate; ss->numberOfTemporalLayers = num_temporal_layers; - ss->maxBitrate = bitrates_kbps[sidx]; - ss->targetBitrate = bitrates_kbps[sidx]; + ss->maxBitrate = layer_bitrate[sidx].kbps(); + ss->targetBitrate = layer_bitrate[sidx].kbps(); ss->minBitrate = 0; ss->qpMax = 0; ss->active = true; @@ -1412,7 +1408,7 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, vc); VideoBitrateAllocation bitrate_allocation = bitrate_allocator->Allocate(VideoBitrateAllocationParameters( - 1000 * total_bitrate_kbps, framerate_fps)); + total_bitrate.bps(), framerate.hertz())); std::vector bitrates; for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { @@ -1486,22 +1482,22 @@ void VideoCodecStats::Stream::LogMetrics( metadata); } -// TODO(ssilkin): use Frequency and DataRate for framerate and bitrate. -std::map VideoCodecTester::CreateEncodingSettings( +EncodingSettings VideoCodecTester::CreateEncodingSettings( std::string codec_type, std::string scalability_name, int width, int height, - std::vector layer_bitrates_kbps, - double framerate_fps, - int num_frames, - uint32_t first_timestamp_rtp, - webrtc::VideoCodecMode content_type, + std::vector bitrate, + Frequency framerate, + bool screencast, bool frame_drop) { - auto [layer_bitrates, scalability_mode] = + VideoCodecMode content_type = screencast ? VideoCodecMode::kScreensharing + : VideoCodecMode::kRealtimeVideo; + + auto [adjusted_bitrate, scalability_mode] = SplitBitrateAndUpdateScalabilityMode( codec_type, *ScalabilityModeFromString(scalability_name), width, - height, layer_bitrates_kbps, framerate_fps, content_type); + height, bitrate, framerate, content_type); int num_spatial_layers = ScalabilityModeToNumSpatialLayers(scalability_mode); int num_temporal_layers = @@ -1512,14 +1508,12 @@ std::map VideoCodecTester::CreateEncodingSettings( int layer_width = width >> (num_spatial_layers - sidx - 1); int layer_height = height >> (num_spatial_layers - sidx - 1); for (int tidx = 0; tidx < num_temporal_layers; ++tidx) { - double layer_framerate_fps = - framerate_fps / (1 << (num_temporal_layers - tidx - 1)); layers_settings.emplace( LayerId{.spatial_idx = sidx, .temporal_idx = tidx}, LayerSettings{ .resolution = {.width = layer_width, .height = layer_height}, - .framerate = Frequency::MilliHertz(1000 * layer_framerate_fps), - .bitrate = layer_bitrates[sidx * num_temporal_layers + tidx]}); + .framerate = framerate / (1 << (num_temporal_layers - tidx - 1)), + .bitrate = adjusted_bitrate[sidx * num_temporal_layers + tidx]}); } } @@ -1534,20 +1528,25 @@ std::map VideoCodecTester::CreateEncodingSettings( .parameters; } - std::map frames_settings; - uint32_t timestamp_rtp = first_timestamp_rtp; + return EncodingSettings{.sdp_video_format = sdp_video_format, + .scalability_mode = scalability_mode, + .content_type = content_type, + .frame_drop = frame_drop, + .layers_settings = layers_settings}; +} + +std::map VideoCodecTester::CreateFrameSettings( + const EncodingSettings& encoding_settings, + int num_frames, + uint32_t timestamp_rtp) { + std::map frame_settings; + Frequency framerate = + encoding_settings.layers_settings.rbegin()->second.framerate; for (int frame_num = 0; frame_num < num_frames; ++frame_num) { - frames_settings.emplace( - timestamp_rtp, EncodingSettings{.sdp_video_format = sdp_video_format, - .scalability_mode = scalability_mode, - .content_type = content_type, - .frame_drop = frame_drop, - .layers_settings = layers_settings}); - - timestamp_rtp += k90kHz / Frequency::MilliHertz(1000 * framerate_fps); + frame_settings.emplace(timestamp_rtp, encoding_settings); + timestamp_rtp += k90kHz / framerate; } - - return frames_settings; + return frame_settings; } std::unique_ptr diff --git a/test/video_codec_tester.h b/test/video_codec_tester.h index ba8b197c58..b4c14a8e1e 100644 --- a/test/video_codec_tester.h +++ b/test/video_codec_tester.h @@ -188,19 +188,26 @@ class VideoCodecTester { virtual absl::optional PullFrame() = 0; }; - // A helper function that creates `EncodingSettings` for `num_frames` frames, - // wraps the settings into RTP timestamp -> settings map and returns the map. - static std::map CreateEncodingSettings( - std::string codec_type, - std::string scalability_name, - int width, - int height, - std::vector bitrates_kbps, - double framerate_fps, + // A helper function that creates `EncodingSettings` from the given + // parameters. `bitrate` is either total, or per-spatial layer or per-spatial + // and per-temporal layer. If layer bitrates are not explicitly specified, + // then the codec-specific rate allocators used to distribute the total + // bitrate across spatial or/and temporal layers. + static EncodingSettings CreateEncodingSettings(std::string codec_type, + std::string scalability_name, + int width, + int height, + std::vector bitrate, + Frequency framerate, + bool screencast = false, + bool frame_drop = true); + + // A helper function that creates a map of RTP timestamps to + // `EncodingSettings` for the given number of frames. + static std::map CreateFrameSettings( + const EncodingSettings& encoding_settings, int num_frames, - uint32_t first_timestamp_rtp = 90000, - VideoCodecMode content_type = VideoCodecMode::kRealtimeVideo, - bool frame_drop = true); + uint32_t first_timestamp_rtp = 90000); // Decodes video, collects and returns decode metrics. static std::unique_ptr RunDecodeTest( diff --git a/test/video_codec_tester_unittest.cc b/test/video_codec_tester_unittest.cc index 6405080a63..2361d25257 100644 --- a/test/video_codec_tester_unittest.cc +++ b/test/video_codec_tester_unittest.cc @@ -69,8 +69,8 @@ using Stream = VideoCodecTester::VideoCodecStats::Stream; constexpr int kWidth = 2; constexpr int kHeight = 2; -const DataRate kTargetLayerBitrate = DataRate::BytesPerSec(100); -const Frequency kTargetFramerate = Frequency::Hertz(30); +const DataRate kBitrate = DataRate::BytesPerSec(100); +const Frequency kFramerate = Frequency::Hertz(30); constexpr Frequency k90kHz = Frequency::Hertz(90000); rtc::scoped_refptr CreateYuvBuffer(uint8_t y = 0, @@ -191,7 +191,7 @@ class VideoCodecTesterTest : public ::testing::Test { VideoSourceSettings video_source_settings{ .file_path = yuv_path, .resolution = {.width = kWidth, .height = kHeight}, - .framerate = kTargetFramerate}; + .framerate = kFramerate}; NiceMock encoder_factory; ON_CALL(encoder_factory, Create).WillByDefault(WithoutArgs([&] { @@ -235,9 +235,9 @@ class VideoCodecTesterTest : public ::testing::Test { LayerId{.spatial_idx = sidx, .temporal_idx = tidx}, LayerSettings{ .resolution = {.width = kWidth, .height = kHeight}, - .framerate = kTargetFramerate / - (1 << (num_temporal_layers - 1 - tidx)), - .bitrate = kTargetLayerBitrate}); + .framerate = + kFramerate / (1 << (num_temporal_layers - 1 - tidx)), + .bitrate = kBitrate}); } } encoding_settings.emplace( @@ -420,9 +420,9 @@ INSTANTIATE_TEST_SUITE_P( DataRate::BytesPerSec(15).kbps(), .expected_encoded_framerate_fps = 2, .expected_bitrate_mismatch_pct = - 100 * (15.0 / (kTargetLayerBitrate.bytes_per_sec() * 4) - 1), - .expected_framerate_mismatch_pct = - 100 * (2.0 / kTargetFramerate.hertz() - 1)}, + 100 * (15.0 / (kBitrate.bytes_per_sec() * 4) - 1), + .expected_framerate_mismatch_pct = 100 * + (2.0 / kFramerate.hertz() - 1)}, // L0T0 AggregationTestParameters{ .filter = {.layer_id = {{.spatial_idx = 0, .temporal_idx = 0}}}, @@ -431,9 +431,9 @@ INSTANTIATE_TEST_SUITE_P( DataRate::BytesPerSec(1).kbps(), .expected_encoded_framerate_fps = 1, .expected_bitrate_mismatch_pct = - 100 * (1.0 / kTargetLayerBitrate.bytes_per_sec() - 1), + 100 * (1.0 / kBitrate.bytes_per_sec() - 1), .expected_framerate_mismatch_pct = - 100 * (1.0 / (kTargetFramerate.hertz() / 2) - 1)}, + 100 * (1.0 / (kFramerate.hertz() / 2) - 1)}, // L0T1 AggregationTestParameters{ .filter = {.layer_id = {{.spatial_idx = 0, .temporal_idx = 1}}}, @@ -442,9 +442,9 @@ INSTANTIATE_TEST_SUITE_P( DataRate::BytesPerSec(5).kbps(), .expected_encoded_framerate_fps = 2, .expected_bitrate_mismatch_pct = - 100 * (5.0 / (kTargetLayerBitrate.bytes_per_sec() * 2) - 1), - .expected_framerate_mismatch_pct = - 100 * (2.0 / kTargetFramerate.hertz() - 1)}, + 100 * (5.0 / (kBitrate.bytes_per_sec() * 2) - 1), + .expected_framerate_mismatch_pct = 100 * + (2.0 / kFramerate.hertz() - 1)}, // L1T0 AggregationTestParameters{ .filter = {.layer_id = {{.spatial_idx = 1, .temporal_idx = 0}}}, @@ -453,9 +453,9 @@ INSTANTIATE_TEST_SUITE_P( DataRate::BytesPerSec(3).kbps(), .expected_encoded_framerate_fps = 1, .expected_bitrate_mismatch_pct = - 100 * (3.0 / kTargetLayerBitrate.bytes_per_sec() - 1), + 100 * (3.0 / kBitrate.bytes_per_sec() - 1), .expected_framerate_mismatch_pct = - 100 * (1.0 / (kTargetFramerate.hertz() / 2) - 1)}, + 100 * (1.0 / (kFramerate.hertz() / 2) - 1)}, // L1T1 AggregationTestParameters{ .filter = {.layer_id = {{.spatial_idx = 1, .temporal_idx = 1}}}, @@ -464,9 +464,9 @@ INSTANTIATE_TEST_SUITE_P( DataRate::BytesPerSec(11).kbps(), .expected_encoded_framerate_fps = 2, .expected_bitrate_mismatch_pct = - 100 * (11.0 / (kTargetLayerBitrate.bytes_per_sec() * 2) - 1), - .expected_framerate_mismatch_pct = - 100 * (2.0 / kTargetFramerate.hertz() - 1)})); + 100 * (11.0 / (kBitrate.bytes_per_sec() * 2) - 1), + .expected_framerate_mismatch_pct = 100 * (2.0 / kFramerate.hertz() - + 1)})); TEST_F(VideoCodecTesterTest, Psnr) { std::unique_ptr stats = RunEncodeDecodeTest( @@ -593,8 +593,7 @@ class VideoCodecTesterTestPacing const int kSourceWidth = 2; const int kSourceHeight = 2; const int kNumFrames = 3; - const int kTargetLayerBitrateKbps = 128; - const Frequency kTargetFramerate = Frequency::Hertz(10); + const Frequency kFramerate = Frequency::Hertz(10); void SetUp() override { source_yuv_file_path_ = CreateYuvFile(kSourceWidth, kSourceHeight, 1); @@ -613,23 +612,23 @@ TEST_P(VideoCodecTesterTestPacing, PaceEncode) { VideoSourceSettings video_source{ .file_path = source_yuv_file_path_, .resolution = {.width = kSourceWidth, .height = kSourceHeight}, - .framerate = kTargetFramerate}; + .framerate = kFramerate}; NiceMock encoder_factory; ON_CALL(encoder_factory, Create).WillByDefault(WithoutArgs([] { return std::make_unique>(); })); - std::map encoding_settings = - VideoCodecTester::CreateEncodingSettings( - "VP8", "L1T1", kSourceWidth, kSourceHeight, {kTargetLayerBitrateKbps}, - kTargetFramerate.hertz(), kNumFrames); + EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings( + "VP8", "L1T1", kSourceWidth, kSourceHeight, {kBitrate}, kFramerate); + std::map frame_settings = + VideoCodecTester::CreateFrameSettings(encoding_settings, kNumFrames); EncoderSettings encoder_settings; encoder_settings.pacing_settings = pacing_settings; std::vector frames = VideoCodecTester::RunEncodeTest(env, video_source, &encoder_factory, - encoder_settings, encoding_settings) + encoder_settings, frame_settings) ->Slice(/*filter=*/{}, /*merge=*/false); ASSERT_THAT(frames, SizeIs(kNumFrames)); EXPECT_NEAR((frames[1].encode_start - frames[0].encode_start).ms(), @@ -640,7 +639,7 @@ TEST_P(VideoCodecTesterTestPacing, PaceEncode) { TEST_P(VideoCodecTesterTestPacing, PaceDecode) { auto [pacing_settings, expected_delta_ms] = GetParam(); - MockCodedVideoSource video_source(kNumFrames, kTargetFramerate); + MockCodedVideoSource video_source(kNumFrames, kFramerate); NiceMock decoder_factory; ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([] { @@ -678,8 +677,8 @@ INSTANTIATE_TEST_SUITE_P( struct EncodingSettingsTestParameters { std::string codec_type; std::string scalability_mode; - std::vector bitrate_kbps; - std::vector expected_bitrate_kbps; + std::vector bitrate; + std::vector expected_bitrate; }; class VideoCodecTesterTestEncodingSettings @@ -687,124 +686,189 @@ class VideoCodecTesterTestEncodingSettings TEST_P(VideoCodecTesterTestEncodingSettings, CreateEncodingSettings) { EncodingSettingsTestParameters test_params = GetParam(); - std::map encoding_settings = - VideoCodecTester::CreateEncodingSettings( - test_params.codec_type, test_params.scalability_mode, /*width=*/1280, - /*height=*/720, test_params.bitrate_kbps, /*framerate_fps=*/30, - /*num_frames=*/1); - ASSERT_THAT(encoding_settings, SizeIs(1)); + EncodingSettings encoding_settings = VideoCodecTester::CreateEncodingSettings( + test_params.codec_type, test_params.scalability_mode, /*width=*/1280, + /*height=*/720, test_params.bitrate, kFramerate); const std::map& layers_settings = - encoding_settings.begin()->second.layers_settings; - std::vector configured_bitrate_kbps; - std::transform(layers_settings.begin(), layers_settings.end(), - std::back_inserter(configured_bitrate_kbps), - [](const auto& layer_settings) { - return layer_settings.second.bitrate.kbps(); - }); - EXPECT_EQ(configured_bitrate_kbps, test_params.expected_bitrate_kbps); + encoding_settings.layers_settings; + std::vector configured_bitrate; + std::transform( + layers_settings.begin(), layers_settings.end(), + std::back_inserter(configured_bitrate), + [](const auto& layer_settings) { return layer_settings.second.bitrate; }); + EXPECT_EQ(configured_bitrate, test_params.expected_bitrate); } INSTANTIATE_TEST_SUITE_P( Vp8, VideoCodecTesterTestEncodingSettings, - Values(EncodingSettingsTestParameters{.codec_type = "VP8", - .scalability_mode = "L1T1", - .bitrate_kbps = {1}, - .expected_bitrate_kbps = {1}}, - EncodingSettingsTestParameters{.codec_type = "VP8", - .scalability_mode = "L1T1", - .bitrate_kbps = {10000}, - .expected_bitrate_kbps = {10000}}, - EncodingSettingsTestParameters{ - .codec_type = "VP8", - .scalability_mode = "L1T3", - .bitrate_kbps = {1000}, - .expected_bitrate_kbps = {400, 200, 400}}, - EncodingSettingsTestParameters{ - .codec_type = "VP8", - .scalability_mode = "S3T3", - .bitrate_kbps = {100}, - .expected_bitrate_kbps = {40, 20, 40, 0, 0, 0, 0, 0, 0}}, - EncodingSettingsTestParameters{ - .codec_type = "VP8", - .scalability_mode = "S3T3", - .bitrate_kbps = {10000}, - .expected_bitrate_kbps = {60, 30, 60, 200, 100, 200, 1000, 500, - 1000}}, - EncodingSettingsTestParameters{ - .codec_type = "VP8", - .scalability_mode = "S3T3", - .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, - .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, - 900}})); + Values( + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "L1T1", + .bitrate = {DataRate::KilobitsPerSec(1)}, + .expected_bitrate = {DataRate::KilobitsPerSec(1)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "L1T1", + .bitrate = {DataRate::KilobitsPerSec(10000)}, + .expected_bitrate = {DataRate::KilobitsPerSec(10000)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "L1T3", + .bitrate = {DataRate::KilobitsPerSec(1000)}, + .expected_bitrate = {DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(400)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate = {DataRate::KilobitsPerSec(100)}, + .expected_bitrate = + {DataRate::KilobitsPerSec(40), DataRate::KilobitsPerSec(20), + DataRate::KilobitsPerSec(40), DataRate::KilobitsPerSec(0), + DataRate::KilobitsPerSec(0), DataRate::KilobitsPerSec(0), + DataRate::KilobitsPerSec(0), DataRate::KilobitsPerSec(0), + DataRate::KilobitsPerSec(0)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate = {DataRate::KilobitsPerSec(10000)}, + .expected_bitrate = + {DataRate::KilobitsPerSec(60), DataRate::KilobitsPerSec(30), + DataRate::KilobitsPerSec(60), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(1000), DataRate::KilobitsPerSec(500), + DataRate::KilobitsPerSec(1000)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate = + {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600), + DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800), + DataRate::KilobitsPerSec(900)}, + .expected_bitrate = { + DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600), + DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800), + DataRate::KilobitsPerSec(900)}})); INSTANTIATE_TEST_SUITE_P( Vp9, VideoCodecTesterTestEncodingSettings, - Values(EncodingSettingsTestParameters{.codec_type = "VP9", - .scalability_mode = "L1T1", - .bitrate_kbps = {1}, - .expected_bitrate_kbps = {1}}, - EncodingSettingsTestParameters{.codec_type = "VP9", - .scalability_mode = "L1T1", - .bitrate_kbps = {10000}, - .expected_bitrate_kbps = {10000}}, - EncodingSettingsTestParameters{ - .codec_type = "VP9", - .scalability_mode = "L1T3", - .bitrate_kbps = {1000}, - .expected_bitrate_kbps = {540, 163, 297}}, - EncodingSettingsTestParameters{ - .codec_type = "VP9", - .scalability_mode = "L3T3", - .bitrate_kbps = {100}, - .expected_bitrate_kbps = {54, 16, 30, 0, 0, 0, 0, 0, 0}}, - EncodingSettingsTestParameters{ - .codec_type = "VP9", - .scalability_mode = "L3T3", - .bitrate_kbps = {10000}, - .expected_bitrate_kbps = {77, 23, 42, 226, 68, 124, 823, 249, - 452}}, - EncodingSettingsTestParameters{ - .codec_type = "VP9", - .scalability_mode = "L3T3", - .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, - .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, - 900}})); + Values( + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L1T1", + .bitrate = {DataRate::KilobitsPerSec(1)}, + .expected_bitrate = {DataRate::KilobitsPerSec(1)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L1T1", + .bitrate = {DataRate::KilobitsPerSec(10000)}, + .expected_bitrate = {DataRate::KilobitsPerSec(10000)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L1T3", + .bitrate = {DataRate::KilobitsPerSec(1000)}, + .expected_bitrate = {DataRate::BitsPerSec(539811), + DataRate::BitsPerSec(163293), + DataRate::BitsPerSec(296896)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate = {DataRate::KilobitsPerSec(100)}, + .expected_bitrate = + {DataRate::BitsPerSec(53981), DataRate::BitsPerSec(16329), + DataRate::BitsPerSec(29690), DataRate::BitsPerSec(0), + DataRate::BitsPerSec(0), DataRate::BitsPerSec(0), + DataRate::BitsPerSec(0), DataRate::BitsPerSec(0), + DataRate::BitsPerSec(0)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate = {DataRate::KilobitsPerSec(10000)}, + .expected_bitrate = + {DataRate::BitsPerSec(76653), DataRate::BitsPerSec(23188), + DataRate::BitsPerSec(42159), DataRate::BitsPerSec(225641), + DataRate::BitsPerSec(68256), DataRate::BitsPerSec(124103), + DataRate::BitsPerSec(822672), DataRate::BitsPerSec(248858), + DataRate::BitsPerSec(452470)}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate = + {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600), + DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800), + DataRate::KilobitsPerSec(900)}, + .expected_bitrate = { + DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600), + DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800), + DataRate::KilobitsPerSec(900)}})); INSTANTIATE_TEST_SUITE_P( Av1, VideoCodecTesterTestEncodingSettings, - Values(EncodingSettingsTestParameters{.codec_type = "AV1", - .scalability_mode = "L1T1", - .bitrate_kbps = {1}, - .expected_bitrate_kbps = {1}}, - EncodingSettingsTestParameters{.codec_type = "AV1", - .scalability_mode = "L1T1", - .bitrate_kbps = {10000}, - .expected_bitrate_kbps = {10000}}, - EncodingSettingsTestParameters{ - .codec_type = "AV1", - .scalability_mode = "L1T3", - .bitrate_kbps = {1000}, - .expected_bitrate_kbps = {540, 163, 297}}, - EncodingSettingsTestParameters{ - .codec_type = "AV1", - .scalability_mode = "L3T3", - .bitrate_kbps = {100}, - .expected_bitrate_kbps = {54, 16, 30, 0, 0, 0, 0, 0, 0}}, - EncodingSettingsTestParameters{ - .codec_type = "AV1", - .scalability_mode = "L3T3", - .bitrate_kbps = {10000}, - .expected_bitrate_kbps = {77, 23, 42, 226, 68, 124, 823, 249, - 452}}, - EncodingSettingsTestParameters{ - .codec_type = "AV1", - .scalability_mode = "L3T3", - .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, - .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, - 900}})); + Values( + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L1T1", + .bitrate = {DataRate::KilobitsPerSec(1)}, + .expected_bitrate = {DataRate::KilobitsPerSec(1)}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L1T1", + .bitrate = {DataRate::KilobitsPerSec(10000)}, + .expected_bitrate = {DataRate::KilobitsPerSec(10000)}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L1T3", + .bitrate = {DataRate::KilobitsPerSec(1000)}, + .expected_bitrate = {DataRate::BitsPerSec(539811), + DataRate::BitsPerSec(163293), + DataRate::BitsPerSec(296896)}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate = {DataRate::KilobitsPerSec(100)}, + .expected_bitrate = + {DataRate::BitsPerSec(53981), DataRate::BitsPerSec(16329), + DataRate::BitsPerSec(29690), DataRate::BitsPerSec(0), + DataRate::BitsPerSec(0), DataRate::BitsPerSec(0), + DataRate::BitsPerSec(0), DataRate::BitsPerSec(0), + DataRate::BitsPerSec(0)}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate = {DataRate::KilobitsPerSec(10000)}, + .expected_bitrate = + {DataRate::BitsPerSec(76653), DataRate::BitsPerSec(23188), + DataRate::BitsPerSec(42159), DataRate::BitsPerSec(225641), + DataRate::BitsPerSec(68256), DataRate::BitsPerSec(124103), + DataRate::BitsPerSec(822672), DataRate::BitsPerSec(248858), + DataRate::BitsPerSec(452470)}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate = + {DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600), + DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800), + DataRate::KilobitsPerSec(900)}, + .expected_bitrate = { + DataRate::KilobitsPerSec(100), DataRate::KilobitsPerSec(200), + DataRate::KilobitsPerSec(300), DataRate::KilobitsPerSec(400), + DataRate::KilobitsPerSec(500), DataRate::KilobitsPerSec(600), + DataRate::KilobitsPerSec(700), DataRate::KilobitsPerSec(800), + DataRate::KilobitsPerSec(900)}})); } // namespace test } // namespace webrtc