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
29
30 //Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
32 uint32_t av_unused * const score_map= c->score_map;\
33 const int av_unused xmin= c->xmin;\
34 const int av_unused ymin= c->ymin;\
35 const int av_unused xmax= c->xmax;\
36 const int av_unused ymax= c->ymax;\
37 uint8_t *mv_penalty= c->current_mv_penalty;\
38 const int pred_x= c->pred_x;\
39 const int pred_y= c->pred_y;\
40
41 #define CHECK_HALF_MV(dx, dy, x, y)\
42 {\
43 const int hx= 2*(x)+(dx);\
44 const int hy= 2*(y)+(dy);\
45 d= cmp_hpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\
46 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
47 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
48 }
49
51 int *mx_ptr, int *my_ptr, int dmin,
52 int src_index, int ref_index,
54 {
56 const int mx = *mx_ptr;
57 const int my = *my_ptr;
60 int bx=2*mx, by=2*my;
61
64
65 //FIXME factorize
66
69
70 if(c->
skip){
//FIXME move out of hpel?
71 *mx_ptr = 0;
72 *my_ptr = 0;
73 return dmin;
74 }
75
77 dmin=
cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
78 if(mx || my || size>0)
80 }
81
82 if (mx > xmin && mx < xmax &&
83 my > ymin && my < ymax) {
84 int d= dmin;
94
95 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
96 unsigned key;
106 #endif
107 if(t<=b){
113 }else{
115 }
117 }else{
121 }else{
123 }
125 }
126 }else{
130 }else{
132 }
135 }else{
138 }else{
140 }
143 }
145 }
146 av_assert2(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
147 }
148
149 *mx_ptr = bx;
150 *my_ptr = by;
151
152 return dmin;
153 }
154
156 int *mx_ptr, int *my_ptr, int dmin,
157 int src_index, int ref_index,
159 {
160 (*mx_ptr)<<=1;
161 (*my_ptr)<<=1;
162 return dmin;
163 }
164
166 int src_index,
int ref_index,
int size,
168 {
173 const int mask= 1+2*qpel;
175 int d;
176
178
179 //FIXME factorize
180
183
184 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);
185 //FIXME check cbp before adding penalty for (0,0) vector
186 if(add_rate && (mx || my || size>0))
188
189 return d;
190 }
191
193 int ref_index,
int size,
int h,
int add_rate)
194 {
195 return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
196 }
197
198 #define CHECK_QUARTER_MV(dx, dy, x, y)\
199 {\
200 const int hx= 4*(x)+(dx);\
201 const int hy= 4*(y)+(dy);\
202 d= cmp_qpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
203 d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
204 COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
205 }
206
208 int *mx_ptr, int *my_ptr, int dmin,
209 int src_index, int ref_index,
211 {
213 const int mx = *mx_ptr;
214 const int my = *my_ptr;
218 uint32_t *map= c->
map;
221
224
226 chroma_cmpf = s->
mecc.
me_cmp[size + 1];
// FIXME: factorize
227 //FIXME factorize
228
231
232 if(c->
skip){
//FIXME somehow move up (benchmark)
233 *mx_ptr = 0;
234 *my_ptr = 0;
235 return dmin;
236 }
237
239 dmin=
cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
240 if(mx || my || size>0)
242 }
243
244 if (mx > xmin && mx < xmax &&
245 my > ymin && my < ymax) {
246 int bx=4*mx, by=4*my;
247 int d= dmin;
248 int i, nx, ny;
251 const int l= score_map[(index- 1 )&(
ME_MAP_SIZE-1)];
255 int best[8];
256 int best_pos[8][2];
257
258 memset(best, 64, sizeof(int)*8);
264
265 for(ny= -3; ny <= 3; ny++){
266 for(nx= -3; nx <= 3; nx++){
267 //FIXME this could overflow (unlikely though)
268 const int64_t
t2= nx*nx*(tr + tl - 2*t) + 4*nx*(tr-tl) + 32*t;
269 const int64_t
c2= nx*nx*( r + l - 2*
c) + 4*nx*( r- l) + 32*
c;
270 const int64_t b2= nx*nx*(br + bl - 2*
b) + 4*nx*(br-bl) + 32*
b;
271 int score= (ny*ny*(b2 + t2 - 2*
c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10;
272 int i;
273
274 if((nx&3)==0 && (ny&3)==0) continue;
275
277
278 // if(nx&1) score-=1024*c->penalty_factor;
279 // if(ny&1) score-=1024*c->penalty_factor;
280
281 for(i=0; i<8; i++){
282 if(score < best[i]){
283 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
284 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
285 best[i]= score;
286 best_pos[i][0]= nx + 4*mx;
287 best_pos[i][1]= ny + 4*my;
288 break;
289 }
290 }
291 }
292 }
293 }else{
294 int tl;
295 //FIXME this could overflow (unlikely though)
296 const int cx = 4*(r - l);
297 const int cx2= r + l - 2*
c;
298 const int cy = 4*(b - t);
299 const int cy2= b + t - 2*
c;
300 int cxy;
301
304 }else{
305 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
306 }
307
308 cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*
c;
309
314 av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
315
316 for(ny= -3; ny <= 3; ny++){
317 for(nx= -3; nx <= 3; nx++){
318 //FIXME this could overflow (unlikely though)
319 int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*
c;
//FIXME factor
320 int i;
321
322 if((nx&3)==0 && (ny&3)==0) continue;
323
325 // if(nx&1) score-=32*c->penalty_factor;
326 // if(ny&1) score-=32*c->penalty_factor;
327
328 for(i=0; i<8; i++){
329 if(score < best[i]){
330 memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
331 memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
332 best[i]= score;
333 best_pos[i][0]= nx + 4*mx;
334 best_pos[i][1]= ny + 4*my;
335 break;
336 }
337 }
338 }
339 }
340 }
341 for(i=0; i<subpel_quality; i++){
342 nx= best_pos[i][0];
343 ny= best_pos[i][1];
345 }
346
347 av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
348
349 *mx_ptr = bx;
350 *my_ptr = by;
351 }else{
352 *mx_ptr =4*mx;
353 *my_ptr =4*my;
354 }
355
356 return dmin;
357 }
358
359
360 #define CHECK_MV(x,y)\
361 {\
362 const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
363 const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
364 av_assert2((x) >= xmin);\
365 av_assert2((x) <= xmax);\
366 av_assert2((y) >= ymin);\
367 av_assert2((y) <= ymax);\
368 if(map[index]!=key){\
369 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
370 map[index]= key;\
371 score_map[index]= d;\
372 d += (mv_penalty[((x)*(1<<shift))-pred_x] + mv_penalty[((y)*(1<<shift))-pred_y])*penalty_factor;\
373 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
374 }\
375 }
376
377 #define CHECK_CLIPPED_MV(ax,ay)\
378 {\
379 const int Lx= ax;\
380 const int Ly= ay;\
381 const int Lx2= FFMAX(xmin, FFMIN(Lx, xmax));\
382 const int Ly2= FFMAX(ymin, FFMIN(Ly, ymax));\
383 CHECK_MV(Lx2, Ly2)\
384 }
385
386 #define CHECK_MV_DIR(x,y,new_dir)\
387 {\
388 const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
389 const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
390 if(map[index]!=key){\
391 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
392 map[index]= key;\
393 score_map[index]= d;\
394 d += (mv_penalty[(int)((unsigned)(x)<<shift)-pred_x] + mv_penalty[(int)((unsigned)(y)<<shift)-pred_y])*penalty_factor;\
395 if(d<dmin){\
396 best[0]=x;\
397 best[1]=y;\
398 dmin=d;\
399 next_dir= new_dir;\
400 }\
401 }\
402 }
403
404 #define check(x,y,S,v)\
405 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);\
406 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);\
407 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);\
408 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);\
409
410 #define LOAD_COMMON2\
411 uint32_t *map= c->map;\
412 const int qpel= flags&FLAG_QPEL;\
413 const int shift= 1+qpel;\
414
416 int src_index, int ref_index, int const penalty_factor,
418 {
421 int next_dir=-1;
425
428
429 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
430 const unsigned key = ((unsigned)best[1]<<
ME_MAP_MV_BITS) + best[0] + map_generation;
432 if(map[index]!=key){ //this will be executed only very rarey
433 score_map[
index]=
cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
435 }
436 }
437
438 for(;;){
439 int d;
440 const int dir= next_dir;
441 const int x= best[0];
442 const int y= best[1];
443 next_dir=-1;
444
449
450 if(next_dir==-1){
451 return dmin;
452 }
453 }
454 }
455
457 int src_index, int ref_index, int const penalty_factor,
459 {
462 int dia_size;
466
469
470 for(dia_size=1; dia_size<=4; dia_size++){
471 int dir;
472 const int x= best[0];
473 const int y= best[1];
474
475 if(dia_size&(dia_size-1)) continue;
476
477 if( x + dia_size > xmax
478 || x - dia_size < xmin
479 || y + dia_size > ymax
480 || y - dia_size < ymin)
481 continue;
482
483 for(dir= 0; dir<dia_size; dir+=2){
484 int d;
485
486 CHECK_MV(x + dir , y + dia_size - dir);
487 CHECK_MV(x + dia_size - dir, y - dir );
488 CHECK_MV(x - dir , y - dia_size + dir);
489 CHECK_MV(x - dia_size + dir, y + dir );
490 }
491
492 if(x!=best[0] || y!=best[1])
493 dia_size=0;
494 }
495 return dmin;
496 }
497
499 int src_index, int ref_index, int const penalty_factor,
501 {
507 int x,y,d;
508 const int dec= dia_size & (dia_size-1);
509
512
513 for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
514 do{
515 x= best[0];
516 y= best[1];
517
522 if(dia_size>1){
525 }
526 }while(best[0] != x || best[1] != y);
527 }
528
529 return dmin;
530 }
531
533 int src_index, int ref_index, int const penalty_factor,
535 {
541 int x,y,i,d;
543 const int dec= dia_size & (dia_size-1);
544 static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
545 { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
546
549
550 for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
551 do{
552 x= best[0];
553 y= best[1];
554 for(i=0; i<8; i++){
556 }
557 }while(best[0] != x || best[1] != y);
558 }
559
560 x= best[0];
561 y= best[1];
566
567 return dmin;
568 }
569
571 int src_index, int ref_index, int const penalty_factor,
573 {
579 int x,y,x2,y2, i, j, d;
580 const int dia_size= c->
dia_size&0xFE;
581 static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
582 { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
583 {-2, 3}, { 0, 4}, { 2, 3},
584 {-2,-3}, { 0,-4}, { 2,-3},};
585
588
589 x= best[0];
590 y= best[1];
591 for(x2=
FFMAX(x-dia_size+1, xmin); x2<=
FFMIN(x+dia_size-1,xmax); x2+=2){
593 }
594 for(y2=
FFMAX(y-dia_size/2+1, ymin); y2<=
FFMIN(y+dia_size/2-1,ymax); y2+=2){
596 }
597
598 x= best[0];
599 y= best[1];
600 for(y2=
FFMAX(y-2, ymin); y2<=
FFMIN(y+2,ymax); y2++){
601 for(x2=
FFMAX(x-2, xmin); x2<=
FFMIN(x+2,xmax); x2++){
603 }
604 }
605
606 //FIXME prevent the CLIP stuff
607
608 for(j=1; j<=dia_size/4; j++){
609 for(i=0; i<16; i++){
611 }
612 }
613
614 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2);
615 }
616
618 int src_index, int ref_index, int const penalty_factor,
620 {
626 int x,y, d;
627 const int dia_size= c->
dia_size&0xFF;
628
631
632 for(y=
FFMAX(-dia_size, ymin); y<=
FFMIN(dia_size,ymax); y++){
633 for(x=
FFMAX(-dia_size, xmin); x<=
FFMIN(dia_size,xmax); x++){
635 }
636 }
637
638 x= best[0];
639 y= best[1];
640 d= dmin;
646 best[0]= x;
647 best[1]= y;
648
649 return d;
650 }
651
652 #define SAB_CHECK_MV(ax,ay)\
653 {\
654 const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
655 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
656 if(map[index]!=key){\
657 d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
658 map[index]= key;\
659 score_map[index]= d;\
660 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
661 if(d < minima[minima_count-1].height){\
662 int j=0;\
663 \
664 while(d >= minima[j].height) j++;\
665 \
666 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
667 \
668 minima[j].checked= 0;\
669 minima[j].height= d;\
670 minima[j].x= ax;\
671 minima[j].y= ay;\
672 \
673 i=-1;\
674 continue;\
675 }\
676 }\
677 }
678
679 #define MAX_SAB_SIZE ME_MAP_SIZE
681 int src_index, int ref_index, int const penalty_factor,
683 {
688 int i, j;
692
694
697
698 /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
699 become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
700 */
702 uint32_t key= map[i];
703
705
707 continue;
708
709 minima[j].
height= score_map[i];
714
715 // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space
716 if( minima[j].x > xmax || minima[j].x < xmin
717 || minima[j].y > ymax || minima[j].y < ymin)
718 continue;
719
721 if(minima[j].x || minima[j].y)
723
724 j++;
725 }
726
728
729 for(; j<minima_count; j++){
730 minima[j].
height=256*256*256*64;
732 minima[j].
x= minima[j].
y=0;
733 }
734
735 for(i=0; i<minima_count; i++){
736 const int x= minima[i].
x;
737 const int y= minima[i].
y;
738 int d;
739
740 if(minima[i].
checked)
continue;
741
742 if( x >= xmax || x <= xmin
743 || y >= ymax || y <= ymin)
744 continue;
745
750
752 }
753
754 best[0]= minima[0].
x;
755 best[1]= minima[0].
y;
757
758 if( best[0] < xmax && best[0] > xmin
759 && best[1] < ymax && best[1] > ymin){
760 int d;
761 //ensure that the refernece samples for hpel refinement are in the map
766 }
767 return dmin;
768 }
769
771 int src_index, int ref_index, int const penalty_factor,
773 {
776 int dia_size;
780
783
784 for(dia_size=1; dia_size<=c->
dia_size; dia_size++){
786 const int x= best[0];
787 const int y= best[1];
788
789 start=
FFMAX(0, y + dia_size - ymax);
790 end =
FFMIN(dia_size, xmax - x + 1);
791 for(dir= start; dir<
end; dir++){
792 int d;
793
794 //check(x + dir,y + dia_size - dir,0, a0)
795 CHECK_MV(x + dir , y + dia_size - dir);
796 }
797
798 start=
FFMAX(0, x + dia_size - xmax);
799 end =
FFMIN(dia_size, y - ymin + 1);
800 for(dir= start; dir<
end; dir++){
801 int d;
802
803 //check(x + dia_size - dir, y - dir,0, a1)
804 CHECK_MV(x + dia_size - dir, y - dir );
805 }
806
807 start=
FFMAX(0, -y + dia_size + ymin );
808 end =
FFMIN(dia_size, x - xmin + 1);
809 for(dir= start; dir<
end; dir++){
810 int d;
811
812 //check(x - dir,y - dia_size + dir,0, a2)
813 CHECK_MV(x - dir , y - dia_size + dir);
814 }
815
816 start=
FFMAX(0, -x + dia_size + xmin );
817 end =
FFMIN(dia_size, ymax - y + 1);
818 for(dir= start; dir<
end; dir++){
819 int d;
820
821 //check(x - dia_size + dir, y + dir,0, a3)
822 CHECK_MV(x - dia_size + dir, y + dir );
823 }
824
825 if(x!=best[0] || y!=best[1])
826 dia_size=0;
827 }
828 return dmin;
829 }
830
832 int src_index, int ref_index, int const penalty_factor,
836 return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
838 return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
840 return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
842 return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
844 return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
846 return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, c->
dia_size&0xFF);
848 return l2s_dia_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
849 else
850 return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
851 }
852
853 /**
854 @param P a list of candidate mvs to check before starting the
855 iterative search. If one of the candidates is close to the optimal mv, then
856 it takes fewer iterations. And it increases the chance that we find the
857 optimal mv.
858 */
860 int P[10][2],
int src_index,
int ref_index, int16_t (*
last_mv)[2],
862 {
864 int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
865 i.e. the difference between the position of the
866 block currently being encoded and the position of
867 the block chosen to predict it from. */
868 int d; ///< the score (cmp + penalty) of any given mv
869 int dmin; /**< the best value of d, i.e. the score
870 corresponding to the mv stored in best[]. */
871 unsigned map_generation;
872 int penalty_factor;
873 const int ref_mv_stride= s->
mb_stride;
//pass as arg FIXME
874 const int ref_mv_xy= s->
mb_x + s->
mb_y*ref_mv_stride;
//add to last_mv beforepassing FIXME
876
879
884 }else{
888 }
889
891
893 dmin=
cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
894 map[0]= map_generation;
895 score_map[0]= dmin;
896
897 //FIXME precalc first term below?
901
902 /* first line */
906 (
last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
907 }else{
912 *mx_ptr= 0;
913 *my_ptr= 0;
915 return dmin;
916 }
923 (
last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
927 }
928 if(dmin>h*h*4){
931 (
last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
934 (
last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
935 }else{
937 (
last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
938 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
940 (
last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
941 }
942 }
943
946 const int xstart=
FFMAX(0, s->
mb_x - count);
947 const int ystart=
FFMAX(0, s->
mb_y - count);
951
952 for(mb_y=ystart; mb_y<yend; mb_y++){
954 for(mb_x=xstart; mb_x<xend; mb_x++){
955 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;
956 int mx= (
last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;
957 int my= (
last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;
958
959 if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue;
961 }
962 }
963 }
964
965 //check(best[0],best[1],0, b0)
966 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
967
968 //check(best[0],best[1],0, b1)
969 *mx_ptr= best[0];
970 *my_ptr= best[1];
971
972 return dmin;
973 }
974
975 //this function is dedicated to the braindamaged gcc
977 int P[10][2], int src_index, int ref_index,
978 int16_t (*
last_mv)[2],
int ref_mv_scale,
980 {
982 //FIXME convert other functions in the same way if faster
983 if(c->
flags==0 && h==16 && size==0){
984 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index,
last_mv, ref_mv_scale, 0, 0, 16);
985 // case FLAG_QPEL:
986 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
987 }else{
988 return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index,
last_mv, ref_mv_scale, c->
flags, size, h);
989 }
990 }
991
993 int *mx_ptr, int *my_ptr, int P[10][2],
994 int src_index,
int ref_index, int16_t (*
last_mv)[2],
995 int ref_mv_scale)
996 {
998 int best[2]={0, 0};
999 int d, dmin;
1000 unsigned map_generation;
1005 const int ref_mv_xy= s->
mb_x + s->
mb_y *ref_mv_stride;
1010
1013
1015
1016 dmin = 1000000;
1017
1018 /* first line */
1022 (
last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1024 }else{
1026 //FIXME try some early stop
1032 (
last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1033 }
1034 if(dmin>64*4){
1036 (
last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1037 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
1039 (
last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1040 }
1041
1042 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1043
1044 *mx_ptr= best[0];
1045 *my_ptr= best[1];
1046
1047 return dmin;
1048 }
1049
1050 //try to merge with above FIXME (needs PSNR test)
1052 int *mx_ptr, int *my_ptr, int P[10][2],
1053 int src_index,
int ref_index, int16_t (*
last_mv)[2],
1054 int ref_mv_scale)
1055 {
1057 int best[2]={0, 0};
1058 int d, dmin;
1059 unsigned map_generation;
1061 const int size=0;
//FIXME pass as arg
1064 const int ref_mv_xy= s->
mb_x + s->
mb_y *ref_mv_stride;
1069
1072
1074
1075 dmin = 1000000;
1076
1077 /* first line */
1081 (
last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1083 }else{
1085 //FIXME try some early stop
1091 (
last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1092 }
1093 if(dmin>64*4){
1095 (
last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1096 if(s->
mb_y+1<s->
end_mb_y)
//FIXME replace at least with last_slice_line
1098 (
last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1099 }
1100
1101 dmin=
diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1102
1103 *mx_ptr= best[0];
1104 *my_ptr= best[1];
1105
1106 return dmin;
1107 }
static uint8_t mv_penalty[MAX_FCODE+1][MAX_DMV *2+1]
Table of number of bits a motion vector component needs.
static int minima_cmp(const void *a, const void *b)
static unsigned update_map_generation(MotionEstContext *c)
static int shift(int a, int b)
static int epzs_motion_search2(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t(*last_mv)[2], int ref_mv_scale)
int skip
set if ME is skipped for the current MB
int last_mv[2][2][2]
last MV, used for MV prediction in MPEG1 & B-frame MPEG4
int pre_pass
= 1 for the pre pass
#define SAB_CHECK_MV(ax, ay)
int end_mb_y
end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) ...
static av_always_inline int diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
static int sab_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
static int funny_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
int mpv_flags
flags set by private options
me_cmp_func me_pre_cmp[6]
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
static int full_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
static av_cold int end(AVCodecContext *avctx)
Motion estimation context.
int me_cmp
motion estimation comparison function
static int umh_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t(*last_mv)[2], int ref_mv_scale, int size, int h)
int mb_height
number of MBs horizontally & vertically
#define CHECK_CLIPPED_MV(ax, ay)
int ff_get_mb_score(MpegEncContext *s, int mx, int my, int src_index, int ref_index, int size, int h, int add_rate)
static const uint16_t mask[17]
static int epzs_motion_search4(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t(*last_mv)[2], int ref_mv_scale)
static int no_sub_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
int me_sub_cmp
subpixel motion estimation comparison function
static av_always_inline int small_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
#define CHECK_MV_DIR(x, y, new_dir)
#define CHECK_HALF_MV(dx, dy, x, y)
static av_always_inline int epzs_motion_search_internal(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t(*last_mv)[2], int ref_mv_scale, int flags, int size, int h)
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static int hex_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags, int dia_size)
static int hpel_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
compares a block (either a full macroblock or a partition thereof) against a proposed motion-compensa...
int(* me_cmp_func)(struct MpegEncContext *c, uint8_t *blk1, uint8_t *blk2, ptrdiff_t stride, int h)
int last_predictor_count
amount of previous MV predictors (2a+1 x 2a+1 square)
static int get_mb_score(MpegEncContext *s, int mx, int my, int src_index, int ref_index, int size, int h, int add_rate)
static int qpel_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
int penalty_factor
an estimate of the bits required to code a given mv value, e.g.
static int l2s_dia_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
int first_slice_line
used in mpeg4 too to handle resync markers
#define CHECK_QUARTER_MV(dx, dy, x, y)
int pict_type
AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
struct AVCodecContext * avctx
int mb_stride
mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 ...
me_cmp_func me_sub_cmp[6]
uint32_t * map
map to avoid duplicate evaluations
int mv0_threshold
Note: Value depends upon the compare function used for fullpel ME.
static int var_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags)
int me_subpel_quality
subpel ME quality
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...