474cea92eacc462461a1bed4b00806bb75e23c01
[deb_x265.git] / source / x265.cpp
1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
3 *
4 * Authors: Steve Borho <steve@borho.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
19 *
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
23
24 #if _MSC_VER
25 #pragma warning(disable: 4127) // conditional expression is constant, yes I know
26 #endif
27
28 #include "input/input.h"
29 #include "output/output.h"
30 #include "filters/filters.h"
31 #include "common.h"
32 #include "param.h"
33 #include "cpu.h"
34 #include "x265.h"
35
36 #if HAVE_VLD
37 /* Visual Leak Detector */
38 #include <vld.h>
39 #endif
40 #include "PPA/ppa.h"
41
42 #include <signal.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <getopt.h>
46
47 #include <string>
48 #include <ostream>
49 #include <fstream>
50
51 #ifdef _WIN32
52 #include <windows.h>
53 #else
54 #define GetConsoleTitle(t, n)
55 #define SetConsoleTitle(t)
56 #endif
57
58 using namespace x265;
59
60 static const char short_options[] = "o:p:f:F:r:I:i:b:s:t:q:m:hwV?";
61 static const struct option long_options[] =
62 {
63 { "help", no_argument, NULL, 'h' },
64 { "version", no_argument, NULL, 'V' },
65 { "asm", required_argument, NULL, 0 },
66 { "no-asm", no_argument, NULL, 0 },
67 { "threads", required_argument, NULL, 0 },
68 { "preset", required_argument, NULL, 'p' },
69 { "tune", required_argument, NULL, 't' },
70 { "frame-threads", required_argument, NULL, 'F' },
71 { "no-pmode", no_argument, NULL, 0 },
72 { "pmode", no_argument, NULL, 0 },
73 { "no-pme", no_argument, NULL, 0 },
74 { "pme", no_argument, NULL, 0 },
75 { "log-level", required_argument, NULL, 0 },
76 { "profile", required_argument, NULL, 0 },
77 { "level-idc", required_argument, NULL, 0 },
78 { "high-tier", no_argument, NULL, 0 },
79 { "no-high-tier", no_argument, NULL, 0 },
80 { "csv", required_argument, NULL, 0 },
81 { "no-cu-stats", no_argument, NULL, 0 },
82 { "cu-stats", no_argument, NULL, 0 },
83 { "y4m", no_argument, NULL, 0 },
84 { "no-progress", no_argument, NULL, 0 },
85 { "output", required_argument, NULL, 'o' },
86 { "input", required_argument, NULL, 0 },
87 { "input-depth", required_argument, NULL, 0 },
88 { "input-res", required_argument, NULL, 0 },
89 { "input-csp", required_argument, NULL, 0 },
90 { "interlace", required_argument, NULL, 0 },
91 { "no-interlace", no_argument, NULL, 0 },
92 { "fps", required_argument, NULL, 0 },
93 { "seek", required_argument, NULL, 0 },
94 { "frame-skip", required_argument, NULL, 0 },
95 { "frames", required_argument, NULL, 'f' },
96 { "recon", required_argument, NULL, 'r' },
97 { "recon-depth", required_argument, NULL, 0 },
98 { "no-wpp", no_argument, NULL, 0 },
99 { "wpp", no_argument, NULL, 0 },
100 { "ctu", required_argument, NULL, 's' },
101 { "tu-intra-depth", required_argument, NULL, 0 },
102 { "tu-inter-depth", required_argument, NULL, 0 },
103 { "me", required_argument, NULL, 0 },
104 { "subme", required_argument, NULL, 'm' },
105 { "merange", required_argument, NULL, 0 },
106 { "max-merge", required_argument, NULL, 0 },
107 { "no-temporal-mvp", no_argument, NULL, 0 },
108 { "temporal-mvp", no_argument, NULL, 0 },
109 { "rdpenalty", required_argument, NULL, 0 },
110 { "no-rect", no_argument, NULL, 0 },
111 { "rect", no_argument, NULL, 0 },
112 { "no-amp", no_argument, NULL, 0 },
113 { "amp", no_argument, NULL, 0 },
114 { "no-early-skip", no_argument, NULL, 0 },
115 { "early-skip", no_argument, NULL, 0 },
116 { "no-fast-cbf", no_argument, NULL, 0 },
117 { "fast-cbf", no_argument, NULL, 0 },
118 { "no-tskip", no_argument, NULL, 0 },
119 { "tskip", no_argument, NULL, 0 },
120 { "no-tskip-fast", no_argument, NULL, 0 },
121 { "tskip-fast", no_argument, NULL, 0 },
122 { "cu-lossless", no_argument, NULL, 0 },
123 { "no-cu-lossless", no_argument, NULL, 0 },
124 { "no-constrained-intra", no_argument, NULL, 0 },
125 { "constrained-intra", no_argument, NULL, 0 },
126 { "fast-intra", no_argument, NULL, 0 },
127 { "no-fast-intra", no_argument, NULL, 0 },
128 { "no-open-gop", no_argument, NULL, 0 },
129 { "open-gop", no_argument, NULL, 0 },
130 { "keyint", required_argument, NULL, 'I' },
131 { "min-keyint", required_argument, NULL, 'i' },
132 { "scenecut", required_argument, NULL, 0 },
133 { "no-scenecut", no_argument, NULL, 0 },
134 { "rc-lookahead", required_argument, NULL, 0 },
135 { "bframes", required_argument, NULL, 'b' },
136 { "bframe-bias", required_argument, NULL, 0 },
137 { "b-adapt", required_argument, NULL, 0 },
138 { "no-b-adapt", no_argument, NULL, 0 },
139 { "no-b-pyramid", no_argument, NULL, 0 },
140 { "b-pyramid", no_argument, NULL, 0 },
141 { "ref", required_argument, NULL, 0 },
142 { "no-weightp", no_argument, NULL, 0 },
143 { "weightp", no_argument, NULL, 'w' },
144 { "no-weightb", no_argument, NULL, 0 },
145 { "weightb", no_argument, NULL, 0 },
146 { "crf", required_argument, NULL, 0 },
147 { "crf-max", required_argument, NULL, 0 },
148 { "crf-min", required_argument, NULL, 0 },
149 { "vbv-maxrate", required_argument, NULL, 0 },
150 { "vbv-bufsize", required_argument, NULL, 0 },
151 { "vbv-init", required_argument, NULL, 0 },
152 { "bitrate", required_argument, NULL, 0 },
153 { "qp", required_argument, NULL, 'q' },
154 { "aq-mode", required_argument, NULL, 0 },
155 { "aq-strength", required_argument, NULL, 0 },
156 { "ipratio", required_argument, NULL, 0 },
157 { "pbratio", required_argument, NULL, 0 },
158 { "cbqpoffs", required_argument, NULL, 0 },
159 { "crqpoffs", required_argument, NULL, 0 },
160 { "rd", required_argument, NULL, 0 },
161 { "psy-rd", required_argument, NULL, 0 },
162 { "psy-rdoq", required_argument, NULL, 0 },
163 { "scaling-list", required_argument, NULL, 0 },
164 { "lossless", no_argument, NULL, 0 },
165 { "no-lossless", no_argument, NULL, 0 },
166 { "no-signhide", no_argument, NULL, 0 },
167 { "signhide", no_argument, NULL, 0 },
168 { "no-lft", no_argument, NULL, 0 },
169 { "lft", no_argument, NULL, 0 },
170 { "no-sao", no_argument, NULL, 0 },
171 { "sao", no_argument, NULL, 0 },
172 { "no-sao-non-deblock", no_argument, NULL, 0 },
173 { "sao-non-deblock", no_argument, NULL, 0 },
174 { "no-ssim", no_argument, NULL, 0 },
175 { "ssim", no_argument, NULL, 0 },
176 { "no-psnr", no_argument, NULL, 0 },
177 { "psnr", no_argument, NULL, 0 },
178 { "hash", required_argument, NULL, 0 },
179 { "no-strong-intra-smoothing", no_argument, NULL, 0 },
180 { "strong-intra-smoothing", no_argument, NULL, 0 },
181 { "no-cutree", no_argument, NULL, 0 },
182 { "cutree", no_argument, NULL, 0 },
183 { "no-hrd", no_argument, NULL, 0 },
184 { "hrd", no_argument, NULL, 0 },
185 { "sar", required_argument, NULL, 0 },
186 { "overscan", required_argument, NULL, 0 },
187 { "videoformat", required_argument, NULL, 0 },
188 { "range", required_argument, NULL, 0 },
189 { "colorprim", required_argument, NULL, 0 },
190 { "transfer", required_argument, NULL, 0 },
191 { "colormatrix", required_argument, NULL, 0 },
192 { "chromaloc", required_argument, NULL, 0 },
193 { "crop-rect", required_argument, NULL, 0 },
194 { "no-dither", no_argument, NULL, 0 },
195 { "dither", no_argument, NULL, 0 },
196 { "no-repeat-headers", no_argument, NULL, 0 },
197 { "repeat-headers", no_argument, NULL, 0 },
198 { "aud", no_argument, NULL, 0 },
199 { "no-aud", no_argument, NULL, 0 },
200 { "info", no_argument, NULL, 0 },
201 { "no-info", no_argument, NULL, 0 },
202 { "qpfile", required_argument, NULL, 0 },
203 { "lambda-file", required_argument, NULL, 0 },
204 { "b-intra", no_argument, NULL, 0 },
205 { "no-b-intra", no_argument, NULL, 0 },
206 { "nr", required_argument, NULL, 0 },
207 { "stats", required_argument, NULL, 0 },
208 { "pass", required_argument, NULL, 0 },
209 { "slow-firstpass", no_argument, NULL, 0 },
210 { "no-slow-firstpass", no_argument, NULL, 0 },
211 { "analysis-mode", required_argument, NULL, 0 },
212 { "analysis-file", required_argument, NULL, 0 },
213 { 0, 0, 0, 0 }
214 };
215
216 /* Ctrl-C handler */
217 static volatile sig_atomic_t b_ctrl_c /* = 0 */;
218 static void sigint_handler(int)
219 {
220 b_ctrl_c = 1;
221 }
222
223 struct CLIOptions
224 {
225 Input* input;
226 Output* recon;
227 std::fstream bitstreamFile;
228 bool bProgress;
229 bool bForceY4m;
230 bool bDither;
231
232 uint32_t seek; // number of frames to skip from the beginning
233 uint32_t framesToBeEncoded; // number of frames to encode
234 uint64_t totalbytes;
235 size_t analysisRecordSize; // number of bytes read from or dumped into file
236 int analysisHeaderSize;
237
238 int64_t startTime;
239 int64_t prevUpdateTime;
240 float frameRate;
241 FILE* qpfile;
242 FILE* analysisFile;
243
244 /* in microseconds */
245 static const int UPDATE_INTERVAL = 250000;
246
247 CLIOptions()
248 {
249 input = NULL;
250 recon = NULL;
251 framesToBeEncoded = seek = 0;
252 totalbytes = 0;
253 bProgress = true;
254 bForceY4m = false;
255 startTime = x265_mdate();
256 prevUpdateTime = 0;
257 bDither = false;
258 qpfile = NULL;
259 analysisFile = NULL;
260 analysisRecordSize = 0;
261 analysisHeaderSize = 0;
262 }
263
264 void destroy();
265 void writeNALs(const x265_nal* nal, uint32_t nalcount);
266 void printStatus(uint32_t frameNum, x265_param *param);
267 void printVersion(x265_param *param);
268 void showHelp(x265_param *param);
269 bool parse(int argc, char **argv, x265_param* param);
270 bool parseQPFile(x265_picture &pic_org);
271 void readAnalysisFile(x265_picture* pic, x265_param*);
272 void writeAnalysisFile(x265_picture* pic, x265_param*);
273 bool validateFanout(x265_param*);
274 };
275
276 void CLIOptions::destroy()
277 {
278 if (input)
279 input->release();
280 input = NULL;
281 if (recon)
282 recon->release();
283 recon = NULL;
284 if (qpfile)
285 fclose(qpfile);
286 qpfile = NULL;
287 if (analysisFile)
288 fclose(analysisFile);
289 analysisFile = NULL;
290 }
291
292 void CLIOptions::writeNALs(const x265_nal* nal, uint32_t nalcount)
293 {
294 PPAScopeEvent(bitstream_write);
295 for (uint32_t i = 0; i < nalcount; i++)
296 {
297 bitstreamFile.write((const char*)nal->payload, nal->sizeBytes);
298 totalbytes += nal->sizeBytes;
299 nal++;
300 }
301 }
302
303 void CLIOptions::printStatus(uint32_t frameNum, x265_param *param)
304 {
305 char buf[200];
306 int64_t time = x265_mdate();
307
308 if (!bProgress || !frameNum || (prevUpdateTime && time - prevUpdateTime < UPDATE_INTERVAL))
309 return;
310 int64_t elapsed = time - startTime;
311 double fps = elapsed > 0 ? frameNum * 1000000. / elapsed : 0;
312 float bitrate = 0.008f * totalbytes * (param->fpsNum / param->fpsDenom) / ((float)frameNum);
313 if (framesToBeEncoded)
314 {
315 int eta = (int)(elapsed * (framesToBeEncoded - frameNum) / ((int64_t)frameNum * 1000000));
316 sprintf(buf, "x265 [%.1f%%] %d/%d frames, %.2f fps, %.2f kb/s, eta %d:%02d:%02d",
317 100. * frameNum / framesToBeEncoded, frameNum, framesToBeEncoded, fps, bitrate,
318 eta / 3600, (eta / 60) % 60, eta % 60);
319 }
320 else
321 {
322 sprintf(buf, "x265 %d frames: %.2f fps, %.2f kb/s", frameNum, fps, bitrate);
323 }
324 fprintf(stderr, "%s \r", buf + 5);
325 SetConsoleTitle(buf);
326 fflush(stderr); // needed in windows
327 prevUpdateTime = time;
328 }
329
330 void CLIOptions::printVersion(x265_param *param)
331 {
332 x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n", x265_version_str);
333 x265_log(param, X265_LOG_INFO, "build info %s\n", x265_build_info_str);
334 }
335
336 void CLIOptions::showHelp(x265_param *param)
337 {
338 x265_param_default(param);
339 printVersion(param);
340
341 #define H0 printf
342 #define OPT(value) (value ? "enabled" : "disabled")
343 H0("\nSyntax: x265 [options] infile [-o] outfile\n");
344 H0(" infile can be YUV or Y4M\n");
345 H0(" outfile is raw HEVC bitstream\n");
346 H0("\nExecutable Options:\n");
347 H0("-h/--help Show this help text and exit\n");
348 H0("-V/--version Show version info and exit\n");
349 H0("\nOutput Options:\n");
350 H0("-o/--output <filename> Bitstream output file name\n");
351 H0(" --log-level <string> Logging level: none error warning info debug full. Default %s\n", logLevelNames[param->logLevel + 1]);
352 H0(" --no-progress Disable CLI progress reports\n");
353 H0(" --[no-]cu-stats Enable logging stats about distribution of cu across all modes. Default %s\n",OPT(param->bLogCuStats));
354 H0(" --csv <filename> Comma separated log file, log level >= 3 frame log, else one line per run\n");
355 H0("\nInput Options:\n");
356 H0(" --input <filename> Raw YUV or Y4M input file name. `-` for stdin\n");
357 H0(" --y4m Force parsing of input stream as YUV4MPEG2 regardless of file extension\n");
358 H0(" --fps <float|rational> Source frame rate (float or num/denom), auto-detected if Y4M\n");
359 H0(" --input-res WxH Source picture size [w x h], auto-detected if Y4M\n");
360 H0(" --input-depth <integer> Bit-depth of input file. Default 8\n");
361 H0(" --input-csp <string> Source color space: i420, i444 or i422, auto-detected if Y4M. Default: i420\n");
362 H0("-f/--frames <integer> Maximum number of frames to encode. Default all\n");
363 H0(" --seek <integer> First frame to encode\n");
364 H0(" --[no-]interlace <bff|tff> Indicate input pictures are interlace fields in temporal order. Default progressive\n");
365 H0(" --dither Enable dither if downscaling to 8 bit pixels. Default disabled\n");
366 H0("\nQuality reporting metrics:\n");
367 H0(" --[no-]ssim Enable reporting SSIM metric scores. Default %s\n", OPT(param->bEnableSsim));
368 H0(" --[no-]psnr Enable reporting PSNR metric scores. Default %s\n", OPT(param->bEnablePsnr));
369 H0("\nProfile, Level, Tier:\n");
370 H0(" --profile <string> Enforce an encode profile: main, main10, mainstillpicture\n");
371 H0(" --level-idc <integer|float> Force a minumum required decoder level (as '5.0' or '50')\n");
372 H0(" --[no-]high-tier If a decoder level is specified, this modifier selects High tier of that level\n");
373 H0("\nThreading, performance:\n");
374 H0(" --threads <integer> Number of threads for thread pool (0: detect CPU core count, default)\n");
375 H0("-F/--frame-threads <integer> Number of concurrently encoded frames. 0: auto-determined by core count\n");
376 H0(" --[no-]wpp Enable Wavefront Parallel Processing. Default %s\n", OPT(param->bEnableWavefront));
377 H0(" --[no-]pmode Parallel mode analysis. Default %s\n", OPT(param->bDistributeModeAnalysis));
378 H0(" --[no-]pme Parallel motion estimation. Default %s\n", OPT(param->bDistributeMotionEstimation));
379 H0(" --[no-]asm <bool|int|string> Override CPU detection. Default: auto\n");
380 H0("\nPresets:\n");
381 H0("-p/--preset <string> Trade off performance for compression efficiency. Default medium\n");
382 H0(" ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, or placebo\n");
383 H0("-t/--tune <string> Tune the settings for a particular type of source or situation:\n");
384 H0(" psnr, ssim, zerolatency, or fastdecode\n");
385 H0("\nQuad-Tree size and depth:\n");
386 H0("-s/--ctu <64|32|16> Maximum CU size (default: 64x64). Default %d\n", param->maxCUSize);
387 H0(" --tu-intra-depth <integer> Max TU recursive depth for intra CUs. Default %d\n", param->tuQTMaxIntraDepth);
388 H0(" --tu-inter-depth <integer> Max TU recursive depth for inter CUs. Default %d\n", param->tuQTMaxInterDepth);
389 H0(" --[no-]rect Enable rectangular motion partitions Nx2N and 2NxN. Default %s\n", OPT(param->bEnableRectInter));
390 H0(" --[no-]amp Enable asymmetric motion partitions, requires --rect. Default %s\n", OPT(param->bEnableAMP));
391 H0("\nAnalysis:\n");
392 H0(" --rd <0..6> Level of RD in mode decision 0:least....6:full RDO. Default %d\n", param->rdLevel);
393 H0(" --psy-rd <0..2.0> Strength of psycho-visual rate distortion optimization, 0 to disable. Default %f\n", param->psyRd);
394 H0(" --psy-rdoq <0..50.0> Strength of psycho-visual optimization in quantization, 0 to disable. Default %f\n", param->psyRdoq);
395 H0(" --nr <integer> An integer value in range of 100 to 1000, which denotes strength of noise reduction. Default disabled\n");
396 H0(" --[no-]tskip-fast Enable fast intra transform skipping. Default %s\n", OPT(param->bEnableTSkipFast));
397 H0(" --[no-]early-skip Enable early SKIP detection. Default %s\n", OPT(param->bEnableEarlySkip));
398 H0(" --[no-]fast-cbf Enable early outs based on whether residual is coded. Default %s\n", OPT(param->bEnableCbfFastMode));
399 H0("\nCoding tools:\n");
400 H0("-w/--[no-]weightp Enable weighted prediction in P slices. Default %s\n", OPT(param->bEnableWeightedPred));
401 H0(" --[no-]weightb Enable weighted prediction in B slices. Default %s\n", OPT(param->bEnableWeightedBiPred));
402 H0(" --[no-]cu-lossless Consider lossless mode in CU RDO decisions. Default %s\n", OPT(param->bCULossless));
403 H0(" --[no-]signhide Hide sign bit of one coeff per TU (rdo). Default %s\n", OPT(param->bEnableSignHiding));
404 H0(" --[no-]tskip Enable intra 4x4 transform skipping. Default %s\n", OPT(param->bEnableTransformSkip));
405 H0("\nTemporal / motion search options:\n");
406 H0(" --me <string> Motion search method dia hex umh star full. Default %d\n", param->searchMethod);
407 H0("-m/--subme <integer> Amount of subpel refinement to perform (0:least .. 7:most). Default %d \n", param->subpelRefine);
408 H0(" --merange <integer> Motion search range. Default %d\n", param->searchRange);
409 H0(" --max-merge <1..5> Maximum number of merge candidates. Default %d\n", param->maxNumMergeCand);
410 H0(" --[no-]temporal-mvp Enable temporal MV predictors. Default %s\n", OPT(param->bEnableTemporalMvp));
411 H0("\nSpatial / intra options:\n");
412 H0(" --[no-]strong-intra-smoothing Enable strong intra smoothing for 32x32 blocks. Default %s\n", OPT(param->bEnableStrongIntraSmoothing));
413 H0(" --[no-]constrained-intra Constrained intra prediction (use only intra coded reference pixels) Default %s\n", OPT(param->bEnableConstrainedIntra));
414 H0(" --[no-]b-intra Enable intra in B frames in veryslow presets. Default %s\n", OPT(param->bIntraInBFrames));
415 H0(" --[no-]fast-intra Enable faster search method for angular intra predictions. Default %s\n", OPT(param->bEnableFastIntra));
416 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);
417 H0("\nSlice decision options:\n");
418 H0(" --[no-]open-gop Enable open-GOP, allows I slices to be non-IDR. Default %s\n", OPT(param->bOpenGOP));
419 H0("-I/--keyint <integer> Max IDR period in frames. -1 for infinite-gop. Default %d\n", param->keyframeMax);
420 H0("-i/--min-keyint <integer> Scenecuts closer together than this are coded as I, not IDR. Default: auto\n");
421 H0(" --no-scenecut Disable adaptive I-frame decision\n");
422 H0(" --scenecut <integer> How aggressively to insert extra I-frames. Default %d\n", param->scenecutThreshold);
423 H0(" --rc-lookahead <integer> Number of frames for frame-type lookahead (determines encoder latency) Default %d\n", param->lookaheadDepth);
424 H0(" --bframes <integer> Maximum number of consecutive b-frames (now it only enables B GOP structure) Default %d\n", param->bframes);
425 H0(" --bframe-bias <integer> Bias towards B frame decisions. Default %d\n", param->bFrameBias);
426 H0(" --b-adapt <0..2> 0 - none, 1 - fast, 2 - full (trellis) adaptive B frame scheduling. Default %d\n", param->bFrameAdaptive);
427 H0(" --[no-]b-pyramid Use B-frames as references. Default %s\n", OPT(param->bBPyramid));
428 H0(" --ref <integer> max number of L0 references to be allowed (1 .. 16) Default %d\n", param->maxNumReferences);
429 H0(" --qpfile <string> Force frametypes and QPs for some or all frames\n");
430 H0(" Format of each line: framenumber frametype QP\n");
431 H0(" QP is optional (none lets x265 choose). Frametypes: I,i,P,B,b.\n");
432 H0(" QPs are restricted by qpmin/qpmax.\n");
433 H0("\nRate control, Quantization:\n");
434 H0(" --bitrate <integer> Target bitrate (kbps) for ABR (implied). Default %d\n", param->rc.bitrate);
435 H0("-q/--qp <integer> QP for P slices in CQP mode (implied). --ipratio and --pbration determine other slice QPs\n");
436 H0(" --crf <float> Quality-based VBR (0-51). Default %f\n", param->rc.rfConstant);
437 H0(" --[no-]lossless Enable lossless: bypass transform, quant and loop filters globally. Default %s\n", OPT(param->bLossless));
438 H0(" --crf-max <float> With CRF+VBV, limit RF to this value. Default %f\n", param->rc.rfConstantMax);
439 H0(" May cause VBV underflows!\n");
440 H0(" --crf-min <float> With CRF+VBV, limit RF to this value. Default %f\n", param->rc.rfConstantMin);
441 H0(" this specifies a minimum rate factor value for encode!\n");
442 H0(" --vbv-maxrate <integer> Max local bitrate (kbit/s). Default %d\n", param->rc.vbvMaxBitrate);
443 H0(" --vbv-bufsize <integer> Set size of the VBV buffer (kbit). Default %d\n", param->rc.vbvBufferSize);
444 H0(" --vbv-init <float> Initial VBV buffer occupancy (fraction of bufsize or in kbits). Default %f\n", param->rc.vbvBufferInit);
445 H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance. Default %d\n", param->rc.aqMode);
446 H0(" --aq-strength <float> Reduces blocking and blurring in flat and textured areas.(0 to 3.0). Default %f\n", param->rc.aqStrength);
447 H0(" --[no-]cutree Enable cutree for Adaptive Quantization. Default %s\n", OPT(param->rc.cuTree));
448 H0(" --ipratio <float> QP factor between I and P. Default %f\n", param->rc.ipFactor);
449 H0(" --pbratio <float> QP factor between P and B. Default %f\n", param->rc.pbFactor);
450 H0(" --cbqpoffs <integer> Chroma Cb QP Offset. Default %d\n", param->cbQpOffset);
451 H0(" --crqpoffs <integer> Chroma Cr QP Offset. Default %d\n", param->crQpOffset);
452 H0(" --stats Filename for stats file in multipass pass rate control. Default x265_2pass.log\n");
453 H0(" --pass Multi pass rate control.\n"
454 " - 1 : First pass, creates stats file\n"
455 " - 2 : Last pass, does not overwrite stats file\n"
456 " - 3 : Nth pass, overwrites stats file\n");
457 H0(" --[no-]slow-firstpass Enable a slow first pass in a multipass rate control mode. Default %s\n", OPT(param->rc.bEnableSlowFirstPass));
458 H0(" --analysis-mode <string|int> save - Dump analysis info into file, load - Load analysis buffers from the file. Default %d\n", param->analysisMode);
459 H0(" --analysis-file <filename> Specify file name used for either dumping or reading analysis data.\n");
460 H0(" --scaling-list <string> Specify a file containing HM style quant scaling lists or 'default' or 'off'. Default: off\n");
461 H0(" --lambda-file <string> Specify a file containing replacement values for the lambda tables\n");
462 H0(" MAX_MAX_QP+1 floats for lambda table, then again for lambda2 table\n");
463 H0(" Blank lines and lines starting with hash(#) are ignored\n");
464 H0(" Comma is considered to be white-space\n");
465 H0("\nLoop filters (deblock and SAO):\n");
466 H0(" --[no-]lft Enable Deblocking Loop Filter. Default %s\n", OPT(param->bEnableLoopFilter));
467 H0(" --[no-]sao Enable Sample Adaptive Offset. Default %s\n", OPT(param->bEnableSAO));
468 H0(" --[no-]sao-non-deblock Use non-deblocked pixels, else right/bottom boundary areas skipped. Default %s\n", OPT(param->bSaoNonDeblocked));
469 H0("\nVUI options:\n");
470 H0(" --sar <width:height|int> Sample Aspect Ratio, the ratio of width to height of an individual pixel.\n");
471 H0(" Choose from 0=undef, 1=1:1(\"square\"), 2=12:11, 3=10:11, 4=16:11,\n");
472 H0(" 5=40:33, 6=24:11, 7=20:11, 8=32:11, 9=80:33, 10=18:11, 11=15:11,\n");
473 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);
474 H0(" --crop-rect <string> Add 'left,top,right,bottom' to the bitstream-level cropping rectangle\n");
475 H0(" --overscan <string> Specify whether it is appropriate for decoder to show cropped region: undef, show or crop. Default undef\n");
476 H0(" --videoformat <string> Specify video format from undef, component, pal, ntsc, secam, mac. Default undef\n");
477 H0(" --range <string> Specify black level and range of luma and chroma signals as full or limited Default limited\n");
478 H0(" --colorprim <string> Specify color primaries from undef, bt709, bt470m, bt470bg, smpte170m,\n");
479 H0(" smpte240m, film, bt2020. Default undef\n");
480 H0(" --transfer <string> Specify transfer characteristics from undef, bt709, bt470m, bt470bg, smpte170m,\n");
481 H0(" smpte240m, linear, log100, log316, iec61966-2-4, bt1361e, iec61966-2-1,\n");
482 H0(" bt2020-10, bt2020-12. Default undef\n");
483 H0(" --colormatrix <string> Specify color matrix setting from undef, bt709, fcc, bt470bg, smpte170m,\n");
484 H0(" smpte240m, GBR, YCgCo, bt2020nc, bt2020c. Default undef\n");
485 H0(" --chromaloc <integer> Specify chroma sample location (0 to 5). Default of %d\n", param->vui.chromaSampleLocTypeTopField);
486 H0("\nBitstream options:\n");
487 H0(" --[no-]info Emit SEI identifying encoder and parameters. Default %s\n", OPT(param->bEmitInfoSEI));
488 H0(" --[no-]aud Emit access unit delimiters at the start of each access unit. Default %s\n", OPT(param->bEnableAccessUnitDelimiters));
489 H0(" --[no-]hrd Enable HRD parameters signalling. Default %s\n", OPT(param->bEmitHRDSEI));
490 H0(" --[no-]repeat-headers Emit SPS and PPS headers at each keyframe. Default %s\n", OPT(param->bRepeatHeaders));
491 H0(" --hash <integer> Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum. Default %d\n", param->decodedPictureHashSEI);
492 H0("\nReconstructed video options (debugging):\n");
493 H0("-r/--recon <filename> Reconstructed raw image YUV or Y4M output file name\n");
494 H0(" --recon-depth <integer> Bit-depth of reconstructed raw image file. Defaults to input bit depth, or 8 if Y4M\n");
495 #undef OPT
496 #undef H0
497 printf("\n\nFull documentation may be found at http://x265.readthedocs.org/en/default/cli.html\n");
498 exit(0);
499 }
500
501 bool CLIOptions::parse(int argc, char **argv, x265_param* param)
502 {
503 bool bError = 0;
504 int help = 0;
505 int inputBitDepth = 8;
506 int reconFileBitDepth = 0;
507 const char *inputfn = NULL;
508 const char *reconfn = NULL;
509 const char *bitstreamfn = NULL;
510 const char *preset = NULL;
511 const char *tune = NULL;
512 const char *profile = NULL;
513 const char *analysisfn = "x265_analysis.dat";
514
515 if (argc <= 1)
516 {
517 x265_log(NULL, X265_LOG_ERROR, "No input file. Run x265 --help for a list of options.\n");
518 return true;
519 }
520
521 /* Presets are applied before all other options. */
522 for (optind = 0;; )
523 {
524 int c = getopt_long(argc, argv, short_options, long_options, NULL);
525 if (c == -1)
526 break;
527 if (c == 'p')
528 preset = optarg;
529 if (c == 't')
530 tune = optarg;
531 else if (c == '?')
532 showHelp(param);
533 }
534
535 if (x265_param_default_preset(param, preset, tune) < 0)
536 {
537 x265_log(NULL, X265_LOG_ERROR, "preset or tune unrecognized\n");
538 return true;
539 }
540
541 for (optind = 0;; )
542 {
543 int long_options_index = -1;
544 int c = getopt_long(argc, argv, short_options, long_options, &long_options_index);
545 if (c == -1)
546 {
547 break;
548 }
549
550 switch (c)
551 {
552 case 'h':
553 showHelp(param);
554 break;
555
556 case 'V':
557 printVersion(param);
558 x265_setup_primitives(param, -1);
559 exit(0);
560
561 default:
562 if (long_options_index < 0 && c > 0)
563 {
564 for (size_t i = 0; i < sizeof(long_options) / sizeof(long_options[0]); i++)
565 {
566 if (long_options[i].val == c)
567 {
568 long_options_index = (int)i;
569 break;
570 }
571 }
572
573 if (long_options_index < 0)
574 {
575 /* getopt_long might have already printed an error message */
576 if (c != 63)
577 x265_log(NULL, X265_LOG_WARNING, "internal error: short option '%c' has no long option\n", c);
578 return true;
579 }
580 }
581 if (long_options_index < 0)
582 {
583 x265_log(NULL, X265_LOG_WARNING, "short option '%c' unrecognized\n", c);
584 return true;
585 }
586 #define OPT(longname) \
587 else if (!strcmp(long_options[long_options_index].name, longname))
588 #define OPT2(name1, name2) \
589 else if (!strcmp(long_options[long_options_index].name, name1) || \
590 !strcmp(long_options[long_options_index].name, name2))
591
592 if (0) ;
593 OPT2("frame-skip", "seek") this->seek = (uint32_t)x265_atoi(optarg, bError);
594 OPT("frames") this->framesToBeEncoded = (uint32_t)x265_atoi(optarg, bError);
595 OPT("no-progress") this->bProgress = false;
596 OPT("output") bitstreamfn = optarg;
597 OPT("input") inputfn = optarg;
598 OPT("recon") reconfn = optarg;
599 OPT("input-depth") inputBitDepth = (uint32_t)x265_atoi(optarg, bError);
600 OPT("dither") this->bDither = true;
601 OPT("recon-depth") reconFileBitDepth = (uint32_t)x265_atoi(optarg, bError);
602 OPT("y4m") this->bForceY4m = true;
603 OPT("profile") profile = optarg; /* handled last */
604 OPT("preset") /* handled above */;
605 OPT("tune") /* handled above */;
606 OPT("analysis-file") analysisfn = optarg;
607 OPT("qpfile")
608 {
609 this->qpfile = fopen(optarg, "rb");
610 if (!this->qpfile)
611 {
612 x265_log(param, X265_LOG_ERROR, "%s qpfile not found or error in opening qp file \n", optarg);
613 return false;
614 }
615 }
616 else
617 bError |= !!x265_param_parse(param, long_options[long_options_index].name, optarg);
618
619 if (bError)
620 {
621 const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind - 2];
622 x265_log(NULL, X265_LOG_ERROR, "invalid argument: %s = %s\n", name, optarg);
623 return true;
624 }
625 #undef OPT
626 }
627 }
628
629 if (optind < argc && !inputfn)
630 inputfn = argv[optind++];
631 if (optind < argc && !bitstreamfn)
632 bitstreamfn = argv[optind++];
633 if (optind < argc)
634 {
635 x265_log(param, X265_LOG_WARNING, "extra unused command arguments given <%s>\n", argv[optind]);
636 return true;
637 }
638
639 if (argc <= 1 || help)
640 showHelp(param);
641
642 if (inputfn == NULL || bitstreamfn == NULL)
643 {
644 x265_log(param, X265_LOG_ERROR, "input or output file not specified, try -V for help\n");
645 return true;
646 }
647
648 #if HIGH_BIT_DEPTH
649 if (param->internalBitDepth != 10)
650 {
651 x265_log(param, X265_LOG_ERROR, "Only bit depths of 10 are supported in this build\n");
652 return true;
653 }
654 #else
655 if (param->internalBitDepth != 8)
656 {
657 x265_log(param, X265_LOG_ERROR, "Only bit depths of 8 are supported in this build\n");
658 return true;
659 }
660 #endif // if HIGH_BIT_DEPTH
661
662 InputFileInfo info;
663 info.filename = inputfn;
664 info.depth = inputBitDepth;
665 info.csp = param->internalCsp;
666 info.width = param->sourceWidth;
667 info.height = param->sourceHeight;
668 info.fpsNum = param->fpsNum;
669 info.fpsDenom = param->fpsDenom;
670 info.sarWidth = param->vui.sarWidth;
671 info.sarHeight = param->vui.sarHeight;
672 info.skipFrames = seek;
673 info.frameCount = 0;
674 getParamAspectRatio(param, info.sarWidth, info.sarHeight);
675
676 this->input = Input::open(info, this->bForceY4m);
677 if (!this->input || this->input->isFail())
678 {
679 x265_log(param, X265_LOG_ERROR, "unable to open input file <%s>\n", inputfn);
680 return true;
681 }
682
683 if (info.depth < 8 || info.depth > 16)
684 {
685 x265_log(param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n", inputBitDepth);
686 return true;
687 }
688
689 /* Unconditionally accept height/width/csp from file info */
690 param->sourceWidth = info.width;
691 param->sourceHeight = info.height;
692 param->internalCsp = info.csp;
693
694 /* Accept fps and sar from file info if not specified by user */
695 if (param->fpsDenom == 0 || param->fpsNum == 0)
696 {
697 param->fpsDenom = info.fpsDenom;
698 param->fpsNum = info.fpsNum;
699 }
700 if (!param->vui.aspectRatioIdc && info.sarWidth && info.sarHeight)
701 setParamAspectRatio(param, info.sarWidth, info.sarHeight);
702 if (this->framesToBeEncoded == 0 && info.frameCount > (int)seek)
703 this->framesToBeEncoded = info.frameCount - seek;
704 param->totalFrames = this->framesToBeEncoded;
705
706 if (x265_param_apply_profile(param, profile))
707 return true;
708
709 if (param->logLevel >= X265_LOG_INFO)
710 {
711 char buf[128];
712 int p = sprintf(buf, "%dx%d fps %d/%d %sp%d", param->sourceWidth, param->sourceHeight,
713 param->fpsNum, param->fpsDenom, x265_source_csp_names[param->internalCsp], info.depth);
714
715 int width, height;
716 getParamAspectRatio(param, width, height);
717 if (width && height)
718 p += sprintf(buf + p, " sar %d:%d", width, height);
719
720 if (framesToBeEncoded <= 0 || info.frameCount <= 0)
721 strcpy(buf + p, " unknown frame count");
722 else
723 sprintf(buf + p, " frames %u - %d of %d", this->seek, this->seek + this->framesToBeEncoded - 1, info.frameCount);
724
725 fprintf(stderr, "%s [info]: %s\n", input->getName(), buf);
726 }
727
728 this->input->startReader();
729
730 if (reconfn)
731 {
732 if (reconFileBitDepth == 0)
733 reconFileBitDepth = param->internalBitDepth;
734 this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, reconFileBitDepth,
735 param->fpsNum, param->fpsDenom, param->internalCsp);
736 if (this->recon->isFail())
737 {
738 x265_log(param, X265_LOG_WARNING, "unable to write reconstruction file\n");
739 this->recon->release();
740 this->recon = 0;
741 }
742 else
743 fprintf(stderr, "%s [info]: reconstructed images %dx%d fps %d/%d %s\n", this->recon->getName(),
744 param->sourceWidth, param->sourceHeight, param->fpsNum, param->fpsDenom,
745 x265_source_csp_names[param->internalCsp]);
746 }
747
748 this->bitstreamFile.open(bitstreamfn, std::fstream::binary | std::fstream::out);
749 if (!this->bitstreamFile)
750 {
751 x265_log(NULL, X265_LOG_ERROR, "failed to open bitstream file <%s> for writing\n", bitstreamfn);
752 return true;
753 }
754
755 if (param->analysisMode)
756 {
757 const char *mode = param->analysisMode == X265_ANALYSIS_SAVE ? "wb" : "rb";
758 this->analysisFile = fopen(analysisfn, mode);
759 if (!this->analysisFile)
760 {
761 x265_log(NULL, X265_LOG_ERROR, "failed to open analysis file %s\n", analysisfn);
762 return true;
763 }
764 }
765
766 return false;
767 }
768
769 bool CLIOptions::validateFanout(x265_param *param)
770 {
771 #define CMP_OPT_FANOUT(opt, param_val)\
772 {\
773 bErr = 0;\
774 p = strstr(paramBuf, opt "=");\
775 char* q = strstr(paramBuf, "no-"opt);\
776 if (p && sscanf(p, opt "=%d" , &i) && param_val != i)\
777 bErr = 1;\
778 else if (!param_val && !q)\
779 bErr = 1;\
780 else if (param_val && (q || !strstr(paramBuf, opt)))\
781 bErr = 1;\
782 if (bErr)\
783 {\
784 x265_log(param, X265_LOG_ERROR, "different " opt " setting than given in analysis file (%d vs %d)\n", param_val, i);\
785 X265_FREE(paramBuf);\
786 return false;\
787 }\
788 }
789
790 char *p = NULL, *paramBuf;
791 int i, j;
792 uint32_t k , l;
793 bool bErr = false;
794
795 paramBuf = X265_MALLOC(char, MAXPARAMSIZE);
796 if (!paramBuf)
797 return false;
798
799 fread(paramBuf, 1, MAXPARAMSIZE, this->analysisFile);
800
801 /* check whether fanout options are compatible */
802 if (strncmp(paramBuf, "#options:", 9))
803 {
804 x265_log(param, X265_LOG_ERROR, "options list in analysis file is not valid\n");
805 X265_FREE(paramBuf);
806 return false;
807 }
808
809 char* buf = strchr(paramBuf, '\n');
810 if (!buf)
811 {
812 x265_log(param, X265_LOG_ERROR, "Malformed analysis file\n");
813 X265_FREE(paramBuf);
814 return false;
815 }
816 *buf = '\0';
817 fseek(this->analysisFile, (int)strlen(paramBuf) + 1, SEEK_SET);
818
819 if (sscanf(paramBuf, "#options: %dx%d", &i, &j) != 2)
820 {
821 x265_log(param, X265_LOG_ERROR, "Resolution specified in analysis file is not valid\n");
822 X265_FREE(paramBuf);
823 return false;
824 }
825 if ((p = strstr(paramBuf, " fps=")) == 0 || sscanf(p, " fps=%u/%u", &k, &l) != 2)
826 {
827 x265_log(param, X265_LOG_ERROR, "fps specified in analysis file is not valid\n");
828 X265_FREE(paramBuf);
829 return false;
830 }
831 if (k != param->fpsNum || l != param->fpsDenom)
832 {
833 x265_log(param, X265_LOG_ERROR, "fps mismatch than given in analysis file (%u/%u vs %u/%u)\n",
834 param->fpsNum, param->fpsDenom, k, l);
835 X265_FREE(paramBuf);
836 return false;
837 }
838
839 CMP_OPT_FANOUT("bitdepth", param->internalBitDepth);
840 CMP_OPT_FANOUT("weightp", param->bEnableWeightedPred);
841 CMP_OPT_FANOUT("bframes", param->bframes);
842 CMP_OPT_FANOUT("b-pyramid", param->bBPyramid);
843 CMP_OPT_FANOUT("b-adapt", param->bFrameAdaptive);
844 CMP_OPT_FANOUT("open-gop", param->bOpenGOP);
845 CMP_OPT_FANOUT("keyint", param->keyframeMax);
846 CMP_OPT_FANOUT("min-keyint", param->keyframeMin);
847 CMP_OPT_FANOUT("scenecut", param->scenecutThreshold);
848 CMP_OPT_FANOUT("ctu", (int)param->maxCUSize);
849 CMP_OPT_FANOUT("ref", param->maxNumReferences);
850 CMP_OPT_FANOUT("rc-lookahead", param->lookaheadDepth);
851
852 #undef CMP_OPT_FANOUT
853
854 X265_FREE(paramBuf);
855 return true;
856 }
857
858 void CLIOptions::readAnalysisFile(x265_picture* pic, x265_param* p)
859 {
860 int poc, width, height;
861 uint32_t numPart, numCU;
862 fread(&width, sizeof(int), 1, this->analysisFile);
863 fread(&height, sizeof(int), 1, this->analysisFile);
864 fread(&poc, sizeof(int), 1, this->analysisFile);
865 fread(&pic->sliceType, sizeof(int), 1, this->analysisFile);
866 fread(&numCU, sizeof(int), 1, this->analysisFile);
867 fread(&numPart, sizeof(int), 1, this->analysisFile);
868
869 if (poc != pic->poc || width != p->sourceWidth || height != p->sourceHeight)
870 {
871 x265_log(NULL, X265_LOG_WARNING, "Error in reading intra-inter data.\n");
872 x265_free_analysis_data(pic);
873 return;
874 }
875
876 fread(pic->analysisData.intraData->depth,
877 sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
878 fread(pic->analysisData.intraData->modes,
879 sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
880 fread(pic->analysisData.intraData->partSizes,
881 sizeof(char), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
882 fread(pic->analysisData.intraData->poc,
883 sizeof(int), pic->analysisData.numCUsInFrame, this->analysisFile);
884 fread(pic->analysisData.intraData->cuAddr,
885 sizeof(uint32_t), pic->analysisData.numCUsInFrame, this->analysisFile);
886 fread(pic->analysisData.interData, sizeof(x265_inter_data), pic->analysisData.numCUsInFrame * 85, this->analysisFile);
887 }
888
889 void CLIOptions::writeAnalysisFile(x265_picture* pic, x265_param *p)
890 {
891 uint64_t seekTo = pic->poc * this->analysisRecordSize + this->analysisHeaderSize;
892 fseeko(this->analysisFile, seekTo, SEEK_SET);
893 fwrite(&p->sourceWidth, sizeof(int), 1, this->analysisFile);
894 fwrite(&p->sourceHeight, sizeof(int), 1, this->analysisFile);
895 fwrite(&pic->poc, sizeof(int), 1, this->analysisFile);
896 fwrite(&pic->sliceType, sizeof(int), 1, this->analysisFile);
897 fwrite(&pic->analysisData.numCUsInFrame, sizeof(int), 1, this->analysisFile);
898 fwrite(&pic->analysisData.numPartitions, sizeof(int), 1, this->analysisFile);
899
900 fwrite(pic->analysisData.intraData->depth,
901 sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
902 fwrite(pic->analysisData.intraData->modes,
903 sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
904 fwrite(pic->analysisData.intraData->partSizes,
905 sizeof(char), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
906 fwrite(pic->analysisData.intraData->poc, sizeof(int), pic->analysisData.numCUsInFrame, this->analysisFile);
907 fwrite(pic->analysisData.intraData->cuAddr, sizeof(uint32_t), pic->analysisData.numCUsInFrame, this->analysisFile);
908 fwrite(pic->analysisData.interData, sizeof(x265_inter_data), pic->analysisData.numCUsInFrame * 85, this->analysisFile);
909 }
910
911 bool CLIOptions::parseQPFile(x265_picture &pic_org)
912 {
913 int32_t num = -1, qp, ret;
914 char type;
915 uint32_t filePos;
916 pic_org.forceqp = 0;
917 pic_org.sliceType = X265_TYPE_AUTO;
918 while (num < pic_org.poc)
919 {
920 filePos = ftell(qpfile);
921 qp = -1;
922 ret = fscanf(qpfile, "%d %c%*[ \t]%d\n", &num, &type, &qp);
923
924 if (num > pic_org.poc || ret == EOF)
925 {
926 fseek(qpfile, filePos, SEEK_SET);
927 break;
928 }
929 if (num < pic_org.poc && ret >= 2)
930 continue;
931 if (ret == 3 && qp >= 0)
932 pic_org.forceqp = qp + 1;
933 if (type == 'I') pic_org.sliceType = X265_TYPE_IDR;
934 else if (type == 'i') pic_org.sliceType = X265_TYPE_I;
935 else if (type == 'P') pic_org.sliceType = X265_TYPE_P;
936 else if (type == 'B') pic_org.sliceType = X265_TYPE_BREF;
937 else if (type == 'b') pic_org.sliceType = X265_TYPE_B;
938 else ret = 0;
939 if (ret < 2 || qp < -1 || qp > 51)
940 return 0;
941 }
942 return 1;
943 }
944
945 int main(int argc, char **argv)
946 {
947 #if HAVE_VLD
948 // This uses Microsoft's proprietary WCHAR type, but this only builds on Windows to start with
949 VLDSetReportOptions(VLD_OPT_REPORT_TO_DEBUGGER | VLD_OPT_REPORT_TO_FILE, L"x265_leaks.txt");
950 #endif
951 PPA_INIT();
952
953 x265_param *param = x265_param_alloc();
954 CLIOptions cliopt;
955
956 if (cliopt.parse(argc, argv, param))
957 {
958 cliopt.destroy();
959 x265_param_free(param);
960 exit(1);
961 }
962
963 x265_encoder *encoder = x265_encoder_open(param);
964 if (!encoder)
965 {
966 x265_log(param, X265_LOG_ERROR, "failed to open encoder\n");
967 cliopt.destroy();
968 x265_param_free(param);
969 x265_cleanup();
970 exit(1);
971 }
972
973 /* get the encoder parameters post-initialization */
974 x265_encoder_parameters(encoder, param);
975
976 /* Control-C handler */
977 if (signal(SIGINT, sigint_handler) == SIG_ERR)
978 x265_log(param, X265_LOG_ERROR, "Unable to register CTRL+C handler: %s\n", strerror(errno));
979
980 x265_picture pic_orig, pic_out;
981 x265_picture *pic_in = &pic_orig;
982 x265_picture *pic_recon = cliopt.recon ? &pic_out : NULL;
983 uint32_t inFrameCount = 0;
984 uint32_t outFrameCount = 0;
985 x265_nal *p_nal;
986 x265_stats stats;
987 uint32_t nal;
988 int16_t *errorBuf = NULL;
989
990 if (!param->bRepeatHeaders)
991 {
992 if (x265_encoder_headers(encoder, &p_nal, &nal) < 0)
993 {
994 x265_log(param, X265_LOG_ERROR, "Failure generating stream headers\n");
995 goto fail;
996 }
997 else
998 cliopt.writeNALs(p_nal, nal);
999 }
1000
1001 x265_picture_init(param, pic_in);
1002
1003 if (param->analysisMode && !pic_recon)
1004 {
1005 x265_log(NULL, X265_LOG_ERROR, "Must specify recon with analysis-mode option.\n");
1006 goto fail;
1007 }
1008 if (param->analysisMode)
1009 {
1010 if (param->analysisMode == X265_ANALYSIS_SAVE)
1011 {
1012 char *p = x265_param2string(param);
1013 if (!p)
1014 {
1015 x265_log(NULL, X265_LOG_ERROR, "analysis: buffer allocation failure, aborting");
1016 goto fail;
1017 }
1018 uint32_t numCU = pic_in->analysisData.numCUsInFrame;
1019 uint32_t numPart = pic_in->analysisData.numPartitions;
1020
1021 cliopt.analysisRecordSize = ((sizeof(int) * 4 + sizeof(uint32_t) * 2) + sizeof(x265_inter_data) * numCU * 85 +
1022 sizeof(uint8_t) * 2 * numPart * numCU + sizeof(char) * numPart * numCU + sizeof(int) * numCU + sizeof(uint32_t) * numCU);
1023
1024 fprintf(cliopt.analysisFile, "#options: %s\n", p);
1025 cliopt.analysisHeaderSize = ftell(cliopt.analysisFile);
1026 X265_FREE(p);
1027 }
1028 else
1029 {
1030 if (!cliopt.validateFanout(param))
1031 goto fail;
1032 }
1033 }
1034
1035 if (cliopt.bDither)
1036 {
1037 errorBuf = X265_MALLOC(int16_t, param->sourceWidth + 1);
1038 if (errorBuf)
1039 memset(errorBuf, 0, (param->sourceWidth + 1) * sizeof(int16_t));
1040 else
1041 cliopt.bDither = false;
1042 }
1043
1044 // main encoder loop
1045 while (pic_in && !b_ctrl_c)
1046 {
1047 pic_orig.poc = inFrameCount;
1048 if (cliopt.qpfile && !param->rc.bStatRead)
1049 {
1050 if (!cliopt.parseQPFile(pic_orig))
1051 {
1052 x265_log(NULL, X265_LOG_ERROR, "can't parse qpfile for frame %d\n", pic_in->poc);
1053 fclose(cliopt.qpfile);
1054 cliopt.qpfile = NULL;
1055 }
1056 }
1057
1058 if (cliopt.framesToBeEncoded && inFrameCount >= cliopt.framesToBeEncoded)
1059 pic_in = NULL;
1060 else if (cliopt.input->readPicture(pic_orig))
1061 inFrameCount++;
1062 else
1063 pic_in = NULL;
1064
1065 if (pic_in)
1066 {
1067 if (pic_in->bitDepth > X265_DEPTH && cliopt.bDither)
1068 {
1069 ditherImage(*pic_in, param->sourceWidth, param->sourceHeight, errorBuf, X265_DEPTH);
1070 pic_in->bitDepth = X265_DEPTH;
1071 }
1072 if (param->analysisMode)
1073 {
1074 x265_alloc_analysis_data(pic_in);
1075
1076 if (param->analysisMode == X265_ANALYSIS_LOAD)
1077 cliopt.readAnalysisFile(pic_in, param);
1078 }
1079 }
1080
1081 int numEncoded = x265_encoder_encode(encoder, &p_nal, &nal, pic_in, pic_recon);
1082 if (numEncoded < 0)
1083 {
1084 b_ctrl_c = 1;
1085 break;
1086 }
1087 outFrameCount += numEncoded;
1088 if (numEncoded && pic_recon)
1089 {
1090 cliopt.recon->writePicture(pic_out);
1091 if (param->analysisMode == X265_ANALYSIS_SAVE)
1092 cliopt.writeAnalysisFile(pic_recon, param);
1093 if (param->analysisMode)
1094 x265_free_analysis_data(pic_recon);
1095 }
1096
1097 if (nal)
1098 cliopt.writeNALs(p_nal, nal);
1099
1100 // Because x265_encoder_encode() lazily encodes entire GOPs, updates are per-GOP
1101 cliopt.printStatus(outFrameCount, param);
1102 }
1103
1104 /* Flush the encoder */
1105 while (!b_ctrl_c)
1106 {
1107 uint32_t numEncoded = x265_encoder_encode(encoder, &p_nal, &nal, NULL, pic_recon);
1108 outFrameCount += numEncoded;
1109 if (numEncoded && pic_recon)
1110 {
1111 cliopt.recon->writePicture(pic_out);
1112 if (param->analysisMode == X265_ANALYSIS_SAVE)
1113 cliopt.writeAnalysisFile(pic_recon, param);
1114 if (param->analysisMode)
1115 x265_free_analysis_data(pic_recon);
1116 }
1117
1118 if (nal)
1119 cliopt.writeNALs(p_nal, nal);
1120
1121 cliopt.printStatus(outFrameCount, param);
1122
1123 if (!numEncoded)
1124 break;
1125 }
1126
1127 /* clear progress report */
1128 if (cliopt.bProgress)
1129 fprintf(stderr, "%*s\r", 80, " ");
1130
1131 fail:
1132 x265_encoder_get_stats(encoder, &stats, sizeof(stats));
1133 if (param->csvfn && !b_ctrl_c)
1134 x265_encoder_log(encoder, argc, argv);
1135 x265_encoder_close(encoder);
1136 cliopt.bitstreamFile.close();
1137
1138 if (b_ctrl_c)
1139 fprintf(stderr, "aborted at input frame %d, output frame %d\n",
1140 cliopt.seek + inFrameCount, stats.encodedPictureCount);
1141
1142 if (stats.encodedPictureCount)
1143 {
1144 printf("\nencoded %d frames in %.2fs (%.2f fps), %.2f kb/s", stats.encodedPictureCount,
1145 stats.elapsedEncodeTime, stats.encodedPictureCount / stats.elapsedEncodeTime, stats.bitrate);
1146
1147 if (param->bEnablePsnr)
1148 printf(", Global PSNR: %.3f", stats.globalPsnr);
1149
1150 if (param->bEnableSsim)
1151 printf(", SSIM Mean Y: %.7f (%6.3f dB)", stats.globalSsim, x265_ssim2dB(stats.globalSsim));
1152
1153 printf("\n");
1154 }
1155 else
1156 {
1157 printf("\nencoded 0 frames\n");
1158 }
1159
1160 x265_cleanup(); /* Free library singletons */
1161
1162 cliopt.destroy();
1163
1164 x265_param_free(param);
1165
1166 X265_FREE(errorBuf);
1167
1168 #if HAVE_VLD
1169 assert(VLDReportLeaks() == 0);
1170 #endif
1171 return 0;
1172 }