海思OSD

news/2025/1/11 10:02:39/

目前我要在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显示则失败?为什么?

注:附件是一个字体库,


http://www.ppmy.cn/news/494988.html

相关文章

音视频OSD完全教程

目录 前言OSD 介绍学习路线图像 字符编码基础知识ASCII点阵字库叠加信息相关操作GB2312点阵字库UNICODE UTF-8矢量字库 前言 感谢海康高级工程师宇哥和安霸高级工程师杰哥对我的无私帮助 现有的博客内容都是抄来抄去&#xff0c;不成体系 希望我整理的内容能够对行业有所帮助…

MiniOSD DIY记

最近迷上了航模&#xff0c;研究了很多东西&#xff0c;感觉路走的长了还是适当要停下脚步休息下总结下。 这次DIY的是一块OSD设备&#xff0c;主要用于航模图传的叠加显示&#xff0c;原理也很简单就是atmel atmega328pMAX7456芯片&#xff0c;网上卖的成品基本上都是一个原理…

ceph 删除 osd

# ceph --version ceph version 12.2.13 luminous (stable)# ceph osd tree 0 hdd 7.27739 osd.0 up 1.00000 1.00000# ceph osd out 0 marked out osd.0. # ceph osd tree0 hdd 7.27739 osd.0 up 0 1.00000等待数据迁移 # ceph -w…

OSD实现原理介绍

OSD的主要实现方法和类型 目前有两种主要的OSD实现方法&#xff1a;外部OSD发生器与视频处理器间的叠加合成&#xff1b;视频处理器内部 支持OSD&#xff0c;直接在视频缓存内部叠加OSD信息。 外部OSD发生器与视频处理器间的叠加合成的实现原理是&#xff1a;由一个MCU内建的字…

QT 视频窗口 OSD 使用详解

QT 视频窗口 OSD 效果展示 悬浮 FormSensorPannel 设置 在构造函数中 1》//设置 Qt::FramelessWindowHint|Qt::Tool Qt::Tool 表示小部件是一个工具窗口。 工具窗口通常是一个小窗口&#xff0c;具有比通常的标题栏和装饰更小的窗口&#xff0c;通常用于工具按钮的集合。 如…

ceph osd学习小结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ceph osd学习小结 前言一、osd是什么&#xff1f;二、osd的特点 二、osd的状态查看三、osd的故障与修复 前言 ceph是一种后端文件存储集群。相对于hdfs等传统文件系统&#…

对象存储osd以及存储分类

一、三种存储 首先我们来看一看什么是对象存储&#xff1f;目前&#xff0c;独立的存储形态有三种&#xff1a;块存储、文件存储&#xff0c;以及新出现的对象存储。块存储我们简单的理解就是一块一块的硬盘&#xff0c;直接挂载在主机上&#xff0c;在主机上我们能够看到的就…

问题:宇视摄像机OSD如何配置

答案&#xff1a; 说明&#xff1a;OSD 是指与视频图像同时叠加显示在屏幕上的字符信息。OSD 内容包括时间自定义等多种信息。 不同产品型号支持的OSD 操作会有所不同&#xff0c;请以实际web 界面显示为准&#xff1b;部分设备支持双通道功能&#xff0c;根据实际需求分别设置…