early termination in UMH search
[x262.git] / encoder / me.c
1 /*****************************************************************************
2  * me.c: h264 encoder library (Motion Estimation)
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: me.c,v 1.1 2004/06/03 19:27:08 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Loren Merritt <lorenm@u.washington.edu>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "common/common.h"
29 #include "me.h"
30
31 /* presets selected from good points on the speed-vs-quality curve of several test videos
32  * subpel_iters[i_subpel_refine] = { refine_hpel, refine_qpel, me_hpel, me_qpel }
33  * where me_* are the number of EPZS iterations run on all candidate block types,
34  * and refine_* are run only on the winner. */
35 static const int subpel_iterations[][4] = 
36    {{1,0,0,0},
37     {1,1,0,0},
38     {0,1,1,0},
39     {0,2,1,0},
40     {0,2,1,1},
41     {0,2,1,2},
42     {0,0,2,2}};
43
44 static void refine_subpel( x264_t *h, x264_me_t *m, int hpel_iters, int qpel_iters, int *p_halfpel_thresh, int b_refine_qpel );
45
46 #define COST_MV_INT( mx, my, bd, d ) \
47 { \
48     int cost = h->pixf.sad[i_pixel]( m->p_fenc[0], m->i_stride[0],     \
49                    &p_fref[(my)*m->i_stride[0]+(mx)], m->i_stride[0] ) \
50              + p_cost_mvx[ (mx)<<2 ]  \
51              + p_cost_mvy[ (my)<<2 ]; \
52     if( cost < bcost ) \
53     {                  \
54         bcost = cost;  \
55         bmx = mx;      \
56         bmy = my;      \
57         if( bd ) \
58             dir = d; \
59     } \
60 }
61 #define COST_MV( mx, my )         COST_MV_INT( mx, my, 0, 0 )
62 #define COST_MV_DIR( mx, my, d )  COST_MV_INT( mx, my, 1, d )
63
64 #define COST_MV_PDE( mx, my ) \
65 { \
66     int cost = h->pixf.sad_pde[i_pixel]( m->p_fenc[0], m->i_stride[0], \
67                    &p_fref[(my)*m->i_stride[0]+(mx)], m->i_stride[0], \
68                    bcost - p_cost_mvx[ (mx)<<2 ] - p_cost_mvy[ (my)<<2 ] ); \
69     if( cost < bcost - p_cost_mvx[ (mx)<<2 ] - p_cost_mvy[ (my)<<2 ] ) \
70     {                  \
71         bcost = cost + p_cost_mvx[ (mx)<<2 ] + p_cost_mvy[ (my)<<2 ];  \
72         bmx = mx;      \
73         bmy = my;      \
74     } \
75 }
76
77 #define DIA1_ITER( mx, my )\
78     {\
79         omx = mx; omy = my;\
80         COST_MV( omx  , omy-1 );/*  1  */\
81         COST_MV( omx  , omy+1 );/* 101 */\
82         COST_MV( omx-1, omy   );/*  1  */\
83         COST_MV( omx+1, omy   );\
84     }
85
86 #define DIA2 \
87     {\
88         COST_MV( omx  , omy-2 );\
89         COST_MV( omx-1, omy-1 );/*   1   */\
90         COST_MV( omx+1, omy-1 );/*  1 1  */\
91         COST_MV( omx-2, omy   );/* 1 0 1 */\
92         COST_MV( omx+2, omy   );/*  1 1  */\
93         COST_MV( omx-1, omy+1 );/*   1   */\
94         COST_MV( omx+1, omy+1 );\
95         COST_MV( omx  , omy+2 );\
96     }\
97
98 #define OCT2 \
99     {\
100         COST_MV( omx-1, omy-2 );\
101         COST_MV( omx+1, omy-2 );/*  1 1  */\
102         COST_MV( omx-2, omy-1 );/* 1   1 */\
103         COST_MV( omx+2, omy-1 );/*   0   */\
104         COST_MV( omx-2, omy+1 );/* 1   1 */\
105         COST_MV( omx+2, omy+1 );/*  1 1  */\
106         COST_MV( omx-1, omy+2 );\
107         COST_MV( omx+1, omy+2 );\
108     }
109
110 #define CROSS( start, x_max, y_max ) \
111     { \
112         for( i = start; i < x_max; i+=2 ) \
113         { \
114             if( omx + i <= mv_x_max ) \
115                 COST_MV( omx + i, omy ); \
116             if( omx - i >= mv_x_min ) \
117                 COST_MV( omx - i, omy ); \
118         } \
119         for( i = start; i < y_max; i+=2 ) \
120         { \
121             if( omy + i <= mv_y_max ) \
122                 COST_MV( omx, omy + i ); \
123             if( omy - i >= mv_y_min ) \
124                 COST_MV( omx, omy - i ); \
125         } \
126     }
127
128
129 void x264_me_search_ref( x264_t *h, x264_me_t *m, int (*mvc)[2], int i_mvc, int *p_halfpel_thresh )
130 {
131     const int i_pixel = m->i_pixel;
132     int i_me_range = h->param.analyse.i_me_range;
133     int bmx, bmy, bcost;
134     int omx, omy, pmx, pmy;
135     uint8_t *p_fref = m->p_fref[0];
136     int i, j;
137     int dir;
138
139     int mv_x_min = h->mb.mv_min_fpel[0];
140     int mv_y_min = h->mb.mv_min_fpel[1];
141     int mv_x_max = h->mb.mv_max_fpel[0];
142     int mv_y_max = h->mb.mv_max_fpel[1];
143
144     const int16_t *p_cost_mvx = m->p_cost_mv - m->mvp[0];
145     const int16_t *p_cost_mvy = m->p_cost_mv - m->mvp[1];
146
147     if( h->mb.i_me_method == X264_ME_UMH )
148     {
149         /* clamp mvp to inside frame+padding, so that we don't have to check it each iteration */
150         p_cost_mvx = m->p_cost_mv - x264_clip3( m->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
151         p_cost_mvy = m->p_cost_mv - x264_clip3( m->mvp[1], h->mb.mv_min_spel[1], h->mb.mv_max_spel[1] );
152     }
153
154     bmx = pmx = x264_clip3( ( m->mvp[0] + 2 ) >> 2, mv_x_min, mv_x_max );
155     bmy = pmy = x264_clip3( ( m->mvp[1] + 2 ) >> 2, mv_y_min, mv_y_max );
156     bcost = COST_MAX;
157     COST_MV( pmx, pmy );
158     /* I don't know why this helps */
159     bcost -= p_cost_mvx[ bmx<<2 ] + p_cost_mvy[ bmy<<2 ];
160
161     /* try extra predictors if provided */
162     for( i = 0; i < i_mvc; i++ )
163     {
164         const int mx = x264_clip3( ( mvc[i][0] + 2 ) >> 2, mv_x_min, mv_x_max );
165         const int my = x264_clip3( ( mvc[i][1] + 2 ) >> 2, mv_y_min, mv_y_max );
166         if( mx != bmx || my != bmy )
167             COST_MV( mx, my );
168     }
169     
170     COST_MV( 0, 0 );
171
172     mv_x_max += 8;
173     mv_y_max += 8;
174     mv_x_min -= 8;
175     mv_y_min -= 8;
176
177     switch( h->mb.i_me_method )
178     {
179     case X264_ME_DIA:
180         /* diamond search, radius 1 */
181         for( i = 0; i < i_me_range; i++ )
182         {
183             DIA1_ITER( bmx, bmy );
184             if( bmx == omx && bmy == omy )
185                 break;
186         }
187         break;
188
189     case X264_ME_HEX:
190 me_hex2:
191         /* hexagon search, radius 2 */
192 #if 0
193         for( i = 0; i < i_me_range/2; i++ )
194         {
195             omx = bmx; omy = bmy;
196             COST_MV( omx-2, omy   );
197             COST_MV( omx-1, omy+2 );
198             COST_MV( omx+1, omy+2 );
199             COST_MV( omx+2, omy   );
200             COST_MV( omx+1, omy-2 );
201             COST_MV( omx-1, omy-2 );
202             if( bmx == omx && bmy == omy )
203                 break;
204         }
205 #else
206         /* equivalent to the above, but eliminates duplicate candidates */
207         dir = -1;
208         omx = bmx; omy = bmy;
209         COST_MV_DIR( omx-2, omy,   0 );
210         COST_MV_DIR( omx-1, omy+2, 1 );
211         COST_MV_DIR( omx+1, omy+2, 2 );
212         COST_MV_DIR( omx+2, omy,   3 );
213         COST_MV_DIR( omx+1, omy-2, 4 );
214         COST_MV_DIR( omx-1, omy-2, 5 );
215         if( dir != -1 )
216         {
217             for( i = 1; i < i_me_range/2; i++ )
218             {
219                 static const int hex2[8][2] = {{-1,-2}, {-2,0}, {-1,2}, {1,2}, {2,0}, {1,-2}, {-1,-2}, {-2,0}};
220                 static const int mod6[8] = {5,0,1,2,3,4,5,0};
221                 const int odir = mod6[dir+1];
222                 omx = bmx; omy = bmy;
223                 COST_MV_DIR( omx + hex2[odir+0][0], omy + hex2[odir+0][1], odir-1 );
224                 COST_MV_DIR( omx + hex2[odir+1][0], omy + hex2[odir+1][1], odir   );
225                 COST_MV_DIR( omx + hex2[odir+2][0], omy + hex2[odir+2][1], odir+1 );
226                 if( bmx == omx && bmy == omy )
227                     break;
228             }
229         }
230 #endif
231         /* square refine */
232         DIA1_ITER( bmx, bmy );
233         COST_MV( omx-1, omy-1 );
234         COST_MV( omx-1, omy+1 );
235         COST_MV( omx+1, omy-1 );
236         COST_MV( omx+1, omy+1 );
237         break;
238
239     case X264_ME_UMH:
240         {
241             /* Uneven-cross Multi-Hexagon-grid Search
242              * as in JM, except with different early termination */
243
244             static const int x264_pixel_size_shift[7] = { 0, 1, 1, 2, 3, 3, 4 };
245
246             int ucost1, ucost2;
247             int cross_start = 1;
248
249             /* refine predictors */
250             ucost1 = bcost;
251             DIA1_ITER( pmx, pmy );
252             if( pmx || pmy )
253                 DIA1_ITER( 0, 0 );
254
255             if(i_pixel == PIXEL_4x4)
256                 goto me_hex2;
257
258             ucost2 = bcost;
259             if( (bmx || bmy) && (bmx!=pmx || bmy!=pmy) )
260                 DIA1_ITER( bmx, bmy );
261             if( bcost == ucost2 )
262                 cross_start = 3;
263             omx = bmx; omy = bmy;
264
265             /* early termination */
266 #define SAD_THRESH(v) ( bcost < ( v >> x264_pixel_size_shift[i_pixel] ) )
267             if( bcost == ucost2 && SAD_THRESH(2000) )
268             {
269                 DIA2;
270                 if( bcost == ucost1 && SAD_THRESH(500) )
271                     break;
272                 if( bcost == ucost2 )
273                 {
274                     int range = (i_me_range>>1) | 1;
275                     CROSS( 3, range, range );
276                     OCT2;
277                     if( bcost == ucost2 )
278                         break;
279                     cross_start = range + 2;
280                 }
281             }
282
283             /* adaptive search range */
284             if( i_mvc ) 
285             {
286                 /* range multipliers based on casual inspection of some statistics of
287                  * average distance between current predictor and final mv found by ESA.
288                  * these have not been tuned much by actual encoding. */
289                 static const int range_mul[4][4] =
290                 {
291                     { 3, 3, 4, 4 },
292                     { 3, 4, 4, 4 },
293                     { 4, 4, 4, 5 },
294                     { 4, 4, 5, 6 },
295                 };
296                 int mvd;
297                 int sad_ctx, mvd_ctx;
298
299                 if( i_mvc == 1 )
300                 {
301                     if( i_pixel == PIXEL_16x16 )
302                         /* mvc is probably the same as mvp, so the difference isn't meaningful.
303                          * but prediction usually isn't too bad, so just use medium range */
304                         mvd = 25;
305                     else
306                         mvd = abs( m->mvp[0] - mvc[0][0] )
307                             + abs( m->mvp[1] - mvc[0][1] );
308                 }
309                 else
310                 {
311                     /* calculate the degree of agreement between predictors. */
312                     /* in 16x16, mvc includes all the neighbors used to make mvp,
313                      * so don't count mvp separately. */
314                     int i_denom = i_mvc - 1;
315                     mvd = 0;
316                     if( i_pixel != PIXEL_16x16 )
317                     {
318                         mvd = abs( m->mvp[0] - mvc[0][0] )
319                             + abs( m->mvp[1] - mvc[0][1] );
320                         i_denom++;
321                     }
322                     for( i = 0; i < i_mvc-1; i++ )
323                         mvd += abs( mvc[i][0] - mvc[i+1][0] )
324                              + abs( mvc[i][1] - mvc[i+1][1] );
325                     mvd /= i_denom; //FIXME idiv
326                 }
327
328                 sad_ctx = SAD_THRESH(1000) ? 0
329                         : SAD_THRESH(2000) ? 1
330                         : SAD_THRESH(4000) ? 2 : 3;
331                 mvd_ctx = mvd < 10 ? 0
332                         : mvd < 20 ? 1
333                         : mvd < 40 ? 2 : 3;
334
335                 i_me_range = i_me_range * range_mul[mvd_ctx][sad_ctx] / 4;
336             }
337
338             /* FIXME if the above DIA2/OCT2/CROSS found a new mv, it has not updated omx/omy.
339              * we are still centered on the same place as the DIA2. is this desirable? */
340             CROSS( cross_start, i_me_range, i_me_range/2 );
341
342             /* 5x5 ESA */
343             omx = bmx; omy = bmy;
344             for( i = (bcost == ucost2) ? 4 : 0; i < 24; i++ )
345             {
346                 static const int square2[24][2] = {
347                     { 1, 0}, { 0, 1}, {-1, 0}, { 0,-1},
348                     { 1, 1}, {-1, 1}, {-1,-1}, { 1,-1},
349                     { 2,-1}, { 2, 0}, { 2, 1}, { 2, 2},
350                     { 1, 2}, { 0, 2}, {-1, 2}, {-2, 2},
351                     {-2, 1}, {-2, 0}, {-2,-1}, {-2,-2},
352                     {-1,-2}, { 0,-2}, { 1,-2}, { 2,-2}
353                 };
354                 COST_MV( omx + square2[i][0], omy + square2[i][1] );
355             }
356
357             /* hexagon grid */
358             omx = bmx; omy = bmy;
359             for( i = 1; i <= i_me_range/4; i++ )
360             {
361                 static const int hex4[16][2] = {
362                     {-4, 2}, {-4, 1}, {-4, 0}, {-4,-1}, {-4,-2},
363                     { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
364                     { 2, 3}, { 0, 4}, {-2, 3},
365                     {-2,-3}, { 0,-4}, { 2,-3},
366                 };
367                 const int bounds_check = 4*i > X264_MIN4( mv_x_max-omx, mv_y_max-omy, omx-mv_x_min, omy-mv_y_min );
368
369                 if( h->pixf.sad_pde[i_pixel] )
370                 {
371                     for( j = 0; j < 16; j++ )
372                     {
373                         int mx = omx + hex4[j][0]*i;
374                         int my = omy + hex4[j][1]*i;
375                         if( !bounds_check || ( mx >= mv_x_min && mx <= mv_x_max
376                                             && my >= mv_y_min && my <= mv_y_max ) )
377                             COST_MV_PDE( mx, my );
378                     }
379                 }
380                 else
381                 {
382                     for( j = 0; j < 16; j++ )
383                     {
384                         int mx = omx + hex4[j][0]*i;
385                         int my = omy + hex4[j][1]*i;
386                         if( !bounds_check || ( mx >= mv_x_min && mx <= mv_x_max
387                                             && my >= mv_y_min && my <= mv_y_max ) )
388                             COST_MV( mx, my );
389                     }
390                 }
391             }
392             goto me_hex2;
393         }
394
395     case X264_ME_ESA:
396         {
397             const int min_x = X264_MAX( bmx - i_me_range, mv_x_min);
398             const int min_y = X264_MAX( bmy - i_me_range, mv_y_min);
399             const int max_x = X264_MIN( bmx + i_me_range, mv_x_max);
400             const int max_y = X264_MIN( bmy + i_me_range, mv_y_max);
401             int mx, my;
402 #if 0
403             /* plain old exhaustive search */
404             for( my = min_y; my <= max_y; my++ )
405                 for( mx = min_x; mx <= max_x; mx++ )
406                     COST_MV( mx, my );
407 #else
408             /* successive elimination by comparing DC before a full SAD,
409              * because sum(abs(diff)) >= abs(diff(sum)). */
410             const int stride = m->i_stride[0];
411             const int dw = x264_pixel_size[i_pixel].w;
412             const int dh = x264_pixel_size[i_pixel].h * stride;
413             static uint8_t zero[16*16] = {0,};
414             const int enc_dc = h->pixf.sad[i_pixel]( m->p_fenc[0], stride, zero, 16 );
415             const uint16_t *integral_base = &m->integral[ -1 - 1*stride ];
416
417             if( h->pixf.sad_pde[i_pixel] )
418             {
419                 for( my = min_y; my <= max_y; my++ )
420                     for( mx = min_x; mx <= max_x; mx++ )
421                     {
422                         const uint16_t *integral = &integral_base[ mx + my * stride ];
423                         const uint16_t ref_dc = integral[  0 ] + integral[ dh + dw ]
424                                               - integral[ dw ] - integral[ dh ];
425                         const int bsad = bcost - p_cost_mvx[ (mx)<<2 ] - p_cost_mvy[ (my)<<2 ];
426                         if( abs( ref_dc - enc_dc ) < bsad )
427                             COST_MV_PDE( mx, my );
428                     }
429             }
430             else
431             {
432                 for( my = min_y; my <= max_y; my++ )
433                     for( mx = min_x; mx <= max_x; mx++ )
434                     {
435                         const uint16_t *integral = &integral_base[ mx + my * stride ];
436                         const uint16_t ref_dc = integral[  0 ] + integral[ dh + dw ]
437                                               - integral[ dw ] - integral[ dh ];
438                         const int bsad = bcost - p_cost_mvx[ (mx)<<2 ] - p_cost_mvy[ (my)<<2 ];
439                         if( abs( ref_dc - enc_dc ) < bsad )
440                             COST_MV( mx, my );
441                     }
442             }
443 #endif
444         }
445         break;
446     }
447
448     /* -> qpel mv */
449     m->mv[0] = bmx << 2;
450     m->mv[1] = bmy << 2;
451
452     /* compute the real cost */
453     m->cost_mv = p_cost_mvx[ m->mv[0] ] + p_cost_mvy[ m->mv[1] ];
454     m->cost = bcost;
455     if( bmx == pmx && bmy == pmy )
456         m->cost += m->cost_mv;
457     
458     /* subpel refine */
459     if( h->mb.i_subpel_refine >= 2 )
460     {
461         int hpel = subpel_iterations[h->mb.i_subpel_refine][2];
462         int qpel = subpel_iterations[h->mb.i_subpel_refine][3];
463         refine_subpel( h, m, hpel, qpel, p_halfpel_thresh, 0 );
464     }
465 }
466 #undef COST_MV
467
468 void x264_me_refine_qpel( x264_t *h, x264_me_t *m )
469 {
470     int hpel = subpel_iterations[h->mb.i_subpel_refine][0];
471     int qpel = subpel_iterations[h->mb.i_subpel_refine][1];
472
473     if( m->i_pixel <= PIXEL_8x8 && h->sh.i_type == SLICE_TYPE_P )
474         m->cost -= m->i_ref_cost;
475         
476     refine_subpel( h, m, hpel, qpel, NULL, 1 );
477 }
478
479 #define COST_MV_SAD( mx, my, dir ) \
480 if( b_refine_qpel || (dir^1) != odir ) \
481 { \
482     int stride = 16; \
483     uint8_t *src = h->mc.get_ref( m->p_fref, m->i_stride[0], pix, &stride, mx, my, bw, bh ); \
484     int cost = h->pixf.sad[i_pixel]( m->p_fenc[0], m->i_stride[0], src, stride ) \
485              + p_cost_mvx[ mx ] + p_cost_mvy[ my ]; \
486     if( cost < bcost ) \
487     {                  \
488         bcost = cost;  \
489         bmx = mx;      \
490         bmy = my;      \
491         bdir = dir;    \
492     } \
493 }
494
495 #define COST_MV_SATD( mx, my, dir ) \
496 if( b_refine_qpel || (dir^1) != odir ) \
497 { \
498     int stride = 16; \
499     uint8_t *src = h->mc.get_ref( m->p_fref, m->i_stride[0], pix, &stride, mx, my, bw, bh ); \
500     int cost = h->pixf.mbcmp[i_pixel]( m->p_fenc[0], m->i_stride[0], src, stride ) \
501              + p_cost_mvx[ mx ] + p_cost_mvy[ my ]; \
502     if( b_chroma_me && cost < bcost ) \
503     { \
504         h->mc.mc_chroma( m->p_fref[4], m->i_stride[1], pix, 8, mx, my, bw/2, bh/2 ); \
505         cost += h->pixf.mbcmp[i_pixel+3]( m->p_fenc[1], m->i_stride[1], pix, 8 ); \
506         if( cost < bcost ) \
507         { \
508             h->mc.mc_chroma( m->p_fref[5], m->i_stride[1], pix, 8, mx, my, bw/2, bh/2 ); \
509             cost += h->pixf.mbcmp[i_pixel+3]( m->p_fenc[2], m->i_stride[1], pix, 8 ); \
510         } \
511     } \
512     if( cost < bcost ) \
513     {                  \
514         bcost = cost;  \
515         bmx = mx;      \
516         bmy = my;      \
517         bdir = dir;    \
518     } \
519 }
520
521 static void refine_subpel( x264_t *h, x264_me_t *m, int hpel_iters, int qpel_iters, int *p_halfpel_thresh, int b_refine_qpel )
522 {
523     const int bw = x264_pixel_size[m->i_pixel].w;
524     const int bh = x264_pixel_size[m->i_pixel].h;
525     const int16_t *p_cost_mvx = m->p_cost_mv - m->mvp[0];
526     const int16_t *p_cost_mvy = m->p_cost_mv - m->mvp[1];
527     const int i_pixel = m->i_pixel;
528     const int b_chroma_me = h->mb.b_chroma_me && i_pixel <= PIXEL_8x8;
529
530     DECLARE_ALIGNED( uint8_t, pix[16*16], 16 );
531     int omx, omy;
532     int i;
533
534     int bmx = m->mv[0];
535     int bmy = m->mv[1];
536     int bcost = m->cost;
537     int odir = -1, bdir;
538
539
540     /* try the subpel component of the predicted mv */
541     if( hpel_iters )
542     {
543         int mx = x264_clip3( m->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
544         int my = x264_clip3( m->mvp[1], h->mb.mv_min_spel[1], h->mb.mv_max_spel[1] );
545         if( mx != bmx || my != bmy )
546             COST_MV_SAD( mx, my, -1 );
547     }
548     
549     /* hpel search */
550     bdir = -1;
551     for( i = hpel_iters; i > 0; i-- )
552     {
553         odir = bdir;
554         omx = bmx;
555         omy = bmy;
556         COST_MV_SAD( omx, omy - 2, 0 );
557         COST_MV_SAD( omx, omy + 2, 1 );
558         COST_MV_SAD( omx - 2, omy, 2 );
559         COST_MV_SAD( omx + 2, omy, 3 );
560         if( bmx == omx && bmy == omy )
561             break;
562     }
563     
564     if( !b_refine_qpel )
565     {
566         bcost = COST_MAX;
567         COST_MV_SATD( bmx, bmy, -1 );
568     }
569     
570     /* early termination when examining multiple reference frames */
571     if( p_halfpel_thresh )
572     {
573         if( (bcost*7)>>3 > *p_halfpel_thresh )
574         {
575             m->cost = bcost;
576             m->mv[0] = bmx;
577             m->mv[1] = bmy;
578             // don't need cost_mv
579             return;
580         }
581         else if( bcost < *p_halfpel_thresh )
582             *p_halfpel_thresh = bcost;
583     }
584
585     /* qpel search */
586     bdir = -1;
587     for( i = qpel_iters; i > 0; i-- )
588     {
589         odir = bdir;
590         omx = bmx;
591         omy = bmy;
592         COST_MV_SATD( omx, omy - 1, 0 );
593         COST_MV_SATD( omx, omy + 1, 1 );
594         COST_MV_SATD( omx - 1, omy, 2 );
595         COST_MV_SATD( omx + 1, omy, 3 );
596         if( bmx == omx && bmy == omy )
597             break;
598     }
599
600     m->cost = bcost;
601     m->mv[0] = bmx;
602     m->mv[1] = bmy;
603     m->cost_mv = p_cost_mvx[ bmx ] + p_cost_mvy[ bmy ];
604 }
605
606 #define BIME_CACHE( dx, dy ) \
607 { \
608     int i = 4 + 3*dx + dy; \
609     h->mc.mc_luma( m0->p_fref, m0->i_stride[0], pix0[i], bw, om0x+dx, om0y+dy, bw, bh ); \
610     h->mc.mc_luma( m1->p_fref, m1->i_stride[0], pix1[i], bw, om1x+dx, om1y+dy, bw, bh ); \
611 }
612
613 #define BIME_CACHE2(a,b) \
614     BIME_CACHE(a,b) \
615     BIME_CACHE(-(a),-(b))
616
617 #define COST_BIMV_SATD( m0x, m0y, m1x, m1y ) \
618 if( pass == 0 || !visited[(m0x)&7][(m0y)&7][(m1x)&7][(m1y)&7] ) \
619 { \
620     int cost; \
621     int i0 = 4 + 3*(m0x-om0x) + (m0y-om0y); \
622     int i1 = 4 + 3*(m1x-om1x) + (m1y-om1y); \
623     visited[(m0x)&7][(m0y)&7][(m1x)&7][(m1y)&7] = 1; \
624     memcpy( pix, pix0[i0], bs ); \
625     if( i_weight == 32 ) \
626         h->mc.avg[i_pixel]( pix, bw, pix1[i1], bw ); \
627     else \
628         h->mc.avg_weight[i_pixel]( pix, bw, pix1[i1], bw, i_weight ); \
629     cost = h->pixf.mbcmp[i_pixel]( m0->p_fenc[0], m0->i_stride[0], pix, bw ) \
630          + p_cost_m0x[ m0x ] + p_cost_m0y[ m0y ] \
631          + p_cost_m1x[ m1x ] + p_cost_m1y[ m1y ]; \
632     if( cost < bcost ) \
633     {                  \
634         bcost = cost;  \
635         bm0x = m0x;    \
636         bm0y = m0y;    \
637         bm1x = m1x;    \
638         bm1y = m1y;    \
639     } \
640 }
641
642 #define CHECK_BIDIR(a,b,c,d) \
643     COST_BIMV_SATD(om0x+a, om0y+b, om1x+c, om1y+d)
644
645 #define CHECK_BIDIR2(a,b,c,d) \
646     CHECK_BIDIR(a,b,c,d) \
647     CHECK_BIDIR(-(a),-(b),-(c),-(d))
648
649 #define CHECK_BIDIR8(a,b,c,d) \
650     CHECK_BIDIR2(a,b,c,d) \
651     CHECK_BIDIR2(b,c,d,a) \
652     CHECK_BIDIR2(c,d,a,b) \
653     CHECK_BIDIR2(d,a,b,c)
654
655 int x264_me_refine_bidir( x264_t *h, x264_me_t *m0, x264_me_t *m1, int i_weight )
656 {
657     const int i_pixel = m0->i_pixel;
658     const int bw = x264_pixel_size[i_pixel].w;
659     const int bh = x264_pixel_size[i_pixel].h;
660     const int bs = bw*bh;
661     const int16_t *p_cost_m0x = m0->p_cost_mv - x264_clip3( m0->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
662     const int16_t *p_cost_m0y = m0->p_cost_mv - x264_clip3( m0->mvp[1], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
663     const int16_t *p_cost_m1x = m1->p_cost_mv - x264_clip3( m1->mvp[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
664     const int16_t *p_cost_m1y = m1->p_cost_mv - x264_clip3( m1->mvp[1], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] );
665     DECLARE_ALIGNED( uint8_t, pix0[9][16*16], 16 );
666     DECLARE_ALIGNED( uint8_t, pix1[9][16*16], 16 );
667     DECLARE_ALIGNED( uint8_t, pix[16*16], 16 );
668     int bm0x = m0->mv[0], om0x = bm0x;
669     int bm0y = m0->mv[1], om0y = bm0y;
670     int bm1x = m1->mv[0], om1x = bm1x;
671     int bm1y = m1->mv[1], om1y = bm1y;
672     int bcost = COST_MAX;
673     int pass = 0;
674     uint8_t visited[8][8][8][8];
675     memset( visited, 0, sizeof(visited) );
676
677     BIME_CACHE( 0, 0 );
678     CHECK_BIDIR( 0, 0, 0, 0 );
679
680     for( pass = 0; pass < 8; pass++ )
681     {
682         /* check all mv pairs that differ in at most 2 components from the current mvs. */
683         /* doesn't do chroma ME. this probably doesn't matter, as the gains
684          * from bidir ME are the same with and without chroma ME. */
685
686         BIME_CACHE2( 1, 0 );
687         BIME_CACHE2( 0, 1 );
688         BIME_CACHE2( 1, 1 );
689         BIME_CACHE2( 1,-1 );
690
691         CHECK_BIDIR8( 0, 0, 0, 1 );
692         CHECK_BIDIR8( 0, 0, 1, 1 );
693         CHECK_BIDIR2( 0, 1, 0, 1 );
694         CHECK_BIDIR2( 1, 0, 1, 0 );
695         CHECK_BIDIR8( 0, 0,-1, 1 );
696         CHECK_BIDIR2( 0,-1, 0, 1 );
697         CHECK_BIDIR2(-1, 0, 1, 0 );
698
699         if( om0x == bm0x && om0y == bm0y && om1x == bm1x && om1y == bm1y )
700             break;
701
702         om0x = bm0x;
703         om0y = bm0y;
704         om1x = bm1x;
705         om1y = bm1y;
706         BIME_CACHE( 0, 0 );
707     }
708
709     m0->mv[0] = bm0x;
710     m0->mv[1] = bm0y;
711     m1->mv[0] = bm1x;
712     m1->mv[1] = bm1y;
713     return bcost;
714 }