MPP Heap 接口说明
Mpp Heap 负责管理 mpp 中间件独占的 CMA 内存,并在 mpp 中间件需要物理内存时,将内存页面导出为 DMA-BUF。
mpp heap 特点
解决内存碎片化
CMA 内存允许多媒体模块和系统复用,在这种情况下,内存碎片化的情况不可避免(部分内存页面可能会被系统 pin 住,无法迁移)。而 mpp heap 管理的内存能确保只被 mpp 中间件使用,避免了内存页面被 pin 住而导致碎片化的问题。
-
mpp heap 的内存需要在用户态通过
/dev/dmabuf/mpp
节点来申请,这个节点是 ArtInChip 平台扩展的私有节点,只有 mpp 中间件会访问。 -
对于系统来说,该块内存已被 alloc,系统不会再去访问,因此能达到 mpp 中间件独占的效果。
只要在调用 mpp 中间件的过程中,只要做到资源的申请与释放一一对应,就能解决内存碎片化问题。
允许系统回收 mpp heap 内存
mpp heap 管理的内存通过 cma_alloc
申请,在系统内存资源紧张,而又不需要 mpp 中间件的情况下 (例如 OTA
升级),允许通过销毁 mpp heap 释放 CMA 内存给系统使用。
mpp heap 一旦销毁,无法再次初始化,只能 reboot 系统。
mpp heap init
初始化时,MPP Heap 从 CMA 内存中申请一大块物理连续内存,并创建一个 genpool 内存池进行管理。
mpp heap export
mpp heap 通过 /dev/dmabuf/mpp
节点,以 ioctl
的方式将管理的 CMA
内存导出为标准的 DMA-BUF 文件句柄。
genpool 内存池是一个基于 bitmap 的管理算法,其最小分配单位为 4K,分配的内存无论 首地址 还是 大小 ,都遵循
4K
对齐。
mpp heap close
只需要 close
DMA-BUF 的文件句柄,即触发 mpp heap 的回收 DMA-BUF。
当一块 DMA-BUF 还被多媒体模块占用时,close 操作无法触发 mpp heap 回收
mpp heap destroy
通过 /dev/dmabuf/mpp
节点,下发扩展的 ioctl
接口即可销毁 MPP Heap,
将其中的 CMA 内存归还改系统。
mpp heap 一旦被销毁,无法再次初始化,只能 reboot。
mpp heap 接口
接口如下 :
intdmabuf_device_open();voiddmabuf_device_close(intdma_fd);voiddmabuf_device_destroy(intdma_fd);intdmabuf_alloc(intdma_fd,intsize);
函数原型 | int dmabuf_device_open() |
---|---|
功能说明 | 获取 mpp heap 的文件句柄 |
参数定义 | void |
返回值 | dma_fd:成功<0:失败 |
注意事项 | - |
函数原型 | void dmabuf_device_close(int dma_fd) |
---|---|
功能说明 | 释放 mpp heap 的文件句柄 |
参数定义 | dma_fd: mpp heap 的文件句柄 |
返回值 | void |
注意事项 | - |
函数原型 | void dmabuf_device_destroy(int dma_fd) |
---|---|
功能说明 | 销毁 mpp heap |
参数定义 | dma_fd: mpp heap 的文件句柄 |
返回值 | void |
注意事项 | mpp heap 一旦被销毁,无法再次初始化,只能 reboot |
函数原型 | int dmabuf_alloc(int dma_fd, int size) |
---|---|
功能说明 | 通过 mpp heap 申请一块 DMA-BUF |
参数定义 | dma_fd: mpp heap 的文件句柄 size: DMA-BUF size |
返回值 | DMA-BUF fd:成功<0:失败 |
注意事项 | - |
mpp heap 设置
mpp heap 管理的内存必须满足视频播放的最大需求。
视频播放内存可由 video memory得到结果。
mpp heap 中的内存从 CMA 预留内存中申请,但 CMA 内存不能只为 mpp heap 预留,还需要为 其他需要物理连续内存的模块预留,主要是显示,音频和通讯模块。
注解
如果 mpp heap 的 size 或 CMA 预留内存的 size 设置不合理,不仅影响 mpp heap 初始化,还可能影响其他模块运行。
显示模块
以 fb0 为 32 位 argb8888 格式,外接分辨率为 1024x600 的 LCD 为例:
单 buffer 场景下需要 1024 * 600 * (32 / 8) = 2457600 byte, 约 2.4M
CMA
内存
双 buffer 场景下则需要 4.8M
音频模块
启用 ALSL 的场景下需要为音频模块预留 1.5M
CMA 内存
在 ALSL 加 I2S 的场景下则需要 2.5M
CMA 内存
通讯模块
WIFI, Bluetooth, USB 等通讯模块也会占用部分 CMA 内存,这个要根据实际场景进行推算。
CMA 预留内存的大小 ≥ mpp heap + 其他模块,同时 CMA 预留内存大小遵循 4M
对齐。
为确保系统正常运行,在设置 CMA 预留内存时要保有一定的余量。