この記事でわかること
- VAAPIとは何か、どのGPUで使えるか
- LinuxでVAAPIを有効にするための前提条件
h264_vaapi、hevc_vaapi、av1_vaapiの基本的な使い方- GPUデコード+エンコードのパイプライン構成
- よくあるエラーと解決策
テスト済みバージョン: FFmpeg 6.1(Linux/VAAPI環境)
対象 OS: Linux(Intel iGPU / AMD GPU対応)
VAAPIとは
VAAPI(Video Acceleration API)はLinuxのハードウェアビデオアクセラレーション標準インターフェースです。Intel内蔵GPU、AMD GPU、一部のNVIDIA GPUで利用できます。GPUのエンコーダーを直接呼び出すため、CPUソフトウェアエンコードより大幅に高速です。
| GPU | VAAPI サポート |
|---|---|
| Intel iGPU | H.264(Broadwell以降)/H.265は新しい世代で対応。AV1エンコードはIntel Arc・一部の新しいXeに限定 |
| AMD GPU | H.264 / H.265 — VCE/VCNの世代・ドライバ依存。AV1はRDNA3以降 |
| NVIDIA(nouveau) | 限定的(非推奨) |
前提条件
必要なパッケージのインストール
Ubuntu / Debian:
※ このコマンドはVAAPI環境が必要です
sudo apt install vainfo libva-dev intel-media-va-driver # Intel
sudo apt install vainfo libva-dev mesa-va-drivers # AMD
Arch Linux:
※ このコマンドはVAAPI環境が必要です
sudo pacman -S intel-media-driver libva # Intel
sudo pacman -S mesa libva # AMD
VAAPIデバイスの確認
※ このコマンドはVAAPI環境が必要です
vainfo
/dev/dri/renderD128 が表示され、対応しているエントリポイント(VAEntrypointEncSlice など)が一覧されれば準備OK。
h264_vaapi の基本コマンド
※ このコマンドはVAAPI(Linux)環境が必要です
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' \
-c:v h264_vaapi -qp 23 \
-c:a aac -b:a 128k output_vaapi.mp4
ポイント:
-vaapi_device /dev/dri/renderD128:VAAPIデバイスを指定(/dev/dri/renderD129など複数ある場合もある)-vf 'format=nv12,hwupload':フレームをGPUメモリにアップロードするために必須-qp 23:品質パラメーター(0〜51、低いほど高品質)
hevc_vaapi(H.265)
※ このコマンドはVAAPI(Linux)環境が必要です
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' \
-c:v hevc_vaapi -qp 28 \
-c:a aac -b:a 128k output_hevc_vaapi.mp4
av1_vaapi(AV1)— Intel Arc / Xe以降
※ このコマンドはVAAPI(Linux / Intel Arc)環境が必要です
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' \
-c:v av1_vaapi -rc_mode CQP -global_quality 30 \
-c:a aac -b:a 128k output_av1_vaapi.mp4
注意: av1_vaapi は h264_vaapi/hevc_vaapi で使う -qp オプションを受け付けません(FFmpegが「Codec AVOption qp has not been used」とエラーを出します)。固定品質なら -rc_mode CQP -global_quality 30、ビットレート指定なら -b:v 4M を使ってください。AV1は Intel Arc(Alchemist)以降や AMD RDNA3以降のGPUでサポートされています。
VAAPIデコード + エンコードのフルGPUパイプライン
デコードもGPU(VAAPI)で行うことでCPU使用率をほぼゼロにできます:
※ このコマンドはVAAPI(Linux)環境が必要です
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi \
-i input.mp4 \
-c:v h264_vaapi -qp 23 \
-c:a copy output_fullgpu.mp4
この方法ではGPUからCPUへのフレーム転送が不要になります。
ビットレート指定エンコード
※ このコマンドはVAAPI(Linux)環境が必要です
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' \
-c:v h264_vaapi -rc_mode CBR -b:v 4M \
-c:a aac -b:a 128k output_cbr.mp4
よくあるエラーと対処法
Cannot open library: libva.so.2
libvaがインストールされていない- Ubuntu:
sudo apt install libva2
Device creation failed(/dev/dri/renderD128 が見つからない)
ls /dev/dri/でデバイスを確認- カーネルモジュールが読み込まれているか確認(Intel:
i915, AMD:amdgpu)
format=nv12,hwupload なしでエラー
- VAAPIエンコーダーはGPUメモリ上のフレームを要求するため、
hwuploadは必須
Provided pixel format nv12 is not supported
- 一部のGPUは
p010le(10ビット)形式のみ受け付ける場合がある -vf 'format=nv12,hwupload'を-vf 'format=p010le,hwupload'に変更してみる
VAAPIとNVENCの比較
| 項目 | VAAPI(Intel/AMD) | NVENC(NVIDIA) |
|---|---|---|
| 対象GPU | Intel iGPU / AMD GPU | NVIDIA GPU |
| OS | Linux主体 | Windows / Linux |
| 設定の複雑さ | やや複雑(デバイス指定) | 比較的シンプル |
| 速度 | 高速 | 高速 |
速度と品質の目安(実測レンジ)
以下は公開ベンチマークで観測される典型的なレンジです。世代・ドライバ(Intelの場合は旧 i965 か新 iHD/media-driver か)で大きく変わる点に注意してください。
- エンコード速度: Intel UHD/Iris XeのiGPUで1080p H.264を実時間の約4〜8倍、Intel ArcやAMD RDNA系のディスクリートGPUではさらに上のレンジが出ることがあります。CPUの
libx264 -preset medium(実時間1.5〜3倍)と比べて数倍速いのが一般的です。実際の数値はGPU・ドライバ・素材・プリセット・解像度で変わります。 - 品質トレードオフ: 同等VMAFを狙うと、VAAPIエンコードは
libx264より高めのビットレートが必要になりがちです。差の大きさは世代と素材に依存します。Intelの新しいmedia-driver(iHD)はQSV相当のチューニングが効き、旧i965より品質が安定します。 - AV1: Intel Arc / AMD RDNA3のAV1エンコードはH.264比で同品質を明確に小さいサイズで出せることがあり、配信用途で効果が大きいです。
つまずきやすいポイント
/dev/dri/renderD128 で権限エラー(Permission denied)
- 症状:
vainfoやエンコードでfailed to open /dev/dri/renderD128: Permission deniedが出る。 - 原因: 実行ユーザーが
render(またはvideo)グループに属していない。コンテナ内だと特に起きやすい。 - 対処:
sudo usermod -aG render $USERでグループ追加して再ログイン。Dockerでは--device /dev/driを渡し、--group-addでホストのrender GID を指定する。
format=nv12,hwupload を忘れて Impossible to convert between the formats が出る
- 症状: フィルタを付けずに
-c:v h264_vaapiを指定すると変換不能エラーで止まる。 - 原因: VAAPIエンコーダはGPUメモリ上のサーフェスを要求するため、CPU側のフレームをそのまま渡せない。
- 対処:
-vf 'format=nv12,hwupload'を必ず挟む。フルGPUパイプライン(-hwaccel vaapi -hwaccel_output_format vaapi)の場合は既にGPU上にあるのでhwuploadは不要です。
複数GPU環境でデバイスを取り違える
- 症状: iGPUを使いたいのにディスクリートGPU側が選ばれる、または逆。
- 原因:
/dev/dri/renderD128とrenderD129のどちらがどのGPUか環境で異なる。 - 対処:
ls -l /dev/dri/by-path/でPCIアドレスとデバイスの対応を確認し、目的のGPUのrenderDxxxを-vaapi_deviceに明示する。
10ビット入力で nv12 is not supported
- 症状: HDRや10ビットソースで
Provided pixel format nv12 is not supported。 - 原因: 10ビット素材を8ビットの
nv12で受けようとしている。 - 対処:
-vf 'format=p010le,hwupload'に変更する。出力も10ビット対応プロファイル(-profile:v main10など)を指定する。
よくある質問
VAAPIとQSV(Quick Sync)はどう違う?
どちらもIntel GPUのハードウェアエンコードですが、VAAPIはLinux標準のAPI、QSV(h264_qsv)はIntel独自のSDK経由です。Linuxで汎用的に使うならVAAPI、Intel機能をフルに引き出したい・WindowsでもならQSVが選択肢になります。
-qp と -rc_mode のどちらで品質を決めるべき?
固定品質で出力したいなら -qp(小さいほど高品質、23前後が目安)。配信や容量管理でビットレートを揃えたいなら -rc_mode CBR -b:v 4M のようにレート制御を使います。両立させたい場合は -rc_mode VBR -b:v と -maxrate を併用します。
AMD GPUでもVAAPIで使える?
使えます。mesa-va-drivers(Mesa Gallium)をインストールし、カーネルの amdgpu モジュールが有効なら h264_vaapi/hevc_vaapi が動きます。AV1エンコードはRDNA3以降が対象です。
CPUエンコードと比べて画質が落ちた気がする
固定品質値が同じでも、VAAPIは libx264 よりやや効率が劣るため同サイズだと画質が下がって見えることがあります。-qp を1〜2下げるか、ビットレートを1〜2割上げると体感差が縮まります。
Dockerコンテナ内でVAAPIを使うには?
docker run --device /dev/dri ... でデバイスを渡し、コンテナ内ユーザーをホストの render グループGIDに追加します。vainfo がコンテナ内で正常に動けば準備完了です。
関連リソース
長時間のエンコードや大量のバッチ処理を手元のPCで回すのが重い場合は、時間課金で使えるレンタルサーバーやVPSを検討する一案もあります。
関連記事
一次ソース: trac.ffmpeg.org/wiki/HWAccelIntro / ffmpeg.org/ffmpeg-codecs.html