调用libx264进行视频编码的基本流程图
(1)要调用x264库,首先要加上头文件#include <x264.h>,为了方便后面的操作,定义了一个结构体Encoder,定义Encoder *en,此后的操作都会围绕*en进行相关操作。
typedef struct
{
x264_param_t *param;//参数结构体
x264_t *handle;//压缩器句柄
x264_picture_t *picture; //存储压缩编码前的像素数据。
x264_nal_t *nal;//存储压缩编码后的码流数据
} Encoder;
在定义了结构体Encoder的指针过后需要给param和picture分配空间,将存储压缩编码前的像素数据类型设置为YUV420 planar数据。
en->param = (x264_param_t *) malloc(sizeof(x264_param_t));
en->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t));
x264_picture_alloc(en->picture,X264_CSP_I420,en->param->i_width,en->param->i_height);
en->picture->img.i_csp = X264_CSP_I420;
en->picture->img.i_plane = 3;
(2)然后初始化编码器,用x264_param_t设置压缩图片的参数。并使用函数x264_encoder_open打开压缩编码器,返回的对象给en->handle。
x264_param_default(en->param); //设置默认参数
en->param->i_width = width; //设置帧宽
en->param->i_height = height; //设置帧高
en->param->i_fps_num = 5; //帧率分子
en->param->i_fps_den = 1; //帧率分母
x264_param_apply_profile(en->param, x264_profile_names[0]); //使用baseline
if ((en->handle = x264_encoder_open(en->param)) == 0) {......}
用摄像头采集到的一帧图片的类型为YUV422,要将其进行压缩要讲YUV422的数据转换为YUV420P。YUV420P是plane类型的数据,顾名思义就是将Y,U,V分别存放在不同平面。由像素信息排列介绍可知YUV422和YUV420P的转换,将交错类型转换为平面类型只需要将亮度,色差信号分别存入不同的平面中,en->picture->img.plane[0]存亮度数据,en->picture-> img.plane[1]、en->picture->img.plane[2]分别存色差数据。至于422转换为420时,Y不变,将U和V信号值在行(垂直方向)在进行一次隔行抽样。
YUV422的数据转换为YUV420P
char *y = en->picture->img.plane[0];
char *u = en->picture->img.plane[1];
char *v = en->picture->img.plane[2];
int width=en->param->i_width;
int height=en->param->i_height;
int widthStep422 = width * 2;
for(i = 0; i < height; i += 2)
{
p422 = in + i * widthStep422;
for(j = 0; j < widthStep422; j+=4)
{
*(y++) = p422[j];
*(u++) = p422[j+1];
*(y++) = p422[j+2];
}
p422 += widthStep422;
for(j = 0; j < widthStep422; j+=4)
{
*(y++) = p422[j];
*(v++) = p422[j+3];
*(y++) = p422[j+2];
}
}
(3)转换为YUV420P的数据在en->picture中,下面就可以调用压缩器句柄进行压缩了,压缩完后的码流数据存在x264_nal_t中。
if (x264_encoder_encode(en->handle, &(en->nal), &nNal, en->picture,&pic_out) < 0) {......}
for (i = 0; i < nNal; i++) {.
.....//这里可以进行操作,将码流取出
}
(4)结束视频压缩,通过句柄关闭压缩编码器,释放相关资源,包括存储振数据的类和最初定义的结构体。
x264_picture_clean(en->picture);
free(en->picture);
free(en->param);
x264_encoder_close(en->handle);
free(en)