Allow to disable the probability update

Added the function of allowing to disable the probability update while
needed. This would be needed while encoding in multiple tiles, and
enabling/disabling probability update can be set separately for every
individual tile.

Change-Id: Ic3c64e6cebac89c483d48b874761bd2e902d81e6
diff --git a/aom_dsp/ansreader.h b/aom_dsp/ansreader.h
index e50c63b..4971ff1 100644
--- a/aom_dsp/ansreader.h
+++ b/aom_dsp/ansreader.h
@@ -42,6 +42,7 @@
 #if CONFIG_ACCOUNTING
   Accounting *accounting;
 #endif
+  uint8_t allow_update_cdf;
 };
 
 static INLINE int ans_read_reinit(struct AnsDecoder *const ans);
diff --git a/aom_dsp/bitreader.h b/aom_dsp/bitreader.h
index 297395d..7f8d2ca 100644
--- a/aom_dsp/bitreader.h
+++ b/aom_dsp/bitreader.h
@@ -199,7 +199,7 @@
                                    int nsymbs ACCT_STR_PARAM) {
   int ret;
   ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
-  update_cdf(cdf, ret, nsymbs);
+  if (r->allow_update_cdf) update_cdf(cdf, ret, nsymbs);
   return ret;
 }
 
@@ -210,7 +210,7 @@
   aom_cdf_prob this_cdf[3] = { (aom_cdf_prob)((cdf[0] >> 8) << 8), 0, 0 };
   this_cdf[0] = clamp(this_cdf[0], (1 << 8), (127 << 8));
   ret = aom_read_cdf(r, this_cdf, nsymbs, ACCT_STR_NAME);
-  update_bin(cdf, ret, nsymbs);
+  if (r->allow_update_cdf) update_bin(cdf, ret, nsymbs);
   return ret;
 }
 #endif
diff --git a/aom_dsp/bitwriter.h b/aom_dsp/bitwriter.h
index 1ad7538..8677663 100644
--- a/aom_dsp/bitwriter.h
+++ b/aom_dsp/bitwriter.h
@@ -135,7 +135,7 @@
 static INLINE void aom_write_symbol(aom_writer *w, int symb, aom_cdf_prob *cdf,
                                     int nsymbs) {
   aom_write_cdf(w, symb, cdf, nsymbs);
-  update_cdf(cdf, symb, nsymbs);
+  if (w->allow_update_cdf) update_cdf(cdf, symb, nsymbs);
 }
 
 #if CONFIG_LV_MAP
@@ -144,7 +144,7 @@
   aom_cdf_prob this_cdf[3] = { (aom_cdf_prob)((cdf[0] >> 8) << 8), 0, 0 };
   this_cdf[0] = clamp(this_cdf[0], (1 << 8), (127 << 8));
   aom_write_cdf(w, symb, this_cdf, nsymbs);
-  update_bin(cdf, symb, nsymbs);
+  if (w->allow_update_cdf) update_bin(cdf, symb, nsymbs);
 }
 #endif
 
diff --git a/aom_dsp/buf_ans.h b/aom_dsp/buf_ans.h
index f84ff3a..ae3286c 100644
--- a/aom_dsp/buf_ans.h
+++ b/aom_dsp/buf_ans.h
@@ -47,6 +47,7 @@
   int window_size;
 #endif
   int pos;  // Dummy variable to store the output buffer after closing
+  uint8_t allow_update_cdf;
 };
 
 // Allocate a buffered ANS coder to store size symbols.
diff --git a/aom_dsp/daalaboolreader.h b/aom_dsp/daalaboolreader.h
index 55ff8d3..3ce3047 100644
--- a/aom_dsp/daalaboolreader.h
+++ b/aom_dsp/daalaboolreader.h
@@ -34,6 +34,7 @@
 #if CONFIG_ACCOUNTING
   Accounting *accounting;
 #endif
+  uint8_t allow_update_cdf;
 };
 
 typedef struct daala_reader daala_reader;
diff --git a/aom_dsp/daalaboolwriter.h b/aom_dsp/daalaboolwriter.h
index 6ec0f0b..fb38dd3 100644
--- a/aom_dsp/daalaboolwriter.h
+++ b/aom_dsp/daalaboolwriter.h
@@ -28,6 +28,7 @@
   unsigned int pos;
   uint8_t *buffer;
   od_ec_enc ec;
+  uint8_t allow_update_cdf;
 };
 
 typedef struct daala_writer daala_writer;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 44ab9a3..4c4254b 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1137,7 +1137,7 @@
 static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end,
                                const size_t read_size,
                                struct aom_internal_error_info *error_info,
-                               aom_reader *r,
+                               aom_reader *r, uint8_t allow_update_cdf,
 #if CONFIG_ANS && ANS_MAX_SYMBOLS
                                int window_size,
 #endif  // CONFIG_ANS && ANS_MAX_SYMBOLS
@@ -1155,6 +1155,8 @@
   if (aom_reader_init(r, data, read_size, decrypt_cb, decrypt_state))
     aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder %d", 1);
