Global motion enhancements

Adds warping functions. Also includes some refactoring.

Change-Id: I909830650f29046edf108ddaddceb1a5e7c6c61c
This commit is contained in:
Debargha Mukherjee 2015-05-07 15:09:40 -07:00
parent b4d8b235dd
commit fb093a337f
25 changed files with 728 additions and 402 deletions

View File

@ -318,6 +318,9 @@ enum mv_precision {
struct buf_2d {
uint8_t *buf;
uint8_t *buf0;
int width;
int height;
int stride;
};
@ -401,6 +404,9 @@ typedef struct macroblockd {
PARTITION_CONTEXT *above_seg_context;
PARTITION_CONTEXT left_seg_context[8];
#if CONFIG_GLOBAL_MOTION
Global_Motion_Params (*global_motion)[MAX_GLOBAL_MOTION_MODELS];
#endif // CONFIG_GLOBAL_MOTION
} MACROBLOCKD;
static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,

View File

@ -132,47 +132,6 @@ static const vp9_prob default_global_motion_types_prob
// Currently only translation is used, so make the second prob very high.
240, 255
};
static void convert_params_to_rotzoom(double *H, Global_Motion_Params *model) {
double z = 1.0 + (double) model->zoom / (1 << ZOOM_PRECISION_BITS);
double r = (double) model->rotation / (1 << ROTATION_PRECISION_BITS);
H[0] = (1 + z) * cos(r * M_PI / 180.0);
H[1] = -(1 + z) * sin(r * M_PI / 180.0);
H[2] = (double) model->mv.as_mv.col / 8.0;
H[3] = (double) model->mv.as_mv.row / 8.0;
}
static int_mv get_global_mv(int col, int row, Global_Motion_Params *model) {
int_mv mv;
double H[4];
double x, y;
convert_params_to_rotzoom(H, model);
x = H[0] * col + H[1] * row + H[2];
y = -H[1] * col + H[0] * row + H[3];
mv.as_mv.col = (int)floor(x * 8 + 0.5) - col;
mv.as_mv.row = (int)floor(y * 8 + 0.5) - row;
return mv;
}
int_mv vp9_get_global_sb_center_mv(int col, int row, BLOCK_SIZE bsize,
Global_Motion_Params *model) {
col += num_4x4_blocks_wide_lookup[bsize] * 2;
row += num_4x4_blocks_high_lookup[bsize] * 2;
return get_global_mv(col, row, model);
}
int_mv vp9_get_global_sub8x8_center_mv(int col, int row, int block,
Global_Motion_Params *model) {
if (block == 0 || block == 2)
col += 2;
else
col += 6;
if (block == 0 || block == 1)
row += 2;
else
row += 6;
return get_global_mv(col, row, model);
}
#endif // CONFIG_GLOBAL_MOTION
static INLINE int mv_class_base(MV_CLASS_TYPE c) {

View File

@ -129,36 +129,8 @@ typedef struct {
void vp9_inc_mv(const MV *mv, nmv_context_counts *mvctx);
#if CONFIG_GLOBAL_MOTION
#define MAX_GLOBAL_MOTION_MODELS 1
#define ZOOM_PRECISION_BITS 6
#define ROTATION_PRECISION_BITS 4
#define ABS_ZOOM_BITS 3
#define ABS_ROTATION_BITS 4
#define ABS_TRANSLATION_BITS 7
typedef enum {
GLOBAL_ZERO = 0,
GLOBAL_TRANSLATION = 1,
GLOBAL_ROTZOOM = 2,
GLOBAL_MOTION_TYPES
} GLOBAL_MOTION_TYPE;
// Currently this is specialized for rotzoom model only
typedef struct {
int rotation; // positive or negative rotation angle in degrees
int zoom; // this is actually the zoom multiplier minus 1
int_mv mv;
} Global_Motion_Params;
extern const vp9_tree_index vp9_global_motion_types_tree
[TREE_SIZE(GLOBAL_MOTION_TYPES)];
int_mv vp9_get_global_sb_center_mv(int col, int row, BLOCK_SIZE bsize,
Global_Motion_Params *model);
int_mv vp9_get_global_sub8x8_center_mv(int col, int row, int block,
Global_Motion_Params *model);
#endif // CONFIG_GLOBAL_MOTION
#ifdef __cplusplus

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be
* found in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include "vp9/common/vp9_common_data.h"
#include "vp9/common/vp9_mv.h"
#include "vp9/common/vp9_motion_model.h"
INLINE projectPointsType get_projectPointsType(TransformationType type) {
switch (type) {
case HOMOGRAPHY:
return projectPointsHomography;
case AFFINE:
return projectPointsAffine;
case ROTZOOM:
return projectPointsRotZoom;
case TRANSLATION:
return projectPointsTranslation;
default:
assert(0);
return NULL;
}
}
void projectPointsTranslation(double *mat, double *points, double *proj,
const int n,
const int stride_points,
const int stride_proj) {
int i;
for (i = 0; i < n; ++i) {
const double x = *(points++), y = *(points++);
*(proj++) = x + mat[0];
*(proj++) = y + mat[1];
points += stride_points - 2;
proj += stride_proj - 2;
}
}
void projectPointsRotZoom(double *mat, double *points,
double *proj, const int n,
const int stride_points, const int stride_proj) {
int i;
for (i = 0; i < n; ++i) {
const double x = *(points++), y = *(points++);
*(proj++) = mat[0] * x + mat[1] * y + mat[2];
*(proj++) = -mat[1] * x + mat[0] * y + mat[3];
points += stride_points - 2;
proj += stride_proj - 2;
}
}
void projectPointsAffine(double *mat, double *points,
double *proj, const int n,
const int stride_points, const int stride_proj) {
int i;
for (i = 0; i < n; ++i) {
const double x = *(points++), y = *(points++);
*(proj++) = mat[0] * x + mat[1] * y + mat[4];
*(proj++) = mat[2] * x + mat[3] * y + mat[5];
points += stride_points - 2;
proj += stride_proj - 2;
}
}
void projectPointsHomography(double *mat, double *points,
double *proj, const int n,
const int stride_points, const int stride_proj) {
int i;
double x, y, Z;
for (i = 0; i < n; ++i) {
x = *(points++), y = *(points++);
Z = 1. / (mat[6] * x + mat[7] * y + mat[8]);
*(proj++) = (mat[0] * x + mat[1] * y + mat[2]) * Z;
*(proj++) = (mat[3] * x + mat[4] * y + mat[5]) * Z;
points += stride_points - 2;
proj += stride_proj - 2;
}
}
#define clip_pixel(v) ((v) < 0 ? 0 : ((v) > 255 ? 255 : (v)))
static unsigned char bilinear(unsigned char *ref, double x, double y,
int width, int height, int stride) {
if (x < 0 && y < 0) return ref[0];
else if (x < 0 && y > height - 1)
return ref[(height - 1) * stride];
else if (x > width - 1 && y < 0)
return ref[width - 1];
else if (x > width - 1 && y > height - 1)
return ref[(height - 1) * stride + (width - 1)];
else if (x < 0) {
int i = (int) y;
double a = y - i;
int v = (int)(ref[i * stride] * (1 - a) + ref[(i + 1) * stride] * a + 0.5);
return clip_pixel(v);
} else if (y < 0) {
int j = (int) x;
double b = x - j;
int v = (int)(ref[j] * (1 - b) + ref[j + 1] * b + 0.5);
return clip_pixel(v);
} else if (x > width - 1) {
int i = (int) y;
double a = y - i;
int v = (int)(ref[i * stride + width - 1] * (1 - a) +
ref[(i + 1) * stride + width - 1] * a + 0.5);
return clip_pixel(v);
} else if (y > height - 1) {
int j = (int) x;
double b = x - j;
int v = (int)(ref[(height - 1) * stride + j] * (1 - b) +
ref[(height - 1) * stride + j + 1] * b + 0.5);
return clip_pixel(v);
} else {
int i = (int) y;
int j = (int) x;
double a = y - i;
double b = x - j;
int v = (int)(ref[i * stride + j] * (1 - a) * (1 - b) +
ref[i * stride + j + 1] * (1 - a) * b +
ref[(i + 1) * stride + j] * a * (1 - b) +
ref[(i + 1) * stride + j + 1] * a * b);
return clip_pixel(v);
}
}
static void WarpImage(TransformationType type, double *H,
unsigned char *ref,
int width, int height, int stride,
unsigned char *pred,
int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_col, int subsampling_row,
int x_scale, int y_scale) {
int i, j;
projectPointsType projectPoints = get_projectPointsType(type);
if (projectPoints == NULL)
return;
for (i = p_row; i < p_row + p_height; ++i) {
for (j = p_col; j < p_col + p_width; ++j) {
double in[2], out[2];
in[0] = subsampling_col ? 2 * j + 0.5 : j;
in[1] = subsampling_row ? 2 * i + 0.5 : i;
projectPoints(H, in, out, 1, 2, 2);
out[0] = subsampling_col ? (out[0] - 0.5) / 2.0 : out[0];
out[1] = subsampling_row ? (out[1] - 0.5) / 2.0 : out[1];
out[0] *= x_scale / 16.0;
out[1] *= y_scale / 16.0;
pred[(j - p_col) + (i - p_row) * p_stride] =
bilinear(ref, out[0], out[1], width, height, stride);
}
}
}
static void convert_params_to_rotzoom(Global_Motion_Params *model,
double *H) {
double z = 1.0 + (double) model->zoom / (1 << ZOOM_PRECISION_BITS);
double r = (double) model->rotation / (1 << ROTATION_PRECISION_BITS);
H[0] = (1 + z) * cos(r * M_PI / 180.0);
H[1] = -(1 + z) * sin(r * M_PI / 180.0);
H[2] = (double) model->mv.as_mv.col / 8.0;
H[3] = (double) model->mv.as_mv.row / 8.0;
}
void vp9_warp_plane(Global_Motion_Params *gm,
unsigned char *ref,
int width, int height, int stride,
unsigned char *pred,
int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_col, int subsampling_row,
int x_scale, int y_scale) {
double H[9];
convert_params_to_rotzoom(gm, H);
WarpImage(ROTZOOM, H,
ref, width, height, stride,
pred, p_col, p_row, p_width, p_height, p_stride,
subsampling_col, subsampling_row,
x_scale, y_scale);
}
static int_mv vp9_get_global_mv(int col, int row, Global_Motion_Params *model) {
int_mv mv;
double H[4];
double x, y;
convert_params_to_rotzoom(model, H);
x = H[0] * col + H[1] * row + H[2];
y = -H[1] * col + H[0] * row + H[3];
mv.as_mv.col = (int)floor(x * 8 + 0.5) - col;
mv.as_mv.row = (int)floor(y * 8 + 0.5) - row;
return mv;
}
int_mv vp9_get_global_sb_center_mv(int col, int row, int bw, int bh,
Global_Motion_Params *model) {
col += bw / 2;
row += bh / 2;
return vp9_get_global_mv(col, row, model);
}
int_mv vp9_get_global_sub8x8_center_mv(int col, int row, int block,
Global_Motion_Params *model) {
if (block == 0 || block == 2)
col += 2;
else
col += 6;
if (block == 0 || block == 1)
row += 2;
else
row += 6;
return vp9_get_global_mv(col, row, model);
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be
* found in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VP9_COMMON_VP9_MOTION_MODEL_H
#define VP9_COMMON_VP9_MOTION_MODEL_H
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include "./vpx_config.h"
#include "vpx_ports/mem.h"
#include "vp9/common/vp9_enums.h"
#include "vp9/common/vp9_mv.h"
typedef void (*projectPointsType)(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
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
} TransformationType;
static INLINE int get_numparams(TransformationType type) {
switch (type) {
case HOMOGRAPHY:
return 9;
case AFFINE:
return 6;
case ROTZOOM:
return 4;
case TRANSLATION:
return 2;
default:
assert(0);
return 0;
}
}
INLINE projectPointsType get_projectPointsType(TransformationType type);
void projectPointsHomography(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void projectPointsAffine(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void projectPointsRotZoom(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void projectPointsTranslation(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void vp9_warp_plane(Global_Motion_Params *gm,
unsigned char *ref,
int width, int height, int stride,
unsigned char *pred,
int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_col, int subsampling_row,
int x_scale, int y_scale);
int_mv vp9_get_global_sb_center_mv(int col, int row, int bw, int bh,
Global_Motion_Params *model);
int_mv vp9_get_global_sub8x8_center_mv(int col, int row, int block,
Global_Motion_Params *model);
#endif // VP9_COMMON_VP9_MOTION_MODEL_H

View File

@ -48,6 +48,40 @@ static INLINE void clamp_mv(MV *mv, int min_col, int max_col,
mv->row = clamp(mv->row, min_row, max_row);
}
#if CONFIG_GLOBAL_MOTION
#define MAX_GLOBAL_MOTION_MODELS 1
#define ZOOM_PRECISION_BITS 6
#define ROTATION_PRECISION_BITS 4
#define ABS_ZOOM_BITS 3
#define ABS_ROTATION_BITS 4
#define ABS_TRANSLATION_BITS 7
typedef enum {
GLOBAL_ZERO = 0,
GLOBAL_TRANSLATION = 1,
GLOBAL_ROTZOOM = 2,
GLOBAL_MOTION_TYPES
} GLOBAL_MOTION_TYPE;
// Currently this is specialized for rotzoom model only
typedef struct {
GLOBAL_MOTION_TYPE gmtype;
int rotation; // positive or negative rotation angle in degrees
int zoom; // this is actually the zoom multiplier minus 1
int_mv mv;
} Global_Motion_Params;
static INLINE GLOBAL_MOTION_TYPE get_gmtype(Global_Motion_Params *gm) {
if (gm->rotation == 0 && gm->zoom == 0) {
return (gm->mv.as_int == 0 ? GLOBAL_ZERO : GLOBAL_TRANSLATION);
} else {
return GLOBAL_ROTZOOM;
}
}
#endif // CONFIG_GLOBAL_MOTION
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -270,7 +270,7 @@ static const int palette_color_context_lookup[PALETTE_COLOR_CONTEXTS] = {
int vp9_get_palette_color_context(const uint8_t *color_map, int cols,
int r, int c, int n, int *color_order) {
int i, j, max, max_idx, temp;
int scores[PALETTE_MAX_SIZE];
int scores[PALETTE_MAX_SIZE + 10];
int weights[4] = {3, 2, 3, 2};
int color_ctx = 0;
int color_neighbors[4];

View File

@ -19,6 +19,9 @@
#include "vp9/common/vp9_filter.h"
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_reconintra.h"
#if CONFIG_GLOBAL_MOTION
#include "vp9/common/vp9_motion_model.h"
#endif // CONFIG_GLOBAL_MOTION
static void build_mc_border(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride,
@ -655,6 +658,13 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
#endif // CONFIG_INTRABC
const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
int ref;
#if CONFIG_GLOBAL_MOTION
Global_Motion_Params *gm[2];
int is_global;
gm[0] = &xd->global_motion[mi->mbmi.ref_frame[0]][0];
if (is_compound)
gm[1] = &xd->global_motion[mi->mbmi.ref_frame[1]][0];
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_INTRABC
assert(!is_intrabc || mi->mbmi.interp_filter == BILINEAR);
#endif // CONFIG_INTRABC
@ -686,6 +696,14 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
int xs, ys, subpel_x, subpel_y;
const int is_scaled = vp9_is_scaled(sf);
#if CONFIG_GLOBAL_MOTION
is_global = (get_y_mode(mi, block) == ZEROMV &&
#if CONFIG_INTRABC
!is_intrabc &&
#endif
get_gmtype(gm[ref]) == GLOBAL_ROTZOOM);
#endif // CONFIG_GLOBAL_MOTION
if (is_scaled) {
#if CONFIG_INTRABC
assert(!is_intrabc);
@ -703,7 +721,7 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
subpel_x = scaled_mv.col & SUBPEL_MASK;
subpel_y = scaled_mv.row & SUBPEL_MASK;
pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride
+ (scaled_mv.col >> SUBPEL_BITS);
+ (scaled_mv.col >> SUBPEL_BITS);
#if CONFIG_WEDGE_PARTITION
if (ref && get_wedge_bits(mi->mbmi.sb_type)
@ -716,19 +734,31 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
#else
uint8_t tmp_dst[4096];
#endif
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys,
xd->bd);
#if CONFIG_GLOBAL_MOTION
if (is_global) {
vp9_warp_plane(gm[ref], pre_buf->buf0,
pre_buf->width, pre_buf->height, pre_buf->stride,
tmp_dst, (mi_x >> pd->subsampling_x) + x,
(mi_y >> pd->subsampling_y) + y, w, h, 64,
pd->subsampling_x, pd->subsampling_y, xs, ys);
} else {
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel,
xs, ys, xd->bd);
} else {
inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
}
#else
inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
}
#else
inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_GLOBAL_MOTION
}
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_SUPERTX
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
@ -763,32 +793,56 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
h, w);
#endif // CONFIG_SUPERTX
} else {
#if CONFIG_GLOBAL_MOTION
if (is_global) {
vp9_warp_plane(gm[ref], pre_buf->buf0,
pre_buf->width, pre_buf->height, pre_buf->stride, dst,
(mi_x >> pd->subsampling_x) + x,
(mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
pd->subsampling_x, pd->subsampling_y, xs, ys);
} else {
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
highbd_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel,
xs, ys, xd->bd);
else
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
highbd_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel,
xs, ys, xd->bd);
else
#endif // CONFIG_VP9_HIGHBITDEPTH
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
#if CONFIG_GLOBAL_MOTION
}
#endif // CONFIG_GLOBAL_MOTION
}
#else // CONFIG_WEDGE_PARTITION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys,
xd->bd);
#if CONFIG_GLOBAL_MOTION
if (is_global) {
vp9_warp_plane(gm[ref], pre_buf->buf0,
pre_buf->width, pre_buf->height, pre_buf->stride, dst,
(mi_x >> pd->subsampling_x) + x,
(mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
pd->subsampling_x, pd->subsampling_y, xs, ys);
} else {
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel,
xs, ys, xd->bd);
} else {
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
}
#else
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
}
#else
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_GLOBAL_MOTION
}
#endif // CONFIG_GLOBAL_MOTION
#endif // CONFIG_WEDGE_PARTITION
}
}
@ -1275,6 +1329,10 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
const int is_compound = has_second_ref(&mi->mbmi);
const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
int ref;
#if CONFIG_GLOBAL_MOTION
Global_Motion_Params *gm[2];
int is_global;
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_INTRABC
const int is_intrabc = is_intrabc_mode(mi->mbmi.mode);
struct scale_factors sf1;
@ -1283,6 +1341,11 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
assert(!is_intrabc || !is_compound);
#endif // CONFIG_INTRABC
#if CONFIG_GLOBAL_MOTION
gm[0] = &xd->global_motion[mi->mbmi.ref_frame[0]][0];
if (is_compound)
gm[1] = &xd->global_motion[mi->mbmi.ref_frame[1]][0];
#endif // CONFIG_GLOBAL_MOTION
for (ref = 0; ref < 1 + is_compound; ++ref) {
struct buf_2d *const dst_buf = &pd->dst;
@ -1313,6 +1376,14 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
uint8_t *ref_frame, *buf_ptr;
const int is_scaled = vp9_is_scaled(sf);
#if CONFIG_GLOBAL_MOTION
is_global = (get_y_mode(mi, block) == ZEROMV &&
#if CONFIG_INTRABC
!is_intrabc &&
#endif
get_gmtype(gm[ref]) == GLOBAL_ROTZOOM);
#endif // CONFIG_GLOBAL_MOTION
// Get reference frame pointer, width and height.
if (plane == 0) {
frame_width = ref_buf->y_crop_width;
@ -1461,19 +1532,31 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
#else
uint8_t tmp_dst[4096];
#endif
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(buf_ptr, buf_stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel,
xs, ys, xd->bd);
#if CONFIG_GLOBAL_MOTION
if (is_global) {
vp9_warp_plane(gm[ref], pre_buf->buf0,
pre_buf->width, pre_buf->height, pre_buf->stride,
tmp_dst, (mi_x >> pd->subsampling_x) + x,
(mi_y >> pd->subsampling_y) + y, w, h, 64,
pd->subsampling_x, pd->subsampling_y, xs, ys);
} else {
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(buf_ptr, buf_stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel,
xs, ys, xd->bd);
} else {
inter_predictor(buf_ptr, buf_stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
}
#else
inter_predictor(buf_ptr, buf_stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
}
#else
inter_predictor(buf_ptr, buf_stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_GLOBAL_MOTION
}
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_SUPERTX
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
@ -1512,32 +1595,56 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // CONFIG_SUPERTX
} else {
#if CONFIG_GLOBAL_MOTION
if (is_global) {
vp9_warp_plane(gm[ref], pre_buf->buf0,
pre_buf->width, pre_buf->height, pre_buf->stride, dst,
(mi_x >> pd->subsampling_x) + x,
(mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
pd->subsampling_x, pd->subsampling_y, xs, ys);
} else {
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
highbd_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel,
xs, ys, xd->bd);
else
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
highbd_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel,
xs, ys, xd->bd);
else
#endif // CONFIG_VP9_HIGHBITDEPTH
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
subpel_y, sf, w, h, ref, kernel, xs, ys);
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
subpel_y, sf, w, h, ref, kernel, xs, ys);
#if CONFIG_GLOBAL_MOTION
}
#endif // CONFIG_GLOBAL_MOTION
}
#else // CONFIG_WEDGE_PARTITION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys,
xd->bd);
#if CONFIG_GLOBAL_MOTION
if (is_global) {
vp9_warp_plane(gm[ref], pre_buf->buf0,
pre_buf->width, pre_buf->height, pre_buf->stride, dst,
(mi_x >> pd->subsampling_x) + x,
(mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
pd->subsampling_x, pd->subsampling_y, xs, ys);
} else {
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
highbd_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel,
xs, ys, xd->bd);
} else {
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
subpel_y, sf, w, h, ref, kernel, xs, ys);
}
#else
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
subpel_y, sf, w, h, ref, kernel, xs, ys);
}
#else
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
subpel_y, sf, w, h, ref, kernel, xs, ys);
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_GLOBAL_MOTION
}
#endif // CONFIG_GLOBAL_MOTION
#endif // CONFIG_WEDGE_PARTITION
}
}
@ -1865,11 +1972,16 @@ void vp9_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
src->alpha_buffer};
const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
src->alpha_stride};
const int widths[4] = {src->y_crop_width, src->uv_crop_width,
src->uv_crop_width, src->alpha_width};
const int heights[4] = {src->y_crop_height, src->uv_crop_height,
src->uv_crop_height, src->alpha_height};
int i;
for (i = 0; i < MAX_MB_PLANE; ++i) {
struct macroblockd_plane *const pd = &planes[i];
setup_pred_plane(&pd->dst, buffers[i], strides[i], mi_row, mi_col, NULL,
setup_pred_plane(&pd->dst, widths[i], heights[i],
buffers[i], strides[i], mi_row, mi_col, NULL,
pd->subsampling_x, pd->subsampling_y);
}
}
@ -1884,10 +1996,15 @@ void vp9_setup_pre_planes(MACROBLOCKD *xd, int idx,
src->alpha_buffer};
const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
src->alpha_stride};
const int widths[4] = {src->y_crop_width, src->uv_crop_width,
src->uv_crop_width, src->alpha_width};
const int heights[4] = {src->y_crop_height, src->uv_crop_height,
src->uv_crop_height, src->alpha_height};
for (i = 0; i < MAX_MB_PLANE; ++i) {
struct macroblockd_plane *const pd = &xd->plane[i];
setup_pred_plane(&pd->pre[idx], buffers[i], strides[i], mi_row, mi_col,
setup_pred_plane(&pd->pre[idx], widths[i], heights[i],
buffers[i], strides[i], mi_row, mi_col,
sf, pd->subsampling_x, pd->subsampling_y);
}
}

View File

@ -58,14 +58,18 @@ static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
}
static INLINE void setup_pred_plane(struct buf_2d *dst,
int width, int height,
uint8_t *src, int stride,
int mi_row, int mi_col,
const struct scale_factors *scale,
int subsampling_x, int subsampling_y) {
const int x = (MI_SIZE * mi_col) >> subsampling_x;
const int y = (MI_SIZE * mi_row) >> subsampling_y;
dst->buf0 = src;
dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
dst->stride = stride;
dst->width = width;
dst->height = height;
}
void vp9_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],

View File

@ -2474,6 +2474,7 @@ static void read_global_motion_params(Global_Motion_Params *params,
vp9_reader *r) {
GLOBAL_MOTION_TYPE gmtype = vp9_read_tree(r, vp9_global_motion_types_tree,
probs);
params->gmtype = gmtype;
switch (gmtype) {
case GLOBAL_ZERO:
break;
@ -2748,6 +2749,9 @@ void vp9_decode_frame(VP9Decoder *pbi,
const int tile_cols = 1 << cm->log2_tile_cols;
YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm);
xd->cur_buf = new_fb;
#if CONFIG_GLOBAL_MOTION
xd->global_motion = cm->global_motion;
#endif // CONFIG_GLOBAL_MOTION
if (!first_partition_size) {
// showing a frame directly

View File

@ -2209,12 +2209,14 @@ static void write_global_motion(VP9_COMP *cpi, vp9_writer *w) {
}
write_global_motion_params(
cm->global_motion[frame], cm->fc.global_motion_types_prob, w);
/*
printf("Ref %d [%d] (used %d): %d %d %d %d\n",
frame, cm->current_video_frame, cpi->global_motion_used[frame],
cm->global_motion[frame][i].zoom,
cm->global_motion[frame][i].rotation,
cm->global_motion[frame][i].mv.as_mv.col,
cm->global_motion[frame][i].mv.as_mv.row);
*/
}
}
}

