Merge "Add EC_ADAPT experiment for symbol-adaptive entropy coding." into nextgenv2
diff --git a/aom_dsp/bitreader.h b/aom_dsp/bitreader.h
index ef2e5e9..058a513 100644
--- a/aom_dsp/bitreader.h
+++ b/aom_dsp/bitreader.h
@@ -203,7 +203,7 @@
   return ret;
 }
 
-static INLINE int aom_read_symbol_(aom_reader *r, const aom_cdf_prob *cdf,
+static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
                                    int nsymbs ACCT_STR_PARAM) {
   int ret;
 #if CONFIG_RANS
@@ -218,6 +218,10 @@
   assert(0 && "Unsupported bitreader operation");
   ret = -1;
 #endif
+#if ((CONFIG_RANS || CONFIG_DAALA_EC) && CONFIG_EC_ADAPT)
+  update_cdf(cdf, ret, nsymbs);
+#endif
+
 #if CONFIG_ACCOUNTING
   if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
 #endif
diff --git a/aom_dsp/bitwriter.h b/aom_dsp/bitwriter.h
index 841a171..ebcedfc 100644
--- a/aom_dsp/bitwriter.h
+++ b/aom_dsp/bitwriter.h
@@ -98,8 +98,8 @@
 #endif
 }
 
-static INLINE void aom_write_symbol(aom_writer *w, int symb,
-                                    const aom_cdf_prob *cdf, int nsymbs) {
+static INLINE void aom_write_symbol(aom_writer *w, int symb, aom_cdf_prob *cdf,
+                                    int nsymbs) {
 #if CONFIG_RANS
   struct rans_sym s;
   (void)nsymbs;
@@ -116,6 +116,10 @@
   (void)nsymbs;
   assert(0 && "Unsupported bitwriter operation");
 #endif
+
+#if ((CONFIG_RANS || CONFIG_DAALA_EC) && CONFIG_EC_ADAPT)
+  update_cdf(cdf, symb, nsymbs);
+#endif
 }
 
 #ifdef __cplusplus
diff --git a/aom_dsp/prob.h b/aom_dsp/prob.h
index fcd1a74..95934cd 100644
--- a/aom_dsp/prob.h
+++ b/aom_dsp/prob.h
@@ -15,6 +15,7 @@
 #include "./aom_config.h"
 #include "./aom_dsp_common.h"
 
+#include "aom_ports/bitops.h"
 #include "aom_ports/mem.h"
 
 #ifdef __cplusplus
@@ -134,6 +135,42 @@
 
 DECLARE_ALIGNED(16, extern const uint8_t, aom_norm[256]);
 
+#if CONFIG_EC_ADAPT
+static INLINE void update_cdf(aom_cdf_prob *cdf, int val, int nsymbs) {
+  const int rate = 3 + get_msb(nsymbs);
+  // Daala method
+  int i, tmp;
+  for (i = 0; i < val; ++i) {
+    tmp = 2 - (1 << rate) + i;
+    cdf[i] -= (cdf[i] - tmp) >> rate;
+  }
+  for (i = val; i < nsymbs; ++i) {
+    tmp = -(1 << rate) + 32768 + (1 << rate) - ((nsymbs - 1) - i);
+    cdf[i] -= (cdf[i] - tmp) >> rate;
+  }
+
+  // Slightly better
+  //  int prob[16];
+  //  int i;
+  //  int diff;
+  //  prob[0] = cdf[0];
+  //  for (i=1; i<nsymbs; ++i)
+  //    prob[i] = cdf[i] - cdf[i-1];
+  //
+  //  for (i=0; i<nsymbs; ++i) {
+  //    prob[i] -= (prob[i] >> rate);
+  //    prob[i] = AOMMAX(prob[i],1);
+  //    cdf[i] = i==0 ? prob[i] : cdf[i-1]+prob[i];
+  //  }
+  //  diff = (1<<15) - cdf[nsymbs-1];
+  //
+  //  for (i=val; i<nsymbs; ++i) {
+  //    cdf[i] += diff;
+  //  }
+  //
+}
+#endif
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index e0e18e1..f515786 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -592,11 +592,10 @@
 }
 
 #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) {
