scalability_mode_util_unittest.cc (6224B)
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 <optional> 14 #include <string> 15 #include <tuple> 16 #include <vector> 17 18 #include "absl/strings/string_view.h" 19 #include "api/video_codecs/scalability_mode.h" 20 #include "test/gmock.h" 21 #include "test/gtest.h" 22 23 namespace webrtc { 24 25 namespace { 26 27 TEST(ScalabilityModeUtil, ConvertsL1T2) { 28 EXPECT_EQ(ScalabilityModeFromString("L1T2"), ScalabilityMode::kL1T2); 29 EXPECT_EQ(ScalabilityModeToString(ScalabilityMode::kL1T2), "L1T2"); 30 } 31 32 TEST(ScalabilityModeUtil, RejectsUnknownString) { 33 EXPECT_EQ(ScalabilityModeFromString(""), std::nullopt); 34 EXPECT_EQ(ScalabilityModeFromString("not-a-mode"), std::nullopt); 35 } 36 37 TEST(ScalabilityModeUtil, MakeScalabilityModeRoundTrip) { 38 const ScalabilityMode kLastEnum = ScalabilityMode::kS3T3h; 39 for (int numerical_enum = 0; numerical_enum <= static_cast<int>(kLastEnum); 40 numerical_enum++) { 41 ScalabilityMode scalability_mode = 42 static_cast<ScalabilityMode>(numerical_enum); 43 std::optional<ScalabilityMode> created_mode = MakeScalabilityMode( 44 ScalabilityModeToNumSpatialLayers(scalability_mode), 45 ScalabilityModeToNumTemporalLayers(scalability_mode), 46 ScalabilityModeToInterLayerPredMode(scalability_mode), 47 ScalabilityModeToResolutionRatio(scalability_mode), 48 ScalabilityModeIsShiftMode(scalability_mode)); 49 EXPECT_THAT(created_mode, ::testing::Optional(scalability_mode)) 50 << "Expected " 51 << (created_mode.has_value() ? ScalabilityModeToString(*created_mode) 52 : "(nullopt)") 53 << " to equal " << ScalabilityModeToString(scalability_mode); 54 } 55 } 56 57 // Check roundtrip conversion of all enum values. 58 TEST(ScalabilityModeUtil, ConvertsAllToAndFromString) { 59 const ScalabilityMode kLastEnum = ScalabilityMode::kS3T3h; 60 for (int numerical_enum = 0; numerical_enum <= static_cast<int>(kLastEnum); 61 numerical_enum++) { 62 ScalabilityMode scalability_mode = 63 static_cast<ScalabilityMode>(numerical_enum); 64 absl::string_view scalability_mode_string = 65 ScalabilityModeToString(scalability_mode); 66 EXPECT_FALSE(scalability_mode_string.empty()); 67 EXPECT_EQ(ScalabilityModeFromString(scalability_mode_string), 68 scalability_mode); 69 } 70 } 71 72 struct TestParams { 73 std::string scalability_mode; 74 std::vector<std::tuple<std::vector<int>, std::string>> 75 limited_scalability_mode; 76 }; 77 78 class NumSpatialLayersTest : public ::testing::TestWithParam<TestParams> {}; 79 80 INSTANTIATE_TEST_SUITE_P( 81 MaxLayers, 82 NumSpatialLayersTest, 83 ::testing::ValuesIn<TestParams>( 84 {{"L1T1", {{{0, 1}, "L1T1"}, {{2}, "L1T1"}, {{3}, "L1T1"}}}, 85 {"L1T2", {{{0, 1}, "L1T2"}, {{2}, "L1T2"}, {{3}, "L1T2"}}}, 86 {"L1T3", {{{0, 1}, "L1T3"}, {{2}, "L1T3"}, {{3}, "L1T3"}}}, 87 {"L2T1", {{{0, 1}, "L1T1"}, {{2}, "L2T1"}, {{3}, "L2T1"}}}, 88 {"L2T1h", {{{0, 1}, "L1T1"}, {{2}, "L2T1h"}, {{3}, "L2T1h"}}}, 89 {"L2T1_KEY", {{{0, 1}, "L1T1"}, {{2}, "L2T1_KEY"}, {{3}, "L2T1_KEY"}}}, 90 {"L2T2", {{{0, 1}, "L1T2"}, {{2}, "L2T2"}, {{3}, "L2T2"}}}, 91 {"L2T2h", {{{0, 1}, "L1T2"}, {{2}, "L2T2h"}, {{3}, "L2T2h"}}}, 92 {"L2T2_KEY", {{{0, 1}, "L1T2"}, {{2}, "L2T2_KEY"}, {{3}, "L2T2_KEY"}}}, 93 {"L2T2_KEY_SHIFT", 94 {{{0, 1}, "L1T2"}, {{2}, "L2T2_KEY_SHIFT"}, {{3}, "L2T2_KEY_SHIFT"}}}, 95 {"L2T3", {{{0, 1}, "L1T3"}, {{2}, "L2T3"}, {{3}, "L2T3"}}}, 96 {"L2T3h", {{{0, 1}, "L1T3"}, {{2}, "L2T3h"}, {{3}, "L2T3h"}}}, 97 {"L2T3_KEY", {{{0, 1}, "L1T3"}, {{2}, "L2T3_KEY"}, {{3}, "L2T3_KEY"}}}, 98 {"L3T1", {{{0, 1}, "L1T1"}, {{2}, "L2T1"}, {{3}, "L3T1"}}}, 99 {"L3T1h", {{{0, 1}, "L1T1"}, {{2}, "L2T1h"}, {{3}, "L3T1h"}}}, 100 {"L3T1_KEY", {{{0, 1}, "L1T1"}, {{2}, "L2T1_KEY"}, {{3}, "L3T1_KEY"}}}, 101 {"L3T2", {{{0, 1}, "L1T2"}, {{2}, "L2T2"}, {{3}, "L3T2"}}}, 102 {"L3T2h", {{{0, 1}, "L1T2"}, {{2}, "L2T2h"}, {{3}, "L3T2h"}}}, 103 {"L3T2_KEY", {{{0, 1}, "L1T2"}, {{2}, "L2T2_KEY"}, {{3}, "L3T2_KEY"}}}, 104 {"L3T3", {{{0, 1}, "L1T3"}, {{2}, "L2T3"}, {{3}, "L3T3"}}}, 105 {"L3T3h", {{{0, 1}, "L1T3"}, {{2}, "L2T3h"}, {{3}, "L3T3h"}}}, 106 {"L3T3_KEY", {{{0, 1}, "L1T3"}, {{2}, "L2T3_KEY"}, {{3}, "L3T3_KEY"}}}, 107 {"S2T1", {{{0, 1}, "L1T1"}, {{2}, "S2T1"}, {{3}, "S2T1"}}}, 108 {"S2T1h", {{{0, 1}, "L1T1"}, {{2}, "S2T1h"}, {{3}, "S2T1h"}}}, 109 {"S2T2", {{{0, 1}, "L1T2"}, {{2}, "S2T2"}, {{3}, "S2T2"}}}, 110 {"S2T2h", {{{0, 1}, "L1T2"}, {{2}, "S2T2h"}, {{3}, "S2T2h"}}}, 111 {"S2T3", {{{0, 1}, "L1T3"}, {{2}, "S2T3"}, {{3}, "S2T3"}}}, 112 {"S2T3h", {{{0, 1}, "L1T3"}, {{2}, "S2T3h"}, {{3}, "S2T3h"}}}, 113 {"S3T1", {{{0, 1}, "L1T1"}, {{2}, "S2T1"}, {{3}, "S3T1"}}}, 114 {"S3T1h", {{{0, 1}, "L1T1"}, {{2}, "S2T1h"}, {{3}, "S3T1h"}}}, 115 {"S3T2", {{{0, 1}, "L1T2"}, {{2}, "S2T2"}, {{3}, "S3T2"}}}, 116 {"S3T2h", {{{0, 1}, "L1T2"}, {{2}, "S2T2h"}, {{3}, "S3T2h"}}}, 117 {"S3T3", {{{0, 1}, "L1T3"}, {{2}, "S2T3"}, {{3}, "S3T3"}}}, 118 {"S3T3h", {{{0, 1}, "L1T3"}, {{2}, "S2T3h"}, {{3}, "S3T3h"}}}}), 119 [](const ::testing::TestParamInfo<TestParams>& info) { 120 return info.param.scalability_mode; 121 }); 122 123 TEST_P(NumSpatialLayersTest, LimitsSpatialLayers) { 124 const ScalabilityMode mode = 125 *ScalabilityModeFromString(GetParam().scalability_mode); 126 for (const auto& param : GetParam().limited_scalability_mode) { 127 const std::vector<int> max_num_spatial_layers = 128 std::get<std::vector<int>>(param); 129 const ScalabilityMode expected_mode = 130 *ScalabilityModeFromString(std::get<std::string>(param)); 131 for (const auto& max_layers : max_num_spatial_layers) { 132 EXPECT_EQ(expected_mode, LimitNumSpatialLayers(mode, max_layers)); 133 } 134 } 135 } 136 137 } // namespace 138 } // namespace webrtc