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()就看到中文字了。
基本思路是:先把字库中的文字叠加到图片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
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()就看到中文字了。
展开》
折叠》