Commit 57c36e18 authored by Pavel Frolov's avatar Pavel Frolov

Init cm->prev_frame before decoding gm params

This fixes global motion read/write mismatch.
Minimal test case would be 3 encoded frames with:
    1) frame0: KEY frame
    2) frame1: INTER frame with refresh_frame_flags not 0x00 and
not 0xFF, say 0x01 (refresh first slot)
    3) frame2: INTER frame with all reference indices equal to 3
(i.e. no reference to frame1)

When decoding frame2 decoder will use cm->prev_frame=frame1
for gm params decoding, then switch to cm->prev_frame=frame0
for the rest of the frame.
This makes frame2 dependent on frame1 which is not used as reference.
And also it is different from what encoder does.

BUG=aomedia:750

Change-Id: I42ba19c03d909286af12ba3149910693a12249e8
parent 91357ee9
......@@ -5076,6 +5076,45 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
cm->reduced_tx_set_used = aom_rb_read_bit(rb);
#endif // CONFIG_EXT_TX
#if CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
// NOTE(zoeliu): As cm->prev_frame can take neither a frame of
// show_exisiting_frame=1, nor can it take a frame not used as
// a reference, it is probable that by the time it is being
// referred to, the frame buffer it originally points to may
// already get expired and have been reassigned to the current
// newly coded frame. Hence, we need to check whether this is
// the case, and if yes, we have 2 choices:
// (1) Simply disable the use of previous frame mvs; or
// (2) Have cm->prev_frame point to one reference frame buffer,
// e.g. LAST_FRAME.
if (!dec_is_ref_frame_buf(pbi, cm->prev_frame)) {
// Reassign the LAST_FRAME buffer to cm->prev_frame.
cm->prev_frame =
cm->frame_refs[LAST_FRAME - LAST_FRAME].idx != INVALID_IDX
? &cm->buffer_pool
->frame_bufs[cm->frame_refs[LAST_FRAME - LAST_FRAME].idx]
: NULL;
}
#endif // CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
#if CONFIG_TEMPMV_SIGNALING
if (cm->use_prev_frame_mvs && !frame_can_use_prev_frame_mvs(cm)) {
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Frame wrongly requests previous frame MVs");
}
#else
cm->use_prev_frame_mvs = !cm->error_resilient_mode && cm->prev_frame &&
#if CONFIG_FRAME_SUPERRES
cm->width == cm->last_width &&
cm->height == cm->last_height &&
#else
cm->width == cm->prev_frame->buf.y_crop_width &&
cm->height == cm->prev_frame->buf.y_crop_height &&
#endif // CONFIG_FRAME_SUPERRES
!cm->last_intra_only && cm->last_show_frame &&
(cm->last_frame_type != KEY_FRAME);
#endif // CONFIG_TEMPMV_SIGNALING
#if CONFIG_GLOBAL_MOTION
if (!frame_is_intra_only(cm)) read_global_motion(cm, rb);
#endif
......@@ -5383,9 +5422,6 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
uint8_t clear_data[MAX_AV1_HEADER_SIZE];
size_t first_partition_size;
YV12_BUFFER_CONFIG *new_fb;
#if CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
RefBuffer *last_fb_ref_buf = &cm->frame_refs[LAST_FRAME - LAST_FRAME];
#endif // CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
#if CONFIG_ADAPT_SCAN
av1_deliver_eob_threshold(cm, xd);
......@@ -5447,43 +5483,6 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
cm->setup_mi(cm);
#if CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
// NOTE(zoeliu): As cm->prev_frame can take neither a frame of
// show_exisiting_frame=1, nor can it take a frame not used as
// a reference, it is probable that by the time it is being
// referred to, the frame buffer it originally points to may
// already get expired and have been reassigned to the current
// newly coded frame. Hence, we need to check whether this is
// the case, and if yes, we have 2 choices:
// (1) Simply disable the use of previous frame mvs; or
// (2) Have cm->prev_frame point to one reference frame buffer,
// e.g. LAST_FRAME.
if (!dec_is_ref_frame_buf(pbi, cm->prev_frame)) {
// Reassign the LAST_FRAME buffer to cm->prev_frame.
cm->prev_frame = last_fb_ref_buf->idx != INVALID_IDX
? &cm->buffer_pool->frame_bufs[last_fb_ref_buf->idx]
: NULL;
}
#endif // CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
#if CONFIG_TEMPMV_SIGNALING
if (cm->use_prev_frame_mvs && !frame_can_use_prev_frame_mvs(cm)) {
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
"Frame wrongly requests previous frame MVs");
}
#else
cm->use_prev_frame_mvs = !cm->error_resilient_mode && cm->prev_frame &&
#if CONFIG_FRAME_SUPERRES
cm->width == cm->last_width &&
cm->height == cm->last_height &&
#else
cm->width == cm->prev_frame->buf.y_crop_width &&
cm->height == cm->prev_frame->buf.y_crop_height &&
#endif // CONFIG_FRAME_SUPERRES
!cm->last_intra_only && cm->last_show_frame &&
(cm->last_frame_type != KEY_FRAME);
#endif // CONFIG_TEMPMV_SIGNALING
#if CONFIG_MFMV
av1_setup_frame_buf_refs(cm);
av1_setup_motion_field(cm);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment