Mercurial > libavcodec.hg
comparison motion_est_template.c @ 948:371bc36a9c5c libavcodec
shape adaptive diamonds for EPZS
user specified amount of MV predictors from the last frame
b frame MV predictor scaling fixed
author | michaelni |
---|---|
date | Wed, 01 Jan 2003 14:36:20 +0000 |
parents | caa77cd960c0 |
children | f348d302a51e |
comparison
equal
deleted
inserted
replaced
947:9be53be2d1a9 | 948:371bc36a9c5c |
---|---|
65 #if 0 | 65 #if 0 |
66 static int RENAME(hpel_motion_search)(MpegEncContext * s, | 66 static int RENAME(hpel_motion_search)(MpegEncContext * s, |
67 int *mx_ptr, int *my_ptr, int dmin, | 67 int *mx_ptr, int *my_ptr, int dmin, |
68 int xmin, int ymin, int xmax, int ymax, | 68 int xmin, int ymin, int xmax, int ymax, |
69 int pred_x, int pred_y, Picture *ref_picture, | 69 int pred_x, int pred_y, Picture *ref_picture, |
70 int n, int size) | 70 int n, int size, uint16_t * const mv_penalty) |
71 { | 71 { |
72 UINT8 *ptr; | |
73 | |
74 const int xx = 16 * s->mb_x + 8*(n&1); | 72 const int xx = 16 * s->mb_x + 8*(n&1); |
75 const int yy = 16 * s->mb_y + 8*(n>>1); | 73 const int yy = 16 * s->mb_y + 8*(n>>1); |
76 const int mx = *mx_ptr; | 74 const int mx = *mx_ptr; |
77 const int my = *my_ptr; | 75 const int my = *my_ptr; |
76 const int penalty_factor= s->me.sub_penalty_factor; | |
78 | 77 |
79 LOAD_COMMON(xx, yy); | 78 LOAD_COMMON(xx, yy); |
80 | 79 |
81 // INIT; | 80 // INIT; |
82 //FIXME factorize | 81 //FIXME factorize |
118 CHECK_HALF_MV(1, 0, mx , my ) | 117 CHECK_HALF_MV(1, 0, mx , my ) |
119 CHECK_HALF_MV(1, 1, mx-1, my ) | 118 CHECK_HALF_MV(1, 1, mx-1, my ) |
120 CHECK_HALF_MV(0, 1, mx , my ) | 119 CHECK_HALF_MV(0, 1, mx , my ) |
121 CHECK_HALF_MV(1, 1, mx , my ) | 120 CHECK_HALF_MV(1, 1, mx , my ) |
122 | 121 |
123 assert(bx < xmin*2 || bx > xmax*2 || by < ymin*2 || by > ymax*2); | 122 assert(bx >= xmin*2 || bx <= xmax*2 || by >= ymin*2 || by <= ymax*2); |
124 | 123 |
125 *mx_ptr = bx; | 124 *mx_ptr = bx; |
126 *my_ptr = by; | 125 *my_ptr = by; |
127 }else{ | 126 }else{ |
128 *mx_ptr =2*mx; | 127 *mx_ptr =2*mx; |
169 my > ymin && my < ymax) { | 168 my > ymin && my < ymax) { |
170 int bx=2*mx, by=2*my; | 169 int bx=2*mx, by=2*my; |
171 int d= dmin; | 170 int d= dmin; |
172 const int index= (my<<ME_MAP_SHIFT) + mx; | 171 const int index= (my<<ME_MAP_SHIFT) + mx; |
173 const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] | 172 const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] |
174 + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*penalty_factor; | 173 + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*s->me.penalty_factor; |
175 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] | 174 const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] |
176 + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*penalty_factor; | 175 + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*s->me.penalty_factor; |
177 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)] | 176 const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)] |
178 + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*penalty_factor; | 177 + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*s->me.penalty_factor; |
179 const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] | 178 const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] |
180 + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*penalty_factor; | 179 + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*s->me.penalty_factor; |
181 | 180 |
181 #if 0 | |
182 int key; | |
183 int map_generation= s->me.map_generation; | |
184 uint32_t *map= s->me.map; | |
185 key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation; | |
186 assert(map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key); | |
187 key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation; | |
188 assert(map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key); | |
189 key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation; | |
190 assert(map[(index+1)&(ME_MAP_SIZE-1)] == key); | |
191 key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation; | |
192 assert(map[(index-1)&(ME_MAP_SIZE-1)] == key); | |
193 #endif | |
182 if(t<=b){ | 194 if(t<=b){ |
183 CHECK_HALF_MV(0, 1, mx ,my-1) | 195 CHECK_HALF_MV(0, 1, mx ,my-1) |
184 if(l<=r){ | 196 if(l<=r){ |
185 CHECK_HALF_MV(1, 1, mx-1, my-1) | 197 CHECK_HALF_MV(1, 1, mx-1, my-1) |
186 if(t+r<=b+l){ | 198 if(t+r<=b+l){ |
458 | 470 |
459 #define CHECK_MV(x,y)\ | 471 #define CHECK_MV(x,y)\ |
460 {\ | 472 {\ |
461 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ | 473 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ |
462 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ | 474 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ |
475 /*printf("check_mv %d %d\n", x, y);*/\ | |
463 if(map[index]!=key){\ | 476 if(map[index]!=key){\ |
464 CMP(d, x, y, size);\ | 477 CMP(d, x, y, size);\ |
465 map[index]= key;\ | 478 map[index]= key;\ |
466 score_map[index]= d;\ | 479 score_map[index]= d;\ |
467 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\ | 480 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\ |
481 /*printf("score:%d\n", d);*/\ | |
468 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\ | 482 COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\ |
469 }\ | 483 }\ |
484 } | |
485 | |
486 #define CHECK_CLIPED_MV(ax,ay)\ | |
487 {\ | |
488 const int x= FFMAX(xmin, FFMIN(ax, xmax));\ | |
489 const int y= FFMAX(ymin, FFMIN(ay, ymax));\ | |
490 CHECK_MV(x, y)\ | |
470 } | 491 } |
471 | 492 |
472 #define CHECK_MV_DIR(x,y,new_dir)\ | 493 #define CHECK_MV_DIR(x,y,new_dir)\ |
473 {\ | 494 {\ |
474 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ | 495 const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ |
475 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ | 496 const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ |
497 /*printf("check_mv_dir %d %d %d\n", x, y, new_dir);*/\ | |
476 if(map[index]!=key){\ | 498 if(map[index]!=key){\ |
477 CMP(d, x, y, size);\ | 499 CMP(d, x, y, size);\ |
478 map[index]= key;\ | 500 map[index]= key;\ |
479 score_map[index]= d;\ | 501 score_map[index]= d;\ |
480 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\ | 502 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\ |
503 /*printf("score:%d\n", d);*/\ | |
481 if(d<dmin){\ | 504 if(d<dmin){\ |
482 best[0]=x;\ | 505 best[0]=x;\ |
483 best[1]=y;\ | 506 best[1]=y;\ |
484 dmin=d;\ | 507 dmin=d;\ |
485 next_dir= new_dir;\ | 508 next_dir= new_dir;\ |
506 LOAD_COMMON(s->mb_x*16, s->mb_y*16); | 529 LOAD_COMMON(s->mb_x*16, s->mb_y*16); |
507 | 530 |
508 cmp= s->dsp.me_cmp[size]; | 531 cmp= s->dsp.me_cmp[size]; |
509 chroma_cmp= s->dsp.me_cmp[size+1]; | 532 chroma_cmp= s->dsp.me_cmp[size+1]; |
510 | 533 |
534 { /* ensure that the best point is in the MAP as h/qpel refinement needs it */ | |
535 const int key= (best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation; | |
536 const int index= ((best[1]<<ME_MAP_SHIFT) + best[0])&(ME_MAP_SIZE-1); | |
537 if(map[index]!=key){ //this will be executed only very rarey | |
538 CMP(score_map[index], best[0], best[1], size); | |
539 map[index]= key; | |
540 } | |
541 } | |
542 | |
511 for(;;){ | 543 for(;;){ |
512 int d; | 544 int d; |
513 const int dir= next_dir; | 545 const int dir= next_dir; |
514 const int x= best[0]; | 546 const int x= best[0]; |
515 const int y= best[1]; | 547 const int y= best[1]; |
525 return dmin; | 557 return dmin; |
526 } | 558 } |
527 } | 559 } |
528 } | 560 } |
529 | 561 |
562 static inline int RENAME(funny_diamond_search)(MpegEncContext * s, int *best, int dmin, | |
563 Picture *ref_picture, | |
564 int const pred_x, int const pred_y, int const penalty_factor, | |
565 int const xmin, int const ymin, int const xmax, int const ymax, int const shift, | |
566 uint32_t *map, int map_generation, int size, uint16_t * const mv_penalty | |
567 ) | |
568 { | |
569 me_cmp_func cmp, chroma_cmp; | |
570 int dia_size; | |
571 LOAD_COMMON(s->mb_x*16, s->mb_y*16); | |
572 | |
573 cmp= s->dsp.me_cmp[size]; | |
574 chroma_cmp= s->dsp.me_cmp[size+1]; | |
575 | |
576 for(dia_size=1; dia_size<=4; dia_size++){ | |
577 int dir; | |
578 const int x= best[0]; | |
579 const int y= best[1]; | |
580 | |
581 if(dia_size&(dia_size-1)) continue; | |
582 | |
583 if( x + dia_size > xmax | |
584 || x - dia_size < xmin | |
585 || y + dia_size > ymax | |
586 || y - dia_size < ymin) | |
587 continue; | |
588 | |
589 for(dir= 0; dir<dia_size; dir+=2){ | |
590 int d; | |
591 | |
592 CHECK_MV(x + dir , y + dia_size - dir); | |
593 CHECK_MV(x + dia_size - dir, y - dir ); | |
594 CHECK_MV(x - dir , y - dia_size + dir); | |
595 CHECK_MV(x - dia_size + dir, y + dir ); | |
596 } | |
597 | |
598 if(x!=best[0] || y!=best[1]) | |
599 dia_size=0; | |
600 #if 0 | |
601 { | |
602 int dx, dy, i; | |
603 static int stats[8*8]; | |
604 dx= ABS(x-best[0]); | |
605 dy= ABS(y-best[1]); | |
606 if(dy>dx){ | |
607 dx^=dy; dy^=dx; dx^=dy; | |
608 } | |
609 stats[dy*8 + dx] ++; | |
610 if(256*256*256*64 % (stats[0]+1)==0){ | |
611 for(i=0; i<64; i++){ | |
612 if((i&7)==0) printf("\n"); | |
613 printf("%8d ", stats[i]); | |
614 } | |
615 printf("\n"); | |
616 } | |
617 } | |
618 #endif | |
619 } | |
620 return dmin; | |
621 } | |
622 | |
623 #define SAB_CHECK_MV(ax,ay)\ | |
624 {\ | |
625 const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\ | |
626 const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\ | |
627 /*printf("sab check %d %d\n", ax, ay);*/\ | |
628 if(map[index]!=key){\ | |
629 CMP(d, ax, ay, size);\ | |
630 map[index]= key;\ | |
631 score_map[index]= d;\ | |
632 d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\ | |
633 /*printf("score: %d\n", d);*/\ | |
634 if(d < minima[minima_count-1].height){\ | |
635 int j=0;\ | |
636 \ | |
637 while(d >= minima[j].height) j++;\ | |
638 \ | |
639 memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\ | |
640 \ | |
641 minima[j].checked= 0;\ | |
642 minima[j].height= d;\ | |
643 minima[j].x= ax;\ | |
644 minima[j].y= ay;\ | |
645 \ | |
646 i=-1;\ | |
647 continue;\ | |
648 }\ | |
649 }\ | |
650 } | |
651 | |
652 #define MAX_SAB_SIZE 16 | |
653 static inline int RENAME(sab_diamond_search)(MpegEncContext * s, int *best, int dmin, | |
654 Picture *ref_picture, | |
655 int const pred_x, int const pred_y, int const penalty_factor, | |
656 int const xmin, int const ymin, int const xmax, int const ymax, int const shift, | |
657 uint32_t *map, int map_generation, int size, uint16_t * const mv_penalty | |
658 ) | |
659 { | |
660 me_cmp_func cmp, chroma_cmp; | |
661 Minima minima[MAX_SAB_SIZE]; | |
662 const int minima_count= ABS(s->avctx->dia_size); | |
663 int i, j; | |
664 LOAD_COMMON(s->mb_x*16, s->mb_y*16); | |
665 | |
666 cmp= s->dsp.me_cmp[size]; | |
667 chroma_cmp= s->dsp.me_cmp[size+1]; | |
668 | |
669 for(j=i=0; i<ME_MAP_SIZE; i++){ | |
670 uint32_t key= map[i]; | |
671 | |
672 key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1)); | |
673 | |
674 if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue; | |
675 | |
676 assert(j<MAX_SAB_SIZE); //max j = number of predictors | |
677 | |
678 minima[j].height= score_map[i]; | |
679 minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS; | |
680 minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1); | |
681 minima[j].x-= (1<<(ME_MAP_MV_BITS-1)); | |
682 minima[j].y-= (1<<(ME_MAP_MV_BITS-1)); | |
683 minima[j].checked=0; | |
684 if(minima[j].x || minima[j].y) | |
685 minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor; | |
686 | |
687 j++; | |
688 } | |
689 | |
690 qsort(minima, j, sizeof(Minima), minima_cmp); | |
691 | |
692 for(; j<minima_count; j++){ | |
693 minima[j].height=256*256*256*64; | |
694 minima[j].checked=0; | |
695 minima[j].x= minima[j].y=0; | |
696 } | |
697 | |
698 for(i=0; i<minima_count; i++){ | |
699 const int x= minima[i].x; | |
700 const int y= minima[i].y; | |
701 int d; | |
702 | |
703 if(minima[i].checked) continue; | |
704 | |
705 if( x >= xmax || x <= xmin | |
706 || y >= ymax || y <= ymin) | |
707 continue; | |
708 | |
709 SAB_CHECK_MV(x-1, y) | |
710 SAB_CHECK_MV(x+1, y) | |
711 SAB_CHECK_MV(x , y-1) | |
712 SAB_CHECK_MV(x , y+1) | |
713 | |
714 minima[i].checked= 1; | |
715 } | |
716 | |
717 best[0]= minima[0].x; | |
718 best[1]= minima[0].y; | |
719 dmin= minima[0].height; | |
720 | |
721 if( best[0] < xmax && best[0] > xmin | |
722 && best[1] < ymax && best[1] > ymin){ | |
723 int d; | |
724 //ensure that the refernece samples for hpel refinement are in the map | |
725 CHECK_MV(best[0]-1, best[1]) | |
726 CHECK_MV(best[0]+1, best[1]) | |
727 CHECK_MV(best[0], best[1]-1) | |
728 CHECK_MV(best[0], best[1]+1) | |
729 } | |
730 return dmin; | |
731 } | |
732 | |
530 static inline int RENAME(var_diamond_search)(MpegEncContext * s, int *best, int dmin, | 733 static inline int RENAME(var_diamond_search)(MpegEncContext * s, int *best, int dmin, |
531 Picture *ref_picture, | 734 Picture *ref_picture, |
532 int const pred_x, int const pred_y, int const penalty_factor, | 735 int const pred_x, int const pred_y, int const penalty_factor, |
533 int const xmin, int const ymin, int const xmax, int const ymax, int const shift, | 736 int const xmin, int const ymin, int const xmax, int const ymax, int const shift, |
534 uint32_t *map, int map_generation, int size, uint16_t * const mv_penalty | 737 uint32_t *map, int map_generation, int size, uint16_t * const mv_penalty |
535 ) | 738 ) |
536 { | 739 { |
537 me_cmp_func cmp, chroma_cmp; | 740 me_cmp_func cmp, chroma_cmp; |
538 int dia_size=1; | 741 int dia_size; |
539 LOAD_COMMON(s->mb_x*16, s->mb_y*16); | 742 LOAD_COMMON(s->mb_x*16, s->mb_y*16); |
540 | 743 |
541 cmp= s->dsp.me_cmp[size]; | 744 cmp= s->dsp.me_cmp[size]; |
542 chroma_cmp= s->dsp.me_cmp[size+1]; | 745 chroma_cmp= s->dsp.me_cmp[size+1]; |
543 | 746 |
545 int dir, start, end; | 748 int dir, start, end; |
546 const int x= best[0]; | 749 const int x= best[0]; |
547 const int y= best[1]; | 750 const int y= best[1]; |
548 | 751 |
549 start= FFMAX(0, y + dia_size - ymax); | 752 start= FFMAX(0, y + dia_size - ymax); |
550 end = FFMIN(dia_size, xmax - x); | 753 end = FFMIN(dia_size, xmax - x + 1); |
551 for(dir= start; dir<end; dir++){ | 754 for(dir= start; dir<end; dir++){ |
552 int d; | 755 int d; |
553 | 756 |
554 //check(x + dir,y + dia_size - dir,0, a0) | 757 //check(x + dir,y + dia_size - dir,0, a0) |
555 CHECK_MV(x + dir , y + dia_size - dir); | 758 CHECK_MV(x + dir , y + dia_size - dir); |
556 } | 759 } |
557 | 760 |
558 start= FFMAX(0, x + dia_size - xmax); | 761 start= FFMAX(0, x + dia_size - xmax); |
559 end = FFMIN(dia_size, y - ymin); | 762 end = FFMIN(dia_size, y - ymin + 1); |
560 for(dir= start; dir<end; dir++){ | 763 for(dir= start; dir<end; dir++){ |
561 int d; | 764 int d; |
562 | 765 |
563 //check(x + dia_size - dir, y - dir,0, a1) | 766 //check(x + dia_size - dir, y - dir,0, a1) |
564 CHECK_MV(x + dia_size - dir, y - dir ); | 767 CHECK_MV(x + dia_size - dir, y - dir ); |
565 } | 768 } |
566 | 769 |
567 start= FFMAX(0, -y + dia_size + ymin ); | 770 start= FFMAX(0, -y + dia_size + ymin ); |
568 end = FFMIN(dia_size, x - xmin); | 771 end = FFMIN(dia_size, x - xmin + 1); |
569 for(dir= start; dir<end; dir++){ | 772 for(dir= start; dir<end; dir++){ |
570 int d; | 773 int d; |
571 | 774 |
572 //check(x - dir,y - dia_size + dir,0, a2) | 775 //check(x - dir,y - dia_size + dir,0, a2) |
573 CHECK_MV(x - dir , y - dia_size + dir); | 776 CHECK_MV(x - dir , y - dia_size + dir); |
574 } | 777 } |
575 | 778 |
576 start= FFMAX(0, -x + dia_size + xmin ); | 779 start= FFMAX(0, -x + dia_size + xmin ); |
577 end = FFMIN(dia_size, ymax - y); | 780 end = FFMIN(dia_size, ymax - y + 1); |
578 for(dir= start; dir<end; dir++){ | 781 for(dir= start; dir<end; dir++){ |
579 int d; | 782 int d; |
580 | 783 |
581 //check(x - dia_size + dir, y + dir,0, a3) | 784 //check(x - dia_size + dir, y + dir,0, a3) |
582 CHECK_MV(x - dia_size + dir, y + dir ); | 785 CHECK_MV(x - dia_size + dir, y + dir ); |
583 } | 786 } |
584 | 787 |
585 if(x!=best[0] || y!=best[1]) | 788 if(x!=best[0] || y!=best[1]) |
586 dia_size=0; | 789 dia_size=0; |
790 #if 0 | |
791 { | |
792 int dx, dy, i; | |
793 static int stats[8*8]; | |
794 dx= ABS(x-best[0]); | |
795 dy= ABS(y-best[1]); | |
796 stats[dy*8 + dx] ++; | |
797 if(256*256*256*64 % (stats[0]+1)==0){ | |
798 for(i=0; i<64; i++){ | |
799 if((i&7)==0) printf("\n"); | |
800 printf("%6d ", stats[i]); | |
801 } | |
802 printf("\n"); | |
803 } | |
804 } | |
805 #endif | |
587 } | 806 } |
588 return dmin; | 807 return dmin; |
589 } | 808 } |
590 | 809 |
591 static int RENAME(epzs_motion_search)(MpegEncContext * s, int block, | 810 static int RENAME(epzs_motion_search)(MpegEncContext * s, int block, |
592 int *mx_ptr, int *my_ptr, | 811 int *mx_ptr, int *my_ptr, |
593 int P[10][2], int pred_x, int pred_y, | 812 int P[10][2], int pred_x, int pred_y, |
594 int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, uint16_t * const mv_penalty) | 813 int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, int16_t (*last_mv)[2], |
814 int ref_mv_scale, uint16_t * const mv_penalty) | |
595 { | 815 { |
596 int best[2]={0, 0}; | 816 int best[2]={0, 0}; |
597 int d, dmin; | 817 int d, dmin; |
598 const int shift= 1+s->quarter_sample; | 818 const int shift= 1+s->quarter_sample; |
599 uint32_t *map= s->me.map; | 819 uint32_t *map= s->me.map; |
600 int map_generation; | 820 int map_generation; |
601 const int penalty_factor= s->me.penalty_factor; | 821 const int penalty_factor= s->me.penalty_factor; |
602 const int size=0; | 822 const int size=0; |
823 const int ref_mv_stride= s->mb_width+2; | |
824 const int ref_mv_xy= 1 + s->mb_x + (s->mb_y + 1)*ref_mv_stride; | |
603 me_cmp_func cmp, chroma_cmp; | 825 me_cmp_func cmp, chroma_cmp; |
604 LOAD_COMMON(s->mb_x*16, s->mb_y*16); | 826 LOAD_COMMON(s->mb_x*16, s->mb_y*16); |
605 | 827 |
606 cmp= s->dsp.me_cmp[size]; | 828 cmp= s->dsp.me_cmp[size]; |
607 chroma_cmp= s->dsp.me_cmp[size+1]; | 829 chroma_cmp= s->dsp.me_cmp[size+1]; |
613 score_map[0]= dmin; | 835 score_map[0]= dmin; |
614 | 836 |
615 /* first line */ | 837 /* first line */ |
616 if ((s->mb_y == 0 || s->first_slice_line)) { | 838 if ((s->mb_y == 0 || s->first_slice_line)) { |
617 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) | 839 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) |
618 CHECK_MV(P_LAST[0]>>shift, P_LAST[1]>>shift) | 840 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
841 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) | |
619 }else{ | 842 }else{ |
620 if(dmin<256 && ( P_LEFT[0] |P_LEFT[1] | 843 if(dmin<256 && ( P_LEFT[0] |P_LEFT[1] |
621 |P_TOP[0] |P_TOP[1] | 844 |P_TOP[0] |P_TOP[1] |
622 |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0 && s->avctx->dia_size==0){ | 845 |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){ |
623 *mx_ptr= 0; | 846 *mx_ptr= 0; |
624 *my_ptr= 0; | 847 *my_ptr= 0; |
625 s->me.skip=1; | 848 s->me.skip=1; |
626 return dmin; | 849 return dmin; |
627 } | 850 } |
628 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) | 851 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) |
629 if(dmin>256*2){ | 852 if(dmin>256*2){ |
630 CHECK_MV(P_LAST[0] >>shift, P_LAST[1] >>shift) | 853 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
854 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) | |
631 CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift) | 855 CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift) |
632 CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift) | 856 CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift) |
633 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) | 857 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) |
634 } | 858 } |
635 } | 859 } |
636 if(dmin>256*4){ | 860 if(dmin>256*4){ |
637 CHECK_MV(P_LAST_RIGHT[0] >>shift, P_LAST_RIGHT[1] >>shift) | 861 CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, |
638 CHECK_MV(P_LAST_BOTTOM[0]>>shift, P_LAST_BOTTOM[1]>>shift) | 862 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) |
639 } | 863 CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, |
640 #if 0 //doest only slow things down | 864 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) |
641 if(dmin>512*3){ | 865 } |
642 int step; | 866 |
643 dmin= score_map[0]; | 867 if(s->avctx->last_predictor_count){ |
644 best[0]= best[1]=0; | 868 const int count= s->avctx->last_predictor_count; |
645 for(step=128; step>0; step>>=1){ | 869 const int xstart= FFMAX(0, s->mb_x - count); |
646 const int step2= step; | 870 const int ystart= FFMAX(0, s->mb_y - count); |
647 int y; | 871 const int xend= FFMIN(s->mb_width , s->mb_x + count + 1); |
648 for(y=-step2+best[1]; y<=step2+best[1]; y+=step){ | 872 const int yend= FFMIN(s->mb_height, s->mb_y + count + 1); |
649 int x; | 873 int mb_y; |
650 if(y<ymin || y>ymax) continue; | 874 |
651 | 875 for(mb_y=ystart; mb_y<yend; mb_y++){ |
652 for(x=-step2+best[0]; x<=step2+best[0]; x+=step){ | 876 int mb_x; |
653 if(x<xmin || x>xmax) continue; | 877 for(mb_x=xstart; mb_x<xend; mb_x++){ |
654 if(x==best[0] && y==best[1]) continue; | 878 const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride; |
655 CHECK_MV(x,y) | 879 int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16; |
656 } | 880 int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16; |
881 | |
882 if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue; | |
883 CHECK_MV(mx,my) | |
657 } | 884 } |
658 } | 885 } |
659 } | 886 } |
660 #endif | 887 |
661 //check(best[0],best[1],0, b0) | 888 //check(best[0],best[1],0, b0) |
662 if(s->avctx->dia_size<2) | 889 if(s->avctx->dia_size==-1) |
890 dmin= RENAME(funny_diamond_search)(s, best, dmin, ref_picture, | |
891 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | |
892 shift, map, map_generation, size, mv_penalty); | |
893 else if(s->avctx->dia_size<-1) | |
894 dmin= RENAME(sab_diamond_search)(s, best, dmin, ref_picture, | |
895 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | |
896 shift, map, map_generation, size, mv_penalty); | |
897 else if(s->avctx->dia_size<2) | |
663 dmin= RENAME(small_diamond_search)(s, best, dmin, ref_picture, | 898 dmin= RENAME(small_diamond_search)(s, best, dmin, ref_picture, |
664 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | 899 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, |
665 shift, map, map_generation, size, mv_penalty); | 900 shift, map, map_generation, size, mv_penalty); |
666 else | 901 else |
667 dmin= RENAME(var_diamond_search)(s, best, dmin, ref_picture, | 902 dmin= RENAME(var_diamond_search)(s, best, dmin, ref_picture, |
678 | 913 |
679 #ifndef CMP_DIRECT /* no 4mv search needed in direct mode */ | 914 #ifndef CMP_DIRECT /* no 4mv search needed in direct mode */ |
680 static int RENAME(epzs_motion_search4)(MpegEncContext * s, int block, | 915 static int RENAME(epzs_motion_search4)(MpegEncContext * s, int block, |
681 int *mx_ptr, int *my_ptr, | 916 int *mx_ptr, int *my_ptr, |
682 int P[10][2], int pred_x, int pred_y, | 917 int P[10][2], int pred_x, int pred_y, |
683 int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, uint16_t * const mv_penalty) | 918 int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, int16_t (*last_mv)[2], |
919 int ref_mv_scale, uint16_t * const mv_penalty) | |
684 { | 920 { |
685 int best[2]={0, 0}; | 921 int best[2]={0, 0}; |
686 int d, dmin; | 922 int d, dmin; |
687 const int shift= 1+s->quarter_sample; | 923 const int shift= 1+s->quarter_sample; |
688 uint32_t *map= s->me.map; | 924 uint32_t *map= s->me.map; |
689 int map_generation; | 925 int map_generation; |
690 const int penalty_factor= s->me.penalty_factor; | 926 const int penalty_factor= s->me.penalty_factor; |
691 const int size=1; | 927 const int size=1; |
928 const int ref_mv_stride= s->mb_width+2; | |
929 const int ref_mv_xy= 1 + s->mb_x + (s->mb_y + 1)*ref_mv_stride; | |
692 me_cmp_func cmp, chroma_cmp; | 930 me_cmp_func cmp, chroma_cmp; |
693 LOAD_COMMON((s->mb_x*2 + (block&1))*8, (s->mb_y*2 + (block>>1))*8); | 931 LOAD_COMMON((s->mb_x*2 + (block&1))*8, (s->mb_y*2 + (block>>1))*8); |
694 | 932 |
695 cmp= s->dsp.me_cmp[size]; | 933 cmp= s->dsp.me_cmp[size]; |
696 chroma_cmp= s->dsp.me_cmp[size+1]; | 934 chroma_cmp= s->dsp.me_cmp[size+1]; |
700 dmin = 1000000; | 938 dmin = 1000000; |
701 //printf("%d %d %d %d //",xmin, ymin, xmax, ymax); | 939 //printf("%d %d %d %d //",xmin, ymin, xmax, ymax); |
702 /* first line */ | 940 /* first line */ |
703 if ((s->mb_y == 0 || s->first_slice_line) && block<2) { | 941 if ((s->mb_y == 0 || s->first_slice_line) && block<2) { |
704 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) | 942 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) |
705 CHECK_MV(P_LAST[0]>>shift, P_LAST[1]>>shift) | 943 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
944 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) | |
706 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) | 945 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) |
707 }else{ | 946 }else{ |
708 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) | 947 CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) |
709 //FIXME try some early stop | 948 //FIXME try some early stop |
710 if(dmin>64*2){ | 949 if(dmin>64*2){ |
711 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) | 950 CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) |
712 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) | 951 CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) |
713 CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) | 952 CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) |
714 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) | 953 CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) |
715 CHECK_MV(P_LAST[0]>>shift, P_LAST[1]>>shift) | 954 CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, |
955 (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) | |
716 } | 956 } |
717 } | 957 } |
718 if(dmin>64*4){ | 958 if(dmin>64*4){ |
719 CHECK_MV(P_LAST_RIGHT[0]>>shift, P_LAST_RIGHT[1]>>shift) | 959 CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, |
720 CHECK_MV(P_LAST_BOTTOM[0]>>shift, P_LAST_BOTTOM[1]>>shift) | 960 (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) |
721 } | 961 CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, |
722 | 962 (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) |
723 if(s->avctx->dia_size<2) | 963 } |
964 | |
965 if(s->avctx->dia_size==-1) | |
966 dmin= RENAME(funny_diamond_search)(s, best, dmin, ref_picture, | |
967 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | |
968 shift, map, map_generation, size, mv_penalty); | |
969 else if(s->avctx->dia_size<-1) | |
970 dmin= RENAME(sab_diamond_search)(s, best, dmin, ref_picture, | |
971 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | |
972 shift, map, map_generation, size, mv_penalty); | |
973 else if(s->avctx->dia_size<2) | |
724 dmin= RENAME(small_diamond_search)(s, best, dmin, ref_picture, | 974 dmin= RENAME(small_diamond_search)(s, best, dmin, ref_picture, |
725 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | 975 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, |
726 shift, map, map_generation, size, mv_penalty); | 976 shift, map, map_generation, size, mv_penalty); |
727 else | 977 else |
728 dmin= RENAME(var_diamond_search)(s, best, dmin, ref_picture, | 978 dmin= RENAME(var_diamond_search)(s, best, dmin, ref_picture, |
729 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, | 979 pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, |
730 shift, map, map_generation, size, mv_penalty); | 980 shift, map, map_generation, size, mv_penalty); |
981 | |
731 *mx_ptr= best[0]; | 982 *mx_ptr= best[0]; |
732 *my_ptr= best[1]; | 983 *my_ptr= best[1]; |
733 | 984 |
734 // printf("%d %d %d \n", best[0], best[1], dmin); | 985 // printf("%d %d %d \n", best[0], best[1], dmin); |
735 return dmin; | 986 return dmin; |