2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
12 #include "findnearmv.h"
14 #define FINDNEAR_SEARCH_SITES 3
16 /* Predict motion vectors using those from already-decoded nearby blocks.
17 Note that we only consider one 4x4 subblock from each candidate 16x16
24 } int_mv
; /* facilitates rapid equality tests */
26 static void mv_bias(const MODE_INFO
*x
, int refframe
, int_mv
*mvp
, const int *ref_frame_sign_bias
)
29 xmv
= x
->mbmi
.mv
.as_mv
;
31 if (ref_frame_sign_bias
[x
->mbmi
.ref_frame
] != ref_frame_sign_bias
[refframe
])
41 void vp8_clamp_mv(MV
*mv
, const MACROBLOCKD
*xd
)
43 if (mv
->col
< (xd
->mb_to_left_edge
- LEFT_TOP_MARGIN
))
44 mv
->col
= xd
->mb_to_left_edge
- LEFT_TOP_MARGIN
;
45 else if (mv
->col
> xd
->mb_to_right_edge
+ RIGHT_BOTTOM_MARGIN
)
46 mv
->col
= xd
->mb_to_right_edge
+ RIGHT_BOTTOM_MARGIN
;
48 if (mv
->row
< (xd
->mb_to_top_edge
- LEFT_TOP_MARGIN
))
49 mv
->row
= xd
->mb_to_top_edge
- LEFT_TOP_MARGIN
;
50 else if (mv
->row
> xd
->mb_to_bottom_edge
+ RIGHT_BOTTOM_MARGIN
)
51 mv
->row
= xd
->mb_to_bottom_edge
+ RIGHT_BOTTOM_MARGIN
;
55 void vp8_find_near_mvs
58 const MODE_INFO
*here
,
64 int *ref_frame_sign_bias
67 const MODE_INFO
*above
= here
- xd
->mode_info_stride
;
68 const MODE_INFO
*left
= here
- 1;
69 const MODE_INFO
*aboveleft
= above
- 1;
71 int_mv
*mv
= near_mvs
;
73 enum {CNT_INTRA
, CNT_NEAREST
, CNT_NEAR
, CNT_SPLITMV
};
75 /* Zero accumulators */
76 mv
[0].as_int
= mv
[1].as_int
= mv
[2].as_int
= 0;
77 cnt
[0] = cnt
[1] = cnt
[2] = cnt
[3] = 0;
80 if (above
->mbmi
.ref_frame
!= INTRA_FRAME
)
82 if (above
->mbmi
.mv
.as_int
)
84 (++mv
)->as_int
= above
->mbmi
.mv
.as_int
;
85 mv_bias(above
, refframe
, mv
, ref_frame_sign_bias
);
93 if (left
->mbmi
.ref_frame
!= INTRA_FRAME
)
95 if (left
->mbmi
.mv
.as_int
)
99 this_mv
.as_int
= left
->mbmi
.mv
.as_int
;
100 mv_bias(left
, refframe
, &this_mv
, ref_frame_sign_bias
);
102 if (this_mv
.as_int
!= mv
->as_int
)
104 (++mv
)->as_int
= this_mv
.as_int
;
114 /* Process above left */
115 if (aboveleft
->mbmi
.ref_frame
!= INTRA_FRAME
)
117 if (aboveleft
->mbmi
.mv
.as_int
)
121 this_mv
.as_int
= aboveleft
->mbmi
.mv
.as_int
;
122 mv_bias(aboveleft
, refframe
, &this_mv
, ref_frame_sign_bias
);
124 if (this_mv
.as_int
!= mv
->as_int
)
126 (++mv
)->as_int
= this_mv
.as_int
;
136 /* If we have three distinct MV's ... */
137 if (cnt
[CNT_SPLITMV
])
139 /* See if above-left MV can be merged with NEAREST */
140 if (mv
->as_int
== near_mvs
[CNT_NEAREST
].as_int
)
141 cnt
[CNT_NEAREST
] += 1;
144 cnt
[CNT_SPLITMV
] = ((above
->mbmi
.mode
== SPLITMV
)
145 + (left
->mbmi
.mode
== SPLITMV
)) * 2
146 + (aboveleft
->mbmi
.mode
== SPLITMV
);
148 /* Swap near and nearest if necessary */
149 if (cnt
[CNT_NEAR
] > cnt
[CNT_NEAREST
])
152 tmp
= cnt
[CNT_NEAREST
];
153 cnt
[CNT_NEAREST
] = cnt
[CNT_NEAR
];
155 tmp
= near_mvs
[CNT_NEAREST
].as_int
;
156 near_mvs
[CNT_NEAREST
].as_int
= near_mvs
[CNT_NEAR
].as_int
;
157 near_mvs
[CNT_NEAR
].as_int
= tmp
;
160 /* Use near_mvs[0] to store the "best" MV */
161 if (cnt
[CNT_NEAREST
] >= cnt
[CNT_INTRA
])
162 near_mvs
[CNT_INTRA
] = near_mvs
[CNT_NEAREST
];
164 /* Set up return values */
165 *best_mv
= near_mvs
[0].as_mv
;
166 *nearest
= near_mvs
[CNT_NEAREST
].as_mv
;
167 *nearby
= near_mvs
[CNT_NEAR
].as_mv
;
169 vp8_clamp_mv(nearest
, xd
);
170 vp8_clamp_mv(nearby
, xd
);
171 vp8_clamp_mv(best_mv
, xd
); /*TODO: move this up before the copy*/
174 vp8_prob
*vp8_mv_ref_probs(
175 vp8_prob p
[VP8_MVREFS
-1], const int near_mv_ref_ct
[4]
178 p
[0] = vp8_mode_contexts
[near_mv_ref_ct
[0]] [0];
179 p
[1] = vp8_mode_contexts
[near_mv_ref_ct
[1]] [1];
180 p
[2] = vp8_mode_contexts
[near_mv_ref_ct
[2]] [2];
181 p
[3] = vp8_mode_contexts
[near_mv_ref_ct
[3]] [3];
182 /*p[3] = vp8_mode_contexts [near_mv_ref_ct[1] + near_mv_ref_ct[2] + near_mv_ref_ct[3]] [3];*/
186 const B_MODE_INFO
*vp8_left_bmi(const MODE_INFO
*cur_mb
, int b
)
190 /* On L edge, get from MB to left of us */
195 return cur_mb
->bmi
+ b
- 1;
198 const B_MODE_INFO
*vp8_above_bmi(const MODE_INFO
*cur_mb
, int b
, int mi_stride
)
202 /* On top edge, get from MB above us */
207 return cur_mb
->bmi
+ b
- 4;