Not signal reference_mode if one ref avaialble Use the frame ID that indicates the frame display order to identify whether two different reference frames exist for inter-coded frames. If there is only one unique reference valid in the reference buffer, there is no need to signal reference_mode. Instead, the decoder may identify such scenario and set reference_mode to SINGLE_REFERENCE. Change-Id: If7d374f5355f153c50b408be5a9956a833c976c3
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h index 26b7c50..df42044 100644 --- a/av1/common/mvref_common.h +++ b/av1/common/mvref_common.h
@@ -367,6 +367,38 @@ return 0; } +static INLINE int av1_is_compound_reference_allowed(const AV1_COMMON *cm) { + if (frame_is_intra_only(cm)) return 0; +#if CONFIG_FRAME_MARKER + // Check whether two different reference frames exist. + int ref, ref_offset0; + int is_comp_allowed = 0; + + for (ref = 0; ref < INTER_REFS_PER_FRAME; ++ref) { + const int buf_idx = cm->frame_refs[ref].idx; + if (buf_idx == INVALID_IDX) continue; + ref_offset0 = cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset; + ref++; + break; + } + + for (; ref < INTER_REFS_PER_FRAME; ++ref) { + const int buf_idx = cm->frame_refs[ref].idx; + if (buf_idx == INVALID_IDX) continue; + const int ref_offset = + cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset; + if (ref_offset != ref_offset0) { + is_comp_allowed = 1; + break; + } + } + + return is_comp_allowed; +#else + return 1; +#endif // CONFIG_FRAME_MARKER +} + #if CONFIG_FRAME_MARKER static INLINE int av1_refs_are_one_sided(const AV1_COMMON *cm) { assert(!frame_is_intra_only(cm));
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 64d3210..23073e8 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -89,10 +89,6 @@ static size_t read_uncompressed_header(AV1Decoder *pbi, struct aom_read_bit_buffer *rb); -static int is_compound_reference_allowed(const AV1_COMMON *cm) { - return !frame_is_intra_only(cm); -} - static void setup_compound_reference_mode(AV1_COMMON *cm) { cm->comp_fwd_ref[0] = LAST_FRAME; cm->comp_fwd_ref[1] = LAST2_FRAME; @@ -129,7 +125,7 @@ static REFERENCE_MODE read_frame_reference_mode( const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { - if (is_compound_reference_allowed(cm)) { + if (av1_is_compound_reference_allowed(cm)) { #if CONFIG_REF_ADAPT return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE; #else
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index a918abc..6aff5f4 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -3940,14 +3940,8 @@ mismatch_reset_frame(); #endif - // In the longer term the encoder should be generalized to match the - // decoder such that we allow compound where one of the 3 buffers has a - // different sign bias and that buffer is then the fixed ref. However, this - // requires further work in the rd loop. For now the only supported encoder - // side behavior is where the ALT ref buffer has opposite sign bias to - // the other two. - if (!frame_is_intra_only(cm)) { - cpi->allow_comp_inter_inter = 1; + cpi->allow_comp_inter_inter = av1_is_compound_reference_allowed(cm); + if (cpi->allow_comp_inter_inter) { cm->comp_fwd_ref[0] = LAST_FRAME; cm->comp_fwd_ref[1] = LAST2_FRAME; cm->comp_fwd_ref[2] = LAST3_FRAME; @@ -3955,8 +3949,6 @@ cm->comp_bwd_ref[0] = BWDREF_FRAME; cm->comp_bwd_ref[1] = ALTREF2_FRAME; cm->comp_bwd_ref[2] = ALTREF_FRAME; - } else { - cpi->allow_comp_inter_inter = 0; } if (cpi->sf.frame_parameter_update) {