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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2. No header comments ????
  3.  
  4. Revision History:
  5. Dec 11, 1997: X. Chen and B. Eifrig
  6. Interlaced tools added by NextLevel Systems
  7. **************************************************************************/
  8. #include <stdio.h>
  9. #include <fstream.h>
  10. #include <math.h>
  11. #include <stdlib.h>
  12. #include "typeapi.h"
  13. #include "codehead.h"
  14. #include "global.hpp"
  15. #include "entropy/bitstrm.hpp"
  16. #include "entropy/entropy.hpp"
  17. #include "entropy/huffman.hpp"
  18. #include "mode.hpp"
  19. #include "vopses.hpp"
  20. #include "vopseenc.hpp"
  21. #ifdef __MFC_
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26. #define new DEBUG_NEW    
  27. #endif // __MFC_
  28. UInt CVideoObjectEncoder::encodeMV (const CMotionVector* pmv, const CMBMode* pmbmd,
  29. Bool bLeftBndry, Bool bRightBndry, Bool bTopBndry, Int iMBX, Int iMBY)
  30. {
  31. UInt nBits = 0;
  32. CVector vctDiff;
  33. CVector vctPred;
  34. if (pmbmd->m_bhas4MVForward) {
  35. if (bLeftBndry || bRightBndry || bTopBndry) {
  36. for (UInt iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
  37. findMVpredGeneric (vctPred, pmv, pmbmd, iBlk, iMBX, iMBY);
  38. vctDiff = (pmv + iBlk)->trueMVHalfPel () - vctPred;
  39. #ifdef __TRACE_AND_STATS_
  40. m_pbitstrmOut->trace ((pmv + iBlk)->trueMVHalfPel (), "MB_MV_Curr");
  41. m_pbitstrmOut->trace (vctPred, "MB_MV_Pred");
  42. m_pbitstrmOut->trace (vctDiff, "MB_MV_Diff");
  43. #endif // __TRACE_AND_STATS_
  44. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  45. }
  46. }
  47. else {
  48. for (UInt iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
  49. find8x8MVpredInterior (vctPred, pmv, (BlockNum) iBlk);
  50. vctDiff = (pmv + iBlk) -> trueMVHalfPel () - vctPred;
  51. #ifdef __TRACE_AND_STATS_
  52. m_pbitstrmOut->trace ((pmv + iBlk)->trueMVHalfPel (), "MB_MV_Curr");
  53. m_pbitstrmOut->trace (vctPred, "MB_MV_Pred");
  54. m_pbitstrmOut->trace (vctDiff, "MB_MV_Diff");
  55. #endif // __TRACE_AND_STATS_
  56. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  57. }
  58. }
  59. } else if (pmbmd->m_bFieldMV) {
  60. find16x16MVpred(vctPred, pmv, bLeftBndry, bRightBndry, bTopBndry);
  61. if(pmbmd->m_bForwardTop) {
  62. vctDiff.x = pmv[6].m_vctTrueHalfPel.x   - vctPred.x;
  63. vctDiff.y = pmv[6].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  64. else
  65. {
  66. vctDiff.x = pmv[5].m_vctTrueHalfPel.x   - vctPred.x;
  67. vctDiff.y = pmv[5].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  68. }
  69. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  70. if(pmbmd->m_bForwardBottom) {
  71. vctDiff.x = pmv[8].m_vctTrueHalfPel.x   - vctPred.x;
  72. vctDiff.y = pmv[8].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  73. }
  74. else
  75. {
  76. vctDiff.x = pmv[7].m_vctTrueHalfPel.x   - vctPred.x;
  77. vctDiff.y = pmv[7].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  78. }
  79. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  80. } else { //1mv
  81. findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iMBX, iMBY);
  82. vctDiff = pmv->trueMVHalfPel () - vctPred;
  83. #ifdef __TRACE_AND_STATS_
  84. m_pbitstrmOut->trace (pmv->trueMVHalfPel (), "MB_MV_Curr");
  85. m_pbitstrmOut->trace (vctPred, "MB_MV_Pred");
  86. m_pbitstrmOut->trace (vctDiff, "MB_MV_Diff");
  87. #endif // __TRACE_AND_STATS_
  88. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  89. }
  90. return nBits;
  91. }
  92. UInt CVideoObjectEncoder::encodeMVWithShape (const CMotionVector* pmv, const CMBMode* pmbmd, Int iXMB, Int iYMB)
  93. {
  94. UInt nBits = 0;
  95. CVector vctDiff;
  96. CVector vctPred;
  97. if (pmbmd->m_bhas4MVForward) { //4mv
  98. for (UInt iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
  99. if (pmbmd->m_rgTranspStatus[iBlk] != ALL) {
  100. findMVpredGeneric (vctPred, pmv, pmbmd, iBlk, iXMB, iYMB);
  101. vctDiff = (pmv + iBlk)->trueMVHalfPel () - vctPred;
  102. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  103. }
  104. }
  105. }
  106. // INTERLACED
  107. // new changes
  108. else if (pmbmd->m_bFieldMV) {
  109. findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iXMB, iYMB);
  110. if(pmbmd->m_bForwardTop) {
  111. vctDiff.x = pmv[6].m_vctTrueHalfPel.x   - vctPred.x;
  112. vctDiff.y = pmv[6].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  113. else
  114. {
  115. vctDiff.x = pmv[5].m_vctTrueHalfPel.x   - vctPred.x;
  116. vctDiff.y = pmv[5].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  117. }
  118. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  119. if(pmbmd->m_bForwardBottom) {
  120. vctDiff.x = pmv[8].m_vctTrueHalfPel.x   - vctPred.x;
  121. vctDiff.y = pmv[8].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  122. }
  123. else
  124. {
  125. vctDiff.x = pmv[7].m_vctTrueHalfPel.x   - vctPred.x;
  126. vctDiff.y = pmv[7].m_vctTrueHalfPel.y/2 - vctPred.y/2;
  127. }
  128. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  129. }
  130. // end of new changes
  131. // INTERLACED
  132. else { //1mv
  133. findMVpredGeneric (vctPred, pmv, pmbmd, ALL_Y_BLOCKS, iXMB, iYMB);
  134. vctDiff = pmv->trueMVHalfPel () - vctPred;
  135. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  136. }
  137. return nBits;
  138. }
  139. Void CVideoObjectEncoder::scaleMV (Int& iVLC, UInt& uiResidual, Int iDiffMVcomponent, const MVInfo *pmviDir)
  140. {
  141. if (iDiffMVcomponent < (-1 * (Int) pmviDir->uiRange))
  142. iDiffMVcomponent += 2 * pmviDir->uiRange;
  143. else if (iDiffMVcomponent > (Int) (pmviDir->uiRange - 1))
  144. iDiffMVcomponent -= 2 * pmviDir->uiRange;
  145. if (iDiffMVcomponent == 0) { //nothing to do
  146. iVLC = 0;
  147. uiResidual = 0;
  148. }
  149. else {
  150. if (pmviDir->uiScaleFactor == 1) { //simple no-scale case
  151. iVLC = iDiffMVcomponent;
  152. uiResidual = 0;
  153. }
  154. else { //stupid scaling
  155. UInt uiAbsDiffMVcomponent = abs (iDiffMVcomponent);
  156. uiResidual = (uiAbsDiffMVcomponent - 1) % pmviDir->uiScaleFactor;
  157. UInt uiVLCmagnitude = (uiAbsDiffMVcomponent 
  158. - uiResidual + (pmviDir->uiScaleFactor - 1)) 
  159. / pmviDir->uiScaleFactor; // absorb ++ into here (m_volmd.mvInfo.uiScaleFactor - 1)
  160. iVLC = uiVLCmagnitude * sign (iDiffMVcomponent);
  161. }
  162. }
  163. }
  164. UInt CVideoObjectEncoder::sendDiffMV (const CVector& vctDiffMVHalfPel, const MVInfo *pmviDir)
  165. {
  166. Int iVLC;
  167. UInt uiResidual;
  168. UInt nBits = 0;
  169. assert(vctDiffMVHalfPel.x < (Int)(pmviDir->uiRange<<1) && vctDiffMVHalfPel.x > -(Int)(pmviDir->uiRange<<1));
  170. assert(vctDiffMVHalfPel.y < (Int)(pmviDir->uiRange<<1) && vctDiffMVHalfPel.y > -(Int)(pmviDir->uiRange<<1));
  171. // send the bits
  172. scaleMV (iVLC, uiResidual, vctDiffMVHalfPel.x, pmviDir);
  173. Long lsymbol = iVLC + 32;
  174. nBits += m_pentrencSet -> m_pentrencMV->encodeSymbol (lsymbol, "MB_MV_Magnitude");
  175. if (iVLC != 0) {
  176. m_pbitstrmOut->putBits ((Char) uiResidual, pmviDir->uiFCode - 1, "MB_MV_Residual");
  177. nBits += pmviDir->uiFCode - 1;
  178. }
  179. else
  180. assert (uiResidual == 0);
  181. scaleMV (iVLC, uiResidual, vctDiffMVHalfPel.y, pmviDir);
  182. lsymbol = iVLC + 32;
  183. nBits += m_pentrencSet -> m_pentrencMV->encodeSymbol (lsymbol, "MB_MV_Magnitude");
  184. if (iVLC != 0) {
  185. m_pbitstrmOut->putBits ((Char) uiResidual, pmviDir->uiFCode - 1, "MB_MV_Residual");
  186. nBits += pmviDir->uiFCode - 1;
  187. }
  188. else
  189. assert (uiResidual == 0);
  190. return nBits;
  191. }
  192. UInt CVideoObjectEncoder::encodeMVofBVOP (
  193.   const CMotionVector* pmvForward, 
  194.   const CMotionVector* pmvBackward, 
  195.   const CMBMode*    pmbmd, 
  196.   Int iMBX, Int iMBY,
  197.   const CMotionVector* pmvRef, // not used
  198.   const CMBMode*    pmbmdRef // not used
  199. )  // encode motion vectors for b-vop
  200. {
  201. assert (pmbmd->m_rgTranspStatus [0] != ALL);
  202. assert (pmbmd->m_dctMd == INTER || pmbmd->m_dctMd == INTERQ);
  203. assert (pmbmd->m_bSkip == FALSE);
  204. CVector vctDiff;
  205. UInt nBits = 0;
  206. const CVector *pvctMV;
  207. if (pmbmd->m_mbType == FORWARD || pmbmd->m_mbType == INTERPOLATE) {
  208. assert (pmbmd->m_bhas4MVForward != TRUE);
  209. // TPS FIX
  210. if (pmbmd->m_bFieldMV && m_volmd.volType != ENHN_LAYER) {
  211. pvctMV = &pmvForward[1 + (Int)pmbmd->m_bForwardTop].m_vctTrueHalfPel;
  212. assert((pvctMV->y & 1) == 0);
  213. vctDiff.x = pvctMV->x   - m_vctForwardMvPredBVOP[0].x;
  214. vctDiff.y = pvctMV->y/2 - m_vctForwardMvPredBVOP[0].y/2;
  215. #ifdef __TRACE_AND_STATS_
  216. m_pbitstrmOut->trace (*pvctMV, "MB_F_MV_Curr_Top");
  217. m_pbitstrmOut->trace (m_vctForwardMvPredBVOP[0],"MB_F_MV_Pred_Top");
  218. m_pbitstrmOut->trace (vctDiff, "MB_F_MV_Diff_Top");
  219. #endif // __TRACE_AND_STATS_
  220. m_vctForwardMvPredBVOP[0] = *pvctMV;
  221. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  222. pvctMV = &pmvForward[3 + (Int)pmbmd->m_bForwardBottom].m_vctTrueHalfPel;
  223. assert((pvctMV->y & 1) == 0);
  224. vctDiff.x = pvctMV->x   - m_vctForwardMvPredBVOP[1].x;
  225. vctDiff.y = pvctMV->y/2 - m_vctForwardMvPredBVOP[1].y/2;
  226. #ifdef __TRACE_AND_STATS_
  227. m_pbitstrmOut->trace (*pvctMV, "MB_F_MV_Curr_Bot");
  228. m_pbitstrmOut->trace (m_vctForwardMvPredBVOP[1],"MB_F_MV_Pred_Bot");
  229. m_pbitstrmOut->trace (vctDiff, "MB_F_MV_Diff_Bot");
  230. #endif // __TRACE_AND_STATS_
  231. m_vctForwardMvPredBVOP[1] = *pvctMV;
  232. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  233. } else {
  234. vctDiff = pmvForward[0].m_vctTrueHalfPel - m_vctForwardMvPredBVOP[0];
  235. #ifdef __TRACE_AND_STATS_
  236. m_pbitstrmOut->trace (pmvForward[0].m_vctTrueHalfPel, "MB_F_MV_Curr");
  237. m_pbitstrmOut->trace (m_vctForwardMvPredBVOP[0],   "MB_F_MV_Pred");
  238. m_pbitstrmOut->trace (vctDiff,   "MB_F_MV_Diff");
  239. #endif // __TRACE_AND_STATS_
  240. m_vctForwardMvPredBVOP[0] = pmvForward[0].m_vctTrueHalfPel;
  241. m_vctForwardMvPredBVOP[1] = pmvForward[0].m_vctTrueHalfPel;
  242. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoForward);
  243. }
  244. }
  245. // TPS FIX
  246. if ((pmbmd->m_mbType == BACKWARD || pmbmd->m_mbType == INTERPOLATE) 
  247. && (m_volmd.volType != ENHN_LAYER || m_vopmd.iRefSelectCode != 0)) { // modified by Sharp (98/3/11)
  248. assert (pmbmd->m_bhas4MVBackward != TRUE);
  249. // TPS FIX
  250. if (pmbmd->m_bFieldMV && m_volmd.volType != ENHN_LAYER) {
  251. pvctMV = &pmvBackward[1 + (Int)pmbmd->m_bBackwardTop].m_vctTrueHalfPel;
  252. assert((pvctMV->y & 1) == 0);
  253. vctDiff.x = pvctMV->x   - m_vctBackwardMvPredBVOP[0].x;
  254. vctDiff.y = pvctMV->y/2 - m_vctBackwardMvPredBVOP[0].y/2;
  255. #ifdef __TRACE_AND_STATS_
  256. m_pbitstrmOut->trace (*pvctMV,   "MB_B_MV_Curr_Top");
  257. m_pbitstrmOut->trace (m_vctBackwardMvPredBVOP[0], "MB_B_MV_Pred_Top");
  258. m_pbitstrmOut->trace (vctDiff,   "MB_B_MV_Diff_Top");
  259. #endif // __TRACE_AND_STATS_
  260. m_vctBackwardMvPredBVOP[0] = *pvctMV;
  261. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoBackward);
  262. pvctMV = &pmvBackward[3 + (Int)pmbmd->m_bBackwardBottom].m_vctTrueHalfPel;
  263. assert((pvctMV->y & 1) == 0);
  264. vctDiff.x = pvctMV->x   - m_vctBackwardMvPredBVOP[1].x;
  265. vctDiff.y = pvctMV->y/2 - m_vctBackwardMvPredBVOP[1].y/2;
  266. #ifdef __TRACE_AND_STATS_
  267. m_pbitstrmOut->trace (*pvctMV,   "MB_B_MV_Curr_Bot");
  268. m_pbitstrmOut->trace (m_vctBackwardMvPredBVOP[1], "MB_B_MV_Pred_Bot");
  269. m_pbitstrmOut->trace (vctDiff,   "MB_B_MV_Diff_Bot");
  270. #endif // __TRACE_AND_STATS_
  271. m_vctBackwardMvPredBVOP[1] = *pvctMV;
  272. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoBackward);
  273. } else {
  274. vctDiff = pmvBackward[0].m_vctTrueHalfPel - m_vctBackwardMvPredBVOP[0];
  275. #ifdef __TRACE_AND_STATS_
  276. m_pbitstrmOut->trace (pmvBackward[0].m_vctTrueHalfPel, "MB_B_MV_Curr");
  277. m_pbitstrmOut->trace (m_vctBackwardMvPredBVOP[0],    "MB_B_MV_Pred");
  278. m_pbitstrmOut->trace (vctDiff,    "MB_B_MV_Diff");
  279. #endif // __TRACE_AND_STATS_
  280. m_vctBackwardMvPredBVOP[0] = pmvBackward[0].m_vctTrueHalfPel;
  281. m_vctBackwardMvPredBVOP[1] = pmvBackward[0].m_vctTrueHalfPel;
  282. nBits += sendDiffMV (vctDiff, &m_vopmd.mvInfoBackward);
  283. }
  284. }
  285. if (pmbmd->m_mbType == DIRECT) {
  286. static MVInfo mviDirect = { 32, 1, 1 };
  287. assert (pmbmd->m_bhas4MVForward != TRUE);
  288. #ifdef __TRACE_AND_STATS_
  289. m_pbitstrmOut->trace (pmbmd->m_vctDirectDeltaMV, "MB_D_MV_Diff");
  290. #endif // __TRACE_AND_STATS_
  291. nBits += sendDiffMV (pmbmd->m_vctDirectDeltaMV, &mviDirect);
  292. }
  293. return nBits;
  294. }