Skip to main content

多媒体 · 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.shlunch <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.solibmpp_venc.solibmpp_vdec.so
    • 示例程序:sample/sample_uvc_vdec
    • 测试程序:test/ 目录下各测试可执行文件(test_venc_filetest_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_GetFrameVDEC_SendStream
选项-h--help显示帮助信息
位置参数devNodeUVC 设备节点,缺省 /dev/video0
位置参数outDir输出目录,缺省 ./nv12_output

注意:--bind 等选项为可选项,且必须位于位置参数(devNodeoutDir)之前。程序按位置顺序解析参数,一旦遇到位置参数即停止识别选项,因此 --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编码格式(支持 h264h265
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解码格式(支持 h264h265mjpeg

预期现象:

[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.hinclude/vdec.hinclude/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.cmpp/test/test_venc_file.cmpp/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硬件解码
编码延迟<50ms1080p 单帧编码

测试方法:使用 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