diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc index fe42039468..7e92b360bd 100644 --- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc +++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc @@ -85,7 +85,7 @@ void ConfigureSvc(VideoCodec* codec_settings) { const std::vector layers = GetSvcConfig( codec_settings->width, codec_settings->height, kMaxFramerateFps, - /*min_spatial_layers=*/1, codec_settings->VP9()->numberOfSpatialLayers, + /*first_active_layer=*/0, codec_settings->VP9()->numberOfSpatialLayers, codec_settings->VP9()->numberOfTemporalLayers, /* is_screen_sharing = */ false); ASSERT_EQ(codec_settings->VP9()->numberOfSpatialLayers, layers.size()) diff --git a/modules/video_coding/codecs/vp9/svc_config.cc b/modules/video_coding/codecs/vp9/svc_config.cc index 764c1a209d..e5d88bce21 100644 --- a/modules/video_coding/codecs/vp9/svc_config.cc +++ b/modules/video_coding/codecs/vp9/svc_config.cc @@ -61,10 +61,10 @@ std::vector ConfigureSvcScreenSharing(size_t input_width, std::vector ConfigureSvcNormalVideo(size_t input_width, size_t input_height, float max_framerate_fps, - size_t min_spatial_layers, + size_t first_active_layer, size_t num_spatial_layers, size_t num_temporal_layers) { - RTC_DCHECK_LE(min_spatial_layers, num_spatial_layers); + RTC_DCHECK_LT(first_active_layer, num_spatial_layers); std::vector spatial_layers; // Limit number of layers for given resolution. @@ -76,9 +76,11 @@ std::vector ConfigureSvcNormalVideo(size_t input_width, kMinVp9SpatialLayerHeight)))); num_spatial_layers = std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert}); - num_spatial_layers = std::max(num_spatial_layers, min_spatial_layers); + // First active layer must be configured. + num_spatial_layers = std::max(num_spatial_layers, first_active_layer + 1); - for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { + for (size_t sl_idx = first_active_layer; sl_idx < num_spatial_layers; + ++sl_idx) { SpatialLayer spatial_layer = {0}; spatial_layer.width = input_width >> (num_spatial_layers - sl_idx - 1); spatial_layer.height = input_height >> (num_spatial_layers - sl_idx - 1); @@ -112,7 +114,7 @@ std::vector ConfigureSvcNormalVideo(size_t input_width, std::vector GetSvcConfig(size_t input_width, size_t input_height, float max_framerate_fps, - size_t min_spatial_layers, + size_t first_active_layer, size_t num_spatial_layers, size_t num_temporal_layers, bool is_screen_sharing) { @@ -126,7 +128,7 @@ std::vector GetSvcConfig(size_t input_width, max_framerate_fps, num_spatial_layers); } else { return ConfigureSvcNormalVideo(input_width, input_height, max_framerate_fps, - min_spatial_layers, num_spatial_layers, + first_active_layer, num_spatial_layers, num_temporal_layers); } } diff --git a/modules/video_coding/codecs/vp9/svc_config.h b/modules/video_coding/codecs/vp9/svc_config.h index 3bc9ba7a34..9bd8b0e313 100644 --- a/modules/video_coding/codecs/vp9/svc_config.h +++ b/modules/video_coding/codecs/vp9/svc_config.h @@ -21,7 +21,7 @@ namespace webrtc { std::vector GetSvcConfig(size_t input_width, size_t input_height, float max_framerate_fps, - size_t min_spatial_layers, + size_t first_active_layer, size_t num_spatial_layers, size_t num_temporal_layers, bool is_screen_sharing); diff --git a/modules/video_coding/codecs/vp9/svc_config_unittest.cc b/modules/video_coding/codecs/vp9/svc_config_unittest.cc index 07a2ebe5ad..abc67a22ff 100644 --- a/modules/video_coding/codecs/vp9/svc_config_unittest.cc +++ b/modules/video_coding/codecs/vp9/svc_config_unittest.cc @@ -19,35 +19,48 @@ namespace webrtc { TEST(SvcConfig, NumSpatialLayers) { const size_t max_num_spatial_layers = 6; - const size_t min_spatial_layers = 1; + const size_t first_active_layer = 0; const size_t num_spatial_layers = 2; std::vector spatial_layers = GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1), kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30, - min_spatial_layers, max_num_spatial_layers, 1, false); + first_active_layer, max_num_spatial_layers, 1, false); EXPECT_EQ(spatial_layers.size(), num_spatial_layers); } -TEST(SvcConfig, NumSpatialLayersRespectsMinNumberOfLayers) { +TEST(SvcConfig, AlwaysSendsAtLeastOneLayer) { const size_t max_num_spatial_layers = 6; - const size_t min_spatial_layers = 2; + const size_t first_active_layer = 5; std::vector spatial_layers = GetSvcConfig(kMinVp9SpatialLayerWidth, kMinVp9SpatialLayerHeight, 30, - min_spatial_layers, max_num_spatial_layers, 1, false); + first_active_layer, max_num_spatial_layers, 1, false); + EXPECT_EQ(spatial_layers.size(), 1u); + EXPECT_EQ(spatial_layers.back().width, kMinVp9SpatialLayerWidth); +} +TEST(SvcConfig, SkipsInactiveLayers) { + const size_t num_spatial_layers = 4; + const size_t first_active_layer = 2; + + std::vector spatial_layers = + GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1), + kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30, + first_active_layer, num_spatial_layers, 1, false); EXPECT_EQ(spatial_layers.size(), 2u); + EXPECT_EQ(spatial_layers.back().width, + kMinVp9SpatialLayerWidth << (num_spatial_layers - 1)); } TEST(SvcConfig, BitrateThresholds) { - const size_t min_spatial_layers = 1; + const size_t first_active_layer = 0; const size_t num_spatial_layers = 3; std::vector spatial_layers = GetSvcConfig(kMinVp9SpatialLayerWidth << (num_spatial_layers - 1), kMinVp9SpatialLayerHeight << (num_spatial_layers - 1), 30, - min_spatial_layers, num_spatial_layers, 1, false); + first_active_layer, num_spatial_layers, 1, false); EXPECT_EQ(spatial_layers.size(), num_spatial_layers); diff --git a/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc b/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc index 7318592ac2..daa0c52e09 100644 --- a/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc +++ b/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc @@ -34,7 +34,7 @@ static VideoCodec Configure(size_t width, : VideoCodecMode::kRealtimeVideo; std::vector spatial_layers = - GetSvcConfig(width, height, 30, /*min_spatial_layers=*/1, + GetSvcConfig(width, height, 30, /*first_active_layer=*/0, num_spatial_layers, num_temporal_layers, is_screen_sharing); RTC_CHECK_LE(spatial_layers.size(), kMaxSpatialLayers); diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc index 58805934e6..d40cf23257 100644 --- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc +++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc @@ -114,7 +114,7 @@ class TestVp9Impl : public VideoCodecUnitTest { std::vector layers = GetSvcConfig(codec_settings_.width, codec_settings_.height, - codec_settings_.maxFramerate, /*min_spatial_layers=*/1, + codec_settings_.maxFramerate, /*first_active_layer=*/0, num_spatial_layers, num_temporal_layers, false); for (size_t i = 0; i < layers.size(); ++i) { codec_settings_.spatialLayers[i] = layers[i]; diff --git a/modules/video_coding/video_codec_initializer.cc b/modules/video_coding/video_codec_initializer.cc index bd40385a51..e8665b9557 100644 --- a/modules/video_coding/video_codec_initializer.cc +++ b/modules/video_coding/video_codec_initializer.cc @@ -179,19 +179,18 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( // Layering is set explicitly. spatial_layers = config.spatial_layers; } else { - size_t min_required_layers = 0; - // Need at least enough layers for the first active one to be present. + size_t first_active_layer = 0; for (size_t spatial_idx = 0; spatial_idx < config.simulcast_layers.size(); ++spatial_idx) { if (config.simulcast_layers[spatial_idx].active) { - min_required_layers = spatial_idx + 1; + first_active_layer = spatial_idx; break; } } spatial_layers = GetSvcConfig( video_codec.width, video_codec.height, video_codec.maxFramerate, - min_required_layers, video_codec.VP9()->numberOfSpatialLayers, + first_active_layer, video_codec.VP9()->numberOfSpatialLayers, video_codec.VP9()->numberOfTemporalLayers, video_codec.mode == VideoCodecMode::kScreensharing); @@ -210,7 +209,7 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( spatial_idx < config.simulcast_layers.size() && spatial_idx < spatial_layers.size(); ++spatial_idx) { - spatial_layers[spatial_idx].active = + spatial_layers[spatial_idx - first_active_layer].active = config.simulcast_layers[spatial_idx].active; } }