ref: 1942eeb8860bd1350e66a250cd684fa7705fb68c
parent: b095d9df3c7492e9ba031c4491a0a565f668c9e5
author: John Koleszar <jkoleszar@google.com>
date: Thu Jan 6 08:07:39 EST 2011
fix last frame buffer copy logic regression Commit 0ce3901 introduced a change in the frame buffer copy logic where the NEW frame could be copied to the ARF or GF buffer through the copy_buffer_to_{arf,gf}==1 flags, if the LAST frame was not being refreshed. This is not correct. The intent of the copy_buffer_to_{arf,gf}==1 flag is to copy the LAST buffer. To copy the NEW buffer, the refresh_{alt_ref,golden}_frame flag should be used. The original buffer copy logic is fairly convoluted. For example: if (cm->refresh_last_frame) { vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame); cm->frame_to_show = &cm->last_frame; } else { cm->frame_to_show = &cm->new_frame; } ... if (cm->copy_buffer_to_arf) { if (cm->copy_buffer_to_arf == 1) { if (cm->refresh_last_frame) vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame); else vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame); } else if (cm->copy_buffer_to_arf == 2) vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame); } Effectively, if refresh_last_frame, then new and last are swapped, so when "new" is copied to ARF, it's equivalent to copying LAST to ARF. If not refresh_last_frame, then LAST is copied to ARF. So LAST is copied to ARF in both cases. Commit 0ce3901 removed the first buffer swap but kept the refresh_last_frame?new:last behavior, changing the sense since the first swap wasn't done to the more readable refresh_last_frame?last:new, but this logic is not correct when !refresh_last_frame. This commit restores the correct behavior from v0.9.1 and prior. This case is missing from the test vector set. Change-Id: I8369fc13a37ae882e31a8a104da808a08bc8428f
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -254,13 +254,8 @@
/* If any buffer copy / swapping is signalled it should be done here. */
static int swap_frame_buffers (VP8_COMMON *cm)
{
- int fb_to_update_with, err = 0;
+ int err = 0;
- if (cm->refresh_last_frame)
- fb_to_update_with = cm->lst_fb_idx;
- else
- fb_to_update_with = cm->new_fb_idx;
-
/* The alternate reference frame or golden frame can be updated
* using the new, last, or golden/alt ref frame. If it
* is updated using the newly decoded frame it is a refresh.
@@ -271,7 +266,7 @@
int new_fb = 0;
if (cm->copy_buffer_to_arf == 1)
- new_fb = fb_to_update_with;
+ new_fb = cm->lst_fb_idx;
else if (cm->copy_buffer_to_arf == 2)
new_fb = cm->gld_fb_idx;
else
@@ -285,7 +280,7 @@
int new_fb = 0;
if (cm->copy_buffer_to_gf == 1)
- new_fb = fb_to_update_with;
+ new_fb = cm->lst_fb_idx;
else if (cm->copy_buffer_to_gf == 2)
new_fb = cm->alt_fb_idx;
else