vp9_findnearmv.c 3.04 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
 */

11
#include "vp9/common/vp9_findnearmv.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
12
#include "vp9/common/vp9_mvref_common.h"
John Koleszar's avatar
John Koleszar committed
13

Dmitry Kovalev's avatar
Dmitry Kovalev committed
14
15
static void lower_mv_precision(MV *mv, int allow_hp) {
  const int use_hp = allow_hp && vp9_use_mv_hp(mv);
16
  if (!use_hp) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
17
18
19
20
    if (mv->row & 1)
      mv->row += (mv->row > 0 ? -1 : 1);
    if (mv->col & 1)
      mv->col += (mv->col > 0 ? -1 : 1);
21
  }
22
23
24
}


Yaowu Xu's avatar
Yaowu Xu committed
25
26
27
28
29
30
31
void vp9_find_best_ref_mvs(MACROBLOCKD *xd,
                           int_mv *mvlist,
                           int_mv *nearest,
                           int_mv *near) {
  int i;
  // Make sure all the candidates are properly clamped etc
  for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
32
    lower_mv_precision(&mvlist[i].as_mv, xd->allow_high_precision_mv);
33
    clamp_mv2(&mvlist[i].as_mv, xd);
Yaowu Xu's avatar
Yaowu Xu committed
34
35
36
37
  }
  *nearest = mvlist[0];
  *near = mvlist[1];
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed
38
39
40
41

void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
                                   int_mv *dst_nearest,
                                   int_mv *dst_near,
42
43
                                   int block_idx, int ref_idx,
                                   int mi_row, int mi_col) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
44
45
  int_mv dst_list[MAX_MV_REF_CANDIDATES];
  int_mv mv_list[MAX_MV_REF_CANDIDATES];
46
  MODE_INFO *const mi = xd->this_mi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
47
48
49
50

  assert(ref_idx == 0 || ref_idx == 1);
  assert(MAX_MV_REF_CANDIDATES == 2);  // makes code here slightly easier

51
  vp9_find_mv_refs_idx(cm, xd, mi, xd->last_mi,
52
53
                       mi->mbmi.ref_frame[ref_idx],
                       mv_list, block_idx, mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
54
55
56

  dst_list[1].as_int = 0;
  if (block_idx == 0) {
Yaowu Xu's avatar
Yaowu Xu committed
57
    vpx_memcpy(dst_list, mv_list, MAX_MV_REF_CANDIDATES * sizeof(int_mv));
Ronald S. Bultje's avatar
Ronald S. Bultje committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  } else if (block_idx == 1 || block_idx == 2) {
    int dst = 0, n;
    union b_mode_info *bmi = mi->bmi;

    dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
    for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
                n < MAX_MV_REF_CANDIDATES; n++)
      if (mv_list[n].as_int != dst_list[0].as_int)
        dst_list[dst++].as_int = mv_list[n].as_int;
  } else {
    int dst = 0, n;
    union b_mode_info *bmi = mi->bmi;

    assert(block_idx == 3);
    dst_list[dst++].as_int = bmi[2].as_mv[ref_idx].as_int;
    if (dst_list[0].as_int != bmi[1].as_mv[ref_idx].as_int)
      dst_list[dst++].as_int = bmi[1].as_mv[ref_idx].as_int;
    if (dst < MAX_MV_REF_CANDIDATES &&
        dst_list[0].as_int != bmi[0].as_mv[ref_idx].as_int)
      dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
    for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
                n < MAX_MV_REF_CANDIDATES; n++)
      if (mv_list[n].as_int != dst_list[0].as_int)
        dst_list[dst++].as_int = mv_list[n].as_int;
  }

  dst_nearest->as_int = dst_list[0].as_int;
  dst_near->as_int = dst_list[1].as_int;
}