shape.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:24k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
  4. (April, 1997)
  5. and edited by
  6.         Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center
  7. and also edited by
  8. Yoshihiro Kikuchi (TOSHIBA CORPORATION)
  9. Takeshi Nagai (TOSHIBA CORPORATION)
  10. Toshiaki Watanabe (TOSHIBA CORPORATION)
  11. Noboru Yamaguchi (TOSHIBA CORPORATION)
  12. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  13. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  14. as specified by the MPEG-4 Video. 
  15. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  16. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  17. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  18. The original developer of this software module and his/her company, 
  19. the subsequent editors and their companies, 
  20. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  21. Copyright is not released for non MPEG-4 Video conforming products. 
  22. Microsoft retains full right to use the code for his/her own purpose, 
  23. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  24. This copyright notice must be included in all copies or derivative works. 
  25. Copyright (c) 1996, 1997.
  26. Module Name:
  27. shpenc.hpp
  28. Abstract:
  29. binary shape encoder with context-based arithmatic coder
  30. Revision History:
  31. *************************************************************************/
  32. #include "typeapi.h"
  33. #include "entropy/entropy.hpp"
  34. #include "entropy/huffman.hpp"
  35. #include "entropy/bitstrm.hpp"
  36. #include "global.hpp"
  37. #include "mode.hpp"
  38. #include "codehead.h"
  39. #include "cae.h"
  40. #include "vopses.hpp"
  41. #ifdef __MFC_
  42. #ifdef _DEBUG
  43. #undef THIS_FILE
  44. static char BASED_CODE THIS_FILE[] = __FILE__;
  45. #endif
  46. #define new DEBUG_NEW    
  47. #endif // __MFC_
  48. own Int* CVideoObject::computeShapeSubBlkIndex (Int iSubBlkSize, Int iSrcSize)
  49. {
  50. Int* rgiShapeSubBlkIndex = new Int [MB_SIZE * MB_SIZE / iSubBlkSize / iSubBlkSize];
  51. Int nBorderLine = (iSrcSize - MB_SIZE) / 2;
  52. CoordI iX, iY, i = 0;
  53. for (iY = nBorderLine; iY < (MB_SIZE + nBorderLine); iY += iSubBlkSize) {
  54. for (iX = nBorderLine; iX < (MB_SIZE + nBorderLine); iX += iSubBlkSize)
  55. rgiShapeSubBlkIndex [i++] = iY * iSrcSize + iX;
  56. }
  57. return rgiShapeSubBlkIndex;
  58. }
  59. Void CVideoObject::downSampleShapeMCPred(const PixelC*ppxlcSrc,
  60. PixelC* ppxlcDst,Int iRate)
  61. {
  62. assert(iRate==1 || iRate==2 || iRate==4);
  63. static Int rgiScan[16] = {0,1,MC_BAB_SIZE,MC_BAB_SIZE+1,
  64. 2,3,MC_BAB_SIZE+2,MC_BAB_SIZE+3,
  65. 2*MC_BAB_SIZE,2*MC_BAB_SIZE+1,2*MC_BAB_SIZE+2,2*MC_BAB_SIZE+3,
  66. 3*MC_BAB_SIZE,3*MC_BAB_SIZE+1,3*MC_BAB_SIZE+2,3*MC_BAB_SIZE+3};
  67. static Int rgiThresh[5] = {0,0,MPEG4_OPAQUE,0,7*MPEG4_OPAQUE};
  68. Int iBdrThresh=0;
  69. if(iRate>2)
  70. iBdrThresh=MPEG4_OPAQUE;
  71. Int iThreshold = rgiThresh[iRate];
  72. #ifdef __TRACE_AND_STATS_
  73. //m_pbitstrmOut->trace ((PixelC*)ppxlcSrc, MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_BAB_ORIG");
  74. #endif //__TRACE_AND_STATS_
  75. const PixelC *ppxlcSrcScan = ppxlcSrc+(MC_BAB_SIZE+1)*MC_BAB_BORDER;
  76. Int iDstSize = 2*MC_BAB_BORDER+(MC_BAB_SIZE-2*MC_BAB_BORDER)/iRate;
  77. PixelC *ppxlcDstScan = ppxlcDst+(iDstSize+1)*MC_BAB_BORDER;
  78. Int iX,iY,i,iSum,iSum1,iSum2,iSum3,iSum4;
  79. Int iRateSqd=iRate*iRate;
  80. const PixelC *ppxlcSrcBdr1 = ppxlcSrc+MC_BAB_SIZE*MC_BAB_BORDER;
  81. const PixelC *ppxlcSrcBdr2 = ppxlcSrc+2*MC_BAB_SIZE-1;
  82. const PixelC *ppxlcSrcBdr3 = ppxlcSrc+MC_BAB_BORDER;
  83. const PixelC *ppxlcSrcBdr4 = ppxlcSrc+MC_BAB_SIZE*(MC_BAB_SIZE-1)+MC_BAB_BORDER;
  84. PixelC *ppxlcDstBdr1 = ppxlcDst+iDstSize*MC_BAB_BORDER;
  85. PixelC *ppxlcDstBdr2 = ppxlcDst+2*iDstSize-1;
  86. PixelC *ppxlcDstBdr3 = ppxlcDst+MC_BAB_BORDER;
  87. PixelC *ppxlcDstBdr4 = ppxlcDst+iDstSize*(iDstSize-1)+MC_BAB_BORDER;
  88. for(iY=MC_BAB_BORDER;iY<iDstSize-MC_BAB_BORDER;iY++)
  89. {
  90. for(iX=MC_BAB_BORDER;iX<iDstSize-MC_BAB_BORDER;iX++,ppxlcDstScan++)
  91. {
  92. iSum=0;
  93. for(i=0;i<iRateSqd;i++)
  94. iSum+=ppxlcSrcScan[rgiScan[i]];
  95. *ppxlcDstScan=(iSum>iThreshold)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
  96. ppxlcSrcScan+=iRate;
  97. }
  98. ppxlcDstScan+=2*MC_BAB_BORDER;
  99. ppxlcSrcScan+=MC_BAB_SIZE*iRate-MC_BAB_SIZE+2*MC_BAB_BORDER;
  100. // border
  101. iSum1=iSum2=iSum3=iSum4=0;
  102. for(i=0;i<iRate;i++)
  103. {
  104. iSum1+=ppxlcSrcBdr1[i*MC_BAB_SIZE];
  105. iSum2+=ppxlcSrcBdr2[i*MC_BAB_SIZE];
  106. iSum3+=ppxlcSrcBdr3[i];
  107. iSum4+=ppxlcSrcBdr4[i];
  108. }
  109. *ppxlcDstBdr1=(iSum1>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
  110. *ppxlcDstBdr2=(iSum2>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
  111. *ppxlcDstBdr3++=(iSum3>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
  112. *ppxlcDstBdr4++=(iSum4>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
  113. ppxlcDstBdr1+=iDstSize;
  114. ppxlcDstBdr2+=iDstSize;
  115. ppxlcSrcBdr1+=MC_BAB_SIZE*iRate;
  116. ppxlcSrcBdr2+=MC_BAB_SIZE*iRate;
  117. ppxlcSrcBdr3+=iRate;
  118. ppxlcSrcBdr4+=iRate;
  119. }
  120. // corners
  121. ppxlcDst[0]=ppxlcSrc[0];
  122. ppxlcDst[iDstSize-1]=ppxlcSrc[MC_BAB_SIZE-1];
  123. ppxlcDst[(iDstSize-1)*iDstSize]=ppxlcSrc[(MC_BAB_SIZE-1)*MC_BAB_SIZE];
  124. ppxlcDst[iDstSize*iDstSize-1]=ppxlcSrc[MC_BAB_SIZE*MC_BAB_SIZE-1];
  125. #ifdef __TRACE_AND_STATS_
  126. //m_pbitstrmOut->trace ((PixelC*)ppxlcDst, iDstSize, iDstSize, "MB_MC_BAB_DOWN");
  127. #endif // __TRACE_AND_STATS_
  128. }
  129. Void CVideoObject::upSampleShape(PixelC*ppxlcBYFrm,const PixelC* rgpxlcSrc, PixelC* rgpxlcDst)
  130. {
  131. if(m_iInverseCR==2)
  132. adaptiveUpSampleShape(rgpxlcSrc, rgpxlcDst,8,8);
  133. else
  134. {
  135. static PixelC rgpxlcTmp[12*12];
  136. assert(m_iInverseCR==4);
  137. adaptiveUpSampleShape(rgpxlcSrc, rgpxlcTmp,4,4);
  138. Int iSizeTmp=12;
  139. Int iSizeSrc=8;
  140. Int i,j;
  141. // top left corner 
  142. rgpxlcTmp[0]=rgpxlcSrc[0];
  143. rgpxlcTmp[1]=rgpxlcSrc[1];
  144. rgpxlcTmp[iSizeTmp]=rgpxlcSrc[iSizeSrc];
  145. rgpxlcTmp[iSizeTmp+1]=rgpxlcSrc[iSizeSrc+1];
  146. // top right corner
  147. rgpxlcTmp[iSizeTmp-2]=rgpxlcSrc[iSizeSrc-2];
  148. rgpxlcTmp[iSizeTmp-1]=rgpxlcSrc[iSizeSrc-1];
  149. rgpxlcTmp[(iSizeTmp<<1)-2]=rgpxlcSrc[(iSizeSrc<<1)-2];
  150. rgpxlcTmp[(iSizeTmp<<1)-1]=rgpxlcSrc[(iSizeSrc<<1)-1];
  151. // top border
  152. for(j=0;j<2;j++)
  153. for(i=BAB_BORDER;i<iSizeTmp-BAB_BORDER;i++)
  154. rgpxlcTmp[j*iSizeTmp+i]=rgpxlcSrc[j*iSizeSrc+i/2+1];
  155. // left border 
  156. for(i=0;i<2;i++)
  157. for(j=BAB_BORDER;j<iSizeTmp-BAB_BORDER;j++)
  158. rgpxlcTmp[j*iSizeTmp+i]=rgpxlcSrc[(j/2+1)*iSizeSrc+i];
  159. /*Int iTmp = m_iWidthCurrBAB;
  160. m_iInverseCR = 2;
  161. m_iWidthCurrBAB = 12;
  162. subsampleLeftTopBorderFromVOP (ppxlcBYFrm, rgpxlcTmp);
  163. m_iInverseCR = 4;
  164. m_iWidthCurrBAB = iTmp;*/
  165. adaptiveUpSampleShape(rgpxlcTmp, rgpxlcDst,8,8);
  166. }
  167. }
  168. Int CVideoObject::getContextUS( PixelC a,
  169.                                 PixelC b,
  170.                                 PixelC c,
  171.                                 PixelC d,
  172.                                 PixelC e,
  173.                                 PixelC f,
  174.                                 PixelC g,
  175.                                 PixelC h)
  176. {
  177.         Int     ret =(Int)(a+(b<<1)+(c<<2)+(d<<3)+(e<<4)+(f<<5)+(g<<6)+(h<<7));
  178.  
  179.         return  ret;
  180. }
  181. PixelC CVideoObject::getRefValue(const PixelC* ppxlcRow,
  182.                                 Int x_adr, Int y_adr,
  183.                                 Int h_size, Int v_size)
  184. {
  185.         assert ((x_adr>=-2) && (x_adr<=h_size+1) && (y_adr>=-2) && (y_adr<=v_size+1));
  186.  
  187.         Int     x_lim, y_lim;
  188.         PixelC  ret;
  189.  
  190.         if(x_adr>=0 && x_adr<h_size && y_adr>=0 && y_adr<v_size) {
  191.                 ret=(ppxlcRow[y_adr*(h_size+BAB_BORDER_BOTH)+x_adr]>0) ? 1 : 0;
  192.         } else {
  193.                 if(y_adr<0 || (x_adr<0 && y_adr<v_size)) {
  194. ret=(ppxlcRow[y_adr*(h_size+BAB_BORDER_BOTH)+x_adr]>0) ? 1 : 0;
  195.                 } else {
  196.                         x_lim=(x_adr<0)? 0: (x_adr>=h_size)? h_size-1 :x_adr;
  197.                         y_lim=(y_adr<0)? 0: (y_adr>=v_size)? v_size-1 :y_adr;
  198.                         ret=(ppxlcRow[y_lim*(h_size+BAB_BORDER_BOTH)+x_lim]>0) ? 1 : 0;
  199.                 }
  200.         }
  201.  
  202.         return ret;
  203. }
  204. Void CVideoObject::adaptiveUpSampleShape (const PixelC* rgpxlcSrc, 
  205. PixelC* rgpxlcDst,
  206. Int h_size, Int v_size)
  207. {
  208. Int x[12], y[12], other_total, context, rvalue, th, m;
  209. Int width_up = h_size << 1;
  210. Int width_up_border = width_up + BAB_BORDER_BOTH;
  211. Int j, i, py, px, py_st, py_en, px_st, px_en, py_p;
  212. PixelC val[12];
  213. const PixelC* ppxlcRow = rgpxlcSrc + BAB_BORDER+BAB_BORDER * (h_size + BAB_BORDER_BOTH);
  214. /* --  4  5 -- */
  215. /*  6  0  1  7 */
  216. /*  8  2  3  9 */
  217. /* -- 10 11 -- */
  218. for (j = -1; j < v_size; j++) {
  219. y[0] = y[1] = y[6] =y[7] = j;
  220. y[2] = y[3] = y[8] =y[9] = j + 1;
  221. y[4] = y[5] = j - 1;
  222. y[10]= y[11]= j + 2;
  223. if (j > -1) 
  224. py_st = 0;
  225. else  
  226. py_st = 1;
  227. if (j < v_size - 1) 
  228. py_en = 2;
  229. else        
  230. py_en = 1;
  231. for(i = -1; i < h_size; i++) {
  232. x[0] = x[2] = x[4] = x[10] = i;
  233. x[1] = x[3] = x[5] = x[11] = i+1;
  234. x[6] = x[8] = i - 1;
  235. x[7] = x[9] = i + 2;
  236. for(m = 0; m < 12; m++)
  237. val[m] = getRefValue (ppxlcRow, x[m], y[m], h_size, v_size);
  238. if (i > -1) 
  239. px_st = 0;
  240. else     
  241. px_st = 1;
  242. if (i < h_size-1) 
  243. px_en = 2;
  244. else   
  245. px_en=1;
  246. other_total = val[4] + val[5] + val[6] + val[7] + val[8] + val[9] + val[10] + val[11];
  247. for (py = py_st; py < py_en; py++) {
  248. py_p = ((j << 1) + 1 + py + BAB_BORDER) * width_up_border + (i << 1) + 1;
  249. for (px = px_st; px < px_en; px++) {
  250. if(px < 1 && py < 1) {
  251. context = getContextUS (val[5], val[4], val[6], val[8], val[10], val[11], val[9], val[7]);
  252. th = grgchInterpolationFilterTh[context];
  253. rvalue = (val[0] << 2) + ((val[1] + val[2] + val[3]) << 1) + other_total;
  254. else if (py < 1) {
  255. context = getContextUS(val[9], val[7], val[5], val[4], val[6], val[8], val[10], val[11]);
  256. th = grgchInterpolationFilterTh [context];
  257. rvalue = (val[1] << 2) + ((val[0] + val[2] + val[3]) << 1) + other_total;
  258. else if (px < 1) {
  259. context = getContextUS(val[6], val[8], val[10], val[11], val[9], val[7], val[5], val[4]);
  260. th = grgchInterpolationFilterTh [context];
  261. rvalue = (val[2] << 2) + ((val[1] + val[0] + val[3]) << 1) + other_total;
  262. else {
  263. context = getContextUS(val[10], val[11], val[9], val[7], val[5], val[4], val[6], val[8]);
  264. th = grgchInterpolationFilterTh [context];
  265. rvalue = (val[3] << 2) + ((val[1] + val[2] + val[0]) << 1) + other_total;
  266. }
  267. rgpxlcDst [py_p+(px+BAB_BORDER)] = (rvalue > th) ? opaqueValue: transpValue;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. Void CVideoObject::copyLeftTopBorderFromVOP (PixelC* ppxlcSrc, PixelC* ppxlcDst)
  274. {
  275. PixelC* ppxlcSrcTop1  = ppxlcSrc - BAB_BORDER  * m_iFrameWidthY - BAB_BORDER;
  276. PixelC* ppxlcSrcTop2  = ppxlcSrcTop1 + m_iFrameWidthY;
  277. PixelC* ppxlcSrcLeft1 = ppxlcSrcTop1;
  278. PixelC* ppxlcSrcLeft2 = ppxlcSrcLeft1 + 1;
  279. PixelC* ppxlcDstTop1  = ppxlcDst;
  280. PixelC* ppxlcDstTop2  = ppxlcDst + TOTAL_BAB_SIZE;
  281. PixelC* ppxlcDstLeft  = ppxlcDst;
  282. CoordI iPixel;
  283. // Modified for error resilient mode by Toshiba(1997-11-14)
  284. for (iPixel = 0; iPixel < BAB_BORDER; iPixel++) {
  285. if (!m_bVPNoLeftTop) {
  286. ppxlcDstTop1 [iPixel]  = *ppxlcSrcTop1;
  287. //src pixel never out of bound due to padding of Ref1
  288. ppxlcDstTop2 [iPixel]  = *ppxlcSrcTop2;
  289. //BY should be intialized as zero outside of VOP
  290. }
  291. else {
  292. ppxlcDstTop1 [iPixel]  = (PixelC) 0;
  293. ppxlcDstTop2 [iPixel]  = (PixelC) 0;
  294. }
  295. ppxlcSrcTop1++; 
  296. ppxlcSrcTop2++; 
  297. }
  298. for (iPixel = BAB_BORDER; iPixel < TOTAL_BAB_SIZE-BAB_BORDER; iPixel++) {
  299. if (!m_bVPNoTop) {
  300. ppxlcDstTop1 [iPixel]  = *ppxlcSrcTop1;
  301. //src pixel never out of bound due to padding of Ref1
  302. ppxlcDstTop2 [iPixel]  = *ppxlcSrcTop2;
  303. //BY should be intialized as zero outside of VOP
  304. }
  305. else {
  306. ppxlcDstTop1 [iPixel]  = (PixelC) 0;
  307. ppxlcDstTop2 [iPixel]  = (PixelC) 0;
  308. }
  309. ppxlcSrcTop1++; 
  310. ppxlcSrcTop2++; 
  311. }
  312. for (iPixel = TOTAL_BAB_SIZE-BAB_BORDER; iPixel < TOTAL_BAB_SIZE; iPixel++) {
  313. if (!m_bVPNoRightTop) {
  314. ppxlcDstTop1 [iPixel]  = *ppxlcSrcTop1;
  315. //src pixel never out of bound due to padding of Ref1
  316. ppxlcDstTop2 [iPixel]  = *ppxlcSrcTop2;
  317. //BY should be intialized as zero outside of VOP
  318. }
  319. else {
  320. ppxlcDstTop1 [iPixel]  = (PixelC) 0;
  321. ppxlcDstTop2 [iPixel]  = (PixelC) 0;
  322. }
  323. ppxlcSrcTop1++; 
  324. ppxlcSrcTop2++; 
  325. }
  326. ppxlcSrcLeft1 += BAB_BORDER*m_iFrameWidthY; 
  327. ppxlcSrcLeft2 += BAB_BORDER*m_iFrameWidthY; 
  328. ppxlcDstLeft += BAB_BORDER*TOTAL_BAB_SIZE;
  329. for (iPixel = BAB_BORDER; iPixel < TOTAL_BAB_SIZE; iPixel++) {
  330. if (!m_bVPNoLeft) {
  331. *ppxlcDstLeft = *ppxlcSrcLeft1;
  332. *(ppxlcDstLeft + 1) = *ppxlcSrcLeft2;
  333. }
  334. else {
  335. *ppxlcDstLeft = (PixelC) 0;
  336. *(ppxlcDstLeft + 1) = (PixelC) 0;
  337. }
  338. ppxlcSrcLeft1 += m_iFrameWidthY; 
  339. ppxlcSrcLeft2 += m_iFrameWidthY; 
  340. ppxlcDstLeft += TOTAL_BAB_SIZE; //last two values of left border will be over written after the loop
  341. }
  342. //repeat pad the left border (this will be done again in right bottom border; improve in the future)
  343. if (!m_bVPNoLeft) {
  344. Int iLastValidSrcLeft1 = *(ppxlcSrcLeft1 - (BAB_BORDER+1) * m_iFrameWidthY);
  345. Int iLastValidSrcLeft2 = *(ppxlcSrcLeft2 - (BAB_BORDER+1) * m_iFrameWidthY);
  346. for (iPixel = 0; iPixel < BAB_BORDER; iPixel++) {
  347. ppxlcDstLeft -= TOTAL_BAB_SIZE;
  348. *ppxlcDstLeft       = iLastValidSrcLeft1;
  349. *(ppxlcDstLeft + 1) = iLastValidSrcLeft2;
  350. }
  351. }
  352. // End Toshiba(1997-11-14)
  353. }
  354. Void CVideoObject::subsampleLeftTopBorderFromVOP (PixelC* ppxlcSrc, PixelC* ppxlcDst)
  355. {
  356. PixelC* ppxlcSrcTop1 = ppxlcSrc - BAB_BORDER  * m_iFrameWidthY - BAB_BORDER;
  357. PixelC* ppxlcSrcTop2 = ppxlcSrcTop1 + m_iFrameWidthY;
  358. PixelC* ppxlcSrcLft1 = ppxlcSrcTop1;
  359. PixelC* ppxlcSrcLft2 = ppxlcSrcLft1 + 1;
  360. PixelC* ppxlcDstTop1 = ppxlcDst;
  361. PixelC* ppxlcDstTop2 = ppxlcDst + m_iWidthCurrBAB;
  362. PixelC* ppxlcDstLft1 = ppxlcDst;
  363. PixelC* ppxlcDstLft2 = ppxlcDst + 1;
  364. Int iThresh = (m_iInverseCR == 2) ? 0 : opaqueValue;
  365. CoordI iPixel, iPixelSub, iSampleInterval;
  366. // Modified for error resilient mode by Toshiba(1997-11-14)
  367. for (iPixelSub = BAB_BORDER, iSampleInterval = BAB_BORDER; 
  368. iPixelSub < m_iWidthCurrBAB - BAB_BORDER; 
  369. iPixelSub++, iSampleInterval += m_iInverseCR) { //get each subsample
  370. Int iTempSumTop1 = 0, iTempSumTop2 = 0; 
  371. Int iTempSumLft1 = 0, iTempSumLft2 = 0;
  372. for (iPixel = 0; iPixel < m_iInverseCR; iPixel++) {
  373. iTempSumTop1 += ppxlcSrcTop1 [iSampleInterval + iPixel];
  374. iTempSumTop2 += ppxlcSrcTop2 [iSampleInterval + iPixel];
  375. iTempSumLft1 += ppxlcSrcLft1 [(iSampleInterval + iPixel) * m_iFrameWidthY];
  376. iTempSumLft2 += ppxlcSrcLft2 [(iSampleInterval + iPixel) * m_iFrameWidthY];
  377. }
  378. if (!m_bVPNoTop) {
  379. ppxlcDstTop1 [iPixelSub] = (iTempSumTop1 > iThresh) ? opaqueValue : transpValue;
  380. ppxlcDstTop2 [iPixelSub] = (iTempSumTop2 > iThresh) ? opaqueValue : transpValue;
  381. }
  382. else {
  383. ppxlcDstTop1 [iPixelSub] = 0;
  384. ppxlcDstTop2 [iPixelSub] = 0;
  385. }
  386. if (!m_bVPNoLeft) {
  387. ppxlcDstLft1 [iPixelSub * m_iWidthCurrBAB] = (iTempSumLft1 > iThresh) ? opaqueValue : transpValue;
  388. ppxlcDstLft2 [iPixelSub * m_iWidthCurrBAB] = (iTempSumLft2 > iThresh) ? opaqueValue : transpValue;
  389. }
  390. else {
  391. ppxlcDstLft1 [iPixelSub * m_iWidthCurrBAB] = 0;
  392. ppxlcDstLft2 [iPixelSub * m_iWidthCurrBAB] = 0;
  393. }
  394. }
  395. //boundary conditions 0, 1, 18, 19 
  396. CoordI iBorder;
  397. for (iBorder = 0; iBorder < BAB_BORDER; iBorder++) {
  398. if (!m_bVPNoLeftTop) {
  399. ppxlcDstTop1 [iBorder] = ppxlcSrcTop1 [iBorder];
  400. ppxlcDstTop2 [iBorder] = ppxlcSrcTop2 [iBorder];
  401. }
  402. else {
  403. ppxlcDstTop1 [iBorder] = 0;
  404. ppxlcDstTop2 [iBorder] = 0;
  405. }
  406. if (!m_bVPNoRightTop) {
  407. ppxlcDstTop1 [m_iWidthCurrBAB - 1 - iBorder] = ppxlcSrcTop1 [TOTAL_BAB_SIZE - 1 - iBorder];
  408. ppxlcDstTop2 [m_iWidthCurrBAB - 1 - iBorder] = ppxlcSrcTop2 [TOTAL_BAB_SIZE - 1 - iBorder];
  409. }
  410. else {
  411. ppxlcDstTop1 [m_iWidthCurrBAB - 1 - iBorder] = 0;
  412. ppxlcDstTop2 [m_iWidthCurrBAB - 1 - iBorder] = 0;
  413. }
  414. }
  415. // End Toshiba(1997-11-14)
  416. //repeat pad left-bottom corner
  417. ppxlcDstLft1 [(m_iWidthCurrBAB - 1) * m_iWidthCurrBAB] = 
  418. ppxlcDstLft1 [(m_iWidthCurrBAB - 2) * m_iWidthCurrBAB] =
  419. ppxlcDstLft1 [(m_iWidthCurrBAB - 3) * m_iWidthCurrBAB];
  420. ppxlcDstLft2 [(m_iWidthCurrBAB - 1) * m_iWidthCurrBAB] =
  421. ppxlcDstLft2 [(m_iWidthCurrBAB - 2) * m_iWidthCurrBAB] =
  422. ppxlcDstLft2 [(m_iWidthCurrBAB - 3) * m_iWidthCurrBAB];
  423. }
  424. Void CVideoObject::makeRightBottomBorder (PixelC* ppxlcSrc, Int iWidth)
  425. {
  426. Int i;
  427. PixelC* ppxlcDst = ppxlcSrc + BAB_BORDER * iWidth + iWidth - BAB_BORDER; //make right border
  428. for (i = 0; i < iWidth - 2*BAB_BORDER; i++) {
  429. *ppxlcDst = *(ppxlcDst - 1);
  430. *(ppxlcDst + 1) = *ppxlcDst;
  431. ppxlcDst += iWidth;
  432. }
  433. ppxlcDst = ppxlcSrc + (iWidth - BAB_BORDER) * iWidth; //make bottom border
  434. for (i = 0; i < iWidth; i++) {
  435. *ppxlcDst = *(ppxlcDst - iWidth);
  436. *(ppxlcDst + iWidth) = *ppxlcDst;
  437. ppxlcDst++;
  438. }
  439. }
  440. Int CVideoObject::contextIntra (const PixelC* ppxlcSrc)
  441. {
  442. Int iContext = 0, i;
  443. static Int rgiNeighbourIndx [10];
  444. rgiNeighbourIndx [0] = -1;
  445. rgiNeighbourIndx [1] = -2;
  446. rgiNeighbourIndx [2] = -m_iWidthCurrBAB + 2;
  447. rgiNeighbourIndx [3] = -m_iWidthCurrBAB + 1;
  448. rgiNeighbourIndx [4] = -m_iWidthCurrBAB;
  449. rgiNeighbourIndx [5] = -m_iWidthCurrBAB - 1;
  450. rgiNeighbourIndx [6] = -m_iWidthCurrBAB - 2;
  451. rgiNeighbourIndx [7] = -2 * m_iWidthCurrBAB + 1;
  452. rgiNeighbourIndx [8] = -2 * m_iWidthCurrBAB;
  453. rgiNeighbourIndx [9] = -2 * m_iWidthCurrBAB - 1;
  454. for (i = 0; i < 10; i++)
  455. iContext += (ppxlcSrc [rgiNeighbourIndx [i]] == MPEG4_OPAQUE) << i;
  456. assert (iContext >= 0 && iContext < 1024);
  457. return iContext;
  458. }
  459. Int CVideoObject::contextIntraTranspose (const PixelC* ppxlcSrc)
  460. {
  461. Int iContext = 0, i;
  462. static Int rgiNeighbourIndx [10];
  463. rgiNeighbourIndx [0] = -m_iWidthCurrBAB;
  464. rgiNeighbourIndx [1] = -2 * m_iWidthCurrBAB;
  465. rgiNeighbourIndx [2] = -1 + 2 * m_iWidthCurrBAB;
  466. rgiNeighbourIndx [3] = -1 + m_iWidthCurrBAB;
  467. rgiNeighbourIndx [4] = -1;
  468. rgiNeighbourIndx [5] = -m_iWidthCurrBAB - 1;
  469. rgiNeighbourIndx [6] = -1 - 2 * m_iWidthCurrBAB;
  470. rgiNeighbourIndx [7] = -2 + m_iWidthCurrBAB;
  471. rgiNeighbourIndx [8] = -2;
  472. rgiNeighbourIndx [9] = -2 - m_iWidthCurrBAB;
  473. for (i = 0; i < 10; i++)
  474. iContext += (ppxlcSrc [rgiNeighbourIndx [i]] == MPEG4_OPAQUE) << i;
  475. assert (iContext >= 0 && iContext < 1024);
  476. return iContext;
  477. }
  478. Int CVideoObject::contextInter (const PixelC* ppxlcSrc, const PixelC* ppxlcPred)
  479. {
  480. Int i, iContext = 0;
  481. static Int rgiNeighbourIndx [9];
  482. Int iSizePredBAB = m_iWidthCurrBAB - 2*BAB_BORDER + 2*MC_BAB_BORDER;
  483. rgiNeighbourIndx [0] = -1;
  484. rgiNeighbourIndx [1] = -m_iWidthCurrBAB + 1;
  485. rgiNeighbourIndx [2] = -m_iWidthCurrBAB;
  486. rgiNeighbourIndx [3] = -m_iWidthCurrBAB - 1;
  487. rgiNeighbourIndx [4] = iSizePredBAB;
  488. rgiNeighbourIndx [5] = 1;
  489. rgiNeighbourIndx [6] = 0;
  490. rgiNeighbourIndx [7] = -1;
  491. rgiNeighbourIndx [8] = -iSizePredBAB;
  492. for (i = 0; i < 4; i++) {
  493. iContext += (ppxlcSrc [rgiNeighbourIndx [i]] == MPEG4_OPAQUE) << i;
  494. }
  495. for (i = 4; i < 9; i++) {
  496. iContext += (ppxlcPred [rgiNeighbourIndx [i]] == MPEG4_OPAQUE) << i;
  497. }
  498. assert (iContext >= 0 && iContext < 1024);
  499. return iContext;
  500. }
  501. Int CVideoObject::contextInterTranspose (const PixelC* ppxlcSrc, const PixelC* ppxlcPred)
  502. {
  503. Int i, iContext = 0;
  504. static Int rgiNeighbourIndx [9];
  505. Int iSizePredBAB = m_iWidthCurrBAB - 2*BAB_BORDER + 2*MC_BAB_BORDER;
  506. rgiNeighbourIndx [0] = -m_iWidthCurrBAB;
  507. rgiNeighbourIndx [1] = m_iWidthCurrBAB - 1;
  508. rgiNeighbourIndx [2] = -1;
  509. rgiNeighbourIndx [3] = -m_iWidthCurrBAB - 1;
  510. rgiNeighbourIndx [4] = 1;
  511. rgiNeighbourIndx [5] = iSizePredBAB;
  512. rgiNeighbourIndx [6] = 0;
  513. rgiNeighbourIndx [7] = -iSizePredBAB;
  514. rgiNeighbourIndx [8] = -1;
  515. for (i = 0; i < 4; i++)
  516. iContext += (ppxlcSrc [rgiNeighbourIndx [i]] == MPEG4_OPAQUE) << i;
  517. for (i = 4; i < 9; i++)
  518. iContext += (ppxlcPred [rgiNeighbourIndx [i]] == MPEG4_OPAQUE) << i;
  519. assert (iContext >= 0 && iContext < 1024);
  520. return iContext;
  521. }
  522. Void CVideoObject::copyReconShapeToMbAndRef (
  523. PixelC* ppxlcDstMB, 
  524. PixelC* ppxlcRefFrm, PixelC pxlcSrc
  525. )
  526. {
  527. pxlcmemset (ppxlcDstMB, pxlcSrc, MB_SQUARE_SIZE); // Modified by swinder
  528. for (Int i = 0; i < MB_SIZE; i++) {
  529. pxlcmemset (ppxlcRefFrm, pxlcSrc, MB_SIZE);
  530. ppxlcRefFrm += m_iFrameWidthY;
  531. }
  532. }
  533. Void CVideoObject::copyReconShapeUVToRef (
  534. PixelC* ppxlcRefFrm, const PixelC* ppxlcSrc)
  535. {
  536. for (Int i = 0; i < BLOCK_SIZE; i++) {
  537. memcpy (ppxlcRefFrm, ppxlcSrc, BLOCK_SIZE*sizeof(PixelC));
  538. ppxlcRefFrm += m_iFrameWidthUV;
  539. ppxlcSrc += BLOCK_SIZE;
  540. }
  541. }
  542. Void CVideoObject::copyReconShapeToMbAndRef (
  543. PixelC* ppxlcDstMB, 
  544. PixelC* ppxlcRefFrm, 
  545. const PixelC* ppxlcSrc, Int iSrcWidth, Int iBorder
  546. )
  547. {
  548. Int iUnit = sizeof(PixelC); // NBIT: for memcpy
  549. ppxlcSrc += iSrcWidth * iBorder + iBorder;
  550. for (Int i = 0; i < MB_SIZE; i++) {
  551. memcpy (ppxlcDstMB, ppxlcSrc, MB_SIZE*iUnit);
  552. memcpy (ppxlcRefFrm, ppxlcSrc, MB_SIZE*iUnit);
  553. ppxlcRefFrm += m_iFrameWidthY;
  554. ppxlcDstMB  += MB_SIZE;
  555. ppxlcSrc += iSrcWidth;
  556. }
  557. }
  558. CMotionVector CVideoObject::findShapeMVP (
  559. const CMotionVector* pmv, const CMotionVector* pmvBY, 
  560. const CMBMode* pmbmd,
  561. Int iMBX, Int iMBY
  562. ) const
  563. {
  564. CMotionVector mvRet;
  565. // try shape vector first
  566. Bool bLeftBndry, bRightBndry, bTopBndry;
  567. Int iMBnum = VPMBnum(iMBX, iMBY);
  568. bLeftBndry = bVPNoLeft(iMBnum, iMBX);
  569. bTopBndry = bVPNoTop(iMBnum);
  570. bRightBndry = bVPNoRightTop(iMBnum, iMBX);
  571. mvRet = *(pmvBY - 1);
  572. // Modified for error resilient mode by Toshiba(1997-11-14)
  573. // if ((iMBX > 0) && ((pmbmd - 1)->m_shpmd == INTER_CAE_MVDZ ||
  574. if (!bLeftBndry && ((pmbmd - 1)->m_shpmd == INTER_CAE_MVDZ ||
  575. (pmbmd - 1)->m_shpmd == INTER_CAE_MVDNZ ||
  576. (pmbmd - 1)->m_shpmd == MVDZ_NOUPDT ||
  577. (pmbmd - 1)->m_shpmd == MVDNZ_NOUPDT))
  578. return mvRet;
  579. if (iMBY > 0)   {
  580. mvRet = *(pmvBY - m_iNumMBX);
  581. // Modified for error resilient mode by Toshiba(1997-11-14)
  582. // if ((pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDZ ||
  583. if (!bTopBndry && ((pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDZ ||
  584. (pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDNZ ||
  585. (pmbmd - m_iNumMBX)->m_shpmd == MVDZ_NOUPDT ||
  586. (pmbmd - m_iNumMBX)->m_shpmd == MVDNZ_NOUPDT
  587. // Modified for error resilient mode by Toshiba(1997-11-14)
  588. // )
  589. ))
  590. return mvRet;
  591. mvRet = *(pmvBY - m_iNumMBX + 1);
  592. // Modified for error resilient mode by Toshiba(1997-11-14)
  593. // if ((iMBX < m_iNumMBX - 1) && ((pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDZ ||
  594. if (!bRightBndry && ((pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDZ ||
  595. (pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDNZ ||
  596. (pmbmd - m_iNumMBX + 1)->m_shpmd == MVDZ_NOUPDT ||
  597. (pmbmd - m_iNumMBX + 1)->m_shpmd == MVDNZ_NOUPDT)
  598. )
  599. return mvRet;
  600. }
  601. // try texture vector then; truncate half pel
  602. if(m_volmd.bShapeOnly==FALSE && m_vopmd.vopPredType==PVOP)
  603. {
  604. // Modified for error resilient mode by Toshiba(1997-11-14)
  605. // if (iMBX != 0 && validBlock (pmbmd - 1, gIndexOfCandBlk [1] [0]))
  606. if (!bLeftBndry && validBlock (pmbmd, pmbmd - 1, gIndexOfCandBlk [1] [0]))
  607. return CMotionVector ((pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0])->m_vctTrueHalfPel.x / 2,
  608.   (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0])->m_vctTrueHalfPel.y / 2);
  609. if (iMBY != 0)   {
  610. // Modified for error resilient mode by Toshiba(1997-11-14)
  611. // if (validBlock (pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1]))
  612. if (!bTopBndry && validBlock (pmbmd, pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1]))
  613. return CMotionVector ((pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1])->m_vctTrueHalfPel.x / 2,
  614.   (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1])->m_vctTrueHalfPel.y / 2);
  615. // Modified for error resilient mode by Toshiba(1997-11-14)
  616. // if (iMBX < m_iNumMBX - 1 && validBlock (pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2]))
  617. if (!bRightBndry && validBlock (pmbmd, pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2]))
  618. return CMotionVector ((pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2])->m_vctTrueHalfPel.x / 2,
  619.   (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2])->m_vctTrueHalfPel.y / 2);
  620. }
  621. }
  622. return CMotionVector ();
  623. }