PVQ uses backward updated context in a tile

In the beginning of encoding and bitstream packing,
the frame context in common of codec is copied to the frame context
in each tile.
Initial prob and context is based on flat probability and
does not come from table at the moment.

The bd-rate change for the test set objective-1-fast
on awcy with high delay mode is:

PSNR   PSNR  HVS  SSIM  CIEDE 2000  PSNR Cb PSNR Cr MS SSIM
-0.77  -1.05      -0.74 -0.67       -0.67   -0.77   -0.88

Change-Id: Ic9105ac68aceb7486cb5f6f1c0b19df5853f2cb9
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index f802662..5c5599f 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -1037,7 +1037,7 @@
   const BLOCK_SIZE plane_bsize =
       get_plane_block_size(AOMMAX(bsize, BLOCK_8X8), pd);
 
-  adapt = &x->daala_enc.state.adapt;
+  adapt = x->daala_enc.state.adapt;
 
   max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
   max_blocks_high = max_block_high(xd, plane_bsize, plane);
@@ -4121,6 +4121,10 @@
       this_tile->tctx = *cm->fc;
       cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx;
 #endif
+#if CONFIG_PVQ
+      cpi->td.mb.pvq_q = &this_tile->pvq_q;
+      cpi->td.mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context;
+#endif  // CONFIG_PVQ
 #if CONFIG_ANS
       buf_ans_write_init(buf_ans, dst + total_size);
       write_modes(cpi, &tile_info, buf_ans, &tok, tok_end);
@@ -4129,11 +4133,6 @@
       tile_size = buf_ans_write_end(buf_ans);
 #else
       aom_start_encode(&mode_bc, dst + total_size);
-#if CONFIG_PVQ
-      // NOTE: This will not work with CONFIG_ANS turned on.
-      od_adapt_ctx_reset(&cpi->td.mb.daala_enc.state.adapt, 0);
-      cpi->td.mb.pvq_q = &this_tile->pvq_q;
-#endif
       write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end);
 #if !CONFIG_LV_MAP
       assert(tok == tok_end);
diff --git a/av1/encoder/daala_compat_enc.c b/av1/encoder/daala_compat_enc.c
index 1933d5c..3df424c 100644
--- a/av1/encoder/daala_compat_enc.c
+++ b/av1/encoder/daala_compat_enc.c
@@ -17,7 +17,7 @@
 #else
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
-  OD_COPY(&rbuf->adapt, &enc->state.adapt, 1);
+  OD_COPY(&rbuf->adapt, enc->state.adapt, 1);
 }
 
 void od_encode_rollback(daala_enc_ctx *enc, const od_rollback_buffer *rbuf) {
@@ -26,5 +26,5 @@
 #else
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
-  OD_COPY(&enc->state.adapt, &rbuf->adapt, 1);
+  OD_COPY(enc->state.adapt, &rbuf->adapt, 1);
 }
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index d101f02..fa65bb9 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4866,9 +4866,7 @@
   const TileInfo *const tile_info = &this_tile->tile_info;
   TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
   int mi_row;
