Commit | Line | Data |
---|---|---|
72b9787e JB |
1 | /***************************************************************************** |
2 | * Copyright (C) 2013 x265 project | |
3 | * | |
4 | * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. | |
19 | * | |
20 | * This program is also available under a commercial proprietary license. | |
21 | * For more information, contact us at license @ x265.com. | |
22 | *****************************************************************************/ | |
23 | ||
24 | #include "common.h" | |
25 | #include "slice.h" | |
26 | #include "threading.h" | |
27 | #include "param.h" | |
28 | #include "cpu.h" | |
29 | #include "x265.h" | |
30 | ||
31 | #if _MSC_VER | |
32 | #pragma warning(disable: 4996) // POSIX functions are just fine, thanks | |
33 | #pragma warning(disable: 4706) // assignment within conditional | |
34 | #pragma warning(disable: 4127) // conditional expression is constant | |
35 | #endif | |
36 | ||
37 | #if _WIN32 | |
38 | #define strcasecmp _stricmp | |
39 | #endif | |
40 | ||
41 | #if !defined(HAVE_STRTOK_R) | |
42 | ||
43 | /* | |
44 | * adapted from public domain strtok_r() by Charlie Gordon | |
45 | * | |
46 | * from comp.lang.c 9/14/2007 | |
47 | * | |
48 | * http://groups.google.com/group/comp.lang.c/msg/2ab1ecbb86646684 | |
49 | * | |
50 | * (Declaration that it's public domain): | |
51 | * http://groups.google.com/group/comp.lang.c/msg/7c7b39328fefab9c | |
52 | */ | |
53 | ||
54 | #undef strtok_r | |
55 | char* strtok_r(char * str, | |
56 | const char *delim, | |
57 | char ** nextp) | |
58 | { | |
59 | if (!str) | |
60 | str = *nextp; | |
61 | ||
62 | str += strspn(str, delim); | |
63 | ||
64 | if (!*str) | |
65 | return NULL; | |
66 | ||
67 | char *ret = str; | |
68 | ||
69 | str += strcspn(str, delim); | |
70 | ||
71 | if (*str) | |
72 | *str++ = '\0'; | |
73 | ||
74 | *nextp = str; | |
75 | ||
76 | return ret; | |
77 | } | |
78 | ||
79 | #endif // if !defined(HAVE_STRTOK_R) | |
80 | ||
81 | using namespace x265; | |
82 | ||
83 | extern "C" | |
84 | x265_param *x265_param_alloc() | |
85 | { | |
86 | return (x265_param*)x265_malloc(sizeof(x265_param)); | |
87 | } | |
88 | ||
89 | extern "C" | |
90 | void x265_param_free(x265_param *p) | |
91 | { | |
92 | return x265_free(p); | |
93 | } | |
94 | ||
95 | extern "C" | |
96 | void x265_param_default(x265_param *param) | |
97 | { | |
98 | memset(param, 0, sizeof(x265_param)); | |
99 | ||
100 | /* Applying default values to all elements in the param structure */ | |
101 | param->cpuid = x265::cpu_detect(); | |
102 | param->bEnableWavefront = 1; | |
103 | param->poolNumThreads = 0; | |
104 | param->frameNumThreads = 0; | |
105 | ||
106 | param->logLevel = X265_LOG_INFO; | |
107 | param->csvfn = NULL; | |
108 | param->rc.lambdaFileName = NULL; | |
109 | param->bLogCuStats = 0; | |
110 | param->decodedPictureHashSEI = 0; | |
111 | ||
112 | /* Quality Measurement Metrics */ | |
113 | param->bEnablePsnr = 0; | |
114 | param->bEnableSsim = 0; | |
115 | ||
116 | /* Source specifications */ | |
117 | param->internalBitDepth = x265_max_bit_depth; | |
118 | param->internalCsp = X265_CSP_I420; | |
119 | ||
120 | param->levelIdc = 0; | |
121 | param->bHighTier = 0; | |
122 | param->interlaceMode = 0; | |
123 | param->bRepeatHeaders = 0; | |
124 | param->bEnableAccessUnitDelimiters = 0; | |
125 | param->bEmitHRDSEI = 0; | |
126 | param->bEmitInfoSEI = 1; | |
127 | ||
128 | /* CU definitions */ | |
129 | param->maxCUSize = 64; | |
130 | param->tuQTMaxInterDepth = 1; | |
131 | param->tuQTMaxIntraDepth = 1; | |
132 | ||
133 | /* Coding Structure */ | |
134 | param->keyframeMin = 0; | |
135 | param->keyframeMax = 250; | |
136 | param->bOpenGOP = 1; | |
137 | param->bframes = 4; | |
138 | param->lookaheadDepth = 20; | |
139 | param->bFrameAdaptive = X265_B_ADAPT_TRELLIS; | |
140 | param->bBPyramid = 1; | |
141 | param->scenecutThreshold = 40; /* Magic number pulled in from x264 */ | |
142 | ||
143 | /* Intra Coding Tools */ | |
144 | param->bEnableConstrainedIntra = 0; | |
145 | param->bEnableStrongIntraSmoothing = 1; | |
146 | param->bEnableFastIntra = 0; | |
147 | ||
148 | /* Inter Coding tools */ | |
149 | param->searchMethod = X265_HEX_SEARCH; | |
150 | param->subpelRefine = 2; | |
151 | param->searchRange = 57; | |
152 | param->maxNumMergeCand = 2; | |
153 | param->bEnableWeightedPred = 1; | |
154 | param->bEnableWeightedBiPred = 0; | |
155 | param->bEnableEarlySkip = 0; | |
156 | param->bEnableCbfFastMode = 0; | |
157 | param->bEnableAMP = 0; | |
158 | param->bEnableRectInter = 0; | |
159 | param->rdLevel = 3; | |
160 | param->bEnableSignHiding = 1; | |
161 | param->bEnableTransformSkip = 0; | |
162 | param->bEnableTSkipFast = 0; | |
163 | param->maxNumReferences = 3; | |
164 | param->bEnableTemporalMvp = 1; | |
165 | ||
166 | /* Loop Filter */ | |
167 | param->bEnableLoopFilter = 1; | |
168 | ||
169 | /* SAO Loop Filter */ | |
170 | param->bEnableSAO = 1; | |
171 | param->bSaoNonDeblocked = 0; | |
172 | ||
173 | /* Coding Quality */ | |
174 | param->cbQpOffset = 0; | |
175 | param->crQpOffset = 0; | |
176 | param->rdPenalty = 0; | |
177 | param->psyRd = 0.0; | |
178 | param->psyRdoq = 0.0; | |
179 | param->bIntraInBFrames = 0; | |
180 | param->bLossless = 0; | |
181 | param->bCULossless = 0; | |
182 | ||
183 | /* Rate control options */ | |
184 | param->rc.vbvMaxBitrate = 0; | |
185 | param->rc.vbvBufferSize = 0; | |
186 | param->rc.vbvBufferInit = 0.9; | |
187 | param->rc.rfConstant = 28; | |
188 | param->rc.bitrate = 0; | |
189 | param->rc.rateTolerance = 1.0; | |
190 | param->rc.qCompress = 0.6; | |
191 | param->rc.ipFactor = 1.4f; | |
192 | param->rc.pbFactor = 1.3f; | |
193 | param->rc.qpStep = 4; | |
194 | param->rc.rateControlMode = X265_RC_CRF; | |
195 | param->rc.qp = 32; | |
196 | param->rc.aqMode = X265_AQ_AUTO_VARIANCE; | |
197 | param->rc.aqStrength = 1.0; | |
198 | param->rc.cuTree = 1; | |
199 | param->rc.rfConstantMax = 0; | |
200 | param->rc.rfConstantMin = 0; | |
201 | param->rc.bStatRead = 0; | |
202 | param->rc.bStatWrite = 0; | |
203 | param->rc.statFileName = NULL; | |
204 | param->rc.complexityBlur = 20; | |
205 | param->rc.qblur = 0.5; | |
206 | param->rc.bEnableSlowFirstPass = 0; | |
207 | ||
208 | /* Video Usability Information (VUI) */ | |
209 | param->vui.aspectRatioIdc = 0; | |
210 | param->vui.sarWidth = 0; | |
211 | param->vui.sarHeight = 0; | |
212 | param->vui.bEnableOverscanAppropriateFlag = 0; | |
213 | param->vui.bEnableVideoSignalTypePresentFlag = 0; | |
214 | param->vui.videoFormat = 5; | |
215 | param->vui.bEnableVideoFullRangeFlag = 0; | |
216 | param->vui.bEnableColorDescriptionPresentFlag = 0; | |
217 | param->vui.colorPrimaries = 2; | |
218 | param->vui.transferCharacteristics = 2; | |
219 | param->vui.matrixCoeffs = 2; | |
220 | param->vui.bEnableChromaLocInfoPresentFlag = 0; | |
221 | param->vui.chromaSampleLocTypeTopField = 0; | |
222 | param->vui.chromaSampleLocTypeBottomField = 0; | |
223 | param->vui.bEnableDefaultDisplayWindowFlag = 0; | |
224 | param->vui.defDispWinLeftOffset = 0; | |
225 | param->vui.defDispWinRightOffset = 0; | |
226 | param->vui.defDispWinTopOffset = 0; | |
227 | param->vui.defDispWinBottomOffset = 0; | |
228 | } | |
229 | ||
230 | extern "C" | |
231 | int x265_param_default_preset(x265_param *param, const char *preset, const char *tune) | |
232 | { | |
233 | x265_param_default(param); | |
234 | ||
235 | if (preset) | |
236 | { | |
237 | char *end; | |
238 | int i = strtol(preset, &end, 10); | |
239 | if (*end == 0 && i >= 0 && i < (int)(sizeof(x265_preset_names) / sizeof(*x265_preset_names) - 1)) | |
240 | preset = x265_preset_names[i]; | |
241 | ||
242 | if (!strcmp(preset, "ultrafast")) | |
243 | { | |
244 | param->lookaheadDepth = 10; | |
245 | param->scenecutThreshold = 0; // disable lookahead | |
246 | param->maxCUSize = 32; | |
247 | param->searchRange = 25; | |
248 | param->bFrameAdaptive = 0; | |
249 | param->subpelRefine = 0; | |
250 | param->searchMethod = X265_DIA_SEARCH; | |
251 | param->bEnableEarlySkip = 1; | |
252 | param->bEnableSAO = 0; | |
253 | param->bEnableSignHiding = 0; | |
254 | param->bEnableWeightedPred = 0; | |
255 | param->rdLevel = 2; | |
256 | param->maxNumReferences = 1; | |
257 | param->bEnableLoopFilter = 0; | |
258 | param->rc.aqStrength = 0.0; | |
259 | param->rc.aqMode = X265_AQ_NONE; | |
260 | param->rc.cuTree = 0; | |
261 | param->bEnableFastIntra = 1; | |
262 | } | |
263 | else if (!strcmp(preset, "superfast")) | |
264 | { | |
265 | param->lookaheadDepth = 10; | |
266 | param->maxCUSize = 32; | |
267 | param->searchRange = 44; | |
268 | param->bFrameAdaptive = 0; | |
269 | param->subpelRefine = 1; | |
270 | param->bEnableEarlySkip = 1; | |
271 | param->bEnableWeightedPred = 0; | |
272 | param->rdLevel = 2; | |
273 | param->maxNumReferences = 1; | |
274 | param->rc.aqStrength = 0.0; | |
275 | param->rc.aqMode = X265_AQ_NONE; | |
276 | param->rc.cuTree = 0; | |
277 | param->bEnableSAO = 0; | |
278 | param->bEnableFastIntra = 1; | |
279 | } | |
280 | else if (!strcmp(preset, "veryfast")) | |
281 | { | |
282 | param->lookaheadDepth = 15; | |
283 | param->maxCUSize = 32; | |
284 | param->bFrameAdaptive = 0; | |
285 | param->subpelRefine = 1; | |
286 | param->bEnableEarlySkip = 1; | |
287 | param->rdLevel = 2; | |
288 | param->maxNumReferences = 1; | |
289 | param->rc.cuTree = 0; | |
290 | param->bEnableFastIntra = 1; | |
291 | } | |
292 | else if (!strcmp(preset, "faster")) | |
293 | { | |
294 | param->lookaheadDepth = 15; | |
295 | param->bFrameAdaptive = 0; | |
296 | param->bEnableEarlySkip = 1; | |
297 | param->rdLevel = 2; | |
298 | param->maxNumReferences = 1; | |
299 | param->rc.cuTree = 0; | |
300 | param->bEnableFastIntra = 1; | |
301 | } | |
302 | else if (!strcmp(preset, "fast")) | |
303 | { | |
304 | param->lookaheadDepth = 15; | |
305 | param->bFrameAdaptive = 0; | |
306 | param->rdLevel = 2; | |
307 | param->maxNumReferences = 2; | |
308 | param->bEnableFastIntra = 1; | |
309 | } | |
310 | else if (!strcmp(preset, "medium")) | |
311 | { | |
312 | /* defaults */ | |
313 | } | |
314 | else if (!strcmp(preset, "slow")) | |
315 | { | |
316 | param->bEnableRectInter = 1; | |
317 | param->lookaheadDepth = 25; | |
318 | param->rdLevel = 4; | |
319 | param->subpelRefine = 3; | |
320 | param->maxNumMergeCand = 3; | |
321 | param->searchMethod = X265_STAR_SEARCH; | |
322 | } | |
323 | else if (!strcmp(preset, "slower")) | |
324 | { | |
325 | param->bEnableWeightedBiPred = 1; | |
326 | param->bEnableAMP = 1; | |
327 | param->bEnableRectInter = 1; | |
328 | param->lookaheadDepth = 30; | |
329 | param->bframes = 8; | |
330 | param->tuQTMaxInterDepth = 2; | |
331 | param->tuQTMaxIntraDepth = 2; | |
332 | param->rdLevel = 6; | |
333 | param->subpelRefine = 3; | |
334 | param->maxNumMergeCand = 3; | |
335 | param->searchMethod = X265_STAR_SEARCH; | |
336 | param->bIntraInBFrames = 1; | |
337 | } | |
338 | else if (!strcmp(preset, "veryslow")) | |
339 | { | |
340 | param->bEnableWeightedBiPred = 1; | |
341 | param->bEnableAMP = 1; | |
342 | param->bEnableRectInter = 1; | |
343 | param->lookaheadDepth = 40; | |
344 | param->bframes = 8; | |
345 | param->tuQTMaxInterDepth = 3; | |
346 | param->tuQTMaxIntraDepth = 3; | |
347 | param->rdLevel = 6; | |
348 | param->subpelRefine = 4; | |
349 | param->maxNumMergeCand = 4; | |
350 | param->searchMethod = X265_STAR_SEARCH; | |
351 | param->maxNumReferences = 5; | |
352 | param->bIntraInBFrames = 1; | |
353 | } | |
354 | else if (!strcmp(preset, "placebo")) | |
355 | { | |
356 | param->bEnableWeightedBiPred = 1; | |
357 | param->bEnableAMP = 1; | |
358 | param->bEnableRectInter = 1; | |
359 | param->lookaheadDepth = 60; | |
360 | param->searchRange = 92; | |
361 | param->bframes = 8; | |
362 | param->tuQTMaxInterDepth = 4; | |
363 | param->tuQTMaxIntraDepth = 4; | |
364 | param->rdLevel = 6; | |
365 | param->subpelRefine = 5; | |
366 | param->maxNumMergeCand = 5; | |
367 | param->searchMethod = X265_STAR_SEARCH; | |
368 | param->bEnableTransformSkip = 1; | |
369 | param->maxNumReferences = 5; | |
370 | param->rc.bEnableSlowFirstPass = 1; | |
371 | param->bIntraInBFrames = 1; | |
372 | // TODO: optimized esa | |
373 | } | |
374 | else | |
375 | return -1; | |
376 | } | |
377 | if (tune) | |
378 | { | |
379 | if (!strcmp(tune, "psnr")) | |
380 | { | |
381 | param->rc.aqStrength = 0.0; | |
382 | param->psyRd = 0.0; | |
383 | param->psyRdoq = 0.0; | |
384 | } | |
385 | else if (!strcmp(tune, "ssim")) | |
386 | { | |
387 | param->rc.aqMode = X265_AQ_AUTO_VARIANCE; | |
388 | param->psyRd = 0.0; | |
389 | param->psyRdoq = 0.0; | |
390 | } | |
391 | else if (!strcmp(tune, "fastdecode") || | |
392 | !strcmp(tune, "fast-decode")) | |
393 | { | |
394 | param->bEnableLoopFilter = 0; | |
395 | param->bEnableSAO = 0; | |
396 | param->bEnableWeightedPred = 0; | |
397 | param->bEnableWeightedBiPred = 0; | |
398 | param->bIntraInBFrames = 0; | |
399 | } | |
400 | else if (!strcmp(tune, "zerolatency") || | |
401 | !strcmp(tune, "zero-latency")) | |
402 | { | |
403 | param->bFrameAdaptive = 0; | |
404 | param->bframes = 0; | |
405 | param->lookaheadDepth = 0; | |
406 | param->scenecutThreshold = 0; | |
407 | param->rc.cuTree = 0; | |
408 | } | |
409 | else | |
410 | return -1; | |
411 | } | |
412 | ||
413 | return 0; | |
414 | } | |
415 | ||
416 | static int x265_atobool(const char *str, bool& bError) | |
417 | { | |
418 | if (!strcmp(str, "1") || | |
419 | !strcmp(str, "true") || | |
420 | !strcmp(str, "yes")) | |
421 | return 1; | |
422 | if (!strcmp(str, "0") || | |
423 | !strcmp(str, "false") || | |
424 | !strcmp(str, "no")) | |
425 | return 0; | |
426 | bError = true; | |
427 | return 0; | |
428 | } | |
429 | ||
430 | static double x265_atof(const char *str, bool& bError) | |
431 | { | |
432 | char *end; | |
433 | double v = strtod(str, &end); | |
434 | ||
435 | if (end == str || *end != '\0') | |
436 | bError = true; | |
437 | return v; | |
438 | } | |
439 | ||
440 | static int parseName(const char *arg, const char * const * names, bool& bError) | |
441 | { | |
442 | for (int i = 0; names[i]; i++) | |
443 | { | |
444 | if (!strcmp(arg, names[i])) | |
445 | { | |
446 | return i; | |
447 | } | |
448 | } | |
449 | ||
450 | return x265_atoi(arg, bError); | |
451 | } | |
452 | ||
453 | /* internal versions of string-to-int with additional error checking */ | |
454 | #undef atoi | |
455 | #undef atof | |
456 | #define atoi(str) x265_atoi(str, bError) | |
457 | #define atof(str) x265_atof(str, bError) | |
458 | #define atobool(str) (bNameWasBool = true, x265_atobool(str, bError)) | |
459 | ||
460 | extern "C" | |
461 | int x265_param_parse(x265_param *p, const char *name, const char *value) | |
462 | { | |
463 | bool bError = false; | |
464 | bool bNameWasBool = false; | |
465 | bool bValueWasNull = !value; | |
466 | char nameBuf[64]; | |
467 | ||
468 | if (!name) | |
469 | return X265_PARAM_BAD_NAME; | |
470 | ||
471 | // skip -- prefix if provided | |
472 | if (name[0] == '-' && name[1] == '-') | |
473 | name += 2; | |
474 | ||
475 | // s/_/-/g | |
476 | if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_')) | |
477 | { | |
478 | char *c; | |
479 | strcpy(nameBuf, name); | |
480 | while ((c = strchr(nameBuf, '_')) != 0) | |
481 | { | |
482 | *c = '-'; | |
483 | } | |
484 | ||
485 | name = nameBuf; | |
486 | } | |
487 | ||
488 | if (!strncmp(name, "no-", 3)) | |
489 | { | |
490 | name += 3; | |
491 | value = !value || x265_atobool(value, bError) ? "false" : "true"; | |
492 | } | |
493 | else if (!strncmp(name, "no", 2)) | |
494 | { | |
495 | name += 2; | |
496 | value = !value || x265_atobool(value, bError) ? "false" : "true"; | |
497 | } | |
498 | else if (!value) | |
499 | value = "true"; | |
500 | else if (value[0] == '=') | |
501 | value++; | |
502 | ||
503 | #if defined(_MSC_VER) | |
504 | #pragma warning(disable: 4127) // conditional expression is constant | |
505 | #endif | |
506 | #define OPT(STR) else if (!strcmp(name, STR)) | |
507 | #define OPT2(STR1, STR2) else if (!strcmp(name, STR1) || !strcmp(name, STR2)) | |
508 | if (0) ; | |
509 | OPT("asm") | |
510 | { | |
511 | if (bValueWasNull) | |
512 | p->cpuid = atobool(value); | |
513 | else | |
514 | p->cpuid = parseCpuName(value, bError); | |
515 | } | |
516 | OPT("fps") | |
517 | { | |
518 | if (sscanf(value, "%u/%u", &p->fpsNum, &p->fpsDenom) == 2) | |
519 | ; | |
520 | else | |
521 | { | |
522 | float fps = (float)atof(value); | |
523 | if (fps > 0 && fps <= INT_MAX / 1000) | |
524 | { | |
525 | p->fpsNum = (int)(fps * 1000 + .5); | |
526 | p->fpsDenom = 1000; | |
527 | } | |
528 | else | |
529 | { | |
530 | p->fpsNum = atoi(value); | |
531 | p->fpsDenom = 1; | |
532 | } | |
533 | } | |
534 | } | |
535 | OPT("csv") p->csvfn = value; | |
536 | OPT("scaling-list") p->scalingLists = value; | |
537 | OPT("lambda-file") p->rc.lambdaFileName = value; | |
538 | OPT("threads") p->poolNumThreads = atoi(value); | |
539 | OPT("frame-threads") p->frameNumThreads = atoi(value); | |
540 | OPT("pmode") p->bDistributeModeAnalysis = atobool(value); | |
541 | OPT("pme") p->bDistributeMotionEstimation = atobool(value); | |
542 | OPT2("level-idc", "level") | |
543 | { | |
544 | /* allow "5.1" or "51", both converted to integer 51 */ | |
545 | if (atof(value) < 7) | |
546 | p->levelIdc = (int)(10 * atof(value) + .5); | |
547 | else | |
548 | p->levelIdc = atoi(value); | |
549 | } | |
550 | OPT("high-tier") p->bHighTier = atobool(value); | |
551 | OPT2("log-level", "log") | |
552 | { | |
553 | p->logLevel = atoi(value); | |
554 | if (bError) | |
555 | { | |
556 | bError = false; | |
557 | p->logLevel = parseName(value, logLevelNames, bError) - 1; | |
558 | } | |
559 | } | |
560 | OPT("cu-stats") p->bLogCuStats = atobool(value); | |
561 | OPT("repeat-headers") p->bRepeatHeaders = atobool(value); | |
562 | OPT("wpp") p->bEnableWavefront = atobool(value); | |
563 | OPT("ctu") p->maxCUSize = (uint32_t)atoi(value); | |
564 | OPT("tu-intra-depth") p->tuQTMaxIntraDepth = (uint32_t)atoi(value); | |
565 | OPT("tu-inter-depth") p->tuQTMaxInterDepth = (uint32_t)atoi(value); | |
566 | OPT("subme") p->subpelRefine = atoi(value); | |
567 | OPT("merange") p->searchRange = atoi(value); | |
568 | OPT("rect") p->bEnableRectInter = atobool(value); | |
569 | OPT("amp") p->bEnableAMP = atobool(value); | |
570 | OPT("max-merge") p->maxNumMergeCand = (uint32_t)atoi(value); | |
571 | OPT("temporal-mvp") p->bEnableTemporalMvp = atobool(value); | |
572 | OPT("early-skip") p->bEnableEarlySkip = atobool(value); | |
573 | OPT("fast-cbf") p->bEnableCbfFastMode = atobool(value); | |
574 | OPT("rdpenalty") p->rdPenalty = atoi(value); | |
575 | OPT("tskip") p->bEnableTransformSkip = atobool(value); | |
576 | OPT("no-tskip-fast") p->bEnableTSkipFast = atobool(value); | |
577 | OPT("tskip-fast") p->bEnableTSkipFast = atobool(value); | |
578 | OPT("strong-intra-smoothing") p->bEnableStrongIntraSmoothing = atobool(value); | |
579 | OPT("lossless") p->bLossless = atobool(value); | |
580 | OPT("cu-lossless") p->bCULossless = atobool(value); | |
581 | OPT("constrained-intra") p->bEnableConstrainedIntra = atobool(value); | |
582 | OPT("fast-intra") p->bEnableFastIntra = atobool(value); | |
583 | OPT("open-gop") p->bOpenGOP = atobool(value); | |
584 | OPT("scenecut") | |
585 | { | |
586 | p->scenecutThreshold = atobool(value); | |
587 | if (bError || p->scenecutThreshold) | |
588 | { | |
589 | bError = false; | |
590 | p->scenecutThreshold = atoi(value); | |
591 | } | |
592 | } | |
593 | OPT("keyint") p->keyframeMax = atoi(value); | |
594 | OPT("min-keyint") p->keyframeMin = atoi(value); | |
595 | OPT("rc-lookahead") p->lookaheadDepth = atoi(value); | |
596 | OPT("bframes") p->bframes = atoi(value); | |
597 | OPT("bframe-bias") p->bFrameBias = atoi(value); | |
598 | OPT("b-adapt") | |
599 | { | |
600 | p->bFrameAdaptive = atobool(value); | |
601 | if (bError || p->bFrameAdaptive) | |
602 | { | |
603 | bError = false; | |
604 | p->bFrameAdaptive = atoi(value); | |
605 | } | |
606 | } | |
607 | OPT("interlace") | |
608 | { | |
609 | p->interlaceMode = atobool(value); | |
610 | if (bError || p->interlaceMode) | |
611 | { | |
612 | bError = false; | |
613 | p->interlaceMode = parseName(value, x265_interlace_names, bError); | |
614 | } | |
615 | } | |
616 | OPT("ref") p->maxNumReferences = atoi(value); | |
617 | OPT("weightp") p->bEnableWeightedPred = atobool(value); | |
618 | OPT("weightb") p->bEnableWeightedBiPred = atobool(value); | |
619 | OPT("cbqpoffs") p->cbQpOffset = atoi(value); | |
620 | OPT("crqpoffs") p->crQpOffset = atoi(value); | |
621 | OPT("rd") p->rdLevel = atoi(value); | |
622 | OPT("psy-rd") p->psyRd = atof(value); | |
623 | OPT("psy-rdoq") p->psyRdoq = atof(value); | |
624 | OPT("signhide") p->bEnableSignHiding = atobool(value); | |
625 | OPT("b-intra") p->bIntraInBFrames = atobool(value); | |
626 | OPT("lft") p->bEnableLoopFilter = atobool(value); | |
627 | OPT("sao") p->bEnableSAO = atobool(value); | |
628 | OPT("sao-non-deblock") p->bSaoNonDeblocked = atobool(value); | |
629 | OPT("ssim") p->bEnableSsim = atobool(value); | |
630 | OPT("psnr") p->bEnablePsnr = atobool(value); | |
631 | OPT("hash") p->decodedPictureHashSEI = atoi(value); | |
632 | OPT("aud") p->bEnableAccessUnitDelimiters = atobool(value); | |
633 | OPT("info") p->bEmitInfoSEI = atobool(value); | |
634 | OPT("b-pyramid") p->bBPyramid = atobool(value); | |
635 | OPT("hrd") p->bEmitHRDSEI = atobool(value); | |
636 | OPT2("ipratio", "ip-factor") p->rc.ipFactor = atof(value); | |
637 | OPT2("pbratio", "pb-factor") p->rc.pbFactor = atof(value); | |
638 | OPT("aq-mode") p->rc.aqMode = atoi(value); | |
639 | OPT("aq-strength") p->rc.aqStrength = atof(value); | |
640 | OPT("vbv-maxrate") p->rc.vbvMaxBitrate = atoi(value); | |
641 | OPT("vbv-bufsize") p->rc.vbvBufferSize = atoi(value); | |
642 | OPT("vbv-init") p->rc.vbvBufferInit = atof(value); | |
643 | OPT("crf-max") p->rc.rfConstantMax = atof(value); | |
644 | OPT("crf-min") p->rc.rfConstantMin = atof(value); | |
645 | OPT("crf") | |
646 | { | |
647 | p->rc.rfConstant = atof(value); | |
648 | p->rc.rateControlMode = X265_RC_CRF; | |
649 | } | |
650 | OPT("bitrate") | |
651 | { | |
652 | p->rc.bitrate = atoi(value); | |
653 | p->rc.rateControlMode = X265_RC_ABR; | |
654 | } | |
655 | OPT("qp") | |
656 | { | |
657 | p->rc.qp = atoi(value); | |
658 | p->rc.rateControlMode = X265_RC_CQP; | |
659 | } | |
660 | OPT("input-res") bError |= sscanf(value, "%dx%d", &p->sourceWidth, &p->sourceHeight) != 2; | |
661 | OPT("input-csp") p->internalCsp = parseName(value, x265_source_csp_names, bError); | |
662 | OPT("me") p->searchMethod = parseName(value, x265_motion_est_names, bError); | |
663 | OPT("cutree") p->rc.cuTree = atobool(value); | |
664 | OPT("slow-firstpass") p->rc.bEnableSlowFirstPass = atobool(value); | |
665 | OPT("analysis-mode") p->analysisMode = parseName(value, x265_analysis_names, bError); | |
666 | OPT("sar") | |
667 | { | |
668 | p->vui.aspectRatioIdc = parseName(value, x265_sar_names, bError); | |
669 | if (bError) | |
670 | { | |
671 | p->vui.aspectRatioIdc = X265_EXTENDED_SAR; | |
672 | bError = sscanf(value, "%d:%d", &p->vui.sarWidth, &p->vui.sarHeight) != 2; | |
673 | } | |
674 | } | |
675 | OPT("overscan") | |
676 | { | |
677 | if (!strcmp(value, "show")) | |
678 | p->vui.bEnableOverscanInfoPresentFlag = 1; | |
679 | else if (!strcmp(value, "crop")) | |
680 | { | |
681 | p->vui.bEnableOverscanInfoPresentFlag = 1; | |
682 | p->vui.bEnableOverscanAppropriateFlag = 1; | |
683 | } | |
684 | else if (!strcmp(value, "undef")) | |
685 | p->vui.bEnableOverscanInfoPresentFlag = 0; | |
686 | else | |
687 | bError = true; | |
688 | } | |
689 | OPT("videoformat") | |
690 | { | |
691 | p->vui.bEnableVideoSignalTypePresentFlag = 1; | |
692 | p->vui.videoFormat = parseName(value, x265_video_format_names, bError); | |
693 | } | |
694 | OPT("range") | |
695 | { | |
696 | p->vui.bEnableVideoSignalTypePresentFlag = 1; | |
697 | p->vui.bEnableVideoFullRangeFlag = parseName(value, x265_fullrange_names, bError); | |
698 | } | |
699 | OPT("colorprim") | |
700 | { | |
701 | p->vui.bEnableVideoSignalTypePresentFlag = 1; | |
702 | p->vui.bEnableColorDescriptionPresentFlag = 1; | |
703 | p->vui.colorPrimaries = parseName(value, x265_colorprim_names, bError); | |
704 | } | |
705 | OPT("transfer") | |
706 | { | |
707 | p->vui.bEnableVideoSignalTypePresentFlag = 1; | |
708 | p->vui.bEnableColorDescriptionPresentFlag = 1; | |
709 | p->vui.transferCharacteristics = parseName(value, x265_transfer_names, bError); | |
710 | } | |
711 | OPT("colormatrix") | |
712 | { | |
713 | p->vui.bEnableVideoSignalTypePresentFlag = 1; | |
714 | p->vui.bEnableColorDescriptionPresentFlag = 1; | |
715 | p->vui.matrixCoeffs = parseName(value, x265_colmatrix_names, bError); | |
716 | } | |
717 | OPT("chromaloc") | |
718 | { | |
719 | p->vui.bEnableChromaLocInfoPresentFlag = 1; | |
720 | p->vui.chromaSampleLocTypeTopField = atoi(value); | |
721 | p->vui.chromaSampleLocTypeBottomField = p->vui.chromaSampleLocTypeTopField; | |
722 | } | |
723 | OPT("crop-rect") | |
724 | { | |
725 | p->vui.bEnableDefaultDisplayWindowFlag = 1; | |
726 | bError |= sscanf(value, "%d,%d,%d,%d", | |
727 | &p->vui.defDispWinLeftOffset, | |
728 | &p->vui.defDispWinTopOffset, | |
729 | &p->vui.defDispWinRightOffset, | |
730 | &p->vui.defDispWinBottomOffset) != 4; | |
731 | } | |
732 | OPT("nr") p->noiseReduction = atoi(value); | |
733 | OPT("pass") | |
734 | { | |
735 | int pass = Clip3(0, 3, atoi(value)); | |
736 | p->rc.bStatWrite = pass & 1; | |
737 | p->rc.bStatRead = pass & 2; | |
738 | } | |
739 | OPT("stats") p->rc.statFileName = strdup(value); | |
740 | else | |
741 | return X265_PARAM_BAD_NAME; | |
742 | #undef OPT | |
743 | #undef atobool | |
744 | #undef atoi | |
745 | #undef atof | |
746 | ||
747 | bError |= bValueWasNull && !bNameWasBool; | |
748 | return bError ? X265_PARAM_BAD_VALUE : 0; | |
749 | } | |
750 | ||
751 | namespace x265 { | |
752 | // internal encoder functions | |
753 | ||
754 | int x265_atoi(const char *str, bool& bError) | |
755 | { | |
756 | char *end; | |
757 | int v = strtol(str, &end, 0); | |
758 | ||
759 | if (end == str || *end != '\0') | |
760 | bError = true; | |
761 | return v; | |
762 | } | |
763 | ||
764 | /* cpu name can be: | |
765 | * auto || true - x265::cpu_detect() | |
766 | * false || no - disabled | |
767 | * integer bitmap value | |
768 | * comma separated list of SIMD names, eg: SSE4.1,XOP */ | |
769 | int parseCpuName(const char *value, bool& bError) | |
770 | { | |
771 | if (!value) | |
772 | { | |
773 | bError = 1; | |
774 | return 0; | |
775 | } | |
776 | int cpu; | |
777 | if (isdigit(value[0])) | |
778 | cpu = x265_atoi(value, bError); | |
779 | else | |
780 | cpu = !strcmp(value, "auto") || x265_atobool(value, bError) ? x265::cpu_detect() : 0; | |
781 | ||
782 | if (bError) | |
783 | { | |
784 | char *buf = strdup(value); | |
785 | char *tok, *saveptr = NULL, *init; | |
786 | bError = 0; | |
787 | cpu = 0; | |
788 | for (init = buf; (tok = strtok_r(init, ",", &saveptr)); init = NULL) | |
789 | { | |
790 | int i; | |
791 | for (i = 0; x265::cpu_names[i].flags && strcasecmp(tok, x265::cpu_names[i].name); i++) | |
792 | { | |
793 | } | |
794 | ||
795 | cpu |= x265::cpu_names[i].flags; | |
796 | if (!x265::cpu_names[i].flags) | |
797 | bError = 1; | |
798 | } | |
799 | ||
800 | free(buf); | |
801 | if ((cpu & X265_CPU_SSSE3) && !(cpu & X265_CPU_SSE2_IS_SLOW)) | |
802 | cpu |= X265_CPU_SSE2_IS_FAST; | |
803 | } | |
804 | ||
805 | return cpu; | |
806 | } | |
807 | ||
808 | static const int fixedRatios[][2] = | |
809 | { | |
810 | { 1, 1 }, | |
811 | { 12, 11 }, | |
812 | { 10, 11 }, | |
813 | { 16, 11 }, | |
814 | { 40, 33 }, | |
815 | { 24, 11 }, | |
816 | { 20, 11 }, | |
817 | { 32, 11 }, | |
818 | { 80, 33 }, | |
819 | { 18, 11 }, | |
820 | { 15, 11 }, | |
821 | { 64, 33 }, | |
822 | { 160, 99 }, | |
823 | { 4, 3 }, | |
824 | { 3, 2 }, | |
825 | { 2, 1 }, | |
826 | }; | |
827 | ||
828 | void setParamAspectRatio(x265_param *p, int width, int height) | |
829 | { | |
830 | p->vui.aspectRatioIdc = X265_EXTENDED_SAR; | |
831 | p->vui.sarWidth = width; | |
832 | p->vui.sarHeight = height; | |
833 | for (size_t i = 0; i < sizeof(fixedRatios) / sizeof(fixedRatios[0]); i++) | |
834 | { | |
835 | if (width == fixedRatios[i][0] && height == fixedRatios[i][1]) | |
836 | { | |
837 | p->vui.aspectRatioIdc = (int)i + 1; | |
838 | return; | |
839 | } | |
840 | } | |
841 | } | |
842 | ||
843 | void getParamAspectRatio(x265_param *p, int& width, int& height) | |
844 | { | |
845 | if (!p->vui.aspectRatioIdc) | |
846 | { | |
847 | width = height = 0; | |
848 | } | |
849 | else if ((size_t)p->vui.aspectRatioIdc <= sizeof(fixedRatios) / sizeof(fixedRatios[0])) | |
850 | { | |
851 | width = fixedRatios[p->vui.aspectRatioIdc - 1][0]; | |
852 | height = fixedRatios[p->vui.aspectRatioIdc - 1][1]; | |
853 | } | |
854 | else if (p->vui.aspectRatioIdc == X265_EXTENDED_SAR) | |
855 | { | |
856 | width = p->vui.sarWidth; | |
857 | height = p->vui.sarHeight; | |
858 | } | |
859 | else | |
860 | { | |
861 | width = height = 0; | |
862 | } | |
863 | } | |
864 | ||
865 | static inline int _confirm(x265_param *param, bool bflag, const char* message) | |
866 | { | |
867 | if (!bflag) | |
868 | return 0; | |
869 | ||
870 | x265_log(param, X265_LOG_ERROR, "%s\n", message); | |
871 | return 1; | |
872 | } | |
873 | ||
874 | int x265_check_params(x265_param *param) | |
875 | { | |
876 | #define CHECK(expr, msg) check_failed |= _confirm(param, expr, msg) | |
877 | int check_failed = 0; /* abort if there is a fatal configuration problem */ | |
878 | ||
879 | CHECK(param->maxCUSize != 64 && param->maxCUSize != 32 && param->maxCUSize != 16, | |
880 | "max ctu size must be 16, 32, or 64"); | |
881 | if (check_failed == 1) | |
882 | return check_failed; | |
883 | ||
884 | uint32_t maxLog2CUSize = (uint32_t)g_log2Size[param->maxCUSize]; | |
885 | uint32_t tuQTMaxLog2Size = X265_MIN(maxLog2CUSize, 5); | |
886 | uint32_t tuQTMinLog2Size = 2; //log2(4) | |
887 | ||
888 | /* These checks might be temporary */ | |
889 | #if HIGH_BIT_DEPTH | |
890 | CHECK(param->internalBitDepth != 10, | |
891 | "x265 was compiled for 10bit encodes, only 10bit internal depth supported"); | |
892 | #else | |
893 | CHECK(param->internalBitDepth != 8, | |
894 | "x265 was compiled for 8bit encodes, only 8bit internal depth supported"); | |
895 | #endif | |
896 | ||
897 | CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > 51, | |
898 | "QP exceeds supported range (-QpBDOffsety to 51)"); | |
899 | CHECK(param->fpsNum == 0 || param->fpsDenom == 0, | |
900 | "Frame rate numerator and denominator must be specified"); | |
901 | CHECK(param->interlaceMode < 0 || param->interlaceMode > 2, | |
902 | "Interlace mode must be 0 (progressive) 1 (top-field first) or 2 (bottom field first)"); | |
903 | CHECK(param->searchMethod<0 || param->searchMethod> X265_FULL_SEARCH, | |
904 | "Search method is not supported value (0:DIA 1:HEX 2:UMH 3:HM 5:FULL)"); | |
905 | CHECK(param->searchRange < 0, | |
906 | "Search Range must be more than 0"); | |
907 | CHECK(param->searchRange >= 32768, | |
908 | "Search Range must be less than 32768"); | |
909 | CHECK(param->subpelRefine > X265_MAX_SUBPEL_LEVEL, | |
910 | "subme must be less than or equal to X265_MAX_SUBPEL_LEVEL (7)"); | |
911 | CHECK(param->subpelRefine < 0, | |
912 | "subme must be greater than or equal to 0"); | |
913 | CHECK(param->frameNumThreads < 0, | |
914 | "frameNumThreads (--frame-threads) must be 0 or higher"); | |
915 | CHECK(param->cbQpOffset < -12, "Min. Chroma Cb QP Offset is -12"); | |
916 | CHECK(param->cbQpOffset > 12, "Max. Chroma Cb QP Offset is 12"); | |
917 | CHECK(param->crQpOffset < -12, "Min. Chroma Cr QP Offset is -12"); | |
918 | CHECK(param->crQpOffset > 12, "Max. Chroma Cr QP Offset is 12"); | |
919 | ||
920 | CHECK(tuQTMaxLog2Size > maxLog2CUSize, | |
921 | "QuadtreeTULog2MaxSize must be log2(maxCUSize) or smaller."); | |
922 | ||
923 | CHECK(param->tuQTMaxInterDepth < 1 || param->tuQTMaxInterDepth > 4, | |
924 | "QuadtreeTUMaxDepthInter must be greater than 0 and less than 5"); | |
925 | CHECK(maxLog2CUSize < tuQTMinLog2Size + param->tuQTMaxInterDepth - 1, | |
926 | "QuadtreeTUMaxDepthInter must be less than or equal to the difference between log2(maxCUSize) and QuadtreeTULog2MinSize plus 1"); | |
927 | CHECK(param->tuQTMaxIntraDepth < 1 || param->tuQTMaxIntraDepth > 4, | |
928 | "QuadtreeTUMaxDepthIntra must be greater 0 and less than 5"); | |
929 | CHECK(maxLog2CUSize < tuQTMinLog2Size + param->tuQTMaxIntraDepth - 1, | |
930 | "QuadtreeTUMaxDepthInter must be less than or equal to the difference between log2(maxCUSize) and QuadtreeTULog2MinSize plus 1"); | |
931 | ||
932 | CHECK(param->maxNumMergeCand < 1, "MaxNumMergeCand must be 1 or greater."); | |
933 | CHECK(param->maxNumMergeCand > 5, "MaxNumMergeCand must be 5 or smaller."); | |
934 | ||
935 | CHECK(param->maxNumReferences < 1, "maxNumReferences must be 1 or greater."); | |
936 | CHECK(param->maxNumReferences > MAX_NUM_REF, "maxNumReferences must be 16 or smaller."); | |
937 | ||
938 | CHECK(param->sourceWidth < (int)param->maxCUSize || param->sourceHeight < (int)param->maxCUSize, | |
939 | "Picture size must be at least one CTU"); | |
940 | CHECK(param->internalCsp < X265_CSP_I420 || X265_CSP_I444 < param->internalCsp, | |
941 | "Color space must be i420, i422, or i444"); | |
942 | CHECK(param->sourceWidth & !!CHROMA_H_SHIFT(param->internalCsp), | |
943 | "Picture width must be an integer multiple of the specified chroma subsampling"); | |
944 | CHECK(param->sourceHeight & !!CHROMA_V_SHIFT(param->internalCsp), | |
945 | "Picture height must be an integer multiple of the specified chroma subsampling"); | |
946 | ||
947 | CHECK(param->rc.rateControlMode > X265_RC_CRF || param->rc.rateControlMode < X265_RC_ABR, | |
948 | "Rate control mode is out of range"); | |
949 | CHECK(param->rdLevel < 0 || param->rdLevel > 6, | |
950 | "RD Level is out of range"); | |
951 | CHECK(param->bframes > param->lookaheadDepth && !param->rc.bStatRead, | |
952 | "Lookahead depth must be greater than the max consecutive bframe count"); | |
953 | CHECK(param->bframes < 0, | |
954 | "bframe count should be greater than zero"); | |
955 | CHECK(param->bframes > X265_BFRAME_MAX, | |
956 | "max consecutive bframe count must be 16 or smaller"); | |
957 | CHECK(param->lookaheadDepth > X265_LOOKAHEAD_MAX, | |
958 | "Lookahead depth must be less than 256"); | |
959 | CHECK(param->rc.aqMode < X265_AQ_NONE || X265_AQ_AUTO_VARIANCE < param->rc.aqMode, | |
960 | "Aq-Mode is out of range"); | |
961 | CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3, | |
962 | "Aq-Strength is out of range"); | |
963 | CHECK(param->psyRd < 0 || 2.0 < param->psyRd, "Psy-rd strength must be between 0 and 2.0"); | |
964 | CHECK(param->psyRdoq < 0 || 50.0 < param->psyRdoq, "Psy-rdoq strength must be between 0 and 50.0"); | |
965 | CHECK(param->bEnableWavefront < 0, "WaveFrontSynchro cannot be negative"); | |
966 | CHECK(!param->bEnableWavefront && param->rc.vbvBufferSize, "VBV requires wave-front parallelism (--wpp)"); | |
967 | CHECK((param->vui.aspectRatioIdc < 0 | |
968 | || param->vui.aspectRatioIdc > 16) | |
969 | && param->vui.aspectRatioIdc != X265_EXTENDED_SAR, | |
970 | "Sample Aspect Ratio must be 0-16 or 255"); | |
971 | CHECK(param->vui.aspectRatioIdc == X265_EXTENDED_SAR && param->vui.sarWidth <= 0, | |
972 | "Sample Aspect Ratio width must be greater than 0"); | |
973 | CHECK(param->vui.aspectRatioIdc == X265_EXTENDED_SAR && param->vui.sarHeight <= 0, | |
974 | "Sample Aspect Ratio height must be greater than 0"); | |
975 | CHECK(param->vui.videoFormat < 0 || param->vui.videoFormat > 5, | |
976 | "Video Format must be component," | |
977 | " pal, ntsc, secam, mac or undef"); | |
978 | CHECK(param->vui.colorPrimaries < 0 | |
979 | || param->vui.colorPrimaries > 9 | |
980 | || param->vui.colorPrimaries == 3, | |
981 | "Color Primaries must be undef, bt709, bt470m," | |
982 | " bt470bg, smpte170m, smpte240m, film or bt2020"); | |
983 | CHECK(param->vui.transferCharacteristics < 0 | |
984 | || param->vui.transferCharacteristics > 15 | |
985 | || param->vui.transferCharacteristics == 3, | |
986 | "Transfer Characteristics must be undef, bt709, bt470m, bt470bg," | |
987 | " smpte170m, smpte240m, linear, log100, log316, iec61966-2-4, bt1361e," | |
988 | " iec61966-2-1, bt2020-10 or bt2020-12"); | |
989 | CHECK(param->vui.matrixCoeffs < 0 | |
990 | || param->vui.matrixCoeffs > 10 | |
991 | || param->vui.matrixCoeffs == 3, | |
992 | "Matrix Coefficients must be undef, bt709, fcc, bt470bg, smpte170m," | |
993 | " smpte240m, GBR, YCgCo, bt2020nc or bt2020c"); | |
994 | CHECK(param->vui.chromaSampleLocTypeTopField < 0 | |
995 | || param->vui.chromaSampleLocTypeTopField > 5, | |
996 | "Chroma Sample Location Type Top Field must be 0-5"); | |
997 | CHECK(param->vui.chromaSampleLocTypeBottomField < 0 | |
998 | || param->vui.chromaSampleLocTypeBottomField > 5, | |
999 | "Chroma Sample Location Type Bottom Field must be 0-5"); | |
1000 | CHECK(param->vui.defDispWinLeftOffset < 0, | |
1001 | "Default Display Window Left Offset must be 0 or greater"); | |
1002 | CHECK(param->vui.defDispWinRightOffset < 0, | |
1003 | "Default Display Window Right Offset must be 0 or greater"); | |
1004 | CHECK(param->vui.defDispWinTopOffset < 0, | |
1005 | "Default Display Window Top Offset must be 0 or greater"); | |
1006 | CHECK(param->vui.defDispWinBottomOffset < 0, | |
1007 | "Default Display Window Bottom Offset must be 0 or greater"); | |
1008 | CHECK(param->rc.rfConstant < -6 * (param->internalBitDepth - 8) || param->rc.rfConstant > 51, | |
1009 | "Valid quality based range: -qpBDOffsetY to 51"); | |
1010 | CHECK(param->rc.rfConstantMax < -6 * (param->internalBitDepth - 8) || param->rc.rfConstantMax > 51, | |
1011 | "Valid quality based range: -qpBDOffsetY to 51"); | |
1012 | CHECK(param->rc.rfConstantMin < -6 * (param->internalBitDepth - 8) || param->rc.rfConstantMin > 51, | |
1013 | "Valid quality based range: -qpBDOffsetY to 51"); | |
1014 | CHECK(param->bFrameAdaptive < 0 || param->bFrameAdaptive > 2, | |
1015 | "Valid adaptive b scheduling values 0 - none, 1 - fast, 2 - full"); | |
1016 | CHECK(param->logLevel<-1 || param->logLevel> X265_LOG_FULL, | |
1017 | "Valid Logging level -1:none 0:error 1:warning 2:info 3:debug 4:full"); | |
1018 | CHECK(param->scenecutThreshold < 0, | |
1019 | "scenecutThreshold must be greater than 0"); | |
1020 | CHECK(param->rdPenalty < 0 || param->rdPenalty > 2, | |
1021 | "Valid penalty for 32x32 intra TU in non-I slices. 0:disabled 1:RD-penalty 2:maximum"); | |
1022 | CHECK(param->keyframeMax < -1, | |
1023 | "Invalid max IDR period in frames. value should be greater than -1"); | |
1024 | CHECK(param->decodedPictureHashSEI < 0 || param->decodedPictureHashSEI > 3, | |
1025 | "Invalid hash option. Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum"); | |
1026 | CHECK(param->rc.vbvBufferSize < 0, | |
1027 | "Size of the vbv buffer can not be less than zero"); | |
1028 | CHECK(param->rc.vbvMaxBitrate < 0, | |
1029 | "Maximum local bit rate can not be less than zero"); | |
1030 | CHECK(param->rc.vbvBufferInit < 0, | |
1031 | "Valid initial VBV buffer occupancy must be a fraction 0 - 1, or size in kbits"); | |
1032 | CHECK(param->rc.bitrate < 0, | |
1033 | "Target bitrate can not be less than zero"); | |
1034 | if (param->noiseReduction) | |
1035 | CHECK(100 > param->noiseReduction || param->noiseReduction > 1000, "Valid noise reduction range 100 - 1000"); | |
1036 | CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead, | |
1037 | "Constant rate-factor is incompatible with 2pass"); | |
1038 | CHECK(param->rc.rateControlMode == X265_RC_CQP && param->rc.bStatRead, | |
1039 | "Constant QP is incompatible with 2pass"); | |
1040 | return check_failed; | |
1041 | } | |
1042 | ||
1043 | void x265_param_apply_fastfirstpass(x265_param* param) | |
1044 | { | |
1045 | /* Set faster options in case of turbo firstpass */ | |
1046 | if (param->rc.bStatWrite && !param->rc.bStatRead) | |
1047 | { | |
1048 | param->maxNumReferences = 1; | |
1049 | param->maxNumMergeCand = 1; | |
1050 | param->bEnableRectInter = 0; | |
1051 | param->bEnableFastIntra = 1; | |
1052 | param->bEnableAMP = 0; | |
1053 | param->searchMethod = X265_DIA_SEARCH; | |
1054 | param->subpelRefine = X265_MIN(2, param->subpelRefine); | |
1055 | param->bEnableEarlySkip = 1; | |
1056 | param->rdLevel = X265_MIN(2, param->rdLevel); | |
1057 | } | |
1058 | } | |
1059 | ||
1060 | int x265_set_globals(x265_param *param) | |
1061 | { | |
1062 | static int once /* = 0 */; | |
1063 | ||
1064 | if (ATOMIC_CAS32(&once, 0, 1) == 1) | |
1065 | { | |
1066 | if (param->maxCUSize != g_maxCUSize) | |
1067 | { | |
1068 | x265_log(param, X265_LOG_ERROR, "maxCUSize must be the same for all encoders in a single process"); | |
1069 | return -1; | |
1070 | } | |
1071 | } | |
1072 | else | |
1073 | { | |
1074 | uint32_t maxLog2CUSize = (uint32_t)g_log2Size[param->maxCUSize]; | |
1075 | ||
1076 | // set max CU width & height | |
1077 | g_maxCUSize = param->maxCUSize; | |
1078 | g_maxLog2CUSize = maxLog2CUSize; | |
1079 | ||
1080 | // compute actual CU depth with respect to config depth and max transform size | |
1081 | g_maxCUDepth = maxLog2CUSize - MIN_LOG2_CU_SIZE; | |
1082 | g_maxFullDepth = maxLog2CUSize - LOG2_UNIT_SIZE; | |
1083 | ||
1084 | // initialize partition order | |
1085 | uint32_t* tmp = &g_zscanToRaster[0]; | |
1086 | initZscanToRaster(g_maxFullDepth, 1, 0, tmp); | |
1087 | initRasterToZscan(g_maxFullDepth); | |
1088 | } | |
1089 | return 0; | |
1090 | } | |
1091 | ||
1092 | void x265_print_params(x265_param *param) | |
1093 | { | |
1094 | if (param->logLevel < X265_LOG_INFO) | |
1095 | return; | |
1096 | ||
1097 | #if HIGH_BIT_DEPTH | |
1098 | x265_log(param, X265_LOG_INFO, "Internal bit depth : %d\n", param->internalBitDepth); | |
1099 | #endif | |
1100 | if (param->interlaceMode) | |
1101 | x265_log(param, X265_LOG_INFO, "Interlaced field inputs : %s\n", x265_interlace_names[param->interlaceMode]); | |
1102 | ||
1103 | x265_log(param, X265_LOG_INFO, "CTU size / RQT depth inter / intra : %d / %d / %d\n", | |
1104 | param->maxCUSize, param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth); | |
1105 | ||
1106 | x265_log(param, X265_LOG_INFO, "ME / range / subpel / merge : %s / %d / %d / %d\n", | |
1107 | x265_motion_est_names[param->searchMethod], param->searchRange, param->subpelRefine, param->maxNumMergeCand); | |
1108 | ||
1109 | if (param->keyframeMax != INT_MAX || param->scenecutThreshold) | |
1110 | x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut : %d / %d / %d\n", param->keyframeMin, param->keyframeMax, param->scenecutThreshold); | |
1111 | else | |
1112 | x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut : disabled\n"); | |
1113 | ||
1114 | if (param->cbQpOffset || param->crQpOffset) | |
1115 | x265_log(param, X265_LOG_INFO, "Cb/Cr QP Offset : %d / %d\n", param->cbQpOffset, param->crQpOffset); | |
1116 | ||
1117 | if (param->rdPenalty) | |
1118 | x265_log(param, X265_LOG_INFO, "Intra 32x32 TU penalty type : %d\n", param->rdPenalty); | |
1119 | ||
1120 | x265_log(param, X265_LOG_INFO, "Lookahead / bframes / badapt : %d / %d / %d\n", param->lookaheadDepth, param->bframes, param->bFrameAdaptive); | |
1121 | x265_log(param, X265_LOG_INFO, "b-pyramid / weightp / weightb / refs: %d / %d / %d / %d\n", | |
1122 | param->bBPyramid, param->bEnableWeightedPred, param->bEnableWeightedBiPred, param->maxNumReferences); | |
1123 | ||
1124 | if (param->bLossless) | |
1125 | x265_log(param, X265_LOG_INFO, "Rate Control : Lossless\n"); | |
1126 | else switch (param->rc.rateControlMode) | |
1127 | { | |
1128 | case X265_RC_ABR: | |
1129 | x265_log(param, X265_LOG_INFO, "Rate Control / AQ-Strength / CUTree : ABR-%d kbps / %0.1f / %d\n", param->rc.bitrate, | |
1130 | param->rc.aqStrength, param->rc.cuTree); | |
1131 | break; | |
1132 | case X265_RC_CQP: | |
1133 | x265_log(param, X265_LOG_INFO, "Rate Control / AQ-Strength / CUTree : CQP-%d / %0.1f / %d\n", param->rc.qp, param->rc.aqStrength, | |
1134 | param->rc.cuTree); | |
1135 | break; | |
1136 | case X265_RC_CRF: | |
1137 | x265_log(param, X265_LOG_INFO, "Rate Control / AQ-Strength / CUTree : CRF-%0.1f / %0.1f / %d\n", param->rc.rfConstant, | |
1138 | param->rc.aqStrength, param->rc.cuTree); | |
1139 | break; | |
1140 | } | |
1141 | ||
1142 | if (param->rc.vbvBufferSize) | |
1143 | x265_log(param, X265_LOG_INFO, "VBV/HRD buffer / max-rate / init : %d / %d / %.3f\n", | |
1144 | param->rc.vbvBufferSize, param->rc.vbvMaxBitrate, param->rc.vbvBufferInit); | |
1145 | ||
1146 | x265_log(param, X265_LOG_INFO, "tools: "); | |
1147 | #define TOOLOPT(FLAG, STR) if (FLAG) fprintf(stderr, "%s ", STR) | |
1148 | TOOLOPT(param->bEnableRectInter, "rect"); | |
1149 | TOOLOPT(param->bEnableAMP, "amp"); | |
1150 | fprintf(stderr, "rd=%d ", param->rdLevel); | |
1151 | if (param->psyRd > 0.) | |
1152 | fprintf(stderr, "psy-rd=%.2lf ", param->psyRd); | |
1153 | if (param->psyRdoq > 0.) | |
1154 | fprintf(stderr, "psy-rdoq=%.2lf ", param->psyRdoq); | |
1155 | TOOLOPT(param->bEnableEarlySkip, "esd"); | |
1156 | TOOLOPT(param->bEnableCbfFastMode, "cfm"); | |
1157 | if (param->noiseReduction) | |
1158 | fprintf(stderr, "nr=%d ", param->noiseReduction); | |
1159 | TOOLOPT(param->bEnableLoopFilter, "lft"); | |
1160 | if (param->bEnableSAO) | |
1161 | fprintf(stderr, "sao%s ", param->bSaoNonDeblocked ? "-non-deblock" : ""); | |
1162 | TOOLOPT(param->bEnableSignHiding, "signhide"); | |
1163 | TOOLOPT(param->bEnableConstrainedIntra, "cip"); | |
1164 | TOOLOPT(param->bIntraInBFrames, "b-intra"); | |
1165 | TOOLOPT(param->bEnableFastIntra, "fast-intra"); | |
1166 | TOOLOPT(param->bEnableTemporalMvp, "tmvp"); | |
1167 | if (param->bEnableTransformSkip) | |
1168 | fprintf(stderr, "tskip%s ", param->bEnableTSkipFast ? "-fast" : ""); | |
1169 | TOOLOPT(param->bCULossless, "cu-lossless"); | |
1170 | TOOLOPT(param->rc.bStatWrite, "stats-write"); | |
1171 | TOOLOPT(param->rc.bStatRead, "stats-read"); | |
1172 | fprintf(stderr, "\n"); | |
1173 | fflush(stderr); | |
1174 | } | |
1175 | ||
1176 | char *x265_param2string(x265_param *p) | |
1177 | { | |
1178 | char *buf, *s; | |
1179 | ||
1180 | buf = s = X265_MALLOC(char, MAXPARAMSIZE); | |
1181 | if (!buf) | |
1182 | return NULL; | |
1183 | ||
1184 | #define BOOL(param, cliopt) \ | |
1185 | s += sprintf(s, " %s", (param) ? cliopt : "no-"cliopt); | |
1186 | ||
1187 | s += sprintf(s, "%dx%d", p->sourceWidth,p->sourceHeight); | |
1188 | s += sprintf(s, " fps=%u/%u", p->fpsNum, p->fpsDenom); | |
1189 | s += sprintf(s, " bitdepth=%d", p->internalBitDepth); | |
1190 | BOOL(p->bEnableWavefront, "wpp"); | |
1191 | s += sprintf(s, " ctu=%d", p->maxCUSize); | |
1192 | s += sprintf(s, " tu-intra-depth=%d", p->tuQTMaxIntraDepth); | |
1193 | s += sprintf(s, " tu-inter-depth=%d", p->tuQTMaxInterDepth); | |
1194 | s += sprintf(s, " me=%d", p->searchMethod); | |
1195 | s += sprintf(s, " subme=%d", p->subpelRefine); | |
1196 | s += sprintf(s, " merange=%d", p->searchRange); | |
1197 | BOOL(p->bEnableRectInter, "rect"); | |
1198 | BOOL(p->bEnableAMP, "amp"); | |
1199 | s += sprintf(s, " max-merge=%d", p->maxNumMergeCand); | |
1200 | BOOL(p->bEnableTemporalMvp, "temporal-mvp"); | |
1201 | BOOL(p->bEnableEarlySkip, "early-skip"); | |
1202 | BOOL(p->bEnableCbfFastMode, "fast-cbf"); | |
1203 | s += sprintf(s, " rdpenalty=%d", p->rdPenalty); | |
1204 | BOOL(p->bEnableTransformSkip, "tskip"); | |
1205 | BOOL(p->bEnableTSkipFast, "tskip-fast"); | |
1206 | BOOL(p->bEnableStrongIntraSmoothing, "strong-intra-smoothing"); | |
1207 | BOOL(p->bLossless, "lossless"); | |
1208 | BOOL(p->bCULossless, "cu-lossless"); | |
1209 | BOOL(p->bEnableConstrainedIntra, "constrained-intra"); | |
1210 | BOOL(p->bEnableFastIntra, "fast-intra"); | |
1211 | BOOL(p->bOpenGOP, "open-gop"); | |
1212 | s += sprintf(s, " interlace=%d", p->interlaceMode); | |
1213 | s += sprintf(s, " keyint=%d", p->keyframeMax); | |
1214 | s += sprintf(s, " min-keyint=%d", p->keyframeMin); | |
1215 | s += sprintf(s, " scenecut=%d", p->scenecutThreshold); | |
1216 | s += sprintf(s, " rc-lookahead=%d", p->lookaheadDepth); | |
1217 | s += sprintf(s, " bframes=%d", p->bframes); | |
1218 | s += sprintf(s, " bframe-bias=%d", p->bFrameBias); | |
1219 | s += sprintf(s, " b-adapt=%d", p->bFrameAdaptive); | |
1220 | s += sprintf(s, " ref=%d", p->maxNumReferences); | |
1221 | BOOL(p->bEnableWeightedPred, "weightp"); | |
1222 | BOOL(p->bEnableWeightedBiPred, "weightb"); | |
1223 | s += sprintf(s, " aq-mode=%d", p->rc.aqMode); | |
1224 | s += sprintf(s, " aq-strength=%.2f", p->rc.aqStrength); | |
1225 | s += sprintf(s, " cbqpoffs=%d", p->cbQpOffset); | |
1226 | s += sprintf(s, " crqpoffs=%d", p->crQpOffset); | |
1227 | s += sprintf(s, " rd=%d", p->rdLevel); | |
1228 | s += sprintf(s, " psy-rd=%.2f", p->psyRd); | |
1229 | s += sprintf(s, " psy-rdoq=%.2f", p->psyRdoq); | |
1230 | BOOL(p->bEnableSignHiding, "signhide"); | |
1231 | BOOL(p->bEnableLoopFilter, "lft"); | |
1232 | BOOL(p->bEnableSAO, "sao"); | |
1233 | BOOL(p->bSaoNonDeblocked, "sao-non-deblock"); | |
1234 | BOOL(p->bBPyramid, "b-pyramid"); | |
1235 | BOOL(p->rc.cuTree, "cutree"); | |
1236 | s += sprintf(s, " rc=%s", p->rc.rateControlMode == X265_RC_ABR ? ( | |
1237 | p->rc.bStatRead ? "2 pass" : p->rc.bitrate == p->rc.vbvMaxBitrate ? "cbr" : "abr") | |
1238 | : p->rc.rateControlMode == X265_RC_CRF ? "crf" : "cqp"); | |
1239 | if (p->rc.rateControlMode == X265_RC_ABR || p->rc.rateControlMode == X265_RC_CRF) | |
1240 | { | |
1241 | if (p->rc.rateControlMode == X265_RC_CRF) | |
1242 | s += sprintf(s, " crf=%.1f", p->rc.rfConstant); | |
1243 | else | |
1244 | s += sprintf(s, " bitrate=%d ratetol=%.1f", | |
1245 | p->rc.bitrate, p->rc.rateTolerance); | |
1246 | s += sprintf(s, " qcomp=%.2f qpmin=%d qpmax=%d qpstep=%d", | |
1247 | p->rc.qCompress, QP_MIN, QP_MAX_SPEC, p->rc.qpStep); | |
1248 | if (p->rc.bStatRead) | |
1249 | s += sprintf( s, " cplxblur=%.1f qblur=%.1f", | |
1250 | p->rc.complexityBlur, p->rc.qblur); | |
1251 | if (p->rc.vbvBufferSize) | |
1252 | { | |
1253 | s += sprintf(s, " vbv-maxrate=%d vbv-bufsize=%d", | |
1254 | p->rc.vbvMaxBitrate, p->rc.vbvBufferSize); | |
1255 | if (p->rc.rateControlMode == X265_RC_CRF) | |
1256 | s += sprintf(s, " crf-max=%.1f", p->rc.rfConstantMax); | |
1257 | } | |
1258 | } | |
1259 | else if (p->rc.rateControlMode == X265_RC_CQP) | |
1260 | s += sprintf(s, " qp=%d", p->rc.qp); | |
1261 | if (!(p->rc.rateControlMode == X265_RC_CQP && p->rc.qp == 0)) | |
1262 | { | |
1263 | s += sprintf(s, " ipratio=%.2f", p->rc.ipFactor); | |
1264 | if (p->bframes) | |
1265 | s += sprintf(s, " pbratio=%.2f", p->rc.pbFactor); | |
1266 | } | |
1267 | #undef BOOL | |
1268 | return buf; | |
1269 | } | |
1270 | ||
1271 | bool parseLambdaFile(x265_param *param) | |
1272 | { | |
1273 | if (!param->rc.lambdaFileName) | |
1274 | return false; | |
1275 | ||
1276 | FILE *lfn = fopen(param->rc.lambdaFileName, "r"); | |
1277 | if (!lfn) | |
1278 | { | |
1279 | x265_log(param, X265_LOG_ERROR, "unable to read lambda file <%s>\n", param->rc.lambdaFileName); | |
1280 | return true; | |
1281 | } | |
1282 | ||
1283 | char line[2048]; | |
1284 | char *toksave = NULL, *tok = NULL, *buf = NULL; | |
1285 | ||
1286 | for (int t = 0; t < 3; t++) | |
1287 | { | |
1288 | double *table = t ? x265_lambda2_tab : x265_lambda_tab; | |
1289 | ||
1290 | for (int i = 0; i < QP_MAX_MAX + 1; i++) | |
1291 | { | |
1292 | double value; | |
1293 | ||
1294 | do | |
1295 | { | |
1296 | if (!tok) | |
1297 | { | |
1298 | /* consume a line of text file */ | |
1299 | if (!fgets(line, sizeof(line), lfn)) | |
1300 | { | |
1301 | fclose(lfn); | |
1302 | ||
1303 | if (t < 2) | |
1304 | { | |
1305 | x265_log(param, X265_LOG_ERROR, "lambda file is incomplete\n"); | |
1306 | return true; | |
1307 | } | |
1308 | else | |
1309 | return false; | |
1310 | } | |
1311 | ||
1312 | /* truncate at first hash */ | |
1313 | char *hash = strchr(line, '#'); | |
1314 | if (hash) *hash = 0; | |
1315 | buf = line; | |
1316 | } | |
1317 | ||
1318 | tok = strtok_r(buf, " ,", &toksave); | |
1319 | buf = NULL; | |
1320 | if (tok && sscanf(tok, "%lf", &value) == 1) | |
1321 | break; | |
1322 | } | |
1323 | while (1); | |
1324 | ||
1325 | if (t == 2) | |
1326 | { | |
1327 | x265_log(param, X265_LOG_ERROR, "lambda file contains too many values\n"); | |
1328 | fclose(lfn); | |
1329 | return true; | |
1330 | } | |
1331 | else | |
1332 | x265_log(param, X265_LOG_DEBUG, "lambda%c[%d] = %lf\n", t ? '2' : ' ', i, value); | |
1333 | table[i] = value; | |
1334 | } | |
1335 | } | |
1336 | ||
1337 | fclose(lfn); | |
1338 | return false; | |
1339 | } | |
1340 | ||
1341 | } |