svc_config_unittest.cc (12754B)
1 /* 2 * Copyright (c) 2018 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/codecs/vp9/svc_config.h" 12 13 #include <cstddef> 14 #include <vector> 15 16 #include "api/video/video_codec_type.h" 17 #include "api/video_codecs/scalability_mode.h" 18 #include "api/video_codecs/spatial_layer.h" 19 #include "api/video_codecs/video_codec.h" 20 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" 21 #include "test/gmock.h" 22 #include "test/gtest.h" 23 24 using ::testing::ElementsAre; 25 using ::testing::Field; 26 27 namespace webrtc { 28 TEST(SvcConfig, NumSpatialLayers) { 29 const size_t max_num_spatial_layers = 6; 30 const size_t first_active_layer = 0; 31 const size_t num_spatial_layers = 2; 32 33 std::vector<SpatialLayer> spatial_layers = GetSvcConfig( 34 kMinVp9SpatialLayerLongSideLength << (num_spatial_layers - 1), 35 kMinVp9SpatialLayerShortSideLength << (num_spatial_layers - 1), 30, 36 first_active_layer, max_num_spatial_layers, 1, false); 37 38 EXPECT_EQ(spatial_layers.size(), num_spatial_layers); 39 } 40 41 TEST(SvcConfig, NumSpatialLayersPortrait) { 42 const size_t max_num_spatial_layers = 6; 43 const size_t first_active_layer = 0; 44 const size_t num_spatial_layers = 2; 45 46 std::vector<SpatialLayer> spatial_layers = GetSvcConfig( 47 kMinVp9SpatialLayerShortSideLength << (num_spatial_layers - 1), 48 kMinVp9SpatialLayerLongSideLength << (num_spatial_layers - 1), 30, 49 first_active_layer, max_num_spatial_layers, 1, false); 50 51 EXPECT_EQ(spatial_layers.size(), num_spatial_layers); 52 } 53 54 TEST(SvcConfig, NumSpatialLayersWithScalabilityMode) { 55 VideoCodec codec; 56 codec.codecType = kVideoCodecVP9; 57 codec.width = 960; 58 codec.height = 540; 59 codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY); 60 61 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 62 EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::height, 135), 63 Field(&SpatialLayer::height, 270), 64 Field(&SpatialLayer::height, 540))); 65 EXPECT_THAT(spatial_layers, 66 ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 3), 67 Field(&SpatialLayer::numberOfTemporalLayers, 3), 68 Field(&SpatialLayer::numberOfTemporalLayers, 3))); 69 EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL3T3_KEY); 70 } 71 72 TEST(SvcConfig, UpdatesInterLayerPredModeBasedOnScalabilityMode) { 73 VideoCodec codec; 74 codec.codecType = kVideoCodecVP9; 75 codec.width = 1280; 76 codec.height = 720; 77 codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY); 78 79 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 80 EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOnKeyPic); 81 82 codec.SetScalabilityMode(ScalabilityMode::kL3T3); 83 spatial_layers = GetVp9SvcConfig(codec); 84 EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOn); 85 86 codec.SetScalabilityMode(ScalabilityMode::kS3T3); 87 spatial_layers = GetVp9SvcConfig(codec); 88 EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOff); 89 } 90 91 TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityMode) { 92 VideoCodec codec; 93 codec.codecType = kVideoCodecVP9; 94 codec.width = 480; 95 codec.height = 270; 96 codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY); 97 98 // Scalability mode updated. 99 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 100 EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::height, 135), 101 Field(&SpatialLayer::height, 270))); 102 EXPECT_THAT(spatial_layers, 103 ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 3), 104 Field(&SpatialLayer::numberOfTemporalLayers, 3))); 105 EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL2T3_KEY); 106 } 107 108 TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModePortrait) { 109 VideoCodec codec; 110 codec.codecType = kVideoCodecVP9; 111 codec.width = 270; 112 codec.height = 480; 113 codec.SetScalabilityMode(ScalabilityMode::kL3T1); 114 115 // Scalability mode updated. 116 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 117 EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::width, 135), 118 Field(&SpatialLayer::width, 270))); 119 EXPECT_THAT(spatial_layers, 120 ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 1), 121 Field(&SpatialLayer::numberOfTemporalLayers, 1))); 122 EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL2T1); 123 } 124 125 TEST(SvcConfig, NumSpatialLayersWithScalabilityModeResolutionRatio1_5) { 126 VideoCodec codec; 127 codec.codecType = kVideoCodecVP9; 128 codec.width = 270; 129 codec.height = 480; 130 codec.SetScalabilityMode(ScalabilityMode::kL2T1h); // 1.5:1 131 132 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 133 EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::width, 180), 134 Field(&SpatialLayer::width, 270))); 135 EXPECT_THAT(spatial_layers, 136 ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 1), 137 Field(&SpatialLayer::numberOfTemporalLayers, 1))); 138 EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL2T1h); 139 } 140 141 TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityModeResolutionRatio1_5) { 142 VideoCodec codec; 143 codec.codecType = kVideoCodecVP9; 144 codec.width = 320; 145 codec.height = 180; 146 codec.SetScalabilityMode(ScalabilityMode::kL3T1h); // 1.5:1 147 148 // Scalability mode updated. 149 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 150 EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::width, 320))); 151 EXPECT_THAT(spatial_layers, 152 ElementsAre(Field(&SpatialLayer::numberOfTemporalLayers, 1))); 153 EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL1T1); 154 } 155 156 TEST(SvcConfig, AlwaysSendsAtLeastOneLayer) { 157 const size_t max_num_spatial_layers = 6; 158 const size_t first_active_layer = 5; 159 160 std::vector<SpatialLayer> spatial_layers = GetSvcConfig( 161 kMinVp9SpatialLayerLongSideLength, kMinVp9SpatialLayerShortSideLength, 30, 162 first_active_layer, max_num_spatial_layers, 1, false); 163 EXPECT_EQ(spatial_layers.size(), 1u); 164 EXPECT_EQ(spatial_layers.back().width, kMinVp9SpatialLayerLongSideLength); 165 } 166 167 TEST(SvcConfig, AlwaysSendsAtLeastOneLayerPortrait) { 168 const size_t max_num_spatial_layers = 6; 169 const size_t first_active_layer = 5; 170 171 std::vector<SpatialLayer> spatial_layers = GetSvcConfig( 172 kMinVp9SpatialLayerShortSideLength, kMinVp9SpatialLayerLongSideLength, 30, 173 first_active_layer, max_num_spatial_layers, 1, false); 174 EXPECT_EQ(spatial_layers.size(), 1u); 175 EXPECT_EQ(spatial_layers.back().width, kMinVp9SpatialLayerShortSideLength); 176 } 177 178 TEST(SvcConfig, EnforcesMinimalRequiredParity) { 179 const size_t max_num_spatial_layers = 3; 180 const int kOddSize = 1023; 181 182 std::vector<SpatialLayer> spatial_layers = 183 GetSvcConfig(kOddSize, kOddSize, 30, 184 /*first_active_layer=*/1, max_num_spatial_layers, 1, false); 185 // Since there are 2 layers total (1, 2), divisiblity by 2 is required. 186 EXPECT_EQ(spatial_layers.back().width, kOddSize - 1); 187 EXPECT_EQ(spatial_layers.back().width, kOddSize - 1); 188 189 spatial_layers = 190 GetSvcConfig(kOddSize, kOddSize, 30, 191 /*first_active_layer=*/0, max_num_spatial_layers, 1, false); 192 // Since there are 3 layers total (0, 1, 2), divisiblity by 4 is required. 193 EXPECT_EQ(spatial_layers.back().width, kOddSize - 3); 194 EXPECT_EQ(spatial_layers.back().width, kOddSize - 3); 195 196 spatial_layers = 197 GetSvcConfig(kOddSize, kOddSize, 30, 198 /*first_active_layer=*/2, max_num_spatial_layers, 1, false); 199 // Since there is only 1 layer active (2), divisiblity by 1 is required. 200 EXPECT_EQ(spatial_layers.back().width, kOddSize); 201 EXPECT_EQ(spatial_layers.back().width, kOddSize); 202 } 203 204 TEST(SvcConfig, EnforcesMinimalRequiredParityWithScalabilityMode) { 205 VideoCodec codec; 206 codec.codecType = kVideoCodecVP9; 207 codec.width = 1023; 208 codec.height = 1023; 209 codec.SetScalabilityMode(ScalabilityMode::kL3T1); 210 211 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 212 EXPECT_THAT(spatial_layers, // Divisiblity by 4 required. 213 ElementsAre(Field(&SpatialLayer::width, 255), 214 Field(&SpatialLayer::width, 510), 215 Field(&SpatialLayer::width, 1020))); 216 217 codec.SetScalabilityMode(ScalabilityMode::kL2T1); 218 spatial_layers = GetVp9SvcConfig(codec); 219 EXPECT_THAT(spatial_layers, // Divisiblity by 2 required. 220 ElementsAre(Field(&SpatialLayer::width, 511), 221 Field(&SpatialLayer::width, 1022))); 222 223 codec.SetScalabilityMode(ScalabilityMode::kL1T1); 224 spatial_layers = GetVp9SvcConfig(codec); 225 EXPECT_THAT(spatial_layers, // Divisiblity by 1 required. 226 ElementsAre(Field(&SpatialLayer::width, 1023))); 227 } 228 229 TEST(SvcConfig, EnforcesMinimalRequiredParityWithScalabilityModeResRatio1_5) { 230 VideoCodec codec; 231 codec.codecType = kVideoCodecVP9; 232 codec.width = 1280; 233 codec.height = 1280; 234 codec.SetScalabilityMode(ScalabilityMode::kL2T1h); // 1.5:1 235 236 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 237 EXPECT_THAT(spatial_layers, // Divisiblity by 3 required. 238 ElementsAre(Field(&SpatialLayer::width, 852), 239 Field(&SpatialLayer::width, 1278))); 240 } 241 242 TEST(SvcConfig, SkipsInactiveLayers) { 243 const size_t num_spatial_layers = 4; 244 const size_t first_active_layer = 2; 245 246 std::vector<SpatialLayer> spatial_layers = GetSvcConfig( 247 kMinVp9SpatialLayerLongSideLength << (num_spatial_layers - 1), 248 kMinVp9SpatialLayerShortSideLength << (num_spatial_layers - 1), 30, 249 first_active_layer, num_spatial_layers, 1, false); 250 EXPECT_EQ(spatial_layers.size(), 2u); 251 EXPECT_EQ(spatial_layers.back().width, 252 kMinVp9SpatialLayerLongSideLength << (num_spatial_layers - 1)); 253 } 254 255 TEST(SvcConfig, BitrateThresholds) { 256 const size_t first_active_layer = 0; 257 const size_t num_spatial_layers = 3; 258 std::vector<SpatialLayer> spatial_layers = GetSvcConfig( 259 kMinVp9SpatialLayerLongSideLength << (num_spatial_layers - 1), 260 kMinVp9SpatialLayerShortSideLength << (num_spatial_layers - 1), 30, 261 first_active_layer, num_spatial_layers, 1, false); 262 263 EXPECT_EQ(spatial_layers.size(), num_spatial_layers); 264 265 for (const SpatialLayer& layer : spatial_layers) { 266 EXPECT_LE(layer.minBitrate, layer.maxBitrate); 267 EXPECT_LE(layer.minBitrate, layer.targetBitrate); 268 EXPECT_LE(layer.targetBitrate, layer.maxBitrate); 269 } 270 } 271 272 TEST(SvcConfig, BitrateThresholdsWithScalabilityMode) { 273 VideoCodec codec; 274 codec.codecType = kVideoCodecVP9; 275 codec.width = 960; 276 codec.height = 540; 277 codec.SetScalabilityMode(ScalabilityMode::kS3T3); 278 279 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 280 EXPECT_THAT(spatial_layers, ElementsAre(Field(&SpatialLayer::height, 135), 281 Field(&SpatialLayer::height, 270), 282 Field(&SpatialLayer::height, 540))); 283 284 for (const SpatialLayer& layer : spatial_layers) { 285 EXPECT_LE(layer.minBitrate, layer.maxBitrate); 286 EXPECT_LE(layer.minBitrate, layer.targetBitrate); 287 EXPECT_LE(layer.targetBitrate, layer.maxBitrate); 288 } 289 } 290 291 TEST(SvcConfig, CopiesMinMaxBitrateForSingleSpatialLayer) { 292 VideoCodec codec; 293 codec.codecType = kVideoCodecVP9; 294 codec.SetScalabilityMode(ScalabilityMode::kL1T3); 295 codec.width = 1280; 296 codec.height = 720; 297 codec.minBitrate = 100; 298 codec.maxBitrate = 500; 299 300 std::vector<SpatialLayer> spatial_layers = GetVp9SvcConfig(codec); 301 EXPECT_EQ(spatial_layers[0].minBitrate, 100u); 302 EXPECT_EQ(spatial_layers[0].maxBitrate, 500u); 303 EXPECT_LE(spatial_layers[0].targetBitrate, 500u); 304 } 305 306 TEST(SvcConfig, ScreenSharing) { 307 std::vector<SpatialLayer> spatial_layers = 308 GetSvcConfig(1920, 1080, 30, 1, 3, 3, true); 309 310 EXPECT_EQ(spatial_layers.size(), 3UL); 311 312 for (size_t i = 0; i < 3; ++i) { 313 const SpatialLayer& layer = spatial_layers[i]; 314 EXPECT_EQ(layer.width, 1920); 315 EXPECT_EQ(layer.height, 1080); 316 EXPECT_EQ(layer.maxFramerate, (i < 1) ? 5 : (i < 2 ? 10 : 30)); 317 EXPECT_EQ(layer.numberOfTemporalLayers, 1); 318 EXPECT_LE(layer.minBitrate, layer.maxBitrate); 319 EXPECT_LE(layer.minBitrate, layer.targetBitrate); 320 EXPECT_LE(layer.targetBitrate, layer.maxBitrate); 321 } 322 } 323 } // namespace webrtc