海思OSD

目前我要在3518E上面做個OSD,疊加時間上去,主要的開發有兩種方式:

一種是獲取時間字符串,通過第三方庫提供的接口將時間字符串轉化爲bmp格式位圖,然後利用SDK中提供的demo直接進行轉化

第三方庫主要有三個,一下是第三方庫的編譯配置:

配置freetype:
xy@xy-pc:~/aaa/freetype-2.4.10#./configure --prefix=/home/xy/aaa/bin --host=arm-hisiv500-linux
編譯安裝:make ,make install。
配置SDL:
xy@xy-pc:~/aaa/SDL-1.2.15#./configure --prefix=/home/xy/aaa/bin --host=arm-hisiv500-linux  --disable-alsa --disable-pulseaudio
編譯安裝。

配置SDL_tff:
xy@xy-pc:~/aaa/SDL_ttf-2.0.11# ./configure --with-freetype-prefix=/home/xy/aaa/bin --host=arm-hisiv500-linux

如果要安轉到指定的文件中使用以下命令

DESTDIR=/home/wangwq/sdl make install

參考海思的demo代碼:

 /*************************************************
      step 1: create region and attach to venc

*************************************************/

#if 1
VencOsdHandle    = 0;
    u32VencRgnNum = 0;
    s32Ret = SAMPLE_RGN_CreateOverlayForVenc(VencOsdHandle, u32VencRgnNum);
    if(HI_SUCCESS != s32Ret)
    {
        printf("SAMPLE_RGN_CreateOverlayForVenc failed! s32Ret: 0x%x.\n", s32Ret);
        return s32Ret;
    }
#endif
    /*************************************************
      step 2: create region and attach to vpss group
     *************************************************/

。。。。。。。。。。。。。 

/*************************************************
      step 10: load bitmap to region
     *************************************************/
 #if 2    
    VpssOsdHandle    = 1;
    u32VpssRgnNum = 0;
    s32Ret = SAMPLE_RGN_CreateOverlayExForVpss(VpssOsdHandle, u32VpssRgnNum);
    if(HI_SUCCESS != s32Ret)
    {
        printf("SAMPLE_RGN_CreateOverlayExForVpss failed! s32Ret: 0x%x.\n", s32Ret);
        return s32Ret;
    }
 #endif   

Handle = 0;
        s32Ret = HI_MPI_RGN_GetAttr(Handle, &stRgnAttrSet);
        if(HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_RGN_GetAttr failed! s32Ret: 0x%x.\n", s32Ret);
            return s32Ret;
        }
        
        s32Ret = HI_MPI_RGN_GetCanvasInfo(Handle, &stCanvasInfo);
        if(HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_RGN_GetCanvasInfo failed! s32Ret: 0x%x.\n", s32Ret);
            return s32Ret;
        }    
         
        stBitmap.pData   = (HI_VOID *)stCanvasInfo.u32VirtAddr;
        stSize.u32Width  = stCanvasInfo.stSize.u32Width;
        stSize.u32Height = stCanvasInfo.stSize.u32Height;
        s32Ret = SAMPLE_RGN_UpdateCanvas("/sd0/mm.bmp", &stBitmap, HI_FALSE, 0, &stSize, stCanvasInfo.u32Stride, 
            stRgnAttrSet.unAttr.stOverlayEx.enPixelFmt);
        if(HI_SUCCESS != s32Ret)
        {
            printf("SAMPLE_RGN_UpdateCanvas failed! s32Ret: 0x%x.\n", s32Ret);
            return s32Ret;
        }
        
        s32Ret = HI_MPI_RGN_UpdateCanvas(Handle);
        if(HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_RGN_UpdateCanvas failed! s32Ret: 0x%x.\n", s32Ret);
            return s32Ret;
        }
}

  /*************************************************
      step 14: create a thread for venc to save stream
      to a file
     *************************************************/
    char pfilename[40]; 
    snprintf(pfilename, sizeof(pfilename), "/sd0/venc_encode_stream.h264");
    pastream = fopen(pfilename, "wb+");  
    HI_ASSERT( NULL != pastream);


    stVencGetPram.pstream   = pastream;
    stVencGetPram.VeChnId   = VencChn;
    stVencGetPram.s32FrmCnt = 0;
    if (0 != pthread_create(&g_stVencThread, 0, SAMPLE_RGN_VencGetStream, (HI_VOID *)&stVencGetPram))
{
printf("create thread failed!\n");
}

step14 並非是OSD代碼,主要是用來測試錄製視頻,注意其路徑既可,涉及到的其他函數都已在demo存在

第二種方法是直接讀取時間並進行顯示,不在進行位圖格式的轉換,下載附件字體庫放在相應的位置

代碼的實現如下:


int OSD_LoadFile(char *pName, int filesize, void *pAddr)
{
        FILE *pfd = NULL;

        if( pAddr == NULL || pName == NULL )

        {
                printf("pAddr or pName not exist !!\n");
                goto QUIT_LOAD;
        }

        pfd = fopen(pName, "rb");
        if ( pfd == NULL ) 

        {
          printf("open file error!!\n");
        goto QUIT_LOAD;
        }

        if( fseek( pfd, 0, SEEK_SET ) < 0)

        {
        printf("file error!!\n");
        goto QUIT_LOAD;
        }

        if( fread(pAddr, filesize, 1, pfd) < 0)

        {
        printf("file error!!\n");
        goto QUIT_LOAD;
        }

        if ( pfd != NULL )

        {
                fclose(pfd);
        }

        return 0;

QUIT_LOAD:
        if( pfd != NULL )

        {
        fclose(pfd);
        }

        return -1; 
}


long OSD_GetFileSize(char *pName)
{
        FILE *pfd = NULL;
        long filesize = 0;

        if(  pName == NULL )

        {
        printf("pName not exist !!\n");
                goto QUIT_GET;
        }

        pfd = fopen(pName, "rb");
        if ( pfd == NULL ) 

        {
                printf("open file error!!\n");
                goto QUIT_GET;
        }


        if ( fseek( pfd, 0, SEEK_END ) < 0)

        {
        printf("file error!!\n");
        goto QUIT_GET;
        }

        filesize = ftell(pfd);

        if ( pfd != NULL )

        {
                fclose(pfd);
        }

        return filesize;

QUIT_GET:
        if( pfd != NULL )

        {
                fclose(pfd);
        }

        return -1;
}

char * open_font_lib( char* fontPath)
{
        int fileSize = 0;
        char *pFont = NULL;


        fileSize = (int)OSD_GetFileSize(fontPath);
        pFont  = malloc(fileSize);
        if ( !pFont )

        {
                printf("memory not enough !!\n");
                return NULL; 
         }

        if ( OSD_LoadFile(fontPath, fileSize, pFont) < 0 ) 

        {
                free ( pFont );
                printf("LoadFile fail !!\n");
                return NULL; 
        }
        return pFont;
}

void init_font_libs(void)
{
        if ( s_pFontSetASC32 == NULL)
                s_pFontSetASC32 = open_font_lib( FONT_PATH_ASC32 );
        if ( s_pFontSetASC16 == NULL)
                s_pFontSetASC16 = open_font_lib( FONT_PATH_ASC16 );
}

 
 int OSD_Draw_BitMap_ASC32( int len, const unsigned char *pdata, unsigned char *pbitmap)
 {  
        int temp;
        int index=0;
 
        if( 0 == len || !pdata || !pbitmap )
        {
                printf("[%s, %d] error, NULL pointer transfered.\n", __FUNCTION__, __LINE__); 
                return -1;
        }
 
        int i, w, h, flag, offset;
        unsigned char ch;
        unsigned char *code, *pDst;
 
        int xx = 0;
 
        /***move 1 Byte to can set color***/
        pbitmap = pbitmap+1; 

        /* get the first row, then next*/
        for( h = 0; h < 32; h++ )// height ;  32
        { 
                for( i = 0; i < len; i++ )   
               {
                       ch = pdata[i];
                       offset  = ch * 64; //32x16/8 = 64 Byte
                       code= s_pFontSetASC32 + offset;
                       lag= 0x8000;
 
                       for ( w = 0; w < 16; w++ ) //width : 16
                      {
                              pDst = (unsigned short *)( pbitmap + xx );
                              if(flag > 0x80)
                              {
                                      if( (code[h*2]) & (flag >> 8))
                                     {
                                             //*pDst = (0x00<< 10) | (0x00<< 5) | (0x80);//display font
                                             *pDst = (0xff<< 10) | (0xff<< 5) | (0xff);//display font
                                     }
                                     else
                                     {
                                             *pDst = (0x88<< 10) | (0x88<< 5) | (0x77);//(0xff<< 10) | (0x00<< 5) | (0x00);//background
                                      }
                              }
                              else
                              {
                                      if( (code[h*2+1]) & flag )
                                      {
                                              *pDst = (0xFF<< 10) | (0xFF<< 5) | (0xff);//display font
                                      }
                                      else
                                      {
                                              *pDst = (0x88<< 10) | (0x88<< 5) | (0x77);//(0xff<< 10) | (0x00<< 5) | (0x00);//background
                                      }
                              }
 
                              flag >>= 1;
                              xx += 2;
                       }
                }
        }

}


static int OSD_Draw_BitMap_ASC16( int len, const unsigned char *pdata, unsigned char *pbitmap)
{
        if( 0 == len || !pdata || !pbitmap )
        {
                printf("[%s, %d] error, NULL pointer transfered.\n", __FUNCTION__, __LINE__); 
                return -1;
        }
        int i, w, h, flag, offset;
        unsigned char ch;
        unsigned char *code, *pDst;
        //printf("[%s %d]: len = %d, data = %s\n", __func__, __LINE__, len, pdata);
        int xx = 0;
    
        char *asc16 =s_pFontSetASC16;

    /***move 1 Byte to can set color***/
        pbitmap = pbitmap+1; 
   
        /* get the first row, then next*/
        for( h = 0; h < 16; h++ )// height ; 
        {
                for( i = 0; i < len; i++ )
                {
                        ch = pdata[i];
                        offset = ch * 16;
                        code = asc16 + offset;
                        flag = 0x80;

                        for ( w = 0; w < 8; w++ )
                        {
                pDst = (unsigned short *)( pbitmap + xx );
                                if( (code[h]) & flag )
                                {
                                        // *pDst = (0x00<< 10) | (0x00<< 5) | (0x80);//display font
                                        *pDst = (0xFF<< 10) | (0xFF<< 5) | (0xFF);//display font
                                 }
                                 else
                                 {
                                         *pDst = (0x88<< 10) | (0x88<< 5) | (0x77);//(0xff<< 10) | (0x00<< 5) | (0x00);//background
                                 }
                                flag >>= 1;
                                xx += 2;
                         }
                 }
        }
        //printf("[%s %d]: xx = %d\n", __func__, __LINE__, xx);
        return 0;
}


int OSD_Overlay_RGN_Handle_Init( RGN_HANDLE Handle,  unsigned int ContentLen )
{
        HI_S32 s32Ret = HI_FAILURE;
        RGN_ATTR_S stRgnAttr;
        MPP_CHN_S stChn;
        VENC_GRP VencGrp;
        RGN_CHN_ATTR_S stChnAttr;

        int font_w = 8;
        int font_h = 16;

        if(Handle == 0)
        {
                font_w = 16;
                font_h = 32;
        }
        else
        {
                font_w = 8;
                font_h = 16;
         }

         stRgnAttr.enType                            = OVERLAY_RGN; 
    stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_RGB_1555; 
         stRgnAttr.unAttr.stOverlay.stSize.u32Width  = font_w * ContentLen; 
         stRgnAttr.unAttr.stOverlay.stSize.u32Height = font_h; 
         stRgnAttr.unAttr.stOverlay.u32BgColor= OSD_PALETTE_COLOR_WHITE; 

         s32Ret = HI_MPI_RGN_Create(Handle, &stRgnAttr);
         if (HI_SUCCESS != s32Ret)
        {
                printf("HI_MPI_RGN_Create (%d) failed with %#x!\n", Handle, s32Ret);
                return HI_FAILURE;
         }
         printf("create handle:%d success!\n", Handle);

         //   VencGrp = 0;

         memset(&stChnAttr, 0, sizeof(stChnAttr));
         if(Handle == 0)
         {
                 stChn.enModId = HI_ID_VENC;
                 stChn.s32DevId = 0;
                 stChn.s32ChnId = 0;
         }
         else
         {
                 stChn.enModId = HI_ID_VENC;
                 stChn.s32DevId = 0;
                 stChn.s32ChnId = 1;
          }
          stChnAttr.bShow = HI_TRUE;
          stChnAttr.enType = OVERLAY_RGN;
          stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X    = OSD_POSITION_X; 
          stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y    = OSD_POSITION_Y; 
          stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha      = 10;
          stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha      = 128; 
          stChnAttr.unChnAttr.stOverlayChn.u32Layer     = 0;

         stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = HI_FALSE;
         stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp  = 0;

         s32Ret = HI_MPI_RGN_AttachToChn(Handle, &stChn, &stChnAttr);
        if (HI_SUCCESS != s32Ret)
        {
                printf("HI_MPI_RGN_AttachToChn (%d to %d) failed with %#x!\n", Handle, VencGrp, s32Ret);
                return HI_FAILURE;
        }
        return HI_SUCCESS;
}


int OSD_Overlay_RGN_Display_English( RGN_HANDLE Handle, const unsigned char *pRgnContent )
{
        HI_S32 s32Ret = HI_FAILURE;
        BITMAP_S stBitmap;
        int ContentLen = 0;

        if (NULL == pRgnContent)
        {
                printf("[%s, %d] error, NULL pointer transfered.\n", __FUNCTION__, __LINE__); 
                return -1;
        }
        ContentLen = strlen(pRgnContent);

        int font_w = 8;
        int font_h = 16;
        if(Handle == 0) //english  :  16 x 32
        {
                font_w = 16;
                font_h = 32;
        }
        else
        {
                font_w = 8;
                font_h = 16;
        }

        /* HI_MPI_RGN_SetBitMap */
        unsigned char *BitMap = (unsigned char *) malloc(ContentLen*font_w*font_h*2); //RGB1555: 2     bytes(R:5 G:5 B:5).
        if (NULL == BitMap)
    {
                printf("malloc error with\n");  
                return HI_FAILURE;
        }
        memset( BitMap, '\0', ContentLen*font_w*font_h*2);

        if(font_w == 16)
                OSD_Draw_BitMap_ASC32( ContentLen, pRgnContent, BitMap );
        else
                OSD_Draw_BitMap_ASC16( ContentLen, pRgnContent, BitMap );

        stBitmap.enPixelFormat = PIXEL_FORMAT_RGB_1555;
        stBitmap.u32Width= font_w*ContentLen;
        stBitmap.u32Height    = font_h;
        stBitmap.pData = BitMap;

        s32Ret = HI_MPI_RGN_SetBitMap(Handle, &stBitmap);
        if (s32Ret != HI_SUCCESS)
        {
        printf("HI_MPI_RGN_SetBitMap failed with %x!\n", s32Ret);
                if (BitMap) 
                        free(BitMap);
                return HI_FAILURE;
         }

        if (BitMap) 
                free(BitMap);
        return 0;
}

HI_S32  Hi_LiteOs_OSD_Start(int channel , const char * text )
{
        static int firstflag = 1;
        if(firstflag)
        {
                firstflag = 0;
                init_font_libs();
        }
        RGN_HANDLE Handle = channel;
        VENC_GRP RgnVencChn = channel;

        OSD_Overlay_RGN_Handle_Init( Handle , RgnVencChn , strlen(text)); 
        OSD_Overlay_RGN_Display_English( Handle, text );
}

時間顯示成功;

HI_S32  Hi_LiteOs_OSD_Update(int channel , const char * text )
{
        OSD_Overlay_RGN_Display_English( channel, text );
}

調用並進行刷新時間

void * API_OSD_DisplayProcess(void * arg)
{
        char timebuf[32];
        Get_Sys_DayTime(timebuf);

        Hi_LiteOs_OSD_Start(0 , timebuf);
        Hi_LiteOs_OSD_Start(1 , timebuf);

        while(1)
        {
                Get_Sys_DayTime(timebuf);

                Hi_LiteOs_OSD_Update(0 , timebuf);
                Hi_LiteOs_OSD_Update(1 , timebuf);

               msleep(500);
        }
}


int Get_Sys_DayTime(unsigned char *pTime)
{
        if (NULL == pTime)
       {
               printf("[%s, %d] error, NULL pointer transfered.\n", __FUNCTION__, __LINE__); 
               return -1;
       }
       memset(pTime, '\0', sizeof(pTime));

       time_t rawtime;
       struct tm * timeinfo = NULL;
       char tmp[32] = {0};
       memset(timeinfo, '\0', sizeof(timeinfo));

       time ( &rawtime );
       timeinfo = localtime ( &rawtime );
       sprintf(tmp, "%04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year+1900, timeinfo->tm_mon+1,timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
       tmp[strlen(tmp)] = '\0';
       strcpy(pTime, tmp);
       return 0;
}

最後提一個問題:怎麼進行反色顯示?加入反色參數後OSD顯示則失敗?爲什麼?

注:附件是一個字體庫,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章