Merge "Detect toolchain based on gcc -dumpmachine"
[profile/ivi/libvpx.git] / vp8 / common / reconinter.c
1 /*
2  *  Copyright (c) 2010 The VP8 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 "vpx_ports/config.h"
13 #include "recon.h"
14 #include "subpixel.h"
15 #include "blockd.h"
16 #include "reconinter.h"
17 #if CONFIG_RUNTIME_CPU_DETECT
18 #include "onyxc_int.h"
19 #endif
20
21 // use this define on systems where unaligned int reads and writes are
22 // not allowed, i.e. ARM architectures
23 //#define MUST_BE_ALIGNED
24
25
26 static const int bbb[4] = {0, 2, 8, 10};
27
28
29
30 void vp8_copy_mem16x16_c(
31     unsigned char *src,
32     int src_stride,
33     unsigned char *dst,
34     int dst_stride)
35 {
36
37     int r;
38
39     for (r = 0; r < 16; r++)
40     {
41 #ifdef MUST_BE_ALIGNED
42         dst[0] = src[0];
43         dst[1] = src[1];
44         dst[2] = src[2];
45         dst[3] = src[3];
46         dst[4] = src[4];
47         dst[5] = src[5];
48         dst[6] = src[6];
49         dst[7] = src[7];
50         dst[8] = src[8];
51         dst[9] = src[9];
52         dst[10] = src[10];
53         dst[11] = src[11];
54         dst[12] = src[12];
55         dst[13] = src[13];
56         dst[14] = src[14];
57         dst[15] = src[15];
58
59 #else
60         ((int *)dst)[0] = ((int *)src)[0] ;
61         ((int *)dst)[1] = ((int *)src)[1] ;
62         ((int *)dst)[2] = ((int *)src)[2] ;
63         ((int *)dst)[3] = ((int *)src)[3] ;
64
65 #endif
66         src += src_stride;
67         dst += dst_stride;
68
69     }
70
71 }
72
73 void vp8_copy_mem8x8_c(
74     unsigned char *src,
75     int src_stride,
76     unsigned char *dst,
77     int dst_stride)
78 {
79     int r;
80
81     for (r = 0; r < 8; r++)
82     {
83 #ifdef MUST_BE_ALIGNED
84         dst[0] = src[0];
85         dst[1] = src[1];
86         dst[2] = src[2];
87         dst[3] = src[3];
88         dst[4] = src[4];
89         dst[5] = src[5];
90         dst[6] = src[6];
91         dst[7] = src[7];
92 #else
93         ((int *)dst)[0] = ((int *)src)[0] ;
94         ((int *)dst)[1] = ((int *)src)[1] ;
95 #endif
96         src += src_stride;
97         dst += dst_stride;
98
99     }
100
101 }
102
103 void vp8_copy_mem8x4_c(
104     unsigned char *src,
105     int src_stride,
106     unsigned char *dst,
107     int dst_stride)
108 {
109     int r;
110
111     for (r = 0; r < 4; r++)
112     {
113 #ifdef MUST_BE_ALIGNED
114         dst[0] = src[0];
115         dst[1] = src[1];
116         dst[2] = src[2];
117         dst[3] = src[3];
118         dst[4] = src[4];
119         dst[5] = src[5];
120         dst[6] = src[6];
121         dst[7] = src[7];
122 #else
123         ((int *)dst)[0] = ((int *)src)[0] ;
124         ((int *)dst)[1] = ((int *)src)[1] ;
125 #endif
126         src += src_stride;
127         dst += dst_stride;
128
129     }
130
131 }
132
133
134
135 void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf)
136 {
137     int r;
138     unsigned char *ptr_base;
139     unsigned char *ptr;
140     unsigned char *pred_ptr = d->predictor;
141
142     ptr_base = *(d->base_pre);
143
144     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
145     {
146         ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
147         sppf(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
148     }
149     else
150     {
151         ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
152         ptr = ptr_base;
153
154         for (r = 0; r < 4; r++)
155         {
156 #ifdef MUST_BE_ALIGNED
157             pred_ptr[0]  = ptr[0];
158             pred_ptr[1]  = ptr[1];
159             pred_ptr[2]  = ptr[2];
160             pred_ptr[3]  = ptr[3];
161 #else
162             *(int *)pred_ptr = *(int *)ptr ;
163 #endif
164             pred_ptr     += pitch;
165             ptr         += d->pre_stride;
166         }
167     }
168 }
169
170 void vp8_build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, int pitch)
171 {
172     unsigned char *ptr_base;
173     unsigned char *ptr;
174     unsigned char *pred_ptr = d->predictor;
175
176     ptr_base = *(d->base_pre);
177     ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
178
179     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
180     {
181         x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
182     }
183     else
184     {
185         RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, pred_ptr, pitch);
186     }
187 }
188
189 void vp8_build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, int pitch)
190 {
191     unsigned char *ptr_base;
192     unsigned char *ptr;
193     unsigned char *pred_ptr = d->predictor;
194
195     ptr_base = *(d->base_pre);
196     ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
197
198     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
199     {
200         x->subpixel_predict8x4(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
201     }
202     else
203     {
204         RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d->pre_stride, pred_ptr, pitch);
205     }
206 }
207
208
209 void vp8_build_inter_predictors_mbuv(MACROBLOCKD *x)
210 {
211     int i;
212
213     if (x->mbmi.ref_frame != INTRA_FRAME && x->mbmi.mode != SPLITMV)
214     {
215         unsigned char *uptr, *vptr;
216         unsigned char *upred_ptr = &x->predictor[256];
217         unsigned char *vpred_ptr = &x->predictor[320];
218
219         int mv_row = x->block[16].bmi.mv.as_mv.row;
220         int mv_col = x->block[16].bmi.mv.as_mv.col;
221         int offset;
222         int pre_stride = x->block[16].pre_stride;
223
224         offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
225         uptr = x->pre.u_buffer + offset;
226         vptr = x->pre.v_buffer + offset;
227
228         if ((mv_row | mv_col) & 7)
229         {
230             x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
231             x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
232         }
233         else
234         {
235             RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
236             RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
237         }
238     }
239     else
240     {
241         for (i = 16; i < 24; i += 2)
242         {
243             BLOCKD *d0 = &x->block[i];
244             BLOCKD *d1 = &x->block[i+1];
245
246             if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
247                 vp8_build_inter_predictors2b(x, d0, 8);
248             else
249             {
250                 vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
251                 vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
252             }
253         }
254     }
255 }
256
257
258 void vp8_build_inter_predictors_mby(MACROBLOCKD *x)
259 {
260     if (x->mbmi.ref_frame != INTRA_FRAME && x->mbmi.mode != SPLITMV)
261     {
262         unsigned char *ptr_base;
263         unsigned char *ptr;
264         unsigned char *pred_ptr = x->predictor;
265         int mv_row = x->mbmi.mv.as_mv.row;
266         int mv_col = x->mbmi.mv.as_mv.col;
267         int pre_stride = x->block[0].pre_stride;
268
269         ptr_base = x->pre.y_buffer;
270         ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
271
272         if ((mv_row | mv_col) & 7)
273         {
274             x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
275         }
276         else
277         {
278             RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
279         }
280     }
281     else
282     {
283         int i;
284
285         if (x->mbmi.partitioning < 3)
286         {
287             for (i = 0; i < 4; i++)
288             {
289                 BLOCKD *d = &x->block[bbb[i]];
290                 vp8_build_inter_predictors4b(x, d, 16);
291             }
292
293         }
294         else
295         {
296             for (i = 0; i < 16; i += 2)
297             {
298                 BLOCKD *d0 = &x->block[i];
299                 BLOCKD *d1 = &x->block[i+1];
300
301                 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
302                     vp8_build_inter_predictors2b(x, d0, 16);
303                 else
304                 {
305                     vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
306                     vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
307                 }
308
309             }
310         }
311     }
312 }
313
314 void vp8_build_inter_predictors_mb(MACROBLOCKD *x)
315 {
316     if (x->mbmi.ref_frame != INTRA_FRAME && x->mbmi.mode != SPLITMV)
317     {
318         int offset;
319         unsigned char *ptr_base;
320         unsigned char *ptr;
321         unsigned char *uptr, *vptr;
322         unsigned char *pred_ptr = x->predictor;
323         unsigned char *upred_ptr = &x->predictor[256];
324         unsigned char *vpred_ptr = &x->predictor[320];
325
326         int mv_row = x->mbmi.mv.as_mv.row;
327         int mv_col = x->mbmi.mv.as_mv.col;
328         int pre_stride = x->block[0].pre_stride;
329
330         ptr_base = x->pre.y_buffer;
331         ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
332
333         if ((mv_row | mv_col) & 7)
334         {
335             x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
336         }
337         else
338         {
339             RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
340         }
341
342         mv_row = x->block[16].bmi.mv.as_mv.row;
343         mv_col = x->block[16].bmi.mv.as_mv.col;
344         pre_stride >>= 1;
345         offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
346         uptr = x->pre.u_buffer + offset;
347         vptr = x->pre.v_buffer + offset;
348
349         if ((mv_row | mv_col) & 7)
350         {
351             x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
352             x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
353         }
354         else
355         {
356             RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
357             RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
358         }
359     }
360     else
361     {
362         int i;
363
364         if (x->mbmi.partitioning < 3)
365         {
366             for (i = 0; i < 4; i++)
367             {
368                 BLOCKD *d = &x->block[bbb[i]];
369                 vp8_build_inter_predictors4b(x, d, 16);
370             }
371         }
372         else
373         {
374             for (i = 0; i < 16; i += 2)
375             {
376                 BLOCKD *d0 = &x->block[i];
377                 BLOCKD *d1 = &x->block[i+1];
378
379                 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
380                     vp8_build_inter_predictors2b(x, d0, 16);
381                 else
382                 {
383                     vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
384                     vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
385                 }
386
387             }
388
389         }
390
391         for (i = 16; i < 24; i += 2)
392         {
393             BLOCKD *d0 = &x->block[i];
394             BLOCKD *d1 = &x->block[i+1];
395
396             if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
397                 vp8_build_inter_predictors2b(x, d0, 8);
398             else
399             {
400                 vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
401                 vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
402             }
403
404         }
405
406     }
407 }
408
409 void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel)
410 {
411     int i, j;
412
413     if (x->mbmi.mode == SPLITMV)
414     {
415         for (i = 0; i < 2; i++)
416         {
417             for (j = 0; j < 2; j++)
418             {
419                 int yoffset = i * 8 + j * 2;
420                 int uoffset = 16 + i * 2 + j;
421                 int voffset = 20 + i * 2 + j;
422
423                 int temp;
424
425                 temp = x->block[yoffset  ].bmi.mv.as_mv.row
426                        + x->block[yoffset+1].bmi.mv.as_mv.row
427                        + x->block[yoffset+4].bmi.mv.as_mv.row
428                        + x->block[yoffset+5].bmi.mv.as_mv.row;
429
430                 if (temp < 0) temp -= 4;
431                 else temp += 4;
432
433                 x->block[uoffset].bmi.mv.as_mv.row = temp / 8;
434
435                 if (fullpixel)
436                     x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & 0xfffffff8;
437
438                 temp = x->block[yoffset  ].bmi.mv.as_mv.col
439                        + x->block[yoffset+1].bmi.mv.as_mv.col
440                        + x->block[yoffset+4].bmi.mv.as_mv.col
441                        + x->block[yoffset+5].bmi.mv.as_mv.col;
442
443                 if (temp < 0) temp -= 4;
444                 else temp += 4;
445
446                 x->block[uoffset].bmi.mv.as_mv.col = temp / 8;
447
448                 if (fullpixel)
449                     x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & 0xfffffff8;
450
451                 x->block[voffset].bmi.mv.as_mv.row = x->block[uoffset].bmi.mv.as_mv.row ;
452                 x->block[voffset].bmi.mv.as_mv.col = x->block[uoffset].bmi.mv.as_mv.col ;
453             }
454         }
455     }
456     else
457     {
458         int mvrow = x->mbmi.mv.as_mv.row;
459         int mvcol = x->mbmi.mv.as_mv.col;
460
461         if (mvrow < 0)
462             mvrow -= 1;
463         else
464             mvrow += 1;
465
466         if (mvcol < 0)
467             mvcol -= 1;
468         else
469             mvcol += 1;
470
471         mvrow /= 2;
472         mvcol /= 2;
473
474         for (i = 0; i < 8; i++)
475         {
476             x->block[ 16 + i].bmi.mv.as_mv.row = mvrow;
477             x->block[ 16 + i].bmi.mv.as_mv.col = mvcol;
478
479             if (fullpixel)
480             {
481                 x->block[ 16 + i].bmi.mv.as_mv.row = mvrow & 0xfffffff8;
482                 x->block[ 16 + i].bmi.mv.as_mv.col = mvcol & 0xfffffff8;
483             }
484         }
485     }
486 }
487
488
489 // The following functions are wriiten for skip_recon_mb() to call. Since there is no recon in this
490 // situation, we can write the result directly to dst buffer instead of writing it to predictor
491 // buffer and then copying it to dst buffer.
492 static void vp8_build_inter_predictors_b_s(BLOCKD *d, unsigned char *dst_ptr, vp8_subpix_fn_t sppf)
493 {
494     int r;
495     unsigned char *ptr_base;
496     unsigned char *ptr;
497     //unsigned char *pred_ptr = d->predictor;
498     int dst_stride = d->dst_stride;
499     int pre_stride = d->pre_stride;
500
501     ptr_base = *(d->base_pre);
502
503     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
504     {
505         ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
506         sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst_ptr, dst_stride);
507     }
508     else
509     {
510         ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
511         ptr = ptr_base;
512
513         for (r = 0; r < 4; r++)
514         {
515 #ifdef MUST_BE_ALIGNED
516             dst_ptr[0]   = ptr[0];
517             dst_ptr[1]   = ptr[1];
518             dst_ptr[2]   = ptr[2];
519             dst_ptr[3]   = ptr[3];
520 #else
521             *(int *)dst_ptr = *(int *)ptr ;
522 #endif
523             dst_ptr      += dst_stride;
524             ptr         += pre_stride;
525         }
526     }
527 }
528
529
530
531 void vp8_build_inter_predictors_mb_s(MACROBLOCKD *x)
532 {
533     //unsigned char *pred_ptr = x->block[0].predictor;
534     //unsigned char *dst_ptr = *(x->block[0].base_dst) + x->block[0].dst;
535     unsigned char *pred_ptr = x->predictor;
536     unsigned char *dst_ptr = x->dst.y_buffer;
537
538     if (x->mbmi.mode != SPLITMV)
539     {
540         int offset;
541         unsigned char *ptr_base;
542         unsigned char *ptr;
543         unsigned char *uptr, *vptr;
544         //unsigned char *pred_ptr = x->predictor;
545         //unsigned char *upred_ptr = &x->predictor[256];
546         //unsigned char *vpred_ptr = &x->predictor[320];
547         unsigned char *udst_ptr = x->dst.u_buffer;
548         unsigned char *vdst_ptr = x->dst.v_buffer;
549
550         int mv_row = x->mbmi.mv.as_mv.row;
551         int mv_col = x->mbmi.mv.as_mv.col;
552         int pre_stride = x->dst.y_stride; //x->block[0].pre_stride;
553
554         ptr_base = x->pre.y_buffer;
555         ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
556
557         if ((mv_row | mv_col) & 7)
558         {
559             x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
560         }
561         else
562         {
563             RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
564         }
565
566         mv_row = x->block[16].bmi.mv.as_mv.row;
567         mv_col = x->block[16].bmi.mv.as_mv.col;
568         pre_stride >>= 1;
569         offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
570         uptr = x->pre.u_buffer + offset;
571         vptr = x->pre.v_buffer + offset;
572
573         if ((mv_row | mv_col) & 7)
574         {
575             x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, udst_ptr, x->dst.uv_stride);
576             x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vdst_ptr, x->dst.uv_stride);
577         }
578         else
579         {
580             RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, udst_ptr, x->dst.uv_stride);
581             RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vdst_ptr, x->dst.uv_stride);
582         }
583     }
584     else
585     {
586         //note: this whole ELSE part is not executed at all. So, no way to test the correctness of my modification. Later,
587         //if sth is wrong, go back to what it is in build_inter_predictors_mb.
588         int i;
589
590         if (x->mbmi.partitioning < 3)
591         {
592             for (i = 0; i < 4; i++)
593             {
594                 BLOCKD *d = &x->block[bbb[i]];
595                 //vp8_build_inter_predictors4b(x, d, 16);
596
597                 {
598                     unsigned char *ptr_base;
599                     unsigned char *ptr;
600                     unsigned char *pred_ptr = d->predictor;
601
602                     ptr_base = *(d->base_pre);
603                     ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
604
605                     if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
606                     {
607                         x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
608                     }
609                     else
610                     {
611                         RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
612                     }
613                 }
614             }
615         }
616         else
617         {
618             for (i = 0; i < 16; i += 2)
619             {
620                 BLOCKD *d0 = &x->block[i];
621                 BLOCKD *d1 = &x->block[i+1];
622
623                 if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
624                 {
625                     //vp8_build_inter_predictors2b(x, d0, 16);
626                     unsigned char *ptr_base;
627                     unsigned char *ptr;
628                     unsigned char *pred_ptr = d0->predictor;
629
630                     ptr_base = *(d0->base_pre);
631                     ptr = ptr_base + d0->pre + (d0->bmi.mv.as_mv.row >> 3) * d0->pre_stride + (d0->bmi.mv.as_mv.col >> 3);
632
633                     if (d0->bmi.mv.as_mv.row & 7 || d0->bmi.mv.as_mv.col & 7)
634                     {
635                         x->subpixel_predict8x4(ptr, d0->pre_stride, d0->bmi.mv.as_mv.col & 7, d0->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride);
636                     }
637                     else
638                     {
639                         RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d0->pre_stride, dst_ptr, x->dst.y_stride);
640                     }
641                 }
642                 else
643                 {
644                     vp8_build_inter_predictors_b_s(d0, dst_ptr, x->subpixel_predict);
645                     vp8_build_inter_predictors_b_s(d1, dst_ptr, x->subpixel_predict);
646                 }
647             }
648         }
649
650         for (i = 16; i < 24; i += 2)
651         {
652             BLOCKD *d0 = &x->block[i];
653             BLOCKD *d1 = &x->block[i+1];
654
655             if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
656             {
657                 //vp8_build_inter_predictors2b(x, d0, 8);
658                 unsigned char *ptr_base;
659                 unsigned char *ptr;
660                 unsigned char *pred_ptr = d0->predictor;
661
662                 ptr_base = *(d0->base_pre);
663                 ptr = ptr_base + d0->pre + (d0->bmi.mv.as_mv.row >> 3) * d0->pre_stride + (d0->bmi.mv.as_mv.col >> 3);
664
665                 if (d0->bmi.mv.as_mv.row & 7 || d0->bmi.mv.as_mv.col & 7)
666                 {
667                     x->subpixel_predict8x4(ptr, d0->pre_stride, d0->bmi.mv.as_mv.col & 7, d0->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride);
668                 }
669                 else
670                 {
671                     RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d0->pre_stride, dst_ptr, x->dst.y_stride);
672                 }
673             }
674             else
675             {
676                 vp8_build_inter_predictors_b_s(d0, dst_ptr, x->subpixel_predict);
677                 vp8_build_inter_predictors_b_s(d1, dst_ptr, x->subpixel_predict);
678             }
679         }
680     }
681 }