Commit 69f18e1a authored by Yue Chen's avatar Yue Chen

Add WARPED_MOTION experiment

Performance gain (REF_MV on by default)
WARPED_MOTION: 1.061%
WARPED_MOTION+MOTION_VAR: 2.917%
MOTION_VAR: 2.337%

Change-Id: I43f742a02cdd43d13ef333a0a15087062ad020ab
parent d326f763
......@@ -309,6 +309,10 @@ typedef struct {
int mi_row;
int mi_col;
#endif
#if CONFIG_WARPED_MOTION
int num_proj_ref[2];
WarpedMotionParams wm_params[2];
#endif // CONFIG_WARPED_MOTION
} MB_MODE_INFO;
typedef struct MODE_INFO {
......@@ -894,13 +898,27 @@ static INLINE int is_motion_variation_allowed_bsize(BLOCK_SIZE bsize) {
return (bsize >= BLOCK_8X8);
}
static INLINE int is_motion_variation_allowed(const MB_MODE_INFO *mbmi) {
static INLINE MOTION_MODE motion_mode_allowed(const MB_MODE_INFO *mbmi) {
#if CONFIG_EXT_INTER
return is_motion_variation_allowed_bsize(mbmi->sb_type) &&
mbmi->ref_frame[1] != INTRA_FRAME;
if (is_motion_variation_allowed_bsize(mbmi->sb_type) &&
is_inter_mode(mbmi->mode) && mbmi->ref_frame[1] != INTRA_FRAME) {
#else
return is_motion_variation_allowed_bsize(mbmi->sb_type);
if (is_motion_variation_allowed_bsize(mbmi->sb_type) &&
is_inter_mode(mbmi->mode)) {
#endif // CONFIG_EXT_INTER
#if CONFIG_WARPED_MOTION
if (!has_second_ref(mbmi) && mbmi->num_proj_ref[0] >= 3)
return WARPED_CAUSAL;
else
#endif // CONFIG_WARPED_MOTION
#if CONFIG_MOTION_VAR
return OBMC_CAUSAL;
#else
return SIMPLE_TRANSLATION;
#endif // CONFIG_MOTION_VAR
} else {
return SIMPLE_TRANSLATION;
}
}
#if CONFIG_MOTION_VAR
......
......@@ -530,6 +530,7 @@ static const aom_prob default_motion_mode_prob[BLOCK_SIZES]
const aom_tree_index av1_motion_mode_tree[TREE_SIZE(MOTION_MODES)] = {
-SIMPLE_TRANSLATION, -WARPED_CAUSAL
};
static const aom_prob default_motion_mode_prob[BLOCK_SIZES]
[MOTION_MODES - 1] = {
{ 255 }, { 255 }, { 255 },
......@@ -556,7 +557,15 @@ static const aom_prob default_motion_mode_prob[BLOCK_SIZES][MOTION_MODES - 1] =
{ 252, 200 }, { 252, 200 }, { 252, 200 },
#endif // CONFIG_EXT_PARTITION
};
#endif // CONFIG_MOTION_VAR || !CONFIG_WARPED_MOTION
// Probability for the case that only 1 additional motion mode is allowed
static const aom_prob default_obmc_prob[BLOCK_SIZES] = {
255, 255, 255, 151, 153, 144, 178, 165, 160, 207, 195, 168, 244,
#if CONFIG_EXT_PARTITION
252, 252, 252,
#endif // CONFIG_EXT_PARTITION
};
#endif
#if CONFIG_DELTA_Q
static const aom_prob default_delta_q_probs[DELTA_Q_CONTEXTS] = { 220, 220,
......@@ -1688,6 +1697,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
av1_copy(fc->motion_mode_prob, default_motion_mode_prob);
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
av1_copy(fc->obmc_prob, default_obmc_prob);
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_EXT_INTER
av1_copy(fc->inter_compound_mode_probs, default_inter_compound_mode_probs);
......@@ -1860,6 +1872,11 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
for (i = BLOCK_8X8; i < BLOCK_SIZES; ++i)
aom_tree_merge_probs(av1_motion_mode_tree, pre_fc->motion_mode_prob[i],
counts->motion_mode[i], fc->motion_mode_prob[i]);
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
for (i = BLOCK_8X8; i < BLOCK_SIZES; ++i)
fc->obmc_prob[i] =
av1_mode_mv_merge_probs(pre_fc->obmc_prob[i], counts->obmc[i]);
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_SUPERTX
......
......@@ -115,6 +115,9 @@ typedef struct frame_contexts {
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
aom_prob motion_mode_prob[BLOCK_SIZES][MOTION_MODES - 1];
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
aom_prob obmc_prob[BLOCK_SIZES];
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
aom_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
aom_prob comp_inter_prob[COMP_INTER_CONTEXTS];
......@@ -221,6 +224,9 @@ typedef struct FRAME_COUNTS {
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
unsigned int motion_mode[BLOCK_SIZES][MOTION_MODES];
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
unsigned int obmc[BLOCK_SIZES][2];
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
......
......@@ -10,6 +10,9 @@
*/
#include "av1/common/mvref_common.h"
#if CONFIG_WARPED_MOTION
#include "av1/common/warped_motion.h"
#endif // CONFIG_WARPED_MOTION
#if CONFIG_REF_MV
......@@ -884,3 +887,214 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
default: assert(0 && "Invalid block index.");
}
}
#if CONFIG_WARPED_MOTION
int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
double *pts, double *pts_inref) {
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, np = 0;
int mvasint[100];
int mvnumber = 0;
int global_offset_c = mi_col * 8;
int global_offset_r = mi_row * 8;
int samples_per_neighbor = 4;
// scan the above row
if (up_available) {
for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
int mi_row_offset = -1;
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;
mi_step = AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[mbmi->sb_type]);
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE) {
int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = -AOMMAX(bh, 8) / 2 - 1;
int cc_offset = i * 8 + AOMMAX(bw, 8) / 2 - 1;
int j;
int pixelperblock = samples_per_neighbor;
mvasint[mvnumber] = mbmi->mv[0].as_int;
mvnumber++;
for (j = 0; j < pixelperblock; j++) {
int r_offset = j / 2;
int c_offset = j % 2;
pts[0] = (double)(cc_offset + c_offset + global_offset_c);
pts[1] = (double)(cr_offset + r_offset + global_offset_r);
if (mbmi->motion_mode == WARPED_CAUSAL) {
int ipts[2], ipts_inref[2];
ipts[0] = cc_offset + c_offset + global_offset_c;
ipts[1] = cr_offset + r_offset + global_offset_r;
project_points(&mbmi->wm_params[0], ipts, ipts_inref, 1, 2, 2, 0,
0);
pts_inref[0] =
(double)ipts_inref[0] / (double)WARPEDPIXEL_PREC_SHIFTS;
pts_inref[1] =
(double)ipts_inref[1] / (double)WARPEDPIXEL_PREC_SHIFTS;
} else {
pts_inref[0] = pts[0] + (double)(mv_col)*0.125;
pts_inref[1] = pts[1] + (double)(mv_row)*0.125;
}
pts += 2;
pts_inref += 2;
}
np += pixelperblock;
}
}
}
// scan the left column
if (left_available) {
for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
int mi_row_offset = i;
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;
mi_step = AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[mbmi->sb_type]);
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE) {
int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = i * 8 + AOMMAX(bh, 8) / 2 - 1;
int cc_offset = -AOMMAX(bw, 8) / 2 - 1;
int j;
int pixelperblock = samples_per_neighbor;
mvasint[mvnumber] = mbmi->mv[0].as_int;
mvnumber++;
for (j = 0; j < pixelperblock; j++) {
int r_offset = j / 2;
int c_offset = j % 2;
pts[0] = (double)(cc_offset + c_offset + global_offset_c);
pts[1] = (double)(cr_offset + r_offset + global_offset_r);
if (mbmi->motion_mode == WARPED_CAUSAL) {
int ipts[2], ipts_inref[2];
ipts[0] = cc_offset + c_offset + global_offset_c;
ipts[1] = cr_offset + r_offset + global_offset_r;
project_points(&mbmi->wm_params[0], ipts, ipts_inref, 1, 2, 2, 0,
0);
pts_inref[0] =
(double)ipts_inref[0] / (double)WARPEDPIXEL_PREC_SHIFTS;
pts_inref[1] =
(double)ipts_inref[1] / (double)WARPEDPIXEL_PREC_SHIFTS;
} else {
pts_inref[0] = pts[0] + (double)(mv_col)*0.125;
pts_inref[1] = pts[1] + (double)(mv_row)*0.125;
}
pts += 2;
pts_inref += 2;
}
np += pixelperblock;
}
}
}
if (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) {
int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = -AOMMAX(bh, 8) / 2 - 1;
int cc_offset = -AOMMAX(bw, 8) / 2 - 1;
int j;
int pixelperblock = samples_per_neighbor;
mvasint[mvnumber] = mbmi->mv[0].as_int;
mvnumber++;
for (j = 0; j < pixelperblock; j++) {
int r_offset = j / 2;
int c_offset = j % 2;
pts[0] = (double)(cc_offset + c_offset + global_offset_c);
pts[1] = (double)(cr_offset + r_offset + global_offset_r);
if (mbmi->motion_mode == WARPED_CAUSAL) {
int ipts[2], ipts_inref[2];
ipts[0] = cc_offset + c_offset + global_offset_c;
ipts[1] = cr_offset + r_offset + global_offset_r;
project_points(&mbmi->wm_params[0], ipts, ipts_inref, 1, 2, 2, 0, 0);
pts_inref[0] =
(double)ipts_inref[0] / (double)WARPEDPIXEL_PREC_SHIFTS;
pts_inref[1] =
(double)ipts_inref[1] / (double)WARPEDPIXEL_PREC_SHIFTS;
} else {
pts_inref[0] = pts[0] + (double)(mv_col)*0.125;
pts_inref[1] = pts[1] + (double)(mv_row)*0.125;
}
pts += 2;
pts_inref += 2;
}
np += pixelperblock;
}
}
for (i = 0; i < (mvnumber - 1); ++i) {
if (mvasint[i] != mvasint[i + 1]) break;
}
if (np == 0 || i == (mvnumber - 1)) {
return 0;
} else {
MODE_INFO *mi = xd->mi[0];
MB_MODE_INFO *mbmi = &mi->mbmi;
int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = AOMMAX(bh, 8) / 2 - 1;
int cc_offset = AOMMAX(bw, 8) / 2 - 1;
int j;
int pixelperblock = samples_per_neighbor;
for (j = 0; j < pixelperblock; j++) {
int r_offset = j / 2;
int c_offset = j % 2;
pts[0] = (double)(cc_offset + c_offset + global_offset_c);
pts[1] = (double)(cr_offset + r_offset + global_offset_r);
pts_inref[0] = pts[0] + (double)(mv_col)*0.125;
pts_inref[1] = pts[1] + (double)(mv_row)*0.125;
pts += 2;
pts_inref += 2;
}
np += pixelperblock;
}
return np;
}
#endif // CONFIG_WARPED_MOTION
......@@ -488,6 +488,11 @@ void av1_update_mv_context(const MACROBLOCKD *xd, MODE_INFO *mi,
int16_t *mode_context);
#endif // CONFIG_EXT_INTER
#if CONFIG_WARPED_MOTION
int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
double *pts, double *pts_inref);
#endif // CONFIG_WARPED_MOTION
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -24,9 +24,9 @@
#if CONFIG_MOTION_VAR
#include "av1/common/onyxc_int.h"
#endif // CONFIG_MOTION_VAR
#if CONFIG_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
#include "av1/common/warped_motion.h"
#endif // CONFIG_GLOBAL_MOTION
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
#if CONFIG_EXT_INTER
......@@ -1377,12 +1377,30 @@ void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
mi_x, mi_y);
}
} else {
build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
0, 0, bw, bh,
#if CONFIG_WARPED_MOTION
if (above_mbmi->motion_mode == WARPED_CAUSAL) {
av1_warp_plane(&above_mbmi->wm_params[0],
#if CONFIG_AOM_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
pd->pre[0].stride, pd->dst.buf,
(((mi_col + i) * MI_SIZE) >> pd->subsampling_x),
((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh,
pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
16, 16, 0);
} else {
#endif // CONFIG_WARPED_MOTION
build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
0, 0, bw, bh,
#if CONFIG_SUPERTX && CONFIG_EXT_INTER
0, 0,
0, 0,
#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
mi_x, mi_y);
mi_x, mi_y);
#if CONFIG_WARPED_MOTION
}
#endif // CONFIG_WARPED_MOTION
}
}
#if CONFIG_EXT_INTER
......@@ -1480,12 +1498,30 @@ void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
mi_x, mi_y);
}
} else {
build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
0, 0, bw, bh,
#if CONFIG_WARPED_MOTION
if (left_mbmi->motion_mode == WARPED_CAUSAL) {
av1_warp_plane(&left_mbmi->wm_params[0],
#if CONFIG_AOM_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
pd->pre[0].stride, pd->dst.buf,
((mi_col * MI_SIZE) >> pd->subsampling_x),
(((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw,
bh, pd->dst.stride, pd->subsampling_x,
pd->subsampling_y, 16, 16, 0);
} else {
#endif // CONFIG_WARPED_MOTION
build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
0, 0, bw, bh,
#if CONFIG_SUPERTX && CONFIG_EXT_INTER
0, 0,
0, 0,
#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
mi_x, mi_y);
mi_x, mi_y);
#if CONFIG_WARPED_MOTION
}
#endif // CONFIG_WARPED_MOTION
}
}
#if CONFIG_EXT_INTER
......
......@@ -210,6 +210,29 @@ void project_points_homography(int32_t *mat, int *points, int *proj,
}
}
// 'points' are at original scale, output 'proj's are scaled up by
// 1 << WARPEDPIXEL_PREC_BITS
void project_points(WarpedMotionParams *wm_params, int *points, int *proj,
const int n, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y) {
switch (wm_params->wmtype) {
case AFFINE:
project_points_affine(wm_params->wmmat, points, proj, n, stride_points,
stride_proj, subsampling_x, subsampling_y);
break;
case ROTZOOM:
project_points_rotzoom(wm_params->wmmat, points, proj, n, stride_points,
stride_proj, subsampling_x, subsampling_y);
break;
case HOMOGRAPHY:
project_points_homography(wm_params->wmmat, points, proj, n,
stride_points, stride_proj, subsampling_x,
subsampling_y);
break;
default: assert(0 && "Invalid warped motion type!"); return;
}
}
static const int16_t
filter_ntap[WARPEDPIXEL_PREC_SHIFTS][WARPEDPIXEL_FILTER_TAPS] = {
{ 0, 0, 128, 0, 0, 0 }, { 0, -1, 128, 2, -1, 0 },
......@@ -342,11 +365,11 @@ static uint8_t warp_interpolate(uint8_t *ref, int x, int y, int width,
if (ix < 0 && iy < 0)
return ref[0];
else if (ix < 0 && iy > height - 1)
else if (ix < 0 && iy >= height - 1)
return ref[(height - 1) * stride];
else if (ix > width - 1 && iy < 0)
else if (ix >= width - 1 && iy < 0)
return ref[width - 1];
else if (ix > width - 1 && iy > height - 1)
else if (ix >= width - 1 && iy >= height - 1)
return ref[(height - 1) * stride + (width - 1)];
else if (ix < 0) {
v = ROUND_POWER_OF_TWO_SIGNED(
......@@ -359,13 +382,13 @@ static uint8_t warp_interpolate(uint8_t *ref, int x, int y, int width,
ref[ix] * (WARPEDPIXEL_PREC_SHIFTS - sx) + ref[ix + 1] * sx,
WARPEDPIXEL_PREC_BITS);
return clip_pixel(v);
} else if (ix > width - 1) {
} else if (ix >= width - 1) {
v = ROUND_POWER_OF_TWO_SIGNED(
ref[iy * stride + width - 1] * (WARPEDPIXEL_PREC_SHIFTS - sy) +
ref[(iy + 1) * stride + width - 1] * sy,
WARPEDPIXEL_PREC_BITS);
return clip_pixel(v);
} else if (iy > height - 1) {
} else if (iy >= height - 1) {
v = ROUND_POWER_OF_TWO_SIGNED(
ref[(height - 1) * stride + ix] * (WARPEDPIXEL_PREC_SHIFTS - sx) +
ref[(height - 1) * stride + ix + 1] * sx,
......@@ -1318,3 +1341,19 @@ int find_homography(const int np, double *pts1, double *pts2, double *mat) {
}
return 0;
}
int find_projection(const int np, double *pts1, double *pts2,
WarpedMotionParams *wm_params) {
double H[9];
int result = 1;
switch (wm_params->wmtype) {
case AFFINE: result = find_affine(np, pts1, pts2, H); break;
case ROTZOOM: result = find_rotzoom(np, pts1, pts2, H); break;
case HOMOGRAPHY: result = find_homography(np, pts1, pts2, H); break;
default: assert(0 && "Invalid warped motion type!"); return 1;
}
if (result == 0) av1_integerize_model(H, wm_params->wmtype, wm_params);
return result;
}
......@@ -24,6 +24,9 @@
#include "av1/common/mv.h"
#define MAX_PARAMDIM 9
#if CONFIG_WARPED_MOTION
#define DEFAULT_WMTYPE AFFINE
#endif // CONFIG_WARPED_MOTION
typedef void (*ProjectPointsFunc)(int32_t *mat, int *points, int *proj,
const int n, const int stride_points,
......@@ -49,6 +52,10 @@ void project_points_homography(int32_t *mat, int *points, int *proj,
const int stride_proj, const int subsampling_x,
const int subsampling_y);
void project_points(WarpedMotionParams *wm_params, int *points, int *proj,
const int n, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y);
double av1_warp_erroradv(WarpedMotionParams *wm,
#if CONFIG_AOM_HIGHBITDEPTH
int use_hbd, int bd,
......@@ -75,4 +82,6 @@ int find_translation(const int np, double *pts1, double *pts2, double *mat);
int find_rotzoom(const int np, double *pts1, double *pts2, double *mat);
int find_affine(const int np, double *pts1, double *pts2, double *mat);
int find_homography(const int np, double *pts1, double *pts2, double *mat);
int find_projection(const int np, double *pts1, double *pts2,
WarpedMotionParams *wm_params);
#endif // AV1_COMMON_WARPED_MOTION_H_
......@@ -54,6 +54,10 @@
#include "av1/decoder/detokenize.h"
#include "av1/decoder/dsubexp.h"
#if CONFIG_WARPED_MOTION
#include "av1/common/warped_motion.h"
#endif // CONFIG_WARPED_MOTION
#define MAX_AV1_HEADER_SIZE 80
#define ACCT_STR __func__
......@@ -1588,8 +1592,36 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
tx_size);
}
} else {
// Prediction
av1_build_inter_predictors_sb(xd, mi_row, mi_col, AOMMAX(bsize, BLOCK_8X8));
// Prediction
#if CONFIG_WARPED_MOTION
if (mbmi->motion_mode == WARPED_CAUSAL) {
int i;
#if CONFIG_AOM_HIGHBITDEPTH
int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
#endif // CONFIG_AOM_HIGHBITDEPTH
for (i = 0; i < 3; ++i) {
const struct macroblockd_plane *pd = &xd->plane[i];
av1_warp_plane(&mbmi->wm_params[0],
#if CONFIG_AOM_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
pd->pre[0].stride, pd->dst.buf,
((mi_col * MI_SIZE) >> pd->subsampling_x),
((mi_row * MI_SIZE) >> pd->subsampling_y),
xd->n8_w * (8 >> pd->subsampling_x),
xd->n8_h * (8 >> pd->subsampling_y), pd->dst.stride,
pd->subsampling_x, pd->subsampling_y, 16, 16, 0);
}
} else {
#endif // CONFIG_WARPED_MOTION
av1_build_inter_predictors_sb(xd, mi_row, mi_col,
AOMMAX(bsize, BLOCK_8X8));
#if CONFIG_WARPED_MOTION
}
#endif // CONFIG_WARPED_MOTION
#if CONFIG_MOTION_VAR
if (mbmi->motion_mode == OBMC_CAUSAL) {
av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
......
......@@ -19,6 +19,9 @@
#include "av1/common/pred_common.h"
#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
#if CONFIG_WARPED_MOTION
#include "av1/common/warped_motion.h"
#endif // CONFIG_WARPED_MOTION
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/decodemv.h"
......@@ -252,18 +255,26 @@ static void read_drl_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
MB_MODE_INFO *mbmi, aom_reader *r) {
if (is_motion_variation_allowed(mbmi)) {
int motion_mode;
FRAME_COUNTS *counts = xd->counts;
MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(mbmi);
int motion_mode;
FRAME_COUNTS *counts = xd->counts;
if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return SIMPLE_TRANSLATION;
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
if (last_motion_mode_allowed == OBMC_CAUSAL) {
motion_mode = aom_read(r, cm->fc->obmc_prob[mbmi->sb_type], ACCT_STR);
if (counts) ++counts->obmc[mbmi->sb_type][motion_mode];
return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
} else {
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
motion_mode =
aom_read_tree(r, av1_motion_mode_tree,
cm->fc->motion_mode_prob[mbmi->sb_type], ACCT_STR);
if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
} else {
return SIMPLE_TRANSLATION;
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
}
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
}
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
......@@ -1423,6 +1434,9 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
int16_t compound_inter_mode_ctx[MODE_CTX_REF_FRAMES];
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
int16_t mode_ctx = 0;
#if CONFIG_WARPED_MOTION
double pts[144], pts_inref[144];
#endif // CONFIG_WARPED_MOTION
#if CONFIG_PALETTE
mbmi->palette_mode_info.palette_size[0] = 0;
......@@ -1591,9 +1605,9 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
}
#endif
#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER && !CONFIG_WARPED_MOTION
read_mb_interp_filter(cm, xd, mbmi, r);
#endif // !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
#endif // !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER && !CONFIG_WARPED_MOTION
if (bsize < BLOCK_8X8) {
const int num_4x4_w = 1 << xd->bmode_blocks_wl;
......@@ -1777,13 +1791,28 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
mbmi->motion_mode = SIMPLE_TRANSLATION;
#if CONFIG_WARPED_MOTION
if (mbmi->sb_type >= BLOCK_8X8 && !has_second_ref(mbmi))
mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
#endif // CONFIG_WARPED_MOTION
#if CONFIG_SUPERTX
if (!supertx_enabled)
if (!supertx_enabled) {
#endif // CONFIG_SUPERTX
#if CONFIG_EXT_INTER
if (mbmi->ref_frame[1] != INTRA_FRAME)
#endif // CONFIG_EXT_INTER
mbmi->motion_mode = read_motion_mode(cm, xd, mbmi, r);
#if CONFIG_WARPED_MOTION
if (mbmi->motion_mode == WARPED_CAUSAL) {
mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
&mbmi->wm_params[0]);
}
#endif // CONFIG_WARPED_MOTION
#if CONFIG_SUPERTX
}
#endif // CONFIG_SUPERTX
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_EXT_INTER
......@@ -1791,8 +1820,7 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
if (cm->reference_mode != SINGLE_REFERENCE &&
is_inter_compound_mode(mbmi->mode) &&
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
!(is_motion_variation_allowed(mbmi) &&
mbmi->motion_mode != SIMPLE_TRANSLATION) &&
mbmi->motion_mode == SIMPLE_TRANSLATION &&
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
is_interinter_wedge_used(bsize)) {
mbmi->interinter_compound = aom_read_tree(
......@@ -1807,9 +1835,25 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
}
#endif // CONFIG_EXT_INTER
#if CONFIG_DUAL_FILTER || CONFIG_EXT_INTERP
read_mb_interp_filter(cm, xd, mbmi, r);
#endif // CONFIG_DUAL_FILTER || CONFIG_EXT_INTERP
#if CONFIG_WARPED_MOTION
if (mbmi->motion_mode != WARPED_CAUSAL) {
#endif // CONFIG_WARPED_MOTION
#if CONFIG_DUAL_FILTER || CONFIG_EXT_INTERP || CONFIG_WARPED_MOTION
read_mb_interp_filter(cm, xd, mbmi, r);
#endif // CONFIG_DUAL_FILTER || CONFIG_EXT_INTERP || CONFIG_WARPED_MOTION
#if CONFIG_WARPED_MOTION
} else {
#if CONFIG_DUAL_FILTER
mbmi->interp_filter[0] =
cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
mbmi->interp_filter[1] =
cm->interp_filter