ffmpeg 2.6から使えるNVENC, NVDECを使う方法。

hardware acceleration の Wiki:HWAccelIntro – FFmpeg

追記 2024年4月1日
SDK 12.2のビット深度APIのサポート。

関連記事

準備

現在はヘッダをインストールしないと有効化されない。インストールしていれば自動でエンコードとデコードが有効化される。

  1. まずはffmpegのソースコードNVidia headersをダウンロードする
  2. nv-codec-headers のフォルダに移動しmake install PREFIX=/usrして、lib, include をインストールする
  3. ffmpegのcofigureに–disable-nvenc –disable-nvdec ––disable-ffnvcodec ––disable-cuda-llvm ––disable-cuvidなどを付けなければ自動で有効化する
  4. SDKを使ったリサイズフィルタscale_npp、映像を回転させるtranspose_nppを使うにはツールキットをインストール(最低限必要なのはカスタムインストールでRuntime -> Libraries、Development -> Compilerの2か所にチェック)して include, lib64 フォルダをリンクし、–enable-cuda-nvcc –enable-libnpp –enable-nonfreeをつける。詳しくは公式stackoverflowを参照
  5. インストールしたSDKのバージョンが上がり、nv-codec-headersがそれに対応してないと使えなくなり、またはその逆も使えなくなる(未確認)
media-autobuild_suiteで最低限必要なもの

タイトルの通りにNVENCなのでNvidiaのグラフィックボードを搭載していないとエンコードできない。ドライバが古いと新しいSDKのバージョンを使ったffmpegで使えない。さらに特定の(価格帯の安い)グラフィックボードでも NVENCが使えないことがあるのでよく調べること。NVENCが使えなくてもフィルタは使えるのでハードウェアデコードしてハードウェアアクセレーションのフィルタを使い、QSVでエンコードすれば処理はとても速くなる。

ドライバのダウンロード先。
NVIDIAドライバダウンロード

SDKのダウンロード先。
CUDA Toolkit Download | NVIDIA Developer
CUDA Toolkit Archive | NVIDIA Developer

公式に対応しているグラフィックボードは以下のリンクを参照。
Video Encode and Decode GPU Support Matrix | NVIDIA Developer

オプション内容

v11より
ffmpeg -h encoder=h264_nvenc

実際にエンコードできる環境がないので設定を煮詰められないがビットレートを上げる以外で画質の直結する設定は preset が大きい。

H.264 オプション日本語訳

  • preset[int]
    • hq, medium, default:high quality の略
    • hp, fast:high performance の略
    • bd:ブルーレイディスク用のエンコード
    • ll:LOW_LATENCY_DEFAULT(低遅延)
    • llhp:LOW_LATENCY_HP(低遅延で高性能)
    • llhq:LOW_LATENCY_HQ(低遅延で高画質)
    • slow:hq 2pass
    • lossless:可逆圧縮
    • losslesshp:可逆圧縮の高圧縮モード
    • p1:一番速く一番低品質。以下SDKのバージョン10以降で使える
    • p2:より速く、より低品質
    • p3:速く、低品質
    • p4:通常。既定値
    • p5:遅く、高品質
    • p6:より遅く、より高品質
    • p7:一番遅く、最大品質
  • tune[int]
    チューン指定。SDKのバージョン10以降で使える
    • hq:High qualityの略で高品質
    • ll:Low latencyの略で低遅延
    • ull:Ultra low latencyの略で超低遅延
    • lossless:可逆圧縮
  • profile[int]
    プロファイル指定。high, main, baseline or high444p
    既定値:main
  • levlel[int]
    レベル指定。整数指定なので求めるレベルの10倍を指定する。
    既定値:auto(解像度とフレームレートで自動設定)
  • cbr[boolean]
    固定ビットレートモード
    既定値:0
  • 2pass[boolean]
    2パスCBRモード
    既定値:auto
  • gpu[int]
    グラフィックボードを2枚差し以上にしている場合にどれを使うか指定する
    0は既定値、1は2枚目、以下同様
  • delay[int]
    指定フレームだけ出力結果を遅らせる。0 から
    既定値:0
