Fix size of warp ref list
The warp ref list (WRL) and other related arrays were sized for
SINGLE_REF_FRAMES many entries. This value seems to be intended for
use with the compacted ref frame set (see COMPACT_INDEX0_NRS), which
includes intra and the TIP frame as possible references.
However, the WRL is only intended to be used with "true" single inter
refs at the moment, so these arrays only need to be sized for
INTER_REFS_PER_FRAME many entries.
As well as saving space, this fixes a bug caused by a mixup of the
compacted single ref set constructed by COMPACT_INDEX0_NRS,
and the combined ref index constructed by av1_ref_frame_type().
Specifically, the line
derive_wrl &= (ref_frame < SINGLE_REF_FRAMES);
ends up allowing the WRL to be derived for the TIP frame and for
compound blocks with the ref pair (0, 1). This behaviour is not
intended, and ends up leading to an out-of-bounds read of
xd->global_motion, since that only has INTER_REFS_PER_FRAME
many entries.
Note: As the modes which use the WRL are only enabled for single-ref
inter blocks, this does not affect the encoder or decoder output.
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 791bbf6..b87bb7d 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -1656,15 +1656,15 @@
/*!
* Number of warp parameters in the buffer.
*/
- int wpb_count[SINGLE_REF_FRAMES];
+ int wpb_count[INTER_REFS_PER_FRAME];
/*!
* Index corresponding to the first warp parameters in the buffer.
*/
- int wpb_start_idx[SINGLE_REF_FRAMES];
+ int wpb_start_idx[INTER_REFS_PER_FRAME];
/*!
* Circular buffer storing the warp parameters.
*/
- WarpedMotionParams wpb_buffer[SINGLE_REF_FRAMES][WARP_PARAM_BANK_SIZE];
+ WarpedMotionParams wpb_buffer[INTER_REFS_PER_FRAME][WARP_PARAM_BANK_SIZE];
/*!
* Total number of mbmi updates conducted in SB
*/
@@ -2011,11 +2011,12 @@
/*!
* warp_param_stack contains the predicted warp parameters
*/
- WARP_CANDIDATE warp_param_stack[SINGLE_REF_FRAMES][MAX_WARP_REF_CANDIDATES];
+ WARP_CANDIDATE warp_param_stack[INTER_REFS_PER_FRAME]
+ [MAX_WARP_REF_CANDIDATES];
/*!
* valid number of candidates in the warp_param_stack.
*/
- uint8_t valid_num_warp_candidates[SINGLE_REF_FRAMES];
+ uint8_t valid_num_warp_candidates[INTER_REFS_PER_FRAME];
#endif // CONFIG_WARP_REF_LIST
#if !CONFIG_EXT_RECUR_PARTITIONS
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index 9024d0d..b252844 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -2747,8 +2747,8 @@
// Initialize the warp parameter list
void av1_initialize_warp_wrl_list(
WARP_CANDIDATE warp_param_stack[][MAX_WARP_REF_CANDIDATES],
- uint8_t valid_num_warp_candidates[SINGLE_REF_FRAMES]) {
- for (int ref_frame = 0; ref_frame < SINGLE_REF_FRAMES; ref_frame++) {
+ uint8_t valid_num_warp_candidates[INTER_REFS_PER_FRAME]) {
+ for (int ref_frame = 0; ref_frame < INTER_REFS_PER_FRAME; ref_frame++) {
for (int warp_idx = 0; warp_idx < MAX_WARP_REF_CANDIDATES; warp_idx++) {
warp_param_stack[ref_frame][warp_idx].wm_params.invalid = 1;
}
@@ -2812,7 +2812,7 @@
,
WARP_CANDIDATE warp_param_stack[][MAX_WARP_REF_CANDIDATES],
int max_num_of_warp_candidates,
- uint8_t valid_num_warp_candidates[SINGLE_REF_FRAMES]
+ uint8_t valid_num_warp_candidates[INTER_REFS_PER_FRAME]
#endif // CONFIG_WARP_REF_LIST
) {
const int mi_row = xd->mi_row;
@@ -2869,7 +2869,7 @@
#if CONFIG_WARP_REF_LIST
bool derive_wrl = (warp_param_stack && valid_num_warp_candidates &&
max_num_of_warp_candidates);
- derive_wrl &= (ref_frame < SINGLE_REF_FRAMES);
+ derive_wrl &= (ref_frame < INTER_REFS_PER_FRAME);
derive_wrl &= is_motion_variation_allowed_bsize(mi->sb_type[PLANE_TYPE_Y],
mi_row, mi_col);
if (derive_wrl && valid_num_warp_candidates) {
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index 0e98ac8..9c88127 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -546,7 +546,7 @@
,
WARP_CANDIDATE warp_param_stack[][MAX_WARP_REF_CANDIDATES],
int max_num_of_warp_candidates,
- uint8_t valid_num_warp_candidates[SINGLE_REF_FRAMES]
+ uint8_t valid_num_warp_candidates[INTER_REFS_PER_FRAME]
#endif // CONFIG_WARP_REF_LIST
);
@@ -554,7 +554,7 @@
// Initialize the warp cadidate lists to invalid values
void av1_initialize_warp_wrl_list(
WARP_CANDIDATE warp_param_stack[][MAX_WARP_REF_CANDIDATES],
- uint8_t valid_num_warp_candidates[SINGLE_REF_FRAMES]);
+ uint8_t valid_num_warp_candidates[INTER_REFS_PER_FRAME]);
#endif // CONFIG_WARP_REF_LIST
// check a list of motion vectors by sad score using a number rows of pixels
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 3dfa75d..4b20c71 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -2573,17 +2573,18 @@
xd->valid_num_warp_candidates);
#endif // CONFIG_WARP_REF_LIST
- av1_find_mv_refs(cm, xd, mbmi, ref_frame, dcb->ref_mv_count, xd->ref_mv_stack,
- xd->weight, ref_mvs, /*global_mvs=*/NULL
+ av1_find_mv_refs(
+ cm, xd, mbmi, ref_frame, dcb->ref_mv_count, xd->ref_mv_stack, xd->weight,
+ ref_mvs, /*global_mvs=*/NULL
#if !CONFIG_C076_INTER_MOD_CTX
- ,
- inter_mode_ctx
+ ,
+ inter_mode_ctx
#endif // !CONFIG_C076_INTER_MOD_CTX
#if CONFIG_WARP_REF_LIST
- ,
- xd->warp_param_stack,
- ref_frame < SINGLE_REF_FRAMES ? MAX_WARP_REF_CANDIDATES : 0,
- xd->valid_num_warp_candidates
+ ,
+ xd->warp_param_stack,
+ ref_frame < INTER_REFS_PER_FRAME ? MAX_WARP_REF_CANDIDATES : 0,
+ xd->valid_num_warp_candidates
#endif // CONFIG_WARP_REF_LIST
);
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index a2a7024..4702b4f 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -252,7 +252,8 @@
/*!
* warp_param_stack is the warp candidate list.
*/
- WARP_CANDIDATE warp_param_stack[SINGLE_REF_FRAMES][MAX_WARP_REF_CANDIDATES];
+ WARP_CANDIDATE warp_param_stack[INTER_REFS_PER_FRAME]
+ [MAX_WARP_REF_CANDIDATES];
#endif // CONFIG_WARP_REF_LIST
} MB_MODE_INFO_EXT;
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index 8cbded4..5208d20 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -207,7 +207,7 @@
sizeof(mbmi_ext->global_mvs));
#if CONFIG_WARP_REF_LIST
- if (ref_frame_type < SINGLE_REF_FRAMES) {
+ if (ref_frame_type < INTER_REFS_PER_FRAME) {
memcpy(mbmi_ext->warp_param_stack[ref_frame_type],
mbmi_ext_best->warp_param_stack,
sizeof(mbmi_ext->warp_param_stack[MAX_WARP_REF_CANDIDATES]));
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 0ea4e81..455a74a 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -831,17 +831,18 @@
#endif // CONFIG_SKIP_MODE_DRL_WITH_REF_IDX
// Gets an initial list of candidate vectors from neighbours and orders them
- av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
- xd->ref_mv_stack, xd->weight, NULL, mbmi_ext->global_mvs
+ av1_find_mv_refs(
+ cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count, xd->ref_mv_stack,
+ xd->weight, NULL, mbmi_ext->global_mvs
#if !CONFIG_C076_INTER_MOD_CTX
- ,
- mbmi_ext->mode_context
+ ,
+ mbmi_ext->mode_context
#endif // !CONFIG_C076_INTER_MOD_CTX
#if CONFIG_WARP_REF_LIST
- ,
- xd->warp_param_stack,
- ref_frame < SINGLE_REF_FRAMES ? MAX_WARP_REF_CANDIDATES : 0,
- xd->valid_num_warp_candidates
+ ,
+ xd->warp_param_stack,
+ ref_frame < INTER_REFS_PER_FRAME ? MAX_WARP_REF_CANDIDATES : 0,
+ xd->valid_num_warp_candidates
#endif // CONFIG_WARP_REF_LIST
);
@@ -6559,7 +6560,7 @@
#if CONFIG_WARP_REF_LIST
,
xd->warp_param_stack,
- ref_frame < SINGLE_REF_FRAMES ? MAX_WARP_REF_CANDIDATES : 0,
+ ref_frame < INTER_REFS_PER_FRAME ? MAX_WARP_REF_CANDIDATES : 0,
xd->valid_num_warp_candidates
#endif // CONFIG_WARP_REF_LIST
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index 47685f4..15fdc0f 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -327,7 +327,7 @@
sizeof(mbmi_ext->global_mvs));
#if CONFIG_WARP_REF_LIST
- if (ref_frame_type < SINGLE_REF_FRAMES) {
+ if (ref_frame_type < INTER_REFS_PER_FRAME) {
memcpy(mbmi_ext_best->warp_param_stack,
mbmi_ext->warp_param_stack[ref_frame_type],
sizeof(mbmi_ext->warp_param_stack[MAX_WARP_REF_CANDIDATES]));