1 /*****************************************************************************
2 * Copyright (C) 2013-2020 MulticoreWare, Inc
3 *
4 * Authors: Deepthi Nandakumar <deepthi@multicorewareinc.com>
5 * Min Chen <min.chen@multicorewareinc.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 "threading.h"
28 #include "param.h"
29 #include "cpu.h"
30 #include "x265.h"
31 #include "svt.h"
32
33 #if _MSC_VER
34 #pragma warning(disable: 4996) // POSIX functions are just fine, thanks
35 #pragma warning(disable: 4706) // assignment within conditional
36 #pragma warning(disable: 4127) // conditional expression is constant
37 #endif
38
39 #if _WIN32
40 #define strcasecmp _stricmp
41 #endif
42
43 #if !defined(HAVE_STRTOK_R)
44
45 /*
46 * adapted from public domain strtok_r() by Charlie Gordon
47 *
48 * from comp.lang.c 9/14/2007
49 *
50 * http://groups.google.com/group/comp.lang.c/msg/2ab1ecbb86646684
51 *
52 * (Declaration that it's public domain):
53 * http://groups.google.com/group/comp.lang.c/msg/7c7b39328fefab9c
54 */
55
56 #undef strtok_r
strtok_r(char * str,const char * delim,char ** nextp)57 static char* strtok_r(char* str, const char* delim, 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 #if EXPORT_C_API
82
83 /* these functions are exported as C functions (default) */
84 using namespace X265_NS;
85 extern "C" {
86
87 #else
88
89 /* these functions exist within private namespace (multilib) */
90 namespace X265_NS {
91
92 #endif
93
x265_param_alloc()94 x265_param *x265_param_alloc()
95 {
96 x265_param* param = (x265_param*)x265_malloc(sizeof(x265_param));
97 #ifdef SVT_HEVC
98 param->svtHevcParam = (EB_H265_ENC_CONFIGURATION*)x265_malloc(sizeof(EB_H265_ENC_CONFIGURATION));
99 #endif
100 return param;
101 }
102
x265_param_free(x265_param * p)103 void x265_param_free(x265_param* p)
104 {
105 x265_zone_free(p);
106 #ifdef SVT_HEVC
107 x265_free(p->svtHevcParam);
108 #endif
109 x265_free(p);
110 }
111
x265_param_default(x265_param * param)112 void x265_param_default(x265_param* param)
113 {
114 #ifdef SVT_HEVC
115 EB_H265_ENC_CONFIGURATION* svtParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
116 #endif
117
118 memset(param, 0, sizeof(x265_param));
119
120 /* Applying default values to all elements in the param structure */
121 param->cpuid = X265_NS::cpu_detect(false);
122 param->bEnableWavefront = 1;
123 param->frameNumThreads = 0;
124
125 param->logLevel = X265_LOG_INFO;
126 param->csvLogLevel = 0;
127 param->csvfn = NULL;
128 param->rc.lambdaFileName = NULL;
129 param->bLogCuStats = 0;
130 param->decodedPictureHashSEI = 0;
131
132 /* Quality Measurement Metrics */
133 param->bEnablePsnr = 0;
134 param->bEnableSsim = 0;
135
136 /* Source specifications */
137 param->internalBitDepth = X265_DEPTH;
138 param->sourceBitDepth = 8;
139 param->internalCsp = X265_CSP_I420;
140 param->levelIdc = 0; //Auto-detect level
141 param->uhdBluray = 0;
142 param->bHighTier = 1; //Allow high tier by default
143 param->interlaceMode = 0;
144 param->bField = 0;
145 param->bAnnexB = 1;
146 param->bRepeatHeaders = 0;
147 param->bEnableAccessUnitDelimiters = 0;
148 param->bEmitHRDSEI = 0;
149 param->bEmitInfoSEI = 1;
150 param->bEmitHDRSEI = 0; /*Deprecated*/
151 param->bEmitHDR10SEI = 0;
152 param->bEmitIDRRecoverySEI = 0;
153
154 /* CU definitions */
155 param->maxCUSize = 64;
156 param->minCUSize = 8;
157 param->tuQTMaxInterDepth = 1;
158 param->tuQTMaxIntraDepth = 1;
159 param->maxTUSize = 32;
160
161 /* Coding Structure */
162 param->keyframeMin = 0;
163 param->keyframeMax = 250;
164 param->gopLookahead = 0;
165 param->bOpenGOP = 1;
166 param->bframes = 4;
167 param->lookaheadDepth = 20;
168 param->bFrameAdaptive = X265_B_ADAPT_TRELLIS;
169 param->bBPyramid = 1;
170 param->scenecutThreshold = 40; /* Magic number pulled in from x264 */
171 param->edgeTransitionThreshold = 0.01;
172 param->bHistBasedSceneCut = 0;
173 param->lookaheadSlices = 8;
174 param->lookaheadThreads = 0;
175 param->scenecutBias = 5.0;
176 param->radl = 0;
177 param->chunkStart = 0;
178 param->chunkEnd = 0;
179 param->bEnableHRDConcatFlag = 0;
180 param->bEnableFades = 0;
181 param->bEnableSceneCutAwareQp = 0;
182 param->scenecutWindow = 500;
183 param->maxQpDelta = 5;
184
185 /* Intra Coding Tools */
186 param->bEnableConstrainedIntra = 0;
187 param->bEnableStrongIntraSmoothing = 1;
188 param->bEnableFastIntra = 0;
189 param->bEnableSplitRdSkip = 0;
190
191 /* Inter Coding tools */
192 param->searchMethod = X265_HEX_SEARCH;
193 param->subpelRefine = 2;
194 param->searchRange = 57;
195 param->maxNumMergeCand = 3;
196 param->limitReferences = 1;
197 param->limitModes = 0;
198 param->bEnableWeightedPred = 1;
199 param->bEnableWeightedBiPred = 0;
200 param->bEnableEarlySkip = 1;
201 param->recursionSkipMode = 1;
202 param->edgeVarThreshold = 0.05f;
203 param->bEnableAMP = 0;
204 param->bEnableRectInter = 0;
205 param->rdLevel = 3;
206 param->rdoqLevel = 0;
207 param->bEnableSignHiding = 1;
208 param->bEnableTransformSkip = 0;
209 param->bEnableTSkipFast = 0;
210 param->maxNumReferences = 3;
211 param->bEnableTemporalMvp = 1;
212 param->bEnableHME = 0;
213 param->hmeSearchMethod[0] = X265_HEX_SEARCH;
214 param->hmeSearchMethod[1] = param->hmeSearchMethod[2] = X265_UMH_SEARCH;
215 param->hmeRange[0] = 16;
216 param->hmeRange[1] = 32;
217 param->hmeRange[2] = 48;
218 param->bSourceReferenceEstimation = 0;
219 param->limitTU = 0;
220 param->dynamicRd = 0;
221
222 /* Loop Filter */
223 param->bEnableLoopFilter = 1;
224
225 /* SAO Loop Filter */
226 param->bEnableSAO = 1;
227 param->bSaoNonDeblocked = 0;
228 param->bLimitSAO = 0;
229 param->selectiveSAO = 0;
230
231 /* Coding Quality */
232 param->cbQpOffset = 0;
233 param->crQpOffset = 0;
234 param->rdPenalty = 0;
235 param->psyRd = 2.0;
236 param->psyRdoq = 0.0;
237 param->analysisReuseMode = 0; /*DEPRECATED*/
238 param->analysisMultiPassRefine = 0;
239 param->analysisMultiPassDistortion = 0;
240 param->analysisReuseFileName = NULL;
241 param->analysisSave = NULL;
242 param->analysisLoad = NULL;
243 param->bIntraInBFrames = 1;
244 param->bLossless = 0;
245 param->bCULossless = 0;
246 param->bEnableTemporalSubLayers = 0;
247 param->bEnableRdRefine = 0;
248 param->bMultiPassOptRPS = 0;
249 param->bSsimRd = 0;
250
251 /* Rate control options */
252 param->rc.vbvMaxBitrate = 0;
253 param->rc.vbvBufferSize = 0;
254 param->rc.vbvBufferInit = 0.9;
255 param->vbvBufferEnd = 0;
256 param->vbvEndFrameAdjust = 0;
257 param->rc.rfConstant = 28;
258 param->rc.bitrate = 0;
259 param->rc.qCompress = 0.6;
260 param->rc.ipFactor = 1.4f;
261 param->rc.pbFactor = 1.3f;
262 param->rc.qpStep = 4;
263 param->rc.rateControlMode = X265_RC_CRF;
264 param->rc.qp = 32;
265 param->rc.aqMode = X265_AQ_AUTO_VARIANCE;
266 param->rc.hevcAq = 0;
267 param->rc.qgSize = 32;
268 param->rc.aqStrength = 1.0;
269 param->rc.qpAdaptationRange = 1.0;
270 param->rc.cuTree = 1;
271 param->rc.rfConstantMax = 0;
272 param->rc.rfConstantMin = 0;
273 param->rc.bStatRead = 0;
274 param->rc.bStatWrite = 0;
275 param->rc.statFileName = NULL;
276 param->rc.complexityBlur = 20;
277 param->rc.qblur = 0.5;
278 param->rc.zoneCount = 0;
279 param->rc.zonefileCount = 0;
280 param->rc.zones = NULL;
281 param->rc.bEnableSlowFirstPass = 1;
282 param->rc.bStrictCbr = 0;
283 param->rc.bEnableGrain = 0;
284 param->rc.qpMin = 0;
285 param->rc.qpMax = QP_MAX_MAX;
286 param->rc.bEnableConstVbv = 0;
287 param->bResetZoneConfig = 1;
288 param->reconfigWindowSize = 0;
289 param->decoderVbvMaxRate = 0;
290
291 /* Video Usability Information (VUI) */
292 param->vui.aspectRatioIdc = 0;
293 param->vui.sarWidth = 0;
294 param->vui.sarHeight = 0;
295 param->vui.bEnableOverscanAppropriateFlag = 0;
296 param->vui.bEnableVideoSignalTypePresentFlag = 0;
297 param->vui.videoFormat = 5;
298 param->vui.bEnableVideoFullRangeFlag = 0;
299 param->vui.bEnableColorDescriptionPresentFlag = 0;
300 param->vui.colorPrimaries = 2;
301 param->vui.transferCharacteristics = 2;
302 param->vui.matrixCoeffs = 2;
303 param->vui.bEnableChromaLocInfoPresentFlag = 0;
304 param->vui.chromaSampleLocTypeTopField = 0;
305 param->vui.chromaSampleLocTypeBottomField = 0;
306 param->vui.bEnableDefaultDisplayWindowFlag = 0;
307 param->vui.defDispWinLeftOffset = 0;
308 param->vui.defDispWinRightOffset = 0;
309 param->vui.defDispWinTopOffset = 0;
310 param->vui.defDispWinBottomOffset = 0;
311 param->maxCLL = 0;
312 param->maxFALL = 0;
313 param->minLuma = 0;
314 param->maxLuma = PIXEL_MAX;
315 param->log2MaxPocLsb = 8;
316 param->maxSlices = 1;
317
318 /*Conformance window*/
319 param->confWinRightOffset = 0;
320 param->confWinBottomOffset = 0;
321
322 param->bEmitVUITimingInfo = 1;
323 param->bEmitVUIHRDInfo = 1;
324 param->bOptQpPPS = 0;
325 param->bOptRefListLengthPPS = 0;
326 param->bOptCUDeltaQP = 0;
327 param->bAQMotion = 0;
328 param->bHDROpt = 0; /*DEPRECATED*/
329 param->bHDR10Opt = 0;
330 param->analysisReuseLevel = 0; /*DEPRECATED*/
331 param->analysisSaveReuseLevel = 0;
332 param->analysisLoadReuseLevel = 0;
333 param->toneMapFile = NULL;
334 param->bDhdr10opt = 0;
335 param->dolbyProfile = 0;
336 param->bCTUInfo = 0;
337 param->bUseRcStats = 0;
338 param->scaleFactor = 0;
339 param->intraRefine = 0;
340 param->interRefine = 0;
341 param->bDynamicRefine = 0;
342 param->mvRefine = 1;
343 param->ctuDistortionRefine = 0;
344 param->bUseAnalysisFile = 1;
345 param->csvfpt = NULL;
346 param->forceFlush = 0;
347 param->bDisableLookahead = 0;
348 param->bCopyPicToFrame = 1;
349 param->maxAUSizeFactor = 1;
350 param->naluFile = NULL;
351
352 /* DCT Approximations */
353 param->bLowPassDct = 0;
354 param->bAnalysisType = 0;
355 param->bSingleSeiNal = 0;
356
357 /* SEI messages */
358 param->preferredTransferCharacteristics = -1;
359 param->pictureStructure = -1;
360 param->bEmitCLL = 1;
361
362 param->bEnableFrameDuplication = 0;
363 param->dupThreshold = 70;
364
365 /* SVT Hevc Encoder specific params */
366 param->bEnableSvtHevc = 0;
367 param->svtHevcParam = NULL;
368
369 #ifdef SVT_HEVC
370 param->svtHevcParam = svtParam;
371 svt_param_default(param);
372 #endif
373 }
374
x265_param_default_preset(x265_param * param,const char * preset,const char * tune)375 int x265_param_default_preset(x265_param* param, const char* preset, const char* tune)
376 {
377 #if EXPORT_C_API
378 ::x265_param_default(param);
379 #else
380 X265_NS::x265_param_default(param);
381 #endif
382
383 if (preset)
384 {
385 char *end;
386 int i = strtol(preset, &end, 10);
387 if (*end == 0 && i >= 0 && i < (int)(sizeof(x265_preset_names) / sizeof(*x265_preset_names) - 1))
388 preset = x265_preset_names[i];
389
390 if (!strcmp(preset, "ultrafast"))
391 {
392 param->maxNumMergeCand = 2;
393 param->bIntraInBFrames = 0;
394 param->lookaheadDepth = 5;
395 param->scenecutThreshold = 0; // disable lookahead
396 param->maxCUSize = 32;
397 param->minCUSize = 16;
398 param->bframes = 3;
399 param->bFrameAdaptive = 0;
400 param->subpelRefine = 0;
401 param->searchMethod = X265_DIA_SEARCH;
402 param->bEnableSAO = 0;
403 param->bEnableSignHiding = 0;
404 param->bEnableWeightedPred = 0;
405 param->rdLevel = 2;
406 param->maxNumReferences = 1;
407 param->limitReferences = 0;
408 param->rc.aqStrength = 0.0;
409 param->rc.aqMode = X265_AQ_NONE;
410 param->rc.hevcAq = 0;
411 param->rc.qgSize = 32;
412 param->bEnableFastIntra = 1;
413 }
414 else if (!strcmp(preset, "superfast"))
415 {
416 param->maxNumMergeCand = 2;
417 param->bIntraInBFrames = 0;
418 param->lookaheadDepth = 10;
419 param->maxCUSize = 32;
420 param->bframes = 3;
421 param->bFrameAdaptive = 0;
422 param->subpelRefine = 1;
423 param->bEnableWeightedPred = 0;
424 param->rdLevel = 2;
425 param->maxNumReferences = 1;
426 param->limitReferences = 0;
427 param->rc.aqStrength = 0.0;
428 param->rc.aqMode = X265_AQ_NONE;
429 param->rc.hevcAq = 0;
430 param->rc.qgSize = 32;
431 param->bEnableSAO = 0;
432 param->bEnableFastIntra = 1;
433 }
434 else if (!strcmp(preset, "veryfast"))
435 {
436 param->maxNumMergeCand = 2;
437 param->limitReferences = 3;
438 param->bIntraInBFrames = 0;
439 param->lookaheadDepth = 15;
440 param->bFrameAdaptive = 0;
441 param->subpelRefine = 1;
442 param->rdLevel = 2;
443 param->maxNumReferences = 2;
444 param->rc.qgSize = 32;
445 param->bEnableFastIntra = 1;
446 }
447 else if (!strcmp(preset, "faster"))
448 {
449 param->maxNumMergeCand = 2;
450 param->limitReferences = 3;
451 param->bIntraInBFrames = 0;
452 param->lookaheadDepth = 15;
453 param->bFrameAdaptive = 0;
454 param->rdLevel = 2;
455 param->maxNumReferences = 2;
456 param->bEnableFastIntra = 1;
457 }
458 else if (!strcmp(preset, "fast"))
459 {
460 param->maxNumMergeCand = 2;
461 param->limitReferences = 3;
462 param->bEnableEarlySkip = 0;
463 param->bIntraInBFrames = 0;
464 param->lookaheadDepth = 15;
465 param->bFrameAdaptive = 0;
466 param->rdLevel = 2;
467 param->maxNumReferences = 3;
468 param->bEnableFastIntra = 1;
469 }
470 else if (!strcmp(preset, "medium"))
471 {
472 /* defaults */
473 }
474 else if (!strcmp(preset, "slow"))
475 {
476 param->limitReferences = 3;
477 param->bEnableEarlySkip = 0;
478 param->bIntraInBFrames = 0;
479 param->bEnableRectInter = 1;
480 param->lookaheadDepth = 25;
481 param->rdLevel = 4;
482 param->rdoqLevel = 2;
483 param->psyRdoq = 1.0;
484 param->subpelRefine = 3;
485 param->searchMethod = X265_STAR_SEARCH;
486 param->maxNumReferences = 4;
487 param->limitModes = 1;
488 param->lookaheadSlices = 4; // limit parallelism as already enough work exists
489 }
490 else if (!strcmp(preset, "slower"))
491 {
492 param->bEnableEarlySkip = 0;
493 param->bEnableWeightedBiPred = 1;
494 param->bEnableAMP = 1;
495 param->bEnableRectInter = 1;
496 param->lookaheadDepth = 40;
497 param->bframes = 8;
498 param->tuQTMaxInterDepth = 3;
499 param->tuQTMaxIntraDepth = 3;
500 param->rdLevel = 6;
501 param->rdoqLevel = 2;
502 param->psyRdoq = 1.0;
503 param->subpelRefine = 4;
504 param->maxNumMergeCand = 4;
505 param->searchMethod = X265_STAR_SEARCH;
506 param->maxNumReferences = 5;
507 param->limitModes = 1;
508 param->lookaheadSlices = 0; // disabled for best quality
509 param->limitTU = 4;
510 }
511 else if (!strcmp(preset, "veryslow"))
512 {
513 param->bEnableEarlySkip = 0;
514 param->bEnableWeightedBiPred = 1;
515 param->bEnableAMP = 1;
516 param->bEnableRectInter = 1;
517 param->lookaheadDepth = 40;
518 param->bframes = 8;
519 param->tuQTMaxInterDepth = 3;
520 param->tuQTMaxIntraDepth = 3;
521 param->rdLevel = 6;
522 param->rdoqLevel = 2;
523 param->psyRdoq = 1.0;
524 param->subpelRefine = 4;
525 param->maxNumMergeCand = 5;
526 param->searchMethod = X265_STAR_SEARCH;
527 param->maxNumReferences = 5;
528 param->limitReferences = 0;
529 param->limitModes = 0;
530 param->lookaheadSlices = 0; // disabled for best quality
531 param->limitTU = 0;
532 }
533 else if (!strcmp(preset, "placebo"))
534 {
535 param->bEnableEarlySkip = 0;
536 param->bEnableWeightedBiPred = 1;
537 param->bEnableAMP = 1;
538 param->bEnableRectInter = 1;
539 param->lookaheadDepth = 60;
540 param->searchRange = 92;
541 param->bframes = 8;
542 param->tuQTMaxInterDepth = 4;
543 param->tuQTMaxIntraDepth = 4;
544 param->rdLevel = 6;
545 param->rdoqLevel = 2;
546 param->psyRdoq = 1.0;
547 param->subpelRefine = 5;
548 param->maxNumMergeCand = 5;
549 param->searchMethod = X265_STAR_SEARCH;
550 param->bEnableTransformSkip = 1;
551 param->recursionSkipMode = 0;
552 param->maxNumReferences = 5;
553 param->limitReferences = 0;
554 param->lookaheadSlices = 0; // disabled for best quality
555 // TODO: optimized esa
556 }
557 else
558 return -1;
559 }
560 if (tune)
561 {
562 if (!strcmp(tune, "psnr"))
563 {
564 param->rc.aqStrength = 0.0;
565 param->psyRd = 0.0;
566 param->psyRdoq = 0.0;
567 }
568 else if (!strcmp(tune, "ssim"))
569 {
570 param->rc.aqMode = X265_AQ_AUTO_VARIANCE;
571 param->psyRd = 0.0;
572 param->psyRdoq = 0.0;
573 }
574 else if (!strcmp(tune, "fastdecode") ||
575 !strcmp(tune, "fast-decode"))
576 {
577 param->bEnableLoopFilter = 0;
578 param->bEnableSAO = 0;
579 param->bEnableWeightedPred = 0;
580 param->bEnableWeightedBiPred = 0;
581 param->bIntraInBFrames = 0;
582 }
583 else if (!strcmp(tune, "zerolatency") ||
584 !strcmp(tune, "zero-latency"))
585 {
586 param->bFrameAdaptive = 0;
587 param->bframes = 0;
588 param->lookaheadDepth = 0;
589 param->scenecutThreshold = 0;
590 param->bHistBasedSceneCut = 0;
591 param->rc.cuTree = 0;
592 param->frameNumThreads = 1;
593 }
594 else if (!strcmp(tune, "grain"))
595 {
596 param->rc.ipFactor = 1.1;
597 param->rc.pbFactor = 1.0;
598 param->rc.cuTree = 0;
599 param->rc.aqMode = 0;
600 param->rc.hevcAq = 0;
601 param->rc.qpStep = 1;
602 param->rc.bEnableGrain = 1;
603 param->recursionSkipMode = 0;
604 param->psyRd = 4.0;
605 param->psyRdoq = 10.0;
606 param->bEnableSAO = 0;
607 param->rc.bEnableConstVbv = 1;
608 }
609 else if (!strcmp(tune, "animation"))
610 {
611 param->bframes = (param->bframes + 2) >= param->lookaheadDepth? param->bframes : param->bframes + 2;
612 param->psyRd = 0.4;
613 param->rc.aqStrength = 0.4;
614 param->deblockingFilterBetaOffset = 1;
615 param->deblockingFilterTCOffset = 1;
616 }
617 else if (!strcmp(tune, "vmaf")) /*Adding vmaf for x265 + SVT-HEVC integration support*/
618 {
619 /*vmaf is under development, currently x265 won't support vmaf*/
620 }
621 else
622 return -1;
623 }
624
625 #ifdef SVT_HEVC
626 if (svt_set_preset(param, preset))
627 return -1;
628 #endif
629
630 return 0;
631 }
632
x265_atobool(const char * str,bool & bError)633 static int x265_atobool(const char* str, bool& bError)
634 {
635 if (!strcmp(str, "1") ||
636 !strcmp(str, "true") ||
637 !strcmp(str, "yes"))
638 return 1;
639 if (!strcmp(str, "0") ||
640 !strcmp(str, "false") ||
641 !strcmp(str, "no"))
642 return 0;
643 bError = true;
644 return 0;
645 }
646
parseName(const char * arg,const char * const * names,bool & bError)647 static int parseName(const char* arg, const char* const* names, bool& bError)
648 {
649 for (int i = 0; names[i]; i++)
650 if (!strcmp(arg, names[i]))
651 return i;
652
653 return x265_atoi(arg, bError);
654 }
655 /* internal versions of string-to-int with additional error checking */
656 #undef atoi
657 #undef atof
658 #define atoi(str) x265_atoi(str, bError)
659 #define atof(str) x265_atof(str, bError)
660 #define atobool(str) (x265_atobool(str, bError))
661
x265_zone_param_parse(x265_param * p,const char * name,const char * value)662 int x265_zone_param_parse(x265_param* p, const char* name, const char* value)
663 {
664 bool bError = false;
665 char nameBuf[64];
666
667 if (!name)
668 return X265_PARAM_BAD_NAME;
669
670 // skip -- prefix if provided
671 if (name[0] == '-' && name[1] == '-')
672 name += 2;
673
674 // s/_/-/g
675 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
676 {
677 char *c;
678 strcpy(nameBuf, name);
679 while ((c = strchr(nameBuf, '_')) != 0)
680 *c = '-';
681
682 name = nameBuf;
683 }
684
685 if (!strncmp(name, "no-", 3))
686 {
687 name += 3;
688 value = !value || x265_atobool(value, bError) ? "false" : "true";
689 }
690 else if (!strncmp(name, "no", 2))
691 {
692 name += 2;
693 value = !value || x265_atobool(value, bError) ? "false" : "true";
694 }
695 else if (!value)
696 value = "true";
697 else if (value[0] == '=')
698 value++;
699
700 #define OPT(STR) else if (!strcmp(name, STR))
701 #define OPT2(STR1, STR2) else if (!strcmp(name, STR1) || !strcmp(name, STR2))
702
703 if (0);
704 OPT("ref") p->maxNumReferences = atoi(value);
705 OPT("fast-intra") p->bEnableFastIntra = atobool(value);
706 OPT("early-skip") p->bEnableEarlySkip = atobool(value);
707 OPT("rskip") p->recursionSkipMode = atoi(value);
708 OPT("rskip-edge-threshold") p->edgeVarThreshold = atoi(value)/100.0f;
709 OPT("me") p->searchMethod = parseName(value, x265_motion_est_names, bError);
710 OPT("subme") p->subpelRefine = atoi(value);
711 OPT("merange") p->searchRange = atoi(value);
712 OPT("rect") p->bEnableRectInter = atobool(value);
713 OPT("amp") p->bEnableAMP = atobool(value);
714 OPT("max-merge") p->maxNumMergeCand = (uint32_t)atoi(value);
715 OPT("rd") p->rdLevel = atoi(value);
716 OPT("radl") p->radl = atoi(value);
717 OPT2("rdoq", "rdoq-level")
718 {
719 int bval = atobool(value);
720 if (bError || bval)
721 {
722 bError = false;
723 p->rdoqLevel = atoi(value);
724 }
725 else
726 p->rdoqLevel = 0;
727 }
728 OPT("b-intra") p->bIntraInBFrames = atobool(value);
729 OPT("scaling-list") p->scalingLists = strdup(value);
730 OPT("crf")
731 {
732 p->rc.rfConstant = atof(value);
733 p->rc.rateControlMode = X265_RC_CRF;
734 }
735 OPT("qp")
736 {
737 p->rc.qp = atoi(value);
738 p->rc.rateControlMode = X265_RC_CQP;
739 }
740 OPT("bitrate")
741 {
742 p->rc.bitrate = atoi(value);
743 p->rc.rateControlMode = X265_RC_ABR;
744 }
745 OPT("aq-mode") p->rc.aqMode = atoi(value);
746 OPT("aq-strength") p->rc.aqStrength = atof(value);
747 OPT("nr-intra") p->noiseReductionIntra = atoi(value);
748 OPT("nr-inter") p->noiseReductionInter = atoi(value);
749 OPT("limit-modes") p->limitModes = atobool(value);
750 OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);
751 OPT("cu-lossless") p->bCULossless = atobool(value);
752 OPT("rd-refine") p->bEnableRdRefine = atobool(value);
753 OPT("limit-tu") p->limitTU = atoi(value);
754 OPT("tskip") p->bEnableTransformSkip = atobool(value);
755 OPT("tskip-fast") p->bEnableTSkipFast = atobool(value);
756 OPT("rdpenalty") p->rdPenalty = atoi(value);
757 OPT("dynamic-rd") p->dynamicRd = atof(value);
758 else
759 return X265_PARAM_BAD_NAME;
760
761 #undef OPT
762 #undef OPT2
763
764 return bError ? X265_PARAM_BAD_VALUE : 0;
765 }
766
767 #undef atobool
768 #undef atoi
769 #undef atof
770
771 /* internal versions of string-to-int with additional error checking */
772 #undef atoi
773 #undef atof
774 #define atoi(str) x265_atoi(str, bError)
775 #define atof(str) x265_atof(str, bError)
776 #define atobool(str) (bNameWasBool = true, x265_atobool(str, bError))
777
x265_param_parse(x265_param * p,const char * name,const char * value)778 int x265_param_parse(x265_param* p, const char* name, const char* value)
779 {
780 bool bError = false;
781 bool bNameWasBool = false;
782 bool bValueWasNull = !value;
783 bool bExtraParams = false;
784 char nameBuf[64];
785 static int count;
786
787 if (!name)
788 return X265_PARAM_BAD_NAME;
789
790 count++;
791 // skip -- prefix if provided
792 if (name[0] == '-' && name[1] == '-')
793 name += 2;
794
795 // s/_/-/g
796 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
797 {
798 char *c;
799 strcpy(nameBuf, name);
800 while ((c = strchr(nameBuf, '_')) != 0)
801 *c = '-';
802
803 name = nameBuf;
804 }
805
806 if (!strncmp(name, "no-", 3))
807 {
808 name += 3;
809 value = !value || x265_atobool(value, bError) ? "false" : "true";
810 }
811 else if (!strncmp(name, "no", 2))
812 {
813 name += 2;
814 value = !value || x265_atobool(value, bError) ? "false" : "true";
815 }
816 else if (!value)
817 value = "true";
818 else if (value[0] == '=')
819 value++;
820
821 #if defined(_MSC_VER)
822 #pragma warning(disable: 4127) // conditional expression is constant
823 #endif
824 #define OPT(STR) else if (!strcmp(name, STR))
825 #define OPT2(STR1, STR2) else if (!strcmp(name, STR1) || !strcmp(name, STR2))
826
827 #ifdef SVT_HEVC
828 if (p->bEnableSvtHevc)
829 {
830 if(svt_param_parse(p, name, value))
831 {
832 x265_log(p, X265_LOG_ERROR, "Error while parsing params \n");
833 bError = true;
834 }
835 return bError ? X265_PARAM_BAD_VALUE : 0;
836 }
837 #endif
838
839 if (0) ;
840 OPT("asm")
841 {
842 #if X265_ARCH_X86
843 if (!strcasecmp(value, "avx512"))
844 {
845 p->cpuid = X265_NS::cpu_detect(true);
846 if (!(p->cpuid & X265_CPU_AVX512))
847 x265_log(p, X265_LOG_WARNING, "AVX512 is not supported\n");
848 }
849 else
850 {
851 if (bValueWasNull)
852 p->cpuid = atobool(value);
853 else
854 p->cpuid = parseCpuName(value, bError, false);
855 }
856 #else
857 if (bValueWasNull)
858 p->cpuid = atobool(value);
859 else
860 p->cpuid = parseCpuName(value, bError, false);
861 #endif
862 }
863 OPT("fps")
864 {
865 if (sscanf(value, "%u/%u", &p->fpsNum, &p->fpsDenom) == 2)
866 ;
867 else
868 {
869 float fps = (float)atof(value);
870 if (fps > 0 && fps <= INT_MAX / 1000)
871 {
872 p->fpsNum = (int)(fps * 1000 + .5);
873 p->fpsDenom = 1000;
874 }
875 else
876 {
877 p->fpsNum = atoi(value);
878 p->fpsDenom = 1;
879 }
880 }
881 }
882 OPT("frame-threads") p->frameNumThreads = atoi(value);
883 OPT("pmode") p->bDistributeModeAnalysis = atobool(value);
884 OPT("pme") p->bDistributeMotionEstimation = atobool(value);
885 OPT2("level-idc", "level")
886 {
887 /* allow "5.1" or "51", both converted to integer 51 */
888 /* if level-idc specifies an obviously wrong value in either float or int,
889 throw error consistently. Stronger level checking will be done in encoder_open() */
890 if (atof(value) < 10)
891 p->levelIdc = (int)(10 * atof(value) + .5);
892 else if (atoi(value) < 100)
893 p->levelIdc = atoi(value);
894 else
895 bError = true;
896 }
897 OPT("high-tier") p->bHighTier = atobool(value);
898 OPT("allow-non-conformance") p->bAllowNonConformance = atobool(value);
899 OPT2("log-level", "log")
900 {
901 p->logLevel = atoi(value);
902 if (bError)
903 {
904 bError = false;
905 p->logLevel = parseName(value, logLevelNames, bError) - 1;
906 }
907 }
908 OPT("cu-stats") p->bLogCuStats = atobool(value);
909 OPT("total-frames") p->totalFrames = atoi(value);
910 OPT("annexb") p->bAnnexB = atobool(value);
911 OPT("repeat-headers") p->bRepeatHeaders = atobool(value);
912 OPT("wpp") p->bEnableWavefront = atobool(value);
913 OPT("ctu") p->maxCUSize = (uint32_t)atoi(value);
914 OPT("min-cu-size") p->minCUSize = (uint32_t)atoi(value);
915 OPT("tu-intra-depth") p->tuQTMaxIntraDepth = (uint32_t)atoi(value);
916 OPT("tu-inter-depth") p->tuQTMaxInterDepth = (uint32_t)atoi(value);
917 OPT("max-tu-size") p->maxTUSize = (uint32_t)atoi(value);
918 OPT("subme") p->subpelRefine = atoi(value);
919 OPT("merange") p->searchRange = atoi(value);
920 OPT("rect") p->bEnableRectInter = atobool(value);
921 OPT("amp") p->bEnableAMP = atobool(value);
922 OPT("max-merge") p->maxNumMergeCand = (uint32_t)atoi(value);
923 OPT("temporal-mvp") p->bEnableTemporalMvp = atobool(value);
924 OPT("early-skip") p->bEnableEarlySkip = atobool(value);
925 OPT("rskip") p->recursionSkipMode = atoi(value);
926 OPT("rdpenalty") p->rdPenalty = atoi(value);
927 OPT("tskip") p->bEnableTransformSkip = atobool(value);
928 OPT("no-tskip-fast") p->bEnableTSkipFast = atobool(value);
929 OPT("tskip-fast") p->bEnableTSkipFast = atobool(value);
930 OPT("strong-intra-smoothing") p->bEnableStrongIntraSmoothing = atobool(value);
931 OPT("lossless") p->bLossless = atobool(value);
932 OPT("cu-lossless") p->bCULossless = atobool(value);
933 OPT2("constrained-intra", "cip") p->bEnableConstrainedIntra = atobool(value);
934 OPT("fast-intra") p->bEnableFastIntra = atobool(value);
935 OPT("open-gop") p->bOpenGOP = atobool(value);
936 OPT("intra-refresh") p->bIntraRefresh = atobool(value);
937 OPT("lookahead-slices") p->lookaheadSlices = atoi(value);
938 OPT("scenecut")
939 {
940 p->scenecutThreshold = atobool(value);
941 if (bError || p->scenecutThreshold)
942 {
943 bError = false;
944 p->scenecutThreshold = atoi(value);
945 p->bHistBasedSceneCut = 0;
946 }
947 }
948 OPT("temporal-layers") p->bEnableTemporalSubLayers = atobool(value);
949 OPT("keyint") p->keyframeMax = atoi(value);
950 OPT("min-keyint") p->keyframeMin = atoi(value);
951 OPT("rc-lookahead") p->lookaheadDepth = atoi(value);
952 OPT("bframes") p->bframes = atoi(value);
953 OPT("bframe-bias") p->bFrameBias = atoi(value);
954 OPT("b-adapt")
955 {
956 p->bFrameAdaptive = atobool(value);
957 if (bError || p->bFrameAdaptive)
958 {
959 bError = false;
960 p->bFrameAdaptive = atoi(value);
961 }
962 }
963 OPT("interlace")
964 {
965 p->interlaceMode = atobool(value);
966 if (bError || p->interlaceMode)
967 {
968 bError = false;
969 p->interlaceMode = parseName(value, x265_interlace_names, bError);
970 }
971 }
972 OPT("ref") p->maxNumReferences = atoi(value);
973 OPT("limit-refs") p->limitReferences = atoi(value);
974 OPT("limit-modes") p->limitModes = atobool(value);
975 OPT("weightp") p->bEnableWeightedPred = atobool(value);
976 OPT("weightb") p->bEnableWeightedBiPred = atobool(value);
977 OPT("cbqpoffs") p->cbQpOffset = atoi(value);
978 OPT("crqpoffs") p->crQpOffset = atoi(value);
979 OPT("rd") p->rdLevel = atoi(value);
980 OPT2("rdoq", "rdoq-level")
981 {
982 int bval = atobool(value);
983 if (bError || bval)
984 {
985 bError = false;
986 p->rdoqLevel = atoi(value);
987 }
988 else
989 p->rdoqLevel = 0;
990 }
991 OPT("psy-rd")
992 {
993 int bval = atobool(value);
994 if (bError || bval)
995 {
996 bError = false;
997 p->psyRd = atof(value);
998 }
999 else
1000 p->psyRd = 0.0;
1001 }
1002 OPT("psy-rdoq")
1003 {
1004 int bval = atobool(value);
1005 if (bError || bval)
1006 {
1007 bError = false;
1008 p->psyRdoq = atof(value);
1009 }
1010 else
1011 p->psyRdoq = 0.0;
1012 }
1013 OPT("rd-refine") p->bEnableRdRefine = atobool(value);
1014 OPT("signhide") p->bEnableSignHiding = atobool(value);
1015 OPT("b-intra") p->bIntraInBFrames = atobool(value);
1016 OPT("lft") p->bEnableLoopFilter = atobool(value); /* DEPRECATED */
1017 OPT("deblock")
1018 {
1019 if (2 == sscanf(value, "%d:%d", &p->deblockingFilterTCOffset, &p->deblockingFilterBetaOffset) ||
1020 2 == sscanf(value, "%d,%d", &p->deblockingFilterTCOffset, &p->deblockingFilterBetaOffset))
1021 {
1022 p->bEnableLoopFilter = true;
1023 }
1024 else if (sscanf(value, "%d", &p->deblockingFilterTCOffset))
1025 {
1026 p->bEnableLoopFilter = 1;
1027 p->deblockingFilterBetaOffset = p->deblockingFilterTCOffset;
1028 }
1029 else
1030 p->bEnableLoopFilter = atobool(value);
1031 }
1032 OPT("sao") p->bEnableSAO = atobool(value);
1033 OPT("sao-non-deblock") p->bSaoNonDeblocked = atobool(value);
1034 OPT("ssim") p->bEnableSsim = atobool(value);
1035 OPT("psnr") p->bEnablePsnr = atobool(value);
1036 OPT("hash") p->decodedPictureHashSEI = atoi(value);
1037 OPT("aud") p->bEnableAccessUnitDelimiters = atobool(value);
1038 OPT("info") p->bEmitInfoSEI = atobool(value);
1039 OPT("b-pyramid") p->bBPyramid = atobool(value);
1040 OPT("hrd") p->bEmitHRDSEI = atobool(value);
1041 OPT2("ipratio", "ip-factor") p->rc.ipFactor = atof(value);
1042 OPT2("pbratio", "pb-factor") p->rc.pbFactor = atof(value);
1043 OPT("qcomp") p->rc.qCompress = atof(value);
1044 OPT("qpstep") p->rc.qpStep = atoi(value);
1045 OPT("cplxblur") p->rc.complexityBlur = atof(value);
1046 OPT("qblur") p->rc.qblur = atof(value);
1047 OPT("aq-mode") p->rc.aqMode = atoi(value);
1048 OPT("aq-strength") p->rc.aqStrength = atof(value);
1049 OPT("vbv-maxrate") p->rc.vbvMaxBitrate = atoi(value);
1050 OPT("vbv-bufsize") p->rc.vbvBufferSize = atoi(value);
1051 OPT("vbv-init") p->rc.vbvBufferInit = atof(value);
1052 OPT("crf-max") p->rc.rfConstantMax = atof(value);
1053 OPT("crf-min") p->rc.rfConstantMin = atof(value);
1054 OPT("qpmax") p->rc.qpMax = atoi(value);
1055 OPT("crf")
1056 {
1057 p->rc.rfConstant = atof(value);
1058 p->rc.rateControlMode = X265_RC_CRF;
1059 }
1060 OPT("bitrate")
1061 {
1062 p->rc.bitrate = atoi(value);
1063 p->rc.rateControlMode = X265_RC_ABR;
1064 }
1065 OPT("qp")
1066 {
1067 p->rc.qp = atoi(value);
1068 p->rc.rateControlMode = X265_RC_CQP;
1069 }
1070 OPT("rc-grain") p->rc.bEnableGrain = atobool(value);
1071 OPT("zones")
1072 {
1073 p->rc.zoneCount = 1;
1074 const char* c;
1075
1076 for (c = value; *c; c++)
1077 p->rc.zoneCount += (*c == '/');
1078
1079 p->rc.zones = X265_MALLOC(x265_zone, p->rc.zoneCount);
1080 c = value;
1081 for (int i = 0; i < p->rc.zoneCount; i++ )
1082 {
1083 int len;
1084 if (3 == sscanf(c, "%d,%d,q=%d%n", &p->rc.zones[i].startFrame, &p->rc.zones[i].endFrame, &p->rc.zones[i].qp, &len))
1085 p->rc.zones[i].bForceQp = 1;
1086 else if (3 == sscanf(c, "%d,%d,b=%f%n", &p->rc.zones[i].startFrame, &p->rc.zones[i].endFrame, &p->rc.zones[i].bitrateFactor, &len))
1087 p->rc.zones[i].bForceQp = 0;
1088 else
1089 {
1090 bError = true;
1091 break;
1092 }
1093 c += len + 1;
1094 }
1095 }
1096 OPT("input-res") bError |= sscanf(value, "%dx%d", &p->sourceWidth, &p->sourceHeight) != 2;
1097 OPT("input-csp") p->internalCsp = parseName(value, x265_source_csp_names, bError);
1098 OPT("me") p->searchMethod = parseName(value, x265_motion_est_names, bError);
1099 OPT("cutree") p->rc.cuTree = atobool(value);
1100 OPT("slow-firstpass") p->rc.bEnableSlowFirstPass = atobool(value);
1101 OPT("strict-cbr")
1102 {
1103 p->rc.bStrictCbr = atobool(value);
1104 p->rc.pbFactor = 1.0;
1105 }
1106 OPT("analysis-reuse-mode") p->analysisReuseMode = parseName(value, x265_analysis_names, bError); /*DEPRECATED*/
1107 OPT("sar")
1108 {
1109 p->vui.aspectRatioIdc = parseName(value, x265_sar_names, bError);
1110 if (bError)
1111 {
1112 p->vui.aspectRatioIdc = X265_EXTENDED_SAR;
1113 bError = sscanf(value, "%d:%d", &p->vui.sarWidth, &p->vui.sarHeight) != 2;
1114 }
1115 }
1116 OPT("overscan")
1117 {
1118 if (!strcmp(value, "show"))
1119 p->vui.bEnableOverscanInfoPresentFlag = 1;
1120 else if (!strcmp(value, "crop"))
1121 {
1122 p->vui.bEnableOverscanInfoPresentFlag = 1;
1123 p->vui.bEnableOverscanAppropriateFlag = 1;
1124 }
1125 else if (!strcmp(value, "undef"))
1126 p->vui.bEnableOverscanInfoPresentFlag = 0;
1127 else
1128 bError = true;
1129 }
1130 OPT("videoformat")
1131 {
1132 p->vui.bEnableVideoSignalTypePresentFlag = 1;
1133 p->vui.videoFormat = parseName(value, x265_video_format_names, bError);
1134 }
1135 OPT("range")
1136 {
1137 p->vui.bEnableVideoSignalTypePresentFlag = 1;
1138 p->vui.bEnableVideoFullRangeFlag = parseName(value, x265_fullrange_names, bError);
1139 }
1140 OPT("colorprim")
1141 {
1142 p->vui.bEnableVideoSignalTypePresentFlag = 1;
1143 p->vui.bEnableColorDescriptionPresentFlag = 1;
1144 p->vui.colorPrimaries = parseName(value, x265_colorprim_names, bError);
1145 }
1146 OPT("transfer")
1147 {
1148 p->vui.bEnableVideoSignalTypePresentFlag = 1;
1149 p->vui.bEnableColorDescriptionPresentFlag = 1;
1150 p->vui.transferCharacteristics = parseName(value, x265_transfer_names, bError);
1151 }
1152 OPT("colormatrix")
1153 {
1154 p->vui.bEnableVideoSignalTypePresentFlag = 1;
1155 p->vui.bEnableColorDescriptionPresentFlag = 1;
1156 p->vui.matrixCoeffs = parseName(value, x265_colmatrix_names, bError);
1157 }
1158 OPT("chromaloc")
1159 {
1160 p->vui.bEnableChromaLocInfoPresentFlag = 1;
1161 p->vui.chromaSampleLocTypeTopField = atoi(value);
1162 p->vui.chromaSampleLocTypeBottomField = p->vui.chromaSampleLocTypeTopField;
1163 }
1164 OPT2("display-window", "crop-rect")
1165 {
1166 p->vui.bEnableDefaultDisplayWindowFlag = 1;
1167 bError |= sscanf(value, "%d,%d,%d,%d",
1168 &p->vui.defDispWinLeftOffset,
1169 &p->vui.defDispWinTopOffset,
1170 &p->vui.defDispWinRightOffset,
1171 &p->vui.defDispWinBottomOffset) != 4;
1172 }
1173 OPT("nr-intra") p->noiseReductionIntra = atoi(value);
1174 OPT("nr-inter") p->noiseReductionInter = atoi(value);
1175 OPT("pass")
1176 {
1177 int pass = x265_clip3(0, 3, atoi(value));
1178 p->rc.bStatWrite = pass & 1;
1179 p->rc.bStatRead = pass & 2;
1180 }
1181 OPT("stats") p->rc.statFileName = strdup(value);
1182 OPT("scaling-list") p->scalingLists = strdup(value);
1183 OPT2("pools", "numa-pools") p->numaPools = strdup(value);
1184 OPT("lambda-file") p->rc.lambdaFileName = strdup(value);
1185 OPT("analysis-reuse-file") p->analysisReuseFileName = strdup(value);
1186 OPT("qg-size") p->rc.qgSize = atoi(value);
1187 OPT("master-display") p->masteringDisplayColorVolume = strdup(value);
1188 OPT("max-cll") bError |= sscanf(value, "%hu,%hu", &p->maxCLL, &p->maxFALL) != 2;
1189 OPT("min-luma") p->minLuma = (uint16_t)atoi(value);
1190 OPT("max-luma") p->maxLuma = (uint16_t)atoi(value);
1191 OPT("uhd-bd") p->uhdBluray = atobool(value);
1192 else
1193 bExtraParams = true;
1194
1195 // solve "fatal error C1061: compiler limit : blocks nested too deeply"
1196 if (bExtraParams)
1197 {
1198 if (0) ;
1199 OPT("csv") p->csvfn = strdup(value);
1200 OPT("csv-log-level") p->csvLogLevel = atoi(value);
1201 OPT("qpmin") p->rc.qpMin = atoi(value);
1202 OPT("analyze-src-pics") p->bSourceReferenceEstimation = atobool(value);
1203 OPT("log2-max-poc-lsb") p->log2MaxPocLsb = atoi(value);
1204 OPT("vui-timing-info") p->bEmitVUITimingInfo = atobool(value);
1205 OPT("vui-hrd-info") p->bEmitVUIHRDInfo = atobool(value);
1206 OPT("slices") p->maxSlices = atoi(value);
1207 OPT("limit-tu") p->limitTU = atoi(value);
1208 OPT("opt-qp-pps") p->bOptQpPPS = atobool(value);
1209 OPT("opt-ref-list-length-pps") p->bOptRefListLengthPPS = atobool(value);
1210 OPT("multi-pass-opt-rps") p->bMultiPassOptRPS = atobool(value);
1211 OPT("scenecut-bias") p->scenecutBias = atof(value);
1212 OPT("hist-scenecut")
1213 {
1214 p->bHistBasedSceneCut = atobool(value);
1215 if (bError)
1216 {
1217 bError = false;
1218 p->bHistBasedSceneCut = 0;
1219 }
1220 if (p->bHistBasedSceneCut)
1221 {
1222 bError = false;
1223 p->scenecutThreshold = 0;
1224 }
1225 }
1226 OPT("hist-threshold") p->edgeTransitionThreshold = atof(value);
1227 OPT("rskip-edge-threshold") p->edgeVarThreshold = atoi(value)/100.0f;
1228 OPT("lookahead-threads") p->lookaheadThreads = atoi(value);
1229 OPT("opt-cu-delta-qp") p->bOptCUDeltaQP = atobool(value);
1230 OPT("multi-pass-opt-analysis") p->analysisMultiPassRefine = atobool(value);
1231 OPT("multi-pass-opt-distortion") p->analysisMultiPassDistortion = atobool(value);
1232 OPT("aq-motion") p->bAQMotion = atobool(value);
1233 OPT("dynamic-rd") p->dynamicRd = atof(value);
1234 OPT("analysis-reuse-level")
1235 {
1236 p->analysisReuseLevel = atoi(value);
1237 p->analysisSaveReuseLevel = atoi(value);
1238 p->analysisLoadReuseLevel = atoi(value);
1239 }
1240 OPT("analysis-save-reuse-level") p->analysisSaveReuseLevel = atoi(value);
1241 OPT("analysis-load-reuse-level") p->analysisLoadReuseLevel = atoi(value);
1242 OPT("ssim-rd")
1243 {
1244 int bval = atobool(value);
1245 if (bError || bval)
1246 {
1247 bError = false;
1248 p->psyRd = 0.0;
1249 p->bSsimRd = atobool(value);
1250 }
1251 }
1252 OPT("hdr") p->bEmitHDR10SEI = atobool(value); /*DEPRECATED*/
1253 OPT("hdr10") p->bEmitHDR10SEI = atobool(value);
1254 OPT("hdr-opt") p->bHDR10Opt = atobool(value); /*DEPRECATED*/
1255 OPT("hdr10-opt") p->bHDR10Opt = atobool(value);
1256 OPT("limit-sao") p->bLimitSAO = atobool(value);
1257 OPT("dhdr10-info") p->toneMapFile = strdup(value);
1258 OPT("dhdr10-opt") p->bDhdr10opt = atobool(value);
1259 OPT("idr-recovery-sei") p->bEmitIDRRecoverySEI = atobool(value);
1260 OPT("const-vbv") p->rc.bEnableConstVbv = atobool(value);
1261 OPT("ctu-info") p->bCTUInfo = atoi(value);
1262 OPT("scale-factor") p->scaleFactor = atoi(value);
1263 OPT("refine-intra")p->intraRefine = atoi(value);
1264 OPT("refine-inter")p->interRefine = atoi(value);
1265 OPT("refine-mv")p->mvRefine = atoi(value);
1266 OPT("force-flush")p->forceFlush = atoi(value);
1267 OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);
1268 OPT("lowpass-dct") p->bLowPassDct = atobool(value);
1269 OPT("vbv-end") p->vbvBufferEnd = atof(value);
1270 OPT("vbv-end-fr-adj") p->vbvEndFrameAdjust = atof(value);
1271 OPT("copy-pic") p->bCopyPicToFrame = atobool(value);
1272 OPT("refine-analysis-type")
1273 {
1274 if (strcmp(strdup(value), "avc") == 0)
1275 {
1276 p->bAnalysisType = AVC_INFO;
1277 }
1278 else if (strcmp(strdup(value), "hevc") == 0)
1279 {
1280 p->bAnalysisType = HEVC_INFO;
1281 }
1282 else if (strcmp(strdup(value), "off") == 0)
1283 {
1284 p->bAnalysisType = DEFAULT;
1285 }
1286 else
1287 {
1288 bError = true;
1289 }
1290 }
1291 OPT("gop-lookahead") p->gopLookahead = atoi(value);
1292 OPT("analysis-save") p->analysisSave = strdup(value);
1293 OPT("analysis-load") p->analysisLoad = strdup(value);
1294 OPT("radl") p->radl = atoi(value);
1295 OPT("max-ausize-factor") p->maxAUSizeFactor = atof(value);
1296 OPT("dynamic-refine") p->bDynamicRefine = atobool(value);
1297 OPT("single-sei") p->bSingleSeiNal = atobool(value);
1298 OPT("atc-sei") p->preferredTransferCharacteristics = atoi(value);
1299 OPT("pic-struct") p->pictureStructure = atoi(value);
1300 OPT("chunk-start") p->chunkStart = atoi(value);
1301 OPT("chunk-end") p->chunkEnd = atoi(value);
1302 OPT("nalu-file") p->naluFile = strdup(value);
1303 OPT("dolby-vision-profile")
1304 {
1305 if (atof(value) < 10)
1306 p->dolbyProfile = (int)(10 * atof(value) + .5);
1307 else if (atoi(value) < 100)
1308 p->dolbyProfile = atoi(value);
1309 else
1310 bError = true;
1311 }
1312 OPT("hrd-concat") p->bEnableHRDConcatFlag = atobool(value);
1313 OPT("refine-ctu-distortion") p->ctuDistortionRefine = atoi(value);
1314 OPT("hevc-aq") p->rc.hevcAq = atobool(value);
1315 OPT("qp-adaptation-range") p->rc.qpAdaptationRange = atof(value);
1316 #ifdef SVT_HEVC
1317 OPT("svt")
1318 {
1319 p->bEnableSvtHevc = atobool(value);
1320 if (count > 1 && p->bEnableSvtHevc)
1321 {
1322 x265_log(NULL, X265_LOG_ERROR, "Enable SVT should be the first call to x265_parse_parse \n");
1323 bError = true;
1324 }
1325 }
1326 OPT("svt-hme") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1327 OPT("svt-search-width") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1328 OPT("svt-search-height") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1329 OPT("svt-compressed-ten-bit-format") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1330 OPT("svt-speed-control") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1331 OPT("input-depth") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1332 OPT("svt-preset-tuner") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1333 OPT("svt-hierarchical-level") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1334 OPT("svt-base-layer-switch-mode") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1335 OPT("svt-pred-struct") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1336 OPT("svt-fps-in-vps") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);
1337 #endif
1338 OPT("selective-sao")
1339 {
1340 p->selectiveSAO = atoi(value);
1341 }
1342 OPT("fades") p->bEnableFades = atobool(value);
1343 OPT("scenecut-aware-qp") p->bEnableSceneCutAwareQp = atobool(value);
1344 OPT("scenecut-window") p->scenecutWindow = atoi(value);
1345 OPT("max-qp-delta") p->maxQpDelta = atoi(value);
1346 OPT("field") p->bField = atobool( value );
1347 OPT("cll") p->bEmitCLL = atobool(value);
1348 OPT("frame-dup") p->bEnableFrameDuplication = atobool(value);
1349 OPT("dup-threshold") p->dupThreshold = atoi(value);
1350 OPT("hme") p->bEnableHME = atobool(value);
1351 OPT("hme-search")
1352 {
1353 char search[3][5];
1354 memset(search, '\0', 15 * sizeof(char));
1355 if(3 == sscanf(value, "%d,%d,%d", &p->hmeSearchMethod[0], &p->hmeSearchMethod[1], &p->hmeSearchMethod[2]) ||
1356 3 == sscanf(value, "%4[^,],%4[^,],%4[^,]", search[0], search[1], search[2]))
1357 {
1358 if(search[0][0])
1359 for(int level = 0; level < 3; level++)
1360 p->hmeSearchMethod[level] = parseName(search[level], x265_motion_est_names, bError);
1361 }
1362 else if (sscanf(value, "%d", &p->hmeSearchMethod[0]) || sscanf(value, "%s", search[0]))
1363 {
1364 if (search[0][0]) {
1365 p->hmeSearchMethod[0] = parseName(search[0], x265_motion_est_names, bError);
1366 p->hmeSearchMethod[1] = p->hmeSearchMethod[2] = p->hmeSearchMethod[0];
1367 }
1368 }
1369 p->bEnableHME = true;
1370 }
1371 OPT("hme-range")
1372 {
1373 sscanf(value, "%d,%d,%d", &p->hmeRange[0], &p->hmeRange[1], &p->hmeRange[2]);
1374 p->bEnableHME = true;
1375 }
1376 else
1377 return X265_PARAM_BAD_NAME;
1378 }
1379 #undef OPT
1380 #undef atobool
1381 #undef atoi
1382 #undef atof
1383
1384 bError |= bValueWasNull && !bNameWasBool;
1385 return bError ? X265_PARAM_BAD_VALUE : 0;
1386 }
1387
1388 } /* end extern "C" or namespace */
1389
1390 namespace X265_NS {
1391 // internal encoder functions
1392
x265_atoi(const char * str,bool & bError)1393 int x265_atoi(const char* str, bool& bError)
1394 {
1395 char *end;
1396 int v = strtol(str, &end, 0);
1397
1398 if (end == str || *end != '\0')
1399 bError = true;
1400 return v;
1401 }
1402
x265_atof(const char * str,bool & bError)1403 double x265_atof(const char* str, bool& bError)
1404 {
1405 char *end;
1406 double v = strtod(str, &end);
1407
1408 if (end == str || *end != '\0')
1409 bError = true;
1410 return v;
1411 }
1412
1413 /* cpu name can be:
1414 * auto || true - x265::cpu_detect()
1415 * false || no - disabled
1416 * integer bitmap value
1417 * comma separated list of SIMD names, eg: SSE4.1,XOP */
parseCpuName(const char * value,bool & bError,bool bEnableavx512)1418 int parseCpuName(const char* value, bool& bError, bool bEnableavx512)
1419 {
1420 if (!value)
1421 {
1422 bError = 1;
1423 return 0;
1424 }
1425 int cpu;
1426 if (isdigit(value[0]))
1427 cpu = x265_atoi(value, bError);
1428 else
1429 cpu = !strcmp(value, "auto") || x265_atobool(value, bError) ? X265_NS::cpu_detect(bEnableavx512) : 0;
1430
1431 if (bError)
1432 {
1433 char *buf = strdup(value);
1434 char *tok, *saveptr = NULL, *init;
1435 bError = 0;
1436 cpu = 0;
1437 for (init = buf; (tok = strtok_r(init, ",", &saveptr)); init = NULL)
1438 {
1439 int i;
1440 for (i = 0; X265_NS::cpu_names[i].flags && strcasecmp(tok, X265_NS::cpu_names[i].name); i++)
1441 {
1442 }
1443
1444 cpu |= X265_NS::cpu_names[i].flags;
1445 if (!X265_NS::cpu_names[i].flags)
1446 bError = 1;
1447 }
1448
1449 free(buf);
1450 if ((cpu & X265_CPU_SSSE3) && !(cpu & X265_CPU_SSE2_IS_SLOW))
1451 cpu |= X265_CPU_SSE2_IS_FAST;
1452 }
1453
1454 return cpu;
1455 }
1456
1457 static const int fixedRatios[][2] =
1458 {
1459 { 1, 1 },
1460 { 12, 11 },
1461 { 10, 11 },
1462 { 16, 11 },
1463 { 40, 33 },
1464 { 24, 11 },
1465 { 20, 11 },
1466 { 32, 11 },
1467 { 80, 33 },
1468 { 18, 11 },
1469 { 15, 11 },
1470 { 64, 33 },
1471 { 160, 99 },
1472 { 4, 3 },
1473 { 3, 2 },
1474 { 2, 1 },
1475 };
1476
setParamAspectRatio(x265_param * p,int width,int height)1477 void setParamAspectRatio(x265_param* p, int width, int height)
1478 {
1479 p->vui.aspectRatioIdc = X265_EXTENDED_SAR;
1480 p->vui.sarWidth = width;
1481 p->vui.sarHeight = height;
1482 for (size_t i = 0; i < sizeof(fixedRatios) / sizeof(fixedRatios[0]); i++)
1483 {
1484 if (width == fixedRatios[i][0] && height == fixedRatios[i][1])
1485 {
1486 p->vui.aspectRatioIdc = (int)i + 1;
1487 return;
1488 }
1489 }
1490 }
1491
getParamAspectRatio(x265_param * p,int & width,int & height)1492 void getParamAspectRatio(x265_param* p, int& width, int& height)
1493 {
1494 if (!p->vui.aspectRatioIdc)
1495 width = height = 0;
1496 else if ((size_t)p->vui.aspectRatioIdc <= sizeof(fixedRatios) / sizeof(fixedRatios[0]))
1497 {
1498 width = fixedRatios[p->vui.aspectRatioIdc - 1][0];
1499 height = fixedRatios[p->vui.aspectRatioIdc - 1][1];
1500 }
1501 else if (p->vui.aspectRatioIdc == X265_EXTENDED_SAR)
1502 {
1503 width = p->vui.sarWidth;
1504 height = p->vui.sarHeight;
1505 }
1506 else
1507 width = height = 0;
1508 }
1509
_confirm(x265_param * param,bool bflag,const char * message)1510 static inline int _confirm(x265_param* param, bool bflag, const char* message)
1511 {
1512 if (!bflag)
1513 return 0;
1514
1515 x265_log(param, X265_LOG_ERROR, "%s\n", message);
1516 return 1;
1517 }
1518
x265_check_params(x265_param * param)1519 int x265_check_params(x265_param* param)
1520 {
1521 #define CHECK(expr, msg) check_failed |= _confirm(param, expr, msg)
1522 int check_failed = 0; /* abort if there is a fatal configuration problem */
1523 CHECK(param->uhdBluray == 1 && (X265_DEPTH != 10 || param->internalCsp != 1 || param->interlaceMode != 0),
1524 "uhd-bd: bit depth, chroma subsample, source picture type must be 10, 4:2:0, progressive");
1525 CHECK(param->maxCUSize != 64 && param->maxCUSize != 32 && param->maxCUSize != 16,
1526 "max cu size must be 16, 32, or 64");
1527 if (check_failed == 1)
1528 return check_failed;
1529
1530 uint32_t maxLog2CUSize = (uint32_t)g_log2Size[param->maxCUSize];
1531 uint32_t tuQTMaxLog2Size = X265_MIN(maxLog2CUSize, 5);
1532 uint32_t tuQTMinLog2Size = 2; //log2(4)
1533
1534 CHECK((param->maxSlices > 1) && !param->bEnableWavefront,
1535 "Multiple-Slices mode must be enable Wavefront Parallel Processing (--wpp)");
1536 CHECK(param->internalBitDepth != X265_DEPTH,
1537 "internalBitDepth must match compiled bit depth");
1538 CHECK(param->minCUSize != 32 && param->minCUSize != 16 && param->minCUSize != 8,
1539 "minimim CU size must be 8, 16 or 32");
1540 CHECK(param->minCUSize > param->maxCUSize,
1541 "min CU size must be less than or equal to max CU size");
1542 CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > QP_MAX_SPEC,
1543 "QP exceeds supported range (-QpBDOffsety to 51)");
1544 CHECK(param->fpsNum == 0 || param->fpsDenom == 0,
1545 "Frame rate numerator and denominator must be specified");
1546 CHECK(param->interlaceMode < 0 || param->interlaceMode > 2,
1547 "Interlace mode must be 0 (progressive) 1 (top-field first) or 2 (bottom field first)");
1548 CHECK(param->searchMethod < 0 || param->searchMethod > X265_FULL_SEARCH,
1549 "Search method is not supported value (0:DIA 1:HEX 2:UMH 3:HM 4:SEA 5:FULL)");
1550 CHECK(param->searchRange < 0,
1551 "Search Range must be more than 0");
1552 CHECK(param->searchRange >= 32768,
1553 "Search Range must be less than 32768");
1554 CHECK(param->subpelRefine > X265_MAX_SUBPEL_LEVEL,
1555 "subme must be less than or equal to X265_MAX_SUBPEL_LEVEL (7)");
1556 CHECK(param->subpelRefine < 0,
1557 "subme must be greater than or equal to 0");
1558 CHECK(param->limitReferences > 3,
1559 "limitReferences must be 0, 1, 2 or 3");
1560 CHECK(param->limitModes > 1,
1561 "limitRectAmp must be 0, 1");
1562 CHECK(param->frameNumThreads < 0 || param->frameNumThreads > X265_MAX_FRAME_THREADS,
1563 "frameNumThreads (--frame-threads) must be [0 .. X265_MAX_FRAME_THREADS)");
1564 CHECK(param->cbQpOffset < -12, "Min. Chroma Cb QP Offset is -12");
1565 CHECK(param->cbQpOffset > 12, "Max. Chroma Cb QP Offset is 12");
1566 CHECK(param->crQpOffset < -12, "Min. Chroma Cr QP Offset is -12");
1567 CHECK(param->crQpOffset > 12, "Max. Chroma Cr QP Offset is 12");
1568
1569 CHECK(tuQTMaxLog2Size > maxLog2CUSize,
1570 "QuadtreeTULog2MaxSize must be log2(maxCUSize) or smaller.");
1571
1572 CHECK(param->tuQTMaxInterDepth < 1 || param->tuQTMaxInterDepth > 4,
1573 "QuadtreeTUMaxDepthInter must be greater than 0 and less than 5");
1574 CHECK(maxLog2CUSize < tuQTMinLog2Size + param->tuQTMaxInterDepth - 1,
1575 "QuadtreeTUMaxDepthInter must be less than or equal to the difference between log2(maxCUSize) and QuadtreeTULog2MinSize plus 1");
1576 CHECK(param->tuQTMaxIntraDepth < 1 || param->tuQTMaxIntraDepth > 4,
1577 "QuadtreeTUMaxDepthIntra must be greater 0 and less than 5");
1578 CHECK(maxLog2CUSize < tuQTMinLog2Size + param->tuQTMaxIntraDepth - 1,
1579 "QuadtreeTUMaxDepthInter must be less than or equal to the difference between log2(maxCUSize) and QuadtreeTULog2MinSize plus 1");
1580 CHECK((param->maxTUSize != 32 && param->maxTUSize != 16 && param->maxTUSize != 8 && param->maxTUSize != 4),
1581 "max TU size must be 4, 8, 16, or 32");
1582 CHECK(param->limitTU > 4, "Invalid limit-tu option, limit-TU must be between 0 and 4");
1583 CHECK(param->maxNumMergeCand < 1, "MaxNumMergeCand must be 1 or greater.");
1584 CHECK(param->maxNumMergeCand > 5, "MaxNumMergeCand must be 5 or smaller.");
1585
1586 CHECK(param->maxNumReferences < 1, "maxNumReferences must be 1 or greater.");
1587 CHECK(param->maxNumReferences > MAX_NUM_REF, "maxNumReferences must be 16 or smaller.");
1588
1589 CHECK(param->sourceWidth < (int)param->maxCUSize || param->sourceHeight < (int)param->maxCUSize,
1590 "Picture size must be at least one CTU");
1591 CHECK(param->internalCsp < X265_CSP_I400 || X265_CSP_I444 < param->internalCsp,
1592 "chroma subsampling must be i400 (4:0:0 monochrome), i420 (4:2:0 default), i422 (4:2:0), i444 (4:4:4)");
1593 CHECK(param->sourceWidth & !!CHROMA_H_SHIFT(param->internalCsp),
1594 "Picture width must be an integer multiple of the specified chroma subsampling");
1595 CHECK(param->sourceHeight & !!CHROMA_V_SHIFT(param->internalCsp),
1596 "Picture height must be an integer multiple of the specified chroma subsampling");
1597
1598 CHECK(param->rc.rateControlMode > X265_RC_CRF || param->rc.rateControlMode < X265_RC_ABR,
1599 "Rate control mode is out of range");
1600 CHECK(param->rdLevel < 1 || param->rdLevel > 6,
1601 "RD Level is out of range");
1602 CHECK(param->rdoqLevel < 0 || param->rdoqLevel > 2,
1603 "RDOQ Level is out of range");
1604 CHECK(param->dynamicRd < 0 || param->dynamicRd > x265_ADAPT_RD_STRENGTH,
1605 "Dynamic RD strength must be between 0 and 4");
1606 CHECK(param->recursionSkipMode > 2 || param->recursionSkipMode < 0,
1607 "Invalid Recursion skip mode. Valid modes 0,1,2");
1608 if (param->recursionSkipMode == EDGE_BASED_RSKIP)
1609 {
1610 CHECK(param->edgeVarThreshold < 0.0f || param->edgeVarThreshold > 1.0f,
1611 "Minimum edge density percentage for a CU should be an integer between 0 to 100");
1612 }
1613 CHECK(param->bframes && param->bframes >= param->lookaheadDepth && !param->rc.bStatRead,
1614 "Lookahead depth must be greater than the max consecutive bframe count");
1615 CHECK(param->bframes < 0,
1616 "bframe count should be greater than zero");
1617 CHECK(param->bframes > X265_BFRAME_MAX,
1618 "max consecutive bframe count must be 16 or smaller");
1619 CHECK(param->lookaheadDepth > X265_LOOKAHEAD_MAX,
1620 "Lookahead depth must be less than 256");
1621 CHECK(param->lookaheadSlices > 16 || param->lookaheadSlices < 0,
1622 "Lookahead slices must between 0 and 16");
1623 CHECK(param->rc.aqMode < X265_AQ_NONE || X265_AQ_EDGE < param->rc.aqMode,
1624 "Aq-Mode is out of range");
1625 CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3,
1626 "Aq-Strength is out of range");
1627 CHECK(param->rc.qpAdaptationRange < 1.0f || param->rc.qpAdaptationRange > 6.0f,
1628 "qp adaptation range is out of range");
1629 CHECK(param->deblockingFilterTCOffset < -6 || param->deblockingFilterTCOffset > 6,
1630 "deblocking filter tC offset must be in the range of -6 to +6");
1631 CHECK(param->deblockingFilterBetaOffset < -6 || param->deblockingFilterBetaOffset > 6,
1632 "deblocking filter Beta offset must be in the range of -6 to +6");
1633 CHECK(param->psyRd < 0 || 5.0 < param->psyRd, "Psy-rd strength must be between 0 and 5.0");
1634 CHECK(param->psyRdoq < 0 || 50.0 < param->psyRdoq, "Psy-rdoq strength must be between 0 and 50.0");
1635 CHECK(param->bEnableWavefront < 0, "WaveFrontSynchro cannot be negative");
1636 CHECK((param->vui.aspectRatioIdc < 0
1637 || param->vui.aspectRatioIdc > 16)
1638 && param->vui.aspectRatioIdc != X265_EXTENDED_SAR,
1639 "Sample Aspect Ratio must be 0-16 or 255");
1640 CHECK(param->vui.aspectRatioIdc == X265_EXTENDED_SAR && param->vui.sarWidth <= 0,
1641 "Sample Aspect Ratio width must be greater than 0");
1642 CHECK(param->vui.aspectRatioIdc == X265_EXTENDED_SAR && param->vui.sarHeight <= 0,
1643 "Sample Aspect Ratio height must be greater than 0");
1644 CHECK(param->vui.videoFormat < 0 || param->vui.videoFormat > 5,
1645 "Video Format must be component,"
1646 " pal, ntsc, secam, mac or undef");
1647 CHECK(param->vui.colorPrimaries < 0
1648 || param->vui.colorPrimaries > 12
1649 || param->vui.colorPrimaries == 3,
1650 "Color Primaries must be undef, bt709, bt470m,"
1651 " bt470bg, smpte170m, smpte240m, film, bt2020, smpte-st-428, smpte-rp-431 or smpte-eg-432");
1652 CHECK(param->vui.transferCharacteristics < 0
1653 || param->vui.transferCharacteristics > 18
1654 || param->vui.transferCharacteristics == 3,
1655 "Transfer Characteristics must be undef, bt709, bt470m, bt470bg,"
1656 " smpte170m, smpte240m, linear, log100, log316, iec61966-2-4, bt1361e,"
1657 " iec61966-2-1, bt2020-10, bt2020-12, smpte-st-2084, smpte-st-428 or arib-std-b67");
1658 CHECK(param->vui.matrixCoeffs < 0
1659 || param->vui.matrixCoeffs > 14
1660 || param->vui.matrixCoeffs == 3,
1661 "Matrix Coefficients must be undef, bt709, fcc, bt470bg, smpte170m,"
1662 " smpte240m, GBR, YCgCo, bt2020nc, bt2020c, smpte-st-2085, chroma-nc, chroma-c or ictcp");
1663 CHECK(param->vui.chromaSampleLocTypeTopField < 0
1664 || param->vui.chromaSampleLocTypeTopField > 5,
1665 "Chroma Sample Location Type Top Field must be 0-5");
1666 CHECK(param->vui.chromaSampleLocTypeBottomField < 0
1667 || param->vui.chromaSampleLocTypeBottomField > 5,
1668 "Chroma Sample Location Type Bottom Field must be 0-5");
1669 CHECK(param->vui.defDispWinLeftOffset < 0,
1670 "Default Display Window Left Offset must be 0 or greater");
1671 CHECK(param->vui.defDispWinRightOffset < 0,
1672 "Default Display Window Right Offset must be 0 or greater");
1673 CHECK(param->vui.defDispWinTopOffset < 0,
1674 "Default Display Window Top Offset must be 0 or greater");
1675 CHECK(param->vui.defDispWinBottomOffset < 0,
1676 "Default Display Window Bottom Offset must be 0 or greater");
1677 CHECK(param->rc.rfConstant < -6 * (param->internalBitDepth - 8) || param->rc.rfConstant > 51,
1678 "Valid quality based range: -qpBDOffsetY to 51");
1679 CHECK(param->rc.rfConstantMax < -6 * (param->internalBitDepth - 8) || param->rc.rfConstantMax > 51,
1680 "Valid quality based range: -qpBDOffsetY to 51");
1681 CHECK(param->rc.rfConstantMin < -6 * (param->internalBitDepth - 8) || param->rc.rfConstantMin > 51,
1682 "Valid quality based range: -qpBDOffsetY to 51");
1683 CHECK(param->bFrameAdaptive < 0 || param->bFrameAdaptive > 2,
1684 "Valid adaptive b scheduling values 0 - none, 1 - fast, 2 - full");
1685 CHECK(param->logLevel<-1 || param->logLevel> X265_LOG_FULL,
1686 "Valid Logging level -1:none 0:error 1:warning 2:info 3:debug 4:full");
1687 CHECK(param->scenecutThreshold < 0,
1688 "scenecutThreshold must be greater than 0");
1689 CHECK(param->scenecutBias < 0 || 100 < param->scenecutBias,
1690 "scenecut-bias must be between 0 and 100");
1691 CHECK(param->edgeTransitionThreshold < 0.0 || 2.0 < param->edgeTransitionThreshold,
1692 "hist-threshold must be between 0.0 and 2.0");
1693 CHECK(param->radl < 0 || param->radl > param->bframes,
1694 "radl must be between 0 and bframes");
1695 CHECK(param->rdPenalty < 0 || param->rdPenalty > 2,
1696 "Valid penalty for 32x32 intra TU in non-I slices. 0:disabled 1:RD-penalty 2:maximum");
1697 CHECK(param->keyframeMax < -1,
1698 "Invalid max IDR period in frames. value should be greater than -1");
1699 CHECK(param->gopLookahead < -1,
1700 "GOP lookahead must be greater than -1");
1701 CHECK(param->decodedPictureHashSEI < 0 || param->decodedPictureHashSEI > 3,
1702 "Invalid hash option. Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum");
1703 CHECK(param->rc.vbvBufferSize < 0,
1704 "Size of the vbv buffer can not be less than zero");
1705 CHECK(param->rc.vbvMaxBitrate < 0,
1706 "Maximum local bit rate can not be less than zero");
1707 CHECK(param->rc.vbvBufferInit < 0,
1708 "Valid initial VBV buffer occupancy must be a fraction 0 - 1, or size in kbits");
1709 CHECK(param->vbvBufferEnd < 0,
1710 "Valid final VBV buffer emptiness must be a fraction 0 - 1, or size in kbits");
1711 CHECK(param->vbvEndFrameAdjust < 0,
1712 "Valid vbv-end-fr-adj must be a fraction 0 - 1");
1713 CHECK(!param->totalFrames && param->vbvEndFrameAdjust,
1714 "vbv-end-fr-adj cannot be enabled when total number of frames is unknown");
1715 CHECK(param->rc.bitrate < 0,
1716 "Target bitrate can not be less than zero");
1717 CHECK(param->rc.qCompress < 0.5 || param->rc.qCompress > 1.0,
1718 "qCompress must be between 0.5 and 1.0");
1719 if (param->noiseReductionIntra)
1720 CHECK(0 > param->noiseReductionIntra || param->noiseReductionIntra > 2000, "Valid noise reduction range 0 - 2000");
1721 if (param->noiseReductionInter)
1722 CHECK(0 > param->noiseReductionInter || param->noiseReductionInter > 2000, "Valid noise reduction range 0 - 2000");
1723 CHECK(param->rc.rateControlMode == X265_RC_CQP && param->rc.bStatRead,
1724 "Constant QP is incompatible with 2pass");
1725 CHECK(param->rc.bStrictCbr && (param->rc.bitrate <= 0 || param->rc.vbvBufferSize <=0),
1726 "Strict-cbr cannot be applied without specifying target bitrate or vbv bufsize");
1727 CHECK(param->analysisSave && (param->analysisSaveReuseLevel < 0 || param->analysisSaveReuseLevel > 10),
1728 "Invalid analysis save refine level. Value must be between 1 and 10 (inclusive)");
1729 CHECK(param->analysisLoad && (param->analysisLoadReuseLevel < 0 || param->analysisLoadReuseLevel > 10),
1730 "Invalid analysis load refine level. Value must be between 1 and 10 (inclusive)");
1731 CHECK(param->analysisLoad && (param->mvRefine < 1 || param->mvRefine > 3),
1732 "Invalid mv refinement level. Value must be between 1 and 3 (inclusive)");
1733 CHECK(param->scaleFactor > 2, "Invalid scale-factor. Supports factor <= 2");
1734 CHECK(param->rc.qpMax < QP_MIN || param->rc.qpMax > QP_MAX_MAX,
1735 "qpmax exceeds supported range (0 to 69)");
1736 CHECK(param->rc.qpMin < QP_MIN || param->rc.qpMin > QP_MAX_MAX,
1737 "qpmin exceeds supported range (0 to 69)");
1738 CHECK(param->log2MaxPocLsb < 4 || param->log2MaxPocLsb > 16,
1739 "Supported range for log2MaxPocLsb is 4 to 16");
1740 CHECK(param->bCTUInfo < 0 || (param->bCTUInfo != 0 && param->bCTUInfo != 1 && param->bCTUInfo != 2 && param->bCTUInfo != 4 && param->bCTUInfo != 6) || param->bCTUInfo > 6,
1741 "Supported values for bCTUInfo are 0, 1, 2, 4, 6");
1742 CHECK(param->interRefine > 3 || param->interRefine < 0,
1743 "Invalid refine-inter value, refine-inter levels 0 to 3 supported");
1744 CHECK(param->intraRefine > 4 || param->intraRefine < 0,
1745 "Invalid refine-intra value, refine-intra levels 0 to 3 supported");
1746 CHECK(param->ctuDistortionRefine < 0 || param->ctuDistortionRefine > 1,
1747 "Invalid refine-ctu-distortion value, must be either 0 or 1");
1748 CHECK(param->maxAUSizeFactor < 0.5 || param->maxAUSizeFactor > 1.0,
1749 "Supported factor for controlling max AU size is from 0.5 to 1");
1750 CHECK((param->dolbyProfile != 0) && (param->dolbyProfile != 50) && (param->dolbyProfile != 81) && (param->dolbyProfile != 82),
1751 "Unsupported Dolby Vision profile, only profile 5, profile 8.1 and profile 8.2 enabled");
1752 CHECK(param->dupThreshold < 1 || 99 < param->dupThreshold,
1753 "Invalid frame-duplication threshold. Value must be between 1 and 99.");
1754 if (param->dolbyProfile)
1755 {
1756 CHECK((param->rc.vbvMaxBitrate <= 0 || param->rc.vbvBufferSize <= 0), "Dolby Vision requires VBV settings to enable HRD.\n");
1757 CHECK((param->internalBitDepth != 10), "Dolby Vision profile - 5, profile - 8.1 and profile - 8.2 is Main10 only\n");
1758 CHECK((param->internalCsp != X265_CSP_I420), "Dolby Vision profile - 5, profile - 8.1 and profile - 8.2 requires YCbCr 4:2:0 color space\n");
1759
1760 if (param->dolbyProfile == 81)
1761 CHECK(!(param->masteringDisplayColorVolume), "Dolby Vision profile - 8.1 requires Mastering display color volume information\n");
1762 }
1763
1764 if (param->bField && param->interlaceMode)
1765 {
1766 CHECK( (param->bFrameAdaptive==0), "Adaptive B-frame decision method should be closed for field feature.\n" );
1767 // to do
1768 }
1769 CHECK(param->selectiveSAO < 0 || param->selectiveSAO > 4,
1770 "Invalid SAO tune level. Value must be between 0 and 4 (inclusive)");
1771 CHECK(param->scenecutWindow < 0 || param->scenecutWindow > 1000,
1772 "Invalid scenecut Window duration. Value must be between 0 and 1000(inclusive)");
1773 CHECK(param->maxQpDelta < 0 || param->maxQpDelta > 10,
1774 "Invalid maxQpDelta value. Value must be between 0 and 10 (inclusive)");
1775 if (param->bEnableHME)
1776 {
1777 for (int level = 0; level < 3; level++)
1778 CHECK(param->hmeRange[level] < 0 || param->hmeRange[level] >= 32768,
1779 "Search Range for HME levels must be between 0 and 32768");
1780 }
1781 #if !X86_64
1782 CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 || param->sourceHeight > 480),
1783 "SEA motion search does not support resolutions greater than 480p in 32 bit build");
1784 #endif
1785
1786 if (param->masteringDisplayColorVolume || param->maxFALL || param->maxCLL)
1787 param->bEmitHDR10SEI = 1;
1788
1789 bool isSingleSEI = (param->bRepeatHeaders
1790 || param->bEmitHRDSEI
1791 || param->bEmitInfoSEI
1792 || param->bEmitHDR10SEI
1793 || param->bEmitIDRRecoverySEI
1794 || !!param->interlaceMode
1795 || param->preferredTransferCharacteristics > 1
1796 || param->toneMapFile
1797 || param->naluFile);
1798
1799 if (!isSingleSEI && param->bSingleSeiNal)
1800 {
1801 param->bSingleSeiNal = 0;
1802 x265_log(param, X265_LOG_WARNING, "None of the SEI messages are enabled. Disabling Single SEI NAL\n");
1803 }
1804 CHECK(param->confWinRightOffset < 0, "Conformance Window Right Offset must be 0 or greater");
1805 CHECK(param->confWinBottomOffset < 0, "Conformance Window Bottom Offset must be 0 or greater");
1806 CHECK(param->decoderVbvMaxRate < 0, "Invalid Decoder Vbv Maxrate. Value can not be less than zero");
1807 return check_failed;
1808 }
1809
x265_param_apply_fastfirstpass(x265_param * param)1810 void x265_param_apply_fastfirstpass(x265_param* param)
1811 {
1812 /* Set faster options in case of turbo firstpass */
1813 if (param->rc.bStatWrite && !param->rc.bStatRead)
1814 {
1815 param->maxNumReferences = 1;
1816 param->maxNumMergeCand = 1;
1817 param->bEnableRectInter = 0;
1818 param->bEnableFastIntra = 1;
1819 param->bEnableAMP = 0;
1820 param->searchMethod = X265_DIA_SEARCH;
1821 param->subpelRefine = X265_MIN(2, param->subpelRefine);
1822 param->bEnableEarlySkip = 1;
1823 param->rdLevel = X265_MIN(2, param->rdLevel);
1824 }
1825 }
1826
appendtool(x265_param * param,char * buf,size_t size,const char * toolstr)1827 static void appendtool(x265_param* param, char* buf, size_t size, const char* toolstr)
1828 {
1829 static const int overhead = (int)strlen("x265 [info]: tools: ");
1830
1831 if (strlen(buf) + strlen(toolstr) + overhead >= size)
1832 {
1833 x265_log(param, X265_LOG_INFO, "tools:%s\n", buf);
1834 sprintf(buf, " %s", toolstr);
1835 }
1836 else
1837 {
1838 strcat(buf, " ");
1839 strcat(buf, toolstr);
1840 }
1841 }
1842
x265_print_params(x265_param * param)1843 void x265_print_params(x265_param* param)
1844 {
1845 if (param->logLevel < X265_LOG_INFO)
1846 return;
1847
1848 if (param->interlaceMode)
1849 x265_log(param, X265_LOG_INFO, "Interlaced field inputs : %s\n", x265_interlace_names[param->interlaceMode]);
1850
1851 x265_log(param, X265_LOG_INFO, "Coding QT: max CU size, min CU size : %d / %d\n", param->maxCUSize, param->minCUSize);
1852
1853 x265_log(param, X265_LOG_INFO, "Residual QT: max TU size, max depth : %d / %d inter / %d intra\n",
1854 param->maxTUSize, param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);
1855
1856 if (param->bEnableHME)
1857 x265_log(param, X265_LOG_INFO, "HME L0,1,2 / range / subpel / merge : %s, %s, %s / %d / %d / %d\n",
1858 x265_motion_est_names[param->hmeSearchMethod[0]], x265_motion_est_names[param->hmeSearchMethod[1]], x265_motion_est_names[param->hmeSearchMethod[2]], param->searchRange, param->subpelRefine, param->maxNumMergeCand);
1859 else
1860 x265_log(param, X265_LOG_INFO, "ME / range / subpel / merge : %s / %d / %d / %d\n",
1861 x265_motion_est_names[param->searchMethod], param->searchRange, param->subpelRefine, param->maxNumMergeCand);
1862
1863 if (param->scenecutThreshold && param->keyframeMax != INT_MAX)
1864 x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut / bias : %d / %d / %d / %.2lf \n",
1865 param->keyframeMin, param->keyframeMax, param->scenecutThreshold, param->scenecutBias * 100);
1866 else if (param->bHistBasedSceneCut && param->keyframeMax != INT_MAX)
1867 x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut / edge threshold : %d / %d / %d / %.2lf\n",
1868 param->keyframeMin, param->keyframeMax, param->bHistBasedSceneCut, param->edgeTransitionThreshold);
1869 else if (param->keyframeMax == INT_MAX)
1870 x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut : disabled\n");
1871
1872 if (param->cbQpOffset || param->crQpOffset)
1873 x265_log(param, X265_LOG_INFO, "Cb/Cr QP Offset : %d / %d\n", param->cbQpOffset, param->crQpOffset);
1874
1875 if (param->rdPenalty)
1876 x265_log(param, X265_LOG_INFO, "Intra 32x32 TU penalty type : %d\n", param->rdPenalty);
1877
1878 x265_log(param, X265_LOG_INFO, "Lookahead / bframes / badapt : %d / %d / %d\n", param->lookaheadDepth, param->bframes, param->bFrameAdaptive);
1879 x265_log(param, X265_LOG_INFO, "b-pyramid / weightp / weightb : %d / %d / %d\n",
1880 param->bBPyramid, param->bEnableWeightedPred, param->bEnableWeightedBiPred);
1881 x265_log(param, X265_LOG_INFO, "References / ref-limit cu / depth : %d / %s / %s\n",
1882 param->maxNumReferences, (param->limitReferences & X265_REF_LIMIT_CU) ? "on" : "off",
1883 (param->limitReferences & X265_REF_LIMIT_DEPTH) ? "on" : "off");
1884
1885 if (param->rc.aqMode)
1886 x265_log(param, X265_LOG_INFO, "AQ: mode / str / qg-size / cu-tree : %d / %0.1f / %d / %d\n", param->rc.aqMode,
1887 param->rc.aqStrength, param->rc.qgSize, param->rc.cuTree);
1888
1889 if (param->bLossless)
1890 x265_log(param, X265_LOG_INFO, "Rate Control : Lossless\n");
1891 else switch (param->rc.rateControlMode)
1892 {
1893 case X265_RC_ABR:
1894 x265_log(param, X265_LOG_INFO, "Rate Control / qCompress : ABR-%d kbps / %0.2f\n", param->rc.bitrate, param->rc.qCompress); break;
1895 case X265_RC_CQP:
1896 x265_log(param, X265_LOG_INFO, "Rate Control : CQP-%d\n", param->rc.qp); break;
1897 case X265_RC_CRF:
1898 x265_log(param, X265_LOG_INFO, "Rate Control / qCompress : CRF-%0.1f / %0.2f\n", param->rc.rfConstant, param->rc.qCompress); break;
1899 }
1900
1901 if (param->rc.vbvBufferSize)
1902 {
1903 if (param->vbvBufferEnd)
1904 x265_log(param, X265_LOG_INFO, "VBV/HRD buffer / max-rate / init / end / fr-adj: %d / %d / %.3f / %.3f / %.3f\n",
1905 param->rc.vbvBufferSize, param->rc.vbvMaxBitrate, param->rc.vbvBufferInit, param->vbvBufferEnd, param->vbvEndFrameAdjust);
1906 else
1907 x265_log(param, X265_LOG_INFO, "VBV/HRD buffer / max-rate / init : %d / %d / %.3f\n",
1908 param->rc.vbvBufferSize, param->rc.vbvMaxBitrate, param->rc.vbvBufferInit);
1909 }
1910
1911 char buf[80] = { 0 };
1912 char tmp[40];
1913 #define TOOLOPT(FLAG, STR) if (FLAG) appendtool(param, buf, sizeof(buf), STR);
1914 #define TOOLVAL(VAL, STR) if (VAL) { sprintf(tmp, STR, VAL); appendtool(param, buf, sizeof(buf), tmp); }
1915 TOOLOPT(param->bEnableRectInter, "rect");
1916 TOOLOPT(param->bEnableAMP, "amp");
1917 TOOLOPT(param->limitModes, "limit-modes");
1918 TOOLVAL(param->rdLevel, "rd=%d");
1919 TOOLVAL(param->dynamicRd, "dynamic-rd=%.2f");
1920 TOOLOPT(param->bSsimRd, "ssim-rd");
1921 TOOLVAL(param->psyRd, "psy-rd=%.2lf");
1922 TOOLVAL(param->rdoqLevel, "rdoq=%d");
1923 TOOLVAL(param->psyRdoq, "psy-rdoq=%.2lf");
1924 TOOLOPT(param->bEnableRdRefine, "rd-refine");
1925 TOOLOPT(param->bEnableEarlySkip, "early-skip");
1926 TOOLVAL(param->recursionSkipMode, "rskip mode=%d");
1927 if (param->recursionSkipMode == EDGE_BASED_RSKIP)
1928 TOOLVAL(param->edgeVarThreshold, "rskip-edge-threshold=%.2f");
1929 TOOLOPT(param->bEnableSplitRdSkip, "splitrd-skip");
1930 TOOLVAL(param->noiseReductionIntra, "nr-intra=%d");
1931 TOOLVAL(param->noiseReductionInter, "nr-inter=%d");
1932 TOOLOPT(param->bEnableTSkipFast, "tskip-fast");
1933 TOOLOPT(!param->bEnableTSkipFast && param->bEnableTransformSkip, "tskip");
1934 TOOLVAL(param->limitTU , "limit-tu=%d");
1935 TOOLOPT(param->bCULossless, "cu-lossless");
1936 TOOLOPT(param->bEnableSignHiding, "signhide");
1937 TOOLOPT(param->bEnableTemporalMvp, "tmvp");
1938 TOOLOPT(param->bEnableConstrainedIntra, "cip");
1939 TOOLOPT(param->bIntraInBFrames, "b-intra");
1940 TOOLOPT(param->bEnableFastIntra, "fast-intra");
1941 TOOLOPT(param->bEnableStrongIntraSmoothing, "strong-intra-smoothing");
1942 TOOLVAL(param->lookaheadSlices, "lslices=%d");
1943 TOOLVAL(param->lookaheadThreads, "lthreads=%d")
1944 TOOLVAL(param->bCTUInfo, "ctu-info=%d");
1945 if (param->bAnalysisType == AVC_INFO)
1946 {
1947 TOOLOPT(param->bAnalysisType, "refine-analysis-type=avc");
1948 }
1949 else if (param->bAnalysisType == HEVC_INFO)
1950 TOOLOPT(param->bAnalysisType, "refine-analysis-type=hevc");
1951 TOOLOPT(param->bDynamicRefine, "dynamic-refine");
1952 if (param->maxSlices > 1)
1953 TOOLVAL(param->maxSlices, "slices=%d");
1954 if (param->bEnableLoopFilter)
1955 {
1956 if (param->deblockingFilterBetaOffset || param->deblockingFilterTCOffset)
1957 {
1958 sprintf(tmp, "deblock(tC=%d:B=%d)", param->deblockingFilterTCOffset, param->deblockingFilterBetaOffset);
1959 appendtool(param, buf, sizeof(buf), tmp);
1960 }
1961 else
1962 TOOLOPT(param->bEnableLoopFilter, "deblock");
1963 }
1964 TOOLOPT(param->bSaoNonDeblocked, "sao-non-deblock");
1965 TOOLOPT(!param->bSaoNonDeblocked && param->bEnableSAO, "sao");
1966 if (param->selectiveSAO && param->selectiveSAO != 4)
1967 TOOLOPT(param->selectiveSAO, "selective-sao");
1968 TOOLOPT(param->rc.bStatWrite, "stats-write");
1969 TOOLOPT(param->rc.bStatRead, "stats-read");
1970 TOOLOPT(param->bSingleSeiNal, "single-sei");
1971 #if ENABLE_HDR10_PLUS
1972 TOOLOPT(param->toneMapFile != NULL, "dhdr10-info");
1973 #endif
1974 x265_log(param, X265_LOG_INFO, "tools:%s\n", buf);
1975 fflush(stderr);
1976 }
1977
x265_param2string(x265_param * p,int padx,int pady)1978 char *x265_param2string(x265_param* p, int padx, int pady)
1979 {
1980 char *buf, *s;
1981 size_t bufSize = 4000 + p->rc.zoneCount * 64;
1982 if (p->numaPools)
1983 bufSize += strlen(p->numaPools);
1984 if (p->masteringDisplayColorVolume)
1985 bufSize += strlen(p->masteringDisplayColorVolume);
1986
1987 buf = s = X265_MALLOC(char, bufSize);
1988 if (!buf)
1989 return NULL;
1990 #define BOOL(param, cliopt) \
1991 s += sprintf(s, " %s", (param) ? cliopt : "no-" cliopt);
1992
1993 s += sprintf(s, "cpuid=%d", p->cpuid);
1994 s += sprintf(s, " frame-threads=%d", p->frameNumThreads);
1995 if (p->numaPools)
1996 s += sprintf(s, " numa-pools=%s", p->numaPools);
1997 BOOL(p->bEnableWavefront, "wpp");
1998 BOOL(p->bDistributeModeAnalysis, "pmode");
1999 BOOL(p->bDistributeMotionEstimation, "pme");
2000 BOOL(p->bEnablePsnr, "psnr");
2001 BOOL(p->bEnableSsim, "ssim");
2002 s += sprintf(s, " log-level=%d", p->logLevel);
2003 if (p->csvfn)
2004 s += sprintf(s, " csv csv-log-level=%d", p->csvLogLevel);
2005 s += sprintf(s, " bitdepth=%d", p->internalBitDepth);
2006 s += sprintf(s, " input-csp=%d", p->internalCsp);
2007 s += sprintf(s, " fps=%u/%u", p->fpsNum, p->fpsDenom);
2008 s += sprintf(s, " input-res=%dx%d", p->sourceWidth - padx, p->sourceHeight - pady);
2009 s += sprintf(s, " interlace=%d", p->interlaceMode);
2010 s += sprintf(s, " total-frames=%d", p->totalFrames);
2011 if (p->chunkStart)
2012 s += sprintf(s, " chunk-start=%d", p->chunkStart);
2013 if (p->chunkEnd)
2014 s += sprintf(s, " chunk-end=%d", p->chunkEnd);
2015 s += sprintf(s, " level-idc=%d", p->levelIdc);
2016 s += sprintf(s, " high-tier=%d", p->bHighTier);
2017 s += sprintf(s, " uhd-bd=%d", p->uhdBluray);
2018 s += sprintf(s, " ref=%d", p->maxNumReferences);
2019 BOOL(p->bAllowNonConformance, "allow-non-conformance");
2020 BOOL(p->bRepeatHeaders, "repeat-headers");
2021 BOOL(p->bAnnexB, "annexb");
2022 BOOL(p->bEnableAccessUnitDelimiters, "aud");
2023 BOOL(p->bEmitHRDSEI, "hrd");
2024 BOOL(p->bEmitInfoSEI, "info");
2025 s += sprintf(s, " hash=%d", p->decodedPictureHashSEI);
2026 BOOL(p->bEnableTemporalSubLayers, "temporal-layers");
2027 BOOL(p->bOpenGOP, "open-gop");
2028 s += sprintf(s, " min-keyint=%d", p->keyframeMin);
2029 s += sprintf(s, " keyint=%d", p->keyframeMax);
2030 s += sprintf(s, " gop-lookahead=%d", p->gopLookahead);
2031 s += sprintf(s, " bframes=%d", p->bframes);
2032 s += sprintf(s, " b-adapt=%d", p->bFrameAdaptive);
2033 BOOL(p->bBPyramid, "b-pyramid");
2034 s += sprintf(s, " bframe-bias=%d", p->bFrameBias);
2035 s += sprintf(s, " rc-lookahead=%d", p->lookaheadDepth);
2036 s += sprintf(s, " lookahead-slices=%d", p->lookaheadSlices);
2037 s += sprintf(s, " scenecut=%d", p->scenecutThreshold);
2038 s += sprintf(s, " hist-scenecut=%d", p->bHistBasedSceneCut);
2039 s += sprintf(s, " radl=%d", p->radl);
2040 BOOL(p->bEnableHRDConcatFlag, "splice");
2041 BOOL(p->bIntraRefresh, "intra-refresh");
2042 s += sprintf(s, " ctu=%d", p->maxCUSize);
2043 s += sprintf(s, " min-cu-size=%d", p->minCUSize);
2044 BOOL(p->bEnableRectInter, "rect");
2045 BOOL(p->bEnableAMP, "amp");
2046 s += sprintf(s, " max-tu-size=%d", p->maxTUSize);
2047 s += sprintf(s, " tu-inter-depth=%d", p->tuQTMaxInterDepth);
2048 s += sprintf(s, " tu-intra-depth=%d", p->tuQTMaxIntraDepth);
2049 s += sprintf(s, " limit-tu=%d", p->limitTU);
2050 s += sprintf(s, " rdoq-level=%d", p->rdoqLevel);
2051 s += sprintf(s, " dynamic-rd=%.2f", p->dynamicRd);
2052 BOOL(p->bSsimRd, "ssim-rd");
2053 BOOL(p->bEnableSignHiding, "signhide");
2054 BOOL(p->bEnableTransformSkip, "tskip");
2055 s += sprintf(s, " nr-intra=%d", p->noiseReductionIntra);
2056 s += sprintf(s, " nr-inter=%d", p->noiseReductionInter);
2057 BOOL(p->bEnableConstrainedIntra, "constrained-intra");
2058 BOOL(p->bEnableStrongIntraSmoothing, "strong-intra-smoothing");
2059 s += sprintf(s, " max-merge=%d", p->maxNumMergeCand);
2060 s += sprintf(s, " limit-refs=%d", p->limitReferences);
2061 BOOL(p->limitModes, "limit-modes");
2062 s += sprintf(s, " me=%d", p->searchMethod);
2063 s += sprintf(s, " subme=%d", p->subpelRefine);
2064 s += sprintf(s, " merange=%d", p->searchRange);
2065 BOOL(p->bEnableTemporalMvp, "temporal-mvp");
2066 BOOL(p->bEnableFrameDuplication, "frame-dup");
2067 if(p->bEnableFrameDuplication)
2068 s += sprintf(s, " dup-threshold=%d", p->dupThreshold);
2069 BOOL(p->bEnableHME, "hme");
2070 if (p->bEnableHME)
2071 {
2072 s += sprintf(s, " Level 0,1,2=%d,%d,%d", p->hmeSearchMethod[0], p->hmeSearchMethod[1], p->hmeSearchMethod[2]);
2073 s += sprintf(s, " merange L0,L1,L2=%d,%d,%d", p->hmeRange[0], p->hmeRange[1], p->hmeRange[2]);
2074 }
2075 BOOL(p->bEnableWeightedPred, "weightp");
2076 BOOL(p->bEnableWeightedBiPred, "weightb");
2077 BOOL(p->bSourceReferenceEstimation, "analyze-src-pics");
2078 BOOL(p->bEnableLoopFilter, "deblock");
2079 if (p->bEnableLoopFilter)
2080 s += sprintf(s, "=%d:%d", p->deblockingFilterTCOffset, p->deblockingFilterBetaOffset);
2081 BOOL(p->bEnableSAO, "sao");
2082 BOOL(p->bSaoNonDeblocked, "sao-non-deblock");
2083 s += sprintf(s, " rd=%d", p->rdLevel);
2084 s += sprintf(s, " selective-sao=%d", p->selectiveSAO);
2085 BOOL(p->bEnableEarlySkip, "early-skip");
2086 BOOL(p->recursionSkipMode, "rskip");
2087 if (p->recursionSkipMode == EDGE_BASED_RSKIP)
2088 s += sprintf(s, " rskip-edge-threshold=%f", p->edgeVarThreshold);
2089
2090 BOOL(p->bEnableFastIntra, "fast-intra");
2091 BOOL(p->bEnableTSkipFast, "tskip-fast");
2092 BOOL(p->bCULossless, "cu-lossless");
2093 BOOL(p->bIntraInBFrames, "b-intra");
2094 BOOL(p->bEnableSplitRdSkip, "splitrd-skip");
2095 s += sprintf(s, " rdpenalty=%d", p->rdPenalty);
2096 s += sprintf(s, " psy-rd=%.2f", p->psyRd);
2097 s += sprintf(s, " psy-rdoq=%.2f", p->psyRdoq);
2098 BOOL(p->bEnableRdRefine, "rd-refine");
2099 BOOL(p->bLossless, "lossless");
2100 s += sprintf(s, " cbqpoffs=%d", p->cbQpOffset);
2101 s += sprintf(s, " crqpoffs=%d", p->crQpOffset);
2102 s += sprintf(s, " rc=%s", p->rc.rateControlMode == X265_RC_ABR ? (
2103 p->rc.bitrate == p->rc.vbvMaxBitrate ? "cbr" : "abr")
2104 : p->rc.rateControlMode == X265_RC_CRF ? "crf" : "cqp");
2105 if (p->rc.rateControlMode == X265_RC_ABR || p->rc.rateControlMode == X265_RC_CRF)
2106 {
2107 if (p->rc.rateControlMode == X265_RC_CRF)
2108 s += sprintf(s, " crf=%.1f", p->rc.rfConstant);
2109 else
2110 s += sprintf(s, " bitrate=%d", p->rc.bitrate);
2111 s += sprintf(s, " qcomp=%.2f qpstep=%d", p->rc.qCompress, p->rc.qpStep);
2112 s += sprintf(s, " stats-write=%d", p->rc.bStatWrite);
2113 s += sprintf(s, " stats-read=%d", p->rc.bStatRead);
2114 if (p->rc.bStatRead)
2115 s += sprintf(s, " cplxblur=%.1f qblur=%.1f",
2116 p->rc.complexityBlur, p->rc.qblur);
2117 if (p->rc.bStatWrite && !p->rc.bStatRead)
2118 BOOL(p->rc.bEnableSlowFirstPass, "slow-firstpass");
2119 if (p->rc.vbvBufferSize)
2120 {
2121 s += sprintf(s, " vbv-maxrate=%d vbv-bufsize=%d vbv-init=%.1f",
2122 p->rc.vbvMaxBitrate, p->rc.vbvBufferSize, p->rc.vbvBufferInit);
2123 if (p->vbvBufferEnd)
2124 s += sprintf(s, " vbv-end=%.1f vbv-end-fr-adj=%.1f", p->vbvBufferEnd, p->vbvEndFrameAdjust);
2125 if (p->rc.rateControlMode == X265_RC_CRF)
2126 s += sprintf(s, " crf-max=%.1f crf-min=%.1f", p->rc.rfConstantMax, p->rc.rfConstantMin);
2127 }
2128 }
2129 else if (p->rc.rateControlMode == X265_RC_CQP)
2130 s += sprintf(s, " qp=%d", p->rc.qp);
2131 if (!(p->rc.rateControlMode == X265_RC_CQP && p->rc.qp == 0))
2132 {
2133 s += sprintf(s, " ipratio=%.2f", p->rc.ipFactor);
2134 if (p->bframes)
2135 s += sprintf(s, " pbratio=%.2f", p->rc.pbFactor);
2136 }
2137 s += sprintf(s, " aq-mode=%d", p->rc.aqMode);
2138 s += sprintf(s, " aq-strength=%.2f", p->rc.aqStrength);
2139 BOOL(p->rc.cuTree, "cutree");
2140 s += sprintf(s, " zone-count=%d", p->rc.zoneCount);
2141 if (p->rc.zoneCount)
2142 {
2143 for (int i = 0; i < p->rc.zoneCount; ++i)
2144 {
2145 s += sprintf(s, " zones: start-frame=%d end-frame=%d",
2146 p->rc.zones[i].startFrame, p->rc.zones[i].endFrame);
2147 if (p->rc.zones[i].bForceQp)
2148 s += sprintf(s, " qp=%d", p->rc.zones[i].qp);
2149 else
2150 s += sprintf(s, " bitrate-factor=%f", p->rc.zones[i].bitrateFactor);
2151 }
2152 }
2153 BOOL(p->rc.bStrictCbr, "strict-cbr");
2154 s += sprintf(s, " qg-size=%d", p->rc.qgSize);
2155 BOOL(p->rc.bEnableGrain, "rc-grain");
2156 s += sprintf(s, " qpmax=%d qpmin=%d", p->rc.qpMax, p->rc.qpMin);
2157 BOOL(p->rc.bEnableConstVbv, "const-vbv");
2158 s += sprintf(s, " sar=%d", p->vui.aspectRatioIdc);
2159 if (p->vui.aspectRatioIdc == X265_EXTENDED_SAR)
2160 s += sprintf(s, " sar-width : sar-height=%d:%d", p->vui.sarWidth, p->vui.sarHeight);
2161 s += sprintf(s, " overscan=%d", p->vui.bEnableOverscanInfoPresentFlag);
2162 if (p->vui.bEnableOverscanInfoPresentFlag)
2163 s += sprintf(s, " overscan-crop=%d", p->vui.bEnableOverscanAppropriateFlag);
2164 s += sprintf(s, " videoformat=%d", p->vui.videoFormat);
2165 s += sprintf(s, " range=%d", p->vui.bEnableVideoFullRangeFlag);
2166 s += sprintf(s, " colorprim=%d", p->vui.colorPrimaries);
2167 s += sprintf(s, " transfer=%d", p->vui.transferCharacteristics);
2168 s += sprintf(s, " colormatrix=%d", p->vui.matrixCoeffs);
2169 s += sprintf(s, " chromaloc=%d", p->vui.bEnableChromaLocInfoPresentFlag);
2170 if (p->vui.bEnableChromaLocInfoPresentFlag)
2171 s += sprintf(s, " chromaloc-top=%d chromaloc-bottom=%d",
2172 p->vui.chromaSampleLocTypeTopField, p->vui.chromaSampleLocTypeBottomField);
2173 s += sprintf(s, " display-window=%d", p->vui.bEnableDefaultDisplayWindowFlag);
2174 if (p->vui.bEnableDefaultDisplayWindowFlag)
2175 s += sprintf(s, " left=%d top=%d right=%d bottom=%d",
2176 p->vui.defDispWinLeftOffset, p->vui.defDispWinTopOffset,
2177 p->vui.defDispWinRightOffset, p->vui.defDispWinBottomOffset);
2178 if (p->masteringDisplayColorVolume)
2179 s += sprintf(s, " master-display=%s", p->masteringDisplayColorVolume);
2180 if (p->bEmitCLL)
2181 s += sprintf(s, " cll=%hu,%hu", p->maxCLL, p->maxFALL);
2182 s += sprintf(s, " min-luma=%hu", p->minLuma);
2183 s += sprintf(s, " max-luma=%hu", p->maxLuma);
2184 s += sprintf(s, " log2-max-poc-lsb=%d", p->log2MaxPocLsb);
2185 BOOL(p->bEmitVUITimingInfo, "vui-timing-info");
2186 BOOL(p->bEmitVUIHRDInfo, "vui-hrd-info");
2187 s += sprintf(s, " slices=%d", p->maxSlices);
2188 BOOL(p->bOptQpPPS, "opt-qp-pps");
2189 BOOL(p->bOptRefListLengthPPS, "opt-ref-list-length-pps");
2190 BOOL(p->bMultiPassOptRPS, "multi-pass-opt-rps");
2191 s += sprintf(s, " scenecut-bias=%.2f", p->scenecutBias);
2192 s += sprintf(s, " hist-threshold=%.2f", p->edgeTransitionThreshold);
2193 BOOL(p->bOptCUDeltaQP, "opt-cu-delta-qp");
2194 BOOL(p->bAQMotion, "aq-motion");
2195 BOOL(p->bEmitHDR10SEI, "hdr10");
2196 BOOL(p->bHDR10Opt, "hdr10-opt");
2197 BOOL(p->bDhdr10opt, "dhdr10-opt");
2198 BOOL(p->bEmitIDRRecoverySEI, "idr-recovery-sei");
2199 if (p->analysisSave)
2200 s += sprintf(s, " analysis-save");
2201 if (p->analysisLoad)
2202 s += sprintf(s, " analysis-load");
2203 s += sprintf(s, " analysis-reuse-level=%d", p->analysisReuseLevel);
2204 s += sprintf(s, " analysis-save-reuse-level=%d", p->analysisSaveReuseLevel);
2205 s += sprintf(s, " analysis-load-reuse-level=%d", p->analysisLoadReuseLevel);
2206 s += sprintf(s, " scale-factor=%d", p->scaleFactor);
2207 s += sprintf(s, " refine-intra=%d", p->intraRefine);
2208 s += sprintf(s, " refine-inter=%d", p->interRefine);
2209 s += sprintf(s, " refine-mv=%d", p->mvRefine);
2210 s += sprintf(s, " refine-ctu-distortion=%d", p->ctuDistortionRefine);
2211 BOOL(p->bLimitSAO, "limit-sao");
2212 s += sprintf(s, " ctu-info=%d", p->bCTUInfo);
2213 BOOL(p->bLowPassDct, "lowpass-dct");
2214 s += sprintf(s, " refine-analysis-type=%d", p->bAnalysisType);
2215 s += sprintf(s, " copy-pic=%d", p->bCopyPicToFrame);
2216 s += sprintf(s, " max-ausize-factor=%.1f", p->maxAUSizeFactor);
2217 BOOL(p->bDynamicRefine, "dynamic-refine");
2218 BOOL(p->bSingleSeiNal, "single-sei");
2219 BOOL(p->rc.hevcAq, "hevc-aq");
2220 BOOL(p->bEnableSvtHevc, "svt");
2221 BOOL(p->bField, "field");
2222 s += sprintf(s, " qp-adaptation-range=%.2f", p->rc.qpAdaptationRange);
2223 BOOL(p->bEnableSceneCutAwareQp, "scenecut-aware-qp");
2224 if (p->bEnableSceneCutAwareQp)
2225 s += sprintf(s, " scenecut-window=%d max-qp-delta=%d", p->scenecutWindow, p->maxQpDelta);
2226 s += sprintf(s, "conformance-window-offsets right=%d bottom=%d", p->confWinRightOffset, p->confWinBottomOffset);
2227 s += sprintf(s, " decoder-max-rate=%d", p->decoderVbvMaxRate);
2228 #undef BOOL
2229 return buf;
2230 }
2231
parseLambdaFile(x265_param * param)2232 bool parseLambdaFile(x265_param* param)
2233 {
2234 if (!param->rc.lambdaFileName)
2235 return false;
2236
2237 FILE *lfn = x265_fopen(param->rc.lambdaFileName, "r");
2238 if (!lfn)
2239 {
2240 x265_log_file(param, X265_LOG_ERROR, "unable to read lambda file <%s>\n", param->rc.lambdaFileName);
2241 return true;
2242 }
2243
2244 char line[2048];
2245 char *toksave = NULL, *tok = NULL, *buf = NULL;
2246
2247 for (int t = 0; t < 3; t++)
2248 {
2249 double *table = t ? x265_lambda2_tab : x265_lambda_tab;
2250
2251 for (int i = 0; i < QP_MAX_MAX + 1; i++)
2252 {
2253 double value;
2254
2255 do
2256 {
2257 if (!tok)
2258 {
2259 /* consume a line of text file */
2260 if (!fgets(line, sizeof(line), lfn))
2261 {
2262 fclose(lfn);
2263
2264 if (t < 2)
2265 {
2266 x265_log(param, X265_LOG_ERROR, "lambda file is incomplete\n");
2267 return true;
2268 }
2269 else
2270 return false;
2271 }
2272
2273 /* truncate at first hash */
2274 char *hash = strchr(line, '#');
2275 if (hash) *hash = 0;
2276 buf = line;
2277 }
2278
2279 tok = strtok_r(buf, " ,", &toksave);
2280 buf = NULL;
2281 if (tok && sscanf(tok, "%lf", &value) == 1)
2282 break;
2283 }
2284 while (1);
2285
2286 if (t == 2)
2287 {
2288 x265_log(param, X265_LOG_ERROR, "lambda file contains too many values\n");
2289 fclose(lfn);
2290 return true;
2291 }
2292 else
2293 x265_log(param, X265_LOG_DEBUG, "lambda%c[%d] = %lf\n", t ? '2' : ' ', i, value);
2294 table[i] = value;
2295 }
2296 }
2297
2298 fclose(lfn);
2299 return false;
2300 }
2301
x265_copy_params(x265_param * dst,x265_param * src)2302 void x265_copy_params(x265_param* dst, x265_param* src)
2303 {
2304 dst->cpuid = src->cpuid;
2305 dst->frameNumThreads = src->frameNumThreads;
2306 if (src->numaPools) dst->numaPools = strdup(src->numaPools);
2307 else dst->numaPools = NULL;
2308
2309 dst->bEnableWavefront = src->bEnableWavefront;
2310 dst->bDistributeModeAnalysis = src->bDistributeModeAnalysis;
2311 dst->bDistributeMotionEstimation = src->bDistributeMotionEstimation;
2312 dst->bLogCuStats = src->bLogCuStats;
2313 dst->bEnablePsnr = src->bEnablePsnr;
2314 dst->bEnableSsim = src->bEnableSsim;
2315 dst->logLevel = src->logLevel;
2316 dst->csvLogLevel = src->csvLogLevel;
2317 if (src->csvfn) dst->csvfn = strdup(src->csvfn);
2318 else dst->csvfn = NULL;
2319 dst->internalBitDepth = src->internalBitDepth;
2320 dst->sourceBitDepth = src->sourceBitDepth;
2321 dst->internalCsp = src->internalCsp;
2322 dst->fpsNum = src->fpsNum;
2323 dst->fpsDenom = src->fpsDenom;
2324 dst->sourceHeight = src->sourceHeight;
2325 dst->sourceWidth = src->sourceWidth;
2326 dst->interlaceMode = src->interlaceMode;
2327 dst->totalFrames = src->totalFrames;
2328 dst->levelIdc = src->levelIdc;
2329 dst->bHighTier = src->bHighTier;
2330 dst->uhdBluray = src->uhdBluray;
2331 dst->maxNumReferences = src->maxNumReferences;
2332 dst->bAllowNonConformance = src->bAllowNonConformance;
2333 dst->bRepeatHeaders = src->bRepeatHeaders;
2334 dst->bAnnexB = src->bAnnexB;
2335 dst->bEnableAccessUnitDelimiters = src->bEnableAccessUnitDelimiters;
2336 dst->bEmitInfoSEI = src->bEmitInfoSEI;
2337 dst->decodedPictureHashSEI = src->decodedPictureHashSEI;
2338 dst->bEnableTemporalSubLayers = src->bEnableTemporalSubLayers;
2339 dst->bOpenGOP = src->bOpenGOP;
2340 dst->keyframeMax = src->keyframeMax;
2341 dst->keyframeMin = src->keyframeMin;
2342 dst->bframes = src->bframes;
2343 dst->bFrameAdaptive = src->bFrameAdaptive;
2344 dst->bFrameBias = src->bFrameBias;
2345 dst->bBPyramid = src->bBPyramid;
2346 dst->lookaheadDepth = src->lookaheadDepth;
2347 dst->lookaheadSlices = src->lookaheadSlices;
2348 dst->lookaheadThreads = src->lookaheadThreads;
2349 dst->scenecutThreshold = src->scenecutThreshold;
2350 dst->bHistBasedSceneCut = src->bHistBasedSceneCut;
2351 dst->bIntraRefresh = src->bIntraRefresh;
2352 dst->maxCUSize = src->maxCUSize;
2353 dst->minCUSize = src->minCUSize;
2354 dst->bEnableRectInter = src->bEnableRectInter;
2355 dst->bEnableAMP = src->bEnableAMP;
2356 dst->maxTUSize = src->maxTUSize;
2357 dst->tuQTMaxInterDepth = src->tuQTMaxInterDepth;
2358 dst->tuQTMaxIntraDepth = src->tuQTMaxIntraDepth;
2359 dst->limitTU = src->limitTU;
2360 dst->rdoqLevel = src->rdoqLevel;
2361 dst->bEnableSignHiding = src->bEnableSignHiding;
2362 dst->bEnableTransformSkip = src->bEnableTransformSkip;
2363 dst->noiseReductionInter = src->noiseReductionInter;
2364 dst->noiseReductionIntra = src->noiseReductionIntra;
2365 if (src->scalingLists) dst->scalingLists = strdup(src->scalingLists);
2366 else dst->scalingLists = NULL;
2367 dst->bEnableStrongIntraSmoothing = src->bEnableStrongIntraSmoothing;
2368 dst->bEnableConstrainedIntra = src->bEnableConstrainedIntra;
2369 dst->maxNumMergeCand = src->maxNumMergeCand;
2370 dst->limitReferences = src->limitReferences;
2371 dst->limitModes = src->limitModes;
2372 dst->searchMethod = src->searchMethod;
2373 dst->subpelRefine = src->subpelRefine;
2374 dst->searchRange = src->searchRange;
2375 dst->bEnableTemporalMvp = src->bEnableTemporalMvp;
2376 dst->bEnableFrameDuplication = src->bEnableFrameDuplication;
2377 dst->dupThreshold = src->dupThreshold;
2378 dst->bEnableHME = src->bEnableHME;
2379 if (src->bEnableHME)
2380 {
2381 for (int level = 0; level < 3; level++)
2382 {
2383 dst->hmeSearchMethod[level] = src->hmeSearchMethod[level];
2384 dst->hmeRange[level] = src->hmeRange[level];
2385 }
2386 }
2387 dst->bEnableWeightedBiPred = src->bEnableWeightedBiPred;
2388 dst->bEnableWeightedPred = src->bEnableWeightedPred;
2389 dst->bSourceReferenceEstimation = src->bSourceReferenceEstimation;
2390 dst->bEnableLoopFilter = src->bEnableLoopFilter;
2391 dst->deblockingFilterBetaOffset = src->deblockingFilterBetaOffset;
2392 dst->deblockingFilterTCOffset = src->deblockingFilterTCOffset;
2393 dst->bEnableSAO = src->bEnableSAO;
2394 dst->bSaoNonDeblocked = src->bSaoNonDeblocked;
2395 dst->rdLevel = src->rdLevel;
2396 dst->bEnableEarlySkip = src->bEnableEarlySkip;
2397 dst->recursionSkipMode = src->recursionSkipMode;
2398 dst->edgeVarThreshold = src->edgeVarThreshold;
2399 dst->bEnableFastIntra = src->bEnableFastIntra;
2400 dst->bEnableTSkipFast = src->bEnableTSkipFast;
2401 dst->bCULossless = src->bCULossless;
2402 dst->bIntraInBFrames = src->bIntraInBFrames;
2403 dst->rdPenalty = src->rdPenalty;
2404 dst->psyRd = src->psyRd;
2405 dst->psyRdoq = src->psyRdoq;
2406 dst->bEnableRdRefine = src->bEnableRdRefine;
2407 dst->analysisReuseMode = src->analysisReuseMode;
2408 if (src->analysisReuseFileName) dst->analysisReuseFileName=strdup(src->analysisReuseFileName);
2409 else dst->analysisReuseFileName = NULL;
2410 dst->bLossless = src->bLossless;
2411 dst->cbQpOffset = src->cbQpOffset;
2412 dst->crQpOffset = src->crQpOffset;
2413 dst->preferredTransferCharacteristics = src->preferredTransferCharacteristics;
2414 dst->pictureStructure = src->pictureStructure;
2415
2416 dst->rc.rateControlMode = src->rc.rateControlMode;
2417 dst->rc.qp = src->rc.qp;
2418 dst->rc.bitrate = src->rc.bitrate;
2419 dst->rc.qCompress = src->rc.qCompress;
2420 dst->rc.ipFactor = src->rc.ipFactor;
2421 dst->rc.pbFactor = src->rc.pbFactor;
2422 dst->rc.rfConstant = src->rc.rfConstant;
2423 dst->rc.qpStep = src->rc.qpStep;
2424 dst->rc.aqMode = src->rc.aqMode;
2425 dst->rc.aqStrength = src->rc.aqStrength;
2426 dst->rc.vbvBufferSize = src->rc.vbvBufferSize;
2427 dst->rc.vbvMaxBitrate = src->rc.vbvMaxBitrate;
2428
2429 dst->rc.vbvBufferInit = src->rc.vbvBufferInit;
2430 dst->rc.cuTree = src->rc.cuTree;
2431 dst->rc.rfConstantMax = src->rc.rfConstantMax;
2432 dst->rc.rfConstantMin = src->rc.rfConstantMin;
2433 dst->rc.bStatWrite = src->rc.bStatWrite;
2434 dst->rc.bStatRead = src->rc.bStatRead;
2435 if (src->rc.statFileName) dst->rc.statFileName=strdup(src->rc.statFileName);
2436 else dst->rc.statFileName = NULL;
2437 dst->rc.qblur = src->rc.qblur;
2438 dst->rc.complexityBlur = src->rc.complexityBlur;
2439 dst->rc.bEnableSlowFirstPass = src->rc.bEnableSlowFirstPass;
2440 dst->rc.zoneCount = src->rc.zoneCount;
2441 dst->rc.zonefileCount = src->rc.zonefileCount;
2442 dst->reconfigWindowSize = src->reconfigWindowSize;
2443 dst->bResetZoneConfig = src->bResetZoneConfig;
2444 dst->decoderVbvMaxRate = src->decoderVbvMaxRate;
2445
2446 if (src->rc.zonefileCount && src->rc.zones && src->bResetZoneConfig)
2447 {
2448 for (int i = 0; i < src->rc.zonefileCount; i++)
2449 {
2450 dst->rc.zones[i].startFrame = src->rc.zones[i].startFrame;
2451 memcpy(dst->rc.zones[i].zoneParam, src->rc.zones[i].zoneParam, sizeof(x265_param));
2452 }
2453 }
2454 else if (src->rc.zoneCount && src->rc.zones)
2455 {
2456 for (int i = 0; i < src->rc.zoneCount; i++)
2457 {
2458 dst->rc.zones[i].startFrame = src->rc.zones[i].startFrame;
2459 dst->rc.zones[i].endFrame = src->rc.zones[i].endFrame;
2460 dst->rc.zones[i].bForceQp = src->rc.zones[i].bForceQp;
2461 dst->rc.zones[i].qp = src->rc.zones[i].qp;
2462 dst->rc.zones[i].bitrateFactor = src->rc.zones[i].bitrateFactor;
2463 }
2464 }
2465 else
2466 dst->rc.zones = NULL;
2467
2468 if (src->rc.lambdaFileName) dst->rc.lambdaFileName = strdup(src->rc.lambdaFileName);
2469 else dst->rc.lambdaFileName = NULL;
2470 dst->rc.bStrictCbr = src->rc.bStrictCbr;
2471 dst->rc.qgSize = src->rc.qgSize;
2472 dst->rc.bEnableGrain = src->rc.bEnableGrain;
2473 dst->rc.qpMax = src->rc.qpMax;
2474 dst->rc.qpMin = src->rc.qpMin;
2475 dst->rc.bEnableConstVbv = src->rc.bEnableConstVbv;
2476 dst->rc.hevcAq = src->rc.hevcAq;
2477 dst->rc.qpAdaptationRange = src->rc.qpAdaptationRange;
2478
2479 dst->vui.aspectRatioIdc = src->vui.aspectRatioIdc;
2480 dst->vui.sarWidth = src->vui.sarWidth;
2481 dst->vui.sarHeight = src->vui.sarHeight;
2482 dst->vui.bEnableOverscanAppropriateFlag = src->vui.bEnableOverscanAppropriateFlag;
2483 dst->vui.bEnableOverscanInfoPresentFlag = src->vui.bEnableOverscanInfoPresentFlag;
2484 dst->vui.bEnableVideoSignalTypePresentFlag = src->vui.bEnableVideoSignalTypePresentFlag;
2485 dst->vui.videoFormat = src->vui.videoFormat;
2486 dst->vui.bEnableVideoFullRangeFlag = src->vui.bEnableVideoFullRangeFlag;
2487 dst->vui.bEnableColorDescriptionPresentFlag = src->vui.bEnableColorDescriptionPresentFlag;
2488 dst->vui.colorPrimaries = src->vui.colorPrimaries;
2489 dst->vui.transferCharacteristics = src->vui.transferCharacteristics;
2490 dst->vui.matrixCoeffs = src->vui.matrixCoeffs;
2491 dst->vui.bEnableChromaLocInfoPresentFlag = src->vui.bEnableChromaLocInfoPresentFlag;
2492 dst->vui.chromaSampleLocTypeTopField = src->vui.chromaSampleLocTypeTopField;
2493 dst->vui.chromaSampleLocTypeBottomField = src->vui.chromaSampleLocTypeBottomField;
2494 dst->vui.bEnableDefaultDisplayWindowFlag = src->vui.bEnableDefaultDisplayWindowFlag;
2495 dst->vui.defDispWinBottomOffset = src->vui.defDispWinBottomOffset;
2496 dst->vui.defDispWinLeftOffset = src->vui.defDispWinLeftOffset;
2497 dst->vui.defDispWinRightOffset = src->vui.defDispWinRightOffset;
2498 dst->vui.defDispWinTopOffset = src->vui.defDispWinTopOffset;
2499
2500 if (src->masteringDisplayColorVolume) dst->masteringDisplayColorVolume=strdup( src->masteringDisplayColorVolume);
2501 else dst->masteringDisplayColorVolume = NULL;
2502 dst->maxLuma = src->maxLuma;
2503 dst->minLuma = src->minLuma;
2504 dst->bEmitCLL = src->bEmitCLL;
2505 dst->maxCLL = src->maxCLL;
2506 dst->maxFALL = src->maxFALL;
2507 dst->log2MaxPocLsb = src->log2MaxPocLsb;
2508 dst->bEmitVUIHRDInfo = src->bEmitVUIHRDInfo;
2509 dst->bEmitVUITimingInfo = src->bEmitVUITimingInfo;
2510 dst->maxSlices = src->maxSlices;
2511 dst->bOptQpPPS = src->bOptQpPPS;
2512 dst->bOptRefListLengthPPS = src->bOptRefListLengthPPS;
2513 dst->bMultiPassOptRPS = src->bMultiPassOptRPS;
2514 dst->scenecutBias = src->scenecutBias;
2515 dst->edgeTransitionThreshold = src->edgeTransitionThreshold;
2516 dst->gopLookahead = src->lookaheadDepth;
2517 dst->bOptCUDeltaQP = src->bOptCUDeltaQP;
2518 dst->analysisMultiPassDistortion = src->analysisMultiPassDistortion;
2519 dst->analysisMultiPassRefine = src->analysisMultiPassRefine;
2520 dst->bAQMotion = src->bAQMotion;
2521 dst->bSsimRd = src->bSsimRd;
2522 dst->dynamicRd = src->dynamicRd;
2523 dst->bEmitHDR10SEI = src->bEmitHDR10SEI;
2524 dst->bEmitHRDSEI = src->bEmitHRDSEI;
2525 dst->bHDROpt = src->bHDROpt; /*DEPRECATED*/
2526 dst->bHDR10Opt = src->bHDR10Opt;
2527 dst->analysisReuseLevel = src->analysisReuseLevel;
2528 dst->analysisSaveReuseLevel = src->analysisSaveReuseLevel;
2529 dst->analysisLoadReuseLevel = src->analysisLoadReuseLevel;
2530 dst->bLimitSAO = src->bLimitSAO;
2531 if (src->toneMapFile) dst->toneMapFile = strdup(src->toneMapFile);
2532 else dst->toneMapFile = NULL;
2533 dst->bDhdr10opt = src->bDhdr10opt;
2534 dst->bCTUInfo = src->bCTUInfo;
2535 dst->bUseRcStats = src->bUseRcStats;
2536 dst->interRefine = src->interRefine;
2537 dst->intraRefine = src->intraRefine;
2538 dst->mvRefine = src->mvRefine;
2539 dst->maxLog2CUSize = src->maxLog2CUSize;
2540 dst->maxCUDepth = src->maxCUDepth;
2541 dst->unitSizeDepth = src->unitSizeDepth;
2542 dst->num4x4Partitions = src->num4x4Partitions;
2543
2544 dst->csvfpt = src->csvfpt;
2545 dst->bEnableSplitRdSkip = src->bEnableSplitRdSkip;
2546 dst->bUseAnalysisFile = src->bUseAnalysisFile;
2547 dst->forceFlush = src->forceFlush;
2548 dst->bDisableLookahead = src->bDisableLookahead;
2549 dst->bLowPassDct = src->bLowPassDct;
2550 dst->vbvBufferEnd = src->vbvBufferEnd;
2551 dst->vbvEndFrameAdjust = src->vbvEndFrameAdjust;
2552 dst->bAnalysisType = src->bAnalysisType;
2553 dst->bCopyPicToFrame = src->bCopyPicToFrame;
2554 if (src->analysisSave) dst->analysisSave=strdup(src->analysisSave);
2555 else dst->analysisSave = NULL;
2556 if (src->analysisLoad) dst->analysisLoad=strdup(src->analysisLoad);
2557 else dst->analysisLoad = NULL;
2558 dst->gopLookahead = src->gopLookahead;
2559 dst->radl = src->radl;
2560 dst->selectiveSAO = src->selectiveSAO;
2561 dst->maxAUSizeFactor = src->maxAUSizeFactor;
2562 dst->bEmitIDRRecoverySEI = src->bEmitIDRRecoverySEI;
2563 dst->bDynamicRefine = src->bDynamicRefine;
2564 dst->bSingleSeiNal = src->bSingleSeiNal;
2565 dst->chunkStart = src->chunkStart;
2566 dst->chunkEnd = src->chunkEnd;
2567 if (src->naluFile) dst->naluFile=strdup(src->naluFile);
2568 else dst->naluFile = NULL;
2569 dst->scaleFactor = src->scaleFactor;
2570 dst->ctuDistortionRefine = src->ctuDistortionRefine;
2571 dst->bEnableHRDConcatFlag = src->bEnableHRDConcatFlag;
2572 dst->dolbyProfile = src->dolbyProfile;
2573 dst->bEnableSvtHevc = src->bEnableSvtHevc;
2574 dst->bEnableFades = src->bEnableFades;
2575 dst->bEnableSceneCutAwareQp = src->bEnableSceneCutAwareQp;
2576 dst->scenecutWindow = src->scenecutWindow;
2577 dst->maxQpDelta = src->maxQpDelta;
2578 dst->bField = src->bField;
2579
2580 dst->confWinRightOffset = src->confWinRightOffset;
2581 dst->confWinBottomOffset = src->confWinBottomOffset;
2582 #ifdef SVT_HEVC
2583 memcpy(dst->svtHevcParam, src->svtHevcParam, sizeof(EB_H265_ENC_CONFIGURATION));
2584 #endif
2585 }
2586
2587 #ifdef SVT_HEVC
2588
svt_param_default(x265_param * param)2589 void svt_param_default(x265_param* param)
2590 {
2591 EB_H265_ENC_CONFIGURATION* svtHevcParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
2592
2593 // Channel info
2594 svtHevcParam->channelId = 0;
2595 svtHevcParam->activeChannelCount = 0;
2596
2597 // GOP Structure
2598 svtHevcParam->intraPeriodLength = -2;
2599 svtHevcParam->intraRefreshType = 1;
2600 svtHevcParam->predStructure = 2;
2601 svtHevcParam->baseLayerSwitchMode = 0;
2602 svtHevcParam->hierarchicalLevels = 3;
2603 svtHevcParam->sourceWidth = 0;
2604 svtHevcParam->sourceHeight = 0;
2605 svtHevcParam->latencyMode = 0;
2606
2607 //Preset & Tune
2608 svtHevcParam->encMode = 7;
2609 svtHevcParam->tune = 1;
2610
2611 // Interlaced Video
2612 svtHevcParam->interlacedVideo = 0;
2613
2614 // Quantization
2615 svtHevcParam->qp = 32;
2616 svtHevcParam->useQpFile = 0;
2617
2618 // Deblock Filter
2619 svtHevcParam->disableDlfFlag = 0;
2620
2621 // SAO
2622 svtHevcParam->enableSaoFlag = 1;
2623
2624 // ME Tools
2625 svtHevcParam->useDefaultMeHme = 1;
2626 svtHevcParam->enableHmeFlag = 1;
2627
2628 // ME Parameters
2629 svtHevcParam->searchAreaWidth = 16;
2630 svtHevcParam->searchAreaHeight = 7;
2631
2632 // MD Parameters
2633 svtHevcParam->constrainedIntra = 0;
2634
2635 // Rate Control
2636 svtHevcParam->frameRate = 60;
2637 svtHevcParam->frameRateNumerator = 0;
2638 svtHevcParam->frameRateDenominator = 0;
2639 svtHevcParam->encoderBitDepth = 8;
2640 svtHevcParam->encoderColorFormat = EB_YUV420;
2641 svtHevcParam->compressedTenBitFormat = 0;
2642 svtHevcParam->rateControlMode = 0;
2643 svtHevcParam->sceneChangeDetection = 1;
2644 svtHevcParam->lookAheadDistance = (uint32_t)~0;
2645 svtHevcParam->framesToBeEncoded = 0;
2646 svtHevcParam->targetBitRate = 7000000;
2647 svtHevcParam->maxQpAllowed = 48;
2648 svtHevcParam->minQpAllowed = 10;
2649 svtHevcParam->bitRateReduction = 0;
2650
2651 // Thresholds
2652 svtHevcParam->improveSharpness = 0;
2653 svtHevcParam->videoUsabilityInfo = 0;
2654 svtHevcParam->highDynamicRangeInput = 0;
2655 svtHevcParam->accessUnitDelimiter = 0;
2656 svtHevcParam->bufferingPeriodSEI = 0;
2657 svtHevcParam->pictureTimingSEI = 0;
2658 svtHevcParam->registeredUserDataSeiFlag = 0;
2659 svtHevcParam->unregisteredUserDataSeiFlag = 0;
2660 svtHevcParam->recoveryPointSeiFlag = 0;
2661 svtHevcParam->enableTemporalId = 1;
2662 svtHevcParam->profile = 1;
2663 svtHevcParam->tier = 0;
2664 svtHevcParam->level = 0;
2665
2666 svtHevcParam->injectorFrameRate = 60 << 16;
2667 svtHevcParam->speedControlFlag = 0;
2668
2669 // ASM Type
2670 svtHevcParam->asmType = 1;
2671
2672 svtHevcParam->codeVpsSpsPps = 1;
2673 svtHevcParam->codeEosNal = 0;
2674 svtHevcParam->reconEnabled = 0;
2675 svtHevcParam->maxCLL = 0;
2676 svtHevcParam->maxFALL = 0;
2677 svtHevcParam->useMasteringDisplayColorVolume = 0;
2678 svtHevcParam->useNaluFile = 0;
2679 svtHevcParam->whitePointX = 0;
2680 svtHevcParam->whitePointY = 0;
2681 svtHevcParam->maxDisplayMasteringLuminance = 0;
2682 svtHevcParam->minDisplayMasteringLuminance = 0;
2683 svtHevcParam->dolbyVisionProfile = 0;
2684 svtHevcParam->targetSocket = -1;
2685 svtHevcParam->logicalProcessors = 0;
2686 svtHevcParam->switchThreadsToRtPriority = 1;
2687 svtHevcParam->fpsInVps = 0;
2688
2689 svtHevcParam->tileColumnCount = 1;
2690 svtHevcParam->tileRowCount = 1;
2691 svtHevcParam->tileSliceMode = 0;
2692 svtHevcParam->unrestrictedMotionVector = 1;
2693 svtHevcParam->threadCount = 0;
2694
2695 // vbv
2696 svtHevcParam->hrdFlag = 0;
2697 svtHevcParam->vbvMaxrate = 0;
2698 svtHevcParam->vbvBufsize = 0;
2699 svtHevcParam->vbvBufInit = 90;
2700 }
2701
svt_set_preset(x265_param * param,const char * preset)2702 int svt_set_preset(x265_param* param, const char* preset)
2703 {
2704 EB_H265_ENC_CONFIGURATION* svtHevcParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
2705
2706 if (preset)
2707 {
2708 if (!strcmp(preset, "ultrafast")) svtHevcParam->encMode = 11;
2709 else if (!strcmp(preset, "superfast")) svtHevcParam->encMode = 10;
2710 else if (!strcmp(preset, "veryfast")) svtHevcParam->encMode = 9;
2711 else if (!strcmp(preset, "faster")) svtHevcParam->encMode = 8;
2712 else if (!strcmp(preset, "fast")) svtHevcParam->encMode = 7;
2713 else if (!strcmp(preset, "medium")) svtHevcParam->encMode = 6;
2714 else if (!strcmp(preset, "slow")) svtHevcParam->encMode = 5;
2715 else if (!strcmp(preset, "slower")) svtHevcParam->encMode =4;
2716 else if (!strcmp(preset, "veryslow")) svtHevcParam->encMode = 3;
2717 else if (!strcmp(preset, "placebo")) svtHevcParam->encMode = 2;
2718 else return -1;
2719 }
2720 return 0;
2721 }
2722
svt_param_parse(x265_param * param,const char * name,const char * value)2723 int svt_param_parse(x265_param* param, const char* name, const char* value)
2724 {
2725 bool bError = false;
2726 #define OPT(STR) else if (!strcmp(name, STR))
2727
2728 EB_H265_ENC_CONFIGURATION* svtHevcParam = (EB_H265_ENC_CONFIGURATION*)param->svtHevcParam;
2729 if (0);
2730 OPT("input-res") bError |= sscanf(value, "%dx%d", &svtHevcParam->sourceWidth, &svtHevcParam->sourceHeight) != 2;
2731 OPT("input-depth") svtHevcParam->encoderBitDepth = atoi(value);
2732 OPT("total-frames") svtHevcParam->framesToBeEncoded = atoi(value);
2733 OPT("frames") svtHevcParam->framesToBeEncoded = atoi(value);
2734 OPT("fps")
2735 {
2736 if (sscanf(value, "%u/%u", &svtHevcParam->frameRateNumerator, &svtHevcParam->frameRateDenominator) == 2)
2737 ;
2738 else
2739 {
2740 int fps = atoi(value);
2741 svtHevcParam->frameRateDenominator = 1;
2742
2743 if (fps < 1000)
2744 svtHevcParam->frameRate = fps << 16;
2745 else
2746 svtHevcParam->frameRate = fps;
2747 }
2748 }
2749 OPT2("level-idc", "level")
2750 {
2751 /* allow "5.1" or "51", both converted to integer 51 */
2752 /* if level-idc specifies an obviously wrong value in either float or int,
2753 throw error consistently. Stronger level checking will be done in encoder_open() */
2754 if (atof(value) < 10)
2755 svtHevcParam->level = (int)(10 * atof(value) + .5);
2756 else if (atoi(value) < 100)
2757 svtHevcParam->level = atoi(value);
2758 else
2759 bError = true;
2760 }
2761 OPT2("pools", "numa-pools")
2762 {
2763 char *pools = strdup(value);
2764 char *temp1, *temp2;
2765 int count = 0;
2766
2767 for (temp1 = strstr(pools, ","); temp1 != NULL; temp1 = strstr(temp2, ","))
2768 {
2769 temp2 = ++temp1;
2770 count++;
2771 }
2772
2773 if (count > 1)
2774 x265_log(param, X265_LOG_WARNING, "SVT-HEVC Encoder supports pools option only upto 2 sockets \n");
2775 else if (count == 1)
2776 {
2777 temp1 = strtok(pools, ",");
2778 temp2 = strtok(NULL, ",");
2779
2780 if (!strcmp(temp1, "+"))
2781 {
2782 if (!strcmp(temp2, "+")) svtHevcParam->targetSocket = -1;
2783 else if (!strcmp(temp2, "-")) svtHevcParam->targetSocket = 0;
2784 else svtHevcParam->targetSocket = -1;
2785 }
2786 else if (!strcmp(temp1, "-"))
2787 {
2788 if (!strcmp(temp2, "+")) svtHevcParam->targetSocket = 1;
2789 else if (!strcmp(temp2, "-")) x265_log(param, X265_LOG_ERROR, "Shouldn't exclude both sockets for pools option %s \n", pools);
2790 else if (!strcmp(temp2, "*")) svtHevcParam->targetSocket = 1;
2791 else
2792 {
2793 svtHevcParam->targetSocket = 1;
2794 svtHevcParam->logicalProcessors = atoi(temp2);
2795 }
2796 }
2797 else svtHevcParam->targetSocket = -1;
2798 }
2799 else
2800 {
2801 if (!strcmp(temp1, "*")) svtHevcParam->targetSocket = -1;
2802 else
2803 {
2804 svtHevcParam->targetSocket = 0;
2805 svtHevcParam->logicalProcessors = atoi(temp1);
2806 }
2807 }
2808 }
2809 OPT("high-tier") svtHevcParam->tier = x265_atobool(value, bError);
2810 OPT("qpmin") svtHevcParam->minQpAllowed = atoi(value);
2811 OPT("qpmax") svtHevcParam->maxQpAllowed = atoi(value);
2812 OPT("rc-lookahead") svtHevcParam->lookAheadDistance = atoi(value);
2813 OPT("scenecut")
2814 {
2815 svtHevcParam->sceneChangeDetection = x265_atobool(value, bError);
2816 if (bError || svtHevcParam->sceneChangeDetection)
2817 {
2818 bError = false;
2819 svtHevcParam->sceneChangeDetection = 1;
2820 }
2821 }
2822 OPT("open-gop")
2823 {
2824 if (x265_atobool(value, bError))
2825 svtHevcParam->intraRefreshType = 1;
2826 else
2827 svtHevcParam->intraRefreshType = 2;
2828 }
2829 OPT("deblock")
2830 {
2831 if (strtol(value, NULL, 0))
2832 svtHevcParam->disableDlfFlag = 0;
2833 else if (x265_atobool(value, bError) == 0 && !bError)
2834 svtHevcParam->disableDlfFlag = 1;
2835 }
2836 OPT("sao") svtHevcParam->enableSaoFlag = (uint8_t)x265_atobool(value, bError);
2837 OPT("keyint") svtHevcParam->intraPeriodLength = atoi(value);
2838 OPT2("constrained-intra", "cip") svtHevcParam->constrainedIntra = (uint8_t)x265_atobool(value, bError);
2839 OPT("vui-timing-info") svtHevcParam->videoUsabilityInfo = x265_atobool(value, bError);
2840 OPT("hdr") svtHevcParam->highDynamicRangeInput = x265_atobool(value, bError);
2841 OPT("aud") svtHevcParam->accessUnitDelimiter = x265_atobool(value, bError);
2842 OPT("qp")
2843 {
2844 svtHevcParam->rateControlMode = 0;
2845 svtHevcParam->qp = atoi(value);
2846 }
2847 OPT("bitrate")
2848 {
2849 svtHevcParam->rateControlMode = 1;
2850 svtHevcParam->targetBitRate = atoi(value);
2851 }
2852 OPT("interlace")
2853 {
2854 svtHevcParam->interlacedVideo = (uint8_t)x265_atobool(value, bError);
2855 if (bError || svtHevcParam->interlacedVideo)
2856 {
2857 bError = false;
2858 svtHevcParam->interlacedVideo = 1;
2859 }
2860 }
2861 OPT("svt-hme")
2862 {
2863 svtHevcParam->enableHmeFlag = (uint8_t)x265_atobool(value, bError);
2864 if (svtHevcParam->enableHmeFlag) svtHevcParam->useDefaultMeHme = 1;
2865 }
2866 OPT("svt-search-width") svtHevcParam->searchAreaWidth = atoi(value);
2867 OPT("svt-search-height") svtHevcParam->searchAreaHeight = atoi(value);
2868 OPT("svt-compressed-ten-bit-format") svtHevcParam->compressedTenBitFormat = x265_atobool(value, bError);
2869 OPT("svt-speed-control") svtHevcParam->speedControlFlag = x265_atobool(value, bError);
2870 OPT("svt-preset-tuner")
2871 {
2872 if (svtHevcParam->encMode == 2)
2873 {
2874 if (!strcmp(value, "0")) svtHevcParam->encMode = 0;
2875 else if (!strcmp(value, "1")) svtHevcParam->encMode = 1;
2876 else
2877 {
2878 x265_log(param, X265_LOG_ERROR, " Unsupported value=%s for svt-preset-tuner \n", value);
2879 bError = true;
2880 }
2881 }
2882 else
2883 x265_log(param, X265_LOG_WARNING, " svt-preset-tuner should be used only with ultrafast preset; Ignoring it \n");
2884 }
2885 OPT("svt-hierarchical-level") svtHevcParam->hierarchicalLevels = atoi(value);
2886 OPT("svt-base-layer-switch-mode") svtHevcParam->baseLayerSwitchMode = atoi(value);
2887 OPT("svt-pred-struct") svtHevcParam->predStructure = (uint8_t)atoi(value);
2888 OPT("svt-fps-in-vps") svtHevcParam->fpsInVps = (uint8_t)x265_atobool(value, bError);
2889 OPT("master-display") svtHevcParam->useMasteringDisplayColorVolume = (uint8_t)atoi(value);
2890 OPT("max-cll") bError |= sscanf(value, "%hu,%hu", &svtHevcParam->maxCLL, &svtHevcParam->maxFALL) != 2;
2891 OPT("nalu-file") svtHevcParam->useNaluFile = (uint8_t)atoi(value);
2892 OPT("dolby-vision-profile")
2893 {
2894 if (atof(value) < 10)
2895 svtHevcParam->dolbyVisionProfile = (int)(10 * atof(value) + .5);
2896 else if (atoi(value) < 100)
2897 svtHevcParam->dolbyVisionProfile = atoi(value);
2898 else
2899 bError = true;
2900 }
2901 OPT("hrd")
2902 svtHevcParam->hrdFlag = (uint32_t)x265_atobool(value, bError);
2903 OPT("vbv-maxrate")
2904 svtHevcParam->vbvMaxrate = (uint32_t)x265_atoi(value, bError);
2905 OPT("vbv-bufsize")
2906 svtHevcParam->vbvBufsize = (uint32_t)x265_atoi(value, bError);
2907 OPT("vbv-init")
2908 svtHevcParam->vbvBufInit = (uint64_t)x265_atof(value, bError);
2909 OPT("frame-threads")
2910 svtHevcParam->threadCount = (uint32_t)x265_atoi(value, bError);
2911 else
2912 x265_log(param, X265_LOG_INFO, "SVT doesn't support %s param; Disabling it \n", name);
2913
2914
2915 return bError ? X265_PARAM_BAD_VALUE : 0;
2916 }
2917
2918 #endif //ifdef SVT_HEVC
2919
2920 }
2921