📄 sys_encoder_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.)and also edited by Mathias Wien (wien@ient.rwth-aachen.de) RWTH Aachen / Robert BOSCH GmbHand also edited by Yoshinori Suzuki (Hitachi, Ltd.)and also edited by Prabhudev Irappa Hosur (pn188359@ntu.edu.sg) NTU singaporeand also edited by Hideaki Kimata (NTT)and also edited by Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu)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 Feb.16, 1999: add Quarter Sample Mathias Wien (wien@ient.rwth-aachen.de) Feb.24, 1999: GMC added by Yoshinori Suzuki (Hitachi, Ltd.) May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net (added by mwi) August 9, 1999: Fast Motion Estimation added by Prabhudev Irappa Hosur (pn188359@ntu.edu.sg), NTU, S'pore Aug.24, 1999: NEWPRED added by Hideaki Kimata (NTT) Aug.31, 1999: QP pred. for GMC/LMC decision in rate control cases added by Yoshinori Suzuki (Hitachi, Ltd.) Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) March 30 , 2000 : Diamond Search removed by Prabhudev Irappa Hosur (NTU)*************************************************************************/#include <stdio.h>#include <math.h>#include <stdlib.h>#include <iostream>#include "typeapi.h"#include "codehead.h"#include "global.hpp"#include "bitstrm.hpp"#include "entropy.hpp"#include "huffman.hpp"#include "mode.hpp"#include "vopses.hpp"#include "vopseenc.hpp"// NEWPRED#include "newpred.hpp"// ~NEWPRED// RRV insertion#include "rrv.hpp"// ~RRV#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 MVs// RRV insertion#define FAVORZERO_RRV 513#define FAVOR_DIRECT_RRV 513#define FAVOR_INTER_RRV 2048#define FAVOR_32x32 513#define FAVOR_FIELD_RRV 65 // ~RRV inline 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;// GMC_V2 if ((m_uiSprite == 2) && (m_vopmd.vopPredType == SPRITE)) { CMBMode* pmbmdRef = m_rgmbmdRef; Int iqp_count=0, iqp_total=0; for (iMBY = 0; iMBY < m_iNumMBYRef; iMBY++) { for (iMBX = 0; iMBX < m_iNumMBXRef; iMBX++) { iqp_total += pmbmdRef -> m_stepSize; iqp_count++; pmbmdRef++; } } m_uiGMCQP = (iqp_total + iqp_count/2)/iqp_count; printf("QP for GMC/LMC selection: %d\n",m_uiGMCQP); }// ~GMC_V2 if (m_iMVFileUsage == 1) readPVOPMVs();// NEWPRED const PixelC* RefbufY = (m_volmd.bOriginalForME ? m_pvopcRefOrig0 : m_pvopcRefQ0)->pixelsY (); if(m_volmd.bNewpredEnable) { g_pNewPredEnc->CopyRefYtoBufY(RefbufY, m_rctRefFrameY); }// ~NEWPRED// RRV modification for(iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += (MB_SIZE *m_iRRVScale)) {// for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) {// ~RRV const PixelC* ppxlcOrigMBY = ppxlcOrigY; const PixelC* ppxlcRefMBY = ppxlcRefY; CoordI x = 0;// RRV modification for(iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += (MB_SIZE *m_iRRVScale)) {// for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {// ~RRV// NEWPRED if(m_volmd.bNewpredEnable) {// RRV modification if(g_pNewPredEnc->CheckSlice((iMBX *m_iRRVScale), (iMBY *m_iRRVScale))){// if(g_pNewPredEnc->CheckSlice(iMBX, iMBY)){// ~RRV// RRV modification PixelC* RefpointY = (PixelC*) m_pvopcRefQ0->pixelsY () + m_iStartInRefToCurrRctY + iMBY * (MB_SIZE *m_iRRVScale) * m_rctRefFrameY.width; g_pNewPredEnc->ChangeRefOfSliceYUV((const PixelC* )RefpointY, RefbufY, (iMBX *m_iRRVScale),(iMBY *m_iRRVScale),m_rctRefFrameY,'Y'); // PixelC* RefpointY = (PixelC*) m_pvopcRefQ0->pixelsY () + m_iStartInRefToCurrRctY + iMBY * MB_SIZE * m_rctRefFrameY.width;// g_pNewPredEnc->ChangeRefOfSliceYUV((const PixelC* )RefpointY, RefbufY, iMBX,iMBY,m_rctRefFrameY,'Y'); // ~RRV m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 (); biInterpolateY (m_pvopcRefQ0, m_rctRefVOPY0, m_puciRefQZoom0, m_rctRefVOPZoom0, m_vopmd.iRoundingControl); } } // ~NEWPRED#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;// RRV modification ppxlcOrigMBY += (MB_SIZE *m_iRRVScale); ppxlcRefMBY += (MB_SIZE *m_iRRVScale);// ppxlcOrigMBY += MB_SIZE;// ppxlcRefMBY += MB_SIZE;// ~RRV } ppxlcOrigY += m_iFrameWidthYxMBSize; ppxlcRefY += m_iFrameWidthYxMBSize; }// RRV insertion pmv = m_rgmv; if(m_vopmd.RRVmode.iRRVOnOff == 1) { MotionVectorScalingDown (pmv, m_iNumMBX *m_iNumMBY, PVOP_MV_PER_REF_PER_MB); }// ~RRV if (m_iMVFileUsage == 2) writePVOPMVs();// NEWPRED if(m_volmd.bNewpredEnable) g_pNewPredEnc->CopyBufYtoRefY(RefbufY, m_rctRefFrameY);// ~NEWPRED}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;// GMC_V2 if ((m_uiSprite == 2) && (m_vopmd.vopPredType == SPRITE)) { CMBMode* pmbmdRef = m_rgmbmdRef; Int iqp_count=0, iqp_total=0; for (iMBY = 0; iMBY < m_iNumMBYRef; iMBY++) { for (iMBX = 0; iMBX < m_iNumMBXRef; iMBX++) { if (pmbmdRef->m_rgTranspStatus [0] != ALL){ iqp_total += pmbmdRef -> m_stepSize; iqp_count++; } pmbmdRef++; } } m_uiGMCQP = (iqp_total + iqp_count/2)/iqp_count; printf("QP for GMC/LMC selection: %d\n",m_uiGMCQP); }// ~GMC_V2 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) {//OBSS_SAIT_991015 if (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 3) motionEstMB_PVOP (x, y, pmv, pmbmd); else { 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); } }//~OBSS_SAIT_991015#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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -