自動フィールドシフト 高速化 7.5a+20
この前は、自動フィールドシフトではいろいろやってだいぶ速くなったのだけど、これ以上は速くするのが難しくなってきているという話だった。
ただ、実はまだ方法が残っているといえば残っていて、実際にコメントを頂いたこともあった。そこで、もう少しやってみたというのが今回。やったのは2つで、
・YUY2フィルタモードへの対応して高速化。
・通常(YC48)モードで高速な簡易解析モードを追加。
どういうことなのかをちょっと書いていく。
AviutlのYUY2フィルタモード
Aviutlはふつう、編集で使うために内部で持っているフレームをYC48という形式で持っている。これは言ってみれば12bitのYUV444の亜種なので、高精度だがデータサーズとしては非常に重い。
一方、YUY2フィルタモードは、Aviutlで内部で持っているフレームをYC48でなくYUY2にする。YUY2は8bitのYUV422なので、データサイズは1/3になる。
YUY2フィルタモードへは、Aviutlの設定画面から切り替えることができる。(下から2つ目)

もちろん、その分、編集時の精度が落ちてしまうという問題がある。ただ、データサイズが1/3になるだけあって、高速化には非常に効果がありそう…ということで、自動フィールドシフトのYUY2フィルタモード対応をやってみた。
自動フィールドシフトのYUY2フィルタモード対応
自動フィールドシフトのYUY2フィルタモードでの処理の流れを、通常の内部YC48モードと比較するとこんな感じ。

まあ、流れとしてはいままでと同じで、単に入出力フレームがYUY2になるだけ。
ただ、問題は、かなり複雑な処理になっている「scan_frame」の処理と自動フィールドシフトの「解除レベル」ごとに処理の異なる「blend」の処理のところでSIMDコードを全部書き直さないといけないというところ。…かなりしんどかった。
YUY2フィルタモードの問題点
実際に作ってみると、ちゃんと速くはなる(後述)のだけど、やはり縞や動きの判定などで、少し差が出てしまう。この原因は2つあって、
・縞や動きの判定を12bitでやっていたのが8bitに。
4bit分精度が落ちているので、設定する閾値に対する応答が離散的(あるところで判定結果が急に変わるような感じ)になって、差が出てしまう。すこし調整しづらいことも?
・色差が横方向に半分に間引かれているので、そのぶん横方向の解像度が落ちている。
少し判定領域が横に広がりやすくなっている。
という理由で、わりとどうしようもない気がする。
実際に比較するとこんな感じ。(自動フィールドシフトを「調整モード」を有効にして判定結果を見た場合)
通常(YC48)モード

クリックで拡大
YUY2フィルタモード

クリックで拡大
とまあ、若干差があるのがわかると思う。
先程も書いたけど、8bit化の影響で、閾値を変えたときの応答が変わり、あるところで判定結果が急に変わるような感じになってしまってい、調整しづらくなっている。なので、特に縞の判定などで小さい閾値を使っている場合には、調整しづらく、ちょっと使えないといったこともあるかもしれない。
YUY2フィルタモードのもうひとつの問題は、AviutlのYUY2フィルタモードでは使える他のフィルタの数がとても少ないということ。まあ、YUY2フィルタモードはおまけのような位置付けのようなのでしょうがないのだけど…。
YUY2フィルタモードのオンオフで、有効になっているフィルタを比べるとこんな感じ。

だいぶ少なくなってしまっていて、これだとほとんどフィルタはかけられない…。
Aviutlの通常(YC48)モードに高速簡易解析モードを追加
ということで、やはりYUY2フィルタモードは、使えるフィルタが限られていて、使いにくい。
そこで、通常(YC48)モードで、解析だけYUY2フィルタモードでやるという、両方の合いの子みたいなことをやって「高速簡易解析モード」というのを追加した。
具体的な処理の流れは下の図のピンクの矢印のような感じで、AviutlからYC48でフレームを受け取り、インタレ解除後のフレームもYC48で出力するが、自動フィールドシフトの内部ではYUY2フィルタモードのときのように8bit/YUV422で持つようにしてみた。内部でYC48から一度8bit/YUV422に落とすことになるけど、そもそもインタレ解除はフィルタ処理の最も最初に行うので、インタレ素材のほとんどが8bit/YUV420であれば、そこは問題にはならないと思う。

