一、下载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、解码流程示例

三、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-develop

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

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

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

RK-MPP硬件编解码库介绍和使用相关推荐

  1. 04 ARM Mali-V VPU硬件视频编解码驱动介绍V61

    ARM Mali-V VPU硬件视频编解码驱动介绍V61 作者 将狼才鲸 创建日期 2022-12-13 CSDN文章地址:ARM Mali-V VPU硬件视频编解码驱动介绍V61 一.PC上的VPU ...

  2. 硬件编解码(一)硬件编解码介绍

    硬件编解码介绍 音视频编解码的两种方式 对视频数据编解码一般有两种方式: 1.软件的方式.使用常规的x264.x265等软件编解码器对数据进行处理,优点是灵活,可以根据需要进行定制,缺点是速度比较慢 ...

  3. Adroid新增硬件编解码

    背景 瑞芯微和全志的平台 硬解的视频codec为H264 修改方法  1. 硬件编码 修改文件MediaCodecVideoEncoder.java(1)文件新增全志和瑞芯微的硬件编解码 //全志 p ...

  4. 【Windows Esp32】基于 libjpeg-9e 编解码库的视频播放器

    目录 一.音视频基础 1.1.图像编码 1.2.视频编码 1.3.AVI 文件结构 二.TF卡基础 三.Windows上播放音视频 3.1.在 Windows 下使用 vs2019 编译 libjpe ...

  5. 硬件编解码,软件编解码,H.263、H.264、H.265/HEVC概念

    概念 硬件编解码通常称为硬编码硬解码,软件编解码称为软编码软解码. 软编码软解码主要依赖的是CPU资源,设备普通使用也是使用CPU做计算,所以开始编解码视频的时候CPU会飙升起来,发热就无法避免. 硬 ...

  6. 【FFmpeg在Intel GPU上的硬件编解码实现】

    用于记录Intel CPU开发qsv硬件解码过程中遇到的一些问题及解决方案 以下文章是在开发过程中参考的比较有意义的文章,供大家学习和参考~~ https://zhuanlan.zhihu.com/p ...

  7. 嵌入式Linux下基于FFmpeg的视频硬件编解码[图]

    转自:http://tech.c114.net/167/a674033.html 摘要: 对FFmpeg多媒体解决方案中的视频编解码流程进行研究.结合对S3C6410处理器视频硬件编解码方法的分析,阐 ...

  8. 嵌入式Linux下基于FFmpeg的视频硬件编解码

    嵌入式Linux下基于FFmpeg的视频硬件编解码[图] http://www.c114.net ( 2012/3/1 15:41 ) 摘要: 对FFmpeg多媒体解决方案中的视频编解码流程进行研究. ...

  9. iOS8系统H264视频硬件编解码说明

    iOS8系统H264视频硬件编解码说明 转载自:http://www.tallmantech.com/archives/206#more-206 公司项目原因,接触了一下视频流H264的编解码知识,之 ...

最新文章

  1. 开关电源三种控制模式:PWM/PFM/PSM
  2. android 将bitmap存为 bmp格式图片大小,Android Bitmap保存為.bmp格式,圖像轉化為黑白圖片...
  3. capistrano部署ruby on rails应用
  4. 50. Leetcode 105. 从前序与中序遍历序列构造二叉树 (二叉树-二叉树构建)
  5. 史上最全Redis面试题及答案。
  6. 成功解决OpenVideoCall(不可用)以及MSB8020 The build tools for v141 (Platform Toolset = ‘v141‘) cannot be found
  7. ubuntu 中vi的使用方法
  8. java图遍历求最长路径_如何在Java中使用递归实现矩阵中最长路径的返回
  9. [C# 项目实战]: 制作一个备忘录(经典)
  10. mybatis学习(38):动态sql-foreach
  11. Spire.Doc for Java的jar包、maven库-全套free资源
  12. jQuery的几种简单实用效果
  13. 【p2p】【EdgeVPNio (evio)】简介: IP-over-P2P (IPOP)
  14. LVGL使用华为鸿蒙字体
  15. 《统计学》第八版贾俊平第三章课后答案Excel
  16. Centos7安装ffmpeg和使用youtube-dl下载Youtube视频
  17. 为什么说HTTP协议是无状态的
  18. 程序员是不是青春饭?年纪大了何去何从
  19. codecademy里能学好php,在iPhone上学编程:Codecademy
  20. Mybatis的Spring集成、Aop整合

热门文章

  1. 【翁恺】35-流的概念
  2. ubuntu16.04删除用户及用户目录(高效方法)
  3. C语言实现简单的状态机
  4. 学习Streams(一)
  5. 销售分析怎么做?掌握3个思路,让你“躺平”秒变“躺赢”
  6. 商城之Fresco(FaceBook)
  7. Argo CD 核心概念
  8. 人机融合智能:人工智能3.0。道翰天琼认知智能机器人平台API接口大脑为您揭秘-20
  9. Lighting - UE5中的灯光练习
  10. 开机不显示桌面]木马 的解决办法