[NORMATIVE] Use the primary reference frame as prev_frame

Previously LAST_FRAME was used.

BUG=aomedia:1589

Change-Id: I5358e81406afeda4b56de41e55c9c1ab104ec6c4
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index bec31a5..9951334 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -653,6 +653,15 @@
   return cm->frame_type == KEY_FRAME || cm->intra_only;
 }
 
+static INLINE RefCntBuffer *get_prev_frame(const AV1_COMMON *const cm) {
+  if (cm->primary_ref_frame == PRIMARY_REF_NONE ||
+      cm->frame_refs[cm->primary_ref_frame].idx == INVALID_IDX) {
+    return NULL;
+  } else {
+    return &cm->buffer_pool
+                ->frame_bufs[cm->frame_refs[cm->primary_ref_frame].idx];
+  }
+}
 // Returns 1 if this frame might use mvs from some previous frame. This
 // function doesn't consider whether prev_frame is actually suitable (see
 // frame_can_use_prev_frame_mvs for that)
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index a115413..78ff4e3 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -2522,8 +2522,9 @@
 static void read_global_motion(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
   for (int frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
     const WarpedMotionParams *ref_params =
-        cm->error_resilient_mode ? &default_warp_params
-                                 : &cm->prev_frame->global_motion[frame];
+        (cm->error_resilient_mode || cm->prev_frame == NULL)
+            ? &default_warp_params
+            : &cm->prev_frame->global_motion[frame];
     int good_params = read_global_motion_params(
         &cm->global_motion[frame], ref_params, rb, cm->allow_high_precision_mv);
     if (!good_params) {
@@ -2837,6 +2838,10 @@
   }
 #endif
 
+  if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) {
+    cm->primary_ref_frame = aom_rb_read_literal(rb, PRIMARY_REF_BITS);
+  }
+
   if (cm->frame_type == KEY_FRAME) {
 #if !CONFIG_EXPLICIT_ORDER_HINT
     wrap_around_current_video_frame(pbi);
@@ -3019,17 +3024,25 @@
 #endif
       cm->interp_filter = read_frame_interp_filter(rb);
       cm->switchable_motion_mode = aom_rb_read_bit(rb);
+    }
+
+    cm->prev_frame = get_prev_frame(cm);
+    if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) {
+      if (cm->primary_ref_frame != PRIMARY_REF_NONE &&
+          cm->frame_refs[cm->primary_ref_frame].idx < 0) {
+        aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
+                           "Reference frame containing this frame's initial "
+                           "frame context is unavailable.");
+      }
+    }
+
+    if (!cm->intra_only && pbi->need_resync != 1) {
       if (frame_might_use_prev_frame_mvs(cm) &&
           cm->seq_params.enable_order_hint)
         cm->use_ref_frame_mvs = aom_rb_read_bit(rb);
       else
         cm->use_ref_frame_mvs = 0;
 
-      cm->prev_frame =
-          cm->frame_refs[LAST_FRAME - LAST_FRAME].idx != INVALID_IDX
-              ? &cm->buffer_pool
-                     ->frame_bufs[cm->frame_refs[LAST_FRAME - LAST_FRAME].idx]
-              : NULL;
       for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
         RefBuffer *const ref_buf = &cm->frame_refs[i];
         av1_setup_scale_factors_for_frame(
@@ -3083,15 +3096,6 @@
   } else {
     cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
   }
-  if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) {
-    cm->primary_ref_frame = aom_rb_read_literal(rb, PRIMARY_REF_BITS);
-    if (cm->primary_ref_frame != PRIMARY_REF_NONE &&
-        cm->frame_refs[cm->primary_ref_frame].idx < 0) {
-      aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
-                         "Reference frame containing this frame's initial "
-                         "frame context is unavailable.");
-    }
-  }
 
   // Generate next_ref_frame_map.
   lock_buffer_pool(pool);
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index abc5643..2838da7 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -379,9 +379,6 @@
   if (!cm->show_existing_frame) {
     cm->last_show_frame = cm->show_frame;
 
-    // NOTE: It is not supposed to ref to any frame not used as reference
-    if (cm->is_reference_frame) cm->prev_frame = cm->cur_frame;
-
     if (cm->seg.enabled) {
 #if CONFIG_SEGMENT_PRED_LAST
       if (cm->prev_frame && (cm->mi_rows == cm->prev_frame->mi_rows) &&
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index c5b513f..70b20ff 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2928,8 +2928,9 @@
   int frame;
   for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
     const WarpedMotionParams *ref_params =
-        cm->error_resilient_mode ? &default_warp_params
-                                 : &cm->prev_frame->global_motion[frame];
+        (cm->error_resilient_mode || cm->prev_frame == NULL)
+            ? &default_warp_params
+            : &cm->prev_frame->global_motion[frame];
     write_global_motion_params(&cm->global_motion[frame], ref_params, wb,
                                cm->allow_high_precision_mv);
     // TODO(sarahparker, debargha): The logic in the commented out code below
@@ -3086,6 +3087,10 @@
   }
 #endif
 
+  if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) {
+    aom_wb_write_literal(wb, cm->primary_ref_frame, PRIMARY_REF_BITS);
+  }
+
   if (cm->frame_type == KEY_FRAME) {
     write_frame_size(cm, frame_size_override_flag, wb);
     assert(av1_superres_unscaled(cm) ||
@@ -3243,9 +3248,7 @@
     aom_wb_write_bit(
         wb, cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_DISABLED);
   }
-  if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) {
-    aom_wb_write_literal(wb, cm->primary_ref_frame, PRIMARY_REF_BITS);
-  }
+
 #if CONFIG_TILE_INFO_FIRST
   write_tile_info(cm, saved_wb, wb);
 #endif  // CONFIG_TILE_INFO_FIRST
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 8348f28..f09343c 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -304,7 +304,8 @@
     if (seg->enabled && !cpi->vaq_refresh) {
       const uint8_t *const map =
           seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
-      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
+      mbmi->segment_id =
+          map ? get_segment_id(cm, map, bsize, mi_row, mi_col) : 0;
     }
     av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
   }
@@ -459,7 +460,8 @@
     if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
       const uint8_t *const map =
           seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
-      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
+      mbmi->segment_id =
+          map ? get_segment_id(cm, map, bsize, mi_row, mi_col) : 0;
       reset_tx_size(x, mbmi, cm->tx_mode);
     }
     // Else for cyclic refresh mode update the segment map, set the segment id
@@ -3505,7 +3507,8 @@
       const uint8_t *const map =
           seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
       int segment_id =
-          get_segment_id(cm, map, cm->seq_params.sb_size, mi_row, mi_col);
+          map ? get_segment_id(cm, map, cm->seq_params.sb_size, mi_row, mi_col)
+              : 0;
       seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
     }
 #if CONFIG_AMVR
@@ -4084,7 +4087,6 @@
   MACROBLOCKD *const xd = &x->e_mbd;
   RD_COUNTS *const rdc = &cpi->td.rd_counts;
   int i;
-  const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
 
   x->min_partition_size = AOMMIN(x->min_partition_size, cm->seq_params.sb_size);
   x->max_partition_size = AOMMIN(x->max_partition_size, cm->seq_params.sb_size);
@@ -4197,6 +4199,62 @@
   }
 #endif
 
+  for (i = 0; i < MAX_SEGMENTS; ++i) {
+    const int qindex = cm->seg.enabled
+                           ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
+                           : cm->base_qindex;
+    xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
+                      cm->u_dc_delta_q == 0 && cm->u_ac_delta_q == 0 &&
+                      cm->v_dc_delta_q == 0 && cm->v_ac_delta_q == 0;
+    if (xd->lossless[i]) cpi->has_lossless_segment = 1;
+    xd->qindex[i] = qindex;
+    if (xd->lossless[i]) {
+      cpi->optimize_seg_arr[i] = 0;
+    } else {
+      cpi->optimize_seg_arr[i] = cpi->optimize_speed_feature;
+    }
+  }
+  cm->all_lossless = all_lossless(cm, xd);
+
+  cm->tx_mode = select_tx_mode(cpi);
+
+  // Fix delta q resolution for the moment
+  cm->delta_q_res = DEFAULT_DELTA_Q_RES;
+// Set delta_q_present_flag before it is used for the first time
+#if CONFIG_EXT_DELTA_Q
+  cm->delta_lf_res = DEFAULT_DELTA_LF_RES;
+  cm->delta_q_present_flag = cpi->oxcf.deltaq_mode != NO_DELTA_Q;
+  cm->delta_lf_present_flag = cpi->oxcf.deltaq_mode == DELTA_Q_LF;
+  cm->delta_lf_multi = DEFAULT_DELTA_LF_MULTI;
+  // update delta_q_present_flag and delta_lf_present_flag based on base_qindex
+  cm->delta_q_present_flag &= cm->base_qindex > 0;
+  cm->delta_lf_present_flag &= cm->base_qindex > 0;
+#else
+  cm->delta_q_present_flag =
+      cpi->oxcf.aq_mode == DELTA_AQ && cm->base_qindex > 0;
+#endif  // CONFIG_EXT_DELTA_Q
+
+  av1_frame_init_quantizer(cpi);
+
+  av1_initialize_rd_consts(cpi);
+  av1_initialize_me_consts(cpi, x, cm->base_qindex);
+  init_encode_frame_mb_context(cpi);
+
+#if CONFIG_SEGMENT_PRED_LAST
+  if (cm->prev_frame)
+    cm->last_frame_seg_map = cm->prev_frame->seg_map;
+  else
+    cm->last_frame_seg_map = NULL;
+  cm->current_frame_seg_map = cm->cur_frame->seg_map;
+#endif
+
+  // Special case: set prev_mi to NULL when the previous mode info
+  // context cannot be used.
+  cm->prev_mi = cm->use_ref_frame_mvs ? cm->prev_mip : NULL;
+
+  x->txb_split_count = 0;
+  av1_zero(x->blk_skip_drl);
+
   av1_zero(rdc->global_motion_used);
   av1_zero(cpi->gmparams_cost);
   if (cpi->common.frame_type == INTER_FRAME && cpi->source &&
@@ -4217,8 +4275,9 @@
       int pframe;
       cm->global_motion[frame] = default_warp_params;
       const WarpedMotionParams *ref_params =
-          cm->error_resilient_mode ? &default_warp_params
-                                   : &cm->prev_frame->global_motion[frame];
+          (cm->error_resilient_mode || cm->prev_frame == NULL)
+              ? &default_warp_params
+              : &cm->prev_frame->global_motion[frame];
       // check for duplicate buffer
       for (pframe = LAST_FRAME; pframe < frame; ++pframe) {
         if (ref_buf[frame] == ref_buf[pframe]) break;
@@ -4315,62 +4374,6 @@
   memcpy(cm->cur_frame->global_motion, cm->global_motion,
          TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
 
-  for (i = 0; i < MAX_SEGMENTS; ++i) {
-    const int qindex = cm->seg.enabled
-                           ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
-                           : cm->base_qindex;
-    xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
-                      cm->u_dc_delta_q == 0 && cm->u_ac_delta_q == 0 &&
-                      cm->v_dc_delta_q == 0 && cm->v_ac_delta_q == 0;
-    if (xd->lossless[i]) cpi->has_lossless_segment = 1;
-    xd->qindex[i] = qindex;
-    if (xd->lossless[i]) {
-      cpi->optimize_seg_arr[i] = 0;
-    } else {
-      cpi->optimize_seg_arr[i] = cpi->optimize_speed_feature;
-    }
-  }
-  cm->all_lossless = all_lossless(cm, xd);
-
-  cm->tx_mode = select_tx_mode(cpi);
-
-  // Fix delta q resolution for the moment
-  cm->delta_q_res = DEFAULT_DELTA_Q_RES;
-// Set delta_q_present_flag before it is used for the first time
-#if CONFIG_EXT_DELTA_Q
-  cm->delta_lf_res = DEFAULT_DELTA_LF_RES;
-  cm->delta_q_present_flag = cpi->oxcf.deltaq_mode != NO_DELTA_Q;
-  cm->delta_lf_present_flag = cpi->oxcf.deltaq_mode == DELTA_Q_LF;
-  cm->delta_lf_multi = DEFAULT_DELTA_LF_MULTI;
-  // update delta_q_present_flag and delta_lf_present_flag based on base_qindex
-  cm->delta_q_present_flag &= cm->base_qindex > 0;
-  cm->delta_lf_present_flag &= cm->base_qindex > 0;
-#else
-  cm->delta_q_present_flag =
-      cpi->oxcf.aq_mode == DELTA_AQ && cm->base_qindex > 0;
-#endif  // CONFIG_EXT_DELTA_Q
-
-  av1_frame_init_quantizer(cpi);
-
-  av1_initialize_rd_consts(cpi);
-  av1_initialize_me_consts(cpi, x, cm->base_qindex);
-  init_encode_frame_mb_context(cpi);
-
-  cm->prev_frame = last_fb_buf_idx != INVALID_IDX
-                       ? &cm->buffer_pool->frame_bufs[last_fb_buf_idx]
-                       : NULL;
-#if CONFIG_SEGMENT_PRED_LAST
-  if (cm->prev_frame) cm->last_frame_seg_map = cm->prev_frame->seg_map;
-  cm->current_frame_seg_map = cm->cur_frame->seg_map;
-#endif
-
-  // Special case: set prev_mi to NULL when the previous mode info
-  // context cannot be used.
-  cm->prev_mi = cm->use_ref_frame_mvs ? cm->prev_mip : NULL;
-
-  x->txb_split_count = 0;
-  av1_zero(x->blk_skip_drl);
-
   av1_setup_motion_field(cm);
 
   cpi->all_one_sided_refs =
@@ -4744,12 +4747,16 @@
                                    mi_row, mi_col);
     }
 
-    // If there is at least one lossless segment, force the skip for intra block
-    // to be 0, in order to avoid the segment_id to be changed by in
-    // write_segment_id().
+      // If there is at least one lossless segment, force the skip for intra
+      // block to be 0, in order to avoid the segment_id to be changed by in
+      // write_segment_id().
+#if CONFIG_SPATIAL_SEGMENTATION
     if (!cpi->common.seg.preskip_segid && cpi->common.seg.update_map &&
         cpi->has_lossless_segment)
       mbmi->skip = 0;
+#else
+    if (cpi->common.seg.update_map && cpi->has_lossless_segment) mbmi->skip = 0;
+#endif
 
     xd->cfl.store_y = 0;
     if (av1_allow_palette(cm->allow_screen_content_tools, bsize)) {
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 49ab33c..d637219 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -302,10 +302,6 @@
   // other inter-frames the encoder currently uses only two contexts;
   // context 1 for ALTREF frames and context 0 for the others.
 
-#if CONFIG_SEGMENT_PRED_LAST
-  if (cm->prev_frame) cm->last_frame_seg_map = cm->prev_frame->seg_map;
-  cm->current_frame_seg_map = cm->cur_frame->seg_map;
-#endif
   cm->primary_ref_frame = PRIMARY_REF_NONE;
   if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
     av1_setup_past_independence(cm);
@@ -361,7 +357,16 @@
     av1_zero(cpi->interp_filter_selected[0]);
   }
 
+  cm->prev_frame = get_prev_frame(cm);
   cpi->vaq_refresh = 0;
+
+#if CONFIG_SEGMENT_PRED_LAST
+  if (cm->prev_frame)
+    cm->last_frame_seg_map = cm->prev_frame->seg_map;
+  else
+    cm->last_frame_seg_map = NULL;
+  cm->current_frame_seg_map = cm->cur_frame->seg_map;
+#endif
 }
 
 static void enc_setup_mi(AV1_COMMON *cm) {
@@ -560,8 +565,10 @@
     av1_set_default_ref_deltas(last_ref_deltas);
     av1_set_default_mode_deltas(last_mode_deltas);
   } else {
+    assert(cm->buffer_pool->frame_bufs[buf_idx].ref_deltas != NULL);
     memcpy(last_ref_deltas, cm->buffer_pool->frame_bufs[buf_idx].ref_deltas,
            TOTAL_REFS_PER_FRAME);
+    assert(cm->buffer_pool->frame_bufs[buf_idx].mode_deltas != NULL);
     memcpy(last_mode_deltas, cm->buffer_pool->frame_bufs[buf_idx].mode_deltas,
            MAX_MODE_LF_DELTAS);
   }