+
+  r->allow_update_cdf = allow_update_cdf;
 }
 
 static void setup_segmentation(AV1_COMMON *const cm,
@@ -2251,6 +2253,7 @@
   int inv_col_order;
   int inv_row_order;
   int tile_row, tile_col;
+  uint8_t allow_update_cdf;
 
 #if CONFIG_EXT_TILE
   if (cm->large_scale_tile) {
@@ -2260,6 +2263,7 @@
     tile_cols_end = single_col ? tile_cols_start + 1 : tile_cols;
     inv_col_order = pbi->inv_tile_order && !single_col;
     inv_row_order = pbi->inv_tile_order && !single_row;
+    allow_update_cdf = 0;
   } else {
 #endif  // CONFIG_EXT_TILE
     tile_rows_start = 0;
@@ -2268,6 +2272,7 @@
     tile_cols_end = tile_cols;
     inv_col_order = pbi->inv_tile_order;
     inv_row_order = pbi->inv_tile_order;
+    allow_update_cdf = 1;
 #if CONFIG_EXT_TILE
   }
 #endif  // CONFIG_EXT_TILE
@@ -2334,7 +2339,7 @@
       av1_zero(td->dqcoeff);
       av1_tile_init(&td->xd.tile, td->cm, tile_row, tile_col);
       setup_bool_decoder(buf->data, data_end, buf->size, &cm->error,
-                         &td->bit_reader,
+                         &td->bit_reader, allow_update_cdf,
 #if CONFIG_ANS && ANS_MAX_SYMBOLS
                          1 << cm->ans_window_size_log2,
 #endif  // CONFIG_ANS && ANS_MAX_SYMBOLS
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index eeaab90..5dff0dc 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -350,7 +350,7 @@
           ? (NEAREST_NEARESTMV - NEAREST_NEARESTMV)
           : aom_read_symbol(r, ec_ctx->inter_compound_mode_cdf[ctx],
                             INTER_COMPOUND_MODES, ACCT_STR);
-  if (xd->mi[0]->mbmi.skip_mode)
+  if (xd->mi[0]->mbmi.skip_mode && r->allow_update_cdf)
     update_cdf(ec_ctx->inter_compound_mode_cdf[ctx], mode,
                INTER_COMPOUND_MODES);
 #else
@@ -1407,12 +1407,14 @@
 
 #if CONFIG_EXT_SKIP
 static void update_block_reference_mode(AV1_COMMON *cm, const MACROBLOCKD *xd,
-                                        REFERENCE_MODE mode) {
+                                        REFERENCE_MODE mode,
+                                        uint8_t allow_update_cdf) {
   if (cm->reference_mode == REFERENCE_MODE_SELECT) {
     assert(mode == SINGLE_REFERENCE || mode == COMPOUND_REFERENCE);
     const int ctx = av1_get_reference_mode_context(cm, xd);
 #if CONFIG_NEW_MULTISYMBOL
-    update_cdf(xd->tile_ctx->comp_inter_cdf[ctx], mode, 2);
+    if (allow_update_cdf)
+      update_cdf(xd->tile_ctx->comp_inter_cdf[ctx], mode, 2);
 #endif  // CONFIG_NEW_MULTISYMBOL
     FRAME_COUNTS *counts = xd->counts;
     if (counts) ++counts->comp_inter[ctx][mode];
@@ -1455,13 +1457,15 @@
 #if CONFIG_EXT_SKIP
 #if CONFIG_EXT_COMP_REFS
 static void update_comp_reference_type(AV1_COMMON *cm, const MACROBLOCKD *xd,
-                                       COMP_REFERENCE_TYPE comp_ref_type) {
+                                       COMP_REFERENCE_TYPE comp_ref_type,
+                                       uint8_t allow_update_cdf) {
   assert(comp_ref_type == UNIDIR_COMP_REFERENCE ||
          comp_ref_type == BIDIR_COMP_REFERENCE);
   (void)cm;
   const int ctx = av1_get_comp_reference_type_context(xd);
 #if CONFIG_NEW_MULTISYMBOL
-  update_cdf(xd->tile_ctx->comp_ref_type_cdf[ctx], comp_ref_type, 2);
+  if (allow_update_cdf)
+    update_cdf(xd->tile_ctx->comp_ref_type_cdf[ctx], comp_ref_type, 2);
 #endif  // CONFIG_NEW_MULTISYMBOL
   FRAME_COUNTS *counts = xd->counts;
   if (counts) ++counts->comp_ref_type[ctx][comp_ref_type];
@@ -1470,25 +1474,27 @@
 
 static void set_ref_frames_for_skip_mode(AV1_COMMON *const cm,
                                          MACROBLOCKD *const xd,
-                                         MV_REFERENCE_FRAME ref_frame[2]) {
+                                         MV_REFERENCE_FRAME ref_frame[2],
+                                         uint8_t allow_update_cdf) {
   assert(xd->mi[0]->mbmi.skip_mode);
 
   ref_frame[0] = LAST_FRAME + cm->ref_frame_idx_0;
   ref_frame[1] = LAST_FRAME + cm->ref_frame_idx_1;
 
   const REFERENCE_MODE mode = COMPOUND_REFERENCE;
-  update_block_reference_mode(cm, xd, mode);
+  update_block_reference_mode(cm, xd, mode, allow_update_cdf);
 
 #if CONFIG_EXT_COMP_REFS
   const COMP_REFERENCE_TYPE comp_ref_type = BIDIR_COMP_REFERENCE;
-  update_comp_reference_type(cm, xd, comp_ref_type);
+  update_comp_reference_type(cm, xd, comp_ref_type, allow_update_cdf);
 #endif  // CONFIG_EXT_COMP_REFS
 
 // Update stats for both forward and backward references
 #if CONFIG_NEW_MULTISYMBOL
-#define UPDATE_REF_BIT(bname, pname, cname, iname)        \
-  update_cdf(av1_get_pred_cdf_##pname(cm, xd), bname, 2); \
-  if (counts)                                             \
+#define UPDATE_REF_BIT(bname, pname, cname, iname)          \
+  if (allow_update_cdf)                                     \
+    update_cdf(av1_get_pred_cdf_##pname(cm, xd), bname, 2); \
+  if (counts)                                               \
     ++counts->comp_##cname[av1_get_pred_context_##pname(cm, xd)][iname][bname];
 #else
 #define UPDATE_REF_BIT(bname, pname, cname, iname) \
@@ -1537,7 +1543,7 @@
   } else {
 #if CONFIG_EXT_SKIP
     if (xd->mi[0]->mbmi.skip_mode) {
-      set_ref_frames_for_skip_mode(cm, xd, ref_frame);
+      set_ref_frames_for_skip_mode(cm, xd, ref_frame, r->allow_update_cdf);
       return;
     }
 #endif  // CONFIG_EXT_SKIP
@@ -2060,12 +2066,13 @@
 #if CONFIG_EXT_SKIP
 static void update_block_intra_inter(AV1_COMMON *const cm,
                                      MACROBLOCKD *const xd, int segment_id,
-                                     const int is_inter) {
+                                     const int is_inter,
+                                     uint8_t allow_update_cdf) {
   if (!segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
     const int ctx = av1_get_intra_inter_context(xd);
 #if CONFIG_NEW_MULTISYMBOL
     FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
-    update_cdf(ec_ctx->intra_inter_cdf[ctx], is_inter, 2);
+    if (allow_update_cdf) update_cdf(ec_ctx->intra_inter_cdf[ctx], is_inter, 2);
 #endif  // CONFIG_NEW_MULTISYMBOL
     FRAME_COUNTS *counts = xd->counts;
     if (counts) ++counts->intra_inter[ctx][is_inter];
@@ -2635,7 +2642,8 @@
 #endif  // CONFIG_EXT_DELTA_Q
     }
 
-    update_block_intra_inter(cm, xd, mbmi->segment_id, inter_block);
+    update_block_intra_inter(cm, xd, mbmi->segment_id, inter_block,
+                             r->allow_update_cdf);
   } else {
 #endif  // CONFIG_EXT_SKIP
     mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index ea038c5..c227960 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3181,6 +3181,7 @@
 #if CONFIG_ANS
         mode_bc.size = 1 << cpi->common.ans_window_size_log2;
 #endif
+        mode_bc.allow_update_cdf = !cm->large_scale_tile;
 #if CONFIG_LOOP_RESTORATION
         for (int p = 0; p < MAX_MB_PLANE; ++p) {
           set_default_wiener(cpi->td.mb.e_mbd.wiener_info + p);
@@ -3367,6 +3368,7 @@
 #if CONFIG_ANS
         mode_bc.size = 1 << cpi->common.ans_window_size_log2;
 #endif  // CONFIG_ANS
+        mode_bc.allow_update_cdf = 1;
 #if CONFIG_LOOP_RESTORATION
         for (int p = 0; p < MAX_MB_PLANE; ++p) {
           set_default_wiener(cpi->td.mb.e_mbd.wiener_info + p);
@@ -4851,6 +4853,7 @@
 #if CONFIG_ANS
         mode_bc.size = 1 << cpi->common.ans_window_size_log2;
 #endif
+        mode_bc.allow_update_cdf = !cm->large_scale_tile;
         aom_start_encode(&mode_bc, buf->data + data_offset);
         write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end);
         assert(tok == tok_end);
@@ -4972,6 +4975,7 @@
 #if CONFIG_ANS
         mode_bc.size = 1 << cpi->common.ans_window_size_log2;
 #endif  // CONFIG_ANS
+        mode_bc.allow_update_cdf = 1;
 #if CONFIG_LOOP_RESTORATION
         for (int p = 0; p < MAX_MB_PLANE; ++p) {
           set_default_wiener(cpi->td.mb.e_mbd.wiener_info + p);
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index cb9a0f6..2b0ab77 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -59,9 +59,10 @@
 #define IF_HBD(...)
 #endif  // CONFIG_HIGHBITDEPTH
 
-static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
-                              TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
-                              int mi_col, BLOCK_SIZE bsize, int *rate);
+static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data,
+                              ThreadData *td, TOKENEXTRA **t, RUN_TYPE dry_run,
+                              int mi_row, int mi_col, BLOCK_SIZE bsize,
+                              int *rate);
 
 // This is used as a reference when computing the source variance for the
 //  purposes of activity masking.
@@ -316,7 +317,8 @@
   mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
 }
 
-static void update_filter_type_count(FRAME_COUNTS *counts,
+static void update_filter_type_count(uint8_t allow_update_cdf,
+                                     FRAME_COUNTS *counts,
                                      const MACROBLOCKD *xd,
                                      const MB_MODE_INFO *mbmi) {
   int dir;
@@ -328,8 +330,9 @@
       InterpFilter filter =
           av1_extract_interp_filter(mbmi->interp_filters, dir);
       ++counts->switchable_interp[ctx][filter];
-      update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
-                 SWITCHABLE_FILTERS);
+      if (allow_update_cdf)
+        update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
+                   SWITCHABLE_FILTERS);
     }
   }
 }
@@ -417,9 +420,9 @@
   }
 }
 
-static void update_state(const AV1_COMP *const cpi, ThreadData *td,
-                         PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
-                         BLOCK_SIZE bsize, RUN_TYPE dry_run) {
+static void update_state(const AV1_COMP *const cpi, TileDataEnc *tile_data,
+                         ThreadData *td, PICK_MODE_CONTEXT *ctx, int mi_row,
+                         int mi_col, BLOCK_SIZE bsize, RUN_TYPE dry_run) {
   int i, x_idx, y;
   const AV1_COMMON *const cm = &cpi->common;
   RD_COUNTS *const rdc = &td->rd_counts;
@@ -559,8 +562,10 @@
           mbmi->motion_mode != WARPED_CAUSAL &&
           !is_nontrans_global_motion(xd)) {
 #if CONFIG_DUAL_FILTER
-        update_filter_type_count(td->counts, xd, mbmi);
+        update_filter_type_count(tile_data->allow_update_cdf, td->counts, xd,
+                                 mbmi);
 #else
+        (void)tile_data;
         const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
         const InterpFilter filter =
             av1_extract_interp_filter(mbmi->interp_filters, 0);
@@ -587,17 +592,17 @@
 }
 
 #if NC_MODE_INFO
-static void set_mode_info_b(const AV1_COMP *const cpi,
-                            const TileInfo *const tile, ThreadData *td,
-                            int mi_row, int mi_col, BLOCK_SIZE bsize,
-                            PICK_MODE_CONTEXT *ctx) {
+static void set_mode_info_b(const AV1_COMP *const cpi, TileDataEnc *tile_data,
+                            ThreadData *td, int mi_row, int mi_col,
+                            BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
+  const TileInfo *const tile = &tile_data->tile_info;
   MACROBLOCK *const x = &td->mb;
   set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
-  update_state(cpi, td, ctx, mi_row, mi_col, bsize, 1);
+  update_state(cpi, tile_data, td, ctx, mi_row, mi_col, bsize, 1);
 }
 
 static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
-                             const TileInfo *const tile, TOKENEXTRA **tp,
+                             TileDataEnc *tile_data, TOKENEXTRA **tp,
                              int mi_row, int mi_col, BLOCK_SIZE bsize,
                              PC_TREE *pc_tree) {
   const AV1_COMMON *const cm = &cpi->common;
@@ -613,68 +618,69 @@
 
   switch (partition) {
     case PARTITION_NONE:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize, &pc_tree->none);
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
+                      &pc_tree->none);
       break;
     case PARTITION_VERT:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
                       &pc_tree->vertical[0]);
       if (mi_col + hbs < cm->mi_cols) {
-        set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
+        set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, subsize,
                         &pc_tree->vertical[1]);
       }
       break;
     case PARTITION_HORZ:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
                       &pc_tree->horizontal[0]);
       if (mi_row + hbs < cm->mi_rows) {
-        set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
+        set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, subsize,
                         &pc_tree->horizontal[1]);
       }
       break;
     case PARTITION_SPLIT:
-      set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col, subsize,
+      set_mode_info_sb(cpi, td, tile_data, tp, mi_row, mi_col, subsize,
                        pc_tree->split[0]);
-      set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, subsize,
+      set_mode_info_sb(cpi, td, tile_data, tp, mi_row, mi_col + hbs, subsize,
                        pc_tree->split[1]);
-      set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, subsize,
+      set_mode_info_sb(cpi, td, tile_data, tp, mi_row + hbs, mi_col, subsize,
                        pc_tree->split[2]);
-      set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, subsize,
-                       pc_tree->split[3]);
+      set_mode_info_sb(cpi, td, tile_data, tp, mi_row + hbs, mi_col + hbs,
+                       subsize, pc_tree->split[3]);
       break;
 #if CONFIG_EXT_PARTITION_TYPES
 #if CONFIG_EXT_PARTITION_TYPES_AB
 #error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
 #endif
     case PARTITION_HORZ_A:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, bsize2,
                       &pc_tree->horizontala[0]);
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, bsize2,
                       &pc_tree->horizontala[1]);
-      set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
+      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, subsize,
                       &pc_tree->horizontala[2]);
       break;
     case PARTITION_HORZ_B:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
                       &pc_tree->horizontalb[0]);
-      set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, bsize2,
                       &pc_tree->horizontalb[1]);
-      set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col + hbs, bsize2,
                       &pc_tree->horizontalb[2]);
       break;
     case PARTITION_VERT_A:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, bsize2,
                       &pc_tree->verticala[0]);
-      set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, bsize2,
                       &pc_tree->verticala[1]);
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, subsize,
                       &pc_tree->verticala[2]);
       break;
     case PARTITION_VERT_B:
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
                       &pc_tree->verticalb[0]);
-      set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, bsize2,
                       &pc_tree->verticalb[1]);
-      set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
+      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col + hbs, bsize2,
                       &pc_tree->verticalb[2]);
       break;
     case PARTITION_HORZ_4:
@@ -682,7 +688,7 @@
         int this_mi_row = mi_row + i * quarter_step;
         if (i > 0 && this_mi_row >= cm->mi_rows) break;
 
-        set_mode_info_b(cpi, tile, td, this_mi_row, mi_col, subsize,
+        set_mode_info_b(cpi, tile_data, td, this_mi_row, mi_col, subsize,
                         &pc_tree->horizontal4[i]);
       }
       break;
@@ -691,7 +697,7 @@
         int this_mi_col = mi_col + i * quarter_step;
         if (i > 0 && this_mi_col >= cm->mi_cols) break;
 
-        set_mode_info_b(cpi, tile, td, mi_row, this_mi_col, subsize,
+        set_mode_info_b(cpi, tile_data, td, mi_row, this_mi_col, subsize,
                         &pc_tree->vertical4[i]);
       }
       break;
@@ -969,8 +975,8 @@
   }
 }
 
-static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
-                         int mi_col) {
+static void update_stats(const AV1_COMMON *const cm, TileDataEnc *tile_data,
+                         ThreadData *td, int mi_row, int mi_col) {
   MACROBLOCK *x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   const MODE_INFO *const mi = xd->mi[0];
@@ -978,6 +984,7 @@
   const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
   const BLOCK_SIZE bsize = mbmi->sb_type;
   FRAME_CONTEXT *fc = xd->tile_ctx;
+  const uint8_t allow_update_cdf = tile_data->allow_update_cdf;
 
   // delta quant applies to both intra and inter
   int super_block_upper_left =
@@ -990,7 +997,7 @@
     const int skip_ctx = av1_get_skip_context(xd);
     td->counts->skip[skip_ctx][mbmi->skip]++;
 #if CONFIG_NEW_MULTISYMBOL
-    update_cdf(fc->skip_cdfs[skip_ctx], mbmi->skip, 2);
+    if (allow_update_cdf) update_cdf(fc->skip_cdfs[skip_ctx], mbmi->skip, 2);
 #endif  // CONFIG_NEW_MULTISYMBOL
   }
 
@@ -1055,8 +1062,9 @@
     if (!seg_ref_active) {
       counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
 #if CONFIG_NEW_MULTISYMBOL
-      update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
-                 inter_block, 2);
+      if (allow_update_cdf)
+        update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
+                   inter_block, 2);
 #endif
       // If the segment reference feature is enabled we have only a single
       // reference frame allowed for the segment so exclude it from
@@ -1076,8 +1084,9 @@
             counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
                               [has_second_ref(mbmi)]++;
 #if CONFIG_NEW_MULTISYMBOL
-            update_cdf(av1_get_reference_mode_cdf(cm, xd), has_second_ref(mbmi),
-                       2);
+            if (allow_update_cdf)
+              update_cdf(av1_get_reference_mode_cdf(cm, xd),
+                         has_second_ref(mbmi), 2);
 #endif  // CONFIG_NEW_MULTISYMBOL
           }
         }
@@ -1161,22 +1170,26 @@
           if (mbmi->ref_frame[1] == INTRA_FRAME) {
             counts->interintra[bsize_group][1]++;
 #if CONFIG_NEW_MULTISYMBOL
-            update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
+            if (allow_update_cdf)
+              update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
 #endif
             counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
-            update_cdf(fc->interintra_mode_cdf[bsize_group],
-                       mbmi->interintra_mode, INTERINTRA_MODES);
+            if (allow_update_cdf)
+              update_cdf(fc->interintra_mode_cdf[bsize_group],
+                         mbmi->interintra_mode, INTERINTRA_MODES);
             if (is_interintra_wedge_used(bsize)) {
               counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
 #if CONFIG_NEW_MULTISYMBOL
-              update_cdf(fc->wedge_interintra_cdf[bsize],
-                         mbmi->use_wedge_interintra, 2);
+              if (allow_update_cdf)
+                update_cdf(fc->wedge_interintra_cdf[bsize],
+                           mbmi->use_wedge_interintra, 2);
 #endif
             }
           } else {
             counts->interintra[bsize_group][0]++;
 #if CONFIG_NEW_MULTISYMBOL
-            update_cdf(fc->interintra_cdf[bsize_group], 0, 2);
+            if (allow_update_cdf)
+              update_cdf(fc->interintra_cdf[bsize_group], 0, 2);
 #endif
           }
         }
@@ -1187,23 +1200,27 @@
         if (mbmi->ref_frame[1] != INTRA_FRAME) {
           if (motion_allowed == WARPED_CAUSAL) {
             counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
-            update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
-                       MOTION_MODES);
+            if (allow_update_cdf)
+              update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
+                         MOTION_MODES);
 #if CONFIG_NCOBMC_ADAPT_WEIGHT
           } else if (motion_allowed == NCOBMC_ADAPT_WEIGHT) {
             counts->ncobmc[mbmi->sb_type][mbmi->motion_mode]++;
-            update_cdf(fc->ncobmc_cdf[mbmi->sb_type], mbmi->motion_mode,
-                       OBMC_FAMILY_MODES);
+            if (allow_update_cdf)
+              update_cdf(fc->ncobmc_cdf[mbmi->sb_type], mbmi->motion_mode,
+                         OBMC_FAMILY_MODES);
           } else if (motion_allowed == OBMC_CAUSAL) {
             counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
-            update_cdf(fc->obmc_cdf[mbmi->sb_type], mbmi->motion_mode, 2);
+            if (allow_update_cdf)
+              update_cdf(fc->obmc_cdf[mbmi->sb_type], mbmi->motion_mode, 2);
           }
 #else
           } else if (motion_allowed == OBMC_CAUSAL) {
             counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
 #if CONFIG_NEW_MULTISYMBOL
-            update_cdf(fc->obmc_cdf[mbmi->sb_type],
-                       mbmi->motion_mode == OBMC_CAUSAL, 2);
+            if (allow_update_cdf)
+              update_cdf(fc->obmc_cdf[mbmi->sb_type],
+                         mbmi->motion_mode == OBMC_CAUSAL, 2);
 #endif
           }
 #endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
