Source code of Windows XP (NT5)
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.

1596 lines
55 KiB

  1. /****************************************************************************
  2. video.c
  3. Contains video APIs
  4. Copyright (c) Microsoft Corporation 1992 - 1995. All rights reserved.
  5. ****************************************************************************/
  6. #include <windows.h>
  7. #include <mmsystem.h>
  8. #include "win32.h"
  9. #include "msviddrv.h"
  10. #include "msvideo.h"
  11. #include <ivideo32.h>
  12. #include "msvideoi.h"
  13. #ifdef WIN32
  14. #include <mmddk.h>
  15. #include <stdlib.h>
  16. #endif
  17. /*****************************************************************************
  18. * Variables
  19. *
  20. ****************************************************************************/
  21. SZCODE szNull[] = TEXT("");
  22. SZCODE szVideo[] = TEXT("msvideo");
  23. #ifndef WIN32
  24. SZCODE szDrivers[] = "Drivers";
  25. #else
  26. STATICDT SZCODE szDrivers[] = DRIVERS_SECTION;
  27. #endif
  28. STATICDT SZCODE szSystemIni[] = TEXT("system.ini");
  29. UINT wTotalVideoDevs; // total video devices
  30. extern HINSTANCE ghInstDll; // our module handle
  31. // ----------------------------------------------------------------------
  32. //
  33. // To clean up when a WOW app exits, we need to maintain a list of
  34. // open devices. A list of HANDLEINFO structs is hung off g_pHandles.
  35. // An item is added to the head of this list in videoOpen, and removed
  36. // in videoClose. When a WOW app exits, winmm will call our WOWAppExit
  37. // function: for each entry in the list that is owned by the exiting thread,
  38. // we call videoClose to close the device and remove the handle entry.
  39. //
  40. // one of these per open handle
  41. typedef struct _HANDLEINFO {
  42. HVIDEO hv;
  43. HANDLE hThread;
  44. struct _HANDLEINFO * pNext;
  45. } HANDLEINFO, * PHANDLEINFO;
  46. // head of global list of open handles
  47. PHANDLEINFO g_pHandles;
  48. // critical section that protects global list
  49. CRITICAL_SECTION csHandles;
  50. // init list and critsec
  51. void
  52. videoInitHandleList()
  53. {
  54. g_pHandles = NULL;
  55. InitializeCriticalSection(&csHandles);
  56. }
  57. // finished with critsec list
  58. void
  59. videoDeleteHandleList()
  60. {
  61. // don't need critical section as no-one else can be using
  62. // it now (we are about to delete the critsec)
  63. // empty everything out of the list
  64. while (g_pHandles) {
  65. videoClose(g_pHandles->hv);
  66. }
  67. DeleteCriticalSection(&csHandles);
  68. }
  69. // add a handle to the list
  70. void
  71. videoAddHandle(HVIDEO hv)
  72. {
  73. PHANDLEINFO pinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLEINFO));
  74. if (!pinfo) {
  75. // couldn't allocate the memory - best thing to do is
  76. // forget it - nothing bad will happen except that we
  77. // might possibly fail to clean up if this is a wow app and
  78. // it exits without closing the capture device.
  79. return;
  80. }
  81. pinfo->hv = hv;
  82. pinfo->hThread = GetCurrentTask();
  83. EnterCriticalSection(&csHandles);
  84. pinfo->pNext = g_pHandles;
  85. g_pHandles = pinfo;
  86. LeaveCriticalSection(&csHandles);
  87. }
  88. // delete an entry from the handle list given the HVIDEO.
  89. // caller must close the HVIDEO
  90. // should be called before closing (in case the HVIDEO is reassigned after
  91. // closing and before removing from the list
  92. void
  93. videoDelete(HVIDEO hv)
  94. {
  95. PHANDLEINFO * ppNext;
  96. PHANDLEINFO pinfo;
  97. EnterCriticalSection(&csHandles);
  98. ppNext = &g_pHandles;
  99. while (*ppNext) {
  100. if ((*ppNext)->hv == hv) {
  101. pinfo = *ppNext;
  102. *ppNext = pinfo->pNext;
  103. HeapFree(GetProcessHeap(), 0, pinfo);
  104. break;
  105. } else {
  106. ppNext = &(*ppNext)->pNext;
  107. }
  108. }
  109. LeaveCriticalSection(&csHandles);
  110. }
  111. // close any handles open by this task
  112. void
  113. AppCleanup(HANDLE hTask)
  114. {
  115. PHANDLEINFO pinfo;
  116. EnterCriticalSection(&csHandles);
  117. pinfo = g_pHandles;
  118. while (pinfo) {
  119. if (pinfo->hThread == hTask) {
  120. // get the next pointer before videoClose deletes the entry
  121. HVIDEO hv = pinfo->hv;
  122. pinfo = pinfo->pNext;
  123. videoClose(hv);
  124. } else {
  125. pinfo = pinfo->pNext;
  126. }
  127. }
  128. LeaveCriticalSection(&csHandles);
  129. }
  130. // ----------------------------------------------------------------------
  131. /*****************************************************************************
  132. * @doc INTERNAL VIDEO validation code for VIDEOHDRs
  133. ****************************************************************************/
  134. #define IsVideoHeaderPrepared(hVideo, lpwh) ((lpwh)->dwFlags & VHDR_PREPARED)
  135. #define MarkVideoHeaderPrepared(hVideo, lpwh) ((lpwh)->dwFlags |= VHDR_PREPARED)
  136. #define MarkVideoHeaderUnprepared(hVideo, lpwh) ((lpwh)->dwFlags &=~VHDR_PREPARED)
  137. /*****************************************************************************
  138. * @doc EXTERNAL VIDEO
  139. *
  140. * @func DWORD | videoMessage | This function sends messages to a
  141. * video device channel.
  142. *
  143. * @parm HVIDEO | hVideo | Specifies the handle to the video device channel.
  144. *
  145. * @parm UINT | wMsg | Specifies the message to send.
  146. *
  147. * @parm DWORD | dwP1 | Specifies the first parameter for the message.
  148. *
  149. * @parm DWORD | dwP2 | Specifies the second parameter for the message.
  150. *
  151. * @rdesc Returns the message specific value returned from the driver.
  152. *
  153. * @comm This function is used for configuration messages such as
  154. * <m DVM_SRC_RECT> and <m DVM_DST_RECT>, and
  155. * device specific messages.
  156. *
  157. * @xref <f videoConfigure>
  158. *
  159. ****************************************************************************/
  160. DWORD WINAPI videoMessage(HVIDEO hVideo, UINT msg, DWORD dwP1, DWORD dwP2)
  161. {
  162. if (!hVideo)
  163. return DV_ERR_INVALHANDLE;
  164. return SendDriverMessage ((HDRVR)hVideo, msg, dwP1, dwP2);
  165. }
  166. /*****************************************************************************
  167. * @doc EXTERNAL VIDEO
  168. *
  169. * @api DWORD | videoGetNumDevs | This function returns the number of MSVIDEO
  170. * devices installed.
  171. *
  172. * @rdesc Returns the number of MSVIDEO devices listed in the
  173. * [drivers] (or [drivers32] for NT) section of the SYSTEM.INI file.
  174. *
  175. * @comm Because the indexes of the MSVIDEO devices in the SYSTEM.INI
  176. * file can be non-contiguous, applications should not assume
  177. * the indexes range between zero and the number of devices minus
  178. * one.
  179. *
  180. * @xref <f videoOpen>
  181. ****************************************************************************/
  182. DWORD WINAPI videoGetNumDevs(void)
  183. {
  184. TCHAR szKey[(sizeof(szVideo)/sizeof(TCHAR)) + 2];
  185. TCHAR szbuf[3];
  186. int i;
  187. wTotalVideoDevs = 0;
  188. lstrcpy(szKey, szVideo);
  189. szKey[(sizeof(szVideo)/sizeof(TCHAR)) - 1] = (TCHAR) 0;
  190. szKey[sizeof(szVideo)/sizeof(TCHAR)] = (TCHAR) 0;
  191. for (i=0; i < MAXVIDEODRIVERS; i++) {
  192. if (GetPrivateProfileString(szDrivers,szKey,szNull,
  193. szbuf,sizeof(szbuf)/sizeof(TCHAR),szSystemIni))
  194. wTotalVideoDevs++;
  195. szKey[(sizeof(szVideo)/sizeof(TCHAR))-1] = (TCHAR) TEXT('1'+ i); // advance driver ordinal
  196. }
  197. return (DWORD)wTotalVideoDevs;
  198. }
  199. /*****************************************************************************
  200. * @doc EXTERNAL VIDEO
  201. *
  202. * @func DWORD | videoGetErrorText | This function retrieves a
  203. * description of the error identified by the error number.
  204. *
  205. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  206. * This might be NULL if the error is not device specific.
  207. *
  208. * @parm UINT | wError | Specifies the error number.
  209. *
  210. * @parm LPSTR | lpText | Specifies a far pointer to a buffer used to
  211. * return the zero-terminated string corresponding to the error number.
  212. *
  213. * @parm UINT | wSize | Specifies the length, in bytes, of the buffer
  214. * referenced by <p lpText>.
  215. *
  216. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  217. * an error number. The following error is defined:
  218. * @flag DV_ERR_BADERRNUM | Specified error number is out of range.
  219. * @flag DV_ERR_SIZEFIELD | The return buffer is not large enough
  220. * to handle the error text.
  221. *
  222. * @comm If the error description is longer than the buffer,
  223. * the description is truncated. The returned error string is always
  224. * zero-terminated. If <p wSize> is zero, nothing is copied and zero
  225. * is returned.
  226. ****************************************************************************/
  227. #ifdef UNICODE // Translate UNICODE response to ansi
  228. DWORD WINAPI videoGetErrorTextA(HVIDEO hVideo, UINT wError,
  229. LPSTR lpText, UINT wSize)
  230. {
  231. VIDEO_GETERRORTEXT_PARMS vet;
  232. if (IsBadWritePtr (lpText, wSize))
  233. return DV_ERR_PARAM1;
  234. lpText[0] = 0;
  235. if (((wError >= DV_ERR_BASE) && (wError <= DV_ERR_LASTERROR))) {
  236. if (wSize > 1) {
  237. if (!LoadStringA(ghInstDll, wError, lpText, wSize))
  238. return DV_ERR_BADERRNUM;
  239. else
  240. return DV_ERR_OK;
  241. }
  242. else
  243. return DV_ERR_SIZEFIELD;
  244. }
  245. else if (wError >= DV_ERR_USER_MSG && hVideo) {
  246. DWORD dwResult;
  247. LPWSTR lpwstr = LocalAlloc(LPTR, wSize*sizeof(WCHAR));
  248. if (NULL == lpwstr) {
  249. return(DV_ERR_NOMEM);
  250. }
  251. vet.dwError = (DWORD) wError;
  252. vet.lpText = lpwstr;
  253. vet.dwLength = (DWORD) wSize;
  254. dwResult = videoMessage (hVideo, DVM_GETERRORTEXT, (DWORD) (LPVOID) &vet,
  255. (DWORD) NULL);
  256. if (DV_ERR_OK == dwResult) {
  257. Iwcstombs(lpText, lpwstr, wSize);
  258. }
  259. LocalFree(lpwstr);
  260. return(dwResult);
  261. }
  262. else
  263. return DV_ERR_BADERRNUM;
  264. }
  265. #endif //UNICODE
  266. //
  267. // The unicode/Win16 equivalent of the above
  268. //
  269. DWORD WINAPI videoGetErrorText(HVIDEO hVideo, UINT wError,
  270. LPTSTR lpText, UINT wSize)
  271. {
  272. VIDEO_GETERRORTEXT_PARMS vet;
  273. lpText[0] = 0;
  274. if (((wError > DV_ERR_BASE) && (wError <= DV_ERR_LASTERROR))) {
  275. if (wSize > 1) {
  276. if (!LoadString(ghInstDll, wError, lpText, wSize))
  277. return DV_ERR_BADERRNUM;
  278. else
  279. return DV_ERR_OK;
  280. }
  281. else
  282. return DV_ERR_SIZEFIELD;
  283. }
  284. else if (wError >= DV_ERR_USER_MSG && hVideo) {
  285. vet.dwError = (DWORD) wError;
  286. vet.lpText = lpText;
  287. vet.dwLength = (DWORD) wSize;
  288. return videoMessage (hVideo, DVM_GETERRORTEXT, (DWORD) (LPVOID) &vet,
  289. (DWORD) NULL);
  290. }
  291. else
  292. return DV_ERR_BADERRNUM;
  293. }
  294. /*****************************************************************************
  295. * @doc EXTERNAL VIDEO
  296. *
  297. * @func DWORD | videoGetChannelCaps | This function retrieves a
  298. * description of the capabilities of a channel.
  299. *
  300. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  301. *
  302. * @parm LPCHANNEL_CAPS | lpChannelCaps | Specifies a far pointer to a
  303. * <t CHANNEL_CAPS> structure.
  304. *
  305. * @parm DWORD | dwSize | Specifies the size, in bytes, of the
  306. * <t CHANNEL_CAPS> structure.
  307. *
  308. * @rdesc Returns zero if the function is successful. Otherwise, it returns
  309. * an error number. The following errors are defined:
  310. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  311. * @flag DV_ERR_UNSUPPORTED | Function is not supported.
  312. *
  313. * @comm The <t CHANNEL_CAPS> structure returns the capability
  314. * information. For example, capability information might
  315. * include whether or not the channel can crop and scale images,
  316. * or show overlay.
  317. ****************************************************************************/
  318. DWORD WINAPI videoGetChannelCaps(HVIDEO hVideo, LPCHANNEL_CAPS lpChannelCaps,
  319. DWORD dwSize)
  320. {
  321. if (!hVideo)
  322. return DV_ERR_INVALHANDLE;
  323. if (IsBadWritePtr (lpChannelCaps, sizeof (CHANNEL_CAPS)))
  324. return DV_ERR_PARAM1;
  325. // _fmemset (lpChannelCaps, 0, sizeof (CHANNEL_CAPS));
  326. lpChannelCaps->dwFlags = 0;
  327. lpChannelCaps->dwSrcRectXMod = 0;
  328. lpChannelCaps->dwSrcRectYMod = 0;
  329. lpChannelCaps->dwSrcRectWidthMod = 0;
  330. lpChannelCaps->dwSrcRectHeightMod = 0;
  331. lpChannelCaps->dwDstRectXMod = 0;
  332. lpChannelCaps->dwDstRectYMod = 0;
  333. lpChannelCaps->dwDstRectWidthMod = 0;
  334. lpChannelCaps->dwDstRectHeightMod = 0;
  335. return videoMessage(hVideo, DVM_GET_CHANNEL_CAPS, (DWORD) lpChannelCaps,
  336. (DWORD) dwSize);
  337. }
  338. /*****************************************************************************
  339. * @doc EXTERNAL VIDEO
  340. *
  341. * @func DWORD | videoUpdate | This function directs a channel to
  342. * repaint the display. It applies only to VIDEO_EXTERNALOUT channels.
  343. *
  344. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  345. *
  346. * @parm HWND | hWnd | Specifies the handle of the window to be used
  347. * by the channel for image display.
  348. *
  349. * @parm HDC | hDC | Specifies a handle to a device context.
  350. *
  351. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  352. * an error number. The following errors are defined:
  353. * @flag DV_ERR_UNSUPPORTED | Specified message is unsupported.
  354. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  355. *
  356. * @comm This message is normally sent
  357. * whenever the client window receives a <m WM_MOVE>, <m WM_SIZE>,
  358. * or <m WM_PAINT> message.
  359. ****************************************************************************/
  360. DWORD WINAPI videoUpdate (HVIDEO hVideo, HWND hWnd, HDC hDC)
  361. {
  362. if ((!hVideo) || (!hWnd) || (!hDC) )
  363. return DV_ERR_INVALHANDLE;
  364. return videoMessage(hVideo, DVM_UPDATE, (DWORD) hWnd, (DWORD) hDC);
  365. }
  366. /*****************************************************************************
  367. * @doc EXTERNAL VIDEO
  368. *
  369. * @api DWORD | videoOpen | This function opens a channel on the
  370. * specified video device.
  371. *
  372. * @parm LPHVIDEO | lphvideo | Specifies a far pointer to a buffer
  373. * used to return an <t HVIDEO> handle. The video capture driver
  374. * uses this location to return
  375. * a handle that uniquely identifies the opened video device channel.
  376. * Use the returned handle to identify the device channel when
  377. * calling other video functions.
  378. *
  379. * @parm DWORD | dwDeviceID | Identifies the video device to open.
  380. * The value of <p dwDeviceID> varies from zero to one less
  381. * than the number of video capture devices installed in the system.
  382. *
  383. * @parm DWORD | dwFlags | Specifies flags for opening the device.
  384. * The following flags are defined:
  385. *
  386. * @flag VIDEO_EXTERNALIN| Specifies the channel is opened
  387. * for external input. Typically, external input channels
  388. * capture images into a frame buffer.
  389. *
  390. * @flag VIDEO_EXTERNALOUT| Specifies the channel is opened
  391. * for external output. Typically, external output channels
  392. * display images stored in a frame buffer on an auxilary monitor
  393. * or overlay.
  394. *
  395. * @flag VIDEO_IN| Specifies the channel is opened
  396. * for video input. Video input channels transfer images
  397. * from a frame buffer to system memory buffers.
  398. *
  399. * @flag VIDEO_OUT| Specifies the channel is opened
  400. * for video output. Video output channels transfer images
  401. * from system memory buffers to a frame buffer.
  402. *
  403. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  404. * an error number. The following errors are defined:
  405. * @flag DV_ERR_BADDEVICEID | Indicates the specified device ID is out of range.
  406. * @flag DV_ERR_ALLOCATED | Indicates the specified resource is already allocated.
  407. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  408. *
  409. * @comm
  410. * At a minimum, all capture drivers support a VIDEO_EXTERNALIN
  411. * and a VIDEO_IN channel.
  412. * Use <f videoGetNumDevs> to determine the number of video
  413. * devices present in the system.
  414. *
  415. * @xref <f videoClose>
  416. ****************************************************************************/
  417. DWORD WINAPI videoOpen (LPHVIDEO lphVideo, DWORD dwDeviceID, DWORD dwFlags)
  418. {
  419. TCHAR szKey[sizeof(szVideo)/sizeof(TCHAR) + 2];
  420. TCHAR szbuf[128];
  421. UINT w;
  422. VIDEO_OPEN_PARMS vop; // Same as IC_OPEN struct!!!
  423. DWORD dwVersion = VIDEOAPIVERSION;
  424. if (IsBadWritePtr ((LPVOID) lphVideo, sizeof (HVIDEO)) )
  425. return DV_ERR_PARAM1;
  426. vop.dwSize = sizeof (VIDEO_OPEN_PARMS);
  427. vop.fccType = OPEN_TYPE_VCAP; // "vcap"
  428. vop.fccComp = 0L;
  429. vop.dwVersion = VIDEOAPIVERSION;
  430. vop.dwFlags = dwFlags; // In, Out, External In, External Out
  431. vop.dwError = DV_ERR_OK;
  432. w = (UINT)dwDeviceID;
  433. *lphVideo = NULL;
  434. if (!wTotalVideoDevs) // trying to open without finding how many devs.
  435. videoGetNumDevs();
  436. if (!wTotalVideoDevs) // No drivers installed
  437. return DV_ERR_BADINSTALL;
  438. if (w >= MAXVIDEODRIVERS)
  439. return DV_ERR_BADDEVICEID;
  440. lstrcpy(szKey, szVideo);
  441. szKey[(sizeof(szVideo)/sizeof(TCHAR)) - 1] = (TCHAR)0;
  442. if( w > 0 ) {
  443. szKey[(sizeof(szVideo)/sizeof(TCHAR))] = (TCHAR)0;
  444. szKey[(sizeof(szVideo)/sizeof(TCHAR))-1] = (TCHAR) TEXT('1' + (w-1) ); // driver ordinal
  445. }
  446. if (GetPrivateProfileString(szDrivers, szKey, szNull,
  447. szbuf, sizeof(szbuf)/sizeof(TCHAR), szSystemIni)) {
  448. #ifdef THIS_IS_ANCIENT_CODE
  449. // Removed for VFW1.1
  450. // Only early Alpha 1.0 drivers required this...
  451. // Check driver version number by doing a configuration open...
  452. // Version 1 used LPARAM = dwFlags
  453. // Version 2 uses LPARAM = LPVIDEO_OPEN_PARMS
  454. if (hVideoTemp = OpenDriver(szKey, szDrivers, (LPARAM) NULL)) {
  455. HVIDEO hVideoTemp;
  456. // Version 1 drivers had the added bug of returning
  457. // the version from this message, instead of in
  458. // lParam1
  459. if (videoMessage (hVideoTemp, DVM_GETVIDEOAPIVER,
  460. (LPARAM) (LPVOID) &dwVersion, 0L) == 1)
  461. dwVersion = 1;
  462. CloseDriver(hVideoTemp, 0L, 0L );
  463. }
  464. if (dwVersion == 1)
  465. *lphVideo = OpenDriver(szKey, szDrivers, dwFlags);
  466. else
  467. #endif // THIS_IS_ANCIENT_CODE
  468. *lphVideo = (HVIDEO)OpenDriver(szKey, szDrivers, (LPARAM) (LPVOID) &vop);
  469. if( ! *lphVideo ) {
  470. if (vop.dwError) // if driver returned an error code...
  471. return vop.dwError;
  472. else {
  473. #ifdef WIN32
  474. if (GetFileAttributes(szbuf) == (DWORD) -1)
  475. #else
  476. OFSTRUCT of;
  477. if (OpenFile (szbuf, &of, OF_EXIST) == HFILE_ERROR)
  478. #endif
  479. return (DV_ERR_BADINSTALL);
  480. else
  481. return (DV_ERR_NOTDETECTED);
  482. }
  483. }
  484. } else {
  485. return( DV_ERR_BADINSTALL );
  486. }
  487. videoAddHandle(*lphVideo);
  488. return DV_ERR_OK;
  489. }
  490. /*****************************************************************************
  491. * @doc EXTERNAL VIDEO
  492. *
  493. * @api DWORD | videoClose | This function closes the specified video
  494. * device channel.
  495. *
  496. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  497. * If this function is successful, the handle is invalid
  498. * after this call.
  499. *
  500. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  501. * an error number. The following errors are defined:
  502. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  503. * @flag DV_ERR_NONSPECIFIC | The driver failed to close the channel.
  504. *
  505. * @comm If buffers have been sent with <f videoStreamAddBuffer> and
  506. * they haven't been returned to the application,
  507. * the close operation fails. You can use <f videoStreamReset> to mark all
  508. * pending buffers as done.
  509. *
  510. * @xref <f videoOpen> <f videoStreamInit> <f videoStreamFini> <f videoStreamReset>
  511. ****************************************************************************/
  512. DWORD WINAPI videoClose (HVIDEO hVideo)
  513. {
  514. if (!hVideo)
  515. return DV_ERR_INVALHANDLE;
  516. videoDelete(hVideo);
  517. return (CloseDriver((HDRVR)hVideo, 0L, 0L ) ? DV_ERR_OK : DV_ERR_NONSPECIFIC);
  518. }
  519. /*****************************************************************************
  520. * @doc EXTERNAL VIDEO
  521. *
  522. * @api DWORD | videoConfigure | This function sets or retrieves
  523. * the options for a configurable driver.
  524. *
  525. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  526. *
  527. * @parm UINT | msg | Specifies the option to set or retrieve. The
  528. * following options are defined:
  529. *
  530. * @flag DVM_PALETTE | Indicates a palette is being sent to the driver
  531. * or retrieved from the driver.
  532. *
  533. * @flag DVM_PALETTERGB555 | Indicates an RGB555 palette is being
  534. * sent to the driver.
  535. *
  536. * @flag DVM_FORMAT | Indicates format information is being sent to
  537. * the driver or retrieved from the driver.
  538. *
  539. * @parm DWORD | dwFlags | Specifies flags for configuring or
  540. * interrogating the device driver. The following flags are defined:
  541. *
  542. * @flag VIDEO_CONFIGURE_SET | Indicates values are being sent to the driver.
  543. *
  544. * @flag VIDEO_CONFIGURE_GET | Indicates values are being obtained from the driver.
  545. *
  546. * @flag VIDEO_CONFIGURE_QUERY | Determines if the
  547. * driver supports the option specified by <p msg>. This flag
  548. * should be combined with either the VIDEO_CONFIGURE_SET or
  549. * VIDEO_CONFIGURE_GET flag. If this flag is
  550. * set, the <p lpData1>, <p dwSize1>, <p lpData2>, and <p dwSize2>
  551. * parameters are ignored.
  552. *
  553. * @flag VIDEO_CONFIGURE_QUERYSIZE | Returns the size, in bytes,
  554. * of the configuration option in <p lpdwReturn>. This flag is only valid if
  555. * the VIDEO_CONFIGURE_GET flag is also set.
  556. *
  557. * @flag VIDEO_CONFIGURE_CURRENT | Requests the current value.
  558. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  559. * @flag VIDEO_CONFIGURE_NOMINAL | Requests the nominal value.
  560. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  561. * @flag VIDEO_CONFIGURE_MIN | Requests the minimum value.
  562. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  563. * @flag VIDEO_CONFIGURE_MAX | Get the maximum value.
  564. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  565. *
  566. * @parm LPDWORD | lpdwReturn | Points to a DWORD used for returning information
  567. * from the driver. If
  568. * the VIDEO_CONFIGURE_QUERYSIZE flag is set, <p lpdwReturn> is
  569. * filled with the size of the configuration option.
  570. *
  571. * @parm LPVOID | lpData1 |Specifies a pointer to message specific data.
  572. *
  573. * @parm DWORD | dwSize1 | Specifies the size, in bytes, of the <p lpData1>
  574. * buffer.
  575. *
  576. * @parm LPVOID | lpData2 | Specifies a pointer to message specific data.
  577. *
  578. * @parm DWORD | dwSize2 | Specifies the size, in bytes, of the <p lpData2>
  579. * buffer.
  580. *
  581. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  582. * an error number. The following errors are defined:
  583. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  584. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  585. *
  586. * @xref <f videoOpen> <f videoMessage>
  587. *
  588. ****************************************************************************/
  589. DWORD WINAPI videoConfigure (HVIDEO hVideo, UINT msg, DWORD dwFlags,
  590. LPDWORD lpdwReturn, LPVOID lpData1, DWORD dwSize1,
  591. LPVOID lpData2, DWORD dwSize2)
  592. {
  593. VIDEOCONFIGPARMS vcp;
  594. if (!hVideo)
  595. return DV_ERR_INVALHANDLE;
  596. if (lpData1)
  597. if (IsBadHugeReadPtr (lpData1, dwSize1))
  598. return DV_ERR_CONFIG1;
  599. if (lpData2)
  600. if (IsBadHugeReadPtr (lpData2, dwSize2))
  601. return DV_ERR_CONFIG2;
  602. if (dwFlags & VIDEO_CONFIGURE_QUERYSIZE) {
  603. if (!lpdwReturn)
  604. return DV_ERR_NONSPECIFIC;
  605. if (IsBadWritePtr (lpdwReturn, sizeof (DWORD)) )
  606. return DV_ERR_NONSPECIFIC;
  607. }
  608. vcp.lpdwReturn = lpdwReturn;
  609. vcp.lpData1 = lpData1;
  610. vcp.dwSize1 = dwSize1;
  611. vcp.lpData2 = lpData2;
  612. vcp.dwSize2 = dwSize2;
  613. return videoMessage(hVideo, msg, dwFlags,
  614. (DWORD)(LPVIDEOCONFIGPARMS)&vcp );
  615. }
  616. /*****************************************************************************
  617. * @doc EXTERNAL VIDEO
  618. *
  619. * @api DWORD | videoConfigureStorage | This function saves or loads
  620. * all configurable options for a channel. Options
  621. * can be saved and recalled for each application or each application
  622. * instance.
  623. *
  624. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  625. *
  626. * @parm LPSTR | lpstrIdent | Identifies the application or instance.
  627. * Use an arbitrary string which uniquely identifies your application
  628. * or instance.
  629. *
  630. * @parm DWORD | dwFlags | Specifies any flags for the function. The following
  631. * flags are defined:
  632. * @flag VIDEO_CONFIGURE_GET | Requests that the values be loaded.
  633. * @flag VIDEO_CONFIGURE_SET | Requests that the values be saved.
  634. *
  635. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  636. * an error number. The following errors are defined:
  637. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  638. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  639. *
  640. * @comm The method used by a driver to save configuration options is
  641. * device dependent.
  642. *
  643. * @xref <f videoOpen>
  644. ****************************************************************************/
  645. #ifdef UNICODE
  646. DWORD WINAPI videoConfigureStorageA(HVIDEO hVideo,
  647. LPSTR lpstrIdent, DWORD dwFlags)
  648. {
  649. DWORD ret;
  650. LPWSTR lpwstr;
  651. if (!hVideo)
  652. return DV_ERR_INVALHANDLE;
  653. // Convert the input string to Unicode
  654. // Call the driver, free the Unicode string and return the result
  655. ret = strlen(lpstrIdent);
  656. lpwstr = LocalAlloc(LPTR, ret*sizeof(WCHAR));
  657. if (!lpwstr) {
  658. return(DV_ERR_NOMEM);
  659. }
  660. Imbstowcs(lpwstr, lpstrIdent, ret);
  661. ret = videoMessage(hVideo, DVM_CONFIGURESTORAGE,
  662. (DWORD)lpwstr, dwFlags);
  663. LocalFree(lpwstr);
  664. return(ret);
  665. }
  666. #endif
  667. // On NT the header file will have ensured that videoConfigureStorage is
  668. // defined by a macro to videoConfigureStorageW
  669. DWORD WINAPI videoConfigureStorage(HVIDEO hVideo,
  670. LPWSTR lpstrIdent, DWORD dwFlags)
  671. {
  672. if (!hVideo)
  673. return DV_ERR_INVALHANDLE;
  674. return videoMessage(hVideo, DVM_CONFIGURESTORAGE,
  675. (DWORD)lpstrIdent, dwFlags);
  676. }
  677. /*****************************************************************************
  678. * @doc EXTERNAL VIDEO
  679. *
  680. * @api DWORD | videoDialog | This function displays a channel-specific
  681. * dialog box used to set configuration parameters.
  682. *
  683. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  684. *
  685. * @parm HWND | hWndParent | Specifies the parent window handle.
  686. *
  687. * @parm DWORD | dwFlags | Specifies flags for the dialog box. The
  688. * following flag is defined:
  689. * @flag VIDEO_DLG_QUERY | If this flag is set, the driver immediately
  690. * returns zero if it supplies a dialog box for the channel,
  691. * or DV_ERR_NOTSUPPORTED if it does not.
  692. *
  693. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  694. * an error number. The following errors are defined:
  695. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  696. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  697. *
  698. * @comm Typically, each dialog box displayed by this
  699. * function lets the user select options appropriate for the channel.
  700. * For example, a VIDEO_IN channel dialog box lets the user select
  701. * the image dimensions and bit depth.
  702. *
  703. * @xref <f videoOpen> <f videoConfigureStorage>
  704. ****************************************************************************/
  705. DWORD WINAPI videoDialog (HVIDEO hVideo, HWND hWndParent, DWORD dwFlags)
  706. {
  707. if (!hVideo)
  708. return DV_ERR_INVALHANDLE;
  709. if ((!hWndParent) || (!IsWindow (hWndParent)) )
  710. return DV_ERR_INVALHANDLE;
  711. return videoMessage(hVideo, DVM_DIALOG, (DWORD)hWndParent, dwFlags);
  712. }
  713. //////////////////////////////////////////////////////////////////////////
  714. //////////////////////////////////////////////////////////////////////////
  715. /*****************************************************************************
  716. * @doc INTERNAL VIDEO
  717. *
  718. * @api DWORD | videoPrepareHeader | This function prepares the
  719. * header and data
  720. * by performing a <f GlobalPageLock>.
  721. *
  722. * @rdesc Returns zero if the function was successful. Otherwise, it
  723. * specifies an error number.
  724. ****************************************************************************/
  725. DWORD WINAPI videoPrepareHeader(LPVIDEOHDR lpVideoHdr, DWORD dwSize)
  726. {
  727. if (!HugePageLock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR)))
  728. return DV_ERR_NOMEM;
  729. if (!HugePageLock(lpVideoHdr->lpData, lpVideoHdr->dwBufferLength)) {
  730. HugePageUnlock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR));
  731. return DV_ERR_NOMEM;
  732. }
  733. lpVideoHdr->dwFlags |= VHDR_PREPARED;
  734. return DV_ERR_OK;
  735. }
  736. /*****************************************************************************
  737. * @doc INTERNAL VIDEO
  738. *
  739. * @api DWORD | videoUnprepareHeader | This function unprepares the header and
  740. * data if the driver returns DV_ERR_NOTSUPPORTED.
  741. *
  742. * @rdesc Currently always returns DV_ERR_OK.
  743. ****************************************************************************/
  744. DWORD WINAPI videoUnprepareHeader(LPVIDEOHDR lpVideoHdr, DWORD dwSize)
  745. {
  746. HugePageUnlock(lpVideoHdr->lpData, lpVideoHdr->dwBufferLength);
  747. HugePageUnlock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR));
  748. lpVideoHdr->dwFlags &= ~VHDR_PREPARED;
  749. return DV_ERR_OK;
  750. }
  751. //////////////////////////////////////////////////////////////////////////
  752. //////////////////////////////////////////////////////////////////////////
  753. /*****************************************************************************
  754. * @doc EXTERNAL VIDEO
  755. *
  756. * @api DWORD | videoStreamAllocHdrAndBuffer | This function is used to allow
  757. * drivers to optionally allocate video buffers. Normally, the client
  758. * application is responsible for allocating buffer memory, but devices
  759. * which have on-board memory may optionally allocate headers and buffers
  760. * using this function. Generally, this will avoid an additional data copy,
  761. * resulting in faster capture rates.
  762. *
  763. * @parm HVIDEO | hVideo | Specifies a handle to the video
  764. * device channel.
  765. *
  766. * @parm LPVIDEOHDR FAR * | plpvideoHdr | Specifies a pointer to the address of a
  767. * <t VIDEOHDR> structure. The driver saves the buffer address in this
  768. * location, or NULL if it cannot allocate a buffer.
  769. *
  770. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure
  771. * and associated video buffer in bytes.
  772. *
  773. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  774. * an error number. The following errors are defined:
  775. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  776. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  777. * @flag DV_ERR_NOTSUPPORTED | Indicates the driver does not have on-board memory.
  778. *
  779. * @comm If the driver
  780. * allocates buffers via this method, the <f videoStreamPrepareHeader> and
  781. * <f videoStreamUnprepareHeader> functions should be used.
  782. *
  783. * The buffer allocated must be accessible for DMA by the host.
  784. *
  785. * @xref <f videoStreamPrepareHeader>
  786. ****************************************************************************/
  787. DWORD WINAPI videoStreamAllocHdrAndBuffer(HVIDEO hVideo,
  788. LPVIDEOHDR FAR * plpvideoHdr, DWORD dwSize)
  789. {
  790. #ifdef OBSOLETE
  791. DWORD wRet;
  792. if (!hVideo)
  793. return DV_ERR_INVALHANDLE;
  794. if (IsBadWritePtr (plpvideoHdr, sizeof (VIDEOHDR *)) )
  795. return DV_ERR_PARAM1;
  796. *plpvideoHdr = NULL; // Init to NULL ptr
  797. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_ALLOCHDRANDBUFFER,
  798. (DWORD)plpvideoHdr, (DWORD)dwSize);
  799. if (*plpvideoHdr == NULL ||
  800. IsBadHugeWritePtr (*plpvideoHdr, dwSize)) {
  801. DebugErr(DBF_WARNING,"videoStreamAllocHdrAndBuffer: Allocation failed.");
  802. *plpvideoHdr = NULL;
  803. return wRet;
  804. }
  805. if (IsVideoHeaderPrepared(HVIDEO, *plpvideoHdr))
  806. {
  807. DebugErr(DBF_WARNING,"videoStreamAllocHdrAndBuffer: header is already prepared.");
  808. return DV_ERR_OK;
  809. }
  810. (*plpvideoHdr)->dwFlags = 0;
  811. if (wRet == DV_ERR_OK)
  812. MarkVideoHeaderPrepared(hVideo, *plpvideoHdr);
  813. return wRet;
  814. #endif
  815. return DV_ERR_NOTSUPPORTED;
  816. }
  817. /*****************************************************************************
  818. * @doc EXTERNAL VIDEO
  819. *
  820. * @api DWORD | videoStreamFreeHdrAndBuffer | This function is used to free
  821. * buffers allocated by the driver using the <f videoStreamAllocHdrAndBuffer>
  822. * function.
  823. *
  824. * @parm HVIDEO | hVideo | Specifies a handle to the video
  825. * device channel.
  826. *
  827. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to the
  828. * <t VIDEOHDR> structure and associated buffer to be freed.
  829. *
  830. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  831. * an error number. The following errors are defined:
  832. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  833. * @flag DV_ERR_NOTSUPPORTED | Indicates the driver does not have on-board memory.
  834. *
  835. * @comm If the driver
  836. * allocates buffers via this method, the <f videoStreamPrepareHeader> and
  837. * <f videoStreamUnprepareHeader> functions should be used.
  838. *
  839. * @xref <f videoStreamPrepareHeader>
  840. ****************************************************************************/
  841. DWORD WINAPI videoStreamFreeHdrAndBuffer(HVIDEO hVideo,
  842. LPVIDEOHDR lpvideoHdr)
  843. {
  844. #ifdef OBSOLETE
  845. DWORD wRet;
  846. if (!hVideo)
  847. return DV_ERR_INVALHANDLE;
  848. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  849. return DV_ERR_PARAM1;
  850. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  851. {
  852. DebugErr(DBF_WARNING, "videoStreamFreeHdrAndBuffer: buffer still in queue.");
  853. return DV_ERR_STILLPLAYING;
  854. }
  855. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  856. {
  857. DebugErr(DBF_WARNING,"videoStreamFreeHdrAndBuffer: header is not prepared.");
  858. }
  859. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_FREEHDRANDBUFFER,
  860. (DWORD)lpvideoHdr, (DWORD)0);
  861. if (wRet != DV_ERR_OK)
  862. {
  863. DebugErr(DBF_WARNING,"videoStreamFreeHdrAndBuffer: Error freeing buffer.");
  864. }
  865. return wRet;
  866. #endif
  867. return DV_ERR_NOTSUPPORTED;
  868. }
  869. /*****************************************************************************
  870. * @doc EXTERNAL VIDEO
  871. *
  872. * @api DWORD | videoStreamPrepareHeader | This function prepares a buffer
  873. * for video streaming.
  874. *
  875. * @parm HVIDEO | hVideo | Specifies a handle to the video
  876. * device channel.
  877. *
  878. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to a
  879. * <t VIDEOHDR> structure identifying the buffer to be prepared.
  880. *
  881. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  882. *
  883. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  884. * an error number. The following errors are defined:
  885. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  886. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  887. *
  888. * @comm Use this function after <f videoStreamInit> or
  889. * after <f videoStreamReset> to prepare the data buffers
  890. * for streaming data.
  891. *
  892. * The <t VIDEOHDR> data structure and the data block pointed to by its
  893. * <e VIDEOHDR.lpData> member must be allocated with <f GlobalAlloc> using the
  894. * GMEM_MOVEABLE and GMEM_SHARE flags, and locked with <f GlobalLock>.
  895. * Preparing a header that has already been prepared will have no effect
  896. * and the function will return zero. Typically, this function is used
  897. * to ensure that the buffer will be available for use at interrupt time.
  898. *
  899. * @xref <f videoStreamUnprepareHeader>
  900. ****************************************************************************/
  901. DWORD WINAPI videoStreamPrepareHeader(HVIDEO hVideo,
  902. LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  903. {
  904. DWORD wRet;
  905. if (!hVideo)
  906. return DV_ERR_INVALHANDLE;
  907. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  908. return DV_ERR_PARAM1;
  909. if (IsVideoHeaderPrepared(HVIDEO, lpvideoHdr))
  910. {
  911. DebugErr(DBF_WARNING,"videoStreamPrepareHeader: header is already prepared.");
  912. return DV_ERR_OK;
  913. }
  914. lpvideoHdr->dwFlags = 0;
  915. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_PREPAREHEADER,
  916. (DWORD)lpvideoHdr, (DWORD)dwSize);
  917. if (wRet == DV_ERR_NOTSUPPORTED)
  918. wRet = videoPrepareHeader(lpvideoHdr, dwSize);
  919. if (wRet == DV_ERR_OK)
  920. MarkVideoHeaderPrepared(hVideo, lpvideoHdr);
  921. return wRet;
  922. }
  923. /*****************************************************************************
  924. * @doc EXTERNAL VIDEO
  925. *
  926. * @api DWORD | videoStreamUnprepareHeader | This function clears the
  927. * preparation performed by <f videoStreamPrepareHeader>.
  928. *
  929. * @parm HVIDEO | hVideo | Specifies a handle to the video
  930. * device channel.
  931. *
  932. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to a <t VIDEOHDR>
  933. * structure identifying the data buffer to be unprepared.
  934. *
  935. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  936. *
  937. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  938. * an error number. The following errors are defined:
  939. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  940. * @flag DV_ERR_STILLPLAYING | Indicates the structure identified by <p lpvideoHdr>
  941. * is still in the queue.
  942. *
  943. * @comm This function is the complementary function to <f videoStreamPrepareHeader>.
  944. * You must call this function before freeing the data buffer with <f GlobalFree>.
  945. * After passing a buffer to the device driver with <f videoStreamAddBuffer>, you
  946. * must wait until the driver is finished with the buffer before calling
  947. * <f videoStreamUnprepareHeader>. Unpreparing a buffer that has not been
  948. * prepared or has been already unprepared has no effect,
  949. * and the function returns zero.
  950. *
  951. * @xref <f videoStreamPrepareHeader>
  952. ****************************************************************************/
  953. DWORD WINAPI videoStreamUnprepareHeader(HVIDEO hVideo, LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  954. {
  955. DWORD wRet;
  956. if (!hVideo)
  957. return DV_ERR_INVALHANDLE;
  958. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  959. return DV_ERR_PARAM1;
  960. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  961. {
  962. DebugErr(DBF_WARNING, "videoStreamUnprepareHeader: buffer still in queue.");
  963. return DV_ERR_STILLPLAYING;
  964. }
  965. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  966. {
  967. DebugErr(DBF_WARNING,"videoStreamUnprepareHeader: header is not prepared.");
  968. return DV_ERR_OK;
  969. }
  970. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_UNPREPAREHEADER,
  971. (DWORD)lpvideoHdr, (DWORD)dwSize);
  972. if (wRet == DV_ERR_NOTSUPPORTED)
  973. wRet = videoUnprepareHeader(lpvideoHdr, dwSize);
  974. if (wRet == DV_ERR_OK)
  975. MarkVideoHeaderUnprepared(hVideo, lpvideoHdr);
  976. return wRet;
  977. }
  978. /*****************************************************************************
  979. * @doc EXTERNAL VIDEO
  980. *
  981. * @api DWORD | videoStreamAddBuffer | This function sends a buffer to a
  982. * video-capture device. After the buffer is filled by the device,
  983. * the device sends it back to the application.
  984. *
  985. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  986. *
  987. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a far pointer to a <t VIDEOHDR>
  988. * structure that identifies the buffer.
  989. *
  990. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  991. *
  992. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  993. * an error number. The following errors are defined:
  994. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  995. * @flag DV_ERR_UNPREPARED | Indicates the <p lpvideoHdr> structure hasn't been prepared.
  996. * @flag DV_ERR_STILLPLAYING | Indicates a buffer is still in the queue.
  997. * @flag DV_ERR_PARAM1 | The <p lpvideoHdr> parameter is invalid or
  998. * the <e VIDEOHDR.dwBufferLength> member of the <t VIDEOHDR>
  999. * structure is not set to the proper value.
  1000. *
  1001. * @comm The data buffer must be prepared with <f videoStreamPrepareHeader>
  1002. * before it is passed to <f videoStreamAddBuffer>. The <t VIDEOHDR> data
  1003. * structure and the data buffer referenced by its <e VIDEOHDR.lpData>
  1004. * member must be allocated with <f GlobalAlloc> using the GMEM_MOVEABLE
  1005. * and GMEM_SHARE flags, and locked with <f GlobalLock>. Set the
  1006. * <e VIDEOHDR.dwBufferLength> member to the size of the header.
  1007. *
  1008. * @xref <f videoStreamPrepareHeader>
  1009. ****************************************************************************/
  1010. DWORD WINAPI videoStreamAddBuffer(HVIDEO hVideo, LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  1011. {
  1012. if (!hVideo)
  1013. return DV_ERR_INVALHANDLE;
  1014. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1015. return DV_ERR_PARAM1;
  1016. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  1017. {
  1018. DebugErr(DBF_WARNING, "videoStreamAddBuffer: buffer not prepared.");
  1019. return DV_ERR_UNPREPARED;
  1020. }
  1021. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  1022. {
  1023. DebugErr(DBF_WARNING, "videoStreamAddBuffer: buffer already in queue.");
  1024. return DV_ERR_STILLPLAYING;
  1025. }
  1026. return (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_ADDBUFFER, (DWORD)lpvideoHdr, (DWORD)dwSize);
  1027. }
  1028. /*****************************************************************************
  1029. * @doc EXTERNAL VIDEO
  1030. *
  1031. * @api DWORD | videoStreamStop | This function stops streaming on a video channel.
  1032. *
  1033. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1034. * device channel.
  1035. *
  1036. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1037. * an error number. The following error is defined:
  1038. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1039. *
  1040. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1041. * function.
  1042. * @comm If there are any buffers in the queue, the current buffer will be
  1043. * marked as done (the <e VIDEOHDR.dwBytesRecorded> member in
  1044. * the <t VIDEOHDR> header will contain the actual length of data), but any
  1045. * empty buffers in the queue will remain there. Calling this
  1046. * function when the channel is not started has no effect, and the
  1047. * function returns zero.
  1048. *
  1049. * @xref <f videoStreamStart> <f videoStreamReset>
  1050. ****************************************************************************/
  1051. DWORD WINAPI videoStreamStop(HVIDEO hVideo)
  1052. {
  1053. if (!hVideo)
  1054. return DV_ERR_INVALHANDLE;
  1055. return videoMessage((HVIDEO)hVideo, DVM_STREAM_STOP, 0L, 0L);
  1056. }
  1057. /*****************************************************************************
  1058. * @doc EXTERNAL VIDEO
  1059. *
  1060. * @api DWORD | videoStreamReset | This function stops streaming
  1061. * on the specified video device channel and resets the current position
  1062. * to zero. All pending buffers are marked as done and
  1063. * are returned to the application.
  1064. *
  1065. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1066. *
  1067. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1068. * an error number. The following errors are defined:
  1069. *
  1070. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1071. *
  1072. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1073. * function.
  1074. *
  1075. * @xref <f videoStreamReset> <f videoStreamStop> <f videoStreamAddBuffer> <f videoStreamClose>
  1076. /****************************************************************************/
  1077. DWORD WINAPI videoStreamReset(HVIDEO hVideo)
  1078. {
  1079. if (!hVideo)
  1080. return DV_ERR_INVALHANDLE;
  1081. return videoMessage((HVIDEO)hVideo, DVM_STREAM_RESET, 0L, 0L);
  1082. }
  1083. /*****************************************************************************
  1084. * @doc EXTERNAL VIDEO
  1085. *
  1086. * @api DWORD | videoStreamGetPosition | This function retrieves the current
  1087. * position of the specified video device channel.
  1088. *
  1089. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1090. *
  1091. * @parm LPMMTIME | lpInfo | Specifies a far pointer to an <t MMTIME>
  1092. * structure.
  1093. *
  1094. * @parm DWORD | dwSize | Specifies the size of the <t MMTIME> structure in bytes.
  1095. *
  1096. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1097. * an error number. The following errors are defined:
  1098. *
  1099. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1100. *
  1101. * @comm Before using <f videoStreamGetPosition>, set the
  1102. * <e MMTIME.wType> member of the <t MMTIME> structure to indicate
  1103. * the time format desired. After
  1104. * <f videoStreamGetPosition> returns, check the <e MMTIME.wType>
  1105. * member to determine if the your time format is supported. If
  1106. * not, <e MMTIME.wType> specifies an alternate format.
  1107. * Video capture drivers typically provide the millisecond time
  1108. * format.
  1109. *
  1110. * The position is set to zero when streaming is started with
  1111. * <f videoStreamStart>.
  1112. ****************************************************************************/
  1113. DWORD WINAPI videoStreamGetPosition(HVIDEO hVideo, LPMMTIME lpInfo, DWORD dwSize)
  1114. {
  1115. if (!hVideo)
  1116. return DV_ERR_INVALHANDLE;
  1117. if (IsBadWritePtr (lpInfo, sizeof (MMTIME)) )
  1118. return DV_ERR_PARAM1;
  1119. return videoMessage(hVideo, DVM_STREAM_GETPOSITION,
  1120. (DWORD)lpInfo, (DWORD)dwSize);
  1121. }
  1122. // ============================================
  1123. /*****************************************************************************
  1124. * @doc EXTERNAL VIDEO
  1125. *
  1126. * @api DWORD | videoStreamInit | This function initializes a video
  1127. * device channel for streaming.
  1128. *
  1129. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1130. *
  1131. * @parm DWORD | dwMicroSecPerFrame | Specifies the number of microseconds
  1132. * between frames.
  1133. *
  1134. * @parm DWORD | dwCallback | Specifies the address of a callback
  1135. * function or a handle to a window called during video
  1136. * streaming. The callback function or window processes
  1137. * messages related to the progress of streaming.
  1138. *
  1139. * @parm DWORD | dwCallbackInstance | Specifies user
  1140. * instance data passed to the callback function. This parameter is not
  1141. * used with window callbacks.
  1142. *
  1143. * @parm DWORD | dwFlags | Specifies flags for opening the device channel.
  1144. * The following flags are defined:
  1145. * @flag CALLBACK_WINDOW | If this flag is specified, <p dwCallback> is
  1146. * a window handle.
  1147. * @flag CALLBACK_FUNCTION | If this flag is specified, <p dwCallback> is
  1148. * a callback procedure address.
  1149. *
  1150. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1151. * an error number. The following errors are defined:
  1152. * @flag DV_ERR_BADDEVICEID | Indicates the device ID specified in
  1153. * <p hVideo> is not valid.
  1154. * @flag DV_ERR_ALLOCATED | Indicates the resource specified is already allocated.
  1155. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  1156. *
  1157. * @comm If a window or function is chosen to receive callback information, the following
  1158. * messages are sent to it to indicate the
  1159. * progress of video input:
  1160. *
  1161. * <m MM_DRVM_OPEN> is sent at the time of <f videoStreamInit>
  1162. *
  1163. * <m MM_DRVM_CLOSE> is sent at the time of <f videoStreamFini>
  1164. *
  1165. * <m MM_DRVM_DATA> is sent when a buffer of image data is available
  1166. *
  1167. * <m MM_DRVM_ERROR> is sent when an error occurs
  1168. *
  1169. * Callback functions must reside in a DLL.
  1170. * You do not have to use <f MakeProcInstance> to get
  1171. * a procedure-instance address for the callback function.
  1172. *
  1173. * @cb void CALLBACK | videoFunc | <f videoFunc> is a placeholder for an
  1174. * application-supplied function name. The actual name must be exported by
  1175. * including it in an EXPORTS statement in the DLL's module-definition file.
  1176. * This is used only when a callback function is specified in
  1177. * <f videoStreamInit>.
  1178. *
  1179. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel
  1180. * associated with the callback.
  1181. *
  1182. * @parm DWORD | wMsg | Specifies the <m MM_DRVM_> messages. Messages indicate
  1183. * errors and when image data is available. For information on
  1184. * these messages, see <f videoStreamInit>.
  1185. *
  1186. * @parm DWORD | dwInstance | Specifies the user instance
  1187. * data specified with <f videoStreamInit>.
  1188. *
  1189. * @parm DWORD | dwParam1 | Specifies a parameter for the message.
  1190. *
  1191. * @parm DWORD | dwParam2 | Specifies a parameter for the message.
  1192. *
  1193. * @comm Because the callback is accessed at interrupt time, it must reside
  1194. * in a DLL and its code segment must be specified as FIXED in the
  1195. * module-definition file for the DLL. Any data the callback accesses
  1196. * must be in a FIXED data segment as well. The callback may not make any
  1197. * system calls except for <f PostMessage>, <f timeGetSystemTime>,
  1198. * <f timeGetTime>, <f timeSetEvent>, <f timeKillEvent>,
  1199. * <f midiOutShortMsg>, <f midiOutLongMsg>, and <f OutputDebugStr>.
  1200. *
  1201. * @xref <f videoOpen> <f videoStreamFini> <f videoClose>
  1202. ****************************************************************************/
  1203. DWORD WINAPI videoStreamInit(HVIDEO hVideo,
  1204. DWORD dwMicroSecPerFrame, DWORD dwCallback,
  1205. DWORD dwCallbackInst, DWORD dwFlags)
  1206. {
  1207. VIDEO_STREAM_INIT_PARMS vsip;
  1208. if (!hVideo)
  1209. return DV_ERR_INVALHANDLE;
  1210. if (dwCallback && ((dwFlags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) ) {
  1211. if (IsBadCodePtr ((FARPROC) dwCallback) )
  1212. return DV_ERR_PARAM2;
  1213. if (!dwCallbackInst)
  1214. return DV_ERR_PARAM2;
  1215. }
  1216. if (dwCallback && ((dwFlags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) ) {
  1217. if (!IsWindow((HWND)(dwCallback)) )
  1218. return DV_ERR_PARAM2;
  1219. }
  1220. vsip.dwMicroSecPerFrame = dwMicroSecPerFrame;
  1221. vsip.dwCallback = dwCallback;
  1222. vsip.dwCallbackInst = dwCallbackInst;
  1223. vsip.dwFlags = dwFlags;
  1224. vsip.hVideo = (DWORD)hVideo;
  1225. return videoMessage(hVideo, DVM_STREAM_INIT,
  1226. (DWORD) (LPVIDEO_STREAM_INIT_PARMS) &vsip,
  1227. (DWORD) sizeof (VIDEO_STREAM_INIT_PARMS));
  1228. }
  1229. /*****************************************************************************
  1230. * @doc EXTERNAL VIDEO
  1231. *
  1232. * @api DWORD | videoStreamFini | This function terminates streaming
  1233. * from the specified device channel.
  1234. *
  1235. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1236. *
  1237. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1238. * an error number. The following errors are defined:
  1239. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1240. * @flag DV_ERR_STILLPLAYING | Indicates there are still buffers in the queue.
  1241. *
  1242. * @comm If there are buffers that have been sent with
  1243. * <f videoStreamAddBuffer> that haven't been returned to the application,
  1244. * this operation will fail. Use <f videoStreamReset> to return all
  1245. * pending buffers.
  1246. *
  1247. * Each call to <f videoStreamInit> must be matched with a call to
  1248. * <f videoStreamFini>.
  1249. *
  1250. * For VIDEO_EXTERNALIN channels, this function is used to
  1251. * halt capturing of data to the frame buffer.
  1252. *
  1253. * For VIDEO_EXTERNALOUT channels supporting overlay,
  1254. * this function is used to disable the overlay.
  1255. *
  1256. * @xref <f videoStreamInit>
  1257. ****************************************************************************/
  1258. DWORD WINAPI videoStreamFini(HVIDEO hVideo)
  1259. {
  1260. if (!hVideo)
  1261. return DV_ERR_INVALHANDLE;
  1262. return videoMessage(hVideo, DVM_STREAM_FINI, 0L, 0L);
  1263. }
  1264. /*****************************************************************************
  1265. * @doc EXTERNAL VIDEO
  1266. *
  1267. * @api DWORD | videoStreamStart | This function starts streaming on the
  1268. * specified video device channel.
  1269. *
  1270. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1271. *
  1272. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1273. * an error number. The following errors are defined:
  1274. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1275. *
  1276. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1277. * function.
  1278. *
  1279. * @xref <f videoStreamReset> <f videoStreamStop> <f videoStreamAddBuffer> <f videoStreamClose>
  1280. /****************************************************************************/
  1281. DWORD WINAPI videoStreamStart(HVIDEO hVideo)
  1282. {
  1283. if (!hVideo)
  1284. return DV_ERR_INVALHANDLE;
  1285. return videoMessage(hVideo, DVM_STREAM_START, 0L, 0L);
  1286. }
  1287. /*****************************************************************************
  1288. * @doc EXTERNAL VIDEO
  1289. *
  1290. * @api DWORD | videoStreamGetError | This function returns the error
  1291. * most recently encountered.
  1292. *
  1293. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1294. *
  1295. * @parm LPDWORD | lpdwErrorID | Specifies a far pointer to the <t DWORD>
  1296. * used to return the error ID.
  1297. *
  1298. * @parm LPDWORD | lpdwErrorValue | Specifies a far pointer to the <t DWORD>
  1299. * used to return the number of frames skipped.
  1300. *
  1301. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1302. * an error number. The following error is defined:
  1303. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1304. *
  1305. * @comm While streaming video data, a capture
  1306. * driver can fill buffers faster than the client application can
  1307. * save the buffers to disk. In this case, the
  1308. * DV_ERR_NO_BUFFERS error is returned in <p lpdwErrorID>
  1309. * and <p lpdwErrorValue> contains a count of the number of
  1310. * frames missed. After
  1311. * receiving this message and returning the error status, a driver
  1312. * should reset its internal error flag to DV_ERR_OK and
  1313. * the count of missed frames to zero.
  1314. *
  1315. * Applications should send this message frequently during capture
  1316. * since some drivers which do not have access to interrupts use
  1317. * this message to trigger buffer processing.
  1318. *
  1319. * @xref <f videoOpen>
  1320. /****************************************************************************/
  1321. DWORD WINAPI videoStreamGetError(HVIDEO hVideo, LPDWORD lpdwError,
  1322. LPDWORD lpdwFramesSkipped)
  1323. {
  1324. if (!hVideo)
  1325. return DV_ERR_INVALHANDLE;
  1326. if (IsBadWritePtr (lpdwError, sizeof (DWORD)) )
  1327. return DV_ERR_PARAM1;
  1328. if (IsBadWritePtr (lpdwFramesSkipped, sizeof (DWORD)) )
  1329. return DV_ERR_PARAM2;
  1330. return videoMessage(hVideo, DVM_STREAM_GETERROR, (DWORD) lpdwError,
  1331. (DWORD) lpdwFramesSkipped);
  1332. }
  1333. /*****************************************************************************
  1334. * @doc EXTERNAL VIDEO
  1335. *
  1336. * @api DWORD | videoFrame | This function transfers a single frame
  1337. * to or from a video device channel.
  1338. *
  1339. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1340. * The channel must be of type VIDEO_IN or VIDEO_OUT.
  1341. *
  1342. * @parm LPVIDEOHDR | lpVHdr | Specifies a far pointer to an <t VIDEOHDR>
  1343. * structure.
  1344. *
  1345. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1346. * an error number. The following errors are defined:
  1347. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  1348. * @flag DV_ERR_PARAM1 | The <p lpVDHdr> parameter is invalid or
  1349. * the <e VIDEOHDR.dwBufferLength> member of the <t VIDEOHDR>
  1350. * structure is not set to the proper value.
  1351. *
  1352. * @comm Use this function with a VIDEO_IN channel to transfer a single
  1353. * image from the frame buffer.
  1354. * Use this function with a VIDEO_OUT channel to transfer a single
  1355. * image to the frame buffer.
  1356. *
  1357. * @xref <f videoOpen>
  1358. /****************************************************************************/
  1359. DWORD WINAPI videoFrame (HVIDEO hVideo, LPVIDEOHDR lpVHdr)
  1360. {
  1361. if (!hVideo)
  1362. return DV_ERR_INVALHANDLE;
  1363. if (!lpVHdr)
  1364. return DV_ERR_PARAM1;
  1365. if (IsBadWritePtr (lpVHdr, sizeof (VIDEOHDR)) )
  1366. return DV_ERR_PARAM1;
  1367. return videoMessage(hVideo, DVM_FRAME, (DWORD) lpVHdr,
  1368. sizeof(VIDEOHDR));
  1369. }
  1370. /**************************************************************************
  1371. * @doc INTERNAL VIDEO
  1372. *
  1373. * @api void | videoCleanup | clean up video stuff
  1374. * called in MSVIDEOs WEP()
  1375. *
  1376. **************************************************************************/
  1377. void FAR PASCAL videoCleanup(HTASK hTask)
  1378. {
  1379. }
  1380. //
  1381. // Assist with unicode conversions
  1382. //
  1383. int Iwcstombs(LPSTR lpstr, LPCWSTR lpwstr, int len)
  1384. {
  1385. return WideCharToMultiByte(GetACP(), 0, lpwstr, -1, lpstr, len, NULL, NULL);
  1386. }
  1387. int Imbstowcs(LPWSTR lpwstr, LPCSTR lpstr, int len)
  1388. {
  1389. return MultiByteToWideChar(GetACP(),
  1390. MB_PRECOMPOSED,
  1391. lpstr,
  1392. -1,
  1393. lpwstr,
  1394. len);
  1395. }