若该文为原创文章,转载请注明原文出处。
主要是想测试MPP的解码,为后续做测试。
一、环境
1、平台:rk3568
2、开发板:ATK-RK3568正点原子板子
3、环境:buildroot
二、编译
使用的是正点原子提供的虚拟机,搭建好环境后,编译SDK,原子的手册有详细的编译过程。
接下来编译mpp
进入/home/alientek/rk3568_linux_sdk目录
cd /home/alientek/rk3568_linux_sdk
执行
./build.sh external/mpp/
可以看出编译的可执行文件在/home/alientek/rk3568_linux_sdk/buildroot/output/rockchip_rk3568/target/usr/bin/目录下
进入/home/alientek/rk3568_linux_sdk/buildroot/output/rockchip_rk3568/target/usr/bin/目录,
给开发板上电,通过adb把可执行文件上传到开发板
adb push mpi_dec_test /userdata/aidemo
三、测试
在测试执行,需要准备一个h264文件,把文件放到和mpi_dec_test同目录。
执行
mpi_dec_test -i output.h264 -t 7 -n 200 -o decode.yuv -w 640 -h 480
看出,解码也yuv文件,通过YUV播放器播放,显示正常。
四、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测试中,将输出帧文件的对比转换成校验文件的对比,可以显著缩短测试周期。
MPP支持的解码类型:
1、MPP库支持的输入文件的编码格式(t)为MPEG2/4、H.263/4/5、VP8/9和JPEG等,id后的数字为不同编码格式对应的参数值。参数值来源于OMX的定义,值得注意的是,HEVC和AVS格式的参数值与其他格式的有显著区别。
五、mpp解码流程解析
- mpp_create :获取 MppCtx 实例以及 MppApi 结构体
- mpp_init: 初始化MppCtx 的编解码类型与格式
- mpi->control:通过相应的命令来配置解码参数
- decode_put_packet:输入码流:编码数据 MppPacke,例如264、265数据
- decode_get_frame: 获取解码的数据存放到MppFrame,例如YUV、RGB数据
- mpi->reset:使解码器恢复为正常初始化后的状态。
- mpp_destroy:释放申请的内存空间,做销毁善后工作
重要函数解析
mpp_init函数:初始化MppCtx 的编解码类型与格式
mpp_init函数原型:
MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding)
mpp_init函数调用实例:
ret = mpp_init(ctx, MPP_CTX_DEC, MppCodingType::MPP_VIDEO_CodingAVC);
if (ret)
{
mpp_err("mpp_init failed ret %d\n", ret);
goto MPP_TEST_OUT;
}
mpp_init函数参数解析:
- MppCtxType 参数:初始化编码还是解码
MPP_CTX_DEC : 解码
MPP_CTX_ENC : 编码 - MppCodingType 参数:编解码的格式
MPP_VIDEO_CodingAVC : H.264
MPP_VIDEO_CodingHEVC: H.265
MPP_VIDEO_CodingVP8 : VP8
MPP_VIDEO_CodingVP9 : VP9
MPP_VIDEO_CodingMJPEG : MJPEG
mpi_dec_test 流程解析:
main( ) ---> dec_decode( ) ---> thread_decode( ) ---> dec_simple( ) ---> mpp_destroy( )
- main函数根据传进来的参数(参数char **argv 对应命令中的 -i output.h264 -t 7 -n 200 -o decode.yuv -w 640-h 480)对参数进行解析保存到 MpiDecTestCmd * cmd 结构体中
- dec_decode(cmd) 函数是封装好的解码函数,传入 MpiDecTestCmd * cmd 结构体即可完成解码
- dec_decode 函数执行了一些MPP的初始化操作:mpp_create() mpp_init() ,mpp_dec_cfg_init() , mpi->control。初始化之后创建解码线程: thread_decode 进行解码。
- 解码线程: thread_decode 线程根据 cmd->simple 变量判断是使用 dec_simple 解码还是 dec_advanced 解码
- 解码完最后一帧之后执行 pthread_join() 函数等待解码线程: thread_decode 结束后做线程释放工作
- 线程释放完毕之后执行reset复位操作:mpi->reset(ctx)把解码器恢复为正常初始化后的状态。
- 解码器复位之后通过mpp_destroy()释放申请的内存空间,进行一些销毁操作防止内存泄漏。
接下来独立编写一个demo测试为后续增加RTSP解码做准备。
如有侵权,或需要完整代码,请及时联系博主。