Restore the flexibility for the new 3 references
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
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h
index 5b8ed2a..fc71387 100644
--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -72,11 +72,13 @@
#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 {
diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c
index 7fed6d5..c0325b7 100644
--- a/vp10/decoder/decodeframe.c
+++ b/vp10/decoder/decodeframe.c
@@ -2130,64 +2130,15 @@
// 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;
}
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index 434cc99..e559da0 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -1483,6 +1483,16 @@
}
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 @@
// 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 @@
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 @@
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);
diff --git a/vp10/encoder/denoiser.c b/vp10/encoder/denoiser.c
index c4955fe..43647b0 100644
--- a/vp10/encoder/denoiser.c
+++ b/vp10/encoder/denoiser.c
@@ -377,9 +377,17 @@
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 @@
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) {
diff --git a/vp10/encoder/denoiser.h b/vp10/encoder/denoiser.h
index e543fb0..f48cbb0 100644
--- a/vp10/encoder/denoiser.h
+++ b/vp10/encoder/denoiser.h
@@ -35,9 +35,13 @@
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,
diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c
index b42e3d6..7042174 100644
--- a/vp10/encoder/encoder.c
+++ b/vp10/encoder/encoder.c
@@ -717,14 +717,14 @@
}
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
}
}
- 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 @@
// 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 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 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 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 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 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 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 @@
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 @@
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 @@
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 @@
}
// 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 @@
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 @@
}
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 @@
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 @@
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) {
diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h
index c45be4c..dc7374b 100644
--- a/vp10/encoder/encoder.h
+++ b/vp10/encoder/encoder.h
@@ -304,31 +304,32 @@
// For a still frame, this flag is set to 1 to skip partition search.
int partition_search_skippable_frame;
- 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 last_ref_to_refresh;
+#endif // CONFIG_EXT_REFS
+
+ int scaled_ref_idx[MAX_REF_FRAMES];
+#if CONFIG_EXT_REFS
+ 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 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,
diff --git a/vp10/encoder/firstpass.c b/vp10/encoder/firstpass.c
index c41fa3e..c865408 100644
--- a/vp10/encoder/firstpass.c
+++ b/vp10/encoder/firstpass.c
@@ -1044,8 +1044,13 @@
((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 @@
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 @@
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;
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c
index c65021b..4e3bf05 100644
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -5126,20 +5126,6 @@
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 @@
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) {