基于寒武纪CNCodec 做视频编解码遇到的一些问题

前段时间基于FFMpeg 写了一个软编软解的 模块 供业务层调用,即利用CPU来做 不需要依赖于特定硬件

最近 又来了一个需求需要基于寒武纪MLU270 来做视频编解码 ,摸索了三四天 发现一个奇怪的现象就是,正常解码没有问题, 但是编码的时候 如果不改变分辨率 可以正常编码 ,

但是如果改变了分辨率发现编出来的数据不对 不能正常播放,最终和寒武纪的人员确认

CNCodec 只能做编解码 不能做视频缩放 ,如果需要做视频缩放需要 自己处理 或者调用CNCV 来实现 ,

ffmpeg-mlu的描述说明里面有 :

如下 :

集成了cambricon 硬件平台的 ffmpeg版本下载ffmpeg-mlu下载

ffmpeg with cambricon​​​​​​

之前没怎么接触过寒武纪平台

发现了和ffmpeg不一样的地方

ffmpeg解码之后 得到yuv数据 直接送给下一步编码就可以了

但是寒武纪的解码之后 得到一个cnvideoDecOutput 的数据结构 

得到的这个数据你并不能直接拿来用 

根据官方提供的sample大概可以理解为,解码出来的这个数据是放在板卡里面的内存里面的

我们要用的话需要将他从板卡的内存考到电脑的的内存  即从device 拷到 host

这个device就是指寒武纪硬件卡 ,host即指我们的电脑

编码的时候 又需要将host的内存拷到板卡的内存 

还有一个就是根据官方文档说明:

解码出来的数据 必须调用 

cnvideoDecAddReference 添加引用之后才能操作他

使用完毕之后 需要调用

cnvideoDecReleaseReference 删除引用 ,当引用计数为0 之后 内部会释放掉这块内存。

所以就会得到如下的代码:


static void decode_cb(void* data, void* param)
{
	cnvideoEncInput input;
	cncodecWorkInfo work_info;

	BOOL ret = 0;
	if (!data || !param)
	{
		return;
	}


	QMCY_MLU270_CODEC *handle = (QMCY_MLU270_CODEC*)param;
	QMCY_MLU270_DECODER* pHandle = &handle->m_decoder;

	QMCY_MLU270_ENCODER* encoder = &handle->m_encoder;


	memset(&work_info, 0, sizeof(work_info));
	work_info.inMsg.instance = 0;
	work_info.inMsg.cardId = 0;
	work_info.inMsg.mode = 0;


	cnvideoDecOutput *output_frame = (cnvideoDecOutput*)data;

	ret = cnvideoDecAddReference(pHandle->decode_handle,&output_frame->frame);
	if(ret < 0)
	{
		printf("cnvideoDecAddReference failed:ret is %d\n",ret);
	   	return;
	}


	//dumpSurfaceData(g_fileyuv,&output_frame->frame);
	//CopyFrame(&input.frame, frame);
	memset(&input, 0, sizeof(cnvideoEncInput));

	ret = cnvideoEncWaitAvailInputBuf(encoder->encode_handle, &input.frame, 3000);
	if (ret < 0) 
	{
		printf("Call cnvideoEncWaitAvailInputBuf failed, ret(%d)\n", ret);
		return;
	}
	
	TranscodeDemoVirFrame src_frame(output_frame->frame.width, output_frame->frame.height,
										output_frame->frame.pixelFmt, output_frame->frame.planeNum,
										output_frame->frame.stride);


	// device to host
	CopyDevFrame2VirFrame(&src_frame, &output_frame->frame);


#if 0 //Does not support
		ret = cncodecImageTransform(&dst_frame, nullptr, &dst_frame, nullptr, CNCODEC_Filter_BiLinear, &work_info);

		if(ret != CNCODEC_SUCCESS)
		{
			printf("cncodecImageTransform failed :%d\n",ret);
		}
#endif


		// host to device
		CopyVirFrame2DevFrame(&input.frame, &src_frame);

		src_frame.ReleaseDemoVirFrame();

		ret = cnvideoDecReleaseReference(pHandle->decode_handle, &output_frame->frame);
		if (ret < 0) 
		{
			printf("Call cnvideoDecReleaseReference failed, ret(%d)\n", ret);
			return ;
		}


		input.pts =  encoder->packet_index++ % CNCODEC_PTS_MAX_VALUE;
		printf("Pts is %d \n",input.pts);
		
		ret = cnvideoEncFeedFrame(encoder->encode_handle, &input, 5000);
		if (ret < 0) 
		{
			printf("Call CN_Encode_Feed_Frame failed, ret(%d)\n", ret);
		}

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QMCY_jason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值