📄 mc.cpp
字号:
/*************************************************************************This software module was originally developed by Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation Bruce Lin (blin@microsoft.com), Microsoft Corporation Simon Winder (swinder@microsoft.com), Microsoft Corporation (date: June, 1997)and edited by Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Centerand 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 Hideaki Kimata (NTT)and also edited by Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu) Sehoon Son (shson@unitel.co.kr) Samsung AITin 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: mc.cppAbstract: Motion compensation routines (common for encoder and decoder).Revision History: December 20, 1997 Interlaced tools added by NextLevel Systems (GI) X. Chen (xchen@nlvl.com) B. Eifrig (beifrig@nlvl.com) Feb.16 1999 add Quarter Sample Mathias Wien (wien@ient.rwth-aachen.de) Feb.23 1999 GMC added by Yoshinori Suzuki (Hitachi, Ltd.) Aug.24, 1999 : NEWPRED added by Hideaki Kimata (NTT) Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) *************************************************************************/#include "typeapi.h"#include "codehead.h"#include "mode.hpp"#include "global.h"#include "entropy/bitstrm.h"#include "entropy/entropy.h"#include "entropy/huffman.h"#include "vopses.hpp"#include "vopsedec.hpp"#include "mae_pass_thru.h"Void CVideoObject::motionCompMB ( PixelC* ppxlcPredMB, const PixelC* ppxlcRefLeftTop, const CMotionVector* pmv, const CMBMode* pmbmd, Int imbX, Int imbY, CoordI x, CoordI y, Bool bSkipNonOBMC, Bool bAlphaMB, CRct *prctMVLimit ) { int MVX, MVY; g_pHeader3->mbtype = MBT_8x8; if (bSkipNonOBMC) return; // 16x16 case if (!pmbmd->m_bhas4MVForward && !pmbmd->m_bFieldMV) { g_pHeader2->mbmode = MBMODE_FWD_ALL_420; g_pHeader3->mbtype = MBT_16x16; // Get the half-pel values MVX = TRUEMVHALFPEL_X(pmv); MVY = TRUEMVHALFPEL_Y(pmv); // Use hpel g_pMV[0] = g_pMV[1] = g_pMV[2] = g_pMV[3] = ((MVX << 16) | (MVY & 0x0000FFFF)); }#ifdef ENABLE_INTERLACING // interlacing, everything to worry about!! else if (pmbmd->m_bFieldMV) { const CMotionVector* pmv16x8 = pmv+5; // Initialize some basic stuff g_MAEWrapper->Set_MAEMB_mbmode(MBM_FORWARD,"CVideoObject::motionCompMB", __LINE__, __FILE__); // 4 forward MVs only g_MAEWrapper->Set_MAEMB_mbtype(MBT_16x8,"CVideoObject::motionCompMB", __LINE__, __FILE__); // ForwardTop Stuff if(pmbmd->m_bForwardTop) { pmv16x8++; // Get the half-pel values MVX = TRUEMVHALFPEL_X(pmv16x8); MVY = TRUEMVHALFPEL_Y(pmv16x8); // Use hpel g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 0, "CVideoObject::motionCompMB", __LINE__, __FILE__); g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 1, "CVideoObject::motionCompMB", __LINE__, __FILE__); pmv16x8++; } // BackwardTop Stuff else { // Get the half-pel values MVX = TRUEMVHALFPEL_X(pmv16x8); MVY = TRUEMVHALFPEL_Y(pmv16x8); // Use hpel g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 0, "CVideoObject::motionCompMB", __LINE__, __FILE__); g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 1, "CVideoObject::motionCompMB", __LINE__, __FILE__); pmv16x8++; pmv16x8++; } // ForwardBottom Stuff if (pmbmd->m_bForwardBottom) { pmv16x8++; // Get the half-pel values MVX = TRUEMVHALFPEL_X(pmv16x8); MVY = TRUEMVHALFPEL_Y(pmv16x8); // Use hpel g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 2, "CVideoObject::motionCompMB", __LINE__, __FILE__); g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 3, "CVideoObject::motionCompMB", __LINE__, __FILE__); } // BackwardBottom Stuff else { // Get the half-pel values MVX = TRUEMVHALFPEL_X(pmv16x8); MVY = TRUEMVHALFPEL_Y(pmv16x8); // Use hpel g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 2, "CVideoObject::motionCompMB", __LINE__, __FILE__); g_MAEWrapper->Set_MAEMB_mv ((MVX << 16) | ((MVY) & 0x0000FFFF), 3, "CVideoObject::motionCompMB", __LINE__, __FILE__); } }#endif // 8x8 case else { const CMotionVector* pmv8 = pmv; int i; g_pHeader2->mbmode = MBMODE_FWD_ALL_420; g_pHeader3->mbtype = MBT_8x8; for (i = 0; i < 4; i++) { // Multiply by 2 to get qpel pmv8++; // Get the half-pel values MVX = TRUEMVHALFPEL_X(pmv8); MVY = TRUEMVHALFPEL_Y(pmv8); // Use hpel g_pMV[i] = ((MVX << 16) | (MVY & 0x0000FFFF)); } }}Void CVideoObject::motionComp ( PixelC* ppxlcPred, // can be either Y or A const PixelC* ppxlcRefLeftTop, // point to left-top of the frame Int iSize, // either MB or BLOCK size CoordI xRef, CoordI yRef, // x + mvX, in half pel unit Int iRoundingControl, CRct *prctMVLimit, // extended bounding box int nMBType, int nBlockNum, const CMotionVector* pmv, int nSkip){ CoordI ix, iy; int nX, nY; const PixelC* pSaveRef; LIMITMVRANGETOEXTENDEDBBHALFPEL(&xRef,&yRef,prctMVLimit,iSize); if (pmv) { nX = TRUEMVHALFPEL_X(pmv); nY = TRUEMVHALFPEL_Y(pmv); } const PixelC* ppxlcRef = ppxlcRefLeftTop + ((yRef >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRef >> 1) + EXPANDY_REF_FRAME; if(iSize==8 || iSize==16) { // optimisation if (!(yRef & 1)) { if (!(xRef & 1)) { Int iSz = iSize * sizeof(PixelC); for(iy = 0; iy < iSize; iy+=8) { memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; memcpy (ppxlcPred, ppxlcRef, iSz); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; } } else { PixelC pxlcT1,pxlcT2, *ppxlcDst; const PixelC *ppxlcSrc; Int iRndCtrl = 1 - iRoundingControl; for (iy = 0; iy < iSize; iy++){ ppxlcDst = ppxlcPred; ppxlcSrc = ppxlcRef; for (ix = 0; ix < iSize; ix+=8) { ppxlcDst [0] = (ppxlcSrc[0] + (pxlcT1=ppxlcSrc[1]) + iRndCtrl) >> 1; ppxlcDst [1] = (pxlcT1 + (pxlcT2=ppxlcSrc[2]) + iRndCtrl) >> 1; ppxlcDst [2] = (pxlcT2 + (pxlcT1=ppxlcSrc[3]) + iRndCtrl) >> 1; ppxlcDst [3] = (pxlcT1 + (pxlcT2=ppxlcSrc[4]) + iRndCtrl) >> 1; ppxlcDst [4] = (pxlcT2 + (pxlcT1=ppxlcSrc[5]) + iRndCtrl) >> 1; ppxlcDst [5] = (pxlcT1 + (pxlcT2=ppxlcSrc[6]) + iRndCtrl) >> 1; ppxlcDst [6] = (pxlcT2 + (pxlcT1=ppxlcSrc[7]) + iRndCtrl) >> 1; ppxlcDst [7] = (pxlcT1 + ppxlcSrc[8] + iRndCtrl) >> 1; ppxlcDst += 8; ppxlcSrc += 8; } ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; } } } else { if (!(xRef & 1)) { Int iRndCtrl = 1 - iRoundingControl; const PixelC *ppxlcSrc, *ppxlcSrc2; PixelC *ppxlcDst; for (iy = 0; iy < iSize; iy++) { ppxlcDst = ppxlcPred; ppxlcSrc = ppxlcRef; ppxlcSrc2 = ppxlcRef + m_iFrameWidthY; for (ix = 0; ix < iSize; ix+=8) { ppxlcDst [0] = (ppxlcSrc [0] + ppxlcSrc2 [0] + iRndCtrl) >> 1; ppxlcDst [1] = (ppxlcSrc [1] + ppxlcSrc2 [1] + iRndCtrl) >> 1; ppxlcDst [2] = (ppxlcSrc [2] + ppxlcSrc2 [2] + iRndCtrl) >> 1; ppxlcDst [3] = (ppxlcSrc [3] + ppxlcSrc2 [3] + iRndCtrl) >> 1; ppxlcDst [4] = (ppxlcSrc [4] + ppxlcSrc2 [4] + iRndCtrl) >> 1; ppxlcDst [5] = (ppxlcSrc [5] + ppxlcSrc2 [5] + iRndCtrl) >> 1; ppxlcDst [6] = (ppxlcSrc [6] + ppxlcSrc2 [6] + iRndCtrl) >> 1; ppxlcDst [7] = (ppxlcSrc [7] + ppxlcSrc2 [7] + iRndCtrl) >> 1; ppxlcDst += 8; ppxlcSrc += 8; ppxlcSrc2 += 8; } ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; } } else { Int iRndCtrl = 2 - iRoundingControl; PixelC pxlcT1, pxlcT2, pxlcT3, pxlcT4, *ppxlcDst; const PixelC *ppxlcSrc, *ppxlcSrc2; for (iy = 0; iy < iSize; iy++) { ppxlcDst = ppxlcPred; ppxlcSrc = ppxlcRef; ppxlcSrc2 = ppxlcRef + m_iFrameWidthY; for (ix = 0; ix < iSize; ix+=8) { ppxlcDst [0] = (ppxlcSrc[0] + (pxlcT1=ppxlcSrc[1]) + ppxlcSrc2[0] + (pxlcT3=ppxlcSrc2[1]) + iRndCtrl) >> 2; ppxlcDst [1] = (pxlcT1 + (pxlcT2=ppxlcSrc[2]) + pxlcT3 + (pxlcT4=ppxlcSrc2[2]) + iRndCtrl) >> 2; ppxlcDst [2] = (pxlcT2 + (pxlcT1=ppxlcSrc[3]) + pxlcT4 + (pxlcT3=ppxlcSrc2[3]) + iRndCtrl) >> 2; ppxlcDst [3] = (pxlcT1 + (pxlcT2=ppxlcSrc[4]) + pxlcT3 + (pxlcT4=ppxlcSrc2[4]) + iRndCtrl) >> 2; ppxlcDst [4] = (pxlcT2 + (pxlcT1=ppxlcSrc[5]) + pxlcT4 + (pxlcT3=ppxlcSrc2[5]) + iRndCtrl) >> 2; ppxlcDst [5] = (pxlcT1 + (pxlcT2=ppxlcSrc[6]) + pxlcT3 + (pxlcT4=ppxlcSrc2[6]) + iRndCtrl) >> 2; ppxlcDst [6] = (pxlcT2 + (pxlcT1=ppxlcSrc[7]) + pxlcT4 + (pxlcT3=ppxlcSrc2[7]) + iRndCtrl) >> 2; ppxlcDst [7] = (pxlcT1 + ppxlcSrc[8] + pxlcT3 + ppxlcSrc2[8] + iRndCtrl) >> 2; ppxlcDst += 8; ppxlcSrc += 8; ppxlcSrc2 += 8; } ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; } } } } else { if (!(yRef & 1)) { if (!(xRef & 1)) { //!bXSubPxl && !bYSubPxl for (iy = 0; iy < iSize; iy++) { memcpy (ppxlcPred, ppxlcRef, iSize*sizeof(PixelC)); ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; } } else { //bXSubPxl && !bYSubPxl for (iy = 0; iy < iSize; iy++){ for (ix = 0; ix < iSize; ix++) ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRef [ix + 1] + 1 - iRoundingControl) >> 1; ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE; } } } else { const PixelC* ppxlcRefBot; if (!(xRef & 1)) { //!bXSubPxl&& bYSubPxl for (iy = 0; iy < iSize; iy++) { ppxlcRefBot = ppxlcRef + m_iFrameWidthY; //UPln -> pixels (xInt,yInt+1); for (ix = 0; ix < iSize; ix++) ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRefBot [ix] + 1 - iRoundingControl) >> 1; ppxlcRef = ppxlcRefBot; ppxlcPred += MB_SIZE; } } else { // bXSubPxl && bYSubPxl for (iy = 0; iy < iSize; iy++) { ppxlcRefBot = ppxlcRef + m_iFrameWidthY; //UPln -> pixels (xInt,yInt+1); for (ix = 0; ix < iSize; ix++){ ppxlcPred [ix] = ( ppxlcRef [ix + 1] + ppxlcRef [ix] + ppxlcRefBot [ix + 1] + ppxlcRefBot [ix] + 2 - iRoundingControl ) >> 2; } ppxlcRef = ppxlcRefBot; ppxlcPred += MB_SIZE; } } } }}Void CVideoObject::motionCompQuarterSample ( PixelC* ppxlcPred, // can be either Y or A const PixelC* ppxlcRefLeftTop, // point to left-top of the frame Int iSize, // either MB or BLOCK size CoordI xRef, CoordI yRef, // x + mvX in quarter pel unit Int iRoundingControl, // rounding control CRct *prctMVLimit, // extended bounding box int nMBType, int nBlockNum, const CMotionVector* pmv, int nSkip){ CoordI ix, iy; U8 *ppxlcblk; LIMITMVRANGETOEXTENDEDBBQUARTERPEL(&xRef,&yRef,prctMVLimit,iSize); Int blkSizeX, blkSizeY; if (iSize == 0) { // INTERLACED blkSizeX = 16; blkSizeY = 8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -