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.

1772 lines
48 KiB

  1. /*
  2. * @DEC_COPYRIGHT@
  3. */
  4. /*
  5. * HISTORY
  6. * $Log: h263.c,v $
  7. * $EndLog$
  8. */
  9. /*
  10. **++
  11. ** FACILITY: Workstation Multimedia (WMM) v1.0
  12. **
  13. ** FILE NAME: h263.c
  14. ** MODULE NAME: h263.c
  15. **
  16. ** MODULE DESCRIPTION:
  17. ** H.263ICM driver
  18. **
  19. ** Microsoft file I/O functions
  20. ** Implemented as functions:
  21. ** H263Close
  22. ** H263Compress
  23. ** H263Decompress
  24. ** H263DecompressEnd
  25. ** H263DecompressGetPalette
  26. ** H263DecompressGetSize
  27. ** H263DecompressQuery
  28. ** H263GetInfo
  29. ** H263Info
  30. ** H263Locate
  31. ** H263Open
  32. ** H263SendMessage
  33. **
  34. ** Private functions:
  35. **
  36. ** DESIGN OVERVIEW:
  37. **
  38. **--
  39. */
  40. /*-------------------------------------------------------------------------
  41. ** Modification History: sc_mem.c
  42. ** 04-15-97 HWG Added debug statements to help with checking
  43. ** for memory leaks
  44. --------------------------------------------------------------------------*/
  45. #include <stdlib.h>
  46. #include <windows.h>
  47. #include <mmsystem.h>
  48. #include "h26x_int.h"
  49. #ifdef _SLIBDEBUG_
  50. #define _DEBUG_ 0 /* detailed debuging statements */
  51. #define _VERBOSE_ 1 /* show progress */
  52. #define _VERIFY_ 1 /* verify correct operation */
  53. #define _WARN_ 1 /* warnings about strange behavior */
  54. #define _MEMORY_ 0 /* memory debugging */
  55. dword scMemDump();
  56. #endif
  57. /* For shared mem */
  58. static H26XINFO *pValidHandles = NULL;
  59. static int NextH263Hic = 1;
  60. static int OpenCount = 0;
  61. static HANDLE InfoMutex = NULL;
  62. #define InitInfoMutex() if (InfoMutex==NULL) InfoMutex=CreateMutex(NULL, FALSE, NULL)
  63. #define FreeInfoMutex() if (InfoMutex!=NULL) \
  64. CloseHandle(InfoMutex); InfoMutex=NULL
  65. #define LockInfo() WaitForSingleObject(InfoMutex, 5000);
  66. #define ReleaseInfo() ReleaseMutex(InfoMutex)
  67. /*
  68. * Macros
  69. */
  70. #define _ICH263CheckFlags(info, flag) ((info->openFlags & flag) ? TRUE : FALSE)
  71. #define FREE_AND_CLEAR(s) if (s) {ScFree(s); (s)=NULL;}
  72. #define FREE_AND_CLEAR_PA(s) if (s) {ScPaFree(s); (s)=NULL;}
  73. /*
  74. * Default LPBI format
  75. */
  76. static BITMAPINFOHEADER __defaultDecompresslpbiOut =
  77. {
  78. sizeof(BITMAPINFOHEADER), // DWORD biSize;
  79. 0, // LONG biWidth;
  80. 0, // LONG biHeight;
  81. 1, // WORD biPlanes;
  82. 24, // WORD biBitCount
  83. BI_RGB, // DWORD biCompression;
  84. 0, // DWORD biSizeImage;
  85. 0, // LONG biXPelsPerMeter;
  86. 0, // LONG biYPelsPerMeter;
  87. 0, // DWORD biClrUsed;
  88. 0 // DWORD biClrImportant;
  89. };
  90. static BITMAPINFOHEADER __defaultCompresslpbiOut =
  91. {
  92. sizeof(BITMAPINFOHEADER), // DWORD biSize;
  93. 0, // LONG biWidth;
  94. 0, // LONG biHeight;
  95. 1, // WORD biPlanes;
  96. 24, // WORD biBitCount
  97. #ifdef H261_SUPPORT
  98. VIDEO_FORMAT_DIGITAL_H261, // DWORD biCompression;
  99. #else
  100. VIDEO_FORMAT_DIGITAL_H263, // DWORD biCompression;
  101. #endif
  102. 0, // DWORD biSizeImage;
  103. 0, // LONG biXPelsPerMeter;
  104. 0, // LONG biYPelsPerMeter;
  105. 0, // DWORD biClrUsed;
  106. 0 // DWORD biClrImportant;
  107. };
  108. typedef struct SupportList_s {
  109. int InFormat; /* Input format */
  110. int InBits; /* Input number of bits */
  111. int OutFormat; /* Output format */
  112. int OutBits; /* Output number of bits */
  113. } SupportList_t;
  114. /*
  115. ** Input & Output Formats supported by H.261 Compression
  116. */
  117. static SupportList_t _ICCompressionSupport[] = {
  118. BI_DECYUVDIB, 16, H26X_FOURCC, 24, /* YUV 4:2:2 Packed */
  119. BI_YUY2, 16, H26X_FOURCC, 24, /* YUV 4:2:2 Packed */
  120. BI_YU12SEP, 24, H26X_FOURCC, 24, /* YUV 4:1:1 Planar */
  121. BI_YVU9SEP, 24, H26X_FOURCC, 24, /* YUV 16:1:1 Planar */
  122. BI_RGB, 16, H26X_FOURCC, 24, /* RGB 16 */
  123. BI_RGB, 24, H26X_FOURCC, 24, /* RGB 24 */
  124. 0, 0, 0, 0
  125. };
  126. /*
  127. ** Input & Output Formats supported by H.261 Decompression
  128. */
  129. static SupportList_t _ICDecompressionSupport[] = {
  130. H26X_FOURCC, 24, BI_DECYUVDIB, 16, /* YUV 4:2:2 Packed */
  131. H26X_FOURCC, 24, BI_YUY2, 16, /* YUV 4:2:2 Packed */
  132. H26X_FOURCC, 24, BI_YU12SEP, 24, /* YUV 4:1:1 Planar */
  133. H26X_FOURCC, 24, BI_YVU9SEP, 24, /* YUV 16:1:1 Planar */
  134. H26X_FOURCC, 24, BI_BITFIELDS, 32, /* BITFIELDS */
  135. H26X_FOURCC, 24, BI_RGB, 16, /* RGB 16 */
  136. H26X_FOURCC, 24, BI_RGB, 24, /* RGB 24 */
  137. H26X_FOURCC, 24, BI_RGB, 32, /* RGB 32 */
  138. H26X_FOURCC, 24, BI_RGB, 8, /* RGB 8 */
  139. 0, 0, 0, 0
  140. };
  141. /*
  142. ** Name: IsSupported
  143. ** Desc: Lookup the a given input and output format to see if it
  144. ** exists in a SupportList.
  145. ** Note: If OutFormat==-1 and OutBits==-1 then only input format
  146. ** is checked for support.
  147. ** If InFormat==-1 and InBits==-1 then only output format
  148. ** is checked for support.
  149. ** Return: NULL Formats not supported.
  150. ** not NULL A pointer to the list entry.
  151. */
  152. static SupportList_t *IsSupported(SupportList_t *list,
  153. int InFormat, int InBits,
  154. int OutFormat, int OutBits)
  155. {
  156. if (OutFormat==-1 && OutBits==-1) /* Looking up only the Input format */
  157. {
  158. while (list->InFormat || list->InBits)
  159. if (list->InFormat == InFormat && list->InBits==InBits)
  160. return(list);
  161. else
  162. list++;
  163. return(NULL);
  164. }
  165. if (InFormat==-1 && InBits==-1) /* Looking up only the Output format */
  166. {
  167. while (list->InFormat || list->InBits)
  168. if (list->OutFormat == OutFormat && list->OutBits==OutBits)
  169. return(list);
  170. else
  171. list++;
  172. return(NULL);
  173. }
  174. /* Looking up both Input and Output */
  175. while (list->InFormat || list->InBits)
  176. if (list->InFormat == InFormat && list->InBits==InBits &&
  177. list->OutFormat == OutFormat && list->OutBits==OutBits)
  178. return(list);
  179. else
  180. list++;
  181. return(NULL);
  182. }
  183. unsigned int CalcImageSize(unsigned int fourcc, int w, int h, int bits)
  184. {
  185. if (h<0) h=-h;
  186. if (IsYUV411Sep(fourcc))
  187. return((w * h * 3) / 2);
  188. else if (IsYUV422Sep(fourcc) || IsYUV422Packed(fourcc))
  189. return(w * h * 2);
  190. else if (IsYUV1611Sep(fourcc))
  191. return((w * h * 9) / 8);
  192. #ifdef BICOMP_DECXIMAGEDIB
  193. else if (fourcc==BICOMP_DECXIMAGEDIB)
  194. return(bits<=8 ? w * h : (w * h * 4));
  195. #endif
  196. else /* RGB */
  197. return(w * h * (bits+7)/8);
  198. }
  199. /*
  200. **++
  201. ** FUNCTIONAL_NAME: InitBitmapinfo
  202. **
  203. ** FUNCTIONAL_DESCRIPTION:
  204. ** Allocate and copy our local copies of the input and output
  205. ** BITMAPINFOHEADERs
  206. **
  207. ** FORMAL PARAMETERS:
  208. ** info pointer to the driver handle
  209. ** lpbiIn pointer to the input BITMAPINFOHEADER
  210. ** lpbiOut pointer to the output BITMAPINFOHEADER
  211. **
  212. ** RETURN VALUE:
  213. **
  214. ** ICERR_OK Success
  215. ** ICERR_MEMORY Malloc failed
  216. **
  217. ** COMMENTS:
  218. **
  219. ** DESIGN:
  220. **
  221. **/
  222. static MMRESULT InitBitmapinfo(H26XINFO *info,
  223. LPBITMAPINFOHEADER lpbiIn,
  224. LPBITMAPINFOHEADER lpbiOut)
  225. {
  226. _SlibDebug(_DEBUG_,
  227. ScDebugPrintf("In InitBitmapinfo(), IN: 0x%x, OUT: 0x%x\n", lpbiIn, lpbiOut));
  228. if (info->lpbiIn == NULL)
  229. {
  230. if ((info->lpbiIn = (VOID *)ScAlloc(lpbiIn->biSize)) == NULL)
  231. return(unsigned int)(ICERR_MEMORY);
  232. }
  233. bcopy(lpbiIn, info->lpbiIn, lpbiIn->biSize);
  234. if (info->lpbiOut == NULL)
  235. {
  236. if ((info->lpbiOut = (VOID *)ScAlloc(lpbiOut->biSize)) == NULL)
  237. return(unsigned int)(ICERR_MEMORY);
  238. }
  239. bcopy(lpbiOut, info->lpbiOut, lpbiOut->biSize);
  240. _SlibDebug(_DEBUG_, ScDebugPrintf("Out InitBitmapinfo()\n"));
  241. return(ICERR_OK);
  242. }
  243. /*
  244. **++
  245. ** FUNCTIONAL_NAME: ICclient2info
  246. **
  247. ** FUNCTIONAL_DESCRIPTION:
  248. ** Translate the client pointer to an H26XINFO pointer
  249. **
  250. ** FORMAL PARAMETERS:
  251. ** client the client ptr to look up
  252. **
  253. ** RETURN VALUE:
  254. **
  255. ** pointer to the H26XINFO structure or NULL
  256. **
  257. ** COMMENTS:
  258. **
  259. ** DESIGN:
  260. **
  261. **/
  262. H26XINFO *ICclient2info(void *client)
  263. {
  264. return (H26XINFO *) NULL;
  265. }
  266. /*
  267. **++
  268. ** FUNCTIONAL_NAME: IChic2info
  269. **
  270. ** FUNCTIONAL_DESCRIPTION:
  271. ** Translate the HIC integer to an H26XINFO pointer
  272. **
  273. ** FORMAL PARAMETERS:
  274. ** hic the hic managed by icm.c
  275. **
  276. ** RETURN VALUE:
  277. **
  278. ** pointer to the H26XINFO structure or NULL
  279. **
  280. ** COMMENTS:
  281. **
  282. ** DESIGN:
  283. **
  284. **/
  285. H26XINFO *IChic2info(HIC hic)
  286. {
  287. H26XINFO *retptr=NULL, *ptr;
  288. InitInfoMutex();
  289. LockInfo();
  290. #ifdef HANDLE_EXCEPTIONS
  291. __try {
  292. /* pointers go wrong when driver closes */
  293. #endif /* HANDLE_EXCEPTIONS */
  294. for (ptr = pValidHandles; ptr; ptr=ptr->next)
  295. if (ptr->hic == hic)
  296. {
  297. retptr=ptr;
  298. break;
  299. }
  300. #ifdef HANDLE_EXCEPTIONS
  301. } __finally {
  302. #endif /* HANDLE_EXCEPTIONS */
  303. ReleaseInfo();
  304. #ifdef HANDLE_EXCEPTIONS
  305. return(retptr);
  306. } /* try..except */
  307. #endif /* HANDLE_EXCEPTIONS */
  308. return(retptr);
  309. }
  310. /*
  311. **++
  312. ** FUNCTIONAL_NAME: ICHandle2hic
  313. **
  314. ** FUNCTIONAL_DESCRIPTION:
  315. ** Translate the SLIB codec handle to an ICM HIC value
  316. **
  317. ** FORMAL PARAMETERS:
  318. ** Sh SLIB handle returned on the SlibOpen call
  319. **
  320. ** RETURN VALUE:
  321. **
  322. ** hic the hic managed by icm.c
  323. **
  324. ** COMMENTS:
  325. **
  326. ** DESIGN:
  327. **
  328. **/
  329. HIC ICHandle2hic(SlibHandle_t Sh)
  330. {
  331. H26XINFO *ptr;
  332. InitInfoMutex();
  333. LockInfo();
  334. for (ptr = pValidHandles; ptr; ptr=ptr->next)
  335. if (ptr->Sh == Sh)
  336. break;
  337. ReleaseInfo();
  338. return(ptr->hic);
  339. }
  340. /*
  341. **++
  342. ** FUNCTIONAL_NAME: ICclientGone
  343. **
  344. ** FUNCTIONAL_DESCRIPTION:
  345. ** Sets the clientGone flag in client's H26XINFO
  346. **
  347. ** FORMAL PARAMETERS:
  348. ** client the client ptr to look up
  349. **
  350. ** RETURN VALUE:
  351. **
  352. ** COMMENTS:
  353. **
  354. ** DESIGN:
  355. **
  356. **/
  357. BOOL ICclientGone(void *client)
  358. {
  359. H26XINFO *ptr;
  360. LockInfo();
  361. for (ptr = pValidHandles; ptr; ptr = ptr->next) {
  362. if (ptr->client == client)
  363. ptr->clientGone = TRUE;
  364. }
  365. ReleaseInfo();
  366. return(ptr != NULL);
  367. }
  368. /*
  369. **++
  370. ** FUNCTIONAL_NAME: ICH263Open
  371. **
  372. ** FUNCTIONAL_DESCRIPTION:
  373. ** Open the Software CODEC
  374. **
  375. ** FORMAL PARAMETERS:
  376. ** client
  377. **
  378. ** RETURN VALUE:
  379. ** driverHandle
  380. **
  381. ** COMMENTS:
  382. **
  383. ** DESIGN:
  384. **
  385. **/
  386. HIC ICH263Open(void *client)
  387. {
  388. H26XINFO *info;
  389. ICOPEN *icopen =(ICOPEN *) client;
  390. DWORD fccType = icopen->fccType;
  391. UINT dwFlags = icopen->dwFlags;
  392. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Open()\n") );
  393. /*
  394. * fccType must be 'vidc'
  395. */
  396. if (fccType != ICTYPE_VIDEO)
  397. return(0);
  398. /*
  399. * We don't support draw operations.
  400. */
  401. if ( dwFlags & ICMODE_DRAW )
  402. return 0;
  403. /*
  404. * We don't support compress and decompress
  405. * with the same handler.
  406. */
  407. if ( (dwFlags & ICMODE_COMPRESS) &&
  408. (dwFlags & ICMODE_DECOMPRESS) )
  409. return 0;
  410. /*
  411. * At least one of these flags must be set:
  412. * COMPRESS, DECOMPRESS or QUERY.
  413. */
  414. if ( !(dwFlags & ICMODE_COMPRESS) &&
  415. !(dwFlags & ICMODE_DECOMPRESS) &&
  416. !(dwFlags & ICMODE_QUERY) )
  417. return 0;
  418. info = (H26XINFO *) ScAlloc(sizeof(H26XINFO));
  419. if (info)
  420. {
  421. InitInfoMutex();
  422. LockInfo();
  423. OpenCount++;
  424. bzero(info, sizeof(H26XINFO));
  425. info->next = pValidHandles;
  426. pValidHandles = info;
  427. info->hic = (HANDLE) NextH263Hic++; /* !!! check for used entry! */
  428. info->client = client;
  429. info->fFrameRate=H26X_DEFAULT_FRAMERATE;
  430. info->dwBitrate=H26X_DEFAULT_BITRATE;
  431. info->dwPacketSize=H26X_DEFAULT_PACKETSIZE;
  432. info->dwRTP=H26X_DEFAULT_RTP;
  433. info->dwQuality=H26X_DEFAULT_QUALITY;
  434. info->dwMaxQuality=H26X_DEFAULT_QUALITY;
  435. info->dwQi=H26X_DEFAULT_CIF_QI;
  436. info->dwQp=H26X_DEFAULT_CIF_QP;
  437. info->dwMaxQi=H26X_DEFAULT_CIF_QI;
  438. info->dwMaxQp=H26X_DEFAULT_CIF_QP;
  439. info->openFlags = dwFlags;
  440. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Open() info=%p hic=%d\n", info, info->hic) );
  441. ReleaseInfo();
  442. return(info->hic);
  443. }
  444. else
  445. {
  446. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Open() alloc failed\n") );
  447. return(NULL);
  448. }
  449. }
  450. /*
  451. **++
  452. ** FUNCTIONAL_NAME: H263Close
  453. **
  454. ** FUNCTIONAL_DESCRIPTION:
  455. ** Close the Software CODEC
  456. **
  457. ** FORMAL PARAMETERS:
  458. ** driverID
  459. **
  460. ** RETURN VALUE:
  461. **
  462. ** COMMENTS:
  463. ** Does it's own post reply.
  464. **
  465. ** DESIGN:
  466. **
  467. **/
  468. void ICH263Close(H26XINFO *info, BOOL postreply)
  469. {
  470. H26XINFO *ptr;
  471. int status;
  472. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Close() In: info=%p\n", info) );
  473. if (info==NULL)
  474. return;
  475. if (info->Sh)
  476. {
  477. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibClose()\n") );
  478. status=SlibClose(info->Sh);
  479. info->Sh = NULL;
  480. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibMemUsed = %ld (after SlibClose)\n", SlibMemUsed()) );
  481. }
  482. _SlibDebug(_VERBOSE_, ScDebugPrintf("Freeing memory\n") );
  483. FREE_AND_CLEAR(info->lpbiIn);
  484. FREE_AND_CLEAR(info->lpbiOut);
  485. LockInfo();
  486. if (pValidHandles == info)
  487. pValidHandles = info->next;
  488. else
  489. {
  490. for (ptr = pValidHandles; ptr && ptr->next; ptr = ptr->next)
  491. if (ptr->next == info) /* found info, remove from linked list */
  492. {
  493. ptr->next = info->next;
  494. break;
  495. }
  496. }
  497. OpenCount--;
  498. if (pValidHandles==NULL) /* all instances closed, reset driver ID */
  499. {
  500. NextH263Hic=1;
  501. ReleaseInfo();
  502. FreeInfoMutex();
  503. }
  504. else
  505. {
  506. ptr = pValidHandles;
  507. ReleaseInfo();
  508. }
  509. _SlibDebug(_VERBOSE_, ScDebugPrintf("DriverPostReply\n") );
  510. if (postreply && !info->clientGone)
  511. {
  512. _SlibDebug(_VERBOSE_, ScDebugPrintf("DriverPostReply\n") );
  513. DriverPostReply(info->client, ICERR_OK, 0);
  514. }
  515. ScFree(info);
  516. _SlibDebug(_MEMORY_, scMemDump() );
  517. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Close() Out\n") );
  518. }
  519. /*
  520. **++
  521. ** FUNCTIONAL_NAME: ICH263QueryConfigure
  522. **
  523. ** FUNCTIONAL_DESCRIPTION:
  524. ** We don't do configure. Say so.
  525. **
  526. ** FORMAL PARAMETERS:
  527. ** Handle
  528. **
  529. ** RETURN VALUE:
  530. **
  531. ** COMMENTS:
  532. **
  533. ** DESIGN:
  534. **
  535. **/
  536. BOOL ICH263QueryConfigure(H26XINFO *info)
  537. {
  538. return(FALSE);
  539. }
  540. /*
  541. **++
  542. ** FUNCTIONAL_NAME: ICH263Configure
  543. **
  544. ** FUNCTIONAL_DESCRIPTION:
  545. ** Unsupported function
  546. **
  547. ** FORMAL PARAMETERS:
  548. ** driverID
  549. **
  550. ** RETURN VALUE:
  551. **
  552. ** COMMENTS:
  553. **
  554. ** DESIGN:
  555. **
  556. **/
  557. MMRESULT ICH263Configure(H26XINFO *info)
  558. {
  559. return(MMRESULT)(ICERR_UNSUPPORTED);
  560. }
  561. MMRESULT ICH263CustomEncoder(H26XINFO *info, DWORD param1, DWORD param2)
  562. {
  563. SlibHandle_t Sh;
  564. SlibStream_t stream=SLIB_STREAM_ALL;
  565. WORD task=HIWORD(param1);
  566. WORD control=LOWORD(param1);
  567. Sh = info->Sh;
  568. if (task==EC_SET_CURRENT)
  569. {
  570. switch (control)
  571. {
  572. case EC_RTP_HEADER: /* Turn on/off RTP */
  573. info->dwRTP=param2;
  574. switch (info->dwRTP)
  575. {
  576. case EC_RTP_MODE_OFF:
  577. SlibSetParamInt (Sh, stream, SLIB_PARAM_FORMATEXT, 0);
  578. break;
  579. default:
  580. case EC_RTP_MODE_A:
  581. SlibSetParamInt (Sh, stream, SLIB_PARAM_FORMATEXT, PARAM_FORMATEXT_RTPA);
  582. break;
  583. case EC_RTP_MODE_B:
  584. SlibSetParamInt (Sh, stream, SLIB_PARAM_FORMATEXT, PARAM_FORMATEXT_RTPB);
  585. break;
  586. case EC_RTP_MODE_C:
  587. SlibSetParamInt (Sh, stream, SLIB_PARAM_FORMATEXT, PARAM_FORMATEXT_RTPC);
  588. break;
  589. }
  590. return (ICERR_OK);
  591. case EC_PACKET_SIZE: /* Set Packet Size */
  592. info->dwPacketSize=param2;
  593. SlibSetParamInt (Sh, stream, SLIB_PARAM_PACKETSIZE, info->dwPacketSize);
  594. return (ICERR_OK);
  595. case EC_BITRATE: /* Set Bitrate */
  596. info->dwBitrate=param2;
  597. SlibSetParamInt (Sh, stream, SLIB_PARAM_BITRATE, info->dwBitrate);
  598. return (ICERR_OK);
  599. case EC_BITRATE_CONTROL: /* Turn constant bitrate on/off */
  600. if (param2==0)
  601. info->dwBitrate=0;
  602. else if (info->dwBitrate)
  603. info->dwBitrate=H26X_DEFAULT_BITRATE;
  604. SlibSetParamInt (Sh, stream, SLIB_PARAM_BITRATE, info->dwBitrate);
  605. return (ICERR_OK);
  606. }
  607. }
  608. else if (task==EC_GET_CURRENT)
  609. {
  610. DWORD *pval=(DWORD *)param2;
  611. if (pval==NULL)
  612. return((MMRESULT)ICERR_BADPARAM);
  613. switch (control)
  614. {
  615. case EC_RTP_HEADER:
  616. *pval=info->dwRTP;
  617. return (ICERR_OK);
  618. case EC_PACKET_SIZE:
  619. *pval=info->dwPacketSize;
  620. return (ICERR_OK);
  621. case EC_BITRATE:
  622. *pval=info->dwBitrate;
  623. return (ICERR_OK);
  624. case EC_BITRATE_CONTROL: /* Turn constant bitrate on/off */
  625. *pval=info->dwBitrate?1:0;
  626. return (ICERR_OK);
  627. }
  628. }
  629. else if (task==EC_GET_FACTORY_DEFAULT)
  630. {
  631. DWORD *pval=(DWORD *)param2;
  632. if (pval==NULL)
  633. return((MMRESULT)ICERR_BADPARAM);
  634. *pval=0;
  635. return (ICERR_OK);
  636. }
  637. else if (task==EC_GET_FACTORY_LIMITS)
  638. {
  639. DWORD *pval=(DWORD *)param2;
  640. if (pval==NULL)
  641. return((MMRESULT)ICERR_BADPARAM);
  642. *pval=0;
  643. return (ICERR_OK);
  644. }
  645. else if (task==EC_RESET_TO_FACTORY_DEFAULTS)
  646. {
  647. return (ICERR_OK);
  648. }
  649. return((MMRESULT)ICERR_UNSUPPORTED);
  650. }
  651. /*
  652. **++
  653. ** FUNCTIONAL_NAME: ICH263QueryAbout
  654. **
  655. ** FUNCTIONAL_DESCRIPTION:
  656. ** Tell 'em we don't do about
  657. **
  658. ** FORMAL PARAMETERS:
  659. ** driverID
  660. **
  661. ** RETURN VALUE:
  662. **
  663. ** COMMENTS:
  664. **
  665. ** DESIGN:
  666. **
  667. **/
  668. BOOL ICH263QueryAbout(H26XINFO *info)
  669. {
  670. return(FALSE);
  671. }
  672. /*
  673. **++
  674. ** FUNCTIONAL_NAME: ICH263About
  675. **
  676. ** FUNCTIONAL_DESCRIPTION:
  677. ** About box
  678. **
  679. ** FORMAL PARAMETERS:
  680. ** driverID
  681. **
  682. ** RETURN VALUE:
  683. **
  684. ** COMMENTS:
  685. **
  686. ** DESIGN:
  687. **
  688. **/
  689. MMRESULT ICH263About (H26XINFO *info)
  690. {
  691. return(MMRESULT)(ICERR_UNSUPPORTED);
  692. }
  693. /*
  694. **++
  695. ** FUNCTIONAL_NAME: ICH263GetInfo
  696. **
  697. ** FUNCTIONAL_DESCRIPTION:
  698. ** Return info about codec
  699. **
  700. ** FORMAL PARAMETERS:
  701. ** driverID
  702. **
  703. ** RETURN VALUE:
  704. **
  705. ** COMMENTS:
  706. **
  707. ** DESIGN:
  708. **
  709. **/
  710. MMRESULT ICH263GetInfo(H26XINFO *info, ICINFO *icinfo, DWORD dwSize)
  711. {
  712. _SlibDebug(_VERBOSE_, ScDebugPrintf("In H263GetInfo\n") );
  713. icinfo->dwSize = sizeof(ICINFO);
  714. icinfo->fccType = ICTYPE_VIDEO;
  715. icinfo->fccHandler = H26X_FOURCC;
  716. icinfo->dwFlags = VIDCF_QUALITY|VIDCF_CRUNCH|VIDCF_TEMPORAL|VIDCF_FASTTEMPORALC;
  717. icinfo->dwVersion = H26X_VERSION;
  718. icinfo->dwVersionICM = ICVERSION;
  719. wcscpy(icinfo->szDescription, H26X_DESCRIPTION);
  720. wcscpy(icinfo->szName, H26X_NAME);
  721. #if 0
  722. /* we shouldn't change the szDriver field */
  723. wcscpy(icinfo->szDriver, _wgetenv(L"SystemRoot"));
  724. if( icinfo->szDriver[0] != 0 )
  725. wcscat(icinfo->szDriver, L"\\System32\\" );
  726. wcscat(icinfo->szDriver, H26X_DRIVER);
  727. #endif
  728. return (dwSize);
  729. }
  730. /*
  731. **++
  732. ** FUNCTIONAL_NAME: ICH263CompressQuery
  733. **
  734. ** FUNCTIONAL_DESCRIPTION:
  735. ** Determine compression capability
  736. **
  737. ** FORMAL PARAMETERS:
  738. ** driverID
  739. ** lpbiIn input BITMAPINFOHEADER
  740. ** lpbiOut output BITMAPINFOHEADER
  741. **
  742. ** RETURN VALUE:
  743. **
  744. ** COMMENTS:
  745. **
  746. ** DESIGN:
  747. **
  748. **/
  749. MMRESULT ICH263CompressQuery(H26XINFO *info,
  750. LPBITMAPINFOHEADER lpbiIn,
  751. LPBITMAPINFOHEADER lpbiOut)
  752. {
  753. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263CompressQuery\n") );
  754. if (
  755. (!_ICH263CheckFlags(info, ICMODE_QUERY)) &&
  756. (
  757. (!_ICH263CheckFlags(info, ICMODE_COMPRESS)) ||
  758. (!_ICH263CheckFlags(info, ICMODE_FASTCOMPRESS))
  759. )
  760. )
  761. return (MMRESULT)ICERR_BADHANDLE;
  762. /*
  763. * Must query at least an input or an output format
  764. */
  765. if (!lpbiIn && !lpbiOut)
  766. return (MMRESULT)(ICERR_BADPARAM);
  767. if (!IsSupported(_ICCompressionSupport,
  768. lpbiIn ? lpbiIn->biCompression : -1,
  769. lpbiIn ? lpbiIn->biBitCount : -1,
  770. lpbiOut ? lpbiOut->biCompression : -1,
  771. lpbiOut ? lpbiOut->biBitCount : -1))
  772. return(MMRESULT)(ICERR_BADFORMAT);
  773. return ICERR_OK;
  774. }
  775. /*
  776. **++
  777. ** FUNCTIONAL_NAME: ICH263CompressBegin
  778. **
  779. ** FUNCTIONAL_DESCRIPTION:
  780. ** Prepare to start a Compression operation
  781. **
  782. ** FORMAL PARAMETERS:
  783. ** driverID
  784. ** lpbiIn input BITMAPINFOHEADER
  785. ** lpbiOut output BITMAPINFOHEADER
  786. **
  787. ** RETURN VALUE:
  788. **
  789. ** COMMENTS:
  790. **
  791. ** DESIGN:
  792. **
  793. **/
  794. MMRESULT ICH263CompressBegin(H26XINFO *info,
  795. LPBITMAPINFOHEADER lpbiIn,
  796. LPBITMAPINFOHEADER lpbiOut)
  797. {
  798. MMRESULT status;
  799. SlibStatus_t sstatus;
  800. #ifdef H261_SUPPORT
  801. SlibType_t stype = SLIB_TYPE_H261;
  802. #else
  803. SlibType_t stype = SLIB_TYPE_H263;
  804. #endif
  805. SlibHandle_t Sh;
  806. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263CompressBegin\n") );
  807. if ((!_ICH263CheckFlags(info, ICMODE_COMPRESS)) || (!_ICH263CheckFlags(info, ICMODE_FASTCOMPRESS)))
  808. return (MMRESULT)ICERR_BADHANDLE;
  809. if (!lpbiIn || !lpbiOut)
  810. return (MMRESULT)(ICERR_BADPARAM);
  811. if ((status = ICH263CompressQuery(info, lpbiIn, lpbiOut)) != ICERR_OK)
  812. return status;
  813. if ((status = InitBitmapinfo(info, lpbiIn, lpbiOut)) != ICERR_OK)
  814. return status;
  815. info->bUsesCodec = TRUE;
  816. lpbiIn=info->lpbiIn;
  817. lpbiOut=info->lpbiOut;
  818. lpbiIn->biHeight=-lpbiIn->biHeight; /* SLIB assume first line is top */
  819. info->dwMaxQuality=H26X_DEFAULT_QUALITY;
  820. if (lpbiIn->biWidth<168) /* Sub-QCIF */
  821. {
  822. info->dwMaxQi=H26X_DEFAULT_SQCIF_QI;
  823. info->dwMaxQp=H26X_DEFAULT_SQCIF_QP;
  824. }
  825. if (lpbiIn->biWidth<300) /* QCIF */
  826. {
  827. info->dwMaxQi=H26X_DEFAULT_QCIF_QI;
  828. info->dwMaxQp=H26X_DEFAULT_QCIF_QP;
  829. }
  830. else /* CIF */
  831. {
  832. info->dwMaxQi=H26X_DEFAULT_CIF_QI;
  833. info->dwMaxQp=H26X_DEFAULT_CIF_QP;
  834. }
  835. info->lastFrameNum=0;
  836. info->lastCompBytes=0;
  837. /* Synchronized SLIB SYSTEMS calls */
  838. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibMemUsed = %ld (before SlibOpen)\n", SlibMemUsed()) );
  839. sstatus = SlibOpenSync (&Sh, SLIB_MODE_COMPRESS, &stype, NULL, 0);
  840. if (sstatus!=SlibErrorNone) return((MMRESULT)ICERR_BADPARAM);
  841. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_WIDTH, lpbiIn->biWidth);
  842. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_HEIGHT, lpbiIn->biHeight);
  843. #if 0
  844. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOFORMAT, lpbiIn->biCompression);
  845. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOBITS, lpbiIn->biBitCount);
  846. #else
  847. SlibSetParamStruct(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOFORMAT, lpbiIn, lpbiIn->biSize);
  848. #endif
  849. // SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOQUALITY, info->dwQuality/100);
  850. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_QUANTI, info->dwQi);
  851. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_QUANTP, info->dwQp);
  852. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_BITRATE, info->dwBitrate);
  853. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_PACKETSIZE, info->dwPacketSize);
  854. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_ALGFLAGS, H26X_DEFAULT_MODE);
  855. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_KEYSPACING, 132);
  856. #ifdef H261_SUPPORT
  857. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_MOTIONALG, 1);
  858. #else
  859. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_MOTIONALG, 2);
  860. #endif
  861. SlibSetParamFloat(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_FPS, info->fFrameRate);
  862. switch (info->dwRTP)
  863. {
  864. case EC_RTP_MODE_OFF:
  865. break;
  866. case EC_RTP_MODE_A:
  867. SlibSetParamInt(Sh, SLIB_STREAM_ALL, SLIB_PARAM_FORMATEXT, PARAM_FORMATEXT_RTPA);
  868. break;
  869. case EC_RTP_MODE_B:
  870. SlibSetParamInt(Sh, SLIB_STREAM_ALL, SLIB_PARAM_FORMATEXT, PARAM_FORMATEXT_RTPB);
  871. break;
  872. case EC_RTP_MODE_C:
  873. SlibSetParamInt(Sh, SLIB_STREAM_ALL, SLIB_PARAM_FORMATEXT, PARAM_FORMATEXT_RTPC);
  874. break;
  875. }
  876. info->Sh = Sh;
  877. lpbiIn->biSizeImage = SlibGetParamInt (Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_IMAGESIZE);
  878. info->dwMaxCompBytes = ICH263CompressGetSize(lpbiIn);
  879. info->bCompressBegun = TRUE;
  880. return ICERR_OK;
  881. }
  882. DWORD ICH263CompressGetSize(LPBITMAPINFOHEADER lpbiIn)
  883. {
  884. if (lpbiIn==NULL)
  885. return(0);
  886. else if (lpbiIn->biWidth<=168)
  887. return(0x1800); /* Sub-QCIF */
  888. else if (lpbiIn->biWidth<=300)
  889. return(0x2000); /* QCIF */
  890. else
  891. return(0x8000); /* CIF */
  892. }
  893. /*
  894. **++
  895. ** FUNCTIONAL_NAME: ICH263CompressGetFormat
  896. **
  897. ** FUNCTIONAL_DESCRIPTION:
  898. ** Get the format for compression
  899. **
  900. ** FORMAL PARAMETERS:
  901. ** driverID
  902. ** lpbiIn input BITMAPINFOHEADER
  903. ** lpbiOut output BITMAPINFOHEADER
  904. **
  905. ** RETURN VALUE:
  906. **
  907. ** COMMENTS:
  908. **
  909. ** DESIGN:
  910. **
  911. **/
  912. MMRESULT ICH263CompressGetFormat(H26XINFO *info,
  913. LPBITMAPINFOHEADER lpbiIn,
  914. LPBITMAPINFOHEADER lpbiOut)
  915. {
  916. _SlibDebug(_DEBUG_, ScDebugPrintf("In ICH263CompressGetFormat\n") );
  917. if ((!_ICH263CheckFlags(info, ICMODE_COMPRESS)) &&
  918. (!_ICH263CheckFlags(info, ICMODE_FASTCOMPRESS)) &&
  919. (!_ICH263CheckFlags(info, ICMODE_QUERY)))
  920. return (MMRESULT)ICERR_BADHANDLE;
  921. if (lpbiIn == NULL)
  922. return (MMRESULT)ICERR_BADPARAM;
  923. if (lpbiOut == NULL)
  924. return (sizeof(BITMAPINFOHEADER));
  925. bcopy(&__defaultCompresslpbiOut, lpbiOut, sizeof(BITMAPINFOHEADER));
  926. lpbiOut->biWidth = lpbiIn->biWidth;
  927. lpbiOut->biHeight= lpbiIn->biHeight;
  928. lpbiOut->biSizeImage = ICH263CompressGetSize(lpbiIn);
  929. _SlibDebug(_DEBUG_, ScDebugPrintf(" lpbiOut filled: %s\n",
  930. BMHtoString(lpbiOut)) );
  931. return(ICERR_OK);
  932. }
  933. /*
  934. **++
  935. ** FUNCTIONAL_NAME: ICH263CompressEnd
  936. **
  937. ** FUNCTIONAL_DESCRIPTION:
  938. ** Terminate the compression cycle
  939. **
  940. ** FORMAL PARAMETERS:
  941. ** driverID
  942. **
  943. ** RETURN VALUE:
  944. **
  945. ** COMMENTS:
  946. **
  947. ** DESIGN:
  948. **
  949. **/
  950. MMRESULT ICH263CompressEnd(H26XINFO *info)
  951. {
  952. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263CompressEnd\n") );
  953. if ((!_ICH263CheckFlags(info, ICMODE_COMPRESS))
  954. || (!_ICH263CheckFlags(info, ICMODE_FASTCOMPRESS)))
  955. return (MMRESULT)ICERR_BADHANDLE;
  956. if (info->Sh)
  957. {
  958. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibClose()\n") );
  959. SlibClose (info->Sh);
  960. info->Sh=NULL;
  961. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibMemUsed = %ld (after SlibClose)\n", SlibMemUsed()) );
  962. }
  963. info->bCompressBegun = FALSE;
  964. return(ICERR_OK);
  965. }
  966. /*
  967. **++
  968. ** FUNCTIONAL_NAME: ICH263DecompressQuery
  969. **
  970. ** FUNCTIONAL_DESCRIPTION:
  971. ** Query the codec to determine if it can decompress specified formats
  972. **
  973. ** FORMAL PARAMETERS:
  974. ** driverID
  975. ** lpbiIn input BITMAPINFOHEADER
  976. ** lpbiOut output BITMAPINFOHEADER
  977. **
  978. ** RETURN VALUE:
  979. **
  980. ** COMMENTS:
  981. **
  982. ** DESIGN:
  983. **
  984. **/
  985. MMRESULT ICH263DecompressQuery(H26XINFO *info,
  986. LPBITMAPINFOHEADER lpbiIn,
  987. LPBITMAPINFOHEADER lpbiOut)
  988. {
  989. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263DecompressQuery\n") );
  990. if (!_ICH263CheckFlags(info, ICMODE_QUERY) &&
  991. !_ICH263CheckFlags(info, ICMODE_DECOMPRESS))
  992. return (MMRESULT)ICERR_BADHANDLE;
  993. /*
  994. * Must query at least an input or an output format
  995. */
  996. if (!lpbiIn && !lpbiOut)
  997. return (MMRESULT)(ICERR_BADPARAM);
  998. if (!IsSupported(_ICDecompressionSupport,
  999. lpbiIn ? lpbiIn->biCompression : -1,
  1000. lpbiIn ? lpbiIn->biBitCount : -1,
  1001. lpbiOut ? lpbiOut->biCompression : -1,
  1002. lpbiOut ? lpbiOut->biBitCount : -1))
  1003. return(MMRESULT)(ICERR_BADFORMAT);
  1004. _SlibDebug(_VERBOSE_, ScDebugPrintf("Out ICH263DecompressQuery\n") );
  1005. return ICERR_OK;
  1006. }
  1007. /*
  1008. **++
  1009. ** FUNCTIONAL_NAME: ICH263DecompressBegin
  1010. **
  1011. ** FUNCTIONAL_DESCRIPTION:
  1012. ** Begin the decompression process
  1013. **
  1014. ** FORMAL PARAMETERS:
  1015. ** driverID
  1016. ** lpbiIn input BITMAPINFOHEADER
  1017. ** lpbiOut output BITMAPINFOHEADER
  1018. **
  1019. ** RETURN VALUE:
  1020. **
  1021. ** ICERR_OK No error
  1022. ** ICERR_MEMORY Insufficient memory
  1023. ** ICERR_BADFORMAT Invalid image format
  1024. ** ICERR_BADPARAM Invalid image size
  1025. **
  1026. ** COMMENTS:
  1027. **
  1028. **
  1029. ** DESIGN:
  1030. **
  1031. **/
  1032. MMRESULT ICH263DecompressBegin(H26XINFO *info,
  1033. LPBITMAPINFOHEADER lpbiIn,
  1034. LPBITMAPINFOHEADER lpbiOut)
  1035. {
  1036. MMRESULT status;
  1037. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263DecompressBegin\n") );
  1038. if (!_ICH263CheckFlags(info, ICMODE_DECOMPRESS))
  1039. return (MMRESULT)ICERR_BADHANDLE;
  1040. if ((status = ICH263DecompressQuery(info, lpbiIn, lpbiOut))
  1041. != ICERR_OK)
  1042. return status;
  1043. if (lpbiIn && lpbiOut)
  1044. {
  1045. if ((status = InitBitmapinfo(info, lpbiIn, lpbiOut)) != ICERR_OK)
  1046. return status;
  1047. info->bUsesCodec = TRUE;
  1048. info->bUsesRender = ((lpbiOut->biBitCount == 8) &&
  1049. ((lpbiOut->biCompression == BI_DECXIMAGEDIB)||
  1050. (lpbiOut->biCompression == BI_DECGRAYDIB) ||
  1051. (lpbiOut->biCompression == BI_RGB)
  1052. )
  1053. );
  1054. if (!info->bUsesCodec && !info->bUsesRender)
  1055. return (MMRESULT)ICERR_BADFORMAT;
  1056. /* SLIB expects first pixel to be top line */
  1057. info->lpbiOut->biHeight=-info->lpbiOut->biHeight;
  1058. }
  1059. info->bDecompressBegun = TRUE;
  1060. _SlibDebug(_VERBOSE_, ScDebugPrintf("Out ICH263DecompressBegin\n") );
  1061. return ICERR_OK;
  1062. }
  1063. /*
  1064. **++
  1065. ** FUNCTIONAL_NAME: ICH263DecompressGetFormat
  1066. **
  1067. ** FUNCTIONAL_DESCRIPTION:
  1068. ** Get the recommended decompressed format of the codec
  1069. **
  1070. ** FORMAL PARAMETERS:
  1071. ** driverID
  1072. ** lpbiIn input BITMAPINFOHEADER
  1073. ** lpbiOut output BITMAPINFOHEADER
  1074. **
  1075. ** RETURN VALUE:
  1076. **
  1077. ** COMMENTS:
  1078. **
  1079. ** DESIGN:
  1080. **
  1081. **/
  1082. MMRESULT ICH263DecompressGetFormat(H26XINFO *info,
  1083. LPBITMAPINFOHEADER lpbiIn,
  1084. LPBITMAPINFOHEADER lpbiOut)
  1085. {
  1086. _SlibDebug(_DEBUG_, ScDebugPrintf("In ICH263DecompressGetFormat\n") );
  1087. if (!_ICH263CheckFlags(info, ICMODE_DECOMPRESS) &&
  1088. (!_ICH263CheckFlags(info, ICMODE_QUERY)))
  1089. return((MMRESULT)ICERR_BADHANDLE);
  1090. if (lpbiIn == NULL)
  1091. return((MMRESULT)ICERR_BADPARAM);
  1092. if (lpbiOut == NULL)
  1093. return (sizeof(BITMAPINFOHEADER));
  1094. _SlibDebug(_DEBUG_,
  1095. ScDebugPrintf("lpbiOut is being filled in DecompressGetFormat\n") );
  1096. bcopy(&__defaultDecompresslpbiOut, lpbiOut, sizeof(BITMAPINFOHEADER));
  1097. lpbiOut->biWidth = lpbiIn->biWidth;
  1098. lpbiOut->biHeight= lpbiIn->biHeight;
  1099. /*
  1100. ** Return biSizeImage = 1.5 * width * height to let application know
  1101. ** how big the image buffers must be when passed to ICAddBuffer.
  1102. ** Internal to the codec, they are used to first store a YUV image,
  1103. ** then the ICM layer renders it (if rendered data is what's called for
  1104. */
  1105. lpbiOut->biSizeImage = CalcImageSize(lpbiOut->biCompression,
  1106. lpbiOut->biWidth, lpbiOut->biHeight, lpbiOut->biBitCount);
  1107. if (lpbiOut->biCompression==BI_RGB && lpbiOut->biBitCount==8)
  1108. lpbiOut->biClrUsed = 1<<lpbiOut->biBitCount;
  1109. else
  1110. lpbiOut->biClrUsed = 0;
  1111. return(0);
  1112. }
  1113. /*
  1114. **++
  1115. ** FUNCTIONAL_NAME: ICH263DecompressGetSize
  1116. **
  1117. ** FUNCTIONAL_DESCRIPTION:
  1118. **
  1119. **
  1120. ** FORMAL PARAMETERS:
  1121. ** driverID
  1122. ** lpbiIn input BITMAPINFOHEADER
  1123. ** lpbiOut output BITMAPINFOHEADER
  1124. **
  1125. ** RETURN VALUE:
  1126. **
  1127. ** COMMENTS:
  1128. **
  1129. ** DESIGN:
  1130. **
  1131. **/
  1132. MMRESULT ICH263DecompressGetSize(H26XINFO *info,
  1133. LPBITMAPINFOHEADER lpbiIn,
  1134. LPBITMAPINFOHEADER lpbiOut)
  1135. {
  1136. return(MMRESULT)(ICERR_UNSUPPORTED);
  1137. }
  1138. /*
  1139. **++
  1140. ** FUNCTIONAL_NAME: ICH263DecompressEnd
  1141. **
  1142. ** FUNCTIONAL_DESCRIPTION:
  1143. ** End the decompression process
  1144. **
  1145. ** FORMAL PARAMETERS:
  1146. ** driverID
  1147. **
  1148. ** RETURN VALUE:
  1149. **
  1150. ** COMMENTS:
  1151. **
  1152. ** DESIGN:
  1153. **
  1154. **/
  1155. MMRESULT ICH263DecompressEnd(H26XINFO *info)
  1156. {
  1157. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263DecompressEnd\n") );
  1158. if (!_ICH263CheckFlags(info, ICMODE_DECOMPRESS))
  1159. return (MMRESULT)ICERR_BADHANDLE;
  1160. if (info->Sh)
  1161. {
  1162. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibClose()\n") );
  1163. SlibClose(info->Sh);
  1164. info->Sh=NULL;
  1165. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibMemUsed = %ld (after SlibClose)\n", SlibMemUsed()) );
  1166. }
  1167. info->bDecompressBegun = FALSE;
  1168. return(ICERR_OK);
  1169. }
  1170. MMRESULT ICH263GetDefaultQuality(H26XINFO *info, DWORD * quality)
  1171. {
  1172. *quality = H26X_DEFAULT_QUALITY;
  1173. return((MMRESULT)ICERR_OK);
  1174. }
  1175. MMRESULT ICH263GetQuality(H26XINFO *info, DWORD * quality)
  1176. {
  1177. *quality = info->dwQuality;
  1178. return((MMRESULT)ICERR_OK);
  1179. }
  1180. MMRESULT ICH263SetQuality(H26XINFO *info, DWORD quality)
  1181. {
  1182. if (quality>10000)
  1183. info->dwQuality=10000;
  1184. else
  1185. info->dwQuality=quality;
  1186. // SlibSetParamInt(info->Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOQUALITY,
  1187. // info->dwQuality/100);
  1188. return((MMRESULT)ICERR_OK);
  1189. }
  1190. /*
  1191. **++
  1192. ** FUNCTIONAL_NAME: ICH263Compress
  1193. **
  1194. ** FUNCTIONAL_DESCRIPTION:
  1195. ** Compress a frame
  1196. **
  1197. ** FORMAL PARAMETERS:
  1198. ** driverID
  1199. ** lpbiIn input BITMAPINFOHEADER
  1200. ** lpbiOut output BITMAPINFOHEADER
  1201. **
  1202. ** RETURN VALUE:
  1203. **
  1204. ** COMMENTS:
  1205. **
  1206. ** DESIGN:
  1207. **
  1208. **/
  1209. MMRESULT ICH263Compress(H26XINFO *info,
  1210. ICCOMPRESS *icCompress,
  1211. DWORD dwSize)
  1212. {
  1213. MMRESULT status;
  1214. LPBITMAPINFOHEADER lpbiIn;
  1215. LPBITMAPINFOHEADER lpbiOut;
  1216. LPVOID lpIn;
  1217. LPVOID lpOut;
  1218. SlibHandle_t Sh;
  1219. int compBytes, reqBytes;
  1220. DWORD newQi, newQp;
  1221. RTPTRAILER_t *ptrail;
  1222. BOOL keyframe=icCompress->dwFlags&ICCOMPRESS_KEYFRAME;
  1223. if (icCompress->dwFrameSize==0 || icCompress->dwFrameSize>64*1024)
  1224. reqBytes = info->dwMaxCompBytes;
  1225. else
  1226. reqBytes = icCompress->dwFrameSize;
  1227. #ifdef H261_SUPPORT
  1228. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH261Compress() FrameNum=%d FrameSize=%d Quality=%d reqBytes=%d\n",
  1229. icCompress->lFrameNum, icCompress->dwFrameSize, icCompress->dwQuality,
  1230. reqBytes) );
  1231. #else
  1232. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Compress() FrameNum=%d FrameSize=%d Quality=%d reqBytes=%d\n",
  1233. icCompress->lFrameNum, icCompress->dwFrameSize, icCompress->dwQuality,
  1234. reqBytes) );
  1235. #endif
  1236. if ((!_ICH263CheckFlags(info, ICMODE_COMPRESS))
  1237. || (!_ICH263CheckFlags(info, ICMODE_FASTCOMPRESS)))
  1238. return (MMRESULT)ICERR_BADHANDLE;
  1239. status = ICERR_OK;
  1240. lpbiIn = icCompress->lpbiInput;
  1241. lpbiOut = icCompress->lpbiOutput;
  1242. lpIn = icCompress->lpInput;
  1243. lpOut = icCompress->lpOutput;
  1244. lpbiOut->biSizeImage = 0;
  1245. /* Synchronized SLIB SYSTEMS calls */
  1246. Sh = info->Sh;
  1247. compress_frame:
  1248. newQi=newQp=(((10000-icCompress->dwQuality)*30)/10000)+1;
  1249. if (info->dwRTP!=EC_RTP_MODE_OFF) /* if using RTP, check Quant limits */
  1250. {
  1251. if (newQi<info->dwMaxQi)
  1252. newQi=info->dwMaxQi;
  1253. if (newQp<info->dwMaxQp)
  1254. newQp=info->dwMaxQp;
  1255. }
  1256. if (info->dwQi!=newQi)
  1257. {
  1258. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_QUANTI, newQi);
  1259. info->dwQi=newQi;
  1260. }
  1261. if (info->dwQp!=newQp)
  1262. {
  1263. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_QUANTP, newQp);
  1264. info->dwQp=newQp;
  1265. }
  1266. if (keyframe)
  1267. {
  1268. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Compress() I Frame: Qi=%d\n", newQi) );
  1269. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_FRAMETYPE, FRAME_TYPE_I);
  1270. }
  1271. else
  1272. {
  1273. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Compress() P Frame: Qp=%d\n", newQp) );
  1274. }
  1275. #ifdef HANDLE_EXCEPTIONS
  1276. __try {
  1277. #endif /* HANDLE_EXCEPTIONS */
  1278. status=SlibErrorWriting; /* in case there's an exception */
  1279. status = SlibWriteVideo (Sh, SLIB_STREAM_MAINVIDEO, lpIn, lpbiIn->biSizeImage);
  1280. #ifdef HANDLE_EXCEPTIONS
  1281. } __finally {
  1282. #endif /* HANDLE_EXCEPTIONS */
  1283. if (status != SlibErrorNone)
  1284. {
  1285. #if defined(EXCEPTION_MESSAGES) && defined(H263_SUPPORT)
  1286. // MessageBox(NULL, "Error in H263 SlibWriteVideo", "Warning", MB_OK);
  1287. #elif defined(EXCEPTION_MESSAGES)
  1288. // MessageBox(NULL, "Error in H261 SlibWriteVideo", "Warning", MB_OK);
  1289. #endif
  1290. /* make the next frame a key */
  1291. SlibSetParamInt(Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_FRAMETYPE, FRAME_TYPE_I);
  1292. status=(MMRESULT)ICERR_INTERNAL;
  1293. goto bail;
  1294. }
  1295. #ifdef HANDLE_EXCEPTIONS
  1296. }
  1297. #endif /* HANDLE_EXCEPTIONS */
  1298. info->lastFrameNum=icCompress->lFrameNum;
  1299. compBytes=reqBytes;
  1300. status = SlibReadData(Sh, SLIB_STREAM_ALL, &lpOut, &compBytes, NULL);
  1301. if (status != SlibErrorNone)
  1302. {
  1303. info->lastCompBytes=0;
  1304. status=(MMRESULT)ICERR_BADSIZE;
  1305. goto bail;
  1306. }
  1307. else /* check the amount of compressed data */
  1308. {
  1309. int extraBytes=0;
  1310. /* query to see if any more data is left in the codec
  1311. * if there is then the quant step was too high, reduce it and try again
  1312. */
  1313. status = SlibReadData(Sh, SLIB_STREAM_ALL, NULL, &extraBytes, NULL);
  1314. if (extraBytes)
  1315. {
  1316. _SlibDebug(_VERBOSE_, ScDebugPrintf("ICH263Compress() Too much data: extraBytes=%d\n",
  1317. extraBytes) );
  1318. if (newQi==31 && newQp==31) /* can't compress to any fewer bytes */
  1319. return((MMRESULT)ICERR_BADSIZE);
  1320. info->dwMaxQi+=1+(newQi/4); /* decrease I frame quality */
  1321. if (info->dwMaxQi>31) info->dwMaxQi=31;
  1322. info->dwMaxQp+=1+(newQp/4); /* decrease P frame quality */
  1323. if (info->dwMaxQp>31) info->dwMaxQp=31;
  1324. /* empty out the compressed data */
  1325. SlibSeekEx(Sh, SLIB_STREAM_ALL, SLIB_SEEK_RESET, 0, 0, NULL);
  1326. /* try to compress again, but make it a key frame */
  1327. keyframe=TRUE;
  1328. goto compress_frame;
  1329. }
  1330. /* we have compressed data less than or equal to request size */
  1331. info->lastCompBytes=compBytes;
  1332. lpbiOut->biSizeImage = compBytes;
  1333. status = ICERR_OK;
  1334. }
  1335. if (info->dwRTP!=EC_RTP_MODE_OFF) /* RTP is on */
  1336. {
  1337. ptrail=(RTPTRAILER_t *)((unsigned char *)lpOut+compBytes-sizeof(RTPTRAILER_t));
  1338. /* check for valid RTP trailer */
  1339. if (compBytes<sizeof(RTPTRAILER_t) || ptrail->dwUniqueCode!=H26X_FOURCC)
  1340. return((MMRESULT)ICERR_INTERNAL);
  1341. }
  1342. if (icCompress->dwFlags&ICCOMPRESS_KEYFRAME) /* I frame */
  1343. {
  1344. if (compBytes>(reqBytes>>2))
  1345. {
  1346. info->dwMaxQi+=1+(newQi>>2); /* decrease quality */
  1347. if (info->dwMaxQi>31) info->dwMaxQi=31;
  1348. }
  1349. else if (newQi==info->dwMaxQi && compBytes<=(reqBytes>>2) && info->dwMaxQi>0)
  1350. info->dwMaxQi--; /* increase quality */
  1351. }
  1352. else /* P frame */
  1353. {
  1354. if (compBytes>(reqBytes>>1))
  1355. {
  1356. info->dwMaxQp+=1+(newQp>>2); /* decrease max quality */
  1357. if (info->dwMaxQp>31) info->dwMaxQp=31;
  1358. /* also decrease I quality, since P limits are based on I limits */
  1359. info->dwMaxQi+=1+(newQi>>2);
  1360. if (info->dwMaxQi>31) info->dwMaxQi=31;
  1361. }
  1362. else if (newQp==info->dwMaxQp && compBytes<(reqBytes>>1)
  1363. && info->dwMaxQp>(info->dwMaxQi+3)/2)
  1364. info->dwMaxQp--; /* increase max quality */
  1365. }
  1366. #ifdef H261_SUPPORT
  1367. _SlibDebug(_VERBOSE_||_WARN_,
  1368. ScDebugPrintf("ICH261Compress(%c) lpOut=%p reqBytes=%d compBytes=%d Qi=%d Qp=%d MaxQi=%d MaxQp=%d\n",
  1369. (icCompress->dwFlags&ICCOMPRESS_KEYFRAME)?'I':'P',
  1370. lpOut, reqBytes, compBytes,
  1371. newQi, newQp, info->dwMaxQi, info->dwMaxQp) );
  1372. #else
  1373. _SlibDebug(_VERBOSE_||_WARN_,
  1374. ScDebugPrintf("ICH263Compress(%c) lpOut=%p reqBytes=%d compBytes=%d Qi=%d Qp=%d MaxQi=%d MaxQp=%d\n",
  1375. (icCompress->dwFlags&ICCOMPRESS_KEYFRAME)?'I':'P',
  1376. lpOut, reqBytes, compBytes,
  1377. newQi, newQp, info->dwMaxQi, info->dwMaxQp) );
  1378. #endif
  1379. _SlibDebug(_DEBUG_,
  1380. {
  1381. RTPTRAILER_t *ptrail=(RTPTRAILER_t *)
  1382. ((unsigned char *)lpOut+compBytes-sizeof(RTPTRAILER_t));
  1383. ScDebugPrintf(" Trailer: \n"
  1384. " dwVersion=%d\n"
  1385. " dwFlags=0x%04X\n"
  1386. " dwUniqueCode=%c%c%c%c\n"
  1387. " dwCompressedSize=%d\n"
  1388. " dwNumberOfPackets=%d\n"
  1389. " SourceFormat=%d\n"
  1390. " TR=%d TRB=%d DBQ=%d\n",
  1391. ptrail->dwVersion,
  1392. ptrail->dwFlags,
  1393. ptrail->dwUniqueCode&0xFF, (ptrail->dwUniqueCode>>8)&0xFF,
  1394. (ptrail->dwUniqueCode>>16)&0xFF, (ptrail->dwUniqueCode>>24)&0xFF,
  1395. ptrail->dwCompressedSize,
  1396. ptrail->dwNumberOfPackets,
  1397. ptrail->SourceFormat,
  1398. ptrail->TR,ptrail->TRB,ptrail->DBQ);
  1399. }
  1400. ); /* _SlibDebug */
  1401. #ifdef H261_SUPPORT
  1402. _SlibDebug((_DEBUG_ || _WARN_) && (info->dwRTP!=EC_RTP_MODE_OFF),
  1403. {
  1404. RTPTRAILER_t *ptrail=(RTPTRAILER_t *)
  1405. ((unsigned char *)lpOut+compBytes-sizeof(RTPTRAILER_t));
  1406. SvH261BITSTREAM_INFO *pinfo;
  1407. BOOL rtperror=FALSE;
  1408. unsigned int i;
  1409. pinfo=(SvH261BITSTREAM_INFO *)((unsigned char *)ptrail
  1410. -(ptrail->dwNumberOfPackets*16));
  1411. if (ptrail->dwNumberOfPackets==0 || pinfo[0].dwBitOffset!=0)
  1412. {
  1413. // MessageBox(NULL, "Critical Error in H.261", "Warning", MB_OK);
  1414. rtperror=TRUE;
  1415. }
  1416. /* check for sequential BitOffsets */
  1417. for (i=1; i<ptrail->dwNumberOfPackets; i++)
  1418. if (pinfo[i-1].dwBitOffset>=pinfo[i].dwBitOffset)
  1419. {
  1420. // MessageBox(NULL, "Critical Error in H.261", "Warning", MB_OK);
  1421. rtperror=TRUE;
  1422. break;
  1423. }
  1424. if (pinfo[ptrail->dwNumberOfPackets-1].dwBitOffset>ptrail->dwCompressedSize*8)
  1425. {
  1426. // MessageBox(NULL, "Critical Error in H.261", "Warning", MB_OK);
  1427. rtperror=TRUE;
  1428. }
  1429. if (_DEBUG_ || rtperror)
  1430. {
  1431. if (ptrail->dwNumberOfPackets>64*2)
  1432. ptrail->dwNumberOfPackets=32;
  1433. for (i=0; i<ptrail->dwNumberOfPackets; i++)
  1434. {
  1435. ScDebugPrintf(" H261 Packet %2d: dwFlag=0x%04X dwBitOffset=%d\n"
  1436. " MBAP=%d Quant=%d\n"
  1437. " GOBN=%d HMV=%d VMV=%d\n",
  1438. i, pinfo[i].dwFlag, pinfo[i].dwBitOffset,
  1439. pinfo[i].MBAP, pinfo[i].Quant,
  1440. pinfo[i].GOBN, pinfo[i].HMV, pinfo[i].VMV);
  1441. }
  1442. }
  1443. }
  1444. ); /* _SlibDebug */
  1445. #else /* H263 */
  1446. _SlibDebug((_DEBUG_ || _WARN_) && (info->dwRTP!=EC_RTP_MODE_OFF),
  1447. {
  1448. RTPTRAILER_t *ptrail=(RTPTRAILER_t *)
  1449. ((unsigned char *)lpOut+compBytes-sizeof(RTPTRAILER_t));
  1450. SvH263BITSTREAM_INFO *pinfo;
  1451. BOOL rtperror=FALSE;
  1452. unsigned int i;
  1453. pinfo=(SvH263BITSTREAM_INFO *)((unsigned char *)ptrail
  1454. -(ptrail->dwNumberOfPackets*16));
  1455. if (ptrail->dwNumberOfPackets==0 || pinfo[0].dwBitOffset!=0)
  1456. {
  1457. // MessageBox(NULL, "Critical Error in H.263", "Warning", MB_OK);
  1458. rtperror=TRUE;
  1459. }
  1460. /* check for sequential BitOffsets */
  1461. for (i=1; i<ptrail->dwNumberOfPackets; i++)
  1462. if (pinfo[i-1].dwBitOffset>=pinfo[i].dwBitOffset)
  1463. {
  1464. // MessageBox(NULL, "Critical Error in H.263", "Warning", MB_OK);
  1465. rtperror=TRUE;
  1466. break;
  1467. }
  1468. if (pinfo[ptrail->dwNumberOfPackets-1].dwBitOffset>ptrail->dwCompressedSize*8)
  1469. {
  1470. // MessageBox(NULL, "Critical Error in H.263", "Warning", MB_OK);
  1471. rtperror=TRUE;
  1472. }
  1473. if (_DEBUG_ || rtperror)
  1474. {
  1475. if (ptrail->dwNumberOfPackets>64*2)
  1476. ptrail->dwNumberOfPackets=32;
  1477. for (i=0; i<ptrail->dwNumberOfPackets; i++)
  1478. {
  1479. ScDebugPrintf(" H263 Packet %2d: dwFlag=0x%04X dwBitOffset=%d Mode=%d\n"
  1480. " MBA=%d Quant=%d\n"
  1481. " GOBN=%d HMV1=%d VMV1=%d HMV2=%d VMV2=%d\n",
  1482. i, pinfo[i].dwFlag, pinfo[i].dwBitOffset, pinfo[i].Mode,
  1483. pinfo[i].MBA, pinfo[i].Quant,
  1484. pinfo[i].GOBN, pinfo[i].HMV1, pinfo[i].VMV1,
  1485. pinfo[i].HMV2, pinfo[i].VMV2);
  1486. }
  1487. }
  1488. }
  1489. ); /* _SlibDebug */
  1490. #endif
  1491. bail:
  1492. return status;
  1493. }
  1494. /*
  1495. **++
  1496. ** FUNCTIONAL_NAME: ICH263Decompress
  1497. **
  1498. ** FUNCTIONAL_DESCRIPTION:
  1499. ** Open the Software CODEC
  1500. **
  1501. ** FORMAL PARAMETERS:
  1502. ** driverID
  1503. ** lpbiIn input BITMAPINFOHEADER
  1504. ** lpbiOut output BITMAPINFOHEADER
  1505. **
  1506. ** RETURN VALUE:
  1507. **
  1508. ** COMMENTS:
  1509. **
  1510. ** DESIGN:
  1511. **
  1512. **/
  1513. MMRESULT ICH263Decompress(H26XINFO *info,
  1514. ICDECOMPRESS *icDecompress,
  1515. DWORD dwSize)
  1516. {
  1517. MMRESULT result=(MMRESULT)ICERR_OK;
  1518. LPBITMAPINFOHEADER lpbiIn;
  1519. LPBITMAPINFOHEADER lpbiOut;
  1520. LPVOID lpIn;
  1521. LPVOID lpOut;
  1522. SlibHandle_t Sh;
  1523. SlibStatus_t status;
  1524. #ifdef H261_SUPPORT
  1525. SlibType_t stype = SLIB_TYPE_H261;
  1526. #else
  1527. SlibType_t stype = SLIB_TYPE_H263;
  1528. #endif
  1529. _SlibDebug(_VERBOSE_, ScDebugPrintf("In ICH263Decompress lpIn is %d\n",lpIn) );
  1530. if (!_ICH263CheckFlags(info, ICMODE_DECOMPRESS))
  1531. return((MMRESULT)ICERR_BADHANDLE);
  1532. lpIn = icDecompress->lpInput;
  1533. lpOut = icDecompress->lpOutput;
  1534. lpbiIn = icDecompress->lpbiInput;
  1535. lpbiOut = icDecompress->lpbiOutput;
  1536. if (!info->bDecompressBegun &&
  1537. (result = ICH263DecompressBegin(info, lpbiIn, lpbiOut))!=ICERR_OK)
  1538. return(result);
  1539. if (icDecompress->dwFlags & ICDECOMPRESS_HURRYUP)
  1540. return((MMRESULT)ICERR_OK);
  1541. info->lpbiIn->biSizeImage = lpbiIn->biSizeImage;
  1542. info->lpbiOut->biClrImportant = lpbiOut->biClrImportant;
  1543. info->lpbiOut->biSizeImage = lpbiOut->biSizeImage; // they don't set it
  1544. lpbiIn=info->lpbiIn;
  1545. lpbiOut=info->lpbiOut;
  1546. if (!info->Sh)
  1547. {
  1548. _SlibDebug(_VERBOSE_, ScDebugPrintf("SlibMemUsed = %ld (before SlibOpen)\n", SlibMemUsed()) );
  1549. status = SlibOpenSync (&Sh, SLIB_MODE_DECOMPRESS, &stype, lpIn, icDecompress->lpbiInput->biSizeImage);
  1550. SlibSetParamInt (Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_HEIGHT, lpbiOut->biHeight);
  1551. SlibSetParamInt (Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_WIDTH, lpbiOut->biWidth);
  1552. SlibSetParamInt (Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOFORMAT, lpbiOut->biCompression);
  1553. SlibSetParamInt (Sh, SLIB_STREAM_MAINVIDEO, SLIB_PARAM_VIDEOBITS, lpbiOut->biBitCount);
  1554. info->Sh = Sh;
  1555. _SlibDebug(_WARN_ && status!=SlibErrorNone,
  1556. ScDebugPrintf("ICH263Decompress() SlibOpenSync: %s\n", SlibGetErrorText(status)) );
  1557. }
  1558. else
  1559. {
  1560. DWORD dwPadding=0xFFFFFFFF;
  1561. status=SlibAddBuffer (info->Sh, SLIB_DATA_COMPRESSED, lpIn, icDecompress->lpbiInput->biSizeImage);
  1562. _SlibDebug(_WARN_ && status!=SlibErrorNone,
  1563. ScDebugPrintf("ICH263Decompress() SlibAddBuffer(%p, %d): %s\n",
  1564. lpIn, lpbiIn->biSizeImage, SlibGetErrorText(status)) );
  1565. /* Add some padding bits to the end because the codecs try to peek
  1566. * forward past the very last bits of the buffer
  1567. */
  1568. status=SlibAddBuffer (info->Sh, SLIB_DATA_COMPRESSED, (char *)&dwPadding, sizeof(DWORD));
  1569. }
  1570. if (status==SlibErrorNone)
  1571. {
  1572. #ifdef HANDLE_EXCEPTIONS
  1573. __try {
  1574. #endif /* HANDLE_EXCEPTIONS */
  1575. status = SlibErrorReading; /* in case there's an exception */
  1576. status = SlibReadVideo(info->Sh, SLIB_STREAM_MAINVIDEO, &lpOut, &lpbiOut->biSizeImage);
  1577. #ifdef HANDLE_EXCEPTIONS
  1578. } __finally {
  1579. #endif /* HANDLE_EXCEPTIONS */
  1580. if (status!=SlibErrorNone)
  1581. {
  1582. _SlibDebug(_WARN_ && status!=SlibErrorNone,
  1583. ScDebugPrintf("ICH263Decompress() SlibReadVideo: %s\n", SlibGetErrorText(status)) );
  1584. status=(MMRESULT)ICERR_BADFORMAT;
  1585. }
  1586. else
  1587. status=(MMRESULT)ICERR_OK;
  1588. goto bail;
  1589. #ifdef HANDLE_EXCEPTIONS
  1590. }
  1591. #endif /* HANDLE_EXCEPTIONS */
  1592. }
  1593. else
  1594. status=(MMRESULT)ICERR_BADFORMAT;
  1595. bail:
  1596. return(status);
  1597. }
  1598. /*
  1599. * This routine just nulls out the pValidHandles
  1600. * pointer so that no lingering threads will be
  1601. * able to use it. It's only called at dll
  1602. * shutdown on NT.
  1603. */
  1604. int TerminateH263()
  1605. {
  1606. pValidHandles = NULL;
  1607. return 0;
  1608. }
  1609.