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

@ -12,6 +12,10 @@ if (is_android) {
import("//build/config/android/rules.gni")
}
rtc_source_set("scalability_mode") {
sources = [ "scalability_mode.h" ]
}
rtc_library("video_codecs_api") {
visibility = [ "*" ]
sources = [
@ -41,6 +45,7 @@ rtc_library("video_codecs_api") {
]
deps = [
":scalability_mode",
"..:fec_controller_api",
"..:scoped_refptr",
"../../api:array_view",
@ -153,7 +158,9 @@ rtc_source_set("video_encoder_factory_template_libaom_av1_adapter") {
public = [ "video_encoder_factory_template_libaom_av1_adapter.h" ]
deps = [
":scalability_mode",
"../../modules/video_coding/codecs/av1:libaom_av1_encoder",
"../../modules/video_coding/svc:scalability_mode_util",
"../../modules/video_coding/svc:scalability_structures",
]
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef API_VIDEO_CODECS_SCALABILITY_MODE_H_
#define API_VIDEO_CODECS_SCALABILITY_MODE_H_
namespace webrtc {
// Supported scalability modes. Most applications should use the
// PeerConnection-level apis where scalability mode is represented as a string.
// This list of currently recognized modes is intended for the api boundary
// between webrtc and injected encoders. Any application usage outside of
// injected encoders is strongly discouraged.
enum class ScalabilityMode {
kL1T1,
kL1T2,
kL1T3,
kL2T1,
kL2T1h,
kL2T1_KEY,
kL2T2,
kL2T2_KEY,
kL2T2_KEY_SHIFT,
kL2T3_KEY,
kL3T1,
kL3T3,
kL3T3_KEY,
kS2T1,
kS3T3,
};
} // namespace webrtc
#endif // API_VIDEO_CODECS_SCALABILITY_MODE_H_

View File

@ -19,6 +19,7 @@
#include "absl/strings/string_view.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/scalability_mode.h"
#include "api/video_codecs/spatial_layer.h"
#include "rtc_base/system/rtc_export.h"
@ -104,11 +105,13 @@ class RTC_EXPORT VideoCodec {
// Scalability mode as described in
// https://www.w3.org/TR/webrtc-svc/#scalabilitymodes*
// or value 'NONE' to indicate no scalability.
absl::string_view ScalabilityMode() const { return scalability_mode_; }
void SetScalabilityMode(absl::string_view scalability_mode) {
scalability_mode_ = std::string(scalability_mode);
absl::optional<ScalabilityMode> GetScalabilityMode() const {
return scalability_mode_;
}
void SetScalabilityMode(ScalabilityMode scalability_mode) {
scalability_mode_ = scalability_mode;
}
void UnsetScalabilityMode() { scalability_mode_ = absl::nullopt; }
VideoCodecComplexity GetVideoEncoderComplexity() const;
void SetVideoEncoderComplexity(VideoCodecComplexity complexity_setting);
@ -172,7 +175,7 @@ class RTC_EXPORT VideoCodec {
// TODO(hta): Consider replacing the union with a pointer type.
// This will allow removing the VideoCodec* types from this file.
VideoCodecUnion codec_specific_;
std::string scalability_mode_;
absl::optional<ScalabilityMode> scalability_mode_;
// 'complexity_' indicates the CPU capability of the client. It's used to
// determine encoder CPU complexity (e.g., cpu_used for VP8, VP9. and AV1).
absl::optional<VideoCodecComplexity> complexity_;

View File

@ -18,6 +18,7 @@
#include "absl/types/optional.h"
#include "api/scoped_refptr.h"
#include "api/video_codecs/scalability_mode.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "rtc_base/ref_count.h"
@ -64,7 +65,7 @@ struct VideoStream {
// between multiple streams.
absl::optional<double> bitrate_priority;
absl::optional<std::string> scalability_mode;
absl::optional<ScalabilityMode> scalability_mode;
// If this stream is enabled by the user, or not.
bool active;

View File

@ -16,6 +16,7 @@
#include "modules/video_coding/codecs/av1/libaom_av1_encoder.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
namespace webrtc {
struct LibaomAv1EncoderTemplateAdapter {
@ -28,10 +29,13 @@ struct LibaomAv1EncoderTemplateAdapter {
return CreateLibaomAv1Encoder();
}
static bool IsScalabilityModeSupported(absl::string_view scalability_mode) {
static bool IsScalabilityModeSupported(absl::string_view mode_string) {
// For libaom AV1, the scalability mode is supported if we can create the
// scalability structure.
return ScalabilityStructureConfig(scalability_mode) != absl::nullopt;
absl::optional<ScalabilityMode> scalability_mode =
ScalabilityModeFromString(mode_string);
return scalability_mode != absl::nullopt &&
ScalabilityStructureConfig(*scalability_mode) != absl::nullopt;
}
};

View File

@ -291,6 +291,7 @@ rtc_library("rtc_audio_video") {
"../modules/video_coding",
"../modules/video_coding:video_codec_interface",
"../modules/video_coding:video_coding_utility",
"../modules/video_coding/svc:scalability_mode_util",
"../rtc_base",
"../rtc_base:audio_format_to_string",
"../rtc_base:buffer",

View File

@ -32,6 +32,7 @@
#include "media/engine/webrtc_media_engine.h"
#include "media/engine/webrtc_voice_engine.h"
#include "modules/rtp_rtcp/source/rtp_util.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/experiments/field_trial_units.h"
@ -2476,7 +2477,8 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig(
encoder_config.simulcast_layers[i].active =
rtp_parameters_.encodings[i].active;
encoder_config.simulcast_layers[i].scalability_mode =
rtp_parameters_.encodings[i].scalability_mode;
webrtc::ScalabilityModeFromString(
rtp_parameters_.encodings[i].scalability_mode.value_or(""));
if (rtp_parameters_.encodings[i].min_bitrate_bps) {
encoder_config.simulcast_layers[i].min_bitrate_bps =
*rtp_parameters_.encodings[i].min_bitrate_bps;

View File

@ -804,6 +804,7 @@ rtc_library("webrtc_vp9") {
"../../rtc_base/synchronization:mutex",
"../../system_wrappers:field_trial",
"../rtp_rtcp:rtp_rtcp_format",
"svc:scalability_mode_util",
"svc:scalability_structures",
"svc:scalable_video_controller",
"svc:svc_rate_allocator",

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 {

View File

@ -8,6 +8,21 @@
import("../../../webrtc.gni")
rtc_source_set("scalability_mode_util") {
sources = [
"scalability_mode_util.cc",
"scalability_mode_util.h",
]
deps = [
"../../../api/video_codecs:scalability_mode",
"../../../rtc_base:checks",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_source_set("scalable_video_controller") {
sources = [
"scalable_video_controller.h",
@ -43,6 +58,7 @@ rtc_source_set("scalability_structures") {
":scalable_video_controller",
"../../../api/transport/rtp:dependency_descriptor",
"../../../api/video:video_bitrate_allocation",
"../../../api/video_codecs:scalability_mode",
"../../../common_video/generic_frame_descriptor",
"../../../rtc_base:checks",
"../../../rtc_base:logging",
@ -75,6 +91,7 @@ if (rtc_include_tests) {
rtc_source_set("scalability_structure_tests") {
testonly = true
sources = [
"scalability_mode_util_unittest.cc",
"scalability_structure_full_svc_unittest.cc",
"scalability_structure_key_svc_unittest.cc",
"scalability_structure_l2t2_key_shift_unittest.cc",
@ -83,6 +100,7 @@ if (rtc_include_tests) {
"scalability_structure_unittest.cc",
]
deps = [
":scalability_mode_util",
":scalability_structures",
":scalable_video_controller",
"..:chain_diff_calculator",
@ -91,10 +109,14 @@ if (rtc_include_tests) {
"../../../api/transport/rtp:dependency_descriptor",
"../../../api/video:video_bitrate_allocation",
"../../../api/video:video_frame_type",
"../../../api/video_codecs:scalability_mode",
"../../../common_video/generic_frame_descriptor",
"../../../test:test_support",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_source_set("svc_rate_allocator_tests") {

View File

@ -11,7 +11,7 @@
#include <memory>
#include "absl/strings/string_view.h"
#include "api/video_codecs/scalability_mode.h"
#include "modules/video_coding/svc/scalability_structure_full_svc.h"
#include "modules/video_coding/svc/scalability_structure_key_svc.h"
#include "modules/video_coding/svc/scalability_structure_l2t2_key_shift.h"
@ -24,7 +24,7 @@ namespace webrtc {
namespace {
struct NamedStructureFactory {
absl::string_view name;
ScalabilityMode name;
// Use function pointer to make NamedStructureFactory trivally destructable.
std::unique_ptr<ScalableVideoController> (*factory)();
ScalableVideoController::StreamLayersConfig config;
@ -114,28 +114,33 @@ constexpr ScalableVideoController::StreamLayersConfig kConfigS3T3 = {
{4, 2, 1}};
constexpr NamedStructureFactory kFactories[] = {
{"L1T1", Create<ScalableVideoControllerNoLayering>, kConfigL1T1},
{"L1T2", Create<ScalabilityStructureL1T2>, kConfigL1T2},
{"L1T3", Create<ScalabilityStructureL1T3>, kConfigL1T3},
{"L2T1", Create<ScalabilityStructureL2T1>, kConfigL2T1},
{"L2T1h", CreateH<ScalabilityStructureL2T1>, kConfigL2T1h},
{"L2T1_KEY", Create<ScalabilityStructureL2T1Key>, kConfigL2T1},
{"L2T2", Create<ScalabilityStructureL2T2>, kConfigL2T2},
{"L2T2_KEY", Create<ScalabilityStructureL2T2Key>, kConfigL2T2},
{"L2T2_KEY_SHIFT", Create<ScalabilityStructureL2T2KeyShift>, kConfigL2T2},
{"L2T3_KEY", Create<ScalabilityStructureL2T3Key>, kConfigL2T3},
{"L3T1", Create<ScalabilityStructureL3T1>, kConfigL3T1},
{"L3T3", Create<ScalabilityStructureL3T3>, kConfigL3T3},
{"L3T3_KEY", Create<ScalabilityStructureL3T3Key>, kConfigL3T3},
{"S2T1", Create<ScalabilityStructureS2T1>, kConfigS2T1},
{"S3T3", Create<ScalabilityStructureS3T3>, kConfigS3T3},
{ScalabilityMode::kL1T1, Create<ScalableVideoControllerNoLayering>,
kConfigL1T1},
{ScalabilityMode::kL1T2, Create<ScalabilityStructureL1T2>, kConfigL1T2},
{ScalabilityMode::kL1T3, Create<ScalabilityStructureL1T3>, kConfigL1T3},
{ScalabilityMode::kL2T1, Create<ScalabilityStructureL2T1>, kConfigL2T1},
{ScalabilityMode::kL2T1h, CreateH<ScalabilityStructureL2T1>, kConfigL2T1h},
{ScalabilityMode::kL2T1_KEY, Create<ScalabilityStructureL2T1Key>,
kConfigL2T1},
{ScalabilityMode::kL2T2, Create<ScalabilityStructureL2T2>, kConfigL2T2},
{ScalabilityMode::kL2T2_KEY, Create<ScalabilityStructureL2T2Key>,
kConfigL2T2},
{ScalabilityMode::kL2T2_KEY_SHIFT, Create<ScalabilityStructureL2T2KeyShift>,
kConfigL2T2},
{ScalabilityMode::kL2T3_KEY, Create<ScalabilityStructureL2T3Key>,
kConfigL2T3},
{ScalabilityMode::kL3T1, Create<ScalabilityStructureL3T1>, kConfigL3T1},
{ScalabilityMode::kL3T3, Create<ScalabilityStructureL3T3>, kConfigL3T3},
{ScalabilityMode::kL3T3_KEY, Create<ScalabilityStructureL3T3Key>,
kConfigL3T3},
{ScalabilityMode::kS2T1, Create<ScalabilityStructureS2T1>, kConfigS2T1},
{ScalabilityMode::kS3T3, Create<ScalabilityStructureS3T3>, kConfigS3T3},
};
} // namespace
std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
absl::string_view name) {
RTC_DCHECK(!name.empty());
ScalabilityMode name) {
for (const auto& entry : kFactories) {
if (entry.name == name) {
return entry.factory();
@ -145,8 +150,7 @@ std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
}
absl::optional<ScalableVideoController::StreamLayersConfig>
ScalabilityStructureConfig(absl::string_view name) {
RTC_DCHECK(!name.empty());
ScalabilityStructureConfig(ScalabilityMode name) {
for (const auto& entry : kFactories) {
if (entry.name == name) {
return entry.config;

View File

@ -13,8 +13,8 @@
#include <memory>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/video_codecs/scalability_mode.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
namespace webrtc {
@ -23,12 +23,12 @@ namespace webrtc {
// https://w3c.github.io/webrtc-svc/#scalabilitymodes*
// Returns nullptr for unknown name.
std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
absl::string_view name);
ScalabilityMode name);
// Returns descrption of the scalability structure identified by 'name',
// Returns description of the scalability structure identified by 'name',
// Return nullopt for unknown name.
absl::optional<ScalableVideoController::StreamLayersConfig>
ScalabilityStructureConfig(absl::string_view name);
ScalabilityStructureConfig(ScalabilityMode name);
} // namespace webrtc

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/video_codecs/scalability_mode.h"
#include "rtc_base/checks.h"
namespace webrtc {
absl::optional<ScalabilityMode> ScalabilityModeFromString(
absl::string_view mode_string) {
if (mode_string == "L1T1")
return ScalabilityMode::kL1T1;
if (mode_string == "L1T2")
return ScalabilityMode::kL1T2;
if (mode_string == "L1T3")
return ScalabilityMode::kL1T3;
if (mode_string == "L2T1")
return ScalabilityMode::kL2T1;
if (mode_string == "L2T1h")
return ScalabilityMode::kL2T1h;
if (mode_string == "L2T1_KEY")
return ScalabilityMode::kL2T1_KEY;
if (mode_string == "L2T2")
return ScalabilityMode::kL2T2;
if (mode_string == "L2T2_KEY")
return ScalabilityMode::kL2T2_KEY;
if (mode_string == "L2T2_KEY_SHIFT")
return ScalabilityMode::kL2T2_KEY_SHIFT;
if (mode_string == "L2T3_KEY")
return ScalabilityMode::kL2T3_KEY;
if (mode_string == "L3T1")
return ScalabilityMode::kL3T1;
if (mode_string == "L3T3")
return ScalabilityMode::kL3T3;
if (mode_string == "L3T3_KEY")
return ScalabilityMode::kL3T3_KEY;
if (mode_string == "S2T1")
return ScalabilityMode::kS2T1;
if (mode_string == "S3T3")
return ScalabilityMode::kS3T3;
return absl::nullopt;
}
absl::string_view ScalabilityModeToString(ScalabilityMode scalability_mode) {
switch (scalability_mode) {
case ScalabilityMode::kL1T1:
return "L1T1";
case ScalabilityMode::kL1T2:
return "L1T2";
case ScalabilityMode::kL1T3:
return "L1T3";
case ScalabilityMode::kL2T1:
return "L2T1";
case ScalabilityMode::kL2T1h:
return "L2T1h";
case ScalabilityMode::kL2T1_KEY:
return "L2T1_KEY";
case ScalabilityMode::kL2T2:
return "L2T2";
case ScalabilityMode::kL2T2_KEY:
return "L2T2_KEY";
case ScalabilityMode::kL2T2_KEY_SHIFT:
return "L2T2_KEY_SHIFT";
case ScalabilityMode::kL2T3_KEY:
return "L2T3_KEY";
case ScalabilityMode::kL3T1:
return "L3T1";
case ScalabilityMode::kL3T3:
return "L3T3";
case ScalabilityMode::kL3T3_KEY:
return "L3T3_KEY";
case ScalabilityMode::kS2T1:
return "S2T1";
case ScalabilityMode::kS3T3:
return "S3T3";
}
RTC_CHECK_NOTREACHED();
}
} // namespace webrtc

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_VIDEO_CODING_SVC_SCALABILITY_MODE_UTIL_H_
#define MODULES_VIDEO_CODING_SVC_SCALABILITY_MODE_UTIL_H_
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/video_codecs/scalability_mode.h"
namespace webrtc {
absl::optional<ScalabilityMode> ScalabilityModeFromString(
absl::string_view scalability_mode_string);
absl::string_view ScalabilityModeToString(ScalabilityMode scalability_mode);
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_SVC_SCALABILITY_MODE_UTIL_H_

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/video_codecs/scalability_mode.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
TEST(ScalabilityModeUtil, ConvertsL1T2) {
EXPECT_EQ(ScalabilityModeFromString("L1T2"), ScalabilityMode::kL1T2);
EXPECT_EQ(ScalabilityModeToString(ScalabilityMode::kL1T2), "L1T2");
}
TEST(ScalabilityModeUtil, RejectsUnknownString) {
EXPECT_EQ(ScalabilityModeFromString(""), absl::nullopt);
EXPECT_EQ(ScalabilityModeFromString("not-a-mode"), absl::nullopt);
}
// Check roundtrip conversion of all enum values.
TEST(ScalabilityModeUtil, ConvertsAllToAndFromString) {
const ScalabilityMode kLastEnum = ScalabilityMode::kS3T3;
for (int numerical_enum = 0; numerical_enum <= static_cast<int>(kLastEnum);
numerical_enum++) {
ScalabilityMode scalability_mode =
static_cast<ScalabilityMode>(numerical_enum);
absl::string_view scalability_mode_string =
ScalabilityModeToString(scalability_mode);
EXPECT_FALSE(scalability_mode_string.empty());
EXPECT_EQ(ScalabilityModeFromString(scalability_mode_string),
scalability_mode);
}
}
} // namespace
} // namespace webrtc

View File

@ -19,6 +19,7 @@
#include "api/array_view.h"
#include "api/transport/rtp/dependency_descriptor.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "modules/video_coding/svc/scalability_structure_test_helpers.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "test/gmock.h"
@ -47,6 +48,13 @@ struct SvcTestParam {
return os << param.name;
}
ScalabilityMode GetScalabilityMode() const {
absl::optional<ScalabilityMode> scalability_mode =
ScalabilityModeFromString(name);
RTC_CHECK(scalability_mode.has_value());
return *scalability_mode;
}
std::string name;
int num_temporal_units;
};
@ -56,9 +64,9 @@ class ScalabilityStructureTest : public TestWithParam<SvcTestParam> {};
TEST_P(ScalabilityStructureTest,
StaticConfigMatchesConfigReturnedByController) {
std::unique_ptr<ScalableVideoController> controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
absl::optional<ScalableVideoController::StreamLayersConfig> static_config =
ScalabilityStructureConfig(GetParam().name);
ScalabilityStructureConfig(GetParam().GetScalabilityMode());
ASSERT_THAT(controller, NotNull());
ASSERT_NE(static_config, absl::nullopt);
ScalableVideoController::StreamLayersConfig config =
@ -78,7 +86,8 @@ TEST_P(ScalabilityStructureTest,
TEST_P(ScalabilityStructureTest,
NumberOfDecodeTargetsAndChainsAreInRangeAndConsistent) {
FrameDependencyStructure structure =
CreateScalabilityStructure(GetParam().name)->DependencyStructure();
CreateScalabilityStructure(GetParam().GetScalabilityMode())
->DependencyStructure();
EXPECT_GT(structure.num_decode_targets, 0);
EXPECT_LE(structure.num_decode_targets,
DependencyDescriptor::kMaxDecodeTargets);
@ -97,7 +106,8 @@ TEST_P(ScalabilityStructureTest,
TEST_P(ScalabilityStructureTest, TemplatesAreSortedByLayerId) {
FrameDependencyStructure structure =
CreateScalabilityStructure(GetParam().name)->DependencyStructure();
CreateScalabilityStructure(GetParam().GetScalabilityMode())
->DependencyStructure();
ASSERT_THAT(structure.templates, Not(IsEmpty()));
const auto& first_templates = structure.templates.front();
EXPECT_EQ(first_templates.spatial_id, 0);
@ -128,7 +138,8 @@ TEST_P(ScalabilityStructureTest, TemplatesAreSortedByLayerId) {
TEST_P(ScalabilityStructureTest, TemplatesMatchNumberOfDecodeTargetsAndChains) {
FrameDependencyStructure structure =
CreateScalabilityStructure(GetParam().name)->DependencyStructure();
CreateScalabilityStructure(GetParam().GetScalabilityMode())
->DependencyStructure();
EXPECT_THAT(
structure.templates,
Each(AllOf(Field(&FrameDependencyTemplate::decode_target_indications,
@ -139,7 +150,7 @@ TEST_P(ScalabilityStructureTest, TemplatesMatchNumberOfDecodeTargetsAndChains) {
TEST_P(ScalabilityStructureTest, FrameInfoMatchesFrameDependencyStructure) {
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
FrameDependencyStructure structure = svc_controller->DependencyStructure();
std::vector<GenericFrameInfo> frame_infos =
ScalabilityStructureWrapper(*svc_controller)
@ -158,7 +169,7 @@ TEST_P(ScalabilityStructureTest, FrameInfoMatchesFrameDependencyStructure) {
TEST_P(ScalabilityStructureTest, ThereIsAPerfectTemplateForEachFrame) {
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
FrameDependencyStructure structure = svc_controller->DependencyStructure();
std::vector<GenericFrameInfo> frame_infos =
ScalabilityStructureWrapper(*svc_controller)
@ -171,7 +182,7 @@ TEST_P(ScalabilityStructureTest, ThereIsAPerfectTemplateForEachFrame) {
TEST_P(ScalabilityStructureTest, FrameDependsOnSameOrLowerLayer) {
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
std::vector<GenericFrameInfo> frame_infos =
ScalabilityStructureWrapper(*svc_controller)
.GenerateFrames(GetParam().num_temporal_units);
@ -192,7 +203,7 @@ TEST_P(ScalabilityStructureTest, FrameDependsOnSameOrLowerLayer) {
TEST_P(ScalabilityStructureTest, NoFrameDependsOnDiscardableOrNotPresent) {
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
std::vector<GenericFrameInfo> frame_infos =
ScalabilityStructureWrapper(*svc_controller)
.GenerateFrames(GetParam().num_temporal_units);
@ -224,7 +235,7 @@ TEST_P(ScalabilityStructureTest, NoFrameDependsOnDiscardableOrNotPresent) {
TEST_P(ScalabilityStructureTest, NoFrameDependsThroughSwitchIndication) {
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
FrameDependencyStructure structure = svc_controller->DependencyStructure();
std::vector<GenericFrameInfo> frame_infos =
ScalabilityStructureWrapper(*svc_controller)
@ -277,7 +288,7 @@ TEST_P(ScalabilityStructureTest, NoFrameDependsThroughSwitchIndication) {
TEST_P(ScalabilityStructureTest, ProduceNoFrameForDisabledLayers) {
std::unique_ptr<ScalableVideoController> svc_controller =
CreateScalabilityStructure(GetParam().name);
CreateScalabilityStructure(GetParam().GetScalabilityMode());
ScalableVideoController::StreamLayersConfig structure =
svc_controller->StreamConfig();

View File

@ -174,8 +174,10 @@ DataRate FindLayerTogglingThreshold(const VideoCodec& codec,
SvcRateAllocator::NumLayers SvcRateAllocator::GetNumLayers(
const VideoCodec& codec) {
NumLayers layers;
if (!codec.ScalabilityMode().empty()) {
if (auto structure = CreateScalabilityStructure(codec.ScalabilityMode())) {
if (absl::optional<ScalabilityMode> scalability_mode =
codec.GetScalabilityMode();
scalability_mode.has_value()) {
if (auto structure = CreateScalabilityStructure(*scalability_mode)) {
ScalableVideoController::StreamLayersConfig config =
structure->StreamConfig();
layers.spatial = config.num_spatial_layers;

View File

@ -275,7 +275,7 @@ TEST(SvcRateAllocatorTest, SupportsAv1) {
codec.width = 640;
codec.height = 360;
codec.codecType = kVideoCodecAV1;
codec.SetScalabilityMode("L3T3");
codec.SetScalabilityMode(ScalabilityMode::kL3T3);
codec.spatialLayers[0].active = true;
codec.spatialLayers[0].minBitrate = 30;
codec.spatialLayers[0].targetBitrate = 51;
@ -304,7 +304,7 @@ TEST(SvcRateAllocatorTest, SupportsAv1WithSkippedLayer) {
codec.width = 640;
codec.height = 360;
codec.codecType = kVideoCodecAV1;
codec.SetScalabilityMode("L3T3");
codec.SetScalabilityMode(ScalabilityMode::kL3T3);
codec.spatialLayers[0].active = false;
codec.spatialLayers[0].minBitrate = 30;
codec.spatialLayers[0].targetBitrate = 51;
@ -333,7 +333,7 @@ TEST(SvcRateAllocatorTest, UsesScalabilityModeToGetNumberOfLayers) {
codec.width = 640;
codec.height = 360;
codec.codecType = kVideoCodecAV1;
codec.SetScalabilityMode("L2T2");
codec.SetScalabilityMode(ScalabilityMode::kL2T2);
codec.spatialLayers[0].active = true;
codec.spatialLayers[0].minBitrate = 30;
codec.spatialLayers[0].targetBitrate = 51;

View File

@ -94,7 +94,8 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
int max_framerate = 0;
absl::optional<std::string> scalability_mode = streams[0].scalability_mode;
absl::optional<ScalabilityMode> scalability_mode =
streams[0].scalability_mode;
for (size_t i = 0; i < streams.size(); ++i) {
SpatialLayer* sim_stream = &video_codec.simulcastStream[i];
RTC_DCHECK_GT(streams[i].width, 0);

View File

@ -430,7 +430,7 @@ TEST_F(VideoCodecInitializerTest, Av1SingleSpatialLayerBitratesAreConsistent) {
VideoEncoderConfig config;
config.codec_type = VideoCodecType::kVideoCodecAV1;
std::vector<VideoStream> streams = {DefaultStream()};
streams[0].scalability_mode = "L1T2";
streams[0].scalability_mode = ScalabilityMode::kL1T2;
VideoCodec codec;
EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
@ -445,7 +445,7 @@ TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersBitratesAreConsistent) {
VideoEncoderConfig config;
config.codec_type = VideoCodecType::kVideoCodecAV1;
std::vector<VideoStream> streams = {DefaultStream()};
streams[0].scalability_mode = "L2T2";
streams[0].scalability_mode = ScalabilityMode::kL2T2;
VideoCodec codec;
EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
@ -465,7 +465,7 @@ TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersActiveByDefault) {
VideoEncoderConfig config;
config.codec_type = VideoCodecType::kVideoCodecAV1;
std::vector<VideoStream> streams = {DefaultStream()};
streams[0].scalability_mode = "L2T2";
streams[0].scalability_mode = ScalabilityMode::kL2T2;
config.spatial_layers = {};
VideoCodec codec;
@ -479,7 +479,7 @@ TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersOneDeactivated) {
VideoEncoderConfig config;
config.codec_type = VideoCodecType::kVideoCodecAV1;
std::vector<VideoStream> streams = {DefaultStream()};
streams[0].scalability_mode = "L2T2";
streams[0].scalability_mode = ScalabilityMode::kL2T2;
config.spatial_layers.resize(2);
config.spatial_layers[0].active = true;
config.spatial_layers[1].active = false;

View File

@ -919,6 +919,7 @@ if (rtc_include_tests) {
"../modules/video_coding:webrtc_vp9",
"../modules/video_coding:webrtc_vp9_helpers",
"../modules/video_coding/codecs/av1:libaom_av1_encoder_if_supported",
"../modules/video_coding/svc:scalability_mode_util",
"../rtc_base",
"../rtc_base:byte_buffer",
"../rtc_base:checks",

View File

@ -67,9 +67,9 @@ void FrameEncodeMetadataWriter::OnEncoderInit(const VideoCodec& codec) {
num_spatial_layers,
static_cast<size_t>(codec_settings_.VP9()->numberOfSpatialLayers));
} else if (codec_settings_.codecType == kVideoCodecAV1 &&
codec_settings_.ScalabilityMode() != "") {
codec_settings_.GetScalabilityMode().has_value()) {
std::unique_ptr<ScalableVideoController> structure =
CreateScalabilityStructure(codec_settings_.ScalabilityMode());
CreateScalabilityStructure(*codec_settings_.GetScalabilityMode());
if (structure) {
num_spatial_layers = structure->StreamConfig().num_spatial_layers;
} else {

View File

@ -39,6 +39,7 @@
#include "modules/video_coding/codecs/interface/common_constants.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "rtc_base/checks.h"
#include "rtc_base/event.h"
#include "rtc_base/experiments/alr_experiment.h"
@ -3383,7 +3384,7 @@ void VideoSendStreamTest::TestVp9NonFlexMode(
vp9_settings_.interLayerPred = params_.inter_layer_pred;
} else {
encoder_config->simulcast_layers[0].scalability_mode =
params_.scalability_mode;
ScalabilityModeFromString(params_.scalability_mode);
}
}

View File

@ -159,7 +159,8 @@ bool RequiresEncoderReset(const VideoCodec& prev_send_codec,
}
}
if (new_send_codec.ScalabilityMode() != prev_send_codec.ScalabilityMode()) {
if (new_send_codec.GetScalabilityMode() !=
prev_send_codec.GetScalabilityMode()) {
return true;
}

View File

@ -8761,7 +8761,7 @@ TEST_P(VideoStreamEncoderWithRealEncoderTest, HandlesLayerToggling) {
/*num_spatial_layers=*/3,
/*num_temporal_layers=*/3,
/*is_screenshare=*/false);
config.simulcast_layers[0].scalability_mode = "L3T3_KEY";
config.simulcast_layers[0].scalability_mode = ScalabilityMode::kL3T3_KEY;
} else {
// Simulcast for VP8/H264.
test::FillEncoderConfiguration(codec_type_, kNumSpatialLayers, &config);
@ -8973,7 +8973,7 @@ class ReconfigureEncoderTest : public VideoStreamEncoderTest {
kHeight / expected.scale_resolution_down_by);
EXPECT_EQ(actual.simulcastStream[0].numberOfTemporalLayers,
expected.num_temporal_layers);
EXPECT_EQ(actual.ScalabilityMode(), expected.scalability_mode);
EXPECT_EQ(actual.GetScalabilityMode(), expected.scalability_mode);
}
VideoStream DefaultConfig() const {
@ -8984,7 +8984,7 @@ class ReconfigureEncoderTest : public VideoStreamEncoderTest {
stream.scale_resolution_down_by = 1.0;
stream.num_temporal_layers = 1;
stream.bitrate_priority = 1.0;
stream.scalability_mode = "";
stream.scalability_mode = absl::nullopt;
return stream;
}
@ -9044,7 +9044,7 @@ TEST_F(ReconfigureEncoderTest, ReconfiguredIfNumTemporalLayerChanges) {
TEST_F(ReconfigureEncoderTest, ReconfiguredIfScalabilityModeChanges) {
VideoStream config1 = DefaultConfig();
VideoStream config2 = config1;
config2.scalability_mode = "L1T2";
config2.scalability_mode = ScalabilityMode::kL1T2;
RunTest({config1, config2}, /*expected_num_init_encode=*/2);
}