X264编码详细过程

(1)       x264_param_default( x264_param_t *param ) 

作用: 对编码器进行参数设定

cqm:量化表相关信息

                 csp:          

                 量化表相关信息里的memset( param->cqm_4iy, 16, 16 );

                                    memset( param->cqm_4ic, 16, 16 );

                                    memset( param->cqm_4py, 16, 16 );

                                    memset( param->cqm_4pc, 16, 16 );

                                    memset( param->cqm_8iy, 16, 64 );

                                    memset( param->cqm_8py, 16, 64 );

(2)static int  Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) 初始化

1.   getopt_long(nargc, nargv, options, long_options, idx) 得到入口地址的向量与方式的选则

2.   getopt_internal(nargc, nargv, options)     解析入口地址向量

(3) static int  Encode( x264_param_t *param, cli_opt_t *opt )

/* Create a copy of param */ h->param=param

/* VUI */vui信息主要包括帧率、图像尺寸等信息

/* Init x264_t */

x264_sps_init( h->sps, 0, &h->param );序列图像集

x264_pps_init( h->pps, 0, &h->param, h->sps);图像参数集

/* Init frames. */     初始化并开辟帧空间

/* init mb cache */   对前一宏块的信息保存,因为是初始化,所以作为第一个宏块的参考,后面会有x264_macroblock_cache_load( h, i_mb_x, i_mb_y );它是将要编码的宏块的周围的宏块的值读进来, 要想得到当前块的预测值,要先知道上面,左面的预测值

/* init cabac adaptive model */

/* init CPU functions */  初始化cpu对各种分块的参数设定

/* rate control */

        1. x264_t *x264_encoder_open   ( x264_param_t *param ) 这个函数是对不正确的参数进行修改,并对各结构体参数和cabac编码,预测等需要的参数进行初始化

        2、p_read_frame( &pic, opt->hin, i_frame + opt->i_seek, param->i_width, param->i_height )

读取一帧,并把这帧设为prev

3. i_file += Encode_frame( h, opt->hout, &pic );进入核心码层

核心编码层的总流程图:(x264.c)

1.         x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out )对帧进行编码

2.         i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) 网络打包编码

3.         i_file += p_write_nalu( hout, data, i_size ) 把网络包写入到输出文件中去

4.         返回,对下一帧进行编码

  下面一页是详细的流程图:

一.帧内详细流程图:

(1).           x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out )对帧进行编码

1.    /* 1: Copy the picture to a frame and move it to a buffer */

    x264_frame_t*fenc=x264_frame_get( h->frames.unused );

x264_frame_copy_picture( h, fenc, pic_in );

fenc->i_frame = h->frames.i_input++;

x264_frame_put( h->frames.next, fenc );

x264_frame_init_lowres( h->param.cpu, fenc );//里面包含低象素的扩展,很多for循环,应该是抽头计算和半精度象素的扩展,要认真看

(2).            264_slicetype_decide( h );对slice类型的判定,里面也要看一下

(3).            while( IS_X264_TYPE_B( h->frames.next[bframes]->i_type ) )

bframes++;

x264_frame_put(h->frames.current,x264_frame_get( &h->frames.next[bframes] ) );这主要是因为B帧必须等后面的非B帧编码结束后才能编码,所以把暂时不编的一系列B帧存入队列中,一直到非B帧才取出进行编码,之后再进行前面的B帧编码

do_encode:

(4).            建立list0 & list1.我感觉

       x264_reference_build_list( h, h->fdec->i_poc, i_slice_type );

      比特率控制初始化

x264_ratecontrol_start(h, i_slice_type, h->fenc->i_qpplus1 );

(5).   创建slice的头部数据

x264_slice_init( h, i_nal_type, i_slice_type, i_global_qp );

(6)     i_frame_size = x264_slices_write( h );这是编码的关键了

1.      x264_slice_header_write(&h->out.bs,&h->sh,h->i_nal_ref_idc ); /* Slice header */

2.      一些初始化工作

3.      for(mb_xy=h->sh.i_first_mb, i_skip = 0; mb_xy < h->sh.i_last_mb; mb_xy++ )对一个slice中每个宏块进行循环遍历编码,其中const int i_mb_y = mb_xy / h->sps->i_mb_width;和const int i_mb_x = mb_xy % h->sps->i_mb_width;是对宏块位置在slice中的x,y坐标的定位,这个for语句几乎覆盖了整个x264_slices_write()函数

4.      x264_macroblock_cache_load( h, i_mb_x, i_mb_y ); 它是将要编码的宏块的周围的宏块的值读进来, 要想得到当前块的预测值,要先知道上面,左面的预测值!

5.      *****x264_macroblock_analyse( h );重点。通过一系列的SAD算出最优化方案,例如把I帧16×16的宏块分成16个4×4分别计算SAD和与原16×16SAD比较我感觉,在下面一层再详细分析。

a.   x264_mb_analyse_intra( h, &analysis, COST_MAX );我感觉是在一个16×16的SAD,4个8×8的SAD和,16个4×4SAD和中选出最优方式进行,可能我的理解不对,里面的x264_mb_encode_i4x4( h, idx, a->i_qp );i8×8几个函数的跟踪有问题,跟得我都找不到,要仔细看(现在又能跟到了)

这边好像如果是直流分量在这里就进行量化ZIGZAG扫描了,不用等到x264_macroblock_encode( h )再完成了

b.   x264_analyse_update_cache( h, &analysis ); 有对色度块的模式选择的计算,好像也有更新信息以为下次的预测作为参考

6.      x264_macroblock_encode( h );

a.   判断宏块的类型

b.   根据判断的类型进行DCT,量化,ZIGZAG,并记录当前的模式为下次编码宏块(亚宏块)做参考

ZIGZAG的实现不明白(原来ZIGZAG有宏定义,在上面,现在明白了),反量化和IDCT的过程跟不进去,应该是汇编了!函数如下:( I 4×4 中 x264_mb_encode_i4x4( h, i, i_qp );)

x264_mb_dequant_4x4( dct4x4, h->dequant4_mf[CQM_4IY], i_qscale );

h->dctf.add4x4_idct( p_dst, i_stride, dct4x4 );

还有,这个函数跟踪不进去,应该是重构图像的反变换吧

h->dctf.add4x4_idct( p_dst, i_stride, dct4x4 );

h->mb.cache.intra4x4_pred_mode[x264_scan8[i]]=x264_mb_pred_mode4x4_fix(i_mode);这个值到底是怎么根据前面的模式改变的,可能是上面两个函数没能更进去所以模糊

c.    对色度块进行编码,QP限制在0-51之间,选定预测模式(DC的话值全为128)

x264_mb_encode_8x8_chroma( h, !IS_INTRA( h->mb.i_type ), i_qp );里面对两个色度信号分别编码,与亮度信号类似

d.   求亮度和色度的cbp,完全不明白是怎么求的,需要解决!现在有点明白,每个比特代表子块是不是全为0,但还没有全部明白,色度块cbp中0x02表示有AC,DC 0x01表示只有DC,

e.利用CBP判断要不要SKIP.,里面还关系到向量预测,明天好好看一下。  其中

h->mb.qp[h->mb.i_mb_xy] = h->mb.i_last_qp;这个为读下一个     qp的保存,不然解码端是读不出下一个  qp的,

关于CBP的理解还存在问题,他的8位比特各个代表的意思还不是十分明确,反正是对DC,AC的编码的选择。185页有介绍(新一代视频压缩标准毕厚杰)

7.      选用CABAC还是CAVLC

CABAC的原理实现没仔细看

8.     x264_macroblock_cache_save( h );保存以为下次的预测作为参考

9.     一些收尾工作,为下次宏块作准备(看的比较粗)

  x264基于经验和感觉的码率控制策略 收藏

前提:

1 high-complexity or high-motion scenes,细节将不会很明显,此时高qp也是浪费

2 where motion compensation works well,在景物边沿的失真,只需在一帧中去掉,以后就都不会有.在这里投入有限的bits可以获得最好的图像质量性价比

3 已经编码一frame,可以预测其他qp下所需bit数.预测距离越远越不精确

