本文根据 x264 中提供的example.c
文件,实现了将 YUV 文件编码为 264 文件,从整体上了解 x264 编码的大体过程。
x264 实现编码器功能与 FFmpeg 实现编码器大致是类似的,因为 FFmpeg 本身实现 264 格式的编码,就是 x264 的库实现的。
首先分析 x264 给定的编码样例,之后根据样例实现自己的编码器功能。
X264编码样例解析
在 X264 中有example.c
文件,它是 X264 库给定的一个将 YUV 编码为 h264 格式的视频文件的样例。分析其中的源码大致如下:
- 检测输入的参数格式是否正确。
- 获取编码过程中需要用到的参数,并对特定的参数进行赋值。
- 根据给定的视频的宽高等信息为图像结构体
x264_picture_t
分配内存。 - 打开编码器
- 从给定的的待编码的 YUV 文件中读取数据,放到上面分配的
x264_picture_t
结构体的特定字段内。 - 编码一帧图像。
- 将编码生成的 h264 格式的视频数据写到输出文件中。
- 循环5、6、7,实现多帧数据的编码。
- 将编码器内缓存的数据编码完成,并写到输出文件中。
- 清理工作,包括关掉编码器、释放的分配的
x264_picture_t
结构体。
第一步中,检测输入参数格式是否正确,X264 中给出的具体实现如下:
1 2 |
|
其中FAIL_IF_ERROR
定义如下:
1 2 3 4 5 6 7 8 9 |
|
第二步中,获取编码过程中需要用到的参数,并对特定的参数进行赋值。样例的实现中主要包括了三部分,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
其中对于preset
tune
profile
参数的选择部分,请参考上一篇中的X264参数详解。
非默认参数i_csp
指定颜色空间、i_width
和i_height
指定宽高信息、b_vfr_input
指定是否使用时间戳用于帧率控制、
b_repeat_headers
指定是否在每个关键帧前添加 SPS/PPS 信息、b_annexb
指定在每个 NAL 前添加起止码或者 NAL 大小。
第三步,根据视频宽高以及颜色空间为图像结构体x264_picture_t
分配内存。代码如下:
1 2 |
|
第四步,打开编码器。
1
|
|
第五步,读取 YUV 文件数据到x264_picture_t
结构体中。代码实现如下:
1 2 3 4 5 6 7 |
|
第六/七步,编码一帧图像,并将其输入到输出文件。代码实现如下:
1 2 3 4 5 6 7 8 9 |
|
第九步,将编码器内缓存的数据编码完成,并写到输出文件中。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
第十步,最后是清理工作,代码如下:
1 2 |
|
x264编码YUV文件示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
|
注意,在 Ubuntu 下编译时编译命令为
1
|
|
执行时命令如下
1
|
|