当前位置:网站首页>Construction of Hisilicon universal platform: color space conversion YUV2RGB
Construction of Hisilicon universal platform: color space conversion YUV2RGB
2022-07-07 03:37:00 【Run! The bug is coming】
Preface
Color space conversion , In addition to playfully looking for positioning , Draw a frame , More representative is yuv To rgb The transformation of
Makefile
Mainly used sdk in ive Inner operator , Because the default is not supported ive Static library , Need to be in Makefile Add it
SENSOR_LIBS += $(REL_LIB)/libive.a
Code
Or create a new thread dedicated to conversion
if(yuv2rgbEnable)
{
stv_process_yuv2rgb.VpssGrp = VpssGrp;
stv_process_yuv2rgb.VpssChn = VpssChn[1];
pthread_t video_process_yuv2rgb_id;
s32Ret=pthread_create(&video_process_yuv2rgb_id, NULL, &video_process_yuv2rgb_task,(HI_VOID*)&stv_process_yuv2rgb);
if(s32Ret != 0)
{
SAMPLE_PRT("pthread video_process_yuv2rgb create failed\n");
return -HI_FAILURE;
}
pthread_detach(video_process_yuv2rgb_id);
}
Modify based on the original processing thread
/* * describe : Used for processing yuv2rgb Color space conversion thread * Parameters :arg For custom structure video_process_s,VPSS_GRP and VPSS_CHN Used to pass parameters to HI_MPI_VPSS_GetChnFrame * Return value : * Be careful :HI_MPI_VPSS_GetChnFrame You must release , Otherwise get again VB Will report a mistake */
HI_VOID *video_process_yuv2rgb_task(HI_VOID *arg)
{
HI_S32 cnt = 0;
HI_S32 s32Ret;
VIDEO_FRAME_INFO_S stVideoFrame;
video_process_s* pstPara;
pstPara = (video_process_s*)arg;
sleep(1);
memset(&stVideoFrame,0,sizeof(VIDEO_FRAME_INFO_S));
while(cnt <= 10)
{
s32Ret = HI_MPI_VPSS_GetChnFrame(pstPara->VpssGrp, pstPara->VpssChn, &stVideoFrame,1000);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("%dVPSS_GetChnFrame err for %#x!\n", cnt,s32Ret);
cnt++;
}
else
{
HI_MPI_VPSS_ReleaseChnFrame(pstPara->VpssGrp, pstPara->VpssChn, &stVideoFrame);// Failure to release will result in subsequent vb collapse
goto DEAL;
}
}
goto EXIT;
DEAL:
// deal_myself_osd(arg);
deal_myself_yuv2rgb(arg);
// deal_myself(arg);
EXIT:
pthread_exit(0);
}
HI_MPI_IVE_CSC
Is the core conversion function , be located SVP Under the table of contents HiIVE API Refer to the manual , The focus is on the configuration of the function parameters
/*****************************************************************************
* Prototype : HI_MPI_IVE_CSC
* Description : YUV2RGB\YUV2HSV\YUV2LAB\RGB2YUV color space conversion are supported.
* Parameters : IVE_HANDLE *pIveHandle Returned handle ID of a task
* IVE_SRC_IMAGE_S *pstSrc Input source data:
* 1. SP420\SP422 type for YUV2RGB\YUV2HSV\YUV2LAB;
* 2. U8C3_PACKAGE\U8C3_PLANAR type for RGB2YUV;
* IVE_DST_IMAGE_S *pstDst Output result:
* 1. U8C3_PACKAGE\U8C3_PLANAR typed for YUV2RGB\YUV2HSV\YUV2LAB;
* 2. SP420\SP422 type for RGB2YUV;
* IVE_CSC_CTRL_S *pstCscCtrl Control parameters for CSC
* HI_BOOL bInstant For details, see HI_MPI_IVE_DMA.
* Return Value : HI_SUCCESS: Success;Error codes: Failure.
* Spec : The size of the input data ranges from 64x64 pixels to 1920x1080 pixels.
* The physical addresses of the input data and output data must be 16-byte-aligned.
* The stride must be 16-pixel-aligned.
* History:
*
* 1. Date : 2011-05-16
* Author :
* Modification : Created function
* 2. Date : 2013-08-09
* Author :
* Modification : Modified function
*
*****************************************************************************/
HI_S32 HI_MPI_IVE_CSC(IVE_HANDLE *pIveHandle, IVE_SRC_IMAGE_S *pstSrc,IVE_DST_IMAGE_S *pstDst, IVE_CSC_CTRL_S *pstCscCtrl, HI_BOOL bInstant);
Precautions should be carefully watched , There are clear requirements for resolution , I didn't look carefully. For the first time, I naively jumped into the pit I dug , However, in the last issue, the mode of thinking changed thick , It was successfully located in less than five minutes , After all, this log function is really powerful 
Then the use of functions is much smoother , Refer to the following code configuration
/* * describe : Thread is used to process image information , complete yuv-rgb Color space conversion * Parameters :arg For custom structure video_process_s,VPSS_GRP and VPSS_CHN Used to pass parameters to HI_MPI_VPSS_GetChnFrame * Return value : nothing * Be careful :HI_MPI_VPSS_GetChnFrame You must release , Otherwise get again VB Will report a mistake HI_MPI_SYS_MmzAlloc_Cached Need to match HI_MPI_SYS_MmzFlushCache Refresh , Last need HI_MPI_SYS_MmzFree Release *Bug : Unknown cause Caton , Occasionally, you cannot run again after exiting ( Locate the save problem ) */
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 Too many prints
continue;
}
else
{
// SAMPLE_PRT("VPSS_GetChnFrame success for %#x!\n",s32Ret);
/* initialization YUV Input data structure 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);
/* Initialize output RPG Data structure and allocate space for image data in memory */
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);
/* take cache Refresh the contents of to memory */
// 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 ;
// }
/* take YUV Data conversion to RGB planar Storage , The address is saved at stDst In the structure */
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);
}
}
}
The transformed rgb Keep the file (rgb888 Or call it rgb24 Format )
/* * describe : Used to hold rgb Images * Parameters :pstImg IVE_IMAGE_S Structure , Define two-dimensional generalized image information , be used for ive_csc After processing rgb24 Image saving pFp The file pointer , Used to save files * Return value : nothing * Be careful : nothing *Bug : It's easy to get stuck for unknown reasons ( Change the location of the open file and solve ) */
HI_VOID WriteBGRPackFile(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 = (HI_U8*)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];
}
}
result
A little accident happened , Except for the small problems solved in the comments bug, The image feels strange , Like adding a filter 
This operator should support yuv turn rgb And our default is always yvu actually ,vpss After modifying the image format at, it is much more normal 
边栏推荐
- 存储过程与函数(MySQL)
- QT 打开文件 使用 QFileDialog 获取文件名称、内容等
- Numpy中排序操作partition,argpartition,sort,argsort
- Stored procedures and functions (MySQL)
- About Tolerance Intervals
- Jerry's broadcast has built-in flash prompt tone to control playback pause [chapter]
- 概率论公式
- Sub pixel corner detection opencv cornersubpix
- 【安全攻防】序列化與反序列,你了解多少?
- About Confidence Intervals
猜你喜欢
![[leetcode] 700 and 701 (search and insert of binary search tree)](/img/b0/6aa9185f02fb1905fc59e6b329f7c3.jpg)
[leetcode] 700 and 701 (search and insert of binary search tree)

