Coverage Report

Created: 2022-08-24 06:15

/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
    uint32_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
    { MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, 1, Level::LEVEL8_5, "8.5", 85 },
61
};
62
63
/* determine minimum decoder level required to decode the described video */
64
void determineLevel(const x265_param &param, VPS& vps)
65
698
{
66
698
    vps.ptl.onePictureOnlyConstraintFlag = param.totalFrames == 1;
67
698
    vps.ptl.intraConstraintFlag = param.keyframeMax <= 1 || vps.ptl.onePictureOnlyConstraintFlag;
68
698
    vps.ptl.bitDepthConstraint = param.internalBitDepth;
69
698
    vps.ptl.chromaFormatConstraint = param.internalCsp;
70
71
    /* TODO: figure out HighThroughput signaling, aka: HbrFactor in section A.4.2, only available
72
     * for intra-only profiles (vps.ptl.intraConstraintFlag) */
73
698
    vps.ptl.lowerBitRateConstraintFlag = true;
74
75
698
    vps.maxTempSubLayers = param.bEnableTemporalSubLayers ? 2 : 1;
76
    
77
698
    if (param.internalCsp == X265_CSP_I420 && param.internalBitDepth <= 10)
78
698
    {
79
        /* Probably an HEVC v1 profile, but must check to be sure */
80
698
        if (param.internalBitDepth <= 8)
81
698
        {
82
698
            if (vps.ptl.onePictureOnlyConstraintFlag)
83
698
                vps.ptl.profileIdc = Profile::MAINSTILLPICTURE;
84
0
            else if (vps.ptl.intraConstraintFlag)
85
0
                vps.ptl.profileIdc = Profile::MAINREXT; /* Main Intra */
86
0
            else 
87
0
                vps.ptl.profileIdc = Profile::MAIN;
88
698
        }
89
0
        else if (param.internalBitDepth <= 10)
90
0
        {
91
            /* note there is no 10bit still picture profile */
92
0
            if (vps.ptl.intraConstraintFlag)
93
0
                vps.ptl.profileIdc = Profile::MAINREXT; /* Main10 Intra */
94
0
            else
95
0
                vps.ptl.profileIdc = Profile::MAIN10;
96
0
        }
97
698
    }
98
0
    else
99
0
        vps.ptl.profileIdc = Profile::MAINREXT;
100
101
    /* determine which profiles are compatible with this stream */
102
103
698
    memset(vps.ptl.profileCompatibilityFlag, 0, sizeof(vps.ptl.profileCompatibilityFlag));
104
698
    vps.ptl.profileCompatibilityFlag[vps.ptl.profileIdc] = true;
105
698
    if (vps.ptl.profileIdc == Profile::MAIN10 && param.internalBitDepth == 8)
106
0
        vps.ptl.profileCompatibilityFlag[Profile::MAIN] = true;
107
698
    else if (vps.ptl.profileIdc == Profile::MAIN)
108
0
        vps.ptl.profileCompatibilityFlag[Profile::MAIN10] = true;
109
698
    else if (vps.ptl.profileIdc == Profile::MAINSTILLPICTURE)
110
698
    {
111
698
        vps.ptl.profileCompatibilityFlag[Profile::MAIN] = true;
112
698
        vps.ptl.profileCompatibilityFlag[Profile::MAIN10] = true;
113
698
    }
114
0
    else if (vps.ptl.profileIdc == Profile::MAINREXT)
115
0
        vps.ptl.profileCompatibilityFlag[Profile::MAINREXT] = true;
116
117
698
    uint32_t lumaSamples = param.sourceWidth * param.sourceHeight;
118
698
    uint32_t samplesPerSec = (uint32_t)(lumaSamples * ((double)param.fpsNum / param.fpsDenom));
119
698
    uint32_t bitrate = param.rc.vbvMaxBitrate ? param.rc.vbvMaxBitrate : param.rc.bitrate;
120
121
698
    const uint32_t MaxDpbPicBuf = 6;
122
698
    vps.ptl.levelIdc = Level::NONE;
123
698
    vps.ptl.tierFlag = Level::MAIN;
124
125
698
    const size_t NumLevels = sizeof(levels) / sizeof(levels[0]);
126
698
    uint32_t i;
127
698
    if (param.bLossless)
128
195
    {
129
195
        i = 13;
130
195
        vps.ptl.minCrForLevel = 1;
131
195
        vps.ptl.maxLumaSrForLevel = MAX_UINT;
132
195
        vps.ptl.levelIdc = Level::LEVEL8_5;
133
195
        vps.ptl.tierFlag = Level::MAIN;
134
195
    }
135
503
    else if (param.uhdBluray)
136
0
    {
137
0
        i = 8;
138
0
        vps.ptl.levelIdc = levels[i].levelEnum;
139
0
        vps.ptl.tierFlag = Level::HIGH;
140
0
        vps.ptl.minCrForLevel = levels[i].minCompressionRatio;
141
0
        vps.ptl.maxLumaSrForLevel = levels[i].maxLumaSamplesPerSecond;
142
0
    }
143
676
    else for (i = 0; i < NumLevels; i++)
144
676
    {
145
676
        if (lumaSamples > levels[i].maxLumaSamples)
146
173
            continue;
147
503
        else if (samplesPerSec > levels[i].maxLumaSamplesPerSecond)
148
0
            continue;
149
503
        else if (bitrate > levels[i].maxBitrateMain && levels[i].maxBitrateHigh == MAX_UINT)
150
0
            continue;
151
503
        else if (bitrate > levels[i].maxBitrateHigh)
152
0
            continue;
153
503
        else if (param.sourceWidth > sqrt(levels[i].maxLumaSamples * 8.0f))
154
0
            continue;
155
503
        else if (param.sourceHeight > sqrt(levels[i].maxLumaSamples * 8.0f))
156
0
            continue;
157
503
        else if (param.levelIdc && param.levelIdc != levels[i].levelIdc)
158
0
            continue;
159
503
        uint32_t maxDpbSize = MaxDpbPicBuf;
160
161
503
        if (lumaSamples <= (levels[i].maxLumaSamples >> 2))
162
87
            maxDpbSize = X265_MIN(4 * MaxDpbPicBuf, 16);
163
416
        else if (lumaSamples <= (levels[i].maxLumaSamples >> 1))
164
270
            maxDpbSize = X265_MIN(2 * MaxDpbPicBuf, 16);
165
146
        else if (lumaSamples <= ((3 * levels[i].maxLumaSamples) >> 2))
166
99
            maxDpbSize = X265_MIN((4 * MaxDpbPicBuf) / 3, 16);
167
168
        /* The value of sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1 shall be less than
169
         * or equal to MaxDpbSize */
170
503
        if (vps.maxDecPicBuffering > maxDpbSize)
171
0
            continue;
172
173
        /* For level 5 and higher levels, the value of CtbSizeY shall be equal to 32 or 64 */
174
503
        if (levels[i].levelEnum >= Level::LEVEL5 && param.maxCUSize < 32)
175
0
        {
176
0
            x265_log(&param, X265_LOG_WARNING, "level %s detected, but CTU size 16 is non-compliant\n", levels[i].name);
177
0
            vps.ptl.profileIdc = Profile::NONE;
178
0
            vps.ptl.levelIdc = Level::NONE;
179
0
            vps.ptl.tierFlag = Level::MAIN;
180
0
            x265_log(&param, X265_LOG_INFO, "NONE profile, Level-NONE (Main tier)\n");
181
0
            return;
182
0
        }
183
184
        /* The value of NumPocTotalCurr shall be less than or equal to 8 */
185
503
        int numPocTotalCurr = param.maxNumReferences + vps.numReorderPics;
186
503
        if (numPocTotalCurr > 8)
187
0
        {
188
0
            x265_log(&param, X265_LOG_WARNING, "level %s detected, but NumPocTotalCurr (total references) is non-compliant\n", levels[i].name);
189
0
            vps.ptl.profileIdc = Profile::NONE;
190
0
            vps.ptl.levelIdc = Level::NONE;
191
0
            vps.ptl.tierFlag = Level::MAIN;
192
0
            x265_log(&param, X265_LOG_INFO, "NONE profile, Level-NONE (Main tier)\n");
193
0
            return;
194
0
        }
195
196
1.50k
#define CHECK_RANGE(value, main, high) (high != MAX_UINT && value > main && value <= high)
197
198
503
        if (CHECK_RANGE(bitrate, levels[i].maxBitrateMain, levels[i].maxBitrateHigh) ||
199
503
            CHECK_RANGE((uint32_t)param.rc.vbvBufferSize, levels[i].maxCpbSizeMain, levels[i].maxCpbSizeHigh))
200
0
        {
201
            /* The bitrate or buffer size are out of range for Main tier, but in
202
             * range for High tier. If the user allowed High tier then give
203
             * them High tier at this level.  Otherwise allow the loop to
204
             * progress to the Main tier of the next level */
205
0
            if (param.bHighTier)
206
0
                vps.ptl.tierFlag = Level::HIGH;
207
0
            else
208
0
                continue;
209
0
        }
210
503
        else
211
503
            vps.ptl.tierFlag = Level::MAIN;
212
503
#undef CHECK_RANGE
213
214
503
        vps.ptl.levelIdc = levels[i].levelEnum;
215
503
        vps.ptl.minCrForLevel = levels[i].minCompressionRatio;
216
503
        vps.ptl.maxLumaSrForLevel = levels[i].maxLumaSamplesPerSecond;
217
503
        break;
218
503
    }
219
220
698
    static const char *profiles[] = { "None", "Main", "Main 10", "Main Still Picture", "RExt" };
221
698
    static const char *tiers[]    = { "Main", "High" };
222
223
698
    char profbuf[64];
224
698
    strcpy(profbuf, profiles[vps.ptl.profileIdc]);
225
226
698
    bool bStillPicture = false;
227
698
    if (vps.ptl.profileIdc == Profile::MAINREXT)
228
0
    {
229
0
        if (vps.ptl.bitDepthConstraint > 12 && vps.ptl.intraConstraintFlag)
230
0
        {
231
0
            if (vps.ptl.onePictureOnlyConstraintFlag)
232
0
            {
233
0
                strcpy(profbuf, "Main 4:4:4 16 Still Picture");
234
0
                bStillPicture = true;
235
0
            }
236
0
            else
237
0
                strcpy(profbuf, "Main 4:4:4 16");
238
0
        }
239
0
        else if (param.internalCsp == X265_CSP_I420)
240
0
        {
241
0
            X265_CHECK(vps.ptl.intraConstraintFlag || vps.ptl.bitDepthConstraint > 10, "rext fail\n");
242
0
            if (vps.ptl.bitDepthConstraint <= 8)
243
0
                strcpy(profbuf, "Main");
244
0
            else if (vps.ptl.bitDepthConstraint <= 10)
245
0
                strcpy(profbuf, "Main 10");
246
0
            else if (vps.ptl.bitDepthConstraint <= 12)
247
0
                strcpy(profbuf, "Main 12");
248
0
        }
249
0
        else if (param.internalCsp == X265_CSP_I422)
250
0
        {
251
            /* there is no Main 4:2:2 profile, so it must be signaled as Main10 4:2:2 */
252
0
            if (param.internalBitDepth <= 10)
253
0
                strcpy(profbuf, "Main 4:2:2 10");
254
0
            else if (vps.ptl.bitDepthConstraint <= 12)
255
0
                strcpy(profbuf, "Main 4:2:2 12");
256
0
        }
257
0
        else if (param.internalCsp == X265_CSP_I444)
258
0
        {
259
0
            if (vps.ptl.bitDepthConstraint <= 8)
260
0
            {
261
0
                if (vps.ptl.onePictureOnlyConstraintFlag)
262
0
                {
263
0
                    strcpy(profbuf, "Main 4:4:4 Still Picture");
264
0
                    bStillPicture = true;
265
0
                }
266
0
                else
267
0
                    strcpy(profbuf, "Main 4:4:4");
268
0
            }
269
0
            else if (vps.ptl.bitDepthConstraint <= 10)
270
0
                strcpy(profbuf, "Main 4:4:4 10");
271
0
            else if (vps.ptl.bitDepthConstraint <= 12)
272
0
                strcpy(profbuf, "Main 4:4:4 12");
273
0
        }
274
0
        else
275
0
            strcpy(profbuf, "Unknown");
276
277
0
        if (vps.ptl.intraConstraintFlag && !bStillPicture)
278
0
            strcat(profbuf, " Intra");
279
0
    }
280
698
    x265_log(&param, X265_LOG_INFO, "%s profile, Level-%s (%s tier)\n",
281
698
             profbuf, levels[i].name, tiers[vps.ptl.tierFlag]);
282
698
}
283
284
/* enforce a maximum decoder level requirement, in other words assure that a
285
 * decoder of the specified level may decode the video about to be created.
286
 * Lower parameters where necessary to ensure the video will be decodable by a
287
 * decoder meeting this level of requirement.  Some parameters (resolution and
288
 * frame rate) are non-negotiable and thus this function may fail. In those
289
 * circumstances it will be quite noisy */
