x264.c 75.6 KB
Newer Older
Laurent Aimar's avatar
Laurent Aimar committed
1
/*****************************************************************************
Fiona Glaser's avatar
Fiona Glaser committed
2
 * x264: top-level x264cli functions
Laurent Aimar's avatar
Laurent Aimar committed
3
 *****************************************************************************
Fiona Glaser's avatar
Fiona Glaser committed
4
 * Copyright (C) 2003-2010 x264 project
Laurent Aimar's avatar
Laurent Aimar committed
5
 *
6 7
 * Authors: Loren Merritt <lorenm@u.washington.edu>
 *          Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Steven Walters <kemuri9@gmail.com>
Fiona Glaser's avatar
Fiona Glaser committed
9
 *          Fiona Glaser <fiona@x264.com>
10
 *          Kieran Kunhya <kieran@kunhya.com>
Laurent Aimar's avatar
Laurent Aimar committed
11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
Fiona Glaser's avatar
Fiona Glaser committed
25 26 27
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at licensing@x264.com.
Laurent Aimar's avatar
Laurent Aimar committed
28 29 30 31 32 33 34 35 36
 *****************************************************************************/

#include <stdlib.h>
#include <math.h>

#include <signal.h>
#define _GNU_SOURCE
#include <getopt.h>

37
#include "common/common.h"
38 39 40
#include "x264cli.h"
#include "input/input.h"
#include "output/output.h"
41
#include "filters/filters.h"
42 43

#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "x264", __VA_ARGS__ )
Loren Merritt's avatar
Loren Merritt committed
44

45 46 47 48 49 50
#ifdef _WIN32
#include <windows.h>
#else
#define SetConsoleTitle(t)
#endif

51
#if HAVE_LAVF
52 53
#undef DECLARE_ALIGNED
#include <libavformat/avformat.h>
54 55 56 57
#include <libavutil/pixfmt.h>
#include <libavutil/pixdesc.h>
#endif

58 59 60 61 62 63 64 65
#if HAVE_SWSCALE
#include <libswscale/swscale.h>
#endif

#if HAVE_FFMS
#include <ffms.h>
#endif

Laurent Aimar's avatar
Laurent Aimar committed
66
/* Ctrl-C handler */
67 68
static volatile int b_ctrl_c = 0;
static int          b_exit_on_ctrl_c = 0;
Anton Mitrofanov's avatar
Anton Mitrofanov committed
69
static void sigint_handler( int a )
Laurent Aimar's avatar
Laurent Aimar committed
70
{
Loren Merritt's avatar
Loren Merritt committed
71 72 73
    if( b_exit_on_ctrl_c )
        exit(0);
    b_ctrl_c = 1;
Laurent Aimar's avatar
Laurent Aimar committed
74 75
}

Loren Merritt's avatar
Loren Merritt committed
76 77 78 79 80
typedef struct {
    int b_progress;
    int i_seek;
    hnd_t hin;
    hnd_t hout;
81
    FILE *qpfile;
Yusuke Nakamura's avatar
Yusuke Nakamura committed
82 83
    FILE *tcfile_out;
    double timebase_convert_multiplier;
84
    int i_pulldown;
Loren Merritt's avatar
Loren Merritt committed
85 86
} cli_opt_t;

87
/* file i/o operation structs */
88 89
cli_input_t input;
static cli_output_t output;
Loren Merritt's avatar
Loren Merritt committed
90

91 92 93
/* video filter operation struct */
static cli_vid_filter_t filter;

94 95 96
static const char * const demuxer_names[] =
{
    "auto",
97
    "raw",
98
    "y4m",
Steven Walters's avatar
Steven Walters committed
99
#if HAVE_AVS
100 101
    "avs",
#endif
Steven Walters's avatar
Steven Walters committed
102
#if HAVE_LAVF
103 104
    "lavf",
#endif
Steven Walters's avatar
Steven Walters committed
105
#if HAVE_FFMS
106 107 108 109 110 111 112 113 114 115 116
    "ffms",
#endif
    0
};

static const char * const muxer_names[] =
{
    "auto",
    "raw",
    "mkv",
    "flv",
Steven Walters's avatar
Steven Walters committed
117
#if HAVE_GPAC
118 119 120 121
    "mp4",
#endif
    0
};
122

123
static const char * const pulldown_names[] = { "none", "22", "32", "64", "double", "triple", "euro", 0 };
124
static const char * const log_level_names[] = { "none", "error", "warning", "info", "debug", 0 };
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148

typedef struct{
    int mod;
    uint8_t pattern[24];
    float fps_factor;
} cli_pulldown_t;

enum pulldown_type_e
{
    X264_PULLDOWN_22 = 1,
    X264_PULLDOWN_32,
    X264_PULLDOWN_64,
    X264_PULLDOWN_DOUBLE,
    X264_PULLDOWN_TRIPLE,
    X264_PULLDOWN_EURO
};

#define TB  PIC_STRUCT_TOP_BOTTOM
#define BT  PIC_STRUCT_BOTTOM_TOP
#define TBT PIC_STRUCT_TOP_BOTTOM_TOP
#define BTB PIC_STRUCT_BOTTOM_TOP_BOTTOM

static const cli_pulldown_t pulldown_values[] =
{
Kieran Kunhya's avatar
Kieran Kunhya committed
149
    [X264_PULLDOWN_22]     = {1,  {TB},                                   1.0},
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    [X264_PULLDOWN_32]     = {4,  {TBT, BT, BTB, TB},                     1.25},
    [X264_PULLDOWN_64]     = {2,  {PIC_STRUCT_DOUBLE, PIC_STRUCT_TRIPLE}, 1.0},
    [X264_PULLDOWN_DOUBLE] = {1,  {PIC_STRUCT_DOUBLE},                    2.0},
    [X264_PULLDOWN_TRIPLE] = {1,  {PIC_STRUCT_TRIPLE},                    3.0},
    [X264_PULLDOWN_EURO]   = {24, {TBT, BT, BT, BT, BT, BT, BT, BT, BT, BT, BT, BT,
                                   BTB, TB, TB, TB, TB, TB, TB, TB, TB, TB, TB, TB}, 25.0/24.0}
};

#undef TB
#undef BT
#undef TBT
#undef BTB

// indexed by pic_struct enum
static const float pulldown_frame_duration[10] = { 0.0, 1, 0.5, 0.5, 1, 1, 1.5, 1.5, 2, 3 };

Anton Mitrofanov's avatar
Anton Mitrofanov committed
166 167 168
static void help( x264_param_t *defaults, int longhelp );
static int  parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt );
static int  encode( x264_param_t *param, cli_opt_t *opt );
Laurent Aimar's avatar
Laurent Aimar committed
169

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
/* logging and printing for within the cli system */
static int cli_log_level;
void x264_cli_log( const char *name, int i_level, const char *fmt, ... )
{
    if( i_level > cli_log_level )
        return;
    char *s_level;
    switch( i_level )
    {
        case X264_LOG_ERROR:
            s_level = "error";
            break;
        case X264_LOG_WARNING:
            s_level = "warning";
            break;
        case X264_LOG_INFO:
            s_level = "info";
            break;
        case X264_LOG_DEBUG:
            s_level = "debug";
            break;
        default:
            s_level = "unknown";
            break;
    }
    fprintf( stderr, "%s [%s]: ", name, s_level );
    va_list arg;
    va_start( arg, fmt );
    vfprintf( stderr, fmt, arg );
    va_end( arg );
}

void x264_cli_printf( int i_level, const char *fmt, ... )
{
    if( i_level > cli_log_level )
        return;
    va_list arg;
    va_start( arg, fmt );
    vfprintf( stderr, fmt, arg );
    va_end( arg );
}

212 213 214 215 216 217
static void print_version_info()
{
#ifdef X264_POINTVER
    printf( "x264 "X264_POINTVER"\n" );
#else
    printf( "x264 0.%d.X\n", X264_BUILD );
218 219 220 221 222 223 224 225 226
#endif
#if HAVE_SWSCALE
    printf( "(libswscale %d.%d.%d)\n", LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO );
#endif
#if HAVE_LAVF
    printf( "(libavformat %d.%d.%d)\n", LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO );
#endif
#if HAVE_FFMS
    printf( "(ffmpegsource %d.%d.%d.%d)\n", FFMS_VERSION >> 24, (FFMS_VERSION & 0xff0000) >> 16, (FFMS_VERSION & 0xff00) >> 8, FFMS_VERSION & 0xff );
227 228 229 230 231 232 233
#endif
    printf( "built on " __DATE__ ", " );
#ifdef __GNUC__
    printf( "gcc: " __VERSION__ "\n" );
#else
    printf( "using a non-gcc compiler\n" );
#endif
234
    printf( "configuration: --bit-depth=%d\n", x264_bit_depth );
235 236 237 238 239 240
    printf( "x264 license: " );
#if HAVE_GPL
    printf( "GPL version 2 or later\n" );
#else
    printf( "Non-GPL commercial\n" );
#endif
241 242 243
#if HAVE_SWSCALE
    const char *license = swscale_license();
    printf( "libswscale%s%s license: %s\n", HAVE_LAVF ? "/libavformat" : "", HAVE_FFMS ? "/ffmpegsource" : "" , license );
244 245 246 247 248 249 250
    if( !strcmp( license, "nonfree and unredistributable" ) ||
       (!HAVE_GPL && (!strcmp( license, "GPL version 2 or later" )
                  ||  !strcmp( license, "GPL version 3 or later" ))))
        printf( "WARNING: This binary is unredistributable!\n" );
#endif
}

Laurent Aimar's avatar
Laurent Aimar committed
251 252 253
int main( int argc, char **argv )
{
    x264_param_t param;
Loren Merritt's avatar
Loren Merritt committed
254
    cli_opt_t opt;
255 256
    int ret;

257
    FAIL_IF_ERROR( x264_threading_init(), "unable to initialize threading\n" )
Laurent Aimar's avatar
Laurent Aimar committed
258

259
#ifdef _WIN32
260
    _setmode(_fileno(stdin), _O_BINARY);
Laurent Aimar's avatar
Laurent Aimar committed
261 262 263 264
    _setmode(_fileno(stdout), _O_BINARY);
#endif

    /* Parse command line */
Anton Mitrofanov's avatar
Anton Mitrofanov committed
265
    if( parse( argc, argv, &param, &opt ) < 0 )
Laurent Aimar's avatar
Laurent Aimar committed
266 267 268
        return -1;

    /* Control-C handler */
Anton Mitrofanov's avatar
Anton Mitrofanov committed
269
    signal( SIGINT, sigint_handler );
Laurent Aimar's avatar
Laurent Aimar committed
270

Anton Mitrofanov's avatar
Anton Mitrofanov committed
271
    ret = encode( &param, &opt );
272 273

    return ret;
Laurent Aimar's avatar
Laurent Aimar committed
274 275
}

276
static char const *strtable_lookup( const char * const table[], int idx )
277 278
{
    int i = 0; while( table[i] ) i++;
279
    return ( ( idx >= 0 && idx < i ) ? table[ idx ] : "???" );
280 281
}

282 283 284 285 286 287 288 289 290 291 292 293 294
static char *stringify_names( char *buf, const char * const names[] )
{
    int i = 0;
    char *p = buf;
    for( p[0] = 0; names[i]; i++ )
    {
        p += sprintf( p, "%s", names[i] );
        if( names[i+1] )
            p += sprintf( p, ", " );
    }
    return buf;
}

295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
static void print_csp_names( int longhelp )
{
    if( longhelp < 2 )
        return;
#   define INDENT "                                "
    printf( "                              - valid csps for `raw' demuxer:\n" );
    printf( INDENT );
    for( int i = X264_CSP_NONE+1; i < X264_CSP_CLI_MAX; i++ )
    {
        printf( "%s", x264_cli_csps[i].name );
        if( i+1 < X264_CSP_CLI_MAX )
            printf( ", " );
    }
#if HAVE_LAVF
    printf( "\n" );
    printf( "                              - valid csps for `lavf' demuxer:\n" );
    printf( INDENT );
    int line_len = strlen( INDENT );
    for( enum PixelFormat i = PIX_FMT_NONE+1; i < PIX_FMT_NB; i++ )
    {
        const char *pfname = av_pix_fmt_descriptors[i].name;
        int name_len = strlen( pfname );
        if( line_len + name_len > (80 - strlen( ", " )) )
        {
            printf( "\n" INDENT );
            line_len = strlen( INDENT );
        }
        printf( "%s", pfname );
        line_len += name_len;
        if( i+1 < PIX_FMT_NB )
        {
            printf( ", " );
            line_len += 2;
        }
    }
#endif
    printf( "\n" );
}

Anton Mitrofanov's avatar
Anton Mitrofanov committed
334
static void help( x264_param_t *defaults, int longhelp )
Laurent Aimar's avatar
Laurent Aimar committed
335
{
336
    char buf[50];
337
#define H0 printf
Fiona Glaser's avatar
Fiona Glaser committed
338 339
#define H1 if(longhelp>=1) printf
#define H2 if(longhelp==2) printf
340
    H0( "x264 core:%d%s\n"
341
        "Syntax: x264 [options] -o outfile infile\n"
342
        "\n"
343 344
        "Infile can be raw (in which case resolution is required),\n"
        "  or YUV4MPEG (*.y4m),\n"
345
        "  or Avisynth if compiled with support (%s).\n"
346
        "  or libav* formats if compiled with lavf support (%s) or ffms support (%s).\n"
347 348 349
        "Outfile type is selected by filename:\n"
        " .264 -> Raw bytestream\n"
        " .mkv -> Matroska\n"
Kieran Kunhya's avatar
Kieran Kunhya committed
350
        " .flv -> Flash Video\n"
351
        " .mp4 -> MP4 if compiled with GPAC support (%s)\n"
352
        "Output bit depth: %d (configured at compile time)\n"
353 354 355
        "\n"
        "Options:\n"
        "\n"
Fiona Glaser's avatar
Fiona Glaser committed
356 357 358
        "  -h, --help                  List basic options\n"
        "      --longhelp              List more options\n"
        "      --fullhelp              List all options\n"
359 360
        "\n",
        X264_BUILD, X264_VERSION,
Steven Walters's avatar
Steven Walters committed
361
#if HAVE_AVS
362 363 364 365
        "yes",
#else
        "no",
#endif
Steven Walters's avatar
Steven Walters committed
366
#if HAVE_LAVF
367 368 369 370
        "yes",
#else
        "no",
#endif
Steven Walters's avatar
Steven Walters committed
371
#if HAVE_FFMS
372
        "yes",
Loren Merritt's avatar
Loren Merritt committed
373
#else
374
        "no",
Loren Merritt's avatar
Loren Merritt committed
375
#endif
Steven Walters's avatar
Steven Walters committed
376
#if HAVE_GPAC
377
        "yes",
Loren Merritt's avatar
Loren Merritt committed
378
#else
379
        "no",
Loren Merritt's avatar
Loren Merritt committed
380
#endif
381
        x264_bit_depth
382
      );
Fiona Glaser's avatar
Fiona Glaser committed
383 384 385
    H0( "Example usage:\n" );
    H0( "\n" );
    H0( "      Constant quality mode:\n" );
386
    H0( "            x264 --crf 24 -o <output> <input>\n" );
Fiona Glaser's avatar
Fiona Glaser committed
387 388
    H0( "\n" );
    H0( "      Two-pass with a bitrate of 1000kbps:\n" );
389 390
    H0( "            x264 --pass 1 --bitrate 1000 -o <output> <input>\n" );
    H0( "            x264 --pass 2 --bitrate 1000 -o <output> <input>\n" );
Fiona Glaser's avatar
Fiona Glaser committed
391 392
    H0( "\n" );
    H0( "      Lossless:\n" );
Fiona Glaser's avatar
Fiona Glaser committed
393
    H0( "            x264 --qp 0 -o <output> <input>\n" );
Fiona Glaser's avatar
Fiona Glaser committed
394 395
    H0( "\n" );
    H0( "      Maximum PSNR at the cost of speed and visual quality:\n" );
396
    H0( "            x264 --preset placebo --tune psnr -o <output> <input>\n" );
Fiona Glaser's avatar
Fiona Glaser committed
397 398
    H0( "\n" );
    H0( "      Constant bitrate at 1000kbps with a 2 second-buffer:\n");
399
    H0( "            x264 --vbv-bufsize 2000 --bitrate 1000 -o <output> <input>\n" );
Fiona Glaser's avatar
Fiona Glaser committed
400
    H0( "\n" );
401 402
    H0( "Presets:\n" );
    H0( "\n" );
403
    H0( "      --profile               Force the limits of an H.264 profile\n"
404
        "                                  Overrides all settings.\n" );
405 406
    H2( "                                  - baseline:\n"
        "                                    --no-8x8dct --bframes 0 --no-cabac\n"
407 408 409
        "                                    --cqm flat --weightp 0\n"
        "                                    No interlaced.\n"
        "                                    No lossless.\n"
410
        "                                  - main:\n"
411 412
        "                                    --no-8x8dct --cqm flat\n"
        "                                    No lossless.\n"
413
        "                                  - high:\n"
414 415 416 417 418
        "                                    No lossless.\n"
        "                                  - high10:\n"
        "                                    No lossless.\n"
        "                                    Support for bit depth 8-10.\n" );
        else H0( "                                  - baseline,main,high,high10\n" );
419 420
    H0( "      --preset                Use a preset to select encoding settings [medium]\n"
        "                                  Overridden by user settings.\n" );
421
    H2( "                                  - ultrafast:\n"
422
        "                                    --no-8x8dct --aq-mode 0 --b-adapt 0\n"
423 424
        "                                    --bframes 0 --no-cabac --no-deblock\n"
        "                                    --no-mbtree --me dia --no-mixed-refs\n"
Fiona Glaser's avatar
Fiona Glaser committed
425 426 427
        "                                    --partitions none --rc-lookahead 0 --ref 1\n"
        "                                    --scenecut 0 --subme 0 --trellis 0\n"
        "                                    --no-weightb --weightp 0\n"
428
        "                                  - superfast:\n"
429
        "                                    --no-mbtree --me dia --no-mixed-refs\n"
Fiona Glaser's avatar
Fiona Glaser committed
430
        "                                    --partitions i8x8,i4x4 --rc-lookahead 0\n"
431
        "                                    --ref 1 --subme 1 --trellis 0 --weightp 1\n"
432
        "                                  - veryfast:\n"
Fiona Glaser's avatar
Fiona Glaser committed
433
        "                                    --no-mixed-refs --rc-lookahead 10\n"
434
        "                                    --ref 1 --subme 2 --trellis 0 --weightp 1\n"
435
        "                                  - faster:\n"
436 437
        "                                    --no-mixed-refs --rc-lookahead 20\n"
        "                                    --ref 2 --subme 4 --weightp 1\n"
438
        "                                  - fast:\n"
439
        "                                    --rc-lookahead 30 --ref 2 --subme 6\n"
440
        "                                    --weightp 1\n"
441
        "                                  - medium:\n"
442
        "                                    Default settings apply.\n"
443
        "                                  - slow:\n"
444 445
        "                                    --b-adapt 2 --direct auto --me umh\n"
        "                                    --rc-lookahead 50 --ref 5 --subme 8\n"
446
        "                                  - slower:\n"
447 448 449
        "                                    --b-adapt 2 --direct auto --me umh\n"
        "                                    --partitions all --rc-lookahead 60\n"
        "                                    --ref 8 --subme 9 --trellis 2\n"
450
        "                                  - veryslow:\n"
451
        "                                    --b-adapt 2 --bframes 8 --direct auto\n"
Fiona Glaser's avatar
Fiona Glaser committed
452
        "                                    --me umh --merange 24 --partitions all\n"
453 454
        "                                    --ref 16 --subme 10 --trellis 2\n"
        "                                    --rc-lookahead 60\n"
455
        "                                  - placebo:\n"
456 457
        "                                    --bframes 16 --b-adapt 2 --direct auto\n"
        "                                    --slow-firstpass --no-fast-pskip\n"
Fiona Glaser's avatar
Fiona Glaser committed
458
        "                                    --me tesa --merange 24 --partitions all\n"
459 460
        "                                    --rc-lookahead 60 --ref 16 --subme 10\n"
        "                                    --trellis 2\n" );
461 462
    else H0( "                                  - ultrafast,superfast,veryfast,faster,fast\n"
             "                                  - medium,slow,slower,veryslow,placebo\n" );
463 464 465 466 467 468
    H0( "      --tune                  Tune the settings for a particular type of source\n"
        "                              or situation\n"
        "                                  Overridden by user settings.\n"
        "                                  Multiple tunings are separated by commas.\n"
        "                                  Only one psy tuning can be used at a time.\n" );
    H2( "                                  - film (psy tuning):\n"
469
        "                                    --deblock -1:-1 --psy-rd <unset>:0.15\n"
470
        "                                  - animation (psy tuning):\n"
471
        "                                    --bframes {+2} --deblock 1:1\n"
472
        "                                    --psy-rd 0.4:<unset> --aq-strength 0.6\n"
473
        "                                    --ref {Double if >1 else 1}\n"
474
        "                                  - grain (psy tuning):\n"
475
        "                                    --aq-strength 0.5 --no-dct-decimate\n"
476
        "                                    --deadzone-inter 6 --deadzone-intra 6\n"
477 478 479
        "                                    --deblock -2:-2 --ipratio 1.1 \n"
        "                                    --pbratio 1.1 --psy-rd <unset>:0.25\n"
        "                                    --qcomp 0.8\n"
480 481 482
        "                                  - stillimage (psy tuning):\n"
        "                                    --aq-strength 1.2 --deblock -3:-3\n"
        "                                    --psy-rd 2.0:0.7\n"
483
        "                                  - psnr (psy tuning):\n"
484
        "                                    --aq-mode 0 --no-psy\n"
485
        "                                  - ssim (psy tuning):\n"
486 487 488 489
        "                                    --aq-mode 2 --no-psy\n"
        "                                  - fastdecode:\n"
        "                                    --no-cabac --no-deblock --no-weightb\n"
        "                                    --weightp 0\n"
490
        "                                  - zerolatency:\n"
Fiona Glaser's avatar
Fiona Glaser committed
491 492 493
        "                                    --bframes 0 --force-cfr --no-mbtree\n"
        "                                    --sync-lookahead 0 --sliced-threads\n"
        "                                    --rc-lookahead 0\n" );
494 495
    else H0( "                                  - psy tunings: film,animation,grain,\n"
             "                                                 stillimage,psnr,ssim\n"
496
             "                                  - other tunings: fastdecode,zerolatency\n" );
497
    H2( "      --slow-firstpass        Don't force these faster settings with --pass 1:\n"
498 499 500
        "                                  --no-8x8dct --me dia --partitions none\n"
        "                                  --ref 1 --subme {2 if >2 else unchanged}\n"
        "                                  --trellis 0 --fast-pskip\n" );
501
    else H1( "      --slow-firstpass        Don't force faster settings with --pass 1\n" );
502
    H0( "\n" );
503 504
    H0( "Frame-type options:\n" );
    H0( "\n" );
505
    H0( "  -I, --keyint <integer or \"infinite\"> Maximum GOP size [%d]\n", defaults->i_keyint_max );
506
    H2( "  -i, --min-keyint <integer>  Minimum GOP size [auto]\n" );
Fiona Glaser's avatar
Fiona Glaser committed
507 508
    H2( "      --no-scenecut           Disable adaptive I-frame decision\n" );
    H2( "      --scenecut <integer>    How aggressively to insert extra I-frames [%d]\n", defaults->i_scenecut_threshold );
Fiona Glaser's avatar
Fiona Glaser committed
509
    H2( "      --intra-refresh         Use Periodic Intra Refresh instead of IDR frames\n" );
Fiona Glaser's avatar
Fiona Glaser committed
510
    H1( "  -b, --bframes <integer>     Number of B-frames between I and P [%d]\n", defaults->i_bframe );
Fiona Glaser's avatar
Fiona Glaser committed
511
    H1( "      --b-adapt <integer>     Adaptive B-frame decision method [%d]\n"
512 513 514 515
        "                                  Higher values may lower threading efficiency.\n"
        "                                  - 0: Disabled\n"
        "                                  - 1: Fast\n"
        "                                  - 2: Optimal (slow with high --bframes)\n", defaults->i_bframe_adaptive );
Fiona Glaser's avatar
Fiona Glaser committed
516
    H2( "      --b-bias <integer>      Influences how often B-frames are used [%d]\n", defaults->i_bframe_bias );
517 518
    H1( "      --b-pyramid <string>    Keep some B-frames as references [%s]\n"
        "                                  - none: Disabled\n"
Fiona Glaser's avatar
Fiona Glaser committed
519
        "                                  - strict: Strictly hierarchical pyramid\n"
520 521
        "                                  - normal: Non-strict (not Blu-ray compatible)\n",
        strtable_lookup( x264_b_pyramid_names, defaults->i_bframe_pyramid ) );
Lamont Alston's avatar
Lamont Alston committed
522
    H1( "      --open-gop <string>     Use recovery points to close GOPs [none]\n"
523 524 525 526
        "                                  - none: closed GOPs only\n"
        "                                  - normal: standard open GOPs\n"
        "                                            (not Blu-ray compatible)\n"
        "                                  - bluray: Blu-ray-compatible open GOPs\n"
Lamont Alston's avatar
Lamont Alston committed
527
        "                              Only available with b-frames\n" );
Fiona Glaser's avatar
Fiona Glaser committed
528 529
    H1( "      --no-cabac              Disable CABAC\n" );
    H1( "  -r, --ref <integer>         Number of reference frames [%d]\n", defaults->i_frame_reference );
530
    H1( "      --no-deblock            Disable loop filter\n" );
Fiona Glaser's avatar
Fiona Glaser committed
531
    H1( "  -f, --deblock <alpha:beta>  Loop filter parameters [%d:%d]\n",
532
                                       defaults->i_deblocking_filter_alphac0, defaults->i_deblocking_filter_beta );
Fiona Glaser's avatar
Fiona Glaser committed
533
    H2( "      --slices <integer>      Number of slices per frame; forces rectangular\n"
Fiona Glaser's avatar
Fiona Glaser committed
534
        "                              slices and is overridden by other slicing options\n" );
Fiona Glaser's avatar
Fiona Glaser committed
535 536 537
    else H1( "      --slices <integer>      Number of slices per frame\n" );
    H2( "      --slice-max-size <integer> Limit the size of each slice in bytes\n");
    H2( "      --slice-max-mbs <integer> Limit the size of each slice in macroblocks\n");
538 539
    H0( "      --tff                   Enable interlaced mode (top field first)\n" );
    H0( "      --bff                   Enable interlaced mode (bottom field first)\n" );
540
    H2( "      --constrained-intra     Enable constrained intra prediction.\n" );
Kieran Kunhya's avatar
Kieran Kunhya committed
541 542 543 544 545
    H0( "      --pulldown <string>     Use soft pulldown to change frame rate\n"
        "                                  - none, 22, 32, 64, double, triple, euro (requires cfr input)\n" );
    H2( "      --fake-interlaced       Flag stream as interlaced but encode progressive.\n"
        "                              Makes it possible to encode 25p and 30p Blu-Ray\n"
        "                              streams. Ignored in interlaced mode.\n" );
546 547 548 549 550 551 552
    H2( "      --frame-packing <integer> For stereoscopic videos define frame arrangement\n"
        "                                  - 0: checkerboard - pixels are alternatively from L and R\n"
        "                                  - 1: column alternation - L and R are interlaced by column\n"
        "                                  - 2: row alternation - L and R are interlaced by row\n"
        "                                  - 3: side by side - L is on the left, R on the right\n"
        "                                  - 4: top bottom - L is on top, R on bottom\n"
        "                                  - 5: frame alternation - one view per frame\n" );
553 554 555
    H0( "\n" );
    H0( "Ratecontrol:\n" );
    H0( "\n" );
556
    H1( "  -q, --qp <integer>          Force constant QP (0-%d, 0=lossless)\n", QP_MAX );
557
    H0( "  -B, --bitrate <integer>     Set bitrate (kbit/s)\n" );
Fiona Glaser's avatar
Fiona Glaser committed
558
    H0( "      --crf <float>           Quality-based VBR (%d-51) [%.1f]\n", 51 - QP_MAX, defaults->rc.f_rf_constant );
Fiona Glaser's avatar
Fiona Glaser committed
559
    H1( "      --rc-lookahead <integer> Number of frames for frametype lookahead [%d]\n", defaults->rc.i_lookahead );
560 561
    H0( "      --vbv-maxrate <integer> Max local bitrate (kbit/s) [%d]\n", defaults->rc.i_vbv_max_bitrate );
    H0( "      --vbv-bufsize <integer> Set size of the VBV buffer (kbit) [%d]\n", defaults->rc.i_vbv_buffer_size );
Fiona Glaser's avatar
Fiona Glaser committed
562
    H2( "      --vbv-init <float>      Initial VBV buffer occupancy [%.1f]\n", defaults->rc.f_vbv_buffer_init );
Fiona Glaser's avatar
Fiona Glaser committed
563 564
    H2( "      --crf-max <float>       With CRF+VBV, limit RF to this value\n"
        "                                  May cause VBV underflows!\n" );
Fiona Glaser's avatar
Fiona Glaser committed
565 566 567
    H2( "      --qpmin <integer>       Set min QP [%d]\n", defaults->rc.i_qp_min );
    H2( "      --qpmax <integer>       Set max QP [%d]\n", defaults->rc.i_qp_max );
    H2( "      --qpstep <integer>      Set max QP step [%d]\n", defaults->rc.i_qp_step );
568
    H2( "      --ratetol <float>       Tolerance of ABR ratecontrol and VBV [%.1f]\n", defaults->rc.f_rate_tolerance );
Fiona Glaser's avatar
Fiona Glaser committed
569 570 571 572
    H2( "      --ipratio <float>       QP factor between I and P [%.2f]\n", defaults->rc.f_ip_factor );
    H2( "      --pbratio <float>       QP factor between P and B [%.2f]\n", defaults->rc.f_pb_factor );
    H2( "      --chroma-qp-offset <integer>  QP difference between chroma and luma [%d]\n", defaults->analyse.i_chroma_qp_offset );
    H2( "      --aq-mode <integer>     AQ method [%d]\n"
573
        "                                  - 0: Disabled\n"
Anton Mitrofanov's avatar
Anton Mitrofanov committed
574 575
        "                                  - 1: Variance AQ (complexity mask)\n"
        "                                  - 2: Auto-variance AQ (experimental)\n", defaults->rc.i_aq_mode );
Fiona Glaser's avatar
Fiona Glaser committed
576 577 578
    H1( "      --aq-strength <float>   Reduces blocking and blurring in flat and\n"
        "                              textured areas. [%.1f]\n", defaults->rc.f_aq_strength );
    H1( "\n" );
Fiona Glaser's avatar
Fiona Glaser committed
579 580
    H0( "  -p, --pass <integer>        Enable multipass ratecontrol\n"
        "                                  - 1: First pass, creates stats file\n"
Fiona Glaser's avatar
Fiona Glaser committed
581 582 583 584 585 586 587 588 589
        "                                  - 2: Last pass, does not overwrite stats file\n" );
    H2( "                                  - 3: Nth pass, overwrites stats file\n" );
    H1( "      --stats <string>        Filename for 2 pass stats [\"%s\"]\n", defaults->rc.psz_stat_out );
    H2( "      --no-mbtree             Disable mb-tree ratecontrol.\n");
    H2( "      --qcomp <float>         QP curve compression [%.2f]\n", defaults->rc.f_qcompress );
    H2( "      --cplxblur <float>      Reduce fluctuations in QP (before curve compression) [%.1f]\n", defaults->rc.f_complexity_blur );
    H2( "      --qblur <float>         Reduce fluctuations in QP (after curve compression) [%.1f]\n", defaults->rc.f_qblur );
    H2( "      --zones <zone0>/<zone1>/...  Tweak the bitrate of regions of the video\n" );
    H2( "                              Each zone is of the form\n"
590 591 592 593
        "                                  <start frame>,<end frame>,<option>\n"
        "                                  where <option> is either\n"
        "                                      q=<integer> (force QP)\n"
        "                                  or  b=<float> (bitrate multiplier)\n" );
594
    H2( "      --qpfile <string>       Force frametypes and QPs for some or all frames\n"
595
        "                              Format of each line: framenumber frametype QP\n"
Fiona Glaser's avatar
Fiona Glaser committed
596
        "                              QP is optional (none lets x264 choose). Frametypes: I,i,K,P,B,b.\n"
Lamont Alston's avatar
Lamont Alston committed
597
        "                                  K=<I or i> depending on open-gop setting\n"
598
        "                              QPs are restricted by qpmin/qpmax.\n" );
Fiona Glaser's avatar
Fiona Glaser committed
599 600 601 602
    H1( "\n" );
    H1( "Analysis:\n" );
    H1( "\n" );
    H1( "  -A, --partitions <string>   Partitions to consider [\"p8x8,b8x8,i8x8,i4x4\"]\n"
603 604 605
        "                                  - p8x8, p4x4, b8x8, i8x8, i4x4\n"
        "                                  - none, all\n"
        "                                  (p4x4 requires p8x8. i8x8 requires --8x8dct.)\n" );
Fiona Glaser's avatar
Fiona Glaser committed
606
    H1( "      --direct <string>       Direct MV prediction mode [\"%s\"]\n"
607 608
        "                                  - none, spatial, temporal, auto\n",
                                       strtable_lookup( x264_direct_pred_names, defaults->analyse.i_direct_mv_pred ) );
Fiona Glaser's avatar
Fiona Glaser committed
609
    H2( "      --no-weightb            Disable weighted prediction for B-frames\n" );
Fiona Glaser's avatar
Fiona Glaser committed
610
    H1( "      --weightp <integer>     Weighted prediction for P-frames [%d]\n"
Fiona Glaser's avatar
Fiona Glaser committed
611
        "                                  - 0: Disabled\n"
612 613
        "                                  - 1: Weighted refs\n"
        "                                  - 2: Weighted refs + Duplicates\n", defaults->analyse.i_weighted_pred );
Fiona Glaser's avatar
Fiona Glaser committed
614
    H1( "      --me <string>           Integer pixel motion estimation method [\"%s\"]\n",
615
                                       strtable_lookup( x264_motion_est_names, defaults->analyse.i_me_method ) );
Fiona Glaser's avatar
Fiona Glaser committed
616
    H2( "                                  - dia: diamond search, radius 1 (fast)\n"
617 618
        "                                  - hex: hexagonal search, radius 2\n"
        "                                  - umh: uneven multi-hexagon search\n"
619 620
        "                                  - esa: exhaustive search\n"
        "                                  - tesa: hadamard exhaustive search (slow)\n" );
Fiona Glaser's avatar
Fiona Glaser committed
621 622 623 624 625 626
    else H1( "                                  - dia, hex, umh\n" );
    H2( "      --merange <integer>     Maximum motion vector search range [%d]\n", defaults->analyse.i_me_range );
    H2( "      --mvrange <integer>     Maximum motion vector length [-1 (auto)]\n" );
    H2( "      --mvrange-thread <int>  Minimum buffer between threads [-1 (auto)]\n" );
    H1( "  -m, --subme <integer>       Subpixel motion estimation and mode decision [%d]\n", defaults->analyse.i_subpel_refine );
    H2( "                                  - 0: fullpel only (not recommended)\n"
627
        "                                  - 1: SAD mode decision, one qpel iteration\n"
628 629 630 631 632
        "                                  - 2: SATD mode decision\n"
        "                                  - 3-5: Progressively more qpel\n"
        "                                  - 6: RD mode decision for I/P-frames\n"
        "                                  - 7: RD mode decision for all frames\n"
        "                                  - 8: RD refinement for I/P-frames\n"
Fiona Glaser's avatar
Fiona Glaser committed
633 634
        "                                  - 9: RD refinement for all frames\n"
        "                                  - 10: QP-RD - requires trellis=2, aq-mode>0\n" );
Fiona Glaser's avatar
Fiona Glaser committed
635 636
    else H1( "                                  decision quality: 1=fast, 10=best.\n"  );
    H1( "      --psy-rd                Strength of psychovisual optimization [\"%.1f:%.1f\"]\n"
637
        "                                  #1: RD (requires subme>=6)\n"
638
        "                                  #2: Trellis (requires trellis, experimental)\n",
Loren Merritt's avatar
Loren Merritt committed
639
                                       defaults->analyse.f_psy_rd, defaults->analyse.f_psy_trellis );
Fiona Glaser's avatar
Fiona Glaser committed
640
    H2( "      --no-psy                Disable all visual optimizations that worsen\n"
Fiona Glaser's avatar
Fiona Glaser committed
641
        "                              both PSNR and SSIM.\n" );
Fiona Glaser's avatar
Fiona Glaser committed
642 643 644
    H2( "      --no-mixed-refs         Don't decide references on a per partition basis\n" );
    H2( "      --no-chroma-me          Ignore chroma in motion estimation\n" );
    H1( "      --no-8x8dct             Disable adaptive spatial transform size\n" );
Fiona Glaser's avatar
Fiona Glaser committed
645
    H1( "  -t, --trellis <integer>     Trellis RD quantization. [%d]\n"
646 647 648
        "                                  - 0: disabled\n"
        "                                  - 1: enabled only on the final encode of a MB\n"
        "                                  - 2: enabled on all mode decisions\n", defaults->analyse.i_trellis );
Fiona Glaser's avatar
Fiona Glaser committed
649 650 651 652 653 654 655 656
    H2( "      --no-fast-pskip         Disables early SKIP detection on P-frames\n" );
    H2( "      --no-dct-decimate       Disables coefficient thresholding on P-frames\n" );
    H1( "      --nr <integer>          Noise reduction [%d]\n", defaults->analyse.i_noise_reduction );
    H2( "\n" );
    H2( "      --deadzone-inter <int>  Set the size of the inter luma quantization deadzone [%d]\n", defaults->analyse.i_luma_deadzone[0] );
    H2( "      --deadzone-intra <int>  Set the size of the intra luma quantization deadzone [%d]\n", defaults->analyse.i_luma_deadzone[1] );
    H2( "                                  Deadzones should be in the range 0 - 32.\n" );
    H2( "      --cqm <string>          Preset quant matrices [\"flat\"]\n"
657
        "                                  - jvt, flat\n" );
Fiona Glaser's avatar
Fiona Glaser committed
658 659 660
    H1( "      --cqmfile <string>      Read custom quant matrices from a JM-compatible file\n" );
    H2( "                                  Overrides any other --cqm* options.\n" );
    H2( "      --cqm4 <list>           Set all 4x4 quant matrices\n"
661
        "                                  Takes a comma-separated list of 16 integers.\n" );
Fiona Glaser's avatar
Fiona Glaser committed
662
    H2( "      --cqm8 <list>           Set all 8x8 quant matrices\n"
663
        "                                  Takes a comma-separated list of 64 integers.\n" );
Fiona Glaser's avatar
Fiona Glaser committed
664
    H2( "      --cqm4i, --cqm4p, --cqm8i, --cqm8p\n"
665
        "                              Set both luma and chroma quant matrices\n" );
Fiona Glaser's avatar
Fiona Glaser committed
666
    H2( "      --cqm4iy, --cqm4ic, --cqm4py, --cqm4pc\n"
667
        "                              Set individual quant matrices\n" );
Fiona Glaser's avatar
Fiona Glaser committed
668 669 670 671 672 673
    H2( "\n" );
    H2( "Video Usability Info (Annex E):\n" );
    H2( "The VUI settings are not used by the encoder but are merely suggestions to\n" );
    H2( "the playback equipment. See doc/vui.txt for details. Use at your own risk.\n" );
    H2( "\n" );
    H2( "      --overscan <string>     Specify crop overscan setting [\"%s\"]\n"
674 675
        "                                  - undef, show, crop\n",
                                       strtable_lookup( x264_overscan_names, defaults->vui.i_overscan ) );
Fiona Glaser's avatar
Fiona Glaser committed
676
    H2( "      --videoformat <string>  Specify video format [\"%s\"]\n"
677 678
        "                                  - component, pal, ntsc, secam, mac, undef\n",
                                       strtable_lookup( x264_vidformat_names, defaults->vui.i_vidformat ) );
Fiona Glaser's avatar
Fiona Glaser committed
679
    H2( "      --fullrange <string>    Specify full range samples setting [\"%s\"]\n"
680 681
        "                                  - off, on\n",
                                       strtable_lookup( x264_fullrange_names, defaults->vui.b_fullrange ) );
Fiona Glaser's avatar
Fiona Glaser committed
682
    H2( "      --colorprim <string>    Specify color primaries [\"%s\"]\n"
683 684 685
        "                                  - undef, bt709, bt470m, bt470bg\n"
        "                                    smpte170m, smpte240m, film\n",
                                       strtable_lookup( x264_colorprim_names, defaults->vui.i_colorprim ) );
Fiona Glaser's avatar
Fiona Glaser committed
686
    H2( "      --transfer <string>     Specify transfer characteristics [\"%s\"]\n"
687 688 689
        "                                  - undef, bt709, bt470m, bt470bg, linear,\n"
        "                                    log100, log316, smpte170m, smpte240m\n",
                                       strtable_lookup( x264_transfer_names, defaults->vui.i_transfer ) );
Fiona Glaser's avatar
Fiona Glaser committed
690
    H2( "      --colormatrix <string>  Specify color matrix setting [\"%s\"]\n"
691 692 693
        "                                  - undef, bt709, fcc, bt470bg\n"
        "                                    smpte170m, smpte240m, GBR, YCgCo\n",
                                       strtable_lookup( x264_colmatrix_names, defaults->vui.i_colmatrix ) );
Fiona Glaser's avatar
Fiona Glaser committed
694
    H2( "      --chromaloc <integer>   Specify chroma sample location (0 to 5) [%d]\n",
695
                                       defaults->vui.i_chroma_loc );
696 697 698 699

    H2( "      --nal-hrd <string>      Signal HRD information (requires vbv-bufsize)\n"
        "                                  - none, vbr, cbr (cbr not allowed in .mp4)\n" );
    H2( "      --pic-struct            Force pic_struct in Picture Timing SEI\n" );
700 701
    H2( "      --crop-rect <string>    Add 'left,top,right,bottom' to the bitstream-level\n"
        "                              cropping rectangle\n" );
702

703 704 705 706
    H0( "\n" );
    H0( "Input/Output:\n" );
    H0( "\n" );
    H0( "  -o, --output                Specify output file\n" );
707 708 709 710
    H1( "      --muxer <string>        Specify output container format [\"%s\"]\n"
        "                                  - %s\n", muxer_names[0], stringify_names( buf, muxer_names ) );
    H1( "      --demuxer <string>      Specify input container format [\"%s\"]\n"
        "                                  - %s\n", demuxer_names[0], stringify_names( buf, demuxer_names ) );
711 712
    H1( "      --input-csp <string>    Specify input colorspace format for raw input\n" );
    print_csp_names( longhelp );
713
    H1( "      --input-depth <integer> Specify input bit depth for raw input\n" );
714
    H1( "      --input-res <intxint>   Specify input resolution (width x height)\n" );
715
    H1( "      --index <string>        Filename for input index file\n" );
716 717 718 719 720
    H0( "      --sar width:height      Specify Sample Aspect Ratio\n" );
    H0( "      --fps <float|rational>  Specify framerate\n" );
    H0( "      --seek <integer>        First frame to encode\n" );
    H0( "      --frames <integer>      Maximum number of frames to encode\n" );
    H0( "      --level <string>        Specify level (as defined by Annex A)\n" );
Fiona Glaser's avatar
Fiona Glaser committed
721 722 723
    H1( "\n" );
    H1( "  -v, --verbose               Print stats for each frame\n" );
    H1( "      --no-progress           Don't show the progress indicator while encoding\n" );
724
    H0( "      --quiet                 Quiet Mode\n" );
725 726 727
    H1( "      --log-level <string>    Specify the maximum level of logging [\"%s\"]\n"
        "                                  - %s\n", strtable_lookup( log_level_names, cli_log_level - X264_LOG_NONE ),
                                       stringify_names( buf, log_level_names ) );
Fiona Glaser's avatar
Fiona Glaser committed
728 729 730
    H1( "      --psnr                  Enable PSNR computation\n" );
    H1( "      --ssim                  Enable SSIM computation\n" );
    H1( "      --threads <integer>     Force a specific number of threads\n" );
731
    H2( "      --sliced-threads        Low-latency but lower-efficiency threading\n" );
Fiona Glaser's avatar
Fiona Glaser committed
732 733 734 735 736 737 738 739 740
    H2( "      --thread-input          Run Avisynth in its own thread\n" );
    H2( "      --sync-lookahead <integer> Number of buffer frames for threaded lookahead\n" );
    H2( "      --non-deterministic     Slightly improve quality of SMP, at the cost of repeatability\n" );
    H2( "      --asm <integer>         Override CPU detection\n" );
    H2( "      --no-asm                Disable all CPU optimizations\n" );
    H2( "      --visualize             Show MB types overlayed on the encoded video\n" );
    H2( "      --dump-yuv <string>     Save reconstructed frames\n" );
    H2( "      --sps-id <integer>      Set SPS and PPS id numbers [%d]\n", defaults->i_sps_id );
    H2( "      --aud                   Use access unit delimiters\n" );
741
    H2( "      --force-cfr             Force constant framerate timestamp generation\n" );
Yusuke Nakamura's avatar
Yusuke Nakamura committed
742 743 744 745 746
    H2( "      --tcfile-in <string>    Force timestamp generation with timecode file\n" );
    H2( "      --tcfile-out <string>   Output timecode v2 file from input timestamps\n" );
    H2( "      --timebase <int/int>    Specify timebase numerator and denominator\n"
        "                 <integer>    Specify timebase numerator for input timecode file\n"
        "                              or specify timebase denominator for other input\n" );
747
    H2( "      --dts-compress          Eliminate initial delay with container DTS hack\n" );
748
    H0( "\n" );
749 750
    H0( "Filtering:\n" );
    H0( "\n" );
751 752 753 754
    H0( "      --vf, --video-filter <filter0>/<filter1>/... Apply video filtering to the input file\n" );
    H0( "\n" );
    H0( "      Filter options may be specified in <filter>:<option>=<value> format.\n" );
    H0( "\n" );
755 756 757 758
    H0( "      Available filters:\n" );
    x264_register_vid_filters();
    x264_vid_filter_help( longhelp );
    H0( "\n" );
Laurent Aimar's avatar
Laurent Aimar committed
759 760
}

