您的位置:首页 > 其它

V4L2视频采集 X264编码项目总结(下)

2015-05-08 14:41 351 查看
X264编码相关的总结
一、库的交叉编译
详情见交叉编译X264

注:
之前我用的arm9的板子,交叉编译x264库的时候出现问题,说是arm9的架构没办法编译
之后换成arm11的板子才成功的。

二、库的调用
typedef struct { //编码需要使用的对象 为Encoder结构的成员

x264_param_t *param; //参数设置

x264_t *handle;

x264_picture_t *picture;

x264_nal_t *nal;

} Encoder;

编码前的初始化函数,包括内存的分配,编码参数的初始化
//按照自己编码的需要,设定en->param里的值

void compress_begin(Encoder *en, int width, int height) {
en->param = (x264_param_t *) malloc(sizeof(x264_param_t));
if(en->param==NULL)
{
printf("param=null
");
exit(1);
}
en->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t));
if(en->picture==NULL)
{
printf("pic=null
");
exit(1);
}
x264_param_default(en->param); //set default param
//en->param->rc.i_rc_method = X264_RC_CQP;	// en->param->i_log_level = X264_LOG_NONE;

// en->param->i_threads  = X264_SYNC_LOOKAHEAD_AUTO;
en->param->i_width =width; //set frame width
en->param->i_height =height; //set frame height

//en->param->i_frame_total = 0;

//  en->param->i_keyint_max = 10;
en->param->rc.i_lookahead = 0;
//   en->param->i_bframe = 5;

//  en->param->b_open_gop = 0;
//  en->param->i_bframe_pyramid = 0;
//   en->param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS;

//en->param->rc.i_bitrate = 1024 * 10;
en->param->i_fps_num = 5; 	en->param->i_fps_den = 1;
x264_param_apply_profile(en->param, x264_profile_names[0]);

if ((en->handle = x264_encoder_open(en->param)) == 0) {
return;
}
/* Create a new pic */
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;
}

编码函数//将yuv422的Y U V抽出,直接编码为264
int compress_frame(Encoder *en, int type, uint8_t *in, uint8_t *out) {
x264_picture_t pic_out;
int nNal = -1;
int result = 0;
int i = 0;
uint8_t *p_out = out;

uint8_t *y = en->picture->img.plane[0];
uint8_t *u = en->picture->img.plane[1];
uint8_t *v = en->picture->img.plane[2];

int is_y = 1, is_u = 1;
int y_index = 0, u_index = 0, v_index = 0;

int yuv422_length = 2 * en->param->i_width * en->param->i_height;
for (i = 0; i < yuv422_length; ++i) {
if (is_y) {
*(y + y_index) = *(in + i);
++y_index;
is_y = 0;
} else {
if (is_u) {
*(u + u_index) = *(in + i);
++u_index;
is_u = 0;
} else {
*(v + v_index) = *(in + i);
++v_index;
is_u = 1;
}
is_y = 1;
}
}

switch (type) {
case 0:
en->picture->i_type = X264_TYPE_P;
break;
case 1:
en->picture->i_type = X264_TYPE_IDR;
break;
case 2:
en->picture->i_type = X264_TYPE_I;
break;
default:
en->picture->i_type = X264_TYPE_AUTO;
break;
}

if (x264_encoder_encode(en->handle, &(en->nal), &nNal, en->picture,
&pic_out) < 0) {
return -1;
}
en->picture->i_pts++;
for (i = 0; i < nNal; i++) {
memcpy(p_out, en->nal[i].p_payload, en->nal[i].i_payload);
p_out += en->nal[i].i_payload;
result += en->nal[i].i_payload;
}
return result;
}


输出264内存的指针为out,长度为result,写入文件可能x264格式的文件,用VLC播放器可以打开。 编码结束的释放内存收尾函数

void compress_end(Encoder *en) {
if (en->picture) {
x264_picture_clean(en->picture);
free(en->picture);
en->picture = 0;
}
if (en->param) {
free(en->param);
en->param = 0;
}
if (en->handle) {
x264_encoder_close(en->handle);
}
free(en);
}


注:
摄像头的分辨率自己根据摄像头设置,否则可能出现segmentation fault.
高版本容易出现彩色空间无法编码的问题,也会出现segmentation fault,或者编码到264文件大小为0kb
建议用低版本的库进行编码。

如果你得到的数据和上面设置的X264_CSP_I420不匹配,每一帧会出现colorplace fault。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: