Add support for VP9 configuration through scalability mode.

Bug: webrtc:13960
Change-Id: Ia930647b15f624a4d10d8d335519b69ffdae6636
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260983
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36919}
This commit is contained in:
Asa Persson
2022-05-16 22:37:34 +02:00
committed by WebRTC LUCI CQ
parent 15a73be295
commit cde992ddad
12 changed files with 435 additions and 83 deletions

View File

@ -14,8 +14,12 @@
#include <vector>
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
#include "test/gmock.h"
#include "test/gtest.h"
using ::testing::ElementsAre;
using ::testing::Field;
namespace webrtc {
TEST(SvcConfig, NumSpatialLayers) {
const size_t max_num_spatial_layers = 6;
@ -43,6 +47,92 @@ TEST(SvcConfig, NumSpatialLayersPortrait) {
EXPECT_EQ(spatial_layers.size(), num_spatial_layers);
}
TEST(SvcConfig, NumSpatialLayersWithScalabilityMode) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 960;
codec.height = 540;
codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY);
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::height, 135),
Field(&SpatialLayer::height, 270),
Field(&SpatialLayer::height, 540)));
EXPECT_THAT(spatial_layers,
ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 3),
Field(&SpatialLayer::numberOfTemporalLayers, 3),
Field(&SpatialLayer::numberOfTemporalLayers, 3)));
EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL3T3_KEY);
}
TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityMode) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 480;
codec.height = 270;
codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY);
// Scalability mode reset, configuration should be in accordance to L2T3_KEY.
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);
}
TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModePortrait) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 270;
codec.height = 480;
codec.SetScalabilityMode(ScalabilityMode::kL3T1);
// Scalability mode reset, configuration should be in accordance to L2T1.
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);
}
TEST(SvcConfig, NumSpatialLayersWithScalabilityModeResolutionRatio1_5) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 270;
codec.height = 480;
codec.SetScalabilityMode(ScalabilityMode::kL2T1h); // 1.5:1
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::width, 180),
Field(&SpatialLayer::width, 270)));
EXPECT_THAT(spatial_layers,
ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 1),
Field(&SpatialLayer::numberOfTemporalLayers, 1)));
EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL2T1h);
}
TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModeResolutionRatio1_5) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 320;
codec.height = 180;
codec.SetScalabilityMode(ScalabilityMode::kL2T1h); // 1.5:1
// Scalability mode reset, configuration should be in accordance to L1T1.
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);
}
TEST(SvcConfig, AlwaysSendsAtLeastOneLayer) {
const size_t max_num_spatial_layers = 6;
const size_t first_active_layer = 5;
@ -91,6 +181,44 @@ TEST(SvcConfig, EnforcesMinimalRequiredParity) {
EXPECT_EQ(spatial_layers.back().width, kOddSize);
}
TEST(SvcConfig, EnforcesMinimalRequiredParityWithScalabilityMode) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 1023;
codec.height = 1023;
codec.SetScalabilityMode(ScalabilityMode::kL3T1);
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, // Divisiblity by 4 required.
ElementsAre(Field(&SpatialLayer::width, 255),
Field(&SpatialLayer::width, 510),
Field(&SpatialLayer::width, 1020)));
codec.SetScalabilityMode(ScalabilityMode::kL2T1);
spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, // Divisiblity by 2 required.
ElementsAre(Field(&SpatialLayer::width, 511),
Field(&SpatialLayer::width, 1022)));
codec.SetScalabilityMode(ScalabilityMode::kL1T1);
spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, // Divisiblity by 1 required.
ElementsAre(Field(&SpatialLayer::width, 1023)));
}
TEST(SvcConfig, EnforcesMinimalRequiredParityWithScalabilityModeResRatio1_5) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 1280;
codec.height = 1280;
codec.SetScalabilityMode(ScalabilityMode::kL2T1h); // 1.5:1
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, // Divisiblity by 3 required.
ElementsAre(Field(&SpatialLayer::width, 852),
Field(&SpatialLayer::width, 1278)));
}
TEST(SvcConfig, SkipsInactiveLayers) {
const size_t num_spatial_layers = 4;
const size_t first_active_layer = 2;
@ -121,6 +249,25 @@ TEST(SvcConfig, BitrateThresholds) {
}
}
TEST(SvcConfig, BitrateThresholdsWithScalabilityMode) {
VideoCodec codec;
codec.codecType = kVideoCodecVP9;
codec.width = 960;
codec.height = 540;
codec.SetScalabilityMode(ScalabilityMode::kS3T3);
std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec);
EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::height, 135),
Field(&SpatialLayer::height, 270),
Field(&SpatialLayer::height, 540)));
for (const SpatialLayer& layer : spatial_layers) {
EXPECT_LE(layer.minBitrate, layer.maxBitrate);
EXPECT_LE(layer.minBitrate, layer.targetBitrate);
EXPECT_LE(layer.targetBitrate, layer.maxBitrate);
}
}
TEST(SvcConfig, ScreenSharing) {
std::vector<SpatialLayer> spatial_layers =
GetSvcConfig(1920, 1080, 30, 1, 3, 3, true);