x264编码过程分析(二)核心函数x264_slice_write()
程序员文章站
2022-07-06 22:55:11
...
(1)调用x264_nal_start()开始输出一个NALU。
//x264_macroblock_thread_init()设定了宏块编码数据指针p_fenc[0],p_fenc[1],p_fenc[2]在fenc_buf[]中的位置,
//以及宏块重建数据指针p_fdec[0],p_fdec[1],p_fdec[2] 在fdec_buf[]中的位置
(2)x264_macroblock_thread_init():初始化宏块重建像素数据缓存fdec_buf[]和编码像素数据缓存fenc_buf[]。
(3)调用x264_slice_header_write()输出 Slice Header。
(4)进入一个循环,该循环每执行一遍编码一个宏块:
a) 每处理一行宏块,调用一次x264_fdec_filter_row()执行滤波模块。
//(1)环路滤波(去块效应滤波)。通过调用x264_frame_deblock_row()实现。
//(2)半像素内插。通过调用x264_frame_filter()实现。
//经过汇编半像素内插函数处理之后,得到的水平半像素内差点存储在x264_frame_t的filtered[][1]中,
//垂直半像素内差点存储在x264_frame_t的filtered[][2]中,
//对角线半像素内差点存储在x264_frame_t的filtered[][3]中
//(整像素点存储在x264_frame_t的filtered[][0]中)。
//(3)视频质量SSIM和PSNR计算。PSNR在这里只计算了SSD,通过调用x264_pixel_ssd_wxh()实现;SSIM的计算则是通过x264_pixel_ssim_wxh()实现。
b) 调用x264_macroblock_cache_load()将要编码的宏块的周围的宏块的信息读进来。
//(1)加载Intra4x4帧内预测模式intra4x4_pred_mode[]和DCT非零系数non_zero_count[]缓存Cache的宏块周边信息。加载顺序为:上->左->左上。
//(2)加载宏块重建像素p_fdec[]的周边像素,以及宏块编码像素p_fenc[]。对于p_fdec[]来说,在本函数中直接加载当前宏块左边的像素;调用函数x264_macroblock_load_pic_pointers()加载当前宏块上面的像素。对于p_fenc[]来说,调用x264_macroblock_load_pic_pointers()从图像上拷贝数据。
//x264_macroblock_load_pic_pointers()用于给宏块重建像素p_fdec[]和宏块编码像素p_fenc[]加载数据,并且加载图像的半像素数据。
//(1)加载编码宏块mb.pic.p_fenc[]的像素数据,以及重建宏块mb.pic.p_fenc[]上边的像素数据。
//(2)加载参考帧的半像素数据(除了整像素外,还包含了:H,V,C三组半像素数据点)。
//(3)加载参考帧序号ref[]和运动矢量mv[]缓存Cache的宏块周边信息。加载顺序为:左上->上->左。
//(4)加载其它信息。
c) 调用x264_macroblock_analyse()用于分析宏块的编码模式。
//对于帧内宏块来说,主要分析使用Intra16x16合适还是使用Intra4x4合适;
//对于帧间宏块来说,主要分析它的划分模式,并且进行运动估计。
d) 调用x264_macroblock_encode()执行宏块编码模块。
//两个工作:编码(DCT变换和量化)和重建(DCT反变换和反量化)。
e) 调用x264_macroblock_write_cabac()/x264_macroblock_write_cavlc()执行熵编码模块。
f) 调用x264_macroblock_cache_save()保存当前宏块的信息。
g) 调用x264_ratecontrol_mb()执行码率控制。
h) 准备处理下一个宏块。
(5)调用x264_nal_end()结束输出一个NALU。
上一篇: eclipse工作空间配置导出