From fb093a337f74979b1b86b10d887fc86423a15bd8 Mon Sep 17 00:00:00 2001 From: Debargha Mukherjee Date: Thu, 7 May 2015 15:09:40 -0700 Subject: [PATCH] Global motion enhancements Adds warping functions. Also includes some refactoring. Change-Id: I909830650f29046edf108ddaddceb1a5e7c6c61c --- vp9/common/vp9_blockd.h | 6 + vp9/common/vp9_entropymv.c | 41 --- vp9/common/vp9_entropymv.h | 28 -- vp9/common/vp9_motion_model.c | 223 ++++++++++++ vp9/common/vp9_motion_model.h | 81 +++++ vp9/common/vp9_mv.h | 34 ++ vp9/common/vp9_palette.c | 2 +- vp9/common/vp9_reconinter.c | 223 +++++++++--- vp9/common/vp9_reconinter.h | 4 + vp9/decoder/vp9_decodeframe.c | 4 + vp9/encoder/vp9_bitstream.c | 2 + vp9/encoder/vp9_encodeframe.c | 27 +- vp9/encoder/vp9_encoder.c | 3 + vp9/encoder/vp9_global_motion.c | 19 +- vp9/encoder/vp9_global_motion.h | 27 +- .../{vp9_motionmodel.c => vp9_motion_field.c} | 0 .../{vp9_motionmodel.h => vp9_motion_field.h} | 6 +- vp9/encoder/vp9_picklpf.c | 8 +- vp9/encoder/vp9_pickmode.c | 2 +- vp9/encoder/vp9_ransac.c | 336 ++++++++---------- vp9/encoder/vp9_ransac.h | 18 +- vp9/encoder/vp9_rd.c | 5 +- vp9/encoder/vp9_rdopt.c | 25 +- vp9/vp9_common.mk | 2 + vp9/vp9cx.mk | 4 +- 25 files changed, 728 insertions(+), 402 deletions(-) create mode 100644 vp9/common/vp9_motion_model.c create mode 100644 vp9/common/vp9_motion_model.h rename vp9/encoder/{vp9_motionmodel.c => vp9_motion_field.c} (100%) rename vp9/encoder/{vp9_motionmodel.h => vp9_motion_field.h} (89%) diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 2fb680f70..af4363878 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -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, diff --git a/vp9/common/vp9_entropymv.c b/vp9/common/vp9_entropymv.c index d58a36ebb..fe7b1ccda 100644 --- a/vp9/common/vp9_entropymv.c +++ b/vp9/common/vp9_entropymv.c @@ -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) { diff --git a/vp9/common/vp9_entropymv.h b/vp9/common/vp9_entropymv.h index 58ad7f267..94e75c6c9 100644 --- a/vp9/common/vp9_entropymv.h +++ b/vp9/common/vp9_entropymv.h @@ -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 diff --git a/vp9/common/vp9_motion_model.c b/vp9/common/vp9_motion_model.c new file mode 100644 index 000000000..ad35247f8 --- /dev/null +++ b/vp9/common/vp9_motion_model.c @@ -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 +#include +#include +#include +#include + +#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); +} diff --git a/vp9/common/vp9_motion_model.h b/vp9/common/vp9_motion_model.h new file mode 100644 index 000000000..82cba9cb9 --- /dev/null +++ b/vp9/common/vp9_motion_model.h @@ -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 +#include +#include +#include +#include + +#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 diff --git a/vp9/common/vp9_mv.h b/vp9/common/vp9_mv.h index 5d89da8c2..9dbbc9570 100644 --- a/vp9/common/vp9_mv.h +++ b/vp9/common/vp9_mv.h @@ -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 diff --git a/vp9/common/vp9_palette.c b/vp9/common/vp9_palette.c index d4c2d4dea..e3ae4d35e 100644 --- a/vp9/common/vp9_palette.c +++ b/vp9/common/vp9_palette.c @@ -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]; diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index c2568a1be..5f1d26853 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -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); } } diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h index b7f5e0be9..10b18cc2e 100644 --- a/vp9/common/vp9_reconinter.h +++ b/vp9/common/vp9_reconinter.h @@ -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], diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index f9d566456..e34818c59 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -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 diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 38445ba65..128df35b2 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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); + */ } } } diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index c56208bb6..7b3077933 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -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; } diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index f5a462790..990101dec 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -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; diff --git a/vp9/encoder/vp9_global_motion.c b/vp9/encoder/vp9_global_motion.c index 40567314d..0096e66e1 100644 --- a/vp9/encoder/vp9_global_motion.c +++ b/vp9/encoder/vp9_global_motion.c @@ -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, diff --git a/vp9/encoder/vp9_global_motion.h b/vp9/encoder/vp9_global_motion.h index ba51b0a7f..ccb72e514 100644 --- a/vp9/encoder/vp9_global_motion.h +++ b/vp9/encoder/vp9_global_motion.h @@ -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, diff --git a/vp9/encoder/vp9_motionmodel.c b/vp9/encoder/vp9_motion_field.c similarity index 100% rename from vp9/encoder/vp9_motionmodel.c rename to vp9/encoder/vp9_motion_field.c diff --git a/vp9/encoder/vp9_motionmodel.h b/vp9/encoder/vp9_motion_field.h similarity index 89% rename from vp9/encoder/vp9_motionmodel.h rename to vp9/encoder/vp9_motion_field.h index abf2a08ca..d1dd17401 100644 --- a/vp9/encoder/vp9_motionmodel.h +++ b/vp9/encoder/vp9_motion_field.h @@ -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_ diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index e225bd9a6..8d0b522bb 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -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; diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 800e32c41..e7c8138e3 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -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; diff --git a/vp9/encoder/vp9_ransac.c b/vp9/encoder/vp9_ransac.c index 8e3643763..7c04c8fbc 100644 --- a/vp9/encoder/vp9_ransac.c +++ b/vp9/encoder/vp9_ransac.c @@ -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=0;i--) { + for (i = n - 1; i >= 0; i--) { if (i < n - 1) { if (g) { - for (j=l;j=0; i--) { - l=i+1; - g=w[i]; - for (j=l;j= 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=0;k--) { - for (its=0;its=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 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 #include +#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 diff --git a/vp9/encoder/vp9_rd.c b/vp9/encoder/vp9_rd.c index 11b5ec801..6591e2b0e 100644 --- a/vp9/encoder/vp9_rd.c +++ b/vp9/encoder/vp9_rd.c @@ -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); } diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 3e1b9dbe6..6d5b4a570 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -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 && diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk index e6bb1d8df..7d9523e70 100644 --- a/vp9/vp9_common.mk +++ b/vp9/vp9_common.mk @@ -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 diff --git a/vp9/vp9cx.mk b/vp9/vp9cx.mk index 100e83045..c3b6e15f3 100644 --- a/vp9/vp9cx.mk +++ b/vp9/vp9cx.mk @@ -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 -- 2.40.0