📄 motest.cpp
字号:
pmvRef = m_rgmvRef;
}
CMotionVector* pmv = m_rgmv;
CMotionVector* pmvBackward = m_rgmvBackward;
const PixelC* ppxlcOrigY = m_pvopcOrig->pixelsBoundY ();
const PixelC* ppxlcRef0Y = m_pvopcRefQ0->pixelsY () + m_iStartInRefToCurrRctY;
const PixelC* ppxlcRef1Y = m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
Int iMBX, iMBY;
for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) {
const PixelC* ppxlcOrigMBY = ppxlcOrigY;
const PixelC* ppxlcRef0MBY = ppxlcRef0Y;
const PixelC* ppxlcRef1MBY = ppxlcRef1Y;
CoordI x = 0; // frame-based, always start from 0
for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {
pmbmd->m_dctMd = INTER; // B-VOP is always INTER
pmbmd->m_bhas4MVForward = pmbmd->m_bhas4MVBackward = FALSE; //out encoder doesn't support 4 mv in bvop (not even direct mode)
// GMC
pmbmd->m_bMCSEL = FALSE;
// ~GMC
// TPS FIX
if(m_volmd.volType == ENHN_LAYER && (m_vopmd.iRefSelectCode != 3 || m_volmd.iEnhnType == 1)){
pmbmd->m_bColocatedMBSkip= FALSE;
copyToCurrBuffY(ppxlcOrigMBY);
// begin: modified by Sharp(98/3/10)
if ( m_vopmd.iRefSelectCode == 0 )
motionEstMB_BVOP (x, y, pmv, pmvBackward, pmbmd, ppxlcRef0MBY, ppxlcRef1MBY);
else
motionEstMB_BVOP (x, y, pmv, pmvBackward, pmbmd, pmbmdRef, pmvRef, ppxlcRef0MBY, ppxlcRef1MBY, TRUE);
// end: modified by Sharp(98/3/10)
}
else {
// GMC
pmbmd->m_bColocatedMBMCSEL = (pmbmdRef!=NULL) ? pmbmdRef->m_bMCSEL : FALSE;
if(pmbmd->m_bColocatedMBMCSEL)
pmbmd->m_bColocatedMBSkip = FALSE;
else
// ~GMC
pmbmd->m_bColocatedMBSkip = (pmbmdRef!=NULL) ? pmbmdRef->m_bSkip : FALSE;
if (pmbmd->m_bColocatedMBSkip) {
pmbmd->m_bSkip = TRUE;
memset (pmv, 0, BVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
pmbmd->m_mbType = FORWARD; // can be set to FORWARD mode since the result is the same
}
else {
// GMC
pmbmd->m_bSkip = FALSE;
// ~GMC
copyToCurrBuffY (ppxlcOrigMBY);
m_iMAD += m_vopmd.bInterlace ?
motionEstMB_BVOP_Interlaced (x, y, pmv, pmvBackward, pmbmd,
pmbmdRef, pmvRef, ppxlcRef0MBY, ppxlcRef1MBY, pmbmdRef!=NULL) :
motionEstMB_BVOP (x, y, pmv, pmvBackward, pmbmd,
pmbmdRef, pmvRef, ppxlcRef0MBY, ppxlcRef1MBY, pmbmdRef!=NULL);
}
}
pmbmd++;
pmv += BVOP_MV_PER_REF_PER_MB;
pmvBackward += BVOP_MV_PER_REF_PER_MB;
if(m_bCodedFutureRef!=FALSE)
{
pmbmdRef++;
pmvRef += PVOP_MV_PER_REF_PER_MB;
}
ppxlcOrigMBY += MB_SIZE;
ppxlcRef0MBY += MB_SIZE;
ppxlcRef1MBY += MB_SIZE;
}
ppxlcOrigY += m_iFrameWidthYxMBSize;
ppxlcRef0Y += m_iFrameWidthYxMBSize;
ppxlcRef1Y += m_iFrameWidthYxMBSize;
}
if (m_iMVFileUsage == 2)
writeBVOPMVs();
}
Void CVideoObjectEncoder::motionEstBVOP_WithShape ()
{
m_iMAD = 0;
CoordI y = m_rctCurrVOPY.top;
CMBMode* pmbmd = m_rgmbmd;
CMotionVector* pmv = m_rgmv;
CMotionVector* pmvBackward = m_rgmvBackward;
Bool bColocatedMBExist;
const PixelC* ppxlcOrigY = m_pvopcOrig->pixelsBoundY ();
const PixelC* ppxlcOrigBY = m_pvopcOrig->pixelsBoundBY ();
//OBSS_SAIT_991015 //_SONY_SS_
//Here, shuld be better to use reconstructed image insted of original image.
// This is same as rectanguler case. See motionEstBVOP .
// Maybe, Motion Estimation using Original Picture cannot be used for all BVOP (not only scalable) in microsoft.
const PixelC* ppxlcRef0Y = m_pvopcRefQ0->pixelsY () + m_iStartInRefToCurrRctY;
const PixelC* ppxlcRef1Y = m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
//~OBSS_SAIT_991015
Int iMBX, iMBY;
if (m_iMVFileUsage == 1)
readBVOPMVs(); //读取VOP的运动向量
for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) {
const PixelC* ppxlcOrigMBY = ppxlcOrigY;
const PixelC* ppxlcOrigMBBY = ppxlcOrigBY;
const PixelC* ppxlcRef0MBY = ppxlcRef0Y;
const PixelC* ppxlcRef1MBY = ppxlcRef1Y;
CoordI x = m_rctCurrVOPY.left;
for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {
pmbmd->m_dctMd = INTER; // B-VOP is always INTER
pmbmd->m_bhas4MVForward = pmbmd->m_bhas4MVBackward = FALSE;
// GMC
pmbmd->m_bMCSEL = FALSE;
// ~GMC
//获取VOP中象素的亮度分量
copyToCurrBuffWithShapeY (ppxlcOrigMBY, ppxlcOrigMBBY);
//VOP中的象素是否透明
decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY);
if (pmbmd->m_rgTranspStatus [0] != ALL) {
const CMBMode* pmbmdRef;
const CMotionVector* pmvRef;
findColocatedMB (iMBX, iMBY, pmbmdRef, pmvRef);
// GMC
pmbmd->m_bColocatedMBMCSEL = (pmbmdRef!=NULL && pmbmdRef->m_bMCSEL);
if(pmbmd->m_bColocatedMBMCSEL)
pmbmd->m_bColocatedMBSkip = FALSE;
else
// ~GMC
pmbmd->m_bColocatedMBSkip = (pmbmdRef!=NULL && pmbmdRef->m_bSkip);
// TPS FIX
if(m_volmd.volType == ENHN_LAYER && (m_vopmd.iRefSelectCode != 3 || m_volmd.iEnhnType == 1)) {
pmbmd->m_bColocatedMBSkip= FALSE;
bColocatedMBExist = (pmbmdRef!=NULL);
//OBSS_SAIT_991015
if (m_vopmd.iRefSelectCode == 0) {
if (pmbmd->m_rgTranspStatus [0] == NONE)
m_iMAD += motionEstMB_BVOP (
x, y, pmv, pmvBackward, pmbmd, ppxlcRef0MBY, ppxlcRef1MBY);
else if (pmbmd->m_rgTranspStatus [0] == PARTIAL) {
m_iMAD += motionEstMB_BVOP_WithShape (
x, y, pmv, pmvBackward, pmbmd, ppxlcRef0MBY, ppxlcRef1MBY);
}
}
else {
if (pmbmd->m_rgTranspStatus [0] == NONE)
m_iMAD += motionEstMB_BVOP (
x, y, pmv, pmvBackward, pmbmd, pmbmdRef, pmvRef, ppxlcRef0MBY, ppxlcRef1MBY, bColocatedMBExist );
else if (pmbmd->m_rgTranspStatus [0] == PARTIAL) {
m_iMAD += motionEstMB_BVOP_WithShape (
x, y, pmv, pmvBackward, pmbmd, pmbmdRef, pmvRef, ppxlcRef0MBY, ppxlcRef1MBY, bColocatedMBExist );
}
}
//~OBSS_SAIT_991015
}
else {
if (pmbmd->m_bColocatedMBSkip) {
pmbmd->m_bSkip = TRUE;
memset (pmv, 0, BVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
m_statsMB.nDirectMB++;
pmbmd->m_mbType = FORWARD;
}
else {
bColocatedMBExist = (pmbmdRef!=NULL);
if (pmbmd->m_rgTranspStatus [0] == NONE) {
// new changes
m_iMAD += m_vopmd.bInterlace ?
motionEstMB_BVOP_Interlaced (x, y, pmv, pmvBackward, pmbmd,
pmbmdRef, pmvRef, ppxlcRef0MBY,
ppxlcRef1MBY
,bColocatedMBExist) :
// end of new changes
motionEstMB_BVOP (
x, y,
pmv, pmvBackward,
pmbmd,
pmbmdRef, pmvRef,
ppxlcRef0MBY, ppxlcRef1MBY,
bColocatedMBExist
);
}
else if (pmbmd->m_rgTranspStatus [0] == PARTIAL) {
// new changes
m_iMAD += m_vopmd.bInterlace ?
motionEstMB_BVOP_InterlacedWithShape (x, y, pmv, pmvBackward, pmbmd,
pmbmdRef, pmvRef, ppxlcRef0MBY,
ppxlcRef1MBY
,bColocatedMBExist) :
// end of new changes
motionEstMB_BVOP_WithShape (
x, y,
pmv, pmvBackward,
pmbmd,
pmbmdRef, pmvRef,
ppxlcRef0MBY, ppxlcRef1MBY,
bColocatedMBExist
);
}
}
}
}
ppxlcOrigMBBY += MB_SIZE;
pmbmd++;
pmv += BVOP_MV_PER_REF_PER_MB;
pmvBackward += BVOP_MV_PER_REF_PER_MB;
ppxlcOrigMBY += MB_SIZE;
ppxlcRef0MBY += MB_SIZE;
ppxlcRef1MBY += MB_SIZE;
}
ppxlcOrigY += m_iFrameWidthYxMBSize;
ppxlcOrigBY += m_iFrameWidthYxMBSize;
ppxlcRef0Y += m_iFrameWidthYxMBSize;
ppxlcRef1Y += m_iFrameWidthYxMBSize;
}
if (m_iMVFileUsage == 2)
writeBVOPMVs();
}
Void CVideoObjectEncoder::copyToCurrBuffWithShapeY (const PixelC* ppxlcCurrY, const PixelC* ppxlcCurrBY)
{
Int iUnit = sizeof(PixelC); // NBIT: for memcpy
PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
PixelC* ppxlcCurrMBBY = m_ppxlcCurrMBBY;
Int ic;
for (ic = 0; ic < MB_SIZE; ic++) {
memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*iUnit);
memcpy (ppxlcCurrMBBY, ppxlcCurrBY, MB_SIZE*iUnit);
ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += m_iFrameWidthY;
ppxlcCurrMBBY += MB_SIZE; ppxlcCurrBY += m_iFrameWidthY;
}
}
Void CVideoObjectEncoder::copyToCurrBuffY (const PixelC* ppxlcCurrY)
{
Int iUnit = sizeof(PixelC); // NBIT: for memcpy
PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
Int ic;
// RRV modification
for(ic = 0; ic < (MB_SIZE *m_iRRVScale); ic++)
{
memcpy(ppxlcCurrMBY, ppxlcCurrY, (MB_SIZE *m_iRRVScale *iUnit));
ppxlcCurrMBY += (MB_SIZE *m_iRRVScale); ppxlcCurrY += m_iFrameWidthY;
}
// for (ic = 0; ic < MB_SIZE; ic++) {
// memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*iUnit);
// ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += m_iFrameWidthY;
// }
// ~RRV
}
//for spatial sclability: basically set every mv to zero
Void CVideoObjectEncoder::motionEstMB_PVOP (CoordI x, CoordI y,
CMotionVector* pmv, CMBMode* pmbmd)
{
pmbmd -> m_bhas4MVForward = FALSE;
pmbmd-> m_dctMd = INTER;
memset (pmv, 0, sizeof (CMotionVector) * PVOP_MV_PER_REF_PER_MB);
for (UInt i = 0; i < PVOP_MV_PER_REF_PER_MB; i++) {
pmv -> computeTrueMV ();
pmv++;
}
}
Int CVideoObjectEncoder::motionEstMB_PVOP (
CoordI x, CoordI y,
CMotionVector* pmv, CMBMode* pmbmd,
const PixelC* ppxlcRefMBY
)
{
// RRV modification/insertion
Int iFavorZero, iFavorInter;
Int nBits = m_volmd.nBits; // NBIT
if(m_vopmd.RRVmode.iRRVOnOff == 1)
{
iFavorZero = FAVORZERO_RRV; // NBIT
iFavorInter = FAVOR_INTER_RRV; // NBIT
}
else
{
iFavorZero = FAVORZERO; // NBIT
iFavorInter = FAVOR_INTER; // NBIT
}
Int iFavor16x16 = FAVOR_16x16; // NBIT
Int iFavor32x32 = FAVOR_32x32; // NBIT
// Int nBits = m_volmd.nBits; // NBIT
// Int iFavorZero = FAVORZERO; // NBIT
// Int iFavorInter = FAVOR_INTER; // NBIT
// Int iFavor16x16 = FAVOR_16x16; // NBIT
// ~RRV
// NBIT: addjust mode selection thresholds
if (nBits > 8) {
iFavorZero <<= (nBits-8);
iFavorInter <<= (nBits-8);
iFavor16x16 <<= (nBits-8);
} else if (nBits < 8) {
iFavorZero >>= (8-nBits);
iFavorInter >>= (8-nBits);
iFavor16x16 >>= (8-nBits);
}
Int iInitSAD = sad16x16At0 (ppxlcRefMBY);
Int iSADInter = blkmatch16 (pmv, x, y, x, y, iInitSAD, ppxlcRefMBY, m_puciRefQZoom0, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
Int iSumDev = sumDev ();
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iSADInter, "MB_SAD16");
#endif // __TRACE_AND_STATS_
// INTERLACE
/* NBIT: change to a bigger number
Int iSAD16x8 = 256*256;
*/
Int iSAD16x8 = 4096*256;
pmbmd -> m_bFieldMV = FALSE;
if(m_vopmd.bInterlace) {
// Field-Based Estimation
CMotionVector* pmv16x8 = pmv + 5;
const PixelC *ppxlcHalfPelRef = m_pvopcRefQ0->pixelsY()
+EXPANDY_REF_FRAME*m_iFrameWidthY + EXPANDY_REF_FRAME+ x + y * m_iFrameWidthY; // 1.31.99 changes
// top to top
Int iSAD16x8top = blkmatch16x8 (pmv16x8, x, y, 0, ppxlcRefMBY,
ppxlcHalfPelRef, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmv16x8++;
// bot to top
Int iSAD16x8bot = blkmatch16x8 (pmv16x8, x, y, 0, ppxlcRefMBY + m_iFrameWidthY,
ppxlcHalfPelRef + m_iFrameWidthY, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
iSAD16x8=(iSAD16x8top<iSAD16x8bot) ? iSAD16x8top : iSAD16x8bot;
pmbmd->m_bForwardTop = (iSAD16x8top<iSAD16x8bot) ? 0 : 1;
pmv16x8++;
// top to bot
iSAD16x8top = blkmatch16x8 (pmv16x8, x, y, MB_SIZE, ppxlcRefMBY,
ppxlcHalfPelRef, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
pmv16x8++;
// bot to bot
iSAD16x8bot = blkmatch16x8 (pmv16x8, x, y, MB_SIZE, ppxlcRefMBY + m_iFrameWidthY,
ppxlcHalfPelRef + m_iFrameWidthY, m_vopmd.iSearchRangeForward, m_volmd.bQuarterSample);
iSAD16x8 += (iSAD16x8top<iSAD16x8bot) ? iSAD16x8top : iSAD16x8bot;
pmbmd->m_bForwardBottom = (iSAD16x8top<iSAD16x8bot) ? 0 : 1;
} else {
/* NBIT: change to a bigger number
iSAD16x8 = 256*256;
*/
iSAD16x8 = 4096*256;
for (Int iBlk = 5; iBlk <= 8; iBlk++) { // 04/28/99 david ruhoff
pmv [iBlk] = pmv [0]; // fill in field info to make mv file deterministic
}
}
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace (iSAD16x8, "MB_SAD16x8");
#endif // __TRACE_AND_STATS_
// ~INTERLACE
CoordI blkX, blkY;
Int iSAD8 = 0;
CMotionVector* pmv8 = pmv + 1;
// RRV modification
blkX = x + (BLOCK_SIZE *m_iRRVScale);
blkY = y + (BLOCK_SIZE *m_iRRVScale);
// blkX = x + BLOCK_SIZE;
// blkY = y + BLOCK_SIZE;
// ~RRV
const PixelC* ppxlcCodedBlkY = m_ppxlcCurrMBY;
#ifdef __DISABLE_4MV_FOR_PVOP_
iSAD8 = 4096*4096; // big number to disable 8x8 mode
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -