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

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。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值