如何在 Intel CPU下面用 FFmpeg 跑 vaapi 编码

众所周知,Intel CPU 集成显卡跑 QSV 做视频编码性能还是很好的,并且节省 CPU 资源,但是搭建环境这个事,对我来说还是挺费劲的,尤其是长时间不碰 QSV 这种环境的。除了用 FFmpeg 跑 QSV 之外,FFmpeg 还支持跑 VAAPI,并且 Intel 的 Xiang Haihao 在 FFmpeg 里面积极地维护了,最近入手了个 NUC 盒子,装了个 CentOS Linux 8,琢磨着跑跑 vaapi 试试看,但是大环境忒费劲了,感觉非常不友好,后来在同事的帮助下,终于用最简单的方式解决了,跑起来了,为了防止大伙以后遇到同样的情况,记录一下分享给大伙。

我拿到的 NUC 设备是这样的。

CPU 信息

(base) [root@localhost lq]# cat /proc/cpuinfo
processor    : 7
vendor_id    : GenuineIntel
cpu family    : 6
model        : 140
model name    : 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
stepping    : 1
microcode    : 0x88
cpu MHz        : 2020.178
cache size    : 8192 KB
physical id    : 0
siblings    : 8
core id        : 3
cpu cores    : 4
apicid        : 7
initial apicid    : 7
fpu        : yes
fpu_exception    : yes
cpuid level    : 27
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l2 invpcid_single cdp_l2 ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb intel_pt avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves split_lock_detect dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid movdiri movdir64b fsrm avx512_vp2intersect md_clear flush_l1d arch_capabilities
vmx flags    : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple pml ept_mode_based_exec tsc_scaling
bugs        : spectre_v1 spectre_v2 spec_store_bypass swapgs
bogomips    : 4838.40
clflush size    : 64
cache_alignment    : 64
address sizes    : 39 bits physical, 48 bits virtual
power management:

PCI 信息


(base) [root@localhost lq]# lspci
00:00.0 Host bridge: Intel Corporation 11th Gen Core Processor Host Bridge/DRAM Registers (rev 01)
00:02.0 VGA compatible controller: Intel Corporation TigerLake-LP GT2 [Iris Xe Graphics] (rev 01)
00:07.0 PCI bridge: Intel Corporation Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #0 (rev 01)
00:07.3 PCI bridge: Intel Corporation Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #3 (rev 01)
00:08.0 System peripheral: Intel Corporation GNA Scoring Accelerator module (rev 01)
00:0d.0 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 USB Controller (rev 01)
00:0d.2 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #0 (rev 01)
00:0d.3 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #1 (rev 01)
00:14.0 USB controller: Intel Corporation Tiger Lake-LP USB 3.2 Gen 2x1 xHCI Host Controller (rev 20)
00:14.2 RAM memory: Intel Corporation Tiger Lake-LP Shared SRAM (rev 20)
00:14.3 Network controller: Intel Corporation Wi-Fi 6 AX201 (rev 20)
00:15.0 Serial bus controller [0c80]: Intel Corporation Tiger Lake-LP Serial IO I2C Controller #0 (rev 20)
00:16.0 Communication controller: Intel Corporation Tiger Lake-LP Management Engine Interface (rev 20)
00:17.0 SATA controller: Intel Corporation Device a0d3 (rev 20)
00:1c.0 PCI bridge: Intel Corporation Device a0bc (rev 20)
00:1c.6 PCI bridge: Intel Corporation Device a0be (rev 20)
00:1f.0 ISA bridge: Intel Corporation Tiger Lake-LP LPC Controller (rev 20)
00:1f.3 Audio device: Intel Corporation Tiger Lake-LP Smart Sound Technology Audio Controller (rev 20)
00:1f.4 SMBus: Intel Corporation Tiger Lake-LP SMBus Controller (rev 20)
00:1f.5 Serial bus controller [0c80]: Intel Corporation Tiger Lake-LP SPI Controller (rev 20)
57:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTS525A PCI Express Card Reader (rev 01)
58:00.0 Ethernet controller: Intel Corporation Ethernet Controller I225-V (rev 03)
(base) [root@localhost lq]#

最开始安装的CentOS Linux 8 的 kernel 版本比较老

4.18.0-147.el8.x86_64

在这期间很明显显卡没有驱动起来,可能是因为设备比较新,所以 VAAPI 需要的设备文件都找不到,根据vaapi的引导找到对应的开源项目源代码工程里面:

https://github.com/intel/media-driverhttps://github.com/intel/libva

这两个是装不上的,因为各种依赖问题,后来咨询了赵委员和 Intel 的技术支持人员,赵委员的建议是升级一下 Kernel。技术支持的大佬的建议是“换 Ubuntu吧”。说心里话,两个选项其实都不是很美好,但是因为我是个人使用,所以我选择升级 CentOS Linux 8的kernel,但是不自己源码编译,我用 Extra Packages for Enterprise Linux 试一下,这个源还是能下载到比较新的 Kernel 的,2022年3月我把 Kernel 升到了

5.16.14-1.el8.elrepo.x86_64

声明:

如果看到这篇内容的时间与2022年3月相差比较大,本人概不负责技术支持,还需要自己琢磨一下。

升级了 kernel 重启后,很明显显卡驱动已经可以正常加载了,因为图像显示都正常了,分辨率可选择的多了好多。lsmod也能看到显卡对应的模块了。


(base) [root@localhost lq]# lsmod|grep i9
i915                 3043328  6
i2c_algo_bit           16384  1 i915
ttm                    81920  1 i915
drm_kms_helper        307200  1 i915
drm                   679936  7 drm_kms_helper,i915,ttm
video                  57344  1 i915
(base) [root@localhost lq]#

但是遇到个问题,源码编译media-driver和libva依然过不去,当然,咱是程序员,改代码可以的,但是目前确实没那个耐性搞这玩意,尤其是有好多事要做的时候,这个会让人烦躁,正在吐槽这破玩意根本不是个产品的时候,伟大的曾经 Intel 搞 QSV 的大佬德哥出现了,说了一句:“可以试试直接用一键安装版本,能节省很多时间”。然后进入到另一个目录里面

https://github.com/Intel-Media-SDK/MediaSDK/releases

这个和intel的那个github似乎不是在一起的,挺奇怪的,最新的版本还是下载源代码,稍微老一点的版本,看到的release信息很巧支持我手里的 NUC 相关的硬件,下载回来根据ReadMe真就轻轻松松一键安装了。

装这个:

MediaStack.tar.gz

然后yum安装vaapi

yum install vaapi

执行vainfo看一下信息,应该就可以了:

(base) [root@localhost lq]# vainfo
libva info: VA-API version 1.14.0
libva info: User environment variable requested driver 'iHD'
libva info: Trying to open /opt/intel/mediasdk/lib64/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_13
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.14 (libva 2.14.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 21.3.4 (46458db8)
vainfo: Supported profile and entrypoints
      VAProfileNone                   :    VAEntrypointVideoProc
      VAProfileNone                   :    VAEntrypointStats
      VAProfileMPEG2Simple            :    VAEntrypointVLD
      VAProfileMPEG2Simple            :    VAEntrypointEncSlice
      VAProfileMPEG2Main              :    VAEntrypointVLD
      VAProfileMPEG2Main              :    VAEntrypointEncSlice
      VAProfileH264Main               :    VAEntrypointVLD
      VAProfileH264Main               :    VAEntrypointEncSlice
      VAProfileH264Main               :    VAEntrypointFEI
      VAProfileH264Main               :    VAEntrypointEncSliceLP
      VAProfileH264High               :    VAEntrypointVLD
      VAProfileH264High               :    VAEntrypointEncSlice
      VAProfileH264High               :    VAEntrypointFEI
      VAProfileH264High               :    VAEntrypointEncSliceLP
      VAProfileVC1Simple              :    VAEntrypointVLD
      VAProfileVC1Main                :    VAEntrypointVLD
      VAProfileVC1Advanced            :    VAEntrypointVLD
      VAProfileJPEGBaseline           :    VAEntrypointVLD
      VAProfileJPEGBaseline           :    VAEntrypointEncPicture
      VAProfileH264ConstrainedBaseline:    VAEntrypointVLD
      VAProfileH264ConstrainedBaseline:    VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline:    VAEntrypointFEI
      VAProfileH264ConstrainedBaseline:    VAEntrypointEncSliceLP
      VAProfileVP8Version0_3          :    VAEntrypointVLD
      VAProfileHEVCMain               :    VAEntrypointVLD
      VAProfileHEVCMain               :    VAEntrypointEncSlice
      VAProfileHEVCMain               :    VAEntrypointFEI
      VAProfileHEVCMain               :    VAEntrypointEncSliceLP
      VAProfileHEVCMain10             :    VAEntrypointVLD
      VAProfileHEVCMain10             :    VAEntrypointEncSlice
      VAProfileHEVCMain10             :    VAEntrypointEncSliceLP
      VAProfileVP9Profile0            :    VAEntrypointVLD
      VAProfileVP9Profile1            :    VAEntrypointVLD
      VAProfileVP9Profile2            :    VAEntrypointVLD
      VAProfileVP9Profile3            :    VAEntrypointVLD
      VAProfileHEVCMain12             :    VAEntrypointVLD
      VAProfileHEVCMain12             :    VAEntrypointEncSlice
      VAProfileHEVCMain422_10         :    VAEntrypointVLD
      VAProfileHEVCMain422_10         :    VAEntrypointEncSlice
      VAProfileHEVCMain422_12         :    VAEntrypointVLD
      VAProfileHEVCMain422_12         :    VAEntrypointEncSlice
      VAProfileHEVCMain444            :    VAEntrypointVLD
      VAProfileHEVCMain444            :    VAEntrypointEncSliceLP
      VAProfileHEVCMain444_10         :    VAEntrypointVLD
      VAProfileHEVCMain444_10         :    VAEntrypointEncSliceLP
      VAProfileHEVCMain444_12         :    VAEntrypointVLD
      VAProfileHEVCSccMain            :    VAEntrypointVLD
      VAProfileHEVCSccMain            :    VAEntrypointEncSliceLP
      VAProfileHEVCSccMain10          :    VAEntrypointVLD
      VAProfileHEVCSccMain10          :    VAEntrypointEncSliceLP
      VAProfileHEVCSccMain444         :    VAEntrypointVLD
      VAProfileHEVCSccMain444         :    VAEntrypointEncSliceLP
      VAProfileAV1Profile0            :    VAEntrypointVLD
      VAProfileHEVCSccMain444_10      :    VAEntrypointVLD
      VAProfileHEVCSccMain444_10      :    VAEntrypointEncSliceLP
(base) [root@localhost lq]#

这才对嘛,这才叫产品。动不动就让用户从CentOS 换到 Ubuntu,相当于从 vim 编辑器切换到 emacs 这样的大动干戈的改动,很恶心啊。

然后接下来就是编译安装 ffmpeg 跑 vaapi 了,性能不错:

(base) [root@localhost lq]# ffmpeg -vaapi_device /dev/dri/renderD128 -f lavfi -i testsrc2=s=1920x1080 -vf 'format=nv12,hwupload' -c:v h264_vaapi -b:v 5M -f flv -y /dev/null
ffmpeg version N-105941-gc3fea6d83b Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 8 (GCC)
  configuration: --extra-cflags=-I/usr/local/include/ --extra-cflags=-I/usr/local/include/va --enable-vaapi
  libavutil      57. 23.100 / 57. 23.100
  libavcodec     59. 23.100 / 59. 23.100
  libavformat    59. 18.101 / 59. 18.101
  libavdevice    59.  5.100 / 59.  5.100
  libavfilter     8. 27.100 /  8. 27.100
  libswscale      6.  5.100 /  6.  5.100
  libswresample   4.  4.100 /  4.  4.100
Input #0, lavfi, from 'testsrc2=s=1920x1080':
  Duration: N/A, start: 0.000000, bitrate: N/A
  Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 25 tbr, 25 tbn
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (h264_vaapi))
Press [q] to stop, [?] for help
Output #0, flv, to '/dev/null':
  Metadata:
    encoder         : Lavf59.18.101
  Stream #0:0: Video: h264 (High) ([7][0][0][0] / 0x0007), vaapi(tv, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 5000 kb/s, 25 fps, 1k tbn
    Metadata:
      encoder         : Lavc59.23.100 h264_vaapi
frame= 3427 fps=227 q=-0.0 size=   83968kB time=00:02:16.88 bitrate=5025.3kbits/s speed=9.08x

更多详细的使用例子,可以在ffmpeg官方的wiki里面找到:

https://trac.ffmpeg.org/wiki/Hardware/VAAPI

来源:公众号 – 流媒体技术
链接:https://mp.weixin.qq.com/s/3e96xjJ6zAXiM6RyPZMHQw

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论