]> granicus.if.org Git - libvpx/commitdiff
Restore the flexibility for the new 3 references
authorZoe Liu <zoeliu@google.com>
Thu, 3 Dec 2015 00:27:46 +0000 (16:27 -0800)
committerZoe Liu <zoeliu@google.com>
Fri, 18 Dec 2015 00:34:02 +0000 (16:34 -0800)
For the experiment of EXT_REFS, removed the previous special handling
on the new last 3 references, i.e. LAST2_FRAME, LAST3_FRAME, and
LAST4_FRAME, at the decoder, so that these new last references are
treated the same way as the other 3 references (LAST_FRAME,
GOLDEN_FRAME, and ALTREF_FRAME). Encoder changes have been made
accordingly to realize this flexibility.

Change-Id: Ic6546f9443b4377bb7e7b101bfa3e70a8b8d1c65

vp10/common/blockd.h
vp10/decoder/decodeframe.c
vp10/encoder/bitstream.c
vp10/encoder/denoiser.c
vp10/encoder/denoiser.h
vp10/encoder/encoder.c
vp10/encoder/encoder.h
vp10/encoder/firstpass.c
vp10/encoder/rdopt.c

index 5b8ed2a268fb66dc16ed5c0540ce20e7be1d9735..fc71387155f4f7bb67024fbc3e48279c2f5b2836 100644 (file)
@@ -72,11 +72,13 @@ typedef struct {
 #define GOLDEN_FRAME    5
 #define ALTREF_FRAME    6
 #define MAX_REF_FRAMES  7
+#define LAST_REF_FRAMES (LAST4_FRAME - LAST_FRAME + 1)
 #else
 #define GOLDEN_FRAME    2
 #define ALTREF_FRAME    3
 #define MAX_REF_FRAMES  4
 #endif  // CONFIG_EXT_REFS
+
 typedef int8_t MV_REFERENCE_FRAME;
 
 typedef struct {
index 7fed6d53cb3edaab19fb2c6d45b8ab644cf7f18d..c0325b73a7091087cca17994142d3e6c820b8e02 100644 (file)
@@ -2130,64 +2130,15 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
   // Generate next_ref_frame_map.
   lock_buffer_pool(pool);
   for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
-#if CONFIG_EXT_REFS
-// TODO(zoeliu): To move the following #define's to a header file
-#define PBI_LST_FB_IDX  0
-#define PBI_LST2_FB_IDX 1
-#define PBI_LST3_FB_IDX 2
-#define PBI_LST4_FB_IDX 3
-#define PBI_GLD_FB_IDX  4
-#define PBI_ALT_FB_IDX  5
-    // NOTE(zoeliu):
-    // (1) When ref_index == PBI_LST2_FB_IDX and the corresponding mask bit is
-    //     set, it indicates that LAST2_FRAME shall be refreshed, but keep in
-    //     mind that this has already been handled when LAST_FRAME is being
-    //     refreshed, i.e., when ref_index == PBI_LST_FB_IDX and the mask bit
-    //     is being set correspondingly;
-    // (2) The only exception is that when current frame is a KEY_FRAME, where
-    //     all the frames in the frame buffer shall get refreshed;
-    // (3) Similar handling for when ref_index == PBI_LST3_FB_IDX or when
-    //     ref_indx == PBI_LST4_FB_IDX.
-    if ((mask & 1) &&
-        (cm->frame_type == KEY_FRAME || (ref_index != PBI_LST2_FB_IDX &&
-                                         ref_index != PBI_LST3_FB_IDX &&
-                                         ref_index != PBI_LST4_FB_IDX))) {
-      // The reference frame map for the decoding of the next frame is updated
-      // and held by either current thread or possibly another decoder thread.
-      if (cm->frame_type != KEY_FRAME && ref_index == PBI_LST_FB_IDX &&
-          (mask & (1 << PBI_LST2_FB_IDX))) {
-        if (mask & (1 << PBI_LST3_FB_IDX)) {
-          if (mask & (1 << PBI_LST4_FB_IDX)) {
-            cm->next_ref_frame_map[PBI_LST4_FB_IDX] =
-                cm->next_ref_frame_map[PBI_LST3_FB_IDX];
-            ++frame_bufs[cm->next_ref_frame_map[PBI_LST3_FB_IDX]].ref_count;
-          }
-          cm->next_ref_frame_map[PBI_LST3_FB_IDX] =
-              cm->next_ref_frame_map[PBI_LST2_FB_IDX];
-          ++frame_bufs[cm->next_ref_frame_map[PBI_LST2_FB_IDX]].ref_count;
-        }
-        cm->next_ref_frame_map[PBI_LST2_FB_IDX] =
-            cm->next_ref_frame_map[PBI_LST_FB_IDX];
-        ++frame_bufs[cm->next_ref_frame_map[PBI_LST_FB_IDX]].ref_count;
-      }
-      cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
-      ++frame_bufs[cm->new_fb_idx].ref_count;
-    } else if (!(mask & 1)) {
-      cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
-    }
-#else
     if (mask & 1) {
       cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
       ++frame_bufs[cm->new_fb_idx].ref_count;
     } else {
       cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
     }
-#endif  // CONFIG_EXT_REFS
-
     // Current thread holds the reference frame.
     if (cm->ref_frame_map[ref_index] >= 0)
       ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
-
     ++ref_index;
   }
 
index 434cc99f78952553a9213a138887ad8dca4da0fc..e559da0853d49d246d5037e74c0084b3d95d8b0a 100644 (file)
@@ -1483,6 +1483,16 @@ static void write_tile_info(const VP10_COMMON *const cm,
 }
 
 static int get_refresh_mask(VP10_COMP *cpi) {
+#if CONFIG_EXT_REFS
+  int refresh_mask = 0;
+  int ref_frame;
+
+  for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame) {
+    refresh_mask |= (cpi->refresh_last_frames[ref_frame - LAST_FRAME] <<
+                     cpi->lst_fb_idxes[ref_frame - LAST_FRAME]);
+  }
+#endif  // CONFIG_EXT_REFS
+
   if (vp10_preserve_existing_gf(cpi)) {
     // We have decided to preserve the previously existing golden frame as our
     // new ARF frame. However, in the short term we leave it in the GF slot and,
@@ -1494,11 +1504,10 @@ static int get_refresh_mask(VP10_COMP *cpi) {
     // Note: This is highly specific to the use of ARF as a forward reference,
     // and this needs to be generalized as other uses are implemented
     // (like RTC/temporal scalability).
-    return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
 #if CONFIG_EXT_REFS
-           (cpi->refresh_last2_frame << cpi->lst2_fb_idx) |
-           (cpi->refresh_last3_frame << cpi->lst3_fb_idx) |
-           (cpi->refresh_last4_frame << cpi->lst4_fb_idx) |
+    return refresh_mask |
+#else
+    return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
 #endif  // CONFIG_EXT_REFS
            (cpi->refresh_golden_frame << cpi->alt_fb_idx);
   } else {
@@ -1507,11 +1516,10 @@ static int get_refresh_mask(VP10_COMP *cpi) {
       const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
       arf_idx = gf_group->arf_update_idx[gf_group->index];
     }
-    return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
 #if CONFIG_EXT_REFS
-           (cpi->refresh_last2_frame << cpi->lst2_fb_idx) |
-           (cpi->refresh_last3_frame << cpi->lst3_fb_idx) |
-           (cpi->refresh_last4_frame << cpi->lst4_fb_idx) |
+    return refresh_mask |
+#else
+    return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
 #endif  // CONFIG_EXT_REFS
            (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
            (cpi->refresh_alt_ref_frame << arf_idx);
@@ -1683,13 +1691,6 @@ static void write_uncompressed_header(VP10_COMP *cpi,
   vpx_wb_write_bit(wb, cm->show_frame);
   vpx_wb_write_bit(wb, cm->error_resilient_mode);
 
-#if CONFIG_EXT_REFS
-  cpi->refresh_last2_frame =
-      (cm->frame_type == KEY_FRAME || cpi->refresh_last_frame) ? 1 : 0;
-  cpi->refresh_last3_frame = cpi->refresh_last2_frame ? 1 : 0;
-  cpi->refresh_last4_frame = cpi->refresh_last3_frame ? 1 : 0;
-#endif  // CONFIG_EXT_REFS
-
   if (cm->frame_type == KEY_FRAME) {
     write_sync_code(wb);
     write_bitdepth_colorspace_sampling(cm, wb);
index c4955fe9f88c8a8a771b61f3f3f4a8cef23dfc11..43647b0f4d530e23bd6980c08d4f8219063ce762 100644 (file)
@@ -377,9 +377,17 @@ static void swap_frame_buffer(YV12_BUFFER_CONFIG *dest,
 void vp10_denoiser_update_frame_info(VP9_DENOISER *denoiser,
                                     YV12_BUFFER_CONFIG src,
                                     FRAME_TYPE frame_type,
+#if CONFIG_EXT_REFS
+                                    int refresh_last_frames[LAST_REF_FRAMES],
+#else
+                                    int refresh_last_frame,
+#endif  // CONFIG_EXT_REFS
                                     int refresh_alt_ref_frame,
-                                    int refresh_golden_frame,
-                                    int refresh_last_frame) {
+                                    int refresh_golden_frame) {
+#if CONFIG_EXT_REFS
+  int ref_frame;
+#endif  // CONFIG_EXT_REFS
+
   if (frame_type == KEY_FRAME) {
     int i;
     // Start at 1 so as not to overwrite the INTRA_FRAME
@@ -397,18 +405,19 @@ void vp10_denoiser_update_frame_info(VP9_DENOISER *denoiser,
     swap_frame_buffer(&denoiser->running_avg_y[GOLDEN_FRAME],
                       &denoiser->running_avg_y[INTRA_FRAME]);
   }
-  if (refresh_last_frame) {
 #if CONFIG_EXT_REFS
-    swap_frame_buffer(&denoiser->running_avg_y[LAST4_FRAME],
-                      &denoiser->running_avg_y[LAST3_FRAME]);
-    swap_frame_buffer(&denoiser->running_avg_y[LAST3_FRAME],
-                      &denoiser->running_avg_y[LAST2_FRAME]);
-    swap_frame_buffer(&denoiser->running_avg_y[LAST2_FRAME],
-                      &denoiser->running_avg_y[LAST_FRAME]);
-#endif  // CONFIG_EXT_REFS
+  for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame) {
+    if (refresh_last_frames[ref_frame - LAST_FRAME]) {
+      swap_frame_buffer(&denoiser->running_avg_y[ref_frame],
+                        &denoiser->running_avg_y[INTRA_FRAME]);
+    }
+  }
+#else
+  if (refresh_last_frame) {
     swap_frame_buffer(&denoiser->running_avg_y[LAST_FRAME],
                       &denoiser->running_avg_y[INTRA_FRAME]);
   }
+#endif  // CONFIG_EXT_REFS
 }
 
 void vp10_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx) {
index e543fb05fa06d9966a9b57303026a1018a43dce2..f48cbb0d05b68446413cae9e533e6d67ff0cefc0 100644 (file)
@@ -35,9 +35,13 @@ typedef struct vp10_denoiser {
 void vp10_denoiser_update_frame_info(VP9_DENOISER *denoiser,
                                     YV12_BUFFER_CONFIG src,
                                     FRAME_TYPE frame_type,
+#if CONFIG_EXT_REFS
+                                    int refresh_last_frames[LAST_REF_FRAMES],
+#else
+                                    int refresh_last_frame,
+#endif  // CONFIG_EXT_REFS
                                     int refresh_alt_ref_frame,
-                                    int refresh_golden_frame,
-                                    int refresh_last_frame);
+                                    int refresh_golden_frame);
 
 void vp10_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
                           int mi_row, int mi_col, BLOCK_SIZE bs,
index b42e3d6b0c90ded0c69139e8558cb99f4589e09f..704217467ee05019df05171bc8b71e8a7cc749c2 100644 (file)
@@ -717,14 +717,14 @@ static void update_frame_size(VP10_COMP *cpi) {
 }
 
 static void init_buffer_indices(VP10_COMP *cpi) {
-  cpi->lst_fb_idx = 0;
 #if CONFIG_EXT_REFS
-  cpi->lst2_fb_idx = 1;
-  cpi->lst3_fb_idx = 2;
-  cpi->lst4_fb_idx = 3;
-  cpi->gld_fb_idx = 4;
-  cpi->alt_fb_idx = 5;
+  int fb_idx;
+  for (fb_idx = 0; fb_idx < LAST_REF_FRAMES; ++fb_idx)
+    cpi->lst_fb_idxes[fb_idx] = fb_idx;
+  cpi->gld_fb_idx = LAST_REF_FRAMES;
+  cpi->alt_fb_idx = cpi->gld_fb_idx + 1;
 #else
+  cpi->lst_fb_idx = 0;
   cpi->gld_fb_idx = 1;
   cpi->alt_fb_idx = 2;
 #endif  // CONFIG_EXT_REFS
@@ -752,6 +752,10 @@ static void init_config(struct VP10_COMP *cpi, VP10EncoderConfig *oxcf) {
   cpi->td.counts = &cm->counts;
 
   // change includes all joint functionality
+#if CONFIG_EXT_REFS
+  cpi->last_ref_to_refresh = LAST_FRAME;
+#endif  // CONFIG_EXT_REFS
+
   vp10_change_config(cpi, oxcf);
 
   cpi->static_mb_pct = 0;
@@ -1409,6 +1413,9 @@ static void realloc_segmentation_maps(VP10_COMP *cpi) {
 void vp10_change_config(struct VP10_COMP *cpi, const VP10EncoderConfig *oxcf) {
   VP10_COMMON *const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
+#if CONFIG_EXT_REFS
+  int ref_frame;
+#endif  // CONFIG_EXT_REFS
 
   if (cm->profile != oxcf->profile)
     cm->profile = oxcf->profile;
@@ -1433,11 +1440,16 @@ void vp10_change_config(struct VP10_COMP *cpi, const VP10EncoderConfig *oxcf) {
   }
 
   cpi->refresh_golden_frame = 0;
-  cpi->refresh_last_frame = 1;
+
 #if CONFIG_EXT_REFS
-  cpi->refresh_last2_frame = 0;
-  cpi->refresh_last3_frame = 0;
-  cpi->refresh_last4_frame = 0;
+  for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame) {
+    if (ref_frame == cpi->last_ref_to_refresh)
+      cpi->refresh_last_frames[ref_frame - LAST_FRAME] = 1;
+    else
+      cpi->refresh_last_frames[ref_frame - LAST_FRAME] = 0;
+  }
+#else
+  cpi->refresh_last_frame = 1;
 #endif  // CONFIG_EXT_REFS
 
   cm->refresh_frame_context =
@@ -2307,11 +2319,13 @@ int vp10_use_as_reference(VP10_COMP *cpi, int ref_frame_flags) {
 void vp10_update_reference(VP10_COMP *cpi, int ref_frame_flags) {
   cpi->ext_refresh_golden_frame = (ref_frame_flags & VP9_GOLD_FLAG) != 0;
   cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & VP9_ALT_FLAG) != 0;
-  cpi->ext_refresh_last_frame = (ref_frame_flags & VP9_LAST_FLAG) != 0;
 #if CONFIG_EXT_REFS
-  cpi->ext_refresh_last2_frame = (ref_frame_flags & VP9_LAST2_FLAG) != 0;
-  cpi->ext_refresh_last3_frame = (ref_frame_flags & VP9_LAST3_FLAG) != 0;
-  cpi->ext_refresh_last4_frame = (ref_frame_flags & VP9_LAST4_FLAG) != 0;
+  cpi->ext_refresh_last_frames[0] = (ref_frame_flags & VP9_LAST_FLAG) != 0;
+  cpi->ext_refresh_last_frames[1] = (ref_frame_flags & VP9_LAST2_FLAG) != 0;
+  cpi->ext_refresh_last_frames[2] = (ref_frame_flags & VP9_LAST3_FLAG) != 0;
+  cpi->ext_refresh_last_frames[3] = (ref_frame_flags & VP9_LAST4_FLAG) != 0;
+#else
+  cpi->ext_refresh_last_frame = (ref_frame_flags & VP9_LAST_FLAG) != 0;
 #endif  // CONFIG_EXT_REFS
   cpi->ext_refresh_frame_flags_pending = 1;
 }
@@ -2610,6 +2624,9 @@ static int recode_loop_test(VP10_COMP *cpi,
 void vp10_update_reference_frames(VP10_COMP *cpi) {
   VP10_COMMON * const cm = &cpi->common;
   BufferPool *const pool = cm->buffer_pool;
+#if CONFIG_EXT_REFS
+  int ref_frame;
+#endif  // CONFIG_EXT_REFS
 
   // At this point the new frame has been encoded.
   // If any buffer copy / swapping is signaled it should be done here.
@@ -2664,92 +2681,49 @@ void vp10_update_reference_frames(VP10_COMP *cpi) {
     }
   }
 
-  if (cpi->refresh_last_frame) {
 #if CONFIG_EXT_REFS
-    if (cpi->refresh_last2_frame) {
-      if (cpi->refresh_last3_frame) {
-        if (cpi->refresh_last4_frame) {
-          if (cm->frame_type == KEY_FRAME)
-            ref_cnt_fb(pool->frame_bufs,
-                       &cm->ref_frame_map[cpi->lst4_fb_idx],
-                       cm->new_fb_idx);
-          else
-            ref_cnt_fb(pool->frame_bufs,
-                       &cm->ref_frame_map[cpi->lst4_fb_idx],
-                       cm->ref_frame_map[cpi->lst3_fb_idx]);
-        }
-
-        if (cm->frame_type == KEY_FRAME)
-          ref_cnt_fb(pool->frame_bufs,
-                     &cm->ref_frame_map[cpi->lst3_fb_idx],
-                     cm->new_fb_idx);
-        else
-          ref_cnt_fb(pool->frame_bufs,
-                     &cm->ref_frame_map[cpi->lst3_fb_idx],
-                     cm->ref_frame_map[cpi->lst2_fb_idx]);
+  for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame) {
+    const int ref_idx = ref_frame - LAST_FRAME;
+    if (cpi->refresh_last_frames[ref_idx]) {
+      ref_cnt_fb(pool->frame_bufs,
+                 &cm->ref_frame_map[cpi->lst_fb_idxes[ref_idx]],
+                 cm->new_fb_idx);
+      if (!cpi->rc.is_src_frame_alt_ref) {
+        memcpy(cpi->interp_filter_selected[ref_frame],
+               cpi->interp_filter_selected[0],
+               sizeof(cpi->interp_filter_selected[0]));
       }
-
-      if (cm->frame_type == KEY_FRAME)
-        ref_cnt_fb(pool->frame_bufs,
-                   &cm->ref_frame_map[cpi->lst2_fb_idx],
-                   cm->new_fb_idx);
-      else
-        ref_cnt_fb(pool->frame_bufs,
-                   &cm->ref_frame_map[cpi->lst2_fb_idx],
-                   cm->ref_frame_map[cpi->lst_fb_idx]);
     }
-#endif  // CONFIG_EXT_REFS
+  }
+  // NOTE: The order for the refreshing of the 4 last reference frames are:
+  // LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME -> LAST4_FRAME -> LAST_FRAME
+  cpi->last_ref_to_refresh += 1;
+  if (cpi->last_ref_to_refresh == LAST4_FRAME)
+    cpi->last_ref_to_refresh = LAST_FRAME;
+#else
+  if (cpi->refresh_last_frame) {
     ref_cnt_fb(pool->frame_bufs,
                &cm->ref_frame_map[cpi->lst_fb_idx], cm->new_fb_idx);
-
     if (!cpi->rc.is_src_frame_alt_ref) {
-#if CONFIG_EXT_REFS
-      if (cpi->refresh_last2_frame) {
-        if (cpi->refresh_last3_frame) {
-          if (cpi->refresh_last4_frame) {
-            if (cm->frame_type == KEY_FRAME)
-              memcpy(cpi->interp_filter_selected[LAST4_FRAME],
-                     cpi->interp_filter_selected[0],
-                     sizeof(cpi->interp_filter_selected[0]));
-            else
-              memcpy(cpi->interp_filter_selected[LAST4_FRAME],
-                     cpi->interp_filter_selected[LAST3_FRAME],
-                     sizeof(cpi->interp_filter_selected[LAST3_FRAME]));
-          }
-
-          if (cm->frame_type == KEY_FRAME)
-            memcpy(cpi->interp_filter_selected[LAST3_FRAME],
-                   cpi->interp_filter_selected[0],
-                   sizeof(cpi->interp_filter_selected[0]));
-          else
-            memcpy(cpi->interp_filter_selected[LAST3_FRAME],
-                   cpi->interp_filter_selected[LAST2_FRAME],
-                   sizeof(cpi->interp_filter_selected[LAST2_FRAME]));
-        }
-
-        if (cm->frame_type == KEY_FRAME)
-          memcpy(cpi->interp_filter_selected[LAST2_FRAME],
-                 cpi->interp_filter_selected[0],
-                 sizeof(cpi->interp_filter_selected[0]));
-        else
-          memcpy(cpi->interp_filter_selected[LAST2_FRAME],
-                 cpi->interp_filter_selected[LAST_FRAME],
-                 sizeof(cpi->interp_filter_selected[LAST_FRAME]));
-      }
-#endif  // CONFIG_EXT_REFS
       memcpy(cpi->interp_filter_selected[LAST_FRAME],
              cpi->interp_filter_selected[0],
              sizeof(cpi->interp_filter_selected[0]));
     }
   }
+#endif  // CONFIG_EXT_REFS
+
 #if CONFIG_VP9_TEMPORAL_DENOISING
   if (cpi->oxcf.noise_sensitivity > 0) {
     vp10_denoiser_update_frame_info(&cpi->denoiser,
                                    *cpi->Source,
                                    cpi->common.frame_type,
+#if CONFIG_EXT_REFS
+                                   cpi->refresh_last_frames,
+#else
+                                   cpi->refresh_last_frame,
+#endif  // CONFIG_EXT_REFS
                                    cpi->refresh_alt_ref_frame,
-                                   cpi->refresh_golden_frame,
-                                   cpi->refresh_last_frame);
+                                   cpi->refresh_golden_frame);
   }
 #endif
 }
@@ -2902,14 +2876,14 @@ static void release_scaled_references(VP10_COMP *cpi) {
     // Only release scaled references under certain conditions:
     // if reference will be updated, or if scaled reference has same resolution.
     int refresh[REFS_PER_FRAME];
-    refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
 #if CONFIG_EXT_REFS
-    refresh[1] = (cpi->refresh_last2_frame) ? 1 : 0;
-    refresh[2] = (cpi->refresh_last3_frame) ? 1 : 0;
-    refresh[3] = (cpi->refresh_last4_frame) ? 1 : 0;
+    for (i = LAST_FRAME; i <= LAST4_FRAME; ++i)
+      refresh[i - LAST_FRAME] =
+          (cpi->refresh_last_frames[i - LAST_FRAME]) ? 1 : 0;
     refresh[4] = (cpi->refresh_golden_frame) ? 1 : 0;
     refresh[5] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
 #else
+    refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
     refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
     refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
 #endif  // CONFIG_EXT_REFS
@@ -3545,26 +3519,36 @@ static void encode_with_recode_loop(VP10_COMP *cpi,
 
 static int get_ref_frame_flags(const VP10_COMP *cpi) {
   const int *const map = cpi->common.ref_frame_map;
-  const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
-  const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
-  const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
 
 #if CONFIG_EXT_REFS
-  const int last2_is_last = map[cpi->lst2_fb_idx] == map[cpi->lst_fb_idx];
-  const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst2_fb_idx];
-  const int alt_is_last2 = map[cpi->alt_fb_idx] == map[cpi->lst2_fb_idx];
-
-  const int last3_is_last = map[cpi->lst3_fb_idx] == map[cpi->lst_fb_idx];
-  const int last3_is_last2 = map[cpi->lst3_fb_idx] == map[cpi->lst2_fb_idx];
-  const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst3_fb_idx];
-  const int alt_is_last3 = map[cpi->alt_fb_idx] == map[cpi->lst3_fb_idx];
-
-  const int last4_is_last = map[cpi->lst4_fb_idx] == map[cpi->lst_fb_idx];
-  const int last4_is_last2 = map[cpi->lst4_fb_idx] == map[cpi->lst2_fb_idx];
-  const int last4_is_last3 = map[cpi->lst4_fb_idx] == map[cpi->lst3_fb_idx];
-  const int gld_is_last4 = map[cpi->gld_fb_idx] == map[cpi->lst4_fb_idx];
-  const int alt_is_last4 = map[cpi->alt_fb_idx] == map[cpi->lst4_fb_idx];
+  const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[0]];
+  const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[0]];
+
+  const int last2_is_last =
+      map[cpi->lst_fb_idxes[1]] == map[cpi->lst_fb_idxes[0]];
+  const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[1]];
+  const int alt_is_last2 = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[1]];
+
+  const int last3_is_last =
+      map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[0]];
+  const int last3_is_last2 =
+      map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[1]];
+  const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[2]];
+  const int alt_is_last3 = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[2]];
+
+  const int last4_is_last =
+      map[cpi->lst_fb_idxes[3]] == map[cpi->lst_fb_idxes[0]];
+  const int last4_is_last2 =
+      map[cpi->lst_fb_idxes[3]] == map[cpi->lst_fb_idxes[1]];
+  const int last4_is_last3 =
+      map[cpi->lst_fb_idxes[3]] == map[cpi->lst_fb_idxes[2]];
+  const int gld_is_last4 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[3]];
+  const int alt_is_last4 = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[3]];
+#else
+  const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
+  const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
 #endif  // CONFIG_EXT_REFS
+  const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
 
   int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
 #if CONFIG_EXT_REFS
@@ -3573,7 +3557,7 @@ static int get_ref_frame_flags(const VP10_COMP *cpi) {
   flags |= VP9_LAST4_FLAG;
 #endif  // CONFIG_EXT_REFS
 
-  if (gold_is_last)
+  if (gld_is_last)
     flags &= ~VP9_GOLD_FLAG;
 
   if (cpi->rc.frames_till_gf_update_due == INT_MAX)
@@ -3582,35 +3566,23 @@ static int get_ref_frame_flags(const VP10_COMP *cpi) {
   if (alt_is_last)
     flags &= ~VP9_ALT_FLAG;
 
-  if (gold_is_alt)
+  if (gld_is_alt)
     flags &= ~VP9_ALT_FLAG;
 
 #if CONFIG_EXT_REFS
   if (last4_is_last || last4_is_last2 || last4_is_last3)
     flags &= ~VP9_LAST4_FLAG;
 
-  if (gld_is_last4)
-    flags &= ~VP9_GOLD_FLAG;
-
-  if (alt_is_last4)
-    flags &= ~VP9_ALT_FLAG;
-
   if (last3_is_last || last3_is_last2)
     flags &= ~VP9_LAST3_FLAG;
 
-  if (gld_is_last3)
-    flags &= ~VP9_GOLD_FLAG;
-
-  if (alt_is_last3)
-    flags &= ~VP9_ALT_FLAG;
-
   if (last2_is_last)
     flags &= ~VP9_LAST2_FLAG;
 
-  if (gld_is_last2)
+  if (gld_is_last4 || gld_is_last3 || gld_is_last2)
     flags &= ~VP9_GOLD_FLAG;
 
-  if (alt_is_last2)
+  if (alt_is_last4 || alt_is_last3 || alt_is_last2)
     flags &= ~VP9_ALT_FLAG;
 #endif  // CONFIG_EXT_REFS
 
@@ -3627,11 +3599,14 @@ static void set_ext_overrides(VP10_COMP *cpi) {
     cpi->ext_refresh_frame_context_pending = 0;
   }
   if (cpi->ext_refresh_frame_flags_pending) {
-    cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
 #if CONFIG_EXT_REFS
-    cpi->refresh_last2_frame = cpi->ext_refresh_last2_frame;
-    cpi->refresh_last3_frame = cpi->ext_refresh_last3_frame;
-    cpi->refresh_last4_frame = cpi->ext_refresh_last4_frame;
+    int ref_frame;
+    for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame) {
+      cpi->refresh_last_frames[ref_frame - LAST_FRAME] =
+          cpi->ext_refresh_last_frames[ref_frame - LAST_FRAME];
+    }
+#else
+    cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
 #endif  // CONFIG_EXT_REFS
     cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
     cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
@@ -3828,8 +3803,16 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi,
   }
 
   // If the encoder forced a KEY_FRAME decision
-  if (cm->frame_type == KEY_FRAME)
+  if (cm->frame_type == KEY_FRAME) {
+#if CONFIG_EXT_REFS
+    int ref_frame;
+    for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame)
+      cpi->refresh_last_frames[ref_frame - LAST_FRAME] = 1;
+    cpi->last_ref_to_refresh = LAST_FRAME;
+#else
     cpi->refresh_last_frame = 1;
+#endif  // CONFIG_EXT_REFS
+  }
 
   cm->frame_to_show = get_frame_new_buffer(cm);
   cm->frame_to_show->color_space = cm->color_space;
@@ -4045,11 +4028,13 @@ static int frame_is_reference(const VP10_COMP *cpi) {
   const VP10_COMMON *cm = &cpi->common;
 
   return cm->frame_type == KEY_FRAME ||
-         cpi->refresh_last_frame ||
 #if CONFIG_EXT_REFS
-         cpi->refresh_last2_frame ||
-         cpi->refresh_last3_frame ||
-         cpi->refresh_last4_frame ||
+         cpi->refresh_last_frames[LAST_FRAME - LAST_FRAME] ||
+         cpi->refresh_last_frames[LAST2_FRAME - LAST_FRAME] ||
+         cpi->refresh_last_frames[LAST3_FRAME - LAST_FRAME] ||
+         cpi->refresh_last_frames[LAST4_FRAME - LAST_FRAME] ||
+#else
+         cpi->refresh_last_frame ||
 #endif  // CONFIG_EXT_REFS
          cpi->refresh_golden_frame ||
          cpi->refresh_alt_ref_frame ||
@@ -4130,12 +4115,21 @@ static void check_src_altref(VP10_COMP *cpi,
   }
 
   if (rc->is_src_frame_alt_ref) {
+#if CONFIG_EXT_REFS
+    int ref_frame;
+#endif  // CONFIG_EXT_REFS
+
     // Current frame is an ARF overlay frame.
     cpi->alt_ref_source = NULL;
 
     // Don't refresh the last buffer for an ARF overlay frame. It will
     // become the GF so preserve last as an alternative prediction option.
+#if CONFIG_EXT_REFS
+    for (ref_frame = LAST_FRAME; ref_frame <= LAST4_FRAME; ++ref_frame)
+      cpi->refresh_last_frames[ref_frame - LAST_FRAME] = 0;
+#else
     cpi->refresh_last_frame = 0;
+#endif  // CONFIG_EXT_REFS
   }
 }
 
@@ -4186,11 +4180,15 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
           oxcf->frame_parallel_decoding_mode ? REFRESH_FRAME_CONTEXT_FORWARD
                                              : REFRESH_FRAME_CONTEXT_BACKWARD;
 
-  cpi->refresh_last_frame = 1;
 #if CONFIG_EXT_REFS
-  cpi->refresh_last2_frame = 0;
-  cpi->refresh_last3_frame = 0;
-  cpi->refresh_last4_frame = 0;
+  for (i = LAST_FRAME; i <= LAST4_FRAME; ++i) {
+    if (i == cpi->last_ref_to_refresh)
+      cpi->refresh_last_frames[i - LAST_FRAME] = 1;
+    else
+      cpi->refresh_last_frames[i - LAST_FRAME] = 0;
+  }
+#else
+  cpi->refresh_last_frame = 1;
 #endif  // CONFIG_EXT_REFS
   cpi->refresh_golden_frame = 0;
   cpi->refresh_alt_ref_frame = 0;
@@ -4215,17 +4213,15 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
       cm->intra_only = 0;
       cpi->refresh_alt_ref_frame = 1;
       cpi->refresh_golden_frame = 0;
-      cpi->refresh_last_frame = 0;
 #if CONFIG_EXT_REFS
-      cpi->refresh_last2_frame = 0;
-      cpi->refresh_last3_frame = 0;
-      cpi->refresh_last4_frame = 0;
+      for (i = LAST_FRAME; i <= LAST4_FRAME; ++i)
+        cpi->refresh_last_frames[i - LAST_FRAME] = 0;
+#else
+      cpi->refresh_last_frame = 0;
 #endif  // CONFIG_EXT_REFS
       rc->is_src_frame_alt_ref = 0;
-      rc->source_alt_ref_pending = 0;
-    } else {
-      rc->source_alt_ref_pending = 0;
     }
+    rc->source_alt_ref_pending = 0;
   }
 
   if (!source) {
index c45be4ce0f21d27bd65592273a1c038d49fbfae0..dc7374b1e472737fc0b05f629eca78bc9c17ce00 100644 (file)
@@ -304,31 +304,32 @@ typedef struct VP10_COMP {
   // For a still frame, this flag is set to 1 to skip partition search.
   int partition_search_skippable_frame;
 
+#if CONFIG_EXT_REFS
+  int last_ref_to_refresh;
+#endif  // CONFIG_EXT_REFS
+
   int scaled_ref_idx[MAX_REF_FRAMES];
-  int lst_fb_idx;
 #if CONFIG_EXT_REFS
-  int lst2_fb_idx;
-  int lst3_fb_idx;
-  int lst4_fb_idx;
+  int lst_fb_idxes[LAST_REF_FRAMES];
+#else
+  int lst_fb_idx;
 #endif  // CONFIG_EXT_REFS
   int gld_fb_idx;
   int alt_fb_idx;
 
-  int refresh_last_frame;
 #if CONFIG_EXT_REFS
-  int refresh_last2_frame;
-  int refresh_last3_frame;
-  int refresh_last4_frame;
+  int refresh_last_frames[LAST_REF_FRAMES];
+#else
+  int refresh_last_frame;
 #endif  // CONFIG_EXT_REFS
   int refresh_golden_frame;
   int refresh_alt_ref_frame;
 
   int ext_refresh_frame_flags_pending;
-  int ext_refresh_last_frame;
 #if CONFIG_EXT_REFS
-  int ext_refresh_last2_frame;
-  int ext_refresh_last3_frame;
-  int ext_refresh_last4_frame;
+  int ext_refresh_last_frames[LAST_REF_FRAMES];
+#else
+  int ext_refresh_last_frame;
 #endif  // CONFIG_EXT_REFS
   int ext_refresh_golden_frame;
   int ext_refresh_alt_ref_frame;
@@ -575,21 +576,17 @@ static INLINE int frame_is_kf_gf_arf(const VP10_COMP *cpi) {
 
 static INLINE int get_ref_frame_map_idx(const VP10_COMP *cpi,
                                         MV_REFERENCE_FRAME ref_frame) {
-  if (ref_frame == LAST_FRAME) {
-    return cpi->lst_fb_idx;
 #if CONFIG_EXT_REFS
-  } else if (ref_frame == LAST2_FRAME) {
-    return cpi->lst2_fb_idx;
-  } else if (ref_frame == LAST3_FRAME) {
-    return cpi->lst3_fb_idx;
-  } else if (ref_frame == LAST4_FRAME) {
-    return cpi->lst4_fb_idx;
+  if (ref_frame >= LAST_FRAME && ref_frame <= LAST4_FRAME)
+    return cpi->lst_fb_idxes[ref_frame - 1];
+#else
+  if (ref_frame == LAST_FRAME)
+    return cpi->lst_fb_idx;
 #endif  // CONFIG_EXT_REFS
-  } else if (ref_frame == GOLDEN_FRAME) {
+  else if (ref_frame == GOLDEN_FRAME)
     return cpi->gld_fb_idx;
-  } else {
+  else
     return cpi->alt_fb_idx;
-  }
 }
 
 static INLINE int get_ref_frame_buf_idx(const VP10_COMP *const cpi,
index c41fa3e3993e3eb3a064abdf4dd9cb6a06c18776..c865408d78151e58fa1f1aa0bbab8271765e1982 100644 (file)
@@ -1044,8 +1044,13 @@ void vp10_first_pass(VP10_COMP *cpi, const struct lookahead_entry *source) {
        ((twopass->this_frame_stats.intra_error /
          DOUBLE_DIVIDE_CHECK(twopass->this_frame_stats.coded_error)) > 2.0))) {
     if (gld_yv12 != NULL) {
+#if CONFIG_EXT_REFS
+      ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
+                 cm->ref_frame_map[cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]]);
+#else
       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
                  cm->ref_frame_map[cpi->lst_fb_idx]);
+#endif  // CONFIG_EXT_REFS
     }
     twopass->sr_update_lag = 1;
   } else {
@@ -1055,14 +1060,25 @@ void vp10_first_pass(VP10_COMP *cpi, const struct lookahead_entry *source) {
   vpx_extend_frame_borders(new_yv12);
 
   // The frame we just compressed now becomes the last frame.
+#if CONFIG_EXT_REFS
+  ref_cnt_fb(pool->frame_bufs,
+             &cm->ref_frame_map[cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]],
+             cm->new_fb_idx);
+#else
   ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
              cm->new_fb_idx);
+#endif  // CONFIG_EXT_REFS
 
   // Special case for the first frame. Copy into the GF buffer as a second
   // reference.
   if (cm->current_video_frame == 0 && cpi->gld_fb_idx != INVALID_IDX) {
+#if CONFIG_EXT_REFS
+    ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
+               cm->ref_frame_map[cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]]);
+#else
     ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
                cm->ref_frame_map[cpi->lst_fb_idx]);
+#endif  // CONFIG_EXT_REFS
   }
 
   // Use this to see what the first pass reconstruction looks like.
@@ -2382,28 +2398,48 @@ static void configure_buffer_updates(VP10_COMP *cpi) {
   cpi->rc.is_src_frame_alt_ref = 0;
   switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
     case KF_UPDATE:
+#if CONFIG_EXT_REFS
+      cpi->refresh_last_frames[LAST_FRAME - LAST_FRAME] = 1;
+#else
       cpi->refresh_last_frame = 1;
+#endif  // CONFIG_EXT_REFS
       cpi->refresh_golden_frame = 1;
       cpi->refresh_alt_ref_frame = 1;
       break;
     case LF_UPDATE:
+#if CONFIG_EXT_REFS
+      cpi->refresh_last_frames[LAST_FRAME - LAST_FRAME] = 1;
+#else
       cpi->refresh_last_frame = 1;
+#endif  // CONFIG_EXT_REFS
       cpi->refresh_golden_frame = 0;
       cpi->refresh_alt_ref_frame = 0;
       break;
     case GF_UPDATE:
+#if CONFIG_EXT_REFS
+      cpi->refresh_last_frames[LAST_FRAME - LAST_FRAME] = 1;
+#else
       cpi->refresh_last_frame = 1;
+#endif  // CONFIG_EXT_REFS
       cpi->refresh_golden_frame = 1;
       cpi->refresh_alt_ref_frame = 0;
       break;
     case OVERLAY_UPDATE:
+#if CONFIG_EXT_REFS
+      cpi->refresh_last_frames[LAST_FRAME - LAST_FRAME] = 0;
+#else
       cpi->refresh_last_frame = 0;
+#endif  // CONFIG_EXT_REFS
       cpi->refresh_golden_frame = 1;
       cpi->refresh_alt_ref_frame = 0;
       cpi->rc.is_src_frame_alt_ref = 1;
       break;
     case ARF_UPDATE:
+#if CONFIG_EXT_REFS
+      cpi->refresh_last_frames[LAST_FRAME - LAST_FRAME] = 0;
+#else
       cpi->refresh_last_frame = 0;
+#endif  // CONFIG_EXT_REFS
       cpi->refresh_golden_frame = 0;
       cpi->refresh_alt_ref_frame = 1;
       break;
index c65021b4b761070f021155d616eac3f533cca0e9..4e3bf053c2e8eafe7853be8de5a364a5aac498b7 100644 (file)
@@ -5126,20 +5126,6 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
     if (mode_skip_mask[ref_frame] & (1 << this_mode))
       continue;
 
-#if CONFIG_EXT_REFS
-    if (cm->last_frame_type == KEY_FRAME && ref_frame == LAST2_FRAME)
-      continue;
-
-    if ((cm->last2_frame_type == KEY_FRAME ||
-         cm->last_frame_type == KEY_FRAME) && ref_frame == LAST3_FRAME)
-      continue;
-
-    if ((cm->last3_frame_type == KEY_FRAME ||
-         cm->last2_frame_type == KEY_FRAME ||
-         cm->last_frame_type == KEY_FRAME) && ref_frame == LAST4_FRAME)
-      continue;
-#endif  // CONFIG_EXT_REFS
-
     // Test best rd so far against threshold for trying this mode.
     if (best_mode_skippable && sf->schedule_mode_search)
       mode_threshold[mode_index] <<= 1;
@@ -5889,20 +5875,6 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
     ref_frame = vp10_ref_order[ref_index].ref_frame[0];
     second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
 
-#if CONFIG_EXT_REFS
-    if (cm->last_frame_type == KEY_FRAME && ref_frame == LAST2_FRAME)
-      continue;
-
-    if ((cm->last2_frame_type == KEY_FRAME ||
-         cm->last_frame_type == KEY_FRAME) && ref_frame == LAST3_FRAME)
-      continue;
-
-    if ((cm->last3_frame_type == KEY_FRAME ||
-         cm->last2_frame_type == KEY_FRAME ||
-         cm->last_frame_type == KEY_FRAME) && ref_frame == LAST4_FRAME)
-      continue;
-#endif  // CONFIG_EXT_REFS
-
     // Look at the reference frame of the best mode so far and set the
     // skip mask to look at a subset of the remaining modes.
     if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {