当前位置:网站首页>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
边栏推荐
- leetcode
- [leetcode] 700 and 701 (search and insert of binary search tree)
- Jerry's broadcast has built-in flash prompt tone to control playback pause [chapter]
- Can the applet run in its own app and realize live broadcast and connection?
- VHDL实现任意大小矩阵乘法运算
- Free PHP online decryption tool source code v1.2
- What is Ba? How about Ba? What is the relationship between Ba and Bi?
- Jericho turns on the display icon of the classic Bluetooth hid mobile phone to set the keyboard [chapter]
- 21. (article ArcGIS API for JS) ArcGIS API for JS rectangular acquisition (sketchviewmodel)
- VHDL实现单周期CPU设计
猜你喜欢
ubuntu20安装redisjson记录
U.S. Air Force Research Laboratory, "exploring the vulnerability and robustness of deep learning systems", the latest 85 page technical report in 2022
小程序能运行在自有App中,且实现直播和连麦?
存储过程与函数(MySQL)
VHDL实现单周期CPU设计
Free PHP online decryption tool source code v1.2
Variables, process control and cursors (MySQL)
海思3559万能平台搭建:RTSP实时播放的支持
21.(arcgis api for js篇)arcgis api for js矩形采集(SketchViewModel)
Do you know the five most prominent advantages of E-bidding?
随机推荐
QT 项目 表格新建列名称设置 需求练习(找数组消失的数字、最大值)
HDU 4337 King Arthur&#39; S Knights it outputs a Hamiltonian circuit
Set static IP for raspberry pie
About Confidence Intervals
Experience design details
Under the tide of "going from virtual to real", Baidu AI Cloud is born from real
数学归纳与递归
2022年上半年HIT行业TOP50
Lab1 configuration script
大白话高并发(二)
Jerry's ble exiting Bluetooth mode card machine [chapter]
Sorting operation partition, argpartition, sort, argsort in numpy
【安全攻防】序列化与反序列,你了解多少?
PHP lightweight Movie Video Search Player source code
R data analysis: how to predict Cox model and reproduce high score articles
CMB's written test - quantitative relationship
ubuntu20安裝redisjson記錄
[security attack and Defense] how much do you know about serialization and deserialization?
23. (ArcGIS API for JS) ArcGIS API for JS ellipse collection (sketchviewmodel)
19.(arcgis api for js篇)arcgis api for js线采集(SketchViewModel)