@@ -1214,12 +1231,14 @@
           ADAPT_OVERLAP_BLOCK ao_block =
               adapt_overlap_block_lookup[mbmi->sb_type];
           ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[0]];
-          update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[0],
-                     MAX_NCOBMC_MODES);
+          if (allow_update_cdf)
+            update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[0],
+                       MAX_NCOBMC_MODES);
           if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
             ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[1]];
-            update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[1],
-                       MAX_NCOBMC_MODES);
+            if (allow_update_cdf)
+              update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[1],
+                         MAX_NCOBMC_MODES);
           }
         }
 #endif
@@ -1235,8 +1254,9 @@
           if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
             counts
                 ->compound_interinter[bsize][mbmi->interinter_compound_type]++;
-            update_cdf(fc->compound_type_cdf[bsize],
-                       mbmi->interinter_compound_type, COMPOUND_TYPES);
+            if (allow_update_cdf)
+              update_cdf(fc->compound_type_cdf[bsize],
+                         mbmi->interinter_compound_type, COMPOUND_TYPES);
           }
         }
       }
@@ -1249,8 +1269,9 @@
       if (has_second_ref(mbmi)) {
         mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
         ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
-        update_cdf(fc->inter_compound_mode_cdf[mode_ctx],
-                   INTER_COMPOUND_OFFSET(mode), INTER_COMPOUND_MODES);
+        if (allow_update_cdf)
+          update_cdf(fc->inter_compound_mode_cdf[mode_ctx],
+                     INTER_COMPOUND_OFFSET(mode), INTER_COMPOUND_MODES);
 #if CONFIG_COMPOUND_SINGLEREF
       } else if (is_inter_singleref_comp_mode(mode)) {
         mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
@@ -1387,13 +1408,14 @@
   ctx->p_tl = xd->left_txfm_context;
 }
 
-static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
+static void encode_b(const AV1_COMP *const cpi, TileDataEnc *tile_data,
                      ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
                      RUN_TYPE dry_run, BLOCK_SIZE bsize,
 #if CONFIG_EXT_PARTITION_TYPES
                      PARTITION_TYPE partition,
 #endif
                      PICK_MODE_CONTEXT *ctx, int *rate) {
+  TileInfo *const tile = &tile_data->tile_info;
   MACROBLOCK *const x = &td->mb;
 #if (CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q | CONFIG_NCOBMC_ADAPT_WEIGHT
   MACROBLOCKD *xd = &x->e_mbd;
@@ -1407,7 +1429,7 @@
 #if CONFIG_EXT_PARTITION_TYPES
   x->e_mbd.mi[0]->mbmi.partition = partition;
 #endif
-  update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
+  update_state(cpi, tile_data, td, ctx, mi_row, mi_col, bsize, dry_run);
 #if (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
   mbmi = &xd->mi[0]->mbmi;
   set_ref_ptrs(&cpi->common, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
@@ -1442,7 +1464,8 @@
   }
 #endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
 
-  encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, rate);
+  encode_superblock(cpi, tile_data, td, tp, dry_run, mi_row, mi_col, bsize,
+                    rate);
 
 #if CONFIG_LV_MAP
   if (dry_run == 0)
@@ -1461,12 +1484,12 @@
       mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base;
     }
 #endif
-    update_stats(&cpi->common, td, mi_row, mi_col);
+    update_stats(&cpi->common, tile_data, td, mi_row, mi_col);
   }
 }
 
 static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
-                      const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
+                      TileDataEnc *tile_data, TOKENEXTRA **tp, int mi_row,
                       int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
                       PC_TREE *pc_tree, int *rate) {
   const AV1_COMMON *const cm = &cpi->common;
@@ -1501,20 +1524,20 @@
 
   switch (partition) {
     case PARTITION_NONE:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
 #if CONFIG_EXT_PARTITION_TYPES
                partition,
 #endif
                &pc_tree->none, rate);
       break;
     case PARTITION_VERT:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
 #if CONFIG_EXT_PARTITION_TYPES
                partition,
 #endif
                &pc_tree->vertical[0], rate);
       if (mi_col + hbs < cm->mi_cols) {
-        encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
+        encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
 #if CONFIG_EXT_PARTITION_TYPES
                  partition,
 #endif
@@ -1522,13 +1545,13 @@
       }
       break;
     case PARTITION_HORZ:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
 #if CONFIG_EXT_PARTITION_TYPES
                partition,
 #endif
                &pc_tree->horizontal[0], rate);
       if (mi_row + hbs < cm->mi_rows) {
-        encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
+        encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
 #if CONFIG_EXT_PARTITION_TYPES
                  partition,
 #endif
@@ -1536,94 +1559,94 @@
       }
       break;
     case PARTITION_SPLIT:
-      encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize,
                 pc_tree->split[0], rate);
-      encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + hbs, dry_run, subsize,
                 pc_tree->split[1], rate);
-      encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row + hbs, mi_col, dry_run, subsize,
                 pc_tree->split[2], rate);
-      encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run, subsize,
-                pc_tree->split[3], rate);
+      encode_sb(cpi, td, tile_data, tp, mi_row + hbs, mi_col + hbs, dry_run,
+                subsize, pc_tree->split[3], rate);
       break;
 
 #if CONFIG_EXT_PARTITION_TYPES
 #if CONFIG_EXT_PARTITION_TYPES_AB
     case PARTITION_HORZ_A:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run,
                get_subsize(bsize, PARTITION_HORZ_4), partition,
                &pc_tree->horizontala[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row + qbs, mi_col, dry_run,
+      encode_b(cpi, tile_data, td, tp, mi_row + qbs, mi_col, dry_run,
                get_subsize(bsize, PARTITION_HORZ_4), partition,
                &pc_tree->horizontala[1], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
                partition, &pc_tree->horizontala[2], rate);
       break;
     case PARTITION_HORZ_B:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
-               &pc_tree->horizontalb[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
+               partition, &pc_tree->horizontalb[0], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run,
                get_subsize(bsize, PARTITION_HORZ_4), partition,
                &pc_tree->horizontalb[1], rate);
       if (mi_row + 3 * qbs < cm->mi_rows)
-        encode_b(cpi, tile, td, tp, mi_row + 3 * qbs, mi_col, dry_run,
+        encode_b(cpi, tile_data, td, tp, mi_row + 3 * qbs, mi_col, dry_run,
                  get_subsize(bsize, PARTITION_HORZ_4), partition,
                  &pc_tree->horizontalb[2], rate);
       break;
     case PARTITION_VERT_A:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run,
                get_subsize(bsize, PARTITION_VERT_4), partition,
                &pc_tree->verticala[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row, mi_col + qbs, dry_run,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col + qbs, dry_run,
                get_subsize(bsize, PARTITION_VERT_4), partition,
                &pc_tree->verticala[1], rate);
-      encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
                partition, &pc_tree->verticala[2], rate);
 
       break;
     case PARTITION_VERT_B:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
-               &pc_tree->verticalb[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
+               partition, &pc_tree->verticalb[0], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run,
                get_subsize(bsize, PARTITION_VERT_4), partition,
                &pc_tree->verticalb[1], rate);
       if (mi_col + 3 * qbs < cm->mi_cols)
-        encode_b(cpi, tile, td, tp, mi_row, mi_col + 3 * qbs, dry_run,
+        encode_b(cpi, tile_data, td, tp, mi_row, mi_col + 3 * qbs, dry_run,
                  get_subsize(bsize, PARTITION_VERT_4), partition,
                  &pc_tree->verticalb[2], rate);
       break;
 #else
     case PARTITION_HORZ_A:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
-               &pc_tree->horizontala[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, bsize2,
+               partition, &pc_tree->horizontala[0], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
                partition, &pc_tree->horizontala[1], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
                partition, &pc_tree->horizontala[2], rate);
       break;
     case PARTITION_HORZ_B:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
-               &pc_tree->horizontalb[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
+               partition, &pc_tree->horizontalb[0], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
                partition, &pc_tree->horizontalb[1], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
-               partition, &pc_tree->horizontalb[2], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col + hbs, dry_run,
+               bsize2, partition, &pc_tree->horizontalb[2], rate);
       break;
     case PARTITION_VERT_A:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
-               &pc_tree->verticala[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, bsize2,
+               partition, &pc_tree->verticala[0], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
                partition, &pc_tree->verticala[1], rate);
-      encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
                partition, &pc_tree->verticala[2], rate);
 
       break;
     case PARTITION_VERT_B:
-      encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
-               &pc_tree->verticalb[0], rate);
-      encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
+               partition, &pc_tree->verticalb[0], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
                partition, &pc_tree->verticalb[1], rate);
