FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/tests/h265_levels.c
Date: 2024-04-25 15:36:26
Exec Total Coverage
Lines: 24 24 100.0%
Functions: 1 1 100.0%
Branches: 27 48 56.2%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libavutil/common.h"
20 #include "libavcodec/h265_profile_level.h"
21
22 static const struct {
23 int width;
24 int height;
25 int level_idc;
26 } test_sizes[] = {
27 // First level usable at standard sizes, from H.265 table A.9.
28 { 176, 144, 30 }, // QCIF
29 { 352, 288, 60 }, // CIF
30 { 640, 480, 90 }, // VGA
31 { 720, 480, 90 }, // NTSC
32 { 720, 576, 90 }, // PAL
33 { 1024, 768, 93 }, // XGA
34 { 1280, 720, 93 }, // 720p
35 { 1280, 1024, 120 }, // SXGA
36 { 1920, 1080, 120 }, // 1080p
37 { 2048, 1080, 120 }, // 2Kx1080
38 { 2048, 1536, 150 }, // 4XGA
39 { 3840, 2160, 150 }, // 4K
40 { 7680, 4320, 180 }, // 8K
41
42 // Overly wide or tall sizes.
43 { 1, 512, 30 },
44 { 1, 1024, 63 },
45 { 1, 2048, 90 },
46 { 1, 4096, 120 },
47 { 1, 8192, 150 },
48 { 1, 16384, 180 },
49 { 1, 32768, 0 },
50 { 512, 1, 30 },
51 { 1024, 1, 63 },
52 { 2048, 1, 90 },
53 { 4096, 1, 120 },
54 { 8192, 1, 150 },
55 { 16384, 1, 180 },
56 { 32768, 1, 0 },
57 { 2800, 256, 93 },
58 { 2816, 128, 120 },
59 { 256, 4208, 120 },
60 { 128, 4224, 150 },
61 { 8432, 256, 150 },
62 { 8448, 128, 180 },
63 { 256, 16880, 180 },
64 { 128, 16896, 0 },
65 };
66
67 static const struct {
68 int width;
69 int height;
70 int dpb_size;
71 int level_idc;
72 } test_dpb[] = {
73 // First level usable for some DPB sizes.
74
75 // L1: 176 * 144 = 25344 <= 36864 * 3/4 = 27648
76 // L2: <= 122880 * 1/4 = 30720
77 { 176, 144, 8, 30 },
78 { 176, 144, 9, 60 },
79
80 // L2: 352 * 288 = 101376 <= 122880
81 // L2.1: <= 245760 * 1/2 = 122880
82 // L3: <= 552960 * 1/4 = 138240
83 { 352, 288, 6, 60 },
84 { 352, 288, 7, 63 },
85 { 352, 288, 13, 90 },
86
87 // L3.1: 1280 * 720 = 921600 <= 983040
88 // L4: <= 2228224 * 1/2 = 1114112
89 // L5: <= 8912896 * 1/4 = 2228224
90 { 1280, 720, 6, 93 },
91 { 1280, 720, 12, 120 },
92 { 1280, 720, 16, 150 },
93
94 // L5: 3840 * 2160 = 8294400 <= 8912896
95 // L6: <= 35651584 * 1/4 = 8912896
96 { 3840, 2160, 6, 150 },
97 { 3840, 2160, 7, 180 },
98 { 3840, 2160, 16, 180 },
99 };
100
101 static const H265RawProfileTierLevel profile_main = {
102 // CpbNalFactor = 1100
103 .general_profile_space = 0,
104 .general_profile_idc = 1,
105 .general_tier_flag = 0,
106 .general_profile_compatibility_flag[1] = 1,
107 };
108
109 static const H265RawProfileTierLevel profile_main_12 = {
110 // CpbNalFactor = 1650
111 .general_profile_space = 0,
112 .general_profile_idc = 4,
113 .general_tier_flag = 0,
114 .general_profile_compatibility_flag[4] = 1,
115 .general_max_12bit_constraint_flag = 1,
116 .general_max_10bit_constraint_flag = 0,
117 .general_max_8bit_constraint_flag = 0,
118 .general_max_422chroma_constraint_flag = 1,
119 .general_max_420chroma_constraint_flag = 1,
120 .general_max_monochrome_constraint_flag = 0,
121 .general_intra_constraint_flag = 0,
122 .general_one_picture_only_constraint_flag = 0,
123 .general_lower_bit_rate_constraint_flag = 1,
124 };
125
126 static const H265RawProfileTierLevel profile_main_422_12_intra = {
127 // CpbNalFactor = 2200
128 .general_profile_space = 0,
129 .general_profile_idc = 4,
130 .general_tier_flag = 0,
131 .general_profile_compatibility_flag[4] = 1,
132 .general_max_12bit_constraint_flag = 1,
133 .general_max_10bit_constraint_flag = 0,
134 .general_max_8bit_constraint_flag = 0,
135 .general_max_422chroma_constraint_flag = 1,
136 .general_max_420chroma_constraint_flag = 0,
137 .general_max_monochrome_constraint_flag = 0,
138 .general_intra_constraint_flag = 1,
139 .general_one_picture_only_constraint_flag = 0,
140 };
141
142 static const H265RawProfileTierLevel profile_ht_444_14 = {
143 // CpbNalFactor = 3850
144 .general_profile_space = 0,
145 .general_profile_idc = 5,
146 .general_tier_flag = 0,
147 .general_profile_compatibility_flag[5] = 1,
148 .general_max_14bit_constraint_flag = 1,
149 .general_max_12bit_constraint_flag = 0,
150 .general_max_10bit_constraint_flag = 0,
151 .general_max_8bit_constraint_flag = 0,
152 .general_max_422chroma_constraint_flag = 0,
153 .general_max_420chroma_constraint_flag = 0,
154 .general_max_monochrome_constraint_flag = 0,
155 .general_intra_constraint_flag = 0,
156 .general_one_picture_only_constraint_flag = 0,
157 .general_lower_bit_rate_constraint_flag = 1,
158 };
159
160 static const H265RawProfileTierLevel profile_main_high_tier = {
161 // CpbNalFactor = 1100
162 .general_profile_space = 0,
163 .general_profile_idc = 1,
164 .general_tier_flag = 1,
165 .general_profile_compatibility_flag[1] = 1,
166 };
167
168 static const struct {
169 int64_t bitrate;
170 const H265RawProfileTierLevel *ptl;
171 int level_idc;
172 } test_bitrate[] = {
173 // First level usable for some bitrates and profiles.
174
175 // L2.1: 3000 * 1100 = 3300000
176 // L3: 6000 * 1100 = 6600000
177 { 4000000, &profile_main, 90 },
178 // L2: 1500 * 1650 = 2475000
179 // L2.1: 3000 * 1650 = 4950000
180 { 4000000, &profile_main_12, 63 },
181 // L1: 350 * 2200 * 2 = 1540000
182 // L2: 1500 * 2200 * 2 = 6600000
183 { 4000000, &profile_main_422_12_intra, 60 },
184
185 // L5.1: 40000 * 1100 = 44000000
186 // L5.2: 60000 * 1100 = 66000000
187 { 50000000, &profile_main, 156 },
188 // L5: 25000 * 1650 = 41250000
189 // L5.1: 40000 * 1650 = 66000000
190 { 50000000, &profile_main_12, 153 },
191 // L3.1: 10000 * 2200 * 2 = 44000000
192 // L4: 12000 * 2200 * 2 = 52800000
193 { 50000000, &profile_main_422_12_intra, 120 },
194 // L2: 1500 * 3850 * 6 = 34650000
195 // L2.1: 3000 * 3850 * 6 = 69300000
196 { 50000000, &profile_ht_444_14, 63 },
197
198 // Level changes based on tier.
199 { 1000, &profile_main, 30 },
200 { 1000, &profile_main_high_tier, 120 },
201 { 40000000, &profile_main, 153 },
202 { 40000000, &profile_main_high_tier, 123 },
203 { 200000000, &profile_main, 186 },
204 { 200000000, &profile_main_high_tier, 156 },
205
206 // Overflowing 32-bit integers.
207 // L6: 60000 * 3850 * 6 = 1386000000
208 // L6.1: 120000 * 3850 * 6 = 2772000000
209 // L6.2: 240000 * 3850 * 6 = 5544000000
210 { INT64_C(2700000000), &profile_ht_444_14, 183 },
211 { INT64_C(4200000000), &profile_ht_444_14, 186 },
212 { INT64_C(5600000000), &profile_ht_444_14, 0 },
213 };
214
215 static const struct {
216 int slice_segments;
217 int tile_rows;
218 int tile_cols;
219 int level_idc;
220 } test_fragments[] = {
221 // Slices.
222 { 4, 1, 1, 30 },
223 { 32, 1, 1, 93 },
224 { 70, 1, 1, 120 },
225 { 80, 1, 1, 150 },
226 { 201, 1, 1, 180 },
227 { 600, 1, 1, 180 },
228 { 601, 1, 1, 0 },
229
230 // Tiles.
231 { 1, 2, 1, 90 },
232 { 1, 1, 2, 90 },
233 { 1, 3, 3, 93 },
234 { 1, 4, 2, 120 },
235 { 1, 2, 4, 120 },
236 { 1, 11, 10, 150 },
237 { 1, 10, 11, 180 },
238 { 1, 22, 20, 180 },
239 { 1, 20, 22, 0 },
240 };
241
242 1 int main(void)
243 {
244 const H265ProfileDescriptor *profile;
245 const H265LevelDescriptor *level;
246 int i;
247
248 #define CHECK(expected, format, ...) do { \
249 if (expected ? (!level || level->level_idc != expected) \
250 : !!level) { \
251 av_log(NULL, AV_LOG_ERROR, "Incorrect level for " \
252 format ": expected %d, got %d.\n", __VA_ARGS__, \
253 expected, level ? level->level_idc : -1); \
254 return 1; \
255 } \
256 } while (0)
257
258
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 1 times.
36 for (i = 0; i < FF_ARRAY_ELEMS(test_sizes); i++) {
259 35 level = ff_h265_guess_level(&profile_main, 0,
260 35 test_sizes[i].width,
261 35 test_sizes[i].height,
262 0, 0, 0, 0);
263
5/10
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 35 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
35 CHECK(test_sizes[i].level_idc, "size %dx%d",
264 test_sizes[i].width, test_sizes[i].height);
265 }
266
267
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1 times.
12 for (i = 0; i < FF_ARRAY_ELEMS(test_dpb); i++) {
268 11 level = ff_h265_guess_level(&profile_main, 0,
269 11 test_dpb[i].width,
270 11 test_dpb[i].height,
271 11 0, 0, 0, test_dpb[i].dpb_size);
272
4/10
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
11 CHECK(test_dpb[i].level_idc, "size %dx%d dpb %d",
273 test_dpb[i].width, test_dpb[i].height,
274 test_dpb[i].dpb_size);
275 }
276
277
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
17 for (i = 0; i < FF_ARRAY_ELEMS(test_bitrate); i++) {
278 16 profile = ff_h265_get_profile(test_bitrate[i].ptl);
279 16 level = ff_h265_guess_level(test_bitrate[i].ptl,
280 16 test_bitrate[i].bitrate,
281 0, 0, 0, 0, 0, 0);
282
5/10
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
16 CHECK(test_bitrate[i].level_idc, "bitrate %"PRId64" profile %s",
283 test_bitrate[i].bitrate, profile->name);
284 }
285
286
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
17 for (i = 0; i < FF_ARRAY_ELEMS(test_fragments); i++) {
287 16 level = ff_h265_guess_level(&profile_main, 0, 0, 0,
288 16 test_fragments[i].slice_segments,
289 16 test_fragments[i].tile_rows,
290 16 test_fragments[i].tile_cols, 0);
291
5/10
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
16 CHECK(test_fragments[i].level_idc, "%d slices %dx%d tiles",
292 test_fragments[i].slice_segments,
293 test_fragments[i].tile_cols, test_fragments[i].tile_rows);
294 }
295
296 1 return 0;
297 }
298