天天看点

x264代码剖析(九):x264_encoder_encode()函数之x264_slice's'_write()函数x264代码剖析(九):x264_encoder_encode()函数之x264_slice's'_write()函数

        x264_encoder_encode()函数的核心函数就是x264_slices_write()函数。在x264_slices_write()函数中,最主要的工作就是调用了x264_slice_write()函数(注意“x264_slices_write()”和“x264_slice_write()”名字差了一个“s”),x264_slice_write()函数才是真正完成编码的核心函数,如下图所示。

x264代码剖析(九):x264_encoder_encode()函数之x264_slice's'_write()函数x264代码剖析(九):x264_encoder_encode()函数之x264_slice's'_write()函数

        在x264_slices_write()函数中,最主要的工作就是调用了x264_slice_write()函数,需要注意,x264_slices_write()调用了x264_slice_write()。其中x264_slices_write()的单位为帧,而x264_slice_write()的单位为slice。最常见的情况下一个帧里面只有一个slice,但是也有可能一个帧里面有多个slice。对应的代码如下:

        x264_slice_write()是完成编码工作的函数。该函数中包含了去块效应滤波,运动估计,宏块编码,熵编码等模块。x264_slice_write()调用了如下函数:

x264_nal_start():开始写一个nalu。

x264_macroblock_thread_init():初始化宏块重建数据缓存fdec_buf[]和编码数据缓存fenc_buf[]。

x264_slice_header_write():输出 slice header。

x264_fdec_filter_row():滤波模块。该模块包含了环路滤波,半像素插值,ssim/psnr的计算。

x264_macroblock_cache_load():将要编码的宏块的周围的宏块的信息读进来。

x264_macroblock_analyse():分析模块。该模块包含了帧内预测模式分析以及帧间运动估计等。

x264_macroblock_encode():宏块编码模块。该模块通过对残差的dct变换、量化等方式对宏块进行编码。

x264_macroblock_write_cabac():cabac熵编码模块。

x264_macroblock_write_cavlc():cavlc熵编码模块。

x264_macroblock_cache_save():保存当前宏块的信息。

x264_ratecontrol_mb():码率控制。

x264_nal_end():结束写一个nalu。

        x264_slice_write()用于编码一个slice。该函数的定义位于encoder\encoder.c,对应的代码分析如下:

        根据源代码简单梳理了x264_slice_write()的流程,如下所示:

(1)、调用x264_nal_start()开始输出一个nalu。

(2)、x264_macroblock_thread_init():初始化宏块重建像素缓存fdec_buf[]和编码像素缓存fenc_buf[]。

(3)、调用x264_slice_header_write()输出 slice header。

(4)、进入一个循环,该循环每执行一遍编码一个宏块:

               a)、 每处理一行宏块,调用一次x264_fdec_filter_row()执行滤波模块。

               b)、 调用x264_macroblock_cache_load_progressive()将要编码的宏块的周围的宏块的信息读进来。

               c) 、调用x264_macroblock_analyse()执行分析模块。

               d) 、调用x264_macroblock_encode()执行宏块编码模块。

               e) 、调用x264_macroblock_write_cabac()/x264_macroblock_write_cavlc()执行熵编码模块。

               f) 、调用x264_macroblock_cache_save()保存当前宏块的信息。

              g) 、调用x264_ratecontrol_mb()执行码率控制。

              h) 、准备处理下一个宏块。

(5)、调用x264_nal_end()结束输出一个nalu。

        到这儿,其实还没进入真正的h.264视频编码算法,后续将正式进入,依次分析帧内预测、帧间预测、变换与量化、去方块滤波、熵编码、码率控制等等。

继续阅读