-      encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
-               partition, &pc_tree->verticalb[2], rate);
+      encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col + hbs, dry_run,
+               bsize2, partition, &pc_tree->verticalb[2], rate);
       break;
 #endif
     case PARTITION_HORZ_4:
@@ -1631,7 +1654,7 @@
         int this_mi_row = mi_row + i * quarter_step;
         if (i > 0 && this_mi_row >= cm->mi_rows) break;
 
-        encode_b(cpi, tile, td, tp, this_mi_row, mi_col, dry_run, subsize,
+        encode_b(cpi, tile_data, td, tp, this_mi_row, mi_col, dry_run, subsize,
                  partition, &pc_tree->horizontal4[i], rate);
       }
       break;
@@ -1640,7 +1663,7 @@
         int this_mi_col = mi_col + i * quarter_step;
         if (i > 0 && this_mi_col >= cm->mi_cols) break;
 
-        encode_b(cpi, tile, td, tp, mi_row, this_mi_col, dry_run, subsize,
+        encode_b(cpi, tile_data, td, tp, mi_row, this_mi_col, dry_run, subsize,
                  partition, &pc_tree->vertical4[i], rate);
       }
       break;
@@ -1839,9 +1862,9 @@
         RD_STATS tmp_rdc;
         PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
         av1_init_rd_stats(&tmp_rdc);
-        update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
-        encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
-                          NULL);
+        update_state(cpi, tile_data, td, ctx_h, mi_row, mi_col, subsize, 1);
+        encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL, mi_row,
+                          mi_col, subsize, NULL);
         rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
 #if CONFIG_EXT_PARTITION_TYPES
                          PARTITION_HORZ,
@@ -1867,9 +1890,9 @@
         RD_STATS tmp_rdc;
         PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
         av1_init_rd_stats(&tmp_rdc);
-        update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
-        encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
-                          NULL);
+        update_state(cpi, tile_data, td, ctx_v, mi_row, mi_col, subsize, 1);
+        encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL, mi_row,
+                          mi_col, subsize, NULL);
         rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
 #if CONFIG_EXT_PARTITION_TYPES
                          PARTITION_VERT,
@@ -1967,7 +1990,7 @@
       chosen_rdc.dist += tmp_rdc.dist;
 
       if (i != 3)
-        encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
+        encode_sb(cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx,
                   OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
 
       chosen_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
@@ -2001,12 +2024,12 @@
     if (bsize == cm->sb_size) {
       // NOTE: To get estimate for rate due to the tokens, use:
       // int rate_coeffs = 0;
-      // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
+      // encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
       //           bsize, pc_tree, &rate_coeffs);
-      encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
                 pc_tree, NULL);
     } else {
-      encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
                 pc_tree, NULL);
     }
   }
@@ -2329,9 +2352,9 @@
   if (sum_rdc->rdcost >= RTS_MAX_RDCOST) return 0;
 
   if (!is_last) {
-    update_state(cpi, td, this_ctx, mi_row, mi_col, subsize, 1);
-    encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
-                      NULL);
+    update_state(cpi, tile_data, td, this_ctx, mi_row, mi_col, subsize, 1);
+    encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL, mi_row, mi_col,
+                      subsize, NULL);
   }
 
   return 1;
@@ -2826,9 +2849,9 @@
 
     if (sum_rdc.rdcost < temp_best_rdcost && !force_horz_split) {
       PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
-      update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
-      encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
-                        NULL);
+      update_state(cpi, tile_data, td, ctx_h, mi_row, mi_col, subsize, 1);
+      encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL, mi_row, mi_col,
+                        subsize, NULL);
 
       if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
 
@@ -2846,10 +2869,10 @@
 
 #if CONFIG_DIST_8X8
       if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
-        update_state(cpi, td, &pc_tree->horizontal[1], mi_row + mi_step, mi_col,
-                     subsize, DRY_RUN_NORMAL);
-        encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row + mi_step, mi_col,
-                          subsize, NULL);
+        update_state(cpi, tile_data, td, &pc_tree->horizontal[1],
+                     mi_row + mi_step, mi_col, subsize, DRY_RUN_NORMAL);
+        encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL,
+                          mi_row + mi_step, mi_col, subsize, NULL);
       }
 #endif  // CONFIG_DIST_8X8
 
@@ -2904,9 +2927,10 @@
                      subsize, &pc_tree->vertical[0], best_rdc.rdcost);
     const int64_t vert_max_rdcost = best_rdc.rdcost;
     if (sum_rdc.rdcost < vert_max_rdcost && !force_vert_split) {
-      update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
-      encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
-                        NULL);
+      update_state(cpi, tile_data, td, &pc_tree->vertical[0], mi_row, mi_col,
+                   subsize, 1);
+      encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL, mi_row, mi_col,
+                        subsize, NULL);
 
       if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
 
@@ -2924,10 +2948,10 @@
 
 #if CONFIG_DIST_8X8
       if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
-        update_state(cpi, td, &pc_tree->vertical[1], mi_row, mi_col + mi_step,
-                     subsize, DRY_RUN_NORMAL);
-        encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col + mi_step,
-                          subsize, NULL);
+        update_state(cpi, tile_data, td, &pc_tree->vertical[1], mi_row,
+                     mi_col + mi_step, subsize, DRY_RUN_NORMAL);
+        encode_superblock(cpi, tile_data, td, tp, DRY_RUN_NORMAL, mi_row,
+                          mi_col + mi_step, subsize, NULL);
       }
 #endif  // CONFIG_DIST_8X8
 
@@ -3151,7 +3175,7 @@
       pc_tree->index != 3) {
     if (bsize == cm->sb_size) {
 #if NC_MODE_INFO
-      set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
+      set_mode_info_sb(cpi, td, tile_data, tp, mi_row, mi_col, bsize, pc_tree);
 #endif
 
 #if CONFIG_LV_MAP
@@ -3161,10 +3185,10 @@
 #if CONFIG_NCOBMC_ADAPT_WEIGHT
       set_sb_mi_boundaries(cm, xd, mi_row, mi_col);
 #endif
-      encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
                 pc_tree, NULL);
     } else {
-      encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
+      encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
                 pc_tree, NULL);
     }
   }
@@ -3172,7 +3196,7 @@
 #if CONFIG_DIST_8X8
   if (x->using_dist_8x8 && best_rdc.rate < INT_MAX &&
       best_rdc.dist < INT64_MAX && bsize == BLOCK_4X4 && pc_tree->index == 3) {
-    encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
+    encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
               pc_tree, NULL);
   }
 #endif  // CONFIG_DIST_8X8
@@ -3444,13 +3468,20 @@
 
   for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
     for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
-      TileInfo *const tile_info =
-          &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
+      TileDataEnc *const tile_data =
+          &cpi->tile_data[tile_row * tile_cols + tile_col];
+      TileInfo *const tile_info = &tile_data->tile_info;
       av1_tile_init(tile_info, cm, tile_row, tile_col);
 
       cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
       pre_tok = cpi->tile_tok[tile_row][tile_col];
       tile_tok = allocated_tokens(*tile_info, cm->mib_size_log2 + MI_SIZE_LOG2);
+
+#if CONFIG_EXT_TILE
+      tile_data->allow_update_cdf = !cm->large_scale_tile;
+#else
+      tile_data->allow_update_cdf = 1;
+#endif  // CONFIG_EXT_TILE
     }
   }
 }
@@ -4135,7 +4166,8 @@
 static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
                             const MODE_INFO *mi, const MODE_INFO *above_mi,
                             const MODE_INFO *left_mi, const int intraonly,