+static INLINE aom_cdf_prob *get_y_mode_cdf(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];
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index ab535ae..cb45445 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -114,6 +114,7 @@
   return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
 }
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 static void read_switchable_interp_probs(FRAME_CONTEXT *fc, aom_reader *r) {
   int i, j;
   for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) {
@@ -165,6 +166,34 @@
   }
 }
 #endif  // CONFIG_EXT_INTER
+#if !CONFIG_EXT_TX
+static void read_ext_tx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
+  int i, j, k;
+  if (aom_read(r, GROUP_DIFF_UPDATE_PROB, ACCT_STR)) {
+    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
+      for (j = 0; j < TX_TYPES; ++j) {
+        for (k = 0; k < TX_TYPES - 1; ++k)
+          av1_diff_update_prob(r, &fc->intra_ext_tx_prob[i][j][k], ACCT_STR);
+#if CONFIG_DAALA_EC
+        av1_tree_to_cdf(av1_ext_tx_tree, fc->intra_ext_tx_prob[i][j],
+                        fc->intra_ext_tx_cdf[i][j]);
+#endif
+      }
+    }
+  }
+  if (aom_read(r, GROUP_DIFF_UPDATE_PROB, ACCT_STR)) {
+    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
+      for (k = 0; k < TX_TYPES - 1; ++k)
+        av1_diff_update_prob(r, &fc->inter_ext_tx_prob[i][k], ACCT_STR);
+#if CONFIG_DAALA_EC
+      av1_tree_to_cdf(av1_ext_tx_tree, fc->inter_ext_tx_prob[i],
+                      fc->inter_ext_tx_cdf[i]);
+#endif
+    }
+  }
+}
+#endif
+#endif
 
 static REFERENCE_MODE read_frame_reference_mode(
     const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
@@ -214,8 +243,10 @@
 }
 
 static void read_mv_probs(nmv_context *ctx, int allow_hp, aom_reader *r) {
-  int i, j;
+  int i;
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
+  int j;
   update_mv_probs(ctx->joints, MV_JOINTS - 1, r);
 #if CONFIG_DAALA_EC || CONFIG_RANS
   av1_tree_to_cdf(av1_mv_joint_tree, ctx->joints, ctx->joint_cdf);
@@ -231,7 +262,6 @@
     av1_tree_to_cdf(av1_mv_class_tree, comp_ctx->classes, comp_ctx->class_cdf);
 #endif
   }
-
   for (i = 0; i < 2; ++i) {
     nmv_component *const comp_ctx = &ctx->comps[i];
     for (j = 0; j < CLASS0_SIZE; ++j) {
@@ -246,6 +276,7 @@
     av1_tree_to_cdf(av1_mv_fp_tree, comp_ctx->fp, comp_ctx->fp_cdf);
 #endif
   }
+#endif  // CONFIG_EC_ADAPT, CONFIG_DAALA_EC
 
   if (allow_hp) {
     for (i = 0; i < 2; ++i) {
@@ -1885,13 +1916,18 @@
 static void read_coef_probs_common(av1_coeff_probs_model *coef_probs,
                                    aom_reader *r) {
   int i, j, k, l, m;
+#if CONFIG_EC_ADAPT
+  const int node_limit = ONE_TOKEN;
+#else
+  const int node_limit = UNCONSTRAINED_NODES;
+#endif
 
   if (aom_read_bit(r, ACCT_STR))
     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)
-            for (m = 0; m < UNCONSTRAINED_NODES; ++m)
+            for (m = 0; m < node_limit; ++m)
               av1_diff_update_prob(r, &coef_probs[i][j][k][l][m], ACCT_STR);
 }
 
@@ -3587,6 +3623,7 @@
 }
 
 #if CONFIG_EXT_TX
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 static void read_ext_tx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
   int i, j, k;
   int s;
@@ -3612,36 +3649,10 @@
     }
   }
 }
-
+#endif  // !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 #else
 
-static void read_ext_tx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
-  int i, j, k;
-  if (aom_read(r, GROUP_DIFF_UPDATE_PROB, ACCT_STR)) {
-    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
-      for (j = 0; j < TX_TYPES; ++j) {
-        for (k = 0; k < TX_TYPES - 1; ++k)
-          av1_diff_update_prob(r, &fc->intra_ext_tx_prob[i][j][k], ACCT_STR);
-#if CONFIG_DAALA_EC
-        av1_tree_to_cdf(av1_ext_tx_tree, fc->intra_ext_tx_prob[i][j],
-                        fc->intra_ext_tx_cdf[i][j]);
-#endif
-      }
-    }
-  }
-  if (aom_read(r, GROUP_DIFF_UPDATE_PROB, ACCT_STR)) {
-    for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
-      for (k = 0; k < TX_TYPES - 1; ++k)
-        av1_diff_update_prob(r, &fc->inter_ext_tx_prob[i][k], ACCT_STR);
-#if CONFIG_DAALA_EC
-      av1_tree_to_cdf(av1_ext_tx_tree, fc->inter_ext_tx_prob[i],
-                      fc->inter_ext_tx_cdf[i]);
-#endif
-    }
-  }
-}
 #endif  // CONFIG_EXT_TX
-
 #if CONFIG_SUPERTX
 static void read_supertx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
   int i, j;
@@ -3765,6 +3776,7 @@
     av1_diff_update_prob(&r, &fc->delta_q_prob[k], ACCT_STR);
 #endif
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
   if (cm->seg.enabled && cm->seg.update_map) {
     if (cm->seg.temporal_update) {
       for (k = 0; k < PREDICTION_PROBS; k++)
@@ -3803,7 +3815,7 @@
 #endif
   }
 #endif  // CONFIG_EXT_PARTITION_TYPES
-
+#endif  // EC_ADAPT, DAALA_EC
 #if CONFIG_EXT_INTRA
   for (i = 0; i < INTRA_FILTERS + 1; ++i)
     for (j = 0; j < INTRA_FILTERS - 1; ++j)
@@ -3815,6 +3827,7 @@
 #if CONFIG_DAALA_EC
     av1_copy(cm->kf_y_cdf, av1_kf_y_mode_cdf);
 #endif
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     for (k = 0; k < INTRA_MODES; k++)
       for (j = 0; j < INTRA_MODES; j++) {
         for (i = 0; i < INTRA_MODES - 1; ++i)
@@ -3824,12 +3837,14 @@
                         cm->kf_y_cdf[k][j]);
 #endif
       }
+#endif  // EC_ADAPT, DAALA_EC
   } else {
 #if !CONFIG_REF_MV
     nmv_context *const nmvc = &fc->nmvc;
 #endif
-
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     read_inter_mode_probs(fc, &r);
+#endif
 
 #if CONFIG_EXT_INTER
     read_inter_compound_mode_probs(fc, &r);
@@ -3865,7 +3880,9 @@
     }
 #endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     if (cm->interp_filter == SWITCHABLE) read_switchable_interp_probs(fc, &r);
+#endif
 
     for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
       av1_diff_update_prob(&r, &fc->intra_inter_prob[i], ACCT_STR);
@@ -3875,6 +3892,7 @@
 
     read_frame_reference_mode_probs(cm, &r);
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     for (j = 0; j < BLOCK_SIZE_GROUPS; j++) {
       for (i = 0; i < INTRA_MODES - 1; ++i)
         av1_diff_update_prob(&r, &fc->y_mode_prob[j][i], ACCT_STR);
@@ -3883,6 +3901,7 @@
                       fc->y_mode_cdf[j]);
 #endif
     }
