2. 视频编解码——基于mpp库

2.1. MPP 介绍

瑞芯微提供的媒体处理软件平台(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)

以下为RK官方MPP文档的GitHub链接,包含了中文/英文的MPP开发指南。

https://github.com/rockchip-linux/mpp/tree/develop/doc

2.2. 获取和编译RKMPP库

2.2.1. 测试环境

测试板卡:鲁班猫1

测试操作系统:Ubuntu20.04

内核版本:Linux 4.19.232

RK官方MPP库地址: https://github.com/rockchip-linux/mpp

2.2.2. 安装相关依赖工具

sudo apt update
sudo apt install -y git cmake

2.2.3. 拉取RK官方MPP仓库

git clone https://github.com/rockchip-linux/mpp.git

2.2.4. 编译

进入aarch64相应的编译路径

cd mpp/build/linux/aarch64/

修改交叉编译配置文件,指定编译器gcc和g++(一般默认就好)

vim arm.linux.cross.cmake
../../../_images/MPP-001.png

运行bash脚本后编译(编译过程大概需要15分钟)

./make-Makefiles.bash
make

编译结束后,你将会发现目录下多了很多文件

../../../_images/MPP-002.png

进入test目录,目录下便是编译生成的一些测试程序。

../../../_images/MPP-003.png

2.3. 视频解码

解码器demo为mpi_dec_test系列程序,包括使用decode_put_packet和decode_get_frame接口的单线程mpi_dec_test、多线程的mpi_dec_mt_test以及多实例的mpi_dec_multi_test。

2.3.1. 测试环境

测试板卡:鲁班猫1

测试操作系统:Ubuntu20.04

内核版本:Linux 4.19.232

2.3.2. mpi_dec_test的命令参数

2.3.2.1. 终端查看mpi_dec_test的命令参数

打开两个终端,其中一个终端输入以下命令,来监控日志输出。

sudo tail -f /var/log/syslog

另一个终端执行mpi_dec_test测试程序

mpi_dec_test
../../../_images/MPP-010.png

执行完测试程序后,会在日志中打印如下帮助文档:

../../../_images/MPP-011.png

帮助文档可以分为两部分:一是mpi_dec_test的命令参数说明;二是码流文件的协议类型说明。

2.3.2.2. mpi_dec_test的命令参数描述说明

命令参数的描述说明如下:

-i

输入的码流文件。

-o

输出的图像文件。

-w

图像宽度,单位为像素。

-h

图像高度,单位为像素。

-t

码流文件的协议类型。

-f

图像色彩空间格式以及内存排布方式,默认为NV12。

-n

最大解码帧数。测试时若码流较长,可仅输出前n帧。

-s

MPP实例数,默认为1。

-v

日志选项:q为静默标志;f为fps显示标志。

-slt

输出帧对应的校验文件。

-help

打开帮助文档。

小技巧

1、mpi_dec_test的命令参数中,输入文件(i)和码流类型(t)为强制要求配置的参数,其他参数如输出文件(o)、图像宽度(w)、图像高度(h)和解码帧数(n)等为可选参数,可以根据不同的测试需求进行配置。

2、mpi_dec_test的命令参数中,输出帧对应的校验文件(slt)将输出帧数据转换为对应的循环冗余校验码(具体逻辑见utils/utils.c)。校验文件的大小往往只有几kB,在芯片的slt测试中,将输出帧文件的对比转换成校验文件的对比,可以显著缩短测试周期。

2.3.2.3. MPP解码支持的码流文件协议类型说明

MPP支持的解码类型:

../../../_images/MPP-012.png

小技巧

1、MPP库支持的输入文件的编码格式(t)为MPEG2/4、H.263/4/5、VP8/9和JPEG等,id后的数字为不同编码格式对应的参数值。参数值来源于OMX的定义,值得注意的是,HEVC和AVS格式的参数值与其他格式的有显著区别。

2.3.3. 解码Demo

这里以解码《01-什么是鲁班猫.mp4》视频为例,演示一下解码的过程。

小技巧

mp4解码过程主要分为两步,第一步是将mp4转换成mpp库支持解码的纯视频类型(如:h264),第二步是使用mpp库对转换后的视频进行解码。

2.3.3.1. mp4转h264

mp4转h264,这里使用FFmpeg工具实现,关于FFmpeg工具的其他使用,可参考对应章节。

sudo apt update && sudo apt install -y ffmpeg #安装ffmpeg工具
ffmpeg -i 01-什么是鲁班猫.mp4 -c:v libx264 01.h264

其中, 01-什么是鲁班猫.mp4是要转换的源文件名, 01.h264是输出文件名.

2.3.3.2. h264解码

这步主要是对01.h264文件进行解码。打开两个终端,其中一个终端输入以下命令,来监控日志输出:

