]> git.sesse.net Git - x264/blobdiff - x264.c
Open-GOP support
[x264] / x264.c
diff --git a/x264.c b/x264.c
index 3a01854255bacb94fde5dc0158c997fd55dd0c77..8722565111a1fa67a5b14c84eea8c49628cd363a 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -71,13 +71,13 @@ static const char * const demuxer_names[] =
     "auto",
     "yuv",
     "y4m",
-#ifdef AVS_INPUT
+#if HAVE_AVS
     "avs",
 #endif
-#ifdef LAVF_INPUT
+#if HAVE_LAVF
     "lavf",
 #endif
-#ifdef FFMS_INPUT
+#if HAVE_FFMS
     "ffms",
 #endif
     0
@@ -89,7 +89,7 @@ static const char * const muxer_names[] =
     "raw",
     "mkv",
     "flv",
-#ifdef MP4_OUTPUT
+#if HAVE_GPAC
     "mp4",
 #endif
     0
@@ -150,7 +150,7 @@ int main( int argc, char **argv )
     cli_opt_t opt;
     int ret;
 
-#ifdef PTW32_STATIC_LIB
+#if PTW32_STATIC_LIB
     pthread_win32_process_attach_np();
     pthread_win32_thread_attach_np();
 #endif
@@ -169,7 +169,7 @@ int main( int argc, char **argv )
 
     ret = Encode( &param, &opt );
 
-#ifdef PTW32_STATIC_LIB
+#if PTW32_STATIC_LIB
     pthread_win32_thread_detach_np();
     pthread_win32_process_detach_np();
 #endif
@@ -177,10 +177,10 @@ int main( int argc, char **argv )
     return ret;
 }
 
-static char const *strtable_lookup( const char * const table[], int index )
+static char const *strtable_lookup( const char * const table[], int idx )
 {
     int i = 0; while( table[i] ) i++;
-    return ( ( index >= 0 && index < i ) ? table[ index ] : "???" );
+    return ( ( idx >= 0 && idx < i ) ? table[ idx ] : "???" );
 }
 
 static char *stringify_names( char *buf, const char * const names[] )
@@ -225,22 +225,22 @@ static void Help( x264_param_t *defaults, int longhelp )
         "      --fullhelp              List all options\n"
         "\n",
         X264_BUILD, X264_VERSION,
-#ifdef AVS_INPUT
+#if HAVE_AVS
         "yes",
 #else
         "no",
 #endif
-#ifdef LAVF_INPUT
+#if HAVE_LAVF
         "yes",
 #else
         "no",
 #endif
-#ifdef FFMS_INPUT
+#if HAVE_FFMS
         "yes",
 #else
         "no",
 #endif
-#ifdef MP4_OUTPUT
+#if HAVE_GPAC
         "yes"
 #else
         "no"
@@ -380,6 +380,12 @@ static void Help( x264_param_t *defaults, int longhelp )
         "                                  - strict: Strictly hierarchical pyramid\n"
         "                                  - normal: Non-strict (not Blu-ray compatible)\n",
         strtable_lookup( x264_b_pyramid_names, defaults->i_bframe_pyramid ) );
+    H1( "      --open-gop <string>     Use recovery points to close GOPs [none]\n"
+        "                                  - none: Use standard closed GOPs\n"
+        "                                  - display: Base GOP length on display order\n"
+        "                                             (not Blu-ray compatible)\n"
+        "                                  - coded: Base GOP length on coded order\n"
+        "                              Only available with b-frames\n" );
     H1( "      --no-cabac              Disable CABAC\n" );
     H1( "  -r, --ref <integer>         Number of reference frames [%d]\n", defaults->i_frame_reference );
     H1( "      --no-deblock            Disable loop filter\n" );
@@ -441,7 +447,8 @@ static void Help( x264_param_t *defaults, int longhelp )
         "                                  or  b=<float> (bitrate multiplier)\n" );
     H2( "      --qpfile <string>       Force frametypes and QPs for some or all frames\n"
         "                              Format of each line: framenumber frametype QP\n"
-        "                              QP of -1 lets x264 choose. Frametypes: I,i,P,B,b.\n"
+        "                              QP of -1 lets x264 choose. Frametypes: I,i,K,P,B,b.\n"
+        "                                  K=<I or i> depending on open-gop setting\n"
         "                              QPs are restricted by qpmin/qpmax.\n" );
     H1( "\n" );
     H1( "Analysis:\n" );
@@ -585,28 +592,30 @@ static void Help( x264_param_t *defaults, int longhelp )
     H0( "\n" );
 }
 
-#define OPT_FRAMES 256
-#define OPT_SEEK 257
-#define OPT_QPFILE 258
-#define OPT_THREAD_INPUT 259
-#define OPT_QUIET 260
-#define OPT_NOPROGRESS 261
-#define OPT_VISUALIZE 262
-#define OPT_LONGHELP 263
-#define OPT_PROFILE 264
-#define OPT_PRESET 265
-#define OPT_TUNE 266
-#define OPT_SLOWFIRSTPASS 267
-#define OPT_FULLHELP 268
-#define OPT_FPS 269
-#define OPT_MUXER 270
-#define OPT_DEMUXER 271
-#define OPT_INDEX 272
-#define OPT_INTERLACED 273
-#define OPT_TCFILE_IN 274
-#define OPT_TCFILE_OUT 275
-#define OPT_TIMEBASE 276
-#define OPT_PULLDOWN 277
+enum {
+    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,
+} OptionsOPT;
 
 static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw";
 static struct option long_options[] =
@@ -625,6 +634,7 @@ static struct option long_options[] =
     { "no-b-adapt",        no_argument, NULL, 0 },
     { "b-bias",      required_argument, NULL, 0 },
     { "b-pyramid",   required_argument, NULL, 0 },
+    { "open-gop",    required_argument, NULL, 0 },
     { "min-keyint",  required_argument, NULL, 'i' },
     { "keyint",      required_argument, NULL, 'I' },
     { "intra-refresh",     no_argument, NULL, 0 },
@@ -762,7 +772,7 @@ static int select_output( const char *muxer, char *filename, x264_param_t *param
 
     if( !strcasecmp( ext, "mp4" ) )
     {
-#ifdef MP4_OUTPUT
+#if HAVE_GPAC
         output = mp4_output;
         param->b_annexb = 0;
         param->b_dts_compress = 0;
@@ -804,6 +814,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename
     int b_auto = !strcasecmp( demuxer, "auto" );
     if( !b_regular && b_auto )
         ext = "yuv";
+    b_regular = b_regular && x264_is_regular_file_path( filename );
     if( b_regular )
     {
         FILE *f = fopen( filename, "r" );
@@ -817,7 +828,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename
 
     if( !strcasecmp( module, "avs" ) || !strcasecmp( ext, "d2v" ) || !strcasecmp( ext, "dga" ) )
     {
-#ifdef AVS_INPUT
+#if HAVE_AVS
         input = avs_input;
         module = "avs";
 #else
@@ -831,7 +842,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename
         input = yuv_input;
     else
     {
-#ifdef FFMS_INPUT
+#if HAVE_FFMS
         if( b_regular && (b_auto || !strcasecmp( demuxer, "ffms" )) &&
             !ffms_input.open_file( filename, p_handle, info, opt ) )
         {
@@ -840,7 +851,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename
             input = ffms_input;
         }
 #endif
-#ifdef LAVF_INPUT
+#if HAVE_LAVF
         if( (b_auto || !strcasecmp( demuxer, "lavf" )) &&
             !lavf_input.open_file( filename, p_handle, info, opt ) )
         {
@@ -849,7 +860,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename
             input = lavf_input;
         }
 #endif
-#ifdef AVS_INPUT
+#if HAVE_AVS
         if( b_regular && (b_auto || !strcasecmp( demuxer, "avs" )) &&
             !avs_input.open_file( filename, p_handle, info, opt ) )
         {
@@ -993,14 +1004,20 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
                 break;
             case OPT_MUXER:
                 if( parse_enum_name( optarg, muxer_names, &muxer ) < 0 )
+                {
+                    fprintf( stderr, "x264 [error]: Unknown muxer `%s'\n", optarg );
                     return -1;
+                }
                 break;
             case OPT_DEMUXER:
                 if( parse_enum_name( optarg, demuxer_names, &demuxer ) < 0 )
+                {
+                    fprintf( stderr, "x264 [error]: Unknown demuxer `%s'\n", optarg );
                     return -1;
+                }
                 break;
             case OPT_INDEX:
-                input_opt.index = optarg;
+                input_opt.index_file = optarg;
                 break;
             case OPT_QPFILE:
                 opt->qpfile = fopen( optarg, "rb" );
@@ -1029,7 +1046,7 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
                 opt->b_progress = 0;
                 break;
             case OPT_VISUALIZE:
-#ifdef HAVE_VISUALIZE
+#if HAVE_VISUALIZE
                 param->b_visualize = 1;
                 b_exit_on_ctrl_c = 1;
 #else
@@ -1239,7 +1256,7 @@ generic_option:
         param->vui.i_sar_height = info.sar_height;
     }
 
-#ifdef HAVE_PTHREAD
+#if HAVE_PTHREAD
     if( b_thread_input || param->i_threads > 1
         || (param->i_threads == X264_THREADS_AUTO && x264_cpu_num_processors() > 1) )
     {
@@ -1296,6 +1313,7 @@ static void parse_qpfile( cli_opt_t *opt, x264_picture_t *pic, int i_frame )
         pic->i_qpplus1 = qp+1;
         if     ( type == 'I' ) pic->i_type = X264_TYPE_IDR;
         else if( type == 'i' ) pic->i_type = X264_TYPE_I;
+        else if( type == 'K' ) pic->i_type = X264_TYPE_KEYFRAME;
         else if( type == 'P' ) pic->i_type = X264_TYPE_P;
         else if( type == 'B' ) pic->i_type = X264_TYPE_BREF;
         else if( type == 'b' ) pic->i_type = X264_TYPE_B;