AV1 specification を読む (デコード処理の概要2:参考)


スーパーブロックはHEVCの64x64 LCUに相当するようですね。

参照フレーム管理の詳細まではまだ言及されていませんが、H264のRefPicList modification、HEVCのRefPicSetより単純な処理のように見えます。

hidden frameも使いようによっては面白いエンコーダに応用できる匂いがします。


スーパーブロック

画像内には、同時に予測できるような広い領域(例えば、静止した背景画像)があるかもしれません。
そしてそれは、微妙な細部の変化(例えば、会話している頭部)があり、それらはより小さなブロックサイズが適切になるかもしれません。
AV1では、様々な予測サイズを扱う機能を提供します。

デコーダは、64x64画素のスーパーブロックの単位で画像をデコードします。
各スーパーブロックは、どのようにエンコードされたか分割します。
これらは、以下のように構成されます。

  • 1つの64x64ブロック
  • 2つの64x32ブロック
  • 2つの32x64ブロック
  • 4つの64x32ブロック

それずれのパーツはラスタ順にデコードします。
各32x32ブロックは、同様に8x8ブロックになるまで分割することができます。
8x8ブロックは、以下のようになります。

  • 1つの8x8ブロック
  • 2つの8x4ブロック
  • 2つの4x8ブロック
  • 4つの4x4ブロック

64x64スーパーブロックの分割例を示します。

番号はブロックのデコード順で、カッコ内はブロックサイズです。
サイズが書かれていないブロックは8x8のサブブロックです。

ブロックとサブブロックとの違いは、8x8領域内のすべてのサブブロックのために1つのブロックヘッダ(モード情報と呼ばれる)が送られますが、ブロックはそれ自身でブロックヘッダを持つことです。
サブブロックは別々のイントラモード・動きベクトルを持つことができますが、どこからフレームを参照するかというような情報は共有されます。

複数変換

AV1では残差に適用する複数の変換を規定しています。
これらは、サイズ(4x4, 8x8, 16x16, 32x32をサポート)が違ったり、変換のタイプが違ったりします。
変換のタイプは、行方向と列方向独立して変更することができ、整数精度のDCTとADSTのどちらかでsす。
変換タイプの選択はイントラモードから指定されますが、変換サイズはフレームレベルあるいはブロック単位で指定できます。

この考え方は、イントラ予測をするときにおいて、既知のエッジに近い画素は遠い画素よりもよりよく予測ができるため、ふつうは誤差が片側だけ小さくなります。
ADSTはこのような形状に対してよい仕事をしてくれます。
基底ベクトルが既知の境界を消し、未知の境界にエネルギーを最大化する傾向があるからです。

変換サイズがブロックサイズよりも小さいとき、変換ブロックは予測されてラスタ順に再構成されます。
例えば、64x64イントラブロックで16x16変換サイズを仮定します。
ブロックの処理順は以下のようになります。

各16ブロックに対して以下を繰り返し適用します。

  1. 過去にデコードした画素を使って、16x16ブロックを予測
  2. 16x16ブロックの変換係数を逆変換して残差を計算
  3. 予測値に残差を加算し、デコード画素を計算する

2番目の16x16ブロックの予測は、最初のブロックでデコードされた画素に依存することに注意してください。
(ループフィルタはフレーム全体がデコードされた後に適用されることにも注意してください。)

逆DCT構造

係数のブロックを処理するために使われる2次元逆変換は、まずブロックの行方向の1次元逆変換を適用し、行方向の変換結果を列方向に変換します。

逆DCTは最初に入力データをビットリバース順にシャッフルした後、バタフライ処理をします。
各バタフライには2つの入力があり、2つの出力値を生成します。
バタフライは入力値の2次元回転をしているとも考えることができます。

バタフライには2つのタイプ(B,H)があります。
Hタイプのバタフライはスケーリング付きのマトリックスで、1つの加算と2つの減算で実装できます。
Bタイプのバタフライは乗算器が必要です。

32点逆DCTの構造を、以下のようなバタフライ図(入力のシャッフルは省略)に示します。
2n点逆DCTの構造は、2n-1点逆DCTを含みます。
この再帰構造は、下図の 4, 8, 16点逆DTとしてハイライトしています。

逆ADST構造

ADSTはもう1つの1次元変換で、長さ4,8,16の配列に適用できます。

ADSTのステージ内では、高精度な中間結果の配列Sが使われます。
バタフライ演算SBがその出力をSに格納し、バタフライ演算SHがSから入力をもらいます。

AV1で使用する8点逆ADSTを、下図に示します。

参照フレーム

物体がシーンをまたがってしているならば、ブロックのインター予測のもっとも良いソースは、直前のフレームではないかもしれません(ここで、ブロックは動く物体によっておおわれているとします)。

AV1ではインターブロックが参照フレームとして使うフレームを指定する機能があります。
デコードは、デコードされた参照フレームが入った8つのスロットを管理します。
新たなフレームがデコードされたら、フレームヘッダはどのスロットに新たなフレームを上書きするか指定します。

8つのスロットが管理されますが、任意の特定のフレームでは最大3つの参照フレームを使うことができます。
この使用する参照フレームはフレームヘッダで指定され、この3つの中の詳細な選択は符号化ブロックレベルのモード情報で指定します。
各ブロック(サイズは8x8以上)では、最大2つの参照フレームが許可されています。
ブロック内のすべてのサブ8x部8ブロックは、同じ参照フレームの組み合わせを共有します(最大2枚の参照フレーム)。

隠れフレーム

フレームがデコードされたら、通常は表示されます。
しかし、フレームをデコードしても表示しないということも可能です。
このフレームは参照フレームとしてスロットに格納され、将来のインターフレームとして使います。

このオプションは、シーン内の様々な物体の高品質版をふくむような ゴールデンフレームを作るために使えます。
このフレームは、他のフレームを構築するために使います。

デコーダに直接フレームスロットの1つを表示させるため、非常に短いフレーム(1バイトや2バイト)を送ることもでいます。

コンパウンド予測

上で述べたように、1つのインターブロックは1枚の参照フレームあるいは2枚の参照フレームの組み合わせえ予測することができます。
後者はコンパウンド予測と呼び、2つの動きベクトルと2枚の参照フレームが1つのインターブロックで指定されあす。

この場合、まずそれぞれの参照フレームで予測がなされ、これら2つを平均化した組み合わせで最終的な予測値を得ます。
それぞれ別個の予測よりも、その平均のほうがより良くなるであろうという希望です。

コンパウンド予測を使うかどうかの指定は、フレームレベルあるいはインターブロックのモード情報で指定できます。

動きベクトル予測

多くのブロックが同じ動きベクトルを共有することがよくあります(例えば、パンするカメラ)。
AV1では、既にデコードされたインターブロックをスキャンしてカレントブロックの動きベクトルを探すことで、この特徴を利用します。
隣接するブロックと同じ参照フレームの選択を共有するのが望ましいのですが、最大2つの異なる予測が見つかるまでサーチ範囲を少しづつ拡張します。
空間的な近傍で効果的な除法が得られなかったら、過去にデコードされたフレームの動きベクトルを使うことにします。
前者で見つかった動きベクトルを再近傍動きべkとる、後者で見つかった動きベクトルを近傍動きベクトル(nearmv)と呼びます。

ブロックには、再近傍動きベクトル・近傍動きベクトル・ゼロ動きベクトル・新動きベクトルのどれを使うかが指定されます。

新たな動きベクトルの場合、ビットストリーム内では差分動きベクトルと呼びます。
デコーダはその差分動きベクトルを読み、再近傍動きベクトルに加算することで実際の動きベクトルを計算します。

実効的な動きベクトルは、最大1/8(8分の1)画素精度で指定されます。
予測された動きベクトルの両方の成分の大きさが64以上(つまり、8画素)のとき、実行動きベクトルの制度は自動的に1/4画素精度になります。

タイル

フレーム内の64x64スーパーブロックは5.6節で説明したようにタイル内をラスタ順に送られ、タイルはフレーム内をラスタ順に送られます。
以下のT図は、フレーム内のタイルセット(ラスタ順の番号)の一例で、タイル1には個々の64x64スーパーブロック(a-h)を示しています。

64x64スーパーブロックの整数倍の大きさで、可能な限りの面積になります。

タイルはバンド幅を削減する効果はありませんが(実際には微妙に圧縮が悪くなります)、この目的は異なるタイルを並列にエンコード・デコード処理できるという利点を目的としています。
タイルサイズは角各イルの最初(最後のタイルは除いて)に送られるので、デコーダはどこから並列デコードをすればよいか知ることができます。