FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264

1.前置说明

这里分析的是x264的测试程序x264的结构。命令如下:

./x264 -o akiyo.mkv --input-res 176x144 ~/yuv/akiyo_qcif.yuv

它读入文件akiyo_qcif.mkv,用h.264压缩编码后,写入akiyo.mkv。--input-res是输入文件的解析度。

2. 程序结构

x264分三个步骤:从命令行解析x264编码参数;编码;清理工作。

FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第1张图片

x264的参数有2个:x264_param_t和cli_opt_t,它们作为parse()的参数传递,并得到设置,然后传递给encode()。

FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第2张图片

3. parse() - 命令行解析

  • 如下图是parse()的过程:
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第3张图片
  • x264_param_default()设置x264_param_t的缺省值;
  • getopt_long()解析命令行,紧随其后,在一个while()循环设置x264_param_t和cli_opt_t。这其中还用到了两个临时变量cli_input_opt_t和cli_output_opt_t,分别用来保存输入文件的参数和输出文件的参数。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第4张图片
  • 调用select_output()得到输出文件类型,然后调用该类型的open_file()。这里的文件类型是.mkv,所以调用的是mkv_output的open_file();在mkv_hnd_t中保存了mkv_output_t的相关数据。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第5张图片
  • 调用select_input()得到输入文件类型,然后调用该类型的open_file()。这里的文件类型是.yuv,所以调用的是raw_input的open_file();在raw_hnd_t中保存了raw_input_t的相关数据。当文件以文件映射的方式访问时,使用cli_mmap_t。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第6张图片
  • 最后是调用x264_init_vid_filters()注册和初始化filters,filter包括一个name作为区别。如下图包括source, resize,fix_vfr_pts和depth等等。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第7张图片

在x264_init_vid_filters()中,首先要调用x264_register_vid_filters(),将filters保存在全局链表first_filter中。然后它依次调用source、resize和depth的初始化函数init()。x264_init_vid_filter使用filter name在first_filter链表中找到filter,然后调用其init()函数。

FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第8张图片

4. encode() - 编码

  • 如下图是encode()的过程:
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第9张图片
  • 首先是调用x264_encoder_open()初始化encoder的各个组件。如下图,包括sps, pps, predict, dct, mc, cabac, ratecontrol等等。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第10张图片

x264_encoder_open()得到是一个x264_t类型变量。后面的encode_frame()要参考它。

FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第11张图片
  • 然后是调用x264_encoder_heades()构造头部,包括nal, sps, pps, sei等等,并调用mkv_output::write_headers()写入文件。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第12张图片
  • 最后在一个循环中调用get_frame()读出下一帧,并调用encode_frame()编码并写文件。
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第13张图片

get_frame()和encode_frame()使用了cli_pic_t和x264_picture_t两个变量保存帧。

FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264_第14张图片

在x264_encoder_encode()中,则使用x264_frame_t保存帧。

相关链接

FFMPEG 3.4.2 - ffmpeg源代码分析 (一)
FFMPEG 3.4.2 - ffmpeg源代码分析 (二)
FFMPEG 3.4.2 - ffmpeg源代码分析 (三)
FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264
FFMPEG 3.4.2 - ffplay源代码分析 (一)
FFMPEG 3.4.2 - ffplay源代码分析 (二)
FFMPEG 3.4.2 - ffplay源代码分析 (三)

你可能感兴趣的:(FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264)