18296
- 收藏
- 点赞
- 分享
- 举报
FBI 叠加自定义中文字库 做OSD用,或者叠加其他信息
本帖最后由 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()就看到中文字了。

下载

下载

下载
我来回答
回答69个
时间排序
认可量排序
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片
相关问答
-
422015-09-15 08:51:04
-
2013-11-25 21:16:52
-
22020-04-11 20:34:59
-
2013-08-28 10:33:44
-
2019-01-18 19:10:29
-
2013-12-19 21:51:34
-
42020-07-15 18:01:32
-
82014-10-30 10:05:47
-
2016-10-29 17:33:09
-
2015-08-08 13:26:41
-
142013-12-10 23:10:39
-
2020-10-30 15:36:57
-
2018-12-25 10:53:03
-
2018-12-06 09:58:10
-
2019-01-18 20:50:29
-
2013-08-28 14:09:59
-
2020-07-07 17:58:02
-
2018-08-17 17:24:46
-
2008-10-02 20:15:51
无更多相似问答 去提问

点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
53519dv500接lvds的sensor mn34120,图像出现很多竖线,sensor板接以前的3519v101没问题
-
103403外接hdmi口1024*600显示屏报错
-
5SS928点DC camera的6946,全屏紫色
-
5hi3519 的 网络传输的MTU值可以修改到比1500大嘛?
-
10WS73V100星闪扫描不到设备sle
-
5SS928/SD3403 录像失败 venc stream time out, exit thread; venc 2 stream buffer is full
-
10Hi3516DV500无法运行PQTool软件
-
10君正T23+1084带TF卡插卡(给该主板适配TF卡驱动,电机驱动,适配GPIO)
-
5Hi3536A从vpss获取1080分辨率的yuv数据异常
-
10谁有RV1126 最新版本SDK卖吗?
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认