x264源代码简单分析 x264命令行工具(x264 exe)

               

=====================================================

H.264源代码分析文章列表:

【编码 - x264】

x264源代码简单分析:概述

x264源代码简单分析:x264命令行工具(x264.exe)

x264源代码简单分析:编码器主干部分-1

x264源代码简单分析:编码器主干部分-2

x264源代码简单分析:x264_slice_write()

x264源代码简单分析:滤波(Filter)部分

x264源代码简单分析:宏块分析(Analysis)部分-帧内宏块(Intra)

x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)

x264源代码简单分析:宏块编码(Encode)部分

x264源代码简单分析:熵编码(Entropy Encoding)部分

FFmpeg与libx264接口源代码简单分析

【解码 - libavcodec H.264 解码器】

FFmpeg的H.264解码器源代码简单分析:概述

FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分

FFmpeg的H.264解码器源代码简单分析:解码器主干部分

FFmpeg的H.264解码器源代码简单分析:熵解码(EntropyDecoding)部分

FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧内宏块(Intra)

FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分

=====================================================


本文简单分析x264项目中的命令行工具(x264.exe)的源代码。该命令行工具可以调用libx264将YUV格式像素数据编码为H.264码流。



函数调用关系图

X264命令行工具的源代码在x264中的位置如下图所示。


单击查看更清晰的图片

X264命令行工具的源代码的调用关系如下图所示。
 
单击查看更清晰的图片

从图中可以看出,X264命令行工具调用了libx264的几个API完成了H.264编码工作。使用libx264的API进行编码可以参考《 最简单的视频编码器:基于libx264(编码YUV为H.264)》,这个流程中最关键的API包括:
x264_param_default():设置参数集结构体x264_param_t的缺省值。
x264_encoder_open():打开编码器。
x264_encoder_headers():输出SPS,PPS,SEI等信息。
x264_encoder_encode():编码输出一帧图像。
x264_encoder_close():关闭编码器。

在X264命令行工具中,main()首先调用parse()解析输入的命令行参数,然后调用encode()进行编码。parse()首先调用x264_param_default()为存储参数的结构体x264_param_t赋默认值;然后在一个大循环中调用getopt_long()逐个解析输入的参数,并作相应的处理;最后调用select_input()和select_output()解析输入文件格式(例如yuv,y4m…)和输出文件格式(例如raw,flv,MP4…)。encode()首先调用x264_encoder_open()打开H.264编码器,然后调用x264_encoder_headers()输出H.264码流的头信息(例如SPS、PPS、SEI),接着进入一个循环并且调用encode_frame()逐帧编码视频,最后调用x264_encoder_close()关闭解码器。其中encode_frame()中又调用了x264_encoder_encode()完成了具体的编码工作。下文将会对上述流程展开分析。



main()

main()是x264控制台程序的入口函数,定义如下所示。
//主函数int main( int argc, char **argv )//参数集    x264_param_t param;    cli_opt_t opt = {0};    int ret = 0;    FAIL_IF_ERROR( x264_threading_init(), "unable to initialize threading\n" )#ifdef _WIN32    FAIL_IF_ERROR( !get_argv_utf8( &argc, &argv ), "unable to convert command line to UTF-8\n" )    GetConsoleTitleW( org_console_title, CONSOLE_TITLE_SIZE );    _setmode( _fileno( stdin ),  _O_BINARY );    _setmode( _fileno( stdout ), _O_BINARY );    _setmode( _fileno( stderr ), _O_BINARY );#endif    /* Parse command line */    //解析命令行输入    if( parse( argc, argv, ¶m, &opt ) < 0 )        ret = -1;#ifdef _WIN32    /* Restore title; it can be changed by input modules */    SetConsoleTitleW( org_console_title );#endif    /* Control-C handler */    signal( SIGINT, sigint_handler );    //编码    if( !ret )        ret = encode( ¶m, &opt );    /* clean up handles */    if( filter.free )        filter.free( opt.hin );    else if( opt.hin )        cli_input.close_file( opt.hin );    if( opt.hout )        cli_output.close_file( opt.hout, 0, 0 );    if( opt.tcfile_out )        fclose( opt.tcfile_out );    if( opt.qpfile )        fclose( opt.qpfile );#ifdef _WIN32    SetConsoleTitleW( org_console_title );    free( argv );#endif    return ret;}

可以看出main()的定义很简单,它主要调用了两个函数:parse()和encode()。main()首先调用parse()解析输入的命令行参数,然后调用encode()进行编码。下面分别分析这两个函数。



parse()

parse()用于解析命令行输入的参数(存储于argv[]中)。它的定义如下所示。
//解析命令行输入static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ){    char *input_filename = NULL;    const char *demuxer = demuxer_names[0];    char *output_filename = NULL;    const char *muxer = muxer_names[0];    char *tcfile_name = NULL;    x264_param_t defaults;    char *profile = NULL;    char *vid_filters = NULL;    int b_thread_input = 0;    int b_turbo = 1;    int b_user_ref = 0;    int b_user_fps = 0;    int b_user_interlaced = 0;    cli_input_opt_t input_opt;    cli_output_opt_t output_opt;    char *preset = NULL;    char *tune = NULL;    //初始化参数默认值    x264_param_default( &defaults );    cli_log_level = defaults.i_log_level;    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;    /* 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 )            preset = optarg;        if( c == OPT_TUNE )            tune = optarg;        else if( c == '?' )            return -1;    }    if( preset && !strcasecmp( preset, "placebo" ) )        b_turbo = 0;    //设置preset,tune    if( x264_param_default_preset( param, preset, tune ) < 0 )        return -1;    /* Parse command line options */    //解析命令行选项    for( optind = 0;; )    {        int b_error = 0;        int long_options_index = -1;        int c = getopt_long( argc, argv, short_options, long_options, &long_options_index );        if( c == -1 )        {            break;        }        //不同的选项做不同的处理        switch( c )        {            case 'h':                help( &defaults, 0 );//"-h"帮助菜单                exit(0);            case OPT_LONGHELP:                help( &defaults, 1 );                exit(0);            case OPT_FULLHELP:                help( &defaults, 2 );                exit(0);            case 'V':                print_version_info();//打印版本信息                exit(0);            case OPT_FRAMES:                param->i_frame_total = X264_MAX( atoi( optarg ), 0 );                break;            case OPT_SEEK:                opt->i_seek = X264_MAX( atoi( optarg ), 0 );                break;            case 'o':                output_filename = optarg;//输出文件路径                break;            case OPT_MUXER:                FAIL_IF_ERROR( parse_enum_name( optarg, muxer_names, &muxer ), "Unknown muxer `%s'\n", optarg )                break;            case OPT_DEMUXER:                FAIL_IF_ERROR( parse_enum_name( optarg, demuxer_names, &demuxer ), "Unknown demuxer `%s'\n", optarg )                break;            case OPT_INDEX:                input_opt.index_file = optarg;                break;            case OPT_QPFILE:                opt->qpfile = x264_fopen( optarg, "rb" );                FAIL_IF_ERROR( !opt->qpfile, "can't open qpfile `%s'\n", optarg )                if( !x264_is_regular_file( opt->qpfile ) )                {                    x264_cli_log( "x264", X264_LOG_ERROR, "qpfile incompatible with non-regular file `%s'\n", optarg );                    fclose( opt->qpfile );                    return -1;                }                break;            case OPT_THREAD_INPUT:                b_thread_input = 1;                break;            case OPT_QUIET:                cli_log_level = param->i_log_level = X264_LOG_NONE;//设置log级别                break;            case 'v':                cli_log_level = param->i_log_level = X264_LOG_DEBUG;//设置log级别                break;            case OPT_LOG_LEVEL:                if( !parse_enum_value( optarg, log_level_names, &cli_log_level ) )                    cli_log_level += X264_LOG_NONE;                else                    cli_log_level = atoi( optarg );                param->i_log_level = cli_log_level;//设置log级别                break;            case OPT_NOPROGRESS:                opt->b_progress = 0;                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 OPT_FPS:                b_user_fps = 1;                param->b_vfr_input = 0;                goto generic_option;            case OPT_INTERLACED:                b_user_interlaced = 1;                goto generic_option;            case OPT_TCFILE_IN:                tcfile_name = optarg;                break;            case OPT_TCFILE_OUT:                opt->tcfile_out = x264_fopen( optarg, "wb" );                FAIL_IF_ERROR( !opt->tcfile_out, "can't open `%s'\n", optarg )                break;            case OPT_TIMEBASE:                input_opt.timebase = optarg;                break;            case OPT_PULLDOWN:                FAIL_IF_ERROR( parse_enum_value( optarg, pulldown_names, &opt->i_pulldown ), "Unknown pulldown `%s'\n", optarg )                break;            case OPT_VIDEO_FILTER:                vid_filters = optarg;                break;            case OPT_INPUT_FMT:                input_opt.format = optarg;//输入文件格式                break;            case OPT_INPUT_RES:                input_opt.resolution = optarg;//输入分辨率                break;            case OPT_INPUT_CSP:                input_opt.colorspace = optarg;//输入色域                break;            case OPT_INPUT_DEPTH:                input_opt.bit_depth = atoi( optarg );//输入颜色位深                break;            case OPT_DTS_COMPRESSION:                output_opt.use_dts_compress = 1;                break;            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:            {                if( long_options_index < 0 )                {                    for( int i = 0; long_options[i].name; i++ )                        if( long_options[i].val == c )                        {                            long_options_index = i;                            break;                        }                    if( long_options_index < 0 )                    {                        /* getopt_long already printed an error message */                        return -1;                    }                }                //解析以字符串方式输入的参数                //即选项名称和选项值都是字符串                b_error |= x264_param_parse( param, long_options[long_options_index].name, optarg );            }        }        if( b_error )        {            const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind-2];            x264_cli_log( "x264", X264_LOG_ERROR, "invalid argument: %s = %s\n", name, optarg );            return -1;        }    }    /* If first pass mode is used, apply faster settings. */    if( b_turbo )        x264_param_apply_fastfirstpass( param );    /* Apply profile restrictions. */    //设置profile    if( x264_param_apply_profile( param, profile ) < 0 )        return -1;    /* Get the file name */    FAIL_IF_ERROR( optind > argc - 1 || !output_filename, "No %s file. Run x264 --help for a list of options.\n",                   optind > argc - 1 ? "input" : "output" )    //根据文件名的后缀确定输出的文件格式(raw H264,flv,mp4...)    if( select_output( muxer, output_filename, param ) )        return -1;    FAIL_IF_ERROR( cli_output.open_file( output_filename, &opt->hout, &output_opt ), "could not open output file `%s'\n", output_filename )    //输入文件路径    input_filename = argv[optind++];    video_info_t info = {0};    char demuxername[5];    /* set info flags to be overwritten by demuxer as necessary. */    //设置info结构体    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;    if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 )    {        info.sar_width  = param->vui.i_sar_width;        info.sar_height = param->vui.i_sar_height;    }    info.tff        = param->b_tff;    info.vfr        = param->b_vfr_input;    input_opt.seek = opt->i_seek;    input_opt.progress = opt->b_progress;    input_opt.output_csp = output_csp;    //设置输入文件的格式(yuv,y4m...)    if( select_input( demuxer, demuxername, input_filename, &opt->hin, &info, &input_opt ) )        return -1;    FAIL_IF_ERROR( !opt->hin && cli_input.open_file( input_filename, &opt->hin, &info, &input_opt ),                   "could not open input file `%s'\n", input_filename )    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 %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' );    if( tcfile_name )    {        FAIL_IF_ERROR( b_user_fps, "--fps + --tcfile-in is incompatible.\n" )        FAIL_IF_ERROR( timecode_input.open_file( tcfile_name, &opt->hin, &info, &input_opt ), "timecode input failed\n" )        cli_input = timecode_input;    }    else FAIL_IF_ERROR( !info.vfr && input_opt.timebase, "--timebase is incompatible with cfr input\n" )    /* init threaded input while the information about the input video is unaltered by filtering */#if HAVE_THREAD    if( info.thread_safe && (b_thread_input || param->i_threads > 1        || (param->i_threads == X264_THREADS_AUTO && x264_cpu_num_processors() > 1)) )    {        if( thread_input.open_file( NULL, &opt->hin, &info, NULL ) )        {            fprintf( stderr, "x264 [error]: threaded input failed\n" );            return -1;        }        cli_input = thread_input;    }#endif    /* override detected values by those specified by the user */    if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 )    {        info.sar_width  = param->vui.i_sar_width;        info.sar_height = param->vui.i_sar_height;    }    if( b_user_fps )    {        info.fps_num = param->i_fps_num;        info.fps_den = param->i_fps_den;    }    if( !info.vfr )    {        info.timebase_num = info.fps_den;        info.timebase_den = info.fps_num;    }    if( !tcfile_name && input_opt.timebase )    {        uint64_t i_user_timebase_num;        uint64_t i_user_timebase_den;        int ret = sscanf( input_opt.timebase, "%"SCNu64"/%"SCNu64, &i_user_timebase_num, &i_user_timebase_den );        FAIL_IF_ERROR( !ret, "invalid argument: timebase = %s\n", input_opt.timebase )        else if( ret == 1 )        {            i_user_timebase_num = info.timebase_num;            i_user_timebase_den = strtoul( input_opt.timebase, NULL, 10 );        }        FAIL_IF_ERROR( i_user_timebase_num > UINT32_MAX || i_user_timebase_den > UINT32_MAX,                       "timebase you specified exceeds H.264 maximum\n" )        opt->timebase_convert_multiplier = ((double)i_user_timebase_den / info.timebase_den)                                         * ((double)info.timebase_num / i_user_timebase_num);        info.timebase_num = i_user_timebase_num;        info.timebase_den = i_user_timebase_den;        info.vfr = 1;    }    if( b_user_interlaced )    {        info.interlaced = param->b_interlaced;        info.tff = param->b_tff;    }    if( input_opt.input_range != RANGE_AUTO )        info.fullrange = input_opt.input_range;    //初始化滤镜filter    //filter可以认为是一种“扩展”了的输入源    if( init_vid_filters( vid_filters, &opt->hin, &info, param, output_csp ) )        return -1;    /* set param flags from the post-filtered video */    param->b_vfr_input = info.vfr;    param->i_fps_num = info.fps_num;    param->i_fps_den = info.fps_den;    param->i_timebase_num = info.timebase_num;    param->i_timebase_den = info.timebase_den;    param->vui.i_sar_width  = info.sar_width;    param->vui.i_sar_height = info.sar_height;    info.num_frames = X264_MAX( info.num_frames - opt->i_seek, 0 );    if( (!info.num_frames || param->i_frame_total < info.num_frames)        && param->i_frame_total > 0 )        info.num_frames = param->i_frame_total;    param->i_frame_total = info.num_frames;    if( !b_user_interlaced && info.interlaced )    {#if HAVE_INTERLACED        x264_cli_log( "x264", X264_LOG_WARNING, "input appears to be interlaced, enabling %cff interlaced mode.\n"                      "                If you want otherwise, use --no-interlaced or --%cff\n",                      info.tff ? 't' : 'b', info.tff ? 'b' : 't' );        param->b_interlaced = 1;        param->b_tff = !!info.tff;#else        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. */    if( !b_user_ref )    {        int mbs = (((param->i_width)+15)>>4) * (((param->i_height)+15)>>4);        for( int i = 0; x264_levels[i].level_idc != 0; i++ )            if( param->i_level_idc == x264_levels[i].level_idc )            {                while( mbs * param->i_frame_reference > x264_levels[i].dpb && param->i_frame_reference > 1 )                    param->i_frame_reference--;                break;            }    }    return 0;}

