]> git.sesse.net Git - x264/blobdiff - x264.c
Altivec functions for MC using the cached halfpel planes.
[x264] / x264.c
diff --git a/x264.c b/x264.c
index a16cf6b42bf273bf836bfce3b14cc7efbe50ae18..415e314f567341bb024f10051981301a7dd67c98 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -36,7 +36,7 @@
 #include <fcntl.h>  /* _O_BINARY */
 #endif
 
-#include "core/common.h"
+#include "common/common.h"
 #include "x264.h"
 
 #define DATA_MAX 3000000
@@ -49,7 +49,7 @@ static void    SigIntHandler( int a )
     i_ctrl_c = 1;
 }
 
-static void Help( void );
+static void Help( x264_param_t *defaults );
 static int  Parse( int argc, char **argv, x264_param_t  *param, FILE **p_fin, FILE **p_fout, int *pb_decompress );
 static int  Encode( x264_param_t  *param, FILE *fyuv,  FILE *fout );
 static int  Decode( x264_param_t  *param, FILE *fh26l, FILE *fout );
@@ -73,7 +73,6 @@ int main( int argc, char **argv )
 #endif
 
     x264_param_default( &param );
-    param.f_fps = 25.0;
 
     /* Parse command line */
     if( Parse( argc, argv, &param, &fin, &fout, &b_decompress ) < 0 )
@@ -95,7 +94,7 @@ int main( int argc, char **argv )
 /*****************************************************************************
  * Help:
  *****************************************************************************/