4随着frame重要性降低,他们只配用更大的qp,i ,p ,参考b ,disposable b.依次降低

5H.264支持1frame内不同mb使用不同qp,x264不支持,而由rc返回统一qp。但有那个功能函数存在那个函数仅精确到每一行mb变一次qp

所以rc策略如下:

2pass:

step1 1pass编码,由qp推断某qp下framesize *0.6符合目标frame size的限制,得到这个qp

step2 修改qp 以满足requested total size(total是指整个Gop的大小,分段先编一边再一边)

step3 encode根据实际大小值修正预测的qp,并额外增加short-term compensation,针对开始和结束部分没有很多bits余地的位置.

1pass:  abr (average bit rate )

step1 用半尺寸快速运动估计和SATD residuals 替换1st pass中相关部分,获得预测

step2 用之前的样本估计scale

step3 Overflow compensation 和2pass相似 限制filesize 牺牲图像质量

1pass,:constant bitrate (VBV compliant)!!!

VBV是指:   Video Buffer Verifier

The Video Buffer Verifier (VBV) is a model hypothetical decoder buffer that will not overflow or underflow when fed a conforming MPEG bit stream.   包含2个因素.size和造成的delay

step1  same as abr

step2 Scaling factor is based on a local average (dependent on VBV buffer size) instead of all past frames

step3 stricter Overflow compensation  ,  additional term to hard limit the QPs if the VBV is near empty. no hard limit is done for a full VBV这里更加严格的空限制,防止没有bits可以送出,破坏了cbr的传输

1pass, constant ratefactor:      Constant Rate Factor (or Constant Quality)

(1) Same as ABR.

(2) The scaling factor is a constant based on the --crf argument.

(3) No overflow compensation is done.

ratefactor是指:

constant quantizer:

QPs are simply based on frame type.

RC中的蛋鸡悖论:为了计算当前帧中宏块的

RDO,需利用已定qp确定当前帧或宏块的cost预测每个宏块的mode mv ref等.

ratecontrol是在确定mode mv ref后决定qp,在此之前qp不能获得。

于是rdo与rc不知道先做哪个了.

  x264命令行参数解释 收藏

本文对应的是x264命令行模式,VFW方式也用相同的参数,不过是图形界面,可以自己找对应的英文。

    使用格式:x264 默认选项 -o 输出文件 输入文件 [长x宽]

输入支持格式:RAW/y4m/avi/avs(编译时可选)

输出支持格式:264/mkv/mp4(编译时可选)

    x264的许多参数可以有-/--两种输入法,笔者也不知道为什么。以下等价参数用“参

数1/参数2 <必需数值格式>”表示,参数尾部()内为个人推荐。

-h/--help 帮助

帧类型选项:

-I/--keyint <整数> 最大IDR帧间距,默认250

-i/--min-keyint <整数> 最小IDR帧间距,默认25

--scenecut <整数> 画面动态变化限,当超出此值时插入I帧,默认40

-b/--bframes <整数>     在IP帧之间可插入的B帧数量最大值,范围0~16,默认0

--no-b-adapt            关闭自适应B帧判定(-b设为1时可用,其他不推荐)

--b-bias <整数> 控制插入B帧判定,范围-100~+100,越高越容易插入B帧,默认0

--b-pyramid             允许B帧做参考帧

--no-cabac              关闭内容自适应二进制算术编码(CABAC,高效率的熵编码)(会

提高速度,但严重影响质量)

-r/--ref <整数>         最大参考帧数,范围0~16,默认1

--nf                    关闭环路滤波(一种除马赛克算法)

-f/--filter <alpha:beta>设置环路滤波的AlphaC和Beta的参数,范围-6-6,默认都为0

码率控制选项:

-q/--qp <整数> 固定量化模式并设置使用的量化值,范围0~51,0为无损压缩,默认26

-B/--bitrate <整数> 设置平均码率

--crf <整数> 质量模式,量化值动态可变(目前不太成熟,质量不如设置固定量化值)

--qpmin <整数> 设置最小量化值,范围0~51,默认10

--qpmax <整数> 设置最大量化值,范围0~51,默认51

--qpstep <整数> 设置相邻帧之间的量化值差,范围0~50,默认4

--ratetol <小数> 平均码率模式下,瞬时码率可以偏离的倍数,范围0.1~100.0,默认1.

0

--vbv-maxrate <整数> 平均码率模式下,最大瞬时码率,默认0(与-B设置相同)

--vbv-bufsize <整数> 码率控制缓冲区的大小,单位kbit,默认0

--vbv-init <小数> 码率控制缓冲区数据保留的最大数据量与缓冲区大小之比,范围0~1.

0,默认0.9

--ipratio <小数> I帧和P帧之间的量化系数,默认1.40

--pbratio <小数> P帧和B帧之间的量化系数,默认1.30

--色度-qp-offset <整数> 色度和亮度之间的量化差,范围-12~+12,默认0

-p/--pass <1|2|3> 多次压缩码率控制

1:第一次压缩,创建统计文件

2:按建立的统计文件压缩并输出,不覆盖统计文件,

3:按建立的统计文件压缩,优化统计文件

--stats <字符串> 统计文件的名称,默认"x264_2pass.log"

--rceq <字符串> 速率控制公式,默认"blurCplx^(1-qComp)"

--qcomp <小数> 线性量化控制,0.0为固定码率,1.0为固定量化值,默认0.6,只用于2-

pass和质量模式

--cplxblur <小数> 根据相邻帧平滑量化值比例的最大值,范围0~99.9,默认20.0,只用

于2-pass和质量模式

--qblur <小数> 对统计文件结果平滑量化值比例的最大值,范围0~99.9,默认0.5,只用于

2-pass

--zones <z0>/<z1>/… 分段量化,格式为:<开始帧>,<结束帧>,<选项>,可选项为:q=<

整数>(量化值)或b=<小数>(码率倍数)

分析选项:

-A/--analyse <字符串> 动态块划分方法,默认"p8x8,b8x8,i8x8,i4x4"。可选项:p8x8/

p4x4/b8x8/i8x8/i4x4;none/all(p4x4需要p8x8. i8x8需要--8x8dct)

--direct <字符串>       动态预测方式,默认"spatial"。可选项:none/spatial/temp

oral/auto

-w/--weightb 允许B帧加权预测(可以减少相邻B帧质量低的影响)

--me <字符串> 对全像素块动态预测搜索的方式,默认"hex",可选项:

dia:菱形搜索,半径1 (快)

hex:正六边形搜索,半径2

umh:可变半径六边形搜索

esa:全面搜索(很慢,而且效果与umh几乎相同)

--merange <整数> --me为umh/esa时的搜索半径,最大64,默认16

-m/--subme <整数> 动态预测和分区方式,可选项1~7,默认5(与压缩质量和时间关系密切

,1是7速度的四倍以上)

1:用全像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索

2:用半像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索

3:用半像素块进行动态搜索,对每个块再用质量模式进行四分之一像素块精确搜索

4:用快速模式进行四分之一像素块精确搜索

5:用质量模式进行四分之一像素块精确搜索

6:进行I、P帧像素块的速率失真最优化(rdo)

7:进行I、P帧运动矢量及块内部的速率失真最优化(质量最好)

--b-rdo B帧也进行rdo,需要--subme在6以上

--mixed-refs 可以在一帧内使用不同参考帧

--no-chroma-me 不进行色度的动态预测

--bime 可以平均B帧参考块的运动矢量

-8/--8x8dct 可以使用8x8的离散余弦变换(DCT)

-t/--trellis <整数>     Trellis量化,对每个8x8的块寻找合适的量化值,需要CABAC,

默认0

0:关闭

1:只在最后编码时使用

2:一直使用

--no-fast-pskip 关闭快速P帧跳过检测

--no-dct-decimate       关闭P帧联合编码(可以增加细节,但也会增大体积)

--nr <整数> 噪声去除,范围0~100000,默认0

--cqm <字符串> 设置外部量化矩阵格式,默认"flat",可选项:jvt/flat

--cqmfile <字符串> 读取JM格式的外部量化矩阵文件,自动忽略其他--cqm*选项

