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;
// Use function pointer to make NamedStructureFactory trivally destructable.
std::unique_ptr<ScalableVideoController> (*factory)();
ScalableVideoController::StreamLayersConfig config;
};
// 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);
}
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[] = {
{"NONE", Create<ScalableVideoControllerNoLayering>},
{"L1T2", Create<ScalabilityStructureL1T2>},
{"L1T3", Create<ScalabilityStructureL1T3>},
{"L2T1", Create<ScalabilityStructureL2T1>},
{"L2T1h", CreateH<ScalabilityStructureL2T1>},
{"L2T1_KEY", Create<ScalabilityStructureL2T1Key>},
{"L2T2", Create<ScalabilityStructureL2T2>},
{"L2T2_KEY", Create<ScalabilityStructureL2T2Key>},
{"L2T2_KEY_SHIFT", Create<ScalabilityStructureL2T2KeyShift>},
{"L2T3_KEY", Create<ScalabilityStructureL2T3Key>},
{"L3T1", Create<ScalabilityStructureL3T1>},
{"L3T3", Create<ScalabilityStructureL3T3>},
{"L3T3_KEY", Create<ScalabilityStructureL3T3Key>},
{"S2T1", Create<ScalabilityStructureS2T1>},
{"S3T3", Create<ScalabilityStructureS3T3>},
{"NONE", Create<ScalableVideoControllerNoLayering>, kConfigNone},
{"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},
};
} // namespace
@ -75,4 +144,15 @@ std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
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

View file

@ -14,6 +14,7 @@
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
namespace webrtc {
@ -24,6 +25,11 @@ namespace webrtc {
std::unique_ptr<ScalableVideoController> CreateScalabilityStructure(
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
#endif // MODULES_VIDEO_CODING_SVC_CREATE_SCALABILITY_STRUCTURE_H_

View file

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

View file

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

View file

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

View file

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

View file

@ -16,6 +16,7 @@
#include <string>
#include "absl/types/optional.h"
#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_structure_test_helpers.h"
@ -29,12 +30,14 @@ namespace {
using ::testing::AllOf;
using ::testing::Contains;
using ::testing::Each;
using ::testing::ElementsAreArray;
using ::testing::Field;
using ::testing::Ge;
using ::testing::IsEmpty;
using ::testing::Le;
using ::testing::Lt;
using ::testing::Not;
using ::testing::NotNull;
using ::testing::SizeIs;
using ::testing::TestWithParam;
using ::testing::Values;
@ -50,6 +53,28 @@ struct 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,
NumberOfDecodeTargetsAndChainsAreInRangeAndConsistent) {
FrameDependencyStructure structure =

View file

@ -27,6 +27,8 @@ class ScalableVideoController {
struct StreamLayersConfig {
int num_spatial_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
// with original_resolution * scaling_factor_num[i] / scaling_factor_den[i].
int scaling_factor_num[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};

View file

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