当前位置:网站首页>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
 Insert picture description here
   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
 Insert picture description here

   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
 Insert picture description here

原网站

版权声明
本文为[Run! The bug is coming]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207062023146730.html