--cqm4 <list> 设置4x4的量化矩阵,用逗号分开,范围1~255的16个整数

--cqm8 <list> 设置8x8的量化矩阵,用逗号分开,范围1~255的64个整数

--cqm4i/--cqm4p/--cqm8i/--cqm8p 设置I、P帧不同的量化矩阵

--cqm4iy/--cqm4ic/--cqm4py/--cqm4pc 设置亮度、色度不同的量化矩阵

视频标准化选项:

这些选项与编码无关,不过如果要用mp4之类的播放器,可以设置,风险自担

--sar width:height 设置长宽比

--overscan <字符串> 过扫描线,默认"undef"(不设置),可选项:show(观看)/crop(去除

)

--videoformat <字符串> 视频格式,默认"undef",可选项:component/pal/ntsc/secam

/mac/undef

--fullrange <字符串>    Specify full range samples setting,默认"off",可选项:

off/on(我也不明白这是干什么的,请高手指点)

--colorprim <字符串>    原始色度格式,默认"undef",可选项:undef/bt709/bt470m/

bt470bg,smpte170m/smpte240m/film

--transfer <字符串>     转换方式,默认"undef",可选项:undef/bt709/bt470m/bt47

0bg/linear,log100/log316/smpte170m/smpte240m

--colormatrix <字符串>  色度矩阵设置,默认"undef",undef/bt709/fcc/bt470bg,smpt

e170m/smpte240m/GBR/YCgCo

--chromaloc <整数> 色度样本指定,范围0~5,默认0

输入、输出选项:

--level <字符串> 设定等级(as defined by Annex A)(不明白,请高手指点)

--fps <小数> 设定帧率

--seek <整数> 设定起始帧

--frames <整数> 最大编码帧数

-o/--output 指定输出文件

--threads <整数> 编码线程(使用分片技术)

--thread-input 在编码线程中运行Avisynth

--no-asm 关闭全部CPU优化指令

--no-psnr 关闭PSNR计算

--quiet 安静模式

-v/--verbose 显示每一个帧的信息

--progress 显示编码进程

--visualize 显示运动矢量

--sps-id <整数> 设置SPS和PPS的ID值,默认0

--aud 使用数据单元定义符号

x264中重要结构体说明 收藏

首先解释一下cli_opt_t的这个_t代表结构图可能是type的意思。同时还有很多i_ b_等作为前缀的变量,其中的I_表示int类型的变量 b表示bool类型的。依次类推。

正式进入主题。

typedef struct {

    int b_progress;

    int i_seek;

    hnd_t hin;

    hnd_t hout;

    FILE *qpfile;

} cli_opt_t;

此结构体是记录一些与编码关系较小的设置信息的opt=option。结构体内部的变量都可以通过读取main()的参数获得。也就是argv。

b_progress表示一个bool类型的变量,看参数帮助 也就是x264--help你会知道,他是用来控制是否显示编码进度的一个东西。取值为0,1.

I_seek 整数类型 表示开始从哪一帧编码。因为不一定从这个文件的第一帧开始编码,这是可以控制的。

Hnd_t(hnd=handle)是一个空指针, void *在C语言里空指针是有几个特性的,他是一个一般化指针,可以指向任何一种类型,但却不能解引用,需要解引用的时候,需要进行强制转换。采用空指针的策略,应该是为了声明变量的简便和统一。

Hin 指向输入yuv文件的指针。

Hout 指向编码过后生成的文件的指针。

Qpfile 是一个指向文件类型的指针,他是文本文件,其每一行的格式是framenum frametype QP

用于强制指定某些帧或者全部帧的帧类型和QP(quant param量化参数)的值。

x264_param_default( &param );

这部分设置编码参数的缺省值

附结构体param中部分变量的意义:

    param->i_csp          = X264_CSP_I420; // 设置输入的视频采样的格式

param->vui.i_sar_width = 0;  //VUI:video usability information

    param->i_fps_num       = 10; //帧率

    param->i_fps_den       = 1;  //用两个整型的数的比值,来表示帧率

    /* Encoder parameters */

    param->i_frame_reference = 1; //参考帧的最大帧数。

    param->i_bframe = 0;          //两个参考帧之间的B帧数目。

    param->b_deblocking_filter = 1; //去块效应相关

    param->b_cabac = 0;            //cabac的开关

    param->i_cabac_init_idc = -1;

    param->rc.b_cbr = 1;           //constant bitrate 恒定码率控制模式

    param->rc.i_bitrate = 0;       //默认的码率

    param->rc.i_rc_buffer_size = 0;   //buffer的大小

    param->rc.i_rc_init_buffer = 0;   //

param->rc.i_rc_sens = 100;       ///* rate control sensitivity

param->rc.i_rc_method = X264_RC_NONE;  //码率控制,CQP(恒定质量)、//CRF(恒定码率)、ABR(平均码率)

param->rc.i_qp_constant = 26; //qp的初始值,最大最小的qp值,

    param->rc.i_qp_min = 10;           //最小的qp值

    param->rc.i_qp_max = 51;          //最大的qp值

param->rc.i_qp_step = 4;       //qp[步长step。

    param->rc.f_ip_factor = 1.4;  //ip--i帧p帧的qp的差值

    param->rc.f_pb_factor = 1.3;  //pb--p帧b帧的qp的差值

/* Log */ //整个param的一个log文件

    /*analyse */

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.i_me_range = 16;              //运动估计范围

    param->analyse.i_subpel_refine = 5;

    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_direct_8x8_inference = -1; // set from level_idc

    param->analyse.i_chroma_qp_offset = 0;

    param->analyse.b_fast_pskip = 1;

    param->analyse.b_dct_decimate = 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->i_cqm_preset = X264_CQM_FLAT;  //自定义量化矩阵(CQM),初始化量化模式为flat

typedef struct

{

    /* In: force picture type (if not auto)

     *     If x264 encoding parameters are violated in the forcing of picture types,

     *     x264 will correct the input picture type and log a warning.

     *     The quality of frametype decisions may suffer if a great deal of fine-grained

     *     mixing of auto and forced frametypes is done.

     * Out: type of the picture encoded */

    int     i_type;

    /* In: force quantizer for > 0 */

    int     i_qpplus1;

    /* In: user pts, Out: pts of encoded picture (user)*/

    int64_t i_pts;

    /* In: raw data */

    x264_image_t img;

} x264_picture_t;

具体的含义理解参考了read_frame_yuv()x264_picture_alloc();

I_type 指明被编码图像的类型,有X264_TYPE_AUTO X264_TYPE_IDR         X264_TYPE_I X264_TYPE_P X264_TYPE_BREF X264_TYPE_B可供选择,初始化为AUTO,说明由x264在编码过程中自行控制。

I_qpplus1 :此参数减1代表当前画面的量化参数值。

I_pts :program time stamp 程序时间戳,指示这幅画面编码的时间戳。

Img :存放真正一副图像的原始数据。

typedef struct

{

    int     i_csp;

    int     i_plane;

    int     i_stride[4];

    uint8_t *plane[4];

} x264_image_t;

Csp: color space parameter 色彩空间参数 X264只支持I420

i_Plane 代表色彩空间的个数。一般为3,YUV,初始化为

x264常用options整理 收藏

 

x264源码解析

2009年11月12日 星期四 22:44

http://hi.baidu.com/mingjiang_apple/blog/item/aed41f08efb10b3ae82488eb.html

x264源码解析(01)

    由main函数进入参数设置后开始Encode函数。。。这里只把Encode函数体解析下,借鉴了很多网上资源(即使不全是自己原话也是亲手打字上去的哦^_^),感谢网友。

    代码似懂非懂的注释了下,尽当资源存储吧吧,暂且发到博客大家讨论批评。

static int Encode( x264_param_t *param, cli_opt_t *opt )

