多媒体 · MPP
1. 模块概述
- 主要功能:MPP(Media Processing Platform)是 SPACEMIT 媒体处理平台,提供视频编解码、视频输入输出、图像处理等核心能力,支持 H.264/H.265 编解码、JPEG 编解码、视频采集、显示输出等功能
- 规格或特性:
- 视频编码:支持 H.264/H.265/JPEG 编码,最高 4K@30fps
- 视频解码:支持 H.264/H.265/JPEG 解码,最高 4K@60fps
- 视频输入(VI):支持 MIPI CSI、USB UVC 等接口
- 视频输出(VO):支持 HDMI、MIPI DSI 等接口
- 图像处理(V2D):支持格式转换、缩放、旋转等
- 封装/解封装:支持 MP4、RTSP 等协议
- 相关目录结构:
mpp/
├── include/ # 对外头文件
│ ├── venc.h # 视频编码 API
│ ├── vdec.h # 视频解码 API
│ ├── vi/ # 视频输入 API
│ ├── vo/ # 视频输出 API
│ ├── v2d/ # 图像处理 API
│ └── sys/ # 系统管理 API
├── mpi/ # MPI 实现层
│ ├── venc/ # 编码器实现
│ ├── vdec/ # 解码器实现
│ ├── vi/ # 视频输入实现
│ └── ...
├── al/ # 抽象层(模块插件)
├── utils/ # 工具库
├── sample/ # 示例程序
├── test/ # 测试程序
└── CMakeLists.txt # 构建配置
2. 环境准备
前置条件
- 运行环境:Linux 内核、CMake ≥ 3.16、gcc/g++ 编译器(支持 C11/C++14)
- 依赖与外部资源:
- 硬件编解码器驱动(内核模块)
- 第三方库:可选 FFmpeg、live555(用于 RTSP)
- 环境变量与初始化:通过 SDK 编译需先执行
source build/envsetup.sh并lunch <target> - 硬件与连接:SPACEMIT K1 芯片或兼容平台,摄像头(MIPI/USB)、显示器(HDMI/MIPI)
- 工具与权限:访问
/dev/video*等设备节点需相应权限
构建编译
-
获取代码:
SDK 源码获取和基础编译环境配置参考2.3-构建编译。完成 SDK 初始化后,回到本文继续执行
后续命令默认在 spacemit_robot SDK 根目录执行。
-
本模块编译:
source build/envsetup.sh
cd components/multimedia/mpp
mm
- 产物:
- 库文件:
libmpp.so、libmpp_venc.so、libmpp_vdec.so等 - 示例程序:
sample/sample_uvc_vdec - 测试程序:
test/目录下各测试可执行文件(test_venc_file、test_vdec_file等)
- 库文件:
3. 示例使用(从 0 跑通)
3.1 USB 摄像头采集与解码
前置:已编译 MPP,USB 摄像头已连接
步骤 1:确认摄像头设备
ls /dev/video*
预期现象:显示 /dev/video0 等设备节点
步骤 2:运行 UVC 采集解码示例
cd output/build/cmake/pkgs/components_multimedia_mpp/sample
# 指定 UVC 设备节点(步骤 1 中确认的节点)和输出目录
./sample_uvc_vdec /dev/video0 ./nv12_output
参数说明(命令格式:./sample_uvc_vdec [选项] [devNode] [outDir]):
| 类型 | 参数 | 说明 |
|---|---|---|
| 选项 | --bind | 使用 SYS_Bind 模式(UVC→VDEC 自动传输码流);缺省为手动模式(UVC_GetFrame → VDEC_SendStream) |
| 选项 | -h、--help | 显示帮助信息 |
| 位置参数 | devNode | UVC 设备节点,缺省 /dev/video0 |
| 位置参数 | outDir | 输出目录,缺省 ./nv12_output |
注意:
--bind等选项为可选项,且必须位于位置参数(devNode、outDir)之前。程序按位置顺序解析参数,一旦遇到位置参数即停止识别选项,因此--bind若写在设备节点之后会被误当作设备节点路径。
用法示例:
./sample_uvc_vdec # 手动模式,使用默认设备与目录
./sample_uvc_vdec --bind # bind 模式,使用默认设备与目录
./sample_uvc_vdec /dev/video0 ./nv12_output # 手动模式,自定义设备与目录
./sample_uvc_vdec --bind /dev/video0 ./nv12_output # bind 模式,自定义设备与目录
预期现象:程序采集 USB 摄像头视频流并解码显示,输出帧率和分辨率信息
3.2 视频编码示例(文件到文件)
使用 test_venc_file 将 YUV 原始帧编码为 H.264 码流。
前置:见 §2
步骤 1:进入测试程序目录
cd output/build/cmake/pkgs/components_multimedia_mpp/test
步骤 2:运行编码测试
./test_venc_file ../../../../../../components/multimedia/mpp/test/assets/vi_phy0_last_frame.yuv 1920 1080 ./enc_out.h264 h264 1
参数说明:
| 参数 | 含义 |
|---|---|
| ../../../../../../components/multimedia/mpp/test/assets/vi_phy0_last_frame.yuv | 输入 YUV 文件路径 |
1920 | 图像宽度 |
1080 | 图像高度 |
./enc_out.h264 | 输出码流文件路径 |
h264 | 编码格式(支持 h264、h265) |
1 | 编码帧数 |
预期现象:
[INFO] VENC file test: ../../../../../../components/multimedia/mpp/test/assets/vi_phy0_last_frame.yuv 1920x1080 -> ./enc_out.h264 (H.264), frames=1
[INFO] encoded frame 0: size=63778 key=0 pts=0
[INFO] done, encoded 1 frame(s)
编码完成后在当前目录生成 enc_out.h264 文件,可使用 ffplay enc_out.h264 验证。
3.3 视频解码示例(文件到文件)
使用 test_vdec_file 将压缩码流解码为 YUV 原始帧。
前置:见 §2
步骤 1:进入测试程序目录
cd output/build/cmake/pkgs/components_multimedia_mpp/test
步骤 2:运行解码测试(以 MJPEG 为例)
./test_vdec_file ../../../../../../components/multimedia/mpp/test/assets/1920x1080.jpg 1920 1080 ./dec_out_nv12.yuv mjpeg
参数说明:
| 参数 | 含义 |
|---|---|
../../../../../../components/multimedia/mpp/test/assets/1920x1080.jpg | 输入码流文件路径 |
1920 | 图像宽度 |
1080 | 图像高度 |
./dec_out_nv12.yuv | 输出 YUV 文件路径 |
mjpeg | 解码格式(支持 h264、h265、mjpeg) |
预期现象:
[INFO] VDEC file test: ../../../../../../components/multimedia/mpp/test/assets/1920x1080.jpg -> ./dec_out_nv12.yuv, codec=mjpeg, size=105692
[INFO] decoded frame: 1920x1080 planes=2 stride=1920 pts=0
解码完成后在当前目录生成 dec_out_nv12.yuv 文件,可使用以下命令验证:
ffplay -f rawvideo -pix_fmt nv12 -s 1920x1080 dec_out_nv12.yuv
4. 应用开发
-
对外 API 或接口形态:
- 头文件:
include/venc.h、include/vdec.h、include/vi/、include/vo/等 - 库名:
libmpp.so及各子模块库 - 主要 API:
- 编码:
venc_ctx_create()、venc_ctx_init()、venc_ctx_encode()、venc_ctx_destroy() - 解码:
vdec_ctx_create()、vdec_ctx_init()、vdec_ctx_decode()、vdec_ctx_destroy() - 视频输入:VI 模块 API
- 视频输出:VO 模块 API
- 编码:
- 头文件:
-
调用方式与注意点:
- 初始化顺序:先创建上下文,再初始化,最后设置参数
- 线程安全:单个上下文不支持多线程并发,需上层加锁
- 内存管理:输入输出 buffer 需使用 MPP 提供的内存分配接口
- 资源释放:使用完毕后必须按顺序释放资源(先停止,再销毁上下文)
- 硬件加速:编解码自动使用硬件加速,无需额外配置
-
参考 demo 或示例路径:
mpp/sample/sample_uvc_vdec.c、mpp/test/test_venc_file.c、mpp/test/test_vdec_file.c
5. 调试指南
- 内核日志:
dmesg | grep -E "vpu|codec|MPP"查看硬件编解码器日志 - 设备节点:
ls -l /dev/video*确认视频设备 - 性能分析:使用
time命令测量编解码耗时 - 帧率统计:在代码中添加时间戳计算实际帧率
6. 常见问题
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 编码初始化失败 | 硬件编码器插件未加载 | 检查libv4l2_linlonv5v7_codec2.so是否存在 |
| 解码花屏 | 码流格式不支持或损坏 | 确认码流格式,使用标准测试码流 |
| 帧率低 | CPU 负载高或内存带宽不足 | 优化代码,减少内存拷贝 |
| 设备节点不存在 | 摄像头未连接或驱动未加载 | 检查硬件连接,加载驱动模块 |
附录:性能与测试数据
| 指标 | 数值 | 测试条件 |
|---|---|---|
| H.264 编码性能 | 1080p@30fps | 硬件编码,码率 4Mbps |
| H.265 编码性能 | 1080p@30fps | 硬件编码,码率 2Mbps |
| H.264 解码性能 | 4K@60fps | 硬件解码 |
| 编码延迟 | <50ms | 1080p 单帧编码 |
测试方法:使用 MPP 测试程序在 SPACEMIT K3 平台测试,Linux 内核 5.10,硬件编解码器。测试命令:
cd output/build/cmake/pkgs/components_multimedia_mpp/test
# 编码测试
./test_venc_file ../../../../../../components/multimedia/mpp/test/assets/vi_phy0_last_frame.yuv 1920 1080 ./enc_out.h264 h264 1
# 解码测试
./test_vdec_file ../../../../../../components/multimedia/mpp/test/assets/1920x1080.jpg 1920 1080 ./dec_out_nv12.yuv mjpeg