【x264】x264编码库的安装与使用
1.x264编码库简介
X264是一个开源的H.264/MPEG-4 AVC视频编码器库。它是一个纯软件的H.264视频编码器,完全基于CPU进行运算,不依赖硬件编码器驱动
官网:x264, the best H.264/AVC encoder - VideoLAN
1.1 x264编码库的特点
x264不依赖任何硬件编码器,而是通过高度优化的C语言和汇编代码实现所有的编码算法,有以下特点:
1.纯CPU运算
- 所有编码步骤,变换,量化,运动估计,熵编码等,都是CPU做的
- 通过多线程并行化利用多核CPU性能
2.多层优化
- 基于C语言实现:易于移植
- 平台专属汇编优化:针对x86/ARM等架构的SIMD指令集优化关键函数
- 算法优化:快速运动估计算法、自适应量化等
3.模块化设计
graph LR
A[原始YUV帧] --> B[帧内预测]
A --> C[帧间预测]
B & C --> D[变换量化]
D --> E[熵编码]
E --> F[H.264比特流]

1.2 x264的核心编码流程
1.预测编码:
- 帧间预测:利用当前帧内相邻块预测(9种4x4模式,4种16x16模式)
- 帧间预测:运动估计和运动补偿
2.变换与量化
- 对残差数据进行整数DCT变换(4x4/8x8)
- 通过量化矩阵控制约压缩强度
3.熵编码
- CAVLC (上下文自适应变长编码):默认用于 Baseline/Extended Profile
- CABAC (上下文自适应二进制算术编码):用于 Main/High Profile(压缩率更高)
4.码率控制
- 支持CQP/CRF/ABR等多种模式
- 通过MB-tree、psy-RD等算法优化视觉质量
2.x264编码库安装
2.1 通过APT安装(版本未必最新)
sudo apt update
sudo apt install x264 libx264-dev
- x264:提供命令行工具x264(没有头文件和动态库)
- libx264-dev:开发库,用于C/C++程序中使用x264编码
验证安装:
x264 --version
# x264 --version
x264 0.152.2854 e9a5903
(libswscale 4.8.100)
(libavformat 57.83.100)
(ffmpegsource 2.23.0.0)
built on Jan 19 2018, gcc: 7.2.0
x264 configuration: --bit-depth=8 --chroma-format=all
libx264 configuration: --bit-depth=8 --chroma-format=all
x264 license: GPL version 2 or later
libswscale/libavformat/ffmpegsource license: GPL version 2 or later
以上表示安装成功
2.2 从源码编译安装(可以任选版本)
git clone https://code.videolan.org/videolan/x264.git
cd x264
配置并编译
./configure --enable-shared --enable-static
make -j 4 # 使用多核编译加快速度
sudo make install
--enable-shared:生成动态链接库.so文件
--enable-static:生成静态链接库.a文件
验证安装
x264 --version
3.x264的关键参数
3.1 基本参数
| 参数名 | 说明 | 典型值 |
|---|---|---|
| i_width | 视频宽度 | 640/1280/1920 |
| i_height | 视频高度 | 480/720/1080 |
| i_fps_num | 帧率分子 | 30 |
| i_fps_den | 帧率分母 | 1 |
| i_csp | 色彩空间 | X264_CSP_I420 |
3.2 编码质量参数
| 参数名 | 说明 | 典型值 |
|---|---|---|
| i_bitdepth | 位深 | 8/10 |
| rc.i_bitrate | 目标码率(kbps) | 1000-8000 |
| rc.i_rc_method | 码率控制方法 | X264_RC_ABR/CRF/CQP |
| rc.f_rf_constant | CRF质量系数 | 18-28 |
| i_keyint_max | 最大关键帧间隔 | 250 |
3.3 性能参数
| 参数名 | 说明 | 典型值 |
|---|---|---|
| i_threads | 编码线程数 | CPU核心数 |
| b_sliced_threads | 切片线程 | 1 |
| i_lookahead_threads | 前瞻线程 | 0-8 |
4.x264编码库核心API
4.1 初始化接口
// 参数初始化
void x264_param_default(x264_param_t *);
// 应用预设配置
int x264_param_default_preset(x264_param_t *, const char *preset, const char *tune);
// 打开编码器
x264_t* x264_encoder_open(x264_param_t *);
// 分配图像内存
int x264_picture_alloc(x264_picture_t *pic, int i_csp, int i_width, int i_height);
4.2 编码接口
// 编码一帧
int x264_encoder_encode(x264_t *h,
x264_nal_t **pp_nal,
int *pi_nal,
x264_picture_t *pic_in,
x264_picture_t *pic_out);
// 刷新编码器
int x264_encoder_delayed_frames(x264_t *h);
// 关闭编码器
void x264_encoder_close(x264_t *h);
4.3 参数调整接口
// 动态调整参数
int x264_encoder_reconfig(x264_t *h, x264_param_t *param);
// 获取编码器参数
int x264_encoder_parameters(x264_t *h, x264_param_t *param);
5.x264使用示例
#include <stdio.h>
#include <stdint.h>
#include <x264.h>
#include <stdlib.h>
#include <string.h>
#define WIDTH 640
#define HEIGHT 480
#define FPS 30
#define BITRATE 1000
#define OUTPUT_FILE "test.h264"
int main() {
x264_t *encoder = NULL;
x264_picture_t pic_in, pic_out;
x264_param_t param;
FILE *fp = fopen(OUTPUT_FILE, "wb");
// 1. 初始化参数
x264_param_default(¶m);
x264_param_default_preset(¶m, "fast", "zerolatency");
param.i_width = WIDTH;
param.i_height = HEIGHT;
param.i_fps_num = FPS;
param.i_fps_den = 1;
param.i_csp = X264_CSP_I420;
// 码率控制设置
param.rc.i_rc_method = X264_RC_ABR;
param.rc.i_bitrate = BITRATE;
param.rc.i_vbv_max_bitrate = BITRATE * 1.2;
// 关键帧间隔
param.i_keyint_max = FPS * 2;
param.b_intra_refresh = 1;
// 2. 打开编码器
encoder = x264_encoder_open(¶m);
x264_picture_alloc(&pic_in, X264_CSP_I420, WIDTH, HEIGHT);
// 3. 模拟生成测试帧并编码
for(int i = 0; i < 100; i++) {
// 生成测试图像(YUV420)
memset(pic_in.img.plane[0], i%256, WIDTH*HEIGHT); // Y
memset(pic_in.img.plane[1], 128, WIDTH*HEIGHT/4); // U
memset(pic_in.img.plane[2], 128, WIDTH*HEIGHT/4); // V
pic_in.i_pts = i;
// 编码帧
x264_nal_t *nals;
int i_nal;
int frame_size = x264_encoder_encode(encoder, &nals, &i_nal, &pic_in, &pic_out);
if(frame_size > 0) {
for(int j = 0; j < i_nal; j++) {
fwrite(nals[j].p_payload, 1, nals[j].i_payload, fp);
}
}
}
// 4. 刷新编码器
while(x264_encoder_delayed_frames(encoder)) {
x264_nal_t *nals;
int i_nal;
int frame_size = x264_encoder_encode(encoder, &nals, &i_nal, NULL, &pic_out);
if(frame_size > 0) {
for(int j = 0; j < i_nal; j++) {
fwrite(nals[j].p_payload, 1, nals[j].i_payload, fp);
}
}
}
// 5. 清理资源
x264_picture_clean(&pic_in);
x264_encoder_close(encoder);
fclose(fp);
printf("Encoding completed. Output saved to %s\n", OUTPUT_FILE);
return 0;
}

浙公网安备 33010602011771号