{

    x264_t *h; //还不知道干啥的,这个结构也很烦,不压x264_param_t

    x264_picture_t pic; //一帧的结构体,色度存储

    int     i_frame, i_frame_total;

    int64_t i_start, i_end; //用来计算时间

    int64_t i_file;

    int     i_frame_size;

    int     i_update_interval;

    char    buf[200];

    opt->b_progress &= param->i_log_level < X264_LOG_DEBUG;

    i_frame_total = p_get_frame_total( opt->hin );

    i_frame_total -= opt->i_seek;

    if( ( i_frame_total == 0 || param->i_frame_total < i_frame_total )

        && param->i_frame_total > 0 )

        i_frame_total = param->i_frame_total;

    param->i_frame_total = i_frame_total;

       //上面这段代码是实现,计算文件中的总共的帧数,并根据输入的参数初始帧的位置,

       //对i_frame_total做出修正,i_frame_total -= opt->i_seek,然后再根据param->i_frame_total,

       //对i_frame_total做出进一步的修正。

       //总体来说,就是对参数设置中的进行编码的帧数的总数进行修正和计算。

    i_update_interval = i_frame_total ? x264_clip3( i_frame_total / 1000, 1, 10 ) : 10;

    if( ( h = x264_encoder_open( param ) ) == NULL )//关键函数:x264_encoder_open( param ) 根据参数要求对encoder进行一系列的初始化,例如分配内存,值的初始化等。

    {

        …… ……(略)

    }

    if( p_set_outfile_param( opt->hout, param ) )//关键函数:p_set_outfile_param() 设置输出文件格式

    {

        …… ……(略)

    }

    /* Create a new pic */

       //关键函数:x264_picture_alloc() 按照色度空间分配内存,并返回内存的首地址作为指针

    if( x264_picture_alloc( &pic, X264_CSP_I420, param->i_width, param->i_height ) < 0 )

    {

        …… ……(略)

    }

       //关键函数:x264_mdate()     用于编码用时的计算,设定起始时间

    i_start = x264_mdate();

    /* Encode frames */

    for( i_frame = 0, i_file = 0; b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); )

    {

              //p_read_frame() 按照h->hin提供的输入文件的地址,读入图像的内容到&pic提供的存储区的首地址

        if( p_read_frame( &pic, opt->hin, i_frame + opt->i_seek ) )

            break;

        pic.i_pts = (int64_t)i_frame * param->i_fps_den;

        if( opt->qpfile )

            parse_qpfile( opt, &pic, i_frame + opt->i_seek );//parse_qpfile() 为从指定的文件中读入qp的值留下的接口,qpfile为文件的首地址

        else

        {

            /* Do not force any parameters */

            pic.i_type = X264_TYPE_AUTO;

            pic.i_qpplus1 = 0;// 参数减1代表当前画面的量化参数值

        }

        i_frame_size = Encode_frame( h, opt->hout, &pic );//************核心程序

        …… ……(略)

        /* update status line (up to 1000 times per input file) */

           //用于显示整个编码过程的进度

        if( opt->b_progress && i_frame % i_update_interval == 0 )

        {

            int64_t i_elapsed = x264_mdate() - i_start;//编码使用的时间计算

                 //帧率的计算

            double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0;

            double bitrate = (double) i_file * 8 * param->i_fps_num / ( (double) param->i_fps_den * i_frame * 1000 );

             …… ……(略)

            SetConsoleTitle( buf );

            fflush( stderr ); // needed in windows

        }

    }

    ……   ………………

    // 后边的除了清理工作,其他的还不知道。

    return 0;

}

1、x264学习笔记(9)--x264中16x16运动搜索过程

函数实现是函数 static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a )

1、大循环是参考帧的循环,从最近的一个参考帧开始搜索,一直到最远的一个参考帧;
2、调用x264_mb_predict_mv_16x16函数,以上、右上、左块运动矢量的中值m.mvp作为候
选运动矢量。
3、调用x264_mb_predict_mv_ref16x16函数,寻找其它候选运动矢量。这些候选者包括:
空间相邻的左、左上、上、右上块的MV;第0个参考帧中的当前块、右边块、下边快运动矢
量乘以时间差权重。
4、调用x264_me_search_ref进行运动搜索。搜索时先从所有候选运动矢量中选出最佳的起
点,然后使用小钻石法、六边形法、UMH或者全搜索搜索出最佳的整像素位置。
5、x264_me_search_ref调用refine_subpel进行1/2和1/4运动搜索。两者都使用小钻石法

6、搜索出最佳运动矢量后,如果当前是最近一个参考帧,而且最佳SA(T)D小与检测门限,
则尝试对其进行P_SKIP编码。
7、保存搜索结果。

2、x264学习笔记(10)---分像素的运动估计总结 

得到分像素的值函数是下面两个函数,对照着

(1) static uint8_t *get_ref( uint8_t *src[4], int i_src_stride,

                         uint8_t *dst,    int * i_dst_stride,

                         int mvx,int mvy,

                         int i_width, int i_height )

{

    int qpel_idx = ((mvy&3)<<2) + (mvx&3);   //取出运动矢量的分像素部分。

    int offset = (mvy>>2)*i_src_stride + (mvx>>2);  //偏移到所选的整像素点

    uint8_t *src1 = src[hpel_ref0[qpel_idx]] + offset + ((mvy&3) == 3) * i_src_stride;

/*src1和src2都分别指向的是1/2像素块,关键是这个hpel_ref0[qpel_idx]和hpel_ref1[qpel_idx],下面将详细介绍。

注意一点就是参考帧定义了uint8_t *p_fref[2][32][4+2]; /* last: lN, lH, lV, lHV, cU, cV */

这里面的 4+2 的这个2代表色度,而这个4分别代表整像素,在整像素水平右边的1/2像素,在整像素垂直下面的1/2像素和整像素右下角的1/2像素。1/2像素的值已经在前面函数里面插值存好了,只要调用就可以了,而如果要进行1/4像素估计,要临时插值。现在这个函数 get_ref 中,src[0]、src[1]、src[2]、src[3]这传进来的就是分别是 lN, lH, lV, lHV

*/

    if( qpel_idx & 5 ) /* qpel interpolation needed */

    {

        uint8_t *src2 = src[hpel_ref1[qpel_idx]] + offset + ((mvx&3) == 3);

        pixel_avg( dst, *i_dst_stride, src1, i_src_stride,

                   src2, i_src_stride, i_width, i_height );//1/4搜索时需要临时插值函数

        return dst;

    }

    else

    {

        *i_dst_stride = i_src_stride;

        return src1;

    }

}

按照 毕厚杰 的《新一代视频压缩编码标准——H.264/AVC》关于运动矢量那一节的介绍。看图6.22

那四个像素点,G为整像素点 b、h、i分别是lH, lV, lHV,也就是水平,垂直和对角线的值。

G  b

h   i

对应为

src[0]  src[1]

src[2]  src[3]

现在看这两个数组

static const int hpel_ref0[16] = {0,1,1,1,0,1,1,1,2,3,3,3,0,1,1,1};

static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};

也按像素的平面图画出来的话

src[hpel_ref0[qpel_idx]]为

0 1 1 1

0 1 1 1

2 3 3 3

0 1 1 1

src[hpel_ref1[qpel_idx]]为

0 0 0 0

2 2 3 2

2 2 3 2

2 2 3 2

这上面的数字 0、1、2、3分别代表 整像素、水平1/2像素值、垂直1/2像素值 和对角线1/2像素值,也就是毕厚杰书中的 G、b、h、I 。这里要注意src[hpel_ref0[qpel_idx]]最后一行的 0 1 1 1 和src[hpel_ref1[qpel_idx]]最右边一列0 2 2 2不是当前的整像素0的1/2像素,而分别是其下面和右边一个整像素的对应的1/2像素值,因为 ((mvy&3) == 3) * i_src_stride 和((mvx&3) == 3)。

为什么要这么来排,是因为要根据1/4像素是通过1/2像素线性插值的公式来的,具体看下面这个函数。

(2) static inline void pixel_avg( uint8_t *dst,  int i_dst_stride,

                              uint8_t *src1, int i_src1_stride,

                              uint8_t *src2, int i_src2_stride,

                              int i_width, int i_height )

