📄 motest.cpp
字号:
/*************************************************************************This software module was originally developed by Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation Bruce Lin (blin@microsoft.com), Microsoft Corporation (date: March, 1996)and edited by Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Centerand edited by Xuemin Chen (xchen@gi.com) General Instrument Corp.)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 standard> conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1996, 1997.Module Name: motEst.cppAbstract: Motion estimation routines.Revision History: Dec 20, 1997: Interlaced tools added by NextLevel Systems May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net*************************************************************************/#include <stdio.h>#include <math.h>#include <stdlib.h>#include <iostream.h>#include "typeapi.h"#include "codehead.h"#include "global.hpp"#include "entropy/bitstrm.hpp"#include "entropy/entropy.hpp"#include "entropy/huffman.hpp"#include "mode.hpp"#include "vopses.hpp"#include "vopseenc.hpp"#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW #endif // __MFC_#define FAVORZERO 129#define FAVOR_DIRECT 129#define FAVOR_INTER 512#define FAVOR_16x16 129#define FAVOR_FIELD 65 // P-VOP favor field over 8x8 due to fewer MVsinline Int minimum (Int a, Int b, Int c, Int d){ if (a <= b && a <= c && a <= d) return a; else if (b <= a && b <= c && b <= d) return b; else if (c <= a && c <= b && c <= d) return c; else return d;}Void CVideoObjectEncoder::motionEstPVOP (){ m_iMAD = 0; CoordI y = 0; CMBMode* pmbmd = m_rgmbmd; CMotionVector* pmv = m_rgmv; const PixelC* ppxlcOrigY = m_pvopcOrig->pixelsBoundY (); const PixelC* ppxlcRefY = (m_volmd.bOriginalForME ? m_pvopcRefOrig0 : m_pvopcRefQ0)->pixelsY () + m_iStartInRefToCurrRctY; Int iMBX, iMBY; if (m_iMVFileUsage == 1) readPVOPMVs(); for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) { const PixelC* ppxlcOrigMBY = ppxlcOrigY; const PixelC* ppxlcRefMBY = ppxlcRefY; CoordI x = 0; for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");#endif // __TRACE_AND_STATS_ if (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 3) { motionEstMB_PVOP (x, y, pmv, pmbmd); } else { copyToCurrBuffY (ppxlcOrigMBY); pmbmd->m_bFieldDCT=0; m_iMAD += motionEstMB_PVOP (x, y, pmv, pmbmd, ppxlcRefMBY); }#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y"); m_pbitstrmOut->trace (pmv [0], "MV16"); m_pbitstrmOut->trace (pmv [1], "MV8"); m_pbitstrmOut->trace (pmv [2], "MV8"); m_pbitstrmOut->trace (pmv [3], "MV8"); m_pbitstrmOut->trace (pmv [4], "MV8");// INTERLACE if(pmbmd->m_bForwardTop) m_pbitstrmOut->trace (pmv [6], "MV16x8"); else m_pbitstrmOut->trace (pmv [5], "MV16x8"); if(pmbmd->m_bForwardBottom) m_pbitstrmOut->trace (pmv [8], "MV16x8"); else m_pbitstrmOut->trace (pmv [7], "MV16x8");// ~INTERLACE#endif // __TRACE_AND_STATS_ pmbmd++; pmv += PVOP_MV_PER_REF_PER_MB; ppxlcOrigMBY += MB_SIZE; ppxlcRefMBY += MB_SIZE; } ppxlcOrigY += m_iFrameWidthYxMBSize; ppxlcRefY += m_iFrameWidthYxMBSize; } if (m_iMVFileUsage == 2) writePVOPMVs();}Void CVideoObjectEncoder::motionEstPVOP_WithShape (){ m_iMAD = 0; CoordI y = m_rctCurrVOPY.top; CMBMode* pmbmd = m_rgmbmd; CMotionVector* pmv = m_rgmv; const PixelC* ppxlcOrigY = m_pvopcOrig->pixelsBoundY (); const PixelC* ppxlcOrigBY = m_pvopcOrig->pixelsBoundBY (); const PixelC* ppxlcRefY = (m_volmd.bOriginalForME ? m_pvopcRefOrig0 : m_pvopcRefQ0)->pixelsY () + m_iStartInRefToCurrRctY; Int iMBX, iMBY; if (m_iMVFileUsage == 1) readPVOPMVs(); for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) { const PixelC* ppxlcOrigMBY = ppxlcOrigY; const PixelC* ppxlcOrigMBBY = ppxlcOrigBY; const PixelC* ppxlcRefMBY = ppxlcRefY; CoordI x = m_rctCurrVOPY.left; for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {#ifdef __TRACE_AND_STATS_ if(m_volmd.bShapeOnly==FALSE) m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");#endif // __TRACE_AND_STATS_ copyToCurrBuffWithShapeY (ppxlcOrigMBY, ppxlcOrigMBBY); decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); if(m_volmd.bShapeOnly==FALSE) { if (pmbmd->m_rgTranspStatus [0] == NONE) {// new changes X. Chen pmbmd->m_bFieldDCT=0; m_iMAD += motionEstMB_PVOP (x, y, pmv, pmbmd, ppxlcRefMBY); } else if (pmbmd->m_rgTranspStatus [0] == PARTIAL) {// new changes X. Chen pmbmd->m_bFieldDCT=0; m_iMAD += motionEstMB_PVOP_WithShape (x, y, pmv, pmbmd, ppxlcRefMBY); }#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y"); m_pbitstrmOut->trace (pmv [0], "MV16"); m_pbitstrmOut->trace (pmv [1], "MV8"); m_pbitstrmOut->trace (pmv [2], "MV8"); m_pbitstrmOut->trace (pmv [3], "MV8"); m_pbitstrmOut->trace (pmv [4], "MV8");// INTERLACE // new changes if(pmbmd->m_bFieldDCT) { if(pmbmd->m_bForwardTop) m_pbitstrmOut->trace (pmv [6], "MV16x8"); else m_pbitstrmOut->trace (pmv [5], "MV16x8"); if(pmbmd->m_bForwardBottom) m_pbitstrmOut->trace (pmv [8], "MV16x8"); else m_pbitstrmOut->trace (pmv [7], "MV16x8"); } // end of new changes// ~INTERLACE#endif // __TRACE_AND_STATS_ } pmbmd++; pmv += PVOP_MV_PER_REF_PER_MB; ppxlcOrigMBY += MB_SIZE; ppxlcOrigMBBY += MB_SIZE; ppxlcRefMBY += MB_SIZE; } ppxlcOrigY += m_iFrameWidthYxMBSize; ppxlcOrigBY += m_iFrameWidthYxMBSize; ppxlcRefY += m_iFrameWidthYxMBSize; } if (m_iMVFileUsage == 2) writePVOPMVs();}Void CVideoObjectEncoder::motionEstBVOP (){ if (m_iMVFileUsage == 1) readBVOPMVs(); m_iMAD = 0; CoordI y = 0; // frame-based, always start from 0 CMBMode* pmbmd = m_rgmbmd; const CMBMode* pmbmdRef = NULL; const CMotionVector* pmvRef = NULL; //mv in ref frame (for direct mode) if(m_bCodedFutureRef!=FALSE) { pmbmdRef = m_rgmbmdRef; 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) // 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 { pmbmd->m_bColocatedMBSkip = (pmbmdRef==NULL) ? FALSE : pmbmdRef->m_bSkip; 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 { 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 (); const PixelC* ppxlcRef0Y = m_pvopcRefOrig0->pixelsY () + m_iStartInRefToCurrRctY; const PixelC* ppxlcRef1Y = m_pvopcRefOrig1->pixelsY () + m_iStartInRefToCurrRctY; Int iMBX, iMBY; if (m_iMVFileUsage == 1) readBVOPMVs(); 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; copyToCurrBuffWithShapeY (ppxlcOrigMBY, ppxlcOrigMBBY); decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); if (pmbmd->m_rgTranspStatus [0] != ALL) { const CMBMode* pmbmdRef; const CMotionVector* pmvRef; findColocatedMB (iMBX, iMBY, pmbmdRef, pmvRef); 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); 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 ); } } 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -