瑞芯微 RK 系列 RK3588 使用 ffmpeg-rockchip 实现 MPP 硬件编解码和 RGA 图形加速-命令版

前言

最近使用 RK3588 在做音视频项目开发,过程中使用了该芯片提供的硬件编解码和 2D 图形加速能力,发现相比软编解码,硬编解码无论是处理速度、系统负载还是稳定性,都比软编解码强太多了。本文将分享如何使用 RK 提供的 FFmpeg + MPP + RGA,实现一个硬件编解码+2D图形加速的功能,全部使用命令行来完成。后面也会出一篇使用开发库实现的源码版。

本文不仅适用于 RK3588,也还适用于其他 RK 系列的芯片,具体的细节出入请参考官方文档

本文首先简要介绍下 MPP 和 RGA,之后介绍如何编译项目,最后介绍如何使用命令来调动它们。关于命令的代码版,将会在之后的文章中介绍,敬请期待~

什么是 MPP

MPP(Media Process Platform)全称为媒体处理平台,它是 RK 提供的一个用于进行视频硬编解码的库。通过 MPP,我们就可以使用 RK 芯片的 VPU(Video Process Unit,视频处理单元)对我们的视频进行硬件编解码,从而减少 CPU 的负担,加快编解码速度。它的架构如下:

                +---------------------------------------+
                |                                       |
                | ffmpeg / OpenMax / gstreamer / libva  |
                |                                       |
                +---------------------------------------+  
  
            +-------------------- MPP ----------------------+
            |                                               |
            |   +-------------------------+    +--------+   |
            |   |                         |    |        |   |
            |   |        MPI / MPP        |    |        |   |
            |   |   buffer queue manage   |    |        |   |
            |   |                         |    |        |   |
            |   +-------------------------+    |        |   |
            |                                  |        |   |
            |   +-------------------------+    |        |   |
            |   |                         |    |        |   |
            |   |          codec          |    |  OSAL  |   |
            |   |    decoder / encoder    |    |        |   |
            |   |                         |    |        |   |
            |   +-------------------------+    |        |   |
            |                                  |        |   |
            |   +-----------+ +-----------+    |        |   |
            |   |           | |           |    |        |   |
            |   |  parser   | |    HAL    |    |        |   |
            |   |  recoder  | |  reg_gen  |    |        |   |
            |   |           | |           |    |        |   |
            |   +-----------+ +-----------+    +--------|   |
            |                                               |
            +-------------------- MPP ----------------------+

                +---------------------------------------+
                |                                       |
                |                kernel                 |
                |       RK vcodec_service / v4l2        |
                |                                       |
                +---------------------------------------+

MPP 分别 4 个模块,分别是:

  • MPP : 媒体处理平台
  • MPI : 媒体处理接口
  • HAL : 硬件抽象层
  • OSAL : 操作系统抽象层

关于如何编译 MPP,会在下面进行介绍。

什么是 RGA

RGA(Raster Graphic Acceleration Unit)是一个独立的 2D 硬件加速器,可用于加速点/线绘制,执行图像缩放、旋转、bitBlt、alpha混合等常见的2D图形操作。

有时候我们在进行视频帧处理过程中,可能会对它进行缩放,比如摄像头捕获的是 2160P 的画面,我们想缩小到 1080P,传统的方式是使用 CPU 处理,但这会造成 CPU 的处理负担,而 RGA 提供了这个功能,可以把图形的缩放、旋转等方式放到这个硬件加速器中,加速处理。

关于如何查看 RGA 或 VPU 是否正在运行以及负载状态,可以参考我这篇文章:《瑞芯微 RK 系列 RK3588 CPU、GPU、NPU、VPU、RGA、DDR 状态查看与操作》

什么是 ffmpeg-rockchip

FFmpeg 是一个支持解码、编码、转码和流式传输多种媒体格式的多媒体框架。而 ffmpeg-rockchip 是在 FFmpeg 的基础上,封装了 MPP 编解码和 RGA 2D 图形加速功能,使得我们可以使用 FFmpeg 的 api 就能实现 MPP 和 RGA 的功能,大大降低开发成本。

下图展示了 ffmpeg-rockchip 源码库的 libavcodec 目录下的部分文件,libavcodec 目录主要是包含各种编解码器的实现,比如 h264、h265、aac 等等,而 ffmpeg-rockchip 在此基础上实现了 RK 的编解码器,比如 h264_rkmpp、hevc_rkmpp 的硬件编解码格式。