エンコード例

ffmpeg -i input -c:v h264_nvenc ouput.mp4

画面下半分の色がおかしくなる場合は-pix_fmt nv12をつける
ffmpeg -i input -c:v h264_nvenc -pix_fmt nv12 ouput.mp4

実際にエンコードする場合は、-rc, -qmin, -qmaxを併用して品質指定をする
ffmpeg -i input -c:v h264_nvenc -pix_fmt nv12 -rc constqp -qmin 20 -qmax 26 ouput.mp4

具体的な設定内容
mp4 – Best settings for FFMpeg with NVENC – Super User

-force_key_framesで指定するときは-forced-idr 1も併用する。
ffmpeg -i input -c:v h264_nvenc -pix_fmt nv12 -forced-idr 1 -force_key_frames "expr:gte(t,n_forced*5)" ouput.mp4

FFMPEG + h264_nvenc + -force_key_frames – Stack Overflow

複数の GPU を取り付けていて使い分ける場合には-gpuを使う。
parameters – how to specify the GPU to be used by nvenc in ffmpeg – Stack Overflow : archive.org

リストを表示するコマンド例(Windows)。
ffmpeg -f lavfi -i nullsrc -c:v h264_nvenc -gpu list -f null -

色空間を明示する場合は H.264 だと-bsf:v h264_metadataを設定する。

ビットストリームフィルタのまとめ

1 : BT.709
6 : BT.601(smpte170m)

ffmpeg -i input -c:v h264_nvenc -pix_fmt nv12 -rc constqp -qmin 20 -qmax 26 -bsf:v h264_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1 ouput.mp4

HDR ストリームからハードウェア支援を使って SDR にエンコードする。
ffmpeg -hwaccel cuda -init_hw_device opencl=ocl -filter_hw_device ocl -extra_hw_frames 3 -threads 16 -c:v hevc_cuvid -i input.mp4 -vf "format=p010,hwupload,tonemap_opencl=tonemap=mobius:param=0.01:desat=0:r=tv:p=bt709:t=bt709:m=bt709:format=nv12,hwdownload,format=nv12" -c:v h264_nvenc -c:a copy -bsf:v h264_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1 -max_muxing_queue_size 9999 output.mp4

Converting 4K HDR to SDR with hardware acceleration : ffmpeg

NVENC が使えるようになった commitdiff
avcodec: Add NVENC encoder : git.videolan.org Git
H.264 だけではなく H.265(HEVC)にも対応した commitdiff
avcodec/nvenc: Add support for H.265 encoding : git.videolan.org Git

H.265(HEVC)オプション

v11より
ffmpeg -h encoder=hevc_nvenc

エンコード例

ソフトウェアデコードして8ビット深度でエンコード
ffmpeg -i input -c:v hevc_nvenc -preset p6 -rc constqp -qmin 20 -qmax 26 -c:a copy ouput.mp4

ハードウェアデコードして8ビット深度でエンコード
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -c:v hevc_nvenc -preset p6 -rc constqp -qmin 20 -qmax 26 -c:a copy ouput.mp4

ハードウェアデコードして10ビット深度でエンコード
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -vf scale_cuda=format=p010le -c:v hevc_nvenc -preset p6 -rc constqp -qmin 20 -qmax 26 -c:a copy ouput.mp4

色空間を明示する場合は H.265 だと-bsf:v hevc_metadataを設定する。

ビットストリームフィルタのまとめ

1 : BT.709
6 : BT.601(smpte170m)

colorprim, colormatrix の 9 は bt2020, bt2020nc になるが、transfer の 9 は log100 になる。詳しくはH.265 section E.3.1 and tables E.3, E.4 and E.5にある。わかりやすい記事はx265 の公式ドキュメントを読む。

-bsf:v hevc_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1

AV1のオプション

使えるのはRTX 40シリーズ。
ffmpeg -h encoder=av1_nvenc

