RK3588 视频编解码(MPP)
文档版本: V1.0 适用系统: Linux 6.1(Debian 12 / Ubuntu 22.04) 适用硬件: RK3588(C-3588LQ V1.0 核心板 + SHIMETAPI-M5-R2A V1.0 底板) 更新日期: 2026-08-19
1. 概述
1.1 功能简介
RK3588 搭载 Rockchip MPP(Media Process Platform,媒体处理平台)硬件编解码引擎,支持 8K 级别视频的硬件加速解码与多路编码。MPP 是瑞芯微提供的编解码中间件:应用程序调用它的用户态库,库再去驱动芯片内置的硬件编解码单元,CPU 全程不用逐像素计算。RK3588 里负责编解码的硬件单元有两个:
| 模块 | 寄存器基地址 | 功能 |
|---|---|---|
| rkvdec2 | fe610000 | 视频解码器,支持 H.264/H.265/VP9/AV1 |
| rkvenc | fe640000 | 视频编码器,支持 H.264/H.265 |
编解码能力如下:
| 编解码类型 | 分辨率/帧率 | 说明 |
|---|---|---|
| H.264 解码 | 8K@30fps / 4K@120fps | 最高支持 8K@30 或 4K@120 |
| H.265 解码 | 8K@60fps | 支持 8K@60 流畅解码 |
| VP9 解码 | 8K@30fps | Google VP9 格式 |
| AV1 解码 | 8K@30fps | 新一代开放格式 |
| H.264 编码 | 4K@60fps | 高帧率编码 |
| H.265 编码 | 4K@30fps | 高压缩率编码 |
其他核心特性包括:多路并行编解码、低延迟模式、硬件后处理(去块、色彩空间转换)、DRM/GBM Buffer 支持,以及 NV12/NV21/YUV420P 等多种像素格式。用户态通过 MPP 库 librockchip_mpp.so 调用这些硬件。
1.2 应用场景
| 应用场景 | 使用的编解码能力 | 说明 |
|---|---|---|
| 智能安防监控 | 多路解码 + 编码 | 同时解码多路摄像头流并编码存储 |
| 视频会议终端 | H.264/H.265 编解码 | 实时双向视频通话 |
| 8K 媒体播放 | H.265/VP9 解码 | 8K 超高清视频播放 |
| 视频转码服务器 | 编码 + 解码 | 格式转换与转码服务 |
| AI 视频分析 | 解码 + 后处理 | 视频帧提取用于 AI 推理 |
1.3 工作原理
┌─────────────────────────────────┐
│ RK3588 MPP 架构 │
└─────────────────────────────────┘
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ 视频输入 │────>│ rkvdec2 │────>│ MPP 框架 │
│ (编码流) │ │ 硬件解码器 │ │ (用户态库) │
└──────────┘ │ fe610000 │ └──────┬───────┘
│ H.264/H.265│ │
│ VP9/AV1 │ │
└──────────────┘ ┌──────┴───────┐
│ │
┌──────────┐ ┌──────────────┐ │ 应用程序 │
│ 视频输出 │<────│ rkvenc │<────│ │
│ (编码流) │ │ 硬件编码器 │ └──────────────┘
└──────────┘ │ fe640000 │
│ H.264/H.265│
└──────────────┘2. 硬件准备
2.1 硬件清单
| 序号 | 硬件名称 | 型号/规格 | 说明 |
|---|---|---|---|
| 1 | 核心板 | C-3588LQ V1.0 | RK3588 主芯片,含 VPU 编解码单元 |
| 2 | 底板 | SHIMETAPI-M5-R2A V1.0 | 扩展接口底板 |
| 3 | 电源 | 12V/5A DC | 至少 60W 供电 |
| 4 | HDMI 输出 | HDMI 2.1 线缆 | 用于显示输出 |
| 5 | 存储 | eMMC 32GB+ 或 TF 卡 | 用于系统和测试码流 |
| 6 | 串口调试 | USB 转串口线 | 用于串口调试 |
| 7 | 网线 | 千兆网线 | 用于网络传输和 SSH |
2.2 硬件确认
上电进入系统后,用下面的命令确认芯片、内核和编解码设备都就位,预期输出写在注释里:
# 确认 RK3588 芯片
cat /proc/device-tree/model
# 确认内核版本(应为 6.1)
uname -r
# 确认解码器设备节点
ls /dev/video*
# 查看 MPP 相关内核模块
lsmod | grep mpp
# 预期看到 rkvdec2, rkvenc 等模块
# 确认设备树中的 VPU 节点
cat /proc/device-tree/vpu@fe610000/compatible
# 预期输出: rockchip,rkvdec2
cat /proc/device-tree/vpu@fe640000/compatible
# 预期输出: rockchip,rkvenc3. 软件准备
3.1 内核配置项
自己编译内核时,需要确认以下配置已启用:
# MPP 相关配置
CONFIG_ROCKCHIP_MPP=y
CONFIG_ROCKCHIP_VCODEC=y
CONFIG_ROCKCHIP_RKVDEC2=y
CONFIG_ROCKCHIP_RKVENC=y
# V4L2 相关配置
CONFIG_V4L2_VIDEODEV=y
CONFIG_V4L2_MEM2MEM=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
# DMA-BUF 相关配置
CONFIG_DMABUF=y
CONFIG_DMA_BUF_SYNC=y
CONFIG_DMABUF_HEAPS=y
CONFIG_DMABUF_HEAPS_ROCKCHIP=y3.2 设备树配置
解码器和编码器在设备树中的节点定义如下:
/* 解码器节点 */
vpu@fe610000 {
compatible = "rockchip,rkvdec2";
reg = <0x0 0xfe610000 0x0 0x10000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_VDEC>, <&cru HCLK_VDEC>,
<&cru ACLK_VDEC_NIU>, <&cru HCLK_VDEC_NIU>;
clock-names = "axi", "ahb", "noc", "h264";
resets = <&cru SRST_A_VDEC>, <&cru SRST_H_VDEC>;
reset-names = "axi", "ahb";
power-domains = <&power RK3588_PD_VDEC>;
status = "okay";
};
/* 编码器节点 */
vpu@fe640000 {
compatible = "rockchip,rkvenc";
reg = <0x0 0xfe640000 0x0 0x10000>;
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_VENC>, <&cru HCLK_VENC>,
<&cru CLK_VENC_CORE>;
clock-names = "axi", "ahb", "core";
resets = <&cru SRST_A_VENC>, <&cru SRST_H_VENC>;
reset-names = "axi", "ahb";
power-domains = <&power RK3588_PD_VENC>;
status = "okay";
};3.3 MPP 库安装
先检查系统里有没有 MPP 库,没有再从源码编译安装:
# 方法1:使用预编译库(推荐)
ls /usr/lib/librockchip_mpp.so*
ldconfig -p | grep rockchip_mpp
# 方法2:从源码编译安装
git clone https://github.com/rockchip-linux/mpp.git
cd mpp/build/linux/aarch64/
./make-Makefiles.bash
make -j$(nproc)
sudo cp librockchip_mpp.so* /usr/lib/
sudo cp librockchip_mpp_*.so* /usr/lib/
sudo ldconfig
# 确认安装
ls -la /usr/lib/librockchip_mpp*3.4 ffmpeg 编译(带 MPP 硬件加速)
要让 ffmpeg 走 MPP 硬件加速,需要编译带 rkmpp 支持的 Rockchip 定制版 ffmpeg:
# 获取 Rockchip 定制 ffmpeg 源码
git clone https://github.com/rockchip-linux/ffmpeg.git
cd ffmpeg
./configure \
--enable-rkmpp \
--enable-libdrm \
--enable-gpl \
--enable-nonfree \
--prefix=/usr/local
make -j$(nproc)
sudo make install
# 验证 rkmpp 支持
ffmpeg -hwaccels 2>&1 | grep rkmpp
ffmpeg -encoders 2>&1 | grep rkmpp
# 预期看到 h264_rkmpp, hevc_rkmpp4. 操作步骤
4.1 MPP 测试工具编译
先看看测试工具是否已经就位:
# 出厂镜像已预装全套工具,无需编译!
which mpi_dec_test mpi_enc_test mpp_info_test
# /usr/bin/mpi_dec_test
# /usr/bin/mpi_enc_test
# /usr/bin/mpp_info_test
mpp_info_test | head -3
# 输出(MPP 版本 520ab553, 2025-12-16):
# mpp_info_test: normal version log:
# mpp_info: mpp version: 520ab553 author: Herman Chen 2025-12-16 ...
# 如需从源码构建(二次开发时):
git clone https://github.com/rockchip-linux/mpp.git
cd mpp && mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DROCKCHIP_MPP=ON
make -j$(nproc)4.2 解码测试
解码用 mpi_dec_test,关键是 -t 后面的编码类型 ID,注意和原文不同:
# ⚠ 勘误:-t 的编码类型 ID 与原文不同!
# 直接跑 mpi_dec_test(无参数)会打印完整 coding type 表,本机:
# mpeg2=2 mpeg4=4 h.263=3 h.264/AVC=7 h.265/HEVC=16777220
# vp8=9 jpeg=8 av1=16777224
# H.264 解码(-t 7)
mpi_dec_test -t 7 -i test.h264 -o output.yuv
# H.265 解码(-t 16777220)
mpi_dec_test -t 16777220 -i test.h265 -o output.yuv
# AV1 解码(-t 16777224)
mpi_dec_test -t 16777224 -i test.av1 -o output.yuv
# 指定分辨率输出
mpi_dec_test -t 7 -i test.h264 -o output.yuv -w 3840 -h 2160用出厂自带的 200 帧 H.264 测试流
mpi_dec_test -t 7 -i /oem/200frames_count.h264 -n 200mpp: decode get frame 199
mpp: decode 200 frames time 77 ms delay 5 ms fps 2586.79
mpp: test success max memory 5.27 MB对照同一流用 ffmpeg(apt 5.1.9,纯 CPU 软解)耗时 0.24s,约 833 FPS;MPP 硬解 77ms,约 2586 FPS,是软解的 3.1 倍,而且完全不占 CPU。
4.3 编码测试
编码用 mpi_enc_test,参数含义都写在注释里:
# 勘误:-t 7 = H.264(不是 1);-t 16777220 = H.265(不是 2)
# 编码器支持: h264=7 jpeg=8 h265=16777220 vp8=9
# H.264 编码(-f 0 表示 NV12 输入)
mpi_enc_test -t 7 -w 1280 -h 720 -f 0 -n 30 -i input.nv12 -o output.h264
# H.265 编码
mpi_enc_test -t 16777220 -w 1920 -h 1080 -f 0 -i input.nv12 -o output.h265
# 参数说明(mpi_enc_test -h 输出):
# -t 输出流编码类型(7/16777220/8/9)
# -f 0 输入格式 0=NV12
# -rc 码控模式 0:vbr 1:cbr 2:fixqp 3:avbr 4:smtrc
# -bps 目标:最小:最大 码率
# -w/-h 宽度/高度 -i/-o 输入/输出 -n 最大帧数下面用 720p NV12 30 帧做 H.264 编码,再把编出的流回环解码,验证编解码一致性:
mpi_enc_test -t 7 -w 1280 -h 720 -f 0 -n 30 -i /var/tmp/test720.nv12 -o /var/tmp/out720.h264mpp: chn 0 encoded frame 29 size 209550 qp 42 bps_rt 19423577 psnr 33.3447
mpp: chn 0 encode 30 frames time 182 ms delay 4 ms fps 164.52 bps 52481240
mpp: mpi_enc_test average frame rate 164.52
# 产物 6.5MB
# 回环:把刚编的流再硬解,验证编解码一致性
mpi_dec_test -t 7 -i /var/tmp/out720.h264
# mpp: decode 30 frames time 481 ms delay 38 ms fps 62.27
# mpp: test success max memory 3.52 MB4.4 多路编解码
多路解码有两种做法:多进程并行,或者单进程多实例:
#!/bin/bash
# multi_decode.sh - 多路并行解码
STREAMS=("stream1.h265" "stream2.h265" "stream3.h265")
OUTPUTS=("out1.yuv" "out2.yuv" "out3.yuv")
for i in "${!STREAMS[@]}"; do
mpi_dec_test -t 7 -i "${STREAMS[$i]}" -o "${OUTPUTS[$i]}" &
done
wait
echo "All decoding finished"
# 或者单进程多实例:-s 4 开 4 个解码实例
mpi_dec_test -t 7 -i /oem/200frames_count.h264 -n 200 -s 4
# decode 200 frames time 70 ms delay 4 ms fps 2837.40
# test success max memory 5.27 MB4.5 ffmpeg 集成
ffmpeg -hide_banner -hwaccels # 输出: vdpau cuda vaapi drm opencl ← 没有 rkmpp ffmpeg -encoders | grep rkmpp # 无结果出厂的 apt 版 ffmpeg 没有 rkmpp 支持,要用 ffmpeg+rkmpp 必须自编译(ffmpeg 源码 + rkmpp 补丁,参考 Rockchip ffmpeg-rk 仓库),工程量大。出厂镜像开箱即用的硬件编解码路径有两条:
mpi_dec_test / mpi_enc_test(本文件 4.2/4.3,通过)- GStreamer
mpph264enc / mppvideodec(见下,通过)
# 自编译 rkmpp 版 ffmpeg 后可用:
ffmpeg -hwaccel rkmpp -i input.h265 -f rawvideo output.yuv
ffmpeg -f rawvideo -pix_fmt yuv420p -video_size 1920x1080 \
-i input.yuv -c:v h264_rkmpp -b:v 10M output.h264
# 出厂可用的等价命令(GStreamer,720p×300 帧 1.03s ≈ 291FPS):
gst-launch-1.0 -e videotestsrc num-buffers=300 \
! video/x-raw,width=1280,height=720,format=NV12 \
! mpph264enc ! h264parse ! qtmux ! filesink location=out.mp44.6 视频转码
前提同 4.5:本节命令依赖自编译的 rkmpp 版 ffmpeg(apt 版没有 rkmpp)。出厂可用的替代方案是 GStreamer mpp 元件或 mpi_enc/dec_test。
# H.265 -> H.264 转码
ffmpeg -hwaccel rkmpp -i input.h265 -c:v h264_rkmpp -b:v 8M output.h264
# 4K -> 1080p 降分辨率转码
ffmpeg -hwaccel rkmpp -i input_4k.mp4 -vf scale=1920:1080 \
-c:v h264_rkmpp -b:v 5M -c:a copy output_1080p.mp4
# 批量转码脚本
#!/bin/bash
for f in *.mp4; do
ffmpeg -hwaccel rkmpp -i "$f" -c:v h264_rkmpp -b:v 8M -c:a copy "${f%.mp4}_h264.mp4"
done4.7 Python 使用示例
这个类在出厂镜像上会立即抛出
RuntimeError: ffmpeg 未编译 rkmpp 支持(构造函数检查失败,apt 版 ffmpeg 无 rkmpp)。需先自编译 rkmpp 版 ffmpeg;_probe()的 ffprobe 部分装 apt ffmpeg 后可用。
#!/usr/bin/env python3
"""RK3588 MPP 视频编解码 Python 封装"""
import subprocess
import os
import time
import json
class RK3588Codec:
def __init__(self):
result = subprocess.run(["ffmpeg", "-hwaccels"], capture_output=True, text=True)
if "rkmpp" not in result.stdout:
raise RuntimeError("ffmpeg 未编译 rkmpp 支持")
print("rkmpp 硬件加速:已支持")
def decode(self, input_file, output_file):
"""硬件解码视频文件"""
cmd = ["ffmpeg", "-y", "-hwaccel", "rkmpp", "-i", input_file,
"-f", "rawvideo", "-pix_fmt", "yuv420p", output_file]
start = time.time()
result = subprocess.run(cmd, capture_output=True, text=True)
elapsed = time.time() - start
if result.returncode != 0:
raise RuntimeError(f"解码失败:\n{result.stderr}")
info = self._probe(input_file)
info["decode_time"] = elapsed
return info
def encode(self, input_yuv, output_file, width, height,
codec="h264_rkmpp", bitrate="8M", fps=30):
"""硬件编码 YUV 数据"""
cmd = ["ffmpeg", "-y", "-f", "rawvideo", "-pix_fmt", "yuv420p",
"-video_size", f"{width}x{height}", "-framerate", str(fps),
"-i", input_yuv, "-c:v", codec, "-b:v", bitrate, output_file]
start = time.time()
result = subprocess.run(cmd, capture_output=True, text=True)
elapsed = time.time() - start
if result.returncode != 0:
raise RuntimeError(f"编码失败:\n{result.stderr}")
return {"encode_time": elapsed, "file_size": os.path.getsize(output_file)}
def transcode(self, input_file, output_file,
codec="h264_rkmpp", bitrate="8M", scale=None):
"""硬件转码视频文件"""
cmd = ["ffmpeg", "-y", "-hwaccel", "rkmpp", "-i", input_file,
"-c:v", codec, "-b:v", bitrate, "-c:a", "copy"]
if scale:
cmd.extend(["-vf", f"scale={scale[0]}:{scale[1]}"])
cmd.append(output_file)
start = time.time()
result = subprocess.run(cmd, capture_output=True, text=True)
elapsed = time.time() - start
if result.returncode != 0:
raise RuntimeError(f"转码失败:\n{result.stderr}")
return {"transcode_time": elapsed}
@staticmethod
def _probe(filepath):
cmd = ["ffprobe", "-v", "quiet", "-print_format", "json",
"-show_format", "-show_streams", filepath]
result = subprocess.run(cmd, capture_output=True, text=True)
try:
info = json.loads(result.stdout)
for s in info.get("streams", []):
if s.get("codec_type") == "video":
return {"width": s.get("width"), "height": s.get("height"),
"codec": s.get("codec_name")}
except (json.JSONDecodeError, ValueError):
pass
return {}
if __name__ == "__main__":
codec = RK3588Codec()
print("=== 解码示例 ===")
r = codec.decode("input.h265", "output.yuv")
print(f" {r.get('width')}x{r.get('height')}, 耗时: {r['decode_time']:.2f}s")
print("=== 编码示例 ===")
r = codec.encode("input.yuv", "output.h264", 1920, 1080)
print(f" 耗时: {r['encode_time']:.2f}s, 大小: {r['file_size']/1024/1024:.1f}MB")5. 代码详解
5.1 MPP API 详解
MPP 的 C API 围绕「上下文 + buffer」组织,先看创建解码器和编码器的两个初始化函数:
#include <rockchip/mpp.h>
#include <rockchip/mpp_mem.h>
#include <rockchip/mpp_buffer.h>
/* MPP 编解码上下文结构 */
typedef struct MppContext {
MppApi *mpp_api;
MppCtx ctx;
MppBufferGroup frm_grp;
MppBufferGroup pkt_grp;
MppPacket packet;
MppFrame frame;
} MppContext;
/* 创建并初始化解码器 */
int init_decoder(MppContext *mpp, MppVideoCodingType coding)
{
MPP_RET ret;
ret = mpp_create(&mpp->ctx, &mpp->mpp_api);
if (ret != MPP_OK) return -1;
ret = mpp_init(mpp->ctx, MPP_CTX_DEC, coding);
if (ret != MPP_OK) return -1;
ret = mpp_buffer_group_get_internal(&mpp->frm_grp, MPP_BUFFER_TYPE_ION);
if (ret != MPP_OK) return -1;
return 0;
}
/* 创建并初始化编码器 */
int init_encoder(MppContext *mpp, RK_U32 width, RK_U32 height,
RK_U32 fps, RK_U32 bps)
{
MPP_RET ret;
ret = mpp_create(&mpp->ctx, &mpp->mpp_api);
if (ret != MPP_OK) return -1;
ret = mpp_init(mpp->ctx, MPP_CTX_ENC, MPP_VIDEO_CodingAVC);
if (ret != MPP_OK) return -1;
/* 配置编码参数 */
MppEncCfg cfg;
mpp_enc_cfg_init(&cfg);
mpp_enc_cfg_set_u32(cfg, "prep:width", width);
mpp_enc_cfg_set_u32(cfg, "prep:height", height);
mpp_enc_cfg_set_u32(cfg, "rc:bps_target", bps);
mpp_enc_cfg_set_u32(cfg, "rc:bps_max", bps * 120 / 100);
mpp_enc_cfg_set_u32(cfg, "rc:fps_in_num", fps);
mpp_enc_cfg_set_u32(cfg, "rc:fps_out_num", fps);
mpp_enc_cfg_set_u32(cfg, "rc:gop", fps * 2);
ret = mpp->mpp_api->control(mpp->ctx, MPP_ENC_SET_CFG, cfg);
mpp_enc_cfg_deinit(cfg);
if (ret != MPP_OK) return -1;
return 0;
}5.2 解码流程
解码的核心是两步:把编码流打包送进解码器,再取回解码好的帧:
int decode_video(MppContext *mpp, uint8_t *data, size_t len)
{
MPP_RET ret;
/* 创建并设置输入包 */
ret = mpp_packet_init(&mpp->packet, mpp->pkt_grp, len);
if (ret != MPP_OK) return -1;
mpp_packet_set_data(mpp->packet, data);
mpp_packet_set_size(mpp->packet, len);
mpp_packet_set_pos(mpp->packet, data);
mpp_packet_set_eos(mpp->packet);
/* 送入解码器 */
ret = mpp->mpp_api->decode_put_packet(mpp->ctx, mpp->packet);
if (ret != MPP_OK) return -1;
/* 获取解码结果 */
ret = mpp->mpp_api->decode_get_frame(mpp->ctx, &mpp->frame);
if (ret != MPP_OK) return -1;
if (mpp->frame) {
RK_U32 w = mpp_frame_get_width(mpp->frame);
RK_U32 h = mpp_frame_get_height(mpp->frame);
MppBuffer buf = mpp_frame_get_buffer(mpp->frame);
printf("Decoded: %dx%d, buf=%p\n", w, h, mpp_buffer_get_ptr(buf));
mpp_frame_deinit(&mpp->frame);
}
return 0;
}5.3 编码流程
编码与解码对称:送入 YUV 帧,取回编码后的码流包:
int encode_video(MppContext *mpp, uint8_t *yuv_data, size_t yuv_size,
FILE *output_file)
{
MPP_RET ret;
ret = mpp_frame_init(&mpp->frame);
if (ret != MPP_OK) return -1;
mpp_frame_set_fmt(mpp->frame, MPP_FMT_YUV420SP);
mpp_frame_set_width(mpp->frame, 1920);
mpp_frame_set_height(mpp->frame, 1080);
mpp_frame_set_ver_stride(mpp->frame, 1080);
mpp_frame_set_hor_stride(mpp->frame, 1920);
MppBuffer buf;
ret = mpp_buffer_get(mpp->frm_grp, &buf, yuv_size);
if (ret != MPP_OK) return -1;
memcpy(mpp_buffer_get_ptr(buf), yuv_data, yuv_size);
mpp_frame_set_buffer(mpp->frame, buf);
mpp_frame_set_eos(mpp->frame, 0);
/* 送入编码器 */
ret = mpp->mpp_api->encode_put_frame(mpp->ctx, mpp->frame);
if (ret != MPP_OK) return -1;
/* 获取编码包 */
ret = mpp->mpp_api->encode_get_packet(mpp->ctx, &mpp->packet);
if (ret != MPP_OK) return -1;
if (mpp->packet) {
void *pkt_data = mpp_packet_get_data(mpp->packet);
size_t pkt_len = mpp_packet_get_length(mpp->packet);
fwrite(pkt_data, 1, pkt_len, output_file);
mpp_packet_deinit(&mpp->packet);
}
mpp_frame_deinit(&mpp->frame);
mpp_buffer_put(buf);
return 0;
}5.4 MPP API 参考速查
| API 函数 | 功能 |
|---|---|
mpp_create() | 创建 MPP 实例 |
mpp_init() | 初始化编/解码上下文 |
mpp_destroy() | 销毁 MPP 实例 |
mpp_packet_init() | 初始化输入包 |
mpp_frame_init() | 初始化输出帧 |
decode_put_packet() | 送入编码数据(解码) |
decode_get_frame() | 获取解码帧 |
encode_put_frame() | 送入 YUV 帧(编码) |
encode_get_packet() | 获取编码后的码流包 |
control() | 控制操作(如设置编码参数、请求 I 帧) |
编码类型常量:
| 常量 | 值 | 说明 |
|---|---|---|
MPP_VIDEO_CodingAVC | 1 | H.264 |
MPP_VIDEO_CodingHEVC | 2 | H.265 |
MPP_VIDEO_CodingVP9 | 4 | VP9 |
MPP_VIDEO_CodingAV1 | 6 | AV1 |
像素格式常量:
| 常量 | 说明 |
|---|---|
MPP_FMT_YUV420SP | NV12 |
MPP_FMT_YUV420P | YUV420P (I420) |
MPP_FMT_YUV422SP | NV16 |
MPP_FMT_RGB888 | RGB888 |
MPP_FMT_RGBA8888 | RGBA8888 |
6. 常见问题
6.1 MPP 库加载失败
现象:error while loading shared libraries: librockchip_mpp.so
ls -la /usr/lib/librockchip_mpp*
ldconfig -p | grep rockchip
# 如果不存在,手动安装
sudo cp /path/to/librockchip_mpp.so* /usr/lib/
sudo ldconfig6.2 解码输出异常(花屏/绿屏)
ffprobe -i test.h265 # 检查文件完整性
./mpi_dec_test -t 2 -i test.h265 -o output.yuv -w 1920 -h 1080 # 指定分辨率6.3 编码性能不足
sudo cpupower frequency-set -g performance # CPU 性能模式
./mpi_enc_test -t 2 -w 1280 -h 720 -i input.yuv -o output.h265 # 降低分辨率
cat /sys/kernel/debug/clk/clk_summary | grep -i vdec # 检查 VPU 时钟6.4 多路解码内存不足
free -h # 检查系统内存
cat /sys/kernel/debug/dma_buf/bufinfo # 检查 DMA-BUF
cat /sys/kernel/debug/ion/heaps/system # 检查 ION 分配
# 减少同时解码路数或降低分辨率6.5 ffmpeg 硬件加速不生效
ffmpeg -hwaccels 2>&1 | grep rkmpp # 检查 rkmpp 是否可用
ls -la /dev/mpp_service # 检查 MPP 设备节点
ffmpeg -hwaccel rkmpp -i input.mp4 -f rawvideo output.yuv # 明确指定6.6 解码器初始化失败
lsmod | grep rkvdec2 # 检查内核模块
sudo modprobe rkvdec2 # 加载模块
cat /proc/device-tree/vpu@fe610000/status # 检查设备树
dmesg | grep -i "rkvdec\|rkvenc" # 查看内核日志
sudo chmod 666 /dev/video* # 修复权限7. 相关文档
| 文档名称 | 路径 | 说明 |
|---|---|---|
| 显示框架(DRM/KMS) | ../multimedia/ch01-display-framework.md | DRM 显示输出 |
| 音频开发与 ALSA | ../multimedia/ch04-audio-development-alsa.md | 音频采集与播放 |
| RGA 图像处理 | ../multimedia/ch05-rga-image-processing.md | 解码后格式转换与缩放 |
| GStreamer 多媒体开发 | ../application-development/ch04-gstreamer-multimedia-development.md | GStreamer 流水线与 MPP 集成 |
| C/C++ 应用开发入门 | 04_application-development/01_C-C++应用开发.md | 编译环境与基础开发 |