+#endif
 
 #if CONFIG_REF_MV
     for (i = 0; i < NMV_CONTEXTS; ++i)
@@ -3890,7 +3909,9 @@
 #else
     read_mv_probs(nmvc, cm->allow_high_precision_mv, &r);
 #endif
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     read_ext_tx_probs(fc, &r);
+#endif  // EC_ADAPT, DAALA_EC
 #if CONFIG_SUPERTX
     if (!xd->lossless[0]) read_supertx_probs(fc, &r);
 #endif
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 9aa182d..20f034f 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -42,7 +42,7 @@
 #endif  // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
 
 #if CONFIG_DAALA_EC
-static PREDICTION_MODE read_intra_mode(aom_reader *r, const aom_cdf_prob *cdf) {
+static PREDICTION_MODE read_intra_mode(aom_reader *r, aom_cdf_prob *cdf) {
   return (PREDICTION_MODE)
       av1_intra_mode_inv[aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR)];
 }
@@ -264,8 +264,7 @@
 }
 #endif  // CONFIG_EXT_INTER
 
-static int read_segment_id(aom_reader *r,
-                           const struct segmentation_probs *segp) {
+static int read_segment_id(aom_reader *r, struct segmentation_probs *segp) {
 #if CONFIG_DAALA_EC
   return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
 #else
@@ -796,8 +795,7 @@
   }
 }
 
-static int read_mv_component(aom_reader *r, const nmv_component *mvcomp,
-                             int usehp) {
+static int read_mv_component(aom_reader *r, nmv_component *mvcomp, int usehp) {
   int mag, d, fr, hp;
   const int sign = aom_read(r, mvcomp->sign, ACCT_STR);
   const int mv_class =
@@ -840,7 +838,7 @@
 }
 
 static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
-                           const nmv_context *ctx, nmv_context_counts *counts,
+                           nmv_context *ctx, nmv_context_counts *counts,
                            int allow_hp) {
   MV_JOINT_TYPE joint_type;
   MV diff = { 0, 0 };
diff --git a/av1/decoder/detokenize.c b/av1/decoder/detokenize.c
index 67af6f3..02139ef 100644
--- a/av1/decoder/detokenize.c
+++ b/av1/decoder/detokenize.c
@@ -48,15 +48,13 @@
 }
 
 #if CONFIG_AOM_QM
-static int decode_coefs(const MACROBLOCKD *xd, PLANE_TYPE type,
-                        tran_low_t *dqcoeff, TX_SIZE tx_size, TX_TYPE tx_type,
-                        const int16_t *dq, int ctx, const int16_t *scan,
-                        const int16_t *nb, aom_reader *r,
-                        const qm_val_t *iqm[2][TX_SIZES])
+static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
+                        TX_SIZE tx_size, TX_TYPE tx_type, const int16_t *dq,
+                        int ctx, const int16_t *scan, const int16_t *nb,
+                        aom_reader *r, const qm_val_t *iqm[2][TX_SIZES])
 #else
-static int decode_coefs(const MACROBLOCKD *xd, PLANE_TYPE type,
-                        tran_low_t *dqcoeff, TX_SIZE tx_size, TX_TYPE tx_type,
-                        const int16_t *dq,
+static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
+                        TX_SIZE tx_size, TX_TYPE tx_type, const int16_t *dq,
 #if CONFIG_NEW_QUANT
                         dequant_val_type_nuq *dq_val,
 #endif  // CONFIG_NEW_QUANT
@@ -66,20 +64,20 @@
 {
   FRAME_COUNTS *counts = xd->counts;
   const int max_eob = get_tx2d_size(tx_size);
-  const FRAME_CONTEXT *const fc = xd->fc;
+  FRAME_CONTEXT *const fc = xd->fc;
   const int ref = is_inter_block(&xd->mi[0]->mbmi);
 #if CONFIG_AOM_QM
   const qm_val_t *iqmatrix = iqm[!ref][tx_size];
 #endif
   int band, c = 0;
   const int tx_size_ctx = txsize_sqr_map[tx_size];
-  const aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
+  aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
       fc->coef_probs[tx_size_ctx][type][ref];
   const aom_prob *prob;
 #if CONFIG_RANS || CONFIG_DAALA_EC
-  const aom_cdf_prob(*const coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
+  aom_cdf_prob(*coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
       fc->coef_cdfs[tx_size_ctx][type][ref];
-  const aom_cdf_prob(*cdf)[ENTROPY_TOKENS];
+  aom_cdf_prob(*cdf)[ENTROPY_TOKENS];
 #endif  // CONFIG_RANS
   unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1];
   unsigned int(*eob_branch_count)[COEFF_CONTEXTS];
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 25b02e4..b17d0e4 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -329,6 +329,7 @@
     av1_cond_prob_diff_update(w, &probs[i], branch_ct[i], probwt);
 }
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 static int prob_diff_update_savings(const aom_tree_index *tree,
                                     aom_prob probs[/*n - 1*/],
                                     const unsigned int counts[/*n - 1*/], int n,
@@ -346,6 +347,7 @@
   }
   return savings;
 }
+#endif
 
 #if CONFIG_VAR_TX
 static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
@@ -550,6 +552,7 @@
   }
 }
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w,
                                            FRAME_COUNTS *counts) {
   int j;
@@ -681,7 +684,7 @@
   }
 }
 #endif  // CONFIG_EXT_TX
-
+#endif
 #if CONFIG_PALETTE
 static void pack_palette_tokens(aom_writer *w, const TOKENEXTRA **tp, int n,
                                 int num) {
@@ -877,8 +880,7 @@
 #endif
 
 static void write_segment_id(aom_writer *w, const struct segmentation *seg,
-                             const struct segmentation_probs *segp,
-                             int segment_id) {
+                             struct segmentation_probs *segp, int segment_id) {
   if (seg->enabled && seg->update_map) {
 #if CONFIG_DAALA_EC
     aom_write_symbol(w, segment_id, segp->tree_cdf, MAX_SEGMENTS);
@@ -1139,7 +1141,7 @@
                                 aom_writer *w) {
   AV1_COMMON *const cm = &cpi->common;
 #if !CONFIG_REF_MV
-  const nmv_context *nmvc = &cm->fc->nmvc;
+  nmv_context *nmvc = &cm->fc->nmvc;
 #endif
 
 #if CONFIG_DELTA_Q
@@ -1150,7 +1152,7 @@
   const MACROBLOCKD *xd = &x->e_mbd;
 #endif
   const struct segmentation *const seg = &cm->seg;
-  const struct segmentation_probs *const segp = &cm->fc->seg;
+  struct segmentation_probs *const segp = &cm->fc->seg;
   const MB_MODE_INFO *const mbmi = &mi->mbmi;
   const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
   const PREDICTION_MODE mode = mbmi->mode;
@@ -1363,7 +1365,7 @@
               int nmv_ctx = av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                                         mbmi_ext->ref_mv_stack[rf_type], ref,
                                         mbmi->ref_mv_idx);
-              const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
+              nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
 #endif
               av1_encode_mv(cpi, w, &mi->bmi[j].as_mv[ref].as_mv,
 #if CONFIG_EXT_INTER
@@ -1388,7 +1390,7 @@
             int nmv_ctx = av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                                       mbmi_ext->ref_mv_stack[rf_type], 1,
                                       mbmi->ref_mv_idx);
-            const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
+            nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
 #endif
             av1_encode_mv(cpi, w, &mi->bmi[j].as_mv[1].as_mv,
                           &mi->bmi[j].ref_mv[1].as_mv,
@@ -1402,7 +1404,7 @@
             int nmv_ctx = av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                                       mbmi_ext->ref_mv_stack[rf_type], 0,
                                       mbmi->ref_mv_idx);
-            const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
+            nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
 #endif
             av1_encode_mv(cpi, w, &mi->bmi[j].as_mv[0].as_mv,
                           &mi->bmi[j].ref_mv[0].as_mv,
@@ -1427,7 +1429,7 @@
           int nmv_ctx = av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                                     mbmi_ext->ref_mv_stack[rf_type], ref,
                                     mbmi->ref_mv_idx);
-          const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
+          nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
 #endif
           ref_mv = mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0];
 #if CONFIG_EXT_INTER
@@ -1453,7 +1455,7 @@
         int nmv_ctx =
             av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                         mbmi_ext->ref_mv_stack[rf_type], 1, mbmi->ref_mv_idx);