image.png

ffmpeg-rockchip 封装了如下格式:

解码器

 V..... av1_rkmpp            Rockchip MPP (Media Process Platform) AV1 decoder (codec av1)
 V..... h263_rkmpp           Rockchip MPP (Media Process Platform) H263 decoder (codec h263)
 V..... h264_rkmpp           Rockchip MPP (Media Process Platform) H264 decoder (codec h264)
 V..... hevc_rkmpp           Rockchip MPP (Media Process Platform) HEVC decoder (codec hevc)
 V..... mpeg1_rkmpp          Rockchip MPP (Media Process Platform) MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_rkmpp          Rockchip MPP (Media Process Platform) MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_rkmpp          Rockchip MPP (Media Process Platform) MPEG4 decoder (codec mpeg4)
 V..... vp8_rkmpp            Rockchip MPP (Media Process Platform) VP8 decoder (codec vp8)
 V..... vp9_rkmpp            Rockchip MPP (Media Process Platform) VP9 decoder (codec vp9)

编码器

 V..... h264_rkmpp           Rockchip MPP (Media Process Platform) H264 encoder (codec h264)
 V..... hevc_rkmpp           Rockchip MPP (Media Process Platform) HEVC encoder (codec hevc)
 V..... mjpeg_rkmpp          Rockchip MPP (Media Process Platform) MJPEG encoder (codec mjpeg)

过滤器

 ... overlay_rkrga     VV->V      Rockchip RGA (2D Raster Graphic Acceleration) video compositor
 ... scale_rkrga       V->V       Rockchip RGA (2D Raster Graphic Acceleration) video resizer and format converter
 ... vpp_rkrga         V->V       Rockchip RGA (2D Raster Graphic Acceleration) video post-process (scale/crop/transpose)

编译项目

一共要编译 3 个项目,因为 ffmpeg-rockchip 依赖于 MPP 和 RGA,先编译 MPP 和 RGA,最后编译 ffmpeg-rockchip,具体如下:

# 在ARM/ARM64主机上进行本地编译

# 编译 MPP
mkdir -p ~/dev && cd ~/dev
git clone -b jellyfin-mpp --depth=1 https://github.com/nyanmisaka/mpp.git rkmpp
pushd rkmpp
mkdir rkmpp_build
pushd rkmpp_build
cmake \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_BUILD_TYPE=Release \
    -DBUILD_SHARED_LIBS=ON \
    -DBUILD_TEST=OFF \
    ..
make -j $(nproc)
make install


# 编译 RGA
sudo apt install meson ninja-build
mkdir -p ~/dev && cd ~/dev
git clone -b jellyfin-rga --depth=1 https://github.com/nyanmisaka/rk-mirrors.git rkrga
meson setup rkrga rkrga_build \
    --prefix=/usr \
    --libdir=lib \
    --buildtype=release \
    --default-library=shared \
    -Dcpp_args=-fpermissive \
    -Dlibdrm=false \
    -Dlibrga_demo=false
meson configure rkrga_build
ninja -C rkrga_build install


# 构建FFmpeg(可自定义配置及安装路径)
mkdir -p ~/dev && cd ~/dev
git clone --depth=1 https://github.com/nyanmisaka/ffmpeg-rockchip.git ffmpeg
cd ffmpeg
./configure --prefix=/usr --enable-gpl --enable-version3 --enable-libdrm --enable-rkmpp --enable-rkrga
make -j $(nproc)

# 将FFmpeg安装到指定前缀路径
make install

注:如果看完上面教程还是不会编译项目的小伙伴,可以在评论区回复,我可以提供已经编译好的 arrch64 架构的库文件和头文件,你直接放到开发板即可使用。

// 下载地址,评论区一直发不出来,放这里
pan.baidu.com
/s/1MRv2SR6Fl-zscWLJSHNlfQ?pwd=54kh

是否有相应的编解码器和 rga

ffmpeg -decoders | grep rkmpp # 查看是否有 rk 的解码器
ffmpeg -encoders | grep rkmpp # 查看是否有 rk 的编码器
ffmpeg -filters | grep rkrga # 查看是否有 rk 的 rga

