OBMCについて
具体的な実装の細部までは分かりませんが、概念的にはだいたいこういうことだそうです。
DivX、XviDなどの動画で、ビットレートが足らないときなど、もともとそんなものはないのに、マス目状の線が出てしまうのは、 よく見かけると思いま す。ブロック単位に分割してから各ブロックを処理しているので、ブロックの中身をきめ細かにしてとなりのブロックと滑らかにつながるようにできるだけの情 報量がないと、ブロックの境界の線が目立ってしまうわけです。
MPEG-1ではブロックのサイズが固定(のっぺりしていておおざっぱに切ればいいところも同じに切るし、複雑なところで繊細に処理 してほしいところでも 細かく切ってくれない)なのですが、新しいコーデックでは、ブロックサイズを都合に合わせて動的に変えたり、長方形にしたり…と、 これはx264 (AVC)のユーザなら、設定の検索オプションのところで、いっぱい種類があるのをよくご存知と思います。
しかし、可変ブロックであっても、ブロック境界があることには変わりないので、効率は上がったとはいえ、原理的にブロックノイズが回 避できているわけでは 全然ないわけです。
AVCやWMVやRV10では、それを緩和するために、インループ・フィルターをかけています。特にRV10ではインループが明示的 に設定できるので、気 が付いた方も多いと思いますが、自分がエンコードした結果を自分で(エンコード中に)デコードしてみて、ブロックノイズの原因になる誤差が蓄積していない か確認し、必要に応じて補正をかけるわけです。 AviUtlなどのノイズフィルターなどは、コーデックに行く前にかけるプレフィルターですし、 ffdshowなどの後処理はコーデックから出てきたデコード結果を調整するものですが、インループは前でも後でもなくコーデック自体の中でかけている フィルターです。
しかし、このデブロッキングというのは、案外、実写とは相性が悪いです。ブロックノイズが出ない代わり、繊細なテクスチャー、人の肌 のきめなどがツルンと してしまいます。ただ、たいていのアニメでは、もともとツルンとしているので、この(本来は欠点の)性質がかえってランダムノイズを消して、良い感じに なってくれます。実際、ソースのノイズがデブロッキングの副作用(副作用の副作用?)で勝手に消えてくれることさえあります。とはいえ、自分で発生させた ブロック境界を消すための補正情報にレートを回すのは、巧妙ですが、本質的には無駄です。自分でノイズを作っておいて、それの消し方をコーディングするわ けですので。最初からブロック境界がなければそういう二度手間にならず、自分で汚したものを直すのに必要な情報量を、本質的なテクスチャーに回すことがで きます。
で、SNOWが実装したOBMCですが、 OBMCは、本当はh263にも規格上はあったそうなのですが、実際には使われなかったようです。 GMC同様h264では規格から外されてしまいました。
名前のとおり、オーバーラップしたブロックの動き補償です。碁盤の目のようにきっちり切るのでなく、各ブロックが少しずつ(上下左右 斜めの8方向とも)重 なって定義されています。言い換えれば、古典的な切り方での境界付近のピクセルは、実は両側のブロックに属しているわけです。一般に、各ピクセルは4ブ ロック(実装によっては3ブロック)に同時に属し、それらの加重平均をとることで、区切りの線が目立たず「とろんと」滑らかになります。段差ができる原因 が最初から回避されているわけです。段差を補正するインループ回路も確かに巧妙で効果的ですが、最初から段差ができないようなブロックを重ね合わせた取り 方、というのは本質的に素晴らしい発想でしょう。ただ、一つのマクロの動きを何重にもコーディングして、デコードのときにも重ね合わせて平均をとるので、 計算量(CPU負荷)の問題はありますが、まあ、少し未来にはハードが発達して何とかなるのではないでしょうか。
「波」の重なりで図形を表すウェーブレットも、そうした従来型のアーティファクトを克服するのに貢献するはずです。まあ、これも計算 量が大変そうです が…。
開発者の方から説明してもらったことを生半可な理解で受け売りしているのでちょっと(かなり)間違ってるかもしれませんが、あの SNOWの「とろん」とし た雰囲気と異様な美しさは、だいたいそんなような感じ…らしいです。そして、その計算がたいへんというのは、計算量が多くてもリニ アの計算なので、 GPUでハード的に実装するのは原理的には簡単らしいです。そうすればCPU負荷も問題にならないはずです。
MEncoder で使えるインタレ 解除としては間違いなく最高の部類。こうかはばつぐんだ。ただし、手許ではx264より遅く、実用には耐えない。
インタレ解除のくせに8x8ブロックにqpelに複数参照まである。 訳しながら笑ってしまった。ビグザムだビグザム。完成の暁には!(不吉)
MEncoderマニュアルの説明
mcdeint=[mode[:parity[:qp]]]
動き補償デインターレーサ。
1フレームにつき1フィールドの入力が必要となるので、tfields=1 や yadif=1/3、または同等のものと一緒に使う必要がある。
- <mode>
- 0: 高速
1: ミディアム
2: 低速, 反復動き予測
3: 超低速、複数参照フレームを2以上にしたのと同等。
- <parity>
- 0 または1でどちらのフィールドを使うかを指定(note:自動検出はまだ無い!)
- <qp>
- 高い値ほどモーションベクトルがスムースになるが、個々のベクトルは最適ではなくなる。
開発者、Michael's Niedermayerによる解説
mcdeint は “missing” line を埋める為に動き予測と動き補償をやる。
うまく動き予測をするには、元になる映像が要る。
単純に奇数/偶数ラインを使う手も試したがうまくいか なかった。単純にフレームレートを倍増させるデインターレーサですら、mcdeintの後では向上が見られた。
mcdeint はオーバーラップド・ブロック・ベースの動き予測と動き補償を使う。このコードはsnowのコードから持って来た。だから、snowに進展があれば自動的にmcdeintも進化する。
mcdeint=0 :オーバーラップド・ブロック予測/補償を使わない。16×16 blockの 1/4精度。
mcdeint=1 :8×8 blockサポートを追加、予測ゾーンサーチのダイヤモンド・サイズを拡大。
mcdeint=2 :反復的オーバーラップド・ブロック・ベースの動き予測と動き補償
mcdeint=3 :複数参照(*multiple reference frames*)を追加
Comment by Michael — June 21, 2006 @ 19:16
![]() |
左は料理番組の冒頭でCGのタイトルが出るシーン。 赤い球体が画面に侵入してくるが、図の通り縞がある。コマ送りで見ても縞の消える瞬間が無い。中華鍋を振る料理人の手も同様。どちらも1/60秒の間にこれだけ動いてると言う事だ。 CG製作の時点でこうしたシマシマデータを作るわけが無いので(できなくは無いが無駄)、TV用に合成する段階で切り刻まれている。コックさんが「物理的にこういう手の人」だったという可能性も無くは無いが稀であろう。 もともとTVカメラの走査線は一本飛ばしで映像を捉える。空間軸画質を最初から大胆に間引いてあるのだ。パソコンの言い方で言うと、解像度が 720x480あったとしても、一枚のフィールド上の実データは720x240しか存在しない。もしも正確にフィールドだけを表示できるなら、ブラインド越しに見たような絵しかでてこないハズだ。これが上で言う"missing" lineの意味。 インタレ解除の本質は「失われたデータの復元」ではなく「もともとこの世に存在しないデータのでっち上げ」。 余談ながら、インターレースはもともとブラウン管の構造に則したしかけ。電子銃による管面走査機構のない機械に余分な機構を強いる。これは液晶、PDP、 SEDを問わない。高柳健次郎博士御存命なれば、地デジ規格は断然 1080p/720p@30fps以上を主張されたであろう。 |
-vf yadif=3,mcdeint,framestep=2 -ofps [素材fps]
MEncoderで使えるインタレ解除フィルタの中では、 抜群だ。
理屈を読むとかなり無駄っぽい印象を受ける上にいーのかそれでという感じもあるが、フィールドを半分捨てるといってもフレーム内の大部分のデータは重複しているものだし、必要な部分は動き補償で(単純なブレンドなどでなく)出力されるフレームに加味されている。時間軸fps混在だの空間軸fps混 在だのの厄介ごとを気にせず、とりあえず、オールラウンドに使っても相当の性能を発揮する。
手許の実写は落語が多いので、細かい動きのジャギが気になりがちなのだけれど、yadif単独では地味に気になっていた唇の端っこのジャギやズーム時のちらつきなどが緩和した。
なお、少なくとも動作原理 上、pullupとの併用は無意味と考えられる。pullupは素材映像の中のテレシネパターンを頼りに元の film映像を復元するものだ。その後でyadif,mcdeintをかけると画質劣化のデメリットのほうが大きく、yadif,mcdeintの後では テレシネパターンが残っていない。逆テレシネはテレシネ素材にしか効かず、逆テレシネが効くならインタレ解除は適切ではない。映画とアニメはpullup を軸にした方が良さげ。
桁違いに遅い。x264より重い。
手許(Power PC G5, 2Ghzx2)では1分半のクリップに2時間以上。turbo使用の1stと、より重い2ndがきっちり1時間ずつと同じだったので、mcdeintが最 大のボトルネック。CPU利用効率も激減していた。速度を計算すると0.0xfpsと文字通り桁違い。mcdeint を使うなら事前に中間生成物で吐くべきだろう。
また、インタレ解除である以上は「もともとこの世 に存在しないデータのでっち上げ」という限界があるのでpullupに比べれば印象はやはり落ちる。
MEncoder ユーザーメーリングリストでもyadif単独がいまのところ最も実用的なのではという意見が一般的なようだ。
そこで、yadif=3でフィールドをフレーム化し、 framestep=2で半分捨てる手を軸に、間に挟む調整(前後フィールドから必要なデータを持って来る)にmcdeint以外のものを使う手はどうかと思った。例えば、
-vf yadif=3,pp=l5,framestep=2 -ofps [素材fps]ま たは、
-vf yadif=3,framestep=2,pp=l5 -ofps [素材fps]
pp=l5に全フィールドを見させるなら前者。データの混合を実際に残るフレーム同士に限りたければ後者。
なお、pp=l5を重用しているのは それが最も優れているからというわけではないです。手許でビルドしたMEncoderではkerndeintやfilmdintがなんか動作が怪しいだけです。
ちゃんと動作するなら、kerndeintのピ ンポイント縞除去や、filmdint=io=2997:2997にした上で、 dint_thresを調整した方が良いかも知れません(yadifの後ならテレシネパターンなど残っていないから、インタレ解除しか作動できないハズ)。
気になる速度面ですが、やっぱ倍増しますなyadif単独にくらべると。-vfチェイン内だけとはいえ、書き出しフレーム数が倍増してるわけだし。一方面白い事にCPU利用効率がyadif単独の30fpsより上がりました。threads=4と一緒に使うとCPUメーターが天井に張り付きっぱなしの 185~195%になります。たぶんx264の処理速度といい感じにバランスするのでしょう。処理密度とか、命令粒度とかいうのかな。