love_lin

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin  发布于  2016-04-05 11:29:44
采纳率 0%
22个问答
20783

【已解决】海思OSD时间戳

 
本帖最后由 love_lin 于 2016-5-31 08:57 编辑

有谁做海思OSD时间戳遇到如下问题?求大神帮忙!!谢谢
时间显示有时正常,有时最后的数字跑前面去了,而且字体是斜的[img]C:\Users\Administrator\Desktop\QQ图片20160405113400[/img][img]C:\Users\Administrator\Desktop\QQ图片20160405113409[/img]
我来回答
回答41个
时间排序
认可量排序

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-05 11:30:46
认可0
[img]C:\Users\Administrator\Desktop\QQ图片20160405113400C[/img]

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-04-05 12:46:15
认可0
两个现象
1.最后的数字跑前面去了
2.字体是斜的

一种情况是OSD原始buffer中就是有问题的, 比如制作OSD时是一个字符一个字符加到buffer中去,如果添加的字符x坐标(当然这里还要注意格式)大于buffer的stride,就会出现后面的字符跑到前面去

一种情况是OSD buffer里面实际内容的宽度大于了 RGN设置的stride导致,通常大的不多(比如2)会看到字体时斜的,大的比较多会看到的OSD是全部斜条纹

当然上面制作时也会出现斜纹的情况,通常是一行一行拷贝数据又没有注意起始地址时容易出现

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-04-05 14:53:48
认可0
楼主 您好 近期我也在弄3516的osd功能 能方便看下您的配置osd的各函数及参数配置么 可以的话麻烦给个分享谢谢啦

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-05 18:40:32
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=27948&ptid=10879]zhuangweiye 发表于 2016-4-5 12:46[/url]
两个现象
1.最后的数字跑前面去了
2.字体是斜的
[/quote]

你好,我目前使用SDL库显示时间戳的,如果我用有些字库是不会出现这两个问题的,但是用我自己生成的和某些字库也是会的,奇怪的的是我用SDL_SaveBMP()函数生成成图片,是完全正常的。请问你是怎me实现时间戳的?能给点经验吗?

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-05 18:43:46
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=27955&ptid=10879]localhost 发表于 2016-4-5 14:53[/url]
楼主 您好 近期我也在弄3516的osd功能 能方便看下您的配置osd的各函数及参数配置么 可以的话麻烦给个分享谢 ...[/quote]

我还没完全弄好,我这边也遇到了问题,你可先参考下http://blog.sina.com.cn/s/blog_8795b0970101j5fo.html,

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-04-06 08:29:37
认可0
建议先看一下以前的帖子
关于Hi3516A做OSD的问题
[url]http://www.ebaina.com/bbs/forum.php?mod=viewthread&tid=10385&fromuid=12370[/url]
(出处: 易百纳论坛)


如果save下来的图没有问题, 那么就很简单了, 得到原始OSD的宽度, 设到RGN上去,就好了,当然这里要注意的对齐的问题,

开始调试可以这样做, 先开一个buffer(可以大一点),用于RGN的显示用, 把生成的OSD buffer(开始可以用生成的图片来加载,)一行一行拷贝到RGN的buffer中的每一行, 每行拷贝时开始可以少拷贝一点数据
这样搞成一个模板,不断测试各种拷贝数据的大小,就会对图像数据的摆放及显示有更深的理解
然后就可以考虑实现OSD背景透明的功能
最后再考虑整体上内存使用效率,减少内存拷贝等问题

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 10:24:11
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=27973&ptid=10879]zhuangweiye 发表于 2016-4-6 08:29[/url]
建议先看一下以前的帖子
关于Hi3516A做OSD的问题
http://www.ebaina.com/bbs/forum.php?mod=viewthread&t ...[/quote]

你好,首先谢谢您的耐心回答。
我贴下我显示位图的接口代码,然后,我看了[url]http://www.ebaina.com/bbs/forum.[/url] ... 5&fromuid=12370这个论坛,它是把他生成图片,然后在通过加载图片显示位图的,这样应该不好吧。
[code]HI_S32 SDK_COMM_VIDEO_LoadOSDBmp(const char *ptxt,HI_S32 handle)
{
        SDL_Surface *sdl_txtsurface = NULL;
        SDL_Surface *sdl_tmpsurface = NULL;
        BITMAP_S stBitmap;
        HI_S32 s32Ret = HI_SUCCESS;
       
        //osd text color 1:R 2:G 3:B 4:no use
        SDL_Color forecol= { 0xff, 0xff, 0xff, 0 };

        sdl_txtsurface = TTF_RenderUTF8_Solid(stFont, ptxt, forecol);

        //save bmp to file
        //SDL_SaveBMP(sdl_txtsurface, "osd_cloudtop.bmp");

        sdl_tmpsurface = SDL_CreateRGBSurface(SDL_SWSURFACE,sdl_txtsurface->w, sdl_txtsurface->h, 16,\
                        0x00000000, 0x00000000, 0x00000000,0x00000000);
        SDL_Rect bounds;
        if (sdl_tmpsurface != NULL)
        {
                bounds.x = 0;
                bounds.y = 0;
                bounds.w = sdl_txtsurface->w;
                bounds.h = sdl_txtsurface->h;
                if (SDL_LowerBlit(sdl_txtsurface, &bounds, sdl_tmpsurface, &bounds) < 0) {
                        SDL_FreeSurface(sdl_txtsurface);
                        SDL_SetError("Couldn't convert image to 16 bpp");
                        sdl_txtsurface = NULL;
                        return HI_FAILURE;
                }
        }else{
                SAMPLE_PRT("sdl creat RGB surface failed\n");
                return HI_FAILURE;
        }

        stBitmap.pData        = malloc (2*sdl_tmpsurface->w*sdl_tmpsurface->h);
        if ( stBitmap.pData == NULL ) {
                SAMPLE_PRT( stderr, "\ndynamic memory allocation failed\n" );
        }

        stBitmap.u32Width = sdl_tmpsurface->w;
        stBitmap.u32Height = sdl_tmpsurface->h;
        stBitmap.pData= sdl_tmpsurface->pixels;
        stBitmap.enPixelFormat= PIXEL_FORMAT_RGB_1555 ;

        //SDL_SaveBMP(sdl_tmpsurface, "hi_osd.bmp");
    s32Ret = HI_MPI_RGN_SetBitMap(handle,&stBitmap);
    if(s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
               
    }
    if (NULL != stBitmap.pData)
    {
        free(stBitmap.pData);
        stBitmap.pData = NULL;
    }
       
        //SDL_FreeSurface(sdl_tmpsurface);
        //SDL_FreeSurface(sdl_txtsurface);
        return HI_SUCCESS;
}[/code]

我这边如果通过此函数SDL_SaveBMP(sdl_tmpsurface, "hi_osd.bmp")生成出来的图片是完全正常的。
但是setbipmap之后就有问题了。而且如果使用simhei.ttf这个字库太大了,所以就自己生成了字库。
而且我在时venc通道创建区域的,创建区域的大小还根据当前的分辨率来设置大小,不然不同分辨率的OSD小时效果很奇怪。以下是我的代码,请帮我看看哪有问题。[code]I_S32 SAMPLE_RGN_CreateOverlayForVenc(VIDEO_PIC_PARAM videoPicParam, HI_S32 wSize)
{
    HI_S32 i;
    HI_S32 s32Ret;
    MPP_CHN_S stChn;
        RGN_ATTR_S stRgnAttr;
    RGN_CHN_ATTR_S stChnAttr;

        SIZE_S picSize ;
        s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm_sample,videoPicParam.enSize, &picSize);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("get picture size failed!\ninit osd mudule failed\n");
                return s32Ret;
    }
    /* Add cover to vpss group */
    stChn.enModId  = HI_ID_VENC;
    stChn.s32DevId = 0;
    stChn.s32ChnId = VENC_CHN_VIDEO;
       
    for (i = 0; i < 2; i++)
    {
        stRgnAttr.enType = OVERLAY_RGN;
        stRgnAttr.unAttr.stOverlay.enPixelFmt       = PIXEL_FORMAT_RGB_1555;
        stRgnAttr.unAttr.stOverlay.stSize.u32Width  = 15*wSize;
        stRgnAttr.unAttr.stOverlay.stSize.u32Height = wSize*1.2;
        stRgnAttr.unAttr.stOverlay.u32BgColor       = 0x00000000;

        if (1 == i % 2)
        {
            stRgnAttr.unAttr.stOverlay.stSize.u32Width  = 25*wSize;
            stRgnAttr.unAttr.stOverlay.stSize.u32Height = wSize*1.2;
            stRgnAttr.unAttr.stOverlay.u32BgColor       = 0x00000000;
        }

        s32Ret = HI_MPI_RGN_Create(i, &stRgnAttr);
        if (s32Ret != HI_SUCCESS)
        {
            SAMPLE_PRT("HI_MPI_RGN_Create failed! s32Ret: 0x%x.\n", s32Ret);
            return s32Ret;
        }

        stChnAttr.bShow  = HI_TRUE;
        stChnAttr.enType = OVERLAY_RGN;
        stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 8;
        stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 18;
        stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha   = 0;//region bg alpha
        stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha   = 128;//text bg alpha
        stChnAttr.unChnAttr.stOverlayChn.u32Layer     = i;

        stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = HI_FALSE;
        stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp  = 0;

        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width  = 16;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 128;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod     = LESSTHAN_LUM_THRESH;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn    = HI_FALSE;
        if (1 == i % 2)
        {
            stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = (picSize.u32Width - 18*wSize);
            stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 18;
                        stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha   = 0;//region bg alpha
                stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha   = 128;//text bg alpha
                        stChnAttr.unChnAttr.stOverlayChn.u32Layer     = i;
        }
        s32Ret = HI_MPI_RGN_AttachToChn(i, &stChn, &stChnAttr);
        if (s32Ret != HI_SUCCESS)
        {
                        SAMPLE_PRT("rgn attach err\n");
           // AMPLE_RGN_NOT_PASS(s32Ret);
        }
    }

    return HI_SUCCESS;

}

HI_S32 SDK_COMM_VIDEO_InitOSDModule(VIDEO_PIC_PARAM videoPicParam)
{
        HI_S32 s32Ret = HI_SUCCESS;
        HI_S32 wordSize ;
        isOSDFlg = HI_TRUE;

       
        switch(videoPicParam.enSize){
                case PIC_QVGA:
                        wordSize = 12;
                        break;
                case PIC_VGA:
                        wordSize = 16;
                        break;
                case PIC_XGA:
                        wordSize = 16;
                        break;
                case PIC_HD720:
                        wordSize = 24;
                        break;
                case PIC_HD1080:
                        wordSize = 32;
                        break;
                default:
                        SAMPLE_PRT("video size err,not support osd time\n");
                        break;
        }

    s32Ret = SAMPLE_RGN_CreateOverlayForVenc(videoPicParam,wordSize);
        if (HI_SUCCESS != s32Ret)
        {
                SAMPLE_PRT("SAMPLE_RGN_CreateOverlayForVenc failed! s32Ret: 0x%x.\n", s32Ret);
                return s32Ret;
        }
       
        if ( TTF_Init() < 0 )
        {
                fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
                SDL_Quit();
                return HI_FAILURE;
        }
        stFont = TTF_OpenFont("JDTUAN.TTF",wordSize);
        if ( stFont == NULL )
        {
                SAMPLE_PRT("ttf open err\n");
                return HI_FAILURE;
        }
        return HI_SUCCESS;
}[/code]

以下是我调用测试代码:
        if(HI_SUCCESS != SDK_COMM_VIDEO_InitOSDModule(videoPicParam))
        {
                printf("init OSD failed\n");
        }else{
                if(HI_SUCCESS != SDK_COMM_VIDEO_LoadOSDBmp("CTIPCam",0))
                {
                        printf("osd load bmp failed\n");
                }
                SAMPLE_LIBVIDEO_SetTimerOSD();
        }

我是分线程来处理时间戳的:

/**********************************************
*
*  Name:        SAMPLE_LIBVIDEO_getLocalTime
*  Description:  get local time
*  Param:       
*  Return:
*
*********************************************/
static void SAMPLE_LIBVIDEO_getLocalTime (char *pstr)
{
        time_t timep;
        struct tm *p;
        time(&timep);
        p=localtime(&timep); /*get local time*/

        snprintf(pstr,32,"%d-%d-%d %d:%d:%d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,    \
                        p->tm_hour,p->tm_min,p->tm_sec);
        return ;
}/*End of SAMPLE_LIBVIDEO_getLocalTime*/

/**********************************************
*
*  Name:        SAMPLE_LIBVIDEO_setTimerOSDProc
*  Description:  set timer osd
*  Param:       
*  Return:
*
*********************************************/
static HI_VOID* SAMPLE_LIBVIDEO_setTimerOSDProc (HI_VOID* p)
{
        HI_BOOL *pStartFlg;
        pStartFlg = (HI_BOOL*)p;
        char str[32] = {0};
        while(*pStartFlg){
                SAMPLE_LIBVIDEO_getLocalTime(str);
                printf("---->%s\n",str);
                if(HI_SUCCESS != SDK_COMM_VIDEO_LoadOSDBmp(str,1))
                {
                        printf("osd timer load bmp failed\n");
                }
                sleep(1);
        }
        SDK_COMM_VIDEO_OSDDestory();
        return NULL;
}/*End of SAMPLE_LIBVIDEO_setTimerOSDProc*/

/**********************************************
*
*  Name:        SAMPLE_LIBVIDEO_SetTimerOSD
*  Description:  creat to set timer osd
*  Param:       
*  Return:
*
*********************************************/
HI_S32 SAMPLE_LIBVIDEO_SetTimerOSD ()
{

        vOSDFlg = HI_TRUE;
    return pthread_create(&osdPid, 0, SAMPLE_LIBVIDEO_setTimerOSDProc, &vOSDFlg);
}/*End of SAMPLE_LIBVIDEO_SetTimerOSD*/

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-04-06 10:52:45
认可0


36.        stBitmap.pData        = malloc (2*sdl_tmpsurface->w*sdl_tmpsurface->h);
37.        if ( stBitmap.pData == NULL ) {
38.                SAMPLE_PRT( stderr, "\ndynamic memory allocation failed\n" );
39.        }
40.
41.        stBitmap.u32Width = sdl_tmpsurface->w;
42.        stBitmap.u32Height = sdl_tmpsurface->h;
43.        stBitmap.pData= sdl_tmpsurface->pixels;
44.        stBitmap.enPixelFormat= PIXEL_FORMAT_RGB_1555 ;

A. 以下是SDL_Surface的结构请注意成员pitch

1 typedef struct SDL_Surface {
   2     Uint32 flags;                           /* Read-only */
   3     SDL_PixelFormat *format;                /* Read-only */
   4     int w, h;                               /* Read-only */
   5     Uint16 pitch;                           /* Read-only */
   6     void *pixels;                           /* Read-write */
   7     SDL_Rect clip_rect;                     /* Read-only */
   8     int refcount;                           /* Read-mostly */
   9
  10   /* This structure also contains private fields not shown here */
  11 } SDL_Surface;

意思就是说 sdl_tmpsurface->pixels这块buffer里面的数据的放法是每行宽度是pitch*2个bytes,里面放了w个像素,每个像素2bytes,
按楼主的设置,如果w=pitch,那么显示出来的OSD是没有问题的,如果w!=pitch,那么显示就有问题了(会出现后面的字跑到前面去,斜纹等等)

把41行改成
stBitmap.u32Width = sdl_tmpsurface->pitch;
应该会好

另外,
1.stRgnAttr.unAttr.stOverlay.stSize.u32Height = wSize*1.2 用浮点乘法这样不太好, 也没有保证2对齐

2.楼主已经把stBitmap.pData= sdl_tmpsurface->pixels了, 前面就不要再malloc了,不然内存就泄漏了,时间一长程序就要out of memory了

cfgrpg

0个粉丝

7

问答

0

专栏

1

资料

cfgrpg 2016-04-06 14:03:09
认可0
本帖最后由 cfgrpg 于 2016-4-6 14:14 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=27981&ptid=10879]love_lin 发表于 2016-4-6 10:24[/url]
你好,首先谢谢您的耐心回答。
我贴下我显示位图的接口代码,然后,我看了[url]http://www.ebaina.com/bbs/fo[/url] ...[/quote]

[code]static void SAMPLE_LIBVIDEO_getLocalTime (char *pstr)
{
        time_t timep;
        struct tm *p;
        time(&timep);
        p=localtime(&timep); /*get local time*/

        snprintf(pstr,32,"  %d-%d-%d %d:%d:%d  ",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,    \
                        p->tm_hour,p->tm_min,p->tm_sec);
        return ;
}/*End of SAMPLE_LIBVIDEO_getLocalTime*/[/code]

主要是因为你的字库不是等宽字体导致的,可以有如下解决办法:
1、snprintf的字符串前后各加2个空格试一下,肯定好了,弄好了共享下代码吧。
2、换等宽的ttf字库。

共享一个支持中文的小型等宽的ttf字库

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 15:21:06
认可0
本帖最后由 love_lin 于 2016-4-6 15:24 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=27991&ptid=10879]cfgrpg 发表于 2016-4-6 14:03[/url]
主要是因为你的字库不是等宽字体导致的,可以有如下解决办法:
1、snprintf的字符串前后各加2个空 ...[/quote]

[img]C:\Users\Administrator\Desktop\QQ图片20160406150557[/img][img]C:\Users\Administrator\Desktop\QQ图片20160406150513[/img]
谢谢你的字库,但是按照你的办法,还是会出现如图的现象。有时正常,有时倾斜,但是最后一位不会跑到前面去了。

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 15:28:36
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=27987&ptid=10879]zhuangweiye 发表于 2016-4-6 10:52[/url]
36.        stBitmap.pData        = malloc (2*sdl_tmpsurface->w*sdl_tmpsurface->h);
37.        i ...[/quote]

您好,我把41行按照您的改法貌似不行,会出现地址非法的错误。多谢您给我优化代码。

cfgrpg

0个粉丝

7

问答

0

专栏

1

资料

cfgrpg 2016-04-06 15:29:58
认可0
本帖最后由 cfgrpg 于 2016-4-6 15:32 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=28002&ptid=10879]love_lin 发表于 2016-4-6 15:21[/url]
谢谢你的字库,但是按照你的办法,还是会出现如图的现象。有时正常,有时倾斜,但是最后一位不会跑到 ...[/quote]

是不是创建的reg太小了?
我的代码,先用一个时间格式的假字符串获取当前的宽度和高度,然后根据这个宽度和高度创建reg。
[code]    int w, h;
    TTF_SizeUTF8(font, " 2015-12-18 17:47:08 ", &w, &h);
    /****************************************
      step 1: create overlay regions
     ****************************************/
        stRgnAttr.enType = OVERLAY_RGN;
        stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_RGB_1555;//PIXEL_FORMAT_RGB_565
        stRgnAttr.unAttr.stOverlay.stSize.u32Width  = w + w%2 + 16;
    stRgnAttr.unAttr.stOverlay.stSize.u32Height = h + h%2;
        stRgnAttr.unAttr.stOverlay.u32BgColor = 0x0;[/code]

我当时也遇到过这个斜的情况,大致问题就是这么解决的,你可以试着再在两边多加点空格。

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-04-06 15:35:20
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=27965&ptid=10879]love_lin 发表于 2016-4-5 18:43[/url]
我还没完全弄好,我这边也遇到了问题,你可先参考下http://blog.sina.com.cn/s/blog_8795b0970101j5fo.ht ...[/quote]

