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.

3272 lines
115 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. ** Copyright (c) 1996 Intel Corporation.
  11. ** All Rights Reserved.
  12. **
  13. ** *************************************************************************
  14. */
  15. ;// $Author: JMCVEIGH $
  16. ;// $Date: 11 Dec 1996 14:59:36 $
  17. ;// $Archive: S:\h26x\src\dec\d3dec.cpv $
  18. ;// $Header: S:\h26x\src\dec\d3dec.cpv 1.119 11 Dec 1996 14:59:36 JMCVEIGH $
  19. ;// $Log: S:\h26x\src\dec\d3dec.cpv $
  20. //
  21. // Rev 1.119 11 Dec 1996 14:59:36 JMCVEIGH
  22. //
  23. // Moved deblocking filter within the loop and fixed bug for YUV12
  24. // input and arbitrary frame sizes (must use actual dimensions for
  25. // YUV12, not padded sizes).
  26. //
  27. // Rev 1.118 09 Dec 1996 18:02:06 JMCVEIGH
  28. // Added support for arbitrary frame sizes.
  29. //
  30. // Rev 1.117 09 Dec 1996 09:35:14 MDUDA
  31. // Put new version of block edge filter under H263P.
  32. //
  33. // Rev 1.116 27 Nov 1996 15:24:34 BECHOLS
  34. // Added check for NULL ptr around EMMS at end of decompress.
  35. //
  36. // Rev 1.115 26 Nov 1996 09:05:22 KLILLEVO
  37. // changed allocation of dtab to array
  38. //
  39. // Rev 1.114 25 Nov 1996 15:23:40 KLILLEVO
  40. // changed filter coefficients and table size for deblocking filter
  41. //
  42. // Rev 1.113 25 Nov 1996 14:11:14 KLILLEVO
  43. // updated de-blocking filter to latest version of annex J
  44. //
  45. // Rev 1.112 19 Nov 1996 15:05:32 MDUDA
  46. // For YUV12 I420 output color conversion, copy at least the V plane
  47. // to prevent assembler code from reading beyond end of buffer.
  48. //
  49. // Rev 1.111 07 Nov 1996 08:31:04 CZHU
  50. // Fixed bugs in Mode C recovery.
  51. //
  52. // Rev 1.110 06 Nov 1996 16:37:00 CZHU
  53. // Moved initialization for BlockAction earlier
  54. //
  55. // Rev 1.109 06 Nov 1996 15:47:10 CZHU
  56. //
  57. // Added mode C support, replacing zero size r1.108
  58. //
  59. // Rev 1.107 31 Oct 1996 10:50:44 KLILLEVO
  60. // changed one debug message
  61. //
  62. // Rev 1.106 31 Oct 1996 10:17:56 KLILLEVO
  63. // changed the last DBOUTs to DbgLog
  64. //
  65. // Rev 1.105 25 Oct 1996 15:20:30 KLILLEVO
  66. // changed debug-message for Block Edge Filter initialization
  67. // in GetDecoderOptions() to be more informatice
  68. //
  69. // Rev 1.104 25 Oct 1996 15:01:56 KLILLEVO
  70. // null frame warning should have level 4, not 2
  71. //
  72. // Rev 1.103 25 Oct 1996 09:13:40 KLILLEVO
  73. // changed an error message about null frame received after non-PB frame
  74. // to trace message and level 2.
  75. //
  76. // Rev 1.102 20 Oct 1996 18:10:46 AGUPTA2
  77. // Changed DBOUT into DbgLog. ASSERT is not changed to DbgAssert.
  78. //
  79. //
  80. // Rev 1.101 16 Oct 1996 17:17:52 MDUDA
  81. // Added initialization for DC->bReadSrcFormat to fix a capture bug.
  82. //
  83. // Rev 1.100 11 Oct 1996 16:08:30 MDUDA
  84. // Added initial _CODEC_STATS stuff.
  85. //
  86. // Rev 1.99 26 Sep 1996 10:35:14 KLILLEVO
  87. // need to ExplandPlane for bUnrestrictedMotionVectors in addition to
  88. // bAdvancedPrediction
  89. //
  90. // Rev 1.98 26 Sep 1996 09:42:18 BECHOLS
  91. //
  92. // Added Snapshot Event for synchronization and code to copy the Snapshot
  93. // just prior to color conversion.
  94. //
  95. // Rev 1.97 25 Sep 1996 08:05:10 KLILLEVO
  96. // initial extended motion vectors support
  97. // does not work for AP yet
  98. //
  99. // Rev 1.96 20 Sep 1996 09:36:04 MDUDA
  100. // Fixed problem with video effects on YUV12 input images.
  101. // Need to copy frame in this case.
  102. //
  103. // Rev 1.95 19 Sep 1996 19:40:40 MDUDA
  104. // Fixed problem with calling AdjustPels - performed frame copy
  105. // and set pFrame to correct location.
  106. //
  107. // Rev 1.94 16 Sep 1996 16:44:40 CZHU
  108. // Fixed buffer overflow problem to support RTP MTU down to 128
  109. //
  110. // Rev 1.93 11 Sep 1996 15:12:26 CZHU
  111. // Tuned off deblocking filter by default.
  112. //
  113. // Rev 1.92 10 Sep 1996 16:10:20 KLILLEVO
  114. // added custom message to turn block edge filter on or off
  115. //
  116. // Rev 1.91 10 Sep 1996 14:15:24 BNICKERS
  117. // Select Pentium Pro color convertors, when running on that processor.
  118. //
  119. // Rev 1.90 10 Sep 1996 10:31:04 KLILLEVO
  120. // changed all GlobalAlloc/GlobalLock calls to HeapAlloc
  121. //
  122. // Rev 1.89 06 Sep 1996 14:21:38 BECHOLS
  123. //
  124. // Removed code that was wrapped by RTP_HEADER, and removed the wrapping too.
  125. //
  126. // Rev 1.88 30 Aug 1996 08:37:58 KLILLEVO
  127. // added C version of block edge filter, and changed the bias in
  128. // ClampTbl[] from 128 to CLAMP_BIAS (defined to 128)
  129. // The C version of the block edge filter takes up way too much CPU time
  130. // relative to the rest of the decode time (4 ms for QCIF and 16 ms
  131. // for CIF on a P120, so this needs to coded in assembly)
  132. //
  133. // Rev 1.87 29 Aug 1996 09:29:08 CZHU
  134. //
  135. // Fixed another bug in recovering lost packets followed by MODE M packet.
  136. //
  137. // Rev 1.86 27 Aug 1996 16:17:00 CZHU
  138. // Commented out previous code to turn on MMX with RTP
  139. //
  140. // Rev 1.85 23 Jul 1996 11:20:56 CZHU
  141. // Fixed two bugs related to packet loss recovery, one for the last packet los
  142. // in current frame, the other in mode B packets.
  143. // Also added motion vector adjustment for lost MBs
  144. //
  145. // Rev 1.84 18 Jul 1996 09:23:12 KLILLEVO
  146. // implemented YUV12 color convertor (pitch changer) in assembly
  147. // and added it as a normal color convertor function, via the
  148. // ColorConvertorCatalog() call.
  149. //
  150. // Rev 1.83 11 Jul 1996 15:12:40 AGUPTA2
  151. // Changed assertion failures into errors when decoder goes past end of
  152. // the bitstream.
  153. //
  154. // Rev 1.82 01 Jul 1996 10:04:12 RHAZRA
  155. // Force shaping flag to false for YUY2 color conversion
  156. // .
  157. //
  158. // Rev 1.81 25 Jun 1996 14:27:20 BECHOLS
  159. // Set ini file variables for use with RTP stuff.
  160. //
  161. // Rev 1.80 19 Jun 1996 14:30:12 RHAZRA
  162. //
  163. // Added code to deal with pitch and output buffer offset & pitch
  164. // setting for YUY2 output format.
  165. //
  166. // Rev 1.79 14 Jun 1996 17:27:44 AGUPTA2
  167. // Updated the color convertor table.
  168. //
  169. // Rev 1.77 30 May 1996 17:04:54 RHAZRA
  170. // Added SQCIF support.
  171. //
  172. // Rev 1.76 30 May 1996 15:16:32 KLILLEVO
  173. // added YUV12 output
  174. //
  175. // Rev 1.75 30 May 1996 12:45:12 KLILLEVO
  176. // fixed debug warning message in PB-frames mode
  177. //
  178. // Rev 1.74 30 May 1996 11:26:38 AGUPTA2
  179. // Added support for MMX color convertors.
  180. //
  181. // Rev 1.73 29 May 1996 14:11:14 RHAZRA
  182. // Changes made to use MMxVersion set in ccpuvsn.cpp.
  183. //
  184. // Rev 1.72 24 May 1996 10:04:20 KLILLEVO
  185. // does not need to assert out if a null frame is received when
  186. // the previous frame was not a PB. This will often happen
  187. // with the new MMX PB switch
  188. //
  189. // Rev 1.71 03 May 1996 13:08:28 CZHU
  190. //
  191. // Added checking of packet fault after picture header decoding, and
  192. // change pass1 loop control to recover from packe loss. Checking packet
  193. // fault after MB header decoding.
  194. //
  195. // Rev 1.70 12 Apr 1996 14:16:40 RHAZRA
  196. // Added paranthesis to make ifdef SUPPORT_SQCIF work properly
  197. //
  198. // Rev 1.69 12 Apr 1996 13:32:22 RHAZRA
  199. //
  200. // Added SQCIF support with #ifdef SUPPORT_SQCIF.
  201. //
  202. // Rev 1.68 10 Apr 1996 16:28:20 RHAZRA
  203. // Added a check to make sure that the input bitstream buffer does
  204. // not exceed the H263 spec mandated size. If it does, the decoder
  205. // now returns ICERR_ERROR.
  206. //
  207. // Rev 1.67 04 Apr 1996 13:32:02 RHAZRA
  208. // Changed bitstream buffer allocation as per H.263 spec
  209. //
  210. // Rev 1.66 03 Apr 1996 09:06:06 RMCKENZX
  211. // Moved "emms" to end of decoder.
  212. //
  213. // Rev 1.65 26 Mar 1996 16:43:38 AGUPTA2
  214. // Corrected opcode for emms.
  215. //
  216. // Rev 1.64 22 Mar 1996 17:49:48 AGUPTA2
  217. // MMX support. Added emms around pass1 and pass2 calls.
  218. //
  219. // Rev 1.63 18 Mar 1996 09:58:48 bnickers
  220. // Make color convertors non-destructive.
  221. //
  222. // Rev 1.62 12 Mar 1996 20:15:04 RHAZRA
  223. // Fixed still-mode. Use framecopy() in 320x240 mode to copy display frame
  224. // to post frame.
  225. //
  226. // Rev 1.61 08 Mar 1996 16:46:12 AGUPTA2
  227. // Added pragma code_seg.
  228. // Created three new routines: IAPass1ProcessFrame(), IAPass2ProcessFrame(),
  229. // and H263InitializeGOBBlockActionStream(). H263InitializeGOB.. rtn. is
  230. // called once for each block after decoding the GOB header; this is good for
  231. // the data cache. H263InitializeBlockActionStream() is not needed now.
  232. // ExpandPlane() is called only when needed; it is called just before its
  233. // results are needed : before Pass2 call (improves DCache util.). Decoder
  234. // does not copy current frame to previous frame after decoding; it just swaps
  235. // the pointers. Made changes to call the new non-destructive color convertor;
  236. // this avoids a frame copy if mirroring is not needed. I DON"T THINK ADJUST
  237. // PELS FUNCTIONALITY WORKS.
  238. //
  239. //
  240. //
  241. // Rev 1.59 23 Feb 1996 09:46:52 KLILLEVO
  242. // fixed decoding of Unrestricted Motion Vector mode
  243. //
  244. // Rev 1.58 05 Feb 1996 13:35:46 BNICKERS
  245. // Fix RGB16 color flash problem, by allowing different RGB16 formats at oce.
  246. //
  247. // Rev 1.57 17 Jan 1996 18:55:10 RMCKENZX
  248. // more clean up from pb null frame bug
  249. //
  250. // Rev 1.56 17 Jan 1996 17:56:04 sing
  251. // moved memcopy past the null P frame hack to avoid GPF
  252. //
  253. // Rev 1.55 12 Jan 1996 14:59:42 TRGARDOS
  254. // Added aspect ration correction logic and code to force
  255. // aspect ration correction on based on INI file settings.
  256. //
  257. // Rev 1.54 11 Jan 1996 14:05:10 RMCKENZX
  258. // Made changes to support stills. In initialization set a local
  259. // flag (as DC hasn't been created yet). In frame handling, restore
  260. // the CIF size and use the new 320x240 Offset To Line Zero figure.
  261. //
  262. // Rev 1.53 09 Jan 1996 10:44:38 RMCKENZX
  263. // More revisions to support frame mirroring. Added
  264. // absolute value to references to destination width.
  265. //
  266. // Rev 1.52 08 Jan 1996 17:45:12 unknown
  267. // Check destination pointer before using it
  268. //
  269. // Rev 1.51 08 Jan 1996 12:18:20 RMCKENZX
  270. // Added logic to implement frame-mirroring and
  271. // 320x240 still frames.
  272. //
  273. // Rev 1.50 06 Jan 1996 18:39:46 RMCKENZX
  274. // Updated copyright
  275. //
  276. // Rev 1.49 06 Jan 1996 18:34:28 RMCKENZX
  277. // Made changes to support still frame at 320x240 resolution
  278. //
  279. // Rev 1.48 03 Jan 1996 16:52:40 TRGARDOS
  280. // Added code to set a boolean, bMirror, when destination
  281. // frame width is the negative of the source frame width.
  282. // Added if statement so that FrameMirror is called instead
  283. // of FrameCopy when bMirror is set. This only works for
  284. // H.263 bit streams. A new function has to be written for
  285. // YUV12 data.
  286. //
  287. // Rev 1.47 18 Dec 1995 12:44:28 RMCKENZX
  288. // added copyright notice
  289. //
  290. // Rev 1.46 15 Dec 1995 13:51:56 RHAZRA
  291. //
  292. // Added code to force fpBlockAction->u8BlkType = BT_EMPTY in
  293. // block action stream initialization
  294. //
  295. // Rev 1.45 13 Dec 1995 11:00:42 RHAZRA
  296. // No change.
  297. //
  298. // Rev 1.44 11 Dec 1995 11:31:22 RHAZRA
  299. // 12-10-95 changes: added AP stuff
  300. //
  301. // Rev 1.43 09 Dec 1995 17:26:36 RMCKENZX
  302. // Re-architected the decoder, splitting into a 2-pass
  303. // approach. See comments in the code.
  304. //
  305. // Rev 1.41 09 Nov 1995 14:09:18 AGUPTA2
  306. // Changes for PB-frame (call new ExpandYPlane, ExpandUVPlane rtns.)
  307. //
  308. // Rev 1.40 30 Oct 1995 14:08:00 TRGARDOS
  309. // Second attempt - turn off aspect ration correction.
  310. //
  311. // Rev 1.39 30 Oct 1995 13:25:14 TRGARDOS
  312. // Turned off aspect ration correction in color convertor.
  313. //
  314. // Rev 1.38 27 Oct 1995 16:21:56 CZHU
  315. // Added support to return P frame in the PB pair if the bitstream is
  316. // encoder with special null frame following previous PB frame
  317. //
  318. // Rev 1.37 26 Oct 1995 11:25:16 BNICKERS
  319. // Fix quasi color convertor for encoder's decoder; bugs introduced when
  320. // adding YUV12 color convertors.
  321. //
  322. // Rev 1.36 25 Oct 1995 18:09:02 BNICKERS
  323. //
  324. // Switch to YUV12 color convertors. Clean up archival stuff.
  325. //
  326. // Rev 1.35 13 Oct 1995 16:06:16 CZHU
  327. // First version that supports PB frames. Display B or P frames under
  328. // VfW for now.
  329. //
  330. // Rev 1.34 08 Oct 1995 13:45:56 CZHU
  331. //
  332. // Added debug session to output reconstructed pels in YUV12 to a file
  333. //
  334. // Rev 1.33 27 Sep 1995 16:24:00 TRGARDOS
  335. //
  336. // Added debug print statements.
  337. //
  338. // Rev 1.32 26 Sep 1995 15:32:12 CZHU
  339. // Added expand y, u, v planes.
  340. //
  341. // Rev 1.31 26 Sep 1995 10:53:26 CZHU
  342. //
  343. // Call ExpandPlane to expand each plane before half pel MC.
  344. //
  345. // Rev 1.30 25 Sep 1995 11:07:56 CZHU
  346. // Added debug message
  347. //
  348. // Rev 1.29 21 Sep 1995 12:04:26 DBRUCKS
  349. // fix assert
  350. //
  351. // Rev 1.28 20 Sep 1995 14:47:26 CZHU
  352. // Added iNumberOfMBsPerGOB in decoder catalog
  353. //
  354. // Rev 1.27 19 Sep 1995 16:04:10 DBRUCKS
  355. // changed to yuv12forenc
  356. //
  357. // Rev 1.26 19 Sep 1995 11:13:16 DBRUCKS
  358. // clarify the code that orders the YYYYCbCr data (YYYYUV) data into
  359. // YYYYVU in the decoder's internal memory. The variable names were
  360. // incorrect in one place. The reordering is necessary to simplify
  361. // later conversion to YVU9.
  362. //
  363. // Rev 1.25 19 Sep 1995 10:36:46 CZHU
  364. // Added comments to the codes added for YUV12 decoder
  365. //
  366. // Rev 1.24 18 Sep 1995 08:41:54 CZHU
  367. //
  368. // Added support for YUV12
  369. //
  370. // Rev 1.23 12 Sep 1995 11:13:00 CZHU
  371. //
  372. // Copy the decoded YUV12 from Current frame to Previous frame
  373. // to prepare for P frames
  374. //
  375. // Rev 1.22 11 Sep 1995 16:42:36 CZHU
  376. // P frames
  377. //
  378. // Rev 1.21 11 Sep 1995 14:33:10 CZHU
  379. //
  380. // Refresh MV info in BlockAction stream, needed for P frames
  381. //
  382. // Rev 1.20 08 Sep 1995 11:49:52 CZHU
  383. // Added support for P frames and more debug info
  384. //
  385. // Rev 1.19 07 Sep 1995 10:48:10 DBRUCKS
  386. // added OUTPUT_MBDATA_ADDRESS option
  387. //
  388. // Rev 1.18 05 Sep 1995 17:22:12 DBRUCKS
  389. // u & v are offset by 8 from Y in YVU12ForEnc
  390. //
  391. // Rev 1.17 01 Sep 1995 17:13:52 DBRUCKS
  392. // add adjustpels
  393. //
  394. // Rev 1.16 01 Sep 1995 09:49:34 DBRUCKS
  395. // checkin partial ajdust pels changes
  396. //
  397. // Rev 1.15 29 Aug 1995 16:50:40 DBRUCKS
  398. // add support for YVU9 playback
  399. //
  400. // Rev 1.14 28 Aug 1995 17:45:58 DBRUCKS
  401. // add yvu12forenc
  402. //
  403. // Rev 1.13 28 Aug 1995 10:15:14 DBRUCKS
  404. // update to 5 July Spec and 8/25 Errata
  405. //
  406. // Rev 1.12 24 Aug 1995 08:51:30 CZHU
  407. // Turned off apsect ratio correction.
  408. //
  409. // Rev 1.11 23 Aug 1995 12:25:10 DBRUCKS
  410. // Turn on the color converters
  411. //
  412. // Rev 1.10 14 Aug 1995 16:40:34 DBRUCKS
  413. // initialize block action stream
  414. //
  415. // Rev 1.9 11 Aug 1995 17:47:58 DBRUCKS
  416. // cleanup
  417. //
  418. // Rev 1.8 11 Aug 1995 17:30:00 DBRUCKS
  419. // copy source to bitstream
  420. //
  421. // Rev 1.7 11 Aug 1995 16:12:14 DBRUCKS
  422. // add ptr check to MB data and add #ifndef early exit
  423. //
  424. // Rev 1.6 11 Aug 1995 15:10:18 DBRUCKS
  425. // get ready to integrate with block level code and hook up macro block level code
  426. //
  427. // Rev 1.5 03 Aug 1995 14:57:56 DBRUCKS
  428. // Add ASSERT macro
  429. //
  430. // Rev 1.4 02 Aug 1995 15:31:34 DBRUCKS
  431. // added GOB header parsing
  432. //
  433. // Rev 1.3 01 Aug 1995 12:27:38 DBRUCKS
  434. // add PSC parsing
  435. //
  436. // Rev 1.2 31 Jul 1995 16:28:00 DBRUCKS
  437. // move loacl BITS defs to D3DEC.CPP
  438. //
  439. // Rev 1.1 31 Jul 1995 15:32:22 CZHU
  440. // Moved global tables to d3tables.h
  441. //
  442. // Rev 1.0 31 Jul 1995 13:00:04 DBRUCKS
  443. // Initial revision.
  444. //
  445. // Rev 1.3 28 Jul 1995 13:57:36 CZHU
  446. // Started to add picture level decoding of fixed length codes.
  447. //
  448. // Rev 1.2 24 Jul 1995 14:57:52 CZHU
  449. // Added global tables for VLD decoding. Also added instance initialization
  450. // and termination. Several data structures are updated for H.263.
  451. //
  452. // Rev 1.1 17 Jul 1995 14:46:20 CZHU
  453. //
  454. //
  455. // Rev 1.0 17 Jul 1995 14:14:40 CZHU
  456. // Initial revision.
  457. //////////////////////////////////////////////////////////////////////////////
  458. #include "precomp.h"
  459. #ifdef TRACK_ALLOCATIONS
  460. char gsz1[32];
  461. #endif
  462. extern BYTE PalTable[236*4];
  463. #if defined(H263P)
  464. extern void EdgeFilter(unsigned char *lum,
  465. unsigned char *Cb,
  466. unsigned char *Cr,
  467. int width, int height, int pitch
  468. );
  469. extern void InitEdgeFilterTab();
  470. /* map of coded and not-coded blocks */
  471. char coded_map[18+1][22+1];
  472. /* QP map */
  473. char QP_map[18][22];
  474. #else
  475. #ifdef NEW_BEF // { NEW_BEF
  476. // C version of block edge filter functions
  477. // takes about 3 ms for QCIF and 12 ms for CIF on a Pentium 120.
  478. static void HorizEdgeFilter(unsigned char *rec,
  479. int width, int height, int pitch, int chr);
  480. static void VertEdgeFilter(unsigned char *rec,
  481. int width, int height, int pitch, int chr);
  482. static void EdgeFilter(unsigned char *lum,
  483. unsigned char *Cb,
  484. unsigned char *Cr,
  485. int width, int height, int pitch
  486. );
  487. static void InitEdgeFilterTab();
  488. static void FreeEdgeFilterTab();
  489. /* map of coded and not-coded blocks */
  490. static char coded_map[18+1][22+1];
  491. /* QP map */
  492. static char QP_map[18][22];
  493. /* table for de-blocking filter */
  494. /* currently requires 11232 bytes */
  495. signed char dtab[352*32];
  496. #else // }{ NEW_BEF
  497. // C version of block edge filter functions
  498. // takes about 4 ms for QCIF and 16 ms for CIF. This is a large percentage
  499. // of the decoding time, so we need to implement these in assembly before
  500. // the next big release
  501. void EdgeFilter(unsigned char *lum, unsigned char *Cb, unsigned char *Cr,
  502. int pels, int lines, int pitch, int QP);
  503. void HorizEdgeFilter(unsigned char *rec, int width, int height, int pitch, int QP,
  504. int chr, int *deltatab);
  505. void VertEdgeFilter(unsigned char *rec, int width, int height, int pitch, int QP,
  506. int chr, int *deltatab);
  507. /* stores information about coded and not-coded blocks */
  508. static char coded_map[44][36]; // memory for this should probably be allocated somewhere else
  509. #endif // } NEW_BEF
  510. #endif
  511. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  512. /* Decoder Timing Data - per frame
  513. */
  514. #define DEC_TIMING_INFO_FRAME_COUNT 105
  515. #pragma message ("Current log decode timing computations handle 105 frames max")
  516. void OutputDecodeTimingStatistics(char * szFileName, DEC_TIMING_INFO * pDecTimingInfo, U32 uStatFrameCount);
  517. void OutputDecTimingDetail(FILE * pFile, DEC_TIMING_INFO * pDecTimingInfo);
  518. #endif // } LOG_DECODE_TIMINGS_ON
  519. extern "C" {
  520. void ExpandPlane(U32, U32, U32, U32);
  521. }
  522. static I32 iNumberOfGOBsBySourceFormat[8] = {
  523. 0, /* FORBIDDEN */
  524. 6, /* SQCIF */
  525. 9, /* QCIF */
  526. 18, /* CIF */
  527. 0, /* 4CIF - Not supported */
  528. 0, /* 16CIF - Not supported */
  529. #ifdef H263P
  530. 0, /* Custom */
  531. 0 /* Extended PTYPE */
  532. #else
  533. 0, /* Reserved */
  534. 0 /* Reserved */
  535. #endif
  536. };
  537. static I32 iNumberOfMBsInAGOBBySourceFormat[8] = {
  538. 0, /* FORBIDDEN */
  539. 8, /* SQCIF */
  540. 11, /* QCIF */
  541. 22, /* CIF */
  542. 0, /* 4CIF - Not supported */
  543. 0, /* 16CIF - Not supported */
  544. #ifdef H263P
  545. 0, /* Custom */
  546. 0 /* Extended PTYPE */
  547. #else
  548. 0, /* Reserved */
  549. 0 /* Reserved */
  550. #endif
  551. };
  552. //#pragma warning(disable:4101)
  553. //#pragma warning(disable:4102)
  554. static LRESULT IAPass1ProcessFrame(
  555. T_H263DecoderCatalog *DC,
  556. T_BlkAction *fpBlockAction,
  557. T_MBInfo *fpMBInfo,
  558. BITSTREAM_STATE *fpbsState,
  559. U8 *fpu8MaxPtr,
  560. U32 *pN,
  561. T_IQ_INDEX *pRUN_INVERSE_Q,
  562. const I32 iNumberOfGOBs,
  563. const I32 iNumberOfMBs,
  564. const I32 iGOB_start,
  565. const I32 iMB_start);
  566. static void H263InitializeGOBBlockActionStream(
  567. T_H263DecoderCatalog *DC,
  568. const I32 iGOBno,
  569. const T_BlkAction FAR *fpStartGOBBlockActionStream
  570. );
  571. static void IAPass2ProcessFrame(
  572. T_H263DecoderCatalog *DC,
  573. T_BlkAction *fpBlockAction,
  574. T_MBInfo *fpMBInfo,
  575. U32 *pN,
  576. T_IQ_INDEX *pRUN_INVERSE_Q,
  577. const I32 iNumberOfGOBs,
  578. const I32 iNumberOfMBs
  579. );
  580. static long DibXY(ICDECOMPRESSEX FAR *lpicDecEx, LPINT lpiPitch, UINT yScale);
  581. static void GetDecoderOptions(T_H263DecoderCatalog *);
  582. static void ZeroFill(HPBYTE hpbY, HPBYTE hpbU, HPBYTE hpbV, int iPitch, U32 uWidth, U32 uHeight);
  583. #define REUSE_DECODE 1
  584. #define DEFAULT_BUFFER_SIZE 32768L
  585. #if REUSE_DECODE
  586. struct { // Communicate Encoder's decode to display decode.
  587. U8 FAR * Address; // Addr at which encoded frame is placed.
  588. DECINSTINFO BIGG * PDecoderInstInfo; // Encoder's decoder instance.
  589. unsigned int FrameNumber; // Frame number last encoded, mod 128.
  590. } CompandedFrame;
  591. #endif
  592. /**********************************************************************
  593. * H263InitDeocderGlobal
  594. **********************************************************************/
  595. LRESULT H263InitDecoderGlobal(void)
  596. {
  597. return ICERR_OK;
  598. }
  599. /***********************************************************************
  600. * Description:
  601. * Initialize the MB action stream for GOB 'iGOBno'.
  602. * Parameters:
  603. * DC:
  604. * iGOBno: GOB no counting from one;i.e. the first GOB in the frame is 1.
  605. * fpStartGOBBlockActionStream: Pointer to start of the block action stream
  606. * for iGOBno.
  607. * Note:
  608. * This routine needs to change for picture sizes larger than CIF
  609. ***********************************************************************/
  610. #pragma code_seg("IACODE1")
  611. static void H263InitializeGOBBlockActionStream(
  612. T_H263DecoderCatalog *DC,
  613. const I32 iGOBno,
  614. T_BlkAction FAR *fpStartGOBBlockActionStream
  615. )
  616. {
  617. const U32 uFrameHeight = DC->uFrameHeight;
  618. const U32 uFrameWidth = DC->uFrameWidth;
  619. const U32 uCurBlock = (U32) ((U8 FAR *)DC + DC->CurrFrame.X32_YPlane);
  620. const U32 uRefBlock = (U32) ((U8 FAR *)DC + DC->PrevFrame.X32_YPlane);
  621. const U32 uBBlock = (U32) ((U8 FAR *)DC + DC->PBFrame.X32_YPlane);
  622. U32 uYOffset;
  623. U32 uUOffset;
  624. U32 uVOffset;
  625. U32 uYUpdate;
  626. U32 uUVUpdate;
  627. U32 uBlkNumber;
  628. T_BlkAction *fpBlockAction = fpStartGOBBlockActionStream;
  629. // assume that the width and height are multiples of 16
  630. ASSERT((uFrameHeight & 0xF) == 0);
  631. ASSERT((uFrameWidth & 0xF) == 0);
  632. // calculate distance to the next row.
  633. uYUpdate = (16 * PITCH)*(iGOBno - 1);
  634. uUVUpdate = (8 * PITCH)*(iGOBno - 1);
  635. // skip the padding used for unconstrained motion vectors
  636. uYOffset = Y_START + uYUpdate;
  637. uVOffset = DC->uSz_YPlane + UV_START + uUVUpdate;
  638. uUOffset = uVOffset + (PITCH >> 1);
  639. // Start with the first block of the GOB
  640. uBlkNumber = (iGOBno -1)*((uFrameWidth>>4)*6);
  641. // Initialize the array
  642. for (U32 xpos = 0 ; xpos < uFrameWidth ; xpos += 16) {
  643. U8 loadcacheline;
  644. // Four Y Blocks
  645. // Y0 Y1
  646. // Y2 Y3
  647. loadcacheline = fpBlockAction->u8BlkType;
  648. fpBlockAction->u8BlkType = BT_EMPTY;
  649. fpBlockAction->pCurBlock = uCurBlock + uYOffset;
  650. fpBlockAction->pRefBlock = uRefBlock + uYOffset;
  651. fpBlockAction->pBBlock = uBBlock + uYOffset;
  652. fpBlockAction->uBlkNumber = uBlkNumber++;
  653. fpBlockAction->i8MVx2=0;
  654. fpBlockAction->i8MVy2=0;
  655. uYOffset += 8;
  656. fpBlockAction++;
  657. fpBlockAction->u8BlkType = BT_EMPTY;
  658. fpBlockAction->pCurBlock = uCurBlock + uYOffset;
  659. fpBlockAction->pRefBlock = uRefBlock + uYOffset;
  660. fpBlockAction->pBBlock = uBBlock + uYOffset;
  661. fpBlockAction->uBlkNumber = uBlkNumber++;
  662. fpBlockAction->i8MVx2=0;
  663. fpBlockAction->i8MVy2=0;
  664. uYOffset = uYOffset - 8 + (8 * PITCH);
  665. fpBlockAction++;
  666. loadcacheline = fpBlockAction->u8BlkType;
  667. fpBlockAction->u8BlkType = BT_EMPTY;
  668. fpBlockAction->pCurBlock = uCurBlock + uYOffset;
  669. fpBlockAction->pRefBlock = uRefBlock + uYOffset;
  670. fpBlockAction->pBBlock = uBBlock + uYOffset;
  671. fpBlockAction->uBlkNumber = uBlkNumber++;
  672. fpBlockAction->i8MVx2=0;
  673. fpBlockAction->i8MVy2=0;
  674. uYOffset += 8;
  675. fpBlockAction++;
  676. fpBlockAction->u8BlkType = BT_EMPTY;
  677. fpBlockAction->pCurBlock = uCurBlock + uYOffset;
  678. fpBlockAction->pRefBlock = uRefBlock + uYOffset;
  679. fpBlockAction->pBBlock = uBBlock + uYOffset;
  680. fpBlockAction->uBlkNumber = uBlkNumber++;
  681. fpBlockAction->i8MVx2=0;
  682. fpBlockAction->i8MVy2=0;
  683. uYOffset = uYOffset + 8 - (8 * PITCH);
  684. fpBlockAction++;
  685. // Notice: although the blocks are read in YYYYUV order we store the
  686. // data in memory in Y V U order. This is accomplished because
  687. // block 5 (U) is written to the right of block 6 (V).
  688. // One Cb (U) Block
  689. loadcacheline = fpBlockAction->u8BlkType;
  690. fpBlockAction->u8BlkType = BT_EMPTY;
  691. fpBlockAction->pCurBlock = uCurBlock + uUOffset;
  692. fpBlockAction->pRefBlock = uRefBlock + uUOffset;
  693. fpBlockAction->pBBlock = uBBlock + uUOffset;
  694. fpBlockAction->uBlkNumber = uBlkNumber++;
  695. fpBlockAction->i8MVx2=0;
  696. fpBlockAction->i8MVy2=0;
  697. uUOffset += 8;
  698. fpBlockAction++;
  699. // One Cr (V) Block
  700. fpBlockAction->u8BlkType = BT_EMPTY;
  701. fpBlockAction->pCurBlock = uCurBlock + uVOffset;
  702. fpBlockAction->pRefBlock = uRefBlock + uVOffset;
  703. fpBlockAction->pBBlock = uBBlock + uVOffset;
  704. fpBlockAction->uBlkNumber = uBlkNumber++;
  705. fpBlockAction->i8MVx2=0;
  706. fpBlockAction->i8MVy2=0;
  707. uVOffset += 8;
  708. fpBlockAction++;
  709. }
  710. } // end H263InitializeGOBBlockActionStream()
  711. #pragma code_seg()
  712. /**********************************************************************
  713. * H263InitDecoderInstance
  714. * This function allocates and initializes the per-instance tables used by
  715. * the H263 decoder. Note that in 16-bit Windows, the non-instance-specific
  716. * global tables are copied to the per-instance data segment, so that they
  717. * can be used without segment override prefixes.
  718. ***********************************************************************/
  719. LRESULT H263InitDecoderInstance(
  720. LPDECINST lpInst,
  721. int CodecID)
  722. {
  723. U32 u32YActiveHeight, u32YActiveWidth;
  724. U32 u32UVActiveHeight, u32UVActiveWidth;
  725. U32 u32YPlane, u32VUPlanes ,u32YVUPlanes,u32SizeBlkActionStream;
  726. U32 uSizeBitStreamBuffer;
  727. U32 u32SizeT_IQ_INDEXBuffer, u32SizepNBuffer, u32SizeMBInfoStream; // NEW
  728. U32 lOffset=0;
  729. U32 u32TotalSize;
  730. LRESULT iReturn= ICERR_OK;
  731. LPVOID pDecoderInstance;
  732. U32 * pInitLimit;
  733. U32 * pInitPtr;
  734. I32 i32xres, i32yres;
  735. #ifdef H263P
  736. I32 i32xresActual, i32yresActual; // i32xres and i32yres are padded to multiples of 16
  737. #endif
  738. BOOL bIs320x240;
  739. T_H263DecoderCatalog * DC;
  740. U8 * P32Inst;
  741. FX_ENTRY("H263InitDecoderInstance");
  742. if(IsBadWritePtr((LPVOID)lpInst, sizeof(DECINSTINFO)))
  743. {
  744. ERRORMESSAGE(("%s: Bad input parameter!\r\n", _fx_));
  745. iReturn = ICERR_BADPARAM;
  746. goto done;
  747. }
  748. lpInst->Initialized = FALSE;
  749. #ifdef NO_BEF // { NO_BEF
  750. // default block edge filter
  751. lpInst->bUseBlockEdgeFilter = 0;
  752. #else // }{ NO_BEF
  753. // default block edge filter
  754. lpInst->bUseBlockEdgeFilter = 1;
  755. #endif // } NO_BEF
  756. #if defined(FORCE_8BIT_OUTPUT) && defined(USE_WIN95_PAL) // { #if defined(FORCE_8BIT_OUTPUT) && defined(USE_WIN95_PAL)
  757. lpInst->UseActivePalette = TRUE;
  758. lpInst->InitActivePalette = TRUE;
  759. CopyMemory((PVOID)&lpInst->ActivePalette[10], (CONST VOID *)PalTable, (DWORD)sizeof(PalTable));
  760. #endif // } #if defined(FORCE_8BIT_OUTPUT) && defined(USE_WIN95_PAL)
  761. // Peel off special cases here
  762. i32xres = lpInst->xres;
  763. i32yres = lpInst->yres;
  764. // use positive frame size{s}
  765. // (may be negative to signal frame mirroring or inverted video)
  766. if (i32xres < 0) i32xres = -i32xres;
  767. if (i32yres < 0) i32yres = -i32yres;
  768. #ifdef H263P
  769. // Need to use the padded dimensions for decoding since H.263+ supports
  770. // custom picture formats, which are padded to multiples of 16 for encoding
  771. // and decoding. The actual dimensions are used for display only
  772. i32xresActual = i32xres;
  773. i32yresActual = i32yres;
  774. i32xres = (i32xresActual + 0xf) & ~0xf;
  775. i32yres = (i32yresActual + 0xf) & ~0xf;
  776. #endif
  777. // Next check for 320x240 still
  778. if ( (CodecID == H263_CODEC) && (i32xres == 320) && (i32yres == 240) ) {
  779. i32xres = 352;
  780. i32yres = 288;
  781. bIs320x240 = TRUE;
  782. } else {
  783. bIs320x240 = FALSE;
  784. }
  785. #ifdef H263P
  786. // Add lower bounds and multiples of 4
  787. if ((CodecID == H263_CODEC &&
  788. (i32yresActual > 288 || i32yresActual < 4 ||
  789. i32xresActual > 352 || i32xresActual < 4 ||
  790. (i32yres & ~0x3) != i32yres || (i32xres & ~0x3) != i32xres)) ||
  791. #else
  792. if ((CodecID == H263_CODEC && (i32yres > 288 || i32xres > 352)) ||
  793. #endif
  794. (CodecID == YUV12_CODEC && (i32yres > 480 || i32xres > 640)) )
  795. {
  796. ERRORMESSAGE(("%s: Bad input image size!\r\n", _fx_));
  797. iReturn = ICERR_BADSIZE;
  798. goto done;
  799. }
  800. if (CodecID == YUV12_CODEC)
  801. {
  802. /* The active height and width must be padded to a multiple of 8
  803. * since the adjustpels routine relies on it.
  804. */
  805. u32YActiveHeight = ((i32yres + 0x7) & (~ 0x7));
  806. u32YActiveWidth = ((i32xres + 0x7) & (~ 0x7));
  807. u32UVActiveHeight = ((i32yres + 0xF) & (~ 0xF)) >> 1;
  808. u32UVActiveWidth = ((i32xres + 0xF) & (~ 0xF)) >> 1;
  809. u32YPlane = u32YActiveWidth * u32YActiveHeight;
  810. u32VUPlanes = u32UVActiveWidth * u32UVActiveHeight * 2;
  811. u32YVUPlanes = u32YPlane + u32VUPlanes;
  812. u32TotalSize = 512L + 0x1FL; /* Just enough space for Decoder Catalog. */
  813. }
  814. else
  815. {
  816. ASSERT(CodecID == H263_CODEC);
  817. u32YActiveHeight = i32yres + UMV_EXPAND_Y + UMV_EXPAND_Y ;
  818. u32YActiveWidth = i32xres + UMV_EXPAND_Y + UMV_EXPAND_Y ;
  819. u32UVActiveHeight = u32YActiveHeight/2;
  820. u32UVActiveWidth = u32YActiveWidth /2;
  821. u32YPlane = PITCH * u32YActiveHeight;
  822. u32VUPlanes = PITCH * u32UVActiveHeight;
  823. u32YVUPlanes = u32YPlane + u32VUPlanes;
  824. // calculate the block action stream size. The Y portion has one block
  825. // for every 8x8 region. The U and V portion has one block for every
  826. // 16x16 region. We also want to make sure that the size is aligned to
  827. // a cache line.
  828. u32SizeBlkActionStream = (i32xres >> 3) * (i32yres >> 3);
  829. u32SizeBlkActionStream += ((i32xres >> 4) * (i32yres >> 4)) * 2;
  830. u32SizeBlkActionStream *= sizeof (T_BlkAction);
  831. u32SizeBlkActionStream = (u32SizeBlkActionStream + 31) & ~0x1F;
  832. // calculate sizes of NEW data structures
  833. u32SizeT_IQ_INDEXBuffer = (i32xres)*(i32yres*3)*sizeof(T_IQ_INDEX);
  834. u32SizepNBuffer = (i32xres>>4)*(i32yres>>4)*sizeof(U32)*12;
  835. u32SizeMBInfoStream = (i32xres>>4)*(i32yres>>4)*sizeof(T_MBInfo);
  836. // calculate the bitstream buffer size. We copy the input data to a
  837. // buffer in our space because we read ahead up to 4 bytes beyond the
  838. // end of the input data. The input data size changes for each frame.
  839. // So the following is a very safe upper bound estimate. I am using
  840. // the same formula as in CompressGetSize().
  841. uSizeBitStreamBuffer = i32yres * i32xres;
  842. // RH: allocate bit-stream buffer according to the max size
  843. // specified in the spec.
  844. /*
  845. if (
  846. ((i32xres == 176) && (i32yres == 144))
  847. ||
  848. ((i32xres == 128) && (i32yres == 96))
  849. )
  850. uSizeBitStreamBuffer = 8 * 1024;
  851. else
  852. {
  853. if ( (i32xres == 352) && (i32yres == 288) )
  854. uSizeBitStreamBuffer = 32 * 1024;
  855. else
  856. { // Should never happen
  857. DBOUT("ERROR :: H263InitDecoderInstance :: ICERR_BADSIZE");
  858. iReturn = ICERR_BADSIZE;
  859. goto done;
  860. }
  861. }
  862. */
  863. u32TotalSize = INSTANCE_DATA_FIXED_SIZE +
  864. u32SizeBlkActionStream +
  865. u32YVUPlanes + // current frame
  866. u32YVUPlanes + // prev frame
  867. u32YVUPlanes + // B frame
  868. uSizeBitStreamBuffer + // input data
  869. MB_MC_BUFFER_SIZE +
  870. u32SizeT_IQ_INDEXBuffer + // NEW
  871. u32SizepNBuffer + // NEW
  872. u32SizeMBInfoStream + // PB-NEW
  873. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  874. (DEC_TIMING_INFO_FRAME_COUNT+4) * sizeof (DEC_TIMING_INFO) + // Timing infos
  875. #endif // } LOG_DECODE_TIMINGS_ON
  876. 0x1F;
  877. }
  878. // allocate the memory for the instance
  879. lpInst->pDecoderInst = HeapAlloc(GetProcessHeap(), 0, u32TotalSize);
  880. if (lpInst->pDecoderInst == NULL)
  881. {
  882. ERRORMESSAGE(("%s: Can't allocate %ld bytes!\r\n", _fx_, u32TotalSize));
  883. iReturn = ICERR_MEMORY;
  884. goto done;
  885. }
  886. #ifdef TRACK_ALLOCATIONS
  887. // Track memory allocation
  888. wsprintf(gsz1, "D3DEC: %7ld Ln %5ld\0", u32TotalSize, __LINE__);
  889. AddName((unsigned int)lpInst->pDecoderInst, gsz1);
  890. #endif
  891. pDecoderInstance = lpInst->pDecoderInst;
  892. //build the decoder catalog
  893. P32Inst = (U8 *) pDecoderInstance;
  894. P32Inst = (U8 *) ((((U32) P32Inst) + 31) & ~0x1F);
  895. // The catalog of per-instance data is at the start of the per-instance data.
  896. DC = (T_H263DecoderCatalog *) P32Inst;
  897. DC->DecoderType = CodecID;
  898. DC->uFrameHeight = i32yres;
  899. DC->uFrameWidth = i32xres;
  900. #ifdef H263P
  901. DC->uActualFrameHeight = i32yresActual;
  902. DC->uActualFrameWidth = i32xresActual;
  903. if (CodecID == YUV12_CODEC) {
  904. // YUV12 data is not padded out to multiples of 16 as H.263+ frames are
  905. // Therefore, only use the actual frame dimensions!
  906. DC->uFrameHeight = DC->uActualFrameHeight;
  907. DC->uFrameWidth = DC->uActualFrameWidth;
  908. }
  909. #endif
  910. DC->uYActiveHeight = u32YActiveHeight;
  911. DC->uYActiveWidth = u32YActiveWidth;
  912. DC->uUVActiveHeight = u32UVActiveHeight;
  913. DC->uUVActiveWidth = u32UVActiveWidth;
  914. DC->uSz_YPlane = u32YPlane;
  915. DC->uSz_VUPlanes = u32VUPlanes;
  916. DC->uSz_YVUPlanes = u32YVUPlanes;
  917. DC->BrightnessSetting = H26X_DEFAULT_BRIGHTNESS;
  918. DC->ContrastSetting = H26X_DEFAULT_CONTRAST;
  919. DC->SaturationSetting = H26X_DEFAULT_SATURATION;
  920. DC->iAPColorConvPrev = 0;
  921. DC->pAPInstPrev = NULL; // assume no previous AP instance.
  922. DC->p16InstPostProcess = NULL;
  923. DC->_p16InstPostProcess = (void *)NULL;
  924. DC->uIs320x240 = bIs320x240;
  925. DC->bReadSrcFormat = FALSE;
  926. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  927. DC->uStatFrameCount = 0;
  928. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  929. /* Get the Options
  930. */
  931. GetDecoderOptions(DC);
  932. if (CodecID == H263_CODEC)
  933. {
  934. // Notice: Decoder memory is stored in YVU order. This simplifies
  935. // working with the color converters which use YVU12.
  936. // LONG TERM: We may want to change this someday because the encoder
  937. // stores data in YUV order. Or perhaps the encoder should
  938. // change?
  939. lOffset = INSTANCE_DATA_FIXED_SIZE;
  940. DC->Ticker = 127;
  941. //instance dependent table here
  942. ASSERT((lOffset & 0x3) == 0); // DWORD alignment
  943. DC->X16_BlkActionStream = lOffset;
  944. lOffset += u32SizeBlkActionStream;
  945. ASSERT((lOffset & 0x7) == 0); // QWORD alignment
  946. DC->CurrFrame.X32_YPlane = lOffset;
  947. lOffset += DC->uSz_YPlane;
  948. ASSERT((lOffset & 0x7) == 0); // QWORD alignment
  949. DC->CurrFrame.X32_VPlane = lOffset;
  950. DC->CurrFrame.X32_UPlane = DC->CurrFrame.X32_VPlane + PITCH / 2;
  951. ASSERT((DC->CurrFrame.X32_UPlane & 0x7) == 0); // QWORD alignment
  952. lOffset += DC->uSz_VUPlanes;
  953. //no padding is needed
  954. ASSERT((lOffset & 0x7) == 0); // QWORD alignment
  955. DC->PrevFrame.X32_YPlane = lOffset;
  956. lOffset += DC->uSz_YPlane;
  957. ASSERT((lOffset & 0x7) == 0); // QWORD alignment
  958. DC->PrevFrame.X32_VPlane = lOffset;
  959. DC->PrevFrame.X32_UPlane = DC->PrevFrame.X32_VPlane + PITCH / 2;
  960. ASSERT((DC->PrevFrame.X32_UPlane & 0x7) == 0); // QWORD alignment
  961. lOffset += DC->uSz_VUPlanes;
  962. // B Frame
  963. ASSERT((lOffset & 0x7) == 0); // QWORD alignment
  964. DC->PBFrame.X32_YPlane = lOffset;
  965. lOffset += DC->uSz_YPlane;
  966. ASSERT((lOffset & 0x7) == 0); // QWORD alignment
  967. DC->PBFrame.X32_VPlane = lOffset;
  968. DC->PBFrame.X32_UPlane = DC->PBFrame.X32_VPlane + PITCH / 2;
  969. ASSERT((DC->PBFrame.X32_UPlane & 0x7) == 0); // QWORD alignment
  970. lOffset += DC->uSz_VUPlanes;
  971. // Bitstream
  972. ASSERT((lOffset & 0x3) == 0); // DWORD alignment
  973. DC->X32_BitStream = lOffset;
  974. lOffset += uSizeBitStreamBuffer;
  975. DC->uSizeBitStreamBuffer = uSizeBitStreamBuffer;
  976. DC->uMBBuffer = lOffset;
  977. // MMX IDCT writes its output to (DC->uMBBuffer + BLOCK_BUFFER_OFFSET)
  978. // and so it must be aligned at QWORD
  979. ASSERT((( (U32)DC + DC->uMBBuffer + BLOCK_BUFFER_OFFSET) & 0x7) == 0);
  980. lOffset += MB_MC_BUFFER_SIZE;
  981. ASSERT((lOffset & 0x3) == 0); // DWORD alignment
  982. DC->X32_InverseQuant = lOffset;
  983. lOffset += u32SizeT_IQ_INDEXBuffer;
  984. ASSERT((lOffset & 0x3) == 0); // DWORD alignment
  985. DC->X32_pN = lOffset;
  986. lOffset += u32SizepNBuffer;
  987. ASSERT((lOffset & 0x3) == 0); // DWORD alignment
  988. DC->X32_uMBInfoStream = lOffset;
  989. lOffset += u32SizeMBInfoStream;
  990. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  991. // Decode Timing Info
  992. DC->X32_DecTimingInfo = lOffset;
  993. lOffset += (DEC_TIMING_INFO_FRAME_COUNT+4) * sizeof (DEC_TIMING_INFO);
  994. #endif // } LOG_DECODE_TIMINGS_ON
  995. // init the data
  996. ASSERT((U32)lOffset <= u32TotalSize);
  997. pInitLimit = (U32 *) (P32Inst + lOffset);
  998. pInitPtr = (U32 *) (P32Inst + DC->CurrFrame.X32_YPlane);
  999. for (;pInitPtr < pInitLimit;pInitPtr++) *pInitPtr =0;
  1000. // Fill the Y,U,V Previous Frame space with black, this way
  1001. // even if we lose an I frame, the background will remain black
  1002. ZeroFill((HPBYTE)P32Inst + DC->PrevFrame.X32_YPlane + Y_START,
  1003. (HPBYTE)P32Inst + DC->PrevFrame.X32_UPlane + UV_START,
  1004. (HPBYTE)P32Inst + DC->PrevFrame.X32_VPlane + UV_START,
  1005. PITCH,
  1006. DC->uFrameWidth,
  1007. DC->uFrameHeight);
  1008. // H263InitializeBlockActionStream(DC);
  1009. } // H263
  1010. #ifdef NEW_BEF // { NEW_BEF
  1011. // Initialize de-blocking filter
  1012. {
  1013. int i,j;
  1014. for (j = 0; j < 19; j++) {
  1015. for (i = 0; i < 23; i++) {
  1016. coded_map[j][i] = 0;
  1017. }
  1018. }
  1019. InitEdgeFilterTab();
  1020. }
  1021. #endif // } NEW_BEF
  1022. lpInst->Initialized = TRUE;
  1023. iReturn = ICERR_OK;
  1024. done:
  1025. return iReturn;
  1026. }
  1027. /***********************************************************************
  1028. * ZeroFill
  1029. * Fill the YVU data area with black.
  1030. ***********************************************************************/
  1031. static void ZeroFill(HPBYTE hpbY, HPBYTE hpbU, HPBYTE hpbV, int iPitch, U32 uWidth, U32 uHeight)
  1032. {
  1033. U32 w,h;
  1034. int y,u,v;
  1035. U32 uNext;
  1036. HPBYTE pY, pU, pV;
  1037. y = 32;
  1038. uNext = iPitch - uWidth;
  1039. for (h = 0 ; h < uHeight ; h++) {
  1040. pY = hpbY;
  1041. for (w = 0; w < uWidth ; w++) {
  1042. *hpbY++ = (U8)16;
  1043. }
  1044. hpbY += uNext;
  1045. }
  1046. uWidth = uWidth / 2;
  1047. uHeight = uHeight / 2;
  1048. uNext = iPitch - uWidth;
  1049. for (h = 0 ; h < uHeight ; h++) {
  1050. pV = hpbV;
  1051. pU = hpbU;
  1052. for (w = 0; w < uWidth ; w++) {
  1053. *hpbV++ = (U8)128;
  1054. *hpbU++ = (U8)128;
  1055. }
  1056. hpbV += uNext;
  1057. hpbU += uNext;
  1058. }
  1059. }
  1060. /***********************************************************************
  1061. * TestFill
  1062. * Fill the YVU data area with a test pattern.
  1063. ***********************************************************************/
  1064. #if 0
  1065. static void
  1066. TestFill(
  1067. HPBYTE hpbY,
  1068. HPBYTE hpbU,
  1069. HPBYTE hpbV,
  1070. int iPitch,
  1071. U32 uWidth,
  1072. U32 uHeight)
  1073. {
  1074. U32 w,h;
  1075. int y,u,v;
  1076. U32 uNext;
  1077. HPBYTE pY, pU, pV;
  1078. y = 32;
  1079. uNext = iPitch - uWidth;
  1080. for (h = 0 ; h < uHeight ; h++) {
  1081. pY = hpbY;
  1082. for (w = 0; w < uWidth ; w++) {
  1083. *hpbY++ = (U8) (y + (w & ~0xF));
  1084. }
  1085. hpbY += uNext;
  1086. }
  1087. uWidth = uWidth / 2;
  1088. uHeight = uHeight / 2;
  1089. u = 0x4e * 2;
  1090. v = 44;
  1091. uNext = iPitch - uWidth;
  1092. for (h = 0 ; h < uHeight ; h++) {
  1093. pV = hpbV;
  1094. pU = hpbU;
  1095. for (w = 0; w < uWidth ; w++) {
  1096. *hpbV++ = (U8) v;
  1097. *hpbU++ = (U8) u;
  1098. }
  1099. hpbV += uNext;
  1100. hpbU += uNext;
  1101. }
  1102. } /* end TestFill */
  1103. static void
  1104. TestFillUV(
  1105. HPBYTE hpbU,
  1106. HPBYTE hpbV,
  1107. int iPitch,
  1108. U32 uWidth,
  1109. U32 uHeight)
  1110. {
  1111. U32 w,h;
  1112. int u,v;
  1113. U32 uNext;
  1114. HPBYTE pU, pV;
  1115. uWidth = uWidth / 2;
  1116. uHeight = uHeight / 2;
  1117. u = 128;
  1118. v = 128;
  1119. uNext = iPitch - uWidth;
  1120. for (h = 0 ; h < uHeight ; h++) {
  1121. pV = hpbV;
  1122. pU = hpbU;
  1123. for (w = 0; w < uWidth ; w++) {
  1124. *hpbV++ = (U8) v;
  1125. *hpbU++ = (U8) u;
  1126. }
  1127. hpbV += uNext;
  1128. hpbU += uNext;
  1129. }
  1130. } // end TestFill
  1131. #endif
  1132. /*********************************************************************
  1133. * H263Decompress
  1134. * This function drives the decompress and display of one frame
  1135. *********************************************************************/
  1136. LRESULT H263Decompress(
  1137. LPDECINST lpInst,
  1138. ICDECOMPRESSEX FAR * lpicDecEx,
  1139. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1140. BOOL bIsDCI,
  1141. BOOL bRealDecompress)
  1142. #else // }{ #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1143. BOOL bIsDCI)
  1144. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1145. {
  1146. LRESULT iReturn = ICERR_ERROR;
  1147. U8 FAR * fpSrc;
  1148. U8 FAR * P32Inst;
  1149. U8 FAR * fpu8MaxPtr;
  1150. LPVOID pDecoderInstance = NULL;
  1151. T_H263DecoderCatalog * DC = NULL;
  1152. I32 iNumberOfGOBs, iNumberOfMBs, iBlockNumber = 0;
  1153. T_BlkAction FAR * fpBlockAction;
  1154. LONG lOutput;
  1155. int intPitch;
  1156. U32 uNewOffsetToLine0, uNewFrameHeight;
  1157. BOOL bShapingFlag, bMirror;
  1158. U32 uYPitch, uUVPitch;
  1159. T_IQ_INDEX * pRUN_INVERSE_Q;
  1160. U32 * pN;
  1161. T_MBInfo FAR * fpMBInfo;
  1162. U32 uSaveHeight, uSaveWidth, utemp, uYPlane, uUPlane;
  1163. I32 uVPlane;
  1164. U8 * pFrame;
  1165. U32 uWork; // variables for reading bits
  1166. U32 uBitsReady;
  1167. BITSTREAM_STATE bsState;
  1168. BITSTREAM_STATE FAR * fpbsState = &bsState;
  1169. I32 gob_start = 1, mb_start = 1, b_skip;
  1170. I8 p8MVs[4]={0,0,0,0};
  1171. #ifdef H263P
  1172. BOOL bTmpPostProcessBEF;
  1173. #endif
  1174. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1175. U32 uStartLow;
  1176. U32 uStartHigh;
  1177. U32 uElapsed;
  1178. U32 uBefore;
  1179. U32 uDecodeTime = 0;
  1180. U32 uBEFTime = 0;
  1181. int bTimingThisFrame = 0;
  1182. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1183. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1184. U32 uDecIDCTCoeffs = 0;
  1185. U32 uHeaders = 0;
  1186. U32 uMemcpy = 0;
  1187. U32 uFrameCopy = 0;
  1188. U32 uOutputCC = 0;
  1189. U32 uIDCTandMC = 0;
  1190. #endif // } DETAILED_DECODE_TIMINGS_ON
  1191. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  1192. DEC_TIMING_INFO * pDecTimingInfo = NULL;
  1193. #endif // } LOG_DECODE_TIMINGS_ON
  1194. FX_ENTRY("H263Decompress");
  1195. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1196. if (bRealDecompress)
  1197. {
  1198. TIMER_START(bTimingThisFrame,uStartLow,uStartHigh);
  1199. }
  1200. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1201. // check the input pointers
  1202. if (IsBadWritePtr((LPVOID)lpInst, sizeof(DECINSTINFO))||
  1203. IsBadReadPtr((LPVOID)lpicDecEx, sizeof(ICDECOMPRESSEX)))
  1204. {
  1205. ERRORMESSAGE(("%s: Bad input parameter!\r\n", _fx_));
  1206. iReturn = ICERR_BADPARAM;
  1207. goto done;
  1208. }
  1209. // Check for a bad length
  1210. if (lpicDecEx->lpbiSrc->biSizeImage == 0) {
  1211. ERRORMESSAGE(("%s: Bad image size!\r\n", _fx_));
  1212. iReturn = ICERR_BADIMAGESIZE;
  1213. goto done;
  1214. }
  1215. // set local pointer to global memory
  1216. pDecoderInstance = lpInst->pDecoderInst;
  1217. // Set the frame mirroring flag
  1218. bMirror = FALSE;
  1219. if (lpicDecEx->lpbiDst != 0)
  1220. {
  1221. if(lpicDecEx->lpbiSrc->biWidth * lpicDecEx->lpbiDst->biWidth < 0)
  1222. bMirror = TRUE;
  1223. }
  1224. // Build the decoder catalog pointer
  1225. P32Inst = (U8 FAR *) pDecoderInstance;
  1226. P32Inst = (U8 FAR *) ((((U32) P32Inst) + 31) & ~0x1F);
  1227. DC = (T_H263DecoderCatalog FAR *) P32Inst;
  1228. if (DC->DecoderType == H263_CODEC)
  1229. {
  1230. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  1231. if (bRealDecompress)
  1232. {
  1233. if ((DC->uStatFrameCount <= DEC_TIMING_INFO_FRAME_COUNT) && (DC->ColorConvertor != YUV12ForEnc))
  1234. {
  1235. if (DC->X32_DecTimingInfo > 0)
  1236. DC->pDecTimingInfo = (DEC_TIMING_INFO FAR *)( ((U8 FAR *)P32Inst) + DC->X32_DecTimingInfo );
  1237. DC->uStartLow = uStartLow;
  1238. DC->uStartHigh = uStartHigh;
  1239. }
  1240. else
  1241. {
  1242. DC->pDecTimingInfo = (DEC_TIMING_INFO FAR *) NULL;
  1243. }
  1244. DC->bTimingThisFrame = bTimingThisFrame;
  1245. }
  1246. #endif // } LOG_DECODE_TIMINGS_ON
  1247. // Check if h263test.ini has been used to override custom message
  1248. // for block edge filter. If BlockEdgeFilter is not specified in
  1249. // the [Decode] section of h263test.ini, DC->bUseBlockEdgeFilter
  1250. // will be set to 2, and the value specified in a custom message
  1251. // will be chosen.
  1252. if (DC->bUseBlockEdgeFilter == 2) {
  1253. DC->bUseBlockEdgeFilter = lpInst->bUseBlockEdgeFilter;
  1254. }
  1255. // First check to see if we are just going to return the P frame
  1256. // which we have already decoded.
  1257. /*********************************************************************
  1258. *
  1259. * Hack for the special "Null" P frames for Windows
  1260. *
  1261. *********************************************************************/
  1262. if (lpicDecEx->lpbiSrc->biSizeImage != 8)
  1263. {
  1264. /* Is there room to copy the bitstream data? */
  1265. // OLD: ASSERT(lpicDecEx->lpbiSrc->biSizeImage <= DC->uSizeBitStreamBuffer);
  1266. // RH: Make sure that the bitstream can be fit in our allocated buffer. If
  1267. // not, return an error.
  1268. if ( lpicDecEx->lpbiSrc->biSizeImage > DC->uSizeBitStreamBuffer) {
  1269. ERRORMESSAGE(("%s: Internal buffer (%ld bytes) too small for input data (%ld bytes)!\r\n", _fx_, DC->uSizeBitStreamBuffer, lpicDecEx->lpbiSrc->biSizeImage));
  1270. if (!H263RTP_VerifyBsInfoStream(DC,
  1271. (U8 *) lpicDecEx->lpSrc,
  1272. lpicDecEx->lpbiSrc->biSizeImage))
  1273. {
  1274. ERRORMESSAGE(("%s: Input buffer too big without RTP extention!\r\n", _fx_));
  1275. iReturn = ICERR_ERROR;
  1276. goto done;
  1277. }
  1278. else
  1279. lpicDecEx->lpbiSrc->biSizeImage= DC->uSizeBitStreamBuffer;
  1280. }
  1281. // Copy the source data to the bitstream region.
  1282. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1283. if (bRealDecompress)
  1284. {
  1285. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1286. }
  1287. #endif // } DETAILED_DECODE_TIMINGS_ON
  1288. fpSrc = (U8 FAR *)(P32Inst + DC->X32_BitStream);
  1289. memcpy((char FAR *)fpSrc, (const char FAR *) lpicDecEx->lpSrc,
  1290. lpicDecEx->lpbiSrc->biSizeImage);
  1291. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1292. if (bRealDecompress)
  1293. {
  1294. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uMemcpy)
  1295. }
  1296. #endif // } DETAILED_DECODE_TIMINGS_ON
  1297. // Initialize the bit stream reader
  1298. GET_BITS_INIT(uWork, uBitsReady);
  1299. //#ifdef LOSS_RECOVERY
  1300. DC->Sz_BitStream = lpicDecEx->lpbiSrc->biSizeImage;
  1301. // H263RTP_VerifyBsInfoStream(DC,fpSrc,DC->Sz_BitStream);
  1302. //RtpForcePacketLoss(fpSrc,lpicDecEx->lpbiSrc->biSizeImage,0);
  1303. //#endif
  1304. // Initialize pointers to data structures which carry info
  1305. // between passes
  1306. pRUN_INVERSE_Q = (T_IQ_INDEX *)(P32Inst + DC->X32_InverseQuant);
  1307. pN = (U32 *)(P32Inst + DC->X32_pN);
  1308. fpMBInfo = (T_MBInfo FAR *) (P32Inst + DC->X32_uMBInfoStream);
  1309. // Initialize block action stream pointer
  1310. iBlockNumber = 0;
  1311. fpBlockAction = (T_BlkAction FAR *)(P32Inst + DC->X16_BlkActionStream);
  1312. // Decode the Picture Header
  1313. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1314. if (bRealDecompress)
  1315. {
  1316. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1317. }
  1318. #endif // } DETAILED_DECODE_TIMINGS_ON
  1319. iReturn = H263DecodePictureHeader(DC, fpSrc, uBitsReady, uWork,
  1320. fpbsState);
  1321. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1322. if (bRealDecompress)
  1323. {
  1324. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uHeaders)
  1325. }
  1326. #endif // } DETAILED_DECODE_TIMINGS_ON
  1327. if (iReturn == PACKET_FAULT)
  1328. {
  1329. ERRORMESSAGE(("%s: PSC lost!\r\n", _fx_));
  1330. iReturn = RtpGetPicHeaderFromBsExt(DC);
  1331. if (iReturn != ICERR_OK)
  1332. goto done;
  1333. iReturn = RtpH263FindNextPacket(DC, fpbsState, &pN,
  1334. &DC->uPQuant, (int *)&mb_start, (int *)&gob_start,p8MVs);
  1335. if (iReturn == NEXT_MODE_A)
  1336. {
  1337. //trick it for now, do not change without consulting Chad
  1338. gob_start++;
  1339. mb_start++;
  1340. ERRORMESSAGE(("%s: Next packet following lost PSC is in MODE A\r\n", _fx_));
  1341. }
  1342. else if ((iReturn == NEXT_MODE_B) || (iReturn == NEXT_MODE_C))
  1343. {
  1344. int k;
  1345. if (iReturn == NEXT_MODE_B)
  1346. {
  1347. k=1;
  1348. ERRORMESSAGE(("%s: Next packet in MODE B\r\n", _fx_));
  1349. }
  1350. else
  1351. {
  1352. ERRORMESSAGE(("%s: Next packet in MODE C\r\n", _fx_));
  1353. k=2;
  1354. }
  1355. #ifdef H263P
  1356. // The number of MB's is merely (width / 16)
  1357. iNumberOfMBs = DC->uFrameWidth >> 4;
  1358. #else
  1359. iNumberOfMBs = iNumberOfMBsInAGOBBySourceFormat[DC->uSrcFormat];
  1360. #endif
  1361. b_skip = (gob_start* iNumberOfMBs + mb_start)*6*k;
  1362. for ( k=0; k < b_skip; k++) *pN++=0;
  1363. fpBlockAction += b_skip;
  1364. iBlockNumber += b_skip;
  1365. fpMBInfo += b_skip/6;
  1366. mb_start++;
  1367. gob_start++;
  1368. /*for (k=0;k<6;k++)
  1369. {
  1370. fpBlockAction[k].i8MVx2 = p8MVs[0];
  1371. fpBlockAction[k].i8MVy2 = p8MVs[1];
  1372. } */
  1373. }
  1374. else
  1375. {
  1376. iReturn = ICERR_UNSUPPORTED;
  1377. goto done;
  1378. }
  1379. }
  1380. else
  1381. //old code before merging
  1382. if (iReturn != ICERR_OK)
  1383. {
  1384. ERRORMESSAGE(("%s: Error reading the picture header!\r\n", _fx_));
  1385. goto done;
  1386. }
  1387. // Set a limit for testing for bitstream over-run
  1388. fpu8MaxPtr = fpSrc;
  1389. fpu8MaxPtr += (lpicDecEx->lpbiSrc->biSizeImage - 1);
  1390. // Initialize some constants
  1391. #if defined(H263P) || defined(USE_BILINEAR_MSH26X)
  1392. if (DC->uFrameHeight < 500)
  1393. // Each GOB consists of 16 lines
  1394. iNumberOfGOBs = DC->uFrameHeight >> 4;
  1395. else if (DC->uFrameHeight < 996)
  1396. // Each GOB consists of 32 lines
  1397. iNumberOfGOBs = DC->uFrameHeight >> 5;
  1398. else
  1399. // Each GOB consists of 64 lines
  1400. iNumberOfGOBs = DC->uFrameHeight >> 6;
  1401. iNumberOfMBs = DC->uFrameWidth >> 4;
  1402. #else
  1403. iNumberOfGOBs = iNumberOfGOBsBySourceFormat[DC->uSrcFormat];
  1404. iNumberOfMBs = iNumberOfMBsInAGOBBySourceFormat[DC->uSrcFormat];
  1405. #endif
  1406. DC->iNumberOfMBsPerGOB = iNumberOfMBs;
  1407. /*
  1408. * Check dimensions:
  1409. * In H263 a GOB is a single row of MB, and a MB is 16x16
  1410. */
  1411. ASSERT(((U32)iNumberOfGOBs * 16) == DC->uFrameHeight);
  1412. ASSERT(((U32)iNumberOfMBs * 16) == DC->uFrameWidth);
  1413. /*****************************************************************
  1414. FIRST PASS - bitream parsing and IDCT prep work
  1415. ***************************************************************/
  1416. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1417. if (bRealDecompress)
  1418. {
  1419. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1420. }
  1421. #endif // } DETAILED_DECODE_TIMINGS_ON
  1422. #ifdef USE_MMX // { USE_MMX
  1423. if (DC->bMMXDecoder)
  1424. {
  1425. __asm {
  1426. _emit 0x0f
  1427. _emit 0x77 // emms
  1428. }
  1429. }
  1430. #endif // } USE_MMX
  1431. iReturn = IAPass1ProcessFrame(DC,
  1432. fpBlockAction,
  1433. fpMBInfo,
  1434. fpbsState,
  1435. fpu8MaxPtr,
  1436. pN,
  1437. pRUN_INVERSE_Q,
  1438. iNumberOfGOBs,
  1439. iNumberOfMBs,
  1440. gob_start,
  1441. mb_start);
  1442. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1443. if (bRealDecompress)
  1444. {
  1445. // decode and inverse quantize the transform coefficients
  1446. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uDecIDCTCoeffs)
  1447. }
  1448. #endif // } DETAILED_DECODE_TIMINGS_ON
  1449. if (iReturn != ICERR_OK) {
  1450. ERRORMESSAGE(("%s: Error during first pass - bitream parsing and IDCT prep work!\r\n", _fx_));
  1451. goto done;
  1452. }
  1453. /*****************************************************************
  1454. SECOND PASS - IDCT and motion compensation (MC)
  1455. ***************************************************************/
  1456. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1457. if (bRealDecompress)
  1458. {
  1459. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1460. }
  1461. #endif // } DETAILED_DECODE_TIMINGS_ON
  1462. if (DC->bAdvancedPrediction || DC->bUnrestrictedMotionVectors)
  1463. {
  1464. // Change parameter profile once Bob is finished making
  1465. // changes to ExpandPlane routine : AG
  1466. ExpandPlane((U32) (P32Inst + DC->PrevFrame.X32_YPlane + Y_START),
  1467. (U32) (DC->uFrameWidth),
  1468. (U32) (DC->uFrameHeight),
  1469. 16); // TODO 16 number of pels to expand by
  1470. ExpandPlane((U32) (P32Inst + DC->PrevFrame.X32_VPlane + UV_START),
  1471. (U32) (DC->uFrameWidth>>1),
  1472. (U32) (DC->uFrameHeight>>1),
  1473. 8); // TODO 8
  1474. ExpandPlane((U32) (P32Inst + DC->PrevFrame.X32_UPlane + UV_START),
  1475. (U32) (DC->uFrameWidth>>1),
  1476. (U32) (DC->uFrameHeight>>1),
  1477. 8); // TODO 8
  1478. }
  1479. fpBlockAction = (T_BlkAction FAR *) (P32Inst + DC->X16_BlkActionStream);
  1480. pRUN_INVERSE_Q = (T_IQ_INDEX *)(P32Inst + DC->X32_InverseQuant);
  1481. pN = (U32 *)(P32Inst + DC->X32_pN);
  1482. fpMBInfo = (T_MBInfo FAR *)(P32Inst + DC->X32_uMBInfoStream);
  1483. IAPass2ProcessFrame(DC,
  1484. fpBlockAction,
  1485. fpMBInfo,
  1486. pN,
  1487. pRUN_INVERSE_Q,
  1488. iNumberOfGOBs,
  1489. iNumberOfMBs);
  1490. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1491. if (bRealDecompress)
  1492. {
  1493. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uIDCTandMC)
  1494. }
  1495. #endif // } DETAILED_DECODE_TIMINGS_ON
  1496. #ifdef H263P
  1497. if (DC->bDeblockingFilter) {
  1498. // In the loop deblocking filter.
  1499. // Annex J, document LBC-96-358
  1500. // If the filtering is performed inside the loop, we
  1501. // do not also perform a post-process block edge filter.
  1502. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1503. if (bRealDecompress)
  1504. {
  1505. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1506. }
  1507. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1508. bTmpPostProcessBEF = DC->bUseBlockEdgeFilter;
  1509. DC->bUseBlockEdgeFilter = FALSE;
  1510. EdgeFilter((U8 *)DC + DC->CurrFrame.X32_YPlane + Y_START,
  1511. (U8 *)DC + DC->CurrFrame.X32_VPlane + UV_START,
  1512. (U8 *)DC + DC->CurrFrame.X32_UPlane + UV_START,
  1513. DC->uFrameWidth,
  1514. DC->uFrameHeight,
  1515. PITCH);
  1516. if (DC->bPBFrame)
  1517. {
  1518. // Filtering of B frames is not a manner of standardization.
  1519. // We do it since we assume that it will yield improved
  1520. // picture quality.
  1521. // TODO, verify this assumption.
  1522. EdgeFilter((U8 *)DC + DC->PBFrame.X32_YPlane + Y_START,
  1523. (U8 *)DC + DC->PBFrame.X32_VPlane + UV_START,
  1524. (U8 *)DC + DC->PBFrame.X32_UPlane + UV_START,
  1525. DC->uFrameWidth,
  1526. DC->uFrameHeight,
  1527. PITCH);
  1528. }
  1529. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1530. if (bRealDecompress)
  1531. {
  1532. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uBEFTime)
  1533. }
  1534. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1535. } // if (DC->bDeblockingFilter)
  1536. #endif // H263P
  1537. //copy to the reference frame to prepare for the next frame
  1538. // Decide which frame to display
  1539. if (DC->bPBFrame)
  1540. { // Set pointers to return B frame for PB pair
  1541. DC->DispFrame.X32_YPlane = DC->PBFrame.X32_YPlane;
  1542. DC->DispFrame.X32_VPlane = DC->PBFrame.X32_VPlane;
  1543. DC->DispFrame.X32_UPlane = DC->PBFrame.X32_UPlane;
  1544. }
  1545. else
  1546. { // Set pointers to return future P of PB pair
  1547. DC->DispFrame.X32_YPlane = DC->CurrFrame.X32_YPlane;
  1548. DC->DispFrame.X32_VPlane = DC->CurrFrame.X32_VPlane;
  1549. DC->DispFrame.X32_UPlane = DC->CurrFrame.X32_UPlane;
  1550. }
  1551. utemp = DC->CurrFrame.X32_YPlane;
  1552. DC->CurrFrame.X32_YPlane = DC->PrevFrame.X32_YPlane;
  1553. DC->PrevFrame.X32_YPlane = utemp;
  1554. utemp = DC->CurrFrame.X32_VPlane ;
  1555. DC->CurrFrame.X32_VPlane = DC->PrevFrame.X32_VPlane;
  1556. DC->PrevFrame.X32_VPlane = utemp;
  1557. utemp = DC->CurrFrame.X32_UPlane ;
  1558. DC->CurrFrame.X32_UPlane = DC->PrevFrame.X32_UPlane;
  1559. DC->PrevFrame.X32_UPlane = utemp;
  1560. }
  1561. /*********************************************************************
  1562. *
  1563. * Hack for the special "Null" P frames for Windows
  1564. *
  1565. *********************************************************************/
  1566. else // lpicDecEx->lpbiSrc->biSizeImage == 8
  1567. { // Set pointers to return P frame for PB pair
  1568. #ifdef _DEBUG
  1569. if (!DC->bPBFrame)
  1570. {
  1571. ERRORMESSAGE(("%s: Null frame received even though previous was not PB\r\n", _fx_));
  1572. }
  1573. #endif
  1574. DC->DispFrame.X32_YPlane = DC->PrevFrame.X32_YPlane;
  1575. DC->DispFrame.X32_VPlane = DC->PrevFrame.X32_VPlane;
  1576. DC->DispFrame.X32_UPlane = DC->PrevFrame.X32_UPlane;
  1577. }
  1578. } // end of H263_CODEC
  1579. else
  1580. { // why is this here??? Is it really needed for YUV12 display?
  1581. DC->DispFrame.X32_YPlane = DC->PrevFrame.X32_YPlane;
  1582. DC->DispFrame.X32_VPlane = DC->PrevFrame.X32_VPlane;
  1583. DC->DispFrame.X32_UPlane = DC->PrevFrame.X32_UPlane;
  1584. }
  1585. // Return if there is no need to update screen yet.
  1586. if(lpicDecEx->dwFlags & ICDECOMPRESS_HURRYUP) {
  1587. iReturn = ICERR_DONTDRAW;
  1588. goto done;
  1589. }
  1590. if (DC->ColorConvertor == YUV12ForEnc)
  1591. {
  1592. /* NOTICE: This color converter reverses the order of the data in
  1593. * memory. The decoder uses YVU order and the encoder uses
  1594. * YUV order.
  1595. */
  1596. // TODO can this be DispFrame ???? Trying to get rid of
  1597. // references to PrevFrame and CurrFrame after this point
  1598. H26x_YUV12ForEnc ((HPBYTE)P32Inst,
  1599. DC->PrevFrame.X32_YPlane + Y_START,
  1600. DC->PrevFrame.X32_VPlane + UV_START,
  1601. DC->PrevFrame.X32_UPlane + UV_START,
  1602. DC->uFrameWidth,
  1603. DC->uFrameHeight,
  1604. PITCH,
  1605. (HPBYTE)lpicDecEx->lpDst,
  1606. (DWORD)Y_START,
  1607. (DWORD)(MAX_HEIGHT + 2L*UMV_EXPAND_Y) * PITCH + 8 + UV_START + PITCH / 2,
  1608. (DWORD)(MAX_HEIGHT + 2L*UMV_EXPAND_Y) * PITCH + 8 + UV_START);
  1609. iReturn = ICERR_OK;
  1610. goto done;
  1611. }
  1612. #if 0
  1613. // Fill the Y,U,V Current Frame space with a test pattern
  1614. TestFill((HPBYTE)P32Inst + DC->DispFrame.X32_YPlane + Y_START,
  1615. (HPBYTE)P32Inst + DC->DispFrame.X32_UPlane + UV_START,
  1616. (HPBYTE)P32Inst + DC->DispFrame.X32_VPlane + UV_START,
  1617. PITCH,
  1618. DC->uFrameWidth,
  1619. DC->uFrameHeight);
  1620. #endif
  1621. #if MAKE_GRAY
  1622. // Fill the U,V Current Frame space with a test pattern
  1623. TestFillUV((HPBYTE)P32Inst + DC->DispFrame.X32_UPlane + UV_START,
  1624. (HPBYTE)P32Inst + DC->DispFrame.X32_VPlane + UV_START,
  1625. PITCH,
  1626. DC->uFrameWidth,
  1627. DC->uFrameHeight);
  1628. #endif
  1629. /* Special case the YVU12 for the encoder because it should not include
  1630. * BEF, Shaping or aspect ratio correction...
  1631. */
  1632. // Copy Planes to Post Processing area, and block edge filter.
  1633. if (DC->DecoderType == H263_CODEC)
  1634. {
  1635. // 3/5/96: Steve asserted that mirroring is not needed for the remote
  1636. // stream (i.e. H263_CODEC) -a.g.
  1637. // But I will leave this code in.
  1638. uYPitch = PITCH;
  1639. uUVPitch = PITCH;
  1640. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1641. if (bRealDecompress)
  1642. {
  1643. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1644. }
  1645. #endif // } DETAILED_DECODE_TIMINGS_ON
  1646. if(bMirror)
  1647. {
  1648. // copy with mirroring
  1649. pFrame = (U8 *)DC->p16InstPostProcess;
  1650. uYPlane = DC->PostFrame.X32_YPlane;
  1651. uUPlane = DC->PostFrame.X32_UPlane;
  1652. uVPlane = DC->PostFrame.X32_VPlane;
  1653. FrameMirror((U8 *)DC + DC->DispFrame.X32_YPlane + Y_START,
  1654. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_YPlane,
  1655. #ifdef H263P
  1656. DC->uActualFrameHeight,
  1657. DC->uActualFrameWidth,
  1658. #else
  1659. DC->uFrameHeight,
  1660. DC->uFrameWidth,
  1661. #endif
  1662. PITCH);
  1663. FrameMirror((U8 *)DC + DC->DispFrame.X32_UPlane + UV_START,
  1664. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_UPlane,
  1665. #ifdef H263P
  1666. DC->uActualFrameHeight/2,
  1667. DC->uActualFrameWidth/2,
  1668. #else
  1669. DC->uFrameHeight/2,
  1670. DC->uFrameWidth/2,
  1671. #endif
  1672. PITCH);
  1673. FrameMirror((U8 *)DC + DC->DispFrame.X32_VPlane + UV_START,
  1674. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_VPlane,
  1675. #ifdef H263P
  1676. DC->uActualFrameHeight/2,
  1677. DC->uActualFrameWidth/2,
  1678. #else
  1679. DC->uFrameHeight/2,
  1680. DC->uFrameWidth/2,
  1681. #endif
  1682. PITCH);
  1683. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1684. if (bRealDecompress)
  1685. {
  1686. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFrameCopy)
  1687. }
  1688. #endif // } DETAILED_DECODE_TIMINGS_ON
  1689. }
  1690. else
  1691. { // no mirroring
  1692. // check for 320x240 still
  1693. if (DC->uIs320x240) {
  1694. // save frame size, set 320 x 240 size, then copy as normal
  1695. uSaveWidth = DC->uFrameWidth;
  1696. uSaveHeight = DC->uFrameHeight;
  1697. DC->uFrameWidth = 320;
  1698. DC->uFrameHeight = 240;
  1699. FrameCopy (((HPBYTE) P32Inst) + DC->DispFrame.X32_YPlane + Y_START,
  1700. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_YPlane,
  1701. DC->uFrameHeight,
  1702. DC->uFrameWidth,
  1703. PITCH);
  1704. FrameCopy (((HPBYTE) P32Inst) + DC->DispFrame.X32_UPlane + UV_START,
  1705. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_UPlane,
  1706. DC->uFrameHeight/2,
  1707. DC->uFrameWidth/2,
  1708. PITCH);
  1709. FrameCopy (((HPBYTE) P32Inst) + DC->DispFrame.X32_VPlane + UV_START,
  1710. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_VPlane,
  1711. DC->uFrameHeight/2,
  1712. DC->uFrameWidth/2,
  1713. PITCH);
  1714. pFrame = (U8 *)DC->p16InstPostProcess;
  1715. uYPlane = DC->PostFrame.X32_YPlane;
  1716. uUPlane = DC->PostFrame.X32_UPlane;
  1717. uVPlane = DC->PostFrame.X32_VPlane;
  1718. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1719. if (bRealDecompress)
  1720. {
  1721. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFrameCopy)
  1722. }
  1723. #endif // } DETAILED_DECODE_TIMINGS_ON
  1724. }
  1725. else
  1726. {
  1727. // Added checks for adjusting video effects. Since pFrame must be
  1728. // set to DC->p16InstPostProcess to call AdjustPels, the FrameCopy
  1729. // must be done.
  1730. if (!(DC->bUseBlockEdgeFilter || DC->bAdjustLuma || DC->bAdjustChroma))
  1731. {
  1732. // New color convertors do not destroy Y plane input and so
  1733. // we do not have to do a frame copy
  1734. pFrame = (U8 *)DC;
  1735. uYPlane = DC->DispFrame.X32_YPlane + Y_START;
  1736. uUPlane = DC->DispFrame.X32_UPlane + UV_START;
  1737. uVPlane = DC->DispFrame.X32_VPlane + UV_START;
  1738. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1739. if (bRealDecompress)
  1740. {
  1741. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFrameCopy)
  1742. }
  1743. #endif // } DETAILED_DECODE_TIMINGS_ON
  1744. }
  1745. else
  1746. {
  1747. // The block edge filtered frame can not be used as a reference
  1748. // and we need to make a copy of the frame before doing the
  1749. // block edge filtering.
  1750. // This is also true for adjusting pels.
  1751. FrameCopy (((HPBYTE) P32Inst) + DC->DispFrame.X32_YPlane + Y_START,
  1752. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_YPlane,
  1753. DC->uFrameHeight,
  1754. DC->uFrameWidth,
  1755. PITCH);
  1756. FrameCopy (((HPBYTE) P32Inst) + DC->DispFrame.X32_UPlane + UV_START,
  1757. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_UPlane,
  1758. DC->uFrameHeight/2,
  1759. DC->uFrameWidth/2,
  1760. PITCH);
  1761. FrameCopy (((HPBYTE) P32Inst) + DC->DispFrame.X32_VPlane + UV_START,
  1762. ((HPBYTE) DC->p16InstPostProcess) + DC->PostFrame.X32_VPlane,
  1763. DC->uFrameHeight/2,
  1764. DC->uFrameWidth/2,
  1765. PITCH);
  1766. pFrame = (U8 *)DC->p16InstPostProcess;
  1767. uYPlane = DC->PostFrame.X32_YPlane;
  1768. uUPlane = DC->PostFrame.X32_UPlane;
  1769. uVPlane = DC->PostFrame.X32_VPlane;
  1770. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1771. if (bRealDecompress)
  1772. {
  1773. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFrameCopy)
  1774. }
  1775. #endif // } DETAILED_DECODE_TIMINGS_ON
  1776. if (DC->bUseBlockEdgeFilter) {
  1777. // C version of block edge filter
  1778. // should this be added to the mirrored case?
  1779. // it should not be added to the b320x240 case
  1780. // since we want that to be as sharp as possible
  1781. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1782. if (bRealDecompress)
  1783. {
  1784. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1785. }
  1786. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1787. EdgeFilter((unsigned char *)(pFrame + uYPlane),
  1788. (unsigned char *)(pFrame + uUPlane),
  1789. (unsigned char *)(pFrame + uVPlane),
  1790. #ifndef NEW_BEF // { NEW_BEF
  1791. DC->uPQuant,
  1792. #endif // } NEW_BEF
  1793. DC->uFrameWidth,
  1794. DC->uFrameHeight,
  1795. PITCH);
  1796. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1797. if (bRealDecompress)
  1798. {
  1799. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uBEFTime)
  1800. }
  1801. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1802. }
  1803. }
  1804. }
  1805. } // end no mirroring case
  1806. #ifdef H263P
  1807. if (DC->bDeblockingFilter) {
  1808. // Restore post-process (i.e., outside of loop) block edge filter flag
  1809. DC->bUseBlockEdgeFilter = bTmpPostProcessBEF;
  1810. }
  1811. #endif
  1812. }
  1813. else // YUV12
  1814. {
  1815. const U32 uHeight = DC->uFrameHeight;
  1816. const U32 uWidth = DC->uFrameWidth;
  1817. const U32 uYPlaneSize = uHeight*uWidth;
  1818. uYPitch = uWidth;
  1819. uUVPitch = uWidth >> 1;
  1820. if(bMirror) // mirroring and YUV12
  1821. {
  1822. HPBYTE pSource, pDestination;
  1823. pFrame = DC->p16InstPostProcess;
  1824. uYPlane = DC->PostFrame.X32_YPlane;
  1825. uUPlane = uYPlane + uYPlaneSize;
  1826. uVPlane = uUPlane + (uYPlaneSize>>2);
  1827. pSource = (HPBYTE)lpicDecEx->lpSrc;
  1828. pDestination = (HPBYTE)(DC->p16InstPostProcess + (DWORD)DC->PostFrame.X32_YPlane);
  1829. FrameMirror (pSource, pDestination, uHeight, uWidth, uWidth);
  1830. pSource += uYPlaneSize;
  1831. pDestination += uYPlaneSize;
  1832. FrameMirror (pSource, pDestination, uHeight>>1, uWidth>>1, uWidth>>1);
  1833. pSource += (uYPlaneSize>>2);
  1834. pDestination += (uYPlaneSize>>2);
  1835. FrameMirror (pSource, pDestination, uHeight>>1, uWidth>>1, uWidth>>1);
  1836. }
  1837. else // no mirroring
  1838. {
  1839. HPBYTE pSource, pDestination;
  1840. if (DC->bAdjustLuma || DC->bAdjustChroma) {
  1841. pFrame = DC->p16InstPostProcess;
  1842. uYPlane = DC->PostFrame.X32_YPlane;
  1843. uUPlane = uYPlane + uYPlaneSize;
  1844. uVPlane = uUPlane + (uYPlaneSize>>2);
  1845. pSource = (HPBYTE)lpicDecEx->lpSrc;
  1846. pDestination = (HPBYTE)(DC->p16InstPostProcess + (DWORD)DC->PostFrame.X32_YPlane);
  1847. FrameCopy (pSource, pDestination, uHeight, uWidth, uWidth);
  1848. pSource += uYPlaneSize;
  1849. pDestination += uYPlaneSize;
  1850. FrameCopy (pSource, pDestination, uHeight>>1, uWidth>>1, uWidth>>1);
  1851. pSource += (uYPlaneSize>>2);
  1852. pDestination += (uYPlaneSize>>2);
  1853. FrameCopy (pSource, pDestination, uHeight>>1, uWidth>>1, uWidth>>1);
  1854. } else {
  1855. // Copy the V plane from the source buffer into DC because the
  1856. // input buffer may end at the end of a section. The assembler versions
  1857. // of the color convertors are optimized to read ahead, in which case
  1858. // a GPF occurs if the buffer is at the end of a section.
  1859. pFrame = (HPBYTE)lpicDecEx->lpSrc;
  1860. uYPlane = 0;
  1861. uUPlane = uYPlane + uYPlaneSize;
  1862. uVPlane = uUPlane + (uYPlaneSize>>2);
  1863. pSource = (HPBYTE)lpicDecEx->lpSrc + uYPlane + uYPlaneSize + (uYPlaneSize >> 2);
  1864. pDestination = (HPBYTE)DC->p16InstPostProcess + DC->PostFrame.X32_YPlane +
  1865. uYPlaneSize + (uYPlaneSize >> 2);
  1866. FrameCopy (pSource, pDestination, uHeight>>1, uWidth>>1, uWidth>>1);
  1867. uVPlane += (pDestination - pSource);
  1868. }
  1869. }
  1870. } // else YUV12
  1871. // Check if we are to do aspect ration correction on this frame.
  1872. if (DC->bForceOnAspectRatioCorrection || lpInst->bCorrectAspectRatio) {
  1873. bShapingFlag = 1;
  1874. uNewFrameHeight = (DC->uFrameHeight * 11 / 12);
  1875. } else {
  1876. bShapingFlag = 0;
  1877. uNewFrameHeight = DC->uFrameHeight;
  1878. }
  1879. // Do the PEL color adjustments if necessary.
  1880. if(DC->bAdjustLuma)
  1881. {
  1882. // width is rounded up to a multiple of 8
  1883. AdjustPels(pFrame,
  1884. uYPlane,
  1885. DC->uFrameWidth,
  1886. uYPitch,
  1887. DC->uFrameHeight,
  1888. (U32) DC->X16_LumaAdjustment);
  1889. }
  1890. if(DC->bAdjustChroma)
  1891. {
  1892. // width = Y-Width / 4 and then rounded up to a multiple of 8
  1893. AdjustPels(pFrame,
  1894. uUPlane,
  1895. (DC->uFrameWidth >> 1),
  1896. uUVPitch,
  1897. (DC->uFrameHeight >> 1),
  1898. (U32) DC->X16_ChromaAdjustment);
  1899. AdjustPels(pFrame,
  1900. uVPlane,
  1901. (DC->uFrameWidth >> 1),
  1902. uUVPitch,
  1903. (DC->uFrameHeight >> 1),
  1904. (U32) DC->X16_ChromaAdjustment);
  1905. }
  1906. // Determine parameters need for color conversion.
  1907. if(lpicDecEx->lpbiDst->biCompression == FOURCC_YUY2) /* output pitch, offset */
  1908. {
  1909. intPitch = (lpicDecEx->lpbiDst->biBitCount >> 3) * abs ((int)(lpicDecEx->lpbiDst->biWidth));
  1910. lOutput = 0; /* for YUY2 format */
  1911. uNewOffsetToLine0 = DC->CCOffsetToLine0;
  1912. bShapingFlag=FALSE;
  1913. }
  1914. else if ((lpicDecEx->lpbiDst->biCompression == FOURCC_YUV12) || (lpicDecEx->lpbiDst->biCompression == FOURCC_IYUV)) /* output pitch, offset */
  1915. {
  1916. intPitch = 0xdeadbeef; // should not be used
  1917. lOutput = 0; /* for YUV format */
  1918. uNewOffsetToLine0 = DC->CCOffsetToLine0;
  1919. bShapingFlag=FALSE;
  1920. }
  1921. else // not YUY2
  1922. {
  1923. // this call also sets intPitch
  1924. lOutput = DibXY(lpicDecEx, &intPitch, lpInst->YScale);
  1925. if (DC->uIs320x240)
  1926. uNewOffsetToLine0 = DC->CCOffset320x240;
  1927. else
  1928. uNewOffsetToLine0 = DC->CCOffsetToLine0;
  1929. if (!bIsDCI)
  1930. {
  1931. uNewOffsetToLine0 +=
  1932. ( (U32)DC->uFrameHeight - (U32)uNewFrameHeight ) * (U32)intPitch;
  1933. if(lpInst->YScale == 2)
  1934. uNewOffsetToLine0 +=
  1935. ( (U32)DC->uFrameHeight - (U32)uNewFrameHeight ) * (U32)intPitch;
  1936. } // end if (!bIsDCI)
  1937. } // end if (YUY2) ... else ...
  1938. // Call the H26x color convertors
  1939. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1940. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1941. #endif // } DETAILED_DECODE_TIMINGS_ON
  1942. #ifdef USE_MMX // { USE_MMX
  1943. ColorConvertorCatalog[DC->ColorConvertor].ColorConvertor[DC->bMMXDecoder ? MMX_CC : PENTIUM_CC](
  1944. #else // }{ USE_MMX
  1945. ColorConvertorCatalog[DC->ColorConvertor].ColorConvertor[PENTIUM_CC](
  1946. #endif // } USE_MMX
  1947. (LPSTR) pFrame+uYPlane, // Y plane
  1948. (LPSTR) pFrame+uVPlane, // V plane
  1949. (LPSTR) pFrame+uUPlane, // U plane
  1950. #ifdef H263P
  1951. // The actual frame dimensions are needed for the color conversion
  1952. (UN) DC->uActualFrameWidth,
  1953. (UN) DC->uActualFrameHeight,
  1954. #else
  1955. (UN) DC->uFrameWidth,
  1956. (UN) DC->uFrameHeight,
  1957. #endif
  1958. (UN) uYPitch,
  1959. (UN) uUVPitch,
  1960. (UN) (bShapingFlag ? 12 : 9999), // Aspect Adjustment Counter
  1961. (LPSTR) lpicDecEx->lpDst, // Color Converted Frame
  1962. (U32) lOutput, // DCI offset
  1963. (U32) uNewOffsetToLine0, // Color converter offset to line 0
  1964. (int) intPitch, // Color converter pitch
  1965. DC->ColorConvertor);
  1966. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  1967. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uOutputCC);
  1968. #endif // } DETAILED_DECODE_TIMINGS_ON
  1969. // check for 320x240 still
  1970. if (DC->uIs320x240) {
  1971. // restore frame size for next frame
  1972. DC->uFrameWidth = uSaveWidth;
  1973. DC->uFrameHeight = uSaveHeight;
  1974. }
  1975. iReturn = ICERR_OK;
  1976. done:
  1977. #ifdef USE_MMX // { USE_MMX
  1978. if(NULL != DC)
  1979. {
  1980. if (DC->bMMXDecoder)
  1981. {
  1982. __asm {
  1983. _emit 0x0f
  1984. _emit 0x77 // emms
  1985. }
  1986. }
  1987. }
  1988. #endif // } USE_MMX
  1989. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  1990. if (bRealDecompress)
  1991. {
  1992. TIMER_STOP(bTimingThisFrame,uStartLow,uStartHigh,uDecodeTime);
  1993. if (bTimingThisFrame)
  1994. {
  1995. // Update the decompression timings counter
  1996. #pragma message ("Current decode timing computations assume P5/90Mhz")
  1997. UPDATE_COUNTER(g_pctrDecompressionTimePerFrame, (uDecodeTime + 45000UL) / 90000UL);
  1998. UPDATE_COUNTER(g_pctrBEFTimePerFrame, (uBEFTime + 45000UL) / 90000UL);
  1999. DEBUGMSG(ZONE_DECODE_DETAILS, ("%s: Decompression time: %ld\r\n", _fx_, (uDecodeTime + 45000UL) / 90000UL));
  2000. DEBUGMSG(ZONE_DECODE_DETAILS, ("%s: Block Edge Filtering time: %ld\r\n", _fx_, (uBEFTime + 45000UL) / 90000UL));
  2001. }
  2002. }
  2003. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2004. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  2005. if (bRealDecompress)
  2006. {
  2007. if (bTimingThisFrame)
  2008. {
  2009. pDecTimingInfo = DC->pDecTimingInfo + DC->uStatFrameCount;
  2010. pDecTimingInfo->uDecodeFrame = uDecodeTime;
  2011. pDecTimingInfo->uBEF = uBEFTime;
  2012. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  2013. pDecTimingInfo->uHeaders = uHeaders;
  2014. pDecTimingInfo->uMemcpy = uMemcpy;
  2015. pDecTimingInfo->uFrameCopy = uFrameCopy;
  2016. pDecTimingInfo->uIDCTandMC = uIDCTandMC;
  2017. pDecTimingInfo->uOutputCC = uOutputCC;
  2018. pDecTimingInfo->uDecIDCTCoeffs = uDecIDCTCoeffs;
  2019. #endif // } DETAILED_DECODE_TIMINGS_ON
  2020. DC->uStatFrameCount++;
  2021. }
  2022. }
  2023. #endif // } LOG_DECODE_TIMINGS_ON
  2024. return iReturn;
  2025. }
  2026. /************************************************************************
  2027. * H263TermDecoderInstance
  2028. * This function frees the space allocated for an instance of the H263
  2029. * decoder.
  2030. ************************************************************************/
  2031. LRESULT H263TermDecoderInstance(
  2032. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2033. LPDECINST lpInst,
  2034. BOOL bRealDecompress)
  2035. #else // }{ #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2036. LPDECINST lpInst)
  2037. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2038. {
  2039. LRESULT iReturn=ICERR_OK;
  2040. T_H263DecoderCatalog * DC;
  2041. FX_ENTRY("H263TermDecoderInstance");
  2042. if(IsBadWritePtr((LPVOID)lpInst, sizeof(DECINSTINFO)))
  2043. {
  2044. ERRORMESSAGE(("%s: Bad input parameter!\r\n", _fx_));
  2045. iReturn = ICERR_BADPARAM;
  2046. }
  2047. if(lpInst->Initialized == FALSE)
  2048. {
  2049. ERRORMESSAGE(("%s: Uninitialized instance!\r\n", _fx_));
  2050. return(ICERR_OK);
  2051. }
  2052. lpInst->Initialized = FALSE;
  2053. DC = (T_H263DecoderCatalog *) ((((U32) lpInst->pDecoderInst) + 31) & ~0x1F);
  2054. if (DC->_p16InstPostProcess != NULL)
  2055. {
  2056. HeapFree(GetProcessHeap(), 0, DC->_p16InstPostProcess);
  2057. #ifdef TRACK_ALLOCATIONS
  2058. // Track memory allocation
  2059. RemoveName((unsigned int)DC->_p16InstPostProcess);
  2060. #endif
  2061. // PhilF: Also freed in H263TerminateDecoderInstance! For now set to NULL to avoid second HeapFree.
  2062. // Investigate reason for 2nd call later...
  2063. DC->_p16InstPostProcess = NULL;
  2064. }
  2065. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  2066. if (bRealDecompress && DC->X32_DecTimingInfo)
  2067. {
  2068. DC->pDecTimingInfo = (DEC_TIMING_INFO FAR *)( ((U8 FAR *)DC) + DC->X32_DecTimingInfo );
  2069. OutputDecodeTimingStatistics("c:\\decode.txt", DC->pDecTimingInfo, DC->uStatFrameCount);
  2070. }
  2071. #endif // } LOG_DECODE_TIMINGS_ON
  2072. HeapFree(GetProcessHeap(), 0, lpInst->pDecoderInst);
  2073. #ifdef TRACK_ALLOCATIONS
  2074. // Track memory allocation
  2075. RemoveName((unsigned int)lpInst->pDecoderInst);
  2076. #endif
  2077. return iReturn;
  2078. }
  2079. /***********************************************************************
  2080. * Description:
  2081. * This routine parses the bit-stream and initializes two major streams:
  2082. * 1) pN: no of coefficients in each of the block (biased by 65 for INTRA)
  2083. * 2) pRun_INVERSE_Q: de-quantized coefficient stream for the frame;
  2084. * MMX stream is scaled because we use scaled IDCT.
  2085. * Other information (e.g. MVs) is kept in decoder catalog, block action
  2086. * stream, and MB infor stream.
  2087. * Parameters:
  2088. * DC: Decoder catalog ptr
  2089. * fpBlockAction: block action stream ptr
  2090. * fpMBInfo: Macroblock info ptr
  2091. * fpbsState: bit-stream state pointer
  2092. * fpu8MaxPtr: sentinel value to check for bit-stream overruns
  2093. * pN: stream of no. of coeffs (biased by block type) for each block
  2094. * pRun_INVERSE_Q:stream of de-quantized (and scaled if using MMX) coefficients
  2095. * iNumberOfGOBs: no. of GOBs in the frame
  2096. * iNumberOfMBs: no. of MBs in a GOB in the frame
  2097. * iGOB_start:
  2098. * iMB_start:
  2099. * Note:
  2100. ***********************************************************************/
  2101. #pragma code_seg("IACODE1")
  2102. static LRESULT IAPass1ProcessFrame(
  2103. T_H263DecoderCatalog *DC,
  2104. T_BlkAction *fpBlockAction,
  2105. T_MBInfo *fpMBInfo,
  2106. BITSTREAM_STATE *fpbsState,
  2107. U8 *fpu8MaxPtr,
  2108. U32 *pN,
  2109. T_IQ_INDEX *pRUN_INVERSE_Q,
  2110. const I32 iNumberOfGOBs,
  2111. const I32 iNumberOfMBs,
  2112. const I32 iGOB_start,
  2113. const I32 iMB_start)
  2114. {
  2115. I32 g, m, gg, mm, iReturn, iBlockNumber = 0 ;
  2116. #if 1
  2117. I32 mb_start = iMB_start;
  2118. I32 old_g, old_m, b_skip;
  2119. U32 *pNnew;
  2120. I8 p8MVs[4]={0,0,0,0};
  2121. FX_ENTRY("IAPass1ProcessFrame");
  2122. // In case of H.263, iGOB_start will be 1; H.263RTP may have value
  2123. // larger than 1
  2124. for (g = 1; g < iGOB_start; g++, fpBlockAction += iNumberOfMBs*6)
  2125. H263InitializeGOBBlockActionStream(DC, g, fpBlockAction);
  2126. for (g = iGOB_start; g <= iNumberOfGOBs; g++)
  2127. {
  2128. iReturn = H263DecodeGOBHeader(DC, fpbsState, g);
  2129. if (iReturn != ICERR_OK)
  2130. {
  2131. ERRORMESSAGE(("%s: Error reading GOB header!\r\n", _fx_));
  2132. goto error;
  2133. }
  2134. if (g != 1) g = DC->uGroupNumber + 1;
  2135. fpBlockAction = (T_BlkAction FAR *)((U8 *)DC + DC->X16_BlkActionStream);
  2136. fpBlockAction += (g - 1)* iNumberOfMBs*6;
  2137. H263InitializeGOBBlockActionStream(DC, g, fpBlockAction);
  2138. // re-sync uBlockNum fpBlockAction, fpMBInfo at this point
  2139. iBlockNumber = (g - 1)* iNumberOfMBs*6+(mb_start-1)*6;
  2140. fpBlockAction = (T_BlkAction FAR *)((U8 *)DC + DC->X16_BlkActionStream);
  2141. fpMBInfo = (T_MBInfo FAR *) ((U8 *)DC + DC->X32_uMBInfoStream);
  2142. fpBlockAction += iBlockNumber;
  2143. fpMBInfo += iBlockNumber/6;
  2144. if (DC->bPBFrame)
  2145. pNnew = (U32 *)((U8 *)DC + DC->X32_pN) + iBlockNumber*2;
  2146. else
  2147. pNnew = (U32 *)((U8 *)DC + DC->X32_pN) + iBlockNumber;
  2148. while (pN < pNnew ) *pN++ = 0;
  2149. // For each MB do ...
  2150. for (m = mb_start; m <= iNumberOfMBs; m++, iBlockNumber += 6, fpBlockAction += 6, fpMBInfo++)
  2151. {
  2152. if (mb_start != 1) mb_start = 1; //use it only once ?
  2153. iReturn = H263DecodeMBHeader(DC, fpbsState, &pN, fpMBInfo); // NEW - added pN
  2154. if (iReturn == PACKET_FAULT)
  2155. {
  2156. ERRORMESSAGE(("%s: H263DecodeMBHeader() failed!\r\n", _fx_));
  2157. old_g = g;
  2158. old_m = m;
  2159. //Find the next good packet and find GOB and MB lost
  2160. iReturn = RtpH263FindNextPacket(DC, fpbsState, &pN,
  2161. &DC->uPQuant,(int *)&m, (int *)&g,
  2162. p8MVs);
  2163. if (iReturn == NEXT_MODE_A)
  2164. {
  2165. ERRORMESSAGE(("%s: Next packet in MODE A\r\n", _fx_));
  2166. MVAdjustment(fpBlockAction, iBlockNumber, old_g-1, old_m-1, g, m,iNumberOfMBs); //Chad,7/22/96
  2167. break;
  2168. }
  2169. else if ((iReturn == NEXT_MODE_B) ||(iReturn == NEXT_MODE_C) )
  2170. {//lost multiple of MBs, could belong to more than one GOB
  2171. if (iReturn == NEXT_MODE_B)
  2172. {
  2173. ERRORMESSAGE(("%s: Next packet in MODE B\r\n", _fx_));
  2174. b_skip = ((g - old_g+1)* iNumberOfMBs + m - old_m + 1)*6;
  2175. for (int k = 0; k < b_skip; k++) *pN++ = 0;
  2176. }
  2177. else
  2178. {
  2179. ERRORMESSAGE(("%s: Next packet in MODE C\r\n", _fx_));
  2180. b_skip = ((g - old_g+1)* iNumberOfMBs + m - old_m + 1)*6*2;
  2181. for (int k = 0; k < b_skip; k++) *pN++ = 0;
  2182. b_skip = b_skip /2;
  2183. }
  2184. for (int k=0;k< b_skip /6;k++)
  2185. {
  2186. fpMBInfo->i8MVDBx2=0;
  2187. fpMBInfo->i8MVDBy2=0;
  2188. fpMBInfo->i8MBType =0;
  2189. fpMBInfo++;
  2190. }
  2191. fpMBInfo--;
  2192. b_skip -= 6; //this is a tricky one since the parameter
  2193. //below will be adjust again later
  2194. //Chad, 8/28/96
  2195. fpBlockAction += b_skip;
  2196. iBlockNumber += b_skip;
  2197. g++; //because g start with 1 instead of 0 as specified by H.263
  2198. for (k=0;k<6;k++)
  2199. {
  2200. fpBlockAction[k].i8MVx2 = p8MVs[0];
  2201. fpBlockAction[k].i8MVy2 = p8MVs[1];
  2202. }
  2203. }
  2204. else //Added by Chad.
  2205. if (iReturn == NEXT_MODE_LAST)
  2206. {
  2207. int ii, jj, kk; //last packet found
  2208. //set all the rest of MB and GOB to NOT CODED.
  2209. ERRORMESSAGE(("%s: Last packet lost\r\n", _fx_));
  2210. for ( ii = m;ii <= iNumberOfMBs; ii++)
  2211. for (kk = 0; kk < 6; kk++)
  2212. *pN++ = 0;
  2213. for ( jj = g; jj <= iNumberOfGOBs; jj++)
  2214. for (ii = 0; ii <= iNumberOfMBs; ii++)
  2215. for (kk = 0; kk<6; kk++)
  2216. *pN++ = 0;
  2217. m = iNumberOfMBs;
  2218. g = iNumberOfMBs;
  2219. }
  2220. DC->bCoded = FALSE;
  2221. }
  2222. else if (iReturn != ICERR_OK)
  2223. {
  2224. ERRORMESSAGE(("%s: Error reading MB header!\r\n", _fx_));
  2225. goto error;
  2226. }
  2227. #ifdef NEW_BEF // { NEW_BEF
  2228. gg = (g - 1);
  2229. mm = (m - 1);
  2230. #else // }{ NEW_BEF
  2231. gg = (g-1)<<1;
  2232. mm = (m-1)<<1;
  2233. #endif // } NEW_BEF
  2234. if (DC->bCoded)
  2235. {
  2236. // coded_map is used by the block edge filter to indicate
  2237. // which blocks are coded, and which are not coded.
  2238. #ifdef NEW_BEF // { NEW_BEF
  2239. coded_map[gg+1][mm+1] = 1;
  2240. QP_map[gg][mm] = (char)DC->uGQuant;
  2241. #else // }{ NEW_BEF
  2242. coded_map[gg] [mm] = 1;
  2243. coded_map[gg+1][mm] = 1;
  2244. coded_map[gg] [mm+1] = 1;
  2245. coded_map[gg+1][mm+1] = 1;
  2246. #endif // } NEW_BEF
  2247. // decode and inverse quantize the transform coefficients
  2248. iReturn = H263DecodeIDCTCoeffs(DC,
  2249. fpBlockAction,
  2250. iBlockNumber,
  2251. fpbsState,
  2252. fpu8MaxPtr,
  2253. &pN,
  2254. &pRUN_INVERSE_Q);
  2255. if (iReturn != ICERR_OK) {
  2256. ERRORMESSAGE(("%s: Error parsing MB data!\r\n", _fx_));
  2257. goto error;
  2258. }
  2259. } // end if DC->bCoded
  2260. else
  2261. {
  2262. #ifdef NEW_BEF // { NEW_BEF
  2263. coded_map[gg+1][mm+1] = 0;
  2264. #else // }{ NEW_BEF
  2265. coded_map[gg] [mm] = 0;
  2266. coded_map[gg+1][mm] = 0;
  2267. coded_map[gg] [mm+1] = 0;
  2268. coded_map[gg+1][mm+1] = 0;
  2269. #endif // } NEW_BEF
  2270. }
  2271. } // end for each MB
  2272. /* allow the pointer to address up to four beyond the end - reading
  2273. * by DWORD using postincrement.
  2274. */
  2275. if (fpbsState->fpu8 > fpu8MaxPtr+4)
  2276. goto error;
  2277. // The test matrix includes the debug version of the driver. The
  2278. // following assertion creates a problem when testing with VideoPhone
  2279. // and so please do not check-in a version with the assertion
  2280. // uncommented.
  2281. // ASSERT(fpbsState->fpu8 <= fpu8MaxPtr+4);
  2282. } // End for each GOB
  2283. DC->iVerifiedBsExt=FALSE;
  2284. #else
  2285. //old code
  2286. for (g = 1; g <= iNumberOfGOBs; g++)
  2287. {
  2288. iReturn = H263DecodeGOBHeader(DC, fpbsState, g);
  2289. if (iReturn != ICERR_OK) {
  2290. ERRORMESSAGE(("%s: Error reading GOB header!\r\n", _fx_));
  2291. goto error;
  2292. }
  2293. H263InitializeGOBBlockActionStream(DC, g, fpBlockAction);
  2294. /* For each MB do ...
  2295. */
  2296. for (m = 1; m <= iNumberOfMBs;
  2297. m++, iBlockNumber+=6, fpBlockAction += 6, fpMBInfo++)
  2298. {
  2299. iReturn = H263DecodeMBHeader(DC, fpbsState, &pN, fpMBInfo);
  2300. if (iReturn != ICERR_OK) {
  2301. ERRORMESSAGE(("%s: Error reading MB header!\r\n", _fx_));
  2302. goto error;
  2303. }
  2304. if (DC->bCoded) {
  2305. // decode and inverse quantize the transform coefficients
  2306. iReturn = H263DecodeIDCTCoeffs(DC,
  2307. fpBlockAction,
  2308. iBlockNumber,
  2309. fpbsState,
  2310. fpu8MaxPtr,
  2311. &pN,
  2312. &pRUN_INVERSE_Q);
  2313. if (iReturn != ICERR_OK)
  2314. {
  2315. ERRORMESSAGE(("%s: Error parsing MB data!\r\n", _fx_));
  2316. goto error;
  2317. }
  2318. } // end if DC->bCoded
  2319. } // end for each MB
  2320. /* allow the pointer to address up to four beyond the end - reading
  2321. * by DWORD using postincrement.
  2322. */
  2323. ASSERT(fpbsState->fpu8 <= fpu8MaxPtr+4);
  2324. } // End for each GOB
  2325. #endif
  2326. return ICERR_OK;
  2327. error:
  2328. return ICERR_ERROR;
  2329. }
  2330. #pragma code_seg()
  2331. /***********************************************************************
  2332. * Description:
  2333. * This routines does IDCT and motion compensation.
  2334. * Parameters:
  2335. * DC: Decoder catalog ptr
  2336. * fpBlockAction: block action stream ptr
  2337. * fpMBInfo: Macroblock info ptr
  2338. * pN: stream of no. of coeffs (biased by block type) for each block
  2339. * pRun_INVERSE_Q:stream of de-quantized (and scaled if using MMX) coefficients
  2340. * iNumberOfGOBs: no. of GOBs in the frame
  2341. * iNumberOfMBs: no. of MBs in a GOB in the frame
  2342. * Note:
  2343. ***********************************************************************/
  2344. #pragma code_seg("IACODE2")
  2345. static void IAPass2ProcessFrame(
  2346. T_H263DecoderCatalog *DC,
  2347. T_BlkAction *fpBlockAction,
  2348. T_MBInfo *fpMBInfo,
  2349. U32 *pN,
  2350. T_IQ_INDEX *pRUN_INVERSE_Q,
  2351. const I32 iNumberOfGOBs,
  2352. const I32 iNumberOfMBs
  2353. )
  2354. {
  2355. I32 g, m, b, uBlockNumber = 0, iEdgeFlag=0;
  2356. U32 pRef[6];
  2357. // for each GOB do
  2358. for (g = 1 ; g <= iNumberOfGOBs; g++)
  2359. {
  2360. // for each MB do
  2361. for (m = 1; m <= iNumberOfMBs; m++, fpBlockAction+=6, fpMBInfo++)
  2362. {
  2363. // Motion Vectors need to be clipped if they point outside the
  2364. // 16 pels wide edge
  2365. if (DC->bUnrestrictedMotionVectors)
  2366. {
  2367. iEdgeFlag = 0;
  2368. if (m == 1)
  2369. iEdgeFlag |= LEFT_EDGE;
  2370. if (m == DC->iNumberOfMBsPerGOB)
  2371. iEdgeFlag |= RIGHT_EDGE;
  2372. if (g == 1)
  2373. iEdgeFlag |= TOP_EDGE;
  2374. if (g == iNumberOfGOBsBySourceFormat[DC->uSrcFormat])
  2375. iEdgeFlag |= BOTTOM_EDGE;
  2376. }
  2377. // for each block do
  2378. for (b = 0; b < 6; b++)
  2379. { // AP-NEW
  2380. // do inverse transform & motion compensation for the block
  2381. H263IDCTandMC(DC, fpBlockAction, b, m, g, pN, pRUN_INVERSE_Q,
  2382. fpMBInfo, iEdgeFlag); // AP-NEW
  2383. // Adjust pointers for next block
  2384. if ( *pN >= 65 )
  2385. pRUN_INVERSE_Q += *pN - 65;
  2386. else
  2387. pRUN_INVERSE_Q += *pN;
  2388. pN++;
  2389. } // end for each block
  2390. // if this is a PB Frame
  2391. if (DC->bPBFrame)
  2392. {
  2393. // Compute the B Frame motion vectors
  2394. H263BBlockPrediction(DC, fpBlockAction, pRef, fpMBInfo,
  2395. iEdgeFlag); // AP-NEW
  2396. // For each B block
  2397. for (b = 0; b < 6; b++)
  2398. {
  2399. // perform inverse transform & bi-directional motion
  2400. // compensation
  2401. H263BFrameIDCTandBiMC(DC, fpBlockAction, b, pN,
  2402. pRUN_INVERSE_Q, pRef);
  2403. // Adjust pointers for next block
  2404. pRUN_INVERSE_Q += *pN;
  2405. pN++;
  2406. } // end for each B block
  2407. } // end if PB Frame
  2408. } // end for each MB
  2409. } // End for each GOB
  2410. }
  2411. #pragma code_seg()
  2412. /****************************************************************************
  2413. * DibXY
  2414. * This function is used to map color converted output to the screen.
  2415. * note: this function came from the H261 code base.
  2416. ****************************************************************************/
  2417. static long DibXY(ICDECOMPRESSEX FAR *lpicDecEx, LPINT lpiPitch, UINT yScale)
  2418. {
  2419. int iPitch; /* width of DIB */
  2420. long lOffset = 0;
  2421. LPBITMAPINFOHEADER lpbi = lpicDecEx->lpbiDst;
  2422. iPitch = ( ( (abs((int)lpbi->biWidth) * (int)lpbi->biBitCount) >> 3) + 3) & ~3;
  2423. if(lpicDecEx->xDst > 0) /* go to proper X position */
  2424. lOffset += ((long)lpicDecEx->xDst * (long)lpbi->biBitCount) >> 3;
  2425. if(lpbi->biHeight * lpicDecEx->dxSrc < 0) { /* DIB is bottom to top */
  2426. lOffset += (long) abs((int)lpbi->biWidth) *
  2427. (long) abs((int)lpbi->biHeight) *
  2428. ((long) lpbi->biBitCount >> 3) -
  2429. (long) iPitch;
  2430. /************************************************************************
  2431. * This next line is used to subtract the amount that Brian added
  2432. * to CCOffsetToLine0 in COLOR.C during initialization. This is
  2433. * needed because, for DCI, the pitch he used is incorrect.
  2434. ***********************************************************************/
  2435. lOffset -= ((long) yScale * (long) lpicDecEx->dySrc - 1) *
  2436. (long) lpicDecEx->dxDst * ((long) lpbi->biBitCount >> 3);
  2437. iPitch *= -1;
  2438. }
  2439. if(lpicDecEx->yDst > 0) /* go to proper Y position */
  2440. lOffset += ((long)lpicDecEx->yDst * (long)iPitch);
  2441. if(lpicDecEx->dxSrc > 0) {
  2442. lOffset += ((long)lpicDecEx->dyDst * (long)iPitch) - (long)iPitch;
  2443. iPitch *= -1;
  2444. }
  2445. if( (lpicDecEx->dxDst == 0) && (lpicDecEx->dyDst == 0) )
  2446. *lpiPitch = -iPitch;
  2447. else
  2448. *lpiPitch = iPitch;
  2449. return(lOffset);
  2450. }
  2451. /************************************************************************
  2452. * GetDecoderOptions:
  2453. * Get the options, saving them in the catalog
  2454. ***********************************************************************/
  2455. static void GetDecoderOptions(
  2456. T_H263DecoderCatalog * DC)
  2457. {
  2458. /* Default Options
  2459. */
  2460. #ifdef NO_BEF // { NO_BEF
  2461. DC->bUseBlockEdgeFilter = 0;
  2462. #else // }{ NO_BEF
  2463. DC->bUseBlockEdgeFilter = 1;
  2464. #endif // } NO_BEF
  2465. DC->bForceOnAspectRatioCorrection = 0;
  2466. #ifdef USE_MMX // { USE_MMX
  2467. DC->bMMXDecoder = MMxVersion;
  2468. #endif // } USE_MMX
  2469. FX_ENTRY("GetDecoderOptions");
  2470. /* Can only use force aspect ratio correction on if SQCIF, QCIF, or CIF
  2471. */
  2472. if (DC->bForceOnAspectRatioCorrection)
  2473. {
  2474. if (! ( ((DC->uFrameWidth == 128) && (DC->uFrameHeight == 96)) ||
  2475. ((DC->uFrameWidth == 176) && (DC->uFrameHeight == 144)) ||
  2476. ((DC->uFrameWidth == 352) && (DC->uFrameHeight == 288)) ) )
  2477. {
  2478. ERRORMESSAGE(("%s: Aspect ratio correction can not be forced on unless the dimensions are SQCIF, QCIF, or CIF!\r\n", _fx_));
  2479. DC->bForceOnAspectRatioCorrection = 0;
  2480. }
  2481. }
  2482. /* Display the options
  2483. */
  2484. if (DC->bUseBlockEdgeFilter)
  2485. {
  2486. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (BlockEdgeFilter) is ON\r\n", _fx_));
  2487. }
  2488. else
  2489. {
  2490. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (BlockEdgeFilter) is OFF\r\n", _fx_));
  2491. }
  2492. if (DC->bForceOnAspectRatioCorrection)
  2493. {
  2494. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (ForceOnAspectRatioCorrection) is ON\r\n", _fx_));
  2495. }
  2496. else
  2497. {
  2498. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (ForceOnAspectRatioCorrection) is OFF\r\n", _fx_));
  2499. }
  2500. #ifdef USE_MMX // { USE_MMX
  2501. if (DC->bMMXDecoder)
  2502. {
  2503. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (MMXDecoder) is ON\r\n", _fx_));
  2504. }
  2505. else
  2506. {
  2507. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (MMXDecoder) is OFF\r\n", _fx_));
  2508. }
  2509. #else // }{ USE_MMX
  2510. DEBUGMSG (ZONE_INIT, ("%s: Decoder option (MMXDecoder) is OFF\r\n", _fx_));
  2511. #endif // } USE_MMX
  2512. } /* end GetDecoderOptions() */
  2513. #if !defined(H263P)
  2514. #ifdef NEW_BEF // { NEW_BEF
  2515. /**********************************************************************
  2516. *
  2517. * Name: EdgeFilter
  2518. * Description: performs deblocking filtering on
  2519. * reconstructed frames
  2520. *
  2521. * Input: pointers to reconstructed frame and difference
  2522. * image
  2523. * Returns:
  2524. * Side effects:
  2525. *
  2526. * Date: 951129 Author: Gisle.Bjontegaard@fou.telenor.no
  2527. * Karl.Lillevold@nta.no
  2528. * Modified for annex J in H.263+: 961120 Karl O. Lillevold
  2529. *
  2530. ***********************************************************************/
  2531. static void EdgeFilter(unsigned char *lum,
  2532. unsigned char *Cb,
  2533. unsigned char *Cr,
  2534. int width, int height, int pitch
  2535. )
  2536. {
  2537. /* Luma */
  2538. HorizEdgeFilter(lum, width, height, pitch, 0);
  2539. VertEdgeFilter (lum, width, height, pitch, 0);
  2540. /* Chroma */
  2541. HorizEdgeFilter(Cb, width>>1, height>>1, pitch, 1);
  2542. VertEdgeFilter (Cb, width>>1, height>>1, pitch, 1);
  2543. HorizEdgeFilter(Cr, width>>1, height>>1, pitch, 1);
  2544. VertEdgeFilter (Cr, width>>1, height>>1, pitch, 1);
  2545. return;
  2546. }
  2547. /***********************************************************************/
  2548. static void HorizEdgeFilter(unsigned char *rec,
  2549. int width, int height, int pitch, int chr)
  2550. {
  2551. int i,j,k;
  2552. int delta;
  2553. int mbc, mbr, do_filter;
  2554. unsigned char *r_2, *r_1, *r, *r1;
  2555. signed char *deltatab;
  2556. /* horizontal edges */
  2557. r = rec + 8*pitch;
  2558. r_2 = r - 2*pitch;
  2559. r_1 = r - pitch;
  2560. r1 = r + pitch;
  2561. for (j = 8; j < height; j += 8) {
  2562. for (i = 0; i < width; i += 8) {
  2563. if (!chr) {
  2564. mbr = (j >> 4);
  2565. mbc = (i >> 4);
  2566. }
  2567. else {
  2568. mbr = (j >> 3);
  2569. mbc = (i >> 3);
  2570. }
  2571. deltatab = dtab + 176 + 351 * (QP_map[mbr][mbc] - 1);
  2572. do_filter = coded_map[mbr+1][mbc+1] || coded_map[mbr][mbc+1];
  2573. if (do_filter) {
  2574. for (k = i; k < i+8; k++) {
  2575. delta = (int)deltatab[ (( (int)(*(r_2 + k) * 3) -
  2576. (int)(*(r_1 + k) * 8) +
  2577. (int)(*(r + k) * 8) -
  2578. (int)(*(r1 + k) * 3)) >>4)];
  2579. *(r + k) = ClampTbl[ (int)(*(r + k)) - delta + CLAMP_BIAS];
  2580. *(r_1 + k) = ClampTbl[ (int)(*(r_1 + k)) + delta + CLAMP_BIAS];
  2581. }
  2582. }
  2583. }
  2584. r += (pitch<<3);
  2585. r1 += (pitch<<3);
  2586. r_1 += (pitch<<3);
  2587. r_2 += (pitch<<3);
  2588. }
  2589. return;
  2590. }
  2591. /***********************************************************************/
  2592. static void VertEdgeFilter(unsigned char *rec,
  2593. int width, int height, int pitch, int chr)
  2594. {
  2595. int i,j,k;
  2596. int delta;
  2597. int mbc, mbr;
  2598. int do_filter;
  2599. signed char *deltatab;
  2600. unsigned char *r;
  2601. /* vertical edges */
  2602. for (i = 8; i < width; i += 8)
  2603. {
  2604. r = rec;
  2605. for (j = 0; j < height; j +=8)
  2606. {
  2607. if (!chr) {
  2608. mbr = (j >> 4);
  2609. mbc = (i >> 4);
  2610. }
  2611. else {
  2612. mbr = (j >> 3);
  2613. mbc = (i >> 3);
  2614. }
  2615. deltatab = dtab + 176 + 351 * (QP_map[mbr][mbc] - 1);
  2616. do_filter = coded_map[mbr+1][mbc+1] || coded_map[mbr+1][mbc];
  2617. if (do_filter) {
  2618. for (k = 0; k < 8; k++) {
  2619. delta = (int)deltatab[(( (int)(*(r + i-2 ) * 3) -
  2620. (int)(*(r + i-1 ) * 8) +
  2621. (int)(*(r + i ) * 8) -
  2622. (int)(*(r + i+1 ) * 3) ) >>4)];
  2623. *(r + i ) = ClampTbl[ (int)(*(r + i )) - delta + CLAMP_BIAS];
  2624. *(r + i-1 ) = ClampTbl[ (int)(*(r + i-1)) + delta + CLAMP_BIAS];
  2625. r += pitch;
  2626. }
  2627. }
  2628. else {
  2629. r += (pitch<<3);
  2630. }
  2631. }
  2632. }
  2633. return;
  2634. }
  2635. #define sign(a) ((a) < 0 ? -1 : 1)
  2636. static void InitEdgeFilterTab()
  2637. {
  2638. int i,QP;
  2639. for (QP = 1; QP <= 31; QP++) {
  2640. for (i = -176; i <= 175; i++) {
  2641. dtab[i+176 +(QP-1)*351] = sign(i) * (max(0,abs(i)-max(0,2*abs(i) - QP)));
  2642. }
  2643. }
  2644. }
  2645. #else // }{ NEW_BEF
  2646. /**********************************************************************
  2647. *
  2648. * Name: EdgeFilter
  2649. * Description: performs in the loop edge-filtering on
  2650. * reconstructed frames
  2651. *
  2652. * Input: pointers to reconstructed frame and difference
  2653. * image
  2654. * Returns:
  2655. * Side effects:
  2656. *
  2657. * Date: 951129 Author: Gisle.Bjontegaard@fou.telenor.no
  2658. * Karl.Lillevold@nta.no
  2659. *
  2660. ***********************************************************************/
  2661. void EdgeFilter(unsigned char *lum, unsigned char *Cb, unsigned char *Cr, int QP, int pels, int lines, int pitch)
  2662. {
  2663. int dtab[512];
  2664. int *deltatab;
  2665. int i;
  2666. deltatab = &dtab[0] + 256;
  2667. for (i=-256; i < 0; i++)
  2668. deltatab[i] = min(0,i-min(0,((i + (QP>>1))<<1)));
  2669. for (i=0; i < 256; i++)
  2670. deltatab[i] = max(0,i-max(0,((i - (QP>>1))<<1)));
  2671. /* Luma */
  2672. HorizEdgeFilter(lum, pels, lines, pitch, QP, 0, deltatab);
  2673. VertEdgeFilter (lum, pels, lines, pitch, QP, 0, deltatab);
  2674. /* Chroma */
  2675. HorizEdgeFilter(Cb, pels>>1, lines>>1, pitch, QP, 1, deltatab);
  2676. VertEdgeFilter (Cb, pels>>1, lines>>1, pitch, QP, 1, deltatab);
  2677. HorizEdgeFilter(Cr, pels>>1, lines>>1, pitch, QP, 1, deltatab);
  2678. VertEdgeFilter (Cr, pels>>1, lines>>1, pitch, QP, 1, deltatab);
  2679. /* that's it */
  2680. return;
  2681. }
  2682. /***********************************************************************/
  2683. void HorizEdgeFilter(unsigned char *rec, int width, int height, int pitch, int QP,
  2684. int chr, int *deltatab)
  2685. {
  2686. int i,j,k;
  2687. int delta;
  2688. int mbc, mbr, do_filter;
  2689. int coded1, coded2;
  2690. unsigned char *r_2, *r_1, *r, *r1;
  2691. /* horizontal edges */
  2692. r = rec + 8*pitch;
  2693. r_2 = r - 2*pitch;
  2694. r_1 = r - pitch;
  2695. r1 = r + pitch;
  2696. if (!chr) {
  2697. for (j = 8; j < height; j += 8) {
  2698. for (i = 0; i < width; i += 8) {
  2699. mbr = (j >> 3);
  2700. mbc = (i >> 3);
  2701. do_filter = coded_map[mbr][mbc] | coded_map[mbr-1][mbc];
  2702. if (do_filter) {
  2703. for (k = i; k < i+8; k++) {
  2704. delta = deltatab[ (( (int)(*(r_2 + k)) +
  2705. (int)(*(r_1 + k) * (-3)) +
  2706. (int)(*(r + k) * ( 3)) -
  2707. (int)(*(r1 + k) )) >>3)];
  2708. *(r + k) = ClampTbl[ (int)(*(r + k)) - delta + CLAMP_BIAS];
  2709. *(r_1 + k) = ClampTbl[ (int)(*(r_1 + k)) + delta + CLAMP_BIAS];
  2710. }
  2711. }
  2712. }
  2713. r += (pitch<<3);
  2714. r1 += (pitch<<3);
  2715. r_1 += (pitch<<3);
  2716. r_2 += (pitch<<3);
  2717. }
  2718. }
  2719. else { /* chr */
  2720. for (j = 8; j < height; j += 8) {
  2721. for (i = 0; i < width; i += 8) {
  2722. mbr = (j >> 3);
  2723. mbc = (i >> 3);
  2724. coded1 =
  2725. coded_map[2*mbr][2*mbc] |
  2726. coded_map[2*mbr][2*mbc+1] |
  2727. coded_map[2*mbr+1][2*mbc] |
  2728. coded_map[2*mbr+1][2*mbc+1];
  2729. coded2 =
  2730. coded_map[2*(mbr-1)][2*mbc] |
  2731. coded_map[2*(mbr-1)][2*mbc+1] |
  2732. coded_map[2*(mbr-1)+1][2*mbc] |
  2733. coded_map[2*(mbr-1)+1][2*mbc+1];
  2734. do_filter = coded1 | coded2;
  2735. if (do_filter) {
  2736. for (k = i; k < i+8; k++) {
  2737. delta = deltatab[ (( (int)(*(r_2 + k)) +
  2738. (int)(*(r_1 + k) * (-3)) +
  2739. (int)(*(r + k) * ( 3)) -
  2740. (int)(*(r1 + k) )) >>3)];
  2741. *(r + k) = ClampTbl[ (int)(*(r + k)) - delta + CLAMP_BIAS];
  2742. *(r_1 + k) = ClampTbl[ (int)(*(r_1 + k)) + delta + CLAMP_BIAS];
  2743. }
  2744. }
  2745. }
  2746. r += (pitch<<3);
  2747. r1 += (pitch<<3);
  2748. r_1 += (pitch<<3);
  2749. r_2 += (pitch<<3);
  2750. }
  2751. }
  2752. return;
  2753. }
  2754. /***********************************************************************/
  2755. void VertEdgeFilter(unsigned char *rec, int width, int height, int pitch, int QP,
  2756. int chr, int *deltatab)
  2757. {
  2758. int i,j,k;
  2759. int delta;
  2760. int mbc, mbr;
  2761. int do_filter, coded1, coded2;
  2762. unsigned char *r;
  2763. extern const U8 ClampTbl[CLAMP_BIAS+256+CLAMP_BIAS];
  2764. /* vertical edges */
  2765. for (i = 8; i < width; i += 8) {
  2766. r = rec;
  2767. for (j = 0; j < height; j +=8) {
  2768. mbr = (j >> 3);
  2769. mbc = (i >> 3);
  2770. if (!chr) {
  2771. do_filter = coded_map[mbr][mbc] | coded_map[mbr][mbc-1];
  2772. }
  2773. else {
  2774. coded1 =
  2775. coded_map[2*mbr][2*mbc] |
  2776. coded_map[2*mbr][2*mbc+1] |
  2777. coded_map[2*mbr+1][2*mbc] |
  2778. coded_map[2*mbr+1][2*mbc+1];
  2779. coded2 =
  2780. coded_map[2*mbr][2*(mbc-1)] |
  2781. coded_map[2*mbr][2*(mbc-1)+1] |
  2782. coded_map[2*mbr+1][2*(mbc-1)] |
  2783. coded_map[2*mbr+1][2*(mbc-1)+1];
  2784. do_filter = coded1 | coded2;
  2785. }
  2786. if (do_filter) {
  2787. for (k = 0; k < 8; k++) {
  2788. delta = deltatab[(( (int)(*(r + i-2 ) ) +
  2789. (int)(*(r + i-1 ) * (-3)) +
  2790. (int)(*(r + i ) * ( 3)) -
  2791. (int)(*(r + i+1 ) ) ) >>3)];
  2792. *(r + i ) = ClampTbl[ (int)(*(r + i )) - delta + CLAMP_BIAS];
  2793. *(r + i-1 ) = ClampTbl[ (int)(*(r + i-1)) + delta + CLAMP_BIAS];
  2794. r += pitch;
  2795. }
  2796. }
  2797. else {
  2798. r += (pitch<<3);
  2799. }
  2800. }
  2801. }
  2802. return;
  2803. }
  2804. #endif // } NEW_BEF
  2805. #endif
  2806. #ifdef LOG_DECODE_TIMINGS_ON // { LOG_DECODE_TIMINGS_ON
  2807. void OutputDecodeTimingStatistics( char * szFileName, DEC_TIMING_INFO * pDecTimingInfo, U32 uStatFrameCount)
  2808. {
  2809. FILE * pFile;
  2810. DEC_TIMING_INFO * pTempDecTimingInfo;
  2811. DEC_TIMING_INFO dtiTemp;
  2812. int i;
  2813. int iCount;
  2814. FX_ENTRY("OutputDecodeTimingStatistics")
  2815. pFile = fopen(szFileName, "a");
  2816. if (pFile == NULL)
  2817. {
  2818. ERRORMESSAGE("%s: Error opening decode stat file\r\n", _fx_));
  2819. goto done;
  2820. }
  2821. /* Output the detail information
  2822. */
  2823. fprintf(pFile,"\nDetail Timing Information\n");
  2824. // for ( i = 0, pTempDecTimingInfo = pDecTimingInfo ; i < uStatFrameCount ; i++, pTempDecTimingInfo++ )
  2825. for ( i = 0, pTempDecTimingInfo = pDecTimingInfo ; i < DEC_TIMING_INFO_FRAME_COUNT ; i++, pTempDecTimingInfo++ )
  2826. {
  2827. if (pTempDecTimingInfo->uDecodeFrame != 0)
  2828. {
  2829. fprintf(pFile, "Frame %d Detail Timing Information\n", i);
  2830. OutputDecTimingDetail(pFile, pTempDecTimingInfo);
  2831. }
  2832. }
  2833. /* Compute the total information
  2834. */
  2835. memset(&dtiTemp, 0, sizeof(DEC_TIMING_INFO));
  2836. iCount = 0;
  2837. // for ( i = 0, pTempDecTimingInfo = pDecTimingInfo ; i < uStatFrameCount ; i++, pTempDecTimingInfo++ )
  2838. for ( i = 0, pTempDecTimingInfo = pDecTimingInfo ; i < DEC_TIMING_INFO_FRAME_COUNT ; i++, pTempDecTimingInfo++ )
  2839. {
  2840. if (pTempDecTimingInfo->uDecodeFrame != 0)
  2841. {
  2842. iCount++;
  2843. dtiTemp.uDecodeFrame += pTempDecTimingInfo->uDecodeFrame;
  2844. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  2845. dtiTemp.uHeaders += pTempDecTimingInfo->uHeaders;
  2846. dtiTemp.uMemcpy += pTempDecTimingInfo->uMemcpy;
  2847. dtiTemp.uFrameCopy += pTempDecTimingInfo->uFrameCopy;
  2848. dtiTemp.uOutputCC += pTempDecTimingInfo->uOutputCC;
  2849. dtiTemp.uIDCTandMC += pTempDecTimingInfo->uIDCTandMC;
  2850. dtiTemp.uDecIDCTCoeffs+= pTempDecTimingInfo->uDecIDCTCoeffs;
  2851. #endif // } DETAILED_DECODE_TIMINGS_ON
  2852. dtiTemp.uBEF += pTempDecTimingInfo->uBEF;
  2853. }
  2854. }
  2855. if (iCount > 0)
  2856. {
  2857. /* Output the total information
  2858. */
  2859. fprintf(pFile,"Total for %d frames\n", iCount);
  2860. OutputDecTimingDetail(pFile, &dtiTemp);
  2861. /* Compute the average
  2862. */
  2863. dtiTemp.uDecodeFrame = (dtiTemp.uDecodeFrame + (iCount / 2)) / iCount;
  2864. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  2865. dtiTemp.uHeaders = (dtiTemp.uHeaders + (iCount / 2)) / iCount;
  2866. dtiTemp.uMemcpy = (dtiTemp.uMemcpy + (iCount / 2)) / iCount;
  2867. dtiTemp.uFrameCopy = (dtiTemp.uFrameCopy + (iCount / 2)) / iCount;
  2868. dtiTemp.uOutputCC = (dtiTemp.uOutputCC + (iCount / 2)) / iCount;
  2869. dtiTemp.uIDCTandMC = (dtiTemp.uIDCTandMC+ (iCount / 2)) / iCount;
  2870. dtiTemp.uDecIDCTCoeffs= (dtiTemp.uDecIDCTCoeffs+ (iCount / 2)) / iCount;
  2871. #endif // } DETAILED_DECODE_TIMINGS_ON
  2872. dtiTemp.uBEF = (dtiTemp.uBEF + (iCount / 2)) / iCount;
  2873. /* Output the average information
  2874. */
  2875. fprintf(pFile,"Average over %d frames\n", iCount);
  2876. OutputDecTimingDetail(pFile, &dtiTemp);
  2877. }
  2878. fclose(pFile);
  2879. done:
  2880. return;
  2881. }
  2882. void OutputDecTimingDetail(FILE * pFile, DEC_TIMING_INFO * pDecTimingInfo)
  2883. {
  2884. U32 uOther;
  2885. U32 uRoundUp;
  2886. U32 uDivisor;
  2887. fprintf(pFile, "\tDecode Frame = %10d (%d milliseconds at 90Mhz)\n", pDecTimingInfo->uDecodeFrame,
  2888. (pDecTimingInfo->uDecodeFrame + 45000) / 90000);
  2889. uOther = pDecTimingInfo->uDecodeFrame;
  2890. /* This is needed because of the integer truncation.
  2891. */
  2892. uDivisor = pDecTimingInfo->uDecodeFrame / 100; // to yield a percent
  2893. uRoundUp = uDivisor / 2;
  2894. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  2895. fprintf(pFile, "\tmemcpy = %10d (%2d%%)\n", pDecTimingInfo->uMemcpy,
  2896. (pDecTimingInfo->uMemcpy + uRoundUp) / uDivisor);
  2897. uOther -= pDecTimingInfo->uMemcpy;
  2898. fprintf(pFile, "\tHeaders = %10d (%2d%%)\n", pDecTimingInfo->uHeaders,
  2899. (pDecTimingInfo->uHeaders + uRoundUp) / uDivisor);
  2900. uOther -= pDecTimingInfo->uHeaders;
  2901. fprintf(pFile, "\tFrameCopy = %10d (%2d%%)\n", pDecTimingInfo->uFrameCopy,
  2902. (pDecTimingInfo->uFrameCopy + uRoundUp) / uDivisor);
  2903. uOther -= pDecTimingInfo->uFrameCopy;
  2904. fprintf(pFile, "\tDecode DCT Coeffs = %10d (%2d%%)\n", pDecTimingInfo->uDecIDCTCoeffs,
  2905. (pDecTimingInfo->uDecIDCTCoeffs + uRoundUp) / uDivisor);
  2906. uOther -= pDecTimingInfo->uDecIDCTCoeffs;
  2907. fprintf(pFile, "\tIDCT and MC = %10d (%2d%%)\n", pDecTimingInfo->uIDCTandMC,
  2908. (pDecTimingInfo->uIDCTandMC + uRoundUp) / uDivisor);
  2909. uOther -= pDecTimingInfo->uIDCTandMC;
  2910. #endif // } DETAILED_DECODE_TIMINGS_ON
  2911. fprintf(pFile, "\tBlock Edge Filter = %10d (%2d%%)\n", pDecTimingInfo->uBEF,
  2912. (pDecTimingInfo->uBEF + uRoundUp) / uDivisor);
  2913. uOther -= pDecTimingInfo->uBEF;
  2914. #ifdef DETAILED_DECODE_TIMINGS_ON // { DETAILED_DECODE_TIMINGS_ON
  2915. fprintf(pFile, "\tOutput CC = %10d (%2d%%)\n", pDecTimingInfo->uOutputCC,
  2916. (pDecTimingInfo->uOutputCC + uRoundUp) / uDivisor);
  2917. uOther -= pDecTimingInfo->uOutputCC;
  2918. #endif // } DETAILED_DECODE_TIMINGS_ON
  2919. fprintf(pFile, "\tOther = %10d (%2d%%)\n", uOther,
  2920. (uOther + uRoundUp) / uDivisor);
  2921. }
  2922. #endif // } LOG_DECODE_TIMINGS_ON