diff --git a/modules/video_coding/codecs/av1/av1_svc_config.cc b/modules/video_coding/codecs/av1/av1_svc_config.cc index 2acadbd0d3..c480737096 100644 --- a/modules/video_coding/codecs/av1/av1_svc_config.cc +++ b/modules/video_coding/codecs/av1/av1_svc_config.cc @@ -118,10 +118,21 @@ bool SetAv1SvcConfig(VideoCodec& video_codec, spatial_layer.active = true; } + if (info.num_spatial_layers == 1) { + SpatialLayer& spatial_layer = video_codec.spatialLayers[0]; + spatial_layer.minBitrate = video_codec.minBitrate; + spatial_layer.maxBitrate = video_codec.maxBitrate; + spatial_layer.targetBitrate = + (video_codec.minBitrate + video_codec.maxBitrate) / 2; + return true; + } + for (int sl_idx = 0; sl_idx < info.num_spatial_layers; ++sl_idx) { SpatialLayer& spatial_layer = video_codec.spatialLayers[sl_idx]; + // minBitrate and maxBitrate formulas are copied from vp9 settings and + // are not yet tuned for av1. const int num_pixels = spatial_layer.width * spatial_layer.height; - int min_bitrate_kbps = (480.0 * std::sqrt(num_pixels) - 95'000.0) / 1000.0; + int min_bitrate_kbps = (600.0 * std::sqrt(num_pixels) - 95'000.0) / 1000.0; spatial_layer.minBitrate = std::max(min_bitrate_kbps, 20); spatial_layer.maxBitrate = 50 + static_cast(1.6 * num_pixels / 1000.0); spatial_layer.targetBitrate = diff --git a/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc b/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc index 3a4af05e40..7ba7986f0d 100644 --- a/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc +++ b/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc @@ -123,21 +123,48 @@ TEST(Av1SvcConfigTest, SetsNumberOfTemporalLayers) { EXPECT_EQ(video_codec.spatialLayers[0].numberOfTemporalLayers, 3); } -TEST(Av1SvcConfigTest, SetsBitratesForMultipleSpatialLayers) { +TEST(Av1SvcConfigTest, CopiesMinMaxBitrateForSingleSpatialLayer) { VideoCodec video_codec; video_codec.codecType = kVideoCodecAV1; - video_codec.width = 640; - video_codec.height = 360; - video_codec.SetScalabilityMode(ScalabilityMode::kL2T2); + video_codec.SetScalabilityMode(ScalabilityMode::kL1T3); + video_codec.minBitrate = 100; + video_codec.maxBitrate = 500; EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); - EXPECT_EQ(video_codec.spatialLayers[0].minBitrate, 20u); - EXPECT_EQ(video_codec.spatialLayers[0].maxBitrate, 142u); + EXPECT_EQ(video_codec.spatialLayers[0].minBitrate, 100u); + EXPECT_EQ(video_codec.spatialLayers[0].maxBitrate, 500u); + EXPECT_LE(video_codec.spatialLayers[0].minBitrate, + video_codec.spatialLayers[0].targetBitrate); + EXPECT_LE(video_codec.spatialLayers[0].targetBitrate, + video_codec.spatialLayers[0].maxBitrate); +} - EXPECT_EQ(video_codec.spatialLayers[1].minBitrate, 135u); - EXPECT_EQ(video_codec.spatialLayers[1].maxBitrate, 418u); +TEST(Av1SvcConfigTest, SetsBitratesForMultipleSpatialLayers) { + VideoCodec video_codec = GetDefaultVideoCodec(); + video_codec.SetScalabilityMode(ScalabilityMode::kL3T3); + + EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, + /*num_spatial_layers=*/kDontCare)); + + EXPECT_GT(video_codec.spatialLayers[0].minBitrate, 0u); + EXPECT_LE(video_codec.spatialLayers[0].minBitrate, + video_codec.spatialLayers[0].targetBitrate); + EXPECT_LE(video_codec.spatialLayers[0].targetBitrate, + video_codec.spatialLayers[0].maxBitrate); + + EXPECT_GT(video_codec.spatialLayers[1].minBitrate, 0u); + EXPECT_LE(video_codec.spatialLayers[1].minBitrate, + video_codec.spatialLayers[1].targetBitrate); + EXPECT_LE(video_codec.spatialLayers[1].targetBitrate, + video_codec.spatialLayers[1].maxBitrate); + + EXPECT_GT(video_codec.spatialLayers[2].minBitrate, 0u); + EXPECT_LE(video_codec.spatialLayers[2].minBitrate, + video_codec.spatialLayers[2].targetBitrate); + EXPECT_LE(video_codec.spatialLayers[2].targetBitrate, + video_codec.spatialLayers[2].maxBitrate); } TEST(Av1SvcConfigTest, ReduceSpatialLayersOnInsufficentInputResolution) { diff --git a/video/end_to_end_tests/resolution_bitrate_limits_tests.cc b/video/end_to_end_tests/resolution_bitrate_limits_tests.cc index b62d702dd7..e110fb759c 100644 --- a/video/end_to_end_tests/resolution_bitrate_limits_tests.cc +++ b/video/end_to_end_tests/resolution_bitrate_limits_tests.cc @@ -502,6 +502,24 @@ TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest, RunBaseTest(&test); } +TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest, + OneStreamLimitsAppliedForAv1OneSpatialLayer) { + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-GetEncoderInfoOverride/" + "frame_size_pixels:921600," + "min_start_bitrate_bps:0," + "min_bitrate_bps:32000," + "max_bitrate_bps:133000/"); + + InitEncodeTest test( + "AV1", {{.active = true, .scalability_mode = ScalabilityMode::kL1T1}}, + // Expectations: + {{.pixels = 1280 * 720, + .eq_bitrate = {DataRate::KilobitsPerSec(32), + DataRate::KilobitsPerSec(133)}}}); + RunBaseTest(&test); +} + TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest, LimitsAppliedForAv1Simulcast) { webrtc::test::ScopedFieldTrials field_trials(