📄 mcdec.cpp
字号:
/*************************************************************************
This software module was originally developed by
Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
(date: July, 1997)
in the course of development of the MPEG-4 Video (ISO/IEC 14496-2).
This software module is an implementation of a part of one or more MPEG-4 Video tools
as specified by the MPEG-4 Video.
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video.
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents.
The original developer of this software module and his/her company,
the subsequent editors and their companies,
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation.
Copyright is not released for non MPEG-4 Video conforming products.
Microsoft retains full right to use the code for his/her own purpose,
assign or donate the code to a third party and to inhibit third parties from using the code for non MPEG-4 Video conforming products.
This copyright notice must be included in all copies or derivative works.
Copyright (c) 1996, 1997.
Module Name:
mcdec.cpp
Abstract:
motion compensation for decoder
Revision History:
Dec 20, 1997: Interlaced tools added by NextLevel Systems (GI)
B. Eifrig (beifrig@nlvl.com) X. Chen (xchen@nlvl.com)
*************************************************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "typeapi.h"
#include "mode.hpp"
#include "codehead.h"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "global.hpp"
#include "vopses.hpp"
#include "vopsedec.hpp"
#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#endif // __MFC_
const Int rgiBlkOffsetX [] = {0, BLOCK_SIZE, 0, BLOCK_SIZE};
const Int rgiBlkOffsetY [] = {0, 0, BLOCK_SIZE, BLOCK_SIZE};
const Int rgiBlkOffsetPixel [] = {0, OFFSET_BLK1, OFFSET_BLK2, OFFSET_BLK3};
Void CVideoObjectDecoder::motionCompAndAddErrorMB_BVOP (
const CMotionVector* pmvForward, const CMotionVector* pmvBackward,
CMBMode* pmbmd,
Int iMBX, Int iMBY,
CoordI x, CoordI y,
PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV,
CRct *prctMVLimitForward,CRct *prctMVLimitBackward
)
{
Int iBlk;
// INTERLACE
// new chnages
if (m_vopmd.bInterlace) { // Should not depend on .bInterlace; this code should work the progressive
switch (pmbmd->m_mbType) {
case FORWARD:
motionCompOneBVOPReference(m_pvopcPredMB, FORWARD, x, y, pmbmd, pmvForward, prctMVLimitForward);
addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
break;
case BACKWARD:
motionCompOneBVOPReference(m_pvopcPredMB, BACKWARD, x, y, pmbmd, pmvBackward, prctMVLimitBackward);
addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
break;
case DIRECT:
Int iOffset;
if(m_volmd.fAUsage != RECTANGLE)
iOffset = (min (max (0, iMBX), m_iNumMBXRef - 1) +
min (max (0, iMBY), m_iNumMBYRef - 1) * m_iNumMBXRef) * PVOP_MV_PER_REF_PER_MB;
else
iOffset=PVOP_MV_PER_REF_PER_MB*(iMBX + iMBY*m_iNumMBX);
motionCompDirectMode(x, y, pmbmd, &m_rgmvRef[iOffset],
prctMVLimitForward, prctMVLimitBackward, 0);
averagePredAndAddErrorToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
break;
case INTERPOLATE:
motionCompOneBVOPReference(m_pvopcPredMB, FORWARD, x, y, pmbmd, pmvForward, prctMVLimitForward);
motionCompOneBVOPReference(m_pvopcPredMBBack, BACKWARD, x, y, pmbmd, pmvBackward, prctMVLimitBackward);
averagePredAndAddErrorToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
break;
}
return;
}
// ~INTERLACE
if (pmbmd->m_mbType == DIRECT || pmbmd->m_mbType == INTERPOLATE) {
if (pmbmd->m_bhas4MVForward != TRUE)
motionComp (
m_ppxlcPredMBY,
m_pvopcRefQ0->pixelsY (),
MB_SIZE, // either MB or BLOCK size
x * 2 + pmvForward->trueMVHalfPel ().x,
y * 2 + pmvForward->trueMVHalfPel ().y,
m_vopmd.iRoundingControl,
prctMVLimitForward
);
else {
const CMotionVector* pmv8 = pmvForward;
for (iBlk = 0; iBlk < 4; iBlk++) {
pmv8++;
if (pmbmd->m_rgTranspStatus [iBlk + 1] != ALL)
motionComp (
m_ppxlcPredMBY + rgiBlkOffsetPixel [iBlk],
m_pvopcRefQ0->pixelsY (),
BLOCK_SIZE,
(x + rgiBlkOffsetX [iBlk]) * 2 + pmv8->trueMVHalfPel ().x,
(y + rgiBlkOffsetY [iBlk]) * 2 + pmv8->trueMVHalfPel ().y,
m_vopmd.iRoundingControl,
prctMVLimitForward
);
}
}
CoordI xRefUVForward, yRefUVForward;
mvLookupUVWithShape (pmbmd, pmvForward, xRefUVForward, yRefUVForward);
motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUVForward, yRefUVForward, 0, prctMVLimitForward);
if (pmbmd->m_bhas4MVBackward != TRUE)
motionComp (
m_ppxlcPredMBBackY,
m_pvopcRefQ1->pixelsY (),
MB_SIZE, // either MB or BLOCK size
x * 2 + pmvBackward->trueMVHalfPel ().x,
y * 2 + pmvBackward->trueMVHalfPel ().y,
m_vopmd.iRoundingControl,
prctMVLimitBackward
);
else {
const CMotionVector* pmv8 = pmvBackward;
for (iBlk = 0; iBlk < 4; iBlk++) {
pmv8++;
if (pmbmd->m_rgTranspStatus [iBlk + 1] != ALL)
motionComp (
m_ppxlcPredMBBackY + rgiBlkOffsetPixel [iBlk],
m_pvopcRefQ1->pixelsY (),
BLOCK_SIZE,
(x + rgiBlkOffsetX [iBlk]) * 2 + pmv8->trueMVHalfPel ().x,
(y + rgiBlkOffsetY [iBlk]) * 2 + pmv8->trueMVHalfPel ().y,
m_vopmd.iRoundingControl,
prctMVLimitBackward
);
}
}
CoordI xRefUVBackward, yRefUVBackward;
mvLookupUVWithShape (pmbmd, pmvBackward, xRefUVBackward, yRefUVBackward);
motionCompUV (m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y, xRefUVBackward, yRefUVBackward, 0, prctMVLimitBackward);
averagePredAndAddErrorToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
}
else {
const CMotionVector* pmv;
const PixelC* ppxlcRef; // point to left-top of the reference VOP
const CVOPU8YUVBA* pvopcRef;
CRct *prctMVLimit;
if (pmbmd->m_mbType == FORWARD) { // Y is done when doing motion estimation
pmv = pmvForward;
ppxlcRef = m_pvopcRefQ0->pixelsY (); // point to left-top of the reference VOP
pvopcRef = m_pvopcRefQ0;
prctMVLimit = prctMVLimitForward;
}
else {
pmv = pmvBackward;
ppxlcRef = m_pvopcRefQ1->pixelsY (); // point to left-top of the reference VOP
pvopcRef = m_pvopcRefQ1;
prctMVLimit = prctMVLimitBackward;
}
motionComp (
m_ppxlcPredMBY,
ppxlcRef,
MB_SIZE, // either MB or BLOCK size
x * 2 + pmv->trueMVHalfPel ().x,
y * 2 + pmv->trueMVHalfPel ().y,
m_vopmd.iRoundingControl,
prctMVLimit
);
CoordI xRefUV, yRefUV;
mvLookupUVWithShape (pmbmd, pmv, xRefUV, yRefUV);
motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, pvopcRef, x, y, xRefUV, yRefUV, 0, prctMVLimit);
addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
}
}
Void CVideoObjectDecoder::motionCompAlphaMB_BVOP(
const CMotionVector* pmvForward, const CMotionVector* pmvBackward,
CMBMode* pmbmd,
Int iMBX, Int iMBY,
CoordI x, CoordI y,
PixelC* ppxlcCurrQMBA,
CRct *prctMVLimitForward,CRct *prctMVLimitBackward)
{
Int iBlk;
if (pmbmd->m_mbType == DIRECT || pmbmd->m_mbType == INTERPOLATE) {
if (!pmbmd->m_bhas4MVForward && !pmbmd -> m_bFieldMV) //12.22.98
motionComp (
m_ppxlcPredMBA,
m_pvopcRefQ0->pixelsA (),
MB_SIZE, // either MB or BLOCK size
x * 2 + pmvForward->trueMVHalfPel ().x,
y * 2 + pmvForward->trueMVHalfPel ().y,
0,
prctMVLimitForward
);
// INTERLACE 12.22.98 with new change 02-19-99
else if ((pmbmd -> m_bFieldMV) && (pmbmd->m_mbType == INTERPOLATE)) {
const CMotionVector* pmvTop = pmvForward + 1 + pmbmd->m_bForwardTop;
motionCompYField(m_ppxlcPredMBA,
m_pvopcRefQ0->pixelsA () + pmbmd->m_bForwardTop * m_iFrameWidthY,
2*x + pmvTop->trueMVHalfPel ().x, 2*y + pmvTop->trueMVHalfPel ().y);
const CMotionVector* pmvBottom = pmvForward + 3 + pmbmd->m_bForwardBottom;
motionCompYField(m_ppxlcPredMBA + MB_SIZE,
m_pvopcRefQ0->pixelsA () + pmbmd->m_bForwardBottom * m_iFrameWidthY,
2*x + pmvBottom->trueMVHalfPel ().x, 2*y + pmvBottom->trueMVHalfPel ().y);
}
// ~INTERLACE 12.22.98 with new change 02-19-99
// INTERLACE 02-19-99
else if ((pmbmd -> m_bFieldMV) && (pmbmd->m_mbType == DIRECT)) {
Int iOffset = (min (max (0,iMBX), m_iNumMBXRef - 1) +
min (max (0, iMBY), m_iNumMBYRef - 1) * m_iNumMBXRef) * PVOP_MV_PER_REF_PER_MB;
motionCompDirectMode(x, y, pmbmd, &m_rgmvRef[iOffset],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -