海思使用ive转化图片格式并转成OPENCV的Mat对象

海思使用ive转化图片格式并转成OPENCV的Mat对象 Marc 2023-08-29 15:55:54 526

有个需求, 在海思平台, 把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:

https://github.com/MontaukLaw/hi_ive_demo

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
Marc
红包 3 2 评论 打赏
评论
1个
内容存在敏感词
手气红包
  • 白龙 2023-09-27 16:07:54
    回复
    RK也有IVE模块,你这里的IPC_IMAGE *dstImage 就是后面要导入到opencv中的rbg图么?
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
Marc
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区