技术专栏
海思使用ive转化图片格式并转成OPENCV的Mat对象
有个需求, 在海思平台, 把yuv图像, 转成rgb, 方便后续进行opencv的处理, 这个东西在RK的平台似乎很简单, 使用RGA就行, 但是居然在海思的平台, VPSS只能在YUV的各个分支格式中来回切换, 比如sp420转sp440之类 后来, 经人提醒才知道, 原来海思也是有硬件可以支持这种操作的, 就在海思的IVE里面, 而ive在mpp的文档中没有被提及, 所以一直以来, 我以为VPSS就能做YUV转RGB…
方法其实很简单, 参考了csdn的几个博客, 下面是我的实现(在3516DV300上测试过):
HI_S32 yuvFrame2rgb(VIDEO_FRAME_INFO_S *srcFrame, IPC_IMAGE *dstImage)
{
IVE_HANDLE hIveHandle;
IVE_SRC_IMAGE_S pstSrc;
IVE_DST_IMAGE_S pstDst;
IVE_CSC_CTRL_S stCscCtrl;
HI_S32 s32Ret = 0;
stCscCtrl.enMode = IVE_CSC_MODE_PIC_BT709_YUV2RGB; // IVE_CSC_MODE_VIDEO_BT601_YUV2RGB;
pstSrc.enType = IVE_IMAGE_TYPE_YUV420SP;
pstSrc.au64VirAddr[0] = srcFrame->stVFrame.u64VirAddr[0];
pstSrc.au64VirAddr[1] = srcFrame->stVFrame.u64VirAddr[1];
pstSrc.au64VirAddr[2] = srcFrame->stVFrame.u64VirAddr[2];
pstSrc.au64PhyAddr[0] = srcFrame->stVFrame.u64PhyAddr[0];
pstSrc.au64PhyAddr[1] = srcFrame->stVFrame.u64PhyAddr[1];
pstSrc.au64PhyAddr[2] = srcFrame->stVFrame.u64PhyAddr[2];
pstSrc.au32Stride[0] = srcFrame->stVFrame.u32Stride[0];
pstSrc.au32Stride[1] = srcFrame->stVFrame.u32Stride[1];
pstSrc.au32Stride[2] = srcFrame->stVFrame.u32Stride[2];
pstSrc.u32Width = srcFrame->stVFrame.u32Width;
pstSrc.u32Height = srcFrame->stVFrame.u32Height;
pstDst.enType = IVE_IMAGE_TYPE_U8C3_PACKAGE;
pstDst.u32Width = pstSrc.u32Width;
pstDst.u32Height = pstSrc.u32Height;
pstDst.au32Stride[0] = pstSrc.au32Stride[0];
pstDst.au32Stride[1] = 0;
pstDst.au32Stride[2] = 0;
s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstDst.au64PhyAddr[0], (void **)&pstDst.au64VirAddr[0], "User", HI_NULL, pstDst.u32Height * pstDst.au32Stride[0] * 3);
if (HI_SUCCESS != s32Ret)
{
HI_MPI_SYS_MmzFree(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0]);
LOG(ERROR) << "HI_MPI_SYS_MmzAlloc_Cached Failed with 0x" << hex << s32Ret << endl;
return s32Ret;
}
s32Ret = HI_MPI_SYS_MmzFlushCache(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0], pstDst.u32Height * pstDst.au32Stride[0] * 3);
if (HI_SUCCESS != s32Ret)
{
HI_MPI_SYS_MmzFree(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0]);
LOG(ERROR) << "HI_MPI_SYS_MmzFlushCache Failed with 0x" << hex << s32Ret << endl;
return s32Ret;
}
memset((void *)pstDst.au64VirAddr[0], 0, pstDst.u32Height * pstDst.au32Stride[0] * 3);
HI_BOOL bInstant = HI_TRUE;
s32Ret = HI_MPI_IVE_CSC(&hIveHandle, &pstSrc, &pstDst, &stCscCtrl, bInstant);
if (HI_SUCCESS != s32Ret)
{
HI_MPI_SYS_MmzFree(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0]);
LOG(ERROR) << "HI_MPI_IVE_CSC Failed with 0x" << hex << s32Ret << endl;
return s32Ret;
}
if (HI_TRUE == bInstant)
{
HI_BOOL bFinish = HI_TRUE;
HI_BOOL bBlock = HI_TRUE;
s32Ret = HI_MPI_IVE_Query(hIveHandle, &bFinish, bBlock);
while (HI_ERR_IVE_QUERY_TIMEOUT == s32Ret)
{
usleep(100);
s32Ret = HI_MPI_IVE_Query(hIveHandle, &bFinish, bBlock);
}
}
dstImage->u64PhyAddr = pstDst.au64PhyAddr[0];
dstImage->u64VirAddr = pstDst.au64VirAddr[0];
dstImage->u32Width = pstDst.u32Width;
dstImage->u32Height = pstDst.u32Height;
return HI_SUCC;
}
上面申请内存, 并且等待任务的方式, 是不是很眼熟, 跟特么RK的TDE的异步模式一摸一样…
项目示例放到了github:
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
3
2
评论
打赏
- 分享
- 举报
评论
1个
手气红包
-
白龙 2023-09-27 16:07:54回复 举报RK也有IVE模块,你这里的IPC_IMAGE *dstImage 就是后面要导入到opencv中的rbg图么?
相关专栏
-
浏览量:2521次2019-12-31 16:23:45
-
浏览量:216次2024-09-29 15:57:47
-
浏览量:2305次2022-05-13 10:46:47
-
浏览量:1136次2024-01-11 17:32:51
-
浏览量:1242次2023-10-09 19:22:39
-
浏览量:5138次2020-08-25 18:07:54
-
浏览量:2485次2020-08-25 18:07:51
-
浏览量:2146次2020-08-04 20:32:16
-
浏览量:6119次2019-12-28 10:35:51
-
浏览量:1158次2024-03-04 14:48:01
-
浏览量:8307次2020-12-13 17:04:33
-
浏览量:1707次2019-12-31 16:25:11
-
浏览量:1196次2023-12-19 16:06:28
-
浏览量:469次2023-12-20 17:20:29
-
浏览量:698次2023-06-03 16:02:40
-
浏览量:648次2023-11-30 17:44:37
-
浏览量:2501次2020-08-04 15:11:02
-
浏览量:828次2024-01-24 16:33:36
-
浏览量:875次2024-02-04 10:08:58
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
Marc
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注