Intel CPU の内蔵 GPU を使って FFmpeg の H.264 / HEVC エンコードを高速化したい場合、Intel Quick Sync Video(QSV)が利用できます。
しかし Linux、特に Rocky Linux 9 のような RHEL 系ディストリビューションでは、
FFmpeg が h264_qsv を認識している
だけでは QSV は動きません。
実際、今回 Rocky Linux 9 上で次のようなエラーに遭遇しました。
[AVHWDeviceContext @ 0x562042595380] Failed to initialise VAAPI connection: -1 (unknown libva error).
[h264_qsv @ 0x56204258e140] Failed to create a VAAPI device.
Error initializing output stream 0:0
さらに -qsv_device で Intel GPU を明示しても、
[AVHWDeviceContext @ 0x55ac9a494500] Failed to initialise VAAPI connection: -1 (unknown libva error).
Device creation failed: -5.
Failed to set value '/dev/dri/renderD128' for option 'qsv_device': Input/output error
となりました。
この記事では、Rocky Linux 9 で FFmpeg + QSV をセットアップする方法と、こうしたエラーをどの順番で切り分けるべきかをまとめます。
QSV が動くまでのレイヤを理解する
最初に重要なのは、QSV は FFmpeg 単体の機能ではないということです。
Linux では概念的に次のような複数のレイヤを通って Intel GPU にアクセスします。
FFmpeg
↓
QSV
↓
Intel Media SDK / oneVPL
↓
Intel Media Driver
↓
VA-API / libva
↓
/dev/dri/renderD128
↓
i915 / xe
↓
Intel GPU
そのため、
ffmpeg -encoders | grep qsv
で
h264_qsv
hevc_qsv
が表示されても、それだけでは GPU が実際に使えることを意味しません。
例えば、
- Intel GPU を Linux が認識していない
nomodesetが設定されているi915/xeがロードされていない/dev/dri/renderD128にアクセスできないlibvaがない- Intel Media Driver がない、またはロードできない
- Media SDK / oneVPL runtime が合っていない
- FFmpeg 自体が QSV 対応でビルドされていない
といったどこか一箇所でも問題があると、QSV は動きません。
したがって、下から順番に確認していくのがトラブルシューティングの基本です。
1. Intel GPU を Linux が認識しているか確認する
まず PCI デバイスを確認します。
lspci -nn | grep -Ei 'VGA|Display'
今回の環境では、
00:02.0 VGA compatible controller [0300]:
Intel Corporation GeminiLake [UHD Graphics 605] [8086:3184] (rev 03)
となりました。
Intel UHD Graphics 605、つまり Gemini Lake の GPU が認識されています。
次に、カーネルドライバを確認します。
lspci -nnk | grep -A4 -Ei 'VGA|Display'
今回の結果は、
00:02.0 VGA compatible controller [0300]: Intel Corporation GeminiLake [UHD Graphics 605] [8086:3184] (rev 03)
DeviceName: Onboard - Video
Subsystem: Elitegroup Computer Systems Device [1019:a94d]
Kernel driver in use: i915
Kernel modules: i915
でした。
ここで重要なのは、
Kernel driver in use: i915
です。
Gemini Lake では i915 が使われます。
最近の Intel GPU では構成によって xe が使われることもあります。
念のため、
lsmod | grep -E 'i915|xe'
でも確認できます。
2. nomodeset を設定している場合は外す
Intel iGPU を QSV / VA-API で使用する場合、カーネルの起動オプションに nomodeset を指定していると、GPU ドライバが正常に初期化されず、QSV が使えない原因になることがあります。
まず現在のカーネルコマンドラインを確認します。
cat /proc/cmdline
ここに、
nomodeset
が含まれている場合は削除します。
nomodeset は Kernel Mode Setting(KMS)を無効化するオプションです。Intel GPU で使用する i915 などの DRM/KMS ドライバの正常な初期化を妨げるため、/dev/dri/renderD128 が生成されない、あるいは GPU デバイスが存在していても VA-API の初期化に失敗する原因になり得ます。
Rocky Linux 9 では GRUB の設定を確認します。
sudo grubby --info=ALL | grep args
nomodeset が設定されている場合は、全カーネルエントリから削除できます。
sudo grubby --update-kernel=ALL --remove-args="nomodeset"
設定後、再起動します。
sudo reboot
再起動後、もう一度確認します。
cat /proc/cmdline
nomodeset が消えていることを確認した上で、
lspci -nnk | grep -A4 -Ei 'VGA|Display'
を実行し、
Kernel driver in use: i915
となっていることを確認します。
続いて DRM デバイスも確認します。
ls -l /dev/dri/
最低限、
card0
renderD128
などが生成されていることを確認します。
3. /dev/dri/renderD128 を確認する
次に DRM デバイスを確認します。
ls -l /dev/dri/
今回の環境では、
drwxr-xr-x. 2 root root 80 Aug 7 16:04 by-path
crw-rw----. 1 root video 226, 0 Aug 7 16:04 card0
crw-rw-rw-. 1 root render 226, 128 Aug 7 16:04 renderD128
となっていました。
QSV や VA-API のサーバ用途で特に重要なのが、
/dev/dri/renderD128
です。
X11 や Wayland を起動していないサーバでも、renderD128 にアクセスできればハードウェアエンコードできます。
つまり、
GUI がない = QSV が使えない
ではありません。
ヘッドレスサーバでも利用可能です。
4. renderD128 の権限を確認する
典型的には次のようになっています。
crw-rw---- 1 root render ... /dev/dri/renderD128
この場合、FFmpeg を実行するユーザーを render グループへ追加します。
sudo usermod -aG render $USER
環境によっては video も必要になるため、
sudo usermod -aG video,render $USER
としても構いません。
再ログイン後、
id
で確認します。
systemd サービスから FFmpeg を起動する場合には、ログインユーザーではなくサービスを実行しているユーザーに権限が必要です。
Jellyfin、Plex、MediaMTX と組み合わせた独自トランスコード処理などでも、この点には注意が必要です。
今回の環境では、
crw-rw-rw-. 1 root render ... renderD128
だったため、単純な Unix パーミッション不足である可能性は低い状態でした。
5. EPEL と RPM Fusion を有効にする
Rocky Linux 9 の標準リポジトリだけでは FFmpeg や Intel Media Driver 周辺のパッケージが不足する場合があります。
まず EPEL を追加します。
sudo dnf install -y epel-release
続いて RPM Fusion Free / Nonfree を追加します。
sudo dnf install -y \
https://download1.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm \
https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-9.noarch.rpm
その後更新しておきます。
sudo dnf update -y
6. Intel Media Driver をインストールする
Intel の比較的新しい GPU では、VA-API ドライバとして Intel Media Driver、つまり iHD ドライバを使用します。
Rocky Linux 9 + RPM Fusion なら、
sudo dnf install -y intel-media-driver
をインストールします。
Intel Media Driver は VA-API バックエンドとなる、
/usr/lib64/dri/iHD_drv_video.so
を提供します。
今回使用した Intel UHD Graphics 605 / Gemini Lake も Intel Media Driver の対象です。
7. libva と vainfo をインストールする
VA-API の動作確認には vainfo が非常に便利です。
sudo dnf install -y libva libva-utils
インストール後、
vainfo
を実行します。
ただし GUI のないサーバでは、DRM デバイスを明示したほうが確実です。
vainfo --display drm --device /dev/dri/renderD128
正常なら、概ね次のようになります。
libva info: VA-API version ...
libva info: Trying to open /usr/lib64/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_...
libva info: va_openDriver() returns 0
vainfo: Driver version: Intel iHD driver ...
8. LIBVA_DRIVER_NAME=iHD で明示する
自動判定がうまくいかない場合には、使用する VA-API ドライバを明示できます。
LIBVA_DRIVER_NAME=iHD \
vainfo --display drm --device /dev/dri/renderD128
恒久的に指定したければ、
export LIBVA_DRIVER_NAME=iHD
としても構いません。
9. Intel Media SDK と oneVPL の違い
QSV 周りでは、
Intel Media SDK
libmfx
oneVPL
libvpl
intel-vpl-gpu-rt
といった名前が登場します。
Intel の新しいソフトウェアスタックは、従来の Intel Media SDK から oneVPL へ移行しています。
ただし Rocky Linux 9 の FFmpeg で何を入れるべきかは、使用している FFmpeg がどちらに対してビルドされているか確認することが重要です。
今回使用した RPM Fusion の FFmpeg 5.1.10 は、
ffmpeg -version
を見ると、
--enable-libmfx
でビルドされていました。
そして実際に、
rpm -qa | grep -Ei 'libva|intel-media|libmfx|vpl'
を確認すると、
libva-2.22.0-1.el9.x86_64
intel-mediasdk-21.3.5-1.el9.x86_64
libva-utils-2.11.1-1.el9.x86_64
となっていました。
この環境では FFmpeg が libmfx、つまり Intel Media SDK 経由の QSV を使用する構成です。
したがって、「Rocky 9 なら必ず libvpl + intel-vpl-gpu-rt をインストールする」と考えないほうが安全です。
まず、
ffmpeg -version
の configure オプションを確認してください。
10. FFmpeg をインストールする
RPM Fusion から FFmpeg を入れます。
sudo dnf install -y ffmpeg
確認します。
ffmpeg -version
11. FFmpeg が QSV 対応か確認する
まずハードウェアアクセラレーション一覧を確認します。
ffmpeg -hwaccels
今回の FFmpeg では、
Hardware acceleration methods:
vdpau
cuda
vaapi
qsv
drm
opencl
vulkan
となっていました。
ここで、
vaapi
qsv
が確認できます。
次に QSV エンコーダを確認します。
ffmpeg -hide_banner -encoders | grep -E 'qsv|vaapi'
今回の環境では、
V..... h264_qsv H.264 / AVC ... (Intel Quick Sync Video acceleration)
V....D h264_vaapi H.264/AVC (VAAPI)
V..... hevc_qsv HEVC (Intel Quick Sync Video acceleration)
V....D hevc_vaapi H.265/HEVC (VAAPI)
V..... mjpeg_qsv MJPEG (Intel Quick Sync Video acceleration)
V....D mjpeg_vaapi MJPEG (VAAPI)
V..... mpeg2_qsv MPEG-2 video (Intel Quick Sync Video acceleration)
V....D mpeg2_vaapi MPEG-2 (VAAPI)
V....D vp8_vaapi VP8 (VAAPI)
V....D vp9_vaapi VP9 (VAAPI)
V..... vp9_qsv VP9 video (Intel Quick Sync Video acceleration)
となりました。
h264_qsv が一覧にあることと、実際に GPU が使用できることは別問題です。
12. まず vainfo を正常にする
QSV のトラブルシューティングでは、いきなり FFmpeg のオプションを変更し続けるより、
vainfo --display drm --device /dev/dri/renderD128
を最初に正常化したほうが早いです。
今回の環境では、
libva info: VA-API version 1.22.0
libva info: Trying to open /usr/lib64/dri/iHD_drv_video.so
libva info: va_openDriver() returns -1
libva info: Trying to open /usr/lib64/dri/i965_drv_video.so
libva info: va_openDriver() returns -1
vaInitialize failed with error code -1 (unknown libva error),exit
となっていました。
GPU は認識され、i915 も使用され、/dev/dri/renderD128 も存在しているため、問題は libva / Intel Media Driver 付近にあると切り分けられます。
13. iHD_drv_video.so がどの RPM に含まれるか確認する
ls -l /usr/lib64/dri/iHD_drv_video.so
さらに、
rpm -qf /usr/lib64/dri/iHD_drv_video.so
で、どの RPM が提供しているファイルか確認できます。
RPM が分からなければ、
dnf provides '*/iHD_drv_video.so'
でも検索できます。
期待するのは intel-media-driver 系の RPM です。
sudo dnf install -y intel-media-driver
ここで注意したいのが intel-mediasdk と intel-media-driver は別物だということです。
14. ドライバの依存ライブラリを確認する
ldd /usr/lib64/dri/iHD_drv_video.so
ここに、
not found
があれば、その依存ライブラリが不足しています。
15. パッケージの出所とバージョンも確認する
rpm -qi libva libva-utils intel-mediasdk intel-media-driver
または、
dnf repoquery --installed \
--qf '%{name} %{version}-%{release} %{repoid}' \
libva libva-utils intel-mediasdk intel-media-driver
を使用します。
16. iHD を明示してテストする
LIBVA_DRIVER_NAME=iHD \
vainfo --display drm --device /dev/dri/renderD128
正常なら、
Trying to open /usr/lib64/dri/iHD_drv_video.so
Found init function ...
va_openDriver() returns 0
となります。
17. QSV 単体テストをする
vainfo が正常になったら、入力動画とは無関係なテスト映像で QSV エンコードを確認します。
ffmpeg \
-qsv_device /dev/dri/renderD128 \
-f lavfi \
-i testsrc2=size=1280x720:rate=30 \
-t 5 \
-c:v h264_qsv \
-global_quality 23 \
-f null -
これが成功すれば H.264 QSV エンコード経路が動作していると判断できます。
18. VAAPI エンコードでも切り分ける
ffmpeg \
-vaapi_device /dev/dri/renderD128 \
-f lavfi \
-i testsrc2=size=1280x720:rate=30 \
-vf 'format=nv12,hwupload' \
-t 5 \
-c:v h264_vaapi \
-f null -
| VAAPI | QSV | 考えられる原因 |
|---|---|---|
| NG | NG | VA-API / Intel Media Driver / GPU デバイス側 |
| OK | NG | Media SDK / oneVPL / QSV runtime 側 |
| OK | OK | GPU スタックは正常。元の FFmpeg コマンドを調査 |
| NG | OK | 通常はあまりない特殊な構成 |
19. QSV で H.264 をエンコードする
ffmpeg \
-qsv_device /dev/dri/renderD128 \
-i input.mp4 \
-c:v h264_qsv \
-global_quality 23 \
-c:a copy \
output.mp4
20. HEVC / H.265 を QSV でエンコードする
ffmpeg \
-qsv_device /dev/dri/renderD128 \
-i input.mp4 \
-c:v hevc_qsv \
-global_quality 25 \
-c:a copy \
output.mp4
21. QSV decode + QSV encode
ffmpeg \
-qsv_device /dev/dri/renderD128 \
-hwaccel qsv \
-hwaccel_output_format qsv \
-i input.mp4 \
-c:v h264_qsv \
-global_quality 23 \
-c:a copy \
output.mp4
トラブルシューティングでは、まず CPU decode + QSV encode から始めるほうが切り分けやすくなります。
22. yuv420p → nv12 の警告は致命的エラーではない
Incompatible pixel format 'yuv420p' for codec 'h264_qsv',
auto-selecting format 'nv12'
これは今回の VA-API エラーとは別問題です。
必要なら、
-pix_fmt nv12
を指定できます。
23. ALSA の Thread message queue blocking も別問題
[alsa] Thread message queue blocking;
consider raising the thread_queue_size option
が出る場合は ALSA 入力の前に、
-thread_queue_size 1024
などを指定します。
24. Rocky Linux 9 のセットアップ例
sudo dnf install -y epel-release
sudo dnf install -y \
https://download1.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm \
https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-9.noarch.rpm
sudo dnf install -y \
ffmpeg \
libva \
libva-utils \
intel-media-driver
今回のように ffmpeg -version に、
--enable-libmfx
がある環境では、
sudo dnf install -y intel-mediasdk
も候補になります。
Gemini Lake + RPM Fusion FFmpeg 5.1 系であれば、概ね、
sudo dnf install -y \
ffmpeg \
libva \
libva-utils \
intel-media-driver \
intel-mediasdk
という構成から始めるのが分かりやすいでしょう。
25. 最終確認チェックリスト
# 0. nomodeset
cat /proc/cmdline
# 1. GPU / kernel driver
lspci -nnk | grep -A4 -Ei 'VGA|Display'
# 2. Kernel module
lsmod | grep -E 'i915|xe'
# 3. DRM
ls -l /dev/dri/
# 4. Intel Media Driver
rpm -q intel-media-driver
# 5. iHD driver
ls -l /usr/lib64/dri/iHD_drv_video.so
rpm -qf /usr/lib64/dri/iHD_drv_video.so
# 6. VA-API
LIBVA_DRIVER_NAME=iHD \
vainfo --display drm --device /dev/dri/renderD128
# 7. FFmpeg HW acceleration
ffmpeg -hwaccels
# 8. QSV encoders
ffmpeg -hide_banner -encoders | grep _qsv
# 9. QSV decoders
ffmpeg -hide_banner -decoders | grep _qsv
# 10. QSV encode test
ffmpeg \
-qsv_device /dev/dri/renderD128 \
-f lavfi \
-i testsrc2=size=1280x720:rate=30 \
-t 5 \
-c:v h264_qsv \
-global_quality 23 \
-f null -
確認順序は次のように考えると分かりやすくなります。
nomodeset の有無
↓
Intel GPU
↓
i915 / xe
↓
/dev/dri/renderD128
↓
VA-API / libva
↓
Intel Media Driver
↓
Media SDK / oneVPL
↓
FFmpeg
今回の Gemini Lake / UHD Graphics 605 で分かったこと
今回の実機では、
Intel Corporation GeminiLake [UHD Graphics 605]
Kernel driver in use: i915
であり、/dev/dri/renderD128 も存在していました。
さらに FFmpeg は --enable-libmfx 付きで、qsv / vaapi を認識し、h264_qsv、hevc_qsv、vp9_qsv なども列挙できました。
しかし、
vainfo --display drm --device /dev/dri/renderD128
では、
Trying to open /usr/lib64/dri/iHD_drv_video.so
va_openDriver() returns -1
Trying to open /usr/lib64/dri/i965_drv_video.so
va_openDriver() returns -1
となっていました。
QSV テストでも、
Failed to initialise VAAPI connection
Device creation failed
となりました。
このことから、問題は FFmpeg のエンコードオプションではなく、VA-API / Intel Media Driver 層にあると切り分けられます。
このような場合は、
rpm -qf /usr/lib64/dri/iHD_drv_video.so
ldd /usr/lib64/dri/iHD_drv_video.so
LIBVA_DRIVER_NAME=iHD \
vainfo --display drm --device /dev/dri/renderD128
の順で Intel Media Driver の導入状態・依存関係を調べます。
まとめ
Rocky Linux 9 で FFmpeg + Intel QSV を使う場合、単に ffmpeg -encoders に h264_qsv が表示されれば完了、というわけではありません。
必要になるレイヤは概ね次の通りです。
| コンポーネント | 必要性 | 役割 |
|---|---|---|
nomodeset 無効化 | 重要 | DRM/KMS を正常に初期化 |
| Intel GPU | 必須 | ハードウェア |
i915 / xe | 必須 | Kernel GPU driver |
/dev/dri/renderD128 | 必須 | DRM render node |
libva | Linux QSV 環境で重要 | VA-API |
intel-media-driver | 対応 Intel GPU で重要 | iHD_drv_video.so |
intel-mediasdk | libmfx 構成 | Legacy QSV runtime |
libvpl | oneVPL 構成 | oneVPL dispatcher |
intel-vpl-gpu-rt | 対応する新世代 GPU | oneVPL GPU implementation |
| QSV 対応 FFmpeg | 必須 | h264_qsv / hevc_qsv 等 |
特に、
Failed to initialise VAAPI connection
Failed to create a VAAPI device
が出た場合には、エンコードオプションを変更する前に、
cat /proc/cmdline
vainfo --display drm --device /dev/dri/renderD128
を確認するのが近道です。
nomodeset が残っていれば外し、vainfo が正常に動かなければ VA-API / Intel Media Driver の問題を先に解決します。
Rocky Linux 9 で QSV を構築するときは、
nomodeset
↓
GPU
↓
Kernel driver
↓
DRM
↓
VA-API
↓
Intel Media Driver
↓
Media SDK / oneVPL
↓
FFmpeg
というレイヤを意識して、下から一段ずつ正常動作を確認するのが最も確実なセットアップ方法です。