はじめに(TL;DR)
最近、GTX1660ti買いました。それまではRadeon7970を使っていましたが、技術の進歩は素晴らしいですね。GTX1660tiのグラフィック処理能力も(Radeon7970と比較して)素晴らしいものですが、GPUエンコードの能力も昔(2013~2014年頃)と比較して素晴らしいものになりました。
これを見ている皆さんはご存知かもしれませんが最近のGPU(Geforce)は、CUDAとGPUエンコード/デコードが独立しており、何かしらのゲームをしながら同時にYoutubeを見たり、ゲームをキャプチャして録画or配信も余裕で出来るようになりました。
また、昔のGPUエンコードを使ったことある方ならわかりますが、画質なんて10Mbps積んでもようやく見れるかどうかというとても酷いものでした。しかし、現在のGPUエンコードはHEVCにも対応しており、品質もCPUエンコードと比べて遜色ないものになりました。私は
rigaya氏のNVEncを利用しています。
さすがに、極めて細かい点(ファイルサイズ、1フレーム単位でみた動画の画質の比較)を比較するとCPUエンコードが優りますが、文字通り極めて細かい点ですし、どうしてもCPUではないとイヤだ!という場合でなければGPUエンコードでも全く問題ありません。
しかし、GPUエンコードが進化したことによって別の問題が発生するようになりました。それは、Avisynth自体のデコード速度です。
CPUエンコードで品質と処理速度を両立しようとすると、どう頑張っても最大エンコード速度が 20 frame/sec 程度となり、Avisynthのデコード速度が別にその程度でもCPUエンコードがどちらにしろボトルネックになるので、別にAvisynthのデコード速度なんてあんまり考えなくても大丈夫でした。
しかし、今では妥協しない品質の設定でGPUエンコードを行っても 200~300 frame/sec とか余裕でエンコード出来るようになり、むしろボトルネックがAvisynthのデコード速度となりました。
そこで今回は、主にアニメなど24pへのソースを想定しながら、60iから30pへの高いクオリティでのデインターレース(インターレース解除)を行いながらも、高速なデコードを速度を両立したデインターレース方法を紹介したいと思います。
Avisynthでのデインターレースと新しい自分なりのインターレース解除の方法
まずは自分の環境
Avisynth+ 3.6.0 64bit
CPU:3930K
GPU:1660ti
MEM:32GB
TIVTC.dll の x64版 は、pinterf氏の .dllを使っています。この dll の中に TFM 、TDeint 、IsCombedTIVTC などの関数があります。
また、今のうちに書いておきますが yadifmod2.dll の x64版 は asd-g氏の .dll 、nnedi3.dll の x64版 は jpsdr氏の .dll を使っています。
主なデインターレースの方法
Avisynthのデインターレースには、主に有名な方法で、
- TFM
- TDeint
- nnedi3
- yadifmod2
などがあります。メジャーなのはこんな感じですが、他にもあるので気になる方は調べてみてください。
それぞれ一長一短があり、品質が良いけれども処理が遅いとか、その逆もあります。
新しい自分なりのインターレース解除の方法(コード)
自分なりの新しい方法はこちらです。
LoadPlugin("TIVTC.dll")
##ここに何かしらの60iビデオソース##
ConditionalFilter(DoubleWeave().SelectOdd(), last,"Crop(0,250,0,-180).IsCombedTIVTC()", "=", "true")
#ConditinalFilterの部分が新しい自分なりの方法です。
「くっさ!こんな簡単そうなコードで良いインタレ解除出来るわけ無いやろ!」とか思うのは当然だと思います。
でも自分が研究してみた限りでは、これがいい方法だったんですよね・・・
関数の内容自体は、 IsCombedTIVTC() でインターレースなフレームかプログレッシブなフレームか判定し、インターレースなフレームのみに対し DoubleWeave().SelectOdd() をかけています。
Crop(0,250,0,-180) をしているのは、右から流れるテロップとか、特にBS11に出るAnime+のロゴに誤爆対策にわざとトリミングしてインターレースかプログレッシブか判定を行っています。
技術的な詳細はこちら
こちらや、こちらがわかりやすいのですが、特に元は24pのソースを60iで放送している場合、任意の5フレームを抽出した内、3フレームはプログレッシブなフレーム、2フレームはインターレースなフレームです。
1t | 2t | 2t | 3t | 4t |
1b | 2b | 3b | 4b | 4b |
60iなソースから任意に抽出した5フレームをフィールド単位に分割したイメージ
tはtop、 bはbottomの略
欲しいフレームは2フレームのインターレースなフレーム(この場合は、2tと3bと、3tと4bがインターレースなフレーム)を、プログレッシブなフレームに変えて、5フレームの内5フレームともプログレッシブなフレームに変えたものです。
1t | 2t | 3t | 4t | 4t |
1b | 2b | 3b | 4b | 4b |
5フレームともプログレッシブなフレームに変えた場合のイメージ
ということは、インターレースなフレームと判定された場合にのみインターレース解除を行えばよいわけです。
ここで、インターレースなフレームと判定するために IsCombedTIVTC() を使っています。
もちろん全てのフレームに対しまずは IsCombedTIVTC() をかけなければ行けないため、そのために ConditinalFilter を使っています。
Cropの部分は前述の通り、誤爆対策です。
その後のインターレース解除は、Doubleweave() でフィールドを合成し、奇数フレームのみプログレッシブなフレームができるため SelectOdd() でプログレッシブなフレームのみ抽出しています。
古典的ですがシンプルで一番キレイな方法です。
デコード速度と画質の比較
初期条件
TFM、TDeint、nnedi3、yadifmod2 と 今回の ConditinalFilter関数でのデインターレースを用いて、比較を行います。
映像ソースは、とある科学の超電磁砲TのTSソース(1920x1080)のOP部分のみで、フレーム数は2696フレームです。
それぞれの関数の内容は以下のとおりです。
ConditionalFilter(DoubleWeave().SelectOdd(), last, "Crop(0,250,0,-180).IsCombedTIVTC()", "=", "true")
TFM(mode=5,pp=7,slow=2,blockx=4,blocky=4,MI=16)
nnedi3(field=-1,nsize=4,nns=4)
TDeint(mode=0,order=-1, field=-1)
yadifmod2(order=-1,field=-1, opt=3)
TDeintとYadifmod2は少しいい加減な設定
デコード速度
最初にデコード速度です。
デコード速度は数値が高ければ良く、処理時間は小さければ良いです。
AVSMeterでデコード速度をそれぞれ1回のみ測りました。
以下の表に示します。
順位は、表の通り
① Yadifmod2
② 今回の関数
③ nnedi3
④ TFM
⑤ TDeint
流石Yadifmod2と言ったところでしょうか、0.1秒の差ながら自分の作った関数よりも速いです。
個人的には nnedi3 が一番遅いのかなと思っていましたが、 jpsdr氏の最適化が進んでいるためか NN で計算速度多そうながらも思ったより速かったです。
ここで処理速度が一番良いのは Yadifmod2 であることはわかりましたが、次は画質の面で比較しましょう。
処理速度が良くても画質が悪ければ意味ないですからね。
画質面での比較
プログレッシブなフレームでの比較
最初は、プログレッシブなフレームで比較してみましょう。
まずはその最初のオリジナルなフレームから。
至って普通ですね。プログレッシブなフレームです。
次に、今回の関数で見てみましょう。
今回の関数は、プログレッシブなフレームは全く触らないようにしているので、左上の字幕以外は全くの同じです。もし違いがわかる方が居たら教えて下さい。
次に TFM で見てみましょう。
TFMで見ても、気持ちプラセボレベルで変わったかな・・・?というぐらいです。99%は同じでしょう。
処理速度は遅いものの、プログレッシブなフレームでの品質は良いですね。
次に nnedi3 で見てみましょう。
結構変わりました。御坂の脚の部分の線と、原作者の文字がオリジナルと比較して結構変わっています。
わかりやすい点は、レールガン独特の明朝フォントが潰れた形になり、NNを使ってもこのような細かい補正は難しいことが伺えます。
次に TDeint で見てみましょう。
nnedi3 ほど文字は潰れていないものの、オリジナルのフレームと比較してみると御坂の脚の部分の黒い線にノイズが少し載っているのがよく見ると分かると思います。すこしぼやけてノイズがかかっているような感じですね。
また、御坂の服の薄い線がオリジナルと比べてやや薄くなっています。
次に Yadifmod2 で見てみましょう。
はい、御坂の脚の部分にコーミングノイズが載っています。オリジナルと比較してもすぐに分かるのではないでしょうか。オリジナルと比較しても御坂の服の薄い線の書き込みがぼやかした状態になり、いくら処理速度が速いと言っても個人的に常用としては採用し難いです。
個人的な主観ではありますが、オリジナルのプログレッシブなフレームの品質を100点満点とすると、それぞれのフレームの品質は以下の表となります。
関数 | 点数 |
オリジナル | 100 |
今回の関数 | 100 |
TFM | 99 |
nnedi3 | 70 |
TDeint | 75 |
yadifmod2 | 55 |
プログレッシブな場合の得点表
結構、プログレッシブなフレームでも処理によっては少し画質が下がることがわかりました。
デインターレースの処理を行う以上、どうしても画質の低下は避けられない話にはなりますが、あまり下がりすぎるというのもよくありません。
そのような意味において、今回の関数はインターレースだとは判定されない限りは全く手をつけないので、少なくともAvisynth上においてオリジナルのフレームと同等の物を維持できます。
次にインターレースの場合の画質を見てみます。
インターレースなフレームでの比較
オリジナルのインターレースなフレームを見てみます。
はい。わかりやすいインターレースなフレームですね。これを元にしてデインターレースを行い、画質の比較を行います。
今回の関数の場合を見てみましょう。
御坂が前に行っているフレームを抽出したようですね。
理論的にはこのフレームが綺麗にデインターレースできたフレーム・・・のはず・・・
TFMでデインターレースした場合を見てみましょう。
これ以降、基準フレーム + 1フレーム のフレームを抽出しています。例えば、これよりも上の2枚が50フレームの所を参照していたならば、この1枚の画像は51フレームの所を参照している形です。本来ならば同じフレームを以て比較すべきですが、それだとインターレースの仕様上、アニメの絵が1コマズレる形になり、画質の比較が困難な為やむを得ず1フレームだけズラしています。予めご了承ください。
画質の内容ですが、とても素晴らしく綺麗にデインターレースできていると評価しても良いでしょう。本当に処理時間がネックです。
次に nnedi3 を見てみましょう。
御坂の服の薄い線が少しぼやけているのと、プログレッシブな場合と同じくフォントが潰れているのが分かると思います。
次に TDeint で見てみましょう。
御坂の脚の部分が、これもプログレッシブの場合と同じくややノイズというか、ジャギっているのがわかると思います。文字は潰れていませんし、ジャギー以外は全くもって問題ありませんが、今回の関数と比較するとやや劣ると言えるでしょう。
次に、yadifmod2 を見てみましょう。
御坂の服の部分の線が潰れているのが分かると思います。また、TDeintのインターレースなフレームと比較してみると、ジャギーもコーミングノイズも増えています。今回の関数でのデインターレースがスッキリしていると感じられるのに対し、これはノイズなどの情報量が増えていると感じられても仕方ないでしょう。
個人的な主観ではありますが、今回のデインターレースされたプログレッシブなフレームの品質を100点満点とすると、それぞれのフレームの品質は以下の表となります。
関数 | 点数 |
今回の関数 | 100 |
TFM | 99 |
nnedi3 | 75 |
TDeint | 85 |
yadifmod2 | 60 |
インターレースな場合の得点表
まとめ
以上の比較より、結果の表と得点付け、最終的な総合順位をまとめていきます。
今回は、処理速度と画質の両立を狙って総合順位を付けます。
見ている方によって意見は分かれると思いますが、その場合は自分で順位を付けてみてください。
関数 | デコード速度(frame/sec) | 処理時間(sec) | プログレッシブ得点 | インターレース得点 | 総合順位 |
ConditinalFilter and TIVTC (今回の関数) | 411.2 | 6.557 | 100 | 100 | ① |
Yadifmod2 | 416.4 | 6.457 | 55 | 60 | ④ |
nnedi3 | 54.0 | 49.961 | 75 | 70 | ② |
TFM | 20.2 | 133.572 | 99 | 99 | ③ |
TDeint | 19.8 | 136.383 | 85 | 75 | ⑤ |
結果と総合順位
今回の関数は、処理速度も速く、画質も良いので1位となりました。
Yadifmod2は、処理速度は1番速いですが、画質はいずれも悪く、4位となりました。
nnedi3は、処理速度はこの中では速い(と言っても今回の関数とyadifmod2の7~8倍かかりますが)、ですが文字が潰れる欠点があるので2位となりました。
TFMは、画質は良いものの処理速度が遅いため、3位となりました。
TDeintは、器用貧乏と評価さぜるを得ず、5位となりました。
無論この順位にはいろいろ意見があると思いますが、それでも今回の関数が良いのは揺るがないと思います。
この関数を使ってみて、良いエンコードライフを送っていただければ幸いです。
多くの方はデインターレースした後、逆テレシネの作業に入ると思いますが個人的には、NVEncの --vpp-decimate の blockx, blocky を 4 か 8 にした上で処理にかければ速く誤爆せずに逆テレシネ出来ると思います。
参考(AVS Meterの結果を貼り付けているだけ)
見たい人はどうぞ
今回の関数のAVS Meter Benchmark.
yadifmod2 のAVS Meter Benchmark.
nnedi3 のAVS Meter Benchmark.
TFM の AVS Benchmark.
TDeint の AVS Benchmark.
Written with
StackEdit.