第三章:RK MPP 框架入门

好,咱们今天聊聊瑞芯微平台上的核心中间件——MPP。说实话,很多刚接触RK平台的开发者,上来就被MPP的各种缩写搞懵了。VDPP、RGA、MJPEG、H264……这些到底都是啥?它们之间怎么配合的?

我刚开始做RK3399项目时,也踩过不少坑。有一次,视频预览画面一直出不来,查了两天才发现是VDPP的路由没配对。嗯,从那以后,我就把MPP的模块划分彻底搞明白了。今天,我把这些经验分享给你。

一、MPP到底是什么?

MPP,全称是Media Process Platform。说白了,它就是瑞芯微提供的一套多媒体处理中间件。

你想想看,芯片厂家如果让你直接操作底层寄存器去编解码视频,那得多痛苦?MPP的作用,就是把这些复杂的硬件操作封装成一套统一的API。你调用MPP的接口,它帮你调度硬件,完成视频的编解码、图像处理、显示输出等工作。

我个人习惯把MPP理解成「硬件加速的调度中心」。它不负责具体的算法实现,而是把VDPP、RGA这些硬件模块组织起来,形成一个流水线。

核心要点:MPP = 硬件抽象层 + 任务调度器 + 内存管理器

它让你用软件思维操作硬件,不用关心底层寄存器细节。

二、MPP的模块划分

MPP内部不是铁板一块,它由多个独立的硬件模块组成。每个模块负责一类特定的任务。我画个简单的思维导图给你:

模块名称 全称 主要功能 我常用的场景
VDPP Video Display Processor 视频显示处理、缩放、旋转、叠加 摄像头预览、UI叠加显示
RGA Raster Graphic Acceleration 2D图像加速、格式转换、裁剪、旋转 图像预处理、后处理、画中画
MJPEG Motion JPEG JPEG图片编解码、MJPEG视频流 抓拍、缩略图生成、网络传输
H264/H265 视频编码标准 H.264/H.265视频编解码 视频录制、直播推流、视频通话

三、VDPP:视频显示的「调度员」

VDPP主要负责视频数据的显示输出。它能把解码后的视频帧,经过缩放、裁剪、旋转等处理,最终送到显示器上。

我在项目中遇到过一个问题:摄像头采集的画面是1080p,但屏幕只有720p。如果不经过VDPP处理,画面要么溢出,要么被截断。VDPP的缩放功能就派上用场了。

我的经验:VDPP支持多个视频层叠加。你可以把摄像头画面放在底层,UI界面放在上层,实现画中画效果。但要注意,层数越多,带宽消耗越大。

四、RGA:2D图像处理的「瑞士军刀」

RGA是专门做2D图像加速的。它不像GPU那么强大,但处理格式转换、旋转、裁剪这些操作,效率极高。

举个例子:摄像头采集的数据通常是NV12格式,但编码器需要YUV420。如果没有RGA,你得用CPU去转换,那效率就太低了。RGA一条指令就能搞定。

// RGA初始化示例(伪代码)
rga_context *ctx = rga_create();
rga_set_src(ctx, src_buf, src_fmt, src_w, src_h);
rga_set_dst(ctx, dst_buf, dst_fmt, dst_w, dst_h);
rga_do_convert(ctx);  // 一键转换

避坑指南:我曾经在RK3288上遇到过RGA输出花屏的问题。后来发现是输入缓冲区的对齐方式不对。RGA要求缓冲区地址按16字节对齐,否则会出奇怪的问题。

五、MJPEG:轻量级的编解码方案

MJPEG其实就是一系列JPEG图片组成的视频流。它不像H264那样有帧间压缩,所以压缩率不高,但优点是实现简单、延迟低。

我一般在两种场景下用MJPEG:

  • 抓拍功能:从视频流中提取一帧,编码成JPEG保存
  • 低延迟预览:比如无人机图传,对延迟敏感,MJPEG比H264更合适

MPP对MJPEG的支持很完善。你只需要设置好输入输出格式,调用编码接口就行。但要注意,MJPEG的码流大小波动很大,缓冲区要留够余量。

六、H264/H265:视频编解码的「主力军」

这是MPP最核心的功能。H264和H265是目前主流的视频编码标准。H265在同等画质下,码率比H264低30%-50%,但计算复杂度也更高。

MPP对这两种编码的支持非常成熟。我做过一个4K视频录制的项目,用H265编码,码率控制在20Mbps,画质完全够用。

// H264编码示例(简化版)
MppCtx ctx;
MppApi *mpi;
MppPacket packet;

// 1. 创建编码器
mpp_create(&ctx, &mpi);

// 2. 初始化编码参数
MppEncCfg cfg;
mpp_enc_cfg_init(&cfg);
mpp_enc_cfg_set_s32(cfg, "type", MPP_ENC_TYPE_H264);
mpp_enc_cfg_set_s32(cfg, "width", 1920);
mpp_enc_cfg_set_s32(cfg, "height", 1080);
mpp_enc_cfg_set_s32(cfg, "bitrate", 4000000);  // 4Mbps

// 3. 开始编码
mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
mpi->encode(ctx, frame, packet);

关键点:H264和H265的编码参数很多,但最核心的就三个:分辨率、码率、帧率。其他参数(如GOP大小、码率控制模式)按默认值跑,基本没问题。

七、模块之间的协作流程

实际项目中,这些模块不是独立工作的。我给你画一个典型的视频采集-编码-显示流程:

  1. 摄像头采集:原始数据进入内存
  2. RGA处理:格式转换、裁剪、旋转
  3. 编码器:H264/H265/MJPEG编码
  4. VDPP显示:解码后的视频帧送到屏幕

你看,RGA负责预处理,编码器负责压缩,VDPP负责显示。MPP就是把这些步骤串起来的「总指挥」。

我的建议:刚开始学MPP,不要试图一次搞懂所有模块。先跑通一个最简单的编码示例,比如用MPP编码一张图片。然后逐步加入RGA预处理、VDPP显示。循序渐进,反而学得快。

八、总结

MPP是瑞芯微平台多媒体开发的核心。它把VDPP、RGA、MJPEG、H264/H265这些硬件模块组织起来,提供统一的API接口。

记住三点:

  • VDPP管显示,RGA管图像处理,编解码器管压缩
  • MPP是调度中心,不是算法库
  • 遇到问题先查模块间的数据流,八成是格式或对齐问题

下一章,我会带你实际搭建MPP的开发环境,并跑通第一个编解码示例。到时候,你会真正感受到MPP的强大。