海思编码:1、mpp系统详谈以及VI、VPSS、VENC之间的关系

在HiMPP手册中都会有这么一张图
在这里插入图片描述

先讲一下视频缓存池这个概念

视频缓存池主要向媒体业务提供大块物理内存管理功能,负责内存的分配和回收
这部分具体什么作用,首先视频输入回需要大量的内存,打比方1080P的视频输入,VI部分怎么保存或者使用呢?就是用的视频缓存池概念,
比如:VI将视频输入的一张图像数据放在一个缓存池的缓存块,然后处理后将这个缓存块的地址和大小交给VPSS处理,VPSS处理后又将这个缓存块的地址传给venc,venc就会对这个缓存块的画面进行编码,在这个过程中只有缓存块的地址在来回传递,没有内存拷贝,而且编码完后,MPP系统自动将这个缓存块注销了,这样既节省了性能,又防止咱们自己写程序出现内存泄漏的情况

1、VI部分

视频输入设备
视频输入设备支持标准 BT.656、标准 BT.1120、自定义时序等若干种时序输入,负责对时序进行解析。

视频物理通道
视频物理通道负责将输入设备解析后得到的视频数据输出到 DDR。在真正将数据输出到 DDR 之前,它可以实现裁剪、遮挡、水平垂直缩小和水平垂直翻转等功能,具体功能见各芯片的详细描述。

掩码
掩码用于指示 VI 设备的视频数据来源。

有的可以进行级联
级联指芯片的视频输出端通过 BT1120 时序或其他时序将视频数据传送到另一颗芯片的视频输入端。

根据上面那张图,AD这里就代表了一些传感器sensor,比如摄像头等,vi(video input)就是从sensor获取图像数据的一个功能模块,Hi3521DV100 芯片有 2 个 BT.1120 接口,每个 BT.1120 接口依次对应两个 VI 设备,即第一个 BT.1120 口对应 VI 的 Dev0 和 Dev1,第二个 BT.1120 口对应 VI 的 Dev2 和Dev3。所以使用两个接口时,基本用dev0和dev2。

 for(int i = 0; i < 2; i++)  // 由于这里用了两个BT1120的vi设备,所以使用dev0和dev2
 {
        ViDev = i * 2;
 }

2、VPSS

VPSS(Video Process Sub-System)支持对一幅输入图像进行统一预处理,如去噪、去隔行等,然后再对各通道分别进行缩放、锐化等处理,最后输出多种不同分辨率的图像。
VPSS有组(GRP)的概念,最大可用数为 256 个,各 GROUP 分时复用 VPSS 硬件。每个 VPSS GROUP 包含多个通道,VPSS的GROUP 只能绑定一个输入。
VPSS的GROUP 和VI的通道进行绑定,分为在线和离线模式,离线模式时VI将从摄像头读取的视频数据放入到DDR内存中,VPSS去内存中读取,在线模式时VI将从摄像头读取的视频数据直接传递给VPSS,中间没有了内存复制等的操作,节省带宽和内存,性能更好,但是在线模式,因为VI没有将数据写入到DDR,无法进行coverEx,OverlayEx,Retate,LDC等操作,需要在VPSS各通道输出后再进行处理,而且有的功能还只能在离线使用,比如DIS
VPSS的GROUP 和VI的通道进行绑定:

HI_S32 SAMPLE_COMM_VI_BindVpss(SAMPLE_VI_MODE_E enViMode)
{
    HI_S32 j, s32Ret;
    VPSS_GRP VpssGrp;
    MPP_CHN_S stSrcChn;
    MPP_CHN_S stDestChn;
    SAMPLE_VI_PARAM_S stViParam;
    VI_CHN ViChn;

// 获取VI的一些参数
    s32Ret = SAMPLE_COMM_VI_Mode2Param(enViMode, &stViParam);
    if (HI_SUCCESS !=s32Ret)
    {
        SAMPLE_PRT("SAMPLE_COMM_VI_Mode2Param failed!\n");
        return HI_FAILURE;
    }
    
    VpssGrp = 0;
    for (j=0; j<stViParam.s32ViChnCnt; j++)  //s32ViChnCnt代表VI设备的个数为1
    {
        ViChn = j * stViParam.s32ViChnInterval;
        
        //将VpssGrp和VI的通道进行绑定
        stSrcChn.enModId  = HI_ID_VIU;
        stSrcChn.s32DevId = 0;
        stSrcChn.s32ChnId = ViChn;
    
        stDestChn.enModId  = HI_ID_VPSS;
        stDestChn.s32DevId = VpssGrp;
        stDestChn.s32ChnId = 0;
    
        s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);  //源通道就是VI模块,目的通道就是VPSS的Group,绑定后,VI的视频数据就会自动流转到VPSS
        if (s32Ret != HI_SUCCESS)
        {
            SAMPLE_PRT("failed with %#x!\n", s32Ret);
            return HI_FAILURE;
        }
        
        VpssGrp ++;
    }
    return HI_SUCCESS;
}

在这里插入图片描述可以看到叠加OSD等可以在VPSS的离线模式进行
VPSS的group虽然只能绑定一个输入,但是可以有多个输出通道,这样可以获取多路不同分辨率的视频流。比如vi采集的是1080P的数据,但是有的时候不需要这么高的分辨率,想要最终获取三个不同分辨率的视频,1080P用于显示,720P用于存储,480P行车记录仪存储,这三路视频,那么VPSS就可以输出三个通道的视频数据,这个时候就可以创建3个chn
3、VENC
venc的chn绑定vpss某个group的chn

 s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);   //venc的chn绑定vpss的chn

终上所述:VI、VPSS、VENC之间的关系

VI dev的chn-》VPSS某个GRP-》VPSS某个GRP的某个chn-》VENC的某个chn
VPSS的GROUP绑定VI的chn,VENC的chn绑定VPSS某个GROUP的chn

绑定关系

系统目前支持的绑定关系,请参见表 2-1。 同一个数据接收者只能绑定一个数据源。
绑定是指数据源和数据接收者建立关联关系。绑定后,数据源生成的数据将自动发送给接收者。 VI 和 VDEC
作为数据源,是以通道为发送者,向其他模块发送数据,用户将设备号置为 0,SDK 不检查输入的设备号。 VO
作为数据源发送回写(WBC)数据时,是以设备为发送者,向其他模块发送数据,用户将通道号置为 0,SDK 不检查输入的通道号。 VPSS
作为数据接收者时,是以设备(GROUP)为接收者,接收其他模块发来的数据,用户将通道号置为 0,SDK 不检查输入的通道号。 VENC
作为数据接收者时,是以通道号为接收者,接收其他模块发过来的数据,用户应将设备号置为 0。 其他情况均需指定设备号和通道号

  • 11
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值