-#if CONFIG_PVQ
-  od_adapt_ctx *adapt;
-#endif
+
 #if CONFIG_DEPENDENT_HORZTILES
 #if CONFIG_TILE_GROUPS
   if ((!cm->dependent_horz_tiles) || (tile_row == 0) ||
@@ -4957,14 +4955,11 @@
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
 
-  adapt = &td->mb.daala_enc.state.adapt;
-
 #if CONFIG_DAALA_EC
   od_ec_enc_reset(&td->mb.daala_enc.w.ec);
 #else
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
-  od_adapt_ctx_reset(adapt, 0);
 #endif  // #if CONFIG_PVQ
 
 #if CONFIG_EC_ADAPT
@@ -4972,6 +4967,10 @@
   td->mb.e_mbd.tile_ctx = &this_tile->tctx;
 #endif  // #if CONFIG_EC_ADAPT
 
+#if CONFIG_PVQ
+  td->mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context;
+#endif  // CONFIG_PVQ
+
   for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
        mi_row += cm->mib_size) {
     encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index ceeac84..03ec981 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -1257,9 +1257,9 @@
 
   // Encode residue of DC coeff, if required.
   if (!has_dc_skip || out_int32[0]) {
-    generic_encode(&daala_enc->w, &daala_enc->state.adapt.model_dc[plane],
+    generic_encode(&daala_enc->w, &daala_enc->state.adapt->model_dc[plane],
                    abs(out_int32[0]) - has_dc_skip, -1,
-                   &daala_enc->state.adapt.ex_dc[plane][tx_size][0], 2);
+                   &daala_enc->state.adapt->ex_dc[plane][tx_size][0], 2);
   }
   if (out_int32[0]) {
     aom_write_bit(&daala_enc->w, out_int32[0] < 0);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 74c8491..03b3b49 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -503,6 +503,7 @@
   const int mb_scale = mi_size_wide[BLOCK_16X16];
 #if CONFIG_PVQ
   PVQ_QUEUE pvq_q;
+  od_adapt_ctx pvq_context;
 #endif
 
   // First pass code requires valid last and new frame buffers.
@@ -541,8 +542,6 @@
 #if CONFIG_PVQ
   // For pass 1 of 2-pass encoding, init here for PVQ for now.
   {
-    od_adapt_ctx *adapt;
-
     pvq_q.buf_len = 5000;
     CHECK_MEM_ERROR(cm, pvq_q.buf,
                     aom_malloc(pvq_q.buf_len * sizeof(PVQ_INFO)));
@@ -567,13 +566,11 @@
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
 
-    adapt = &x->daala_enc.state.adapt;
 #if CONFIG_DAALA_EC
     od_ec_enc_reset(&x->daala_enc.w.ec);
 #else
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
-    od_adapt_ctx_reset(adapt, 0);
   }
 #endif
 
@@ -595,6 +592,10 @@
   av1_init_scan_order(cm);
 #endif
   av1_convolve_init(cm);
+#if CONFIG_PVQ
+  od_adapt_ctx_reset(&pvq_context, 0);
+  x->daala_enc.state.adapt = &pvq_context;
+#endif  // CONFIG_PVQ
   av1_initialize_rd_consts(cpi);
 
   // Tiling is ignored in the first pass.
diff --git a/av1/encoder/pvq_encoder.c b/av1/encoder/pvq_encoder.c
index 4811544..945ecf8 100644
--- a/av1/encoder/pvq_encoder.c
+++ b/av1/encoder/pvq_encoder.c
@@ -797,10 +797,10 @@
   else
     pvq_qm = 0;
 
-  exg = &enc->state.adapt.pvq.pvq_exg[pli][bs][0];
-  ext = enc->state.adapt.pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS;
-  skip_cdf = enc->state.adapt.skip_cdf[2*bs + (pli != 0)];
-  model = enc->state.adapt.pvq.pvq_param_model;
+  exg = &enc->state.adapt->pvq.pvq_exg[pli][bs][0];
+  ext = enc->state.adapt->pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS;
+  skip_cdf = enc->state.adapt->skip_cdf[2*bs + (pli != 0)];
+  model = enc->state.adapt->pvq.pvq_param_model;
   nb_bands = OD_BAND_OFFSETS[bs][0];
   off = &OD_BAND_OFFSETS[bs][1];
 
@@ -847,7 +847,7 @@
 
     qg[i] = pvq_theta(out + off[i], in + off[i], ref + off[i], size[i],
      q, y + off[i], &theta[i], &max_theta[i],
-     &k[i], beta[i], &skip_diff, nodesync, is_keyframe, pli, &enc->state.adapt,
+     &k[i], beta[i], &skip_diff, nodesync, is_keyframe, pli, enc->state.adapt,
      qm + off[i], qm_inv + off[i], enc->pvq_norm_lambda, speed);
   }
   od_encode_checkpoint(enc, &buf);
@@ -871,8 +871,8 @@
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
       od_encode_checkpoint(enc, &dc_buf);
-      generic_encode(&enc->w, &enc->state.adapt.model_dc[pli],
-       n - 1, -1, &enc->state.adapt.ex_dc[pli][bs][0], 2);
+      generic_encode(&enc->w, &enc->state.adapt->model_dc[pli],
+       n - 1, -1, &enc->state.adapt->ex_dc[pli][bs][0], 2);
 #if CONFIG_DAALA_EC
       tell2 = od_ec_enc_tell_frac(&enc->w.ec) - tell2;
 #else
@@ -926,14 +926,14 @@
     encode_flip = pli != 0 && is_keyframe && theta[i] != -1 && !cfl_encoded;
     if (i == 0 || (!skip_rest && !(skip_dir & (1 << ((i - 1)%3))))) {
       pvq_encode_partition(&enc->w, qg[i], theta[i], max_theta[i], y + off[i],
-       size[i], k[i], model, &enc->state.adapt, exg + i, ext + i,
+       size[i], k[i], model, enc->state.adapt, exg + i, ext + i,
        nodesync, (pli != 0)*OD_TXSIZES*PVQ_MAX_PARTITIONS
        + bs*PVQ_MAX_PARTITIONS + i, is_keyframe, i == 0 && (i < nb_bands - 1),
        skip_rest, encode_flip, flip);
     }
     if (i == 0 && !skip_rest && bs > 0) {
       aom_write_symbol(&enc->w, skip_dir,
-       &enc->state.adapt.pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7);
+       &enc->state.adapt->pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7);
     }
     if (encode_flip) cfl_encoded = 1;
   }
@@ -977,8 +977,8 @@
 #error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
 #endif
         od_encode_checkpoint(enc, &dc_buf);
-        generic_encode(&enc->w, &enc->state.adapt.model_dc[pli],
-         n - 1, -1, &enc->state.adapt.ex_dc[pli][bs][0], 2);
+        generic_encode(&enc->w, &enc->state.adapt->model_dc[pli],
+         n - 1, -1, &enc->state.adapt->ex_dc[pli][bs][0], 2);
 #if CONFIG_DAALA_EC
         tell2 = od_ec_enc_tell_frac(&enc->w.ec) - tell2;
 #else