-                            const int mi_row, const int mi_col) {
+                            const int mi_row, const int mi_col,
+                            uint8_t allow_update_cdf) {
   FRAME_CONTEXT *fc = xd->tile_ctx;
   const MB_MODE_INFO *const mbmi = &mi->mbmi;
   const PREDICTION_MODE y_mode = mbmi->mode;
@@ -4149,13 +4181,15 @@
     const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
     ++counts->kf_y_mode[above][left][y_mode];
 #endif  // CONFIG_ENTROPY_STATS
-    update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, 0), y_mode,
-               INTRA_MODES);
+    if (allow_update_cdf)
+      update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, 0), y_mode,
+                 INTRA_MODES);
   } else {
 #if CONFIG_ENTROPY_STATS
     ++counts->y_mode[size_group_lookup[bsize]][y_mode];
 #endif  // CONFIG_ENTROPY_STATS
-    update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
+    if (allow_update_cdf)
+      update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
   }
 
 #if CONFIG_FILTER_INTRA
@@ -4168,9 +4202,10 @@
     ++counts->filter_intra_mode[0][mbmi->filter_intra_mode_info
                                        .filter_intra_mode[0]];
 #endif  // CONFIG_ENTROPY_STATS
-    update_cdf(fc->filter_intra_mode_cdf[0],
-               mbmi->filter_intra_mode_info.filter_intra_mode[0],
-               FILTER_INTRA_MODES);
+    if (allow_update_cdf)
+      update_cdf(fc->filter_intra_mode_cdf[0],
+                 mbmi->filter_intra_mode_info.filter_intra_mode[0],
+                 FILTER_INTRA_MODES);
   }
 #endif  // CONFIG_FILTER_INTRA
 #if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
@@ -4180,8 +4215,10 @@
     ++counts->angle_delta[mbmi->mode - V_PRED]
                          [mbmi->angle_delta[0] + MAX_ANGLE_DELTA];
 #endif
-    update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
-               mbmi->angle_delta[0] + MAX_ANGLE_DELTA, 2 * MAX_ANGLE_DELTA + 1);
+    if (allow_update_cdf)
+      update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
+                 mbmi->angle_delta[0] + MAX_ANGLE_DELTA,
+                 2 * MAX_ANGLE_DELTA + 1);
   }
 #endif  // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
 
@@ -4195,14 +4232,17 @@
     ++counts->angle_delta[mbmi->uv_mode - V_PRED]
                          [mbmi->angle_delta[1] + MAX_ANGLE_DELTA];
 #endif
-    update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
-               mbmi->angle_delta[1] + MAX_ANGLE_DELTA, 2 * MAX_ANGLE_DELTA + 1);
+    if (allow_update_cdf)
+      update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
+                 mbmi->angle_delta[1] + MAX_ANGLE_DELTA,
+                 2 * MAX_ANGLE_DELTA + 1);
   }
 #endif  // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
 #if CONFIG_ENTROPY_STATS
   ++counts->uv_mode[y_mode][uv_mode];
 #endif  // CONFIG_ENTROPY_STATS
-  update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
+  if (allow_update_cdf)
+    update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
 }
 
 #if CONFIG_NEW_MULTISYMBOL
@@ -4244,7 +4284,8 @@
 
 static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
                               FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
-                              int blk_row, int blk_col) {
+                              int blk_row, int blk_col,
+                              uint8_t allow_update_cdf) {
   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
   const int tx_row = blk_row >> 1;
   const int tx_col = blk_col >> 1;
@@ -4278,7 +4319,8 @@
   {
     ++counts->txfm_partition[ctx][0];
 #if CONFIG_NEW_MULTISYMBOL
-    update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 0, 2);
+    if (allow_update_cdf)
+      update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 0, 2);
 #endif
 #if CONFIG_RECT_TX_EXT
     if (tx_size == plane_tx_size)
@@ -4293,7 +4335,8 @@
 
     ++counts->txfm_partition[ctx][1];
 #if CONFIG_NEW_MULTISYMBOL
-    update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 1, 2);
+    if (allow_update_cdf)
+      update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 1, 2);
 #endif
     ++x->txb_split_count;
 
@@ -4309,14 +4352,15 @@
       int offsetr = (i >> 1) * bs;
       int offsetc = (i & 0x01) * bs;
       update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
-                        blk_col + offsetc);
+                        blk_col + offsetc, allow_update_cdf);
     }
   }
 }
 
 static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
                                       BLOCK_SIZE plane_bsize, int mi_row,
-                                      int mi_col, FRAME_COUNTS *td_counts) {
+                                      int mi_col, FRAME_COUNTS *td_counts,
+                                      uint8_t allow_update_cdf) {
   MACROBLOCKD *xd = &x->e_mbd;
   const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
   const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
@@ -4332,7 +4376,8 @@
 
   for (idy = 0; idy < mi_height; idy += bh)
     for (idx = 0; idx < mi_width; idx += bw)
-      update_txfm_count(x, xd, td_counts, max_tx_size, 0, idy, idx);
+      update_txfm_count(x, xd, td_counts, max_tx_size, 0, idy, idx,
+                        allow_update_cdf);
 }
 
 static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
@@ -4398,7 +4443,7 @@
                               int blk_row, int blk_col, int block, int plane,
 #endif
                               BLOCK_SIZE bsize, TX_SIZE tx_size,
-                              FRAME_COUNTS *counts) {
+                              FRAME_COUNTS *counts, uint8_t allow_update_cdf) {
   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
   int is_inter = is_inter_block(mbmi);
   FRAME_CONTEXT *fc = xd->tile_ctx;
@@ -4426,9 +4471,10 @@
       const TxSetType tx_set_type = get_ext_tx_set_type(
           tx_size, bsize, is_inter, cm->reduced_tx_set_used);
       if (is_inter) {
-        update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
-                   av1_ext_tx_ind[tx_set_type][tx_type],
-                   av1_num_ext_tx_set[tx_set_type]);
+        if (allow_update_cdf)
+          update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
+                     av1_ext_tx_ind[tx_set_type][tx_type],
+                     av1_num_ext_tx_set[tx_set_type]);
 #if CONFIG_ENTROPY_STATS
         ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
 #endif  // CONFIG_ENTROPY_STATS
@@ -4444,24 +4490,27 @@
         ++counts
               ->intra_ext_tx[eset][txsize_sqr_map[tx_size]][intra_dir][tx_type];
 #endif  // CONFIG_ENTROPY_STATS
-        update_cdf(
-            fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][intra_dir],
-            av1_ext_tx_ind[tx_set_type][tx_type],
-            av1_num_ext_tx_set[tx_set_type]);
+        if (allow_update_cdf)
+          update_cdf(
+              fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][intra_dir],
+              av1_ext_tx_ind[tx_set_type][tx_type],
+              av1_num_ext_tx_set[tx_set_type]);
 #else
 #if CONFIG_ENTROPY_STATS
         ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
                               [tx_type];
 #endif  // CONFIG_ENTROPY_STATS
-        update_cdf(
-            fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][mbmi->mode],
-            av1_ext_tx_ind[tx_set_type][tx_type],
-            av1_num_ext_tx_set[tx_set_type]);
+        if (allow_update_cdf)
+          update_cdf(
+              fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][mbmi->mode],
+              av1_ext_tx_ind[tx_set_type][tx_type],
+              av1_num_ext_tx_set[tx_set_type]);
 #endif
       }
 #else
       (void)tx_type;
       (void)fc;
+      (void)allow_update_cdf;
       if (is_inter) {
         if (LGT_FROM_PRED_INTER) {
           if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
@@ -4501,9 +4550,10 @@
   }
 }
 
-static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
-                              TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
-                              int mi_col, BLOCK_SIZE bsize, int *rate) {
+static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data,
+                              ThreadData *td, TOKENEXTRA **t, RUN_TYPE dry_run,
+                              int mi_row, int mi_col, BLOCK_SIZE bsize,
+                              int *rate) {
   const AV1_COMMON *const cm = &cpi->common;
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
@@ -4533,9 +4583,11 @@
 #endif  // CONFIG_CFL
     if (!dry_run) {
       sum_intra_stats(td->counts, xd, mi, xd->above_mi, xd->left_mi,
-                      frame_is_intra_only(cm), mi_row, mi_col);
+                      frame_is_intra_only(cm), mi_row, mi_col,
+                      tile_data->allow_update_cdf);
 #if CONFIG_NEW_MULTISYMBOL
-      if (av1_allow_palette(cm->allow_screen_content_tools, bsize))
+      if (av1_allow_palette(cm->allow_screen_content_tools, bsize) &&
+          tile_data->allow_update_cdf)
         update_palette_cdf(xd, mi);
 #endif
     }
@@ -4555,9 +4607,11 @@
 
     mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
 #if CONFIG_LV_MAP
-    av1_update_txb_context(cpi, td, dry_run, block_size, rate, mi_row, mi_col);
+    av1_update_txb_context(cpi, td, dry_run, block_size, rate, mi_row, mi_col,
+                           tile_data->allow_update_cdf);
 #else   // CONFIG_LV_MAP