Anton Mitrofanov's avatar
Anton Mitrofanov committed
761 762
enum
{
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
    OPT_FRAMES = 256,
    OPT_SEEK,
    OPT_QPFILE,
    OPT_THREAD_INPUT,
    OPT_QUIET,
    OPT_NOPROGRESS,
    OPT_VISUALIZE,
    OPT_LONGHELP,
    OPT_PROFILE,
    OPT_PRESET,
    OPT_TUNE,
    OPT_SLOWFIRSTPASS,
    OPT_FULLHELP,
    OPT_FPS,
    OPT_MUXER,
    OPT_DEMUXER,
    OPT_INDEX,
    OPT_INTERLACED,
    OPT_TCFILE_IN,
    OPT_TCFILE_OUT,
    OPT_TIMEBASE,
    OPT_PULLDOWN,
785 786 787
    OPT_LOG_LEVEL,
    OPT_VIDEO_FILTER,
    OPT_INPUT_RES,
788
    OPT_INPUT_CSP,
789 790
    OPT_INPUT_DEPTH,
    OPT_DTS_COMPRESSION
791
} OptionsOPT;
792 793 794 795 796 797

static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw";
static struct option long_options[] =
{
    { "help",              no_argument, NULL, 'h' },
    { "longhelp",          no_argument, NULL, OPT_LONGHELP },
Fiona Glaser's avatar
Fiona Glaser committed
798
    { "fullhelp",          no_argument, NULL, OPT_FULLHELP },
799 800 801 802 803 804 805 806 807 808
    { "version",           no_argument, NULL, 'V' },
    { "profile",     required_argument, NULL, OPT_PROFILE },
    { "preset",      required_argument, NULL, OPT_PRESET },
    { "tune",        required_argument, NULL, OPT_TUNE },
    { "slow-firstpass",    no_argument, NULL, OPT_SLOWFIRSTPASS },
    { "bitrate",     required_argument, NULL, 'B' },
    { "bframes",     required_argument, NULL, 'b' },
    { "b-adapt",     required_argument, NULL, 0 },
    { "no-b-adapt",        no_argument, NULL, 0 },
    { "b-bias",      required_argument, NULL, 0 },
809
    { "b-pyramid",   required_argument, NULL, 0 },
Lamont Alston's avatar
Lamont Alston committed
810
    { "open-gop",    required_argument, NULL, 0 },
811 812
    { "min-keyint",  required_argument, NULL, 'i' },
    { "keyint",      required_argument, NULL, 'I' },
Fiona Glaser's avatar
Fiona Glaser committed
813
    { "intra-refresh",     no_argument, NULL, 0 },
814 815 816 817 818 819
    { "scenecut",    required_argument, NULL, 0 },
    { "no-scenecut",       no_argument, NULL, 0 },
    { "nf",                no_argument, NULL, 0 },
    { "no-deblock",        no_argument, NULL, 0 },
    { "filter",      required_argument, NULL, 0 },
    { "deblock",     required_argument, NULL, 'f' },
820
    { "interlaced",        no_argument, NULL, OPT_INTERLACED },
821 822
    { "tff",               no_argument, NULL, OPT_INTERLACED },
    { "bff",               no_argument, NULL, OPT_INTERLACED },
823
    { "no-interlaced",     no_argument, NULL, OPT_INTERLACED },
824
    { "constrained-intra", no_argument, NULL, 0 },
825 826 827 828 829 830 831
    { "cabac",             no_argument, NULL, 0 },
    { "no-cabac",          no_argument, NULL, 0 },
    { "qp",          required_argument, NULL, 'q' },
    { "qpmin",       required_argument, NULL, 0 },
    { "qpmax",       required_argument, NULL, 0 },
    { "qpstep",      required_argument, NULL, 0 },
    { "crf",         required_argument, NULL, 0 },
Fiona Glaser's avatar
Fiona Glaser committed
832
    { "rc-lookahead",required_argument, NULL, 0 },
833 834 835 836
    { "ref",         required_argument, NULL, 'r' },
    { "asm",         required_argument, NULL, 0 },
    { "no-asm",            no_argument, NULL, 0 },
    { "sar",         required_argument, NULL, 0 },
837
    { "fps",         required_argument, NULL, OPT_FPS },
838 839 840
    { "frames",      required_argument, NULL, OPT_FRAMES },
    { "seek",        required_argument, NULL, OPT_SEEK },
    { "output",      required_argument, NULL, 'o' },
841 842 843 844 845
    { "muxer",       required_argument, NULL, OPT_MUXER },
    { "demuxer",     required_argument, NULL, OPT_DEMUXER },
    { "stdout",      required_argument, NULL, OPT_MUXER },
    { "stdin",       required_argument, NULL, OPT_DEMUXER },
    { "index",       required_argument, NULL, OPT_INDEX },
846 847 848 849 850
    { "analyse",     required_argument, NULL, 0 },
    { "partitions",  required_argument, NULL, 'A' },
    { "direct",      required_argument, NULL, 0 },
    { "weightb",           no_argument, NULL, 'w' },
    { "no-weightb",        no_argument, NULL, 0 },
Dylan Yudaken's avatar
Dylan Yudaken committed
851
    { "weightp",     required_argument, NULL, 0 },
852 853 854 855 856 857
    { "me",          required_argument, NULL, 0 },
    { "merange",     required_argument, NULL, 0 },
    { "mvrange",     required_argument, NULL, 0 },
    { "mvrange-thread", required_argument, NULL, 0 },
    { "subme",       required_argument, NULL, 'm' },
    { "psy-rd",      required_argument, NULL, 0 },
Fiona Glaser's avatar
Fiona Glaser committed
858 859
    { "no-psy",            no_argument, NULL, 0 },
    { "psy",               no_argument, NULL, 0 },
860 861 862
    { "mixed-refs",        no_argument, NULL, 0 },
    { "no-mixed-refs",     no_argument, NULL, 0 },
    { "no-chroma-me",      no_argument, NULL, 0 },
863
    { "8x8dct",            no_argument, NULL, '8' },
864 865 866 867 868 869 870
    { "no-8x8dct",         no_argument, NULL, 0 },
    { "trellis",     required_argument, NULL, 't' },
    { "fast-pskip",        no_argument, NULL, 0 },
    { "no-fast-pskip",     no_argument, NULL, 0 },
    { "no-dct-decimate",   no_argument, NULL, 0 },
    { "aq-strength", required_argument, NULL, 0 },
    { "aq-mode",     required_argument, NULL, 0 },
871 872
    { "deadzone-inter", required_argument, NULL, 0 },
    { "deadzone-intra", required_argument, NULL, 0 },
873 874 875 876
    { "level",       required_argument, NULL, 0 },
    { "ratetol",     required_argument, NULL, 0 },
    { "vbv-maxrate", required_argument, NULL, 0 },
    { "vbv-bufsize", required_argument, NULL, 0 },
Fiona Glaser's avatar
Fiona Glaser committed
877 878
    { "vbv-init",    required_argument, NULL, 0 },
    { "crf-max",     required_argument, NULL, 0 },
879 880 881 882 883 884
    { "ipratio",     required_argument, NULL, 0 },
    { "pbratio",     required_argument, NULL, 0 },
    { "chroma-qp-offset", required_argument, NULL, 0 },
    { "pass",        required_argument, NULL, 'p' },
    { "stats",       required_argument, NULL, 0 },
    { "qcomp",       required_argument, NULL, 0 },
Fiona Glaser's avatar
Fiona Glaser committed
885 886
    { "mbtree",            no_argument, NULL, 0 },
    { "no-mbtree",         no_argument, NULL, 0 },
887 888 889 890 891
    { "qblur",       required_argument, NULL, 0 },
    { "cplxblur",    required_argument, NULL, 0 },
    { "zones",       required_argument, NULL, 0 },
    { "qpfile",      required_argument, NULL, OPT_QPFILE },
    { "threads",     required_argument, NULL, 0 },
892 893
    { "sliced-threads",    no_argument, NULL, 0 },
    { "no-sliced-threads", no_argument, NULL, 0 },
Fiona Glaser's avatar
Fiona Glaser committed
894 895 896
    { "slice-max-size",    required_argument, NULL, 0 },
    { "slice-max-mbs",     required_argument, NULL, 0 },
    { "slices",            required_argument, NULL, 0 },
897
    { "thread-input",      no_argument, NULL, OPT_THREAD_INPUT },
Steven Walters's avatar
Steven Walters committed
898
    { "sync-lookahead",    required_argument, NULL, 0 },
899 900 901 902 903
    { "non-deterministic", no_argument, NULL, 0 },
    { "psnr",              no_argument, NULL, 0 },
    { "ssim",              no_argument, NULL, 0 },
    { "quiet",             no_argument, NULL, OPT_QUIET },
    { "verbose",           no_argument, NULL, 'v' },
904
    { "log-level",   required_argument, NULL, OPT_LOG_LEVEL },
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
    { "no-progress",       no_argument, NULL, OPT_NOPROGRESS },
    { "visualize",         no_argument, NULL, OPT_VISUALIZE },
    { "dump-yuv",    required_argument, NULL, 0 },
    { "sps-id",      required_argument, NULL, 0 },
    { "aud",               no_argument, NULL, 0 },
    { "nr",          required_argument, NULL, 0 },
    { "cqm",         required_argument, NULL, 0 },
    { "cqmfile",     required_argument, NULL, 0 },
    { "cqm4",        required_argument, NULL, 0 },
    { "cqm4i",       required_argument, NULL, 0 },
    { "cqm4iy",      required_argument, NULL, 0 },
    { "cqm4ic",      required_argument, NULL, 0 },
    { "cqm4p",       required_argument, NULL, 0 },
    { "cqm4py",      required_argument, NULL, 0 },
    { "cqm4pc",      required_argument, NULL, 0 },
    { "cqm8",        required_argument, NULL, 0 },
    { "cqm8i",       required_argument, NULL, 0 },
    { "cqm8p",       required_argument, NULL, 0 },
    { "overscan",    required_argument, NULL, 0 },
    { "videoformat", required_argument, NULL, 0 },
    { "fullrange",   required_argument, NULL, 0 },
    { "colorprim",   required_argument, NULL, 0 },
    { "transfer",    required_argument, NULL, 0 },
    { "colormatrix", required_argument, NULL, 0 },
    { "chromaloc",   required_argument, NULL, 0 },
930
    { "force-cfr",         no_argument, NULL, 0 },
Yusuke Nakamura's avatar
Yusuke Nakamura committed
931 932 933
    { "tcfile-in",   required_argument, NULL, OPT_TCFILE_IN },
    { "tcfile-out",  required_argument, NULL, OPT_TCFILE_OUT },
    { "timebase",    required_argument, NULL, OPT_TIMEBASE },
934
    { "pic-struct",        no_argument, NULL, 0 },
935
    { "crop-rect",   required_argument, NULL, 0 },
936 937
    { "nal-hrd",     required_argument, NULL, 0 },
    { "pulldown",    required_argument, NULL, OPT_PULLDOWN },
Kieran Kunhya's avatar
Kieran Kunhya committed
938
    { "fake-interlaced",   no_argument, NULL, 0 },
939
    { "frame-packing",     required_argument, NULL, 0 },
940 941 942 943
    { "vf",          required_argument, NULL, OPT_VIDEO_FILTER },
    { "video-filter", required_argument, NULL, OPT_VIDEO_FILTER },
    { "input-res",   required_argument, NULL, OPT_INPUT_RES },
    { "input-csp",   required_argument, NULL, OPT_INPUT_CSP },
944
    { "input-depth", required_argument, NULL, OPT_INPUT_DEPTH },
945
    { "dts-compress",      no_argument, NULL, OPT_DTS_COMPRESSION },
946 947 948
    {0, 0, 0, 0}
};

