vp9_findnearmv.c 3.2 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
 */

Dmitry Kovalev's avatar
Dmitry Kovalev committed
11
12
#include <limits.h>

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

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


Yaowu Xu's avatar
Yaowu Xu committed
27
28
29
30
31
32
33
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
34
    lower_mv_precision(&mvlist[i].as_mv, xd->allow_high_precision_mv);
35
    clamp_mv2(&mvlist[i].as_mv, xd);
Yaowu Xu's avatar
Yaowu Xu committed
36
37
38
39
  }
  *nearest = mvlist[0];
  *near = mvlist[1];
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed
40
41
42
43

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

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

  vp9_find_mv_refs_idx(cm, xd, xd->mode_info_context,
55
                       xd->prev_mode_info_context,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
56
                       mbmi->ref_frame[ref_idx],
57
58
                       mv_list, cm->ref_frame_sign_bias, block_idx,
                       mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
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
87
88
89
90
91

  dst_list[1].as_int = 0;
  if (block_idx == 0) {
    memcpy(dst_list, mv_list, MAX_MV_REF_CANDIDATES * sizeof(int_mv));
  } 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;
}