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.

4260 lines
148 KiB

  1. #define P6Version 0
  2. /* *************************************************************************
  3. ** INTEL Corporation Proprietary Information
  4. **
  5. ** This listing is supplied under the terms of a license
  6. ** agreement with INTEL Corporation and may not be copied
  7. ** nor disclosed except in accordance with the terms of
  8. ** that agreement.
  9. **
  10. ** Copyright (c) 1995,1996 Intel Corporation.
  11. ** All Rights Reserved.
  12. **
  13. ** *************************************************************************
  14. */
  15. /*****************************************************************************
  16. * e3enc.cpp
  17. *
  18. * DESCRIPTION:
  19. * Specific encoder compression functions.
  20. *
  21. * Routines: Prototypes in:
  22. * H263InitEncoderInstance
  23. * H263Compress
  24. * H263TermEncoderInstance
  25. *
  26. */
  27. //
  28. // $Author: JMCVEIGH $
  29. // $Date: 22 Apr 1997 10:44:58 $
  30. // $Archive: S:\h26x\src\enc\e3enc.cpv $
  31. // $Header: S:\h26x\src\enc\e3enc.cpv 1.185 22 Apr 1997 10:44:58 gmlim $
  32. // $Log: S:\h26x\src\enc\e3enc.cpv $
  33. //
  34. // Rev 1.185 22 Apr 1997 10:44:58 gmlim
  35. // Change to not return an ICERR_ERROR in H263Compress() when a PB frame
  36. // is dropped due to 8k/32k buffer size overflow. ICERR_OK will be
  37. // returned and the encoded P frame will be output.
  38. //
  39. // Rev 1.184 18 Apr 1997 10:45:18 JMCVEIGH
  40. // Clean-up of InitMEState when resiliency is turned on. Before, we
  41. // would duplicate the number of GOBs forced to be intra if packet
  42. // loss was requested.
  43. //
  44. // Rev 1.183 18 Apr 1997 08:43:22 gmlim
  45. // Fixed a bug where uAdjCumFrmSize was not being updated when RTP was
  46. // disabled.
  47. //
  48. // Rev 1.182 17 Apr 1997 17:12:20 gmlim
  49. // Added u32sizeBSnEBS to indicate the total buffer size. Changed
  50. // u32sizeBitBuffer to indicate the 8k/32k frame size without the
  51. // RTP extension and trailer. Added check for buffer overflow before
  52. // attaching the EBS and trailer to a PB frame. Also, added
  53. // uAdjCumFrmSize to be used with rate control in the IA case.
  54. //
  55. // Rev 1.181 17 Mar 1997 20:22:06 MDUDA
  56. // Adjusted calls to motion estimation to use pseudo stack space.
  57. // Moved local storage to encoder catalog from H263Compress.
  58. // This fixes were needed to support 16-bit apps that had insufficient
  59. // stack space.
  60. //
  61. // Rev 1.180 12 Mar 1997 16:51:02 CLORD
  62. // now check for NULL in H263TermEncoder
  63. //
  64. // Rev 1.179 11 Mar 1997 13:47:36 JMCVEIGH
  65. // Catch AVIIF_KEYFRAME flag for coding as an INTRA frame. Some
  66. // apps. use ICCOMPRESS_KEYFRAME, others AVIIF_KEYFRAME.
  67. //
  68. // Rev 1.178 10 Feb 1997 11:43:26 JMCVEIGH
  69. //
  70. // Support for new interpretation of blocking filter -
  71. // allow for motion vectors outside of the reference picture.
  72. //
  73. // Rev 1.177 05 Feb 1997 13:07:44 JMCVEIGH
  74. //
  75. // Further clean-up of improved PB.
  76. //
  77. // Rev 1.176 05 Feb 1997 12:18:16 JMCVEIGH
  78. // Pass GOBHeaderPresent parameter to MMxEDTQ() for EMV bug fix
  79. // support latest H.263+ draft bitstream spec, and support for
  80. // separate improved PB-frame flag.
  81. //
  82. // Rev 1.175 20 Jan 1997 17:02:16 JMCVEIGH
  83. //
  84. // Allow UMV without AP (MMX only).
  85. //
  86. // Rev 1.174 14 Jan 1997 17:55:04 JMCVEIGH
  87. // Allow in-the-loop deblocking filter on IA encoder.
  88. //
  89. // Rev 1.173 09 Jan 1997 13:49:46 MDUDA
  90. // Put emms instruction at end of H263Compress for MMX.
  91. //
  92. // Rev 1.172 08 Jan 1997 11:37:22 BECHOLS
  93. // Changed ini file name to H263Test.ini
  94. //
  95. // Rev 1.171 30 Dec 1996 19:54:08 MDUDA
  96. // Passing input format to encoder initializer so input color convertors
  97. // can be initialized.
  98. //
  99. // Rev 1.170 19 Dec 1996 16:32:52 MDUDA
  100. // Modified call to colorCnvtFrame to support H263 backward compatibility.
  101. //
  102. // Rev 1.169 19 Dec 1996 16:01:38 JMCVEIGH
  103. // Fixed turning off of deblocking filter if not MMX.
  104. //
  105. // Rev 1.168 16 Dec 1996 17:50:00 JMCVEIGH
  106. // Support for improved PB-frame mode and 8x8 motion vectors if
  107. // deblocking filter selected (no OBMC unless advanced prediction
  108. // also selected).
  109. //
  110. // Rev 1.167 16 Dec 1996 13:34:46 MDUDA
  111. // Added support for H263' codec plus some _CODEC_STATS changes.
  112. //
  113. // Rev 1.166 11 Dec 1996 15:02:06 JMCVEIGH
  114. //
  115. // Turning on of deblocking filter and true B-frames. Currently
  116. // only deblocking filter is implemented. Also, we do not automatically
  117. // turn on 8x8 motion vectors when the deblocking filter is selected.
  118. // Will use 8x8 vectors when the OBMC part of AP can be selectively
  119. // turned off.
  120. //
  121. // Rev 1.165 09 Dec 1996 17:57:24 JMCVEIGH
  122. // Added support for arbitrary frame size support.
  123. // 4 <= width <= 352, 4 <= height <= 288, both multiples of 4.
  124. // Normally, application will pass identical (arbitrary) frame
  125. // sizes in lParam1 and lParam2 of CompressBegin(). If
  126. // cropping/stretching desired to convert to standard frame sizes,
  127. // application should pass the desired output size in lParam2 and
  128. // the input size in lParam1.
  129. //
  130. // Rev 1.164 09 Dec 1996 09:49:56 MDUDA
  131. //
  132. // Modified for H263P.
  133. //
  134. // Rev 1.163 05 Dec 1996 16:49:46 GMLIM
  135. // Changed the way RTP packetization was done to guarantee proper packet
  136. // size. Modifications made to RTP related function calls in H263Compress().
  137. //
  138. // Rev 1.162 03 Dec 1996 08:53:22 GMLIM
  139. // Move the check for TR==TRPrev a few lines forward so that it is done
  140. // before any write to the bitstream buffer.
  141. //
  142. // Rev 1.161 03 Dec 1996 08:47:36 KLILLEVO
  143. // improved overflow resiliency for PB-frames. Still not perfect, since
  144. // that would require re-encoding of parts of the P-frames as well as the
  145. // corresponding parts of the B-frames.
  146. //
  147. // Rev 1.160 27 Nov 1996 16:15:50 gmlim
  148. // Modified RTP bitstream bufferring to improve efficiency and also to
  149. // avoid internal bitstream buffer overflow.
  150. //
  151. // Rev 1.159 26 Nov 1996 16:28:30 GMLIM
  152. // Added error checking for TR == TRPrev. Merged two sections of identical
  153. // code into one block common to both MMX and non-MMX cases.
  154. //
  155. // Rev 1.157 11 Nov 1996 09:14:26 JMCVEIGH
  156. // Fixed bug that caused all blocks in interframes to be intra coded
  157. // after the second I frame in a sequence. Now the ME states are
  158. // re-initialized when the previous frame was an I frame and the current
  159. // frame is a non-intra frame (also reinitialized when the AP state
  160. // changes).
  161. //
  162. // Rev 1.156 06 Nov 1996 16:29:20 gmlim
  163. // Removed H263ModeC.
  164. //
  165. // Rev 1.155 05 Nov 1996 13:33:22 GMLIM
  166. // Added mode c support for mmx case.
  167. //
  168. // Rev 1.154 03 Nov 1996 18:56:46 gmlim
  169. // Added mode c support for rtp bs ext.
  170. //
  171. // Rev 1.153 24 Oct 1996 15:25:54 KLILLEVO
  172. //
  173. // removed two string allocations no longer needed
  174. //
  175. // Rev 1.152 24 Oct 1996 15:19:40 KLILLEVO
  176. //
  177. // changed loglevel for instance events to 2 (from 4)
  178. //
  179. // Rev 1.151 23 Oct 1996 17:13:36 KLILLEVO
  180. //
  181. // typo in one DbgLog statement fixed
  182. //
  183. // Rev 1.150 23 Oct 1996 17:11:36 KLILLEVO
  184. // changed to DbgLog()
  185. //
  186. // Rev 1.149 22 Oct 1996 14:51:10 KLILLEVO
  187. // Blocktype initialization in InitMEState() is now only called if
  188. // the AP mode has changed from the previous picture.
  189. //
  190. // Rev 1.148 18 Oct 1996 16:57:00 BNICKERS
  191. // Fixes for EMV
  192. //
  193. // Rev 1.147 10 Oct 1996 16:43:00 BNICKERS
  194. // Initial debugging of Extended Motion Vectors.
  195. //
  196. // Rev 1.146 04 Oct 1996 17:05:22 BECHOLS
  197. // When we set the output flags lpdwFlags to AVIIF_KEYFRAME, we also set
  198. // dwFlags to ICCOMPRESS_KEYFRAME, to support changes Sylvia Day made to
  199. // CXQ_MAIN.CPP
  200. //
  201. // Rev 1.145 04 Oct 1996 08:47:40 BNICKERS
  202. // Add EMV.
  203. //
  204. // Rev 1.144 16 Sep 1996 16:49:52 CZHU
  205. // Changed interface for RTP BS initialization for smaller packet size
  206. //
  207. // Rev 1.143 13 Sep 1996 12:48:30 KLILLEVO
  208. // cleaned up intra update code to make it more understandable
  209. //
  210. // Rev 1.142 12 Sep 1996 14:46:14 KLILLEVO
  211. // finished baseline+PB
  212. //
  213. // Rev 1.141 12 Sep 1996 14:09:58 KLILLEVO
  214. // started baseline+PB changes (not finished)
  215. // added PVCS log
  216. ;////////////////////////////////////////////////////////////////////////////
  217. #include "precomp.h"
  218. #ifdef TRACK_ALLOCATIONS
  219. char gsz1[32];
  220. char gsz2[32];
  221. char gsz3[32];
  222. #endif
  223. #define DUMPFILE 0
  224. /* QP level for which the AP mode is turned off for IA */
  225. /* on MMX AP is always used if the caller asks for it */
  226. const int AP_MODE_QP_LEVEL = 11;
  227. /*
  228. Pick a resiliency strategy.
  229. */
  230. #define REQUESTED_KEY_FRAME 0
  231. #define PERIODIC_KEY_FRAME 1
  232. #define FAST_RECOVERY 2
  233. #define SLOW_RECOVERY 3
  234. #define RESILIENCY_STRATEGY PERIODIC_KEY_FRAME
  235. #define PERIODIC_KEY_FRAME_PERIODICITY 15 // Select periodicity (max 32767)
  236. #define UNRESTRICTED_MOTION_FRAMES 16 // Number of frames that don't have an
  237. // Intra slice. 0 for FAST_RECOVERY.
  238. // Modest amount for SLOW_RECOVERY.
  239. // Unimportant for other strategies.
  240. #define REUSE_DECODE 1 // Set to one if second decode (as under Videdit)
  241. // can reuse the encoder's decode.
  242. /*
  243. * Need this hack to allow temporarily turning off PB frames
  244. * when they are turned on usin the INI file.
  245. */
  246. #define TEMPORARILY_FALSE 88
  247. #ifdef STAT
  248. #define STATADDRESS 0x250
  249. #define ELAPSED_ENCODER_TIME 1 // Must be set for other timers to work right.
  250. #define SAMPLE_RGBCONV_TIME 0 // Time conversion of RGB24 to YUV9 step.
  251. #define SAMPLE_MOTION_TIME 0 // Time motion estimation step.
  252. #define SAMPLE_ENCBLK_TIME 0 // Time encode block layer step.
  253. #define SAMPLE_ENCMBLK_TIME 0 // Time encode macroblock layer step.
  254. #define SAMPLE_ENCVLC_TIME 0 // Time encode VLC step.
  255. #define SAMPLE_COMPAND_TIME 1 // Time decode of encoded block step.
  256. #else
  257. #define STATADDRESS 0x250
  258. #define ELAPSED_ENCODER_TIME 0 // Must be set for other timers to work right.
  259. #define SAMPLE_RGBCONV_TIME 0 // Time conversion of RGB24 to YUV9 step.
  260. #define SAMPLE_MOTION_TIME 0 // Time motion estimation step.
  261. #define SAMPLE_ENCBLK_TIME 0 // Time encode block layer step.
  262. #define SAMPLE_ENCMBLK_TIME 0 // Time encode macroblock layer step.
  263. #define SAMPLE_ENCVLC_TIME 0 // Time encode VLC step.
  264. #define SAMPLE_COMPAND_TIME 0 // Time decode of encoded block step.
  265. #endif
  266. //#pragma warning(disable:4101)
  267. //#pragma warning(disable:4102)
  268. #if ELAPSED_ENCODER_TIME
  269. // #include "statx.h" --- commented out to allow updating dependencies
  270. DWORD Elapsed, Sample;
  271. DWORD TotalElapsed, TotalSample, TimedIterations;
  272. #endif
  273. //#define PITCH 384
  274. #define PITCHL 384L
  275. #define DEFAULT_DCSTEP 8
  276. #define DEFAULT_QUANTSTEP 36
  277. #define DEFAULT_QUANTSTART 30
  278. #define LEFT 0
  279. #define INNERCOL 1
  280. #define NEARRIGHT 2
  281. #define RIGHT 3
  282. #define TOP 0
  283. #define INNERROW 4
  284. #define NEARBOTTOM 8
  285. #define BOTTOM 12
  286. #ifdef USE_MMX // { USE_MMX
  287. extern BOOL MMxVersion; // from ccpuvsn.cpp
  288. BOOL MMX_Enabled = MMxVersion;
  289. #endif // } USE_MMX
  290. BOOL ToggleAP = TRUE;
  291. BOOL TogglePB = TRUE;
  292. U8 u8QPMax;
  293. #ifdef REUSE_DECODE
  294. extern struct { // Communicate Encoder's decode to display decode.
  295. U8 FAR * Address; // Addr at which encoded frame is placed.
  296. DECINSTINFO BIGG * PDecoderInstInfo; // Encoder's decoder instance.
  297. unsigned int FrameNumber; // Frame number last encoded, mod 128.
  298. } CompandedFrame;
  299. #endif
  300. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  301. #pragma message ("Current log encode timing computations handle 105 frames max")
  302. void OutputEncodeTimingStatistics(char * szFileName, ENC_TIMING_INFO * pEncTimingInfo);
  303. void OutputEncTimingDetail(FILE * pFile, ENC_TIMING_INFO * pEncTimingInfo);
  304. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  305. /*
  306. * Look up table for quarter pel to half pel conversion of chroma MV's.
  307. * The motion vectors value is half the index value. The input to the
  308. * array must be biased by +64.
  309. */
  310. const char QtrPelToHalfPel[] = {
  311. -32, -31, -31, -31, -30, -29, -29, -29, -28, -27, -27, -27, -26, -25, -25, -25,
  312. -24, -23, -23, -23, -22, -21, -21, -21, -20, -19, -19, -19, -18, -17, -17, -17,
  313. -16, -15, -15, -15, -14, -13, -13, -13, -12, -11, -11, -11, -10, -9, -9, -9,
  314. -8, -7, -7, -7, -6, -5, -5, -5, -4, -3, -3, -3, -2, -1, -1, -1,
  315. 0, 1, 1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7,
  316. 8, 9, 9, 9, 10, 11, 11, 11, 12, 13, 13, 13, 14, 15, 15, 15,
  317. 16, 17, 17, 17, 18, 19, 19, 19, 20, 21, 21, 21, 22, 23, 23, 23,
  318. 24, 25, 25, 25, 26, 27, 27, 27, 28, 29, 29, 29, 30, 31, 31, 31};
  319. /*
  320. * Look-up table for converting the sum of four motion vectors to a chroma
  321. * motion vector. Since motion vectors are in the range [-32,31.5], their
  322. * indices are in the range [-64,63]. Hence the sum are in the range [-256,248].
  323. * The input to the array must be biased by +256.
  324. */
  325. const char SixteenthPelToHalfPel[] = {
  326. -32, -32, -32, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, -30, -30,
  327. -30, -30, -30, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -28, -28,
  328. -28, -28, -28, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -26, -26,
  329. -26, -26, -26, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -24, -24,
  330. -24, -24, -24, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -22, -22,
  331. -22, -22, -22, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -20, -20,
  332. -20, -20, -20, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, -18, -18,
  333. -18, -18, -18, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -16, -16,
  334. -16, -16, -16, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -14, -14,
  335. -14, -14, -14, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -12, -12,
  336. -12, -12, -12, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -10, -10,
  337. -10, -10, -10, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -8, -8,
  338. -8, -8, -8, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, -6, -6,
  339. -6, -6, -6, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -4, -4,
  340. -4, -4, -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2,
  341. -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0,
  342. 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
  343. 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
  344. 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
  345. 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8,
  346. 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10,
  347. 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12,
  348. 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14,
  349. 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16,
  350. 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
  351. 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20,
  352. 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22,
  353. 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
  354. 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26,
  355. 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28,
  356. 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30,
  357. 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32};
  358. void InitMEState(T_H263EncoderCatalog *EC, ICCOMPRESS *lpicComp, T_CONFIGURATION * pConfiguration);
  359. UN FindNewQuant(
  360. T_H263EncoderCatalog *EC,
  361. UN gquant_prev,
  362. UN uComFrmSize,
  363. UN GOB,
  364. U8 u8QPMax,
  365. U8 u8QPMin,
  366. BOOL bBitRateControl,
  367. BOOL bGOBoverflowWarning
  368. );
  369. static void encodeFrameHeader(
  370. T_H263EncoderCatalog * EC,
  371. U8 ** ppCurBitStream,
  372. U8 * u8BitOffset,
  373. BOOL bPBframe
  374. );
  375. /*
  376. static void copyEdgePels(T_H263EncoderCatalog * EC);
  377. */
  378. extern "C" {
  379. void ExpandPlane(U32, U32, U32, U32);
  380. }
  381. #ifdef USE_MMX // { USE_MMX
  382. static void Check_InterCodeCnt_MMX(T_H263EncoderCatalog *, U32);
  383. #endif // } USE_MMX
  384. static void Check_InterCodeCnt (T_H263EncoderCatalog *, U32);
  385. static void calcGOBChromaVectors(
  386. T_H263EncoderCatalog *EC,
  387. U32 StartingMB,
  388. T_CONFIGURATION *pConfiguration
  389. );
  390. static void calcBGOBChromaVectors(
  391. T_H263EncoderCatalog *EC,
  392. const U32 StartingMB
  393. );
  394. static void GetEncoderOptions(T_H263EncoderCatalog * EC);
  395. /*static U8 StillImageQnt[] = {
  396. 31, 29, 27, 26, 25, 24, 23, 22, 21, 20,
  397. 19, 18, 17, 16, 15, 14, 14, 13, 13, 12,
  398. 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
  399. 7, 6, 6, 6, 5, 5, 5, 4, 4, 4,
  400. 3, 3, 3, 3}; */
  401. static U8 StillImageQnt[] = {
  402. 31, 18, 12, 10, 8, 6, 5, 4, 4, 3}; //ia
  403. #ifdef USE_MMX // { USE_MMX
  404. static U8 StillImageQnt_MMX[] = {
  405. 31, 12, 10, 8, 6, 4, 3, 3, 3, 2}; //mmx
  406. #endif // } USE_MMX
  407. const int numStillImageQnts = 10;
  408. #ifdef COUNT_BITS
  409. static void InitBits(T_H263EncoderCatalog * EC);
  410. void InitCountBitFile();
  411. void WriteCountBitFile(T_BitCounts *Bits);
  412. #endif
  413. #ifdef USE_MMX // { USE_MMX
  414. /*
  415. * Exception Filter for access violations in MMxEDTQ B-frame motion estimation
  416. * No memory is allocation before run-time, it is only reserved.
  417. * Then, when an access violation occurs, more memory is allocated,
  418. * provided the access violation is withing the reserved memory area.
  419. */
  420. int ExceptionFilterForMMxEDTQ(
  421. LPEXCEPTION_POINTERS exc,
  422. LPVOID lpMBRVS,
  423. BOOL fLuma)
  424. {
  425. DWORD dwCode;
  426. LPVOID lpAddress;
  427. FX_ENTRY("ExceptionFilterForMMxEDTQ")
  428. dwCode = exc->ExceptionRecord->ExceptionCode;
  429. // check that this is an access violation
  430. if (dwCode != EXCEPTION_ACCESS_VIOLATION)
  431. return EXCEPTION_CONTINUE_SEARCH;
  432. lpAddress = (LPVOID)exc->ExceptionRecord->ExceptionInformation[1];
  433. // check for access violation outside address range
  434. if (lpAddress < lpMBRVS)
  435. return EXCEPTION_CONTINUE_SEARCH; // this exception is not handled here
  436. if (fLuma)
  437. {
  438. if ((DWORD)lpAddress > ((DWORD)lpMBRVS + 18*65*22*3*4))
  439. return EXCEPTION_CONTINUE_SEARCH; // this exception is not handled here
  440. }
  441. else
  442. {
  443. if ((DWORD)lpAddress > ((DWORD)lpMBRVS + 18*65*22*3*2))
  444. return EXCEPTION_CONTINUE_SEARCH; // this exception is not handled here
  445. }
  446. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Access Violation. Don't worry - be happy - committing another page\r\n", _fx_));
  447. // commit another page
  448. if (VirtualAlloc(lpAddress,4095,MEM_COMMIT,PAGE_READWRITE) == NULL)
  449. {
  450. return EXCEPTION_CONTINUE_SEARCH; // could not commit
  451. // this should never happen, since RESERVE was successfull
  452. }
  453. // return and try instruction causing the access violation again
  454. return EXCEPTION_CONTINUE_EXECUTION;
  455. }
  456. #endif // } USE_MMX
  457. /*******************************************************************************
  458. H263InitEncoderGlobal -- This function initializes the global tables used by
  459. the H263 encoder. Note that in 16-bit Windows, these
  460. tables are copied to the per-instance data segment, so
  461. that they can be used without segment override prefixes.
  462. In 32-bit Windows, the tables are left in their staticly
  463. allocated locations.
  464. *******************************************************************************/
  465. LRESULT H263InitEncoderGlobal(void)
  466. {
  467. // Initialize fixed length tables for INTRADC
  468. InitVLC();
  469. return ICERR_OK;
  470. }
  471. /*******************************************************************************
  472. H263InitEncoderInstance -- This function allocates and initializes the
  473. per-instance tables used by the H263 encoder.
  474. *******************************************************************************/
  475. #if defined(H263P) || defined(USE_BILINEAR_MSH26X)
  476. LRESULT H263InitEncoderInstance(LPBITMAPINFOHEADER lpbiInput, LPCODINST lpCompInst)
  477. #else
  478. LRESULT H263InitEncoderInstance(LPCODINST lpCompInst)
  479. #endif
  480. {
  481. LRESULT ret;
  482. UN i;
  483. U32 Sz;
  484. T_H263EncoderInstanceMemory * P32Inst;
  485. T_H263EncoderCatalog * EC;
  486. #if ELAPSED_ENCODER_TIME
  487. TotalElapsed = 0;
  488. TotalSample = 0;
  489. TimedIterations = 0;
  490. #endif
  491. T_CONFIGURATION * pConfiguration;
  492. UN uIntraQP;
  493. UN uInterQP;
  494. FX_ENTRY("H263InitEncoderInstance")
  495. /*
  496. * Allocate memory if instance is not initialized.
  497. * TO ADD: If instance IS intialized, we have to check to see
  498. * if important parameters have changed, such as frame size, and
  499. * then reallocate memory if necessary.
  500. */
  501. if(lpCompInst->Initialized == FALSE)
  502. {
  503. /*
  504. * Calculate size of encoder instance memory needed. We add the size
  505. * of a MacroBlock Action Descriptor to it since we want the MacroBlock
  506. * Action Stream (which is the first element of the memory structure)
  507. * to be aligned to a boundary equal to the size of a descriptor.
  508. */
  509. Sz = sizeof(T_H263EncoderInstanceMemory) + sizeof(T_MBlockActionStream);
  510. /*
  511. * Allocate the memory.
  512. */
  513. // lpCompInst->hEncoderInst = GlobalAlloc(GHND, Sz);
  514. // VirtualAlloc automatically zeros memory. The bitstream
  515. // needs to be zeroed when I change this to HeapAlloc.
  516. lpCompInst->hEncoderInst = VirtualAlloc(
  517. NULL, // can be allocated anywhere
  518. Sz, // number of bytes to allocate
  519. MEM_RESERVE | MEM_COMMIT, // reserve & commit memory
  520. PAGE_READWRITE); // protection
  521. #ifdef TRACK_ALLOCATIONS
  522. // Track memory allocation
  523. wsprintf(gsz1, "E3ENC: (VM) %7ld Ln %5ld\0", Sz, __LINE__);
  524. AddName((unsigned int)lpCompInst->hEncoderInst, gsz1);
  525. #endif
  526. /* Indicate that we have allocated memory for the compressor instance. */
  527. lpCompInst->Initialized = TRUE;
  528. }
  529. /* else
  530. {
  531. // check if parameters have changed, thay may make us have
  532. // to reallocate memory.
  533. }
  534. */
  535. // lpCompInst->EncoderInst = (LPVOID)GlobalLock(lpCompInst->hEncoderInst);
  536. lpCompInst->EncoderInst = lpCompInst->hEncoderInst;
  537. if (lpCompInst->hEncoderInst == NULL)
  538. {
  539. ret = ICERR_MEMORY;
  540. goto done;
  541. }
  542. /*
  543. * Calculate the 32 bit instance pointer starting at required boundary.
  544. */
  545. P32Inst = (T_H263EncoderInstanceMemory *)
  546. ((((U32) lpCompInst->EncoderInst) +
  547. (sizeof(T_MBlockActionStream) - 1)) &
  548. ~(sizeof(T_MBlockActionStream) - 1));
  549. /*
  550. * The encoder catalog is at the start of the per-instance data.
  551. */
  552. EC = &(P32Inst->EC);
  553. #ifdef COUNT_BITS
  554. InitCountBitFile();
  555. #endif
  556. #ifdef ENCODE_STATS
  557. InitQuantStats();
  558. InitFrameSizeStats();
  559. InitPSNRStats();
  560. #endif /* ENCODE_STATS */
  561. /* Initialize the Configuration information
  562. */
  563. pConfiguration = &(lpCompInst->Configuration);
  564. #if 0
  565. if (LoadConfiguration(pConfiguration) == FALSE)
  566. GetConfigurationDefaults(pConfiguration);
  567. #endif
  568. pConfiguration->bInitialized = TRUE;
  569. pConfiguration->bCompressBegin = TRUE;
  570. EC->hBsInfoStream= NULL;
  571. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  572. // We really want those timings to match the actual use we
  573. // will make of the codec. So initialize it with the same values
  574. pConfiguration->bRTPHeader = TRUE;
  575. pConfiguration->unPacketSize = 512;
  576. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  577. DEBUGMSG(ZONE_INIT, ("%s: Encoder Configuration Options: bRTPHeader=%d, unPacketSize=%d, bEncoderResiliency=%d, bDisallowPosVerMVs=%d\r\n", _fx_, (int)pConfiguration->bRTPHeader, (int)pConfiguration->unPacketSize, (int)pConfiguration->bEncoderResiliency, (int)pConfiguration->bDisallowPosVerMVs));
  578. DEBUGMSG(ZONE_INIT, ("%s: Encoder Configuration Options: bDisallowAllVerMVs=%d, unPercentForcedUpdate=%d, unDefaultIntraQuant=%d, unDefaultInterQuant=%d\r\n", _fx_, (int)pConfiguration->bDisallowAllVerMVs, (int)pConfiguration->unPercentForcedUpdate, (int)pConfiguration->unDefaultIntraQuant, (int)pConfiguration->unDefaultInterQuant));
  579. /*
  580. * Initialize encoder catalog.
  581. */
  582. #if defined(H263P) || defined(USE_BILINEAR_MSH26X)
  583. // In H.263+, we encode and decode the padded frames (padded to the right
  584. // and bottom to multiples of 16). The actual frame dimensions are used
  585. // for display purposes only.
  586. EC->FrameHeight = (lpCompInst->yres + 0xf) & ~0xf;
  587. EC->FrameWidth = (lpCompInst->xres + 0xf) & ~0xf;
  588. EC->uActualFrameHeight = lpCompInst->yres;
  589. EC->uActualFrameWidth = lpCompInst->xres;
  590. ASSERT(sizeof(T_H263EncoderCatalog) == sizeof_T_H263EncoderCatalog);
  591. {
  592. int found_cc = TRUE;
  593. if (BI_RGB == lpCompInst->InputCompression) {
  594. #ifdef USE_BILINEAR_MSH26X
  595. if (24 == lpCompInst->InputBitWidth) {
  596. EC->ColorConvertor = RGB24toYUV12;
  597. #else
  598. if (32 == lpCompInst->InputBitWidth) {
  599. EC->ColorConvertor = RGB32toYUV12;
  600. } else if (24 == lpCompInst->InputBitWidth) {
  601. EC->ColorConvertor = RGB24toYUV12;
  602. #endif
  603. } else if (16 == lpCompInst->InputBitWidth) {
  604. EC->ColorConvertor = RGB16555toYUV12;
  605. } else if (8 == lpCompInst->InputBitWidth) {
  606. EC->ColorConvertor = CLUT8toYUV12;
  607. } else if (4 == lpCompInst->InputBitWidth) {
  608. EC->ColorConvertor = CLUT4toYUV12;
  609. } else {
  610. found_cc = FALSE;
  611. ERRORMESSAGE(("%s: Unexpected input format detected\r\n", _fx_));
  612. }
  613. } else if (FOURCC_YVU9 == lpCompInst->InputCompression) {
  614. EC->ColorConvertor = YVU9toYUV12;
  615. } else if (FOURCC_YUY2 == lpCompInst->InputCompression) {
  616. EC->ColorConvertor = YUY2toYUV12;
  617. } else if (FOURCC_UYVY == lpCompInst->InputCompression) {
  618. EC->ColorConvertor = UYVYtoYUV12;
  619. } else if ((FOURCC_YUV12 == lpCompInst->InputCompression) || (FOURCC_IYUV == lpCompInst->InputCompression)) {
  620. EC->ColorConvertor = YUV12toEncYUV12;
  621. } else {
  622. found_cc = FALSE;
  623. ERRORMESSAGE(("%s: Unexpected input format detected\r\n", _fx_));
  624. }
  625. if (found_cc) {
  626. colorCnvtInitialize(lpbiInput, EC->ColorConvertor);
  627. }
  628. }
  629. #else
  630. EC->FrameHeight = lpCompInst->yres;
  631. EC->FrameWidth = lpCompInst->xres;
  632. #endif
  633. EC->FrameSz = lpCompInst->FrameSz;
  634. EC->NumMBRows = EC->FrameHeight >> 4;
  635. EC->NumMBPerRow = EC->FrameWidth >> 4;
  636. EC->NumMBs = EC->NumMBRows * EC->NumMBPerRow;
  637. // This should default to zero. If RTP is used, it will be changed later
  638. EC->uNumberForcedIntraMBs = 0;
  639. #ifdef H263P
  640. EC->uNextIntraMB = 0;
  641. #else
  642. if(pConfiguration->bEncoderResiliency &&
  643. pConfiguration->unPercentForcedUpdate &&
  644. pConfiguration->unPacketLoss)
  645. {//Chad Intra GOB
  646. // EC->uNumberForcedIntraMBs = ((EC->NumMBs * pConfiguration->unPercentForcedUpdate) + 50) / 100;
  647. EC->uNextIntraMB = 0;
  648. }
  649. #endif
  650. // Store pointers to current frame in the catalog.
  651. EC->pU8_CurrFrm = P32Inst->u8CurrentPlane;
  652. EC->pU8_CurrFrm_YPlane = EC->pU8_CurrFrm + 16;
  653. EC->pU8_CurrFrm_UPlane = EC->pU8_CurrFrm_YPlane + YU_OFFSET;
  654. EC->pU8_CurrFrm_VPlane = EC->pU8_CurrFrm_UPlane + UV_OFFSET;
  655. // Store pointers to the previous frame in the catalog.
  656. EC->pU8_PrevFrm = P32Inst->u8PreviousPlane;
  657. EC->pU8_PrevFrm_YPlane = EC->pU8_PrevFrm + 16*PITCH + 16;
  658. EC->pU8_PrevFrm_UPlane = EC->pU8_PrevFrm_YPlane + YU_OFFSET;
  659. EC->pU8_PrevFrm_VPlane = EC->pU8_PrevFrm_UPlane + UV_OFFSET;
  660. // Store pointers to the future frame in the catalog.
  661. EC->pU8_FutrFrm = P32Inst->u8FuturePlane;
  662. EC->pU8_FutrFrm_YPlane = EC->pU8_FutrFrm + 16*PITCH + 16;
  663. EC->pU8_FutrFrm_UPlane = EC->pU8_FutrFrm_YPlane + YU_OFFSET;
  664. EC->pU8_FutrFrm_VPlane = EC->pU8_FutrFrm_UPlane + UV_OFFSET;
  665. // Store pointers to the B frame in the catalog.
  666. EC->pU8_BidiFrm = P32Inst->u8BPlane;
  667. EC->pU8_BFrm_YPlane = EC->pU8_BidiFrm + 16;
  668. EC->pU8_BFrm_UPlane = EC->pU8_BFrm_YPlane + YU_OFFSET;
  669. EC->pU8_BFrm_VPlane = EC->pU8_BFrm_UPlane + UV_OFFSET;
  670. // Store pointers to the signature frame in the catalog.
  671. EC->pU8_Signature = P32Inst->u8Signature;
  672. EC->pU8_Signature_YPlane = EC->pU8_Signature + 16*PITCH + 16;
  673. // Store pointer to the macroblock action stream in the catalog.
  674. EC->pU8_MBlockActionStream = P32Inst->MBActionStream;
  675. // Store pointer to the GOB DCT coefficient buffer in the catalog.
  676. EC->pU8_DCTCoefBuf = P32Inst->piGOB_DCTCoefs;
  677. // Store pointer to area in which to pre-compute OBMC predictions.
  678. EC->pU8_PredictionScratchArea = P32Inst->u8PredictionScratchArea;
  679. // Store pointer to the bit stream buffer in the catalog.
  680. EC->pU8_BitStream = P32Inst->u8BitStream;
  681. EC->pU8_BitStrCopy = P32Inst->u8BitStrCopy;
  682. // Store pointer to the RunValSign triplets for Luma and Chroma
  683. EC->pI8_MBRVS_Luma = P32Inst->i8MBRVS_Luma;
  684. EC->pI8_MBRVS_Chroma = P32Inst->i8MBRVS_Chroma;
  685. // Reserve virtual memory
  686. EC->pI8_MBRVS_BLuma = (I8 *) VirtualAlloc(
  687. NULL, // anywhere
  688. 18*(65*3*22*4), // number of bytes
  689. MEM_RESERVE, // reserve
  690. PAGE_READWRITE); // access
  691. #ifdef TRACK_ALLOCATIONS
  692. // Track memory allocation
  693. wsprintf(gsz2, "E3ENC: (VM) %7ld Ln %5ld\0", 18*(65*3*22*4), __LINE__);
  694. AddName((unsigned int)EC->pI8_MBRVS_BLuma, gsz2);
  695. #endif
  696. EC->pI8_MBRVS_BChroma = (I8 *) VirtualAlloc(
  697. NULL, // anywhere
  698. 18*(65*3*22*2), // number of bytes
  699. MEM_RESERVE, // reserve
  700. PAGE_READWRITE); // access
  701. #ifdef TRACK_ALLOCATIONS
  702. // Track memory allocation
  703. wsprintf(gsz3, "E3ENC: (VM) %7ld Ln %5ld\0", 18*(65*3*22*2), __LINE__);
  704. AddName((unsigned int)EC->pI8_MBRVS_BChroma, gsz3);
  705. #endif
  706. if (EC->pI8_MBRVS_BLuma == NULL || EC->pI8_MBRVS_BChroma == NULL)
  707. {
  708. ret = ICERR_MEMORY;
  709. goto done;
  710. }
  711. // Store pointer to private copy of decoder instance info.
  712. EC->pDecInstanceInfo = &(P32Inst->DecInstanceInfo);
  713. /*
  714. * Check to see if there is an H263test.ini file. If the UseINI key
  715. * is not 1, or the INI file is not found, then we allow option
  716. * signalling in the ICCOMPRESS structure. If set, the INI
  717. * options override the ICCOMPRESS options.
  718. */
  719. GetEncoderOptions(EC);
  720. EC->u8SavedBFrame = FALSE;
  721. // Fill the picture header structure.
  722. EC->PictureHeader.TR = 0;
  723. EC->PictureHeader.Split = OFF;
  724. EC->PictureHeader.DocCamera = OFF;
  725. EC->PictureHeader.PicFreeze = OFF;
  726. EC->PictureHeader.PB = OFF; // Leave this off here. It is turned on after the P frame
  727. // has been encoded, when the PB frame is written.
  728. EC->prevAP = 255;
  729. EC->prevUMV = 255;
  730. #ifdef H263P
  731. EC->prevDF = 255;
  732. #endif
  733. EC->PictureHeader.CPM = 0;
  734. EC->PictureHeader.TRB = 0;
  735. EC->PictureHeader.DBQUANT = 1;
  736. EC->PictureHeader.PLCI = 0;
  737. EC->PictureHeader.PEI = 0;
  738. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  739. EC->pEncTimingInfo = P32Inst->EncTimingInfo;
  740. #endif // } LOG_ENCODE_TIMINGS_ON
  741. /*
  742. * This flag is used by the encoder to signal that the
  743. * next frame should be encoded as an INTRA regardless of what
  744. * the client asks for. This may be either because an error was
  745. * detected in compressing the current delta, or to ensure that
  746. * the first frame is encoded INTRA.
  747. */
  748. EC->bMakeNextFrameKey = TRUE; // Ensure that we always start with a key frame.
  749. /*
  750. * Initialize table with Bit Usage Profile
  751. */
  752. for (i = 0; i <= EC->NumMBRows ; i++)
  753. EC->uBitUsageProfile[i] = i; // assume linear distribution at first
  754. /*
  755. * Check assumptions about structure sizes and boundary
  756. * alignment.
  757. */
  758. ASSERT( sizeof(T_Blk) == sizeof_T_Blk )
  759. ASSERT( sizeof(T_MBlockActionStream) == sizeof_T_MBlockActionStream )
  760. ASSERT( ((sizeof_T_MBlockActionStream-1) & sizeof_T_MBlockActionStream) == 0); // Size is power of two
  761. ASSERT( sizeof(T_H263EncoderCatalog) == sizeof_T_H263EncoderCatalog )
  762. // Encoder instance memory should start on a 32 byte boundary.
  763. ASSERT( ( (unsigned int)P32Inst & 0x1f) == 0)
  764. // MB Action Stream should be on boundary equal to size of a descriptor.
  765. ASSERT((((int)EC->pU8_MBlockActionStream) & (sizeof_T_MBlockActionStream-1)) == 0); // Allocated at right boundary.
  766. // Block structure array should be on a 16 byte boundary.
  767. ASSERT( ( (unsigned int) &(EC->pU8_MBlockActionStream->BlkY1) & 0xf) == 0)
  768. // DCT coefficient array should be on a 32 byte boundary.
  769. ASSERT( ( (unsigned int)EC->pU8_DCTCoefBuf & 0x1f) == 0)
  770. // Current Frame Buffers should be on 32 byte boundaries.
  771. ASSERT( ( (unsigned int)EC->pU8_CurrFrm_YPlane & 0x1f) == 0)
  772. ASSERT( ( (unsigned int)EC->pU8_CurrFrm_UPlane & 0x1f) == 0)
  773. ASSERT( ( (unsigned int)EC->pU8_CurrFrm_VPlane & 0x1f) == 0)
  774. ASSERT( ( (unsigned int)EC->pU8_BFrm_YPlane & 0x1f) == 0x10)
  775. ASSERT( ( (unsigned int)EC->pU8_BFrm_UPlane & 0x1f) == 0x10)
  776. ASSERT( ( (unsigned int)EC->pU8_BFrm_VPlane & 0x1f) == 0x10)
  777. // Previous Frame Buffers should be on 32 byte boundaries.
  778. ASSERT( ( (unsigned int)EC->pU8_PrevFrm_YPlane & 0x1f) == 0x10)
  779. ASSERT( ( (unsigned int)EC->pU8_PrevFrm_UPlane & 0x1f) == 0x10)
  780. ASSERT( ( (unsigned int)EC->pU8_PrevFrm_VPlane & 0x1f) == 0x10)
  781. ASSERT( ( (unsigned int)EC->pU8_FutrFrm_YPlane & 0x1f) == 0x10)
  782. ASSERT( ( (unsigned int)EC->pU8_FutrFrm_UPlane & 0x1f) == 0x10)
  783. ASSERT( ( (unsigned int)EC->pU8_FutrFrm_VPlane & 0x1f) == 0x10)
  784. // Decoder instance structure should be on a DWORD boundary.
  785. ASSERT( ( (unsigned int)EC->pDecInstanceInfo & 0x3 ) == 0 )
  786. /*
  787. * Initialize MBActionStream
  788. */
  789. int YBlockOffset, UBlockOffset;
  790. YBlockOffset = 0;
  791. UBlockOffset = EC->pU8_CurrFrm_UPlane - EC->pU8_CurrFrm_YPlane;
  792. for(i = 0; i < EC->NumMBs; i++)
  793. {
  794. // Clear the counter of the number of consecutive times a
  795. // macroblock has been inter coded.
  796. (EC->pU8_MBlockActionStream[i]).InterCodeCnt = (i & 0xf);
  797. // Store offsets to each block in the MB from the beginning of
  798. // the Y plane.
  799. (EC->pU8_MBlockActionStream[i]).BlkY1.BlkOffset = YBlockOffset;
  800. (EC->pU8_MBlockActionStream[i]).BlkY2.BlkOffset = YBlockOffset+8;
  801. (EC->pU8_MBlockActionStream[i]).BlkY3.BlkOffset = YBlockOffset+PITCH*8;
  802. (EC->pU8_MBlockActionStream[i]).BlkY4.BlkOffset = YBlockOffset+PITCH*8+8;
  803. (EC->pU8_MBlockActionStream[i]).BlkU.BlkOffset = UBlockOffset;
  804. (EC->pU8_MBlockActionStream[i]).BlkV.BlkOffset = UBlockOffset+UV_OFFSET;
  805. YBlockOffset += 16;
  806. UBlockOffset += 8;
  807. (EC->pU8_MBlockActionStream[i]).MBEdgeType = 0xF;
  808. if ((i % EC->NumMBPerRow) == 0)
  809. {
  810. (EC->pU8_MBlockActionStream[i]).MBEdgeType &= MBEdgeTypeIsLeftEdge;
  811. }
  812. if (((i+1) % EC->NumMBPerRow) == 0)
  813. {
  814. (EC->pU8_MBlockActionStream[i]).MBEdgeType &=
  815. MBEdgeTypeIsRightEdge;
  816. // Set bit six of CodedBlocks to indicate this is the last
  817. // MB of the row.
  818. (EC->pU8_MBlockActionStream[i]).CodedBlocks |= 0x40;
  819. YBlockOffset += PITCH*16 - EC->NumMBPerRow*16;
  820. UBlockOffset += PITCH*8 - EC->NumMBPerRow*8;
  821. }
  822. if (i < EC->NumMBPerRow)
  823. {
  824. (EC->pU8_MBlockActionStream[i]).MBEdgeType &= MBEdgeTypeIsTopEdge;
  825. }
  826. if ((i + EC->NumMBPerRow) >= EC->NumMBs)
  827. {
  828. (EC->pU8_MBlockActionStream[i]).MBEdgeType &= MBEdgeTypeIsBottomEdge;
  829. }
  830. } // end of for loop.
  831. /*
  832. * Initialize previous frame pointers. For now we can do this from here.
  833. */
  834. /*
  835. YBlockAddress = EC->pU8_PrevFrm_YPlane;
  836. UBlockAddress = EC->pU8_PrevFrm_UPlane;
  837. for(i = 0; i < EC->NumMBs; i++)
  838. {
  839. (EC->pU8_MBlockActionStream[i]).Blk[0].PastRef = YBlockAddress;
  840. (EC->pU8_MBlockActionStream[i]).Blk[1].PastRef = YBlockAddress+8;
  841. (EC->pU8_MBlockActionStream[i]).Blk[2].PastRef = YBlockAddress+PITCH*8;
  842. (EC->pU8_MBlockActionStream[i]).Blk[3].PastRef = YBlockAddress+PITCH*8+8;
  843. (EC->pU8_MBlockActionStream[i]).Blk[4].PastRef = UBlockAddress;
  844. (EC->pU8_MBlockActionStream[i]).Blk[5].PastRef = UBlockAddress+UV_OFFSET;
  845. // Zero all motion vectors.
  846. (EC->pU8_MBlockActionStream[i]).Blk[0].PastHMV = 0;
  847. (EC->pU8_MBlockActionStream[i]).Blk[0].PastVMV = 0;
  848. (EC->pU8_MBlockActionStream[i]).Blk[1].PastHMV = 0;
  849. (EC->pU8_MBlockActionStream[i]).Blk[1].PastVMV = 0;
  850. (EC->pU8_MBlockActionStream[i]).Blk[2].PastHMV = 0;
  851. (EC->pU8_MBlockActionStream[i]).Blk[2].PastVMV = 0;
  852. (EC->pU8_MBlockActionStream[i]).Blk[3].PastHMV = 0;
  853. (EC->pU8_MBlockActionStream[i]).Blk[3].PastVMV = 0;
  854. (EC->pU8_MBlockActionStream[i]).Blk[4].PastHMV = 0;
  855. (EC->pU8_MBlockActionStream[i]).Blk[4].PastVMV = 0;
  856. (EC->pU8_MBlockActionStream[i]).Blk[5].PastHMV = 0;
  857. (EC->pU8_MBlockActionStream[i]).Blk[5].PastVMV = 0;
  858. YBlockAddress += 16;
  859. UBlockAddress += 8;
  860. if( (i != 0) && (( (i+1) % EC->NumMBPerRow ) == 0) )
  861. {
  862. YBlockAddress += PITCH*16 - EC->NumMBPerRow*16;
  863. UBlockAddress += PITCH*8 - EC->NumMBPerRow*8;
  864. }
  865. } // end of for loop.
  866. */
  867. /*
  868. * Initialize bit rate controller.
  869. */
  870. if(pConfiguration->bEncoderResiliency && pConfiguration->unPacketLoss)
  871. {
  872. uIntraQP = pConfiguration->unDefaultIntraQuant;
  873. uInterQP = pConfiguration->unDefaultInterQuant;
  874. }
  875. else
  876. {
  877. uIntraQP = def263INTRA_QP;
  878. uInterQP = def263INTER_QP;
  879. }
  880. InitBRC(&(EC->BRCState), uIntraQP, uInterQP, EC->NumMBs);
  881. if (pConfiguration->bRTPHeader)
  882. H263RTP_InitBsInfoStream(lpCompInst,EC);
  883. /*
  884. * Create a decoder instance and initialize it. DecoderInstInfo must be in first 64K.
  885. */
  886. EC->pDecInstanceInfo->xres = lpCompInst->xres;
  887. EC->pDecInstanceInfo->yres = lpCompInst->yres;
  888. ret = H263InitDecoderInstance(EC->pDecInstanceInfo, H263_CODEC);
  889. if (ret != ICERR_OK)
  890. goto done1;
  891. ret = H263InitColorConvertor(EC->pDecInstanceInfo, YUV12ForEnc);
  892. if (ret != ICERR_OK)
  893. goto done1;
  894. /*
  895. * Clear initialized memory.
  896. */
  897. // to be added.
  898. lpCompInst->Initialized = TRUE;
  899. ret = ICERR_OK;
  900. #if defined(H263P)
  901. // Set the pseudo stack space pointer (to be used for motion estimation and
  902. // whatever else needs extra stack space).
  903. EC->pPseudoStackSpace =
  904. ((T_H263EncoderInstanceMemory *)(lpCompInst->EncoderInst))->u8PseudoStackSpace +
  905. (SIZEOF_PSEUDOSTACKSPACE - sizeof(DWORD));
  906. #endif
  907. done1:
  908. //GlobalUnlock(lpCompInst->hEncoderInst);
  909. done:
  910. return ret;
  911. }
  912. /*******************************************************************************
  913. *
  914. * H263Compress
  915. * This function drives the compression of one frame
  916. * Note:
  917. * The timing statistics code produces incorrect no. after PB-frame changes
  918. * were made.
  919. *******************************************************************************/
  920. LRESULT H263Compress(
  921. #ifdef USE_BILINEAR_MSH26X
  922. LPINST pi,
  923. #else
  924. LPCODINST lpCompInst, // ptr to compressor instance info.
  925. #endif
  926. ICCOMPRESS *lpicComp // ptr to ICCOMPRESS structure.
  927. )
  928. {
  929. FX_ENTRY("H263Compress");
  930. #ifdef USE_BILINEAR_MSH26X
  931. LPCODINST lpCompInst = (LPCODINST)pi->CompPtr; // ptr to compressor instance info.
  932. #endif
  933. // Start PB-frame data
  934. #if !defined(H263P)
  935. T_FutrPMBData FutrPMBData[GOBs_IN_CIF*MBs_PER_GOB_CIF + 1];
  936. I8 WeightForwMotion[128]; // values based on TRb and TRd
  937. I8 WeightBackMotion[128]; // values based on TRb and TRd
  938. #endif
  939. U8 FutrFrmGQUANT[GOBs_IN_CIF];
  940. // End PB-frame
  941. LRESULT ret;
  942. UN GOB, SizeBitStream;
  943. UN SizeBSnEBS;
  944. #ifdef DEBUG
  945. UN i;
  946. #endif
  947. U8 *pCurBitStream; // pointer to the current location in the bitstream.
  948. U8 u8bitoffset; // bit offset in the current byte of the bitstream.
  949. U32 uCumFrmSize = 0, GOBHeaderMask;
  950. U32 uAdjCumFrmSize = 0;
  951. T_H263EncoderInstanceMemory *P32Inst;
  952. T_H263EncoderCatalog *EC;
  953. T_MBlockActionStream *MBlockActionPtr;
  954. BOOL bGOBoverflowWarning = FALSE; //RH
  955. U32 u32tempBuf; //RH
  956. U32 u32sizeBitBuffer; //RH
  957. U32 u32sizeBSnEBS;
  958. LPVOID EncoderInst;
  959. ICDECOMPRESSEX ICDecExSt;
  960. ICDECOMPRESSEX DefaultICDecExSt = {
  961. 0,
  962. NULL, NULL,
  963. NULL, NULL,
  964. 0, 0, 0, 0,
  965. 0, 0, 0, 0
  966. };
  967. unsigned int gquant, gquant_prev;
  968. U32 QP_cumulative;
  969. U32 IntraSWDTotal, IntraSWDBlocks, InterSWDTotal, InterSWDBlocks;
  970. int StartingMB;
  971. EnumOnOff bBitRateControl;
  972. T_CONFIGURATION * pConfiguration = &(lpCompInst->Configuration);
  973. #ifdef ENCODE_STATS
  974. U32 uBitStreamBytes;
  975. #endif /* ENCODE_STATS */
  976. U32 iSumSWD = 0, iSumBSWD = 0;
  977. U32 iSWD = 0, iBSWD = 0;
  978. U8 u8QPMin;
  979. // PB-frame variables
  980. I32 TRb;
  981. I32 TRd;
  982. I32 j;
  983. U8 *pP_BitStreamStart;
  984. U8 *pPB_BitStream;
  985. U8 u8PB_BitOffset;
  986. U8 *temp;
  987. BOOL bEncodePBFrame;
  988. BOOL bPBFailed;
  989. U32 u32BFrmZeroThreshold;
  990. //Chad, intra gob
  991. int uUsedByIntra=0;
  992. DWORD dwRTPSize=0;
  993. #if ELAPSED_ENCODER_TIME
  994. SetStatAdd (STATADDRESS);
  995. InitStat ();
  996. ConfigElapsed ();
  997. ConfigSample ();
  998. StartElapsed ();
  999. #endif
  1000. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  1001. U32 uStartLow;
  1002. U32 uStartHigh;
  1003. U32 uElapsed;
  1004. U32 uBefore;
  1005. U32 uEncodeTime = 0;
  1006. int bTimingThisFrame = 0;
  1007. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  1008. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1009. U32 uInputCC = 0;
  1010. U32 uMotionEstimation = 0;
  1011. U32 uFDCT = 0;
  1012. U32 uQRLE = 0;
  1013. U32 uDecodeFrame = 0;
  1014. U32 uZeroingBuffer = 0;
  1015. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1016. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  1017. ENC_TIMING_INFO * pEncTimingInfo = NULL;
  1018. #endif // } LOG_ENCODE_TIMINGS_ON
  1019. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  1020. TIMER_START(bTimingThisFrame,uStartLow,uStartHigh);
  1021. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  1022. #ifdef REUSE_DECODE
  1023. CompandedFrame.Address = NULL;
  1024. CompandedFrame.PDecoderInstInfo = NULL;
  1025. CompandedFrame.FrameNumber = 0xFFFF;
  1026. #endif
  1027. ret = ICERR_OK;
  1028. // check instance pointer
  1029. if (!lpCompInst)
  1030. return ICERR_ERROR;
  1031. /*
  1032. * Lock the instance data private to the encoder.
  1033. */
  1034. // EncoderInst = (LPVOID)GlobalLock(lpCompInst->hEncoderInst);
  1035. EncoderInst = lpCompInst->hEncoderInst;
  1036. if (EncoderInst == NULL)
  1037. {
  1038. ERRORMESSAGE(("%s: ICERR_MEMORY\r\n", _fx_));
  1039. ret = ICERR_MEMORY;
  1040. goto done;
  1041. }
  1042. /*
  1043. * Generate the pointer to the encoder instance memory aligned to the
  1044. * required boundary.
  1045. */
  1046. P32Inst = (T_H263EncoderInstanceMemory *)
  1047. ((((U32) EncoderInst) +
  1048. (sizeof(T_MBlockActionStream) - 1)) &
  1049. ~(sizeof(T_MBlockActionStream) - 1));
  1050. // Get pointer to encoder catalog.
  1051. EC = &(P32Inst->EC);
  1052. // Check pointer to encoder catalog
  1053. if (!EC)
  1054. return ICERR_ERROR;
  1055. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  1056. if (EC->uStatFrameCount < ENC_TIMING_INFO_FRAME_COUNT)
  1057. {
  1058. EC->uStartLow = uStartLow;
  1059. EC->uStartHigh = uStartHigh;
  1060. }
  1061. EC->bTimingThisFrame = bTimingThisFrame;
  1062. #endif // } LOG_ENCODE_TIMINGS_ON
  1063. #ifdef FORCE_ADVANCED_OPTIONS_ON // { FORCE_ADVANCED_OPTIONS_ON
  1064. // Force PB-Frame for testing
  1065. lpicComp->dwFlags |= CODEC_CUSTOM_PB;
  1066. // Force UMV for testing
  1067. lpicComp->dwFlags |= CODEC_CUSTOM_UMV;
  1068. // Force AP for testing
  1069. lpicComp->dwFlags |= CODEC_CUSTOM_AP;
  1070. // Force SAC for testing
  1071. EC->PictureHeader.SAC = ON;
  1072. if (!(lpicComp->dwFlags & ICCOMPRESS_KEYFRAME))
  1073. {
  1074. lpicComp->lFrameNum *= 5;
  1075. }
  1076. #endif // } FORCE_ADVANCED_OPTIONS_ON
  1077. /***************************************************************************
  1078. * Do per-frame initialization.
  1079. **************************************************************************/
  1080. if ((lpicComp->dwFlags & ICCOMPRESS_KEYFRAME) ||
  1081. (*(lpicComp->lpdwFlags) & AVIIF_KEYFRAME) ||
  1082. (EC->bMakeNextFrameKey == TRUE))
  1083. {
  1084. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Coding an Intra Frame\r\n", _fx_));
  1085. EC->PictureHeader.PicCodType = INTRAPIC;
  1086. EC->bMakeNextFrameKey = FALSE;
  1087. EC->u8SavedBFrame = FALSE;
  1088. }
  1089. else
  1090. EC->PictureHeader.PicCodType = INTERPIC;
  1091. /*
  1092. * Check for H.263 options. This is the location that
  1093. * you can manually enable the options if you want.
  1094. */
  1095. if (!EC->bUseINISettings)
  1096. {
  1097. // Check to see if PB frames is requested.
  1098. // For our particular implementation, unrestricted motion vectors
  1099. // are used when PB is on.
  1100. //
  1101. if (lpicComp->dwFlags & CODEC_CUSTOM_PB)
  1102. EC->u8EncodePBFrame = TRUE;
  1103. else
  1104. {
  1105. EC->u8EncodePBFrame = FALSE;
  1106. }
  1107. // Check to see if advanced prediction is requested.
  1108. if (lpicComp->dwFlags & CODEC_CUSTOM_AP)
  1109. EC->PictureHeader.AP = ON;
  1110. else
  1111. EC->PictureHeader.AP = OFF;
  1112. // Check to see if advanced prediction is requested.
  1113. if (lpicComp->dwFlags & CODEC_CUSTOM_UMV)
  1114. EC->PictureHeader.UMV = ON;
  1115. else
  1116. EC->PictureHeader.UMV = OFF;
  1117. #ifdef H263P
  1118. if (pConfiguration->bH263PlusState)
  1119. {
  1120. // Check to see if in-the-loop deblocking filter is requested.
  1121. if (pConfiguration->bDeblockingFilterState)
  1122. EC->PictureHeader.DeblockingFilter = ON;
  1123. else
  1124. EC->PictureHeader.DeblockingFilter = OFF;
  1125. // Check to see if improved PB-frame mode requested.
  1126. if (pConfiguration->bImprovedPBState)
  1127. {
  1128. EC->PictureHeader.ImprovedPB = ON;
  1129. EC->u8EncodePBFrame = TRUE;
  1130. }
  1131. else
  1132. EC->PictureHeader.ImprovedPB = OFF;
  1133. }
  1134. #endif
  1135. // Turn off AP mode if the QP_mean is lower than a certain level. This should increase
  1136. // sharpness for low motion (low QP => no AP), and reduce blockiness at high motion
  1137. // (higher QP => with AP)
  1138. #ifdef USE_MMX // { USE_MMX
  1139. if (ToggleAP == ON && MMX_Enabled == FALSE)
  1140. #else // }{ USE_MMX
  1141. if (ToggleAP == ON)
  1142. #endif // } USE_MMX
  1143. {
  1144. if (EC->PictureHeader.AP == ON &&
  1145. EC->BRCState.QP_mean < AP_MODE_QP_LEVEL &&
  1146. EC->u8EncodePBFrame == FALSE)
  1147. EC->PictureHeader.AP = OFF;
  1148. }
  1149. }
  1150. // If we are not going to encode as a PB-frame, reset the saved flag
  1151. if (EC->u8EncodePBFrame == FALSE)
  1152. EC->u8SavedBFrame = FALSE;
  1153. // verify that flags are set correctly
  1154. if (EC->PictureHeader.UMV == ON)
  1155. {
  1156. #ifdef USE_MMX // { USE_MMX
  1157. if (MMX_Enabled == FALSE)
  1158. #endif // } USE_MMX
  1159. {
  1160. // can't do this
  1161. #ifdef USE_MMX // { USE_MMX
  1162. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Warning: turning UMV off MMX_Enabled is FALSE\r\n", _fx_));
  1163. #else // }{ USE_MMX
  1164. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Warning: turning UMV off MMX_Enabled is FALSE\r\n", _fx_));
  1165. #endif // } USE_MMX
  1166. EC->PictureHeader.UMV = OFF;
  1167. }
  1168. }
  1169. #ifdef H263P
  1170. if (EC->PictureHeader.ImprovedPB == ON)
  1171. {
  1172. #ifdef USE_MMX // { USE_MMX
  1173. if (MMX_Enabled == FALSE)
  1174. #endif // } USE_MMX
  1175. {
  1176. // can't do this
  1177. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Warning: turning improved PB off MMX_Enabled is FALSE\r\n", _fx_));
  1178. EC->PictureHeader.ImprovedPB = OFF;
  1179. }
  1180. }
  1181. #endif // H263P
  1182. #ifdef COUNT_BITS
  1183. // Clear bit counters.
  1184. InitBits(EC);
  1185. #endif
  1186. #ifdef USE_MMX // { USE_MMX
  1187. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: AP: %d, PB: %d, UMV: %d, MMX: %d, Target fr.size: %d\r\n", _fx_, EC->PictureHeader.AP, EC->u8EncodePBFrame, EC->PictureHeader.UMV, MMX_Enabled, lpicComp->dwFrameSize));
  1188. #else // }{ USE_MMX
  1189. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: AP: %d, PB: %d, UMV: %d, Target fr.size: %d\r\n", _fx_, EC->PictureHeader.AP, EC->u8EncodePBFrame, EC->PictureHeader.UMV, lpicComp->dwFrameSize));
  1190. #endif // } USE_MMX
  1191. #if H263P
  1192. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: H.263+ options: IPB: %d, DF: %d\r\n", _fx_, EC->PictureHeader.ImprovedPB, EC->PictureHeader.DeblockingFilter));
  1193. #endif
  1194. /*
  1195. * Check to see if this is an inter-frame and if a B frame has not been
  1196. * saved yet. If so, we do nothing but save the frame to the B frame
  1197. * buffer and exit.
  1198. *
  1199. */
  1200. U32 TRB;
  1201. /*
  1202. * Turn PB frame option back on if it was just
  1203. * temporariy turned off for last frame.
  1204. */
  1205. if( EC->u8EncodePBFrame == TEMPORARILY_FALSE )
  1206. EC->u8EncodePBFrame = TRUE;
  1207. // If this is to be saved as a B frame.
  1208. if (EC->u8EncodePBFrame == TRUE &&
  1209. EC->PictureHeader.PicCodType == INTERPIC &&
  1210. EC->u8SavedBFrame == FALSE)
  1211. {
  1212. /*
  1213. * Set temporal reference for B frame.
  1214. * It is the number of non-transmitted pictures (at 29.97 Hz)
  1215. * since the last P or I frame plus 1. TRB has a maximum value
  1216. * of 7, and can never be zero.
  1217. * TODO: At the beginning of a sequence, the key frame is compressed,
  1218. * and then the first frame is copied over to the B frame store, so that
  1219. * temporal reference for B is zero, which is not allowed. This may cause
  1220. * problems in some decoders.
  1221. */
  1222. TRB = (lpicComp->lFrameNum % 256); // Take the modulo in order to compare it with TR.
  1223. if ( TRB < EC->PictureHeader.TR )
  1224. TRB += 256; // It should always be greater than TR.
  1225. TRB = TRB - EC->PictureHeader.TR; // Calculate the TRB value for the bitstream.
  1226. if (TRB > 7)
  1227. {
  1228. /*
  1229. * We don't want to encode this as a PB-frame because TRB > 7, or
  1230. * the adaptive switch has turned PB-frames off for a while.
  1231. */
  1232. EC->PictureHeader.TR = (lpicComp->lFrameNum % 256);
  1233. EC->u8EncodePBFrame = TEMPORARILY_FALSE; // Turn off PBframe for this frame.
  1234. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: TRB too big (%d), making P frame, TR = %d\r\n", _fx_, TRB, EC->PictureHeader.TR));
  1235. }
  1236. else
  1237. {
  1238. EC->PictureHeader.TRB = (U8) TRB;
  1239. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Saving B Frame, TRB = %d\r\n", _fx_, EC->PictureHeader.TRB));
  1240. // Copy with color conversion and return
  1241. #if defined(H263P) || defined(USE_BILINEAR_MSH26X)
  1242. colorCnvtFrame(EC->ColorConvertor, lpCompInst, lpicComp, EC->pU8_BFrm_YPlane,
  1243. EC->pU8_BFrm_UPlane, EC->pU8_BFrm_VPlane);
  1244. #else
  1245. colorCnvtFrame(EC, lpCompInst, lpicComp, EC->pU8_BFrm_YPlane,
  1246. EC->pU8_BFrm_UPlane, EC->pU8_BFrm_VPlane);
  1247. #endif
  1248. EC->u8SavedBFrame = TRUE; // indicate that we saved a B frame.
  1249. lpCompInst->CompressedSize = 8; // Internal Encoder/decoder agreement
  1250. #ifdef ENCODE_STATS
  1251. StatsFrameSize(lpCompInst->CompressedSize, lpCompInst->CompressedSize);
  1252. #endif /* ENCODE_STATS */
  1253. goto done; // <<<<<<<<<<<<<<<<<<<<
  1254. }
  1255. }
  1256. else // This is a P or I frame.
  1257. {
  1258. // Save temporal reference modulo 256.
  1259. EC->PictureHeader.TR = (lpicComp->lFrameNum % 256);
  1260. #ifdef _DEBUG
  1261. if (EC->u8EncodePBFrame == TRUE)
  1262. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: PB Frame, TR = %d\r\n", _fx_, EC->PictureHeader.TR));
  1263. else if (EC->PictureHeader.PicCodType == INTRAPIC)
  1264. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: I Frame, TR = %d\r\n", _fx_, EC->PictureHeader.TR));
  1265. else
  1266. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: P Frame, TR = %d\r\n", _fx_, EC->PictureHeader.TR));
  1267. #endif
  1268. }
  1269. // Initialize Motion Estimation state
  1270. InitMEState(EC, lpicComp, pConfiguration);
  1271. // Get pointer to macrobock action stream.
  1272. MBlockActionPtr = EC->pU8_MBlockActionStream;
  1273. /******************************************************************
  1274. * RGB to YVU 12 Conversion
  1275. ******************************************************************/
  1276. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1277. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1278. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1279. #if defined(H263P) || defined(USE_BILINEAR_MSH26X)
  1280. colorCnvtFrame(EC->ColorConvertor, lpCompInst, lpicComp,
  1281. EC->pU8_CurrFrm_YPlane,
  1282. EC->pU8_CurrFrm_UPlane,
  1283. EC->pU8_CurrFrm_VPlane);
  1284. #else
  1285. colorCnvtFrame(EC, lpCompInst, lpicComp,
  1286. EC->pU8_CurrFrm_YPlane,
  1287. EC->pU8_CurrFrm_UPlane,
  1288. EC->pU8_CurrFrm_VPlane);
  1289. #endif
  1290. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1291. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uInputCC)
  1292. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1293. #if SAMPLE_RGBCONV_TIME && ELAPSED_ENCODER_TIME
  1294. StopSample ();
  1295. #endif
  1296. /******************************************************
  1297. * Set picture level quantizer.
  1298. ******************************************************/
  1299. // clear the still quantizer counter if this is not a still frame or
  1300. // it is the key frame for a still frame sequence. R.H.
  1301. if (
  1302. ((lpicComp->dwFlags & CODEC_CUSTOM_STILL) == 0 ) ||
  1303. ((lpicComp->dwFlags & CODEC_CUSTOM_STILL) &&
  1304. (EC->PictureHeader.PicCodType == INTRAPIC))
  1305. )
  1306. EC->BRCState.u8StillQnt = 0;
  1307. // If the Encoder Bit Rate section of the configuration has been
  1308. // set ON then, we override quality only or any frame size normally
  1309. // sent in and use frame rate and data rate to determine frame
  1310. // size.
  1311. if (EC->PictureHeader.PicCodType == INTERPIC &&
  1312. lpCompInst->Configuration.bBitRateState == TRUE &&
  1313. lpCompInst->FrameRate != 0.0f &&
  1314. lpicComp->dwFrameSize == 0UL)
  1315. {
  1316. 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));
  1317. lpicComp->dwFrameSize = (U32)((float)lpCompInst->DataRate / lpCompInst->FrameRate);
  1318. }
  1319. // Use a different quantizer selection scheme if this is a
  1320. // progressive still transmission.
  1321. if (lpicComp->dwFlags & CODEC_CUSTOM_STILL)
  1322. {
  1323. bBitRateControl = OFF;
  1324. #ifdef USE_MMX // { USE_MMX
  1325. if (MMX_Enabled == TRUE)
  1326. EC->PictureHeader.PQUANT = StillImageQnt_MMX[ EC->BRCState.u8StillQnt ];
  1327. else
  1328. EC->PictureHeader.PQUANT = StillImageQnt[ EC->BRCState.u8StillQnt ];
  1329. #else // }{ USE_MMX
  1330. EC->PictureHeader.PQUANT = StillImageQnt[ EC->BRCState.u8StillQnt ];
  1331. #endif // } USE_MMX
  1332. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Setting still frames QP : %d\r\n", _fx_, EC->PictureHeader.PQUANT));
  1333. }
  1334. // If requested frame size is 0, then we simply set the quantizer
  1335. // according to the value in dwQuality.
  1336. else
  1337. if (lpicComp->dwFrameSize == 0)
  1338. {
  1339. bBitRateControl = OFF;
  1340. EC->PictureHeader.PQUANT = clampQP((10000 - lpicComp->dwQuality)*32/10000);
  1341. // In case a fixed quality setting is chosen (for example from VidEdit),
  1342. // we have to limit the lower QP value, in order not to blow the quite
  1343. // small bitstream buffer size. This size is set to be compliant with
  1344. // the H.263 spec. If the "chance of buffer overflow" code had not been
  1345. // added (search for "bGOBoverflowWarning", these limits would have had
  1346. // to be even higher.
  1347. if (EC->PictureHeader.PicCodType == INTERPIC)
  1348. {
  1349. if (EC->PictureHeader.PQUANT < 3)
  1350. EC->PictureHeader.PQUANT = 3;
  1351. }
  1352. else
  1353. {
  1354. if (EC->PictureHeader.PQUANT < 8)
  1355. EC->PictureHeader.PQUANT = 8;
  1356. }
  1357. DEBUGMSG(ZONE_BITRATE_CONTROL, ("\r\n%s: Bitrate controller disabled (no target frame size), setting EC->PictureHeader.PQUANT = %ld\r\n", _fx_, EC->PictureHeader.PQUANT));
  1358. // Limit the picture header QP to 2. Because of the calculation of u8QPMin
  1359. // below, this will effectively limit the QP at 2 for all macroblocks.
  1360. // The reason we need this is that the encoder generates an illegal
  1361. // bitstream when encoding a synthetic image for QP=1
  1362. if (EC->PictureHeader.PQUANT == 1)
  1363. EC->PictureHeader.PQUANT = 2;
  1364. // Calculate the lower level for GQuant in this picture
  1365. u8QPMin = EC->PictureHeader.PQUANT - EC->PictureHeader.PQUANT/3;
  1366. }
  1367. else
  1368. {
  1369. // Calculate PQUANT based on bits used in last picture
  1370. // Get Target Frame Rate that was passed from CompressFrames structure.
  1371. if (lpCompInst->FrameRate != 0)
  1372. EC->BRCState.TargetFrameRate = lpCompInst->FrameRate;
  1373. bBitRateControl = ON;
  1374. // If this is to be compressed as a PB frame, then we modify
  1375. // the target framesize for the P frame to be a percentage
  1376. // of twice the target frame size.
  1377. if ((EC->u8EncodePBFrame == TRUE) && (EC->PictureHeader.PicCodType == INTERPIC) && (EC->u8SavedBFrame == TRUE))
  1378. EC->BRCState.uTargetFrmSize = (80 * 2 * lpicComp->dwFrameSize)/100;
  1379. else
  1380. EC->BRCState.uTargetFrmSize = lpicComp->dwFrameSize;
  1381. DEBUGMSG(ZONE_BITRATE_CONTROL, ("\r\n%s: Bitrate controller enabled with\r\n", _fx_));
  1382. 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, (DWORD)lpicComp->dwQuality, (DWORD)lpicComp->dwFrameSize << 3, (DWORD)(EC->BRCState.TargetFrameRate * EC->BRCState.uTargetFrmSize) * 8UL));
  1383. DEBUGMSG(ZONE_BITRATE_CONTROL, (" Minimum quantizer = %ld\r\n Maximum quantizer = 31\r\n", clampQP((10000 - lpicComp->dwQuality)*15/10000)));
  1384. // Get the new quantizer value
  1385. EC->PictureHeader.PQUANT = CalcPQUANT( &(EC->BRCState), EC->PictureHeader.PicCodType);
  1386. // Calculate the min and max value for GQuant in this picture
  1387. u8QPMax = 31;
  1388. u8QPMin = clampQP((10000 - lpicComp->dwQuality)*15/10000);
  1389. }
  1390. gquant_prev = EC->PictureHeader.PQUANT;
  1391. QP_cumulative = 0;
  1392. // Check for AP, UMV or deblocking-filter modes. Each of these allows
  1393. // motion vectors to point outside of the reference picture.
  1394. // Need to verify this in final H.263+ spec for the deblocking filter.
  1395. if (EC->PictureHeader.AP == ON || EC->PictureHeader.UMV
  1396. #ifdef H263P
  1397. || EC->PictureHeader.DeblockingFilter == ON
  1398. #endif
  1399. )
  1400. {
  1401. ExpandPlane((U32)EC->pU8_PrevFrm_YPlane,
  1402. (U32)EC->FrameWidth,
  1403. (U32)EC->FrameHeight,
  1404. 16);
  1405. ExpandPlane((U32)EC->pU8_PrevFrm_UPlane,
  1406. (U32)EC->FrameWidth>>1,
  1407. (U32)EC->FrameHeight>>1,
  1408. 8);
  1409. ExpandPlane((U32)EC->pU8_PrevFrm_VPlane,
  1410. (U32)EC->FrameWidth>>1,
  1411. (U32)EC->FrameHeight>>1,
  1412. 8);
  1413. }
  1414. // If PB-frames are used and AP or UMV is not used at the same time, we can't search
  1415. // for a PB-delta vector (this is a limitation in the motion estimation routine,
  1416. // not the standard)
  1417. // If we allowed searching for B-frame vectors without AP, UMV or DF, we would need
  1418. // to worry about searching outside of the frame
  1419. if (EC->u8EncodePBFrame == TRUE && EC->PictureHeader.AP == OFF &&
  1420. EC->PictureHeader.UMV == OFF
  1421. #ifdef H263P
  1422. && EC->PictureHeader.DeblockingFilter == OFF
  1423. #endif
  1424. )
  1425. u32BFrmZeroThreshold = 999999; // do not search for other vectors than zero vector
  1426. else
  1427. #ifdef USE_MMX // { USE_MMX
  1428. u32BFrmZeroThreshold = (MMX_Enabled == FALSE ? 384 : 500);
  1429. #else // }{ USE_MMX
  1430. u32BFrmZeroThreshold = 384;
  1431. #endif // } USE_MMX
  1432. // Variables which will not change during the frame
  1433. // Gim 4/16/97 - added u32sizeBSnEBS
  1434. // u32sizeBitBuffer : max. allowable frame size w/o RTP stuff
  1435. // u32sizeBSnEBS : max. allowable size w/ RTP stuff (EBS & trailer)
  1436. #if defined(H263P)
  1437. u32sizeBSnEBS = CompressGetSize(lpCompInst, lpicComp->lpbiInput,
  1438. lpicComp->lpbiOutput);
  1439. #elif defined(USE_BILINEAR_MSH26X)
  1440. u32sizeBSnEBS = CompressGetSize(pi, lpicComp->lpbiInput,
  1441. lpicComp->lpbiOutput);
  1442. #else
  1443. u32sizeBSnEBS = CompressGetSize(lpCompInst, lpicComp->lpbiInput, 0);
  1444. #endif
  1445. if (pConfiguration->bRTPHeader)
  1446. u32sizeBitBuffer = u32sizeBSnEBS - getRTPBsInfoSize(lpCompInst);
  1447. else
  1448. u32sizeBitBuffer = u32sizeBSnEBS;
  1449. u32tempBuf = (3 * u32sizeBitBuffer / EC->NumMBRows) >> 2;
  1450. /*
  1451. * Check to see if we told VfW to create a buffer smaller
  1452. * than the maximum allowable.
  1453. */
  1454. ASSERT(u32sizeBitBuffer <= sizeof_bitstreambuf)
  1455. // Check to see if we are to encode a PB frame
  1456. bEncodePBFrame = (EC->u8EncodePBFrame && EC->u8SavedBFrame);
  1457. bPBFailed = FALSE;
  1458. #if defined(H263P)
  1459. EC->pFutrPMBData = ((T_H263EncoderInstanceMemory *)(lpCompInst->EncoderInst))->FutrPMBData;
  1460. EC->pWeightForwMotion = ((T_H263EncoderInstanceMemory *)(lpCompInst->EncoderInst))->WeightForwMotion; // values based on TRb and TRd
  1461. EC->pWeightBackMotion = ((T_H263EncoderInstanceMemory *)(lpCompInst->EncoderInst))->WeightBackMotion; // values based on TRb and TRd
  1462. #endif
  1463. if (bEncodePBFrame)
  1464. {
  1465. TRb = EC->PictureHeader.TRB;
  1466. TRd = (I32) EC->PictureHeader.TR - (I32) EC->PictureHeader.TRPrev;
  1467. if (TRd == 0) {
  1468. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Warning: TR == TRPrev. Setting TRd = 256\r\n", _fx_));
  1469. }
  1470. else if (TRd < 0) TRd += 256;
  1471. for (j = 0; j < 128; j ++)
  1472. {
  1473. #if defined(H263P)
  1474. EC->pWeightForwMotion[j] = (I8) ((TRb * (j-64)) / TRd);
  1475. EC->pWeightBackMotion[j] = (I8) (((TRb-TRd) * (j-64)) / TRd);
  1476. #else
  1477. WeightForwMotion[j] = (I8) ((TRb * (j-64)) / TRd);
  1478. WeightBackMotion[j] = (I8) (((TRb-TRd) * (j-64)) / TRd);
  1479. #endif
  1480. }
  1481. }
  1482. /***************************************************************
  1483. * Initialization before encoding all GOBs.
  1484. * Store frame header code into bitstream buffer.
  1485. ***************************************************************/
  1486. if (pConfiguration->bRTPHeader)
  1487. H263RTP_ResetBsInfoStream(EC);
  1488. // zero bit stream buffer
  1489. pCurBitStream = EC->pU8_BitStream;
  1490. u8bitoffset = 0;
  1491. GOBHeaderMask = 1;
  1492. EC->GOBHeaderPresent = 0; // Clear GOB Header Present flag.
  1493. encodeFrameHeader(EC, &pCurBitStream, &u8bitoffset, FALSE);
  1494. #ifdef USE_MMX // { USE_MMX
  1495. if (MMX_Enabled == FALSE)
  1496. {
  1497. for (GOB = 0; GOB < EC->NumMBRows; GOB ++, GOBHeaderMask <<= 1)
  1498. {
  1499. StartingMB = GOB * EC->NumMBPerRow;
  1500. gquant = FindNewQuant(EC,gquant_prev,uAdjCumFrmSize,GOB,u8QPMax,u8QPMin,
  1501. bBitRateControl,bGOBoverflowWarning);
  1502. // Save gquant for PB-frames
  1503. FutrFrmGQUANT[GOB] = gquant;
  1504. QP_cumulative += gquant;
  1505. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1506. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1507. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1508. MOTIONESTIMATION(
  1509. &(EC->pU8_MBlockActionStream[StartingMB]),
  1510. EC->pU8_CurrFrm_YPlane,
  1511. EC->pU8_PrevFrm_YPlane,
  1512. 0, // Not used for H.263.
  1513. 1, // Do Radius 15 search.
  1514. 1, // Half Pel Motion Estimation flag (0-off, 1-on)
  1515. #ifdef H263P
  1516. (EC->PictureHeader.AP == ON || EC->PictureHeader.DeblockingFilter) ? 1 : 0, // Block MVs flag
  1517. EC->pPseudoStackSpace,
  1518. #else
  1519. (EC->PictureHeader.AP == ON) ? 1 : 0, // Block MVs flag
  1520. #endif
  1521. 0, // No Spatial Filtering
  1522. 150,//384, // Zero Vector Threshold. If less than this threshold
  1523. // don't search for NZ MV's. Set to 99999 to not search.
  1524. 128, // NonZeroMVDifferential. Once the best NZ MV is found,
  1525. // it must be better than the 0 MV SWD by at least this
  1526. // amount. Set to 99999 to never choose NZ MV.
  1527. 512, // BlockMVDifferential. The sum of the four block SWD
  1528. // must be better than the MB SWD by at least this
  1529. // amount to choose block MV's.
  1530. 20,//96, // Empty Threshold. Set to 0 to not force empty blocks.
  1531. 550,///1152, // Inter Coding Threshold. If the inter SWD is less than
  1532. // this amount then don't bother calc. the intra SWD.
  1533. 500, // Intra Coding Differential. Bias against choosing INTRA
  1534. // blocks.
  1535. 0, // Spatial Filtering Threshold.
  1536. 0, // Spatial Filtering Differential.
  1537. &IntraSWDTotal,
  1538. &IntraSWDBlocks,
  1539. &InterSWDTotal,
  1540. &InterSWDBlocks
  1541. );
  1542. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1543. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uMotionEstimation)
  1544. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1545. // Sum up SWD
  1546. iSumSWD += IntraSWDTotal + InterSWDTotal;
  1547. /*
  1548. * If it's an inter frame then calculate chroma vectors.
  1549. * Also check the inter coded count for each macro block
  1550. * and force to intra if it exceeds 132.
  1551. */
  1552. if (EC->PictureHeader.PicCodType == INTERPIC)
  1553. {
  1554. calcGOBChromaVectors(EC, StartingMB, pConfiguration);
  1555. // for IA this is called after motion estimation
  1556. Check_InterCodeCnt(EC, StartingMB);
  1557. }
  1558. // Save the starting offset of the GOB as the start
  1559. // bit offset of the first MB.
  1560. if (bEncodePBFrame) {
  1561. #if defined(H263P)
  1562. EC->pFutrPMBData[StartingMB].MBStartBitOff =
  1563. (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  1564. #else
  1565. FutrPMBData[StartingMB].MBStartBitOff =
  1566. (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  1567. #endif
  1568. }
  1569. if (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev))
  1570. {
  1571. unsigned int GFID;
  1572. // Set a bit if header is present. (bit0=GOB0, bit1=GOB1, ...)
  1573. EC->GOBHeaderPresent |= GOBHeaderMask;
  1574. // Write GOB start code.
  1575. PutBits(FIELDVAL_GBSC, FIELDLEN_GBSC, &pCurBitStream, &u8bitoffset);
  1576. // Write GOB number.
  1577. PutBits(GOB, FIELDLEN_GN, &pCurBitStream, &u8bitoffset);
  1578. // Write GOB frame ID.
  1579. // According to section 5.2.5 of the H.263 specification:
  1580. // "GFID shall have the same value in every GOB header of a given
  1581. // picture. Moreover, if PTYPE as indicated in a picture header is
  1582. // the same as for the previous transmitted picture, GFID shall have
  1583. // the same value as in that previous picture. However, if PTYPE in
  1584. // a certain picture header differs from the PTYPE in the previous
  1585. // transmitted picture header, the value for GFID in that picture
  1586. // shall differ from the value in the previous picture."
  1587. // In our usage of H.263, we usually send either I of P frames with
  1588. // all options turned of, or always the same options turned on. This
  1589. // simplifies the fix in allowing us to compute a GFID based only on
  1590. // the picture type and the presence of at least on option.
  1591. GFID = (EC->PictureHeader.PB || EC->PictureHeader.AP || EC->PictureHeader.SAC || EC->PictureHeader.UMV) ? 2 : 0;
  1592. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1593. GFID++;
  1594. PutBits(GFID, FIELDLEN_GFID, &pCurBitStream, &u8bitoffset);
  1595. // Write GQUANT.
  1596. PutBits(gquant, FIELDLEN_GQUANT, &pCurBitStream, &u8bitoffset);
  1597. gquant_prev = gquant;
  1598. #ifdef COUNT_BITS
  1599. EC->Bits.GOBHeader += FIELDLEN_GBSC + FIELDLEN_GN + FIELDLEN_GFID + FIELDLEN_GQUANT;
  1600. #endif
  1601. }
  1602. /*
  1603. * Input is the macroblock action stream with pointers to
  1604. * current and previous blocks. Output is a set of 32 DWORDs
  1605. * containing pairs of coefficients for each block. There are
  1606. * from 0 to 12 blocks depending on if PB frames are used and
  1607. * what the CBP field states.
  1608. */
  1609. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1610. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1611. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1612. FORWARDDCT(&(EC->pU8_MBlockActionStream[StartingMB]),
  1613. EC->pU8_CurrFrm_YPlane,
  1614. EC->pU8_PrevFrm_YPlane,
  1615. 0,
  1616. EC->pU8_DCTCoefBuf,
  1617. 0, // 0 = not a B-frame
  1618. EC->PictureHeader.AP == ON, // Advanced prediction (OBMC)
  1619. bEncodePBFrame, // Is P of PB pair?
  1620. EC->pU8_PredictionScratchArea,
  1621. EC->NumMBPerRow
  1622. );
  1623. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1624. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFDCT)
  1625. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1626. /*
  1627. * Input is the string of coefficient pairs output from the
  1628. * DCT routine.
  1629. */
  1630. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1631. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1632. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1633. GOB_Q_RLE_VLC_WriteBS(
  1634. EC,
  1635. EC->pU8_DCTCoefBuf,
  1636. &pCurBitStream,
  1637. &u8bitoffset,
  1638. #if defined(H263P)
  1639. EC->pFutrPMBData,
  1640. #else
  1641. FutrPMBData,
  1642. #endif
  1643. GOB,
  1644. gquant,
  1645. pConfiguration->bRTPHeader,
  1646. StartingMB);
  1647. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1648. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uQRLE)
  1649. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1650. //Chad INTRA GOB
  1651. if (pConfiguration->bRTPHeader && IsIntraCoded(EC, GOB))
  1652. uUsedByIntra += pCurBitStream - EC->pU8_BitStream + 1 - uCumFrmSize;
  1653. // Accumulate number of bytes used in frame so far.
  1654. uCumFrmSize = pCurBitStream - EC->pU8_BitStream + 1;
  1655. // Here we will check to see if we have blown the buffer. If we have,
  1656. // then we will set the next frame up to be a key frame and return an
  1657. // ICERR_ERROR. We hope that with an INTRA quantizer of 16, we will not
  1658. // overflow the buffer for the next frame.
  1659. if (uCumFrmSize > u32sizeBitBuffer)
  1660. {
  1661. ERRORMESSAGE(("%s: Buffer overflow, uCumFrmSize %d > %d\r\n", _fx_, uCumFrmSize, u32sizeBitBuffer));
  1662. // Now clear the buffer for the next frame and set up for a key frame
  1663. memset(EC->pU8_BitStream, 0, uCumFrmSize);
  1664. EC->bMakeNextFrameKey = TRUE; // Could be a problem in still mode if
  1665. ret = ICERR_ERROR; // we blow the buffer on the first key frame: RH
  1666. goto done;
  1667. }
  1668. else
  1669. {
  1670. if ((bEncodePBFrame?3*uCumFrmSize>>1:uCumFrmSize) > ((GOB + 1) * u32tempBuf))
  1671. {
  1672. // set the next GOB quantizer to be higher to minimize overflowing the
  1673. // buffer at the end of GOB processing.
  1674. bGOBoverflowWarning = TRUE;
  1675. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Anticipating overflow: uCumFrmSize = %ld bits > (GOB + 1) * u32tempBuf = (#%ld + 1) * %ld\r\n", _fx_, uCumFrmSize << 3, GOB, u32tempBuf << 3));
  1676. }
  1677. else
  1678. bGOBoverflowWarning = FALSE;
  1679. }
  1680. // Gim 4/16/97 - moved this adjustment from before to after the
  1681. // buffer check above
  1682. // if the current GOB is intra coded, adjust the cumulated sum
  1683. if (pConfiguration->bRTPHeader)
  1684. {
  1685. if (!GOB)
  1686. uAdjCumFrmSize = uCumFrmSize - uUsedByIntra / 4;
  1687. else
  1688. uAdjCumFrmSize = uCumFrmSize - uUsedByIntra;
  1689. }
  1690. else
  1691. uAdjCumFrmSize = uCumFrmSize;
  1692. } // for GOB
  1693. //Chad INTRA GOB restore after use
  1694. uUsedByIntra = 0;
  1695. // Store the number of bits spent so far
  1696. EC->uBitUsageProfile[GOB] = uAdjCumFrmSize;
  1697. }
  1698. else // MMX_Enabled == TRUE
  1699. {
  1700. MMxMESignaturePrep(EC->pU8_PrevFrm_YPlane,
  1701. EC->pU8_Signature_YPlane,
  1702. EC->FrameWidth,
  1703. EC->FrameHeight);
  1704. for (GOB = 0; GOB < EC->NumMBRows; GOB ++, GOBHeaderMask <<= 1)
  1705. {
  1706. StartingMB = GOB * EC->NumMBPerRow;
  1707. // Check inter code count for all macroblocks on this row
  1708. // Need special version for MMX since it is called before motion estiamtion
  1709. // When the intra coding flag is set, Brian still does motion estimation
  1710. // for this MB in MMXEDTQ if the PB coding flag is set
  1711. Check_InterCodeCnt_MMX(EC, StartingMB);
  1712. gquant = FindNewQuant(EC,gquant_prev,uCumFrmSize,GOB,u8QPMax,u8QPMin,
  1713. bBitRateControl,bGOBoverflowWarning);
  1714. // Save gquant for PB-frames
  1715. FutrFrmGQUANT[GOB] = gquant;
  1716. QP_cumulative += gquant;
  1717. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1718. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1719. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1720. // This does the pass over the Luma blocks...
  1721. __try
  1722. {
  1723. MMxEDTQ (
  1724. &(EC->pU8_MBlockActionStream[StartingMB]),
  1725. EC->pU8_CurrFrm_YPlane,
  1726. EC->pU8_PrevFrm_YPlane,
  1727. EC->pU8_BFrm_YPlane,
  1728. EC->pU8_Signature_YPlane,
  1729. #if defined(H263P)
  1730. EC->pWeightForwMotion,
  1731. EC->pWeightBackMotion,
  1732. #else
  1733. WeightForwMotion,
  1734. WeightBackMotion,
  1735. #endif
  1736. EC->FrameWidth,
  1737. 1, // Half Pel Motion Estimation flag (0-off, 1-on)
  1738. #ifdef H263P
  1739. // H.263+, deblocking filter automatically turns on
  1740. // block level MVs, but not OBMC
  1741. (EC->PictureHeader.AP == ON) || (EC->PictureHeader.DeblockingFilter == ON), // Block MVs flag
  1742. EC->pPseudoStackSpace,
  1743. #else
  1744. EC->PictureHeader.AP == ON, // Block MVs flag
  1745. #endif
  1746. 0, // No Spatial Filtering
  1747. EC->PictureHeader.AP == ON, // Advanced Prediction (OBMC) and MVs outside of picture flag
  1748. bEncodePBFrame, // Is PB pair?
  1749. #ifdef H263P
  1750. EC->PictureHeader.DeblockingFilter == ON, // Use deblocking filter (8x8 and unrestricted MV's)
  1751. EC->PictureHeader.ImprovedPB == ON, // Use improved PB-frame method
  1752. #endif
  1753. 1, // Do Luma blocks this Pass
  1754. EC->PictureHeader.UMV, // MVs outside of picture and within [-31.5, 31.5]
  1755. #ifdef H263P
  1756. (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev)),
  1757. // GOB header present. Used to generate MV predictor and search range in UMV
  1758. #endif
  1759. gquant,
  1760. min((6*gquant)>>2, 31), // TODO: to match DBQUANT in picture header
  1761. u32BFrmZeroThreshold, // BFrmZeroVectorThreshold
  1762. 0, // SpatialFiltThreshold
  1763. 0, // SpatialFiltDifferential
  1764. &iSWD,
  1765. &iBSWD,
  1766. EC->pI8_MBRVS_Luma,
  1767. EC->pI8_MBRVS_BLuma+GOB*(65*3*22*4)
  1768. );
  1769. }
  1770. __except(ExceptionFilterForMMxEDTQ(GetExceptionInformation(),EC->pI8_MBRVS_BLuma,1))
  1771. {
  1772. // no exception handler
  1773. }
  1774. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1775. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uMotionEstimation)
  1776. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1777. // Sum up SWDs
  1778. iSumSWD += iSWD;
  1779. iSumBSWD += iBSWD;
  1780. /*
  1781. * If it's an inter frame then calculate chroma vectors.
  1782. * Also check the inter coded count for each macro block
  1783. * and force to intra if it exceeds 132.
  1784. */
  1785. if (EC->PictureHeader.PicCodType == INTERPIC)
  1786. {
  1787. calcGOBChromaVectors(EC, StartingMB, pConfiguration);
  1788. if (bEncodePBFrame)
  1789. // Calculate chroma vectors.
  1790. calcBGOBChromaVectors(EC, StartingMB);
  1791. }
  1792. // Save the starting offset of the GOB as the start
  1793. // bit offset of the first MB.
  1794. if (bEncodePBFrame) {
  1795. #if defined(H263P)
  1796. EC->pFutrPMBData[StartingMB].MBStartBitOff =
  1797. (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  1798. #else
  1799. FutrPMBData[StartingMB].MBStartBitOff =
  1800. (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  1801. #endif
  1802. }
  1803. if (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev))
  1804. {
  1805. unsigned int GFID;
  1806. // Set a bit if header is present. (bit0=GOB0, bit1=GOB1, ...)
  1807. EC->GOBHeaderPresent |= GOBHeaderMask;
  1808. // Write GOB start code.
  1809. PutBits(FIELDVAL_GBSC, FIELDLEN_GBSC, &pCurBitStream, &u8bitoffset);
  1810. // Write GOB number.
  1811. PutBits(GOB, FIELDLEN_GN, &pCurBitStream, &u8bitoffset);
  1812. // Write GOB frame ID.
  1813. // According to section 5.2.5 of the H.263 specification:
  1814. // "GFID shall have the same value in every GOB header of a given
  1815. // picture. Moreover, if PTYPE as indicated in a picture header is
  1816. // the same as for the previous transmitted picture, GFID shall have
  1817. // the same value as in that previous picture. However, if PTYPE in
  1818. // a certain picture header differs from the PTYPE in the previous
  1819. // transmitted picture header, the value for GFID in that picture
  1820. // shall differ from the value in the previous picture."
  1821. // In our usage of H.263, we usually send either I of P frames with
  1822. // all options turned of, or always the same options turned on. This
  1823. // simplifies the fix in allowing us to compute a GFID based only on
  1824. // the picture type and the presence of at least on option.
  1825. GFID = (EC->PictureHeader.PB || EC->PictureHeader.AP || EC->PictureHeader.SAC || EC->PictureHeader.UMV) ? 2 : 0;
  1826. if (EC->PictureHeader.PicCodType == INTRAPIC)
  1827. GFID++;
  1828. PutBits(GFID, FIELDLEN_GFID, &pCurBitStream, &u8bitoffset);
  1829. // Write GQUANT.
  1830. PutBits(gquant, FIELDLEN_GQUANT, &pCurBitStream, &u8bitoffset);
  1831. gquant_prev = gquant;
  1832. #ifdef COUNT_BITS
  1833. EC->Bits.GOBHeader += FIELDLEN_GBSC + FIELDLEN_GN + FIELDLEN_GFID + FIELDLEN_GQUANT;
  1834. #endif
  1835. }
  1836. /*
  1837. * Input is the macroblock action stream with pointers to
  1838. * current and previous blocks. Output is a set of 32 DWORDs
  1839. * containing pairs of coefficients for each block. There are
  1840. * from 0 to 12 blocks depending on if PB frames are used and
  1841. * what the CBP field states.
  1842. */
  1843. // This does the pass over the Chroma blocks....
  1844. //
  1845. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1846. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1847. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1848. __try
  1849. {
  1850. MMxEDTQ (
  1851. &(EC->pU8_MBlockActionStream[StartingMB]),
  1852. EC->pU8_CurrFrm_YPlane,
  1853. EC->pU8_PrevFrm_YPlane,
  1854. EC->pU8_BFrm_YPlane,
  1855. EC->pU8_Signature_YPlane,
  1856. #if defined(H263P)
  1857. EC->pWeightForwMotion,
  1858. EC->pWeightBackMotion,
  1859. #else
  1860. WeightForwMotion,
  1861. WeightBackMotion,
  1862. #endif
  1863. EC->FrameWidth,
  1864. 1, // Half Pel Motion Estimation flag (0-off, 1-on)
  1865. #ifdef H263P
  1866. // H.263+, deblocking filter automatically turns on
  1867. // block level MVs, but not OBMC
  1868. (EC->PictureHeader.AP == ON) || (EC->PictureHeader.DeblockingFilter == ON), // Block MVs flag
  1869. EC->pPseudoStackSpace,
  1870. #else
  1871. EC->PictureHeader.AP == ON, // Block MVs flag
  1872. #endif
  1873. 0, // No Spatial Filtering
  1874. EC->PictureHeader.AP == ON, // Advanced Prediction (OBMC)
  1875. bEncodePBFrame, // Is PB pair?
  1876. #ifdef H263P
  1877. EC->PictureHeader.DeblockingFilter == ON, // Use deblocking filter (8x8 and unrestricted MV's)
  1878. EC->PictureHeader.ImprovedPB == ON, // Use improved PB-frame method
  1879. 0, // If not H.263+, must be 0
  1880. 0, // If not H.263+, must be 0
  1881. #endif
  1882. 0, // Do Chroma blocks this Pass
  1883. 0, // 1 for extended motion vectors
  1884. #ifdef H263P
  1885. 0, // GOB header present. Used in UMV to generate MV predictor.
  1886. #endif
  1887. gquant,
  1888. min((6*gquant) >> 2, 31),
  1889. 500, // BFrmZeroVectorThreshold
  1890. 0, // SpatialFiltThreshold
  1891. 0, // SpatialFiltDifferential
  1892. &iSWD,
  1893. &iBSWD,
  1894. EC->pI8_MBRVS_Chroma,
  1895. EC->pI8_MBRVS_BChroma+GOB*(65*3*22*2)
  1896. );
  1897. }
  1898. __except(ExceptionFilterForMMxEDTQ(GetExceptionInformation(),EC->pI8_MBRVS_BChroma,0))
  1899. {
  1900. // no exception handler
  1901. }
  1902. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1903. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFDCT)
  1904. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1905. /*
  1906. * Input is the string of coefficient pairs output from the
  1907. * DCT routine.
  1908. */
  1909. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1910. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1911. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1912. GOB_VLC_WriteBS(
  1913. EC,
  1914. EC->pI8_MBRVS_Luma,
  1915. EC->pI8_MBRVS_Chroma,
  1916. &pCurBitStream,
  1917. &u8bitoffset,
  1918. #if defined(H263P)
  1919. EC->pFutrPMBData,
  1920. #else
  1921. FutrPMBData,
  1922. #endif
  1923. GOB,
  1924. gquant,
  1925. pConfiguration->bRTPHeader,
  1926. StartingMB);
  1927. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1928. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uQRLE)
  1929. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1930. // Accumulate number of bytes used in frame so far.
  1931. uCumFrmSize = pCurBitStream - EC->pU8_BitStream + 1;
  1932. // Here we will check to see if we have blown the buffer. If we have,
  1933. // then we will set the next frame up to be a key frame and return an
  1934. // ICERR_ERROR. We hope that with an INTRA quantizer of 16, we will not
  1935. // overflow the buffer for the next frame.
  1936. if (uCumFrmSize > u32sizeBitBuffer)
  1937. {
  1938. ERRORMESSAGE(("%s: Buffer overflow, uCumFrmSize %d > %d\r\n", _fx_, uCumFrmSize, u32sizeBitBuffer));
  1939. memset(EC->pU8_BitStream, 0, uCumFrmSize);
  1940. EC->bMakeNextFrameKey = TRUE; // Could be a problem in still mode if
  1941. ret = ICERR_ERROR; // we blow the buffer on the first key frame: RH
  1942. goto done;
  1943. }
  1944. else
  1945. {
  1946. if ((bEncodePBFrame?3*uCumFrmSize>>1:uCumFrmSize) > ((GOB + 1) * u32tempBuf))
  1947. // set the next GOB quantizer to be higher to minimize overflowing the
  1948. // buffer at the end of GOB processing.
  1949. bGOBoverflowWarning = TRUE;
  1950. else
  1951. bGOBoverflowWarning = FALSE;
  1952. }
  1953. } // for GOB
  1954. // Store the number of bits spent so far
  1955. EC->uBitUsageProfile[GOB] = uCumFrmSize;
  1956. // This is the new MMX PB-frames switch
  1957. // Simple check to see if B-frame will look bad
  1958. // This could be possibly be improved by looking at the
  1959. // actual number of coefficients, or the number of bits
  1960. // in the bitstream.
  1961. #ifdef H263P
  1962. // Always use the B frame if improved PB-frame mode and AP or UMV mode requested
  1963. if (TogglePB == TRUE && iSumBSWD >= iSumSWD &&
  1964. !(EC->PictureHeader.ImprovedPB == ON &&
  1965. (EC->PictureHeader.AP == ON || EC->PictureHeader.UMV == ON ||
  1966. EC->PictureHeader.DeblockingFilter == ON)))
  1967. #else
  1968. if (TogglePB == TRUE && iSumBSWD >= iSumSWD)
  1969. #endif
  1970. {
  1971. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Giving up PB, SumBSWD = %d, SumSWD = %d\r\n", _fx_, iSumBSWD, iSumSWD));
  1972. bEncodePBFrame = FALSE;
  1973. EC->u8SavedBFrame = FALSE;
  1974. }
  1975. }
  1976. #else // }{ USE_MMX
  1977. for (GOB = 0; GOB < EC->NumMBRows; GOB ++, GOBHeaderMask <<= 1)
  1978. {
  1979. StartingMB = GOB * EC->NumMBPerRow;
  1980. gquant = FindNewQuant(EC,gquant_prev,uAdjCumFrmSize,GOB,u8QPMax,u8QPMin,
  1981. bBitRateControl,bGOBoverflowWarning);
  1982. // Save gquant for PB-frames
  1983. FutrFrmGQUANT[GOB] = gquant;
  1984. QP_cumulative += gquant;
  1985. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  1986. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  1987. #endif // } DETAILED_ENCODE_TIMINGS_ON
  1988. MOTIONESTIMATION(
  1989. &(EC->pU8_MBlockActionStream[StartingMB]),
  1990. EC->pU8_CurrFrm_YPlane,
  1991. EC->pU8_PrevFrm_YPlane,
  1992. 0, // Not used for H.263.
  1993. 1, // Do Radius 15 search.
  1994. 1, // Half Pel Motion Estimation flag (0-off, 1-on)
  1995. #ifdef H263P
  1996. (EC->PictureHeader.AP == ON || EC->PictureHeader.DeblockingFilter) ? 1 : 0, // Block MVs flag
  1997. EC->pPseudoStackSpace,
  1998. #else
  1999. (EC->PictureHeader.AP == ON) ? 1 : 0, // Block MVs flag
  2000. #endif
  2001. 0, // No Spatial Filtering
  2002. 150,//384, // Zero Vector Threshold. If less than this threshold
  2003. // don't search for NZ MV's. Set to 99999 to not search.
  2004. 128, // NonZeroMVDifferential. Once the best NZ MV is found,
  2005. // it must be better than the 0 MV SWD by at least this
  2006. // amount. Set to 99999 to never choose NZ MV.
  2007. 512, // BlockMVDifferential. The sum of the four block SWD
  2008. // must be better than the MB SWD by at least this
  2009. // amount to choose block MV's.
  2010. 20,//96, // Empty Threshold. Set to 0 to not force empty blocks.
  2011. 550,///1152, // Inter Coding Threshold. If the inter SWD is less than
  2012. // this amount then don't bother calc. the intra SWD.
  2013. 500, // Intra Coding Differential. Bias against choosing INTRA
  2014. // blocks.
  2015. 0, // Spatial Filtering Threshold.
  2016. 0, // Spatial Filtering Differential.
  2017. &IntraSWDTotal,
  2018. &IntraSWDBlocks,
  2019. &InterSWDTotal,
  2020. &InterSWDBlocks
  2021. );
  2022. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2023. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uMotionEstimation)
  2024. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2025. // Sum up SWD
  2026. iSumSWD += IntraSWDTotal + InterSWDTotal;
  2027. /*
  2028. * If it's an inter frame then calculate chroma vectors.
  2029. * Also check the inter coded count for each macro block
  2030. * and force to intra if it exceeds 132.
  2031. */
  2032. if (EC->PictureHeader.PicCodType == INTERPIC)
  2033. {
  2034. calcGOBChromaVectors(EC, StartingMB, pConfiguration);
  2035. // for IA this is called after motion estimation
  2036. Check_InterCodeCnt(EC, StartingMB);
  2037. }
  2038. // Save the starting offset of the GOB as the start
  2039. // bit offset of the first MB.
  2040. if (bEncodePBFrame) {
  2041. #if defined(H263P)
  2042. EC->pFutrPMBData[StartingMB].MBStartBitOff =
  2043. (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  2044. #else
  2045. FutrPMBData[StartingMB].MBStartBitOff =
  2046. (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  2047. #endif
  2048. }
  2049. if (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev))
  2050. {
  2051. unsigned int GFID;
  2052. // Set a bit if header is present. (bit0=GOB0, bit1=GOB1, ...)
  2053. EC->GOBHeaderPresent |= GOBHeaderMask;
  2054. // Write GOB start code.
  2055. PutBits(FIELDVAL_GBSC, FIELDLEN_GBSC, &pCurBitStream, &u8bitoffset);
  2056. // Write GOB number.
  2057. PutBits(GOB, FIELDLEN_GN, &pCurBitStream, &u8bitoffset);
  2058. // Write GOB frame ID.
  2059. // According to section 5.2.5 of the H.263 specification:
  2060. // "GFID shall have the same value in every GOB header of a given
  2061. // picture. Moreover, if PTYPE as indicated in a picture header is
  2062. // the same as for the previous transmitted picture, GFID shall have
  2063. // the same value as in that previous picture. However, if PTYPE in
  2064. // a certain picture header differs from the PTYPE in the previous
  2065. // transmitted picture header, the value for GFID in that picture
  2066. // shall differ from the value in the previous picture."
  2067. // In our usage of H.263, we usually send either I of P frames with
  2068. // all options turned of, or always the same options turned on. This
  2069. // simplifies the fix in allowing us to compute a GFID based only on
  2070. // the picture type and the presence of at least on option.
  2071. GFID = (EC->PictureHeader.PB || EC->PictureHeader.AP || EC->PictureHeader.SAC || EC->PictureHeader.UMV) ? 2 : 0;
  2072. if (EC->PictureHeader.PicCodType == INTRAPIC)
  2073. GFID++;
  2074. PutBits(GFID, FIELDLEN_GFID, &pCurBitStream, &u8bitoffset);
  2075. // Write GQUANT.
  2076. PutBits(gquant, FIELDLEN_GQUANT, &pCurBitStream, &u8bitoffset);
  2077. gquant_prev = gquant;
  2078. #ifdef COUNT_BITS
  2079. EC->Bits.GOBHeader += FIELDLEN_GBSC + FIELDLEN_GN + FIELDLEN_GFID + FIELDLEN_GQUANT;
  2080. #endif
  2081. }
  2082. /*
  2083. * Input is the macroblock action stream with pointers to
  2084. * current and previous blocks. Output is a set of 32 DWORDs
  2085. * containing pairs of coefficients for each block. There are
  2086. * from 0 to 12 blocks depending on if PB frames are used and
  2087. * what the CBP field states.
  2088. */
  2089. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2090. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  2091. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2092. FORWARDDCT(&(EC->pU8_MBlockActionStream[StartingMB]),
  2093. EC->pU8_CurrFrm_YPlane,
  2094. EC->pU8_PrevFrm_YPlane,
  2095. 0,
  2096. EC->pU8_DCTCoefBuf,
  2097. 0, // 0 = not a B-frame
  2098. EC->PictureHeader.AP == ON, // Advanced prediction (OBMC)
  2099. bEncodePBFrame, // Is P of PB pair?
  2100. EC->pU8_PredictionScratchArea,
  2101. EC->NumMBPerRow
  2102. );
  2103. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2104. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uFDCT)
  2105. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2106. /*
  2107. * Input is the string of coefficient pairs output from the
  2108. * DCT routine.
  2109. */
  2110. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2111. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  2112. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2113. GOB_Q_RLE_VLC_WriteBS(
  2114. EC,
  2115. EC->pU8_DCTCoefBuf,
  2116. &pCurBitStream,
  2117. &u8bitoffset,
  2118. #if defined(H263P)
  2119. EC->pFutrPMBData,
  2120. #else
  2121. FutrPMBData,
  2122. #endif
  2123. GOB,
  2124. gquant,
  2125. pConfiguration->bRTPHeader,
  2126. StartingMB);
  2127. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2128. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uQRLE)
  2129. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2130. //Chad INTRA GOB
  2131. if (pConfiguration->bRTPHeader && IsIntraCoded(EC, GOB))
  2132. uUsedByIntra += pCurBitStream - EC->pU8_BitStream + 1 - uCumFrmSize;
  2133. // Accumulate number of bytes used in frame so far.
  2134. uCumFrmSize = pCurBitStream - EC->pU8_BitStream + 1;
  2135. // Here we will check to see if we have blown the buffer. If we have,
  2136. // then we will set the next frame up to be a key frame and return an
  2137. // ICERR_ERROR. We hope that with an INTRA quantizer of 16, we will not
  2138. // overflow the buffer for the next frame.
  2139. if (uCumFrmSize > u32sizeBitBuffer)
  2140. {
  2141. ERRORMESSAGE(("%s: Buffer overflow, uCumFrmSize %d > %d\r\n", _fx_, uCumFrmSize, u32sizeBitBuffer));
  2142. // Now clear the buffer for the next frame and set up for a key frame
  2143. memset(EC->pU8_BitStream, 0, uCumFrmSize);
  2144. EC->bMakeNextFrameKey = TRUE; // Could be a problem in still mode if
  2145. ret = ICERR_ERROR; // we blow the buffer on the first key frame: RH
  2146. goto done;
  2147. }
  2148. else
  2149. {
  2150. if ((bEncodePBFrame?3*uCumFrmSize>>1:uCumFrmSize) > ((GOB + 1) * u32tempBuf))
  2151. // set the next GOB quantizer to be higher to minimize overflowing the
  2152. // buffer at the end of GOB processing.
  2153. bGOBoverflowWarning = TRUE;
  2154. else
  2155. bGOBoverflowWarning = FALSE;
  2156. }
  2157. // Gim 4/16/97 - moved this adjustment from before to after the
  2158. // buffer check above
  2159. // if the current GOB is intra coded, adjust the cumulated sum
  2160. if (pConfiguration->bRTPHeader)
  2161. {
  2162. if (!GOB)
  2163. uAdjCumFrmSize = uCumFrmSize - uUsedByIntra / 4;
  2164. else
  2165. uAdjCumFrmSize = uCumFrmSize - uUsedByIntra;
  2166. }
  2167. else
  2168. uAdjCumFrmSize = uCumFrmSize;
  2169. } // for GOB
  2170. //Chad INTRA GOB restore after use
  2171. uUsedByIntra = 0;
  2172. // Store the number of bits spent so far
  2173. EC->uBitUsageProfile[GOB] = uAdjCumFrmSize;
  2174. #endif // } USE_MMX
  2175. #ifdef COUNT_BITS
  2176. WriteCountBitFile( &(EC->Bits) );
  2177. #endif
  2178. // ------------------------------------------------------------------------
  2179. // Write the MBStartBitOff in the sentinel macroblock
  2180. // ------------------------------------------------------------------------
  2181. if (bEncodePBFrame)
  2182. { // Encoding future P frame
  2183. #if defined(H263P)
  2184. EC->pFutrPMBData[EC->NumMBs].MBStartBitOff
  2185. = (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  2186. #else
  2187. FutrPMBData[EC->NumMBs].MBStartBitOff
  2188. = (U32) (((pCurBitStream - EC->pU8_BitStream) << 3) + u8bitoffset);
  2189. #endif
  2190. #ifdef DEBUG
  2191. for (i = 0; i < EC->NumMBs; i++)
  2192. {
  2193. #if defined(H263P)
  2194. ASSERT(EC->pFutrPMBData[i].MBStartBitOff < EC->pFutrPMBData[i + 1].MBStartBitOff)
  2195. ASSERT(EC->pFutrPMBData[i].CBPYBitOff <= EC->pFutrPMBData[i].MVDBitOff)
  2196. ASSERT(EC->pFutrPMBData[i].MVDBitOff <= EC->pFutrPMBData[i].BlkDataBitOff)
  2197. ASSERT(EC->pFutrPMBData[i].BlkDataBitOff <= (EC->pFutrPMBData[i + 1].MBStartBitOff - EC->pFutrPMBData[i].MBStartBitOff))
  2198. #else
  2199. ASSERT(FutrPMBData[i].MBStartBitOff < FutrPMBData[i + 1].MBStartBitOff)
  2200. ASSERT(FutrPMBData[i].CBPYBitOff <= FutrPMBData[i].MVDBitOff)
  2201. ASSERT(FutrPMBData[i].MVDBitOff <= FutrPMBData[i].BlkDataBitOff)
  2202. ASSERT(FutrPMBData[i].BlkDataBitOff <= (FutrPMBData[i + 1].MBStartBitOff - FutrPMBData[i].MBStartBitOff))
  2203. #endif
  2204. }
  2205. #endif
  2206. }
  2207. // ------------------------------------------------------------------------
  2208. // Copy the compressed image to the output area.
  2209. // ------------------------------------------------------------------------
  2210. SizeBitStream = pCurBitStream - EC->pU8_BitStream + 1;
  2211. /* make sure we don't write 8 empty bits */
  2212. if (!u8bitoffset) SizeBitStream --;
  2213. // Gim 4/21/97 - added check for overall buffer overflow before attaching
  2214. // RTP info and trailer to the end of a P or I frame bitstream
  2215. if (pConfiguration->bRTPHeader)
  2216. {
  2217. SizeBSnEBS = SizeBitStream + H263RTP_GetMaxBsInfoStreamSize(EC);
  2218. if (SizeBSnEBS > u32sizeBSnEBS)
  2219. {
  2220. ERRORMESSAGE(("%s: BS+EBS buffer overflow, SizeBSnEBS %d > %d\r\n", _fx_, SizeBSnEBS, u32sizeBSnEBS));
  2221. memset(EC->pU8_BitStream, 0, SizeBitStream);
  2222. EC->bMakeNextFrameKey = TRUE;
  2223. ret = ICERR_ERROR;
  2224. goto done;
  2225. }
  2226. }
  2227. #ifdef ENCODE_STATS
  2228. uBitStreamBytes = SizeBitStream;
  2229. #endif
  2230. memcpy(lpicComp->lpOutput, EC->pU8_BitStream, SizeBitStream);
  2231. memset(EC->pU8_BitStream, 0, SizeBitStream);
  2232. if (pConfiguration->bRTPHeader)
  2233. SizeBitStream += (WORD) H263RTP_AttachBsInfoStream(EC,
  2234. (U8 *) lpicComp->lpOutput, SizeBitStream);
  2235. lpCompInst->CompressedSize = SizeBitStream;
  2236. // ------------------------------------------------------------------------
  2237. // Run the decoder on this frame, to get next basis for prediction.
  2238. // ------------------------------------------------------------------------
  2239. ICDecExSt = DefaultICDecExSt;
  2240. ICDecExSt.lpSrc = lpicComp->lpOutput;
  2241. ICDecExSt.lpbiSrc = lpicComp->lpbiOutput;
  2242. ICDecExSt.lpbiSrc->biSizeImage = SizeBitStream;
  2243. // Decode it in future frame if doing PB-frame
  2244. ICDecExSt.lpDst = bEncodePBFrame ? EC->pU8_FutrFrm : EC->pU8_PrevFrm;
  2245. ICDecExSt.lpbiDst = NULL;
  2246. if (EC->PictureHeader.PicCodType == INTERPIC)
  2247. ICDecExSt.dwFlags = ICDECOMPRESS_NOTKEYFRAME;
  2248. // Call the decompressor
  2249. // Call the decompressor
  2250. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2251. TIMER_BEFORE(bTimingThisFrame,uStartLow,uStartHigh,uBefore);
  2252. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2253. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2254. ret = H263Decompress (EC->pDecInstanceInfo, (ICDECOMPRESSEX FAR *)&ICDecExSt, FALSE, FALSE);
  2255. #else // }{ #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2256. ret = H263Decompress (EC->pDecInstanceInfo, (ICDECOMPRESSEX FAR *)&ICDecExSt, FALSE);
  2257. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2258. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2259. TIMER_AFTER_P5(bTimingThisFrame,uStartLow,uStartHigh,uBefore,uElapsed,uDecodeFrame)
  2260. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2261. if (ret != ICERR_OK)
  2262. {
  2263. // Check to see if an error occurred in the decoder. If it did
  2264. // we don't have a valid "previous frame" hence force the next
  2265. // frame to be a key frame.
  2266. ERRORMESSAGE(("%s: Decoder failed in encoder\r\n", _fx_));
  2267. EC->bMakeNextFrameKey = TRUE;
  2268. ret = ICERR_ERROR;
  2269. goto done;
  2270. }
  2271. // ------------------------------------------------------------------------
  2272. // Start processing the saved B frame.
  2273. // ------------------------------------------------------------------------
  2274. if (bEncodePBFrame)
  2275. {
  2276. #ifdef COUNT_BITS
  2277. InitBits(EC);
  2278. #endif
  2279. // zero PB-frame bit stream buffer.
  2280. pPB_BitStream = EC->pU8_BitStrCopy;
  2281. pP_BitStreamStart = (U8 *) lpicComp->lpOutput;
  2282. u8PB_BitOffset = 0;
  2283. // Encode the frame header
  2284. EC->PictureHeader.PB = ON;
  2285. // Clear GOB Header Present flag.
  2286. EC->GOBHeaderPresent = 0;
  2287. GOBHeaderMask = 1;
  2288. gquant_prev = EC->PictureHeader.PQUANT;
  2289. if (pConfiguration->bRTPHeader)
  2290. H263RTP_ResetBsInfoStream(EC);
  2291. encodeFrameHeader(EC, &pPB_BitStream, &u8PB_BitOffset, TRUE);
  2292. #ifdef USE_MMX // { USE_MMX
  2293. if (MMX_Enabled == FALSE)
  2294. {
  2295. /*****************************************
  2296. * . copy edge pels in the previous frame
  2297. * . initialize arrays used in motion estimation
  2298. * . foreach(GOB)
  2299. * . BFRAMEMOTIONESTIMATION
  2300. * . Compute Chroma motion vectors
  2301. * . Write GOB header
  2302. * . FORWARDDCT
  2303. * . PB_GOB_Q_RLE_VLC_WriteBS
  2304. *****************************************/
  2305. for (GOB = 0; GOB < EC->NumMBRows; GOB ++, GOBHeaderMask <<= 1)
  2306. {
  2307. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: BFRAME GOB #%d\r\n", _fx_, GOB));
  2308. gquant = FutrFrmGQUANT[GOB];
  2309. if (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev))
  2310. {
  2311. // Set a bit if header is present. (bit0=GOB0, bit1=GOB1, ...)
  2312. EC->GOBHeaderPresent |= GOBHeaderMask;
  2313. gquant_prev = gquant;
  2314. }
  2315. StartingMB = GOB * EC->NumMBPerRow;
  2316. BFRAMEMOTIONESTIMATION(
  2317. &(EC->pU8_MBlockActionStream[StartingMB]),
  2318. EC->pU8_BFrm_YPlane,
  2319. EC->pU8_PrevFrm_YPlane,
  2320. EC->pU8_FutrFrm_YPlane,
  2321. #if defined(H263P)
  2322. EC->pWeightForwMotion+32,
  2323. EC->pWeightBackMotion+32,
  2324. #else
  2325. WeightForwMotion+32,
  2326. WeightBackMotion+32,
  2327. #endif
  2328. u32BFrmZeroThreshold, // Zero Vector Threshold. If less than this threshold don't search for
  2329. #if defined(H263P)
  2330. EC->pPseudoStackSpace,
  2331. #endif
  2332. // NZ MV's. Set to 99999 to not search.
  2333. 128, // NonZeroMVDifferential. Once the best NZ MV is found, it must be better
  2334. // than the 0 MV SWD by at least this amount.
  2335. // Set to 99999 to never choose NZ MV.
  2336. 96, // Empty Threshold. Set to 0 to not force empty blocks.
  2337. &InterSWDTotal,
  2338. &InterSWDBlocks
  2339. );
  2340. iSumBSWD += InterSWDTotal;
  2341. if (TogglePB && iSumBSWD >= (3 * iSumSWD) >> 1)
  2342. {
  2343. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Giving up PB, SumBSWD = %d, SumSWD = %d\r\n", _fx_, iSumBSWD, iSumSWD));
  2344. memset(EC->pU8_BitStrCopy, 0, pPB_BitStream - EC->pU8_BitStrCopy + 1);
  2345. bPBFailed = TRUE;
  2346. break;
  2347. }
  2348. // Calculate chroma vectors.
  2349. calcBGOBChromaVectors(EC, StartingMB);
  2350. FORWARDDCT(
  2351. &(EC->pU8_MBlockActionStream[StartingMB]),
  2352. EC->pU8_BFrm_YPlane,
  2353. EC->pU8_PrevFrm_YPlane,
  2354. EC->pU8_FutrFrm_YPlane,
  2355. EC->pU8_DCTCoefBuf,
  2356. 1, // 1 = BFrame
  2357. 0, // Advanced prediction irrelevant for B frame.
  2358. 0, // Is not P of PB pair.
  2359. 0, // PredictionScratchArea unneeded.
  2360. EC->NumMBPerRow
  2361. );
  2362. // GOB header is copied to PB stream when the data for the first
  2363. // macroblock in the GOB is copied
  2364. PB_GOB_Q_RLE_VLC_WriteBS(
  2365. EC,
  2366. EC->pU8_DCTCoefBuf,
  2367. pP_BitStreamStart,
  2368. &pPB_BitStream,
  2369. &u8PB_BitOffset,
  2370. #if defined(H263P)
  2371. EC->pFutrPMBData,
  2372. #else
  2373. FutrPMBData,
  2374. #endif
  2375. GOB,
  2376. min((6*FutrFrmGQUANT[GOB])>>2, 31), // TODO: to match DBQUANT in picture header
  2377. pConfiguration->bRTPHeader
  2378. );
  2379. }
  2380. }
  2381. else // MMX_Enabled == TRUE
  2382. {
  2383. for (GOB = 0; GOB < EC->NumMBRows; GOB ++, GOBHeaderMask <<= 1)
  2384. {
  2385. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: BFRAME GOB #%d\r\n", _fx_, GOB));
  2386. gquant = FutrFrmGQUANT[GOB];
  2387. if (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev))
  2388. {
  2389. // Set a bit if header is present. (bit0=GOB0, bit1=GOB1, ...)
  2390. EC->GOBHeaderPresent |= GOBHeaderMask;
  2391. gquant_prev = gquant;
  2392. }
  2393. // GOB header is copied to PB stream when the data for the first
  2394. // macroblock in the GOB is copied
  2395. PB_GOB_VLC_WriteBS(
  2396. EC,
  2397. EC->pI8_MBRVS_BLuma+GOB*(65*3*22*4),
  2398. EC->pI8_MBRVS_BChroma+GOB*(65*3*22*2),
  2399. pP_BitStreamStart,
  2400. &pPB_BitStream,
  2401. &u8PB_BitOffset,
  2402. #if defined(H263P)
  2403. EC->pFutrPMBData,
  2404. #else
  2405. FutrPMBData,
  2406. #endif
  2407. GOB,
  2408. min((6 * gquant) >> 2, 31),
  2409. pConfiguration->bRTPHeader);
  2410. }
  2411. }
  2412. #else // }{ USE_MMX
  2413. /*****************************************
  2414. * . copy edge pels in the previous frame
  2415. * . initialize arrays used in motion estimation
  2416. * . foreach(GOB)
  2417. * . BFRAMEMOTIONESTIMATION
  2418. * . Compute Chroma motion vectors
  2419. * . Write GOB header
  2420. * . FORWARDDCT
  2421. * . PB_GOB_Q_RLE_VLC_WriteBS
  2422. *****************************************/
  2423. for (GOB = 0; GOB < EC->NumMBRows; GOB ++, GOBHeaderMask <<= 1)
  2424. {
  2425. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: BFRAME GOB #%d\r\n", _fx_, GOB));
  2426. gquant = FutrFrmGQUANT[GOB];
  2427. if (GOB && (pConfiguration->bRTPHeader || gquant != gquant_prev))
  2428. {
  2429. // Set a bit if header is present. (bit0=GOB0, bit1=GOB1, ...)
  2430. EC->GOBHeaderPresent |= GOBHeaderMask;
  2431. gquant_prev = gquant;
  2432. }
  2433. StartingMB = GOB * EC->NumMBPerRow;
  2434. BFRAMEMOTIONESTIMATION(
  2435. &(EC->pU8_MBlockActionStream[StartingMB]),
  2436. EC->pU8_BFrm_YPlane,
  2437. EC->pU8_PrevFrm_YPlane,
  2438. EC->pU8_FutrFrm_YPlane,
  2439. #if defined(H263P)
  2440. EC->pWeightForwMotion+32,
  2441. EC->pWeightBackMotion+32,
  2442. #else
  2443. WeightForwMotion+32,
  2444. WeightBackMotion+32,
  2445. #endif
  2446. u32BFrmZeroThreshold, // Zero Vector Threshold. If less than this threshold don't search for
  2447. #if defined(H263P)
  2448. EC->pPseudoStackSpace,
  2449. #endif
  2450. // NZ MV's. Set to 99999 to not search.
  2451. 128, // NonZeroMVDifferential. Once the best NZ MV is found, it must be better
  2452. // than the 0 MV SWD by at least this amount.
  2453. // Set to 99999 to never choose NZ MV.
  2454. 96, // Empty Threshold. Set to 0 to not force empty blocks.
  2455. &InterSWDTotal,
  2456. &InterSWDBlocks
  2457. );
  2458. iSumBSWD += InterSWDTotal;
  2459. if (TogglePB && iSumBSWD >= (3 * iSumSWD) >> 1)
  2460. {
  2461. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Giving up PB, SumBSWD = %d, SumSWD = %d\r\n", _fx_, iSumBSWD, iSumSWD));
  2462. memset(EC->pU8_BitStrCopy, 0, pPB_BitStream - EC->pU8_BitStrCopy + 1);
  2463. bPBFailed = TRUE;
  2464. break;
  2465. }
  2466. // Calculate chroma vectors.
  2467. calcBGOBChromaVectors(EC, StartingMB);
  2468. FORWARDDCT(
  2469. &(EC->pU8_MBlockActionStream[StartingMB]),
  2470. EC->pU8_BFrm_YPlane,
  2471. EC->pU8_PrevFrm_YPlane,
  2472. EC->pU8_FutrFrm_YPlane,
  2473. EC->pU8_DCTCoefBuf,
  2474. 1, // 1 = BFrame
  2475. 0, // Advanced prediction irrelevant for B frame.
  2476. 0, // Is not P of PB pair.
  2477. 0, // PredictionScratchArea unneeded.
  2478. EC->NumMBPerRow
  2479. );
  2480. // GOB header is copied to PB stream when the data for the first
  2481. // macroblock in the GOB is copied
  2482. PB_GOB_Q_RLE_VLC_WriteBS(
  2483. EC,
  2484. EC->pU8_DCTCoefBuf,
  2485. pP_BitStreamStart,
  2486. &pPB_BitStream,
  2487. &u8PB_BitOffset,
  2488. #if defined(H263P)
  2489. EC->pFutrPMBData,
  2490. #else
  2491. FutrPMBData,
  2492. #endif
  2493. GOB,
  2494. min((6*FutrFrmGQUANT[GOB])>>2, 31), // TODO: to match DBQUANT in picture header
  2495. pConfiguration->bRTPHeader
  2496. );
  2497. }
  2498. #endif // } USE_MMX
  2499. if (bPBFailed == FALSE)
  2500. {
  2501. // Copy the compressed image to the output area.
  2502. SizeBitStream = pPB_BitStream - EC->pU8_BitStrCopy + 1;
  2503. // make sure we don't write 8 empty bits
  2504. if (u8PB_BitOffset == 0) SizeBitStream --;
  2505. // Gim 4/21/97 - check to see if the PB buffer overflows the spec
  2506. // size. If it does, zero out the PB buffer and continue. The P
  2507. // frame encoded will be returned.
  2508. if (SizeBitStream > u32sizeBitBuffer)
  2509. {
  2510. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: PB buffer overflow, SizeBitStream %d > %d\r\n", _fx_, SizeBitStream, u32sizeBitBuffer));
  2511. bPBFailed = TRUE;
  2512. }
  2513. else
  2514. if (pConfiguration->bRTPHeader)
  2515. {
  2516. SizeBSnEBS = SizeBitStream + H263RTP_GetMaxBsInfoStreamSize(EC);
  2517. if (SizeBSnEBS > u32sizeBSnEBS)
  2518. {
  2519. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: PB BS+EBS buffer overflow, SizeBSnEBS %d > %d\r\n", _fx_, SizeBSnEBS, u32sizeBSnEBS));
  2520. bPBFailed = TRUE;
  2521. }
  2522. }
  2523. if (bPBFailed == TRUE)
  2524. {
  2525. // if buffer overflow has been detected, we will drop the PB
  2526. // and return the encoded P
  2527. memset(EC->pU8_BitStrCopy, 0, SizeBitStream);
  2528. EC->u8SavedBFrame = FALSE;
  2529. }
  2530. else
  2531. {
  2532. #ifdef ENCODE_STATS
  2533. uBitStreamBytes = SizeBitStream;
  2534. #endif
  2535. memcpy(lpicComp->lpOutput, EC->pU8_BitStrCopy, SizeBitStream);
  2536. memset(EC->pU8_BitStrCopy, 0, SizeBitStream);
  2537. if (pConfiguration->bRTPHeader)
  2538. SizeBitStream += (WORD) H263RTP_AttachBsInfoStream(EC,
  2539. (U8 *) lpicComp->lpOutput, SizeBitStream);
  2540. lpCompInst->CompressedSize = SizeBitStream;
  2541. }
  2542. }
  2543. // For the next PB-frame, frame pointers are swapped; i.e. for the next
  2544. // frame future ...
  2545. temp = EC->pU8_PrevFrm;
  2546. EC->pU8_PrevFrm = EC->pU8_FutrFrm;
  2547. EC->pU8_FutrFrm = temp;
  2548. temp = EC->pU8_PrevFrm_YPlane;
  2549. EC->pU8_PrevFrm_YPlane = EC->pU8_FutrFrm_YPlane;
  2550. EC->pU8_FutrFrm_YPlane = temp;
  2551. temp = EC->pU8_PrevFrm_UPlane;
  2552. EC->pU8_PrevFrm_UPlane = EC->pU8_FutrFrm_UPlane;
  2553. EC->pU8_FutrFrm_UPlane = temp;
  2554. temp = EC->pU8_PrevFrm_VPlane;
  2555. EC->pU8_PrevFrm_VPlane = EC->pU8_FutrFrm_VPlane;
  2556. EC->pU8_FutrFrm_VPlane = temp;
  2557. EC->u8SavedBFrame = FALSE;
  2558. EC->PictureHeader.PB = OFF; // RH: why is this here ?
  2559. } // if (bEncodePBFrame)
  2560. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Frame size: %d\r\n", _fx_, lpCompInst->CompressedSize));
  2561. #ifdef ENCODE_STATS
  2562. StatsFrameSize(uBitStreamBytes, lpCompInst->CompressedSize);
  2563. #endif
  2564. // ------------------------------------------------------------------------
  2565. // update states for next frame, etc.
  2566. // ------------------------------------------------------------------------
  2567. // This is a still image sequence and there is still more quantizers
  2568. // in the sequence, then increment the quantizer.
  2569. if ((lpicComp->dwFlags & CODEC_CUSTOM_STILL) &&
  2570. (EC->BRCState.u8StillQnt < (numStillImageQnts-1)))
  2571. EC->BRCState.u8StillQnt ++;
  2572. // Calculate average quantizer to be used for next frame.
  2573. if (EC->PictureHeader.PicCodType == INTERPIC)
  2574. EC->BRCState.QP_mean = (QP_cumulative + (EC->NumMBRows >> 1)) / EC->NumMBRows;
  2575. else
  2576. // If this is an INTRA frame, then we don't want to
  2577. // use the QP for the next delta frame, hence we just
  2578. // reset the QP_mean to the default.
  2579. EC->BRCState.QP_mean = def263INTER_QP;
  2580. // Record frame size for bit rate controller on next frame.
  2581. // IP + UDP + RTP + payload mode C header - worst case
  2582. #define TRANSPORT_HEADER_SIZE (20 + 8 + 12 + 12)
  2583. DWORD dwTransportOverhead;
  2584. // Estimate the transport overhead
  2585. if (pConfiguration->bRTPHeader)
  2586. dwTransportOverhead = (lpCompInst->CompressedSize / pConfiguration->unPacketSize + 1) * TRANSPORT_HEADER_SIZE;
  2587. else
  2588. dwTransportOverhead = 0UL;
  2589. #ifdef USE_MMX // { USE_MMX
  2590. if (EC->PictureHeader.PicCodType == INTRAPIC)
  2591. EC->BRCState.uLastINTRAFrmSz = dwTransportOverhead + ((MMX_Enabled == FALSE) ? uAdjCumFrmSize : uCumFrmSize);
  2592. else
  2593. EC->BRCState.uLastINTERFrmSz = dwTransportOverhead + ((MMX_Enabled == FALSE) ? uAdjCumFrmSize : uCumFrmSize);
  2594. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Total cumulated frame size = %ld bits (data: %ld, transport overhead: %ld)\r\n", _fx_, (((MMX_Enabled == FALSE) ? uAdjCumFrmSize : uCumFrmSize) << 3) + (dwTransportOverhead << 3), ((MMX_Enabled == FALSE) ? uAdjCumFrmSize : uCumFrmSize) << 3, dwTransportOverhead << 3));
  2595. #else // }{ USE_MMX
  2596. if (EC->PictureHeader.PicCodType == INTRAPIC)
  2597. EC->BRCState.uLastINTRAFrmSz = dwTransportOverhead + uAdjCumFrmSize;
  2598. else
  2599. EC->BRCState.uLastINTERFrmSz = dwTransportOverhead + uAdjCumFrmSize;
  2600. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Total cumulated frame size = %ld bits (data: %ld, transport overhead: %ld)\r\n", _fx_, (uAdjCumFrmSize << 3) + (dwTransportOverhead << 3), uAdjCumFrmSize << 3, dwTransportOverhead << 3));
  2601. #endif // } USE_MMX
  2602. // Save temporal reference for next frame.
  2603. EC->PictureHeader.TRPrev = EC->PictureHeader.TR;
  2604. // Save AP, UMV and DF modes in case InitMEState needs to re-initialize some data
  2605. if (EC->PictureHeader.PicCodType == INTERPIC)
  2606. {
  2607. EC->prevAP = EC->PictureHeader.AP;
  2608. EC->prevUMV = EC->PictureHeader.UMV;
  2609. #ifdef H263P
  2610. EC->prevDF = EC->PictureHeader.DeblockingFilter;
  2611. #endif
  2612. }
  2613. // send mean quantizer to real-time app. Not necessary, info. only
  2614. *(lpicComp->lpdwFlags) |= (EC->BRCState.QP_mean << 16);
  2615. #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON) // { #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  2616. TIMER_STOP(bTimingThisFrame,uStartLow,uStartHigh,uEncodeTime);
  2617. if (bTimingThisFrame)
  2618. {
  2619. // Update the decompression timings counter
  2620. #pragma message ("Current encode timing computations assume P5/90Mhz")
  2621. UPDATE_COUNTER(g_pctrCompressionTimePerFrame, (uEncodeTime + 45000UL) / 90000UL);
  2622. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Compression time: %ld\r\n", _fx_, (uEncodeTime + 45000UL) / 90000UL));
  2623. }
  2624. #endif // } ENCODE_TIMINGS_ON
  2625. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  2626. if (bTimingThisFrame)
  2627. {
  2628. pEncTimingInfo = EC->pEncTimingInfo + EC->uStatFrameCount;
  2629. pEncTimingInfo->uEncodeFrame = uEncodeTime;
  2630. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  2631. pEncTimingInfo->uInputCC = uInputCC;
  2632. pEncTimingInfo->uMotionEstimation = uMotionEstimation;
  2633. pEncTimingInfo->uFDCT = uFDCT;
  2634. pEncTimingInfo->uQRLE = uQRLE;
  2635. pEncTimingInfo->uDecodeFrame = uDecodeFrame;
  2636. pEncTimingInfo->uZeroingBuffer = uZeroingBuffer;
  2637. #endif // } DETAILED_ENCODE_TIMINGS_ON
  2638. EC->uStatFrameCount++;
  2639. }
  2640. #endif // } #if defined(ENCODE_TIMINGS_ON) || defined(DETAILED_ENCODE_TIMINGS_ON)
  2641. /*
  2642. #ifdef REUSE_DECODE
  2643. CompandedFrame.Address = (unsigned char*) lpicComp->lpOutput;
  2644. CompandedFrame.PDecoderInstInfo = PDecoderInstInfo;
  2645. CompandedFrame.FrameNumber = PFrmHdr->FrameNumber;
  2646. #endif
  2647. */
  2648. #if ELAPSED_ENCODER_TIME
  2649. StopElapsed ();
  2650. Elapsed = ReadElapsed () / 4L;
  2651. Sample = ReadSample () / 4L;
  2652. #if 01
  2653. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: "%ld,%ld us\r\n", _fx_, Elapsed, Sample));
  2654. #else
  2655. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Elapsed time to encode frame: %ld us\r\n", _fx_, Elapsed));
  2656. #if SAMPLE_RGBCONV_TIME
  2657. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Time to convert RGB24 to YUV9: %ld us\r\n", _fx_, Sample));
  2658. #endif
  2659. #if SAMPLE_MOTION_TIME
  2660. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Time to do motion estimation: %ld us\r\n", _fx_, Sample));
  2661. #endif
  2662. #if SAMPLE_ENCBLK_TIME
  2663. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Time to encode block layer: %ld us\r\n", _fx_, Sample));
  2664. #endif
  2665. #if SAMPLE_ENCMBLK_TIME
  2666. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Time to encode macroblock layer: %ld us\r\n", _fx_, Sample));
  2667. #endif
  2668. #if SAMPLE_ENCVLC_TIME
  2669. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Time to encode VLC: %ld us\r\n", _fx_, Sample));
  2670. #endif
  2671. #if SAMPLE_COMPAND_TIME
  2672. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Time to decode companded image: %ld us\r\n", _fx_, Sample));
  2673. #endif
  2674. #endif
  2675. TotalElapsed += Elapsed;
  2676. TotalSample += Sample;
  2677. TimedIterations++;
  2678. #endif
  2679. done:
  2680. // GlobalUnlock(lpCompInst->hEncoderInst);
  2681. #ifdef FORCE_ADVANCED_OPTIONS_ON // { FORCE_ADVANCED_OPTIONS_ON
  2682. // Force advanced options for testing
  2683. if (!(lpicComp->dwFlags & ICCOMPRESS_KEYFRAME))
  2684. lpicComp->lFrameNum /= 5;
  2685. #endif // } FORCE_ADVANCED_OPTIONS_ON
  2686. #ifdef USE_MMX // { USE_MMX
  2687. if (MMX_Enabled)
  2688. {
  2689. __asm {
  2690. _emit 0x0f
  2691. _emit 0x77 // emms
  2692. }
  2693. }
  2694. #endif // } USE_MMX
  2695. return ret;
  2696. }
  2697. /****************************************************************************
  2698. * @doc INTERNAL H263FUNC
  2699. *
  2700. * @func UN | FindNewQuant | This function computes the GQUANT value to
  2701. * use for a GOB.
  2702. *
  2703. * @parm T_H263EncoderCatalog * | EC | Specifies a pointer to the encoder
  2704. * catalog (global encoder state).
  2705. *
  2706. * @parm UN | gquant_prev | Specifies the GQUANT value of the previous GOB.
  2707. *
  2708. * @parm UN | uCumFrmSize | Specifies the cumulated size of the previous GOBs.
  2709. *
  2710. * @parm UN | GOB | Specifies the number of the GOB to find a new quantizer
  2711. * for.
  2712. *
  2713. * @parm U8 | u8QPMax | Specifies the maximum GQUANT value for the GOB. It
  2714. * is always set to 31.
  2715. *
  2716. * @parm U8 | u8QPMin | Specifies the minimum GQUANT value for the GOB. It
  2717. * is typically 1 when compressing at high quality, or 15 at low quality.
  2718. *
  2719. * @parm BOOL | bBitRateControl | If set to TRUE, the new value for GQUANT
  2720. * is computed to achieve a target bitrate.
  2721. *
  2722. * @parm BOOL | bGOBoverflowWarning | If set to TRUE, the previous GQUANT was
  2723. * tool low and could potentially generate a buffer overflow.
  2724. *
  2725. * @rdesc The GQUANT value.
  2726. *
  2727. * @xref <f CalcMBQUANT>
  2728. ***************************************************************************/
  2729. UN FindNewQuant(
  2730. T_H263EncoderCatalog *EC,
  2731. UN gquant_prev,
  2732. UN uCumFrmSize,
  2733. UN GOB,
  2734. U8 u8QPMax,
  2735. U8 u8QPMin,
  2736. BOOL bBitRateControl,
  2737. BOOL bGOBoverflowWarning
  2738. )
  2739. {
  2740. FX_ENTRY("FindNewQuant");
  2741. I32 gquant_delta;
  2742. I32 gquant;
  2743. if (bBitRateControl == ON)
  2744. {
  2745. // Check out if some GOBs have been arbitrary forced to be Intra coded. This always
  2746. // returns TRUE for an I-frame, and FALSE for all other frame types since this can only
  2747. // return TRUE for predicted frames when the error resiliency mode is ON, and we never
  2748. // use this mode.
  2749. if (IsIntraCoded(EC,GOB) && GOB)
  2750. gquant = CalcMBQUANT(&(EC->BRCState), EC->uBitUsageProfile[GOB], EC->uBitUsageProfile[EC->NumMBRows], uCumFrmSize,INTRAPIC);
  2751. else
  2752. gquant = CalcMBQUANT(&(EC->BRCState), EC->uBitUsageProfile[GOB], EC->uBitUsageProfile[EC->NumMBRows], uCumFrmSize, EC->PictureHeader.PicCodType);
  2753. EC->uBitUsageProfile[GOB] = uCumFrmSize;
  2754. // Make sure we don't exceed the maximum quantizer value
  2755. if (gquant > u8QPMax)
  2756. gquant = u8QPMax;
  2757. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Bitrate controller enabled for GOB #%ld (uCumFrmSize = %ld bits and gquant_prev = %ld), setting gquant = %ld (min and max were %ld and %ld)\r\n", _fx_, GOB, uCumFrmSize << 3, gquant_prev, gquant, u8QPMin, u8QPMax));
  2758. }
  2759. else
  2760. {
  2761. // No bitrate control. Use the picture quantizer value for this GOB
  2762. gquant = EC->PictureHeader.PQUANT;
  2763. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, ("%s: Bitrate controller disabled for GOB #%ld (uCumFrmSize = %ld bits and gquant_prev = %ld), setting gquant = %ld (min and max were %ld and %ld)\r\n", _fx_, GOB, uCumFrmSize << 3, gquant_prev, gquant, u8QPMin, u8QPMax));
  2764. }
  2765. // Make sure we're not below the minimum quantizer value
  2766. if (gquant < u8QPMin)
  2767. gquant = u8QPMin;
  2768. // Limit the amount that GQUANT can change from frame to frame
  2769. gquant_delta = gquant - gquant_prev;
  2770. // Increase the QP value if there is danger of buffer overflow
  2771. if (!bGOBoverflowWarning)
  2772. {
  2773. // There's no overflow warning, but we don't want the quantizer value to
  2774. // fluctuate too much from GOB to GOB
  2775. if (gquant_delta > 4L)
  2776. {
  2777. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, (" %s: Limiting amount of increase for GOB #%ld to 4, changing gquant from %ld to %ld\r\n", _fx_, GOB, gquant, clampQP(gquant_prev + 4L)));
  2778. gquant = gquant_prev + 4L;
  2779. }
  2780. else if (gquant_delta < -2L)
  2781. {
  2782. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, (" %s: Limiting amount of decrease for GOB #%ld to -2, changing gquant from %ld to %ld\r\n", _fx_, GOB, gquant, clampQP(gquant_prev - 2L)));
  2783. gquant = gquant_prev - 2L;
  2784. }
  2785. }
  2786. else
  2787. {
  2788. // There's a risk of overflow - arbitrarily raise the value of the quantizer if necessary
  2789. if (gquant_delta < 4L)
  2790. {
  2791. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, (" %s: Danger of overflow for GOB #%ld, changing gquant from %ld to %ld\r\n", _fx_, GOB, gquant, clampQP(gquant_prev + 4L)));
  2792. gquant = gquant_prev + 4L;
  2793. }
  2794. }
  2795. return clampQP(gquant);
  2796. }
  2797. /*******************************************************************************
  2798. H263TermEncoderInstance -- This function frees the space allocated for an
  2799. instance of the H263 encoder.
  2800. *******************************************************************************/
  2801. LRESULT H263TermEncoderInstance(LPCODINST lpInst)
  2802. {
  2803. LRESULT ret;
  2804. U8 BIGG * P32Inst;
  2805. T_H263EncoderCatalog FAR * EC;
  2806. FX_ENTRY("H263TermEncoderInstance")
  2807. #if DUMPFILE
  2808. _lclose (dmpfil);
  2809. #endif
  2810. #if ELAPSED_ENCODER_TIME
  2811. if (TimedIterations == 0) TimedIterations = 10000000;
  2812. TotalElapsed /= TimedIterations;
  2813. TotalSample /= TimedIterations;
  2814. #if 01
  2815. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: "%ld,%ld us\r\n", _fx_, TotalElapsed, TotalSample));
  2816. #else
  2817. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average elapsed time to encode frame: %ld us\r\n", _fx_, TotalElapsed));
  2818. #if SAMPLE_RGBCONV_TIME
  2819. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average time to convert RGB24 to YUV9: %ld us\r\n", _fx_, TotalSample));
  2820. #endif
  2821. #if SAMPLE_MOTION_TIME
  2822. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average time to do motion estimation: %ld us\r\n", _fx_, TotalSample));
  2823. #endif
  2824. #if SAMPLE_ENCBLK_TIME
  2825. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average time to encode block layer: %ld us\r\n", _fx_, TotalSample));
  2826. #endif
  2827. #if SAMPLE_ENCMBLK_TIME
  2828. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average time to encode macroblock layer: %ld us\r\n", _fx_, TotalSample));
  2829. #endif
  2830. #if SAMPLE_ENCVLC_TIME
  2831. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average time to encode VLC: %ld us\r\n", _fx_, TotalSample));
  2832. #endif
  2833. #if SAMPLE_COMPAND_TIME
  2834. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Average time to decode companded image: %ld us\r\n", _fx_, TotalSample));
  2835. #endif
  2836. #endif
  2837. #endif
  2838. // Check instance pointer
  2839. if (!lpInst)
  2840. return ICERR_ERROR;
  2841. if(lpInst->Initialized == FALSE)
  2842. {
  2843. ERRORMESSAGE(("%s: Uninitialized instance\r\n", _fx_));
  2844. ret = ICERR_OK;
  2845. goto done;
  2846. }
  2847. lpInst->Initialized = FALSE;
  2848. // lpInst->EncoderInst = (LPVOID)GlobalLock(lpInst->hEncoderInst);
  2849. lpInst->EncoderInst = lpInst->hEncoderInst;
  2850. P32Inst = (U8 *)
  2851. ((((U32) lpInst->EncoderInst) +
  2852. (sizeof(T_MBlockActionStream) - 1)) &
  2853. ~(sizeof(T_MBlockActionStream) - 1));
  2854. EC = ((T_H263EncoderCatalog *) P32Inst);
  2855. // Check encoder catalog pointer
  2856. if (!EC)
  2857. return ICERR_ERROR;
  2858. if (lpInst->Configuration.bRTPHeader)
  2859. H263RTP_TermBsInfoStream(EC);
  2860. #ifdef ENCODE_STATS
  2861. OutputQuantStats("encstats.txt");
  2862. OutputPSNRStats("encstats.txt");
  2863. OutputFrameSizeStats("encstats.txt");
  2864. #endif /* ENCODE_STATS */
  2865. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  2866. if (EC->pEncTimingInfo)
  2867. OutputEncodeTimingStatistics("c:\\encode.txt", EC->pEncTimingInfo);
  2868. #endif // } LOG_ENCODE_TIMINGS_ON
  2869. ret = H263TermColorConvertor(EC->pDecInstanceInfo);
  2870. if (ret != ICERR_OK) goto done;
  2871. #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON) // { #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2872. ret = H263TermDecoderInstance(EC->pDecInstanceInfo, FALSE);
  2873. #else // }{ #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2874. ret = H263TermDecoderInstance(EC->pDecInstanceInfo);
  2875. #endif // } #if defined(DECODE_TIMINGS_ON) || defined(DETAILED_DECODE_TIMINGS_ON)
  2876. if (ret != ICERR_OK) goto done;
  2877. // Free virtual memory
  2878. VirtualFree(EC->pI8_MBRVS_BLuma,0,MEM_RELEASE);
  2879. #ifdef TRACK_ALLOCATIONS
  2880. // Track memory allocation
  2881. RemoveName((unsigned int)EC->pI8_MBRVS_BLuma);
  2882. #endif
  2883. VirtualFree(EC->pI8_MBRVS_BChroma,0,MEM_RELEASE);
  2884. #ifdef TRACK_ALLOCATIONS
  2885. // Track memory allocation
  2886. RemoveName((unsigned int)EC->pI8_MBRVS_BChroma);
  2887. #endif
  2888. // No matter how many sparse pages we committed during encoding,
  2889. // the whole memory block is released with these calls.
  2890. // Documentation on VirtualFree() says the individual pages must
  2891. // first be decommitted, but this is not correct, according
  2892. // to Jeffrey R. Richter
  2893. // GlobalUnlock(lpInst->hEncoderInst);
  2894. // GlobalFree(lpInst->hEncoderInst);
  2895. VirtualFree(lpInst->hEncoderInst,0,MEM_RELEASE);
  2896. #ifdef TRACK_ALLOCATIONS
  2897. // Track memory allocation
  2898. RemoveName((unsigned int)lpInst->hEncoderInst);
  2899. #endif
  2900. ret = ICERR_OK;
  2901. done:
  2902. return ret;
  2903. }
  2904. /************************************************************************
  2905. *
  2906. * GetEncoderOptions
  2907. *
  2908. * Get the options, saving them in the catalog
  2909. *************************************************************************/
  2910. static void GetEncoderOptions(T_H263EncoderCatalog * EC)
  2911. {
  2912. /* Default Options
  2913. */
  2914. #ifdef FORCE_ADVANCED_OPTIONS_ON // { FORCE_ADVANCED_OPTIONS_ON
  2915. // Force PB-Frames for testing
  2916. EC->u8EncodePBFrame = OFF;
  2917. // Force UMV for testing
  2918. EC->PictureHeader.UMV = ON;
  2919. // Force SAC for testing
  2920. EC->PictureHeader.SAC = ON;
  2921. // Force AP for testing
  2922. EC->PictureHeader.AP = ON;
  2923. #else // }{ FORCE_ADVANCED_OPTIONS_ON
  2924. EC->u8EncodePBFrame = FALSE;
  2925. EC->PictureHeader.UMV = OFF;
  2926. EC->PictureHeader.SAC = OFF;
  2927. EC->PictureHeader.AP = OFF;
  2928. #endif // } FORCE_ADVANCED_OPTIONS_ON
  2929. #ifdef USE_MMX // { USE_MMX
  2930. MMX_Enabled = MMxVersion;
  2931. #endif // } USE_MMX
  2932. #ifdef H263P
  2933. EC->bH263Plus = FALSE;
  2934. EC->PictureHeader.DeblockingFilter = OFF;
  2935. EC->PictureHeader.ImprovedPB = OFF;
  2936. #endif
  2937. EC->bUseINISettings = 0; // Clear option override.
  2938. return;
  2939. } /* end GetEncoderOptions() */
  2940. /*************************************************************
  2941. * Name: encodeFrameHeader
  2942. * Description: Write out the PB-frame header to the bit stream.
  2943. ************************************************************/
  2944. static void encodeFrameHeader(
  2945. T_H263EncoderCatalog * EC,
  2946. U8 ** ppCurBitStream,
  2947. U8 * pBitOffset,
  2948. BOOL PBframe
  2949. )
  2950. {
  2951. U8 temp=0;
  2952. #ifdef H263P
  2953. BOOL bUseH263PlusOptions = FALSE;
  2954. #endif
  2955. // Picture start code
  2956. PutBits(FIELDVAL_PSC, FIELDLEN_PSC, ppCurBitStream, pBitOffset);
  2957. // TR : Temporal reference
  2958. PutBits(EC->PictureHeader.TR, FIELDLEN_TR, ppCurBitStream, pBitOffset);
  2959. // PTYPE : bits 1-2
  2960. PutBits(0x2, FIELDLEN_PTYPE_CONST, ppCurBitStream, pBitOffset);
  2961. // PTYPE : bit 3 split screen indicator
  2962. PutBits(EC->PictureHeader.Split, FIELDLEN_PTYPE_SPLIT, ppCurBitStream,
  2963. pBitOffset);
  2964. // PTYPE : bit 4 document camera indicator
  2965. PutBits(EC->PictureHeader.DocCamera, FIELDLEN_PTYPE_DOC, ppCurBitStream,
  2966. pBitOffset);
  2967. // PTYPE : bit 5 freeze picture release
  2968. PutBits(EC->PictureHeader.PicFreeze, FIELDLEN_PTYPE_RELEASE,
  2969. ppCurBitStream, pBitOffset);
  2970. #ifdef H263P
  2971. if ((EC->FrameSz == CUSTOM) ||
  2972. (EC->PictureHeader.DeblockingFilter == ON) ||
  2973. (EC->PictureHeader.PB == ON && EC->PictureHeader.ImprovedPB == ON)
  2974. // other supported H.263+ options
  2975. )
  2976. {
  2977. // PTYPE : bits 6-8 extended PTYPE flag
  2978. enum FrameSize tmpFrameSz = EPTYPE;
  2979. bUseH263PlusOptions = TRUE; // at least one H.263+ optional mode requested
  2980. PutBits(tmpFrameSz, FIELDLEN_PTYPE_SRCFORMAT, ppCurBitStream, pBitOffset);
  2981. }
  2982. else
  2983. {
  2984. // PTYPE : bits 6-8 source format
  2985. PutBits(EC->FrameSz, FIELDLEN_PTYPE_SRCFORMAT, ppCurBitStream, pBitOffset);
  2986. }
  2987. #else
  2988. // PTYPE : bits 6-8 source format
  2989. PutBits(EC->FrameSz, FIELDLEN_PTYPE_SRCFORMAT, ppCurBitStream, pBitOffset);
  2990. #endif
  2991. // PTYPE : bit 9 picture coding type
  2992. PutBits(EC->PictureHeader.PicCodType, FIELDLEN_PTYPE_CODINGTYPE,
  2993. ppCurBitStream, pBitOffset);
  2994. // PTYPE : bit 10 UMV
  2995. PutBits(EC->PictureHeader.UMV, FIELDLEN_PTYPE_UMV,
  2996. ppCurBitStream, pBitOffset);
  2997. // PTYPE : bit 11 SAC
  2998. PutBits(EC->PictureHeader.SAC, FIELDLEN_PTYPE_SAC,
  2999. ppCurBitStream, pBitOffset);
  3000. // PTYPE : bit 12 advanced prediction mode
  3001. PutBits(EC->PictureHeader.AP, FIELDLEN_PTYPE_AP,
  3002. ppCurBitStream, pBitOffset);
  3003. // PTYPE : bit 13 PB-frames mode
  3004. PutBits(EC->PictureHeader.PB, FIELDLEN_PTYPE_PB,
  3005. ppCurBitStream, pBitOffset);
  3006. #ifdef H263P
  3007. // EPTYPE : 18 bits
  3008. if (bUseH263PlusOptions) {
  3009. // EPTYPE : bits 1-3 source format
  3010. PutBits(EC->FrameSz, FIELDLEN_EPTYPE_SRCFORMAT,
  3011. ppCurBitStream, pBitOffset);
  3012. // EPTYPE : bit 4 custom PCF
  3013. PutBits(EC->PictureHeader.CustomPCF, FIELDLEN_EPTYPE_CPCF,
  3014. ppCurBitStream, pBitOffset);
  3015. // EPTYPE : bit 5 advanced intra coding mode
  3016. PutBits(EC->PictureHeader.AdvancedIntra, FIELDLEN_EPTYPE_AI,
  3017. ppCurBitStream, pBitOffset);
  3018. // EPTYPE : bit 6 deblocking filter mode
  3019. PutBits(EC->PictureHeader.DeblockingFilter, FIELDLEN_EPTYPE_DF,
  3020. ppCurBitStream, pBitOffset);
  3021. // EPTYPE : bit 7 slice structured mode
  3022. PutBits(EC->PictureHeader.SliceStructured, FIELDLEN_EPTYPE_SS,
  3023. ppCurBitStream, pBitOffset);
  3024. // EPTYPE : bit 8 improved PB-frame mode
  3025. PutBits((EC->PictureHeader.PB == ON && EC->PictureHeader.ImprovedPB),
  3026. FIELDLEN_EPTYPE_IPB,
  3027. ppCurBitStream, pBitOffset);
  3028. // EPTYPE : bit 9 back-channel operation mode
  3029. PutBits(EC->PictureHeader.BackChannel, FIELDLEN_EPTYPE_BCO,
  3030. ppCurBitStream, pBitOffset);
  3031. // EPTYPE : bit 10 SNR and spatial scalability mode
  3032. PutBits(EC->PictureHeader.Scalability, FIELDLEN_EPTYPE_SCALE,
  3033. ppCurBitStream, pBitOffset);
  3034. // EPTYPE : bit 11 true B-frame mode
  3035. PutBits(EC->PictureHeader.TrueBFrame, FIELDLEN_EPTYPE_TB,
  3036. ppCurBitStream, pBitOffset);
  3037. // EPTYPE : bit 12 reference-picture resampling mode
  3038. PutBits(EC->PictureHeader.RefPicResampling, FIELDLEN_EPTYPE_RPR,
  3039. ppCurBitStream, pBitOffset);
  3040. // EPTYPE : bit 13 reduced-resolution update mode
  3041. PutBits(EC->PictureHeader.RedResUpdate, FIELDLEN_EPTYPE_RRU,
  3042. ppCurBitStream, pBitOffset);
  3043. // EPTYPE : bit 14-18 reserved
  3044. PutBits(0x1, FIELDLEN_EPTYPE_CONST, ppCurBitStream, pBitOffset);
  3045. }
  3046. if (EC->FrameSz == CUSTOM) {
  3047. // CSFMT : bit 1-4 pixel aspect ratio code
  3048. // TODO. For now, force to CIF
  3049. PutBits(0x2, FIELDLEN_CSFMT_PARC,
  3050. ppCurBitStream, pBitOffset);
  3051. // CSFMT : bits 5-13 frame width indication
  3052. PutBits((EC->uActualFrameWidth >> 2) - 1, FIELDLEN_CSFMT_FWI,
  3053. ppCurBitStream, pBitOffset);
  3054. // CSFMT : bit 14 "1" to avoid start code emulation
  3055. PutBits(0x1, FIELDLEN_CSFMT_CONST, ppCurBitStream, pBitOffset);
  3056. // CSFMT : bits 15-23 frame height indication
  3057. PutBits((EC->uActualFrameHeight >> 2) - 1, FIELDLEN_CSFMT_FHI,
  3058. ppCurBitStream, pBitOffset);
  3059. }
  3060. #endif
  3061. // PQUANT
  3062. PutBits(EC->PictureHeader.PQUANT, FIELDLEN_PQUANT,
  3063. ppCurBitStream, pBitOffset);
  3064. // CPM
  3065. PutBits(EC->PictureHeader.CPM, FIELDLEN_CPM,
  3066. ppCurBitStream, pBitOffset);
  3067. if (PBframe == TRUE)
  3068. {
  3069. // AG:TODO
  3070. // TRB
  3071. PutBits(EC->PictureHeader.TRB, FIELDLEN_TRB,
  3072. ppCurBitStream, pBitOffset);
  3073. // AG:TODO
  3074. // DBQUANT
  3075. PutBits(EC->PictureHeader.DBQUANT, FIELDLEN_DBQUANT,
  3076. ppCurBitStream, pBitOffset);
  3077. #ifdef COUNT_BITS
  3078. EC->Bits.PictureHeader += FIELDLEN_TRB + FIELDLEN_DBQUANT;
  3079. #endif
  3080. }
  3081. // PEI
  3082. PutBits(EC->PictureHeader.PEI, FIELDLEN_PEI,
  3083. ppCurBitStream, pBitOffset);
  3084. #ifdef COUNT_BITS
  3085. EC->Bits.PictureHeader += FIELDLEN_PSC + FIELDLEN_TR
  3086. + FIELDLEN_PTYPE_CONST + FIELDLEN_PTYPE_SPLIT
  3087. + FIELDLEN_PTYPE_DOC + FIELDLEN_PTYPE_RELEASE
  3088. + FIELDLEN_PTYPE_SRCFORMAT + FIELDLEN_PTYPE_CODINGTYPE
  3089. + FIELDLEN_PTYPE_UMV + FIELDLEN_PTYPE_SAC
  3090. + FIELDLEN_PTYPE_AP + FIELDLEN_PTYPE_PB
  3091. + FIELDLEN_PQUANT + FIELDLEN_CPM
  3092. + FIELDLEN_PEI;
  3093. #endif
  3094. }
  3095. /*************************************************************
  3096. * Name: InitMEState
  3097. * Description: Initialize the MB action stream for the ME
  3098. * state engine.
  3099. ************************************************************/
  3100. void InitMEState(T_H263EncoderCatalog *EC, ICCOMPRESS *lpicComp, T_CONFIGURATION *pConfiguration)
  3101. {
  3102. register unsigned int i;
  3103. U8 u8FirstMEState;
  3104. FX_ENTRY("InitMEState")
  3105. // TODO: The FirstMEState initialization can be avoided
  3106. // for each compress by either adding a parameter to the
  3107. // motion estimator signalling key frame, or by not calling
  3108. // motion estimation on intra frames, and resetting MBType,
  3109. // CodedBlocks ourselves.
  3110. if (EC->PictureHeader.PicCodType == INTRAPIC)
  3111. {
  3112. for(i=0; i < EC->NumMBs; i++)
  3113. {
  3114. // Clear the intercode count.
  3115. (EC->pU8_MBlockActionStream[i]).InterCodeCnt = (i & 0xf);
  3116. // For the motion estimator, this field must be set to force
  3117. // intra blocks for intra frames.
  3118. (EC->pU8_MBlockActionStream[i]).FirstMEState = ForceIntra;
  3119. }
  3120. *(lpicComp->lpdwFlags) |= AVIIF_KEYFRAME;
  3121. lpicComp->dwFlags |= ICCOMPRESS_KEYFRAME;
  3122. // Store that this frame was intra coded. Used during the initialization
  3123. // of the ME state for the next frame.
  3124. EC->bPrevFrameIntra = TRUE;
  3125. }
  3126. else // Picture Coding type is INTERPIC
  3127. {
  3128. /*
  3129. * The FirstMEState element in each MB structure must be set
  3130. * to indicate its position in the frame. This is used by the
  3131. * motion estimator.
  3132. */
  3133. /*
  3134. * Check for AP or UMV modes. When these mode is signalled, motion vectors are
  3135. * allowed to point outside the picture.
  3136. */
  3137. /* We also need to perform the initialization if the previous frame
  3138. was an intra frame! (JM)
  3139. */
  3140. if (EC->bPrevFrameIntra ||
  3141. EC->PictureHeader.AP != EC->prevAP ||
  3142. EC->PictureHeader.UMV != EC->prevUMV
  3143. #ifdef H263P
  3144. || EC->PictureHeader.DeblockingFilter != EC->prevDF
  3145. #endif
  3146. ) {
  3147. if( (EC->PictureHeader.UMV == ON) || (EC->PictureHeader.AP == ON)
  3148. #ifdef H263P
  3149. || (EC->PictureHeader.DeblockingFilter == ON)
  3150. #endif
  3151. )
  3152. {
  3153. // Set ME state central blocks.
  3154. for(i=0; i < EC->NumMBs; i++)
  3155. (EC->pU8_MBlockActionStream[i]).FirstMEState = CentralBlock;
  3156. }
  3157. else // No AP or UMV option.
  3158. {
  3159. // Set upper left corner
  3160. (EC->pU8_MBlockActionStream[0]).FirstMEState = UpperLeft;
  3161. // Set ME state for top edge.
  3162. for(i=1; i < EC->NumMBPerRow; i++)
  3163. (EC->pU8_MBlockActionStream[i]).FirstMEState = UpperEdge;
  3164. // Set upper right corner.
  3165. (EC->pU8_MBlockActionStream[ EC->NumMBPerRow - 1 ]).FirstMEState = UpperRight;
  3166. // Set ME state for central blocks.
  3167. for(i=EC->NumMBPerRow; i < EC->NumMBs; i++)
  3168. (EC->pU8_MBlockActionStream[i]).FirstMEState = CentralBlock;
  3169. // Set ME state for bottom edge.
  3170. for(i= (EC->NumMBs - EC->NumMBPerRow); i < EC->NumMBs; i++)
  3171. (EC->pU8_MBlockActionStream[i]).FirstMEState = LowerEdge;
  3172. // Set ME state for left edge
  3173. for(i= EC->NumMBPerRow ; i < EC->NumMBs; i += EC->NumMBPerRow)
  3174. (EC->pU8_MBlockActionStream[i]).FirstMEState = LeftEdge;
  3175. // Set ME state for right edge.
  3176. for(i= 2 * EC->NumMBPerRow - 1 ; i < EC->NumMBs; i += EC->NumMBPerRow)
  3177. (EC->pU8_MBlockActionStream[i]).FirstMEState = RightEdge;
  3178. // Bottom left corner.
  3179. (EC->pU8_MBlockActionStream[EC->NumMBs - EC->NumMBPerRow]).FirstMEState = LowerLeft;
  3180. // Bottom right corner.
  3181. (EC->pU8_MBlockActionStream[EC->NumMBs - 1]).FirstMEState = LowerRight;
  3182. } // end of else (not UMV)
  3183. } // end of if (bPrevFrameIntra || prevAP != AP || prevUMV != UMV || prevDF != DF)
  3184. // Clear key frame flag.
  3185. *(lpicComp->lpdwFlags) &= ~AVIIF_KEYFRAME;
  3186. lpicComp->dwFlags &= ~ICCOMPRESS_KEYFRAME;
  3187. // Store that this frame was not intra coded. Used during the initialization
  3188. // of the ME state for the next frame.
  3189. EC->bPrevFrameIntra = FALSE;
  3190. }
  3191. // RTP stuff which needs to be done for every frame (?)
  3192. if (pConfiguration->bEncoderResiliency && pConfiguration->unPacketLoss)
  3193. { //Chad intra GOB
  3194. // Of course unPacketLoss is non-zero. Why are we checking it here
  3195. if (pConfiguration->unPacketLoss > 0)
  3196. { //Chad INTRA GOB
  3197. EC->uNumberForcedIntraMBs = ((EC->NumMBs * pConfiguration->unPacketLoss) + 50) / 100;
  3198. EC->uNumberForcedIntraMBs = (EC->uNumberForcedIntraMBs+EC->NumMBPerRow-1) / EC->NumMBPerRow * EC->NumMBPerRow;
  3199. }
  3200. if (EC->uNumberForcedIntraMBs > 0)
  3201. {
  3202. /* Force all the MBs in a GOB to intra.
  3203. */
  3204. for ( i = 0 ; i < EC->uNumberForcedIntraMBs ; i++, EC->uNextIntraMB++)
  3205. { // Reset it to the first row when we reach the end.
  3206. if (EC->uNextIntraMB >= EC->NumMBs)
  3207. {
  3208. EC->uNextIntraMB = 0;
  3209. }
  3210. (EC->pU8_MBlockActionStream[EC->uNextIntraMB]).FirstMEState = ForceIntra;
  3211. }
  3212. }
  3213. if (pConfiguration->bDisallowAllVerMVs)
  3214. {
  3215. /* Walk thru all the FirstMEStateME settings turning off Vertical.
  3216. */
  3217. for(i=0; i < EC->NumMBs; i++)
  3218. {
  3219. u8FirstMEState = (EC->pU8_MBlockActionStream[i]).FirstMEState;
  3220. switch (u8FirstMEState)
  3221. {
  3222. case ForceIntra:
  3223. break;
  3224. case UpperLeft:
  3225. case LeftEdge:
  3226. case LowerLeft:
  3227. u8FirstMEState = NoVertLeftEdge;
  3228. break;
  3229. case UpperEdge:
  3230. case CentralBlock:
  3231. case LowerEdge:
  3232. u8FirstMEState = NoVertCentralBlock;
  3233. break;
  3234. case UpperRight:
  3235. case RightEdge:
  3236. case LowerRight:
  3237. u8FirstMEState = NoVertRightEdge;
  3238. break;
  3239. case NoVertLeftEdge:
  3240. case NoVertCentralBlock:
  3241. case NoVertRightEdge:
  3242. ASSERT(0); /* It should work, but why was this already on */
  3243. break;
  3244. default:
  3245. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Warning: Unexpected FirstMEState\r\n", _fx_));
  3246. break;
  3247. }
  3248. (EC->pU8_MBlockActionStream[i]).FirstMEState = u8FirstMEState;
  3249. }
  3250. }
  3251. else if (pConfiguration->bDisallowPosVerMVs)
  3252. { /* Walk thru all the FirstMEState settings turning off Positive Vertical
  3253. */
  3254. for(i=0; i < EC->NumMBs; i++)
  3255. {
  3256. u8FirstMEState = (EC->pU8_MBlockActionStream[i]).FirstMEState;
  3257. switch (u8FirstMEState)
  3258. {
  3259. case ForceIntra:
  3260. case LowerLeft:
  3261. case LowerEdge:
  3262. case LowerRight:
  3263. break;
  3264. case UpperLeft:
  3265. u8FirstMEState = NoVertLeftEdge;
  3266. break;
  3267. case LeftEdge:
  3268. u8FirstMEState = LowerLeft;
  3269. break;
  3270. case UpperEdge:
  3271. u8FirstMEState = NoVertCentralBlock;
  3272. break;
  3273. case CentralBlock:
  3274. u8FirstMEState = LowerEdge;
  3275. break;
  3276. case UpperRight:
  3277. u8FirstMEState = NoVertRightEdge;
  3278. break;
  3279. case RightEdge:
  3280. u8FirstMEState = LowerRight;
  3281. break;
  3282. case NoVertLeftEdge:
  3283. case NoVertCentralBlock:
  3284. case NoVertRightEdge:
  3285. ASSERT(0); /* It should work, but why was this already on */
  3286. break;
  3287. default:
  3288. DEBUGMSG(ZONE_ENCODE_DETAILS, ("%s: Warning: Unexpected FirstMEState\r\n", _fx_));
  3289. break;
  3290. }
  3291. (EC->pU8_MBlockActionStream[i]).FirstMEState = u8FirstMEState;
  3292. } /* for */
  3293. } /* else if... */
  3294. } /* if (pConfiguration->bEncoderResiliency) */
  3295. } // end of InitMEState()
  3296. #ifdef USE_MMX // { USE_MMX
  3297. /*************************************************************
  3298. * Name: Check_InterCodeCnt_MMX
  3299. * Description: Track inter code count for macro blocks
  3300. * for forced update. Called before Motion
  3301. * Estimation.
  3302. ************************************************************/
  3303. static void Check_InterCodeCnt_MMX(T_H263EncoderCatalog *EC, U32 StartingMB)
  3304. {
  3305. register T_MBlockActionStream *pCurrMB;
  3306. T_MBlockActionStream *pLastMBPlus1;
  3307. pCurrMB = &(EC->pU8_MBlockActionStream[StartingMB]);
  3308. pLastMBPlus1 = &(EC->pU8_MBlockActionStream[StartingMB + EC->NumMBPerRow]);
  3309. for(; pCurrMB < pLastMBPlus1; pCurrMB++, StartingMB++)
  3310. {
  3311. // Check to see if it's time to refresh this block.
  3312. if(pCurrMB->InterCodeCnt > 132)
  3313. {
  3314. pCurrMB->CodedBlocks |= 0x80;
  3315. // InterCodeCnt is reset in GOB_VLC_WriteBS() in e3mbenc.cpp */
  3316. }
  3317. }
  3318. }
  3319. #endif // } USE_MMX
  3320. /*************************************************************
  3321. * Name: Check_InterCodeCnt
  3322. * Description: Track inter code count for macro blocks
  3323. * for forced update. Called after Motion
  3324. * Estimation.
  3325. ************************************************************/
  3326. static void Check_InterCodeCnt(T_H263EncoderCatalog *EC, U32 StartingMB)
  3327. {
  3328. register T_MBlockActionStream *pCurrMB;
  3329. T_MBlockActionStream *pLastMBPlus1;
  3330. pCurrMB = &(EC->pU8_MBlockActionStream[StartingMB]);
  3331. pLastMBPlus1 = &(EC->pU8_MBlockActionStream[StartingMB + EC->NumMBPerRow]);
  3332. for(; pCurrMB < pLastMBPlus1; pCurrMB++, StartingMB++)
  3333. {
  3334. // Check to see if it's time to refresh this block.
  3335. if(pCurrMB->InterCodeCnt > 132)
  3336. {
  3337. if (pCurrMB->BlockType == INTER4MV)
  3338. {
  3339. pCurrMB->BlkY1.PHMV = pCurrMB->BlkY2.PHMV = pCurrMB->BlkY3.PHMV = pCurrMB->BlkY4.PHMV =
  3340. (pCurrMB->BlkY1.PHMV+pCurrMB->BlkY2.PHMV+pCurrMB->BlkY3.PHMV+pCurrMB->BlkY4.PHMV+2) >> 2;
  3341. pCurrMB->BlkY1.PVMV = pCurrMB->BlkY2.PVMV = pCurrMB->BlkY3.PVMV = pCurrMB->BlkY4.PVMV =
  3342. (pCurrMB->BlkY1.PVMV+pCurrMB->BlkY2.PVMV+pCurrMB->BlkY3.PVMV+pCurrMB->BlkY4.PVMV+2) >> 2;
  3343. }
  3344. pCurrMB->BlockType = INTRABLOCK;
  3345. pCurrMB->CodedBlocks |= 0x3f;
  3346. // InterCodeCnt is reset in GOB_Q_VLC_WriteBS() in e3mbenc.cpp */
  3347. }
  3348. }
  3349. }
  3350. /*************************************************************
  3351. * Name: calcGOBChromaVectors
  3352. * Description: Compute chroma motion vectors
  3353. ************************************************************/
  3354. static void calcGOBChromaVectors(
  3355. T_H263EncoderCatalog *EC,
  3356. U32 StartingMB,
  3357. T_CONFIGURATION *pConfiguration
  3358. )
  3359. {
  3360. register T_MBlockActionStream *pCurrMB;
  3361. T_MBlockActionStream *pLastMBPlus1;
  3362. char HMV, VMV;
  3363. pCurrMB = &(EC->pU8_MBlockActionStream[StartingMB]);
  3364. pLastMBPlus1 = &(EC->pU8_MBlockActionStream[StartingMB + EC->NumMBPerRow]);
  3365. for( ; pCurrMB < pLastMBPlus1; pCurrMB++, StartingMB++)
  3366. {
  3367. // The ME should generate MV indices in the range
  3368. // of [-32,31].
  3369. // ASSERT( (pCurrMB->BlkY1.PHMV >= -32) &&
  3370. // (pCurrMB->BlkY1.PHMV <= 31) )
  3371. // ASSERT( (pCurrMB->BlkY1.PVMV >= -32) &&
  3372. // (pCurrMB->BlkY1.PVMV <= 31) )
  3373. // ASSERT( (pCurrMB->BlkY2.PHMV >= -32) &&
  3374. // (pCurrMB->BlkY2.PHMV <= 31) )
  3375. // ASSERT( (pCurrMB->BlkY2.PVMV >= -32) &&
  3376. // (pCurrMB->BlkY2.PVMV <= 31) )
  3377. // ASSERT( (pCurrMB->BlkY3.PHMV >= -32) &&
  3378. // (pCurrMB->BlkY3.PHMV <= 31) )
  3379. // ASSERT( (pCurrMB->BlkY3.PVMV >= -32) &&
  3380. // (pCurrMB->BlkY3.PVMV <= 31) )
  3381. // ASSERT( (pCurrMB->BlkY4.PHMV >= -32) &&
  3382. // (pCurrMB->BlkY4.PHMV <= 31) )
  3383. // ASSERT( (pCurrMB->BlkY4.PVMV >= -32) &&
  3384. // (pCurrMB->BlkY4.PVMV <= 31) )
  3385. #ifdef _DEBUG
  3386. if (pConfiguration->bEncoderResiliency && pConfiguration->unPacketLoss)
  3387. {
  3388. if (pConfiguration->bDisallowAllVerMVs)
  3389. {
  3390. ASSERT(pCurrMB->BlkY1.PVMV == 0);
  3391. ASSERT(pCurrMB->BlkY2.PVMV == 0);
  3392. ASSERT(pCurrMB->BlkY3.PVMV == 0);
  3393. ASSERT(pCurrMB->BlkY4.PVMV == 0);
  3394. }
  3395. else if (pConfiguration->bDisallowPosVerMVs)
  3396. {
  3397. ASSERT(pCurrMB->BlkY1.PVMV <= 0);
  3398. ASSERT(pCurrMB->BlkY2.PVMV <= 0);
  3399. ASSERT(pCurrMB->BlkY3.PVMV <= 0);
  3400. ASSERT(pCurrMB->BlkY4.PVMV <= 0);
  3401. }
  3402. }
  3403. #endif /* _DEBUG */
  3404. // TODO: Don't calculate chroma vectors if this is not a P-frame
  3405. // inside a PB frame and it's an INTRA MB or inter code count
  3406. // exceeded 132.
  3407. if(pCurrMB->BlockType != INTER4MV)
  3408. {
  3409. HMV = QtrPelToHalfPel[pCurrMB->BlkY1.PHMV+64];
  3410. VMV = QtrPelToHalfPel[pCurrMB->BlkY1.PVMV+64];
  3411. }
  3412. else // 4 MV's per block.
  3413. {
  3414. HMV = SixteenthPelToHalfPel[
  3415. pCurrMB->BlkY1.PHMV + pCurrMB->BlkY2.PHMV +
  3416. pCurrMB->BlkY3.PHMV + pCurrMB->BlkY4.PHMV + 256 ];
  3417. VMV = SixteenthPelToHalfPel[
  3418. pCurrMB->BlkY1.PVMV + pCurrMB->BlkY2.PVMV +
  3419. pCurrMB->BlkY3.PVMV + pCurrMB->BlkY4.PVMV + 256 ];
  3420. }
  3421. pCurrMB->BlkU.PHMV = HMV;
  3422. pCurrMB->BlkU.PVMV = VMV;
  3423. pCurrMB->BlkV.PHMV = HMV;
  3424. pCurrMB->BlkV.PVMV = VMV;
  3425. pCurrMB->BlkU.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + pCurrMB->BlkU.BlkOffset
  3426. + (VMV>>1)*PITCH + (HMV>>1);
  3427. pCurrMB->BlkV.B4_7.PastRef = EC->pU8_PrevFrm_YPlane + pCurrMB->BlkV.BlkOffset
  3428. + (VMV>>1)*PITCH + (HMV>>1);
  3429. // The increment of pCurrMB->InterCodeCnt is now done
  3430. // in void GOB_VLC_WriteBS and void GOB_Q_RLE_VLC_WriteBS
  3431. // When it was incremented here, it was always incremented,
  3432. // no matter whether coefficients were coded or not.
  3433. } // end of for loop
  3434. } // end of
  3435. /*************************************************************
  3436. * Name: calcBGOBChromaVectors
  3437. * Description: Compute forward and backward chroma motion vectors for the
  3438. * B-frame GOB starting at MB number "StartingMB". Luma motion
  3439. * vectors are biased by 0x60. Chroma motion vectors are also
  3440. * biased by 0x60.
  3441. ************************************************************/
  3442. static void calcBGOBChromaVectors(
  3443. T_H263EncoderCatalog *EC,
  3444. const U32 StartingMB
  3445. )
  3446. {
  3447. register T_MBlockActionStream *pCurrMB;
  3448. register I8 HMVf, HMVb, VMVf, VMVb;
  3449. for(pCurrMB = &(EC->pU8_MBlockActionStream[StartingMB]);
  3450. pCurrMB < &(EC->pU8_MBlockActionStream[StartingMB + EC->NumMBPerRow]);
  3451. pCurrMB++)
  3452. {
  3453. // Luma block motion vectors
  3454. HMVf = QtrPelToHalfPel[pCurrMB->BlkY1.BestMV.HMVf-0x60+64]+0x60;
  3455. HMVb = QtrPelToHalfPel[pCurrMB->BlkY1.BestMV.HMVb-0x60+64]+0x60;
  3456. VMVf = QtrPelToHalfPel[pCurrMB->BlkY1.BestMV.VMVf-0x60+64]+0x60;
  3457. VMVb = QtrPelToHalfPel[pCurrMB->BlkY1.BestMV.VMVb-0x60+64]+0x60;
  3458. pCurrMB->BlkU.BestMV.HMVf = HMVf;
  3459. pCurrMB->BlkU.BestMV.HMVb = HMVb;
  3460. pCurrMB->BlkU.BestMV.VMVf = VMVf;
  3461. pCurrMB->BlkU.BestMV.VMVb = VMVb;
  3462. pCurrMB->BlkV.BestMV.HMVf = HMVf;
  3463. pCurrMB->BlkV.BestMV.HMVb = HMVb;
  3464. pCurrMB->BlkV.BestMV.VMVf = VMVf;
  3465. pCurrMB->BlkV.BestMV.VMVb = VMVb;
  3466. }
  3467. }
  3468. /*************************************************************
  3469. * Name: InitBits
  3470. ************************************************************/
  3471. #ifdef COUNT_BITS
  3472. static void InitBits(T_H263EncoderCatalog * EC)
  3473. {
  3474. EC->Bits.PictureHeader = 0;
  3475. EC->Bits.GOBHeader = 0;
  3476. EC->Bits.MBHeader = 0;
  3477. EC->Bits.DQUANT = 0;
  3478. EC->Bits.MV = 0;
  3479. EC->Bits.Coefs = 0;
  3480. EC->Bits.Coefs_Y = 0;
  3481. EC->Bits.IntraDC_Y = 0;
  3482. EC->Bits.Coefs_C = 0;
  3483. EC->Bits.IntraDC_C = 0;
  3484. EC->Bits.CBPY = 0;
  3485. EC->Bits.MCBPC = 0;
  3486. EC->Bits.Coded = 0;
  3487. EC->Bits.num_intra = 0;
  3488. EC->Bits.num_inter = 0;
  3489. EC->Bits.num_inter4v = 0;
  3490. }
  3491. #endif
  3492. #ifdef COUNT_BITS
  3493. void InitCountBitFile()
  3494. {
  3495. FILE *fp;
  3496. fp = fopen("bits.txt", "w");
  3497. ASSERT(fp != NULL);
  3498. fclose(fp);
  3499. }
  3500. void WriteCountBitFile(T_BitCounts *Bits)
  3501. {
  3502. FILE *fp;
  3503. fp = fopen("bits.txt", "a");
  3504. ASSERT(fp != NULL);
  3505. fprintf(fp, "%8d %8d %8d %8d %8d %8d %8d\n",
  3506. Bits->PictureHeader,
  3507. Bits->GOBHeader,
  3508. Bits->MBHeader,
  3509. Bits->MV,
  3510. Bits->Coefs,
  3511. Bits->CBPY,
  3512. Bits->MCBPC
  3513. );
  3514. fclose(fp);
  3515. }
  3516. #endif
  3517. #ifdef DEBUG_ENC
  3518. void trace(char *str)
  3519. {
  3520. FILE *fp;
  3521. fp = fopen("trace.txt", "a");
  3522. fprintf(fp, "%s\n", str);
  3523. fclose(fp);
  3524. }
  3525. #endif
  3526. #ifdef DEBUG_DCT
  3527. void cnvt_fdct_output(unsigned short *DCTcoeff, int DCTarray[64], int BlockType)
  3528. {
  3529. register int i;
  3530. static int coefforder[64] = {
  3531. // 0 1 2 3 4 5 6 7
  3532. 6,38, 4,36,70,100,68,102, // 0
  3533. 10,46, 8,44,74,104,72,106, // 1
  3534. 18,50,16,48,82,112,80,114, // 2
  3535. 14,42,12,40,78,108,76,110, // 3
  3536. 22,54,20,52,86,116,84,118, // 4
  3537. 2,34, 0,32,66, 96,64, 98, // 5
  3538. 26,58,24,56,90,120,88,122, // 6
  3539. 30,62,28,60,94,124,92,126 // 7
  3540. };
  3541. static int zigzag[64] = {
  3542. 0, 1, 5, 6, 14, 15, 27, 28,
  3543. 2, 4, 7, 13, 16, 26, 29, 42,
  3544. 3, 8, 12, 17, 25, 30, 41, 43,
  3545. 9, 11, 18, 24, 31, 40, 44, 53,
  3546. 10, 19, 23, 32, 39, 45, 52, 54,
  3547. 20, 22, 33, 38, 46, 51, 55, 60,
  3548. 21, 34, 37, 47, 50, 56, 59, 61,
  3549. 35, 36, 48, 49, 57, 58, 62, 63
  3550. };
  3551. unsigned int index;
  3552. for (i = 0; i < 64; i++) {
  3553. index = (coefforder[i])>>1;
  3554. if( (i ==0) && ((BlockType & 1) == 1) )
  3555. DCTarray[zigzag[i]] = ((int)(DCTcoeff[index])) >> 4 ;
  3556. else
  3557. DCTarray[zigzag[i]] = ((int)(DCTcoeff[index] - 0x8000)) >> 4;
  3558. }
  3559. }
  3560. #endif
  3561. #ifdef LOG_ENCODE_TIMINGS_ON // { LOG_ENCODE_TIMINGS_ON
  3562. void OutputEncodeTimingStatistics(char * szFileName, ENC_TIMING_INFO * pEncTimingInfo)
  3563. {
  3564. FILE * pFile;
  3565. ENC_TIMING_INFO * pTempEncTimingInfo;
  3566. ENC_TIMING_INFO etiTemp;
  3567. int i;
  3568. int iCount;
  3569. FX_ENTRY("OutputEncodeTimingStatistics")
  3570. pFile = fopen(szFileName, "a");
  3571. if (pFile == NULL)
  3572. {
  3573. ERRORMESSAGE(("%s: Error opening encode stat file\r\n", _fx_));
  3574. goto done;
  3575. }
  3576. /* Output the detail information
  3577. */
  3578. fprintf(pFile,"\nDetail Timing Information\n");
  3579. for ( i = 0, pTempEncTimingInfo = pEncTimingInfo ; i < ENC_TIMING_INFO_FRAME_COUNT ; i++, pTempEncTimingInfo++ )
  3580. {
  3581. fprintf(pFile, "Frame %d Detail Timing Information\n", i);
  3582. OutputEncTimingDetail(pFile, pTempEncTimingInfo);
  3583. }
  3584. /* Compute the total information
  3585. */
  3586. memset(&etiTemp, 0, sizeof(ENC_TIMING_INFO));
  3587. iCount = 0;
  3588. for ( i = 0, pTempEncTimingInfo = pEncTimingInfo ; i < ENC_TIMING_INFO_FRAME_COUNT ; i++, pTempEncTimingInfo++ )
  3589. {
  3590. iCount++;
  3591. etiTemp.uEncodeFrame += pTempEncTimingInfo->uEncodeFrame;
  3592. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  3593. etiTemp.uInputCC += pTempEncTimingInfo->uInputCC;
  3594. etiTemp.uMotionEstimation += pTempEncTimingInfo->uMotionEstimation;
  3595. etiTemp.uFDCT += pTempEncTimingInfo->uFDCT;
  3596. etiTemp.uQRLE += pTempEncTimingInfo->uQRLE;
  3597. etiTemp.uDecodeFrame += pTempEncTimingInfo->uDecodeFrame;
  3598. etiTemp.uZeroingBuffer += pTempEncTimingInfo->uZeroingBuffer;
  3599. #endif // } DETAILED_ENCODE_TIMINGS_ON
  3600. }
  3601. if (iCount > 0)
  3602. {
  3603. /* Output the total information
  3604. */
  3605. fprintf(pFile,"Total for %d frames\n", iCount);
  3606. OutputEncTimingDetail(pFile, &etiTemp);
  3607. /* Compute the average
  3608. */
  3609. etiTemp.uEncodeFrame = (etiTemp.uEncodeFrame + (iCount / 2)) / iCount;
  3610. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  3611. etiTemp.uInputCC = (etiTemp.uInputCC + (iCount / 2)) / iCount;
  3612. etiTemp.uMotionEstimation = (etiTemp.uMotionEstimation + (iCount / 2)) / iCount;
  3613. etiTemp.uFDCT = (etiTemp.uFDCT + (iCount / 2)) / iCount;
  3614. etiTemp.uQRLE = (etiTemp.uQRLE + (iCount / 2)) / iCount;
  3615. etiTemp.uDecodeFrame = (etiTemp.uDecodeFrame + (iCount / 2)) / iCount;
  3616. etiTemp.uZeroingBuffer = (etiTemp.uZeroingBuffer + (iCount / 2)) / iCount;
  3617. #endif // } DETAILED_ENCODE_TIMINGS_ON
  3618. /* Output the average information
  3619. */
  3620. fprintf(pFile,"Average over %d frames\n", iCount);
  3621. OutputEncTimingDetail(pFile, &etiTemp);
  3622. }
  3623. fclose(pFile);
  3624. done:
  3625. return;
  3626. }
  3627. void OutputEncTimingDetail(FILE * pFile, ENC_TIMING_INFO * pEncTimingInfo)
  3628. {
  3629. U32 uOther;
  3630. U32 uRoundUp;
  3631. U32 uDivisor;
  3632. fprintf(pFile, "\tEncode Frame = %10d (%d milliseconds at 90Mhz)\n", pEncTimingInfo->uEncodeFrame,
  3633. (pEncTimingInfo->uEncodeFrame + 45000) / 90000);
  3634. uOther = pEncTimingInfo->uEncodeFrame;
  3635. #ifdef DETAILED_ENCODE_TIMINGS_ON // { DETAILED_ENCODE_TIMINGS_ON
  3636. /* This is needed because of the integer truncation.
  3637. */
  3638. uDivisor = pEncTimingInfo->uEncodeFrame / 100; // to yield a percent
  3639. uRoundUp = uDivisor / 2;
  3640. fprintf(pFile, "\tInputCC = %10d (%2d%%)\n", pEncTimingInfo->uInputCC,
  3641. (pEncTimingInfo->uInputCC + uRoundUp) / uDivisor);
  3642. uOther -= pEncTimingInfo->uInputCC;
  3643. fprintf(pFile, "\tMotionEstimation = %10d (%2d%%)\n", pEncTimingInfo->uMotionEstimation,
  3644. (pEncTimingInfo->uMotionEstimation + uRoundUp) / uDivisor);
  3645. uOther -= pEncTimingInfo->uMotionEstimation;
  3646. fprintf(pFile, "\tFDCT = %10d (%2d%%)\n", pEncTimingInfo->uFDCT,
  3647. (pEncTimingInfo->uFDCT + uRoundUp) / uDivisor);
  3648. uOther -= pEncTimingInfo->uFDCT;
  3649. fprintf(pFile, "\tQRLE = %10d (%2d%%)\n", pEncTimingInfo->uQRLE,
  3650. (pEncTimingInfo->uQRLE + uRoundUp) / uDivisor);
  3651. uOther -= pEncTimingInfo->uQRLE;
  3652. fprintf(pFile, "\tDecodeFrame = %10d (%2d%%)\n", pEncTimingInfo->uDecodeFrame,
  3653. (pEncTimingInfo->uDecodeFrame + uRoundUp) / uDivisor);
  3654. uOther -= pEncTimingInfo->uDecodeFrame;
  3655. fprintf(pFile, "\tZeroingBuffer = %10d (%2d%%)\n", pEncTimingInfo->uZeroingBuffer,
  3656. (pEncTimingInfo->uZeroingBuffer + uRoundUp) / uDivisor);
  3657. uOther -= pEncTimingInfo->uZeroingBuffer;
  3658. fprintf(pFile, "\tOther = %10d (%2d%%)\n", uOther,
  3659. (uOther + uRoundUp) / uDivisor);
  3660. #endif // } DETAILED_ENCODE_TIMINGS_ON
  3661. }
  3662. #endif // { LOG_ENCODE_TIMINGS_ON