3 * Copyright (c) 2002 Michael Niedermayer
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * @file motion_est_template.c
23 * Motion estimation template.
25 //FIXME ref2_y next_pic?
26 //lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
27 //Note, the last line is there to kill these ugly unused var warnings
29 uint32_t * const score_map= s->me.score_map;\
30 const int time_pp= s->pp_time;\
31 const int time_pb= s->pb_time;\
32 const int xmin= s->me.xmin;\
33 const int ymin= s->me.ymin;\
34 const int xmax= s->me.xmax;\
35 const int ymax= s->me.ymax;\
36 uint8_t * const src_y= src_data[0];\
37 uint8_t * const src_u= src_data[1];\
38 uint8_t * const src_v= src_data[2];\
39 uint8_t * const ref_y= ref_data[0];\
40 uint8_t * const ref_u= ref_data[1];\
41 uint8_t * const ref_v= ref_data[2];\
42 op_pixels_func (*hpel_put)[4];\
43 op_pixels_func (*hpel_avg)[4]= &s->dsp.avg_pixels_tab[size];\
44 op_pixels_func (*chroma_hpel_put)[4];\
45 qpel_mc_func (*qpel_put)[16];\
46 qpel_mc_func (*qpel_avg)[16]= &s->dsp.avg_qpel_pixels_tab[size];\
47 const __attribute__((unused)) int unu= time_pp + time_pb + (size_t)src_u + (size_t)src_v + (size_t)ref_u + (size_t)ref_v\
48 + (size_t)hpel_avg + (size_t)qpel_avg + (size_t)score_map\
49 + xmin + xmax + ymin + ymax;\
50 if(s->no_rounding /*FIXME b_type*/){\
51 hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];\
52 chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];\
53 qpel_put= &s->dsp.put_no_rnd_qpel_pixels_tab[size];\
55 hpel_put=& s->dsp.put_pixels_tab[size];\
56 chroma_hpel_put= &s->dsp.put_pixels_tab[size+1];\
57 qpel_put= &s->dsp.put_qpel_pixels_tab[size];\
63 #define CHECK_HALF_MV(dx, dy, x, y)\
65 const int hx= 2*(x)+(dx);\
66 const int hy= 2*(y)+(dy);\
67 CMP_HPEL(d, dx, dy, x, y, size);\
68 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
69 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
73 static int RENAME(hpel_motion_search
)(MpegEncContext
* s
,
74 int *mx_ptr
, int *my_ptr
, int dmin
,
75 int pred_x
, int pred_y
, uint8_t *ref_data
[3],
76 int size
, uint8_t * const mv_penalty
)
78 const int xx
= 16 * s
->mb_x
+ 8*(n
&1);
79 const int yy
= 16 * s
->mb_y
+ 8*(n
>>1);
80 const int mx
= *mx_ptr
;
81 const int my
= *my_ptr
;
82 const int penalty_factor
= s
->me
.sub_penalty_factor
;
88 me_cmp_func cmp
, chroma_cmp
, cmp_sub
, chroma_cmp_sub
;
90 if(s
->no_rounding
/*FIXME b_type*/){
91 hpel_put
= &s
->dsp
.put_no_rnd_pixels_tab
[size
];
92 chroma_hpel_put
= &s
->dsp
.put_no_rnd_pixels_tab
[size
+1];
94 hpel_put
=& s
->dsp
.put_pixels_tab
[size
];
95 chroma_hpel_put
= &s
->dsp
.put_pixels_tab
[size
+1];
97 cmp
= s
->dsp
.me_cmp
[size
];
98 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
99 cmp_sub
= s
->dsp
.me_sub_cmp
[size
];
100 chroma_cmp_sub
= s
->dsp
.me_sub_cmp
[size
+1];
102 if(s
->me
.skip
){ //FIXME somehow move up (benchmark)
108 if(s
->avctx
->me_cmp
!= s
->avctx
->me_sub_cmp
){
109 CMP_HPEL(dmin
, 0, 0, mx
, my
, size
);
111 dmin
+= (mv_penalty
[2*mx
- pred_x
] + mv_penalty
[2*my
- pred_y
])*penalty_factor
;
114 if (mx
> xmin
&& mx
< xmax
&&
115 my
> ymin
&& my
< ymax
) {
116 int bx
=2*mx
, by
=2*my
;
119 CHECK_HALF_MV(1, 1, mx
-1, my
-1)
120 CHECK_HALF_MV(0, 1, mx
, my
-1)
121 CHECK_HALF_MV(1, 1, mx
, my
-1)
122 CHECK_HALF_MV(1, 0, mx
-1, my
)
123 CHECK_HALF_MV(1, 0, mx
, my
)
124 CHECK_HALF_MV(1, 1, mx
-1, my
)
125 CHECK_HALF_MV(0, 1, mx
, my
)
126 CHECK_HALF_MV(1, 1, mx
, my
)
128 assert(bx
>= xmin
*2 || bx
<= xmax
*2 || by
>= ymin
*2 || by
<= ymax
*2);
141 static int RENAME(hpel_motion_search
)(MpegEncContext
* s
,
142 int *mx_ptr
, int *my_ptr
, int dmin
,
143 int pred_x
, int pred_y
, uint8_t *src_data
[3],
144 uint8_t *ref_data
[3], int stride
, int uvstride
,
145 int size
, int h
, uint8_t * const mv_penalty
)
147 const int mx
= *mx_ptr
;
148 const int my
= *my_ptr
;
149 const int penalty_factor
= s
->me
.sub_penalty_factor
;
150 me_cmp_func cmp_sub
, chroma_cmp_sub
;
151 int bx
=2*mx
, by
=2*my
;
157 cmp_sub
= s
->dsp
.me_sub_cmp
[size
];
158 chroma_cmp_sub
= s
->dsp
.me_sub_cmp
[size
+1];
160 if(s
->me
.skip
){ //FIXME move out of hpel?
166 if(s
->avctx
->me_cmp
!= s
->avctx
->me_sub_cmp
){
167 CMP_HPEL(dmin
, 0, 0, mx
, my
, size
);
168 if(mx
|| my
|| size
>0)
169 dmin
+= (mv_penalty
[2*mx
- pred_x
] + mv_penalty
[2*my
- pred_y
])*penalty_factor
;
172 if (mx
> xmin
&& mx
< xmax
&&
173 my
> ymin
&& my
< ymax
) {
175 const int index
= (my
<<ME_MAP_SHIFT
) + mx
;
176 const int t
= score_map
[(index
-(1<<ME_MAP_SHIFT
))&(ME_MAP_SIZE
-1)]
177 + (mv_penalty
[bx
- pred_x
] + mv_penalty
[by
-2 - pred_y
])*s
->me
.penalty_factor
;
178 const int l
= score_map
[(index
- 1 )&(ME_MAP_SIZE
-1)]
179 + (mv_penalty
[bx
-2 - pred_x
] + mv_penalty
[by
- pred_y
])*s
->me
.penalty_factor
;
180 const int r
= score_map
[(index
+ 1 )&(ME_MAP_SIZE
-1)]
181 + (mv_penalty
[bx
+2 - pred_x
] + mv_penalty
[by
- pred_y
])*s
->me
.penalty_factor
;
182 const int b
= score_map
[(index
+(1<<ME_MAP_SHIFT
))&(ME_MAP_SIZE
-1)]
183 + (mv_penalty
[bx
- pred_x
] + mv_penalty
[by
+2 - pred_y
])*s
->me
.penalty_factor
;
187 int map_generation
= s
->me
.map_generation
;
189 uint32_t *map
= s
->me
.map
;
191 key
= ((my
-1)<<ME_MAP_MV_BITS
) + (mx
) + map_generation
;
192 assert(map
[(index
-(1<<ME_MAP_SHIFT
))&(ME_MAP_SIZE
-1)] == key
);
193 key
= ((my
+1)<<ME_MAP_MV_BITS
) + (mx
) + map_generation
;
194 assert(map
[(index
+(1<<ME_MAP_SHIFT
))&(ME_MAP_SIZE
-1)] == key
);
195 key
= ((my
)<<ME_MAP_MV_BITS
) + (mx
+1) + map_generation
;
196 assert(map
[(index
+1)&(ME_MAP_SIZE
-1)] == key
);
197 key
= ((my
)<<ME_MAP_MV_BITS
) + (mx
-1) + map_generation
;
198 assert(map
[(index
-1)&(ME_MAP_SIZE
-1)] == key
);
201 CHECK_HALF_MV(0, 1, mx
,my
-1)
203 CHECK_HALF_MV(1, 1, mx
-1, my
-1)
205 CHECK_HALF_MV(1, 1, mx
, my
-1)
207 CHECK_HALF_MV(1, 1, mx
-1, my
)
209 CHECK_HALF_MV(1, 0, mx
-1, my
)
211 CHECK_HALF_MV(1, 1, mx
, my
-1)
213 CHECK_HALF_MV(1, 1, mx
-1, my
-1)
215 CHECK_HALF_MV(1, 1, mx
, my
)
217 CHECK_HALF_MV(1, 0, mx
, my
)
222 CHECK_HALF_MV(1, 1, mx
-1, my
-1)
224 CHECK_HALF_MV(1, 1, mx
, my
)
226 CHECK_HALF_MV(1, 0, mx
-1, my
)
227 CHECK_HALF_MV(1, 1, mx
-1, my
)
230 CHECK_HALF_MV(1, 1, mx
, my
-1)
232 CHECK_HALF_MV(1, 1, mx
-1, my
)
234 CHECK_HALF_MV(1, 0, mx
, my
)
235 CHECK_HALF_MV(1, 1, mx
, my
)
237 CHECK_HALF_MV(0, 1, mx
, my
)
239 assert(bx
>= xmin
*2 && bx
<= xmax
*2 && by
>= ymin
*2 && by
<= ymax
*2);
249 static int RENAME(hpel_get_mb_score
)(MpegEncContext
* s
, int mx
, int my
, int pred_x
, int pred_y
, uint8_t *src_data
[3],
250 uint8_t *ref_data
[3], int stride
, int uvstride
,
251 uint8_t * const mv_penalty
)
253 // const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;
256 const int penalty_factor
= s
->me
.mb_penalty_factor
;
257 me_cmp_func cmp_sub
, chroma_cmp_sub
;
264 cmp_sub
= s
->dsp
.mb_cmp
[size
];
265 chroma_cmp_sub
= s
->dsp
.mb_cmp
[size
+1];
268 assert(s
->avctx
->me_sub_cmp
!= s
->avctx
->mb_cmp
);
270 CMP_HPEL(d
, mx
&1, my
&1, mx
>>1, my
>>1, size
);
271 //FIXME check cbp before adding penalty for (0,0) vector
272 if(mx
|| my
|| size
>0)
273 d
+= (mv_penalty
[mx
- pred_x
] + mv_penalty
[my
- pred_y
])*penalty_factor
;
278 #endif /* CMP_HPEL */
284 #define CHECK_QUARTER_MV(dx, dy, x, y)\
286 const int hx= 4*(x)+(dx);\
287 const int hy= 4*(y)+(dy);\
288 CMP_QPEL(d, dx, dy, x, y, size);\
289 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
290 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
293 static int RENAME(qpel_motion_search
)(MpegEncContext
* s
,
294 int *mx_ptr
, int *my_ptr
, int dmin
,
295 int pred_x
, int pred_y
, uint8_t *src_data
[3],
296 uint8_t *ref_data
[3], int stride
, int uvstride
,
297 int size
, int h
, uint8_t * const mv_penalty
)
299 const int mx
= *mx_ptr
;
300 const int my
= *my_ptr
;
301 const int penalty_factor
= s
->me
.sub_penalty_factor
;
302 const int map_generation
= s
->me
.map_generation
;
303 const int subpel_quality
= s
->avctx
->me_subpel_quality
;
304 uint32_t *map
= s
->me
.map
;
305 me_cmp_func cmp
, chroma_cmp
;
306 me_cmp_func cmp_sub
, chroma_cmp_sub
;
310 cmp
= s
->dsp
.me_cmp
[size
];
311 chroma_cmp
= s
->dsp
.me_cmp
[size
+1]; //factorize FIXME
314 cmp_sub
= s
->dsp
.me_sub_cmp
[size
];
315 chroma_cmp_sub
= s
->dsp
.me_sub_cmp
[size
+1];
317 if(s
->me
.skip
){ //FIXME somehow move up (benchmark)
323 if(s
->avctx
->me_cmp
!= s
->avctx
->me_sub_cmp
){
324 CMP_QPEL(dmin
, 0, 0, mx
, my
, size
);
325 if(mx
|| my
|| size
>0)
326 dmin
+= (mv_penalty
[4*mx
- pred_x
] + mv_penalty
[4*my
- pred_y
])*penalty_factor
;
329 if (mx
> xmin
&& mx
< xmax
&&
330 my
> ymin
&& my
< ymax
) {
331 int bx
=4*mx
, by
=4*my
;
334 const int index
= (my
<<ME_MAP_SHIFT
) + mx
;
335 const int t
= score_map
[(index
-(1<<ME_MAP_SHIFT
) )&(ME_MAP_SIZE
-1)];
336 const int l
= score_map
[(index
- 1 )&(ME_MAP_SIZE
-1)];
337 const int r
= score_map
[(index
+ 1 )&(ME_MAP_SIZE
-1)];
338 const int b
= score_map
[(index
+(1<<ME_MAP_SHIFT
) )&(ME_MAP_SIZE
-1)];
339 const int c
= score_map
[(index
)&(ME_MAP_SIZE
-1)];
343 memset(best
, 64, sizeof(int)*8);
345 if(s
->me
.dia_size
>=2){
346 const int tl
= score_map
[(index
-(1<<ME_MAP_SHIFT
)-1)&(ME_MAP_SIZE
-1)];
347 const int bl
= score_map
[(index
+(1<<ME_MAP_SHIFT
)-1)&(ME_MAP_SIZE
-1)];
348 const int tr
= score_map
[(index
-(1<<ME_MAP_SHIFT
)+1)&(ME_MAP_SIZE
-1)];
349 const int br
= score_map
[(index
+(1<<ME_MAP_SHIFT
)+1)&(ME_MAP_SIZE
-1)];
351 for(ny
= -3; ny
<= 3; ny
++){
352 for(nx
= -3; nx
<= 3; nx
++){
353 const int t2
= nx
*nx
*(tr
+ tl
- 2*t
) + 4*nx
*(tr
-tl
) + 32*t
;
354 const int c2
= nx
*nx
*( r
+ l
- 2*c
) + 4*nx
*( r
- l
) + 32*c
;
355 const int b2
= nx
*nx
*(br
+ bl
- 2*b
) + 4*nx
*(br
-bl
) + 32*b
;
356 int score
= ny
*ny
*(b2
+ t2
- 2*c2
) + 4*ny
*(b2
- t2
) + 32*c2
;
359 if((nx
&3)==0 && (ny
&3)==0) continue;
361 score
+= 1024*(mv_penalty
[4*mx
+ nx
- pred_x
] + mv_penalty
[4*my
+ ny
- pred_y
])*penalty_factor
;
363 // if(nx&1) score-=1024*s->me.penalty_factor;
364 // if(ny&1) score-=1024*s->me.penalty_factor;
368 memmove(&best
[i
+1], &best
[i
], sizeof(int)*(7-i
));
369 memmove(&best_pos
[i
+1][0], &best_pos
[i
][0], sizeof(int)*2*(7-i
));
371 best_pos
[i
][0]= nx
+ 4*mx
;
372 best_pos
[i
][1]= ny
+ 4*my
;
380 const int cx
= 4*(r
- l
);
381 const int cx2
= r
+ l
- 2*c
;
382 const int cy
= 4*(b
- t
);
383 const int cy2
= b
+ t
- 2*c
;
386 if(map
[(index
-(1<<ME_MAP_SHIFT
)-1)&(ME_MAP_SIZE
-1)] == (my
<<ME_MAP_MV_BITS
) + mx
+ map_generation
&& 0){ //FIXME
387 tl
= score_map
[(index
-(1<<ME_MAP_SHIFT
)-1)&(ME_MAP_SIZE
-1)];
389 CMP(tl
, mx
-1, my
-1, size
); //FIXME wrong if chroma me is different
392 cxy
= 2*tl
+ (cx
+ cy
)/4 - (cx2
+ cy2
) - 2*c
;
394 assert(16*cx2
+ 4*cx
+ 32*c
== 32*r
);
395 assert(16*cx2
- 4*cx
+ 32*c
== 32*l
);
396 assert(16*cy2
+ 4*cy
+ 32*c
== 32*b
);
397 assert(16*cy2
- 4*cy
+ 32*c
== 32*t
);
398 assert(16*cxy
+ 16*cy2
+ 16*cx2
- 4*cy
- 4*cx
+ 32*c
== 32*tl
);
400 for(ny
= -3; ny
<= 3; ny
++){
401 for(nx
= -3; nx
<= 3; nx
++){
402 int score
= ny
*nx
*cxy
+ nx
*nx
*cx2
+ ny
*ny
*cy2
+ nx
*cx
+ ny
*cy
+ 32*c
; //FIXME factor
405 if((nx
&3)==0 && (ny
&3)==0) continue;
407 score
+= 32*(mv_penalty
[4*mx
+ nx
- pred_x
] + mv_penalty
[4*my
+ ny
- pred_y
])*penalty_factor
;
408 // if(nx&1) score-=32*s->me.penalty_factor;
409 // if(ny&1) score-=32*s->me.penalty_factor;
413 memmove(&best
[i
+1], &best
[i
], sizeof(int)*(7-i
));
414 memmove(&best_pos
[i
+1][0], &best_pos
[i
][0], sizeof(int)*2*(7-i
));
416 best_pos
[i
][0]= nx
+ 4*mx
;
417 best_pos
[i
][1]= ny
+ 4*my
;
424 for(i
=0; i
<subpel_quality
; i
++){
427 CHECK_QUARTER_MV(nx
&3, ny
&3, nx
>>2, ny
>>2)
431 const int tl
= score_map
[(index
-(1<<ME_MAP_SHIFT
)-1)&(ME_MAP_SIZE
-1)];
432 const int bl
= score_map
[(index
+(1<<ME_MAP_SHIFT
)-1)&(ME_MAP_SIZE
-1)];
433 const int tr
= score_map
[(index
-(1<<ME_MAP_SHIFT
)+1)&(ME_MAP_SIZE
-1)];
434 const int br
= score_map
[(index
+(1<<ME_MAP_SHIFT
)+1)&(ME_MAP_SIZE
-1)];
435 // if(l < r && l < t && l < b && l < tl && l < bl && l < tr && l < br && bl < tl){
438 // nx= FFMAX(4*mx - bx, bx - 4*mx);
439 // ny= FFMAX(4*my - by, by - 4*my);
441 static int stats
[7][7], count
;
443 stats
[4*mx
- bx
+ 3][4*my
- by
+ 3]++;
444 if(256*256*256*64 % count
==0){
446 if((i
%7)==0) printf("\n");
447 printf("%6d ", stats
[0][i
]);
455 CHECK_QUARTER_MV(2, 2, mx
-1, my
-1)
456 CHECK_QUARTER_MV(0, 2, mx
, my
-1)
457 CHECK_QUARTER_MV(2, 2, mx
, my
-1)
458 CHECK_QUARTER_MV(2, 0, mx
, my
)
459 CHECK_QUARTER_MV(2, 2, mx
, my
)
460 CHECK_QUARTER_MV(0, 2, mx
, my
)
461 CHECK_QUARTER_MV(2, 2, mx
-1, my
)
462 CHECK_QUARTER_MV(2, 0, mx
-1, my
)
468 int ox
[8]= {0, 1, 1, 1, 0,-1,-1,-1};
469 int oy
[8]= {1, 1, 0,-1,-1,-1, 0, 1};
470 CHECK_QUARTER_MV((nx
+ ox
[i
])&3, (ny
+ oy
[i
])&3, (nx
+ ox
[i
])>>2, (ny
+ oy
[i
])>>2)
475 CHECK_QUARTER_MV(1, 3, mx
-1, my
-1)
476 CHECK_QUARTER_MV(1, 2, mx
-1, my
-1)
477 CHECK_QUARTER_MV(1, 1, mx
-1, my
-1)
478 CHECK_QUARTER_MV(2, 1, mx
-1, my
-1)
479 CHECK_QUARTER_MV(3, 1, mx
-1, my
-1)
480 CHECK_QUARTER_MV(0, 1, mx
, my
-1)
481 CHECK_QUARTER_MV(1, 1, mx
, my
-1)
482 CHECK_QUARTER_MV(2, 1, mx
, my
-1)
483 CHECK_QUARTER_MV(3, 1, mx
, my
-1)
484 CHECK_QUARTER_MV(3, 2, mx
, my
-1)
485 CHECK_QUARTER_MV(3, 3, mx
, my
-1)
486 CHECK_QUARTER_MV(3, 0, mx
, my
)
487 CHECK_QUARTER_MV(3, 1, mx
, my
)
488 CHECK_QUARTER_MV(3, 2, mx
, my
)
489 CHECK_QUARTER_MV(3, 3, mx
, my
)
490 CHECK_QUARTER_MV(2, 3, mx
, my
)
491 CHECK_QUARTER_MV(1, 3, mx
, my
)
492 CHECK_QUARTER_MV(0, 3, mx
, my
)
493 CHECK_QUARTER_MV(3, 3, mx
-1, my
)
494 CHECK_QUARTER_MV(2, 3, mx
-1, my
)
495 CHECK_QUARTER_MV(1, 3, mx
-1, my
)
496 CHECK_QUARTER_MV(1, 2, mx
-1, my
)
497 CHECK_QUARTER_MV(1, 1, mx
-1, my
)
498 CHECK_QUARTER_MV(1, 0, mx
-1, my
)
500 assert(bx
>= xmin
*4 && bx
<= xmax
*4 && by
>= ymin
*4 && by
<= ymax
*4);
512 static int RENAME(qpel_get_mb_score
)(MpegEncContext
* s
, int mx
, int my
, int pred_x
, int pred_y
, uint8_t *src_data
[3],
513 uint8_t *ref_data
[3], int stride
, int uvstride
,
514 uint8_t * const mv_penalty
)
518 const int penalty_factor
= s
->me
.mb_penalty_factor
;
519 me_cmp_func cmp_sub
, chroma_cmp_sub
;
526 cmp_sub
= s
->dsp
.mb_cmp
[size
];
527 chroma_cmp_sub
= s
->dsp
.mb_cmp
[size
+1];
530 assert(s
->avctx
->me_sub_cmp
!= s
->avctx
->mb_cmp
);
532 CMP_QPEL(d
, mx
&3, my
&3, mx
>>2, my
>>2, size
);
533 //FIXME check cbp before adding penalty for (0,0) vector
534 if(mx
|| my
|| size
>0)
535 d
+= (mv_penalty
[mx
- pred_x
] + mv_penalty
[my
- pred_y
])*penalty_factor
;
541 #endif /* CMP_QPEL */
543 #define CHECK_MV(x,y)\
545 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
546 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
547 /*printf("check_mv %d %d\n", x, y);*/\
548 if(map[index]!=key){\
551 score_map[index]= d;\
552 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\
553 /*printf("score:%d\n", d);*/\
554 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
558 #define CHECK_CLIPED_MV(ax,ay)\
560 const int x= FFMAX(xmin, FFMIN(ax, xmax));\
561 const int y= FFMAX(ymin, FFMIN(ay, ymax));\
565 #define CHECK_MV_DIR(x,y,new_dir)\
567 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
568 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
569 /*printf("check_mv_dir %d %d %d\n", x, y, new_dir);*/\
570 if(map[index]!=key){\
573 score_map[index]= d;\
574 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\
575 /*printf("score:%d\n", d);*/\
585 #define check(x,y,S,v)\
586 if( (x)<(xmin<<(S)) ) printf("%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
587 if( (x)>(xmax<<(S)) ) printf("%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
588 if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
589 if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
592 static inline int RENAME(small_diamond_search)(MpegEncContext * s, int *best, int dmin,
593 uint8_t *src_data
[3],
594 uint8_t *ref_data
[3], int stride
, int uvstride
,
595 int const pred_x
, int const pred_y
, int const penalty_factor
,
597 uint32_t *map
, int map_generation
, int size
, int h
, uint8_t * const mv_penalty
600 me_cmp_func cmp
, chroma_cmp
;
604 cmp
= s
->dsp
.me_cmp
[size
];
605 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
607 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
608 const int key
= (best
[1]<<ME_MAP_MV_BITS
) + best
[0] + map_generation
;
609 const int index
= ((best
[1]<<ME_MAP_SHIFT
) + best
[0])&(ME_MAP_SIZE
-1);
610 if(map
[index
]!=key
){ //this will be executed only very rarey
611 CMP(score_map
[index
], best
[0], best
[1], size
);
618 const int dir
= next_dir
;
619 const int x
= best
[0];
620 const int y
= best
[1];
624 if(dir
!=2 && x
>xmin
) CHECK_MV_DIR(x
-1, y
, 0)
625 if(dir
!=3 && y
>ymin
) CHECK_MV_DIR(x
, y
-1, 1)
626 if(dir
!=0 && x
<xmax
) CHECK_MV_DIR(x
+1, y
, 2)
627 if(dir
!=1 && y
<ymax
) CHECK_MV_DIR(x
, y
+1, 3)
635 static inline int RENAME(funny_diamond_search
)(MpegEncContext
* s
, int *best
, int dmin
,
636 uint8_t *src_data
[3],
637 uint8_t *ref_data
[3], int stride
, int uvstride
,
638 int const pred_x
, int const pred_y
, int const penalty_factor
,
640 uint32_t *map
, int map_generation
, int size
, int h
, uint8_t * const mv_penalty
643 me_cmp_func cmp
, chroma_cmp
;
647 cmp
= s
->dsp
.me_cmp
[size
];
648 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
650 for(dia_size
=1; dia_size
<=4; dia_size
++){
652 const int x
= best
[0];
653 const int y
= best
[1];
655 if(dia_size
&(dia_size
-1)) continue;
657 if( x
+ dia_size
> xmax
658 || x
- dia_size
< xmin
659 || y
+ dia_size
> ymax
660 || y
- dia_size
< ymin
)
663 for(dir
= 0; dir
<dia_size
; dir
+=2){
666 CHECK_MV(x
+ dir
, y
+ dia_size
- dir
);
667 CHECK_MV(x
+ dia_size
- dir
, y
- dir
);
668 CHECK_MV(x
- dir
, y
- dia_size
+ dir
);
669 CHECK_MV(x
- dia_size
+ dir
, y
+ dir
);
672 if(x
!=best
[0] || y
!=best
[1])
677 static int stats
[8*8];
681 dx
^=dy
; dy
^=dx
; dx
^=dy
;
684 if(256*256*256*64 % (stats
[0]+1)==0){
686 if((i
&7)==0) printf("\n");
687 printf("%8d ", stats
[i
]);
697 #define SAB_CHECK_MV(ax,ay)\
699 const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
700 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
701 /*printf("sab check %d %d\n", ax, ay);*/\
702 if(map[index]!=key){\
703 CMP(d, ax, ay, size);\
705 score_map[index]= d;\
706 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
707 /*printf("score: %d\n", d);*/\
708 if(d < minima[minima_count-1].height){\
711 while(d >= minima[j].height) j++;\
713 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
715 minima[j].checked= 0;\
716 minima[j].height= d;\
726 #define MAX_SAB_SIZE 16
727 static inline int RENAME(sab_diamond_search
)(MpegEncContext
* s
, int *best
, int dmin
,
728 uint8_t *src_data
[3],
729 uint8_t *ref_data
[3], int stride
, int uvstride
,
730 int const pred_x
, int const pred_y
, int const penalty_factor
,
732 uint32_t *map
, int map_generation
, int size
, int h
, uint8_t * const mv_penalty
735 me_cmp_func cmp
, chroma_cmp
;
736 Minima minima
[MAX_SAB_SIZE
];
737 const int minima_count
= ABS(s
->me
.dia_size
);
741 cmp
= s
->dsp
.me_cmp
[size
];
742 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
744 for(j
=i
=0; i
<ME_MAP_SIZE
; i
++){
745 uint32_t key
= map
[i
];
747 key
+= (1<<(ME_MAP_MV_BITS
-1)) + (1<<(2*ME_MAP_MV_BITS
-1));
749 if((key
&((-1)<<(2*ME_MAP_MV_BITS
))) != map_generation
) continue;
751 assert(j
<MAX_SAB_SIZE
); //max j = number of predictors
753 minima
[j
].height
= score_map
[i
];
754 minima
[j
].x
= key
& ((1<<ME_MAP_MV_BITS
)-1); key
>>=ME_MAP_MV_BITS
;
755 minima
[j
].y
= key
& ((1<<ME_MAP_MV_BITS
)-1);
756 minima
[j
].x
-= (1<<(ME_MAP_MV_BITS
-1));
757 minima
[j
].y
-= (1<<(ME_MAP_MV_BITS
-1));
759 if(minima
[j
].x
|| minima
[j
].y
)
760 minima
[j
].height
+= (mv_penalty
[((minima
[j
].x
)<<shift
)-pred_x
] + mv_penalty
[((minima
[j
].y
)<<shift
)-pred_y
])*penalty_factor
;
765 qsort(minima
, j
, sizeof(Minima
), minima_cmp
);
767 for(; j
<minima_count
; j
++){
768 minima
[j
].height
=256*256*256*64;
770 minima
[j
].x
= minima
[j
].y
=0;
773 for(i
=0; i
<minima_count
; i
++){
774 const int x
= minima
[i
].x
;
775 const int y
= minima
[i
].y
;
778 if(minima
[i
].checked
) continue;
780 if( x
>= xmax
|| x
<= xmin
781 || y
>= ymax
|| y
<= ymin
)
786 SAB_CHECK_MV(x
, y
-1)
787 SAB_CHECK_MV(x
, y
+1)
789 minima
[i
].checked
= 1;
792 best
[0]= minima
[0].x
;
793 best
[1]= minima
[0].y
;
794 dmin
= minima
[0].height
;
796 if( best
[0] < xmax
&& best
[0] > xmin
797 && best
[1] < ymax
&& best
[1] > ymin
){
799 //ensure that the refernece samples for hpel refinement are in the map
800 CHECK_MV(best
[0]-1, best
[1])
801 CHECK_MV(best
[0]+1, best
[1])
802 CHECK_MV(best
[0], best
[1]-1)
803 CHECK_MV(best
[0], best
[1]+1)
808 static inline int RENAME(var_diamond_search
)(MpegEncContext
* s
, int *best
, int dmin
,
809 uint8_t *src_data
[3],
810 uint8_t *ref_data
[3], int stride
, int uvstride
,
811 int const pred_x
, int const pred_y
, int const penalty_factor
,
813 uint32_t *map
, int map_generation
, int size
, int h
, uint8_t * const mv_penalty
816 me_cmp_func cmp
, chroma_cmp
;
820 cmp
= s
->dsp
.me_cmp
[size
];
821 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
823 for(dia_size
=1; dia_size
<=s
->me
.dia_size
; dia_size
++){
825 const int x
= best
[0];
826 const int y
= best
[1];
828 start
= FFMAX(0, y
+ dia_size
- ymax
);
829 end
= FFMIN(dia_size
, xmax
- x
+ 1);
830 for(dir
= start
; dir
<end
; dir
++){
833 //check(x + dir,y + dia_size - dir,0, a0)
834 CHECK_MV(x
+ dir
, y
+ dia_size
- dir
);
837 start
= FFMAX(0, x
+ dia_size
- xmax
);
838 end
= FFMIN(dia_size
, y
- ymin
+ 1);
839 for(dir
= start
; dir
<end
; dir
++){
842 //check(x + dia_size - dir, y - dir,0, a1)
843 CHECK_MV(x
+ dia_size
- dir
, y
- dir
);
846 start
= FFMAX(0, -y
+ dia_size
+ ymin
);
847 end
= FFMIN(dia_size
, x
- xmin
+ 1);
848 for(dir
= start
; dir
<end
; dir
++){
851 //check(x - dir,y - dia_size + dir,0, a2)
852 CHECK_MV(x
- dir
, y
- dia_size
+ dir
);
855 start
= FFMAX(0, -x
+ dia_size
+ xmin
);
856 end
= FFMIN(dia_size
, ymax
- y
+ 1);
857 for(dir
= start
; dir
<end
; dir
++){
860 //check(x - dia_size + dir, y + dir,0, a3)
861 CHECK_MV(x
- dia_size
+ dir
, y
+ dir
);
864 if(x
!=best
[0] || y
!=best
[1])
869 static int stats
[8*8];
873 if(256*256*256*64 % (stats
[0]+1)==0){
875 if((i
&7)==0) printf("\n");
876 printf("%6d ", stats
[i
]);
886 static int RENAME(epzs_motion_search
)(MpegEncContext
* s
,
887 int *mx_ptr
, int *my_ptr
,
888 int P
[10][2], int pred_x
, int pred_y
, uint8_t *src_data
[3],
889 uint8_t *ref_data
[3], int stride
, int uvstride
, int16_t (*last_mv
)[2],
890 int ref_mv_scale
, uint8_t * const mv_penalty
)
894 const int shift
= 1+s
->quarter_sample
;
895 uint32_t *map
= s
->me
.map
;
897 const int penalty_factor
= s
->me
.penalty_factor
;
900 const int ref_mv_stride
= s
->mb_stride
; //pass as arg FIXME
901 const int ref_mv_xy
= s
->mb_x
+ s
->mb_y
*ref_mv_stride
; //add to last_mv beforepassing FIXME
902 me_cmp_func cmp
, chroma_cmp
;
905 cmp
= s
->dsp
.me_cmp
[size
];
906 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
908 map_generation
= update_map_generation(s
);
910 CMP(dmin
, 0, 0, size
);
911 map
[0]= map_generation
;
916 CHECK_MV(P_LEFT
[0]>>shift
, P_LEFT
[1]>>shift
)
917 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
][0]*ref_mv_scale
+ (1<<15))>>16,
918 (last_mv
[ref_mv_xy
][1]*ref_mv_scale
+ (1<<15))>>16)
920 if(dmin
<256 && ( P_LEFT
[0] |P_LEFT
[1]
922 |P_TOPRIGHT
[0]|P_TOPRIGHT
[1])==0){
928 CHECK_MV(P_MEDIAN
[0]>>shift
, P_MEDIAN
[1]>>shift
)
930 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
][0]*ref_mv_scale
+ (1<<15))>>16,
931 (last_mv
[ref_mv_xy
][1]*ref_mv_scale
+ (1<<15))>>16)
932 CHECK_MV(P_LEFT
[0] >>shift
, P_LEFT
[1] >>shift
)
933 CHECK_MV(P_TOP
[0] >>shift
, P_TOP
[1] >>shift
)
934 CHECK_MV(P_TOPRIGHT
[0]>>shift
, P_TOPRIGHT
[1]>>shift
)
939 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
-1][0]*ref_mv_scale
+ (1<<15))>>16,
940 (last_mv
[ref_mv_xy
-1][1]*ref_mv_scale
+ (1<<15))>>16)
941 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
-ref_mv_stride
][0]*ref_mv_scale
+ (1<<15))>>16,
942 (last_mv
[ref_mv_xy
-ref_mv_stride
][1]*ref_mv_scale
+ (1<<15))>>16)
944 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
+1][0]*ref_mv_scale
+ (1<<15))>>16,
945 (last_mv
[ref_mv_xy
+1][1]*ref_mv_scale
+ (1<<15))>>16)
946 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
+ref_mv_stride
][0]*ref_mv_scale
+ (1<<15))>>16,
947 (last_mv
[ref_mv_xy
+ref_mv_stride
][1]*ref_mv_scale
+ (1<<15))>>16)
951 if(s
->avctx
->last_predictor_count
){
952 const int count
= s
->avctx
->last_predictor_count
;
953 const int xstart
= FFMAX(0, s
->mb_x
- count
);
954 const int ystart
= FFMAX(0, s
->mb_y
- count
);
955 const int xend
= FFMIN(s
->mb_width
, s
->mb_x
+ count
+ 1);
956 const int yend
= FFMIN(s
->mb_height
, s
->mb_y
+ count
+ 1);
959 for(mb_y
=ystart
; mb_y
<yend
; mb_y
++){
961 for(mb_x
=xstart
; mb_x
<xend
; mb_x
++){
962 const int xy
= mb_x
+ 1 + (mb_y
+ 1)*ref_mv_stride
;
963 int mx
= (last_mv
[xy
][0]*ref_mv_scale
+ (1<<15))>>16;
964 int my
= (last_mv
[xy
][1]*ref_mv_scale
+ (1<<15))>>16;
966 if(mx
>xmax
|| mx
<xmin
|| my
>ymax
|| my
<ymin
) continue;
972 //check(best[0],best[1],0, b0)
973 if(s
->me
.dia_size
==-1)
974 dmin
= RENAME(funny_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
975 pred_x
, pred_y
, penalty_factor
,
976 shift
, map
, map_generation
, size
, h
, mv_penalty
);
977 else if(s
->me
.dia_size
<-1)
978 dmin
= RENAME(sab_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
979 pred_x
, pred_y
, penalty_factor
,
980 shift
, map
, map_generation
, size
, h
, mv_penalty
);
981 else if(s
->me
.dia_size
<2)
982 dmin
= RENAME(small_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
983 pred_x
, pred_y
, penalty_factor
,
984 shift
, map
, map_generation
, size
, h
, mv_penalty
);
986 dmin
= RENAME(var_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
987 pred_x
, pred_y
, penalty_factor
,
988 shift
, map
, map_generation
, size
, h
, mv_penalty
);
990 //check(best[0],best[1],0, b1)
994 // printf("%d %d %d \n", best[0], best[1], dmin);
998 #ifndef CMP_DIRECT /* no 4mv search needed in direct mode */
999 static int RENAME(epzs_motion_search4
)(MpegEncContext
* s
,
1000 int *mx_ptr
, int *my_ptr
,
1001 int P
[10][2], int pred_x
, int pred_y
,
1002 uint8_t *src_data
[3],
1003 uint8_t *ref_data
[3], int stride
, int uvstride
, int16_t (*last_mv
)[2],
1004 int ref_mv_scale
, uint8_t * const mv_penalty
)
1008 const int shift
= 1+s
->quarter_sample
;
1009 uint32_t *map
= s
->me
.map
;
1011 const int penalty_factor
= s
->me
.penalty_factor
;
1014 const int ref_mv_stride
= s
->mb_stride
;
1015 const int ref_mv_xy
= s
->mb_x
+ s
->mb_y
*ref_mv_stride
;
1016 me_cmp_func cmp
, chroma_cmp
;
1019 cmp
= s
->dsp
.me_cmp
[size
];
1020 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
1022 map_generation
= update_map_generation(s
);
1025 //printf("%d %d %d %d //",xmin, ymin, xmax, ymax);
1027 if (s
->mb_y
== 0/* && block<2*/) {
1028 CHECK_MV(P_LEFT
[0]>>shift
, P_LEFT
[1]>>shift
)
1029 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
][0]*ref_mv_scale
+ (1<<15))>>16,
1030 (last_mv
[ref_mv_xy
][1]*ref_mv_scale
+ (1<<15))>>16)
1031 CHECK_MV(P_MV1
[0]>>shift
, P_MV1
[1]>>shift
)
1033 CHECK_MV(P_MV1
[0]>>shift
, P_MV1
[1]>>shift
)
1034 //FIXME try some early stop
1036 CHECK_MV(P_MEDIAN
[0]>>shift
, P_MEDIAN
[1]>>shift
)
1037 CHECK_MV(P_LEFT
[0]>>shift
, P_LEFT
[1]>>shift
)
1038 CHECK_MV(P_TOP
[0]>>shift
, P_TOP
[1]>>shift
)
1039 CHECK_MV(P_TOPRIGHT
[0]>>shift
, P_TOPRIGHT
[1]>>shift
)
1040 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
][0]*ref_mv_scale
+ (1<<15))>>16,
1041 (last_mv
[ref_mv_xy
][1]*ref_mv_scale
+ (1<<15))>>16)
1045 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
+1][0]*ref_mv_scale
+ (1<<15))>>16,
1046 (last_mv
[ref_mv_xy
+1][1]*ref_mv_scale
+ (1<<15))>>16)
1047 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
+ref_mv_stride
][0]*ref_mv_scale
+ (1<<15))>>16,
1048 (last_mv
[ref_mv_xy
+ref_mv_stride
][1]*ref_mv_scale
+ (1<<15))>>16)
1051 if(s
->me
.dia_size
==-1)
1052 dmin
= RENAME(funny_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1053 pred_x
, pred_y
, penalty_factor
,
1054 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1055 else if(s
->me
.dia_size
<-1)
1056 dmin
= RENAME(sab_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1057 pred_x
, pred_y
, penalty_factor
,
1058 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1059 else if(s
->me
.dia_size
<2)
1060 dmin
= RENAME(small_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1061 pred_x
, pred_y
, penalty_factor
,
1062 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1064 dmin
= RENAME(var_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1065 pred_x
, pred_y
, penalty_factor
,
1066 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1072 // printf("%d %d %d \n", best[0], best[1], dmin);
1076 //try to merge with above FIXME (needs PSNR test)
1077 static int RENAME(epzs_motion_search2
)(MpegEncContext
* s
,
1078 int *mx_ptr
, int *my_ptr
,
1079 int P
[10][2], int pred_x
, int pred_y
,
1080 uint8_t *src_data
[3],
1081 uint8_t *ref_data
[3], int stride
, int uvstride
, int16_t (*last_mv
)[2],
1082 int ref_mv_scale
, uint8_t * const mv_penalty
)
1086 const int shift
= 1+s
->quarter_sample
;
1087 uint32_t *map
= s
->me
.map
;
1089 const int penalty_factor
= s
->me
.penalty_factor
;
1090 const int size
=0; //FIXME pass as arg
1092 const int ref_mv_stride
= s
->mb_stride
;
1093 const int ref_mv_xy
= s
->mb_x
+ s
->mb_y
*ref_mv_stride
;
1094 me_cmp_func cmp
, chroma_cmp
;
1097 cmp
= s
->dsp
.me_cmp
[size
];
1098 chroma_cmp
= s
->dsp
.me_cmp
[size
+1];
1100 map_generation
= update_map_generation(s
);
1103 //printf("%d %d %d %d //",xmin, ymin, xmax, ymax);
1106 CHECK_MV(P_LEFT
[0]>>shift
, P_LEFT
[1]>>shift
)
1107 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
][0]*ref_mv_scale
+ (1<<15))>>16,
1108 (last_mv
[ref_mv_xy
][1]*ref_mv_scale
+ (1<<15))>>16)
1109 CHECK_MV(P_MV1
[0]>>shift
, P_MV1
[1]>>shift
)
1111 CHECK_MV(P_MV1
[0]>>shift
, P_MV1
[1]>>shift
)
1112 //FIXME try some early stop
1114 CHECK_MV(P_MEDIAN
[0]>>shift
, P_MEDIAN
[1]>>shift
)
1115 CHECK_MV(P_LEFT
[0]>>shift
, P_LEFT
[1]>>shift
)
1116 CHECK_MV(P_TOP
[0]>>shift
, P_TOP
[1]>>shift
)
1117 CHECK_MV(P_TOPRIGHT
[0]>>shift
, P_TOPRIGHT
[1]>>shift
)
1118 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
][0]*ref_mv_scale
+ (1<<15))>>16,
1119 (last_mv
[ref_mv_xy
][1]*ref_mv_scale
+ (1<<15))>>16)
1123 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
+1][0]*ref_mv_scale
+ (1<<15))>>16,
1124 (last_mv
[ref_mv_xy
+1][1]*ref_mv_scale
+ (1<<15))>>16)
1125 CHECK_CLIPED_MV((last_mv
[ref_mv_xy
+ref_mv_stride
][0]*ref_mv_scale
+ (1<<15))>>16,
1126 (last_mv
[ref_mv_xy
+ref_mv_stride
][1]*ref_mv_scale
+ (1<<15))>>16)
1129 if(s
->me
.dia_size
==-1)
1130 dmin
= RENAME(funny_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1131 pred_x
, pred_y
, penalty_factor
,
1132 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1133 else if(s
->me
.dia_size
<-1)
1134 dmin
= RENAME(sab_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1135 pred_x
, pred_y
, penalty_factor
,
1136 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1137 else if(s
->me
.dia_size
<2)
1138 dmin
= RENAME(small_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1139 pred_x
, pred_y
, penalty_factor
,
1140 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1142 dmin
= RENAME(var_diamond_search
)(s
, best
, dmin
, src_data
, ref_data
, stride
, uvstride
,
1143 pred_x
, pred_y
, penalty_factor
,
1144 shift
, map
, map_generation
, size
, h
, mv_penalty
);
1150 // printf("%d %d %d \n", best[0], best[1], dmin);
1153 #endif /* !CMP_DIRECT */