海思3559万能平台搭建:OSD实时叠加的支持2区域RGN的配置

2023-05-16

前言

  位图的生成只是我们字符叠加的基础,具体表现就要靠对区域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;
}

结果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海思3559万能平台搭建:OSD实时叠加的支持2区域RGN的配置 的相关文章

  • 计算机网络---应用层以及HTTP协议

    网络层是程序员接触最多的一个层级 xff0c 应用层是层级体系中的最上层的一级 xff0c 是我们做逻辑处理最多的 应用层的功能什么是urlhttp协议 应用层的功能 是程序员写的一个一个解决的实际的问题都是在应用层 xff0c 是做逻辑运
  • 51驱动NRF24L01通信,NRF24L01与TTL转NRF24L01模块通信

    51驱动NRF24L01通信 xff0c NRF24L01与TTL转NRF24L01模块通信 NRF24L01一 简介二 引脚功能描述 程序设计一 对 24L01 的程序编程的基本思路如下 xff1a 二 Tx 与 Rx 的配置过程1 Tx
  • 51单片机驱动K型热电偶 OLED0.96显示

    51单片机驱动K型热电偶 OLED0 96显示 一 基本参数二 接线三 部分代码引脚定义时序对用代码 四 实验现象五 注意事项 一 基本参数 二 接线 K型热电偶 MAX6675 模块引脚说明GNDGND接地 单独供电需要与MCU共地VCC
  • 基于ESP32做低功耗墨水屏时钟

    基于ESP32做低功耗墨水屏时钟 电子墨水屏概述 ESP32实验低功耗电子时钟功能描述接线开发实验结果 电子墨水屏 概述 电子墨水是一种革新信息显示的新方法和技术 和传统纸差异是电子墨水在通电时改变颜色 xff0c 并且可以显示变化的图象
  • STC89C52制作可程控低频信号发生器

    STC89C52制作可程控低频信号发生器 准备工作操作流程关于PCF8591实现构思 相关代码定时器相关代码串口控制频率和LCD显示函数 相关功能现象总结 准备工作 由于51单片机本身并不自带DAC的功能 xff0c 因此需要借助外置模块实
  • Arduino UNO驱动 Si3531A三通道时钟信号发生器

    Arduino UNO驱动 Si3531A三通道时钟信号发生器 Si3531A模块简介模块引脚定义Arduino UNO与模块接线测试代码实验结果 Si3531A模块简介 Si3531A是一个IIC接口可编程时钟信号频率发生器 xff0c
  • Arduino驱动HC-SR04超声波测距

    Arduino驱动HC SR04超声波测距 前言电气参数基本工作原理时序图接线程序实验结果总结 前言 HC SR04超声波测距模块可提供2cm 400cm的非接触式距离感测功能 xff0c 测距精度可达3mm xff0c 包括发射器 接收器
  • stm32f103c8t6新建环境+点灯

    stm32f103c8t6新建环境 43 点灯 简介步骤一 新建文件二 建立启动 43 用户端本身文件三 mdk内部设置四 实现基础工作效果五 点灯 总结 简介 STM32F103C8T6是一款由意法半导体公司 xff08 ST xff09
  • ESP32驱动1.28寸GC9A01播放视频(一、视频分辨率的调整和视频格式的转换)

    ESP32驱动1 28寸GC9A01播放视频 xff08 一 视频分辨率的调整和视频格式的转换 xff09 播放前准备转换视频分辨率用FFmpeg将 MP4转换为 mjpeg格式FFmpeg的win10环境搭建FFmpeg的下载环境变量的搭
  • Arduino UNO驱动micro SD卡读写模块

    目录 一 简介二 使用前准备三 测试方法四 实验现象 一 简介 Micro SD卡模块TF卡读写卡器板载电平转换电路 xff0c 即接口电平可为5V或3 3V xff0c 支持支持Micro SD卡 2G Micro SDHC高速卡 32G
  • ESP32驱动1.28寸GC9A01播放视频(二、程序说明和效果展示)

    ESP32驱动1 28寸GC9A01播放视频 xff08 二 程序下载和效果展示 xff09 1 28寸GC9A01屏幕屏幕引脚定义 程序说明程序更改1 Arduino DataBus bus和Arduino GC9A01 gfx要改成ES
  • 计算机网络---传输层的udp协议

    首先我们认识要在应用层对数据封装之后需要传输到传输层进行封装 xff0c 但是在应用层只是对数据进行了处理 xff0c 所以在传输层上需要对传输到那个进程进行设置 xff0c 所以在传输层需要对port进行设置 所以port是标志一个进程
  • c++中 ->,c++中::

    gt gt 用于指针 gt 用于指向结构体的指针 gt 用于指向结构体的指针 xff0c 表示结构体内的元素 include lt stdio h gt struct role 定义一个结构体 char name 8 姓名 int leve
  • U8W/U8W-Mini使用与常见问题解决

    U8W U8W Mini使用与常见问题解决 U8WU8W U8W mini简介准备工作U8W U8W mini在线联机下载U8W U8W mini脱机下载第一步 xff0c 把程序下载到U8W U8W mini烧录器中 xff1a 第二步
  • Arduino 驱动GP2Y1014AU检测PM2.5

    Arduino 驱动GP2Y1014AU检测PM2 5 一 基本参数二 接线三 部分代码引脚定义对应代码 四 实验现象五 注意事项 一 基本参数 二 接线 三 部分代码 引脚定义 define measurePin span class t
  • STM32F103ZET6驱动TOF250激光测距传感器

    STM32驱动TOF250激光测距传感器 TOF250介绍I2C通讯协议I2C寄存器地址 TOF250引脚说明和STM32的接线和STM32的接线 程序实验结果总结 TOF250介绍 TOF250是一款基于TOF原理的单点测距雷达 xff0
  • STM32驱动SG90舵机

    STM32驱动SG90舵机 关于SG90舵机SG90转动角度与占空比的关系驱动SG90舵机代码 确定控制引脚 写代码 SG90舵机正常驱动现象总结 关于SG90舵机 SG90是一种小型伺服电机 xff0c 通常用于模型制作和小型机械应用中
  • Arduino驱动L298N控制直流电机的正反转和调速

    Arduino驱动L298N控制直流电机的正反转和调速 一 前言二 产品参数三 驱动直流电机三 接线图四 程序五 实验结果总结 一 前言 本模块使用ST公司的L298N作为主驱动芯片 xff0c 具有驱动能力强 xff0c 发热量低 xff
  • Livox MID-70连接及使用

    ROS下载安装 本文选用ros xff0c 未使用ros2 在Ubuntu18 04下配置ros 下载安装参考 xff1a Ubuntu18 04安装 ROS桌面完整版 其中注意在第8部分 span class token function
  • 微信小程序 宠物论坛1

    微信小程序宠物论坛1 一个简单的论坛包括以下几个方面 xff1a 登录模块发帖模块首页模块帖子详情模块搜索模块个人主页模块 下面将从这6个方面介绍如何用微信小程序开发一个简单的论坛 登录模块 先看界面图 打开小程序首先看到这个界面 xff0

随机推荐