{  //1/4搜索时需要临时插值函数

    int x, y;

    for( y = 0; y < i_height; y++ )

    {

        for( x = 0; x < i_width; x++ )

        {

            dst[x] = ( src1[x] + src2[x] + 1 ) >> 1;   //利用相邻半像素和两个像素取平均插值

        }

        dst  += i_dst_stride;

        src1 += i_src1_stride;

        src2 += i_src2_stride;

    }

} 不过最后我有个疑问,那就是1/4插值后,应该原来的1/2 值保持不变的.但是分析发现,这个 b 、h、 i 这三个1/2像素中,h和i是不变的,不过 b会发生变化. 个人觉得 static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};如果改为 static const int hpel_ref1[16] = {0,0,1,0,2,2,3,2,2,2,3,2,2,2,3,2};则  b也不会发生变化. 所以这里打个问号?

3、x264学习笔记(11)---关于运动矢量MV不传输的问题

    昨天看到H.264乐园群里面有人在讨论运动矢量MV不用传输的问题,就去看了下x264源代码,作个总结

编码端: 运动估计搜索得到的运动矢量MV是不需要传送的,需要传送的是MVD,MVD即运动矢量MV(运动估计得到)和运动矢量的预测矢量MVP(预测得到)的差值。

MVD = MV - MVP

 

解码端:通过预测得到MVP,将传输过来的MVD和MVP相加得到 MV = MVD + MVP,然后用这个MV去参考帧中获取预测象素值,最后把这个预测值和残差加一起, 作为重构像素值

 

x264中把这个过程放在了熵编码阶段,在这个函数里 x264_macroblock_write_cabac

 

MVD并保存下来以备传输的函数如下:

static inline void x264_cabac_mb_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int width, int height )

{

    int mvp[2];

    int mdx, mdy;

 

    /* Calculate mvd */

    x264_mb_predict_mv( h, i_list, idx, width, mvp );  //预测MVP

    mdx = h->mb.cache.mv[i_list][x264_scan8[idx]][0] - mvp[0];  //计算MVD

    mdy = h->mb.cache.mv[i_list][x264_scan8[idx]][1] - mvp[1];

 

    /* encode */

    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 0, mdx ); //编码

    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 1, mdy );

 

    /* save value */

    x264_macroblock_cache_mvd( h, block_idx_x[idx], block_idx_y[idx], width, height, i_list, mdx, mdy ); // 保存MVD

}

4、firstime

MV预测过程详解(附图)

===========第一步:确定相邻块===========

      MV 预测以宏块分割(或亚宏块分割,如果宏块存在亚分割)为单位,同一个宏块分割(或亚宏块分割)内所有 4*4 块 MV 预测值相同。以每个宏块分割(或亚宏块分割)的左上角像素 pixel1 和右上角像素 pixel2 为参考点来确定相邻块则:

      pixel1 左侧相邻像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 A

      pixel1 上方相邻像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 B

      pixel2 右上对角线像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 C

      pixel1 左上对角线像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 D

图片附件: MV预测示意图.JPG (2006-9-29 11:14 AM, 85.25 K)

      以最复杂的 8*8 宏块分割类型为例(此时只存在亚宏块分割),分析如下:

      假设图中黑色框表示宏块、每个绿色框表示一个 4*4 块、每个红色框表示一个 8*8 块。当前宏块的宏块分割模式为 8*8(如图中红色线),其亚宏块分割模式分别为:第一个 8*8 块为 8*8,第二个 8*8 块为 4*4(如图中蓝色线),第三个 8*8 块为 4*8(如图中蓝色线),第四个 8*8 块为 8*4(如图中蓝色线)。则按照上述方法来确定相邻块的方法如下:

      第一个预测对象为第一个 8*8 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 7 号 4*4 块,B 为 2 号 4*4 块,C 为 4 号 4*4 块,D 为 1 号 4*4 块。9、14、15 与 8 具有相同 MV 预测值

      第二个预测对象为第二个 8*8 块的第一个 4*4 块,即 10 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 9 号4*4块,B 为 4 号4*4块,C 为 5 号 4*4 块, D 为 3 号 4*4 块

      第三个预测对象为第二个 8*8 块的第二个 4*4 块,即 11 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 10 号4*4块,B 为 5 号4*4块,C 为 6 号 4*4 块,D 为 4 号 4*4 块

      第四个预测对象为第二个 8*8 块的第三个 4*4 块,即 16 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 15 号4*4块,B 为 10 号4*4块,C 为 11 号 4*4 块,D 为 9 号 4*4 块

      第五个预测对象为第二个 8*8 块的第四个 4*4 块,即 17 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 16 号4*4块,B 为 11 号4*4块,C 为 12 号 4*4 块,D 为 10 号 4*4 块

      第六个预测对象为第三个 8*8 块的第一个 4*8 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 19 号 4*4 块,B 为 14 号 4*4 块,C 为 15 号 4*4 块,D 为 13 号 4*4 块。26 与 20 具有相同 MV 预测值

      第七个预测对象为第三个 8*8 块的第二个 4*8 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 20 号 4*4 块,B 为 15 号 4*4 块,C 为 16 号 4*4 块,D 为 14 号 4*4 块。27 与 21 具有相同 MV 预测值

      第八个预测对象为第四个 8*8 块的第一个 8*4 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 21 号 4*4 块,B 为 16 号 4*4 块,C 为 18 号 4*4 块,D 为 15 号 4*4 块。23 与 22 具有相同 MV 预测值

     第九个预测对象为第四个 8*8 块的第二个 8*4 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 27 号 4*4 块,B 为 22 号 4*4 块,C 为 24 号 4*4 块,D 为 21 号 4*4 块。29 与 28 具有相同 MV 预测值

===========第二步:确定 A、B、C 的可用性===========

根据 A、B、C 所在宏块是否存在或者是否允许参与预测来判断。如果 C 不可用,采用 D 代替 C

===========第三步:预测 MV ===========

1、如果 A、B、C 三个参考块中只有一个与当前预测对象为同一参考帧,则选取该参考块的 MV 作为最终 MV 预测值

2、当前宏块是否为 8*16 或者 16*8 分割:

(1)、如果当前宏块为 8*16 分割类型:

          对于左边 8*16 分割,如果 A 与当前分割为同一参考帧,则采用 A 的 MV 为该分割的最终 MV 预测值

          对于右边 8*16 分割,如果 C 与当前分割为同一参考帧,则采用 C 的 MV 为该分割的最终 MV 预测值

(2)、如果当前宏块为 16*8 分割类型:

          对于上边 16*8 分割,如果 B 与当前分割为同一参考帧,则采用 B 的 MV 为该分割的最终 MV 预测值

          对于下边 16*8 分割,如果 A 与当前分割为同一参考帧,则采用 A 的 MV 为该分割的最终 MV 预测值

3、其余情况并且 B、C 中有一个可用或者两者都可用,则采用中值预测(取 A、B、C 三者中MV的中值为最终 MV 预测值)

4、其余情况并且 B、C 皆不可用,则采用 A 的 MV 为最终 MV 预测值

【注】:1、宏块分割时的相邻块确定方法与第一步所述过程雷同:16*16 相当于 8*8,8*16、16*8 分别相当于 4*8、8*4

            2、对于不可用的相邻块,其 MV 仍然可能参与 MV 预测,但其值为 0。例如:A 不可用,B、C 可用,则最终可能仍然是在 A、B、C 中取中值,但此时 A 的 MV 为 0;

            3、对于不可用的相邻块,其参考帧索引被设置为 -1,即必然与当前预测对象非同一参考帧;

            4、可以验证:同时满足第三步的第一、第二两种情况时,按第一种情况计算 MV 预测值与按第二种情况计算 MV 预测值等效;

            5、该预测过程即为标准 8.4.1.3 小节的内容,在 JM86 中对应的代码为 SetMotionVectorPredictor 函数;

            6、MBAFF 情况下的相邻块均指对应位置(co-locate)块。

