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