Commit ec36a2b0 authored by Zoe Liu's avatar Zoe Liu
Browse files

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
parent 8b9efaa1
......@@ -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 {
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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,
......
......@@ -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)