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 :
12 : #include "findnearmv.h"
13 :
14 : const unsigned char vp8_mbsplit_offset[4][16] = {
15 : { 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
16 : { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
17 : { 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
18 : { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
19 : };
20 :
21 : /* Predict motion vectors using those from already-decoded nearby blocks.
22 : Note that we only consider one 4x4 subblock from each candidate 16x16
23 : macroblock. */
24 0 : void vp8_find_near_mvs
25 : (
26 : MACROBLOCKD *xd,
27 : const MODE_INFO *here,
28 : int_mv *nearest,
29 : int_mv *nearby,
30 : int_mv *best_mv,
31 : int cnt[4],
32 : int refframe,
33 : int *ref_frame_sign_bias
34 : )
35 : {
36 0 : const MODE_INFO *above = here - xd->mode_info_stride;
37 0 : const MODE_INFO *left = here - 1;
38 0 : const MODE_INFO *aboveleft = above - 1;
39 : int_mv near_mvs[4];
40 0 : int_mv *mv = near_mvs;
41 0 : int *cntx = cnt;
42 : enum {CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV};
43 :
44 : /* Zero accumulators */
45 0 : mv[0].as_int = mv[1].as_int = mv[2].as_int = 0;
46 0 : cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
47 :
48 : /* Process above */
49 0 : if (above->mbmi.ref_frame != INTRA_FRAME)
50 : {
51 0 : if (above->mbmi.mv.as_int)
52 : {
53 0 : (++mv)->as_int = above->mbmi.mv.as_int;
54 0 : mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], refframe, mv, ref_frame_sign_bias);
55 0 : ++cntx;
56 : }
57 :
58 0 : *cntx += 2;
59 : }
60 :
61 : /* Process left */
62 0 : if (left->mbmi.ref_frame != INTRA_FRAME)
63 : {
64 0 : if (left->mbmi.mv.as_int)
65 : {
66 : int_mv this_mv;
67 :
68 0 : this_mv.as_int = left->mbmi.mv.as_int;
69 0 : mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], refframe, &this_mv, ref_frame_sign_bias);
70 :
71 0 : if (this_mv.as_int != mv->as_int)
72 : {
73 0 : (++mv)->as_int = this_mv.as_int;
74 0 : ++cntx;
75 : }
76 :
77 0 : *cntx += 2;
78 : }
79 : else
80 0 : cnt[CNT_INTRA] += 2;
81 : }
82 :
83 : /* Process above left */
84 0 : if (aboveleft->mbmi.ref_frame != INTRA_FRAME)
85 : {
86 0 : if (aboveleft->mbmi.mv.as_int)
87 : {
88 : int_mv this_mv;
89 :
90 0 : this_mv.as_int = aboveleft->mbmi.mv.as_int;
91 0 : mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], refframe, &this_mv, ref_frame_sign_bias);
92 :
93 0 : if (this_mv.as_int != mv->as_int)
94 : {
95 0 : (++mv)->as_int = this_mv.as_int;
96 0 : ++cntx;
97 : }
98 :
99 0 : *cntx += 1;
100 : }
101 : else
102 0 : cnt[CNT_INTRA] += 1;
103 : }
104 :
105 : /* If we have three distinct MV's ... */
106 0 : if (cnt[CNT_SPLITMV])
107 : {
108 : /* See if above-left MV can be merged with NEAREST */
109 0 : if (mv->as_int == near_mvs[CNT_NEAREST].as_int)
110 0 : cnt[CNT_NEAREST] += 1;
111 : }
112 :
113 0 : cnt[CNT_SPLITMV] = ((above->mbmi.mode == SPLITMV)
114 0 : + (left->mbmi.mode == SPLITMV)) * 2
115 0 : + (aboveleft->mbmi.mode == SPLITMV);
116 :
117 : /* Swap near and nearest if necessary */
118 0 : if (cnt[CNT_NEAR] > cnt[CNT_NEAREST])
119 : {
120 : int tmp;
121 0 : tmp = cnt[CNT_NEAREST];
122 0 : cnt[CNT_NEAREST] = cnt[CNT_NEAR];
123 0 : cnt[CNT_NEAR] = tmp;
124 0 : tmp = near_mvs[CNT_NEAREST].as_int;
125 0 : near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int;
126 0 : near_mvs[CNT_NEAR].as_int = tmp;
127 : }
128 :
129 : /* Use near_mvs[0] to store the "best" MV */
130 0 : if (cnt[CNT_NEAREST] >= cnt[CNT_INTRA])
131 0 : near_mvs[CNT_INTRA] = near_mvs[CNT_NEAREST];
132 :
133 : /* Set up return values */
134 0 : best_mv->as_int = near_mvs[0].as_int;
135 0 : nearest->as_int = near_mvs[CNT_NEAREST].as_int;
136 0 : nearby->as_int = near_mvs[CNT_NEAR].as_int;
137 :
138 : //TODO: move clamp outside findnearmv
139 0 : vp8_clamp_mv2(nearest, xd);
140 0 : vp8_clamp_mv2(nearby, xd);
141 0 : vp8_clamp_mv2(best_mv, xd);
142 0 : }
143 :
144 0 : vp8_prob *vp8_mv_ref_probs(
145 : vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
146 : )
147 : {
148 0 : p[0] = vp8_mode_contexts [near_mv_ref_ct[0]] [0];
149 0 : p[1] = vp8_mode_contexts [near_mv_ref_ct[1]] [1];
150 0 : p[2] = vp8_mode_contexts [near_mv_ref_ct[2]] [2];
151 0 : p[3] = vp8_mode_contexts [near_mv_ref_ct[3]] [3];
152 : /*p[3] = vp8_mode_contexts [near_mv_ref_ct[1] + near_mv_ref_ct[2] + near_mv_ref_ct[3]] [3];*/
153 0 : return p;
154 : }
155 :
|