• Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件


    前言

      上一篇已经将himpp套入qt的基础上进行开发。那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤。

     

    受限制

      因为直接配置sample的vi比较麻烦,确实是困难的,其实就是配置驱动,所以我们只能从开发板的demo入手,去在相等条件下探测可能的留,从vpss中拿取后,进行软编码。
      当然,如果不用qt还有一种方式,也就是大量开发海思人员使用的方式,是基于sample写一个编码程序,然后使用本地socket交互,其实绝大部分海思开发者都是这样开发的,但是他们不涉及与qt的深入交互。

     

    前提条件

      需要移植ffmpeg到海思平台,可参考博文《FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台》。

     

    Demo演示

      从vpss中获取一帧图像,如下图:
      在这里插入图片描述
      在这里插入图片描述

     

    相关的API

      (原本整理了一大半自己的习惯格式,后续海思看多了,觉得海思文档也还行,就是争对性的开发,无用信息有点多,所以此处还是用海思的文档,但是只提取涉及的部分,海思文档是个庞大的体系,需要动手,光看是很难理解的)。

    HI_MPI_VPSS_GetChnFrame:从通道获取一帧处理完的数据

      用户从通道获取一帧处理完成的图像,必须与HI_MPI_VPSS_ReleaseChnFrame()配对使用。

    函数原型

    HI_S32 HI_MPI_VPSS_GetChnFrame(VPSS_GRP VpssGrp,
                                   VPSS_CHN VpssChn,
                                   VIDEO_FRAME_INFO_S *pstVideoFrame,
                                   HI_S32 s32MilliSec);
    
    • 参数一:VpssGrou,通道组号,海思芯片通道号,
      取值[0, VPSS_MAX_GRP_NUM];
    • 参数二:VpssChn,通道号,通道组下的通道号,
      取值[0, VPSS_MAX_CHN_NUM];
    • 参数三:pstVideoFrame,帧数据的结构体,要取的数据就在这个帧里面,这
      是很关键的结构体,稍后是会深入讲解的重点;
    • 参数四:s32MilliSec,阻塞时间,跟其他阻塞有点区别,-1为阻塞,0为直
      接获取,其他整数位等待的超时时间。

    返回值

       在这里插入图片描述

    其他注意

      在这里插入图片描述

    HI_MPI_VPSS_ReleaseChnFrame:释放一帧图像

      释放之前通过HI_MPI_VPSS_GetChnFrame获取获取的图像。

    函数原型

    HI_S32 HI_MPI_VPSS_ReleaseChnFrame (VPSS_GRP VpssGrp,
                                        VPSS_CHN VpssChn,
                                        const VIDEO_FRAME_INFO_S *pstVideoFrame);
    
    • 参数一:VpssGrou,通道组号,海思芯片通道号,
      取值[0, VPSS_MAX_GRP_NUM],之前获取使用的是哪个就哪个;
    • 参数二:VpssChn,通道号,通道组下的通道号,
      取值[0, VPSS_MAX_CHN_NUM];之前获取使用的是哪个就哪个;
    • 参数三:pstVideoFrame,帧数据的结构体,要取的数据就在这个帧里面,这
      是很关键的结构体,稍后是会深入讲解的重点;

    返回值

      在这里插入图片描述

    其他注意

       在这里插入图片描述

     

    相关的结构体

    VIDEO_FRAME_INFO_S:定义视频图像帧信息结构体

    结构体原型

    typedef struct hiVIDEO_FRAME_INFO_S
    {
        VIDEO_FRAME_S stVFrame;		// 视频图像帧
        HI_U32 u32PoolId;			// 视频缓存池ID
        MOD_ID_E enModId;			// 当前帧数据是由哪一个硬件逻辑模块写出的
    } VIDEO_FRAME_INFO_S;
    

    VIDEO_FRAME_S:定义视频原始图像帧结构体

    结构体原型

    typedef struct hiVIDEO_FRAME_S
    {
        HI_U32 u32Width;					// 图像宽度
        HI_U32 u32Height;					// 图像高度
        VIDEO_FIELD_E enField;				// 帧场模式
        PIXEL_FORMAT_E enPixelFormat;		// 视频图像像素格式
        VIDEO_FORMAT_E enVideoFormat;		// 视频图像格式
        COMPRESS_MODE_E enCompressMode;		// 视频压缩模式
        DYNAMIC_RANGE_E enDynamicRange;		// 动态范围
        COLOR_GAMUT_E enColorGamut;			// 色域范围
        HI_U32 u32HeaderStride[3];			// 图像压缩头跨距
        HI_U32 u32Stride[3];				// 图像数据跨距
        HI_U32 u32ExtStride[3];				// 10bit数据位宽的图像,部分格式分开存
        HI_U64 u64HeaderPhyAddr[3];			// 压缩头物理地址
        HI_U64 u64HeaderVirAddr[3];			// 压缩头虚拟地址,内核态虚拟地址
        HI_U64 u64PhyAddr[3];				// 图像数据物理地址
        HI_U64 u64VirAddr[3];				// 图像数据虚拟地址,内核态虚拟地址
        HI_U64 u64ExtPhyAddr[3];			// 10bit数据位宽度的图像,部分格式分开存
        HI_U64 u64ExtVirAddr[3];			// 10bit数据位宽度的图像,部分格式分开存
       HI_S16 s16OffsetTop;					// 图像顶部剪裁宽度
        HI_S16 s16OffsetBottom;				// 图像底部剪裁宽度
        HI_S16 s16OffsetLeft;				// 图像左侧剪裁宽度
        HI_S16 s16OffsetRight;				// 图像右侧剪裁宽度
        HI_U32 u32MaxLuminance;				// 显示图像的最大亮度
        HI_U32 u32MinLuminance;				// 显示图像的最小亮度
        HI_U32 u32TimeRef;					// 图像帧序列号
        HI_U64 u64PTS;						// 图像时间戳
        HI_U64 u64PrivateData;				// 私有数据
       HI_U32 u32FrameFlag;					// 当前帧的标记,使用FRAME_FLAG_E标记
        VIDEO_SUPPLEMENT_S stSupplement;	// 图像的补充信息
    } VIDEO_FRAME_S;
    

    其他注意

      在这里插入图片描述

     

    相关枚举

    VIDEO_FIELD_E:帧场模式

      在这里插入图片描述

    PIXEL_FORMAT_E:视频图像像素格式

      在这里插入图片描述
      在这里插入图片描述

    VIDEO_FORMAT_E:视频图像格式

      在这里插入图片描述

    COMPRESS_MODE_E:视频压缩模式

      在这里插入图片描述

    DYNAMIC_RANGE_E:动态范围

      在这里插入图片描述

    COLOR_GAMUT_E:色域范围

      在这里插入图片描述

    VIDEO_SUPPLEMENT_S:图像的补充信息

      在这里插入图片描述

     

    Demo

    void HiMppManager::testGetVPssFrame()
    {
        VIDEO_FRAME_INFO_S videoFrameInfoS;
    #if 0
        // 搜索开开发板用了哪个通道(应该只有2个摄像头,绑定了vpss)
        // 结果:探测到开发板在snap抓图模式下在通道组0通道0下有图片
        for(int groupIndex = 0; groupIndex < VPSS_MAX_GRP_NUM; groupIndex++)
        {
            for(int channelIndex = 0; channelIndex < VPSS_MAX_CHN_NUM; channelIndex++)
            {
                HI_S32 s32MilliSec = 100;
                HI_S32 ret = HI_MPI_VPSS_GetChnFrame(groupIndex, channelIndex, &videoFrameInfoS, s32MilliSec);
                if(ret == 0)
                {
                    LOG << QString("Succeed to get HI_MPI_VPSS_GetChnFrame(%1, %2, &videoFrameInfoS, %3)")
                           .arg(groupIndex)
                           .arg(channelIndex)
                           .arg(s32MilliSec);
                    break;
    #if 0
                }else{
                    LOG <<  QString("Failed to get HI_MPI_VPSS_GetChnFrame(%1, %2, &videoFrameInfoS, %3): %4")
                            .arg(groupIndex)
                            .arg(channelIndex)
                            .arg(s32MilliSec)
                            .arg(ret);
    #endif
                }
    
            }
        }
    #endif
        while(HI_MPI_VPSS_GetChnFrame(0, 0, &videoFrameInfoS, -1) == 0)
        {
            LOG << "get frame";
            LOG << videoFrameInfoS.stVFrame.enPixelFormat
                << "PIXEL_FORMAT_YVU_PLANAR_420:" << (int)PIXEL_FORMAT_YVU_PLANAR_420
                << "PIXEL_FORMAT_YVU_SEMIPLANAR_420:" << (int)PIXEL_FORMAT_YVU_SEMIPLANAR_420;
            LOG << videoFrameInfoS.stVFrame.enVideoFormat;
            HI_MPI_VPSS_ReleaseChnFrame(0, 0, &videoFrameInfoS);
            LOG << "release frame";    }
    }
    
     

    入坑

    入坑一:获取vpss图像一定帧数后无法再获取

    问题

      使用海思sdk获取图像后,多次获取后,大概20次左右就获取失败了。

    原因

      海思获取图像后,需要释放,是占用了缓存区。
      海思的HI_MPI_VPSS_GetChanFrame与Hi_MPI_VPSS_ReleaseChnFrame要成对使用。

    解决方法

      

  • 相关阅读:
    [SDOI2015]约数个数和
    [POI2007]ZAP-Queries
    fpu栈溢出
    shader 汇编
    sample a texture as a rendertarget
    ID3d11asynchronous
    DEVICE DRAW VERTEX BUFFER TOO SMALL
    模型的一个点显示在原点
    setrendertraget 上下颠倒
    skinned mesh 蜘蛛样
  • 原文地址:https://www.cnblogs.com/qq21497936/p/16579899.html
Copyright © 2020-2023  润新知