编程语言
首页 > 编程语言> > 海思3518E开发笔记2.3——海思mpp架构及sample程序流程分析

海思3518E开发笔记2.3——海思mpp架构及sample程序流程分析

作者:互联网

目录

MPP

海思提供的媒体处理软件平台(Media Process Platform,简称 MPP),可支持应用软件快速开发。

通俗点就是海思提供的这套ko、lib、api,对内存的管理。对内部进行视频编码的dsp的封装。

这一套体系就是mpp

MPP系统架构

在这里插入图片描述

海思媒体处理平台架构

海思媒体处理平台的主要内部处理流程如图 1-2 所示,主要分为

视频缓存池

视频缓存池主要向媒体业务提供大块物理内存管理功能,负责内存的分配和回收,充分发挥内存缓存池的作用,让物理内存资源在各个媒体处理模块中合理使用。

一组大小相同、物理地址连续的缓存块组成一个视频缓存池。

视频输入通道需要使用公共视频缓存池。所有的视频输入通道都可以从公共视频缓存池中获取视频缓存块用于保存采集的图像(如图 2-1 中所示从公共视频缓存池 A 中获取视频缓存块 Bm)。由于视频输入通道不提供创建和销毁公共视频缓存池功能,因此,在系统初始化之前,必须为视频输入通道配置公共视频缓存池。根据业务的不同,公共缓存池的数量、缓存块的大小和数量不同。 图 2-1 中所示缓存块的生存期是指经过 VPSS 通道传给后续模块的情形( 图 2-1 实线径)。如果该缓存块完全没有经过 VPSS 通道传给其他模块,则将在 VPSS 模块处理后被放回公共缓存池( 图 2-1 虚线路径)。
在这里插入图片描述

其中

typedef struct hiVB_CONF_S
{
    HI_U32 u32MaxPoolCnt;     /* max count of pools, (0,VB_MAX_POOLS]  */    
    struct hiVB_CPOOL_S
    {
        HI_U32 u32BlkSize;
        HI_U32 u32BlkCnt;
        HI_CHAR acMmzName[MAX_MMZ_NAME_LEN];
    }astCommPool[VB_MAX_COMM_POOLS];
} VB_CONF_S;

这个结构体是一些公共缓冲池的属性
由于板载DDR是64M,所以视频缓冲池的大小是有限的
结构体中的结构体就是每个缓冲池中块的大小

海思SDK中给的相关函数是

需要按照海思文档中说明的顺序进行操作

sample

从main函数开始

int main(int argc, char *argv[])
{
    HI_S32 s32Ret;
    if ( (argc < 2) || (1 != strlen(argv[1])))//如果传参用法不对
    {
        SAMPLE_VENC_Usage(argv[0]);//打印用法函数
        return HI_FAILURE;
    }

    signal(SIGINT, SAMPLE_VENC_HandleSig);
    signal(SIGTERM, SAMPLE_VENC_HandleSig);
    
    switch (*argv[1])
    {
    	//H264 编码  1080分辨率  30帧/秒
        case '0':/* H.264@1080p@30fps+H.265@1080p@30fps+H.264@D1@30fps */
            s32Ret = SAMPLE_VENC_1080P_CLASSIC();
            break;
        case '1':/* 1*1080p mjpeg encode + 1*1080p jpeg  */
            s32Ret = SAMPLE_VENC_1080P_MJPEG_JPEG();
            break;
        case '2':/* low delay */
            s32Ret = SAMPLE_VENC_LOW_DELAY();
            break;
        case '3':/* roibg framerate */
            s32Ret = SAMPLE_VENC_ROIBG_CLASSIC();
            break;
        case '4':/* Thumbnail of 1*1080p jpeg  */
            s32Ret = SAMPLE_VENC_1080P_JPEG_Thumb();
            break;
#ifndef hi3518ev201			
		case '5':/* H.264 Svc-t */
			s32Ret = SAMPLE_VENC_SVC_H264();
			break;
#endif
        default:
            printf("the index is invaild!\n");
            SAMPLE_VENC_Usage(argv[0]);
            return HI_FAILURE;
    }
    
    if (HI_SUCCESS == s32Ret)
        printf("program exit normally!\n");
    else
        printf("program exit abnormally!\n");
    exit(s32Ret);
}

