海思编码通道添加显示时间

在学了在学了! 2020-08-17 19:55:50 2576

说明

这里的需求是要往生成的录像文件中添加显示时间,实际上也就是海思的VENC与OSD的绑定。

在上一篇博客海思平台freetype、SDL、SDL_TTL的编译编译出三个库之后,又提供了例程生成一个bmp图片,但是实际上我们每次往海思通道贴图,不可能说都像例程一样保存成bmp图片再贴图,这样会造成资源的浪费。

所以这里进行了进一步的修改,让我们能够直接拿到bmp图片的位图数据,而不需要生成bmp图片。

一、bmp位图数据的获取

/*
getVencOsd  获取生成的位图数据
bitmap 海思 BITMAP_S 位图数据结构体指针
*/
static SV_S32 getVencOsd(BITMAP_S *bitmap) {
if( bitmap == NULL || bitmap->pData == NULL ) {
    LOG(ERROR)<<"bitmap or pData is NULL";
    return SV_FAILURE;
}

//初始化字库
if ( TTF_Init() < 0 ) {
    SDL_Quit();
    return SV_FAILURE;
}

//打开字库
font = TTF_OpenFont("/root/res/wqy-microhei.ttc", 48);
if ( font == NULL ) {
    fprintf(stderr, "Couldn't load %d pt font from %s: %s\n", 18, "ptsize", SDL_GetError());
    SDL_Quit();
    return SV_FAILURE;
}

//生成显示时间
std::string time("2019-10-10 10:10:10");
SDL_Color forecol = { 0xff, 0xff, 0xff, 0xff };
SDL_Surface *text = TTF_RenderUTF8_Solid(font, time.c_str(), forecol);
if ( text == NULL ) {
    LOG(ERROR)<<"temp is NULL";
    return SV_FAILURE;
}

SDL_PixelFormat fmt;
memset(&fmt, 0, sizeof(SDL_PixelFormat));
fmt.BitsPerPixel = 16;
fmt.BytesPerPixel = 2;
fmt.colorkey = 0xffffffff;
fmt.alpha = 0xff;
fmt.Rmask = 0xff000000;//0x00FF0000
fmt.Gmask = 0x0000ff00;//0x0000FF00
fmt.Bmask = 0x000000ff;//0x000000FF
fmt.Amask = 0;

SDL_Surface *temp = SDL_ConvertSurface(text, &fmt, 0);
if ( temp == NULL ) {
    LOG(ERROR)<<"temp is NULL";
    SDL_FreeSurface(text);
    return SV_FAILURE;
}

memset(bitmap->pData, 0, DATA_BUFF);
memcpy(bitmap->pData, temp->pixels, (2*(temp->w)*(temp->h)));

bitmap->u32Width = temp->w;
bitmap->u32Height = temp->h;
bitmap->enPixelFormat = PIXEL_FORMAT_RGB_1555 ;

SDL_FreeSurface(text);
SDL_FreeSurface(temp);
return SV_SUCCEED;

}

二、创建RGN区域

