84 |
{ |
{ |
85 |
int sad; |
int sad; |
86 |
const uint32_t stride = data->iEdgedWidth/2; |
const uint32_t stride = data->iEdgedWidth/2; |
|
dx = (dx >> 1) + roundtab_79[dx & 0x3]; |
|
|
dy = (dy >> 1) + roundtab_79[dy & 0x3]; |
|
87 |
|
|
88 |
if (dx == data->temp[5] && dy == data->temp[6]) return data->temp[7]; //it has been checked recently |
if (dx == data->temp[5] && dy == data->temp[6]) return data->temp[7]; //it has been checked recently |
89 |
data->temp[5] = dx; data->temp[6] = dy; // backup |
data->temp[5] = dx; data->temp[6] = dy; // backup |
262 |
data->temp[0] += (data->lambda16 * t * data->temp[0])/1000; |
data->temp[0] += (data->lambda16 * t * data->temp[0])/1000; |
263 |
data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))/100; |
data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))/100; |
264 |
|
|
265 |
if (data->chroma) data->temp[0] += ChromaSAD(xc, yc, data); |
if (data->chroma) data->temp[0] += ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3], |
266 |
|
(yc >> 1) + roundtab_79[yc & 0x3], data); |
267 |
|
|
268 |
if (data->temp[0] < data->iMinSAD[0]) { |
if (data->temp[0] < data->iMinSAD[0]) { |
269 |
data->iMinSAD[0] = data->temp[0]; |
data->iMinSAD[0] = data->temp[0]; |
753 |
uint32_t x, y; |
uint32_t x, y; |
754 |
uint32_t iIntra = 0; |
uint32_t iIntra = 0; |
755 |
int32_t InterBias, quant = current->quant, sad00; |
int32_t InterBias, quant = current->quant, sad00; |
|
uint8_t *qimage; |
|
756 |
|
|
757 |
// some pre-initialized thingies for SearchP |
// some pre-initialized thingies for SearchP |
758 |
int32_t temp[8]; |
int32_t temp[8]; |
778 |
Data.qpel = Data.chroma = 0; |
Data.qpel = Data.chroma = 0; |
779 |
} |
} |
780 |
|
|
781 |
if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL) |
Data.RefQ = pRefV->u; // a good place, also used in MC (for similar purpose) |
|
return 1; // allocate some mem for qpel interpolated blocks |
|
|
// somehow this is dirty since I think we shouldn't use malloc outside |
|
|
// encoder_create() - so please fix me! |
|
|
Data.RefQ = qimage; |
|
782 |
if (sadInit) (*sadInit) (); |
if (sadInit) (*sadInit) (); |
783 |
|
|
784 |
for (y = 0; y < mb_height; y++) { |
for (y = 0; y < mb_height; y++) { |
870 |
pParam->edged_width); |
pParam->edged_width); |
871 |
|
|
872 |
if (deviation < (pMB->sad16 - InterBias)) { |
if (deviation < (pMB->sad16 - InterBias)) { |
873 |
if (++iIntra >= iLimit) { free(qimage); return 1; } |
if (++iIntra >= iLimit) return 1; |
874 |
pMB->mode = MODE_INTRA; |
pMB->mode = MODE_INTRA; |
875 |
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = |
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = |
876 |
pMB->mvs[3] = zeroMV; |
pMB->mvs[3] = zeroMV; |
882 |
} |
} |
883 |
} |
} |
884 |
} |
} |
|
free(qimage); |
|
885 |
|
|
886 |
if (current->coding_type == S_VOP) /* first GMC step only for S(GMC)-VOPs */ |
if (current->coding_type == S_VOP) /* first GMC step only for S(GMC)-VOPs */ |
887 |
current->GMC_MV = GlobalMotionEst( pMBs, pParam, current->fcode ); |
current->GMC_MV = GlobalMotionEst( pMBs, pParam, current->fcode ); |
932 |
else pmv[4].x = pmv[4].y = 0; |
else pmv[4].x = pmv[4].y = 0; |
933 |
|
|
934 |
// [1] median prediction |
// [1] median prediction |
935 |
if (rrv) { //median is in halfzero-precision |
pmv[1].x = EVEN(pmv[0].x); pmv[1].y = EVEN(pmv[0].y); |
|
pmv[1].x = RRV_MV_SCALEUP(pmv[0].x); |
|
|
pmv[1].y = RRV_MV_SCALEUP(pmv[0].y); |
|
|
} else { pmv[1].x = EVEN(pmv[0].x); pmv[1].y = EVEN(pmv[0].y); } |
|
936 |
|
|
937 |
pmv[0].x = pmv[0].y = 0; // [0] is zero; not used in the loop (checked before) but needed here for make_mask |
pmv[0].x = pmv[0].y = 0; // [0] is zero; not used in the loop (checked before) but needed here for make_mask |
938 |
|
|
947 |
if (rrv) { |
if (rrv) { |
948 |
int i; |
int i; |
949 |
for (i = 0; i < 7; i++) { |
for (i = 0; i < 7; i++) { |
950 |
pmv[i].x = RRV_MV_SCALEDOWN(pmv[i].x); |
pmv[i].x = RRV_MV_SCALEUP(pmv[i].x); // halfzero->halfpel |
951 |
pmv[i].x = RRV_MV_SCALEUP(pmv[i].x); // a trick |
pmv[i].y = RRV_MV_SCALEUP(pmv[i].y); |
952 |
} |
} |
953 |
} |
} |
954 |
} |
} |
1114 |
Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8); |
Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8); |
1115 |
|
|
1116 |
if (Data->chroma) { |
if (Data->chroma) { |
1117 |
int sumx, sumy, dx, dy; |
int sumx, sumy; |
1118 |
|
|
1119 |
if(pParam->m_quarterpel) { |
if(pParam->m_quarterpel) { |
1120 |
sumx= pMB->qmvs[0].x/2 + pMB->qmvs[1].x/2 + pMB->qmvs[2].x/2 + pMB->qmvs[3].x/2; |
sumx= pMB->qmvs[0].x/2 + pMB->qmvs[1].x/2 + pMB->qmvs[2].x/2 + pMB->qmvs[3].x/2; |
1123 |
sumx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; |
sumx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; |
1124 |
sumy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; |
sumy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; |
1125 |
} |
} |
|
dx = (sumx >> 3) + roundtab_76[sumx & 0xf]; |
|
|
dy = (sumy >> 3) + roundtab_76[sumy & 0xf]; |
|
1126 |
|
|
1127 |
Data->iMinSAD[1] += ChromaSAD(dx, dy, Data); |
Data->iMinSAD[1] += ChromaSAD( (sumx >> 3) + roundtab_76[sumx & 0xf], |
1128 |
|
(sumy >> 3) + roundtab_76[sumy & 0xf], Data); |
1129 |
} |
} |
1130 |
} |
} |
1131 |
|
|
1307 |
|
|
1308 |
if ((x != 0)&&(y != 0)) { |
if ((x != 0)&&(y != 0)) { |
1309 |
pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr); |
pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr); |
1310 |
pmv[6].x = EVEN(pmv[5].x); pmv[5].y = EVEN(pmv[5].y); |
pmv[6].x = EVEN(pmv[6].x); pmv[6].y = EVEN(pmv[6].y); |
1311 |
} else pmv[6].x = pmv[6].y = 0; |
} else pmv[6].x = pmv[6].y = 0; |
1312 |
|
|
1313 |
// more? |
// more? |
1415 |
const IMAGE * const f_Ref, |
const IMAGE * const f_Ref, |
1416 |
const IMAGE * const b_Ref, |
const IMAGE * const b_Ref, |
1417 |
MACROBLOCK * const pMB, |
MACROBLOCK * const pMB, |
|
const uint32_t quant, |
|
1418 |
const uint32_t x, const uint32_t y, |
const uint32_t x, const uint32_t y, |
1419 |
const SearchData * const Data) |
const SearchData * const Data) |
1420 |
{ |
{ |
1421 |
int dx, dy, b_dx, b_dy; |
int dx = 0, dy = 0, b_dx = 0, b_dy = 0; |
1422 |
uint32_t sum; |
uint32_t sum; |
1423 |
|
const int div = 1 + Data->qpel; |
1424 |
|
int k; |
1425 |
|
const uint32_t quant = pMB->quant; |
1426 |
//this is not full chroma compensation, only it's fullpel approximation. should work though |
//this is not full chroma compensation, only it's fullpel approximation. should work though |
|
if (Data->qpel) { |
|
|
dy = Data->directmvF[0].y/2 + Data->directmvF[1].y/2 + |
|
|
Data->directmvF[2].y/2 + Data->directmvF[3].y/2; |
|
|
|
|
|
dx = Data->directmvF[0].x/2 + Data->directmvF[1].x/2 + |
|
|
Data->directmvF[2].x/2 + Data->directmvF[3].x/2; |
|
|
|
|
|
b_dy = Data->directmvB[0].y/2 + Data->directmvB[1].y/2 + |
|
|
Data->directmvB[2].y/2 + Data->directmvB[3].y/2; |
|
|
|
|
|
b_dx = Data->directmvB[0].x/2 + Data->directmvB[1].x/2 + |
|
|
Data->directmvB[2].x/2 + Data->directmvB[3].x/2; |
|
|
|
|
|
} else { |
|
|
dy = Data->directmvF[0].y + Data->directmvF[1].y + |
|
|
Data->directmvF[2].y + Data->directmvF[3].y; |
|
1427 |
|
|
1428 |
dx = Data->directmvF[0].x + Data->directmvF[1].x + |
for (k = 0; k < 4; k++) { |
1429 |
Data->directmvF[2].x + Data->directmvF[3].x; |
dy += Data->directmvF[k].y / div; |
1430 |
|
dx += Data->directmvF[0].x / div; |
1431 |
b_dy = Data->directmvB[0].y + Data->directmvB[1].y + |
b_dy += Data->directmvB[0].y / div; |
1432 |
Data->directmvB[2].y + Data->directmvB[3].y; |
b_dx += Data->directmvB[0].x / div; |
|
|
|
|
b_dx = Data->directmvB[0].x + Data->directmvB[1].x + |
|
|
Data->directmvB[2].x + Data->directmvB[3].x; |
|
1433 |
} |
} |
1434 |
|
|
|
|
|
1435 |
dy = (dy >> 3) + roundtab_76[dy & 0xf]; |
dy = (dy >> 3) + roundtab_76[dy & 0xf]; |
1436 |
dx = (dx >> 3) + roundtab_76[dx & 0xf]; |
dx = (dx >> 3) + roundtab_76[dx & 0xf]; |
1437 |
b_dy = (b_dy >> 3) + roundtab_76[b_dy & 0xf]; |
b_dy = (b_dy >> 3) + roundtab_76[b_dy & 0xf]; |
1441 |
f_Ref->u + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2, |
f_Ref->u + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2, |
1442 |
b_Ref->u + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2, |
b_Ref->u + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2, |
1443 |
Data->iEdgedWidth/2); |
Data->iEdgedWidth/2); |
1444 |
|
|
1445 |
|
if (sum >= 2 * MAX_CHROMA_SAD_FOR_SKIP * quant) return; //no skip |
1446 |
|
|
1447 |
sum += sad8bi(pCur->v + 8*x + 8*y*(Data->iEdgedWidth/2), |
sum += sad8bi(pCur->v + 8*x + 8*y*(Data->iEdgedWidth/2), |
1448 |
f_Ref->v + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2, |
f_Ref->v + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2, |
1449 |
b_Ref->v + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2, |
b_Ref->v + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2, |
1533 |
|
|
1534 |
// initial (fast) skip decision |
// initial (fast) skip decision |
1535 |
if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH*2) { |
if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH*2) { |
1536 |
SkipDecisionB(pCur, f_Ref, b_Ref, pMB, x, y, Data->chroma, Data); //possible skip - checking chroma |
SkipDecisionB(pCur, f_Ref, b_Ref, pMB, x, y, Data); //possible skip - checking chroma |
1537 |
if (pMB->mode == MODE_DIRECT_NONE_MV) return *Data->iMinSAD; // skip. |
if (pMB->mode == MODE_DIRECT_NONE_MV) return *Data->iMinSAD; // skip. |
1538 |
} |
} |
1539 |
|
|
1736 |
|
|
1737 |
const int32_t TRB = time_pp - time_bp; |
const int32_t TRB = time_pp - time_bp; |
1738 |
const int32_t TRD = time_pp; |
const int32_t TRD = time_pp; |
|
uint8_t * qimage; |
|
1739 |
|
|
1740 |
// some pre-inintialized data for the rest of the search |
// some pre-inintialized data for the rest of the search |
1741 |
|
|
1752 |
Data.qpel = pParam->m_quarterpel; |
Data.qpel = pParam->m_quarterpel; |
1753 |
Data.rounding = 0; |
Data.rounding = 0; |
1754 |
|
|
1755 |
if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL) |
Data.RefQ = f_refV->u; // a good place, also used in MC (for similar purpose) |
|
return; // allocate some mem for qpel interpolated blocks |
|
|
// somehow this is dirty since I think we shouldn't use malloc outside |
|
|
// encoder_create() - so please fix me! |
|
|
Data.RefQ = qimage; |
|
|
|
|
1756 |
// note: i==horizontal, j==vertical |
// note: i==horizontal, j==vertical |
1757 |
for (j = 0; j < pParam->mb_height; j++) { |
for (j = 0; j < pParam->mb_height; j++) { |
1758 |
|
|
1818 |
// final skip decision |
// final skip decision |
1819 |
if ( (skip_sad < frame->quant * MAX_SAD00_FOR_SKIP*2) |
if ( (skip_sad < frame->quant * MAX_SAD00_FOR_SKIP*2) |
1820 |
&& ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) ) |
&& ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) ) |
1821 |
SkipDecisionB(&frame->image, f_ref, b_ref, pMB,frame->quant, i, j, &Data); |
SkipDecisionB(&frame->image, f_ref, b_ref, pMB, i, j, &Data); |
1822 |
|
|
1823 |
switch (pMB->mode) { |
switch (pMB->mode) { |
1824 |
case MODE_FORWARD: |
case MODE_FORWARD: |
1849 |
} |
} |
1850 |
} |
} |
1851 |
} |
} |
|
free(qimage); |
|
1852 |
} |
} |
1853 |
|
|
1854 |
static __inline void |
static __inline void |