554 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
555 |
|
|
556 |
|
|
557 |
if (iDirection) |
if (iDirection) { |
558 |
while (!iFound) { |
while (!iFound) { |
559 |
iFound = 1; |
iFound = 1; |
560 |
backupMV = *currMV; |
backupMV = *currMV; |
563 |
case 1: |
case 1: |
564 |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
565 |
backupMV.y, 1); |
backupMV.y, 1); |
566 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
567 |
backupMV.y - iDiamondSize, 5); |
backupMV.y - iDiamondSize, 5); |
568 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
569 |
backupMV.y - iDiamondSize, 7); |
backupMV.y - iDiamondSize, 7); |
570 |
break; |
break; |
571 |
case 2: |
case 2: |
572 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
573 |
2); |
2); |
574 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
575 |
backupMV.y + iDiamondSize, 6); |
backupMV.y + iDiamondSize, 6); |
576 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
577 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
578 |
break; |
break; |
579 |
|
|
580 |
case 3: |
case 3: |
581 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
582 |
4); |
4); |
583 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
584 |
backupMV.y - iDiamondSize, 7); |
backupMV.y - iDiamondSize, 7); |
585 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
586 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
587 |
break; |
break; |
588 |
|
|
589 |
case 4: |
case 4: |
590 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
591 |
3); |
3); |
592 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
593 |
backupMV.y - iDiamondSize, 5); |
backupMV.y - iDiamondSize, 5); |
594 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
595 |
backupMV.y + iDiamondSize, 6); |
backupMV.y + iDiamondSize, 6); |
596 |
break; |
break; |
597 |
|
|
598 |
case 5: |
case 5: |
599 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, |
600 |
1); |
1); |
601 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
602 |
3); |
3); |
603 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
604 |
backupMV.y - iDiamondSize, 5); |
backupMV.y - iDiamondSize, 5); |
605 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
606 |
backupMV.y + iDiamondSize, 6); |
backupMV.y + iDiamondSize, 6); |
607 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
608 |
backupMV.y - iDiamondSize, 7); |
backupMV.y - iDiamondSize, 7); |
609 |
break; |
break; |
610 |
|
|
611 |
case 6: |
case 6: |
612 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
613 |
2); |
2); |
614 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
615 |
3); |
3); |
616 |
|
|
617 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
618 |
backupMV.y - iDiamondSize, 5); |
backupMV.y - iDiamondSize, 5); |
619 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
620 |
backupMV.y + iDiamondSize, 6); |
backupMV.y + iDiamondSize, 6); |
621 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
622 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
623 |
|
|
624 |
break; |
break; |
626 |
case 7: |
case 7: |
627 |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
628 |
backupMV.y, 1); |
backupMV.y, 1); |
629 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
630 |
4); |
4); |
631 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
632 |
backupMV.y - iDiamondSize, 5); |
backupMV.y - iDiamondSize, 5); |
633 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
634 |
backupMV.y - iDiamondSize, 7); |
backupMV.y - iDiamondSize, 7); |
635 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
636 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
637 |
break; |
break; |
638 |
|
|
639 |
case 8: |
case 8: |
640 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
641 |
2); |
2); |
642 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
643 |
4); |
4); |
644 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
645 |
backupMV.y + iDiamondSize, 6); |
backupMV.y + iDiamondSize, 6); |
646 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
647 |
backupMV.y - iDiamondSize, 7); |
backupMV.y - iDiamondSize, 7); |
648 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
649 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
650 |
break; |
break; |
651 |
default: |
default: |
652 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, |
653 |
1); |
1); |
654 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
655 |
2); |
2); |
656 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
657 |
3); |
3); |
658 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
659 |
4); |
4); |
660 |
|
|
661 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
662 |
backupMV.y - iDiamondSize, 5); |
backupMV.y - iDiamondSize, 5); |
663 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
664 |
backupMV.y + iDiamondSize, 6); |
backupMV.y + iDiamondSize, 6); |
665 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
666 |
backupMV.y - iDiamondSize, 7); |
backupMV.y - iDiamondSize, 7); |
667 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
668 |
backupMV.y + iDiamondSize, 8); |
backupMV.y + iDiamondSize, 8); |
669 |
break; |
break; |
670 |
} |
} |
671 |
|
} |
672 |
} else { |
} else { |
673 |
currMV->x = start_x; |
currMV->x = start_x; |
674 |
currMV->y = start_y; |
currMV->y = start_y; |
874 |
return iMinSAD; |
return iMinSAD; |
875 |
} |
} |
876 |
|
|
877 |
|
#define CHECK_MV16_F_INTERPOL(X,Y) { \ |
878 |
#define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \ |
if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \ |
879 |
if ( ((X) <= max_dx) && ((X) >= min_dx) \ |
&& ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \ |
|
&& ((Y) <= max_dy) && ((Y) >= min_dy) ) \ |
|
880 |
{ \ |
{ \ |
881 |
iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ |
iSAD = sad16bi( cur, \ |
882 |
iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\ |
get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth), \ |
883 |
|
get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth), \ |
884 |
|
iEdgedWidth); \ |
885 |
|
iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\ |
886 |
|
iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\ |
887 |
if (iSAD < iMinSAD) \ |
if (iSAD < iMinSAD) \ |
888 |
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \ |
{ iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \ |
889 |
} |
} |
890 |
|
|
891 |
#define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \ |
#define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \ |
892 |
if ( ((X) <= max_dx) && ((X) >= min_dx) \ |
if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \ |
893 |
&& ((Y) <= max_dy) && ((Y) >= min_dy) ) \ |
&& ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \ |
894 |
{ \ |
{ \ |
895 |
iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ |
iSAD = sad16bi( cur, \ |
896 |
iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\ |
get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth), \ |
897 |
|
get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth), \ |
898 |
|
iEdgedWidth); \ |
899 |
|
iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\ |
900 |
|
iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\ |
901 |
if (iSAD < iMinSAD) \ |
if (iSAD < iMinSAD) \ |
902 |
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \ |
{ iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \ |
903 |
} |
} |
904 |
|
|
905 |
#define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \ |
#define CHECK_MV16_B_INTERPOL(X,Y) { \ |
906 |
if ( ((X) <= max_dx) && ((X) >= min_dx) \ |
if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \ |
907 |
&& ((Y) <= max_dy) && ((Y) >= min_dy) ) \ |
&& ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \ |
908 |
{ \ |
{ \ |
909 |
iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ |
iSAD = sad16bi( cur, \ |
910 |
iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\ |
get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth), \ |
911 |
|
get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth), \ |
912 |
|
iEdgedWidth); \ |
913 |
|
iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\ |
914 |
|
iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\ |
915 |
if (iSAD < iMinSAD) \ |
if (iSAD < iMinSAD) \ |
916 |
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \ |
{ iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \ |
917 |
} |
} |
918 |
|
|
919 |
|
#define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \ |
920 |
#define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \ |
if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \ |
921 |
if ( ((X) <= max_dx) && ((X) >= min_dx) \ |
&& ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \ |
|
&& ((Y) <= max_dy) && ((Y) >= min_dy) ) \ |
|
922 |
{ \ |
{ \ |
923 |
iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ |
iSAD = sad16bi( cur, \ |
924 |
iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\ |
get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth), \ |
925 |
|
get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth), \ |
926 |
|
iEdgedWidth); \ |
927 |
|
iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\ |
928 |
|
iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\ |
929 |
if (iSAD < iMinSAD) \ |
if (iSAD < iMinSAD) \ |
930 |
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \ |
{ iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \ |
931 |
} |
} |
932 |
|
|
|
|
|
|
#define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \ |
|
|
if ( ((X) <= max_dx) && ((X) >= min_dx) \ |
|
|
&& ((Y) <= max_dy) && ((Y) >= min_dy) ) \ |
|
|
{ \ |
|
|
iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ |
|
|
iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\ |
|
|
if (iSAD < iMinSAD) \ |
|
|
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \ |
|
|
} |
|
|
|
|
|
|
|
|
#define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \ |
|
|
if ( ((X) <= max_dx) && ((X) >= min_dx) \ |
|
|
&& ((Y) <= max_dy) && ((Y) >= min_dy) ) \ |
|
|
{ \ |
|
|
iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ |
|
|
iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\ |
|
|
if (iSAD < iMinSAD) \ |
|
|
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \ |
|
|
} |
|
|
|
|
|
|
|
|
#if (0==1) |
|
933 |
int32_t |
int32_t |
934 |
Diamond16_InterpolMainSearch( |
Diamond16_InterpolMainSearch( |
935 |
const uint8_t * const f_pRef, |
const uint8_t * const f_pRef, |
936 |
const uint8_t * const f_pRefH, |
const uint8_t * const f_pRefH, |
937 |
const uint8_t * const f_pRefV, |
const uint8_t * const f_pRefV, |
938 |
const uint8_t * const f_pRefHV, |
const uint8_t * const f_pRefHV, |
939 |
|
|
940 |
const uint8_t * const cur, |
const uint8_t * const cur, |
941 |
|
|
942 |
const uint8_t * const b_pRef, |
const uint8_t * const b_pRef, |
961 |
const int b_center_x, |
const int b_center_x, |
962 |
const int b_center_y, |
const int b_center_y, |
963 |
|
|
964 |
const int32_t min_dx, |
const int32_t f_min_dx, |
965 |
const int32_t max_dx, |
const int32_t f_max_dx, |
966 |
const int32_t min_dy, |
const int32_t f_min_dy, |
967 |
const int32_t max_dy, |
const int32_t f_max_dy, |
968 |
|
|
969 |
|
const int32_t b_min_dx, |
970 |
|
const int32_t b_max_dx, |
971 |
|
const int32_t b_min_dy, |
972 |
|
const int32_t b_max_dy, |
973 |
|
|
974 |
const int32_t iEdgedWidth, |
const int32_t iEdgedWidth, |
975 |
const int32_t iDiamondSize, |
const int32_t iDiamondSize, |
976 |
|
|
982 |
{ |
{ |
983 |
/* Do a diamond search around given starting point, return SAD of best */ |
/* Do a diamond search around given starting point, return SAD of best */ |
984 |
|
|
|
int32_t f_iDirection = 0; |
|
|
int32_t b_iDirection = 0; |
|
985 |
int32_t iSAD; |
int32_t iSAD; |
986 |
|
|
987 |
VECTOR f_backupMV; |
VECTOR f_backupMV; |
988 |
VECTOR b_backupMV; |
VECTOR b_backupMV; |
989 |
|
|
990 |
f_backupMV.x = start_x; |
f_currMV->x = f_start_x; |
991 |
f_backupMV.y = start_y; |
f_currMV->y = f_start_y; |
992 |
b_backupMV.x = start_x; |
b_currMV->x = b_start_x; |
993 |
b_backupMV.y = start_y; |
b_currMV->y = b_start_y; |
994 |
|
|
995 |
/* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */ |
do |
996 |
|
{ |
997 |
|
iFound = 1; |
998 |
|
|
999 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1); |
f_backupMV = *f_currMV; |
|
CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2); |
|
|
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); |
|
|
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); |
|
1000 |
|
|
1001 |
if (iDirection) |
CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y); |
1002 |
while (!iFound) { |
CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y); |
1003 |
iFound = 1; |
CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize); |
1004 |
backupMV = *currMV; |
CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize); |
1005 |
|
|
1006 |
|
b_backupMV = *b_currMV; |
1007 |
|
|
1008 |
|
CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y); |
1009 |
|
CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y); |
1010 |
|
CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize); |
1011 |
|
CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize); |
1012 |
|
|
1013 |
|
} while (!iFound); |
1014 |
|
|
1015 |
|
return iMinSAD; |
1016 |
|
} |
1017 |
|
|
1018 |
|
/* Sorry, these MACROS really got too large... I'll turn them into function soon! */ |
1019 |
|
|
1020 |
|
#define CHECK_MV16_DIRECT_FOUND(X,Y) \ |
1021 |
|
if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \ |
1022 |
|
{ int k;\ |
1023 |
|
VECTOR mvs,b_mvs; \ |
1024 |
|
iSAD = 0;\ |
1025 |
|
for (k = 0; k < 4; k++) { \ |
1026 |
|
mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X)); \ |
1027 |
|
b_mvs.x = (int32_t) (((X) == 0) \ |
1028 |
|
? ((TRB - TRD) * directmv[k].x) / TRD \ |
1029 |
|
: mvs.x - directmv[k].x); \ |
1030 |
|
\ |
1031 |
|
mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y)); \ |
1032 |
|
b_mvs.y = (int32_t) (((Y) == 0) \ |
1033 |
|
? ((TRB - TRD) * directmv[k].y) / TRD \ |
1034 |
|
: mvs.y - directmv[k].y); \ |
1035 |
|
\ |
1036 |
|
if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \ |
1037 |
|
&& (mvs.y <= max_dy) && (mvs.y >= min_dy) \ |
1038 |
|
&& (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx) \ |
1039 |
|
&& (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \ |
1040 |
|
iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth, \ |
1041 |
|
get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \ |
1042 |
|
mvs.x, mvs.y, iEdgedWidth), \ |
1043 |
|
get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \ |
1044 |
|
b_mvs.x, b_mvs.y, iEdgedWidth), \ |
1045 |
|
iEdgedWidth); \ |
1046 |
|
} \ |
1047 |
|
else \ |
1048 |
|
iSAD = 65535; \ |
1049 |
|
} \ |
1050 |
|
iSAD += calc_delta_16((X),(Y), 1, iQuant);\ |
1051 |
|
if (iSAD < iMinSAD) \ |
1052 |
|
{ iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \ |
1053 |
|
} |
1054 |
|
|
1055 |
|
|
1056 |
|
|
1057 |
|
int32_t |
1058 |
|
Diamond16_DirectMainSearch( |
1059 |
|
const uint8_t * const f_pRef, |
1060 |
|
const uint8_t * const f_pRefH, |
1061 |
|
const uint8_t * const f_pRefV, |
1062 |
|
const uint8_t * const f_pRefHV, |
1063 |
|
|
1064 |
|
const uint8_t * const cur, |
1065 |
|
|
1066 |
|
const uint8_t * const b_pRef, |
1067 |
|
const uint8_t * const b_pRefH, |
1068 |
|
const uint8_t * const b_pRefV, |
1069 |
|
const uint8_t * const b_pRefHV, |
1070 |
|
|
1071 |
|
const int x, |
1072 |
|
const int y, |
1073 |
|
|
1074 |
|
const int TRB, |
1075 |
|
const int TRD, |
1076 |
|
|
1077 |
|
const int start_x, |
1078 |
|
const int start_y, |
1079 |
|
|
1080 |
|
int iMinSAD, |
1081 |
|
VECTOR * const currMV, |
1082 |
|
const VECTOR * const directmv, |
1083 |
|
|
1084 |
|
const int32_t min_dx, |
1085 |
|
const int32_t max_dx, |
1086 |
|
const int32_t min_dy, |
1087 |
|
const int32_t max_dy, |
1088 |
|
|
1089 |
|
const int32_t iEdgedWidth, |
1090 |
|
const int32_t iDiamondSize, |
1091 |
|
|
1092 |
|
const int32_t iQuant, |
1093 |
|
int iFound) |
1094 |
|
{ |
1095 |
|
/* Do a diamond search around given starting point, return SAD of best */ |
1096 |
|
|
1097 |
|
int32_t iSAD; |
1098 |
|
|
1099 |
|
VECTOR backupMV; |
1100 |
|
|
|
if (iDirection != 2) |
|
|
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
|
|
backupMV.y, 1); |
|
|
if (iDirection != 1) |
|
|
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
|
|
backupMV.y, 2); |
|
|
if (iDirection != 4) |
|
|
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, |
|
|
backupMV.y - iDiamondSize, 3); |
|
|
if (iDirection != 3) |
|
|
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, |
|
|
backupMV.y + iDiamondSize, 4); |
|
|
} else { |
|
1101 |
currMV->x = start_x; |
currMV->x = start_x; |
1102 |
currMV->y = start_y; |
currMV->y = start_y; |
1103 |
} |
|
1104 |
|
/* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */ |
1105 |
|
|
1106 |
|
do |
1107 |
|
{ |
1108 |
|
iFound = 1; |
1109 |
|
|
1110 |
|
backupMV = *currMV; |
1111 |
|
|
1112 |
|
CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y); |
1113 |
|
CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y); |
1114 |
|
CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize); |
1115 |
|
CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize); |
1116 |
|
|
1117 |
|
} while (!iFound); |
1118 |
|
|
1119 |
return iMinSAD; |
return iMinSAD; |
1120 |
} |
} |
|
#endif |
|
1121 |
|
|
1122 |
|
|
1123 |
int32_t |
int32_t |
1368 |
const IMAGE * const pCur, |
const IMAGE * const pCur, |
1369 |
const int x, |
const int x, |
1370 |
const int y, |
const int y, |
1371 |
const int start_x, |
const int start_x, /* start is searched first, so it should contain the most */ |
1372 |
const int start_y, |
const int start_y, /* likely motion vector for this block */ |
1373 |
const int center_x, |
const int center_x, /* center is from where length of MVs is measured */ |
1374 |
const int center_y, |
const int center_y, |
1375 |
const uint32_t MotionFlags, |
const uint32_t MotionFlags, |
1376 |
const uint32_t iQuant, |
const uint32_t iQuant, |
1747 |
return iMinSAD; |
return iMinSAD; |
1748 |
} |
} |
1749 |
|
|
1750 |
|
|
1751 |
|
|
1752 |
|
|
1753 |
|
int32_t |
1754 |
|
Square8_MainSearch(const uint8_t * const pRef, |
1755 |
|
const uint8_t * const pRefH, |
1756 |
|
const uint8_t * const pRefV, |
1757 |
|
const uint8_t * const pRefHV, |
1758 |
|
const uint8_t * const cur, |
1759 |
|
const int x, |
1760 |
|
const int y, |
1761 |
|
int32_t start_x, |
1762 |
|
int32_t start_y, |
1763 |
|
int32_t iMinSAD, |
1764 |
|
VECTOR * const currMV, |
1765 |
|
const int center_x, |
1766 |
|
const int center_y, |
1767 |
|
const int32_t min_dx, |
1768 |
|
const int32_t max_dx, |
1769 |
|
const int32_t min_dy, |
1770 |
|
const int32_t max_dy, |
1771 |
|
const int32_t iEdgedWidth, |
1772 |
|
const int32_t iDiamondSize, |
1773 |
|
const int32_t iFcode, |
1774 |
|
const int32_t iQuant, |
1775 |
|
int iFound) |
1776 |
|
{ |
1777 |
|
/* Do a square search around given starting point, return SAD of best */ |
1778 |
|
|
1779 |
|
int32_t iDirection = 0; |
1780 |
|
int32_t iSAD; |
1781 |
|
VECTOR backupMV; |
1782 |
|
|
1783 |
|
backupMV.x = start_x; |
1784 |
|
backupMV.y = start_y; |
1785 |
|
|
1786 |
|
/* It's one search with full square pattern, and new parts for all following diamonds */ |
1787 |
|
|
1788 |
|
/* new direction are extra, so 1-4 is normal diamond |
1789 |
|
537 |
1790 |
|
1*2 |
1791 |
|
648 |
1792 |
|
*/ |
1793 |
|
|
1794 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1); |
1795 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2); |
1796 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); |
1797 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); |
1798 |
|
|
1799 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
1800 |
|
backupMV.y - iDiamondSize, 5); |
1801 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, |
1802 |
|
backupMV.y + iDiamondSize, 6); |
1803 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
1804 |
|
backupMV.y - iDiamondSize, 7); |
1805 |
|
CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, |
1806 |
|
backupMV.y + iDiamondSize, 8); |
1807 |
|
|
1808 |
|
|
1809 |
|
if (iDirection) { |
1810 |
|
while (!iFound) { |
1811 |
|
iFound = 1; |
1812 |
|
backupMV = *currMV; |
1813 |
|
|
1814 |
|
switch (iDirection) { |
1815 |
|
case 1: |
1816 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1817 |
|
backupMV.y, 1); |
1818 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1819 |
|
backupMV.y - iDiamondSize, 5); |
1820 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1821 |
|
backupMV.y - iDiamondSize, 7); |
1822 |
|
break; |
1823 |
|
case 2: |
1824 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
1825 |
|
2); |
1826 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1827 |
|
backupMV.y + iDiamondSize, 6); |
1828 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1829 |
|
backupMV.y + iDiamondSize, 8); |
1830 |
|
break; |
1831 |
|
|
1832 |
|
case 3: |
1833 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
1834 |
|
4); |
1835 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1836 |
|
backupMV.y - iDiamondSize, 7); |
1837 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1838 |
|
backupMV.y + iDiamondSize, 8); |
1839 |
|
break; |
1840 |
|
|
1841 |
|
case 4: |
1842 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
1843 |
|
3); |
1844 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1845 |
|
backupMV.y - iDiamondSize, 5); |
1846 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1847 |
|
backupMV.y + iDiamondSize, 6); |
1848 |
|
break; |
1849 |
|
|
1850 |
|
case 5: |
1851 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, |
1852 |
|
1); |
1853 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
1854 |
|
3); |
1855 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1856 |
|
backupMV.y - iDiamondSize, 5); |
1857 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1858 |
|
backupMV.y + iDiamondSize, 6); |
1859 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1860 |
|
backupMV.y - iDiamondSize, 7); |
1861 |
|
break; |
1862 |
|
|
1863 |
|
case 6: |
1864 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
1865 |
|
2); |
1866 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
1867 |
|
3); |
1868 |
|
|
1869 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1870 |
|
backupMV.y - iDiamondSize, 5); |
1871 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1872 |
|
backupMV.y + iDiamondSize, 6); |
1873 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1874 |
|
backupMV.y + iDiamondSize, 8); |
1875 |
|
|
1876 |
|
break; |
1877 |
|
|
1878 |
|
case 7: |
1879 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1880 |
|
backupMV.y, 1); |
1881 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
1882 |
|
4); |
1883 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1884 |
|
backupMV.y - iDiamondSize, 5); |
1885 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1886 |
|
backupMV.y - iDiamondSize, 7); |
1887 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1888 |
|
backupMV.y + iDiamondSize, 8); |
1889 |
|
break; |
1890 |
|
|
1891 |
|
case 8: |
1892 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
1893 |
|
2); |
1894 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
1895 |
|
4); |
1896 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1897 |
|
backupMV.y + iDiamondSize, 6); |
1898 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1899 |
|
backupMV.y - iDiamondSize, 7); |
1900 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1901 |
|
backupMV.y + iDiamondSize, 8); |
1902 |
|
break; |
1903 |
|
default: |
1904 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y, |
1905 |
|
1); |
1906 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y, |
1907 |
|
2); |
1908 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize, |
1909 |
|
3); |
1910 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize, |
1911 |
|
4); |
1912 |
|
|
1913 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1914 |
|
backupMV.y - iDiamondSize, 5); |
1915 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1916 |
|
backupMV.y + iDiamondSize, 6); |
1917 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1918 |
|
backupMV.y - iDiamondSize, 7); |
1919 |
|
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1920 |
|
backupMV.y + iDiamondSize, 8); |
1921 |
|
break; |
1922 |
|
} |
1923 |
|
} |
1924 |
|
} else { |
1925 |
|
currMV->x = start_x; |
1926 |
|
currMV->y = start_y; |
1927 |
|
} |
1928 |
|
return iMinSAD; |
1929 |
|
} |
1930 |
|
|
1931 |
|
|
1932 |
|
|
1933 |
|
|
1934 |
|
|
1935 |
int32_t |
int32_t |
1936 |
Halfpel8_Refine_c(const uint8_t * const pRef, |
Halfpel8_Refine_c(const uint8_t * const pRef, |
1937 |
const uint8_t * const pRefH, |
const uint8_t * const pRefH, |
2070 |
|
|
2071 |
// Prepare for main loop |
// Prepare for main loop |
2072 |
|
|
2073 |
// if (MotionFlags & PMV_USESQUARES8) |
if (MotionFlags & PMV_USESQUARES8) |
2074 |
// MainSearchPtr = Square8_MainSearch; |
MainSearchPtr = Square8_MainSearch; |
2075 |
// else |
else |
2076 |
|
|
2077 |
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
2078 |
MainSearchPtr = AdvDiamond8_MainSearch; |
MainSearchPtr = AdvDiamond8_MainSearch; |
2750 |
|
|
2751 |
// there is no EPZS^2 for inter4v at the moment |
// there is no EPZS^2 for inter4v at the moment |
2752 |
|
|
2753 |
// if (MotionFlags & PMV_USESQUARES8) |
if (MotionFlags & PMV_USESQUARES8) |
2754 |
// MainSearchPtr = Square8_MainSearch; |
MainSearchPtr = Square8_MainSearch; |
2755 |
// else |
else |
2756 |
|
|
2757 |
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
2758 |
MainSearchPtr = AdvDiamond8_MainSearch; |
MainSearchPtr = AdvDiamond8_MainSearch; |
2827 |
const IMAGE * const pCur, |
const IMAGE * const pCur, |
2828 |
const int x, |
const int x, |
2829 |
const int y, |
const int y, |
2830 |
const int start_x, |
const int start_x, /* start should be most likely vector */ |
2831 |
const int start_y, |
const int start_y, |
2832 |
const int center_x, |
const int center_x, /* center is from where length of MVs is measured */ |
2833 |
const int center_y, |
const int center_y, |
2834 |
const uint32_t MotionFlags, |
const uint32_t MotionFlags, |
2835 |
const uint32_t iQuant, |
const uint32_t iQuant, |
2858 |
int32_t iFound; |
int32_t iFound; |
2859 |
|
|
2860 |
VECTOR newMV; |
VECTOR newMV; |
2861 |
VECTOR backupMV; /* just for PMVFAST */ |
VECTOR backupMV; |
2862 |
|
|
2863 |
VECTOR pmv[4]; |
VECTOR pmv[4]; |
2864 |
int32_t psad[4]; |
int32_t psad[4]; |
3113 |
|
|
3114 |
/* *********************************************************** |
/* *********************************************************** |
3115 |
bvop motion estimation |
bvop motion estimation |
|
// TODO: need to incorporate prediction here (eg. sad += calc_delta_16) |
|
3116 |
***************************************************************/ |
***************************************************************/ |
3117 |
|
|
|
|
|
|
#define DIRECT_PENALTY 0 |
|
|
#define DIRECT_UPPERLIMIT 256 // never use direct mode if SAD is larger than this |
|
|
|
|
3118 |
void |
void |
3119 |
MotionEstimationBVOP(MBParam * const pParam, |
MotionEstimationBVOP(MBParam * const pParam, |
3120 |
FRAMEINFO * const frame, |
FRAMEINFO * const frame, |
3137 |
const int mb_height = pParam->mb_height; |
const int mb_height = pParam->mb_height; |
3138 |
const int edged_width = pParam->edged_width; |
const int edged_width = pParam->edged_width; |
3139 |
|
|
3140 |
|
const int32_t iWidth = pParam->width; |
3141 |
|
const int32_t iHeight = pParam->height; |
3142 |
|
|
3143 |
int i, j, k; |
int i, j, k; |
3144 |
|
|
3145 |
static const VECTOR zeroMV={0,0}; |
static const VECTOR zeroMV={0,0}; |
3147 |
int f_sad16; /* forward (as usual) search */ |
int f_sad16; /* forward (as usual) search */ |
3148 |
int b_sad16; /* backward (only in b-frames) search */ |
int b_sad16; /* backward (only in b-frames) search */ |
3149 |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
3150 |
int d_sad16; /* direct mode (assume linear motion) */ |
int d_sad16; /* direct mode (assume almost linear motion) */ |
3151 |
|
|
3152 |
int best_sad; |
int best_sad; |
3153 |
|
|
3154 |
VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ |
VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ |
3155 |
|
VECTOR f_interpolMV, b_interpolMV; |
3156 |
VECTOR pmv_dontcare; |
VECTOR pmv_dontcare; |
3157 |
|
|
3158 |
|
int min_dx, max_dx, min_dy, max_dy; |
3159 |
|
int f_min_dx, f_max_dx, f_min_dy, f_max_dy; |
3160 |
|
int b_min_dx, b_max_dx, b_min_dy, b_max_dy; |
3161 |
|
|
3162 |
int f_count=0; |
int f_count=0; |
3163 |
int b_count=0; |
int b_count=0; |
3164 |
int i_count=0; |
int i_count=0; |
3165 |
int d_count=0; |
int d_count=0; |
|
int s_count=0; |
|
3166 |
|
|
3167 |
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
3168 |
const int64_t TRD = (int32_t)time_pp; |
const int64_t TRD = (int32_t)time_pp; |
3181 |
|
|
3182 |
mb->deltamv=zeroMV; |
mb->deltamv=zeroMV; |
3183 |
|
|
3184 |
/* special case, if collocated block is SKIPed: encoding is forward(0,0) */ |
/* special case, if collocated block is SKIPed: encoding is forward (0,0), cpb=0 without further ado */ |
3185 |
|
|
|
#ifndef _DISABLE_SKIP |
|
3186 |
if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && |
if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && |
3187 |
b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { |
b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { |
3188 |
mb->mode = MODE_NOT_CODED; |
mb->mode = MODE_NOT_CODED; |
3189 |
mb->mvs[0].x = 0; |
mb->b_mvs[0] = mb->mvs[0] = zeroMV; |
|
mb->mvs[0].y = 0; |
|
|
mb->b_mvs[0].x = 0; |
|
|
mb->b_mvs[0].y = 0; |
|
3190 |
continue; |
continue; |
3191 |
} |
} |
|
#endif |
|
|
|
|
|
d_sad16 = DIRECT_PENALTY; |
|
3192 |
|
|
3193 |
if (b_mb->mode == MODE_INTER4V) |
if (b_mb->mode == MODE_INTER4V) |
3194 |
{ |
{ |
3195 |
|
d_sad16 = 0; |
3196 |
/* same method of scaling as in decoder.c, so we copy from there */ |
/* same method of scaling as in decoder.c, so we copy from there */ |
3197 |
for (k = 0; k < 4; k++) { |
for (k = 0; k < 4; k++) { |
3198 |
|
|
3204 |
: mb->mvs[k].x - mb->directmv[k].x); |
: mb->mvs[k].x - mb->directmv[k].x); |
3205 |
|
|
3206 |
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
3207 |
mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) |
mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0) |
3208 |
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
3209 |
: mb->mvs[k].y - mb->directmv[k].y); |
: mb->mvs[k].y - mb->directmv[k].y); |
3210 |
|
|
3232 |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
3233 |
: mb->mvs[0].y - mb->directmv[0].y); |
: mb->mvs[0].y - mb->directmv[0].y); |
3234 |
|
|
3235 |
d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
3236 |
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
3237 |
i, j, 16, &mb->mvs[0], edged_width), |
i, j, 16, &mb->mvs[0], edged_width), |
3238 |
get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
3275 |
i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y, |
i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y, |
3276 |
frame->bcode, frame->quant); |
frame->bcode, frame->quant); |
3277 |
|
|
3278 |
// TODO: direct search |
get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight, |
3279 |
// predictor + delta vector in range [-32,32] (fcode=1) |
frame->fcode); |
3280 |
|
get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight, |
3281 |
|
frame->bcode); |
3282 |
|
|
3283 |
|
/* Interpolated MC motion vector search, this is tedious and more complicated because there are |
3284 |
|
two values for everything, always one for backward and one for forward ME. Still, we don't gain |
3285 |
|
much from this search, maybe it should simply be skipped and simply current i_sad16 value used |
3286 |
|
as "optimal". */ |
3287 |
|
|
3288 |
|
i_sad16 = Diamond16_InterpolMainSearch( |
3289 |
|
f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
3290 |
|
frame->image.y + i * 16 + j * 16 * edged_width, |
3291 |
|
b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
3292 |
|
i, j, |
3293 |
|
mb->mvs[0].x, mb->mvs[0].y, |
3294 |
|
mb->b_mvs[0].x, mb->b_mvs[0].y, |
3295 |
|
i_sad16, |
3296 |
|
&f_interpolMV, &b_interpolMV, |
3297 |
|
f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y, |
3298 |
|
f_min_dx, f_max_dx, f_min_dy, f_max_dy, |
3299 |
|
b_min_dx, b_max_dx, b_min_dy, b_max_dy, |
3300 |
|
edged_width, 1, |
3301 |
|
frame->fcode, frame->bcode,frame->quant,0); |
3302 |
|
|
3303 |
|
|
3304 |
|
/* DIRECT MODE DELTA VECTOR SEARCH. |
3305 |
|
This has to be made more effective, but at the moment I'm happy it's running at all */ |
3306 |
|
|
3307 |
|
/* range is taken without fcode restriction, just a hack instead of writing down the dimensions, of course */ |
3308 |
|
|
3309 |
|
get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19); |
3310 |
|
|
3311 |
|
d_sad16 = Diamond16_DirectMainSearch( |
3312 |
|
f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
3313 |
|
frame->image.y + i*16 + j*16*edged_width, |
3314 |
|
b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
3315 |
|
i, j, |
3316 |
|
TRB,TRD, |
3317 |
|
0,0, |
3318 |
|
d_sad16, |
3319 |
|
&mb->deltamv, |
3320 |
|
mb->directmv, // this has to be pre-initialized with b_mb->mvs[} |
3321 |
|
min_dx, max_dx, min_dy, max_dy, |
3322 |
|
edged_width, 1, frame->quant, 0); |
3323 |
|
|
3324 |
i_sad16 = 65535; |
|
3325 |
f_sad16 = 65535; |
// i_sad16 = 65535; /* remove the comment to disable any of the MODEs */ |
3326 |
b_sad16 = 65535; |
// f_sad16 = 65535; |
3327 |
|
// b_sad16 = 65535; |
3328 |
// d_sad16 = 65535; |
// d_sad16 = 65535; |
3329 |
|
|
3330 |
if (f_sad16 < b_sad16) { |
if (f_sad16 < b_sad16) { |
3345 |
if (b_mb->mode == MODE_INTER4V) |
if (b_mb->mode == MODE_INTER4V) |
3346 |
{ |
{ |
3347 |
|
|
3348 |
/* same method of scaling as in decoder.c, so we copy from there */ |
/* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */ |
3349 |
|
/* for the bitstream, the value mb->deltamv is read directly */ |
3350 |
|
|
3351 |
for (k = 0; k < 4; k++) { |
for (k = 0; k < 4; k++) { |
3352 |
|
|
3353 |
mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); |
mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); |
3356 |
: mb->mvs[k].x - mb->directmv[k].x); |
: mb->mvs[k].x - mb->directmv[k].x); |
3357 |
|
|
3358 |
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
3359 |
mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) |
mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0) |
3360 |
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
3361 |
: mb->mvs[k].y - mb->directmv[k].y); |
: mb->mvs[k].y - mb->directmv[k].y); |
3362 |
} |
} |
3371 |
|
|
3372 |
mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); |
mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); |
3373 |
|
|
3374 |
mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) |
mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0) |
3375 |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
3376 |
: mb->mvs[0].y - mb->directmv[0].y); |
: mb->mvs[0].y - mb->directmv[0].y); |
3377 |
|
|
3381 |
|
|
3382 |
best_sad = d_sad16; |
best_sad = d_sad16; |
3383 |
mb->mode = MODE_DIRECT; |
mb->mode = MODE_DIRECT; |
|
mb->mode = MODE_INTERPOLATE; // direct mode still broken :-( |
|
3384 |
} |
} |
3385 |
|
|
3386 |
switch (mb->mode) |
switch (mb->mode) |
3396 |
break; |
break; |
3397 |
case MODE_INTERPOLATE: |
case MODE_INTERPOLATE: |
3398 |
i_count++; |
i_count++; |
3399 |
|
mb->mvs[0] = f_interpolMV; |
3400 |
|
mb->b_mvs[0] = b_interpolMV; |
3401 |
f_predMV = mb->mvs[0]; |
f_predMV = mb->mvs[0]; |
3402 |
b_predMV = mb->b_mvs[0]; |
b_predMV = mb->b_mvs[0]; |
3403 |
break; |
break; |
3405 |
d_count++; |
d_count++; |
3406 |
break; |
break; |
3407 |
default: |
default: |
|
s_count++; // ??? |
|
3408 |
break; |
break; |
3409 |
} |
} |
3410 |
|
|
3412 |
} |
} |
3413 |
|
|
3414 |
#ifdef _DEBUG_BFRAME_STAT |
#ifdef _DEBUG_BFRAME_STAT |
3415 |
fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D: %04d S: %04d\n", |
fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D: %04d\n", |
3416 |
f_count,b_count,i_count,d_count,s_count); |
f_count,b_count,i_count,d_count); |
3417 |
#endif |
#endif |
3418 |
|
|
3419 |
} |
} |