Delete implicit layering mode.
This is a cleanup in VP9 encoder wrapper. The removed code paths were only used in tests. In prod layers are configured explicitly via VideoCodec::spatialLayers[].
Bug: webrtc:42225151
Change-Id: I1de90039488b36e3c88e788c78e675bf2ee68f9b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/349222
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Auto-Submit: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42250}
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
index 877d10d..5a6d465 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
@@ -120,7 +120,7 @@
}
// Check spatial ratio.
- if (num_spatial_layers > 1 && codec.spatialLayers[0].targetBitrate > 0) {
+ if (num_spatial_layers > 1) {
if (codec.width != codec.spatialLayers[num_spatial_layers - 1].width ||
codec.height != codec.spatialLayers[num_spatial_layers - 1].height) {
RTC_LOG(LS_WARNING)
@@ -302,12 +302,6 @@
return ret_val;
}
-bool LibvpxVp9Encoder::ExplicitlyConfiguredSpatialLayers() const {
- // We check target_bitrate_bps of the 0th layer to see if the spatial layers
- // (i.e. bitrates) were explicitly configured.
- return codec_.spatialLayers[0].targetBitrate > 0;
-}
-
bool LibvpxVp9Encoder::SetSvcRates(
const VideoBitrateAllocation& bitrate_allocation) {
std::pair<size_t, size_t> current_layers =
@@ -334,66 +328,23 @@
config_->rc_target_bitrate = bitrate_allocation.get_sum_kbps();
- if (ExplicitlyConfiguredSpatialLayers()) {
- for (size_t sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
- const bool was_layer_active = (config_->ss_target_bitrate[sl_idx] > 0);
- config_->ss_target_bitrate[sl_idx] =
- bitrate_allocation.GetSpatialLayerSum(sl_idx) / 1000;
-
- for (size_t tl_idx = 0; tl_idx < num_temporal_layers_; ++tl_idx) {
- config_->layer_target_bitrate[sl_idx * num_temporal_layers_ + tl_idx] =
- bitrate_allocation.GetTemporalLayerSum(sl_idx, tl_idx) / 1000;
- }
-
- if (!was_layer_active) {
- // Reset frame rate controller if layer is resumed after pause.
- framerate_controller_[sl_idx].Reset();
- }
-
- framerate_controller_[sl_idx].SetTargetRate(
- codec_.spatialLayers[sl_idx].maxFramerate);
- }
- } else {
- float rate_ratio[VPX_MAX_LAYERS] = {0};
- float total = 0;
- for (int i = 0; i < num_spatial_layers_; ++i) {
- if (svc_params_.scaling_factor_num[i] <= 0 ||
- svc_params_.scaling_factor_den[i] <= 0) {
- RTC_LOG(LS_ERROR) << "Scaling factors not specified!";
- return false;
- }
- rate_ratio[i] = static_cast<float>(svc_params_.scaling_factor_num[i]) /
- svc_params_.scaling_factor_den[i];
- total += rate_ratio[i];
+ for (size_t sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
+ if (config_->ss_target_bitrate[sl_idx] == 0) {
+ // Reset frame rate controller if layer is resumed after pause.
+ framerate_controller_[sl_idx].Reset();
}
- for (int i = 0; i < num_spatial_layers_; ++i) {
- RTC_CHECK_GT(total, 0);
- config_->ss_target_bitrate[i] = static_cast<unsigned int>(
- config_->rc_target_bitrate * rate_ratio[i] / total);
- if (num_temporal_layers_ == 1) {
- config_->layer_target_bitrate[i] = config_->ss_target_bitrate[i];
- } else if (num_temporal_layers_ == 2) {
- config_->layer_target_bitrate[i * num_temporal_layers_] =
- config_->ss_target_bitrate[i] * 2 / 3;
- config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
- config_->ss_target_bitrate[i];
- } else if (num_temporal_layers_ == 3) {
- config_->layer_target_bitrate[i * num_temporal_layers_] =
- config_->ss_target_bitrate[i] / 2;
- config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
- config_->layer_target_bitrate[i * num_temporal_layers_] +
- (config_->ss_target_bitrate[i] / 4);
- config_->layer_target_bitrate[i * num_temporal_layers_ + 2] =
- config_->ss_target_bitrate[i];
- } else {
- RTC_LOG(LS_ERROR) << "Unsupported number of temporal layers: "
- << num_temporal_layers_;
- return false;
- }
+ config_->ss_target_bitrate[sl_idx] =
+ bitrate_allocation.GetSpatialLayerSum(sl_idx) / 1000;
- framerate_controller_[i].SetTargetRate(codec_.maxFramerate);
+ for (size_t tl_idx = 0; tl_idx < num_temporal_layers_; ++tl_idx) {
+ config_->layer_target_bitrate[sl_idx * num_temporal_layers_ + tl_idx] =
+ bitrate_allocation.GetTemporalLayerSum(sl_idx, tl_idx) / 1000;
}
+
+ framerate_controller_[sl_idx].SetTargetRate(
+ num_spatial_layers_ > 1 ? codec_.spatialLayers[sl_idx].maxFramerate
+ : codec_.maxFramerate);
}
num_active_spatial_layers_ = 0;
@@ -787,7 +738,7 @@
svc_params_.scaling_factor_num[i] = stream_config.scaling_factor_num[i];
svc_params_.scaling_factor_den[i] = stream_config.scaling_factor_den[i];
}
- } else if (ExplicitlyConfiguredSpatialLayers()) {
+ } else if (num_spatial_layers_ > 1) {
for (int i = 0; i < num_spatial_layers_; ++i) {
const auto& layer = codec_.spatialLayers[i];
RTC_CHECK_GT(layer.width, 0);
@@ -822,15 +773,6 @@
codec_.spatialLayers[i - 1].maxFramerate);
}
}
- } else {
- int scaling_factor_num = 256;
- for (int i = num_spatial_layers_ - 1; i >= 0; --i) {
- // 1:2 scaling in each dimension.
- svc_params_.scaling_factor_num[i] = scaling_factor_num;
- svc_params_.scaling_factor_den[i] = 256;
- if (inst->mode != VideoCodecMode::kScreensharing)
- scaling_factor_num /= 2;
- }
}
UpdatePerformanceFlags();
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
index d8c9805..0134e3e 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
@@ -139,6 +139,7 @@
uint8_t num_spatial_layers_; // Number of configured SLs
uint8_t num_active_spatial_layers_; // Number of actively encoded SLs
uint8_t first_active_layer_;
+ uint8_t last_active_layer_;
bool layer_deactivation_requires_key_frame_;
bool is_svc_;
InterLayerPredMode inter_layer_pred_;
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 7fdd4ed..9fd2875 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -25,6 +25,7 @@
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h"
#include "modules/video_coding/codecs/vp9/svc_config.h"
+#include "modules/video_coding/svc/scalability_mode_util.h"
#include "rtc_base/strings/string_builder.h"
#include "test/explicit_key_value_config.h"
#include "test/field_trial.h"
@@ -64,6 +65,7 @@
constexpr size_t kWidth = 1280;
constexpr size_t kHeight = 720;
+constexpr int kBitrateKbps = 2048;
const VideoEncoder::Capabilities kCapabilities(false);
const VideoEncoder::Settings kSettings(kCapabilities,
@@ -75,17 +77,18 @@
webrtc::test::CodecSettings(kVideoCodecVP9, &codec_settings);
codec_settings.width = kWidth;
codec_settings.height = kHeight;
+ codec_settings.startBitrate = kBitrateKbps;
+ codec_settings.maxBitrate = kBitrateKbps;
codec_settings.VP9()->numberOfTemporalLayers = 1;
codec_settings.VP9()->numberOfSpatialLayers = 1;
return codec_settings;
}
void ConfigureSvc(VideoCodec& codec_settings,
- int num_spatial_layers,
+ int num_spatial_layers = 1,
int num_temporal_layers = 1) {
codec_settings.VP9()->numberOfSpatialLayers = num_spatial_layers;
codec_settings.VP9()->numberOfTemporalLayers = num_temporal_layers;
- codec_settings.SetFrameDropEnabled(false);
std::vector<SpatialLayer> layers = GetSvcConfig(
codec_settings.width, codec_settings.height, codec_settings.maxFramerate,
@@ -111,8 +114,7 @@
webrtc::test::CodecSettings(kVideoCodecVP9, codec_settings);
codec_settings->width = kWidth;
codec_settings->height = kHeight;
- codec_settings->VP9()->numberOfTemporalLayers = 1;
- codec_settings->VP9()->numberOfSpatialLayers = 1;
+ ConfigureSvc(*codec_settings);
}
};
@@ -292,9 +294,10 @@
TEST(Vp9ImplTest, EncoderWith2TemporalLayers) {
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
VideoCodec codec_settings = DefaultCodecSettings();
- codec_settings.VP9()->numberOfTemporalLayers = 2;
// Tl0PidIdx is only used in non-flexible mode.
codec_settings.VP9()->flexibleMode = false;
+ ConfigureSvc(codec_settings, /*num_spatial_layers=*/1,
+ /*num_temporal_layers=*/2);
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
WEBRTC_VIDEO_CODEC_OK);
@@ -314,7 +317,8 @@
TEST(Vp9ImplTest, EncodeTemporalLayersWithSvcController) {
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
VideoCodec codec_settings = DefaultCodecSettings();
- codec_settings.VP9()->numberOfTemporalLayers = 2;
+ ConfigureSvc(codec_settings, /*num_spatial_layers=*/1,
+ /*num_temporal_layers=*/2);
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
WEBRTC_VIDEO_CODEC_OK);
@@ -343,7 +347,7 @@
TEST(Vp9ImplTest, EncoderWith2SpatialLayers) {
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
VideoCodec codec_settings = DefaultCodecSettings();
- codec_settings.VP9()->numberOfSpatialLayers = 2;
+ ConfigureSvc(codec_settings, /*num_spatial_layers=*/2);
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
WEBRTC_VIDEO_CODEC_OK);
@@ -361,7 +365,7 @@
TEST(Vp9ImplTest, EncodeSpatialLayersWithSvcController) {
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
VideoCodec codec_settings = DefaultCodecSettings();
- codec_settings.VP9()->numberOfSpatialLayers = 2;
+ ConfigureSvc(codec_settings, /*num_spatial_layers=*/2);
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
WEBRTC_VIDEO_CODEC_OK);
@@ -388,34 +392,7 @@
}
TEST_F(TestVp9Impl, EncoderExplicitLayering) {
- // Override default settings.
- codec_settings_.VP9()->numberOfTemporalLayers = 1;
- codec_settings_.VP9()->numberOfSpatialLayers = 2;
-
- codec_settings_.width = 960;
- codec_settings_.height = 540;
- codec_settings_.spatialLayers[0].minBitrate = 200;
- codec_settings_.spatialLayers[0].maxBitrate = 500;
- codec_settings_.spatialLayers[0].targetBitrate =
- (codec_settings_.spatialLayers[0].minBitrate +
- codec_settings_.spatialLayers[0].maxBitrate) /
- 2;
- codec_settings_.spatialLayers[0].active = true;
-
- codec_settings_.spatialLayers[1].minBitrate = 400;
- codec_settings_.spatialLayers[1].maxBitrate = 1500;
- codec_settings_.spatialLayers[1].targetBitrate =
- (codec_settings_.spatialLayers[1].minBitrate +
- codec_settings_.spatialLayers[1].maxBitrate) /
- 2;
- codec_settings_.spatialLayers[1].active = true;
-
- codec_settings_.spatialLayers[0].width = codec_settings_.width / 2;
- codec_settings_.spatialLayers[0].height = codec_settings_.height / 2;
- codec_settings_.spatialLayers[0].maxFramerate = codec_settings_.maxFramerate;
- codec_settings_.spatialLayers[1].width = codec_settings_.width;
- codec_settings_.spatialLayers[1].height = codec_settings_.height;
- codec_settings_.spatialLayers[1].maxFramerate = codec_settings_.maxFramerate;
+ ConfigureSvc(codec_settings_, /*num_spatial_layers=*/2);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, kSettings));
@@ -1853,8 +1830,7 @@
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.VP9()->flexibleMode = true;
codec_settings.SetFrameDropEnabled(false);
- codec_settings.VP9()->numberOfSpatialLayers = num_spatial_layers_;
- codec_settings.VP9()->numberOfTemporalLayers = num_temporal_layers_;
+ ConfigureSvc(codec_settings, num_spatial_layers_, num_temporal_layers_);
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
WEBRTC_VIDEO_CODEC_OK);
@@ -1932,6 +1908,7 @@
const float max_abs_framerate_error_fps = expected_framerate_fps * 0.1f;
codec_settings_.maxFramerate = static_cast<uint32_t>(expected_framerate_fps);
+ ConfigureSvc(codec_settings_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
encoder_->InitEncode(&codec_settings_, kSettings));
@@ -2485,11 +2462,17 @@
VideoCodec settings = DefaultCodecSettings();
settings.VP9()->flexibleMode = test_params.flexible_mode;
+
+ int num_spatial_layers = 3;
if (test_params.scalability_mode.has_value()) {
settings.SetScalabilityMode(*test_params.scalability_mode);
+ num_spatial_layers =
+ ScalabilityModeToNumSpatialLayers(*test_params.scalability_mode);
+ } else {
+ num_spatial_layers =
+ 3; // to execute SVC code paths even when scalability_mode is not set.
}
- settings.VP9()->numberOfSpatialLayers =
- 3; // to execute SVC code paths even when scalability_mode is not set.
+ ConfigureSvc(settings, num_spatial_layers);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder.InitEncode(&settings, kSettings));
}
diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc
index 813fbdb..d46b5d1 100644
--- a/test/video_codec_tester.cc
+++ b/test/video_codec_tester.cc
@@ -1070,8 +1070,6 @@
break;
case kVideoCodecVP9:
*(vc.VP9()) = VideoEncoder::GetDefaultVp9Settings();
- // See LibvpxVp9Encoder::ExplicitlyConfiguredSpatialLayers.
- vc.spatialLayers[0].targetBitrate = vc.maxBitrate;
vc.qpMax = cricket::kDefaultVideoMaxQpVpx;
break;
case kVideoCodecAV1: