Add helper to query scalability structure configuration

without creating svc controller for it.

Bug: chromium:1187565
Change-Id: I219f88203e73036bf48bce04527bb8e46ccf1c33
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231128
Reviewed-by: Johannes Kron <kron@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34968}
This commit is contained in:
Danil Chapovalov
2021-09-06 15:41:54 +02:00
committed by WebRTC LUCI CQ
parent b32650e219
commit 5d3bf6ae2a
9 changed files with 133 additions and 15 deletions

View File

@ -27,6 +27,7 @@ struct NamedStructureFactory {
absl::string_view name; absl::string_view name;
// Use function pointer to make NamedStructureFactory trivally destructable. // Use function pointer to make NamedStructureFactory trivally destructable.
std::unique_ptr<ScalableVideoController> (*factory)(); std::unique_ptr<ScalableVideoController> (*factory)();
ScalableVideoController::StreamLayersConfig config;
}; };
// Wrap std::make_unique function to have correct return type. // Wrap std::make_unique function to have correct return type.
@ -44,22 +45,90 @@ std::unique_ptr<ScalableVideoController> CreateH() {
return std::make_unique<T>(factor); return std::make_unique<T>(factor);
} }
constexpr ScalableVideoController::StreamLayersConfig kConfigNone = {
/*num_spatial_layers=*/1, /*num_temporal_layers=*/1,
/*uses_reference_scaling=*/false};
constexpr ScalableVideoController::StreamLayersConfig kConfigL1T2 = {
/*num_spatial_layers=*/1, /*num_temporal_layers=*/2,
/*uses_reference_scaling=*/false};
constexpr ScalableVideoController::StreamLayersConfig kConfigL1T3 = {
/*num_spatial_layers=*/1, /*num_temporal_layers=*/3,
/*uses_reference_scaling=*/false};
constexpr ScalableVideoController::StreamLayersConfig kConfigL2T1 = {
/*num_spatial_layers=*/2,
/*num_temporal_layers=*/1,
/*uses_reference_scaling=*/true,
{1, 1},
{2, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigL2T1h = {
/*num_spatial_layers=*/2,
/*num_temporal_layers=*/1,
/*uses_reference_scaling=*/true,
{2, 1},
{3, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigL2T2 = {
/*num_spatial_layers=*/2,
/*num_temporal_layers=*/2,
/*uses_reference_scaling=*/true,
{1, 1},
{2, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigL2T3 = {
/*num_spatial_layers=*/2,
/*num_temporal_layers=*/3,
/*uses_reference_scaling=*/true,
{1, 1},
{2, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigL3T1 = {
/*num_spatial_layers=*/3,
/*num_temporal_layers=*/1,
/*uses_reference_scaling=*/true,
{1, 1, 1},
{4, 2, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigL3T3 = {
/*num_spatial_layers=*/3,
/*num_temporal_layers=*/3,
/*uses_reference_scaling=*/true,
{1, 1, 1},
{4, 2, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigS2T1 = {
/*num_spatial_layers=*/2,
/*num_temporal_layers=*/1,
/*uses_reference_scaling=*/false,
{1, 1},
{2, 1}};
constexpr ScalableVideoController::StreamLayersConfig kConfigS3T3 = {
/*num_spatial_layers=*/3,
/*num_temporal_layers=*/3,
/*uses_reference_scaling=*/false,
{1, 1, 1},
{4, 2, 1}};
constexpr NamedStructureFactory kFactories[] = { constexpr NamedStructureFactory kFactories[] = {
{"NONE", Create<ScalableVideoControllerNoLayering>}, {"NONE", Create<ScalableVideoControllerNoLayering>, kConfigNone},
{"L1T2", Create<ScalabilityStructureL1T2>}, {"L1T2", Create<ScalabilityStructureL1T2>, kConfigL1T2},
{"L1T3", Create<ScalabilityStructureL1T3>}, {"L1T3", Create<ScalabilityStructureL1T3>, kConfigL1T3},
{"L2T1", Create<ScalabilityStructureL2T1>}, {"L2T1", Create<ScalabilityStructureL2T1>, kConfigL2T1},
{"L2T1h", CreateH<ScalabilityStructureL2T1>}, {"L2T1h", CreateH<ScalabilityStructureL2T1>, kConfigL2T1h},
{"L2T1_KEY", Create<ScalabilityStructureL2T1Key>}, {"L2T1_KEY", Create<ScalabilityStructureL2T1Key>, kConfigL2T1},
{"L2T2", Create<ScalabilityStructureL2T2>}, {"L2T2", Create<ScalabilityStructureL2T2>, kConfigL2T2},
{"L2T2_KEY", Create<ScalabilityStructureL2T2Key>}, {"L2T2_KEY", Create<ScalabilityStructureL2T2Key>, kConfigL2T2},
{"L2T2_KEY_SHIFT", Create<ScalabilityStructureL2T2KeyShift>}, {"L2T2_KEY_SHIFT", Create<ScalabilityStructureL2T2KeyShift>, kConfigL2T2},
{"L2T3_KEY", Create<ScalabilityStructureL2T3Key>}, {"L2T3_KEY", Create<ScalabilityStructureL2T3Key>, kConfigL2T3},
{"L3T1", Create<ScalabilityStructureL3T1>}, {"L3T1", Create<ScalabilityStructureL3T1>, kConfigL3T1},
{"L3T3", Create<ScalabilityStructureL3T3>}, {"L3T3", Create<ScalabilityStructureL3T3>, kConfigL3T3},
{"L3T3_KEY", Create<ScalabilityStructureL3T3Key>}, {"L3T3_KEY", Create<ScalabilityStructureL3T3Key>, kConfigL3T3},
{"S2T1", Create<ScalabilityStructureS2T1>}, {"S2T1", Create<ScalabilityStructureS2T1>, kConfigS2T1},
{"S3T3", Create<ScalabilityStructureS3T3>}, {"S3T3", Create<ScalabilityStructureS3T3>, kConfigS3T3},
}; };
} // namespace } // namespace
@ -75,4 +144,15 @@ std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
return nullptr; return nullptr;
} }
absl::optional<ScalableVideoController::StreamLayersConfig>
ScalabilityStructureConfig(absl::string_view name) {
RTC_DCHECK(!name.empty());
for (const auto& entry : kFactories) {
if (entry.name == name) {
return entry.config;
}
}
return absl::nullopt;
}
} // namespace webrtc } // namespace webrtc

View File

@ -14,6 +14,7 @@
#include <vector> #include <vector>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "modules/video_coding/svc/scalable_video_controller.h" #include "modules/video_coding/svc/scalable_video_controller.h"
namespace webrtc { namespace webrtc {
@ -24,6 +25,11 @@ namespace webrtc {
std::unique_ptr<ScalableVideoController> CreateScalabilityStructure( std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
absl::string_view name); absl::string_view name);
// Returns descrption of the scalability structure identified by 'name',
// Return nullopt for unknown name.
absl::optional<ScalableVideoController::StreamLayersConfig>
ScalabilityStructureConfig(absl::string_view name);
} // namespace webrtc } // namespace webrtc
#endif // MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_ #endif // MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_

View File

@ -52,6 +52,7 @@ ScalabilityStructureFullSvc::StreamConfig() const {
result.scaling_factor_den[sid - 1] = result.scaling_factor_den[sid - 1] =
resolution_factor_.den * result.scaling_factor_den[sid]; resolution_factor_.den * result.scaling_factor_den[sid];
} }
result.uses_reference_scaling = num_spatial_layers_ > 1;
return result; return result;
} }

View File

@ -51,6 +51,7 @@ ScalabilityStructureKeySvc::StreamConfig() const {
result.scaling_factor_num[sid - 1] = 1; result.scaling_factor_num[sid - 1] = 1;
result.scaling_factor_den[sid - 1] = 2 * result.scaling_factor_den[sid]; result.scaling_factor_den[sid - 1] = 2 * result.scaling_factor_den[sid];
} }
result.uses_reference_scaling = true;
return result; return result;
} }

View File

@ -51,6 +51,7 @@ ScalabilityStructureL2T2KeyShift::StreamConfig() const {
result.num_temporal_layers = 2; result.num_temporal_layers = 2;
result.scaling_factor_num[0] = 1; result.scaling_factor_num[0] = 1;
result.scaling_factor_den[0] = 2; result.scaling_factor_den[0] = 2;
result.uses_reference_scaling = true;
return result; return result;
} }

View File

@ -65,6 +65,7 @@ ScalabilityStructureSimulcast::StreamConfig() const {
result.scaling_factor_num[sid - 1] = 1; result.scaling_factor_num[sid - 1] = 1;
result.scaling_factor_den[sid - 1] = 2 * result.scaling_factor_den[sid]; result.scaling_factor_den[sid - 1] = 2 * result.scaling_factor_den[sid];
} }
result.uses_reference_scaling = false;
return result; return result;
} }

