FFmpeg で CUDA によるGPUエンコーディング

FFmpegで動画容量を節約 HowTo
FFmpegで動画容量を節約

 NASの容量節約のための動画エンコードについての記事を書きましたが、今回は NVIDIA の GPU によるハードウェアエンコードに挑戦します。

ハードウェアエンコーディングのメリット

 それはもう、”処理速度が速い”の一言に尽きます。爆速(のはず)です。

 昔から動画処理は重たい処理の代名詞。リアルタイムにこれを処理するための専用ASICを備えた拡張ボードがたくさん売られていたものです。パソコンの高性能化で、最近はCPU単体で4K動画を再生したりといった離れ業を難なくやってのけてしまうのです。1080pのエンコードくらいならばリアルタイム処理ができるでしょう。

 しかし、尺時間に対して数倍、数十倍の処理速度を求めるには、やはりハードウェアの支援がないとまだ厳しいですね。そこで、GPUコンピューティングの出番です。

GPUコンピューティングとは

 GPU ( Graphic Processing Unit ) とは、分かりやすく言えば、NVIDIA や AMD のビデオカードのことです。行列演算処理など、大量のストリーミングデータの演算処理に特化したハードウェアを山盛り実装したGPUは、動画処理 にも最適という訳です。

 NVIDIA は3Dポリゴン処理のためのスループットが過剰となりはじめた時期から、3Dグラフィックカードの演算能力を汎用的に活用するための規格を立ち上げました。それが CUDA ( Compute Unified Device Architecture ) というソフトウェア群にあたります。CUDA はマシンラーンニングや Stable Diffusion に代表されるAIによる画像生成処理を飛躍的に高めるために欠かせないものです。

 GPUの特化したスピード番長っぷりを FFmpeg でも発揮させることができます。

GPUコンピューティングに必要なもの

ビデオカード / Geforce シリーズ

 当然、必須となるのはビデオカードです。今回はCUDAエンジンを利用するので、NVIDIAのビデオカードが必要になります。ほかにも、Intel の Quick Sync を使うこともできるようですが、捗々しい成果は得られないようですね。AMD Radeon 系のプリセットも使用できるようですので、お持ちの方はぜひお試しください。

NVIDIA CUDA Toolkit

 このソフトウェア群がなければ CUDA は動いてくれません。公式サイトからダウンロードしてインストールしてください。

CUDA Toolkit - Free Tools and Training
Get access to SDKs, trainings, and connect with developers.
NVIDIA CUDA Toolkit ホーム
NVIDIA CUDA Toolkit ホーム

Geforce ドライバ

 現在、ゲームなどに活用しているならば、特に問題はないでしょう。できれば最新版というところ。

 私の環境では、バージョン 31.0.15.3625 でした。

エンコードする環境

 Windowsが対象です。前回紹介した FFmpeg Batch AV Converter を使用します。

PC環境

OSWindows11
CPUCore i7 8700
メモリDDR4 2666 32GB
SSDNVMe 1GB
GPUNDIAIA Geforce GTX 1060 6GB

 いまとなっては、何の変哲もない構成です。

CUDAエンコーディングの実際

素材の動画データ

 前回使用したものと同一のファイルを使います。

H.264によるサンプル動画 / 30.9MB

FFmpeg のパラメータ

ここで扱う FFmpeg のパラメータは、あくまで FFmpeg Batch AV Converter に渡すためのもので、シェルで渡すコマンドとは異なりますので、ご注意ください。

 今回も、素材の H.264 動画を H.265 に変換します。CUDA を使用するためにパラメータの調整が必要です。

-c:a copy -vcodec hevc_nvenc

 ”hevc_nvenc” というパラメータは「H.265 への変換を NVIDIA のハードウェアエンコードで」といった意味合いです。本来ならば、これさえつければ問題ないはずなのですが、エラーが出て困ってしまいました。 

FFmpeg log sesion: 7/31/2023 9:47:49 PM
-------------------------------
---------------------Start of H264 - Made with Clipchamp.mp4 log-------------------------------

[hevc_nvenc @ 0000025814c65c00] B frames as references are not supported
[hevc_nvenc @ 0000025814c65c00] No capable devices found

 調べてみると、FFmpeg 6 系のバグというか仕様のようで、FFmpeg Batch AV Converter に付属する FFmpeg もこのバージョンに該当します。GTX1060 はBフレームに未対応で、デフォルトでBフレームがONになっているのが原因ということでしょうか。未検証ですが、バージョン5までは発生しないということのようです。未だGTX1060が現役の環境は多いでしょうから、ハマりどころですね。

 FFmpeg 6 のままで、何とか動作するパラメータに辿り着いたのが以下のものです。

-c:a copy -vcodec hevc_nvenc -profile:v main -level:v auto -preset:v default -b_ref_mode 0 

CUDA によるエンコード

 さすがに爆速でした!尺時間12秒に対しての処理時間は1秒以下で計測不能です。

FFmpeg + CUDA エンコードで出力された結果
  • ファイルサイズ 3.25MB (素材は30.9MB)
  • ビットレート 2,247Kb/s (素材は21Mb/s)

 オリジナルに対して、多少、鮮やかさが落ちて細部のジャギーが目立つようには見えますが、約1/10 に圧縮されているにも関わらず、劣化の度合いはそれほどでないのは驚きです。ハードウェアエンコード特有の画質の劣化というのも、ソフトウェアエンコードと比較してもハッキリ認知できないレベルに見えます。

ビットレートを 8,192 Kb/s に変更

 ビットレート未指定では 2Mb/s ( Variable Bit Rate ) となるようです。

 比較のためにビットレートを1/2程度にしてみて、画質の改善がどの程度なのかをチェックしてみましょう。

-c:a copy -vcodec hevc_nvenc -profile:v main -level:v auto -preset:v default -b_ref_mode 0 -b:v 8192k

 今回も1秒以内で計測不能で、処理速度自体に大差はありません。

FFmpeg + CUDA による H.265 エンコーディング(ビットレート8Mb/s)
  • ファイルサイズ 12.8MB (素材は30.9MB)
  • ビットレート 8,832Kb/s (素材は21Mb/s)

こちらはもう、オリジナルとの見分けがつかないレベルですね。

CUDA による H.265 エンコードスピードは?

 いろいろなファイルで試してみましたが、概ね尺時間の13倍ソフトウェアエンコードに対しては20倍以上のスピードUPとなりました。素晴らしい!

 玄人ならざる私の目には、ソフトとハードの違いは認知できませんでしたので、今後はハードウェアエンコードを使用する気になっています。ビットレートに関しては、用途次第で選択ですかね。”保存版”ということでなければ、2Mb/s は現実的な選択肢ではないかと思えますが、どうぞ、ご自身の目で確認してみてください。

 これだけ CUDA のパワーが圧倒的であると、スマホ閲覧用のローレゾファイルを別に用意することも現実味を帯びてきます。Nextcloud などのクラウドストレージ上の動画データをスマホで閲覧するといったシチュエーションでは、ギガ欠にならないために大変有効でしょう。

💡 コマンドに不安がある方は、こちらの記事で紹介している無料のGUIツールを使う方法もあります。

AV1 のハードウェアエンコードは?

 現状、Geforce RTX40xx シリーズのみの対応のようですね。CPUによるエンコードは厳しいものがありますので、しばらくは CUDA のハードウェアエンコーディングで H.265 にコンバートして凌ぐしかないようです。

AI活用の自動化例はこちら