reset_frame_buffers: decrease ref_count correctly.
Right now reset_frame_buffers() blindly resets the ref_count of all
frame buffers to 0, except for the frame buffer referenced by
cm->new_fb_idx. But the pbi->output_frame_index array may also reference
frame buffers. reset_frame_buffers() should not release the references
stored in the pbi->output_frame_index array without also clearing that
array. Since I do not know if reset_frame_buffers() should release the
references stored in pbi->output_frame_index, I decided to play safe and
only release the references stored in cm->ref_frame_map correctly.
BUG=oss-fuzz:10779
BUG=oss-fuzz:10782
Change-Id: I37b56c28e5308a1bcb53c64603deed0a8bb5fc03
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 1b960c0..9cb1cee 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4750,17 +4750,18 @@
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
int i;
- memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
+ // We have not stored any references to frame buffers in
+ // cm->next_ref_frame_map, so we can directly reset it to all -1.
memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map));
lock_buffer_pool(cm->buffer_pool);
+ reset_ref_frame_map(cm);
+ assert(frame_bufs[cm->new_fb_idx].ref_count == 1);
for (i = 0; i < FRAME_BUFFERS; ++i) {
- if (i != cm->new_fb_idx) {
- frame_bufs[i].ref_count = 0;
- cm->buffer_pool->release_fb_cb(cm->buffer_pool->cb_priv,
- &frame_bufs[i].raw_frame_buffer);
- } else {
- assert(frame_bufs[i].ref_count == 1);
+ // Reset all unreferenced frame buffers. We can also reset cm->new_fb_idx
+ // because we are the sole owner of cm->new_fb_idx.
+ if (frame_bufs[i].ref_count > 0 && i != cm->new_fb_idx) {
+ continue;
}
frame_bufs[i].cur_frame_offset = 0;
av1_zero(frame_bufs[i].ref_frame_offset);