-        const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
+        nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
 #endif
         av1_encode_mv(cpi, w, &mbmi->mv[1].as_mv,
                       &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv,
@@ -1467,7 +1469,7 @@
         int nmv_ctx =
             av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
                         mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx);
-        const nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
+        nmv_context *nmvc = &cm->fc->nmvc[nmv_ctx];
 #endif
         av1_encode_mv(cpi, w, &mbmi->mv[0].as_mv,
                       &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv,
@@ -1613,15 +1615,15 @@
 }
 
 #if CONFIG_DELTA_Q
-static void write_mb_modes_kf(const AV1_COMMON *cm, MACROBLOCKD *xd,
+static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd,
                               MODE_INFO **mi_8x8, aom_writer *w) {
   int skip;
 #else
-static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd,
+static void write_mb_modes_kf(AV1_COMMON *cm, const MACROBLOCKD *xd,
                               MODE_INFO **mi_8x8, aom_writer *w) {
 #endif
   const struct segmentation *const seg = &cm->seg;
-  const struct segmentation_probs *const segp = &cm->fc->seg;
+  struct segmentation_probs *const segp = &cm->fc->seg;
   const MODE_INFO *const mi = mi_8x8[0];
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
@@ -2203,7 +2205,11 @@
                                      av1_coeff_probs_model *new_coef_probs) {
   av1_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size];
   const aom_prob upd = DIFF_UPDATE_PROB;
+#if CONFIG_EC_ADAPT
+  const int entropy_nodes_update = ONE_TOKEN;
+#else
   const int entropy_nodes_update = UNCONSTRAINED_NODES;
+#endif
   int i, j, k, l, t;
   int stepsize = cpi->sf.coeff_prob_appx_step;
 #if CONFIG_TILE_GROUPS
@@ -2889,6 +2895,7 @@
   }
 }
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 static void update_seg_probs(AV1_COMP *cpi, aom_writer *w) {
   AV1_COMMON *cm = &cpi->common;
 #if CONFIG_TILE_GROUPS
@@ -2917,6 +2924,7 @@
                   cm->fc->seg.tree_cdf);
 #endif
 }
+#endif  // CONFIG_EC_ADAPT,CONFIG_DAALA_EC
 
 static void write_txfm_mode(TX_MODE mode, struct aom_write_bit_buffer *wb) {
   aom_wb_write_bit(wb, mode == TX_MODE_SELECT);
@@ -3691,6 +3699,7 @@
   FRAME_COUNTS *counts = cpi->td.counts;
   aom_writer *header_bc;
   int i, j;
+
 #if CONFIG_TILE_GROUPS
   const int probwt = cm->num_tg;
 #else
@@ -3713,6 +3722,7 @@
 #endif  // CONFIG_LOOP_RESTORATION
 
   update_txfm_probs(cm, header_bc, counts);
+
   update_coef_probs(cpi, header_bc);
 
 #if CONFIG_VAR_TX
@@ -3730,6 +3740,7 @@
 #if CONFIG_DELTA_Q
   update_delta_q_probs(cm, header_bc, counts);
 #endif
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
   update_seg_probs(cpi, header_bc);
 
   for (i = 0; i < INTRA_MODES; ++i) {
@@ -3764,12 +3775,14 @@
     prob_diff_update(av1_intra_filter_tree, fc->intra_filter_probs[i],
                      counts->intra_filter[i], INTRA_FILTERS, probwt, header_bc);
 #endif  // CONFIG_EXT_INTRA
-
+#endif  // CONFIG_EC_ADAPT, CONFIG_DAALA_EC
   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
+
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     for (i = 0; i < INTRA_MODES; ++i)
       for (j = 0; j < INTRA_MODES; ++j) {
         prob_diff_update(av1_intra_mode_tree, cm->kf_y_prob[i][j],
@@ -3780,7 +3793,9 @@
                         cm->kf_y_cdf[i][j]);
 #endif
       }
+#endif  // CONFIG_EC_ADAPT, CONFIG_DAALA_EC
   } else {
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 #if CONFIG_REF_MV
     update_inter_mode_probs(cm, header_bc, counts);
 #else
@@ -3793,7 +3808,7 @@
 #endif
     }
 #endif
-
+#endif  // CONFIG_EC_ADAPT, CONFIG_DAALA_EC
 #if CONFIG_EXT_INTER
     update_inter_compound_mode_probs(cm, probwt, header_bc);
 
@@ -3828,9 +3843,10 @@
       prob_diff_update(av1_motion_mode_tree, fc->motion_mode_prob[i],
                        counts->motion_mode[i], MOTION_MODES, probwt, header_bc);
 #endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
-
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     if (cm->interp_filter == SWITCHABLE)
       update_switchable_interp_probs(cm, header_bc, counts);
+#endif
 
     for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
       av1_cond_prob_diff_update(header_bc, &fc->intra_inter_prob[i],
@@ -3852,7 +3868,6 @@
         }
       }
     }
-
     if (cm->reference_mode != SINGLE_REFERENCE) {
       for (i = 0; i < REF_CONTEXTS; i++) {
 #if CONFIG_EXT_REFS
@@ -3873,6 +3888,7 @@
       }
     }
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) {
       prob_diff_update(av1_intra_mode_tree, cm->fc->y_mode_prob[i],
                        counts->y_mode[i], INTRA_MODES, probwt, header_bc);
@@ -3881,6 +3897,7 @@
                       cm->fc->y_mode_cdf[i]);
 #endif
     }
+#endif  // CONFIG_EC_ADAPT, CONFIG_DAALA_EC
 
     av1_write_nmv_probs(cm, cm->allow_high_precision_mv, header_bc,
 #if CONFIG_REF_MV
@@ -3892,7 +3909,9 @@
     av1_tree_to_cdf(av1_mv_joint_tree, cm->fc->nmvc.joints,
                     cm->fc->nmvc.joint_cdf);
 #endif
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
     update_ext_tx_probs(cm, header_bc);
+#endif
 #if CONFIG_SUPERTX
     if (!xd->lossless[0]) update_supertx_probs(cm, probwt, header_bc);
 #endif  // CONFIG_SUPERTX
diff --git a/av1/encoder/encodemv.c b/av1/encoder/encodemv.c
index 2f0daae..1f81fc0 100644
--- a/av1/encoder/encodemv.c
+++ b/av1/encoder/encodemv.c
@@ -30,8 +30,8 @@
   av1_tokens_from_tree(mv_fp_encodings, av1_mv_fp_tree);
 }
 
-static void encode_mv_component(aom_writer *w, int comp,
-                                const nmv_component *mvcomp, int usehp) {
+static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
+                                int usehp) {
   int offset;
   const int sign = comp < 0;
   const int mag = sign ? -comp : comp;
@@ -150,6 +150,7 @@
 #endif
 }
 
+#if !CONFIG_EC_ADAPT || !CONFIG_DAALA_EC
 static void write_mv_update(const aom_tree_index *tree,
                             aom_prob probs[/*n - 1*/],
                             const unsigned int counts[/*n - 1*/], int n,
@@ -164,6 +165,7 @@
   for (i = 0; i < n - 1; ++i)
     update_mv(w, branch_ct[i], &probs[i], MV_UPDATE_PROB);
 }
