OSUOSL/Nero are experiencing Internet connectivity problems. This affects us as we're hosted with OSUOSL. We apologize for the inconvenience.

Commit 248b9563 authored by Jingning Han's avatar Jingning Han Committed by Yaowu Xu

[NORMATIVE] Limit valid frame distance for mfmv projection

Set the maximum frame distance to be 32. If a reference motion
vector needs to span across two frames at distance more than 32,
drop the use of this reference motion vector.

BUG=aomedia:1394

This also clears ubsan warnings in unit tests.

Change-Id: I98b72b5fd2a885661542bbc5f8da1886d77f889f
parent 44cb357e
...@@ -30,6 +30,9 @@ static int div_mult[64] = { ...@@ -30,6 +30,9 @@ static int div_mult[64] = {
// TODO(jingning): Consider the use of lookup table for (num / den) // TODO(jingning): Consider the use of lookup table for (num / den)
// altogether. // altogether.
static void get_mv_projection(MV *output, MV ref, int num, int den) { static void get_mv_projection(MV *output, MV ref, int num, int den) {
den = AOMMIN(den, MAX_FRAME_DISTANCE);
num = num > 0 ? AOMMIN(num, MAX_FRAME_DISTANCE)
: AOMMAX(num, -MAX_FRAME_DISTANCE);
output->row = output->row =
(int16_t)(ROUND_POWER_OF_TWO_SIGNED(ref.row * num * div_mult[den], 14)); (int16_t)(ROUND_POWER_OF_TWO_SIGNED(ref.row * num * div_mult[den], 14));
output->col = output->col =
...@@ -1651,9 +1654,16 @@ static int motion_field_projection(AV1_COMMON *cm, MV_REFERENCE_FRAME ref_frame, ...@@ -1651,9 +1654,16 @@ static int motion_field_projection(AV1_COMMON *cm, MV_REFERENCE_FRAME ref_frame,
int mi_r, mi_c; int mi_r, mi_c;
const int ref_frame_offset = ref_offset[mv_ref->ref_frame[dir & 0x01]]; const int ref_frame_offset = ref_offset[mv_ref->ref_frame[dir & 0x01]];
get_mv_projection(&this_mv.as_mv, fwd_mv, ref_to_cur, ref_frame_offset); int pos_valid = abs(ref_frame_offset) < MAX_FRAME_DISTANCE &&
int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col, abs(ref_to_cur) < MAX_FRAME_DISTANCE;
this_mv.as_mv, dir >> 1);
if (pos_valid) {
get_mv_projection(&this_mv.as_mv, fwd_mv, ref_to_cur,
ref_frame_offset);
pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
this_mv.as_mv, dir >> 1);
}
if (pos_valid) { if (pos_valid) {
int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c; int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
......
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