为了保证兼容性,海思给的sample中有很多版本需要的内容

SAMPLE_VENC_1080P_CLASSIC

我们所用的主要是input为0时候,即SAMPLE_VENC_1080P_CLASSIC函数

/******************************************************************************
* function :  H.264@1080p@30fps+H.264@VGA@30fps
******************************************************************************/
HI_S32 SAMPLE_VENC_1080P_CLASSIC(HI_VOID)
{
    PAYLOAD_TYPE_E enPayLoad[3]= {PT_H264, PT_H264,PT_H264};
    PIC_SIZE_E enSize[3] = {PIC_HD1080, PIC_VGA,PIC_QVGA};
	HI_U32 u32Profile = 0;
	
    VB_CONF_S stVbConf;//视频缓存池//VB_CONF_S视频缓存池结构体
    SAMPLE_VI_CONFIG_S stViConfig = {0};
    
    VPSS_GRP VpssGrp;
    VPSS_CHN VpssChn;
    VPSS_GRP_ATTR_S stVpssGrpAttr;
    VPSS_CHN_ATTR_S stVpssChnAttr;
    VPSS_CHN_MODE_S stVpssChnMode;
    
    VENC_CHN VencChn;//编码通道
    SAMPLE_RC_E enRcMode= SAMPLE_RC_CBR;
	
    HI_S32 s32ChnNum=0;
    
    HI_S32 s32Ret = HI_SUCCESS;
    HI_U32 u32BlkSize;
    SIZE_S stSize;
    char c;

首先看上面的变量定义部分
最开始定义了一个PAYLOAD_TYPE_E的数组,对应三个通道,每一个都是H264格式
图像的尺寸对应三个通道,分别是1080、VGA、QVGA

有一点值得一提的是,枚举类型的结尾是BUTT,由于枚举是从1开始按顺序每个值增加的,所以最后写一个BUTT,可以通过BUTT进行判断

在初始化分辨率和编码格式结构体数组
还会定义一个公共视频缓存池

step 1: init sys variable

定义完变量后,第一步就是初始化sys部分的变量(mpp系统中的变量)

step 2: mpp system init.

系统初始化,为之前申请的变量分配内存

step 3: start vi dev & chn to capture

图像的采集,启动VI部分的dev(设备)和chn(通道)

step 4: start vpss and vi bind vpss

VI之后就会传给VPSS,传给VPSS之前先要把它启动起来
vi bind vpss:VI和VPSS是两个独立的模块.通过bind这操作,MPP系统提供的一个API(bind api),
通过调用bind api就可以把VI和VPSS这两个模块绑定起来。绑定起来之后有什么作用呢?
VI这边当它采集到一帧图像丢到一个VB(VIDEO BUFFER视频缓冲池)里面的缓存块里面之后,这个缓存块会自动传送到VPSS里面去。

step 5: start stream venc

VPSS处理完之后就会到VENC里面去。这一步就开始启动VENC单元,如果你要添加水印信息就在这一步去添加。
H.264编码也在这一步去研究。编码完之后呢就得到H.264的一个码流了。

step 6: stream venc process // get stream, then save it to file

我们得到H.264码流之后怎么处理呢?
-(1)可以把这个码流打包成一个MP4存储到硬盘里面去,这就是录像。
-(2)也可以分包,分成一个一个视频包通过RTSP传出去。
-(3)也可以像sample一样直接作为一个裸流直接丢到流文件里面去。

那么这种流文件必须通过像VLC这种能够解析裸流文件的播放器来观看。
所以说编码模块只负责输出一段H.264的裸流,这个裸流要怎么办是你的事。

step 7: exit process

如果不想录了之后就按两次回车跑到SAMPLE_COMM_VENC_StopGetStream();里面去
然后进行一些列的释放内存、解除绑定的操作

标签:视频,缓存,sample,SAMPLE,HI,3518E,VENC,VPSS,海思
来源: https://blog.csdn.net/qq_28258885/article/details/118675318