下面简单梳理parse()的流程:
(1)调用x264_param_default()为存储参数的结构体x264_param_t赋默认值
(2)调用x264_param_default_preset()为x264_param_t赋值
(3)在一个大循环中调用getopt_long()逐个解析输入的参数,并作相应的处理。举几个例子:
a)“-h”:调用help()打开帮助菜单。
b)“-V”调用print_version_info()打印版本信息。
c)对于长选项,调用x264_param_parse()进行处理。
(4)调用select_input()解析输出文件格式(例如raw,flv,MP4…)
(5)调用select_output()解析输入文件格式(例如yuv,y4m…)

下文按照顺序记录parse()中涉及到的函数:

x264_param_default()
x264_param_default_preset()
help()
print_version_info()
x264_param_parse()
select_input()
select_output()

x264_param_default()

x264_param_default()是一个x264的API。该函数用于设置x264中x264_param_t结构体的默认值。函数的声明如下所示。
/* x264_param_default: *      fill x264_param_t with default values and do CPU detection */void    x264_param_default( x264_param_t * );
x264_param_default()的定义如下所示。
/**************************************************************************** * x264_param_default: ****************************************************************************///初始化参数默认值void x264_param_default( x264_param_t *param ){    /* */    memset( param, 0, sizeof( x264_param_t ) );    /* CPU autodetect */    param->cpu = x264_cpu_detect();    param->i_threads = X264_THREADS_AUTO;    param->i_lookahead_threads = X264_THREADS_AUTO;    param->b_deterministic = 1;    param->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO;    /* Video properties */    param->i_csp           = X264_CHROMA_FORMAT ? X264_CHROMA_FORMAT : X264_CSP_I420;    param->i_width         = 0;    param->i_height        = 0;    param->vui.i_sar_width = 0;    param->vui.i_sar_height= 0;    param->vui.i_overscan  = 0/* undef */    param->vui.i_vidformat = 5/* undef */    param->vui.b_fullrange = -1; /* default depends on input */    param->vui.i_colorprim = 2/* undef */    param->vui.i_transfer  = 2/* undef */    param->vui.i_colmatrix = -1; /* default depends on input */    param->vui.i_chroma_loc= 0/* left center */    param->i_fps_num       = 25;    param->i_fps_den       = 1;    param->i_level_idc     = -1;    param->i_slice_max_size = 0;    param->i_slice_max_mbs = 0;    param->i_slice_count = 0;    /* Encoder parameters */    //编码参数--最常见    param->i_frame_reference = 3;    param->i_keyint_max = 250;    param->i_keyint_min = X264_KEYINT_MIN_AUTO;    param->i_bframe = 3;    param->i_scenecut_threshold = 40;    param->i_bframe_adaptive = X264_B_ADAPT_FAST;    param->i_bframe_bias = 0;    param->i_bframe_pyramid = X264_B_PYRAMID_NORMAL;    param->b_interlaced = 0;    param->b_constrained_intra = 0;    param->b_deblocking_filter = 1;    param->i_deblocking_filter_alphac0 = 0;    param->i_deblocking_filter_beta = 0;    param->b_cabac = 1;    param->i_cabac_init_idc = 0;    //码率控制模块 Rate Control    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 = 23 + QP_BD_OFFSET;    param->rc.f_rf_constant = 23;    param->rc.i_qp_min = 0;    param->rc.i_qp_max = QP_MAX;    param->rc.i_qp_step = 4;    param->rc.f_ip_factor = 1.4;    param->rc.f_pb_factor = 1.3;    param->rc.i_aq_mode = X264_AQ_VARIANCE;    param->rc.f_aq_strength = 1.0;    param->rc.i_lookahead = 40;    param->rc.b_stat_write = 0;    param->rc.psz_stat_out = "x264_2pass.log";    param->rc.b_stat_read = 0;    param->rc.psz_stat_in = "x264_2pass.log";    param->rc.f_qcompress = 0.6;    param->rc.f_qblur = 0.5;    param->rc.f_complexity_blur = 20;    param->rc.i_zones = 0;    param->rc.b_mb_tree = 1;    /* Log */    //日志模块    param->pf_log = x264_log_default;    param->p_log_private = NULL;    param->i_log_level = X264_LOG_INFO;    /* */    //分析模块 Analysis    param->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8;    param->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8                         | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;    param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;    param->analyse.i_me_method = X264_ME_HEX;    param->analyse.f_psy_rd = 1.0;    param->analyse.b_psy = 1;    param->analyse.f_psy_trellis = 0;    param->analyse.i_me_range = 16;    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.i_weighted_pred = X264_WEIGHTP_SMART;    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 = 0;    param->analyse.b_ssim = 0;    param->i_cqm_preset = X264_CQM_FLAT;    memset( param->cqm_4iy, 16, sizeof( param->cqm_4iy ) );    memset( param->cqm_4py, 16, sizeof( param->cqm_4py ) );    memset( param->cqm_4ic, 16, sizeof( param->cqm_4ic ) );    memset( param->cqm_4pc, 16, sizeof( param->cqm_4pc ) );    memset( param->cqm_8iy, 16, sizeof( param->cqm_8iy ) );    memset( param->cqm_8py, 16, sizeof( param->cqm_8py ) );    memset( param->cqm_8ic, 16, sizeof( param->cqm_8ic ) );    memset( param->cqm_8pc, 16, sizeof( param->cqm_8pc ) );    param->b_repeat_headers = 1;    param->b_annexb = 1;    param->b_aud = 0;    param->b_vfr_input = 1;    param->i_nal_hrd = X264_NAL_HRD_NONE;    param->b_tff = 1;    param->b_pic_struct = 0;    param->b_fake_interlaced = 0;    param->i_frame_packing = -1;    param->b_opencl = 0;    param->i_opencl_device = 0;    param->opencl_device_id = NULL;    param->psz_clbin_file = NULL;}

