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 <stddef.h>
20cabdff1aSopenharmony_ci#include "libavutil/macros.h"
21cabdff1aSopenharmony_ci#include "h264_levels.h"
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci// H.264 table A-1.
24cabdff1aSopenharmony_cistatic const H264LevelDescriptor h264_levels[] = {
25cabdff1aSopenharmony_ci    // Name          MaxMBPS                   MaxBR              MinCR
26cabdff1aSopenharmony_ci    //  | level_idc     |       MaxFS            |    MaxCPB        | MaxMvsPer2Mb
27cabdff1aSopenharmony_ci    //  |     | cs3f    |         |  MaxDpbMbs   |       |  MaxVmvR |   |
28cabdff1aSopenharmony_ci    { "1",   10, 0,     1485,     99,    396,     64,    175,   64, 2,  0 },
29cabdff1aSopenharmony_ci    { "1b",  11, 1,     1485,     99,    396,    128,    350,   64, 2,  0 },
30cabdff1aSopenharmony_ci    { "1b",   9, 0,     1485,     99,    396,    128,    350,   64, 2,  0 },
31cabdff1aSopenharmony_ci    { "1.1", 11, 0,     3000,    396,    900,    192,    500,  128, 2,  0 },
32cabdff1aSopenharmony_ci    { "1.2", 12, 0,     6000,    396,   2376,    384,   1000,  128, 2,  0 },
33cabdff1aSopenharmony_ci    { "1.3", 13, 0,    11880,    396,   2376,    768,   2000,  128, 2,  0 },
34cabdff1aSopenharmony_ci    { "2",   20, 0,    11880,    396,   2376,   2000,   2000,  128, 2,  0 },
35cabdff1aSopenharmony_ci    { "2.1", 21, 0,    19800,    792,   4752,   4000,   4000,  256, 2,  0 },
36cabdff1aSopenharmony_ci    { "2.2", 22, 0,    20250,   1620,   8100,   4000,   4000,  256, 2,  0 },
37cabdff1aSopenharmony_ci    { "3",   30, 0,    40500,   1620,   8100,  10000,  10000,  256, 2, 32 },
38cabdff1aSopenharmony_ci    { "3.1", 31, 0,   108000,   3600,  18000,  14000,  14000,  512, 4, 16 },
39cabdff1aSopenharmony_ci    { "3.2", 32, 0,   216000,   5120,  20480,  20000,  20000,  512, 4, 16 },
40cabdff1aSopenharmony_ci    { "4",   40, 0,   245760,   8192,  32768,  20000,  25000,  512, 4, 16 },
41cabdff1aSopenharmony_ci    { "4.1", 41, 0,   245760,   8192,  32768,  50000,  62500,  512, 2, 16 },
42cabdff1aSopenharmony_ci    { "4.2", 42, 0,   522240,   8704,  34816,  50000,  62500,  512, 2, 16 },
43cabdff1aSopenharmony_ci    { "5",   50, 0,   589824,  22080, 110400, 135000, 135000,  512, 2, 16 },
44cabdff1aSopenharmony_ci    { "5.1", 51, 0,   983040,  36864, 184320, 240000, 240000,  512, 2, 16 },
45cabdff1aSopenharmony_ci    { "5.2", 52, 0,  2073600,  36864, 184320, 240000, 240000,  512, 2, 16 },
46cabdff1aSopenharmony_ci    { "6",   60, 0,  4177920, 139264, 696320, 240000, 240000, 8192, 2, 16 },
47cabdff1aSopenharmony_ci    { "6.1", 61, 0,  8355840, 139264, 696320, 480000, 480000, 8192, 2, 16 },
48cabdff1aSopenharmony_ci    { "6.2", 62, 0, 16711680, 139264, 696320, 800000, 800000, 8192, 2, 16 },
49cabdff1aSopenharmony_ci};
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci// H.264 table A-2 plus values from A-1.
52cabdff1aSopenharmony_cistatic const struct {
53cabdff1aSopenharmony_ci    int profile_idc;
54cabdff1aSopenharmony_ci    int cpb_br_vcl_factor;
55cabdff1aSopenharmony_ci    int cpb_br_nal_factor;
56cabdff1aSopenharmony_ci} h264_br_factors[] = {
57cabdff1aSopenharmony_ci    {  66, 1000, 1200 },
58cabdff1aSopenharmony_ci    {  77, 1000, 1200 },
59cabdff1aSopenharmony_ci    {  88, 1000, 1200 },
60cabdff1aSopenharmony_ci    { 100, 1250, 1500 },
61cabdff1aSopenharmony_ci    { 110, 3000, 3600 },
62cabdff1aSopenharmony_ci    { 122, 4000, 4800 },
63cabdff1aSopenharmony_ci    { 244, 4000, 4800 },
64cabdff1aSopenharmony_ci    {  44, 4000, 4800 },
65cabdff1aSopenharmony_ci};
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci// We are only ever interested in the NAL bitrate factor.
68cabdff1aSopenharmony_cistatic int h264_get_br_factor(int profile_idc)
69cabdff1aSopenharmony_ci{
70cabdff1aSopenharmony_ci    int i;
71cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(h264_br_factors); i++) {
72cabdff1aSopenharmony_ci        if (h264_br_factors[i].profile_idc == profile_idc)
73cabdff1aSopenharmony_ci            return h264_br_factors[i].cpb_br_nal_factor;
74cabdff1aSopenharmony_ci    }
75cabdff1aSopenharmony_ci    // Default to the non-high profile value if not specified.
76cabdff1aSopenharmony_ci    return 1200;
77cabdff1aSopenharmony_ci}
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ciconst H264LevelDescriptor *ff_h264_guess_level(int profile_idc,
80cabdff1aSopenharmony_ci                                               int64_t bitrate,
81cabdff1aSopenharmony_ci                                               int framerate,
82cabdff1aSopenharmony_ci                                               int width, int height,
83cabdff1aSopenharmony_ci                                               int max_dec_frame_buffering)
84cabdff1aSopenharmony_ci{
85cabdff1aSopenharmony_ci    int width_mbs  = (width  + 15) / 16;
86cabdff1aSopenharmony_ci    int height_mbs = (height + 15) / 16;
87cabdff1aSopenharmony_ci    int no_cs3f = !(profile_idc == 66 ||
88cabdff1aSopenharmony_ci                    profile_idc == 77 ||
89cabdff1aSopenharmony_ci                    profile_idc == 88);
90cabdff1aSopenharmony_ci    int i;
91cabdff1aSopenharmony_ci
92cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(h264_levels); i++) {
93cabdff1aSopenharmony_ci        const H264LevelDescriptor *level = &h264_levels[i];
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci        if (level->constraint_set3_flag && no_cs3f)
96cabdff1aSopenharmony_ci            continue;
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci        if (bitrate > (int64_t)level->max_br * h264_get_br_factor(profile_idc))
99cabdff1aSopenharmony_ci            continue;
100cabdff1aSopenharmony_ci
101cabdff1aSopenharmony_ci        if (width_mbs  * height_mbs > level->max_fs)
102cabdff1aSopenharmony_ci            continue;
103cabdff1aSopenharmony_ci        if (width_mbs  * width_mbs  > 8 * level->max_fs)
104cabdff1aSopenharmony_ci            continue;
105cabdff1aSopenharmony_ci        if (height_mbs * height_mbs > 8 * level->max_fs)
106cabdff1aSopenharmony_ci            continue;
107cabdff1aSopenharmony_ci
108cabdff1aSopenharmony_ci        if (width_mbs && height_mbs) {
109cabdff1aSopenharmony_ci            int max_dpb_frames =
110cabdff1aSopenharmony_ci                FFMIN(level->max_dpb_mbs / (width_mbs * height_mbs), 16);
111cabdff1aSopenharmony_ci            if (max_dec_frame_buffering > max_dpb_frames)
112cabdff1aSopenharmony_ci                continue;
113cabdff1aSopenharmony_ci
114cabdff1aSopenharmony_ci            if (framerate > (level->max_mbps / (width_mbs * height_mbs)))
115cabdff1aSopenharmony_ci                continue;
116cabdff1aSopenharmony_ci        }
117cabdff1aSopenharmony_ci
118cabdff1aSopenharmony_ci        return level;
119cabdff1aSopenharmony_ci    }
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    // No usable levels found - frame is too big or bitrate is too high.
122cabdff1aSopenharmony_ci    return NULL;
123cabdff1aSopenharmony_ci}
124