📄 mvdec.cpp
字号:
} else {
end of new changes 02-19-99 */
// begin of new changes 02-19-99
if (m_vopmd.bInterlace) {
if (!pmbmd->m_bSkip) {
getDiffMV (pmbmd->m_vctDirectDeltaMV, directInfo);
vctDiff.x = pmbmd->m_vctDirectDeltaMV.x;
vctDiff.y = pmbmd->m_vctDirectDeltaMV.y;
}
else
vctDiff.x = vctDiff.y = 0;
}
else {
//end of new changes 02-19-99
if (pmbmd->m_bSkip)
vctDiff.x = vctDiff.y = 0;
else {
Long lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
vctDiff.x = deScaleMV (lSymbol - 32, 0, 1);
lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
vctDiff.y = deScaleMV (lSymbol - 32, 0, 1);
}
} // new change 02-19-99
computeDirectForwardMV (vctDiff, pmvForward, pmvRef, pmbmdRef); //compute forward mv from diff
if(pmbmdRef==NULL)
{
// transparent reference macroblock
pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = FALSE;
CMotionVector mvRef; // zero motion vector
backwardMVFromForwardMV (*pmvBackward, *pmvForward, mvRef, vctDiff);
}
else
{
pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = pmbmdRef->m_bhas4MVForward; //reset 4mv mode
if (pmbmd->m_bhas4MVBackward) {
for (Int i = 0; i < 4; i++) {
pmvForward++;
pmvBackward++;
pmvRef++;
backwardMVFromForwardMV (*pmvBackward, *pmvForward, *pmvRef,
vctDiff); //compute back mv from forward mv and ref mv for direct mode
}
}
else
backwardMVFromForwardMV (*pmvBackward, *pmvForward, *pmvRef,
vctDiff); //compute back mv from forward mv and ref mv for direct mode
}
// } new change 02-19-99
}
}
Void CVideoObjectDecoder::computeDirectForwardMV (CVector vctDiff, CMotionVector* pmv,
const CMotionVector* pmvRef,
const CMBMode* pmbmdRef)
{
if(pmvRef==NULL)
{
// colocated macroblock is transparent, use zero reference MV
*pmv++ = CMotionVector (vctDiff); //convert to full pel now
for (Int i = 0; i < 4; i++) {
*pmv = *(pmv - 1);
pmv++;
}
}
else
{
Int iPartInterval = m_t - m_tPastRef;
Int iFullInterval = m_tFutureRef - m_tPastRef;
if (pmbmdRef->m_bhas4MVForward == FALSE) {
CVector vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval;
vctRefScaled.x /= iFullInterval; //truncation as per vm
vctRefScaled.y /= iFullInterval; //truncation as per vm
CVector vctDecode = vctDiff + vctRefScaled;
*pmv++ = CMotionVector (vctDecode); //convert to full pel now
for (Int i = 0; i < 4; i++) {
*pmv = *(pmv - 1);
pmv++;
}
}
else {
for (Int i = 0; i < 4; i++) {
pmv++;
pmvRef++;
CVector vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval;
vctRefScaled.x /= iFullInterval; //truncation as per vm
vctRefScaled.y /= iFullInterval; //truncation as per vm
CVector vctDecode = vctDiff + vctRefScaled;
*pmv = CMotionVector (vctDecode); //convert to full pel now
}
}
}
}
Void CVideoObjectDecoder::decodeMVWithShape (const CMBMode* pmbmd, CoordI iMBX, CoordI iMBY, CMotionVector* pmv)
{
if (pmbmd->m_bSkip || pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
memset (pmv, 0, PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
return;
}
CVector vctDiff, vctDecode, vctPred;
if (pmbmd->m_bhas4MVForward) {
for (Int iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
if (pmbmd->m_rgTranspStatus [iBlk] == ALL)
pmv [iBlk] = CMotionVector (NOT_MV, NOT_MV);
else {
findMVpredGeneric (vctPred, pmv, pmbmd, iBlk, iMBX, iMBY);
getDiffMV (vctDiff, m_vopmd.mvInfoForward);
vctDecode = vctDiff + vctPred; //fit in range
fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
pmv [iBlk] = CMotionVector (vctDecode);
}
}
}
// INTERLACE
//new changes
else if ((m_vopmd.bInterlace)&&(pmbmd->m_bFieldMV)) {
Int iTempX1, iTempY1, iTempX2, iTempY2;
assert (pmbmd->m_rgTranspStatus [0] != ALL);
findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);
getDiffMV (vctDiff, m_vopmd.mvInfoForward);
vctDiff.y *= 2;
vctPred.y = 2*(vctPred.y / 2);
vctDecode = vctDiff + vctPred; //fit in range
fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
CMotionVector* pmv16x8 = pmv +5;
if(pmbmd->m_bForwardTop) {
pmv16x8++;
*pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
iTempX1 = pmv16x8->m_vctTrueHalfPel.x;
iTempY1 = pmv16x8->m_vctTrueHalfPel.y;
pmv16x8++;
}
else
{
*pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
iTempX1 = pmv16x8->m_vctTrueHalfPel.x;
iTempY1 = pmv16x8->m_vctTrueHalfPel.y;
pmv16x8++;
pmv16x8++;
}
getDiffMV (vctDiff, m_vopmd.mvInfoForward);
vctDiff.y *= 2;
vctPred.y = 2*(vctPred.y / 2);
vctDecode = vctDiff + vctPred; //fit in range
fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
if(pmbmd->m_bForwardBottom) {
pmv16x8++;
*pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
iTempX2 = pmv16x8->m_vctTrueHalfPel.x;
iTempY2 = pmv16x8->m_vctTrueHalfPel.y;
}
else
{
*pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
iTempX2 = pmv16x8->m_vctTrueHalfPel.x;
iTempY2 = pmv16x8->m_vctTrueHalfPel.y;
}
Int iTemp;
for (UInt i = 1; i < 5; i++) {
iTemp = iTempX1 + iTempX2;
pmv [i].m_vctTrueHalfPel.x = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);
iTemp = iTempY1 + iTempY2;
pmv [i].m_vctTrueHalfPel.y = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);
}
}
//end of new changes
// ~INTERLACE
else { //1 mv
assert (pmbmd->m_rgTranspStatus [0] != ALL);
findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);
getDiffMV (vctDiff, m_vopmd.mvInfoForward);
vctDecode = vctDiff + vctPred; //fit in range
fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
*pmv++ = CMotionVector (vctDecode);
for (Int i = 0; i < 4; i++) {
*pmv = *(pmv - 1);
pmv++;
}
}
}
Void CVideoObjectDecoder::getDiffMV (CVector& vctDiffMV, MVInfo mvinfo) //get half pel
{
Int iResidual;
Long lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
Int iVLC = lSymbol - 32;
if (iVLC != 0)
iResidual = m_pbitstrmIn->getBits (mvinfo.uiFCode - 1);
else
iResidual = 0;
vctDiffMV.x = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);
lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
iVLC = lSymbol - 32;
if (iVLC != 0)
iResidual = m_pbitstrmIn->getBits (mvinfo.uiFCode - 1);
else
iResidual = 0;
vctDiffMV.y = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);
}
Int CVideoObjectDecoder::deScaleMV (Int iVLC, Int iResidual, Int iScaleFactor)
{
if (iVLC == 0 && iResidual == 0)
return 0;
else if (iScaleFactor == 1)
return (iVLC);
else {
Int iAbsDiffMVcomponent = abs (iVLC) * iScaleFactor + iResidual - iScaleFactor + 1; //changed a'c to enc
return (sign (iVLC) * iAbsDiffMVcomponent);
}
}
Void CVideoObjectDecoder::fitMvInRange (CVector& vctSrc, MVInfo mvinfo)
{
Int iMvRange = mvinfo.uiRange; //in half pel unit
if (vctSrc.x < -1 * iMvRange) //* 2 to get length of [-range, range]
vctSrc.x += 2 * iMvRange;
else if (vctSrc.x >= iMvRange)
vctSrc.x -= 2 * iMvRange;
if (vctSrc.y < -1 * iMvRange)
vctSrc.y += 2 * iMvRange;
else if (vctSrc.y >= iMvRange)
vctSrc.y -= 2 * iMvRange;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -