【hisi3516】——IVE yuv420转bgr planner(代码)

hisi3516, yuv420, bgr

整体流程是从VPSS中获取到yuv数据,然后yuv420转rgb,rgb resize,最后送入nnie。其中的yuv420转rgb,resize用cpu来处理的话,耗时比较验证。

时间对比:

方法 设备 尺寸 时间
yuv2rgb arm cpu 416x416 40ms
resize arm cpu 720p->416x416 103ms
yuv2rgb IVE 416x416 44 us

这里 IVE的时间只有us,是因为输入数据本身就在MMZ内存中,所以没有内存申请,搬运的耗时。

代码和测试数据下载链接:https://download.csdn.net/download/u011622208/87253632

有积分的支持一下。感谢。

code:

#include "hi_common.h"
#include "hi_comm_ive.h"
#include "hi_ive.h"
#include "sample_comm.h"
#include 

typedef struct tag_csc_s
{
        HI_S32  sWidth;
        HI_S32  sHeight;
        IVE_SRC_IMAGE_S stSrc;
        IVE_DST_IMAGE_S stDst;
        IVE_CSC_CTRL_S stCtrl;
}CSC_S;

void CreateCSC2(CSC_S* pstCSC, HI_S32 sWidth, HI_S32 sHeight)
{
        HI_S32 s32Ret;
        HI_U32 u32Size;

        pstCSC->sWidth = sWidth;
        pstCSC->sHeight = sHeight;

        // input image
        memset(&pstCSC->stSrc,0,sizeof(IVE_SRC_IMAGE_S));
        pstCSC->stSrc.enType        = IVE_IMAGE_TYPE_YUV420SP;

        s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstCSC->stSrc.au64PhyAddr[0], (HI_VOID **)&pstCSC->stSrc.au64VirAddr[0],
                                                                                 "InputImage", HI_NULL, sWidth * sHeight * 3 / 2);
        if(s32Ret != HI_SUCCESS)
        {
                printf("can't alloc InputImage memory for %x\n",s32Ret);
        }                        
        pstCSC->stSrc.u32Width      = sWidth;
        pstCSC->stSrc.u32Height     = sHeight;
        pstCSC->stSrc.au32Stride[0]  = sWidth;

        // SP420
        pstCSC->stSrc.au32Stride[1] = pstCSC->stSrc.au32Stride[0];
        pstCSC->stSrc.au64PhyAddr[1] = pstCSC->stSrc.au64PhyAddr[0] + pstCSC->stSrc.au32Stride[0] * pstCSC->stSrc.u32Height;
        pstCSC->stSrc.au64VirAddr[1] = pstCSC->stSrc.au64VirAddr[0] + pstCSC->stSrc.au32Stride[0] * pstCSC->stSrc.u32Height;

        SAMPLE_PRT("[nnie yolov3], ive yuv phy addr0:%lld \n", pstCSC->stSrc.au64PhyAddr[0]);
        SAMPLE_PRT("[nnie yolov3], ive yuv phy addr1:%lld \n", pstCSC->stSrc.au64PhyAddr[1]);
        SAMPLE_PRT("[nnie yolov3], ive yuv vir addr0:%lld \n", pstCSC->stSrc.au64VirAddr[0]);
        SAMPLE_PRT("[nnie yolov3], ive yuv vir addr1:%lld \n", pstCSC->stSrc.au64VirAddr[1]);

        // output image
        memset(&pstCSC->stDst,0,sizeof(IVE_DST_IMAGE_S));
        u32Size = sWidth * sHeight * 3;
        pstCSC->stDst.enType        = IVE_IMAGE_TYPE_U8C3_PLANAR;
        s32Ret = HI_MPI_SYS_MmzAlloc(&pstCSC->stDst.au64PhyAddr[0], (void**)&pstCSC->stDst.au64VirAddr[0],
                                    "OutputImage", HI_NULL, u32Size);

        SAMPLE_PRT("[nnie yolov3], ive rgb addr0:%lld \n", pstCSC->stDst.au64PhyAddr[0]);
        SAMPLE_PRT("[nnie yolov3], ive rgb addr1:%lld \n", pstCSC->stDst.au64PhyAddr[1]);
        SAMPLE_PRT("[nnie yolov3], ive rgb addr2:%lld \n", pstCSC->stDst.au64PhyAddr[2]);
        SAMPLE_PRT("[nnie yolov3], ive rgb vir addr0:%lld \n", pstCSC->stDst.au64VirAddr[0]);
        SAMPLE_PRT("[nnie yolov3], ive rgb vir addr1:%lld \n", pstCSC->stDst.au64VirAddr[1]);
        SAMPLE_PRT("[nnie yolov3], ive rgb vir addr2:%lld \n", pstCSC->stDst.au64VirAddr[2]);

        if(s32Ret != HI_SUCCESS)
        {
                printf("can't alloc OutputImage memory for %x\n",s32Ret);
        }
        pstCSC->stDst.u32Width      = sWidth;
        pstCSC->stDst.u32Height     = sHeight;
        pstCSC->stDst.au32Stride[0]  = sWidth;

        pstCSC->stDst.au64VirAddr[1] = pstCSC->stDst.au64VirAddr[0] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[0];
        pstCSC->stDst.au64PhyAddr[1] = pstCSC->stDst.au64PhyAddr[0] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[0];
        pstCSC->stDst.au32Stride[1] = pstCSC->stDst.au32Stride[0];

        pstCSC->stDst.au64VirAddr[2] = pstCSC->stDst.au64VirAddr[1] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[1];       
        pstCSC->stDst.au64PhyAddr[2] = pstCSC->stDst.au64PhyAddr[1] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[1];
        
        pstCSC->stDst.au32Stride[2] = pstCSC->stDst.au32Stride[0];
       
        // ctrl
        memset(&pstCSC->stCtrl, 0, sizeof(IVE_CSC_CTRL_S));
        pstCSC->stCtrl.enMode = IVE_CSC_MODE_PIC_BT601_YUV2RGB;
}


int main(int argc, char* argv[])
{

    TestCSC();

    return 1;
}



void DestoryCSC(CSC_S* pstCSC)
{
        if (pstCSC->stSrc.au64PhyAddr[0] != NULL)
        {
                HI_MPI_SYS_MmzFree(pstCSC->stSrc.au64PhyAddr[0], pstCSC->stSrc.au64VirAddr[0]);
        }

        if (pstCSC->stDst.au64VirAddr[0] != NULL)
        {
                HI_MPI_SYS_MmzFree(pstCSC->stDst.au64PhyAddr[0], pstCSC->stDst.au64VirAddr[0]);
        }
}

void ReadYUV420pFile(IVE_IMAGE_S *pstImg, FILE *pFp)
{
        HI_U16 y;
        HI_U8 *pU8;
        HI_U16 height;
        HI_U16 width;
        HI_U8 *pUBuf;
        HI_U8 *pVBuf;
        HI_U16 x;
        int nShift;

        width = pstImg->u32Width;
        height = pstImg->u32Height * 1.5;
        pU8 = pstImg->au64VirAddr[0];

        printf("input yuv data uv vir addr:%lld \n", pstImg->au64VirAddr[0]);

        for (y = 0; y < height; y++)
        {
                if ( 1 != fread(pU8,width,1,pFp))
                {
                        printf("Read file fail\n");
                        return ;
                }

                pU8 += pstImg->au32Stride[0];
        }

}


void WriteYUV420spFile(IVE_IMAGE_S *pstImg, FILE *pFp)
{
        HI_U16 y;
        HI_U8 *pU8;
        HI_U16 height;
        HI_U16 width;

        width = pstImg->u32Width;
        height = pstImg->u32Height * 3 / 2;
        pU8 = pstImg->au64VirAddr[0];

        printf("in write yuv file, vir addr:%lld \n", pstImg->au64VirAddr[0]);

        for (y = 0; y < height; y++)
        {
                if ( 1 != fwrite(pU8, width, 1, pFp))
                {
                        printf("write file error, y = %d\n", y);
                        return ;
                }

                pU8 += pstImg->au32Stride[0];
        }
}


void WriteBGRPackFile2(IVE_IMAGE_S *pstImg, FILE *pFp)
{
        HI_U16 y;
        HI_U8 *pU8;
        HI_U16 height;
        HI_U16 width;

        width = pstImg->u32Width;
        height = pstImg->u32Height*3;
        pU8 = pstImg->au64VirAddr[0];
        printf("in write rgb file, vir addr:%lld \n", pstImg->au64VirAddr[0]);

        for (y = 0; y < height; y++)
        {
                if ( 1 != fwrite(pU8,width,1,pFp))
                {
                        printf("write file error, y = %d\n", y);
                        return ;
                }

                pU8 += pstImg->au32Stride[0];
        }
}

long long time_use2(struct timeval start, struct timeval end)
{
    long long time_ = (end.tv_sec - start.tv_sec) * 1000000.0 + end.tv_usec - start.tv_usec;
    return time_ ;
}

void TestCSC()
{
    IVE_HANDLE hIveHandle;
    CSC_S stCSC;
    FILE *fIn;
    FILE *fOut;
    FILE *fMid;
    HI_CHAR *pchSrcFileName = "./yuv416x416.bin";
    HI_CHAR *pchDstFileName = "./rgb416x416.bin";

    HI_CHAR *pchMidFileName = "./middle_yuv416x416.bin";


    fIn = fopen(pchSrcFileName,"rb");
    if(HI_NULL == fIn)
    {
        printf("Open in file %s fail\n",pchSrcFileName);
                return;
    }

    fOut = fopen(pchDstFileName,"wb");
    if(HI_NULL == fOut)
    {
        printf("Open out file %s fail\n",pchDstFileName);
        fclose(fIn);
                return;
    }

    fMid = fopen(pchMidFileName,"wb");
    if(HI_NULL == fOut)
    {
        printf("Open out file %s fail\n",pchMidFileName);
        fclose(fIn);
                return;
    }



    int sWidth = 416;
    int sHeight = 416;
    struct timeval begin, t_ive;

    printf("aaaaaaaaaaaaaaaaaaaaa\n");
    CreateCSC2(&stCSC, sWidth, sHeight);

    ReadYUV420pFile(&stCSC.stSrc, fIn);

    WriteYUV420spFile(&stCSC.stSrc, fMid);

    gettimeofday(&begin, NULL);
    HI_S32 s32Ret = HI_MPI_IVE_CSC(&hIveHandle, &stCSC.stSrc, &stCSC.stDst, &stCSC.stCtrl, HI_TRUE);
    if (s32Ret != HI_SUCCESS)
    {       
        printf("[nnie yolov3], HI_MPI_IVE_CSC failed with:%d \n", s32Ret );
    }
    gettimeofday(&t_ive, NULL);
    SAMPLE_PRT("[nnie yolov3], ive yuv2rgb, time:%lld us \n", time_use2(begin, t_ive) );

    WriteBGRPackFile2(&stCSC.stDst, fOut);
    DestoryCSC(&stCSC);

    printf("finish ive yuv2rgb\n");

    fclose(fIn);
    fclose(fMid);
    fclose(fOut);
}

你可能感兴趣的:(嵌入式AI,yuv2bgr,hisi3516dv300)