ffmpeg 2.6から使えるNVENC, NVDECを使う方法。
- FFmpeg / libav | NVIDIA Developer
- NVIDIA FFmpeg Transcoding Guide | NVIDIA Developer Blog
- NVIDIA VIDEO CODEC SDK | NVIDIA Developer
- Using FFmpeg with NVIDIA GPU Hardware Acceleration
hardware acceleration の Wiki:HWAccelIntro – FFmpeg
追記 2024年4月1日
SDK 12.2のビット深度APIのサポート。
- avcodec/nvenc: support SDK 12.2 bit depth API · FFmpeg/FFmpeg@06c2a2c · GitHub
- avcodec/nvenc: update minimum driver version list · FFmpeg/FFmpeg@c06e9e2 · GitHub
- avcodec/nvenc: add support for unidirectional b-frames · FFmpeg/FFmpeg@21b4708 · GitHub
- avcodec/nvenc: add support for uhq tune · FFmpeg/FFmpeg@a270966 · GitHub
- avcodec/nvenc: add support for lookahead_level · FFmpeg/FFmpeg@77d23bc · GitHub
- avcodec/nvenc: add support for HEVC temporal filtering · FFmpeg/FFmpeg@64e3fc9 · GitHub
関連記事
- qsv 対応の ffmpeg をつくる
- AMD VCE 対応の ffmpeg をつくる
- ハードウェアデコーダ、フィルタ、エンコーダを組み合わせる
- CUDA を使ったハードウェアアクセレーションフィルタのまとめ
- Vulkan を使ったハードウェアアクセレーションフィルタのまとめ
目次
準備
現在はヘッダをインストールしないと有効化されない。インストールしていれば自動でエンコードとデコードが有効化される。
- まずはffmpegのソースコードとNVidia headersをダウンロードする
- nv-codec-headers のフォルダに移動しmake install PREFIX=/usrして、lib, include をインストールする
- ffmpegのcofigureに–disable-nvenc –disable-nvdec ––disable-ffnvcodec ––disable-cuda-llvm ––disable-cuvidなどを付けなければ自動で有効化する
- SDKを使ったリサイズフィルタ
scale_npp
、映像を回転させるtranspose_npp
を使うにはツールキットをインストール(最低限必要なのはカスタムインストールでRuntime -> Libraries、Development -> Compilerの2か所にチェック)して include, lib64 フォルダをリンクし、–enable-cuda-nvcc –enable-libnpp –enable-nonfreeをつける。詳しくは公式、stackoverflowを参照 - インストールしたSDKのバージョンが上がり、nv-codec-headersがそれに対応してないと使えなくなり、またはその逆も使えなくなる(未確認)
- 待ってました CUDA on WSL 2 – Qiita
- How to install FFmpeg with GPU on AWS | Mirza Bilal | Medium
- Install ffmpeg from source on CPU or GPU
タイトルの通りに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
オプション内容
H.264 オプション
v11より
ffmpeg -h encoder=h264_nvenc
実際にエンコードできる環境がないので設定を煮詰められないがビットレートを上げる以外で画質の直結する設定は preset が大きい。
- 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
- How can I use CRF encoding with nvenc in ffmpeg? – Super User
- ffmpeg NVENCの画質と最適設定
- mp4 – Best settings for FFMpeg with NVENC – Super User
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
- Unable to make Cuda FFmpeg work : ffmpeg
- FFmpeg: For NVENC, what is a concurrent surface? – Super User
- #7562 (using -hwaccel nvdec produces ‘No decoder surfaces left’ with interlaced input and 3 or more b-frames) – FFmpeg
デコードオプションの使い方
ハードウェアデコーダのオプションを使うと、インターレース解除、クロップ、リサイズが利用できる。デコーダ名を省略するとオプションが使えないのに注意する。
利用できるハードウェアデコーダの一覧
- h264_cuvid
- hevc_cuvid
- mjpeg_cuvid
- mpeg1_cuvid
- mpeg2_cuvid
- mpeg4_cuvid
- vc1_cuvid
- vp8_cuvid
- vp9_cuvid
- av1_cuvid
詳しくは以下を参照。
- ffmpeg: remove superfluous custom cuvid hwaccel · FFmpeg/FFmpeg@60b1f85
- ffmpeg: default hwaccel_output_format to cuda when hwaccel is cuvid · FFmpeg/FFmpeg@cb3c77c
- #6989 (Hwaccel cuvid fails with “Error creating a NVDEC decoder: 1”) – FFmpeg
ライブラリを使ったフィルタ:
CUDA を使ったハードウェアアクセレーションフィルタのまとめ
Vulkan を使ったハードウェアアクセレーションフィルタのまとめ
- -deint[int]
インターレースの解除方法 - 0, weave:何もしない。既定値
- 1, bob
- 2, adaptive:テレシネのインターレース解除にはこちらを使う
- -gpu[string]
デコードに使うGPUを指定する。複数GPUを挿している場合に指定する
例:”cuda” - -surfaces[int]
Maximum surfaces to be used for decoding
既定値:-1
範囲:0 から INT_MAX まで - -drop_second_field[boolean]
インターレース解除したときに2番目のフィールドを間引く。-deint bob、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オプションの追加。
- avcodec/nvenc: add chroma qp offset support · FFmpeg/FFmpeg@e56f6e5
- avcodec/nvenc: always set qp cr/cb offsets · FFmpeg/FFmpeg@00b5798
- Update headers from Video SDK 11.1 · FFmpeg/nv-codec-headers@b641a19
Linux: 470.57.02 or newer
Windows: 471.41 or newer
[…] 参考:ffmpeg に nvenc(cuda)をインストールする | ニコラボNVENCを使ったHWEncode環境 – QiitaffmpegでNVENCを使ってエンコードしてみる […]