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 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}
21 /* Predict motion vectors using those from already-decoded nearby blocks.
22 Note that we only consider one 4x4 subblock from each candidate 16x16
24 void vp8_find_near_mvs
27 const MODE_INFO
*here
,
33 int *ref_frame_sign_bias
36 const MODE_INFO
*above
= here
- xd
->mode_info_stride
;
37 const MODE_INFO
*left
= here
- 1;
38 const MODE_INFO
*aboveleft
= above
- 1;
40 int_mv
*mv
= near_mvs
;
42 enum {CNT_INTRA
, CNT_NEAREST
, CNT_NEAR
, CNT_SPLITMV
};
44 /* Zero accumulators */
45 mv
[0].as_int
= mv
[1].as_int
= mv
[2].as_int
= 0;
46 cnt
[0] = cnt
[1] = cnt
[2] = cnt
[3] = 0;
49 if (above
->mbmi
.ref_frame
!= INTRA_FRAME
)
51 if (above
->mbmi
.mv
.as_int
)
53 (++mv
)->as_int
= above
->mbmi
.mv
.as_int
;
54 mv_bias(ref_frame_sign_bias
[above
->mbmi
.ref_frame
], refframe
, mv
, ref_frame_sign_bias
);
62 if (left
->mbmi
.ref_frame
!= INTRA_FRAME
)
64 if (left
->mbmi
.mv
.as_int
)
68 this_mv
.as_int
= left
->mbmi
.mv
.as_int
;
69 mv_bias(ref_frame_sign_bias
[left
->mbmi
.ref_frame
], refframe
, &this_mv
, ref_frame_sign_bias
);
71 if (this_mv
.as_int
!= mv
->as_int
)
73 (++mv
)->as_int
= this_mv
.as_int
;
83 /* Process above left */
84 if (aboveleft
->mbmi
.ref_frame
!= INTRA_FRAME
)
86 if (aboveleft
->mbmi
.mv
.as_int
)
90 this_mv
.as_int
= aboveleft
->mbmi
.mv
.as_int
;
91 mv_bias(ref_frame_sign_bias
[aboveleft
->mbmi
.ref_frame
], refframe
, &this_mv
, ref_frame_sign_bias
);
93 if (this_mv
.as_int
!= mv
->as_int
)
95 (++mv
)->as_int
= this_mv
.as_int
;
105 /* If we have three distinct MV's ... */
106 if (cnt
[CNT_SPLITMV
])
108 /* See if above-left MV can be merged with NEAREST */
109 if (mv
->as_int
== near_mvs
[CNT_NEAREST
].as_int
)
110 cnt
[CNT_NEAREST
] += 1;
113 cnt
[CNT_SPLITMV
] = ((above
->mbmi
.mode
== SPLITMV
)
114 + (left
->mbmi
.mode
== SPLITMV
)) * 2
115 + (aboveleft
->mbmi
.mode
== SPLITMV
);
117 /* Swap near and nearest if necessary */
118 if (cnt
[CNT_NEAR
] > cnt
[CNT_NEAREST
])
121 tmp
= cnt
[CNT_NEAREST
];
122 cnt
[CNT_NEAREST
] = cnt
[CNT_NEAR
];
124 tmp
= near_mvs
[CNT_NEAREST
].as_int
;
125 near_mvs
[CNT_NEAREST
].as_int
= near_mvs
[CNT_NEAR
].as_int
;
126 near_mvs
[CNT_NEAR
].as_int
= tmp
;
129 /* Use near_mvs[0] to store the "best" MV */
130 if (cnt
[CNT_NEAREST
] >= cnt
[CNT_INTRA
])
131 near_mvs
[CNT_INTRA
] = near_mvs
[CNT_NEAREST
];
133 /* Set up return values */
134 best_mv
->as_int
= near_mvs
[0].as_int
;
135 nearest
->as_int
= near_mvs
[CNT_NEAREST
].as_int
;
136 nearby
->as_int
= near_mvs
[CNT_NEAR
].as_int
;
138 //TODO: move clamp outside findnearmv
139 vp8_clamp_mv2(nearest
, xd
);
140 vp8_clamp_mv2(nearby
, xd
);
141 vp8_clamp_mv2(best_mv
, xd
);
144 vp8_prob
*vp8_mv_ref_probs(
145 vp8_prob p
[VP8_MVREFS
-1], const int near_mv_ref_ct
[4]
148 p
[0] = vp8_mode_contexts
[near_mv_ref_ct
[0]] [0];
149 p
[1] = vp8_mode_contexts
[near_mv_ref_ct
[1]] [1];
150 p
[2] = vp8_mode_contexts
[near_mv_ref_ct
[2]] [2];
151 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];*/