1 /*
2 * Motion estimation
3 * Copyright (c) 2002-2004 Michael Niedermayer
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * Motion estimation template.
25 */
26
27 //Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
29 uint32_t av_unused * const score_map= c->score_map;\
30 const int av_unused xmin= c->xmin;\
31 const int av_unused ymin= c->ymin;\
32 const int av_unused xmax= c->xmax;\
33 const int av_unused ymax= c->ymax;\
34 uint8_t *mv_penalty= c->current_mv_penalty;\
35 const int pred_x= c->pred_x;\
36 const int pred_y= c->pred_y;\
37
38 #define CHECK_HALF_MV(dx, dy, x, y)\
39 {\
40 const int hx= 2*(x)+(dx);\
41 const int hy= 2*(y)+(dy);\
42 d= cmp_hpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\
43 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
44 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
45 }
46
48 int *mx_ptr, int *my_ptr, int dmin,
49 int src_index, int ref_index,
51 {
53 const int mx = *mx_ptr;
54 const int my = *my_ptr;
57 int bx=2*mx, by=2*my;
58
61
62 //FIXME factorize
63
66
67 if(c->
skip){
//FIXME move out of hpel?
68 *mx_ptr = 0;
69 *my_ptr = 0;
70 return dmin;
71 }
72
74 dmin=
cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
75 if(mx || my || size>0)
77 }
78
79 if (mx > xmin && mx < xmax &&
80 my > ymin && my < ymax) {
81 int d= dmin;
91
92 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
93 unsigned key;
103 #endif
104 if(t<=b){
110 }else{
112 }
114 }else{
118 }else{
120 }
122 }
123 }else{
127 }else{
129 }
132 }else{
135 }else{
137 }
140 }
142 }
143 av_assert2(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
144 }
145
146 *mx_ptr = bx;
147 *my_ptr = by;
148
149 return dmin;
150 }
151
153 int *mx_ptr, int *my_ptr, int dmin,
154 int src_index, int ref_index,
156 {
157 (*mx_ptr)<<=1;
158 (*my_ptr)<<=1;
159 return dmin;
160 }
161
163 int src_index,
int ref_index,
int size,
164 int h, int add_rate)
165 {
166 // const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;
171 const int mask= 1+2*qpel;
173 int d;
174
176
177 //FIXME factorize
178
181
182 d=
cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
183 //FIXME check cbp before adding penalty for (0,0) vector
184 if(add_rate && (mx || my || size>0))
186
187 return d;
188 }
189
191 int ref_index,
int size,
int h,
int add_rate)
192 {
193 return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
194 }
195
196 #define CHECK_QUARTER_MV(dx, dy, x, y)\
197 {\
198 const int hx= 4*(x)+(dx);\
199 const int hy= 4*(y)+(dy);\
200 d= cmp_qpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
201 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
202 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
203 }
204
206 int *mx_ptr, int *my_ptr, int dmin,
207 int src_index, int ref_index,
209 {
211 const int mx = *mx_ptr;
212 const int my = *my_ptr;
216 uint32_t *map= c->
map;
219
222
224 chroma_cmpf= s->
dsp.
me_cmp[size+1];
//factorize FIXME
225 //FIXME factorize
226
229
230 if(c->
skip){
//FIXME somehow move up (benchmark)
231 *mx_ptr = 0;
232 *my_ptr = 0;
233 return dmin;
234 }
235
237 dmin=
cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
238 if(mx || my || size>0)
240 }
241
242 if (mx > xmin && mx < xmax &&
243 my > ymin && my < ymax) {
244 int bx=4*mx, by=4*my;
245 int d= dmin;
246 int i, nx, ny;
249 const int l= score_map[(index- 1 )&(
ME_MAP_SIZE-1)];
253 int best[8];
254 int best_pos[8][2];
255
256 memset(best, 64, sizeof(int)*8);
262
263 for(ny= -3; ny <= 3; ny++){
264 for(nx= -3; nx <= 3; nx++){
265 //FIXME this could overflow (unlikely though)
266 const int64_t
t2= nx*nx*(tr + tl - 2*
t) + 4*nx*(tr-tl) + 32*
t;
267 const int64_t
c2= nx*nx*( r + l - 2*
c) + 4*nx*( r- l) + 32*
c;
268 const int64_t b2= nx*nx*(br + bl - 2*
b) + 4*nx*(br-bl) + 32*
b;
269 int score= (ny*ny*(b2 + t2 - 2*
c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10;
270 int i;
271
272 if((nx&3)==0 && (ny&3)==0) continue;
273
275
276 // if(nx&1) score-=1024*c->penalty_factor;
277 // if(ny&1) score-=1024*c->penalty_factor;
278
279 for(i=0; i<8; i++){
280 if(score < best[i]){
281 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
282 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
283 best[i]= score;
284 best_pos[i][0]= nx + 4*mx;
285 best_pos[i][1]= ny + 4*my;
286 break;
287 }
288 }
289 }
290 }
291 }else{
292 int tl;
293 //FIXME this could overflow (unlikely though)
294 const int cx = 4*(r - l);
295 const int cx2= r + l - 2*
c;
296 const int cy = 4*(b -
t);
297 const int cy2= b + t - 2*
c;
298 int cxy;
299
302 }else{
303 tl=
cmp(s, mx-1, my-1, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
//FIXME wrong if chroma me is different
304 }
305
306 cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*
c;
307
312 av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
313
314 for(ny= -3; ny <= 3; ny++){
315 for(nx= -3; nx <= 3; nx++){
316 //FIXME this could overflow (unlikely though)
317 int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*
c;
//FIXME factor
318 int i;
319
320 if((nx&3)==0 && (ny&3)==0) continue;
321
323 // if(nx&1) score-=32*c->penalty_factor;
324 // if(ny&1) score-=32*c->penalty_factor;
325
326 for(i=0; i<8; i++){
327 if(score < best[i]){
328 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
329 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
330 best[i]= score;
331 best_pos[i][0]= nx + 4*mx;
332 best_pos[i][1]= ny + 4*my;
333 break;
334 }
335 }
336 }
337 }
338 }
339 for(i=0; i<subpel_quality; i++){
340 nx= best_pos[i][0];
341 ny= best_pos[i][1];
343 }
344
345 av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
346
347 *mx_ptr = bx;
348 *my_ptr = by;
349 }else{
350 *mx_ptr =4*mx;
351 *my_ptr =4*my;
352 }
353
354 return dmin;
355 }
356
357
358 #define CHECK_MV(x,y)\
359 {\
360 const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
361 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
362 av_assert2((x) >= xmin);\
363 av_assert2((x) <= xmax);\
364 av_assert2((y) >= ymin);\
365 av_assert2((y) <= ymax);\
366 if(map[index]!=key){\
367 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
368 map[index]= key;\
369 score_map[index]= d;\
370 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\
371 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
372 }\
373 }
374
375 #define CHECK_CLIPPED_MV(ax,ay)\
376 {\
377 const int Lx= ax;\
378 const int Ly= ay;\
379 const int Lx2= FFMAX(xmin, FFMIN(Lx, xmax));\
380 const int Ly2= FFMAX(ymin, FFMIN(Ly, ymax));\
381 CHECK_MV(Lx2, Ly2)\
382 }
383
384 #define CHECK_MV_DIR(x,y,new_dir)\
385 {\
386 const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
387 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
388 if(map[index]!=key){\
389 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
390 map[index]= key;\
391 score_map[index]= d;\
392 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\
393 if(d<dmin){\
394 best[0]=x;\
395 best[1]=y;\
396 dmin=d;\
397 next_dir= new_dir;\
398 }\
399 }\
400 }
401
402 #define check(x,y,S,v)\
403 if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
404 if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
405 if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
406 if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
407
408 #define LOAD_COMMON2\
409 uint32_t *map= c->map;\
410 const int qpel= flags&FLAG_QPEL;\
411 const int shift= 1+qpel;\
412
414 int src_index, int ref_index, int const penalty_factor,
416 {
419 int next_dir=-1;
423
426
427 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
428 const unsigned key = (best[1]<<
ME_MAP_MV_BITS) + best[0] + map_generation;
430 if(map[index]!=key){ //this will be executed only very rarey
431 score_map[
index]=
cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
433 }
434 }
435
436 for(;;){
437 int d;
438 const int dir= next_dir;
439 const int x= best[0];
440 const int y= best[1];
441 next_dir=-1;
442
447
448 if(next_dir==-1){
449 return dmin;
450 }
451 }
452 }
453
455 int src_index, int ref_index, int const penalty_factor,
457 {
460 int dia_size;
464
467
468 for(dia_size=1; dia_size<=4; dia_size++){
469 int dir;
470 const int x= best[0];
471 const int y= best[1];
472
473 if(dia_size&(dia_size-1)) continue;
474
475 if( x + dia_size > xmax
476 || x - dia_size < xmin
477 || y + dia_size > ymax
478 || y - dia_size < ymin)
479 continue;
480
481 for(dir= 0; dir<dia_size; dir+=2){
482 int d;
483
484 CHECK_MV(x + dir , y + dia_size - dir);
485 CHECK_MV(x + dia_size - dir, y - dir );
486 CHECK_MV(x - dir , y - dia_size + dir);
487 CHECK_MV(x - dia_size + dir, y + dir );
488 }
489
490 if(x!=best[0] || y!=best[1])
491 dia_size=0;
492 }
493 return dmin;
494 }
495
497 int src_index, int ref_index, int const penalty_factor,
498 int size,
int h,
int flags,
int dia_size)
499 {
506 const int dec= dia_size & (dia_size-1);
507
510
511 for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
512 do{
513 x= best[0];
514 y= best[1];
515
520 if(dia_size>1){
523 }
524 }while(best[0] != x || best[1] != y);
525 }
526
527 return dmin;
528 }
529
531 int src_index, int ref_index, int const penalty_factor,
533 {
541 const int dec= dia_size & (dia_size-1);
542 static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
543 { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
544
547
548 for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
549 do{
550 x= best[0];
551 y= best[1];
552 for(i=0; i<8; i++){
554 }
555 }while(best[0] != x || best[1] != y);
556 }
557
558 x= best[0];
559 y= best[1];
564
565 return dmin;
566 }
567
569 int src_index, int ref_index, int const penalty_factor,
571 {
577 int x,
y,x2,y2, i, j, d;
578 const int dia_size= c->
dia_size&0xFE;
579 static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
580 { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
581 {-2, 3}, { 0, 4}, { 2, 3},
582 {-2,-3}, { 0,-4}, { 2,-3},};
583
586
587 x= best[0];
588 y= best[1];
589 for(x2=
FFMAX(x-dia_size+1, xmin); x2<=
FFMIN(x+dia_size-1,xmax); x2+=2){
591 }
592 for(y2=
FFMAX(y-dia_size/2+1, ymin); y2<=
FFMIN(y+dia_size/2-1,ymax); y2+=2){
594 }
595
596 x= best[0];
597 y= best[1];
598 for(y2=
FFMAX(y-2, ymin); y2<=
FFMIN(y+2,ymax); y2++){
599 for(x2=
FFMAX(x-2, xmin); x2<=
FFMIN(x+2,xmax); x2++){
601 }
602 }
603
604 //FIXME prevent the CLIP stuff
605
606 for(j=1; j<=dia_size/4; j++){
607 for(i=0; i<16; i++){
609 }
610 }
611
612 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2);
613 }
614
616 int src_index, int ref_index, int const penalty_factor,
618 {
625 const int dia_size= c->
dia_size&0xFF;
626
629
630 for(y=
FFMAX(-dia_size, ymin); y<=
FFMIN(dia_size,ymax); y++){
631 for(x=
FFMAX(-dia_size, xmin); x<=
FFMIN(dia_size,xmax); x++){
633 }
634 }
635
636 x= best[0];
637 y= best[1];
638 d= dmin;
644 best[0]= x;
646
647 return d;
648 }
649
650 #define SAB_CHECK_MV(ax,ay)\
651 {\
652 const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
653 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
654 if(map[index]!=key){\
655 d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
656 map[index]= key;\
657 score_map[index]= d;\
658 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
659 if(d < minima[minima_count-1].height){\
660 int j=0;\
661 \
662 while(d >= minima[j].height) j++;\
663 \
664 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
665 \
666 minima[j].checked= 0;\
667 minima[j].height= d;\
668 minima[j].x= ax;\
669 minima[j].y= ay;\
670 \
671 i=-1;\
672 continue;\
673 }\
674 }\
675 }
676
677 #define MAX_SAB_SIZE ME_MAP_SIZE
679 int src_index, int ref_index, int const penalty_factor,
681 {
686 int i, j;
690
692
695
696 /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
697 become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
698 */
700 uint32_t key= map[i];
701
703
705
706 minima[j].
height= score_map[i];
711
712 // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space
713 if( minima[j].x > xmax || minima[j].x < xmin
714 || minima[j].
y > ymax || minima[j].
y < ymin)
715 continue;
716
718 if(minima[j].x || minima[j].
y)
720
721 j++;
722 }
723
725
726 for(; j<minima_count; j++){
727 minima[j].
height=256*256*256*64;
729 minima[j].
x= minima[j].
y=0;
730 }
731
732 for(i=0; i<minima_count; i++){
733 const int x= minima[i].
x;
734 const int y= minima[i].
y;
735 int d;
736
737 if(minima[i].
checked)
continue;
738
739 if( x >= xmax || x <= xmin
740 || y >= ymax || y <= ymin)
741 continue;
742
747
749 }
750
751 best[0]= minima[0].
x;
752 best[1]= minima[0].
y;
754
755 if( best[0] < xmax && best[0] > xmin
756 && best[1] < ymax && best[1] > ymin){
757 int d;
758 //ensure that the refernece samples for hpel refinement are in the map
763 }
764 return dmin;
765 }
766
768 int src_index, int ref_index, int const penalty_factor,
770 {
773 int dia_size;
777
780
781 for(dia_size=1; dia_size<=c->
dia_size; dia_size++){
783 const int x= best[0];
784 const int y= best[1];
785
786 start=
FFMAX(0, y + dia_size - ymax);
787 end =
FFMIN(dia_size, xmax - x + 1);
788 for(dir= start; dir<
end; dir++){
789 int d;
790
791 //check(x + dir,y + dia_size - dir,0, a0)
792 CHECK_MV(x + dir , y + dia_size - dir);
793 }
794
795 start=
FFMAX(0, x + dia_size - xmax);
796 end =
FFMIN(dia_size, y - ymin + 1);
797 for(dir= start; dir<
end; dir++){
798 int d;
799
800 //check(x + dia_size - dir, y - dir,0, a1)
801 CHECK_MV(x + dia_size - dir, y - dir );
802 }
803
804 start=
FFMAX(0, -y + dia_size + ymin );
805 end =
FFMIN(dia_size, x - xmin + 1);
806 for(dir= start; dir<
end; dir++){
807 int d;
808
809 //check(x - dir,y - dia_size + dir,0, a2)
810 CHECK_MV(x - dir , y - dia_size + dir);
811 }
812
813 start=
FFMAX(0, -x + dia_size + xmin );
814 end =
FFMIN(dia_size, ymax - y + 1);
815 for(dir= start; dir<
end; dir++){
816 int d;
817
818 //check(x - dia_size + dir, y + dir,0, a3)
819 CHECK_MV(x - dia_size + dir, y + dir );
820 }
821
822 if(x!=best[0] || y!=best[1])
823 dia_size=0;
824 }
825 return dmin;
826 }
827
829 int src_index, int ref_index, int const penalty_factor,
833 return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
835 return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
837 return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
839 return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
841 return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
843 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, c->
dia_size&0xFF);
845 return l2s_dia_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
846 else
847 return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
848 }
849
850 /**
851 @param P a list of candidate mvs to check before starting the
852 iterative search. If one of the candidates is close to the optimal mv, then
853 it takes fewer iterations. And it increases the chance that we find the
854 optimal mv.
855 */
857 int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
858 int ref_mv_scale,
int flags,
int size,
int h)
859 {
861 int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
862 i.e. the difference between the position of the
863 block currently being encoded and the position of
864 the block chosen to predict it from. */
865 int d; ///< the score (cmp + penalty) of any given mv
866 int dmin; /**< the best value of d, i.e. the score
867 corresponding to the mv stored in best[]. */
868 unsigned map_generation;
869 int penalty_factor;
870 const int ref_mv_stride= s->
mb_stride;
//pass as arg FIXME
871 const int ref_mv_xy= s->
mb_x + s->
mb_y*ref_mv_stride;
//add to last_mv beforepassing FIXME
873
876
881 }else{
885 }
886
888
890 dmin=
cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
891 map[0]= map_generation;
892 score_map[0]= dmin;
893
894 //FIXME precalc first term below?
897
898 /* first line */
902 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
903 }else{
908 *mx_ptr= 0;
909 *my_ptr= 0;
911 return dmin;
912 }
919 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
923 }
924 if(dmin>h*h*4){
927 (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
929 CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
930 (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
931 }else{
933 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
934 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
935 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
936 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
937 }
938 }
939
942 const int xstart=
FFMAX(0, s->
mb_x - count);
943 const int ystart=
FFMAX(0, s->
mb_y - count);
946 int mb_y;
947
948 for(mb_y=ystart; mb_y<yend; mb_y++){
949 int mb_x;
950 for(mb_x=xstart; mb_x<xend; mb_x++){
951 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;
952 int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;
953 int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;
954
955 if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue;
957 }
958 }
959 }
960
961 //check(best[0],best[1],0, b0)
962 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
963
964 //check(best[0],best[1],0, b1)
965 *mx_ptr= best[0];
966 *my_ptr= best[1];
967
968 return dmin;
969 }
970
971 //this function is dedicated to the braindamaged gcc
973 int P[10][2], int src_index, int ref_index,
974 int16_t (*last_mv)[2], int ref_mv_scale,
976 {
978 //FIXME convert other functions in the same way if faster
979 if(c->
flags==0 && h==16 && size==0){
980 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
981 // case FLAG_QPEL:
982 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
983 }else{
984 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->
flags, size, h);
985 }
986 }
987
989 int *mx_ptr, int *my_ptr, int P[10][2],
990 int src_index, int ref_index, int16_t (*last_mv)[2],
991 int ref_mv_scale)
992 {
994 int best[2]={0, 0};
995 int d, dmin;
996 unsigned map_generation;
999 const int h=8;
1001 const int ref_mv_xy= s->
mb_x + s->
mb_y *ref_mv_stride;
1006
1009
1011
1012 dmin = 1000000;
1013
1014 /* first line */
1018 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1020 }else{
1022 //FIXME try some early stop
1028 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1029 }
1030 if(dmin>64*4){
1032 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1033 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
1034 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1035 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1036 }
1037
1038 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1039
1040 *mx_ptr= best[0];
1041 *my_ptr= best[1];
1042
1043 return dmin;
1044 }
1045
1046 //try to merge with above FIXME (needs PSNR test)
1048 int *mx_ptr, int *my_ptr, int P[10][2],
1049 int src_index, int ref_index, int16_t (*last_mv)[2],
1050 int ref_mv_scale)
1051 {
1053 int best[2]={0, 0};
1054 int d, dmin;
1055 unsigned map_generation;
1057 const int size=0;
//FIXME pass as arg
1058 const int h=8;
1060 const int ref_mv_xy= s->
mb_x + s->
mb_y *ref_mv_stride;
1065
1068
1070
1071 dmin = 1000000;
1072
1073 /* first line */
1077 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1079 }else{
1081 //FIXME try some early stop
1087 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1088 }
1089 if(dmin>64*4){
1091 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1092 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
1093 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1094 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1095 }
1096
1097 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1098
1099 *mx_ptr= best[0];
1100 *my_ptr= best[1];
1101
1102 return dmin;
1103 }