11184aebb761cbeac9124c37189a80a1a58f04b6bhkuang 2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* 3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Use of this source code is governed by a BSD-style license 6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * that can be found in the LICENSE file in the root of the source 7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * tree. An additional intellectual property rights grant can be found 8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * in the file PATENTS. All contributing project authors may 9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * be found in the AUTHORS file in the root of the source tree. 10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_mvref_common.h" 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define MVREF_NEIGHBOURS 8 15f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniantypedef struct position { 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int row; 18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int col; 19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} POSITION; 20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 21f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef enum { 22f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_ZERO = 0, 23f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang ZERO_PLUS_PREDICTED = 1, 24f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_PREDICTED = 2, 25f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang NEW_PLUS_NON_INTRA = 3, 26f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_NEW = 4, 27f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INTRA_PLUS_NON_INTRA = 5, 28f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_INTRA = 6, 29f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE = 9 30f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang} motion_vector_context; 31f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 32f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// This is used to figure out a context for the ref blocks. The code flattens 33f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// an array that would have 3 possible counts (0, 1 & 2) for 3 choices by 34f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// adding 9 for each intra block, 3 for each zero mv and 1 for each new 35f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// motion vector. This single number is then converted into a context 36f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// with a single lookup ( counter_to_context ). 37f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic const int mode_2_counter[MB_MODE_COUNT] = { 38f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // DC_PRED 39f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // V_PRED 40f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // H_PRED 41f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // D45_PRED 42f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // D135_PRED 43f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // D117_PRED 44f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // D153_PRED 451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang 9, // D207_PRED 46f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // D63_PRED 47f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 9, // TM_PRED 48f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 0, // NEARESTMV 49f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 0, // NEARMV 50f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 3, // ZEROMV 51f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 1, // NEWMV 52f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang}; 53f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 54f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// There are 3^3 different combinations of 3 counts that can be either 0,1 or 55f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// 2. However the actual count can never be greater than 2 so the highest 56f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// counter we need is 18. 9 is an invalid counter that's never used. 57f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic const int counter_to_context[19] = { 58f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_PREDICTED, // 0 59f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang NEW_PLUS_NON_INTRA, // 1 60f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_NEW, // 2 61f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang ZERO_PLUS_PREDICTED, // 3 62f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang NEW_PLUS_NON_INTRA, // 4 63f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 5 64f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_ZERO, // 6 65f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 7 66f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 8 67f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INTRA_PLUS_NON_INTRA, // 9 68f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INTRA_PLUS_NON_INTRA, // 10 69f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 11 70f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INTRA_PLUS_NON_INTRA, // 12 71f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 13 72f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 14 73f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 15 74f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 16 75f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang INVALID_CASE, // 17 76f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang BOTH_INTRA // 18 77f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang}; 78f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const POSITION mv_ref_blocks[BLOCK_SIZES][MVREF_NEIGHBOURS] = { 801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 4X4 811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}}, 821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 4X8 831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}}, 841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 8X4 851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}}, 861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 8X8 871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}}, 881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 8X16 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang {{0, -1}, {-1, 0}, {1, -1}, {-1, -1}, {0, -2}, {-2, 0}, {-2, -1}, {-1, -2}}, 901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 16X8 911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, 1}, {-1, -1}, {-2, 0}, {0, -2}, {-1, -2}, {-2, -1}}, 921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 16X16 931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, 1}, {1, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-3, -3}}, 941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 16X32 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang {{0, -1}, {-1, 0}, {2, -1}, {-1, -1}, {-1, 1}, {0, -3}, {-3, 0}, {-3, -3}}, 961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 32X16 971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, 2}, {-1, -1}, {1, -1}, {-3, 0}, {0, -3}, {-3, -3}}, 981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 32X32 991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 1}, {1, -1}, {-1, 2}, {2, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-3, -3}}, 1001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 32X64 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang {{0, -1}, {-1, 0}, {4, -1}, {-1, 2}, {-1, -1}, {0, -3}, {-3, 0}, {2, -1}}, 1021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 64X32 1031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 0}, {0, -1}, {-1, 4}, {2, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-1, 2}}, 1041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // 64X64 1051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang {{-1, 3}, {3, -1}, {-1, 4}, {4, -1}, {-1, -1}, {-1, 0}, {0, -1}, {-1, 6}} 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 107f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 108f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic const int idx_n_column_to_subblock[4][2] = { 109f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang {1, 2}, 110f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang {1, 3}, 111f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang {3, 2}, 112f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang {3, 3} 113f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang}; 114f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// clamp_mv_ref 1165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1181184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void clamp_mv_ref(MV *mv, const MACROBLOCKD *xd) { 1191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang clamp_mv(mv, xd->mb_to_left_edge - MV_BORDER, 1201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang xd->mb_to_right_edge + MV_BORDER, 1211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang xd->mb_to_top_edge - MV_BORDER, 1221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang xd->mb_to_bottom_edge + MV_BORDER); 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 125f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// This function returns either the appropriate sub block or block's mv 126f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// on whether the block_size < 8x8 and we have check_sub_blocks set. 1275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic INLINE int_mv get_sub_block_mv(const MODE_INFO *candidate, int which_mv, 128f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang int search_col, int block_idx) { 1295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang return block_idx >= 0 && candidate->mbmi.sb_type < BLOCK_8X8 130f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang ? candidate->bmi[idx_n_column_to_subblock[block_idx][search_col == 0]] 131f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang .as_mv[which_mv] 1321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang : candidate->mbmi.mv[which_mv]; 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Performs mv sign inversion if indicated by the reference frame combination. 1371184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic INLINE int_mv scale_mv(const MB_MODE_INFO *mbmi, int ref, 138f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang const MV_REFERENCE_FRAME this_ref_frame, 139f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang const int *ref_sign_bias) { 1401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang int_mv mv = mbmi->mv[ref]; 1411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang if (ref_sign_bias[mbmi->ref_frame[ref]] != ref_sign_bias[this_ref_frame]) { 1421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang mv.as_mv.row *= -1; 1431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang mv.as_mv.col *= -1; 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang return mv; 146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 148f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// This macro is used to add a motion vector mv_ref list if it isn't 149f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// already in the list. If it's the second motion vector it will also 150f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// skip all additional processing and jump to done! 1516ac915abcdb404a00d927fe6308a47fcf09d9519hkuang#define ADD_MV_REF_LIST(mv) \ 1521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang do { \ 1531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang if (refmv_count) { \ 1546ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if ((mv).as_int != mv_ref_list[0].as_int) { \ 1556ac915abcdb404a00d927fe6308a47fcf09d9519hkuang mv_ref_list[refmv_count] = (mv); \ 1561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang goto Done; \ 1571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang } \ 1581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang } else { \ 1596ac915abcdb404a00d927fe6308a47fcf09d9519hkuang mv_ref_list[refmv_count++] = (mv); \ 160f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang } \ 1611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang } while (0) 162f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 163f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// If either reference frame is different, not INTRA, and they 164f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// are different from each other scale and add the mv to our list. 1656ac915abcdb404a00d927fe6308a47fcf09d9519hkuang#define IF_DIFF_REF_FRAME_ADD_MV(mbmi) \ 1661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang do { \ 1676ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (is_inter_block(mbmi)) { \ 1686ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if ((mbmi)->ref_frame[0] != ref_frame) \ 1696ac915abcdb404a00d927fe6308a47fcf09d9519hkuang ADD_MV_REF_LIST(scale_mv((mbmi), 0, ref_frame, ref_sign_bias)); \ 1706ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (has_second_ref(mbmi) && \ 1716ac915abcdb404a00d927fe6308a47fcf09d9519hkuang (mbmi)->ref_frame[1] != ref_frame && \ 1726ac915abcdb404a00d927fe6308a47fcf09d9519hkuang (mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \ 1736ac915abcdb404a00d927fe6308a47fcf09d9519hkuang ADD_MV_REF_LIST(scale_mv((mbmi), 1, ref_frame, ref_sign_bias)); \ 1746ac915abcdb404a00d927fe6308a47fcf09d9519hkuang } \ 1751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang } while (0) 1761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang 177f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 178f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Checks that the given mi_row, mi_col and search point 179f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// are inside the borders of the tile. 1805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic INLINE int is_inside(const TileInfo *const tile, 1815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang int mi_col, int mi_row, int mi_rows, 182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const POSITION *mi_pos) { 183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return !(mi_row + mi_pos->row < 0 || 184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mi_col + mi_pos->col < tile->mi_col_start || 185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mi_row + mi_pos->row >= mi_rows || 186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mi_col + mi_pos->col >= tile->mi_col_end); 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// This function searches the neighbourhood of a given MB/SB 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// to try and find candidate reference vectors. 191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, 192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const TileInfo *const tile, 193a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, 194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int_mv *mv_ref_list, 195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int block, int mi_row, int mi_col) { 1961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const int *ref_sign_bias = cm->ref_frame_sign_bias; 1971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang int i, refmv_count = 0; 1986ac915abcdb404a00d927fe6308a47fcf09d9519hkuang const MODE_INFO *prev_mi = cm->prev_mi 1996ac915abcdb404a00d927fe6308a47fcf09d9519hkuang ? cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col] 2006ac915abcdb404a00d927fe6308a47fcf09d9519hkuang : NULL; 2016ac915abcdb404a00d927fe6308a47fcf09d9519hkuang const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL; 2026ac915abcdb404a00d927fe6308a47fcf09d9519hkuang 2036ac915abcdb404a00d927fe6308a47fcf09d9519hkuang 204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type]; 2056ac915abcdb404a00d927fe6308a47fcf09d9519hkuang 206f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang int different_ref_found = 0; 207f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang int context_counter = 0; 208f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 209f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // Blank the reference vector list 210f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); 211f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 212f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // The nearest 2 blocks are treated differently 213f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // if the size < 8x8 we get the mv from the bmi substructure, 214f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // and we also need to keep a mode count. 2151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang for (i = 0; i < 2; ++i) { 216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const POSITION *const mv_ref = &mv_ref_search[i]; 2175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { 2186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row * 2196ac915abcdb404a00d927fe6308a47fcf09d9519hkuang xd->mi_stride]; 2201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; 2211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // Keep counts for entropy encoding. 2221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang context_counter += mode_2_counter[candidate->mode]; 223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian different_ref_found = 1; 2241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang 225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (candidate->ref_frame[0] == ref_frame) 226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block)); 227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else if (candidate->ref_frame[1] == ref_frame) 228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block)); 229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 232f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // Check the rest of the neighbors in much the same way 233f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // as before except we don't need to keep track of sub blocks or 234f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // mode counts. 2351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang for (; i < MVREF_NEIGHBOURS; ++i) { 236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const POSITION *const mv_ref = &mv_ref_search[i]; 2375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { 2386ac915abcdb404a00d927fe6308a47fcf09d9519hkuang const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row * 2396ac915abcdb404a00d927fe6308a47fcf09d9519hkuang xd->mi_stride]->mbmi; 240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian different_ref_found = 1; 2411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang 242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (candidate->ref_frame[0] == ref_frame) 2431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang ADD_MV_REF_LIST(candidate->mv[0]); 244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else if (candidate->ref_frame[1] == ref_frame) 245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ADD_MV_REF_LIST(candidate->mv[1]); 246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 249f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // Check the last frame's mode and mv info. 2501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang if (prev_mbmi) { 2511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang if (prev_mbmi->ref_frame[0] == ref_frame) 2521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang ADD_MV_REF_LIST(prev_mbmi->mv[0]); 2531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang else if (prev_mbmi->ref_frame[1] == ref_frame) 2541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang ADD_MV_REF_LIST(prev_mbmi->mv[1]); 255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 257f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // Since we couldn't find 2 mvs from the same reference frame 258f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // go back through the neighbors and find motion vectors from 259f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // different reference frames. 260f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang if (different_ref_found) { 2611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang for (i = 0; i < MVREF_NEIGHBOURS; ++i) { 262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const POSITION *mv_ref = &mv_ref_search[i]; 2635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { 2646ac915abcdb404a00d927fe6308a47fcf09d9519hkuang const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row 2656ac915abcdb404a00d927fe6308a47fcf09d9519hkuang * xd->mi_stride]->mbmi; 2661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang 2671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang // If the candidate is INTRA we don't want to consider its mv. 2686ac915abcdb404a00d927fe6308a47fcf09d9519hkuang IF_DIFF_REF_FRAME_ADD_MV(candidate); 2691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang } 270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 273f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang // Since we still don't have a candidate we'll try the last frame. 2746ac915abcdb404a00d927fe6308a47fcf09d9519hkuang if (prev_mbmi) 2751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang IF_DIFF_REF_FRAME_ADD_MV(prev_mbmi); 276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 277f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang Done: 278f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 2791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter]; 280f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Clamp vectors 2821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) 2831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang clamp_mv_ref(&mv_ref_list[i].as_mv, xd); 284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 285b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, 287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const TileInfo *const tile, 288a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, 289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int_mv *mv_ref_list, 290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int mi_row, int mi_col) { 291a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian find_mv_refs_idx(cm, xd, tile, mi, ref_frame, mv_ref_list, -1, 292b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mi_row, mi_col); 293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void lower_mv_precision(MV *mv, int allow_hp) { 296b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const int use_hp = allow_hp && vp9_use_mv_hp(mv); 297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!use_hp) { 298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (mv->row & 1) 299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mv->row += (mv->row > 0 ? -1 : 1); 300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (mv->col & 1) 301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mv->col += (mv->col > 0 ? -1 : 1); 302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp, 307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int_mv *mvlist, int_mv *nearest, int_mv *near) { 308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int i; 309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian // Make sure all the candidates are properly clamped etc 310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) { 311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lower_mv_precision(&mvlist[i].as_mv, allow_hp); 312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clamp_mv2(&mvlist[i].as_mv, xd); 313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *nearest = mvlist[0]; 315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *near = mvlist[1]; 316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, 319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const TileInfo *const tile, 320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int block, int ref, int mi_row, int mi_col, 321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int_mv *nearest, int_mv *near) { 322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int_mv mv_list[MAX_MV_REF_CANDIDATES]; 3236ac915abcdb404a00d927fe6308a47fcf09d9519hkuang MODE_INFO *const mi = xd->mi[0]; 324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian b_mode_info *bmi = mi->bmi; 325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int n; 326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(MAX_MV_REF_CANDIDATES == 2); 328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 329a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian find_mv_refs_idx(cm, xd, tile, mi, mi->mbmi.ref_frame[ref], mv_list, block, 330a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian mi_row, mi_col); 331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 332b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian near->as_int = 0; 333b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian switch (block) { 334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 0: 335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nearest->as_int = mv_list[0].as_int; 336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian near->as_int = mv_list[1].as_int; 337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 1: 339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 2: 340b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nearest->as_int = bmi[0].as_mv[ref].as_int; 341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n) 342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (nearest->as_int != mv_list[n].as_int) { 343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian near->as_int = mv_list[n].as_int; 344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 347b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 3: { 348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int_mv candidates[2 + MAX_MV_REF_CANDIDATES]; 349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian candidates[0] = bmi[1].as_mv[ref]; 350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian candidates[1] = bmi[0].as_mv[ref]; 351b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian candidates[2] = mv_list[0]; 352b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian candidates[3] = mv_list[1]; 353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 354b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nearest->as_int = bmi[2].as_mv[ref].as_int; 355b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n) 356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (nearest->as_int != candidates[n].as_int) { 357b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian near->as_int = candidates[n].as_int; 358b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 361b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 362b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian default: 363b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert("Invalid block index."); 364b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 365b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 366