From: Fiona Glaser Date: Thu, 2 Jul 2009 04:14:57 +0000 (-0700) Subject: Totally new preset system for x264.c (not libx264), new defaults X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71b9d885aacd1cc86851248af6824ed0cd965d98;p=libx264 Totally new preset system for x264.c (not libx264), new defaults Other new features include "tune" and "profile" settings; see --help for more details. Unlike most other settings, "preset" and "tune" act before all other options. However, "profile" acts afterwards, overriding all other options. Our defaults have also changed: new defaults are --subme 7 --bframes 3 --8x8dct --no-psnr --no-ssim --threads auto --ref 3 --mixed-refs --trellis 1 --weightb --crf 23 --progress. Users will hopefully find these changes to greatly improve usability. --- diff --git a/common/common.c b/common/common.c index d7d45d32..9260c641 100644 --- a/common/common.c +++ b/common/common.c @@ -43,7 +43,7 @@ void x264_param_default( x264_param_t *param ) /* CPU autodetect */ param->cpu = x264_cpu_detect(); - param->i_threads = 1; + param->i_threads = X264_THREADS_AUTO; param->b_deterministic = 1; /* Video properties */ @@ -64,10 +64,10 @@ void x264_param_default( x264_param_t *param ) param->i_level_idc = -1; /* Encoder parameters */ - param->i_frame_reference = 1; + param->i_frame_reference = 3; param->i_keyint_max = 250; param->i_keyint_min = 25; - param->i_bframe = 0; + param->i_bframe = 3; param->i_scenecut_threshold = 40; param->i_bframe_adaptive = X264_B_ADAPT_FAST; param->i_bframe_bias = 0; @@ -80,14 +80,14 @@ void x264_param_default( x264_param_t *param ) param->b_cabac = 1; param->i_cabac_init_idc = 0; - param->rc.i_rc_method = X264_RC_NONE; + param->rc.i_rc_method = X264_RC_CRF; param->rc.i_bitrate = 0; param->rc.f_rate_tolerance = 1.0; param->rc.i_vbv_max_bitrate = 0; param->rc.i_vbv_buffer_size = 0; param->rc.f_vbv_buffer_init = 0.9; - param->rc.i_qp_constant = 26; - param->rc.f_rf_constant = 0; + param->rc.i_qp_constant = 23; + param->rc.f_rf_constant = 23; param->rc.i_qp_min = 10; param->rc.i_qp_max = 51; param->rc.i_qp_step = 4; @@ -119,17 +119,21 @@ void x264_param_default( x264_param_t *param ) param->analyse.f_psy_rd = 1.0; param->analyse.f_psy_trellis = 0; param->analyse.i_me_range = 16; - param->analyse.i_subpel_refine = 6; + param->analyse.i_subpel_refine = 7; + param->analyse.b_mixed_references = 1; param->analyse.b_chroma_me = 1; param->analyse.i_mv_range_thread = -1; param->analyse.i_mv_range = -1; // set from level_idc param->analyse.i_chroma_qp_offset = 0; param->analyse.b_fast_pskip = 1; + param->analyse.b_weighted_bipred = 1; param->analyse.b_dct_decimate = 1; + param->analyse.b_transform_8x8 = 1; + param->analyse.i_trellis = 1; param->analyse.i_luma_deadzone[0] = 21; param->analyse.i_luma_deadzone[1] = 11; - param->analyse.b_psnr = 1; - param->analyse.b_ssim = 1; + param->analyse.b_psnr = 0; + param->analyse.b_ssim = 0; param->i_cqm_preset = X264_CQM_FLAT; memset( param->cqm_4iy, 16, 16 ); @@ -262,7 +266,7 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value ) OPT("threads") { if( !strcmp(value, "auto") ) - p->i_threads = 0; + p->i_threads = X264_THREADS_AUTO; else p->i_threads = atoi(value); } diff --git a/encoder/encoder.c b/encoder/encoder.c index 205a7208..b980bbd2 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -383,6 +383,26 @@ static int x264_validate_parameters( x264_t *h ) } } + /* Detect default ffmpeg settings and terminate with an error. */ + { + int score = 0; + score += h->param.analyse.i_me_range == 0; + score += h->param.rc.i_qp_step == 3; + score += h->param.i_keyint_max == 12; + score += h->param.rc.i_qp_min == 2; + score += h->param.rc.i_qp_max == 31; + score += h->param.rc.f_qcompress == 0.5; + score += fabs(h->param.rc.f_ip_factor - 1.25) < 0.01; + score += fabs(h->param.rc.f_pb_factor - 1.25) < 0.01; + score += h->param.analyse.inter == 0 && h->param.analyse.i_subpel_refine == 8; + if( score >= 5 ) + { + x264_log( h, X264_LOG_ERROR, "broken ffmpeg default settings detected\n" ); + x264_log( h, X264_LOG_ERROR, "use an encoding preset (vpre)\n" ); + return -1; + } + } + if( h->param.rc.i_rc_method < 0 || h->param.rc.i_rc_method > 2 ) { x264_log( h, X264_LOG_ERROR, "no ratecontrol method specified\n" ); diff --git a/x264.c b/x264.c index 9aafc357..e79f9acc 100644 --- a/x264.c +++ b/x264.c @@ -161,6 +161,22 @@ static void Help( x264_param_t *defaults, int b_longhelp ) "no" #endif ); + H0( "Presets:\n" ); + H0( "\n" ); + H0( " --profile Force H.264 profile [high]\n" ); + H0( " Overrides all settings\n"); + H0( " - baseline,main,high\n" ); + H0( " --preset Use a preset to select encoding settings [medium]\n" ); + H0( " Overridden by user settings\n"); + H1( " - ultrafast,veryfast,fast,medium\n" + " - slow,slower,placebo\n" ); + else H0( " - ultrafast,veryfast,fast,medium,slow,slower\n" ); + H0( " --tune Tune the settings for a particular type of source\n" ); + H0( " Overridden by user settings\n"); + H1( " - film,animation,grain,psnr,ssim,touhou\n"); + else H0( " - film,animation,grain,psnr,ssim\n"); + H0( " --slow-firstpass Don't use faster settings with --pass 1\n" ); + H0( "\n" ); H0( "Frame-type options:\n" ); H0( "\n" ); H0( " -I, --keyint Maximum GOP size [%d]\n", defaults->i_keyint_max ); @@ -232,7 +248,7 @@ static void Help( x264_param_t *defaults, int b_longhelp ) H0( " --direct Direct MV prediction mode [\"%s\"]\n" " - none, spatial, temporal, auto\n", strtable_lookup( x264_direct_pred_names, defaults->analyse.i_direct_mv_pred ) ); - H0( " -w, --weightb Weighted prediction for B-frames\n" ); + H0( " --no-weightb Disable weighted prediction for B-frames\n" ); H0( " --me Integer pixel motion estimation method [\"%s\"]\n", strtable_lookup( x264_motion_est_names, defaults->analyse.i_me_method ) ); H1( " - dia: diamond search, radius 1 (fast)\n" @@ -258,9 +274,9 @@ static void Help( x264_param_t *defaults, int b_longhelp ) " #1: RD (requires subme>=6)\n" " #2: Trellis (requires trellis, experimental)\n", defaults->analyse.f_psy_rd, defaults->analyse.f_psy_trellis ); - H0( " --mixed-refs Decide references on a per partition basis\n" ); + H0( " --no-mixed-refs Don't decide references on a per partition basis\n" ); H1( " --no-chroma-me Ignore chroma in motion estimation\n" ); - H0( " -8, --8x8dct Adaptive spatial transform size\n" ); + H0( " --no-8x8dct Disable adaptive spatial transform size\n" ); H0( " -t, --trellis Trellis RD quantization. Requires CABAC. [%d]\n" " - 0: disabled\n" " - 1: enabled only on the final encode of a MB\n" @@ -323,12 +339,12 @@ static void Help( x264_param_t *defaults, int b_longhelp ) H0( " --level Specify level (as defined by Annex A)\n" ); H0( "\n" ); H0( " -v, --verbose Print stats for each frame\n" ); - H0( " --progress Show a progress indicator while encoding\n" ); + H0( " --no-progress Don't show the progress indicator while encoding\n" ); H0( " --quiet Quiet Mode\n" ); - H0( " --no-psnr Disable PSNR computation\n" ); - H0( " --no-ssim Disable SSIM computation\n" ); - H0( " --threads Parallel encoding\n" ); - H0( " --thread-input Run Avisynth in its own thread\n" ); + H0( " --psnr Enable PSNR computation\n" ); + H0( " --ssim Enable SSIM computation\n" ); + H0( " --threads Force a specific number of threads\n" ); + H1( " --thread-input Run Avisynth in its own thread\n" ); H1( " --non-deterministic Slightly improve quality of SMP, at the cost of repeatability\n" ); H1( " --asm Override CPU detection\n" ); H1( " --no-asm Disable all CPU optimizations\n" ); @@ -339,6 +355,133 @@ static void Help( x264_param_t *defaults, int b_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 + +static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw"; +static struct option long_options[] = +{ + { "help", no_argument, NULL, 'h' }, + { "longhelp", no_argument, NULL, OPT_LONGHELP }, + { "version", no_argument, NULL, 'V' }, + { "profile", required_argument, NULL, OPT_PROFILE }, + { "preset", required_argument, NULL, OPT_PRESET }, + { "tune", required_argument, NULL, OPT_TUNE }, + { "slow-firstpass", no_argument, NULL, OPT_SLOWFIRSTPASS }, + { "bitrate", required_argument, NULL, 'B' }, + { "bframes", required_argument, NULL, 'b' }, + { "b-adapt", required_argument, NULL, 0 }, + { "no-b-adapt", no_argument, NULL, 0 }, + { "b-bias", required_argument, NULL, 0 }, + { "b-pyramid", no_argument, NULL, 0 }, + { "min-keyint", required_argument, NULL, 'i' }, + { "keyint", required_argument, NULL, 'I' }, + { "scenecut", required_argument, NULL, 0 }, + { "no-scenecut", no_argument, NULL, 0 }, + { "nf", no_argument, NULL, 0 }, + { "no-deblock", no_argument, NULL, 0 }, + { "filter", required_argument, NULL, 0 }, + { "deblock", required_argument, NULL, 'f' }, + { "interlaced", no_argument, NULL, 0 }, + { "cabac", no_argument, NULL, 0 }, + { "no-cabac", no_argument, NULL, 0 }, + { "qp", required_argument, NULL, 'q' }, + { "qpmin", required_argument, NULL, 0 }, + { "qpmax", required_argument, NULL, 0 }, + { "qpstep", required_argument, NULL, 0 }, + { "crf", required_argument, NULL, 0 }, + { "ref", required_argument, NULL, 'r' }, + { "asm", required_argument, NULL, 0 }, + { "no-asm", no_argument, NULL, 0 }, + { "sar", required_argument, NULL, 0 }, + { "fps", required_argument, NULL, 0 }, + { "frames", required_argument, NULL, OPT_FRAMES }, + { "seek", required_argument, NULL, OPT_SEEK }, + { "output", required_argument, NULL, 'o' }, + { "analyse", required_argument, NULL, 0 }, + { "partitions", required_argument, NULL, 'A' }, + { "direct", required_argument, NULL, 0 }, + { "weightb", no_argument, NULL, 'w' }, + { "no-weightb", no_argument, NULL, 0 }, + { "me", required_argument, NULL, 0 }, + { "merange", required_argument, NULL, 0 }, + { "mvrange", required_argument, NULL, 0 }, + { "mvrange-thread", required_argument, NULL, 0 }, + { "subme", required_argument, NULL, 'm' }, + { "psy-rd", required_argument, NULL, 0 }, + { "mixed-refs", no_argument, NULL, 0 }, + { "no-mixed-refs", no_argument, NULL, 0 }, + { "no-chroma-me", no_argument, NULL, 0 }, + { "8x8dct", no_argument, NULL, 0 }, + { "no-8x8dct", no_argument, NULL, 0 }, + { "trellis", required_argument, NULL, 't' }, + { "fast-pskip", no_argument, NULL, 0 }, + { "no-fast-pskip", no_argument, NULL, 0 }, + { "no-dct-decimate", no_argument, NULL, 0 }, + { "aq-strength", required_argument, NULL, 0 }, + { "aq-mode", required_argument, NULL, 0 }, + { "deadzone-inter", required_argument, NULL, '0' }, + { "deadzone-intra", required_argument, NULL, '0' }, + { "level", required_argument, NULL, 0 }, + { "ratetol", required_argument, NULL, 0 }, + { "vbv-maxrate", required_argument, NULL, 0 }, + { "vbv-bufsize", required_argument, NULL, 0 }, + { "vbv-init", required_argument, NULL, 0 }, + { "ipratio", required_argument, NULL, 0 }, + { "pbratio", required_argument, NULL, 0 }, + { "chroma-qp-offset", required_argument, NULL, 0 }, + { "pass", required_argument, NULL, 'p' }, + { "stats", required_argument, NULL, 0 }, + { "qcomp", required_argument, NULL, 0 }, + { "qblur", required_argument, NULL, 0 }, + { "cplxblur", required_argument, NULL, 0 }, + { "zones", required_argument, NULL, 0 }, + { "qpfile", required_argument, NULL, OPT_QPFILE }, + { "threads", required_argument, NULL, 0 }, + { "thread-input", no_argument, NULL, OPT_THREAD_INPUT }, + { "non-deterministic", no_argument, NULL, 0 }, + { "psnr", no_argument, NULL, 0 }, + { "ssim", no_argument, NULL, 0 }, + { "quiet", no_argument, NULL, OPT_QUIET }, + { "verbose", no_argument, NULL, 'v' }, + { "no-progress", no_argument, NULL, OPT_NOPROGRESS }, + { "visualize", no_argument, NULL, OPT_VISUALIZE }, + { "dump-yuv", required_argument, NULL, 0 }, + { "sps-id", required_argument, NULL, 0 }, + { "aud", no_argument, NULL, 0 }, + { "nr", required_argument, NULL, 0 }, + { "cqm", required_argument, NULL, 0 }, + { "cqmfile", required_argument, NULL, 0 }, + { "cqm4", required_argument, NULL, 0 }, + { "cqm4i", required_argument, NULL, 0 }, + { "cqm4iy", required_argument, NULL, 0 }, + { "cqm4ic", required_argument, NULL, 0 }, + { "cqm4p", required_argument, NULL, 0 }, + { "cqm4py", required_argument, NULL, 0 }, + { "cqm4pc", required_argument, NULL, 0 }, + { "cqm8", required_argument, NULL, 0 }, + { "cqm8i", required_argument, NULL, 0 }, + { "cqm8p", required_argument, NULL, 0 }, + { "overscan", required_argument, NULL, 0 }, + { "videoformat", required_argument, NULL, 0 }, + { "fullrange", required_argument, NULL, 0 }, + { "colorprim", required_argument, NULL, 0 }, + { "transfer", required_argument, NULL, 0 }, + { "colormatrix", required_argument, NULL, 0 }, + { "chromaloc", required_argument, NULL, 0 }, + {0, 0, 0, 0} +}; + /***************************************************************************** * Parse: *****************************************************************************/ @@ -348,11 +491,16 @@ static int Parse( int argc, char **argv, char *psz_filename = NULL; x264_param_t defaults = *param; char *psz; + char *profile = NULL; int b_avis = 0; int b_y4m = 0; int b_thread_input = 0; + int b_turbo = 1; + int b_pass1 = 0; + int b_user_ref = 0; memset( opt, 0, sizeof(cli_opt_t) ); + opt->b_progress = 1; /* Default input file driver */ p_open_infile = open_file_yuv; @@ -367,127 +515,165 @@ static int Parse( int argc, char **argv, p_set_eop = set_eop_bsf; p_close_outfile = close_file_bsf; + /* Presets are applied before all other options. */ + for( optind = 0;; ) + { + int c = getopt_long( argc, argv, short_options, long_options, NULL ); + if( c == -1 ) + break; + + if( c == OPT_PRESET ) + { + if( !strcasecmp( optarg, "ultrafast" ) ) + { + param->i_frame_reference = 1; + param->i_scenecut_threshold = 0; + param->b_deblocking_filter = 0; + param->b_cabac = 0; + param->i_bframe = 0; + param->analyse.intra = 0; + param->analyse.inter = 0; + param->analyse.b_transform_8x8 = 0; + param->analyse.i_me_method = X264_ME_DIA; + param->analyse.i_subpel_refine = 0; + param->rc.i_aq_mode = 0; + param->analyse.b_mixed_references = 0; + param->analyse.i_trellis = 0; + } + else if( !strcasecmp( optarg, "veryfast" ) ) + { + param->analyse.inter = X264_ANALYSE_I8x8|X264_ANALYSE_I4x4; + param->analyse.i_me_method = X264_ME_DIA; + param->analyse.i_subpel_refine = 1; + param->i_frame_reference = 1; + param->analyse.b_mixed_references = 0; + param->analyse.i_trellis = 0; + } + else if( !strcasecmp( optarg, "fast" ) ) + { + param->analyse.b_mixed_references = 0; + param->i_frame_reference = 2; + param->analyse.i_subpel_refine = 4; + } + else if( !strcasecmp( optarg, "medium" ) ) + { + /* Default is medium */ + } + else if( !strcasecmp( optarg, "slow" ) ) + { + param->analyse.i_me_method = X264_ME_UMH; + param->analyse.i_subpel_refine = 8; + param->i_frame_reference = 5; + param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; + param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; + } + else if( !strcasecmp( optarg, "slower" ) ) + { + param->analyse.i_me_method = X264_ME_UMH; + param->analyse.i_subpel_refine = 9; + param->i_frame_reference = 8; + param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; + param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; + param->analyse.inter |= X264_ANALYSE_PSUB8x8; + param->analyse.i_trellis = 2; + } + else if( !strcasecmp( optarg, "placebo" ) ) + { + param->analyse.i_me_method = X264_ME_TESA; + param->analyse.i_subpel_refine = 9; + param->analyse.i_me_range = 24; + param->i_frame_reference = 16; + param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; + param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO; + param->analyse.inter |= X264_ANALYSE_PSUB8x8; + param->analyse.b_fast_pskip = 0; + param->analyse.i_trellis = 2; + param->i_bframe = 16; + } + else + { + fprintf( stderr, "x264 [error]: invalid preset: %s\n", optarg ); + return -1; + } + } + else if( c == '?' ) + return -1; + } + + /* Tunings are applied next. */ + for( optind = 0;; ) + { + int c = getopt_long( argc, argv, short_options, long_options, NULL ); + if( c == -1 ) + break; + + if( c == OPT_TUNE ) + { + if( !strcasecmp( optarg, "film" ) ) + { + param->i_deblocking_filter_alphac0 = -1; + param->i_deblocking_filter_beta = -1; + param->analyse.f_psy_trellis = 0.15; + } + else if( !strcasecmp( optarg, "animation" ) ) + { + param->i_frame_reference = param->i_frame_reference > 1 ? param->i_frame_reference*2 : 1; + param->i_deblocking_filter_alphac0 = 1; + param->i_deblocking_filter_beta = 1; + param->analyse.f_psy_rd = 0.4; + param->rc.f_aq_strength = 0.6; + param->i_bframe += 2; + } + else if( !strcasecmp( optarg, "grain" ) ) + { + param->i_deblocking_filter_alphac0 = -2; + param->i_deblocking_filter_beta = -2; + param->analyse.f_psy_trellis = 0.25; + param->analyse.b_dct_decimate = 0; + param->rc.f_pb_factor = 1.1; + param->rc.f_ip_factor = 1.1; + param->rc.f_aq_strength = 0.5; + param->analyse.i_luma_deadzone[0] = 6; + param->analyse.i_luma_deadzone[1] = 6; + param->rc.f_qcompress = 0.8; + } + else if( !strcasecmp( optarg, "psnr" ) ) + { + param->analyse.f_psy_rd = 0; + param->rc.i_aq_mode = 0; + } + else if( !strcasecmp( optarg, "ssim" ) ) + { + param->analyse.f_psy_rd = 0; + } + else if( !strcasecmp( optarg, "touhou" ) ) + { + param->i_frame_reference = param->i_frame_reference > 1 ? param->i_frame_reference*2 : 1; + param->i_deblocking_filter_alphac0 = -1; + param->i_deblocking_filter_beta = -1; + param->analyse.f_psy_trellis = 0.2; + param->rc.f_ip_factor = 2.1; + param->rc.f_aq_strength = 1.3; + if( param->analyse.inter & X264_ANALYSE_PSUB16x16 ) + param->analyse.inter |= X264_ANALYSE_PSUB8x8; + } + else + { + fprintf( stderr, "x264 [error]: invalid tune: %s\n", optarg ); + return -1; + } + } + else if( c == '?' ) + return -1; + } + /* Parse command line options */ - for( ;; ) + for( optind = 0;; ) { int b_error = 0; int long_options_index = -1; -#define OPT_FRAMES 256 -#define OPT_SEEK 257 -#define OPT_QPFILE 258 -#define OPT_THREAD_INPUT 259 -#define OPT_QUIET 260 -#define OPT_PROGRESS 261 -#define OPT_VISUALIZE 262 -#define OPT_LONGHELP 263 - - static struct option long_options[] = - { - { "help", no_argument, NULL, 'h' }, - { "longhelp",no_argument, NULL, OPT_LONGHELP }, - { "version", no_argument, NULL, 'V' }, - { "bitrate", required_argument, NULL, 'B' }, - { "bframes", required_argument, NULL, 'b' }, - { "b-adapt", required_argument, NULL, 0 }, - { "no-b-adapt", no_argument, NULL, 0 }, - { "b-bias", required_argument, NULL, 0 }, - { "b-pyramid", no_argument, NULL, 0 }, - { "min-keyint",required_argument,NULL,'i' }, - { "keyint", required_argument, NULL, 'I' }, - { "scenecut",required_argument, NULL, 0 }, - { "no-scenecut",no_argument, NULL, 0 }, - { "nf", no_argument, NULL, 0 }, - { "no-deblock", no_argument, NULL, 0 }, - { "filter", required_argument, NULL, 0 }, - { "deblock", required_argument, NULL, 'f' }, - { "interlaced", no_argument, NULL, 0 }, - { "no-cabac",no_argument, NULL, 0 }, - { "qp", required_argument, NULL, 'q' }, - { "qpmin", required_argument, NULL, 0 }, - { "qpmax", required_argument, NULL, 0 }, - { "qpstep", required_argument, NULL, 0 }, - { "crf", required_argument, NULL, 0 }, - { "ref", required_argument, NULL, 'r' }, - { "asm", required_argument, NULL, 0 }, - { "no-asm", no_argument, NULL, 0 }, - { "sar", required_argument, NULL, 0 }, - { "fps", required_argument, NULL, 0 }, - { "frames", required_argument, NULL, OPT_FRAMES }, - { "seek", required_argument, NULL, OPT_SEEK }, - { "output", required_argument, NULL, 'o' }, - { "analyse", required_argument, NULL, 0 }, - { "partitions", required_argument, NULL, 'A' }, - { "direct", required_argument, NULL, 0 }, - { "weightb", no_argument, NULL, 'w' }, - { "me", required_argument, NULL, 0 }, - { "merange", required_argument, NULL, 0 }, - { "mvrange", required_argument, NULL, 0 }, - { "mvrange-thread", required_argument, NULL, 0 }, - { "subme", required_argument, NULL, 'm' }, - { "psy-rd", required_argument, NULL, 0 }, - { "mixed-refs", no_argument, NULL, 0 }, - { "no-chroma-me", no_argument, NULL, 0 }, - { "8x8dct", no_argument, NULL, '8' }, - { "trellis", required_argument, NULL, 't' }, - { "no-fast-pskip", no_argument, NULL, 0 }, - { "no-dct-decimate", no_argument, NULL, 0 }, - { "aq-strength", required_argument, NULL, 0 }, - { "aq-mode", required_argument, NULL, 0 }, - { "deadzone-inter", required_argument, NULL, '0' }, - { "deadzone-intra", required_argument, NULL, '0' }, - { "level", required_argument, NULL, 0 }, - { "ratetol", required_argument, NULL, 0 }, - { "vbv-maxrate", required_argument, NULL, 0 }, - { "vbv-bufsize", required_argument, NULL, 0 }, - { "vbv-init", required_argument,NULL, 0 }, - { "ipratio", required_argument, NULL, 0 }, - { "pbratio", required_argument, NULL, 0 }, - { "chroma-qp-offset", required_argument, NULL, 0 }, - { "pass", required_argument, NULL, 'p' }, - { "stats", required_argument, NULL, 0 }, - { "qcomp", required_argument, NULL, 0 }, - { "qblur", required_argument, NULL, 0 }, - { "cplxblur",required_argument, NULL, 0 }, - { "zones", required_argument, NULL, 0 }, - { "qpfile", required_argument, NULL, OPT_QPFILE }, - { "threads", required_argument, NULL, 0 }, - { "thread-input", no_argument, NULL, OPT_THREAD_INPUT }, - { "non-deterministic", no_argument, NULL, 0 }, - { "no-psnr", no_argument, NULL, 0 }, - { "no-ssim", no_argument, NULL, 0 }, - { "quiet", no_argument, NULL, OPT_QUIET }, - { "verbose", no_argument, NULL, 'v' }, - { "progress",no_argument, NULL, OPT_PROGRESS }, - { "visualize",no_argument, NULL, OPT_VISUALIZE }, - { "dump-yuv",required_argument, NULL, 0 }, - { "sps-id", required_argument, NULL, 0 }, - { "aud", no_argument, NULL, 0 }, - { "nr", required_argument, NULL, 0 }, - { "cqm", required_argument, NULL, 0 }, - { "cqmfile", required_argument, NULL, 0 }, - { "cqm4", required_argument, NULL, 0 }, - { "cqm4i", required_argument, NULL, 0 }, - { "cqm4iy", required_argument, NULL, 0 }, - { "cqm4ic", required_argument, NULL, 0 }, - { "cqm4p", required_argument, NULL, 0 }, - { "cqm4py", required_argument, NULL, 0 }, - { "cqm4pc", required_argument, NULL, 0 }, - { "cqm8", required_argument, NULL, 0 }, - { "cqm8i", required_argument, NULL, 0 }, - { "cqm8p", required_argument, NULL, 0 }, - { "overscan", required_argument, NULL, 0 }, - { "videoformat", required_argument, NULL, 0 }, - { "fullrange", required_argument, NULL, 0 }, - { "colorprim", required_argument, NULL, 0 }, - { "transfer", required_argument, NULL, 0 }, - { "colormatrix", required_argument, NULL, 0 }, - { "chromaloc", required_argument, NULL, 0 }, - {0, 0, 0, 0} - }; - - int c = getopt_long( argc, argv, "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw", - long_options, &long_options_index); + int c = getopt_long( argc, argv, short_options, long_options, &long_options_index ); if( c == -1 ) { @@ -568,8 +754,8 @@ static int Parse( int argc, char **argv, case 'v': param->i_log_level = X264_LOG_DEBUG; break; - case OPT_PROGRESS: - opt->b_progress = 1; + case OPT_NOPROGRESS: + opt->b_progress = 0; break; case OPT_VISUALIZE: #ifdef VISUALIZE @@ -579,7 +765,23 @@ static int Parse( int argc, char **argv, fprintf( stderr, "x264 [warning]: not compiled with visualization support\n" ); #endif break; + case OPT_TUNE: + case OPT_PRESET: + break; + case OPT_PROFILE: + profile = optarg; + break; + case OPT_SLOWFIRSTPASS: + b_turbo = 0; + break; + case 'r': + b_user_ref = 1; + goto generic_option; + case 'p': + b_pass1 = atoi( optarg ) == 1; + goto generic_option; default: +generic_option: { int i; if( long_options_index < 0 ) @@ -609,6 +811,72 @@ static int Parse( int argc, char **argv, } } + /* Set faster options in case of turbo firstpass. */ + if( b_turbo && b_pass1 ) + { + param->i_frame_reference = 1; + param->analyse.b_transform_8x8 = 0; + param->analyse.inter = 0; + param->analyse.i_me_method = X264_ME_DIA; + param->analyse.i_subpel_refine = X264_MIN( 2, param->analyse.i_subpel_refine ); + param->analyse.i_trellis = 0; + } + + /* Automatically reduce reference frame count to match the user's target level + * if the user didn't explicitly set a reference frame count. */ + if( !b_user_ref ) + { + int mbs = (((param->i_width)+15)>>4) * (((param->i_height)+15)>>4); + int i; + for( i = 0; x264_levels[i].level_idc != 0; i++ ) + if( param->i_level_idc == x264_levels[i].level_idc ) + { + while( mbs * 384 * param->i_frame_reference > x264_levels[i].dpb + && param->i_frame_reference > 1 ) + { + param->i_frame_reference--; + } + break; + } + } + + /* Apply profile restrictions. */ + if( profile ) + { + if( !strcasecmp( profile, "baseline" ) ) + { + param->analyse.b_transform_8x8 = 0; + param->b_cabac = 0; + param->i_cqm_preset = X264_CQM_FLAT; + param->i_bframe = 0; + if( param->b_interlaced ) + { + fprintf( stderr, "x264 [error]: baseline profile doesn't support interlacing\n" ); + return -1; + } + } + else if( !strcasecmp( profile, "main" ) ) + { + param->analyse.b_transform_8x8 = 0; + param->i_cqm_preset = X264_CQM_FLAT; + } + else if( !strcasecmp( profile, "high" ) ) + { + /* Default */ + } + else + { + fprintf( stderr, "x264 [error]: invalid profile: %s\n", profile ); + return -1; + } + if( (param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0) || + (param->rc.i_rc_method == X264_RC_CRF && param->rc.f_rf_constant == 0) ) + { + fprintf( stderr, "x264 [error]: %s profile doesn't support lossless\n", profile ); + return -1; + } + } + /* Get the file name */ if( optind > argc - 1 || !opt->hout ) { diff --git a/x264.h b/x264.h index 26ac421c..e61040e5 100644 --- a/x264.h +++ b/x264.h @@ -35,7 +35,7 @@ #include -#define X264_BUILD 67 +#define X264_BUILD 68 /* x264_t: * opaque handler for encoder */ @@ -83,7 +83,6 @@ typedef struct x264_t x264_t; #define X264_CQM_FLAT 0 #define X264_CQM_JVT 1 #define X264_CQM_CUSTOM 2 -#define X264_RC_NONE -1 #define X264_RC_CQP 0 #define X264_RC_CRF 1 #define X264_RC_ABR 2 @@ -103,8 +102,7 @@ static const char * const x264_transfer_names[] = { "", "bt709", "undef", "", "b static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m", "smpte240m", "YCgCo", 0 }; /* Colorspace type - * legacy only; nothing other than I420 is really supported. - */ + * legacy only; nothing other than I420 is really supported. */ #define X264_CSP_MASK 0x00ff /* */ #define X264_CSP_NONE 0x0000 /* Invalid mode */ #define X264_CSP_I420 0x0001 /* yuv 4:2:0 planar */ @@ -118,8 +116,7 @@ static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "" #define X264_CSP_MAX 0x0009 /* end of list */ #define X264_CSP_VFLIP 0x1000 /* */ -/* Slice type - */ +/* Slice type */ #define X264_TYPE_AUTO 0x0000 /* Let x264 choose the right type */ #define X264_TYPE_IDR 0x0001 #define X264_TYPE_I 0x0002 @@ -129,14 +126,16 @@ static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "" #define IS_X264_TYPE_I(x) ((x)==X264_TYPE_I || (x)==X264_TYPE_IDR) #define IS_X264_TYPE_B(x) ((x)==X264_TYPE_B || (x)==X264_TYPE_BREF) -/* Log level - */ +/* Log level */ #define X264_LOG_NONE (-1) #define X264_LOG_ERROR 0 #define X264_LOG_WARNING 1 #define X264_LOG_INFO 2 #define X264_LOG_DEBUG 3 +/* Threading */ +#define X264_THREADS_AUTO 0 /* Automatically select optimal number of threads */ + /* Zones: override ratecontrol or other options for specific sections of the video. * See x264_encoder_reconfig() for which options can be changed. * If zones overlap, whichever comes later in the list takes precedence. */