Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1155 lines
37 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1995 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. // $Author: JMCVEIGH $
  15. // $Date: 21 Jan 1997 08:53:16 $
  16. // $Archive: S:\h26x\src\dec\d3mblk.cpv $
  17. // $Header: S:\h26x\src\dec\d3mblk.cpv 1.60 21 Jan 1997 08:53:16 JMCVEIGH $
  18. // $Log: S:\h26x\src\dec\d3mblk.cpv $
  19. //
  20. // Rev 1.60 21 Jan 1997 08:53:16 JMCVEIGH
  21. // Before we calculated the interpolated index for MC prior to
  22. // clipping for UMV. We might then reference outside of the 16 pel
  23. // wide padded border. Moved calculation of interp_index to after
  24. // UMV clipping.
  25. //
  26. // Rev 1.59 16 Dec 1996 17:45:26 JMCVEIGH
  27. // Proper motion vector decoding and prediction for forward prediction
  28. // in B portion of improved PB-frame.
  29. //
  30. // Rev 1.58 09 Dec 1996 15:54:10 GMLIM
  31. //
  32. // Added a debug message in H263BBlockPrediction() for the case where
  33. // TR == TR_Prev. Set iTRD = 256 to avoid divide by 0.
  34. //
  35. // Rev 1.57 27 Sep 1996 17:29:24 KLILLEVO
  36. //
  37. // added clipping of extended motion vectors for MMX
  38. //
  39. // Rev 1.56 26 Sep 1996 13:56:52 KLILLEVO
  40. //
  41. // fixed a totally bogus version of the extended motion vectors
  42. //
  43. // Rev 1.55 26 Sep 1996 11:32:16 KLILLEVO
  44. // extended motion vectors now work for AP on the P54C chip
  45. //
  46. // Rev 1.54 25 Sep 1996 08:05:32 KLILLEVO
  47. // initial extended motion vectors support
  48. // does not work for AP yet
  49. //
  50. // Rev 1.53 09 Jul 1996 16:46:00 AGUPTA2
  51. // MMX code now clears DC value for INTRA blocks and adds it back during
  52. // ClipANdMove; this is to solve overflow problem.
  53. //
  54. // Rev 1.52 29 May 1996 10:18:36 AGUPTA2
  55. // MMX need not be defd to use MMX decoder.
  56. //
  57. // Rev 1.51 04 Apr 1996 11:06:16 AGUPTA2
  58. // Added calls to MMX_BlockCopy().
  59. //
  60. // Rev 1.50 01 Apr 1996 13:05:28 RMCKENZX
  61. // Added MMx functionality for Advance Prediction and PB Frames.
  62. //
  63. // Rev 1.49 22 Mar 1996 17:50:30 AGUPTA2
  64. // MMX support. MMX support is included only if MMX defined. MMX is
  65. // not defined by default so that we do not impact IA code size.
  66. //
  67. // Rev 1.48 08 Mar 1996 16:46:22 AGUPTA2
  68. // Added pragmas code_seg and data_seg to place code and data in appropriate
  69. // segments. Created a function table of interpolation rtns.; interpolation
  70. // rtns. are now called thru this function table. Commented out the clipping of
  71. // MV code. It is not needed now and it needs to be re-written to be more
  72. // efficient.
  73. //
  74. //
  75. // Rev 1.47 23 Feb 1996 09:46:54 KLILLEVO
  76. // fixed decoding of Unrestricted Motion Vector mode
  77. //
  78. // Rev 1.46 29 Jan 1996 17:50:48 RMCKENZX
  79. // Reorganized logic in H263IDCTandMC for AP, optimizing the changes
  80. // made for revision 1.42 and simplifying logic for determining iNext[i].
  81. // Also corrected omission for UMV decoding in H263BBlockPrediction.
  82. //
  83. // Rev 1.0 29 Jan 1996 12:44:00 RMCKENZX
  84. // Initial revision.
  85. //
  86. // Rev 1.45 24 Jan 1996 13:22:06 BNICKERS
  87. // Turn OBMC back on.
  88. //
  89. // Rev 1.44 16 Jan 1996 11:46:22 RMCKENZX
  90. // Added support for UMV -- to correctly decode B-block
  91. // motion vectors when UMV is on
  92. //
  93. // Rev 1.43 15 Jan 1996 14:34:32 BNICKERS
  94. //
  95. // Temporarily turn off OBMC until encoder can be changed to do it too.
  96. //
  97. // Rev 1.42 12 Jan 1996 16:29:48 BNICKERS
  98. //
  99. // Correct OBMC to be spec compliant when neighbor is Intra coded.
  100. //
  101. // Rev 1.41 06 Jan 1996 18:36:58 RMCKENZX
  102. // Simplified rounding logic for chroma motion vector computation
  103. // using MUCH smaller tables (at the cost of a shift, add, and mask
  104. // per vector).
  105. //
  106. // Rev 1.40 05 Jan 1996 15:59:12 RMCKENZX
  107. //
  108. // fixed bug in decoding forward b-frame motion vectors
  109. // so that they will stay within the legal ranges.
  110. // re-organized the BBlockPredict function - using only
  111. // one test for 4 motion vectors and a unified call to
  112. // do the backward prediction for both lumina and chroma blocks.
  113. //
  114. // Rev 1.39 21 Dec 1995 17:05:24 TRGARDOS
  115. // Added comments about descrepancy with H.263 spec.
  116. //
  117. // Rev 1.38 21 Dec 1995 13:24:28 RMCKENZX
  118. // Fixed bug on pRefL, re-architected IDCTandMC
  119. //
  120. // Rev 1.37 18 Dec 1995 12:46:34 RMCKENZX
  121. // added copyright notice
  122. //
  123. // Rev 1.36 16 Dec 1995 20:34:04 RHAZRA
  124. //
  125. // Changed declaration of pRefX to U32
  126. //
  127. // Rev 1.35 15 Dec 1995 13:53:32 RHAZRA
  128. //
  129. // AP cleanup
  130. //
  131. // Rev 1.34 15 Dec 1995 10:51:38 RHAZRA
  132. //
  133. // Changed reference block addresses in AP
  134. //
  135. // Rev 1.33 14 Dec 1995 17:04:16 RHAZRA
  136. //
  137. // Cleanup in the if-then-else structure in the OBMC part
  138. //
  139. // Rev 1.32 13 Dec 1995 22:11:56 RHAZRA
  140. // AP cleanup
  141. //
  142. // Rev 1.31 13 Dec 1995 10:59:26 RHAZRA
  143. // More AP+PB fixes
  144. //
  145. // Rev 1.29 11 Dec 1995 11:33:12 RHAZRA
  146. // 12-10-95 changes: added AP stuff
  147. //
  148. // Rev 1.28 09 Dec 1995 17:31:22 RMCKENZX
  149. // Gutted and re-built file to support decoder re-architecture.
  150. // New modules are:
  151. // H263IDCTandMC
  152. // H263BFrameIDCTandBiMC
  153. // H263BBlockPrediction
  154. // This module now contains code to support the second pass of the decoder.
  155. //
  156. // Rev 1.27 23 Oct 1995 13:28:42 CZHU
  157. // Use the right quant for B blocks and call BlockAdd for type 3/4 too
  158. //
  159. // Rev 1.26 17 Oct 1995 17:18:24 CZHU
  160. // Fixed the bug in decoding PB block CBPC
  161. //
  162. // Rev 1.25 13 Oct 1995 16:06:20 CZHU
  163. // First version that supports PB frames. Display B or P frames under
  164. // VfW for now.
  165. //
  166. // Rev 1.24 11 Oct 1995 17:46:28 CZHU
  167. // Fixed bitstream bugs
  168. //
  169. // Rev 1.23 11 Oct 1995 13:26:00 CZHU
  170. // Added code to support PB frame
  171. //
  172. // Rev 1.22 27 Sep 1995 16:24:14 TRGARDOS
  173. //
  174. // Added debug print statements.
  175. //
  176. // Rev 1.21 26 Sep 1995 15:33:52 CZHU
  177. //
  178. // Adjusted buffers used for MB for inter frame motion compensation
  179. //
  180. // Rev 1.20 19 Sep 1995 10:37:04 CZHU
  181. //
  182. // Cleaning up
  183. //
  184. // Rev 1.19 15 Sep 1995 09:39:34 CZHU
  185. //
  186. // Update both GOB Quant and Picture Quant after DQUANT
  187. //
  188. // Rev 1.18 14 Sep 1995 10:11:48 CZHU
  189. // Fixed bugs updating Quant for the picture
  190. //
  191. // Rev 1.17 13 Sep 1995 11:57:08 CZHU
  192. //
  193. // Fixed bugs in calling Chroma BlockAdd parameters.
  194. //
  195. // Rev 1.16 12 Sep 1995 18:18:40 CZHU
  196. // Call BlockAdd finally.
  197. //
  198. // Rev 1.15 12 Sep 1995 11:12:38 CZHU
  199. // Call blockCopy for MB that is not coded.
  200. //
  201. // Rev 1.14 11 Sep 1995 16:43:26 CZHU
  202. // Changed interface to DecodeBlock. Added interface calls to BlockCopy and Bl
  203. //
  204. // Rev 1.13 11 Sep 1995 14:30:12 CZHU
  205. // MVs decoding.
  206. //
  207. // Rev 1.12 08 Sep 1995 11:48:12 CZHU
  208. // Added support for Delta frames, also fixed early bugs regarding INTER CBPY
  209. //
  210. // Rev 1.11 25 Aug 1995 09:16:32 DBRUCKS
  211. // add ifdef DEBUG_MBLK
  212. //
  213. // Rev 1.10 23 Aug 1995 19:12:02 AKASAI
  214. // Fixed gNewTAB_CBPY table building. Was using 8 as mask instead of 0xf.
  215. //
  216. // Rev 1.9 18 Aug 1995 15:03:22 CZHU
  217. //
  218. // Output more error message when DecodeBlock returns error.
  219. //
  220. // Rev 1.8 16 Aug 1995 14:26:54 CZHU
  221. //
  222. // Changed DWORD adjustment back to byte oriented reading.
  223. //
  224. // Rev 1.7 15 Aug 1995 09:54:18 DBRUCKS
  225. // improve stuffing handling and add debug msg
  226. //
  227. // Rev 1.6 14 Aug 1995 18:00:40 DBRUCKS
  228. // add chroma parsing
  229. //
  230. // Rev 1.5 11 Aug 1995 17:47:58 DBRUCKS
  231. // cleanup
  232. //
  233. // Rev 1.4 11 Aug 1995 16:12:28 DBRUCKS
  234. // add ptr check to MB data
  235. //
  236. // Rev 1.3 11 Aug 1995 15:10:58 DBRUCKS
  237. // finish INTRA mb header parsing and callblock
  238. //
  239. // Rev 1.2 03 Aug 1995 14:30:26 CZHU
  240. // Take block level operations out to d3block.cpp
  241. //
  242. // Rev 1.1 02 Aug 1995 10:21:12 CZHU
  243. // Added asm codes for VLD of TCOEFF, inverse quantization, run-length decode.
  244. //
  245. // Rev 1.0 31 Jul 1995 13:00:08 DBRUCKS
  246. // Initial revision.
  247. //
  248. // Rev 1.2 31 Jul 1995 11:45:42 CZHU
  249. // changed the parameter list
  250. //
  251. // Rev 1.1 28 Jul 1995 16:25:52 CZHU
  252. //
  253. // Added per block decoding framework.
  254. //
  255. // Rev 1.0 28 Jul 1995 15:20:16 CZHU
  256. // Initial revision.
  257. //Block level decoding for H.26x decoder
  258. #include "precomp.h"
  259. extern "C" {
  260. void H263BiMotionComp(U32, U32, I32, I32, I32);
  261. void H263OBMC(U32, U32, U32, U32, U32, U32);
  262. }
  263. #ifdef USE_MMX // { USE_MMX
  264. extern "C" {
  265. void MMX_AdvancePredict(T_BlkAction FAR *, int *, U8 *, I8 *, I8 *);
  266. void MMX_BiMotionComp(U32, U32, I32, I32, I32);
  267. }
  268. #endif // } USE_MMX
  269. void AdvancePredict(T_BlkAction FAR *fpBlockAction, int *iNext, U8 *pDst, int, int, BOOL);
  270. #pragma data_seg("IARDATA2")
  271. char QuarterPelRound[] =
  272. {0, 1, 0, 0};
  273. char SixteenthPelRound[] =
  274. {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1};
  275. void (*Interpolate_Table[4])(U32, U32) =
  276. {NULL,
  277. Interpolate_Half_Int,
  278. Interpolate_Int_Half,
  279. Interpolate_Half_Half};
  280. #ifdef USE_MMX // { USE_MMX
  281. void (_fastcall * MMX_Interpolate_Table[4])(U32, U32) =
  282. {NULL,
  283. MMX_Interpolate_Half_Int,
  284. MMX_Interpolate_Int_Half,
  285. MMX_Interpolate_Half_Half};
  286. #endif // } USE_MMX
  287. I8 i8EMVClipTbl_NoClip[128] = {
  288. -64,-63,-62,-61,-60,-59,-58,-57,
  289. -56,-55,-54,-53,-52,-51,-50,-49,
  290. -48,-47,-46,-45,-44,-43,-42,-41,
  291. -40,-39,-38,-37,-36,-35,-34,-33,
  292. -32,-31,-30,-29,-28,-27,-26,-25,
  293. -24,-23,-22,-21,-20,-19,-18,-17,
  294. -16,-15,-14,-13,-12,-11,-10, -9,
  295. -8, -7, -6, -5, -4, -3, -2, -1,
  296. 0, 1, 2, 3, 4, 5, 6, 7,
  297. 8, 9, 10, 11, 12, 13, 14, 15,
  298. 16, 17, 18, 19, 20, 21, 22, 23,
  299. 24, 25, 26, 27, 28, 29, 30, 31,
  300. 32, 33, 34, 35, 36, 37, 38, 39,
  301. 40, 41, 42, 43, 44, 45, 46, 47,
  302. 48, 49, 50, 51, 52, 53, 54, 55,
  303. 56, 57, 58, 59, 60, 61, 62, 63,
  304. };
  305. I8 i8EMVClipTbl_HiClip[128] = {
  306. -64,-63,-62,-61,-60,-59,-58,-57,
  307. -56,-55,-54,-53,-52,-51,-50,-49,
  308. -48,-47,-46,-45,-44,-43,-42,-41,
  309. -40,-39,-38,-37,-36,-35,-34,-33,
  310. -32,-31,-30,-29,-28,-27,-26,-25,
  311. -24,-23,-22,-21,-20,-19,-18,-17,
  312. -16,-15,-14,-13,-12,-11,-10, -9,
  313. -8, -7, -6, -5, -4, -3, -2, -1,
  314. 0, 1, 2, 3, 4, 5, 6, 7,
  315. 8, 9, 10, 11, 12, 13, 14, 15,
  316. 16, 17, 18, 19, 20, 21, 22, 23,
  317. 24, 25, 26, 27, 28, 29, 30, 31,
  318. 32, 32, 32, 32, 32, 32, 32, 32,
  319. 32, 32, 32, 32, 32, 32, 32, 32,
  320. 32, 32, 32, 32, 32, 32, 32, 32,
  321. 32, 32, 32, 32, 32, 32, 32, 32,
  322. };
  323. I8 i8EMVClipTbl_LoClip[128] = {
  324. -32,-32,-32,-32,-32,-32,-32,-32,
  325. -32,-32,-32,-32,-32,-32,-32,-32,
  326. -32,-32,-32,-32,-32,-32,-32,-32,
  327. -32,-32,-32,-32,-32,-32,-32,-32,
  328. -32,-31,-30,-29,-28,-27,-26,-25,
  329. -24,-23,-22,-21,-20,-19,-18,-17,
  330. -16,-15,-14,-13,-12,-11,-10, -9,
  331. -8, -7, -6, -5, -4, -3, -2, -1,
  332. 0, 1, 2, 3, 4, 5, 6, 7,
  333. 8, 9, 10, 11, 12, 13, 14, 15,
  334. 16, 17, 18, 19, 20, 21, 22, 23,
  335. 24, 25, 26, 27, 28, 29, 30, 31,
  336. 32, 33, 34, 35, 36, 37, 38, 39,
  337. 40, 41, 42, 43, 44, 45, 46, 47,
  338. 48, 49, 50, 51, 52, 53, 54, 55,
  339. 56, 57, 58, 59, 60, 61, 62, 63,
  340. };
  341. #pragma data_seg(".data")
  342. #pragma code_seg("IACODE2")
  343. // doing this as a function instead of a macro should save
  344. // some codespace.
  345. void UmvOnEdgeClipMotionVectors2(I32 *mvx, I32 *mvy, int EdgeFlag, int BlockNo)
  346. {
  347. int MaxVec;
  348. if (BlockNo < 4)
  349. MaxVec = 32;
  350. else
  351. MaxVec = 16;
  352. if (EdgeFlag & LEFT_EDGE)
  353. {
  354. if (*mvx < -MaxVec)
  355. *mvx = -MaxVec;
  356. }
  357. if (EdgeFlag & RIGHT_EDGE)
  358. {
  359. if (*mvx > MaxVec )
  360. *mvx = MaxVec ;
  361. }
  362. if (EdgeFlag & TOP_EDGE)
  363. {
  364. if (*mvy < -MaxVec )
  365. *mvy = -MaxVec ;
  366. }
  367. if (EdgeFlag & BOTTOM_EDGE)
  368. {
  369. if (*mvy > MaxVec )
  370. *mvy = MaxVec ;
  371. }
  372. }
  373. #pragma code_seg()
  374. /*****************************************************************************
  375. *
  376. * H263IDCTandMC
  377. *
  378. * Inverse Discrete Cosine Transform and
  379. * Motion Compensation for each block
  380. *
  381. */
  382. #pragma code_seg("IACODE2")
  383. void H263IDCTandMC(
  384. T_H263DecoderCatalog FAR *DC,
  385. T_BlkAction FAR *fpBlockAction,
  386. int iBlock,
  387. int iMBNum, // AP-NEW
  388. int iGOBNum, // AP-NEW
  389. U32 *pN,
  390. T_IQ_INDEX *pRUN_INVERSE_Q,
  391. T_MBInfo *fpMBInfo, // AP-NEW
  392. int iEdgeFlag
  393. )
  394. {
  395. I32 pRef;
  396. int iNext[4]; // Left-Right-Above-Below
  397. I32 mvx, mvy;
  398. U32 pRefTmp;
  399. int i;
  400. ASSERT(*pN != 65);
  401. if (*pN < 65) // Inter block
  402. {
  403. int interp_index;
  404. // first do motion compensation
  405. // result will be pointed to by pRef
  406. pRef = (U32) DC + DC->uMBBuffer;
  407. mvx = fpBlockAction[iBlock].i8MVx2;
  408. mvy = fpBlockAction[iBlock].i8MVy2;
  409. // Clip motion vectors pointing outside active image area
  410. if (DC->bUnrestrictedMotionVectors)
  411. {
  412. UmvOnEdgeClipMotionVectors2(&mvx,&mvy,iEdgeFlag,iBlock);
  413. }
  414. pRefTmp = fpBlockAction[iBlock].pRefBlock +
  415. (I32) (mvx >> 1) +
  416. PITCH * (I32) (mvy >> 1);
  417. // Must calculate AFTER UMV clipping
  418. interp_index = ((mvy & 0x1)<<1) | (mvx & 0x1);
  419. // Do non-OBMC prediction if this is a chroma block OR
  420. // a luma block in non-AP mode of operation
  421. if ( (!DC->bAdvancedPrediction) || (iBlock > 3) )
  422. {
  423. if (interp_index)
  424. {
  425. // TODO
  426. #ifdef USE_MMX // { USE_MMX
  427. if (DC->bMMXDecoder)
  428. (*MMX_Interpolate_Table[interp_index])(pRefTmp, pRef);
  429. else
  430. (*Interpolate_Table[interp_index])(pRefTmp, pRef);
  431. #else // }{ USE_MMX
  432. (*Interpolate_Table[interp_index])(pRefTmp, pRef);
  433. #endif // } USE_MMX
  434. }
  435. else
  436. pRef = pRefTmp;
  437. }
  438. else // Overlapped block motion compensation
  439. {
  440. ASSERT (DC->bAdvancedPrediction);
  441. ASSERT ( (iBlock <= 3) );
  442. // Compute iNext[i] which will point at the adjacent blocks.
  443. // Left & Right blocks
  444. if (iBlock & 1) { // blocks 1 or 3, on right
  445. iNext[0] = -1;
  446. if ( iMBNum == DC->iNumberOfMBsPerGOB )
  447. iNext[1] = 0;
  448. else
  449. iNext[1] = 5;
  450. }
  451. else { // blocks 0 or 2, on left
  452. iNext[1] = 1;
  453. if (iMBNum == 1)
  454. iNext[0] = 0;
  455. else
  456. iNext[0] = -5;
  457. }
  458. // Above & Below blocks
  459. if (iBlock > 1) { // blocks 2 or 3, on bottom
  460. iNext[2] = -2;
  461. iNext[3] = 0;
  462. }
  463. else { // blocks 0 or 1, on top
  464. iNext[3] = 2;
  465. if (iGOBNum == 1)
  466. iNext[2] = 0;
  467. else
  468. iNext[2] = -6*DC->iNumberOfMBsPerGOB + 2;
  469. }
  470. // When PB frames are OFF
  471. // if there is a neighbor and it is INTRA, use this block's vector instead.
  472. if (!DC->bPBFrame)
  473. for (i=0; i<4; i++)
  474. // block types: 0=INTRA_DC, 1=INTRA, 2=INTER, 3=EMPTY, 4=ERROR
  475. if (iNext[i] && fpBlockAction[iBlock+iNext[i]].u8BlkType < 2)
  476. iNext[i] = 0;
  477. // Now do overlapped motion compensation; output to pRef
  478. #ifdef USE_MMX // { USE_MMX
  479. if (DC->bMMXDecoder)
  480. {
  481. I8 *pClipX, *pClipY;
  482. pClipY = pClipX = &i8EMVClipTbl_NoClip[0];
  483. if (DC->bUnrestrictedMotionVectors)
  484. {
  485. if (iEdgeFlag & TOP_EDGE)
  486. pClipY = &i8EMVClipTbl_LoClip[0];
  487. else if (iEdgeFlag & BOTTOM_EDGE)
  488. pClipY = &i8EMVClipTbl_HiClip[0];
  489. if (iEdgeFlag & LEFT_EDGE)
  490. pClipX = &i8EMVClipTbl_LoClip[0];
  491. else if (iEdgeFlag & RIGHT_EDGE)
  492. pClipX = &i8EMVClipTbl_HiClip[0];
  493. }
  494. MMX_AdvancePredict(fpBlockAction+iBlock, iNext, (U8*)pRef, pClipX, pClipY);
  495. }
  496. else
  497. AdvancePredict(fpBlockAction+iBlock, iNext, (U8*)pRef, iEdgeFlag, iBlock, DC->bUnrestrictedMotionVectors);
  498. #else // }{ USE_MMX
  499. AdvancePredict(fpBlockAction+iBlock, iNext, (U8*)pRef, iEdgeFlag, iBlock, DC->bUnrestrictedMotionVectors);
  500. #endif // } USE_MMX
  501. } // end OBMC
  502. // now do the inverse transform (where appropriate) & combine
  503. if (*pN > 0) // and, of course, < 65.
  504. {
  505. // Get residual block; output at DC+DC->uMBBuffer+BLOCK_BUFFER_OFFSET
  506. // Finally add the residual to the reference block
  507. // TODO
  508. #ifdef USE_MMX // { USE_MMX
  509. if (DC->bMMXDecoder)
  510. {
  511. MMX_DecodeBlock_IDCT(
  512. (U32)pRUN_INVERSE_Q,
  513. *pN,
  514. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET); // inter output
  515. MMX_BlockAdd(
  516. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // output
  517. pRef, // prediction
  518. fpBlockAction[iBlock].pCurBlock); // destination
  519. }
  520. else
  521. {
  522. DecodeBlock_IDCT(
  523. (U32)pRUN_INVERSE_Q,
  524. *pN,
  525. fpBlockAction[iBlock].pCurBlock, // not used here
  526. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);// inter output
  527. BlockAdd(
  528. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // output
  529. pRef, // prediction
  530. fpBlockAction[iBlock].pCurBlock); // destination
  531. }
  532. #else // }{ USE_MMX
  533. DecodeBlock_IDCT(
  534. (U32)pRUN_INVERSE_Q,
  535. *pN,
  536. fpBlockAction[iBlock].pCurBlock, // not used here
  537. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);// inter output
  538. BlockAdd(
  539. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // output
  540. pRef, // prediction
  541. fpBlockAction[iBlock].pCurBlock); // destination
  542. #endif // } USE_MMX
  543. }
  544. else // *pN == 0, so no transform coefficients for this block
  545. {
  546. // Just copy motion compensated reference block
  547. #ifdef USE_MMX // { USE_MMX
  548. if (DC->bMMXDecoder)
  549. MMX_BlockCopy(
  550. fpBlockAction[iBlock].pCurBlock, // destination
  551. pRef); // prediction
  552. else
  553. BlockCopy(
  554. fpBlockAction[iBlock].pCurBlock, // destination
  555. pRef); // prediction
  556. #else // }{ USE_MMX
  557. BlockCopy(
  558. fpBlockAction[iBlock].pCurBlock, // destination
  559. pRef); // prediction
  560. #endif // } USE_MMX
  561. }
  562. }
  563. else // *pN >= 65, hence intRA
  564. {
  565. // TODO
  566. #ifdef USE_MMX // { USE_MMX
  567. if (DC->bMMXDecoder)
  568. {
  569. U32 ScaledDC = pRUN_INVERSE_Q->dInverseQuant;
  570. pRUN_INVERSE_Q->dInverseQuant = 0;
  571. MMX_DecodeBlock_IDCT(
  572. (U32)pRUN_INVERSE_Q, //
  573. *pN - 65, // No. of coeffs
  574. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);
  575. MMX_ClipAndMove((U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET,
  576. fpBlockAction[iBlock].pCurBlock, (U32)ScaledDC);
  577. }
  578. else
  579. DecodeBlock_IDCT(
  580. (U32)pRUN_INVERSE_Q,
  581. *pN,
  582. fpBlockAction[iBlock].pCurBlock, // INTRA transform output
  583. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);
  584. #else // }{ USE_MMX
  585. DecodeBlock_IDCT(
  586. (U32)pRUN_INVERSE_Q,
  587. *pN,
  588. fpBlockAction[iBlock].pCurBlock, // INTRA transform output
  589. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET);
  590. #endif // } USE_MMX
  591. } // end if (*pN < 65) ... else ...
  592. }
  593. // End IDCTandMC
  594. ////////////////////////////////////////////////////////////////////////////////
  595. #pragma code_seg()
  596. /*****************************************************************************
  597. *
  598. * AdvancePredict
  599. *
  600. * Motion Compensation for Advance Prediction
  601. * This module is only called in the non-MMx case.
  602. * In the MMx case, MMX_AdvancePredict is called instead.
  603. *
  604. ****************************************************************************/
  605. #pragma code_seg("IACODE2")
  606. void AdvancePredict(
  607. T_BlkAction FAR *fpBlockAction,
  608. int *iNext,
  609. U8 *pDst,
  610. int iEdgeFlag,
  611. int iBlock,
  612. BOOL bUnrestrictedMotionVectors
  613. )
  614. {
  615. U32 pRefC, pRefN[4]; // Left-Right-Above-Below
  616. I32 mvx, mvy;
  617. U32 pRefTmp;
  618. int i;
  619. int interp_index;
  620. mvx = fpBlockAction->i8MVx2;
  621. mvy = fpBlockAction->i8MVy2;
  622. // Clip motion vectors pointing outside active image area
  623. if (bUnrestrictedMotionVectors)
  624. {
  625. UmvOnEdgeClipMotionVectors2(&mvx,&mvy,iEdgeFlag,iBlock);
  626. }
  627. interp_index = ((mvy & 0x1)<<1) | (mvx & 0x1);
  628. pRefTmp = fpBlockAction->pRefBlock +
  629. (I32) (mvx >> 1) +
  630. PITCH * (I32) (mvy >> 1);
  631. pRefC = (U32) pDst + 8;
  632. pRefN[0] = (U32) pDst + 16;
  633. pRefN[1] = (U32) pDst + 24;
  634. pRefN[2] = (U32) pDst + 32;
  635. pRefN[3] = (U32) pDst + 40;
  636. // Current block
  637. if (interp_index)
  638. (*Interpolate_Table[interp_index])(pRefTmp, pRefC);
  639. else
  640. pRefC = pRefTmp;
  641. // Compute and apply motion vectors
  642. // Prediction is placed at pRefN[i]
  643. for (i=0; i<4; i++) {
  644. if (iNext[i]) {
  645. // Get the motion vector components.
  646. // Note that for macroblocks that were not coded, THESE MUST BE 0!
  647. // (Which is what H263InitializeBlockActionStream sets them to.)
  648. mvx = fpBlockAction[iNext[i]].i8MVx2;
  649. mvy = fpBlockAction[iNext[i]].i8MVy2;
  650. // Clip motion vectors pointing outside active image area
  651. if (bUnrestrictedMotionVectors)
  652. {
  653. UmvOnEdgeClipMotionVectors2(&mvx,&mvy,iEdgeFlag,iBlock);
  654. }
  655. // apply motion vector to get reference block at pRefN[i]
  656. pRefTmp = fpBlockAction->pRefBlock +
  657. (I32) (mvx >> 1) +
  658. PITCH * (I32) (mvy >> 1);
  659. // do interpolation if needed
  660. interp_index = ((mvy & 0x1)<<1) | (mvx & 0x1);
  661. if (interp_index)
  662. (*Interpolate_Table[interp_index])(pRefTmp, pRefN[i]);
  663. else
  664. pRefN[i] = pRefTmp;
  665. } // end if (iNext[i])
  666. else { // use this block's reference
  667. pRefN[i] = pRefC;
  668. } // end if (iNext[i] && ...) ... else ...
  669. } // end for (i=0; i<4; i++) {}
  670. // Now do overlapped motion compensation.
  671. H263OBMC(pRefC, pRefN[0], pRefN[1], pRefN[2], pRefN[3], (U32)pDst);
  672. }
  673. // End AdvancePredict
  674. ////////////////////////////////////////////////////////////////////////////////
  675. #pragma code_seg()
  676. /*****************************************************************************
  677. *
  678. * BBlockPrediction
  679. *
  680. * Compute the predictions from the "forward" and "backward" motion vectors.
  681. *
  682. ****************************************************************************/
  683. #pragma code_seg("IACODE2")
  684. void H263BBlockPrediction(
  685. T_H263DecoderCatalog FAR *DC,
  686. T_BlkAction FAR *fpBlockAction,
  687. U32 pRef[],
  688. T_MBInfo FAR *fpMBInfo,
  689. int iEdgeFlag
  690. )
  691. {
  692. //find out the MVf and MVb first from TR
  693. I32 mv_f_x[6], mv_b_x[6], mv_f_y[6], mv_b_y[6];
  694. I32 mvx_expectation, mvy_expectation;
  695. I32 iTRD, iTRB;
  696. I32 i;
  697. U32 pRefTmp;
  698. int mvfx, mvbx, mvfy, mvby;
  699. FX_ENTRY("H263BBlockPrediction")
  700. iTRB = DC->uBFrameTempRef;
  701. iTRD = DC->uTempRef - DC->uTempRefPrev;
  702. if (!iTRD)
  703. {
  704. DEBUGMSG(ZONE_DECODE_DETAILS, ("%s: Warning: given TR == last TR, set TRD = 256\r\n", _fx_));
  705. iTRD = 256;
  706. }
  707. else
  708. if (iTRD < 0)
  709. iTRD += 256;
  710. // final MVD for P blocks is in
  711. // fpBlockAction[0].i8MVx2,... and fpBlockAction[3].i8MVx2, and
  712. // fpBlockAction[0].i8MVy2,... and fpBlockAction[3].i8MVy2.
  713. // check for 4 motion vectors per macroblock
  714. // TODO can motion vector calculation be done in the first pass
  715. if (fpMBInfo->i8MBType == 2)
  716. { // yep, we got 4 of 'em
  717. #ifdef H263P
  718. // If H.263+, we can have 8x8 MV's if the deblocking filter
  719. // was selected.
  720. ASSERT(DC->bAdvancedPrediction || DC->bDeblockingFilter);
  721. #else
  722. ASSERT(DC->bAdvancedPrediction);
  723. #endif
  724. // Do luma vectors first
  725. for (i=0; i<4; i++)
  726. {
  727. #ifdef H263P
  728. // If we are using improved PB-frame mode (H.263+) and the B-block
  729. // was signalled to be predicted in the forward direction only,
  730. // the motion vector contained in MVDB is the actual forward MV -
  731. // no prediction is used.
  732. if (DC->bImprovedPBFrames == TRUE &&
  733. fpMBInfo->bForwardPredOnly == TRUE)
  734. {
  735. // Zero-out the expectation (the motion vector prediction)
  736. mvx_expectation = 0;
  737. mvy_expectation = 0;
  738. }
  739. else
  740. #endif
  741. {
  742. // compute forward expectation
  743. mvx_expectation = ( iTRB * (I32)fpBlockAction[i].i8MVx2 / iTRD );
  744. mvy_expectation = ( iTRB * (I32)fpBlockAction[i].i8MVy2 / iTRD );
  745. }
  746. // add in differential
  747. mv_f_x[i] = mvx_expectation + fpMBInfo->i8MVDBx2;
  748. mv_f_y[i] = mvy_expectation + fpMBInfo->i8MVDBy2;
  749. // check to see if the differential carried us too far
  750. if (DC->bUnrestrictedMotionVectors)
  751. {
  752. if (mvx_expectation > 32)
  753. {
  754. if (mv_f_x[i] > 63) mv_f_x[i] -=64;
  755. }
  756. else if (mvx_expectation < -31)
  757. {
  758. if (mv_f_x[i] < -63) mv_f_x[i] +=64;
  759. } // always use "first column" when expectation lies in [-31, +32]
  760. if (mvy_expectation > 32)
  761. {
  762. if (mv_f_y[i] > 63) mv_f_y[i] -=64;
  763. }
  764. else if (mvy_expectation < -31)
  765. {
  766. if (mv_f_y[i] < -63) mv_f_y[i] +=64;
  767. }
  768. }
  769. else // UMV off
  770. {
  771. if (mv_f_x[i] >= 32) mv_f_x[i] -= 64;
  772. else if (mv_f_x[i] < -32) mv_f_x[i] += 64;
  773. if (mv_f_y[i] >= 32) mv_f_y[i] -= 64;
  774. else if (mv_f_y[i] < -32) mv_f_y[i] += 64;
  775. } // end if (UMV) ... else ...
  776. // Do backwards motion vectors
  777. // Backward vectors are not required if using improved PB-frame mode
  778. // and the B-block uses only forward prediction. We will keep the calculation
  779. // of mv_b_{x,y} here since it doesn't harm anything.
  780. // TODO
  781. if (fpMBInfo->i8MVDBx2)
  782. mv_b_x[i] = mv_f_x[i] - fpBlockAction[i].i8MVx2;
  783. else
  784. mv_b_x[i] = ( (iTRB - iTRD) * (I32)fpBlockAction[i].i8MVx2 / iTRD );
  785. if (fpMBInfo->i8MVDBy2)
  786. mv_b_y[i] = mv_f_y[i] - fpBlockAction[i].i8MVy2;
  787. else
  788. mv_b_y[i] = ( (iTRB - iTRD) * (I32)fpBlockAction[i].i8MVy2 / iTRD );
  789. } // end for(i=0; i<4; i++){}
  790. // Now do the chromas
  791. // first get average times 4
  792. for (i=0, mvfx=mvbx=mvfy=mvby=0; i<4; i++)
  793. {
  794. mvfx += mv_f_x[i];
  795. mvfy += mv_f_y[i];
  796. mvbx += mv_b_x[i];
  797. mvby += mv_b_y[i];
  798. }
  799. // now interpolate
  800. mv_f_x[4] = mv_f_x[5] = (mvfx >> 3) + SixteenthPelRound[mvfx & 0x0f];
  801. mv_f_y[4] = mv_f_y[5] = (mvfy >> 3) + SixteenthPelRound[mvfy & 0x0f];
  802. mv_b_x[4] = mv_b_x[5] = (mvbx >> 3) + SixteenthPelRound[mvbx & 0x0f];
  803. mv_b_y[4] = mv_b_y[5] = (mvby >> 3) + SixteenthPelRound[mvby & 0x0f];
  804. }
  805. else // only 1 motion vector for this macroblock
  806. {
  807. #ifdef H263P
  808. // If we are using improved PB-frame mode (H.263+) and the B-block
  809. // was signalled to be predicted in the forward direction only,
  810. // the motion vector contained in MVDB is the actual forward MV -
  811. // no prediction is used.
  812. if (DC->bImprovedPBFrames == TRUE &&
  813. fpMBInfo->bForwardPredOnly == TRUE)
  814. {
  815. // Zero-out the expectation (the motion vector prediction)
  816. mvx_expectation = 0;
  817. mvy_expectation = 0;
  818. }
  819. else
  820. #endif
  821. {
  822. // compute forward expectation
  823. mvx_expectation = ( iTRB * (I32)fpBlockAction[0].i8MVx2 / iTRD );
  824. mvy_expectation = ( iTRB * (I32)fpBlockAction[0].i8MVy2 / iTRD );
  825. }
  826. // add in differential
  827. mv_f_x[0] = mvx_expectation + fpMBInfo->i8MVDBx2;
  828. mv_f_y[0] = mvy_expectation + fpMBInfo->i8MVDBy2;
  829. // check to see if the differential carried us too far
  830. // TODO: Clipping of motion vector needs to happen when decoder needs
  831. // to interoperate
  832. if (DC->bUnrestrictedMotionVectors)
  833. {
  834. if (mvx_expectation > 32)
  835. {
  836. if (mv_f_x[0] > 63) mv_f_x[0] -=64;
  837. }
  838. else if (mvx_expectation < -31)
  839. {
  840. if (mv_f_x[0] < -63) mv_f_x[0] +=64;
  841. } // always use "first column" when expectation lies in [-31, +32]
  842. if (mvy_expectation > 32)
  843. {
  844. if (mv_f_y[0] > 63) mv_f_y[0] -=64;
  845. }
  846. else if (mvy_expectation < -31)
  847. {
  848. if (mv_f_y[0] < -63) mv_f_y[0] +=64;
  849. }
  850. }
  851. else // UMV off, decode normally
  852. {
  853. if (mv_f_x[0] >= 32) mv_f_x[0] -= 64;
  854. else if (mv_f_x[0] < -32) mv_f_x[0] += 64;
  855. if (mv_f_y[0] >= 32) mv_f_y[0] -= 64;
  856. else if (mv_f_y[0] < -32) mv_f_y[0] += 64;
  857. } // finished decoding
  858. // copy for other 3 motion vectors
  859. mv_f_x[1] = mv_f_x[2] = mv_f_x[3] = mv_f_x[0];
  860. mv_f_y[1] = mv_f_y[2] = mv_f_y[3] = mv_f_y[0];
  861. // do backwards motion vectors
  862. // Backward vectors are not required if using improved PB-frame mode
  863. // and the B-block uses only forward prediction. We will keep the calculation
  864. // of mv_b_{x,y} here since it doesn't harm anything.
  865. // TODO
  866. if (fpMBInfo->i8MVDBx2)
  867. mv_b_x[0] = mv_f_x[0] - fpBlockAction[0].i8MVx2;
  868. else
  869. mv_b_x[0] = ( (iTRB - iTRD) * (I32)fpBlockAction[0].i8MVx2 / iTRD );
  870. if (fpMBInfo->i8MVDBy2)
  871. mv_b_y[0] = mv_f_y[0] - fpBlockAction[0].i8MVy2;
  872. else
  873. mv_b_y[0] = ( (iTRB - iTRD) * (I32)fpBlockAction[0].i8MVy2 / iTRD );
  874. // copy for other 3 motion vectors
  875. mv_b_x[1] = mv_b_x[2] = mv_b_x[3] = mv_b_x[0];
  876. mv_b_y[1] = mv_b_y[2] = mv_b_y[3] = mv_b_y[0];
  877. // interpolate for chroma
  878. mv_f_x[4] = mv_f_x[5] = (mv_f_x[0] >> 1) + QuarterPelRound[mv_f_x[0] & 0x03];
  879. mv_f_y[4] = mv_f_y[5] = (mv_f_y[0] >> 1) + QuarterPelRound[mv_f_y[0] & 0x03];
  880. mv_b_x[4] = mv_b_x[5] = (mv_b_x[0] >> 1) + QuarterPelRound[mv_b_x[0] & 0x03];
  881. mv_b_y[4] = mv_b_y[5] = (mv_b_y[0] >> 1) + QuarterPelRound[mv_b_y[0] & 0x03];
  882. } // end else 1 motion vector per macroblock
  883. // Prediction from Previous decoder P frames, referenced by RefBlock
  884. // Note: The previous decoder P blocks in in RefBlock, and
  885. // the just decoder P blocks are in CurBlock
  886. // the target B blocks are in BBlock
  887. // translate MV into address of reference blocks.
  888. pRefTmp = (U32) DC + DC->uMBBuffer;
  889. for (i=0; i<6; i++)
  890. {
  891. pRef[i] = pRefTmp;
  892. pRefTmp += 8;
  893. }
  894. // Do the forward predictions
  895. for (i=0; i<6; i++)
  896. {
  897. int interp_index;
  898. // in UMV mode: clip MVs pointing outside 16 pels wide edge
  899. if (DC->bUnrestrictedMotionVectors)
  900. {
  901. UmvOnEdgeClipMotionVectors2(&mv_f_x[i],&mv_f_y[i], iEdgeFlag, i);
  902. // no need to clip backward vectors
  903. }
  904. // Put forward predictions at addresses pRef[0], ..., pRef[5].
  905. pRefTmp = fpBlockAction[i].pRefBlock + (I32)(mv_f_x[i]>>1) +
  906. PITCH * (I32)(mv_f_y[i]>>1);
  907. // TODO
  908. interp_index = ((mv_f_y[i] & 0x1)<<1) | (mv_f_x[i] & 0x1);
  909. if (interp_index)
  910. {
  911. #ifdef USE_MMX // { USE_MMX
  912. if (DC->bMMXDecoder)
  913. (*MMX_Interpolate_Table[interp_index])(pRefTmp, pRef[i]);
  914. else
  915. (*Interpolate_Table[interp_index])(pRefTmp, pRef[i]);
  916. #else // }{ USE_MMX
  917. (*Interpolate_Table[interp_index])(pRefTmp, pRef[i]);
  918. #endif // } USE_MMX
  919. }
  920. else
  921. {
  922. #ifdef USE_MMX // { USE_MMX
  923. if (DC->bMMXDecoder)
  924. MMX_BlockCopy(
  925. pRef[i], // destination
  926. pRefTmp); // prediction
  927. else
  928. BlockCopy(pRef[i], pRefTmp);
  929. #else // }{ USE_MMX
  930. BlockCopy(pRef[i], pRefTmp);
  931. #endif // } USE_MMX
  932. }
  933. #ifdef H263P
  934. // If we are using improved PB-frame mode (H.263+) and the B-block
  935. // was signalled to be predicted in the forward direction only,
  936. // we do not adjust with the backward prediction from the future.
  937. if (DC->bImprovedPBFrames == FALSE ||
  938. fpMBInfo->bForwardPredOnly == FALSE)
  939. #endif
  940. {
  941. #ifdef USE_MMX // { USE_MMX
  942. if (DC->bMMXDecoder)
  943. // adjust with bacward prediction from the future
  944. MMX_BiMotionComp(
  945. pRef[i],
  946. fpBlockAction[i].pCurBlock,
  947. (I32) mv_b_x[i],
  948. (I32) mv_b_y[i],
  949. i);
  950. else
  951. // adjust with bacward prediction from the future
  952. H263BiMotionComp(
  953. pRef[i],
  954. fpBlockAction[i].pCurBlock,
  955. (I32) mv_b_x[i],
  956. (I32) mv_b_y[i],
  957. i);
  958. #else // }{ USE_MMX
  959. // adjust with bacward prediction from the future
  960. H263BiMotionComp(
  961. pRef[i],
  962. fpBlockAction[i].pCurBlock,
  963. (I32) mv_b_x[i],
  964. (I32) mv_b_y[i],
  965. i);
  966. #endif // } USE_MMX
  967. }
  968. } // end for (i=0; i<6; i++) {}
  969. }
  970. #pragma code_seg()
  971. /*****************************************************************************
  972. *
  973. * H263BFrameIDCTandBiMC
  974. *
  975. * B Frame IDCT and
  976. * Bi-directional MC for B blocks
  977. */
  978. #pragma code_seg("IACODE2")
  979. void H263BFrameIDCTandBiMC(
  980. T_H263DecoderCatalog FAR *DC,
  981. T_BlkAction FAR *fpBlockAction,
  982. int iBlock,
  983. U32 *pN,
  984. T_IQ_INDEX *pRUN_INVERSE_Q,
  985. U32 *pRef
  986. )
  987. {
  988. ASSERT(*pN < 65);
  989. // do the inverse transform (where appropriate) & combine
  990. if (*pN > 0) {
  991. #ifdef USE_MMX // { USE_MMX
  992. if (DC->bMMXDecoder)
  993. {
  994. MMX_DecodeBlock_IDCT(
  995. (U32)pRUN_INVERSE_Q,
  996. *pN,
  997. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET); // inter output
  998. MMX_BlockAdd(
  999. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // output
  1000. pRef[iBlock], // prediction
  1001. fpBlockAction[iBlock].pBBlock); // destination
  1002. }
  1003. else
  1004. {
  1005. // Get residual block; put output at DC+DC->uMBBuffer+BLOCK_BUFFER_OFFSET
  1006. DecodeBlock_IDCT(
  1007. (U32)pRUN_INVERSE_Q,
  1008. *pN,
  1009. fpBlockAction[iBlock].pBBlock, // intRA not used here
  1010. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET); // inter output
  1011. // Add the residual to the reference block
  1012. BlockAdd(
  1013. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // transform output
  1014. pRef[iBlock], // prediction
  1015. fpBlockAction[iBlock].pBBlock); // destination
  1016. }
  1017. #else // }{ USE_MMX
  1018. // Get residual block; put output at DC+DC->uMBBuffer+BLOCK_BUFFER_OFFSET
  1019. DecodeBlock_IDCT(
  1020. (U32)pRUN_INVERSE_Q,
  1021. *pN,
  1022. fpBlockAction[iBlock].pBBlock, // intRA not used here
  1023. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET); // inter output
  1024. // Add the residual to the reference block
  1025. BlockAdd(
  1026. (U32) DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET, // transform output
  1027. pRef[iBlock], // prediction
  1028. fpBlockAction[iBlock].pBBlock); // destination
  1029. #endif // } USE_MMX
  1030. }
  1031. else
  1032. {
  1033. // No transform coefficients for this block,
  1034. // copy the prediction to the output.
  1035. #ifdef USE_MMX // { USE_MMX
  1036. if (DC->bMMXDecoder)
  1037. MMX_BlockCopy(
  1038. fpBlockAction[iBlock].pBBlock, // destination
  1039. pRef[iBlock]); // prediction
  1040. else
  1041. BlockCopy(
  1042. fpBlockAction[iBlock].pBBlock, // destination
  1043. pRef[iBlock]); // prediction
  1044. #else // }{ USE_MMX
  1045. BlockCopy(
  1046. fpBlockAction[iBlock].pBBlock, // destination
  1047. pRef[iBlock]); // prediction
  1048. #endif // } USE_MMX
  1049. }
  1050. }
  1051. #pragma code_seg()