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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
  4. Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
  5. (date: July, 1997)
  6. and edited by Xuemin Chen (xchen@gi.com), General Instrument Corp.
  7. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  8. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  9. as specified by the MPEG-4 Video. 
  10. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  11. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  12. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  13. The original developer of this software module and his/her company, 
  14. the subsequent editors and their companies, 
  15. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  16. Copyright is not released for non MPEG-4 Video conforming products. 
  17. Microsoft retains full right to use the code for his/her own purpose, 
  18. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  19. This copyright notice must be included in all copies or derivative works. 
  20. Copyright (c) 1996, 1997.
  21. Module Name:
  22. mvDec.cpp
  23. Abstract:
  24. motion vector decoder
  25. Revision History:
  26. Dec 20, 1997: Interlaced tools added by General Instrument Corp.
  27. *************************************************************************/
  28. #include "typeapi.h"
  29. #include "codehead.h"
  30. #include "mode.hpp"
  31. #include "global.hpp"
  32. #include "entropy/bitstrm.hpp"
  33. #include "entropy/entropy.hpp"
  34. #include "entropy/huffman.hpp"
  35. #include "vopses.hpp"
  36. #include "vopsedec.hpp"
  37. #ifdef __MFC_
  38. #ifdef _DEBUG
  39. #undef THIS_FILE
  40. static char BASED_CODE THIS_FILE[] = __FILE__;
  41. #endif
  42. #define new DEBUG_NEW    
  43. #endif // __MFC_
  44. Void CVideoObjectDecoder::decodeMV (const CMBMode* pmbmd, CMotionVector* pmv, 
  45. Bool bLeftBndry, Bool bRightBndry, Bool bTopBndry, 
  46. Bool bZeroMV, Int iMBX, Int iMBY)
  47. {
  48. if (pmbmd->m_bSkip || pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ || bZeroMV) {
  49. memset (pmv, 0, PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
  50. return;
  51. }
  52. CVector vctDiff, vctDecode, vctPred;
  53. if (pmbmd->m_bhas4MVForward) {
  54. for (Int iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
  55. if (bLeftBndry || bRightBndry || bTopBndry)
  56. if(short_video_header)
  57. find8x8MVpredAtBoundary(vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry, (BlockNum) iBlk);
  58. else
  59. findMVpredGeneric (vctPred, pmv, pmbmd, iBlk, iMBX, iMBY);
  60. else 
  61. find8x8MVpredInterior (vctPred, pmv, (BlockNum) iBlk);
  62. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  63. vctDecode = vctDiff + vctPred; //fit in range
  64. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  65. pmv [iBlk] = CMotionVector (vctDecode); //convert to full pel now
  66. }
  67. }
  68. // INTERLACE
  69. else if ((m_vopmd.bInterlace)&&(pmbmd->m_bFieldMV)) {
  70. Int iTempX1, iTempY1, iTempX2, iTempY2;
  71. find16x16MVpred (vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry);
  72. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  73. vctDiff.y *= 2;
  74. vctPred.y = 2*(vctPred.y / 2);
  75. vctDecode = vctDiff + vctPred; //fit in range
  76. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  77. CMotionVector* pmv16x8 = pmv +5;
  78. if(pmbmd->m_bForwardTop) {
  79. pmv16x8++;
  80. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  81. iTempX1 = pmv16x8->m_vctTrueHalfPel.x;
  82. iTempY1 = pmv16x8->m_vctTrueHalfPel.y;
  83. pmv16x8++;
  84. else
  85. {
  86. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  87. iTempX1 = pmv16x8->m_vctTrueHalfPel.x;
  88. iTempY1 = pmv16x8->m_vctTrueHalfPel.y;
  89. pmv16x8++;
  90. pmv16x8++;
  91. }
  92. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  93. vctDiff.y *= 2;
  94. vctPred.y = 2*(vctPred.y / 2);
  95. vctDecode = vctDiff + vctPred; //fit in range
  96. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  97. if(pmbmd->m_bForwardBottom) {
  98. pmv16x8++;
  99. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  100. iTempX2 = pmv16x8->m_vctTrueHalfPel.x;
  101. iTempY2 = pmv16x8->m_vctTrueHalfPel.y;
  102. }
  103. else
  104. {
  105. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  106. iTempX2 = pmv16x8->m_vctTrueHalfPel.x;
  107. iTempY2 = pmv16x8->m_vctTrueHalfPel.y;
  108. }
  109. Int iTemp;
  110. for (UInt i = 1; i < 5; i++) {
  111. iTemp = iTempX1 + iTempX2;
  112. pmv [i].m_vctTrueHalfPel.x = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);
  113. iTemp = iTempY1 + iTempY2;
  114. pmv [i].m_vctTrueHalfPel.y = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);
  115. }
  116. }
  117. // ~INTERLACE
  118. else { //1 mv
  119. if(short_video_header)
  120. find16x16MVpred(vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry);
  121. else
  122. findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);
  123. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  124. vctDecode = vctDiff + vctPred; //fit in range
  125. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  126. *pmv++ = CMotionVector (vctDecode); //convert to full pel now
  127. for (Int i = 0; i < 4; i++) {
  128. *pmv = *(pmv - 1);
  129. pmv++;
  130. }
  131. }
  132. }
  133. Void CVideoObjectDecoder::decodeMVofBVOP (CMotionVector* pmvForward, CMotionVector* pmvBackward, CMBMode* pmbmd, 
  134.   Int iMBX, Int iMBY, const CMotionVector* pmvRef, const CMBMode* pmbmdRef)
  135. {
  136. CVector vctDiff;
  137. //CVector vctPred;
  138. CVector vctDecode;
  139. //UInt nBits = 0;
  140. if(pmbmd->m_bSkip == TRUE && m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0)
  141. return;
  142. if (pmbmd->m_mbType == FORWARD || pmbmd->m_mbType == INTERPOLATE) {
  143. assert (pmbmd->m_bSkip != TRUE);
  144. assert (pmbmd->m_bhas4MVForward != TRUE);
  145. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  146. // TPS FIX
  147. if (pmbmd->m_bFieldMV && m_volmd.volType != ENHN_LAYER) {
  148. vctDecode.x = vctDiff.x + m_vctForwardMvPredBVOP[0].x;
  149. vctDecode.y = 2 * (vctDiff.y + m_vctForwardMvPredBVOP[0].y / 2);
  150. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  151. m_vctForwardMvPredBVOP[0] = vctDecode;
  152. pmvForward[0] = CMotionVector(vctDecode);
  153. pmvForward[1] = pmvForward[0];
  154. pmvForward[2] = pmvForward[0];
  155. getDiffMV(vctDiff, m_vopmd.mvInfoForward);
  156. vctDecode.x = vctDiff.x + m_vctForwardMvPredBVOP[1].x;
  157. vctDecode.y = 2 * (vctDiff.y + m_vctForwardMvPredBVOP[1].y / 2);
  158. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  159. m_vctForwardMvPredBVOP[1] = vctDecode;
  160. pmvForward[3] = CMotionVector(vctDecode);
  161. pmvForward[4] = pmvForward[3];
  162. } else {
  163. vctDecode = vctDiff + m_vctForwardMvPredBVOP[0];
  164. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  165. m_vctForwardMvPredBVOP[0] = vctDecode;
  166. m_vctForwardMvPredBVOP[1] = vctDecode;
  167. *pmvForward++ = CMotionVector(vctDecode);
  168. for (Int i = 0; i < 4; i++) {
  169. *pmvForward = *(pmvForward - 1);
  170. pmvForward++;
  171. }
  172. }
  173. }
  174. // TPS FIX
  175. if ( (pmbmd->m_mbType == BACKWARD || pmbmd->m_mbType == INTERPOLATE)
  176. && (m_volmd.volType != ENHN_LAYER || m_vopmd.iRefSelectCode != 0) ){ // modified by Sharp (98/3/11)
  177. assert (pmbmd->m_bSkip != TRUE);
  178. assert (pmbmd->m_bhas4MVBackward != TRUE);
  179. getDiffMV (vctDiff, m_vopmd.mvInfoBackward);
  180. if (pmbmd->m_bFieldMV && m_volmd.volType != ENHN_LAYER) {
  181. vctDecode.x = vctDiff.x + m_vctBackwardMvPredBVOP[0].x;
  182. vctDecode.y = 2 * (vctDiff.y + m_vctBackwardMvPredBVOP[0].y / 2);
  183. fitMvInRange (vctDecode, m_vopmd.mvInfoBackward);
  184. m_vctBackwardMvPredBVOP[0] = vctDecode;
  185. pmvBackward[0] = CMotionVector(vctDecode);
  186. pmvBackward[1] = pmvBackward[0];
  187. pmvBackward[2] = pmvBackward[0];
  188. getDiffMV(vctDiff, m_vopmd.mvInfoBackward);
  189. vctDecode.x = vctDiff.x + m_vctBackwardMvPredBVOP[1].x;
  190. vctDecode.y = 2 * (vctDiff.y + m_vctBackwardMvPredBVOP[1].y / 2);
  191. fitMvInRange (vctDecode, m_vopmd.mvInfoBackward);
  192. m_vctBackwardMvPredBVOP[1] = vctDecode;
  193. pmvBackward[3] = CMotionVector(vctDecode);
  194. pmvBackward[4] = pmvBackward[3];
  195. } else {
  196. vctDecode = vctDiff + m_vctBackwardMvPredBVOP[0];
  197. fitMvInRange (vctDecode, m_vopmd.mvInfoBackward);
  198. m_vctBackwardMvPredBVOP[0] = vctDecode;
  199. m_vctBackwardMvPredBVOP[1] = vctDecode;
  200. *pmvBackward++ = CMotionVector(vctDecode);
  201. for (Int i = 0; i < 4; i++) {
  202. *pmvBackward = *(pmvBackward - 1);
  203. pmvBackward++;
  204. }
  205. }
  206. }
  207. if (pmbmd->m_mbType == DIRECT) {
  208. static MVInfo directInfo = { 32, 1, 1};
  209. assert (pmbmd->m_bhas4MVForward != TRUE);
  210. /* begin of new changes 02-19-99 
  211.      if (m_vopmd.bInterlace) {
  212.     memset (pmvForward, 0, BVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector)); //set forward mv to zero
  213.     if (!pmbmd->m_bSkip)
  214.     getDiffMV (pmbmd->m_vctDirectDeltaMV, directInfo);
  215.     } else {
  216. end of new changes 02-19-99 */
  217. // begin of new changes 02-19-99
  218. if (m_vopmd.bInterlace) {
  219. if (!pmbmd->m_bSkip) {
  220. getDiffMV (pmbmd->m_vctDirectDeltaMV, directInfo);
  221. vctDiff.x = pmbmd->m_vctDirectDeltaMV.x;
  222. vctDiff.y = pmbmd->m_vctDirectDeltaMV.y;
  223. }
  224. else
  225. vctDiff.x = vctDiff.y = 0;
  226. }
  227. else {  
  228. //end of new changes 02-19-99
  229. if (pmbmd->m_bSkip)
  230. vctDiff.x = vctDiff.y = 0;
  231. else  {
  232. Long lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
  233. vctDiff.x  = deScaleMV (lSymbol - 32, 0, 1);
  234. lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
  235. vctDiff.y  = deScaleMV (lSymbol - 32, 0, 1);
  236. }
  237. }  // new change 02-19-99
  238.     computeDirectForwardMV (vctDiff, pmvForward, pmvRef, pmbmdRef); //compute forward mv from diff
  239.     if(pmbmdRef==NULL)
  240.     {
  241.     // transparent reference macroblock
  242.     pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = FALSE;
  243.     CMotionVector mvRef; // zero motion vector
  244.     backwardMVFromForwardMV (*pmvBackward, *pmvForward, mvRef, vctDiff);
  245.     }
  246.     else
  247.     {
  248.     pmbmd->m_bhas4MVBackward = pmbmd->m_bhas4MVForward = pmbmdRef->m_bhas4MVForward; //reset 4mv mode
  249.     if (pmbmd->m_bhas4MVBackward) {
  250.     for (Int i = 0; i < 4; i++) {
  251.     pmvForward++;
  252.     pmvBackward++;
  253.     pmvRef++;
  254.     backwardMVFromForwardMV (*pmvBackward, *pmvForward, *pmvRef,
  255.      vctDiff); //compute back mv from forward mv and ref mv for direct mode
  256.     }
  257.     }
  258.     else
  259.     backwardMVFromForwardMV (*pmvBackward, *pmvForward, *pmvRef,
  260.      vctDiff); //compute back mv from forward mv and ref mv for direct mode
  261. // }  new change 02-19-99
  262. }
  263. }
  264. Void CVideoObjectDecoder::computeDirectForwardMV (CVector vctDiff, CMotionVector* pmv,
  265.   const CMotionVector* pmvRef,
  266.   const CMBMode* pmbmdRef)
  267. {
  268. if(pmvRef==NULL)
  269. {
  270. // colocated macroblock is transparent, use zero reference MV
  271. *pmv++ = CMotionVector (vctDiff); //convert to full pel now
  272. for (Int i = 0; i < 4; i++) {
  273. *pmv = *(pmv - 1);
  274. pmv++;
  275. }
  276. }
  277. else
  278. {
  279. Int iPartInterval = m_t - m_tPastRef;
  280. Int iFullInterval = m_tFutureRef - m_tPastRef;
  281. if (pmbmdRef->m_bhas4MVForward == FALSE) {
  282. CVector vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval;
  283. vctRefScaled.x /= iFullInterval; //truncation as per vm
  284. vctRefScaled.y /= iFullInterval; //truncation as per vm
  285. CVector vctDecode = vctDiff + vctRefScaled;
  286. *pmv++ = CMotionVector (vctDecode); //convert to full pel now
  287. for (Int i = 0; i < 4; i++) {
  288. *pmv = *(pmv - 1);
  289. pmv++;
  290. }
  291. }
  292. else {
  293. for (Int i = 0; i < 4; i++) {
  294. pmv++;
  295. pmvRef++;
  296. CVector vctRefScaled = pmvRef->trueMVHalfPel () * iPartInterval;
  297. vctRefScaled.x /= iFullInterval; //truncation as per vm
  298. vctRefScaled.y /= iFullInterval; //truncation as per vm
  299. CVector vctDecode = vctDiff + vctRefScaled;
  300. *pmv = CMotionVector (vctDecode); //convert to full pel now
  301. }
  302. }
  303. }
  304. }
  305. Void CVideoObjectDecoder::decodeMVWithShape (const CMBMode* pmbmd, CoordI iMBX, CoordI iMBY, CMotionVector* pmv)
  306. {
  307. if (pmbmd->m_bSkip || pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
  308. memset (pmv, 0, PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
  309. return;
  310. }
  311. CVector vctDiff, vctDecode, vctPred;
  312. if (pmbmd->m_bhas4MVForward) {
  313. for (Int iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
  314. if (pmbmd->m_rgTranspStatus [iBlk] == ALL)
  315. pmv [iBlk] = CMotionVector (NOT_MV, NOT_MV);
  316. else {
  317. findMVpredGeneric (vctPred, pmv, pmbmd, iBlk, iMBX, iMBY);
  318. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  319. vctDecode = vctDiff + vctPred; //fit in range
  320. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  321. pmv [iBlk] = CMotionVector (vctDecode);
  322. }
  323. }
  324. }
  325. // INTERLACE
  326. //new changes
  327. else if ((m_vopmd.bInterlace)&&(pmbmd->m_bFieldMV)) {
  328. Int iTempX1, iTempY1, iTempX2, iTempY2;
  329. assert (pmbmd->m_rgTranspStatus [0] != ALL);
  330. findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);
  331. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  332. vctDiff.y *= 2;
  333. vctPred.y = 2*(vctPred.y / 2);
  334. vctDecode = vctDiff + vctPred; //fit in range
  335. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  336. CMotionVector* pmv16x8 = pmv +5;
  337. if(pmbmd->m_bForwardTop) {
  338. pmv16x8++;
  339. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  340. iTempX1 = pmv16x8->m_vctTrueHalfPel.x;
  341. iTempY1 = pmv16x8->m_vctTrueHalfPel.y;
  342. pmv16x8++;
  343. else
  344. {
  345. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  346. iTempX1 = pmv16x8->m_vctTrueHalfPel.x;
  347. iTempY1 = pmv16x8->m_vctTrueHalfPel.y;
  348. pmv16x8++;
  349. pmv16x8++;
  350. }
  351. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  352. vctDiff.y *= 2;
  353. vctPred.y = 2*(vctPred.y / 2);
  354. vctDecode = vctDiff + vctPred; //fit in range
  355. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  356. if(pmbmd->m_bForwardBottom) {
  357. pmv16x8++;
  358. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  359. iTempX2 = pmv16x8->m_vctTrueHalfPel.x;
  360. iTempY2 = pmv16x8->m_vctTrueHalfPel.y;
  361. }
  362. else
  363. {
  364. *pmv16x8 = CMotionVector (vctDecode); //convert to full pel now
  365. iTempX2 = pmv16x8->m_vctTrueHalfPel.x;
  366. iTempY2 = pmv16x8->m_vctTrueHalfPel.y;
  367. }
  368. Int iTemp;
  369. for (UInt i = 1; i < 5; i++) {
  370. iTemp = iTempX1 + iTempX2;
  371. pmv [i].m_vctTrueHalfPel.x = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);
  372. iTemp = iTempY1 + iTempY2;
  373. pmv [i].m_vctTrueHalfPel.y = (iTemp & 3) ? ((iTemp>>1) | 1) : (iTemp>>1);
  374. }
  375. }
  376. //end of new changes
  377. // ~INTERLACE
  378. else { //1 mv
  379. assert (pmbmd->m_rgTranspStatus [0] != ALL);
  380. findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);
  381. getDiffMV (vctDiff, m_vopmd.mvInfoForward);
  382. vctDecode = vctDiff + vctPred; //fit in range
  383. fitMvInRange (vctDecode, m_vopmd.mvInfoForward);
  384. *pmv++ = CMotionVector (vctDecode);
  385. for (Int i = 0; i < 4; i++) {
  386. *pmv = *(pmv - 1);
  387. pmv++;
  388. }
  389. }
  390. }
  391. Void CVideoObjectDecoder::getDiffMV (CVector& vctDiffMV, MVInfo mvinfo) //get half pel
  392. {
  393. Int iResidual;
  394. Long lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
  395. Int iVLC = lSymbol - 32;
  396. if (iVLC != 0)
  397. iResidual = m_pbitstrmIn->getBits (mvinfo.uiFCode - 1);
  398. else
  399. iResidual = 0;
  400. vctDiffMV.x  = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);
  401. lSymbol = m_pentrdecSet->m_pentrdecMV->decodeSymbol ();
  402. iVLC = lSymbol - 32;
  403. if (iVLC != 0)
  404. iResidual = m_pbitstrmIn->getBits (mvinfo.uiFCode - 1);
  405. else
  406. iResidual = 0;
  407. vctDiffMV.y  = deScaleMV (iVLC, iResidual, mvinfo.uiScaleFactor);
  408. }
  409. Int CVideoObjectDecoder::deScaleMV (Int iVLC, Int iResidual, Int iScaleFactor)
  410. {
  411. if (iVLC == 0 && iResidual == 0)
  412. return 0;
  413. else if (iScaleFactor == 1)
  414. return (iVLC);
  415. else {
  416. Int iAbsDiffMVcomponent = abs (iVLC) * iScaleFactor + iResidual - iScaleFactor + 1; //changed a'c to enc
  417. return (sign (iVLC) * iAbsDiffMVcomponent);
  418. }
  419. }
  420. Void CVideoObjectDecoder::fitMvInRange (CVector& vctSrc, MVInfo mvinfo)
  421. {
  422. Int iMvRange = mvinfo.uiRange; //in half pel unit
  423. if (vctSrc.x < -1 * iMvRange) //* 2 to get length of [-range, range]
  424. vctSrc.x += 2 * iMvRange;
  425. else if (vctSrc.x >= iMvRange)
  426. vctSrc.x  -= 2 * iMvRange;
  427. if (vctSrc.y < -1 * iMvRange)
  428. vctSrc.y += 2 * iMvRange;
  429. else if (vctSrc.y >= iMvRange)
  430. vctSrc.y  -= 2 * iMvRange;
  431. }