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);
}