From fc905edb3a0f0330957094b2836ef8bf03573e04 Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Sat, 25 Aug 2018 21:39:59 -0700 Subject: [PATCH] Build arf index stack Stack the ARF frame indexes. Use the most recent one as the ARF reference frame for frame coding. Change-Id: I88a2202fa5deb2587d861b434d27ab8de0642cf7 --- vp9/encoder/vp9_bitstream.c | 15 +++++++++++++++ vp9/encoder/vp9_encoder.c | 27 +++++++++++++++++++++++++-- vp9/encoder/vp9_encoder.h | 5 +++++ vp9/encoder/vp9_firstpass.h | 5 +++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 79fc160c1..21a68bf39 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -909,10 +909,25 @@ int vp9_get_refresh_mask(VP9_COMP *cpi) { (cpi->refresh_golden_frame << cpi->alt_fb_idx); } else { int arf_idx = cpi->alt_fb_idx; + GF_GROUP *const gf_group = &cpi->twopass.gf_group; if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; arf_idx = gf_group->arf_update_idx[gf_group->index]; } + + if (cpi->multi_layer_arf) { + for (arf_idx = 0; arf_idx < REF_FRAMES; ++arf_idx) { + if (arf_idx != cpi->alt_fb_idx && arf_idx != cpi->lst_fb_idx && + arf_idx != cpi->gld_fb_idx) { + int idx; + for (idx = 0; idx < gf_group->stack_size; ++idx) + if (arf_idx == gf_group->arf_index_stack[idx]) break; + if (idx == gf_group->stack_size) break; + } + } + } + cpi->twopass.gf_group.top_arf_idx = arf_idx; + if (cpi->use_svc && cpi->svc.use_set_ref_frame_config && cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) return cpi->svc.update_buffer_slot[cpi->svc.spatial_layer_id]; diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index c4efd9954..7f9f2c5d5 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3169,6 +3169,15 @@ void update_multi_arf_ref_frames(VP9_COMP *cpi) { void update_ref_frames(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; BufferPool *const pool = cm->buffer_pool; + GF_GROUP *const gf_group = &cpi->twopass.gf_group; + + // Pop ARF. + if (cm->show_existing_frame) { + cpi->lst_fb_idx = cpi->alt_fb_idx; + cpi->alt_fb_idx = + stack_pop(gf_group->arf_index_stack, gf_group->stack_size); + --gf_group->stack_size; + } // At this point the new frame has been encoded. // If any buffer copy / swapping is signaled it should be done here. @@ -3196,16 +3205,25 @@ void update_ref_frames(VP9_COMP *cpi) { cpi->gld_fb_idx = tmp; } else { /* For non key/golden frames */ if (cpi->refresh_alt_ref_frame) { - int arf_idx = cpi->alt_fb_idx; + int arf_idx = gf_group->top_arf_idx; if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; arf_idx = gf_group->arf_update_idx[gf_group->index]; } + // Push new ARF into stack. + stack_push(gf_group->arf_index_stack, cpi->alt_fb_idx, + gf_group->stack_size); + ++gf_group->stack_size; + + assert(arf_idx < REF_FRAMES); + ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx); memcpy(cpi->interp_filter_selected[ALTREF_FRAME], cpi->interp_filter_selected[0], sizeof(cpi->interp_filter_selected[0])); + + cpi->alt_fb_idx = arf_idx; } if (cpi->refresh_golden_frame) { @@ -6091,9 +6109,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, } } + // Clear arf index stack before group of pictures processing starts. + if (cpi->twopass.gf_group.index == 1) { + stack_init(cpi->twopass.gf_group.arf_index_stack, MAX_LAG_BUFFERS * 2); + cpi->twopass.gf_group.stack_size = 0; + } + if (arf_src_index) { assert(arf_src_index <= rc->frames_to_key); - if ((source = vp9_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) { cpi->alt_ref_source = source; diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 9adcb4522..446e030ba 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -834,6 +834,11 @@ static INLINE void stack_push(int *stack, int new_item, int stack_size) { stack[0] = new_item; } +static INLINE void stack_init(int *stack, int length) { + int idx; + for (idx = 0; idx < length; ++idx) stack[idx] = -1; +} + int vp9_get_quantizer(struct VP9_COMP *cpi); static INLINE int frame_is_kf_gf_arf(const VP9_COMP *cpi) { diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h index 0a7e1adf7..e1c882df4 100644 --- a/vp9/encoder/vp9_firstpass.h +++ b/vp9/encoder/vp9_firstpass.h @@ -143,6 +143,11 @@ typedef struct { unsigned char brf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 2]; unsigned char bidir_pred_enabled[MAX_STATIC_GF_GROUP_LENGTH + 2]; int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH + 2]; + + // TODO(jingning): The array size of arf_stack could be reduced. + int arf_index_stack[MAX_LAG_BUFFERS * 2]; + int top_arf_idx; + int stack_size; } GF_GROUP; typedef struct { -- 2.40.0