【FFmpeg在Intel GPU上的硬件编解码实现】

用于记录Intel CPU开发qsv硬件解码过程中遇到的一些问题及解决方案

以下文章是在开发过程中参考的比较有意义的文章,供大家学习和参考~~

https://zhuanlan.zhihu.com/p/62246545
##FFMPEG+Intel QSV硬解的环境安装篇##
https://zhuanlan.zhihu.com/p/372361709
##Ubuntu20.04 ffmpeg添加 Intel核显QSV加速支持##
https://blog.csdn.net/weixin_47407737/article/details/128933104
##FFmpeg集成qsv的编译安装##
https://pic.huodongjia.com/ganhuodocs/2018-05-26/1527317476.4.pdf
##FFmpeg在Intel GPU上的硬件加速与优化##
https://blog.csdn.net/kkae8643150/article/details/107472572
##ubuntu18.0.4编译ffmpeg开启qsv硬件编解码##

描述 git仓库链接地址
Driver 依赖库 https://github.com/intel/libva
Driver 测试工具 https://github.com/intel/libva-utils
Driver 依赖库 https://github.com/intel/gmmlib
Driver https://github.com/intel/media-driver/tree/intel-media-21.3
Driver https://github.com/intel/intel-vaapi-driver
MediaSDK https://github.com/Intel-Media-SDK/MediaSDK/wiki/Build-FFmpeg-QSV
MediaSDK https://github.com/Intel-Media-SDK/MediaSDK/wiki/Build-Media-SDK-on-Ubuntu
MediaSDK https://github.com/Intel-Media-SDK/MediaSDK/wiki/Intel-media-stack-on-Ubuntu
MediaSDK https://github.com/Intel-Media-SDK/MediaSDK/releases
FFMPEG https://github.com/FFmpeg/FFmpeg
RUN TIME https://github.com/oneapi-src/oneVPL-intel-gpu

intel-media-driver+intel-media-sdk = iHD(i915 driver)
vaapi-driver = i965 driver

【FFmpeg在Intel GPU上的硬件编解码实现】_第1张图片

准备工作

安装依赖

2222 sudo apt-get install git cmake pkg-config meson libdrm-dev automake libtool

gcc/g++ cmake版本要求

编译过程中对gcc和cmake有版本的要求,需要先升级gcc和cmake到一定的版本之上,gcc/g++的版本要求大于等于4.9,cmake的版本要求大于等于3.6.

注意点

另外在开展编译工作开始之前,需要注意libva/media-driver以及Media-SDK各个版本的对应关系,否则会出现编译报错,为避免入坑,需要先查看以下链接中各版本对应关系,通过查看官方Intel-Media-SDK的release文档(链接:Intel Media SDK来知道分别是用libva和media-driver的哪个tag编译的。

测试环境:

一共测试了四台x86的机器

CPU型号 CPU架构
Intel J1900 Bay Trail Gen7
Intel i5-6442EQ Skylake Gen9
Intel i7-7600U Kaby Lake Gen9.5
Intel i7-8700 Coffee Lake Gen9.5

其中Intel i7-8700机器既有独显又有集显,为避免在调试过程中需要显式指定-qsv_device或-hwaccel_device,可在开机后进入BIOS,设定默认使用集显或使用独显或自动选择,系统默认设定的是AUTO。

#用来查看当前显示的配置
2256 lspci | grep -i vga
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Oland [Radeon HD 8570 / R7 240/340 OEM] (rev 87)
2257 cat /sys/kernel/debug/dri/128/name
2258 cat /sys/kernel/debug/dri/129/name

其中,/dev/dri/renderD128 对应集显,/dev/dri/renderD129对应独显。

ubuntu16.04升级gcc/g++

   69  add-apt-repository ppa:ubuntu-toolchain-r/test
   70  apt-get update
   88  apt-get install gcc-8 g++-8
   91  gcc -v
   95  update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 20
   96  update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 20
   97  update-alternatives --config gcc
   98  update-alternatives --config g++

ubuntu16.04升级cmake

https://askubuntu.com/questions/829310/how-to-upgrade-cmake-in-ubuntu

 2203  chmod +x cmake-3.25.2-linux-x86_64.sh 
 2204  ./cmake-3.25.2-linux-x86_64.sh 
 2212  cd /home/ning/Downloads/cmake-3.25.2-linux-x86_64/bin/
 2213  ./cmake --version
 2214  ln -sf /home/ning/Downloads/cmake-3.25.2-linux-x86_64/bin/cmake /usr/local/bin/cmake
 2215  cd /usr/local/bin/
 2216  ./cmake --version

安装libva

 2224  git clone https://github.com/intel/libva.git
 2226  cd libva/
 2227  git checkout v2.13-branch
 2228  ./autogen.sh --prefix=/opt/intel/mediasdk/
 2229  make -j8
 2231  make install

libva安装完成后需要配置环境变量export LIBVA_DRIVER_NAME=iHD

安装va-utils

 2247  git clone https://github.com/intel/libva-utils.git
 2248  git checkout v2.13-branch
 2249  cd libva-utils/
 2250  git checkout v2.13-branch
 2251  ./autogen.sh --prefix=/opt/intel/mediasdk
 2252  make -j8
 2253  make install

安装gmmlib

 2234  tar xf gmmlib-intel-gmmlib-21.3.1.tar.gz 
 2235  cd gmmlib-intel-gmmlib-21.3.1
       或者
       git clone https://github.com/intel/gmmlib.git
       cd gmmlib
       git reset --hard 1c975c52634172376b49f2983d4d0fd7049302f9
 2236  mkdir build
 2237  cd build/
 2238  cmake -DCMAKE_BUILD_TYPE=Release -DARCH=64 -DCMAKE_INSTALL_PREFIX=/opt/intel/mediasdk ..
 2239  make -j8
 2240  make install

安装media-driver

 2242  git clone https://github.com/intel/media-driver.git
 2243  cd media-driver/
 2244  git checkout intel-media-21.3
 2245  git br
 2246  cd ../
 2265  cd media-driver/
 2266  git br
 2267  cd ../
 2268  mkdir build_media
 2269  cd build_media/
 2270  cmake -DCMAKE_INSTALL_PREFIX=/opt/intel/mediasdk/ ../media-driver/
 2271  cd ../media-driver/
 2272  git br
 2273  git log
 2274  git reset --hard 46458db8104e70602e99bd233119d022bc54a39a
 2275  cd ../
 2276  cd build_media/
 2277  rm -rf ./*
 2278  cmake -DCMAKE_INSTALL_PREFIX=/opt/intel/mediasdk/ ../media-driver/
 2279  make -j8
 2280  make install

driver安装完成后,需要配置环境变量export LIBVA_DRIVERS_PATH=/opt/intel/mediasdk/lib/dri/;
以上环境变量配置完成后,可使用va-utils编译生成的功能vainfo验证驱动安装是否成功,首先可以先读取环境变量的值,判断环境变量是否设置正确;

 2307  echo $LIBVA_DRIVERS_PATH
 2308  echo $LIBVA_DRIVER_NAME
 2309  #这里,media-driver对应的LIBVA_DRIVERS_NAME=iHD,$LIBVA_DRIVERS_PATH=iHD_drv_video.so

使用vainfo进行测试

#由于测试机器i7-8700同时存在集显和独显,所以这里需要指定--display drm --device,如果只有集显,执行运行vainfo即可
2278 ./vainfo
或者
2279 ./vainfo --display drm --device /dev/dri/renderD128
2279 root@ning-QiTianM620-N000:/opt/intel/mediasdk/bin# ./vainfo 

2279 error: XDG_RUNTIME_DIR not set in the environment.
2279 libva info: VA-API version 1.13.0
2279 libva info: User environment variable requested driver 'i965'
2279 libva info: Trying to open /opt/intel/mediasdk/lib/dri/i965_drv_video.so
2279 libva info: Found init function __vaDriverInit_1_13
2279 libva info: va_openDriver() returns 0
2279 vainfo: VA-API version: 1.13 (libva 2.13.0)
2279 vainfo: Driver version: Intel i965 driver for Intel(R) Coffee Lake - 2.4.1
2279 vainfo: Supported profile and entrypoints
2279       VAProfileMPEG2Simple            :	VAEntrypointVLD
2279       VAProfileMPEG2Simple            :	VAEntrypointEncSlice
2279       VAProfileMPEG2Main              :	VAEntrypointVLD
2279       VAProfileMPEG2Main              :	VAEntrypointEncSlice
2279       VAProfileH264ConstrainedBaseline:	VAEntrypointVLD
2279       VAProfileH264ConstrainedBaseline:	VAEntrypointEncSlice
2279       VAProfileH264ConstrainedBaseline:	VAEntrypointEncSliceLP
2279       VAProfileH264Main               :	VAEntrypointVLD
2279       VAProfileH264Main               :	VAEntrypointEncSlice
2279       VAProfileH264Main               :	VAEntrypointEncSliceLP
2279       VAProfileH264High               :	VAEntrypointVLD
2279       VAProfileH264High               :	VAEntrypointEncSlice
2279       VAProfileH264High               :	VAEntrypointEncSliceLP
2279       VAProfileH264MultiviewHigh      :	VAEntrypointVLD
2279       VAProfileH264MultiviewHigh      :	VAEntrypointEncSlice
2279       VAProfileH264StereoHigh         :	VAEntrypointVLD
2279       VAProfileH264StereoHigh         :	VAEntrypointEncSlice
2279       VAProfileVC1Simple              :	VAEntrypointVLD
2279       VAProfileVC1Main                :	VAEntrypointVLD
2279       VAProfileVC1Advanced            :	VAEntrypointVLD
2279       VAProfileNone                   :	VAEntrypointVideoProc
2279       VAProfileJPEGBaseline           :	VAEntrypointVLD
2279       VAProfileJPEGBaseline           :	VAEntrypointEncPicture
2279       VAProfileVP8Version0_3          :	VAEntrypointVLD
2279       VAProfileVP8Version0_3          :	VAEntrypointEncSlice
2279       VAProfileHEVCMain               :	VAEntrypointVLD
2279       VAProfileHEVCMain               :	VAEntrypointEncSlice
2279       VAProfileHEVCMain10             :	VAEntrypointVLD
2279       VAProfileHEVCMain10             :	VAEntrypointEncSlice
2279       VAProfileVP9Profile0            :	VAEntrypointVLD
2279       VAProfileVP9Profile0            :	VAEntrypointEncSlice
2279       VAProfileVP9Profile2            :	VAEntrypointVLD
2279 root@ning-QiTianM620-N000:/opt/intel/mediasdk/bin# 

安装Intel-Media-SDK

 2315  git clone https://github.com/Intel-Media-SDK/MediaSDK.git
 2316  cd MediaSDK/
 2317  git checkout intel-mediasdk-21.3
 2318  mkdir build
 2319  cd build
 2320  cmake -DCMAKE_INSTALL_PREFIX=/opt/intel/mediasdk ..
 2321  make -j8
 2322  make install

在这里需要注意的是,编译SDK如果出现找不到库或头文件的情况,需要export设置环境变量

export PKG_CONFIG_PATH=/opt/intel/mediasdk/lib/pkgconfig

在该目录下,存放了很多.pc文件,指定了库以及头文件的引用路径。

安装ffmpeg

通过apt-get安装的ffmpeg本身不支持QSV选项,因此必须自己去重新编译。
使用Intel-Media-SDK也就是Driver使用iHD_dri_video.so,配置ffmpeg时,需要加入–enable-libmfx选项;
使用vaapi也就是Driver使用i965_dri_video.so,配置ffmpeg时,需要加入–enable-vaapi选项;
另外,编译如果需要生成ffplay用来播放视频的话,配置ffmpeg也需要加入–enable-ffplay选项。

 2327  git clone https://github.com/ffmpeg/ffmpeg.git
 2330  cd ffmpeg/
 2331  git br
 2332  git checkout release/3.4
 2333  ./configure --arch=x86_64 --prefix=/opt/intel/mediasdk/ --disable-yasm --enable-vaapi --enable-libmfx --enable-debug=3 --disable-stripping --extra-cflags=-gstabs+ --disable-optimizations
 2334  make -j8
 2335  make install

安装vaapi-driver

关于在Intel J1900机器上不能使用iHD Driver的原因如图上描述:
【FFmpeg在Intel GPU上的硬件编解码实现】_第2张图片
所以,在J1900机器上,必须使用vaapi driver来实现硬件解码功能。

  560  git clone https://github.com/intel/intel-vaapi-driver.git
  561  cd intel-vaapi-driver/
  562  git checkout v2.4-branch
  563  git branch
  564  ls -ll
  565  ./autogen.sh --prefix=/opt/intel/mediasdk/
  566  make -j4
  567  make install
  568  #这里,media-driver对应的LIBVA_DRIVERS_NAME=i965,$LIBVA_DRIVERS_PATH=i965_drv_video.so

使用ffmpeg测试硬件解码

#1080P 同时存在集显和独显的情况下,使用-hwaccel_device指定集显设备
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device /dev/dri/renderD128 -i RISC_e.mp4  -f null -
#4K视频
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i 3840x2160.mp4 -vf 'hwdownload,format=nv12' -f null -
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i 3840x2160.mp4 -f null -
#1080P
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i RISC_e.mp4 -vf 'hwdownload,format=nv12' -f null -
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i RISC_e.mp4 -vf -f null -

注意以上指令中的差异在于过滤器的使用 -vf ‘hwdownload,format=nv12’
使用’hwdownload’可以将硬件解码输出的gpu frame下载到cpu memory,关键字是下载
使用’format=NV12’可以选择NV12格式的数据作为hwdownload的输出
-f null - 是将硬件解码输出的gpu frame输出到cpu memory,不进行保存,4K视频不加 -vf ‘hwdownload,format=nv12’ 报错怀疑是cpu memory内存不够导致,使用hwdownload就不会报错

安装ffplay

ffplay编译主要依赖sdl2环境(针对ffmpeg 3.x版本),未安装sdl2的情况下,不会自动生成关于ffplay的编译选项

sudo apt-get install libsdl2-2.0
# libSDL2-2.0.so.0位于/usr/lib/x86_64-linux-gnu/目录下
#ffmpeg configure时加上 --enable-ffplay选项即可
2333  ./configure --arch=x86_64 --prefix=/opt/intel/mediasdk/ --disable-yasm --enable-vaapi --enable-libmfx --enable-debug=3 --disable-stripping --extra-cflags=-gstabs+ --disable-optimizations --enable-ffplay

另外,ffplay依赖VPL运行环境,用户可设定以下环境变量用于指定VPL RuntimeMSDK Runtime(default)

export INTEL_MEDIA_RUNTIME=ONEVPL #for VPL Runtime:libmfx-gen.so.1.2
或者
export INTEL_MEDIA_RUNTIME=MSDK #for Media SDK Runtime:libmfxhw64.so.1

安装libmfx-gen.so.1.2,如果不安装 ffplay播放视频会报错

https://bugs.launchpad.net/ubuntu/+source/ffmpeg/+bug/1970637

 2085  git clone https://github.com/oneapi-src/oneVPL-intel-gpu.git
 2088  cd oneVPL-intel-gpu/
 2089  git br
 2090  git checkout intel-onevpl-21.2
 2091  git br
 2092  mkdir build
 2093  cd build
 2094  cmake ..
 2095  make -j8
 2096  make install
 2097  cd /opt/intel/mediasdk/lib/
 2098  ls (libmfx-gen*.so)
 2101  export INTEL_MEDIA_RUNTIME=ONEVPL(这步一定要加上)
 2099  cd ../bin/
 2102  ./ffplay -vcodec h264_qsv -i RISC_e.mp4 
 2103  ./ffplay -vcodec h264_qsv -i /home/ning/Downloads/3840x2160.mp4 

VAAPI驱动(硬件解码+硬件编码+保存yuv文件)

这里需要说明一下,为什么要保存yuv文件?
原因在于使用vaapi驱动,ffplay播放视频无法通过-vcodec指定解码器,所以无法实现使用ffplay直接硬件解码播放视频,达到降低设备cpu占用率的需求。所以,保存yuv文件,也就是说先完成硬件解码输出,然后再使用ffplay进行播放,可达到降低设备cpu占用的需求。

#硬件解码+硬件编码
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i RISC_e.mp4 -c:v h264_vaapi /home/ning/Downloads/RISC_vaapi.mp4
#硬件解码+输出yuv文件
#YUV420P的片源通常會硬體加速解碼會輸出NV12格式
./ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i RISC_e.mp4 -vf 'hwdownload,format=nv12' -pix_fmt yuv420p /home/ning/Downloads/risc_e.yuv
#ffplay播放yuv文件
./ffplay -pix_fmt yuv420p -f rawvideo -video_size 1920x1080 /home/ning/Downloads/risc_e.yuv
#这里注意需要填相应的分辨率
#16M MP4文件大小,转换为yuv后为8.5G

iHD驱动(硬件解码+硬件编码+保存yuv文件)

#硬件解码+硬件编码
./ffmpeg -hwaccel qsv -c:v h264_qsv -i RISC_e.mp4 -c:v h264_qsv /home/ning/Downloads/RISC_qsv.mp4
#硬件解码+输出yuv文件
#YUV420P的片源通常會硬體加速解碼會輸出NV12格式
./ffmpeg -hwaccel qsv -c:v h264_qsv -i RISC_e.mp4 -vf 'hwdownload,format=nv12' -pix_fmt yuv420p /home/ning/Downloads/risc_e_qsv.yuv
#ffplay播放MP4,使用硬件解码
./ffplay -vcodec h264_qsv -i /home/ning/Downloads/RISC_vaapi.mp4

使用ffmpeg截取一段长度视频

-codec copy表示使用和输入视频相同的解码器,并且不重新进行编码

./ffmpeg -i 3840x2160.mp4 -vcodec copy -acodec copy -ss 00:00:00 -to 00:00:10 4k_test.mp4 -y

这里截取一段MP4视频的原因,是由于4K分辨率的视频,从MP4格式硬件解码为yuv格式后数据量太大,所以需要截取其中一小段用于测试。

你可能感兴趣的:(文件系统移植,ffmpeg,音视频)