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