もう2か月近くやっていた作業をやっと終わらせた。NVEncの抱えていたいろいろなよくわからない制限を撤廃して、ついでにGPUフィルタ機能を大幅に拡張。
もともとNVEncはavcuvid読みなときしかできない処理とかがあった。例えばGPUでのリサイズとか、cropとか。
なんでそんなことになっていたかというと、avcuvid読みなとき(GPUでデコードするとき)とそうでないとき(CPUでデコードするとき)で、全然違う処理になっていて、片方にしか実装してないとかいう機能もあったせいでそういうよくわからないことになっていた。
図にするとこんな感じ。
読み込み方法によって、処理の流れが違って、avcuvidの時はhw resizeはできるけど、yuv444とか10bitとかは使えないので、そういうことがしたければavsw経由で流してね…ということになっていた。逆にavswとかavsとかから読み込むとリサイズができない…。
今回フィルタ処理を入れてみようかなあ、と思ったときに、このavcuvidとそうでないときで分かれている処理のところをさわる必要が出てきたので、このあたりをいっそ全部書き直してみた。かなり時間がかかったけど、おかげでいろいろな機能を追加することができた。
で、新しい流れはこんな感じ。
処理の合間にCUDAによるフィルタ処理ができるようにして、yuv444/10bitとの変換や、リサイズ・delogo・ノイズ除去ができるようにした。
なので、今回追加したフィルタ処理は、一応全部GPUで動作する。QSVだと、SDKにフィルタ処理が用意されていて便利なのだけど、NVENCの場合はnppライブラリというのを使用するか、あとは自分で書くしかない。nppライブラリはx64版しか用意されていないという欠点があって、そのせいで基本的には全部自分で書くはめになった(リサイズは32bit版ではできませんとかなったら大変だ…)。
というわけでほとんどのGPUコードはわたしがCUDAで適当に書いのだけど、速いのかなあ?
まあ、一応リサイズとかはnppライブラリを呼べるように作ったので、使ってみたい方はNVEncC64.exeのあるフォルダに、別途nppi64_80.dll/nppc64_80.dllを入れて使ってみてください。(nppの再頒布可能なdllは重いので、別途npp64_80_dll.zipとしてあげておきます)
変更点
[NVEncC]・音声処理のエラー耐性を向上。"failed to run bitstream filter for AAC audio."のようなエラーが出てしまった場合でも処理を(ある程度)継続できるように。
・avcuvid読み込みでも10bit深度/YUV444出力に対応。・avcuvid読み込み以外でもリサイズを可能に。・avcuvid読み込み以外でもtrimを可能に。・左cropが動作しないのを解消。・透過性ロゴフィルタを追加。(--vpp-delogo)--vpp-delogo <string>ロゴファイルを指定する。".lgd",".ldp",".ldp2"に対応。
通常、複数のオプションを組み合わせて使用する。(ファイルにロゴがひとつの".lgd"なら不要)
例:--vpp-delogo "logopack.ldp2" --vpp-delogo-select "TBS 1440x1080"
ロゴパックファイル "logopack.ldp2" からロゴ "TBS 1440x1080" を使用。
--vpp-delogo-select <string>ロゴパックの場合に、使用するロゴを以下のいずれかで指定する。
・ロゴ名(完全一致!)
・インデックス (1,2,...)
・自動選択用iniファイル
下記の書式に従って、入力ファイル名から自動的にロゴを選択する。
書式 [LOGO_AUTO_SELECT]
logo<連番数字>=<マッチパターン>,<リストに表示されているロゴ名(完全一致!)>
設定ファイルの例
[LOGO_AUTO_SELECT]
logo1= (NHK-G).,NHK総合 1440x1080
logo2= (NHK-E).,NHK-E 1440x1080
logo3= (MX).,TOKYO MX 1 1440x1080
logo4= (CTC).,チバテレビ 1440x1080
logo5= (NTV).,日本テレビ 1440x1080
logo6= (TBS).,TBS 1440x1088
logo7= (TX).,TV東京 50th 1440x1080
logo8= (CX).,フジテレビ 1440x1088
logo9= (BSP).,NHK BSP v3 1920x1080
logo10= (BS4).,BS日テレ 1920x1080
logo11= (BSA).,BS朝日 1920x1080
logo12= (BS-TBS).,BS-TBS 1920x1080
logo13= (BSJ).,BS Japan 1920x1080
logo14= (BS11).,BS11 1920x1080 v3
この場合、入力ファイル名が"響け!ユーフォニアム #13 「さよならコンクール」 (BS11).ts"なら、ロゴ名"BS11 1920x1080 v3"が使用される。
--vpp-delogo-pos <int>:<int>1/4画素精度のロゴ位置の調整。Aviutlで言うところの <位置 X>:<位置 Y>。
--vpp-delogo-depth <int>ロゴの透明度の補正。デフォルト128。Aviutlで言うところの <深度>。
--vpp-delogo-y <int>--vpp-delogo-cb <int>--vpp-delogo-cr <int>ロゴの各色成分の補正。Aviutlで言うところの <Y>, <Cb>, <Cr>。
[NVEnc.auo/NVEncC共通]・さまざまなリサイズアルゴリズムを追加。(--vpp-resize)リサイズアルゴリズムを選択。
--vpp-resize <string>標準で使用可能なもの |
---|
default | 自動的に適切なものを選択 |
bilinear | 線形補間 |
spline36 | 6x6 Spline補間 |
nppi64_80.dll導入で追加されるもの(x64のみ) |
---|
nn | 最近傍点選択 |
npp_linear | nppの線形補間 |
cubic | 4x4 3次補間 |
cubic_bspline | 4x4 3次補間 (B=1, C=0) |
cubic_catmull | 4x4 3次補間 (B=0, C=1/2) |
cubic_b05c03 | 4x4 3次補間 (B=1/2, C=3/10) |
super | nppのsuper sampling(詳細不明) |
lanczons | Lanczos法 (参照点数不明) |
・Knn(K nearest neighbor)ノイズ除去を追加。(--vpp-knn)K nearest neighborなる方法によるノイズ除去。強めのノイズ除去を行いたいときに使用する。
--vpp-knn [<param1>=<value1>][,<param2>=<value2>],...パラメータradius=<int>
適用半径。1-5の範囲で指定、デフォルトは3。
strength=<float>
フィルタの強さ。0.0-1.0の範囲で指定、デフォルトは0.08。
lerp=<float>
ノイズ除去ピクセルへのオリジナルピクセルのブレンド度合い。0.0-1.0の範囲で指定、デフォルトは0.2。
th_lerp=<float>
エッジ検出の閾値。0.0-1.0の範囲で指定、デフォルトは0.8。
使用例(すこし強め): --vpp-knn radius=3,strength=0.10,lerp=0.1
・正則化PMD法によるノイズ除去を追加。(--vpp-pmd)--vpp-pmd [<param1>=<value1>][,<param2>=<value2>],...正則化pmd法によるノイズ除去。弱めのノイズ除去を行いたいときに使用する。
パラメータapply_count=<int>
適用回数。デフォルトは2。
strength=<float>
フィルタの強さ。0-100の範囲で指定、デフォルトは100。
threshold=<float>
フィルタの閾値。0-255の範囲で指定、デフォルトは100。
使用例(すこし弱め): --vpp-pmd apply_count=2,strength=90,threshold=120
・ガウシアンフィルタを追加(x64のみ)。(--vpp-gauss)--vpp-gauss <int>nppi64_80.dll導入が必要。
適用サイズを指定してガウスフィルタをかける。サイズは3,5,7のどれか。
・エンコード終了時に各フィルタの平均所要時間を表示するオプションを追加。--vpp-perf-monitorこれを使用するとエンコード全体としては若干遅くなるので注意。
フィルタ実行速度
入力MPEG2 1920x1080 29.97fps
環境 OS | Win10 x64 | Win10 x64 |
CPU | i7 5960X | i7 4770K |
Core | 4.2GHz | 4.2GHz |
UnCore | 3.6GHz | 4.0GHz |
GPU | GTX 1060 | GTX 960 |
コア数 | 1280コア | 1024コア |
ベースクロック | 1506MHz | 1177MHz |
ブーストクロック | 1709MHz | 1240MHz |
メモリクロック | 8008MHz | 7010MHz |
メモリ帯域 | 192.2GB/s | 112.1GB/s |
フィルタ速度 (1フレームの処理時間 [単位: us ( = 1/1000 ms)]) | GTX 1060 | GTX 960 |
copyHostToDevice | 327.2 | 518.6 |
copyDeviceToDevice | 48.8 | 86.8 |
vpp-resize | 1080p→720p | spline36 | 379.0 | 637.7 |
bilinear | 57.2 | 91.4 |
nn | 218.5 | 770.7 |
npp_linear | 163.1 | 783.4 |
cubic | 297.6 | 1066.1 |
lanczos | 639.4 | 1661.9 |
vpp-delogo | BS11 | 8.8 | 14.8 |
vpp-knn | radius | 1 | 374.2 | 624.9 |
2 | 838.7 | 1443.7 |
3 | 1524.8 | 2553.2 |
vpp-pmd | apply_count | 1 | 838.4 | 1416.3 |
2 | 1101.6 | 1876.6 |
3 | 1356.7 | 2271.5 |
vpp-gauss | size | 3 | 198.7 | 890.5 |
5 | 339.2 | 1106.0 |
7 | 404.2 | 1117.8 |
という感じで"--vpp-perf-monitor"でとりあえず測定してみたけど、速いのかな、これ。1000us割ってれば、1秒間に1000フレーム処理できると考えればたしかに速いかもしれない。あと、Pascal (GTX1060)がMaxwell (GTX960)に圧勝しているのが目を引く。
まあ、NVENCのエンコーダーより速ければ、「フィルタかけても遅くない」が実現できるので、それでいい気がする。
ダウンロード>>ダウンロード (ミラー) >>OneDriveの調子がいまいちの時はミラー(GDrive)からどうぞ。同じものです。ソースはこちら>>