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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2. mv.cpp
  3. No header comments ????
  4.  
  5. Revision History:
  6. Nov. 14, 1997: Added/Modified for error resilient mode by Toshiba
  7. December 20, 1997: Interlaced tools added by NextLevel Systems (GI)
  8.                         X. Chen (xchen@nlvl.com), B. Eifrig (beifrig@nlvl.com)
  9. **************************************************************************/
  10. #include <stdio.h>
  11. #include "typeapi.h"
  12. #include "global.hpp"
  13. #include "codehead.h"
  14. #include "mode.hpp"
  15. #include "vopses.hpp"
  16. #ifdef __MFC_
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char BASED_CODE THIS_FILE[] = __FILE__;
  20. #endif
  21. #define new DEBUG_NEW    
  22. #endif // __MFC_
  23. inline Int medianof3 (Int a0, Int a1, Int a2)
  24. {
  25. if (a0 > a1) {
  26. if (a1 > a2)
  27. return a1;
  28. else if (a0 > a2)
  29. return a2;
  30. else
  31. return a0;
  32. }
  33. else if (a0 > a2)
  34. return a0;
  35. else if (a1 > a2)
  36. return a2;
  37. else
  38. return a1;
  39. }
  40. Void CVideoObject::find16x16MVpred (CVector& vecPred, const CMotionVector* pmv, Bool bLeftBndry, Bool bRightBndry, Bool bTopBndry) const
  41. {
  42. CVector vctCandMV0, vctCandMV1, vctCandMV2;
  43. if (bLeftBndry)
  44. vctCandMV0.set (0, 0);
  45. else
  46. vctCandMV0 = (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0]) -> trueMVHalfPel ();
  47. if (bTopBndry) {
  48. vecPred = vctCandMV0;
  49. return;
  50. }
  51. else {
  52. vctCandMV1 = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1]) -> trueMVHalfPel ();
  53. if (bRightBndry)
  54. vctCandMV2.set (0, 0);
  55. else
  56. vctCandMV2 = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2]) -> trueMVHalfPel ();
  57. }
  58. vecPred.x = medianof3 (vctCandMV0.x, vctCandMV1.x, vctCandMV2.x);
  59. vecPred.y = medianof3 (vctCandMV0.y, vctCandMV1.y, vctCandMV2.y);
  60. }
  61. Void CVideoObject::find8x8MVpredAtBoundary (CVector& vecPred, const CMotionVector* pmv, Bool bLeftBndry, Bool bRightBndry, Bool bTopBndry, BlockNum blknCurr) const
  62. {
  63. CVector vctCandMV0, vctCandMV1, vctCandMV2;
  64. switch (blknCurr){
  65. case Y_BLOCK1:
  66. if (bLeftBndry)
  67. vctCandMV0.set (0, 0);
  68. else
  69. vctCandMV0 = (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  70. if (bTopBndry){
  71. vecPred = vctCandMV0;
  72. return;
  73. }
  74. else{
  75. vctCandMV1 = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [blknCurr] [1])->trueMVHalfPel ();
  76. if (bRightBndry)
  77. vctCandMV2.set (0, 0);
  78. else
  79. vctCandMV2 = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [blknCurr] [2])->trueMVHalfPel ();
  80. }
  81. break;
  82. case Y_BLOCK2:
  83. vctCandMV0 = (pmv +  gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  84. if (bTopBndry) {
  85. vecPred = vctCandMV0;
  86. return;
  87. }
  88. else{
  89. vctCandMV1 = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  90. if (bRightBndry)
  91. vctCandMV2.set (0, 0);
  92. else
  93. vctCandMV2 = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  94. }
  95. break;
  96. case Y_BLOCK3:
  97. if (bLeftBndry)
  98. vctCandMV0.set (0,0);
  99. else
  100. vctCandMV0 = (pmv - PVOP_MV_PER_REF_PER_MB +  gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  101. vctCandMV1 = (pmv + gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  102. vctCandMV2 = (pmv + gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  103. break;
  104. case Y_BLOCK4:
  105. vctCandMV0 = (pmv + gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  106. vctCandMV1 = (pmv + gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  107. vctCandMV2 = (pmv + gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  108. break;
  109. default:
  110.   break;
  111. }
  112. vecPred.x = medianof3 (vctCandMV0.x, vctCandMV1.x, vctCandMV2.x);
  113. vecPred.y = medianof3 (vctCandMV0.y, vctCandMV1.y, vctCandMV2.y);
  114. }
  115. Void CVideoObject::find8x8MVpredInterior (CVector& vecPred, const CMotionVector* pmv, BlockNum blknCurr) const
  116. {
  117. CVector vctCandMV0, vctCandMV1, vctCandMV2;
  118. switch (blknCurr){
  119. case Y_BLOCK1:
  120. vctCandMV0 = (pmv - PVOP_MV_PER_REF_PER_MB +  gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  121. vctCandMV1 = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  122. vctCandMV2 = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  123. break;
  124. case Y_BLOCK2:
  125. vctCandMV0 = (pmv +  gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  126. vctCandMV1 = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  127. vctCandMV2 = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  128. break;
  129. case Y_BLOCK3:
  130. vctCandMV0 = (pmv - PVOP_MV_PER_REF_PER_MB +  gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  131. vctCandMV1 = (pmv +  gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  132. vctCandMV2 = (pmv +  gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  133. break;
  134. case Y_BLOCK4:
  135. vctCandMV0 = (pmv +  gIndexOfCandBlk [blknCurr] [0]) -> trueMVHalfPel ();
  136. vctCandMV1 = (pmv +  gIndexOfCandBlk [blknCurr] [1]) -> trueMVHalfPel ();
  137. vctCandMV2 = (pmv +  gIndexOfCandBlk [blknCurr] [2]) -> trueMVHalfPel ();
  138. break;
  139. default:
  140.   break;
  141. }
  142. vecPred.x = medianof3 (vctCandMV0.x, vctCandMV1.x, vctCandMV2.x);
  143. vecPred.y = medianof3 (vctCandMV0.y, vctCandMV1.y, vctCandMV2.y);
  144. }
  145. Void CVideoObject::mvLookupUV (const CMBMode* pmbmd, const CMotionVector* pmv, 
  146.    CoordI& xRefUV, CoordI& yRefUV, CoordI& xRefUV1,CoordI& yRefUV1)
  147. {
  148. Int dx = 0, dy = 0;
  149. UInt uiDivisor = 2; //2 = Y->UV resolution change
  150. if (pmbmd -> m_bhas4MVForward) {
  151. uiDivisor *= 4; //4 = 4 blocks
  152. pmv++;
  153. for (UInt k = 1; k <= 4; k++){
  154. dx += pmv->m_vctTrueHalfPel.x;
  155. dy += pmv->m_vctTrueHalfPel.y;
  156. pmv++;
  157. }
  158. xRefUV = sign (dx) * (grgiMvRound16 [abs (dx) % 16] + (abs (dx) / 16) * 2);
  159. yRefUV = sign (dy) * (grgiMvRound16 [abs (dy) % 16] + (abs (dy) / 16) * 2);
  160. }
  161. // INTERLACE
  162. else if (pmbmd -> m_bFieldMV) {
  163. if(pmbmd->m_bForwardTop) {
  164. dx = pmv [6].m_vctTrueHalfPel.x;
  165. dy = pmv [6].m_vctTrueHalfPel.y;
  166. }
  167. else {
  168. dx = pmv [5].m_vctTrueHalfPel.x;
  169. dy = pmv [5].m_vctTrueHalfPel.y;
  170. }
  171. xRefUV = ((dx & 3) ? ((dx >> 1) | 1) : (dx>>1));
  172. yRefUV = ((dy & 6) ? ((dy >> 1) | 2) : (dy>>1));
  173. if(pmbmd->m_bForwardBottom) {
  174. dx = pmv [8].m_vctTrueHalfPel.x;
  175. dy = pmv [8].m_vctTrueHalfPel.y;
  176. }
  177. else {
  178. dx = pmv [7].m_vctTrueHalfPel.x;
  179. dy = pmv [7].m_vctTrueHalfPel.y;
  180. }
  181. xRefUV1 = ((dx & 3) ? ((dx >> 1) | 1) : (dx>>1));
  182. yRefUV1 = ((dy & 6) ? ((dy >> 1) | 2) : (dy>>1));
  183. }
  184. // ~INTERLACE
  185. else {
  186. dx = pmv->m_vctTrueHalfPel.x;
  187. dy = pmv->m_vctTrueHalfPel.y;
  188. xRefUV = sign (dx) * (grgiMvRound4  [abs (dx) % 4] + (abs (dx) / 4) * 2);
  189. yRefUV = sign (dy) * (grgiMvRound4  [abs (dy) % 4] + (abs (dy) / 4) * 2);
  190. }
  191. }
  192. Void CVideoObject::mvLookupUVWithShape (const CMBMode* pmbmd, const CMotionVector* pmv,
  193.    CoordI& xRefUV, CoordI& yRefUV)
  194. {
  195. Int* rgiMvRound = NULL;
  196. Int dx = 0, dy = 0;
  197. UInt uiDivisor = 0; //2 = Y->UV resolution change; another -> full pel
  198. if (pmbmd -> m_bhas4MVForward) {
  199. for (UInt i = Y_BLOCK1; i <= Y_BLOCK4; i++) {
  200. pmv++;
  201. if (pmbmd->m_rgTranspStatus [i] != ALL) {
  202. dx += pmv->m_vctTrueHalfPel.x;
  203. dy += pmv->m_vctTrueHalfPel.y;
  204. uiDivisor += 4;
  205. }
  206. }
  207. switch (uiDivisor) {
  208. case 4:
  209. rgiMvRound = grgiMvRound4;
  210. break;
  211. case 8:
  212. rgiMvRound = grgiMvRound8;
  213. break;
  214. case 12:
  215. rgiMvRound = grgiMvRound12;
  216. break;
  217. case 16:
  218. rgiMvRound = grgiMvRound16;
  219. break;
  220. }
  221. xRefUV = sign (dx) * (rgiMvRound [abs (dx) % uiDivisor] + (abs (dx) / uiDivisor) * 2);
  222. yRefUV = sign (dy) * (rgiMvRound [abs (dy) % uiDivisor] + (abs (dy) / uiDivisor) * 2);
  223. }
  224. else {
  225. dx = pmv->m_vctTrueHalfPel.x;
  226. dy = pmv->m_vctTrueHalfPel.y;
  227. xRefUV = sign (dx) * (grgiMvRound4  [abs (dx) % 4] + (abs (dx) / 4) * 2);
  228. yRefUV = sign (dy) * (grgiMvRound4  [abs (dy) % 4] + (abs (dy) / 4) * 2);
  229. }
  230. }
  231. Void CVideoObject::findMVpredGeneric (CVector& vecPred, 
  232.   const CMotionVector* pmv, 
  233.   const CMBMode* pmbmd, 
  234.   Int iBlk, 
  235.   Int iXMB, Int iYMB) const
  236. {
  237. static Bool rgbInBound [3];
  238. rgbInBound [0] = FALSE;
  239. rgbInBound [1] = FALSE;
  240. rgbInBound [2] = FALSE;
  241. Int nInBound = 0;
  242. CVector vctCandMV [3];
  243. UInt i;
  244. for (i = 0; i < 3; i++) {
  245. vctCandMV [i].x = 0;
  246. vctCandMV [i].y = 0;
  247. }
  248. Bool bLeftBndry, bRightBndry, bTopBndry;
  249. Int iMBnum = VPMBnum(iXMB, iYMB);
  250. bLeftBndry = bVPNoLeft(iMBnum, iXMB);
  251. bTopBndry = bVPNoTop(iMBnum);
  252. bRightBndry = bVPNoRightTop(iMBnum, iXMB);
  253. if (pmbmd->m_bhas4MVForward == TRUE) { //how about backward??
  254. switch (iBlk){
  255. case Y_BLOCK1:
  256. // Modified for error resilient mode by Toshiba(1997-11-14)
  257. // if (iXMB != 0 && validBlock (pmbmd - 1, gIndexOfCandBlk [iBlk] [0])) {
  258. if (!bLeftBndry && validBlock (pmbmd, pmbmd - 1, gIndexOfCandBlk [iBlk] [0])) {
  259. vctCandMV [0] = (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [iBlk] [0]) -> trueMVHalfPel ();
  260. rgbInBound [0] = TRUE;
  261. nInBound++;
  262. }
  263. if (iYMB != 0) {
  264. // Modified for error resilient mode by Toshiba(1997-11-14)
  265. // if (validBlock (pmbmd - m_iNumMBX, gIndexOfCandBlk [iBlk] [1])) {
  266. if (!bTopBndry && validBlock (pmbmd, pmbmd - m_iNumMBX, gIndexOfCandBlk [iBlk] [1])) {
  267. vctCandMV [1] = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [iBlk] [1])->trueMVHalfPel ();
  268. rgbInBound [1] = TRUE;
  269. nInBound++;
  270. }
  271. // Modified for error resilient mode by Toshiba(1997-11-14)
  272. // if (iXMB < m_iNumMBX - 1 && validBlock (pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [iBlk] [2])) {
  273. if (!bRightBndry && validBlock (pmbmd, pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [iBlk] [2])) {
  274. vctCandMV [2] = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [iBlk] [2])->trueMVHalfPel ();
  275. rgbInBound [2] = TRUE;
  276. nInBound++;
  277. }
  278. }
  279. break;
  280. case Y_BLOCK2:
  281. if (validBlock (pmbmd, pmbmd, gIndexOfCandBlk [iBlk] [0])) {
  282. vctCandMV [0] = (pmv +  gIndexOfCandBlk [iBlk] [0]) -> trueMVHalfPel ();
  283. rgbInBound [0] = TRUE;
  284. nInBound++;
  285. }
  286. if (iYMB != 0) {
  287. // Modified for error resilient mode by Toshiba(1997-11-14)
  288. // if (validBlock (pmbmd - m_iNumMBX, gIndexOfCandBlk [iBlk] [1])) {
  289. if (!bTopBndry && validBlock (pmbmd, pmbmd - m_iNumMBX, gIndexOfCandBlk [iBlk] [1])) {
  290. vctCandMV [1] = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [iBlk] [1]) -> trueMVHalfPel ();
  291. rgbInBound [1] = TRUE;
  292. nInBound++;
  293. }
  294. // Modified for error resilient mode by Toshiba(1997-11-14)
  295. // if (iXMB < m_iNumMBX - 1 && validBlock (pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [iBlk] [2])) {
  296. if (!bRightBndry && validBlock (pmbmd, pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [iBlk] [2])) {
  297. vctCandMV [2] = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [iBlk] [2]) -> trueMVHalfPel ();
  298. rgbInBound [2] = TRUE;
  299. nInBound++;
  300. }
  301. }
  302. break;
  303. case Y_BLOCK3:
  304. // Modified for error resilient mode by Toshiba(1997-11-14)
  305. // if (iXMB != 0 && validBlock (pmbmd - 1, gIndexOfCandBlk [iBlk] [0])) {
  306. if (!bLeftBndry && validBlock (pmbmd, pmbmd - 1, gIndexOfCandBlk [iBlk] [0])) {
  307. vctCandMV [0] = (pmv - PVOP_MV_PER_REF_PER_MB +  gIndexOfCandBlk [iBlk] [0]) -> trueMVHalfPel ();
  308. rgbInBound [0] = TRUE;
  309. nInBound++;
  310. }
  311. if (validBlock (pmbmd, pmbmd, gIndexOfCandBlk [iBlk] [1])) {
  312. vctCandMV [1] = (pmv + gIndexOfCandBlk [iBlk] [1]) -> trueMVHalfPel ();
  313. rgbInBound [1] = TRUE;
  314. nInBound++;
  315. }
  316. if (validBlock (pmbmd, pmbmd, gIndexOfCandBlk [iBlk] [2])) {
  317. vctCandMV [2] = (pmv + gIndexOfCandBlk [iBlk] [2]) -> trueMVHalfPel ();
  318. rgbInBound [2] = TRUE;
  319. nInBound++;
  320. }
  321. break;
  322. case Y_BLOCK4:
  323. if (validBlock (pmbmd, pmbmd, gIndexOfCandBlk [iBlk] [0])) {
  324. vctCandMV [0] = (pmv + gIndexOfCandBlk [iBlk] [0]) -> trueMVHalfPel ();
  325. rgbInBound [0] = TRUE;
  326. nInBound++;
  327. }
  328. if (validBlock (pmbmd, pmbmd, gIndexOfCandBlk [iBlk] [1])) {
  329. vctCandMV [1] = (pmv + gIndexOfCandBlk [iBlk] [1]) -> trueMVHalfPel ();
  330. rgbInBound [1] = TRUE;
  331. nInBound++;
  332. }
  333. if (validBlock (pmbmd, pmbmd, gIndexOfCandBlk [iBlk] [2])) {
  334. vctCandMV [2] = (pmv + gIndexOfCandBlk [iBlk] [2]) -> trueMVHalfPel ();
  335. rgbInBound [2] = TRUE;
  336. nInBound++;
  337. }
  338. break;
  339. }
  340. }
  341. else {
  342. // Modified for error resilient mode by Toshiba(1997-11-14)
  343. // if (iXMB != 0 && validBlock (pmbmd - 1, gIndexOfCandBlk [1] [0])) {
  344. if (!bLeftBndry && validBlock (pmbmd, pmbmd - 1, gIndexOfCandBlk [1] [0])) {
  345. vctCandMV [0] = (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0]) -> trueMVHalfPel ();
  346. rgbInBound [0] = TRUE;
  347. nInBound++;
  348. }
  349. if (iYMB != 0)   {
  350. // Modified for error resilient mode by Toshiba(1997-11-14)
  351. // if (validBlock (pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1])) {
  352. if (!bTopBndry && validBlock (pmbmd, pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1])) {
  353. vctCandMV [1] = (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1]) -> trueMVHalfPel ();
  354. rgbInBound [1] = TRUE;
  355. nInBound++;
  356. }
  357. // Modified for error resilient mode by Toshiba(1997-11-14)
  358. // if (iXMB < m_iNumMBX - 1 && validBlock (pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2])) {
  359. if (!bRightBndry && validBlock (pmbmd, pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2])) {
  360. vctCandMV [2] = (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2]) -> trueMVHalfPel ();
  361. rgbInBound [2] = TRUE;
  362. nInBound++;
  363. }
  364. }
  365. }
  366. if (nInBound == 1) {
  367. for (UInt i = 0; i < 3; i++) {
  368. if (rgbInBound [i] == TRUE) {
  369. vecPred = vctCandMV [i];
  370. return;
  371. }
  372. }
  373. }
  374. vecPred.x = medianof3 (vctCandMV [0].x, vctCandMV [1].x, vctCandMV [2].x);
  375. vecPred.y = medianof3 (vctCandMV [0].y, vctCandMV [1].y, vctCandMV [2].y);
  376. }
  377. Bool CVideoObject::validBlock (const CMBMode* pmbmdCurr, const CMBMode* pmbmd, BlockNum blkn) const
  378. {
  379. // block tests with mv padding
  380. if (pmbmd->m_rgTranspStatus [0] == ALL)
  381. return FALSE;
  382. else if(pmbmd != pmbmdCurr)
  383. return TRUE;
  384. else {
  385. if(pmbmd->m_rgTranspStatus [blkn] == ALL)
  386. return FALSE;
  387. else
  388. return TRUE;
  389. }
  390. }
  391. Void CVideoObject::findMVpredictorOfBVOP (CVector& vctPred, const CMotionVector* pmv, const CMBMode* pmbmd, Int iMBX) const       //for B-VOP only
  392. {
  393. vctPred.x = vctPred.y = 0; //intialize to 0
  394. MBType mbtypCurr = pmbmd->m_mbType;
  395. for (Int iMBXCandidate = iMBX - 1; iMBXCandidate >= 0; iMBXCandidate--) { //scan backward MBs
  396. pmbmd--;
  397. pmv -= 5;
  398. if (pmbmd->m_bSkip)
  399. return;
  400. else if (pmbmd->m_mbType == mbtypCurr && pmbmd->m_rgTranspStatus [0] != ALL) {
  401. vctPred = pmv->m_vctTrueHalfPel;
  402. return;
  403. }
  404. }
  405. return; //reach the start of the row; reset
  406. }
  407. Void CVideoObject::backwardMVFromForwardMV ( //compute back mv from forward mv and ref mv for direct mode
  408. CMotionVector& mvBackward, const CMotionVector& mvForward,
  409. const CMotionVector& mvRef, CVector vctDirectDeltaMV)
  410. {
  411. assert (mvForward.iMVX != NOT_MV && mvForward.iMVY != NOT_MV); //mv is valid
  412. CVector vctBackward;
  413. Int iFullInterval = m_tFutureRef - m_tPastRef;
  414. if (vctDirectDeltaMV.x == 0)
  415. vctBackward.x = (m_t - m_tFutureRef) * mvRef.m_vctTrueHalfPel.x / iFullInterval;
  416. else 
  417. vctBackward.x = mvForward.m_vctTrueHalfPel.x - mvRef.m_vctTrueHalfPel.x;
  418. if (vctDirectDeltaMV.y == 0)
  419. vctBackward.y = (m_t - m_tFutureRef) * mvRef.m_vctTrueHalfPel.y / iFullInterval;
  420. else 
  421. vctBackward.y = mvForward.m_vctTrueHalfPel.y - mvRef.m_vctTrueHalfPel.y;
  422. mvBackward = CMotionVector (vctBackward);
  423. }
  424. CVector CVideoObject::averageOfRefMV (const CMotionVector* pmvRef, const CMBMode* pmbmdRef)
  425. {
  426. assert(pmvRef!=NULL);
  427. CVector vctRef (0, 0);
  428. Int i;
  429. if (pmbmdRef -> m_bhas4MVForward) { //average
  430. Int iDivisor = 0;
  431. for (i = Y_BLOCK1; i <= Y_BLOCK4; i++) {
  432. pmvRef++;
  433. if (pmbmdRef->m_rgTranspStatus [i] != ALL) {
  434. assert (pmvRef->iMVX != NOT_MV);
  435. vctRef.x += pmvRef->m_vctTrueHalfPel.x;
  436. vctRef.y += pmvRef->m_vctTrueHalfPel.y;
  437. iDivisor += 1;
  438. }
  439. }
  440. vctRef.x = (Int) rounded((Float) vctRef.x / iDivisor);
  441. vctRef.y = (Int) rounded((Float) vctRef.y / iDivisor);
  442. }
  443. else {
  444. vctRef = pmvRef->m_vctTrueHalfPel;
  445. assert (pmvRef->iMVX != NOT_MV);
  446. }
  447. return vctRef;
  448. }
  449. Void CVideoObject::padMotionVectors (const CMBMode* pmbmd,CMotionVector *pmv)
  450. {
  451. if(pmbmd->m_rgTranspStatus[0]==ALL)
  452. return;
  453. if(pmbmd->m_rgTranspStatus[1]==ALL)
  454. {
  455. pmv[1]=(pmbmd->m_rgTranspStatus[2]!=ALL)?pmv[2]:
  456. ((pmbmd->m_rgTranspStatus[3]!=ALL)?pmv[3]:pmv[4]);
  457. }
  458. if(pmbmd->m_rgTranspStatus[2]==ALL)
  459. {
  460. pmv[2]=(pmbmd->m_rgTranspStatus[1]!=ALL)?pmv[1]:
  461. ((pmbmd->m_rgTranspStatus[4]!=ALL)?pmv[4]:pmv[3]);
  462. }
  463. if(pmbmd->m_rgTranspStatus[3]==ALL)
  464. {
  465. pmv[3]=(pmbmd->m_rgTranspStatus[4]!=ALL)?pmv[4]:
  466. ((pmbmd->m_rgTranspStatus[1]!=ALL)?pmv[1]:pmv[2]);
  467. }
  468. if(pmbmd->m_rgTranspStatus[4]==ALL)
  469. {
  470. pmv[4]=(pmbmd->m_rgTranspStatus[3]!=ALL)?pmv[3]:
  471. ((pmbmd->m_rgTranspStatus[2]!=ALL)?pmv[2]:pmv[1]);
  472. }
  473. }