X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=x264.c;h=4d6465e86126030f226c4ce659f8031174604890;hb=a6c396f0fe01f453de115ba0d8c4aa26138aa6b4;hp=025bc767a010921fa72dfff9b08ea0dcca94d128;hpb=5b0cb86f27ba0c5433c404bed51c06a5124dfb49;p=x264 diff --git a/x264.c b/x264.c index 025bc767..4d6465e8 100644 --- a/x264.c +++ b/x264.c @@ -1,7 +1,7 @@ /***************************************************************************** * x264: top-level x264cli functions ***************************************************************************** - * Copyright (C) 2003-2011 x264 project + * Copyright (C) 2003-2013 x264 project * * Authors: Loren Merritt * Laurent Aimar @@ -53,6 +53,7 @@ #endif #if HAVE_SWSCALE +#undef DECLARE_ALIGNED #include #endif @@ -121,7 +122,21 @@ static const char * const muxer_names[] = static const char * const pulldown_names[] = { "none", "22", "32", "64", "double", "triple", "euro", 0 }; static const char * const log_level_names[] = { "none", "error", "warning", "info", "debug", 0 }; -static const char * const output_csp_names[] = { "i420", "i422", "i444", "rgb", 0 }; +static const char * const output_csp_names[] = +{ +#if !X264_CHROMA_FORMAT || X264_CHROMA_FORMAT == X264_CSP_I420 + "i420", +#endif +#if !X264_CHROMA_FORMAT || X264_CHROMA_FORMAT == X264_CSP_I422 + "i422", +#endif +#if !X264_CHROMA_FORMAT || X264_CHROMA_FORMAT == X264_CSP_I444 + "i444", "rgb", +#endif + 0 +}; + +static const char * const range_names[] = { "auto", "tv", "pc", 0 }; typedef struct { @@ -210,7 +225,7 @@ void x264_cli_printf( int i_level, const char *fmt, ... ) va_end( arg ); } -static void print_version_info() +static void print_version_info( void ) { #ifdef X264_POINTVER printf( "x264 "X264_POINTVER"\n" ); @@ -234,7 +249,7 @@ static void print_version_info() #else printf( "using an unknown compiler\n" ); #endif - printf( "configuration: --bit-depth=%d\n", x264_bit_depth ); + printf( "configuration: --bit-depth=%d --chroma-format=%s\n", x264_bit_depth, X264_CHROMA_FORMAT ? (output_csp_names[0]+1) : "all" ); printf( "x264 license: " ); #if HAVE_GPL printf( "GPL version 2 or later\n" ); @@ -335,19 +350,22 @@ static void print_csp_names( int longhelp ) size_t line_len = strlen( INDENT ); for( enum PixelFormat i = PIX_FMT_NONE+1; i < PIX_FMT_NB; i++ ) { - const char *pfname = av_pix_fmt_descriptors[i].name; - size_t name_len = strlen( pfname ); - if( line_len + name_len > (80 - strlen( ", " )) ) + const char *pfname = av_get_pix_fmt_name( i ); + if( pfname ) { - printf( "\n" INDENT ); - line_len = strlen( INDENT ); - } - printf( "%s", pfname ); - line_len += name_len; - if( i+1 < PIX_FMT_NB ) - { - printf( ", " ); - line_len += 2; + size_t name_len = strlen( pfname ); + if( line_len + name_len > (80 - strlen( ", " )) ) + { + printf( "\n" INDENT ); + line_len = strlen( INDENT ); + } + printf( "%s", pfname ); + line_len += name_len; + if( i+1 < PIX_FMT_NB ) + { + printf( ", " ); + line_len += 2; + } } } #endif @@ -425,7 +443,10 @@ static void help( x264_param_t *defaults, int longhelp ) H0( "\n" ); H0( " --profile Force the limits of an H.264 profile\n" " Overrides all settings.\n" ); - H2( " - baseline:\n" + H2( +#if X264_CHROMA_FORMAT <= X264_CSP_I420 +#if BIT_DEPTH==8 + " - baseline:\n" " --no-8x8dct --bframes 0 --no-cabac\n" " --cqm flat --weightp 0\n" " No interlaced.\n" @@ -435,10 +456,33 @@ static void help( x264_param_t *defaults, int longhelp ) " No lossless.\n" " - high:\n" " No lossless.\n" +#endif " - high10:\n" " No lossless.\n" - " Support for bit depth 8-10.\n" ); - else H0( " - baseline,main,high,high10\n" ); + " Support for bit depth 8-10.\n" +#endif +#if X264_CHROMA_FORMAT <= X264_CSP_I422 + " - high422:\n" + " No lossless.\n" + " Support for bit depth 8-10.\n" + " Support for 4:2:0/4:2:2 chroma subsampling.\n" +#endif + " - high444:\n" + " Support for bit depth 8-10.\n" + " Support for 4:2:0/4:2:2/4:4:4 chroma subsampling.\n" ); + else H0( + " - " +#if X264_CHROMA_FORMAT <= X264_CSP_I420 +#if BIT_DEPTH==8 + "baseline,main,high," +#endif + "high10," +#endif +#if X264_CHROMA_FORMAT <= X264_CSP_I422 + "high422," +#endif + "high444\n" + ); H0( " --preset Use a preset to select encoding settings [medium]\n" " Overridden by user settings.\n" ); H2( " - ultrafast:\n" @@ -552,8 +596,11 @@ static void help( x264_param_t *defaults, int longhelp ) H2( " --slices Number of slices per frame; forces rectangular\n" " slices and is overridden by other slicing options\n" ); else H1( " --slices Number of slices per frame\n" ); + H2( " --slices-max Absolute maximum slices per frame; overrides\n" + " slice-max-size/slice-max-mbs when necessary\n" ); H2( " --slice-max-size Limit the size of each slice in bytes\n"); - H2( " --slice-max-mbs Limit the size of each slice in macroblocks\n"); + H2( " --slice-max-mbs Limit the size of each slice in macroblocks (max)\n"); + H2( " --slice-min-mbs Limit the size of each slice in macroblocks (min)\n"); H0( " --tff Enable interlaced mode (top field first)\n" ); H0( " --bff Enable interlaced mode (bottom field first)\n" ); H2( " --constrained-intra Enable constrained intra prediction.\n" ); @@ -696,20 +743,21 @@ static void help( x264_param_t *defaults, int longhelp ) H2( " --videoformat Specify video format [\"%s\"]\n" " - component, pal, ntsc, secam, mac, undef\n", strtable_lookup( x264_vidformat_names, defaults->vui.i_vidformat ) ); - H2( " --fullrange Specify full range samples setting [\"%s\"]\n" - " - off, on\n", - strtable_lookup( x264_fullrange_names, defaults->vui.b_fullrange ) ); + H2( " --range Specify color range [\"%s\"]\n" + " - %s\n", range_names[0], stringify_names( buf, range_names ) ); H2( " --colorprim Specify color primaries [\"%s\"]\n" - " - undef, bt709, bt470m, bt470bg\n" - " smpte170m, smpte240m, film\n", + " - undef, bt709, bt470m, bt470bg, smpte170m,\n" + " smpte240m, film, bt2020\n", strtable_lookup( x264_colorprim_names, defaults->vui.i_colorprim ) ); H2( " --transfer Specify transfer characteristics [\"%s\"]\n" - " - undef, bt709, bt470m, bt470bg, linear,\n" - " log100, log316, smpte170m, smpte240m\n", + " - undef, bt709, bt470m, bt470bg, smpte170m,\n" + " smpte240m, linear, log100, log316,\n" + " iec61966-2-4, bt1361e, iec61966-2-1,\n" + " bt2020-10, bt2020-12\n", strtable_lookup( x264_transfer_names, defaults->vui.i_transfer ) ); H2( " --colormatrix Specify color matrix setting [\"%s\"]\n" - " - undef, bt709, fcc, bt470bg\n" - " smpte170m, smpte240m, GBR, YCgCo\n", + " - undef, bt709, fcc, bt470bg, smpte170m,\n" + " smpte240m, GBR, YCgCo, bt2020nc, bt2020c\n", strtable_lookup( x264_colmatrix_names, defaults->vui.i_colmatrix ) ); H2( " --chromaloc Specify chroma sample location (0 to 5) [%d]\n", defaults->vui.i_chroma_loc ); @@ -734,6 +782,8 @@ static void help( x264_param_t *defaults, int longhelp ) H1( " --output-csp Specify output colorspace [\"%s\"]\n" " - %s\n", output_csp_names[0], stringify_names( buf, output_csp_names ) ); H1( " --input-depth Specify input bit depth for raw input\n" ); + H1( " --input-range Specify input color range [\"%s\"]\n" + " - %s\n", range_names[0], stringify_names( buf, range_names ) ); H1( " --input-res Specify input resolution (width x height)\n" ); H1( " --index Filename for input index file\n" ); H0( " --sar width:height Specify Sample Aspect Ratio\n" ); @@ -742,6 +792,8 @@ static void help( x264_param_t *defaults, int longhelp ) H0( " --frames Maximum number of frames to encode\n" ); H0( " --level Specify level (as defined by Annex A)\n" ); H1( " --bluray-compat Enable compatibility hacks for Blu-ray support\n" ); + H1( " --stitchable Don't optimize headers based on video content\n" + " Ensures ability to recombine a segmented encode\n" ); H1( "\n" ); H1( " -v, --verbose Print stats for each frame\n" ); H1( " --no-progress Don't show the progress indicator while encoding\n" ); @@ -752,6 +804,7 @@ static void help( x264_param_t *defaults, int longhelp ) H1( " --psnr Enable PSNR computation\n" ); H1( " --ssim Enable SSIM computation\n" ); H1( " --threads Force a specific number of threads\n" ); + H2( " --lookahead-threads Force a specific number of lookahead threads\n" ); H2( " --sliced-threads Low-latency but lower-efficiency threading\n" ); H2( " --thread-input Run Avisynth in its own thread\n" ); H2( " --sync-lookahead Number of buffer frames for threaded lookahead\n" ); @@ -760,6 +813,9 @@ static void help( x264_param_t *defaults, int longhelp ) " as opposed to letting them select different algorithms\n" ); H2( " --asm Override CPU detection\n" ); H2( " --no-asm Disable all CPU optimizations\n" ); + H2( " --opencl Enable use of OpenCL\n" ); + H2( " --opencl-clbin Specify path of compiled OpenCL kernel cache\n" ); + H2( " --opencl-device Specify OpenCL device ordinal\n" ); H2( " --visualize Show MB types overlayed on the encoded video\n" ); H2( " --dump-yuv Save reconstructed frames\n" ); H2( " --sps-id Set SPS and PPS id numbers [%d]\n", defaults->i_sps_id ); @@ -815,7 +871,9 @@ typedef enum OPT_INPUT_CSP, OPT_INPUT_DEPTH, OPT_DTS_COMPRESSION, - OPT_OUTPUT_CSP + OPT_OUTPUT_CSP, + OPT_INPUT_RANGE, + OPT_RANGE } OptionsOPT; static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw"; @@ -862,6 +920,9 @@ static struct option long_options[] = { "ref", required_argument, NULL, 'r' }, { "asm", required_argument, NULL, 0 }, { "no-asm", no_argument, NULL, 0 }, + { "opencl", no_argument, NULL, 1 }, + { "opencl-clbin",required_argument, NULL, 0 }, + { "opencl-device",required_argument, NULL, 0 }, { "sar", required_argument, NULL, 0 }, { "fps", required_argument, NULL, OPT_FPS }, { "frames", required_argument, NULL, OPT_FRAMES }, @@ -918,11 +979,14 @@ static struct option long_options[] = { "zones", required_argument, NULL, 0 }, { "qpfile", required_argument, NULL, OPT_QPFILE }, { "threads", required_argument, NULL, 0 }, + { "lookahead-threads", required_argument, NULL, 0 }, { "sliced-threads", no_argument, NULL, 0 }, { "no-sliced-threads", no_argument, NULL, 0 }, { "slice-max-size", required_argument, NULL, 0 }, { "slice-max-mbs", required_argument, NULL, 0 }, + { "slice-min-mbs", required_argument, NULL, 0 }, { "slices", required_argument, NULL, 0 }, + { "slices-max", required_argument, NULL, 0 }, { "thread-input", no_argument, NULL, OPT_THREAD_INPUT }, { "sync-lookahead", required_argument, NULL, 0 }, { "non-deterministic", no_argument, NULL, 0 }, @@ -952,7 +1016,7 @@ static struct option long_options[] = { "cqm8p", required_argument, NULL, 0 }, { "overscan", required_argument, NULL, 0 }, { "videoformat", required_argument, NULL, 0 }, - { "fullrange", required_argument, NULL, 0 }, + { "range", required_argument, NULL, OPT_RANGE }, { "colorprim", required_argument, NULL, 0 }, { "transfer", required_argument, NULL, 0 }, { "colormatrix", required_argument, NULL, 0 }, @@ -975,6 +1039,8 @@ static struct option long_options[] = { "input-depth", required_argument, NULL, OPT_INPUT_DEPTH }, { "dts-compress", no_argument, NULL, OPT_DTS_COMPRESSION }, { "output-csp", required_argument, NULL, OPT_OUTPUT_CSP }, + { "input-range", required_argument, NULL, OPT_INPUT_RANGE }, + { "stitchable", no_argument, NULL, 0 }, {0, 0, 0, 0} }; @@ -1138,6 +1204,9 @@ static int init_vid_filters( char *sequence, hnd_t *handle, video_info_t *info, else if( output_csp == X264_CSP_RGB && (csp < X264_CSP_BGR || csp > X264_CSP_RGB) ) param->i_csp = X264_CSP_RGB; param->i_csp |= info->csp & X264_CSP_HIGH_DEPTH; + /* if the output range is not forced, assign it to the input one now */ + if( param->vui.b_fullrange == RANGE_AUTO ) + param->vui.b_fullrange = info->fullrange; if( x264_init_vid_filter( "resize", handle, &filter, info, param, NULL ) ) return -1; @@ -1199,6 +1268,7 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) memset( &input_opt, 0, sizeof(cli_input_opt_t) ); memset( &output_opt, 0, sizeof(cli_output_opt_t) ); input_opt.bit_depth = 8; + input_opt.input_range = input_opt.output_range = param->vui.b_fullrange = RANGE_AUTO; int output_csp = defaults.i_csp; opt->b_progress = 1; @@ -1357,9 +1427,21 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) case OPT_OUTPUT_CSP: FAIL_IF_ERROR( parse_enum_value( optarg, output_csp_names, &output_csp ), "Unknown output csp `%s'\n", optarg ) // correct the parsed value to the libx264 csp value +#if X264_CHROMA_FORMAT + static const uint8_t output_csp_fix[] = { X264_CHROMA_FORMAT, X264_CSP_RGB }; +#else static const uint8_t output_csp_fix[] = { X264_CSP_I420, X264_CSP_I422, X264_CSP_I444, X264_CSP_RGB }; +#endif param->i_csp = output_csp = output_csp_fix[output_csp]; break; + case OPT_INPUT_RANGE: + FAIL_IF_ERROR( parse_enum_value( optarg, range_names, &input_opt.input_range ), "Unknown input range `%s'\n", optarg ) + input_opt.input_range += RANGE_AUTO; + break; + case OPT_RANGE: + FAIL_IF_ERROR( parse_enum_value( optarg, range_names, ¶m->vui.b_fullrange ), "Unknown range `%s'\n", optarg ); + input_opt.output_range = param->vui.b_fullrange += RANGE_AUTO; + break; default: generic_option: { @@ -1410,10 +1492,11 @@ generic_option: video_info_t info = {0}; char demuxername[5]; - /* set info flags to param flags to be overwritten by demuxer as necessary. */ + /* set info flags to be overwritten by demuxer as necessary. */ info.csp = param->i_csp; info.fps_num = param->i_fps_num; info.fps_den = param->i_fps_den; + info.fullrange = input_opt.input_range == RANGE_PC; info.interlaced = param->b_interlaced; info.sar_width = param->vui.i_sar_width; info.sar_height = param->vui.i_sar_height; @@ -1432,7 +1515,7 @@ generic_option: x264_reduce_fraction( &info.sar_width, &info.sar_height ); x264_reduce_fraction( &info.fps_num, &info.fps_den ); - x264_cli_log( demuxername, X264_LOG_INFO, "%dx%d%c %d:%d @ %d/%d fps (%cfr)\n", info.width, + x264_cli_log( demuxername, X264_LOG_INFO, "%dx%d%c %u:%u @ %u/%u fps (%cfr)\n", info.width, info.height, info.interlaced ? 'i' : 'p', info.sar_width, info.sar_height, info.fps_num, info.fps_den, info.vfr ? 'v' : 'c' ); @@ -1498,6 +1581,8 @@ generic_option: info.interlaced = param->b_interlaced; info.tff = param->b_tff; } + if( input_opt.input_range != RANGE_AUTO ) + info.fullrange = input_opt.input_range; if( init_vid_filters( vid_filters, &opt->hin, &info, param, output_csp ) ) return -1; @@ -1529,6 +1614,15 @@ generic_option: x264_cli_log( "x264", X264_LOG_WARNING, "input appears to be interlaced, but not compiled with interlaced support\n" ); #endif } + /* if the user never specified the output range and the input is now rgb, default it to pc */ + int csp = param->i_csp & X264_CSP_MASK; + if( csp >= X264_CSP_BGR && csp <= X264_CSP_RGB ) + { + if( input_opt.output_range == RANGE_AUTO ) + param->vui.b_fullrange = RANGE_PC; + /* otherwise fail if they specified tv */ + FAIL_IF_ERROR( !param->vui.b_fullrange, "RGB must be PC range" ) + } /* Automatically reduce reference frame count to match the user's target level * if the user didn't explicitly set a reference frame count. */ @@ -1538,11 +1632,8 @@ generic_option: for( int 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 ) - { + while( mbs * param->i_frame_reference > x264_levels[i].dpb && param->i_frame_reference > 1 ) param->i_frame_reference--; - } break; } }