+#endif
 
 void av1_write_nmv_probs(AV1_COMMON *cm, int usehp, aom_writer *w,
                          nmv_context_counts *const nmv_counts) {
@@ -173,8 +175,13 @@
   for (nmv_ctx = 0; nmv_ctx < NMV_CONTEXTS; ++nmv_ctx) {
     nmv_context *const mvc = &cm->fc->nmvc[nmv_ctx];
     nmv_context_counts *const counts = &nmv_counts[nmv_ctx];
+
     write_mv_update(av1_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS,
                     w);
+#if CONFIG_DAALA_EC
+    av1_tree_to_cdf(av1_mv_joint_tree, cm->fc->nmvc.joints,
+                    cm->fc->nmvc.joint_cdf);
+#endif
 
     for (i = 0; i < 2; ++i) {
       nmv_component *comp = &mvc->comps[i];
@@ -210,7 +217,7 @@
   nmv_context *const mvc = &cm->fc->nmvc;
   nmv_context_counts *const counts = nmv_counts;
 
-#if !(CONFIG_DAALA_EC || CONFIG_RANS)
+#if !CONFIG_EC_ADAPT || !(CONFIG_DAALA_EC || CONFIG_RANS)
   write_mv_update(av1_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS, w);
 #if CONFIG_DAALA_EC || CONFIG_RANS
   av1_tree_to_cdf(av1_mv_joint_tree, cm->fc->nmvc.joints,
@@ -264,7 +271,7 @@
 #if CONFIG_REF_MV
                    int is_compound,
 #endif
-                   const nmv_context *mvctx, int usehp) {
+                   nmv_context *mvctx, int usehp) {
   const MV diff = { mv->row - ref->row, mv->col - ref->col };
   const MV_JOINT_TYPE j = av1_get_mv_joint(&diff);
 #if CONFIG_REF_MV
diff --git a/av1/encoder/encodemv.h b/av1/encoder/encodemv.h
index 543064e..17baa2d 100644
--- a/av1/encoder/encodemv.h
+++ b/av1/encoder/encodemv.h
@@ -27,7 +27,7 @@
 #if CONFIG_REF_MV
                    int is_compound,
 #endif
-                   const nmv_context *mvctx, int usehp);
+                   nmv_context *mvctx, int usehp);
 
 void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
                               const nmv_context *mvctx, int usehp);
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index 47cc02a..36e21b4 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -358,7 +358,7 @@
 
 static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
 #if CONFIG_RANS || CONFIG_DAALA_EC
-                             const aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS],
+                             aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS],
 #endif  // CONFIG_RANS
                              int32_t extra, uint8_t token,
                              uint8_t skip_eob_node, unsigned int *counts) {
@@ -484,7 +484,7 @@
 
     add_token(&t, coef_probs[band[c]][pt],
 #if CONFIG_RANS || CONFIG_DAALA_EC
-              (const aom_cdf_prob(*)[ENTROPY_TOKENS]) & coef_cdfs[band[c]][pt],
+              &coef_cdfs[band[c]][pt],
 #endif
               extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
 
diff --git a/av1/encoder/tokenize.h b/av1/encoder/tokenize.h
index b9487da..9fcb3f8 100644
--- a/av1/encoder/tokenize.h
+++ b/av1/encoder/tokenize.h
@@ -37,7 +37,7 @@
 typedef struct {
   const aom_prob *context_tree;
 #if CONFIG_RANS || CONFIG_DAALA_EC
-  const aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS];
+  aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS];
 #endif
   EXTRABIT extra;
   uint8_t token;
diff --git a/configure b/configure
index fcef855..7176df1 100755
--- a/configure
+++ b/configure
@@ -291,6 +291,7 @@
     filter_7bit
     parallel_deblocking
     tile_groups
+    ec_adapt
 "
 CONFIG_LIST="
     dependency_tracking