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.

3077 lines
103 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-1996 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. /*****************************************************************************
  15. *
  16. * e1enc.cpp
  17. *
  18. * DESCRIPTION:
  19. * Specific encoder compression functions.
  20. *
  21. * Routines: Prototypes in:
  22. * H263InitEncoderInstance
  23. * H263Compress
  24. * H263TermEncoderInstance
  25. */
  26. // $Header: S:\h26x\src\enc\e1enc.cpv 1.78 15 Apr 1997 10:24:48 AGUPTA2 $
  27. // $Log: S:\h26x\src\enc\e1enc.cpv $
  28. //
  29. // Rev 1.78 15 Apr 1997 10:24:48 AGUPTA2
  30. // Added checks to ensure 1) bit-stream is less than (8,32)K and 2)
  31. // extended bitstream is less than allocated buffer size.
  32. //
  33. // Rev 1.77 24 Jan 1997 17:12:06 RHAZRA
  34. // We were computing the size of the bitstream to be one more than
  35. // the real size. Now fixed.
  36. //
  37. // Rev 1.76 17 Dec 1996 09:07:16 SCDAY
  38. // changed an ASSERT to handle Memory Layout changes
  39. //
  40. // Rev 1.75 16 Dec 1996 17:36:04 MBODART
  41. // Applied Raj's changes for tweaking ME parameters under RTP.
  42. // Also restructured some code for cleanliness.
  43. //
  44. // Rev 1.74 13 Dec 1996 17:19:02 MBODART
  45. // Bumped the ME SLF parameters for MMX.
  46. //
  47. // Rev 1.73 13 Dec 1996 15:17:02 MBODART
  48. // Adjusted the motion estimation IA spatial loop filter parameters.
  49. // Still need to tune the MMX parameters.
  50. //
  51. // Rev 1.72 05 Dec 1996 10:56:14 MBODART
  52. // Added h261test.ini options for playing with motion estimation parameters.
  53. //
  54. // Rev 1.71 04 Dec 1996 13:23:34 MBODART
  55. // Tweaked some DbgLog messages to aid bit rate tuning.
  56. // Removed some unused code.
  57. //
  58. // Rev 1.70 21 Nov 1996 10:50:32 RHAZRA
  59. // Changed recompression strategy to be more pessimistic with key
  60. // frames since a buffer overflow on a keyframe can cause a host
  61. // of secondary effects.
  62. //
  63. // Rev 1.69 18 Nov 1996 17:11:38 MBODART
  64. // Replaced all debug message invocations with Active Movie's DbgLog.
  65. //
  66. // Rev 1.68 18 Nov 1996 09:02:34 RHAZRA
  67. // Now no DWORD 0 at the end of the bitstream for both the MMX and IA
  68. // codecs.
  69. //
  70. // Rev 1.67 15 Nov 1996 09:47:22 RHAZRA
  71. // #ifdef ed out the addition of a DWORD of zeros at the end of the bitstream.
  72. //
  73. // Rev 1.66 13 Nov 1996 11:37:20 RHAZRA
  74. // Added MMX autosensing
  75. //
  76. // Rev 1.65 21 Oct 1996 10:45:50 RHAZRA
  77. // Changed interface to EDTQ function to keep in sync with exmme.asm which
  78. // now has EMV
  79. //
  80. // Rev 1.64 21 Oct 1996 09:00:18 RHAZRA
  81. // MMX integration
  82. //
  83. // Rev 1.62 16 Sep 1996 13:17:44 RHAZRA
  84. // Added support for SLF to be adaptively turned on and off via
  85. // coding thresholds and differentials.
  86. //
  87. // Rev 1.61 06 Sep 1996 15:04:52 MBODART
  88. // Added performance counters for NT's perfmon.
  89. // New files: cxprf.cpp, cxprf.h, cxprfmac.h.
  90. // New directory: src\perf
  91. // Updated files: e1enc.{h,cpp}, d1dec.{h,cpp}, cdrvdefs.h, h261* makefiles.
  92. //
  93. // Rev 1.60 26 Aug 1996 10:09:02 RHAZRA
  94. // Added checking to ensure that RTP BS Info stream is rewound on
  95. // GOB recompression only if RTP is signalled. This fixes the reported
  96. // failure of build 29 on q1502stl.avi @ 100Kbps.
  97. //
  98. // Rev 1.59 21 Aug 1996 19:01:18 RHAZRA
  99. // Added RTP extended bitstream generation
  100. //
  101. // Rev 1.58 21 Jun 1996 10:06:06 AKASAI
  102. // Changes to e1enc.cpp, e1mbenc.cpp, ex5me.asm to support "improved
  103. // bit rate control", changing MacroBlock Quantization within a
  104. // row of MB's in addition to changing the Quantization change
  105. // between rows of macro blocks.
  106. //
  107. // ex5me.asm had a problem with SLF SWD. Brian updated asm code.
  108. //
  109. //
  110. // Rev 1.57 05 Jun 1996 13:56:52 AKASAI
  111. // Changes to e1enc.cpp: Added new parameter to MOTIONESTIMATION which
  112. // allows for 15 pel radius search otherwise (? maybe 7 pels).
  113. //
  114. // Changes to e1enc.h: New parameter to MOTIONESTIMATION and change to
  115. // offsets in MBAcationStream to match changes in e3mbad.inc, ex5me.asm
  116. // and ex5fdct.asm.
  117. //
  118. // Rev 1.56 29 May 1996 13:53:00 AKASAI
  119. // Tuned the Motion Estimation parameters. Video quality
  120. // seems to remain about the same, bit rate increased a little (200 bits
  121. // per frame), CPU usage decreased a little.
  122. //
  123. // Rev 1.55 14 May 1996 12:33:10 AKASAI
  124. // Got an undefined on wsprintf so moved it to a #ifdef DEBUG_RECOMPRESS
  125. // area.
  126. //
  127. // Rev 1.54 14 May 1996 10:33:46 AKASAI
  128. // Two files changed to hopefully eliminate Quantization clamping
  129. // artifacts and to reduce the max buffer overflow case: e1enc.cpp
  130. // and e1mbenc.cpp.
  131. //
  132. // In e1mbenc.cpp when the MQuant level is < 6 I test to see if
  133. // the 0th coefficient is larger than the values representable
  134. // at that Quant level if it is I increase the Quant level until
  135. // the clamping artifact will not occur. Note: I am test only
  136. // the Oth coefficient, there is the possibility that some other
  137. // coefficient is larger but the performance trade off seems to
  138. // indicate this is good for now and if we still see clamping
  139. // artifacts we can add more testing later.
  140. //
  141. // In e1enc.cpp I modified when the Overflow types of warnings are
  142. // turn on as well as changing the rate the Quantization level
  143. // changes at.
  144. //
  145. // Rev 1.53 24 Apr 1996 12:13:50 AKASAI
  146. // Added re-compression strategy to encoder. Had to change e1enc.cpp,
  147. // e1enc.h and e1mbenc.cpp.
  148. // Basic strategy is if spending too many bits in a GOB quantize the
  149. // next GOB at a higher rate. If after compressing the frame too
  150. // many bits have been used, re-compress the last GOB at a higher
  151. // QUANT level if that still doesn't work send a "Skip" GOB.
  152. // Needed to add extra parameter to GOB+Q_RLE_VLC_WriteBS because
  153. // CalcMBQuant kept decreasing the QUANT when we were in trouble with
  154. // possibly overflowing the buffer.
  155. //
  156. // Rev 1.52 22 Apr 1996 10:54:24 AKASAI
  157. // Two files changed e1enc.cpp and e1mbenc.cpp to try and support
  158. // allowing the Quantization values to go down to 2 instead of
  159. // CLAMP to 6.
  160. // This is part 1 of implementing the re-compression (what to do
  161. // if exceed max compressed buffer size 8KBytes QCIF, 32KBytes FCIF).
  162. // Also changed in e1enc was to limit request uFrameSize to 8KB or
  163. // 32KB. Problem was if user specified too large of a datarate
  164. // request frame size would be larger than the allowed buffer size.
  165. // If you try to compress qnoise10.avi or fnoise5.avi you get an
  166. // ASSERT error until rest of re-compression is implemented.
  167. //
  168. // Rev 1.51 19 Apr 1996 14:26:26 SCDAY
  169. // Added adaptive bit usage profile (Karl's BRC changes)
  170. //
  171. // Rev 1.50 15 Apr 1996 14:10:30 AKASAI
  172. // Updated range to allow for +/- 15 pel search. There was and assert
  173. // if MV outside +/- 15 (in half pel numbers) now assert if [-32,31].
  174. //
  175. // Rev 1.49 11 Apr 1996 16:00:02 AKASAI
  176. // Updated H261 encoder to new interface and macroblock action stream
  177. // data structure in e3mbad.inc for FORWARDDCT. Files updated together
  178. // e1enc.cpp, e1enc.h, ex5fdct.asm, e3mbad.inc.
  179. //
  180. // Added IFNDEF H261 in ex5fdct so that code used only in H263 is
  181. // not assembled for H261.
  182. //
  183. // Rev 1.48 11 Apr 1996 13:02:04 SCDAY
  184. // Fixed zero dirty buffer problem
  185. //
  186. // Rev 1.45 10 Apr 1996 13:06:40 SCDAY
  187. // Changed clearing of bitstream buffer to zero only the "dirty"
  188. // part of the buffer rather than the entire buffer
  189. //
  190. // Rev 1.44 05 Apr 1996 14:36:28 SCDAY
  191. //
  192. // Added ASM version of UV SLF
  193. //
  194. // Rev 1.43 04 Apr 1996 13:45:32 AKASAI
  195. // Added 2 Bytes, 16-bits of zeros at end of bitstream to help 16-bit
  196. // decoder find end of frame. Under testing we saw green blocks at
  197. // end of frame.
  198. //
  199. // Rev 1.42 27 Mar 1996 15:09:52 SCDAY
  200. // Moved declarations/definition of H26X_YUV12toEncYUV12 to excolcnv.cpp
  201. // to incorporate latest H263 changes and SCD 'C' code optimization
  202. //
  203. // Rev 1.41 20 Mar 1996 14:21:04 Sylvia_C_Day
  204. // Added lower level timing stats for SLF_UV
  205. //
  206. // Rev 1.40 26 Feb 1996 10:09:34 AKASAI
  207. // Corrected PicFreeze bit last fix set it to always ON instead of the
  208. // correct usage. ON for Keys OFF for deltas.
  209. // Also fixed 2 other bits that were set incorrectly. HI_RES and SPARE.
  210. // SPARE should always be 1, HI_RES should be OFF (which is 1 for this
  211. // bit).
  212. //
  213. // Rev 1.39 14 Feb 1996 14:53:56 AKASAI
  214. // Added work around for Blazer team to set PicFreeze to ON when
  215. // encoding a KEY FRAME.
  216. //
  217. // Rev 1.38 06 Feb 1996 09:46:00 AKASAI
  218. // Updated Copyright to include 1996.
  219. //
  220. // Rev 1.37 05 Feb 1996 15:24:04 AKASAI
  221. // Changes to support new BRC interface. Tested with RING3 codec.
  222. //
  223. // Rev 1.36 09 Jan 1996 08:52:34 AKASAI
  224. //
  225. // Added U&V plane loop filter. To enable make sure SLF_WORK_AROUND
  226. // is defined in makefile.
  227. //
  228. // Rev 1.35 08 Jan 1996 10:11:58 DBRUCKS
  229. // Disable half pel interpolation of U & V motion vectors in fdct
  230. // Change to use divide and not shift when calculating U & V motion vectors
  231. // in order that we truncate towards zero as the spec requires.
  232. //
  233. // Rev 1.34 29 Dec 1995 18:12:54 DBRUCKS
  234. //
  235. // add clamp_n_to(qp,6,31) to avoid clipping artifacts.
  236. // add code to assign Y2,3,4-PrevPtr based on Y1-PrevPtr for SLF blocks
  237. //
  238. // Rev 1.33 27 Dec 1995 16:51:54 DBRUCKS
  239. // move the increment of InterCodeCnt to e1mbenc.cpp
  240. // cleanup based on H263 v11
  241. // remove unused definitions
  242. //
  243. // Rev 1.32 26 Dec 1995 17:44:52 DBRUCKS
  244. // moved statistics to e1stat
  245. //
  246. // Rev 1.31 20 Dec 1995 16:46:02 DBRUCKS
  247. // get Spox to compile with the timing code
  248. //
  249. // Rev 1.30 20 Dec 1995 15:35:08 DBRUCKS
  250. // get to build without ENC_STATS define
  251. //
  252. // Rev 1.29 20 Dec 1995 14:56:50 DBRUCKS
  253. // add timing stats
  254. //
  255. // Rev 1.28 18 Dec 1995 15:38:02 DBRUCKS
  256. // improve stats
  257. //
  258. // Rev 1.27 13 Dec 1995 13:58:18 DBRUCKS
  259. //
  260. // moved trace and cnvt_fdct_output to exutil.cpp
  261. // removed BitRev as it was not used
  262. // changed to call terminate if init was called with Initialized == True
  263. // implemented TR
  264. //
  265. // Rev 1.26 07 Dec 1995 12:53:38 DBRUCKS
  266. //
  267. // add an ifdef so the ring0 release build succeeds
  268. // change the quality to quant from conversion to use 3 to 31
  269. // fix mb first state initialization for CIF
  270. //
  271. // Rev 1.25 06 Dec 1995 09:43:38 DBRUCKS
  272. //
  273. // initialize blazer COMPINSTINFO variables
  274. // integrate blazer bit rate control into Compress
  275. // remove LINK_ME
  276. //
  277. // Rev 1.24 04 Dec 1995 10:26:28 DBRUCKS
  278. // cleanup the ini file reading function
  279. //
  280. // Rev 1.23 01 Dec 1995 15:37:56 DBRUCKS
  281. //
  282. // Added the bit rate controller
  283. // set the default options (if no INI file) to:
  284. // RING0: MotionEstimation SpatialLoopFilter FixedQuantization of 8
  285. // RING3: MotionEstimation SpatialLoopFilter VfW driven Bit Rate Control
  286. //
  287. // Rev 1.20 28 Nov 1995 13:21:30 DBRUCKS
  288. // add BRC options
  289. // change to read options from an ini file - h261.ini
  290. //
  291. // Rev 1.19 27 Nov 1995 17:53:42 DBRUCKS
  292. // add spatial loop filtering
  293. //
  294. // Rev 1.18 27 Nov 1995 16:41:44 DBRUCKS
  295. // replace B and Future planes with SLF
  296. // remove the scratch space
  297. //
  298. // Rev 1.17 22 Nov 1995 18:21:42 DBRUCKS
  299. // Add an #ifdef around the MOTIONESTIMATION call in order that the IASpox
  300. // environment not be required to call MOTIONESTIMATION when advancing the
  301. // tip. Unless LINK_ME is defined MOTIONESTIMATION will not be called.
  302. //
  303. // Rev 1.16 22 Nov 1995 17:37:36 DBRUCKS
  304. // cleanup me changes
  305. //
  306. // Rev 1.15 22 Nov 1995 15:34:30 DBRUCKS
  307. //
  308. // Motion Estimation works - but needs to be cleaned up
  309. //
  310. // Rev 1.14 20 Nov 1995 12:13:14 DBRUCKS
  311. // Cleanup the encoder terminate function
  312. // Integrate in the picture checksum code (CHECKSUM_PICTURE)
  313. //
  314. // Rev 1.13 17 Nov 1995 14:25:24 BECHOLS
  315. // Made modifications so that this file can be made for ring 0.
  316. //
  317. // Rev 1.12 15 Nov 1995 19:05:22 AKASAI
  318. // Cleaned up some warning messages.
  319. //
  320. // Rev 1.11 15 Nov 1995 14:38:16 AKASAI
  321. //
  322. // Current and Previous frame pointers changed from Addresses to Offsets.
  323. // Change of parameters to call to FOWARDDCT. Some Union thing.
  324. // (Integration point)
  325. //
  326. // Rev 1.10 01 Nov 1995 09:01:12 DBRUCKS
  327. //
  328. // cleanup variable names
  329. // add ZERO_INPUT test option
  330. // make sure all frames end on a byte boundary.
  331. //
  332. // Rev 1.9 27 Oct 1995 17:19:52 DBRUCKS
  333. // initializing PastRef ptrs
  334. //
  335. // Rev 1.8 27 Oct 1995 15:06:26 DBRUCKS
  336. // update cnvt_fdct_output
  337. //
  338. // Rev 1.7 27 Oct 1995 14:31:10 DBRUCKS
  339. // integrate 0-MV delta support based on 263 baseline
  340. //
  341. // Rev 1.6 28 Sep 1995 17:02:34 DBRUCKS
  342. // fix colorIn to not swap left to right
  343. //
  344. // Rev 1.5 28 Sep 1995 15:58:20 DBRUCKS
  345. // remove pragmas
  346. //
  347. // Rev 1.4 28 Sep 1995 14:21:30 DBRUCKS
  348. // fix to match INTRA and INTER enum changes
  349. //
  350. // Rev 1.3 25 Sep 1995 10:22:48 DBRUCKS
  351. // activate call to InitVLC
  352. //
  353. // Rev 1.2 20 Sep 1995 12:38:48 DBRUCKS
  354. // cleanup
  355. //
  356. // Rev 1.0 18 Sep 1995 10:09:30 DBRUCKS
  357. // Initial revision after the archive got corrupted.
  358. //
  359. // Rev 1.4 15 Sep 1995 12:27:32 DBRUCKS
  360. // intra mb header
  361. //
  362. // Rev 1.3 14 Sep 1995 17:16:08 DBRUCKS
  363. // turn on FDCT and some cleanup
  364. //
  365. // Rev 1.2 14 Sep 1995 14:18:52 DBRUCKS
  366. // init mb action stream
  367. //
  368. // Rev 1.1 13 Sep 1995 13:41:50 DBRUCKS
  369. // move the picture header writing into a separate routine.
  370. // implement the gob header writing.
  371. //
  372. // Rev 1.0 12 Sep 1995 15:53:40 DBRUCKS
  373. // initial
  374. //
  375. #define DUMPFILE 0
  376. /* Pick a resiliency strategy.
  377. */
  378. #define REQUESTED_KEY_FRAME 0
  379. #define PERIODIC_KEY_FRAME 1
  380. #define FAST_RECOVERY 2
  381. #define SLOW_RECOVERY 3
  382. #define MAX_STUFFING_BYTES 10
  383. #define RESILIENCY_STRATEGY PERIODIC_KEY_FRAME
  384. #define PERIODIC_KEY_FRAME_PERIODICITY 15 /* Select periodicity (max 32767) */
  385. #define UNRESTRICTED_MOTION_FRAMES 16 /* Number of frames that don't have an Intra slice. 0 for FAST_RECOVERY.
  386. * Modest amount for SLOW_RECOVERY. Unimportant for other strategies. */
  387. #include "precomp.h"
  388. #ifdef ENCODE_STATS
  389. #define ENCODE_STATS_FILENAME "encstats.txt"
  390. #endif
  391. #define PITCHL 384L
  392. #define DEFAULT_DCSTEP 8
  393. #define DEFAULT_QUANTSTEP 36
  394. #define DEFAULT_QUANTSTART 30
  395. #define LEFT 0
  396. #define INNERCOL 1
  397. #define NEARRIGHT 2
  398. #define RIGHT 3
  399. #define TOP 0
  400. #define INNERROW 4
  401. #define NEARBOTTOM 8
  402. #define BOTTOM 12
  403. #define FCIF_NUM_OF_GOBS 12
  404. #define QCIF_NUM_OF_GOBS 3
  405. #if defined(_DEBUG) || defined(DEBUG_RECOMPRESS) || defined(DEBUG_ENC) || defined(DEBUG_BRC)
  406. char string[128];
  407. #endif
  408. /* Look up table for quarter pel to half pel conversion of chroma MV's. */
  409. const char QtrPelToHalfPel[64] =
  410. { -16, -15, -15, -15, -14, -13, -13, -13, -12, -11, -11, -11, -10, -9, -9, -9, -8,
  411. -7, -7, -7, -6, -5, -5, -5, -4, -3, -3, -3, -2, -1, -1, -1, 0,
  412. 1, 1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8,
  413. 9, 9, 9, 10, 11, 11, 11, 12, 13, 13, 13, 14, 15, 15, 15 };
  414. /* The GOB number arrays contain the GOB numbers for QCIF and CIF. The lists are zero terminated.
  415. */
  416. static U32 uCIFGOBNumbers[] = {1,2,3,4,5,6,7,8,9,10,11,12,0};
  417. static U32 uQCIFGOBNumbers[] = {1,3,5,0};
  418. /* The starting INTER Motion Estimation states are different for QCIF and CIF.
  419. */
  420. #define MAX_ME_STATE_ROW_NUMBER 8
  421. #define BAD_ME_ROW (MAX_ME_STATE_ROW_NUMBER + 1)
  422. static U8 u8FirstInterMEStateRows[MAX_ME_STATE_ROW_NUMBER+1][11] =
  423. { /* 1 2 3 4 5 6 7 8 9 10 11 */
  424. {UpperLeft, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperRight},
  425. {LeftEdge, CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,RightEdge},
  426. {LowerLeft, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerRight},
  427. {UpperLeft, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge},
  428. {UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperEdge, UpperRight},
  429. {LeftEdge, CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock},
  430. {CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,CentralBlock,RightEdge},
  431. {LowerLeft, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge},
  432. {LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerRight},
  433. };
  434. //RTP: resiliency tables.
  435. static U8 u8FirstInterMENoVerMVStateRows[MAX_ME_STATE_ROW_NUMBER+1][11] =
  436. { /* 1 2 3 4 5 6 7 8 9 10 11 */
  437. {NoVertLeftEdge, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertRightEdge},
  438. {NoVertLeftEdge, NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertRightEdge},
  439. {NoVertLeftEdge, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertRightEdge},
  440. {NoVertLeftEdge, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock},
  441. {NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertRightEdge},
  442. {NoVertLeftEdge, NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock},
  443. {NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertCentralBlock,NoVertRightEdge},
  444. {NoVertLeftEdge, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock},
  445. {NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertRightEdge},
  446. };
  447. static U8 u8FirstInterMENoPosVerMVStateRows[MAX_ME_STATE_ROW_NUMBER+1][11] =
  448. { /* 1 2 3 4 5 6 7 8 9 10 11 */
  449. {NoVertLeftEdge, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertRightEdge},
  450. {LowerLeft, LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerRight},
  451. {LowerLeft, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerRight},
  452. {NoVertLeftEdge, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock},
  453. {NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertCentralBlock, NoVertRightEdge},
  454. {LowerLeft, LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge},
  455. {LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerEdge,LowerRight},
  456. {LowerLeft, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge},
  457. {LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerEdge, LowerRight},
  458. };
  459. static U8 u8MEPad[1];
  460. static U8 u8QCIFFirstInterMEStateRowNumbers[12] =
  461. {0,1,1, 1,1,1, 1,1,2, BAD_ME_ROW,BAD_ME_ROW,BAD_ME_ROW};
  462. static U8 u8CIFFirstInterMEStateRowNumbers[40] =
  463. {3,5,5, 4,6,6, 5,5,5, 6,6,6, 5,5,5, 6,6,6, 5,5,5, 6,6,6, 5,5,5, 6,6,6, 5,5,7, 6,6,8, BAD_ME_ROW,BAD_ME_ROW,BAD_ME_ROW,BAD_ME_ROW};
  464. /* The starting offsets for each of the GOBs
  465. * - odd GOBs: NumberOfGOBsAbove * PITCH * 3MacroBlocksToAGOB * NumberOfLinesToAMacroBlock
  466. * - even GOBs: oddGobValue + 11MacroBlocksToAGOB * NumberOfColumnsToAMacroBlock
  467. */
  468. static U32 uStartingYOffsets[16] =
  469. {
  470. 0, /* not used */
  471. 0*PITCH*3*16, 0*PITCH*3*16+11*16, // 1 and 2
  472. 1*PITCH*3*16, 1*PITCH*3*16+11*16, // 3 and 4
  473. 2*PITCH*3*16, 2*PITCH*3*16+11*16, // 5 and 6
  474. 3*PITCH*3*16, 3*PITCH*3*16+11*16, // 7 and 8
  475. 4*PITCH*3*16, 4*PITCH*3*16+11*16, // 9 and 10
  476. 5*PITCH*3*16, 5*PITCH*3*16+11*16, // 11 and 12
  477. 0, 0, 0 /* not used */
  478. };
  479. static U32 uStartingUOffsets[16] =
  480. {
  481. 0, /* not used */
  482. 0*PITCH*3*8, 0*PITCH*3*8+11*8, // 1 and 2
  483. 1*PITCH*3*8, 1*PITCH*3*8+11*8, // 3 and 4
  484. 2*PITCH*3*8, 2*PITCH*3*8+11*8, // 5 and 6
  485. 3*PITCH*3*8, 3*PITCH*3*8+11*8, // 7 and 8
  486. 4*PITCH*3*8, 4*PITCH*3*8+11*8, // 9 and 10
  487. 5*PITCH*3*8, 5*PITCH*3*8+11*8, // 11 and 12
  488. 0, 0, 0
  489. };
  490. /* Table to limit Quant changes between Rows of Marco Blocks */
  491. U8 MaxChangeRowMBTbl[32] =
  492. { 0, /* Not Used */
  493. 1, /* Not Used when clamp to (2,31) */
  494. 1, /* 2 */
  495. 2, /* 3 */
  496. 2, /* 4 */
  497. 3, /* 5 */
  498. 3, /* 6 */
  499. 3, /* 7 */
  500. 3, /* 8 */
  501. 3, /* 9 */
  502. 3, /* 10 */
  503. 3, /* 11 */
  504. 3, /* 12 */
  505. 3, /* 13 */
  506. 3, /* 14 */
  507. 3, /* 15 */
  508. 3, /* 16 */
  509. 3, /* 17 */
  510. 3, /* 18 */
  511. 3, /* 19 */
  512. 3, /* 20 */
  513. 3, /* 21 */
  514. 3, /* 22 */
  515. 3, /* 23 */
  516. 4, /* 24 */
  517. 4, /* 25 */
  518. 4, /* 26 */
  519. 4, /* 27 */
  520. 4, /* 28 */
  521. 4, /* 29 */
  522. 4, /* 30 */
  523. 4 /* 31 */
  524. };
  525. U8 INTERCODECNT_ADJUST[11]=
  526. // Packet loss (in %)
  527. // 0-9 10-19 20-29 30-39 40-49 50-59 60-69 70-79 80-89 90-99 100
  528. // Refresh limit
  529. { 132, 100, 80, 75, 60, 45, 20, 10, 5, 3, 1 };
  530. U32 EMPTYTHRESHOLD_ADJUST[5]=
  531. // Packet loss (in %)
  532. // 0-24 25-49 50-74 75-99 100
  533. // Multiplier
  534. { 1, 2, 3, 4, 10};
  535. /* Static Function declarations
  536. */
  537. static void WriteBeginPictureHeaderToStream(T_H263EncoderCatalog *, U8 ** ,U8 *);
  538. #ifdef CHECKSUM_PICTURE
  539. static void WritePictureChecksum(YVUCheckSum *, U8 ** ,U8 *, U8);
  540. #endif
  541. static void WriteEndPictureHeaderToStream(T_H263EncoderCatalog *, U8 ** ,U8 *);
  542. static void WriteGOBHeaderToStream(U32,unsigned int, U8 ** ,U8 *);
  543. static void CalcGOBChromaVecs(T_H263EncoderCatalog *, UN, T_CONFIGURATION *);
  544. static void GetEncoderOptions(T_H263EncoderCatalog *);
  545. static void StartupBRC(T_H263EncoderCatalog *, U32, U32, float);
  546. static void CalculateQP_mean(T_H263EncoderCatalog * EC);
  547. /* Global Data definition
  548. */
  549. #pragma data_seg ("H263EncoderTbl") /* Put in the data segment named "H263EncoderTbl" */
  550. #pragma data_seg ()
  551. /*****************************************************************************
  552. * EXTERNAL FUNCTIONS
  553. ****************************************************************************/
  554. /*****************************************************************************
  555. *
  556. * H263InitEncoderGlobal
  557. *
  558. * This function initializes the global tables used by the H261 encoder. Note
  559. * that in 16-bit Windows, these tables are copied to the per-instance data
  560. * segment, so that they can be used without segment override prefixes.
  561. * In 32-bit Windows, the tables are left in their staticly allocated locations.
  562. *
  563. * Returns an ICERR value
  564. */
  565. LRESULT H263InitEncoderGlobal(void)
  566. {
  567. /*
  568. * Initialize fixed length tables for INTRADC
  569. */
  570. InitVLC();
  571. return ICERR_OK;
  572. } /* end H263InitEncoderGlobal() */
  573. /*****************************************************************************
  574. *
  575. * H263InitEncoderInstance
  576. *
  577. * This function allocates and initializes the per-instance tables used by
  578. * the H261 encoder. Note that in 16-bit Windows, the non-instance-specific
  579. * global tables are copied to the per-instance data segment, so that they
  580. * can be used without segment override prefixes.
  581. *
  582. * Returns an ICERR value;
  583. */
  584. LRESULT H263InitEncoderInstance(LPCODINST lpCompInst)
  585. {
  586. LRESULT lResult = ICERR_ERROR;
  587. U32 uGOBNumber;
  588. U32 uSize;
  589. UN unIndex;
  590. UN unStartingMB;
  591. T_H263EncoderInstanceMemory * P32Inst;
  592. T_H263EncoderCatalog * EC;
  593. U32 * puGOBNumbers;
  594. int iMBNumber;
  595. UN bEncoderInstLocked = 0;
  596. int iNumMBs;
  597. // RTP: declarations
  598. T_CONFIGURATION *pConfiguration;
  599. UN uIntraQP;
  600. UN uInterQP;
  601. /* If we were already initialized then we need to terminate the instance.
  602. * This happens when two BEGIN's are called without an END.
  603. *
  604. * Note: We can't just clear the memory because that will throw out the
  605. * decoder memory. because it will clear the decoder instance which
  606. * contains the decoder catalog pointer.
  607. */
  608. if(lpCompInst->Initialized)
  609. {
  610. lResult = H263TermEncoderInstance(lpCompInst);
  611. if (lResult != ICERR_OK)
  612. {
  613. DBOUT("Warning an error occurred terminating the encoder before reinitializing");
  614. }
  615. }
  616. /* Calculate size of encoder instance memory needed. */
  617. //uSize = sizeof(T_H263EncoderInstanceMemory) + 32;
  618. uSize = sizeof(T_H263EncoderInstanceMemory) + sizeof(T_MBlockActionStream);
  619. /*
  620. * Allocate the memory.
  621. */
  622. lpCompInst->hEncoderInst = GlobalAlloc(GHND, uSize);
  623. lpCompInst->EncoderInst = (LPVOID) GlobalLock(lpCompInst->hEncoderInst);
  624. if (lpCompInst->hEncoderInst == NULL || lpCompInst->EncoderInst == NULL)
  625. {
  626. lResult = ICERR_MEMORY;
  627. goto done;
  628. }
  629. bEncoderInstLocked = 1;
  630. /* Calculate the 32 bit instance pointer starting at the next
  631. * 32 byte boundary.
  632. */
  633. P32Inst = (T_H263EncoderInstanceMemory *)
  634. ((((U32) lpCompInst->EncoderInst) +
  635. (sizeof(T_MBlockActionStream) - 1)) &
  636. ~(sizeof(T_MBlockActionStream) - 1));
  637. /* The encoder catalog is at the start of the per-instance data.
  638. */
  639. EC = &(P32Inst->EC);
  640. // RTP: initialization
  641. /* Initialize the Configuration information
  642. */
  643. pConfiguration = &(lpCompInst->Configuration);
  644. #if 0
  645. if (LoadConfiguration(pConfiguration) == FALSE)
  646. {
  647. GetConfigurationDefaults(pConfiguration);
  648. }
  649. #endif
  650. pConfiguration->bInitialized = TRUE;
  651. pConfiguration->bCompressBegin = TRUE;
  652. #ifdef _DEBUG
  653. DBOUT("Encoder Configuration Options:");
  654. wsprintf(string,"bRTPHeader=%d", (int)pConfiguration->bRTPHeader);
  655. DBOUT(string);
  656. wsprintf(string,"unPacketSize=%d", (int)pConfiguration->unPacketSize);
  657. DBOUT(string);
  658. wsprintf(string,"bEncoderResiliency=%d", (int)pConfiguration->bEncoderResiliency);
  659. DBOUT(string);
  660. wsprintf(string,"bDisallowPosVerMVs=%d", (int)pConfiguration->bDisallowPosVerMVs);
  661. DBOUT(string);
  662. wsprintf(string,"bDisallowAllVerMVs=%d", (int)pConfiguration->bDisallowAllVerMVs);
  663. DBOUT(string);
  664. wsprintf(string,"unPercentForcedUpdate=%d", (int)pConfiguration->unPercentForcedUpdate);
  665. DBOUT(string);
  666. wsprintf(string,"unDefaultIntraQuant=%d", (int)pConfiguration->unDefaultIntraQuant);
  667. DBOUT(string);
  668. wsprintf(string,"unDefaultInterQuant=%d", (int)pConfiguration->unDefaultInterQuant);
  669. DBOUT(string);
  670. #endif
  671. /* Initialize encoder catalog.
  672. */
  673. EC->FrameHeight = lpCompInst->yres;
  674. EC->FrameWidth = lpCompInst->xres;
  675. EC->FrameSz = lpCompInst->FrameSz;
  676. EC->NumMBRows = EC->FrameHeight >> 4;
  677. EC->NumMBPerRow = EC->FrameWidth >> 4;
  678. EC->NumMBs = EC->NumMBRows * EC->NumMBPerRow;
  679. /* Get the Options
  680. */
  681. GetEncoderOptions(EC);
  682. // RTP: resiliency initialization
  683. if(pConfiguration->bEncoderResiliency &&
  684. pConfiguration->unPercentForcedUpdate &&
  685. pConfiguration->unPacketLoss)
  686. {
  687. EC->uNumberForcedIntraMBs = ((EC->NumMBs * pConfiguration->unPercentForcedUpdate) + 50) / 100;
  688. EC->uNextIntraMB = 0;
  689. }
  690. /* Store pointers to current frame in the catalog.
  691. */
  692. EC->pU8_CurrFrm = P32Inst->u8CurrentPlane;
  693. EC->pU8_CurrFrm_YPlane = EC->pU8_CurrFrm + 16;
  694. EC->pU8_CurrFrm_UPlane = EC->pU8_CurrFrm_YPlane + YU_OFFSET;
  695. EC->pU8_CurrFrm_VPlane = EC->pU8_CurrFrm_UPlane + UV_OFFSET;
  696. /* Store pointers to the previous frame in the catalog.
  697. */
  698. EC->pU8_PrevFrm = P32Inst->u8PreviousPlane;
  699. EC->pU8_PrevFrm_YPlane = EC->pU8_PrevFrm + 16*PITCH + 16;
  700. EC->pU8_PrevFrm_UPlane = EC->pU8_PrevFrm_YPlane + YU_OFFSET;
  701. EC->pU8_PrevFrm_VPlane = EC->pU8_PrevFrm_UPlane + UV_OFFSET;
  702. /* Store pointers to the Spatial Loop Filter frame in the catalog.
  703. */
  704. EC->pU8_SLFFrm = P32Inst->u8SLFPlane;
  705. EC->pU8_SLFFrm_YPlane = EC->pU8_SLFFrm + 16;
  706. EC->pU8_SLFFrm_UPlane = EC->pU8_SLFFrm_YPlane + YU_OFFSET;
  707. EC->pU8_SLFFrm_VPlane = EC->pU8_SLFFrm_UPlane + UV_OFFSET;
  708. /* Store pointers to the Signature frame in the catalog
  709. */
  710. EC->pU8_Signature = P32Inst->u8Signature;
  711. EC->pU8_Signature_YPlane = EC->pU8_Signature + 16*PITCH + 16;
  712. // Store pointer to the RunValSign triplets for Luma and Chroma
  713. EC->pI8_MBRVS_Luma = P32Inst->i8MBRVS_Luma;
  714. EC->pI8_MBRVS_Chroma = P32Inst->i8MBRVS_Chroma;
  715. /* Store pointer to the macroblock action stream in the catalog.
  716. */
  717. EC->pU8_MBlockActionStream = P32Inst->MBActionStream;
  718. /* Store pointer to the GOB DCT coefficient buffer in the catalog.
  719. */
  720. EC->pU8_DCTCoefBuf = P32Inst->piGOB_DCTCoefs;
  721. /* Store pointer to the bit stream buffer in the catalog.
  722. */
  723. EC->pU8_BitStream = P32Inst->u8BitStream;
  724. /* Store pointer to private copy of decoder instance info.
  725. */
  726. EC->pDecInstanceInfo = &(P32Inst->DecInstanceInfo);
  727. /* Fill the picture header structure.
  728. */
  729. EC->PictureHeader.Split = OFF;
  730. EC->PictureHeader.DocCamera = OFF;
  731. EC->PictureHeader.PicFreeze = OFF;
  732. EC->PictureHeader.StillImage = (EnumOnOff) 1; // For this bit ON=0, OFF=1
  733. EC->PictureHeader.TR = 31;
  734. if (EC->FrameWidth == 352)
  735. {
  736. ASSERT(EC->FrameHeight == 288);
  737. EC->PictureHeader.SourceFormat = SF_CIF;
  738. EC->u8DefINTRA_QP = 20;
  739. EC->u8DefINTER_QP = 13;
  740. }
  741. else
  742. {
  743. ASSERT(EC->FrameWidth == 176 && EC->FrameHeight == 144);
  744. EC->PictureHeader.SourceFormat = SF_QCIF;
  745. EC->u8DefINTRA_QP = 15;
  746. EC->u8DefINTER_QP = 10;
  747. }
  748. EC->PictureHeader.Spare = 1; // Spare bits set to 1
  749. EC->PictureHeader.PEI = 0;
  750. EC->PictureHeader.PQUANT = 8; // for now
  751. EC->PictureHeader.PicCodType = INTRAPIC; // for now
  752. #ifndef RING0
  753. /* Save the timing info pointer - only if do this if not Ring0 because
  754. * structure in P32Inst is only declared if not Ring0.
  755. */
  756. EC->pEncTimingInfo = P32Inst->EncTimingInfo;
  757. #endif
  758. /* Force the first frame to a key frame
  759. */
  760. EC->bMakeNextFrameKey = TRUE;
  761. /* Initialize table with Bit Usage Profile */
  762. // for (iNumMBs = 0; iNumMBs <= 33 ; iNumMBs++)
  763. for (iNumMBs = 0; iNumMBs <= (int)EC->NumMBs ; iNumMBs++)
  764. {
  765. EC->uBitUsageProfile[iNumMBs] = iNumMBs; // assume linear distribution at first
  766. }
  767. /* Check assumptions about structure sizes and boundary
  768. * alignment.
  769. */
  770. ASSERT( sizeof(T_Blk) == sizeof_T_Blk )
  771. ASSERT( sizeof(T_MBlockActionStream) == sizeof_T_MBlockActionStream )
  772. /* Encoder instance memory should start on a 32 byte boundary.
  773. */
  774. ASSERT( ( (unsigned int)P32Inst & 0x1f) == 0)
  775. /* MB Action Stream should be on a 16 byte boundary.
  776. */
  777. ASSERT( ( (unsigned int)EC->pU8_MBlockActionStream & 0xf) == 0 )
  778. /* Block structure array should be on a 16 byte boundary.
  779. */
  780. ASSERT( ( (unsigned int) &(EC->pU8_MBlockActionStream->BlkY1) & 0xf) == 0)
  781. /* Current Frame Buffers should be on a 32 byte boundaries.
  782. */
  783. ASSERT( ( (unsigned int)EC->pU8_CurrFrm_YPlane & 0x1f) == 0)
  784. ASSERT( ( (unsigned int)EC->pU8_CurrFrm_UPlane & 0x1f) == 0)
  785. ASSERT( ( (unsigned int)EC->pU8_CurrFrm_VPlane & 0x1f) == 0)
  786. /* Previous Frame Buffers should be on 16 byte boundaries.
  787. */
  788. ASSERT( ( (unsigned int)EC->pU8_PrevFrm_YPlane & 0x1f) == 0x10)
  789. ASSERT( ( (unsigned int)EC->pU8_PrevFrm_UPlane & 0x1f) == 0x10)
  790. ASSERT( ( (unsigned int)EC->pU8_PrevFrm_VPlane & 0x1f) == 0x10)
  791. /* Spatial Loop Filter Frame Buffers should be on a 32 byte boundary.
  792. */
  793. ASSERT( ( (unsigned int)EC->pU8_SLFFrm_YPlane & 0x1f) == 0)
  794. ASSERT( ( (unsigned int)EC->pU8_SLFFrm_UPlane & 0x1f) == 0)
  795. ASSERT( ( (unsigned int)EC->pU8_SLFFrm_VPlane & 0x1f) == 0)
  796. /* Motion Estimation includes a memory layout. Assert that we satisfy it.
  797. */
  798. ASSERT( ( (EC->pU8_PrevFrm_YPlane - EC->pU8_CurrFrm_YPlane) % 128) == 80)
  799. ASSERT( ( (EC->pU8_SLFFrm_YPlane - EC->pU8_PrevFrm_YPlane) % 4096) == 944)
  800. /* The bitstream should be on a 32 byte boundary
  801. */
  802. ASSERT( ( (unsigned int)EC->pU8_BitStream & 0x1f) == 0)
  803. /* DCT coefficient array should be on a 32 byte boundary.
  804. */
  805. ASSERT( ( (unsigned int)EC->pU8_DCTCoefBuf & 0x1f) == 0)
  806. /* Decoder instance structure should be on a DWORD boundary.
  807. */
  808. ASSERT( ( (unsigned int)EC->pDecInstanceInfo & 0x3 ) == 0 )
  809. /* Initialize MBActionStream
  810. */
  811. int YBlockOffset, UBlockOffset;
  812. puGOBNumbers = ( EC->PictureHeader.SourceFormat == SF_CIF ) ? uCIFGOBNumbers : uQCIFGOBNumbers;
  813. for (uGOBNumber = *puGOBNumbers++, unStartingMB = 0;
  814. uGOBNumber != 0;
  815. uGOBNumber = *puGOBNumbers++, unStartingMB += 33)
  816. {
  817. YBlockOffset = uStartingYOffsets[uGOBNumber];
  818. UBlockOffset = EC->pU8_CurrFrm_UPlane - EC->pU8_CurrFrm_YPlane + uStartingUOffsets[uGOBNumber];
  819. for (unIndex = 0; unIndex < 33; )
  820. {
  821. iMBNumber = unStartingMB + unIndex;
  822. /* Clear the counter of the number of consecutive times a macroblock has been inter coded.
  823. */
  824. (EC->pU8_MBlockActionStream[iMBNumber]).InterCodeCnt = 0;
  825. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY1.BlkOffset = YBlockOffset;
  826. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY2.BlkOffset = YBlockOffset+8;
  827. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY3.BlkOffset = YBlockOffset+PITCH*8;
  828. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY4.BlkOffset = YBlockOffset+PITCH*8+8;
  829. (EC->pU8_MBlockActionStream[iMBNumber]).BlkU.BlkOffset = UBlockOffset;
  830. (EC->pU8_MBlockActionStream[iMBNumber]).BlkV.BlkOffset = UBlockOffset+UV_OFFSET;
  831. if (! EC->bUseMotionEstimation)
  832. {
  833. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY1.PHMV = 0;
  834. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY1.PVMV = 0;
  835. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY2.PHMV = 0;
  836. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY2.PVMV = 0;
  837. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY3.PHMV = 0;
  838. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY3.PVMV = 0;
  839. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY4.PHMV = 0;
  840. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY4.PVMV = 0;
  841. (EC->pU8_MBlockActionStream[iMBNumber]).BlkU.PHMV = 0;
  842. (EC->pU8_MBlockActionStream[iMBNumber]).BlkU.PVMV = 0;
  843. (EC->pU8_MBlockActionStream[iMBNumber]).BlkV.PHMV = 0;
  844. (EC->pU8_MBlockActionStream[iMBNumber]).BlkV.PVMV = 0;
  845. }
  846. YBlockOffset += 16;
  847. UBlockOffset += 8;
  848. unIndex++;
  849. if (11 == unIndex || 22 == unIndex)
  850. {
  851. /* skip to the next row of macro blocks
  852. * - skip forward number of lines in a MB and back 11 macroblocks
  853. */
  854. YBlockOffset += PITCH*16 - 11*16;
  855. UBlockOffset += PITCH*8 - 11*8;
  856. }
  857. else if (33 == unIndex)
  858. {
  859. /* Mark the last MB in this GOB.
  860. */
  861. (EC->pU8_MBlockActionStream[iMBNumber]).CodedBlocks |= 0x40;
  862. }
  863. } /* end for unIndex */
  864. } /* end for uGOBNumber */
  865. ASSERT(unStartingMB == EC->NumMBs);
  866. if (! EC->bUseMotionEstimation)
  867. {
  868. /* Initialize previous frame pointers.
  869. */
  870. puGOBNumbers = ( EC->PictureHeader.SourceFormat == SF_CIF ) ? uCIFGOBNumbers : uQCIFGOBNumbers;
  871. for (uGOBNumber = *puGOBNumbers++, unStartingMB = 0;
  872. uGOBNumber != 0;
  873. uGOBNumber = *puGOBNumbers++, unStartingMB += 33)
  874. {
  875. YBlockOffset = uStartingYOffsets[uGOBNumber];
  876. UBlockOffset = EC->pU8_PrevFrm_UPlane - EC->pU8_PrevFrm_YPlane + uStartingUOffsets[uGOBNumber];
  877. for (unIndex = 0; unIndex < 33; )
  878. {
  879. iMBNumber = unStartingMB + unIndex;
  880. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY1.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + YBlockOffset;
  881. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY2.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + YBlockOffset+8;
  882. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY3.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + YBlockOffset+PITCH*8;
  883. (EC->pU8_MBlockActionStream[iMBNumber]).BlkY4.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + YBlockOffset+PITCH*8+8;
  884. (EC->pU8_MBlockActionStream[iMBNumber]).BlkU.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + UBlockOffset;
  885. (EC->pU8_MBlockActionStream[iMBNumber]).BlkV.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + UBlockOffset+UV_OFFSET;
  886. YBlockOffset += 16;
  887. UBlockOffset += 8;
  888. unIndex++;
  889. if (11 == unIndex || 22 == unIndex)
  890. {
  891. /* skip to the next row of macro blocks
  892. * - skip forward number of lines in a MB and back 11 macroblocks
  893. */
  894. YBlockOffset += PITCH*16 - 11*16;
  895. UBlockOffset += PITCH*8 - 11*8;
  896. }
  897. } /* end for unIndex */
  898. } /* end for uGOBNumber */
  899. } /* end ! bUseMotionEstimation */
  900. /* Initialize bit rate controller
  901. */
  902. // RTP: BRC initialization. Changed call to InitBRC to accomodate
  903. // uIntraQP and uInterQP
  904. if(pConfiguration->bEncoderResiliency && pConfiguration->unPacketLoss)
  905. {
  906. uIntraQP = pConfiguration->unDefaultIntraQuant;
  907. uInterQP = pConfiguration->unDefaultInterQuant;
  908. }
  909. else
  910. {
  911. uIntraQP = EC->u8DefINTRA_QP; //def263INTRA_QP;
  912. uInterQP = EC->u8DefINTER_QP; //def263INTER_QP;
  913. }
  914. InitBRC(&(EC->BRCState), /* Address of the state structure */
  915. uIntraQP, //EC->u8DefINTRA_QP, /* default INTRA Quantization value */
  916. uInterQP, //EC->u8DefINTER_QP, /* default INTER Quantization value */
  917. EC->NumMBs); /* number of Macroblocks */
  918. // RTP: initialize BSInfoStream for RTP header generation
  919. if (pConfiguration->bRTPHeader)
  920. {
  921. H261RTP_InitBsInfoStream(EC, pConfiguration->unPacketSize);
  922. }
  923. /* Finished initializing the encoder
  924. */
  925. lpCompInst->Initialized = TRUE;
  926. /*
  927. * Create a decoder instance and init it. DecoderInstInfo must be in first 64K.
  928. */
  929. EC->pDecInstanceInfo->xres = lpCompInst->xres;
  930. EC->pDecInstanceInfo->yres = lpCompInst->yres;
  931. lResult = H263InitDecoderInstance(EC->pDecInstanceInfo, H263_CODEC);
  932. if (lResult != ICERR_OK)
  933. {
  934. DBOUT("Encoder's call to init the decoder failed.");
  935. goto done;
  936. }
  937. lResult = H263InitColorConvertor(EC->pDecInstanceInfo, YUV12ForEnc);
  938. if (lResult != ICERR_OK)
  939. {
  940. DBOUT("Encoder's call to init the color converter failed.");
  941. goto done;
  942. }
  943. lResult = ICERR_OK;
  944. done:
  945. if (bEncoderInstLocked)
  946. {
  947. GlobalUnlock(lpCompInst->hEncoderInst);
  948. }
  949. return lResult;
  950. } /* end H263InitEncoderInstance() */
  951. // Define a variety of parameters to be used with motion estimation.
  952. T_MotionEstimationControls MECatalog[] = {
  953. #define ME_DEFAULT_CTRLS 0
  954. { 300, 128, 20, 150, 100, 100, 50 },
  955. #define ME_MMX_CTRLS 1
  956. // These parameters are used when MMX is enabled.
  957. // NOTE: Of these, only the SLF parameters are currently used.
  958. // For MMX, the other parameters are hard coded in exmme.asm.
  959. { 300, 128, 20, 150, 100, 200, 100 },
  960. #define ME_CUSTOM_CTRLS 2
  961. // These parameters are used when EC->bUseCustomMotionEstimation is enabled.
  962. // EC-bUseCustomMotionEstimation, and the individual values here, can be
  963. // set via the "ini" file.
  964. { 300, 128, 20, 150, 100, 100, 50 }
  965. };
  966. const U32 MAXCIFSIZE = 32768;
  967. const U32 MAXQCIFSIZE = 8192;
  968. /*****************************************************************************
  969. *
  970. * H263Compress
  971. *
  972. * This function drives the compression of one frame
  973. *
  974. */
  975. LRESULT H263Compress(
  976. LPCODINST lpCompInst, /* ptr to compressor instance info. */
  977. ICCOMPRESS *lpicComp) /* ptr to ICCOMPRESS structure. */
  978. {
  979. FX_ENTRY("H261Compress");
  980. LRESULT lResult = ICERR_ERROR;
  981. U32 uGOBNumber;
  982. U32 uMB;
  983. U8 * pu8CurBitStream; /* pointer to the current location in the bitstream. */
  984. U32 * puGOBNumbers;
  985. UN unGQuant;
  986. UN unLastEncodedGQuant;
  987. UN unSizeBitStream;
  988. U32 uMaxSizeBitStream;
  989. // UN unSize;
  990. UN unStartingMB;
  991. U8 u8BitOffset; /* bit offset in the current byte of the bitstream. */
  992. /* Variables used in recompression */
  993. BOOL bOverFlowWarning = FALSE;
  994. BOOL bOverFlowSevereWarning = FALSE;
  995. BOOL bOverFlowSevereDanger = FALSE;
  996. BOOL bOverFlowed = FALSE;
  997. U32 u32AverageSize;
  998. U32 u32sizeBitBuffer;
  999. U32 u32TooBigSize;
  1000. UN unGQuantTmp;
  1001. U8 u8GOBcount;
  1002. U32 iSWD;
  1003. U32 uMAXGOBNumber, uGOBsLeft;
  1004. /* save state for if need to recompress last GOB */
  1005. U8 * pu8CurBitStreamSave; /* ptr to the curr location in the bitstream. */
  1006. U8 u8BitOffsetSave; /* bit offset in the curr byte of the bitstream. */
  1007. UN unStartingMBSave;
  1008. UN unGQuantSave;
  1009. U8 u8CodedBlockSave[33];
  1010. U8 u8blocknum;
  1011. U8 * pu8FirstInterMEStateRowNumbers;
  1012. int inRowNumber;
  1013. int inMEStateIndex;
  1014. U32 uCumFrmSize = 0;
  1015. U32 uFrameCount;
  1016. U8 *pU8_temp; /* dummy pointer needed for FDCT */
  1017. U8 u8_temp; /* dummy variable needed for FDCT */
  1018. #ifdef ENCODE_STATS
  1019. U32 uStartLow;
  1020. U32 uStartHigh;
  1021. U32 uElapsed;
  1022. U32 uBefore;
  1023. U32 uEncodeFrameSum = 0;
  1024. U32 uInputCCSum = 0;
  1025. U32 uMotionEstimationSum = 0;
  1026. U32 uFDCTSum = 0;
  1027. U32 uQRLESum = 0;
  1028. U32 uDecodeFrameSum = 0;
  1029. U32 uZeroingBufferSum = 0;
  1030. // U32 uSLF_UVSum = 0;
  1031. int bTimingThisFrame = 0;
  1032. ENC_TIMING_INFO * pEncTimingInfo = NULL;
  1033. #endif
  1034. U32 uIntraSWDTotal;
  1035. U32 uIntraSWDBlocks;
  1036. U32 uInterSWDTotal;
  1037. U32 uInterSWDBlocks;
  1038. int MEC_index;
  1039. T_MotionEstimationControls MEC;
  1040. float fFrameRate;
  1041. U32 uFrameSize;
  1042. U32 uQuality;
  1043. T_H263EncoderInstanceMemory * P32Inst;
  1044. T_H263EncoderCatalog * EC;
  1045. LPVOID pEncoderInst = NULL;
  1046. ENC_BITSTREAM_INFO * pBSInfo;
  1047. ICDECOMPRESSEX ICDecExSt;
  1048. static ICDECOMPRESSEX DefaultICDecExSt = {
  1049. 0,
  1050. NULL, NULL,
  1051. NULL, NULL,
  1052. 0, 0, 0, 0,
  1053. 0, 0, 0, 0
  1054. };
  1055. int uPQUANTMin;
  1056. // RTP: declaration
  1057. T_CONFIGURATION *pConfiguration = &(lpCompInst->Configuration);
  1058. #ifdef CHECKSUM_PICTURE
  1059. YVUCheckSum YVUCheckSumStruct;
  1060. U8 * pu8SaveCurBitStream;
  1061. U8 u8SaveBitOffset;
  1062. #endif
  1063. // check instance pointer
  1064. if (!lpCompInst)
  1065. return ICERR_ERROR;
  1066. /********************************************************************
  1067. * Lock the instance data private to the encoder.
  1068. ********************************************************************/
  1069. pEncoderInst = (LPVOID)GlobalLock(lpCompInst->hEncoderInst);
  1070. if (pEncoderInst == NULL)
  1071. {
  1072. DBOUT("ERROR :: H263Compress :: ICERR_MEMORY");
  1073. lResult = ICERR_MEMORY;
  1074. goto done;
  1075. }
  1076. /* Generate pointer to the encoder instance memory.
  1077. */
  1078. P32Inst = (T_H263EncoderInstanceMemory *)
  1079. ((((U32) lpCompInst->EncoderInst) +
  1080. (sizeof(T_MBlockActionStream) - 1)) &
  1081. ~(sizeof(T_MBlockActionStream) - 1));
  1082. /* Get pointer to encoder catalog.
  1083. */
  1084. EC = &(P32Inst->EC);
  1085. // Check pointer to encoder catalog
  1086. if (!EC)
  1087. return ICERR_ERROR;
  1088. pBSInfo = &EC->BSInfo;
  1089. /********************************************************************
  1090. * Dummy operations.
  1091. ********************************************************************/
  1092. pU8_temp = &u8_temp;
  1093. /********************************************************************
  1094. * Do per-frame initialization.
  1095. ********************************************************************/
  1096. /* Get the frame number
  1097. */
  1098. uFrameCount = pBSInfo->uKeyFrameCount + pBSInfo->uDeltaFrameCount;
  1099. #ifdef ENCODE_STATS
  1100. if (uFrameCount < DEC_TIMING_INFO_FRAME_COUNT)
  1101. {
  1102. ASSERT(EC->pEncTimingInfo);
  1103. TIMER_START(bTimingThisFrame,uStartLow,uStartHigh);
  1104. ASSERT(bTimingThisFrame);
  1105. EC->uStartLow = uStartLow;
  1106. EC->uStartHigh = uStartHigh;
  1107. EC->uStatFrameCount = uFrameCount;
  1108. }
  1109. else
  1110. {
  1111. ASSERT(!bTimingThisFrame);
  1112. }
  1113. EC->bTimingThisFrame = bTimingThisFrame;
  1114. #endif
  1115. if((lpicComp->dwFlags & ICCOMPRESS_KEYFRAME) ||
  1116. (EC->bMakeNextFrameKey == TRUE))
  1117. {
  1118. EC->PictureHeader.PicCodType = INTRAPIC;
  1119. EC->bMakeNextFrameKey = FALSE;
  1120. EC->PictureHeader.PicFreeze = ON;
  1121. }
  1122. else
  1123. {
  1124. EC->PictureHeader.PicCodType = INTERPIC;
  1125. EC->PictureHeader.PicFreeze = OFF;
  1126. DBOUT("INTERPIC...")
  1127. }
  1128. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1129. {
  1130. /* Initialize macroblocks action stream for INTRA
  1131. */
  1132. for (uMB = 0; uMB < EC->NumMBs; uMB++)
  1133. {
  1134. (EC->pU8_MBlockActionStream[uMB]).CodedBlocks |= 0x3F; /* Set to all nonempty blocks. */
  1135. (EC->pU8_MBlockActionStream[uMB]).CodedBlocksB = 0;
  1136. (EC->pU8_MBlockActionStream[uMB]).InterCodeCnt = ((U8)uMB)&0xF; /* Seed update pattern */
  1137. (EC->pU8_MBlockActionStream[uMB]).FirstMEState = ForceIntra;
  1138. if (! EC->bUseMotionEstimation)
  1139. {
  1140. (EC->pU8_MBlockActionStream[uMB]).BlockType = INTRABLOCK;
  1141. }
  1142. }
  1143. *(lpicComp->lpdwFlags) |= AVIIF_KEYFRAME;
  1144. lpicComp->dwFlags |= ICCOMPRESS_KEYFRAME;
  1145. }
  1146. else // not a key frame, motion vectors present
  1147. {
  1148. /* Setup to initialize the FirstMEState field. The initial data for
  1149. * the FirstMEState is stored compressed in rows of 11 bytes. Different
  1150. * rows are chosen for CIF and QCIF initialization.
  1151. */
  1152. if ( EC->PictureHeader.SourceFormat == SF_CIF )
  1153. {
  1154. pu8FirstInterMEStateRowNumbers = u8CIFFirstInterMEStateRowNumbers;
  1155. }
  1156. else
  1157. {
  1158. pu8FirstInterMEStateRowNumbers = u8QCIFFirstInterMEStateRowNumbers;
  1159. }
  1160. inRowNumber = *pu8FirstInterMEStateRowNumbers++;
  1161. ASSERT(inRowNumber <= MAX_ME_STATE_ROW_NUMBER);
  1162. /* Initialize macroblocks action stream for INTER
  1163. */
  1164. for (inMEStateIndex = 0, uMB = 0; uMB < EC->NumMBs; uMB++, inMEStateIndex++)
  1165. {
  1166. /* There are only 11 bytes in a row of data. So reset the Index and go to
  1167. * the next row number.
  1168. */
  1169. if (inMEStateIndex == 11)
  1170. {
  1171. inMEStateIndex = 0;
  1172. inRowNumber = *pu8FirstInterMEStateRowNumbers++;
  1173. ASSERT(inRowNumber <= MAX_ME_STATE_ROW_NUMBER);
  1174. }
  1175. (EC->pU8_MBlockActionStream[uMB]).CodedBlocks |= 0x3F; /* Initialize to all nonempty blocks. */
  1176. (EC->pU8_MBlockActionStream[uMB]).CodedBlocksB = 0;
  1177. if (EC->pU8_MBlockActionStream[uMB].InterCodeCnt >=
  1178. (pConfiguration->bRTPHeader
  1179. ? INTERCODECNT_ADJUST[pConfiguration->unPacketLoss/10]
  1180. : 132))
  1181. {
  1182. (EC->pU8_MBlockActionStream[uMB]).FirstMEState = ForceIntra; /* Force intra blocks. */
  1183. (EC->pU8_MBlockActionStream[uMB]).BlockType = INTRABLOCK;
  1184. }
  1185. else
  1186. { // RTP: resiliency stuff
  1187. if (pConfiguration->bDisallowAllVerMVs)
  1188. (EC->pU8_MBlockActionStream[uMB]).FirstMEState =
  1189. u8FirstInterMENoVerMVStateRows[inRowNumber][inMEStateIndex];
  1190. else
  1191. {
  1192. if (pConfiguration->bDisallowPosVerMVs)
  1193. (EC->pU8_MBlockActionStream[uMB]).FirstMEState =
  1194. u8FirstInterMENoPosVerMVStateRows[inRowNumber][inMEStateIndex];
  1195. else
  1196. (EC->pU8_MBlockActionStream[uMB]).FirstMEState =
  1197. u8FirstInterMEStateRows[inRowNumber][inMEStateIndex];
  1198. }
  1199. if (! EC->bUseMotionEstimation)
  1200. {
  1201. (EC->pU8_MBlockActionStream[uMB]).BlockType = INTERBLOCK;
  1202. }
  1203. }
  1204. }
  1205. *(lpicComp->lpdwFlags) &= ~AVIIF_KEYFRAME;
  1206. lpicComp->dwFlags &= ~ICCOMPRESS_KEYFRAME;
  1207. }
  1208. // RTP: resiliency stuff
  1209. if (pConfiguration->bEncoderResiliency && pConfiguration->unPacketLoss)
  1210. {
  1211. UN i;
  1212. if (EC->uNumberForcedIntraMBs > 0)
  1213. {
  1214. for (i=0; i < EC->uNumberForcedIntraMBs; i++)
  1215. {
  1216. if (EC->uNextIntraMB == EC->NumMBs)
  1217. EC->uNextIntraMB=0;
  1218. (EC->pU8_MBlockActionStream[EC->uNextIntraMB]).FirstMEState =
  1219. ForceIntra;
  1220. if (! EC->bUseMotionEstimation)
  1221. {
  1222. (EC->pU8_MBlockActionStream[uMB]).BlockType = INTRABLOCK;
  1223. }
  1224. }
  1225. }
  1226. }
  1227. /* Initialize bit stream pointers */
  1228. pu8CurBitStream = EC->pU8_BitStream;
  1229. u8BitOffset = 0;
  1230. /******************************************************************
  1231. * RGB to YVU 12 Conversion
  1232. ******************************************************************/
  1233. #ifdef ENCODE_STATS
  1234. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1235. #endif
  1236. colorCnvtFrame(EC, lpCompInst, lpicComp,
  1237. EC->pU8_CurrFrm_YPlane,
  1238. EC->pU8_CurrFrm_UPlane,
  1239. EC->pU8_CurrFrm_VPlane);
  1240. #ifdef ENCODE_STATS
  1241. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uInputCCSum)
  1242. #endif
  1243. /********************************************************************
  1244. * Setup the bit rate controller
  1245. ********************************************************************/
  1246. // RTP: Configuration setting
  1247. // If the Encoder Bit Rate section of the configuration has been
  1248. // set ON then, we override quality only or any frame size normally
  1249. // sent in and use frame rate and data rate to determine frame
  1250. // size.
  1251. if (EC->PictureHeader.PicCodType == INTERPIC &&
  1252. lpCompInst->Configuration.bBitRateState == TRUE &&
  1253. lpCompInst->FrameRate != 0.0f &&
  1254. lpicComp->dwFrameSize == 0UL)
  1255. {
  1256. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Changing dwFrameSize from %ld to %ld bits\r\n", _fx_, lpicComp->dwFrameSize << 3, (DWORD)((float)lpCompInst->DataRate / lpCompInst->FrameRate) << 3));
  1257. lpicComp->dwFrameSize = (U32)((float)lpCompInst->DataRate / lpCompInst->FrameRate);
  1258. }
  1259. uFrameSize = lpicComp->dwFrameSize;
  1260. #ifdef DEBUG_RECOMPRESS
  1261. wsprintf(string, "uFrameSize %d", (int) uFrameSize);
  1262. DBOUT(string);
  1263. #endif
  1264. /* check uFrameSize. Max compressed frame size for QCIF is 8KBytes
  1265. * and 32 KBytes for FCIF.
  1266. */
  1267. if ( EC->PictureHeader.SourceFormat == SF_CIF )
  1268. {
  1269. uMaxSizeBitStream = MAXCIFSIZE;
  1270. if (uFrameSize > MAXCIFSIZE)
  1271. uFrameSize = MAXCIFSIZE;
  1272. }
  1273. else
  1274. {
  1275. uMaxSizeBitStream = MAXQCIFSIZE;
  1276. if (uFrameSize > MAXQCIFSIZE)
  1277. uFrameSize = MAXQCIFSIZE;
  1278. }
  1279. #ifdef DEBUG_RECOMPRESS
  1280. wsprintf(string, "uFrameSize %d", (int) uFrameSize);
  1281. DBOUT(string);
  1282. #endif
  1283. uQuality = lpicComp->dwQuality;
  1284. fFrameRate = lpCompInst->FrameRate;
  1285. StartupBRC(EC, uFrameSize, uQuality, fFrameRate);
  1286. /* QRLE does not do clamping - it passes 8-bits to VLC. Because of
  1287. * that we need to be sure that all values can be represented by 255.
  1288. * QP-4 represents +-2040 leaving out 2041..2048.
  1289. * QP-5 represents +-2550 which has no clamping problems.
  1290. * Because QRLE does not do clamping we should limit our QP to 5.
  1291. * But I still see some clamping artifacts at 5. See the "Tom" video
  1292. * encoded with a fixed quantizer at frame 100. For that reason I
  1293. * am limiting my QP to 6 (which is the same value as the 750 encoder).
  1294. *
  1295. * If you had unlimited time you could look at the first four coefficients
  1296. * and pretty safely decide if you can use lower quantizers. Since we
  1297. * are supposed to run on a P5/90 we don't have that time.
  1298. */
  1299. //CLAMP_N_TO(EC->PictureHeader.PQUANT,6,31);
  1300. /* Change Clamp range to allow quant to get to 2 unless fixed quant
  1301. * or quality setting used instead of data rate. This does probably
  1302. * cause quantization errors at high data rates the question is does
  1303. * it cause noticable errors at ISDN data rates when the clips are
  1304. * playing at speed? This will be evaluated witn Beta 02 candidate.
  1305. * Changes made in e1enc and e1mbenc.
  1306. */
  1307. if (EC->BRCState.uTargetFrmSize == 0)
  1308. {
  1309. CLAMP_N_TO(EC->PictureHeader.PQUANT,6,31);
  1310. }
  1311. else
  1312. {
  1313. uPQUANTMin = clampQP((10000L - (int)lpicComp->dwQuality) * 15L / 10000L);
  1314. CLAMP_N_TO(EC->PictureHeader.PQUANT, uPQUANTMin, 31);
  1315. }
  1316. // also set previous GQuant
  1317. unLastEncodedGQuant = EC->PictureHeader.PQUANT;
  1318. if (EC->bBitRateControl)
  1319. {
  1320. /* Initialize Cumulative Quantization values
  1321. */
  1322. EC->uQP_cumulative = 0;
  1323. EC->uQP_count = 0;
  1324. }
  1325. /* Increment temporal reference.
  1326. */
  1327. #ifdef RING0
  1328. Increment_TR_UsingFrameRate(&(EC->PictureHeader.TR),
  1329. &(EC->fTR_Error),
  1330. fFrameRate,
  1331. (pBSInfo->uKeyFrameCount + pBSInfo->uDeltaFrameCount) == 0,
  1332. 0x1F);
  1333. #else
  1334. Increment_TR_UsingTemporalValue(&(EC->PictureHeader.TR),
  1335. &(EC->u8LastTR),
  1336. lpicComp->lFrameNum,
  1337. (pBSInfo->uKeyFrameCount + pBSInfo->uDeltaFrameCount) == 0,
  1338. 0x1F);
  1339. #endif
  1340. // RTP: packet initialization for first GOB
  1341. if (pConfiguration->bRTPHeader)
  1342. {
  1343. H261RTP_GOBUpdateBsInfo(EC, 1, pu8CurBitStream, 0);
  1344. }
  1345. /********************************************************************
  1346. * Write the Picture Header
  1347. *******************************************************************/
  1348. WriteBeginPictureHeaderToStream(EC, &pu8CurBitStream, &u8BitOffset);
  1349. #ifdef CHECKSUM_PICTURE
  1350. /* Initialize the checksum record to all zeros.
  1351. */
  1352. YVUCheckSumStruct.uYCheckSum = 0;
  1353. YVUCheckSumStruct.uVCheckSum = 0;
  1354. YVUCheckSumStruct.uUCheckSum = 0;
  1355. /* save the pointers
  1356. */
  1357. pu8SaveCurBitStream = pu8CurBitStream;
  1358. u8SaveBitOffset = u8BitOffset;
  1359. /* write the zero checksum
  1360. */
  1361. WritePictureChecksum(&YVUCheckSumStruct, &pu8CurBitStream, &u8BitOffset, 0);
  1362. #endif
  1363. WriteEndPictureHeaderToStream(EC, &pu8CurBitStream, &u8BitOffset);
  1364. /********************************************************************
  1365. * Inner Loop: Loop through GOBs and macroblocks.
  1366. ********************************************************************/
  1367. puGOBNumbers = ( EC->PictureHeader.SourceFormat == SF_CIF ) ? uCIFGOBNumbers : uQCIFGOBNumbers;
  1368. uMAXGOBNumber = ( EC->PictureHeader.SourceFormat == SF_CIF ) ? 12 : 3;
  1369. u32sizeBitBuffer = CompressGetSize(lpCompInst, lpicComp->lpbiInput,
  1370. lpicComp->lpbiOutput);
  1371. /* Check to see if we told VfW to create a buffer smaller than the maximum allowable.
  1372. */
  1373. ASSERT( u32sizeBitBuffer <= sizeof_bitstreambuf );
  1374. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1375. {
  1376. u32AverageSize =
  1377. (EC->PictureHeader.SourceFormat == SF_CIF ) ?
  1378. (7 * u32sizeBitBuffer/FCIF_NUM_OF_GOBS) >> 3:
  1379. (7 * u32sizeBitBuffer/QCIF_NUM_OF_GOBS) >> 3;
  1380. }
  1381. else
  1382. {
  1383. u32AverageSize =
  1384. (EC->PictureHeader.SourceFormat == SF_CIF ) ?
  1385. (8 * u32sizeBitBuffer/FCIF_NUM_OF_GOBS) >> 4:
  1386. (8 * u32sizeBitBuffer/QCIF_NUM_OF_GOBS) >> 4;
  1387. }
  1388. // Select motion estimation parameters.
  1389. if (EC->bUseCustomMotionEstimation)
  1390. MEC_index = ME_CUSTOM_CTRLS;
  1391. else
  1392. MEC_index = ME_DEFAULT_CTRLS;
  1393. // Make a local copy of the controls, so that we can alter the
  1394. // controls dynamically, without destroying the original values.
  1395. MEC = MECatalog[MEC_index];
  1396. if (pConfiguration->bRTPHeader) {
  1397. MEC.empty_threshold /= EMPTYTHRESHOLD_ADJUST[pConfiguration->unPacketLoss/25];
  1398. if (pConfiguration->unPacketLoss > 25) {
  1399. MEC.zero_vector_threshold = 99999;
  1400. MEC.nonzero_MV_differential = 99999;
  1401. if ((MEC.slf_differential <<= 2) > 99999)
  1402. MEC.slf_differential = 99999;
  1403. if (pConfiguration->unPacketLoss > 50) {
  1404. MEC.slf_threshold = 99999;
  1405. }
  1406. }
  1407. }
  1408. for (uGOBNumber = *puGOBNumbers++, unStartingMB = 0, u8GOBcount = 1;
  1409. uGOBNumber != 0;
  1410. uGOBNumber = *puGOBNumbers++, unStartingMB += 33, u8GOBcount++)
  1411. {
  1412. #ifdef DEBUG_ENC
  1413. wsprintf(string, "GOB #%d", (int) uGOBNumber);
  1414. DBOUT(string);
  1415. trace(string);
  1416. #endif
  1417. uGOBsLeft = uMAXGOBNumber - u8GOBcount;
  1418. if (EC->bUseMotionEstimation)
  1419. {
  1420. #ifdef ENCODE_STATS
  1421. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1422. #endif
  1423. MOTIONESTIMATION(
  1424. &(EC->pU8_MBlockActionStream[unStartingMB]),
  1425. EC->pU8_CurrFrm_YPlane,
  1426. EC->pU8_PrevFrm_YPlane,
  1427. EC->pU8_SLFFrm_YPlane,
  1428. 1, // Do Radius 15 search.
  1429. 0, // No Half Pel motion estimation
  1430. 0, // No Block MVs
  1431. (int)EC->bUseSpatialLoopFilter,
  1432. MEC.zero_vector_threshold, // Zero Vector Threshold. If the
  1433. // SWD for the zero vector is less than this
  1434. // threshold, then don't search for NZ MV's.
  1435. // Set to 99999 to not search.
  1436. MEC.nonzero_MV_differential, // NonZeroMVDifferential.
  1437. // Once the best NZ MV is found, it must be better
  1438. // than the 0 MV SWD by at least this amount.
  1439. // Set to 99999 to never choose NZ MV.
  1440. 128, // BlockMVDifferential. The sum of the four block
  1441. // SWD must be better than the MB SWD by at least
  1442. // this amount to choose block MV's.
  1443. // H.261 don't care
  1444. MEC.empty_threshold, // Empty Threshold. Set to 0 to not force
  1445. // empty blocks.
  1446. MEC.intercoding_threshold, // Inter Coding Threshold. If the
  1447. // inter SWD is less than this amount then don't
  1448. // bother calc. the intra SWD.
  1449. MEC.intercoding_differential, // Intra Coding Differential.
  1450. // Bias against choosing INTRA blocks.
  1451. MEC.slf_threshold, // If the SWD of the chosen MV is less than
  1452. // this threshold, then don't bother investigating
  1453. // the spatial loop filtered case.
  1454. MEC.slf_differential, // If you do look at the SLF case, its
  1455. // SWD must be better than the non-SLF SWD by at
  1456. // least this much in order to select the SLF type.
  1457. &uIntraSWDTotal,
  1458. &uIntraSWDBlocks,
  1459. &uInterSWDTotal,
  1460. &uInterSWDBlocks
  1461. );
  1462. #ifdef ENCODE_STATS
  1463. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uMotionEstimationSum)
  1464. #endif
  1465. /* If it's an inter frame then, calculate chroma vectors and update the InterCodeCnt.
  1466. */
  1467. if (EC->PictureHeader.PicCodType == INTERPIC)
  1468. {
  1469. // RTP: added pConfiguration to CalcGOBChromaVecs()
  1470. CalcGOBChromaVecs(EC, unStartingMB, pConfiguration);
  1471. } /* end INTERPIC */
  1472. } /* end if UseMotionEstimation */
  1473. /* Calculate unGQuant based on bits used in previous GOBs, and bits used
  1474. * for current GOB of previous frame.
  1475. */
  1476. if (EC->bBitRateControl)
  1477. {
  1478. unGQuantTmp = unGQuant;
  1479. unGQuant = CalcMBQUANT(&(EC->BRCState), EC->uBitUsageProfile[unStartingMB],EC->uBitUsageProfile[EC->NumMBs], uCumFrmSize, EC->PictureHeader.PicCodType);
  1480. EC->uBitUsageProfile[unStartingMB] = uCumFrmSize;
  1481. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Bitrate controller enabled for GOB #%ld (uCumFrmSize = %ld bits and unGQuantTmp = %ld), setting unGQuant = %ld (min and max will truncate from %ld to 31)\r\n", _fx_, uGOBNumber, uCumFrmSize << 3, unGQuantTmp, unGQuant, uPQUANTMin));
  1482. /* if bOverFlowSevereDanger True Increase Quant */
  1483. if ( bOverFlowSevereDanger )
  1484. {
  1485. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Danger of overflow for GOB #%ld, changing unGQuant from %ld to %ld\r\n", _fx_, uGOBNumber, unGQuant, (unGQuant < unGQuantTmp) ? (unGQuantTmp + ((EC->PictureHeader.PicCodType == INTRAPIC) ? 12 : 6)) : (unGQuant + ((EC->PictureHeader.PicCodType == INTRAPIC) ? 12 : 6))));
  1486. if (unGQuant < unGQuantTmp)
  1487. unGQuant = unGQuantTmp;
  1488. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1489. unGQuant += 12;
  1490. else
  1491. unGQuant += 6;
  1492. DBOUT("Increasing GQuant increase by +6");
  1493. }
  1494. else if ( bOverFlowSevereWarning )
  1495. {
  1496. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Danger of overflow for GOB #%ld, changing unGQuant from %ld to %ld\r\n", _fx_, uGOBNumber, unGQuant, (unGQuant < unGQuantTmp) ? (unGQuantTmp + ((EC->PictureHeader.PicCodType == INTRAPIC) ? 8 : 4)) : (unGQuant + ((EC->PictureHeader.PicCodType == INTRAPIC) ? 8 : 4))));
  1497. /* if bOverFlowSevereWarning True Increase Quant */
  1498. if (unGQuant < unGQuantTmp)
  1499. unGQuant = unGQuantTmp;
  1500. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1501. unGQuant += 8;
  1502. else
  1503. unGQuant += 4;
  1504. DBOUT("Increasing GQuant increase by +4");
  1505. }
  1506. else if ( !bOverFlowWarning )
  1507. {
  1508. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Warning of overflow for GOB #%ld, changing unGQuant from %ld to %ld\r\n", _fx_, uGOBNumber, unGQuant, ((int)unGQuant > ((int)unLastEncodedGQuant + MaxChangeRowMBTbl[unGQuant])) ? (unLastEncodedGQuant + MaxChangeRowMBTbl[unGQuant]) : (((int)unGQuant < ((int)unLastEncodedGQuant - 2)) ? (unLastEncodedGQuant - 2) : unGQuant)));
  1509. /* if bOverFlowWarning False limit Quant changes */
  1510. /* Limit the quant changes */
  1511. if ((int)unGQuant > ((int)unLastEncodedGQuant + MaxChangeRowMBTbl[unGQuant]))
  1512. {
  1513. unGQuant = unLastEncodedGQuant + MaxChangeRowMBTbl[unGQuant];
  1514. DBOUT("Slowing GQuant increase to +[1-4]");
  1515. }
  1516. else if ((int)unGQuant < ((int)unLastEncodedGQuant - 2))
  1517. {
  1518. unGQuant = unLastEncodedGQuant - 2;
  1519. DBOUT("Slowing GQuant decrease to -2");
  1520. }
  1521. }
  1522. else
  1523. {
  1524. DBOUT("bOverFlowWarning don't limit Quant change");
  1525. }
  1526. if (EC->BRCState.uTargetFrmSize == 0)
  1527. {
  1528. CLAMP_N_TO(unGQuant,6,31);
  1529. }
  1530. else
  1531. {
  1532. CLAMP_N_TO(unGQuant, uPQUANTMin , 31);
  1533. }
  1534. unLastEncodedGQuant = unGQuant;
  1535. #ifdef DEBUG_BRC
  1536. wsprintf(string,"At MB %d GQuant=%d", unStartingMB, unGQuant);
  1537. DBOUT(string);
  1538. #endif
  1539. }
  1540. else
  1541. {
  1542. unGQuant = EC->PictureHeader.PQUANT;
  1543. }
  1544. if ( bOverFlowWarning )
  1545. {
  1546. /* save state may need to recompress */
  1547. pu8CurBitStreamSave = pu8CurBitStream;
  1548. u8BitOffsetSave = u8BitOffset;
  1549. unStartingMBSave = unStartingMB;
  1550. unGQuantSave = unGQuant;
  1551. for (u8blocknum = 0; u8blocknum < 33; u8blocknum++)
  1552. {
  1553. /* go through last GOBs macroblock action stream
  1554. * saving coded block type because quantization
  1555. * resets the pattern in some blocks quantize to 0.
  1556. */
  1557. u8CodedBlockSave[u8blocknum] =
  1558. (EC->pU8_MBlockActionStream[unStartingMB+u8blocknum]).CodedBlocks;
  1559. }
  1560. }
  1561. // RTP: GOB update
  1562. if ( (uGOBNumber != 1) && (pConfiguration->bRTPHeader) )
  1563. {
  1564. H261RTP_GOBUpdateBsInfo(EC, uGOBNumber, pu8CurBitStream, (U32)
  1565. u8BitOffset);
  1566. }
  1567. WriteGOBHeaderToStream(uGOBNumber, unGQuant, &pu8CurBitStream, &u8BitOffset);
  1568. /* Input is the macroblock action stream with pointers to
  1569. * current and previous blocks. Output is a set of 32 DWORDs
  1570. * containing pairs of coefficients for each block. There are
  1571. * from 0 to 12 blocks depending on if PB frames are used and
  1572. * what the CBP field states.
  1573. */
  1574. #ifdef ENCODE_STATS
  1575. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1576. #endif
  1577. FORWARDDCT( &(EC->pU8_MBlockActionStream[unStartingMB]),
  1578. EC->pU8_CurrFrm_YPlane,
  1579. EC->pU8_PrevFrm_YPlane,
  1580. 0,
  1581. EC->pU8_DCTCoefBuf,
  1582. 0, // 0 = not a B-frame
  1583. 0, // 0 = AP not on
  1584. 0, // 0 = PB?
  1585. pU8_temp, // Scratch
  1586. EC->NumMBPerRow
  1587. );
  1588. #ifdef ENCODE_STATS
  1589. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFDCTSum)
  1590. #endif
  1591. /* Input is the string of coefficient pairs output from the
  1592. * DCT routine.
  1593. */
  1594. #ifdef ENCODE_STATS
  1595. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1596. #endif
  1597. GOB_Q_RLE_VLC_WriteBS(
  1598. EC,
  1599. EC->pU8_DCTCoefBuf,
  1600. &pu8CurBitStream,
  1601. &u8BitOffset,
  1602. unStartingMB,
  1603. unGQuant,
  1604. bOverFlowSevereWarning,
  1605. (BOOL) pConfiguration->bRTPHeader, // RTP: MBUpdate flag
  1606. uGOBNumber,
  1607. uPQUANTMin);
  1608. #ifdef ENCODE_STATS
  1609. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uQRLESum)
  1610. #endif
  1611. /* Calculate number of bytes used in frame so far.
  1612. */
  1613. uCumFrmSize = pu8CurBitStream - EC->pU8_BitStream;
  1614. /* Try to make sure we won't overrun the bit stream buffer. Take the stuffing bytes
  1615. * at the end into account when you do this. Also make sure that if this GOB is not
  1616. * recompressed then there is enough space left to send SKIP GOBs for the remaining
  1617. * GOBs. I am using sizeof (SKIP GOB) = 2 bytes.
  1618. */
  1619. if ( (unsigned)uCumFrmSize >=
  1620. (u32sizeBitBuffer - (uGOBsLeft*2) - 10) )
  1621. {
  1622. /* Already about to exceed need to recompress */
  1623. DBOUT("Need to RECOMPRESS");
  1624. if ( bOverFlowWarning )
  1625. {
  1626. #ifdef DEBUG_RECOMPRESS
  1627. wsprintf(string,"Bits Used before recompress= %d ", uCumFrmSize*8);
  1628. DBOUT(string);
  1629. //trace(string);
  1630. #endif
  1631. u32TooBigSize = uCumFrmSize;
  1632. bOverFlowSevereDanger = TRUE;
  1633. /* zero out last GOBs worth of bitstream */
  1634. U8 u8temp;
  1635. u8temp = *pu8CurBitStreamSave;
  1636. u8temp = (u8temp>>(8-u8BitOffsetSave))<<(8-u8BitOffsetSave);
  1637. *pu8CurBitStreamSave = u8temp;
  1638. memset(pu8CurBitStreamSave+1, 0, pu8CurBitStream - pu8CurBitStreamSave);
  1639. /* restore state */
  1640. pu8CurBitStream = pu8CurBitStreamSave;
  1641. u8BitOffset = u8BitOffsetSave;
  1642. unStartingMB = unStartingMBSave;
  1643. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1644. unGQuant = unGQuantSave + 16;
  1645. else
  1646. unGQuant = unGQuantSave + 8;
  1647. CLAMP_N_TO(unGQuant,6,31);
  1648. // RTP: rewind operation
  1649. if (pConfiguration->bRTPHeader)
  1650. H261RTP_RewindBsInfoStream(EC, (U32) uGOBNumber);
  1651. for (u8blocknum = 0; u8blocknum < 33; u8blocknum++)
  1652. {
  1653. /* go through GOBs macroblock action stream
  1654. * restoring coded block type because quantization
  1655. * resets the patter in some blocks quantize to 0.
  1656. */
  1657. (EC->pU8_MBlockActionStream[unStartingMB+u8blocknum]).CodedBlocks = u8CodedBlockSave[u8blocknum];
  1658. }
  1659. /* rewrite GOB header */
  1660. WriteGOBHeaderToStream(uGOBNumber, unGQuant, &pu8CurBitStream, &u8BitOffset);
  1661. GOB_Q_RLE_VLC_WriteBS(
  1662. EC,
  1663. EC->pU8_DCTCoefBuf,
  1664. &pu8CurBitStream,
  1665. &u8BitOffset,
  1666. unStartingMB,
  1667. unGQuant,
  1668. bOverFlowSevereDanger,
  1669. pConfiguration->bRTPHeader, // RTP: switch
  1670. uGOBNumber, // RTP: info
  1671. uPQUANTMin);
  1672. /* test if still too big if so just send skip GOB */
  1673. /* For intended KEY frames, this is a problem */
  1674. uCumFrmSize = pu8CurBitStream - EC->pU8_BitStream;
  1675. if ( (unsigned) uCumFrmSize >=
  1676. (u32sizeBitBuffer - (uGOBsLeft*2) - 10) )
  1677. {
  1678. bOverFlowed = TRUE;
  1679. /* zero out last GOBs worth of bitstream */
  1680. u8temp = *pu8CurBitStreamSave;
  1681. u8temp = (u8temp>>(8-u8BitOffsetSave))<<(8-u8BitOffsetSave);
  1682. *pu8CurBitStreamSave = u8temp;
  1683. memset(pu8CurBitStreamSave+1, 0, pu8CurBitStream - pu8CurBitStreamSave);
  1684. /* restore state */
  1685. pu8CurBitStream = pu8CurBitStreamSave;
  1686. u8BitOffset = u8BitOffsetSave;
  1687. unStartingMB = unStartingMBSave;
  1688. // unGQuant = unGQuantSave + 8;
  1689. // RTP: rewind operation
  1690. if (pConfiguration->bRTPHeader)
  1691. H261RTP_RewindBsInfoStream(EC, (U32) uGOBNumber);
  1692. WriteGOBHeaderToStream(uGOBNumber, unGQuant, &pu8CurBitStream, &u8BitOffset);
  1693. /* write out a stuffing code */
  1694. PutBits(FIELDVAL_MBA_STUFFING, FIELDLEN_MBA_STUFFING, &pu8CurBitStream, &u8BitOffset);
  1695. DBOUT("Just Sent SKIP GOB");
  1696. #ifdef DEBUG_RECOMPRESS
  1697. wsprintf(string,"Just Sent SKIP GOB");
  1698. //trace(string);
  1699. #endif
  1700. }
  1701. }
  1702. else
  1703. {
  1704. DBOUT("Did not save state to recompress");
  1705. }
  1706. }
  1707. /* Calculate number of bytes used in frame so far.
  1708. */
  1709. uCumFrmSize = pu8CurBitStream - EC->pU8_BitStream;
  1710. #ifdef DEBUG_RECOMPRESS
  1711. wsprintf(string,"Bits Used = %d ", uCumFrmSize*8);
  1712. DBOUT(string);
  1713. //trace(string);
  1714. #endif
  1715. /* Check to make sure we haven't overrun the bit stream buffer.
  1716. */
  1717. ASSERT( (unsigned) uCumFrmSize < u32sizeBitBuffer );
  1718. /* Setup method to determine if might have a problem with buffer size */
  1719. bOverFlowWarning =
  1720. bOverFlowSevereWarning =
  1721. bOverFlowSevereDanger = FALSE;
  1722. if (uCumFrmSize > u8GOBcount*u32AverageSize)
  1723. {
  1724. /* allow for more Quant level changes */
  1725. bOverFlowWarning = TRUE;
  1726. if (uCumFrmSize > u8GOBcount*u32AverageSize + (u32AverageSize>>1))
  1727. {
  1728. /* force Quant level increase */
  1729. bOverFlowSevereWarning = TRUE;
  1730. DBOUT("bOverFlowSevereWarning");
  1731. if (uCumFrmSize > u8GOBcount*u32AverageSize+u32AverageSize)
  1732. {
  1733. /* force Quant level increase by even more */
  1734. bOverFlowSevereDanger = TRUE;
  1735. DBOUT("bOverFlowSevereDanger");
  1736. }
  1737. }
  1738. }
  1739. } /* for uGOBNumber */
  1740. /* if recompress failed shove big number in here */
  1741. if (bOverFlowed)
  1742. {
  1743. /* used max size so quant will go up for next frame */
  1744. EC->uBitUsageProfile[unStartingMB] = u32TooBigSize;
  1745. }
  1746. else
  1747. EC->uBitUsageProfile[unStartingMB] = uCumFrmSize;
  1748. /* Make sure we end this frame on a byte boundary - some decoders require this.
  1749. */
  1750. while (u8BitOffset != 0)
  1751. {
  1752. PutBits(FIELDVAL_MBA_STUFFING, FIELDLEN_MBA_STUFFING, &pu8CurBitStream, &u8BitOffset);
  1753. }
  1754. /* Add extra DWORD of zero's to try and get rid of green blocks akk */
  1755. /* 16 bits of zeros seems to work */
  1756. /* 8 bits of zeros does not seems to work */
  1757. #ifdef DWORD_HACK
  1758. PutBits(0x0000, 16, &pu8CurBitStream, &u8BitOffset);
  1759. #endif
  1760. if (EC->bBitRateControl)
  1761. {
  1762. CalculateQP_mean(EC);
  1763. }
  1764. /********************************************************************
  1765. * Calculate the size of the compressed image.
  1766. ********************************************************************/
  1767. unSizeBitStream = pu8CurBitStream - EC->pU8_BitStream;
  1768. lpCompInst->CompressedSize = unSizeBitStream;
  1769. // IP + UDP + RTP + payload mode C header - worst case
  1770. #define TRANSPORT_HEADER_SIZE (20 + 8 + 12 + 12)
  1771. DWORD dwTransportOverhead;
  1772. // Estimate the transport overhead
  1773. if (pConfiguration->bRTPHeader)
  1774. dwTransportOverhead = (lpCompInst->CompressedSize / pConfiguration->unPacketSize + 1) * TRANSPORT_HEADER_SIZE;
  1775. else
  1776. dwTransportOverhead = 0UL;
  1777. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1778. {
  1779. #ifdef _DEBUG
  1780. wsprintf(string, "Intra Frame %d size: %d", pBSInfo->uKeyFrameCount + pBSInfo->uDeltaFrameCount, unSizeBitStream);
  1781. #endif
  1782. pBSInfo->uKeyFrameCount ++;
  1783. pBSInfo->uTotalKeyBytes += unSizeBitStream;
  1784. if (EC->bBitRateControl)
  1785. {
  1786. EC->BRCState.uLastINTRAFrmSz = dwTransportOverhead + unSizeBitStream;
  1787. }
  1788. }
  1789. else
  1790. {
  1791. #ifdef _DEBUG
  1792. wsprintf(string, "Inter Frame %d size: %d", pBSInfo->uKeyFrameCount + pBSInfo->uDeltaFrameCount, unSizeBitStream);
  1793. #endif
  1794. pBSInfo->uDeltaFrameCount ++;
  1795. pBSInfo->uTotalDeltaBytes += unSizeBitStream;
  1796. if (EC->bBitRateControl)
  1797. {
  1798. EC->BRCState.uLastINTERFrmSz = dwTransportOverhead + unSizeBitStream;
  1799. }
  1800. }
  1801. #ifdef _DEBUG
  1802. DBOUT(string)
  1803. #endif
  1804. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Total cumulated frame size = %ld bits (data: %ld, transport overhead: %ld)\r\n", _fx_, (unSizeBitStream + dwTransportOverhead) << 3, unSizeBitStream << 3, dwTransportOverhead << 3));
  1805. /********************************************************************
  1806. * Run the decoder on this frame, to get next basis for prediction.
  1807. ********************************************************************/
  1808. ICDecExSt = DefaultICDecExSt;
  1809. ICDecExSt.lpSrc = EC->pU8_BitStream;
  1810. ICDecExSt.lpbiSrc = lpicComp->lpbiOutput;
  1811. ICDecExSt.lpbiSrc->biSizeImage = unSizeBitStream;
  1812. ICDecExSt.lpDst = P32Inst->u8PreviousPlane;
  1813. ICDecExSt.lpbiDst = NULL;
  1814. if (EC->PictureHeader.PicCodType == INTERPIC)
  1815. {
  1816. ICDecExSt.dwFlags = ICDECOMPRESS_NOTKEYFRAME;
  1817. }
  1818. #ifdef ENCODE_STATS
  1819. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1820. #endif
  1821. lResult = H263Decompress (EC->pDecInstanceInfo, (ICDECOMPRESSEX FAR *)&ICDecExSt, FALSE);
  1822. if (lResult != ICERR_OK)
  1823. {
  1824. DBOUT("Encoder's call to decompress failed.");
  1825. EC->bMakeNextFrameKey = TRUE;
  1826. goto done;
  1827. }
  1828. #ifdef ENCODE_STATS
  1829. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uDecodeFrameSum)
  1830. #endif
  1831. #ifdef CHECKSUM_PICTURE
  1832. lResult = H261PictureCheckSumEntry(EC->pDecInstanceInfo, &YVUCheckSumStruct);
  1833. if (lResult != ICERR_OK)
  1834. {
  1835. DBOUT("Encoder's call to compute the picture checksum failed.");
  1836. goto done;
  1837. }
  1838. /* restore the pointers
  1839. */
  1840. pu8CurBitStream = pu8SaveCurBitStream;
  1841. u8BitOffset = u8SaveBitOffset;
  1842. /* update the checksum
  1843. */
  1844. WritePictureChecksum(&YVUCheckSumStruct, &pu8CurBitStream, &u8BitOffset, 1);
  1845. #endif
  1846. if (unSizeBitStream > uMaxSizeBitStream)
  1847. {
  1848. // Exceeded allowed - 8K for QCIF and 32K for CIF - size
  1849. DBOUT("BS exceeds allowed size");
  1850. EC->bMakeNextFrameKey = TRUE;
  1851. goto done;
  1852. }
  1853. // RTP: bstream extension attachment
  1854. if (pConfiguration->bRTPHeader)
  1855. {
  1856. // Changed this if statement to check for overflow of bitstream buffer
  1857. // 4/14/97 AG.
  1858. U32 uEBSSize = H261RTP_GetMaxBsInfoStreamSize(EC);
  1859. if (uEBSSize + unSizeBitStream <= u32sizeBitBuffer)
  1860. {
  1861. unSizeBitStream +=
  1862. (WORD) H261RTP_AttachBsInfoStream(EC, (U8 *)EC->pU8_BitStream,
  1863. unSizeBitStream);
  1864. lpCompInst->CompressedSize = unSizeBitStream;
  1865. }
  1866. else
  1867. {
  1868. DBOUT("BS+EBS exceeds allocated buffer size");
  1869. EC->bMakeNextFrameKey = TRUE;
  1870. goto done;
  1871. }
  1872. }
  1873. #ifndef RING0
  1874. #ifdef DEBUG
  1875. {
  1876. char buf[60];
  1877. wsprintf(buf, "Compressed frame is %d bytes\n", unSizeBitStream);
  1878. DBOUT(buf);
  1879. }
  1880. #endif
  1881. #endif
  1882. /********************************************************************
  1883. * Copy the compressed image to the output area. This is done after
  1884. * possibly updating the picture checksum.
  1885. ********************************************************************/
  1886. memcpy( lpicComp->lpOutput, EC->pU8_BitStream, unSizeBitStream);
  1887. /* zero only the dirty part of the bitstream buffer */
  1888. #ifdef ENCODE_STATS
  1889. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1890. #endif
  1891. // unSize = CompressGetSize(lpCompInst, lpicComp->lpbiInput, lpicComp->lpbiOutput);
  1892. memset(EC->pU8_BitStream, 0, unSizeBitStream);
  1893. #ifdef ENCODE_STATS
  1894. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uZeroingBufferSum)
  1895. #endif
  1896. #ifdef ENCODE_STATS
  1897. TIMER_STOP(bTimingThisFrame,uStartLow,uStartHigh,uEncodeFrameSum);
  1898. if (bTimingThisFrame)
  1899. {
  1900. pEncTimingInfo = EC->pEncTimingInfo + uFrameCount;
  1901. pEncTimingInfo->uEncodeFrame = uEncodeFrameSum;
  1902. pEncTimingInfo->uInputCC = uInputCCSum;
  1903. pEncTimingInfo->uMotionEstimation = uMotionEstimationSum;
  1904. pEncTimingInfo->uFDCT = uFDCTSum;
  1905. pEncTimingInfo->uQRLE = uQRLESum;
  1906. pEncTimingInfo->uDecodeFrame = uDecodeFrameSum;
  1907. pEncTimingInfo->uZeroingBuffer = uZeroingBufferSum;
  1908. // pEncTimingInfo->uSLF_UV = uSLF_UVSum;
  1909. /* Verify that we have time for all the required steps
  1910. */
  1911. ASSERT(pEncTimingInfo->uEncodeFrame);
  1912. ASSERT(pEncTimingInfo->uInputCC);
  1913. ASSERT(pEncTimingInfo->uMotionEstimation);
  1914. ASSERT(pEncTimingInfo->uFDCT);
  1915. ASSERT(pEncTimingInfo->uQRLE);
  1916. ASSERT(pEncTimingInfo->uDecodeFrame);
  1917. ASSERT(pEncTimingInfo->uZeroingBuffer);
  1918. // ASSERT(pEncTimingInfo->uSLF_UV);
  1919. }
  1920. #endif
  1921. lResult = ICERR_OK;
  1922. done:
  1923. if (pEncoderInst)
  1924. {
  1925. GlobalUnlock(lpCompInst->hEncoderInst);
  1926. }
  1927. return lResult;
  1928. } /* end H263Compress() */
  1929. /*****************************************************************************
  1930. *
  1931. * H263TermEncoderInstance
  1932. *
  1933. * This function frees the space allocated for an instance of the H263 encoder.
  1934. */
  1935. LRESULT H263TermEncoderInstance(LPCODINST lpCompInst)
  1936. {
  1937. LRESULT lResult;
  1938. LRESULT lLockingResult;
  1939. LRESULT lDecoderResult;
  1940. LRESULT lColorOutResult;
  1941. U8 BIGG * P32Inst;
  1942. T_H263EncoderCatalog FAR * EC;
  1943. // Check instance pointer
  1944. if (!lpCompInst)
  1945. return ICERR_ERROR;
  1946. if(lpCompInst->Initialized == FALSE)
  1947. {
  1948. DBOUT("Warning: H263TermEncoderInstance(): Uninitialized instance")
  1949. lResult = ICERR_OK;
  1950. goto done;
  1951. }
  1952. lpCompInst->Initialized = FALSE;
  1953. lpCompInst->EncoderInst = (LPVOID)GlobalLock(lpCompInst->hEncoderInst);
  1954. if (lpCompInst->EncoderInst == NULL)
  1955. {
  1956. DBOUT("ERROR :: H263TermEncoderInstance :: ICERR_MEMORY");
  1957. lLockingResult = ICERR_MEMORY;
  1958. lColorOutResult = ICERR_OK;
  1959. lDecoderResult = ICERR_OK;
  1960. }
  1961. else
  1962. {
  1963. lLockingResult = ICERR_OK;
  1964. P32Inst = (U8 *)
  1965. ((((U32) lpCompInst->EncoderInst) +
  1966. (sizeof(T_MBlockActionStream) - 1)) &
  1967. ~(sizeof(T_MBlockActionStream) - 1));
  1968. // P32Inst = (U8 *) ((((U32) lpCompInst->EncoderInst) + 31) & ~0x1F);
  1969. EC = ((T_H263EncoderCatalog *) P32Inst);
  1970. // Check encoder catalog pointer
  1971. if (!EC)
  1972. return ICERR_ERROR;
  1973. #ifdef ENCODE_STATS
  1974. // OutputEncodeBitStreamStatistics(ENCODE_STATS_FILENAME, &EC->BSInfo, EC->PictureHeader.SourceFormat == SF_CIF);
  1975. OutputEncodeTimingStatistics(ENCODE_STATS_FILENAME, EC->pEncTimingInfo);
  1976. #endif
  1977. /* Terminate the color converter
  1978. */
  1979. lColorOutResult = H263TermColorConvertor(EC->pDecInstanceInfo);
  1980. if (lColorOutResult != ICERR_OK)
  1981. {
  1982. DBOUT("Terminating the color converter failed.");
  1983. }
  1984. /* Terminate the decoder
  1985. */
  1986. lDecoderResult = H263TermDecoderInstance(EC->pDecInstanceInfo);
  1987. if (lDecoderResult != ICERR_OK)
  1988. {
  1989. DBOUT("Terminating the decoder failed.");
  1990. }
  1991. GlobalUnlock(lpCompInst->hEncoderInst);
  1992. GlobalFree(lpCompInst->hEncoderInst);
  1993. }
  1994. /* set the result
  1995. */
  1996. if (lLockingResult != ICERR_OK)
  1997. {
  1998. lResult = lLockingResult;
  1999. }
  2000. else if (lColorOutResult != ICERR_OK)
  2001. {
  2002. lResult = lColorOutResult;
  2003. }
  2004. else if (lDecoderResult != ICERR_OK)
  2005. {
  2006. lResult = lDecoderResult;
  2007. }
  2008. else
  2009. {
  2010. lResult = ICERR_OK;
  2011. }
  2012. done:
  2013. return lResult;
  2014. }
  2015. /*****************************************************************************
  2016. *
  2017. * WriteBeginPictureHeaderToStream
  2018. *
  2019. * Write the beginning of the picture header to the stream updating the
  2020. * stream pointer and the bit offset. The beginning of the picture header
  2021. * is everything but the zero PEI bit
  2022. */
  2023. static void WriteBeginPictureHeaderToStream(
  2024. T_H263EncoderCatalog *EC,
  2025. U8 ** ppu8CurBitStream,
  2026. U8 * pu8BitOffset)
  2027. {
  2028. /* Picture Start Code */
  2029. PutBits(FIELDVAL_PSC, FIELDLEN_PSC, ppu8CurBitStream, pu8BitOffset);
  2030. /* Temporal Reference */
  2031. PutBits( EC->PictureHeader.TR, FIELDLEN_TR, ppu8CurBitStream, pu8BitOffset);
  2032. /* PTYPE: Split screen indicator */
  2033. PutBits( EC->PictureHeader.Split, FIELDLEN_PTYPE_SPLIT, ppu8CurBitStream, pu8BitOffset);
  2034. /* PTYPE: Document camera indicator. */
  2035. PutBits( EC->PictureHeader.DocCamera, FIELDLEN_PTYPE_DOC, ppu8CurBitStream, pu8BitOffset);
  2036. /* PTYPE: Freeze picture release. */
  2037. PutBits( EC->PictureHeader.PicFreeze, FIELDLEN_PTYPE_RELEASE, ppu8CurBitStream, pu8BitOffset);
  2038. /* PTYPE: Source image format. */
  2039. PutBits( EC->PictureHeader.SourceFormat, FIELDLEN_PTYPE_SRCFORMAT, ppu8CurBitStream, pu8BitOffset);
  2040. /* PTYPE: Still image indicator. */
  2041. PutBits( EC->PictureHeader.StillImage, FIELDLEN_PTYPE_STILL, ppu8CurBitStream, pu8BitOffset);
  2042. /* PTYPE: Still image indicator. */
  2043. PutBits( EC->PictureHeader.Spare, FIELDLEN_PTYPE_SPARE, ppu8CurBitStream, pu8BitOffset);
  2044. } /* end WriteBeginPictureHeaderToStream() */
  2045. /*****************************************************************************
  2046. *
  2047. * WriteEndPictureHeaderToStream
  2048. *
  2049. * Write the end of the picture header to the stream updating the
  2050. * stream pointer and the bit offset. The end of the picture header is the
  2051. * zero PEI bit.
  2052. */
  2053. static void WriteEndPictureHeaderToStream(
  2054. T_H263EncoderCatalog *EC,
  2055. U8 ** ppu8CurBitStream,
  2056. U8 * pu8BitOffset)
  2057. {
  2058. /* PEI - Extra insertion information */
  2059. PutBits( EC->PictureHeader.PEI, FIELDLEN_PEI, ppu8CurBitStream, pu8BitOffset);
  2060. } /* end WriteEndPictureHeaderToStream() */
  2061. #ifdef CHECKSUM_PICTURE
  2062. /*****************************************************************************
  2063. *
  2064. * WritePictureChecksum
  2065. *
  2066. * Write the picture checksum to the file.
  2067. *
  2068. * This function should be able to be called twice. The first time it should
  2069. * be called with 0 values after saving the values of the bitstream poointer
  2070. * and bitoffset. After completing the picture call it with the actual
  2071. * checksum values to update.
  2072. */
  2073. static void WritePictureChecksum(
  2074. YVUCheckSum * pYVUCheckSum,
  2075. U8 ** ppu8CurBitStream,
  2076. U8 * pu8BitOffset,
  2077. U8 u8ValidData)
  2078. {
  2079. U32 uBytes;
  2080. UN unData;
  2081. /* Tag data
  2082. */
  2083. unData = (UN) u8ValidData;
  2084. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2085. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2086. /* Y date - high to low bytes.
  2087. */
  2088. uBytes = pYVUCheckSum->uYCheckSum;
  2089. unData = (UN) ((uBytes >> 24) & 0xFF);
  2090. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2091. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2092. unData = (UN) ((uBytes >> 16) & 0xFF);
  2093. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2094. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2095. unData = (UN) ((uBytes >> 8) & 0xFF);
  2096. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2097. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2098. unData = (UN) (uBytes & 0xFF);
  2099. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2100. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2101. /* V date - high to low bytes.
  2102. */
  2103. uBytes = pYVUCheckSum->uVCheckSum;
  2104. unData = (UN) ((uBytes >> 24) & 0xFF);
  2105. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2106. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2107. unData = (UN) ((uBytes >> 16) & 0xFF);
  2108. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2109. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2110. unData = (UN) ((uBytes >> 8) & 0xFF);
  2111. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2112. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2113. unData = (UN) (uBytes & 0xFF);
  2114. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2115. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2116. /* U date - high to low bytes.
  2117. */
  2118. uBytes = pYVUCheckSum->uUCheckSum;
  2119. unData = (UN) ((uBytes >> 24) & 0xFF);
  2120. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2121. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2122. unData = (UN) ((uBytes >> 16) & 0xFF);
  2123. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2124. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2125. unData = (UN) ((uBytes >> 8) & 0xFF);
  2126. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2127. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2128. unData = (UN) (uBytes & 0xFF);
  2129. PutBits(1, 1, ppu8CurBitStream, pu8BitOffset);
  2130. PutBits(unData, 8, ppu8CurBitStream, pu8BitOffset);
  2131. } /* WritePictureChecksum() */
  2132. #endif
  2133. /*****************************************************************************
  2134. *
  2135. * WriteGOBHeaderToStream
  2136. *
  2137. * Write the GOB header to the stream updating the stream pointer and the
  2138. * bit offset.
  2139. */
  2140. static void WriteGOBHeaderToStream(
  2141. U32 uGOBNumber,
  2142. UN unGQuant,
  2143. U8 ** ppu8CurBitStream,
  2144. U8 * pu8BitOffset)
  2145. {
  2146. /* GOB Start Code */
  2147. PutBits(FIELDVAL_GBSC, FIELDLEN_GBSC, ppu8CurBitStream, pu8BitOffset);
  2148. /* GOB Number */
  2149. PutBits((int)uGOBNumber, FIELDLEN_GN, ppu8CurBitStream, pu8BitOffset);
  2150. /* GOB Quant */
  2151. PutBits((int)unGQuant, FIELDLEN_GQUANT, ppu8CurBitStream, pu8BitOffset);
  2152. /* GEI */
  2153. PutBits(0, FIELDLEN_GEI, ppu8CurBitStream, pu8BitOffset);
  2154. } /* end WriteGOBHeaderToStream() */
  2155. /************************************************************************
  2156. *
  2157. * CalcGOBChromaVecs
  2158. */
  2159. static void CalcGOBChromaVecs(
  2160. T_H263EncoderCatalog * EC,
  2161. UN unStartingMB,
  2162. T_CONFIGURATION *pConfiguration)
  2163. {
  2164. #ifdef ENCODE_STATS
  2165. // #include "ctiming.h"
  2166. U32 uStartLow = EC->uStartLow;
  2167. U32 uStartHigh = EC->uStartHigh;
  2168. U32 uElapsed;
  2169. U32 uBefore;
  2170. U32 uSLF_UVSum = 0;
  2171. int bTimingThisFrame = EC->bTimingThisFrame;
  2172. ENC_TIMING_INFO * pEncTimingInfo = NULL;
  2173. #endif
  2174. register T_MBlockActionStream *pCurrMB;
  2175. T_MBlockActionStream *pLastMBPlus1;
  2176. char HMV;
  2177. char VMV;
  2178. int c;
  2179. pCurrMB = &(EC->pU8_MBlockActionStream[unStartingMB]);
  2180. pLastMBPlus1 = &(EC->pU8_MBlockActionStream[unStartingMB + 33]);
  2181. for( c = unStartingMB; pCurrMB < pLastMBPlus1 ; pCurrMB++, c++)
  2182. {
  2183. if (IsIntraBlock(pCurrMB->BlockType))
  2184. continue;
  2185. /* Now that are using +/- 15 pel motion search, need to change
  2186. valid range of returned MVs. Remember these are in 1/2 pel
  2187. increments. Valid range is [-32,31] now.
  2188. */
  2189. /*
  2190. ASSERT( (pCurrMB->BlkY1.PHMV >= -15) &&
  2191. (pCurrMB->BlkY1.PHMV <= 15) )
  2192. ASSERT( (pCurrMB->BlkY1.PVMV >= -15) &&
  2193. (pCurrMB->BlkY1.PVMV <= 15) )
  2194. */
  2195. ASSERT( (pCurrMB->BlkY1.PHMV >= -32) &&
  2196. (pCurrMB->BlkY1.PHMV <= 31) )
  2197. ASSERT( (pCurrMB->BlkY1.PVMV >= -32) &&
  2198. (pCurrMB->BlkY1.PVMV <= 31) )
  2199. // RTP: resiliency considerations check
  2200. if (pConfiguration->bEncoderResiliency && pConfiguration->unPacketLoss)
  2201. {
  2202. if (pConfiguration->bDisallowAllVerMVs)
  2203. {
  2204. ASSERT(pCurrMB->BlkY1.PVMV == 0);
  2205. }
  2206. else if (pConfiguration->bDisallowPosVerMVs)
  2207. {
  2208. ASSERT(pCurrMB->BlkY1.PVMV <= 0);
  2209. }
  2210. }
  2211. HMV = QtrPelToHalfPel[pCurrMB->BlkY1.PHMV+32];
  2212. VMV = QtrPelToHalfPel[pCurrMB->BlkY1.PVMV+32];
  2213. /* Make sure we don't do half pel interpolation in the fdct
  2214. */
  2215. HMV = (HMV / 2) * 2;
  2216. VMV = (VMV / 2) * 2;
  2217. /* Assign the motion vectors for use in the dct
  2218. */
  2219. pCurrMB->BlkU.PHMV = HMV;
  2220. pCurrMB->BlkU.PVMV = VMV;
  2221. pCurrMB->BlkV.PHMV = HMV;
  2222. pCurrMB->BlkV.PVMV = VMV;
  2223. // TBD: get Brian to put this in ex5me.asm
  2224. if (IsSLFBlock(pCurrMB->BlockType))
  2225. {
  2226. /*
  2227. if (pCurrMB->CodedBlocks & 0x2)
  2228. ASSERT(pCurrMB->BlkY2.B4_7.PastRef == pCurrMB->BlkY1.B4_7.PastRef + 8);
  2229. if (pCurrMB->CodedBlocks & 0x4)
  2230. ASSERT(pCurrMB->BlkY3.B4_7.PastRef == pCurrMB->BlkY1.B4_7.PastRef + 8*PITCH);
  2231. if (pCurrMB->CodedBlocks & 0x8)
  2232. ASSERT(pCurrMB->BlkY4.B4_7.PastRef == pCurrMB->BlkY1.B4_7.PastRef + 8*PITCH+8);
  2233. */
  2234. if (pCurrMB->CodedBlocks & 0x2)
  2235. pCurrMB->BlkY2.B4_7.PastRef = pCurrMB->BlkY1.B4_7.PastRef + 8;
  2236. if (pCurrMB->CodedBlocks & 0x4)
  2237. pCurrMB->BlkY3.B4_7.PastRef = pCurrMB->BlkY1.B4_7.PastRef + 8*PITCH;
  2238. if (pCurrMB->CodedBlocks & 0x8)
  2239. pCurrMB->BlkY4.B4_7.PastRef = pCurrMB->BlkY1.B4_7.PastRef + 8*PITCH+8;
  2240. }
  2241. /* Motion vectors are in half pels. So we need to divide by 2 to get
  2242. * to integer pels.
  2243. */
  2244. ASSERT((VMV / 2) == (VMV >> 1)); /* since we divided by 2 and mult above */
  2245. ASSERT((HMV / 2) == (HMV >> 1));
  2246. VMV >>= 1;
  2247. HMV >>= 1;
  2248. #ifdef SLF_WORK_AROUND
  2249. pCurrMB->BlkU.B4_7.PastRef =
  2250. EC->pU8_PrevFrm_YPlane
  2251. + pCurrMB->BlkU.BlkOffset
  2252. + VMV*PITCH + HMV;
  2253. pCurrMB->BlkV.B4_7.PastRef =
  2254. EC->pU8_PrevFrm_YPlane
  2255. + pCurrMB->BlkV.BlkOffset
  2256. + VMV*PITCH + HMV;
  2257. /* Currently U & V are not SLF.
  2258. TBD: assemble version of SLF for U & V, ask Brian
  2259. */
  2260. if (IsSLFBlock(pCurrMB->BlockType))
  2261. {
  2262. if (pCurrMB->CodedBlocks & 0x10)
  2263. {
  2264. #ifdef ENCODE_STATS
  2265. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  2266. #endif
  2267. EncUVLoopFilter((U8*)pCurrMB->BlkU.B4_7.PastRef,
  2268. (U8*)EC->pU8_SLFFrm_YPlane+pCurrMB->BlkU.BlkOffset,PITCH);
  2269. pCurrMB->BlkU.B4_7.PastRef =
  2270. EC->pU8_SLFFrm_YPlane+pCurrMB->BlkU.BlkOffset;
  2271. }
  2272. if (pCurrMB->CodedBlocks & 0x20)
  2273. {
  2274. EncUVLoopFilter((U8*)pCurrMB->BlkV.B4_7.PastRef,
  2275. (U8*)EC->pU8_SLFFrm_YPlane+pCurrMB->BlkV.BlkOffset,PITCH);
  2276. pCurrMB->BlkV.B4_7.PastRef =
  2277. EC->pU8_SLFFrm_YPlane+pCurrMB->BlkV.BlkOffset;
  2278. #ifdef ENCODE_STATS
  2279. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uSLF_UVSum)
  2280. #endif
  2281. }
  2282. }
  2283. #else
  2284. pCurrMB->BlkU.B4_7.PastRef =
  2285. EC->pU8_PrevFrm_YPlane
  2286. + pCurrMB->BlkU.BlkOffset
  2287. + VMV*PITCH + HMV;
  2288. pCurrMB->BlkV.B4_7.PastRef =
  2289. EC->pU8_PrevFrm_YPlane
  2290. + pCurrMB->BlkV.BlkOffset
  2291. + VMV*PITCH + HMV;
  2292. #endif
  2293. } /* for(pCurrMB ... */
  2294. #ifdef ENCODE_STATS
  2295. if (bTimingThisFrame)
  2296. {
  2297. pEncTimingInfo = EC->pEncTimingInfo + EC->uStatFrameCount;
  2298. pEncTimingInfo->uSLF_UV += uSLF_UVSum;
  2299. }
  2300. #endif
  2301. } /* end CalcGOBChromaVecs() */
  2302. /************************************************************************
  2303. *
  2304. * GetEncoderOptions
  2305. *
  2306. * Get the options, saving them in the catalog
  2307. */
  2308. static void GetEncoderOptions(
  2309. T_H263EncoderCatalog * EC)
  2310. {
  2311. int bSetOptions = 1;
  2312. /* Default Options
  2313. */
  2314. const int bDefaultUseMotionEstimation = 1;
  2315. const int bDefaultUseSpatialLoopFilter = 1;
  2316. const char * szDefaultBRCType = "Normal";
  2317. const U32 uDefaultForcedQuant = 8;
  2318. const U32 uDefaultForcedDataRate = 1024;
  2319. const float fDefaultForcedFrameRate = (float) 8.0; /* should be the same as szDefaultForcedFrameRate */
  2320. #ifndef RING0
  2321. const char * szDefaultForcedFrameRate = "8.0"; /* should be the same as fDefaultForcedFrameRate */
  2322. #endif
  2323. /* INI file variables
  2324. */
  2325. #ifndef RING0
  2326. UN unResult;
  2327. DWORD dwResult;
  2328. char buf120[120];
  2329. float fResult;
  2330. #define SECTION_NAME "Encode"
  2331. #define INI_FILE_NAME "h261test.ini"
  2332. #endif
  2333. /* Read the options from the INI file
  2334. */
  2335. #ifndef RING0
  2336. {
  2337. DBOUT("Getting options from the ini file h261test.ini");
  2338. /* Motion Estimation
  2339. */
  2340. unResult = GetPrivateProfileInt(SECTION_NAME, "MotionEstimation", bDefaultUseMotionEstimation, INI_FILE_NAME);
  2341. if (unResult != 0 && unResult != 1)
  2342. {
  2343. #ifdef _DEBUG
  2344. wsprintf(string,"MotionEstimation ini value error (should be 0 or 1) - using default=%d",
  2345. (int) bDefaultUseMotionEstimation);
  2346. DBOUT(string);
  2347. #endif
  2348. unResult = bDefaultUseMotionEstimation;
  2349. }
  2350. EC->bUseMotionEstimation = unResult;
  2351. /* Set the custom parameters for motion estimation.
  2352. */
  2353. unResult = GetPrivateProfileInt(SECTION_NAME, "MEzerothresh", MECatalog[ME_CUSTOM_CTRLS].zero_vector_threshold, INI_FILE_NAME);
  2354. MECatalog[ME_CUSTOM_CTRLS].zero_vector_threshold = unResult;
  2355. unResult = GetPrivateProfileInt(SECTION_NAME, "MEnonzerodiff", MECatalog[ME_CUSTOM_CTRLS].nonzero_MV_differential, INI_FILE_NAME);
  2356. MECatalog[ME_CUSTOM_CTRLS].nonzero_MV_differential = unResult;
  2357. unResult = GetPrivateProfileInt(SECTION_NAME, "MEemptythresh", MECatalog[ME_CUSTOM_CTRLS].empty_threshold, INI_FILE_NAME);
  2358. MECatalog[ME_CUSTOM_CTRLS].empty_threshold = unResult;
  2359. unResult = GetPrivateProfileInt(SECTION_NAME, "MEinterthresh", MECatalog[ME_CUSTOM_CTRLS].intercoding_threshold, INI_FILE_NAME);
  2360. MECatalog[ME_CUSTOM_CTRLS].intercoding_threshold = unResult;
  2361. unResult = GetPrivateProfileInt(SECTION_NAME, "MEinterdiff", MECatalog[ME_CUSTOM_CTRLS].intercoding_differential, INI_FILE_NAME);
  2362. MECatalog[ME_CUSTOM_CTRLS].intercoding_differential = unResult;
  2363. unResult = GetPrivateProfileInt(SECTION_NAME, "MEslfthresh", MECatalog[ME_CUSTOM_CTRLS].slf_threshold, INI_FILE_NAME);
  2364. MECatalog[ME_CUSTOM_CTRLS].slf_threshold = unResult;
  2365. unResult = GetPrivateProfileInt(SECTION_NAME, "MEslfdiff", MECatalog[ME_CUSTOM_CTRLS].slf_differential, INI_FILE_NAME);
  2366. MECatalog[ME_CUSTOM_CTRLS].slf_differential = unResult;
  2367. /* Enable or disable the custom parameters for motion estimation.
  2368. */
  2369. unResult = GetPrivateProfileInt(SECTION_NAME, "CustomME", 0, INI_FILE_NAME);
  2370. EC->bUseCustomMotionEstimation = unResult ? 1 : 0;
  2371. /* Spatial Loop Filter
  2372. */
  2373. unResult = GetPrivateProfileInt(SECTION_NAME, "SpatialLoopFilter", bDefaultUseSpatialLoopFilter, INI_FILE_NAME);
  2374. if (unResult != 0 && unResult != 1)
  2375. {
  2376. #ifdef _DEBUG
  2377. wsprintf(string,"SpatialLoopFilter ini value error (should be 0 or 1) - using default=%d",
  2378. (int) bDefaultUseSpatialLoopFilter);
  2379. DBOUT(string);
  2380. #endif
  2381. unResult = bDefaultUseSpatialLoopFilter;
  2382. }
  2383. EC->bUseSpatialLoopFilter = unResult;
  2384. /* Bit Rate Controller Type
  2385. */
  2386. strcpy(buf120,"Error");
  2387. dwResult = GetPrivateProfileString(SECTION_NAME, "BRCType", szDefaultBRCType, buf120, 120, INI_FILE_NAME);
  2388. if ((dwResult == 0) ||
  2389. ((strcmp(buf120,"Normal") != 0) &&
  2390. (strcmp(buf120,"ForcedQuant") != 0) &&
  2391. (strcmp(buf120,"ForcedDataRate") != 0)))
  2392. {
  2393. #ifdef _DEBUG
  2394. wsprintf(string,"BRCType ini value error (should be Normal, ForcedQuant, or ForcedDataRate) - using default=%s",
  2395. szDefaultBRCType);
  2396. DBOUT(string);
  2397. #endif
  2398. strcpy(buf120,szDefaultBRCType);
  2399. }
  2400. if (strcmp(buf120,"Normal") == 0)
  2401. {
  2402. EC->u8BRCType = BRC_Normal;
  2403. }
  2404. else if (strcmp(buf120,"ForcedQuant") == 0)
  2405. {
  2406. EC->u8BRCType = BRC_ForcedQuant;
  2407. }
  2408. else if (strcmp(buf120,"ForcedDataRate") == 0)
  2409. {
  2410. EC->u8BRCType = BRC_ForcedDataRate;
  2411. }
  2412. else
  2413. {
  2414. ASSERT(0);
  2415. }
  2416. /* ForcedQuant
  2417. */
  2418. if (EC->u8BRCType == BRC_ForcedQuant)
  2419. {
  2420. unResult = GetPrivateProfileInt(SECTION_NAME, "ForcedQuant", uDefaultForcedQuant, INI_FILE_NAME);
  2421. if (unResult < 6 || unResult > 31)
  2422. {
  2423. #ifdef _DEBUG
  2424. wsprintf(string, "ForcedQuant ini value error (should be 6 to 31) - using default=%d",
  2425. uDefaultForcedQuant);
  2426. DBOUT(string);
  2427. #endif
  2428. unResult = uDefaultForcedQuant;
  2429. }
  2430. EC->uForcedQuant = unResult;
  2431. }
  2432. /* ForcedDataRate
  2433. */
  2434. if (EC->u8BRCType == BRC_ForcedDataRate)
  2435. {
  2436. unResult = GetPrivateProfileInt(SECTION_NAME, "ForcedDataRate", uDefaultForcedDataRate, INI_FILE_NAME);
  2437. if (unResult < 1)
  2438. {
  2439. #ifdef _DEBUG
  2440. wsprintf(string,"ForcedDataRate ini value error (should be > 0) - using default=%d",
  2441. uDefaultForcedDataRate);
  2442. DBOUT(string);
  2443. #endif
  2444. unResult = uDefaultForcedDataRate;
  2445. }
  2446. EC->uForcedDataRate = unResult;
  2447. strcpy(buf120,"0.0");
  2448. dwResult = GetPrivateProfileString(SECTION_NAME, "ForcedFrameRate", szDefaultForcedFrameRate, buf120, 120, INI_FILE_NAME);
  2449. if (dwResult > 0)
  2450. {
  2451. fResult = (float) atof(buf120);
  2452. }
  2453. else
  2454. {
  2455. fResult = (float) 0.0;
  2456. }
  2457. if ( fResult <= 0.0 || fResult > 30.0)
  2458. {
  2459. #ifdef _DEBUG
  2460. wsprintf(string, "ForcedFrameRate ini value error (should be > 0.0 and <= 30.0) - using default=%s",
  2461. szDefaultForcedFrameRate);
  2462. DBOUT(string);
  2463. #endif
  2464. fResult = fDefaultForcedFrameRate;
  2465. }
  2466. EC->fForcedFrameRate = fResult;
  2467. }
  2468. bSetOptions = 0;
  2469. }
  2470. #endif
  2471. if (bSetOptions)
  2472. {
  2473. EC->bUseMotionEstimation = bDefaultUseMotionEstimation;
  2474. EC->bUseSpatialLoopFilter = bDefaultUseSpatialLoopFilter;
  2475. EC->u8BRCType = BRC_Normal;
  2476. EC->uForcedQuant = uDefaultForcedQuant; /* Used with BRC_ForcedQuant */
  2477. EC->uForcedDataRate = uDefaultForcedDataRate; /* Used with BRC_ForcedDataRate */
  2478. EC->fForcedFrameRate = fDefaultForcedFrameRate; /* Used with BRC_ForcedDataRate */
  2479. }
  2480. /* Can only use the SLF if ME is on
  2481. */
  2482. if (EC->bUseSpatialLoopFilter && !EC->bUseMotionEstimation)
  2483. {
  2484. DBOUT("The Spatial Loop Filter can not be on if Motion Estimation is OFF");
  2485. EC->bUseSpatialLoopFilter = 0;
  2486. }
  2487. /* Display the options
  2488. */
  2489. if (EC->bUseMotionEstimation)
  2490. {
  2491. DBOUT("Encoder option (Motion Estimation) is ON");
  2492. }
  2493. else
  2494. {
  2495. DBOUT("Encoder option (Motion Estimation) is OFF");
  2496. }
  2497. if (EC->bUseSpatialLoopFilter)
  2498. {
  2499. DBOUT("Encoder option (Spatial Loop Filter) is ON");
  2500. }
  2501. else
  2502. {
  2503. DBOUT("Encoder option (Spatial Loop Filter) is OFF");
  2504. }
  2505. #ifdef _DEBUG
  2506. if (EC->bUseCustomMotionEstimation)
  2507. {
  2508. wsprintf(string, "Encoder option (Custom Motion Estimation) %5d %5d %5d %5d %5d %5d %5d",
  2509. MECatalog[ME_CUSTOM_CTRLS].zero_vector_threshold,
  2510. MECatalog[ME_CUSTOM_CTRLS].nonzero_MV_differential,
  2511. MECatalog[ME_CUSTOM_CTRLS].empty_threshold,
  2512. MECatalog[ME_CUSTOM_CTRLS].intercoding_threshold,
  2513. MECatalog[ME_CUSTOM_CTRLS].intercoding_differential,
  2514. MECatalog[ME_CUSTOM_CTRLS].slf_threshold,
  2515. MECatalog[ME_CUSTOM_CTRLS].slf_differential
  2516. );
  2517. DBOUT(string);
  2518. }
  2519. #endif
  2520. #ifdef _DEBUG
  2521. switch (EC->u8BRCType)
  2522. {
  2523. case BRC_Normal:
  2524. DBOUT("Encoder option (BRC Type) is Normal");
  2525. break;
  2526. case BRC_ForcedQuant:
  2527. wsprintf(string, "Encoder option (BRC Type) is ForcedQuant with value=%d", EC->uForcedQuant);
  2528. DBOUT(string);
  2529. break;
  2530. case BRC_ForcedDataRate:
  2531. wsprintf(string, "Encoder option (BRC Type) is ForcedDataRate with value=%d", EC->uForcedDataRate);
  2532. DBOUT(string);
  2533. break;
  2534. default:
  2535. ASSERT(0); /* shouldn't happen */
  2536. break;
  2537. }
  2538. #endif
  2539. DBOUT("Encoder option (UsePerfmonNFMO) is OFF");
  2540. DBOUT("Encoder option (MMX) is OFF");
  2541. } /* end GetEncoderOptions() */
  2542. /************************************************************************
  2543. *
  2544. * StartupBRC
  2545. *
  2546. * Start up the Bit Rate Controller for this frame
  2547. * - set EC->bBitRateControl
  2548. * - set BRCState.TargetFrameRate
  2549. * - set BRCState.uTargetFrmSize
  2550. * - set EC->PictureHeader.PQuant
  2551. */
  2552. static void StartupBRC(
  2553. T_H263EncoderCatalog * EC,
  2554. U32 uVfWDataRate, /* VfW data rate - byte per frame */
  2555. U32 uVfWQuality, /* VfW Quality 1..10000 */
  2556. float fVfWFrameRate) /* VfW frame rate */
  2557. {
  2558. FX_ENTRY("StartupBRC");
  2559. /* Values used to constrain Quant based on Quality.
  2560. *
  2561. * When you change these remember to change GetOptions.
  2562. */
  2563. const int iLowFixedQuant = 6; // the lowest value without clipping artifacts
  2564. const int iHighFixedQuant = 31; // the highest value
  2565. I32 iRange;
  2566. I32 iValue;
  2567. float fValue;
  2568. switch (EC->u8BRCType) {
  2569. case BRC_Normal:
  2570. if (uVfWDataRate == 0)
  2571. {
  2572. EC->bBitRateControl = 0;
  2573. EC->BRCState.TargetFrameRate = (float) 0.0; /* turn it off */
  2574. EC->BRCState.uTargetFrmSize = 0; /* should not be used */
  2575. /* Compute the fixed quant from the quality
  2576. */
  2577. iRange = iHighFixedQuant - iLowFixedQuant;
  2578. ASSERT((iRange >= 0) && (iRange <= 30));
  2579. iValue = (10000 - (int)uVfWQuality);
  2580. ASSERT((iValue >= 0) && (iValue <= 10000));
  2581. fValue = (float)iValue * (float)iRange / (float)10000.0;
  2582. iValue = (int) (fValue + (float) 0.5);
  2583. iValue += iLowFixedQuant;
  2584. ASSERT((iValue >= iLowFixedQuant) && (iValue <= iHighFixedQuant));
  2585. EC->PictureHeader.PQUANT = (U8) iValue;
  2586. DEBUGMSG(ZONE_BITRATE_CONTROL, ("\r\n%s: Bitrate controller disabled, setting EC->PictureHeader.PQUANT = %ld\r\n", _fx_, EC->PictureHeader.PQUANT));
  2587. }
  2588. else
  2589. {
  2590. EC->bBitRateControl = 1;
  2591. EC->BRCState.TargetFrameRate = fVfWFrameRate;
  2592. EC->BRCState.uTargetFrmSize = uVfWDataRate;
  2593. DEBUGMSG(ZONE_BITRATE_CONTROL, ("\r\n%s: Bitrate controller enabled with\r\n", _fx_));
  2594. DEBUGMSG(ZONE_BITRATE_CONTROL, (" Target frame rate = %ld.%ld fps\r\n Target quality = %ld\r\n Target frame size = %ld bits\r\n Target bitrate = %ld bps\r\n", (DWORD)EC->BRCState.TargetFrameRate, (DWORD)(EC->BRCState.TargetFrameRate - (float)(DWORD)EC->BRCState.TargetFrameRate) * 10UL, uVfWQuality, (DWORD)EC->BRCState.uTargetFrmSize << 3, (DWORD)(EC->BRCState.TargetFrameRate * EC->BRCState.uTargetFrmSize) * 8UL));
  2595. DEBUGMSG(ZONE_BITRATE_CONTROL, (" Minimum quantizer = %ld\r\n Maximum quantizer = 31\r\n", clampQP((10000 - uVfWQuality)*15/10000)));
  2596. EC->PictureHeader.PQUANT = CalcPQUANT( &(EC->BRCState), EC->PictureHeader.PicCodType);
  2597. }
  2598. break;
  2599. case BRC_ForcedQuant:
  2600. EC->bBitRateControl = 0;
  2601. EC->BRCState.TargetFrameRate = (float) 0.0; /* turn it off */
  2602. EC->BRCState.uTargetFrmSize = 0; /* should not be used */
  2603. EC->PictureHeader.PQUANT = (U8) EC->uForcedQuant;
  2604. break;
  2605. case BRC_ForcedDataRate:
  2606. EC->bBitRateControl = 1;
  2607. EC->BRCState.TargetFrameRate = EC->fForcedFrameRate;
  2608. EC->BRCState.uTargetFrmSize = EC->uForcedDataRate;
  2609. DEBUGMSG(ZONE_BITRATE_CONTROL, ("\r\n%s: Bitrate controller enabled with\r\n", _fx_));
  2610. DEBUGMSG(ZONE_BITRATE_CONTROL, (" Target frame rate = %ld.%ld fps\r\n Target quality = %ld\r\n Target frame size = %ld bits\r\n Target bitrate = %ld bps\r\n", (DWORD)EC->BRCState.TargetFrameRate, (DWORD)(EC->BRCState.TargetFrameRate - (float)(DWORD)EC->BRCState.TargetFrameRate) * 10UL, uVfWQuality, (DWORD)EC->BRCState.uTargetFrmSize << 3, (DWORD)(EC->BRCState.TargetFrameRate * EC->BRCState.uTargetFrmSize) * 8UL));
  2611. DEBUGMSG(ZONE_BITRATE_CONTROL, (" Minimum quantizer = %ld\r\n Maximum quantizer = 31\r\n", clampQP((10000 - uVfWQuality)*15/10000)));
  2612. EC->PictureHeader.PQUANT = CalcPQUANT( &(EC->BRCState), EC->PictureHeader.PicCodType);
  2613. break;
  2614. default:
  2615. ASSERT(0); /* should never happen */
  2616. break;
  2617. }
  2618. #ifdef DEBUG_BRC
  2619. wsprintf(string,"PQuant=%d", EC->PictureHeader.PQUANT);
  2620. DBOUT(string);
  2621. #endif
  2622. } /* end StartupBRC() */
  2623. /************************************************************************
  2624. *
  2625. * CalculateQP_mean
  2626. *
  2627. * Calculate the new QP_mean value.
  2628. *
  2629. * TBD: Consider making this more sophisticated - ie: look at more than
  2630. * the last frame or look at the second order affect.
  2631. */
  2632. static void CalculateQP_mean(
  2633. T_H263EncoderCatalog * EC)
  2634. {
  2635. /* Calculate average quantizer to be used for next frame.
  2636. * The current approach changes QP at the beginning of each row.
  2637. */
  2638. /* uQP_count no longer on a row of macroblocks bases, Arlene 6/20/96
  2639. if ( EC->PictureHeader.SourceFormat == SF_CIF )
  2640. {
  2641. ASSERT(EC->uQP_count == 2*EC->NumMBRows);
  2642. }
  2643. else
  2644. {
  2645. ASSERT(EC->uQP_count == EC->NumMBRows);
  2646. }
  2647. */
  2648. /* If this is an an INTRA picture use the inter default as QP_mean
  2649. * Otherwise compute QP_mean.
  2650. */
  2651. if (EC->PictureHeader.PicCodType == INTRAPIC)
  2652. {
  2653. EC->BRCState.QP_mean = EC->u8DefINTER_QP;
  2654. }
  2655. else
  2656. {
  2657. EC->BRCState.QP_mean = EC->uQP_cumulative / EC->uQP_count;
  2658. /* New method, Arlene 6/20/96
  2659. EC->BRCState.QP_mean =
  2660. (EC->uQP_cumulative + (EC->uQP_count >> 1)) / EC->uQP_count;
  2661. */
  2662. }
  2663. } /* end CalculateQP_mean() */