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:
parent
cbf07f70e2
commit
79d566b0cf
@ -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",
|
||||
]
|
||||
}
|
||||
|
||||
40
api/video_codecs/scalability_mode.h
Normal file
40
api/video_codecs/scalability_mode.h
Normal 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_
|
||||
@ -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_;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
]
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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()),
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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") {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
96
modules/video_coding/svc/scalability_mode_util.cc
Normal file
96
modules/video_coding/svc/scalability_mode_util.cc
Normal 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
|
||||
27
modules/video_coding/svc/scalability_mode_util.h
Normal file
27
modules/video_coding/svc/scalability_mode_util.h
Normal 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_
|
||||
47
modules/video_coding/svc/scalability_mode_util_unittest.cc
Normal file
47
modules/video_coding/svc/scalability_mode_util_unittest.cc
Normal 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
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user