290
bool enforceLevel(x265_param& param, VPS& vps)
291
698
{
292
698
    vps.numReorderPics = (param.bBPyramid && param.bframes > 1) ? 2 : !!param.bframes;
293
698
    vps.maxDecPicBuffering = X265_MIN(MAX_NUM_REF, X265_MAX(vps.numReorderPics + 2, (uint32_t)param.maxNumReferences) + 1);
294
295
    /* no level specified by user, just auto-detect from the configuration */
296
698
    if (param.levelIdc <= 0)
297
698
        return true;
298
299
0
    uint32_t level = 0;
300
0
    while (levels[level].levelIdc != param.levelIdc && level + 1 < sizeof(levels) / sizeof(levels[0]))
301
0
        level++;
302
0
    if (levels[level].levelIdc != param.levelIdc)
303
0
    {
304
0
        x265_log(&param, X265_LOG_ERROR, "specified level %d does not exist\n", param.levelIdc);
305
0
        return false;
306
0
    }
307
308
0
    LevelSpec& l = levels[level];
309
310
    //highTier is allowed for this level and has not been explicitly disabled. This does not mean it is the final chosen tier
311
0
    bool allowHighTier = l.maxBitrateHigh < MAX_UINT && param.bHighTier;
312
313
0
    uint32_t lumaSamples = param.sourceWidth * param.sourceHeight;
314
0
    uint32_t samplesPerSec = (uint32_t)(lumaSamples * ((double)param.fpsNum / param.fpsDenom));
315
0
    bool ok = true;
316
0
    if (lumaSamples > l.maxLumaSamples)
317
0
        ok = false;
318
0
    else if (param.sourceWidth > sqrt(l.maxLumaSamples * 8.0f))
319
0
        ok = false;
320
0
    else if (param.sourceHeight > sqrt(l.maxLumaSamples * 8.0f))
321
0
        ok = false;
322
0
    if (!ok)
323
0
    {
324
0
        x265_log(&param, X265_LOG_ERROR, "picture dimensions are out of range for specified level\n");
325
0
        return false;
326
0
    }
327
0
    else if (samplesPerSec > l.maxLumaSamplesPerSecond)
328
0
    {
329
0
        x265_log(&param, X265_LOG_ERROR, "frame rate is out of range for specified level\n");
330
0
        return false;
331
0
    }
332
333
    /* Adjustments of Bitrate, VBV buffer size, refs will be triggered only if specified params do not fit 
334
     * within the max limits of that level (high tier if allowed, main otherwise)
335
     */
336
337
0
    if ((uint32_t)param.rc.vbvMaxBitrate > (allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain))
338
0
    {
339
0
        param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
340
0
        x265_log(&param, X265_LOG_WARNING, "lowering VBV max bitrate to %dKbps\n", param.rc.vbvMaxBitrate);
341
0
    }
342
0
    if ((uint32_t)param.rc.vbvBufferSize > (allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain))
343
0
    {
344
0
        param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
345
0
        x265_log(&param, X265_LOG_WARNING, "lowering VBV buffer size to %dKb\n", param.rc.vbvBufferSize);
346
0
    }
347
348
0
    switch (param.rc.rateControlMode)
349
0
    {
350
0
    case X265_RC_ABR:
351
0
        if ((uint32_t)param.rc.bitrate > (allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain))
352
0
        {
353
0
            param.rc.bitrate =  allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
354
0
            x265_log(&param, X265_LOG_WARNING, "lowering target bitrate to High tier limit of %dKbps\n", param.rc.bitrate);
355
0
        }
356
0
        break;
357
358
0
    case X265_RC_CQP:
359
0
        x265_log(&param, X265_LOG_ERROR, "Constant QP is inconsistent with specifying a decoder level, no bitrate guarantee is possible.\n");
360
0
        return false;
361
362
0
    case X265_RC_CRF:
363
0
        if (!param.rc.vbvBufferSize || !param.rc.vbvMaxBitrate)
364
0
        {
365
0
            if (!param.rc.vbvMaxBitrate)
366
0
                param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
367
0
            if (!param.rc.vbvBufferSize)
368
0
                param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
369
0
            x265_log(&param, X265_LOG_WARNING, "Specifying a decoder level with constant rate factor rate-control requires\n");
370
0
            x265_log(&param, X265_LOG_WARNING, "enabling VBV with vbv-bufsize=%dkb vbv-maxrate=%dkbps. VBV outputs are non-deterministic!\n",
371
0
                     param.rc.vbvBufferSize, param.rc.vbvMaxBitrate);
372
0
        }
373
0
        break;
374
375
0
    default:
376
0
        x265_log(&param, X265_LOG_ERROR, "Unknown rate control mode is inconsistent with specifying a decoder level\n");
377
0
        return false;
378
0
    }
379
380
    /* The value of sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1 shall be less than or equal to MaxDpbSize */
381
0
    const uint32_t MaxDpbPicBuf = 6;
382
0
    uint32_t maxDpbSize = MaxDpbPicBuf;
383
0
    if (!param.uhdBluray) /* Do not change MaxDpbPicBuf for UHD-Bluray */
384
0
    {
385
0
        if (lumaSamples <= (l.maxLumaSamples >> 2))
386
0
            maxDpbSize = X265_MIN(4 * MaxDpbPicBuf, 16);
387
0
        else if (lumaSamples <= (l.maxLumaSamples >> 1))
388
0
            maxDpbSize = X265_MIN(2 * MaxDpbPicBuf, 16);
389
0
        else if (lumaSamples <= ((3 * l.maxLumaSamples) >> 2))
390
0
            maxDpbSize = X265_MIN((4 * MaxDpbPicBuf) / 3, 16);
391
0
    }
392
393
0
    int savedRefCount = param.maxNumReferences;
394
0
    while (vps.maxDecPicBuffering > maxDpbSize && param.maxNumReferences > 1)
395
0
    {
396
0
        param.maxNumReferences--;
397
0
        vps.maxDecPicBuffering = X265_MIN(MAX_NUM_REF, X265_MAX(vps.numReorderPics + 1, (uint32_t)param.maxNumReferences) + 1);
398
0
    }
399
0
    if (param.maxNumReferences != savedRefCount)
400
0
        x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to meet level requirement\n", param.maxNumReferences);
401
402
    /* For level 5 and higher levels, the value of CtbSizeY shall be equal to 32 or 64 */
403
0
    if (param.levelIdc >= 50 && param.maxCUSize < 32)
404
0
    {
405
0
        param.maxCUSize = 32;
406
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");
407
0
    }
408
409
    /* The value of NumPocTotalCurr shall be less than or equal to 8 */
410
0
    int numPocTotalCurr = param.maxNumReferences + !!param.bframes;
411
0
    if (numPocTotalCurr > 8)
412
0
    {
413
0
        param.maxNumReferences = 8 - !!param.bframes;
414
0
        x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to meet numPocTotalCurr requirement\n", param.maxNumReferences);
415
0
    }
416
417
0
    return true;
418
0
}
419
}
420
421
#if EXPORT_C_API
422
423
/* these functions are exported as C functions (default) */
424
using namespace X265_NS;
425
extern "C" {
426
427
#else
428
429
/* these functions exist within private namespace (multilib) */
430
namespace X265_NS {
431
432
#endif
433
434
int x265_param_apply_profile(x265_param *param, const char *profile)
435
698
{
436
698
    if (!param || !profile)
437
0
        return 0;
438
439
#ifdef SVT_HEVC
440
    if (param->bEnableSvtHevc)
441
    {
442
        EB_H265_ENC_CONFIGURATION* svtParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
443
        if (!strcmp(profile, "main"))    svtParam->profile = 1;
444
        else if (!strcmp(profile, "main10"))    svtParam->profile = 2;
445
        else
446
        {
447
            x265_log(param, X265_LOG_ERROR, "SVT-HEVC encoder: Unsupported profile %s \n", profile);
448
            return -1;
449
        }
450
        return 0;
451
    }
452
#endif
453
454
    /* Check if profile bit-depth requirement is exceeded by internal bit depth */
455
698
    bool bInvalidDepth = false;
456
#if X265_DEPTH > 8
457
    if (!strcmp(profile, "main") || !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp") ||
458
        !strcmp(profile, "main444-8") || !strcmp(profile, "main-intra") ||
459
        !strcmp(profile, "main444-intra") || !strcmp(profile, "main444-stillpicture"))
460
        bInvalidDepth = true;
461
#endif
462
#if X265_DEPTH > 10
463
    if (!strcmp(profile, "main10") || !strcmp(profile, "main422-10") || !strcmp(profile, "main444-10") ||
464
        !strcmp(profile, "main10-intra") || !strcmp(profile, "main422-10-intra") || !strcmp(profile, "main444-10-intra"))
465
        bInvalidDepth = true;
466
#endif
467
#if X265_DEPTH > 12
468
    if (!strcmp(profile, "main12") || !strcmp(profile, "main422-12") || !strcmp(profile, "main444-12") ||
469
        !strcmp(profile, "main12-intra") || !strcmp(profile, "main422-12-intra") || !strcmp(profile, "main444-12-intra"))
470
        bInvalidDepth = true;
471
#endif
472
473
698
    if (bInvalidDepth)
474
0
    {
475
0
        x265_log(param, X265_LOG_ERROR, "%s profile not supported, internal bit depth %d.\n", profile, X265_DEPTH);
476
0
        return -1;
477
0
    }
478
479
698
    size_t l = strlen(profile);
480
698
    bool bBoolIntra = (l > 6 && !strcmp(profile + l - 6, "-intra")) ||
481
698
                      !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp");
482
698
    if (bBoolIntra)
483
698
    {
484
        /* The profile may be detected as still picture if param->totalFrames is 1 */
485
698
        param->keyframeMax = 1;
486
698
    }
487
    
488
    /* check that input color space is supported by profile */
489
698
    if (!strcmp(profile, "main") || !strcmp(profile, "main-intra") ||
490
698
        !strcmp(profile, "main10") || !strcmp(profile, "main10-intra") ||
491
698
        !strcmp(profile, "main12") || !strcmp(profile, "main12-intra") ||
492
698
        !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp"))
493
698
    {
494
698
        if (param->internalCsp != X265_CSP_I420)
495
0
        {
496
0
            x265_log(param, X265_LOG_ERROR, "%s profile not compatible with %s input chroma subsampling.\n",
497
0
                     profile, x265_source_csp_names[param->internalCsp]);
498
0
            return -1;
499
0
        }
500
698
    }
501
0
    else if (!strcmp(profile, "main422-10") || !strcmp(profile, "main422-10-intra") ||
502
0
             !strcmp(profile, "main422-12") || !strcmp(profile, "main422-12-intra"))
503
0
    {
504
0
        if (param->internalCsp != X265_CSP_I420 && param->internalCsp != X265_CSP_I422)
505
0
        {
506
0
            x265_log(param, X265_LOG_ERROR, "%s profile not compatible with %s input chroma subsampling.\n",
507
0
                     profile, x265_source_csp_names[param->internalCsp]);
508
0
            return -1;
509
0
        }
510
0
    }
511
0
    else if (!strcmp(profile, "main444-8") ||
512
0
             !strcmp(profile, "main444-intra") || !strcmp(profile, "main444-stillpicture") ||
513
0
             !strcmp(profile, "main444-10") || !strcmp(profile, "main444-10-intra") ||
514
0
             !strcmp(profile, "main444-12") || !strcmp(profile, "main444-12-intra") ||
515
0
             !strcmp(profile, "main444-16-intra") || !strcmp(profile, "main444-16-stillpicture"))
516
0
    {
517
        /* any color space allowed */
518
0
    }
519
0
    else
520
0
    {
521
0
        x265_log(param, X265_LOG_ERROR, "unknown profile <%s>\n", profile);
522
0
        return -1;
523
0
    }
524
525
698
    return 0;
526
698
}
527
}