Update switchable_interp_cdf once per frame.

Move from computing the switchable_interp_cdf per symbol to
 computing once per frame when the probabilities are adapted.

Change-Id: I6571126239f0327e22bb09ee8bad94114291683e
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 9d53df1..d140836 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -396,8 +396,17 @@
 #endif
   av1_copy(fc->intra_ext_tx_prob, default_intra_ext_tx_prob);
   av1_copy(fc->inter_ext_tx_prob, default_inter_ext_tx_prob);
+#if CONFIG_DAALA_EC
+  av1_tree_to_cdf_1D(av1_switchable_interp_tree, fc->switchable_interp_prob,
+                     fc->switchable_interp_cdf, SWITCHABLE_FILTER_CONTEXTS);
+#endif
 }
 
+#if CONFIG_DAALA_EC
+int av1_switchable_interp_ind[SWITCHABLE_FILTERS];
+int av1_switchable_interp_inv[SWITCHABLE_FILTERS];
+#endif
+
 #if CONFIG_EXT_INTERP
 const aom_tree_index av1_switchable_interp_tree[TREE_SIZE(SWITCHABLE_FILTERS)] =
     {
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index a84f90d..6bf0ab7 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -94,6 +94,10 @@
   aom_prob intra_ext_tx_prob[EXT_TX_SIZES][TX_TYPES][TX_TYPES - 1];
   aom_prob inter_ext_tx_prob[EXT_TX_SIZES][TX_TYPES - 1];
   int initialized;
+#if CONFIG_DAALA_EC
+  uint16_t
+      switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
+#endif
 } FRAME_CONTEXT;
 
 typedef struct FRAME_COUNTS {
@@ -153,6 +157,11 @@
 extern const aom_tree_index
     av1_switchable_interp_tree[TREE_SIZE(SWITCHABLE_FILTERS)];
 
+#if CONFIG_DAALA_EC
+extern int av1_switchable_interp_ind[SWITCHABLE_FILTERS];
+extern int av1_switchable_interp_inv[SWITCHABLE_FILTERS];
+#endif
+
 void av1_setup_past_independence(struct AV1Common *cm);
 
 void av1_adapt_intra_frame_probs(struct AV1Common *cm);
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 27591aa..c9e7188 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -128,9 +128,14 @@
 
 static void read_switchable_interp_probs(FRAME_CONTEXT *fc, aom_reader *r) {
   int i, j;
-  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
+  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
     for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
       av1_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
+#if CONFIG_DAALA_EC
+    av1_tree_to_cdf(av1_switchable_interp_tree, fc->switchable_interp_prob[j],
+                    fc->switchable_interp_cdf[j]);
+#endif
+  }
 }
 
 static void read_inter_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 4546149..5e6190d 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -594,8 +594,14 @@
 #endif
     {
       const int ctx = av1_get_pred_context_switchable_interp(xd);
+#if CONFIG_DAALA_EC
+      const InterpFilter type =
+          (InterpFilter)av1_switchable_interp_inv[aom_read_tree_cdf(
+              r, cm->fc->switchable_interp_cdf[ctx], SWITCHABLE_FILTERS)];
+#else
       const InterpFilter type = (InterpFilter)aom_read_tree(
           r, av1_switchable_interp_tree, cm->fc->switchable_interp_prob[ctx]);
+#endif
       FRAME_COUNTS *counts = xd->counts;
       if (counts) ++counts->switchable_interp[ctx][type];
       return type;
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 0b78446..c75e00f 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -43,6 +43,10 @@
     aom_scale_rtcd();
     av1_init_intra_predictors();
     init_done = 1;
+#if CONFIG_DAALA_EC
+    av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
+                          SWITCHABLE_FILTERS, av1_switchable_interp_tree);
+#endif
   }
 }
 
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 48cdcaf..eb0ba4a 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -65,6 +65,13 @@
   av1_tokens_from_tree(motion_mode_encodings, av1_motion_mode_tree);
 #endif  // CONFIG_MOTION_VAR
   av1_tokens_from_tree(ext_tx_encodings, av1_ext_tx_tree);
+#if CONFIG_DAALA_EC
+  /* This hack is necessary when CONFIG_EXT_INTERP is enabled because the five
+      SWITCHABLE_FILTERS are not consecutive, e.g., 0, 1, 2, 3, 4, when doing
+      an in-order traversal of the av1_switchable_interp_tree structure. */
+  av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
+                        SWITCHABLE_FILTERS, av1_switchable_interp_tree);
+#endif
 }
 
 static void write_intra_mode(aom_writer *w, PREDICTION_MODE mode,
@@ -249,10 +256,16 @@
 static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w,
                                            FRAME_COUNTS *counts) {
   int j;
-  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
+  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
     prob_diff_update(av1_switchable_interp_tree,
                      cm->fc->switchable_interp_prob[j],
                      counts->switchable_interp[j], SWITCHABLE_FILTERS, w);
+#if CONFIG_DAALA_EC
+    av1_tree_to_cdf(av1_switchable_interp_tree,
+                    cm->fc->switchable_interp_prob[j],
+                    cm->fc->switchable_interp_cdf[j]);
+#endif
+  }
 }
 
 static void update_ext_tx_probs(AV1_COMMON *cm, aom_writer *w) {
@@ -518,9 +531,15 @@
     if (is_interp_needed(xd)) {
 #endif
       const int ctx = av1_get_pred_context_switchable_interp(xd);
+#if CONFIG_DAALA_EC
+      aom_write_tree_cdf(w, av1_switchable_interp_ind[mbmi->interp_filter],
+                         cm->fc->switchable_interp_cdf[ctx],
+                         SWITCHABLE_FILTERS);
+#else
       av1_write_token(w, av1_switchable_interp_tree,
                       cm->fc->switchable_interp_prob[ctx],
                       &switchable_interp_encodings[mbmi->interp_filter]);
+#endif
       ++cpi->interp_filter_selected[0][mbmi->interp_filter];
 #if CONFIG_EXT_INTERP
     } else {