好的 谢谢啦

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 15:59:00
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=28006&ptid=10879]cfgrpg 发表于 2016-4-6 15:29[/url]
是不是创建的reg太小了?
我的代码,先用一个时间格式的假字符串获取当前的宽度和高度,然后根据这个 ...[/quote]

您好,按照您的方式来分配reg,也是不行,现象是一样的,有时正常,有时倾斜。不知道还有没其他配置和您不一样的。[code]HI_S32 SDK_COMM_VIDEO_LoadOSDBmp(const char *ptxt,HI_S32 handle)
{
        SDL_Surface *sdl_txtsurface = NULL;
        SDL_Surface *sdl_tmpsurface = NULL;
        BITMAP_S stBitmap;
        HI_S32 s32Ret = HI_SUCCESS;
        
        //osd text color 1:R 2:G 3:B 4:no use
        SDL_Color forecol= { 0xff, 0xff, 0xff, 0 };

        sdl_txtsurface = TTF_RenderUTF8_Solid(stFont, ptxt, forecol);

        //save bmp to file
        //SDL_SaveBMP(sdl_txtsurface, "osd_cloudtop.bmp");

        sdl_tmpsurface = SDL_CreateRGBSurface(SDL_SWSURFACE,sdl_txtsurface->w, sdl_txtsurface->h, 16,\
                        0x00000000, 0x00000000, 0x00000000,0x00000000);
        SDL_Rect bounds;
        if (sdl_tmpsurface != NULL)
        {
                bounds.x = 0;
                bounds.y = 0;
                bounds.w = sdl_txtsurface->w;
                bounds.h = sdl_txtsurface->h;
                if (SDL_LowerBlit(sdl_txtsurface, &bounds, sdl_tmpsurface, &bounds) < 0) {
                        SDL_FreeSurface(sdl_txtsurface);
                        SDL_SetError("Couldn't convert image to 16 bpp");
                        sdl_txtsurface = NULL;
                        return HI_FAILURE;
                }
        }else{
                SAMPLE_PRT("sdl creat RGB surface failed\n");
                return HI_FAILURE;
        }

        stBitmap.pData        = malloc (2*sdl_tmpsurface->w*sdl_tmpsurface->h);
        if ( stBitmap.pData == NULL ) {
                SAMPLE_PRT( stderr, "\ndynamic memory allocation failed\n" );
        }

        stBitmap.u32Width = sdl_tmpsurface->w;
        stBitmap.u32Height = sdl_tmpsurface->h;
        stBitmap.pData= sdl_tmpsurface->pixels;
        stBitmap.enPixelFormat= PIXEL_FORMAT_RGB_1555 ;

        //SDL_SaveBMP(sdl_tmpsurface, "hi_osd.bmp");
    s32Ret = HI_MPI_RGN_SetBitMap(handle,&stBitmap);
    if(s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
               
    }
    if (NULL != stBitmap.pData)
    {
        free(stBitmap.pData);
        stBitmap.pData = NULL;
    }
        
        //SDL_FreeSurface(sdl_tmpsurface);
        //SDL_FreeSurface(sdl_txtsurface);
        return HI_SUCCESS;
}[/code]
这个模块的代码配置有问题吗?

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-04-06 16:16:10
认可0
抱歉,试试
stBitmap.u32Width = sdl_tmpsurface->pitch/2;
另外能不能把 pitch, w打出来看看

cfgrpg

0个粉丝

7

问答

0

专栏

1

资料

cfgrpg 2016-04-06 16:20:00
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=28009&ptid=10879]love_lin 发表于 2016-4-6 15:59[/url]
您好,按照您的方式来分配reg,也是不行,现象是一样的,有时正常,有时倾斜。不知道还有没其他配置和您 ...[/quote]

可能有点问题,我把我的贴出来给你参考下,我这个是可以用的。
[code]int creat_bmp_data_show(TTF_Font *font,char *strings, BITMAP_S *osd_bmp_in)
{
        #if 1
        SDL_Color forecol=   { 0x00, 0x00, 0x00, 0x0};

        SDL_Surface *text = TTF_RenderUTF8_Solid(font, strings, forecol);
        #else
        SDL_Color bgforecol=         { 0x00, 0xff, 0xff, 0xff };
        SDL_Color fgforecol=         { 0xFF, 0x00, 0x00, 0x00 };

        SDL_Surface *text = TTF_RenderUTF8_Shaded(font, strings, fgforecol, bgforecol);       
        #endif
   
        if(text == NULL)
        {
                printf("%s:[%d] The text is NULL !\n",__FUNCTION__,__LINE__);
                return -1;
        }

        SDL_PixelFormat fmt;

        memset(&fmt, 0, sizeof(SDL_PixelFormat));
        fmt.BitsPerPixel = 16;
        fmt.BytesPerPixel = 2;

        fmt.Rmask = 0x1F << 10;//
        fmt.Gmask = 0x1F << 5;//0x0000FF00
        fmt.Bmask = 0x1F << 0;//0x000000FF
        fmt.Amask = 0x01 << 15;

        static SDL_Surface *osd_test = NULL;

        if(osd_test != NULL)
        {
                SDL_FreeSurface(osd_test);
        }

    osd_test = SDL_ConvertSurface(text, &fmt, 0);

        osd_bmp_in->u32Width = osd_test->w;  
        osd_bmp_in->u32Height = osd_test->h;       
        osd_bmp_in->pData = osd_test->pixels;

        osd_bmp_in->enPixelFormat= PIXEL_FORMAT_RGB_1555 ;

        SDL_FreeSurface(text);
        text = NULL;
        //SDL_FreeSurface(osd_test);
        text = NULL;

        return 0;
}[/code]

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 16:36:43
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=28010&ptid=10879]zhuangweiye 发表于 2016-4-6 16:16[/url]
抱歉,试试
stBitmap.u32Width = sdl_tmpsurface->pitch/2;
另外能不能把 pitch, w打出来看看[/quote]

