x264代码剖析(十):x264核心算法框架

简介: <h1 style="text-align:center">x264<span style="font-family:宋体">代码剖析(十):</span><span style="font-family:Calibri">x264</span><span style="font-family:宋体">核心算法框架</span></h1> <p> </p> <p>        在正

x264代码剖析(十):x264核心算法框架

 

        在正式介绍H.264/AVC核心编码算法之前,首先分析一下其编码结构或者编码流程,后续我们可以根据编码的各个模块分别进行介绍,这样有利于对H.264/AVC视频编码算法的更深入了解。

 

        H.264并没有明确规定一个编解码器如何实现,而是规定了一个编码后的视频比特流的句法和比特流的解码方法,在实现上有较大的灵活性。

 

        H.264/AVC编码器的功能组成如下图所示,编码器仍旧采用变换和预测的混合编码方法。输入帧以宏块为单位被编码器处理,首先按照帧内或帧间预测编码的方法进行处理;接着,预测值与当前块相减,相减后得到的残差块经变换、量化后产生一组量化后的变换系数;最后,这组量化后的变换系数经过熵编码,与解码所需的一些头信息(如预测模式量化参数、运动矢量等)一起组成一个压缩后的码流,经NAL(网络自适应层)供传输和存储用。

 



        为了提供进一步预测用的参考图像,编码器必须有重建的功能。为了去除编解码环路中产生的噪声,提高参考帧的图像质量,从而提高图像压缩性能,设置了一个环路滤波器,滤波后的输出即是重建图像,可用作参考图像。

 

        从编码器的流程可以看出,我们若要学习H.264编码算法,最好就是按照帧内预测帧间预测变换与量化熵编码滤波的顺序依次学习。除此之外,网络适配层、率失真优化、码率控制也是非常重要的学习点。

 

        如下图所示是x264_slice_write()函数包括的内容,其中帧内预测与帧间预测处于Analysis模块,变换与量化处于Encode模块,熵编码处于Entropy Encoding模块,而重建过程中的滤波处于Filter模块,下面依次对这五大关键编码算法的函数关系进行统一的介绍,为接下来具体的算法细节介绍做铺垫。

 

 

 

        下面我们依次对帧内预测、帧间预测、变换与量化、熵编码与滤波这五大部分进行简单介绍。

 

1、帧内预测与帧间预测

 

        x264的 x264_slice_write()函数中调用的x264_macroblock_analyse()的源代码。x264_macroblock_analyse()对应着x264中的分析模块。分析模块主要完成了下面2个方面的功能:

1)对于帧内宏块,分析帧内预测模式

2)对于帧间宏块,进行运动估计,分析帧间预测模式

 

        分析模块的x264_macroblock_analyse()调用了如下函数:

x264_mb_analyse_init()Analysis模块初始化。

x264_mb_analyse_intra()Intra宏块帧内预测模式分析。

x264_macroblock_probe_pskip():分析是否是skip模式。

x264_mb_analyse_inter_p16x16()P16x16宏块帧间预测模式分析。

x264_mb_analyse_inter_p8x8()P8x8宏块帧间预测模式分析。

x264_mb_analyse_inter_p16x8()P16x8宏块帧间预测模式分析。

x264_mb_analyse_inter_b16x16()B16x16宏块帧间预测模式分析。

x264_mb_analyse_inter_b8x8()B8x8宏块帧间预测模式分析。

x264_mb_analyse_inter_b16x8()B16x8宏块帧间预测模式分析。

 

        x264_mb_analyse_intra()用于对Intra宏块进行帧内预测模式的分析。该函数的定义位于encoder\analyse.c,如下图所示。

 



        x264_mb_analyse_inter_***()用于对inter宏块进行帧间预测模式的分析。该函数的定义位于encoder\analyse.c,如下图所示。

 

 


2、变换与量化

 

        宏块编码模块的x264_macroblock_encode()调用了x264_macroblock_encode_internal(),而x264_macroblock_encode_internal()完成了如下功能:

x264_macroblock_encode_skip():编码Skip类型宏块。

x264_mb_encode_i16x16():编码Intra16x16类型的宏块。该函数除了进行DCT变换之外,还对16个小块的DC系数进行了Hadamard变换。

x264_mb_encode_i4x4():编码Intra4x4类型的宏块。

帧间宏块编码:这一部分代码直接写在了函数体里面。

x264_mb_encode_chroma():编码色度块。

 

        函数关系图如下所示:

 


 

3、熵编码

 

        熵编码模块包含两个函数x264_macroblock_write_cabac()x264_macroblock_write_cavlc()。如果输出设置为CABAC编码,则会调用x264_macroblock_write_cabac();如果输出设置为CAVLC编码,则会调用x264_macroblock_write_cavlc()

 

        函数关系图如下所示:

 



4、滤波

 

        滤波模块对应的x264_fdec_filter_row()调用了如下函数:

x264_frame_deblock_row():去块效应滤波器。

x264_frame_filter():半像素插值。

x264_pixel_ssd_wxh()PSNR计算。

x264_pixel_ssim_wxh()SSIM计算。

 

        函数关系图如下所示:

 


        

         本文暂时只给出帧内预测、帧间预测、变换与量化、熵编码、滤波五大部分的函数关系图,具体的算法分析以及代码剖析将在后面继续更新。

目录
相关文章
|
9天前
|
并行计算 算法 Python
Dantzig-Wolfe分解算法解释与Python代码示例
Dantzig-Wolfe分解算法解释与Python代码示例
|
18天前
|
存储 算法 大数据
Python算法高手的必修课:深入理解分治法、贪心算法、动态规划,让你的代码更智能!
【7月更文挑战第9天】在Python算法学习中,分治法(如归并排序)将大问题分解为小部分递归解决;贪心算法(如货币找零)在每步选择局部最优解尝试达到全局最优;动态规划(如斐波那契数列)通过存储子问题解避免重复计算,解决重叠子问题。掌握这三种方法能提升代码效率,解决复杂问题。
|
25天前
|
算法 PHP
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
14 1
|
5天前
|
缓存 算法 Java
如何使用代码实现漏桶算法
如何使用代码实现漏桶算法
|
1月前
|
搜索推荐
排序算法---选择排序-----详解&&代码
排序算法---选择排序-----详解&&代码
|
1月前
|
搜索推荐 算法
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
|
1月前
|
算法 Java
JavaSE——算法(2/2):查找算法-二分查找(前言、详细图解、代码部分)
JavaSE——算法(2/2):查找算法-二分查找(前言、详细图解、代码部分)
40 2
|
1月前
|
人工智能 算法 Java
java中经典算法代码整理
java中经典算法代码整理
26 0
|
1月前
|
算法 IDE 开发工具
c语言的经典算法代码
c语言进阶11-经典算法代码

热门文章

最新文章