01 MPP媒体处理软件
1 概述
媒体处理软件平台(MediaProcessPlatform,简称MPP),可支持应用软件快速开发。该平台对应用软件屏蔽了芯片相关的复杂的底层处理,并对应用软件直接提供MPI(MPPProgramInterface)接口完成相应功能。该平台支持应用软件快速开发以下功能:输入视频捕获、H.265JPEG编码、H265解码、视频输出显示、视频图像前处理(包括去噪、增强、锐化)、图像几何矫正、图像拼接、黑白图像融合、图像防抖、音频捕获及输出、音频编解码等功能。
1.1 MPP架构
MPP架构自下而上分为硬件层、操作系统层、操作系统适配层、媒体处理平台、其他驱动及应用层,如下图所示。

- 硬件层:由芯片及必要的外围器件构成,包括 Flash、DDR、视频 Sensor 或 AD、音频 AD 等。
- 操作系统层:基于 Linux 的 OS 系统。
- 操作系统适配层:提供操作系统系统调用基础函数,屏蔽操作系统差异,支持媒体处理平台运行在不同操作系统或不同版本上。
- 媒体处理平台(MPP):基于操作系统适配层,控制芯片完成相应的媒体处理功能。它对应用层屏蔽了硬件处理细节,并为应用层提供 API 接口。
- 其他驱动:除媒体处理平台外,提供其他硬件处理单元相应的驱动,如 CIPHER、RTC 等驱动。
- 应用层:基于媒体处理平台及其他驱动,由用户开发的应用软件系统。
1.2 MPP视频流
说明
本文档中出现的“VI在线/离线”是指VI_CAP与VI_PROC之间的在线/离线模式。 本文档中出现的“VPSS在线/离线”是指VI_PROC与VPSS之间的在线/离线模式。 本文档中出现的“GDC在线/离线”是指GDC与VPSS之间的在线/离线模式 VI_PROC与GDC之间固定为离线模式。
MPP视频流如下图所示:

- VI_CAP模块:通过MIPI协议获取sensor原始图像数据
- VI_PROC模块:对原始图像数据做剪切、去噪等处理,并输出多路不同分辨率的图像数据
- GDC模块: 对图像做几何变换,比如鱼眼校正、镜头畸变校正、旋转、透视变换等(为可选项)
- VPSS模块:接收VI、GDC和VDEC模块发送过来的图像,可对图像进行图像增强、锐化拼接等处理,可实现同源输出多路不同分辨率的图像数据
- 编码模块:接收VPSS处理后输出的图像数据,按不同协议进行编码并输出相应码流。
- VO模块:接收VPSS处理后的输出图像,可进行播放控制等处理,按用户配置的输出协议输出给外围视频设备。
pipe模式配置注意事项
- 对任意pipe,GDC和VPSS不能同时处于在线模式
- 仅pipe0支持VI在线模式
- 当pipe0处于VI离线模式时,其余pipe的GDC模式和VPSS模式必须和pipe0的GDC模式和VPSS模式保持一致
2 系统控制模块
系统控制根据芯片特性,完成系统基本初始化工作,同时负责管理MPP(MediaProcessPlatform媒体处理平台)系统各个业务模块的异常退出、提供当前MPP系统的版本信息、提供绑定功能、提供大块物理内存管理、提供模块的OST与QOS值配置等功能。
2.1 SYS模块初始化与去初始化
SYS模块初始化用于指定pipe中各模块之间的工作模式,任何MPP业务在运行前,必须先进行系统初始化;在业务结束后,必须进行系统去初始化以释放资源。示例如下(所需头文件:xmedia_sys.h):
xmedia_s32 mpp_sys_init()
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret=xmedia_sys_exit();
if(ret!=XMEDIA_SUCCESS)
{
printf("xmedia_sys_exit failed !\n");
return ret;
}
xmedia_sys_config sys_config={0};
/*
|注意:
| 1. 对任意pipe,GDC和VPSS不能同时处于在线模式
| 2. 仅pipe0支持VI在线模式
| 3. 当pipe0处于VI离线模式时,其余pipe的GDC模式和VPSS模式必须和pipe0的GDC模式和VPSS模式保持一致
*/
sys_config.pipe_mode[0].vicap_viproc_mode = XMEDIA_WORK_MODE_ONLINE;
sys_config.pipe_mode[0].viproc_vpss_mode = XMEDIA_WORK_MODE_ONLINE;
sys_config.pipe_mode[0].gdc_vpss_mode =XMEDIA_WORK_MODE_OFFLINE;
ret=xmedia_sys_init(&sys_config);
if(ret!=XMEDIA_SUCCESS)
{
printf("xmedia_sys_init failed !\n");
return ret;
}
else
{
printf("xmedia_sys_init success !\n");
return XMEDIA_SUCCESS;
}
}使用注意事项
单进程时,如果多次初始化,仍会返回成功,但实际上不会对MPP的运行状态有任何影响,第一次有效配置为配置结果。若要更改初始化配置,需要调
xmedia_sys_exit后进行。多进程时,每个进程都需要进行初始化操作,只支持一种有效配置(输入参数非空)。若a进程已进行初始化操作且输入参数非空时,其他进程初始化操作的输入参数必须和a进程的一致或者为空;若a进程已进行初始化操作且输入参数为空时,对其他进程的初始化操作没有影响。
同一数据通路上VI和VPSS的pipe号必须一致。
2.2 视频缓存池(VB)管理
视频缓存池主要向媒体业务提供大块物理内存管理功能,负责内存的分配和回收,充分发挥缓存池的作用,让物理内存资源在各个媒体处理模块中合理使用。一组大小相同、物理地址连续的缓存块组成一个视频缓存池。必须在MPP业务之前配置公共视频缓存池。根据业务的不同,公共缓存池的数量、缓存块的大小和数量不同。
公共缓存池配置:
系统支持配置多个公共缓存池,每个缓存池包含若干个大小相同的缓存块。配置时可通过
xmedia_vb_cfg结构体中的commont_pool成员指定缓存池的个数以及每个缓存池的块大小和块数量。- 块大小:需根据业务中最大分辨率图像的尺寸及像素格式计算,可通过
xmedia_vb_get_buffer_config获取。 - 块数量:需根据并发业务路数评估,数量不足会导致获取缓存块失败,数量过多则浪费内存。
- 块大小:需根据业务中最大分辨率图像的尺寸及像素格式计算,可通过
模块私有缓存池: 除公共缓存池外,部分模块(如ISP、VDEC)也支持配置模块私有缓存池,用于特定业务场景的优化,可通过
xmedia_vb_cfg结构体中的supplement_config成员进行配置。缓存块获取与释放:
- 获取:
xmedia_mpi_vb_get_block,从指定公共缓存池中获取一个空闲块。 - 释放:
xmedia_mpi_vb_release_block,使用完毕后必须释放缓存块,否则会导致缓存池耗尽。
- 获取:
说明
因为其他模块依赖公共缓存池,所以在其他模块初始化之前需要执行vb初始化(在sys的初始化之后调用)。可多次调用,返回成功,但只有第一次的配置信息生效。
xmedia_s32 mpp_vb_init()
{
xmedia_s32 ret = XMEDIA_SUCCESS;
ret = xmedia_vb_exit();
if(ret!=XMEDIA_SUCCESS)
{
printf("xmedia_vb_exit failed !\n");
return ret;
}
xmedia_vb_config vb_config={0};//必须先将配置置0,否则会出现随机非零配置,从而出现非法配置,导致vb池初始化失败
/*
#define XMEDIA_VB_SUPPLEMENT_ISP_INFO_ENABLE 1
#define XMEDIA_VB_SUPPLEMENT_VDEC_INFO_ENABLE (1 << 1)
supplement_config: 补充内存池配置,bit[0] 和bit[1]有效,其余为非法值。
bit[0]: 1表示打开ISP的内存申请开关,0表示关闭;
bit[1]: 1表示打开VDEC的内存申请开关,0表示关闭。
*/
vb_config.supplement_config=XMEDIA_VB_SUPPLEMENT_ISP_INFO_ENABLE|XMEDIA_VB_SUPPLEMENT_VDEC_INFO_ENABLE;
vb_config.max_pool_cnt = 25;//最大内存池数量
xmedia_vb_base_info vb_base_info = {0};
vb_base_info.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;//视频存储格式
vb_base_info.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422;//像素格式
vb_base_info.cmp_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;//图像压缩模式
vb_base_info.bit_width = XMEDIA_VIDEO_DATA_WIDTH_8;//数据宽度
vb_base_info.width = 1920;//宽度
vb_base_info.height = 1080;//高度
vb_base_info.align = DEFAULT_ALIGN;//对齐方式
vb_base_info.ainr_attr.ainr_en = XMEDIA_FALSE;//AINR失能
xmedia_vb_cal_cfg vb_cal_cfg = {0};
xmedia_vb_get_buffer_config(&vb_base_info,&vb_cal_cfg);//计算块大小
vb_config.common_pool[0].block_size = vb_cal_cfg.vb_size;//块大小-视频图像帧总大小
vb_config.common_pool[0].block_cnt = 3;//块数量
vb_config.common_pool[0].map_mode = XMEDIA_VB_MAP_MODE_NONE;//VB的内核态虚拟地址映射模式
/* mmz_name保持全0时,默认从anonymous的mmz zone创建pool */
ret = xmedia_vb_init(&vb_config);
if(ret!=XMEDIA_SUCCESS)
{
printf("xmedia_vb_init failed, ret = 0x%x !\n", ret);
return ret;
}
else
{
printf("xmedia_vb_init success !\n");
return XMEDIA_SUCCESS;
}
}2.3 绑定机制
MPP支持模块绑定机制,即通过绑定接口xmedia_sys_bind,通过数据接收者绑定数据源来建立两者之间的关联关系(只允许数据接收者绑定数据源)。绑定后,数据源生成的数据将自动发送给接收者,从而无需应用层频繁干预。MPP所支持的绑定关系如下表所示:
| ---------------------数据源--------------------- | ---------------------数据接收者--------------------- |
|---|---|
| VI | VPSS / MCF |
| MCF | VPSS |
| VPSS | VO / VENC |
| VDEC | VPSS / VO |
所需头文件和库
头文件:common.h、xmedia_sys.h
库文件:libxmedia_common.a
- 绑定API:
//建立绑定:
xmedia_s32 xmedia_sys_bind(const xmedia_chn_info *src_chn,const xmedia_chn_info *dest_chn);
//解除绑定:
xmedia_s32 xmedia_sys_unbind(const xmedia_chn_info *src_chn,const xmedia_chn_info *dest_chn);注意
同一个数据接收者只能绑定一个数据源。
VI和VDEC作为数据源,是以通道为发送者,向其他模块发送数据,用户将设备号置为0,SDK不检查输入的设备号。其他情况均需指定设备号和通道号。