-static void Help( void )
+static void Help( x264_param_t *defaults )
 {
     fprintf( stderr,
              "x264 build:0x%4.4x\n"
@@ -103,35 +102,80 @@ static void Help( void )
              "\n"
              "  -h, --help                  Print this help\n"
              "\n"
-             "  -I, --idrframe <integer>    Each 'number' I frames are IDR frames\n"
-             "  -i, --iframe <integer>      Frequency of I frames\n"
-             "  -b, --bframe <integer>      Number of B-frames between I and P\n"
+             "  -I, --keyint <integer  >    Maximum GOP size [%d]\n"
+             "  -i, --min-keyint <integer>  Minimum GOP size [%d]\n"
+             "      --scenecut <integer>    How aggresively to insert extra I frames [%d]\n"
+             "  -b, --bframe <integer>      Number of B-frames between I and P [%d]\n"
+             "      --no-b-adapt            Disable adaptive B-frame decision\n"
+             "      --b-bias <integer>      Influences how often B-frames are used [%d]\n"
              "\n"
              "  -c, --cabac                 Enable CABAC\n"
-             "  -r, --ref <integer>         Number of references\n"
+             "  -r, --ref <integer>         Number of reference frames [%d]\n"
              "  -n, --nf                    Disable loop filter\n"
-             "  -f, --filter <alpha:beta>   Loop filter AplhaCO and Beta parameters\n"
+             "  -f, --filter <alpha:beta>   Loop filter AplhaCO and Beta parameters [%d]\n"
              "\n"
-             "  -q, --qp <integer>          Set QP\n"
+             "  -q, --qp <integer>          Set QP [%d]\n"
              "  -B, --bitrate <integer>     Set bitrate\n"
-             "      --qpmin <integer>       Set min QP\n"
-             "      --qpmax <integer>       Set max QP\n"
-             "      --qpstep <integer>      Set max QP step\n"
-             "      --rcsens <integer>      RC sensitivity\n"
-             "      --rcbuf <integer>       Size of VBV buffer\n"
-             "      --rcinitbuf <integer>   Initial VBV buffer occupancy\n"
+             "      --qpmin <integer>       Set min QP [%d]\n"
+             "      --qpmax <integer>       Set max QP [%d]\n"
+             "      --qpstep <integer>      Set max QP step [%d]\n"
+             "      --rcsens <integer>      CBR ratecontrol sensitivity [%d]\n"
+             "      --rcbuf <integer>       Size of VBV buffer [%d]\n"
+             "      --rcinitbuf <integer>   Initial VBV buffer occupancy [%d]\n"
+             "      --ipratio <float>       QP factor between I and P [%.2f]\n"
+             "      --pbratio <float>       QP factor between P and B [%.2f]\n"
              "\n"
-             "  -A, --analyse <string>      Analyse options:\n"
+             "  -p, --pass <1|2>            Enable 2 pass ratecontrol\n"
+             "      --stats <string>        Filename for 2 pass stats [\"%s\"]\n"
+             "      --rceq <string>         Ratecontrol equation [\"%s\"]\n"
+             "      --qcomp <float>         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"
+             "\n"
+
+             "  -A, --analyse <string>      Analyse options: [\"i4x4|psub16x16|bsub16x16\"]\n"
              "                                  - i4x4\n"
-             "                                  - psub16x16,psub8x8\n"
+             "                                  - psub16x16, psub8x8, bsub16x16\n"
              "                                  - none, all\n"
+             "      --direct <string>       Direct MV prediction mode [\"temporal\"]\n"
+             "                                  - none, spatial, temporal\n"
+             "  -w, --weightb               Weighted prediction for B-frames\n"
+             "  -m, --subme <integer>       Subpixel motion estimation quality: 1=fast, 5=best. [%d]\n"
              "\n"
+             "      --level <integer>       Specify IDC level\n"
              "  -s, --sar width:height      Specify Sample Aspect Ratio\n"
+             "      --fps <float|rational>  Specify framerate\n"
+             "      --frames <integer>      Maximum number of frames to encode\n"
              "  -o, --output                Specify output file\n"
              "\n"
              "      --no-asm                Disable any CPU optims\n"
+             "      --no-psnr               Disable PSNR computaion\n"
+             "      --quiet                 Quiet Mode\n"
+             "  -v, --verbose               Print stats for each frame\n"
              "\n",
-            X264_BUILD
+            X264_BUILD,
+            defaults->i_keyint_max,
+            defaults->i_keyint_min,
+            defaults->i_scenecut_threshold,
+            defaults->i_bframe,
+            defaults->i_bframe_bias,
+            defaults->i_frame_reference,
+            defaults->i_deblocking_filter_alphac0,
+            defaults->rc.i_qp_constant,
+            defaults->rc.i_qp_min,
+            defaults->rc.i_qp_max,
+            defaults->rc.i_qp_step,
+            defaults->rc.i_rc_sens,
+            defaults->rc.i_rc_buffer_size,
+            defaults->rc.i_rc_init_buffer,
+            defaults->rc.f_ip_factor,
+            defaults->rc.f_pb_factor,
+            defaults->rc.psz_stat_out,
+            defaults->rc.psz_rc_eq,
+            defaults->rc.f_qcompress,
+            defaults->rc.f_complexity_blur,
+            defaults->rc.f_qblur,
+            defaults->analyse.i_subpel_refine
            );
 }
 
@@ -143,6 +187,7 @@ static int  Parse( int argc, char **argv,
                    FILE **p_fin, FILE **p_fout, int *pb_decompress )
 {
     char *psz_filename = NULL;
+    x264_param_t defaults = *param;
 
     /* Default output */
     *p_fout = stdout;
@@ -162,13 +207,31 @@ static int  Parse( int argc, char **argv,
 #define OPT_PBRATIO 261
 #define OPT_RCBUF 262
 #define OPT_RCIBUF 263
+#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
+
         static struct option long_options[] =
         {
             { "help",    no_argument,       NULL, 'h' },
             { "bitrate", required_argument, NULL, 'B' },
             { "bframe",  required_argument, NULL, 'b' },
-            { "iframe",  required_argument, NULL, 'i' },
-            { "idrframe",required_argument, NULL, 'I' },
+            { "no-b-adapt", no_argument,    NULL, OPT_NOBADAPT },
+            { "b-bias",  required_argument, NULL, OPT_BBIAS },
+            { "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' },
             { "cabac",   no_argument,       NULL, 'c' },
@@ -179,19 +242,34 @@ static int  Parse( int argc, char **argv,
             { "ref",     required_argument, NULL, 'r' },
             { "no-asm",  no_argument,       NULL, 'C' },
             { "sar",     required_argument, NULL, 's' },
+            { "fps",     required_argument, NULL, OPT_FPS },
+            { "frames",  required_argument, NULL, OPT_FRAMES },
             { "output",  required_argument, NULL, 'o' },
             { "analyse", required_argument, NULL, 'A' },
+            { "direct",  required_argument, NULL, OPT_DIRECT },
+            { "weightb", no_argument,       NULL, 'w' },
+            { "subme",   required_argument, NULL, 'm' },
+            { "level",   required_argument, NULL, OPT_LEVEL },
             { "rcsens",  required_argument, NULL, OPT_RCSENS },
             { "rcbuf",   required_argument, NULL, OPT_RCBUF },
-            { "rcinitbuf",required_argument, NULL, OPT_RCIBUF },
+            { "rcinitbuf",required_argument,NULL, OPT_RCIBUF },
             { "ipratio", required_argument, NULL, OPT_IPRATIO },
             { "pbratio", required_argument, NULL, OPT_PBRATIO },
+            { "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 },
+            { "no-psnr", no_argument,       NULL, OPT_NOPSNR },
+            { "quiet",   no_argument,       NULL, OPT_QUIET },
+            { "verbose", no_argument,       NULL, 'v' },
             {0, 0, 0, 0}
         };
 
         int c;
 
-        c = getopt_long( argc, argv, "hi:I:b:r:cxB:q:no:s:A:",
+        c = getopt_long( argc, argv, "hi:I:b:r:cxB:q:nf:o:s:A:m:p:vw",
                          long_options, &long_options_index);
 
         if( c == -1 )
@@ -202,23 +280,32 @@ static int  Parse( int argc, char **argv,
         switch( c )
         {
             case 'h':
-                Help();
+                Help( &defaults );
                 return -1;
 
             case 0:
                 break;
             case 'B':
-                param->i_bitrate = atol( optarg );
-                param->b_cbr = 1;
+                param->rc.i_bitrate = atol( optarg );
+                param->rc.b_cbr = 1;
                 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 'i':
-                param->i_iframe = atol( optarg );
+                param->i_keyint_min = atol( optarg );
                 break;
             case 'I':
-                param->i_idrframe = atol( optarg );
+                param->i_keyint_max = atol( optarg );
+                break;
+            case OPT_SCENECUT:
+                param->i_scenecut_threshold = atol( optarg );
                 break;
             case 'n':
                 param->b_deblocking_filter = 0;
@@ -234,16 +321,16 @@ static int  Parse( int argc, char **argv,
                 break;
             }
             case 'q':
-                param->i_qp_constant = atoi( optarg );
+                param->rc.i_qp_constant = atoi( optarg );
                 break;
             case OPT_QPMIN:
-                param->i_qp_min = atoi( optarg );
+                param->rc.i_qp_min = atoi( optarg );
                 break;
             case OPT_QPMAX:
-                param->i_qp_max = atoi( optarg );
+                param->rc.i_qp_max = atoi( optarg );
                 break;
             case OPT_QPSTEP:
-                param->i_qp_step = atoi( optarg );
+                param->rc.i_qp_step = atoi( optarg );
                 break;
             case 'r':
                 param->i_frame_reference = atoi( optarg );
@@ -257,6 +344,9 @@ static int  Parse( int argc, char **argv,
             case 'C':
                 param->cpu = 0;
                 break;
+            case OPT_FRAMES:
+                param->i_maxframes = atoi( optarg );
+                break;
             case'o':
                 if( ( *p_fout = fopen( optarg, "wb" ) ) == NULL )
                 {
@@ -274,29 +364,102 @@ static int  Parse( int argc, char **argv,
                 }
                 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;
+                }
+            }
             case 'A':
                 param->analyse.inter = 0;
                 if( strstr( optarg, "none" ) )  param->analyse.inter = 0x000000;
-                if( strstr( optarg, "all" ) )   param->analyse.inter = X264_ANALYSE_I4x4|X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8;
+                if( strstr( optarg, "all" ) )   param->analyse.inter = X264_ANALYSE_I4x4|X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16;
 
                 if( strstr( optarg, "i4x4" ) )      param->analyse.inter |= X264_ANALYSE_I4x4;
                 if( strstr( optarg, "psub16x16" ) ) param->analyse.inter |= X264_ANALYSE_PSUB16x16;
                 if( strstr( optarg, "psub8x8" ) )   param->analyse.inter |= X264_ANALYSE_PSUB8x8;
+                if( strstr( optarg, "bsub16x16" ) ) param->analyse.inter |= X264_ANALYSE_BSUB16x16;
+                break;
+            case OPT_DIRECT:
+                if( strstr( optarg, "temporal" ) )
+                    param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL;
+                else if( strstr( optarg, "spatial" ) )
+                    param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
+                else if( strstr( optarg, "none" ) )
+                    param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE;
+                else
+                    param->analyse.i_direct_mv_pred = atoi( optarg );
+                break;
+            case 'w':
+                param->analyse.b_weighted_bipred = 1;
+                break;
+            case 'm':
+                param->analyse.i_subpel_refine = atoi(optarg);
+                break;
+            case OPT_LEVEL:
+                param->i_level_idc = atoi(optarg);
                 break;
             case OPT_RCBUF:
-                param->i_rc_buffer_size = atoi(optarg);
+                param->rc.i_rc_buffer_size = atoi(optarg);
                 break;
             case OPT_RCIBUF:
-                param->i_rc_init_buffer = atoi(optarg);
+                param->rc.i_rc_init_buffer = atoi(optarg);
                 break;
             case OPT_RCSENS:
-                param->i_rc_sens = atoi(optarg);
+                param->rc.i_rc_sens = atoi(optarg);
                 break;
             case OPT_IPRATIO:
-                param->f_ip_factor = atoi(optarg);
+                param->rc.f_ip_factor = atof(optarg);
                 break;
             case OPT_PBRATIO:
-                param->f_pb_factor = atoi(optarg);
+                param->rc.f_pb_factor = atof(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_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;
             default:
                 fprintf( stderr, "unknown option (%c)\n", optopt );
@@ -307,7 +470,7 @@ static int  Parse( int argc, char **argv,
     /* Get the file name */
     if( optind > argc - 1 )
     {
-        Help();
+        Help( &defaults );
         return -1;
     }
     psz_filename = argv[optind++];
@@ -337,7 +500,7 @@ static int  Parse( int argc, char **argv,
             }
             if( psz_size == NULL )
             {
-                Help();
+                Help( &defaults );
                 return -1;
             }
             fprintf( stderr, "x264: file name gives %dx%d\n", atoi(psz), atoi(x+1) );
@@ -547,6 +710,9 @@ static int  Encode( x264_param_t  *param, FILE *fyuv, FILE *fout )
 
         int         i;
 
+        if (param->i_maxframes!=0 && i_frame>=param->i_maxframes)
+            break;
+
         /* read a frame */
         if( fread( pic.img.plane[0], 1, param->i_width * param->i_height, fyuv ) <= 0 ||
             fread( pic.img.plane[1], 1, param->i_width * param->i_height / 4, fyuv ) <= 0 ||
@@ -557,7 +723,7 @@ static int  Encode( x264_param_t  *param, FILE *fyuv, FILE *fout )
 
         /* Do not force any parameters */
         pic.i_type = X264_TYPE_AUTO;
-        if( x264_encoder_encode( h, &nal, &i_nal, &pic ) < 0 )
+        if( x264_encoder_encode( h, &nal, &i_nal, &pic, &pic ) < 0 )
         {
             fprintf( stderr, "x264_encoder_encode failed\n" );
         }
@@ -595,7 +761,7 @@ static int  Encode( x264_param_t  *param, FILE *fyuv, FILE *fout )
         double fps = (double)i_frame * (double)1000000 /
                      (double)( i_end - i_start );
 
-        fprintf( stderr, "encoded %d frames %ffps %lld kb/s\n", i_frame, fps, i_file * 8 * 25 / i_frame / 1000 );
+        fprintf( stderr, "encoded %d frames, %.2f fps, %.2f kb/s\n", i_frame, fps, (double) i_file * 8 * param->i_fps_num / ( param->i_fps_den * i_frame * 1000 ) );
     }
 
     return 0;