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// This function searches the neighbourhood of a given MB/SB
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// to try and find candidate reference vectors.
162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                             int_mv *mv_ref_list,
19da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                             int block, int mi_row, int mi_col,
20da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                             find_mv_refs_sync sync, void *const data,
21da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                             uint8_t *mode_context) {
221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int *ref_sign_bias = cm->ref_frame_sign_bias;
231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int i, refmv_count = 0;
242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type];
25f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int different_ref_found = 0;
26f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int context_counter = 0;
27da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  const MV_REF *const  prev_frame_mvs = cm->use_prev_frame_mvs ?
28da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col : NULL;
29da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  const TileInfo *const tile = &xd->tile;
30f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
31f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Blank the reference vector list
32da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
33f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
34f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // The nearest 2 blocks are treated differently
35f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // if the size < 8x8 we get the mv from the bmi substructure,
36f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // and we also need to keep a mode count.
371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (i = 0; i < 2; ++i) {
382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const POSITION *const mv_ref = &mv_ref_search[i];
395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
404fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang      const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row *
414fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                                                   xd->mi_stride];
421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      // Keep counts for entropy encoding.
441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      context_counter += mode_2_counter[candidate->mode];
452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      different_ref_found = 1;
461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (candidate->ref_frame[0] == ref_frame)
48da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block),
49da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                        refmv_count, mv_ref_list, Done);
502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      else if (candidate->ref_frame[1] == ref_frame)
51da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block),
52da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                        refmv_count, mv_ref_list, Done);
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
56f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Check the rest of the neighbors in much the same way
57f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // as before except we don't need to keep track of sub blocks or
58f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // mode counts.
591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (; i < MVREF_NEIGHBOURS; ++i) {
602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    const POSITION *const mv_ref = &mv_ref_search[i];
615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
624fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang      const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row *
634fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                                                    xd->mi_stride]->mbmi;
642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      different_ref_found = 1;
651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      if (candidate->ref_frame[0] == ref_frame)
67da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        ADD_MV_REF_LIST(candidate->mv[0], refmv_count, mv_ref_list, Done);
682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      else if (candidate->ref_frame[1] == ref_frame)
69da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        ADD_MV_REF_LIST(candidate->mv[1], refmv_count, mv_ref_list, Done);
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
73da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // TODO(hkuang): Remove this sync after fixing pthread_cond_broadcast
74da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // on windows platform. The sync here is unncessary if use_perv_frame_mvs
75da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // is 0. But after removing it, there will be hang in the unit test on windows
76da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  // due to several threads waiting for a thread's signal.
77da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(_WIN32) && !HAVE_PTHREAD_H
78da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    if (cm->frame_parallel_decode && sync != NULL) {
79da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      sync(data, mi_row);
80da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    }
81da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif
82da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
83f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Check the last frame's mode and mv info.
84da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (cm->use_prev_frame_mvs) {
85da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    // Synchronize here for frame parallel decode if sync function is provided.
86da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    if (cm->frame_parallel_decode && sync != NULL) {
87da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      sync(data, mi_row);
88da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    }
89da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
90da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    if (prev_frame_mvs->ref_frame[0] == ref_frame) {
91da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      ADD_MV_REF_LIST(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done);
92da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    } else if (prev_frame_mvs->ref_frame[1] == ref_frame) {
93da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      ADD_MV_REF_LIST(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done);
94da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    }
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
97f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Since we couldn't find 2 mvs from the same reference frame
98f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // go back through the neighbors and find motion vectors from
99f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // different reference frames.
100f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (different_ref_found) {
1011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
1022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      const POSITION *mv_ref = &mv_ref_search[i];
1035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
1044fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang        const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row
1054fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang                                              * xd->mi_stride]->mbmi;
1061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        // If the candidate is INTRA we don't want to consider its mv.
108da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        IF_DIFF_REF_FRAME_ADD_MV(candidate, ref_frame, ref_sign_bias,
109da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                 refmv_count, mv_ref_list, Done);
1101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
114f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Since we still don't have a candidate we'll try the last frame.
115da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (cm->use_prev_frame_mvs) {
116da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    if (prev_frame_mvs->ref_frame[0] != ref_frame &&
117da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        prev_frame_mvs->ref_frame[0] > INTRA_FRAME) {
118da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      int_mv mv = prev_frame_mvs->mv[0];
119da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] !=
120da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian          ref_sign_bias[ref_frame]) {
121da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        mv.as_mv.row *= -1;
122da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        mv.as_mv.col *= -1;
123da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      }
124da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, Done);
125da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    }
126da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
127da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME &&
128da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        prev_frame_mvs->ref_frame[1] != ref_frame &&
129da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        prev_frame_mvs->mv[1].as_int != prev_frame_mvs->mv[0].as_int) {
130da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      int_mv mv = prev_frame_mvs->mv[1];
131da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] !=
132da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian          ref_sign_bias[ref_frame]) {
133da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        mv.as_mv.row *= -1;
134da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        mv.as_mv.col *= -1;
135da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      }
136da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, Done);
137da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    }
138da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
140f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang Done:
141f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
142da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  mode_context[ref_frame] = counter_to_context[context_counter];
143f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Clamp vectors
1451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i)
1461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    clamp_mv_ref(&mv_ref_list[i].as_mv, xd);
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
150da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                      MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
151da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                      int_mv *mv_ref_list,
152da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                      int mi_row, int mi_col,
153da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                      find_mv_refs_sync sync, void *const data,
154da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                      uint8_t *mode_context) {
155da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1,
156da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                   mi_row, mi_col, sync, data, mode_context);
1572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic void lower_mv_precision(MV *mv, int allow_hp) {
1602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const int use_hp = allow_hp && vp9_use_mv_hp(mv);
1612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (!use_hp) {
1622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (mv->row & 1)
1632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      mv->row += (mv->row > 0 ? -1 : 1);
1642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    if (mv->col & 1)
1652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      mv->col += (mv->col > 0 ? -1 : 1);
1662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
1672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp,
170da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                           int_mv *mvlist, int_mv *nearest_mv,
171da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                           int_mv *near_mv) {
1722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int i;
1732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  // Make sure all the candidates are properly clamped etc
1742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
1752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    lower_mv_precision(&mvlist[i].as_mv, allow_hp);
1762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    clamp_mv2(&mvlist[i].as_mv, xd);
1772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
178da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  *nearest_mv = mvlist[0];
179da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  *near_mv = mvlist[1];
1802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
1832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                   int block, int ref, int mi_row, int mi_col,
184da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                   int_mv *nearest_mv, int_mv *near_mv,
185da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                   uint8_t *mode_context) {
1862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int_mv mv_list[MAX_MV_REF_CANDIDATES];
1874fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  MODE_INFO *const mi = xd->mi[0];
1882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  b_mode_info *bmi = mi->bmi;
1892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  int n;
1902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  assert(MAX_MV_REF_CANDIDATES == 2);
1922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
193da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block,
194da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                   mi_row, mi_col, NULL, NULL, mode_context);
1952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
196da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  near_mv->as_int = 0;
1972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  switch (block) {
1982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case 0:
199da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      nearest_mv->as_int = mv_list[0].as_int;
200da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      near_mv->as_int = mv_list[1].as_int;
2012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      break;
2022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case 1:
2032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case 2:
204da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      nearest_mv->as_int = bmi[0].as_mv[ref].as_int;
2052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n)
206da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        if (nearest_mv->as_int != mv_list[n].as_int) {
207da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian          near_mv->as_int = mv_list[n].as_int;
2082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          break;
2092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        }
2102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      break;
2112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    case 3: {
2122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      int_mv candidates[2 + MAX_MV_REF_CANDIDATES];
2132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      candidates[0] = bmi[1].as_mv[ref];
2142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      candidates[1] = bmi[0].as_mv[ref];
2152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      candidates[2] = mv_list[0];
2162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      candidates[3] = mv_list[1];
2172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
218da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      nearest_mv->as_int = bmi[2].as_mv[ref].as_int;
2192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n)
220da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        if (nearest_mv->as_int != candidates[n].as_int) {
221da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian          near_mv->as_int = candidates[n].as_int;
2222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian          break;
2232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian        }
2242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian      break;
2252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    }
2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    default:
227da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      assert(0 && "Invalid block index.");
2282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
2292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
230