Store ANS token CDFs in the FRAME_CONTEXT rather than in a global table.

This will facilitate bringing the zero node into the token set while
allowing its probability to vary independently.

Change-Id: I57b44c0fce44debb8e612021e44713b229d1b3cf
diff --git a/vp10/common/entropy.c b/vp10/common/entropy.c
index 16b9dc4..909c3bd 100644
--- a/vp10/common/entropy.c
+++ b/vp10/common/entropy.c
@@ -675,15 +675,6 @@
   {247, 1, 1, 1, 1, 1, 1, 1, 1, 1},
   {247, 1, 1, 1, 1, 1, 1, 1, 1, 1},
 };
-
-void vp10_build_pareto8_cdf_tab(
-    const vpx_prob token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2],
-    rans_dec_lut cdf_tab[COEFF_PROB_MODELS]) {
-  int p;
-  for (p = 0; p < COEFF_PROB_MODELS; ++p) {
-    rans_build_cdf_from_pdf(token_probs[p], cdf_tab[p]);
-  }
-}
 #endif  // CONFIG_ANS
 
 #if CONFIG_ENTROPY
@@ -2807,6 +2798,24 @@
   extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]);
 }
 
+#if CONFIG_ANS
+void vp10_coef_pareto_cdfs(FRAME_CONTEXT *fc) {
+  TX_SIZE t;
+  int i, j, k, l;
+  for (t = TX_4X4; t <= TX_32X32; ++t)
+    for (i = 0; i < PLANE_TYPES; ++i)
+      for (j = 0; j < REF_TYPES; ++j)
+        for (k = 0; k < COEF_BANDS; ++k)
+          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
+            const vpx_prob *const tree_probs = fc->coef_probs[t][i][j][k][l];
+            vpx_prob pivot = tree_probs[PIVOT_NODE];
+            assert(pivot != 0);
+            rans_build_cdf_from_pdf(vp10_pareto8_token_probs[pivot - 1],
+                                    fc->coef_cdfs[t][i][j][k][l]);
+          }
+}
+#endif  // CONFIG_ANS
+
 void vp10_default_coef_probs(VP10_COMMON *cm) {
 #if CONFIG_ENTROPY
   const int index =
@@ -2819,6 +2828,9 @@
   vp10_copy(cm->fc->coef_probs[TX_16X16], default_coef_probs_16x16);
   vp10_copy(cm->fc->coef_probs[TX_32X32], default_coef_probs_32x32);
 #endif  // CONFIG_ENTROPY
+#if CONFIG_ANS
+  vp10_coef_pareto_cdfs(cm->fc);
+#endif  // CONFIG_ANS
 }
 
 #define COEF_COUNT_SAT 24
@@ -2888,6 +2900,9 @@
 #endif  // CONFIG_ENTROPY
   for (t = TX_4X4; t <= TX_32X32; t++)
     adapt_coef_probs(cm, t, count_sat, update_factor);
+#if CONFIG_ANS
+  vp10_coef_pareto_cdfs(cm->fc);
+#endif
 }
 
 #if CONFIG_ENTROPY
diff --git a/vp10/common/entropy.h b/vp10/common/entropy.h
index 2385720..1e47883 100644
--- a/vp10/common/entropy.h
+++ b/vp10/common/entropy.h
@@ -179,9 +179,7 @@
 extern const vpx_prob
     vp10_pareto8_token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2];
 
-void vp10_build_pareto8_cdf_tab(
-    const vpx_prob token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2],
-    rans_dec_lut cdf_tab[COEFF_PROB_MODELS]);
+typedef rans_dec_lut coeff_cdf_model[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS];
 #endif  // CONFIG_ANS
 
 typedef vpx_prob vp10_coeff_probs_model[REF_TYPES][COEF_BANDS]
@@ -229,6 +227,10 @@
   return combine_entropy_contexts(above_ec, left_ec);
 }
 
+#if CONFIG_ANS
+struct frame_contexts;
+void vp10_coef_pareto_cdfs(struct frame_contexts *fc);
+#endif  // CONFIG_ANS
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h
index f8e507e..d9e8cfb 100644
--- a/vp10/common/entropymode.h
+++ b/vp10/common/entropymode.h
@@ -53,6 +53,9 @@
   vpx_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1];
 #endif
   vp10_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
+#if CONFIG_ANS
+  coeff_cdf_model coef_cdfs[TX_SIZES][PLANE_TYPES];
+#endif
   vpx_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
                                  [SWITCHABLE_FILTERS - 1];
 
diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h
index 3ac17e2..7d0b259 100644
--- a/vp10/common/onyxc_int.h
+++ b/vp10/common/onyxc_int.h
@@ -340,9 +340,6 @@
   // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon
   // each keyframe and not used afterwards
   vpx_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1];