从源代码可以看出,x264_param_default()对输入的存储参数的结构体x264_param_t的成员变量进行了赋值工作。

x264_param_default_preset()

x264_param_default_preset()是一个libx264的API,用于设置x264的preset和tune。该函数的声明如下所示。
/*      Multiple tunings can be used if separated by a delimiter in ",./-+", *      however multiple psy tunings cannot be used. *      film, animation, grain, stillimage, psnr, and ssim are psy tunings. * *      returns 0 on success, negative on failure (e.g. invalid preset/tune name). */int     x264_param_default_preset( x264_param_t *, const char *preset, const char *tune );
x264_param_default_preset()的定义如下所示。
//设置preset,tuneint x264_param_default_preset( x264_param_t *param, const char *preset, const char *tune ){    x264_param_default( param );    //设置preset    if( preset && x264_param_apply_preset( param, preset ) < 0 )        return -1;    //设置tune    if( tune && x264_param_apply_tune( param, tune ) < 0 )        return -1;    return 0;}

从源代码可以看出,x264_param_default_preset()调用x264_param_apply_preset()设置preset,调用x264_param_apply_tune()设置tune。记录一下这两个函数。

x264_param_apply_preset()
x264_param_apply_preset()用于设置preset。该函数的定义如下所示。
//设置presetstatic int x264_param_apply_preset( x264_param_t *param, const char *preset ){    char *end;    int i = strtol( preset, &end, 10 );    if( *end == 0 && i >= 0 && i < sizeof(x264_preset_names)/sizeof(*x264_preset_names)-1 )        preset = x264_preset_names[i];    //几种不同的preset设置不同的参数    if( !strcasecmp( preset, "ultrafast" ) )    {        param->i_frame_reference = 1;        param->i_scenecut_threshold = 0;        param->b_deblocking_filter = 0;//不使用去块滤波        param->b_cabac = 0;//不使用CABAC        param->i_bframe = 0;//不使用B帧        param->analyse.intra = 0;        param->analyse.inter = 0;        param->analyse.b_transform_8x8 = 0;//不使用8x8DCT        param->analyse.i_me_method = X264_ME_DIA;//运动搜索方法使用“Diamond”        param->analyse.i_subpel_refine = 0;        param->rc.i_aq_mode = 0;        param->analyse.b_mixed_references = 0;        param->analyse.i_trellis = 0;        param->i_bframe_adaptive = X264_B_ADAPT_NONE;        param->rc.b_mb_tree = 0;        param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;//不使用加权        param->analyse.b_weighted_bipred = 0;        param->rc.i_lookahead = 0;    }    else if( !strcasecmp( preset, "superfast" ) )    {        param->analyse.inter = X264_ANALYSE_I8x8|X264_ANALYSE_I4x4;        param->analyse.i_me_method = X264_ME_DIA;//钻石模板        param->analyse.i_subpel_refine = 1;//亚像素运动估计质量为1        param->i_frame_reference = 1;        param->analyse.b_mixed_references = 0;        param->analyse.i_trellis = 0;        param->rc.b_mb_tree = 0;        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;        param->rc.i_lookahead = 0;    }    else if( !strcasecmp( preset, "veryfast" ) )    {        param->analyse.i_me_method = X264_ME_HEX;//六边形模板        param->analyse.i_subpel_refine = 2;        param->i_frame_reference = 1;        param->analyse.b_mixed_references = 0;        param->analyse.i_trellis = 0;        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;        param->rc.i_lookahead = 10;    }    else if( !strcasecmp( preset, "faster" ) )    {        param->analyse.b_mixed_references = 0;        param->i_frame_reference = 2;        param->analyse.i_subpel_refine = 4;        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;        param->rc.i_lookahead = 20;    }    else if( !strcasecmp( preset, "fast" ) )    {        param->i_frame_reference = 2;        param->analyse.i_subpel_refine = 6;        param->analyse.i_weighted_pred = X264_WEIGHTP_SIMPLE;        param->rc.i_lookahead = 30;    }    else if( !strcasecmp( preset, "medium" ) )    {        /* Default is medium */    }    else if( !strcasecmp( preset, "slow" ) )    {        param->analyse.i_me_method = X264_ME_UMH;//UMH相对复杂        param->analyse.i_subpel_refine = 8;//亚像素运动估计质量为8        param->i_frame_reference = 5;        param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;        param->rc.i_lookahead = 50;    }    else if( !strcasecmp( preset, "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;        param->rc.i_lookahead = 60;    }    else if( !strcasecmp( preset, "veryslow" ) )    {        param->analyse.i_me_method = X264_ME_UMH;        param->analyse.i_subpel_refine = 10;        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.i_trellis = 2;        param->i_bframe = 8;        param->rc.i_lookahead = 60;    }    else if( !strcasecmp( preset, "placebo" ) )    {        param->analyse.i_me_method = X264_ME_TESA;//TESA很慢        param->analyse.i_subpel_refine = 11;        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;        param->rc.i_lookahead = 60;    }    else    {        x264_log( NULL, X264_LOG_ERROR, "invalid preset '%s'\n", preset );        return -1;    }    return 0;}

