📄 shape.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) Mathias Wien (wien@ient.rwth-aachen.de) RWTH Aachen / Robert BOSCH GmbHand also edited by Yoshinori Suzuki (Hitachi, Ltd.) 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.16 1999 : add Quarter Sample Mathias Wien (wien@ient.rwth-aachen.de) Feb.23 1999 : GMC added by Yoshinori Suzuki (Hitachi, Ltd.) *************************************************************************/#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"#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW #endif // __MFC_own Int* CVideoObject::computeShapeSubBlkIndex (Int iSubBlkSize, Int iSrcSize){ Int* rgiShapeSubBlkIndex = new Int [MB_SIZE * MB_SIZE / iSubBlkSize / iSubBlkSize]; Int nBorderLine = (iSrcSize - MB_SIZE) / 2; CoordI iX, iY, i = 0; for (iY = nBorderLine; iY < (MB_SIZE + nBorderLine); iY += iSubBlkSize) { for (iX = nBorderLine; iX < (MB_SIZE + nBorderLine); iX += iSubBlkSize) rgiShapeSubBlkIndex [i++] = iY * iSrcSize + iX; } return rgiShapeSubBlkIndex;}Void CVideoObject::downSampleShapeMCPred(const PixelC*ppxlcSrc, PixelC* ppxlcDst,Int iRate){ assert(iRate==1 || iRate==2 || iRate==4); static Int rgiScan[16] = {0,1,MC_BAB_SIZE,MC_BAB_SIZE+1, 2,3,MC_BAB_SIZE+2,MC_BAB_SIZE+3, 2*MC_BAB_SIZE,2*MC_BAB_SIZE+1,2*MC_BAB_SIZE+2,2*MC_BAB_SIZE+3, 3*MC_BAB_SIZE,3*MC_BAB_SIZE+1,3*MC_BAB_SIZE+2,3*MC_BAB_SIZE+3}; static Int rgiThresh[5] = {0,0,MPEG4_OPAQUE,0,7*MPEG4_OPAQUE}; Int iBdrThresh=0; if(iRate>2) iBdrThresh=MPEG4_OPAQUE; Int iThreshold = rgiThresh[iRate];#ifdef __TRACE_AND_STATS_ //m_pbitstrmOut->trace ((PixelC*)ppxlcSrc, MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_BAB_ORIG");#endif //__TRACE_AND_STATS_ const PixelC *ppxlcSrcScan = ppxlcSrc+(MC_BAB_SIZE+1)*MC_BAB_BORDER; Int iDstSize = 2*MC_BAB_BORDER+(MC_BAB_SIZE-2*MC_BAB_BORDER)/iRate; PixelC *ppxlcDstScan = ppxlcDst+(iDstSize+1)*MC_BAB_BORDER; Int iX,iY,i,iSum,iSum1,iSum2,iSum3,iSum4; Int iRateSqd=iRate*iRate; const PixelC *ppxlcSrcBdr1 = ppxlcSrc+MC_BAB_SIZE*MC_BAB_BORDER; const PixelC *ppxlcSrcBdr2 = ppxlcSrc+2*MC_BAB_SIZE-1; const PixelC *ppxlcSrcBdr3 = ppxlcSrc+MC_BAB_BORDER; const PixelC *ppxlcSrcBdr4 = ppxlcSrc+MC_BAB_SIZE*(MC_BAB_SIZE-1)+MC_BAB_BORDER; PixelC *ppxlcDstBdr1 = ppxlcDst+iDstSize*MC_BAB_BORDER; PixelC *ppxlcDstBdr2 = ppxlcDst+2*iDstSize-1; PixelC *ppxlcDstBdr3 = ppxlcDst+MC_BAB_BORDER; PixelC *ppxlcDstBdr4 = ppxlcDst+iDstSize*(iDstSize-1)+MC_BAB_BORDER; for(iY=MC_BAB_BORDER;iY<iDstSize-MC_BAB_BORDER;iY++) { for(iX=MC_BAB_BORDER;iX<iDstSize-MC_BAB_BORDER;iX++,ppxlcDstScan++) { iSum=0; for(i=0;i<iRateSqd;i++) iSum+=ppxlcSrcScan[rgiScan[i]]; *ppxlcDstScan=(iSum>iThreshold)?MPEG4_OPAQUE:MPEG4_TRANSPARENT; ppxlcSrcScan+=iRate; } ppxlcDstScan+=2*MC_BAB_BORDER; ppxlcSrcScan+=MC_BAB_SIZE*iRate-MC_BAB_SIZE+2*MC_BAB_BORDER; // border iSum1=iSum2=iSum3=iSum4=0; for(i=0;i<iRate;i++) { iSum1+=ppxlcSrcBdr1[i*MC_BAB_SIZE]; iSum2+=ppxlcSrcBdr2[i*MC_BAB_SIZE]; iSum3+=ppxlcSrcBdr3[i]; iSum4+=ppxlcSrcBdr4[i]; } *ppxlcDstBdr1=(iSum1>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT; *ppxlcDstBdr2=(iSum2>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT; *ppxlcDstBdr3++=(iSum3>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT; *ppxlcDstBdr4++=(iSum4>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT; ppxlcDstBdr1+=iDstSize; ppxlcDstBdr2+=iDstSize; ppxlcSrcBdr1+=MC_BAB_SIZE*iRate; ppxlcSrcBdr2+=MC_BAB_SIZE*iRate; ppxlcSrcBdr3+=iRate; ppxlcSrcBdr4+=iRate; } // corners ppxlcDst[0]=ppxlcSrc[0]; ppxlcDst[iDstSize-1]=ppxlcSrc[MC_BAB_SIZE-1]; ppxlcDst[(iDstSize-1)*iDstSize]=ppxlcSrc[(MC_BAB_SIZE-1)*MC_BAB_SIZE]; ppxlcDst[iDstSize*iDstSize-1]=ppxlcSrc[MC_BAB_SIZE*MC_BAB_SIZE-1];#ifdef __TRACE_AND_STATS_ //m_pbitstrmOut->trace ((PixelC*)ppxlcDst, iDstSize, iDstSize, "MB_MC_BAB_DOWN");#endif // __TRACE_AND_STATS_}Void CVideoObject::upSampleShape(PixelC*ppxlcBYFrm,const PixelC* rgpxlcSrc, PixelC* rgpxlcDst){ if(m_iInverseCR==2) adaptiveUpSampleShape(rgpxlcSrc, rgpxlcDst,8,8); else { static PixelC rgpxlcTmp[12*12]; assert(m_iInverseCR==4); adaptiveUpSampleShape(rgpxlcSrc, rgpxlcTmp,4,4); Int iSizeTmp=12; Int iSizeSrc=8; Int i,j; // top left corner rgpxlcTmp[0]=rgpxlcSrc[0]; rgpxlcTmp[1]=rgpxlcSrc[1]; rgpxlcTmp[iSizeTmp]=rgpxlcSrc[iSizeSrc]; rgpxlcTmp[iSizeTmp+1]=rgpxlcSrc[iSizeSrc+1]; // top right corner rgpxlcTmp[iSizeTmp-2]=rgpxlcSrc[iSizeSrc-2]; rgpxlcTmp[iSizeTmp-1]=rgpxlcSrc[iSizeSrc-1]; rgpxlcTmp[(iSizeTmp<<1)-2]=rgpxlcSrc[(iSizeSrc<<1)-2]; rgpxlcTmp[(iSizeTmp<<1)-1]=rgpxlcSrc[(iSizeSrc<<1)-1]; // top border for(j=0;j<2;j++) for(i=BAB_BORDER;i<iSizeTmp-BAB_BORDER;i++) rgpxlcTmp[j*iSizeTmp+i]=rgpxlcSrc[j*iSizeSrc+i/2+1]; // left border for(i=0;i<2;i++) for(j=BAB_BORDER;j<iSizeTmp-BAB_BORDER;j++) rgpxlcTmp[j*iSizeTmp+i]=rgpxlcSrc[(j/2+1)*iSizeSrc+i]; /*Int iTmp = m_iWidthCurrBAB; m_iInverseCR = 2; m_iWidthCurrBAB = 12; subsampleLeftTopBorderFromVOP (ppxlcBYFrm, rgpxlcTmp); m_iInverseCR = 4; m_iWidthCurrBAB = iTmp;*/ adaptiveUpSampleShape(rgpxlcTmp, rgpxlcDst,8,8); }}Int CVideoObject::getContextUS( PixelC a, PixelC b, PixelC c, PixelC d, PixelC e, PixelC f, PixelC g, PixelC h){ Int ret =(Int)(a+(b<<1)+(c<<2)+(d<<3)+(e<<4)+(f<<5)+(g<<6)+(h<<7)); return ret;}PixelC CVideoObject::getRefValue(const PixelC* ppxlcRow, Int x_adr, Int y_adr, Int h_size, Int v_size){ assert ((x_adr>=-2) && (x_adr<=h_size+1) && (y_adr>=-2) && (y_adr<=v_size+1)); Int x_lim, y_lim; PixelC ret; if(x_adr>=0 && x_adr<h_size && y_adr>=0 && y_adr<v_size) { ret=(ppxlcRow[y_adr*(h_size+BAB_BORDER_BOTH)+x_adr]>0) ? 1 : 0; } else { if(y_adr<0 || (x_adr<0 && y_adr<v_size)) { ret=(ppxlcRow[y_adr*(h_size+BAB_BORDER_BOTH)+x_adr]>0) ? 1 : 0; } else { x_lim=(x_adr<0)? 0: (x_adr>=h_size)? h_size-1 :x_adr; y_lim=(y_adr<0)? 0: (y_adr>=v_size)? v_size-1 :y_adr; ret=(ppxlcRow[y_lim*(h_size+BAB_BORDER_BOTH)+x_lim]>0) ? 1 : 0; } } return ret;}Void CVideoObject::adaptiveUpSampleShape (const PixelC* rgpxlcSrc, PixelC* rgpxlcDst, Int h_size, Int v_size){ Int x[12], y[12], other_total, context, rvalue, th, m; Int width_up = h_size << 1; Int width_up_border = width_up + BAB_BORDER_BOTH; Int j, i, py, px, py_st, py_en, px_st, px_en, py_p; PixelC val[12]; const PixelC* ppxlcRow = rgpxlcSrc + BAB_BORDER+BAB_BORDER * (h_size + BAB_BORDER_BOTH); /* -- 4 5 -- */ /* 6 0 1 7 */ /* 8 2 3 9 */ /* -- 10 11 -- */ for (j = -1; j < v_size; j++) { y[0] = y[1] = y[6] =y[7] = j; y[2] = y[3] = y[8] =y[9] = j + 1; y[4] = y[5] = j - 1; y[10]= y[11]= j + 2; if (j > -1) py_st = 0; else py_st = 1; if (j < v_size - 1) py_en = 2; else py_en = 1; for(i = -1; i < h_size; i++) { x[0] = x[2] = x[4] = x[10] = i; x[1] = x[3] = x[5] = x[11] = i+1; x[6] = x[8] = i - 1; x[7] = x[9] = i + 2; for(m = 0; m < 12; m++) val[m] = getRefValue (ppxlcRow, x[m], y[m], h_size, v_size); if (i > -1) px_st = 0; else px_st = 1; if (i < h_size-1) px_en = 2; else px_en=1; other_total = val[4] + val[5] + val[6] + val[7] + val[8] + val[9] + val[10] + val[11]; for (py = py_st; py < py_en; py++) { py_p = ((j << 1) + 1 + py + BAB_BORDER) * width_up_border + (i << 1) + 1; for (px = px_st; px < px_en; px++) { if(px < 1 && py < 1) { context = getContextUS (val[5], val[4], val[6], val[8], val[10], val[11], val[9], val[7]); th = grgchInterpolationFilterTh[context]; rvalue = (val[0] << 2) + ((val[1] + val[2] + val[3]) << 1) + other_total; } else if (py < 1) { context = getContextUS(val[9], val[7], val[5], val[4], val[6], val[8], val[10], val[11]); th = grgchInterpolationFilterTh [context]; rvalue = (val[1] << 2) + ((val[0] + val[2] + val[3]) << 1) + other_total; } else if (px < 1) { context = getContextUS(val[6], val[8], val[10], val[11], val[9], val[7], val[5], val[4]); th = grgchInterpolationFilterTh [context]; rvalue = (val[2] << 2) + ((val[1] + val[0] + val[3]) << 1) + other_total; } else { context = getContextUS(val[10], val[11], val[9], val[7], val[5], val[4], val[6], val[8]); th = grgchInterpolationFilterTh [context]; rvalue = (val[3] << 2) + ((val[1] + val[2] + val[0]) << 1) + other_total; } rgpxlcDst [py_p+(px+BAB_BORDER)] = (rvalue > th) ? opaqueValue: transpValue; } } } }}Void CVideoObject::copyLeftTopBorderFromVOP (PixelC* ppxlcSrc, PixelC* ppxlcDst){ PixelC* ppxlcSrcTop1 = ppxlcSrc - BAB_BORDER * m_iFrameWidthY - BAB_BORDER; PixelC* ppxlcSrcTop2 = ppxlcSrcTop1 + m_iFrameWidthY; PixelC* ppxlcSrcLeft1 = ppxlcSrcTop1; PixelC* ppxlcSrcLeft2 = ppxlcSrcLeft1 + 1; PixelC* ppxlcDstTop1 = ppxlcDst; PixelC* ppxlcDstTop2 = ppxlcDst + TOTAL_BAB_SIZE; PixelC* ppxlcDstLeft = ppxlcDst; CoordI iPixel;// Modified for error resilient mode by Toshiba(1997-11-14) for (iPixel = 0; iPixel < BAB_BORDER; iPixel++) { if (!m_bVPNoLeftTop) { ppxlcDstTop1 [iPixel] = *ppxlcSrcTop1; //src pixel never out of bound due to padding of Ref1 ppxlcDstTop2 [iPixel] = *ppxlcSrcTop2; //BY should be intialized as zero outside of VOP } else { ppxlcDstTop1 [iPixel] = (PixelC) 0; ppxlcDstTop2 [iPixel] = (PixelC) 0; } ppxlcSrcTop1++; ppxlcSrcTop2++; } for (iPixel = BAB_BORDER; iPixel < TOTAL_BAB_SIZE-BAB_BORDER; iPixel++) { if (!m_bVPNoTop) { ppxlcDstTop1 [iPixel] = *ppxlcSrcTop1; //src pixel never out of bound due to padding of Ref1 ppxlcDstTop2 [iPixel] = *ppxlcSrcTop2; //BY should be intialized as zero outside of VOP } else { ppxlcDstTop1 [iPixel] = (PixelC) 0; ppxlcDstTop2 [iPixel] = (PixelC) 0; } ppxlcSrcTop1++; ppxlcSrcTop2++; } for (iPixel = TOTAL_BAB_SIZE-BAB_BORDER; iPixel < TOTAL_BAB_SIZE; iPixel++) { if (!m_bVPNoRightTop) { ppxlcDstTop1 [iPixel] = *ppxlcSrcTop1; //src pixel never out of bound due to padding of Ref1 ppxlcDstTop2 [iPixel] = *ppxlcSrcTop2; //BY should be intialized as zero outside of VOP } else { ppxlcDstTop1 [iPixel] = (PixelC) 0; ppxlcDstTop2 [iPixel] = (PixelC) 0; } ppxlcSrcTop1++; ppxlcSrcTop2++; } ppxlcSrcLeft1 += BAB_BORDER*m_iFrameWidthY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -