FBI 叠加自定义中文字库 做OSD用,或者叠加其他信息

 2 E币 
成为会员,免费下载资料
文件大小:191.87 KB 上传者:ngswfx 时间:2016-06-16 15:05:28 下载量:361
本帖最后由 ngswfx 于 2016-6-22 19:08 编辑

基本思路是:先把字库中的文字叠加到图片buffer上,叠加的时候如果能先得到背景的现在图片,最好了,就可以取反,这样任何光线环境都可以看清文字。
              然后再把这个图片以图形层的方式叠加到输出的主高清通道HD0上即可。
      中间生成文字图片的过程一次完成,可以在线程内执行,通常每秒处理一次即可。这样就可以实现OSD时间,各种文字信息的叠加。

我这边实现的是整个Debug调试信息的叠加,有20行。
   
由于代码在我的整个项目内,还没有搞清爽,所以摘主要关键的传上来大家参考。

其他的部分,参考SDK里面的那个叠加llogo图片的例子,注意把背景色都弄成黑色0x0即可,透出输出的视频了。

附件中,有汉字的字库,本文仅仅使用HZ16Lib.c即可,直接添加到自己的工程里就可以了。如果嫌弃自体小,还可以找24或者32的字库,基础图片可以小一倍,然后叠加时,对缓冲进行放大,要用到那个TDE处理一下缩放,这样效率高些。

我这边输出现在是1024*768,图片用的也是1024*768,所以没用TDE缩放,效率没问题,3520速度很快,我叠加了20行debug信息,都没事,每秒才处理1次。