可以看出x264_param_apply_preset()通过strcasecmp()比较字符串的方法得到输入的preset类型;然后根据preset类型,设定 x264_param_t中相应的参数。

x264_param_apply_tune()
x264_param_apply_tune()用于设置tune。该函数的定义如下所示。
//设置tunestatic int x264_param_apply_tune( x264_param_t *param, const char *tune ){    char *tmp = x264_malloc( strlen( tune ) + 1 );    if( !tmp )        return -1;    tmp = strcpy( tmp, tune );    //分解一个字符串为一个字符串数组。第2个参数为分隔符    char *s = strtok( tmp, ",./-+" );    int psy_tuning_used = 0;    //设置    //这里是循环的,可以设置多次    while( s )    {        if( !strncasecmp( s, "film", 4 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            param->i_deblocking_filter_alphac0 = -1;            param->i_deblocking_filter_beta = -1;            param->analyse.f_psy_trellis = 0.15;        }        else if( !strncasecmp( s, "animation", 9 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            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( !strncasecmp( s, "grain", 5 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            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( !strncasecmp( s, "stillimage", 10 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            param->i_deblocking_filter_alphac0 = -3;            param->i_deblocking_filter_beta = -3;            param->analyse.f_psy_rd = 2.0;            param->analyse.f_psy_trellis = 0.7;            param->rc.f_aq_strength = 1.2;        }        else if( !strncasecmp( s, "psnr", 4 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            param->rc.i_aq_mode = X264_AQ_NONE;            param->analyse.b_psy = 0;        }        else if( !strncasecmp( s, "ssim", 4 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            param->rc.i_aq_mode = X264_AQ_AUTOVARIANCE;            param->analyse.b_psy = 0;        }        else if( !strncasecmp( s, "fastdecode", 10 ) )        {            param->b_deblocking_filter = 0;            param->b_cabac = 0;            param->analyse.b_weighted_bipred = 0;            param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;        }        else if( !strncasecmp( s, "zerolatency", 11 ) )        {         //zerolatency速度快            param->rc.i_lookahead = 0;            param->i_sync_lookahead = 0;            param->i_bframe = 0;//不使用B帧            param->b_sliced_threads = 1;            param->b_vfr_input = 0;            param->rc.b_mb_tree = 0;        }        else if( !strncasecmp( s, "touhou", 6 ) )        {            if( psy_tuning_used++ ) goto psy_failure;            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_aq_strength = 1.3;            if( param->analyse.inter & X264_ANALYSE_PSUB16x16 )                param->analyse.inter |= X264_ANALYSE_PSUB8x8;        }        else        {            x264_log( NULL, X264_LOG_ERROR, "invalid tune '%s'\n", s );            x264_free( tmp );            return -1;        }        if( 0 )        {    psy_failure:            x264_log( NULL, X264_LOG_WARNING, "only 1 psy tuning can be used: ignoring tune %s\n", s );        }        s = strtok( NULL, ",./-+" );    }    x264_free( tmp );    return 0;}

