libx264进行视频编码的流程

时间:2023-01-10 20:25:58

调用libx264进行视频编码的基本流程图

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的指针过后需要给parampicture分配空间,将存储压缩编码前的像素数据类型设置为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的数据转换为YUV420PYUV420Pplane类型的数据,顾名思义就是将Y,U,V分别存放在不同平面。由像素信息排列介绍可知YUV422YUV420P的转换,将交错类型转换为平面类型只需要将亮度,色差信号分别存入不同的平面中,en->picture->img.plane[0]存亮度数据,en->picture-> img.plane[1]en->picture->img.plane[2]分别存色差数据。至于422转换为420时,Y不变,将UV信号值在行(垂直方向)在进行一次隔行抽样。

libx264进行视频编码的流程

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)