Merge "Update kf_y_mode_cdf tables once per frame." into nextgenv2
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 78f4ffe..3a6b3c3 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -147,6 +147,9 @@
       { 43, 81, 53, 140, 169, 204, 68, 84, 72 }     // left = tm
   }
 };
+#if CONFIG_DAALA_EC
+aom_cdf_prob av1_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][INTRA_MODES];
+#endif
 
 static const aom_prob default_if_y_probs[BLOCK_SIZE_GROUPS][INTRA_MODES - 1] = {
   { 65, 32, 18, 144, 162, 194, 41, 51, 98 },   // block_size < 8x8
@@ -368,6 +371,8 @@
 static const aom_prob default_delta_q_probs[DELTA_Q_CONTEXTS] = { 220, 220,
                                                                   220 };
 #endif
+int av1_intra_mode_ind[INTRA_MODES];
+int av1_intra_mode_inv[INTRA_MODES];
 
 /* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
 const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
@@ -1414,6 +1419,8 @@
                      fc->inter_ext_tx_cdf, EXT_TX_SIZES);
   av1_tree_to_cdf_1D(av1_partition_tree, fc->partition_prob, fc->partition_cdf,
                      PARTITION_CONTEXTS);
+  av1_tree_to_cdf_2D(av1_intra_mode_tree, av1_kf_y_mode_prob, av1_kf_y_mode_cdf,
+                     INTRA_MODES, INTRA_MODES);
   av1_tree_to_cdf(av1_segment_tree, fc->seg.tree_probs, fc->seg.tree_cdf);
 #endif
 #if CONFIG_DELTA_Q
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 68a6400..f889c56 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -276,6 +276,9 @@
 
 extern const aom_prob av1_kf_y_mode_prob[INTRA_MODES][INTRA_MODES]
                                         [INTRA_MODES - 1];
+#if CONFIG_DAALA_EC
+extern aom_cdf_prob av1_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][INTRA_MODES];
+#endif
 #if CONFIG_PALETTE
 extern const aom_prob av1_default_palette_y_mode_prob[PALETTE_BLOCK_SIZES]
                                                      [PALETTE_Y_MODE_CONTEXTS];
@@ -294,6 +297,10 @@
 
 extern const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
 extern const aom_tree_index av1_inter_mode_tree[TREE_SIZE(INTER_MODES)];
+#if CONFIG_DAALA_EC
+extern int av1_intra_mode_ind[INTRA_MODES];
+extern int av1_intra_mode_inv[INTRA_MODES];
+#endif
 #if CONFIG_EXT_INTER
 extern const aom_tree_index
     av1_interintra_mode_tree[TREE_SIZE(INTERINTRA_MODES)];
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 3c8eac8..b6e73cd 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -378,6 +378,9 @@
   // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon
   // each keyframe and not used afterwards
   aom_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1];
+#if CONFIG_DAALA_EC
+  aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES][INTRA_MODES];
+#endif
 #if CONFIG_GLOBAL_MOTION
   Global_Motion_Params global_motion[TOTAL_REFS_PER_FRAME];
 #endif
@@ -582,6 +585,18 @@
   return cm->kf_y_prob[above][left];
 }
 
+#if CONFIG_DAALA_EC
+static INLINE const aom_cdf_prob *get_y_mode_cdf(const AV1_COMMON *cm,
+                                                 const MODE_INFO *mi,
+                                                 const MODE_INFO *above_mi,
+                                                 const MODE_INFO *left_mi,
+                                                 int block) {
+  const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, block);
+  const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, block);
+  return cm->kf_y_cdf[above][left];
+}
+#endif
+
 static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row,
                                             int mi_col, BLOCK_SIZE subsize,
                                             BLOCK_SIZE bsize) {
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 2e6e744..b52724f 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3746,10 +3746,18 @@
 
   if (frame_is_intra_only(cm)) {
     av1_copy(cm->kf_y_prob, av1_kf_y_mode_prob);
+#if CONFIG_DAALA_EC
+    av1_copy(cm->kf_y_cdf, av1_kf_y_mode_cdf);
+#endif
     for (k = 0; k < INTRA_MODES; k++)
-      for (j = 0; j < INTRA_MODES; j++)
+      for (j = 0; j < INTRA_MODES; j++) {
         for (i = 0; i < INTRA_MODES - 1; ++i)
           av1_diff_update_prob(&r, &cm->kf_y_prob[k][j][i], ACCT_STR);
+#if CONFIG_DAALA_EC
+        av1_tree_to_cdf(av1_intra_mode_tree, cm->kf_y_prob[k][j],
+                        cm->kf_y_cdf[k][j]);
+#endif
+      }
   } else {
 #if !CONFIG_REF_MV
     nmv_context *const nmvc = &fc->nmvc;
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 8260f9d..68eb482 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -26,7 +26,6 @@
 #include "aom_dsp/aom_dsp_common.h"
 
 #define ACCT_STR __func__
-
 #if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
 static INLINE int read_uniform(aom_reader *r, int n) {
   int l = get_unsigned_bits(n);
@@ -42,6 +41,13 @@
 }
 #endif  // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
 
+#if CONFIG_DAALA_EC
+static PREDICTION_MODE read_intra_mode_cdf(aom_reader *r,
+                                           const aom_cdf_prob *cdf) {
+  return (PREDICTION_MODE)
+      av1_intra_mode_inv[aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR)];
+}
+#endif
 static PREDICTION_MODE read_intra_mode(aom_reader *r, const aom_prob *p) {
   return (PREDICTION_MODE)aom_read_tree(r, av1_intra_mode_tree, p, ACCT_STR);
 }
@@ -657,24 +663,49 @@
     case BLOCK_4X4:
       for (i = 0; i < 4; ++i)
         mi->bmi[i].as_mode =
+#if CONFIG_DAALA_EC
+            read_intra_mode_cdf(r,
+                                get_y_mode_cdf(cm, mi, above_mi, left_mi, i));
+#else
             read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
+#endif
       mbmi->mode = mi->bmi[3].as_mode;
       break;
     case BLOCK_4X8:
       mi->bmi[0].as_mode = mi->bmi[2].as_mode =
+#if CONFIG_DAALA_EC
+          read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
+#else
           read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
+#endif
       mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
+#if CONFIG_DAALA_EC
+          read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 1));
+#else
           read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
+#endif
       break;
     case BLOCK_8X4:
       mi->bmi[0].as_mode = mi->bmi[1].as_mode =
+#if CONFIG_DAALA_EC
+          read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
+#else
           read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
+#endif
       mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
+#if CONFIG_DAALA_EC
+          read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 2));
+#else
           read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
+#endif
       break;
     default:
       mbmi->mode =
+#if CONFIG_DAALA_EC
+          read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
+#else
           read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
+#endif
   }
 
   mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 9952650..ca97817 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -52,6 +52,8 @@
                           SWITCHABLE_FILTERS, av1_switchable_interp_tree);
     av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES,
                           av1_ext_tx_tree);
+    av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, INTRA_MODES,
+                          av1_intra_mode_tree);
 #endif
   }
 }
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index e0fb7ec..70f7e7b 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -192,6 +192,8 @@
       structure. */
   av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES,
                         av1_ext_tx_tree);
