54 |
#define MV16_THRESHOLD 192 |
#define MV16_THRESHOLD 192 |
55 |
#define MV8_THRESHOLD 56 |
#define MV8_THRESHOLD 56 |
56 |
|
|
57 |
#define NEIGH_MOVE_THRESH 8 |
#define NEIGH_MOVE_THRESH 0 |
58 |
// how much a block's MV must differ from his neighbour |
// how much a block's MV must differ from his neighbour |
59 |
// to be search for INTER4V. The more, the faster... |
// to be search for INTER4V. The more, the faster... |
60 |
|
|
272 |
const IMAGE * const pRefV, |
const IMAGE * const pRefV, |
273 |
const IMAGE * const pRefHV, |
const IMAGE * const pRefHV, |
274 |
const uint32_t iLimit) |
const uint32_t iLimit) |
|
|
|
275 |
{ |
{ |
276 |
const uint32_t iWcount = pParam->mb_width; |
const uint32_t iWcount = pParam->mb_width; |
277 |
const uint32_t iHcount = pParam->mb_height; |
const uint32_t iHcount = pParam->mb_height; |
278 |
MACROBLOCK * const pMBs = current->mbs; |
MACROBLOCK * const pMBs = current->mbs; |
279 |
MACROBLOCK * const prevMBs = reference->mbs; // previous frame |
MACROBLOCK * const prevMBs = reference->mbs; |
|
|
|
280 |
const IMAGE * const pCurrent = ¤t->image; |
const IMAGE * const pCurrent = ¤t->image; |
281 |
const IMAGE * const pRef = &reference->image; |
const IMAGE * const pRef = &reference->image; |
282 |
|
|
297 |
pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
298 |
x, y, current->motion_flags, current->quant, current->fcode, |
x, y, current->motion_flags, current->quant, current->fcode, |
299 |
pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]); |
pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]); |
|
} |
|
|
|
|
|
for (y = 0; y < iHcount; y++) |
|
|
for (x = 0; x < iWcount; x++) |
|
|
{ |
|
|
MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; |
|
300 |
|
|
301 |
if (0 < (pMB->sad16 - MV16_INTER_BIAS)) |
if (0 < (pMB->sad16 - MV16_INTER_BIAS)) |
302 |
{ |
{ |
303 |
int32_t deviation; |
int32_t deviation; |
304 |
deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width, |
deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width, pParam->edged_width); |
|
pParam->edged_width); |
|
305 |
|
|
306 |
if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) |
if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) |
307 |
{ |
{ |
308 |
pMB->mode = MODE_INTRA; |
pMB->mode = MODE_INTRA; |
309 |
pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] |
pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = zeroMV; |
310 |
= pMB->mvs[2] = pMB->mvs[3] = zeroMV; |
pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0; |
|
pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] |
|
|
= pMB->sad8[2] = pMB->sad8[3] = 0; |
|
311 |
|
|
312 |
iIntra++; |
iIntra++; |
313 |
if (iIntra >= iLimit) |
if (iIntra >= iLimit) |
317 |
} |
} |
318 |
} |
} |
319 |
|
|
320 |
if ( (current->global_flags & XVID_INTER4V) |
pmv = pMB->pmvs[0]; |
321 |
&& (!(current->global_flags & XVID_LUMIMASKING) |
if (current->global_flags & XVID_INTER4V) |
322 |
|| pMB->dquant == NO_CHANGE) ) |
if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) ) |
|
{ |
|
|
int32_t neigh=0; |
|
|
|
|
|
if (x>0) |
|
|
{ neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x)); |
|
|
neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y)); |
|
|
} |
|
|
if (y>0) |
|
|
{ neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x)); |
|
|
neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y)); |
|
|
} |
|
|
if (x<(iWcount-1)) |
|
|
{ neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x)); |
|
|
neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y)); |
|
|
} |
|
|
if (y<(iHcount-1)) |
|
|
{ neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x)); |
|
|
neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y)); |
|
|
} |
|
|
|
|
|
if (neigh > NEIGH_MOVE_THRESH) |
|
323 |
{ |
{ |
324 |
int32_t sad8 = 129; //IMV16X16 * current->quant; |
int32_t sad8 = IMV16X16 * current->quant; if (sad8 < pMB->sad16) |
325 |
|
|
326 |
if (sad8 < pMB->sad16) |
sad8 += pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
sad8 += pMB->sad8[0] |
|
|
= SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
327 |
2*x, 2*y, pMB->mv16.x, pMB->mv16.y, |
2*x, 2*y, pMB->mv16.x, pMB->mv16.y, |
328 |
current->motion_flags, current->quant, current->fcode, |
current->motion_flags, current->quant, current->fcode, |
329 |
pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]); |
pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]); |
330 |
|
|
331 |
if (sad8 < pMB->sad16) |
if (sad8 < pMB->sad16) |
332 |
sad8 += pMB->sad8[1] |
sad8 += pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
= SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
333 |
2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y, |
2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y, |
334 |
current->motion_flags, current->quant, current->fcode, |
current->motion_flags, current->quant, current->fcode, |
335 |
pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]); |
pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]); |
336 |
|
|
337 |
if (sad8 < pMB->sad16) |
if (sad8 < pMB->sad16) |
338 |
sad8 += pMB->sad8[2] |
sad8 += pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
= SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
339 |
2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y, |
2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y, |
340 |
current->motion_flags, current->quant, current->fcode, |
current->motion_flags, current->quant, current->fcode, |
341 |
pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]); |
pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]); |
342 |
|
|
343 |
if (sad8 < pMB->sad16) |
if (sad8 < pMB->sad16) |
344 |
sad8 += pMB->sad8[3] |
sad8 += pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
= SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
345 |
2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y, |
2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y, |
346 |
current->motion_flags, current->quant, current->fcode, |
current->motion_flags, current->quant, current->fcode, |
347 |
pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]); |
pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]); |
359 |
pMB->sad8[3] *= 4; |
pMB->sad8[3] *= 4; |
360 |
continue; |
continue; |
361 |
} |
} |
362 |
} |
|
363 |
} |
} |
364 |
|
|
365 |
pMB->mode = MODE_INTER; |
pMB->mode = MODE_INTER; |
366 |
|
pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3] are not needed for INTER */ |
367 |
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; |
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; |
368 |
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; |
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; |
369 |
|
|
|
pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0); |
|
|
// get_pmv has to be called again. |
|
|
// intra-decision and inter4v change predictors |
|
|
|
|
|
pMB->pmvs[0].x = pMB->mv16.x - pmv.x; |
|
|
pMB->pmvs[0].y = pMB->mv16.y - pmv.y; |
|
370 |
} |
} |
|
|
|
371 |
return 0; |
return 0; |
372 |
} |
} |
373 |
|
|
726 |
return iMinSAD; |
return iMinSAD; |
727 |
} |
} |
728 |
|
|
729 |
|
int32_t AdvDiamond16_MainSearch( |
730 |
|
const uint8_t * const pRef, |
731 |
|
const uint8_t * const pRefH, |
732 |
|
const uint8_t * const pRefV, |
733 |
|
const uint8_t * const pRefHV, |
734 |
|
const uint8_t * const cur, |
735 |
|
const int x, const int y, |
736 |
|
int32_t startx, int32_t starty, |
737 |
|
int32_t iMinSAD, |
738 |
|
VECTOR * const currMV, |
739 |
|
const VECTOR * const pmv, |
740 |
|
const int32_t min_dx, const int32_t max_dx, |
741 |
|
const int32_t min_dy, const int32_t max_dy, |
742 |
|
const int32_t iEdgedWidth, |
743 |
|
const int32_t iDiamondSize, |
744 |
|
const int32_t iFcode, |
745 |
|
const int32_t iQuant, |
746 |
|
int iDirection) |
747 |
|
{ |
748 |
|
|
749 |
|
int32_t iSAD; |
750 |
|
|
751 |
|
/* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */ |
752 |
|
|
753 |
|
if (iDirection) |
754 |
|
{ |
755 |
|
CHECK_MV16_CANDIDATE(startx-iDiamondSize, starty); |
756 |
|
CHECK_MV16_CANDIDATE(startx+iDiamondSize, starty); |
757 |
|
CHECK_MV16_CANDIDATE(startx, starty-iDiamondSize); |
758 |
|
CHECK_MV16_CANDIDATE(startx, starty+iDiamondSize); |
759 |
|
} |
760 |
|
else |
761 |
|
{ |
762 |
|
int bDirection = 1+2+4+8; |
763 |
|
do |
764 |
|
{ |
765 |
|
iDirection = 0; |
766 |
|
if (bDirection&1) //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left) |
767 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize,starty,1); |
768 |
|
|
769 |
|
if (bDirection&2) |
770 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize,starty,2); |
771 |
|
|
772 |
|
if (bDirection&4) |
773 |
|
CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize,4); |
774 |
|
|
775 |
|
if (bDirection&8) |
776 |
|
CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize,8); |
777 |
|
|
778 |
|
/* now we're doing diagonal checks near our candidate */ |
779 |
|
|
780 |
|
if (iDirection) //checking if anything found |
781 |
|
{ |
782 |
|
bDirection = iDirection; |
783 |
|
iDirection = 0; |
784 |
|
startx=currMV->x; starty=currMV->y; |
785 |
|
if (bDirection & 3) //our candidate is left or right |
786 |
|
{ |
787 |
|
CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize, 8); |
788 |
|
CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize, 4); |
789 |
|
} |
790 |
|
else // what remains here is up or down |
791 |
|
{ |
792 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty, 2); |
793 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty, 1); |
794 |
|
} |
795 |
|
|
796 |
|
if (iDirection) |
797 |
|
{ bDirection+=iDirection; |
798 |
|
startx=currMV->x; starty=currMV->y; |
799 |
|
} |
800 |
|
} |
801 |
|
else //about to quit, eh? not so fast.... |
802 |
|
{ |
803 |
|
switch (bDirection) |
804 |
|
{ |
805 |
|
case 2: |
806 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
807 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
808 |
|
break; |
809 |
|
case 1: |
810 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
811 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
812 |
|
break; |
813 |
|
case 2+4: |
814 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
815 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
816 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
817 |
|
break; |
818 |
|
case 4: |
819 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
820 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
821 |
|
break; |
822 |
|
case 8: |
823 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
824 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
825 |
|
break; |
826 |
|
case 1+4: |
827 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
828 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
829 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
830 |
|
break; |
831 |
|
case 2+8: |
832 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
833 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
834 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
835 |
|
break; |
836 |
|
case 1+8: |
837 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
838 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
839 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
840 |
|
break; |
841 |
|
default: //1+2+4+8 == we didn't find anything at all |
842 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
843 |
|
CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
844 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
845 |
|
CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
846 |
|
break; |
847 |
|
} |
848 |
|
if (!iDirection) break; //ok, the end. really |
849 |
|
else |
850 |
|
{ bDirection=iDirection; |
851 |
|
startx=currMV->x; starty=currMV->y; |
852 |
|
} |
853 |
|
} |
854 |
|
} |
855 |
|
while (1); //forever |
856 |
|
} |
857 |
|
return iMinSAD; |
858 |
|
} |
859 |
|
|
860 |
|
int32_t AdvDiamond8_MainSearch( |
861 |
|
const uint8_t * const pRef, |
862 |
|
const uint8_t * const pRefH, |
863 |
|
const uint8_t * const pRefV, |
864 |
|
const uint8_t * const pRefHV, |
865 |
|
const uint8_t * const cur, |
866 |
|
const int x, const int y, |
867 |
|
int32_t startx, int32_t starty, |
868 |
|
int32_t iMinSAD, |
869 |
|
VECTOR * const currMV, |
870 |
|
const VECTOR * const pmv, |
871 |
|
const int32_t min_dx, const int32_t max_dx, |
872 |
|
const int32_t min_dy, const int32_t max_dy, |
873 |
|
const int32_t iEdgedWidth, |
874 |
|
const int32_t iDiamondSize, |
875 |
|
const int32_t iFcode, |
876 |
|
const int32_t iQuant, |
877 |
|
int iDirection) |
878 |
|
{ |
879 |
|
|
880 |
|
int32_t iSAD; |
881 |
|
|
882 |
|
/* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */ |
883 |
|
|
884 |
|
if (iDirection) |
885 |
|
{ |
886 |
|
CHECK_MV8_CANDIDATE(startx-iDiamondSize, starty); |
887 |
|
CHECK_MV8_CANDIDATE(startx+iDiamondSize, starty); |
888 |
|
CHECK_MV8_CANDIDATE(startx, starty-iDiamondSize); |
889 |
|
CHECK_MV8_CANDIDATE(startx, starty+iDiamondSize); |
890 |
|
} |
891 |
|
else |
892 |
|
{ |
893 |
|
int bDirection = 1+2+4+8; |
894 |
|
do |
895 |
|
{ |
896 |
|
iDirection = 0; |
897 |
|
if (bDirection&1) //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left) |
898 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize,starty,1); |
899 |
|
|
900 |
|
if (bDirection&2) |
901 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize,starty,2); |
902 |
|
|
903 |
|
if (bDirection&4) |
904 |
|
CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize,4); |
905 |
|
|
906 |
|
if (bDirection&8) |
907 |
|
CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize,8); |
908 |
|
|
909 |
|
/* now we're doing diagonal checks near our candidate */ |
910 |
|
|
911 |
|
if (iDirection) //checking if anything found |
912 |
|
{ |
913 |
|
bDirection = iDirection; |
914 |
|
iDirection = 0; |
915 |
|
startx=currMV->x; starty=currMV->y; |
916 |
|
if (bDirection & 3) //our candidate is left or right |
917 |
|
{ |
918 |
|
CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize, 8); |
919 |
|
CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize, 4); |
920 |
|
} |
921 |
|
else // what remains here is up or down |
922 |
|
{ |
923 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty, 2); |
924 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty, 1); |
925 |
|
} |
926 |
|
|
927 |
|
if (iDirection) |
928 |
|
{ bDirection+=iDirection; |
929 |
|
startx=currMV->x; starty=currMV->y; |
930 |
|
} |
931 |
|
} |
932 |
|
else //about to quit, eh? not so fast.... |
933 |
|
{ |
934 |
|
switch (bDirection) |
935 |
|
{ |
936 |
|
case 2: |
937 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
938 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
939 |
|
break; |
940 |
|
case 1: |
941 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
942 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
943 |
|
break; |
944 |
|
case 2+4: |
945 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
946 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
947 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
948 |
|
break; |
949 |
|
case 4: |
950 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
951 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
952 |
|
break; |
953 |
|
case 8: |
954 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
955 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
956 |
|
break; |
957 |
|
case 1+4: |
958 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
959 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
960 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
961 |
|
break; |
962 |
|
case 2+8: |
963 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
964 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
965 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
966 |
|
break; |
967 |
|
case 1+8: |
968 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
969 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
970 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
971 |
|
break; |
972 |
|
default: //1+2+4+8 == we didn't find anything at all |
973 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); |
974 |
|
CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); |
975 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); |
976 |
|
CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); |
977 |
|
break; |
978 |
|
} |
979 |
|
if (!(iDirection)) break; //ok, the end. really |
980 |
|
else |
981 |
|
{ bDirection=iDirection; |
982 |
|
startx=currMV->x; starty=currMV->y; |
983 |
|
} |
984 |
|
} |
985 |
|
} |
986 |
|
while (1); //forever |
987 |
|
} |
988 |
|
return iMinSAD; |
989 |
|
} |
990 |
|
|
991 |
|
|
992 |
int32_t Full8_MainSearch( |
int32_t Full8_MainSearch( |
993 |
const uint8_t * const pRef, |
const uint8_t * const pRef, |
994 |
const uint8_t * const pRefH, |
const uint8_t * const pRefH, |
1097 |
VECTOR pmv[4]; |
VECTOR pmv[4]; |
1098 |
int32_t psad[4]; |
int32_t psad[4]; |
1099 |
|
|
1100 |
|
MainSearch16FuncPtr MainSearchPtr; |
1101 |
|
|
1102 |
// const MACROBLOCK * const pMB = pMBs + x + y * iWcount; |
// const MACROBLOCK * const pMB = pMBs + x + y * iWcount; |
1103 |
const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; |
const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; |
1104 |
|
|
1300 |
Refine by using small diamond and goto step 10. |
Refine by using small diamond and goto step 10. |
1301 |
*/ |
*/ |
1302 |
|
|
1303 |
|
if (MotionFlags & PMV_USESQUARES16) |
1304 |
|
MainSearchPtr = Square16_MainSearch; |
1305 |
|
else |
1306 |
|
if (MotionFlags & PMV_ADVANCEDDIAMOND16) |
1307 |
|
MainSearchPtr = AdvDiamond16_MainSearch; |
1308 |
|
else |
1309 |
|
MainSearchPtr = Diamond16_MainSearch; |
1310 |
|
|
1311 |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
1312 |
|
|
1313 |
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
1314 |
iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1315 |
x, y, |
x, y, |
1316 |
currMV->x, currMV->y, iMinSAD, &newMV, |
currMV->x, currMV->y, iMinSAD, &newMV, |
1317 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
1327 |
/* extended: search (up to) two more times: orignal prediction and (0,0) */ |
/* extended: search (up to) two more times: orignal prediction and (0,0) */ |
1328 |
|
|
1329 |
if (!(MVequal(pmv[0],backupMV)) ) |
if (!(MVequal(pmv[0],backupMV)) ) |
1330 |
{ iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, |
{ iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1331 |
x, y, |
x, y, |
1332 |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
1333 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
1340 |
} |
} |
1341 |
|
|
1342 |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
1343 |
{ iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, |
{ iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1344 |
x, y, |
x, y, |
1345 |
0, 0, iMinSAD, &newMV, |
0, 0, iMinSAD, &newMV, |
1346 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
1514 |
|
|
1515 |
int32_t iSubBlock = (y&1)+(y&1) + (x&1); |
int32_t iSubBlock = (y&1)+(y&1) + (x&1); |
1516 |
|
|
1517 |
|
MainSearch8FuncPtr MainSearchPtr; |
1518 |
|
|
1519 |
/* Init variables */ |
/* Init variables */ |
1520 |
startMV.x = start_x; |
startMV.x = start_x; |
1521 |
startMV.y = start_y; |
startMV.y = start_y; |
1561 |
|
|
1562 |
// Prepare for main loop |
// Prepare for main loop |
1563 |
|
|
1564 |
|
// if (MotionFlags & PMV_USESQUARES8) |
1565 |
|
// MainSearchPtr = Square8_MainSearch; |
1566 |
|
// else |
1567 |
|
|
1568 |
|
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
1569 |
|
MainSearchPtr = AdvDiamond8_MainSearch; |
1570 |
|
else |
1571 |
|
MainSearchPtr = Diamond8_MainSearch; |
1572 |
|
|
1573 |
|
|
1574 |
*currMV = startMV; |
*currMV = startMV; |
1575 |
|
|
1576 |
iMinSAD = sad8( cur, |
iMinSAD = sad8( cur, |
1711 |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
1712 |
|
|
1713 |
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
1714 |
iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1715 |
x, y, |
x, y, |
1716 |
currMV->x, currMV->y, iMinSAD, &newMV, |
currMV->x, currMV->y, iMinSAD, &newMV, |
1717 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
1727 |
/* extended: search (up to) two more times: orignal prediction and (0,0) */ |
/* extended: search (up to) two more times: orignal prediction and (0,0) */ |
1728 |
|
|
1729 |
if (!(MVequal(pmv[0],backupMV)) ) |
if (!(MVequal(pmv[0],backupMV)) ) |
1730 |
{ iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, |
{ iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1731 |
x, y, |
x, y, |
1732 |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
1733 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
1740 |
} |
} |
1741 |
|
|
1742 |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
1743 |
{ iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, |
{ iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1744 |
x, y, |
x, y, |
1745 |
0, 0, iMinSAD, &newMV, |
0, 0, iMinSAD, &newMV, |
1746 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); |
1817 |
int32_t bPredEq; |
int32_t bPredEq; |
1818 |
int32_t iMinSAD,iSAD=9999; |
int32_t iMinSAD,iSAD=9999; |
1819 |
|
|
1820 |
MainSearch16FuncPtr EPZSMainSearchPtr; |
MainSearch16FuncPtr MainSearchPtr; |
1821 |
|
|
1822 |
if (oldMBs == NULL) |
if (oldMBs == NULL) |
1823 |
{ oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK)); |
{ oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK)); |
1984 |
|
|
1985 |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
1986 |
|
|
1987 |
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
if (MotionFlags & PMV_USESQUARES8) |
1988 |
|
MainSearchPtr = Square16_MainSearch; |
1989 |
|
else |
1990 |
|
|
1991 |
if (MotionFlags & PMV_USESQUARES16) |
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
1992 |
EPZSMainSearchPtr = Square16_MainSearch; |
MainSearchPtr = AdvDiamond16_MainSearch; |
1993 |
else |
else |
1994 |
EPZSMainSearchPtr = Diamond16_MainSearch; |
MainSearchPtr = Diamond16_MainSearch; |
1995 |
|
|
1996 |
|
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
1997 |
|
|
1998 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
1999 |
x, y, |
x, y, |
2000 |
currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, |
currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, |
2001 |
2, iFcode, iQuant, 0); |
2, iFcode, iQuant, 0); |
2013 |
|
|
2014 |
if (!(MVequal(pmv[0],backupMV)) ) |
if (!(MVequal(pmv[0],backupMV)) ) |
2015 |
{ |
{ |
2016 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
2017 |
x, y, |
x, y, |
2018 |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
2019 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); |
2027 |
|
|
2028 |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
2029 |
{ |
{ |
2030 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
2031 |
x, y, |
x, y, |
2032 |
0, 0, iMinSAD, &newMV, |
0, 0, iMinSAD, &newMV, |
2033 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); |
2106 |
int32_t bPredEq; |
int32_t bPredEq; |
2107 |
int32_t iMinSAD,iSAD=9999; |
int32_t iMinSAD,iSAD=9999; |
2108 |
|
|
2109 |
MainSearch8FuncPtr EPZSMainSearchPtr; |
MainSearch8FuncPtr MainSearchPtr; |
2110 |
|
|
2111 |
/* Get maximum range */ |
/* Get maximum range */ |
2112 |
get_range(&min_dx, &max_dx, &min_dy, &max_dy, |
get_range(&min_dx, &max_dx, &min_dy, &max_dy, |
2234 |
|
|
2235 |
/* default: use best prediction as starting point for one call of EPZS_MainSearch */ |
/* default: use best prediction as starting point for one call of EPZS_MainSearch */ |
2236 |
|
|
2237 |
/* // there is no EPZS^2 for inter4v at the moment |
// there is no EPZS^2 for inter4v at the moment |
2238 |
|
|
2239 |
if (MotionFlags & PMV_USESQUARES8) |
// if (MotionFlags & PMV_USESQUARES8) |
2240 |
EPZSMainSearchPtr = Square8_MainSearch; |
// MainSearchPtr = Square8_MainSearch; |
2241 |
else |
// else |
|
*/ |
|
2242 |
|
|
2243 |
EPZSMainSearchPtr = Diamond8_MainSearch; |
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
2244 |
|
MainSearchPtr = AdvDiamond8_MainSearch; |
2245 |
|
else |
2246 |
|
MainSearchPtr = Diamond8_MainSearch; |
2247 |
|
|
2248 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
2249 |
x, y, |
x, y, |
2250 |
currMV->x, currMV->y, iMinSAD, &newMV, |
currMV->x, currMV->y, iMinSAD, &newMV, |
2251 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, |
2264 |
|
|
2265 |
if (!(MVequal(pmv[0],backupMV)) ) |
if (!(MVequal(pmv[0],backupMV)) ) |
2266 |
{ |
{ |
2267 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
2268 |
x, y, |
x, y, |
2269 |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
pmv[0].x, pmv[0].y, iMinSAD, &newMV, |
2270 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); |
2278 |
|
|
2279 |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) |
2280 |
{ |
{ |
2281 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
2282 |
x, y, |
x, y, |
2283 |
0, 0, iMinSAD, &newMV, |
0, 0, iMinSAD, &newMV, |
2284 |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); |
pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); |