1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <limits.h> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <math.h> 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h> 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_config.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_mem/vpx_mem.h" 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_common.h" 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_onyx_int.h" 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_mcomp.h" 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan// #define NEW_DIAMOND_SEARCH 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan 26233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE const uint8_t *get_buf_from_mv(const struct buf_2d *buf, 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *mv) { 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &buf->buf[mv->row * buf->stride + mv->col]; 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan 31233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_set_mv_search_range(MACROBLOCK *x, const MV *mv) { 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan int col_min = (mv->col >> 3) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0); 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan int row_min = (mv->row >> 3) - MAX_FULL_PEL_VAL + (mv->row & 7 ? 1 : 0); 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan int col_max = (mv->col >> 3) + MAX_FULL_PEL_VAL; 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan int row_max = (mv->row >> 3) + MAX_FULL_PEL_VAL; 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan col_min = MAX(col_min, (MV_LOW >> 3) + 1); 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan row_min = MAX(row_min, (MV_LOW >> 3) + 1); 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan col_max = MIN(col_max, (MV_UPP >> 3) - 1); 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan row_max = MIN(row_max, (MV_UPP >> 3) - 1); 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Get intersection of UMV window and valid MV window to reduce # of checks 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan // in diamond search. 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->mv_col_min < col_min) 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_col_min = col_min; 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->mv_col_max > col_max) 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_col_max = col_max; 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->mv_row_min < row_min) 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_row_min = row_min; 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->mv_row_max > row_max) 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_row_max = row_max; 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan 54233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_init_search_range(VP9_COMP *cpi, int size) { 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sr = 0; 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Minimum search size no matter what the passed in value. 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan size = MAX(16, size); 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan while ((size << sr) < MAX_FULL_PEL_VAL) 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan sr++; 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan sr += cpi->sf.reduce_first_step_size; 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan sr = MIN(sr, (cpi->sf.max_step_search_steps - 2)); 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan return sr; 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan 68233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int mv_cost(const MV *mv, 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *joint_cost, int *comp_cost[2]) { 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan return joint_cost[vp9_get_mv_joint(mv)] + 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan comp_cost[0][mv->row] + comp_cost[1][mv->col]; 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan 74233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_mv_bit_cost(const MV *mv, const MV *ref, 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjcost, int *mvcost[2], int weight) { 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV diff = { mv->row - ref->row, 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan mv->col - ref->col }; 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * weight, 7); 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan 81233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int mv_err_cost(const MV *mv, const MV *ref, 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjcost, int *mvcost[2], 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan int error_per_bit) { 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mvcost) { 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV diff = { mv->row - ref->row, 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan mv->col - ref->col }; 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan error_per_bit, 13); 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan 93233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int mvsad_err_cost(const MV *mv, const MV *ref, 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost, int *mvsadcost[2], 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan int error_per_bit) { 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mvsadcost) { 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV diff = { mv->row - ref->row, 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan mv->col - ref->col }; 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjsadcost, mvsadcost) * 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan error_per_bit, 8); 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan 105233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_init_dsmotion_compensation(MACROBLOCK *x, int stride) { 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan int len, ss_count = 1; 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->ss[0].mv.col = x->ss[0].mv.row = 0; 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->ss[0].offset = 0; 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (len = MAX_FIRST_STEP; len > 0; len /= 2) { 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Generate offsets for 4 search sites per step. 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV ss_mvs[] = {{-len, 0}, {len, 0}, {0, -len}, {0, len}}; 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; ++i) { 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan search_site *const ss = &x->ss[ss_count++]; 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan ss->mv = ss_mvs[i]; 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan ss->offset = ss->mv.row * stride + ss->mv.col; 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->ss_count = ss_count; 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->searches_per_step = 4; 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan 126233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_init3smotion_compensation(MACROBLOCK *x, int stride) { 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan int len, ss_count = 1; 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->ss[0].mv.col = x->ss[0].mv.row = 0; 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->ss[0].offset = 0; 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (len = MAX_FIRST_STEP; len > 0; len /= 2) { 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Generate offsets for 8 search sites per step. 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV ss_mvs[8] = { 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-len, 0 }, {len, 0 }, { 0, -len}, {0, len}, 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-len, -len}, {-len, len}, {len, -len}, {len, len} 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 8; ++i) { 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan search_site *const ss = &x->ss[ss_count++]; 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan ss->mv = ss_mvs[i]; 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan ss->offset = ss->mv.row * stride + ss->mv.col; 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->ss_count = ss_count; 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->searches_per_step = 8; 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan * To avoid the penalty for crossing cache-line read, preload the reference 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan * area in a small buffer, which is aligned to make sure there won't be crossing 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan * cache-line read while reading from this buffer. This reduced the cpu 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan * cycles spent on reading ref data in sub-pixel filter functions. 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan * TODO: Currently, since sub-pixel search range here is -3 ~ 3, copy 22 rows x 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan * could reduce the area. 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* estimated cost of a motion vector (r,c) */ 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MVC(r, c) \ 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mvcost ? \ 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((mvjcost[((r) != rr) * 2 + ((c) != rc)] + \ 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \ 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan error_per_bit + 4096) >> 13 : 0) 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan// convert motion vector component to offset for svf calc 169233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int sp(int x) { 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan return (x & 7) << 1; 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan 173233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c, 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan int offset) { 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &buf[(r >> 3) * stride + (c >> 3) - offset]; 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* returns subpixel variance error function */ 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DIST(r, c) \ 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan vfp->svf(pre(y, y_stride, r, c, offset), y_stride, sp(c), sp(r), z, \ 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan src_stride, &sse) 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* checks if (r, c) has better score than previous best */ 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define CHECK_BETTER(v, r, c) \ 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \ 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan thismse = (DIST(r, c)); \ 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((v = MVC(r, c) + thismse) < besterr) { \ 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan besterr = v; \ 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan br = r; \ 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc = c; \ 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan *distortion = thismse; \ 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan *sse1 = sse; \ 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan } \ 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { \ 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan v = INT_MAX; \ 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 197233d2500723e5594f3e7c70896ffeeef32b9c950ywan 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define FIRST_LEVEL_CHECKS \ 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan { \ 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int left, right, up, down, diag; \ 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(left, tr, tc - hstep); \ 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(right, tr, tc + hstep); \ 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(up, tr - hstep, tc); \ 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(down, tr + hstep, tc); \ 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan whichdir = (left < right ? 0 : 1) + \ 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan (up < down ? 0 : 2); \ 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (whichdir) { \ 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 0: \ 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(diag, tr - hstep, tc - hstep); \ 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 1: \ 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(diag, tr - hstep, tc + hstep); \ 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 2: \ 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(diag, tr + hstep, tc - hstep); \ 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 3: \ 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(diag, tr + hstep, tc + hstep); \ 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan } \ 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define SECOND_LEVEL_CHECKS \ 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan { \ 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan int kr, kc; \ 226233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int second; \ 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (tr != br && tc != bc) { \ 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan kr = br - tr; \ 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan kc = bc - tc; \ 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + kr, tc + 2 * kc); \ 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + 2 * kr, tc + kc); \ 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (tr == br && tc != bc) { \ 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan kc = bc - tc; \ 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + hstep, tc + 2 * kc); \ 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr - hstep, tc + 2 * kc); \ 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (whichdir) { \ 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 0: \ 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 1: \ 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + hstep, tc + kc); \ 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 2: \ 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 3: \ 243233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr - hstep, tc + kc); \ 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan } \ 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (tr != br && tc == bc) { \ 247233d2500723e5594f3e7c70896ffeeef32b9c950ywan kr = br - tr; \ 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + 2 * kr, tc + hstep); \ 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + 2 * kr, tc - hstep); \ 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (whichdir) { \ 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 0: \ 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 2: \ 253233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + kr, tc + hstep); \ 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 255233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 1: \ 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan case 3: \ 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER(second, tr + kr, tc - hstep); \ 258233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; \ 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan } \ 260233d2500723e5594f3e7c70896ffeeef32b9c950ywan } \ 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 262233d2500723e5594f3e7c70896ffeeef32b9c950ywan 263233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_find_best_sub_pixel_tree(const MACROBLOCK *x, 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *bestmv, const MV *ref_mv, 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan int allow_hp, 266233d2500723e5594f3e7c70896ffeeef32b9c950ywan int error_per_bit, 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 268233d2500723e5594f3e7c70896ffeeef32b9c950ywan int forced_stop, 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan int iters_per_step, 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 271233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *distortion, 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int *sse1) { 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *z = x->plane[0].src.buf; 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int src_stride = x->plane[0].src.stride; 275233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *xd = &x->e_mbd; 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int besterr = INT_MAX; 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sse; 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int whichdir; 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan int thismse; 280233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int halfiters = iters_per_step; 281233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int quarteriters = iters_per_step; 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int eighthiters = iters_per_step; 283233d2500723e5594f3e7c70896ffeeef32b9c950ywan 284233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y_stride = xd->plane[0].pre[0].stride; 285233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int offset = bestmv->row * y_stride + bestmv->col; 286233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *y = xd->plane[0].pre[0].buf + offset; 287233d2500723e5594f3e7c70896ffeeef32b9c950ywan 288233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rr = ref_mv->row; 289233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rc = ref_mv->col; 290233d2500723e5594f3e7c70896ffeeef32b9c950ywan int br = bestmv->row * 8; 291233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bc = bestmv->col * 8; 292233d2500723e5594f3e7c70896ffeeef32b9c950ywan int hstep = 4; 293233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX); 294233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX); 295233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX); 296233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX); 297233d2500723e5594f3e7c70896ffeeef32b9c950ywan 298233d2500723e5594f3e7c70896ffeeef32b9c950ywan int tr = br; 299233d2500723e5594f3e7c70896ffeeef32b9c950ywan int tc = bc; 300233d2500723e5594f3e7c70896ffeeef32b9c950ywan 301233d2500723e5594f3e7c70896ffeeef32b9c950ywan // central mv 302233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->row *= 8; 303233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->col *= 8; 304233d2500723e5594f3e7c70896ffeeef32b9c950ywan 305233d2500723e5594f3e7c70896ffeeef32b9c950ywan // calculate central point error 306233d2500723e5594f3e7c70896ffeeef32b9c950ywan besterr = vfp->vf(y, y_stride, z, src_stride, sse1); 307233d2500723e5594f3e7c70896ffeeef32b9c950ywan *distortion = besterr; 308233d2500723e5594f3e7c70896ffeeef32b9c950ywan besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit); 309233d2500723e5594f3e7c70896ffeeef32b9c950ywan 310233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 1/2 pel 311233d2500723e5594f3e7c70896ffeeef32b9c950ywan FIRST_LEVEL_CHECKS; 312233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (halfiters > 1) { 313233d2500723e5594f3e7c70896ffeeef32b9c950ywan SECOND_LEVEL_CHECKS; 314233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 315233d2500723e5594f3e7c70896ffeeef32b9c950ywan tr = br; 316233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc = bc; 317233d2500723e5594f3e7c70896ffeeef32b9c950ywan 318233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only 319233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (forced_stop != 2) { 320233d2500723e5594f3e7c70896ffeeef32b9c950ywan hstep >>= 1; 321233d2500723e5594f3e7c70896ffeeef32b9c950ywan FIRST_LEVEL_CHECKS; 322233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (quarteriters > 1) { 323233d2500723e5594f3e7c70896ffeeef32b9c950ywan SECOND_LEVEL_CHECKS; 324233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 325233d2500723e5594f3e7c70896ffeeef32b9c950ywan tr = br; 326233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc = bc; 327233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 328233d2500723e5594f3e7c70896ffeeef32b9c950ywan 329233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) { 330233d2500723e5594f3e7c70896ffeeef32b9c950ywan hstep >>= 1; 331233d2500723e5594f3e7c70896ffeeef32b9c950ywan FIRST_LEVEL_CHECKS; 332233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (eighthiters > 1) { 333233d2500723e5594f3e7c70896ffeeef32b9c950ywan SECOND_LEVEL_CHECKS; 334233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 335233d2500723e5594f3e7c70896ffeeef32b9c950ywan tr = br; 336233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc = bc; 337233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 338233d2500723e5594f3e7c70896ffeeef32b9c950ywan // These lines insure static analysis doesn't warn that 339233d2500723e5594f3e7c70896ffeeef32b9c950ywan // tr and tc aren't used after the above point. 340233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) tr; 341233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) tc; 342233d2500723e5594f3e7c70896ffeeef32b9c950ywan 343233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->row = br; 344233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->col = bc; 345233d2500723e5594f3e7c70896ffeeef32b9c950ywan 346233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) || 347233d2500723e5594f3e7c70896ffeeef32b9c950ywan (abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3))) 348233d2500723e5594f3e7c70896ffeeef32b9c950ywan return INT_MAX; 349233d2500723e5594f3e7c70896ffeeef32b9c950ywan 350233d2500723e5594f3e7c70896ffeeef32b9c950ywan return besterr; 351233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 352233d2500723e5594f3e7c70896ffeeef32b9c950ywan 353233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef DIST 354233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* returns subpixel variance error function */ 355233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DIST(r, c) \ 356233d2500723e5594f3e7c70896ffeeef32b9c950ywan vfp->svaf(pre(y, y_stride, r, c, offset), y_stride, sp(c), sp(r), \ 357233d2500723e5594f3e7c70896ffeeef32b9c950ywan z, src_stride, &sse, second_pred) 358233d2500723e5594f3e7c70896ffeeef32b9c950ywan 359233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_find_best_sub_pixel_comp_tree(const MACROBLOCK *x, 360233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *bestmv, const MV *ref_mv, 361233d2500723e5594f3e7c70896ffeeef32b9c950ywan int allow_hp, 362233d2500723e5594f3e7c70896ffeeef32b9c950ywan int error_per_bit, 363233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 364233d2500723e5594f3e7c70896ffeeef32b9c950ywan int forced_stop, 365233d2500723e5594f3e7c70896ffeeef32b9c950ywan int iters_per_step, 366233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 367233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *distortion, 368233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int *sse1, 369233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *second_pred, 370233d2500723e5594f3e7c70896ffeeef32b9c950ywan int w, int h) { 371233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *z = x->plane[0].src.buf; 372233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int src_stride = x->plane[0].src.stride; 373233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *xd = &x->e_mbd; 374233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int besterr = INT_MAX; 375233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sse; 376233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int whichdir; 377233d2500723e5594f3e7c70896ffeeef32b9c950ywan int thismse; 378233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int halfiters = iters_per_step; 379233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int quarteriters = iters_per_step; 380233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int eighthiters = iters_per_step; 381233d2500723e5594f3e7c70896ffeeef32b9c950ywan 382233d2500723e5594f3e7c70896ffeeef32b9c950ywan DECLARE_ALIGNED_ARRAY(16, uint8_t, comp_pred, 64 * 64); 383233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y_stride = xd->plane[0].pre[0].stride; 384233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int offset = bestmv->row * y_stride + bestmv->col; 385233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *y = xd->plane[0].pre[0].buf + offset; 386233d2500723e5594f3e7c70896ffeeef32b9c950ywan 387233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rr = ref_mv->row; 388233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rc = ref_mv->col; 389233d2500723e5594f3e7c70896ffeeef32b9c950ywan int br = bestmv->row * 8; 390233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bc = bestmv->col * 8; 391233d2500723e5594f3e7c70896ffeeef32b9c950ywan int hstep = 4; 392233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX); 393233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX); 394233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX); 395233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX); 396233d2500723e5594f3e7c70896ffeeef32b9c950ywan 397233d2500723e5594f3e7c70896ffeeef32b9c950ywan int tr = br; 398233d2500723e5594f3e7c70896ffeeef32b9c950ywan int tc = bc; 399233d2500723e5594f3e7c70896ffeeef32b9c950ywan 400233d2500723e5594f3e7c70896ffeeef32b9c950ywan // central mv 401233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->row *= 8; 402233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->col *= 8; 403233d2500723e5594f3e7c70896ffeeef32b9c950ywan 404233d2500723e5594f3e7c70896ffeeef32b9c950ywan // calculate central point error 405233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(yunqingwang): central pointer error was already calculated in full- 406233d2500723e5594f3e7c70896ffeeef32b9c950ywan // pixel search, and can be passed in this function. 407233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_comp_avg_pred(comp_pred, second_pred, w, h, y, y_stride); 408233d2500723e5594f3e7c70896ffeeef32b9c950ywan besterr = vfp->vf(comp_pred, w, z, src_stride, sse1); 409233d2500723e5594f3e7c70896ffeeef32b9c950ywan *distortion = besterr; 410233d2500723e5594f3e7c70896ffeeef32b9c950ywan besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit); 411233d2500723e5594f3e7c70896ffeeef32b9c950ywan 412233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Each subsequent iteration checks at least one point in 413233d2500723e5594f3e7c70896ffeeef32b9c950ywan // common with the last iteration could be 2 ( if diag selected) 414233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 1/2 pel 415233d2500723e5594f3e7c70896ffeeef32b9c950ywan FIRST_LEVEL_CHECKS; 416233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (halfiters > 1) { 417233d2500723e5594f3e7c70896ffeeef32b9c950ywan SECOND_LEVEL_CHECKS; 418233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 419233d2500723e5594f3e7c70896ffeeef32b9c950ywan tr = br; 420233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc = bc; 421233d2500723e5594f3e7c70896ffeeef32b9c950ywan 422233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Each subsequent iteration checks at least one point in common with 423233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the last iteration could be 2 ( if diag selected) 1/4 pel 424233d2500723e5594f3e7c70896ffeeef32b9c950ywan 425233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only 426233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (forced_stop != 2) { 427233d2500723e5594f3e7c70896ffeeef32b9c950ywan hstep >>= 1; 428233d2500723e5594f3e7c70896ffeeef32b9c950ywan FIRST_LEVEL_CHECKS; 429233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (quarteriters > 1) { 430233d2500723e5594f3e7c70896ffeeef32b9c950ywan SECOND_LEVEL_CHECKS; 431233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 432233d2500723e5594f3e7c70896ffeeef32b9c950ywan tr = br; 433233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc = bc; 434233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 435233d2500723e5594f3e7c70896ffeeef32b9c950ywan 436233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) { 437233d2500723e5594f3e7c70896ffeeef32b9c950ywan hstep >>= 1; 438233d2500723e5594f3e7c70896ffeeef32b9c950ywan FIRST_LEVEL_CHECKS; 439233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (eighthiters > 1) { 440233d2500723e5594f3e7c70896ffeeef32b9c950ywan SECOND_LEVEL_CHECKS; 441233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 442233d2500723e5594f3e7c70896ffeeef32b9c950ywan tr = br; 443233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc = bc; 444233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 445233d2500723e5594f3e7c70896ffeeef32b9c950ywan // These lines insure static analysis doesn't warn that 446233d2500723e5594f3e7c70896ffeeef32b9c950ywan // tr and tc aren't used after the above point. 447233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) tr; 448233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) tc; 449233d2500723e5594f3e7c70896ffeeef32b9c950ywan 450233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->row = br; 451233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestmv->col = bc; 452233d2500723e5594f3e7c70896ffeeef32b9c950ywan 453233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) || 454233d2500723e5594f3e7c70896ffeeef32b9c950ywan (abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3))) 455233d2500723e5594f3e7c70896ffeeef32b9c950ywan return INT_MAX; 456233d2500723e5594f3e7c70896ffeeef32b9c950ywan 457233d2500723e5594f3e7c70896ffeeef32b9c950ywan return besterr; 458233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 459233d2500723e5594f3e7c70896ffeeef32b9c950ywan 460233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef MVC 461233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef PRE 462233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef DIST 463233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef CHECK_BETTER 464233d2500723e5594f3e7c70896ffeeef32b9c950ywan 465233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int check_bounds(const MACROBLOCK *x, int row, int col, 466233d2500723e5594f3e7c70896ffeeef32b9c950ywan int range) { 467233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ((row - range) >= x->mv_row_min) & 468233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((row + range) <= x->mv_row_max) & 469233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((col - range) >= x->mv_col_min) & 470233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((col + range) <= x->mv_col_max); 471233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 472233d2500723e5594f3e7c70896ffeeef32b9c950ywan 473233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int is_mv_in(const MACROBLOCK *x, const MV *mv) { 474233d2500723e5594f3e7c70896ffeeef32b9c950ywan return (mv->col >= x->mv_col_min) && (mv->col <= x->mv_col_max) && 475233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mv->row >= x->mv_row_min) && (mv->row <= x->mv_row_max); 476233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 477233d2500723e5594f3e7c70896ffeeef32b9c950ywan 478233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define CHECK_BETTER \ 479233d2500723e5594f3e7c70896ffeeef32b9c950ywan {\ 480233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) {\ 481233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (use_mvcost) \ 482233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, \ 483233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit);\ 484233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) {\ 485233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad;\ 486233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = i;\ 487233d2500723e5594f3e7c70896ffeeef32b9c950ywan }\ 488233d2500723e5594f3e7c70896ffeeef32b9c950ywan }\ 489233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 490233d2500723e5594f3e7c70896ffeeef32b9c950ywan 491233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MAX_PATTERN_SCALES 11 492233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MAX_PATTERN_CANDIDATES 8 // max number of canddiates per scale 493233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define PATTERN_CANDIDATES_REF 3 // number of refinement candidates 494233d2500723e5594f3e7c70896ffeeef32b9c950ywan 495233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Generic pattern search function that searches over multiple scales. 496233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Each scale can have a different number of candidates and shape of 497233d2500723e5594f3e7c70896ffeeef32b9c950ywan// candidates as indicated in the num_candidates and candidates arrays 498233d2500723e5594f3e7c70896ffeeef32b9c950ywan// passed into this function 499233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int vp9_pattern_search(const MACROBLOCK *x, 500233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, 501233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, 502233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, 503233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_init_search, int do_refine, 504233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 505233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost, 506233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, MV *best_mv, 507233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_candidates[MAX_PATTERN_SCALES], 508233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV candidates[MAX_PATTERN_SCALES] 509233d2500723e5594f3e7c70896ffeeef32b9c950ywan [MAX_PATTERN_CANDIDATES]) { 510233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 511233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const int search_param_to_steps[MAX_MVSEARCH_STEPS] = { 512233d2500723e5594f3e7c70896ffeeef32b9c950ywan 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 513233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 514233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j, s, t; 515233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const what = &x->plane[0].src; 516233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const in_what = &xd->plane[0].pre[0]; 517233d2500723e5594f3e7c70896ffeeef32b9c950ywan int br, bc; 518233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bestsad = INT_MAX; 519233d2500723e5594f3e7c70896ffeeef32b9c950ywan int thissad; 520233d2500723e5594f3e7c70896ffeeef32b9c950ywan int k = -1; 521233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 522233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_init_s = search_param_to_steps[search_param]; 523233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *const mvjsadcost = x->nmvjointsadcost; 524233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 525233d2500723e5594f3e7c70896ffeeef32b9c950ywan 526233d2500723e5594f3e7c70896ffeeef32b9c950ywan // adjust ref_mv to make sure it is within MV range 527233d2500723e5594f3e7c70896ffeeef32b9c950ywan clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max); 528233d2500723e5594f3e7c70896ffeeef32b9c950ywan br = ref_mv->row; 529233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc = ref_mv->col; 530233d2500723e5594f3e7c70896ffeeef32b9c950ywan 531233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Work out the start point for the search 532233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = vfp->sdf(what->buf, what->stride, 533233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, ref_mv), in_what->stride, 534233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0x7fffffff) + mvsad_err_cost(ref_mv, &fcenter_mv, 535233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 536233d2500723e5594f3e7c70896ffeeef32b9c950ywan 537233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Search all possible scales upto the search param around the center point 538233d2500723e5594f3e7c70896ffeeef32b9c950ywan // pick the scale of the point that is best as the starting scale of 539233d2500723e5594f3e7c70896ffeeef32b9c950ywan // further steps around it. 540233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_init_search) { 541233d2500723e5594f3e7c70896ffeeef32b9c950ywan s = best_init_s; 542233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_init_s = -1; 543233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (t = 0; t <= s; ++t) { 544233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = -1; 545233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (check_bounds(x, br, bc, 1 << t)) { 546233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < num_candidates[t]; i++) { 547233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + candidates[t][i].row, 548233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + candidates[t][i].col}; 549233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 550233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 551233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 552233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 553233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 554233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 555233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < num_candidates[t]; i++) { 556233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + candidates[t][i].row, 557233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + candidates[t][i].col}; 558233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!is_mv_in(x, &this_mv)) 559233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 560233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 561233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 562233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 563233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 564233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 565233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 566233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site == -1) { 567233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 568233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 569233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_init_s = t; 570233d2500723e5594f3e7c70896ffeeef32b9c950ywan k = best_site; 571233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 572233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 573233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_init_s != -1) { 574233d2500723e5594f3e7c70896ffeeef32b9c950ywan br += candidates[best_init_s][k].row; 575233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc += candidates[best_init_s][k].col; 576233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 577233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 578233d2500723e5594f3e7c70896ffeeef32b9c950ywan 579233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If the center point is still the best, just skip this and move to 580233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the refinement step. 581233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_init_s != -1) { 582233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = -1; 583233d2500723e5594f3e7c70896ffeeef32b9c950ywan s = best_init_s; 584233d2500723e5594f3e7c70896ffeeef32b9c950ywan 585233d2500723e5594f3e7c70896ffeeef32b9c950ywan do { 586233d2500723e5594f3e7c70896ffeeef32b9c950ywan // No need to search all 6 points the 1st time if initial search was used 587233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!do_init_search || s != best_init_s) { 588233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (check_bounds(x, br, bc, 1 << s)) { 589233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < num_candidates[s]; i++) { 590233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + candidates[s][i].row, 591233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + candidates[s][i].col}; 592233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 593233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 594233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 595233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 596233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 597233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 598233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < num_candidates[s]; i++) { 599233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + candidates[s][i].row, 600233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + candidates[s][i].col}; 601233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!is_mv_in(x, &this_mv)) 602233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 603233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 604233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 605233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 606233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 607233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 608233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 609233d2500723e5594f3e7c70896ffeeef32b9c950ywan 610233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site == -1) { 611233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 612233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 613233d2500723e5594f3e7c70896ffeeef32b9c950ywan br += candidates[s][best_site].row; 614233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc += candidates[s][best_site].col; 615233d2500723e5594f3e7c70896ffeeef32b9c950ywan k = best_site; 616233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 617233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 618233d2500723e5594f3e7c70896ffeeef32b9c950ywan 619233d2500723e5594f3e7c70896ffeeef32b9c950ywan do { 620233d2500723e5594f3e7c70896ffeeef32b9c950ywan int next_chkpts_indices[PATTERN_CANDIDATES_REF]; 621233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = -1; 622233d2500723e5594f3e7c70896ffeeef32b9c950ywan next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1; 623233d2500723e5594f3e7c70896ffeeef32b9c950ywan next_chkpts_indices[1] = k; 624233d2500723e5594f3e7c70896ffeeef32b9c950ywan next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1; 625233d2500723e5594f3e7c70896ffeeef32b9c950ywan 626233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (check_bounds(x, br, bc, 1 << s)) { 627233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { 628233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row, 629233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + candidates[s][next_chkpts_indices[i]].col}; 630233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 631233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 632233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 633233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 634233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 635233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 636233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { 637233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row, 638233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + candidates[s][next_chkpts_indices[i]].col}; 639233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!is_mv_in(x, &this_mv)) 640233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 641233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 642233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 643233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 644233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 645233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 646233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 647233d2500723e5594f3e7c70896ffeeef32b9c950ywan 648233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site != -1) { 649233d2500723e5594f3e7c70896ffeeef32b9c950ywan k = next_chkpts_indices[best_site]; 650233d2500723e5594f3e7c70896ffeeef32b9c950ywan br += candidates[s][k].row; 651233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc += candidates[s][k].col; 652233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 653233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (best_site != -1); 654233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (s--); 655233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 656233d2500723e5594f3e7c70896ffeeef32b9c950ywan 657233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check 4 1-away neighbors if do_refine is true. 658233d2500723e5594f3e7c70896ffeeef32b9c950ywan // For most well-designed schemes do_refine will not be necessary. 659233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_refine) { 660233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const MV neighbors[4] = {{0, -1}, { -1, 0}, {1, 0}, {0, 1}}; 661233d2500723e5594f3e7c70896ffeeef32b9c950ywan 662233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 16; j++) { 663233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = -1; 664233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (check_bounds(x, br, bc, 1)) { 665233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 666233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + neighbors[i].row, 667233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + neighbors[i].col}; 668233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 669233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 670233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 671233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 672233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 673233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 674233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 675233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {br + neighbors[i].row, 676233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc + neighbors[i].col}; 677233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!is_mv_in(x, &this_mv)) 678233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 679233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = vfp->sdf(what->buf, what->stride, 680233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &this_mv), 681233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, bestsad); 682233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_BETTER 683233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 684233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 685233d2500723e5594f3e7c70896ffeeef32b9c950ywan 686233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site == -1) { 687233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 688233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 689233d2500723e5594f3e7c70896ffeeef32b9c950ywan br += neighbors[best_site].row; 690233d2500723e5594f3e7c70896ffeeef32b9c950ywan bc += neighbors[best_site].col; 691233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 692233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 693233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 694233d2500723e5594f3e7c70896ffeeef32b9c950ywan 695233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = br; 696233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = bc; 697233d2500723e5594f3e7c70896ffeeef32b9c950ywan 698233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 699233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 700233d2500723e5594f3e7c70896ffeeef32b9c950ywan 701233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_get_mvpred_var(const MACROBLOCK *x, 702233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *best_mv, const MV *center_mv, 703233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 704233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost) { 705233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 706233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const what = &x->plane[0].src; 707233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const in_what = &xd->plane[0].pre[0]; 708233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV mv = {best_mv->row * 8, best_mv->col * 8}; 709233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int unused; 710233d2500723e5594f3e7c70896ffeeef32b9c950ywan 711233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vfp->vf(what->buf, what->stride, 712233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, best_mv), in_what->stride, &unused) + 713233d2500723e5594f3e7c70896ffeeef32b9c950ywan (use_mvcost ? mv_err_cost(&mv, center_mv, x->nmvjointcost, 714233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mvcost, x->errorperbit) : 0); 715233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 716233d2500723e5594f3e7c70896ffeeef32b9c950ywan 717233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_get_mvpred_av_var(const MACROBLOCK *x, 718233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *best_mv, const MV *center_mv, 719233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *second_pred, 720233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 721233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost) { 722233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 723233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const what = &x->plane[0].src; 724233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const in_what = &xd->plane[0].pre[0]; 725233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV mv = {best_mv->row * 8, best_mv->col * 8}; 726233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int unused; 727233d2500723e5594f3e7c70896ffeeef32b9c950ywan 728233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vfp->svaf(get_buf_from_mv(in_what, best_mv), in_what->stride, 0, 0, 729233d2500723e5594f3e7c70896ffeeef32b9c950ywan what->buf, what->stride, &unused, second_pred) + 730233d2500723e5594f3e7c70896ffeeef32b9c950ywan (use_mvcost ? mv_err_cost(&mv, center_mv, x->nmvjointcost, 731233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mvcost, x->errorperbit) : 0); 732233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 733233d2500723e5594f3e7c70896ffeeef32b9c950ywan 734233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_hex_search(const MACROBLOCK *x, 735233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, 736233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, 737233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, 738233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_init_search, 739233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 740233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost, 741233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, MV *best_mv) { 742233d2500723e5594f3e7c70896ffeeef32b9c950ywan // First scale has 8-closest points, the rest have 6 points in hex shape 743233d2500723e5594f3e7c70896ffeeef32b9c950ywan // at increasing scales 744233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const int hex_num_candidates[MAX_PATTERN_SCALES] = { 745233d2500723e5594f3e7c70896ffeeef32b9c950ywan 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 746233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 747233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note that the largest candidate step at each scale is 2^scale 748233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const MV hex_candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES] = { 749233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, { 0, 1}, { -1, 1}, {-1, 0}}, 750233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0}}, 751233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-2, -4}, {2, -4}, {4, 0}, {2, 4}, { -2, 4}, { -4, 0}}, 752233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-4, -8}, {4, -8}, {8, 0}, {4, 8}, { -4, 8}, { -8, 0}}, 753233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-8, -16}, {8, -16}, {16, 0}, {8, 16}, { -8, 16}, { -16, 0}}, 754233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-16, -32}, {16, -32}, {32, 0}, {16, 32}, { -16, 32}, { -32, 0}}, 755233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-32, -64}, {32, -64}, {64, 0}, {32, 64}, { -32, 64}, { -64, 0}}, 756233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-64, -128}, {64, -128}, {128, 0}, {64, 128}, { -64, 128}, { -128, 0}}, 757233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-128, -256}, {128, -256}, {256, 0}, {128, 256}, { -128, 256}, { -256, 0}}, 758233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-256, -512}, {256, -512}, {512, 0}, {256, 512}, { -256, 512}, { -512, 0}}, 759233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-512, -1024}, {512, -1024}, {1024, 0}, {512, 1024}, { -512, 1024}, 760233d2500723e5594f3e7c70896ffeeef32b9c950ywan { -1024, 0}}, 761233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 762233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9_pattern_search(x, ref_mv, search_param, sad_per_bit, 763233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_init_search, 0, vfp, use_mvcost, 764233d2500723e5594f3e7c70896ffeeef32b9c950ywan center_mv, best_mv, 765233d2500723e5594f3e7c70896ffeeef32b9c950ywan hex_num_candidates, hex_candidates); 766233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 767233d2500723e5594f3e7c70896ffeeef32b9c950ywan 768233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_bigdia_search(const MACROBLOCK *x, 769233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, 770233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, 771233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, 772233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_init_search, 773233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 774233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost, 775233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, 776233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *best_mv) { 777233d2500723e5594f3e7c70896ffeeef32b9c950ywan // First scale has 4-closest points, the rest have 8 points in diamond 778233d2500723e5594f3e7c70896ffeeef32b9c950ywan // shape at increasing scales 779233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const int bigdia_num_candidates[MAX_PATTERN_SCALES] = { 780233d2500723e5594f3e7c70896ffeeef32b9c950ywan 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 781233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 782233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note that the largest candidate step at each scale is 2^scale 783233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const MV bigdia_candidates[MAX_PATTERN_SCALES] 784233d2500723e5594f3e7c70896ffeeef32b9c950ywan [MAX_PATTERN_CANDIDATES] = { 785233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{0, -1}, {1, 0}, { 0, 1}, {-1, 0}}, 786233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-1, -1}, {0, -2}, {1, -1}, {2, 0}, {1, 1}, {0, 2}, {-1, 1}, {-2, 0}}, 787233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-2, -2}, {0, -4}, {2, -2}, {4, 0}, {2, 2}, {0, 4}, {-2, 2}, {-4, 0}}, 788233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-4, -4}, {0, -8}, {4, -4}, {8, 0}, {4, 4}, {0, 8}, {-4, 4}, {-8, 0}}, 789233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-8, -8}, {0, -16}, {8, -8}, {16, 0}, {8, 8}, {0, 16}, {-8, 8}, {-16, 0}}, 790233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-16, -16}, {0, -32}, {16, -16}, {32, 0}, {16, 16}, {0, 32}, 791233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-16, 16}, {-32, 0}}, 792233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-32, -32}, {0, -64}, {32, -32}, {64, 0}, {32, 32}, {0, 64}, 793233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-32, 32}, {-64, 0}}, 794233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-64, -64}, {0, -128}, {64, -64}, {128, 0}, {64, 64}, {0, 128}, 795233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-64, 64}, {-128, 0}}, 796233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-128, -128}, {0, -256}, {128, -128}, {256, 0}, {128, 128}, {0, 256}, 797233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-128, 128}, {-256, 0}}, 798233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-256, -256}, {0, -512}, {256, -256}, {512, 0}, {256, 256}, {0, 512}, 799233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-256, 256}, {-512, 0}}, 800233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-512, -512}, {0, -1024}, {512, -512}, {1024, 0}, {512, 512}, {0, 1024}, 801233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-512, 512}, {-1024, 0}}, 802233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 803233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9_pattern_search(x, ref_mv, search_param, sad_per_bit, 804233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_init_search, 0, vfp, use_mvcost, 805233d2500723e5594f3e7c70896ffeeef32b9c950ywan center_mv, best_mv, 806233d2500723e5594f3e7c70896ffeeef32b9c950ywan bigdia_num_candidates, bigdia_candidates); 807233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 808233d2500723e5594f3e7c70896ffeeef32b9c950ywan 809233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_square_search(const MACROBLOCK *x, 810233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, 811233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, 812233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, 813233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_init_search, 814233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 815233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost, 816233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, 817233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *best_mv) { 818233d2500723e5594f3e7c70896ffeeef32b9c950ywan // All scales have 8 closest points in square shape 819233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const int square_num_candidates[MAX_PATTERN_SCALES] = { 820233d2500723e5594f3e7c70896ffeeef32b9c950ywan 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 821233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 822233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note that the largest candidate step at each scale is 2^scale 823233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const MV square_candidates[MAX_PATTERN_SCALES] 824233d2500723e5594f3e7c70896ffeeef32b9c950ywan [MAX_PATTERN_CANDIDATES] = { 825233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}}, 826233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-2, -2}, {0, -2}, {2, -2}, {2, 0}, {2, 2}, {0, 2}, {-2, 2}, {-2, 0}}, 827233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-4, -4}, {0, -4}, {4, -4}, {4, 0}, {4, 4}, {0, 4}, {-4, 4}, {-4, 0}}, 828233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-8, -8}, {0, -8}, {8, -8}, {8, 0}, {8, 8}, {0, 8}, {-8, 8}, {-8, 0}}, 829233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-16, -16}, {0, -16}, {16, -16}, {16, 0}, {16, 16}, {0, 16}, 830233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-16, 16}, {-16, 0}}, 831233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-32, -32}, {0, -32}, {32, -32}, {32, 0}, {32, 32}, {0, 32}, 832233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-32, 32}, {-32, 0}}, 833233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-64, -64}, {0, -64}, {64, -64}, {64, 0}, {64, 64}, {0, 64}, 834233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-64, 64}, {-64, 0}}, 835233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-128, -128}, {0, -128}, {128, -128}, {128, 0}, {128, 128}, {0, 128}, 836233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-128, 128}, {-128, 0}}, 837233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-256, -256}, {0, -256}, {256, -256}, {256, 0}, {256, 256}, {0, 256}, 838233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-256, 256}, {-256, 0}}, 839233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-512, -512}, {0, -512}, {512, -512}, {512, 0}, {512, 512}, {0, 512}, 840233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-512, 512}, {-512, 0}}, 841233d2500723e5594f3e7c70896ffeeef32b9c950ywan {{-1024, -1024}, {0, -1024}, {1024, -1024}, {1024, 0}, {1024, 1024}, 842233d2500723e5594f3e7c70896ffeeef32b9c950ywan {0, 1024}, {-1024, 1024}, {-1024, 0}}, 843233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 844233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9_pattern_search(x, ref_mv, search_param, sad_per_bit, 845233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_init_search, 0, vfp, use_mvcost, 846233d2500723e5594f3e7c70896ffeeef32b9c950ywan center_mv, best_mv, 847233d2500723e5594f3e7c70896ffeeef32b9c950ywan square_num_candidates, square_candidates); 848233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 849233d2500723e5594f3e7c70896ffeeef32b9c950ywan 850233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_fast_hex_search(const MACROBLOCK *x, 851233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, 852233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, 853233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, 854233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_init_search, // must be zero for fast_hex 855233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 856233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost, 857233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, 858233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *best_mv) { 859233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9_hex_search(x, ref_mv, MAX(MAX_MVSEARCH_STEPS - 2, search_param), 860233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_per_bit, do_init_search, vfp, use_mvcost, 861233d2500723e5594f3e7c70896ffeeef32b9c950ywan center_mv, best_mv); 862233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 863233d2500723e5594f3e7c70896ffeeef32b9c950ywan 864233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_fast_dia_search(const MACROBLOCK *x, 865233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, 866233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, 867233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, 868233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_init_search, 869233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *vfp, 870233d2500723e5594f3e7c70896ffeeef32b9c950ywan int use_mvcost, 871233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, 872233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *best_mv) { 873233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9_bigdia_search(x, ref_mv, MAX(MAX_MVSEARCH_STEPS - 2, search_param), 874233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_per_bit, do_init_search, vfp, use_mvcost, 875233d2500723e5594f3e7c70896ffeeef32b9c950ywan center_mv, best_mv); 876233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 877233d2500723e5594f3e7c70896ffeeef32b9c950ywan 878233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef CHECK_BETTER 879233d2500723e5594f3e7c70896ffeeef32b9c950ywan 880233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_full_range_search_c(const MACROBLOCK *x, MV *ref_mv, MV *best_mv, 881233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, int sad_per_bit, int *num00, 882233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 883233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 884233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv) { 885233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 886233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *what = x->plane[0].src.buf; 887233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int what_stride = x->plane[0].src.stride; 888233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *in_what; 889233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int in_what_stride = xd->plane[0].pre[0].stride; 890233d2500723e5594f3e7c70896ffeeef32b9c950ywan 891233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int bestsad = INT_MAX; 892233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_row, ref_col; 893233d2500723e5594f3e7c70896ffeeef32b9c950ywan 894233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad; 895233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 896233d2500723e5594f3e7c70896ffeeef32b9c950ywan 897233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 898233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 899233d2500723e5594f3e7c70896ffeeef32b9c950ywan 900233d2500723e5594f3e7c70896ffeeef32b9c950ywan int tr, tc; 901233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_tr = 0; 902233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_tc = 0; 903233d2500723e5594f3e7c70896ffeeef32b9c950ywan int range = 64; 904233d2500723e5594f3e7c70896ffeeef32b9c950ywan 905233d2500723e5594f3e7c70896ffeeef32b9c950ywan int start_col, end_col; 906233d2500723e5594f3e7c70896ffeeef32b9c950ywan int start_row, end_row; 907233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 908233d2500723e5594f3e7c70896ffeeef32b9c950ywan 909233d2500723e5594f3e7c70896ffeeef32b9c950ywan clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max); 910233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_row = ref_mv->row; 911233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_col = ref_mv->col; 912233d2500723e5594f3e7c70896ffeeef32b9c950ywan *num00 = 11; 913233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = ref_row; 914233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = ref_col; 915233d2500723e5594f3e7c70896ffeeef32b9c950ywan 916233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Work out the start point for the search 917233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what = xd->plane[0].pre[0].buf + ref_row * in_what_stride + ref_col; 918233d2500723e5594f3e7c70896ffeeef32b9c950ywan 919233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the starting position 920233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) 921233d2500723e5594f3e7c70896ffeeef32b9c950ywan + mvsad_err_cost(best_mv, &fcenter_mv, 922233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 923233d2500723e5594f3e7c70896ffeeef32b9c950ywan 924233d2500723e5594f3e7c70896ffeeef32b9c950ywan start_row = MAX(-range, x->mv_row_min - ref_row); 925233d2500723e5594f3e7c70896ffeeef32b9c950ywan start_col = MAX(-range, x->mv_col_min - ref_col); 926233d2500723e5594f3e7c70896ffeeef32b9c950ywan end_row = MIN(range, x->mv_row_max - ref_row); 927233d2500723e5594f3e7c70896ffeeef32b9c950ywan end_col = MIN(range, x->mv_col_max - ref_col); 928233d2500723e5594f3e7c70896ffeeef32b9c950ywan 929233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (tr = start_row; tr <= end_row; ++tr) { 930233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (tc = start_col; tc <= end_col; tc += 4) { 931233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((tc + 3) <= end_col) { 932233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad_array[4]; 933233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char const *addr_ref[4]; 934233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; ++i) 935233d2500723e5594f3e7c70896ffeeef32b9c950ywan addr_ref[i] = in_what + tr * in_what_stride + tc + i; 936233d2500723e5594f3e7c70896ffeeef32b9c950ywan 937233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr->sdx4df(what, what_stride, addr_ref, in_what_stride, sad_array); 938233d2500723e5594f3e7c70896ffeeef32b9c950ywan 939233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; ++i) { 940233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad_array[i] < bestsad) { 941233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {ref_row + tr, ref_col + tc + i}; 942233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = sad_array[i] + 943233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvsad_err_cost(&this_mv, &fcenter_mv, 944233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 945233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 946233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 947233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_tr = tr; 948233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_tc = tc + i; 949233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 950233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 951233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 952233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 953233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < end_col - tc; ++i) { 954233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *check_here = in_what + tr * in_what_stride + tc + i; 955233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride, 956233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad); 957233d2500723e5594f3e7c70896ffeeef32b9c950ywan 958233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 959233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {ref_row + tr, ref_col + tc + i}; 960233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 961233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 962233d2500723e5594f3e7c70896ffeeef32b9c950ywan 963233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 964233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 965233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_tr = tr; 966233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_tc = tc + i; 967233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 968233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 969233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 970233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 971233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 972233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 973233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row += best_tr; 974233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col += best_tc; 975233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 976233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 977233d2500723e5594f3e7c70896ffeeef32b9c950ywan 978233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_diamond_search_sad_c(const MACROBLOCK *x, 979233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, MV *best_mv, 980233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_param, int sad_per_bit, int *num00, 981233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 982233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 983233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv) { 984233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j, step; 985233d2500723e5594f3e7c70896ffeeef32b9c950ywan 986233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 987233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *what = x->plane[0].src.buf; 988233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int what_stride = x->plane[0].src.stride; 989233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *in_what; 990233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int in_what_stride = xd->plane[0].pre[0].stride; 991233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *best_address; 992233d2500723e5594f3e7c70896ffeeef32b9c950ywan 993233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bestsad = INT_MAX; 994233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = 0; 995233d2500723e5594f3e7c70896ffeeef32b9c950ywan int last_site = 0; 996233d2500723e5594f3e7c70896ffeeef32b9c950ywan 997233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_row, ref_col; 998233d2500723e5594f3e7c70896ffeeef32b9c950ywan 999233d2500723e5594f3e7c70896ffeeef32b9c950ywan // search_param determines the length of the initial step and hence the number 1000233d2500723e5594f3e7c70896ffeeef32b9c950ywan // of iterations 1001233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = 1002233d2500723e5594f3e7c70896ffeeef32b9c950ywan // (MAX_FIRST_STEP/4) pel... etc. 1003233d2500723e5594f3e7c70896ffeeef32b9c950ywan const search_site *const ss = &x->ss[search_param * x->searches_per_step]; 1004233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int tot_steps = (x->ss_count / x->searches_per_step) - search_param; 1005233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1006233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1007233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1008233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1009233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1010233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1011233d2500723e5594f3e7c70896ffeeef32b9c950ywan clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max); 1012233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_row = ref_mv->row; 1013233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_col = ref_mv->col; 1014233d2500723e5594f3e7c70896ffeeef32b9c950ywan *num00 = 0; 1015233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = ref_row; 1016233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = ref_col; 1017233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1018233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Work out the start point for the search 1019233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what = xd->plane[0].pre[0].buf + ref_row * in_what_stride + ref_col; 1020233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address = in_what; 1021233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1022233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the starting position 1023233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) 1024233d2500723e5594f3e7c70896ffeeef32b9c950ywan + mvsad_err_cost(best_mv, &fcenter_mv, 1025233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1026233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1027233d2500723e5594f3e7c70896ffeeef32b9c950ywan i = 1; 1028233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1029233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (step = 0; step < tot_steps; step++) { 1030233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < x->searches_per_step; j++) { 1031233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {best_mv->row + ss[i].mv.row, 1032233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col + ss[i].mv.col}; 1033233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &this_mv)) { 1034233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const check_here = ss[i].offset + best_address; 1035233d2500723e5594f3e7c70896ffeeef32b9c950ywan int thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride, 1036233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad); 1037233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1038233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1039233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1040233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1041233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1042233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1043233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1044233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = i; 1045233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1046233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1047233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1048233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1049233d2500723e5594f3e7c70896ffeeef32b9c950ywan i++; 1050233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1051233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1052233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site != last_site) { 1053233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row += ss[best_site].mv.row; 1054233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col += ss[best_site].mv.col; 1055233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address += ss[best_site].offset; 1056233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_site = best_site; 1057233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if defined(NEW_DIAMOND_SEARCH) 1058233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (1) { 1059233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {best_mv->row + ss[best_site].mv.row, 1060233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col + ss[best_site].mv.col}; 1061233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &this_mv)) { 1062233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const check_here = ss[best_site].offset + best_address; 1063233d2500723e5594f3e7c70896ffeeef32b9c950ywan int thissad = fn_ptr->sdf(what, what_stride, check_here, 1064233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what_stride, bestsad); 1065233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1066233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1067233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1068233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1069233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1070233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row += ss[best_site].mv.row; 1071233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col += ss[best_site].mv.col; 1072233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address += ss[best_site].offset; 1073233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 1074233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1075233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1076233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1077233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1078233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 1079233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 1080233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (best_address == in_what) { 1081233d2500723e5594f3e7c70896ffeeef32b9c950ywan (*num00)++; 1082233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1083233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1084233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 1085233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1086233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1087233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_diamond_search_sadx4(const MACROBLOCK *x, 1088233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, MV *best_mv, int search_param, 1089233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, int *num00, 1090233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1091233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1092233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv) { 1093233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j, step; 1094233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1095233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1096233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t *what = x->plane[0].src.buf; 1097233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int what_stride = x->plane[0].src.stride; 1098233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *in_what; 1099233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int in_what_stride = xd->plane[0].pre[0].stride; 1100233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *best_address; 1101233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1102233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int bestsad = INT_MAX; 1103233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = 0; 1104233d2500723e5594f3e7c70896ffeeef32b9c950ywan int last_site = 0; 1105233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1106233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_row; 1107233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_col; 1108233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1109233d2500723e5594f3e7c70896ffeeef32b9c950ywan // search_param determines the length of the initial step and hence the number 1110233d2500723e5594f3e7c70896ffeeef32b9c950ywan // of iterations. 1111233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 0 = initial step (MAX_FIRST_STEP) pel 1112233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 1 = (MAX_FIRST_STEP/2) pel, 1113233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 2 = (MAX_FIRST_STEP/4) pel... 1114233d2500723e5594f3e7c70896ffeeef32b9c950ywan const search_site *ss = &x->ss[search_param * x->searches_per_step]; 1115233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int tot_steps = (x->ss_count / x->searches_per_step) - search_param; 1116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1117233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1118233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1119233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1120233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1122233d2500723e5594f3e7c70896ffeeef32b9c950ywan clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max); 1123233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_row = ref_mv->row; 1124233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_col = ref_mv->col; 1125233d2500723e5594f3e7c70896ffeeef32b9c950ywan *num00 = 0; 1126233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = ref_row; 1127233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = ref_col; 1128233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1129233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Work out the start point for the search 1130233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what = xd->plane[0].pre[0].buf + ref_row * in_what_stride + ref_col; 1131233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address = in_what; 1132233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1133233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the starting position 1134233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) 1135233d2500723e5594f3e7c70896ffeeef32b9c950ywan + mvsad_err_cost(best_mv, &fcenter_mv, 1136233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1137233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1138233d2500723e5594f3e7c70896ffeeef32b9c950ywan i = 1; 1139233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1140233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (step = 0; step < tot_steps; step++) { 1141233d2500723e5594f3e7c70896ffeeef32b9c950ywan int all_in = 1, t; 1142233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1143233d2500723e5594f3e7c70896ffeeef32b9c950ywan // All_in is true if every one of the points we are checking are within 1144233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the bounds of the image. 1145233d2500723e5594f3e7c70896ffeeef32b9c950ywan all_in &= ((best_mv->row + ss[i].mv.row) > x->mv_row_min); 1146233d2500723e5594f3e7c70896ffeeef32b9c950ywan all_in &= ((best_mv->row + ss[i + 1].mv.row) < x->mv_row_max); 1147233d2500723e5594f3e7c70896ffeeef32b9c950ywan all_in &= ((best_mv->col + ss[i + 2].mv.col) > x->mv_col_min); 1148233d2500723e5594f3e7c70896ffeeef32b9c950ywan all_in &= ((best_mv->col + ss[i + 3].mv.col) < x->mv_col_max); 1149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1150233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If all the pixels are within the bounds we don't check whether the 1151233d2500723e5594f3e7c70896ffeeef32b9c950ywan // search point is valid in this loop, otherwise we check each point 1152233d2500723e5594f3e7c70896ffeeef32b9c950ywan // for validity.. 1153233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (all_in) { 1154233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad_array[4]; 1155233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1156233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < x->searches_per_step; j += 4) { 1157233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char const *block_offset[4]; 1158233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1159233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (t = 0; t < 4; t++) 1160233d2500723e5594f3e7c70896ffeeef32b9c950ywan block_offset[t] = ss[i + t].offset + best_address; 1161233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1162233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, 1163233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_array); 1164233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1165233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (t = 0; t < 4; t++, i++) { 1166233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad_array[t] < bestsad) { 1167233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {best_mv->row + ss[i].mv.row, 1168233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col + ss[i].mv.col}; 1169233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_array[t] += mvsad_err_cost(&this_mv, &fcenter_mv, 1170233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1171233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1172233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad_array[t] < bestsad) { 1173233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = sad_array[t]; 1174233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = i; 1175233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1176233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1177233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1178233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1179233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1180233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < x->searches_per_step; j++) { 1181233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Trap illegal vectors 1182233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {best_mv->row + ss[i].mv.row, 1183233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col + ss[i].mv.col}; 1184233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1185233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &this_mv)) { 1186233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const check_here = ss[i].offset + best_address; 1187233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here, 1188233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what_stride, bestsad); 1189233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1190233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1191233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1192233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1193233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1194233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1195233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1196233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = i; 1197233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1198233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1199233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1200233d2500723e5594f3e7c70896ffeeef32b9c950ywan i++; 1201233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1202233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1203233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site != last_site) { 1204233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row += ss[best_site].mv.row; 1205233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col += ss[best_site].mv.col; 1206233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address += ss[best_site].offset; 1207233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_site = best_site; 1208233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if defined(NEW_DIAMOND_SEARCH) 1209233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (1) { 1210233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {best_mv->row + ss[best_site].mv.row, 1211233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col + ss[best_site].mv.col}; 1212233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &this_mv)) { 1213233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const check_here = ss[best_site].offset + best_address; 1214233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here, 1215233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what_stride, bestsad); 1216233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1217233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1218233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1219233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1220233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1221233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row += ss[best_site].mv.row; 1222233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col += ss[best_site].mv.col; 1223233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address += ss[best_site].offset; 1224233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 1225233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1226233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1227233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1228233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1229233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 1230233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 1231233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (best_address == in_what) { 1232233d2500723e5594f3e7c70896ffeeef32b9c950ywan (*num00)++; 1233233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1234233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1235233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 1236233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1237233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1238233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* do_refine: If last step (1-away) of n-step search doesn't pick the center 1239233d2500723e5594f3e7c70896ffeeef32b9c950ywan point as the best match, we will do a final 1-away diamond 1240233d2500723e5594f3e7c70896ffeeef32b9c950ywan refining search */ 1241233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1242233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_full_pixel_diamond(const VP9_COMP *cpi, MACROBLOCK *x, 1243233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *mvp_full, int step_param, 1244233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sadpb, int further_steps, int do_refine, 1245233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1246233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *ref_mv, MV *dst_mv) { 1247233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV temp_mv; 1248233d2500723e5594f3e7c70896ffeeef32b9c950ywan int thissme, n, num00 = 0; 1249233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bestsme = cpi->diamond_search_sad(x, mvp_full, &temp_mv, 1250233d2500723e5594f3e7c70896ffeeef32b9c950ywan step_param, sadpb, &n, 1251233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr, x->nmvjointcost, 1252233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mvcost, ref_mv); 1253233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bestsme < INT_MAX) 1254233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsme = vp9_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1); 1255233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dst_mv = temp_mv; 1256233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1257233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If there won't be more n-step search, check to see if refining search is 1258233d2500723e5594f3e7c70896ffeeef32b9c950ywan // needed. 1259233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (n > further_steps) 1260233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_refine = 0; 1261233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1262233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (n < further_steps) { 1263233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++n; 1264233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1265233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (num00) { 1266233d2500723e5594f3e7c70896ffeeef32b9c950ywan num00--; 1267233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1268233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissme = cpi->diamond_search_sad(x, mvp_full, &temp_mv, 1269233d2500723e5594f3e7c70896ffeeef32b9c950ywan step_param + n, sadpb, &num00, 1270233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr, x->nmvjointcost, x->mvcost, 1271233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv); 1272233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissme < INT_MAX) 1273233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissme = vp9_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1); 1274233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1275233d2500723e5594f3e7c70896ffeeef32b9c950ywan // check to see if refining search is needed. 1276233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (num00 > further_steps - n) 1277233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_refine = 0; 1278233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1279233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissme < bestsme) { 1280233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsme = thissme; 1281233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dst_mv = temp_mv; 1282233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1283233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1284233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1285233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1286233d2500723e5594f3e7c70896ffeeef32b9c950ywan // final 1-away diamond refining search 1287233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_refine) { 1288233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int search_range = 8; 1289233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV best_mv = *dst_mv; 1290233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissme = cpi->refining_search_sad(x, &best_mv, sadpb, search_range, 1291233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr, x->nmvjointcost, x->mvcost, 1292233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv); 1293233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissme < INT_MAX) 1294233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissme = vp9_get_mvpred_var(x, &best_mv, ref_mv, fn_ptr, 1); 1295233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissme < bestsme) { 1296233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsme = thissme; 1297233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dst_mv = best_mv; 1298233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1299233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1300233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsme; 1301233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1302233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1303233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_full_search_sad_c(const MACROBLOCK *x, const MV *ref_mv, 1304233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, int distance, 1305233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1306233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1307233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, MV *best_mv) { 1308233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r, c; 1309233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1310233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const what = &x->plane[0].src; 1311233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const in_what = &xd->plane[0].pre[0]; 1312233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int row_min = MAX(ref_mv->row - distance, x->mv_row_min); 1313233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int row_max = MIN(ref_mv->row + distance, x->mv_row_max); 1314233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int col_min = MAX(ref_mv->col - distance, x->mv_col_min); 1315233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int col_max = MIN(ref_mv->col + distance, x->mv_col_max); 1316233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1317233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1318233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1319233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_sad = fn_ptr->sdf(what->buf, what->stride, 1320233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, ref_mv), in_what->stride, 0x7fffffff) + 1321233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvsad_err_cost(ref_mv, &fcenter_mv, mvjsadcost, mvsadcost, sad_per_bit); 1322233d2500723e5594f3e7c70896ffeeef32b9c950ywan *best_mv = *ref_mv; 1323233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1324233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (r = row_min; r < row_max; ++r) { 1325233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (c = col_min; c < col_max; ++c) { 1326233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV mv = {r, c}; 1327233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int sad = fn_ptr->sdf(what->buf, what->stride, 1328233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &mv), in_what->stride, best_sad) + 1329233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvsad_err_cost(&mv, &fcenter_mv, mvjsadcost, mvsadcost, 1330233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_per_bit); 1331233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1332233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad < best_sad) { 1333233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_sad = sad; 1334233d2500723e5594f3e7c70896ffeeef32b9c950ywan *best_mv = mv; 1335233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1336233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1337233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1338233d2500723e5594f3e7c70896ffeeef32b9c950ywan return best_sad; 1339233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1340233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1341233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_full_search_sadx3(const MACROBLOCK *x, const MV *ref_mv, 1342233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, int distance, 1343233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1344233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1345233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, MV *best_mv) { 1346233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1347233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const what = x->plane[0].src.buf; 1348233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int what_stride = x->plane[0].src.stride; 1349233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const in_what = xd->plane[0].pre[0].buf; 1350233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int in_what_stride = xd->plane[0].pre[0].stride; 1351233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV this_mv; 1352233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int bestsad = INT_MAX; 1353233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r, c; 1354233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad; 1355233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_row = ref_mv->row; 1356233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_col = ref_mv->col; 1357233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1358233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Apply further limits to prevent us looking using vectors that stretch 1359233d2500723e5594f3e7c70896ffeeef32b9c950ywan // beyond the UMV border 1360233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int row_min = MAX(ref_row - distance, x->mv_row_min); 1361233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int row_max = MIN(ref_row + distance, x->mv_row_max); 1362233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int col_min = MAX(ref_col - distance, x->mv_col_min); 1363233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int col_max = MIN(ref_col + distance, x->mv_col_max); 1364233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad_array[3]; 1365233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1366233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1367233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1368233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1369233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Work out the mid point for the search 1370233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *bestaddress = &in_what[ref_row * in_what_stride + ref_col]; 1371233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1372233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = ref_row; 1373233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = ref_col; 1374233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1375233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Baseline value at the centre 1376233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = fn_ptr->sdf(what, what_stride, 1377233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestaddress, in_what_stride, 0x7fffffff) 1378233d2500723e5594f3e7c70896ffeeef32b9c950ywan + mvsad_err_cost(best_mv, &fcenter_mv, 1379233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1380233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1381233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (r = row_min; r < row_max; r++) { 1382233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *check_here = &in_what[r * in_what_stride + col_min]; 1383233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.row = r; 1384233d2500723e5594f3e7c70896ffeeef32b9c950ywan c = col_min; 1385233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1386233d2500723e5594f3e7c70896ffeeef32b9c950ywan while ((c + 2) < col_max && fn_ptr->sdx3f != NULL) { 1387233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 1388233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1389233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr->sdx3f(what, what_stride, check_here, in_what_stride, sad_array); 1390233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1391233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 3; i++) { 1392233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = sad_array[i]; 1393233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1394233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1395233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.col = c; 1396233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1397233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1398233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1399233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1400233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1401233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = r; 1402233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = c; 1403233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1404233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1405233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here++; 1406233d2500723e5594f3e7c70896ffeeef32b9c950ywan c++; 1407233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1408233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1409233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1410233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (c < col_max) { 1411233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride, 1412233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad); 1413233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1414233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1415233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.col = c; 1416233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1417233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1418233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1419233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1420233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1421233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = r; 1422233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = c; 1423233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1424233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1425233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1426233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here++; 1427233d2500723e5594f3e7c70896ffeeef32b9c950ywan c++; 1428233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1429233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1430233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 1431233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1432233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1433233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_full_search_sadx8(const MACROBLOCK *x, const MV *ref_mv, 1434233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sad_per_bit, int distance, 1435233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1436233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1437233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, MV *best_mv) { 1438233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1439233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const what = x->plane[0].src.buf; 1440233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int what_stride = x->plane[0].src.stride; 1441233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const in_what = xd->plane[0].pre[0].buf; 1442233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int in_what_stride = xd->plane[0].pre[0].stride; 1443233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV this_mv; 1444233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int bestsad = INT_MAX; 1445233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r, c; 1446233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_row = ref_mv->row; 1447233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_col = ref_mv->col; 1448233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1449233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Apply further limits to prevent us looking using vectors that stretch 1450233d2500723e5594f3e7c70896ffeeef32b9c950ywan // beyond the UMV border 1451233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int row_min = MAX(ref_row - distance, x->mv_row_min); 1452233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int row_max = MIN(ref_row + distance, x->mv_row_max); 1453233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int col_min = MAX(ref_col - distance, x->mv_col_min); 1454233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int col_max = MIN(ref_col + distance, x->mv_col_max); 1455233d2500723e5594f3e7c70896ffeeef32b9c950ywan DECLARE_ALIGNED_ARRAY(16, uint32_t, sad_array8, 8); 1456233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad_array[3]; 1457233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1458233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1459233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1460233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1461233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1462233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Work out the mid point for the search 1463233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *bestaddress = &in_what[ref_row * in_what_stride + ref_col]; 1464233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1465233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = ref_row; 1466233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = ref_col; 1467233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1468233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Baseline value at the center 1469233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = fn_ptr->sdf(what, what_stride, 1470233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestaddress, in_what_stride, 0x7fffffff) 1471233d2500723e5594f3e7c70896ffeeef32b9c950ywan + mvsad_err_cost(best_mv, &fcenter_mv, 1472233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1473233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1474233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (r = row_min; r < row_max; r++) { 1475233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *check_here = &in_what[r * in_what_stride + col_min]; 1476233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.row = r; 1477233d2500723e5594f3e7c70896ffeeef32b9c950ywan c = col_min; 1478233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1479233d2500723e5594f3e7c70896ffeeef32b9c950ywan while ((c + 7) < col_max) { 1480233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 1481233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1482233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr->sdx8f(what, what_stride, check_here, in_what_stride, sad_array8); 1483233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1484233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 8; i++) { 1485233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad = (unsigned int)sad_array8[i]; 1486233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1487233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1488233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.col = c; 1489233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1490233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1491233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1492233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1493233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1494233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = r; 1495233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = c; 1496233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1497233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1498233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1499233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here++; 1500233d2500723e5594f3e7c70896ffeeef32b9c950ywan c++; 1501233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1502233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1503233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1504233d2500723e5594f3e7c70896ffeeef32b9c950ywan while ((c + 2) < col_max && fn_ptr->sdx3f != NULL) { 1505233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 1506233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1507233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr->sdx3f(what, what_stride, check_here, in_what_stride, sad_array); 1508233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1509233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 3; i++) { 1510233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad = sad_array[i]; 1511233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1512233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1513233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.col = c; 1514233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1515233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1516233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1517233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1518233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1519233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = r; 1520233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = c; 1521233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1522233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1523233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1524233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here++; 1525233d2500723e5594f3e7c70896ffeeef32b9c950ywan c++; 1526233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1527233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1528233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1529233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (c < col_max) { 1530233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad = fn_ptr->sdf(what, what_stride, 1531233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here, in_what_stride, bestsad); 1532233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1533233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1534233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_mv.col = c; 1535233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1536233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, sad_per_bit); 1537233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1538233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1539233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1540233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->row = r; 1541233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_mv->col = c; 1542233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1543233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1544233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1545233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here++; 1546233d2500723e5594f3e7c70896ffeeef32b9c950ywan c++; 1547233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1548233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1549233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 1550233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1551233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1552233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_refining_search_sad_c(const MACROBLOCK *x, 1553233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, int error_per_bit, 1554233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_range, 1555233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1556233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1557233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv) { 1558233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; 1559233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1560233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const what = &x->plane[0].src; 1561233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const in_what = &xd->plane[0].pre[0]; 1562233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1563233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1564233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1565233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1566233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int best_sad = fn_ptr->sdf(what->buf, what->stride, 1567233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, ref_mv), 1568233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what->stride, 0x7fffffff) + 1569233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvsad_err_cost(ref_mv, &fcenter_mv, mvjsadcost, mvsadcost, error_per_bit); 1570233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j; 1571233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1572233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < search_range; i++) { 1573233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = -1; 1574233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1575233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 4; j++) { 1576233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV mv = {ref_mv->row + neighbors[j].row, 1577233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col + neighbors[j].col}; 1578233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &mv)) { 1579233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad = fn_ptr->sdf(what->buf, what->stride, 1580233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &mv), in_what->stride, best_sad); 1581233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad < best_sad) { 1582233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad += mvsad_err_cost(&mv, &fcenter_mv, mvjsadcost, mvsadcost, 1583233d2500723e5594f3e7c70896ffeeef32b9c950ywan error_per_bit); 1584233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad < best_sad) { 1585233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_sad = sad; 1586233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = j; 1587233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1588233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1589233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1590233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1591233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1592233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site == -1) { 1593233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1594233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1595233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->row += neighbors[best_site].row; 1596233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col += neighbors[best_site].col; 1597233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1598233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1599233d2500723e5594f3e7c70896ffeeef32b9c950ywan return best_sad; 1600233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1601233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1602233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_refining_search_sadx4(const MACROBLOCK *x, 1603233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, int error_per_bit, 1604233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_range, 1605233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1606233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1607233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv) { 1608233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1609233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; 1610233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j; 1611233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1612233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int what_stride = x->plane[0].src.stride; 1613233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int in_what_stride = xd->plane[0].pre[0].stride; 1614233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *what = x->plane[0].src.buf; 1615233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *best_address = xd->plane[0].pre[0].buf + 1616233d2500723e5594f3e7c70896ffeeef32b9c950ywan (ref_mv->row * xd->plane[0].pre[0].stride) + 1617233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col; 1618233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1619233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1620233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1621233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1622233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1623233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1624233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int bestsad = fn_ptr->sdf(what, what_stride, best_address, 1625233d2500723e5594f3e7c70896ffeeef32b9c950ywan in_what_stride, 0x7fffffff) + 1626233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvsad_err_cost(ref_mv, &fcenter_mv, mvjsadcost, mvsadcost, error_per_bit); 1627233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1628233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < search_range; i++) { 1629233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = -1; 1630233d2500723e5594f3e7c70896ffeeef32b9c950ywan int all_in = ((ref_mv->row - 1) > x->mv_row_min) & 1631233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((ref_mv->row + 1) < x->mv_row_max) & 1632233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((ref_mv->col - 1) > x->mv_col_min) & 1633233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((ref_mv->col + 1) < x->mv_col_max); 1634233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1635233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (all_in) { 1636233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad_array[4]; 1637233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t const *block_offset[4] = { 1638233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address - in_what_stride, 1639233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address - 1, 1640233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address + 1, 1641233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address + in_what_stride 1642233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 1643233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1644233d2500723e5594f3e7c70896ffeeef32b9c950ywan fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, 1645233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_array); 1646233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1647233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 4; j++) { 1648233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad_array[j] < bestsad) { 1649233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {ref_mv->row + neighbors[j].row, 1650233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col + neighbors[j].col}; 1651233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad_array[j] += mvsad_err_cost(&this_mv, &fcenter_mv, 1652233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, error_per_bit); 1653233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1654233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad_array[j] < bestsad) { 1655233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = sad_array[j]; 1656233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = j; 1657233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1658233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1659233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1660233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1661233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 4; j++) { 1662233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV this_mv = {ref_mv->row + neighbors[j].row, 1663233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col + neighbors[j].col}; 1664233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1665233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &this_mv)) { 1666233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *check_here = neighbors[j].row * in_what_stride + 1667233d2500723e5594f3e7c70896ffeeef32b9c950ywan neighbors[j].col + best_address; 1668233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int thissad = fn_ptr->sdf(what, what_stride, 1669233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_here, in_what_stride, 1670233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad); 1671233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1672233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1673233d2500723e5594f3e7c70896ffeeef32b9c950ywan thissad += mvsad_err_cost(&this_mv, &fcenter_mv, 1674233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, error_per_bit); 1675233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1676233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (thissad < bestsad) { 1677233d2500723e5594f3e7c70896ffeeef32b9c950ywan bestsad = thissad; 1678233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = j; 1679233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1680233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1681233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1682233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1683233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1684233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1685233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site == -1) { 1686233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1687233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1688233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->row += neighbors[best_site].row; 1689233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col += neighbors[best_site].col; 1690233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_address += (neighbors[best_site].row) * in_what_stride + 1691233d2500723e5594f3e7c70896ffeeef32b9c950ywan neighbors[best_site].col; 1692233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1693233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1694233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1695233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bestsad; 1696233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1697233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1698233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This function is called when we do joint motion search in comp_inter_inter 1699233d2500723e5594f3e7c70896ffeeef32b9c950ywan// mode. 1700233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_refining_search_8p_c(const MACROBLOCK *x, 1701233d2500723e5594f3e7c70896ffeeef32b9c950ywan MV *ref_mv, int error_per_bit, 1702233d2500723e5594f3e7c70896ffeeef32b9c950ywan int search_range, 1703233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vp9_variance_fn_ptr_t *fn_ptr, 1704233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvjcost, int *mvcost[2], 1705233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV *center_mv, 1706233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *second_pred, int w, int h) { 1707233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV neighbors[8] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}, 1708233d2500723e5594f3e7c70896ffeeef32b9c950ywan {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; 1709233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1710233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const what = &x->plane[0].src; 1711233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct buf_2d *const in_what = &xd->plane[0].pre[0]; 1712233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3}; 1713233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int *mvjsadcost = x->nmvjointsadcost; 1714233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; 1715233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int best_sad = fn_ptr->sdaf(what->buf, what->stride, 1716233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, ref_mv), in_what->stride, 1717233d2500723e5594f3e7c70896ffeeef32b9c950ywan second_pred, 0x7fffffff) + 1718233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvsad_err_cost(ref_mv, &fcenter_mv, mvjsadcost, mvsadcost, error_per_bit); 1719233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j; 1720233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1721233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < search_range; ++i) { 1722233d2500723e5594f3e7c70896ffeeef32b9c950ywan int best_site = -1; 1723233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1724233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 8; ++j) { 1725233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV mv = {ref_mv->row + neighbors[j].row, 1726233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col + neighbors[j].col}; 1727233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1728233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_mv_in(x, &mv)) { 1729233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sad = fn_ptr->sdaf(what->buf, what->stride, 1730233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_buf_from_mv(in_what, &mv), in_what->stride, 1731233d2500723e5594f3e7c70896ffeeef32b9c950ywan second_pred, best_sad); 1732233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad < best_sad) { 1733233d2500723e5594f3e7c70896ffeeef32b9c950ywan sad += mvsad_err_cost(&mv, &fcenter_mv, 1734233d2500723e5594f3e7c70896ffeeef32b9c950ywan mvjsadcost, mvsadcost, error_per_bit); 1735233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sad < best_sad) { 1736233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_sad = sad; 1737233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_site = j; 1738233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1739233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1740233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1741233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1742233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1743233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_site == -1) { 1744233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1745233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1746233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->row += neighbors[best_site].row; 1747233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_mv->col += neighbors[best_site].col; 1748233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1749233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1750233d2500723e5594f3e7c70896ffeeef32b9c950ywan return best_sad; 1751233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1752