トップ 検索 一覧 差分 ソース ヘルプ RSS ログイン

x264でp4x4を使用しない方がよい理由

このページの全ては誤っているかもしれません。x264関連の記事に関してを読んでください。

x264でp4x4を使用しない方がよい理由

かなり以前からp4x4は使うなと言われているし、x264のデフォルト設定でもp4x4は不使用になっている。さらには、一部のx264のフロントエンド(GUI)ではLevelが3以上の場合にp4x4を指定すると規格適合性に問題が出るという趣旨の警告が表示される。少し古い話ではあるが、p4x4の可否は若干ネット上での議論を醸した。

結論から言って、p4x4はSD未満(Level3.0未満)なら使用してもよいし、それなりに効果が期待できる。そして多少の疑問はあるものの、規格適合性の観点からLevel3.0以上では使用しないほうが無難だ。

この記事では、問題となる規格適合性に関して追ってみる。

 なぜ規格に適合しないか

基本的にLevelの定義は高いものほど制限が緩いはずなのに、Levelを上げると問題が出るとはどうしたことか、と疑問に思っていたのだが、doom9にakupenguin氏による答えがあった。

一言で言えば、その理由は規格書のTable A-1、MaxMvsPer2Mbの欄にある。

MaxMvsPer2Mbは「連続する2つのMB(マクロブロック)中で使用可能な最大のMV数(動き補償のためのベクトルデータの個数)」を制限している。MV数が増えれば参照回数が増え、処理が重くなるため、レベルの規定としてその数を制限しようという目的がある模様。

一定の面積(MBの面積なので16x16)に対し、小さなパーティションが増えれば、当然パーティションの個数=MV数が増加することになる。x264ではp4x4がMVを持つ最も小さなパーティションで、これを使いすぎるとMaxMvsPer2Mbを破ってしまうため、規格に適合しなくなる可能性がある。そしてMaxMvsPer2MbがLevel3以上にのみ規定されているため、Levelが高いのに機能が使えなくなるとのこと。

もちろん様々な条件次第ではあるが、akupenguin氏の実験ではcrf=18で2500フレーム中650回、crf=24で120回、crf=30で8回の「規格破り」が発生したそうで、全MBの0.5%以下(これには後述の疑問がある)でのみp4x4が使用されれば問題にはならないそうだ。

もちろんx264がもっと賢くp4x4の使用量を管理すればp4x4を使用しても問題は無いのだが、恐らくx264の開発陣にはp4x4にそれほどの価値がないと見なされていて、p4x4に手間を割きたくないのと速度が低下する懸念から放置されているのだろう。

 もう少し詳細を考える

MaxMvsPer2Mbの実質的な意味

MaxMvsPer2Mbは「2つの連続するMB中の…」という変な定義だが、これは実質的に、移動平均としてのinterパーティションの個数を制限していると思ってよい。そして結果的に、1フレーム中のMV数、つまりパーティションの個数を制限することにもなる。

本来はp/bパーティションの全てが対象だが、パーティションが細かくなるほど全体のパーティション個数が増えることから、実質p4x4とb4x4にしか掛からない。そしてx264はrev1061現在、b4x4はサポートしていないため、p4x4のみが槍玉に挙がっている。b4x4を実装していないのは、bはpより大きなパーティションを使う傾向になるし、小さいbを使うのは効率が悪く、非合理的でやる気がしない的な理由のようだ。

なお、i4x4に掛からないのは、intraパーティションであってMVを持たないからだろうと思うのだが、H.264/AVCにはintra予測ってのもあるのでこれがMVに該当しないのかは若干謎。まぁMotionVectorではない…か?

akupenguin氏のコメントについて

ところでMaxMvsPer2MbはLevel3.0で32、それより上位のLevelで16となっている。これに対するakupenguin氏の弁は「全MBの0.5%のみがp4x4を使用するならOK(that's not likely to be a problem when P4x4 is used in only 0.5% of macroblocks)」と読み取れるのだが、この説明には若干納得がいかない。

結果的に1フレーム中のパーティション数を制限するのは確かだが、規格の定義としてはあくまで2つの連続するMBが対象であるのに、MBの0.5%という表現がまず歪んでいる。そして16x16サイズである1つのMBを4x4のパーティションに分割した場合、発生するMVは16で、連続する2つのMBではx2で32になる。MVの仕様を詳細に把握しているわけではないが、仮にMB自身が消費するMVを含める、YUVが別々にMVを持つ、等と仮定しても0.5%という数値にはなり得ないように思われる。

そしてこの理解が正しいなら、仮に全てのMBにp4x4が使われたとしても規格を破らない可能性は十分あるように思う。なお、「全てのパーティションがp4x4でも」ではなくて「全てのMBがp4x4を1つ以上含んでいても」の意味なので注意。

(追記)IRCで得た情報によれば、筆者のこの想定は正しいようだ。全てのMBにp4x4が使われても規格を破らない可能性はある。ただし、x264はp4x4の使われ具合をコントロールする術を持っていないし、将来的にb4x4(正確にはbsub8x8)が実装された場合にはなお一層、規格違反の可能性は高まる。akupenguin氏の実験はあくまで一例であり、わかりやすくするために上記のように正確ではない説明されたのだろう。しかし、これはエンコード対象の映像にかなり依存すると思った方がいい。

 おまけ(画質面)

開発者にもあまり好まれず、まるも大先生のpartitionsの解説でも散々な評価であったp4x4であるが、それでも使うべきか否かの議論は多かった。

直接的な画質の検証は方々のサイトで行われているので、今更ここで検証はしない。が、概ね「使ったほうがSSIMは上がる」という方向にありそうだ。見た目で分かるほどの変化があるかは微妙にも思うが、一応「画質が上がる」ものとみなそう。そしてここではその理由と、予測される傾向の、理屈を後付けしてみたい。

DCT vs DWTにも書いているように、パーティションのサイズは画像・映像の全体サイズ、つまり解像度によって選択されるべきだ。より小さな解像度ではより小さなパーティションが有用で、より大きな解像度ではより大きなパーティションが有用だ。H.265/HVCで64x64のSupermacroblockの追加が検討されていることから見ても、この傾向は間違いないといっていい。

H.264はHD解像度をもサポートしているが、当初はどちらかというとモバイルデバイスなどの解像度の小さな機器が主眼であった。そのために4x4が重要で、当初はこれで十分だったのだろう。しかし、ある一定以上解像度が大きくなると、より大きなパーティションサイズで大まかに扱ったほうが、(当該パーティションのピンポイントはともかく)全体として画質がよいことが分かってきたものと思われる。

なので、画質的にp4x4が有効なのはより小さな解像度や小さなオブジェクトのある映像であると推測できる。有用である範囲を具体的に明示することは難しいが、各サイトでの検証結果を見ても、概ねSD以下ではそれなりに意味があるのではないだろうか。

まるも大先生のフォロー(?)

では、なぜ先のまるも大先生の解説では芳しくない評価なのだろうか。それは、時期を考えればわかる。まるも先生が上記の解説を書いたのは2007年6月、大体rev663前後の話だ。つまり、古いx264ではp4x4はあまり有用ではなかったのかもしれない。

その後rev1000頃までp4x4の是非の議論は続いたように思うが、重要なのは実はその後だったりする。changelogを見ると、rev1000-1100の間にはポツポツとp4x4の改善が入っている。特にRDOの絡む改善は重要で、これの有無で「p4x4を指定すること」の評価は全く異なる可能性がある。そもそも、ユーザがpartitionsにp4x4を指定していても、画質的に不利だとx264が判断できるならば使用しなければ良いだけの話だ。そしてその判断を行うのがRDOではなかったか。p4x4を指定して画質が悪くなるというのは、単にp4x4が非効率だというだけではなく、RDOが馬鹿だから(rdoの入らないsubme<=5は別としても)だという観点を忘れるべきではない。

加えて、r1523現在、x264の--preset slowerとそれより重い設定では、p4x4が使用されるようになっている。つまり、今やp4x4は開発者にもそれなりに評価はされているのかもしれない。

よって、まるも大先生の評価は過去において正しかったものと考え、現在では「p4x4は比較的小さな(多分SD以下程度)の解像度であればそれなりに有用」なのではないかと考えられる。これに規格適合性の話を加えて、「p4x4はLevel3.0未満なら使用する」のが賢い判断なのかもしれない。

最終更新時間:2008年12月28日 04時16分23秒