Remove cm->next_ref_frame_map, pbi->hold_ref_buf.
cm->next_ref_frame_map was intended to support frame parallel decoding.
Since frame parallel decoding was not implemented, we can remove
cm->next_ref_frame_map and the associated pbi->hold_ref_buf boolean.
swap_frame_buffers() is renamed update_frame_buffers() because the
function no longer swaps cm->ref_frame_map and cm->next_ref_frame_map;
now it updates cm->ref_frame_map. Also, release_frame_buffers() is
renamed release_current_frame() because the only frame buffer it
releases now is cm->current_frame.
TESTED=test_libaom --gtest_filter=*InvalidFileTest*
BUG=aomedia:2110,oss-fuzz:16437
Change-Id: I32dab3d01fb4574f2563f535c24804c6775933d2
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 38b76cd..d2abfd7 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -115,7 +115,6 @@
// - cm->ref_frame_map[]
// - cm->cur_frame
// - cm->scaled_ref_buf[] (encoder only)
- // - cm->next_ref_frame_map[] (decoder only)
// - pbi->output_frame_index[] (decoder only)
// With that definition, 'ref_count' is the number of reference-holding
// variables that are currently referencing this buffer.
@@ -362,9 +361,6 @@
// a pointer to the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'.
RefCntBuffer *ref_frame_map[REF_FRAMES];
- // Prepare ref_frame_map for the next frame.
- // Only used in frame parallel decode.
- RefCntBuffer *next_ref_frame_map[REF_FRAMES];
FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/
int show_frame;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index b51a8e3..f355ca9 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4540,36 +4540,6 @@
}
}
-// Generate next_ref_frame_map.
-static void generate_next_ref_frame_map(AV1Decoder *const pbi) {
- AV1_COMMON *const cm = &pbi->common;
- BufferPool *const pool = cm->buffer_pool;
-
- lock_buffer_pool(pool);
- // cm->next_ref_frame_map holds references to frame buffers. After storing a
- // frame buffer index in cm->next_ref_frame_map, we need to increase the
- // frame buffer's ref_count.
- int ref_index = 0;
- for (int mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) {
- if (mask & 1) {
- cm->next_ref_frame_map[ref_index] = cm->cur_frame;
- } else {
- cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
- }
- if (cm->next_ref_frame_map[ref_index] != NULL)
- ++cm->next_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];
- if (cm->next_ref_frame_map[ref_index] != NULL)
- ++cm->next_ref_frame_map[ref_index]->ref_count;
- }
- unlock_buffer_pool(pool);
- pbi->hold_ref_buf = 1;
-}
-
// If the refresh_frame_flags bitmask is set, update reference frame id values
// and mark frames as valid for reference.
static void update_ref_frame_id(AV1_COMMON *const cm, int frame_id) {
@@ -4607,23 +4577,12 @@
update_ref_frame_id(cm, cm->current_frame_id);
cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
-
- generate_next_ref_frame_map(pbi);
-
- // Reload the adapted CDFs from when we originally coded this keyframe
- *cm->fc = cm->next_ref_frame_map[existing_frame_idx]->frame_context;
}
static INLINE void reset_frame_buffers(AV1_COMMON *cm) {
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
int i;
- // We have not stored any references to frame buffers in
- // cm->next_ref_frame_map, so we can directly reset it to all NULL.
- for (i = 0; i < REF_FRAMES; ++i) {
- cm->next_ref_frame_map[i] = NULL;
- }
-
lock_buffer_pool(cm->buffer_pool);
reset_ref_frame_map(cm);
assert(cm->cur_frame->ref_count == 1);
@@ -4703,9 +4662,8 @@
lock_buffer_pool(pool);
assert(frame_to_show->ref_count > 0);
// cm->cur_frame should be the buffer referenced by the return value
- // of the get_free_fb() call in av1_receive_compressed_data(), and
- // generate_next_ref_frame_map() has not been called, so ref_count
- // should still be 1.
+ // of the get_free_fb() call in assign_cur_frame_new_fb() (called by
+ // av1_receive_compressed_data()), so the ref_count should be 1.
assert(cm->cur_frame->ref_count == 1);
// assign_frame_buffer_p() decrements ref_count directly rather than
// call decrease_ref_count(). If cm->cur_frame->raw_frame_buffer has
@@ -5135,8 +5093,6 @@
" state");
}
- generate_next_ref_frame_map(pbi);
-
if (cm->allow_intrabc) {
// Set parameters corresponding to no filtering.
struct loopfilter *lf = &cm->lf;
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 4cef5e6..ecd267e 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -138,7 +138,6 @@
// Initialize the references to not point to any frame buffers.
for (int i = 0; i < REF_FRAMES; i++) {
cm->ref_frame_map[i] = NULL;
- cm->next_ref_frame_map[i] = NULL;
}
cm->current_frame.frame_number = 0;
@@ -356,22 +355,12 @@
return cm->error.error_code;
}
-static void release_frame_buffers(AV1Decoder *pbi) {
+static void release_current_frame(AV1Decoder *pbi) {
AV1_COMMON *const cm = &pbi->common;
BufferPool *const pool = cm->buffer_pool;
cm->cur_frame->buf.corrupted = 1;
lock_buffer_pool(pool);
- // Release all the reference buffers in cm->next_ref_frame_map if the worker
- // thread is holding them.
- if (pbi->hold_ref_buf) {
- for (int ref_index = 0; ref_index < REF_FRAMES; ++ref_index) {
- decrease_ref_count(cm->next_ref_frame_map[ref_index], pool);
- cm->next_ref_frame_map[ref_index] = NULL;
- }
- pbi->hold_ref_buf = 0;
- }
- // Release current frame.
decrease_ref_count(cm->cur_frame, pool);
unlock_buffer_pool(pool);
cm->cur_frame = NULL;
@@ -382,7 +371,7 @@
//
// This functions returns void. It reports failure by setting
// cm->error.error_code.
-static void swap_frame_buffers(AV1Decoder *pbi, int frame_decoded) {
+static void update_frame_buffers(AV1Decoder *pbi, int frame_decoded) {
int ref_index = 0, mask;
AV1_COMMON *const cm = &pbi->common;
BufferPool *const pool = cm->buffer_pool;
@@ -391,33 +380,19 @@
lock_buffer_pool(pool);
// In ext-tile decoding, the camera frame header is only decoded once. So,
- // we don't release the references here.
+ // we don't update the references here.
if (!pbi->camera_frame_header_ready) {
- // If we are not holding reference buffers in cm->next_ref_frame_map,
- // assert that the following two for loops are no-ops.
- assert(IMPLIES(!pbi->hold_ref_buf,
- cm->current_frame.refresh_frame_flags == 0));
- assert(IMPLIES(!pbi->hold_ref_buf,
- cm->show_existing_frame && !pbi->reset_decoder_state));
-
- // The following two for loops need to release the reference stored in
- // cm->ref_frame_map[ref_index] before transferring the reference stored
- // in cm->next_ref_frame_map[ref_index] to cm->ref_frame_map[ref_index].
+ // The following for loop needs to release the reference stored in
+ // cm->ref_frame_map[ref_index] before storing a reference to
+ // cm->cur_frame in cm->ref_frame_map[ref_index].
for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) {
- decrease_ref_count(cm->ref_frame_map[ref_index], pool);
- cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
- cm->next_ref_frame_map[ref_index] = NULL;
+ if (mask & 1) {
+ decrease_ref_count(cm->ref_frame_map[ref_index], pool);
+ cm->ref_frame_map[ref_index] = cm->cur_frame;
+ ++cm->cur_frame->ref_count;
+ }
++ref_index;
}
-
- const int check_on_show_existing_frame =
- !cm->show_existing_frame || pbi->reset_decoder_state;
- for (; ref_index < REF_FRAMES && check_on_show_existing_frame;
- ++ref_index) {
- decrease_ref_count(cm->ref_frame_map[ref_index], pool);
- cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
- cm->next_ref_frame_map[ref_index] = NULL;
- }
}
if (cm->show_existing_frame || cm->show_frame) {
@@ -448,10 +423,6 @@
unlock_buffer_pool(pool);
} else {
- // The code here assumes we are not holding reference buffers in
- // cm->next_ref_frame_map. If this assertion fails, we are leaking the
- // frame buffer references in cm->next_ref_frame_map.
- assert(IMPLIES(!pbi->camera_frame_header_ready, !pbi->hold_ref_buf));
// Nothing was decoded, so just drop this frame buffer
lock_buffer_pool(pool);
decrease_ref_count(cm->cur_frame, pool);
@@ -460,8 +431,6 @@
cm->cur_frame = NULL;
if (!pbi->camera_frame_header_ready) {
- pbi->hold_ref_buf = 0;
-
// Invalidate these references until the next frame starts.
for (ref_index = 0; ref_index < INTER_REFS_PER_FRAME; ref_index++) {
cm->remapped_ref_idx[ref_index] = INVALID_IDX;
@@ -494,8 +463,6 @@
return 1;
}
- if (!pbi->camera_frame_header_ready) pbi->hold_ref_buf = 0;
-
// The jmp_buf is valid only for the duration of the function that calls
// setjmp(). Therefore, this function must reset the 'setjmp' field to 0
// before it returns.
@@ -512,7 +479,7 @@
winterface->sync(&pbi->tile_workers[i]);
}
- release_frame_buffers(pbi);
+ release_current_frame(pbi);
aom_clear_system_state();
return -1;
}
@@ -524,7 +491,7 @@
if (frame_decoded < 0) {
assert(cm->error.error_code != AOM_CODEC_OK);
- release_frame_buffers(pbi);
+ release_current_frame(pbi);
cm->error.setjmp = 0;
return 1;
}
@@ -539,8 +506,8 @@
#endif
// Note: At this point, this function holds a reference to cm->cur_frame
- // in the buffer pool. This reference is consumed by swap_frame_buffers().
- swap_frame_buffers(pbi, frame_decoded);
+ // in the buffer pool. This reference is consumed by update_frame_buffers().
+ update_frame_buffers(pbi, frame_decoded);
if (frame_decoded) {
pbi->decoding_first_frame = 0;
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index b70630f..140ff4f 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -197,9 +197,7 @@
int allow_lowbitdepth;
int max_threads;
int inv_tile_order;
- int need_resync; // wait for key/intra-only frame.
- int hold_ref_buf; // Boolean: whether we are holding reference buffers in
- // common.next_ref_frame_map.
+ int need_resync; // wait for key/intra-only frame.
int reset_decoder_state;
int tile_size_bytes;
diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc
index 11b8ff3..1f10a2b 100644
--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -144,6 +144,7 @@
{ 1, "invalid-oss-fuzz-11479.ivf", "invalid-oss-fuzz-11479.ivf.res.2" },
{ 1, "invalid-oss-fuzz-11523.ivf", "invalid-oss-fuzz-11523.ivf.res.2" },
{ 4, "invalid-oss-fuzz-15363.ivf", NULL },
+ { 1, "invalid-oss-fuzz-16437.ivf", NULL },
};
AV1_INSTANTIATE_TEST_CASE(InvalidFileTest,
diff --git a/test/test-data.sha1 b/test/test-data.sha1
index b2c8d6e..d162885 100644
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -30,6 +30,8 @@
3198c7af55a7d50173ce3c369c0cf2d9cdfface6 *invalid-oss-fuzz-11523.ivf.res.2
cb445173be760c3554f1740ce4d119f57a7be043 *invalid-oss-fuzz-15363.ivf
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-oss-fuzz-15363.ivf.res
+5b697360bf0f02de31bae9b8da78e93570958fa4 *invalid-oss-fuzz-16437.ivf
+09d2af8dd22201dd8d48e5dcfcaed281ff9422c7 *invalid-oss-fuzz-16437.ivf.res
ccbe4081557eb44820a0e6337c4a094421826b9a *invalid-oss-fuzz-9288.ivf
67c54283fe1a26ccf02cc991e4f9a1eea3ac5e78 *invalid-oss-fuzz-9288.ivf.res
c0960f032484579f967881cc025b71cfd7a79ee1 *invalid-oss-fuzz-9463.ivf
diff --git a/test/test_data_util.cmake b/test/test_data_util.cmake
index 79aa88f..3206f59 100644
--- a/test/test_data_util.cmake
+++ b/test/test_data_util.cmake
@@ -547,6 +547,8 @@
"invalid-oss-fuzz-11523.ivf.res.2"
"invalid-oss-fuzz-15363.ivf"
"invalid-oss-fuzz-15363.ivf.res"
+ "invalid-oss-fuzz-16437.ivf"
+ "invalid-oss-fuzz-16437.ivf.res"
"invalid-oss-fuzz-9288.ivf"
"invalid-oss-fuzz-9288.ivf.res"
"invalid-oss-fuzz-9463.ivf"