/*
* s32CreateRgnAndAttachVencChn  创建贴图区域并绑定到编码通道
* OsdRGBAs 海思 SV_OSD_RGBA_S 结构体对象
* s32VencChn 编码通道号
* s32RgnHandle 通道句柄
注意:海思的编码通道位图只支持PIXEL_FORMAT_RGB_1555或PIXEL_FORMAT_RGB_4444这里用的是1555
*/
static SV_S32 s32CreateRgnAndAttachVencChn(const SV_OSD_RGBA_S OsdRGBAs, const SV_S32 s32VencChn, const SV_S32 s32RgnHandle) {

    MPP_CHN_S stChn;
    //RGN 区域绑定到对应VENC
    stChn.enModId  = HI_ID_VENC;
    stChn.s32DevId = 0;
    stChn.s32ChnId = s32VencChn;

    //创建RGN区域
    RGN_ATTR_S stRgnAttrSet;
    stRgnAttrSet.enType = OVERLAY_RGN;
    stRgnAttrSet.unAttr.stOverlay.enPixelFmt       = PIXEL_FORMAT_RGB_1555;
    stRgnAttrSet.unAttr.stOverlay.stSize.u32Width  = std::max(2, ALIGN_BACK(OsdRGBAs.stPixRect.stRectSize.s32Width, 2));
    stRgnAttrSet.unAttr.stOverlay.stSize.u32Height = std::max(2, ALIGN_BACK(OsdRGBAs.stPixRect.stRectSize.s32Height, 2));
    stRgnAttrSet.unAttr.stOverlay.u32BgColor       = 0;

    HI_MPI_RGN_DetachFromChn(s32RgnHandle, &stChn);
    HI_MPI_RGN_Destroy(s32RgnHandle);
    SV_S32 s32Ret = HI_MPI_RGN_Create(s32RgnHandle, &stRgnAttrSet);
    if(s32Ret != SV_SUCCEED) {
        LOG(ERROR)<<"HI_MPI_RGN_Create failed with 0x"<<std::hex<<s32Ret;
        return SV_FAILURE;
    }

    RGN_CHN_ATTR_S stChnAttr;
    memset(&stChnAttr, 0, sizeof(stChnAttr));
    stChnAttr.bShow  = HI_TRUE;
    stChnAttr.enType = OVERLAY_RGN;
    stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = ALIGN_BACK(OsdRGBAs.stPixRect.stStartPoint.s32X, 2);
    stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = ALIGN_BACK(OsdRGBAs.stPixRect.stStartPoint.s32Y, 2);
    stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha   = 0;
    stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha   = 128;
    stChnAttr.unChnAttr.stOverlayChn.u32Layer     = 0;
    s32Ret = HI_MPI_RGN_AttachToChn(s32RgnHandle, &stChn, &stChnAttr);
    if(s32Ret != SV_SUCCEED) {
        LOG(ERROR)<<"HI_MPI_RGN_AttachToChn failed with 0x"<<std::hex<<s32Ret;
        HI_MPI_RGN_Destroy(s32RgnHandle);
        return SV_FAILURE;
    }
    return SV_SUCCEED;
}

三、加载bmp位图

/*
s32LoadBmp 加载显示bmp
pData 用来存放位图的buffer
*/
SV_S32 s32LoadBmp(SV_VOID *pData) {
    BITMAP_S bitmap;
    bitmap.pData = pData;

    SV_S32 s32VencChn = 0;
    SV_S32 s32Ret = getVencOsd(s32VencChn, &bitmap);
    if( s32Ret == SV_FAILURE ) {
        LOG(ERROR)<<"getVencOsd is failed!";
        return SV_FAILURE;
    }

    SV_OSD_RGBA_S pOsd;
    pOsd.stPixRect.stStartPoint.s32X = 0;
    pOsd.stPixRect.stStartPoint.s32Y = 0;
    pOsd.stPixRect.stRectSize.s32Width = bitmap.u32Width;
    pOsd.stPixRect.stRectSize.s32Height = bitmap.u32Height;

    SV_S32 s32RgnHandle = 0;
    s32Ret = this->s32CreateRgnAndAttachVencChn(pOsd, s32VencChn, s32RgnHandle);
    if( s32Ret == SV_FAILURE ) {
        LOG(ERROR)<<"s32CreateRgnAndAttachVencChn failed with "<<s32Ret;
        return SV_FAILURE;
    }

    //设定相应位图显示
    s32Ret = HI_MPI_RGN_SetBitMap(s32RgnHandle, &bitmap);
    if( s32Ret != SV_SUCCEED ) {
        LOG(ERROR)<<"sv_updateRgnChannals : HI_MPI_RGN_SetBitMap failed with 0x"<<std::hex<<s32Ret;
        HI_MPI_RGN_Destroy(s32RgnHandle);
        return SV_FAILURE;
    }

    return SV_SUCCEED;
}

四、主函数

int main (void) {

    char *pData = (char *)malloc(1024 * 512);
    s32LoadBmp( pData );

    return 0;
}

原文连接:https://blog.csdn.net/weixin_44362642/article/details/103469479

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 点赞 收藏 评论 打赏
评论
1个
内容存在敏感词
手气红包
  • 山楂树 2024-01-12 16:46:29
    回复
    好文章
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
在学了在学了!
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

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

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区