可以看出x264_param_apply_tune()首先通过strtok()得到存储tune[]数组;然后通过strncasecmp()比较字符串的方法判断当前的tune类型;最后根据tune类型,设定 x264_param_t中相应的参数。

help()

help()用于打印帮助菜单。在x264命令行程序中添加“-h”参数后会调用该函数。该函数的定义如下所示。
//帮助菜单//longhelp标识是否展开更长的帮助菜单static void help( x264_param_t *defaults, int longhelp ){    char buf[50];    //H0(),H1(),H2()都是printf()    //H1(),H2()只有“长帮助菜单”的情况下才会调用printf()#define H0 printf#define H1 if(longhelp>=1) printf#define H2 if(longhelp==2) printf    H0( "x264 core:%d%s\n"        "Syntax: x264 [options] -o outfile infile\n"        "\n"        "Infile can be raw (in which case resolution is required),\n"        "  or YUV4MPEG (*.y4m),\n"        "  or Avisynth if compiled with support (%s).\n"        "  or libav* formats if compiled with lavf support (%s) or ffms support (%s).\n"        "Outfile type is selected by filename:\n"        " .264 -> Raw bytestream\n"        " .mkv -> Matroska\n"        " .flv -> Flash Video\n"        " .mp4 -> MP4 if compiled with GPAC or L-SMASH support (%s)\n"        "Output bit depth: %d (configured at compile time)\n"        "\n"        "Options:\n"        "\n"        "  -h, --help                  List basic options\n"        "      --longhelp              List more options\n"        "      --fullhelp              List all options\n"        "\n",        X264_BUILD, X264_VERSION,#if HAVE_AVS        "yes",#else        "no",#endif#if HAVE_LAVF        "yes",#else        "no",#endif#if HAVE_FFMS        "yes",#else        "no",#endif#if HAVE_GPAC        "gpac",#elif HAVE_LSMASH        "lsmash",#else        "no",#endif        x264_bit_depth      );    H0( "Example usage:\n" );    H0( "\n" );    H0( "      Constant quality mode:\n" );    H0( "            x264 --crf 24 -o  \n" );    H0( "\n" );    H0( "      Two-pass with a bitrate of 1000kbps:\n" );    H0( "            x264 --pass 1 --bitrate 1000 -o  \n" );    H0( "            x264 --pass 2 --bitrate 1000 -o  \n" );    H0( "\n" );    H0( "      Lossless:\n" );    H0( "            x264 --qp 0 -o  \n" );    H0( "\n" );    H0( "      Maximum PSNR at the cost of speed and visual quality:\n" );    H0( "            x264 --preset placebo --tune psnr -o  \n" );    H0( "\n" );    H0( "      Constant bitrate at 1000kbps with a 2 second-buffer:\n");    H0( "            x264 --vbv-bufsize 2000 --bitrate 1000 -o  \n" );    H0( "\n" );    H0( "Presets:\n" );    H0( "\n" );    H0( "      --profile       Force the limits of an H.264 profile\n"        "                                  Overrides all settings.\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"        "                                    No lossless.\n"        "                                  - main:\n"        "                                    --no-8x8dct --cqm flat\n"        "                                    No lossless.\n"        "                                  - high:\n"        "                                    No lossless.\n"#endif        "                                  - high10:\n"        "                                    No lossless.\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"        "                                    --no-8x8dct --aq-mode 0 --b-adapt 0\n"        "                                    --bframes 0 --no-cabac --no-deblock\n"        "                                    --no-mbtree --me dia --no-mixed-refs\n"        "                                    --partitions none --rc-lookahead 0 --ref 1\n"        "                                    --scenecut 0 --subme 0 --trellis 0\n"        "                                    --no-weightb --weightp 0\n"        "                                  - superfast:\n"        "                                    --no-mbtree --me dia --no-mixed-refs\n"        "                                    --partitions i8x8,i4x4 --rc-lookahead 0\n"        "                                    --ref 1 --subme 1 --trellis 0 --weightp 1\n"        "                                  - veryfast:\n"        "                                    --no-mixed-refs --rc-lookahead 10\n"        "                                    --ref 1 --subme 2 --trellis 0 --weightp 1\n"        "                                  - faster:\n"        "                                    --no-mixed-refs --rc-lookahead 20\n"        "                                    --ref 2 --subme 4 --weightp 1\n"        "                                  - fast:\n"        "                                    --rc-lookahead 30 --ref 2 --subme 6\n"        "                                    --weightp 1\n"        "                                  - medium:\n"        "                                    Default settings apply.\n"        "                                  - slow:\n"        "                                    --b-adapt 2 --direct auto --me umh\n"        "                                    --rc-lookahead 50 --ref 5 --subme 8\n"        "                                  - slower:\n"        "                                    --b-adapt 2 --direct auto --me umh\n"        "                                    --partitions all --rc-lookahead 60\n"        "                                    --ref 8 --subme 9 --trellis 2\n"        "                                  - veryslow:\n"        "                                    --b-adapt 2 --bframes 8 --direct auto\n"        "                                    --me umh --merange 24 --partitions all\n"        "                                    --ref 16 --subme 10 --trellis 2\n"        "                                    --rc-lookahead 60\n"        "                                  - placebo:\n"        "                                    --bframes 16 --b-adapt 2 --direct auto\n"        "                                    --slow-firstpass --no-fast-pskip\n"        "                                    --me tesa --merange 24 --partitions all\n"        "                                    --rc-lookahead 60 --ref 16 --subme 11\n"        "                                    --trellis 2\n" );    else H0( "                                  - ultrafast,superfast,veryfast,faster,fast\n"             "                                  - medium,slow,slower,veryslow,placebo\n" );    H0( "      --tune          Tune the settings for a particular type of source\n"        "                              or situation\n"        "                                  Overridden by user settings.\n"        "                                  Multiple tunings are separated by commas.\n"        "                                  Only one psy tuning can be used at a time.\n" );    H2( "                                  - film (psy tuning):\n"        "                                    --deblock -1:-1 --psy-rd :0.15\n"        "                                  - animation (psy tuning):\n"        "                                    --bframes {+2} --deblock 1:1\n"        "                                    --psy-rd 0.4: --aq-strength 0.6\n"        "                                    --ref {Double if >1 else 1}\n"        "                                  - grain (psy tuning):\n"        "                                    --aq-strength 0.5 --no-dct-decimate\n"        "                                    --deadzone-inter 6 --deadzone-intra 6\n"        "                                    --deblock -2:-2 --ipratio 1.1 \n"        "                                    --pbratio 1.1 --psy-rd :0.25\n"        "                                    --qcomp 0.8\n"        "                                  - stillimage (psy tuning):\n"        "                                    --aq-strength 1.2 --deblock -3:-3\n"        "                                    --psy-rd 2.0:0.7\n"        "                                  - psnr (psy tuning):\n"        "                                    --aq-mode 0 --no-psy\n"        "                                  - ssim (psy tuning):\n"        "                                    --aq-mode 2 --no-psy\n"        "                                  - fastdecode:\n"        "                                    --no-cabac --no-deblock --no-weightb\n"        "                                    --weightp 0\n"        "                                  - zerolatency:\n"        "                                    --bframes 0 --force-cfr --no-mbtree\n"        "                                    --sync-lookahead 0 --sliced-threads\n"        "                                    --rc-lookahead 0\n" );    else H0( "                                  - psy tunings: film,animation,grain,\n"             "                                                 stillimage,psnr,ssim\n"             "                                  - other tunings: fastdecode,zerolatency\n" );    H2( "      --slow-firstpass        Don't force these faster settings with --pass 1:\n"        "                                  --no-8x8dct --me dia --partitions none\n"        "                                  --ref 1 --subme {2 if >2 else unchanged}\n"        "                                  --trellis 0 --fast-pskip\n" );    else H1( "      --slow-firstpass        Don't force 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 );    H2( "  -i, --min-keyint   Minimum GOP size [auto]\n" );    H2( "      --no-scenecut           Disable adaptive I-frame decision\n" );    H2( "      --scenecut     How aggressively to insert extra I-frames [%d]\n", defaults->i_scenecut_threshold );    H2( "      --intra-refresh         Use Periodic Intra Refresh instead of IDR frames\n" );    H1( "  -b, --bframes      Number of B-frames between I and P [%d]\n", defaults->i_bframe );    H1( "      --b-adapt      Adaptive B-frame decision method [%d]\n"        "                                  Higher values may lower threading efficiency.\n"        "                                  - 0: Disabled\n"        "                                  - 1: Fast\n"        "                                  - 2: Optimal (slow with high --bframes)\n", defaults->i_bframe_adaptive );    H2( "      --b-bias       Influences how often B-frames are used [%d]\n", defaults->i_bframe_bias );    H1( "      --b-pyramid     Keep some B-frames as references [%s]\n"        "                                  - none: Disabled\n"        "                                  - 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              Use recovery points to close GOPs\n"        "                              Only available with b-frames\n" );    H1( "      --no-cabac              Disable CABAC\n" );    H1( "  -r, --ref          Number of reference frames [%d]\n", defaults->i_frame_reference );    H1( "      --no-deblock            Disable loop filter\n" );    H1( "  -f, --deblock   Loop filter parameters [%d:%d]\n",                                       defaults->i_deblocking_filter_alphac0, defaults->i_deblocking_filter_beta );    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 (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" );    H0( "      --pulldown      Use soft pulldown to change frame rate\n"        "                                  - none, 22, 32, 64, double, triple, euro (requires cfr input)\n" );    H2( "      --fake-interlaced       Flag stream as interlaced but encode progressive.\n"        "                              Makes it possible to encode 25p and 30p Blu-Ray\n"        "                              streams. Ignored in interlaced mode.\n" );    H2( "      --frame-packing  For stereoscopic videos define frame arrangement\n"        "                                  - 0: checkerboard - pixels are alternatively from L and R\n"        "                                  - 1: column alternation - L and R are interlaced by column\n"        "                                  - 2: row alternation - L and R are interlaced by row\n"        "                                  - 3: side by side - L is on the left, R on the right\n"        "                                  - 4: top bottom - L is on top, R on bottom\n"        "                                  - 5: frame alternation - one view per frame\n" );    H0( "\n" );    H0( "Ratecontrol:\n" );    H0( "\n" );    H1( "  -q, --qp           Force constant QP (0-%d, 0=lossless)\n", QP_MAX );    H0( "  -B, --bitrate      Set bitrate (kbit/s)\n" );    H0( "      --crf            Quality-based VBR (%d-51) [%.1f]\n", 51 - QP_MAX_SPEC, defaults->rc.f_rf_constant );    H1( "      --rc-lookahead  Number of frames for frametype lookahead [%d]\n", defaults->rc.i_lookahead );    H0( "      --vbv-maxrate  Max local bitrate (kbit/s) [%d]\n", defaults->rc.i_vbv_max_bitrate );    H0( "      --vbv-bufsize  Set size of the VBV buffer (kbit) [%d]\n", defaults->rc.i_vbv_buffer_size );    H2( "      --vbv-init       Initial VBV buffer occupancy [%.1f]\n", defaults->rc.f_vbv_buffer_init );    H2( "      --crf-max        With CRF+VBV, limit RF to this value\n"        "                                  May cause VBV underflows!\n" );    H2( "      --qpmin        Set min QP [%d]\n", defaults->rc.i_qp_min );    H2( "      --qpmax        Set max QP [%d]\n", defaults->rc.i_qp_max );    H2( "      --qpstep       Set max QP step [%d]\n", defaults->rc.i_qp_step );    H2( "      --ratetol        Tolerance of ABR ratecontrol and VBV [%.1f]\n", defaults->rc.f_rate_tolerance );    H2( "      --ipratio        QP factor between I and P [%.2f]\n", defaults->rc.f_ip_factor );    H2( "      --pbratio        QP factor between P and B [%.2f]\n", defaults->rc.f_pb_factor );    H2( "      --chroma-qp-offset   QP difference between chroma and luma [%d]\n", defaults->analyse.i_chroma_qp_offset );    H2( "      --aq-mode      AQ method [%d]\n"        "                                  - 0: Disabled\n"        "                                  - 1: Variance AQ (complexity mask)\n"        "                                  - 2: Auto-variance AQ (experimental)\n", defaults->rc.i_aq_mode );    H1( "      --aq-strength    Reduces blocking and blurring in flat and\n"        "                              textured areas. [%.1f]\n", defaults->rc.f_aq_strength );    H1( "\n" );    H0( "  -p, --pass         Enable multipass ratecontrol\n"        "                                  - 1: First pass, creates stats file\n"        "                                  - 2: Last pass, does not overwrite stats file\n" );    H2( "                                  - 3: Nth pass, overwrites stats file\n" );    H1( "      --stats         Filename for 2 pass stats [\"%s\"]\n", defaults->rc.psz_stat_out );    H2( "      --no-mbtree             Disable mb-tree ratecontrol.\n");    H2( "      --qcomp          QP curve compression [%.2f]\n", defaults->rc.f_qcompress );    H2( "      --cplxblur       Reduce fluctuations in QP (before curve compression) [%.1f]\n", defaults->rc.f_complexity_blur );    H2( "      --qblur          Reduce fluctuations in QP (after curve compression) [%.1f]\n", defaults->rc.f_qblur );    H2( "      --zones //...  Tweak the bitrate of regions of the video\n" );    H2( "                              Each zone is of the form\n"        "                                  ,,        "                                  where         "                                      q= (force QP)\n"        "                                  or  b= (bitrate multiplier)\n" );    H2( "      --qpfile        Force frametypes and QPs for some or all frames\n"        "                              Format of each line: framenumber frametype QP\n"        "                              QP is optional (none lets x264 choose). Frametypes: I,i,K,P,B,b.\n"        "                                  K= depending on open-gop setting\n"        "                              QPs are restricted by qpmin/qpmax.\n" );    H1( "\n" );    H1( "Analysis:\n" );    H1( "\n" );    H1( "  -A, --partitions    Partitions to consider [\"p8x8,b8x8,i8x8,i4x4\"]\n"        "                                  - p8x8, p4x4, b8x8, i8x8, i4x4\n"        "                                  - none, all\n"        "                                  (p4x4 requires p8x8. i8x8 requires --8x8dct.)\n" );    H1( "      --direct        Direct MV prediction mode [\"%s\"]\n"        "                                  - none, spatial, temporal, auto\n",                                       strtable_lookup( x264_direct_pred_names, defaults->analyse.i_direct_mv_pred ) );    H2( "      --no-weightb            Disable weighted prediction for B-frames\n" );    H1( "      --weightp      Weighted prediction for P-frames [%d]\n"        "                                  - 0: Disabled\n"        "                        

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

你可能感兴趣的:(x264源代码简单分析 x264命令行工具(x264 exe))