デコード例

NVDECとCUVIDは似ているが、デコードと読み込むフレーム数に違いがある。HWAccelIntro NVDEC/CUVID – FFmpeg

入力データの前にデコーダを指定する。無指定だとソフトウェアデコードになる。
ffmpeg -hwaccel cuvid -vcodec h264_cuvid -hwaccel_output_format cuda -i input -c:v h264_nvenc output.mp4
ffplay -vcodec h264_cuvid -i input

フィルタを挟んで再生する。
ffplay -vcodec h264_cuvid -i input -vf "hwupload_cuda,scale_cuda=-2:360:interp_algo=lanczos,hwdownload,format=nv12

CUDA を使ったハードウェアアクセレーションフィルタのまとめ

対応コーデックならデコーダ名が不要になった。
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -c:v h264_nvenc output.mp4

No decoder surfaces leftのエラーが出るときは-extra_hw_frames 2を指定する。それでもエラーが出るときは-extra_hw_framesの数値を上げてみる。
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 2 -i input -c:v h264_nvenc output.mp4

デコードオプションの使い方

ハードウェアデコーダのオプションを使うと、インターレース解除、クロップ、リサイズが利用できる。デコーダ名を省略するとオプションが使えないのに注意する。

利用できるハードウェアデコーダの一覧

  • h264_cuvid
  • hevc_cuvid
  • mjpeg_cuvid
  • mpeg1_cuvid
  • mpeg2_cuvid
  • mpeg4_cuvid
  • vc1_cuvid
  • vp8_cuvid
  • vp9_cuvid
  • av1_cuvid

詳しくは以下を参照。

ライブラリを使ったフィルタ:
CUDA を使ったハードウェアアクセレーションフィルタのまとめ
Vulkan を使ったハードウェアアクセレーションフィルタのまとめ

  • -deint[int]
    インターレースの解除方法
    • 0, weave:何もしない。既定値
    • 1, bob
    • 2, adaptive:通常はこちらを使う
  • -gpu[string]
    デコードに使うGPUを指定する。複数GPUを挿している場合に指定する
    例:”cuda”
  • -surfaces[int]
    Maximum surfaces to be used for decoding
    既定値:25
    範囲:0 から INT_MAX まで
  • -drop_second_field[boolean]
    インターレース解除したときに2番目のフィールドを間引く。-deint adaptiveしたときに併用する
    既定値:0
  • -crop[string]
    クロップ(映像を切り取るピクセル数)。0x0x0x0 だと何もクロップしない
    上x下x左x右
  • -resize[string]
    リサイズ
    横幅x縦幅

コマンド例

MPEG2の動画をハードウェアデコードしてインターレースを解除し、不要フィールドを間引き、720pにリサイズし、映像は hevc_nvenc でエンコード、音声はコピーした output.mp4 に出力。
ffmpeg -hwaccel cuvid -c:v mpeg2_cuvid -deint adaptive -drop_second_field 1 -resize 1280x720 -analyzeduration 30M -probesize 30M -i input.ts -c:v hevc_nvenc -c:a copy output.mp4

このコマンドでも可能。デコーダ指定を省略してはならない。
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -c:v mpeg2_cuvid -deint adaptive -drop_second_field 1 -resize 1280x720 -analyzeduration 30M -probesize 30M -i input.ts -c:v hevc_nvenc -c:a copy output.mp4

更新履歴

追記 2019年10月20日
SDK 9.1.23.1 にアップデート。multiple reference frames に対応。

ドライバのバージョンは
Corresponds to Video Codec SDK version 9.1.23.2
Linux: 435.21 以上
Windows: 436.15 以上

追記 2016年4月28日
master で–enable-nonfreeが不要になり配布バイナリに含められるようになった。
configure: Don’t require nonfree for nvenc : git.videolan.org Git – ffmpeg.git/commitdiff

