summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/common/mvref_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/common/mvref_common.c')
-rw-r--r--third_party/aom/av1/common/mvref_common.c291
1 files changed, 276 insertions, 15 deletions
diff --git a/third_party/aom/av1/common/mvref_common.c b/third_party/aom/av1/common/mvref_common.c
index d558111b5..fdbcebcd1 100644
--- a/third_party/aom/av1/common/mvref_common.c
+++ b/third_party/aom/av1/common/mvref_common.c
@@ -840,17 +840,21 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
#endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
- av1_set_ref_frame(rf, ref_frame);
- zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
- cm->allow_high_precision_mv, bsize,
- mi_col, mi_row, 0)
- .as_int;
- zeromv[1].as_int = (rf[1] != NONE_FRAME)
- ? gm_get_motion_vector(&cm->global_motion[rf[1]],
- cm->allow_high_precision_mv,
- bsize, mi_col, mi_row, 0)
- .as_int
- : 0;
+ if (!CONFIG_INTRABC || ref_frame != INTRA_FRAME) {
+ av1_set_ref_frame(rf, ref_frame);
+ zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
+ cm->allow_high_precision_mv, bsize,
+ mi_col, mi_row, 0)
+ .as_int;
+ zeromv[1].as_int = (rf[1] != NONE_FRAME)
+ ? gm_get_motion_vector(&cm->global_motion[rf[1]],
+ cm->allow_high_precision_mv,
+ bsize, mi_col, mi_row, 0)
+ .as_int
+ : 0;
+ } else {
+ zeromv[0].as_int = zeromv[1].as_int = 0;
+ }
#else
zeromv[0].as_int = zeromv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
@@ -925,10 +929,10 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
assert(MAX_MV_REF_CANDIDATES == 2);
#if CONFIG_GLOBAL_MOTION
- zeromv.as_int =
- gm_get_motion_vector(&cm->global_motion[ref], cm->allow_high_precision_mv,
- mi->mbmi.sb_type, mi_col, mi_row, block)
- .as_int;
+ zeromv.as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
+ cm->allow_high_precision_mv,
+ mi->mbmi.sb_type, mi_col, mi_row, block)
+ .as_int;
#else
zeromv.as_int = 0;
#endif
@@ -991,6 +995,262 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
}
#if CONFIG_WARPED_MOTION
+#if WARPED_MOTION_SORT_SAMPLES
+static INLINE void record_samples(MB_MODE_INFO *mbmi, int *pts, int *pts_inref,
+ int *pts_mv, int global_offset_r,
+ int global_offset_c, int row_offset,
+ int sign_r, int col_offset, int sign_c) {
+ int bw = block_size_wide[mbmi->sb_type];
+ int bh = block_size_high[mbmi->sb_type];
+ int cr_offset = row_offset * MI_SIZE + sign_r * AOMMAX(bh, MI_SIZE) / 2 - 1;
+ int cc_offset = col_offset * MI_SIZE + sign_c * AOMMAX(bw, MI_SIZE) / 2 - 1;
+ int x = cc_offset + global_offset_c;
+ int y = cr_offset + global_offset_r;
+
+ pts[0] = (x * 8);
+ pts[1] = (y * 8);
+ pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
+ pts_inref[1] = (y * 8) + mbmi->mv[0].as_mv.row;
+ pts_mv[0] = mbmi->mv[0].as_mv.col;
+ pts_mv[1] = mbmi->mv[0].as_mv.row;
+}
+
+// Only sort pts and pts_inref, and pts_mv is not sorted.
+#define TRIM_THR 16
+int sortSamples(int *pts_mv, MV *mv, int *pts, int *pts_inref, int len) {
+ int pts_mvd[SAMPLES_ARRAY_SIZE] = { 0 };
+ int i, j, k;
+ int ret = len;
+
+ for (i = 0; i < len; ++i)
+ pts_mvd[i] =
+ abs(pts_mv[2 * i] - mv->col) + abs(pts_mv[2 * i + 1] - mv->row);
+
+ for (i = 1; i <= len - 1; ++i) {
+ for (j = 0; j < i; ++j) {
+ if (pts_mvd[j] > pts_mvd[i]) {
+ int temp, tempi, tempj, ptempi, ptempj;
+
+ temp = pts_mvd[i];
+ tempi = pts[2 * i];
+ tempj = pts[2 * i + 1];
+ ptempi = pts_inref[2 * i];
+ ptempj = pts_inref[2 * i + 1];
+
+ for (k = i; k > j; k--) {
+ pts_mvd[k] = pts_mvd[k - 1];
+ pts[2 * k] = pts[2 * (k - 1)];
+ pts[2 * k + 1] = pts[2 * (k - 1) + 1];
+ pts_inref[2 * k] = pts_inref[2 * (k - 1)];
+ pts_inref[2 * k + 1] = pts_inref[2 * (k - 1) + 1];
+ }
+
+ pts_mvd[j] = temp;
+ pts[2 * j] = tempi;
+ pts[2 * j + 1] = tempj;
+ pts_inref[2 * j] = ptempi;
+ pts_inref[2 * j + 1] = ptempj;
+ break;
+ }
+ }
+ }
+
+ for (i = len - 1; i >= 1; i--) {
+ int low = (i == 1) ? 1 : AOMMAX((pts_mvd[i - 1] - pts_mvd[0]) / (i - 1), 1);
+
+ if ((pts_mvd[i] - pts_mvd[i - 1]) >= TRIM_THR * low) ret = i;
+ }
+
+ if (ret > LEAST_SQUARES_SAMPLES_MAX) ret = LEAST_SQUARES_SAMPLES_MAX;
+ return ret;
+}
+
+// Note: Samples returned are at 1/8-pel precision
+int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
+ int *pts, int *pts_inref, int *pts_mv) {
+ MB_MODE_INFO *const mbmi0 = &(xd->mi[0]->mbmi);
+ int ref_frame = mbmi0->ref_frame[0];
+ int up_available = xd->up_available;
+ int left_available = xd->left_available;
+ int i, mi_step = 1, np = 0, n, j, k;
+ int global_offset_c = mi_col * MI_SIZE;
+ int global_offset_r = mi_row * MI_SIZE;
+
+ const TileInfo *const tile = &xd->tile;
+ // Search nb range in the unit of mi
+ int bs =
+ (AOMMAX(xd->n8_w, xd->n8_h) > 1) ? (AOMMAX(xd->n8_w, xd->n8_h) >> 1) : 1;
+ int marked[16 * 32]; // max array size for 128x128
+ int do_tl = 1;
+ int do_tr = 1;
+
+ // scan the above rows
+ if (up_available) {
+ for (n = 0; n < bs; n++) {
+ int mi_row_offset = -1 * (n + 1);
+
+ if (!n) {
+ MODE_INFO *mi = xd->mi[mi_row_offset * xd->mi_stride];
+ MB_MODE_INFO *mbmi = &mi->mbmi;
+ uint8_t n8_w = mi_size_wide[mbmi->sb_type];
+
+ // Handle "current block width <= above block width" case.
+ if (xd->n8_w <= n8_w) {
+ int col_offset = -mi_col % n8_w;
+
+ if (col_offset < 0) do_tl = 0;
+ if (col_offset + n8_w > xd->n8_w) do_tr = 0;
+
+ if (mbmi->ref_frame[0] == ref_frame &&
+ mbmi->ref_frame[1] == NONE_FRAME) {
+ record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
+ global_offset_c, 0, -1, col_offset, 1);
+ pts += 2;
+ pts_inref += 2;
+ pts_mv += 2;
+ np++;
+ }
+ break;
+ }
+ }
+
+ // Handle "current block width > above block width" case.
+ if (!n) memset(marked, 0, bs * xd->n8_w * sizeof(*marked));
+
+ for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
+ int mi_col_offset = i;
+ MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
+ MB_MODE_INFO *mbmi = &mi->mbmi;
+ uint8_t n8_w = mi_size_wide[mbmi->sb_type];
+ uint8_t n8_h = mi_size_high[mbmi->sb_type];
+
+ mi_step = AOMMIN(xd->n8_w, n8_w);
+
+ // Processed already
+ if (marked[n * xd->n8_w + i]) continue;
+
+ for (j = 0; j < AOMMIN(bs, n8_h); j++)
+ for (k = 0; k < AOMMIN(xd->n8_w, n8_w); k++)
+ marked[(n + j) * xd->n8_w + i + k] = 1;
+
+ if (mbmi->ref_frame[0] == ref_frame &&
+ mbmi->ref_frame[1] == NONE_FRAME) {
+ record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
+ global_offset_c, -n, -1, i, 1);
+ pts += 2;
+ pts_inref += 2;
+ pts_mv += 2;
+ np++;
+ }
+ }
+ }
+ }
+ assert(2 * np <= SAMPLES_ARRAY_SIZE);
+
+ // scan the left columns
+ if (left_available) {
+ for (n = 0; n < bs; n++) {
+ int mi_col_offset = -1 * (n + 1);
+
+ if (!n) {
+ MODE_INFO *mi = xd->mi[mi_col_offset];
+ MB_MODE_INFO *mbmi = &mi->mbmi;
+ uint8_t n8_h = mi_size_high[mbmi->sb_type];
+
+ // Handle "current block height <= above block height" case.
+ if (xd->n8_h <= n8_h) {
+ int row_offset = -mi_row % n8_h;
+
+ if (row_offset < 0) do_tl = 0;
+
+ if (mbmi->ref_frame[0] == ref_frame &&
+ mbmi->ref_frame[1] == NONE_FRAME) {
+ record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
+ global_offset_c, row_offset, 1, 0, -1);
+ pts += 2;
+ pts_inref += 2;
+ pts_mv += 2;
+ np++;
+ }
+ break;
+ }
+ }
+
+ // Handle "current block height > above block height" case.
+ if (!n) memset(marked, 0, bs * xd->n8_h * sizeof(*marked));
+
+ for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
+ int mi_row_offset = i;
+ MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
+ MB_MODE_INFO *mbmi = &mi->mbmi;
+ uint8_t n8_w = mi_size_wide[mbmi->sb_type];
+ uint8_t n8_h = mi_size_high[mbmi->sb_type];
+
+ mi_step = AOMMIN(xd->n8_h, n8_h);
+
+ // Processed already
+ if (marked[n * xd->n8_h + i]) continue;
+
+ for (j = 0; j < AOMMIN(bs, n8_w); j++)
+ for (k = 0; k < AOMMIN(xd->n8_h, n8_h); k++)
+ marked[(n + j) * xd->n8_h + i + k] = 1;
+
+ if (mbmi->ref_frame[0] == ref_frame &&
+ mbmi->ref_frame[1] == NONE_FRAME) {
+ record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
+ global_offset_c, i, 1, -n, -1);
+ pts += 2;
+ pts_inref += 2;
+ pts_mv += 2;
+ np++;
+ }
+ }
+ }
+ }
+ assert(2 * np <= SAMPLES_ARRAY_SIZE);
+
+ // Top-left block
+ if (do_tl && left_available && up_available) {
+ int mi_row_offset = -1;
+ int mi_col_offset = -1;
+
+ MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
+ MB_MODE_INFO *mbmi = &mi->mbmi;
+
+ if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
+ record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
+ global_offset_c, 0, -1, 0, -1);
+ pts += 2;
+ pts_inref += 2;
+ pts_mv += 2;
+ np++;
+ }
+ }
+ assert(2 * np <= SAMPLES_ARRAY_SIZE);
+
+ // Top-right block
+ if (do_tr && has_top_right(xd, mi_row, mi_col, AOMMAX(xd->n8_w, xd->n8_h))) {
+ POSITION trb_pos = { -1, xd->n8_w };
+
+ if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &trb_pos)) {
+ int mi_row_offset = -1;
+ int mi_col_offset = xd->n8_w;
+
+ MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
+ MB_MODE_INFO *mbmi = &mi->mbmi;
+
+ if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
+ record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
+ global_offset_c, 0, -1, xd->n8_w, 1);
+ np++;
+ }
+ }
+ }
+ assert(2 * np <= SAMPLES_ARRAY_SIZE);
+
+ return np;
+}
+#else
void calc_projection_samples(MB_MODE_INFO *const mbmi, int x, int y,
int *pts_inref) {
pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
@@ -1095,4 +1355,5 @@ int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
return np;
}
+#endif // WARPED_MOTION_SORT_SAMPLES
#endif // CONFIG_WARPED_MOTION