148 |
const int halfpel_y = y/2; |
const int halfpel_y = y/2; |
149 |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
150 |
|
|
151 |
ref1 = GetReference(halfpel_x, halfpel_y, dir, data); // this reference is used in all cases |
ref1 = GetReference(halfpel_x, halfpel_y, dir, data); |
152 |
ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
153 |
switch( ((x&1)<<1) + (y&1) ) { |
switch( ((x&1)<<1) + (y&1) ) { |
154 |
case 0: // pure halfpel position |
case 0: // pure halfpel position |
155 |
Reference = (uint8_t *) GetReference(halfpel_x, halfpel_y, dir, data); |
return (uint8_t *) ref1; |
|
Reference += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth; |
|
156 |
break; |
break; |
157 |
|
|
158 |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
192 |
const int halfpel_y = y/2; |
const int halfpel_y = y/2; |
193 |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
const uint8_t *ref1, *ref2, *ref3, *ref4; |
194 |
|
|
195 |
ref1 = GetReference(halfpel_x, halfpel_y, dir, data); // this reference is used in all cases |
ref1 = GetReference(halfpel_x, halfpel_y, dir, data); |
196 |
switch( ((x&1)<<1) + (y&1) ) { |
switch( ((x&1)<<1) + (y&1) ) { |
197 |
case 0: // pure halfpel position |
case 0: // pure halfpel position |
198 |
return (uint8_t *) GetReference(halfpel_x, halfpel_y, dir, data); |
return (uint8_t *) ref1; |
199 |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
case 1: // x halfpel, y qpel - top or bottom during qpel refinement |
200 |
ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data); |
ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data); |
201 |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8); |
1137 |
Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x); |
Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x); |
1138 |
Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y); |
Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y); |
1139 |
} |
} |
1140 |
|
|
1141 |
if (!(inter4v) || |
if (!(inter4v) || |
1142 |
(Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + |
(Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + |
1143 |
Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) { |
Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) { |
1338 |
|
|
1339 |
const int32_t iEdgedWidth = pParam->edged_width; |
const int32_t iEdgedWidth = pParam->edged_width; |
1340 |
|
|
1341 |
int i, iDirection, mask; |
int i, iDirection = 255, mask; |
1342 |
VECTOR pmv[7]; |
VECTOR pmv[7]; |
1343 |
MainSearchFunc *MainSearchPtr; |
MainSearchFunc *MainSearchPtr; |
1344 |
*Data->iMinSAD = MV_MAX_ERROR; |
*Data->iMinSAD = MV_MAX_ERROR; |
1363 |
CheckCandidate = CheckCandidate16no4v; |
CheckCandidate = CheckCandidate16no4v; |
1364 |
|
|
1365 |
// main loop. checking all predictions |
// main loop. checking all predictions |
1366 |
for (i = 0; i < 8; i++) { |
for (i = 0; i < 7; i++) { |
1367 |
if (!(mask = make_mask(pmv, i)) ) continue; |
if (!(mask = make_mask(pmv, i)) ) continue; |
1368 |
CheckCandidate16no4v(pmv[i].x, pmv[i].y, mask, &iDirection, Data); |
CheckCandidate16no4v(pmv[i].x, pmv[i].y, mask, &iDirection, Data); |
1369 |
} |
} |
1374 |
MainSearchPtr = AdvDiamondSearch; |
MainSearchPtr = AdvDiamondSearch; |
1375 |
else MainSearchPtr = DiamondSearch; |
else MainSearchPtr = DiamondSearch; |
1376 |
|
|
1377 |
(*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, 255); |
(*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, iDirection); |
1378 |
|
|
1379 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1380 |
|
|
1381 |
if (Data->qpel) { |
if (Data->qpel && *Data->iMinSAD < *best_sad + 300) { |
1382 |
Data->currentQMV->x = 2*Data->currentMV->x; |
Data->currentQMV->x = 2*Data->currentMV->x; |
1383 |
Data->currentQMV->y = 2*Data->currentMV->y; |
Data->currentQMV->y = 2*Data->currentMV->y; |
1384 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1388 |
} |
} |
1389 |
|
|
1390 |
// three bits are needed to code backward mode. four for forward |
// three bits are needed to code backward mode. four for forward |
1391 |
// we treat the bits just like they were vector's |
|
1392 |
if (mode_current == MODE_FORWARD) *Data->iMinSAD += 4 * Data->lambda16; |
if (mode_current == MODE_FORWARD) *Data->iMinSAD += 4 * Data->lambda16; |
1393 |
else *Data->iMinSAD += 3 * Data->lambda16; |
else *Data->iMinSAD += 3 * Data->lambda16; |
1394 |
|
|
1688 |
} while (!(iDirection)); |
} while (!(iDirection)); |
1689 |
|
|
1690 |
if (fData->qpel) { |
if (fData->qpel) { |
1691 |
|
if (*fData->iMinSAD > *best_sad + 500) return; |
1692 |
CheckCandidate = CheckCandidateInt; |
CheckCandidate = CheckCandidateInt; |
1693 |
fData->qpel_precision = bData.qpel_precision = 1; |
fData->qpel_precision = bData.qpel_precision = 1; |
1694 |
get_range(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode, 1, 0); |
get_range(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode, 1, 0); |
1698 |
fData->currentQMV[1].x = 2 * fData->currentMV[1].x; |
fData->currentQMV[1].x = 2 * fData->currentMV[1].x; |
1699 |
fData->currentQMV[1].y = 2 * fData->currentMV[1].y; |
fData->currentQMV[1].y = 2 * fData->currentMV[1].y; |
1700 |
SubpelRefine(fData); |
SubpelRefine(fData); |
1701 |
|
if (*fData->iMinSAD > *best_sad + 300) return; |
1702 |
fData->currentQMV[2] = fData->currentQMV[0]; |
fData->currentQMV[2] = fData->currentQMV[0]; |
1703 |
SubpelRefine(&bData); |
SubpelRefine(&bData); |
1704 |
} |
} |
1705 |
|
|
1706 |
*fData->iMinSAD += (2+2) * fData->lambda16; // two bits are needed to code interpolate mode. |
*fData->iMinSAD += (2+3) * fData->lambda16; // two bits are needed to code interpolate mode. |
1707 |
|
|
1708 |
if (*fData->iMinSAD < *best_sad) { |
if (*fData->iMinSAD < *best_sad) { |
1709 |
*best_sad = *fData->iMinSAD; |
*best_sad = *fData->iMinSAD; |