谢谢您,好像可以了,问题就出现在这里,他们的值有时是两倍关系,有时不是。

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 16:41:31
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=28011&ptid=10879]cfgrpg 发表于 2016-4-6 16:20[/url]
可能有点问题,我把我的贴出来给你参考下,我这个是可以用的。[/quote]

解决了,根据楼上那位大神指点,问题点出现在
  stBitmap.u32Width = sdl_tmpsurface->w;------------》应改成sdl_tmpsurface->pitch/2
        stBitmap.u32Height = sdl_tmpsurface->h;
        stBitmap.pData= sdl_tmpsurface->pixels;
        stBitmap.enPixelFormat= PIXEL_FORMAT_RGB_1555 ;

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-04-06 16:49:46
认可0

"1 typedef struct SDL_Surface {
    2     Uint32 flags;                           /* Read-only */
    3     SDL_PixelFormat *format;                /* Read-only */
    4     int w, h;                               /* Read-only */
    5     Uint16 pitch;                           /* Read-only */
    6     void *pixels;                           /* Read-write */
    7     SDL_Rect clip_rect;                     /* Read-only */
    8     int refcount;                           /* Read-mostly */
    9
   10   /* This structure also contains private fields not shown here */
   11 } SDL_Surface;

意思就是说 sdl_tmpsurface->pixels这块buffer里面的数据的放法是每行宽度是pitch*2个bytes,里面放了w个像素,每个像素2bytes,
按楼主的设置,如果w=pitch,那么显示出来的OSD是没有问题的,如果w!=pitch,那么显示就有问题了(会出现后面的字跑到前面去,斜纹等等)"


前面这段描述有错误, 这里更正一下
意思就是说 sdl_tmpsurface->pixels这块buffer里面的数据的放法是每行宽度是pitch个bytes,里面放了w个像素,每个像素2bytes(ARGB1555格式决定),
按楼主的设置,如果w=pitch/2,那么显示出来的OSD是没有问题的,如果w!=pitch/2,那么显示就有问题了(会出现后面的字跑到前面去,斜纹等等)

所以如果直接使用SDL产生的buffer, 那么bitmap的宽度应该设为pitch/2(ARGB1555格式)

love_lin

1个粉丝

22

问答

0

专栏

1

资料

love_lin 2016-04-06 17:01:02
认可0
本帖最后由 love_lin 于 2016-4-6 17:07 编辑

谢谢各位大神的指点:
此问题已基本解决了。我把他封装成几个接口,方便其他程序调用。
接口代码如下:
[code]
/**********************************************
*
*  Name:        SDK_COMM_SetOSDTimerPos
*  Description:  set osd timer position
*  Param:       
*  Return:
*
*********************************************/
HI_S32 SDK_COMM_VIDEO_SetOSDTimerPos(HI_S32 handle,HI_S32 xPos,HI_S32 yPos)
{
        HI_S32 s32Ret;
    MPP_CHN_S stChn;
    RGN_CHN_ATTR_S stChnAttr;

    stChn.enModId  = HI_ID_VENC;
    stChn.s32DevId = 0;
    stChn.s32ChnId = VENC_CHN_VIDEO;

    stChnAttr.bShow  = HI_TRUE;
    stChnAttr.enType = OVERLAY_RGN;
    stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = xPos;
    stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = yPos;
    stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha   = 0;
    stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha   = 128;
    stChnAttr.unChnAttr.stOverlayChn.u32Layer     = handle;

    stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = HI_FALSE;
    stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp  = 0;
        stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bQpDisable = HI_FALSE;
                       
    stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16;
    stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width  = 16;
    stChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 128;
    stChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod     = LESSTHAN_LUM_THRESH;
    stChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn    = HI_FALSE;

    s32Ret = HI_MPI_RGN_SetDisplayAttr(handle, &stChn, &stChnAttr);
    if (HI_SUCCESS != s32Ret)
    {
                SAMPLE_PRT("set osd rng attr failed\n");
    }
        return s32Ret;

}


