• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main(void)242 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     for (i = 0; i < FF_ARRAY_ELEMS(test_sizes); i++) {
259         level = ff_h265_guess_level(&profile_main, 0,
260                                     test_sizes[i].width,
261                                     test_sizes[i].height,
262                                     0, 0, 0, 0);
263         CHECK(test_sizes[i].level_idc, "size %dx%d",
264               test_sizes[i].width, test_sizes[i].height);
265     }
266 
267     for (i = 0; i < FF_ARRAY_ELEMS(test_dpb); i++) {
268         level = ff_h265_guess_level(&profile_main, 0,
269                                     test_dpb[i].width,
270                                     test_dpb[i].height,
271                                     0, 0, 0, test_dpb[i].dpb_size);
272         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     for (i = 0; i < FF_ARRAY_ELEMS(test_bitrate); i++) {
278         profile = ff_h265_get_profile(test_bitrate[i].ptl);
279         level = ff_h265_guess_level(test_bitrate[i].ptl,
280                                     test_bitrate[i].bitrate,
281                                     0, 0, 0, 0, 0, 0);
282         CHECK(test_bitrate[i].level_idc, "bitrate %"PRId64" profile %s",
283               test_bitrate[i].bitrate, profile->name);
284     }
285 
286     for (i = 0; i < FF_ARRAY_ELEMS(test_fragments); i++) {
287         level = ff_h265_guess_level(&profile_main, 0, 0, 0,
288                                     test_fragments[i].slice_segments,
289                                     test_fragments[i].tile_rows,
290                                     test_fragments[i].tile_cols, 0);
291         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     return 0;
297 }
298