AV1 specification を読む (デコード処理：フレーム順の制約・確率の補正) 

本題のデコード処理です・・・が、まだ画像っぽい話には到達しませんね。

確率変数についての話なので、定義通りやるだけです。

-----

#デコード処理

##概要

デコーダはすべての面で一致し、ここで規定するデコード処理で生成されたのと同じ出力順で、出力フレームを生成しなければなりません。


この処理の入力は、符号化されたフレームのシーケンスです

この処理の出力は、デコードされたフレームのシーケンスです。

以下の手順で各符号化フレームは処理されます。

1. 6章と7章で規定されるように、符号化フレームのシンタックス要素を抽出します。関数コールが含まれるシンタックステーブルは、ブロックデコード処理がなされることを示しています。
2. loop_filter_levelが0ではないならば、8.8節でいていされるループフィルタ処理が、デコードされたフレームに対して1回呼びます。
3. 以下のすべての条件が真のとき、PrevSegmentIds[row][col]　＝SegmentIds[row][cos] とします。row = 0..MiRows-1, col=0..MiCosl-1。
  * show_existing_frame == 0
  * segmentation_enabled == 1
  * segmentation_update_map == 1
4. 8.9節で規定される出力処理を呼びます。
5. 8.10節で規定される参照フレーム更新処理を呼びます。


##フレーム順の制約

本節ではフレームタイプに由来するビットストリームの付加的な制約について説明します。

シーケンスがキーフレームで始まる場合、この付加的な制約は自動的に満たされます。

そうでない場合、シーケンスは非キーフレーム（インターフレーム・イントラオンリーフレーム）で始めることができますが、デコード処理がうまくできるように追加のケアが必要です。
以下を適用することが、ビットストリーム制約の要求です。

 * load_probs(ctx)が呼ばれるとき、初期化された確率のセットをロードしなければなりません。つまり、それ以前にsave_probs(ctx)が存在しなければならないということです。
 * ref_frame_idx[i]がでこどされるとき、初期化された参照フレームを指定しなければなりません。つまり、(refresh_frame_flags»ref_frame_idx[i])&1==1である、それ以前にデコードされたフレームが存在するということです。

注意：
この制約は、最初の符号化フレームはインターフレームになりえないことを意味します。


##カウントクリア処理

この処理は、6.1節で説明したフレームのしんったくすでコード内で呼ばれる clear_counts 関数で開始します。

以下の配列には、特定のコンテキストで特定のシンタックス要素が何回デコードされたかを格納します。

角カッコは、配列の各次元のサイズを定義します。
栗アカウント処理が呼ばれたとき、すべてのカウントをゼロにします。


##確率補正処理

この節では、様々なシンタックス要素の発生頻度に基づいて、確率を後方更新するための2つの処理を定義します。

これらの処理は、6.1.2節の確率更新シンタックステーブル内の関数定義で呼ばれます。

この処理は、以下で定義する関数merge_prob, merge_probs を使います。

###merge prob 処理

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

 * 二値のための、オリジナル確率 preProb
 * 二値が0, 1どちらにデコードされたかの回数を指定する変数 ctx0, ctx1
 * 最大適応には何回デコードが必要かを示す変数 countSat
 * 確率が補正できる最大の回数を指定する変数 maxUpdateFactor

出力は、更新された確率を含む変数 outProbです。
二値がデコードされた合計回数 den = ctx0 + cxx1 とします。

二値が0とデコードされた確率の推定値 prob = (den == 0) ? 128 : Clip3( 1, 255, (ct0 * 256 + (den » 1)) / den ) 
count = Min( ct0 + ct1, countSat )
factor = maxUpdateFactor * count / countSat
戻り値 outProb = Round2( preProb * (256 - factor) + prob * factor, 8 )


###merge probs処理

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

 * シンタックス要素のデコードツリーを指定する配列 tree
 * デコードツリーのカレント位置を示す変数 i
 * シンタックス要素をデコードするためのオリジナル確率s probs
 * 各シンタックス要素の各値がが何回デコードされたかを含む配列 counts
 * 最大適応には何回デコードが必要かを示す変数 countSat
 * 確率が補正できる最大の回数を指定する変数 maxUpdateFactor

出力は入力配列 probs を補正したもので、戻り値には二値がデコードされた合計の回数が含まれます。
処理は以下のように定義されます

```C++
merge_probs( tree, i, probs, counts, countSat, maxUpdateFactor )
{
	s = tree[i]
	leftCount = (s <= 0) ? counts[-s] : merge_probs( tree, s, probs, counts, countSat, maxUpdateFactor )
	
	r = tree[i+1]
	rightCount = (r <= 0) ? counts[-r] : merge_probs( tree, r, probs, counts, countSat, maxUpdateFactor )
	
	probs[i>>1] = merge_prob( probs[i>>1], leftCount, rightCount, countSat, maxUpdateFactor )
	return leftCount + rightCount
}
```

###係数確率適応処理

この処理は、確率更新シンタックステーブルの adapt_coef_probs が呼ばれたときに開始します。
変数 updateFactor は、今のフレームタイプと過去のフレームタイプに従って設定されます。

 * FrameIntra == 1 ならば、updateFactor = 112
 * LastFrameType == KEY_FRAMEならば、updateFactor = 128
 * そうでなければ、updateFacotr = 112

そして、確率変数は以下のように更新します。

```C++
for (t=0; t<4; t++)
  for (i=0; i<2; i++)
    for (j=0; j<2; j++)
      for (k=0; k<6; k++) {
        maxL = (k==0) ? 3 : 6;
        for (l=0; l<maxL; l++) {
          merge_probs(small_token_tree, 2, coef_probs[t][i][j][k][l], counts_token[t][i][j][k][l], 24, updateFactor);
          merge_probs(binary_tree, 0, coef_probs[t][i][j][k][l], counts_more_coefs[t][i][j][k][l], 24, updateFactor);
        }
      }
```

ここで、small_token_treeは以下のように定義します。

```C++
small_token_tree[6] = {
  0, 0, // unused
  -ZERO_TOKEN, 4,
  -ONE_TOKEN, -TWO_TOKEN
};
```


###確率以外の確率適応処理

この処理は、確率更新シンタックステーブルの adapt_noncoef_probs が呼ばれたときに開始します。
確率は以下のように更新します。

```C++
省略
```

adapt_probs は以下のように定義します。

```C++
adapt_probs(tree, probs, counts) {
  merge_probs(tree, 0, probs, counts, COUNT_SAT, MAX_UPDATE_FACTOR);
}
```

adapt_prob は以下のように定義します。

```C++
adapt_prob(probs, counts) {
  return merge_prob(prob, counts[0], counts[1], COUNT_SAT, MAX_UPDATE_FACTOR);
}
```