OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 | 11 |
12 #include "vp9/common/vp9_findnearmv.h" | 12 #include "vp9/common/vp9_findnearmv.h" |
13 #include "vp9/common/vp9_sadmxn.h" | 13 #include "vp9/common/vp9_sadmxn.h" |
14 #include "vp9/common/vp9_subpelvar.h" | 14 #include "vp9/common/vp9_subpelvar.h" |
15 #include <limits.h> | 15 #include <limits.h> |
16 | 16 |
17 const unsigned char vp9_mbsplit_offset[4][16] = { | 17 const uint8_t vp9_mbsplit_offset[4][16] = { |
18 { 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | 18 { 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
19 { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | 19 { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
20 { 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | 20 { 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
21 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} | 21 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} |
22 }; | 22 }; |
23 | 23 |
24 static void lower_mv_precision(int_mv *mv, int usehp) | 24 static void lower_mv_precision(int_mv *mv, int usehp) |
25 { | 25 { |
26 if (!usehp || !vp9_use_nmv_hp(&mv->as_mv)) { | 26 if (!usehp || !vp9_use_nmv_hp(&mv->as_mv)) { |
27 if (mv->as_mv.row & 1) | 27 if (mv->as_mv.row & 1) |
28 mv->as_mv.row += (mv->as_mv.row > 0 ? -1 : 1); | 28 mv->as_mv.row += (mv->as_mv.row > 0 ? -1 : 1); |
29 if (mv->as_mv.col & 1) | 29 if (mv->as_mv.col & 1) |
30 mv->as_mv.col += (mv->as_mv.col > 0 ? -1 : 1); | 30 mv->as_mv.col += (mv->as_mv.col > 0 ? -1 : 1); |
31 } | 31 } |
32 } | 32 } |
33 | 33 |
34 vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, | 34 vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, |
35 vp9_prob p[4], const int context | 35 vp9_prob p[4], const int context |
36 ) { | 36 ) { |
37 p[0] = pc->fc.vp9_mode_contexts[context][0]; | 37 p[0] = pc->fc.vp9_mode_contexts[context][0]; |
38 p[1] = pc->fc.vp9_mode_contexts[context][1]; | 38 p[1] = pc->fc.vp9_mode_contexts[context][1]; |
39 p[2] = pc->fc.vp9_mode_contexts[context][2]; | 39 p[2] = pc->fc.vp9_mode_contexts[context][2]; |
40 p[3] = pc->fc.vp9_mode_contexts[context][3]; | 40 p[3] = pc->fc.vp9_mode_contexts[context][3]; |
41 return p; | 41 return p; |
42 } | 42 } |
43 | 43 |
44 #define SP(x) (((x) & 7) << 1) | 44 #define SP(x) (((x) & 7) << 1) |
45 unsigned int vp9_sad3x16_c(const unsigned char *src_ptr, | 45 unsigned int vp9_sad3x16_c(const uint8_t *src_ptr, |
46 int src_stride, | 46 int src_stride, |
47 const unsigned char *ref_ptr, | 47 const uint8_t *ref_ptr, |
48 int ref_stride) { | 48 int ref_stride) { |
49 return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 3, 16); | 49 return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 3, 16); |
50 } | 50 } |
51 unsigned int vp9_sad16x3_c(const unsigned char *src_ptr, | 51 unsigned int vp9_sad16x3_c(const uint8_t *src_ptr, |
52 int src_stride, | 52 int src_stride, |
53 const unsigned char *ref_ptr, | 53 const uint8_t *ref_ptr, |
54 int ref_stride) { | 54 int ref_stride) { |
55 return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 16, 3); | 55 return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 16, 3); |
56 } | 56 } |
57 | 57 |
58 #if CONFIG_SUBPELREFMV | 58 |
59 unsigned int vp9_variance2x16_c(const unsigned char *src_ptr, | 59 unsigned int vp9_variance2x16_c(const uint8_t *src_ptr, |
60 const int source_stride, | 60 const int source_stride, |
61 const unsigned char *ref_ptr, | 61 const uint8_t *ref_ptr, |
62 const int recon_stride, | 62 const int recon_stride, |
63 unsigned int *sse) { | 63 unsigned int *sse) { |
64 int sum; | 64 int sum; |
65 variance(src_ptr, source_stride, ref_ptr, recon_stride, 2, 16, sse, &sum); | 65 variance(src_ptr, source_stride, ref_ptr, recon_stride, 2, 16, sse, &sum); |
66 return (*sse - (((unsigned int)sum * sum) >> 5)); | 66 return (*sse - (((unsigned int)sum * sum) >> 5)); |
67 } | 67 } |
68 | 68 |
69 unsigned int vp9_variance16x2_c(const unsigned char *src_ptr, | 69 unsigned int vp9_variance16x2_c(const uint8_t *src_ptr, |
70 const int source_stride, | 70 const int source_stride, |
71 const unsigned char *ref_ptr, | 71 const uint8_t *ref_ptr, |
72 const int recon_stride, | 72 const int recon_stride, |
73 unsigned int *sse) { | 73 unsigned int *sse) { |
74 int sum; | 74 int sum; |
75 variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 2, sse, &sum); | 75 variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 2, sse, &sum); |
76 return (*sse - (((unsigned int)sum * sum) >> 5)); | 76 return (*sse - (((unsigned int)sum * sum) >> 5)); |
77 } | 77 } |
78 | 78 |
79 unsigned int vp9_sub_pixel_variance16x2_c(const unsigned char *src_ptr, | 79 unsigned int vp9_sub_pixel_variance16x2_c(const uint8_t *src_ptr, |
80 const int src_pixels_per_line, | 80 const int src_pixels_per_line, |
81 const int xoffset, | 81 const int xoffset, |
82 const int yoffset, | 82 const int yoffset, |
83 const unsigned char *dst_ptr, | 83 const uint8_t *dst_ptr, |
84 const int dst_pixels_per_line, | 84 const int dst_pixels_per_line, |
85 unsigned int *sse) { | 85 unsigned int *sse) { |
86 unsigned short FData3[16 * 3]; // Temp data buffer used in filtering | 86 uint16_t FData3[16 * 3]; // Temp data buffer used in filtering |
87 unsigned char temp2[2 * 16]; | 87 uint8_t temp2[2 * 16]; |
88 const short *HFilter, *VFilter; | 88 const int16_t *HFilter, *VFilter; |
89 | 89 |
90 HFilter = vp9_bilinear_filters[xoffset]; | 90 HFilter = vp9_bilinear_filters[xoffset]; |
91 VFilter = vp9_bilinear_filters[yoffset]; | 91 VFilter = vp9_bilinear_filters[yoffset]; |
92 | 92 |
93 var_filter_block2d_bil_first_pass(src_ptr, FData3, | 93 var_filter_block2d_bil_first_pass(src_ptr, FData3, |
94 src_pixels_per_line, 1, 3, 16, HFilter); | 94 src_pixels_per_line, 1, 3, 16, HFilter); |
95 var_filter_block2d_bil_second_pass(FData3, temp2, 16, 16, 2, 16, VFilter); | 95 var_filter_block2d_bil_second_pass(FData3, temp2, 16, 16, 2, 16, VFilter); |
96 | 96 |
97 return vp9_variance16x2_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse); | 97 return vp9_variance16x2_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse); |
98 } | 98 } |
99 | 99 |
100 unsigned int vp9_sub_pixel_variance2x16_c(const unsigned char *src_ptr, | 100 unsigned int vp9_sub_pixel_variance2x16_c(const uint8_t *src_ptr, |
101 const int src_pixels_per_line, | 101 const int src_pixels_per_line, |
102 const int xoffset, | 102 const int xoffset, |
103 const int yoffset, | 103 const int yoffset, |
104 const unsigned char *dst_ptr, | 104 const uint8_t *dst_ptr, |
105 const int dst_pixels_per_line, | 105 const int dst_pixels_per_line, |
106 unsigned int *sse) { | 106 unsigned int *sse) { |
107 unsigned short FData3[2 * 17]; // Temp data buffer used in filtering | 107 uint16_t FData3[2 * 17]; // Temp data buffer used in filtering |
108 unsigned char temp2[2 * 16]; | 108 uint8_t temp2[2 * 16]; |
109 const short *HFilter, *VFilter; | 109 const int16_t *HFilter, *VFilter; |
110 | 110 |
111 HFilter = vp9_bilinear_filters[xoffset]; | 111 HFilter = vp9_bilinear_filters[xoffset]; |
112 VFilter = vp9_bilinear_filters[yoffset]; | 112 VFilter = vp9_bilinear_filters[yoffset]; |
113 | 113 |
114 var_filter_block2d_bil_first_pass(src_ptr, FData3, | 114 var_filter_block2d_bil_first_pass(src_ptr, FData3, |
115 src_pixels_per_line, 1, 17, 2, HFilter); | 115 src_pixels_per_line, 1, 17, 2, HFilter); |
116 var_filter_block2d_bil_second_pass(FData3, temp2, 2, 2, 16, 2, VFilter); | 116 var_filter_block2d_bil_second_pass(FData3, temp2, 2, 2, 16, 2, VFilter); |
117 | 117 |
118 return vp9_variance2x16_c(temp2, 2, dst_ptr, dst_pixels_per_line, sse); | 118 return vp9_variance2x16_c(temp2, 2, dst_ptr, dst_pixels_per_line, sse); |
119 } | 119 } |
120 #endif | |
121 | 120 |
122 /* check a list of motion vectors by sad score using a number rows of pixels | 121 /* check a list of motion vectors by sad score using a number rows of pixels |
123 * above and a number cols of pixels in the left to select the one with best | 122 * above and a number cols of pixels in the left to select the one with best |
124 * score to use as ref motion vector | 123 * score to use as ref motion vector |
125 */ | 124 */ |
126 void vp9_find_best_ref_mvs(MACROBLOCKD *xd, | 125 void vp9_find_best_ref_mvs(MACROBLOCKD *xd, |
127 unsigned char *ref_y_buffer, | 126 uint8_t *ref_y_buffer, |
128 int ref_y_stride, | 127 int ref_y_stride, |
129 int_mv *mvlist, | 128 int_mv *mvlist, |
130 int_mv *best_mv, | |
131 int_mv *nearest, | 129 int_mv *nearest, |
132 int_mv *near) { | 130 int_mv *near) { |
133 int i, j; | 131 int i, j; |
134 unsigned char *above_src; | 132 uint8_t *above_src; |
135 unsigned char *left_src; | 133 uint8_t *above_ref; |
136 unsigned char *above_ref; | 134 #if !CONFIG_ABOVESPREFMV |
137 unsigned char *left_ref; | 135 uint8_t *left_src; |
| 136 uint8_t *left_ref; |
| 137 #endif |
138 unsigned int score; | 138 unsigned int score; |
139 #if CONFIG_SUBPELREFMV | |
140 unsigned int sse; | 139 unsigned int sse; |
141 #endif | 140 unsigned int ref_scores[MAX_MV_REF_CANDIDATES] = {0}; |
142 unsigned int ref_scores[MAX_MV_REFS] = {0}; | 141 int_mv sorted_mvs[MAX_MV_REF_CANDIDATES]; |
143 int_mv sorted_mvs[MAX_MV_REFS]; | |
144 int zero_seen = FALSE; | 142 int zero_seen = FALSE; |
145 | 143 |
146 // Default all to 0,0 if nothing else available | 144 // Default all to 0,0 if nothing else available |
147 best_mv->as_int = nearest->as_int = near->as_int = 0; | 145 nearest->as_int = near->as_int = 0; |
148 vpx_memset(sorted_mvs, 0, sizeof(sorted_mvs)); | 146 vpx_memset(sorted_mvs, 0, sizeof(sorted_mvs)); |
149 | 147 |
150 #if CONFIG_SUBPELREFMV | |
151 above_src = xd->dst.y_buffer - xd->dst.y_stride * 2; | 148 above_src = xd->dst.y_buffer - xd->dst.y_stride * 2; |
| 149 above_ref = ref_y_buffer - ref_y_stride * 2; |
| 150 #if CONFIG_ABOVESPREFMV |
| 151 above_src -= 4; |
| 152 above_ref -= 4; |
| 153 #else |
152 left_src = xd->dst.y_buffer - 2; | 154 left_src = xd->dst.y_buffer - 2; |
153 above_ref = ref_y_buffer - ref_y_stride * 2; | |
154 left_ref = ref_y_buffer - 2; | 155 left_ref = ref_y_buffer - 2; |
155 #else | |
156 above_src = xd->dst.y_buffer - xd->dst.y_stride * 3; | |
157 left_src = xd->dst.y_buffer - 3; | |
158 above_ref = ref_y_buffer - ref_y_stride * 3; | |
159 left_ref = ref_y_buffer - 3; | |
160 #endif | 156 #endif |
161 | 157 |
162 //for(i = 0; i < MAX_MV_REFS; ++i) { | 158 // Limit search to the predicted best few candidates |
163 // Limit search to the predicted best 4 | 159 for(i = 0; i < MAX_MV_REF_CANDIDATES; ++i) { |
164 for(i = 0; i < 4; ++i) { | |
165 int_mv this_mv; | 160 int_mv this_mv; |
166 int offset = 0; | 161 int offset = 0; |
167 int row_offset, col_offset; | 162 int row_offset, col_offset; |
168 | 163 |
169 this_mv.as_int = mvlist[i].as_int; | 164 this_mv.as_int = mvlist[i].as_int; |
170 | 165 |
171 // If we see a 0,0 vector for a second time we have reached the end of | 166 // If we see a 0,0 vector for a second time we have reached the end of |
172 // the list of valid candidate vectors. | 167 // the list of valid candidate vectors. |
173 if (!this_mv.as_int && zero_seen) | 168 if (!this_mv.as_int && zero_seen) |
174 break; | 169 break; |
175 | 170 |
176 zero_seen = zero_seen || !this_mv.as_int; | 171 zero_seen = zero_seen || !this_mv.as_int; |
177 | 172 |
| 173 #if !CONFIG_ABOVESPREFMV |
178 clamp_mv(&this_mv, | 174 clamp_mv(&this_mv, |
179 xd->mb_to_left_edge - LEFT_TOP_MARGIN + 24, | 175 xd->mb_to_left_edge - LEFT_TOP_MARGIN + 24, |
180 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN, | 176 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN, |
181 xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24, | 177 xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24, |
182 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); | 178 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); |
| 179 #else |
| 180 clamp_mv(&this_mv, |
| 181 xd->mb_to_left_edge - LEFT_TOP_MARGIN + 32, |
| 182 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN, |
| 183 xd->mb_to_top_edge - LEFT_TOP_MARGIN + 24, |
| 184 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); |
| 185 #endif |
183 | 186 |
184 #if CONFIG_SUBPELREFMV | |
185 row_offset = this_mv.as_mv.row >> 3; | 187 row_offset = this_mv.as_mv.row >> 3; |
186 col_offset = this_mv.as_mv.col >> 3; | 188 col_offset = this_mv.as_mv.col >> 3; |
187 offset = ref_y_stride * row_offset + col_offset; | 189 offset = ref_y_stride * row_offset + col_offset; |
188 score = 0; | 190 score = 0; |
189 if (xd->up_available) { | 191 if (xd->up_available) { |
190 vp9_sub_pixel_variance16x2_c(above_ref + offset, ref_y_stride, | 192 vp9_sub_pixel_variance16x2(above_ref + offset, ref_y_stride, |
| 193 SP(this_mv.as_mv.col), |
| 194 SP(this_mv.as_mv.row), |
| 195 above_src, xd->dst.y_stride, &sse); |
| 196 score += sse; |
| 197 if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB32X32) { |
| 198 vp9_sub_pixel_variance16x2(above_ref + offset + 16, |
| 199 ref_y_stride, |
191 SP(this_mv.as_mv.col), | 200 SP(this_mv.as_mv.col), |
192 SP(this_mv.as_mv.row), | 201 SP(this_mv.as_mv.row), |
193 above_src, xd->dst.y_stride, &sse); | 202 above_src + 16, xd->dst.y_stride, &sse); |
194 score += sse; | |
195 #if CONFIG_SUPERBLOCKS | |
196 if (xd->mode_info_context->mbmi.encoded_as_sb) { | |
197 vp9_sub_pixel_variance16x2_c(above_ref + offset + 16, | |
198 ref_y_stride, | |
199 SP(this_mv.as_mv.col), | |
200 SP(this_mv.as_mv.row), | |
201 above_src + 16, xd->dst.y_stride, &sse); | |
202 score += sse; | 203 score += sse; |
203 } | 204 } |
204 #endif | 205 if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB64X64) { |
| 206 vp9_sub_pixel_variance16x2(above_ref + offset + 32, |
| 207 ref_y_stride, |
| 208 SP(this_mv.as_mv.col), |
| 209 SP(this_mv.as_mv.row), |
| 210 above_src + 32, xd->dst.y_stride, &sse); |
| 211 score += sse; |
| 212 vp9_sub_pixel_variance16x2(above_ref + offset + 48, |
| 213 ref_y_stride, |
| 214 SP(this_mv.as_mv.col), |
| 215 SP(this_mv.as_mv.row), |
| 216 above_src + 48, xd->dst.y_stride, &sse); |
| 217 score += sse; |
| 218 } |
205 } | 219 } |
| 220 #if !CONFIG_ABOVESPREFMV |
206 if (xd->left_available) { | 221 if (xd->left_available) { |
207 vp9_sub_pixel_variance2x16_c(left_ref + offset, ref_y_stride, | 222 vp9_sub_pixel_variance2x16_c(left_ref + offset, ref_y_stride, |
208 SP(this_mv.as_mv.col), | 223 SP(this_mv.as_mv.col), |
209 SP(this_mv.as_mv.row), | 224 SP(this_mv.as_mv.row), |
210 left_src, xd->dst.y_stride, &sse); | 225 left_src, xd->dst.y_stride, &sse); |
211 score += sse; | 226 score += sse; |
212 #if CONFIG_SUPERBLOCKS | 227 if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB32X32) { |
213 if (xd->mode_info_context->mbmi.encoded_as_sb) { | |
214 vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 16, | 228 vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 16, |
215 ref_y_stride, | 229 ref_y_stride, |
216 SP(this_mv.as_mv.col), | 230 SP(this_mv.as_mv.col), |
217 SP(this_mv.as_mv.row), | 231 SP(this_mv.as_mv.row), |
218 left_src + xd->dst.y_stride * 16, | 232 left_src + xd->dst.y_stride * 16, |
219 xd->dst.y_stride, &sse); | 233 xd->dst.y_stride, &sse); |
220 score += sse; | 234 score += sse; |
221 } | 235 } |
222 #endif | 236 if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB64X64) { |
223 } | 237 vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 32, |
224 #else | 238 ref_y_stride, |
225 row_offset = (this_mv.as_mv.row > 0) ? | 239 SP(this_mv.as_mv.col), |
226 ((this_mv.as_mv.row + 3) >> 3):((this_mv.as_mv.row + 4) >> 3); | 240 SP(this_mv.as_mv.row), |
227 col_offset = (this_mv.as_mv.col > 0) ? | 241 left_src + xd->dst.y_stride * 32, |
228 ((this_mv.as_mv.col + 3) >> 3):((this_mv.as_mv.col + 4) >> 3); | 242 xd->dst.y_stride, &sse); |
229 offset = ref_y_stride * row_offset + col_offset; | 243 score += sse; |
230 score = 0; | 244 vp9_sub_pixel_variance2x16_c(left_ref + offset + ref_y_stride * 48, |
231 if (xd->up_available) { | 245 ref_y_stride, |
232 score += vp9_sad16x3(above_src, xd->dst.y_stride, | 246 SP(this_mv.as_mv.col), |
233 above_ref + offset, ref_y_stride); | 247 SP(this_mv.as_mv.row), |
234 #if CONFIG_SUPERBLOCKS | 248 left_src + xd->dst.y_stride * 48, |
235 if (xd->mode_info_context->mbmi.encoded_as_sb) { | 249 xd->dst.y_stride, &sse); |
236 score += vp9_sad16x3(above_src + 16, xd->dst.y_stride, | 250 score += sse; |
237 above_ref + offset + 16, ref_y_stride); | |
238 } | 251 } |
239 #endif | |
240 } | |
241 if (xd->left_available) { | |
242 score += vp9_sad3x16(left_src, xd->dst.y_stride, | |
243 left_ref + offset, ref_y_stride); | |
244 #if CONFIG_SUPERBLOCKS | |
245 if (xd->mode_info_context->mbmi.encoded_as_sb) { | |
246 score += vp9_sad3x16(left_src + xd->dst.y_stride * 16, | |
247 xd->dst.y_stride, | |
248 left_ref + offset + ref_y_stride * 16, | |
249 ref_y_stride); | |
250 } | |
251 #endif | |
252 } | 252 } |
253 #endif | 253 #endif |
254 // Add the entry to our list and then resort the list on score. | 254 // Add the entry to our list and then resort the list on score. |
255 ref_scores[i] = score; | 255 ref_scores[i] = score; |
256 sorted_mvs[i].as_int = this_mv.as_int; | 256 sorted_mvs[i].as_int = this_mv.as_int; |
257 j = i; | 257 j = i; |
258 while (j > 0) { | 258 while (j > 0) { |
259 if (ref_scores[j] < ref_scores[j-1]) { | 259 if (ref_scores[j] < ref_scores[j-1]) { |
260 ref_scores[j] = ref_scores[j-1]; | 260 ref_scores[j] = ref_scores[j-1]; |
261 sorted_mvs[j].as_int = sorted_mvs[j-1].as_int; | 261 sorted_mvs[j].as_int = sorted_mvs[j-1].as_int; |
262 ref_scores[j-1] = score; | 262 ref_scores[j-1] = score; |
263 sorted_mvs[j-1].as_int = this_mv.as_int; | 263 sorted_mvs[j-1].as_int = this_mv.as_int; |
264 j--; | 264 j--; |
265 } else | 265 } else |
266 break; | 266 break; |
267 } | 267 } |
268 } | 268 } |
269 | 269 |
270 // Make sure all the candidates are properly clamped etc | 270 // Make sure all the candidates are properly clamped etc |
271 for (i = 0; i < 4; ++i) { | 271 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) { |
272 lower_mv_precision(&sorted_mvs[i], xd->allow_high_precision_mv); | 272 lower_mv_precision(&sorted_mvs[i], xd->allow_high_precision_mv); |
273 clamp_mv2(&sorted_mvs[i], xd); | 273 clamp_mv2(&sorted_mvs[i], xd); |
274 } | 274 } |
275 | 275 |
276 // Set the best mv to the first entry in the sorted list | |
277 best_mv->as_int = sorted_mvs[0].as_int; | |
278 | |
279 // Provided that there are non zero vectors available there will not | 276 // Provided that there are non zero vectors available there will not |
280 // be more than one 0,0 entry in the sorted list. | 277 // be more than one 0,0 entry in the sorted list. |
281 // The best ref mv is always set to the first entry (which gave the best | 278 // The best ref mv is always set to the first entry (which gave the best |
282 // results. The nearest is set to the first non zero vector if available and | 279 // results. The nearest is set to the first non zero vector if available and |
283 // near to the second non zero vector if available. | 280 // near to the second non zero vector if available. |
284 // We do not use 0,0 as a nearest or near as 0,0 has its own mode. | 281 // We do not use 0,0 as a nearest or near as 0,0 has its own mode. |
285 if ( sorted_mvs[0].as_int ) { | 282 if ( sorted_mvs[0].as_int ) { |
286 nearest->as_int = sorted_mvs[0].as_int; | 283 nearest->as_int = sorted_mvs[0].as_int; |
287 if ( sorted_mvs[1].as_int ) | 284 if ( sorted_mvs[1].as_int ) |
288 near->as_int = sorted_mvs[1].as_int; | 285 near->as_int = sorted_mvs[1].as_int; |
289 else | 286 else |
290 near->as_int = sorted_mvs[2].as_int; | 287 near->as_int = sorted_mvs[2].as_int; |
291 } else { | 288 } else { |
292 nearest->as_int = sorted_mvs[1].as_int; | 289 nearest->as_int = sorted_mvs[1].as_int; |
293 near->as_int = sorted_mvs[2].as_int; | 290 near->as_int = sorted_mvs[2].as_int; |
294 } | 291 } |
295 | 292 |
296 // Copy back the re-ordered mv list | 293 // Copy back the re-ordered mv list |
297 vpx_memcpy(mvlist, sorted_mvs, sizeof(sorted_mvs)); | 294 vpx_memcpy(mvlist, sorted_mvs, sizeof(sorted_mvs)); |
298 } | 295 } |
OLD | NEW |