54 |
|
|
55 |
#define iDiamondSize 2 |
#define iDiamondSize 2 |
56 |
|
|
57 |
|
static VECTOR |
58 |
|
GlobalMotionEst(const MACROBLOCK * const pMBs, |
59 |
|
const MBParam * const pParam, const uint32_t iFcode); |
60 |
|
|
61 |
|
|
62 |
static __inline int |
static __inline int |
63 |
d_mv_bits(int x, int y, const uint32_t iFcode) |
d_mv_bits(int x, int y, const uint32_t iFcode) |
64 |
{ |
{ |
142 |
Interpolate8x8qpel(const int x, const int y, const int block, const int dir, const SearchData * const data) |
Interpolate8x8qpel(const int x, const int y, const int block, const int dir, const SearchData * const data) |
143 |
{ |
{ |
144 |
// create or find a qpel-precision reference picture; return pointer to it |
// create or find a qpel-precision reference picture; return pointer to it |
145 |
uint8_t * Reference = (uint8_t *)data->RefQ; |
uint8_t * Reference = (uint8_t *)data->RefQ + 16*dir; |
146 |
const int32_t iEdgedWidth = data->iEdgedWidth; |
const int32_t iEdgedWidth = data->iEdgedWidth; |
147 |
const uint32_t rounding = data->rounding; |
const uint32_t rounding = data->rounding; |
148 |
const int halfpel_x = x/2; |
const int halfpel_x = x/2; |
187 |
Interpolate16x16qpel(const int x, const int y, const int dir, const SearchData * const data) |
Interpolate16x16qpel(const int x, const int y, const int dir, const SearchData * const data) |
188 |
{ |
{ |
189 |
// create or find a qpel-precision reference picture; return pointer to it |
// create or find a qpel-precision reference picture; return pointer to it |
190 |
uint8_t * Reference = (uint8_t *)data->RefQ; |
uint8_t * Reference = (uint8_t *)data->RefQ + 16*dir; |
191 |
const int32_t iEdgedWidth = data->iEdgedWidth; |
const int32_t iEdgedWidth = data->iEdgedWidth; |
192 |
const uint32_t rounding = data->rounding; |
const uint32_t rounding = data->rounding; |
193 |
const int halfpel_x = x/2; |
const int halfpel_x = x/2; |
708 |
|
|
709 |
const VECTOR zeroMV = { 0, 0 }; |
const VECTOR zeroMV = { 0, 0 }; |
710 |
|
|
711 |
|
int mb_width = pParam->mb_width; |
712 |
|
int mb_height = pParam->mb_height; |
713 |
|
|
714 |
uint32_t x, y; |
uint32_t x, y; |
715 |
uint32_t iIntra = 0; |
uint32_t iIntra = 0; |
716 |
int32_t InterBias, quant = current->quant, sad00; |
int32_t InterBias, quant = current->quant, sad00; |
732 |
Data.qpel = pParam->m_quarterpel; |
Data.qpel = pParam->m_quarterpel; |
733 |
Data.chroma = current->global_flags & XVID_ME_COLOUR; |
Data.chroma = current->global_flags & XVID_ME_COLOUR; |
734 |
|
|
735 |
|
if ((current->global_flags & XVID_REDUCED)) |
736 |
|
{ |
737 |
|
mb_width = (pParam->width + 31) / 32; |
738 |
|
mb_height = (pParam->height + 31) / 32; |
739 |
|
} |
740 |
|
|
741 |
if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL) |
if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL) |
742 |
return 1; // allocate some mem for qpel interpolated blocks |
return 1; // allocate some mem for qpel interpolated blocks |
743 |
// somehow this is dirty since I think we shouldn't use malloc outside |
// somehow this is dirty since I think we shouldn't use malloc outside |
745 |
Data.RefQ = qimage; |
Data.RefQ = qimage; |
746 |
if (sadInit) (*sadInit) (); |
if (sadInit) (*sadInit) (); |
747 |
|
|
748 |
for (y = 0; y < pParam->mb_height; y++) { |
for (y = 0; y < mb_height; y++) { |
749 |
for (x = 0; x < pParam->mb_width; x++) { |
for (x = 0; x < mb_width; x++) { |
750 |
MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width]; |
MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width]; |
751 |
|
|
752 |
pMB->sad16 |
pMB->sad16 |
916 |
|
|
917 |
get_pmvdata2(pMBs, pParam->mb_width, 0, x, y, 0, pmv, Data->temp); //has to be changed to get_pmv(2)() |
get_pmvdata2(pMBs, pParam->mb_width, 0, x, y, 0, pmv, Data->temp); //has to be changed to get_pmv(2)() |
918 |
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, |
919 |
pParam->width, pParam->height, Data->iFcode, pParam->m_quarterpel); |
pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel); |
920 |
|
|
921 |
Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16; |
Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16; |
922 |
Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8; |
Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8; |
1031 |
if((pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) { |
if((pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) { |
1032 |
|
|
1033 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1034 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
get_range_qpel(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
1035 |
pParam->width, pParam->height, Data->iFcode, 0); |
pParam->width, pParam->height, Data->iFcode); |
1036 |
|
|
1037 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1038 |
} |
} |
1134 |
Data->qpel_precision = 0; |
Data->qpel_precision = 0; |
1135 |
|
|
1136 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8, |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8, |
1137 |
pParam->width, pParam->height, OldData->iFcode, pParam->m_quarterpel); |
pParam->width, pParam->height, OldData->iFcode - pParam->m_quarterpel); |
1138 |
CheckCandidate = CheckCandidate8; |
CheckCandidate = CheckCandidate8; |
1139 |
|
|
1140 |
if (MotionFlags & PMV_EXTSEARCH8) { |
if (MotionFlags & PMV_EXTSEARCH8) { |
1168 |
if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) && |
if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) && |
1169 |
(MotionFlags & PMV_QUARTERPELREFINE8)) { |
(MotionFlags & PMV_QUARTERPELREFINE8)) { |
1170 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1171 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8, |
get_range_qpel(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8, |
1172 |
pParam->width, pParam->height, OldData->iFcode, 0); |
pParam->width, pParam->height, OldData->iFcode); |
1173 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1174 |
} |
} |
1175 |
} |
} |
1273 |
Data->predMV = *predMV; |
Data->predMV = *predMV; |
1274 |
|
|
1275 |
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, |
1276 |
pParam->width, pParam->height, iFcode, pParam->m_quarterpel); |
pParam->width, pParam->height, iFcode - pParam->m_quarterpel); |
1277 |
|
|
1278 |
pmv[0] = Data->predMV; |
pmv[0] = Data->predMV; |
1279 |
if (Data->qpel) { pmv[0].x /= 2; pmv[0].y /= 2; } |
if (Data->qpel) { pmv[0].x /= 2; pmv[0].y /= 2; } |
1302 |
Data->currentQMV->x = 2*Data->currentMV->x; |
Data->currentQMV->x = 2*Data->currentMV->x; |
1303 |
Data->currentQMV->y = 2*Data->currentMV->y; |
Data->currentQMV->y = 2*Data->currentMV->y; |
1304 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1305 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
get_range_qpel(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
1306 |
pParam->width, pParam->height, iFcode, 0); |
pParam->width, pParam->height, iFcode); |
1307 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1308 |
} |
} |
1309 |
|
|
1382 |
Data->min_dy *= 2; |
Data->min_dy *= 2; |
1383 |
Data->referencemv = b_mb->qmvs; |
Data->referencemv = b_mb->qmvs; |
1384 |
} else Data->referencemv = b_mb->mvs; |
} else Data->referencemv = b_mb->mvs; |
1385 |
Data->qpel_precision = 0; // it'm a trick. it's 1 not 0, but we need 0 here |
Data->qpel_precision = 0; // it's a trick. it's 1 not 0, but we need 0 here |
1386 |
|
|
1387 |
for (k = 0; k < 4; k++) { |
for (k = 0; k < 4; k++) { |
1388 |
pMB->mvs[k].x = Data->directmvF[k].x = ((TRB * Data->referencemv[k].x) / TRD); |
pMB->mvs[k].x = Data->directmvF[k].x = ((TRB * Data->referencemv[k].x) / TRD); |
1469 |
|
|
1470 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1471 |
|
|
1472 |
*Data->iMinSAD += 1 * Data->lambda16; // one bit is needed to code direct mode |
// *Data->iMinSAD += 1 * Data->lambda16; // one bit is needed to code direct mode |
1473 |
*best_sad = *Data->iMinSAD; |
*best_sad = *Data->iMinSAD; |
1474 |
|
|
1475 |
// if (b_mb->mode == MODE_INTER4V) |
if (b_mb->mode == MODE_INTER4V) |
1476 |
pMB->mode = MODE_DIRECT; |
pMB->mode = MODE_DIRECT; |
1477 |
// else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation |
else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation |
1478 |
|
|
1479 |
pMB->pmvs[3] = *Data->currentMV; |
pMB->pmvs[3] = *Data->currentMV; |
1480 |
|
|
1549 |
bData.RefV = fData->bRefV = b_RefV + (x + y * iEdgedWidth) * 16; |
bData.RefV = fData->bRefV = b_RefV + (x + y * iEdgedWidth) * 16; |
1550 |
bData.RefHV = fData->bRefHV = b_RefHV + (x + y * iEdgedWidth) * 16; |
bData.RefHV = fData->bRefHV = b_RefHV + (x + y * iEdgedWidth) * 16; |
1551 |
bData.RefQ = fData->RefQ; |
bData.RefQ = fData->RefQ; |
1552 |
fData->qpel_precision = bData.qpel_precision = 0; |
fData->qpel_precision = bData.qpel_precision = 0; bData.qpel = fData->qpel; |
1553 |
bData.rounding = 0; |
bData.rounding = 0; |
1554 |
|
|
1555 |
bData.bpredMV = fData->predMV = *f_predMV; |
bData.bpredMV = fData->predMV = *f_predMV; |
1556 |
fData->bpredMV = bData.predMV = *b_predMV; |
fData->bpredMV = bData.predMV = *b_predMV; |
1557 |
|
|
1558 |
fData->currentMV[0] = fData->currentMV[2]; |
fData->currentMV[0] = fData->currentMV[2]; |
1559 |
get_range(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode, pParam->m_quarterpel); |
get_range(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode - pParam->m_quarterpel); |
1560 |
get_range(&bData.min_dx, &bData.max_dx, &bData.min_dy, &bData.max_dy, x, y, 16, pParam->width, pParam->height, bcode, pParam->m_quarterpel); |
get_range(&bData.min_dx, &bData.max_dx, &bData.min_dy, &bData.max_dy, x, y, 16, pParam->width, pParam->height, bcode - pParam->m_quarterpel); |
1561 |
|
|
1562 |
if (fData->currentMV[0].x > fData->max_dx) fData->currentMV[0].x = fData->max_dx; |
if (fData->currentMV[0].x > fData->max_dx) fData->currentMV[0].x = fData->max_dx; |
1563 |
if (fData->currentMV[0].x < fData->min_dx) fData->currentMV[0].x = fData->min_dy; |
if (fData->currentMV[0].x < fData->min_dx) fData->currentMV[0].x = fData->min_dx; |
1564 |
if (fData->currentMV[0].y > fData->max_dy) fData->currentMV[0].y = fData->max_dx; |
if (fData->currentMV[0].y > fData->max_dy) fData->currentMV[0].y = fData->max_dy; |
1565 |
if (fData->currentMV[0].y > fData->min_dy) fData->currentMV[0].y = fData->min_dy; |
if (fData->currentMV[0].y < fData->min_dy) fData->currentMV[0].y = fData->min_dy; |
1566 |
|
|
1567 |
if (fData->currentMV[1].x > bData.max_dx) fData->currentMV[1].x = bData.max_dx; |
if (fData->currentMV[1].x > bData.max_dx) fData->currentMV[1].x = bData.max_dx; |
1568 |
if (fData->currentMV[1].x < bData.min_dx) fData->currentMV[1].x = bData.min_dy; |
if (fData->currentMV[1].x < bData.min_dx) fData->currentMV[1].x = bData.min_dx; |
1569 |
if (fData->currentMV[1].y > bData.max_dy) fData->currentMV[1].y = bData.max_dx; |
if (fData->currentMV[1].y > bData.max_dy) fData->currentMV[1].y = bData.max_dy; |
1570 |
if (fData->currentMV[1].y > bData.min_dy) fData->currentMV[1].y = bData.min_dy; |
if (fData->currentMV[1].y < bData.min_dy) fData->currentMV[1].y = bData.min_dy; |
1571 |
|
|
1572 |
CheckCandidateInt(fData->currentMV[0].x, fData->currentMV[0].y, 255, &iDirection, fData); |
CheckCandidateInt(fData->currentMV[0].x, fData->currentMV[0].y, 255, &iDirection, fData); |
1573 |
|
|
1593 |
|
|
1594 |
} while (!(iDirection)); |
} while (!(iDirection)); |
1595 |
|
|
|
*fData->iMinSAD += 2 * fData->lambda16; // two bits are needed to code interpolate mode. |
|
|
|
|
1596 |
if (fData->qpel) { |
if (fData->qpel) { |
1597 |
|
CheckCandidate = CheckCandidateInt; |
1598 |
fData->qpel_precision = bData.qpel_precision = 1; |
fData->qpel_precision = bData.qpel_precision = 1; |
1599 |
get_range(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode, 0); |
get_range_qpel(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode); |
1600 |
get_range(&bData.min_dx, &bData.max_dx, &bData.min_dy, &bData.max_dy, x, y, 16, pParam->width, pParam->height, bcode, 0); |
get_range_qpel(&bData.min_dx, &bData.max_dx, &bData.min_dy, &bData.max_dy, x, y, 16, pParam->width, pParam->height, bcode); |
1601 |
fData->currentQMV[2].x = fData->currentQMV[0].x = 2 * fData->currentMV[0].x; |
fData->currentQMV[2].x = fData->currentQMV[0].x = 2 * fData->currentMV[0].x; |
1602 |
fData->currentQMV[2].y = fData->currentQMV[0].y = 2 * fData->currentMV[0].y; |
fData->currentQMV[2].y = fData->currentQMV[0].y = 2 * fData->currentMV[0].y; |
1603 |
fData->currentQMV[1].x = 2 * fData->currentMV[1].x; |
fData->currentQMV[1].x = 2 * fData->currentMV[1].x; |
1607 |
SubpelRefine(&bData); |
SubpelRefine(&bData); |
1608 |
} |
} |
1609 |
|
|
1610 |
|
*fData->iMinSAD += 2 * fData->lambda16; // two bits are needed to code interpolate mode. |
1611 |
|
|
1612 |
if (*fData->iMinSAD < *best_sad) { |
if (*fData->iMinSAD < *best_sad) { |
1613 |
*best_sad = *fData->iMinSAD; |
*best_sad = *fData->iMinSAD; |
1614 |
pMB->mvs[0] = fData->currentMV[0]; |
pMB->mvs[0] = fData->currentMV[0]; |
1669 |
Data.iEdgedWidth = pParam->edged_width; |
Data.iEdgedWidth = pParam->edged_width; |
1670 |
Data.currentMV = currentMV; Data.currentQMV = currentQMV; |
Data.currentMV = currentMV; Data.currentQMV = currentQMV; |
1671 |
Data.iMinSAD = &iMinSAD; |
Data.iMinSAD = &iMinSAD; |
1672 |
Data.lambda16 = lambda_vec16[frame->quant]; |
Data.lambda16 = lambda_vec16[frame->quant] + 2; |
1673 |
Data.qpel = pParam->m_quarterpel; |
Data.qpel = pParam->m_quarterpel; |
1674 |
Data.rounding = 0; |
Data.rounding = 0; |
1675 |
|
|
1766 |
case MODE_DIRECT: |
case MODE_DIRECT: |
1767 |
case MODE_DIRECT_NO4V: |
case MODE_DIRECT_NO4V: |
1768 |
d_count++; |
d_count++; |
|
break; |
|
1769 |
default: |
default: |
1770 |
break; |
break; |
1771 |
} |
} |
1797 |
MainSearchFunc * MainSearchPtr; |
MainSearchFunc * MainSearchPtr; |
1798 |
|
|
1799 |
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, |
1800 |
pParam->width, pParam->height, Data->iFcode, pParam->m_quarterpel); |
pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel); |
1801 |
|
|
1802 |
Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16; |
Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16; |
1803 |
Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8; |
Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8; |
1860 |
} |
} |
1861 |
|
|
1862 |
if((pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) { |
if((pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) { |
1863 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
get_range_qpel(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
1864 |
pParam->width, pParam->height, Data->iFcode, 0); |
pParam->width, pParam->height, Data->iFcode); |
1865 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
1866 |
SubpelRefine(Data); |
SubpelRefine(Data); |
1867 |
} |
} |
2017 |
else Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); //else median |
else Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); //else median |
2018 |
|
|
2019 |
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, |
2020 |
pParam->width, pParam->height, Data->iFcode, pParam->m_quarterpel); |
pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel); |
2021 |
|
|
2022 |
Data->Cur = pCur + (x + y * pParam->edged_width) * 16; |
Data->Cur = pCur + (x + y * pParam->edged_width) * 16; |
2023 |
Data->Ref = pRef + (x + y * pParam->edged_width) * 16; |
Data->Ref = pRef + (x + y * pParam->edged_width) * 16; |
2051 |
} |
} |
2052 |
|
|
2053 |
#define INTRA_THRESH 1350 |
#define INTRA_THRESH 1350 |
2054 |
#define INTER_THRESH 900 |
#define INTER_THRESH 1200 |
2055 |
|
|
2056 |
|
|
2057 |
int |
int |
2062 |
int intraCount, //number of non-I frames after last I frame; 0 if we force P/B frame |
int intraCount, //number of non-I frames after last I frame; 0 if we force P/B frame |
2063 |
int bCount) // number if B frames in a row |
int bCount) // number if B frames in a row |
2064 |
{ |
{ |
2065 |
|
int mb_width = pParam->mb_width; |
2066 |
|
int mb_height = pParam->mb_height; |
2067 |
|
|
2068 |
uint32_t x, y, intra = 0; |
uint32_t x, y, intra = 0; |
2069 |
int sSAD = 0; |
int sSAD = 0; |
2070 |
MACROBLOCK * const pMBs = Current->mbs; |
MACROBLOCK * const pMBs = Current->mbs; |
2080 |
Data.iFcode = Current->fcode; |
Data.iFcode = Current->fcode; |
2081 |
CheckCandidate = CheckCandidate16no4vI; |
CheckCandidate = CheckCandidate16no4vI; |
2082 |
|
|
2083 |
|
if ((Current->global_flags & XVID_REDUCED)) |
2084 |
|
{ |
2085 |
|
mb_width = (pParam->width + 31) / 32; |
2086 |
|
mb_height = (pParam->height + 31) / 32; |
2087 |
|
} |
2088 |
|
|
2089 |
|
|
2090 |
if (intraCount < 10) // we're right after an I frame |
if (intraCount < 10) // we're right after an I frame |
2091 |
IntraThresh += 4 * (intraCount - 10) * (intraCount - 10); |
IntraThresh += 4 * (intraCount - 10) * (intraCount - 10); |
2092 |
else |
else |
2094 |
IntraThresh -= (IntraThresh * (maxIntra - 5*(maxIntra - intraCount)))/maxIntra; |
IntraThresh -= (IntraThresh * (maxIntra - 5*(maxIntra - intraCount)))/maxIntra; |
2095 |
|
|
2096 |
|
|
2097 |
InterThresh += 300 * (1 - bCount); |
InterThresh += 400 * (1 - bCount); |
2098 |
if (InterThresh < 200) InterThresh = 200; |
if (InterThresh < 200) InterThresh = 200; |
2099 |
|
|
2100 |
if (sadInit) (*sadInit) (); |
if (sadInit) (*sadInit) (); |
2101 |
|
|
2102 |
for (y = 1; y < pParam->mb_height-1; y++) { |
for (y = 1; y < mb_height-1; y++) { |
2103 |
for (x = 1; x < pParam->mb_width-1; x++) { |
for (x = 1; x < mb_width-1; x++) { |
2104 |
int sad, dev; |
int sad, dev; |
2105 |
MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width]; |
MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width]; |
2106 |
|
|
2112 |
pParam->edged_width); |
pParam->edged_width); |
2113 |
if (dev + IntraThresh < sad) { |
if (dev + IntraThresh < sad) { |
2114 |
pMB->mode = MODE_INTRA; |
pMB->mode = MODE_INTRA; |
2115 |
if (++intra > (pParam->mb_height-2)*(pParam->mb_width-2)/2) return 2; // I frame |
if (++intra > (mb_height-2)*(mb_width-2)/2) return 2; // I frame |
2116 |
} |
} |
2117 |
} |
} |
2118 |
sSAD += sad; |
sSAD += sad; |
2119 |
} |
} |
2120 |
} |
} |
2121 |
sSAD /= (pParam->mb_height-2)*(pParam->mb_width-2); |
sSAD /= (mb_height-2)*(mb_width-2); |
2122 |
if (sSAD > InterThresh ) return 1; //P frame |
if (sSAD > InterThresh ) return 1; //P frame |
2123 |
emms(); |
emms(); |
2124 |
return 0; // B frame |
return 0; // B frame |
2129 |
FindFcode( const MBParam * const pParam, |
FindFcode( const MBParam * const pParam, |
2130 |
const FRAMEINFO * const current) |
const FRAMEINFO * const current) |
2131 |
{ |
{ |
2132 |
|
int mb_width = pParam->mb_width; |
2133 |
|
int mb_height = pParam->mb_height; |
2134 |
|
|
2135 |
uint32_t x, y; |
uint32_t x, y; |
2136 |
int max = 0, min = 0, i; |
int max = 0, min = 0, i; |
2137 |
|
|
2138 |
for (y = 0; y < pParam->mb_height; y++) { |
|
2139 |
for (x = 0; x < pParam->mb_width; x++) { |
if ((current->global_flags & XVID_REDUCED)) |
2140 |
|
{ |
2141 |
|
mb_width = (pParam->width + 31) / 32; |
2142 |
|
mb_height = (pParam->height + 31) / 32; |
2143 |
|
} |
2144 |
|
|
2145 |
|
|
2146 |
|
for (y = 0; y < mb_height; y++) { |
2147 |
|
for (x = 0; x < mb_width; x++) { |
2148 |
|
|
2149 |
MACROBLOCK *pMB = ¤t->mbs[x + y * pParam->mb_width]; |
MACROBLOCK *pMB = ¤t->mbs[x + y * pParam->mb_width]; |
2150 |
for(i = 0; i < (pMB->mode == MODE_INTER4V ? 4:1); i++) { |
for(i = 0; i < (pMB->mode == MODE_INTER4V ? 4:1); i++) { |