打印如下:

 V..... av1_rkmpp            Rockchip MPP (Media Process Platform) AV1 decoder (codec av1)
 V..... h263_rkmpp           Rockchip MPP (Media Process Platform) H263 decoder (codec h263)
 V..... h264_rkmpp           Rockchip MPP (Media Process Platform) H264 decoder (codec h264)
 V..... hevc_rkmpp           Rockchip MPP (Media Process Platform) HEVC decoder (codec hevc)
 V..... mpeg1_rkmpp          Rockchip MPP (Media Process Platform) MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_rkmpp          Rockchip MPP (Media Process Platform) MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_rkmpp          Rockchip MPP (Media Process Platform) MPEG4 decoder (codec mpeg4)
 V..... vp8_rkmpp            Rockchip MPP (Media Process Platform) VP8 decoder (codec vp8)
 V..... vp9_rkmpp            Rockchip MPP (Media Process Platform) VP9 decoder (codec vp9)


 V..... h264_rkmpp           Rockchip MPP (Media Process Platform) H264 encoder (codec h264)
 V..... hevc_rkmpp           Rockchip MPP (Media Process Platform) HEVC encoder (codec hevc)
 V..... mjpeg_rkmpp          Rockchip MPP (Media Process Platform) MJPEG encoder (codec mjpeg)


 ... overlay_rkrga     VV->V      Rockchip RGA (2D Raster Graphic Acceleration) video compositor
 ... scale_rkrga       V->V       Rockchip RGA (2D Raster Graphic Acceleration) video resizer and format converter
 ... vpp_rkrga         V->V       Rockchip RGA (2D Raster Graphic Acceleration) video post-process (scale/crop/transpose)

命令

编译好之后,我们就可以执行各种命令来测试我们想要的操作了。

查看编码器的选项

打印编码器的选项,可以让我们知道在使用编码器时应该传入什么选项,例如:

ffmpeg -hide_banner -h encoder=h264_rkmpp

输出如下:

Encoder h264_rkmpp [Rockchip MPP (Media Process Platform) H264 encoder]:
    General capabilities: delay hardware
    Threading capabilities: none
    Supported hardware devices: rkmpp rkmpp drm
    Supported pixel formats: gray yuv420p yuv422p yuv444p nv12 nv21 nv16 nv24 yuyv422 yvyu422 uyvy422 rgb24 bgr24 rgba rgb0 bgra bgr0 argb 0rgb abgr 0bgr drm_prime
h264_rkmpp_encoder AVOptions:
  -rc_mode           <int>        E..V....... Set the encoding rate control mode (from 0 to 5) (default 5)
     VBR             0            E..V.......
     CBR             1            E..V.......
     CQP             2            E..V.......
     AVBR            3            E..V.......
  -qp_init           <int>        E..V....... Set the initial QP value (from -1 to 51) (default -1)
  -qp_max            <int>        E..V....... Set the max QP value for P and B frame (from -1 to 51) (default -1)
  -qp_min            <int>        E..V....... Set the min QP value for P and B frame (from -1 to 51) (default -1)
  -qp_max_i          <int>        E..V....... Set the max QP value for I frame (from -1 to 51) (default -1)
  -qp_min_i          <int>        E..V....... Set the min QP value for I frame (from -1 to 51) (default -1)
  -profile           <int>        E..V....... Set the encoding profile restriction (from -1 to 100) (default high)
     baseline        66           E..V.......
     main            77           E..V.......
     high            100          E..V.......
  -level             <int>        E..V....... Set the encoding level restriction (from -99 to 62) (default 0)
     1               10           E..V.......
     1.1             11           E..V.......
     1.2             12           E..V.......
     1.3             13           E..V.......
     2               20           E..V.......
     2.1             21           E..V.......
     2.2             22           E..V.......
     3               30           E..V.......
     3.1             31           E..V.......
     3.2             32           E..V.......
     4               40           E..V.......
     4.1             41           E..V.......
     4.2             42           E..V.......
     5               50           E..V.......
     5.1             51           E..V.......
     5.2             52           E..V.......
     6               60           E..V.......
     6.1             61           E..V.......
     6.2             62           E..V.......
  -coder             <int>        E..V....... Set the entropy coder type (from 0 to 1) (default cabac) (from 0 to 1) (default cabac)
     cavlc           0            E..V.......
     cabac           1            E..V.......
  -8x8dct            <boolean>    E..V....... Set the high profile 8x8 transform (default true)

编码

下面的命令作用是:使用虚拟设备 lavfi 生成一个测试视频流,使用 hevc_rkmpp 编码器,CQP 速率控制,复用 mp4 容器文件

ffmpeg -f lavfi -i testsrc2=s=1920x1080,format=nv12 -c:v hevc_rkmpp -qp_init 26 -profile:v main -level 4.1 -g:v 100 -vframes 5000 -y /tmp/tmp.mp4

命令参数解释:

  • -f lavfi-f 选项指定输入格式,lavfi 是 FFmpeg 中的一个虚拟设备,用于生成来自 FFmpeg 内部的滤镜或测试源的数据流。
  • -i testsrc2=s=1920x1080,format=nv12-i 选项指定输入文件或输入流。这里使用的是 lavfi 生成的测试源(testsrc2),它会产生一个测试图像作为视频流。生成的视频分辨率为 1920x1080,格式为 nv12。
  • -c:v hevc_rkmpp:指定使用 rockchip 的硬件加速编码器。
  • -qp_init 26:设置视频编码的初始量化参数(QP, Quantization Parameter),数值越小,视频质量越高,但文件越大;数值越大,视频质量降低但文件较小。
  • -profile:v main:设置视频编码的配置文件,这里是根据编码器提供的选项来设置的,通过上面的那个命令就可以知道编码器的参数选项有哪些。
  • -level 4.1:设置编码的级别。
  • -g:v 100:设置 GOP(Group of Pictures)的大小,也就是 I 帧间的间隔。-g:v 100 意味着每 100 帧插入一个 I 帧。
  • -vframes 5000:指定输出视频的帧数。
  • -y:表示在输出文件已存在时自动覆盖输出文件,而不进行提示。

解码

下面的命令作用是:解码 /path/to/any-h264-video.mp4 文件,一共解码 5000 帧

ffmpeg -stream_loop -1 -hwaccel rkmpp -hwaccel_output_format drm_prime -i /path/to/any-h264-video.mp4 -an -sn -vframes 5000 -f null -

命令参数解释:

  • -stream_loop -1:表示视频输入流将会无限循环。-1 表示循环次数为无限,直到手动停止该命令。
  • -hwaccel rkmpp:启用硬件加速
  • -hwaccel_output_format drm_prime:指定硬件加速后的输出格式为 drm_primedrm_prime 是一种 DRM(Direct Rendering Manager)接口的输出格式,通常用于 Linux 系统中进行高效的视频渲染,特别是在使用硬件加速的场景下。
  • -i /path/to/any-h264-video.mp4:指定输入文件路径。
  • -an:禁用音频流,忽略输入视频中的音频部分,不会进行解码或输出音频数据。
  • -sn:禁用字幕流,忽略视频中的字幕部分。
  • -vframes 5000:表示只处理视频中的前 5000 帧。即使视频文件有更长的时长,ffmpeg 也会停止处理,处理完 5000 帧之后退出。
  • -f null:指定输出格式为 null,意味着输出不会保存到文件。null 是一个虚拟格式,用于丢弃所有输出数据。通常用于测试或者性能分析。
  • -:表示 ffmpeg 将输出到标准输出(即终端/控制台)。在这里,由于输出格式是 null,实际上没有任何文件会被生成。

使用 RGA 缩小分辨率

读取 V4L2 摄像头(我的摄像头是 IM415),将 2160P 缩小到 1080P,使用 h264_rkmpp 格式编码器,并推送到 rtsp 服务器:

ffmpeg -init_hw_device rkmpp=hw -filter_hw_device hw -vsync 2 -f v4l2 -i /dev/video11 -vf hwupload,scale_rkrga=w=1920:h=1080:format=nv12 -c:v h264_rkmpp -g:v 100 -qp_init 26 -f rtsp rtsp://192.168.31.253:8554/live/stream