View File

@ -1194,13 +1194,18 @@ void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
int mi_row, int mi_col) {
uint8_t *const buffers[3] = {src->y_buffer, src->u_buffer, src->v_buffer };
const int strides[3] = {src->y_stride, src->uv_stride, src->uv_stride };
const int widths[3] = {src->y_crop_width, src->uv_crop_width,
src->uv_crop_width};
const int heights[3] = {src->y_crop_height, src->uv_crop_height,
src->uv_crop_height};
int i;
// Set current frame pointer.
x->e_mbd.cur_buf = src;
for (i = 0; i < MAX_MB_PLANE; i++)
setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
setup_pred_plane(&x->plane[i].src, widths[i], heights[i],
buffers[i], strides[i], mi_row, mi_col,
NULL, x->e_mbd.plane[i].subsampling_x,
x->e_mbd.plane[i].subsampling_y);
}
@ -4588,7 +4593,7 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#endif
#if CONFIG_GLOBAL_MOTION
#define MIN_TRANSLATION_THRESH 4
#define MIN_TRANSLATION_THRESH 16
static void convert_translation_to_params(
double *H, Global_Motion_Params *model) {
model->mv.as_mv.col = (int) floor(H[0] * 8 + 0.5);
@ -4632,6 +4637,7 @@ static void convert_model_to_params(double *H, TransformationType type,
default:
break;
}
model->gmtype = get_gmtype(model);
}
#endif // CONFIG_GLOBAL_MOTION
@ -4660,7 +4666,9 @@ static void encode_frame_internal(VP9_COMP *cpi) {
cm->tx_mode = select_tx_mode(cpi);
#if CONFIG_GLOBAL_MOTION
#define GLOBAL_MOTION_MODEL TRANSLATION
#define GLOBAL_MOTION_MODEL TRANSLATION
// #define USE_BLOCK_BASED_GLOBAL_MOTION_COMPUTATION
vp9_clear_system_state();
vp9_zero(cpi->global_motion_used);
vpx_memset(cm->num_global_motion, 0, sizeof(cm->num_global_motion));
cm->num_global_motion[LAST_FRAME] = 1;
@ -4674,28 +4682,33 @@ static void encode_frame_internal(VP9_COMP *cpi) {
ref_buf = get_ref_frame_buffer(cpi, frame);
if (ref_buf) {
if ((num =
#ifdef USE_BLOCK_BASED_GLOBAL_MOTION_COMPUTATION
vp9_compute_global_motion_multiple_block_based(
cpi, GLOBAL_MOTION_MODEL, cpi->Source, ref_buf,
BLOCK_16X16, MAX_GLOBAL_MOTION_MODELS, 0.5, global_motion))) {
/*
#else
vp9_compute_global_motion_multiple_feature_based(
cpi, GLOBAL_MOTION_MODEL, cpi->Source, ref_buf,
MAX_GLOBAL_MOTION_MODELS, 0.5, global_motion))) {
*/
#endif
int i;
for (i = 0; i < num; i++) {
/*
printf("Ref %d [%d]: %f %f\n",
frame, cm->current_video_frame,
global_motion[i * get_numparams(GLOBAL_MOTION_MODEL)],
global_motion[i * get_numparams(GLOBAL_MOTION_MODEL) + 1]);
*/
convert_model_to_params(
global_motion + i * get_numparams(GLOBAL_MOTION_MODEL),
GLOBAL_MOTION_MODEL,
&cm->global_motion[frame][i]);
/*
printf("Ref %d [%d]: %d %d %d %d\n",
frame, cm->current_video_frame,
cm->global_motion[frame][i].zoom,
cm->global_motion[frame][i].rotation,
cm->global_motion[frame][i].mv.as_mv.col,
cm->global_motion[frame][i].mv.as_mv.row);
*/
}
cm->num_global_motion[frame] = num;
}

View File

@ -1477,6 +1477,9 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
#if CONFIG_VP9_HIGHBITDEPTH
cpi->mb.e_mbd.bd = (int)cm->bit_depth;
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_GLOBAL_MOTION
cpi->mb.e_mbd.global_motion = cm->global_motion;
#endif
rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;

View File

@ -22,11 +22,12 @@
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/common/vp9_motion_model.h"
#include "vp9/encoder/vp9_corner_detect.h"
#include "vp9/encoder/vp9_corner_match.h"
#include "vp9/encoder/vp9_ransac.h"
#include "vp9/encoder/vp9_global_motion.h"
#include "vp9/encoder/vp9_motionmodel.h"
#include "vp9/encoder/vp9_motion_field.h"
// #define VERBOSE
@ -53,22 +54,6 @@ INLINE ransacType get_ransacType(TransformationType type) {
}
}
INLINE projectPointsType get_projectPointsType(TransformationType type) {
switch (type) {
case HOMOGRAPHY:
return projectPointsHomography;
case AFFINE:
return projectPointsAffine;
case ROTZOOM:
return projectPointsRotZoom;
case TRANSLATION:
return projectPointsTranslation;
default:
assert(0);
return NULL;
}
}
static double compute_error_score(TransformationType type,
int *points1, int stride1,
int *points2, int stride2,

View File

@ -20,39 +20,14 @@
#include "vp9_corner_detect.h"
#include "vp9_corner_match.h"
#include "vp9_ransac.h"
#include "vp9/common/vp9_motion_model.h"
struct VP9_COMP;
static const int CONFIDENCE_THRESHOLD = 1.0;
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
} TransformationType;
static INLINE int get_numparams(TransformationType type) {
switch (type) {
case HOMOGRAPHY:
return 9;
case AFFINE:
return 6;
case ROTZOOM:
return 4;
case TRANSLATION:
return 2;
default:
assert(0);
return 0;
}
}
INLINE ransacType get_ransacType(TransformationType type);
INLINE projectPointsType get_projectPointsType(TransformationType type);
// Returns number of models actually returned: 1 - if success, 0 - if failure
int vp9_compute_global_motion_single_feature_based(struct VP9_COMP *cpi,
TransformationType type,

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VP9_ENCODER_VP9_MOTIONMODEL_H_
#define VP9_ENCODER_VP9_MOTIONMODEL_H_
#ifndef VP9_ENCODER_VP9_MOTION_FIELD_H_
#define VP9_ENCODER_VP9_MOTION_FIELD_H_
#ifdef __cplusplus
extern "C" {
@ -34,4 +34,4 @@ void vp9_get_ref_motionfield(struct VP9_COMP *cpi,
} // extern "C"
#endif
#endif // VP9_ENCODER_VP9_MOTIONMODEL_H_
#endif // VP9_ENCODER_VP9_MOTION_FIELD_H_

View File

@ -84,10 +84,10 @@ static int try_bilateral_frame(const YV12_BUFFER_CONFIG *sd,
return filt_err;
}
static int64_t search_bilateral_level(const YV12_BUFFER_CONFIG *sd,
VP9_COMP *cpi,
int filter_level, int partial_frame,
double *best_cost_ret) {
static int search_bilateral_level(const YV12_BUFFER_CONFIG *sd,
VP9_COMP *cpi,
int filter_level, int partial_frame,
double *best_cost_ret) {
VP9_COMMON *const cm = &cpi->common;
int i, bilateral_best, err;
double best_cost;

View File

@ -119,7 +119,7 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int64_t best_rd_sofar) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0, 0, 0, 0}};
const int step_param = cpi->sf.mv.fullpel_search_step_param;
const int sadpb = x->sadperbit16;
MV mvp_full;

View File

@ -38,11 +38,11 @@ static inline double PYTHAG(double a, double b) {
absb = fabs(b);
if(absa > absb) {
ct = absb/absa;
return absa * sqrt(1.0 + ct*ct);
ct = absb / absa;
return absa * sqrt(1.0 + ct * ct);
} else {
ct = absa/absb;
return (absb == 0) ? 0 : absb * sqrt(1.0 + ct*ct);
ct = absa / absb;
return (absb == 0) ? 0 : absb * sqrt(1.0 + ct * ct);
}
}
@ -66,7 +66,7 @@ static void MultiplyMat(double *m1, double *m2, double *res,
for( col = 0; col < timesCols; ++col ) {
sum = 0;
for (inner = 0; inner < timesInner; ++inner )
sum += m1[row*N1 + inner] * m2[inner*N2 + col];
sum += m1[row * N1 + inner] * m2[inner * N2 + col];
*(res++) = sum;
}
}
@ -78,121 +78,124 @@ static int svdcmp_(double **u, int m, int n, double w[], double **v) {
double anorm, c, f, g, h, s, scale, x, y, z;
double *rv1 = (double *)malloc(sizeof(double) * (n + 1));
g = scale = anorm = 0.0;
for (i=0;i<n;i++) {
l=i+1;
rv1[i]=scale*g;
g=s=scale=0.0;
for (i = 0; i < n; i++) {
l = i + 1;
rv1[i] = scale * g;
g = s = scale = 0.0;
if (i < m) {
for (k=i;k<m;k++) scale += fabs(u[k][i]);
for (k = i; k < m; k++) scale += fabs(u[k][i]);
if (scale) {
for (k=i; k<m; k++) {
for (k = i; k < m; k++) {
u[k][i] /= scale;
s += u[k][i]*u[k][i];
s += u[k][i] * u[k][i];
}
f = u[i][i];
g = -SIGN(sqrt(s), f);
h=f*g-s;
u[i][i]=f-g;
for (j=l;j<n;j++) {
for (s=0.0,k=i;k<m;k++) s += u[k][i]*u[k][j];
f=s/h;
for (k=i;k<m;k++) u[k][j] += f*u[k][i];
h = f * g - s;
u[i][i] = f - g;
for (j = l; j < n; j++) {
for (s = 0.0, k = i; k < m; k++) s += u[k][i] * u[k][j];
f = s / h;
for (k = i; k < m; k++) u[k][j] += f * u[k][i];
}
for (k=i;k<m;k++) u[k][i] *= scale;
for (k = i; k < m; k++) u[k][i] *= scale;
}
}
w[i]=scale *g;
g=s=scale=0.0;
w[i] = scale * g;
g = s = scale = 0.0;
if (i < m && i != n - 1) {
for (k=l;k<n;k++) scale += fabs(u[i][k]);
for (k = l; k < n; k++)
scale += fabs(u[i][k]);
if (scale) {
for (k=l;k<n;k++) {
for (k = l; k < n; k++) {
u[i][k] /= scale;
s += u[i][k]*u[i][k];
s += u[i][k] * u[i][k];
}
f=u[i][l];
f = u[i][l];
g = -SIGN(sqrt(s),f);
h=f*g-s;
u[i][l]=f-g;
for (k=l;k<n;k++) rv1[k]=u[i][k]/h;
for (j=l;j<m;j++) {
for (s=0.0,k=l;k<n;k++) s += u[j][k]*u[i][k];
for (k=l;k<n;k++) u[j][k] += s*rv1[k];
h = f * g - s;
u[i][l] = f - g;
for (k = l; k < n; k++) rv1[k] = u[i][k] / h;
for (j = l; j < m; j++) {
for (s = 0.0, k = l; k < n; k++) s += u[j][k] * u[i][k];
for (k = l; k < n; k++) u[j][k] += s * rv1[k];
}
for (k=l;k<n;k++) u[i][k] *= scale;
for (k = l; k < n; k++) u[i][k] *= scale;
}
}
anorm=fmax(anorm,(fabs(w[i])+fabs(rv1[i])));
anorm = fmax(anorm, (fabs(w[i]) + fabs(rv1[i])));
}
for (i=n-1;i>=0;i--) {
for (i = n - 1; i >= 0; i--) {
if (i < n - 1) {
if (g) {
for (j=l;j<n;j++) v[j][i]=(u[i][j]/u[i][l])/g;
for (j=l;j<n;j++) {
for (s=0.0,k=l;k<n;k++) s += u[i][k]*v[k][j];
for (k=l;k<n;k++) v[k][j] += s*v[k][i];
for (j = l; j < n; j++) v[j][i] = (u[i][j] / u[i][l]) / g;
for (j = l; j < n; j++) {
for (s = 0.0, k = l; k < n; k++) s += u[i][k] * v[k][j];
for (k = l; k < n; k++) v[k][j] += s * v[k][i];
}
}
for (j=l;j<n;j++) v[i][j]=v[j][i]=0.0;
for (j = l; j < n; j++) v[i][j] = v[j][i] = 0.0;
}
v[i][i]=1.0;
g=rv1[i];
l=i;
v[i][i] = 1.0;
g = rv1[i];
l = i;
}
for (i = IMIN(m,n) - 1; i>=0; i--) {
l=i+1;
g=w[i];
for (j=l;j<n;j++) u[i][j]=0.0;
for (i = IMIN(m, n) - 1; i >= 0; i--) {
l = i + 1;
g = w[i];
for (j = l; j < n; j++) u[i][j] = 0.0;
if (g) {
g=1.0/g;
for (j=l;j<n;j++) {
for (s=0.0,k=l;k<m;k++) s += u[k][i]*u[k][j];
f = (s/u[i][i])*g;
for (k=i;k<m;k++) u[k][j] += f*u[k][i];
g = 1.0 / g;
for (j = l; j < n; j++) {
for (s = 0.0, k = l; k < m; k++) s += u[k][i] * u[k][j];
f = (s / u[i][i]) * g;
for (k = i; k < m; k++) u[k][j] += f * u[k][i];
}
for (j=i;j<m;j++) u[j][i] *= g;
} else for (j=i;j<m;j++) u[j][i]=0.0;
for (j = i; j < m; j++) u[j][i] *= g;
} else {
for (j = i; j < m; j++) u[j][i] = 0.0;
}
++u[i][i];
}
for (k=n-1;k>=0;k--) {
for (its=0;its<max_its;its++) {
flag=1;
for (l=k;l>=0;l--) {
nm=l-1;
if ((double)(fabs(rv1[l])+anorm) == anorm || nm < 0) {
flag=0;
for (k = n - 1; k >= 0; k--) {
for (its = 0; its < max_its; its++) {
flag = 1;
for (l = k; l >= 0; l--) {
nm = l - 1;
if ((double)(fabs(rv1[l]) + anorm) == anorm || nm < 0) {
flag = 0;
break;
}
if ((double)(fabs(w[nm])+anorm) == anorm) break;
if ((double)(fabs(w[nm]) + anorm) == anorm) break;
}
if (flag) {
c=0.0;
s=1.0;
for (i=l;i<=k;i++) {
f=s*rv1[i];
rv1[i]=c*rv1[i];
if ((double)(fabs(f)+anorm) == anorm) break;
g=w[i];
h=PYTHAG(f,g);
w[i]=h;
h=1.0/h;
c=g*h;
s = -f*h;
for (j=0;j<m;j++) {
y=u[j][nm];
z=u[j][i];
u[j][nm]=y*c+z*s;
u[j][i]=z*c-y*s;
c = 0.0;
s = 1.0;
for (i = l; i <= k; i++) {
f = s * rv1[i];
rv1[i] = c * rv1[i];
if ((double)(fabs(f) + anorm) == anorm) break;
g = w[i];
h = PYTHAG(f, g);
w[i] = h;
h = 1.0 / h;
c = g * h;
s = -f * h;
for (j = 0; j < m; j++) {
y = u[j][nm];
z = u[j][i];
u[j][nm] = y * c + z * s;
u[j][i] = z * c - y * s;
}
}
}
z=w[k];
z = w[k];
if (l == k) {
if (z < 0.0) {
w[k] = -z;
for (j=0;j<n;j++) v[j][k] = -v[j][k];
for (j = 0; j < n; j++) v[j][k] = -v[j][k];
}
break;
}
@ -200,54 +203,54 @@ static int svdcmp_(double **u, int m, int n, double w[], double **v) {
return 1;
}
assert(k > 0);
x=w[l];
nm=k-1;
y=w[nm];
g=rv1[nm];
h=rv1[k];
f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
g=PYTHAG(f,1.0);
f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
c=s=1.0;
for (j=l;j<=nm;j++) {
i=j+1;
g=rv1[i];
y=w[i];
h=s*g;
g=c*g;
z=PYTHAG(f,h);
rv1[j]=z;
c=f/z;
s=h/z;
f=x*c+g*s;
g = g*c-x*s;
h=y*s;
x = w[l];
nm = k - 1;
y = w[nm];
g = rv1[nm];
h = rv1[k];
f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
g = PYTHAG(f, 1.0);
f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
c = s = 1.0;
for (j = l; j <= nm; j++) {
i = j + 1;
g = rv1[i];
y = w[i];
h = s * g;
g = c * g;
z = PYTHAG(f, h);
rv1[j] = z;
c = f / z;
s = h / z;
f = x * c + g * s;
g = g * c - x * s;
h = y * s;
y *= c;
for (jj=0;jj<n;jj++) {
x=v[jj][j];
z=v[jj][i];
v[jj][j]=x*c+z*s;
v[jj][i]=z*c-x*s;
for (jj = 0; jj < n; jj++) {
x = v[jj][j];
z = v[jj][i];
v[jj][j] = x * c + z * s;
v[jj][i] = z * c - x * s;
}
z=PYTHAG(f,h);
w[j]=z;
z = PYTHAG(f, h);
w[j] = z;
if (z) {
z=1.0/z;
c=f*z;
s=h*z;
z = 1.0 / z;
c = f * z;
s = h * z;
}
f=c*g+s*y;
x=c*y-s*g;
for (jj=0;jj<m;jj++) {
y=u[jj][j];
z=u[jj][i];
u[jj][j]=y*c+z*s;
u[jj][i]=z*c-y*s;
f = c * g + s * y;
x = c * y - s * g;
for (jj = 0; jj < m; jj++) {
y = u[jj][j];
z = u[jj][i];
u[jj][j] = y * c + z * s;
u[jj][i] = z * c - y * s;
}
}
rv1[l]=0.0;
rv1[k]=f;
w[k]=x;
rv1[l] = 0.0;
rv1[k] = f;
w[k] = x;
}
}
free(rv1);
@ -264,10 +267,10 @@ static int SVD(double *U, double *W, double *V, double *matx, int M, int N) {
problem = !(nrU && nrV);
if (!problem) {
problem = 0;
for (i=0; i<M; i++) {
for (i = 0; i < M; i++) {
nrU[i] = &U[i * N];
}
for(i=0; i<N; i++) {
for (i = 0; i < N; i++) {
nrV[i] = &V[i * N];
}
}
@ -276,8 +279,8 @@ static int SVD(double *U, double *W, double *V, double *matx, int M, int N) {
}
/* copy from given matx into nrU */
for (i=0; i<M; i++) {
memcpy(&(nrU[i][0]), matx + N*i, N*sizeof(double));
for (i = 0; i < M; i++) {
memcpy(&(nrU[i][0]), matx + N * i, N * sizeof(*matx));
}
/* HERE IT IS: do SVD */
@ -295,9 +298,9 @@ static int SVD(double *U, double *W, double *V, double *matx, int M, int N) {
int PseudoInverse(double *inv, double *matx, const int M, const int N) {
double *U, *W, *V, ans;
int i, j, k;
U = (double *)malloc(M*N*sizeof(double));
W = (double *)malloc(N*sizeof(double));
V = (double *)malloc(N*N*sizeof(double));
U = (double *)malloc(M * N * sizeof(*matx));
W = (double *)malloc(N * sizeof(*matx));
V = (double *)malloc(N * N * sizeof(*matx));
if (!(U && W && V)) {
return 1;
@ -305,19 +308,19 @@ int PseudoInverse(double *inv, double *matx, const int M, const int N) {
if (SVD(U, W, V, matx, M, N)) {
return 1;
}
for (i=0; i<N; i++) {
for (i = 0; i < N; i++) {
if (fabs(W[i]) < TINY_NEAR_ZERO) {
return 1;
}
}
for (i=0; i<N; i++) {
for (j=0; j<M; j++) {
for (i = 0; i < N; i++) {
for (j = 0; j < M; j++) {
ans = 0;
for (k=0; k<N; k++) {
ans += V[k + N*i]*U[k + N*j]/W[k];
for (k = 0; k < N; k++) {
ans += V[k + N * i] * U[k + N * j] / W[k];
}
inv[j + M*i] = ans;
inv[j + M * i] = ans;
}
}
free(U);
@ -338,7 +341,7 @@ static double compute_error(projectPointsType projectPoints,
if (projectPoints == NULL) return -1.0;
if (mask) {
for (i = 0; i < npoints; ++i, mp1+=stride1, mp2+=stride2) {
for (i = 0; i < npoints; ++i, mp1 += stride1, mp2 += stride2) {
if (mask[i]) {
projectPoints(H, mp1, pt, 1, stride1, stride2);
sqerr += (pt[0] - mp2[0]) * (pt[0] - mp2[0]) +
@ -347,7 +350,7 @@ static double compute_error(projectPointsType projectPoints,
}
}
} else {
for (i = 0; i < npoints; ++i, mp1+=stride1, mp2+=stride2) {
for (i = 0; i < npoints; ++i, mp1 += stride1, mp2 += stride2) {
projectPoints(H, mp1, pt, 1, stride1, stride2);
sqerr += (pt[0] - mp2[0]) * (pt[0] - mp2[0]) +
(pt[1] - mp2[1]) * (pt[1] - mp2[1]);
@ -405,7 +408,7 @@ int ransac_(double *matched_points,
projectPointsType projectPoints) {
static const double INLIER_THRESHOLD_NORMALIZED = 0.1;
static const double INLIER_THRESHOLD_UNNORMALIZED = 0.5;
static const double INLIER_THRESHOLD_UNNORMALIZED = 1.0;
static const double PROBABILITY_REQUIRED = 0.9;
static const double EPS = 1e-12;
static const int MIN_TRIALS = 20;
@ -716,61 +719,6 @@ static int isDegenerateHomography(double *p) {
is_collinear3(p + 2, p + 4, p + 6);
}
void projectPointsTranslation(double *mat, double *points, double *proj,
const int n,
const int stride_points,
const int stride_proj) {
int i;
for (i = 0; i < n; ++i) {
const double x = *(points++), y = *(points++);
*(proj++) = x + mat[0];
*(proj++) = y + mat[1];
points += stride_points - 2;
proj += stride_proj - 2;
}
}
void projectPointsRotZoom(double *mat, double *points,
double *proj, const int n,
const int stride_points, const int stride_proj) {
int i;
for (i = 0; i < n; ++i) {
const double x = *(points++), y = *(points++);
*(proj++) = mat[0]*x + mat[1]*y + mat[2];
*(proj++) = -mat[1]*x + mat[0]*y + mat[3];
points += stride_points - 2;
proj += stride_proj - 2;
}
}
void projectPointsAffine(double *mat, double *points,
double *proj, const int n,
const int stride_points, const int stride_proj) {
int i;
for (i = 0; i < n; ++i) {
const double x = *(points++), y = *(points++);
*(proj++) = mat[0]*x + mat[1]*y + mat[4];
*(proj++) = mat[2]*x + mat[3]*y + mat[5];
points += stride_points - 2;
proj += stride_proj - 2;
}
}
void projectPointsHomography(double *mat, double *points,
double *proj, const int n,
const int stride_points, const int stride_proj) {
int i;
double x, y, Z;
for (i = 0; i < n; ++i) {
x = *(points++), y = *(points++);
Z = 1./(mat[6]*x + mat[7]*y + mat[8]);
*(proj++) = (mat[0]*x + mat[1]*y + mat[2])*Z;
*(proj++) = (mat[3]*x + mat[4]*y + mat[5])*Z;
points += stride_points - 2;
proj += stride_proj - 2;
}
}
int findTranslation(const int np, double *pts1, double *pts2, double *mat) {
int i;
double sx, sy, dx, dy;
@ -1002,7 +950,7 @@ int ransacTranslation(double *matched_points, int npoints,
number_of_inliers,
best_inlier_mask,
bestH,
2,
3,
2,
isDegenerateTranslation,
NULL, // normalizeHomography,

View File

@ -16,12 +16,11 @@
#include <math.h>
#include <memory.h>
#include "vp9/common/vp9_motion_model.h"
typedef int (*ransacType)(double *matched_points, int npoints,
int *number_of_inliers, int *best_inlier_mask,
double *bestH);
typedef void (*projectPointsType)(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
int ransacHomography(double *matched_points, int npoints,
int *number_of_inliers, int *best_inlier_indices,
@ -36,17 +35,4 @@ int ransacTranslation(double *matched_points, int npoints,
int *number_of_inliers, int *best_inlier_indices,
double *bestH);
void projectPointsHomography(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void projectPointsAffine(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void projectPointsRotZoom(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
void projectPointsTranslation(double *mat, double *points, double *proj,
const int n, const int stride_points,
const int stride_proj);
#endif // VP9_ENCODER_VP9_RANSAC_H

View File

@ -583,7 +583,10 @@ void vp9_setup_pred_block(const MACROBLOCKD *xd,
dst[1].stride = dst[2].stride = src->uv_stride;
for (i = 0; i < MAX_MB_PLANE; ++i) {
setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col,
setup_pred_plane(dst + i,
i ? src->uv_crop_width : src->y_crop_width,
i ? src->uv_crop_height : src->y_crop_height,
dst[i].buf, dst[i].stride, mi_row, mi_col,
i ? scale_uv : scale,
xd->plane[i].subsampling_x, xd->plane[i].subsampling_y);
}

View File

@ -3455,11 +3455,15 @@ static int64_t rd_pick_best_sub8x8_mode(
if (!(inter_mode_mask & (1 << this_mode)))
continue;
#if !CONFIG_GLOBAL_MOTION
if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
this_mode, mbmi->ref_frame))
continue;
#if CONFIG_GLOBAL_MOTION
if (get_gmtype(&cm->global_motion[mbmi->ref_frame[0]][0]) ==
GLOBAL_ZERO &&
get_gmtype(&cm->global_motion[mbmi->ref_frame[1]][0]) ==
GLOBAL_ZERO)
#endif
if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
this_mode, mbmi->ref_frame))
continue;
vpx_memcpy(orig_pre, pd->pre, sizeof(orig_pre));
vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
@ -3939,7 +3943,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
MACROBLOCKD *xd = &x->e_mbd;
const VP9_COMMON *cm = &cpi->common;
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0, 0, 0, 0}};
int bestsme = INT_MAX;
int step_param;
int sadpb = x->sadperbit16;
@ -4268,7 +4272,7 @@ static void do_masked_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
MACROBLOCKD *xd = &x->e_mbd;
const VP9_COMMON *cm = &cpi->common;
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0, 0, 0, 0}};
int bestsme = INT_MAX;
int step_param;
int sadpb = x->sadperbit16;
@ -6351,13 +6355,18 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
continue;
}
}
#if !CONFIG_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION
} else if (get_gmtype(&cm->global_motion[ref_frame][0]) ==
GLOBAL_ZERO &&
get_gmtype(&cm->global_motion[second_ref_frame][0]) ==
GLOBAL_ZERO) {
#else
} else {
#endif // CONFIG_GLOBAL_MOTION
const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
this_mode, ref_frames))
continue;
#endif // !CONFIG_GLOBAL_MOTION
}
#if CONFIG_INTERINTRA
if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME &&

View File

@ -68,6 +68,8 @@ VP9_COMMON_SRCS-yes += common/vp9_common_data.c
VP9_COMMON_SRCS-yes += common/vp9_common_data.h
VP9_COMMON_SRCS-yes += common/vp9_scan.c
VP9_COMMON_SRCS-yes += common/vp9_scan.h
VP9_COMMON_SRCS-$(CONFIG_GLOBAL_MOTION) += common/vp9_motion_model.c
VP9_COMMON_SRCS-$(CONFIG_GLOBAL_MOTION) += common/vp9_motion_model.h
VP9_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/vp9_asm_stubs.c
VP9_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/vp9_loopfilter_intrin_sse2.c

View File

@ -83,8 +83,8 @@ VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_corner_match.c
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_corner_match.h
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_global_motion.c
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_global_motion.h
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_motionmodel.c
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_motionmodel.h
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_motion_field.c
VP9_CX_SRCS-$(CONFIG_GLOBAL_MOTION) += encoder/vp9_motion_field.h
VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_ssim.c
VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_ssim.h
VP9_CX_SRCS-yes += encoder/vp9_tokenize.c