+  av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, INTRA_MODES,
+                        av1_intra_mode_tree);
 #endif
 }
 
@@ -1622,8 +1624,13 @@
     write_selected_tx_size(cm, xd, w);
 
   if (bsize >= BLOCK_8X8) {
+#if CONFIG_DAALA_EC
+    aom_write_symbol(w, av1_intra_mode_ind[mbmi->mode],
+                     get_y_mode_cdf(cm, mi, above_mi, left_mi, 0), INTRA_MODES);
+#else
     write_intra_mode(w, mbmi->mode,
                      get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
+#endif
   } else {
     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -1632,8 +1639,14 @@
     for (idy = 0; idy < 2; idy += num_4x4_h) {
       for (idx = 0; idx < 2; idx += num_4x4_w) {
         const int block = idy * 2 + idx;
+#if CONFIG_DAALA_EC
+        aom_write_symbol(w, av1_intra_mode_ind[mi->bmi[block].as_mode],
+                         get_y_mode_cdf(cm, mi, above_mi, left_mi, block),
+                         INTRA_MODES);
+#else
         write_intra_mode(w, mi->bmi[block].as_mode,
                          get_y_mode_probs(cm, mi, above_mi, left_mi, block));
+#endif
       }
     }
   }
@@ -3621,10 +3634,18 @@
 
   if (frame_is_intra_only(cm)) {
     av1_copy(cm->kf_y_prob, av1_kf_y_mode_prob);
+#if CONFIG_DAALA_EC
+    av1_copy(cm->kf_y_cdf, av1_kf_y_mode_cdf);
+#endif
     for (i = 0; i < INTRA_MODES; ++i)
-      for (j = 0; j < INTRA_MODES; ++j)
+      for (j = 0; j < INTRA_MODES; ++j) {
         prob_diff_update(av1_intra_mode_tree, cm->kf_y_prob[i][j],
                          counts->kf_y_mode[i][j], INTRA_MODES, header_bc);
+#if CONFIG_DAALA_EC
+        av1_tree_to_cdf(av1_intra_mode_tree, cm->kf_y_prob[i][j],
+                        cm->kf_y_cdf[i][j]);
+#endif
+      }
   } else {
 #if CONFIG_REF_MV
     update_inter_mode_probs(cm, header_bc, counts);