1 /*
2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/video_coding/svc/scalability_mode_util.h"
12
13 #include <string>
14 #include <tuple>
15 #include <vector>
16
17 #include "absl/strings/string_view.h"
18 #include "absl/types/optional.h"
19 #include "api/video_codecs/scalability_mode.h"
20 #include "test/gtest.h"
21
22 namespace webrtc {
23 namespace {
24
TEST(ScalabilityModeUtil,ConvertsL1T2)25 TEST(ScalabilityModeUtil, ConvertsL1T2) {
26 EXPECT_EQ(ScalabilityModeFromString("L1T2"), ScalabilityMode::kL1T2);
27 EXPECT_EQ(ScalabilityModeToString(ScalabilityMode::kL1T2), "L1T2");
28 }
29
TEST(ScalabilityModeUtil,RejectsUnknownString)30 TEST(ScalabilityModeUtil, RejectsUnknownString) {
31 EXPECT_EQ(ScalabilityModeFromString(""), absl::nullopt);
32 EXPECT_EQ(ScalabilityModeFromString("not-a-mode"), absl::nullopt);
33 }
34
35 // Check roundtrip conversion of all enum values.
TEST(ScalabilityModeUtil,ConvertsAllToAndFromString)36 TEST(ScalabilityModeUtil, ConvertsAllToAndFromString) {
37 const ScalabilityMode kLastEnum = ScalabilityMode::kS3T3h;
38 for (int numerical_enum = 0; numerical_enum <= static_cast<int>(kLastEnum);
39 numerical_enum++) {
40 ScalabilityMode scalability_mode =
41 static_cast<ScalabilityMode>(numerical_enum);
42 absl::string_view scalability_mode_string =
43 ScalabilityModeToString(scalability_mode);
44 EXPECT_FALSE(scalability_mode_string.empty());
45 EXPECT_EQ(ScalabilityModeFromString(scalability_mode_string),
46 scalability_mode);
47 }
48 }
49
50 struct TestParams {
51 std::string scalability_mode;
52 std::vector<std::tuple<std::vector<int>, std::string>>
53 limited_scalability_mode;
54 };
55
56 class NumSpatialLayersTest : public ::testing::TestWithParam<TestParams> {};
57
58 INSTANTIATE_TEST_SUITE_P(
59 MaxLayers,
60 NumSpatialLayersTest,
61 ::testing::ValuesIn<TestParams>(
62 {{"L1T1", {{{0, 1}, "L1T1"}, {{2}, "L1T1"}, {{3}, "L1T1"}}},
63 {"L1T2", {{{0, 1}, "L1T2"}, {{2}, "L1T2"}, {{3}, "L1T2"}}},
64 {"L1T3", {{{0, 1}, "L1T3"}, {{2}, "L1T3"}, {{3}, "L1T3"}}},
65 {"L2T1", {{{0, 1}, "L1T1"}, {{2}, "L2T1"}, {{3}, "L2T1"}}},
66 {"L2T1h", {{{0, 1}, "L1T1"}, {{2}, "L2T1h"}, {{3}, "L2T1h"}}},
67 {"L2T1_KEY", {{{0, 1}, "L1T1"}, {{2}, "L2T1_KEY"}, {{3}, "L2T1_KEY"}}},
68 {"L2T2", {{{0, 1}, "L1T2"}, {{2}, "L2T2"}, {{3}, "L2T2"}}},
69 {"L2T2h", {{{0, 1}, "L1T2"}, {{2}, "L2T2h"}, {{3}, "L2T2h"}}},
70 {"L2T2_KEY", {{{0, 1}, "L1T2"}, {{2}, "L2T2_KEY"}, {{3}, "L2T2_KEY"}}},
71 {"L2T2_KEY_SHIFT",
72 {{{0, 1}, "L1T2"}, {{2}, "L2T2_KEY_SHIFT"}, {{3}, "L2T2_KEY_SHIFT"}}},
73 {"L2T3", {{{0, 1}, "L1T3"}, {{2}, "L2T3"}, {{3}, "L2T3"}}},
74 {"L2T3h", {{{0, 1}, "L1T3"}, {{2}, "L2T3h"}, {{3}, "L2T3h"}}},
75 {"L2T3_KEY", {{{0, 1}, "L1T3"}, {{2}, "L2T3_KEY"}, {{3}, "L2T3_KEY"}}},
76 {"L3T1", {{{0, 1}, "L1T1"}, {{2}, "L2T1"}, {{3}, "L3T1"}}},
77 {"L3T1h", {{{0, 1}, "L1T1"}, {{2}, "L2T1h"}, {{3}, "L3T1h"}}},
78 {"L3T1_KEY", {{{0, 1}, "L1T1"}, {{2}, "L2T1_KEY"}, {{3}, "L3T1_KEY"}}},
79 {"L3T2", {{{0, 1}, "L1T2"}, {{2}, "L2T2"}, {{3}, "L3T2"}}},
80 {"L3T2h", {{{0, 1}, "L1T2"}, {{2}, "L2T2h"}, {{3}, "L3T2h"}}},
81 {"L3T2_KEY", {{{0, 1}, "L1T2"}, {{2}, "L2T2_KEY"}, {{3}, "L3T2_KEY"}}},
82 {"L3T3", {{{0, 1}, "L1T3"}, {{2}, "L2T3"}, {{3}, "L3T3"}}},
83 {"L3T3h", {{{0, 1}, "L1T3"}, {{2}, "L2T3h"}, {{3}, "L3T3h"}}},
84 {"L3T3_KEY", {{{0, 1}, "L1T3"}, {{2}, "L2T3_KEY"}, {{3}, "L3T3_KEY"}}},
85 {"S2T1", {{{0, 1}, "L1T1"}, {{2}, "S2T1"}, {{3}, "S2T1"}}},
86 {"S2T1h", {{{0, 1}, "L1T1"}, {{2}, "S2T1h"}, {{3}, "S2T1h"}}},
87 {"S2T2", {{{0, 1}, "L1T2"}, {{2}, "S2T2"}, {{3}, "S2T2"}}},
88 {"S2T2h", {{{0, 1}, "L1T2"}, {{2}, "S2T2h"}, {{3}, "S2T2h"}}},
89 {"S2T3", {{{0, 1}, "L1T3"}, {{2}, "S2T3"}, {{3}, "S2T3"}}},
90 {"S2T3h", {{{0, 1}, "L1T3"}, {{2}, "S2T3h"}, {{3}, "S2T3h"}}},
91 {"S3T1", {{{0, 1}, "L1T1"}, {{2}, "S2T1"}, {{3}, "S3T1"}}},
92 {"S3T1h", {{{0, 1}, "L1T1"}, {{2}, "S2T1h"}, {{3}, "S3T1h"}}},
93 {"S3T2", {{{0, 1}, "L1T2"}, {{2}, "S2T2"}, {{3}, "S3T2"}}},
94 {"S3T2h", {{{0, 1}, "L1T2"}, {{2}, "S2T2h"}, {{3}, "S3T2h"}}},
95 {"S3T3", {{{0, 1}, "L1T3"}, {{2}, "S2T3"}, {{3}, "S3T3"}}},
96 {"S3T3h", {{{0, 1}, "L1T3"}, {{2}, "S2T3h"}, {{3}, "S3T3h"}}}}),
__anonbd61573e0202(const ::testing::TestParamInfo<TestParams>& info) 97 [](const ::testing::TestParamInfo<TestParams>& info) {
98 return info.param.scalability_mode;
99 });
100
TEST_P(NumSpatialLayersTest,LimitsSpatialLayers)101 TEST_P(NumSpatialLayersTest, LimitsSpatialLayers) {
102 const ScalabilityMode mode =
103 *ScalabilityModeFromString(GetParam().scalability_mode);
104 for (const auto& param : GetParam().limited_scalability_mode) {
105 const std::vector<int> max_num_spatial_layers =
106 std::get<std::vector<int>>(param);
107 const ScalabilityMode expected_mode =
108 *ScalabilityModeFromString(std::get<std::string>(param));
109 for (const auto& max_layers : max_num_spatial_layers) {
110 EXPECT_EQ(expected_mode, LimitNumSpatialLayers(mode, max_layers));
111 }
112 }
113 }
114
115 } // namespace
116 } // namespace webrtc
117