[code]
    #define                                 USE_CHINESE_WORD_LIB_OSD
    #define                                        HZLIB_ZISE                16
    #define                                        UInt32        unsigned int
    #define                                        UInt16        unsigned short
    #define                                        UInt8        unsigned char
    #define                                        Int8        char
    #define                                        CLIP(a,b,c)    (((a)<(b))?(b):(((a)>(c))?(c):(a)))
    #define                                        UCLIPI(a,b)    CLIP(a,0,b)
    #define                                        HZLIB_ZISE                16
    #define                                        MUX(a,b,c)     ((a)?(b):(c))
    #define                                        INONZERO(a,b)     MUX(a,0,b)
    #define                                        UBYTESEL(a, n)        ( (a>>(8*n)) && 0xff)
    extern int                         g_real_HZ16_count;
    extern unsigned short HZ16_Space[];
    extern unsigned char         HZ16Lib[];

    #define MAX_SUPPORT_OSD_LINES                           4
    #define MAX_SUPPORT_OSD_CHAR_NUM_ONE_LINE  32   //一行最大支持的字符数目
    typedef struct IVHI_OSDEX
    {
            bool bUse;//用于高速判断用
            int  nDisplay;//哪个显示器,第几个输出通道,对于3520等,只有一个,所以为0
            int  nChl;//这个指的是某个显示通道,例如某个屏幕上的某个画面
            int  nSupportLines;//支持的行数
            int  nPosX[MAX_SUPPORT_OSD_LINES];//坐标
            int  nPosY[MAX_SUPPORT_OSD_LINES];
            int  nColor[MAX_SUPPORT_OSD_LINES];//字符颜色
            char strInf[MAX_SUPPORT_OSD_LINES][MAX_SUPPORT_OSD_CHAR_NUM_ONE_LINE];
    }IVHI_OSD;
    IVHI_OSD                                                                                        videoChlOsd[MAX_SUPPORT_DEC_VIDEO_CHL];
    int                                 fdOSD                                                        =0;
    char *                                pOSDYuv                                                        =NULL;
    HIFB_BUFFER_S                 stOsdCanvasBuf;
    HI_U16 *                        pOSDBuf=NULL;
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    #define BK_SCR_TRANS_COLOR_KEY                                                 0x01   //背景透明色

    void YtoRGB1555ToChar(unsigned char Y,unsigned char *rgb1555_0,unsigned char *rgb1555_1,int nColor)
    {
            if(Y>0x01){
                    Y=0xF0;
                    switch(nColor){
                    case 0://白色
                            *rgb1555_0=0xFF;
                            *rgb1555_1=0xFF;
                    break;
                    case 1://
                            *rgb1555_0=0x80;
                            *rgb1555_1=0x80;
                            break;
                    case 2:
                            *rgb1555_0=0xFF;
                            *rgb1555_1=0x80;
                            break;
                    case 3:
                            *rgb1555_0=0x14;
                            *rgb1555_1=0x14;
                            break;
                    }
                    return;
            }
    }

    void DrawOSD(unsigned char *buf, unsigned short *hzLib,int stride,int nColor)
    {
            int i, font;
            int        lumi;
            bool lum=true;
            int *p1 = (int *)(buf+(stride<<4));
            float mult_f = (float)(lum?0.20:1);
            mult_f=0.5;
            float mult_b = 1 - mult_f;
            int avglum = (buf[0] + buf[1] + buf[2] + buf[3] + buf[4] +buf[5] + buf[6] + buf[7] + buf[8] + buf[9] + buf[10] +buf[11] + buf[12] + buf[13] + buf[14] + buf[15])/16;
            if(!lum&&(avglum>145))
                    lumi = 0x1;
            else
                    lumi = 0xff;
            //1字节个亮度信息转为2字节1555
            int nD=2;//翻倍
            unsigned short Y;
            int nPos=0;
            for (i=0; i<16; i++) {
                    font = *hzLib ++;
                    ///////////////  这里修改一下,如果开始的buf里面是背景数据的话,通过调整上面的几个参数可以实现取反,主要是avglum的作用,它先计算开始的数据情况,然后如果背景亮度大于145就变黑,我没搞到视频数据,所以暂时没实现,这里有点乱
            //        for (int j=0; j<32; j++) {
            //                buf[j]=BK_SCR_TRANS_COLOR_KEY;
            //        }
                    nPos=0;//buf[0*nD]和buf[0*nD+1] 2个字节就是1555
                    Y   = (unsigned char)MUX(font&0x0080, lumi*mult_f+buf[0*nD]*mult_b, buf[0*nD]); //这个就是一个Y 变成1555 2个字节
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=1;
                    Y   = (unsigned char)MUX(font&0x0040, lumi*mult_f+buf[1*nD]*mult_b, buf[1*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=2;
                    Y   = (unsigned char)MUX(font&0x0020, lumi*mult_f+buf[2*nD]*mult_b, buf[2*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=3;
                    Y   = (unsigned char)MUX(font&0x0010, lumi*mult_f+buf[3*nD]*mult_b, buf[3*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=4;
                    Y   = (unsigned char)MUX(font&0x0008, lumi*mult_f+buf[4*nD]*mult_b, buf[4*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=5;
                    Y   = (unsigned char)MUX(font&0x0004, lumi*mult_f+buf[5*nD]*mult_b,buf[5*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=6;
                    Y   = (unsigned char)MUX(font&0x0002, lumi*mult_f+buf[6*nD]*mult_b,buf[6*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=7;
                    Y   = (unsigned char)MUX(font&0x0001, lumi*mult_f+buf[7*nD]*mult_b,buf[7*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=8;
                    Y   = (unsigned char)MUX(font&0x8000, lumi*mult_f+buf[8*nD]*mult_b,buf[8*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=9;
                    Y   = (unsigned char)MUX(font&0x4000, lumi*mult_f+buf[9*nD]*mult_b,buf[9*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=10;
                    Y = (unsigned char)MUX(font&0x2000, lumi*mult_f+buf[10*nD]*mult_b,  buf[10*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=11;
                    Y = (unsigned char)MUX(font&0x1000, lumi*mult_f+buf[11*nD]*mult_b,  buf[11*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=12;
                    Y = (unsigned char)MUX(font&0x0800, lumi*mult_f+buf[12*nD]*mult_b,  buf[12*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=13;
                    Y = (unsigned char)MUX(font&0x0400, lumi*mult_f+buf[13*nD]*mult_b,  buf[13*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=14;
                    Y = (unsigned char)MUX(font&0x0200, lumi*mult_f+buf[14*nD]*mult_b,  buf[14*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    nPos=15;
                    Y = (unsigned char)MUX(font&0x0100, lumi*mult_f+buf[15*nD]*mult_b,  buf[15*nD]);
                    YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
                    /////////////////////////////////////////
                    buf += stride*2;
            }

    }
    int        ShowOSD_MX(unsigned char *pBase, char *pStr, unsigned short x, unsigned short y,int width, int height,int nColor)
    {
            if(!pBase||!pStr||width<1||height<1||x>width||y>=height)
                    return 0;
            UInt32 nChar=0,wd=0,nOffset=0,nSize, l, r;
    #if defined USE_CHINESE_WORD_LIB_OSD
            Int8 q=3;
            Int8 w;
            Int8 *p=(char *)pStr;
            UInt8 *pHZLib=0;
            UInt8        *pp = (unsigned char *)p;
            pBase += width*2*y+x*2;
            while (*p) {
                    pp = (unsigned char *)p;
                    q = *p&0x80?(*p++)-161:2; // Get qu code
                    w=((*p++)&0x7f)-33; // Get wei code
                    if ((int)(nOffset = q*94+w) >= g_real_HZ16_count)
                            continue;
                    pHZLib = (HZ16Lib+(nOffset<<5));
                    if (q<10) {
                            l = UBYTESEL(HZ16_Space[nOffset],1);
                            r = UBYTESEL(HZ16_Space[nOffset],0);
                            nSize = HZLIB_ZISE-(l+r);
                    }
                    else {
                            nSize = HZLIB_ZISE;
                            l = r = 0;
                    }
                    if ((int)(x+wd+nSize)>width)
                            break;
                    DrawOSD(pBase+(wd+nChar)*2,(unsigned short *)pHZLib,width,nColor);
                    nChar++;
                    wd += 14;//12 自体间距
            }
    #endif
            return nChar;
    }

    void ShowSysWorkInfOSD()
    {
            if(!pOSDYuv)
                    return;
            //DebugInfEx(DBG_LEVEL1,"ShowSysWorkInfOSD in %d\n",GetTickCount());
            //CPU
            int nLineDisY=16;
            int nLineDisX=16;
            int nPosYAdd=20;
            SYSTEMTIME sysTime;
            GetLocalTime(&sysTime);
            char strINF[MAX_SUPPORT_OSD_DEBUG_INF_CHAR_NUM];
            memset(strINF,0,sizeof strINF);
            sprintf(strINF,"CPU:%d%",IVComInf_GetCpuPercent());
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //内存
            nLineDisY+=nPosYAdd;
            memset(strINF,0,sizeof strINF);
            sprintf(strINF,"MEM:%d%",IVComInf_GetMemPercent());
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //网络
            nLineDisY+=nPosYAdd;
            memset(strINF,0,sizeof strINF);
            char strNetCardName[32];
            char strIP[32];
            char strMask[32];
            char strGate[32];
            IVComInf_GetLocalNetPara(0,strNetCardName,strIP,strMask,strGate,NULL);
            sprintf(strINF,"NET:%d%",IVComInf_GetNetPercent(),strNetCardName,strIP,strMask,strGate);
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //硬盘 FLASH
            nLineDisY+=nPosYAdd;
            memset(strINF,0,sizeof strINF);
            sprintf(strINF,"DISK:16M (32M)");
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //通道总数
            nLineDisY+=nPosYAdd;
            memset(strINF,0,sizeof strINF);
            sprintf(strINF,"通道总数:4");
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //分割数
            nLineDisY+=nPosYAdd;
            memset(strINF,0,sizeof strINF);
            sprintf(strINF,"分割数:4");
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //时间
            nLineDisY+=nPosYAdd;
            memset(strINF,0,sizeof strINF);
            sprintf(strINF,"TIME:%04d-%02d-%02d/%02d:%02d:%02d-%d\n",sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute,sysTime.wSecond,GetTickCount());
            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
            //return ;
            //DEBUG 信息
            nLineDisY=nWndHeight-32;
            for(int i=0;i                     if(strlen(lastDebugString)>0){
                            memset(strINF,0,sizeof strINF);
                            sprintf(strINF,"%s",lastDebugString);
                            ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
                            nLineDisY-=nPosYAdd;
                    }
            }
    }

    /////////////////////////////////
    void Check_DeInitOSD()
    {
            if(!bCanUseOSD)
                    return;
            bCanUseOSD=false;
            if(fdOSD){
                    close(fdOSD);
                    fdOSD=0;
            }
            if(stOsdCanvasBuf.stCanvas.u32PhyAddr){
                    HI_MPI_SYS_MmzFree(stOsdCanvasBuf.stCanvas.u32PhyAddr, pOSDBuf);
                    stOsdCanvasBuf.stCanvas.u32PhyAddr=NULL;
                    pOSDBuf=NULL;
                    memset(&stOsdCanvasBuf,0,sizeof stOsdCanvasBuf);
            }
            if(pOSDYuv){
                    delete pOSDYuv;
                    pOSDYuv=NULL;
            }
    }
    int Check_InitOSD_ENV()
    {
            if(fdOSD!=0)
                    return fdOSD;
            ////////////////////////////////////////////////
            HI_S32 s32Ret =         HI_SUCCESS;
            HIFB_LAYER_INFO_S         stLayerInfo;
            HI_BOOL                         Show;
            HI_BOOL                         bCompress = HI_TRUE;
            HIFB_POINT_S stPoint = {0};
            struct fb_var_screeninfo stVarInfo;
            char file[12] = "/dev/fb0";
            HIFB_COLORKEY_S         stColorKey;
            HI_U32                                 maxW,maxH,u32Frm;//指的是屏幕宽度高度
            //////////////////////////////////////////
            strcpy(file, "/dev/fb0");
            fdOSD = open(file, O_RDWR, 0);
            if(fdOSD < 0)
                    return 0;
            if (ioctl(fdOSD, FBIOPUT_COMPRESSION_HIFB, &bCompress) < 0)
            {
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            stColorKey.bKeyEnable = HI_TRUE;
            stColorKey.u32Key = BK_SCR_TRANS_COLOR_KEY;
            if (ioctl(fdOSD, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)
            {
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            s32Ret = ioctl(fdOSD, FBIOGET_VSCREENINFO, &stVarInfo);
            if(s32Ret < 0){
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            if (ioctl(fdOSD, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0){
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            SAMPLE_COMM_VO_GetWH(VIDOE_OUT_RESOLUTION, &maxW,&maxH,&u32Frm);
            stVarInfo.xres = stVarInfo.xres_virtual = maxW;
            stVarInfo.yres = stVarInfo.yres_virtual = maxH;
            s32Ret = ioctl(fdOSD, FBIOPUT_VSCREENINFO, &stVarInfo);
            if(s32Ret < 0){
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            stLayerInfo.BufMode = HIFB_LAYER_BUF_ONE;
            stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE; // HIFB_LAYERMASK_BUFMODE HIFB_LAYERMASK_ANTIFLICKER_MODE
            s32Ret = ioctl(fdOSD, FBIOPUT_LAYER_INFO, &stLayerInfo);
            if(s32Ret < 0){
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            Show = HI_TRUE;
            if (ioctl(fdOSD, FBIOPUT_SHOW_HIFB, &Show) < 0){
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            if (HI_FAILURE == HI_MPI_SYS_MmzAlloc(&(stOsdCanvasBuf.stCanvas.u32PhyAddr), ((void**)&pOSDBuf),NULL, NULL, maxW*maxH*2)){
                    close(fdOSD);fdOSD=0;
                    return 0;
            }
            stOsdCanvasBuf.stCanvas.u32Height = maxH;
            stOsdCanvasBuf.stCanvas.u32Width = maxW;
            stOsdCanvasBuf.stCanvas.u32Pitch = maxW*2;
            stOsdCanvasBuf.stCanvas.enFmt = HIFB_FMT_ARGB1555;//HIFB_FMT_RGB565 HIFB_FMT_ARGB1555 HIFB_FMT_RGB888
            memset(pOSDBuf, BK_SCR_TRANS_COLOR_KEY, stOsdCanvasBuf.stCanvas.u32Pitch*stOsdCanvasBuf.stCanvas.u32Height);
            if(!pOSDYuv)
                    pOSDYuv=new char[maxW*maxH*2];
        return fdOSD;
    }[/code]


//////先调用Check_InitOSD_ENV()准备好OSD 的FBI环境,然后调用ShowSysWorkInfOSD()就看到中文字了。
展开
折叠
OSD
1578
评论
共 0 个
内容存在敏感词
    易百纳技术社区暂无数据
相关资料
关于作者
易百纳技术社区
ngswfx
贡献资料 40
易百纳技术社区 我上传的资料
登录查看
我赚取的积分
登录查看
我赚取的收益
登录查看
上传资料 赚取积分兑换E币
易百纳技术社区
删除原因
广告/SPAM
恶意灌水
违规内容
文不对题
重复发帖
置顶时间设置
结束时间
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-资料模块

审核失败

失败原因
备注
易百纳技术社区