ref: 74f574eab43f36bd02df4319c65ae8b2a332100d
parent: e9bb49f5d9bc41f28b08cf887276fd38f0962f4f
author: Ronald S. Bultje <rsbultje@gmail.com>
date: Mon Oct 22 15:45:17 EDT 2018
Rename unset_hp_bit() to fix_mv_precision() and add integer-mv support. Also prevent using warped motion when force_integer_mv=1. Fixes #84.
--- a/src/decode.c
+++ b/src/decode.c
@@ -1308,10 +1308,8 @@
b->mv[0] = mvstack[0].this_mv;
b->mv[1] = mvstack[0].comp_mv;
- if (!f->frame_hdr.hp) {
- unset_hp_bit(&b->mv[0]);
- unset_hp_bit(&b->mv[1]);
- }
+ fix_mv_precision(&f->frame_hdr, &b->mv[0]);
+ fix_mv_precision(&f->frame_hdr, &b->mv[1]);
if (DEBUG_BLOCK_INFO)
printf("Post-skipmodeblock[mv=1:y=%d,x=%d,2:y=%d,x=%d,refs=%d+%d\n",
b->mv[0].y, b->mv[0].x, b->mv[1].y, b->mv[1].x,
@@ -1431,7 +1429,7 @@
case NEARMV: \
case NEARESTMV: \
b->mv[idx] = mvstack[b->drl_idx].pfx##_mv; \
- if (!f->frame_hdr.hp) unset_hp_bit(&b->mv[idx]); \
+ fix_mv_precision(&f->frame_hdr, &b->mv[idx]); \
break; \
case GLOBALMV: \
has_subpel_filter |= \
@@ -1438,6 +1436,7 @@
f->frame_hdr.gmv[b->ref[idx]].type == WM_TYPE_TRANSLATION; \
b->mv[idx] = get_gmv_2d(&f->frame_hdr.gmv[b->ref[idx]], \
t->bx, t->by, bw4, bh4, &f->frame_hdr); \
+ fix_mv_precision(&f->frame_hdr, &b->mv[idx]); \
break; \
case NEWMV: \
b->mv[idx] = mvstack[b->drl_idx].pfx##_mv; \
@@ -1557,6 +1556,7 @@
b->inter_mode = GLOBALMV;
b->mv[0] = get_gmv_2d(&f->frame_hdr.gmv[b->ref[0]],
t->bx, t->by, bw4, bh4, &f->frame_hdr);
+ fix_mv_precision(&f->frame_hdr, &b->mv[0]);
has_subpel_filter = imin(bw4, bh4) == 1 ||
f->frame_hdr.gmv[b->ref[0]].type == WM_TYPE_TRANSLATION;
} else {
@@ -1585,7 +1585,7 @@
b->mv[0] = mvstack[b->drl_idx].this_mv;
} else {
b->mv[0] = mvlist[0][b->drl_idx];
- if (!f->frame_hdr.hp) unset_hp_bit(&b->mv[0]);
+ fix_mv_precision(&f->frame_hdr, &b->mv[0]);
}
}
@@ -1611,7 +1611,7 @@
b->mv[0] = mvstack[b->drl_idx].this_mv;
} else {
b->mv[0] = mvlist[0][0];
- if (!f->frame_hdr.hp) unset_hp_bit(&b->mv[0]);
+ fix_mv_precision(&f->frame_hdr, &b->mv[0]);
}
if (DEBUG_BLOCK_INFO)
printf("Post-intermode[%d,drl=%d]: r=%d\n",
--- a/src/recon.c
+++ b/src/recon.c
@@ -1084,7 +1084,7 @@
const Dav1dThreadPicture *const refp = &f->refp[b->ref[0]];
const enum Filter2d filter_2d = b->filter2d;
- if (imin(bw4, bh4) > 1 &&
+ if (imin(bw4, bh4) > 1 && !f->frame_hdr.force_integer_mv &&
((b->inter_mode == GLOBALMV &&
f->frame_hdr.gmv[b->ref[0]].type > WM_TYPE_TRANSLATION) ||
(b->motion_mode == MM_WARP &&
@@ -1184,7 +1184,7 @@
mc(t, ((pixel *) f->cur.p.data[1 + pl]) + uvdstoff + h_off + v_off, NULL, f->cur.p.stride[1],
bw4, bh4, t->bx, t->by, 1 + pl, b->mv[0], refp, filter_2d);
} else {
- if (imin(cbw4, cbh4) > 1 &&
+ if (imin(cbw4, cbh4) > 1 && !f->frame_hdr.force_integer_mv &&
((b->inter_mode == GLOBALMV &&
f->frame_hdr.gmv[b->ref[0]].type > WM_TYPE_TRANSLATION) ||
(b->motion_mode == MM_WARP &&
@@ -1262,7 +1262,7 @@
for (int i = 0; i < 2; i++) {
const Dav1dThreadPicture *const refp = &f->refp[b->ref[i]];
- if (b->inter_mode == GLOBALMV_GLOBALMV &&
+ if (b->inter_mode == GLOBALMV_GLOBALMV && !f->frame_hdr.force_integer_mv &&
f->frame_hdr.gmv[b->ref[i]].type > WM_TYPE_TRANSLATION)
{
warp_affine(t, NULL, tmp[i], bw4 * 4, b_dim, 0, refp,
@@ -1303,7 +1303,7 @@
for (int i = 0; i < 2; i++) {
const Dav1dThreadPicture *const refp = &f->refp[b->ref[i]];
if (b->inter_mode == GLOBALMV_GLOBALMV &&
- imin(cbw4, cbh4) > 1 &&
+ imin(cbw4, cbh4) > 1 && !f->frame_hdr.force_integer_mv &&
f->frame_hdr.gmv[b->ref[i]].type > WM_TYPE_TRANSLATION)
{
warp_affine(t, NULL, tmp[i], bw4 * 2, b_dim, 1 + pl,
--- a/src/ref_mvs.h
+++ b/src/ref_mvs.h
@@ -156,15 +156,25 @@
} while (--bh4);
}
-// FIXME integer_mv
-static inline void unset_hp_bit(mv *const a) {
- if (a->x & 1) {
- if (a->x < 0) a->x++;
- else a->x--;
- }
- if (a->y & 1) {
- if (a->y < 0) a->y++;
- else a->y--;
+static inline void fix_mv_precision(const Av1FrameHeader *const hdr,
+ mv *const mv)
+{
+ if (hdr->force_integer_mv) {
+ const int xmod = mv->x & 7;
+ mv->x &= ~7;
+ mv->x += (xmod > 4 - (mv->x < 0)) << 3;
+ const int ymod = mv->y & 7;
+ mv->y &= ~7;
+ mv->y += (ymod > 4 - (mv->y < 0)) << 3;
+ } else if (!hdr->hp) {
+ if (mv->x & 1) {
+ if (mv->x < 0) mv->x++;
+ else mv->x--;
+ }
+ if (mv->y & 1) {
+ if (mv->y < 0) mv->y++;
+ else mv->y--;
+ }
}
}