Commit 8dd1c980 authored by Zoe Liu's avatar Zoe Liu

Add encoder support for multi-layer GF 16

Currently the use of the new multi-layer GF group of 16 is guarded by
the macro USE_GF16_MULTI_LAYER, which is turned off. Hence this CL
does not change any of the encoder behavior.

Change-Id: I588cd34e19388337a2ecb0a0cb3f796a37647e24
parent d1121fa3
......@@ -3649,10 +3649,31 @@ static void write_tile_info(const AV1_COMMON *const cm,
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
}
static int get_refresh_mask(AV1_COMP *cpi) {
#if CONFIG_EXT_REFS
#if USE_GF16_MULTI_LAYER
static int get_refresh_mask_gf16(AV1_COMP *cpi) {
int refresh_mask = 0;
if (cpi->refresh_last_frame || cpi->refresh_golden_frame ||
cpi->refresh_bwd_ref_frame || cpi->refresh_alt2_ref_frame ||
cpi->refresh_alt_ref_frame) {
assert(cpi->refresh_fb_idx >= 0 && cpi->refresh_fb_idx < REF_FRAMES);
refresh_mask |= (1 << cpi->refresh_fb_idx);
}
return refresh_mask;
}
#endif // USE_GF16_MULTI_LAYER
#endif // CONFIG_EXT_REFS
static int get_refresh_mask(AV1_COMP *cpi) {
#if CONFIG_EXT_REFS
#if USE_GF16_MULTI_LAYER
if (cpi->rc.baseline_gf_interval == 16) return get_refresh_mask_gf16(cpi);
#endif // USE_GF16_MULTI_LAYER
int refresh_mask = 0;
// NOTE(zoeliu): When LAST_FRAME is to get refreshed, the decoder will be
// notified to get LAST3_FRAME refreshed and then the virtual indexes for all
// the 3 LAST reference frames will be updated accordingly, i.e.:
......
......@@ -989,6 +989,7 @@ static void init_buffer_indices(AV1_COMP *cpi) {
cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
cpi->alt2_fb_idx = LAST_REF_FRAMES + 2;
cpi->alt_fb_idx = LAST_REF_FRAMES + 3;
cpi->ext_fb_idx = LAST_REF_FRAMES + 4;
for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
#else // !CONFIG_EXT_REFS
......@@ -3101,7 +3102,53 @@ void aom_write_yuv_frame_420(YV12_BUFFER_CONFIG *s, FILE *f) {
#endif
#if CONFIG_EXT_REFS && !CONFIG_XIPHRC
#if USE_GF16_MULTI_LAYER
static void check_show_existing_frame_gf16(AV1_COMP *cpi) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
AV1_COMMON *const cm = &cpi->common;
const FRAME_UPDATE_TYPE next_frame_update_type =
gf_group->update_type[gf_group->index];
if (cm->show_existing_frame == 1) {
cm->show_existing_frame = 0;
} else if (cpi->rc.is_last_bipred_frame) {
cpi->rc.is_last_bipred_frame = 0;
cm->show_existing_frame = 1;
cpi->existing_fb_idx_to_show = cpi->bwd_fb_idx;
} else if (next_frame_update_type == OVERLAY_UPDATE ||
next_frame_update_type == INTNL_OVERLAY_UPDATE) {
// Check the temporal filtering status for the next OVERLAY frame
const int num_arfs_in_gf = cpi->num_extra_arfs + 1;
int which_arf = 0, arf_idx;
// Identify the index to the next overlay frame.
for (arf_idx = 0; arf_idx < num_arfs_in_gf; arf_idx++) {
if (gf_group->index == cpi->arf_pos_for_ovrly[arf_idx]) {
which_arf = arf_idx;
break;
}
}
assert(arf_idx < num_arfs_in_gf);
if (cpi->is_arf_filter_off[which_arf]) {
cm->show_existing_frame = 1;
cpi->rc.is_src_frame_alt_ref = 1;
cpi->existing_fb_idx_to_show = (next_frame_update_type == OVERLAY_UPDATE)
? cpi->alt_fb_idx
: cpi->bwd_fb_idx;
cpi->is_arf_filter_off[which_arf] = 0;
}
}
cpi->rc.is_src_frame_ext_arf = 0;
}
#endif // USE_GF16_MULTI_LAYER
static void check_show_existing_frame(AV1_COMP *cpi) {
#if USE_GF16_MULTI_LAYER
if (cpi->rc.baseline_gf_interval == 16) {
check_show_existing_frame_gf16(cpi);
return;
}
#endif // USE_GF16_MULTI_LAYER
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
AV1_COMMON *const cm = &cpi->common;
const FRAME_UPDATE_TYPE next_frame_update_type =
......@@ -3111,9 +3158,9 @@ static void check_show_existing_frame(AV1_COMP *cpi) {
if (cm->show_existing_frame == 1) {
cm->show_existing_frame = 0;
} else if (cpi->rc.is_last_bipred_frame) {
// NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
// needed next to show the BWDREF_FRAME, which is pointed by
// the last_fb_idxes[0] after reference frame buffer update
// NOTE: If the current frame is a last bi-predictive frame, it is
// needed next to show the BWDREF_FRAME, which is pointed by
// the last_fb_idxes[0] after reference frame buffer update
cpi->rc.is_last_bipred_frame = 0;
cm->show_existing_frame = 1;
cpi->existing_fb_idx_to_show = cpi->lst_fb_idxes[0];
......@@ -3351,14 +3398,69 @@ static void enc_check_valid_ref_frames(AV1_COMP *const cpi) {
}
#endif // CONFIG_VAR_REFS
static void update_reference_frames(AV1_COMP *cpi) {
#if CONFIG_EXT_REFS
#if USE_GF16_MULTI_LAYER
static void update_reference_frames_gf16(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
BufferPool *const pool = cm->buffer_pool;
if (cm->frame_type == KEY_FRAME) {
for (int ref_frame = 0; ref_frame < LAST_REF_FRAMES; ++ref_frame) {
ref_cnt_fb(pool->frame_bufs,
&cm->ref_frame_map[cpi->lst_fb_idxes[ref_frame]],
cm->new_fb_idx);
}
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
cm->new_fb_idx);
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
cm->new_fb_idx);
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt2_fb_idx],
cm->new_fb_idx);
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
cm->new_fb_idx);
} else {
if (cpi->refresh_last_frame || cpi->refresh_golden_frame ||
cpi->refresh_bwd_ref_frame || cpi->refresh_alt2_ref_frame ||
cpi->refresh_alt_ref_frame) {
assert(cpi->refresh_fb_idx >= 0 && cpi->refresh_fb_idx < REF_FRAMES);
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->refresh_fb_idx],
cm->new_fb_idx);
}
// TODO(zoeliu): To handle cpi->interp_filter_selected[].
// For GF of 16, an additional ref frame index mapping needs to be handled
// if this is the last frame to encode in the current GF group.
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
if (gf_group->update_type[gf_group->index + 1] == OVERLAY_UPDATE)
av1_ref_frame_map_idx_updates(cpi, gf_group->index + 1);
}
#if DUMP_REF_FRAME_IMAGES == 1
// Dump out all reference frame images.
dump_ref_frame_images(cpi);
#endif // DUMP_REF_FRAME_IMAGES
}
#endif // USE_GF16_MULTI_LAYER
#endif // CONFIG_EXT_REFS
static void update_reference_frames(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
// NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
// for the purpose to verify no mismatch between encoder and decoder.
if (cm->show_frame) cpi->last_show_frame_buf_idx = cm->new_fb_idx;
#if CONFIG_EXT_REFS
#if USE_GF16_MULTI_LAYER
if (cpi->rc.baseline_gf_interval == 16) {
update_reference_frames_gf16(cpi);
return;
}
#endif // USE_GF16_MULTI_LAYER
#endif // CONFIG_EXT_REFS
BufferPool *const pool = cm->buffer_pool;
// At this point the new frame has been encoded.
// If any buffer copy / swapping is signaled it should be done here.
if (cm->frame_type == KEY_FRAME) {
......
......@@ -414,6 +414,10 @@ typedef struct AV1_COMP {
int alt2_fb_idx; // ALTREF2_FRAME
#endif // CONFIG_EXT_REFS
int alt_fb_idx;
#if CONFIG_EXT_REFS
int ext_fb_idx; // extra ref frame buffer index
int refresh_fb_idx; // ref frame buffer index to refresh
#endif // CONFIG_EXT_REFS
int last_show_frame_buf_idx; // last show frame buffer index
......
......@@ -1700,8 +1700,8 @@ static const unsigned char gf16_multi_layer_params[][GF_FRAME_PARAMS] = {
LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
......@@ -2116,6 +2116,7 @@ static const unsigned char gf16_multi_layer_params[][GF_FRAME_PARAMS] = {
}
};
// === GF Group of 16 ===
static void define_gf_group_structure_16(AV1_COMP *cpi) {
RATE_CONTROL *const rc = &cpi->rc;
TWO_PASS *const twopass = &cpi->twopass;
......@@ -2138,13 +2139,26 @@ static void define_gf_group_structure_16(AV1_COMP *cpi) {
// Treat KEY_FRAME differently
if (frame_index == 0 && key_frame) {
gf_group->update_type[frame_index] = KF_UPDATE;
gf_group->rf_level[frame_index] = KF_STD;
gf_group->arf_src_offset[frame_index] = 0;
gf_group->brf_src_offset[frame_index] = 0;
gf_group->bidir_pred_enabled[frame_index] = 0;
for (int ref_idx = 0; ref_idx < REF_FRAMES; ++ref_idx)
gf_group->ref_fb_idx_map[frame_index][ref_idx] = ref_idx;
gf_group->refresh_idx[frame_index] =
cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
gf_group->refresh_flag[frame_index] =
cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
continue;
}
// == update_type ==
gf_group->update_type[frame_index] =
gf16_multi_layer_params[frame_index][param_idx++];
// == rf_level ==
// Derive rf_level from update_type
switch (gf_group->update_type[frame_index]) {
case LF_UPDATE: gf_group->rf_level[frame_index] = INTER_NORMAL; break;
......@@ -2166,20 +2180,71 @@ static void define_gf_group_structure_16(AV1_COMP *cpi) {
default: gf_group->rf_level[frame_index] = INTER_NORMAL; break;
}
// == arf_src_offset ==
gf_group->arf_src_offset[frame_index] =
gf16_multi_layer_params[frame_index][param_idx++];
// == brf_src_offset ==
gf_group->brf_src_offset[frame_index] =
gf16_multi_layer_params[frame_index][param_idx++];
// == bidir_pred_enabled ==
// Derive bidir_pred_enabled from bidir_src_offset
gf_group->bidir_pred_enabled[frame_index] =
gf_group->brf_src_offset[frame_index] ? 1 : 0;
// == ref_fb_idx_map ==
for (int ref_idx = 0; ref_idx < REF_FRAMES; ++ref_idx)
gf_group->ref_fb_idx_map[frame_index][ref_idx] =
gf16_multi_layer_params[frame_index][param_idx++];
// == refresh_idx ==
gf_group->refresh_idx[frame_index] =
gf16_multi_layer_params[frame_index][param_idx++];
// == refresh_flag ==
gf_group->refresh_flag[frame_index] =
gf16_multi_layer_params[frame_index][param_idx];
}
// Mark the ARF_UPDATE / INTNL_ARF_UPDATE and OVERLAY_UPDATE /
// INTNL_OVERLAY_UPDATE for rate allocation
// NOTE: Indexes are designed in the display order backward:
// ALT[3] .. ALT[2] .. ALT[1] .. ALT[0],
// but their coding order is as follows:
// ALT0-ALT2-ALT3 .. OVERLAY3 .. OVERLAY2-ALT1 .. OVERLAY1 .. OVERLAY0
const int num_arfs_in_gf = cpi->num_extra_arfs + 1;
const int sub_arf_interval = rc->baseline_gf_interval / num_arfs_in_gf;
// == arf_pos_for_ovrly ==: Position for OVERLAY
for (int arf_idx = 0; arf_idx < num_arfs_in_gf; arf_idx++) {
const int prior_num_arfs =
(arf_idx <= 1) ? num_arfs_in_gf : (num_arfs_in_gf - 1);
cpi->arf_pos_for_ovrly[arf_idx] =
sub_arf_interval * (num_arfs_in_gf - arf_idx) + prior_num_arfs;
}
// == arf_pos_in_gf ==: Position for ALTREF
cpi->arf_pos_in_gf[0] = 1;
cpi->arf_pos_in_gf[1] = cpi->arf_pos_for_ovrly[2] + 1;
cpi->arf_pos_in_gf[2] = 2;
cpi->arf_pos_in_gf[3] = 3;
// == arf_update_idx ==
// == arf_ref_idx ==
// NOTE: Due to the hierarchical nature of GF16, these two parameters only
// relect the index to the nearest future overlay.
int start_frame_index = 0;
for (int arf_idx = (num_arfs_in_gf - 1); arf_idx >= 0; --arf_idx) {
const int end_frame_index = cpi->arf_pos_for_ovrly[arf_idx];
for (int frame_index = start_frame_index; frame_index <= end_frame_index;
++frame_index) {
gf_group->arf_update_idx[frame_index] = arf_idx;
gf_group->arf_ref_idx[frame_index] = arf_idx;
}
start_frame_index = end_frame_index + 1;
}
}
#endif // USE_GF16_MULTI_LAYER
#endif // CONFIG_EXT_REFS
......@@ -2191,31 +2256,6 @@ static void define_gf_group_structure(AV1_COMP *cpi) {
#if USE_GF16_MULTI_LAYER
if (rc->baseline_gf_interval == 16) {
define_gf_group_structure_16(cpi);
// Mark the ARF_UPDATE / INTNL_ARF_UPDATE and OVERLAY_UPDATE /
// INTNL_OVERLAY_UPDATE for rate allocation
// NOTE: Indexes are designed in the display order backward:
// ALT[3] .. ALT[2] .. ALT[1] .. ALT[0],
// but their coding order is as follows:
// ALT0-ALT2-ALT3 .. OVERLAY3 .. OVERLAY2-ALT1 .. OVERLAY1 .. OVERLAY0
const int num_arfs_in_gf = cpi->num_extra_arfs + 1;
const int sub_arf_interval = rc->baseline_gf_interval / num_arfs_in_gf;
// arf_pos_for_ovrly[]: Position for OVERLAY
for (int arf_idx = 0; arf_idx < num_arfs_in_gf; arf_idx++) {
const int prior_num_arfs =
(arf_idx <= 1) ? num_arfs_in_gf : (num_arfs_in_gf - 1);
cpi->arf_pos_for_ovrly[arf_idx] =
sub_arf_interval * (num_arfs_in_gf - arf_idx) + prior_num_arfs;
}
// arf_pos_in_gf[]: Position for ALTREF
cpi->arf_pos_in_gf[0] = 1;
cpi->arf_pos_in_gf[1] = cpi->arf_pos_for_ovrly[2] + 1;
cpi->arf_pos_in_gf[2] = 2;
cpi->arf_pos_in_gf[3] = 3;
return;
}
#endif // USE_GF16_MULTI_LAYER
......@@ -2223,7 +2263,6 @@ static void define_gf_group_structure(AV1_COMP *cpi) {
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
int i;
int frame_index = 0;
const int key_frame = cpi->common.frame_type == KEY_FRAME;
......@@ -3385,6 +3424,153 @@ static void find_next_key_frame(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass->modified_error_left -= kf_group_err;
}
#if USE_GF16_MULTI_LAYER
// === GF Group of 16 ===
void av1_ref_frame_map_idx_updates(AV1_COMP *cpi, int gf_frame_index) {
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
int ref_fb_idx_prev[REF_FRAMES];
int ref_fb_idx_curr[REF_FRAMES];
ref_fb_idx_prev[LAST_FRAME - LAST_FRAME] =
cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
ref_fb_idx_prev[LAST2_FRAME - LAST_FRAME] =
cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME];
ref_fb_idx_prev[LAST3_FRAME - LAST_FRAME] =
cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME];
ref_fb_idx_prev[GOLDEN_FRAME - LAST_FRAME] = cpi->gld_fb_idx;
ref_fb_idx_prev[BWDREF_FRAME - LAST_FRAME] = cpi->bwd_fb_idx;
ref_fb_idx_prev[ALTREF2_FRAME - LAST_FRAME] = cpi->alt2_fb_idx;
ref_fb_idx_prev[ALTREF_FRAME - LAST_FRAME] = cpi->alt_fb_idx;
ref_fb_idx_prev[REF_FRAMES - LAST_FRAME] = cpi->ext_fb_idx;
// Update map index for each reference frame
for (int ref_idx = 0; ref_idx < REF_FRAMES; ++ref_idx) {
int ref_frame = gf_group->ref_fb_idx_map[gf_frame_index][ref_idx];
ref_fb_idx_curr[ref_idx] = ref_fb_idx_prev[ref_frame - LAST_FRAME];
}
cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] =
ref_fb_idx_curr[LAST_FRAME - LAST_FRAME];
cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] =
ref_fb_idx_curr[LAST2_FRAME - LAST_FRAME];
cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] =
ref_fb_idx_curr[LAST3_FRAME - LAST_FRAME];
cpi->gld_fb_idx = ref_fb_idx_curr[GOLDEN_FRAME - LAST_FRAME];
cpi->bwd_fb_idx = ref_fb_idx_curr[BWDREF_FRAME - LAST_FRAME];
cpi->alt2_fb_idx = ref_fb_idx_curr[ALTREF2_FRAME - LAST_FRAME];
cpi->alt_fb_idx = ref_fb_idx_curr[ALTREF_FRAME - LAST_FRAME];
cpi->ext_fb_idx = ref_fb_idx_curr[REF_FRAMES - LAST_FRAME];
}
// Define the reference buffers that will be updated post encode.
static void configure_buffer_updates_16(AV1_COMP *cpi) {
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
if (gf_group->update_type[gf_group->index] == KF_UPDATE) {
cpi->refresh_fb_idx = 0;
cpi->refresh_last_frame = 1;
cpi->refresh_golden_frame = 1;
cpi->refresh_bwd_ref_frame = 1;
cpi->refresh_alt2_ref_frame = 1;
cpi->refresh_alt_ref_frame = 1;
return;
}
// Update reference frame map indexes
av1_ref_frame_map_idx_updates(cpi, gf_group->index);
// Update refresh index
switch (gf_group->refresh_idx[gf_group->index]) {
case LAST_FRAME:
cpi->refresh_fb_idx = cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
break;
case LAST2_FRAME:
cpi->refresh_fb_idx = cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME];
break;
case LAST3_FRAME:
cpi->refresh_fb_idx = cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME];
break;
case GOLDEN_FRAME: cpi->refresh_fb_idx = cpi->gld_fb_idx; break;
case BWDREF_FRAME: cpi->refresh_fb_idx = cpi->bwd_fb_idx; break;
case ALTREF2_FRAME: cpi->refresh_fb_idx = cpi->alt2_fb_idx; break;
case ALTREF_FRAME: cpi->refresh_fb_idx = cpi->alt_fb_idx; break;
case REF_FRAMES: cpi->refresh_fb_idx = cpi->ext_fb_idx; break;
default: assert(0); break;
}
// Update refresh flags
switch (gf_group->refresh_flag[gf_group->index]) {
case LAST_FRAME:
cpi->refresh_last_frame = 1;
cpi->refresh_golden_frame = 0;
cpi->refresh_bwd_ref_frame = 0;
cpi->refresh_alt2_ref_frame = 0;
cpi->refresh_alt_ref_frame = 0;
break;
case GOLDEN_FRAME:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 1;
cpi->refresh_bwd_ref_frame = 0;
cpi->refresh_alt2_ref_frame = 0;
cpi->refresh_alt_ref_frame = 0;
break;
case BWDREF_FRAME:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 0;
cpi->refresh_bwd_ref_frame = 1;
cpi->refresh_alt2_ref_frame = 0;
cpi->refresh_alt_ref_frame = 0;
break;
case ALTREF2_FRAME:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 0;
cpi->refresh_bwd_ref_frame = 0;
cpi->refresh_alt2_ref_frame = 1;
cpi->refresh_alt_ref_frame = 0;
break;
case ALTREF_FRAME:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 0;
cpi->refresh_bwd_ref_frame = 0;
cpi->refresh_alt2_ref_frame = 0;
cpi->refresh_alt_ref_frame = 1;
break;
default: assert(0); break;
}
switch (gf_group->update_type[gf_group->index]) {
case BRF_UPDATE: cpi->rc.is_bwd_ref_frame = 1; break;
case LAST_BIPRED_UPDATE: cpi->rc.is_last_bipred_frame = 1; break;
case BIPRED_UPDATE: cpi->rc.is_bipred_frame = 1; break;
case INTNL_OVERLAY_UPDATE: cpi->rc.is_src_frame_ext_arf = 1;
case OVERLAY_UPDATE: cpi->rc.is_src_frame_alt_ref = 1; break;
default: break;
}
}
#endif // USE_GF16_MULTI_LAYER
// Define the reference buffers that will be updated post encode.
static void configure_buffer_updates(AV1_COMP *cpi) {
TWO_PASS *const twopass = &cpi->twopass;
......@@ -3398,6 +3584,14 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
cpi->rc.is_last_bipred_frame = 0;
cpi->rc.is_bipred_frame = 0;
cpi->rc.is_src_frame_ext_arf = 0;
#if USE_GF16_MULTI_LAYER
RATE_CONTROL *const rc = &cpi->rc;
if (rc->baseline_gf_interval == 16) {
configure_buffer_updates_16(cpi);
return;
}
#endif // USE_GF16_MULTI_LAYER
#endif // CONFIG_EXT_REFS
switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
......
......@@ -199,6 +199,10 @@ void av1_rc_get_second_pass_params(struct AV1_COMP *cpi);
void av1_twopass_postencode_update(struct AV1_COMP *cpi);
#if CONFIG_EXT_REFS
#if USE_GF16_MULTI_LAYER
void av1_ref_frame_map_idx_updates(struct AV1_COMP *cpi, int gf_frame_index);
#endif // USE_GF16_MULTI_LAYER
static INLINE int get_number_of_extra_arfs(int interval, int arf_pending) {
if (arf_pending && MAX_EXT_ARFS > 0)
return interval >= MIN_EXT_ARF_INTERVAL * (MAX_EXT_ARFS + 1)
......
......@@ -652,14 +652,29 @@ void av1_temporal_filter(AV1_COMP *cpi,
strength = 0;
frames_to_blur = 1;
}
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_REFS
if (strength == 0 && frames_to_blur == 1) {
cpi->is_arf_filter_off[gf_group->arf_update_idx[gf_group->index]] = 1;
} else {
cpi->is_arf_filter_off[gf_group->arf_update_idx[gf_group->index]] = 0;
int which_arf = gf_group->arf_update_idx[gf_group->index];
#if USE_GF16_MULTI_LAYER
if (cpi->rc.baseline_gf_interval == 16) {
// Identify the index to the current ARF.
const int num_arfs_in_gf = cpi->num_extra_arfs + 1;
int arf_idx;
for (arf_idx = 0; arf_idx < num_arfs_in_gf; arf_idx++) {
if (gf_group->index == cpi->arf_pos_in_gf[arf_idx]) {
which_arf = arf_idx;
break;
}
}
assert(arf_idx < num_arfs_in_gf);
}
#endif // USE_GF16_MULTI_LAYER
// Set the temporal filtering status for the corresponding OVERLAY frame
if (strength == 0 && frames_to_blur == 1)
cpi->is_arf_filter_off[which_arf] = 1;
else
cpi->is_arf_filter_off[which_arf] = 0;
#endif // CONFIG_EXT_REFS
frames_to_blur_backward = (frames_to_blur / 2);
......
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