18217
- 收藏
- 点赞
- 分享
- 举报
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()就看到中文字了。
文件: HZ16Lib.c.tar.gz
下载
文件: HIFB_HZ.tar.gz
下载
文件: hifb.tar.gz
下载
我来回答
回答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. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
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
-
82014-10-30 10:05:47
-
42020-07-15 18:01:32
-
2016-10-29 17:33:09
-
2013-08-28 14:09:59
-
2015-08-08 13:26:41
-
142013-12-10 23:10:39
-
2008-10-02 20:15:51
-
2018-12-25 10:53:03
-
2019-01-18 20:50:29
-
2020-10-30 15:36:57
-
2019-12-16 09:36:27
-
2018-12-06 09:58:10
-
2008-08-07 19:18:16
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认