OSUOSL/Nero are experiencing Internet connectivity problems. This affects us as we're hosted with OSUOSL. We apologize for the inconvenience.

Commit ec36a2b0 authored by Zoe Liu's avatar Zoe Liu

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,
......
This diff is collapsed.
......@@ -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,
......
......@@ -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;
......
......@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment