From f9e38a7bb9e33bbfdc625e975a157492edecd20a Mon Sep 17 00:00:00 2001 From: Wei-ting Lin Date: Thu, 30 Jun 2016 13:33:55 -0700 Subject: [PATCH] Remove reference frame buffer update for show_exsiting_frame Originally we need to send the refresh flag and the virtual indices mapping for the reference frame buffer update for show_existing_frame to have the BWDREF_FRAME replace the LAST_FRAME. To remove sending this information, we update the the virtual indices of the reference frame buffer after the last_bipred_frame is encoded, and therefore the decoder will receive the updated reference mapping at the next non-show-existing frame. As a result, we can save 4 bytes per show-existing frame, and get 0.12, 0.2, and 0.07 BDRATE improvement in lowres, derf, and midref test set respectively. Change-Id: I63d41ee6ea99884798f0778b789d2701e2f2d3e0 --- vp10/decoder/decodeframe.c | 56 +------------------------------------- vp10/decoder/decoder.c | 16 +---------- vp10/encoder/bitstream.c | 11 -------- vp10/encoder/encoder.c | 42 ++++++++++++++++------------ 4 files changed, 26 insertions(+), 99 deletions(-) diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index c414b097f..c4487a9fa 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -3159,66 +3159,12 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, cm->lf.filter_level = 0; cm->show_frame = 1; - -#if CONFIG_EXT_REFS - // NOTE(zoeliu): The existing frame to show is adopted as a reference frame. - pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES); - - for (i = 0; i < REFS_PER_FRAME; ++i) { - const int ref = vpx_rb_read_literal(rb, REF_FRAMES_LOG2); - const int idx = cm->ref_frame_map[ref]; - RefBuffer *const ref_frame = &cm->frame_refs[i]; - ref_frame->idx = idx; - ref_frame->buf = &frame_bufs[idx].buf; - cm->ref_frame_sign_bias[LAST_FRAME + i] = vpx_rb_read_bit(rb); - } - - for (i = 0; i < REFS_PER_FRAME; ++i) { - RefBuffer *const ref_buf = &cm->frame_refs[i]; -#if CONFIG_VP9_HIGHBITDEPTH - vp10_setup_scale_factors_for_frame(&ref_buf->sf, - ref_buf->buf->y_crop_width, - ref_buf->buf->y_crop_height, - cm->width, cm->height, - cm->use_highbitdepth); -#else // CONFIG_VP9_HIGHBITDEPTH - vp10_setup_scale_factors_for_frame(&ref_buf->sf, - ref_buf->buf->y_crop_width, - ref_buf->buf->y_crop_height, - cm->width, cm->height); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - // Generate next_ref_frame_map. - lock_buffer_pool(pool); - for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { - 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]; - } - // 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; - } - - for (; ref_index < REF_FRAMES; ++ref_index) { - cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index]; - // Current thread holds the reference frame. - if (cm->ref_frame_map[ref_index] >= 0) - ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count; - } - unlock_buffer_pool(pool); - pbi->hold_ref_buf = 1; -#else pbi->refresh_frame_flags = 0; + if (cm->frame_parallel_decode) { for (i = 0; i < REF_FRAMES; ++i) cm->next_ref_frame_map[i] = cm->ref_frame_map[i]; } -#endif // CONFIG_EXT_REFS return 0; } diff --git a/vp10/decoder/decoder.c b/vp10/decoder/decoder.c index 13e22613d..d1e710497 100644 --- a/vp10/decoder/decoder.c +++ b/vp10/decoder/decoder.c @@ -285,19 +285,12 @@ static void swap_frame_buffers(VP10Decoder *pbi) { } // Current thread releases the holding of reference frame. -#if CONFIG_EXT_REFS - for (; ref_index < REF_FRAMES; ++ref_index) { - const int old_idx = cm->ref_frame_map[ref_index]; - decrease_ref_count(old_idx, frame_bufs, pool); - cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; - } -#else for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { const int old_idx = cm->ref_frame_map[ref_index]; decrease_ref_count(old_idx, frame_bufs, pool); cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; } -#endif // CONFIG_EXT_REFS + unlock_buffer_pool(pool); pbi->hold_ref_buf = 0; cm->frame_to_show = get_frame_new_buffer(cm); @@ -406,17 +399,10 @@ int vp10_receive_compressed_data(VP10Decoder *pbi, } // Current thread releases the holding of reference frame. -#if CONFIG_EXT_REFS - for (; ref_index < REF_FRAMES; ++ref_index) { - const int old_idx = cm->ref_frame_map[ref_index]; - decrease_ref_count(old_idx, frame_bufs, pool); - } -#else for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { const int old_idx = cm->ref_frame_map[ref_index]; decrease_ref_count(old_idx, frame_bufs, pool); } -#endif // CONFIG_EXT_REFS pbi->hold_ref_buf = 0; } // Release current frame. diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index ba1ca68ad..cabfc4084 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -3042,7 +3042,6 @@ static void write_uncompressed_header(VP10_COMP *cpi, cm->is_reference_frame = 1; if (cm->show_existing_frame) { - MV_REFERENCE_FRAME ref_frame; RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; const int frame_to_show = cm->ref_frame_map[cpi->existing_fb_idx_to_show]; @@ -3057,16 +3056,6 @@ static void write_uncompressed_header(VP10_COMP *cpi, vpx_wb_write_bit(wb, 1); // show_existing_frame vpx_wb_write_literal(wb, cpi->existing_fb_idx_to_show, 3); - cpi->refresh_frame_mask = get_refresh_mask(cpi); - vpx_wb_write_literal(wb, cpi->refresh_frame_mask, REF_FRAMES); - - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - assert(get_ref_frame_map_idx(cpi, ref_frame) != INVALID_IDX); - vpx_wb_write_literal(wb, get_ref_frame_map_idx(cpi, ref_frame), - REF_FRAMES_LOG2); - vpx_wb_write_bit(wb, cm->ref_frame_sign_bias[ref_frame]); - } - return; } else { #endif // CONFIG_EXT_REFS diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index 438cbb531..4e486a9ef 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -3390,23 +3390,6 @@ void vp10_update_reference_frames(VP10_COMP *cpi) { if (cm->show_frame) cpi->last_show_frame_buf_idx = cm->new_fb_idx; -#if CONFIG_EXT_REFS - // TODO(zoeliu): To remove the reference buffer update for the - // show_existing_frame==1 case. -#if 0 - if (cpi->rc.is_last_bipred_frame) { - // NOTE: After the encoding of the LAST_BIPRED_FRAME, the flag of - // show_existing_frame will be set, to notify the decoder to show the - // coded BWDREF_FRAME. During the handling of the show_existing_frame, - // no update will be conducted on the reference frame buffer. - // Following is to get the BWDREF_FRAME to show to be regarded as the - // LAST_FRAME, preparing for the encoding of the next BWDREF_FRAME. - cpi->lst_fb_idx = cpi->bwd_fb_idx; - return; - } -#endif // 0 -#endif // CONFIG_EXT_REFS - if (use_upsampled_ref) { #if CONFIG_EXT_REFS if (cm->show_existing_frame) { @@ -3470,6 +3453,29 @@ void vp10_update_reference_frames(VP10_COMP *cpi) { // TODO(zoeliu): Do we need to copy cpi->interp_filter_selected[0] over to // cpi->interp_filter_selected[GOLDEN_FRAME]? +#if CONFIG_EXT_REFS + } else if (cpi->rc.is_last_bipred_frame) { + // Refresh the LAST_FRAME with the BWDREF_FRAME and retire the LAST3_FRAME + // by updating the virtual indices. Note that the frame BWDREF_FRAME points + // to now should be retired, and it should not be used before refreshed. + int ref_frame, tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES-1]; + for (ref_frame = LAST_REF_FRAMES - 1; ref_frame > 0; --ref_frame) { + cpi->lst_fb_idxes[ref_frame] = cpi->lst_fb_idxes[ref_frame - 1]; + + if (!cpi->rc.is_src_frame_alt_ref) { + memcpy(cpi->interp_filter_selected[ref_frame], + cpi->interp_filter_selected[ref_frame - 1], + sizeof(cpi->interp_filter_selected[ref_frame - 1])); + } + } + cpi->lst_fb_idxes[0] = cpi->bwd_fb_idx; + if (!cpi->rc.is_src_frame_alt_ref) { + memcpy(cpi->interp_filter_selected[0], + cpi->interp_filter_selected[BWDREF_FRAME], + sizeof(cpi->interp_filter_selected[BWDREF_FRAME])); + } + cpi->bwd_fb_idx = tmp; +#endif // CONFIG_EXT_REFS } else { /* For non key/golden frames */ if (cpi->refresh_alt_ref_frame) { int arf_idx = cpi->alt_fb_idx; @@ -4810,7 +4816,7 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi, cm->show_frame = 1; cpi->frame_flags = *frame_flags; - cpi->refresh_last_frame = 1; + cpi->refresh_last_frame = 0; cpi->refresh_golden_frame = 0; cpi->refresh_bwd_ref_frame = 0; cpi->refresh_alt_ref_frame = 0;