只写了主要函数的功能大概是什么,详细代码还需要自己细看研究。
x264中主要的函数调用关系如下:
main()—>main_internal()
main_internal()调用parse()函数解析输入的参数,调用encode()函数编码
parse()函数调用以下函数:
- x264_param_default():给保存参数的结构体x264_param_t中的变量赋默认值
- getopt_long():解析通过命令行传递来的存储在argv[]中的参数,并作相应的设置工作
- x264_param_default_preset():在preset、tune的参数下给结构体x264_param_t中的一些变量设置默认值
- x264_param_parse():解析编码时输入的参数
encode()函数调用以下函数:
- x264_encoder_open():打开编码器,做一些初始化的工作,其中包括初始化sps、pps、变换量化、运动补偿等相关函数
- x264_encoder_headers():用于输出SPS/PPS/SEI这些H.264码流的头信息
- encode_frame()–>x264_encoder_encode():编码一帧图像
- x264_encoder_close():关闭编码器,同时输出一些码流信息
x264_encoder_encode()函数调用以下函数:
- x264_frame_pop_unused():获取一帧的空间fenc,用来存放待编码的帧
- x264_frame_copy_picture():从图像中复制一帧的信息存到fenc中,pic_in(外部结构体x264_picture_t)到fenc(内部结构体x264_frame_t)
- x264_lookahead_put_frame():将待编码帧放入lookahead.next.list[]队列,等待确定帧类型
- x264_lookahead_get_frames():确定帧类型,并且从lookahead->ofbuf.list队列中取出一帧放入frames.current[]队列
- x264_frame_shift():从frames.current[]队列取出1帧用于编码
- reference_update():更新参考帧列表,若为B帧则不更新。帧间预测需要参考帧,参考帧一般是编码后的重建帧,一帧编码重建完后放入到参考帧列表
- reference_build_list():创建参考帧列表list0和list1
- x264_ratecontrol_start():码率控制开始
- slice_init():初始化slice
- slices_write()–>slice_write():这里是正式编码一帧
- encoder_frame_end():编码结束并且输出NALU、输出重建帧等信息
Slice_write()函数调用以下函数:
- x264_macroblock_thread_init():初始化宏块重建数据缓存fdec_buf[]和编码数据缓存fenc_buf[]
- slice_header_write():输出slice_header的相关信息
- fdec_filter_row():滤波模块,该模块包含了环路滤波,半像素插值,SSIM/PSNR的计算,编码完一行宏块时才调用这个函数,一次处理一行宏块
- x264_macroblock_cache_load_progressive():获取相邻宏块的信息
- x264_macroblock_analyse():宏块分析模块,该模块包含了帧内预测模式分析以及帧间运动估计等
- x264_macroblock_encode()–>macroblock_encode_internal():宏块编码模块。该模块通过对残差的DCT变换、量化等方式对宏块进行编码,重建像素值存到h->mb.pic.p_fdec[Y、U、V]
- x264_macroblock_write_cabac()、x264_macroblock_write_cavlc():熵编码模块
- x264_macroblock_cache_save():保存当前宏块的信息,用于以后的宏块的编码 ,包括Intra4x4宏块帧内预测模式,DCT非零系数,运动矢量,参考帧序号等等,h->mb.pic.p_fdec中的重建像素值copy到h->fdec->plane中做滤波使用
- x264_ratecontrol_mb():码率控制
- x264_macroblock_deblock_strength():计算去方块滤波的滤波强度
x264_macroblock_analyse()函数调用以下函数:
- mb_analyse_init():初始化
- mb_analyse_intra():对I宏块做帧内预测模式分析,分别计算亮度16x16(4种)和4x4(9种)所有模式的代价值,选出代价最小的模式
- x264_macroblock_probe_pskip():分析P宏块是否是skip模式
- mb_analyse_inter_p16x16():对16x16的P宏块进行帧间预测分析
- mb_analyse_inter_p8x8():对8x8的P宏块进行帧间预测分析
- mb_analyse_inter_p4x4():对4x4的P宏块进行帧间预测分析
- x264_me_refine_qpel():亚像素精度搜索
- mb_analyse_transform():变换编码
P帧:P帧允许有I宏块和P宏块;对P帧的每一种分割进行帧间预测,帧间预测过程为选出最佳矢量——>找到最佳的整像素点——>找到最佳的二分之一像素点——>找到最佳的1/4像素点,然后取cost最小的MV和分割方式,从而得到最佳的运动矢量及最佳匹配块,最后从帧内模式和帧间模式中选择代价比较小的方式(有可能没有找到很好的匹配块,这时候就直接使用帧内预测而不是帧间预测)。对B帧的预测过程于P帧类似
macroblock_encode_internal()调用以下函数:
- macroblock_encode_skip():编码skip类型的宏块
- mb_encode_i16x16():编码16x16的I宏块,对残差进行DCT变换,量化,对于444格式的视频,分别编码YUV
- x264_mb_encode_i8x8():编码8x8的I宏块,分别编码YUV
- x264_mb_encode_i4x4():编码4x4的I宏块,分别编码YUV