From 43464e94edf3c6cb5792d5c2addb7e0ce1604d4c Mon Sep 17 00:00:00 2001 From: Attila Nagy Date: Wed, 20 Apr 2011 15:12:23 +0300 Subject: [PATCH] Do not copy data between encoder reference buffers. Golden and ALT reference buffers were refreshed by copying from the new buffer. Replaced this by index manipulation. Also moved all the reference frame updates to one function for easier tracking. Change-Id: Icd3e534e7e2c8c5567168d222e6a64a96aae24a1 --- vp8/common/alloccommon.c | 6 +- vp8/encoder/onyx_if.c | 191 ++++++++++++++++++++++----------------- vpx_scale/yv12config.h | 1 + 3 files changed, 111 insertions(+), 87 deletions(-) diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c index edef36094..a1944ebda 100644 --- a/vp8/common/alloccommon.c +++ b/vp8/common/alloccommon.c @@ -65,9 +65,9 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height) for (i = 0; i < NUM_YV12_BUFFERS; i++) { - oci->fb_idx_ref_cnt[0] = 0; - - if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i], width, height, VP8BORDERINPIXELS) < 0) + oci->fb_idx_ref_cnt[0] = 0; + oci->yv12_fb[i].flags = 0; + if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i], width, height, VP8BORDERINPIXELS) < 0) { vp8_de_alloc_frame_buffers(oci); return 1; diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 92e0cbb19..46191f065 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2755,13 +2755,10 @@ static void set_quantizer(VP8_COMP *cpi, int Q) } -static void update_alt_ref_frame_and_stats(VP8_COMP *cpi) +static void update_alt_ref_frame_stats(VP8_COMP *cpi) { VP8_COMMON *cm = &cpi->common; - // Update the golden frame buffer - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->alt_fb_idx]); - // Select an interval before next GF or altref if (!cpi->auto_gold) cpi->frames_till_gf_update_due = cpi->goldfreq; @@ -2794,19 +2791,13 @@ static void update_alt_ref_frame_and_stats(VP8_COMP *cpi) } -static void update_golden_frame_and_stats(VP8_COMP *cpi) +static void update_golden_frame_stats(VP8_COMP *cpi) { VP8_COMMON *cm = &cpi->common; - // Update the Golden frame reconstruction buffer if signalled and the GF usage counts. + // Update the Golden frame usage counts. if (cm->refresh_golden_frame) { - if (cm->frame_type != KEY_FRAME) - { - // Update the golden frame buffer - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->gld_fb_idx]); - } - // Select an interval before next GF if (!cpi->auto_gold) cpi->frames_till_gf_update_due = cpi->goldfreq; @@ -3186,6 +3177,85 @@ static BOOL recode_loop_test( VP8_COMP *cpi, return force_recode; } +void update_reference_frames(VP8_COMMON *cm) +{ + YV12_BUFFER_CONFIG *yv12_fb = cm->yv12_fb; + + // 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) + { + yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FLAG | VP8_ALT_FLAG ; + + yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG; + yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG; + + cm->alt_fb_idx = cm->gld_fb_idx = cm->new_fb_idx; + } + else /* For non key frames */ + { + if (cm->refresh_alt_ref_frame) + { + assert(!cm->copy_buffer_to_arf); + + cm->yv12_fb[cm->new_fb_idx].flags |= VP8_ALT_FLAG; + cm->yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG; + cm->alt_fb_idx = cm->new_fb_idx; + } + else if (cm->copy_buffer_to_arf) + { + assert(!(cm->copy_buffer_to_arf & ~0x3)); + + if (cm->copy_buffer_to_arf == 1) + { + yv12_fb[cm->lst_fb_idx].flags |= VP8_ALT_FLAG; + yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG; + cm->alt_fb_idx = cm->lst_fb_idx; + } + else /* if (cm->copy_buffer_to_arf == 2) */ + { + yv12_fb[cm->gld_fb_idx].flags |= VP8_ALT_FLAG; + yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG; + cm->alt_fb_idx = cm->gld_fb_idx; + } + } + + if (cm->refresh_golden_frame) + { + assert(!cm->copy_buffer_to_gf); + + cm->yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FLAG; + cm->yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG; + cm->gld_fb_idx = cm->new_fb_idx; + } + else if (cm->copy_buffer_to_gf) + { + assert(!(cm->copy_buffer_to_arf & ~0x3)); + + if (cm->copy_buffer_to_gf == 1) + { + yv12_fb[cm->lst_fb_idx].flags |= VP8_GOLD_FLAG; + yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG; + cm->gld_fb_idx = cm->lst_fb_idx; + } + else /* if (cm->copy_buffer_to_gf == 2) */ + { + yv12_fb[cm->alt_fb_idx].flags |= VP8_GOLD_FLAG; + yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG; + cm->gld_fb_idx = cm->alt_fb_idx; + } + } + } + + if (cm->refresh_last_frame) + { + cm->yv12_fb[cm->new_fb_idx].flags |= VP8_LAST_FLAG; + cm->yv12_fb[cm->lst_fb_idx].flags &= ~VP8_LAST_FLAG; + cm->lst_fb_idx = cm->new_fb_idx; + } +} + void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) { if (cm->no_lpf) @@ -3224,50 +3294,6 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show); - { - YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx]; - YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx]; - YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx]; - YV12_BUFFER_CONFIG *alt_yv12 = &cm->yv12_fb[cm->alt_fb_idx]; - // 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) - { - vp8_yv12_copy_frame_ptr(cm->frame_to_show, gld_yv12); - vp8_yv12_copy_frame_ptr(cm->frame_to_show, alt_yv12); - } - else // For non key frames - { - // Code to copy between reference buffers - if (cm->copy_buffer_to_arf) - { - if (cm->copy_buffer_to_arf == 1) - { - if (cm->refresh_last_frame) - // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set. - vp8_yv12_copy_frame_ptr(new_yv12, alt_yv12); - else - vp8_yv12_copy_frame_ptr(lst_yv12, alt_yv12); - } - else if (cm->copy_buffer_to_arf == 2) - vp8_yv12_copy_frame_ptr(gld_yv12, alt_yv12); - } - - if (cm->copy_buffer_to_gf) - { - if (cm->copy_buffer_to_gf == 1) - { - if (cm->refresh_last_frame) - // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set. - vp8_yv12_copy_frame_ptr(new_yv12, gld_yv12); - else - vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12); - } - else if (cm->copy_buffer_to_gf == 2) - vp8_yv12_copy_frame_ptr(alt_yv12, gld_yv12); - } - } - } } static void encode_frame_to_data_rate @@ -4169,21 +4195,15 @@ static void encode_frame_to_data_rate } #endif - // For inter frames the current default behaviour is that when cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer - // This is purely an encoder descision at present. + // For inter frames the current default behavior is that when + // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer + // This is purely an encoder decision at present. if (!cpi->oxcf.error_resilient_mode && cm->refresh_golden_frame) cm->copy_buffer_to_arf = 2; else cm->copy_buffer_to_arf = 0; - if (cm->refresh_last_frame) - { - vp8_swap_yv12_buffer(&cm->yv12_fb[cm->lst_fb_idx], &cm->yv12_fb[cm->new_fb_idx]); - cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx]; - } - else - cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; - + cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; #if CONFIG_MULTITHREAD if (cpi->b_multi_threaded) @@ -4196,6 +4216,8 @@ static void encode_frame_to_data_rate loopfilter_frame(cpi, cm); } + update_reference_frames(cm); + if (cpi->oxcf.error_resilient_mode == 1) { cm->refresh_entropy_probs = 0; @@ -4220,7 +4242,7 @@ static void encode_frame_to_data_rate /* Move storing frame_type out of the above loop since it is also * needed in motion search besides loopfilter */ - cm->last_frame_type = cm->frame_type; + cm->last_frame_type = cm->frame_type; // Update rate control heuristics cpi->total_byte_count += (*size); @@ -4470,26 +4492,14 @@ static void encode_frame_to_data_rate cpi->ref_frame_flags &= ~VP8_ALT_FLAG; - if (cpi->oxcf.error_resilient_mode) - { - if (cm->frame_type != KEY_FRAME) - { - // Is this an alternate reference update - if (cm->refresh_alt_ref_frame) - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->alt_fb_idx]); - - if (cm->refresh_golden_frame) - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->gld_fb_idx]); - } - } - else + if (!cpi->oxcf.error_resilient_mode) { if (cpi->oxcf.play_alternate && cm->refresh_alt_ref_frame && (cm->frame_type != KEY_FRAME)) - // Update the alternate reference frame and stats as appropriate. - update_alt_ref_frame_and_stats(cpi); + // Update the alternate reference frame stats as appropriate. + update_alt_ref_frame_stats(cpi); else - // Update the Golden frame and golden frame and stats as appropriate. - update_golden_frame_and_stats(cpi); + // Update the Golden frame stats as appropriate. + update_golden_frame_stats(cpi); } if (cm->frame_type == KEY_FRAME) @@ -4833,7 +4843,20 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon } #endif + /* find a free buffer for the new frame */ + { + int i = 0; + for(; i < NUM_YV12_BUFFERS; i++) + { + if(!cm->yv12_fb[i].flags) + { + cm->new_fb_idx = i; + break; + } + } + assert(i < NUM_YV12_BUFFERS ); + } #if !(CONFIG_REALTIME_ONLY) if (cpi->pass == 1) diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h index e10db3468..3cc4746f7 100644 --- a/vpx_scale/yv12config.h +++ b/vpx_scale/yv12config.h @@ -59,6 +59,7 @@ extern "C" YUV_TYPE clrtype; int corrupted; + int flags; } YV12_BUFFER_CONFIG; int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border);