追記 2016年8月29日
master で API 7.x に対応し、ffmpeg に組み込まれたので nvEncodeAPI.h のコピーが不要になった。ffmpeg で NVENC を使うのに SDK をダウンロードする必要がなくなったが、SDK をダウンロードするにはアカウント作成が必要になった。API 7.x で rc-lookahead のオプションと、Pascal generation GPU(GTX 1060、GTX 1070、GTX 1080)から HEVC 10-bit エンコードが追加された。それ以外の新機能が ffmpeg に実装されているかは未確認。API 7.x の新機能は以下の通り。

  • HEVC 8K (8192 pixels x 8192 pixels) encoding *
  • HEVC 4:4:4 encoding *
  • HEVC 10-bit encoding *
  • HEVC lossless encoding *
  • HEVC Sample Adaptive Offset (SAO) *
  • HEVC Motion-Estimation-(ME)-only mode *
  • HEVC (up to 8K) decoding *
  • VP9 (up to 8K) decoding *
  • HEVC long term reference (LTR) frame support
  • Asynchronous H.264 Motion-Estimation-(ME)-only mode
  • Look-ahead
  • Improved H.264 spatial adaptive quantization
  • H.264 temporal adaptive quantization
  • Rate control and quality improvements

* は Pascal generation GPU(GTX 1060、GTX 1070、GTX 1080)からの新機能になる

avcodec/nvenc: include nvEncodeAPI v7 SDK header : git.videolan.org Git
avcodec/nvenc: added support for 10 bit HEVC encoding : git.videolan.org Git
avcodec/nvenc: added support for rate control lookahead : git.videolan.org Git

追記 2017年5月10日
SDK 8.0.14 にアップデートされた。新機能は

  • 10/12-bit decoding support with HEVC/VP9, enabling end-to-end HDR transcoding
  • Improved quality via weighted prediction
  • Support for OpenGL inputs (Linux only)

ドライバのバージョンは
NVIDIA Linux display driver 378.13 以上
NVIDIA Windows display driver 378.66 以上

compat/nvenc: bump nvEncodeAPI.h to Video Codec SDK 8.0.14 – ffmpeg.git/commitdiff
avcodec/nvenc: add weighted prediction support – ffmpeg.git/commitdiff
avcodec/nvenc: add fractional CQ support – ffmpeg.git/commitdiff

追記 2020年10月21日
SDK 11.0.10にアップデート。新機能はプロファイルレベルの上限があがり、プリセット、マルチパス対応、低遅延のシーンチェンジキーフレーム挿入オプションが追加された。機能自体はSDK 10のものになる。
avcodec/nvenc: add new h264 levels from Video SDK 10 · FFmpeg/FFmpeg@3223f6b
avcodec/nvenc: add new Video SDK 10 features · FFmpeg/FFmpeg@9115d77

Linux: 455.28 or newer
Windows: 456.71 or newer

追記 2020年7月8日
SDK 10.0.26にアップデート。新機能は1. new Nvenc presets、2. new multipass encode modes、3. low delay key frame scale

追記 2019年2月14日、2019年3月18日
SDK 9.0.18にアップデート。新機能はGeForce RTX 2000番台、GTX 1660 Ti/1660 に追加されたHEVC(hevc_nvenc)のBフレーム対応。H.264(h264_nvenc)ではない。H.265(HEVC)4:4:4デコード対応。

avcodec/nvenc: add b_as_ref support for HEVC – ffmpeg.git/commitdiff

現状、cuda_10.2.89_441.22_win10 をインストールすると、NVIDIA GeForce GT 1030 が認識しなくなったのでデバイスマネージャーからダウングレードして使っている。

追記 2021年8月11日
SDK 11.1.5.0にアップデート。新機能はh264_nvenc、hevc_nvenc両方にchroma qp offsetオプションの追加。

Linux: 470.57.02 or newer
Windows: 471.41 or newer

One thought on “ffmpeg に nvenc(cuda)をインストールする”

Ubuntu 18.04.4 LTS にTV録画環境をインスト その2 | ぽんこつ庵 へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)