欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

构建海思万能平台:YUV到RGB的颜色空间转换

最编程 2024-08-15 15:11:57
...
/* *描述 :线程里用于处理图像信息,完成yuv-rgb的颜色空间转换 *参数 :arg 为自定义结构video_process_s,VPSS_GRP和VPSS_CHN用于传参给HI_MPI_VPSS_GetChnFrame *返回值:无 *注意 :HI_MPI_VPSS_GetChnFrame完必须释放,否则再次获取VB会报错 HI_MPI_SYS_MmzAlloc_Cached需要搭配HI_MPI_SYS_MmzFlushCache刷新,最后需要HI_MPI_SYS_MmzFree释放 *Bug :未知原因卡顿,偶现退出后无法再次运行的问题(定位至保存问题) */ HI_S32 deal_myself_yuv2rgb(HI_VOID *arg) { HI_S32 s32Ret; IVE_SRC_IMAGE_S stSrc ; IVE_DST_IMAGE_S stDst ; IVE_HANDLE IveHandle ; IVE_CSC_CTRL_S stCscControl ; HI_BOOL bInstant = HI_TRUE; VIDEO_FRAME_INFO_S stVideoFrame; // VIDEO_FRAME_INFO_S* pstVideoFrame = &stVideoFrame; video_process_s* pstPara; pstPara = (video_process_s*)arg; memset(&stSrc,0,sizeof(IVE_SRC_IMAGE_S)); memset(&stDst,0,sizeof(IVE_DST_IMAGE_S)); memset(&stCscControl,0,sizeof(IVE_CSC_CTRL_S)); stCscControl.enMode = IVE_CSC_MODE_VIDEO_BT601_YUV2RGB; // #define RGB_SAVE #ifdef RGB_SAVE FILE *fOut; HI_CHAR *pchDstFileName = "./YUV/chn1_w1920_h1080_RGB.bgr"; #endif // ftruncate(fOut,0); while(1) { // sleep(1); s32Ret = HI_MPI_VPSS_GetChnFrame(pstPara->VpssGrp, pstPara->VpssChn, &stVideoFrame,1000); // SAMPLE_PRT("deal_myself_yuv2rgb chn is %d!\n",pstPara->VpssChn); if(s32Ret != HI_SUCCESS) { // SAMPLE_PRT("VPSS_GetChnFrame err for %#x!\n",s32Ret);//while1打印太多 continue; } else { // SAMPLE_PRT("VPSS_GetChnFrame success for %#x!\n",s32Ret); /*初始化YUV输入数据结构体stSrc*/ stSrc.enType = IVE_IMAGE_TYPE_YUV420SP ; stSrc.au64PhyAddr[0] = stVideoFrame.stVFrame.u64PhyAddr[0] ; stSrc.au64PhyAddr[1] = stVideoFrame.stVFrame.u64PhyAddr[1] ; stSrc.au64PhyAddr[2] = stVideoFrame.stVFrame.u64PhyAddr[2] ; stSrc.au64VirAddr[0] = stVideoFrame.stVFrame.u64VirAddr[0] ; stSrc.au64VirAddr[1] = stVideoFrame.stVFrame.u64VirAddr[1] ; stSrc.au64VirAddr[2] = stVideoFrame.stVFrame.u64VirAddr[2] ; stSrc.au32Stride[0] = stVideoFrame.stVFrame.u32Stride[0] ; stSrc.au32Stride[1] = stVideoFrame.stVFrame.u32Stride[1] ; stSrc.au32Stride[2] = stVideoFrame.stVFrame.u32Stride[2] ; stSrc.u32Width = stVideoFrame.stVFrame.u32Width ; stSrc.u32Height = stVideoFrame.stVFrame.u32Height ; // printf("width is %d, height is %d\n", stSrc.au32Stride[0], stSrc.u32Height); /*初始化输出RPG数据结构体并在内存中为图像数据分配空间*/ s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&stDst.au64PhyAddr[0], (HI_VOID *)&stDst.au64VirAddr[0], "DstImg", HI_NULL, stSrc.au32Stride[0] * stSrc.u32Height * 3); if(HI_SUCCESS != s32Ret) { SAMPLE_PRT("Error(%#x),HI_MPI_SYS_MmzAlloc_Cached failed!\n",s32Ret) ; HI_MPI_SYS_MmzFree(stDst.au64PhyAddr[0],(HI_VOID*)stDst.au64VirAddr) ; return s32Ret; } // memset(stDst.au64VirAddr[0],0,stSrc.u32Height * stSrc.au32Stride[0] * 3) ; stDst.enType = IVE_IMAGE_TYPE_U8C3_PACKAGE ; stDst.u32Height = stSrc.u32Height ; stDst.u32Width = stSrc.u32Width ; stDst.au32Stride[0] = (((stVideoFrame.stVFrame.u32Width + 15) >> 4) << 4); // stDst.au32Stride[0] = stSrc.au32Stride[0] ; // stDst.au32Stride[1] = stDst.au32Stride[1] ; // stDst.au32Stride[2] = stDst.au32Stride[2] ; // stDst.au64VirAddr[1] = stDst.au64VirAddr[0] + stDst.u32Height * stDst.au32Stride[0] ; // stDst.au64VirAddr[2] = stDst.au64VirAddr[1] + stDst.u32Height * stDst.au32Stride[0] ; // stDst.au64PhyAddr[1] = stDst.au64PhyAddr[0] + stDst.u32Height * stDst.au32Stride[0] ; // stDst.au64PhyAddr[2] = stDst.au64PhyAddr[1] + stDst.u32Height * stDst.au32Stride[0] ; // memset(stDst.au64VirAddr,0, stSrc.au32Stride[0] * stSrc.u32Height * 3); /*将cache中的内容刷新到内存*/ // s32Ret = HI_MPI_SYS_MmzFlushCache(stDst.au64PhyAddr[0],(HI_VOID*)stDst.au64VirAddr[0],stDst.u32Height * stDst.au32Stride[0] * 3) ; // // s32Ret = HI_MPI_SYS_MmzFlushCache(0, NULL, 0) ; // if(HI_SUCCESS != s32Ret){ // SAMPLE_PRT("Error(%#x),HI_MPI_SYS_MmzFlushCache failed!\n",s32Ret) ; // // HI_MPI_SYS_MmzFree(stDst.au64PhyAddr[0],stDst.au64VirAddr) ; // // HI_MPI_SYS_MmzFree(stDst.au64PhyAddr[0],stDst.au64VirAddr) ; // // return ; // } /*将YUV数据转换到RGB planar存储,地址保存在stDst结构体中*/ s32Ret = HI_MPI_IVE_CSC(&IveHandle,&stSrc,&stDst,&stCscControl,bInstant) ; if(HI_SUCCESS != s32Ret) { SAMPLE_PRT("Error(%#x),HI_MPI_IVE_CSC failed!\n",s32Ret) ; // return ; } #ifdef RGB_SAVE printf("yuv2bgr success\r\n"); fflush(stdout); fOut = fopen(pchDstFileName,"wb"); if(HI_NULL == fOut) { printf("Open out file %s fail\n",pchDstFileName); fclose(fOut); // return; } WriteBGRPackFile(&stDst, fOut); fclose(fOut); printf("file\r\n"); #endif s32Ret = HI_MPI_SYS_MmzFree(stDst.au64PhyAddr[0],(HI_VOID*)stDst.au64VirAddr) ; if(HI_SUCCESS != s32Ret){ SAMPLE_PRT("Error(%#x),HI_MPI_SYS_MmzFree failed!\n",s32Ret) ; HI_MPI_SYS_MmzFree(stDst.au64PhyAddr[0],(HI_VOID*)stDst.au64VirAddr) ; // return ; } s32Ret = HI_MPI_VENC_SendFrame(pstPara->VpssChn, &stVideoFrame,1000); HI_MPI_VPSS_ReleaseChnFrame(pstPara->VpssGrp, pstPara->VpssChn, &stVideoFrame); } } }