1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * This file is part of FFmpeg.
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cabdff1aSopenharmony_ci * Lesser General Public License for more details.
13cabdff1aSopenharmony_ci *
14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17cabdff1aSopenharmony_ci */
18cabdff1aSopenharmony_ci
19cabdff1aSopenharmony_ci#include "libavutil/common.h"
20cabdff1aSopenharmony_ci#include "libavcodec/h264_levels.h"
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_cistatic const struct {
23cabdff1aSopenharmony_ci    int width;
24cabdff1aSopenharmony_ci    int height;
25cabdff1aSopenharmony_ci    int level_idc;
26cabdff1aSopenharmony_ci} test_sizes[] = {
27cabdff1aSopenharmony_ci    // First level usable at some standard sizes.
28cabdff1aSopenharmony_ci    // (From H.264 table A-6.)
29cabdff1aSopenharmony_ci    {  176,  144, 10 }, // QCIF
30cabdff1aSopenharmony_ci    {  352,  288, 11 }, // CIF
31cabdff1aSopenharmony_ci    {  640,  480, 22 }, // VGA
32cabdff1aSopenharmony_ci    {  720,  480, 22 }, // NTSC
33cabdff1aSopenharmony_ci    {  720,  576, 22 }, // PAL
34cabdff1aSopenharmony_ci    {  800,  600, 31 }, // SVGA
35cabdff1aSopenharmony_ci    { 1280,  720, 31 }, // 720p
36cabdff1aSopenharmony_ci    { 1280, 1024, 32 }, // SXGA
37cabdff1aSopenharmony_ci    { 1920, 1080, 40 }, // 1080p
38cabdff1aSopenharmony_ci    { 2048, 1080, 42 }, // 2Kx1080
39cabdff1aSopenharmony_ci    { 2048, 1536, 50 }, // 4XGA
40cabdff1aSopenharmony_ci    { 3840, 2160, 51 }, // 4K
41cabdff1aSopenharmony_ci    { 7680, 4320, 60 }, // 8K
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci    // Overly wide or tall sizes.
44cabdff1aSopenharmony_ci    {    1,  256, 10 },
45cabdff1aSopenharmony_ci    {    1,  512, 11 },
46cabdff1aSopenharmony_ci    {    1, 1024, 21 },
47cabdff1aSopenharmony_ci    {    1, 1808, 22 },
48cabdff1aSopenharmony_ci    {    1, 1824, 31 },
49cabdff1aSopenharmony_ci    {  256,    1, 10 },
50cabdff1aSopenharmony_ci    {  512,    1, 11 },
51cabdff1aSopenharmony_ci    { 1024,    1, 21 },
52cabdff1aSopenharmony_ci    { 1808,    1, 22 },
53cabdff1aSopenharmony_ci    { 1824,    1, 31 },
54cabdff1aSopenharmony_ci    {  512, 4096, 40 },
55cabdff1aSopenharmony_ci    {  256, 4112, 42 },
56cabdff1aSopenharmony_ci    { 8688, 1024, 51 },
57cabdff1aSopenharmony_ci    { 8704,  512, 60 },
58cabdff1aSopenharmony_ci    { 16880,   1, 60 },
59cabdff1aSopenharmony_ci    { 16896,   1,  0 },
60cabdff1aSopenharmony_ci};
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_cistatic const struct {
63cabdff1aSopenharmony_ci    int width;
64cabdff1aSopenharmony_ci    int height;
65cabdff1aSopenharmony_ci    int framerate;
66cabdff1aSopenharmony_ci    int level_idc;
67cabdff1aSopenharmony_ci} test_framerate[] = {
68cabdff1aSopenharmony_ci    // Some typical sizes and frame rates.
69cabdff1aSopenharmony_ci    // (From H.264 table A-1 and table A-6)
70cabdff1aSopenharmony_ci    {  176,  144,  15, 10 },
71cabdff1aSopenharmony_ci    {  176,  144,  16, 11 },
72cabdff1aSopenharmony_ci    {  320,  240,  10, 11 },
73cabdff1aSopenharmony_ci    {  320,  240,  20, 12 },
74cabdff1aSopenharmony_ci    {  320,  240,  40, 21 },
75cabdff1aSopenharmony_ci    {  352,  288,  30, 13 },
76cabdff1aSopenharmony_ci    {  352,  288,  51, 22 },
77cabdff1aSopenharmony_ci    {  352,  576,  25, 21 },
78cabdff1aSopenharmony_ci    {  352,  576,  26, 30 },
79cabdff1aSopenharmony_ci    {  640,  480,  33, 30 },
80cabdff1aSopenharmony_ci    {  640,  480,  34, 31 },
81cabdff1aSopenharmony_ci    {  720,  480,  50, 31 },
82cabdff1aSopenharmony_ci    {  720,  576,  25, 30 },
83cabdff1aSopenharmony_ci    {  800,  600,  55, 31 },
84cabdff1aSopenharmony_ci    { 1024,  768,  35, 31 },
85cabdff1aSopenharmony_ci    { 1024,  768,  70, 32 },
86cabdff1aSopenharmony_ci    { 1280,  720,  30, 31 },
87cabdff1aSopenharmony_ci    { 1280,  720,  31, 32 },
88cabdff1aSopenharmony_ci    { 1280,  960,  45, 32 },
89cabdff1aSopenharmony_ci    { 1280,  960,  46, 40 },
90cabdff1aSopenharmony_ci    { 1280, 1024,  42, 32 },
91cabdff1aSopenharmony_ci    { 1600, 1200,  32, 40 },
92cabdff1aSopenharmony_ci    { 1600, 1200,  33, 42 },
93cabdff1aSopenharmony_ci    { 1920, 1088,  30, 40 },
94cabdff1aSopenharmony_ci    { 1920, 1088,  55, 42 },
95cabdff1aSopenharmony_ci    { 2048, 1024,  30, 40 },
96cabdff1aSopenharmony_ci    { 2048, 1024,  62, 42 },
97cabdff1aSopenharmony_ci    { 2048, 1088,  60, 42 },
98cabdff1aSopenharmony_ci    { 3680, 1536,  26, 50 },
99cabdff1aSopenharmony_ci    { 4096, 2048,  30, 51 },
100cabdff1aSopenharmony_ci    { 4096, 2048,  59, 52 },
101cabdff1aSopenharmony_ci    { 4096, 2160,  60, 52 },
102cabdff1aSopenharmony_ci};
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_cistatic const struct {
105cabdff1aSopenharmony_ci    int width;
106cabdff1aSopenharmony_ci    int height;
107cabdff1aSopenharmony_ci    int dpb_size;
108cabdff1aSopenharmony_ci    int level_idc;
109cabdff1aSopenharmony_ci} test_dpb[] = {
110cabdff1aSopenharmony_ci    // First level usable for some DPB sizes.
111cabdff1aSopenharmony_ci    // (From H.264 table A-7.)
112cabdff1aSopenharmony_ci    {  176,  144,  4, 10 },
113cabdff1aSopenharmony_ci    {  176,  144,  8, 11 },
114cabdff1aSopenharmony_ci    {  176,  144, 16, 12 },
115cabdff1aSopenharmony_ci    { 1280,  720,  1, 31 },
116cabdff1aSopenharmony_ci    { 1280,  720,  5, 31 },
117cabdff1aSopenharmony_ci    { 1280,  720,  9, 40 },
118cabdff1aSopenharmony_ci    { 1280,  720, 10, 50 },
119cabdff1aSopenharmony_ci    { 1920, 1080,  1, 40 },
120cabdff1aSopenharmony_ci    { 1920, 1080,  5, 50 },
121cabdff1aSopenharmony_ci    { 1920, 1080, 13, 50 },
122cabdff1aSopenharmony_ci    { 1920, 1080, 14, 51 },
123cabdff1aSopenharmony_ci    { 3840, 2160,  5, 51 },
124cabdff1aSopenharmony_ci    { 3840, 2160,  6, 60 },
125cabdff1aSopenharmony_ci    { 3840, 2160, 16, 60 },
126cabdff1aSopenharmony_ci    { 7680, 4320,  5, 60 },
127cabdff1aSopenharmony_ci    { 7680, 4320,  6,  0 },
128cabdff1aSopenharmony_ci};
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_cistatic const struct {
131cabdff1aSopenharmony_ci    int64_t bitrate;
132cabdff1aSopenharmony_ci    int profile_idc;
133cabdff1aSopenharmony_ci    int level_idc;
134cabdff1aSopenharmony_ci} test_bitrate[] = {
135cabdff1aSopenharmony_ci    // Values where profile affects level at a given bitrate.
136cabdff1aSopenharmony_ci    {   2500000,  77, 21 },
137cabdff1aSopenharmony_ci    {   2500000, 100, 20 },
138cabdff1aSopenharmony_ci    {   2500000, 244, 13 },
139cabdff1aSopenharmony_ci    { 100000000,  77, 50 },
140cabdff1aSopenharmony_ci    { 100000000, 100, 50 },
141cabdff1aSopenharmony_ci    { 100000000, 244, 41 },
142cabdff1aSopenharmony_ci    { 999999999,  77,  0 },
143cabdff1aSopenharmony_ci    { 999999999, 100, 62 },
144cabdff1aSopenharmony_ci    // Check level 1b.
145cabdff1aSopenharmony_ci    {  32 * 1200,  66, 10 },
146cabdff1aSopenharmony_ci    {  32 * 1500, 100, 10 },
147cabdff1aSopenharmony_ci    {  96 * 1200,  66, 11 },
148cabdff1aSopenharmony_ci    {  96 * 1500, 100,  9 },
149cabdff1aSopenharmony_ci    { 144 * 1200,  66, 11 },
150cabdff1aSopenharmony_ci    { 144 * 1500, 100, 11 },
151cabdff1aSopenharmony_ci};
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_cistatic const struct {
154cabdff1aSopenharmony_ci    const char *name;
155cabdff1aSopenharmony_ci    int profile_idc;
156cabdff1aSopenharmony_ci    int64_t bitrate;
157cabdff1aSopenharmony_ci    int width;
158cabdff1aSopenharmony_ci    int height;
159cabdff1aSopenharmony_ci    int dpb_frames;
160cabdff1aSopenharmony_ci    int level_idc;
161cabdff1aSopenharmony_ci} test_all[] = {
162cabdff1aSopenharmony_ci    { "Bluray 1080p 40Mb/s", 100, 40000000, 1920, 1080, 4, 41 },
163cabdff1aSopenharmony_ci    { "Bluray 1080p 24Mb/s", 100, 24000000, 1920, 1080, 4, 40 },
164cabdff1aSopenharmony_ci    { "Bluray 720p 40Mb/s",  100, 40000000, 1280,  720, 6, 41 },
165cabdff1aSopenharmony_ci    { "Bluray 720p 24Mb/s",  100, 24000000, 1280,  720, 6, 40 },
166cabdff1aSopenharmony_ci    { "Bluray PAL 40Mb/s",   100, 40000000,  720,  576, 6, 41 },
167cabdff1aSopenharmony_ci    { "Bluray PAL 24Mb/s",   100, 24000000,  720,  576, 6, 32 },
168cabdff1aSopenharmony_ci    { "Bluray PAL 16Mb/s",   100, 16800000,  720,  576, 6, 31 },
169cabdff1aSopenharmony_ci    { "Bluray PAL 12Mb/s",   100, 12000000,  720,  576, 5, 30 },
170cabdff1aSopenharmony_ci    { "Bluray NTSC 40Mb/s",  100, 40000000,  720,  480, 6, 41 },
171cabdff1aSopenharmony_ci    { "Bluray NTSC 24Mb/s",  100, 24000000,  720,  480, 6, 32 },
172cabdff1aSopenharmony_ci    { "Bluray NTSC 16Mb/s",  100, 16800000,  720,  480, 6, 31 },
173cabdff1aSopenharmony_ci    { "Bluray NTSC 12Mb/s",  100, 12000000,  720,  480, 6, 30 },
174cabdff1aSopenharmony_ci};
175cabdff1aSopenharmony_ci
176cabdff1aSopenharmony_ciint main(void)
177cabdff1aSopenharmony_ci{
178cabdff1aSopenharmony_ci    const H264LevelDescriptor *level;
179cabdff1aSopenharmony_ci    int i;
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci#define CHECK(expected, format, ...) do { \
182cabdff1aSopenharmony_ci        if (expected ? (!level || level->level_idc != expected) \
183cabdff1aSopenharmony_ci                     : !!level) { \
184cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Incorrect level for " \
185cabdff1aSopenharmony_ci                   format ": expected %d, got %d.\n", __VA_ARGS__, \
186cabdff1aSopenharmony_ci                   expected, level ? level->level_idc : -1); \
187cabdff1aSopenharmony_ci            return 1; \
188cabdff1aSopenharmony_ci        } \
189cabdff1aSopenharmony_ci    } while (0)
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(test_sizes); i++) {
192cabdff1aSopenharmony_ci        level = ff_h264_guess_level(0, 0, 0, test_sizes[i].width,
193cabdff1aSopenharmony_ci                                    test_sizes[i].height, 0);
194cabdff1aSopenharmony_ci        CHECK(test_sizes[i].level_idc, "size %dx%d",
195cabdff1aSopenharmony_ci              test_sizes[i].width, test_sizes[i].height);
196cabdff1aSopenharmony_ci    }
197cabdff1aSopenharmony_ci
198cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(test_framerate); i++) {
199cabdff1aSopenharmony_ci        level = ff_h264_guess_level(0, 0, test_framerate[i].framerate,
200cabdff1aSopenharmony_ci                                    test_framerate[i].width,
201cabdff1aSopenharmony_ci                                    test_framerate[i].height, 0);
202cabdff1aSopenharmony_ci        CHECK(test_framerate[i].level_idc, "framerate %d, size %dx%d",
203cabdff1aSopenharmony_ci              test_framerate[i].framerate, test_framerate[i].width,
204cabdff1aSopenharmony_ci              test_framerate[i].height);
205cabdff1aSopenharmony_ci    }
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(test_dpb); i++) {
208cabdff1aSopenharmony_ci        level = ff_h264_guess_level(0, 0, 0, test_dpb[i].width,
209cabdff1aSopenharmony_ci                                    test_dpb[i].height,
210cabdff1aSopenharmony_ci                                    test_dpb[i].dpb_size);
211cabdff1aSopenharmony_ci        CHECK(test_dpb[i].level_idc, "size %dx%d dpb %d",
212cabdff1aSopenharmony_ci              test_dpb[i].width, test_dpb[i].height,
213cabdff1aSopenharmony_ci              test_dpb[i].dpb_size);
214cabdff1aSopenharmony_ci    }
215cabdff1aSopenharmony_ci
216cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(test_bitrate); i++) {
217cabdff1aSopenharmony_ci        level = ff_h264_guess_level(test_bitrate[i].profile_idc,
218cabdff1aSopenharmony_ci                                    test_bitrate[i].bitrate,
219cabdff1aSopenharmony_ci                                    0, 0, 0, 0);
220cabdff1aSopenharmony_ci        CHECK(test_bitrate[i].level_idc, "bitrate %"PRId64" profile %d",
221cabdff1aSopenharmony_ci              test_bitrate[i].bitrate, test_bitrate[i].profile_idc);
222cabdff1aSopenharmony_ci    }
223cabdff1aSopenharmony_ci
224cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(test_all); i++) {
225cabdff1aSopenharmony_ci        level = ff_h264_guess_level(test_all[i].profile_idc,
226cabdff1aSopenharmony_ci                                    test_all[i].bitrate,
227cabdff1aSopenharmony_ci                                    0,
228cabdff1aSopenharmony_ci                                    test_all[i].width,
229cabdff1aSopenharmony_ci                                    test_all[i].height,
230cabdff1aSopenharmony_ci                                    test_all[i].dpb_frames);
231cabdff1aSopenharmony_ci        CHECK(test_all[i].level_idc, "%s", test_all[i].name);
232cabdff1aSopenharmony_ci    }
233cabdff1aSopenharmony_ci
234cabdff1aSopenharmony_ci    return 0;
235cabdff1aSopenharmony_ci}
236