OSD时间显示到输出设备

 2 E币 
成为会员,免费下载资料
文件大小:191.87 KB 上传者:ngswfx 时间:2016-03-10 23:44:53 下载量:50
本帖最后由 ngswfx 于 2016-3-11 00:00 编辑

基本思想是:先把字库中的文字叠加到图片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]
展开
折叠
2516
评论
共 0 个
内容存在敏感词
    易百纳技术社区暂无数据
相关资料
关于作者
易百纳技术社区
ngswfx
贡献资料 40
易百纳技术社区 我上传的资料
登录查看
我赚取的积分
登录查看
我赚取的收益
登录查看
上传资料 赚取积分兑换E币
易百纳技术社区
删除原因
广告/SPAM
恶意灌水
违规内容
文不对题
重复发帖
置顶时间设置
结束时间
举报反馈

举报类型

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

详细说明

审核成功

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

审核失败

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