海思3559平台OSD实时叠加的支持2区域RGN的配置
前言
位图的生成只是我们字符叠加的基础,具体表现就要靠对区域RGN的配置了
调试记录
现在距离移植成功osd也有一段时间了,所有所有的报错一时也想不起来太多,当时是在焦头烂额没有记录下全部,但是遇到错误一定要按照logmpp下的错误告警做出修改,再次感谢之前的转变
这部分的代码是参考手册写的,直接搬来肯定肯定肯定是跑不起来的!
报错1
HI_MPI_RGN_Create
出师不利,生成区域就开始报错,这个还是比较直接的根据提示修改画布数量
stRgnAttr.unAttr.stOverlay.u32CanvasNum = 1;
报错2
HI_MPI_RGN_AttachToChn实际上,创建通道的时候并不会对参数检查,真正的参数检查在这个函数进行
rgn_check_qp [Line]:1152 [Info]:protect_qp:127 err!
stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bQpDisable = HI_FALSE;
看样子关键字就是qp(我当时也不知道qp是啥)(Qp量化参数,反应压缩效果)那就解决qp的部分错误
报错3
stChnAttr.unChnAttr.stOverlayChn.enAttachDest =ATTACH_JPEG_MAIN;
可写可不写。最开始忘记什么原因导致的HI_MPI_RGN_AttachToChn报了错,当时也是根据log的提示表示dest值不对,提示需要修改此处值。后来不知道为什么删了也没有影响,留作疑问
报错4
空指针错误
这个错误就是没有在设置画布之前生成位图导致的
报错汇总5
一切都好像设置对了之后还是没有区域叠加怎么办?
检查编码通道是否正确?位图是否生成正确?宽高XY的值是否都设置正确了?
改进
此外,关于w和h的值,必须是偶数。但是字库导出的位图不可能每次都刚好,也是在其他博主处看到的字体大小无法调节,调节后参数错误的,非常简单,检查一下手动部位偶数即可。更不能随意设置,有可能会遇到明明水印文件字体是常规,不是倾斜的,但在视频上显示倾斜,更不用说还显示不全。
if (stBitmap.u32Width % 2 != 0)
{
stBitmap.u32Width += 1;
}
if (stBitmap.u32Height % 2 != 0)
{
stBitmap.u32Height += 1;
}
printf ("stBitmap.u32Width is %d ,stBitmap.u32Height is %d\n",stBitmap.u32Width,stBitmap.u32Height);
stRgnAttr.unAttr.stOverlay.stSize.u32Width = stBitmap.u32Width;//240; /**区域宽**/
stRgnAttr.unAttr.stOverlay.stSize.u32Height = stBitmap.u32Height;//192; /**区域高**/
同样XY的值是需要16的倍数,但是XY的值相对是比较灵活的,我们自己按照心情手动配置就好了
透明度的解决办法暂时还没有思路,后续补充
代码框架如下
区域设置函数RGN_AddOsdToVenc
/*
*描述 :用于将视频文件添加时间水印
*参数 :无
*返回值:OverlayHandle
*注意 :参数在HI_MPI_RGN_Create并不做检查,只有在HI_MPI_RGN_AttachToChn的时候才会报出相应的错
*/
HI_S32 RGN_AddOsdToVenc(HI_VOID)
{
HI_S32 s32Ret;
RGN_ATTR_S stRgnAttr;
RGN_CHN_ATTR_S stChnAttr;
MPP_CHN_S stChn;
RGN_HANDLE OverlayHandle;
// RGN_CANVAS_INFO_S stCanvasInfo;
OverlayHandle =0;
stChn.enModId = HI_ID_VENC; /**模块号**///HI_ID_VPSS HI_ID_VENC
stChn.s32DevId = 0; /**设备号**/
stChn.s32ChnId = 1; /**通道号**/
/**创建区域**/
sleep(2);//等待位图生成
stRgnAttr.unAttr.stOverlay.u32CanvasNum = 2;
stRgnAttr.enType = OVERLAY_RGN; /**区域类型:叠加**/
stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_ARGB_1555; /**像素格式**///PIXEL_FORMAT_BGR_565 PIXEL_FORMAT_ARGB_1555
if (stBitmap.u32Width % 2 != 0)
{
stBitmap.u32Width += 1;
}
if (stBitmap.u32Height % 2 != 0)
{
stBitmap.u32Height += 1;
}
printf ("stBitmap.u32Width is %d ,stBitmap.u32Height is %d\n",stBitmap.u32Width,stBitmap.u32Height);
stRgnAttr.unAttr.stOverlay.stSize.u32Width = stBitmap.u32Width;//240; /**区域宽**/
stRgnAttr.unAttr.stOverlay.stSize.u32Height = stBitmap.u32Height;//192; /**区域高**/
stRgnAttr.unAttr.stOverlay.u32BgColor = 0xffffff00;//0x00007c00; /**区域背景颜色**/
s32Ret = HI_MPI_RGN_Create(OverlayHandle, &stRgnAttr);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("RGN create failed: %#x\n", s32Ret);
}
/**将区域叠加到通道**/
/**设置叠加区域的通道显示属性**/
stChnAttr.bShow = HI_TRUE;
stChnAttr.enType = OVERLAY_RGN;
stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 640;//240;
stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 320;//192;
stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 128;
stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 80;
stChnAttr.unChnAttr.stOverlayChn.u32Layer = OverlayHandle;
/**设置QP属性**/
stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = HI_FALSE;
stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp = 0;
stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bQpDisable = HI_FALSE;
/**定义 OSD 反色相关属性**/
/**单元反色区域,反色处理的基本单元,[16, 64],需 16 对齐**/
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16;
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width = 16;
/**亮度阈值,取值范围:[0, 255]**/
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 128;//128
/**OSD 反色触发模式**/
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod = LESSTHAN_LUM_THRESH;
/**OSD 反色开关。overlay不支持反色**/
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn = HI_FALSE;
stChnAttr.unChnAttr.stOverlayChn.enAttachDest =ATTACH_JPEG_MAIN;
OverlayHandle =0;
s32Ret = HI_MPI_RGN_AttachToChn(OverlayHandle, &stChn, &stChnAttr);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_RGN_AttachToChn: %#x\n", s32Ret);
}
stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555;
// stBitmap.u32Height = OVERLAY_H;
// stBitmap.u32Width = OVERLAY_W;
s32Ret = HI_MPI_RGN_SetBitMap(OverlayHandle,&stBitmap);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
}
memset(stBitmap.pData, 0, sizeof(BITMAP_S));
// s32Ret = HI_MPI_RGN_GetCanvasInfo(OverlayHandle,&stCanvasInfo);
// s32Ret = HI_MPI_RGN_DetachFromChn(OverlayHandle, &stChn);//最后用户可以将该区域从通道中撤出(非必须操作),再销毁区域。
// if(s32Ret != HI_SUCCESS)
// {
// SAMPLE_PRT("HI_MPI_RGN_DetachFromChn: %#x\n", s32Ret);
// }
// s32Ret = HI_MPI_RGN_Destroy(OverlayHandle);
// if(s32Ret != HI_SUCCESS)
// {
// SAMPLE_PRT("RGN create failed: %#x\n", s32Ret);
// }
return 0;
}
实时更新
开个线程每秒更新画布
/*
*描述 :用于osd 字体bmp图像生成
*参数 :NULL
*返回值:无
*注意 :需要加载字体ttf才能使用,否则会报段错误
*/
HI_VOID *bitmap_update(HI_VOID*arg)
{
RGN_HANDLE OverlayHandle = 0;
HI_S32 s32Ret;
// time_t now;
// struct tm *ptm;
// char timestr[OSD_LENGTH] = {0};
while(1)
{
sleep(1);
HI_MPI_RGN_UpdateCanvas(0);
s32Ret = HI_MPI_RGN_SetBitMap(OverlayHandle,&stBitmap);//s32Ret 为RGN_HANDLE OverlayHandle
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
}
memset(stBitmap.pData, 0, sizeof(BITMAP_S));
}
return 0;
}
每秒生成新的位图
画布结构体BITMAP_S设置成全局的,方便更新
/*
*描述 :用于将想填写的内容生成位图 用于pthread osd_create_task
*参数 :pu8Str u8指针,传字符串
*返回值:成功返回0
*注意 :无
*/
HI_S32 string_to_bmp(char *pu8Str)
{
SDL_PixelFormat *fmt;
TTF_Font *font;
SDL_Surface *text, *temp;
if (TTF_Init() < 0 )
{
fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
SDL_Quit();
}
font = TTF_OpenFont(FONT_PATH, 45);
if ( font == NULL )
{
fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());
}
SDL_Color forecol = { 0xff, 0xff, 0xff, 0xff };
text = TTF_RenderUTF8_Solid(font, pu8Str, forecol);
fmt = (SDL_PixelFormat*)malloc(sizeof(SDL_PixelFormat));
memset(fmt,0,sizeof(SDL_PixelFormat));
fmt->BitsPerPixel = 16;
fmt->BytesPerPixel = 2;
fmt->colorkey = 0xffffffff;
fmt->alpha = 0xff;
temp = SDL_ConvertSurface(text,fmt,0);
// SDL_Surface *osd_test = SDL_ConvertSurface(text, fmt, 0);
// printf ("w is %d ,h is %d\n",temp->w,temp->h);
stBitmap.pData = malloc(2*(temp->w)*(temp->h));
if(stBitmap.pData == NULL)
{
printf("stBitmap.pData faided\r\n");
}
memset(stBitmap.pData, 0, sizeof(BITMAP_S));
memcpy(stBitmap.pData, temp->pixels, (2*(temp->w)*(temp->h)));
stBitmap.u32Width = temp->w;
stBitmap.u32Height = temp->h;
char savename[20] = {0};
snprintf(savename,20,"./osd/now_time.bmp");
// printf("savename = %s\n",savename);
SDL_SaveBMP(temp, savename);
free(fmt);
// memset(stBitmap.pData, 0, sizeof(BITMAP_S));
SDL_FreeSurface(text);
SDL_FreeSurface(temp);
TTF_CloseFont(font);
TTF_Quit();
return 0;
}
/*
*描述 :用于osd 字体bmp图像生成
*参数 :NULL
*返回值:无
*注意 :需要加载字体ttf才能使用,否则会报段错误
*/
HI_VOID *osd_ttf_task(HI_VOID*arg)
{
RGN_HANDLE OverlayHandle = 0;
HI_S32 s32Ret;
time_t now;
struct tm *ptm;
char timestr[OSD_LENGTH] = {0};
while(1)
{
usleep(1000000);
time(&now);
ptm = localtime(&now);
snprintf(timestr,100,"时间:%d-%02d-%02d %02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
string_to_bmp(timestr);
HI_MPI_RGN_UpdateCanvas(OverlayHandle);
s32Ret = HI_MPI_RGN_SetBitMap(OverlayHandle,&stBitmap);//s32Ret 为RGN_HANDLE OverlayHandle
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
}
memset(stBitmap.pData, 0, sizeof(BITMAP_S));
memset(timestr,0,OSD_LENGTH);
}
return 0;
}
结果
- 分享
- 举报
-
wizard 2024-10-14 16:50:45回复 举报问一下 stBitmap的值是怎么获取的 上面看没有定义
-
小小小小 回复 wizard 2024-10-22 17:06:31回复 举报请问一下,这个叠加的时间水印上的时间,是可以实时更新显示的吗
-
-
浏览量:1729次2024-01-02 16:35:00
-
浏览量:5673次2020-08-26 14:15:06
-
浏览量:1009次2024-01-19 17:52:40
-
浏览量:717次2024-01-11 15:05:58
-
浏览量:1621次2020-08-10 19:19:56
-
浏览量:1244次2024-01-19 17:57:59
-
浏览量:14117次2019-09-21 19:14:57
-
浏览量:3193次2020-08-17 19:55:50
-
浏览量:1511次2023-07-30 08:53:58
-
浏览量:2443次2020-08-04 20:15:40
-
浏览量:2688次2020-08-04 20:12:26
-
浏览量:1682次2023-10-12 16:48:04
-
浏览量:6749次2020-09-27 14:15:09
-
浏览量:13319次2020-11-14 10:57:08
-
浏览量:2344次2020-09-21 19:06:02
-
浏览量:3554次2020-07-27 15:12:15
-
浏览量:1268次2023-10-12 14:39:21
-
浏览量:2182次2020-08-05 21:02:35
-
浏览量:3513次2020-07-30 11:57:30
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
Tony
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明