Adds warping functions. Also includes some refactoring.
Change-Id: I909830650f29046edf108ddaddceb1a5e7c6c61c
struct buf_2d {
uint8_t *buf;
+ uint8_t *buf0;
+ int width;
+ int height;
int stride;
};
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,
// 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) {
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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
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
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];
#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,
#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
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);
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)
#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) {
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
}
}
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;
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;
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;
#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) {
#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
}
}
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);
}
}
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);
}
}
}
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],
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;
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
}
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);
+ */
}
}
}
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);
}
#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);
default:
break;
}
+ model->gmtype = get_gmtype(model);
}
#endif // CONFIG_GLOBAL_MOTION
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;
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;
}
#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;
#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
}
}
-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,
#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,
* 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" {
} // extern "C"
#endif
-#endif // VP9_ENCODER_VP9_MOTIONMODEL_H_
+#endif // VP9_ENCODER_VP9_MOTION_FIELD_H_
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;
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;
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);
}
}
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;
}
}
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;
}
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);
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];
}
}
}
/* 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 */
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;
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);
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]) +
}
}
} 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]);
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;
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;
number_of_inliers,
best_inlier_mask,
bestH,
- 2,
+ 3,
2,
isDegenerateTranslation,
NULL, // normalizeHomography,
#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,
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
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);
}
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,
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;
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;
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 &&
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
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