static HI_S32 SAMPLE_RGN_CreateOverlayForVenc(VIDEO_PIC_PARAM videoPicParam)
{
    HI_S32 i;
    HI_S32 s32Ret;
    MPP_CHN_S stChn;
        RGN_ATTR_S stRgnAttr;
    RGN_CHN_ATTR_S stChnAttr;
        HI_S32 w, h;

        SIZE_S picSize ;
        s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm_sample,videoPicParam.enSize, &picSize);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("get picture size failed!\ninit osd mudule failed\n");
                return s32Ret;
    }
    /* Add cover to vpss group */
    stChn.enModId  = HI_ID_VENC;
    stChn.s32DevId = 0;
    stChn.s32ChnId = VENC_CHN_VIDEO;
       
    for (i = 0; i < 2; i++)
    {

                TTF_SizeUTF8(stFont, "CLOUDTOPIPCAM", &w, &h);
        stRgnAttr.enType = OVERLAY_RGN;
        stRgnAttr.unAttr.stOverlay.enPixelFmt       = PIXEL_FORMAT_RGB_1555;
        stRgnAttr.unAttr.stOverlay.stSize.u32Width  = w + w%2 + 16;
        stRgnAttr.unAttr.stOverlay.stSize.u32Height = h + h%2;
        stRgnAttr.unAttr.stOverlay.u32BgColor       = 0x00000000;

        if (1 == i % 2)
        {
                        TTF_SizeUTF8(stFont, "2015-12-18 17:23:08", &w, &h);
            stRgnAttr.unAttr.stOverlay.stSize.u32Width  = w + w%2 + 16;
            stRgnAttr.unAttr.stOverlay.stSize.u32Height = h + h%2;
            stRgnAttr.unAttr.stOverlay.u32BgColor       = 0x00000000;
        }

        s32Ret = HI_MPI_RGN_Create(i, &stRgnAttr);
        if (s32Ret != HI_SUCCESS)
        {
            SAMPLE_PRT("HI_MPI_RGN_Create failed! s32Ret: 0x%x.\n", s32Ret);
            return s32Ret;
        }

        stChnAttr.bShow  = HI_TRUE;
        stChnAttr.enType = OVERLAY_RGN;
        stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 8;
        stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 18;
        stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha   = 0;//region bg alpha
        stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha   = 128;//text bg alpha
        stChnAttr.unChnAttr.stOverlayChn.u32Layer     = i;

        stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = HI_FALSE;
        stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp  = 0;

        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width  = 16;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 128;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod     = LESSTHAN_LUM_THRESH;
        stChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn    = HI_FALSE;
        if (1 == i % 2)
        {
            stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = (picSize.u32Width - (w + w%2 +16));
            stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 18;
                        stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha   = 0;//region bg alpha
                stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha   = 128;//text bg alpha
                        stChnAttr.unChnAttr.stOverlayChn.u32Layer     = i;
        }
        s32Ret = HI_MPI_RGN_AttachToChn(i, &stChn, &stChnAttr);
        if (s32Ret != HI_SUCCESS)
        {
                        SAMPLE_PRT("rgn attach err\n");
           // AMPLE_RGN_NOT_PASS(s32Ret);
        }
    }

    return HI_SUCCESS;

}

HI_S32 SDK_COMM_VIDEO_InitOSDModule(VIDEO_PIC_PARAM videoPicParam)
{
        HI_S32 s32Ret = HI_SUCCESS;
        HI_S32 wordSize ;
        isOSDFlg = HI_TRUE;

       
        switch(videoPicParam.enSize){
                case PIC_QVGA:
                        wordSize = 12;
                        break;
                case PIC_VGA:
                        wordSize = 16;
                        break;
                case PIC_XGA:
                        wordSize = 24;
                        break;
                case PIC_HD720:
                        wordSize = 32;
                        break;
                case PIC_HD1080:
                        wordSize = 48;
                        break;
                default:
                        SAMPLE_PRT("video size err,not support osd time\n");
                        break;
        }

       
        if ( TTF_Init() < 0 )
        {
                fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
                SDL_Quit();
                return HI_FAILURE;
        }
        stFont = TTF_OpenFont("word.ttf",wordSize);
        if ( stFont == NULL )
        {
                SAMPLE_PRT("ttf open err\n");
                return HI_FAILURE;
        }
    s32Ret = SAMPLE_RGN_CreateOverlayForVenc(videoPicParam);
        if (HI_SUCCESS != s32Ret)
        {
                SAMPLE_PRT("SAMPLE_RGN_CreateOverlayForVenc failed! s32Ret: 0x%x.\n", s32Ret);
                return s32Ret;
        }
        return HI_SUCCESS;
}

