[Video, Svc] Remove inactive spatial layers in codec initializer
This is more logical way to remove inactive lower layers.
Current way is to notify the encoder that the layer is inactive,
then renumber layers at the packatization level.
This Cl will allow to simplify libvpx vp9 encoder, svcRateAllocator and
vp9 packetizer.
Bug: webrtc:11319
Change-Id: Idf0bb30b729f5ecc97e31454b32934546b681aa2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/173182
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31058}
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 fe42039..7e92b36 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 @@
const std::vector<SpatialLayer> 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 764c1a2..e5d88bc 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<SpatialLayer> 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<SpatialLayer> spatial_layers;
// Limit number of layers for given resolution.
@@ -76,9 +76,11 @@
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<SpatialLayer> 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 @@
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 3bc9ba7..9bd8b0e 100644
--- a/modules/video_coding/codecs/vp9/svc_config.h
+++ b/modules/video_coding/codecs/vp9/svc_config.h
@@ -21,7 +21,7 @@
std::vector<SpatialLayer> 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 07a2ebe..abc67a2 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<SpatialLayer> 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<SpatialLayer> 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<SpatialLayer> 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<SpatialLayer> 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 7318592..daa0c52 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 @@
: VideoCodecMode::kRealtimeVideo;
std::vector<SpatialLayer> 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 5880593..d40cf23 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 @@
std::vector<SpatialLayer> 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 bd40385..e8665b9 100644
--- a/modules/video_coding/video_codec_initializer.cc
+++ b/modules/video_coding/video_codec_initializer.cc
@@ -179,19 +179,18 @@
// 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 @@
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;
}
}