-    av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
+    av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col,
+                    tile_data->allow_update_cdf);
 #endif  // CONFIG_LV_MAP
   } else {
     int ref;
@@ -4613,8 +4667,8 @@
 
     av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
     if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
-    av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col, block_size,
-                          rate);
+    av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col, block_size, rate,
+                          tile_data->allow_update_cdf);
   }
 
 #if CONFIG_DIST_8X8
@@ -4631,7 +4685,8 @@
     if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id] &&
         mbmi->sb_type > BLOCK_4X4 && !(is_inter && (mbmi->skip || seg_skip))) {
       if (is_inter) {
-        tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
+        tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts,
+                                  tile_data->allow_update_cdf);
       } else {
         if (tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
       }
@@ -4644,7 +4699,8 @@
         const int use_qttx = mbmi->tx_size == quarter_txsize_lookup[bsize];
         ++td->counts->quarter_tx_size[use_qttx];
 #if CONFIG_NEW_MULTISYMBOL
-        update_cdf(xd->tile_ctx->quarter_tx_size_cdf, use_qttx, 2);
+        if (tile_data->allow_update_cdf)
+          update_cdf(xd->tile_ctx->quarter_tx_size_cdf, use_qttx, 2);
 #endif
       }
 #endif
@@ -4675,7 +4731,8 @@
     }
 
 #if !CONFIG_TXK_SEL
-    av1_update_tx_type_count(cm, xd, bsize, tx_size, td->counts);
+    av1_update_tx_type_count(cm, xd, bsize, tx_size, td->counts,
+                             tile_data->allow_update_cdf);
 #endif
   }
 
diff --git a/av1/encoder/encodeframe.h b/av1/encoder/encodeframe.h
index b54e54d..745940d 100644
--- a/av1/encoder/encodeframe.h
+++ b/av1/encoder/encodeframe.h
@@ -40,7 +40,7 @@
                               int blk_row, int blk_col, int block, int plane,
 #endif
                               BLOCK_SIZE bsize, TX_SIZE tx_size,
-                              FRAME_COUNTS *counts);
+                              FRAME_COUNTS *counts, uint8_t allow_update_cdf);
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index ff978a2..075b07d 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -320,6 +320,7 @@
   CFL_CTX cfl;
 #endif
   DECLARE_ALIGNED(16, FRAME_CONTEXT, tctx);
+  uint8_t allow_update_cdf;
 } TileDataEnc;
 
 typedef struct RD_COUNTS {
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index dbb7d90..05a2033 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -132,7 +132,8 @@
 
 void av1_update_eob_context(int eob, int seg_eob, TX_SIZE tx_size,
                             TX_TYPE tx_type, PLANE_TYPE plane,
-                            FRAME_CONTEXT *ec_ctx, FRAME_COUNTS *counts) {
+                            FRAME_CONTEXT *ec_ctx, FRAME_COUNTS *counts,
+                            uint8_t allow_update_cdf) {
   int16_t eob_extra;
   int16_t eob_pt = get_eob_pos_token(eob, &eob_extra);
   int16_t dummy;
@@ -142,8 +143,9 @@
   for (int i = 1; i < max_eob_pt; i++) {
     int eob_pos_ctx = av1_get_eob_pos_ctx(tx_type, i);
     counts->eob_flag[txs_ctx][plane][eob_pos_ctx][eob_pt == i]++;
-    update_cdf(ec_ctx->eob_flag_cdf[txs_ctx][plane][eob_pos_ctx], eob_pt == i,
-               2);
+    if (allow_update_cdf)
+      update_cdf(ec_ctx->eob_flag_cdf[txs_ctx][plane][eob_pos_ctx], eob_pt == i,
+                 2);
     if (eob_pt == i) {
       break;
     }
@@ -153,7 +155,8 @@
     int eob_shift = k_eob_offset_bits[eob_pt] - 1;
     int bit = (eob_extra & (1 << eob_shift)) ? 1 : 0;
     counts->eob_extra[txs_ctx][plane][eob_pt][bit]++;
-    update_cdf(ec_ctx->eob_extra_cdf[txs_ctx][plane][eob_pt], bit, 2);
+    if (allow_update_cdf)
+      update_cdf(ec_ctx->eob_extra_cdf[txs_ctx][plane][eob_pt], bit, 2);
   }
 }
 
@@ -1974,6 +1977,7 @@
   const int height = tx_size_high[tx_size];
   uint8_t levels[64 * 64];
   int8_t signs[64 * 64];
+  const uint8_t allow_update_cdf = args->allow_update_cdf;
 
   TX_SIZE txsize_ctx = get_txsize_context(tx_size);
   FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
@@ -1981,8 +1985,9 @@
   memcpy(tcoeff, qcoeff, sizeof(*tcoeff) * seg_eob);
 
   ++td->counts->txb_skip[txsize_ctx][txb_ctx.txb_skip_ctx][eob == 0];
-  update_bin(ec_ctx->txb_skip_cdf[txsize_ctx][txb_ctx.txb_skip_ctx], eob == 0,
-             2);
+  if (allow_update_cdf)
+    update_bin(ec_ctx->txb_skip_cdf[txsize_ctx][txb_ctx.txb_skip_ctx], eob == 0,
+               2);
   x->mbmi_ext->txb_skip_ctx[plane][block] = txb_ctx.txb_skip_ctx;
 
   x->mbmi_ext->eobs[plane][block] = eob;
@@ -1999,13 +2004,14 @@
 
 #if CONFIG_TXK_SEL
   av1_update_tx_type_count(cm, xd, blk_row, blk_col, block, plane,
-                           mbmi->sb_type, get_min_tx_size(tx_size), td->counts);
+                           mbmi->sb_type, get_min_tx_size(tx_size), td->counts,
+                           allow_update_cdf);
 #endif
 
   unsigned int(*nz_map_count)[SIG_COEF_CONTEXTS][2] =
       &(td->counts->nz_map[txsize_ctx][plane_type]);
   av1_update_eob_context(eob, seg_eob, tx_size, tx_type, plane_type, ec_ctx,
-                         td->counts);
+                         td->counts, allow_update_cdf);
 #if USE_CAUSAL_BASE_CTX
   int coeff_ctx = 0;
   update_eob = eob - 1;
@@ -2018,8 +2024,9 @@
     coeff_ctx = get_nz_map_ctx(tcoeff, c, scan, bwl, height, tx_type, 0);
     if (c < eob - 1) {
       ++(*nz_map_count)[coeff_ctx][is_nz];
-      update_cdf(ec_ctx->nz_map_cdf[txsize_ctx][plane_type][coeff_ctx], is_nz,
-                 2);
+      if (allow_update_cdf)
+        update_cdf(ec_ctx->nz_map_cdf[txsize_ctx][plane_type][coeff_ctx], is_nz,
+                   2);
     }
 
     if (is_nz) {
@@ -2029,8 +2036,9 @@
         int is_k = (abs(v) > (k + 1));
 
         ++td->counts->coeff_base[txsize_ctx][plane_type][k][ctx][is_k];
-        update_bin(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][k][ctx], is_k,
-                   2);
+        if (allow_update_cdf)
+          update_bin(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][k][ctx],
+                     is_k, 2);
         if (is_k == 0) break;
       }
     }
@@ -2040,7 +2048,9 @@
     if (c == eob - 1) continue;
 
     ++(*nz_map_count)[coeff_ctx][is_nz];
-    update_cdf(ec_ctx->nz_map_cdf[txsize_ctx][plane_type][coeff_ctx], is_nz, 2);
+    if (allow_update_cdf)
+      update_cdf(ec_ctx->nz_map_cdf[txsize_ctx][plane_type][coeff_ctx], is_nz,
+                 2);
 #endif
   }
 
@@ -2058,12 +2068,15 @@
 
       if (level == i + 1) {
         ++td->counts->coeff_base[txsize_ctx][plane_type][i][ctx][1];
-        update_bin(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][i][ctx], 1,
-                   2);
+        if (allow_update_cdf)
+          update_bin(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][i][ctx], 1,
+                     2);
         continue;
       }
       ++td->counts->coeff_base[txsize_ctx][plane_type][i][ctx][0];
-      update_bin(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][i][ctx], 0, 2);
+      if (allow_update_cdf)
+        update_bin(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][i][ctx], 0,
+                   2);
       update_eob = AOMMAX(update_eob, c);
     }
   }
@@ -2076,7 +2089,8 @@
 
     ++td->counts->dc_sign[plane_type][dc_sign_ctx][sign];
 #if LV_MAP_PROB
-    update_bin(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], sign, 2);
+    if (allow_update_cdf)
+      update_bin(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], sign, 2);
 #endif
     x->mbmi_ext->dc_sign_ctx[plane][block] = dc_sign_ctx;
   }
