本文共 2644 字,大约阅读时间需要 8 分钟。
(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合适; //对于帧间宏块来说,主要分析它的划分模式,并且进行运动估计。 //(1)如果I Slice,调用x264_mb_analyse_intra()帧内预测分析-从16x16的SAD(4种预测方向),4个8x8的SAD(方向同4x4 仅限high profile及更高profile)和,16个4x4SA(9种)中选出最优方式:宏块大小+预测模式 //(2)如果当前是P Slice,则进行下面流程的分析: //1、调用x264_macroblock_probe_pskip()分析是否为Skip宏块,如果是的话则不再进行下面分析。 //2、调用各种函数x264_mb_analyse_inter_?计算多种模式中哪一种代价最低(P16x16 P16x8 P8x16 P8x8 P4x8 P8x4 P4x4 Intra宏块)(P Slice中也允许有Intra宏块)。 //(3)如果当前是B Slice,则进行和P Slice类似的处理。//宏块的帧间预测方法:初始化 + x264_me_search_ref运动估计(先整像素 再亚像素精度) + 统计 //X264中,半像素数据是在滤波(Filter)部分的x264_fdec_filter_row()中提前计算出来的,而1/4像素数据则是临时通过半像素数据线性内插得到的。//运动搜索估计方式:1、快读搜索(菱形搜索算法(DIA) 六边形搜索算法(HEX) 非对称十字型多层次六边形格点搜索算法(UMH))//2、全局搜索(太慢故极少使用)//搜索的工作量越大。速度越慢 质量越高 (就是在找局部代价极小值点) d) 调用x264_macroblock_encode()执行宏块编码模块。 //两个工作:编码(DCT变换和量化)和重建(DCT反变换和反量化)。 e) 调用x264_macroblock_write_cabac()/x264_macroblock_write_cavlc()执行熵编码模块。 //(1)根据Slice类型的不同,调用不同的函数输出宏块头(MB Header):对于P/B/I Slice,调用x264_cavlc_mb_header_p/b/i() //(2)调用x264_cavlc_qp_delta()输出宏块QP值 //(3)调用x264_cavlc_block_residual()输出CAVLC编码的残差数据 f) 调用x264_macroblock_cache_save()保存当前宏块的信息。以供后面宏块编码作为参考。 //它的作用与x264_macroblock_cache_load()是相对应的。 g) 调用x264_ratecontrol_mb()执行码率控制。 h) 准备处理下一个宏块。(5)调用x264_nal_end()结束输出一个NALU。
转载地址:http://wbhrn.baihongyu.com/