海思3559万能平台搭建:RTSP实时播放的支持

20.(arcgis api for js篇)arcgis api for js面采集(SketchViewModel)

【安全攻防】序列化與反序列,你了解多少?

Ubuntu20 installation redisjson record

Set static IP for raspberry pie

2022年上半年HIT行业TOP50

Shangsilicon Valley JVM Chapter 1 class loading subsystem

Open3d mesh filtering

22. (ArcGIS API for JS) ArcGIS API for JS Circle Collection (sketchviewmodel)
随机推荐
Leetcode-02 (linked list question)
Mobile measurement and depth link platform - Branch
QT 打开文件 使用 QFileDialog 获取文件名称、内容等
什么是 BA ?BA怎么样?BA和BI是什么关系?
[security attack and Defense] how much do you know about serialization and deserialization?
1200.Minimum Absolute Difference
【C语言】 题集 of Ⅸ
Jerry's transmitter crashed after the receiver shut down [chapter]
When you go to the toilet, you can clearly explain the three Scheduling Strategies of scheduled tasks
LAB1配置脚本
Do you know the five most prominent advantages of E-bidding?
My brave way to line -- elaborate on what happens when the browser enters the URL
Create applet from 0
Jerry's RTC clock development [chapter]
ubuntu20安装redisjson记录
About Tolerance Intervals
Jerry's FM mode mono or stereo selection setting [chapter]
19. (ArcGIS API for JS) ArcGIS API for JS line acquisition (sketchviewmodel)
1200.Minimum Absolute Difference
未来发展路线确认!数字经济、数字化转型、数据...这次会议很重要