HI_S32 SDK_COMM_VIDEO_LoadOSDBmp(const char *ptxt,HI_S32 handle)
{
        SDL_Surface *sdl_txtsurface = NULL;
        SDL_Surface *sdl_tmpsurface = NULL;
        BITMAP_S stBitmap;
        HI_S32 s32Ret = HI_SUCCESS;
       
        //osd text color 1:R 2:G 3:B 4:no use
        SDL_Color forecol= { 0xff, 0xff, 0xff, 0 };

        sdl_txtsurface = TTF_RenderUTF8_Solid(stFont, ptxt, forecol);

        //save bmp to file
        //SDL_SaveBMP(sdl_txtsurface, "osd_cloudtop.bmp");

        sdl_tmpsurface = SDL_CreateRGBSurface(SDL_SWSURFACE,sdl_txtsurface->w, sdl_txtsurface->h, 16,\
                        0x00000000, 0x00000000, 0x00000000,0x00000000);
        SDL_Rect bounds;
        if (sdl_tmpsurface != NULL)
        {
                bounds.x = 0;
                bounds.y = 0;
                bounds.w = sdl_txtsurface->w;
                bounds.h = sdl_txtsurface->h;
                if (SDL_LowerBlit(sdl_txtsurface, &bounds, sdl_tmpsurface, &bounds) < 0) {
                        SDL_FreeSurface(sdl_txtsurface);
                        SDL_SetError("Couldn't convert image to 16 bpp");
                        sdl_txtsurface = NULL;
                        return HI_FAILURE;
                }
        }else{
                SAMPLE_PRT("sdl creat RGB surface failed\n");
                return HI_FAILURE;
        }
        stBitmap.u32Width = sdl_tmpsurface->pitch/2;
        //stBitmap.u32Width = sdl_tmpsurface->w;//字体会倾斜
        stBitmap.u32Height = sdl_tmpsurface->h;
        stBitmap.pData= sdl_tmpsurface->pixels;
        stBitmap.enPixelFormat= PIXEL_FORMAT_RGB_1555 ;

        //SDL_SaveBMP(sdl_tmpsurface, "hi_osd.bmp");
    s32Ret = HI_MPI_RGN_SetBitMap(handle,&stBitmap);
    if(s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
               
    }
    if (NULL != stBitmap.pData)
    {
        free(stBitmap.pData);
        stBitmap.pData = NULL;
    }
       
        //SDL_FreeSurface(sdl_tmpsurface);
        SDL_FreeSurface(sdl_txtsurface);
        return HI_SUCCESS;
}

/**********************************************
*
*  Name:        SDK_COMM_VIDEO_OSDDestory
*  Description:  destory osd
*  Param:       
*  Return:
*
*********************************************/
HI_S32 SDK_COMM_VIDEO_OSDDestory()
{
        if(NULL != stFont){
                TTF_CloseFont(stFont);
                TTF_Quit();
                stFont = NULL;
        }
        return HI_SUCCESS;
}
[/code]

应用程序调用代码如下:
[code]/**********************************************
*
*  Name:        SAMPLE_LIBVIDEO_getLocalTime
*  Description:  get local time
*  Param:       
*  Return:
*
*********************************************/
static void SAMPLE_LIBVIDEO_getLocalTime (char *pstr)
{
        time_t timep;
        struct tm *p;
        time(&timep);
        p=localtime(&timep); /*get local time*/

        snprintf(pstr,32,"%4d-%02d-%02d %02d:%02d:%02d",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday,    \
                        p->tm_hour,p->tm_min,p->tm_sec);
        return ;
}/*End of SAMPLE_LIBVIDEO_getLocalTime*/

/**********************************************
*
*  Name:        SAMPLE_LIBVIDEO_setTimerOSDProc
*  Description:  set timer osd
*  Param:       
*  Return:
*
*********************************************/
static HI_VOID* SAMPLE_LIBVIDEO_setTimerOSDProc (HI_VOID* p)
{
        HI_BOOL *pStartFlg;
        pStartFlg = (HI_BOOL*)p;
        char str[32] = {0};
        while(*pStartFlg){
                SAMPLE_LIBVIDEO_getLocalTime(str);
                //printf("---->%s\n",str);
                if(HI_SUCCESS != SDK_COMM_VIDEO_LoadOSDBmp(str,1))
                {
                        printf("osd timer load bmp failed\n");
                }
                sleep(1);
        }
        SDK_COMM_VIDEO_OSDDestory();
        return NULL;
}/*End of SAMPLE_LIBVIDEO_setTimerOSDProc*/

/**********************************************
*
*  Name:        SAMPLE_LIBVIDEO_SetTimerOSD
*  Description:  creat to set timer osd
*  Param:       
*  Return:
*
*********************************************/
HI_S32 SAMPLE_LIBVIDEO_SetTimerOSD ()
{

        vOSDFlg = HI_TRUE;
    return pthread_create(&osdPid, 0, SAMPLE_LIBVIDEO_setTimerOSDProc, &vOSDFlg);
}/*End of SAMPLE_LIBVIDEO_SetTimerOSD*/[/code]
主函数主要是显示产品logo,和创建时间戳线程:
部分代码如下:
[code]        if(HI_SUCCESS != SDK_COMM_VIDEO_InitOSDModule(videoPicParam))
        {
                printf("init OSD failed\n");
        }else{
                if(HI_SUCCESS != SDK_COMM_VIDEO_LoadOSDBmp("CTIPCam",0))
                {
                        printf("osd load bmp failed\n");
                }
                SAMPLE_LIBVIDEO_SetTimerOSD();
        }[/code]

加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

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

详细说明

易百纳技术社区