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.

982 lines
32 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1996 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. //
  15. ////////////////////////////////////////////////////////////////////////////
  16. //
  17. // $Author: mbodart $
  18. // $Date: 17 Mar 1997 08:22:08 $
  19. // $Archive: S:\h26x\src\enc\exbase.cpv $
  20. // $Header: S:\h26x\src\enc\exbase.cpv 1.73 17 Mar 1997 08:22:08 mbodart $
  21. // $Log: S:\h26x\src\enc\exbase.cpv $
  22. //
  23. // Rev 1.73 17 Mar 1997 08:22:08 mbodart
  24. // Minor fixes.
  25. //
  26. // Rev 1.72 11 Mar 1997 13:46:46 JMCVEIGH
  27. // Allow input = 320x240 and output = 320x240 for YUV12. This is
  28. // for snapshot mode.
  29. //
  30. // Rev 1.71 10 Mar 1997 17:34:34 MDUDA
  31. // Put in a check for 9-bit YUV12 and adjusted the internal compress
  32. // structure instead of the input bitmap header info.
  33. //
  34. // Rev 1.70 10 Mar 1997 10:41:20 MDUDA
  35. // Treating inconsistent format/bitwidth as a debug warning. Changing
  36. // bit count to match format.
  37. //
  38. // Rev 1.69 07 Mar 1997 16:00:32 JMCVEIGH
  39. // Added checks for non-NULL lpInst before getting H263PlusState.
  40. // Two separate "suggestions" for image sizes if input size is not
  41. // supported in GetFormat.
  42. //
  43. // Rev 1.68 07 Mar 1997 11:55:44 JMCVEIGH
  44. // Moved query in GetFormat to after we have filled out the output
  45. // format. This is because some apps. will ask for the format and
  46. // then use the returned data, regardless if there was an error.
  47. // Silly apps!
  48. //
  49. // Rev 1.67 07 Mar 1997 09:53:08 mbodart
  50. // Added a call to _clearfp() in the Compress exception handler, so that
  51. // the exception will not reoccur in the caller's code.
  52. //
  53. // Rev 1.66 06 Mar 1997 15:39:26 KLILLEVO
  54. //
  55. // CompressQuery now checks for input/output formats regardless
  56. // of configuration status. Also put in trace support for lparam1 and lparam2.
  57. //
  58. // Rev 1.65 22 Jan 1997 12:17:14 MDUDA
  59. //
  60. // Put in more checking for H263+ option in CompressQuery
  61. // and CompressBegin.
  62. //
  63. // Rev 1.64 22 Jan 1997 08:11:22 JMCVEIGH
  64. // Backward compatibility with crop/stretch for 160x120 and 240x180
  65. // in CompressGetFormat(). Do old way unless we have received the
  66. // H263Plus custom message.
  67. //
  68. // Rev 1.63 13 Jan 1997 10:52:14 JMCVEIGH
  69. //
  70. // Added NULL pointer checks in all functions that interface with
  71. // application.
  72. //
  73. // Rev 1.62 09 Jan 1997 13:50:50 MDUDA
  74. // Removed some _CODEC_STATS stuff.
  75. //
  76. // Rev 1.61 06 Jan 1997 17:42:30 JMCVEIGH
  77. // If H263Plus message is not sent, encoder only supports standard
  78. // frame sizes (sub-QCIF, QCIF, or CIF along with special cases),
  79. // as before.
  80. //
  81. // Rev 1.60 30 Dec 1996 19:57:04 MDUDA
  82. // Making sure that input formats agree with the bit count field.
  83. //
  84. // Rev 1.59 20 Dec 1996 15:25:28 MDUDA
  85. // Fixed problem where YUV12 was enabled for crop and stretch.
  86. // This feature is only allowed for RGB, YVU9 and YUY2.
  87. //
  88. // Rev 1.58 16 Dec 1996 13:36:08 MDUDA
  89. //
  90. // Modified Compress Instance info for input color convertors.
  91. //
  92. // Rev 1.57 11 Dec 1996 16:01:20 MBODART
  93. // In Compress, catch any exceptions and return an error code. This gives
  94. // upstream active movie filters a chance to recover gracefully.
  95. //
  96. // Rev 1.56 09 Dec 1996 17:59:36 JMCVEIGH
  97. // Added support for arbitrary frame size support.
  98. // 4 <= width <= 352, 4 <= height <= 288, both multiples of 4.
  99. // Normally, application will pass identical (arbitrary) frame
  100. // sizes in lParam1 and lParam2 of CompressBegin(). If
  101. // cropping/stretching desired to convert to standard frame sizes,
  102. // application should pass the desired output size in lParam2 and
  103. // the input size in lParam1.
  104. //
  105. // Rev 1.55 09 Dec 1996 09:50:12 MDUDA
  106. //
  107. // Allowing 240x180 and 160x120 (crop and stretch) for YUY2.
  108. // Modified _CODEC_STATS stuff.
  109. //
  110. // Rev 1.54 07 Nov 1996 14:45:16 RHAZRA
  111. // Added buffer size adjustment to H.261 CompressGetSize() function
  112. //
  113. // Rev 1.53 31 Oct 1996 22:33:32 BECHOLS
  114. // Decided buffer arbitration must be done in cxq_main.cpp for RTP.
  115. //
  116. // Rev 1.52 31 Oct 1996 21:55:50 BECHOLS
  117. // Added fudge factor for RTP waiting for Raj to decide what he wants to do.
  118. //
  119. // Rev 1.51 31 Oct 1996 10:05:46 KLILLEVO
  120. // changed from DBOUT to DbgLog
  121. //
  122. // Rev 1.50 18 Oct 1996 14:35:46 MDUDA
  123. //
  124. // Separated CompressGetSize and CompressQuery for H261 and H263 cases.
  125. //
  126. // Rev 1.49 11 Oct 1996 16:05:16 MDUDA
  127. //
  128. // Added initial _CODEC_STATS stuff.
  129. //
  130. // Rev 1.48 16 Sep 1996 16:50:52 CZHU
  131. // Return larger size for GetCompressedSize when RTP is enabled.
  132. //
  133. // Rev 1.47 13 Aug 1996 10:36:46 MDUDA
  134. //
  135. // Now allowing RGB4 input format.
  136. //
  137. // Rev 1.46 09 Aug 1996 09:43:30 MDUDA
  138. // Now allowing RGB16 format on input. This is generated by the color Quick Ca
  139. //
  140. // Rev 1.45 02 Aug 1996 13:45:58 MDUDA
  141. //
  142. // Went back to previous version that allows RGB8 and RGB24 in
  143. // 240x180 and 160x120 frames.
  144. //
  145. // Rev 1.44 01 Aug 1996 11:54:58 BECHOLS
  146. // Cut & Paste Error.
  147. //
  148. // Rev 1.43 01 Aug 1996 11:20:28 BECHOLS
  149. // Fixed handling of RGB 24 bit stuff so that it doesn't allow sizes other
  150. // than QCIF, SQCIF, or CIF. I broke this earlier when I added the RGB 8
  151. // bit support. ...
  152. //
  153. // Rev 1.42 22 Jul 1996 13:31:16 BECHOLS
  154. //
  155. // Added code to allow a CLUT8 input providing that the input resolutions
  156. // are either 240x180 or 160x120.
  157. //
  158. // Rev 1.41 11 Jul 1996 15:43:58 MDUDA
  159. // Added support for YVU9 240 x 180 and 160 x 120 for H263 only.
  160. // We now produce subQCIF for 160x120 and QCIF for 240x180.
  161. //
  162. // Rev 1.40 05 Jun 1996 10:57:54 AKASAI
  163. // Added #ifndef H261 in CompressQuery to make sure that H.261 will
  164. // only support FCIF and QCIF input image sizes. All other input sizes
  165. // should return ICERR_BADFORMAT.
  166. //
  167. // Rev 1.39 30 May 1996 17:02:34 RHAZRA
  168. // Added SQCIF support for H.263 in CompressGetSize()
  169. //
  170. // Rev 1.38 06 May 1996 12:47:40 BECHOLS
  171. // Changed the structure element to unBytesPerSecond.
  172. //
  173. // Rev 1.37 06 May 1996 00:09:44 BECHOLS
  174. // Changed the handling of the CompressFramesInfo message to get DataRate
  175. // from the configuration data if the configuration has the data, and
  176. // we haven't received a CompressBegin message yet.
  177. //
  178. // Rev 1.36 23 Apr 1996 16:51:20 KLILLEVO
  179. // moved paranthesis to fix format check in CompressQuery()
  180. //
  181. // Rev 1.35 18 Apr 1996 16:07:10 RHAZRA
  182. // Fixed CompressQuery to keep compiler happy for the non-MICROSOFT version
  183. //
  184. // Rev 1.34 18 Apr 1996 15:57:46 BECHOLS
  185. // RAJ- Changed the query logic to correctly filter the allowable resolutions
  186. // for compression.
  187. //
  188. // Rev 1.33 12 Apr 1996 14:15:40 RHAZRA
  189. // Added paranthesis in CompressGetSize() to make the ifdef case work
  190. //
  191. // Rev 1.32 12 Apr 1996 13:31:02 RHAZRA
  192. // Added SQCIF support in CompressGetSize() with #ifdef SUPPORT_SQCIF;
  193. // changed CompressGetSize() to return 0 if the input format is not
  194. // supported.
  195. //
  196. // Rev 1.31 10 Apr 1996 16:53:08 RHAZRA
  197. // Added a error return in CompressGetSize() to keep complier smiling...
  198. //
  199. // Rev 1.30 10 Apr 1996 16:39:56 RHAZRA
  200. // Added a check for the 320x240 size in CompressGetSize() function;
  201. // added a ifndef to disable certain sizes and compression formats.
  202. //
  203. // Rev 1.29 04 Apr 1996 13:35:00 RHAZRA
  204. // Changed CompressGetSize() to return spec-compliant buffer sizes.
  205. //
  206. // Rev 1.28 03 Apr 1996 08:39:52 SCDAY
  207. // Added H261 specific code to CompressGetSize to limit buffer size
  208. // as defined in H261 spec
  209. //
  210. // Rev 1.27 21 Feb 1996 11:43:12 SCDAY
  211. // cleaned up compiler build warning by changing conversion frlDataRate to (U3
  212. //
  213. // Rev 1.26 15 Feb 1996 16:03:36 RHAZRA
  214. //
  215. // Added a check for NULL lpInst pointer in CompressGetFormat()
  216. //
  217. // Rev 1.25 02 Feb 1996 18:53:46 TRGARDOS
  218. // Changed code to read frame rate from Compressor Instance
  219. // instead of the hack from Quality field.
  220. //
  221. // Rev 1.24 26 Jan 1996 09:35:32 TRGARDOS
  222. // Added #ifndef H261 for 160x120,320x240 support.
  223. //
  224. // Rev 1.23 04 Jan 1996 18:36:54 TRGARDOS
  225. // Added code to permit 320x240 input and then set a boolean
  226. // bIs320x240.
  227. //
  228. // Rev 1.22 27 Dec 1995 15:32:50 RMCKENZX
  229. // Added copyright notice
  230. //
  231. ///////////////////////////////////////////////////////////////////////////
  232. #include "precomp.h"
  233. #ifdef YUV9FROMFILE
  234. PAVIFILE paviFile;
  235. PAVISTREAM paviStream;
  236. U8 huge * glpTmp;
  237. HGLOBAL hgMem;
  238. #endif
  239. ;////////////////////////////////////////////////////////////////////////////
  240. ;// Function: DWORD PASCAL CompressGetFormat(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
  241. ;//
  242. ;// Description: Added header. This function returns a format that
  243. ;// we can deliver back to the caller.
  244. ;//
  245. ;// History: 05/11/94 -BEN-
  246. ;////////////////////////////////////////////////////////////////////////////
  247. DWORD PASCAL CompressGetFormat(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
  248. {
  249. DWORD dwQuery;
  250. // lpInst == NULL is OK
  251. // this is what you get on ICOpen(...,ICMODE_QUERY)
  252. #if 0
  253. if (lpInst == NULL) {
  254. DBOUT("CompressGetFormat: got a NULL lpInst pointer");
  255. return ((DWORD) ICERR_ERROR);
  256. }
  257. #endif
  258. if(dwQuery = CompressQuery(lpInst, lParam1, NULL)) {
  259. DBOUT("encbase.c :: CompressGetFormat :: ICERR_BADFORMAT")
  260. return(dwQuery);
  261. }
  262. if(lParam2 == NULL) {
  263. // he just want me to return the output buffer size.
  264. return ((DWORD)sizeof(BITMAPINFOHEADER));
  265. }
  266. // Check pointer
  267. if (!lParam1)
  268. return ICERR_ERROR;
  269. // give him back what he passed with our stuff in it
  270. #ifndef WIN32
  271. (void)_fmemcpy(lParam2, lParam1,sizeof(BITMAPINFOHEADER));
  272. #else
  273. (void)memcpy(lParam2, lParam1,sizeof(BITMAPINFOHEADER));
  274. #endif
  275. lParam2->biBitCount = 24;
  276. lParam2->biCompression = FOURCC_H263;
  277. #if defined(H263P)
  278. BOOL bH263PlusState = FALSE;
  279. if (lpInst)
  280. CustomGetH263PlusState(lpInst, (DWORD FAR *)&bH263PlusState);
  281. if (!bH263PlusState) {
  282. // For backward compatibility, make sure the crop and stretch cases are covered.
  283. if ( (lParam1->biCompression == FOURCC_YVU9) ||
  284. (lParam1->biCompression == FOURCC_YUY2) ||
  285. (lParam1->biCompression == FOURCC_UYVY) ||
  286. (lParam1->biCompression == FOURCC_YUV12) ||
  287. (lParam1->biCompression == FOURCC_IYUV) ||
  288. (lParam1->biCompression == BI_RGB) )
  289. {
  290. if ( (lParam1->biWidth == 240) && (lParam1->biHeight == 180) )
  291. {
  292. lParam2->biWidth = 176;
  293. lParam2->biHeight = 144;
  294. }
  295. if ( (lParam1->biWidth == 160) && (lParam1->biHeight == 120) )
  296. {
  297. lParam2->biWidth = 128;
  298. lParam2->biHeight = 96;
  299. }
  300. }
  301. }
  302. #else
  303. if ( (lParam1->biCompression == FOURCC_YVU9) ||
  304. (lParam1->biCompression == FOURCC_YUY2) ||
  305. (lParam1->biCompression == FOURCC_UYVY) ||
  306. (lParam1->biCompression == FOURCC_YUV12) ||
  307. (lParam1->biCompression == FOURCC_IYUV) ||
  308. (lParam1->biCompression == BI_RGB) )
  309. {
  310. if ( (lParam1->biWidth == 240) && (lParam1->biHeight == 180) )
  311. {
  312. lParam2->biWidth = 176;
  313. lParam2->biHeight = 144;
  314. }
  315. if ( (lParam1->biWidth == 160) && (lParam1->biHeight == 120) )
  316. {
  317. lParam2->biWidth = 128;
  318. lParam2->biHeight = 96;
  319. }
  320. }
  321. else
  322. {
  323. lParam2->biWidth = MOD4(lParam1->biWidth);
  324. lParam2->biHeight = MOD4(lParam1->biHeight);
  325. }
  326. #endif
  327. lParam2->biClrUsed = 0;
  328. lParam2->biClrImportant = 0;
  329. lParam2->biPlanes = 1;
  330. lParam2->biSizeImage = CompressGetSize(lpInst, lParam1, lParam2);
  331. return(ICERR_OK);
  332. }
  333. ;////////////////////////////////////////////////////////////////////////////
  334. ;// Function: DWORD PASCAL CompressGetSize(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
  335. ;//
  336. ;// Description: Added header. This function returns the maximum
  337. ;// size that a compressed buffer can be. This size is
  338. ;// guaranteed in encoder design.
  339. ;//
  340. ;// History: 05/11/94 -BEN-
  341. ;////////////////////////////////////////////////////////////////////////////
  342. #if defined(H261)
  343. DWORD PASCAL CompressGetSize(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
  344. {
  345. // RH: For QCIF and CIF, the maximum buffer sizes for 261 & 263 are identical.
  346. DWORD dwRet = 0;
  347. DWORD dwExtSize=0;
  348. if ( ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
  349. ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) ||
  350. ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) ) {
  351. dwRet = 8192L;
  352. } else
  353. if (((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ||
  354. ((lParam1->biWidth == 320) && (lParam1->biHeight == 240))) {
  355. dwRet = 32768L;
  356. }
  357. else // unsupported frame size; should not happen
  358. {
  359. DBOUT("CompressGetSize:ICERR_BADIMAGESIZE");
  360. dwRet = 0;
  361. }
  362. // Adjust the buffer size for RTP. Note that this adjustment will be performed
  363. // only if the codec has been told previously to use RTP and the RTP-related
  364. // information has been initialized. Therefore, the current (11/7) AM interface
  365. // will not take advantage of this routine.
  366. #if 0
  367. if (dwRet && lpInst && lpInst->Configuration.bRTPHeader && lpInst->Configuration.bInitialized)
  368. {
  369. dwRet += H261EstimateRTPOverhead(lpInst, lParam1);
  370. }
  371. #endif
  372. return dwRet;
  373. }
  374. #else
  375. /* H.263 case */
  376. DWORD PASCAL CompressGetSize(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
  377. {
  378. // RH: For QCIF and CIF, the maximum buffer sizes for 261 & 263 are identical.
  379. DWORD dwRet = 0;
  380. DWORD dwExtSize=0;
  381. if (lParam1 == NULL)
  382. {
  383. // We will use a size of zero to indicate an error for CompressGetSize
  384. dwRet = 0;
  385. return dwRet;
  386. }
  387. #ifndef H263P
  388. if (((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
  389. ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
  390. ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) ||
  391. ((lParam1->biWidth == 160) && (lParam1->biHeight == 120))) {
  392. dwRet = 8192L;
  393. } else
  394. if (((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ||
  395. ((lParam1->biWidth == 320) && (lParam1->biHeight == 240))) {
  396. dwRet = 32768L;
  397. }
  398. else // unsupported frame size; should not happen
  399. {
  400. DBOUT("CompressGetSize:ICERR_BADIMAGESIZE");
  401. dwRet = 0;
  402. }
  403. #else
  404. // H.263+
  405. U32 unPaddedWidth;
  406. U32 unPaddedHeight;
  407. U32 unSourceFormatSize;
  408. // Base buffer size on frame dimensions padded to multiples of 16
  409. if (lParam2 == NULL)
  410. {
  411. // In case an old application passed in a NULL pointer in lParam2,
  412. // we use the input frame dimensions to calculate the format size
  413. unPaddedWidth = (lParam1->biWidth + 0xf) & ~0xf;
  414. unPaddedHeight = (lParam1->biHeight + 0xf) & ~0xf;
  415. }
  416. else
  417. {
  418. unPaddedWidth = (lParam2->biWidth + 0xf) & ~0xf;
  419. unPaddedHeight = (lParam2->biHeight + 0xf) & ~0xf;
  420. }
  421. unSourceFormatSize = unPaddedWidth * unPaddedHeight;
  422. // See Table 1/H.263, document LBC-96-358
  423. if (unSourceFormatSize < 25348)
  424. dwRet = 8192L;
  425. else if (unSourceFormatSize < 101380)
  426. dwRet = 32768L;
  427. else if (unSourceFormatSize < 405508)
  428. dwRet = 65536L;
  429. else
  430. dwRet = 131072L;
  431. #endif
  432. //adjust if RTP is enabled, based on information in Configuration
  433. //Size calculated using DataRate, FrameRate in lpInst,
  434. //and lpInst->Configuration.unPacketSize;
  435. //Chad, 9/12/96
  436. #if 0
  437. if (dwRet && lpInst &&
  438. lpInst->Configuration.bRTPHeader && lpInst->Configuration.bInitialized)
  439. {
  440. dwRet += getRTPBsInfoSize(lpInst);
  441. }
  442. #endif
  443. return dwRet;
  444. }
  445. #endif
  446. ;////////////////////////////////////////////////////////////////////////////
  447. ;// Function: DWORD PASCAL CompressQuery(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
  448. ;//
  449. ;// Description:
  450. ;//
  451. ;// History: 05/11/94 -BEN-
  452. ;////////////////////////////////////////////////////////////////////////////
  453. #if defined(H261)
  454. DWORD PASCAL CompressQuery(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
  455. {
  456. // Check for good input format
  457. if(NULL == lParam1)
  458. {
  459. DBOUT("ICERR_BADFORMAT")
  460. return((DWORD)ICERR_BADFORMAT);
  461. }
  462. if( (lParam1->biCompression != BI_RGB) &&
  463. (lParam1->biCompression != FOURCC_YVU9) &&
  464. (lParam1->biCompression != FOURCC_YUV12) &&
  465. (lParam1->biCompression != FOURCC_IYUV) &&
  466. (lParam1->biCompression != FOURCC_UYVY) &&
  467. (lParam1->biCompression != FOURCC_YUY2) )
  468. {
  469. DBOUT("ICERR_BADFORMAT")
  470. return((DWORD)ICERR_BADFORMAT);
  471. }
  472. if( (lParam1->biCompression == BI_RGB) &&
  473. ( (lParam1->biBitCount != 24) &&
  474. (lParam1->biBitCount != 16) &&
  475. (lParam1->biBitCount != 8) &&
  476. (lParam1->biBitCount != 4) ) )
  477. {
  478. DBOUT("ICERR_BADFORMAT")
  479. return((DWORD)ICERR_BADFORMAT);
  480. }
  481. if(!
  482. ( ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
  483. ((lParam1->biWidth == 352) && (lParam1->biHeight == 288))
  484. #ifndef MICROSOFT
  485. ||
  486. ( ( (lParam1->biCompression == FOURCC_YVU9) ||
  487. (lParam1->biCompression == FOURCC_YUY2) ||
  488. (lParam1->biCompression == FOURCC_UYVY) ||
  489. (lParam1->biCompression == FOURCC_YUV12) ||
  490. (lParam1->biCompression == FOURCC_IYUV) ||
  491. (lParam1->biCompression == BI_RGB) )
  492. && ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) )
  493. ||
  494. ( ( (lParam1->biCompression == FOURCC_YVU9) ||
  495. (lParam1->biCompression == FOURCC_YUY2) ||
  496. (lParam1->biCompression == FOURCC_UYVY) ||
  497. (lParam1->biCompression == FOURCC_YUV12) ||
  498. (lParam1->biCompression == FOURCC_IYUV) ||
  499. (lParam1->biCompression == BI_RGB) )
  500. && ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) )
  501. ||
  502. ( ( (lParam1->biCompression == FOURCC_YUV12) || (lParam1->biCompression == FOURCC_IYUV) )
  503. && ((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) )
  504. #endif
  505. ))
  506. {
  507. DBOUT("ICERR_BADFORMAT")
  508. return((DWORD)ICERR_BADFORMAT);
  509. }
  510. if( lParam1->biPlanes != 1 )
  511. {
  512. DBOUT("ICERR_BADFORMAT")
  513. return((DWORD)ICERR_BADFORMAT);
  514. }
  515. if(0 == lParam2) // Checking input only
  516. return(ICERR_OK);
  517. // TODO: Do we want to check frame dimensions of output?
  518. if( lParam2->biCompression != FOURCC_H263 )
  519. {
  520. DBOUT("ICERR_BADFORMAT")
  521. return((DWORD)ICERR_BADFORMAT);
  522. }
  523. return(ICERR_OK);
  524. }
  525. #else
  526. /* H.263 case */
  527. DWORD PASCAL CompressQuery(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
  528. {
  529. #if defined(H263P)
  530. BOOL bH263PlusState = FALSE;
  531. if (lpInst)
  532. CustomGetH263PlusState(lpInst, (DWORD FAR *)&bH263PlusState);
  533. #endif
  534. // Check for good input format
  535. if(NULL == lParam1)
  536. {
  537. DBOUT("ICERR_BADFORMAT")
  538. return((DWORD)ICERR_BADFORMAT);
  539. }
  540. if( (lParam1->biCompression != BI_RGB) &&
  541. (lParam1->biCompression != FOURCC_YVU9) &&
  542. (lParam1->biCompression != FOURCC_YUV12) &&
  543. (lParam1->biCompression != FOURCC_IYUV) &&
  544. (lParam1->biCompression != FOURCC_YUY2) )
  545. {
  546. DBOUT("ICERR_BADFORMAT")
  547. return((DWORD)ICERR_BADFORMAT);
  548. }
  549. if( (lParam1->biCompression == BI_RGB) &&
  550. ( (lParam1->biBitCount != 24) &&
  551. #ifdef H263P
  552. (lParam1->biBitCount != 32) &&
  553. #endif
  554. (lParam1->biBitCount != 16) &&
  555. (lParam1->biBitCount != 8) &&
  556. (lParam1->biBitCount != 4) ) )
  557. {
  558. DBOUT("ICERR_BADFORMAT")
  559. return((DWORD)ICERR_BADFORMAT);
  560. }
  561. #ifndef H263P
  562. if(!
  563. ( ((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
  564. ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
  565. ((lParam1->biWidth == 352) && (lParam1->biHeight == 288))
  566. #ifndef MICROSOFT
  567. ||
  568. ( ( (lParam1->biCompression == FOURCC_YVU9) ||
  569. (lParam1->biCompression == FOURCC_YUY2) ||
  570. (lParam1->biCompression == BI_RGB) )
  571. && ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) )
  572. ||
  573. ( ( (lParam1->biCompression == FOURCC_YVU9) ||
  574. (lParam1->biCompression == FOURCC_YUY2) ||
  575. (lParam1->biCompression == BI_RGB) )
  576. && ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) )
  577. ||
  578. ( ( (lParam1->biCompression == FOURCC_YUV12) ||
  579. (lParam1->biCompression == FOURCC_IYUV) )
  580. && ((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) )
  581. #endif
  582. ))
  583. {
  584. DBOUT("ICERR_BADFORMAT")
  585. return((DWORD)ICERR_BADFORMAT);
  586. }
  587. #else
  588. if (((FOURCC_YVU9 == lParam1->biCompression) && (9 != lParam1->biBitCount)) ||
  589. ((FOURCC_YUY2 == lParam1->biCompression) && (16 != lParam1->biBitCount)) ||
  590. (((FOURCC_YUV12 == lParam1->biCompression) || (FOURCC_IYUV == lParam1->biCompression)) && (12 != lParam1->biBitCount)))
  591. {
  592. DBOUT("CompressQuery:Incorrect bit width (ICERR_BADFORMAT)");
  593. return((DWORD)ICERR_BADFORMAT);
  594. }
  595. // The H263+ message indicates whether arbitrary frame
  596. // sizes are to be supported. If arbitrary frames are needed,
  597. // the H263+ message must be sent before the first call to
  598. // CompressQuery.
  599. if (bH263PlusState) {
  600. if ((lParam1->biWidth & 0x3) || (lParam1->biHeight & 0x3) ||
  601. (lParam1->biWidth < 4) || (lParam1->biWidth > 352) ||
  602. (lParam1->biHeight < 4) || (lParam1->biHeight > 288)) {
  603. DBOUT("CompressQuery:ICERR_BADFORMAT");
  604. return((DWORD)ICERR_BADFORMAT);
  605. }
  606. } else {
  607. if(!
  608. ( ((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
  609. ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
  610. ((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ||
  611. ( ( (lParam1->biCompression == FOURCC_YVU9) ||
  612. (lParam1->biCompression == FOURCC_YUY2) ||
  613. (lParam1->biCompression == BI_RGB) )
  614. && ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) ) ||
  615. ( ( (lParam1->biCompression == FOURCC_YVU9) ||
  616. (lParam1->biCompression == FOURCC_YUY2) ||
  617. (lParam1->biCompression == BI_RGB) )
  618. && ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) ) ||
  619. ( ( (lParam1->biCompression == FOURCC_YUV12) || (lParam1->biCompression == FOURCC_IYUV))
  620. && ((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) ) ))
  621. {
  622. DBOUT("CompressQuery:ICERR_BADFORMAT");
  623. return((DWORD)ICERR_BADFORMAT);
  624. }
  625. }
  626. #endif
  627. if( lParam1->biPlanes != 1 )
  628. {
  629. DBOUT("ICERR_BADFORMAT")
  630. return((DWORD)ICERR_BADFORMAT);
  631. }
  632. if(lParam2 == 0) // Checking input only
  633. return(ICERR_OK);
  634. // TODO: Do we want to check frame dimensions of output?
  635. if( lParam2->biCompression != FOURCC_H263 )
  636. {
  637. DBOUT("ICERR_BADFORMAT")
  638. return((DWORD)ICERR_BADFORMAT);
  639. }
  640. #if defined(H263P)
  641. if (bH263PlusState) {
  642. if ((lParam1->biWidth != lParam2->biWidth) ||
  643. (lParam1->biHeight != lParam2->biHeight)) {
  644. DBOUT("CompressQuery:ICERR_BADFORMAT");
  645. return ((DWORD)ICERR_BADFORMAT);
  646. }
  647. } else {
  648. if(!
  649. (( ( ((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
  650. ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
  651. ((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ) &&
  652. (lParam1->biWidth == lParam2->biWidth) && (lParam1->biHeight == lParam2->biHeight) ) ||
  653. (((lParam1->biCompression == FOURCC_YVU9) ||
  654. (lParam1->biCompression == FOURCC_YUY2) ||
  655. (lParam1->biCompression == BI_RGB)) &&
  656. (((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) &&
  657. ((lParam2->biWidth == 128) && (lParam2->biHeight == 96)))) ||
  658. (((lParam1->biCompression == FOURCC_YVU9) ||
  659. (lParam1->biCompression == FOURCC_YUY2) ||
  660. (lParam1->biCompression == BI_RGB)) &&
  661. (((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) &&
  662. ((lParam2->biWidth == 176) && (lParam2->biHeight == 144)))) ||
  663. (((lParam1->biCompression == FOURCC_YUV12) || (lParam1->biCompression == FOURCC_IYUV)) &&
  664. (((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) &&
  665. ((lParam2->biWidth == 320) && (lParam2->biHeight == 240)))) ) )
  666. {
  667. DBOUT("CompressQuery:ICERR_BADFORMAT");
  668. return ((DWORD)ICERR_BADFORMAT);
  669. }
  670. }
  671. #endif
  672. return(ICERR_OK);
  673. }
  674. #endif
  675. ;////////////////////////////////////////////////////////////////////////////
  676. ;// Function: DWORD PASCAL CompressFramesInfo(LPCODINST, ICCOMPRESSFRAMES *);
  677. ;//
  678. ;// Description:
  679. ;//
  680. ;// History: 05/11/94 -BEN-
  681. ;////////////////////////////////////////////////////////////////////////////
  682. DWORD PASCAL CompressFramesInfo(LPCODINST lpCompInst, ICCOMPRESSFRAMES *lParam1, int lParam2)
  683. {
  684. FX_ENTRY("CompressFramesInfo");
  685. // Check to see if we are given a nonzero pointer.
  686. if (lpCompInst == NULL)
  687. {
  688. ERRORMESSAGE(("%s: CompressFramesInfo called with NULL parameter - returning ICERR_BADFORMAT", _fx_));
  689. return ((DWORD)ICERR_BADFORMAT);
  690. }
  691. // lParam2 should be the size of the structure.
  692. if (lParam2 != sizeof(ICCOMPRESSFRAMES))
  693. {
  694. ERRORMESSAGE(("%s: wrong size of ICOMPRESSFRAMES structure", _fx_));
  695. return ((DWORD)ICERR_BADFORMAT);
  696. }
  697. if (!lParam1 || (lParam1->dwScale == 0))
  698. {
  699. ERRORMESSAGE(("%s: dwScale is zero", _fx_));
  700. return ((DWORD)ICERR_BADFORMAT);
  701. }
  702. lpCompInst->FrameRate = (float)lParam1->dwRate / (float)lParam1->dwScale;
  703. lpCompInst->DataRate = (U32)lParam1->lDataRate;
  704. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Setting frame rate at %ld.%ld fps and bitrate at %ld bps", _fx_, (DWORD)lpCompInst->FrameRate, (DWORD)((lpCompInst->FrameRate - (float)(DWORD)lpCompInst->FrameRate) * 100.0f), lpCompInst->DataRate * 8UL));
  705. return ((DWORD)ICERR_OK);
  706. }
  707. ;////////////////////////////////////////////////////////////////////////////
  708. ;// Function: BOOL bIsOkRes(LPCODINST);
  709. ;//
  710. ;// Description: This function checks whether the desired height and
  711. ;// width are possible.
  712. ;//
  713. ;// History: 05/11/94 -BEN-
  714. ;////////////////////////////////////////////////////////////////////////////
  715. BOOL bIsOkRes(LPCODINST lpCompInst)
  716. {
  717. BOOL bRet;
  718. // Check for NULL pointer
  719. if (lpCompInst == NULL)
  720. return 0;
  721. bRet = lpCompInst->xres <= 352
  722. && lpCompInst->yres <= 288
  723. && lpCompInst->xres >= 4
  724. && lpCompInst->yres >= 4
  725. && (lpCompInst->xres & ~3) == lpCompInst->xres
  726. && (lpCompInst->yres & ~3) == lpCompInst->yres;
  727. return(bRet);
  728. }
  729. ;////////////////////////////////////////////////////////////////////////////
  730. ;// Function: DWORD PASCAL CompressBegin(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
  731. ;//
  732. ;// Description:
  733. ;//
  734. ;// History: 05/11/94 -BEN-
  735. ;////////////////////////////////////////////////////////////////////////////
  736. DWORD PASCAL CompressBegin(
  737. LPCODINST lpCompInst,
  738. LPBITMAPINFOHEADER lParam1,
  739. LPBITMAPINFOHEADER lParam2
  740. )
  741. {
  742. DWORD dwQuery;
  743. LRESULT retval;
  744. #if defined(H263P)
  745. BOOL bH263PlusState = FALSE;
  746. if (lpCompInst)
  747. CustomGetH263PlusState(lpCompInst, (DWORD FAR *)&bH263PlusState);
  748. #endif
  749. // Check input and output format.
  750. if( (dwQuery = CompressQuery(lpCompInst, lParam1, lParam2)) != ICERR_OK)
  751. return(dwQuery);
  752. // Check instance pointer
  753. if (!lpCompInst)
  754. return ICERR_ERROR;
  755. #ifdef H263P
  756. lpCompInst->InputCompression = lParam1->biCompression;
  757. lpCompInst->InputBitWidth = lParam1->biBitCount;
  758. if (((FOURCC_YUV12 == lParam1->biCompression) || (FOURCC_IYUV == lParam1->biCompression)) && (9 == lParam1->biBitCount)) {
  759. lpCompInst->InputBitWidth = 12;
  760. }
  761. if ( lParam2 && bH263PlusState)
  762. {
  763. // This is the "new" style for indicating if the input should
  764. // be cropped/stretched to a standard frame size.
  765. // Old applications may pass in NULL or junk for lparam2.
  766. // New applications should pass a valid lParam2 that indicates
  767. // the desired output frame size. Also, the H263Plus flag must
  768. // be set in the configuration structure before calling CompressBegin()
  769. lpCompInst->xres = (WORD)lParam2->biWidth;
  770. lpCompInst->yres = (WORD)lParam2->biHeight;
  771. } else
  772. #endif // H263P
  773. {
  774. lpCompInst->xres = (WORD)lParam1->biWidth;
  775. lpCompInst->yres = (WORD)lParam1->biHeight;
  776. lpCompInst->Is160x120 = FALSE;
  777. lpCompInst->Is240x180 = FALSE;
  778. lpCompInst->Is320x240 = FALSE;
  779. if ( (lParam1->biWidth == 160) && (lParam1->biHeight == 120) )
  780. {
  781. lpCompInst->xres = 128;
  782. lpCompInst->yres = 96;
  783. lpCompInst->Is160x120 = TRUE;
  784. }
  785. else if ( (lParam1->biWidth == 240) && (lParam1->biHeight == 180) )
  786. {
  787. lpCompInst->xres = 176;
  788. lpCompInst->yres = 144;
  789. lpCompInst->Is240x180 = TRUE;
  790. }
  791. else if ( (lParam1->biWidth == 320) && (lParam1->biHeight == 240) )
  792. {
  793. lpCompInst->xres = 352;
  794. lpCompInst->yres = 288;
  795. lpCompInst->Is320x240 = TRUE;
  796. }
  797. }
  798. if(!bIsOkRes(lpCompInst))
  799. return((DWORD)ICERR_BADIMAGESIZE);
  800. // Set frame size.
  801. if (lpCompInst->xres == 128 && lpCompInst->yres == 96)
  802. lpCompInst->FrameSz = SQCIF;
  803. else if (lpCompInst->xres == 176 && lpCompInst->yres == 144)
  804. lpCompInst->FrameSz = QCIF;
  805. else if (lpCompInst->xres == 352 && lpCompInst->yres == 288)
  806. lpCompInst->FrameSz = CIF;
  807. #ifdef H263P
  808. else
  809. lpCompInst->FrameSz = CUSTOM;
  810. #else
  811. else // unsupported frame size.
  812. return (DWORD)ICERR_BADIMAGESIZE;
  813. #endif
  814. // Allocate and Initialize tables and memory that are specific to
  815. // this instance.
  816. #if defined(H263P)
  817. retval = H263InitEncoderInstance(lParam1,lpCompInst);
  818. #else
  819. retval = H263InitEncoderInstance(lpCompInst);
  820. #endif
  821. return(retval);
  822. }
  823. ;////////////////////////////////////////////////////////////////////////////
  824. ;// Function: DWORD PASCAL CompressEnd(LPCODINST);
  825. ;//
  826. ;// Description:
  827. ;//
  828. ;// History: 05/11/94 -BEN-
  829. ;////////////////////////////////////////////////////////////////////////////
  830. DWORD PASCAL CompressEnd(LPCODINST lpInst)
  831. {
  832. LRESULT retval;
  833. retval = H263TermEncoderInstance(lpInst);
  834. return(retval);
  835. }
  836. ;////////////////////////////////////////////////////////////////////////////
  837. ;// Function: DWORD PASCAL Compress(LPCODINST, ICCOMPRESS FAR *, DWORD);
  838. ;//
  839. ;// Description:
  840. ;//
  841. ;// History: 05/11/94 -BEN-
  842. ;////////////////////////////////////////////////////////////////////////////
  843. DWORD PASCAL Compress(
  844. LPCODINST lpInst, // ptr to Compressor instance information.
  845. ICCOMPRESS FAR * lpCompInfo, // ptr to ICCOMPRESS structure.
  846. DWORD dOutbufSize // size, in bytes, of the ICCOMPRESS structure.
  847. )
  848. {
  849. DWORD dwRet;
  850. // Check to see if we are given a NULL pointer.
  851. if(lpInst == NULL || lpCompInfo == NULL)
  852. {
  853. DBOUT("Compress called with NULL parameter");;
  854. return( (DWORD) ICERR_ERROR );
  855. }
  856. try
  857. {
  858. dwRet = H263Compress(lpInst, lpCompInfo);
  859. }
  860. catch (...)
  861. {
  862. // For a DEBUG build, display a message and pass the exception up.
  863. // For a release build, stop the exception here and return an error
  864. // code. This gives upstream code a chance to gracefully recover.
  865. // We also need to clear the floating point control word, otherwise
  866. // the upstream code may incur an exception the next time it tries
  867. // a floating point operation (presuming this exception was due
  868. // to a floating point problem).
  869. #if defined(DEBUG) || defined(_DEBUG)
  870. DBOUT("Exception during H263Compress!!!");
  871. throw;
  872. #else
  873. _clearfp();
  874. return (DWORD) ICERR_ERROR;
  875. #endif
  876. }
  877. if (dwRet != ICERR_OK)
  878. {
  879. DBOUT("H263Compress Failed");
  880. }
  881. // now transfer the information.
  882. lpCompInfo->lpbiOutput->biSize =sizeof(BITMAPINFOHEADER);
  883. lpCompInfo->lpbiOutput->biCompression = FOURCC_H263;
  884. lpCompInfo->lpbiOutput->biPlanes = 1;
  885. lpCompInfo->lpbiOutput->biBitCount = 24;
  886. lpCompInfo->lpbiOutput->biWidth = lpInst->xres;
  887. lpCompInfo->lpbiOutput->biHeight = lpInst->yres;
  888. lpCompInfo->lpbiOutput->biSizeImage = lpInst->CompressedSize;
  889. lpCompInfo->lpbiOutput->biClrUsed = 0;
  890. lpCompInfo->lpbiOutput->biClrImportant = 0;
  891. // lpCompInfo->dwFlags is set inside the compressor.
  892. // set the chunk idea if requested
  893. if (lpCompInfo->lpckid)
  894. {
  895. *(lpCompInfo->lpckid) = TWOCC_H26X;
  896. }
  897. return(dwRet);
  898. }