(转)x264 编码流程



Main函数中包含三个函数:Init,Encode,Fini,分别用来初始化,编码和编码后内存处理。

Init:

I(1)X264_param_default: 参数初始化,包括:CPU,视频参数,编码参数,码率控制参数,日志,分析参数和量化参数等。需要注意的是:

    param->rc.i_qp_constant = 26;  //量化步长;
    param->b_cabac=0;//   关闭CABAC编码;
    param->analyse.i_me_method = X264_ME_DIA; // 菱形搜索
(2)x264_encode_open: 对不正确的参数进行修改,并对各结构体的参数和预测等需要的参数进行初始化。
        x264_validate_parameters参数有效性检验
         1. x264_cpu_num_processors:根据不同的系统确定使用的CPU个数
         2. x264_clip3:取三者之间的最大值

Fini:

x264_picture_clean:释放一副图像所占内存

x264_encoder_close:计算每个宏块的数量和其对应的PSNR值,删除一些关键数据(包括帧的有关信息,量化矩阵和码率控制信息)
/*率失真理论:对有损压缩编码下的失真和编码性能之间的关系
码率控制方法:利用半精度的SATD(sum of absolute transformed differrence)作为模式选择的依据。SATD是将残差经哈达曼变换4*4块的预测残差绝对值总和*/

Encode:

Efseek:重定位文件流上的内部位置指针

  fread:从文件流中读数据

x264_encoder_encode:



编码时,维持着三个队列:frame_next队列(临时缓存,帧类型没确定,待编码的帧队列),frame_current队列(按编码顺序排放,已经确定了帧的类型,正在编码的帧队列)和frame_unused队列(空白队列,将要编码的帧放入该队列)。

   1.x264_reference_update:(更新参考帧队列,若为B帧则不更新)将上一个参考帧放入参考帧队列,并从空闲队列中取出一帧作为当前参考工作帧;

  2.x264_frame_pop_unused:(获取一帧的空间fenc,用来存放待编码的帧)若unused队列不为空,则将取出的帧放入unused队列(x264_frame_pop),否则,分配一帧空间(x264_frame_new);
   3. x264_frame_copy_picture:将该帧图像拷贝到fenc中
   4.判断是否需要进行边界扩展(x264_frame_expand_border_mod16),不能被16整除的都需要进行扩展。
   5.将fenc放入frame_next中(x264_frame_push
  6.如果用到半精度亮度块,需要进行1/2像素扩展(x264_frame_init_lowres
   7.若frame.current[0]==NULL(当前队列中没有帧需要编码)
       I.若frame.next[0]==NULL,结束编码(x264_encoder_frame_end
       II. 判断帧类型(x264_slicetype_decide
       III.将帧类型确定的帧重新排列存放在frame.current队列中
   8. 调整当前队列中帧的顺序,开始编码
  9.对编码之后的nal封装成NAL单元(x264_nal_encode);
   10.将NALU单元写入输出文件(p_write_nalu)

do_encode:


(1).        根据帧类型设置NAL的类型和优先级,若是IDR帧,则清空所有参考帧(x264_reference_reset)。
(2).        初始化参考队列(x264_reference_build_list),list0 前向参考队列,P帧参考;list1,后向参考队列(B帧参考list0和list1)
(3).        码率控制初始化(x264_ratecontrol_start),得到该帧所使用的量化步长QP(x264_ratecontrol_qp)
(4).        创建片头数据(x264_slice_init)
(5).        初始化比特流(bs_init)
(6).        当前帧为IDR帧时,NAL单元更新SPS(x264_sps_write)和PPS(x264_pps_write)
(7).        写片操作,返回编完一帧之后的比特流(x264_slices_write)
(8).        恢复CPU状态(x264_cpu_restore)
(9).        若帧类型是P帧,分别计算帧内编码开销和帧间编码开销,若帧间>帧内,则将P帧重新按I帧进行编码(若图片组的大小>=最小关键帧的个数,则按IDR帧编码)。
(10).        编码结束(x264_encoder_frame_end)

x264_slices_write:


1. 帧内帧间编码(x264_slice_write)
   2. 去块滤波(x264_fdec_filter_row)

x264_slice_write:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgygxw.html