200 |
GetReferenceB(const int x, const int y, const uint32_t dir, const SearchData * const data) |
GetReferenceB(const int x, const int y, const uint32_t dir, const SearchData * const data) |
201 |
{ |
{ |
202 |
// dir : 0 = forward, 1 = backward |
// dir : 0 = forward, 1 = backward |
203 |
const uint8_t* const *direction = ( dir == 0 ? data->RefP : data->b_RefP ); |
const uint8_t *const *const direction = ( dir == 0 ? data->RefP : data->b_RefP ); |
204 |
const int picture = ((x&1)<<1) | (y&1); |
const int picture = ((x&1)<<1) | (y&1); |
205 |
const int offset = (x>>1) + (y>>1)*data->iEdgedWidth; |
const int offset = (x>>1) + (y>>1)*data->iEdgedWidth; |
206 |
return direction[picture] + offset; |
return direction[picture] + offset; |
351 |
data->iMinSAD[3] = data->temp[3]; current[3].x = x; current[3].y = y; } |
data->iMinSAD[3] = data->temp[3]; current[3].x = x; current[3].y = y; } |
352 |
if (data->temp[4] < data->iMinSAD[4]) { |
if (data->temp[4] < data->iMinSAD[4]) { |
353 |
data->iMinSAD[4] = data->temp[4]; current[4].x = x; current[4].y = y; } |
data->iMinSAD[4] = data->temp[4]; current[4].x = x; current[4].y = y; } |
|
|
|
354 |
} |
} |
355 |
|
|
356 |
static void |
static void |
383 |
} |
} |
384 |
} |
} |
385 |
|
|
|
|
|
386 |
static void |
static void |
387 |
CheckCandidate32(const int x, const int y, const int Direction, int * const dir, const SearchData * const data) |
CheckCandidate32(const int x, const int y, const int Direction, int * const dir, const SearchData * const data) |
388 |
{ |
{ |
463 |
if ( (x > data->max_dx) || (x < data->min_dx) |
if ( (x > data->max_dx) || (x < data->min_dx) |
464 |
|| (y > data->max_dy) || (y < data->min_dy) ) return; |
|| (y > data->max_dy) || (y < data->min_dy) ) return; |
465 |
|
|
466 |
sad = sad32v_c(data->Cur, data->RefP[0] + x/2 + (y/2)*(data->iEdgedWidth), |
sad = sad32v_c(data->Cur, data->RefP[0] + (x>>1) + (y>>1)*(data->iEdgedWidth), |
467 |
data->iEdgedWidth, data->temp+1); |
data->iEdgedWidth, data->temp+1); |
468 |
|
|
469 |
if (sad < *(data->iMinSAD)) { |
if (sad < *(data->iMinSAD)) { |
1221 |
if (bits_inter4v < bits) { Data->iMinSAD[0] = bits = bits_inter4v; mode = MODE_INTER4V; } |
if (bits_inter4v < bits) { Data->iMinSAD[0] = bits = bits_inter4v; mode = MODE_INTER4V; } |
1222 |
} |
} |
1223 |
|
|
|
|
|
1224 |
intra = CountMBBitsIntra(Data); |
intra = CountMBBitsIntra(Data); |
1225 |
|
|
1226 |
if (intra < bits) { *Data->iMinSAD = bits = intra; return MODE_INTRA; } |
if (intra < bits) { *Data->iMinSAD = bits = intra; return MODE_INTRA; } |
1359 |
} |
} |
1360 |
|
|
1361 |
if (MotionFlags & PMV_HALFPELREFINE16) |
if (MotionFlags & PMV_HALFPELREFINE16) |
|
if ((!(MotionFlags & HALFPELREFINE16_BITS)) || Data->iMinSAD[0] < 200*(int)iQuant) |
|
1362 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1363 |
|
|
1364 |
for(i = 0; i < 5; i++) { |
for(i = 0; i < 5; i++) { |
1370 |
|
|
1371 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
1372 |
pParam->width, pParam->height, Data->iFcode, 1, 0); |
pParam->width, pParam->height, Data->iFcode, 1, 0); |
|
|
|
|
if ((!(MotionFlags & QUARTERPELREFINE16_BITS)) || (Data->iMinSAD[0] < 200*(int)iQuant)) { |
|
1373 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1374 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1375 |
} |
} |
|
} |
|
1376 |
|
|
1377 |
if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) && (Data->iMinSAD[0] < (int32_t)iQuant * 30)) inter4v = 0; |
if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) && (Data->iMinSAD[0] < (int32_t)iQuant * 30)) inter4v = 0; |
1378 |
|
|
1379 |
if (inter4v && (!(GlobalFlags & XVID_MODEDECISION_BITS) || |
if (inter4v) { |
|
(!(MotionFlags & QUARTERPELREFINE8_BITS)) || (!(MotionFlags & HALFPELREFINE8_BITS)) || |
|
|
((!(MotionFlags & EXTSEARCH_BITS)) && (!(MotionFlags&PMV_EXTSEARCH8)) ))) { |
|
|
// if decision is BITS-based and all refinement steps will be done in BITS domain, there is no reason to call this loop |
|
|
|
|
1380 |
SearchData Data8; |
SearchData Data8; |
1381 |
memcpy(&Data8, Data, sizeof(SearchData)); //quick copy of common data |
memcpy(&Data8, Data, sizeof(SearchData)); //quick copy of common data |
1382 |
|
|
1388 |
if ((Data->chroma) && (!(GlobalFlags & XVID_MODEDECISION_BITS))) { |
if ((Data->chroma) && (!(GlobalFlags & XVID_MODEDECISION_BITS))) { |
1389 |
// chroma is only used for comparsion to INTER. if the comparsion will be done in BITS domain, there is no reason to compute it |
// chroma is only used for comparsion to INTER. if the comparsion will be done in BITS domain, there is no reason to compute it |
1390 |
int sumx = 0, sumy = 0; |
int sumx = 0, sumy = 0; |
1391 |
const int div = 1 + Data->qpel; |
const int div = Data->qpel ? 2 : 0; |
1392 |
const VECTOR * const mv = Data->qpel ? pMB->qmvs : pMB->mvs; |
const VECTOR * const mv = Data->qpel ? pMB->qmvs : pMB->mvs; |
1393 |
|
|
1394 |
for (i = 0; i < 4; i++) { |
for (i = 0; i < 4; i++) { |
2180 |
} |
} |
2181 |
} |
} |
2182 |
|
|
2183 |
#define INTRA_THRESH 2400 |
#define INTRA_THRESH 2050 |
2184 |
#define INTER_THRESH 1300 |
#define INTER_THRESH 1200 |
2185 |
|
|
2186 |
int |
int |
2187 |
MEanalysis( const IMAGE * const pRef, |
MEanalysis( const IMAGE * const pRef, |
2256 |
sSAD /= blocks; |
sSAD /= blocks; |
2257 |
s = (10*s) / blocks; |
s = (10*s) / blocks; |
2258 |
|
|
2259 |
if (s > 4) sSAD += (s - 3) * (300 - 2*b_thresh); //static block - looks bad when in bframe... |
if (s > 4) sSAD += (s - 2) * (160 - 2*b_thresh); //static block - looks bad when in bframe... |
2260 |
|
|
2261 |
if (sSAD > InterThresh ) return P_VOP; |
if (sSAD > InterThresh ) return P_VOP; |
2262 |
emms(); |
emms(); |
2310 |
if (pMB->mode == MODE_INTRA || pMB->mode == MODE_NOT_CODED) |
if (pMB->mode == MODE_INTRA || pMB->mode == MODE_NOT_CODED) |
2311 |
continue; |
continue; |
2312 |
|
|
2313 |
if ( ( (ABS(mv.x - (pMB-1)->mvs[0].x) < deltax) && (ABS(mv.y - (pMB-1)->mvs[0].y) < deltay) ) |
if ( ( (abs(mv.x - (pMB-1)->mvs[0].x) < deltax) && (abs(mv.y - (pMB-1)->mvs[0].y) < deltay) ) |
2314 |
&& ( (ABS(mv.x - (pMB+1)->mvs[0].x) < deltax) && (ABS(mv.y - (pMB+1)->mvs[0].y) < deltay) ) |
&& ( (abs(mv.x - (pMB+1)->mvs[0].x) < deltax) && (abs(mv.y - (pMB+1)->mvs[0].y) < deltay) ) |
2315 |
&& ( (ABS(mv.x - (pMB-MBw)->mvs[0].x) < deltax) && (ABS(mv.y - (pMB-MBw)->mvs[0].y) < deltay) ) |
&& ( (abs(mv.x - (pMB-MBw)->mvs[0].x) < deltax) && (abs(mv.y - (pMB-MBw)->mvs[0].y) < deltay) ) |
2316 |
&& ( (ABS(mv.x - (pMB+MBw)->mvs[0].x) < deltax) && (ABS(mv.y - (pMB+MBw)->mvs[0].y) < deltay) ) ) |
&& ( (abs(mv.x - (pMB+MBw)->mvs[0].x) < deltax) && (abs(mv.y - (pMB+MBw)->mvs[0].y) < deltay) ) ) |
2317 |
MBmask[mbnum]=1; |
MBmask[mbnum]=1; |
2318 |
} |
} |
2319 |
|
|
2388 |
continue; |
continue; |
2389 |
|
|
2390 |
oldnum++; |
oldnum++; |
2391 |
meanx += ABS(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x ); |
meanx += fabs(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x ); |
2392 |
meany += ABS(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y ); |
meany += fabs(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y ); |
2393 |
} |
} |
2394 |
|
|
2395 |
if (4*meanx > oldnum) /* better fit than 0.25 is useless */ |
if (4*meanx > oldnum) /* better fit than 0.25 is useless */ |
2416 |
if (!MBmask[mbnum]) |
if (!MBmask[mbnum]) |
2417 |
continue; |
continue; |
2418 |
|
|
2419 |
if ( ( ABS(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x ) > meanx ) |
if ( ( fabs(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x ) > meanx ) |
2420 |
|| ( ABS(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y ) > meany ) ) |
|| ( fabs(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y ) > meany ) ) |
2421 |
MBmask[mbnum]=0; |
MBmask[mbnum]=0; |
2422 |
else |
else |
2423 |
num++; |
num++; |
2560 |
|
|
2561 |
Data8->qpel_precision = Data8->qpel; |
Data8->qpel_precision = Data8->qpel; |
2562 |
// checking the vector which has been found by SAD-based 8x8 search (if it's different than the one found so far) |
// checking the vector which has been found by SAD-based 8x8 search (if it's different than the one found so far) |
2563 |
if (Data8->qpel) { |
{ |
2564 |
if (!(Data8->currentQMV->x == backup[i+1].x && Data8->currentQMV->y == backup[i+1].y)) |
VECTOR *v = Data8->qpel ? Data8->currentQMV : Data8->currentMV; |
2565 |
CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8); |
if (!( (v->x == backup[i+1].x) && (v->y == backup[i+1].y) )) |
|
} else { |
|
|
if (!(Data8->currentMV->x == backup[i+1].x && Data8->currentMV->y == backup[i+1].y)) |
|
2566 |
CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8); |
CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8); |
2567 |
} |
} |
2568 |
|
|