Add support for reducing number of spatial layers via scalability mode.

Bug: webrtc:13960
Change-Id: Icf31d2e327e363dac24245cb5c9fc14cbaa9b3b4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/275942
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38454}
This commit is contained in:
Åsa Persson
2022-10-21 10:59:19 +02:00
committed by WebRTC LUCI CQ
parent 1c8103d4db
commit b8a4daa31c
5 changed files with 190 additions and 21 deletions

View File

@ -172,6 +172,21 @@ std::vector<SpatialLayer> GetVp9SvcConfig(VideoCodec& codec) {
absl::optional<ScalabilityMode> scalability_mode = codec.GetScalabilityMode();
RTC_DCHECK(scalability_mode.has_value());
// Limit number of spatial layers for given resolution.
int limited_num_spatial_layers =
GetLimitedNumSpatialLayers(codec.width, codec.height);
if (limited_num_spatial_layers <
ScalabilityModeToNumSpatialLayers(*scalability_mode)) {
ScalabilityMode limited_scalability_mode =
LimitNumSpatialLayers(*scalability_mode, limited_num_spatial_layers);
RTC_LOG(LS_WARNING)
<< "Reducing number of spatial layers due to low input resolution: "
<< ScalabilityModeToString(*scalability_mode) << " to "
<< ScalabilityModeToString(limited_scalability_mode);
scalability_mode = limited_scalability_mode;
codec.SetScalabilityMode(limited_scalability_mode);
}
absl::optional<ScalableVideoController::StreamLayersConfig> info =
ScalabilityStructureConfig(*scalability_mode);
if (!info.has_value()) {
@ -180,16 +195,6 @@ std::vector<SpatialLayer> GetVp9SvcConfig(VideoCodec& codec) {
return {};
}
if (static_cast<int>(GetLimitedNumSpatialLayers(codec.width, codec.height)) <
info->num_spatial_layers) {
// Layers will be reduced, do not use scalability mode for now.
// TODO(bugs.webrtc.org/11607): Use a lower scalability mode once all lower
// modes are supported.
codec.UnsetScalabilityMode();
codec.VP9()->interLayerPred =
ScalabilityModeToInterLayerPredMode(*scalability_mode);
}
// TODO(bugs.webrtc.org/11607): Add support for screensharing.
std::vector<SpatialLayer> spatial_layers =
GetSvcConfig(codec.width, codec.height, codec.maxFramerate,

View File

@ -72,15 +72,14 @@ TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityMode) {
codec.height = 270;
codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY);
// Scalability mode reset, configuration should be in accordance to L2T3_KEY.
// Scalability mode updated.
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::height, 135),
Field(&SpatialLayer::height, 270)));
EXPECT_THAT(spatial_layers,
ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 3),
Field(&SpatialLayer::numberOfTemporalLayers, 3)));
EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOnKeyPic);
EXPECT_EQ(codec.GetScalabilityMode(), absl::nullopt);
EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL2T3_KEY);
}
TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModePortrait) {
@ -90,15 +89,14 @@ TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModePortrait) {
codec.height = 480;
codec.SetScalabilityMode(ScalabilityMode::kL3T1);
// Scalability mode reset, configuration should be in accordance to L2T1.
// Scalability mode updated.
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::width, 135),
Field(&SpatialLayer::width, 270)));
EXPECT_THAT(spatial_layers,
ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 1),
Field(&SpatialLayer::numberOfTemporalLayers, 1)));
EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOn);
EXPECT_EQ(codec.GetScalabilityMode(), absl::nullopt);
EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL2T1);
}
TEST(SvcConfig, NumSpatialLayersWithScalabilityModeResolutionRatio1_5) {
@ -122,15 +120,14 @@ TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModeResolutionRatio1_5) {
codec.codecType = kVideoCodecVP9;
codec.width = 320;
codec.height = 180;
codec.SetScalabilityMode(ScalabilityMode::kL2T1h); // 1.5:1
codec.SetScalabilityMode(ScalabilityMode::kL3T1h); // 1.5:1
// Scalability mode reset, configuration should be in accordance to L1T1.
// Scalability mode updated.
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::width, 320)));
EXPECT_THAT(spatial_layers,
ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 1)));
EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOn);
EXPECT_EQ(codec.GetScalabilityMode(), absl::nullopt);
EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL1T1);
}
TEST(SvcConfig, AlwaysSendsAtLeastOneLayer) {