常规选项设置
  在常规选项栏中的参数设置及含义如下:
  输出路径:设置最后生成的MP4-AVC所在的目录。
  建议:设置到的分区有较大的剩余空间
  保持文件夹结构:减少文件碎片。
  建议:勾选
  在视频选项栏中的参数设置及含义如下:
  模式:设置转换视频时所采用的编码方式。可选项:
  1.Bitrate-based固定比特率;
  2.Quality-based动态比特率,基于质量模式,文件大小不可控;
  3.Two-Pass转换两遍
  4.Three-Pass转换三遍。
  建议:选择Quality-based
  滑条:设置转换时使用的比特率(Bitrate-based、Two-Pass、Three-Pass,范围0Kbps-20000Kbps)及原来视屏质量的百分比(Quality-based范围1-100),数值越大质量越好,文件越大。其中在Quality-based模式下数值调整到100(--crf 0)为无损压缩,且文件大小不能预测。
  建议:在Quality-based模式下设置为52
  转换视频流:设置MediaCoder对视频进行编码时的参数。只有勾选了该项后,才会启用编码器对原始视频进行编码。
  建议:勾选
  格式编码设置
  格式:设置转换后临时的视屏文件(未与音频文件封装之前)的格式。可选项:XviD、H.264、MPEG1、MPEG2、MPEG4、Theora、Flash Video、Dirac Video、Windows Media Video、RealMedia、H.263、H.263+、H.261、MS-MPEG4-V2、DV Video、Motion JPEG、Lossless JPEG、Huffyuv、
  Snow、AMV、Raw Video
  建议:选择H.264
  (注意:格式的选择会影响下面容器的选择,不是所有的格式都能封装到一个容器中的!由于我们是转MP4-AVC的所以格式选择H.264!)
  容器:最后进行封装时使用的容器,如XXXX.AVI就是使用的AVI作为容器。可选项:Default、AVI、MP4、Matroska、MPEG1、MPEG2、MPEG2-TS、Flash Video、ASF、3GP、3GP2、MOV、MJPEG、RealMedia、DV Forma、OGG、NUT、PMP、Raw Stream
  建议:选择MP4 java强烈推荐:Matroska (MKV)
  (注意:很多转换任务一开始就报有关容器的错误,是因为混流软件对转换后的音频文件或视频文件无法混流所致.具体MediaCoder的混流器能封装什么格式的视频文件和音频文件,请参考其他有关资料!)
  复制视屏流:当勾选参数时,MediaCoder不会对原始视频进行转换,而是直接无损提取。
  建议:不勾选
  (注意:只有勾选转换视频流时,复制视频流的设置才会有效!)
  来源:设置MediaCoder对原视屏解码时所使用的解码方式。可选项:Bypass、MPlayer、MEncoder、FFmpeg、WM Decoder、JM Decoder、AviSynth、File Stream
  建议:勾选自动选择
  (注意:只有不勾选自动选择时才能选择以上解码方式,不正确的选择会导致文件转换失败!)
  编码器:设置MediaCoder对视屏编码时所使用的编码器。可选项:MEncoder、FFmpeg、x264、JM Encoder、XviD、Theora Encoder、Dirac、WM Encoder、VFW Encoder、AMV Encoder、Stream Dumper、Frame Dumper、x264 Remote
  建议:选择x264
  (注意:只有不勾选自动选择后才能选择以上编码器。不正确选择会导致转换失败.要转换MP4-AVC则必须选择x264以防转换失败!)
  右边选区点击x264选项栏进行视频质量的设置
  规格:压缩时使用规格模式。可选项:Auto、Baseline、Main、High
  建议:选择Main 现在的MP4如艾诺v6000HDV 可以用High
  (注意:需要在PSP上播放的MP4-AVC必须选择Main,否则PSP无法播放!)
  级别:--Level:表示编、解码等级
  (注意:无论是转480x272的MP4-AVC,还是720x480的MP4-AVC建议选择Level3.0,防止PSP无法播放!)
  参考帧数:--ref:最大参考帧数,范围0-16。该参数对质量和压缩比都有提高。
  建议:设置大于1
  B帧数:--bframes:在I帧与P帧之间可插入B帧数量的最大值,范围0-16。
  建议:设置大于1
  运动估算模式
  运动估算模式:--me:对全像素块动态预测搜索的方式,可选项:
  Diamond:菱形搜索,搜索半径为1;
  Hexagonal:正六边形搜索,搜索半径为2;
  Uneven Multi-Hexagon:可变半径六边形搜索;
  Exhaustive:全面搜索;
  Hadamard Exhaustive:用Hadamard方式进行全面搜索,比Exhaustive更慢。
  建议:选择Uneven Multi-Hexagon
  (注意:建议设为Uneven Multi-Hexagon;Exhaustive和Hadamard Exhaustive实在太慢了,而且画面质量提高极不明显。除非你不怕浪费时间且追求高质量画面的骨灰级玩家并且很相信自己机器配置那么就选Hadamard Exhaustive吧!)。
  子像素质量优化:--subme:动态预测和分区方式,可选项1-9
  1:用全像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索
  2:用半像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索
  3:用半像素块进行动态搜索,对每个块再用质量模式进行四分之一像素块精确搜索
  4:用快速模式进行四分之一像素块精确搜索
  5:用质量模式进行四分之一像素块精确搜索
  6:进行I、P帧像素块的速率失真最优化(rdo)
  7:进行全部帧像素块的速率失真最优化
  8:进行I、P帧运动矢量及块内部的速率失真最优化
  9:进行全部帧运动矢量及块内部的速率失真最优化
  建议:选择7
  (注意:该选项选择的数值越大画面质量越好,而编码的速度越慢!)
  运动估算半径:--merange:当运动估算模式选项中选择Uneven Multi-Hexagon或Exhaustive时的搜索半径,最大64。
  建议:设置为16

