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
28
29 //Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
31 uint32_t av_unused * const score_map= c->score_map;\
32 const int av_unused xmin= c->xmin;\
33 const int av_unused ymin= c->ymin;\
34 const int av_unused xmax= c->xmax;\
35 const int av_unused ymax= c->ymax;\
36 uint8_t *mv_penalty= c->current_mv_penalty;\
37 const int pred_x= c->pred_x;\
38 const int pred_y= c->pred_y;\
39
40 #define CHECK_HALF_MV(dx, dy, x, y)\
41 {\
42 const int hx= 2*(x)+(dx);\
43 const int hy= 2*(y)+(dy);\
44 d= cmp_hpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\
45 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
46 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
47 }
48
50 int *mx_ptr, int *my_ptr, int dmin,
51 int src_index, int ref_index,
53 {
55 const int mx = *mx_ptr;
56 const int my = *my_ptr;
59 int bx=2*mx, by=2*my;
60
63
64 //FIXME factorize
65
68
69 if(c->
skip){
//FIXME move out of hpel?
70 *mx_ptr = 0;
71 *my_ptr = 0;
72 return dmin;
73 }
74
76 dmin=
cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
77 if(mx || my || size>0)
79 }
80
81 if (mx > xmin && mx < xmax &&
82 my > ymin && my < ymax) {
83 int d= dmin;
93
94 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
95 unsigned key;
105 #endif
106 if(t<=b){
112 }else{
114 }
116 }else{
120 }else{
122 }
124 }
125 }else{
129 }else{
131 }
134 }else{
137 }else{
139 }
142 }
144 }
145 av_assert2(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
146 }
147
148 *mx_ptr = bx;
149 *my_ptr = by;
150
151 return dmin;
152 }
153
155 int *mx_ptr, int *my_ptr, int dmin,
156 int src_index, int ref_index,
158 {
159 (*mx_ptr)<<=1;
160 (*my_ptr)<<=1;
161 return dmin;
162 }
163
165 int src_index,
int ref_index,
int size,
166 int h, int add_rate)
167 {
172 const int mask= 1+2*qpel;
174 int d;
175
177
178 //FIXME factorize
179
182
183 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);
184 //FIXME check cbp before adding penalty for (0,0) vector
185 if(add_rate && (mx || my || size>0))
187
188 return d;
189 }
190
192 int ref_index,
int size,
int h,
int add_rate)
193 {
194 return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
195 }
196
197 #define CHECK_QUARTER_MV(dx, dy, x, y)\
198 {\
199 const int hx= 4*(x)+(dx);\
200 const int hy= 4*(y)+(dy);\
201 d= cmp_qpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
202 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
203 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
204 }
205
207 int *mx_ptr, int *my_ptr, int dmin,
208 int src_index, int ref_index,
210 {
212 const int mx = *mx_ptr;
213 const int my = *my_ptr;
217 uint32_t *map= c->
map;
220
223
225 chroma_cmpf = s->
mecc.
me_cmp[size + 1];
// FIXME: factorize
226 //FIXME factorize
227
230
231 if(c->
skip){
//FIXME somehow move up (benchmark)
232 *mx_ptr = 0;
233 *my_ptr = 0;
234 return dmin;
235 }
236
238 dmin=
cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
239 if(mx || my || size>0)
241 }
242
243 if (mx > xmin && mx < xmax &&
244 my > ymin && my < ymax) {
245 int bx=4*mx, by=4*my;
246 int d= dmin;
247 int i, nx, ny;
250 const int l= score_map[(index- 1 )&(
ME_MAP_SIZE-1)];
254 int best[8];
255 int best_pos[8][2];
256
257 memset(best, 64, sizeof(int)*8);
263
264 for(ny= -3; ny <= 3; ny++){
265 for(nx= -3; nx <= 3; nx++){
266 //FIXME this could overflow (unlikely though)
267 const int64_t
t2= nx*nx*(tr + tl - 2*t) + 4*nx*(tr-tl) + 32*t;
268 const int64_t
c2= nx*nx*( r + l - 2*
c) + 4*nx*( r- l) + 32*
c;
269 const int64_t b2= nx*nx*(br + bl - 2*
b) + 4*nx*(br-bl) + 32*
b;
270 int score= (ny*ny*(b2 + t2 - 2*
c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10;
271 int i;
272
273 if((nx&3)==0 && (ny&3)==0) continue;
274
276
277 // if(nx&1) score-=1024*c->penalty_factor;
278 // if(ny&1) score-=1024*c->penalty_factor;
279
280 for(i=0; i<8; i++){
281 if(score < best[i]){
282 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
283 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
284 best[i]= score;
285 best_pos[i][0]= nx + 4*mx;
286 best_pos[i][1]= ny + 4*my;
287 break;
288 }
289 }
290 }
291 }
292 }else{
293 int tl;
294 //FIXME this could overflow (unlikely though)
295 const int cx = 4*(r - l);
296 const int cx2= r + l - 2*
c;
297 const int cy = 4*(b - t);
298 const int cy2= b + t - 2*
c;
299 int cxy;
300
303 }else{
304 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
305 }
306
307 cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*
c;
308
313 av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
314
315 for(ny= -3; ny <= 3; ny++){
316 for(nx= -3; nx <= 3; nx++){
317 //FIXME this could overflow (unlikely though)
318 int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*
c;
//FIXME factor
319 int i;
320
321 if((nx&3)==0 && (ny&3)==0) continue;
322
324 // if(nx&1) score-=32*c->penalty_factor;
325 // if(ny&1) score-=32*c->penalty_factor;
326
327 for(i=0; i<8; i++){
328 if(score < best[i]){
329 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
330 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
331 best[i]= score;
332 best_pos[i][0]= nx + 4*mx;
333 best_pos[i][1]= ny + 4*my;
334 break;
335 }
336 }
337 }
338 }
339 }
340 for(i=0; i<subpel_quality; i++){
341 nx= best_pos[i][0];
342 ny= best_pos[i][1];
344 }
345
346 av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
347
348 *mx_ptr = bx;
349 *my_ptr = by;
350 }else{
351 *mx_ptr =4*mx;
352 *my_ptr =4*my;
353 }
354
355 return dmin;
356 }
357
358
359 #define CHECK_MV(x,y)\
360 {\
361 const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
362 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
363 av_assert2((x) >= xmin);\
364 av_assert2((x) <= xmax);\
365 av_assert2((y) >= ymin);\
366 av_assert2((y) <= ymax);\
367 if(map[index]!=key){\
368 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
369 map[index]= key;\
370 score_map[index]= d;\
371 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\
372 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
373 }\
374 }
375
376 #define CHECK_CLIPPED_MV(ax,ay)\
377 {\
378 const int Lx= ax;\
379 const int Ly= ay;\
380 const int Lx2= FFMAX(xmin, FFMIN(Lx, xmax));\
381 const int Ly2= FFMAX(ymin, FFMIN(Ly, ymax));\
382 CHECK_MV(Lx2, Ly2)\
383 }
384
385 #define CHECK_MV_DIR(x,y,new_dir)\
386 {\
387 const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
388 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
389 if(map[index]!=key){\
390 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
391 map[index]= key;\
392 score_map[index]= d;\
393 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\
394 if(d<dmin){\
395 best[0]=x;\
396 best[1]=y;\
397 dmin=d;\
398 next_dir= new_dir;\
399 }\
400 }\
401 }
402
403 #define check(x,y,S,v)\
404 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);\
405 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);\
406 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);\
407 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);\
408
409 #define LOAD_COMMON2\
410 uint32_t *map= c->map;\
411 const int qpel= flags&FLAG_QPEL;\
412 const int shift= 1+qpel;\
413
415 int src_index, int ref_index, int const penalty_factor,
417 {
420 int next_dir=-1;
424
427
428 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
429 const unsigned key = (best[1]<<
ME_MAP_MV_BITS) + best[0] + map_generation;
431 if(map[index]!=key){ //this will be executed only very rarey
432 score_map[
index]=
cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
434 }
435 }
436
437 for(;;){
438 int d;
439 const int dir= next_dir;
440 const int x= best[0];
441 const int y= best[1];
442 next_dir=-1;
443
448
449 if(next_dir==-1){
450 return dmin;
451 }
452 }
453 }
454
456 int src_index, int ref_index, int const penalty_factor,
458 {
461 int dia_size;
465
468
469 for(dia_size=1; dia_size<=4; dia_size++){
470 int dir;
471 const int x= best[0];
472 const int y= best[1];
473
474 if(dia_size&(dia_size-1)) continue;
475
476 if( x + dia_size > xmax
477 || x - dia_size < xmin
478 || y + dia_size > ymax
479 || y - dia_size < ymin)
480 continue;
481
482 for(dir= 0; dir<dia_size; dir+=2){
483 int d;
484
485 CHECK_MV(x + dir , y + dia_size - dir);
486 CHECK_MV(x + dia_size - dir, y - dir );
487 CHECK_MV(x - dir , y - dia_size + dir);
488 CHECK_MV(x - dia_size + dir, y + dir );
489 }
490
491 if(x!=best[0] || y!=best[1])
492 dia_size=0;
493 }
494 return dmin;
495 }
496
498 int src_index, int ref_index, int const penalty_factor,
499 int size,
int h,
int flags,
int dia_size)
500 {
507 const int dec= dia_size & (dia_size-1);
508
511
512 for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
513 do{
514 x= best[0];
515 y= best[1];
516
521 if(dia_size>1){
524 }
525 }while(best[0] != x || best[1] != y);
526 }
527
528 return dmin;
529 }
530
532 int src_index, int ref_index, int const penalty_factor,
534 {
542 const int dec= dia_size & (dia_size-1);
543 static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
544 { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
545
548
549 for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
550 do{
551 x= best[0];
552 y= best[1];
553 for(i=0; i<8; i++){
555 }
556 }while(best[0] != x || best[1] != y);
557 }
558
559 x= best[0];
560 y= best[1];
565
566 return dmin;
567 }
568
570 int src_index, int ref_index, int const penalty_factor,
572 {
578 int x,
y,x2,y2, i, j, d;
579 const int dia_size= c->
dia_size&0xFE;
580 static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
581 { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
582 {-2, 3}, { 0, 4}, { 2, 3},
583 {-2,-3}, { 0,-4}, { 2,-3},};
584
587
588 x= best[0];
589 y= best[1];
590 for(x2=
FFMAX(x-dia_size+1, xmin); x2<=
FFMIN(x+dia_size-1,xmax); x2+=2){
592 }
593 for(y2=
FFMAX(y-dia_size/2+1, ymin); y2<=
FFMIN(y+dia_size/2-1,ymax); y2+=2){
595 }
596
597 x= best[0];
598 y= best[1];
599 for(y2=
FFMAX(y-2, ymin); y2<=
FFMIN(y+2,ymax); y2++){
600 for(x2=
FFMAX(x-2, xmin); x2<=
FFMIN(x+2,xmax); x2++){
602 }
603 }
604
605 //FIXME prevent the CLIP stuff
606
607 for(j=1; j<=dia_size/4; j++){
608 for(i=0; i<16; i++){
610 }
611 }
612
613 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2);
614 }
615
617 int src_index, int ref_index, int const penalty_factor,
619 {
626 const int dia_size= c->
dia_size&0xFF;
627
630
631 for(y=
FFMAX(-dia_size, ymin); y<=
FFMIN(dia_size,ymax); y++){
632 for(x=
FFMAX(-dia_size, xmin); x<=
FFMIN(dia_size,xmax); x++){
634 }
635 }
636
637 x= best[0];
638 y= best[1];
639 d= dmin;
645 best[0]= x;
647
648 return d;
649 }
650
651 #define SAB_CHECK_MV(ax,ay)\
652 {\
653 const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
654 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
655 if(map[index]!=key){\
656 d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
657 map[index]= key;\
658 score_map[index]= d;\
659 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
660 if(d < minima[minima_count-1].height){\
661 int j=0;\
662 \
663 while(d >= minima[j].height) j++;\
664 \
665 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
666 \
667 minima[j].checked= 0;\
668 minima[j].height= d;\
669 minima[j].x= ax;\
670 minima[j].y= ay;\
671 \
672 i=-1;\
673 continue;\
674 }\
675 }\
676 }
677
678 #define MAX_SAB_SIZE ME_MAP_SIZE
680 int src_index, int ref_index, int const penalty_factor,
682 {
687 int i, j;
691
693
696
697 /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
698 become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
699 */
701 uint32_t key= map[i];
702
704
706
707 minima[j].
height= score_map[i];
712
713 // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space
714 if( minima[j].x > xmax || minima[j].x < xmin
715 || minima[j].
y > ymax || minima[j].
y < ymin)
716 continue;
717
719 if(minima[j].x || minima[j].
y)
721
722 j++;
723 }
724
726
727 for(; j<minima_count; j++){
728 minima[j].
height=256*256*256*64;
730 minima[j].
x= minima[j].
y=0;
731 }
732
733 for(i=0; i<minima_count; i++){
734 const int x= minima[i].
x;
735 const int y= minima[i].
y;
736 int d;
737
738 if(minima[i].
checked)
continue;
739
740 if( x >= xmax || x <= xmin
741 || y >= ymax || y <= ymin)
742 continue;
743
748
750 }
751
752 best[0]= minima[0].
x;
753 best[1]= minima[0].
y;
755
756 if( best[0] < xmax && best[0] > xmin
757 && best[1] < ymax && best[1] > ymin){
758 int d;
759 //ensure that the refernece samples for hpel refinement are in the map
764 }
765 return dmin;
766 }
767
769 int src_index, int ref_index, int const penalty_factor,
771 {
774 int dia_size;
778
781
782 for(dia_size=1; dia_size<=c->
dia_size; dia_size++){
784 const int x= best[0];
785 const int y= best[1];
786
787 start=
FFMAX(0, y + dia_size - ymax);
788 end =
FFMIN(dia_size, xmax - x + 1);
789 for(dir= start; dir<
end; dir++){
790 int d;
791
792 //check(x + dir,y + dia_size - dir,0, a0)
793 CHECK_MV(x + dir , y + dia_size - dir);
794 }
795
796 start=
FFMAX(0, x + dia_size - xmax);
797 end =
FFMIN(dia_size, y - ymin + 1);
798 for(dir= start; dir<
end; dir++){
799 int d;
800
801 //check(x + dia_size - dir, y - dir,0, a1)
802 CHECK_MV(x + dia_size - dir, y - dir );
803 }
804
805 start=
FFMAX(0, -y + dia_size + ymin );
806 end =
FFMIN(dia_size, x - xmin + 1);
807 for(dir= start; dir<
end; dir++){
808 int d;
809
810 //check(x - dir,y - dia_size + dir,0, a2)
811 CHECK_MV(x - dir , y - dia_size + dir);
812 }
813
814 start=
FFMAX(0, -x + dia_size + xmin );
815 end =
FFMIN(dia_size, ymax - y + 1);
816 for(dir= start; dir<
end; dir++){
817 int d;
818
819 //check(x - dia_size + dir, y + dir,0, a3)
820 CHECK_MV(x - dia_size + dir, y + dir );
821 }
822
823 if(x!=best[0] || y!=best[1])
824 dia_size=0;
825 }
826 return dmin;
827 }
828
830 int src_index, int ref_index, int const penalty_factor,
834 return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
836 return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
838 return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
840 return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
842 return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
844 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, c->
dia_size&0xFF);
846 return l2s_dia_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
847 else
848 return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
849 }
850
851 /**
852 @param P a list of candidate mvs to check before starting the
853 iterative search. If one of the candidates is close to the optimal mv, then
854 it takes fewer iterations. And it increases the chance that we find the
855 optimal mv.
856 */
858 int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
859 int ref_mv_scale,
int flags,
int size,
int h)
860 {
862 int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
863 i.e. the difference between the position of the
864 block currently being encoded and the position of
865 the block chosen to predict it from. */
866 int d; ///< the score (cmp + penalty) of any given mv
867 int dmin; /**< the best value of d, i.e. the score
868 corresponding to the mv stored in best[]. */
869 unsigned map_generation;
870 int penalty_factor;
871 const int ref_mv_stride= s->
mb_stride;
//pass as arg FIXME
872 const int ref_mv_xy= s->
mb_x + s->
mb_y*ref_mv_stride;
//add to last_mv beforepassing FIXME
874
877
882 }else{
886 }
887
889
891 dmin=
cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
892 map[0]= map_generation;
893 score_map[0]= dmin;
894
895 //FIXME precalc first term below?
899
900 /* first line */
904 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
905 }else{
910 *mx_ptr= 0;
911 *my_ptr= 0;
913 return dmin;
914 }
921 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
925 }
926 if(dmin>h*h*4){
929 (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
931 CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
932 (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
933 }else{
935 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
936 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
937 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
938 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
939 }
940 }
941
944 const int xstart=
FFMAX(0, s->
mb_x - count);
945 const int ystart=
FFMAX(0, s->
mb_y - count);
948 int mb_y;
949
950 for(mb_y=ystart; mb_y<yend; mb_y++){
951 int mb_x;
952 for(mb_x=xstart; mb_x<xend; mb_x++){
953 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;
954 int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;
955 int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;
956
957 if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue;
959 }
960 }
961 }
962
963 //check(best[0],best[1],0, b0)
964 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
965
966 //check(best[0],best[1],0, b1)
967 *mx_ptr= best[0];
968 *my_ptr= best[1];
969
970 return dmin;
971 }
972
973 //this function is dedicated to the braindamaged gcc
975 int P[10][2], int src_index, int ref_index,
976 int16_t (*last_mv)[2], int ref_mv_scale,
978 {
980 //FIXME convert other functions in the same way if faster
981 if(c->
flags==0 && h==16 && size==0){
982 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
983 // case FLAG_QPEL:
984 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
985 }else{
986 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->
flags, size, h);
987 }
988 }
989
991 int *mx_ptr, int *my_ptr, int P[10][2],
992 int src_index, int ref_index, int16_t (*last_mv)[2],
993 int ref_mv_scale)
994 {
996 int best[2]={0, 0};
997 int d, dmin;
998 unsigned map_generation;
1001 const int h=8;
1003 const int ref_mv_xy= s->
mb_x + s->
mb_y *ref_mv_stride;
1008
1011
1013
1014 dmin = 1000000;
1015
1016 /* first line */
1020 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1022 }else{
1024 //FIXME try some early stop
1030 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1031 }
1032 if(dmin>64*4){
1034 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1035 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
1036 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1037 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1038 }
1039
1040 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1041
1042 *mx_ptr= best[0];
1043 *my_ptr= best[1];
1044
1045 return dmin;
1046 }
1047
1048 //try to merge with above FIXME (needs PSNR test)
1050 int *mx_ptr, int *my_ptr, int P[10][2],
1051 int src_index, int ref_index, int16_t (*last_mv)[2],
1052 int ref_mv_scale)
1053 {
1055 int best[2]={0, 0};
1056 int d, dmin;
1057 unsigned map_generation;
1059 const int size=0;
//FIXME pass as arg
1060 const int h=8;
1062 const int ref_mv_xy= s->
mb_x + s->
mb_y *ref_mv_stride;
1067
1070
1072
1073 dmin = 1000000;
1074
1075 /* first line */
1079 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1081 }else{
1083 //FIXME try some early stop
1089 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1090 }
1091 if(dmin>64*4){
1093 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1094 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
1095 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1096 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1097 }
1098
1099 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1100
1101 *mx_ptr= best[0];
1102 *my_ptr= best[1];
1103
1104 return dmin;
1105 }