x264编码详细文字全过程

x264编码详细文字全过程

      苏辉         2006年4月 南京

(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.     一些收尾工作,为下次宏块作准备(看的比较粗)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值