📄 motest.cpp
字号:
Bool bColocatedMBExist
)
{
assert (pmbmd->m_rgTranspStatus [0] == PARTIAL);
Int iInitSAD = sad16x16At0WithShape (ppxlcRef0MBY, pmbmd); //shouldn't favor 0 mv inside this function
Int iSADForward = blkmatch16WithShape (pmvForward, x, y, x, y, iInitSAD, ppxlcRef0MBY,
m_puciRefQZoom0, pmbmd, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample,0);
pmvForward->computeTrueMV ();
pmvForward->computeMV ();
Int iSADDirect = 1000000000;
CVector vctRefScaled;
if (bColocatedMBExist && pmbmdRef->m_bhas4MVForward == FALSE &&
(m_volmd.volType != ENHN_LAYER || ( m_vopmd.iRefSelectCode != 1 && m_vopmd.iRefSelectCode != 2))) {
Int iPartInterval = m_t - m_tPastRef; //initialize at MVDB = 0
vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval;
Int iFullInterval = m_tFutureRef - m_tPastRef;
vctRefScaled.x /= iFullInterval; //truncation as per vm
vctRefScaled.y /= iFullInterval; //truncation as per vm
//set up initial forward vector;
rgmvDirectForward->iMVX = vctRefScaled.x / 2;
rgmvDirectForward->iMVY = vctRefScaled.y / 2;
rgmvDirectForward->iHalfX = 0;
rgmvDirectForward->iHalfY = 0;
rgmvDirectForward->computeTrueMV ();
rgmvDirectForward->computeMV ();
//set up initial backward vector
pmbmd->m_vctDirectDeltaMV = rgmvDirectForward->m_vctTrueHalfPel - vctRefScaled; //mvdb not necessaryly 0 due to truncation of half pel
backwardMVFromForwardMV (rgmvDirectBack [0], rgmvDirectForward [0], *pmvRef, pmbmd->m_vctDirectDeltaMV);
//compute initial sad
iSADDirect = interpolateAndDiffY_WithShape (rgmvDirectForward, rgmvDirectBack, x, y,
&m_rctRefVOPY0, &m_rctRefVOPY1) - FAVORZERO;;
//set up inital position in ref frame
Int iXInit = x + rgmvDirectForward->iMVX;
Int iYInit = y + rgmvDirectForward->iMVY;
const PixelC* ppxlcInitRefMBY = m_pvopcRefQ0->pixelsY () + m_rctRefFrameY.offset (iXInit, iYInit);
//compute forward mv and sad; to be continue in iSADMin==iSADDirect
Int isave = m_iMVFileUsage; // 04/28/99 david ruhoff
if (!m_volmd.bOriginalForME) m_iMVFileUsage = 0; // 04/28/99 must not use mv file based on reconstructed vop
iSADDirect = blkmatch16WithShape (rgmvDirectForward, iXInit, iYInit, x, y, iSADDirect, ppxlcInitRefMBY,
m_puciRefQZoom0, pmbmd, m_vopmd.iDirectModeRadius, m_volmd.bQuarterSample,0) - FAVOR_DIRECT;
m_iMVFileUsage = isave; // 04/28/99
rgmvDirectForward->computeTrueMV ();
rgmvDirectForward->computeMV ();
pmbmd->m_vctDirectDeltaMV = rgmvDirectForward->m_vctTrueHalfPel - vctRefScaled;
backwardMVFromForwardMV (rgmvDirectBack [0], rgmvDirectForward [0], *pmvRef,
pmbmd->m_vctDirectDeltaMV);
iSADDirect = interpolateAndDiffY (rgmvDirectForward, rgmvDirectBack, x, y,
&m_rctRefVOPY0, &m_rctRefVOPY1);
// GMC
if(pmbmdRef->m_bMCSEL)
iSADDirect -= FAVORZERO;
else
// ~GMC
if (pmbmd->m_vctDirectDeltaMV.x == 0 && pmbmd->m_vctDirectDeltaMV.y == 0)
iSADDirect -= FAVORZERO;
}
iInitSAD = sad16x16At0WithShape (ppxlcRef1MBY, pmbmd);//shouldn't favor 0 mv inside this function
Int iSADBackward = blkmatch16WithShape (pmvBackward, x, y, x, y, iInitSAD, ppxlcRef1MBY,
m_puciRefQZoom1, pmbmd, m_vopmd.iSearchRangeBackward, m_volmd.bQuarterSample,1);
pmvBackward->computeTrueMV ();
pmvBackward->computeMV ();
Int iSADInterpolate = interpolateAndDiffY_WithShape (
pmvForward, pmvBackward,
x, y, &m_rctRefVOPY0, &m_rctRefVOPY1
);
Int iSADMin = minimum (iSADDirect, iSADForward, iSADBackward, iSADInterpolate);
Int iBlk;
if(m_bCodedFutureRef==FALSE)
iSADMin = iSADForward; // force forward mode
if (iSADMin == iSADDirect) {
pmbmd->m_mbType = DIRECT;
//compute backward mv
pmvForward [0] = rgmvDirectForward [0];
pmvBackward [0] = rgmvDirectBack [0];
for (iBlk = 1; iBlk <= 4; iBlk++) {
pmvForward [iBlk] = pmvForward [0];
pmvBackward [iBlk] = pmvBackward [0];
}
}
else if (iSADMin == iSADForward) {
pmbmd->m_mbType = FORWARD;
for (iBlk = 1; iBlk <= 4; iBlk++)
pmvForward [iBlk] = pmvForward [0];
}
else if (iSADMin == iSADBackward) {
pmbmd->m_mbType = BACKWARD;
for (iBlk = 1; iBlk <= 4; iBlk++)
pmvBackward [iBlk] = pmvBackward [0];
}
else {
pmbmd->m_mbType = INTERPOLATE;
for (iBlk = 1; iBlk <= 4; iBlk++) {
pmvForward [iBlk] = pmvForward [0];
pmvBackward [iBlk] = pmvBackward [0];
}
}
return iSADMin;
}
//OBSS_SAIT_991015
Int CVideoObjectEncoder::motionEstMB_BVOP_WithShape (
CoordI x, CoordI y, CMotionVector* pmvForward, CMotionVector* pmvBackward,
CMBMode* pmbmd, const PixelC* ppxlcRef0MBY, const PixelC* ppxlcRef1MBY
)
{
Int numForePixel=0;Bool BackwardSkipped = FALSE;
assert (pmbmd->m_rgTranspStatus [0] == PARTIAL);
Int iInitSAD = sad16x16At0WithShape (ppxlcRef0MBY, pmbmd); //shouldn't favor 0 mv inside this function
Int iSADForward = blkmatch16WithShape (pmvForward, x, y, x, y, iInitSAD, ppxlcRef0MBY,
m_puciRefQZoom0, pmbmd, m_vopmd.iSearchRangeForward,m_volmd.bQuarterSample,0);
pmvForward->computeTrueMV ();
Int iSADDirect = 1000000000;
iInitSAD = sad16x16At0WithShape (ppxlcRef1MBY, pmbmd, &numForePixel);
Int iSADBackward = iInitSAD;
*pmvBackward = CMotionVector( 0, 0 );
pmvBackward->computeTrueMV ();
BackwardSkipped = quantizeTextureMBBackwardCheck (pmbmd, m_ppxlcCurrMBY, m_ppxlcCurrMBBY, ppxlcRef1MBY);
Int iSADInterpolate = interpolateAndDiffY_WithShape(pmvForward, pmvBackward, x, y,
&m_rctRefVOPY0, &m_rctRefVOPY1);
Int iSADMin = 0;
if(BackwardSkipped)
iSADMin = iSADBackward;
else {
if(iSADForward <= iSADBackward && iSADForward <= iSADInterpolate)
iSADMin = iSADForward;
else if (iSADBackward <= iSADInterpolate)
iSADMin = iSADBackward;
else
iSADMin = iSADInterpolate;
}
Int iBlk;
if (iSADMin == iSADForward) {
pmbmd->m_mbType = FORWARD;
for (iBlk = 1; iBlk <= 4; iBlk++)
pmvForward [iBlk] = pmvForward [0];
}
else if (iSADMin == iSADBackward) {
pmbmd->m_mbType = BACKWARD;
for (iBlk = 1; iBlk <= 4; iBlk++)
pmvBackward [iBlk] = pmvBackward [0];
}
else {
pmbmd->m_mbType = INTERPOLATE;
for (iBlk = 1; iBlk <= 4; iBlk++) {
pmvForward [iBlk] = pmvForward [0];
pmvBackward [iBlk] = pmvBackward [0];
}
}
return iSADMin;
}
//~OBSS_SAIT_991015
// INTERLACE
#define BbiasAgainstFrameAve ((MB_SIZE*MB_SIZE)/2 + 1) // Biases favor modes with fewer MVs
#define BbiasAgainstFieldAve ((MB_SIZE*MB_SIZE)/1 + 1)
#define BbiasAgainstField ((MB_SIZE*MB_SIZE)/2 + 1)
#define BbiasFavorDirect ((MB_SIZE*MB_SIZE)/2 + 1)
Int CVideoObjectEncoder::motionEstMB_BVOP_Interlaced (
CoordI x, CoordI y,
CMotionVector* pmvForward, CMotionVector* pmvBackward,
CMBMode* pmbmd,
const CMBMode* pmbmdRef, const CMotionVector* pmvRef,
const PixelC* ppxlcRef0MBY, const PixelC* ppxlcRef1MBY,
Bool bColocatedMBExist
)
{
Int iSAD, iSADnobias, iFieldSAD, iSADFrmMB[3];
MBType mbtype;
iSADFrmMB[0] = blkmatch16(pmvForward, x, y,x,y, sad16x16At0 (ppxlcRef0MBY),
ppxlcRef0MBY, m_puciRefQZoom0, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmvForward->computeTrueMV ();
pmvForward->computeMV ();
iSADFrmMB[1] = blkmatch16(pmvBackward, x, y,x,y, sad16x16At0 (ppxlcRef1MBY),
ppxlcRef1MBY, m_puciRefQZoom1, m_vopmd.iSearchRangeBackward, m_volmd.bQuarterSample);
pmvBackward->computeTrueMV ();
pmvBackward->computeMV ();
iSADFrmMB[2] = interpolateAndDiffY(pmvForward, pmvBackward, x, y
, &m_rctRefVOPY0, &m_rctRefVOPY1);
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iSADFrmMB, 3, "SADFrmMB");
#endif // __TRACE_AND_STATS_
// Choose best 16x16 mode
pmbmd->m_bFieldMV = FALSE;
if (iSADFrmMB[0] < iSADFrmMB[1]) {
iSAD = iSADFrmMB[0];
pmbmd->m_mbType = FORWARD;
} else {
iSAD = iSADFrmMB[1];
pmbmd->m_mbType = BACKWARD;
}
iSADnobias = iSAD;
if ((iSADFrmMB[2] + BbiasAgainstFrameAve) < iSAD) {
iSAD = iSADFrmMB[2] + BbiasAgainstFrameAve;
iSADnobias = iSADFrmMB[2];
pmbmd->m_mbType = INTERPOLATE;
}
if(m_bCodedFutureRef==FALSE)
{
iSAD = iSADFrmMB[0];
pmbmd->m_mbType = FORWARD; // force forward mode
}
if (m_vopmd.bInterlace) {
const PixelC *ppxlcFwdHalfPelRef = m_pvopcRefQ0->pixelsY()
+EXPANDY_REF_FRAME * m_iFrameWidthY + EXPANDY_REF_FRAME+ x + y * m_iFrameWidthY; // 1.31.99 changes
const PixelC *ppxlcBakHalfPelRef = m_pvopcRefQ1->pixelsY()
+EXPANDY_REF_FRAME * m_iFrameWidthY + EXPANDY_REF_FRAME+ x + y * m_iFrameWidthY; // 1.31.99 changes
Int iSADFldMB[3], iSADFld[8];
// Choose best fwd top field predictor // ppxlc???HalfPelRef is not zoomed [interpolation within blkmatch??()]
iSADFld[0] = blkmatch16x8 (pmvForward+1, x, y, 0,
ppxlcRef0MBY, ppxlcFwdHalfPelRef, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmvForward[1].computeTrueMV();
pmvForward[1].computeMV();
iSADFld[1] = blkmatch16x8 (pmvForward+2, x, y, 0,
ppxlcRef0MBY + m_iFrameWidthY, ppxlcFwdHalfPelRef + m_iFrameWidthY,
m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmvForward[2].computeTrueMV();
pmvForward[2].computeMV();
if (iSADFld[0] <= iSADFld[1]) {
pmbmd->m_bForwardTop = 0;
iSADFldMB[0] = iSADFld[0];
} else {
pmbmd->m_bForwardTop = 1;
iSADFldMB[0] = iSADFld[1];
}
// Choose best fwd botton field predictor
iSADFld[2] = blkmatch16x8 (pmvForward+3, x, y, MB_SIZE,
ppxlcRef0MBY, ppxlcFwdHalfPelRef, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmvForward[3].computeTrueMV();
pmvForward[3].computeMV();
iSADFld[3] = blkmatch16x8 (pmvForward+4, x, y, MB_SIZE,
ppxlcRef0MBY + m_iFrameWidthY, ppxlcFwdHalfPelRef + m_iFrameWidthY,
m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmvForward[4].computeTrueMV();
pmvForward[4].computeMV();
if (iSADFld[2] < iSADFld[3]) {
pmbmd->m_bForwardBottom = 0;
iSADFldMB[0] += iSADFld[2];
} else {
pmbmd->m_bForwardBottom = 1;
iSADFldMB[0] += iSADFld[3];
}
// Choose best bak top field predictor
iSADFld[4] = blkmatch16x8 (pmvBackward+1, x, y, 0,
ppxlcRef1MBY, ppxlcBakHalfPelRef, m_vopmd.iSearchRangeBackward, m_volmd.bQuarterSample);
pmvBackward[1].computeTrueMV();
pmvBackward[1].computeMV();
iSADFld[5] = blkmatch16x8 (pmvBackward+2, x, y, 0,
ppxlcRef1MBY + m_iFrameWidthY, ppxlcBakHalfPelRef + m_iFrameWidthY,
m_vopmd.iSearchRangeBackward, m_volmd.bQuarterSample);
pmvBackward[2].computeTrueMV();
pmvBackward[2].computeMV();
if (iSADFld[4] <= iSADFld[5]) {
pmbmd->m_bBackwardTop = 0;
iSADFldMB[1] = iSADFld[4];
} else {
pmbmd->m_bBackwardTop = 1;
iSADFldMB[1] = iSADFld[5];
}
// Choose best bak bottom field predictor
iSADFld[6] = blkmatch16x8 (pmvBackward+3, x, y, MB_SIZE,
ppxlcRef1MBY, ppxlcBakHalfPelRef, m_vopmd.iSearchRangeBackward, m_volmd.bQuarterSample);
pmvBackward[3].computeTrueMV();
pmvBackward[3].computeMV();
iSADFld[7] = blkmatch16x8 (pmvBackward+4, x, y, MB_SIZE,
ppxlcRef1MBY + m_iFrameWidthY, ppxlcBakHalfPelRef + m_iFrameWidthY,
m_vopmd.iSearchRangeBackward, m_volmd.bQuarterSample);
pmvBackward[4].computeTrueMV();
pmvBackward[4].computeMV();
if (iSADFld[6] < iSADFld[7]) {
pmbmd->m_bBackwardBottom = 0;
iSADFldMB[1] += iSADFld[6];
} else {
pmbmd->m_bBackwardBottom = 1;
iSADFldMB[1] += iSADFld[7];
}
// Choose best of forward & backward field prediction
if (iSADFldMB[0] <= iSADFldMB[1]) {
iFieldSAD = iSADFldMB[0];
mbtype = FORWARD;
} else {
iFieldSAD = iSADFldMB[1];
mbtype = BACKWARD;
}
iFieldSAD += BbiasAgainstField;
iSADFldMB[2] = interpolateAndDiffYField(
pmvForward + 1 + (int)pmbmd->m_bForwardTop,
pmvForward + 3 + (int)pmbmd->m_bForwardBottom,
pmvBackward + 1 + (int)pmbmd->m_bBackwardTop,
pmvBackward + 3 + (int)pmbmd->m_bBackwardBottom,
x, y, pmbmd);
if ((iSADFldMB[2] + BbiasAgainstFieldAve) < iFieldSAD) {
iFieldSAD = iSADFldMB[2] + BbiasAgainstFieldAve;
mbtype = INTERPOLATE;
}
if(m_bCodedFutureRef==FALSE) // FORCE FORWARD
{
iFieldSAD = iSADFldMB[0];
mbtype = FORWARD;
}
// Field versus Frame prediction
if (iFieldSAD < iSAD) {
pmbmd->m_bFieldMV = TRUE;
pmbmd->m_mbType = mbtype;
iSAD = iFieldSAD;
iSADnobias = iFieldSAD - ((mbtype == INTERPOLATE) ? BbiasAgainstFieldAve : BbiasAgainstField);
}
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iSADFld, 8, "SADFld");
m_pbitstrmOut->trace (iSADFldMB, 3, "SADFldMB");
#endif // __TRACE_AND_STATS_
}
#if 1 // #if 0 to temporarily disable direct mode (debug only)
// Check direct mode
Int iSADDirect;
if (m_volmd.fAUsage == RECTANGLE) {
iSADDirect= (pmbmdRef->m_bFieldMV && !pmbmdRef->m_bMCSEL) ? // GMC
directSADField(x, y, pmbmd, pmbmdRef, pmvRef, ppxlcRef0MBY, ppxlcRef1MBY) :
directSAD (x, y, pmbmd, pmbmdRef, pmvRef);
if ((iSADDirect - BbiasFavorDirect) < iSAD) {
pmbmd->m_mbType = DIRECT;
pmbmd->m_bFieldMV = pmbmdRef->m_bFieldMV;
iSADnobias = iSADDirect;
}
}
#endif
#ifdef __TRACE_AND_STATS_
static char *cDirectType[] = { "FrmDirectSAD", "FldDirectSAD" };
static char *cWinner[] = { "FrmDirect\n", "FrmAve\n", "FrmBak\n", "FrmFwd\n", "FldDirect\n", "FldAve\n", "FldBak\n", "FldFwd\n" };
if(bColocatedMBExist)
m_pbitstrmOut->trace (iSADDirect, cDirectType[pmbmdRef->m_bFieldMV]);
m_pbitstrmOut->trace (cWinner[(Int)pmbmd->m_mbType + 4*pmbmd->m_bFieldMV]);
#if 0 // Put all MV candidates in trace file
Int iMV[10];
iMV[0] = pmvForward[0].m_vctTrueHalfPel.x; iMV[1] = pmvForward[0].m_vctTrueHalfPel.y;
iMV[2] = pmvForward[1].m_vctTrueHalfPel.x; iMV[3] = pmvForward[1].m_vctTrueHalfPel.y;
iMV[4] = pmvForward[2].m_vctTrueHalfPel.x; iMV[5] = pmvForward[2].m_vctTrueHalfPel.y;
iMV[6] = pmvForward[3].m_vctTrueHalfPel.x; iMV[7] = pmvForward[3].m_vctTrueHal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -