📄 mbenc.cpp
字号:
/************************************************************************* This software module was originally developed by Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation Wei-ge Chen (wchen@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 Center and also edited by Yoshihiro Kikuchi (TOSHIBA CORPORATION) Takeshi Nagai (TOSHIBA CORPORATION) Toshiaki Watanabe (TOSHIBA CORPORATION) Noboru Yamaguchi (TOSHIBA CORPORATION) and also edited by Yoshinori Suzuki (Hitachi, Ltd.) and also edited by Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu) and also edited by Takefumi Nagumo (nagumo@av.crl.sony.co.jp) Sony Corporation Sehoon Son (shson@unitel.co.kr) Samsung AIT 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: MBenc.cpp Abstract: MacroBlock encoder Revision History: This software module was edited by Hiroyuki Katata (katata@imgsl.mkhar.sharp.co.jp), Sharp Corporation Norio Ito (norio@imgsl.mkhar.sharp.co.jp), Sharp Corporation Shuichi Watanabe (watanabe@imgsl.mkhar.sharp.co.jp), Sharp Corporation (date: October, 1997) for object based temporal scalability. Dec 20, 1997: Interlaced tools added by NextLevel Systems X.Chen, B. Eifrig May. 9 1998: add boundary by Hyundai Electronics Cheol-Soo Park (cspark@super5.hyundai.co.kr) Feb. 23 1999: GMC added by Yoshinori Suzuki(Hitachi, Ltd.) May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net NOTE: m_pvopfCurrQ holds the original data until it is texture quantized Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) Feb.01 2000 : Bug fixed OBSS by Takefumi Nagumo (Sony)*************************************************************************/#include <stdlib.h>#include <math.h>#include <iostream.h>#include "typeapi.h"#include "codehead.h"#include "mode.hpp"#include "global.hpp"#include "entropy/bitstrm.hpp"#include "entropy/entropy.hpp"#include "entropy/huffman.hpp"#include "vopses.hpp"#include "vopseenc.hpp"// 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_Void CVideoObjectEncoder::updateQP(CMBMode* pmbmd, Int iPrevQP, Int iNewQP){ Int iNewStepSize; if(pmbmd->m_dctMd==INTER && pmbmd->m_bhas4MVForward) pmbmd->m_intStepDelta = 0; // cant change if 4mv // we do not know yet if the mb is not-coded, or transparent // therefore we must cancel the qp update later if we find we are skipping the mb // to do this we call cancelQPUpdate else pmbmd->m_intStepDelta = iNewQP - iPrevQP; // bounds check QP and delta QP if(pmbmd->m_intStepDelta>2) pmbmd->m_intStepDelta = 2; else if(pmbmd->m_intStepDelta<-2) pmbmd->m_intStepDelta = -2; iNewStepSize = iPrevQP + pmbmd->m_intStepDelta; Int iMaxQP = (1<<m_volmd.uiQuantPrecision)-1; if(iNewStepSize > iMaxQP) iNewStepSize = iMaxQP; else if(iNewStepSize < 1) iNewStepSize = 1; // set values pmbmd->m_stepSize = iNewStepSize; pmbmd->m_intStepDelta = iNewStepSize - iPrevQP; // set dct mode (robustly) if (pmbmd->m_intStepDelta == 0) { if(pmbmd->m_dctMd==INTRAQ) pmbmd->m_dctMd = INTRA; else if(pmbmd->m_dctMd==INTERQ) pmbmd->m_dctMd = INTER; } else { if(pmbmd->m_dctMd==INTRA) pmbmd->m_dctMd = INTRAQ; else if(pmbmd->m_dctMd==INTER) pmbmd->m_dctMd = INTERQ; } if(m_volmd.fAUsage == EIGHT_BIT) setAlphaQP(pmbmd); }// this is called if we wanted a dquant but later found the mb was skippedVoid CVideoObjectEncoder::cancelQPUpdate(CMBMode* pmbmd){ // we set the delta qp to be zero pmbmd->m_stepSize -= pmbmd->m_intStepDelta; pmbmd->m_intStepDelta = 0; if(pmbmd->m_dctMd == INTERQ) pmbmd->m_dctMd = INTER; if(m_volmd.fAUsage == EIGHT_BIT) setAlphaQP(pmbmd);}Void CVideoObjectEncoder::setAlphaQP(CMBMode* pmbmd){ Int iQPA; if(!m_volmd.bNoGrayQuantUpdate) { if(m_vopmd.vopPredType == BVOP) iQPA = (pmbmd->m_stepSize * m_vopmd.intStepBAlpha[0]) / m_vopmd.intStepB; else if(m_vopmd.vopPredType == IVOP) iQPA = (pmbmd->m_stepSize * m_vopmd.intStepIAlpha[0]) / m_vopmd.intStepI; else iQPA = (pmbmd->m_stepSize * m_vopmd.intStepPAlpha[0]) / m_vopmd.intStep; } else { if(m_vopmd.vopPredType == BVOP) iQPA = m_vopmd.intStepBAlpha[0]; else if(m_vopmd.vopPredType == IVOP) iQPA = m_vopmd.intStepIAlpha[0]; else iQPA = m_vopmd.intStepPAlpha[0]; } if(iQPA<1) iQPA=1; pmbmd->m_stepSizeAlpha = iQPA;}Void CVideoObjectEncoder::encodePVOPMBJustShape( PixelC* ppxlcRefBY, CMBMode* pmbmd, ShapeMode shpmdColocatedMB, const CMotionVector* pmv, CMotionVector* pmvBY, CoordI x, CoordI y, Int imbX, Int imbY){ //OBSS_SAIT_991015 //OBSSFIX_MODE3 if(!(m_volmd.bSpatialScalability && m_volmd.iHierarchyType==0) || (m_volmd.bSpatialScalability && m_volmd.iHierarchyType==0 && m_volmd.volType == ENHN_LAYER && m_volmd.iEnhnType!=0 && m_volmd.iuseRefShape ==1)){ // if(!(m_volmd.bSpatialScalability && m_volmd.iHierarchyType==0)){ //~OBSSFIX_MODE3 m_statsMB.nBitsShape += codeInterShape ( ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB, pmv, pmvBY, x, y, imbX, imbY); } else{ if((m_volmd.volType == BASE_LAYER) || (!(m_volmd.iEnhnType==0 || m_volmd.iuseRefShape ==0) && !m_volmd.bShapeOnly) ) m_statsMB.nBitsShape += codeInterShape ( ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB, pmv, pmvBY, x, y, imbX, imbY); else m_statsMB.nBitsShape += codeSIShapePVOP ( ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB, pmv, pmvBY, x, y, imbX, imbY); } //~OBSS_SAIT_991015 // change pmbmd to inter if all transparent decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY);}Void CVideoObjectEncoder::dumpCachedShapeBits(){#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace("INSERTING PRE-ENCODED MB SHAPE STREAM HERE\n"); m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location Before");#endif // __TRACE_AND_STATS_ m_pbitstrmOut->putBitStream(*m_pbitstrmShapeMBOut);#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location After");#endif // __TRACE_AND_STATS_ m_pbitstrmShapeMBOut->flush(); m_pbitstrmShapeMBOut->resetAll();}// HHI Schueuer: added const PixelC *ppxlcCurrMBBY, const PixelC *ppxlcCurrMBBUV for sadctVoid CVideoObjectEncoder::encodePVOPMBTextureWithShape( PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV, PixelC** pppxlcRefMBA, CMBMode* pmbmd, const CMotionVector* pmv, Int imbX, Int imbY, CoordI x, CoordI y, Bool* pbRestart, const PixelC *ppxlcCurrMBBY, const PixelC *ppxlcCurrMBBUV){ if (pmbmd -> m_dctMd == INTRA || pmbmd -> m_dctMd == INTRAQ) { if(pmbmd -> m_rgTranspStatus [0] == PARTIAL) LPEPadding (pmbmd); assert (pmbmd -> m_rgTranspStatus [0] != ALL); // vlc mode needs to be set up provisionally before quantisation // to ensure that the correct cbp is generated if using ac coefs // however codembtextureheadofpvop also calls the function, so we // save the restart value to avoid problems on the second call Bool bTemp = *pbRestart; setDCVLCMode(pmbmd, pbRestart); *pbRestart = bTemp; if (!m_volmd.bSadctDisable) quantizeTextureIntraMB (imbX, imbY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA, ppxlcCurrMBBY, ppxlcCurrMBBUV); else quantizeTextureIntraMB (imbX, imbY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA); codeMBTextureHeadOfPVOP (pmbmd, pbRestart); sendDCTCoefOfIntraMBTexture (pmbmd); if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99 codeMBAlphaHeadOfPVOP (pmbmd,iAuxComp); sendDCTCoefOfIntraMBAlpha (pmbmd,iAuxComp); } } } else { // INTER or skipped if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) { CoordI xRefUV, yRefUV; if(pmbmd->m_bMCSEL) { FindGlobalChromPredForGMC(x,y,m_ppxlcPredMBU,m_ppxlcPredMBV); }else{ if(pmbmd->m_bFieldMV) { CoordI xRefUV1, yRefUV1; mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1); motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop, &m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE, m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom, &m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support } else { mvLookupUVWithShape (pmbmd, pmv, xRefUV, yRefUV); motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUV, yRefUV, m_vopmd.iRoundingControl,&m_rctRefVOPY0); } } motionCompMBYEnc (pmv, pmbmd, imbX, imbY, x, y, &m_rctRefVOPY0); computeTextureErrorWithShape (); } else { // not partial CoordI xRefUV, yRefUV, xRefUV1, yRefUV1; if(pmbmd->m_bMCSEL) { FindGlobalChromPredForGMC(x,y,m_ppxlcPredMBU,m_ppxlcPredMBV); }else{ mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1); if(pmbmd->m_bFieldMV) { motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop, &m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE, m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom, &m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support } else { motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUV, yRefUV, m_vopmd.iRoundingControl, &m_rctRefVOPY0); } } motionCompMBYEnc (pmv, pmbmd, imbX, imbY, x, y, &m_rctRefVOPY0); computeTextureError (); } Bool bSkip = pmbmd->m_bhas4MVForward ? (pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ()) : (!pmbmd->m_bFieldMV && pmv->isZero()) ; if(pmbmd -> m_bMCSEL) bSkip= TRUE; if(!m_volmd.bAllowSkippedPMBs) bSkip = FALSE; if (!m_volmd.bSadctDisable) quantizeTextureInterMB (pmbmd, pmv, pppxlcRefMBA, bSkip, ppxlcCurrMBBY, ppxlcCurrMBBUV); // decide COD here else quantizeTextureInterMB (pmbmd, pmv, pppxlcRefMBA, bSkip); // decide COD here if((m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE)) if(pmbmd -> m_bSkip && !pmbmd -> m_bMCSEL) pmbmd -> m_bSkip = FALSE; codeMBTextureHeadOfPVOP (pmbmd, pbRestart); if (!(pmbmd -> m_bSkip && !pmbmd -> m_bMCSEL)) { if(!(m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 3) && !pmbmd -> m_bMCSEL) //for zero-MV of OBSS(P-VOP) m_statsMB.nBitsMV += encodeMVWithShape (pmv, pmbmd, imbX, imbY); if (pmbmd -> m_bSkip) assignPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV); else sendDCTCoefOfInterMBTexture (pmbmd); } else assignPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV); if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99 codeMBAlphaHeadOfPVOP (pmbmd, iAuxComp); if (pmbmd -> m_pCODAlpha[iAuxComp] == ALPHA_CODED) { sendDCTCoefOfInterMBAlpha (pmbmd, iAuxComp); } else if(pmbmd -> m_pCODAlpha[iAuxComp] == ALPHA_SKIPPED) assignAlphaPredToCurrQ (pppxlcRefMBA[iAuxComp],iAuxComp); } } if (!pmbmd -> m_bSkip) { addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV); } if (m_volmd.fAUsage == EIGHT_BIT) { for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99 if (pmbmd -> m_pCODAlpha[iAuxComp] == ALPHA_CODED) addAlphaErrorAndPredToCurrQ (pppxlcRefMBA[iAuxComp],iAuxComp); } } }}Void CVideoObjectEncoder::encodePVOPMB ( PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV, CMBMode* pmbmd, const CMotionVector* pmv, const CMotionVector* pmv_RRV, Int iMBX, Int iMBY, CoordI x, CoordI y, Bool *pbRestart )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -