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 av_unused uint32_t * const score_map= c->score_map;\
33 av_unused const int xmin= c->xmin;\
34 av_unused const int ymin= c->ymin;\
35 av_unused const int xmax= c->xmax;\
36 av_unused const int ymax= c->ymax;\
37 const 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;
58 const int penalty_factor=
c->sub_penalty_factor;
61
64
65 //FIXME factorize
66
67 cmp_sub =
c->me_sub_cmp[
size];
68 chroma_cmp_sub =
c->me_sub_cmp[
size + 1];
69
70 if(
c->skip){
//FIXME move out of hpel?
71 *mx_ptr = 0;
72 *my_ptr = 0;
73 return dmin;
74 }
75
76 if(
c->avctx->me_cmp !=
c->avctx->me_sub_cmp){
77 dmin=
cmp(
s,
mx,
my, 0, 0,
size,
h, ref_index, src_index, cmp_sub, chroma_cmp_sub,
flags);
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
97 unsigned map_generation=
c->map_generation;
106 #endif
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) *= 2;
161 (*my_ptr) *= 2;
162 return dmin;
163 }
164
166 int src_index,
int ref_index,
int size,
168 {
170 const int penalty_factor=
c->mb_penalty_factor;
171 const int flags=
c->mb_flags;
173 const int mask= 1+2*qpel;
175 int d;
176
178
179 //FIXME factorize
180
181 cmp_sub =
c->mb_cmp[
size];
182 chroma_cmp_sub =
c->mb_cmp[
size + 1];
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 {
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;
215 const int penalty_factor=
c->sub_penalty_factor;
216 const unsigned map_generation =
c->map_generation;
217 const int subpel_quality=
c->avctx->me_subpel_quality;
218 uint32_t *
map=
c->map;
221
224
225 cmpf =
c->me_cmp[
size];
226 chroma_cmpf =
c->me_cmp[
size + 1];
// FIXME: factorize
227 //FIXME factorize
228
229 cmp_sub =
c->me_sub_cmp[
size];
230 chroma_cmp_sub =
c->me_sub_cmp[
size + 1];
231
232 if(
c->skip){
//FIXME somehow move up (benchmark)
233 *mx_ptr = 0;
234 *my_ptr = 0;
235 return dmin;
236 }
237
238 if(
c->avctx->me_cmp !=
c->avctx->me_sub_cmp){
239 dmin=
cmp(
s,
mx,
my, 0, 0,
size,
h, ref_index, src_index, cmp_sub, chroma_cmp_sub,
flags);
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;
255 int best[8];
256 int best_pos[8][2];
257
258 memset(best, 64, sizeof(int)*8);
259 if(
s->me.dia_size>=2){
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;
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
283 memmove(&best[
i+1], &best[
i],
sizeof(
int)*(7-
i));
284 memmove(&best_pos[
i + 1], &best_pos[
i],
sizeof(*best_pos) * (7 -
i));
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
305 }else{
306 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
307 }
308
309 cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*
c;
310
315 av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*
c == 32*tl);
316
317 for(ny= -3; ny <= 3; ny++){
318 for(nx= -3; nx <= 3; nx++){
319 //FIXME this could overflow (unlikely though)
320 int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*
c;
//FIXME factor
322
323 if((nx&3)==0 && (ny&3)==0) continue;
324
326 // if(nx&1) score-=32*c->penalty_factor;
327 // if(ny&1) score-=32*c->penalty_factor;
328
331 memmove(&best[
i+1], &best[
i],
sizeof(
int)*(7-
i));
332 memmove(best_pos[
i + 1], best_pos[
i],
sizeof(best_pos[0]) * (7 -
i));
334 best_pos[
i][0]= nx + 4*
mx;
335 best_pos[
i][1]= ny + 4*
my;
336 break;
337 }
338 }
339 }
340 }
341 }
342 for(
i=0;
i<subpel_quality;
i++){
346 }
347
348 av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
349
350 *mx_ptr = bx;
351 *my_ptr = by;
352 }else{
355 }
356
357 return dmin;
358 }
359
360
361 #define CHECK_MV(x,y)\
362 {\
363 const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
364 const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
365 av_assert2((x) >= xmin);\
366 av_assert2((x) <= xmax);\
367 av_assert2((y) >= ymin);\
368 av_assert2((y) <= ymax);\
369 if(map[index]!=key){\
370 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
371 map[index]= key;\
372 score_map[index]= d;\
373 d += (mv_penalty[((x)*(1<<shift))-pred_x] + mv_penalty[((y)*(1<<shift))-pred_y])*penalty_factor;\
374 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
375 }\
376 }
377
378 #define CHECK_CLIPPED_MV(ax,ay)\
379 {\
380 const int Lx= ax;\
381 const int Ly= ay;\
382 const int Lx2= FFMAX(xmin, FFMIN(Lx, xmax));\
383 const int Ly2= FFMAX(ymin, FFMIN(Ly, ymax));\
384 CHECK_MV(Lx2, Ly2)\
385 }
386
387 #define CHECK_MV_DIR(x,y,new_dir)\
388 {\
389 const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
390 const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
391 if(map[index]!=key){\
392 d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
393 map[index]= key;\
394 score_map[index]= d;\
395 d += (mv_penalty[(int)((unsigned)(x)<<shift)-pred_x] + mv_penalty[(int)((unsigned)(y)<<shift)-pred_y])*penalty_factor;\
396 if(d<dmin){\
397 best[0]=x;\
398 best[1]=y;\
399 dmin=d;\
400 next_dir= new_dir;\
401 }\
402 }\
403 }
404
405 #define check(x,y,S,v)\
406 if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->c.mb_x, s->c.mb_y);\
407 if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->c.mb_x, s->c.mb_y);\
408 if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->c.mb_x, s->c.mb_y);\
409 if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->c.mb_x, s->c.mb_y);\
410
411 #define LOAD_COMMON2\
412 uint32_t *map= c->map;\
413 const int qpel= flags&FLAG_QPEL;\
414 const int shift= 1+qpel;\
415
417 int src_index, int ref_index, const int penalty_factor,
419 {
422 int next_dir=-1;
425 unsigned map_generation =
c->map_generation;
426
427 cmpf =
c->me_cmp[
size];
428 chroma_cmpf =
c->me_cmp[
size + 1];
429
430 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
431 const unsigned key = ((unsigned)best[1]<<
ME_MAP_MV_BITS) + best[0] + map_generation;
433 if (
map[
index] !=
key) {
// this will be executed only very rarely
434 score_map[
index]=
cmp(
s, best[0], best[1], 0, 0,
size,
h, ref_index, src_index, cmpf, chroma_cmpf,
flags);
436 }
437 }
438
439 for(;;){
440 int d;
441 const int dir= next_dir;
442 const int x= best[0];
443 const int y= best[1];
444 next_dir=-1;
445
450
451 if(next_dir==-1){
452 return dmin;
453 }
454 }
455 }
456
458 int src_index, int ref_index, const int penalty_factor,
460 {
463 int dia_size;
466 unsigned map_generation =
c->map_generation;
467
468 cmpf =
c->me_cmp[
size];
469 chroma_cmpf =
c->me_cmp[
size + 1];
470
471 for(dia_size=1; dia_size<=4; dia_size++){
472 int dir;
473 const int x= best[0];
474 const int y= best[1];
475
476 if(dia_size&(dia_size-1)) continue;
477
478 if( x + dia_size > xmax
479 || x - dia_size < xmin
480 || y + dia_size > ymax
481 || y - dia_size < ymin)
482 continue;
483
484 for(dir= 0; dir<dia_size; dir+=2){
485 int d;
486
487 CHECK_MV(x + dir , y + dia_size - dir);
488 CHECK_MV(x + dia_size - dir, y - dir );
489 CHECK_MV(x - dir , y - dia_size + dir);
490 CHECK_MV(x - dia_size + dir, y + dir );
491 }
492
493 if(x!=best[0] || y!=best[1])
494 dia_size=0;
495 }
496 return dmin;
497 }
498
500 int src_index, int ref_index, const int penalty_factor,
502 {
507 unsigned map_generation =
c->map_generation;
508 int x,y,d;
509 const int dec= dia_size & (dia_size-1);
510
511 cmpf =
c->me_cmp[
size];
512 chroma_cmpf =
c->me_cmp[
size + 1];
513
514 for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
515 do{
516 x= best[0];
517 y= best[1];
518
523 if(dia_size>1){
526 }
527 }while(best[0] != x || best[1] != y);
528 }
529
530 return dmin;
531 }
532
534 int src_index, int ref_index, const int penalty_factor,
536 {
541 unsigned map_generation =
c->map_generation;
543 int dia_size=
c->dia_size&0xFF;
544 const int dec= dia_size & (dia_size-1);
545 static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
546 { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
547
548 cmpf =
c->me_cmp[
size];
549 chroma_cmpf =
c->me_cmp[
size + 1];
550
551 for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
552 do{
553 x= best[0];
554 y= best[1];
557 }
558 }while(best[0] != x || best[1] != y);
559 }
560
561 x= best[0];
562 y= best[1];
567
568 return dmin;
569 }
570
572 int src_index, int ref_index, const int penalty_factor,
574 {
579 unsigned map_generation =
c->map_generation;
580 int x,y,x2,y2,
i, j, d;
581 const int dia_size=
c->dia_size&0xFE;
582 static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
583 { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
584 {-2, 3}, { 0, 4}, { 2, 3},
585 {-2,-3}, { 0,-4}, { 2,-3},};
586
587 cmpf =
c->me_cmp[
size];
588 chroma_cmpf =
c->me_cmp[
size + 1];
589
590 x= best[0];
591 y= best[1];
592 for(x2=
FFMAX(x-dia_size+1, xmin); x2<=
FFMIN(x+dia_size-1,xmax); x2+=2){
594 }
595 for(y2=
FFMAX(y-dia_size/2+1, ymin); y2<=
FFMIN(y+dia_size/2-1,ymax); y2+=2){
597 }
598
599 x= best[0];
600 y= best[1];
601 for(y2=
FFMAX(y-2, ymin); y2<=
FFMIN(y+2,ymax); y2++){
602 for(x2=
FFMAX(x-2, xmin); x2<=
FFMIN(x+2,xmax); x2++){
604 }
605 }
606
607 //FIXME prevent the CLIP stuff
608
609 for(j=1; j<=dia_size/4; j++){
612 }
613 }
614
616 }
617
619 int src_index, int ref_index, const int penalty_factor,
621 {
626 unsigned map_generation =
c->map_generation;
627 int x,y, d;
628 const int dia_size=
c->dia_size&0xFF;
629
630 cmpf =
c->me_cmp[
size];
631 chroma_cmpf =
c->me_cmp[
size + 1];
632
633 for(y=
FFMAX(-dia_size, ymin); y<=
FFMIN(dia_size,ymax); y++){
634 for(x=
FFMAX(-dia_size, xmin); x<=
FFMIN(dia_size,xmax); x++){
636 }
637 }
638
639 x= best[0];
640 y= best[1];
641 d= dmin;
647 best[0]= x;
648 best[1]= y;
649
650 return d;
651 }
652
653 #define SAB_CHECK_MV(ax,ay)\
654 {\
655 const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
656 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
657 if(map[index]!=key){\
658 d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
659 map[index]= key;\
660 score_map[index]= d;\
661 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
662 if(d < minima[minima_count-1].height){\
663 int j=0;\
664 \
665 while(d >= minima[j].height) j++;\
666 \
667 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
668 \
669 minima[j].checked= 0;\
670 minima[j].height= d;\
671 minima[j].x= ax;\
672 minima[j].y= ay;\
673 \
674 i=-1;\
675 continue;\
676 }\
677 }\
678 }
679
680 #define MAX_SAB_SIZE ME_MAP_SIZE
682 int src_index, int ref_index, const int penalty_factor,
684 {
688 const int minima_count=
FFABS(
c->dia_size);
692 unsigned map_generation =
c->map_generation;
693
695
696 cmpf =
c->me_cmp[
size];
697 chroma_cmpf =
c->me_cmp[
size + 1];
698
699 /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
700 become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
701 */
704
706
708 continue;
709
710 minima[j].
height= score_map[
i];
715
716 // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space
717 if( minima[j].x > xmax || minima[j].x < xmin
718 || minima[j].y > ymax || minima[j].y < ymin)
719 continue;
720
722 if(minima[j].x || minima[j].y)
724
725 j++;
726 }
727
729
730 for(; j<minima_count; j++){
731 minima[j].
height=256*256*256*64;
733 minima[j].
x= minima[j].
y=0;
734 }
735
736 for(
i=0;
i<minima_count;
i++){
737 const int x= minima[
i].
x;
738 const int y= minima[
i].
y;
739 int d;
740
741 if(minima[
i].checked)
continue;
742
743 if( x >= xmax || x <= xmin
744 || y >= ymax || y <= ymin)
745 continue;
746
751
753 }
754
755 best[0]= minima[0].
x;
756 best[1]= minima[0].
y;
758
759 if( best[0] < xmax && best[0] > xmin
760 && best[1] < ymax && best[1] > ymin){
761 int d;
762 // ensure that the reference samples for hpel refinement are in the map
767 }
768 return dmin;
769 }
770
772 int src_index, int ref_index, const int penalty_factor,
774 {
777 int dia_size;
780 unsigned map_generation =
c->map_generation;
781
782 cmpf =
c->me_cmp[
size];
783 chroma_cmpf =
c->me_cmp[
size + 1];
784
785 for(dia_size=1; dia_size<=
c->dia_size; dia_size++){
786 int dir, start, end;
787 const int x= best[0];
788 const int y= best[1];
789
790 start=
FFMAX(0, y + dia_size - ymax);
791 end =
FFMIN(dia_size, xmax - x + 1);
792 for(dir= start; dir<end; dir++){
793 int d;
794
795 //check(x + dir,y + dia_size - dir,0, a0)
796 CHECK_MV(x + dir , y + dia_size - dir);
797 }
798
799 start=
FFMAX(0, x + dia_size - xmax);
800 end =
FFMIN(dia_size, y - ymin + 1);
801 for(dir= start; dir<end; dir++){
802 int d;
803
804 //check(x + dia_size - dir, y - dir,0, a1)
805 CHECK_MV(x + dia_size - dir, y - dir );
806 }
807
808 start=
FFMAX(0, -y + dia_size + ymin );
809 end =
FFMIN(dia_size, x - xmin + 1);
810 for(dir= start; dir<end; dir++){
811 int d;
812
813 //check(x - dir,y - dia_size + dir,0, a2)
814 CHECK_MV(x - dir , y - dia_size + dir);
815 }
816
817 start=
FFMAX(0, -x + dia_size + xmin );
818 end =
FFMIN(dia_size, ymax - y + 1);
819 for(dir= start; dir<end; dir++){
820 int d;
821
822 //check(x - dia_size + dir, y + dir,0, a3)
823 CHECK_MV(x - dia_size + dir, y + dir );
824 }
825
826 if(x!=best[0] || y!=best[1])
827 dia_size=0;
828 }
829 return dmin;
830 }
831
833 int src_index, int ref_index, const int penalty_factor,
838 else if(
c->dia_size<-1)
840 else if(
c->dia_size<2)
842 else if(
c->dia_size>1024)
844 else if(
c->dia_size>768)
846 else if(
c->dia_size>512)
848 else if(
c->dia_size>256)
850 else
852 }
853
854 /**
855 @param P a list of candidate mvs to check before starting the
856 iterative search. If one of the candidates is close to the optimal mv, then
857 it takes fewer iterations. And it increases the chance that we find the
858 optimal mv.
859 */
861 int P[10][2],
int src_index,
int ref_index,
const int16_t (*last_mv)[2],
863 {
865 int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
866 i.e. the difference between the position of the
867 block currently being encoded and the position of
868 the block chosen to predict it from. */
869 int d; ///< the score (cmp + penalty) of any given mv
870 int dmin; /**< the best value of d, i.e. the score
871 corresponding to the mv stored in best[]. */
872 unsigned map_generation;
873 int penalty_factor;
874 const int ref_mv_stride=
s->c.mb_stride;
//pass as arg FIXME
875 const int ref_mv_xy =
s->c.mb_x +
s->c.mb_y * ref_mv_stride;
// add to last_mv before passing FIXME
877
880
882 penalty_factor=
c->pre_penalty_factor;
883 cmpf =
c->me_pre_cmp[
size];
884 chroma_cmpf =
c->me_pre_cmp[
size + 1];
885 }else{
886 penalty_factor=
c->penalty_factor;
887 cmpf =
c->me_cmp[
size];
888 chroma_cmpf =
c->me_cmp[
size + 1];
889 }
890
892
894 dmin=
cmp(
s, 0, 0, 0, 0,
size,
h, ref_index, src_index, cmpf, chroma_cmpf,
flags);
895 map[0]= map_generation;
896 score_map[0]= dmin;
897
898 //FIXME precalc first term below?
902
903 /* first line */
904 if (
s->c.first_slice_line) {
907 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
908 }else{
909 if (dmin < ((
h *
h *
c->avctx->mv0_threshold) >> 8)
913 *mx_ptr= 0;
914 *my_ptr= 0;
916 return dmin;
917 }
924 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
928 }
932 (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
933 if(!
s->c.first_slice_line)
934 CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
935 (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
936 }else{
938 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
939 if(
s->c.mb_y+1<
s->c.end_mb_y)
//FIXME replace at least with last_slice_line
940 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
941 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
942 }
943 }
944
945 if(
c->avctx->last_predictor_count){
946 const int count=
c->avctx->last_predictor_count;
947 const int xstart=
FFMAX(0,
s->c.mb_x - count);
948 const int ystart=
FFMAX(0,
s->c.mb_y - count);
949 const int xend=
FFMIN(
s->c.mb_width ,
s->c.mb_x + count + 1);
950 const int yend=
FFMIN(
s->c.mb_height,
s->c.mb_y + count + 1);
951 int mb_y;
952
953 for(mb_y=ystart; mb_y<yend; mb_y++){
954 int mb_x;
955 for(mb_x=xstart; mb_x<xend; mb_x++){
956 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;
957 int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;
958 int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;
959
960 if(
mx>xmax || mx<xmin || my>ymax ||
my<ymin)
continue;
962 }
963 }
964 }
965
966 //check(best[0],best[1],0, b0)
968
969 //check(best[0],best[1],0, b1)
970 *mx_ptr= best[0];
971 *my_ptr= best[1];
972
973 return dmin;
974 }
975
976 //this function is dedicated to the brain damaged gcc
978 int P[10][2],
int src_index,
int ref_index,
979 const int16_t (*last_mv)[2], int ref_mv_scale,
981 {
983 //FIXME convert other functions in the same way if faster
984 if(
c->flags==0 &&
h==16 &&
size==0){
985 return epzs_motion_search_internal(
s, mx_ptr, my_ptr,
P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
986 // case FLAG_QPEL:
987 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
988 }else{
989 return epzs_motion_search_internal(
s, mx_ptr, my_ptr,
P, src_index, ref_index, last_mv, ref_mv_scale,
c->flags,
size,
h);
990 }
991 }
992
994 int *mx_ptr,
int *my_ptr,
int P[10][2],
995 int src_index, int ref_index, const int16_t (*last_mv)[2],
996 int ref_mv_scale,
const int size)
997 {
999 int best[2]={0, 0};
1000 int d, dmin;
1001 unsigned map_generation;
1002 const int penalty_factor=
c->penalty_factor;
1004 const int ref_mv_stride=
s->c.mb_stride;
1005 const int ref_mv_xy=
s->c.mb_x +
s->c.mb_y *ref_mv_stride;
1010
1011 cmpf =
c->me_cmp[
size];
1012 chroma_cmpf =
c->me_cmp[
size + 1];
1013
1015
1016 dmin = 1000000;
1017
1018 /* first line */
1019 if (
s->c.first_slice_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->c.mb_y+1<
s->c.end_mb_y)
//FIXME replace at least with last_slice_line
1038 CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1039 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1040 }
1041
1043
1044 *mx_ptr= best[0];
1045 *my_ptr= best[1];
1046
1047 return dmin;
1048 }