Merge "Add global motion experiment to rdopt" into nextgenv2

This commit is contained in:
Sarah Parker 2016-09-06 18:07:31 +00:00 коммит произвёл Gerrit Code Review
Родитель 40da2c899a e529986568
Коммит 5ebdf40d77
9 изменённых файлов: 298 добавлений и 151 удалений

Просмотреть файл

@ -14,9 +14,6 @@
#include "av1/common/common.h" #include "av1/common/common.h"
#include "aom_dsp/aom_filter.h" #include "aom_dsp/aom_filter.h"
#if CONFIG_GLOBAL_MOTION
#include "av1/common/warped_motion.h"
#endif // CONFIG_GLOBAL_MOTION
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -37,6 +34,41 @@ typedef struct mv32 {
int32_t col; int32_t col;
} MV32; } MV32;
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
// Bits of precision used for the model
#define WARPEDMODEL_PREC_BITS 8
#define WARPEDMODEL_ROW3HOMO_PREC_BITS 12
// Bits of subpel precision for warped interpolation
#define WARPEDPIXEL_PREC_BITS 6
#define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS)
// Taps for ntap filter
#define WARPEDPIXEL_FILTER_TAPS 6
// Precision of filter taps
#define WARPEDPIXEL_FILTER_BITS 7
#define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)
typedef enum {
UNKNOWN_TRANSFORM = -1,
HOMOGRAPHY, // homography, 8-parameter
AFFINE, // affine, 6-parameter
ROTZOOM, // simplified affine with rotation and zoom only, 4-parameter
TRANSLATION, // translational motion 2-parameter
TRANS_TYPES
} TransformationType;
// number of parameters used by each transformation in TransformationTypes
static const int n_trans_model_params[TRANS_TYPES] = { 9, 6, 4, 2 };
typedef struct {
TransformationType wmtype;
int_mv wmmat[4]; // For homography wmmat[9] is assumed to be 1
} WarpedMotionParams;
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
#if CONFIG_GLOBAL_MOTION #if CONFIG_GLOBAL_MOTION
// ALPHA here refers to parameters a and b in rotzoom model: // ALPHA here refers to parameters a and b in rotzoom model:
// | a b| // | a b|
@ -62,16 +94,16 @@ typedef struct mv32 {
// //
// XX_MIN, XX_MAX are also computed to avoid repeated computation // XX_MIN, XX_MAX are also computed to avoid repeated computation
#define GM_TRANS_PREC_BITS 5 #define GM_TRANS_PREC_BITS 8
#define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS) #define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
#define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF) #define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF)
#define GM_ALPHA_PREC_BITS 5 #define GM_ALPHA_PREC_BITS 8
#define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS) #define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS)
#define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF) #define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF)
#define GM_ABS_ALPHA_BITS 8 #define GM_ABS_ALPHA_BITS 18
#define GM_ABS_TRANS_BITS 8 #define GM_ABS_TRANS_BITS 18
#define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS) #define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS)
#define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS) #define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS)
@ -103,11 +135,10 @@ static INLINE TransformationType gm_to_trans_type(GLOBAL_MOTION_TYPE gmtype) {
} }
static INLINE GLOBAL_MOTION_TYPE get_gmtype(const Global_Motion_Params *gm) { static INLINE GLOBAL_MOTION_TYPE get_gmtype(const Global_Motion_Params *gm) {
if (gm->motion_params.wmmat[4] == 0 && gm->motion_params.wmmat[5] == 0) { if (!gm->motion_params.wmmat[2].as_int) {
if (gm->motion_params.wmmat[2] == 0 && gm->motion_params.wmmat[3] == 0) { if (!gm->motion_params.wmmat[1].as_int) {
return ((gm->motion_params.wmmat[0] | gm->motion_params.wmmat[1]) return (gm->motion_params.wmmat[0].as_int ? GLOBAL_TRANSLATION
? GLOBAL_TRANSLATION : GLOBAL_ZERO);
: GLOBAL_ZERO);
} else { } else {
return GLOBAL_ROTZOOM; return GLOBAL_ROTZOOM;
} }

Просмотреть файл

@ -26,7 +26,7 @@ static ProjectPointsType get_project_points_type(TransformationType type) {
} }
} }
void projectPointsTranslation(int *mat, int *points, int *proj, const int n, void projectPointsTranslation(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_x,
const int subsampling_y) { const int subsampling_y) {
@ -35,24 +35,24 @@ void projectPointsTranslation(int *mat, int *points, int *proj, const int n,
const int x = *(points++), y = *(points++); const int x = *(points++), y = *(points++);
if (subsampling_x) if (subsampling_x)
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
((x << (WARPEDMODEL_PREC_BITS + 1)) + mat[0]), ((x << (WARPEDMODEL_PREC_BITS + 1)) + mat[1]),
WARPEDDIFF_PREC_BITS + 1); WARPEDDIFF_PREC_BITS + 1);
else else
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
((x << WARPEDMODEL_PREC_BITS)) + mat[0], WARPEDDIFF_PREC_BITS); ((x << WARPEDMODEL_PREC_BITS) + mat[1]), WARPEDDIFF_PREC_BITS);
if (subsampling_y) if (subsampling_y)
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
((y << (WARPEDMODEL_PREC_BITS + 1)) + mat[1]), ((y << (WARPEDMODEL_PREC_BITS + 1)) + mat[0]),
WARPEDDIFF_PREC_BITS + 1); WARPEDDIFF_PREC_BITS + 1);
else else
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
((y << WARPEDMODEL_PREC_BITS)) + mat[1], WARPEDDIFF_PREC_BITS); ((y << WARPEDMODEL_PREC_BITS)) + mat[0], WARPEDDIFF_PREC_BITS);
points += stride_points - 2; points += stride_points - 2;
proj += stride_proj - 2; proj += stride_proj - 2;
} }
} }
void projectPointsRotZoom(int *mat, int *points, int *proj, const int n, void projectPointsRotZoom(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y) { const int subsampling_x, const int subsampling_y) {
int i; int i;
@ -60,26 +60,26 @@ void projectPointsRotZoom(int *mat, int *points, int *proj, const int n,
const int x = *(points++), y = *(points++); const int x = *(points++), y = *(points++);
if (subsampling_x) if (subsampling_x)
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
mat[2] * 2 * x + mat[3] * 2 * y + mat[0] + mat[3] * 2 * x + mat[2] * 2 * y + mat[1] +
(mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS)) / 2, (mat[3] + mat[2] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
WARPEDDIFF_PREC_BITS + 1); WARPEDDIFF_PREC_BITS + 1);
else else
*(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[2] * x + mat[3] * y + mat[0], *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[3] * x + mat[2] * y + mat[1],
WARPEDDIFF_PREC_BITS); WARPEDDIFF_PREC_BITS);
if (subsampling_y) if (subsampling_y)
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-mat[3] * 2 * x + mat[2] * 2 * y + mat[1] + -mat[2] * 2 * x + mat[3] * 2 * y + mat[0] +
(-mat[3] + mat[2] - (1 << WARPEDMODEL_PREC_BITS)) / 2, (-mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
WARPEDDIFF_PREC_BITS + 1); WARPEDDIFF_PREC_BITS + 1);
else else
*(proj++) = ROUND_POWER_OF_TWO_SIGNED(-mat[3] * x + mat[2] * y + mat[1], *(proj++) = ROUND_POWER_OF_TWO_SIGNED(-mat[2] * x + mat[3] * y + mat[0],
WARPEDDIFF_PREC_BITS); WARPEDDIFF_PREC_BITS);
points += stride_points - 2; points += stride_points - 2;
proj += stride_proj - 2; proj += stride_proj - 2;
} }
} }
void projectPointsAffine(int *mat, int *points, int *proj, const int n, void projectPointsAffine(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y) { const int subsampling_x, const int subsampling_y) {
int i; int i;
@ -87,26 +87,26 @@ void projectPointsAffine(int *mat, int *points, int *proj, const int n,
const int x = *(points++), y = *(points++); const int x = *(points++), y = *(points++);
if (subsampling_x) if (subsampling_x)
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
mat[2] * 2 * x + mat[3] * 2 * y + mat[0] + mat[3] * 2 * x + mat[2] * 2 * y + mat[1] +
(mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS)) / 2, (mat[3] + mat[2] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
WARPEDDIFF_PREC_BITS + 1); WARPEDDIFF_PREC_BITS + 1);
else else
*(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[2] * x + mat[3] * y + mat[0], *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[3] * x + mat[2] * y + mat[1],
WARPEDDIFF_PREC_BITS); WARPEDDIFF_PREC_BITS);
if (subsampling_y) if (subsampling_y)
*(proj++) = ROUND_POWER_OF_TWO_SIGNED( *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
mat[4] * 2 * x + mat[5] * 2 * y + mat[1] + mat[5] * 2 * x + mat[4] * 2 * y + mat[0] +
(mat[4] + mat[5] - (1 << WARPEDMODEL_PREC_BITS)) / 2, (mat[5] + mat[4] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
WARPEDDIFF_PREC_BITS + 1); WARPEDDIFF_PREC_BITS + 1);
else else
*(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[4] * x + mat[5] * y + mat[1], *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[5] * x + mat[4] * y + mat[0],
WARPEDDIFF_PREC_BITS); WARPEDDIFF_PREC_BITS);
points += stride_points - 2; points += stride_points - 2;
proj += stride_proj - 2; proj += stride_proj - 2;
} }
} }
void projectPointsHomography(int *mat, int *points, int *proj, const int n, void projectPointsHomography(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y) { const int subsampling_x, const int subsampling_y) {
int i; int i;
@ -117,11 +117,11 @@ void projectPointsHomography(int *mat, int *points, int *proj, const int n,
x = (subsampling_x ? 4 * x + 1 : 2 * x); x = (subsampling_x ? 4 * x + 1 : 2 * x);
y = (subsampling_y ? 4 * y + 1 : 2 * y); y = (subsampling_y ? 4 * y + 1 : 2 * y);
Z = (mat[6] * x + mat[7] * y + (1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS + 1))); Z = (mat[7] * x + mat[6] * y + (1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS + 1)));
xp = (mat[0] * x + mat[1] * y + 2 * mat[2]) xp = (mat[1] * x + mat[0] * y + 2 * mat[3])
<< (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS - << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
WARPEDMODEL_PREC_BITS); WARPEDMODEL_PREC_BITS);
yp = (mat[3] * x + mat[4] * y + 2 * mat[5]) yp = (mat[2] * x + mat[5] * y + 2 * mat[4])
<< (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS - << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
WARPEDMODEL_PREC_BITS); WARPEDMODEL_PREC_BITS);
@ -483,7 +483,8 @@ static double highbd_warp_erroradv(WarpedMotionParams *wm, uint8_t *ref8,
int in[2], out[2]; int in[2], out[2];
in[0] = j; in[0] = j;
in[1] = i; in[1] = i;
projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y); projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
subsampling_y);
out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4); out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4); out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
gm_err = dst[(j - p_col) + (i - p_row) * p_stride] - gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
@ -514,7 +515,8 @@ static void highbd_warp_plane(WarpedMotionParams *wm, uint8_t *ref8, int width,
int in[2], out[2]; int in[2], out[2];
in[0] = j; in[0] = j;
in[1] = i; in[1] = i;
projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y); projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
subsampling_y);
out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4); out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4); out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
pred[(j - p_col) + (i - p_row) * p_stride] = highbd_warp_interpolate( pred[(j - p_col) + (i - p_row) * p_stride] = highbd_warp_interpolate(
@ -538,7 +540,8 @@ static double warp_erroradv(WarpedMotionParams *wm, uint8_t *ref, int width,
int in[2], out[2]; int in[2], out[2];
in[0] = j; in[0] = j;
in[1] = i; in[1] = i;
projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y); projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
subsampling_y);
out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4); out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4); out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
gm_err = dst[(j - p_col) + (i - p_row) * p_stride] - gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
@ -565,7 +568,8 @@ static void warp_plane(WarpedMotionParams *wm, uint8_t *ref, int width,
int in[2], out[2]; int in[2], out[2];
in[0] = j; in[0] = j;
in[1] = i; in[1] = i;
projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y); projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
subsampling_y);
out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4); out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4); out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
pred[(j - p_col) + (i - p_row) * p_stride] = pred[(j - p_col) + (i - p_row) * p_stride] =
@ -620,22 +624,28 @@ void av1_integerize_model(const double *model, TransformationType wmtype,
switch (wmtype) { switch (wmtype) {
case HOMOGRAPHY: case HOMOGRAPHY:
assert(fabs(model[8] - 1.0) < 1e-12); assert(fabs(model[8] - 1.0) < 1e-12);
wm->wmmat[7] = wm->wmmat[3].as_mv.row =
(int)lrint(model[7] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS)); (int16_t)lrint(model[6] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
wm->wmmat[6] = wm->wmmat[3].as_mv.col =
(int)lrint(model[6] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS)); (int16_t)lrint(model[7] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
/* fallthrough intended */ /* fallthrough intended */
case AFFINE: case AFFINE:
wm->wmmat[5] = (int)lrint(model[5] * (1 << WARPEDMODEL_PREC_BITS)); wm->wmmat[2].as_mv.row =
wm->wmmat[4] = (int)lrint(model[4] * (1 << WARPEDMODEL_PREC_BITS)); (int16_t)lrint(model[4] * (1 << WARPEDMODEL_PREC_BITS));
wm->wmmat[2].as_mv.col =
(int16_t)lrint(model[5] * (1 << WARPEDMODEL_PREC_BITS));
/* fallthrough intended */ /* fallthrough intended */
case ROTZOOM: case ROTZOOM:
wm->wmmat[3] = (int)lrint(model[3] * (1 << WARPEDMODEL_PREC_BITS)); wm->wmmat[1].as_mv.row =
wm->wmmat[2] = (int)lrint(model[2] * (1 << WARPEDMODEL_PREC_BITS)); (int16_t)lrint(model[2] * (1 << WARPEDMODEL_PREC_BITS));
wm->wmmat[1].as_mv.col =
(int16_t)lrint(model[3] * (1 << WARPEDMODEL_PREC_BITS));
/* fallthrough intended */ /* fallthrough intended */
case TRANSLATION: case TRANSLATION:
wm->wmmat[1] = (int)lrint(model[1] * (1 << WARPEDMODEL_PREC_BITS)); wm->wmmat[0].as_mv.row =
wm->wmmat[0] = (int)lrint(model[0] * (1 << WARPEDMODEL_PREC_BITS)); (int16_t)lrint(model[0] * (1 << WARPEDMODEL_PREC_BITS));
wm->wmmat[0].as_mv.col =
(int16_t)lrint(model[1] * (1 << WARPEDMODEL_PREC_BITS));
break; break;
default: assert(0 && "Invalid TransformationType"); default: assert(0 && "Invalid TransformationType");
} }

Просмотреть файл

@ -20,6 +20,7 @@
#include "./aom_config.h" #include "./aom_config.h"
#include "aom_ports/mem.h" #include "aom_ports/mem.h"
#include "aom_dsp/aom_dsp_common.h" #include "aom_dsp/aom_dsp_common.h"
#include "av1/common/mv.h"
// Bits of precision used for the model // Bits of precision used for the model
#define WARPEDMODEL_PREC_BITS 8 #define WARPEDMODEL_PREC_BITS 8
@ -37,49 +38,36 @@
#define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS) #define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)
typedef void (*ProjectPointsType)(int *mat, int *points, int *proj, const int n, typedef void (*ProjectPointsType)(int16_t *mat, int *points, int *proj,
const int stride_points, const int n, const int stride_points,
const int stride_proj, const int stride_proj,
const int subsampling_x, const int subsampling_x,
const int subsampling_y); const int subsampling_y);
void projectPointsHomography(int *mat, int *points, int *proj, const int n,
void projectPointsHomography(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y); const int subsampling_x, const int subsampling_y);
void projectPointsAffine(int *mat, int *points, int *proj, const int n,
void projectPointsAffine(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y); const int subsampling_x, const int subsampling_y);
void projectPointsRotZoom(int *mat, int *points, int *proj, const int n,
void projectPointsRotZoom(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y); const int subsampling_x, const int subsampling_y);
void projectPointsTranslation(int *mat, int *points, int *proj, const int n,
void projectPointsTranslation(int16_t *mat, int *points, int *proj, const int n,
const int stride_points, const int stride_proj, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y); const int subsampling_x, const int subsampling_y);
typedef enum {
UNKNOWN_TRANSFORM = -1,
HOMOGRAPHY, // homography, 8-parameter
AFFINE, // affine, 6-parameter
ROTZOOM, // simplified affine with rotation and zoom only, 4-parameter
TRANSLATION, // translational motion 2-parameter
TRANS_TYPES
} TransformationType;
// number of parameters used by each transformation in TransformationTypes
static const int n_trans_model_params[TRANS_TYPES] = { 9, 6, 4, 2 };
typedef struct {
TransformationType wmtype;
int wmmat[8]; // For homography wmmat[9] is assumed to be 1
} WarpedMotionParams;
double av1_warp_erroradv(WarpedMotionParams *wm, double av1_warp_erroradv(WarpedMotionParams *wm,
#if CONFIG_AOM_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
int use_hbd, int bd, int use_hbd, int bd,
#endif // CONFIG_AOM_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
uint8_t *ref, int width, int height, int stride, uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width, uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x, int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale); int subsampling_y, int x_scale, int y_scale);
void av1_warp_plane(WarpedMotionParams *wm, void av1_warp_plane(WarpedMotionParams *wm,
#if CONFIG_AOM_HIGHBITDEPTH #if CONFIG_AOM_HIGHBITDEPTH

Просмотреть файл

@ -3411,28 +3411,28 @@ static void read_global_motion_params(Global_Motion_Params *params,
switch (gmtype) { switch (gmtype) {
case GLOBAL_ZERO: break; case GLOBAL_ZERO: break;
case GLOBAL_AFFINE: case GLOBAL_AFFINE:
params->motion_params.wmmat[4] = params->motion_params.wmmat[2].as_mv.row =
(aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR);
params->motion_params.wmmat[5] =
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) * aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR + GM_ALPHA_DECODE_FACTOR +
(1 << WARPEDMODEL_PREC_BITS); (1 << WARPEDMODEL_PREC_BITS);
params->motion_params.wmmat[2].as_mv.col =
(aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR);
// fallthrough intended // fallthrough intended
case GLOBAL_ROTZOOM: case GLOBAL_ROTZOOM:
params->motion_params.wmmat[2] = params->motion_params.wmmat[1].as_mv.row =
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR;
params->motion_params.wmmat[1].as_mv.col =
(aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) * (aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR) + GM_ALPHA_DECODE_FACTOR) +
(1 << WARPEDMODEL_PREC_BITS); (1 << WARPEDMODEL_PREC_BITS);
params->motion_params.wmmat[3] =
aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR;
// fallthrough intended // fallthrough intended
case GLOBAL_TRANSLATION: case GLOBAL_TRANSLATION:
params->motion_params.wmmat[0] = params->motion_params.wmmat[0].as_mv.row =
aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) * aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR; GM_TRANS_DECODE_FACTOR;
params->motion_params.wmmat[1] = params->motion_params.wmmat[0].as_mv.col =
aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) * aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR; GM_TRANS_DECODE_FACTOR;
break; break;
@ -3446,6 +3446,14 @@ static void read_global_motion(AV1_COMMON *cm, aom_reader *r) {
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) { for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
read_global_motion_params(&cm->global_motion[frame], read_global_motion_params(&cm->global_motion[frame],
cm->fc->global_motion_types_prob, r); cm->fc->global_motion_types_prob, r);
/*
printf("Dec Ref %d [%d]: %d %d %d %d\n",
frame, cm->current_video_frame,
cm->global_motion[frame].motion_params.wmmat[0].as_mv.row,
cm->global_motion[frame].motion_params.wmmat[0].as_mv.col,
cm->global_motion[frame].motion_params.wmmat[1].as_mv.row,
cm->global_motion[frame].motion_params.wmmat[1].as_mv.col);
*/
} }
} }
#endif // CONFIG_GLOBAL_MOTION #endif // CONFIG_GLOBAL_MOTION

Просмотреть файл

@ -939,6 +939,7 @@ static INLINE int is_mv_valid(const MV *mv) {
static INLINE int assign_mv(AV1_COMMON *cm, MACROBLOCKD *xd, static INLINE int assign_mv(AV1_COMMON *cm, MACROBLOCKD *xd,
PREDICTION_MODE mode, PREDICTION_MODE mode,
MV_REFERENCE_FRAME ref_frame[2],
#if CONFIG_REF_MV #if CONFIG_REF_MV
int block, int block,
#endif #endif
@ -953,6 +954,7 @@ static INLINE int assign_mv(AV1_COMMON *cm, MACROBLOCKD *xd,
int_mv *pred_mv = int_mv *pred_mv =
(bsize >= BLOCK_8X8) ? mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv_s8; (bsize >= BLOCK_8X8) ? mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv_s8;
#endif #endif
(void)ref_frame;
switch (mode) { switch (mode) {
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
@ -1007,8 +1009,16 @@ static INLINE int assign_mv(AV1_COMMON *cm, MACROBLOCKD *xd,
break; break;
} }
case ZEROMV: { case ZEROMV: {
#if CONFIG_GLOBAL_MOTION
mv[0].as_int =
cm->global_motion[ref_frame[0]].motion_params.wmmat[0].as_int;
if (is_compound)
mv[1].as_int =
cm->global_motion[ref_frame[1]].motion_params.wmmat[0].as_int;
#else
mv[0].as_int = 0; mv[0].as_int = 0;
if (is_compound) mv[1].as_int = 0; if (is_compound) mv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_REF_MV #if CONFIG_REF_MV
pred_mv[0].as_int = 0; pred_mv[0].as_int = 0;
@ -1429,7 +1439,7 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
(void)ref_mv_s8; (void)ref_mv_s8;
#endif #endif
if (!assign_mv(cm, xd, b_mode, if (!assign_mv(cm, xd, b_mode, mbmi->ref_frame,
#if CONFIG_REF_MV #if CONFIG_REF_MV
j, j,
#endif #endif
@ -1481,7 +1491,7 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
} }
xd->corrupted |= xd->corrupted |=
!assign_mv(cm, xd, mbmi->mode, !assign_mv(cm, xd, mbmi->mode, mbmi->ref_frame,
#if CONFIG_REF_MV #if CONFIG_REF_MV
0, 0,
#endif #endif

Просмотреть файл

@ -3196,29 +3196,29 @@ static void write_global_motion_params(Global_Motion_Params *params,
switch (gmtype) { switch (gmtype) {
case GLOBAL_ZERO: break; case GLOBAL_ZERO: break;
case GLOBAL_AFFINE: case GLOBAL_AFFINE:
av1_write_primitive_symmetric( aom_write_primitive_symmetric(
w, params->motion_params.wmmat[4] >> GM_ALPHA_PREC_DIFF, w, (params->motion_params.wmmat[2].as_mv.row >> GM_ALPHA_PREC_DIFF) -
GM_ABS_ALPHA_BITS);
av1_write_primitive_symmetric(
w, (params->motion_params.wmmat[5] >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS), (1 << GM_ALPHA_PREC_BITS),
GM_ABS_ALPHA_BITS); GM_ABS_ALPHA_BITS);
aom_write_primitive_symmetric(
w, (params->motion_params.wmmat[2].as_mv.col >> GM_ALPHA_PREC_DIFF),
GM_ABS_ALPHA_BITS);
// fallthrough intended // fallthrough intended
case GLOBAL_ROTZOOM: case GLOBAL_ROTZOOM:
aom_write_primitive_symmetric( aom_write_primitive_symmetric(
w, (params->motion_params.wmmat[2] >> GM_ALPHA_PREC_DIFF) - w, (params->motion_params.wmmat[1].as_mv.row >> GM_ALPHA_PREC_DIFF),
(1 << GM_ALPHA_PREC_BITS),
GM_ABS_ALPHA_BITS); GM_ABS_ALPHA_BITS);
aom_write_primitive_symmetric( aom_write_primitive_symmetric(
w, params->motion_params.wmmat[3] >> GM_ALPHA_PREC_DIFF, w, (params->motion_params.wmmat[1].as_mv.col >> GM_ALPHA_PREC_DIFF) -
(1 << GM_ALPHA_PREC_BITS),
GM_ABS_ALPHA_BITS); GM_ABS_ALPHA_BITS);
// fallthrough intended // fallthrough intended
case GLOBAL_TRANSLATION: case GLOBAL_TRANSLATION:
aom_write_primitive_symmetric( aom_write_primitive_symmetric(
w, params->motion_params.wmmat[0] >> GM_TRANS_PREC_DIFF, w, (params->motion_params.wmmat[0].as_mv.row >> GM_TRANS_PREC_DIFF),
GM_ABS_TRANS_BITS); GM_ABS_TRANS_BITS);
aom_write_primitive_symmetric( aom_write_primitive_symmetric(
w, params->motion_params.wmmat[1] >> GM_TRANS_PREC_DIFF, w, (params->motion_params.wmmat[0].as_mv.col >> GM_TRANS_PREC_DIFF),
GM_ABS_TRANS_BITS); GM_ABS_TRANS_BITS);
break; break;
default: assert(0); default: assert(0);
@ -3234,6 +3234,14 @@ static void write_global_motion(AV1_COMP *cpi, aom_writer *w) {
} }
write_global_motion_params(&cm->global_motion[frame], write_global_motion_params(&cm->global_motion[frame],
cm->fc->global_motion_types_prob, w); cm->fc->global_motion_types_prob, w);
/*
printf("Enc Ref %d [%d] (used %d): %d %d %d %d\n",
frame, cm->current_video_frame, cpi->global_motion_used[frame],
cm->global_motion[frame].motion_params.wmmat[0].as_mv.row,
cm->global_motion[frame].motion_params.wmmat[0].as_mv.col,
cm->global_motion[frame].motion_params.wmmat[1].as_mv.row,
cm->global_motion[frame].motion_params.wmmat[1].as_mv.col);
*/
} }
} }
#endif #endif

Просмотреть файл

@ -41,6 +41,7 @@
#include "av1/encoder/cost.h" #include "av1/encoder/cost.h"
#endif #endif
#if CONFIG_GLOBAL_MOTION #if CONFIG_GLOBAL_MOTION
#include "av1/common/warped_motion.h"
#include "av1/encoder/global_motion.h" #include "av1/encoder/global_motion.h"
#endif #endif
#include "av1/encoder/encodeframe.h" #include "av1/encoder/encodeframe.h"
@ -4402,37 +4403,30 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#if CONFIG_GLOBAL_MOTION #if CONFIG_GLOBAL_MOTION
#define MIN_TRANS_THRESH 8 #define MIN_TRANS_THRESH 8
#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60 #define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60
#define GLOBAL_MOTION_MODEL ROTZOOM #define GLOBAL_MOTION_MODEL TRANSLATION
static void convert_to_params(double *H, TransformationType type, static void convert_to_params(double *H, TransformationType type,
Global_Motion_Params *model) { int16_t *model) {
int i; int i;
int alpha_present = 0; int alpha_present = 0;
int n_params = n_trans_model_params[type]; int n_params = n_trans_model_params[type];
model->motion_params.wmmat[0] = model[0] = (int16_t)floor(H[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
(int)floor(H[0] * (1 << GM_TRANS_PREC_BITS) + 0.5); model[1] = (int16_t)floor(H[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
model->motion_params.wmmat[1] = model[0] = (int16_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
(int)floor(H[1] * (1 << GM_TRANS_PREC_BITS) + 0.5); GM_TRANS_DECODE_FACTOR;
model->motion_params.wmmat[0] = model[1] = (int16_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
clamp(model->motion_params.wmmat[0], GM_TRANS_MIN, GM_TRANS_MAX) * GM_TRANS_DECODE_FACTOR;
GM_TRANS_DECODE_FACTOR;
model->motion_params.wmmat[1] =
clamp(model->motion_params.wmmat[1], GM_TRANS_MIN, GM_TRANS_MAX) *
GM_TRANS_DECODE_FACTOR;
for (i = 2; i < n_params; ++i) { for (i = 2; i < n_params; ++i) {
model->motion_params.wmmat[i] = model[i] = (int16_t)floor(H[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
(int)floor(H[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5); model[i] = (int16_t)clamp(model[i], GM_ALPHA_MIN, GM_ALPHA_MAX) *
model->motion_params.wmmat[i] = GM_ALPHA_DECODE_FACTOR;
clamp(model->motion_params.wmmat[i], GM_ALPHA_MIN, GM_ALPHA_MAX) * alpha_present |= (model[i] != 0);
GM_ALPHA_DECODE_FACTOR;
alpha_present |= (model->motion_params.wmmat[i] != 0);
} }
if (!alpha_present) { if (!alpha_present) {
if (abs(model->motion_params.wmmat[0]) < MIN_TRANS_THRESH && if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
abs(model->motion_params.wmmat[1]) < MIN_TRANS_THRESH) { model[0] = 0;
model->motion_params.wmmat[0] = 0; model[1] = 0;
model->motion_params.wmmat[1] = 0;
} }
} }
} }
@ -4440,7 +4434,8 @@ static void convert_to_params(double *H, TransformationType type,
static void convert_model_to_params(double *H, TransformationType type, static void convert_model_to_params(double *H, TransformationType type,
Global_Motion_Params *model) { Global_Motion_Params *model) {
// TODO(sarahparker) implement for homography // TODO(sarahparker) implement for homography
if (type > HOMOGRAPHY) convert_to_params(H, type, model); if (type > HOMOGRAPHY)
convert_to_params(H, type, (int16_t *)model->motion_params.wmmat);
model->gmtype = get_gmtype(model); model->gmtype = get_gmtype(model);
model->motion_params.wmtype = gm_to_trans_type(model->gmtype); model->motion_params.wmtype = gm_to_trans_type(model->gmtype);
} }

Просмотреть файл

@ -469,7 +469,8 @@ int ransac_(double *matched_points, int npoints, int *number_of_inliers,
} }
av1_integerize_model(H, type, &wm); av1_integerize_model(H, type, &wm);
projectpoints(wm.wmmat, corners1_int, image1_coord, npoints, 2, 2, 0, 0); projectpoints((int16_t *)wm.wmmat, corners1_int, image1_coord, npoints, 2,
2, 0, 0);
for (i = 0; i < npoints; ++i) { for (i = 0; i < npoints; ++i) {
double dx = double dx =
@ -610,12 +611,12 @@ static void denormalizeAffine(double *H, double *T1, double *T2) {
Ha[6] = Ha[7] = 0; Ha[6] = Ha[7] = 0;
Ha[8] = 1; Ha[8] = 1;
denormalizeHomography(Ha, T1, T2); denormalizeHomography(Ha, T1, T2);
H[0] = Ha[2]; H[0] = Ha[5];
H[1] = Ha[5]; H[1] = Ha[2];
H[2] = Ha[0]; H[2] = Ha[1];
H[3] = Ha[1]; H[3] = Ha[0];
H[4] = Ha[3]; H[4] = Ha[4];
H[5] = Ha[4]; H[5] = Ha[3];
} }
static void denormalizeRotZoom(double *H, double *T1, double *T2) { static void denormalizeRotZoom(double *H, double *T1, double *T2) {
@ -629,10 +630,10 @@ static void denormalizeRotZoom(double *H, double *T1, double *T2) {
Ha[6] = Ha[7] = 0; Ha[6] = Ha[7] = 0;
Ha[8] = 1; Ha[8] = 1;
denormalizeHomography(Ha, T1, T2); denormalizeHomography(Ha, T1, T2);
H[0] = Ha[2]; H[0] = Ha[5];
H[1] = Ha[5]; H[1] = Ha[2];
H[2] = Ha[0]; H[2] = Ha[1];
H[3] = Ha[1]; H[3] = Ha[0];
} }
static void denormalizeTranslation(double *H, double *T1, double *T2) { static void denormalizeTranslation(double *H, double *T1, double *T2) {
@ -646,8 +647,8 @@ static void denormalizeTranslation(double *H, double *T1, double *T2) {
Ha[6] = Ha[7] = 0; Ha[6] = Ha[7] = 0;
Ha[8] = 1; Ha[8] = 1;
denormalizeHomography(Ha, T1, T2); denormalizeHomography(Ha, T1, T2);
H[0] = Ha[2]; H[0] = Ha[5];
H[1] = Ha[5]; H[1] = Ha[2];
} }
static int is_collinear3(double *p1, double *p2, double *p3) { static int is_collinear3(double *p1, double *p2, double *p3) {

Просмотреть файл

@ -4069,6 +4069,31 @@ static int cost_mv_ref(const AV1_COMP *cpi, PREDICTION_MODE mode,
#endif #endif
} }
#if CONFIG_GLOBAL_MOTION
static int get_gmbitcost(const Global_Motion_Params *gm,
const aom_prob *probs) {
int gmtype_cost[GLOBAL_MOTION_TYPES];
int bits;
av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
if (gm->motion_params.wmmat[2].as_int) {
bits = (GM_ABS_TRANS_BITS + 1) * 2 + 4 * GM_ABS_ALPHA_BITS + 4;
} else if (gm->motion_params.wmmat[1].as_int) {
bits = (GM_ABS_TRANS_BITS + 1) * 2 + 2 * GM_ABS_ALPHA_BITS + 2;
} else {
bits =
(gm->motion_params.wmmat[0].as_int ? ((GM_ABS_TRANS_BITS + 1) * 2) : 0);
}
return (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[gm->gmtype];
}
#define GLOBAL_MOTION_RATE(ref) \
(cpi->global_motion_used[ref] >= 2 \
? 0 \
: get_gmbitcost(&cm->global_motion[(ref)], \
cm->fc->global_motion_types_prob) / \
2);
#endif // CONFIG_GLOBAL_MOTION
static int set_and_cost_bmi_mvs( static int set_and_cost_bmi_mvs(
AV1_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i, PREDICTION_MODE mode, AV1_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
int_mv this_mv[2], int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int_mv this_mv[2], int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
@ -4077,6 +4102,9 @@ static int set_and_cost_bmi_mvs(
int_mv compound_seg_newmvs[2], int_mv compound_seg_newmvs[2],
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2]) { int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2]) {
#if CONFIG_GLOBAL_MOTION
const AV1_COMMON *cm = &cpi->common;
#endif // CONFIG_GLOBAL_MOTION
MODE_INFO *const mic = xd->mi[0]; MODE_INFO *const mic = xd->mi[0];
const MB_MODE_INFO *const mbmi = &mic->mbmi; const MB_MODE_INFO *const mbmi = &mic->mbmi;
const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
@ -4128,8 +4156,21 @@ static int set_and_cost_bmi_mvs(
this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int; this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
break; break;
case ZEROMV: case ZEROMV:
#if CONFIG_GLOBAL_MOTION
this_mv[0].as_int = cpi->common.global_motion[mbmi->ref_frame[0]]
.motion_params.wmmat[0]
.as_int;
thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
if (is_compound) {
this_mv[1].as_int = cpi->common.global_motion[mbmi->ref_frame[1]]
.motion_params.wmmat[0]
.as_int;
thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
}
#else // CONFIG_GLOBAL_MOTION
this_mv[0].as_int = 0; this_mv[0].as_int = 0;
if (is_compound) this_mv[1].as_int = 0; if (is_compound) this_mv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
break; break;
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
case NEW_NEWMV: case NEW_NEWMV:
@ -4838,7 +4879,12 @@ static int64_t rd_pick_best_sub8x8_mode(
av1_update_mv_context(xd, mi, frame, mv_ref_list, i, mi_row, mi_col, av1_update_mv_context(xd, mi, frame, mv_ref_list, i, mi_row, mi_col,
NULL); NULL);
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
frame_mv[ZEROMV][frame].as_int =
cm->global_motion[frame].motion_params.wmmat[0].as_int;
#else // CONFIG_GLOBAL_MOTION
frame_mv[ZEROMV][frame].as_int = 0; frame_mv[ZEROMV][frame].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
av1_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col, av1_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
#if CONFIG_REF_MV #if CONFIG_REF_MV
ref_mv_stack[ref], &ref_mv_count[ref], ref_mv_stack[ref], &ref_mv_count[ref],
@ -4974,12 +5020,19 @@ static int64_t rd_pick_best_sub8x8_mode(
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
#endif // CONFIG_REF_MV #endif // CONFIG_REF_MV
if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, #if CONFIG_GLOBAL_MOTION
if (get_gmtype(&cm->global_motion[mbmi->ref_frame[0]]) == GLOBAL_ZERO &&
(!has_second_rf ||
get_gmtype(&cm->global_motion[mbmi->ref_frame[1]]) == GLOBAL_ZERO))
#endif // CONFIG_GLOBAL_MOTION
if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
#if CONFIG_REF_MV && CONFIG_EXT_INTER #if CONFIG_REF_MV && CONFIG_EXT_INTER
mbmi_ext->compound_mode_context, mbmi_ext->compound_mode_context,
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER #endif // CONFIG_REF_MV && CONFIG_EXT_INTER
frame_mv, this_mode, mbmi->ref_frame, bsize, i)) frame_mv, this_mode, mbmi->ref_frame, bsize,
continue; i))
continue;
memcpy(orig_pre, pd->pre, sizeof(orig_pre)); memcpy(orig_pre, pd->pre, sizeof(orig_pre));
memcpy(bsi->rdstat[i][mode_idx].ta, t_above, memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
@ -7639,6 +7692,12 @@ static int64_t handle_inter_mode(
*rate_uv = 0; *rate_uv = 0;
*skippable = 1; *skippable = 1;
} }
#if CONFIG_GLOBAL_MOTION
if (this_mode == ZEROMV) {
*rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
if (is_comp_pred) *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
}
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_OBMC || CONFIG_WARPED_MOTION #if CONFIG_OBMC || CONFIG_WARPED_MOTION
tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion); tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
@ -8275,7 +8334,12 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb); frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
} }
frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
#if CONFIG_GLOBAL_MOTION
frame_mv[ZEROMV][ref_frame].as_int =
cm->global_motion[ref_frame].motion_params.wmmat[0].as_int;
#else // CONFIG_GLOBAL_MOTION
frame_mv[ZEROMV][ref_frame].as_int = 0; frame_mv[ZEROMV][ref_frame].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV; frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV; frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
@ -8352,6 +8416,7 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
// an unfiltered alternative. We allow near/nearest as well // an unfiltered alternative. We allow near/nearest as well
// because they may result in zero-zero MVs but be cheaper. // because they may result in zero-zero MVs but be cheaper.
if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
int_mv zeromv;
ref_frame_skip_mask[0] = (1 << LAST_FRAME) | ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
(1 << LAST2_FRAME) | (1 << LAST3_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
@ -8362,18 +8427,24 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
// TODO(zoeliu): To further explore whether following needs to be done for // TODO(zoeliu): To further explore whether following needs to be done for
// BWDREF_FRAME as well. // BWDREF_FRAME as well.
mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO; mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0) #if CONFIG_GLOBAL_MOTION
zeromv.as_int =
cm->global_motion[ALTREF_FRAME].motion_params.wmmat[0].as_int;
#else
zeromv.as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV); mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0) if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV); mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0) if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV); mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0) if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV); mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0) if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV); mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != 0) if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV); mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
} }
@ -8581,7 +8652,14 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
if (conditional_skipintra(this_mode, best_intra_mode)) continue; if (conditional_skipintra(this_mode, best_intra_mode)) continue;
} }
} }
#if CONFIG_GLOBAL_MOTION
} else if (get_gmtype(&cm->global_motion[ref_frame]) == GLOBAL_ZERO &&
(!comp_pred ||
get_gmtype(&cm->global_motion[second_ref_frame]) ==
GLOBAL_ZERO)) {
#else // CONFIG_GLOBAL_MOTION
} else { } else {
#endif // CONFIG_GLOBAL_MOTION
const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame }; const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
#if CONFIG_REF_MV && CONFIG_EXT_INTER #if CONFIG_REF_MV && CONFIG_EXT_INTER
@ -9426,8 +9504,18 @@ PALETTE_EXIT:
const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0], const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
best_mbmode.ref_frame[1] }; best_mbmode.ref_frame[1] };
int comp_pred_mode = refs[1] > INTRA_FRAME; int comp_pred_mode = refs[1] > INTRA_FRAME;
int_mv zeromv[2];
#if CONFIG_REF_MV #if CONFIG_REF_MV
const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame); const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
#endif // CONFIG_REF_MV
#if CONFIG_GLOBAL_MOTION
zeromv[0].as_int = cm->global_motion[refs[0]].motion_params.wmmat[0].as_int;
zeromv[1].as_int = cm->global_motion[refs[1]].motion_params.wmmat[0].as_int;
#else
zeromv[0].as_int = 0;
zeromv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_REF_MV
if (!comp_pred_mode) { if (!comp_pred_mode) {
int i; int i;
int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2) int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
@ -9444,7 +9532,7 @@ PALETTE_EXIT:
if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int) if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
best_mbmode.mode = NEARESTMV; best_mbmode.mode = NEARESTMV;
else if (best_mbmode.mv[0].as_int == 0) else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
best_mbmode.mode = ZEROMV; best_mbmode.mode = ZEROMV;
} else { } else {
int_mv nearestmv[2]; int_mv nearestmv[2];
@ -9500,7 +9588,8 @@ PALETTE_EXIT:
best_mbmode.mode = ZERO_ZEROMV; best_mbmode.mode = ZERO_ZEROMV;
#else #else
best_mbmode.mode = NEARESTMV; best_mbmode.mode = NEARESTMV;
else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0) else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
best_mbmode.mv[1].as_int == zeromv[1].as_int)
best_mbmode.mode = ZEROMV; best_mbmode.mode = ZEROMV;
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
} }
@ -9519,8 +9608,9 @@ PALETTE_EXIT:
best_mbmode.mv[1].as_int) || best_mbmode.mv[1].as_int) ||
!comp_pred_mode)) !comp_pred_mode))
best_mbmode.mode = NEARMV; best_mbmode.mode = NEARMV;
else if (best_mbmode.mv[0].as_int == 0 && else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || ((comp_pred_mode &&
best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
!comp_pred_mode)) !comp_pred_mode))
best_mbmode.mode = ZEROMV; best_mbmode.mode = ZEROMV;
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
@ -9692,7 +9782,13 @@ void av1_rd_pick_inter_mode_sb_seg_skip(AV1_COMP *cpi, TileDataEnc *tile_data,
mbmi->uv_mode = DC_PRED; mbmi->uv_mode = DC_PRED;
mbmi->ref_frame[0] = LAST_FRAME; mbmi->ref_frame[0] = LAST_FRAME;
mbmi->ref_frame[1] = NONE; mbmi->ref_frame[1] = NONE;
#if CONFIG_GLOBAL_MOTION
mbmi->mv[0].as_int =
cm->global_motion[mbmi->ref_frame[0]].motion_params.wmmat[0].as_int;
#else // CONFIG_GLOBAL_MOTION
mbmi->mv[0].as_int = 0; mbmi->mv[0].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_REF_MV #if CONFIG_REF_MV
mbmi->ref_mv_idx = 0; mbmi->ref_mv_idx = 0;
mbmi->pred_mv[0].as_int = 0; mbmi->pred_mv[0].as_int = 0;