📄 shpenc.cpp
字号:
/*************************************************************************This software module was originally developed by Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation (April, 1997)and edited by Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Centerand also edited by Yoshihiro Kikuchi (TOSHIBA CORPORATION) Takeshi Nagai (TOSHIBA CORPORATION) Toshiaki Watanabe (TOSHIBA CORPORATION) Noboru Yamaguchi (TOSHIBA CORPORATION)and also edited by Takefumi Nagumo (nagumo@av.crl.sony.co.jp) Sony Corporation 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: shpenc.hppAbstract: binary shape encoder with context-based arithmatic coderRevision History: Feb.01 2000: Bug fixed OBSS by Takefumi Nagumo (SONY)*************************************************************************/#include "typeapi.h"#include "entropy/entropy.hpp"#include "entropy/huffman.hpp"#include "entropy/bitstrm.hpp"#include "global.hpp"#include "mode.hpp"#include "codehead.h"#include "cae.h"#include "vopses.hpp"#include "vopseenc.hpp"#include "dct.hpp" // HHI Schueuer: inserted for deriveSADCTRowLengths//OBSS_SAIT_991015#include <math.h> #define SIGN(n) (n>0)?1:((n<0)?-1:0) //~OBSS_SAIT_991015#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW #endif // __MFC_// HHI Schueuer: inserted for SADCT Void CVideoObjectEncoder::deriveSADCTRowLengths(Int **piCoeffWidths, const PixelC* ppxlcMBBY, const PixelC* ppxlcCurrMBBUV, const TransparentStatus *pTransparentStatus){ CFwdSADCT *pfdct = (CFwdSADCT *)m_pfdct; const PixelC *pSrc = NULL; int i; for (i=Y_BLOCK1; i<U_BLOCK; i++) { if (pTransparentStatus[i] != PARTIAL) { memset(piCoeffWidths[i], 0, BLOCK_SIZE * sizeof(piCoeffWidths[i][0])); continue; } switch (i) { case Y_BLOCK1: pSrc = ppxlcMBBY; break; case Y_BLOCK2: pSrc = ppxlcMBBY + BLOCK_SIZE; break; case Y_BLOCK3: pSrc = ppxlcMBBY + BLOCK_SIZE*MB_SIZE; break; case Y_BLOCK4: pSrc = ppxlcMBBY + BLOCK_SIZE*MB_SIZE + BLOCK_SIZE; break; } pfdct->getRowLength(piCoeffWidths[i], pSrc, MB_SIZE);#ifdef _DEBUG for (int iy=0; iy<BLOCK_SIZE; iy++) { int l = *(piCoeffWidths[i] + iy); assert(l>=0 && l<=BLOCK_SIZE); }#endif } if (pTransparentStatus[U_BLOCK] == PARTIAL) { pfdct->getRowLength(piCoeffWidths[U_BLOCK], ppxlcCurrMBBUV, BLOCK_SIZE); #ifdef _DEBUG for (int iy=0; iy<BLOCK_SIZE; iy++) { int l = *(piCoeffWidths[i] + iy); assert(l>=0 && l<=BLOCK_SIZE); }#endif } else memset(piCoeffWidths[U_BLOCK], 0, BLOCK_SIZE * sizeof(piCoeffWidths[i][0])); #ifdef __TRACE_DECODING_ m_ptrcer->dumpSADCTRowLengths(piCoeffWidths);#endif}// end Int CVideoObjectEncoder::codeIntraShape (PixelC* ppxlcSrcFrm, CMBMode* pmbmd, Int iMBX, Int iMBY){ m_iInverseCR = 1; m_iWidthCurrBAB = BAB_SIZE;#ifdef __TRACE_AND_STATS_ if(pmbmd->m_rgTranspStatus [0] == NONE) m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL OPAQUE"); else if(pmbmd->m_rgTranspStatus [0] == ALL) m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL TRANSP"); else m_pbitstrmOut->trace (m_ppxlcCurrMBBY, MB_SIZE, MB_SIZE, "ORIGINAL_BAB");#endif // __TRACE_AND_STATS_ Int iMBnum = VPMBnum(iMBX, iMBY); m_bVPNoLeft = bVPNoLeft(iMBnum, iMBX); m_bVPNoTop = bVPNoTop(iMBnum); m_bVPNoRightTop = bVPNoRightTop(iMBnum, iMBX); m_bVPNoLeftTop = bVPNoLeftTop(iMBnum, iMBX); if (pmbmd->m_rgTranspStatus [0] == NONE) pmbmd->m_shpmd = ALL_OPAQUE; else if (pmbmd->m_rgTranspStatus [0] == ALL) pmbmd->m_shpmd = ALL_TRANSP; else if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, MPEG4_TRANSPARENT, pmbmd)) { pmbmd->m_shpmd = ALL_TRANSP; if ( !isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, MPEG4_OPAQUE, pmbmd)) { // both opaque and transparent are good, so count pixels to decide Int i,iSum=0; for(i=0;i<MB_SQUARE_SIZE;i++) iSum+=(m_ppxlcCurrMBBY[i]>0); if(iSum>=(MB_SQUARE_SIZE>>1)) pmbmd->m_shpmd = ALL_OPAQUE; } } else if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, MPEG4_OPAQUE, pmbmd)) pmbmd->m_shpmd = ALL_OPAQUE; else pmbmd->m_shpmd = round (ppxlcSrcFrm, pmbmd); if(pmbmd->m_shpmd==ALL_TRANSP) {#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_ALL_TRANSP");#endif // __TRACE_AND_STATS_ copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, MPEG4_TRANSPARENT); return codeShapeModeIntra (ALL_TRANSP, pmbmd, iMBX, iMBY); } else if(pmbmd->m_shpmd==ALL_OPAQUE) {#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_ALL_OPAQUE");#endif // __TRACE_AND_STATS_ copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, MPEG4_OPAQUE); return codeShapeModeIntra (ALL_OPAQUE, pmbmd, iMBX, iMBY); } else { // intra CAE assert(pmbmd->m_shpmd == INTRA_CAE);#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, TOTAL_BAB_SIZE, "MB_RECON_BAB (Ignore border)"); m_pbitstrmOut->trace (m_rgpxlcCaeSymbol, m_iWidthCurrBAB , m_iWidthCurrBAB , "MB_ENCODED_BAB");#endif // __TRACE_AND_STATS_ if (m_bNoShapeChg) //must be partial copyReconShapeToRef (ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER); else copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER); UInt nBitsMode = codeShapeModeIntra (INTRA_CAE, pmbmd, iMBX, iMBY); m_pbitstrmShapeMBOut->setBookmark (); UInt nBitsV = encodeCAEIntra (INTRA_CAE, VERTICAL); m_pbitstrmShapeMBOut->gotoBookmark (); UInt nBitsH = encodeCAEIntra (INTRA_CAE, HORIZONTAL); if (nBitsV < nBitsH) { m_pbitstrmShapeMBOut->gotoBookmark (); nBitsV = encodeCAEIntra (INTRA_CAE, VERTICAL); return nBitsV+nBitsMode; } else return nBitsH+nBitsMode; }}Int CVideoObjectEncoder::codeInterShape (PixelC* ppxlcSrcFrm, CVOPU8YUVBA* pvopcRefQ, CMBMode* pmbmd, const ShapeMode& shpmdColocatedMB, const CMotionVector* pmv, CMotionVector* pmvBY, CoordI iX, CoordI iY, Int iMBX, Int iMBY){ m_iInverseCR = 1; m_iWidthCurrBAB = BAB_SIZE; pmbmd->m_shpmd = UNKNOWN; CMotionVector mvBYD (0, 0); CMotionVector mvShapeMVP;#ifdef __TRACE_AND_STATS_ if(pmbmd->m_rgTranspStatus [0] == NONE) m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL MPEG4_OPAQUE"); else if(pmbmd->m_rgTranspStatus [0] == ALL) m_pbitstrmOut->trace ("ORIGINAL BAB IS ALL TRANSP"); else m_pbitstrmOut->trace (m_ppxlcCurrMBBY, MB_SIZE, MB_SIZE, "ORIGINAL_BAB");#endif // __TRACE_AND_STATS_ Int iMBnum = VPMBnum(iMBX, iMBY); m_bVPNoLeft = bVPNoLeft(iMBnum, iMBX); m_bVPNoTop = bVPNoTop(iMBnum); m_bVPNoRightTop = bVPNoRightTop(iMBnum, iMBX); m_bVPNoLeftTop = bVPNoLeftTop(iMBnum, iMBX); if (pmbmd->m_rgTranspStatus [0] == ALL) pmbmd->m_shpmd = ALL_TRANSP; else if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, MPEG4_TRANSPARENT, pmbmd)) { pmbmd->m_shpmd = ALL_TRANSP; if ( !isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, MPEG4_OPAQUE, pmbmd)) { // both opaque and transparent are good, so count pixels to decide Int i,iSum=0; for(i=0;i<MB_SQUARE_SIZE;i++) iSum+=(m_ppxlcCurrMBBY[i]>0); if(iSum>=(MB_SQUARE_SIZE>>1)) pmbmd->m_shpmd = ALL_OPAQUE; } } else if(pmbmd->m_rgTranspStatus [0] == NONE) pmbmd->m_shpmd = ALL_OPAQUE; else if(!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, MPEG4_OPAQUE, pmbmd)) pmbmd->m_shpmd = ALL_OPAQUE; if(pmbmd->m_shpmd!=ALL_TRANSP ) { // find motion vectors//OBSSFIX_MODE3 if( m_volmd.volType == ENHN_LAYER && m_volmd.bSpatialScalability == 1 && m_volmd.iHierarchyType == 0 && m_volmd.iEnhnType != 0 && m_volmd.iuseRefShape == 1 && m_vopmd.vopPredType == PVOP){ //Set predictor of Shape coding of OBSS (simulcast shape case) mvShapeMVP.setToZero(); memset((void *)m_puciPredBAB->pixels(),255, MC_BAB_SIZE*MC_BAB_SIZE); }else{ mvShapeMVP = findShapeMVP (pmv, pmvBY, pmbmd, iMBX, iMBY); assert (mvShapeMVP.iMVX != NOT_MV && mvShapeMVP.iMVY != NOT_MV); // mvShapeMVP = CMotionVector ((mvShapeMVP.iMVX * 2 + mvShapeMVP.iHalfX) / 2, //rounding // (mvShapeMVP.iMVY * 2 + mvShapeMVP.iHalfY) / 2); motionCompBY ((PixelC*) m_puciPredBAB->pixels (), (PixelC*) pvopcRefQ->getPlane (BY_PLANE)->pixels (), mvShapeMVP.iMVX + iX - 1, mvShapeMVP.iMVY + iY - 1); //-1 due to 18x18 motion comp }// mvShapeMVP = findShapeMVP (pmv, pmvBY, pmbmd, iMBX, iMBY);// assert (mvShapeMVP.iMVX != NOT_MV && mvShapeMVP.iMVY != NOT_MV);// // mvShapeMVP = CMotionVector ((mvShapeMVP.iMVX * 2 + mvShapeMVP.iHalfX) / 2, //rounding// // (mvShapeMVP.iMVY * 2 + mvShapeMVP.iHalfY) / 2); // motionCompBY ((PixelC*) m_puciPredBAB->pixels (),// (PixelC*) pvopcRefQ->getPlane (BY_PLANE)->pixels (),// mvShapeMVP.iMVX + iX - 1, // mvShapeMVP.iMVY + iY - 1); //-1 due to 18x18 motion comp//~OBSSFIX_MODE3 if (!isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, m_puciPredBAB->pixels (), m_rgiSubBlkIndx18x18, 18, pmbmd)) // zero mvd is ok *pmvBY = mvShapeMVP; else { // do block matching CMotionVector mvShape;//OBSSFIX_MODE3 if(m_volmd.volType == ENHN_LAYER && m_volmd.bSpatialScalability == 1 && m_volmd.iHierarchyType == 0 && m_volmd.iEnhnType != 0 && m_volmd.iuseRefShape == 1 && m_vopmd.vopPredType == PVOP){ mvShapeMVP.setToZero(); memset((void *)m_puciPredBAB->pixels(),255, MC_BAB_SIZE*MC_BAB_SIZE); }else{ blkmatchForShape (pvopcRefQ,&mvShape, mvShapeMVP.trueMVHalfPel (), iX, iY); assert (mvShape.iMVX != NOT_MV && mvShape.iMVY != NOT_MV); *pmvBY = mvShape; mvBYD = mvShape - mvShapeMVP; motionCompBY ((PixelC*) m_puciPredBAB->pixels (), (PixelC*) pvopcRefQ->getPlane (BY_PLANE)->pixels (), mvShape.iMVX + iX - 1, mvShape.iMVY + iY - 1); //-1 due to 18x18 motion comp }// blkmatchForShape (pvopcRefQ,&mvShape, mvShapeMVP.trueMVHalfPel (), iX, iY);// assert (mvShape.iMVX != NOT_MV && mvShape.iMVY != NOT_MV);// *pmvBY = mvShape;// mvBYD = mvShape - mvShapeMVP;// motionCompBY ((PixelC*) m_puciPredBAB->pixels (),// (PixelC*) pvopcRefQ->getPlane (BY_PLANE)->pixels (),// mvShape.iMVX + iX - 1,// mvShape.iMVY + iY - 1); //-1 due to 18x18 motion comp//~OBSSFIX_MODE3 } // check status of motion compensated prediction BAB PixelC *ppxlcPredBAB = (PixelC *)m_puciPredBAB->pixels()+MC_BAB_SIZE*MC_BAB_BORDER; Int iXX,iYY,iOpaqueCount = 0; for(iYY=MC_BAB_BORDER;iYY<MC_BAB_SIZE-MC_BAB_BORDER;iYY++,ppxlcPredBAB+=MC_BAB_SIZE) for(iXX=MC_BAB_BORDER;iXX<MC_BAB_SIZE-MC_BAB_BORDER;iXX++) if(ppxlcPredBAB[iXX] == opaqueValue) iOpaqueCount++; if(iOpaqueCount==0 || isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16, m_puciPredBAB->pixels (), m_rgiSubBlkIndx18x18, 18, pmbmd)) { // MC BAB is all transparent or not acceptable, so code. round(ppxlcSrcFrm, pmbmd); if(mvBYD.isZero()) pmbmd->m_shpmd = INTER_CAE_MVDZ; else pmbmd->m_shpmd = INTER_CAE_MVDNZ; } else if(pmbmd->m_shpmd==ALL_OPAQUE && !mvBYD.isZero()) ; else if(pmbmd->m_rgTranspStatus[0] == NONE && iOpaqueCount!=MB_SQUARE_SIZE) pmbmd->m_shpmd=ALL_OPAQUE; else if(mvBYD.isZero()) pmbmd->m_shpmd = MVDZ_NOUPDT; else pmbmd->m_shpmd = MVDNZ_NOUPDT; } switch(pmbmd->m_shpmd) { case ALL_OPAQUE:#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_ALL_OPAQUE");#endif // __TRACE_AND_STATS_ pmvBY->iMVX = NOT_MV; pmvBY->iMVY = NOT_MV; copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, MPEG4_OPAQUE); return (codeShapeModeInter (ALL_OPAQUE, shpmdColocatedMB)); case ALL_TRANSP:#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ("MB_ALL_TRANSP");#endif // __TRACE_AND_STATS_ pmvBY->iMVX = NOT_MV; pmvBY->iMVY = NOT_MV; copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, MPEG4_TRANSPARENT); return (codeShapeModeInter (ALL_TRANSP, shpmdColocatedMB)); case INTER_CAE_MVDZ: case INTER_CAE_MVDNZ: { if (m_bNoShapeChg) copyReconShapeToRef (ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER); else copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);#ifdef __TRACE_AND_STATS_ m_pbitstrmOut->trace ((PixelC *)m_puciPredBAB->pixels(), MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_PRED_BAB"); m_pbitstrmOut->trace (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, TOTAL_BAB_SIZE, "MB_RECON_BAB (Ignore Borders)"); m_pbitstrmOut->trace (m_rgpxlcCaeSymbol, m_iWidthCurrBAB , m_iWidthCurrBAB , "MB_ENCODED_BAB");#endif // __TRACE_AND_STATS_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -