diff --git a/doc/Rockchip_Developer_Guide_MPP_CN.md b/doc/Rockchip_Developer_Guide_MPP_CN.md new file mode 100644 index 00000000..2f4e5fa9 --- /dev/null +++ b/doc/Rockchip_Developer_Guide_MPP_CN.md @@ -0,0 +1,1126 @@ +# MPP 开发参考 + +| Project: | MPP | +| --------- | ---------- | +| Version: | 0.7 | +| Author: | 陈恒明 | +| Date: | 10/17/2023 | + +| Revision | Date | Description | Author | +| -------- | ---------- | ------------------------------------------------------- | ----------------------- | +| 0.1 | 04/18/2018 | 初始版本 | 陈恒明 | +| 0.2 | 05/07/2018 | 增加解码器control命令说明,编码器部分说明和demo部分说明 | 陈恒明 | +| 0.3 | 05/22/2018 | 修正一些笔误和说明错误,重新编排页码 | 陈恒明 谢雄斌(精英智通) | +| 0.4 | 11/28/2018 | 更新编码器输入图像的内存排布说明。 修正编码器流程图笔误 | 陈恒明 研果(科通) | +| 0.5 | 06/08/2020 | 更新编码器新配置接口 不再支持RK3188 | 陈恒明 | +| 0.6 | 08/31/2022 | 更新MPP demo说明 更新编码器控制接口说明 | 陈恒明 阮学满 | +| 0.7 | 10/17/2023 | 添加markdown文档 |阮学满 林言东| +| | | | | +| | | | | + +# 第一章 MPP 介绍 + +## 1.1 概述 + +瑞芯微提供的媒体处理软件平台(Media Process Platform,简称MPP)是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理,其目的是为了屏蔽不同芯片的差异,为使用者提供统一的视频媒体处理接口(Media Process Interface,缩写MPI)。MPP提供的功能包括: + +- 视频解码 + - H.265 / H.264 / H.263 / VP9 / VP8 / MPEG-4 / MPEG-2 / MPEG-1 / VC1 / MJPEG / AV1 +- 视频编码 + - H.265 / H.264 / VP8 / MJPEG +- 视频处理 + - 视频拷贝,缩放,色彩空间转换,场视频解交织(Deinterlace) + +本文档描述了MPP框架以及组成模块,以及供用户使用的MPI接口。本文档适合于上层应用开发人员以及技术支持人员阅读。 + +## 1.2 系统架构 + +MPP平台在系统架构的层次图如下图: + +![](media/Figure01_MPP_system_framework.png) +
图表 1 MPP系统框架
+ +- 硬件层Hardware + +硬件层是瑞芯微系列芯片平台的视频编解码硬件加速模块,包括vdpu、vepu、rkvdec和rkvenc等不同类型、不同功能的硬件加速器。 + +- 内核驱动层Kernel driver + +Linux内核的编码器硬件设备驱动,以及相关的mmu,内存,时钟,电源管理模块等。支持的平台版本主要是Linux kernel 3.10、4.4、4.19和5.10。MPP库对于内核驱动有依赖。 + +- MPP层 + +用户态的MPP层屏蔽了不同操作系统和不同芯片平台的差异,为上层使用者提供统一的MPI接口。 + +MPP层包括MPI模块、OSAL模块、HAL模块以及视频编解码器(Video Decoder / Video Encoder)和视频处理功能模块(Video Process)。 + +- 操作系统层 + +MPP用户态的运行平台,如Android以及Debian等Linux发行版 + +- 应用层 + +MPP层通过MPI对接各种中间件软件,如OpenMax、ffmpeg和gstreamer,或者直接对接客户的上层应用。 + +## 1.3 平台支持 + +### 1.3.1 软件平台支持 + +MPP支持在各种版本的Android平台和纯Linux平台上运行。 + +支持瑞芯微Linux内核3.10、4.4、4.19和5.10版本,需要有vcodec_service设备驱动支持以及相应的DTS配置支持。 + +### 1.3.2 硬件平台支持 + +支持瑞芯微主流的各种系列芯片平台: + +RK3288系列,RK3368系列,RK3399系列,RK3588系列 + +RK30xx系列,RK312x系列芯片,RK322x系列芯片,RK332x系列 + +RV1109 / RV1126系列(注:RV1107/RV1108会逐步退出支持) + +## 1.4 功能支持 + +MPP支持的编解码功能随运行的芯片平台规格不同区别很大,请查询对应芯片的《Multimedia Benchmark》。 + +## 1.5 注意事项 + +如果想快速了解MPP的使用和demo,请直接转至——第四章 MPP demo说明。 + +如果想快速编译和使用MPP代码,请直接转至——第五章 MPP库编译与使用。 + +如果想了解MPP设计细节与设计思路,请参考MPP代码根目录的readme.txt,doc目录下的txt文档以及头文件的注释说明。 + +# 第二章 接口设计说明 + +本章节描述了用户在使用MPP过程中会直接接触到的数据结构,以及这些数据结构的使用说明。 + +由于视频编解码与视频处理过程需要处理大量的数据交互,包括码流数据、图像数据以及内存数据,同时还要处理与上层应用以及内核驱动的交叉关系,所以MPP设计了MPI接口,用于与上层交互。 + +本章节说明了MPI接口使用的数据结构,以及设计思路。 + +## 2.1 接口结构概述 + +下图为MPI接口使用的主要数据结构: + +![](media/Figure02_Data_structure_used_in_MPI_interface.png) +
图表 2 MPI接口使用的数据结构
+ +MppMem为C库malloc内存的封装。 + +MppBuffer为硬件用的dmabuf内存的封装。 + +MppPacket为一维缓存封装,可以从MppMem和MppBuffer生成,主要用于表示码流数据。 + +MppFrame为二维帧数据封装,可以从MppMem和MppBuffer生成,主要用于表示图像数据。 + +使用MppPacket和MppFrame就可以简单有效的完成一般的视频编解码工作。 + +以视频解码为例,码流输入端把地址和大小赋值给MppPacket,通过put_packet接口输入,在输出端通过get_frame接口得到输入图像MppFrame,即可完成最简单的视频解码过程。 + +![](media/Figure03_Use_simple_interface_to_realize_video_decoding.png) +
图表 3 使用简单接口实现视频解码
+ +MppMeta和MppTask为输入输出用任务的高级组合接口,可以支持指定输入输出方式等复杂使用方式,支持异步数据流处理。 + +**注意**:以上这些接口数据结构都是使用void\*句柄来引用使用,其目的是为了方便扩展和前向兼容。 + +本段落中的提到的成员都是通过形如mpp_xxx_set/get_xxx的接口来访问。 + +## 2.2 内存封装MppBuffer + +MppBuffer主要用于描述供硬件使用的内存块(即缓存),提供了内存块的分配、释放和加减引用等功能,目前支持的分配器有:ion、drm和dma_heap。MppBuffer几个重要的参数成员如下: + +| 成员名称 | 成员类型 | 描述说明 | +|----------|----------|----------------------------------| +| ptr | void \* | 表示内存块的起始虚拟地址。 | +| size | size_t | 表示内存块的大小。 | +| fd | int | 表示内存块的用户态空间文件句柄。 | + +在解码过程中,解码图像的缓存通常需要在固定的缓存池里进行轮转,为了实现这一点,MPP在MppBuffer基础之上又定义了MppBufferGroup。MppBuffer的使用方式有两种:常规使用方式和外部导入方式,由于二者的内存分配方式不同,也称为internal模式和external模式。 + +在MppBuffer常规使用方式下,MppBufferGroup由MPP内部生成和维护。通过mpp_buffer_get和mpp_buffer_put对内存块进行申请和释放,如下图所示: + +![](media/Figure04_Normal_usage_of_MppBuffer.png) +
图表 4 MppBuffer的常规使用方式
+ +其流程伪代码如下图: + +![](media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage.png) + +这种方式可以实现解码器在解码过程中**零拷贝输出**(解码器的输出帧与解码器内部使用的参考帧用是同一帧),但不容易实现**零拷贝显示**(解码器的输出帧不一定在显示端可以直接显示),同时要求用户知道需要给解码器开多大的空间进行解码。 + +另一种使用方式是把MppBufferGroup完全做为一个缓存的管理器,用于管理外部导入的缓存。其使用方式如下图: + +![](media/Figure05_Usage_of_MppBuffer_External_Import.png) +
图表 5 MppBuffer外部导入使用方式
+ +其流程伪代码如下图: + +![](media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage.png) + +这种方式可以使得解码器使用外部的缓存,可以对接OpenMax/ffmpeg/gstreamer这样的中间件,也方便对接用户己有的上层代码,便于实现零拷贝显示。 + +## 2.3 码流封装MppPacket + +MppPacket主要用于描述一维码流的相关信息,特别是有效数据的位置与长度。MppPacket几个重要的参数成员如下: + +| 成员名称 | 成员类型 | 描述说明 | +|----------|----------|----------------------------------------------------------------------------------------------------| +| data | void \* | 表示缓存空间的起始地址。 | +| size | size_t | 表示缓存空间的大小。 | +| pos | void \* | 表示缓存空间内有效数据的起始地址。 | +| length | size_t | 表示缓存空间内有效数据的长度。如果在decode_put_packet调用之后length变为0,说明此包码流己消耗完成。 | + +其关系如下图所示: + +![](media/Figure06_Important_parameter_description_of_MppPacket.png) + +
图表 6 MppPacket重要参数说明
+ +MppPacket的其他配置参数成员如下: + +| 成员名称 | 成员类型 | 描述说明 | +| -------- | --------- | ------------------------------------------------------------ | +| pts | RK_U64 | 表示显示时间戳(Present Time Stamp)。 | +| dts | RK_U64 | 表示解码时间戳(Decoding Time Stamp)。 | +| eos | RK_U32 | 表示码流结束标志(End Of Stream)。 | +| buffer | MppBuffer | 表示MppPacket对应的MppBuffer。 | +| flag | RK_U32 | 表示MPP内部使用的标志位,包含如下标志:
\#define MPP_PACKET_FLAG_EOS (0x00000001)
\#define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002)
\#define MPP_PACKET_FLAG_INTERNAL (0x00000004)
\#define MPP_PACKET_FLAG_INTRA (0x00000008) | + +MppPacket做为描述一维内存的结构体,在使用时需要使用malloc出来的内存或者使用MppBuffer的内存进行初始化。在释放MppPacket时有几种情况: + +如果是外部malloc地址配置到MppPacket,不会做free释放处理,如下示例; + +![](media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket.png) + +如果是拷贝产生的MppPacket,会做free释放内存,如下示例; + +![](media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init.png) + +如果是MppBuffer产生的MppPacket,会在生成时对MppBuffer加引用,在释放时对MppPacket减引用。 + +![](media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer.png) + +## 2.4 图像封装MppFrame + +MppFrame主要用于定义二维图像缓存的相关信息,有效数据的位置与长度。MppFrame几个重要的参数成员如下: + +| 成员名称 | 成员类型 | 描述说明 | +|------------|----------|------------------------------------------------| +| width | RK_U32 | 表示水平方向像素数,单位为像素个数。 | +| height | RK_U32 | 表示垂直方向像素数,单位为像素个数。 | +| hor_stride | RK_U32 | 表示垂直方向相邻两行之间的距离,单位为byte数。 | +| ver_stride | RK_U32 | 表示图像分量之间的以行数间隔数,单位为1。 | + +![](media/Figure07_Important_parameter_description_of_MppFrame.png) +
图表 7 MppFrame重要参数说明
+ +MppFrame的其他配置参数成员如下: + +| 成员名称 | 成员类型 | 描述说明 | +|-------------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| mode | RK_U32 | 表示图像数据帧场属性: ![](media/Rockchip_Developer_Guide_MPP/MPP_image_data_frame_field_properties.png) | +| pts | RK_U64 | 表示图像的显示时间戳(Present Time Stamp)。 | +| dts | RK_U64 | 表示图像的解码时间戳(Decoding Time Stamp)。 | +| eos | RK_U32 | 表示图像的结束标志(End Of Stream)。 | +| errinfo | RK_U32 | 表示图像的错误标志,是否图像内有解码错误。 | +| discard | RK_U32 | 表示图像的丢弃标志,如果图像解码时的参考关系不满足要求,则这帧图像会被标记为需要丢弃,不被显示。 | +| buf_size | size_t | 表示图像需要分配的缓存大小,与图像的格式相关,也与解码数据的格式相关。 | +| info_change | RK_U32 | 如果为真,表示当前MppFrame是一个用于标记码流信息变化的描述结构,说明了新的宽高,stride,以及图像格式。 可能的info_change原因有: 图像序列宽高变化。 图像序列格式变化,如8bit变为10bit。 一旦info_change产生,需要重新分析解码器使用的内存池。 | +| fmt | MppFrameFormat | 表示图像色彩空间格式以及内存排布方式: ![](media/Rockchip_Developer_Guide_MPP/MPP_image_colorspace_format_and_memory_arrangement.png) | +| color_range | MppFrameColorRange | 表示图像数据彩色空间范围: YUV full range:0 \~ 255(8bit) YUV limit range:16 \~ 235(8bit) ![](media/Rockchip_Developer_Guide_MPP/MPP_color_space_range.png) | +| buffer | MppBuffer | 表示MppFrame对应的MppBuffer。 | + +对于解码器来说,MppFrame是其输出的信息结构体,码流解码后的信息(包括像素数据与pts,错误信息等相关信息)都需要带在MppFrame结构体给调用者。MppFrame中的pts/dts,以及eos标志,就是继承自对应的输入MppPacket。 + +同时,一旦发现码流分辨率改变,MppFrame中的info_change标志就会对应置位,向用户通知发生了info_change事件,需要用户进行缓存池修改处理。 + +## 2.5 高级任务封装MppTask + +当MppPacket与MppFrame组成的接口无法满足需求时,需要使用MppTask做为一个数据容器,来满足复杂的输入输出需求。MppTask需要与poll/dequeuer/enqueue接口来配合使用,对比put_packet/get_frame等简单流程接口,MppTask的使用流程复杂,效率低,是为了满足复杂需求的代价。 + +![](media/Figure08_Use_MppTask_for_input_and_output.png) +
图表 8 使用MppTask来进行输入输出
+ +MppTask是一个通过关键字key值(MppMetaKey)来进行扩展的结构,可以通过扩展支持的数据类型来支持复杂的高级需求。可以使用通过mpp_task_meta_set/get_xxx系列接口来对MppTask里的不同关键字数据进行访问。 + +![](media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask.png) +
图表 9 MppTask支持的数据类型与关键字类型
+ +在实际使用中,需要从MPP的输入端口通过dequeue接口获取MppTask,把需要处理的数据通过mpp_task_meta_set_xxx系列接口配置到MppTask里,之后enqueue输出到MPP实例进行处理。MPP的输出端口流程类似,需要把mpp_task_meta_set_xxx系列接口换成mpp_task_meta_get_xxx系列接口来从MppTask里获取数据。 + +目前实用的编码器接口,以及MJPEG解码接口有使用MppTask进行实现。 + +## 2.6 实例上下文封装MppCtx + +MppCtx是提供给用户使用的MPP实例上下文句柄,用于指代解码器或编码器实例。 + +用户可以通过mpp_create接口获取MppCtx实例以及MppApi结构体,再通过mpp_init来初始化MppCtx的编解码类型与格式,之后通过decode_xxx/encode_xxx以及poll/dequeuer/enqueue接口来进行访问,使用结束时通过mpp_destroy接口进行销毁。 + +![](media/Figure10_MppCtx_usage_process.png) +
图表 10 MppCtx使用过程
+ +## 2.7 API封装MppApi(MPI) + +MppApi结构体封装了MPP的对外API接口,用户通过使用MppApi结构中提供的函数指针实现视频编解码功能,其结构如下: + +| 成员名称 | 成员类型 | 描述 | +| ----------------- | -------- | ------------------------------------------------------------ | +| size | RK_U32 | MppApi结构体大小。 | +| version | RK_U32 | MppApi结构体版本。 | +| decode | 函数指针 | MPP_RET (\*decode)(MppCtx ctx, MppPacket packet, MppFrame \*frame)
视频解码接口,同时进行输入与输出,单独使用。
ctx :MPP实例上下文。
packet :输入码流。
frame :输出图像。
返回值 :0为正常,非零为错误码。 | +| decode_put_packet | 函数指针 | MPP_RET (\*decode_put_packet)(MppCtx ctx, MppPacket packet)
视频解码输入接口,与decode_get_frame配合使用。
ctx :MPP实例上下文。
packet :输入码流。
返回值 :0为正常,表示码流己被MPP处理;非零为出现错误,码流未被处理,需要把码流重新输入。 | +| decode_get_frame | 函数指针 | MPP_RET (\*decode_get_frame)(MppCtx ctx, MppFrame \*frame)
视频解码输出接口,与decode_put_packet配合使用。
ctx :MPP实例上下文。
frame :输出图像。
返回值 :0为正常,表示获取输出过程正常,需要判断是否有得到有值的frame指针;非零为出现错误。 | +| encode | 函数指针 | MPP_RET (\*encode)(MppCtx ctx, MppFrame frame, MppPacket \*packet)
视频编码接口,同时进行输入与输出,单独使用。
ctx :MPP实例上下文。
frame :输入图像。
packet :输出码流。
返回值 :0为正常,非零为错误码。 | +| encode_put_frame | 函数指针 | MPP_RET (\*encode_put_frame)(MppCtx ctx, MppFrame frame)
视频编码输入接口,与encode_get_packet配合使用。
ctx :MPP实例上下文。
frame :输入图像。
返回值 :0为正常,非零为错误码。 | +| encode_get_packet | 函数指针 | MPP_RET (\*encode_get_packet)(MppCtx ctx, MppPacket \*packet)
视频编码输出接口,与encode_put_frame配合使用。
ctx :MPP实例上下文。
packet :输出码流。
返回值 :0为正常,非零为错误码。 | +| poll | 函数指针 | MPP_RET (\*poll)(MppCtx ctx, MppPortType type, MppPollType timeout)
端口查询接口,用于查询端口是否有数据可供dequeue。
ctx :MPP实例上下文。
type :端口类型,分为输入端口与输出端口。
timeout :查询超时参数,-1为阻塞查询,0为非阻塞查询,正值为超时毫秒数。
返回值 :0为正常,有数据可取出,非零为错误码。 | +| dequeue | 函数指针 | MPP_RET (\*dequeue)(MppCtx ctx, MppPortType type, MppTask \*task)
端口出队列接口,用于从端口中取出MppTask结构。
ctx :MPP实例上下文。
type :端口类型,分为输入端口与输出端口。
task :MppTask。
返回值 :0为正常,有数据可取出,非零为错误码。 | +| enqueue | 函数指针 | MPP_RET (\*enqueue)(MppCtx ctx, MppPortType type, MppTask task)
端口入队列接口,用于往端口送入MppTask结构。
ctx :MPP实例上下文。
type :端口类型,分为输入端口与输出端口。
task :MppTask。
返回值 :0为正常,有数据可取出,非零为错误码。 | +| reset | 函数指针 | MPP_RET (\*reset)(MppCtx ctx)
复位接口,用于对MppCtx的内部状态进行复位,回到可用的初始化状态。需要注意的是,reset接口是阻塞的同步接口。
ctx :MPP实例上下文。
返回值 :0为正常,有数据可取出,非零为错误码。 | +| control | 函数指针 | MPP_RET (\*control)(MppCtx ctx, MpiCmd cmd, MppParam param)
控制接口,用于向MPP实例进行额外控制操作的接口。
ctx :MPP实例上下文。
cmd :Mpi命令类型,表示控制命令的不同类型的。
task :Mpi命令参数,表示控制控制命令的附加参数。
返回值 :0为正常,有数据可取出,非零为错误码。 | + +# 第三章 MPI接口使用说明 + +本章节描述了用户使用MPI接口的具体过程,以及过程是的一些注意事项。 + +MPI(Media Process Interface)是MPP提供给用户的接口,用于提供硬件编解码功能,以及一些必要的相关功能。MPI是通过C结构里的函数指针方式提供给用户,用户可以通过MPP上下文结构MppCtx与MPI接口结构MppApi组合使用来实现解码器与编码器的功能。 + +![](media/Figure11_MPI_interface_range.png) +
图表 11 MPI接口范围
+ +如上图所示,mpp_create,mpp_init,mpp_destroy是操作MppCtx接口的过程,其中mpp_create接口也获取到了MPI接口结构体MppApi,真正的编码与解码过程是通过调用MppApi结构体里内的函数指针来实现,也就是上图中红框内的部分。红框内的函数调用分为编解码流程接口put/get_packet/frame和相关的control和reset接口。下文先描述编解码器接口,再对编解码器工作中的一些要点进行说明。 + +## 3.1 解码器数据流接口 + +解码器接口为用户提供了输入码流,输出图像的功能,接口函数为MppApi结构体里的decode_put_packet函数,decode_get_frame函数和decode函数。这组函数提供了最简洁的解码功能支持。 + +### 3.1.1 decode_put_packet + +| 接口定义 | MPP_RET decode_put_packet(MppCtx ctx, MppPacket packet) | +|----------|---------------------------------------------------------| +| 输入参数 | ctx :MPP解码器实例 packet :待输入的码流数据 | +| 返回参数 | 运行错误码 | +| 功能 | 输入packet码流包数据给ctx指定的MPP解码器实例 | + +#### 输入码流的形式 + +MPP的输入都是没有封装信息的裸码流,裸码流输入有两种形式: + +1. 外部分帧 + +一种是外部已经按帧分段的数据,即每一包输入给decode_put_packet函数的MppPacket数据都已经包含完整的一帧,不多也不少。在这种情况下,MPP可以直接按包处理码流,是MPP的默认运行情况。 + +2. 内部分帧 + +另一种是按长度读取的数据,这样的数据无法判断一包MppPacket数据是否是完整的一帧,需要MPP内部进行分帧处理。MPP也可以支持这种形式的输入,但需要在mpp_init之前,通过control接口的MPP_DEC_SET_PARSER_SPLIT_MODE命令,MPP内的need_split标志打开。 + +![](media/Rockchip_Developer_Guide_MPP/MPP_Split_mode_config.png) + +这样,调用decode_put_packet输入的MppPacket就会被MPP重新分帧,进入到情况一的处理。 + +如果这两种情况出现了混用,会出现码流解码出错的问题。 + +分帧方式处理效率高,但需要输入码流之前先进行解析与分帧; + +不分帧方式使用简单,但效率会受影响。 + +在mpi_dec_test的测试用例中,使用的是方式内部分帧的方式。在瑞芯微的Android SDK中,使用的是外部分帧的方式。用户可以根据自己的应用场景和平台条件进行选择。 + +#### 输入码流的消耗 + +输入MppPacket的有效数据长度为length,在送入decode_put_packet之后,如果输入码流被成功地消耗,函数返回值为零(MPP_OK),同时MppPacket的length被清为0。如果输入码流还没有被处理,会返回非零错误码,MppPacket的length保持不变。 + +#### 函数的工作模式 + +decode_put_packet函数的功能是输入待解码码流给MPP实例,但在一些情况下,MPP实例无法接收更多的数据,这时,工作于非阻塞模式的decode_put_packet会报出错误信息并直接返回。用户得到decode_put_packet返回的错误码之后,需要进行一定时间的等待,再重新送入码流数据,避免额外的频繁cpu开销。 + +#### 最大缓冲数据包数量 + +MPP实例默认可以接收4个输入码流包在处理队列中,如果码流送得太快,就会报出错误码要求用户等待后再送。 + +### 3.1.2 decode_get_frame + +| 接口定义 | MPP_RET decode_get_frame(MppCtx ctx, MppFrame \*frame) | +|----------|------------------------------------------------------------| +| 输入参数 | ctx :MPP解码器实例。 frame :用于获取MppFrame实例的指针。 | +| 返回参数 | 运行错误码 | +| 功能 | 从ctx指定的MPP解码器实例里获取完成解码的frame描述信息。 | + +MPP解码输出的图像是通过MppFrame结构来描述的,同时MppFrame结构也是MPP实例输出信息的管道,图像的错误信息,以及变宽高信息(info change)也是带在MppFrame结构进行输出的。 + +- 输出图像的错误信息 + +图像的错误信息为errinfo,表示图像内容是否有错误,errinfo不为零则表示码流解码时发生了错误,图像内容是有问题的,可以做丢弃处理。 + +- 解码器图像空间需求的确认 + +解码器在解码时,需要为输出图像获取保存像素数据的内存空间,用户需要给解码器提供足够大小,这个空间大小的需求,会在MPP解码器内部根据不同的芯片平台以及不同的视频格式需求进行计算,计算后的内存空间需求会通过MppFrame的成员变量buf_size提供给用户。用户需要按buf_size的大小进行内存分配,即可满足解码器的要求。 + +- 输出图像的变宽高信息(Info change) + +当码流的宽高,格式,像素位深等信息发生变化时,需要反馈给用户,用户需要更新解码器使用的内存池,把新的内存更新给解码器。这里涉及到解码内存分配与使用模式,会在3.3.2 图像内存分配以及交互模式进行说明。 + +### 3.1.3 decode + +decode函数是decode_put_packet与decode_get_frame数据的结合,为用户提供了两个函数的复合调用。其内部逻辑为: + +1. 获取输出图像; +2. 如果输出图像获取成功即返回; +3. 判断码流己送入成功则返回; +4. 送入输入码流; +5. 标记码流送入是否成功并循环第一步; + +在用户看来,decode函数首先是获取解码图像,有解码图像优先返回解码图像,没有可输出的解码图像的情况下送入码流,最后再尝试一次获取解码图像并退出。 + +## 3.2 解码器控制接口 + +### 3.2.1 control + +在定义于rk_mpi_cmd.h文件的MpiCmd枚举类型定义了control接口命令字,其中与解码器和解码过程相关的命令如下: + +![](media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type.png) + +从MPP_DEC_CMD_BASE到MPP_DEC_CMD_END之间的命令为解码器的control接口命令,分别介绍这些命令的功能如下: + +- MPP_DEC_SET_FRAME_INFO + +命令参数为MppFrame,用于配置解码器的默认宽高信息,返回的MppFrame结构会从解码器中带出需要分配的图像缓存大小。命令调用时机一般在mpp_init之后,mpi-\>decode_put_packet之前。 + +- MPP_DEC_SET_EXT_BUF_GROUP + +命令参数为MppBufferGroup,用于把解码器图像解码所需的MppBufferGroup配置给解码器。命令调用时机视图像内存分配模式有不同。 + +- MPP_DEC_SET_INFO_CHANGE_READY + +无命令参数,用于标记解码器使用的MppBufferGroup已经完成Info Change操作的reset处理,可以继续解码。命令调用时机视图像内存分配模式有不同。 + +- MPP_DEC_SET_PRESENT_TIME_ORDER + +命令参数为RK_U32\*,用于处理异常的码流时间戳。 + +- MPP_DEC_SET_PARSER_SPLIT_MODE + +命令参数为RK_U32\*,用于使能MPP内的协议解析器使用内部分帧处理,默认为码流按帧输入,不开启。命令调用时机是在- MPP_init之前。 + +- MPP_DEC_SET_PARSER_FAST_MODE + +命令参数为RK_U32\*,用于使能MPP内的快速帧解析,提升解码的软硬件并行度,但副作用是会对错误码流的标志有影响,默认关闭。命令调用时机是在- MPP_init之前。 + +- MPP_DEC_GET_STREAM_COUT + +命令参数为RK_U32\*,用于外部应用获取还未处理的码流包数量,历史遗留接口。 + +- MPP_DEC_GET_VPUMEM_USED_COUT + +命令参数为RK_U32\*,用于外部应用获取MPP使用的MppBuffer数量,历史遗留接口。 + +- MPP_DEC_SET_VC1_EXTRA_DATA + +暂未实现,历史遗留接口。 + +- MPP_DEC_SET_OUTPUT_FORMAT + +命令参数为MppFrameFormat,用于外部应用配置JPEG解码器的输出格式,默认不使用。 + +- MPP_DEC_SET_DISABLE_ERROR + +命令参数为RK_U32\*,用于关闭MPP解码器的错误处理。一旦使能,MPP解码会无视码流的错误情况,输出全部的可解码图像,同时不对输出的MppFrame结构里的errinfo进行标记。命令调用时机在decode_put_packet之前。 + +- MPP_DEC_SET_IMMEDIATE_OUT + +命令参数为RK_U32\*,用于使能H.264解码器的立即输出模式。一旦使能,H.264解码器会忽略丢帧导致的帧序不连续情况,立即输出解码的图像。命令调用时机在decode_put_packet之前。 + +### 3.2.2 reset + +reset接口用于把解码器恢复为正常初始化后的状态。 + +当用户发送最后一包MppPacket码流,并置上EOS标记送入解码器,解码器在处理完这最后一包数据之后会进入EOS的状态,不再接收和处理码流,需要reset之后再才能再继续接收新的码流。 + +## 3.3 解码器使用要点 + +解码器在使用过程中,需要注意的一些重要事项: + +### 3.3.1 解码器单/多线程使用方式 + +MPP解码器的MPI接口是线程安全的,可以在多线环境下使用。单线程工作模式如mpi_dec_test的demo所示,多线程工作模式如mpi_dec_mt_test的demo所示。 + +![](media/Figure12_Decoder_single_thread_usage.png) + +![](media/Figure12_Decoder_multi_thread_usage.png) + +
图表 12 解码器单线程与多线程使用方式
+ +### 3.3.2 图像内存分配以及交互模式 + +解码器在解码图像时,需要获取内存空间以写入数据,在解码完成之后,这块内存空间需要交给用户使用,在用户使用完成之后要释放给解码器,在关闭解码器时要释放全部内存空间。在这种工作方式下,解码器与用户之间才可以形成零拷贝的数据交互。MPP解码器支持三种内存分配以及与用户交互图像数据的模式: + +#### 模式一:纯内部分配模式 + +图像内存直接从MPP解码器内部分配,内存由解码器直接分配,用户得到解码器输出图像,在使用完成之后直接释放。 + +![](media/Figure13_Schematic_diagram_of_pure_internal_allocation_mode.png) +
图表 13 解码器图像内存纯内部分配模式示意图
+ +在这种方式下,用户不需要调用解码器control接口的MPP_DEC_SET_EXT_BUF_GROUP命令,只需要在解码器上报info change时直接调用control接口的MPP_DEC_SET_INFO_CHANGE_READY命令即可。解码器会自动在内部进行内存分配,用户需要把获取到的每帧数据直接释放。 + +![](media/Figure14_Code_flow_of_decoder_image_memory_pure_internal_allocation_mode.png) +
图表 14 解码器图像内存纯内部分配模式代码流程
+ +**优点:** + +过程简单,可以快速完成一个可用的demo,评估解码器的性能。 + +**缺点:** + +1. 内存都是从解码器内部分配的,如果内存在解码器被销毁时还没有被释放,有可能出现内存泄漏或崩溃问题。 +2. 无法控制解码器的内存使用量。解码器可以不受限制地使用内存,如果码流输入的速度很快,用户又没有及时释放内存,解码器会很快消耗掉全部的可用内存。 +3. 实现零拷贝的显示比较困难,因为内存是从解码器内部分配的,不一定和用户的显示系统兼容。 + +#### 模式二:半内部分配模式 + +这种模式是mpi_dec_test demo使用的默认模式。用户需要根据get_frame返回的MppFrame的buf_size来创建MppBufferGroup,并通过control接口的MPP_DEC_SET_EXT_BUF_GROUP配置给解码器。用户可以通过mpp_buffer_group_limit_config接口来限制解码器的内存使用量。 + +![](media/Figure15_Semi-internal_allocation_mode_decoder_work_flow.png) +
图表 15 解码器图像内存半内部分配模式代码流程
+ +**优点:** + +过程简单,易上手,可以一定程度限制内存的使用。 + +**缺点:** + +1. 内存空间的限制并不准确,内存的使用量不是100%固定的,会有波动。 +2. 同样难于实现零拷贝的显示。 + +#### 模式三:纯外部分配模式 + +这种模式通过创建空的external模式的MppBufferGroup,从用户那里导入外部分配器分析的内存块文件句柄(一般是dmabuf/ion/drm)。在Android平台上,Mediaserver通过gralloc从SurfaceFlinger获取显示用内存,把gralloc得到的文件句柄提交(commit)到MppBufferGroup里,再把MppBufferGroup通过control接口MPP_DEC_SET_EXT_BUF_GROUP命令配置给解码器,然后MPP解码器将循环使用gralloc得到的内存空间。 + +![](media/Figure16_Schematic_diagram_of_pure_external_allocation_mode.png) +
图表 16 解码器图像内存纯外部分配模式示意图
+ +![](media/Figure17_Pure_external_allocation_mode_decoder_work_flow.png) +
图表 17 解码器图像内存纯外部分配模式代码流程
+ +**优点:** + +直接使用外部显示用的内存,容易实现零拷贝。 + +**缺点:** + +1. 理解与使用较困难。 +2. 需要修改用户程序,一些用户程序的调用方式限制了纯外部分配方式的使用。 + +**纯外部分配模式使用时的注意事项:** + +1. 如果图像内存分配是在解码器创建之前,需要有额外的方式来得到图像内存的大小。 + +一般的YUV420图像内存空间计算方法: + +图像像素数据:hor_stride \* ver_stride \* 3 / 2 +额外附加信息:hor_stride \* ver_stride / 2 + +2. 内存块数需要考虑解码和显示的需求,如果内存块数分配得太少,可能会卡住解码器。 + +H.264/H.265这类参考帧较多的协议需要20+内存块能保证一定能解码。其它协议需要10+内存块能保证一定能解码。 + +3. 如果在码流解码过程中发生了info change,需要把已有的MppBufferGroup进行reset,再commit进新的图像缓存,同时外部的显示也需要相应调整。 + + +## 3.4 编码器数据流接口 + +编码器接口为用户提供了输入图像,输出码流的功能,接口函数为MppApi结构体里的encode_put_frame函数, encode_get_packet函数和encode函数。这组函数提供了简洁的编码功能支持。 + +### 3.4.1 encode_put_frame + +| 接口定义 | MPP_RET encode_put_frame(MppCtx ctx, MppFrame frame) | +|----------|------------------------------------------------------| +| 输入参数 | ctx :MPP解码器实例 frame :待输入的图像数据 | +| 返回参数 | 运行错误码 | +| 功能 | 输入frame图像数据给ctx指定的MPP编码器实例 | + +#### 函数的工作模式 + +由于编码器的输入图像一般都比较大,如果进行拷贝,效率会大幅度下降,所以编码器的输入函数需要等待编码器硬件完成对输入图像内存的使用,才能把输入函数返回,把使用后的图像归还给调用者。基于以上的考虑,encode_put_frame是阻塞式函数,会把调用者阻塞住,直到输入图像使用完成,会一定程度上导致软硬件运行无法并行,效率下降。 + +#### 拷贝与零拷贝输入 + +编码器的输入不支持CPU分配的空间,如果需要支持编码CPU分配的地址,需要分配MppBuffer并把数据拷贝进去,这样做会很大程度影响效率。编码器更喜欢dmabuf/ion/drm内存形式的输入,这样可以实现零拷贝的编码,额外的系统开销最小。 + +### 3.4.2 encode_get_packet + +| 接口定义 | MPP_RET encode_get_packet(MppCtx ctx, MppPacket \*packet) | +|----------|------------------------------------------------------------| +| 输入参数 | ctx :MPP解码器实例 packet :用于获取MppPacket实例的指针。 | +| 返回参数 | 运行错误码 | +| 功能 | 从ctx指定的MPP编码器实例里获取完成编码的packet描述信息。 | + +#### 取头信息与图像数据 + +以H.264编码器为例,编码器的输出数据分为头信息(sps/pps)和图像数据(I/P slice)两部分,头信息需要通过control接口的MPP_ENC_GET_EXTRA_INFO命令获取,图像数据则是通过encode_get_packet接口来获取。获取的时机是在control接口的SET_RC_CFG/SET_PREP_CFG/SET_CODEC_CFG参数配置命令完成之后。在参数配置命令调用时,编码器会进行各个参数的更新,在更新全部完成之后,调用MPP_ENC_GET_EXTRA_INFO获取到的头信息才是最新的。 + +#### H.264编码器输出码流的格式 + +目前硬件固定输出带00 00 00 01起始码的码流,所以encode_get_packet函数获取到码流都是带有00 00 00 01起始码。如果需要去掉起始码,可以从起始码之后的地址进行拷贝。 + +#### 码流数据的零拷贝 + +由于使用encode_put_frame和encode_get_packet接口时没有提供配置输出缓存的方法,所以使用encode_get_packet时一定会进行一次拷贝。一般来说,编码器的输出码流相对于输入图像不算大,数据拷贝可以接受。如果需要使用零拷贝的接口,需要使用enqueue/dequeue接口以及MppTask结构。 + +### 3.4.3 encode + +暂未实现 + +## 3.5 编码器控制接口 + +编码器与解码器不同,需要用户进行一定的参数配置。编码器需要用户通过control接口配置编码器信息之后才可以进行编码工作。 + +### 3.5.1 control与MppEncCfg + +MPP推荐使用封装后的MppEncCfg结构通过control接口的MPP_ENC_SET_CFG/MPP_ENC_GET_CFG命令来进行编码器信息配置。 + +由于编码器可配置的选项与参数繁多,使用固定结构体容易出现接口结构体频繁变化,导致接口二进制兼容性无法得到保证,版本管理复杂,极大增加维护量。 + +为了缓解这个问题MppEncCfg使用(void \*)作为类型,使用<字符串-值>进行key map式的配置,函数接口分为s32/u32/s64/u64/ptr,对应的接口函数分为set与get两组,如下: + +```c +配置编码器信息: +MPP_RET mpp_enc_cfg_set_s32(MppEncCfg cfg, const char *name, RK_S32 val); +MPP_RET mpp_enc_cfg_set_u32(MppEncCfg cfg, const char *name, RK_U32 val); +MPP_RET mpp_enc_cfg_set_s64(MppEncCfg cfg, const char *name, RK_S64 val); +MPP_RET mpp_enc_cfg_set_u64(MppEncCfg cfg, const char *name, RK_U64 val); +MPP_RET mpp_enc_cfg_set_ptr(MppEncCfg cfg, const char *name, void *val); +MPP_RET mpp_enc_cfg_set_st(MppEncCfg cfg, const char *name, void *val); +获取编码器信息: +MPP_RET mpp_enc_cfg_get_s32(MppEncCfg cfg, const char *name, RK_S32 *val); +MPP_RET mpp_enc_cfg_get_u32(MppEncCfg cfg, const char *name, RK_U32 *val); +MPP_RET mpp_enc_cfg_get_s64(MppEncCfg cfg, const char *name, RK_S64 *val); +MPP_RET mpp_enc_cfg_get_u64(MppEncCfg cfg, const char *name, RK_U64 *val); +MPP_RET mpp_enc_cfg_get_ptr(MppEncCfg cfg, const char *name, void **val); +MPP_RET mpp_enc_cfg_get_st(MppEncCfg cfg, const char *name, void *val); +``` + + +字符串一般用\[类型:参数\]的方式进行定义,可支持的字符串与参数类型如下: + +| 参数字串 | 接口 | 实际类型 | 描述说明 | +| ----------------------- | ---- | ----------------------------------- | ------------------------------------------------------------ | +| base:low_delay | S32 | RK_S32 | 表示低延时输出模式。 0 – 表示关闭;1 – 表示开启。 | +| rc:mode | S32 | MppEncRcMode | 表示码率控制模式,目前支持CBR、VBR和AVBR三种: CBR为Constant Bit Rate,固定码率模式。 在固定码率模式下,目标码率起决定性作用。 VBR为Variable Bit Rate,可变码率模式。 在可变码率模式下,最大最小码率起决定性作用。 AVBR为Adaptive Variable Bit Rate,自适应码率模式。 在自适应码率模式下,静止场景中最小码率起决定性作用,运动场景中最大码率起决定性作用。最终平均码率将接近目标码率。 FIX_QP为固定QP模式,用于调试和性能评估。 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcMode.png) | +| rc:bps_target | S32 | RK_S32 | 表示CBR模式下的目标码率。 | +| rc:bps_max | S32 | RK_S32 | 表示VBR/AVBR模式下的最高码率。 | +| rc:bps_min | S32 | RK_S32 | 表示VBR/AVBR模式下的最低码率。 | +| rc:fps_in_flex | S32 | RK_S32 | 表示输入帧率是否可变的标志位,默认为0。 为0表示输入帧率固定,帧率计算方式为: fps_in_num / fps_in_denorm,可以表示分数帧率。 为1表示输入帧率可变。可变帧率的情况下,帧率不固定,对应的码率计算与分配的规则变为按实际时间进行计算。 | +| rc:fps_in_num | S32 | RK_S32 | 表示输入帧率分数值的分子部分,默认值为30。 | +| rc:fps_in_denorm | S32 | RK_S32 | 表示输入帧率分数值的分母部分,默认值为1。 | +| rc:fps_out_flex | S32 | RK_S32 | 表示输出帧率是否可变的标志位,默认为0。 为0表示输出帧率固定,帧率计算方式为: fps_out_num / fps_out_denorm,可以表示分数帧率。 为1表示输出帧率可变。可变帧率的情况下,帧率不固定,对应的码流输出时间按实际时间进行计算。 | +| rc:fps_out_num | S32 | RK_S32 | 表示输出帧率分数值的分子部分,默认值为30。 | +| rc:fps_out_denorm | S32 | RK_S32 | 表示输出帧率分数值的分母部分,默认值为1。 | +| rc:gop | S32 | RK_S32 | 表示Group Of Picture,即两个I帧之间的间隔,含义如下: 0 – 表示只有一个I帧,其他帧均为P帧。 1 – 表示全为I帧。 2 – 表示序列为I P I P I P… 3 – 表示序列为I P P I P P I P P… 一般情况下,gop应配置为输出帧率的整数倍,默认值为两倍输出帧率。 | +| rc:max_reenc_times | U32 | RK_U32 | 表示一帧图像最大重编码次数,默认值为1。在低延时输出模式下,max_reenc_times只能配置为0。 | +| rc:priority | U32 | MppEncRcPriority | 表示超大帧重编优先级。 0 – 表示目标码率优先。 1 – 表示超大帧阈值优先。 此优先级只在超大帧重编时有效。 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcPriority.png) | +| rc:drop_mode | U32 | MppEncRcDropFrmMode | 表示丢帧模式。 0 – 表示丢帧模式未使能。 1 – 表示正常丢帧模式。当瞬时码率超过丢帧阈值时,正常丢帧。 2 – 表示pskip构造模式。当瞬时码率超过丢帧阈值时,编码pskip帧替代当前帧。 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcDropFrmMode.png) | +| rc:drop_thd | U32 | RK_U32 | 表示丢帧阈值控制变量,默认值为20。丢帧阈值计算公式为: bps_max \* (1 + drop_thd / 100)。 | +| rc:drop_gap | U32 | RK_U32 | 表示最大允许连续丢帧数。当输出码流的poc_type为2时,drop_gap只能配置为1。 | +| rc:max_i_prop | S32 | RK_S32 | 表示最大 IP 比例,用于钳位IP比例的范围,默认值为30。当max_i_proportion被调整较小时,会导致I帧模糊,P 帧清晰。 | +| rc:min_i_prop | S32 | RK_S32 | 表示最小 IP 比例,用于钳位IP比例的范围,默认值为10。当min_i_proportion被调整较大时,会导致I帧清晰,P 帧模糊。 | +| rc:init_ip_ratio | S32 | RK_S32 | 表示初始IP比例,默认值为160。IP比例表示I帧和P帧的bits数的比例,有效范围为\[160, 640\]。 | +| rc:super_mode | U32 | MppEncRcSuperFrameMode | 表示超大帧处理模式。 0 – 表示无特殊策略。 1 – 表示丢弃超大帧。 2 – 表示重编超大帧。
![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcSuperFrameMode.png) | +| rc:super_i_thd | U32 | RK_U32 | 表示超大I帧阈值。 | +| rc:super_p_thd | U32 | RK_U32 | 表示超大P帧阈值。 | +| rc:debreath_en | U32 | RK_U32 | 表示去除呼吸效应使能标志。 0 – 表示关闭;1 – 表示开启。 | +| rc:debreath_strength | U32 | RK_U32 | 表示去除呼吸效应强度调节参数,有效范围为\[0, 35\]。值越大,呼吸效应改善会越弱;值越小,呼吸效应改善越明显。 | +| rc:qp_init | S32 | RK_S32 | 表示初始QP值。 | +| rc:qp_min | S32 | RK_S32 | 表示P、B帧的最小QP值。 | +| rc:qp_max | S32 | RK_S32 | 表示P、B帧的最大QP值。 | +| rc:qp_min_i | S32 | RK_S32 | 表示I帧的最小QP值。 | +| rc:qp_max_i | S32 | RK_S32 | 表示I帧的最大QP值。 | +| rc:qp_step | S32 | RK_S32 | 表示相临两帧之间的帧级QP变化幅度。目前仅配备于RV1109/RV1126系统芯片,默认值为4。 | +| rc:qp_ip | S32 | RK_S32 | 表示I帧和P帧的QP差值,有效范围为\[0, 8\]。 | +| rc:qp_vi | S32 | RK_S32 | 表示虚拟I帧和P帧的QP差值,有效范围为\[0, 6\]。 | +| rc:hier_qp_en | S32 | RK_S32 | 表示QP分层使能标识。 0 – 表示关闭;1 – 表示开启。 | +| rc:hier_qp_delta | St | RK_S32 \* | 表示各层帧相对于第0层P帧的QP差值,层数为4,用数组存储。 | +| rc:hier_frame_num | St | RK_S32 \* | 表示各层帧数,层数为4,用数组存储。 | +| rc:stats_time | S32 | RK_S32 | 表示瞬时码率统计时间,单位为秒,有效范围为\[1, 60\]。默认值为3。 | +| prep:width | S32 | RK_S32 | 表示图像水平方向像素数,单位为像素个数。 | +| prep:height | S32 | RK_S32 | 表示图像垂直方向像素数,单位为像素个数。 | +| prep:format | S32 | MppFrameFormat | 表示图像色彩空间格式以及内存排布方式。 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppFrameFormat.png) | +| prep:hor_stride | S32 | RK_S32 | 表示图像垂直方向相邻两行之间的距离,单位为byte数。 | +| prep:ver_stride | S32 | RK_S32 | 表示图像分量之间的以行数间隔数,单位为1。 | +| prep:colorspace | S32 | MppFrameColorSpace | 表示VUI信息中色域空间类型,用于colour_primaries和transfer_characteristics的备注。 | +| prep:colorprim | S32 | MppFrameColorPrimaries | 表示VUI信息中colour_primaries参数,具体含义请参考H.264/H.265协议。 | +| prep:colortrc | S32 | MppFrameColorTransferCharacteristic | 表示VUI信息中transfer_characteristics参数,具体含义请参考H.264/H.265协议。 | +| prep:colorrange | S32 | MppFrameColorRange | 表示YUV转RGB的色彩范围。 0 – 表示未指定,由MPP配置。 1 – 表示码流格式为MPEG,限制色彩范围。 2 – 表示码流格式为JPEG,不限制色彩范围。 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppFrameColorRange.png) | +| prep:range | S32 | MppFrameColorRange | 同prep:colorrange,用于前向兼容MPP版本。 | +| prep:rotation | S32 | MppEncRotationCfg | 表示图像旋转属性,默认值为0。除了RK3588芯片,其他芯片均不支持FBC数据结构的旋转操作。 0 – 表示图像不旋转。 1 – 表示图像逆时针旋转90度。 2 – 表示图像逆时针旋转180度。 3 – 表示图像逆时针旋转270度。 | +| prep:mirroring | S32 | RK_S32 | 表示图像镜像属性,默认值为0。除了RK3588芯片,其他芯片均不支持FBC数据结构的镜像操作。 0 – 表示图像不做镜像。 1 – 表示图像做水平镜像。 2 – 表示图像做垂直镜像。 | +| codec:type | S32 | MppCodingType | 表示MppEncCodecCfg对应的协议类型,需要与MppCtx初始化函数mpp_init的参数一致。 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppCodingType.png) | +| h264:stream_type | S32 | RK_S32 | 表示H.264码流格式类型。 0 – 表示Annex-B格式,即用00 00 00 01的起始码对齐、分割码流数据。 1 – 表示AVCC格式,仅支持extradata中码流的解析。 目前MPP内部固定为带00 00 00 01起始码的格式。 | +| h264:profile | S32 | RK_S32 | 表示SPS中的profile_idc参数。 ![](media/Rockchip_Developer_Guide_MPP/MPP_H264Profile.png) | +| h264:level | S32 | RK_S32 | 表示SPS中的level_idc参数,其中10表示level 1.0: 10/11/12/13 – qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps 20/21/22 – cif@30fps / half-D1@25fps / D1@12.5fps 30/31/32 – D1@25fps / 720p@30fps / 720p@60fps 40/41/42 – 1080p@30fps / 1080p@30fps / 1080p@60fps 50/51/52 – 4K@30fps / 4K@30fps / 4K@60fps 一般配置为level 4.1即可满足要求。 | +| h264:poc_type | U32 | RK_U32 | 表示SPS中的pic_order_cnt_type参数。 | +| h264:log2_max_poc_lsb | U32 | RK_U32 | 表示SPS中的log2_max_pic_order_cnt_lsb_minus4参数,只在pic_order_cnt_type为0时使用。 | +| h264:log2_max_frm_num | U32 | RK_U32 | 表示SPS中的log2_max_frame_num_minus4参数。 | +| h264:gaps_not_allowed | U32 | RK_U32 | 表示SPS中的gaps_in_frame_num_value_allowed_flag参数的非。 | +| h264:cabac_en | S32 | RK_S32 | 表示编码器使用的熵编码格式。 0 – 表示CAVLC,自适应变长编码。 1 – 表示CABAC,自适应算术编码。 | +| h264:cabac_idc | S32 | RK_S32 | 表示H.264协议中的cabac_init_idc参数,只在cabac_en为1时使用,有效范围为\[0, 2\]。 | +| h264:trans8x8 | S32 | RK_S32 | 表示H.264协议中transform_8x8_mode_flag参数,即8x8变换的使能标志。 0 – 表示关闭,在Baseline/Main profile时固定关闭。 1 – 表示开启,在High profile时可选开启。 | +| h264:const_intra | S32 | RK_S32 | 表示H.264协议中constrained_intra_pred_flag参数,即 constrained_intra_pred_mode模式使能标志。 0 – 表示关闭;1 – 表示开启。 | +| h264:scaling_list | S32 | RK_S32 | 表示H.264协议中scaling_list_matrix模式。 0 – 表示flat matrix;1 – 表示默认matrix。 | +| h264:cb_qp_offset | S32 | RK_S32 | 表示H.264协议中chroma_qp_index_offset参数,即应添加到QPY和QSY的偏移量,用于寻址Cb色度分量的QPC表,有效范围为\[-12, 12\]。 | +| h264:cr_qp_offset | S32 | RK_S32 | 表示H.264协议中second_chroma_qp_index_offset参数,即应添加到QPY和QSY的偏移量,用于寻址Cr色度分量的QPC表,有效范围为\[-12, 12\]。 | +| h264:dblk_disable | S32 | RK_S32 | 表示H.264协议中deblocking_filter_control_present_flag参数,即deblock禁用标志,有效范围为\[0, 2\]。
0 – deblocking开启。
1 – deblocking关闭。
2 – 在slice边界关闭deblocking。 | +| h264:dblk_alpha | S32 | RK_S32 | 表示H.264协议中slice_alpha_c0_offset_div2参数,有效范围为\[-6, 6\]。 | +| h264:dblk_beta | S32 | RK_S32 | 表示H.264协议中slice_beta_offset_div2参数,有效范围为\[-6, 6\]。 | +| h264:qp_init | S32 | RK_S32 | 表示初始QP值,同rc:qp_init,用于前向兼容MPP版本。 | +| h264:qp_max | S32 | RK_S32 | 表示P、B帧的最大QP值,同rc:qp_max,用于前向兼容MPP版本。 | +| h264:qp_min | S32 | RK_S32 | 表示P、B帧的最小QP值,同rc:qp_min,用于前向兼容MPP版本。 | +| h264:qp_max_i | S32 | RK_S32 | 表示I帧的最大QP值,同rc:qp_max_i,用于前向兼容MPP版本。 | +| h264:qp_min_i | S32 | RK_S32 | 表示I帧的最小QP值,同rc:qp_min_i,用于前向兼容MPP版本。 | +| h264:qp_step | S32 | RK_S32 | 表示相临两帧之间的帧级QP变化幅度,同rc:qp_step,用于前向兼容MPP版本。 | +| h264:qp_delta_ip | S32 | RK_S32 | 表示I帧和P帧的QP差值,同rc:qp_ip,用于前向兼容MPP版本。 | +| h264:max_tid | S32 | RK_S32 | 表示最大时序层ID。 | +| h264:max_ltr | S32 | RK_S32 | 表示最大长期参考帧数。 | +| h264:prefix_mode | S32 | RK_S32 | 表示添加prefix nal的使能标志。 0 – 表示关闭。 1 – 表示开启,在SEI信息和硬件编码的码流数据之间添加prefix nal。 | +| h264:base_layer_pid | S32 | RK_S32 | 表示基准层优先级ID。 | +| h264:constraint_set | U32 | RK_U32 | 表示SPS中的constraint_set0_flag至constraint_set5_flag参数。 | +| h265:profile | S32 | RK_S32 | 表示VPS中的profile_idc参数。目前MPP内部固定为1,Main profile。 | +| h265:level | S32 | RK_S32 | 表示VPS中的level_idc参数。 | +| h265:scaling_list | S32 | RK_S32 | 表示H.265协议中scaling_list_matrix模式。 0 – 表示flat matrix,1 – 表示默认matrix。 | +| h265:cb_qp_offset | S32 | RK_S32 | 表示H.265协议中chroma_qp_index_offset参数,即应添加到QPY和QSY的偏移量,用于寻址Cb色度分量的QPC表,有效范围为\[-12, 12\]。 | +| h265:cr_qp_offset | S32 | RK_S32 | 表示H.265协议中second_chroma_qp_index_offset参数,即应添加到QPY和QSY的偏移量,用于寻址Cr色度分量的QPC表,有效范围为\[-12, 12\]。 | +| h265:dblk_disable | S32 | RK_S32 | 表示H.265协议中deblocking_filter_control_present_flag参数,即deblock禁用标志,有效范围为\[0, 2\]。
0 – deblocking开启。
1 – deblocking关闭。
2 – 在slice边界关闭deblocking。 | +| h265:dblk_alpha | S32 | RK_S32 | 表示H.265协议中slice_alpha_c0_offset_div2参数,有效范围为\[-6, 6\]。 | +| h265:dblk_beta | S32 | RK_S32 | 表示H.265协议中slice_beta_offset_div2参数,有效范围为\[-6, 6\]。 | +| h265:qp_init | S32 | RK_S32 | 表示初始QP值,同rc:qp_init,用于前向兼容MPP版本。 | +| h265:qp_max | S32 | RK_S32 | 表示P、B帧的最大QP值,同rc:qp_max,用于前向兼容MPP版本。 | +| h265:qp_min | S32 | RK_S32 | 表示P、B帧的最小QP值,同rc:qp_min,用于前向兼容MPP版本。 | +| h265:qp_max_i | S32 | RK_S32 | 表示I帧的最大QP值,同rc:qp_max_i,用于前向兼容MPP版本。 | +| h265:qp_min_i | S32 | RK_S32 | 表示I帧的最小QP值,同rc:qp_min_i,用于前向兼容MPP版本。 | +| h265:qp_step | S32 | RK_S32 | 表示相临两帧之间的帧级QP变化幅度,同rc:qp_step,用于前向兼容MPP版本。 | +| h265:qp_delta_ip | S32 | RK_S32 | 表示I帧和P帧的QP差值,同rc:qp_ip,用于前向兼容MPP版本。 | +| h265:sao_luma_disable | S32 | RK_S32 | 表示H.265协议中slice_sao_luma_flag参数的非,即当前slice亮度分量的采样点自适应偏移的禁用标志。
0 – 亮度分量的SAO开启。
1 – 亮度分量的SAO关闭。 | +| h265:sao_chroma_disable | S32 | RK_S32 | 表示H.265协议中slice_sao_chroma_flag参数的非,即当前slice色度分量的采样点自适应偏移的禁用标志。
0 – 色度分量的SAO开启。
1 – 色度分量的SAO关闭。 | +| vp8:qp_init | S32 | RK_S32 | 表示初始QP值,同rc:qp_init,用于前向兼容MPP版本。 | +| vp8:qp_max | S32 | RK_S32 | 表示P、B帧的最大QP值,同rc:qp_max,用于前向兼容MPP版本。 | +| vp8:qp_min | S32 | RK_S32 | 表示P、B帧的最小QP值,同rc:qp_min,用于前向兼容MPP版本。 | +| vp8:qp_max_i | S32 | RK_S32 | 表示I帧的最大QP值,同rc:qp_max_i,用于前向兼容MPP版本。 | +| vp8:qp_min_i | S32 | RK_S32 | 表示I帧的最小QP值,同rc:qp_min_i,用于前向兼容MPP版本。 | +| vp8:qp_step | S32 | RK_S32 | 表示相临两帧之间的帧级QP变化幅度,同rc:qp_step,用于前向兼容MPP版本。 | +| vp8:qp_delta_ip | S32 | RK_S32 | 表示I帧和P帧的QP差值,同rc:qp_ip,用于前向兼容MPP版本。 | +| vp8:disable_ivf | S32 | RK_S32 | 表示ivf封装的禁用标志,禁用后硬件编码的码流数据不封装成ivf格式。
0 – 表示开启;
1 – 表示关闭。 | +| jpeg:quant | S32 | RK_S32 | 表示JPEG编码器使用的量化参数等级,编码器一共内置了11级量化系数表格,从0到10,图像质量从差到好。 | +| jpeg:qtable_y | Ptr | RK_U8 \* | 表示样本亮度分量量化表,大小为64,用数组存储。 | +| jpeg:qtable_u | Ptr | RK_U8 \* | 表示样本色度分量u量化表,大小为64,用数组存储。 | +| jpeg:qtable_v | Ptr | RK_U8 \* | 表示样本色度分量v量化表,大小为64,用数组存储。 | +| jpeg:q_factor | S32 | RK_S32 | 表示量化表因子,有效范围为\[1, 99\]。qfactor 越大,量化表中的量化系数越小,得到的图像质量更好,但编码压缩率更低。同理,qfactor 越小,量化表中的量化系数越大,编码压缩率更高,但得到的图像质量更差。默认值为80。 | +| jpeg:qf_max | S32 | RK_S32 | 表示量化表因子最大值,默认值为99。 | +| jpeg:qf_min | S32 | RK_S32 | 表示量化表因子最小值,默认值为1。 | +| split:mode | U32 | MppEncSplitMode | 表示H.264/H.265协议的slice切分模式 ![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncSplitMode.png)
0– 不切分。
1– BY_BYTE 切分 slice 根据 slice 大小。
2– BY_CTU 切分 slice 根据宏块或 CTU 个数。 | +| split:arg | U32 | RK_U32 | Slice切分参数: 在BY_BYTE模式下,参数表示每个slice的最大大小。 在BY_CTU模式下,参数表示每个slice包含的宏块或CTU个数。 | + +其他的字符串与参数会进行后续扩展。 + +### 3.5.2 control其他命令 + +在定义于rk_mpi_cmd.h文件的MpiCmd枚举类型定义了control接口命令字,其中与编码器和编码过程相关的命令如下: + +![](media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type_related_to_MPP.png) + +从MPP_ENC_CMD_BASE到MPP_ENC_CMD_END之间的命令为编码器的control接口命令,其中配置命令的MPP_ENC_SET/GET\_ CFG已经做为基本的配置命令在3.5.1进行了介绍。剩下的命令在下面进行简要的介绍,其中的命令与编码器硬件相关,只有部分硬件支持。 + +目前MPP支持的编码器硬件分为vepu系列和rkvenc系列,vepu系列支持H.264编码,vp8编码和jpeg编码,配备于绝大多数RK芯片中。rkvenc系列只支持H.264编码,目前只配备于RV1109/RV1126系统芯片,其支持的编码功能相对于vepu系统会更多更强。 + +部分CMD命令简要说明: + +- ~~MPP_ENC_SET_PREP_CFG/ MPP_ENC_GET_PREP_CFG~~ + +- ~~MPP_ENC_SET_RC_CFG/ MPP_ENC_GET_RC_CFG~~ + +- ~~MPP_ENC_SET_CODEC_CFG/ MPP_ENC_GET_CODEC_CFG~~ + +废弃命令,为了前向兼容保留,不要使用 + +- MPP_ENC_SET_IDR_FRAME + +无命令参数,用于向编码器请求I帖,编码器收到请求之后,会将待编码的下一帧编码为IDR帧。 + +全部硬件都支持。 + +- ~~MPP_ENC_SET_OSD_LEGACY_0~~ + +- ~~MPP_ENC_SET_OSD_LEGACY_1~~ + +- ~~MPP_ENC_SET_OSD_LEGACY_2~~ + +废弃命令,前向兼容用保留,不要使用 + +- MPP_ENC_GET_HDR_SYNC/ ~~MPP_ENC_GET_EXTRA_INFO~~ + +用于单独获取码流头数据的命令,其中MPP_ENC_GET_EXTRA_INFO为旧命令,不推荐使用。 + +MPP_ENC_GET_HDR_SYNC输入参数为MppPacket,需要外部用户分配好空间并封装为MppPacket再control到编码器,control接口调用返回时就完成了数据拷贝,线程安全。调用时机在编码器基本配置完成之后。需要用户手动释放之前分配的MppPacket。 + +MPP_ENC_GET_EXTRA_INFO输入参数为MppPacket\*,会获取编码器的内部MppPacket来进行访问。调用时机在编码器基本配置完成之后。需要注意的是,这里得到的MppPacket是MPP的内部空间,不需要用户释放。 + +由于在多线程情况下,MPP_ENC_GET_EXTRA_INFO命令获取的MppPacket有可能在读取时被其他control修改,所以这个命令并不是线程安全的,仅做为旧vpu_api的兼容用,不要再使用。 + +- ~~MPP_ENC_SET_SEI_CFG/MPP_ENC_GET_SEI_DATA~~ + +废弃命令,前向兼容用保留,不要使用 + +- ~~MPP_ENC_PRE_ALLOC_BUFF/ MPP_ENC_SET_QP_RANGE/ MPP_ENC_SET_ROI_CFG/ MPP_ENC_SET_CTU_QP~~ + +废弃命令,前向兼容用保留,不要使用 + +- MPP_ENC_GET_RC_API_ALL + +获取MPP目前支持的码率控制策略API信息的接口,输入 RcApiQueryAll\*指针,在返回时填充好结构体内容 + +- MPP_ENC_GET_RC_API_BY_TYPE + +获取指定MppCodingType类型的所有码率控制策略API信息,输入RcApiQueryType\*指针并指定MppCodingType,在返回时会填充好结构体内容。 + +- MPP_ENC_SET_RC_API_CFG + +注册外部码率控制策略API,输入RcImplApi\*指针,该结构中的函数指针定义了码率控制策略插件的行为,注册之后的码率控制策略才可以被查询和激活使用。 + +- MPP_ENC_GET_RC_API_CURRENT + +返回当前使用的码率控制策略API信息,输入RcApiBrief\*指针,在返回时会填充好结构体内容。 + +- MPP_ENC_SET_RC_API_CURRENT + +激活指定名字的码率控制策略API,输入RcApiBrief\*指针,编码器会搜索到RcApiBrief中指定字符串名字的码率控制策略API并激活为当前码率控制策略。 + +- MPP_ENC_SET_HEADER_MODE/MPP_ENC_GET_HEADER_MODE + +配置和获取H.264/H.265编码器的SEI调试信息输出方式,调试用开关,以后会被环境变量取代,不要使用。 + +- MPP_ENC_SET_SPLIT/MPP_ENC_GET_SPLIT + +配置和获取H.264/H265编码器的slice切分配置信息,己被MppEncCfg中的split:mode和split:arg取代,不要使用 + +- MPP_ENC_SET_REF_CFG + +配置编码器高级参考帧模式,默认不需要配置,在需要配置长期参考帧,短期参考帧参考关系模式时使用,用于配置特殊的参考关系模式。高级接口,文档待完善。 + +- MPP_ENC_SET_OSD_PLT_CFG + +用于配置rkvenc系列硬件的OSD调色板,命令参数为MppEncOSDPlt。一般只在编码开始时配置一次,全编码过程使用统一的调色板。仅RV1109/RV1126系列支持。 + +- MPP_ENC_GET_OSD_PLT_CFG + +用于获取rkvenc系列硬件的OSD调色板,命令参数为MppEncOSDPlt\*。一般不使用 + +- MPP_ENC_SET_OSD_DATA_CFG + +用于配置rkvenc系列硬件的OSD数据,命令参数为MppEncOSDData。需要每帧进行配置,每编码一帧之后需要重新配置。本命令被MppFrame带的MppMeta中的KEY_OSD_DATA进行替代,不再使用。 + +## 3.6 编码器使用要点 + +### 3.6.1 输入图像的宽高与stride + +编码器的输入图像宽高配置需要与图像数据在内存中的排布一致。以1920x1080大小的YUV420图像编码为例,参考`图表 7 `MppFrame重要参数说明的内容,假设有两种情况如下: + +![](media/Figure18_Encoder_input_frame_memory_arrangement_1.png) + +![](media/Figure18_Encoder_input_frame_memory_arrangement_2.png) +
图表 18 编码器输入帧内存排布
+ +上图图情况:亮度分量的宽度为1920,高度为1080,亮度数据与色度数据不直接相接,中间有8行的空行。 + +这种情况下,水平stride为1920,垂直stride为1088,应用需要以1920\*1088\*3/2的大小分配空间并写入数据,使用宽1920,高1080,水平stride 1920,垂直stride 1088的配置即可以正常进行编码。 + +下图情况:亮度分量的宽度为1920,高度为1080,亮度数据与色度数据直接相接,中间没有空行。 + +这种情况下,水平stride为1920,垂直stride为1080,但由于编码器对数据的访问是16对齐的,在读取亮度下边缘数据时会读取到色度部分,读取色度下边缘数据时会读取到色度数据之外的部分,需要用户开出额外的空间,这里的空间为1920\*1080\*3/2+1920\*4的填充,才能保证编码器不出现访问未分配空间的情况。 + +### 3.6.2 编码器控制信息输入方式以及扩展 + +编码器控制信息的输入方式分为两种: + +一种是全局性控制信息,如码率配置,宽高配置等,作用于整个编码器和编码过程;另一种是临时性控制信息,如每帧的OSD配置信息,用户数据信息等,只作用于单帧编码过程。 + +第一类控制信息主要通过control接口来进行配置,第二类控制信息主要是通过MppFrame所带的MppMeta接口来进行配置。 + +今后对控制信息的扩展也会遵循这两种规则来进行扩展。 + +### 3.6.3 编码器输入输出流程 + +目前编码器默认输入接口仅支持阻塞式调用,输出接口支持非阻塞式和阻塞式调用,默认为非阻塞式调用,有可能出现获取数据失败的情况,需要在使用中注意。 + +### 3.6.4 插件式自定义码率控制策略机制 + +MPP支持用户自己定义码率控制策略,码率控制策略接口RcImplApi定义了几个编码处理流程上的钩子函数,用于在指定环节插入用户自定义的处理方法。具体使用方法可以参考默认的H.264/H.265码控策略实现(default_h264e/default_h265e结构)。 + +码控插件机制在MPP中有预留,接口与流程都不算稳定,可以预见将来还会有不少调整,只建议有能力阅读理解代码,以及持续维护更新的用户使用这个机制,一般用户不建议使用。 + +# 第四章 MPP demo说明 + +MPP的demo程序变化比较快,以下说明仅供参考,具体情况以实际运行结果为准。Demo的运行环境均以Android 32bit平台为准。 + +## 4.1 解码器demo + +解码器demo为mpi_dec_test系列程序,包括使用decode_put_packet和decode_get_frame接口的单线程mpi_dec_test、多线程的mpi_dec_mt_test以及多实例的mpi_dec_multi_test。 + +以Android平台上的mpi_dec_test为例进行使用说明。直接运行测试用例mpi_dec_test,可以在日志中打印帮助文档,如下图所示: + +![](media/Rockchip_Developer_Guide_MPP/MPP_print_decode_help.png) + +帮助文档可以分为两部分:一是mpi_dec_test的命令参数说明;二是码流文件的协议类型说明。 + +命令参数的描述说明如下: + +| 命令参数 | 描述说明 | +|----------|-------------------------------------------------| +| -i | 输入的码流文件。 | +| -o | 输出的图像文件。 | +| -w | 图像宽度,单位为像素。 | +| -h | 图像高度,单位为像素。 | +| -t | 码流文件的协议类型。 | +| -f | 图像色彩空间格式以及内存排布方式,默认为NV12。 | +| -n | 最大解码帧数。测试时若码流较长,可仅输出前n帧。 | +| -s | MPP实例数,默认为1。 | +| -v | 日志选项:q为静默标志;f为fps显示标志。 | +| -slt | 输出帧对应的校验文件。 | +| -help | 打开帮助文档。 | + +mpi_dec_test的命令参数中,输入文件(i)和码流类型(t)为强制要求配置的参数,其他参数如输出文件(o)、图像宽度(w)、图像高度(h)和解码帧数(n)等为可选参数,可以根据不同的测试需求进行配置。 + +mpi_dec_test的命令参数中,输出帧对应的校验文件(slt)将输出帧数据转换为对应的循环冗余校验码(具体逻辑见utils/utils.c)。校验文件的大小往往只有几kB,在芯片的slt测试中,将输出帧文件的对比转换成校验文件的对比,可以显著缩短测试周期。 + +MPP库支持的输入文件的编码格式(t)为MPEG2/4、H.263/4/5、VP8/9和JPEG等,id后的数字为不同编码格式对应的参数值。参数值来源于OMX的定义,值得注意的是,HEVC和AVS格式的参数值与其他格式的有显著区别。 + +以目录/data/下的ocrean.h264解码30帧为例,对demo和输出进行说明。运行的命令为: + +```bash + mpi_dec_test -t 7 -i /data/ocrean.h264 -n 30 +``` + +其中,-t 7表示输入码流文件的协议类型是H.264,-i表示输入文件,-n 30表示解码30帧。测试用例正常运行结果如下: + +![](media/Rockchip_Developer_Guide_MPP/MPP_decode_log.png) + +其中,打印的信息里包含了部分命令参数和部分解码日志。 + +MPP库的版本信息: + +``` +I mpp_info: mpp version: 6cc173d1 author: Ding Wei 2022-08-29 [hal_avsd]: Fix crash on avsd ref err path +``` + +`I mpi_dec_test: 0xeebc01c0 decode_get_frame get info changed found` + +为mpi_dec_test本身的打印,表示发现解码器上报了info change事件。 + +`I mpi_dec_test: 0xeebc01c0 decoder require buffer w:h [1920:1080] stride [1920:1088] buf_size 4177920` + +为mpi_dec_test本身的打印,表示解码器请求的图像内存情况。 + +`I mpi_dec_test: 0xf1c40730 decode get frame 0` + +为mpi_dec_test本身的打印,表示解码器在正常解码和输出图像。 + +`I mpi_dec_test: decode 10 frames time 263ms delay 69ms fps 113.99` + +为mpi_dec_test本身的打印,表示解码器解码30帧所用的时间为263ms,解码第一包数据的延迟时间为69ms,帧率为113.99。 + +`I mpi_dec_test: test success max memory 19.92 MB` + +为mpi_dec_test本身的打印,表示解码器完成了解码30帧的功能,最大的内存开销为19.92 MB。 + +解码器的demo具体代码参见test/mpi_dec_test.c。 + +## 4.2 编码器demo + +编码器demo为mpi_enc_test系列程序,包括单线程的mpi_enc_test及多实例的mpi_enc_multi_test。 + +以下以Android平台上的mpi_enc_test为例进行使用说明。直接运行测试用例mpi_enc_test,可以在日志中打印帮助文档,如下图所示: + +![](media/Rockchip_Developer_Guide_MPP/MPP_print_encode_help.png) + +帮助文档可以分为三部分:一是mpi_enc_test的命令参数说明;二是码流文件的协议类型说明;三是图像色彩空间格式以及内存排布方式说明。 + +命令参数的描述说明如下: + +| 命令参数 | 描述说明 | +|------------------------------|-------------------------------------------------------------------------------------------------| +| -i | 输入的图像文件。 | +| -o | 输出的码流文件。 | +| -w | 图像宽度,单位为像素。 | +| -h | 图像高度,单位为像素。 | +| -hstride | 垂直方向相邻两行之间的距离,单位为byte。 | +| -vstride | 图像分量之间的以行数间隔数,单位为1。 | +| -f | 图像色彩空间格式以及内存排布方式,默认为NV12。 | +| -t | 码流文件的协议类型。 | +| -tsrc | 源码流格式,仅在测试整体编解码性能时使用。 | +| -n | 最大解码帧数。测试时若码流较长,可仅输出前n帧。 | +| -g | gop参考模式,对应不同的TSVC码流。 | +| -rc | 码率控制模式。0:VBR; 1:CBR; 2:FIXQP; 3:AVBR。 | +| -bps | 码率约束参数。命令格式:bps_target:bps_min:bps_max。 | +| -fps | 输入/输出帧率控制,默认为30。该命令参数仅说明输入帧率和输出帧率之间的比例关系,与实际帧率无关。 | +| -qc | 质量控制。 | +| -s | MPP实例数,默认为1。 | +| -v | 日志选项:q为静默标志;f为fps显示标志。 | +| -ini | 额外的编码配置文件ini(暂未生效)。 | +| -slt | 输出码流对应的校验文件。 | + +mpi_enc_test的命令参数中,图像宽度(w)、图像高度(h)和码流类型(t)为强制要求配置的参数,其他参数如输入文件(i)、输出文件(o)、编码帧数(n)和色彩空间格式及内存排布方式(f)等为可选参数。如果没有指定输入文件,mpi_enc_test会生成默认的彩条图像进行编码。 + +mpi_enc_test的命令参数提供了多样化的码率控制方案,用户可以通过码率控制模式(rc)和码率约束参数(bps)对输出码流的码率进行控制。码率控制模式(rc)分为可变码率模式(VBR)、固定码率模式(CBR)、qp修正的码率模式(FIXQP)和自适应码率模式(AVBR),默认模式为VBR;码率约束参数(bps)则是为MPP内部配置码率边界提供参考。 + +mpi_enc_test的命令参数中,输入/输出帧率控制(fps)的格式为: + +```bash +-fps fps_in_num:fps_in_den:fps_in_flex/fps_out_num:fps_out_den:fps_out_flex +``` + +其中,in/out分别表示输入/输出;num表示分子;den表示分母;flex为0表示帧率固定,为1表示帧率可变。输入和输出默认的num和den分别为30和1,即默认的输入/输出帧率为30。该命令参数仅说明输入帧率和输出帧率之间的比例关系,与实际帧率无关。 + +mpi_enc_test的命令参数中,质量控制(qc)仅在输出码流格式为H.264、H.265、VP8和JPEG时生效,命令格式为: + +```bash +-qc qp_init/min/max/min_i/max_i +``` + +其中,qp表示质量参数;init表示初值;min表示最小值;max表示最大值;后缀i表示I帧最值,未标注则表示B、P帧最值。 + +mpi_enc_test的命令参数中,日志选项(v)为q时,MPP日常日志关闭;日志选项(v)为f时,每秒会打印一次平均帧率和当前帧率。 + +图像的色彩空间格式分为YUV和RGB两类。MPP支持多种内存排布方式(f),id后的数字为不同内存排布方式对应的参数值,值得注意的是,YUV和RGB格式的参数值有显著区别。 + +以目录/data/下的ocrean.yuv编码30帧为例,对demo和输出进行说明。运行的命令为: + +```bash +mpi_enc_test -w 1920 -h 1080 -t 7 -i /data/ocrean.yuv -o /data/out.h264 -n 30 +``` + +测试用例正常运行结果如下: + +![](media/Rockchip_Developer_Guide_MPP/MPP_encode_log.png) + +在解码器demo中已经介绍的日志略。 + +`I mpp_enc : MPP_ENC_SET_RC_CFG bps 7776000 [486000 : 8262000] fps [30:30] gop 60` + +默认的编码器的码率控制参数,目标码率为7.8Mbps,码率参考下界为0.5Mbps,码率参考上界为8.3Mbps;默认的输入和输出帧率为30;默认gop数为60。 + +`I mpi_enc_test: chn 0 encoded frame 0 size 218616 qp 11` + +为mpi_enc_test本身的打印,表示编码器在正常编码,输出单帧码流大小为0.2M,质量参数为11。 + +`I mpi_enc_test: chn 0 encode 30 frames time 628 ms delay 4 ms fps 47.72 bps 10265048` + +为mpi_enc_test本身的打印,表示编码器编码30帧所用的时间为628 ms,编码第一帧数据的延迟时间为4ms,帧率为47.72,码率为10.2Mbps。 + +`I mpi_enc_test: mpi_enc_test average frame rate 47.72` + +为mpi_enc_test本身的打印,表示编码器编码平均帧率为47.72。 + +编码器的控制参数还可以通过环境变量配置。在android环境下,环境变量配置命令为: + +```bash +setprop <控制参数> value +``` + +在linux环境下,环境变量配置命令为: + +```bash +export <控制参数>=value +``` + +相应的描述说明如下: + +| 控制参数 | 类型 | 描述说明 | +|------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| constraint_set | RK_U32 | 仅对H.264格式的码流生效,对应语法中的constraint_set0_flag至constraint_set5_flag。其中,强制标志force_flag和强制约束参数constraint_force存储格式为:\| 00 \| force_flag \| 00 \| constraint_force \|。 只有低6位生效,对应constraint_set5_flag至constraint_set0_flag,当force_flag为1时,对应的constraint_set将被配置入编码器。 | +| split_mode | RK_U32 | 编码器分片模式。0:不分片; 1:按字节分片; 2:按CTU分片。 | +| split_arg | RK_U32 | 分片大小参数,编码器分片模式开启后生效。按字节分片时,该参数为各片字节上限;按CTU分片时,该参数为各片CTU数上限。 | +| split_out | RK_U32 | 分片输出模式,编码器分片模式开启后生效。1:低延时输出模式; 2:段信息输出模式。低延时输出模式下,编码器输出包内每个片的延时较低;段信息输出模式下,编码器会为每个片封装段信息。 | +| sei_mode | RK_U32 | SEI写入模式。0:不写入SEI; 1:序列写入模式; 2:帧写入模式。序列写入模式下,每个gop只有一个SEI;帧写入模式下,若SEI信息发生改变,则还会在每帧数据前添加SEI。 | +| gop_mode | RK_U32 | gop参考模式。若环境变量gop_mode未配置,则按命令参数配置;否则,按环境变量配置。 | +| osd_enable | RK_U32 | 使能OSD调色板。 | +| osd_mode | RK_U32 | OSD调色板模式,使能OSD调色板后生效。0:默认配置; 1:用户定义配置。 | +| roi_enable | RK_U32 | 使能ROI测试,并根据平台配置默认的roi_type。 | +| roi_type | RK_U32 | 强制配置roi_type。 | +| user_data_enable | RK_U32 | 使能用户数据。 | + +编码器的demo具体代码参见test/mpi_enc_test.c。 + +## 4.3 实用工具 + +MPP提供了一些单元测试用的工具程序,这种程序可以对软硬件平台以及MPP库本身进行测试 + +- mpp_info_test + +用于读取和打印MPP库的版本信息,在反馈问题时,可以把打印出来信息附上。 + +- mpp_buffer_test + +用于测试内核的内存分配器是否正常。 + +- mpp_mem_test + +用于测试C库的内存分配器是否正常。 + +- mpp_runtime_test + +用于测试一些软硬件运行时环境是否正常。 + +- mpp_platform_test + +用于读取和测试芯片平台信息是否正常。 + +# 第五章 MPP库编译与使用 + +## 5.1 下载源代码 + +MPP源代码发布官方地址: + +发布分支为release分支,开发分支为develop分支,默认为开发分支。 + +下载命令:git clone https://github.com/rockchip-linux/mpp.git + +## 5.2 编译 + +MPP源代码编译脚本为cmake,需要依赖2.8.12以上的版本,建议使用2.8.12版,使用高版本的cmake工具可能会产生较多的warning。 + +### 5.2.1 Android平台交叉编译 + +编译Android库需要使用ndk环境,默认脚本使用android-ndk-r10d进行编译。 + +r10d ndk的下载路径可以在源代码目录下的build/android/ndk_links.md文件里查找。 + +把下载好的ndk解压到/home/pub/ndk/android-ndk-r10d,或者手动修改build/android/目录下env_setup.sh脚本的ANDROID_NDK变量路径。 + +进入build/android/arm/目录,运行make-Android.bash脚本生成编译用Makefile,运行make –j16进行编译。 + +### 5.2.2 Unix/Linux平台编译 + +先配置build/linux/arm/目录下arm.linux.cross.cmake文件里的工具链,再运行make-Makefiles.bash脚本通过cmake生成Makefile,最后运行make –j16进行编译。 + +MPP也支持直接在开发板运行的Debian上编译。 + +# 第六章 常见问题FAQ + +Q:aarch64编译出错,报错为undefined reference to \`__system_property_get'。 + +A:这是google 64bit ndk的问题,其libc.so中缺少一些符号定义,问题情况参见: + + + +解决方法:MPP中已经把对应的libc.so放到build/android/aarch64/fix/目录下,把库拷贝到path_to_ndk/platforms/android-21/arch-arm64/usr/lib/路径下,重新编译即正常。 + +Q:运行时会打印如下这样的内核log,是不是有问题? + +vpu_service_ioctl:1844: error: unknow vpu service ioctl cmd 40086c01 + +A:没有问题,mpp对内核驱动有一些依赖,内核驱动有不同版本的接口,mpp会进行多次尝试。如果遇到尝试失败会进行另外一种接口的尝试。这个打印是尝试失败时打印出来的,只会打印一次,可以忽略这个打印。 + +Q:MPP运行异常如何分析? + +A:首先先分析错误日志,如果出现打开内核设备失败的log,需要先分析内核平台的视频编解码器硬件设备配置文件是否有使能,然后提交问题到redmine上,分析运行环境问题之后,再来分析MPP运行的内部问题。 diff --git a/doc/Rockchip_Developer_Guide_MPP_EN.md b/doc/Rockchip_Developer_Guide_MPP_EN.md new file mode 100644 index 00000000..f61c2790 --- /dev/null +++ b/doc/Rockchip_Developer_Guide_MPP_EN.md @@ -0,0 +1,1074 @@ +# MPP Development Reference + +| Project: | MPP | +| --------- | ----------- | +| Version: | 0.7 | +| Author: | Herman Chen | +| Date: | 10/17/2023 | + +| **Revision** | **Date** | **Description** | **Author** | +| ------------ | ---------- | ------------------------------------------------------------ | --------------------------------------- | +| 0.1 | 04/18/2018 | Initial version | Herman Chen | +| 0.2 | 05/07/2018 | Add decoder control command description, encoder part description and demo part description | Herman Chen | +| 0.3 | 05/22/2018 | Fix some clerical errors and explanation errors, rearrange page numbers | Herman Chen
Xiongbin Xie(精英智通) | +| | 07/08/2019 | Translation | Lily Chen | +| 0.4 | 11/28/2018 | 1、Updated the memory layout instructions of the encoder input image.
2、Correct the encoder flowchart error | Herman Chen
Vyagoo | +| 0.5 | 06/08/2020 | Update encoder new configuration interface, no longer supports RK3188 | Herman Chen | +| 0.6 | 06/11/2020 | Translation | Lily Chen | +| 0.7 | 10/17/2023 | add markdown document | Xueman Ruan
Yandong Lin | +| | | | | +| | | | | + + +# 1.1 Overview + +Media Process Platform (MPP) provided by Rockchip is a general media processing software platform for Rockchip chip series. For applications the MPP platform shields the complex lower-level processing related to chips. Its purpose is to shield the differences between different chips and provide a unified media process interface (MPI) to users. The functions provided by MPP include: + +- video decoding + - H.265 / H.264 / H.263 / AV1 / VP9 / VP8 / AVS2 / AVS / AVS+ / MPEG-4 / MPEG-2 / MPEG-1 / VC1 / MJPEG +- video encoding + - H.265 / H.264 / VP8 / MJPEG +- video processing + - Video copy, zoom, color space conversion, Field video de-interleaving (Deinterlace) + + This document describes the MPP framework and its components, as well as the MPI interface for users. This document is intended for upper-level application developers and technical support staff. + +# 1.2 System framework + +The hierarchical diagram of MPP platform in system architecture is shown below: + +![](media/Figure01_MPP_system_framework.png) +
Figure 1 MPP system framework
+ +- Hardware layer + + Hardware layer is the hardware accelerator module of video encoding and decoding based on Rockchip platform, including vdpu, vepu, rkvdec, rkvenc and other different type hardware accelerators with different functions. + +- Kernel driver layer + +Linux kernel codec hardware driver contains device driver and related MMU, memory, clock, power management module. The supported platforms are mainly Linux kernel version 3.10, 4.4, 4.19 and 5.10. MPP libraries depend on kernel drivers. + +- MPP layer + +Userspace MPP layer shields the differences between different operating systems and different chip platforms, and provides a unified MPI interface for upper users. MPP layer includes MPI module, OSAL module, HAL module, Video Decoder / Video Encoder and Video Processing module. + +- Operating system layer + + MPP userspace operating platforms, Linux distributions such as Android and Debian + +- Application layer + +MPP layer can adapt to various middleware by MPI, such as OpenMax, ffmpeg and gstreamer, or directly be called by the upper application of customers. + +# 1.3 Supported platform + +## 1.3.1 Software platform + +MPP supports running on different versions of Android platforms and pure Linux platforms. + +It supports Rockchip 3.10, 4.4, 4.19 and 5.10 Linux kernels with vcodec_service device driver and corresponding DTS configuration as requirement. + +## 1.3.2 Hardware platform + +Support different series of Rockchip mainstream chip platforms: + +RK3288 series,RK3368 series,RK3399 series,RK3588 series + +RK30xx series,RK312x series,RK322x series ,RK332x series + +RV1109 / RV1126 series(Note: RV1107/RV1108 will gradually not support anymore) + +# 1.4 Supported function + +There are a lot of great differences when MPP encoding and decoding function is running on the different chip platforms. Please refer to the Multimedia Benchmark of the corresponding chip. + +# 1.5 Attentions + +If you want to quickly understand MPP usage and demo please go to Chapter 4 MPP demo instruction. + +If you want to compile and use MPP code quickly, please go to Chapter 5 compilation and use MPP library For detail MPP design and design principle, please refer to readme.txt in the MPP code root directory, txt documents in doc directory and annotations of header files. + +# Chapter 2 Interface design instruction + +This chapter describes the data structure that directly exposed to users in the process of using MPP and the usage instruction of the data structures. + +Because video encoding, decoding and video processing process need to deal with a large number of data interaction, including bitstream data, image data and memory data and also deal with the cross-relationship between upper application and kernel driver MPP designed MPI interface for interaction with the upper layer. This chapter explains the data structure used in MPI interface and design principle. + +## 2.1 Interface structure overview + +The following figure shows the main data structures used by the MPI interface: + +![](media/Figure02_Data_structure_used_in_MPI_interface.png) +
Figure 2 Data structure used in MPI interface
+ +MppMem is the encapsulation of malloc memory in library C. + +MppBuffer is the encapsulation of dmabuf memory for hardware. + +MppPacket is a one-dimensional buffer encapsulation, which can be generated from MppMem and MapBuffer. It is mainly used to represent bitstream data. + +MppFrame is a two-dimensional frame data encapsulation, which can be generated from MppMem and MapBuffer. It is mainly used to represent image data. + +Using MppPacket and MapFrame the general video encoding and decoding can be accomplished simply and effectively. + +Taking video decoding for example, bitstream at input side assigns the address and size to MppPacket. Input through the put_packet interface, and then get the input image MppFrame through the get_frame interface at the output side. It completes the simplest video decoding process. + +![](media/Figure03_Use_simple_interface_to_realize_video_decoding_EN.png) +
Figure 3 Use simple interface to realize video decoding
+ +MppMeta and MPTask are advanced combination interfaces for input and output tasks which can support complex usage modes such as specified input and output modes. It is occasionally used. + +Note: The above interface data structures are all referenced using void\*handle in order to facilitate extension and forward compatibility. The members mentioned in this paragraph are accessed through interfaces such as mpp_xxx_set/get_xxx. + +## 2.2 Memory structure(MppBuffer) + +MppBuffer is mainly used to describe memory blocks for hardware. It provides functions such as memory block allocate and release, reference counter increase and decrease. So far ion/drm allocators are supported. Several important parameters are listed as follows: + +| Parameter name | Parameter type | Description | +|----------------|----------------|----------------------------------------------------| +| ptr | void \* | Represents virtual address of memory block. | +| size | size_t | Represents size of memory block. | +| fd | int | Represents userspace file handler of memory block. | + +In decoding process the decoded picture buffer usually needs to be recycled in a fixed buffer pool. To achieve this behavior MPP defines MppBufferGroup based on MppBuffer. There are two ways to use them as follows: + +![](media/Figure04_Normal_usage_of_MppBuffer_EN.png) +
Figure 4 Normal usage of MppBuffer
+ +The procedure pseudo code is shown as follows: + +![](media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage_EN.png) + +This method can implement decoder zero-copy output in decoding process (the output frame of decoder is the same as the reference frame used in decoder). But it is not easy to implement zero-copy display (the output frame of decoder may not be displayed directly on the display side). At the same time users are required to know the memory space requirement of the decoder. + +Another way to use MppBufferGroup is to use it as a buffer manager only to manage external imported buffers. Its usage is shown as follows: + +![](media/Figure05_Usage_of_MppBuffer_External_Import_EN.png) +
Figure 5 Usage of MppBuffer External Import
+ +The procedure pseudo code is shown as follows: + +![](media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage_EN.png) + +This procedure can enable decoder to use external buffer, adapt to middleware such as OpenMax/ffmpeg/ gstreamer, easy to adapt to user upper application. It’s also easy to implement zero-copy display. + +## 2.3 Bitstream structure(MppPacket) + +MppPacket is mainly used to describe the related information of one-dimensional bitstream data, especially the location and length of valid data. Several important parameters of MppPacket are listed below: + +| Parameter name | Parameter type | Description | +|----------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| data | void \* | Represents start address of the buffer space. | +| size | size_t | Represents size of the buffer space. | +| pos | void \* | Represents start address of valid data in the buffer space. | +| length | size_t | Represents length of valid data in the buffer space. If the length changes to 0 after the decode_put_packet call the packet stream is consumed. | + +Their relationship is shown below: + +![](media/Figure06_Important_parameter_description_of_MppPacket_EN.png) +
Figure 6 Important parameter description of MppPacket
+ +The other configuration parameters of MppPacket are listed as follows: + +| Parameter name | Parameter type | Description | +|----------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| pts | RK_U64 | Represents display time stamp(Present Time Stamp) | +| dts | RK_U64 | Represents decoding time stamp(Decoding Time Stamp) | +| eos | RK_U32 | Represents end of stream flag(End Of Stream) | +| buffer | MppBuffer | Represents MppBuffer associated with MppPacket | +| flag | RK_U32 | Represents the flag bits used within MPP, including the following flag:
\#define MPP_PACKET_FLAG_EOS (0x00000001)
\#define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002)
\#define MPP_PACKET_FLAG_INTERNAL (0x00000004)
\#define MPP_PACKET_FLAG_INTRA (0x00000008) | + +MppPacket, as a structure describing one-dimensional memory, needs to be initialized using allocated memory or MppBuffer memory. There are several situations when releasing MppPacket: + +If the external malloc address is configured to MppPacket,the memory will not be released. As shown in the following example. + +![](media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket_EN.png) + +If the MppPacket is generated by copy_init, the memory allocated during the copying process will be released after the copy is completed. As shown in the following example. + +![](media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init_EN.png) + +If MppPacket is generated from MppBuffer, MppBuffer is referenced at the time of MppPacket creation and dereferenced at the time of MppPacket releasing. + +![](media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer_EN.png) + +## 2.4 Image structure(MppFrame) + +MppFrame is mainly used to define the related information of two-dimensional image buffer, the location and length of valid data. Several important parameters of the MppFrame are listed below: + +| Parameter name | Parameter type | Description | +|----------------|----------------|---------------------------------------------------------------------------------------------| +| width | RK_U32 | Represents the number of pixels in horizontal direction, in units of pixels. | +| height | RK_U32 | Represents the number of pixels in vertical direction, in units of pixels. | +| hor_stride | RK_U32 | Represents the distance between two adjacent rows in vertical direction, in units of bytes. | +| ver_stride | RK_U32 | Represents the number of row spacing between image components, in units of 1. | + +![](media/Figure07_Important_parameter_description_of_MppFrame_EN.png) +
Figure 7 Important parameter description of MppFrame
+ +The other configuration parameters of MppFrame are listed below: + +| Parameter name | Parameter type | Description | +|----------------|----------------|-----------------------------------------------| +| mode | RK_U32 | Represents image data frame field properties:
![](media/Rockchip_Developer_Guide_MPP/MPP_image_data_frame_field_properties.png) | +| pts | RK_U64 | Represents display time stamp of image(Present Time Stamp) | +| dts | RK_U64 | Represents Image decoding time stamp(Decoding Time Stamp) | +| eos | RK_U32 | Represents the end stream flag of image(End Of Stream) | +| errinfo | RK_U32 | Represents the image error flag, whether there is decoding error in the image. | +| discard | RK_U32 | Represents the discarding mark of the image. If the reference relation of image decoding does not satisfy the requirement the frame image will be marked as needing to be discarded and not to be displayed. | +| buf_size | size_t | Represents the size of the buffer that the image needs to allocate, which is related to the format of the image and the format of the decoded data. | +| info_change | RK_U32 | If true it represents that the current MppFrame is a descriptive structure for marking changes in bitstream information, indicating changes on width, height, stride or the image format.
Possible reasons for info_change are:
1. Change of image sequence width and height.
2. Image sequence format changes, for example 8 bit to 10 bit.
Once info_change is generated the memory pool used by the decoder needs to be reallocated. | +| fmt | MppFrameFormat | Represents image color space format and memory arrangement: ![](media/Rockchip_Developer_Guide_MPP/MPP_image_colorspace_format_and_memory_arrangement.png) | +| color_range | MppFrameColorRange | Represents the color space range of image data:
YUV full range:0 \~ 255(8bit)
YUV limit range:16 ~ 235(8bit )
![](media/Rockchip_Developer_Guide_MPP/MPP_color_space_range.png) | +| buffer | MppBuffer | Represents the MppBuffer corresponding to the MppFrame. | + +For the decoder the MppFrame is its output information structure. The decoded information (including pixel data, pts, error information and other related information) of the bitstream needs to be brought to the caller within MppFrame structure. The PTS / DTS and EOS flags in the MppFrame are inherited from the corresponding input MppPacket. + +Meanwhile once the resolution of input stream is changed the info_change flag in MppFrame will be set and info_change event will be notified to user who is required to modify the buffer pool. + +## 2.5 Advanced task structure (MppTask) + +When the interface between MppPacket and MppFrame cannot fulfill user’s requirements it is necessary to use MppTask as a data container to fulfill more complex input and output requirements. MppTask needs to be used in conjunction with poll/dequeuer/enqueue interface. Compared with simple process interfaces such as put_packet/get_frame, MppTask has complex process and low efficiency which is the cost of fulfilling complex requirements. + +![](media/Figure08_Use_MppTask_for_input_and_output_EN.png) +
Figure 8 Use MppTask for input and output
+ +MppTask is a structure which can be extended by keyword value (MppMetaKey) and support complex high-level requirements by extending the supported data types. Different keyword data in MppTask can be accessed using mpp_task_meta_set/get_xxx series interface. + +![](media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask_EN.png) +
Figure 9 Data Types and Keyword Types Supported by MppTask
+ +In practical usage we need to get MppTask from the input port of MPP by dequeue interface. Configure data to MppTask through mpp_task_meta_set_xxx series interface, and then enqueue to MPP instance for processing. The output port workflow of MPP is similar. But need to replace the serial interfaces of mpp_task_meta_set_xxx with the serial interfaces of mpp_task_meta_get_xxx to obtain data from MppTask. + +At present the practical encoder interface and MJPEG decoding interface are implemented with MppTask. + +## 2.6 Instance context structure(MppCtx) + +MppCtx is the MPP instance context handle provided to user as decoder or encoder. Users can create MppCtx instance and MppApi structure by mpp_create function, initialize type of encoding or decoding and format by mpp_init function, and then access context by decode_xxx/encode_xx or poll/dequeuer/enqueue function. Finally destroy it by mpp_destroy function at the end of use. + +![](media/Figure10_MppCtx_usage_process.png) +
Figure 10 MppCtx usage process
+ +## 2.7 API structure MppApi(MPI) + +The MppApi structure encapsulates the API of MPP. User implements the video codec function by using the function pointer provided in the MppApi structure. The structure is shown below: + +| Parameter name | Parameter type | Description | +|--------------------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| size | RK_U32 | MppApi structure size | +| version | RK_U32 | MppApi structure version | +| decode | Function pointer | MPP_RET (\*decode)(MppCtx ctx, MppPacket packet, MppFrame \*frame)
Video decoding interface, input and output at the same time, used alone.
ctx :MPP instance context.
packet :Input bitstream
frame :output image return value :0 is normal and non-zero is error code. | +| decode_put_packet | Function pointer | MPP_RET (\*decode_put_packet)(MppCtx ctx, MppPacket packet)
Video decoding input interface, used in conjunction with decode_get_frame.
ctx :MPP instance context.
packet :Input bitstream
return value :0 is normal, indicating that the stream has been processed by MPP; non-zero is an error, and the stream has not been processed, so the stream needs to be resented. | +| decode_get_frame | Function pointer | MPP_RET (\*decode_get_frame)(MppCtx ctx, MppFrame \*frame)
Video decoding output interface, used in conjunction with decode_put_packet.
ctx :MPP instance context.
frame :output image
return value :0 is normal, indicating that the acquisition of output process is normal, we need to determine whether there is a value of the frame pointer; non-zero is error code. | +| encode | Function pointer | MPP_RET (\*encode)(MppCtx ctx, MppFrame frame, MppPacket \*packet)
Video encoding interface, input and output at the same time, used separately.
ctx :MPP instance context.
frame :input image
packet :output bitstream
return value:0 is normal, non-zero is error code. | +| encode_put_frame | Function pointer | MPP_RET (\*encode_put_frame)(MppCtx ctx, MppFrame frame)
Video encoding input interface, used in conjunction with encode_get_packet.
ctx :MPP instance context.
frame :input image
return value :0 is normal and non-zero is error code. | +| encode_get_packet | Function pointer | MPP_RET (\*encode_get_packet)(MppCtx ctx, MppPacket \*packet) Video encoding output interface, used in conjunction with encode_put_frame.
ctx :MPP instance context.
packet :output bitstream
return value :0 is normal, non-zero is error code.| +| poll | Function pointer | MPP_RET (\*poll)(MppCtx ctx, MppPortType type, MppPollType timeout) Port query interface, used to query whether the port has data available for dequeue.
ctx :MPP instance context.
type :Port types are divided into input port and output port.
timeout :Query timeout parameter, -1 is blocking query, 0 is non-blocking query, and positive value is milliseconds of timeout.
return value :0 is normal, data can be retrieved, non-zero is error code. | +| dequeue | Function pointer | MPP_RET (\*dequeue)(MppCtx ctx, MppPortType type, MppTask \*task) The port dequeue interface is used to dequeue the MppTask structure from the port.
ctx :MPP instance context.
type :Port types are divided into input port and output port.
task :MppTask
return value :0 is normal, non-zero is error code. | +| enqueue | Function pointer | MPP_RET (\*enqueue)( MppCtx ctx, MppPortType type, MppTask task) The port enqueue interface is used to feed the port into the MppTask structure.
ctx :MPP instance context.
type :Port types are divided into input port and output port.
task :MppTask
return value:0 is normal, non-zero is error code. | +| reset | Function pointer | MPP_RET (\*reset)(MppCtx ctx) The reset interface is used to reset the internal state of MppCtx and set to available initialized state.
NOTE: the reset interface is a blocked synchronous interface.
ctx :MPP instance context.
return value :0 is normal, non-zero is error code. | +| control | Function pointer | MPP_RET (\*control)(MppCtx ctx, MpiCmd cmd, MppParam param) Control interface, an interface for additional control operations to MPP instances.
ctx :MPP instance context.
cmd :Mpi command id, representing different types of control commands.
task :The Mpi command parameter represents the additional parameter of the control command.
return value :0 is normal, non-zero is error code. | + +# Chapter 3 MPI interface instructions + +This chapter describes the specific process for user to use MPI interface and some considerations on use. MPI (Media Process Interface) is the interface provided by MPP for user. It provides hardware encoding and decoding functions, as well as some necessary related functions. MPI is provided to users through function pointer in C structure. Users can use MPP context structure MppCtx and MPI interface structure MppApi to implement decoder and encoder function. + +![](media/Figure11_MPI_interface_range.png) +
Figure 11 MPI interface range range
+ +As shown in the figure above mpp_create, mpp_init and mpp_destroy are the interfaces of operating MppCtx. The mpp_create interface also obtains the MPI interface structure MppApi. The real encoding and decoding process is achieved by calling the function pointer in the MppApi structure, that is, the part in the red box in the figure above. Function calls in red boxes are divided into codec process interface put/get_packet/frame and related control and reset interfaces. The description of the codec interface is shown below, and then some key points in the work of the codec are explained. + +# 3.1 Decoder data flow interface + +The decoder interface provides the user with the function of input stream and output image. The interface functions are decode_put_packet function, decode_get_frame function and decode function in MppApi structure. This set of functions provides the simplest decoding support. + +## 3.1.1 decode_put_packet + +| Interface definition | MPP_RET decode_put_packet(MppCtx ctx, MppPacket packet) | +|----------------------|-----------------------------------------------------------------| +| Input parameter | ctx :MPP Decoder instance packet :Bit stream data to be input | +| Return parameter | Runtime error code | +| Function | Input stream data **packet** to MPP decoder instance **ctx**. | + +##### The Form of Input Bit Stream: whole-frame and broken-frame + +The input of MPP is raw stream without encapsulated information. There are two forms of raw stream input: + +1. Whole frame data: + The input data has been segmented by frame, that is, each packet of MppPacket data input to decode_put_packet function already contains one and only one complete frame. In this case, MPP can directly process the stream by package, which is the default operation of MPP. + +2. Broken frame data: + The input data is segmented by length, and then it cannot judge whether a package of MppPacket data is only one complete frame or not. MPP needs frame segmenting operation internally. MPP can also support this broken frame data. But it needs to set the need_split flag through the MPP_DEC_SET_PARSER_SPLIT_MODE command of the control interface before mpp_init. + +![](media/Rockchip_Developer_Guide_MPP/MPP_Split_mode_config.png) + +In this way the MppPacket with broken frame data that input by decode_put_packet will be segmented frame by frame inside MPP and processed in the same way of whole frame data. + +If these two situations are mixed up there will be some bitstream decoding error generated. + +Whole frame data process is more efficient, but it needs to be parsed and frame segmented before input. Broken frame data process is simple to use, but its efficiency will be affected. + +In the mpi_dec_test test case the default mode is broken frame mode. In Rockchip Android SDK the whole frame mode is used. Users can choose according to their application scenarios and platform conditions. + +##### **Consumption of input bit stream** + +The valid data length of input MppPacket is “length”. After input decode_put_packet, if the input stream is consumed successfully, the function return value is zero (MPP_OK), and the length of MppPacket is cleared to zero. If the input stream has not been processed a non-zero error code is returned, and the length of MppPacket remains unchanged. + +##### **Working mode of function call** + +The decode_put_packet function is to input the raw bitstream to MPP instance, but in some cases the MPP instance cannot receive more data. At this time decode_put_packet works in non-blocking mode and it will return error code directly. User gets the returned error codes and waits for a certain time, and then resends the stream data to avoid extra overhead. + +##### **The number of maximum buffered packets** + +By default the MPP instance can receive four input stream packets in the processing queue. If input stream is sent too fast an error code will be reported and user will be required to wait a moment and resent the stream.. + +## 3.1.2 decode_get_frame + +| Interface definition | MPP_RET decode_get_frame(MppCtx ctx, MppFrame \*frame) | +|----------------------|----------------------------------------------------------------------------| +| Input parameter | ctx :MPP Decoder instance
frame :A pointer to obtain MppFrame instances. | +| Return parameter | Runtime error code | +| function | Get **frame** description information of decoded frame from MPP decoder instance **ctx**. | + +The image decoded by MPP is described by the structure of MppFrame. Also the structure of MppFrame is the channel for MPP decoder instance to output information. The error information of image and the info change are also output with MppFrame structure. + +##### **Error information of output image** + +The error information of the image is errinfo, which indicates whether there is an error in the process of decoding this image. If errInfo is not zero it means that an error occurred on decoding the corresponding bitstream. The image contains error can be discarded. + +##### **Space requirement on decoding image** + +When decoding image the decoder needs to obtain memory for the pixel data of output image. User is required to provide buffer with proper size to decoder. The space size requirement will be calculated in MPP decoder according to different chip platform and different video format. The calculated memory space requirement will be provided to user through the member variable buf_size of MppFrame. Users need to allocate memory according to the buf_size value to meet the requirement of decoder. + +##### **Change of output image information (Info change)** + +When the information such as the width, height, format, and pixel bit depth of the bitstream is changed decoder will report to user. User is required to update the memory pool used by decoder by update new memory buffer to the decoder. This involves decoding memory allocation and usage procedure, which are described in 3..2 Image Memory Allocation and Interactive Mode. + +## 3.1.3 decode + +The decode function is a combination of decode_put_packet and decode_get_frame data, providing user with a composite call of two functions. Its internal logic is: + +1. Try to acquire an output image; +2. If the output image is successfully acquired, function will return; +3. If the bitstream has been successfully sent, function will return; +4. Send the input bitstream; +5. Check the bitstream is sent successfully or not and loops back to step 1; + +In user view, the decode function firstly try to acquire a decoded image. If the decoded image is obtained, the decoded image is preferentially returned to the caller. If there is no decoded image can be output the bitstream is sent, and then try again to get the decoded image and exit. + +# 3.2 Decoder control interface + +## 3.2.1 control + +The MpiCmd enumeration type defined in rk_mpi_cmd.h defines the control interface command word. The decoder and decoding process commands are shown as follows: + +![](media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type.png) + +**MPP_DEC_SET_FRAME_INFO** + +The command parameter is MppFrame, which is used to configure the default width and height information of the decoder. The returned MppFrame structure will bring out the image buffer size to be allocated from the decoder. This command is called usually right after mpp_init and before decode_put_packet. + +**MPP_DEC_SET_EXT_BUF_GROUP** + +The command parameter is MppBufferGroup, which is used to configure the MppBufferGroup as buffer pool to decoder. This command is called at different position depending on image memory allocation mode. + +**MPP_DEC_SET_INFO_CHANGE_READY** + +There is no command parameter for this command. It is used to mark decoder’s MppBufferGroup has completed the reset processing of the Info change operation, and decoder can continue decoding. This command is called at different position depending on image memory allocation mode. + +**MPP_DEC_SET_PRESENT_TIME_ORDER** + +The command parameter is RK_U32*, which is used to process special bitstream timestamp case. + +**MPP_DEC_SET_PARSER_SPLIT_MODE** + +The command parameter is RK_U32*, which is used to enable the protocol parser in the MPP to process internal frame segmentation. The default bitstream input mode is whole frame mode and assume the input is frame segmented. This command is called before mpp_init. + +**MPP_DEC_SET_PARSER_FAST_MODE** + +The command parameter is RK_U32*, which is used to enable fast frame parsing in MPP and improve the parallelism of decoder hardware and software. However, the side-effect is some influence on error stream flag so it is disabled by default. This command is called before mpp_init. + +**MPP_DEC_GET_STREAM_COUT** + +The command parameter is RK_U32*. It is called by external applications to obtain the number of bitstream packets that have not been processed. It is a historical legacy interface. + +**MPP_DEC_GET_VPUMEM_USED_COUT** + +The command parameter is RK_U32*. It is called by external applications to obtain the number of MppBuffer used by MPP. It is a historical legacy interface. + +**~~MPP_DEC_SET_VC1_EXTRA_DATA~~** + +Not yet implemented. It is a historical legacy interface. + +**MPP_DEC_SET_OUTPUT_FORMAT** + +The command parameter is MppFrameFormat. It is called by external applications to configure the output image format of the JPEG decoder. It is not used by default. + +**MPP_DEC_SET_DISABLE_ERROR** + +The command parameter is RK_U32*. It is used to disable error handling of the MPP decoder. Once enabled, MPP decoding ignores the error flag of the stream, outputs all decodable images, and does not mark any errinfo in the output MppFrame structure. This command is called before decode_put_packet. + +**MPP_DEC_SET_IMMEDIATE_OUT** + +The command parameter is RK_U32*. It is used to enable the immediate output mode of H.264 decoder. Once enabled the H.264 decoder ignores the frame sequence discontinuity caused by frame dropping or picture order count, just outputs the current decoded image immediately. This command is called before decode_put_packet. + +## 3.2.2 reset + +The reset interface is used to restore the decoder to the state after normal initialization. + +When the user sends the last packet of MppPacket code stream, and puts the EOS mark into the decoder, the decoder will enter the EOS state after processing the last packet of data, and will no longer receive and process the code stream. Only after resetting can it continue to receive the new code stream. + +# 3.3 Key points on decoder usage + +In the process of using decoder some important notices need to be paid attention to: + +## 3.3.1 Decoder single/multithread usage + +The MPI interface of MPP decoder is thread-safe and can be used in multi-thread environment. The single-thread mode is shown in mpi_dec_test demo, and the multi-threaded mode is shown in mpi_dec_mt_test demo. + +![](media/Figure12_Decoder_single_thread_usage_EN.png) + +![](media/Figure12_Decoder_multi_thread_usage_EN.png) + +
Figure 12 Decoder single/multithread usage
+ +## 3.3.2 Image memory allocation and user interaction mode + +When decoder decodes image it needs to obtain memory space to write pixel data. When decoding is completed, the memory space needs to be handed over to user, and released back to decoder after user completes his usage. And all the Memory space will be released when the decoder is closed. In this procedure mode zero-copy interaction can be achieved between the decoder and the user. The MPP decoder supports three memory allocation and user interaction mode: + +##### **Mode 1: Pure internal allocation mode** + +The image memory is allocated from the MPP decoder directly. The user obtains the decoder output image and releases it directly after use. + +![](media/Figure13_Schematic_diagram_of_pure_internal_allocation_mode.png) +
Figure 13 Schematic diagram of pure internal allocation mode
+ +In this way the user does not need to call the MPP_DEC_SET_EXT_BUF_GROUP command of the decoder control interface, and only needs to directly call the MPP_DEC_SET_INFO_CHANGE_READY command of + +the control interface when the decoder reports the info change. The decoder will automatically allocate memory internally and the user needs to release the acquired data of each frame direct I. + +![](media/Figure14_Code_flow_of_decoder_image_memory_pure_internal_allocation_mode.png) +
Figure 14 Code flow of decoder image memory pure internal allocation mode
+ +Advantage: + +Procedure is simple. A demo can be setup quickly to evaluate the decoder performance. Disadvantage: + +1. Memory is allocated internally from the decoder. If the memory has not been released when the decoder is destroyed, there may be a memory leak or crash. +2. Unable to control the memory usage of the decoder. The decoder can use the memory without restrictions. If the bitstream is input quickly and the user does not release the decoded image memory in time, the decoder will quickly consume all available memory. +3. To achieve zero-copy display is difficult, because the memory is allocated from the inner decoder, and the user's display system may be not compatible. + +##### **Mode 2:Semi-internal allocation mode** + +This mode is the default mode used by the mpi_dec_test demo. The user needs to create an MppBufferGroup according to the buf_size of the MppFrame returned by the get_frame, and configure it to the decoder through the MPP_DEC_SET_EXT_BUF_GROUP of the control interface. Users can limit the memory usage of the decoder through the mpp_buffer_group_limit_config interface. + +![](media/Figure15_Semi-internal_allocation_mode_decoder_work_flow.png) + +
Figure 15 Semi-internal allocation mode decoder work flow
+ + + +Advantage: + +Procedure is simple, approachable, can do some limitation on the memory usage. Disadvantage: + +1. The limitation of memory space is not accurate. The usage of memory is not fixed at 100% and will fluctuate. +2. It is also difficult to achieve zero copy display + +##### **Mode 3:Pure external allocation mode** + +In this mode decoder imports the memory file handle of the external allocator (usually dmabuf/ion/drm) from the user by creating an empty external mode MppBufferGroup. On the Android platform, Mediaserver obtains the display memory from SurfaceFlinger through gralloc, commits the file handle obtained by gralloc to MppBufferGroup, configures MppBufferGroup to the decoder through the control interface MPP_DEC_SET_EXT_BUF_GROUP command, and then the MPP decoder will recycle the memory space obtained by gralloc + +![](media/Figure16_Schematic_diagram_of_pure_external_allocation_mode.png) +
Figure 16 Schematic diagram of pure external allocation mode
+ +![](media/Figure17_Pure_external_allocation_mode_decoder_work_flow.png) +
Figure 17 Pure external allocation mode decoder work flow
+ +Advantage: + +It is easy to achieve zero copy by directly using the memory from external display. Disadvantage: + +1. It is difficult to understand and use. +2. The user program needs to be modified. Some user program work flow restricts the pure external allocation mode usage. + +**Note on use of pure external distribution mode:** + +1. If the image memory pool is created before the decoder is created there should be an extra way to get the size of the image memory. + + General YUV420 image memory space calculation method: Image pixel datahor_stride \* ver_stride \* 3 / 2 Additional information: hor_stride \* ver_stride / 2 + +2. The number of memory blocks needs to consider the requirements of both decoding and display. If the number of memory blocks is enough the decoder may get stuck. + + H.264/H.265 protocols with more reference frames require 20+ memory blocks to guarantee decoding. Other protocols require 10+ memory blocks to ensure decoding. + +3. If an info change occurs during the bitstream decoding process, the existing MppBufferGroup needs to be reset. New image memory buffer should be committed, and the external display needs to be adjusted accordingly. + +# 3.4 Encoder data flow interface + +The encoder interface provides the user with the image input function and bitstream output functions . The interface function is the encode_put_frame function, the encode_get_packet function and the encode function in the MppApi structure. This set of functions provides simple coding support, while the control interface provides the ability to configure the encoder. + +## 3.4.1 encode_put_frame + +| Interface definition | MPP_RET encode_put_frame(MppCtx ctx, MppFrame frame) | +|----------------------|----------------------------------------------------------------------| +| Input parameter | ctx :MPP decoder instance
frame :Image data to be input | +| Return parameter | Running error code | +| Function | Input frame image data to the MPP encoder instance specified by ctx. | + +#### **Function working mode** + +Since the input image of the encoder is very large in normal case, if the image copy is performed, the efficiency will be greatly reduced. Therefore, the input function of the encoder needs to wait for the encoder hardware to complete the use of the input image memory then the input function can return. The used image is returned to the caller. Based on the above considerations the encode_put_frame is a blocking function that blocks the call until the input image usage is finished. To a certain extent, the software and hardware operations cannot be paralleled and the efficiency is reduced. + +#### **Copy and zero copy input** + +The input of the encoder does not support the space allocated by the CPU. If you need to support the address allocated by the CPU, you need to allocate MppBuffer and copy the data into it. This will greatly affect the efficiency. The encoder prefers input memory to be in form of dmabuf/ion/drm, which enables zero-copy encoding with minimal overhead. + +## 3.4.2 encode_get_packet + +| Interface definition | MPP_RET encode_get_packet(MppCtx ctx, MppPacket \*packet) | +|----------------------|--------------------------------------------------------------------------------------------------------------------------| +| Input parameter | ctx :MPP decoder instance
packet :A pointer to get an instance of MppPacket. | +| Return parameter | Runtime error mode | +| Function | The packet description information of the completed encoding is obtained from the MPP encoder instance specified by ctx. | + +##### **Header information and image data** + +Taking the H.264 encoder as an example, the output data of the encoder is divided into two parts: header information bitstream (sps/pps) and image data bitstream (I/P slice). The header information needs to be obtained by the MPP_ENC_GET_EXTRA_INFO command of the control interface, and the image data is obtained through the encode_get_packet interface. The timing of the header information acquisition is after the SET_RC_CFG/SET_PREP_CFG/SET_CODEC_CFG parameter configuration command of the control interface is completed. When the parameter configuration command is called, the encoder will update each parameter. After the update is completed, the latest header information can be obtained by calling MPP_ENC_GET_EXTRA_INFO + +##### **H.264 encoder output stream format** + +At present, the hardware fixed output stream with the start code of 00 00 00 01, so the encode_get_packet function gets the code stream with the start code of 00 00 00 01. If you need to remove the start code, you can copy it start with the address after the start code. + +##### **Zero copy of code stream data** + +Since there is no way to configure the output buffer when using the encode_put_frame and encode_get_packet interfaces, a copy will be made when using encode_get_packet. In general the output stream of the encoder is not large comparing to the input image, and the copy of the bitstream data is acceptable. If you need to use a zero-copy interface, you need to use the enqueue/dequeue interface and the MppTask structure. + +## 3.4.3 encode + +##### **Not yet implemented** + +# 3.5 Encoder control interface + +Encoders and decoders are different and require users to configure certain parameters. The encoder requires the user to configure the encoder configuration information through the control interface before encoding. + +## 3.5.1 Control and MppEncCfg + +MPP recommends using the encapsulated MppEncCfg structure to configure encoder information through the MPP_ENC_SET_CFG/MPP_ENC_GET_CFG command of the control interface. + +Due to the configurable options and parameters of the encoder, the use of fixed structures is prone to frequent changes in the interface structure, resulting in the inability to ensure binary compatibility of the interface, complicated version management, and greatly increased maintenance. + +To alleviate this problem, MppEncCfg uses (void \*) as the type, and uses \ for key map configuration. The function interface is divided into s32/u32/s64/u64/ptr/st, and the corresponding interface functions are divided into set and get two groups, as follows: + +```c +MPP_RET mpp_enc_cfg_set_s32(MppEncCfg cfg, const char *name, RK_S32 val); +MPP_RET mpp_enc_cfg_set_u32(MppEncCfg cfg, const char *name, RK_U32 val); +MPP_RET mpp_enc_cfg_set_s64(MppEncCfg cfg, const char *name, RK_S64 val); +MPP_RET mpp_enc_cfg_set_u64(MppEncCfg cfg, const char *name, RK_U64 val); +MPP_RET mpp_enc_cfg_set_ptr(MppEncCfg cfg, const char *name, void *val); +MPP_RET mpp_enc_cfg_set_st(MppEncCfg cfg, const char *name, void *val); + +MPP_RET mpp_enc_cfg_get_s32(MppEncCfg cfg, const char *name, RK_S32 *val); +MPP_RET mpp_enc_cfg_get_u32(MppEncCfg cfg, const char *name, RK_U32 *val); +MPP_RET mpp_enc_cfg_get_s64(MppEncCfg cfg, const char *name, RK_S64 *val); +MPP_RET mpp_enc_cfg_get_u64(MppEncCfg cfg, const char *name, RK_U64 *val); +MPP_RET mpp_enc_cfg_get_ptr(MppEncCfg cfg, const char *name, void **val); +MPP_RET mpp_enc_cfg_get_st(MppEncCfg cfg, const char *name, void *val); +``` + +The character string is generally defined by \[type:parameter\]. The supported character strings and parameter types are as follows: + +|Parameter string |Interface |Actual type |Description | +|---|---|---|---| +|rc:mode|S32|MppEncRcMode|Indicates the bit rate control mode, currently supports CBR and VBR:
CBR is Constant Bit Rate,fixed bit rate mode。In fixed bit rate mode, the target bit rate plays a decisive role.
VBR is Variable Bit Rate, variable bit rate mode.In variable bit rate mode, the maximum and minimum bit rates play a decisive role.
FIX_QP is a fixed QP mode, used for debugging and performance evaluation.
![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcMode.png)| +|rc:bps_target|S32|RK_S32|Indicates the target code rate in CBR mode.| +|rc:bps_max|S32|RK_S32|Indicates the highest bit rate in VBR mode.| +|rc:bps_min|S32|RK_S32|Indicates the lowest bit rate in VBR mode.| +|rc:fps_in_flex|S32|RK_S32|Flag bit indicating whether the input frame rate is variable. The default is 0.
0 means that the input frame rate is fixed, and the frame rate calculation method is fps_in_num/fps_in_denorm, which can indicate the fractional frame rate.
1 means that the input frame rate is variable. In the case of a variable frame rate, the frame rate is not fixed, and the corresponding code rate calculation and allocation rules become calculated according to actual time.| +|rc:fps_in_flex|S32|RK_S32|Flag bit indicating whether the input frame rate is variable. The default is 0.
0 means that the input frame rate is fixed, and the frame rate calculation method is fps_in_num/fps_in_denorm, which can indicate the fractional frame rate.
1 means that the input frame rate is variable. In the case of a variable frame rate, the frame rate is not fixed, and the corresponding code rate calculation and allocation rules become calculated according to actual time.| +|rc:fps_in_num|S32|RK_S32|Indicates the numerator part of the input frame rate score value, for example, 0 means the default 30fps.| +|rc:fps_in_denorm|S32|RK_S32|Indicates the denominator part of the input frame rate fraction value. If 0 is 1| +|rc:fps_out_flex|S32|RK_S32|Flag indicating whether the output frame rate is variable. The default is 0.
0 means that the output frame rate is fixed, and the frame rate calculation method is fps_out_num/fps_out_denorm, which can indicate the fractional frame rate.
1 means that the output frame rate is variable. In the case of variable frame rate, the frame rate is not fixed, and the corresponding code stream output time is calculated according to the actual time.| +|rc:fps_out_num|S32|RK_S32|Indicates the numerator part of the output frame rate score, such as 0 means the default 30fps.| +|rc:fps_out_denorm|S32|RK_S32|Indicates the denominator part of the output frame rate score value. If 0 is 1| +|rc:gop||RK_S32|Indicates Group Of Picture, that is, the interval between two I frames, the meaning is as follows.
0-indicates that there is only one I frame, other frames are P frames
1-means all I frames
2-means the sequence is I P I P I P...
3-means the sequence is I P P I P P I P P...
In general, gop is selected as an integer multiple of the input frame rate.| +|rc:max_reenc_times|U32|RK_U32|The maximum recoding times of a frame of image.| +|prep:width|S32|RK_S32|Indicates the number of pixels in the horizontal direction of the input image, in units of pixels.| +|prep:height|S32|RK_S32|Indicates the number of pixels in the vertical direction of the input image, in units of pixels.| +|prep:hor_stride|S32|RK_S32|Indicates the distance between two adjacent lines in the vertical direction of the input image, in bytes.| +|prep:ver_stride|S32|RK_S32|Indicates the number of lines between input image components, and the unit is 1.| +|prep:format|S32|MppFrameFormat|Represents the input image color space format and memory layout.
![](media/Rockchip_Developer_Guide_MPP/MPP_MppFrameFormat.png)| +|prep:color|S32|MppFrameColorSpace|Represents the color space range of input image data.| +|prep:range|S32|MppFrameColorRange|Indicates whether the input image is full range or limit range
![](media/Rockchip_Developer_Guide_MPP/MPP_MppFrameColorRange.png)| +|prep:rotation|S32|MppEncRotationCfg|Represents the input image rotation attribute, the default is 0, no rotation.
![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncRotationCfg.png)| +|prep:mirroring|S32|RK_S32|Indicates the mirroring attribute of the input image, the default is no mirroring . 
![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncMirrorCfg.png)| +|codec:type|S32|MppCodingType|Indicates the protocol type corresponding to MppEncCodecCfg, which needs to be consistent with the parameters of the MppCtx initialization function mpp_init.
![](media/Rockchip_Developer_Guide_MPP/MPP_MppCodingType.png)| +|h264:stream_type|S32|RK_S32|Indicates the type of input H.264 stream format, and the default is 0.
0-indicates Annex B format, that is, the start code of 00 00 00 01 is added.
1-indicates a format without a start code.
At present, the internal fixed format is Annex B format| +|h264:profile|S32|RK_S32|The profile_idc parameter in SPS:
66-indicates Baseline profile.
77-indicates Main profile.
100-indicates High profile.
![](media/Rockchip_Developer_Guide_MPP/MPP_H264Profile.png)| +|h264:level|S32|RK_S32|Indicates  the level_idc parameter in SPS, where 10 represents level 1.0:10/11/12/13 – qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
20/21/22 – cif@30fps / half-D1@25fps / D1@12.5fps
30/31/32 – D1@25fps / 720p@30fps / 720p@60fps
40/41/42 – 1080p@30fps / 1080p@30fps / 1080p@60fps
50/51/52 – 4K@30fps / 4K@30fps / 4K@60fps
The general configuration is level 4.1 to meet the requirements.| +|h264:cabac_en|S32|RK_S32|Represents the entropy encoding format used by the encoder:
0 – CAVLC,Adaptive variable length coding.
1 – CABAC, Adaptive arithmetic coding.| +|h264:cabac_idc|S32|RK_S32|The cabac_init_idc in the protocol syntax is valid when cabac_en is 1, and the valid value is 0~2.| +|h264:trans8x8|S32|RK_S32|Indicates the 8x8 conversion enable flag in the protocol syntax.| +|h264:const_intra|S32|RK_S32|0-to close, fixed close in Baseline/Main profile.| +|h264:scaling_list|S32|RK_S32|1-to enable, selectable to enable in High profile.| +|h264:cb_qp_offset|S32|RK_S32|It indicates the constrained_intra_pred_mode mode enable flag in the protocol syntax.| +|h264:cr_qp_offset|S32|RK_S32|0-is off, 1-is on.| +|h264:dblk_disable|S32|RK_S32|Represents the scaling_list_matrix mode in the protocol syntax| +|h264:dblk_alpha|S32|RK_S32|0-flat matrix, 1-default matrix.| +|h264:dblk_beta|S32|RK_S32|Indicates the deblock_offset_beta value in the protocol syntax.| +|h264:qp_init|S32|RK_S32|The valid range is [-6, 6].| +|h264:qp_max|S32|RK_S32|Indicates the initial QP value. Do not configure it under normal circumstances.| +|h264:qp_min|S32|RK_S32|Indicates the maximum QP value, do not configure it under normal circumstances.| +|h264:qp_max_i|S32|RK_S32|Indicates the minimum QP value, do not configure it under normal circumstances.| +|h264:qp_min_i|S32|RK_S32|Indicates the maximum I frame QP value. Do not configure it under normal circumstances.| +|h264:qp_step|S32|RK_S32|Indicates the minimum I frame QP value. Do not configure it under normal circumstances.| +|h265:profile|S32|RK_S32|Indicates the frame-level QP change amplitude between two adjacent frames.| +|h265:level|S32|RK_S32|The profile_idc parameter in the VPS:| +|h265:scaling_list|S32|RK_S32|Fixed at 1, Main profile| +|h265:cb_qp_offset|S32|RK_S32|Represents the level_idc parameter in VPS| +|h265:cr_qp_offset|S32|RK_S32|Represents the scaling_list_matrix mode in the protocol syntax| +|h265:dblk_disable|S32|RK_S32|0-flat matrix, 1-default matrix.| +|h265:dblk_alpha|S32|RK_S32|Indicates the chroma_cb_qp_offset value in the protocol syntax.| +|h265:dblk_beta|S32|RK_S32|The valid range is [-12, 12].| +|h265:qp_init|S32|RK_S32|Indicates the chroma_cr_qp_offset value in the protocol syntax.| +|h265:qp_max|S32|RK_S32|The valid range is [-12, 12].| +|h265:qp_min|S32|RK_S32|Indicates the deblock_disable flag in the protocol syntax, and the valid range is [0, 2].| +|h265:qp_max_i|S32|RK_S32|0 – deblocking is enabled.| +|h265:qp_min_i|S32|RK_S32|Indicates the minimum I frame QP value. Do not configure it under normal circumstances.| +|h265:qp_step|S32|RK_S32|Indicates the frame-level QP change amplitude between two adjacent frames.| +|h265:qp_delta_ip|S32|RK_S32|Indicates the QP difference between the I frame and the previous P frame.| +|jpeg: quant|S32|RK_S32|Indicates the quantization parameter level used by the JPEG encoder. The encoder has a total of 11 levels of quantization coefficient tables, from 0 to 10, and the image quality is from poor to good.| +|split:mode|U32|MppEncSplitMode|Represents the slice split mode of H.264/H.265 protocol
![](media/Rockchip_Developer_Guide_MPP/MPP_MppEncSplitMode.png)
0–  no split.
1– BY_BYTE divides the slice according to the slice size.
2– BY_CTU divides the slice according to the number of macroblocks or CTUs.| +|split:arg|U32|RK_U32|Slice cutting parameters:
In BY_BYTE mode, the parameter indicates the maximum size of each slice.
In BY_CTU mode, the parameter indicates the number of macroblocks or CTUs contained in each slice.| + +Other strings and parameters will be expanded later. + +## 3.5.2 Control other commands + +The MpiCmd enumeration type defined in the rk_mpi_cmd.h file defines the control interface command word, where the commands related to the encoder and encoding process are as follows: + +![](media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type_related_to_MPP.png) + +The commands from MPP_ENC_CMD_BASE to MPP_ENC_CMD_END are the control interface commands of the encoder. Among them, the MPP_ENC_SET/GET_CFG configuration command has been introduced as the basic configuration command in 3.5.1. The rest of the commands are briefly described below, where the commands are related to the encoder hardware and only some hardware support. + +At present, the encoder hardware supported by MPP is divided into vepu series and rkvenc series. The vepu series supports H.264 encoding, vp8 encoding and jpeg encoding, and is equipped in most RK chips. The rkvenc series only supports H.264 encoding, and is currently only available on the RV1109/RV1126 SoC, which supports more encoding functions than the vepu series. + +Brief description of some CMD commands: + +**~~MPP_ENC_SET_PREP_CFG/ MPP_ENC_GET_PREP_CFG~~** +**~~MPP_ENC_SET_RC_CFG/ MPP_ENC_GET_RC_CFG~~** +**~~MPP_ENC_SET_CODEC_CFG/ MPP_ENC_GET_CODEC_CFG~~** + +Deprecated commands, reserved for forward compatibility, do not use. + +**MPP_ENC_SET_IDR_FRAME** + +There is no command parameter. It is used to request IDR frame to the encoder. After the encoder receives the request, it encodes the next frame to be an IDR frame. All hardware supports. + + +**~~MPP_ENC_SET_OSD_LEGACY_0~~** +**~~MPP_ENC_SET_OSD_LEGACY_1~~** +**~~MPP_ENC_SET_OSD_LEGACY_2~~** + +Deprecated commands, reserved for forward compatibility, do not use. + +**MPP_ENC_GET_HDR_SYNC**/ ~~MPP_ENC_GET_EXTRA_INFO~~ + +The command used to obtain the stream header data separately. MPP_ENC_GET_EXTRA_INFO is an old command and is not recommended. + +The input parameter of MPP_ENC_GET_HDR_SYNC is MppPacket, which requires external users to allocate space and encapsulate it as MppPacket and then control to the encoder. When the control interface returns, the data copy is completed and the thread is safe. The calling timing is after the basic configuration of the encoder is completed. The user needs to manually release the previously allocated The input parameter of MppPacket.MPP_ENC_GET_EXTRA_INFO is MppPacket*, and the internal MppPacket of the encoder will be obtained for access. The calling timing is after the basic configuration of the encoder is completed. It should be noted that the MppPacket obtained here is the internal space of the MPP and does not need to be released by the user. + +In the case of multi-threading, the MppPacket obtained by the MPP_ENC_GET_EXTRA_INFO command may be modified by other controls during reading, so this command is not thread-safe and is only used for compatibility with the old vpu_api. Do not use it again. + + +**~~MPP_ENC_SET_SEI_CFG/MPP_ENC_GET_SEI_DATA~~** + +Deprecated commands, reserved for forward compatibility, do not use. + + +**~~MPP_ENC_PRE_ALLOC_BUFF/MPP_ENC_SET_QP_RANGE/MPP_ENC_SET_ROI_CFG/ MPP_ENC_SET_CTU_QP~~** + +Deprecated commands, reserved for forward compatibility, do not use. + + +**MPP_ENC_GET_RC_API_ALL** + +Get the API information of the rate control strategy currently supported by MPP, enter the RcApiQueryAll* pointer, and fill in the structure content when returning. + + +**MPP_ENC_GET_RC_API_BY_TYPE** + +Obtain the API information of all the rate control strategies of the specified MppCodingType type, enter the RcApiQueryType* pointer and specify MppCodingType, and the structure content will be filled in when returned. + + +**MPP_ENC_SET_RC_API_CFG** + +Register the external rate control strategy API, and enter the RcImplApi* pointer. The function pointer in this structure defines the behavior of the rate control strategy plug-in. The rate control strategy after registration can be queried and activated. + + +**MPP_ENC_GET_RC_API_CURRENT** + +Return the API information of the currently used rate control strategy, enter the RcApiBrief* pointer, and the content of the structure will be filled in when returning. + + +**MPP_ENC_SET_RC_API_CURRENT** + +Activate the rate control strategy API of the specified name, enter the RcApiBrief* pointer, the encoder will search the rate control strategy API of the specified string name in RcApiBrief and activate it as the current rate control strategy. + + +**~~MPP_ENC_SET_HEADER_MODE/MPP_ENC_GET_HEADER_MODE~~** + +Configure and obtain the SEI debugging information output method of the H.264/H.265 encoder. The debugging switch will be replaced by environment variables in the future. Do not use + + +**~~MPP_ENC_SET_SPLIT/ MPP_ENC_GET_SPLIT~~** + +Configure and obtain slice split configuration information of H.264/H265 encoder, which has been replaced by split:mode and split:arg in MppEncCfg, do not use + + +**MPP_ENC_SET_REF_CFG** + +Configure the advanced reference frame mode of the encoder. By default, no configuration is required. It is used when the long-term reference frame and short-term reference frame reference relationship modes need to be configured. It is used to configure a special reference relationship mode. It is advanced interface to be more documented. + + +**MPP_ENC_SET_OSD_PLT_CFG** + +The command parameter is MppEncOSDPlt, which is used to configure the OSD palette of the rkvenc series hardware. Used to configure the OSD palette of rkvenc series hardware, the command parameter is MppEncOSDPlt.It is usually configured only once at the beginning of the encoding, and the full encoding process uses a uniform palette. Only the RV1109/RV1126 series supports. + + +**MPP_ENC_GET_OSD_PLT_CFG** + +Used to obtain the OSD palette of rkvenc series hardware, the command parameter is MppEncOSDPlt*. Generally not used + + +**~~MPP_ENC_SET_OSD_DATA_CFG~~** + +The command parameter is MppEncOSDData, which is used to configure the OSD data of the rkvenc series hardware.Used to configure OSD data of rkvenc series hardware, the command parameter is MppEncOSDData.It needs to be configured every frame, and needs to be reconfigured after each frame is encoded.This command is replaced by KEY_OSD_DATA in MppMeta with MppFrame and is no longer used. + +# **3.6** **Key** points **on** **encoder** **usage** + +## **3.6.1** **Width** and height of input image and stride + +The width and height configuration of the input image of the encoder needs to be consistent with the arrangement of the image data in the memory. Taking the 1920x1080 size YUV420 image coding as an example, referring to the description of the important parameters of Figure 7 MppFrame, it is assumed that there are two cases as follows: + +![](media/Figure18_Encoder_input_frame_memory_arrangement_1_EN.png) + +![](media/Figure18_Encoder_input_frame_memory_arrangement_2_EN.png) + +
Figure 18 Encoder input frame memory arrangement
+ +Left case: the width of the luminance component is 1920, the height is 1080, the luminance data and the chrominance data are not directly connected, there are 8 blank lines in the middle. + +In this case, the horizontal stride is 1920 and the vertical stride is 1088. The application needs to allocate space and write data in the size of 1920\*1088\*3\/2. Use the configuration of width 1920, height 1080, horizontal stride 1920, and vertical stride 1088. That is, the encoding can be performed normally. + +Right case: The width of the luminance component is 1920 and the height is 1080. The luminance data and the chrominance data are directly connected, and there is no blank line in the middle. + +In this case, the horizontal stride is 1920 and the vertical stride is 1080, but because the encoder accesses the data to 16 alignment, the chroma part will be read when reading the lower edge data of the brightness, and the lower edge of the chroma will be read. The data will be read out of the chroma data, and the user needs to provide extra space. The space here is 1920\*1080\*3\/2+1920\*4 padding to ensure that the encoder does not access unallocated space. + +## 3.6.2 Encoder control information input method and expansion + +There are two ways to input encoder control information: + +One is global control information, such as code rate configuration, width and height configuration, etc., which affects the entire encoder and encoding process; the other is temporary control information, such as OSD configuration information per frame, user data information, etc., only Acts on the single frame encoding process. + +The first type of control information is mainly configured through the control interface, and the second type of control information is mainly configured through the MppMeta interface carried by the MppFrame. + +Future expansion of control information will follow these two rules. + +## 3.6.3 Encoder input and output process + +At present, the encoder's default input interface only supports blocking calls, and the output interface supports non-blocking and blocking calls. The default is non-blocking calls. There may be a failure to obtain data. You need to pay attention to it in use. + +## 3.6.4 Plug-in custom rate control strategy mechanism + +MPP supports users to define their own rate control strategy. The rate control strategy interface RcImplApi defines several hook functions on the encoding processing flow, which are used to insert user-defined processing methods in designated links. For specific usage, please refer to the default H.264/H.265 code control strategy implementation (default_h264e/default_h265e structure). + +The code control plug-in mechanism is reserved in the MPP, and the interface and process are not stable. It is foreseeable that there will be many adjustments in the future. It is only recommended to users who have the ability to read and understand the code and continue to maintain and update this mechanism. The general users do not Recommended for use. + +# Chapter 4 MPP demo description + +The demo program of MPP changes quickly. The following descriptions are for reference only. The actual operation results shall subject to practice. The operating environment of Demo is based on the Android 32bit platform. + +# 4.1 Decoder demo + +The decoder demo is the mpi_dec_test series programs including the single-threaded mpi_dec_test using the decode_put_packet and decode_get_frame interfaces, the multi-threaded mpi_dec_mt_test, and the multi-instance mpi_dec_multi_test. + +The following is an example of using mpi_dec_test on the Android platform as an example. First run mpi_dec_test directly, help document can be printed in the log, as shown below: + +![](media/Rockchip_Developer_Guide_MPP/MPP_print_decode_help.png) + +The help document can be divided into two parts: command parameter descriptions of mpi_dec_test and the description of supported coding type of the input bitstream file. + +The command parameter descriptions as follows. + +| command parameter | descriptions | +| ----------------- | ------------------------------------------------------------ | +| -i | input bitstream file | +| -o | output decoded frame file | +| -w | width of input bitstream, in pixels | +| -h | height of input bitstream, in pixels | +| -t | input bitstream coding type | +| -f | output frame format type, NV12 by default | +| -n | max output frame number. If input bitstream is too long, only the first n frames can be decoded. | +| -s | number of instances, 1 by default | +| -v | trace option: q - quiet; f - show fps | +| -slt | slt verify data file corresponding to output decoded frame | +| -help | show help | + +In the command parameters of mpi_dec_test, input file (i), coding type (t) is mandatory parameter. Other parameters such as output file (o), image width (w) image height (h), decoded frame number (n), etc. are optional parameters with less effect. + +In the command parameter of mpi_dec_test, slt verify data file converts the output frame data into the corresponding cyclic redundancy check code (see utils/utils.c). The size of the slt file is often only a few kB. In the slt test of the chip, the comparison of the output frame file is converted to the comparison of the slt file, which can significantly shorten the test cycle. + +The following print shows the encoding format supported by the MPP library. It supports MPEG2/4, H.263/4/5, and VP8/9 decoding. The number after the id is the parameter value after the -t item corresponding to the format. The parameter values are derived from the definition of OMX. The format parameter values of HEVC and AVS are quite different from other format parameter values, so you need to pay attention. + +Take 30 frames of ocrean.h264 under /data/ as an example to introduce the demo and output. The command is: + +```bash +mpi_dec_test -t 7 -i /data/ocrean.h264 -n 30 +``` + +where -t 7 indicates H.264 code stream, -i indicates input file, and -n 30 indicates decoding 30 frames. If everything is normal, the following result will be obtained: + +![](media/Rockchip_Developer_Guide_MPP/MPP_decode_log.png) + +The printed information contains the version information of the MPP library: + +``` +I mpp_info: mpp version: 6cc173d1 author: Ding Wei 2022-08-29 [hal_avsd]: Fix crash on avsd ref err path +``` + +``` +I mpi_dec_test: 0xeebc01c0 decode_get_frame get info changed found +``` + +The mpi_dec_test printing indicates that the MPP decoder has reported an info change event. + + ``` + I mpi_dec_test: 0xeebc01c0 decoder require buffer w:h [1920:1080] stride [1920:1088] buf_size 4177920 + ``` + +The mpi_dec_test printing indicates that the image memory condition requested by the MPP decoder. + + ``` + I mpi_dec_test: 0xf1c40730 decode get frame 0 + ``` + +The mpi_dec_test printing indicates that the decoder is decoding and outputting images normally. + +``` +I mpi_dec_test: decode 30 frames time 263ms delay 69ms fps 113.99 +``` + +The mpi_dec_test printing indicates that the decoder uses 263ms to decode 30 frames, first frame delays 69ms, fps is 113.99. + +``` +I mpi_dec_test: test success max memory 19.92 MB +``` + +The mpi_dec_test printing indicates that max memory of decoding is 19.92 MB. + +See the test/mpi_dec_test.c for detailed decoder demo source code. + +# 4.2 Encoder demo + +The encoder demo is the mpi_enc_test series programs, including single-threaded mpi_enc_test and multi-instance mpi_enc_multi_test. + +Take mpi_enc_test on the Android platform as an example. First run mpi_enc_test directly, output is shown below: + +![](media/Rockchip_Developer_Guide_MPP/MPP_print_encode_help.png) + +The help document can be divided into three parts: + +(1) mpi_enc_test command parameter descriptions; + +(2) the coding type description of the output encoded bitstream file; + +(3) the format description of the input picture. + +The command parameter descriptions as follows. + +| command parameter | descriptions | +| ----------------- | ------------------------------------------------------------ | +| -i | input frame file | +| -o | output encoded bitstream | +| -w | width of input bitstream, in pixels | +| -h | height of input bitstream, in pixels | +| -hstride | the horizontal stride of input picture, in byte | +| -vstride | the vertical stride of input picture, in 1 | +| -f | the format of input picture, NV12 by default | +| -t | output stream coding type | +| -tsrc | input file source coding type, only used in the codec performance test(see mpi_rc2_test.c) | +| -n | max encoding frame number. If input bitstream is too long, only the first n frames can be decoded. | +| -g | gop reference mode | +| -rc | set rc_mode, 0:vbr 1:cbr 2:fixqp 3:avbr | +| -bps | set bit rate | +| -fps | set input and output frame rate, 30 by default. This command parameter only describes the proportional relationship between the input frame rate and the output frame rate, which is to related to the real frame rate. | +| -qc | set quality control | +| -s | number of instances, 1 by default | +| -v | trace option: q - quiet; f - show fps | +| -ini | encoder extra ini config file(not yet in effect) | +| -slt | slt verify data file corresponding to output encoded bitstream | + +mpi_enc_test command parameters, image width (w), image height (h), and coding type (t) are mandatory configuration parameters, while other parameters such as input file (i), output file (o), encoding frame number (n), and the format of input picture(f) are optional parameters. If no input file is specified, mpi_enc_test will generate a default color bar image for encoding. + +mpi_enc_test command parameters provide diversified bit rate control schemes, allowing users to control the bit rate of the output stream through bit rate control mode and bit rate constraint parameter. The bit rate control mode is divided into variable bit rate mode (VBR), fixed bit rate mode (CBR), QP-adjusted bit rate mode (FIXQP), and adaptive bit rate mode (AVBR), with the default mode being VBR; the bit rate constraint parameter provides reference for configuring bit rate boundaries within MPP. + +The format for input/output frame rate control (fps) in mpi_enc_test command parameters is: + + ``` + -fps fps_in_num:fps_in_den:fps_in_flex/fps_out_num:fps_out_den:fps_out_flex + ``` + +where in/out represents input/output, num represents the numerator, den represents the denominator, and flex being 0 indicates fixed frame rate and 1 indicates variable frame rate. The default num and den for input and output are 30 and 1, respectively, indicating a default input/output frame rate of 30. This command parameter only indicates the proportional relationship between input frame rate and output frame rate, and is independent of the actual frame rate. + +In mpi_enc_test command parameters, quality control only takes effect when the output stream format is H.264, H.265, VP8, or JPEG. The command format is: + + ``` + -qc qp_init/min/max/min_i/max_i + ``` + +where qp represents quality parameters, init represents the initial value, min represents the minimum value, max represents the maximum value; the suffix i indicates the maximum value of I frames if unspecified, representing B and P frames. + +In mpi_enc_test command parameters, if the logging option (v) is set to q, MPP daily logging will be disabled; if set to f, the average frame rate and current frame rate will be printed once every second. + +Image color space formats are divided into YUV and RGB. MPP supports multiple formats (f), with different parameter values corresponding to different layouts; it is worth noting that there are significant differences between YUV and RGB format parameter values. + +Taking encoding of ocrean.yuv under the directory /data with 30 frames as an example, the corresponding demo and output are described. The running command is: + + ```bash + mpi_enc_test -w 1920 -h 1080 -t 7 -i /data/ocrean.yuv -o /data/out.h264 -n 30 + ``` + +If everything is normal, the following result will be obtained: + +![](media/Rockchip_Developer_Guide_MPP/MPP_encode_log.png) + +Log introduction related to the decoder demo have been omitted. + + ``` + I mpp_enc: MPP_ENC_SET_RC_CFG bps 7776000 [486000:8262000] fps [30:30] gop 60 + ``` + +Default bitrate control parameters for the encoder, with a target bitrate of 7.8 Mbps, a lower reference bitrate of 0.5 Mbps, and an upper reference bitrate of 8.3 Mbps. The default input and output frame rate is 30, and the default GOP size is 60. + + ``` + I mpi_enc_test: chn 0 encoded frame 0 size 218616 qp 11 + ``` + +The mpi_enc_test printing indicates that the encoder is encoding normally. The size of the output single-frame bitstream is 0.2 M, and the quality parameter is 11. + + ``` + I mpi_enc_test: chn 0 encode 30 frames time 628 ms delay 4 ms fps 47.72 bps 10265048 + ``` + +The mpi_enc_test printing indicates that the encoder encoded 30 frames within 628 ms, with a delay of 4 ms for the first frame. The frame rate is 47.72 fps, and the bitrate is 10.2 Mbps. + +``` +I mpi_enc_test: mpi_enc_test average frame rate 47.72 +``` + +The mpi_enc_test printing indicates that the average frame rate of the encoder is 47.72 fps. + +The encoder's control parameters can also be configured through environment variables. In the Android environment, the command for configuring environment variables is: + +```bash +setprop value +``` + +In the Linux environment, the command for configuring environment variables is: + +```bash +export =value +``` + +The corresponding descriptions are as follows: + +| Control Parameter | Type | Description | +| ----------------- | ------ | ------------------------------------------------------------ | +| constraint_set | RK_U32 | Only effective for H.264 bitstream, corresponding to the constraint_set0_flag to constraint_set5_flag in the syntax. The forced flag force_flag and forced constraint parameter constraint_force are stored in the format: \| 00 \| force_flag \| 00 \| constraint_force \| Only the lower 6 bits are valid, corresponding to constraint_set5_flag to constraint_set0_flag. When force_flag is 1, the corresponding constraint_set is configured to the encoder. | +| split_mode | RK_U32 | Encoder split mode. 0: No split. 1: divides the slice according to the slice size. 2: divides the slice according to the number of macroblocks or CTUs. | +| split_arg | RK_U32 | split_arg takes effect only when encoder split_mode is enabled. When by byte, this parameter is the byte limit for each slice; when by CTU, this parameter is the CTU limit for each slice. | +| split_out | RK_U32 | Split output mode, effective only when encoder splitting mode is enabled. 1: Low delay output mode; 2:Segment information output mode. Under low delay output mode, the encoder outputs each slice with low delay; under segment information output mode, the encoder encapsulates segment information for each slice. | +| sei_mode | RK_U32 | SEI write mode. 0: No SEI write; 1: Sequence write mode; 2: Frame write mode. Under sequence write mode, there is only one SEI for each GOP; under frame write mode, SEI will also be added before each frame if SEI information changes. | +| gop_mode | RK_U32 | gop reference mode. If the environment variable gop_mode is not configured, it will be configured according to the command parameter; otherwise, it will be configured according to the environment variable. | +| osd_enable | RK_U32 | Enable OSD palette. | +| osd_mode | RK_U32 | OSD palette mode, effective only after enabling OSD palette. 0: Default configuration; 1: User-defined configuration. | +| roi_enable | RK_U32 | Enable ROI testing and use the platform's default roi_type configuration. | +| roi_type | RK_U32 | Forced configuration of roi_type. | +| user_data_enable | RK_U32 | Enable user data. | + +The specific code of the encoder demo can be found in test/mpi_enc_test.c, but the current encoder demo uses the enqueue/dequeue interface mode, which will be modified later. + +# 4.3 Utilities + +MPP provides some tool programs for unit testing, which can test the hardware and software platform and the MPP library itself. + +**mpp_info_test** + +Used to read and print the version information of the MPP library. When feeding back the problem, you can attach the printed information. + + **mpp_buffer_test** + +Used to test whether kernel memory allocator is normal or not. + + **mpp_mem_test** + +Used to test whether memory allocator of the C library is normal or not. + + **mpp_runtime_test** + +Used to test whether some hardware and software running environment is normal. + + **mpp_platform_test** + +Used to read and test whether the chip platform information is normal. + +# Chapter 5 MPP library compiling and use + +# 5.1 Download source code + +The MPP source code is released at the official address: https://github.com/rockchip-linux/mpp + +The release branch is the release branch, the development branch is the develop branch, and the default is the development branch. + +The command of download: git clone [https://github.com/rockchip-linux/mpp.git](https://github.com/rockchip-linux/mpp.git) + +# 5.2 Compiling + +The MPP source code compilation script is cmake. It depends on the version above 2.8.12. It is recommended to use the 2.8.12 version. Using the high version of the cmake tool may generate more warnings. + +## 5.2.1 Android platform cross-compiling + +Compiling the Android library requires the ndk environment, and the default script is compiled using android-ndk-r10d. + +The download path for r10d ndk can be found in the build/android/ndk_links.md file in the source directory. + +Unzip the downloaded ndk to /home/pub/ndk/android-ndk-r10d, or manually modify the ANDROID_NDK variable path of the env_setup.sh script in the build/android/ directory. + +Go to the build/android/arm/ directory, run the make-Android.bash script to generate the Makefile for compilation, and run make –j16 to compile. + +## 5.2.2 Unix/Linux platform compiling + +First configure the toolchain in the arm.linux.cross.cmake file in the build/linux/arm/ directory, then run the make-Makefiles.bash script to generate the Makefile via cmake, and finally run make –j16 to compile. + +MPP also supports compiling directly on Debian running on the development board. + +# Chapter 6 Frequently Asked Questions + +Q: Aarch64 compile error, the error is undefined reference to \`system_property_get\`. + +A: This is a problem with google 64bit ndk. Some symbol definitions are missing from libc.so. For the problem, see: + +[http://stackoverflow.com/questions/28413530/api-to-get-android-system-properties-is-removed-in-arm6](http://stackoverflow.com/questions/28413530/api-to-get-android-system-properties-is-removed-in-arm64-platforms) [4-platforms](http://stackoverflow.com/questions/28413530/api-to-get-android-system-properties-is-removed-in-arm64-platforms) + +Solution: MPP has put the corresponding libc.so into the build/android/aarch64/fix/ directory, copy the library to the path_to_ndk/platforms/android-21/arch-arm64/usr/lib/ path. You just need recompiling. + +Q: When running, the following kernel log will be printed, is there a problem?? + +vpu_service_ioctl:1844: error: unknow vpu service ioctl cmd 40086c01 + +A: No problem, mpp has some dependencies on the kernel driver, the kernel driver has different versions of the interface, mpp will make multiple attempts. If it fails, it will try another interface. This print is printed when the attempt fails and will only be printed once. This print can be ignored. + +Q: How to analyze the problem of abnormal MPP operation? + +A: First analyze the error log. If there is a log that fails to open the kernel device, you need to analyze whether the hardware device configuration file of the video codec of the kernel platform is available, and then submit the problem to redmine. After analyzing the operating environment problem, analyze the MPP operation Internal issue. \ No newline at end of file diff --git a/doc/media/Figure01_MPP_system_framework.png b/doc/media/Figure01_MPP_system_framework.png new file mode 100644 index 00000000..a486fc5a Binary files /dev/null and b/doc/media/Figure01_MPP_system_framework.png differ diff --git a/doc/media/Figure02_Data_structure_used_in_MPI_interface.png b/doc/media/Figure02_Data_structure_used_in_MPI_interface.png new file mode 100644 index 00000000..45b8eaa5 Binary files /dev/null and b/doc/media/Figure02_Data_structure_used_in_MPI_interface.png differ diff --git a/doc/media/Figure03_Use_simple_interface_to_realize_video_decoding.png b/doc/media/Figure03_Use_simple_interface_to_realize_video_decoding.png new file mode 100644 index 00000000..9bc4e8c8 Binary files /dev/null and b/doc/media/Figure03_Use_simple_interface_to_realize_video_decoding.png differ diff --git a/doc/media/Figure03_Use_simple_interface_to_realize_video_decoding_EN.png b/doc/media/Figure03_Use_simple_interface_to_realize_video_decoding_EN.png new file mode 100644 index 00000000..7550577c Binary files /dev/null and b/doc/media/Figure03_Use_simple_interface_to_realize_video_decoding_EN.png differ diff --git a/doc/media/Figure04_Normal_usage_of_MppBuffer.png b/doc/media/Figure04_Normal_usage_of_MppBuffer.png new file mode 100644 index 00000000..f5c8b33d Binary files /dev/null and b/doc/media/Figure04_Normal_usage_of_MppBuffer.png differ diff --git a/doc/media/Figure04_Normal_usage_of_MppBuffer_EN.png b/doc/media/Figure04_Normal_usage_of_MppBuffer_EN.png new file mode 100644 index 00000000..7a915fbc Binary files /dev/null and b/doc/media/Figure04_Normal_usage_of_MppBuffer_EN.png differ diff --git a/doc/media/Figure05_Usage_of_MppBuffer_External_Import.png b/doc/media/Figure05_Usage_of_MppBuffer_External_Import.png new file mode 100644 index 00000000..8a582ecf Binary files /dev/null and b/doc/media/Figure05_Usage_of_MppBuffer_External_Import.png differ diff --git a/doc/media/Figure05_Usage_of_MppBuffer_External_Import_EN.png b/doc/media/Figure05_Usage_of_MppBuffer_External_Import_EN.png new file mode 100644 index 00000000..0a5305e3 Binary files /dev/null and b/doc/media/Figure05_Usage_of_MppBuffer_External_Import_EN.png differ diff --git a/doc/media/Figure06_Important_parameter_description_of_MppPacket.png b/doc/media/Figure06_Important_parameter_description_of_MppPacket.png new file mode 100644 index 00000000..f02ee40c Binary files /dev/null and b/doc/media/Figure06_Important_parameter_description_of_MppPacket.png differ diff --git a/doc/media/Figure06_Important_parameter_description_of_MppPacket_EN.png b/doc/media/Figure06_Important_parameter_description_of_MppPacket_EN.png new file mode 100644 index 00000000..688f5465 Binary files /dev/null and b/doc/media/Figure06_Important_parameter_description_of_MppPacket_EN.png differ diff --git a/doc/media/Figure07_Important_parameter_description_of_MppFrame.png b/doc/media/Figure07_Important_parameter_description_of_MppFrame.png new file mode 100644 index 00000000..3a945da5 Binary files /dev/null and b/doc/media/Figure07_Important_parameter_description_of_MppFrame.png differ diff --git a/doc/media/Figure07_Important_parameter_description_of_MppFrame_EN.png b/doc/media/Figure07_Important_parameter_description_of_MppFrame_EN.png new file mode 100644 index 00000000..e8969ef9 Binary files /dev/null and b/doc/media/Figure07_Important_parameter_description_of_MppFrame_EN.png differ diff --git a/doc/media/Figure08_Use_MppTask_for_input_and_output.png b/doc/media/Figure08_Use_MppTask_for_input_and_output.png new file mode 100644 index 00000000..6cf50ea9 Binary files /dev/null and b/doc/media/Figure08_Use_MppTask_for_input_and_output.png differ diff --git a/doc/media/Figure08_Use_MppTask_for_input_and_output_EN.png b/doc/media/Figure08_Use_MppTask_for_input_and_output_EN.png new file mode 100644 index 00000000..06f38267 Binary files /dev/null and b/doc/media/Figure08_Use_MppTask_for_input_and_output_EN.png differ diff --git a/doc/media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask.png b/doc/media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask.png new file mode 100644 index 00000000..2df56e88 Binary files /dev/null and b/doc/media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask.png differ diff --git a/doc/media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask_EN.png b/doc/media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask_EN.png new file mode 100644 index 00000000..d1cb6c24 Binary files /dev/null and b/doc/media/Figure09_Data_Types_and_Keyword_Types_Supported_by_MppTask_EN.png differ diff --git a/doc/media/Figure10_MppCtx_usage_process.png b/doc/media/Figure10_MppCtx_usage_process.png new file mode 100644 index 00000000..b5df8ae7 Binary files /dev/null and b/doc/media/Figure10_MppCtx_usage_process.png differ diff --git a/doc/media/Figure11_MPI_interface_range.png b/doc/media/Figure11_MPI_interface_range.png new file mode 100644 index 00000000..d7d9696e Binary files /dev/null and b/doc/media/Figure11_MPI_interface_range.png differ diff --git a/doc/media/Figure12_Decoder_multi_thread_usage.png b/doc/media/Figure12_Decoder_multi_thread_usage.png new file mode 100644 index 00000000..7fe1c26d Binary files /dev/null and b/doc/media/Figure12_Decoder_multi_thread_usage.png differ diff --git a/doc/media/Figure12_Decoder_multi_thread_usage_EN.png b/doc/media/Figure12_Decoder_multi_thread_usage_EN.png new file mode 100644 index 00000000..e9310811 Binary files /dev/null and b/doc/media/Figure12_Decoder_multi_thread_usage_EN.png differ diff --git a/doc/media/Figure12_Decoder_single_thread_usage.png b/doc/media/Figure12_Decoder_single_thread_usage.png new file mode 100644 index 00000000..43f08207 Binary files /dev/null and b/doc/media/Figure12_Decoder_single_thread_usage.png differ diff --git a/doc/media/Figure12_Decoder_single_thread_usage_EN.png b/doc/media/Figure12_Decoder_single_thread_usage_EN.png new file mode 100644 index 00000000..6f758f28 Binary files /dev/null and b/doc/media/Figure12_Decoder_single_thread_usage_EN.png differ diff --git a/doc/media/Figure13_Schematic_diagram_of_pure_internal_allocation_mode.png b/doc/media/Figure13_Schematic_diagram_of_pure_internal_allocation_mode.png new file mode 100644 index 00000000..04f914c0 Binary files /dev/null and b/doc/media/Figure13_Schematic_diagram_of_pure_internal_allocation_mode.png differ diff --git a/doc/media/Figure14_Code_flow_of_decoder_image_memory_pure_internal_allocation_mode.png b/doc/media/Figure14_Code_flow_of_decoder_image_memory_pure_internal_allocation_mode.png new file mode 100644 index 00000000..6e459031 Binary files /dev/null and b/doc/media/Figure14_Code_flow_of_decoder_image_memory_pure_internal_allocation_mode.png differ diff --git a/doc/media/Figure15_Semi-internal_allocation_mode_decoder_work_flow.png b/doc/media/Figure15_Semi-internal_allocation_mode_decoder_work_flow.png new file mode 100644 index 00000000..4b687fd1 Binary files /dev/null and b/doc/media/Figure15_Semi-internal_allocation_mode_decoder_work_flow.png differ diff --git a/doc/media/Figure16_Schematic_diagram_of_pure_external_allocation_mode.png b/doc/media/Figure16_Schematic_diagram_of_pure_external_allocation_mode.png new file mode 100644 index 00000000..e46261ce Binary files /dev/null and b/doc/media/Figure16_Schematic_diagram_of_pure_external_allocation_mode.png differ diff --git a/doc/media/Figure17_Pure_external_allocation_mode_decoder_work_flow.png b/doc/media/Figure17_Pure_external_allocation_mode_decoder_work_flow.png new file mode 100644 index 00000000..0aa33019 Binary files /dev/null and b/doc/media/Figure17_Pure_external_allocation_mode_decoder_work_flow.png differ diff --git a/doc/media/Figure18_Encoder_input_frame_memory_arrangement_1.png b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_1.png new file mode 100644 index 00000000..73bbae4b Binary files /dev/null and b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_1.png differ diff --git a/doc/media/Figure18_Encoder_input_frame_memory_arrangement_1_EN.png b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_1_EN.png new file mode 100644 index 00000000..d80df22d Binary files /dev/null and b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_1_EN.png differ diff --git a/doc/media/Figure18_Encoder_input_frame_memory_arrangement_2.png b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_2.png new file mode 100644 index 00000000..8bab7e2a Binary files /dev/null and b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_2.png differ diff --git a/doc/media/Figure18_Encoder_input_frame_memory_arrangement_2_EN.png b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_2_EN.png new file mode 100644 index 00000000..e2d88a64 Binary files /dev/null and b/doc/media/Figure18_Encoder_input_frame_memory_arrangement_2_EN.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_H264Profile.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_H264Profile.png new file mode 100644 index 00000000..287bf456 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_H264Profile.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type.png new file mode 100644 index 00000000..a13613f5 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type_related_to_MPP.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type_related_to_MPP.png new file mode 100644 index 00000000..1a72084c Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MpiCmd_enumeration_type_related_to_MPP.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppCodingType.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppCodingType.png new file mode 100644 index 00000000..328d5958 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppCodingType.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncMirrorCfg.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncMirrorCfg.png new file mode 100644 index 00000000..649606a7 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncMirrorCfg.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcDropFrmMode.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcDropFrmMode.png new file mode 100644 index 00000000..e7a059e3 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcDropFrmMode.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcMode.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcMode.png new file mode 100644 index 00000000..e31b19ef Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcMode.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcPriority.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcPriority.png new file mode 100644 index 00000000..9ebca5ca Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcPriority.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcSuperFrameMode.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcSuperFrameMode.png new file mode 100644 index 00000000..31e1808a Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRcSuperFrameMode.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRotationCfg.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRotationCfg.png new file mode 100644 index 00000000..29df9ef9 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncRotationCfg.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncSplitMode.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncSplitMode.png new file mode 100644 index 00000000..2e8c095b Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppEncSplitMode.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppFrameColorRange.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppFrameColorRange.png new file mode 100644 index 00000000..466d01e8 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppFrameColorRange.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppFrameFormat.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppFrameFormat.png new file mode 100644 index 00000000..87475ac3 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppFrameFormat.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init.png new file mode 100644 index 00000000..e34aa61a Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init_EN.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init_EN.png new file mode 100644 index 00000000..8ed3a99b Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_by_copy_init_EN.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer.png new file mode 100644 index 00000000..c64ca91e Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer_EN.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer_EN.png new file mode 100644 index 00000000..c25a12e0 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_MppPacket_is_generated_from_MppBuffer_EN.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_Split_mode_config.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_Split_mode_config.png new file mode 100644 index 00000000..06f149a5 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_Split_mode_config.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_color_space_range.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_color_space_range.png new file mode 100644 index 00000000..1754b7bf Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_color_space_range.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_decode_log.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_decode_log.png new file mode 100644 index 00000000..bce110af Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_decode_log.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_encode_log.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_encode_log.png new file mode 100644 index 00000000..7afb5827 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_encode_log.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket.png new file mode 100644 index 00000000..7e896b0d Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket_EN.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket_EN.png new file mode 100644 index 00000000..c1296696 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_external_malloc_address_is_configured_to_MppPacket_EN.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_image_colorspace_format_and_memory_arrangement.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_image_colorspace_format_and_memory_arrangement.png new file mode 100644 index 00000000..ac9df3e6 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_image_colorspace_format_and_memory_arrangement.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_image_data_frame_field_properties.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_image_data_frame_field_properties.png new file mode 100644 index 00000000..f7a20c0f Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_image_data_frame_field_properties.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_print_decode_help.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_print_decode_help.png new file mode 100644 index 00000000..6f4dfd39 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_print_decode_help.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_print_encode_help.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_print_encode_help.png new file mode 100644 index 00000000..0811285d Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_print_encode_help.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage.png new file mode 100644 index 00000000..5a233744 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage_EN.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage_EN.png new file mode 100644 index 00000000..deab6cc6 Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_external_import_usage_EN.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage.png new file mode 100644 index 00000000..74f851bb Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage.png differ diff --git a/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage_EN.png b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage_EN.png new file mode 100644 index 00000000..7dc26e0d Binary files /dev/null and b/doc/media/Rockchip_Developer_Guide_MPP/MPP_procedure_pseudo_code_of_normal_usage_EN.png differ