@@ -2101,23 +2115,29 @@
         int br_base = br_index_to_coeff[br_set_idx];
         int br_offset = base_range - br_base;
         ++td->counts->coeff_br[txsize_ctx][plane_type][idx][ctx][1];
-        update_bin(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][idx][ctx], 1,
-                   2);
+        if (allow_update_cdf)
+          update_bin(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][idx][ctx], 1,
+                     2);
         int extra_bits = (1 << br_extra_bits[idx]) - 1;
         for (int tok = 0; tok < extra_bits; ++tok) {
           if (br_offset == tok) {
             ++td->counts->coeff_lps[txsize_ctx][plane_type][ctx][1];
-            update_bin(ec_ctx->coeff_lps_cdf[txsize_ctx][plane_type][ctx], 1,
-                       2);
+            if (allow_update_cdf)
+              update_bin(ec_ctx->coeff_lps_cdf[txsize_ctx][plane_type][ctx], 1,
+                         2);
             break;
           }
           ++td->counts->coeff_lps[txsize_ctx][plane_type][ctx][0];
-          update_bin(ec_ctx->coeff_lps_cdf[txsize_ctx][plane_type][ctx], 0, 2);
+          if (allow_update_cdf)
+            update_bin(ec_ctx->coeff_lps_cdf[txsize_ctx][plane_type][ctx], 0,
+                       2);
         }
         break;
       }
       ++td->counts->coeff_br[txsize_ctx][plane_type][idx][ctx][0];
-      update_bin(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][idx][ctx], 0, 2);
+      if (allow_update_cdf)
+        update_bin(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][idx][ctx], 0,
+                   2);
     }
     // use 0-th order Golomb code to handle the residual level.
   }
@@ -2137,11 +2157,11 @@
 
 void av1_update_txb_context(const AV1_COMP *cpi, ThreadData *td,
                             RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
-                            int mi_row, int mi_col) {
+                            int mi_row, int mi_col, uint8_t allow_update_cdf) {
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
-  struct tokenize_b_args arg = { cpi, td, NULL, 0 };
+  struct tokenize_b_args arg = { cpi, td, NULL, 0, allow_update_cdf };
   (void)rate;
   (void)mi_row;
   (void)mi_col;
diff --git a/av1/encoder/encodetxb.h b/av1/encoder/encodetxb.h
index f9362da..653e131 100644
--- a/av1/encoder/encodetxb.h
+++ b/av1/encoder/encodetxb.h
@@ -82,7 +82,8 @@
                                 const SCAN_ORDER *scan_order, int eob);
 void av1_update_txb_context(const AV1_COMP *cpi, ThreadData *td,
                             RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
-                            const int mi_row, const int mi_col);
+                            const int mi_row, const int mi_col,
+                            uint8_t allow_update_cdf);
 
 void av1_update_txb_context_b(int plane, int block, int blk_row, int blk_col,
                               BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index f62fef4..947f05a 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -306,7 +306,7 @@
                              aom_cdf_prob (*tail_cdf)[CDF_SIZE(ENTROPY_TOKENS)],
                              aom_cdf_prob (*head_cdf)[CDF_SIZE(ENTROPY_TOKENS)],
                              int8_t eob_val, int8_t first_val, int32_t extra,
-                             uint8_t token) {
+                             uint8_t token, uint8_t allow_update_cdf) {
   (*t)->token = token;
   (*t)->extra = extra;
   (*t)->tail_cdf = tail_cdf;
@@ -315,15 +315,17 @@
   (*t)->first_val = first_val;
   (*t)++;
 
-  if (token == BLOCK_Z_TOKEN) {
-    update_cdf(*head_cdf, 0, HEAD_TOKENS + 1);
-  } else {
-    if (eob_val != LAST_EOB) {
-      const int symb = 2 * AOMMIN(token, TWO_TOKEN) - eob_val + first_val;
-      update_cdf(*head_cdf, symb, HEAD_TOKENS + first_val);
+  if (allow_update_cdf) {
+    if (token == BLOCK_Z_TOKEN) {
+      update_cdf(*head_cdf, 0, HEAD_TOKENS + 1);
+    } else {
+      if (eob_val != LAST_EOB) {
+        const int symb = 2 * AOMMIN(token, TWO_TOKEN) - eob_val + first_val;
+        update_cdf(*head_cdf, symb, HEAD_TOKENS + first_val);
+      }
+      if (token > ONE_TOKEN)
+        update_cdf(*tail_cdf, token - TWO_TOKEN, TAIL_TOKENS);
     }
-    if (token > ONE_TOKEN)
-      update_cdf(*tail_cdf, token - TWO_TOKEN, TAIL_TOKENS);
   }
 }
 
@@ -455,6 +457,7 @@
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   TOKENEXTRA **tp = args->tp;
+  const uint8_t allow_update_cdf = args->allow_update_cdf;
   uint8_t token_cache[MAX_TX_SQUARE];
   struct macroblock_plane *p = &x->plane[plane];
   struct macroblockd_plane *pd = &xd->plane[plane];
@@ -498,7 +501,7 @@
 
   if (eob == 0)
     add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt], 1,
-              1, 0, BLOCK_Z_TOKEN);
+              1, 0, BLOCK_Z_TOKEN, allow_update_cdf);
 
   while (c < eob) {
     int v = qcoeff[scan[c]];
@@ -506,14 +509,14 @@
 
     if (!v) {
       add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt],
-                0, first_val, 0, ZERO_TOKEN);
+                0, first_val, 0, ZERO_TOKEN, allow_update_cdf);
       token_cache[scan[c]] = 0;
     } else {
       eob_val =
           (c + 1 == eob) ? (c + 1 == seg_eob ? LAST_EOB : EARLY_EOB) : NO_EOB;
       av1_get_token_extra(v, &token, &extra);
       add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt],
-                eob_val, first_val, extra, (uint8_t)token);
+                eob_val, first_val, extra, (uint8_t)token, allow_update_cdf);
       token_cache[scan[c]] = av1_pt_energy_class[token];
     }
     ++c;
@@ -641,7 +644,8 @@
 
 void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
                            RUN_TYPE dry_run, int mi_row, int mi_col,
-                           BLOCK_SIZE bsize, int *rate) {
+                           BLOCK_SIZE bsize, int *rate,
+                           uint8_t allow_update_cdf) {
   const AV1_COMMON *const cm = &cpi->common;
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
@@ -651,7 +655,7 @@
 #else
   TOKENEXTRA *t_backup = *t;
 #endif
-  struct tokenize_b_args arg = { cpi, td, t, 0 };
+  struct tokenize_b_args arg = { cpi, td, t, 0, allow_update_cdf };
   int plane;
   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
 
@@ -729,11 +733,12 @@
 
 void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
                      RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
-                     const int mi_row, const int mi_col) {
+                     const int mi_row, const int mi_col,
+                     uint8_t allow_update_cdf) {
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
-  struct tokenize_b_args arg = { cpi, td, t, 0 };
+  struct tokenize_b_args arg = { cpi, td, t, 0, allow_update_cdf };
   if (mbmi->skip) {
     av1_reset_skip_context(xd, mi_row, mi_col, bsize);
     return;
diff --git a/av1/encoder/tokenize.h b/av1/encoder/tokenize.h
index 5dc39c1..77ae3bc 100644
--- a/av1/encoder/tokenize.h
+++ b/av1/encoder/tokenize.h
@@ -59,6 +59,7 @@
   struct ThreadData *td;
   TOKENEXTRA **tp;
   int this_rate;
+  uint8_t allow_update_cdf;
 };
 
 typedef enum {
@@ -72,7 +73,8 @@
 // otherwise rate is not incremented.
 void av1_tokenize_sb_vartx(const struct AV1_COMP *cpi, struct ThreadData *td,
                            TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
-                           int mi_col, BLOCK_SIZE bsize, int *rate);
+                           int mi_col, BLOCK_SIZE bsize, int *rate,
+                           uint8_t allow_update_cdf);
 
 int av1_cost_color_map(const MACROBLOCK *const x, int plane, int block,
                        BLOCK_SIZE bsize, TX_SIZE tx_size, COLOR_MAP_TYPE type);
@@ -83,7 +85,8 @@
 
 void av1_tokenize_sb(const struct AV1_COMP *cpi, struct ThreadData *td,
                      TOKENEXTRA **t, RUN_TYPE dry_run, BLOCK_SIZE bsize,
-                     int *rate, const int mi_row, const int mi_col);
+                     int *rate, const int mi_row, const int mi_col,
+                     uint8_t allow_update_cdf);
 
 extern const int16_t *av1_dct_value_cost_ptr;
 /* TODO: The Token field should be broken out into a separate char array to