949
static int select_output( const char *muxer, char *filename, x264_param_t *param )
950
{
951
    const char *ext = get_filename_extension( filename );
952 953
    if( !strcmp( filename, "-" ) || strcasecmp( muxer, "auto" ) )
        ext = muxer;
954

Fiona Glaser's avatar
Fiona Glaser committed
955
    if( !strcasecmp( ext, "mp4" ) )
956
    {
Steven Walters's avatar
Steven Walters committed
957
#if HAVE_GPAC
958 959 960
        output = mp4_output;
        param->b_annexb = 0;
        param->b_repeat_headers = 0;
961 962
        if( param->i_nal_hrd == X264_NAL_HRD_CBR )
        {
963
            x264_cli_log( "x264", X264_LOG_WARNING, "cbr nal-hrd is not compatible with mp4\n" );
964 965
            param->i_nal_hrd = X264_NAL_HRD_VBR;
        }
966
#else
967
        x264_cli_log( "x264", X264_LOG_ERROR, "not compiled with MP4 output support\n" );
968 969 970
        return -1;
#endif
    }
971
    else if( !strcasecmp( ext, "mkv" ) )
972 973 974 975 976
    {
        output = mkv_output;
        param->b_annexb = 0;
        param->b_repeat_headers = 0;
    }
977
    else if( !strcasecmp( ext, "flv" ) )
Kieran Kunhya's avatar
Kieran Kunhya committed
978 979 980
    {
        output = flv_output;
        param->b_annexb = 0;
981
        param->b_repeat_headers = 0;
Kieran Kunhya's avatar
Kieran Kunhya committed
982
    }
983 984 985 986 987
    else
        output = raw_output;
    return 0;
}

988 989
static int select_input( const char *demuxer, char *used_demuxer, char *filename,
                         hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
990
{
991
    int b_auto = !strcasecmp( demuxer, "auto" );
992 993
    const char *ext = b_auto ? get_filename_extension( filename ) : "";
    int b_regular = strcmp( filename, "-" );
994
    if( !b_regular && b_auto )
995
        ext = "raw";
996
    b_regular = b_regular && x264_is_regular_file_path( filename );
997 998 999
    if( b_regular )
    {
        FILE *f = fopen( filename, "r" );
1000
        if( f )
1001
        {
1002 1003
            b_regular = x264_is_regular_file( f );
            fclose( f );
1004 1005 1006
        }
    }
    const char *module = b_auto ? ext : demuxer;
1007

1008
    if( !strcasecmp( module, "avs" ) || !strcasecmp( ext, "d2v" ) || !strcasecmp( ext, "dga" ) )
1009
    {
Steven Walters's avatar
Steven Walters committed
1010
#if HAVE_AVS
1011
        input = avs_input;
1012
        module = "avs";
1013
#else
1014
        x264_cli_log( "x264", X264_LOG_ERROR, "not compiled with AVS input support\n" );
1015 1016 1017
        return -1;
#endif
    }
1018
    else if( !strcasecmp( module, "y4m" ) )
1019
        input = y4m_input;
1020 1021
    else if( !strcasecmp( module, "raw" ) || !strcasecmp( ext, "yuv" ) )
        input = raw_input;
1022
    else
1023
    {
Steven Walters's avatar
Steven Walters committed
1024
#if HAVE_FFMS
1025 1026
        if( b_regular && (b_auto || !strcasecmp( demuxer, "ffms" )) &&
            !ffms_input.open_file( filename, p_handle, info, opt ) )
1027
        {
1028 1029 1030
            module = "ffms";
            b_auto = 0;
            input = ffms_input;
1031
        }
1032
#endif
Steven Walters's avatar
Steven Walters committed
1033
#if HAVE_LAVF
1034
        if( (b_auto || !strcasecmp( demuxer, "lavf" )) &&
1035
            !lavf_input.open_file( filename, p_handle, info, opt ) )
1036
        {
1037 1038 1039
            module = "lavf";
            b_auto = 0;
            input = lavf_input;
1040
        }
1041
#endif
Steven Walters's avatar
Steven Walters committed
1042
#if HAVE_AVS
1043 1044
        if( b_regular && (b_auto || !strcasecmp( demuxer, "avs" )) &&
            !avs_input.open_file( filename, p_handle, info, opt ) )
1045
        {
1046 1047 1048
            module = "avs";
            b_auto = 0;
            input = avs_input;
1049
        }
1050
#endif
1051
        if( b_auto && !raw_input.open_file( filename, p_handle, info, opt ) )
1052
        {
1053
            module = "raw";
1054
            b_auto = 0;
1055
            input = raw_input;
1056 1057
        }

1058
        FAIL_IF_ERROR( !(*p_handle), "could not open input file `%s' via any method!\n", filename )
1059
    }
1060
    strcpy( used_demuxer, module );
1061 1062 1063 1064

    return 0;
}