/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 ¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, X265_LOG_WARNING, "Specifying a decoder level with constant rate factor rate-control requires\n"); |
370 | 0 | x265_log(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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 | | } |