New enum ScalabilityMode.

Used instead of string representation in lower-levels of encoder configuration, to avoid string comparisons (with risk of misspelling) in lots of places.

Bug: webrtc:11607
Change-Id: I4d51c2265aac297c29976d2aa601d8ffb33b7326
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259870
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36706}
This commit is contained in:
Niels Möller
2022-04-29 11:03:13 +02:00
committed by WebRTC LUCI CQ
parent cbf07f70e2
commit 79d566b0cf
33 changed files with 397 additions and 112 deletions

View File

@ -99,6 +99,7 @@ rtc_library("libaom_av1_encoder_if_supported") {
sources = [ "libaom_av1_encoder_supported.cc" ]
deps = [
"../../../../api/video_codecs:video_codecs_api",
"../../svc:scalability_mode_util",
"../../svc:scalability_structures",
"../../svc:scalable_video_controller",
]
@ -139,6 +140,7 @@ if (rtc_include_tests) {
"../../../../api/units:data_size",
"../../../../api/units:time_delta",
"../../../../api/video:video_frame",
"../../svc:scalability_mode_util",
"../../svc:scalability_structures",
"../../svc:scalable_video_controller",
]

View File

@ -24,16 +24,18 @@ namespace webrtc {
bool SetAv1SvcConfig(VideoCodec& video_codec) {
RTC_DCHECK_EQ(video_codec.codecType, kVideoCodecAV1);
absl::string_view scalability_mode = video_codec.ScalabilityMode();
if (scalability_mode.empty()) {
absl::optional<ScalabilityMode> scalability_mode =
video_codec.GetScalabilityMode();
if (!scalability_mode.has_value()) {
RTC_LOG(LS_WARNING) << "Scalability mode is not set, using 'L1T1'.";
scalability_mode = "L1T1";
scalability_mode = ScalabilityMode::kL1T1;
}
std::unique_ptr<ScalableVideoController> structure =
CreateScalabilityStructure(scalability_mode);
CreateScalabilityStructure(*scalability_mode);
if (structure == nullptr) {
RTC_LOG(LS_WARNING) << "Failed to create structure " << scalability_mode;
RTC_LOG(LS_WARNING) << "Failed to create structure "
<< static_cast<int>(*scalability_mode);
return false;
}

View File

@ -17,22 +17,10 @@
namespace webrtc {
namespace {
TEST(Av1SvcConfigTest, RequireScalabilityMode) {
TEST(Av1SvcConfigTest, TreatsEmptyAsL1T1) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("Unknown");
EXPECT_FALSE(SetAv1SvcConfig(video_codec));
video_codec.SetScalabilityMode("L1T1");
EXPECT_TRUE(SetAv1SvcConfig(video_codec));
}
TEST(Av1SvcConfigTest, TreatsEmptyAsNone) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("");
EXPECT_TRUE(SetAv1SvcConfig(video_codec));
EXPECT_TRUE(video_codec.spatialLayers[0].active);
@ -43,7 +31,7 @@ TEST(Av1SvcConfigTest, TreatsEmptyAsNone) {
TEST(Av1SvcConfigTest, SetsActiveSpatialLayersFromScalabilityMode) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("L2T1");
video_codec.SetScalabilityMode(ScalabilityMode::kL2T1);
EXPECT_TRUE(SetAv1SvcConfig(video_codec));
@ -55,7 +43,7 @@ TEST(Av1SvcConfigTest, SetsActiveSpatialLayersFromScalabilityMode) {
TEST(Av1SvcConfigTest, ConfiguresDobuleResolutionRatioFromScalabilityMode) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("L2T1");
video_codec.SetScalabilityMode(ScalabilityMode::kL2T1);
video_codec.width = 1200;
video_codec.height = 800;
@ -71,7 +59,7 @@ TEST(Av1SvcConfigTest, ConfiguresSmallResolutionRatioFromScalabilityMode) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
// h mode uses 1.5:1 ratio
video_codec.SetScalabilityMode("L2T1h");
video_codec.SetScalabilityMode(ScalabilityMode::kL2T1h);
video_codec.width = 1500;
video_codec.height = 900;
@ -87,7 +75,7 @@ TEST(Av1SvcConfigTest, CopiesFramrate) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
// h mode uses 1.5:1 ratio
video_codec.SetScalabilityMode("L2T1");
video_codec.SetScalabilityMode(ScalabilityMode::kL2T1);
video_codec.maxFramerate = 27;
EXPECT_TRUE(SetAv1SvcConfig(video_codec));
@ -99,7 +87,7 @@ TEST(Av1SvcConfigTest, CopiesFramrate) {
TEST(Av1SvcConfigTest, SetsNumberOfTemporalLayers) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("L1T3");
video_codec.SetScalabilityMode(ScalabilityMode::kL1T3);
EXPECT_TRUE(SetAv1SvcConfig(video_codec));
@ -109,7 +97,7 @@ TEST(Av1SvcConfigTest, SetsNumberOfTemporalLayers) {
TEST(Av1SvcConfigTest, CopiesMinMaxBitrateForSingleSpatialLayer) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("L1T3");
video_codec.SetScalabilityMode(ScalabilityMode::kL1T3);
video_codec.minBitrate = 100;
video_codec.maxBitrate = 500;
@ -126,7 +114,7 @@ TEST(Av1SvcConfigTest, CopiesMinMaxBitrateForSingleSpatialLayer) {
TEST(Av1SvcConfigTest, SetsBitratesForMultipleSpatialLayers) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("L3T3");
video_codec.SetScalabilityMode(ScalabilityMode::kL3T3);
EXPECT_TRUE(SetAv1SvcConfig(video_codec));

View File

@ -169,15 +169,16 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings,
RTC_LOG(LS_WARNING) << "Simulcast is not implemented by LibaomAv1Encoder.";
return result;
}
absl::string_view scalability_mode = encoder_settings_.ScalabilityMode();
if (scalability_mode.empty()) {
absl::optional<ScalabilityMode> scalability_mode =
encoder_settings_.GetScalabilityMode();
if (!scalability_mode.has_value()) {
RTC_LOG(LS_WARNING) << "Scalability mode is not set, using 'L1T1'.";
scalability_mode = "L1T1";
scalability_mode = ScalabilityMode::kL1T1;
}
svc_controller_ = CreateScalabilityStructure(scalability_mode);
svc_controller_ = CreateScalabilityStructure(*scalability_mode);
if (svc_controller_ == nullptr) {
RTC_LOG(LS_WARNING) << "Failed to set scalability mode "
<< scalability_mode;
<< static_cast<int>(*scalability_mode);
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}

View File

@ -10,6 +10,7 @@
#include "modules/video_coding/codecs/av1/libaom_av1_encoder_supported.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#if defined(RTC_USE_LIBAOM_AV1_ENCODER)
#include "modules/video_coding/codecs/av1/libaom_av1_encoder.h" // nogncheck
@ -21,11 +22,14 @@ const bool kIsLibaomAv1EncoderSupported = true;
std::unique_ptr<VideoEncoder> CreateLibaomAv1EncoderIfSupported() {
return CreateLibaomAv1Encoder();
}
bool LibaomAv1EncoderSupportsScalabilityMode(
absl::string_view scalability_mode) {
bool LibaomAv1EncoderSupportsScalabilityMode(absl::string_view mode_string) {
absl::optional<ScalabilityMode> scalability_mode =
ScalabilityModeFromString(mode_string);
// For libaom AV1, the scalability mode is supported if we can create the
// scalability structure.
return ScalabilityStructureConfig(scalability_mode) != absl::nullopt;
return scalability_mode.has_value() &&
ScalabilityStructureConfig(*scalability_mode) != absl::nullopt;
}
#else
const bool kIsLibaomAv1EncoderSupported = false;

View File

@ -64,7 +64,7 @@ TEST(LibaomAv1EncoderTest, NoBitrateOnTopLayerRefecltedInActiveDecodeTargets) {
// Configure encoder with 2 temporal layers.
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.SetScalabilityMode("L1T2");
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T2);
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
@ -90,7 +90,7 @@ TEST(LibaomAv1EncoderTest,
SpatialScalabilityInTemporalUnitReportedAsDeltaFrame) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.SetScalabilityMode("L2T1");
codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
@ -112,7 +112,7 @@ TEST(LibaomAv1EncoderTest,
TEST(LibaomAv1EncoderTest, NoBitrateOnTopSpatialLayerProduceDeltaFrames) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.SetScalabilityMode("L2T1");
codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
@ -140,7 +140,7 @@ TEST(LibaomAv1EncoderTest, SetsEndOfPictureForLastFrameInTemporalUnit) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
// Configure encoder with 3 spatial layers.
codec_settings.SetScalabilityMode("L3T1");
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
codec_settings.maxBitrate = allocation.get_sum_kbps();
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
@ -167,7 +167,7 @@ TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
// Configure encoder with 3 spatial layers.
codec_settings.SetScalabilityMode("L3T1");
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
// Odd width and height values should not make encoder crash.
codec_settings.width = 623;
codec_settings.height = 405;
@ -186,7 +186,7 @@ TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) {
TEST(LibaomAv1EncoderTest, EncoderInfoProvidesFpsAllocation) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.SetScalabilityMode("L3T3");
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T3);
codec_settings.maxFramerate = 60;
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
@ -208,7 +208,7 @@ TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) {
codec_settings.maxBitrate = allocation.get_sum_kbps();
ASSERT_GT(codec_settings.width, 4);
// Configure encoder with 3 spatial layers.
codec_settings.SetScalabilityMode("L3T1");
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
encoder->SetRates(VideoEncoder::RateControlParameters(

View File

@ -28,6 +28,7 @@
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
#include "test/gmock.h"
@ -55,7 +56,7 @@ constexpr int kFramerate = 30;
VideoCodec DefaultCodecSettings() {
VideoCodec codec_settings;
codec_settings.SetScalabilityMode("L1T1");
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
codec_settings.width = kWidth;
codec_settings.height = kHeight;
codec_settings.maxFramerate = kFramerate;
@ -175,6 +176,13 @@ struct LayerId {
};
struct SvcTestParam {
ScalabilityMode GetScalabilityMode() const {
absl::optional<ScalabilityMode> scalability_mode =
ScalabilityModeFromString(name);
RTC_CHECK(scalability_mode.has_value());
return *scalability_mode;
}
std::string name;
int num_frames_to_generate;
std::map<LayerId, DataRate> configured_bitrates;
@ -185,7 +193,7 @@ class LibaomAv1SvcTest : public ::testing::TestWithParam<SvcTestParam> {};
TEST_P(LibaomAv1SvcTest, EncodeAndDecodeAllDecodeTargets) {
const SvcTestParam param = GetParam();
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(param.name);
CreateScalabilityStructure(param.GetScalabilityMode());
ASSERT_TRUE(svc_controller);
VideoBitrateAllocation allocation;
if (param.configured_bitrates.empty()) {
@ -208,7 +216,7 @@ TEST_P(LibaomAv1SvcTest, EncodeAndDecodeAllDecodeTargets) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.SetScalabilityMode(GetParam().name);
codec_settings.SetScalabilityMode(GetParam().GetScalabilityMode());
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
encoder->SetRates(VideoEncoder::RateControlParameters(
@ -278,7 +286,7 @@ TEST_P(LibaomAv1SvcTest, SetRatesMatchMeasuredBitrate) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
ASSERT_TRUE(encoder);
VideoCodec codec_settings = DefaultCodecSettings();
codec_settings.SetScalabilityMode(param.name);
codec_settings.SetScalabilityMode(param.GetScalabilityMode());
codec_settings.maxBitrate = allocation.get_sum_kbps();
codec_settings.maxFramerate = 30;
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),

View File

@ -52,7 +52,7 @@ TEST_P(VideoCodecTestAv1, HighBitrate) {
auto config = CreateConfig("foreman_cif");
config.SetCodecSettings(cricket::kAv1CodecName, 1, 1, 1, false, true, true,
kCifWidth, kCifHeight);
config.codec_settings.SetScalabilityMode("L1T1");
config.codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
config.num_frames = kNumFramesLong;
auto fixture = CreateVideoCodecTestFixture(config);
@ -70,7 +70,7 @@ TEST_P(VideoCodecTestAv1, VeryLowBitrate) {
auto config = CreateConfig("foreman_cif");
config.SetCodecSettings(cricket::kAv1CodecName, 1, 1, 1, false, true, true,
kCifWidth, kCifHeight);
config.codec_settings.SetScalabilityMode("L1T1");
config.codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {{50, 30, 0}};
@ -90,7 +90,7 @@ TEST_P(VideoCodecTestAv1, Hd) {
auto config = CreateConfig("ConferenceMotion_1280_720_50");
config.SetCodecSettings(cricket::kAv1CodecName, 1, 1, 1, false, true, true,
kHdWidth, kHdHeight);
config.codec_settings.SetScalabilityMode("L1T1");
config.codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
config.num_frames = kNumFramesLong;
auto fixture = CreateVideoCodecTestFixture(config);

View File

@ -27,6 +27,7 @@
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
#include "modules/video_coding/svc/svc_rate_allocator.h"
@ -142,7 +143,14 @@ std::unique_ptr<ScalableVideoController> CreateVp9ScalabilityStructure(
}
}
auto scalability_structure_controller = CreateScalabilityStructure(name);
absl::optional<ScalabilityMode> scalability_mode =
ScalabilityModeFromString(name);
if (!scalability_mode.has_value()) {
RTC_LOG(LS_WARNING) << "Invalid scalability mode " << name;
return nullptr;
}
auto scalability_structure_controller =
CreateScalabilityStructure(*scalability_mode);
if (scalability_structure_controller == nullptr) {
RTC_LOG(LS_WARNING) << "Unsupported scalability structure " << name;
} else {