帧的相关设置
  2.x264的参数设置
  点击高级进行有关x264编码器的高级参数设置
  (注意:当要更改参数时,选中该参数后在对话框左下角进行参数选择更改,如果是数值型的参数在填入参数数值后点击对话框左下角的Apply进行保存,每改一个数值型参数都要点击Apply保存。非数值型参数则不用点击任何按钮即可保存。右下角Revert为恢复默认值。没有说明的只需保持默认即可!)
  Bitstream profile:压缩时使用规格模式。可选项:Auto、Baseline、Main、High建议:选择Main
  (注意:需要在PSP上播放的MP4-AVC必须选择Main,否则PSP无法播放!)
  Bitstream level:--Level:表示编、解码等级
  (注意:无论是转480x272的MP4-AVC,还是720x480的MP4-AVC建议该参数选择为30,防止PSP无法播放!)
  P frame Quantitizer:--qp:固定量化模式并设置使用的量化值。
  Maximum interval between IDR-frames:--keyint:最大IDR帧间距。一般来说压制动画时,可以增大该值。
  默认值:250
  Minimum interval between IDR-frames:--min-keyint:最小IDR帧间距。一般来说压制动画时,可以减小该值。
  默认值:25
  Frames used as predictors in B and P frames:--ref:最大参考帧数,范围0-16。该参数对质量和压缩比都有提高。
  建议:大于1
  (注意:数值越高速度越慢!)
  Maximum B frames between I and P frames:--bframes:在I帧与P帧之间可插入B帧数量的最大值,范围0-16。
  建议:大于1
  (注意:数值越高速度越慢!)
  Adaptive B-frame decision method:--b-adapt:自适应B帧判定模式。0:关闭;1:快速;2:优化。下拉菜单中:0-Off为:关闭,1-Fast为:快速,2-Optimal为:优化。默认值为:1-Fast。
  建议:选择2-Optimal
  (注意:当该选项选择为2时, Number of B-frames参数设置较高时,编码速度会下降!)。
  B-frames used as for predicting:--b-pyramid:允许B帧做参考帧。
  建议:选择No
  Alpha parameter of deblocking filter:设置环路滤波的AlphaC的参数,范围-6-6。
  默认值:0
  Beta parameter of deblocking filter:设置环路滤波的Beta的参数,范围-6-6。
  默认值:0
  (注意:Alpha parameter of deblocking filter和Beta parameter of deblocking filter在X264中的参数为--deblock 0:0前一个0对应Alpha parameter of deblocking filter的参数值,后一个0对应Beta parameter of deblocking filter的参数值!)
  熵编码与缓冲
  Use CABAC:内容自适应二进制算术编码,高效率的熵编码。关闭该参数时会严重降低画面质量,但是能提高编码速度。(当不勾选该项时该参数显示为:--no-cabac)。
  默认值:选择Yes
  Minimum quantizer:--qpmin:设置最小量化值,范围0-51。
  默认值:10
  Maximum quantizer:--qpmax:设置最大量化值,范围0-51。
  默认值:51
  Quantizer step:--qpstep:设置相邻帧之间的量化值差,范围0-50。
  默认值:4
  Maximum local bitrate:--vbv-maxrate:平均码率模式下,最大瞬时码率 (与-B设置相同)。
  默认值:0
  (注意:该参数的取值与在ABR编码模式下的Bitrate(码率)保持一致!)
  Averaging period for maximum local bitrate:--vbv-bufsize:码率控制缓冲区的大小,单位kbit。
  默认值:0
  Initial buffer occupancy:--vbv-init:码率控制缓冲区数据保留的最大数据量与冲区大小之比,范围0-1.0。
  默认值:0.9
  Quantizer compression percentage:--qcomp:线性量化控制,0.0为固定码率,1.0为固定量化值,只能用于二次压缩和基于质量的压缩模式。
  默认值:60
  Direct macroblocks prediction:--direct:动态预测方式。可选项:None、Spatial、Temporal、Auto。
  默认值:Temporal。
  建议:选择Auto
  Use weighted prediction for B-frames:--weightb:允许B帧加权预测,可以减少相邻B帧质量低的影响,对质量和压缩比都有提高,且对速度影响极少。
  建议:选择Yes
  (注意:要使该参数生效需要让Maximum B frames between I and P frames设置大于1!)
  Enable all macroblock type:动态块划分方法,在Level较低时允许使用包括8x8、4x8、4x4划分方法。
  建议:选择Yes
  (注意:如果要使用这些划分方法,需要Subpel refinement quality设置大于等于5!)
  Adaptive spatial transform size:允许动态划分方法在4x4和8x8DCT之间自动选择,并且允许使用i8x8动态划分方法。
  建议:选择Yes
  (注意:如果选择No那么只是用4x4DCT动态预测!)
  动态预测与分区
  Fullpixel motion estimation algorithm:--me:对全像素块动态预测搜索的方式,可选项:
  Diamond:菱形搜索,搜索半径为1;
  Hexagonal:正六边形搜索,搜索半径为2;
  Uneven Multi-Hexagon:可变半径六边形搜索;
  Exhaustive:全面搜索;
  Hadamard Exhaustive:用Hadamard方式进行全面搜索,比Exhaustive更慢。
  建议:选择Uneven Multi-Hexagon
  (注意:建议设为Uneven Multi-Hexagon;Exhaustive和Hadamard Exhaustive实在太慢了,而且质量提高极不明显。除非你不怕浪费时间且追求高质量画面的骨灰级玩家并且很相信自己机器配置,那么就选Hadamard Exhaustive吧!)
  Motion search radius:--merange:Fullpixel motion estimation algorithm选择为Uneven Multi-Hexagon或Exhaustive时的搜索半径,最大64。
  默认值:16
  Ignore chroma in motion estimation:不进行色度的动态预测。
  建议:选择No
  (注意:当选则Yes时该参数显示为:--no-chroma-me!)
  Subpel refinement quality:--subme:动态预测和分区方式,可选项1-9
  1:用全像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索
  2:用半像素块进行动态搜索,对每个块再用快速模式进行四分之一像素块精确搜索
  3:用半像素块进行动态搜索,对每个块再用质量模式进行四分之一像素块精确搜索
  4:用快速模式进行四分之一像素块精确搜索
  5:用质量模式进行四分之一像素块精确搜索
  6:进行I、P帧像素块的速率失真最优化(rdo)
  7:进行全部帧像素块的速率失真最优化
  8:进行I、P帧运动矢量及块内部的速率失真最优化
  9:进行全部帧运动矢量及块内部的速率失真最优化
  建议:设置为7
  (注意:该选项选择的数值越大画面质量越好速度越慢!)

Psy算法与量化值
  Psychovisual optimization strength for RDO:--psy-rd 0:0:在rdo中使用Psy算法(一种心理视觉模型)。
  默认值:1.0
  建议:0
  (注意:这个参数对应--psy-rd 0:0中前面的数值!当Subpel refinement quality参数大于等于6时才能使用该这个参数。该参数会影响到Chroma Qp Offset参数。当设置该数设置为1.0时Chroma Qp Offset会自动设置为-2;当该参数设置为0时Chroma Qp Offset会自动设置为0!)
  Psychovisual optimization strength for Trellis:--psy-rd 0:0sy-Trellis量化,可提高细节,但会大幅提高码率。
  默认值:0.0。
  (注意:该参数需要Subpel refinement quality参数大于等于6且Trellis参数大于等于1才能使用。这个参数对应--psy-rd 0:0中后面的数值!)
  Mixed reference frame:--mixed-refs:可以在一帧内使用不同参考帧。该参数能提高画面质量,但对速度影响较大。
  默认值:不勾选
  建议:勾选
  Rate-distortion optimal quantization(trellis):--trellis:Trellis量化,对每个8x8的块寻找合适的量化值,需要勾选CABAC才能使用该参数。可选项:
  Disabled:关闭(0);
  Enabled only for the final encode:只在最后编码时使用(1);
  Enabled during all mode decision:一直使用(2)。
  默认值:0
  建议:开启该参数
  (注意:该参数能提画面高质量,配置较低的电脑且对画面质量没有要求的用户可以选择Enabled only for the final encode,配置较高的电脑且对画面质量有要求的用户可以选择Enabled during all mode decision;画面质量:Enabled only for the final encode比Enabled during all mode decision差!编码速度:Enabled only for the final encode比Enabled during all mode decision快!)
  量化模式等设置
  How AQ distribures bits:--aq-mode:自适应量化模式,可以在1帧中不同宏块间重新分配量化值,能提高暗部细节,但会提高码率。不能在固定量化模式(Const.Quantizer模式)中使用。0:关闭;1:开启。可选项:
  Disabled:关闭(0);
  Variance:AQ开启(1)。
  默认值:Variance AQ(1)
  Reduce blocking and blurring in flat and texture areas:--aq-strength:AQ强度,减小低细节宏块的量化值。可选项:Weak、Normal、Strong。
  默认值:Normal
  Intra luma quantization deadzone:--deadzone-intra:设置intra模式下,亮度死区量化值,范围0-32。
  默认值:11
  Inter luma quantization deadzone:--deadzone-inter:设置inter模式下,亮度死区量化值,范围0-32;
  默认值:21
  Performs early skip detection in P-frames:关闭P帧快速跳过的检测。
  默认值:Yes
  建议:勾选No
  (注意:勾选No后视屏参数中显示为:--no-fast-pskip!)
  Eliminate DCT blocks with small coefficient:关闭P帧联合编码。关闭该项后可以增加细节,但也会增大体积。
  默认值:Yes
  建议:勾选No
  (注意:勾选No后视屏参数中显示为:--no-dct-decimate!)
  Noise reduction:--nr:噪声去除,范围0-100000。
  默认值:0
  Interlaced video content:--interlaced:启用纯交错模式。用于隔行扫描的源。
  默认值:No
  Global header:在基于码率的编码模式下 SPS和PPS只会在开头出现一次。许多播放器(如索尼的PSP)需要使用这一功能.默认会让PPS在每个阶段重复检测。
  默认值:No
  Use access unit delimiters:--aud:使用数据定义符号。
  默认值:No
  Enable picture timing data:允许画面启用定时数据。
  默认值:No
  Set SPS and PPS id number:--sps-id:设置SPS和PPS的ID值。
  默认值:0
  JM-compatible custom quant matrices file:--cqmfile:读取JM格式的外部量化矩阵文件。
  默认值:空
  (注意:如果设置了该选项x264会自动忽略其他--cqm选项)
  编码线程与加速
  Threads:--threads:编码线程,使用多线程技术。多核CPU可以选择自己的CPU核数加快编码速度。
  默认值:0(自动)
  Non-deterministic:--non-deterministic:非确定性。可以稍微减少多线程的开销。
  默认值:Yes
  Crop overscan setting:--overscan:过扫描线。可选项:
  Undefined:不设置
  Show:观看
  Crop:去除
  默认值:Undefined(不设置)
  Video format:--videoformat:视频格式,有点像播放制式。
  可选项:Component、Pal、Ntsc、Secam、Mac、Undefined.
  默认值:Undefined
  Full range samples setting:--fullrange:指定颜色全范围样本设置。
  默认值:No
  Color Primaries:--colorprim:原始色度格式。
  默认值:空
  Transfer characteristics:--transfer:转换方式。
  默认值:空
  Color matrix setting:--colormatrix:色度矩阵设置.
  默认值:空
  Chroma sample location:--chromaloc:色度样本指定,范围0-5。
  默认值:0
  (注意:以上画有波浪线的参数关系到MP4播放器能否正常播放,强烈列建议如果使用是MP4播放器不要设置以上画波浪线的参数,默认即可!)
  Turbo Mode:在多次编码时通过降低Subpel refinement quality参数和Frames used as predictors in B and P frames参数从而加速第一次编码的速度。
  可选项:
  Disabled:禁止使用加速功能。
  Reduce subq:保持Subpel refinement quality参数为用户设置参数不变,降低Frames used as predictors in B and P frames参数为1。
  Reduce subq and frameref to 1:将Subpel refinement quality参数和Frames used as predictors in B and P frames参数都降低为1.
  默认值:Reduce subq and frameref to 1
  (注意:码速度Reduce subq and frameref to 1的编码速度大于Reduce subq大于Disabled;编码质量Disabled优于Reduce subq优于Reduce subq and frameref to 1!)
  在音频选项栏中的参数设置及含义如下:
  转换音频流:对原始音频进行编码。只有勾选该项后,才会启用编码器对原始音频进行编码。
  建议:勾选
  (注意:当转换音频流不勾选时,MediaCoder所转换的MP4-AVC是没有声音的!)

