Temporary fix for resize tests Prior to this patch, the TestExternalResizeWorks tests were failing to encode after frame 43. This was because of an encoder optimisation that was failing to properly release frame buffers for scaled frames (and failing to re-order them correctly), thus resulting in it running out of free frame buffers from the buffer pool. Note that the tests were still passing, as they did not check that the number of decoded frames matched the number of frames that the test tried to encode. This patch makes three changes: - The optimisation mentioned above has been removed, i.e. all buffers relating to scaled frames are released at the end of each frame. Scaled frames are generated again if necessary when encoding subsequent frames. - Checks have been added to the resize tests to ensure that we do actually decode the same number of frames that we tried to encode. - The number of frames encoded in these tests has been reduced from 350 to 250. This is because the above changes now allow a separate test to proceed far enough to encounter a different bug. BUG=aomedia:1097 Change-Id: I9680d61b0f1c35ba0ccd2d1378a216c69738aaef
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index fa67389..d3ce31c 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -4313,6 +4313,7 @@ // LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME // when the LAST_FRAME is updated. static INLINE void shift_last_ref_frames(AV1_COMP *cpi) { + // TODO(isbs): shift the scaled indices as well int ref_frame; 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]; @@ -4633,37 +4634,14 @@ static void release_scaled_references(AV1_COMP *cpi) { AV1_COMMON *cm = &cpi->common; int i; - if (cpi->oxcf.pass == 0) { - // Only release scaled references under certain conditions: - // if reference will be updated, or if scaled reference has same resolution. - int refresh[INTER_REFS_PER_FRAME]; - refresh[0] = (cpi->refresh_last_frame) ? 1 : 0; - refresh[1] = refresh[2] = 0; - refresh[3] = (cpi->refresh_golden_frame) ? 1 : 0; - refresh[4] = (cpi->refresh_bwd_ref_frame) ? 1 : 0; - refresh[5] = (cpi->refresh_alt2_ref_frame) ? 1 : 0; - refresh[6] = (cpi->refresh_alt_ref_frame) ? 1 : 0; - for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { - const int idx = cpi->scaled_ref_idx[i - 1]; - RefCntBuffer *const buf = - idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL; - const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i); - if (buf != NULL && - (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width && - buf->buf.y_crop_height == ref->y_crop_height))) { - --buf->ref_count; - cpi->scaled_ref_idx[i - 1] = INVALID_IDX; - } - } - } else { - for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) { - const int idx = cpi->scaled_ref_idx[i]; - RefCntBuffer *const buf = - idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL; - if (buf != NULL) { - --buf->ref_count; - cpi->scaled_ref_idx[i] = INVALID_IDX; - } + // TODO(isbs): only refresh the necessary frames, rather than all of them + for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) { + const int idx = cpi->scaled_ref_idx[i]; + RefCntBuffer *const buf = + idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL; + if (buf != NULL) { + --buf->ref_count; + cpi->scaled_ref_idx[i] = INVALID_IDX; } } }
diff --git a/test/resize_test.cc b/test/resize_test.cc index 0b5586e..5fc6fe0 100644 --- a/test/resize_test.cc +++ b/test/resize_test.cc
@@ -247,7 +247,7 @@ public: ResizingVideoSource() { SetSize(kInitialWidth, kInitialHeight); - limit_ = 350; + limit_ = 250; } int flag_codec_; virtual ~ResizingVideoSource() {} @@ -291,6 +291,9 @@ cfg_.g_lag_in_frames = 0; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + // Check we decoded the same number of frames as we attempted to encode + ASSERT_EQ(frame_info_list_.size(), video.limit()); + for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin(); info != frame_info_list_.end(); ++info) { const unsigned int frame = static_cast<unsigned>(info->pts); @@ -505,6 +508,9 @@ mismatch_nframes_ = 0; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + // Check we decoded the same number of frames as we attempted to encode + ASSERT_EQ(frame_info_list_.size(), video.limit()); + for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin(); info != frame_info_list_.end(); ++info) { const unsigned int frame = static_cast<unsigned>(info->pts); @@ -706,6 +712,9 @@ cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48; cfg_.g_lag_in_frames = 0; ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + + // Check we decoded the same number of frames as we attempted to encode + ASSERT_EQ(frame_info_list_.size(), video.limit()); } AV1_INSTANTIATE_TEST_CASE(ResizeTest,