-#if CONFIG_ANS
-  rans_dec_lut token_tab[COEFF_PROB_MODELS];
-#endif  // CONFIG_ANS
 
   BLOCK_SIZE sb_size;   // Size of the superblock used for this frame
   int mib_size;         // Size of the superblock in units of MI blocks
diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c
index 0e51b15..0860ec5 100644
--- a/vp10/decoder/decodeframe.c
+++ b/vp10/decoder/decodeframe.c
@@ -259,7 +259,6 @@
 
 static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
 #if CONFIG_ANS
-                                         const rans_dec_lut *const token_tab,
                                                 struct AnsDecoder *const r,
 #else
                                                 vp10_reader *r,
@@ -287,9 +286,6 @@
     TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
     const scan_order *sc = get_scan(tx_size, tx_type, 0);
     const int eob = vp10_decode_block_tokens(xd,
-#if CONFIG_ANS
-                                             token_tab,
-#endif  // CONFIG_ANS
                                              plane, sc, col, row, tx_size,
                                              tx_type, r, mbmi->segment_id);
     inverse_transform_block(xd, plane, tx_type, tx_size,
@@ -357,7 +353,6 @@
 #if !CONFIG_VAR_TX || CONFIG_SUPERTX
 static int reconstruct_inter_block(MACROBLOCKD *const xd,
 #if CONFIG_ANS
-                                   const rans_dec_lut *const token_tab,
                                    struct AnsDecoder *const r,
 #else
                                    vp10_reader *r,
@@ -370,9 +365,6 @@
   TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
   const scan_order *sc = get_scan(tx_size, tx_type, 1);
   const int eob = vp10_decode_block_tokens(xd,
-#if CONFIG_ANS
-                                           token_tab,
-#endif
                                            plane, sc, col, row,
                                            tx_size, tx_type, r,
                                            mbmi->segment_id);
@@ -1878,9 +1870,6 @@
         for (row = 0; row < max_blocks_high; row += step)
           for (col = 0; col < max_blocks_wide; col += step)
             predict_and_reconstruct_intra_block(xd,
-#if CONFIG_ANS
-                                                cm->token_tab,
-#endif
                                                 r,
                                                 mbmi, plane,
                                                 row, col, tx_size);
@@ -1981,9 +1970,6 @@
           for (row = 0; row < max_blocks_high; row += step)
             for (col = 0; col < max_blocks_wide; col += step)
               eobtotal += reconstruct_inter_block(xd,
-#if CONFIG_ANS
-                                                  cm->token_tab,
-#endif
                                                   r,
                                                   mbmi, plane, row, col,
                                                   tx_size);
@@ -2381,9 +2367,6 @@
         for (row = 0; row < max_blocks_high; row += step)
           for (col = 0; col < max_blocks_wide; col += step)
             eobtotal += reconstruct_inter_block(xd,
-#if CONFIG_ANS
-                                                cm->token_tab,
-#endif
                                                 r,
                                                 mbmi, i, row, col,
                                                 tx_size);
@@ -2495,6 +2478,9 @@
     TX_SIZE tx_size;
     for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
       read_coef_probs_common(fc->coef_probs[tx_size], r);
+#if CONFIG_ANS
+    vp10_coef_pareto_cdfs(fc);
+#endif  // CONFIG_ANS
 }
 
 static void setup_segmentation(VP10_COMMON *const cm,
diff --git a/vp10/decoder/decoder.c b/vp10/decoder/decoder.c
index 11ffe88..6d567d6 100644
--- a/vp10/decoder/decoder.c
+++ b/vp10/decoder/decoder.c
@@ -122,9 +122,6 @@
 #if CONFIG_LOOP_RESTORATION
   vp10_loop_restoration_precal();
 #endif  // CONFIG_LOOP_RESTORATION
-#if CONFIG_ANS
-  vp10_build_pareto8_cdf_tab(vp10_pareto8_token_probs, cm->token_tab);
-#endif  // CONFIG_ANS
 
   cm->error.setjmp = 0;
 
diff --git a/vp10/decoder/detokenize.c b/vp10/decoder/detokenize.c
index def3d7a..44cb58d 100644
--- a/vp10/decoder/detokenize.c
+++ b/vp10/decoder/detokenize.c
@@ -220,7 +220,6 @@
 }
 
 static int decode_coefs_ans(const MACROBLOCKD *const xd,
-                            const rans_dec_lut *const token_tab,
                             PLANE_TYPE type,
                             tran_low_t *dqcoeff, TX_SIZE tx_size,
                             TX_TYPE tx_type,
@@ -234,7 +233,10 @@
   int band, c = 0;
   const vpx_prob (*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
       fc->coef_probs[tx_size][type][ref];
+  const rans_dec_lut(*coef_cdfs)[COEFF_CONTEXTS] =
+      fc->coef_cdfs[tx_size][type][ref];
   const vpx_prob *prob;
+  const rans_dec_lut *cdf;
   unsigned int (*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1];
   unsigned int (*eob_branch_count)[COEFF_CONTEXTS];
   uint8_t token_cache[MAX_TX_SQUARE];
@@ -312,8 +314,9 @@
       band = *band_translate++;
       prob = coef_probs[band][ctx];
     }
+    cdf = &coef_cdfs[band][ctx];
 
-    token = ONE_TOKEN + rans_read(ans, token_tab[prob[PIVOT_NODE] - 1]);
+    token = ONE_TOKEN + rans_read(ans, *cdf);
     INCREMENT_COUNT(ONE_TOKEN + (token > ONE_TOKEN));
     switch (token) {
       case ONE_TOKEN:
@@ -458,9 +461,6 @@
 }
 
 int vp10_decode_block_tokens(MACROBLOCKD *const xd,
-#if CONFIG_ANS
-                             const rans_dec_lut *const token_tab,
-#endif  // CONFIG_ANS
                              int plane, const scan_order *sc,
                              int x, int y,
                              TX_SIZE tx_size,
@@ -480,7 +480,7 @@
                                pd->dqcoeff, tx_size, tx_type,
                                dequant, ctx, sc->scan, sc->neighbors, r);
 #else
-  const int eob = decode_coefs_ans(xd, token_tab, pd->plane_type,
+  const int eob = decode_coefs_ans(xd, pd->plane_type,
                                    pd->dqcoeff, tx_size, tx_type,
                                    dequant, ctx, sc->scan, sc->neighbors, r);
 #endif  // !CONFIG_ANS
diff --git a/vp10/decoder/detokenize.h b/vp10/decoder/detokenize.h
index a19d90f..7b25b41 100644
--- a/vp10/decoder/detokenize.h
+++ b/vp10/decoder/detokenize.h
@@ -23,9 +23,6 @@
 void vp10_decode_palette_tokens(MACROBLOCKD *const xd, int plane,
                                 vp10_reader *r);
 int vp10_decode_block_tokens(MACROBLOCKD *const xd,
-#if CONFIG_ANS
-                             const rans_dec_lut *const token_tab,
-#endif  // CONFIG_ANS
                              int plane, const scan_order *sc,
                              int x, int y,
                              TX_SIZE tx_size,
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index b7bd6fc..47c0942 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -676,7 +676,6 @@
 // This function serializes the tokens in forward order using a buffered ans
 // coder.
 static void pack_mb_tokens_ans(struct BufAnsCoder *ans,
-                               const rans_dec_lut token_tab[COEFF_PROB_MODELS],
                                const TOKENEXTRA **tp,
                                const TOKENEXTRA *const stop,
                                vpx_bit_depth_t bit_depth,
@@ -711,8 +710,7 @@
 
       if (t != ZERO_TOKEN) {
         struct rans_sym s;
-        const rans_dec_lut *token_cdf =
-            &token_tab[p->context_tree[PIVOT_NODE] - 1];
+        const rans_dec_lut *token_cdf = p->token_cdf;
         s.cum_prob = (*token_cdf)[t - ONE_TOKEN];
         s.prob = (*token_cdf)[t - ONE_TOKEN + 1] - s.cum_prob;
         buf_rans_write(ans, &s);
@@ -1587,8 +1585,7 @@
         for (row = 0; row < num_4x4_h; row += bw)
           for (col = 0; col < num_4x4_w; col += bw)
 #if CONFIG_ANS
-            pack_mb_tokens_ans(w, cm->token_tab, tok, tok_end, cm->bit_depth,
-                               tx);
+            pack_mb_tokens_ans(w, tok, tok_end, cm->bit_depth, tx);
 #else
             pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx);
 #endif  // CONFIG_ANS
@@ -1597,7 +1594,7 @@
       TX_SIZE tx = plane ? get_uv_tx_size(&m->mbmi, &xd->plane[plane])
                          : m->mbmi.tx_size;
 #if CONFIG_ANS
-      pack_mb_tokens_ans(w, cm->token_tab, tok, tok_end, cm->bit_depth, tx);
+      pack_mb_tokens_ans(w, tok, tok_end, cm->bit_depth, tx);
 #else
       pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx);
 #endif  // CONFIG_ANS
@@ -1805,8 +1802,7 @@
       for (row = 0; row < num_4x4_h; row += bw)
         for (col = 0; col < num_4x4_w; col += bw)
 #if CONFIG_ANS
-          pack_mb_tokens_ans(w, cm->token_tab, tok, tok_end, cm->bit_depth,
-                             tx);
+          pack_mb_tokens_ans(w, tok, tok_end, cm->bit_depth, tx);
 #else
           pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx);
 #endif
@@ -2244,6 +2240,9 @@
   const TX_MODE tx_mode = cpi->common.tx_mode;
   const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
   TX_SIZE tx_size;
+#if CONFIG_ANS
+  int update = 0;
+#endif  // CONFIG_ANS
 #if CONFIG_ENTROPY
   VP10_COMMON *cm = &cpi->common;
   SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
@@ -2296,12 +2295,18 @@
 
         update_coef_probs_subframe(w, cpi, tx_size, branch_ct,
                                    frame_coef_probs);
+#if CONFIG_ANS
+        update = 1;
+#endif  // CONFIG_ANS
       } else {
 #endif  // CONFIG_ENTROPY
         build_tree_distribution(cpi, tx_size, frame_branch_ct,
                                 frame_coef_probs);
         update_coef_probs_common(w, cpi, tx_size, frame_branch_ct,
                                  frame_coef_probs);
+#if CONFIG_ANS
+        update = 1;
+#endif  // CONFIG_ANS
 #if CONFIG_ENTROPY
       }
 #endif  // CONFIG_ENTROPY
@@ -2326,6 +2331,9 @@
     vp10_copy(cm->counts.eob_branch, eob_counts_copy);
   }
 #endif  // CONFIG_ENTROPY
+#if CONFIG_ANS
+  if (update) vp10_coef_pareto_cdfs(cpi->common.fc);
+#endif  // CONFIG_ANS
 }
 
 #if CONFIG_LOOP_RESTORATION
diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c
index 2d51114..40d4c36 100644
--- a/vp10/encoder/encoder.c
+++ b/vp10/encoder/encoder.c
@@ -2485,9 +2485,6 @@
 #if CONFIG_LOOP_RESTORATION
   vp10_loop_restoration_precal();
 #endif  // CONFIG_LOOP_RESTORATION
-#if CONFIG_ANS
-  vp10_build_pareto8_cdf_tab(vp10_pareto8_token_probs, cm->token_tab);
-#endif  // CONFIG_ANS
 
   cm->error.setjmp = 0;
 
diff --git a/vp10/encoder/tokenize.c b/vp10/encoder/tokenize.c
index a283b10..5aed80c 100644
--- a/vp10/encoder/tokenize.c
+++ b/vp10/encoder/tokenize.c
@@ -363,12 +363,17 @@
 }
 
 static INLINE void add_token(TOKENEXTRA **t, const vpx_prob *context_tree,
+#if CONFIG_ANS
+                             const rans_dec_lut *token_cdf,
+#endif  // CONFIG_ANS
                              int32_t extra, uint8_t token,
-                             uint8_t skip_eob_node,
-                             unsigned int *counts) {
+                             uint8_t skip_eob_node, unsigned int *counts) {
   (*t)->token = token;
   (*t)->extra = extra;
   (*t)->context_tree = context_tree;
+#if CONFIG_ANS
+  (*t)->token_cdf = token_cdf;
+#endif  // CONFIG_ANS
   (*t)->skip_eob_node = skip_eob_node;
   (*t)++;
   ++counts[token];
@@ -463,6 +468,10 @@
   vpx_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
       cpi->common.fc->coef_probs[tx_size][type][ref];
 #endif  // CONFIG_ENTROPY
+#if CONFIG_ANS
+  rans_dec_lut(*const coef_cdfs)[COEFF_CONTEXTS] =
+      cpi->common.fc->coef_cdfs[tx_size][type][ref];
+#endif  // CONFIG_ANS
   unsigned int (*const eob_branch)[COEFF_CONTEXTS] =
       td->counts->eob_branch[tx_size][type][ref];
   const uint8_t *const band = get_band_translate(tx_size);
@@ -495,8 +504,11 @@
 
     vp10_get_token_extra(v, &token, &extra);
 
-    add_token(&t, coef_probs[band[c]][pt], extra, (uint8_t)token,
-              (uint8_t)skip_eob, counts[band[c]][pt]);
+    add_token(&t, coef_probs[band[c]][pt],
+#if CONFIG_ANS
+              &coef_cdfs[band[c]][pt],
+#endif  // CONFIG_ANS
+              extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
     eob_branch[band[c]][pt] += !skip_eob;
 
     token_cache[scan[c]] = vp10_pt_energy_class[token];
diff --git a/vp10/encoder/tokenize.h b/vp10/encoder/tokenize.h
index 46b7f3f..c9b20df 100644
--- a/vp10/encoder/tokenize.h
+++ b/vp10/encoder/tokenize.h
@@ -36,6 +36,9 @@
 
 typedef struct {
   const vpx_prob *context_tree;
+#if CONFIG_ANS
+  const rans_dec_lut *token_cdf;
+#endif  // CONFIG_ANS
   EXTRABIT extra;
   uint8_t token;
   uint8_t skip_eob_node;