comparison motion_est.c @ 294:944632089814 libavcodec

4MV motion estimation (not finished yet) SAD functions rewritten (8x8 support & MMX2 optimizations) HQ inter/intra decission msmpeg4 encoding bugfix (MV where too long)
author michaelni
date Wed, 27 Mar 2002 21:25:22 +0000
parents 648e9245546d
children 6622b0fd036c
comparison
equal deleted inserted replaced
293:6eaf5da091fa 294:944632089814
24 #include "avcodec.h" 24 #include "avcodec.h"
25 #include "dsputil.h" 25 #include "dsputil.h"
26 #include "mpegvideo.h" 26 #include "mpegvideo.h"
27 27
28 #define ABS(a) ((a)>0 ? (a) : -(a)) 28 #define ABS(a) ((a)>0 ? (a) : -(a))
29 #define MAX(a,b) ((a) > (b) ? (a) : (b))
29 #define INTER_BIAS 257 30 #define INTER_BIAS 257
30 31
31 static void halfpel_motion_search(MpegEncContext * s, 32 static void halfpel_motion_search(MpegEncContext * s,
32 int *mx_ptr, int *my_ptr, int dmin, 33 int *mx_ptr, int *my_ptr, int dmin,
33 int xmin, int ymin, int xmax, int ymax, 34 int xmin, int ymin, int xmax, int ymax,
162 mx = 0; 163 mx = 0;
163 my = 0; 164 my = 0;
164 for (y = y1; y <= y2; y++) { 165 for (y = y1; y <= y2; y++) {
165 for (x = x1; x <= x2; x++) { 166 for (x = x1; x <= x2; x++) {
166 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, 167 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x,
167 s->linesize, 16); 168 s->linesize);
168 if (d < dmin || 169 if (d < dmin ||
169 (d == dmin && 170 (d == dmin &&
170 (abs(x - xx) + abs(y - yy)) < 171 (abs(x - xx) + abs(y - yy)) <
171 (abs(mx - xx) + abs(my - yy)))) { 172 (abs(mx - xx) + abs(my - yy)))) {
172 dmin = d; 173 dmin = d;
226 my = 0; 227 my = 0;
227 228
228 do { 229 do {
229 for (y = y1; y <= y2; y += range) { 230 for (y = y1; y <= y2; y += range) {
230 for (x = x1; x <= x2; x += range) { 231 for (x = x1; x <= x2; x += range) {
231 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize, 16); 232 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize);
232 if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { 233 if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {
233 dmin = d; 234 dmin = d;
234 mx = x; 235 mx = x;
235 my = y; 236 my = y;
236 } 237 }
306 dminx = 0x7fffffff; 307 dminx = 0x7fffffff;
307 dminy = 0x7fffffff; 308 dminy = 0x7fffffff;
308 309
309 lastx = x; 310 lastx = x;
310 for (x = x1; x <= x2; x += range) { 311 for (x = x1; x <= x2; x += range) {
311 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize, 16); 312 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize);
312 if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { 313 if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {
313 dminx = d; 314 dminx = d;
314 mx = x; 315 mx = x;
315 } 316 }
316 } 317 }
317 318
318 x = lastx; 319 x = lastx;
319 for (y = y1; y <= y2; y += range) { 320 for (y = y1; y <= y2; y += range) {
320 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize, 16); 321 d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize);
321 if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { 322 if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {
322 dminy = d; 323 dminy = d;
323 my = y; 324 my = y;
324 } 325 }
325 } 326 }
359 360
360 #define Z_THRESHOLD 256 361 #define Z_THRESHOLD 256
361 362
362 #define CHECK_MV(x,y)\ 363 #define CHECK_MV(x,y)\
363 {\ 364 {\
364 d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\ 365 d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\
365 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\ 366 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
366 if(d<dmin){\ 367 if(d<dmin){\
367 best[0]=x;\ 368 best[0]=x;\
368 best[1]=y;\ 369 best[1]=y;\
369 dmin=d;\ 370 dmin=d;\
370 }\ 371 }\
371 } 372 }
372 373
373 #define CHECK_MV_DIR(x,y,new_dir)\ 374 #define CHECK_MV_DIR(x,y,new_dir)\
374 {\ 375 {\
375 d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\ 376 d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\
376 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\ 377 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
377 if(d<dmin){\ 378 if(d<dmin){\
378 best[0]=x;\ 379 best[0]=x;\
379 best[1]=y;\ 380 best[1]=y;\
380 dmin=d;\ 381 dmin=d;\
381 next_dir= new_dir;\ 382 next_dir= new_dir;\
382 }\ 383 }\
383 } 384 }
385
386 #define CHECK_MV4(x,y)\
387 {\
388 d = pix_abs8x8(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\
389 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
390 if(d<dmin){\
391 best[0]=x;\
392 best[1]=y;\
393 dmin=d;\
394 }\
395 }
396
397 #define CHECK_MV4_DIR(x,y,new_dir)\
398 {\
399 d = pix_abs8x8(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\
400 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
401 if(d<dmin){\
402 best[0]=x;\
403 best[1]=y;\
404 dmin=d;\
405 next_dir= new_dir;\
406 }\
407 }
408
384 409
385 #define check(x,y,S,v)\ 410 #define check(x,y,S,v)\
386 if( (x)<(xmin<<(S)) ) printf("%d %d %d %d xmin" #v, (x), (y), s->mb_x, s->mb_y);\ 411 if( (x)<(xmin<<(S)) ) printf("%d %d %d %d xmin" #v, (x), (y), s->mb_x, s->mb_y);\
387 if( (x)>(xmax<<(S)) ) printf("%d %d %d %d xmax" #v, (x), (y), s->mb_x, s->mb_y);\ 412 if( (x)>(xmax<<(S)) ) printf("%d %d %d %d xmax" #v, (x), (y), s->mb_x, s->mb_y);\
388 if( (y)<(ymin<<(S)) ) printf("%d %d %d %d ymin" #v, (x), (y), s->mb_x, s->mb_y);\ 413 if( (y)<(ymin<<(S)) ) printf("%d %d %d %d ymin" #v, (x), (y), s->mb_x, s->mb_y);\
438 if(dmin==last_min) return dmin; 463 if(dmin==last_min) return dmin;
439 } 464 }
440 */ 465 */
441 } 466 }
442 467
468 static inline int small_diamond_search4MV(MpegEncContext * s, int *best, int dmin,
469 UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
470 int pred_x, int pred_y, UINT16 *mv_penalty, int quant,
471 int xmin, int ymin, int xmax, int ymax, int shift)
472 {
473 int next_dir=-1;
474
475 for(;;){
476 int d;
477 const int dir= next_dir;
478 const int x= best[0];
479 const int y= best[1];
480 next_dir=-1;
481
482 //printf("%d", dir);
483 if(dir!=2 && x>xmin) CHECK_MV4_DIR(x-1, y , 0)
484 if(dir!=3 && y>ymin) CHECK_MV4_DIR(x , y-1, 1)
485 if(dir!=0 && x<xmax) CHECK_MV4_DIR(x+1, y , 2)
486 if(dir!=1 && y<ymax) CHECK_MV4_DIR(x , y+1, 3)
487
488 if(next_dir==-1){
489 return dmin;
490 }
491 }
492 }
493
443 static inline int snake_search(MpegEncContext * s, int *best, int dmin, 494 static inline int snake_search(MpegEncContext * s, int *best, int dmin,
444 UINT8 *new_pic, UINT8 *old_pic, int pic_stride, 495 UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
445 int pred_x, int pred_y, UINT16 *mv_penalty, int quant, 496 int pred_x, int pred_y, UINT16 *mv_penalty, int quant,
446 int xmin, int ymin, int xmax, int ymax, int shift) 497 int xmin, int ymin, int xmax, int ymax, int shift)
447 { 498 {
467 int y= best[1]; 518 int y= best[1];
468 int d; 519 int d;
469 x+=x_dir[dir]; 520 x+=x_dir[dir];
470 y+=y_dir[dir]; 521 y+=y_dir[dir];
471 if(x>=xmin && x<=xmax && y>=ymin && y<=ymax){ 522 if(x>=xmin && x<=xmax && y>=ymin && y<=ymax){
472 d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16); 523 d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);
473 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant; 524 d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;
474 }else{ 525 }else{
475 d = dmin + 10000; //FIXME smarter boundary handling 526 d = dmin + 10000; //FIXME smarter boundary handling
476 } 527 }
477 if(d<dmin){ 528 if(d<dmin){
515 const int shift= 1+s->quarter_sample; 566 const int shift= 1+s->quarter_sample;
516 567
517 new_pic = s->new_picture[0] + pic_xy; 568 new_pic = s->new_picture[0] + pic_xy;
518 old_pic = s->last_picture[0] + pic_xy; 569 old_pic = s->last_picture[0] + pic_xy;
519 570
520 dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16); 571 dmin = pix_abs16x16(new_pic, old_pic, pic_stride);
521 if(dmin<Z_THRESHOLD){ 572 if(dmin<Z_THRESHOLD){
522 *mx_ptr= 0; 573 *mx_ptr= 0;
523 *my_ptr= 0; 574 *my_ptr= 0;
524 //printf("Z"); 575 //printf("Z");
525 return dmin; 576 return dmin;
555 606
556 // printf("%d %d %d \n", best[0], best[1], dmin); 607 // printf("%d %d %d \n", best[0], best[1], dmin);
557 return dmin; 608 return dmin;
558 } 609 }
559 610
611 static int epzs_motion_search4(MpegEncContext * s, int block,
612 int *mx_ptr, int *my_ptr,
613 int P[6][2], int pred_x, int pred_y,
614 int xmin, int ymin, int xmax, int ymax)
615 {
616 int best[2]={0, 0};
617 int d, dmin;
618 UINT8 *new_pic, *old_pic;
619 const int pic_stride= s->linesize;
620 const int pic_xy= ((s->mb_y*2 + (block>>1))*pic_stride + s->mb_x*2 + (block&1))*8;
621 UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
622 int quant= s->qscale; // qscale of the prev frame
623 const int shift= 1+s->quarter_sample;
624
625 new_pic = s->new_picture[0] + pic_xy;
626 old_pic = s->last_picture[0] + pic_xy;
627
628 dmin = pix_abs8x8(new_pic, old_pic, pic_stride);
629
630 /* first line */
631 if ((s->mb_y == 0 || s->first_slice_line || s->first_gob_line) && block<2) {
632 CHECK_MV4(P[1][0]>>shift, P[1][1]>>shift)
633 }else{
634 CHECK_MV4(P[4][0]>>shift, P[4][1]>>shift)
635 if(dmin<Z_THRESHOLD){
636 *mx_ptr= P[4][0]>>shift;
637 *my_ptr= P[4][1]>>shift;
638 //printf("M\n");
639 return dmin;
640 }
641 CHECK_MV4(P[1][0]>>shift, P[1][1]>>shift)
642 CHECK_MV4(P[2][0]>>shift, P[2][1]>>shift)
643 CHECK_MV4(P[3][0]>>shift, P[3][1]>>shift)
644 }
645 CHECK_MV4(P[0][0]>>shift, P[0][1]>>shift)
646 CHECK_MV4(P[5][0]>>shift, P[5][1]>>shift)
647
648 //check(best[0],best[1],0, b0)
649 dmin= small_diamond_search4MV(s, best, dmin, new_pic, old_pic, pic_stride,
650 pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift);
651 //check(best[0],best[1],0, b1)
652 *mx_ptr= best[0];
653 *my_ptr= best[1];
654
655 // printf("%d %d %d \n", best[0], best[1], dmin);
656 return dmin;
657 }
658
560 #define CHECK_HALF_MV(suffix, x, y) \ 659 #define CHECK_HALF_MV(suffix, x, y) \
561 d= pix_abs16x16_ ## suffix(pix, ptr+((x)>>1), s->linesize, 16);\ 660 d= pix_abs16x16_ ## suffix(pix, ptr+((x)>>1), s->linesize);\
562 d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*quant;\ 661 d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*quant;\
563 if(d<dminh){\ 662 if(d<dminh){\
564 dminh= d;\ 663 dminh= d;\
565 mx= mx1 + x;\ 664 mx= mx1 + x;\
566 my= my1 + y;\ 665 my= my1 + y;\
567 } 666 }
568 667
668 #define CHECK_HALF_MV4(suffix, x, y) \
669 d= pix_abs8x8_ ## suffix(pix, ptr+((x)>>1), s->linesize);\
670 d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*quant;\
671 if(d<dminh){\
672 dminh= d;\
673 mx= mx1 + x;\
674 my= my1 + y;\
675 }
676
569 /* The idea would be to make half pel ME after Inter/Intra decision to 677 /* The idea would be to make half pel ME after Inter/Intra decision to
570 save time. */ 678 save time. */
571 static inline void halfpel_motion_search(MpegEncContext * s, 679 static inline void halfpel_motion_search(MpegEncContext * s,
572 int *mx_ptr, int *my_ptr, int dmin, 680 int *mx_ptr, int *my_ptr, int dmin,
573 int xmin, int ymin, int xmax, int ymax, 681 int xmin, int ymin, int xmax, int ymax,
612 CHECK_HALF_MV(x2 , -1, 0) 720 CHECK_HALF_MV(x2 , -1, 0)
613 CHECK_HALF_MV(x2 , +1, 0) 721 CHECK_HALF_MV(x2 , +1, 0)
614 CHECK_HALF_MV(xy2, -1, +1) 722 CHECK_HALF_MV(xy2, -1, +1)
615 CHECK_HALF_MV(y2 , 0, +1) 723 CHECK_HALF_MV(y2 , 0, +1)
616 CHECK_HALF_MV(xy2, +1, +1) 724 CHECK_HALF_MV(xy2, +1, +1)
725
617 }else{ 726 }else{
618 mx= 2*(mx - xx); 727 mx= 2*(mx - xx);
619 my= 2*(my - yy); 728 my= 2*(my - yy);
620 } 729 }
621 730
622 *mx_ptr = mx; 731 *mx_ptr = mx;
623 *my_ptr = my; 732 *my_ptr = my;
624 } 733 }
625 734
735 static inline void halfpel_motion_search4(MpegEncContext * s,
736 int *mx_ptr, int *my_ptr, int dmin,
737 int xmin, int ymin, int xmax, int ymax,
738 int pred_x, int pred_y, int block_x, int block_y)
739 {
740 UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
741 const int quant= s->qscale;
742 int pen_x, pen_y;
743 int mx, my, mx1, my1, d, xx, yy, dminh;
744 UINT8 *pix, *ptr;
745
746 xx = 8 * block_x;
747 yy = 8 * block_y;
748 pix = s->new_picture[0] + (yy * s->linesize) + xx;
749
750 mx = *mx_ptr;
751 my = *my_ptr;
752 ptr = s->last_picture[0] + ((yy+my) * s->linesize) + xx + mx;
753
754 dminh = dmin;
755
756 if (mx > xmin && mx < xmax &&
757 my > ymin && my < ymax) {
758
759 mx= mx1= 2*mx;
760 my= my1= 2*my;
761 if(dmin < Z_THRESHOLD && mx==0 && my==0){
762 *mx_ptr = 0;
763 *my_ptr = 0;
764 return;
765 }
766
767 pen_x= pred_x + mx;
768 pen_y= pred_y + my;
769
770 ptr-= s->linesize;
771 CHECK_HALF_MV4(xy2, -1, -1)
772 CHECK_HALF_MV4(y2 , 0, -1)
773 CHECK_HALF_MV4(xy2, +1, -1)
774
775 ptr+= s->linesize;
776 CHECK_HALF_MV4(x2 , -1, 0)
777 CHECK_HALF_MV4(x2 , +1, 0)
778 CHECK_HALF_MV4(xy2, -1, +1)
779 CHECK_HALF_MV4(y2 , 0, +1)
780 CHECK_HALF_MV4(xy2, +1, +1)
781
782 }else{
783 mx*=2;
784 my*=2;
785 }
786
787 *mx_ptr = mx;
788 *my_ptr = my;
789 }
790
791 static inline void set_mv_tables(MpegEncContext * s, int mx, int my)
792 {
793 const int xy= s->mb_x + s->mb_y*s->mb_width;
794
795 s->mv_table[0][xy] = mx;
796 s->mv_table[1][xy] = my;
797
798 /* has allready been set to the 4 MV if 4MV is done */
799 if(!(s->flags&CODEC_FLAG_4MV)){
800 int mot_xy= s->block_index[0];
801
802 s->motion_val[mot_xy ][0]= mx;
803 s->motion_val[mot_xy ][1]= my;
804 s->motion_val[mot_xy+1][0]= mx;
805 s->motion_val[mot_xy+1][1]= my;
806
807 mot_xy += s->block_wrap[0];
808 s->motion_val[mot_xy ][0]= mx;
809 s->motion_val[mot_xy ][1]= my;
810 s->motion_val[mot_xy+1][0]= mx;
811 s->motion_val[mot_xy+1][1]= my;
812 }
813 }
814
626 #ifndef CONFIG_TEST_MV_ENCODE 815 #ifndef CONFIG_TEST_MV_ENCODE
627 816
628 int estimate_motion(MpegEncContext * s, 817 void estimate_motion(MpegEncContext * s,
629 int mb_x, int mb_y, 818 int mb_x, int mb_y)
630 int *mx_ptr, int *my_ptr)
631 { 819 {
632 UINT8 *pix, *ppix; 820 UINT8 *pix, *ppix;
633 int sum, varc, vard, mx, my, range, dmin, xx, yy; 821 int sum, varc, vard, mx, my, range, dmin, xx, yy;
634 int xmin, ymin, xmax, ymax; 822 int xmin, ymin, xmax, ymax;
635 int rel_xmin, rel_ymin, rel_xmax, rel_ymax; 823 int rel_xmin, rel_ymin, rel_xmax, rel_ymax;
636 int pred_x=0, pred_y=0; 824 int pred_x=0, pred_y=0;
637 int P[5][2]; 825 int P[6][2];
638 const int shift= 1+s->quarter_sample; 826 const int shift= 1+s->quarter_sample;
827 int mb_type=0;
639 828
640 range = 8 * (1 << (s->f_code - 1)); 829 range = 8 * (1 << (s->f_code - 1));
641 /* XXX: temporary kludge to avoid overflow for msmpeg4 */ 830 /* XXX: temporary kludge to avoid overflow for msmpeg4 */
642 if (s->out_format == FMT_H263 && !s->h263_msmpeg4) 831 if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
643 range = range * 2; 832 range = range * 2;
678 dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax); 867 dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax);
679 break; 868 break;
680 case ME_X1: 869 case ME_X1:
681 case ME_EPZS: 870 case ME_EPZS:
682 { 871 {
683 static const int off[4]= {2, 1, 1, -1}; 872 const int mot_stride = s->block_wrap[0];
684 const int mot_stride = s->mb_width*2 + 2; 873 const int mot_xy = s->block_index[0];
685 const int mot_xy = (s->mb_y*2 + 1)*mot_stride + s->mb_x*2 + 1; 874
686 875 rel_xmin= xmin - mb_x*16;
687 rel_xmin= xmin - s->mb_x*16; 876 rel_xmax= xmax - mb_x*16;
688 rel_xmax= xmax - s->mb_x*16; 877 rel_ymin= ymin - mb_y*16;
689 rel_ymin= ymin - s->mb_y*16; 878 rel_ymax= ymax - mb_y*16;
690 rel_ymax= ymax - s->mb_y*16;
691 879
692 P[0][0] = s->motion_val[mot_xy ][0]; 880 P[0][0] = s->motion_val[mot_xy ][0];
693 P[0][1] = s->motion_val[mot_xy ][1]; 881 P[0][1] = s->motion_val[mot_xy ][1];
694 P[1][0] = s->motion_val[mot_xy - 1][0]; 882 P[1][0] = s->motion_val[mot_xy - 1][0];
695 P[1][1] = s->motion_val[mot_xy - 1][1]; 883 P[1][1] = s->motion_val[mot_xy - 1][1];
696 if(P[1][0] > (rel_xmax<<shift)) P[1][0]= (rel_xmax<<shift); 884 if(P[1][0] > (rel_xmax<<shift)) P[1][0]= (rel_xmax<<shift);
697 885
698 /* special case for first line */ 886 /* special case for first line */
699 if ((s->mb_y == 0 || s->first_slice_line || s->first_gob_line)) { 887 if ((mb_y == 0 || s->first_slice_line || s->first_gob_line)) {
700 P[4][0] = P[1][0]; 888 P[4][0] = P[1][0];
701 P[4][1] = P[1][1]; 889 P[4][1] = P[1][1];
702 } else { 890 } else {
703 P[2][0] = s->motion_val[mot_xy - mot_stride ][0]; 891 P[2][0] = s->motion_val[mot_xy - mot_stride ][0];
704 P[2][1] = s->motion_val[mot_xy - mot_stride ][1]; 892 P[2][1] = s->motion_val[mot_xy - mot_stride ][1];
705 P[3][0] = s->motion_val[mot_xy - mot_stride + off[0] ][0]; 893 P[3][0] = s->motion_val[mot_xy - mot_stride + 2 ][0];
706 P[3][1] = s->motion_val[mot_xy - mot_stride + off[0] ][1]; 894 P[3][1] = s->motion_val[mot_xy - mot_stride + 2 ][1];
707 if(P[2][1] > (rel_ymax<<shift)) P[2][1]= (rel_ymax<<shift); 895 if(P[2][1] > (rel_ymax<<shift)) P[2][1]= (rel_ymax<<shift);
708 if(P[3][0] < (rel_xmin<<shift)) P[3][0]= (rel_xmin<<shift); 896 if(P[3][0] < (rel_xmin<<shift)) P[3][0]= (rel_xmin<<shift);
709 if(P[3][1] > (rel_ymax<<shift)) P[3][1]= (rel_ymax<<shift); 897 if(P[3][1] > (rel_ymax<<shift)) P[3][1]= (rel_ymax<<shift);
710 898
711 P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]); 899 P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]);
719 pred_y= P[1][1]; 907 pred_y= P[1][1];
720 } 908 }
721 } 909 }
722 dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax); 910 dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax);
723 911
724 mx+= s->mb_x*16; 912 mx+= mb_x*16;
725 my+= s->mb_y*16; 913 my+= mb_y*16;
726 break; 914 break;
915 }
916
917 if(s->flags&CODEC_FLAG_4MV){
918 int block;
919
920 mb_type|= MB_TYPE_INTER4V;
921
922 for(block=0; block<4; block++){
923 int mx4, my4;
924 int pred_x4, pred_y4;
925 int dmin4;
926 static const int off[4]= {2, 1, 1, -1};
927 const int mot_stride = s->block_wrap[0];
928 const int mot_xy = s->block_index[block];
929 const int block_x= mb_x*2 + (block&1);
930 const int block_y= mb_y*2 + (block>>1);
931
932 const int rel_xmin4= xmin - block_x*8;
933 const int rel_xmax4= xmax - block_x*8;
934 const int rel_ymin4= ymin - block_y*8;
935 const int rel_ymax4= ymax - block_y*8;
936
937 P[0][0] = s->motion_val[mot_xy ][0];
938 P[0][1] = s->motion_val[mot_xy ][1];
939 P[1][0] = s->motion_val[mot_xy - 1][0];
940 P[1][1] = s->motion_val[mot_xy - 1][1];
941 if(P[1][0] > (rel_xmax4<<shift)) P[1][0]= (rel_xmax4<<shift);
942
943 /* special case for first line */
944 if ((mb_y == 0 || s->first_slice_line || s->first_gob_line) && block<2) {
945 P[4][0] = P[1][0];
946 P[4][1] = P[1][1];
947 } else {
948 P[2][0] = s->motion_val[mot_xy - mot_stride ][0];
949 P[2][1] = s->motion_val[mot_xy - mot_stride ][1];
950 P[3][0] = s->motion_val[mot_xy - mot_stride + off[block]][0];
951 P[3][1] = s->motion_val[mot_xy - mot_stride + off[block]][1];
952 if(P[2][1] > (rel_ymax4<<shift)) P[2][1]= (rel_ymax4<<shift);
953 if(P[3][0] < (rel_xmin4<<shift)) P[3][0]= (rel_xmin4<<shift);
954 if(P[3][1] > (rel_ymax4<<shift)) P[3][1]= (rel_ymax4<<shift);
955
956 P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]);
957 P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]);
958 }
959 if(s->out_format == FMT_H263){
960 pred_x4 = P[4][0];
961 pred_y4 = P[4][1];
962 }else { /* mpeg1 at least */
963 pred_x4= P[1][0];
964 pred_y4= P[1][1];
965 }
966 P[5][0]= mx - mb_x*16;
967 P[5][1]= my - mb_y*16;
968
969 dmin4 = epzs_motion_search4(s, block, &mx4, &my4, P, pred_x4, pred_y4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4);
970
971 halfpel_motion_search4(s, &mx4, &my4, dmin4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4,
972 pred_x4, pred_y4, block_x, block_y);
973
974 s->motion_val[ s->block_index[block] ][0]= mx4;
975 s->motion_val[ s->block_index[block] ][1]= my4;
976 }
727 } 977 }
728 978
729 /* intra / predictive decision */ 979 /* intra / predictive decision */
730 xx = mb_x * 16; 980 xx = mb_x * 16;
731 yy = mb_y * 16; 981 yy = mb_y * 16;
735 ppix = s->last_picture[0] + (my * s->linesize) + mx; 985 ppix = s->last_picture[0] + (my * s->linesize) + mx;
736 986
737 sum = pix_sum(pix, s->linesize); 987 sum = pix_sum(pix, s->linesize);
738 #if 0 988 #if 0
739 varc = pix_dev(pix, s->linesize, (sum+128)>>8) + INTER_BIAS; 989 varc = pix_dev(pix, s->linesize, (sum+128)>>8) + INTER_BIAS;
740 vard = pix_abs16x16(pix, ppix, s->linesize, 16); 990 vard = pix_abs16x16(pix, ppix, s->linesize);
741 #else 991 #else
742 sum= (sum+8)>>4; 992 sum= (sum+8)>>4;
743 varc = ((pix_norm1(pix, s->linesize) - sum*sum + 128 + 500)>>8); 993 varc = ((pix_norm1(pix, s->linesize) - sum*sum + 128 + 500)>>8);
744 vard = (pix_norm(pix, ppix, s->linesize)+128)>>8; 994 vard = (pix_norm(pix, ppix, s->linesize)+128)>>8;
745 #endif 995 #endif
746 996
747 s->mb_var[s->mb_width * mb_y + mb_x] = varc; 997 s->mb_var[s->mb_width * mb_y + mb_x] = varc;
748 s->avg_mb_var += varc; 998 s->avg_mb_var+= varc;
749 s->mc_mb_var += vard; 999 s->mc_mb_var += vard;
750 1000
751 #if 0 1001 #if 0
752 printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", 1002 printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",
753 varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); 1003 varc, s->avg_mb_var, sum, vard, mx - xx, my - yy);
754 #endif 1004 #endif
755 if (vard <= 64 || vard < varc) { 1005 if(s->flags&CODEC_FLAG_HQ){
756 if (s->full_search != ME_ZERO) { 1006 if (vard*2 + 200 > varc)
1007 mb_type|= MB_TYPE_INTRA;
1008 if (varc*2 + 200 > vard){
1009 mb_type|= MB_TYPE_INTER;
757 halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y); 1010 halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y);
758 } else { 1011 }
759 mx -= 16 * s->mb_x; 1012 }else{
760 my -= 16 * s->mb_y; 1013 if (vard <= 64 || vard < varc) {
761 } 1014 mb_type|= MB_TYPE_INTER;
762 // check(mx + 32*s->mb_x, my + 32*s->mb_y, 1, end) 1015 if (s->full_search != ME_ZERO) {
763 1016 halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y);
764 *mx_ptr = mx; 1017 } else {
765 *my_ptr = my; 1018 mx -= 16 * mb_x;
766 return 0; 1019 my -= 16 * mb_y;
767 } else { 1020 }
768 *mx_ptr = 0; 1021 }else{
769 *my_ptr = 0; 1022 mb_type|= MB_TYPE_INTRA;
770 return 1; 1023 mx = 0;//mx*2 - 32 * mb_x;
771 } 1024 my = 0;//my*2 - 32 * mb_y;
1025 }
1026 }
1027
1028 s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1029 set_mv_tables(s, mx, my);
772 } 1030 }
773 1031
774 #else 1032 #else
775 1033
776 /* test version which generates valid random vectors */ 1034 /* test version which generates valid random vectors */