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 |
|
|
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]); |
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) |
316 |
continue; |
continue; |
317 |
} |
} |
318 |
} |
} |
|
pMB->mode = MODE_INTER; |
|
|
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; |
|
|
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; |
|
|
} |
|
|
|
|
|
// we try to do as few INTER4V-searches as possible. So we split ME in two parts, normal |
|
|
// SEARCH16 and only for special blocks SEARCH8. May this should be modified for quality |
|
|
// levels. |
|
|
|
|
|
|
|
319 |
|
|
320 |
|
pmv = pMB->pmvs[0]; |
321 |
if (current->global_flags & XVID_INTER4V) |
if (current->global_flags & XVID_INTER4V) |
|
for (y = 0; y < iHcount; y++) |
|
|
for (x = 0; x < iWcount; x++) |
|
|
{ |
|
|
MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; |
|
|
|
|
|
if (pMB->mode == MODE_INTRA) |
|
|
continue; |
|
|
|
|
|
|
|
322 |
if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) ) |
if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) ) |
323 |
{ |
{ |
324 |
int32_t neigh=0; |
int32_t sad8 = IMV16X16 * current->quant; if (sad8 < pMB->sad16) |
325 |
|
|
326 |
if (x>0) |
sad8 += pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, |
|
{ 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) |
|
|
{ |
|
|
int32_t sad8 = IMV16X16 * current->quant; |
|
|
|
|
|
if (sad8 < pMB->sad16) |
|
|
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]); |
360 |
continue; |
continue; |
361 |
} |
} |
362 |
|
|
|
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; |
|
|
} |
|
|
|
|
363 |
} |
} |
364 |
|
|
365 |
// get_pmv has to be called again, because inter4v changes predictors |
pMB->mode = MODE_INTER; |
366 |
|
pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3] are not needed for INTER */ |
367 |
pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0); |
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; |
368 |
pMB->pmvs[0].x = pMB->mv16.x - pmv.x; /* the other pmvs are only needed in INTER4V-mode */ |
pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; |
|
pMB->pmvs[0].y = pMB->mv16.y - pmv.y; |
|
369 |
|
|
370 |
} |
} |
|
|
|
371 |
return 0; |
return 0; |
372 |
} |
} |
373 |
|
|
1984 |
|
|
1985 |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ |
1986 |
|
|
1987 |
|
if (MotionFlags & PMV_USESQUARES8) |
1988 |
|
MainSearchPtr = Square16_MainSearch; |
1989 |
|
else |
1990 |
|
|
1991 |
|
if (MotionFlags & PMV_ADVANCEDDIAMOND8) |
1992 |
|
MainSearchPtr = AdvDiamond16_MainSearch; |
1993 |
|
else |
1994 |
|
MainSearchPtr = Diamond16_MainSearch; |
1995 |
|
|
1996 |
/* 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 */ |
1997 |
|
|
1998 |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, |
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 |
|
|
|
|
if (MotionFlags & PMV_USESQUARES8) |
|
|
MainSearchPtr = Square8_MainSearch; |
|
|
else |
|
|
*/ |
|
2238 |
|
|
2239 |
// if (MotionFlags & PMV_USESQUARES8) |
// if (MotionFlags & PMV_USESQUARES8) |
2240 |
// MainSearchPtr = Square8_MainSearch; |
// MainSearchPtr = Square8_MainSearch; |