1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Steve Borho <steve@borho.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
25 #pragma warning(disable: 4127) // conditional expression is constant, yes I know
28 #include "input/input.h"
29 #include "output/output.h"
30 #include "filters/filters.h"
37 /* Visual Leak Detector */
53 #define GetConsoleTitle(t, n)
54 #define SetConsoleTitle(t)
59 static const char short_options
[] = "o:p:f:F:r:I:i:b:s:t:q:m:hwV?";
60 static const struct option long_options
[] =
62 { "help", no_argument
, NULL
, 'h' },
63 { "version", no_argument
, NULL
, 'V' },
64 { "asm", required_argument
, NULL
, 0 },
65 { "no-asm", no_argument
, NULL
, 0 },
66 { "threads", required_argument
, NULL
, 0 },
67 { "preset", required_argument
, NULL
, 'p' },
68 { "tune", required_argument
, NULL
, 't' },
69 { "frame-threads", required_argument
, NULL
, 'F' },
70 { "no-pmode", no_argument
, NULL
, 0 },
71 { "pmode", no_argument
, NULL
, 0 },
72 { "no-pme", no_argument
, NULL
, 0 },
73 { "pme", no_argument
, NULL
, 0 },
74 { "log-level", required_argument
, NULL
, 0 },
75 { "profile", required_argument
, NULL
, 0 },
76 { "level-idc", required_argument
, NULL
, 0 },
77 { "high-tier", no_argument
, NULL
, 0 },
78 { "no-high-tier", no_argument
, NULL
, 0 },
79 { "csv", required_argument
, NULL
, 0 },
80 { "no-cu-stats", no_argument
, NULL
, 0 },
81 { "cu-stats", no_argument
, NULL
, 0 },
82 { "y4m", no_argument
, NULL
, 0 },
83 { "no-progress", no_argument
, NULL
, 0 },
84 { "output", required_argument
, NULL
, 'o' },
85 { "input", required_argument
, NULL
, 0 },
86 { "input-depth", required_argument
, NULL
, 0 },
87 { "input-res", required_argument
, NULL
, 0 },
88 { "input-csp", required_argument
, NULL
, 0 },
89 { "interlace", required_argument
, NULL
, 0 },
90 { "no-interlace", no_argument
, NULL
, 0 },
91 { "fps", required_argument
, NULL
, 0 },
92 { "seek", required_argument
, NULL
, 0 },
93 { "frame-skip", required_argument
, NULL
, 0 },
94 { "frames", required_argument
, NULL
, 'f' },
95 { "recon", required_argument
, NULL
, 'r' },
96 { "recon-depth", required_argument
, NULL
, 0 },
97 { "no-wpp", no_argument
, NULL
, 0 },
98 { "wpp", no_argument
, NULL
, 0 },
99 { "ctu", required_argument
, NULL
, 's' },
100 { "tu-intra-depth", required_argument
, NULL
, 0 },
101 { "tu-inter-depth", required_argument
, NULL
, 0 },
102 { "me", required_argument
, NULL
, 0 },
103 { "subme", required_argument
, NULL
, 'm' },
104 { "merange", required_argument
, NULL
, 0 },
105 { "max-merge", required_argument
, NULL
, 0 },
106 { "no-temporal-mvp", no_argument
, NULL
, 0 },
107 { "temporal-mvp", no_argument
, NULL
, 0 },
108 { "rdpenalty", required_argument
, NULL
, 0 },
109 { "no-rect", no_argument
, NULL
, 0 },
110 { "rect", no_argument
, NULL
, 0 },
111 { "no-amp", no_argument
, NULL
, 0 },
112 { "amp", no_argument
, NULL
, 0 },
113 { "no-early-skip", no_argument
, NULL
, 0 },
114 { "early-skip", no_argument
, NULL
, 0 },
115 { "no-fast-cbf", no_argument
, NULL
, 0 },
116 { "fast-cbf", no_argument
, NULL
, 0 },
117 { "no-tskip", no_argument
, NULL
, 0 },
118 { "tskip", no_argument
, NULL
, 0 },
119 { "no-tskip-fast", no_argument
, NULL
, 0 },
120 { "tskip-fast", no_argument
, NULL
, 0 },
121 { "cu-lossless", no_argument
, NULL
, 0 },
122 { "no-cu-lossless", no_argument
, NULL
, 0 },
123 { "no-constrained-intra", no_argument
, NULL
, 0 },
124 { "constrained-intra", no_argument
, NULL
, 0 },
125 { "fast-intra", no_argument
, NULL
, 0 },
126 { "no-fast-intra", no_argument
, NULL
, 0 },
127 { "no-open-gop", no_argument
, NULL
, 0 },
128 { "open-gop", no_argument
, NULL
, 0 },
129 { "keyint", required_argument
, NULL
, 'I' },
130 { "min-keyint", required_argument
, NULL
, 'i' },
131 { "scenecut", required_argument
, NULL
, 0 },
132 { "no-scenecut", no_argument
, NULL
, 0 },
133 { "rc-lookahead", required_argument
, NULL
, 0 },
134 { "bframes", required_argument
, NULL
, 'b' },
135 { "bframe-bias", required_argument
, NULL
, 0 },
136 { "b-adapt", required_argument
, NULL
, 0 },
137 { "no-b-adapt", no_argument
, NULL
, 0 },
138 { "no-b-pyramid", no_argument
, NULL
, 0 },
139 { "b-pyramid", no_argument
, NULL
, 0 },
140 { "ref", required_argument
, NULL
, 0 },
141 { "no-weightp", no_argument
, NULL
, 0 },
142 { "weightp", no_argument
, NULL
, 'w' },
143 { "no-weightb", no_argument
, NULL
, 0 },
144 { "weightb", no_argument
, NULL
, 0 },
145 { "crf", required_argument
, NULL
, 0 },
146 { "crf-max", required_argument
, NULL
, 0 },
147 { "crf-min", required_argument
, NULL
, 0 },
148 { "vbv-maxrate", required_argument
, NULL
, 0 },
149 { "vbv-bufsize", required_argument
, NULL
, 0 },
150 { "vbv-init", required_argument
, NULL
, 0 },
151 { "bitrate", required_argument
, NULL
, 0 },
152 { "qp", required_argument
, NULL
, 'q' },
153 { "aq-mode", required_argument
, NULL
, 0 },
154 { "aq-strength", required_argument
, NULL
, 0 },
155 { "ipratio", required_argument
, NULL
, 0 },
156 { "pbratio", required_argument
, NULL
, 0 },
157 { "qcomp", required_argument
, NULL
, 0 },
158 { "qpstep", required_argument
, NULL
, 0 },
159 { "ratetol", required_argument
, NULL
, 0 },
160 { "cplxblur", required_argument
, NULL
, 0 },
161 { "qblur", required_argument
, NULL
, 0 },
162 { "cbqpoffs", required_argument
, NULL
, 0 },
163 { "crqpoffs", required_argument
, NULL
, 0 },
164 { "rd", required_argument
, NULL
, 0 },
165 { "psy-rd", required_argument
, NULL
, 0 },
166 { "psy-rdoq", required_argument
, NULL
, 0 },
167 { "scaling-list", required_argument
, NULL
, 0 },
168 { "lossless", no_argument
, NULL
, 0 },
169 { "no-lossless", no_argument
, NULL
, 0 },
170 { "no-signhide", no_argument
, NULL
, 0 },
171 { "signhide", no_argument
, NULL
, 0 },
172 { "no-lft", no_argument
, NULL
, 0 }, /* DEPRECATED */
173 { "lft", no_argument
, NULL
, 0 }, /* DEPRECATED */
174 { "no-deblock", no_argument
, NULL
, 0 },
175 { "deblock", required_argument
, NULL
, 0 },
176 { "no-sao", no_argument
, NULL
, 0 },
177 { "sao", no_argument
, NULL
, 0 },
178 { "no-sao-non-deblock", no_argument
, NULL
, 0 },
179 { "sao-non-deblock", no_argument
, NULL
, 0 },
180 { "no-ssim", no_argument
, NULL
, 0 },
181 { "ssim", no_argument
, NULL
, 0 },
182 { "no-psnr", no_argument
, NULL
, 0 },
183 { "psnr", no_argument
, NULL
, 0 },
184 { "hash", required_argument
, NULL
, 0 },
185 { "no-strong-intra-smoothing", no_argument
, NULL
, 0 },
186 { "strong-intra-smoothing", no_argument
, NULL
, 0 },
187 { "no-cutree", no_argument
, NULL
, 0 },
188 { "cutree", no_argument
, NULL
, 0 },
189 { "no-hrd", no_argument
, NULL
, 0 },
190 { "hrd", no_argument
, NULL
, 0 },
191 { "sar", required_argument
, NULL
, 0 },
192 { "overscan", required_argument
, NULL
, 0 },
193 { "videoformat", required_argument
, NULL
, 0 },
194 { "range", required_argument
, NULL
, 0 },
195 { "colorprim", required_argument
, NULL
, 0 },
196 { "transfer", required_argument
, NULL
, 0 },
197 { "colormatrix", required_argument
, NULL
, 0 },
198 { "chromaloc", required_argument
, NULL
, 0 },
199 { "crop-rect", required_argument
, NULL
, 0 },
200 { "no-dither", no_argument
, NULL
, 0 },
201 { "dither", no_argument
, NULL
, 0 },
202 { "no-repeat-headers", no_argument
, NULL
, 0 },
203 { "repeat-headers", no_argument
, NULL
, 0 },
204 { "aud", no_argument
, NULL
, 0 },
205 { "no-aud", no_argument
, NULL
, 0 },
206 { "info", no_argument
, NULL
, 0 },
207 { "no-info", no_argument
, NULL
, 0 },
208 { "qpfile", required_argument
, NULL
, 0 },
209 { "lambda-file", required_argument
, NULL
, 0 },
210 { "b-intra", no_argument
, NULL
, 0 },
211 { "no-b-intra", no_argument
, NULL
, 0 },
212 { "nr-intra", required_argument
, NULL
, 0 },
213 { "nr-inter", required_argument
, NULL
, 0 },
214 { "stats", required_argument
, NULL
, 0 },
215 { "pass", required_argument
, NULL
, 0 },
216 { "slow-firstpass", no_argument
, NULL
, 0 },
217 { "no-slow-firstpass", no_argument
, NULL
, 0 },
218 { "analysis-mode", required_argument
, NULL
, 0 },
219 { "analysis-file", required_argument
, NULL
, 0 },
224 static volatile sig_atomic_t b_ctrl_c
/* = 0 */;
225 static void sigint_handler(int)
234 std::fstream bitstreamFile
;
239 uint32_t seek
; // number of frames to skip from the beginning
240 uint32_t framesToBeEncoded
; // number of frames to encode
242 size_t analysisRecordSize
; // number of bytes read from or dumped into file
243 int analysisHeaderSize
;
246 int64_t prevUpdateTime
;
251 /* in microseconds */
252 static const int UPDATE_INTERVAL
= 250000;
258 framesToBeEncoded
= seek
= 0;
262 startTime
= x265_mdate();
267 analysisRecordSize
= 0;
268 analysisHeaderSize
= 0;
272 void writeNALs(const x265_nal
* nal
, uint32_t nalcount
);
273 void printStatus(uint32_t frameNum
, x265_param
*param
);
274 void printVersion(x265_param
*param
);
275 void showHelp(x265_param
*param
);
276 bool parse(int argc
, char **argv
, x265_param
* param
);
277 bool parseQPFile(x265_picture
&pic_org
);
278 bool validateFanout(x265_param
*);
281 void CLIOptions::destroy()
293 fclose(analysisFile
);
297 void CLIOptions::writeNALs(const x265_nal
* nal
, uint32_t nalcount
)
299 ProfileScopeEvent(bitstreamWrite
);
300 for (uint32_t i
= 0; i
< nalcount
; i
++)
302 bitstreamFile
.write((const char*)nal
->payload
, nal
->sizeBytes
);
303 totalbytes
+= nal
->sizeBytes
;
308 void CLIOptions::printStatus(uint32_t frameNum
, x265_param
*param
)
311 int64_t time
= x265_mdate();
313 if (!bProgress
|| !frameNum
|| (prevUpdateTime
&& time
- prevUpdateTime
< UPDATE_INTERVAL
))
315 int64_t elapsed
= time
- startTime
;
316 double fps
= elapsed
> 0 ? frameNum
* 1000000. / elapsed
: 0;
317 float bitrate
= 0.008f
* totalbytes
* (param
->fpsNum
/ param
->fpsDenom
) / ((float)frameNum
);
318 if (framesToBeEncoded
)
320 int eta
= (int)(elapsed
* (framesToBeEncoded
- frameNum
) / ((int64_t)frameNum
* 1000000));
321 sprintf(buf
, "x265 [%.1f%%] %d/%d frames, %.2f fps, %.2f kb/s, eta %d:%02d:%02d",
322 100. * frameNum
/ framesToBeEncoded
, frameNum
, framesToBeEncoded
, fps
, bitrate
,
323 eta
/ 3600, (eta
/ 60) % 60, eta
% 60);
327 sprintf(buf
, "x265 %d frames: %.2f fps, %.2f kb/s", frameNum
, fps
, bitrate
);
329 fprintf(stderr
, "%s \r", buf
+ 5);
330 SetConsoleTitle(buf
);
331 fflush(stderr
); // needed in windows
332 prevUpdateTime
= time
;
335 void CLIOptions::printVersion(x265_param
*param
)
337 x265_log(param
, X265_LOG_INFO
, "HEVC encoder version %s\n", x265_version_str
);
338 x265_log(param
, X265_LOG_INFO
, "build info %s\n", x265_build_info_str
);
341 void CLIOptions::showHelp(x265_param
*param
)
343 int level
= param
->logLevel
;
344 x265_param_default(param
);
347 #define OPT(value) (value ? "enabled" : "disabled")
349 #define H1 if (level >= X265_LOG_DEBUG) printf
351 H0("\nSyntax: x265 [options] infile [-o] outfile\n");
352 H0(" infile can be YUV or Y4M\n");
353 H0(" outfile is raw HEVC bitstream\n");
354 H0("\nExecutable Options:\n");
355 H0("-h/--help Show this help text and exit\n");
356 H0("-V/--version Show version info and exit\n");
357 H0("\nOutput Options:\n");
358 H0("-o/--output <filename> Bitstream output file name\n");
359 H0(" --log-level <string> Logging level: none error warning info debug full. Default %s\n", logLevelNames
[param
->logLevel
+ 1]);
360 H0(" --no-progress Disable CLI progress reports\n");
361 H0(" --[no-]cu-stats Enable logging stats about distribution of cu across all modes. Default %s\n",OPT(param
->bLogCuStats
));
362 H1(" --csv <filename> Comma separated log file, log level >= 3 frame log, else one line per run\n");
363 H0("\nInput Options:\n");
364 H0(" --input <filename> Raw YUV or Y4M input file name. `-` for stdin\n");
365 H1(" --y4m Force parsing of input stream as YUV4MPEG2 regardless of file extension\n");
366 H0(" --fps <float|rational> Source frame rate (float or num/denom), auto-detected if Y4M\n");
367 H0(" --input-res WxH Source picture size [w x h], auto-detected if Y4M\n");
368 H1(" --input-depth <integer> Bit-depth of input file. Default 8\n");
369 H1(" --input-csp <string> Source color space: i420, i444 or i422, auto-detected if Y4M. Default: i420\n");
370 H0("-f/--frames <integer> Maximum number of frames to encode. Default all\n");
371 H0(" --seek <integer> First frame to encode\n");
372 H1(" --[no-]interlace <bff|tff> Indicate input pictures are interlace fields in temporal order. Default progressive\n");
373 H1(" --dither Enable dither if downscaling to 8 bit pixels. Default disabled\n");
374 H0("\nQuality reporting metrics:\n");
375 H0(" --[no-]ssim Enable reporting SSIM metric scores. Default %s\n", OPT(param
->bEnableSsim
));
376 H0(" --[no-]psnr Enable reporting PSNR metric scores. Default %s\n", OPT(param
->bEnablePsnr
));
377 H0("\nProfile, Level, Tier:\n");
378 H0(" --profile <string> Enforce an encode profile: main, main10, mainstillpicture\n");
379 H0(" --level-idc <integer|float> Force a minumum required decoder level (as '5.0' or '50')\n");
380 H0(" --[no-]high-tier If a decoder level is specified, this modifier selects High tier of that level\n");
381 H0("\nThreading, performance:\n");
382 H0(" --threads <integer> Number of threads for thread pool (0: detect CPU core count, default)\n");
383 H0("-F/--frame-threads <integer> Number of concurrently encoded frames. 0: auto-determined by core count\n");
384 H0(" --[no-]wpp Enable Wavefront Parallel Processing. Default %s\n", OPT(param
->bEnableWavefront
));
385 H0(" --[no-]pmode Parallel mode analysis. Default %s\n", OPT(param
->bDistributeModeAnalysis
));
386 H0(" --[no-]pme Parallel motion estimation. Default %s\n", OPT(param
->bDistributeMotionEstimation
));
387 H0(" --[no-]asm <bool|int|string> Override CPU detection. Default: auto\n");
389 H0("-p/--preset <string> Trade off performance for compression efficiency. Default medium\n");
390 H0(" ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, or placebo\n");
391 H0("-t/--tune <string> Tune the settings for a particular type of source or situation:\n");
392 H0(" psnr, ssim, grain, zerolatency, fastdecode or cbr\n");
393 H0("\nQuad-Tree size and depth:\n");
394 H0("-s/--ctu <64|32|16> Maximum CU size (WxH). Default %d\n", param
->maxCUSize
);
395 H0(" --tu-intra-depth <integer> Max TU recursive depth for intra CUs. Default %d\n", param
->tuQTMaxIntraDepth
);
396 H0(" --tu-inter-depth <integer> Max TU recursive depth for inter CUs. Default %d\n", param
->tuQTMaxInterDepth
);
398 H0(" --rd <0..6> Level of RD in mode decision 0:least....6:full RDO. Default %d\n", param
->rdLevel
);
399 H0(" --psy-rd <0..2.0> Strength of psycho-visual rate distortion optimization, 0 to disable. Default %.1f\n", param
->psyRd
);
400 H0(" --psy-rdoq <0..50.0> Strength of psycho-visual optimization in quantization, 0 to disable. Default %.1f\n", param
->psyRdoq
);
401 H0(" --[no-]early-skip Enable early SKIP detection. Default %s\n", OPT(param
->bEnableEarlySkip
));
402 H1(" --[no-]fast-cbf Enable early outs based on whether residual is coded. Default %s\n", OPT(param
->bEnableCbfFastMode
));
403 H1(" --[no-]tskip-fast Enable fast intra transform skipping. Default %s\n", OPT(param
->bEnableTSkipFast
));
404 H1(" --nr-intra <integer> An integer value in range of 0 to 2000, which denotes strength of noise reduction in intra CUs. Default 0\n");
405 H1(" --nr-inter <integer> An integer value in range of 0 to 2000, which denotes strength of noise reduction in inter CUs. Default 0\n");
406 H0("\nCoding tools:\n");
407 H0("-w/--[no-]weightp Enable weighted prediction in P slices. Default %s\n", OPT(param
->bEnableWeightedPred
));
408 H0(" --[no-]weightb Enable weighted prediction in B slices. Default %s\n", OPT(param
->bEnableWeightedBiPred
));
409 H0(" --[no-]cu-lossless Consider lossless mode in CU RDO decisions. Default %s\n", OPT(param
->bCULossless
));
410 H0(" --[no-]signhide Hide sign bit of one coeff per TU (rdo). Default %s\n", OPT(param
->bEnableSignHiding
));
411 H1(" --[no-]tskip Enable intra 4x4 transform skipping. Default %s\n", OPT(param
->bEnableTransformSkip
));
412 H0("\nTemporal / motion search options:\n");
413 H0(" --me <string> Motion search method dia hex umh star full. Default %d\n", param
->searchMethod
);
414 H0("-m/--subme <integer> Amount of subpel refinement to perform (0:least .. 7:most). Default %d \n", param
->subpelRefine
);
415 H0(" --merange <integer> Motion search range. Default %d\n", param
->searchRange
);
416 H0(" --max-merge <1..5> Maximum number of merge candidates. Default %d\n", param
->maxNumMergeCand
);
417 H0(" --[no-]rect Enable rectangular motion partitions Nx2N and 2NxN. Default %s\n", OPT(param
->bEnableRectInter
));
418 H0(" --[no-]amp Enable asymmetric motion partitions, requires --rect. Default %s\n", OPT(param
->bEnableAMP
));
419 H1(" --[no-]temporal-mvp Enable temporal MV predictors. Default %s\n", OPT(param
->bEnableTemporalMvp
));
420 H0("\nSpatial / intra options:\n");
421 H0(" --[no-]strong-intra-smoothing Enable strong intra smoothing for 32x32 blocks. Default %s\n", OPT(param
->bEnableStrongIntraSmoothing
));
422 H0(" --[no-]constrained-intra Constrained intra prediction (use only intra coded reference pixels) Default %s\n", OPT(param
->bEnableConstrainedIntra
));
423 H0(" --[no-]b-intra Enable intra in B frames in veryslow presets. Default %s\n", OPT(param
->bIntraInBFrames
));
424 H0(" --[no-]fast-intra Enable faster search method for angular intra predictions. Default %s\n", OPT(param
->bEnableFastIntra
));
425 H0(" --rdpenalty <0..2> penalty for 32x32 intra TU in non-I slices. 0:disabled 1:RD-penalty 2:maximum. Default %d\n", param
->rdPenalty
);
426 H0("\nSlice decision options:\n");
427 H0(" --[no-]open-gop Enable open-GOP, allows I slices to be non-IDR. Default %s\n", OPT(param
->bOpenGOP
));
428 H0("-I/--keyint <integer> Max IDR period in frames. -1 for infinite-gop. Default %d\n", param
->keyframeMax
);
429 H0("-i/--min-keyint <integer> Scenecuts closer together than this are coded as I, not IDR. Default: auto\n");
430 H0(" --no-scenecut Disable adaptive I-frame decision\n");
431 H0(" --scenecut <integer> How aggressively to insert extra I-frames. Default %d\n", param
->scenecutThreshold
);
432 H0(" --rc-lookahead <integer> Number of frames for frame-type lookahead (determines encoder latency) Default %d\n", param
->lookaheadDepth
);
433 H0(" --bframes <integer> Maximum number of consecutive b-frames (now it only enables B GOP structure) Default %d\n", param
->bframes
);
434 H1(" --bframe-bias <integer> Bias towards B frame decisions. Default %d\n", param
->bFrameBias
);
435 H0(" --b-adapt <0..2> 0 - none, 1 - fast, 2 - full (trellis) adaptive B frame scheduling. Default %d\n", param
->bFrameAdaptive
);
436 H0(" --[no-]b-pyramid Use B-frames as references. Default %s\n", OPT(param
->bBPyramid
));
437 H0(" --ref <integer> max number of L0 references to be allowed (1 .. 16) Default %d\n", param
->maxNumReferences
);
438 H1(" --qpfile <string> Force frametypes and QPs for some or all frames\n");
439 H1(" Format of each line: framenumber frametype QP\n");
440 H1(" QP is optional (none lets x265 choose). Frametypes: I,i,P,B,b.\n");
441 H1(" QPs are restricted by qpmin/qpmax.\n");
442 H0("\nRate control, Adaptive Quantization:\n");
443 H0(" --bitrate <integer> Target bitrate (kbps) for ABR (implied). Default %d\n", param
->rc
.bitrate
);
444 H1("-q/--qp <integer> QP for P slices in CQP mode (implied). --ipratio and --pbration determine other slice QPs\n");
445 H0(" --crf <float> Quality-based VBR (0-51). Default %.1f\n", param
->rc
.rfConstant
);
446 H1(" --[no-]lossless Enable lossless: bypass transform, quant and loop filters globally. Default %s\n", OPT(param
->bLossless
));
447 H1(" --crf-max <float> With CRF+VBV, limit RF to this value. Default %f\n", param
->rc
.rfConstantMax
);
448 H1(" May cause VBV underflows!\n");
449 H1(" --crf-min <float> With CRF+VBV, limit RF to this value. Default %f\n", param
->rc
.rfConstantMin
);
450 H1(" this specifies a minimum rate factor value for encode!\n");
451 H0(" --vbv-maxrate <integer> Max local bitrate (kbit/s). Default %d\n", param
->rc
.vbvMaxBitrate
);
452 H0(" --vbv-bufsize <integer> Set size of the VBV buffer (kbit). Default %d\n", param
->rc
.vbvBufferSize
);
453 H0(" --vbv-init <float> Initial VBV buffer occupancy (fraction of bufsize or in kbits). Default %.2f\n", param
->rc
.vbvBufferInit
);
454 H0(" --pass Multi pass rate control.\n"
455 " - 1 : First pass, creates stats file\n"
456 " - 2 : Last pass, does not overwrite stats file\n"
457 " - 3 : Nth pass, overwrites stats file\n");
458 H0(" --stats Filename for stats file in multipass pass rate control. Default x265_2pass.log\n");
459 H0(" --[no-]slow-firstpass Enable a slow first pass in a multipass rate control mode. Default %s\n", OPT(param
->rc
.bEnableSlowFirstPass
));
460 H0(" --analysis-mode <string|int> save - Dump analysis info into file, load - Load analysis buffers from the file. Default %d\n", param
->analysisMode
);
461 H0(" --analysis-file <filename> Specify file name used for either dumping or reading analysis data.\n");
462 H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance. Default %d\n", param
->rc
.aqMode
);
463 H0(" --aq-strength <float> Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param
->rc
.aqStrength
);
464 H0(" --[no-]cutree Enable cutree for Adaptive Quantization. Default %s\n", OPT(param
->rc
.cuTree
));
465 H1(" --ipratio <float> QP factor between I and P. Default %.2f\n", param
->rc
.ipFactor
);
466 H1(" --pbratio <float> QP factor between P and B. Default %.2f\n", param
->rc
.pbFactor
);
467 H1(" --qcomp <float> Weight given to predicted complexity. Default %.2f\n", param
->rc
.qCompress
);
468 H1(" --ratetol <float> Degree of rate fluctuation that can be tolerated. Default %.2f\n", param
->rc
.rateTolerance
);
469 H1(" --cbqpoffs <integer> Chroma Cb QP Offset. Default %d\n", param
->cbQpOffset
);
470 H1(" --crqpoffs <integer> Chroma Cr QP Offset. Default %d\n", param
->crQpOffset
);
471 H1(" --scaling-list <string> Specify a file containing HM style quant scaling lists or 'default' or 'off'. Default: off\n");
472 H1(" --lambda-file <string> Specify a file containing replacement values for the lambda tables\n");
473 H1(" MAX_MAX_QP+1 floats for lambda table, then again for lambda2 table\n");
474 H1(" Blank lines and lines starting with hash(#) are ignored\n");
475 H1(" Comma is considered to be white-space\n");
476 H0("\nLoop filters (deblock and SAO):\n");
477 H0(" --[no-]deblock Enable Deblocking Loop Filter, optionally specify tC:Beta offsets Default %s\n", OPT(param
->bEnableLoopFilter
));
478 H0(" --[no-]sao Enable Sample Adaptive Offset. Default %s\n", OPT(param
->bEnableSAO
));
479 H1(" --[no-]sao-non-deblock Use non-deblocked pixels, else right/bottom boundary areas skipped. Default %s\n", OPT(param
->bSaoNonDeblocked
));
480 H0("\nVUI options:\n");
481 H0(" --sar <width:height|int> Sample Aspect Ratio, the ratio of width to height of an individual pixel.\n");
482 H0(" Choose from 0=undef, 1=1:1(\"square\"), 2=12:11, 3=10:11, 4=16:11,\n");
483 H0(" 5=40:33, 6=24:11, 7=20:11, 8=32:11, 9=80:33, 10=18:11, 11=15:11,\n");
484 H0(" 12=64:33, 13=160:99, 14=4:3, 15=3:2, 16=2:1 or custom ratio of <int:int>. Default %d\n", param
->vui
.aspectRatioIdc
);
485 H1(" --crop-rect <string> Add 'left,top,right,bottom' to the bitstream-level cropping rectangle\n");
486 H1(" --overscan <string> Specify whether it is appropriate for decoder to show cropped region: undef, show or crop. Default undef\n");
487 H0(" --videoformat <string> Specify video format from undef, component, pal, ntsc, secam, mac. Default undef\n");
488 H0(" --range <string> Specify black level and range of luma and chroma signals as full or limited Default limited\n");
489 H0(" --colorprim <string> Specify color primaries from undef, bt709, bt470m, bt470bg, smpte170m,\n");
490 H0(" smpte240m, film, bt2020. Default undef\n");
491 H0(" --transfer <string> Specify transfer characteristics from undef, bt709, bt470m, bt470bg, smpte170m,\n");
492 H0(" smpte240m, linear, log100, log316, iec61966-2-4, bt1361e, iec61966-2-1,\n");
493 H0(" bt2020-10, bt2020-12. Default undef\n");
494 H1(" --colormatrix <string> Specify color matrix setting from undef, bt709, fcc, bt470bg, smpte170m,\n");
495 H1(" smpte240m, GBR, YCgCo, bt2020nc, bt2020c. Default undef\n");
496 H1(" --chromaloc <integer> Specify chroma sample location (0 to 5). Default of %d\n", param
->vui
.chromaSampleLocTypeTopField
);
497 H0("\nBitstream options:\n");
498 H0(" --[no-]info Emit SEI identifying encoder and parameters. Default %s\n", OPT(param
->bEmitInfoSEI
));
499 H0(" --[no-]aud Emit access unit delimiters at the start of each access unit. Default %s\n", OPT(param
->bEnableAccessUnitDelimiters
));
500 H0(" --[no-]hrd Enable HRD parameters signaling. Default %s\n", OPT(param
->bEmitHRDSEI
));
501 H0(" --[no-]repeat-headers Emit SPS and PPS headers at each keyframe. Default %s\n", OPT(param
->bRepeatHeaders
));
502 H1(" --hash <integer> Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum. Default %d\n", param
->decodedPictureHashSEI
);
503 H1("\nReconstructed video options (debugging):\n");
504 H1("-r/--recon <filename> Reconstructed raw image YUV or Y4M output file name\n");
505 H1(" --recon-depth <integer> Bit-depth of reconstructed raw image file. Defaults to input bit depth, or 8 if Y4M\n");
510 if (level
< X265_LOG_DEBUG
)
511 printf("\nUse --log-level full --help for a full listing\n");
512 printf("\n\nComplete documentation may be found at http://x265.readthedocs.org/en/default/cli.html\n");
516 bool CLIOptions::parse(int argc
, char **argv
, x265_param
* param
)
520 int inputBitDepth
= 8;
521 int reconFileBitDepth
= 0;
522 const char *inputfn
= NULL
;
523 const char *reconfn
= NULL
;
524 const char *bitstreamfn
= NULL
;
525 const char *preset
= NULL
;
526 const char *tune
= NULL
;
527 const char *profile
= NULL
;
531 x265_log(NULL
, X265_LOG_ERROR
, "No input file. Run x265 --help for a list of options.\n");
535 /* Presets are applied before all other options. */
538 int c
= getopt_long(argc
, argv
, short_options
, long_options
, NULL
);
549 if (x265_param_default_preset(param
, preset
, tune
) < 0)
551 x265_log(NULL
, X265_LOG_ERROR
, "preset or tune unrecognized\n");
557 int long_options_index
= -1;
558 int c
= getopt_long(argc
, argv
, short_options
, long_options
, &long_options_index
);
572 x265_setup_primitives(param
, -1);
576 if (long_options_index
< 0 && c
> 0)
578 for (size_t i
= 0; i
< sizeof(long_options
) / sizeof(long_options
[0]); i
++)
580 if (long_options
[i
].val
== c
)
582 long_options_index
= (int)i
;
587 if (long_options_index
< 0)
589 /* getopt_long might have already printed an error message */
591 x265_log(NULL
, X265_LOG_WARNING
, "internal error: short option '%c' has no long option\n", c
);
595 if (long_options_index
< 0)
597 x265_log(NULL
, X265_LOG_WARNING
, "short option '%c' unrecognized\n", c
);
600 #define OPT(longname) \
601 else if (!strcmp(long_options[long_options_index].name, longname))
602 #define OPT2(name1, name2) \
603 else if (!strcmp(long_options[long_options_index].name, name1) || \
604 !strcmp(long_options[long_options_index].name, name2))
607 OPT2("frame-skip", "seek") this->seek
= (uint32_t)x265_atoi(optarg
, bError
);
608 OPT("frames") this->framesToBeEncoded
= (uint32_t)x265_atoi(optarg
, bError
);
609 OPT("no-progress") this->bProgress
= false;
610 OPT("output") bitstreamfn
= optarg
;
611 OPT("input") inputfn
= optarg
;
612 OPT("recon") reconfn
= optarg
;
613 OPT("input-depth") inputBitDepth
= (uint32_t)x265_atoi(optarg
, bError
);
614 OPT("dither") this->bDither
= true;
615 OPT("recon-depth") reconFileBitDepth
= (uint32_t)x265_atoi(optarg
, bError
);
616 OPT("y4m") this->bForceY4m
= true;
617 OPT("profile") profile
= optarg
; /* handled last */
618 OPT("preset") /* handled above */;
619 OPT("tune") /* handled above */;
622 this->qpfile
= fopen(optarg
, "rb");
625 x265_log(param
, X265_LOG_ERROR
, "%s qpfile not found or error in opening qp file \n", optarg
);
630 bError
|= !!x265_param_parse(param
, long_options
[long_options_index
].name
, optarg
);
634 const char *name
= long_options_index
> 0 ? long_options
[long_options_index
].name
: argv
[optind
- 2];
635 x265_log(NULL
, X265_LOG_ERROR
, "invalid argument: %s = %s\n", name
, optarg
);
642 if (optind
< argc
&& !inputfn
)
643 inputfn
= argv
[optind
++];
644 if (optind
< argc
&& !bitstreamfn
)
645 bitstreamfn
= argv
[optind
++];
648 x265_log(param
, X265_LOG_WARNING
, "extra unused command arguments given <%s>\n", argv
[optind
]);
652 if (argc
<= 1 || help
)
655 if (inputfn
== NULL
|| bitstreamfn
== NULL
)
657 x265_log(param
, X265_LOG_ERROR
, "input or output file not specified, try -V for help\n");
662 if (param
->internalBitDepth
!= 10)
664 x265_log(param
, X265_LOG_ERROR
, "Only bit depths of 10 are supported in this build\n");
668 if (param
->internalBitDepth
!= 8)
670 x265_log(param
, X265_LOG_ERROR
, "Only bit depths of 8 are supported in this build\n");
673 #endif // if HIGH_BIT_DEPTH
676 info
.filename
= inputfn
;
677 info
.depth
= inputBitDepth
;
678 info
.csp
= param
->internalCsp
;
679 info
.width
= param
->sourceWidth
;
680 info
.height
= param
->sourceHeight
;
681 info
.fpsNum
= param
->fpsNum
;
682 info
.fpsDenom
= param
->fpsDenom
;
683 info
.sarWidth
= param
->vui
.sarWidth
;
684 info
.sarHeight
= param
->vui
.sarHeight
;
685 info
.skipFrames
= seek
;
687 getParamAspectRatio(param
, info
.sarWidth
, info
.sarHeight
);
689 this->input
= Input::open(info
, this->bForceY4m
);
690 if (!this->input
|| this->input
->isFail())
692 x265_log(param
, X265_LOG_ERROR
, "unable to open input file <%s>\n", inputfn
);
696 if (info
.depth
< 8 || info
.depth
> 16)
698 x265_log(param
, X265_LOG_ERROR
, "Input bit depth (%d) must be between 8 and 16\n", inputBitDepth
);
702 /* Unconditionally accept height/width/csp from file info */
703 param
->sourceWidth
= info
.width
;
704 param
->sourceHeight
= info
.height
;
705 param
->internalCsp
= info
.csp
;
707 /* Accept fps and sar from file info if not specified by user */
708 if (param
->fpsDenom
== 0 || param
->fpsNum
== 0)
710 param
->fpsDenom
= info
.fpsDenom
;
711 param
->fpsNum
= info
.fpsNum
;
713 if (!param
->vui
.aspectRatioIdc
&& info
.sarWidth
&& info
.sarHeight
)
714 setParamAspectRatio(param
, info
.sarWidth
, info
.sarHeight
);
715 if (this->framesToBeEncoded
== 0 && info
.frameCount
> (int)seek
)
716 this->framesToBeEncoded
= info
.frameCount
- seek
;
717 param
->totalFrames
= this->framesToBeEncoded
;
719 if (x265_param_apply_profile(param
, profile
))
722 if (param
->logLevel
>= X265_LOG_INFO
)
725 int p
= sprintf(buf
, "%dx%d fps %d/%d %sp%d", param
->sourceWidth
, param
->sourceHeight
,
726 param
->fpsNum
, param
->fpsDenom
, x265_source_csp_names
[param
->internalCsp
], info
.depth
);
729 getParamAspectRatio(param
, width
, height
);
731 p
+= sprintf(buf
+ p
, " sar %d:%d", width
, height
);
733 if (framesToBeEncoded
<= 0 || info
.frameCount
<= 0)
734 strcpy(buf
+ p
, " unknown frame count");
736 sprintf(buf
+ p
, " frames %u - %d of %d", this->seek
, this->seek
+ this->framesToBeEncoded
- 1, info
.frameCount
);
738 fprintf(stderr
, "%s [info]: %s\n", input
->getName(), buf
);
741 this->input
->startReader();
745 if (reconFileBitDepth
== 0)
746 reconFileBitDepth
= param
->internalBitDepth
;
747 this->recon
= Output::open(reconfn
, param
->sourceWidth
, param
->sourceHeight
, reconFileBitDepth
,
748 param
->fpsNum
, param
->fpsDenom
, param
->internalCsp
);
749 if (this->recon
->isFail())
751 x265_log(param
, X265_LOG_WARNING
, "unable to write reconstruction file\n");
752 this->recon
->release();
756 fprintf(stderr
, "%s [info]: reconstructed images %dx%d fps %d/%d %s\n", this->recon
->getName(),
757 param
->sourceWidth
, param
->sourceHeight
, param
->fpsNum
, param
->fpsDenom
,
758 x265_source_csp_names
[param
->internalCsp
]);
761 this->bitstreamFile
.open(bitstreamfn
, std::fstream::binary
| std::fstream::out
);
762 if (!this->bitstreamFile
)
764 x265_log(NULL
, X265_LOG_ERROR
, "failed to open bitstream file <%s> for writing\n", bitstreamfn
);
770 bool CLIOptions::parseQPFile(x265_picture
&pic_org
)
772 int32_t num
= -1, qp
, ret
;
776 pic_org
.sliceType
= X265_TYPE_AUTO
;
777 while (num
< pic_org
.poc
)
779 filePos
= ftell(qpfile
);
781 ret
= fscanf(qpfile
, "%d %c%*[ \t]%d\n", &num
, &type
, &qp
);
783 if (num
> pic_org
.poc
|| ret
== EOF
)
785 fseek(qpfile
, filePos
, SEEK_SET
);
788 if (num
< pic_org
.poc
&& ret
>= 2)
790 if (ret
== 3 && qp
>= 0)
791 pic_org
.forceqp
= qp
+ 1;
792 if (type
== 'I') pic_org
.sliceType
= X265_TYPE_IDR
;
793 else if (type
== 'i') pic_org
.sliceType
= X265_TYPE_I
;
794 else if (type
== 'P') pic_org
.sliceType
= X265_TYPE_P
;
795 else if (type
== 'B') pic_org
.sliceType
= X265_TYPE_BREF
;
796 else if (type
== 'b') pic_org
.sliceType
= X265_TYPE_B
;
798 if (ret
< 2 || qp
< -1 || qp
> 51)
804 int main(int argc
, char **argv
)
807 // This uses Microsoft's proprietary WCHAR type, but this only builds on Windows to start with
808 VLDSetReportOptions(VLD_OPT_REPORT_TO_DEBUGGER
| VLD_OPT_REPORT_TO_FILE
, L
"x265_leaks.txt");
812 x265_param
*param
= x265_param_alloc();
815 if (cliopt
.parse(argc
, argv
, param
))
818 x265_param_free(param
);
822 x265_encoder
*encoder
= x265_encoder_open(param
);
825 x265_log(param
, X265_LOG_ERROR
, "failed to open encoder\n");
827 x265_param_free(param
);
832 /* get the encoder parameters post-initialization */
833 x265_encoder_parameters(encoder
, param
);
835 /* Control-C handler */
836 if (signal(SIGINT
, sigint_handler
) == SIG_ERR
)
837 x265_log(param
, X265_LOG_ERROR
, "Unable to register CTRL+C handler: %s\n", strerror(errno
));
839 x265_picture pic_orig
, pic_out
;
840 x265_picture
*pic_in
= &pic_orig
;
841 /* Allocate recon picture if analysisMode is enabled */
842 x265_picture
*pic_recon
= (cliopt
.recon
|| !!param
->analysisMode
) ? &pic_out
: NULL
;
843 uint32_t inFrameCount
= 0;
844 uint32_t outFrameCount
= 0;
848 int16_t *errorBuf
= NULL
;
850 if (!param
->bRepeatHeaders
)
852 if (x265_encoder_headers(encoder
, &p_nal
, &nal
) < 0)
854 x265_log(param
, X265_LOG_ERROR
, "Failure generating stream headers\n");
858 cliopt
.writeNALs(p_nal
, nal
);
861 x265_picture_init(param
, pic_in
);
863 if (param
->analysisMode
)
865 if (param
->bDistributeModeAnalysis
|| param
->bDistributeMotionEstimation
)
867 x265_log(NULL
, X265_LOG_ERROR
, "Analysis load/save options incompatible with pmode/pme");
874 errorBuf
= X265_MALLOC(int16_t, param
->sourceWidth
+ 1);
876 memset(errorBuf
, 0, (param
->sourceWidth
+ 1) * sizeof(int16_t));
878 cliopt
.bDither
= false;
882 while (pic_in
&& !b_ctrl_c
)
884 pic_orig
.poc
= inFrameCount
;
885 if (cliopt
.qpfile
&& !param
->rc
.bStatRead
)
887 if (!cliopt
.parseQPFile(pic_orig
))
889 x265_log(NULL
, X265_LOG_ERROR
, "can't parse qpfile for frame %d\n", pic_in
->poc
);
890 fclose(cliopt
.qpfile
);
891 cliopt
.qpfile
= NULL
;
895 if (cliopt
.framesToBeEncoded
&& inFrameCount
>= cliopt
.framesToBeEncoded
)
897 else if (cliopt
.input
->readPicture(pic_orig
))
904 if (pic_in
->bitDepth
> X265_DEPTH
&& cliopt
.bDither
)
906 ditherImage(*pic_in
, param
->sourceWidth
, param
->sourceHeight
, errorBuf
, X265_DEPTH
);
907 pic_in
->bitDepth
= X265_DEPTH
;
911 int numEncoded
= x265_encoder_encode(encoder
, &p_nal
, &nal
, pic_in
, pic_recon
);
917 outFrameCount
+= numEncoded
;
919 if (numEncoded
&& pic_recon
&& cliopt
.recon
)
920 cliopt
.recon
->writePicture(pic_out
);
922 cliopt
.writeNALs(p_nal
, nal
);
924 // Because x265_encoder_encode() lazily encodes entire GOPs, updates are per-GOP
925 cliopt
.printStatus(outFrameCount
, param
);
928 /* Flush the encoder */
931 uint32_t numEncoded
= x265_encoder_encode(encoder
, &p_nal
, &nal
, NULL
, pic_recon
);
932 outFrameCount
+= numEncoded
;
933 if (numEncoded
&& pic_recon
&& cliopt
.recon
)
934 cliopt
.recon
->writePicture(pic_out
);
936 cliopt
.writeNALs(p_nal
, nal
);
938 cliopt
.printStatus(outFrameCount
, param
);
944 /* clear progress report */
945 if (cliopt
.bProgress
)
946 fprintf(stderr
, "%*s\r", 80, " ");
949 x265_encoder_get_stats(encoder
, &stats
, sizeof(stats
));
950 if (param
->csvfn
&& !b_ctrl_c
)
951 x265_encoder_log(encoder
, argc
, argv
);
952 x265_encoder_close(encoder
);
953 cliopt
.bitstreamFile
.close();
956 fprintf(stderr
, "aborted at input frame %d, output frame %d\n",
957 cliopt
.seek
+ inFrameCount
, stats
.encodedPictureCount
);
959 if (stats
.encodedPictureCount
)
961 printf("\nencoded %d frames in %.2fs (%.2f fps), %.2f kb/s", stats
.encodedPictureCount
,
962 stats
.elapsedEncodeTime
, stats
.encodedPictureCount
/ stats
.elapsedEncodeTime
, stats
.bitrate
);
964 if (param
->bEnablePsnr
)
965 printf(", Global PSNR: %.3f", stats
.globalPsnr
);
967 if (param
->bEnableSsim
)
968 printf(", SSIM Mean Y: %.7f (%6.3f dB)", stats
.globalSsim
, x265_ssim2dB(stats
.globalSsim
));
974 printf("\nencoded 0 frames\n");
977 x265_cleanup(); /* Free library singletons */
981 x265_param_free(param
);
986 assert(VLDReportLeaks() == 0);