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}
This commit is contained in:
Sergey Silkin 2024-05-07 07:23:41 +00:00 committed by WebRTC LUCI CQ
parent 47bfe39ecf
commit f126e8af82
4 changed files with 39 additions and 115 deletions

View file

@ -120,7 +120,7 @@ std::unique_ptr<ScalableVideoController> CreateVp9ScalabilityStructure(
}
// 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 @@ int LibvpxVp9Encoder::Release() {
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 @@ bool LibvpxVp9Encoder::SetSvcRates(
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 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
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 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
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();

View file

@ -139,6 +139,7 @@ class LibvpxVp9Encoder : public VideoEncoder {
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_;

View file

@ -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 @@ using FramerateFractions =
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 @@ VideoCodec DefaultCodecSettings() {
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 @@ class TestVp9Impl : public VideoCodecUnitTest {
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, EncodeAttachesTemplateStructureWithSvcController) {
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, EncoderWith2TemporalLayers) {
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, EncodeTemporalLayersWithSvcController) {
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, EncoderWith2SpatialLayers) {
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(Vp9ImplTest, EncodeSpatialLayersWithSvcController) {
}
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 @@ TEST_P(Vp9ImplWithLayeringTest, FlexibleMode) {
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 @@ TEST_F(TestVp9ImplFrameDropping, PreEncodeFrameDropping) {
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 @@ TEST_P(TestVp9ImplSvcFrameDropConfig, SvcFrameDropConfig) {
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));
}

View file

@ -1070,8 +1070,6 @@ class Encoder : public EncodedImageCallback {
break;
case kVideoCodecVP9:
*(vc.VP9()) = VideoEncoder::GetDefaultVp9Settings();
// See LibvpxVp9Encoder::ExplicitlyConfiguredSpatialLayers.
vc.spatialLayers[0].targetBitrate = vc.maxBitrate;
vc.qpMax = cricket::kDefaultVideoMaxQpVpx;
break;
case kVideoCodecAV1: