Ejemplo n.º 1
0
gpointer
x264_gtk_encode_encode (X264_Thread_Data *thread_data)
{
  GIOStatus       status;
  gsize           size;
  X264_Pipe_Data  pipe_data;
  x264_param_t   *param;
  x264_picture_t  pic;
  x264_t         *h;
  hnd_t           hin;
  hnd_t           hout;
  int             i_frame;
  int             i_frame_total;
  int64_t         i_start;
  int64_t         i_end;
  int64_t         i_file;
  int             i_frame_size;
  int             i_progress;
  int             err;

  g_print (_("encoding...\n"));
  param = thread_data->param;
  err = x264_set_drivers (thread_data->in_container, thread_data->out_container);
  if (err < 0) {
    GtkWidget *no_driver;
    no_driver = gtk_message_dialog_new (GTK_WINDOW(thread_data->dialog),
                                        GTK_DIALOG_DESTROY_WITH_PARENT,
                                        GTK_MESSAGE_ERROR,
                                        GTK_BUTTONS_CLOSE,
                                        (err == -2) ? _("Error: unknown output file type")
                                                    : _("Error: unknown input file type"));
    gtk_dialog_run (GTK_DIALOG (no_driver));
    gtk_widget_destroy (no_driver);
    return NULL;
  }

  if (p_open_infile (thread_data->file_input, &hin, param)) {
    fprintf( stderr, _("could not open input file '%s'\n"), thread_data->file_input );
    return NULL;
  }

  p_open_outfile ((char *)thread_data->file_output, &hout);

  i_frame_total = p_get_frame_total (hin );
  if (((i_frame_total == 0) || (param->i_frame_total < i_frame_total)) &&
      (param->i_frame_total > 0))
    i_frame_total = param->i_frame_total;
  param->i_frame_total = i_frame_total;

  if ((h = x264_encoder_open (param)) == NULL)
    {
      fprintf (stderr, _("x264_encoder_open failed\n"));
      p_close_infile (hin);
      p_close_outfile (hout);
      g_free (param);

      return NULL;
    }

  if (p_set_outfile_param (hout, param))
    {
      fprintf (stderr, _("can't set outfile param\n"));
      p_close_infile (hin);
      p_close_outfile (hout);
      g_free (param);

      return NULL;
    }

  /* Create a new pic */
  x264_picture_alloc (&pic, X264_CSP_I420, param->i_width, param->i_height );

  i_start = x264_mdate();

  /* Encode frames */
  for (i_frame = 0, i_file = 0, i_progress = 0;
       ((i_frame < i_frame_total) || (i_frame_total == 0)); )
    {
      if (p_read_frame (&pic, hin, i_frame))
        break;

      pic.i_pts = (int64_t)i_frame * param->i_fps_den;

      i_file += x264_encode_frame (h, hout, &pic);

      i_frame++;

      /* update status line (up to 1000 times per input file) */
      if (param->i_log_level < X264_LOG_DEBUG &&
          (i_frame_total ? i_frame * 1000 / i_frame_total > i_progress
           : i_frame % 10 == 0))
        {
          int64_t i_elapsed = x264_mdate () - i_start;

          if (i_frame_total)
            {
              pipe_data.frame = i_frame;
              pipe_data.frame_total = i_frame_total;
              pipe_data.file = i_file;
              pipe_data.elapsed = i_elapsed;
              status = g_io_channel_write_chars (thread_data->io_write,
                                                 (const gchar *)&pipe_data,
                                                 sizeof (X264_Pipe_Data),
                                                 &size, NULL);
              if (status != G_IO_STATUS_NORMAL) {
                g_print (_("Error ! %d %d %d\n"), status, (int)sizeof (X264_Pipe_Data), (int)size);
              }
              else {
                /* we force the GIOChannel to write to the pipeline */
                status = g_io_channel_flush (thread_data->io_write,
                                             NULL);
                if (status != G_IO_STATUS_NORMAL) {
                  g_print (_("Error ! %d\n"), status);
                }
              }
            }
        }
    }
  /* Flush delayed B-frames */
  do {
    i_file += i_frame_size = x264_encode_frame (h, hout, NULL);
  } while (i_frame_size);

  i_end = x264_mdate ();
  x264_picture_clean (&pic);
  x264_encoder_close (h);
  fprintf (stderr, "\n");

  p_close_infile (hin);
  p_close_outfile (hout);

  if (i_frame > 0) {
    double fps = (double)i_frame * (double)1000000 /
      (double)(i_end - i_start);

    fprintf (stderr, _("encoded %d frames, %.2f fps, %.2f kb/s\n"),
             i_frame, fps,
             (double) i_file * 8 * param->i_fps_num /
             ((double) param->i_fps_den * i_frame * 1000));
  }

  gtk_widget_set_sensitive (thread_data->end_button, TRUE);
  gtk_widget_hide (thread_data->button);
  return NULL;
}
Ejemplo n.º 2
0
/*****************************************************************************
 * Parse:
 *****************************************************************************/
static int  Parse( int argc, char **argv,
                   x264_param_t *param, cli_opt_t *opt )
{
    char *psz_filename = NULL;
    x264_param_t defaults = *param;
    char *psz;
    int b_avis = 0;
    int b_y4m = 0;
    int b_thread_input = 0;

    memset( opt, 0, sizeof(cli_opt_t) );

    /* Default input file driver */
    p_open_infile = open_file_yuv;
    p_get_frame_total = get_frame_total_yuv;
    p_read_frame = read_frame_yuv;
    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;

    /* Parse command line options */
    opterr = 0; // no error message
    for( ;; )
    {
        int b_error = 0;
        int long_options_index;
#define OPT_QPMIN 256
#define OPT_QPMAX 257
#define OPT_QPSTEP 258
#define OPT_IPRATIO 260
#define OPT_PBRATIO 261
#define OPT_RATETOL 262
#define OPT_RCSTATS 264
#define OPT_RCEQ 265
#define OPT_QCOMP 266
#define OPT_NOPSNR 267
#define OPT_QUIET 268
#define OPT_SCENECUT 270
#define OPT_QBLUR 271
#define OPT_CPLXBLUR 272
#define OPT_FRAMES 273
#define OPT_FPS 274
#define OPT_DIRECT 275
#define OPT_LEVEL 276
#define OPT_NOBADAPT 277
#define OPT_BBIAS 278
#define OPT_BPYRAMID 279
#define OPT_CHROMA_QP 280
#define OPT_NO_CHROMA_ME 281
#define OPT_NO_CABAC 282
#define OPT_AUD 283
#define OPT_PROGRESS 284
#define OPT_ME 285
#define OPT_MERANGE 286
#define OPT_VBVMAXRATE 287
#define OPT_VBVBUFSIZE 288
#define OPT_VBVINIT 289
#define OPT_VISUALIZE 290
#define OPT_SEEK 291
#define OPT_ZONES 292
#define OPT_THREADS 293
#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
#define OPT_CQMFILE 305
#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
#define OPT_MIXED_REFS 314
#define OPT_CRF 315
#define OPT_B_RDO 316
#define OPT_NO_FAST_PSKIP 317
#define OPT_BIME 318
#define OPT_NR 319
#define OPT_THREAD_INPUT 320
#define OPT_NO_DCT_DECIMATE 321
#define OPT_SPS_ID 322
#define OPT_QPFILE 323

        static struct option long_options[] =
        {
            { "help",    no_argument,       NULL, 'h' },
            { "bitrate", required_argument, NULL, 'B' },
            { "bframes", required_argument, NULL, 'b' },
            { "no-b-adapt", no_argument,    NULL, OPT_NOBADAPT },
            { "b-bias",  required_argument, NULL, OPT_BBIAS },
            { "b-pyramid", no_argument,     NULL, OPT_BPYRAMID },
            { "min-keyint",required_argument,NULL,'i' },
            { "keyint",  required_argument, NULL, 'I' },
            { "scenecut",required_argument, NULL, OPT_SCENECUT },
            { "nf",      no_argument,       NULL, 'n' },
            { "filter",  required_argument, NULL, 'f' },
            { "no-cabac",no_argument,       NULL, OPT_NO_CABAC },
            { "qp",      required_argument, NULL, 'q' },
            { "qpmin",   required_argument, NULL, OPT_QPMIN },
            { "qpmax",   required_argument, NULL, OPT_QPMAX },
            { "qpstep",  required_argument, NULL, OPT_QPSTEP },
            { "crf",     required_argument, NULL, OPT_CRF },
            { "ref",     required_argument, NULL, 'r' },
            { "no-asm",  no_argument,       NULL, 'C' },
            { "sar",     required_argument, NULL, OPT_SAR },
            { "fps",     required_argument, NULL, OPT_FPS },
            { "frames",  required_argument, NULL, OPT_FRAMES },
            { "seek",    required_argument, NULL, OPT_SEEK },
            { "output",  required_argument, NULL, 'o' },
            { "analyse", required_argument, NULL, 'A' },
            { "direct",  required_argument, NULL, OPT_DIRECT },
            { "weightb", no_argument,       NULL, 'w' },
            { "me",      required_argument, NULL, OPT_ME },
            { "merange", required_argument, NULL, OPT_MERANGE },
            { "subme",   required_argument, NULL, 'm' },
            { "b-rdo",   no_argument,       NULL, OPT_B_RDO },
            { "mixed-refs", no_argument,    NULL, OPT_MIXED_REFS },
            { "no-chroma-me", no_argument,  NULL, OPT_NO_CHROMA_ME },
            { "bime",    no_argument,       NULL, OPT_BIME },
            { "8x8dct",  no_argument,       NULL, '8' },
            { "trellis", required_argument, NULL, 't' },
            { "no-fast-pskip", no_argument, NULL, OPT_NO_FAST_PSKIP },
            { "no-dct-decimate", no_argument, NULL, OPT_NO_DCT_DECIMATE },
            { "level",   required_argument, NULL, OPT_LEVEL },
            { "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 },
            { "ipratio", required_argument, NULL, OPT_IPRATIO },
            { "pbratio", required_argument, NULL, OPT_PBRATIO },
            { "chroma-qp-offset", required_argument, NULL, OPT_CHROMA_QP },
            { "pass",    required_argument, NULL, 'p' },
            { "stats",   required_argument, NULL, OPT_RCSTATS },
            { "rceq",    required_argument, NULL, OPT_RCEQ },
            { "qcomp",   required_argument, NULL, OPT_QCOMP },
            { "qblur",   required_argument, NULL, OPT_QBLUR },
            { "cplxblur",required_argument, NULL, OPT_CPLXBLUR },
            { "zones",   required_argument, NULL, OPT_ZONES },
            { "qpfile",  required_argument, NULL, OPT_QPFILE },
            { "threads", required_argument, NULL, OPT_THREADS },
            { "thread-input", no_argument,  NULL, OPT_THREAD_INPUT },
            { "no-psnr", no_argument,       NULL, OPT_NOPSNR },
            { "quiet",   no_argument,       NULL, OPT_QUIET },
            { "verbose", no_argument,       NULL, 'v' },
            { "progress",no_argument,       NULL, OPT_PROGRESS },
            { "visualize",no_argument,      NULL, OPT_VISUALIZE },
            { "sps-id",  required_argument, NULL, OPT_SPS_ID },
            { "aud",     no_argument,       NULL, OPT_AUD },
            { "nr",      required_argument, NULL, OPT_NR },
            { "cqm",     required_argument, NULL, OPT_CQM },
            { "cqmfile", required_argument, NULL, OPT_CQMFILE },
            { "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 },
            { "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 },
            {0, 0, 0, 0}
        };

        int c;

        c = getopt_long( argc, argv, "hi:I:b:r:cxB:q:f:o:A:m:p:t:vw8",
                         long_options, &long_options_index);

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

        switch( c )
        {
            case 'h':
                Help( &defaults );
                return -1;

            case 0:
                break;
            case 'B':
                param->rc.i_bitrate = atol( optarg );
                param->rc.i_rc_method = X264_RC_ABR;
                break;
            case OPT_CRF:
                param->rc.i_rf_constant = atol( optarg );
                param->rc.i_rc_method = X264_RC_CRF;
                break;
            case 'b':
                param->i_bframe = atol( optarg );
                break;
            case OPT_NOBADAPT:
                param->b_bframe_adaptive = 0;
                break;
            case OPT_BBIAS:
                param->i_bframe_bias = atol( optarg );
                break;
            case OPT_BPYRAMID:
                param->b_bframe_pyramid = 1;
                break;
            case 'i':
                param->i_keyint_min = atol( optarg );
                if( param->i_keyint_max < param->i_keyint_min )
                    param->i_keyint_max = param->i_keyint_min;
                break;
            case 'I':
                param->i_keyint_max = atol( optarg );
                if( param->i_keyint_min > param->i_keyint_max )
                    param->i_keyint_min = param->i_keyint_max;
                break;
            case OPT_SCENECUT:
                param->i_scenecut_threshold = atol( optarg );
                break;
            case 'n':
                param->b_deblocking_filter = 0;
                break;
            case 'f':
            {
                char *p = strchr( optarg, ':' );
                if( !p ) p = strchr( optarg, ',' );
                param->i_deblocking_filter_alphac0 = atoi( optarg );
                param->i_deblocking_filter_beta = p ? atoi( p+1 ) : param->i_deblocking_filter_alphac0;
                break;
            }
            case 'q':
                param->rc.i_qp_constant = atoi( optarg );
                param->rc.i_rc_method = X264_RC_CQP;
                break;
            case OPT_QPMIN:
                param->rc.i_qp_min = atoi( optarg );
                break;
            case OPT_QPMAX:
                param->rc.i_qp_max = atoi( optarg );
                break;
            case OPT_QPSTEP:
                param->rc.i_qp_step = atoi( optarg );
                break;
            case 'r':
                param->i_frame_reference = atoi( optarg );
                break;
            case OPT_NO_CABAC:
                param->b_cabac = 0;
                break;
            case 'x':
                opt->b_decompress = 1;
                break;
            case 'C':
                param->cpu = 0;
                break;
            case OPT_FRAMES:
                param->i_frame_total = atoi( optarg );
                break;
            case OPT_SEEK:
                opt->i_seek = atoi( optarg );
                break;
            case 'o':
                if( !strncasecmp(optarg + strlen(optarg) - 4, ".mp4", 4) )
                {
#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;
#endif
                }
                else if( !strncasecmp(optarg + strlen(optarg) - 4, ".mkv", 4) )
                {
                    p_open_outfile = open_file_mkv;
                    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;
                }
                if( !strcmp(optarg, "-") )
                    opt->hout = stdout;
                else if( p_open_outfile( optarg, &opt->hout ) )
                {
                    fprintf( stderr, "cannot open output file `%s'\n", optarg );
                    return -1;
                }
                break;
            case OPT_SAR:
            {
                char *p = strchr( optarg, ':' );
                if( !p ) p = strchr( optarg, '/' );
                if( p )
                {
                    param->vui.i_sar_width = atoi( optarg );
                    param->vui.i_sar_height = atoi( p + 1 );
                }
                break;
            }
            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;
                }
                break;
            }
            case 'A':
                param->analyse.inter = 0;
                if( strstr( optarg, "none" ) )  param->analyse.inter =  0;
                if( strstr( optarg, "all" ) )   param->analyse.inter = ~0;

                if( strstr( optarg, "i4x4" ) )  param->analyse.inter |= X264_ANALYSE_I4x4;
                if( strstr( optarg, "i8x8" ) )  param->analyse.inter |= X264_ANALYSE_I8x8;
                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;
                break;
            case OPT_DIRECT:
                b_error |= parse_enum( optarg, x264_direct_pred_names, &param->analyse.i_direct_mv_pred );
                break;
            case 'w':
                param->analyse.b_weighted_bipred = 1;
                break;
            case OPT_ME:
                b_error |= parse_enum( optarg, x264_motion_est_names, &param->analyse.i_me_method );
                break;
            case OPT_MERANGE:
                param->analyse.i_me_range = atoi(optarg);
                break;
            case 'm':
                param->analyse.i_subpel_refine = atoi(optarg);
                break;
            case OPT_B_RDO:
                param->analyse.b_bframe_rdo = 1;
                break;
            case OPT_MIXED_REFS:
                param->analyse.b_mixed_references = 1;
                break;
            case OPT_NO_CHROMA_ME:
                param->analyse.b_chroma_me = 0;
                break;
            case OPT_BIME:
                param->analyse.b_bidir_me = 1;
                break;
            case '8':
                param->analyse.b_transform_8x8 = 1;
                break;
            case 't':
                param->analyse.i_trellis = atoi(optarg);
                break;
            case OPT_NO_FAST_PSKIP:
                param->analyse.b_fast_pskip = 0;
                break;
            case OPT_NO_DCT_DECIMATE:
                param->analyse.b_dct_decimate = 0;
                break;
            case OPT_LEVEL:
                if( atof(optarg) < 6 )
                    param->i_level_idc = (int)(10*atof(optarg)+.5);
                else
                    param->i_level_idc = atoi(optarg);
                break;
            case OPT_RATETOL:
                param->rc.f_rate_tolerance = !strncmp("inf", optarg, 3) ? 1e9 : atof(optarg);
                break;
            case OPT_VBVMAXRATE:
                param->rc.i_vbv_max_bitrate = atoi( optarg );
                break;
            case OPT_VBVBUFSIZE:
                param->rc.i_vbv_buffer_size = atoi( optarg );
                break;
            case OPT_VBVINIT:
                param->rc.f_vbv_buffer_init = atof(optarg);
                break;
            case OPT_IPRATIO:
                param->rc.f_ip_factor = atof(optarg);
                break;
            case OPT_PBRATIO:
                param->rc.f_pb_factor = atof(optarg);
                break;
            case OPT_CHROMA_QP:
                param->analyse.i_chroma_qp_offset = atoi(optarg);
                break;
            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;
                else if( i_pass > 2 )
                    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);
                break;
            case OPT_QBLUR:
                param->rc.f_qblur = atof(optarg);
                break;
            case OPT_CPLXBLUR:
                param->rc.f_complexity_blur = atof(optarg);
                break;
            case OPT_ZONES:
                param->rc.psz_zones = optarg;
                break;
            case OPT_QPFILE:
                opt->qpfile = fopen( optarg, "r" );
                if( !opt->qpfile )
                {
                    fprintf( stderr, "can't open `%s'\n", optarg );
                    return -1;
                }
                param->i_scenecut_threshold = -1;
                param->b_bframe_adaptive = 0;
                break;
            case OPT_THREADS:
                param->i_threads = atoi(optarg);
                break;
            case OPT_THREAD_INPUT:
                b_thread_input = 1;
                break;
            case OPT_NOPSNR:
                param->analyse.b_psnr = 0;
                break;
            case OPT_QUIET:
                param->i_log_level = X264_LOG_NONE;
                break;
            case 'v':
                param->i_log_level = X264_LOG_DEBUG;
                break;
            case OPT_SPS_ID:
                param->i_sps_id = atoi(optarg);
                break;
            case OPT_AUD:
                param->b_aud = 1;
                break;
            case OPT_PROGRESS:
                opt->b_progress = 1;
                break;
            case OPT_VISUALIZE:
#ifdef VISUALIZE
                param->b_visualize = 1;
                b_exit_on_ctrl_c = 1;
#else
                fprintf( stderr, "not compiled with visualization support\n" );
#endif
                break;
            case OPT_NR:
                param->analyse.i_noise_reduction = atoi(optarg);
                break;
            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;
            case OPT_CQMFILE:
                param->psz_cqm_file = optarg;
                break;
            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;
                b_error |= parse_cqm( optarg, param->cqm_4py, 16 );
                break;
            case OPT_CQM4PC:
                param->i_cqm_preset = X264_CQM_CUSTOM;
                b_error |= parse_cqm( optarg, param->cqm_4pc, 16 );
                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;
            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;
            default:
                fprintf( stderr, "unknown option (%c)\n", optopt );
                return -1;
        }

        if( b_error )
        {
            fprintf( stderr, "bad argument: %s %s\n", argv[optind-2], optarg );
            return -1;
        }
    }

    /* Get the file name */
    if( optind > argc - 1 || !opt->hout )
    {
        Help( &defaults );
        return -1;
    }
    psz_filename = argv[optind++];

    if( !opt->b_decompress )
    {
        if( optind > argc - 1 )
        {
            /* try to parse the file name */
            for( psz = psz_filename; *psz; psz++ )
            {
                if( *psz >= '0' && *psz <= '9'
                    && sscanf( psz, "%ux%u", &param->i_width, &param->i_height ) == 2 )
                {
                    if( param->i_log_level >= X264_LOG_INFO )
                        fprintf( stderr, "x264 [info]: file name gives %dx%d\n", param->i_width, param->i_height );
                    break;
                }
            }
        }
        else
        {
            sscanf( argv[optind++], "%ux%u", &param->i_width, &param->i_height );
        }
        
        /* check avis input */
        psz = psz_filename + strlen(psz_filename) - 1;
        while( psz > psz_filename && *psz != '.' )
            psz--;

        if( !strncasecmp( psz, ".avi", 4 ) || !strncasecmp( psz, ".avs", 4 ) )
            b_avis = 1;
        if( !strncasecmp( psz, ".y4m", 4 ) )
            b_y4m = 1;
        if( !(b_avis || b_y4m) && ( !param->i_width || !param->i_height ) )
        {
            Help( &defaults );
            return -1;
        }
    }

    /* open the input */
    {
        if( b_avis )
        {
#ifdef AVIS_INPUT
            p_open_infile = open_file_avis;
            p_get_frame_total = get_frame_total_avis;
            p_read_frame = read_frame_avis;
            p_close_infile = close_file_avis;
#else
            fprintf( stderr, "not compiled with AVIS input support\n" );
            return -1;
#endif
        }
        if ( b_y4m )
        {
            p_open_infile = open_file_y4m;
            p_get_frame_total = get_frame_total_y4m;
            p_read_frame = read_frame_y4m;
            p_close_infile = close_file_y4m;
        }

        if( p_open_infile( psz_filename, &opt->hin, param ) )
        {
            fprintf( stderr, "could not open input file '%s'\n", psz_filename );
            return -1;
        }
    }

#ifdef HAVE_PTHREAD
    if( b_thread_input || param->i_threads > 1 )
    {
        if( open_file_thread( NULL, &opt->hin, param ) )
        {
            fprintf( stderr, "threaded input failed\n" );
        }
        else
        {
            p_open_infile = open_file_thread;
            p_get_frame_total = get_frame_total_thread;
            p_read_frame = read_frame_thread;
            p_close_infile = close_file_thread;
        }
    }
#endif

    return 0;
}