View File

@ -16,6 +16,7 @@
#include <string> #include <string>
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/transport/rtp/dependency_descriptor.h" #include "api/transport/rtp/dependency_descriptor.h"
#include "modules/video_coding/svc/create_scalability_structure.h" #include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_structure_test_helpers.h" #include "modules/video_coding/svc/scalability_structure_test_helpers.h"
@ -29,12 +30,14 @@ namespace {
using ::testing::AllOf; using ::testing::AllOf;
using ::testing::Contains; using ::testing::Contains;
using ::testing::Each; using ::testing::Each;
using ::testing::ElementsAreArray;
using ::testing::Field; using ::testing::Field;
using ::testing::Ge; using ::testing::Ge;
using ::testing::IsEmpty; using ::testing::IsEmpty;
using ::testing::Le; using ::testing::Le;
using ::testing::Lt; using ::testing::Lt;
using ::testing::Not; using ::testing::Not;
using ::testing::NotNull;
using ::testing::SizeIs; using ::testing::SizeIs;
using ::testing::TestWithParam; using ::testing::TestWithParam;
using ::testing::Values; using ::testing::Values;
@ -50,6 +53,28 @@ struct SvcTestParam {
class ScalabilityStructureTest : public TestWithParam<SvcTestParam> {}; class ScalabilityStructureTest : public TestWithParam<SvcTestParam> {};
TEST_P(ScalabilityStructureTest,
StaticConfigMatchesConfigReturnedByController) {
std::unique_ptr<ScalableVideoController> controller =
CreateScalabilityStructure(GetParam().name);
absl::optional<ScalableVideoController::StreamLayersConfig> static_config =
ScalabilityStructureConfig(GetParam().name);
ASSERT_THAT(controller, NotNull());
ASSERT_NE(static_config, absl::nullopt);
ScalableVideoController::StreamLayersConfig config =
controller->StreamConfig();
EXPECT_EQ(config.num_spatial_layers, static_config->num_spatial_layers);
EXPECT_EQ(config.num_temporal_layers, static_config->num_temporal_layers);
EXPECT_THAT(
rtc::MakeArrayView(config.scaling_factor_num, config.num_spatial_layers),
ElementsAreArray(static_config->scaling_factor_num,
static_config->num_spatial_layers));
EXPECT_THAT(
rtc::MakeArrayView(config.scaling_factor_den, config.num_spatial_layers),
ElementsAreArray(static_config->scaling_factor_den,
static_config->num_spatial_layers));
}
TEST_P(ScalabilityStructureTest, TEST_P(ScalabilityStructureTest,
NumberOfDecodeTargetsAndChainsAreInRangeAndConsistent) { NumberOfDecodeTargetsAndChainsAreInRangeAndConsistent) {
FrameDependencyStructure structure = FrameDependencyStructure structure =

View File

@ -27,6 +27,8 @@ class ScalableVideoController {
struct StreamLayersConfig { struct StreamLayersConfig {
int num_spatial_layers = 1; int num_spatial_layers = 1;
int num_temporal_layers = 1; int num_temporal_layers = 1;
// Indicates if frames can reference frames of a different resolution.
bool uses_reference_scaling = true;
// Spatial layers scaling. Frames with spatial_id = i expected to be encoded // Spatial layers scaling. Frames with spatial_id = i expected to be encoded
// with original_resolution * scaling_factor_num[i] / scaling_factor_den[i]. // with original_resolution * scaling_factor_num[i] / scaling_factor_den[i].
int scaling_factor_num[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1}; int scaling_factor_num[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};

View File

@ -25,6 +25,7 @@ ScalableVideoControllerNoLayering::StreamConfig() const {
StreamLayersConfig result; StreamLayersConfig result;
result.num_spatial_layers = 1; result.num_spatial_layers = 1;
result.num_temporal_layers = 1; result.num_temporal_layers = 1;
result.uses_reference_scaling = false;
return result; return result;
} }