1/*
2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "vp9/common/vp9_findnearmv.h"
12#include "vp9/common/vp9_mvref_common.h"
13
14static void lower_mv_precision(MV *mv, int allow_hp) {
15  const int use_hp = allow_hp && vp9_use_mv_hp(mv);
16  if (!use_hp) {
17    if (mv->row & 1)
18      mv->row += (mv->row > 0 ? -1 : 1);
19    if (mv->col & 1)
20      mv->col += (mv->col > 0 ? -1 : 1);
21  }
22}
23
24
25void vp9_find_best_ref_mvs(MACROBLOCKD *xd,
26                           int_mv *mvlist,
27                           int_mv *nearest,
28                           int_mv *near) {
29  int i;
30  // Make sure all the candidates are properly clamped etc
31  for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
32    lower_mv_precision(&mvlist[i].as_mv, xd->allow_high_precision_mv);
33    clamp_mv2(&mvlist[i].as_mv, xd);
34  }
35  *nearest = mvlist[0];
36  *near = mvlist[1];
37}
38
39void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
40                                   int_mv *dst_nearest,
41                                   int_mv *dst_near,
42                                   int block_idx, int ref_idx,
43                                   int mi_row, int mi_col) {
44  int_mv dst_list[MAX_MV_REF_CANDIDATES];
45  int_mv mv_list[MAX_MV_REF_CANDIDATES];
46  MODE_INFO *const mi = xd->this_mi;
47
48  assert(ref_idx == 0 || ref_idx == 1);
49  assert(MAX_MV_REF_CANDIDATES == 2);  // makes code here slightly easier
50
51  vp9_find_mv_refs_idx(cm, xd, mi, xd->last_mi,
52                       mi->mbmi.ref_frame[ref_idx],
53                       mv_list, block_idx, mi_row, mi_col);
54
55  dst_list[1].as_int = 0;
56  if (block_idx == 0) {
57    memcpy(dst_list, mv_list, MAX_MV_REF_CANDIDATES * sizeof(int_mv));
58  } else if (block_idx == 1 || block_idx == 2) {
59    int dst = 0, n;
60    union b_mode_info *bmi = mi->bmi;
61
62    dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
63    for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
64                n < MAX_MV_REF_CANDIDATES; n++)
65      if (mv_list[n].as_int != dst_list[0].as_int)
66        dst_list[dst++].as_int = mv_list[n].as_int;
67  } else {
68    int dst = 0, n;
69    union b_mode_info *bmi = mi->bmi;
70
71    assert(block_idx == 3);
72    dst_list[dst++].as_int = bmi[2].as_mv[ref_idx].as_int;
73    if (dst_list[0].as_int != bmi[1].as_mv[ref_idx].as_int)
74      dst_list[dst++].as_int = bmi[1].as_mv[ref_idx].as_int;
75    if (dst < MAX_MV_REF_CANDIDATES &&
76        dst_list[0].as_int != bmi[0].as_mv[ref_idx].as_int)
77      dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
78    for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
79                n < MAX_MV_REF_CANDIDATES; n++)
80      if (mv_list[n].as_int != dst_list[0].as_int)
81        dst_list[dst++].as_int = mv_list[n].as_int;
82  }
83
84  dst_nearest->as_int = dst_list[0].as_int;
85  dst_near->as_int = dst_list[1].as_int;
86}
87