@@ -4386,10 +4393,11 @@
   apply_active_map(cpi);
 #if CONFIG_SEGMENT_PRED_LAST
   if (cm->seg.enabled) {
-    if (cm->seg.update_data)
+    if (cm->seg.update_data) {
       segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
-    else if (cm->prev_frame)
+    } else if (cm->prev_frame) {
       segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
+    }
   }
 #endif
 
@@ -4494,10 +4502,11 @@
     }
 #if CONFIG_SEGMENT_PRED_LAST
     if (cm->seg.enabled) {
-      if (cm->seg.update_data)
+      if (cm->seg.update_data) {
         segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
-      else if (cm->prev_frame)
+      } else if (cm->prev_frame) {
         segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
+      }
     }
 #endif
 
@@ -5211,7 +5220,7 @@
   if (cm->seg.enabled) {
     if (cm->seg.update_map) {
       update_reference_segmentation_map(cpi);
-    } else {
+    } else if (cm->last_frame_seg_map) {
       memcpy(cm->current_frame_seg_map, cm->last_frame_seg_map,
              cm->mi_cols * cm->mi_rows * sizeof(uint8_t));
     }
@@ -5283,7 +5292,6 @@
 
   // NOTE: Shall not refer to any frame not used as reference.
   if (cm->is_reference_frame) {
-    cm->prev_frame = cm->cur_frame;
     // keep track of the last coded dimensions
     cm->last_width = cm->width;
     cm->last_height = cm->height;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 9ebf0e2..c7b6dfb 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4460,7 +4460,6 @@
 
   ref_best_rd = AOMMIN(rd, ref_best_rd);
   if (rd < best_rd) {
-    best_rd = rd;
     *rd_stats = this_rd_stats;
     best_tx = mbmi->tx_size;
     memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
diff --git a/av1/encoder/segmentation.c b/av1/encoder/segmentation.c
index e90fb07..d77bcb5 100644
--- a/av1/encoder/segmentation.c
+++ b/av1/encoder/segmentation.c
@@ -70,7 +70,9 @@
     const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
     // Test to see if the segment id matches the predicted value.
     const int pred_segment_id =
-        get_segment_id(cm, cm->last_frame_seg_map, bsize, mi_row, mi_col);
+        cm->last_frame_seg_map
+            ? get_segment_id(cm, cm->last_frame_seg_map, bsize, mi_row, mi_col)
+            : 0;
     const int pred_flag = pred_segment_id == segment_id;
     const int pred_context = av1_get_pred_context_seg_id(xd);