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 /* Predict motion vectors using those from already-decoded nearby blocks.
15 Note that we only consider one 4x4 subblock from each candidate 16x16
17 void vp8_find_near_mvs
20 const MODE_INFO
*here
,
26 int *ref_frame_sign_bias
29 const MODE_INFO
*above
= here
- xd
->mode_info_stride
;
30 const MODE_INFO
*left
= here
- 1;
31 const MODE_INFO
*aboveleft
= above
- 1;
33 int_mv
*mv
= near_mvs
;
35 enum {CNT_INTRA
, CNT_NEAREST
, CNT_NEAR
, CNT_SPLITMV
};
37 /* Zero accumulators */
38 mv
[0].as_int
= mv
[1].as_int
= mv
[2].as_int
= 0;
39 cnt
[0] = cnt
[1] = cnt
[2] = cnt
[3] = 0;
42 if (above
->mbmi
.ref_frame
!= INTRA_FRAME
)
44 if (above
->mbmi
.mv
.as_int
)
46 (++mv
)->as_int
= above
->mbmi
.mv
.as_int
;
47 mv_bias(ref_frame_sign_bias
[above
->mbmi
.ref_frame
], refframe
, mv
, ref_frame_sign_bias
);
55 if (left
->mbmi
.ref_frame
!= INTRA_FRAME
)
57 if (left
->mbmi
.mv
.as_int
)
61 this_mv
.as_int
= left
->mbmi
.mv
.as_int
;
62 mv_bias(ref_frame_sign_bias
[left
->mbmi
.ref_frame
], refframe
, &this_mv
, ref_frame_sign_bias
);
64 if (this_mv
.as_int
!= mv
->as_int
)
66 (++mv
)->as_int
= this_mv
.as_int
;
76 /* Process above left */
77 if (aboveleft
->mbmi
.ref_frame
!= INTRA_FRAME
)
79 if (aboveleft
->mbmi
.mv
.as_int
)
83 this_mv
.as_int
= aboveleft
->mbmi
.mv
.as_int
;
84 mv_bias(ref_frame_sign_bias
[aboveleft
->mbmi
.ref_frame
], refframe
, &this_mv
, ref_frame_sign_bias
);
86 if (this_mv
.as_int
!= mv
->as_int
)
88 (++mv
)->as_int
= this_mv
.as_int
;
98 /* If we have three distinct MV's ... */
101 /* See if above-left MV can be merged with NEAREST */
102 if (mv
->as_int
== near_mvs
[CNT_NEAREST
].as_int
)
103 cnt
[CNT_NEAREST
] += 1;
106 cnt
[CNT_SPLITMV
] = ((above
->mbmi
.mode
== SPLITMV
)
107 + (left
->mbmi
.mode
== SPLITMV
)) * 2
108 + (aboveleft
->mbmi
.mode
== SPLITMV
);
110 /* Swap near and nearest if necessary */
111 if (cnt
[CNT_NEAR
] > cnt
[CNT_NEAREST
])
114 tmp
= cnt
[CNT_NEAREST
];
115 cnt
[CNT_NEAREST
] = cnt
[CNT_NEAR
];
117 tmp
= near_mvs
[CNT_NEAREST
].as_int
;
118 near_mvs
[CNT_NEAREST
].as_int
= near_mvs
[CNT_NEAR
].as_int
;
119 near_mvs
[CNT_NEAR
].as_int
= tmp
;
122 /* Use near_mvs[0] to store the "best" MV */
123 if (cnt
[CNT_NEAREST
] >= cnt
[CNT_INTRA
])
124 near_mvs
[CNT_INTRA
] = near_mvs
[CNT_NEAREST
];
126 /* Set up return values */
127 *best_mv
= near_mvs
[0].as_mv
;
128 *nearest
= near_mvs
[CNT_NEAREST
].as_mv
;
129 *nearby
= near_mvs
[CNT_NEAR
].as_mv
;
131 vp8_clamp_mv(nearest
, xd
);
132 vp8_clamp_mv(nearby
, xd
);
133 vp8_clamp_mv(best_mv
, xd
); /*TODO: move this up before the copy*/
136 vp8_prob
*vp8_mv_ref_probs(
137 vp8_prob p
[VP8_MVREFS
-1], const int near_mv_ref_ct
[4]
140 p
[0] = vp8_mode_contexts
[near_mv_ref_ct
[0]] [0];
141 p
[1] = vp8_mode_contexts
[near_mv_ref_ct
[1]] [1];
142 p
[2] = vp8_mode_contexts
[near_mv_ref_ct
[2]] [2];
143 p
[3] = vp8_mode_contexts
[near_mv_ref_ct
[3]] [3];
144 /*p[3] = vp8_mode_contexts [near_mv_ref_ct[1] + near_mv_ref_ct[2] + near_mv_ref_ct[3]] [3];*/
148 const B_MODE_INFO
*vp8_left_bmi(const MODE_INFO
*cur_mb
, int b
)
152 /* On L edge, get from MB to left of us */
157 return cur_mb
->bmi
+ b
- 1;
160 const B_MODE_INFO
*vp8_above_bmi(const MODE_INFO
*cur_mb
, int b
, int mi_stride
)
164 /* On top edge, get from MB above us */
169 return cur_mb
->bmi
+ b
- 4;