動画というのは、言うなれば画像の連続だ。静止画が連続していることにより、動きとして見えるわけだ。ここでもし、動画のある区間で、動きがない場合、フレームを連続させず、止めていても、人間の目には分からないはずだ。動きがほとんどない場合は、フレームレートを落としても、人間の目には分からない。逆に、動きが激しい場合、この場合は、フレームレートをあげたほうがいいはずだ。
どのような状況にもかかわらず、フレームレートを一定に保つことを、CFR(Constant Frame Rate)といい、フレームレートが可変であることを、VFR(Variable Frame Rate)という。
VFRは理にかなっていて、すばらしいのだが、世の中はいまだにCFRが多い。理由は、VFRにまともに対応しているソフトウェアが少ないからだ。
動画をエンコードする際、入力は既にVFRになっているとしよう。ここで言うVFRとは、ある区間がCFRの30fpsで、ある区間がCFRの60fpsというものではなく、本当に1フレームごとに時間が違っているような、VFR動画のことだ。
H.264にエンコードする場合の、現状はどうだろう。
x264は、動画ストリームをmp4やmkvコンテナに入れて吐くことができるが、VFRにはならない(非公式のパッチはあるにしても)。エンコーダ自体がVFRを取り扱ってくれるのが、理想なのだが、まず現状は、そう恵まれていない。
では、timecodeを出力して、別途、動画ストリームをコンテナにmuxするときに、フレームレートを設定するというのはどうか。mkvコンテナであれば、この方法はとてもうまくいく。最も有名なmkvmergeが、実に分かりやすいフォーマットのtimecodeを受け付けてくれるからだ。しかし、mp4コンテナは恵まれていない。最も有名なmp4boxが、mkvmergeのように分かりやすいtimecodeの入力をサポートしていないからだ。世の中には、現状を打開すべく、tc2mp4なるPerlスクリプトがある。しかし、これは私の理想とするところではない。このスクリプトが何をしているかというと、mkvmergeのtimecodeファイルを、NHMLに変換しているのだ。なぜこんな不便なステップを踏まなければならないのか。
また、AviSynthがVFRに対応していないので、x264にVFRを入力するのも一苦労する。おそらく現状では、フレームを重複させるなどして、一旦CFRに変換し、Decombプラグインで重複するフレームを脱落させてVFRにし(このプラグインはmkvmergeのtimecodeを吐いてくれる) 上記のステップを踏む形になるだろう。なんて無駄が多いのだ。
結局、VFRなH.264のmp4を作る場合、
- DirectShowSourceで、VFRを、フレームを重複させることでCFRにする。
- Decombというプラグインで重複フレームを削除、mkvmerge用のtimecodeを出力する。
- AviSynthの出力を、x264でエンコード。
- tc2mp4という、Perlスクリプトを使い、timecodeをNHMLに変換して、mp4boxで適用する。
どう考えても不便極まりない。
さらに絶望的なことに、こうまでしてVFRにしても、劇的な画質向上、ビットレート削減など得られないということだ。
第一、動画を、WUXGA(1920x1200)などの高解像度に拡大してコマ送りで再生し、
「おお、このうp主のエンコードは流石だな。職人芸を感じるぜ」
とか言いつつニヤニヤする奴など、いったい何人いるのだろう。やれやれ、しばらくはVFRをCFRに変換してエンコードしたほうが、楽そうだ。
制作段階でVFRならそのままVFRで保存するのが理想だけれど
ReplyDelete現実的にはそれでもVFRで扱わなくても、エンコーダの方が適当に圧縮してくれるんだから不要では?