sudo tail -f /var/log/syslog

另一个终端执行解码程序

mpi_dec_test -i 01.h264 -t 7 -n 60 -o 01.yuv

提示

上述命令的作用是将01.h264解码,并保存为01.yuv。其中-i 表示输入文件,-t 7表示输入码流文件的协议类型是H.264,-n 60表示解码60帧,-o表示输出文件。

部分解码日志输出如下:

../../../_images/MPP-013.png

2.4. 视频编码

编码器demo为mpi_enc_test系列程序,包括单线程的mpi_enc_test及多实例的mpi_enc_multi_test。

2.4.1. 测试环境

测试板卡:鲁班猫1

测试操作系统:Ubuntu20.04

内核版本:Linux 4.19.232

2.4.2. mpi_enc_test的命令参数

2.4.2.1. 终端查看mpi_enc_test的命令参数

打开两个终端,其中一个终端输入以下命令,来监控日志输出。

sudo tail -f /var/log/syslog

另一个终端执行mpi_dec_test测试程序

mpi_enc_test

执行完测试程序后,会在日志中打印如下帮助文档:

../../../_images/MPP-014.png

帮助文档可以分为三部分:一是mpi_enc_test的命令参数说明;二是码流文件的协议类型说明;三是图像色彩空间格式以及内存排布方式说明。

2.4.2.2. 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

输出码流对应的校验文件。

小技巧

1、mpi_enc_test的命令参数中,图像宽度(w)、图像高度(h)和码流类型(t)为强制要求配置的参数,其他参数如输入文件(i)、输出文件(o)、编码帧数(n)和色彩空间格式及内存排布方式(f)等为可选参数。如果没有指定输入文件,mpi_enc_test会生成默认的彩条图像进行编码。

2、mpi_enc_test的命令参数提供了多样化的码率控制方案,用户可以通过码率控制模式(rc)和码率约束参数(bps)对输出码流的码率进行控制。码率控制模式(rc)分为可变码率模式(VBR)、固定码率模式(CBR)、qp修正的码率模式(FIXQP)和自适应码率模式(AVBR),默认模式为VBR;码率约束参数(bps)则是为MPP内部配置码率边界提供参考。

3、mpi_enc_test的命令参数中,日志选项(v)为q时,MPP日常日志关闭;日志选项(v)为f时,每秒会打印一次平均帧率和当前帧率。

mpi_enc_test的命令参数中,输入/输出帧率控制(fps)的格式为:

-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时生效,命令格式为:

-qc qp_init/min/max/min_i/max_i

2.4.2.3. MPP编码支持的码流文件协议类型说明

MPP支持的编码类型:

../../../_images/MPP-016.png

小技巧

1、MPP库支持的输入文件的编码格式(t)为H.265 / H.264 / VP8 / MJPEG等,id后的数字为不同编码格式对应的参数值。

2.4.2.4. 图像色彩空间格式以及内存排布方式说明

图像的色彩空间格式分为YUV和RGB两类。MPP支持多种内存排布方式(f),id后的数字为不同内存排布方式对应的参数值,值得注意的是,YUV和RGB格式的参数值有显著区别。

2.4.3. 编码Demo

这里以编码上述解码出的01.yuv文件为例,演示一下编码的过程。

小技巧

这里主要演示如何通过mpp库将yuv文件编码成h265,以及如何使用ffmepg将h265转成mp4。

2.4.3.1. yuv编码成h265

打开两个终端,其中一个终端输入以下命令,来监控日志输出:

sudo tail -f /var/log/syslog

另一个终端执行编码程序

mpi_enc_test -i 01.yuv -w 1920 -h 1080 -t 16777220 -o 01.h265 -n 20

提示

上述命令的作用是将01.yuv编码,并保存为01.h265。其中-i 表示输入文件,-w 1920表示指定像素宽度为1920,-h 1080表示指定像素高度为1080,-t 16777220表示输出码流文件的协议类型是H.265,-n 60表示解码60帧,-o表示输出文件。

部分编码日志输出如下:

../../../_images/MPP-015.png

2.4.3.2. h265转mp4

h265转mp4,这里使用FFmpeg工具实现。

sudo apt update && sudo apt install -y ffmpeg #安装ffmpeg工具
ffmpeg -i 01.h265 -c:v libx265 -c:a aac -f mp4 0101.mp4

提示

其中,01.h265是要转码的H.265视频文件名,0101.mp4是转码后的MP4文件名,-c:v libx265将视频编码为H.265格式,-c:a aac将音频编码为AAC格式,-f mp4指定输出格式为MP4。

2.5. 实用工具

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

mpp_info_test

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

mpp_buffer_test

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

mpp_mem_test

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

mpp_runtime_test

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

mpp_platform_test

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