命令参数解释:

  • -init_hw_device rkmpp=hw:初始化一个名为 hw 的硬件加速设备,使用 rkmpp 作为 Rockchip 平台的硬件加速库(MultiMedia Processing Platform)。
  • -filter_hw_device hw:将上一步初始化的硬件设备(hw)用于硬件滤镜。意味着后续的硬件处理将通过这个设备来完成。
  • -vsync 2:控制视频帧同步。设置为 2 表示使用时间戳来调整视频帧的同步,确保输出的帧率正确并避免掉帧或重复帧。
  • -f v4l2:指定输入格式为 v4l2(Video4Linux2)。
  • -i /dev/video11:指定输入设备为 /dev/video11,即从该设备获取视频流。
  • -vf hwupload,scale_rkrga=w=1920:h=1080:format=nv12:将视频帧从 CPU 内存上传到硬件设备的内存中,以便硬件加速处理。使用 rkrga 硬件加速库对视频进行缩放,调整视频的分辨率到 1920x1080,并且设置像素格式为 nv12
  • -c:v h264_rkmpp:指定视频编码器为 h264_rkmpp
  • -g:v 100:设置视频的 GOP(Group of Pictures)大小为 100。GOP 控制的是关键帧(I 帧)之间的间隔,100 帧的 GOP 大小表示每 100 帧中会有一个关键帧。
  • -qp_init 26:设置视频编码器的初始量化参数(QP)为 26。量化参数控制视频的压缩率和质量,数值越低,图像质量越好,但压缩率较低;数值越高,图像质量下降,压缩率增大。26 是一个中等质量的设置。
  • -f rtsp:指定输出格式为 RTSP(实时流协议)。

视频解码再转码

下面这个例子展示了同时使用了编码和解码来加速转码:

ffmpeg -hwaccel rkmpp -hwaccel_output_format drm_prime -afbc rga -i /path/to/any_4k_10bit_hevc.mkv -c:a copy -strict -2 \
-vf scale_rkrga=w=1920:h=1080:format=nv12:afbc=1 -c:v h264_rkmpp -rc_mode VBR -b:v 6M -maxrate 6M \
-bufsize 12M -profile:v high -g:v 120 -y /path/to/1080p_h264_6M.mkv

命令参数解释:

  • -hwaccel rkmpp:启用硬件加速解码。
  • -hwaccel_output_format drm_prime:设置硬件加速后的输出格式为 drm_prime
  • -afbc rga:启用 Rockchip 的 RGA(Raster Graphics Accelerator)硬件加速库。afbc(Arm Framebuffer Compression)是一种压缩格式,旨在减少内存带宽的占用,提高视频处理效率。
  • -i /path/to/any_4k_10bit_hevc.mkv:指定输入文件路径。
  • -c:a copy:音频编解码器设置为 copy,即直接复制输入视频文件中的音频流而不做任何编码或转换。
  • -strict -2:启用实验性功能或允许使用一些非标准的选项。这个选项主要是用于启用 ffmpeg 中一些不符合标准的功能或编解码器选项。
  • -vf scale_rkrga=w=1920:h=1080:format=nv12:afbc=1:使用 Rockchip 的硬件加速 rkrga 进行视频缩放操作。将视频缩放到 1920x1080 分辨率(即 1080p)。设置输出像素格式为 nv12。启用 ARM Framebuffer Compression(AFBC),这有助于减少内存带宽的使用,提升性能。
  • -c:v h264_rkmpp:视频编码器设置为 h264_rkmpp
  • -rc_mode VBR:设置视频的比特率控制模式为 VBR(Variable Bit Rate,可变比特率)。这意味着 ffmpeg 会根据视频内容的复杂度动态调整比特率,从而优化视频质量和压缩效率。
  • -b:v 6M:设置视频的目标比特率为 6 Mbps(兆比特每秒)。这是输出视频的平均比特率,表示视频每秒传输的比特数。
  • -maxrate 6M:设置视频编码时允许的最大比特率为 6 Mbps。这个限制确保视频流的比特率不会超过此值,有助于在带宽有限的情况下控制输出质量。
  • -bufsize 12M:设置码流缓冲区的大小为 12 Mbps。此参数用于控制编码器的码率控制,确保编码器能够平稳地处理比特率波动,避免过度波动导致质量问题。
  • -profile:v high:设置视频编码的 H.264 配置文件为 highhigh 配置文件提供了更好的视频质量和更多的特性,适合于高质量的编码和兼容性要求较高的场景。
  • -g:v 120:设置视频的 GOP(Group of Pictures)大小为 120。这表示视频编码中关键帧(I 帧)之间的间隔为 120 帧。较大的 GOP 会减少视频文件的大小,但可能导致随机访问性能差一些。
  • -y:表示自动覆盖输出文件(如果该文件已经存在)。

结语

在下一篇文章,我将介绍如何使用 ffmpeg 的用户空间库实现同样的功能,因为在日常开发过程中,大部分都是使用开发库进行开发的,这样可以支持更多的功能自定义,以满足不同的业务需求。

如果觉得本文不错,请麻烦帮忙点赞、转发、收藏,谢谢~

猜你喜欢

转载自blog.csdn.net/Leon_Chenl/article/details/144839093
今日推荐