Coverage Report

Created: 2025-07-23 08:18

/src/x265/source/encoder/level.cpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * Copyright (C) 2013-2020 MulticoreWare, Inc
3
 *
4
 * Authors: Steve Borho <steve@borho.org>
5
 *          Min Chen <chenm003@163.com>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
20
 *
21
 * This program is also available under a commercial proprietary license.
22
 * For more information, contact us at license @ x265.com.
23
 *****************************************************************************/
24
25
#include "common.h"
26
#include "slice.h"
27
#include "level.h"
28
#include "svt.h"
29
30
namespace X265_NS {
31
typedef struct
32
{
33
    uint32_t maxLumaSamples;
34
    uint64_t maxLumaSamplesPerSecond;
35
    uint32_t maxBitrateMain;
36
    uint32_t maxBitrateHigh;
37
    uint32_t maxCpbSizeMain;
38
    uint32_t maxCpbSizeHigh;
39
    uint32_t minCompressionRatio;
40
    Level::Name levelEnum;
41
    const char* name;
42
    int levelIdc;
43
} LevelSpec;
44
45
LevelSpec levels[] =
46
{
47
    { 36864,      552960,         128,      MAX_UINT, 350,     MAX_UINT, 2, Level::LEVEL1,   "1",   10 },
48
    { 122880,     3686400,        1500,     MAX_UINT, 1500,    MAX_UINT, 2, Level::LEVEL2,   "2",   20 },
49
    { 245760,     7372800,        3000,     MAX_UINT, 3000,    MAX_UINT, 2, Level::LEVEL2_1, "2.1", 21 },
50
    { 552960,     16588800,       6000,     MAX_UINT, 6000,    MAX_UINT, 2, Level::LEVEL3,   "3",   30 },
51
    { 983040,     33177600,       10000,    MAX_UINT, 10000,   MAX_UINT, 2, Level::LEVEL3_1, "3.1", 31 },
52
    { 2228224,    66846720,       12000,    30000,    12000,   30000,    4, Level::LEVEL4,   "4",   40 },
53
    { 2228224,    133693440,      20000,    50000,    20000,   50000,    4, Level::LEVEL4_1, "4.1", 41 },
54
    { 8912896,    267386880,      25000,    100000,   25000,   100000,   6, Level::LEVEL5,   "5",   50 },
55
    { 8912896,    534773760,      40000,    160000,   40000,   160000,   8, Level::LEVEL5_1, "5.1", 51 },
56
    { 8912896,    1069547520,     60000,    240000,   60000,   240000,   8, Level::LEVEL5_2, "5.2", 52 },
57
    { 35651584,   1069547520,     60000,    240000,   60000,   240000,   8, Level::LEVEL6,   "6",   60 },
58
    { 35651584,   2139095040,     120000,   480000,   120000,  480000,   8, Level::LEVEL6_1, "6.1", 61 },
59
    { 35651584,   4278190080U,    240000,   800000,   240000,  800000,   6, Level::LEVEL6_2, "6.2", 62 },
60
    { 80216064,   4812963840ULL,  320000,   1600000,  240000,  1600000,  6, Level::LEVEL6_3, "6.3", 63 },
61
    { 142606336,  4812963840ULL,  320000,   1600000,  240000,  1600000,  6, Level::LEVEL7,   "7",   70 },
62
    { 142606336,  8556380160ULL,  480000,   3200000,  480000,  3200000,  6, Level::LEVEL7_1, "7.1", 71 },
63
    { 142606336,  17112760320ULL, 960000,   6400000,  960000,  6400000,  6, Level::LEVEL7_2, "7.2", 72 },
64
    { MAX_UINT, MAX_UINT64, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, 1, Level::LEVEL8_5, "8.5", 85 },
65
};
66
67
/* determine minimum decoder level required to decode the described video */
68
void determineLevel(const x265_param &param, VPS& vps)
69
0
{
70
0
    vps.ptl.onePictureOnlyConstraintFlag = param.totalFrames == 1;
71
0
    vps.ptl.intraConstraintFlag = param.keyframeMax <= 1 || vps.ptl.onePictureOnlyConstraintFlag;
72
0
    vps.ptl.bitDepthConstraint = param.internalBitDepth;
73
0
    vps.ptl.chromaFormatConstraint = param.internalCsp;
74
75
    /* TODO: figure out HighThroughput signaling, aka: HbrFactor in section A.4.2, only available
76
     * for intra-only profiles (vps.ptl.intraConstraintFlag) */
77
0
    vps.ptl.lowerBitRateConstraintFlag = true;
78
79
0
    vps.maxTempSubLayers = !!param.bEnableTemporalSubLayers ? param.bEnableTemporalSubLayers : 1;
80
    
81
0
    if (param.internalCsp == X265_CSP_I420 && param.internalBitDepth <= 10)
82
0
    {
83
        /* Probably an HEVC v1 profile, but must check to be sure */
84
0
        if (param.internalBitDepth <= 8)
85
0
        {
86
0
            if (vps.ptl.onePictureOnlyConstraintFlag)
87
0
                vps.ptl.profileIdc[0] = Profile::MAINSTILLPICTURE;
88
0
            else if (vps.ptl.intraConstraintFlag)
89
0
                vps.ptl.profileIdc[0] = Profile::MAINREXT; /* Main Intra */
90
0
            else 
91
0
                vps.ptl.profileIdc[0] = Profile::MAIN;
92
93
#if ENABLE_ALPHA
94
            if (param.numScalableLayers == 2)
95
                vps.ptl.profileIdc[1] = Profile::SCALABLEMAIN;
96
#endif
97
0
        }
98
0
        else if (param.internalBitDepth <= 10)
99
0
        {
100
            /* note there is no 10bit still picture profile */
101
0
            if (vps.ptl.intraConstraintFlag)
102
0
                vps.ptl.profileIdc[0] = Profile::MAINREXT; /* Main10 Intra */
103
0
            else
104
0
                vps.ptl.profileIdc[0] = Profile::MAIN10;
105
106
#if ENABLE_ALPHA
107
            if (param.numScalableLayers == 2)
108
                vps.ptl.profileIdc[1] = Profile::SCALABLEMAIN10;
109
#endif
110
0
        }
111
0
    }
112
0
    else
113
0
        vps.ptl.profileIdc[0] = Profile::MAINREXT;
114
115
#if ENABLE_MULTIVIEW
116
    if (param.numViews == 2)
117
        vps.ptl.profileIdc[1] = Profile::MULTIVIEWMAIN;
118
#endif
119
120
#if ENABLE_SCC_EXT
121
    if (param.bEnableSCC)
122
        vps.ptl.profileIdc[0] = Profile::MAINSCC;
123
124
    /* determine which profiles are compatible with this stream */
125
    if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
126
    {
127
        vps.ptl.onePictureOnlyConstraintFlag = false;
128
        vps.ptl.intraConstraintFlag = param.keyframeMax <= 1 || vps.ptl.onePictureOnlyConstraintFlag;
129
    }
130
#endif
131
132
0
    memset(vps.ptl.profileCompatibilityFlag, 0, sizeof(vps.ptl.profileCompatibilityFlag));
133
0
    vps.ptl.profileCompatibilityFlag[vps.ptl.profileIdc[0]] = true;
134
0
    if (vps.ptl.profileIdc[0] == Profile::MAIN10 && param.internalBitDepth == 8)
135
0
        vps.ptl.profileCompatibilityFlag[Profile::MAIN] = true;
136
0
    else if (vps.ptl.profileIdc[0] == Profile::MAIN)
137
0
        vps.ptl.profileCompatibilityFlag[Profile::MAIN10] = true;
138
0
    else if (vps.ptl.profileIdc[0] == Profile::MAINSTILLPICTURE)
139
0
    {
140
0
        vps.ptl.profileCompatibilityFlag[Profile::MAIN] = true;
141
0
        vps.ptl.profileCompatibilityFlag[Profile::MAIN10] = true;
142
0
    }
143
0
    else if (vps.ptl.profileIdc[0] == Profile::MAINREXT)
144
0
        vps.ptl.profileCompatibilityFlag[Profile::MAINREXT] = true;
145
#if ENABLE_SCC_EXT
146
    else if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
147
        vps.ptl.profileCompatibilityFlag[Profile::MAINSCC] = true;
148
#endif
149
150
0
    uint32_t lumaSamples = param.sourceWidth * param.sourceHeight;
151
0
    uint64_t samplesPerSec = (uint64_t)(lumaSamples * ((double)param.fpsNum / param.fpsDenom));
152
0
    uint32_t bitrate = param.rc.vbvMaxBitrate ? param.rc.vbvMaxBitrate : param.rc.bitrate;
153
154
0
    const uint32_t MaxDpbPicBuf = param.bEnableSCC ? 7 : 6;
155
0
    vps.ptl.levelIdc = Level::NONE;
156
0
    vps.ptl.tierFlag = Level::MAIN;
157
158
0
    const size_t NumLevels = sizeof(levels) / sizeof(levels[0]);
159
0
    uint32_t i;
160
0
    if (param.bLossless)
161
0
    {
162
0
        i = NumLevels - 1;
163
0
        vps.ptl.minCrForLevel = 1;
164
0
        vps.ptl.maxLumaSrForLevel = MAX_UINT64;
165
0
        vps.ptl.levelIdc = Level::LEVEL8_5;
166
0
        vps.ptl.tierFlag = Level::MAIN;
167
0
    }
168
0
    else if (param.uhdBluray)
169
0
    {
170
0
        i = 8;
171
0
        vps.ptl.levelIdc = levels[i].levelEnum;
172
0
        vps.ptl.tierFlag = Level::HIGH;
173
0
        vps.ptl.minCrForLevel = levels[i].minCompressionRatio;
174
0
        vps.ptl.maxLumaSrForLevel = levels[i].maxLumaSamplesPerSecond;
175
0
    }
176
0
    else for (i = 0; i < NumLevels; i++)
177
0
    {
178
0
        if (lumaSamples > levels[i].maxLumaSamples)
179
0
            continue;
180
0
        else if (samplesPerSec > levels[i].maxLumaSamplesPerSecond)
181
0
            continue;
182
0
        else if (bitrate > levels[i].maxBitrateMain && levels[i].maxBitrateHigh == MAX_UINT)
183
0
            continue;
184
0
        else if (bitrate > levels[i].maxBitrateHigh)
185
0
            continue;
186
0
        else if (param.sourceWidth > sqrt(levels[i].maxLumaSamples * 8.0f))
187
0
            continue;
188
0
        else if (param.sourceHeight > sqrt(levels[i].maxLumaSamples * 8.0f))
189
0
            continue;
190
0
        else if (param.levelIdc && param.levelIdc != levels[i].levelIdc)
191
0
            continue;
192
0
        uint32_t maxDpbSize = MaxDpbPicBuf;
193
194
0
        if (lumaSamples <= (levels[i].maxLumaSamples >> 2))
195
0
            maxDpbSize = X265_MIN(4 * MaxDpbPicBuf, 16);
196
0
        else if (lumaSamples <= (levels[i].maxLumaSamples >> 1))
197
0
            maxDpbSize = X265_MIN(2 * MaxDpbPicBuf, 16);
198
0
        else if (lumaSamples <= ((3 * levels[i].maxLumaSamples) >> 2))
199
0
            maxDpbSize = X265_MIN((4 * MaxDpbPicBuf) / 3, 16);
200
201
        /* The value of sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1 shall be less than
202
         * or equal to MaxDpbSize */
203
0
        if (vps.maxDecPicBuffering[vps.maxTempSubLayers - 1] > maxDpbSize)
204
0
            continue;
205
206
        /* For level 5 and higher levels, the value of CtbSizeY shall be equal to 32 or 64 */
207
0
        if (levels[i].levelEnum >= Level::LEVEL5 && param.maxCUSize < 32)
208
0
        {
209
0
            x265_log(&param, X265_LOG_WARNING, "level %s detected, but CTU size 16 is non-compliant\n", levels[i].name);
210
0
            vps.ptl.profileIdc[0] = Profile::NONE;
211
0
            vps.ptl.levelIdc = Level::NONE;
212
0
            vps.ptl.tierFlag = Level::MAIN;
213
0
            x265_log(&param, X265_LOG_INFO, "NONE profile, Level-NONE (Main tier)\n");
214
0
            return;
215
0
        }
216
217
        /* The value of NumPocTotalCurr shall be less than or equal to 8 */
218
0
        int numPocTotalCurr = param.maxNumReferences + vps.numReorderPics[vps.maxTempSubLayers - 1];
219
0
        if (numPocTotalCurr > 10)
220
0
        {
221
0
            x265_log(&param, X265_LOG_WARNING, "level %s detected, but NumPocTotalCurr (total references) is non-compliant\n", levels[i].name);
222
0
            vps.ptl.profileIdc[0] = Profile::NONE;
223
0
            vps.ptl.levelIdc = Level::NONE;
224
0
            vps.ptl.tierFlag = Level::MAIN;
225
0
            x265_log(&param, X265_LOG_INFO, "NONE profile, Level-NONE (Main tier)\n");
226
0
            return;
227
0
        }
228
229
0
#define CHECK_RANGE(value, main, high) (high != MAX_UINT && value > main && value <= high)
230
231
0
        if (CHECK_RANGE(bitrate, levels[i].maxBitrateMain, levels[i].maxBitrateHigh) ||
232
0
            CHECK_RANGE((uint32_t)param.rc.vbvBufferSize, levels[i].maxCpbSizeMain, levels[i].maxCpbSizeHigh))
233
0
        {
234
            /* The bitrate or buffer size are out of range for Main tier, but in
235
             * range for High tier. If the user allowed High tier then give
236
             * them High tier at this level.  Otherwise allow the loop to
237
             * progress to the Main tier of the next level */
238
0
            if (param.bHighTier)
239
0
                vps.ptl.tierFlag = Level::HIGH;
240
0
            else
241
0
                continue;
242
0
        }
243
0
        else
244
0
            vps.ptl.tierFlag = Level::MAIN;
245
0
#undef CHECK_RANGE
246
247
0
        vps.ptl.levelIdc = levels[i].levelEnum;
248
0
        vps.ptl.minCrForLevel = levels[i].minCompressionRatio;
249
0
        vps.ptl.maxLumaSrForLevel = levels[i].maxLumaSamplesPerSecond;
250
0
        break;
251
0
    }
252
253
0
    static const char* profiles[] = { "None", "Main", "Main 10", "Main Still Picture", "RExt", "", "", "", "", "Main Scc" };
254
0
    static const char *tiers[]    = { "Main", "High" };
255
256
0
    char profbuf[64];
257
0
    strcpy(profbuf, profiles[vps.ptl.profileIdc[0]]);
258
259
0
    bool bStillPicture = false;
260
0
    if (vps.ptl.profileIdc[0] == Profile::MAINREXT)
261
0
    {
262
0
        if (vps.ptl.bitDepthConstraint > 12 && vps.ptl.intraConstraintFlag)
263
0
        {
264
0
            if (vps.ptl.onePictureOnlyConstraintFlag)
265
0
            {
266
0
                strcpy(profbuf, "Main 4:4:4 16 Still Picture");
267
0
                bStillPicture = true;
268
0
            }
269
0
            else
270
0
                strcpy(profbuf, "Main 4:4:4 16");
271
0
        }
272
0
        else if (param.internalCsp == X265_CSP_I420)
273
0
        {
274
0
            X265_CHECK(vps.ptl.intraConstraintFlag || vps.ptl.bitDepthConstraint > 10, "rext fail\n");
275
0
            if (vps.ptl.bitDepthConstraint <= 8)
276
0
                strcpy(profbuf, "Main");
277
0
            else if (vps.ptl.bitDepthConstraint <= 10)
278
0
                strcpy(profbuf, "Main 10");
279
0
            else if (vps.ptl.bitDepthConstraint <= 12)
280
0
                strcpy(profbuf, "Main 12");
281
0
        }
282
0
        else if (param.internalCsp == X265_CSP_I422)
283
0
        {
284
            /* there is no Main 4:2:2 profile, so it must be signaled as Main10 4:2:2 */
285
0
            if (param.internalBitDepth <= 10)
286
0
                strcpy(profbuf, "Main 4:2:2 10");
287
0
            else if (vps.ptl.bitDepthConstraint <= 12)
288
0
                strcpy(profbuf, "Main 4:2:2 12");
289
0
        }
290
0
        else if (param.internalCsp == X265_CSP_I444)
291
0
        {
292
0
            if (vps.ptl.bitDepthConstraint <= 8)
293
0
            {
294
0
                if (vps.ptl.onePictureOnlyConstraintFlag)
295
0
                {
296
0
                    strcpy(profbuf, "Main 4:4:4 Still Picture");
297
0
                    bStillPicture = true;
298
0
                }
299
0
                else
300
0
                    strcpy(profbuf, "Main 4:4:4");
301
0
            }
302
0
            else if (vps.ptl.bitDepthConstraint <= 10)
303
0
                strcpy(profbuf, "Main 4:4:4 10");
304
0
            else if (vps.ptl.bitDepthConstraint <= 12)
305
0
                strcpy(profbuf, "Main 4:4:4 12");
306
0
        }
307
0
        else
308
0
            strcpy(profbuf, "Unknown");
309
310
0
        if (vps.ptl.intraConstraintFlag && !bStillPicture)
311
0
            strcat(profbuf, " Intra");
312
0
    }
313
314
#if ENABLE_SCC_EXT
315
    if (vps.ptl.profileIdc[0] == Profile::MAINSCC)
316
    {
317
        if (param.internalCsp == X265_CSP_I420)
318
        {
319
            if (vps.ptl.bitDepthConstraint <= 8)
320
                strcpy(profbuf, "Main Scc");
321
            else if (vps.ptl.bitDepthConstraint <= 10)
322
                strcpy(profbuf, "Main 10 Scc");
323
        }
324
        else if (param.internalCsp == X265_CSP_I444)
325
        {
326
            if (vps.ptl.bitDepthConstraint <= 8)
327
                strcpy(profbuf, "Main 4:4:4 Scc");
328
            else if (vps.ptl.bitDepthConstraint <= 10)
329
                strcpy(profbuf, "Main 4:4:4 10 Scc");
330
        }
331
    }
332
#endif
333
334
0
    x265_log(&param, X265_LOG_INFO, "%s profile, Level-%s (%s tier)\n",
335
0
             profbuf, levels[i].name, tiers[vps.ptl.tierFlag]);
336
0
}
337
338
/* enforce a maximum decoder level requirement, in other words assure that a
339
 * decoder of the specified level may decode the video about to be created.
340
 * Lower parameters where necessary to ensure the video will be decodable by a
341
 * decoder meeting this level of requirement.  Some parameters (resolution and
342
 * frame rate) are non-negotiable and thus this function may fail. In those
343
 * circumstances it will be quite noisy */
344
bool enforceLevel(x265_param& param, VPS& vps)
345
0
{
346
0
    vps.maxTempSubLayers = !!param.bEnableTemporalSubLayers ? param.bEnableTemporalSubLayers : 1;
347
0
    for (uint32_t i = 0; i < vps.maxTempSubLayers; i++)
348
0
    {
349
0
        vps.numReorderPics[i] = (i == 0) ? ((param.bBPyramid && param.bframes > 1) ? 2 : !!param.bframes) : i;
350
0
        vps.maxDecPicBuffering[i] = X265_MIN(MAX_NUM_REF, X265_MAX(vps.numReorderPics[i] + 2, (uint32_t)param.maxNumReferences) + 1) + !!param.bEnableSCC;
351
0
    }
352
353
0
    if (!!param.bEnableTemporalSubLayers)
354
0
    {
355
0
        for (int i = 0; i < MAX_T_LAYERS - 1; i++)
356
0
        {
357
            // a lower layer can not have higher value of numReorderPics than a higher layer
358
0
            if (vps.numReorderPics[i + 1] < vps.numReorderPics[i])
359
0
            {
360
0
                vps.numReorderPics[i + 1] = vps.numReorderPics[i];
361
0
            }
362
            // the value of numReorderPics[i] shall be in the range of 0 to maxDecPicBuffering[i] - 1, inclusive
363
0
            if (vps.numReorderPics[i] > vps.maxDecPicBuffering[i] - 1)
364
0
            {
365
0
                vps.maxDecPicBuffering[i] = vps.numReorderPics[i] + 1;
366
0
            }
367
            // a lower layer can not have higher value of maxDecPicBuffering than a higher layer
368
0
            if (vps.maxDecPicBuffering[i + 1] < vps.maxDecPicBuffering[i])
369
0
            {
370
0
                vps.maxDecPicBuffering[i + 1] = vps.maxDecPicBuffering[i];
371
0
            }
372
0
        }
373
374
        // the value of numReorderPics[i] shall be in the range of 0 to maxDecPicBuffering[ i ] -  1, inclusive
375
0
        if (vps.numReorderPics[MAX_T_LAYERS - 1] > vps.maxDecPicBuffering[MAX_T_LAYERS - 1] - 1)
376
0
        {
377
0
            vps.maxDecPicBuffering[MAX_T_LAYERS - 1] = vps.numReorderPics[MAX_T_LAYERS - 1] + 1;
378
0
        }
379
0
    }
380
    /* no level specified by user, just auto-detect from the configuration */
381
0
    if (param.levelIdc <= 0)
382
0
        return true;
383
384
0
    uint32_t level = 0;
385
0
    while (levels[level].levelIdc != param.levelIdc && level + 1 < sizeof(levels) / sizeof(levels[0]))
386
0
        level++;
387
0
    if (levels[level].levelIdc != param.levelIdc)
388
0
    {
389
0
        x265_log(&param, X265_LOG_ERROR, "specified level %d does not exist\n", param.levelIdc);
390
0
        return false;
391
0
    }
392
393
0
    LevelSpec& l = levels[level];
394
395
    //highTier is allowed for this level and has not been explicitly disabled. This does not mean it is the final chosen tier
396
0
    bool allowHighTier = l.maxBitrateHigh < MAX_UINT && param.bHighTier;
397
398
0
    uint32_t lumaSamples = param.sourceWidth * param.sourceHeight;
399
0
    uint64_t samplesPerSec = (uint64_t)(lumaSamples * ((double)param.fpsNum / param.fpsDenom));
400
0
    bool ok = true;
401
0
    if (lumaSamples > l.maxLumaSamples)
402
0
        ok = false;
403
0
    else if (param.sourceWidth > sqrt(l.maxLumaSamples * 8.0f))
404
0
        ok = false;
405
0
    else if (param.sourceHeight > sqrt(l.maxLumaSamples * 8.0f))
406
0
        ok = false;
407
0
    if (!ok)
408
0
    {
409
0
        x265_log(&param, X265_LOG_ERROR, "picture dimensions are out of range for specified level\n");
410
0
        return false;
411
0
    }
412
0
    else if (samplesPerSec > l.maxLumaSamplesPerSecond)
413
0
    {
414
0
        x265_log(&param, X265_LOG_ERROR, "frame rate is out of range for specified level\n");
415
0
        return false;
416
0
    }
417
418
    /* Adjustments of Bitrate, VBV buffer size, refs will be triggered only if specified params do not fit 
419
     * within the max limits of that level (high tier if allowed, main otherwise)
420
     */
421
422
0
    if ((uint32_t)param.rc.vbvMaxBitrate > (allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain))
423
0
    {
424
0
        param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
425
0
        x265_log(&param, X265_LOG_WARNING, "lowering VBV max bitrate to %dKbps\n", param.rc.vbvMaxBitrate);
426
0
    }
427
0
    if ((uint32_t)param.rc.vbvBufferSize > (allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain))
428
0
    {
429
0
        param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
430
0
        x265_log(&param, X265_LOG_WARNING, "lowering VBV buffer size to %dKb\n", param.rc.vbvBufferSize);
431
0
    }
432
433
0
    switch (param.rc.rateControlMode)
434
0
    {
435
0
    case X265_RC_ABR:
436
0
        if ((uint32_t)param.rc.bitrate > (allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain))
437
0
        {
438
0
            param.rc.bitrate =  allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
439
0
            x265_log(&param, X265_LOG_WARNING, "lowering target bitrate to High tier limit of %dKbps\n", param.rc.bitrate);
440
0
        }
441
0
        break;
442
443
0
    case X265_RC_CQP:
444
0
        x265_log(&param, X265_LOG_ERROR, "Constant QP is inconsistent with specifying a decoder level, no bitrate guarantee is possible.\n");
445
0
        return false;
446
447
0
    case X265_RC_CRF:
448
0
        if (!param.rc.vbvBufferSize || !param.rc.vbvMaxBitrate)
449
0
        {
450
0
            if (!param.rc.vbvMaxBitrate)
451
0
                param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
452
0
            if (!param.rc.vbvBufferSize)
453
0
                param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
454
0
            x265_log(&param, X265_LOG_WARNING, "Specifying a decoder level with constant rate factor rate-control requires\n");
455
0
            x265_log(&param, X265_LOG_WARNING, "enabling VBV with vbv-bufsize=%dkb vbv-maxrate=%dkbps. VBV outputs are non-deterministic!\n",
456
0
                     param.rc.vbvBufferSize, param.rc.vbvMaxBitrate);
457
0
        }
458
0
        break;
459
460
0
    default:
461
0
        x265_log(&param, X265_LOG_ERROR, "Unknown rate control mode is inconsistent with specifying a decoder level\n");
462
0
        return false;
463
0
    }
464
465
    /* The value of sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1 shall be less than or equal to MaxDpbSize */
466
0
    const uint32_t MaxDpbPicBuf = param.bEnableSCC ? 7 : 6;
467
0
    uint32_t maxDpbSize = MaxDpbPicBuf;
468
0
    if (!param.uhdBluray) /* Do not change MaxDpbPicBuf for UHD-Bluray */
469
0
    {
470
0
        if (lumaSamples <= (l.maxLumaSamples >> 2))
471
0
            maxDpbSize = X265_MIN(4 * MaxDpbPicBuf, 16);
472
0
        else if (lumaSamples <= (l.maxLumaSamples >> 1))
473
0
            maxDpbSize = X265_MIN(2 * MaxDpbPicBuf, 16);
474
0
        else if (lumaSamples <= ((3 * l.maxLumaSamples) >> 2))
475
0
            maxDpbSize = X265_MIN((4 * MaxDpbPicBuf) / 3, 16);
476
0
    }
477
478
0
    int savedRefCount = param.maxNumReferences;
479
0
    while (vps.maxDecPicBuffering[vps.maxTempSubLayers - 1] > maxDpbSize && param.maxNumReferences > 1)
480
0
    {
481
0
        param.maxNumReferences--;
482
0
        vps.maxDecPicBuffering[vps.maxTempSubLayers - 1] = X265_MIN(MAX_NUM_REF, X265_MAX(vps.numReorderPics[vps.maxTempSubLayers - 1] + 1, (uint32_t)param.maxNumReferences) + 1 + !!param.bEnableSCC);
483
0
    }
484
0
    if (param.maxNumReferences != savedRefCount)
485
0
        x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to meet level requirement\n", param.maxNumReferences);
486
487
    /* For level 5 and higher levels, the value of CtbSizeY shall be equal to 32 or 64 */
488
0
    if (param.levelIdc >= 50 && param.maxCUSize < 32)
489
0
    {
490
0
        param.maxCUSize = 32;
491
0
        x265_log(&param, X265_LOG_WARNING, "Levels 5.0 and above require a maximum CTU size of at least 32, using --ctu 32\n");
492
0
    }
493
494
    /* The value of NumPocTotalCurr shall be less than or equal to 8 */
495
0
    int numPocTotalCurr = param.maxNumReferences + !!param.bframes;
496
0
    if (numPocTotalCurr > 8)
497
0
    {
498
0
        param.maxNumReferences = 8 - !!param.bframes;
499
0
        x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to meet numPocTotalCurr requirement\n", param.maxNumReferences);
500
0
    }
501
502
0
    return true;
503
0
}
504
}
505
506
#if EXPORT_C_API
507
508
/* these functions are exported as C functions (default) */
509
using namespace X265_NS;
510
extern "C" {
511
512
#else
513
514
/* these functions exist within private namespace (multilib) */
515
namespace X265_NS {
516
517
#endif
518
519
int x265_param_apply_profile(x265_param *param, const char *profile)
520
0
{
521
0
    if (!param || !profile)
522
0
        return 0;
523
524
#ifdef SVT_HEVC
525
    if (param->bEnableSvtHevc)
526
    {
527
        EB_H265_ENC_CONFIGURATION* svtParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
528
        if (!strcmp(profile, "main"))    svtParam->profile = 1;
529
        else if (!strcmp(profile, "main10"))    svtParam->profile = 2;
530
        else
531
        {
532
            x265_log(param, X265_LOG_ERROR, "SVT-HEVC encoder: Unsupported profile %s \n", profile);
533
            return -1;
534
        }
535
        return 0;
536
    }
537
#endif
538
539
    /* Check if profile bit-depth requirement is exceeded by internal bit depth */
540
0
    bool bInvalidDepth = false;
541
#if X265_DEPTH > 8
542
    if (!strcmp(profile, "main") || !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp") ||
543
        !strcmp(profile, "main444-8") || !strcmp(profile, "main-intra") ||
544
        !strcmp(profile, "main444-intra") || !strcmp(profile, "main444-stillpicture"))
545
        bInvalidDepth = true;
546
#endif
547
#if X265_DEPTH > 10
548
    if (!strcmp(profile, "main10") || !strcmp(profile, "main422-10") || !strcmp(profile, "main444-10") ||
549
        !strcmp(profile, "main10-intra") || !strcmp(profile, "main422-10-intra") || !strcmp(profile, "main444-10-intra"))
550
        bInvalidDepth = true;
551
#endif
552
#if X265_DEPTH > 12
553
    if (!strcmp(profile, "main12") || !strcmp(profile, "main422-12") || !strcmp(profile, "main444-12") ||
554
        !strcmp(profile, "main12-intra") || !strcmp(profile, "main422-12-intra") || !strcmp(profile, "main444-12-intra"))
555
        bInvalidDepth = true;
556
#endif
557
558
0
    if (bInvalidDepth)
559
0
    {
560
0
        x265_log(param, X265_LOG_ERROR, "%s profile not supported, internal bit depth %d.\n", profile, X265_DEPTH);
561
0
        return -1;
562
0
    }
563
564
0
    size_t l = strlen(profile);
565
0
    bool bBoolIntra = (l > 6 && !strcmp(profile + l - 6, "-intra")) ||
566
0
                      !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp");
567
0
    if (bBoolIntra)
568
0
    {
569
        /* The profile may be detected as still picture if param->totalFrames is 1 */
570
0
        param->keyframeMax = 1;
571
0
    }
572
    
573
    /* check that input color space is supported by profile */
574
0
    if (!strcmp(profile, "main") || !strcmp(profile, "main-intra") ||
575
0
        !strcmp(profile, "main10") || !strcmp(profile, "main10-intra") ||
576
0
        !strcmp(profile, "main12") || !strcmp(profile, "main12-intra") ||
577
0
        !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp") ||
578
0
        !strcmp(profile, "main-scc") || !strcmp(profile, "main10-scc"))
579
0
    {
580
0
        if (param->internalCsp != X265_CSP_I420)
581
0
        {
582
0
            x265_log(param, X265_LOG_ERROR, "%s profile not compatible with %s input chroma subsampling.\n",
583
0
                     profile, x265_source_csp_names[param->internalCsp]);
584
0
            return -1;
585
0
        }
586
0
    }
587
0
    else if (!strcmp(profile, "main422-10") || !strcmp(profile, "main422-10-intra") ||
588
0
             !strcmp(profile, "main422-12") || !strcmp(profile, "main422-12-intra"))
589
0
    {
590
0
        if (param->internalCsp != X265_CSP_I420 && param->internalCsp != X265_CSP_I422)
591
0
        {
592
0
            x265_log(param, X265_LOG_ERROR, "%s profile not compatible with %s input chroma subsampling.\n",
593
0
                     profile, x265_source_csp_names[param->internalCsp]);
594
0
            return -1;
595
0
        }
596
0
    }
597
0
    else if (!strcmp(profile, "main444-8") ||
598
0
             !strcmp(profile, "main444-intra") || !strcmp(profile, "main444-stillpicture") ||
599
0
             !strcmp(profile, "main444-10") || !strcmp(profile, "main444-10-intra") ||
600
0
             !strcmp(profile, "main444-12") || !strcmp(profile, "main444-12-intra") ||
601
0
             !strcmp(profile, "main444-16-intra") || !strcmp(profile, "main444-16-stillpicture") ||
602
0
             !strcmp(profile, "main444-scc") || !strcmp(profile, "main444-10-scc"))
603
0
    {
604
        /* any color space allowed */
605
0
    }
606
0
    else
607
0
    {
608
0
        x265_log(param, X265_LOG_ERROR, "unknown profile <%s>\n", profile);
609
0
        return -1;
610
0
    }
611
612
0
    return 0;
613
0
}
614
}