54 |
#define MV16_THRESHOLD 192 |
#define MV16_THRESHOLD 192 |
55 |
#define MV8_THRESHOLD 56 |
#define MV8_THRESHOLD 56 |
56 |
|
|
57 |
|
#define NEIGH_MOVE_THRESH 0 |
58 |
|
// how much a block's MV must differ from his neighbour |
59 |
|
// to be search for INTER4V. The more, the faster... |
60 |
|
|
61 |
/* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */ |
/* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */ |
62 |
/* nb = vop pixels * 2^(bpp-8) */ |
/* nb = vop pixels * 2^(bpp-8) */ |
63 |
#define MV16_00_BIAS (128+1) |
#define MV16_00_BIAS (128+1) |
64 |
#define MV8_00_BIAS (0) |
#define MV8_00_BIAS (0) |
65 |
|
|
66 |
/* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */ |
/* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */ |
67 |
#define INTER_BIAS 512 |
#define MV16_INTER_BIAS 512 |
68 |
|
|
69 |
/* Parameters which control inter/inter4v decision */ |
/* Parameters which control inter/inter4v decision */ |
70 |
#define IMV16X16 5 |
#define IMV16X16 5 |
73 |
#define NEIGH_TEND_16X16 2 |
#define NEIGH_TEND_16X16 2 |
74 |
#define NEIGH_TEND_8X8 2 |
#define NEIGH_TEND_8X8 2 |
75 |
|
|
|
|
|
76 |
// fast ((A)/2)*2 |
// fast ((A)/2)*2 |
77 |
#define EVEN(A) (((A)<0?(A)+1:(A)) & ~1) |
#define EVEN(A) (((A)<0?(A)+1:(A)) & ~1) |
78 |
|
|
79 |
|
#define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) ) |
80 |
|
#define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) |
81 |
|
|
82 |
int32_t PMVfastSearch16( |
int32_t PMVfastSearch16( |
83 |
const uint8_t * const pRef, |
const uint8_t * const pRef, |
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 * pMBs = current->mbs; |
MACROBLOCK * const pMBs = current->mbs; |
279 |
IMAGE * pCurrent = ¤t->image; |
MACROBLOCK * const prevMBs = reference->mbs; |
280 |
|
const IMAGE * const pCurrent = ¤t->image; |
281 |
MACROBLOCK * prevMBs = reference->mbs; // previous frame |
const IMAGE * const pRef = &reference->image; |
282 |
IMAGE * pRef = &reference->image; |
|
283 |
|
const VECTOR zeroMV = {0,0}; |
284 |
|
|
285 |
uint32_t i, j, iIntra = 0; |
int32_t x, y; |
286 |
|
int32_t iIntra = 0; |
287 |
VECTOR mv16; |
VECTOR pmv; |
|
VECTOR pmv16; |
|
|
|
|
|
int32_t sad8 = 0; |
|
|
int32_t sad16; |
|
|
int32_t deviation; |
|
288 |
|
|
289 |
if (sadInit) |
if (sadInit) |
290 |
(*sadInit)(); |
(*sadInit)(); |
291 |
|
|
292 |
// note: i==horizontal, j==vertical |
for (y = 0; y < iHcount; y++) |
293 |
for (i = 0; i < iHcount; i++) |
for (x = 0; x < iWcount; x++) |
|
for (j = 0; j < iWcount; j++) |
|
294 |
{ |
{ |
295 |
MACROBLOCK *pMB = &pMBs[j + i * iWcount]; |
MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; |
|
MACROBLOCK *prevMB = &prevMBs[j + i * iWcount]; |
|
296 |
|
|
297 |
sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
298 |
j, i, current->motion_flags, current->quant, current->fcode, |
x, y, current->motion_flags, current->quant, current->fcode, |
299 |
pParam, pMBs, prevMBs, &mv16, &pmv16); |
pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]); |
|
pMB->sad16=sad16; |
|
300 |
|
|
301 |
|
if (0 < (pMB->sad16 - MV16_INTER_BIAS)) |
302 |
|
{ |
303 |
|
int32_t deviation; |
304 |
|
deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width, pParam->edged_width); |
305 |
|
|
306 |
/* decide: MODE_INTER or MODE_INTRA |
if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) |
|
if (dev_intra < sad_inter - 2 * nb) use_intra |
|
|
*/ |
|
|
|
|
|
deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width); |
|
|
|
|
|
if (deviation < (sad16 - INTER_BIAS)) |
|
307 |
{ |
{ |
308 |
pMB->mode = MODE_INTRA; |
pMB->mode = MODE_INTRA; |
309 |
pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; |
pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = zeroMV; |
310 |
pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; |
pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0; |
|
|
|
|
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0; |
|
311 |
|
|
312 |
iIntra++; |
iIntra++; |
313 |
if(iIntra >= iLimit) |
if(iIntra >= iLimit) |
315 |
|
|
316 |
continue; |
continue; |
317 |
} |
} |
318 |
|
} |
319 |
|
|
320 |
|
pmv = pMB->pmvs[0]; |
321 |
if (current->global_flags & XVID_INTER4V) |
if (current->global_flags & XVID_INTER4V) |
322 |
|
if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) ) |
323 |
{ |
{ |
324 |
pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
int32_t sad8 = IMV16X16 * current->quant; if (sad8 < pMB->sad16) |
325 |
2 * j, 2 * i, mv16.x, mv16.y, |
|
326 |
|
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, |
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 |
pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
if (sad8 < pMB->sad16) |
332 |
2 * j + 1, 2 * i, mv16.x, mv16.y, |
sad8 += pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
333 |
|
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 |
pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
if (sad8 < pMB->sad16) |
338 |
2 * j, 2 * i + 1, mv16.x, mv16.y, |
sad8 += pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
339 |
|
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 |
pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
if (sad8 < pMB->sad16) |
344 |
2 * j + 1, 2 * i + 1, mv16.x, mv16.y, |
sad8 += pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
345 |
|
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]); |
348 |
|
|
|
sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3]; |
|
|
} |
|
|
|
|
|
|
|
349 |
/* decide: MODE_INTER or MODE_INTER4V |
/* decide: MODE_INTER or MODE_INTER4V |
350 |
mpeg4: if (sad8 < sad16 - nb/2+1) use_inter4v |
mpeg4: if (sad8 < pMB->sad16 - nb/2+1) use_inter4v |
351 |
*/ |
*/ |
352 |
|
|
353 |
if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) |
if (sad8 < pMB->sad16) |
|
{ |
|
|
if (((current->global_flags & XVID_INTER4V)==0) || |
|
|
(sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant)))) |
|
|
{ |
|
|
|
|
|
sad8 = sad16; |
|
|
pMB->mode = MODE_INTER; |
|
|
pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; |
|
|
pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; |
|
|
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16; |
|
|
pMB->pmvs[0].x = pmv16.x; |
|
|
pMB->pmvs[0].y = pmv16.y; |
|
|
} |
|
|
else |
|
354 |
{ |
{ |
355 |
pMB->mode = MODE_INTER4V; |
pMB->mode = MODE_INTER4V; |
356 |
pMB->sad8[0] *= 4; |
pMB->sad8[0] *= 4; |
357 |
pMB->sad8[1] *= 4; |
pMB->sad8[1] *= 4; |
358 |
pMB->sad8[2] *= 4; |
pMB->sad8[2] *= 4; |
359 |
pMB->sad8[3] *= 4; |
pMB->sad8[3] *= 4; |
360 |
|
continue; |
361 |
} |
} |
362 |
|
|
363 |
} |
} |
364 |
else |
|
|
{ |
|
|
sad8 = sad16; |
|
365 |
pMB->mode = MODE_INTER; |
pMB->mode = MODE_INTER; |
366 |
pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; |
pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3] are not needed for INTER */ |
367 |
pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; |
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] = sad16; |
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; |
369 |
|
|
|
pMB->pmvs[0].x = pmv16.x; |
|
|
pMB->pmvs[0].y = pmv16.y; |
|
|
} |
|
370 |
} |
} |
|
|
|
371 |
return 0; |
return 0; |
372 |
} |
} |
373 |
|
|
|
#define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) ) |
|
|
|
|
|
#define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) |
|
|
|
|
|
|
|
374 |
#define CHECK_MV16_ZERO {\ |
#define CHECK_MV16_ZERO {\ |
375 |
if ( (0 <= max_dx) && (0 >= min_dx) \ |
if ( (0 <= max_dx) && (0 >= min_dx) \ |
376 |
&& (0 <= max_dy) && (0 >= min_dy) ) \ |
&& (0 <= max_dy) && (0 >= min_dy) ) \ |
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 |
const MACROBLOCK * const pMB = pMBs + x + y * iWcount; |
MainSearch16FuncPtr MainSearchPtr; |
1101 |
|
|
1102 |
|
// 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 |
|
|
1105 |
static int32_t threshA,threshB; |
static int32_t threshA,threshB; |
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); |
1505 |
VECTOR backupMV; |
VECTOR backupMV; |
1506 |
VECTOR startMV; |
VECTOR startMV; |
1507 |
|
|
1508 |
const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; |
// const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; |
1509 |
const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount; |
const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount; |
1510 |
|
|
1511 |
static int32_t threshA,threshB; |
static int32_t threshA,threshB; |
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); |
1809 |
int32_t psad[8]; |
int32_t psad[8]; |
1810 |
|
|
1811 |
static MACROBLOCK * oldMBs = NULL; |
static MACROBLOCK * oldMBs = NULL; |
1812 |
const MACROBLOCK * const pMB = pMBs + x + y * iWcount; |
// const MACROBLOCK * const pMB = pMBs + x + y * iWcount; |
1813 |
const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; |
const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; |
1814 |
MACROBLOCK * oldMB = NULL; |
MACROBLOCK * oldMB = NULL; |
1815 |
|
|
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 |
iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ |
1997 |
|
|
1998 |
|
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); |
2100 |
|
|
2101 |
const int32_t iSubBlock = ((y&1)<<1) + (x&1); |
const int32_t iSubBlock = ((y&1)<<1) + (x&1); |
2102 |
|
|
2103 |
const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; |
// const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; |
2104 |
const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount; |
const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount; |
2105 |
|
|
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); |