こうすると、YUY2フィルタモードほどではないが、ある程度高速化しつつ、ほかのフィルタとの組み合わせも使用できるようになる。ただ、縞や動きの判定方法はYUY2フィルタモードのときと変わらないので、閾値の問題はYUY2のときと同じ。
高速化結果
じゃあ実際どんだけ速くなるの、という話。
計測環境
その他計測環境・計測条件
Aviutl 1.00
入力プラグイン: L-SMASH Works r917 (POP氏ビルド)
入力: MPEG2 1920x1080 29.97fps 10240フレーム
一発勝負
i7 4770K
r20 簡易 = 通常(YC48)モード + 簡易高速解析オン
r20 yuy2 = YUY2フィルタモード

i7 6700K
r20 簡易 = 通常(YC48)モード + 簡易高速解析オン
r20 yuy2 = YUY2フィルタモード

というわけでまあ、久しぶりに大幅に速くなった。YUY2フィルタモードが非常に速いのはもちろん、通常(YC48)モードの簡易高速解析でもかなり速くなったことがわかる。ひとつの目標であった5msを割れてとてもうれしい。
大量にSIMDコードを書きまくる羽目になって疲れたが…。
まあ、YUY2モードや簡易モードは若干精度が落ちるので、気になる人は使えないかもしれないが、速度重視の場合には使えるんじゃないかなあ、と思う。
というわけで需要があるか謎だけど公開しておく。
7.5a+20の変更点
・YUY2フィルタモードに対応した。
・処理モードを選択できるようにした。
フル解析 / 簡易高速解析
・サブスレッド数を指定できるようにした。
scan_frame以外の部分のスレッド数。たいてい1~2で十分。"4"は、i7 5960Xなど、4chメモリーを持つPC用。
・設定をファイルに保存 / ファイルからロードできるようにした。
・save_stg_afs.exeを追加。
Aviutlのプロファイル(cfgファイル)から自動フィールドシフトの設定を抽出して保存する。

7.5a+20の注意点
・YUY2フィルタモード及び簡易高速解析モードは先程も述べたように判定が若干荒くなるのでご注意ください。
・YUY2フィルタモード及び簡易高速解析モードは、afs.aufのみの機能です。afsvf.aufからは利用できません。
・かなりデバッグしましたが、大きくいじっているのでまだバグがあるかもしれません…。
・従来の自動フィールドシフトを7.5a+20に更新すると、Aviutlのプロファイルに保存されている自動フィールドシフトの設定が消えてしまいます。これは、設定の数が増えると、保存されている設定を初期化してしまうAviutlの動作によるもので回避できません。
ただ、消えてしまうので、自分でなんとかしてね、というのはさすがにないかなと思ったので、プロファイル(具体的にはAviutlのcfgファイル)から、"自動フィールドシフト"と"自動フィールドシフトVF"の設定を抽出して保存するプログラムを作成しました。
プロファイルの設定を保存するには、7.5a+20の導入前に、Aviutlフォルダの中にsave_stg_afs.exeをコピーして、ダブルクリックして実行してください。そうするとすべての「プロファイル名.cfg」ファイルに対して、「プロファイル名.cfg.afs.ini」という名前で、現時点での自動フィールドシフトの設定が保存されます。
その後、7.5a+20を導入して、自動フィールドシフト右側の「設定ロード」からロードしたいプロファイルのiniファイルを選択してください。もとの設定がロードされます。
※save_stg_afs.exeはダウンロードしたzipファイルに同梱してあります。
ダウンロード>>
ダウンロード (ミラー) >>
ソースはこちら。
ソースを見るとOpenCLでごちゃごちゃなんかやってますが、まだうまくいってません
というわけで、執念深く(?)やってきたおかげで、だいぶ速くなってきたのではないかと思う。自動フィールドシフトが「遅い」と言われない時が来ることを願って、今後も頑張りたい。
なんならAviutlの24fps化最速を目指したいがさすがに無理か…。
ただ、実はまだ方法が残っているといえば残っていて、実際にコメントを頂いたこともあった。そこで、もう少しやってみたというのが今回。やったのは2つで、
・YUY2フィルタモードへの対応して高速化。
・通常(YC48)モードで高速な簡易解析モードを追加。
どういうことなのかをちょっと書いていく。
AviutlのYUY2フィルタモード
Aviutlはふつう、編集で使うために内部で持っているフレームをYC48という形式で持っている。これは言ってみれば12bitのYUV444の亜種なので、高精度だがデータサーズとしては非常に重い。
一方、YUY2フィルタモードは、Aviutlで内部で持っているフレームをYC48でなくYUY2にする。YUY2は8bitのYUV422なので、データサイズは1/3になる。
YUY2フィルタモードへは、Aviutlの設定画面から切り替えることができる。(下から2つ目)

もちろん、その分、編集時の精度が落ちてしまうという問題がある。ただ、データサイズが1/3になるだけあって、高速化には非常に効果がありそう…ということで、自動フィールドシフトのYUY2フィルタモード対応をやってみた。
自動フィールドシフトのYUY2フィルタモード対応
自動フィールドシフトのYUY2フィルタモードでの処理の流れを、通常の内部YC48モードと比較するとこんな感じ。

まあ、流れとしてはいままでと同じで、単に入出力フレームがYUY2になるだけ。
ただ、問題は、かなり複雑な処理になっている「scan_frame」の処理と自動フィールドシフトの「解除レベル」ごとに処理の異なる「blend」の処理のところでSIMDコードを全部書き直さないといけないというところ。…かなりしんどかった。
YUY2フィルタモードの問題点
実際に作ってみると、ちゃんと速くはなる(後述)のだけど、やはり縞や動きの判定などで、少し差が出てしまう。この原因は2つあって、
・縞や動きの判定を12bitでやっていたのが8bitに。
4bit分精度が落ちているので、設定する閾値に対する応答が離散的(あるところで判定結果が急に変わるような感じ)になって、差が出てしまう。すこし調整しづらいことも?
・色差が横方向に半分に間引かれているので、そのぶん横方向の解像度が落ちている。
少し判定領域が横に広がりやすくなっている。
という理由で、わりとどうしようもない気がする。
実際に比較するとこんな感じ。(自動フィールドシフトを「調整モード」を有効にして判定結果を見た場合)
通常(YC48)モード

クリックで拡大
YUY2フィルタモード

クリックで拡大
とまあ、若干差があるのがわかると思う。
先程も書いたけど、8bit化の影響で、閾値を変えたときの応答が変わり、あるところで判定結果が急に変わるような感じになってしまってい、調整しづらくなっている。なので、特に縞の判定などで小さい閾値を使っている場合には、調整しづらく、ちょっと使えないといったこともあるかもしれない。
YUY2フィルタモードのもうひとつの問題は、AviutlのYUY2フィルタモードでは使える他のフィルタの数がとても少ないということ。まあ、YUY2フィルタモードはおまけのような位置付けのようなのでしょうがないのだけど…。
YUY2フィルタモードのオンオフで、有効になっているフィルタを比べるとこんな感じ。

だいぶ少なくなってしまっていて、これだとほとんどフィルタはかけられない…。
Aviutlの通常(YC48)モードに高速簡易解析モードを追加
ということで、やはりYUY2フィルタモードは、使えるフィルタが限られていて、使いにくい。
そこで、通常(YC48)モードで、解析だけYUY2フィルタモードでやるという、両方の合いの子みたいなことをやって「高速簡易解析モード」というのを追加した。
具体的な処理の流れは下の図のピンクの矢印のような感じで、AviutlからYC48でフレームを受け取り、インタレ解除後のフレームもYC48で出力するが、自動フィールドシフトの内部ではYUY2フィルタモードのときのように8bit/YUV422で持つようにしてみた。内部でYC48から一度8bit/YUV422に落とすことになるけど、そもそもインタレ解除はフィルタ処理の最も最初に行うので、インタレ素材のほとんどが8bit/YUV420であれば、そこは問題にはならないと思う。

こうすると、YUY2フィルタモードほどではないが、ある程度高速化しつつ、ほかのフィルタとの組み合わせも使用できるようになる。ただ、縞や動きの判定方法はYUY2フィルタモードのときと変わらないので、閾値の問題はYUY2のときと同じ。
高速化結果
じゃあ実際どんだけ速くなるの、という話。
計測環境
OS | Win10 x64 | Win10 x64 |
---|---|---|
CPU | i7 4770K (4C/8T) | i7 6700K (4C/8T) |
CPU世代 | Haswell | Skylake |
Core | 4.0GHz | 4.3GHz |
UnCore | 4.0GHz | 4.1GHz |
キャッシュ | L3=8MB | L3=8MB |
メモリ | DDR3-1600, 2ch | DDR4-2933, 2ch |
CL | 8-8-8-24-2 | 16-18-18-34-2 |
その他計測環境・計測条件
Aviutl 1.00
入力プラグイン: L-SMASH Works r917 (POP氏ビルド)
入力: MPEG2 1920x1080 29.97fps 10240フレーム
一発勝負
i7 4770K
r20 簡易 = 通常(YC48)モード + 簡易高速解析オン
r20 yuy2 = YUY2フィルタモード

i7 6700K
r20 簡易 = 通常(YC48)モード + 簡易高速解析オン
r20 yuy2 = YUY2フィルタモード

というわけでまあ、久しぶりに大幅に速くなった。YUY2フィルタモードが非常に速いのはもちろん、通常(YC48)モードの簡易高速解析でもかなり速くなったことがわかる。ひとつの目標であった5msを割れてとてもうれしい。
大量にSIMDコードを書きまくる羽目になって疲れたが…。
まあ、YUY2モードや簡易モードは若干精度が落ちるので、気になる人は使えないかもしれないが、速度重視の場合には使えるんじゃないかなあ、と思う。
というわけで需要があるか謎だけど公開しておく。
7.5a+20の変更点
・YUY2フィルタモードに対応した。
・処理モードを選択できるようにした。
フル解析 / 簡易高速解析
・サブスレッド数を指定できるようにした。
scan_frame以外の部分のスレッド数。たいてい1~2で十分。"4"は、i7 5960Xなど、4chメモリーを持つPC用。
・設定をファイルに保存 / ファイルからロードできるようにした。
・save_stg_afs.exeを追加。
Aviutlのプロファイル(cfgファイル)から自動フィールドシフトの設定を抽出して保存する。

7.5a+20の注意点
・YUY2フィルタモード及び簡易高速解析モードは先程も述べたように判定が若干荒くなるのでご注意ください。
・YUY2フィルタモード及び簡易高速解析モードは、afs.aufのみの機能です。afsvf.aufからは利用できません。
・かなりデバッグしましたが、大きくいじっているのでまだバグがあるかもしれません…。
・従来の自動フィールドシフトを7.5a+20に更新すると、Aviutlのプロファイルに保存されている自動フィールドシフトの設定が消えてしまいます。これは、設定の数が増えると、保存されている設定を初期化してしまうAviutlの動作によるもので回避できません。
ただ、消えてしまうので、自分でなんとかしてね、というのはさすがにないかなと思ったので、プロファイル(具体的にはAviutlのcfgファイル)から、"自動フィールドシフト"と"自動フィールドシフトVF"の設定を抽出して保存するプログラムを作成しました。
プロファイルの設定を保存するには、7.5a+20の導入前に、Aviutlフォルダの中にsave_stg_afs.exeをコピーして、ダブルクリックして実行してください。そうするとすべての「プロファイル名.cfg」ファイルに対して、「プロファイル名.cfg.afs.ini」という名前で、現時点での自動フィールドシフトの設定が保存されます。
その後、7.5a+20を導入して、自動フィールドシフト右側の「設定ロード」からロードしたいプロファイルのiniファイルを選択してください。もとの設定がロードされます。
※save_stg_afs.exeはダウンロードしたzipファイルに同梱してあります。
ダウンロード>>
ダウンロード (ミラー) >>
ソースはこちら。
ソースを見るとOpenCLでごちゃごちゃなんかやってますが、まだうまくいってません
というわけで、執念深く(?)やってきたおかげで、だいぶ速くなってきたのではないかと思う。自動フィールドシフトが「遅い」と言われない時が来ることを願って、今後も頑張りたい。
なんならAviutlの24fps化最速を目指したいがさすがに無理か…。
スポンサーサイト