音频解码方式
  来源:设置MediaCoder对原视频的音频解码时所使用的解码方式。可选项:Default、MPlayer、Mencoder、FFmpeg、Winamp Input Plugins、AviSynth、Lame MP3 Decoder、FLAC Decoder、WavPack Decoder、APE Decoder、Waveform File、Waveform Composer、CD Audio
  建议:勾选自动选择
  (注意:只有不勾选自动选择时才能选择以上解码方式,不正确的选择会导致文件转换失败!)
  编码器:设置MediaCoder对视频的音频编码时所使用的编码器。可选项:Lame MP3、Vorbis、Nero Encoder、FAAC、CT AAC+、3GPP AAC+、Windows Media Audio、Helix MP3、Fraunhofer IIS MP3、MusePack、Speex、AMR、Ffmpeg、MEncoder、WavPack、FLAC、APE、TTA、ALS、OptimFROG、lossyWAV、Waveform、Stream Dumper、Generic CLI
  建议:选择Nero Encoder
  (注意:Fraunhofer IIS MP3和 AMR是没有安装的,用户如有需要,点击弹出的对话框中的确定后在自动弹出的网页中下载安装编码器。其他编码器中有少部分不能进行参数调整。要转换MP4-AVC建议选择Nero Encoder以防转换失败!)
  复制音频流:当勾选参数时,MediaCoder不会对原始音频进行转换,而是直接无损提取。
  建议:不勾选
  (注意:只有勾选转换音频流时,复制音频流的设置才会有效!)
  右边选区点击Nero Encoder选项栏进行音频质量的设置
  规格:设置编码时所采用的编码规范。可选项:Auto、LC-AAC、HE-AAC、HE-AAC V2
  建议:选择Auto
  码率模式:设置MediaCoder对音屏编码时采用的编码方式。可选项:
  1.Target Quality动态编码率(VBR);
  2.Target Bitrate平均编码率(ABR);
  3.CBR固定编码率(CBR);
  建议:选择Target Quality
  码率/质量:设置音频编码器的的编码质量。当编码模式选择Target Bitrate或CBR时,范围8-320,数值越大音质越好,编码后的文件越大;当编码模式选择Target Quality时,范围0-100,数值越大音质越好。
  建议:编码模式选择Target Quality时调整到60
  (注意:选用Target Quality转换的音频文件的大小不可预测!)
  Hint Track:增加音频索引。
  建议:不勾选
  音轨ID:当视频文件有多个音轨时(不是多个声道),可以选取不同的音轨。
  建议:默认
  外部文件:当转换时需要采用别的音频文件配音时,可以在添加需要转换的视频文件后,勾选该项并进行其他音频文件的选择。
  建议:一般情况下不勾选
  (注意:只有添加视频文件后才能启用该选项的设置!)
  音轨模式选择
  双音轨模式:当原视频文件包含两条音轨时,可将这两条音轨同时转换并封装。
  建议:不勾选
  分辨率:勾选该项后可以调整MP4-AVC的分辨率,由于PSP的最佳分辨率为480x272所以我们就设置为480x272即可。如果要转720x480的MP4-AVC请参照下面画面裁剪中加黑边的教程,或参照AVS脚本编写教程来加黑边,两者任选其一。
  画面裁剪:默认:Disabled
  双击Video Filters出现子选项后,先双击Scaling将Enable选项设置为true(左下角选择Yes)然后在Width(宽)和Height(高)中输入调整后的分辨率;
  然后双击Expanding将Enable选项设置为true(左下角选择Yes)然后在Width(宽)和Height(高)中输入加黑边后的最终分辨率;
  不使用黑边功能时将Expanding的Enable选项设置为false(左下角选择No)即可。
  图中设置的实际含义:将画面调整为704x480再在左右两边各加8像素黑边((720-704)÷2),变为720x480输出。
  去除黑边:点击裁剪器在弹出的窗口中的模式中选择Auto Detect即可自动除去黑边。点击完成即可。
  (注意:如果在使用AVS时,已经在脚本写入裁剪信息,那么以上裁剪设置忽略!)
  帧率:调整MP4-AVC的帧率,不勾选则会采用原视频的帧率。
  建议:不勾选
  (注意:如果非要更改帧率,选择的帧率应该小于或等于原始文件的帧率,如果发现改变帧率后MP4-AVC的声音与画面不同步,那么就不要勾选该项!)
  宽高比:设置转换后的视频文件的宽高比。
  建议:不勾选
  画面旋转:设置MP4-AVC播放时的画面方向。
  默认值:不勾选
  效果:可以实时显示正在编码的画面。
  默认值:勾选
  (注意:转换过程中效果画面不流畅、没有声音是正常现象。如果效果画面为一片漆黑,说明视频转换出错,请检查设置的参数是否正确!)
  在声音选项栏中的参数设置及含义如下:
  声道:设置转换后音频的声道数。可选项:Original、Mono(Left)、Mono(Right)、Stereo、4Channels、4.1Channels、5.1Channels
  建议:选择Stereo
  (注意:选择多声道会导致转换失败,因为音频选项中的来源如果选择自动,那么会优先使用Mencoder,Mencoder不支持多声道输出,且PSP不支持多声道MP4-AVC的播放!如果需要保留多声道,请在音频选项中的来源手动选择其他解码器,如MPlayer等!)
  声道映射:勾选后可以将左声道映射到右声道,这样就可以将单声道转为立体声。
  建议:根据自己的需要进行设置
  (例如:影片在播放时同时有国语和其他语言时,可以将国语声道映射到非国语声道,这样转换后的MP4-AVC的声道依然会是立体声且为国语发声.)
  输出声道数:设置映射后音频的声道数。
  建议:如开启声道映射功能后选择2
  音量:调整转换后声音过大或过小的问题。范围-200dB-60dB。该参数根据自己的实际情况及需要自行调整,声音过大就调整到0dB以下,相反,声音过小就调整到0dB以上。0dB是不进行任何调整。
  音量自平衡:当无法把握音量参数时使用的选项。可选项:
  Disabled:不使用;
  Mode1:自动增大音量;
  Mode2:自动减少音量;
  建议:选择Disabled

你可能感兴趣的:(X264编码详细过程)