AV1 specification を読む 2018-04-04 (7.10.2. Inter Prediction Process)

#AV1 specification 日本語訳 (2018-04-04)

インター予測では、refIdx で指定した参照フレームの、mv で指定した座標の画素ブロックを切り出して、予測値とします。
（細かな条件は端折りますが）インター予測で使える機能は以下のような選択肢があります。

参照フレームの選択

 * シングル予測
    * 過去にデコードされた、1枚の参照フレームを使って予測値を得る
 * コンパウンド予測
    * 2枚の参照フレームを使って予測値を得る
    * インターインター予測（オレオレ用語）
       * 過去にデコードされた、2枚の参照フレームからの予測値をブレンドして、予測値を得る。
    * インターイントラ予測
       * 過去にデコードされた1枚の参照フレームと、カレントブロックの近傍画素からの予測値（イントラ予測）をブレンドして、予測値を得る。

参照画像からの画素ブロックの切り出し方　(motion_mode) も選択できます。

 * シンプル
    * 単純な矩形切り出し＆貼り付けで予測
 * ローカルワープ
    * カレントブロック周辺のMVの具合から、参照画像の変形（アフィンパラメータ）を予測
    * 参照画像を局所的にアフィン変換してから、切り出す
 * OBMC (Overwrapped Block Motion Compensation)
    * 切り出したブロック単位で単に貼り付けるのではなく、隣接するブロックのインター予測値をはみ出させてから貼り付ける
    * 隣接する予測値同士でのブロック境界がなめらかになり、より良い予測になる

（コンパウンド予測の場合）2つの予測値のブレンドの仕方を選択できます。

 * AVERAGE
    * 2つの予測値の平均値をとる
 * DISTANCE
    * 参照されるフレームと、カレントフレームとの距離（表示時刻差）に応じて、重みづけ平均をとる
    * 遠いフレームは軽めに、近いフレームは重めに
 * DIFFWTD
    * 2つの予測値の画素単位の差分に応じて、画素単位で重みづけ平均をとる
    * 差分が小さい（似ている）箇所は平均的に、差分が大きい（不一致）箇所は片側だけを強調して
 * WEDGE
    * 斜め方向にブロックを分割して、それぞれの領域に
    * 斜め具合は16種類から選択可能

----

### 7.10.2. Inter Prediction Process

> The inter prediction process is invoked for inter coded blocks and interintra blocks.

インター予測処理は、インター符号化ブロックとインターイントラブロックで呼ばれます。

>The inputs to this process are:
>
> * a variable plane specifying which plane is being predicted,
> * variables x and y specifying the location of the top left sample in the CurrFrame[ plane ] array of the region to be predicted,
> * variables w and h specifying the width and height of the region to be predicted,
> * variables candRow and candCol specifying the location (in units of 4x4 blocks) of the motion vector information to be used.

この処理の入力は以下のとおりです。

 * どのプレーンを予測するか指定する plane
 * 予測すべき領域左上の、CurrFrame[plane] 内の画素座標 (x,y)
 * 予測領域の幅と高さ w, h
 * 使用するMV情報の位置を指定する candRow, candCol（4x4ブロック単位）

>The outputs of this process are predicted samples in the current frame CurrFrame.

この処理の出力は、CurrFrame の予測された画素です。

>This process is triggered by a function call to predict_inter.

この処理は predict_inter() 関数呼び出しで実行します。

>The variable isCompound is set equal to RefFrames[ candRow ][ candCol ][ 1 ] > INTRA_FRAME.

isCompound = RefFrames[ candRow ][ candCol ][ 1 ] > INTRA_FRAME

>The prediction arrays are formed by the following ordered steps:
>
> 1. The variable refList is set equal to 0.
> 2. The variable useWarp is derived as follows:
>  * If w < 8 or h < 8, useWarp is set equal to 0.
>  * Otherwise, if force_integer_mv is equal to 1, useWarp is set equal to 0.
>  * Otherwise, if motion_mode is equal to LOCALWARP, useWarp is set equal to 1.
>  * Otherwise, if (YMode == GLOBALMV || YMode == GLOBAL_GLOBALMV) and GmType[ RefFrame[ refList ] ] > TRANSLATION, useWarp is set equal to 1.
>  * Otherwise, useWarp is set equal to 0.
> 3. The rounding variables derivation process specified in section 7.10.2.1 is invoked with the variable isCompound as input.
> 4. If setting useWarp equal to 1 would result in the bitstream not being conformant (due to either the requirement in the warp estimation process in section 7.10.2.7 about the determinant being non-zero, or the requirement in the setup shear process in section 7.10.2.5 about the size of the shear) then useWarp is set equal to 0.
> 5. If plane is equal to 0 and motion_mode is equal to LOCALWARP and useWarp is equal to 1, the warp estimation process in section 7.10.2.7 is invoked.
> 6. The motion vector array mv is set equal to Mvs[ candRow ][ candCol ][ refList ].
> 7. The variable refIdx specifying which reference frame is being used is set as follows:
>  * If use_intrabc is equal to 0, refIdx is set equal to ref_frame_idx[ RefFrame[ refList ] - LAST_FRAME ].
>  * Otherwise (use_intrabc is equal to 1), refIdx is set equal to -1 and RefFrameWidth[ -1 ] is set equal to FrameWidth, RefFrameHeight[ -1 ] is set equal to FrameHeight, and RefUpscaledWidth[ -1 ] is set equal to UpscaledWidth.
> 8. The motion vector scaling process in section 7.10.2.2 is invoked with plane, refIdx, x, y, mv as inputs and theoutput being the initial location startX, startY, and the step sizes stepX, stepY.
> 9. If useWarp is equal to 1, the block warp process in section 7.10.2.4 is invoked with plane, refList, x, y, i8, j8, w, h as inputs and the output is merged into the 2D array preds[ refList ] for i8 = 0..((h-1) >> 3) and for j8 = 0..((w-1) >> 3). (Each invocation fills in a block of output of size w by h at x offset j8 * 8 and y offset i8 * 8.)
> 10. If useWarp is equal to 0, the block inter prediction process in section 7.10.2.3 is invoked with plane, refIdx, startX, startY, stepX, stepY, w, h, candRow, candCol as inputs and the output is assigned to the 2D array preds[ refList ].
> 11. If isCompound is equal to 1, then the variable refList is set equal to 1 and steps 4 to 9 are repeated to form the prediction for the second reference.

予測配列を以下の手順で構成します。

 1. refList = 0
 2. useWarp を以下の手順で求めます。
  * w<8 || h<8 ならば、userWarp = 0
  * そうではなく、force_integer_mv==1 ならば、useWarp=0
  * そうではなく、motion_mode==LOCALWARP ならば、useWarp=1
  * そうではなく、(YMode==GLOBALMV || YMode==GLOBAL__GLOBA_MV) && GmType[RefFrame[refList]]>TRANSLATION ならば、useWarp=1
  * そうではなければ、userWarp = 0
 3. 丸め変数導出処理（7.10.2.1節）を、isCompound を入力として呼び出します。
 4. useWarp=1 に設定することで、適合しないビットストリームになってしまう場合には、useWarp=0 にします。（ワープ予測処理（7.10.2.7節）での行列式が非ゼロという制約か、シアー設定処理（7.10.2.5節）のシアーサイズの制約などによる）
 5. plane==0 && motion_mode==LOCALWARP && useWarp==1 ならば、ワープ予測処理（7.10.2.7節）を呼び出します。
 6. 動きベクトル配列 mv = Mvs[ candRow ][ candCol ][ refList ]
 7. どの参照フレームを使うかを指定する変数 refIdx を、以下のように設定します。
  * use_intrabc==0 ならば、refIdx = ref_frame_idx[ RefFrame[ refList ] - LAST_FRAME ]
  * use_intrabc==1 ならば、refIdx = -1, RefFrameWidth[ -1 ] = FrameWidth, RefFrameHeight[ -1 ] = FrameHeight, RefUpscaledWidth[ -1 ] = UpscaledWidth
 8. 動きベクトルスケーリング処理（7.10.2.2節）を、plane, refIdx, x, y, mv を入力として呼び出し、初期座標 startX, startY, ステップサイズ step, stepY を出力とします
 9. useWarp==1 ならば、ブロックワープ処理（7.10.2.4節）を、plane, refList, x, y, i8, j8, w, h を入力として呼び出し、2次元配列 preds[ refList ], i8 = 0..((h-1) >> 3), j8 = 0..((w-1) >> 3) を出力とします。(それぞれの呼び出しについて、xオフセット j8*8, yオフセットi8*y の w x h ブロックを埋めます）
 10. useWarp==0 ならば、ブロックインター予測処理（7.10.2.3節）を、plane, refIdx, startX, startY, stepX, stepY, w, h, candRow, candCol を入力として呼び出し、2次元配列 preds[ refList ] を出力とします。
 11. isCompound==1 ならば、refList = 1として、手順 4..9 を2枚目の参照の予測をするために繰り返します。

>If IsInterIntra is equal to 1, the following ordered steps apply:
>
>　1. The variable mode is set as follows:
>　 * If interintra_mode is equal to II_DC_PRED, mode is set equal to DC_PRED.
>　 * Otherwise if interintra_mode is equal to II_V_PRED, mode is set equal to V_PRED,
>　 * Otherwise if interintra_mode is equal to II_H_PRED, mode is set equal to H_PRED,
>　 * Otherwise (interintra_mode is equal to II_SMOOTH_PRED), mode is set equal to SMOOTH_PRED.
>　2. The variable haveLeft is set equal to AvailL
>　3. The variable haveAbove is set equal to AvailU
>　4. The variable haveAboveRight is set equal to 0
>　5. The variable haveBelowLeft is set equal to 0
>　6. The variable log2W is set equal to log2( w )
>　7. The variable log2H is set equal to log2( h )
>　8. The intra prediction process specified in section 7.10.1 is invoked with plane, x, y, haveLeft, haveAbove, haveAboveRight, haveBelowLeft, mode, log2W, log2H as inputs. (This will write intra predicted samples into CurrFrame.)

IsInterIntra==1 ならば、以下の手順を適用します。

　1. mode を以下のように設定します。
　 * interintra_mode==II_DC_PRED ならば、mode = DC_PRED
　 * interintra_mode==II_V_PRED ならば、mode = V_PRED
　 * interintra_mode==II_H_PRED ならば、mode = H_PRED
　 * interintra_mode==II_SMOOTH_PRED ならば、mode = SMOOTH_PRED
　2. haveLeft = AvailL
　3. haveAbove = AvailU
　4. haveAboveRight = 0
　5. haveBelowLeft = 0
　6. log2W = log2( w )
　7. log2H = log2( h )
　8. イントラ予測処理（7.10.1節）を、plane, x, y, haveLeft, haveAbove, haveAboveRight, haveBelowLeft, mode, log2W, log2H を入力として呼び出します。（これによって、イントラ予測画素が CurrFrame に書き込まれます）

>An array named Mask is prepared as follows:
>
> * If compound_type is equal to COMPOUND_WEDGE and plane is equal to 0, the wedge mask process in section 7.10.2.10 is invoked with w, h as inputs.
> * Otherwise if compound_type is equal to COMPOUND_INTRA, the inter intra mask process in section 7.10.2.12 is invoked with preds, plane, x, y, w, h as inputs.
> * Otherwise if compound_type is equal to COMPOUND_DIFFWTD and plane is equal to 0, the segment mask process in section 7.10.2.11 is invoked with preds, w, h as inputs.
> * Otherwise, no mask array is needed.

配列 Mask を以下のように求めます。

 * compound_type==COMPOUND_WEDGE && plane==0 ならば、ウェッジマスク処理（7.10.2.10節）を、w, h を入力として呼び出します。
 * そうではなく、compound_type==COMPOUND_INTRA ならば、インターイントラマスク処理（7.10.2.12節）を、preds, plane, x, y, w, h を入力として呼び出します。
 * そうではなく、compound_type==COMPOUND_DIFFWTD && plane==0 ならあば、セグメントマスク処理（7.10.2.11節）を、preds, w, h as を入力として呼び出します。
 * そうではなければ、mask は必要ありません。

>If compound_type is equal to COMPOUND_DISTANCE, the distance weights process in section 7.10.2.14 is invoked with
candRow and candCol as inputs.

compound_type==COMPOUND_DISTANCE ならば、距離ウェイト処理（7.10.2.14節）を、candRow, candCol を入力として呼び出します。

>The inter predicted samples are then derived as follows:
>
> * If isCompound is equal to 0 and IsInterIntra is equal to 0, CurrFrame[ plane ][ y + i ][ x + j ] is set equal to Clip1( preds[ 0 ][ i ][ j ] ) for i = 0..h-1 and j = 0..w-1.
> * Otherwise if compound_type is equal to COMPOUND_AVERAGE, CurrFrame[ plane ][ y + i ][ x + j ] is set equal to Clip1( Round2( preds[ 0 ][ i ][ j ] + preds[ 1 ][ i ][ j ], 1 + InterPostRound ) ) for i = 0..h-1 and j = 0..w-1.
> * Otherwise if compound_type is equal to COMPOUND_DISTANCE, CurrFrame[ plane ][ y + i ][ x + j ] is set equal to Clip1( Round2( FwdWeight * preds[ 0 ][ i ][ j ] + BckWeight * preds[ 1 ][ i ][ j ], 4 + InterPostRound ) ) for i = 0..h-1 and j = 0..w-1.
> * Otherwise, the mask blend process in section 7.10.2.13 is invoked with preds, plane, x, y, w, h as inputs.

インター予測された画素を以下のように求めます。

 * isCompound==0 && IsInterIntra==0 ならば、CurrFrame[ plane ][ y + i ][ x + j ] = Clip1( preds[ 0 ][ i ][ j ] ), i = 0..h-1, j = 0..w-1
 * そうではなく、compound_type==COMPOUND_AVERAGE ならば、CurrFrame[ plane ][ y + i ][ x + j ] = Clip1( Round2( preds[ 0 ][ i ][ j ] + preds[ 1 ][ i ][ j ], 1 + InterPostRound ) ) for i = 0..h-1 and j = 0..w-1
 * そうではなく、compound_type==COMPOUND_DISTANCE ならば、CurrFrame[ plane ][ y + i ][ x + j ] = Clip1( Round2( FwdWeight * preds[ 0 ][ i ][ j ] + BckWeight * preds[ 1 ][ i ][ j ], 4 + InterPostRound ) ) for i = 0..h-1 and j = 0..w-1.
 * そうではなければ、マスクブレンド処理（7.10.2.13節）を、preds, plane, x, y, w, h を入力として呼び出します。

>　If motion_mode is equal to OBMC, the overlapped motion compensation in section 7.10.2.8 is invoked with plane, x, y, w, h as inputs.

motion_mode==OBMC ならば、オーバーラップMC（7.10.2.8節）を、plane, x, y, w, h を入力として呼び出します。