RK-MPP硬件编解码库介绍和使用

article/2025/11/9 1:55:10

一、下载RK-MPP硬件编解码库

        下载链接:https://github.com/rockchip-linux/mpp

二、RK-MPP库介绍

        1、资料来源:MPP 开发参考.pdf

        2、MPP说明

        MPP(Media Process Platform )是rk提供的一款硬件编解码库,为用户空间屏蔽了复杂的底层操作,通过MPP提供了一组MPI接口,用户通过MPI接口来实现媒体处理

        MPP提供的功能包括:

         视频解码

         H.265 / H.264 / H.263 / VP9 / VP8 / MPEG-4 / MPEG-2 / MPEG-1 / VC1 / MJPEG

         视频编码

         H.264 / VP8 / MJPEG

         视频处理

         视频拷贝,缩放,色彩空间转换,场视频解交织(Deinterlace)

        3、mpp系统框架

        4、MPP库的MPI接口介绍 

                

         5、MPI数据结构说明

        MppMem 为 C 库 malloc 内存的封装。

        MppBuffer 为硬件用的 dmabuf 内存的封装。

        MppPacket 为一维缓存封装,可以从 MppMem 和 MppBuffer 生成,表示码流数据。

        MppFrame 为二维帧数据封装,可以从 MppMem 和 MppBuffer 生成,表示图像数据。

        使用 MppPacket 和 MppFrame 就可以简单有效的完成一般的视频编解码工作。

        以视频解码为例,码流输入端把地址和大小赋值给 MppPacket,通过 put_packet 接口输入,在输出端通过 get_frame 接口得到输入图像 MppFrame,即可完成最简单的视频解码过程。

        6、解码流程示例

 5b73bb9aa28df76f3bf30ebae310b6aa.png

三、RK-MPP库工具介绍与使用

        1、MPP测试工具说明

        MPP 提供了一些单元测试用的工具程序,这种程序可以对软硬件平台以及 MPP 库本身进行测试

        mpp_info_test

        用于读取和打印 MPP 库的版本信息,在反馈问题时,可以把打印出来信息附上。

        mpp_buffer_test

        用于测试内核的内存分配器是否正常。

        mpp_mem_test

        用于测试 C 库的内存分配器是否正常。

        mpp_runtime_test

        用于测试一些软硬件运行时环境是否正常。

        mpp_platform_test

        用于读取和测试芯片平台信息是否正常

        2、交叉编译MPP库

        unzip mpp-develop.zip && cd mpp-developab473bb6d94757e60efd3320e93de993.png

        cd build/linux/aarch64(根据平台选择) && vim arm.linux.cross.cmake(看下是否是对应平台的交叉编译工具)

d30f998ff1f057414c83d0c01f1ddb24.png        3、./arm.linux.cross.cmake && make,编译之后,动态库在mpp目录下,测试工具在test目录下 

fa4ae183ac5c5c0a27e05b517d026e35.png

45692a1ce3d6dd24d5f885740cd56925.png

        4、将工具和动态库push到rk的平台上(一般rk的平台都已经自带MPP动态库了),以解码为例执行./mpi_dec_test -t 7 -i /sdcard/tennis200.h264 -n 10

        -t 7 表示是 H.264 码流, -i 表示输入文件, -n 10 表示解码 10 帧,如果一切正常,会得到如下的结果:

四、仿照mpi_dec_test.c 写一个最简单的解码demo 

#include <string.h>
#include "rk_mpi.h"
#include "mpp_mem.h"
#include "mpp_env.h"
#include "mpp_time.h"
#include "mpp_common.h"
#include "mpi_dec_utils.h"
#include "utils.h"typedef struct 
{MppCtx          ctx;MppApi          *mpi;RK_U32          eos;char            *buf;MppBufferGroup  frm_grp;MppPacket       packet;size_t          packet_size;MppFrame        frame;FILE            *fp_input;FILE            *fp_output;RK_S32          frame_count;RK_S32          frame_num;size_t          max_usage;
} MpiDecLoopData;static int decode_simple(MpiDecLoopData *data)
{RK_U32 pkt_done = 0;RK_U32 err_info = 0;MPP_RET ret = MPP_OK;MppCtx ctx  = data->ctx;MppApi *mpi = data->mpi;char   *buf = data->buf;MppPacket packet = data->packet;MppFrame  frame  = NULL;size_t read_size = fread(buf, 1, data->packet_size, data->fp_input);if (read_size != data->packet_size || feof(data->fp_input)) {printf("found last packet\n");data->eos = 1;}mpp_packet_write(packet, 0, buf, read_size);mpp_packet_set_pos(packet, buf);mpp_packet_set_length(packet, read_size);if (data->eos){mpp_packet_set_eos(packet);}do {if (!pkt_done) {ret = mpi->decode_put_packet(ctx, packet);if (MPP_OK == ret){pkt_done = 1;}}do {RK_S32 get_frm = 0;RK_U32 frm_eos = 0;ret = mpi->decode_get_frame(ctx, &frame);if (frame) {if (mpp_frame_get_info_change(frame)){RK_U32 width = mpp_frame_get_width(frame);RK_U32 height = mpp_frame_get_height(frame);RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);RK_U32 buf_size = mpp_frame_get_buf_size(frame);								printf("decode_get_frame get info changed found\n");printf("decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d", width, height, hor_stride, ver_stride, buf_size);        if (NULL == data->frm_grp) {                       ret = mpp_buffer_group_get_internal(&data->frm_grp, MPP_BUFFER_TYPE_ION);if (ret) {printf("get mpp buffer group failed ret %d\n", ret);break;}							ret = mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, data->frm_grp);if (ret) {printf("set buffer group failed ret %d\n", ret);break;}} else {                      ret = mpp_buffer_group_clear(data->frm_grp);if (ret){printf("clear buffer group failed ret %d\n", ret);break;}}ret = mpp_buffer_group_limit_config(data->frm_grp, buf_size, 24);if (ret) {printf("limit buffer group failed ret %d\n", ret);break;}                   ret = mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);if (ret) {printf("info change ready failed ret %d\n", ret);break;}}else{err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame);if (err_info) {printf("decoder_get_frame get err info:%d discard:%d.\n", mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame));}data->frame_count++;printf("decode_get_frame get frame %d\n", data->frame_count);if ( (!err_info) && (data->frame_count==data->frame_num)){dump_mpp_frame_to_file(frame, data->fp_output);}}frm_eos = mpp_frame_get_eos(frame);mpp_frame_deinit(&frame);frame = NULL;get_frm = 1;}if (data->frm_grp) {size_t usage = mpp_buffer_group_usage(data->frm_grp);if (usage > data->max_usage){data->max_usage = usage;}	}if (data->eos && pkt_done && !frm_eos) {msleep(10);continue;}if (frm_eos) {printf("found last frame\n");break;}if (data->frame_num && data->frame_count >= data->frame_num) {data->eos = 1;break;}if (get_frm){continue;}break;} while (1);if (data->frame_num && data->frame_count >= data->frame_num){data->eos = 1;printf("reach max frame number %d\n", data->frame_count);break;}if (pkt_done){break;}} while (1);return ret;
}int mpi_dec_test_decode(char **argv)
{MPP_RET ret         = MPP_OK;size_t file_size 	= 0;MppParam param      = NULL;RK_U32 need_split   = 1;MpiDecLoopData data;memset(&data, 0, sizeof(data));data.eos            = 0;data.packet_size    = MPI_DEC_STREAM_SIZE;data.frame_count    = 0;data.frame_num		= 1;data.fp_input = fopen(argv[1], "rb");data.fp_output = fopen(argv[2], "w+");if ( (NULL == data.fp_input) || (NULL == data.fp_output) ) {printf("failed to open input/output file \n");goto MPP_TEST_OUT;}data.buf = mpp_malloc(char, data.packet_size);ret = mpp_packet_init(&data.packet, data.buf, data.packet_size);if(MPP_OK != ret){printf("mpp_packet_init error\n");goto MPP_TEST_OUT;}ret = mpp_create(&data.ctx, &data.mpi);if(MPP_OK != ret){printf("mpp_create error\n");goto MPP_TEST_OUT;}ret = mpp_init(data.ctx, MPP_CTX_DEC, MPP_VIDEO_CodingAVC);if (MPP_OK != ret) {printf("mpp_init failed\n");goto MPP_TEST_OUT;}param = &need_split;ret = data.mpi->control(data.ctx, MPP_DEC_SET_PARSER_SPLIT_MODE, param);if (MPP_OK != ret) {printf("mpi->control failed\n");goto MPP_TEST_OUT;}fseek(data.fp_input, 0L, SEEK_END);file_size = ftell(data.fp_input);rewind(data.fp_input);printf("input file size %ld\n", file_size);while (!data.eos) {decode_simple(&data);}ret = data.mpi->reset(data.ctx);if (MPP_OK != ret) {printf("mpi->reset failed\n");goto MPP_TEST_OUT;}MPP_TEST_OUT:if (data.packet) {mpp_packet_deinit(&data.packet);data.packet = NULL;}if (data.ctx) {mpp_destroy(data.ctx);data.ctx = NULL;}if (data.buf) {mpp_free(data.buf);data.buf = NULL;}if (data.frm_grp) {mpp_buffer_group_put(data.frm_grp);data.frm_grp = NULL;}if (data.fp_output){fclose(data.fp_output);data.fp_output = NULL;}if (data.fp_input) {fclose(data.fp_input);data.fp_input = NULL;}return ret;
}int main(int argc, char **argv)
{RK_S32 ret = 0;if(argc != 3 ){printf("please input options\n");return -1;}ret = mpi_dec_test_decode(argv);return ret;
}

五、测试MPP解码H264,解码输出格式为YUV420SP


http://chatgpt.dhexx.cn/article/t8Ex1WZF.shtml

相关文章

第二季1:MPP模块概述

以下内容源于海思官方文档内容&#xff0c;如有侵权请告知删除。 一、MPP模块概述 海思的媒体处理软件平台&#xff08;MPP&#xff0c;Media Process Platform&#xff09;有利于应用软件的快速开发。因为该平台屏蔽了一些与芯片相关的复杂的底层处理&#xff0c;给应用软件提…

从系统架构角度出发,服务器该如何分类?MPP 是什么?

写在前面 本文隶属于专栏《100个问题搞定大数据理论体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和文献引用请见100个问题搞定大数据理论体系 解答 从系统架构来…

区分一下cluster、MPP、SMP和SSMP

最近学习GA库&#xff0c;发现应当对多种计算机架构进行区分,故查阅资料&#xff0c;总结如下 MPP&#xff08;Massive Parallel Processing)&#xff0c;每个 现在有多种架构需要区分 MPP &#xff08;Massive Parallel Processing&#xff09;clusterSMP&#xff08;Symmet…

MPP 与 Hadoop是什么关系?

链接&#xff1a;https://www.zhihu.com/question/22037987/answer/106984010 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 1. hadoop(hive)跟mpp的本质区别是什么&#xff0c;这个有的时候界限很模糊&#xff0c;比…

RKMPP库快速上手--(四)MPP编码入门

首先,了解MPP编码之前,先了解一下MPP的MPI接口。 1、MPI接口结构 MPP设计的MPI接口,下面的图都来自于官方参考文档: MppMem:C库malloc内存的封装; MppBuffer:dmabuf内存的封装; MppPacket:一维缓存封装,可以从MppMem、MppBuffer生成,用来表示码流数据; MppFram…

MPP数据库初识

MPP数据库初识 先了解下OLTP与OLAP区别为什么需要MPP数据库&#xff1f;MPP数据库应用领域什么是MPP&#xff1f;MPP架构特征MPPDB架构什么是MPP数据库&#xff1f;MPP数据库的使用场景&#xff1f;MPPDB、Hadoop与传统数据库技术对比与适用场景 先了解下OLTP与OLAP区别 OLTP(…

MPP架构,SMP架构,NUWA架构

MPP架构 随着分布式、并行化技术成熟应用&#xff0c;MPP引擎逐渐表现出强大的高吞吐、低时延计算能力&#xff0c;有很多采用MPP架构的引擎都能达到“亿级秒开 MPP是由多台SMP服务器通过一定的节点互联网络进行连接&#xff0c;协同工作&#xff0c;完成相同的任务&#xff0…

MPP架构是什么?看这一篇就行了。。

文章目录 MPP是什么SMP- Symmetric Multi-Processor 对称多处理器结构NUMA -Non-Uniform Memory Access 非一致存储访问结构MPP -Massive-Parallel Processing 海量并行处理架构 MPP DB- Share Disk- Share Nothing 典型MPP DBGreenplumTeradataImpalaPrestoElasticSearchVerti…

MPP数据库

MPP数据库定义 MPP即大规模并行处理&#xff08;Massively Parallel Processor &#xff09;。 在数据库非共享集群中&#xff0c;每个节点都有独立的磁盘存储系统和内存系统&#xff0c;业务数据根据数据库模型和应用特点划分到各个节点上&#xff0c;每台数据节点通过专用网…

MPP数据库简介及架构分析

目录 什么是MPP&#xff1f;特性并行处理超大规模 数据仓库真正适合什么典型的分析工作量数据集中化线性可伸缩性 MPP架构技术特性数据库架构分析Shared EverythingShared DiskShare MemoryShared NothingShared Nothing数据库架构优势 什么是MPP&#xff1f; MPP (Massively P…

什么是MPP数据库?

大规模并行分析&#xff08;MPP&#xff09;数据库&#xff08;Analytical Massively Parallel Processing (MPP) Databases&#xff09;是针对分析工作负载进行了优化的数据库&#xff1a;聚合和处理大型数据集。MPP数据库往往是列式的&#xff0c;因此MPP数据库通常将每一列存…

MPP数据库简介

1、先了解下OLTP与OLAP区别 OLTP(OnLine Transaction Processing &#xff0c;联机事务处理)系统 例如mysql。擅长事务处理&#xff0c;在数据操作中保持着很强的一致性和原子性 &#xff0c;能够很好的支持频繁的数据插入和修改 &#xff0c;但是&#xff0c;一旦数据量过大…

MPP(大规模并行处理)

1、 什么是MPP? MPP (Massively Parallel Processing),即大规模并行处理,在数据库非共享集群中,每个节点都有独立的磁盘存储系统和内存系统,业务数据根据数据库模型和应用特点划分到各个节点上,每台数据节点通过专用网络或者商业通用网络互相连接,彼此协同计算,作为整体…

MPP架构

MPP架构 0x01 摘要 本文综合各家看法&#xff0c;再加上个人理解&#xff0c;介绍下对MPP架构的理解以及一些其他架构的对比。 0x02 MPP架构基本概念 2.1 什么是MPP MPP&#xff0c;全称为Massively Parallel Processor&#xff0c;翻译过来就是大规模并行处理。MPP系统是由…

MPP(大规模并行处理)简介

1、 什么是MPP&#xff1f; MPP (Massively Parallel Processing)&#xff0c;即大规模并行处理&#xff0c;在数据库非共享集群中&#xff0c;每个节点都有独立的磁盘存储系统和内存系统&#xff0c;业务数据根据数据库模型和应用特点划分到各个节点上&#xff0c;每台数据节…

基于WiFi的Android局域网即时通讯软件

基于WiFi的Android局域网即时通讯软件&#xff0c;通过自建WiFi热点的方式与其他移动设备进行通信&#xff0c;实现了文字聊天、语音留言、文件互传等功能&#xff0c;满足基本的日常使用需求。 下载地址&#xff1a;http://www.devstore.cn/code/info/670.html 运行截图&…

基于WiFi的Android局域网即时通讯软件——Android源码

基于WiFi的Android局域网即时通讯软件 基于WiFi的Android局域网即时通讯软件&#xff0c;通过自建WiFi热点的方式与其他移动设备进行通信&#xff0c;实现了文字聊天、语音留言、文件互传等功能&#xff0c;满足基本的日常使用需求。 下载地址&#xff1a;http://www.devstore.…

局域网即时通讯软件_企业即时通讯软件需要符合哪些要求?

随着网络信息的发展&#xff0c;市面上出现了大量的企业即时通讯软件&#xff0c;旨在帮助企业打通信息化的道路。很多企业不知道该如何正确选择一款符合要求的通讯软件&#xff0c;选择的标准应该从哪些方面入手。下面企达小编为大家详细介绍一下。 1、数据安全性 企业的商业部…

局域网即时通讯软件_远程桌面监控软件好不好用?哪个好?

远程桌面监控软件好不好用?哪个好?有时候经常需要进行远程协助&#xff0c;大家第一时间想到的就是QQ远程协助了&#xff0c;没错&#xff0c;QQ可以&#xff0c;但是 QQ远程协助很卡顿&#xff0c;响应不及时。电脑自带应用不会设置&#xff0c;这可怎么办?超级眼远程监控软…

局域网即时通讯软件_做企业即时通讯软件,我们是认真的

协同办公无非分为外部沟通和内部沟通两种局势&#xff0c;内部沟通则是企业协同工作的一部分&#xff0c;注重效率&#xff1b;外部沟通为企业社交&#xff0c;注重便捷&#xff0c;从而实现内部沟通的高效性&#xff0c;是协同办公工具所要解决的基础性问题。真心特别羡慕那些…