[Normative] Move global loopfilter info to ref buf

Let loop filer ref_delta, mode_deltas, sharpness_level
associated with corresponding reference buffer, such
that for error resilient frame or droppable frame, the
decoder could correctly decode contexts.

BUG=aomedia:1581
BUG=aomedia:1588

Change-Id: I3c297ec2b36b32c89b8ac783348c23d57d27d4d0
diff --git a/av1/common/av1_loopfilter.c b/av1/common/av1_loopfilter.c
index 7fe907a..1a5cb1b 100644
--- a/av1/common/av1_loopfilter.c
+++ b/av1/common/av1_loopfilter.c
@@ -655,7 +655,6 @@
 
   // init limits for given sharpness
   update_sharpness(lfi, lf->sharpness_level);
-  lf->last_sharpness_level = lf->sharpness_level;
 
   // init hev threshold const vectors
   for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++)
@@ -672,11 +671,8 @@
   struct loopfilter *const lf = &cm->lf;
   const struct segmentation *const seg = &cm->seg;
 
-  // update limits if sharpness has changed
-  if (lf->last_sharpness_level != lf->sharpness_level) {
-    update_sharpness(lfi, lf->sharpness_level);
-    lf->last_sharpness_level = lf->sharpness_level;
-  }
+  // update sharpness limits
+  update_sharpness(lfi, lf->sharpness_level);
 
   for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) {
     for (int dir = 0; dir < 2; ++dir) {
diff --git a/av1/common/av1_loopfilter.h b/av1/common/av1_loopfilter.h
index f811129..dbd0795 100644
--- a/av1/common/av1_loopfilter.h
+++ b/av1/common/av1_loopfilter.h
@@ -27,8 +27,6 @@
 
 #define SIMD_WIDTH 16
 
-#define MAX_MODE_LF_DELTAS 2
-
 enum lf_path {
   LF_PATH_420,
   LF_PATH_444,
@@ -122,7 +120,6 @@
   int filter_level_v;
 
   int sharpness_level;
-  int last_sharpness_level;
 
   uint8_t mode_ref_delta_enabled;
   uint8_t mode_ref_delta_update;
@@ -130,11 +127,9 @@
   // 0 = Intra, Last, Last2+Last3,
   // GF, BRF, ARF2, ARF
   int8_t ref_deltas[TOTAL_REFS_PER_FRAME];
-  int8_t last_ref_deltas[TOTAL_REFS_PER_FRAME];
 
   // 0 = ZERO_MV, MV
   int8_t mode_deltas[MAX_MODE_LF_DELTAS];
-  int8_t last_mode_deltas[MAX_MODE_LF_DELTAS];
 
 #if LOOP_FILTER_BITMASK
   LoopFilterMask *lfm;
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index fe44290..9f876a8 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -1144,24 +1144,32 @@
   av1_copy(fc->intrabc_cdf, default_intrabc_cdf);
 }
 
+void av1_set_default_ref_deltas(int8_t *ref_deltas) {
+  assert(ref_deltas != NULL);
+
+  ref_deltas[INTRA_FRAME] = 1;
+  ref_deltas[LAST_FRAME] = 0;
+  ref_deltas[LAST2_FRAME] = ref_deltas[LAST_FRAME];
+  ref_deltas[LAST3_FRAME] = ref_deltas[LAST_FRAME];
+  ref_deltas[BWDREF_FRAME] = ref_deltas[LAST_FRAME];
+  ref_deltas[GOLDEN_FRAME] = -1;
+  ref_deltas[ALTREF2_FRAME] = -1;
+  ref_deltas[ALTREF_FRAME] = -1;
+}
+
+void av1_set_default_mode_deltas(int8_t *mode_deltas) {
+  assert(mode_deltas != NULL);
+
+  mode_deltas[0] = 0;
+  mode_deltas[0] = 0;
+}
+
 static void set_default_lf_deltas(struct loopfilter *lf) {
   lf->mode_ref_delta_enabled = 1;
   lf->mode_ref_delta_update = 1;
 
-  lf->ref_deltas[INTRA_FRAME] = 1;
-  lf->ref_deltas[LAST_FRAME] = 0;
-  lf->ref_deltas[LAST2_FRAME] = lf->ref_deltas[LAST_FRAME];
-  lf->ref_deltas[LAST3_FRAME] = lf->ref_deltas[LAST_FRAME];
-  lf->ref_deltas[BWDREF_FRAME] = lf->ref_deltas[LAST_FRAME];
-  lf->ref_deltas[GOLDEN_FRAME] = -1;
-  lf->ref_deltas[ALTREF2_FRAME] = -1;
-  lf->ref_deltas[ALTREF_FRAME] = -1;
-
-  lf->mode_deltas[0] = 0;
-  lf->mode_deltas[1] = 0;
-
-  av1_copy(lf->last_ref_deltas, lf->ref_deltas);
-  av1_copy(lf->last_mode_deltas, lf->mode_deltas);
+  av1_set_default_ref_deltas(lf->ref_deltas);
+  av1_set_default_mode_deltas(lf->mode_deltas);
 }
 
 void av1_setup_frame_contexts(AV1_COMMON *cm) {
@@ -1176,8 +1184,6 @@
 void av1_setup_past_independence(AV1_COMMON *cm) {
   // Reset the segment feature data to the default stats:
   // Features disabled, 0, with delta coding (Default state).
-  struct loopfilter *const lf = &cm->lf;
-
   av1_clearall_segfeatures(&cm->seg);
 
   cm->current_frame_seg_map = cm->cur_frame->seg_map;
@@ -1185,13 +1191,12 @@
   if (cm->current_frame_seg_map)
     memset(cm->current_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols));
 
-  // Reset the mode ref deltas for loop filter
-  av1_zero(lf->last_ref_deltas);
-  av1_zero(lf->last_mode_deltas);
-  set_default_lf_deltas(lf);
-
-  // To force update of the sharpness
-  lf->last_sharpness_level = -1;
+  // reset mode ref deltas
+  av1_set_default_ref_deltas(cm->cur_frame->ref_deltas);
+  av1_set_default_mode_deltas(cm->cur_frame->mode_deltas);
+  cm->cur_frame->sharpness_level = -1;
+  cm->lf.sharpness_level = -1;
+  set_default_lf_deltas(&cm->lf);
 
   av1_default_coef_probs(cm);
   init_mode_probs(cm->fc);
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 0905516..53430c4 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -292,6 +292,8 @@
   { 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 4, 5, 3, 6, 7, 8 },
 };
 
+void av1_set_default_ref_deltas(int8_t *ref_deltas);
+void av1_set_default_mode_deltas(int8_t *mode_deltas);
 void av1_setup_frame_contexts(struct AV1Common *cm);
 void av1_setup_past_independence(struct AV1Common *cm);
 
diff --git a/av1/common/enums.h b/av1/common/enums.h
index d2dc31f..400a238 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -78,6 +78,8 @@
 #define II_WEDGE_IDX_ENTROPY_CODING 0
 #endif
 
+#define MAX_MODE_LF_DELTAS 2
+
 typedef enum COMPOUND_DIST_WEIGHT_MODE {
   DIST,
 } COMPOUND_DIST_WEIGHT_MODE;
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 5d99d5d..fe88c2d 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -154,6 +154,14 @@
   // when the frame is fully decoded.
   int row;
   int col;
+
+  // Inter frame reference frame delta for loop filter
+  int8_t ref_deltas[TOTAL_REFS_PER_FRAME];
+
+  // 0 = ZERO_MV, MV
+  int8_t mode_deltas[MAX_MODE_LF_DELTAS];
+
+  int sharpness_level;
 } RefCntBuffer;
 
 typedef struct BufferPool {
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 280c1c3..4758b18 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1101,8 +1101,23 @@
 static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
   assert(!cm->all_lossless);
   const int num_planes = av1_num_planes(cm);
-  if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
   struct loopfilter *lf = &cm->lf;
+  if ((cm->allow_intrabc && NO_FILTER_FOR_IBC) || cm->all_lossless) {
+    // write default deltas to frame buffer
+    av1_set_default_ref_deltas(lf->ref_deltas);
+    av1_set_default_mode_deltas(lf->mode_deltas);
+    av1_set_default_ref_deltas(cm->cur_frame->ref_deltas);
+    av1_set_default_mode_deltas(cm->cur_frame->mode_deltas);
+    cm->cur_frame->sharpness_level = -1;
+    lf->sharpness_level = -1;
+    return;
+  }
+  if (cm->prev_frame) {
+    // write deltas to frame buffer
+    memcpy(lf->ref_deltas, cm->prev_frame->ref_deltas, TOTAL_REFS_PER_FRAME);
+    memcpy(lf->mode_deltas, cm->prev_frame->mode_deltas, MAX_MODE_LF_DELTAS);
+    lf->sharpness_level = cm->prev_frame->sharpness_level;
+  }
   lf->filter_level[0] = aom_rb_read_literal(rb, 6);
   lf->filter_level[1] = aom_rb_read_literal(rb, 6);
   if (num_planes > 1) {
@@ -1130,6 +1145,11 @@
           lf->mode_deltas[i] = aom_rb_read_inv_signed_literal(rb, 6);
     }
   }
+
+  // write deltas to frame buffer
+  cm->cur_frame->sharpness_level = lf->sharpness_level;
+  memcpy(cm->cur_frame->ref_deltas, lf->ref_deltas, TOTAL_REFS_PER_FRAME);
+  memcpy(cm->cur_frame->mode_deltas, lf->mode_deltas, MAX_MODE_LF_DELTAS);
 }
 
 static void setup_cdef(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
diff --git a/av1/decoder/dthread.c b/av1/decoder/dthread.c
index 20724ff..c186f46 100644
--- a/av1/decoder/dthread.c
+++ b/av1/decoder/dthread.c
@@ -176,7 +176,7 @@
 
   memcpy(dst_cm->lf_info.lfthr, src_cm->lf_info.lfthr,
          (MAX_LOOP_FILTER + 1) * sizeof(loop_filter_thresh));
-  dst_cm->lf.last_sharpness_level = src_cm->lf.sharpness_level;
+  dst_cm->lf.sharpness_level = src_cm->lf.sharpness_level;
   dst_cm->lf.filter_level[0] = src_cm->lf.filter_level[0];
   dst_cm->lf.filter_level[1] = src_cm->lf.filter_level[1];
   memcpy(dst_cm->lf.ref_deltas, src_cm->lf.ref_deltas, TOTAL_REFS_PER_FRAME);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 5713d94..840b192 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2021,25 +2021,38 @@
 
   if (lf->mode_ref_delta_enabled) {
     aom_wb_write_bit(wb, lf->mode_ref_delta_update);
+
     if (lf->mode_ref_delta_update) {
+      const int prime_idx = cm->primary_ref_frame;
+      const int buf_idx =
+          prime_idx == PRIMARY_REF_NONE ? -1 : cm->frame_refs[prime_idx].idx;
+      int8_t last_ref_deltas[TOTAL_REFS_PER_FRAME];
+      if (prime_idx == PRIMARY_REF_NONE || buf_idx < 0) {
+        av1_set_default_ref_deltas(last_ref_deltas);
+      } else {
+        memcpy(last_ref_deltas, cm->buffer_pool->frame_bufs[buf_idx].ref_deltas,
+               TOTAL_REFS_PER_FRAME);
+      }
       for (i = 0; i < TOTAL_REFS_PER_FRAME; i++) {
         const int delta = lf->ref_deltas[i];
-        const int changed = delta != lf->last_ref_deltas[i];
+        const int changed = delta != last_ref_deltas[i];
         aom_wb_write_bit(wb, changed);
-        if (changed) {
-          lf->last_ref_deltas[i] = delta;
-          aom_wb_write_inv_signed_literal(wb, delta, 6);
-        }
+        if (changed) aom_wb_write_inv_signed_literal(wb, delta, 6);
       }
 
+      int8_t last_mode_deltas[MAX_MODE_LF_DELTAS];
+      if (prime_idx == PRIMARY_REF_NONE || buf_idx < 0) {
+        av1_set_default_mode_deltas(last_mode_deltas);
+      } else {
+        memcpy(last_mode_deltas,
+               cm->buffer_pool->frame_bufs[buf_idx].mode_deltas,
+               MAX_MODE_LF_DELTAS);
+      }
       for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
         const int delta = lf->mode_deltas[i];
-        const int changed = delta != lf->last_mode_deltas[i];
+        const int changed = delta != last_mode_deltas[i];
         aom_wb_write_bit(wb, changed);
-        if (changed) {
-          lf->last_mode_deltas[i] = delta;
-          aom_wb_write_inv_signed_literal(wb, delta, 6);
-        }
+        if (changed) aom_wb_write_inv_signed_literal(wb, delta, 6);
       }
     }
   }
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 4b1e80c..29dba41 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4222,6 +4222,25 @@
   else
     cm->last_frame_seg_map = NULL;
   cm->current_frame_seg_map = cm->cur_frame->seg_map;
+  if ((cm->allow_intrabc && NO_FILTER_FOR_IBC) || cm->all_lossless) {
+    cm->lf.sharpness_level = -1;
+    av1_set_default_ref_deltas(cm->lf.ref_deltas);
+    av1_set_default_mode_deltas(cm->lf.mode_deltas);
+    cm->lf.mode_ref_delta_enabled = 1;
+    cm->lf.mode_ref_delta_update = 1;
+  } else if (cm->prev_frame) {
+    cm->lf.sharpness_level = cm->prev_frame->sharpness_level;
+    memcpy(cm->lf.ref_deltas, cm->prev_frame->ref_deltas, TOTAL_REFS_PER_FRAME);
+    memcpy(cm->lf.mode_deltas, cm->prev_frame->mode_deltas, MAX_MODE_LF_DELTAS);
+    cm->lf.mode_ref_delta_enabled = 1;
+    cm->lf.mode_ref_delta_update = 1;
+  } else {
+    cm->lf.mode_ref_delta_enabled = 0;
+    cm->lf.mode_ref_delta_update = 0;
+  }
+  cm->cur_frame->sharpness_level = cm->lf.sharpness_level;
+  memcpy(cm->cur_frame->ref_deltas, cm->lf.ref_deltas, TOTAL_REFS_PER_FRAME);
+  memcpy(cm->cur_frame->mode_deltas, cm->lf.mode_deltas, MAX_MODE_LF_DELTAS);
 
   // Special case: set prev_mi to NULL when the previous mode info
   // context cannot be used.
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 6cb6528..f0299c3 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -354,12 +354,6 @@
 
   cm->prev_frame = get_prev_frame(cm);
   cpi->vaq_refresh = 0;
-
-  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;
 }
 
 static void enc_setup_mi(AV1_COMMON *cm) {
@@ -549,9 +543,6 @@
   av1_copy(cc->nmv_costs, cpi->nmv_costs);
   av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
 
-  av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
-  av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
-
   cc->fc = *cm->fc;
 }
 
@@ -565,9 +556,6 @@
   av1_copy(cpi->nmv_costs, cc->nmv_costs);
   av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
 
-  av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
-  av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
-
   *cm->fc = cc->fc;
 }
 
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 4f488ad..e882826 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -51,11 +51,6 @@
   int nmv_costs[2][MV_VALS];
   int nmv_costs_hp[2][MV_VALS];
 
-  // 0 = Intra, Last, GF, ARF
-  int8_t last_ref_lf_deltas[TOTAL_REFS_PER_FRAME];
-  // 0 = ZERO_MV, MV
-  int8_t last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
-
   FRAME_CONTEXT fc;
 } CODING_CONTEXT;