LoginSignup
8
5

More than 1 year has passed since last update.

さくらのアドベントカレンダー2022 20日目の記事です。

どうも、さくらインターネット やまけんです。

2日目で さくらのクラウドでUniFi Network Applicationを動かす

こちらの紹介をしましたが、今度はGPUでのハードウェアエンコードのお話です。
GPUでのハードウェアエンコードの話は、2018年にnvidiaのNVENCを使うお話を。

2021年にはハードウェアエンコードでの品質比較の話をさせていただきました。

今回は、今年発売されたIntelのGPU Intel Arcを使ったハードウェアエンコード環境作成のお話をさせていただきます。

はじめに

intelは今年に入り20数年ぶりに単体GPUカード市場に再参入しました。
とはいえ、再参入と言っても、過去に出したGPUカードはIntel740という製品で、このカードは当時スペック詐欺と言われ全く売れず、その後のi810チップセットの内蔵グラフィックや、CPU内蔵グラフィックという形で単体GPUではなく、お世辞にも性能が高いわけでもなく、表示ができる程度のものがずっと続いていました。
ちなみに黒歴史化してるらしく、アスキーの記事にされています。

一応当時を知る身から一言だけ言わせてもらうと、intelはDirect Memory Executionという、当時としては画期的かつ今のグラボにも応用されている先進機能を搭載したあたりは評価されるべきだし、本当はRDRAMが廉価で提供できれば、この機能を最大限活用できただろうが、そうはならなかったと言うところ。

そんなintelは細々とCPUにiGPUというのを長く続けており、ハードウェアデコーダやエンコーダを搭載し、ゲームをするには心細いが、最低限の機能は兼ね備えています。

昨年の記事でも変換速度はNVEncには敵わないものの、品質についてはNVEncよりも高いものとなっており、バランスのとれたものでありました。

ここに来て、新たに発売されたIntel Arcシリーズは新たにAV1のハードウェアエンコーダをGPUとして初搭載したり(現在はNVIDIA Ada Lovelace世代でも搭載しました)と少し先進的な取り組みをしています。

そんな新しいGPUのハードウェアエンコーダ性能を検証しようと言う内容です。

必須環境

Intel Arcが載っている Ubuntu 22.04 x86_64 マシン
→DC向けのFlexでも同様の状況になります。

今回はArc A380を使ったASRockの Intel Arc A380 Challenger ITX 6GB OC を使いました

準備

ドライバのインストール
Installation Guidesにしたがってドライバを入れます。

GPUの認識確認

# GPU認識の確認
sudo lspci -v |grep -A8 VGA

下記の結果のようになります。

ubuntu@intel-arc:~$ lspci -v |grep -A8 VGA
86:00.0 VGA compatible controller: Intel Corporation Device 56a5 (rev 05) (prog-if 00 [VGA controller])
	Subsystem: ASRock Incorporation Device 6004
	Flags: bus master, fast devsel, latency 0, IRQ 76, NUMA node 1, IOMMU group 76
	Memory at fa000000 (64-bit, non-prefetchable) [size=16M]
	Memory at 39ffe0000000 (64-bit, prefetchable) [size=256M]
	Expansion ROM at fb000000 [disabled] [size=2M]
	Capabilities: [40] Vendor Specific Information: Len=0c <?>
	Capabilities: [70] Express Endpoint, MSI 00
	Capabilities: [ac] MSI: Enable+ Count=1/1 Maskable+ 64bit+
ubuntu@intel-arc:~$ 

きちんと認識しているのが確認できました。

intelグラフィック リポジトリの追加

こちらも手順通りそのまま追加します。

sudo apt-get install -y gpg-agent wget && \
wget -qO - https://repositories.intel.com/graphics/intel-graphics.key |
  sudo gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg && \
echo 'deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/graphics/ubuntu jammy arc' | \
  sudo tee  /etc/apt/sources.list.d/intel.gpu.jammy.list

OEMカーネルのインストール

現在 Linux 5.17 のみサポートしているようで、専用の linux-image-5.17.0-1019-oem をインストールします。

sudo apt-get update && sudo apt-get install -y linux-image-5.17.0-1019-oem

インストールが終わったら、一度リブートさせ、インストールしたカーネルで起動させます。

sudo reboot

立ち上がってきたら、カーネルバージョンを確認します。

uname -r

以下のような結果になるはずです。

ubuntu@intel-arc:~$ uname -r
5.17.0-1019-oem
ubuntu@intel-arc:~$ 

dkmsとカーネルヘッダをインストールします。

sudo apt-get update && sudo apt-get -y install \
    gawk \
    dkms \
    linux-headers-$(uname -r) \
    libc6-dev udev

ドライバのインストール

sudo apt-get install -y intel-platform-vsec-dkms intel-platform-cse-dkms && \
sudo apt-get install -y intel-i915-dkms intel-fw-gpu

ライブラリのインストール

下記パッケージインストールでライブラリがインストールされる。

sudo apt-get install -y \
  intel-opencl-icd intel-level-zero-gpu level-zero \
  intel-media-va-driver-non-free libmfx-dev libmfx1 libmfxgen1 libvpl2 \
  libegl-mesa0 libegl1-mesa libegl1-mesa-dev libgbm1 libgl1-mesa-dev libgl1-mesa-dri libva-dev \
  libglapi-mesa libgles2-mesa-dev libglx-mesa0 libigdgmm12 libxatracker2 mesa-va-drivers \
  mesa-vdpau-drivers mesa-vulkan-drivers va-driver-all

再度再起動をする。

sudo reboot

再起動すると、ドライバがロードされます。

しかし、このままでは、エンコードに使う /dev/dri/renderD128 のパーミッションの問題で、一般ユーザーでffmpegを使う場合、HWエンコードができなくなります。

ubuntu@intel-arc:~$ ls -l /dev/dri/render*
crw-rw---- 1 root render 226, 128 Dec 19 18:07 /dev/dri/renderD128
ubuntu@intel-arc:~$

そこで、一般ユーザーでもアクセス可能にするための設定ファイルを作成します。

sudo vi /etc/udev/rules.d/99-render.rules
99-render.rules
KERNEL=="render*" GROUP="render", MODE="0666"

設定反映のためにOS再起動後、デバイスのパーミッションを確認します。

ubuntu@intel-arc:~$ ls -l /dev/dri/render*
crw-rw-rw- 1 root render 226, 128 Dec 19 18:16 /dev/dri/renderD128
ubuntu@intel-arc:~$ 

ドライバインストールの確認

hwinfoをインストールし、ドライバインストールができているか確認します。

sudo apt-get install hwinfo
sudo hwinfo --display

下記のように Driver Status: i915 is active なっていればOKです

ubuntu@intel-arc:~$ sudo hwinfo --display
141: PCI 8600.0: 0300 VGA compatible controller (VGA)
  [Created at pci.386]
  Unique ID: EWSR.28Q6RjwKYw7
  Parent ID: emIm.mr2N3fBJq5F
  SysFS ID: /devices/pci0000:80/0000:80:02.0/0000:84:00.0/0000:85:01.0/0000:86:00.0
  SysFS BusID: 0000:86:00.0
  Hardware Class: graphics card
  Model: "Intel VGA compatible controller"
  Vendor: pci 0x8086 "Intel Corporation"
  Device: pci 0x56a5 
  SubVendor: pci 0x1849 "ASRock Incorporation"
  SubDevice: pci 0x6004 
  Revision: 0x05
  Driver: "i915"
  Driver Modules: "i915"
  Memory Range: 0xfa000000-0xfaffffff (rw,non-prefetchable)
  Memory Range: 0x39ffe0000000-0x39ffefffffff (ro,non-prefetchable)
  Memory Range: 0xfb000000-0xfb1fffff (ro,non-prefetchable,disabled)
  IRQ: 76 (155 events)
  Module Alias: "pci:v00008086d000056A5sv00001849sd00006004bc03sc00i00"
  Driver Info #0:
    Driver Status: i915 is active
    Driver Activation Cmd: "modprobe i915"
  Config Status: cfg=new, avail=yes, need=no, active=unknown
  Attached to: #111 (PCI bridge)

Primary display adapter: #126
ubuntu@intel-arc:~$ 
ubuntu@intel-arc:~$

メディアドライバの確認

export DISPLAY=:0.0

sudo apt-get install vainfo
export LIBVA_DRIVER_NAME=iHD
vainfo

下記のように vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.5.1 (a12fef1) 表示されればOKです。

ubuntu@intel-arc:~$ sudo vainfo
Trying display: wayland
Trying display: x11
error: can't connect to X server!
Trying display: drm
libva info: VA-API version 1.16.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_16
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.16 (libva 2.16.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.6.4 (aca8ee0)
vainfo: Supported profile and entrypoints
      VAProfileNone                   :	VAEntrypointVideoProc
      VAProfileNone                   :	VAEntrypointStats
      VAProfileMPEG2Simple            :	VAEntrypointVLD
      VAProfileMPEG2Main              :	VAEntrypointVLD
      VAProfileH264Main               :	VAEntrypointVLD
      VAProfileH264Main               :	VAEntrypointEncSliceLP
      VAProfileH264High               :	VAEntrypointVLD
      VAProfileH264High               :	VAEntrypointEncSliceLP
      VAProfileJPEGBaseline           :	VAEntrypointVLD
      VAProfileJPEGBaseline           :	VAEntrypointEncPicture
      VAProfileH264ConstrainedBaseline:	VAEntrypointVLD
      VAProfileH264ConstrainedBaseline:	VAEntrypointEncSliceLP
      VAProfileHEVCMain               :	VAEntrypointVLD
      VAProfileHEVCMain               :	VAEntrypointEncSliceLP
      VAProfileHEVCMain10             :	VAEntrypointVLD
      VAProfileHEVCMain10             :	VAEntrypointEncSliceLP
      VAProfileVP9Profile0            :	VAEntrypointVLD
      VAProfileVP9Profile0            :	VAEntrypointEncSliceLP
      VAProfileVP9Profile1            :	VAEntrypointVLD
      VAProfileVP9Profile1            :	VAEntrypointEncSliceLP
      VAProfileVP9Profile2            :	VAEntrypointVLD
      VAProfileVP9Profile2            :	VAEntrypointEncSliceLP
      VAProfileVP9Profile3            :	VAEntrypointVLD
      VAProfileVP9Profile3            :	VAEntrypointEncSliceLP
      VAProfileHEVCMain12             :	VAEntrypointVLD
      VAProfileHEVCMain422_10         :	VAEntrypointVLD
      VAProfileHEVCMain422_12         :	VAEntrypointVLD
      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
      VAProfileAV1Profile0            :	VAEntrypointEncSliceLP
      VAProfileHEVCSccMain444_10      :	VAEntrypointVLD
      VAProfileHEVCSccMain444_10      :	VAEntrypointEncSliceLP
ubuntu@intel-arc:~$ 

oneAPI Toolkitsのインストール

IntelGPUではIntel Media SDKを使っていましたが、新しいGPUからoneAPIを使うようになりました。
oneAPIの中のoneVPLというのが該当のものですが、MediaSDKを置き換える存在になっています。

今回は下記のAPTにてインストールします。

wget -qO - https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB |
  sudo gpg --dearmor --output /usr/share/keyrings/oneapi-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list

sudo apt-get update && sudo apt-get -y install intel-basekit libvpl-dev

oneVPL GPUのインストール

oneVPL自体はパッケージでのインストールが完了していますが、GPU Runtimeは別途インストールが必要です。

インストール

sudo apt-get -y install git build-essential pkg-config cmake automake autoconf libva-dev libdrm-dev

git clone https://github.com/oneapi-src/oneVPL-intel-gpu onevpl-gpu
cd onevpl-gpu

mkdir build && cd build
cmake ..
make
sudo make install

上記にてoneVPL GPUランタイムがインストールされます。

FFmpegのインストール

Compile FFmpeg for Ubuntu, Debian, or Mint

こちらをベースにパッケージベースで入れていきます。

intel GPUでのHWエンコードについては

に記載があるのですが、現状

Build FFmpeg with oneVPL
coming soon

とのことなので、このビルド方法が正しいかはわかりません。

またffmpegの取得リポジトリですが、intelにて管理しているリポジトリから取得しています。
合わせて、intel提供の最新パッチを当てるようになっています。

個人的にhapエンコードを使いたいので libsnappy-dev をインストールの上
--enable-libsnappy を追記しています。

またTLS対応のために libssl-dev をインストールの上
--enable-openssl を追記しています。

#FFmpegコンパイルに必要なものを導入
sudo apt-get update -qq && sudo apt-get -y install \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libgnutls28-dev \
  libmp3lame-dev \
  libssl-dev \
  libtool \
  libva-dev \
  libvorbis-dev \
  libsnappy-dev \
  meson \
  ninja-build \
  pkg-config \
  texinfo \
  wget \
  yasm \
  zlib1g-dev

#作業ディレクトリ作成
mkdir -p ~/ffmpeg_sources ~/bin

#NASM インストール
sudo apt-get install nasm

# libx264 インストール
sudo apt-get install libx264-dev

# libx265 インストール
sudo apt-get install libx265-dev libnuma-dev

# libvpx インストール
sudo apt-get install libvpx-dev

# libfdk-aac インストール
sudo apt-get install libfdk-aac-dev

# libopus インストール
sudo apt-get install libopus-dev

# libaom インストール
sudo apt-get -y install libaom-dev

# libvmaf インストール
cd ~/ffmpeg_sources && \
wget https://github.com/Netflix/vmaf/archive/v2.1.1.tar.gz && \
tar xvf v2.1.1.tar.gz && mkdir -p vmaf-2.1.1/libvmaf/build && \
cd vmaf-2.1.1/libvmaf/build && \
meson setup -Denable_tests=false -Denable_docs=false --buildtype=release --default-library=static .. --prefix "$HOME/ffmpeg_build" --bindir="$HOME/ffmpeg_build/bin" --libdir="$HOME/ffmpeg_build/lib" && \
ninja && \
ninja install

# FFmpeg インストール
cd ~/ffmpeg_sources && \
git -C ffmpeg pull 2> /dev/null || git clone --depth 1 https://github.com/intel-media-ci/cartwheel-ffmpeg --recursive && \
cd cartwheel-ffmpeg/ffmpeg && \
for i in ../patches/*.patch; do patch -p1 < $i; done && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --prefix="$HOME/ffmpeg_build" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --extra-libs="-lpthread -lm" \
  --ld="g++" \
  --bindir="$HOME/bin" \
  --enable-vaapi \
  --enable-libvpl \
  --enable-openssl \
  --enable-gpl \
  --enable-libaom \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libvorbis \
  --enable-libsnappy \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-libvmaf \
  --enable-static \
  --enable-nonfree && \
PATH="$HOME/bin:$PATH" make && \
make install && \
hash -r

パスを通したり
source ~/.profile
echo "MANPATH_MAP $HOME/bin $HOME/ffmpeg_build/share/man" >> ~/.manpath

動作確認

実際にインストールが成功したか、下記のコマンドでQSVエンコード関連オプションが使えるか確認します。

for i in buildconf hwaccels decoders filters encoders; do echo $i:; ffmpeg -hide_banner -${i} | egrep -i "qsv|vaapi|libvpl"; done

結果はこのようになると思います。

ubuntu@intel-arc:~$ for i in buildconf hwaccels decoders filters encoders; do echo $i:; ffmpeg -hide_banner -${i} | egrep -i "qsv|vaapi|libvpl"; done
buildconf:
    --enable-vaapi
    --enable-libvpl
hwaccels:
vaapi
qsv
decoders:
 V....D av1_qsv              AV1 video (Intel Quick Sync Video acceleration) (codec av1)
 V....D h264_qsv             H264 video (Intel Quick Sync Video acceleration) (codec h264)
 V....D hevc_qsv             HEVC video (Intel Quick Sync Video acceleration) (codec hevc)
 V....D mjpeg_qsv            MJPEG video (Intel Quick Sync Video acceleration) (codec mjpeg)
 V....D mpeg2_qsv            MPEG2VIDEO video (Intel Quick Sync Video acceleration) (codec mpeg2video)
 V....D vc1_qsv              VC1 video (Intel Quick Sync Video acceleration) (codec vc1)
 V....D vp8_qsv              VP8 video (Intel Quick Sync Video acceleration) (codec vp8)
 V....D vp9_qsv              VP9 video (Intel Quick Sync Video acceleration) (codec vp9)
filters:
 ... deinterlace_qsv   V->V       Quick Sync Video "deinterlacing"
 ... deinterlace_vaapi V->V       Deinterlacing of VAAPI surfaces
 ... denoise_vaapi     V->V       VAAPI VPP for de-noise
 ... overlay_qsv       VV->V      Quick Sync Video overlay.
 ... overlay_vaapi     VV->V      Overlay one video on top of another
 ... procamp_vaapi     V->V       ProcAmp (color balance) adjustments for hue, saturation, brightness, contrast
 ... scale_qsv         V->V       Quick Sync Video "scaling and format conversion"
 ... scale_vaapi       V->V       Scale to/from VAAPI surfaces.
 ... sharpness_vaapi   V->V       VAAPI VPP for sharpness
 ... tonemap_vaapi     V->V       VAAPI VPP for tone-mapping
 ... transpose_vaapi   V->V       VAAPI VPP for transpose
 ... vpp_qsv           V->V       Quick Sync Video "VPP"
encoders:
 V..... av1_qsv              AV1 (Intel Quick Sync Video acceleration) (codec av1)
 V....D av1_vaapi            AV1 (VAAPI) (codec av1)
 V..... h264_qsv             H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
 V....D h264_vaapi           H.264/AVC (VAAPI) (codec h264)
 V..... hevc_qsv             HEVC (Intel Quick Sync Video acceleration) (codec hevc)
 V....D hevc_vaapi           H.265/HEVC (VAAPI) (codec hevc)
 V..... mjpeg_qsv            MJPEG (Intel Quick Sync Video acceleration) (codec mjpeg)
 V....D mjpeg_vaapi          MJPEG (VAAPI) (codec mjpeg)
 V..... mpeg2_qsv            MPEG-2 video (Intel Quick Sync Video acceleration) (codec mpeg2video)
 V....D mpeg2_vaapi          MPEG-2 (VAAPI) (codec mpeg2video)
 V....D vp8_vaapi            VP8 (VAAPI) (codec vp8)
 V....D vp9_vaapi            VP9 (VAAPI) (codec vp9)
 V..... vp9_qsv              VP9 video (Intel Quick Sync Video acceleration) (codec vp9)
ubuntu@intel-arc:~$ 
8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5