> 技术文档 > 全网最细万字教学!RK3588使用ffmpeg+rkmpp硬解码+DRM渲染显示MP4视频【纯代码】_ffmpeg mpp

全网最细万字教学!RK3588使用ffmpeg+rkmpp硬解码+DRM渲染显示MP4视频【纯代码】_ffmpeg mpp


文章目录

  • 1.项目介绍
  • 2.项目文件架构介绍
  • 3.使用说明
  • 4.交叉编译介绍
    • 4.1 查找对应的交叉编译工具
    • 4.2 交叉编译对应模块
      • 4.2.1 交叉编译libdrm
      • 4.2.2 交叉编译mpp
      • 4.2.3交叉编译 x264
      • 4.2.4 交叉编译opencv
      • 4.2.5 交叉编译ffmpeg
    • 4.3 打包动态链接到板子端
  • 5.DRM讲解
    • 5.1DRM基本概念
    • 5.2 modetset调试DRM
    • 5.3 DRM初始化代码讲解
  • 6.ffmpeg讲解
    • 6.1 ffmpeg初始化
  • 7.播放视频
  • 8.演示成果

1.项目介绍

板子:正点原子RK3588开发板

SDK:正点原子官方提供,正点原子RK3588开发板 — 正点原子资料下载中心 1.0.0 文档

交叉工具编译链:gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu

编程语言:c/c++

cmake: 3.22.1

os:ubuntu22.04(wsl2)

本项目是在PC上搭建交叉编译环境进行编译最后将程序部署在板子端,功能为:应用层使用ffmpeg+rkmpp插件对h.264格式的mp4进行硬解码,然后将得到的AV_PIX_FMT_DRM_PRIME格式帧使用DRM框架进行渲染显示。

题外话,市面上流行的共有三套方案:

(1)ffmpeg使用CPU进行软解,占用cpu资源高,但是稳定;

(2)ffmpeg进行解封装,然后使用瑞芯微提供的mpp框架进行硬解码;

(3)ffmpeg+rkmpp硬解码。

其实2跟3的原理是差不多,只是3把官方的mpp杂糅进了ffmpeg里面。经过实测下来方案三在稳定性上更胜一筹,并且使用流程和ffmpeg一致,基本没有再学习成本。

2.项目文件架构介绍

├───3rd :使用的第三模块,包括mpp、DRM、ffmpeg、x264、opencv、 ├───install/ :交叉编译生成的头文件和库├───source/ :第三模块的源代码├───example :参考代码,大部分是单独模块的实现和测试├──drm-howto/ :DRM的原子操作示例├──drm-test/ :DRM的测试├─── drm_atomic_ctrc.c :最简单的DRM 原子操作,不使用plane,使单颜色铺满屏幕├─── drm_atomic_plane.c:使用plane的DRM原子操作,使单颜色铺满屏幕├─── drm_atomic_jpg.c:使用opencv和plane显示一张jpg图片到屏幕上├─── drm_test.c : 不使用原子操作,用最原始的方式(已过时)使用DRM框架显示彩色方块├──ffmpeg_player/ :ffmpeg+sdl2实现最简单的播放视频,想了解使用ffmpeg流程的可以查阅├───source:项目的DRM显示和ffmpeg解码渲染源代码,也是最关键的代码├───drmDisplay.cpp:DRM相关的操作和对象├───drmDisplay.h├───ffmpegPlayer.cpp:ffmpeg相关的操作和对象├───ffmpegPlayer.h├───toolchain:交叉编译工具链放置地点├───main.cpp:程序的入口函数...

3.使用说明

由于gitee对个人用户git-lfs有限制不能上传大文件,所以交叉编译工具链无法上传,不过大家的板子不一样,SDK不一样,使用的编译链也不一样,就算上传了用处也不大hhh。所以程序要运用到各自的板子上的话要重新配置交叉编译工具链,使用你们的交叉工具链重新编译对应模块,再编译链接成可执行程序。

(1) 拉取源码

git clone https://gitee.com/freecry039/ffmpeg_rkmpp_drm.gitcd ./ffmpeg_rkmpp_drm

(2) 更新子模块,获取第三方官方库

git submodule update --init --recursive

(3) 重新编译第三方库:

​ 参考第四章节的内容

(4) 创建build目录编译生成对应的执行文件

mkdir ./buildcd buildcmake ..make -j36

(5)在项目根目录下会出现bin目录,里面会生成main.exe执行程序,/path/to/ffmpeg-rkmpp-drm/bin/main/.exe,将其使用u盘或者frp等拉取到板子上运行即可。

4.交叉编译介绍

嵌入式系统通常由具有特殊硬件架构的处理器(如ARM、MIPS等)组成,而这些处理器的架构和常见的桌面计算机(如x86、x64)有所不同。为了在嵌入式设备上运行程序,我们需要将程序从PC上编译成适用于嵌入式目标平台的代码。这个过程就叫做交叉编译

其实可以简单这样理解,你必须使用你编译sdk时使用的交叉编译工具链去编译目标程序,目标程序才能正常跑在板子上。

4.1 查找对应的交叉编译工具链

厂商一般会提供对应的sdk给用户去编译烧录进板子,那么他们肯定会提供对应的交叉编译工具链的,以正点原子rk3588为例,在官方提供的说明文档中介绍了交叉编译工具链就在prebuilts文件夹下面。
SDK工程目录描述

在找到对应的交叉编译工具链之后直接复制整个交叉编译工具链到项目目录下的toolchain文件夹下面,正点原子的目录如下:

交叉编译工具链所在位置

cp -rf /path/to/toolchain /path/to/ffmpeg_rkmpp_drm/toolchian

然后声明交叉编译工具链的环境变量

export PATH=/path/to/ffmpeg_rkmpp_drm/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH

如果声明成功的话在终端输入交叉编译的前缀然后按TAB键会出现提示
交叉编译链声明成功

然后执行会有相对于输出

 aarch64-none-linux-gnu-gcc -v

4.2 交叉编译对应模块

如果不是和本项目一样的环境,那么需要重新编译不同模块。先把项目下对应已经编译好的模块删掉,在项目根目录下执行以下命令

rm -rf ./3rd/install/mpp/* ./3rd/install/ffmpeg/* ./3rd/install/libdrm/* ./3rd/install/opencv/* ./3rd/install/x264/*

因为ffmpeg的交叉编译依赖其他模块,所以要先编译完其它四个模块最后再编译ffmpeg

4.2.1 交叉编译libdrm

进入到libdrm的源码之中

cd ./3rd/source/libdrm-2.4.123/

创建build文件夹

mkdir ./build

创建cross_file.txt文件,用于配置 meson 交叉编译 libdrm 库。这些配置文件指定了交叉编译所需的工具链、目标平台(嵌入式平台)和构建平台(开发平台)的信息。

touch ./cross_file.txt

打开cross_file.txt文件填上以下内容,如果是不同的交叉编译工具链记得把[binaries]下面的对应选项更换成你们的编译链名称,其他照抄即可

[binaries]c = \'aarch64-none-linux-gnu-gcc\'cpp = \'aarch64-none-linux-gnu-g++\'ar = \'aarch64-none-linux-gnu-ar\'strip = \'aarch64-none-linux-gnu-strip\'[host_machine]system = \'linux\'cpu_family = \'arm\'cpu = \'armv8\'endian = \'little\'[build_machine]system = \'linux\'cpu_family = \'x86_64\'cpu = \'x86_64\'endian = \'little\'[project options]install-test-programs = \'true\'

进入之前创建好的build目录下使用 meson 构建系统来配置并构建一个项目

cd ./buildmeson --prefix=$(pwd)/../../../install/libdrm/ --cross-file=../cross_file.txt -D exynos=enabled

–prefix 选项指定了项目构建后的安装路径。这里使用了 $(pwd),它是一个 shell 命令,表示当前工作目录的路径(即你运行命令时所在的目录),命令让它指向了ffmpeg_rkmpp_drm/3rd/install/libdrm/

–cross-file 选项告诉 Meson 使用指定的交叉编译配置文件进行构建。…/cross_file.txt 是一个相对路径,指向当前目录的上一级目录中的 cross_file.txt 文件

-D是配置是否编译对应功能的,可加可不加

执行ninja命令进行编译和安装

ninja && ninja install

命令执行完后发现已经生成对应的头文件和库

在这里插入图片描述

也可以使用file命令查看一下对应的.so文件的架构来确认是否交叉编译成功

file libdrm.so.123.0*

在这里插入图片描述

4.2.2 交叉编译mpp

本项目使用的是https://github.com/rockchip-linux/mpp仓库,在编译时使用的日志编号是aaa4c8e9(当时最新),也是项目的子模块里面链接的分支,使用git submodule update --init --recursive可以拉取。

进入到mpp的源码之中

cd ./3rd/source/mpp/

进入对应的build文件夹

cd ./build/linux/aarch64/

按照自己的环境修改make-Makefiles.bash文件,主要是下面标注的两个选项,第一个为交叉编译链的名称,第二个为交叉编译链的路径

mpp_make-Makefiles.bash

修改arm.linux.cross.cmake文件,也是修改为对应的交叉工具链,下面是运行平台,rk3588的话就写aarch64即可

arm.linux.cross.cmake

修改完毕后直接执行脚本

./make-Makefiles.bash

执行成功后会生成makefile对应的文件

广东新闻