x264.c 62.3 KB
Newer Older
Laurent Aimar's avatar
Laurent Aimar committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*****************************************************************************
 * x264: h264 encoder/decoder testing program.
 *****************************************************************************
 * Copyright (C) 2003 Laurent Aimar
 * $Id: x264.c,v 1.1 2004/06/03 19:24:12 fenrir Exp $
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *
 * 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
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

Loren Merritt's avatar
Loren Merritt committed
24
25
26
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64

Laurent Aimar's avatar
Laurent Aimar committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <math.h>

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

#ifdef _MSC_VER
#include <io.h>     /* _setmode() */
#include <fcntl.h>  /* _O_BINARY */
#endif

Loren Merritt's avatar
Loren Merritt committed
42
43
44
45
#ifndef _MSC_VER
#include "config.h"
#endif

Loren Merritt's avatar
Loren Merritt committed
46
#ifdef AVIS_INPUT
47
48
#include <windows.h>
#include <vfw.h>
Loren Merritt's avatar
Loren Merritt committed
49
50
51
#endif

#ifdef MP4_OUTPUT
52
#include <gpac/isomedia.h>
53
54
#endif

55

56
#include "common/common.h"
57
#include "x264.h"
58
59
60

#include "matroska.h"

Laurent Aimar's avatar
Laurent Aimar committed
61
62
63
#define DATA_MAX 3000000
uint8_t data[DATA_MAX];

64
65
typedef void *hnd_t;

Laurent Aimar's avatar
Laurent Aimar committed
66
/* Ctrl-C handler */
Loren Merritt's avatar
Loren Merritt committed
67
68
static int     b_ctrl_c = 0;
static int     b_exit_on_ctrl_c = 0;
Laurent Aimar's avatar
Laurent Aimar committed
69
70
static void    SigIntHandler( int a )
{
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
81
82
83
typedef struct {
    int b_decompress;
    int b_progress;
    int i_seek;
    hnd_t hin;
    hnd_t hout;
} cli_opt_t;

84
/* input file operation function pointers */
Loren Merritt's avatar
Loren Merritt committed
85
static int (*p_open_infile)( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
86
static int (*p_get_frame_total)( hnd_t handle, int i_width, int i_height );
Loren Merritt's avatar
Loren Merritt committed
87
static int (*p_read_frame)( x264_picture_t *p_pic, hnd_t handle, int i_frame, int i_width, int i_height );
Loren Merritt's avatar
Loren Merritt committed
88
static int (*p_close_infile)( hnd_t handle );
89
90
91

static int open_file_yuv( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
static int get_frame_total_yuv( hnd_t handle, int i_width, int i_height );
Loren Merritt's avatar
Loren Merritt committed
92
static int read_frame_yuv( x264_picture_t *p_pic, hnd_t handle, int i_frame, int i_width, int i_height );
93
94
95
96
97
static int close_file_yuv( hnd_t handle );

#ifdef AVIS_INPUT
static int open_file_avis( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
static int get_frame_total_avis( hnd_t handle, int i_width, int i_height );
Loren Merritt's avatar
Loren Merritt committed
98
static int read_frame_avis( x264_picture_t *p_pic, hnd_t handle, int i_frame, int i_width, int i_height );
99
100
101
static int close_file_avis( hnd_t handle );
#endif

Loren Merritt's avatar
Loren Merritt committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* output file operation function pointers */
static int (*p_open_outfile)( char *psz_filename, hnd_t *p_handle );
static int (*p_set_outfile_param)( hnd_t handle, x264_param_t *p_param );
static int (*p_write_nalu)( hnd_t handle, uint8_t *p_nal, int i_size );
static int (*p_set_eop)( hnd_t handle, x264_picture_t *p_picture );
static int (*p_close_outfile)( hnd_t handle );

static int open_file_bsf( char *psz_filename, hnd_t *p_handle );
static int set_param_bsf( hnd_t handle, x264_param_t *p_param );
static int write_nalu_bsf( hnd_t handle, uint8_t *p_nal, int i_size );
static int set_eop_bsf( hnd_t handle,  x264_picture_t *p_picture );
static int close_file_bsf( hnd_t handle );

#ifdef MP4_OUTPUT
static int open_file_mp4( char *psz_filename, hnd_t *p_handle );
static int set_param_mp4( hnd_t handle, x264_param_t *p_param );
static int write_nalu_mp4( hnd_t handle, uint8_t *p_nal, int i_size );
static int set_eop_mp4( hnd_t handle, x264_picture_t *p_picture );
static int close_file_mp4( hnd_t handle );
#endif

123
124
125
126
127
128
static int open_file_mkv( char *psz_filename, hnd_t *p_handle );
static int set_param_mkv( hnd_t handle, x264_param_t *p_param );
static int write_nalu_mkv( hnd_t handle, uint8_t *p_nal, int i_size );
static int set_eop_mkv( hnd_t handle, x264_picture_t *p_picture );
static int close_file_mkv( hnd_t handle );

129
static void Help( x264_param_t *defaults );
Loren Merritt's avatar
Loren Merritt committed
130
131
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
132

133

Laurent Aimar's avatar
Laurent Aimar committed
134
135
136
137
138
139
/****************************************************************************
 * main:
 ****************************************************************************/
int main( int argc, char **argv )
{
    x264_param_t param;
Loren Merritt's avatar
Loren Merritt committed
140
    cli_opt_t opt;
Laurent Aimar's avatar
Laurent Aimar committed
141
142
143
144
145
146
147
148
149

#ifdef _MSC_VER
    _setmode(_fileno(stdin), _O_BINARY);    /* thanks to Marcos Morais <morais at dee.ufcg.edu.br> */
    _setmode(_fileno(stdout), _O_BINARY);
#endif

    x264_param_default( &param );

    /* Parse command line */
Loren Merritt's avatar
Loren Merritt committed
150
    if( Parse( argc, argv, &param, &opt ) < 0 )
Laurent Aimar's avatar
Laurent Aimar committed
151
152
153
154
155
        return -1;

    /* Control-C handler */
    signal( SIGINT, SigIntHandler );

Loren Merritt's avatar
Loren Merritt committed
156
    return Encode( &param, &opt );
Laurent Aimar's avatar
Laurent Aimar committed
157
158
}

Loren Merritt's avatar
Loren Merritt committed
159
160
161
162
163
164
165
166
static const char * const overscan_str[] = { "undef", "show", "crop", NULL };
static const char * const vidformat_str[] = { "component", "pal", "ntsc", "secam", "mac", "undef", NULL };
static const char * const fullrange_str[] = { "off", "on", NULL };
static const char * const colorprim_str[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m", "smpte240m", "film", NULL };
static const char * const transfer_str[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100", "log316", NULL };
static const char * const colmatrix_str[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m", "smpte240m", "YCgCo", NULL };

static char const *strtable_lookup( const char * const table[], int index )
167
168
169
170
171
{
    int i = 0; while( table[i] ) i++;
    return ( ( index >= 0 && index < i ) ? table[ index ] : "???" );
}

Laurent Aimar's avatar
Laurent Aimar committed
172
173
174
/*****************************************************************************
 * Help:
 *****************************************************************************/
175
static void Help( x264_param_t *defaults )
Laurent Aimar's avatar
Laurent Aimar committed
176
177
{
    fprintf( stderr,
178
179
             "x264 core:%d%s\n"
             "Syntax: x264 [options] -o outfile infile [widthxheight]\n"
Loren Merritt's avatar
Loren Merritt committed
180
181
182
183
184
             "\n"
             "Infile can be raw YUV 4:2:0 (in which case resolution is required),\n"
             "  or AVI or Avisynth if compiled with AVIS support (%s).\n"
             "Outfile type is selected by filename:\n"
             " .264 -> Raw bytestream\n"
185
             " .mkv -> Matroska\n"
Loren Merritt's avatar
Loren Merritt committed
186
187
188
             " .mp4 -> MP4 if compiled with GPAC support (%s)\n"
             "\n"
             "Options:\n"
Laurent Aimar's avatar
Laurent Aimar committed
189
190
191
             "\n"
             "  -h, --help                  Print this help\n"
             "\n"
Loren Merritt's avatar
Loren Merritt committed
192
193
             "Frame-type options:\n"
             "\n"
Loren Merritt's avatar
Loren Merritt committed
194
             "  -I, --keyint <integer>      Maximum GOP size [%d]\n"
195
             "  -i, --min-keyint <integer>  Minimum GOP size [%d]\n"
Loren Merritt's avatar
Loren Merritt committed
196
             "      --scenecut <integer>    How aggressively to insert extra I-frames [%d]\n"
Loren Merritt's avatar
Loren Merritt committed
197
             "  -b, --bframes <integer>     Number of B-frames between I and P [%d]\n"
198
199
             "      --no-b-adapt            Disable adaptive B-frame decision\n"
             "      --b-bias <integer>      Influences how often B-frames are used [%d]\n"
200
             "      --b-pyramid             Keep some B-frames as references\n"
Laurent Aimar's avatar
Laurent Aimar committed
201
             "\n"
202
             "      --no-cabac              Disable CABAC\n"
203
             "  -r, --ref <integer>         Number of reference frames [%d]\n"
204
             "      --nf                    Disable loop filter\n"
Loren Merritt's avatar
Loren Merritt committed
205
             "  -f, --filter <alpha:beta>   Loop filter AlphaC0 and Beta parameters [%d:%d]\n"
206
             "\n"
Loren Merritt's avatar
Loren Merritt committed
207
208
             "Ratecontrol:\n"
             "\n"
Loren Merritt's avatar
Loren Merritt committed
209
             "  -q, --qp <integer>          Set QP (0=lossless) [%d]\n"
210
             "  -B, --bitrate <integer>     Set bitrate\n"
211
             "      --crf <integer>         Quality-based VBR (nominal QP)\n"
212
213
214
             "      --qpmin <integer>       Set min QP [%d]\n"
             "      --qpmax <integer>       Set max QP [%d]\n"
             "      --qpstep <integer>      Set max QP step [%d]\n"
Loren Merritt's avatar
Loren Merritt committed
215
216
217
218
219
             "      --ratetol <float>       Allowed variance of average bitrate [%.1f]\n"
             "      --vbv-maxrate <integer> Max local bitrate [%d]\n"
             "      --vbv-bufsize <integer> Size of VBV buffer [%d]\n"
             "      --vbv-init <float>      Initial VBV buffer occupancy [%.1f]\n"
             "\n"
220
221
             "      --ipratio <float>       QP factor between I and P [%.2f]\n"
             "      --pbratio <float>       QP factor between P and B [%.2f]\n"
222
             "      --chroma-qp-offset <integer>  QP difference between chroma and luma [%d]\n"
Laurent Aimar's avatar
Laurent Aimar committed
223
             "\n"
Loren Merritt's avatar
Loren Merritt committed
224
225
226
227
             "  -p, --pass <1|2|3>          Enable multipass ratecontrol:\n"
             "                                  - 1: First pass, creates stats file\n"
             "                                  - 2: Last pass, does not overwrite stats file\n"
             "                                  - 3: Nth pass, overwrites stats file\n"
228
229
             "      --stats <string>        Filename for 2 pass stats [\"%s\"]\n"
             "      --rceq <string>         Ratecontrol equation [\"%s\"]\n"
Loren Merritt's avatar
Loren Merritt committed
230
231
232
             "      --qcomp <float>         QP curve compression: 0.0 => CBR, 1.0 => CQP [%.2f]\n"
             "      --cplxblur <float>      Reduce fluctuations in QP (before curve compression) [%.1f]\n"
             "      --qblur <float>         Reduce fluctuations in QP (after curve compression) [%.1f]\n"
233
             "\n"
Loren Merritt's avatar
Loren Merritt committed
234
235
236
237
238
239
240
241
242
243
             "      --zones <zone0>/<zone1>/...\n"
             "                              Tweak the bitrate of some regions of the video\n"
             "                              Each zone is of the form\n"
             "                                  <start frame>,<end frame>,<option>\n"
             "                                  where <option> is either\n"
             "                                      q=<integer> (force QP)\n"
             "                                  or  b=<float> (bitrate multiplier)\n"
             "\n"
             "Analysis:\n"
             "\n"
244
245
             "  -A, --analyse <string>      Partitions to consider [\"p8x8,b8x8,i8x8,i4x4\"]\n"
             "                                  - p8x8, p4x4, b8x8, i8x8, i4x4\n"
Laurent Aimar's avatar
Laurent Aimar committed
246
             "                                  - none, all\n"
247
             "                                  (p4x4 requires p8x8. i8x8 requires --8x8dct.)\n"
Loren Merritt's avatar
Loren Merritt committed
248
             "      --direct <string>       Direct MV prediction mode [\"%s\"]\n"
249
             "                                  - none, spatial, temporal\n"
250
             "  -w, --weightb               Weighted prediction for B-frames\n"
251
252
253
             "      --me <string>           Integer pixel motion estimation method [\"%s\"]\n"
             "                                  - dia: diamond search, radius 1 (fast)\n"
             "                                  - hex: hexagonal search, radius 2\n"
254
255
             "                                  - umh: uneven multi-hexagon search\n"
             "                                  - esa: exhaustive search (slow)\n"
256
             "      --merange <integer>     Maximum motion vector search range [%d]\n"
257
258
             "  -m, --subme <integer>       Subpixel motion estimation and partition\n"
             "                                  decision quality: 1=fast, 6=best. [%d]\n"
259
             "      --b-rdo                 RD based mode decision for B-frames. Requires subme 6.\n"
Loren Merritt's avatar
Loren Merritt committed
260
             "      --mixed-refs            Decide references on a per partition basis\n"
261
             "      --no-chroma-me          Ignore chroma in motion estimation\n"
262
             "      --bime                  Jointly optimize both MVs in B-frames\n"
263
             "  -8, --8x8dct                Adaptive spatial transform size\n"
Loren Merritt's avatar
Loren Merritt committed
264
265
266
267
             "  -t, --trellis <integer>     Trellis RD quantization. Requires CABAC. [%d]\n"
             "                                  - 0: disabled\n"
             "                                  - 1: enabled only on the final encode of a MB\n"
             "                                  - 2: enabled on all mode decisions\n"
Loren Merritt's avatar
Loren Merritt committed
268
             "      --no-fast-pskip         Disables early SKIP detection on P-frames\n"
269
             "      --nr <integer>          Noise reduction [%d]\n"
Laurent Aimar's avatar
Laurent Aimar committed
270
             "\n"
Loren Merritt's avatar
Loren Merritt committed
271
272
             "      --cqm <string>          Preset quant matrices [\"flat\"]\n"
             "                                  - jvt, flat\n"
273
274
             "      --cqmfile <string>      Read quant matrices from a JM-compatible file\n"
             "                                  Overrides any other --cqm* options.\n"
Loren Merritt's avatar
Loren Merritt committed
275
276
277
278
279
280
281
282
283
             "      --cqm4 <list>           Set all 4x4 quant matrices\n"
             "                                  Takes a comma-separated list of 16 integers.\n"
             "      --cqm8 <list>           Set all 8x8 quant matrices\n"
             "                                  Takes a comma-separated list of 64 integers.\n"
             "      --cqm4i, --cqm4p, --cqm8i, --cqm8p\n"
             "                              Set both luma and chroma quant matrices\n"
             "      --cqm4iy, --cqm4ic, --cqm4py, --cqm4pc\n"
             "                              Set individual quant matrices\n"
             "\n"
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
             "Video Usability Info (Annex E):\n"
             "The VUI settings are not used by the encoder but are merely suggestions to\n"
             "the playback equipment. See doc/vui.txt for details. Use at your own risk.\n"
             "\n"
             "      --sar width:height      Specify Sample Aspect Ratio\n"
             "      --overscan <string>     Specify crop overscan setting [\"%s\"]\n"
             "                                  - undef, show, crop\n"
             "      --videoformat <string>  Specify video format [\"%s\"]\n"
             "                                  - component, pal, ntsc, secam, mac, undef\n"
             "      --fullrange <string>    Specify full range samples setting [\"%s\"]\n"
             "                                  - off, on\n"
             "      --colorprim <string>    Specify color primaries [\"%s\"]\n"
             "                                  - undef, bt709, bt470m, bt470bg\n"
             "                                    smpte170m, smpte240m, film\n"
             "      --transfer <string>     Specify transfer characteristics [\"%s\"]\n"
             "                                  - undef, bt709, bt470m, bt470bg, linear,\n"
             "                                    log100, log316, smpte170m, smpte240m\n"
             "      --colormatrix <string>  Specify color matrix setting [\"%s\"]\n"
             "                                  - undef, bt709, fcc, bt470bg\n"
             "                                    smpte170m, smpte240m, GBR, YCgCo\n"
             "      --chromaloc <integer>   Specify chroma sample location (0 to 5) [%d]\n"
             "\n"
Loren Merritt's avatar
Loren Merritt committed
306
307
             "Input/Output:\n"
             "\n"
308
             "      --level <string>        Specify level (as defined by Annex A)\n"
Loren Merritt's avatar
Loren Merritt committed
309
             "      --fps <float|rational>  Specify framerate\n"
Loren Merritt's avatar
Loren Merritt committed
310
             "      --seek <integer>        First frame to encode\n"
311
             "      --frames <integer>      Maximum number of frames to encode\n"
Laurent Aimar's avatar
Laurent Aimar committed
312
313
             "  -o, --output                Specify output file\n"
             "\n"
Loren Merritt's avatar
Loren Merritt committed
314
             "      --threads <integer>     Parallel encoding (uses slices)\n"
Loren Merritt's avatar
Loren Merritt committed
315
316
             "      --no-asm                Disable all CPU optimizations\n"
             "      --no-psnr               Disable PSNR computation\n"
317
             "      --quiet                 Quiet Mode\n"
318
             "  -v, --verbose               Print stats for each frame\n"
Loren Merritt's avatar
Loren Merritt committed
319
             "      --progress              Show a progress indicator while encoding\n"
Loren Merritt's avatar
Loren Merritt committed
320
             "      --visualize             Show MB types overlayed on the encoded video\n"
321
             "      --aud                   Use access unit delimiters\n"
Laurent Aimar's avatar
Laurent Aimar committed
322
             "\n",
323
            X264_BUILD, X264_VERSION,
Loren Merritt's avatar
Loren Merritt committed
324
325
326
327
328
329
330
331
332
333
#ifdef AVIS_INPUT
            "yes",
#else
            "no",
#endif
#ifdef MP4_OUTPUT
            "yes",
#else
            "no",
#endif
334
335
            defaults->i_keyint_max,
            defaults->i_keyint_min,
336
337
            defaults->i_scenecut_threshold,
            defaults->i_bframe,
338
            defaults->i_bframe_bias,
339
340
            defaults->i_frame_reference,
            defaults->i_deblocking_filter_alphac0,
Loren Merritt's avatar
Loren Merritt committed
341
            defaults->i_deblocking_filter_beta,
342
343
344
345
            defaults->rc.i_qp_constant,
            defaults->rc.i_qp_min,
            defaults->rc.i_qp_max,
            defaults->rc.i_qp_step,
Loren Merritt's avatar
Loren Merritt committed
346
347
348
349
            defaults->rc.f_rate_tolerance,
            defaults->rc.i_vbv_max_bitrate,
            defaults->rc.i_vbv_buffer_size,
            defaults->rc.f_vbv_buffer_init,
350
351
            defaults->rc.f_ip_factor,
            defaults->rc.f_pb_factor,
352
            defaults->analyse.i_chroma_qp_offset,
353
354
355
356
357
            defaults->rc.psz_stat_out,
            defaults->rc.psz_rc_eq,
            defaults->rc.f_qcompress,
            defaults->rc.f_complexity_blur,
            defaults->rc.f_qblur,
Loren Merritt's avatar
Loren Merritt committed
358
359
            strtable_lookup( x264_direct_pred_names, defaults->analyse.i_direct_mv_pred ),
            strtable_lookup( x264_motion_est_names, defaults->analyse.i_me_method ),
360
            defaults->analyse.i_me_range,
361
            defaults->analyse.i_subpel_refine,
Loren Merritt's avatar
Loren Merritt committed
362
            defaults->analyse.i_trellis,
363
            defaults->analyse.i_noise_reduction,
364
365
366
367
368
369
370
            strtable_lookup( overscan_str, defaults->vui.i_overscan ),
            strtable_lookup( vidformat_str, defaults->vui.i_vidformat ),
            strtable_lookup( fullrange_str, defaults->vui.b_fullrange ),
            strtable_lookup( colorprim_str, defaults->vui.i_colorprim ),
            strtable_lookup( transfer_str, defaults->vui.i_transfer ),
            strtable_lookup( colmatrix_str, defaults->vui.i_colmatrix ),
            defaults->vui.i_chroma_loc
Laurent Aimar's avatar
Laurent Aimar committed
371
372
373
           );
}

Loren Merritt's avatar
Loren Merritt committed
374
static int parse_enum( const char *arg, const char * const *names, int *dst )
375
376
377
378
379
380
381
382
383
384
385
{
    int i;
    for( i = 0; names[i]; i++ )
        if( !strcmp( arg, names[i] ) )
        {
            *dst = i;
            return 0;
        }
    return -1;
}

Loren Merritt's avatar
Loren Merritt committed
386
387
388
389
390
391
392
393
394
395
396
397
static int parse_cqm( const char *str, uint8_t *cqm, int length )
{
    int i = 0;
    do {
        int coef;
        if( !sscanf( str, "%d", &coef ) || coef < 1 || coef > 255 )
            return -1;
        cqm[i++] = coef;
    } while( i < length && (str = strchr( str, ',' )) && str++ );
    return (i == length) ? 0 : -1;
}

Laurent Aimar's avatar
Laurent Aimar committed
398
399
400
401
/*****************************************************************************
 * Parse:
 *****************************************************************************/
static int  Parse( int argc, char **argv,
Loren Merritt's avatar
Loren Merritt committed
402
                   x264_param_t *param, cli_opt_t *opt )
Laurent Aimar's avatar
Laurent Aimar committed
403
404
{
    char *psz_filename = NULL;
405
    x264_param_t defaults = *param;
406
407
    char *psz;
    char b_avis = 0;
Laurent Aimar's avatar
Laurent Aimar committed
408

Loren Merritt's avatar
Loren Merritt committed
409
    memset( opt, 0, sizeof(cli_opt_t) );
Laurent Aimar's avatar
Laurent Aimar committed
410

411
    /* Default input file driver */
Loren Merritt's avatar
Loren Merritt committed
412
    p_open_infile = open_file_yuv;
413
414
    p_get_frame_total = get_frame_total_yuv;
    p_read_frame = read_frame_yuv;
Loren Merritt's avatar
Loren Merritt committed
415
416
417
418
419
420
421
422
    p_close_infile = close_file_yuv;

    /* Default output file driver */
    p_open_outfile = open_file_bsf;
    p_set_outfile_param = set_param_bsf;
    p_write_nalu = write_nalu_bsf;
    p_set_eop = set_eop_bsf;
    p_close_outfile = close_file_bsf;
423

Laurent Aimar's avatar
Laurent Aimar committed
424
425
426
427
    /* Parse command line options */
    opterr = 0; // no error message
    for( ;; )
    {
Loren Merritt's avatar
Loren Merritt committed
428
        int b_error = 0;
Laurent Aimar's avatar
Laurent Aimar committed
429
        int long_options_index;
430
431
432
433
434
#define OPT_QPMIN 256
#define OPT_QPMAX 257
#define OPT_QPSTEP 258
#define OPT_IPRATIO 260
#define OPT_PBRATIO 261
Loren Merritt's avatar
Loren Merritt committed
435
#define OPT_RATETOL 262
436
437
438
#define OPT_RCSTATS 264
#define OPT_RCEQ 265
#define OPT_QCOMP 266
439
440
#define OPT_NOPSNR 267
#define OPT_QUIET 268
441
#define OPT_SCENECUT 270
Loren Merritt's avatar
Loren Merritt committed
442
443
#define OPT_QBLUR 271
#define OPT_CPLXBLUR 272
444
#define OPT_FRAMES 273
Loren Merritt's avatar
Loren Merritt committed
445
#define OPT_FPS 274
446
#define OPT_DIRECT 275
447
#define OPT_LEVEL 276
448
449
#define OPT_NOBADAPT 277
#define OPT_BBIAS 278
450
#define OPT_BPYRAMID 279
451
#define OPT_CHROMA_QP 280
Loren Merritt's avatar
Loren Merritt committed
452
#define OPT_NO_CHROMA_ME 281
453
#define OPT_NO_CABAC 282
454
#define OPT_AUD 283
Loren Merritt's avatar
Loren Merritt committed
455
#define OPT_PROGRESS 284
456
457
#define OPT_ME 285
#define OPT_MERANGE 286
Loren Merritt's avatar
Loren Merritt committed
458
459
460
#define OPT_VBVMAXRATE 287
#define OPT_VBVBUFSIZE 288
#define OPT_VBVINIT 289
Loren Merritt's avatar
Loren Merritt committed
461
#define OPT_VISUALIZE 290
Loren Merritt's avatar
Loren Merritt committed
462
#define OPT_SEEK 291
Loren Merritt's avatar
Loren Merritt committed
463
#define OPT_ZONES 292
Loren Merritt's avatar
Loren Merritt committed
464
#define OPT_THREADS 293
Loren Merritt's avatar
Loren Merritt committed
465
466
467
468
469
470
471
472
473
474
475
#define OPT_CQM 294
#define OPT_CQM4 295
#define OPT_CQM4I 296
#define OPT_CQM4IY 297
#define OPT_CQM4IC 298
#define OPT_CQM4P 299
#define OPT_CQM4PY 300
#define OPT_CQM4PC 301
#define OPT_CQM8 302
#define OPT_CQM8I 303
#define OPT_CQM8P 304
476
#define OPT_CQMFILE 305
477
478
479
480
481
482
483
484
#define OPT_SAR 306
#define OPT_OVERSCAN 307
#define OPT_VIDFORMAT 308
#define OPT_FULLRANGE 309
#define OPT_COLOURPRIM 310
#define OPT_TRANSFER 311
#define OPT_COLOURMATRIX 312
#define OPT_CHROMALOC 313
Loren Merritt's avatar
Loren Merritt committed
485
#define OPT_MIXED_REFS 314
486
#define OPT_CRF 315
487
#define OPT_B_RDO 316
Loren Merritt's avatar
Loren Merritt committed
488
#define OPT_NO_FAST_PSKIP 317
489
#define OPT_BIME 318
490
#define OPT_NR 319
491

Laurent Aimar's avatar
Laurent Aimar committed
492
493
494
495
        static struct option long_options[] =
        {
            { "help",    no_argument,       NULL, 'h' },
            { "bitrate", required_argument, NULL, 'B' },
Loren Merritt's avatar
Loren Merritt committed
496
            { "bframes", required_argument, NULL, 'b' },
497
498
            { "no-b-adapt", no_argument,    NULL, OPT_NOBADAPT },
            { "b-bias",  required_argument, NULL, OPT_BBIAS },
499
            { "b-pyramid", no_argument,     NULL, OPT_BPYRAMID },
500
501
            { "min-keyint",required_argument,NULL,'i' },
            { "keyint",  required_argument, NULL, 'I' },
502
            { "scenecut",required_argument, NULL, OPT_SCENECUT },
Laurent Aimar's avatar
Laurent Aimar committed
503
504
            { "nf",      no_argument,       NULL, 'n' },
            { "filter",  required_argument, NULL, 'f' },
505
            { "no-cabac",no_argument,       NULL, OPT_NO_CABAC },
Laurent Aimar's avatar
Laurent Aimar committed
506
            { "qp",      required_argument, NULL, 'q' },
507
508
509
            { "qpmin",   required_argument, NULL, OPT_QPMIN },
            { "qpmax",   required_argument, NULL, OPT_QPMAX },
            { "qpstep",  required_argument, NULL, OPT_QPSTEP },
510
            { "crf",     required_argument, NULL, OPT_CRF },
Laurent Aimar's avatar
Laurent Aimar committed
511
512
            { "ref",     required_argument, NULL, 'r' },
            { "no-asm",  no_argument,       NULL, 'C' },
513
            { "sar",     required_argument, NULL, OPT_SAR },
Loren Merritt's avatar
Loren Merritt committed
514
            { "fps",     required_argument, NULL, OPT_FPS },
515
            { "frames",  required_argument, NULL, OPT_FRAMES },
Loren Merritt's avatar
Loren Merritt committed
516
            { "seek",    required_argument, NULL, OPT_SEEK },
Laurent Aimar's avatar
Laurent Aimar committed
517
518
            { "output",  required_argument, NULL, 'o' },
            { "analyse", required_argument, NULL, 'A' },
519
            { "direct",  required_argument, NULL, OPT_DIRECT },
520
            { "weightb", no_argument,       NULL, 'w' },
521
522
            { "me",      required_argument, NULL, OPT_ME },
            { "merange", required_argument, NULL, OPT_MERANGE },
523
            { "subme",   required_argument, NULL, 'm' },
524
            { "b-rdo",   no_argument,       NULL, OPT_B_RDO },
Loren Merritt's avatar
Loren Merritt committed
525
            { "mixed-refs", no_argument,    NULL, OPT_MIXED_REFS },
Loren Merritt's avatar
Loren Merritt committed
526
            { "no-chroma-me", no_argument,  NULL, OPT_NO_CHROMA_ME },
527
            { "bime",    no_argument,       NULL, OPT_BIME },
528
            { "8x8dct",  no_argument,       NULL, '8' },
Loren Merritt's avatar
Loren Merritt committed
529
            { "trellis", required_argument, NULL, 't' },
Loren Merritt's avatar
Loren Merritt committed
530
            { "no-fast-pskip", no_argument, NULL, OPT_NO_FAST_PSKIP },
531
            { "level",   required_argument, NULL, OPT_LEVEL },
Loren Merritt's avatar
Loren Merritt committed
532
533
534
535
            { "ratetol", required_argument, NULL, OPT_RATETOL },
            { "vbv-maxrate", required_argument, NULL, OPT_VBVMAXRATE },
            { "vbv-bufsize", required_argument, NULL, OPT_VBVBUFSIZE },
            { "vbv-init", required_argument,NULL,  OPT_VBVINIT },
536
537
            { "ipratio", required_argument, NULL, OPT_IPRATIO },
            { "pbratio", required_argument, NULL, OPT_PBRATIO },
538
            { "chroma-qp-offset", required_argument, NULL, OPT_CHROMA_QP },
539
540
541
542
            { "pass",    required_argument, NULL, 'p' },
            { "stats",   required_argument, NULL, OPT_RCSTATS },
            { "rceq",    required_argument, NULL, OPT_RCEQ },
            { "qcomp",   required_argument, NULL, OPT_QCOMP },
Loren Merritt's avatar
Loren Merritt committed
543
544
            { "qblur",   required_argument, NULL, OPT_QBLUR },
            { "cplxblur",required_argument, NULL, OPT_CPLXBLUR },
Loren Merritt's avatar
Loren Merritt committed
545
            { "zones",   required_argument, NULL, OPT_ZONES },
Loren Merritt's avatar
Loren Merritt committed
546
            { "threads", required_argument, NULL, OPT_THREADS },
547
548
            { "no-psnr", no_argument,       NULL, OPT_NOPSNR },
            { "quiet",   no_argument,       NULL, OPT_QUIET },
549
            { "verbose", no_argument,       NULL, 'v' },
Loren Merritt's avatar
Loren Merritt committed
550
            { "progress",no_argument,       NULL, OPT_PROGRESS },
Loren Merritt's avatar
Loren Merritt committed
551
            { "visualize",no_argument,      NULL, OPT_VISUALIZE },
552
            { "aud",     no_argument,       NULL, OPT_AUD },
553
            { "nr",      required_argument, NULL, OPT_NR },
Loren Merritt's avatar
Loren Merritt committed
554
            { "cqm",     required_argument, NULL, OPT_CQM },
555
            { "cqmfile", required_argument, NULL, OPT_CQMFILE },
Loren Merritt's avatar
Loren Merritt committed
556
557
558
559
560
561
562
563
564
565
            { "cqm4",    required_argument, NULL, OPT_CQM4 },
            { "cqm4i",   required_argument, NULL, OPT_CQM4I },
            { "cqm4iy",  required_argument, NULL, OPT_CQM4IY },
            { "cqm4ic",  required_argument, NULL, OPT_CQM4IC },
            { "cqm4p",   required_argument, NULL, OPT_CQM4P },
            { "cqm4py",  required_argument, NULL, OPT_CQM4PY },
            { "cqm4pc",  required_argument, NULL, OPT_CQM4PC },
            { "cqm8",    required_argument, NULL, OPT_CQM8 },
            { "cqm8i",   required_argument, NULL, OPT_CQM8I },
            { "cqm8p",   required_argument, NULL, OPT_CQM8P },
566
567
568
569
570
571
572
            { "overscan", required_argument, NULL, OPT_OVERSCAN },
            { "videoformat", required_argument, NULL, OPT_VIDFORMAT },
            { "fullrange", required_argument, NULL, OPT_FULLRANGE },
            { "colorprim", required_argument, NULL, OPT_COLOURPRIM },
            { "transfer", required_argument, NULL, OPT_TRANSFER },
            { "colormatrix", required_argument, NULL, OPT_COLOURMATRIX },
            { "chromaloc", required_argument, NULL, OPT_CHROMALOC },
Laurent Aimar's avatar
Laurent Aimar committed
573
574
575
576
577
            {0, 0, 0, 0}
        };

        int c;

Loren Merritt's avatar
Loren Merritt committed
578
        c = getopt_long( argc, argv, "hi:I:b:r:cxB:q:f:o:A:m:p:t:vw8",
Laurent Aimar's avatar
Laurent Aimar committed
579
580
581
582
583
584
585
586
587
588
                         long_options, &long_options_index);

        if( c == -1 )
        {
            break;
        }

        switch( c )
        {
            case 'h':
589
                Help( &defaults );
Laurent Aimar's avatar
Laurent Aimar committed
590
591
592
593
594
                return -1;

            case 0:
                break;
            case 'B':
595
596
                param->rc.i_bitrate = atol( optarg );
                param->rc.b_cbr = 1;
Laurent Aimar's avatar
Laurent Aimar committed
597
                break;
598
599
600
            case OPT_CRF:
                param->rc.i_rf_constant = atol( optarg );
                break;
Laurent Aimar's avatar
Laurent Aimar committed
601
602
603
            case 'b':
                param->i_bframe = atol( optarg );
                break;
604
605
606
607
608
609
            case OPT_NOBADAPT:
                param->b_bframe_adaptive = 0;
                break;
            case OPT_BBIAS:
                param->i_bframe_bias = atol( optarg );
                break;
610
611
612
            case OPT_BPYRAMID:
                param->b_bframe_pyramid = 1;
                break;
Laurent Aimar's avatar
Laurent Aimar committed
613
            case 'i':
614
                param->i_keyint_min = atol( optarg );
615
616
                if( param->i_keyint_max < param->i_keyint_min )
                    param->i_keyint_max = param->i_keyint_min;
Laurent Aimar's avatar
Laurent Aimar committed
617
618
                break;
            case 'I':
619
                param->i_keyint_max = atol( optarg );
620
621
                if( param->i_keyint_min > param->i_keyint_max )
                    param->i_keyint_min = param->i_keyint_max;
Laurent Aimar's avatar
Laurent Aimar committed
622
                break;
623
624
625
            case OPT_SCENECUT:
                param->i_scenecut_threshold = atol( optarg );
                break;
Laurent Aimar's avatar
Laurent Aimar committed
626
627
628
629
630
631
            case 'n':
                param->b_deblocking_filter = 0;
                break;
            case 'f':
            {
                char *p = strchr( optarg, ':' );
632
                if( !p ) p = strchr( optarg, ',' );
633
634
                param->i_deblocking_filter_alphac0 = atoi( optarg );
                param->i_deblocking_filter_beta = p ? atoi( p+1 ) : param->i_deblocking_filter_alphac0;
Laurent Aimar's avatar
Laurent Aimar committed
635
636
637
                break;
            }
            case 'q':
638
                param->rc.i_qp_constant = atoi( optarg );
Laurent Aimar's avatar
Laurent Aimar committed
639
                break;
640
            case OPT_QPMIN:
641
                param->rc.i_qp_min = atoi( optarg );
642
643
                break;
            case OPT_QPMAX:
644
                param->rc.i_qp_max = atoi( optarg );
645
646
                break;
            case OPT_QPSTEP:
647
                param->rc.i_qp_step = atoi( optarg );
648
                break;
Laurent Aimar's avatar
Laurent Aimar committed
649
650
651
            case 'r':
                param->i_frame_reference = atoi( optarg );
                break;
652
653
            case OPT_NO_CABAC:
                param->b_cabac = 0;
Laurent Aimar's avatar
Laurent Aimar committed
654
655
                break;
            case 'x':
Loren Merritt's avatar
Loren Merritt committed
656
                opt->b_decompress = 1;
Laurent Aimar's avatar
Laurent Aimar committed
657
658
659
660
                break;
            case 'C':
                param->cpu = 0;
                break;
661
            case OPT_FRAMES:
662
                param->i_frame_total = atoi( optarg );
Loren Merritt's avatar
Loren Merritt committed
663
664
665
                break;
            case OPT_SEEK:
                opt->i_seek = atoi( optarg );
666
                break;
Loren Merritt's avatar
Loren Merritt committed
667
            case 'o':
668
                if( !strncasecmp(optarg + strlen(optarg) - 4, ".mp4", 4) )
Loren Merritt's avatar
Loren Merritt committed
669
                {
670
671
672
673
674
675
676
677
678
#ifdef MP4_OUTPUT
                    p_open_outfile = open_file_mp4;
                    p_write_nalu = write_nalu_mp4;
                    p_set_outfile_param = set_param_mp4;
                    p_set_eop = set_eop_mp4;
                    p_close_outfile = close_file_mp4;
#else
                    fprintf( stderr, "not compiled with MP4 output support\n" );
                    return -1;
Loren Merritt's avatar
Loren Merritt committed
679
#endif
680
                }
Loren Merritt's avatar
Loren Merritt committed
681
682
683
                else if( !strncasecmp(optarg + strlen(optarg) - 4, ".mkv", 4) )
                {
                    p_open_outfile = open_file_mkv;
684
685
686
687
                    p_write_nalu = write_nalu_mkv;
                    p_set_outfile_param = set_param_mkv;
                    p_set_eop = set_eop_mkv;
                    p_close_outfile = close_file_mkv;
Loren Merritt's avatar
Loren Merritt committed
688
                }
689
                if( !strcmp(optarg, "-") )
Loren Merritt's avatar
Loren Merritt committed
690
691
                    opt->hout = stdout;
                else if( p_open_outfile( optarg, &opt->hout ) )
Laurent Aimar's avatar
Laurent Aimar committed
692
693
694
695
696
                {
                    fprintf( stderr, "cannot open output file `%s'\n", optarg );
                    return -1;
                }
                break;
697
            case OPT_SAR:
Laurent Aimar's avatar
Laurent Aimar committed
698
699
            {
                char *p = strchr( optarg, ':' );
700
                if( !p ) p = strchr( optarg, '/' );
Laurent Aimar's avatar
Laurent Aimar committed
701
702
703
704
705
706
707
                if( p )
                {
                    param->vui.i_sar_width = atoi( optarg );
                    param->vui.i_sar_height = atoi( p + 1 );
                }
                break;
            }
Loren Merritt's avatar
Loren Merritt committed
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
            case OPT_FPS:
            {
                float fps;
                if( sscanf( optarg, "%d/%d", &param->i_fps_num, &param->i_fps_den ) == 2 )
                    ;
                else if( sscanf( optarg, "%f", &fps ) )
                {
                    param->i_fps_num = (int)(fps * 1000 + .5);
                    param->i_fps_den = 1000;
                }
                else
                {
                    fprintf( stderr, "bad fps `%s'\n", optarg );
                    return -1;
                }
723
                break;
Loren Merritt's avatar
Loren Merritt committed
724
            }
Laurent Aimar's avatar
Laurent Aimar committed
725
726
            case 'A':
                param->analyse.inter = 0;
727
728
                if( strstr( optarg, "none" ) )  param->analyse.inter =  0;
                if( strstr( optarg, "all" ) )   param->analyse.inter = ~0;
Laurent Aimar's avatar
Laurent Aimar committed
729

730
                if( strstr( optarg, "i4x4" ) )  param->analyse.inter |= X264_ANALYSE_I4x4;
731
                if( strstr( optarg, "i8x8" ) )  param->analyse.inter |= X264_ANALYSE_I8x8;
732
733
734
                if( strstr( optarg, "p8x8" ) )  param->analyse.inter |= X264_ANALYSE_PSUB16x16;
                if( strstr( optarg, "p4x4" ) )  param->analyse.inter |= X264_ANALYSE_PSUB8x8;
                if( strstr( optarg, "b8x8" ) )  param->analyse.inter |= X264_ANALYSE_BSUB16x16;
735
736
                break;
            case OPT_DIRECT:
Loren Merritt's avatar
Loren Merritt committed
737
                b_error |= parse_enum( optarg, x264_direct_pred_names, &param->analyse.i_direct_mv_pred );
Laurent Aimar's avatar
Laurent Aimar committed
738
                break;
739
740
741
            case 'w':
                param->analyse.b_weighted_bipred = 1;
                break;
742
            case OPT_ME:
Loren Merritt's avatar
Loren Merritt committed
743
                b_error |= parse_enum( optarg, x264_motion_est_names, &param->analyse.i_me_method );
744
745
746
747
                break;
            case OPT_MERANGE:
                param->analyse.i_me_range = atoi(optarg);
                break;
748
            case 'm':
749
750
                param->analyse.i_subpel_refine = atoi(optarg);
                break;
751
752
753
            case OPT_B_RDO:
                param->analyse.b_bframe_rdo = 1;
                break;
Loren Merritt's avatar
Loren Merritt committed
754
755
756
            case OPT_MIXED_REFS:
                param->analyse.b_mixed_references = 1;
                break;
Loren Merritt's avatar
Loren Merritt committed
757
758
759
            case OPT_NO_CHROMA_ME:
                param->analyse.b_chroma_me = 0;
                break;
760
761
762
            case OPT_BIME:
                param->analyse.b_bidir_me = 1;
                break;
763
764
765
            case '8':
                param->analyse.b_transform_8x8 = 1;
                break;
Loren Merritt's avatar
Loren Merritt committed
766
767
768
            case 't':
                param->analyse.i_trellis = atoi(optarg);
                break;
Loren Merritt's avatar
Loren Merritt committed
769
770
771
            case OPT_NO_FAST_PSKIP:
                param->analyse.b_fast_pskip = 0;
                break;
772
            case OPT_LEVEL:
773
774
775
776
                if( atof(optarg) < 6 )
                    param->i_level_idc = (int)(10*atof(optarg)+.5);
                else
                    param->i_level_idc = atoi(optarg);
777
                break;
Loren Merritt's avatar
Loren Merritt committed
778
            case OPT_RATETOL:
779
                param->rc.f_rate_tolerance = !strncmp("inf", optarg, 3) ? 1e9 : atof(optarg);
Loren Merritt's avatar
Loren Merritt committed
780
781
782
                break;
            case OPT_VBVMAXRATE:
                param->rc.i_vbv_max_bitrate = atoi( optarg );
783
                break;
Loren Merritt's avatar
Loren Merritt committed
784
785
            case OPT_VBVBUFSIZE:
                param->rc.i_vbv_buffer_size = atoi( optarg );
786
                break;
Loren Merritt's avatar
Loren Merritt committed
787
788
            case OPT_VBVINIT:
                param->rc.f_vbv_buffer_init = atof(optarg);
789
790
                break;
            case OPT_IPRATIO:
791
                param->rc.f_ip_factor = atof(optarg);
792
793
                break;
            case OPT_PBRATIO:
794
                param->rc.f_pb_factor = atof(optarg);
795
                break;
796
797
798
            case OPT_CHROMA_QP:
                param->analyse.i_chroma_qp_offset = atoi(optarg);
                break;
799
800
801
802
803
804
805
            case 'p':
            {
                int i_pass = atoi(optarg);
                if( i_pass == 1 )
                    param->rc.b_stat_write = 1;
                else if( i_pass == 2 )
                    param->rc.b_stat_read = 1;
806
                else if( i_pass > 2 )
807
808
809
810
811
812
813
814
815
816
817
818
819
                    param->rc.b_stat_read =
                    param->rc.b_stat_write = 1;
                break;
            }
            case OPT_RCSTATS:
                param->rc.psz_stat_in = optarg;
                param->rc.psz_stat_out = optarg;
                break;
            case OPT_RCEQ:
                param->rc.psz_rc_eq = optarg;
               break;
            case OPT_QCOMP:
                param->rc.f_qcompress = atof(optarg);
820
                break;
Loren Merritt's avatar
Loren Merritt committed
821
822
823
824
825
826
            case OPT_QBLUR:
                param->rc.f_qblur = atof(optarg);
                break;
            case OPT_CPLXBLUR:
                param->rc.f_complexity_blur = atof(optarg);
                break;
Loren Merritt's avatar
Loren Merritt committed
827
            case OPT_ZONES:
828
                param->rc.psz_zones = optarg;
Loren Merritt's avatar
Loren Merritt committed
829
                break;
Loren Merritt's avatar
Loren Merritt committed
830
831
832
            case OPT_THREADS:
                param->i_threads = atoi(optarg);
                break;
833
834
835
836
837
838
            case OPT_NOPSNR:
                param->analyse.b_psnr = 0;
                break;
            case OPT_QUIET:
                param->i_log_level = X264_LOG_NONE;
                break;
839
840
841
            case 'v':
                param->i_log_level = X264_LOG_DEBUG;
                break;
842
843
844
            case OPT_AUD:
                param->b_aud = 1;
                break;
Loren Merritt's avatar
Loren Merritt committed
845
            case OPT_PROGRESS:
Loren Merritt's avatar
Loren Merritt committed
846
                opt->b_progress = 1;
Loren Merritt's avatar
Loren Merritt committed
847
                break;
Loren Merritt's avatar
Loren Merritt committed
848
849
850
            case OPT_VISUALIZE:
#ifdef VISUALIZE
                param->b_visualize = 1;
Loren Merritt's avatar
Loren Merritt committed
851
                b_exit_on_ctrl_c = 1;
Loren Merritt's avatar
Loren Merritt committed
852
853
854
855
#else
                fprintf( stderr, "not compiled with visualization support\n" );
#endif
                break;
856
857
858
            case OPT_NR:
                param->analyse.i_noise_reduction = atoi(optarg);
                break;
Loren Merritt's avatar
Loren Merritt committed
859
860
861
862
863
864
865
866
867
868
869
            case OPT_CQM:
                if( strstr( optarg, "flat" ) )
                    param->i_cqm_preset = X264_CQM_FLAT;
                else if( strstr( optarg, "jvt" ) )
                    param->i_cqm_preset = X264_CQM_JVT;
                else
                {
                    fprintf( stderr, "bad CQM preset `%s'\n", optarg );
                    return -1;
                }
                break;
870
871
872
            case OPT_CQMFILE:
                param->psz_cqm_file = optarg;
                break;
Loren Merritt's avatar
Loren Merritt committed
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
            case OPT_CQM4:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_4iy, 16 );
                b_error |= parse_cqm( optarg, param->cqm_4ic, 16 );
                b_error |= parse_cqm( optarg, param->cqm_4py, 16 );
                b_error |= parse_cqm( optarg, param->cqm_4pc, 16 );
                break;
            case OPT_CQM8:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_8iy, 64 );
                b_error |= parse_cqm( optarg, param->cqm_8py, 64 );
                break;
            case OPT_CQM4I:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_4iy, 16 );
                b_error |= parse_cqm( optarg, param->cqm_4ic, 16 );
                break;
            case OPT_CQM4P:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_4py, 16 );
                b_error |= parse_cqm( optarg, param->cqm_4pc, 16 );
                break;
            case OPT_CQM4IY:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_4iy, 16 );
                break;
            case OPT_CQM4IC:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_4ic, 16 );
                break;
            case OPT_CQM4PY:
                param->i_cqm_preset = X264_CQM_CUSTOM;
905
                b_error |= parse_cqm( optarg, param->cqm_4py, 16 );
Loren Merritt's avatar
Loren Merritt committed
906
907
908
                break;
            case OPT_CQM4PC:
                param->i_cqm_preset = X264_CQM_CUSTOM;
909
                b_error |= parse_cqm( optarg, param->cqm_4pc, 16 );
Loren Merritt's avatar
Loren Merritt committed
910
911
912
913
914
915
916
917
918
                break;
            case OPT_CQM8I:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_8iy, 64 );
                break;
            case OPT_CQM8P:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_8py, 64 );
                break;
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
            case OPT_OVERSCAN:
                b_error |= parse_enum( optarg, overscan_str, &param->vui.i_overscan );
                break;
            case OPT_VIDFORMAT:
                b_error |= parse_enum( optarg, vidformat_str, &param->vui.i_vidformat );
                break;
            case OPT_FULLRANGE:
                b_error |= parse_enum( optarg, fullrange_str, &param->vui.b_fullrange );
                break;
            case OPT_COLOURPRIM:
                b_error |= parse_enum( optarg, colorprim_str, &param->vui.i_colorprim );
                break;
            case OPT_TRANSFER:
                b_error |= parse_enum( optarg, transfer_str, &param->vui.i_transfer );
                break;
            case OPT_COLOURMATRIX:
                b_error |= parse_enum( optarg, colmatrix_str, &param->vui.i_colmatrix );
                break;
            case OPT_CHROMALOC:
                param->vui.i_chroma_loc = atoi( optarg );
                b_error = ( param->vui.i_chroma_loc < 0 || param->vui.i_chroma_loc > 5 );
                break;
Laurent Aimar's avatar
Laurent Aimar committed
941
942
943
944
            default:
                fprintf( stderr, "unknown option (%c)\n", optopt );
                return -1;
        }
Loren Merritt's avatar
Loren Merritt committed
945
946
947

        if( b_error )
        {
948
            fprintf( stderr, "bad argument: %s %s\n", argv[optind-2], optarg );
Loren Merritt's avatar
Loren Merritt committed
949
950
            return -1;
        }
Laurent Aimar's avatar
Laurent Aimar committed
951
952
953
    }

    /* Get the file name */
Loren Merritt's avatar
Loren Merritt committed
954
    if( optind > argc - 1 || !opt->hout )
Laurent Aimar's avatar
Laurent Aimar committed
955
    {
956
        Help( &defaults );
Laurent Aimar's avatar
Laurent Aimar committed
957
958
959
960
        return -1;
    }
    psz_filename = argv[optind++];

Loren Merritt's avatar
Loren Merritt committed
961
    if( !opt->b_decompress )
Laurent Aimar's avatar
Laurent Aimar committed
962
963
964
965
    {
        if( optind > argc - 1 )
        {
            /* try to parse the file name */
966
            for( psz = psz_filename; *psz; psz++ )
Laurent Aimar's avatar
Laurent Aimar committed
967
            {
968
969
                if( *psz >= '0' && *psz <= '9'
                    && sscanf( psz, "%ux%u", &param->i_width, &param->i_height ) == 2 )
Laurent Aimar's avatar
Laurent Aimar committed
970
                {
971
972
                    if( param->i_log_level >= X264_LOG_INFO )
                        fprintf( stderr, "x264 [info]: file name gives %dx%d\n", param->i_width, param->i_height );
Laurent Aimar's avatar
Laurent Aimar committed
973
974
975
976
977
978
                    break;
                }
            }
        }
        else
        {
979
            sscanf( argv[optind++], "%ux%u", &param->i_width, &param->i_height );
Laurent Aimar's avatar
Laurent Aimar committed
980
        }
981
982
983
984
985
986
        
        /* check avis input */
        psz = psz_filename + strlen(psz_filename) - 1;
        while( psz > psz_filename && *psz != '.' )
            psz--;

987
        if( !strncasecmp( psz, ".avi", 4 ) || !strncasecmp( psz, ".avs", 4 ) )
988
            b_avis = 1;
Laurent Aimar's avatar
Laurent Aimar committed
989

990
        if( !b_avis && ( !param->i_width || !param->i_height ) )
991
992
993
994
        {
            Help( &defaults );
            return -1;
        }
Laurent Aimar's avatar
Laurent Aimar committed
995
996
997
998
999
    }

    /* open the input */
    if( !strcmp( psz_filename, "-" ) )
    {
Loren Merritt's avatar
Loren Merritt committed
1000
        opt->hin = stdin;