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.

2020 lines
70 KiB

  1. /****************************************************************************
  2. video.c
  3. Contains video APIs
  4. Copyright (c) Microsoft Corporation 1992. All rights reserved
  5. ****************************************************************************/
  6. #include <windows.h>
  7. #include <mmsystem.h>
  8. #include <win32.h>
  9. #include <winerror.h>
  10. #include "msviddrv.h"
  11. #include "ivideo32.h" // includes msvideo.h
  12. #include "msvideoi.h"
  13. #ifdef _WIN32
  14. #include "profile.h"
  15. #include <mmddk.h>
  16. #include <stdlib.h>
  17. #include <winver.h>
  18. #else
  19. #include <ver.h>
  20. #endif
  21. #include "debug.h"
  22. #ifndef DEVNODE
  23. typedef DWORD DEVNODE; // Devnode.
  24. #endif
  25. #ifndef LPHKEY
  26. typedef HKEY FAR * LPHKEY;
  27. #endif
  28. #if defined _WIN32 && !defined UNICODE
  29. HDRVR WINAPI OpenDriverA( LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2);
  30. #endif
  31. /*****************************************************************************
  32. * Variables
  33. *
  34. ****************************************************************************/
  35. #ifdef WIN16 // All of this is currently only used in 16 bit land
  36. SZCODE szVideo[] = TEXT("msvideo");
  37. #ifndef UNICODE
  38. // Registry settings of interest to capture drivers
  39. SZCODE szRegKey[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\MediaResources\\msvideo");
  40. SZCODE szRegActive[] = TEXT("Active");
  41. SZCODE szRegDisabled[] = TEXT("Disabled");
  42. SZCODE szRegDescription[] = TEXT("Description");
  43. SZCODE szRegDevNode[] = TEXT("DevNode");
  44. SZCODE szRegDriver[] = TEXT("Driver");
  45. SZCODE szRegSoftwareKey[] = TEXT("SOFTWAREKEY");
  46. #endif
  47. #ifndef _WIN32
  48. SZCODE szDrivers[] = "Drivers";
  49. #else
  50. STATICDT SZCODE szDrivers[] = DRIVERS_SECTION;
  51. #endif
  52. STATICDT SZCODE szSystemIni[] = TEXT("system.ini");
  53. static SZCODE szNull[] = TEXT("");
  54. UINT wTotalVideoDevs; // total video devices
  55. LPCAPDRIVERINFO aCapDriverList[MAXVIDEODRIVERS]; // Array of all capture drivers
  56. /*****************************************************************************
  57. * @doc INTERNAL VIDEO validation code for VIDEOHDRs
  58. ****************************************************************************/
  59. #define IsVideoHeaderPrepared(hVideo, lpwh) ((lpwh)->dwFlags & VHDR_PREPARED)
  60. #define MarkVideoHeaderPrepared(hVideo, lpwh) ((lpwh)->dwFlags |= VHDR_PREPARED)
  61. #define MarkVideoHeaderUnprepared(hVideo, lpwh) ((lpwh)->dwFlags &=~VHDR_PREPARED)
  62. /*****************************************************************************
  63. * @doc INTERNAL VIDEO
  64. *
  65. * @api BOOL | videoRegOpenMSVideoKey | This function returns a key
  66. * for the msvideo node in the registry.
  67. * If the key does not exist it will be created,
  68. * and the default entries made.
  69. *
  70. * @rdesc Returns Key on success, else NULL.
  71. ****************************************************************************/
  72. HKEY videoRegOpenMSVideoKey (void)
  73. {
  74. HKEY hKey = NULL;
  75. // Get the key if it already exists
  76. if (RegOpenKey (
  77. HKEY_LOCAL_MACHINE,
  78. szRegKey,
  79. &hKey) != ERROR_SUCCESS) {
  80. // Otherwise make a new key
  81. if (RegCreateKey (
  82. HKEY_LOCAL_MACHINE,
  83. szRegKey,
  84. &hKey) == ERROR_SUCCESS) {
  85. // Add the default entries to the msvideo node?
  86. }
  87. }
  88. return hKey;
  89. }
  90. /*****************************************************************************
  91. * @doc INTERNAL VIDEO
  92. *
  93. * @api BOOL | videoRegGetDriverByIndex | This function returns information
  94. * about a capture driver by index from the registry.
  95. *
  96. * @parm DWORD | dwDeviceID | Identifies the video device to open.
  97. * The value of <p dwDeviceID> varies from zero to one less
  98. * than the number of video capture devices installed in the system.
  99. *
  100. * @parm LPDEVNODE | lpDevnode | Specifies a far pointer to a buffer
  101. * used to return an <t DEVNODE> handle. For non Plug-and-Play devices,
  102. * this return value will be NULL.
  103. *
  104. * @parm LPBOOL | lpEnabled | Specifies a far pointer to a buffer
  105. * used to return a <t BOOL> flag. If this value is TRUE, the driver is
  106. * enabled, if FALSE, the corresponding device is disabled.
  107. *
  108. * @rdesc Returns TRUE if successful, or FALSE if a driver was not found
  109. * with the <p dwDeviceID> index.
  110. *
  111. * @comm Because the indexes of the MSVIDEO devices in the SYSTEM.INI
  112. * file can be non-contiguous, applications should not assume
  113. * the indexes range between zero and the number of devices minus
  114. * one.
  115. *
  116. ****************************************************************************/
  117. BOOL videoRegGetKeyByIndex (
  118. HKEY hKeyMSVideoRoot,
  119. DWORD dwDeviceID,
  120. LPCAPDRIVERINFO lpCapDriverInfo,
  121. LPHKEY phKeyChild)
  122. {
  123. BOOL fOK = FALSE;
  124. HKEY hKeyEnum;
  125. int i;
  126. *phKeyChild = (HKEY) 0;
  127. for (i=0; i < MAXVIDEODRIVERS; i++) {
  128. if (RegEnumKey (
  129. hKeyMSVideoRoot,
  130. i,
  131. lpCapDriverInfo-> szKeyEnumName,
  132. sizeof(lpCapDriverInfo->szKeyEnumName)/sizeof(TCHAR)) != ERROR_SUCCESS)
  133. break;
  134. // Found a subkey, does it match the requested index?
  135. if (i == (int) dwDeviceID) {
  136. if (RegOpenKey (
  137. hKeyMSVideoRoot,
  138. lpCapDriverInfo-> szKeyEnumName,
  139. &hKeyEnum) == ERROR_SUCCESS) {
  140. *phKeyChild = hKeyEnum; // Found it!!!
  141. fOK = TRUE;
  142. }
  143. break;
  144. }
  145. } // endof all driver indices
  146. return fOK;
  147. }
  148. // Fetches driver info listed in the registry.
  149. // Returns: TRUE if the index was valid, FALSE if no driver at that index
  150. // Note: Registry entry ordering is random.
  151. BOOL videoRegGetDriverByIndex (
  152. DWORD dwDeviceID,
  153. LPCAPDRIVERINFO lpCapDriverInfo)
  154. {
  155. DWORD dwType;
  156. DWORD dwSize;
  157. BOOL fOK;
  158. HKEY hKeyChild;
  159. HKEY hKeyMSVideoRoot;
  160. // Always start clean since the entry may be recycled
  161. _fmemset (lpCapDriverInfo, 0, sizeof (CAPDRIVERINFO));
  162. if (!(hKeyMSVideoRoot = videoRegOpenMSVideoKey()))
  163. return FALSE;
  164. if (fOK = videoRegGetKeyByIndex (
  165. hKeyMSVideoRoot,
  166. dwDeviceID,
  167. lpCapDriverInfo,
  168. &hKeyChild)) {
  169. // Fetch the values:
  170. // Active
  171. // Disabled
  172. // Description
  173. // DEVNODE
  174. // Driver
  175. // SOFTWAREKEY
  176. dwSize = sizeof(BOOL); // Active
  177. RegQueryValueEx(
  178. hKeyChild,
  179. szRegActive,
  180. NULL,
  181. &dwType,
  182. (LPBYTE) &lpCapDriverInfo->fActive,
  183. &dwSize);
  184. dwSize = sizeof(BOOL); // Enabled
  185. RegQueryValueEx(
  186. hKeyChild,
  187. szRegDisabled,
  188. NULL,
  189. &dwType,
  190. (LPBYTE) &lpCapDriverInfo->fDisabled,
  191. &dwSize);
  192. // Convert this thing to a bool
  193. lpCapDriverInfo->fDisabled = (lpCapDriverInfo->fDisabled == '1');
  194. // DriverDescription
  195. dwSize = sizeof (lpCapDriverInfo->szDriverDescription) / sizeof (TCHAR);
  196. RegQueryValueEx(
  197. hKeyChild,
  198. szRegDescription,
  199. NULL,
  200. &dwType,
  201. (LPBYTE) lpCapDriverInfo->szDriverDescription,
  202. &dwSize);
  203. // DEVNODE
  204. dwSize = sizeof(DEVNODE);
  205. RegQueryValueEx(
  206. hKeyChild,
  207. szRegDevNode,
  208. NULL,
  209. &dwType,
  210. (LPBYTE) &lpCapDriverInfo->dnDevNode,
  211. &dwSize);
  212. // DriverName
  213. dwSize = sizeof (lpCapDriverInfo->szDriverName) / sizeof (TCHAR);
  214. RegQueryValueEx(
  215. hKeyChild,
  216. szRegDriver,
  217. NULL,
  218. &dwType,
  219. (LPBYTE) lpCapDriverInfo->szDriverName,
  220. &dwSize);
  221. // SoftwareKey
  222. dwSize = sizeof (lpCapDriverInfo->szSoftwareKey) / sizeof (TCHAR);
  223. RegQueryValueEx(
  224. hKeyChild,
  225. szRegSoftwareKey,
  226. NULL,
  227. &dwType,
  228. (LPBYTE) lpCapDriverInfo->szSoftwareKey,
  229. &dwSize);
  230. RegCloseKey (hKeyChild);
  231. } // if the subkey could be opened
  232. RegCloseKey (hKeyMSVideoRoot);
  233. return fOK;
  234. }
  235. // Fetches driver info listed in system.ini
  236. // Returns: TRUE if the index was valid, FALSE if no driver at that index
  237. BOOL videoIniGetDriverByIndex (
  238. DWORD dwDeviceID,
  239. LPCAPDRIVERINFO lpCapDriverInfo)
  240. {
  241. TCHAR szKey[sizeof(szVideo)/sizeof(TCHAR) + 2];
  242. int w = (int) dwDeviceID;
  243. BOOL fOK = FALSE;
  244. // Always start clean since the entry may be recycled
  245. _fmemset (lpCapDriverInfo, 0, sizeof (CAPDRIVERINFO));
  246. lstrcpy(szKey, szVideo);
  247. szKey[(sizeof(szVideo)/sizeof(TCHAR)) - 1] = (TCHAR)0;
  248. if( w > 0 ) {
  249. szKey[(sizeof(szVideo)/sizeof(TCHAR))] = (TCHAR)0;
  250. szKey[(sizeof(szVideo)/sizeof(TCHAR))-1] = (TCHAR) TEXT('1' + (w-1) ); // driver ordinal
  251. }
  252. if (GetPrivateProfileString(szDrivers, szKey, szNull,
  253. lpCapDriverInfo->szDriverName,
  254. sizeof(lpCapDriverInfo->szDriverName)/sizeof(TCHAR),
  255. szSystemIni)) {
  256. // Found an entry at the requested index
  257. // The description and version info will be inserted as
  258. // requested by the client app.
  259. lpCapDriverInfo-> fOnlySystemIni = TRUE;
  260. fOK = TRUE;
  261. }
  262. return fOK;
  263. }
  264. DWORD videoFreeDriverList (void)
  265. {
  266. int i;
  267. // Free the driver list
  268. for (i = 0; i < MAXVIDEODRIVERS; i++) {
  269. if (aCapDriverList[i])
  270. GlobalFreePtr (aCapDriverList[i]);
  271. aCapDriverList[i] = NULL;
  272. }
  273. return DV_ERR_OK;
  274. }
  275. // This function may be called a number of times to create the
  276. // current driver array. Since Capscrn assumes it can throw a
  277. // driver into system.ini on the fly and have it immediately accessible,
  278. // this routine is called on videoGetNumDevs() and when AVICapx.dll
  279. // tries to get the driver description and version.
  280. //
  281. // Drivers in the registry will be the first entries in the list.
  282. //
  283. // If a driver is listed in the registry AND in system.ini AND
  284. // the full path to the drivers match, the system.ini entry will NOT
  285. // be in the resulting list.
  286. // The variable wTotalVideoDevs is set as a byproduct of this function.
  287. // Returns DV_ERR_OK on success, even if no drivers are installed.
  288. //
  289. DWORD videoCreateDriverList (void)
  290. {
  291. int i, j, k;
  292. wTotalVideoDevs = 0;
  293. // Delete the existing list
  294. videoFreeDriverList ();
  295. // Allocate an array of pointers to all possible capture drivers
  296. for (i = 0; i < MAXVIDEODRIVERS; i++) {
  297. aCapDriverList[i] = (LPCAPDRIVERINFO) GlobalAllocPtr (
  298. GMEM_MOVEABLE |
  299. GMEM_SHARE |
  300. GMEM_ZEROINIT,
  301. sizeof (CAPDRIVERINFO));
  302. if (aCapDriverList[i] == NULL)
  303. return DV_ERR_NOMEM;
  304. }
  305. // Walk the list of Registry drivers and get each entry
  306. for (i = 0; i < MAXVIDEODRIVERS; i++) {
  307. if (videoRegGetDriverByIndex (
  308. (DWORD) i, aCapDriverList[wTotalVideoDevs])) {
  309. wTotalVideoDevs++;
  310. }
  311. else
  312. break;
  313. }
  314. if (wTotalVideoDevs == MAXVIDEODRIVERS)
  315. goto AllDone;
  316. // Now add the entries listed in system.ini, (msvideo[0-9] = driver.drv)
  317. // to the driver array, ONLY if the entry doesn't exactly match
  318. // an existing registry entry.
  319. for (j = 0; j < MAXVIDEODRIVERS; j++) {
  320. if (videoIniGetDriverByIndex ((DWORD) j,
  321. aCapDriverList[wTotalVideoDevs])) {
  322. // Found an entry, now see if it is a duplicate of an existing
  323. // registry entry
  324. for (k = 0; k < (int) wTotalVideoDevs; k++) {
  325. if (lstrcmpi (aCapDriverList[k]->szDriverName,
  326. aCapDriverList[wTotalVideoDevs]->szDriverName) == 0) {
  327. // Found an exact match, so skip it!
  328. goto SkipThisEntry;
  329. }
  330. }
  331. if (wTotalVideoDevs >= MAXVIDEODRIVERS - 1)
  332. break;
  333. wTotalVideoDevs++;
  334. SkipThisEntry:
  335. ;
  336. } // If sytem.ini entry was found
  337. } // For all system.ini possibilities
  338. AllDone:
  339. // Decrement wTotalVideoDevs for any entries which are marked as disabled
  340. // And remove disabled entries from the list
  341. for (i = 0; i < MAXVIDEODRIVERS; ) {
  342. if (aCapDriverList[i] && aCapDriverList[i]->fDisabled) {
  343. GlobalFreePtr (aCapDriverList[i]);
  344. // Shift down the remaining drivers
  345. for (j = i; j < MAXVIDEODRIVERS - 1; j++) {
  346. aCapDriverList[j] = aCapDriverList[j + 1];
  347. }
  348. aCapDriverList[MAXVIDEODRIVERS - 1] = NULL;
  349. wTotalVideoDevs--;
  350. }
  351. else
  352. i++;
  353. }
  354. // Free the unused pointers
  355. for (i = wTotalVideoDevs; i < MAXVIDEODRIVERS; i++) {
  356. if (aCapDriverList[i])
  357. GlobalFreePtr (aCapDriverList[i]);
  358. aCapDriverList[i] = NULL;
  359. }
  360. // Put PnP drivers first in the list
  361. // These are the only entries that have a DevNode
  362. for (k = i = 0; i < (int) wTotalVideoDevs; i++) {
  363. if (aCapDriverList[i]-> dnDevNode) {
  364. LPCAPDRIVERINFO lpCDTemp;
  365. if (k != i) {
  366. // Swap the entries
  367. lpCDTemp = aCapDriverList[k];
  368. aCapDriverList[k] = aCapDriverList[i];
  369. aCapDriverList[i] = lpCDTemp;
  370. }
  371. k++; // Index of first non-PnP driver
  372. }
  373. }
  374. return DV_ERR_OK;
  375. }
  376. typedef struct tagVS_VERSION
  377. {
  378. WORD wTotLen;
  379. WORD wValLen;
  380. char szSig[16];
  381. VS_FIXEDFILEINFO vffInfo;
  382. } VS_VERSION;
  383. typedef struct tagLANGANDCP
  384. {
  385. WORD wLanguage;
  386. WORD wCodePage;
  387. } LANGANDCP;
  388. // Extracts the Description string and version info from a driver.
  389. // Drivers listed in the registry will typically already include a
  390. // description string, but not version info.
  391. // Drivers listed in system.ini will fetch both.
  392. //
  393. // Returns DV_ERR_OK on success, even if no version info was available.
  394. //
  395. DWORD WINAPI videoGetDriverDescAndVer (
  396. LPCAPDRIVERINFO lpCapDriverInfo)
  397. {
  398. LPSTR lpVersion;
  399. WORD wVersionLen;
  400. BOOL bRetCode;
  401. DWORD dwVerInfoSize;
  402. DWORD dwVerHnd;
  403. TCHAR szBuf[MAX_PATH];
  404. BOOL fGetDesc;
  405. BOOL fGetVersion;
  406. // Only get the description if not already supplied by the registry
  407. fGetDesc = (lpCapDriverInfo->szDriverDescription[0] == '\0');
  408. fGetVersion = (lpCapDriverInfo->szDriverVersion[0] == '\0');
  409. if (fGetDesc)
  410. lpCapDriverInfo->szDriverDescription[0] = '\0';
  411. if (fGetVersion)
  412. lpCapDriverInfo->szDriverVersion [0] = '\0';
  413. // Copy in the driver name initially, just in case the driver
  414. // has omitted a description field.
  415. if (fGetDesc)
  416. lstrcpyn (lpCapDriverInfo->szDriverDescription,
  417. lpCapDriverInfo->szDriverName,
  418. sizeof (lpCapDriverInfo->szDriverDescription) / sizeof (TCHAR));
  419. // You must find the size first before getting any file info
  420. dwVerInfoSize =
  421. GetFileVersionInfoSize(lpCapDriverInfo->szDriverName, &dwVerHnd);
  422. if (dwVerInfoSize) {
  423. LPSTR lpstrVffInfo; // Pointer to block to hold info
  424. // Get a block big enough to hold version info
  425. if (lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize)) {
  426. // Get the File Version first
  427. if(GetFileVersionInfo(lpCapDriverInfo->szDriverName, 0L,
  428. dwVerInfoSize, lpstrVffInfo)) {
  429. VS_VERSION FAR *pVerInfo = (VS_VERSION FAR *) lpstrVffInfo;
  430. // fill in the file version
  431. wsprintf(szBuf,
  432. "Version: %d.%d.%d.%d",
  433. HIWORD(pVerInfo->vffInfo.dwFileVersionMS),
  434. LOWORD(pVerInfo->vffInfo.dwFileVersionMS),
  435. HIWORD(pVerInfo->vffInfo.dwFileVersionLS),
  436. LOWORD(pVerInfo->vffInfo.dwFileVersionLS));
  437. if (fGetVersion)
  438. lstrcpyn (lpCapDriverInfo->szDriverVersion, szBuf,
  439. sizeof (lpCapDriverInfo->szDriverVersion) / sizeof(TCHAR));
  440. }
  441. // Now try to get the FileDescription
  442. // First try this for the "Translation" entry, and then
  443. // try the American english translation.
  444. // Keep track of the string length for easy updating.
  445. // 040904E4 represents the language ID and the four
  446. // least significant digits represent the codepage for
  447. // which the data is formatted. The language ID is
  448. // composed of two parts: the low ten bits represent
  449. // the major language and the high six bits represent
  450. // the sub language.
  451. lstrcpy(szBuf, "\\StringFileInfo\\040904E4\\FileDescription");
  452. wVersionLen = 0;
  453. lpVersion = NULL;
  454. // Look for the corresponding string.
  455. bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
  456. (LPSTR)szBuf,
  457. (void FAR* FAR*)&lpVersion,
  458. (UINT FAR *) &wVersionLen);
  459. if (fGetDesc && bRetCode && wVersionLen && lpVersion)
  460. lstrcpyn (lpCapDriverInfo->szDriverDescription, lpVersion,
  461. sizeof (lpCapDriverInfo->szDriverDescription) / sizeof(TCHAR));
  462. // Let go of the memory
  463. GlobalFreePtr(lpstrVffInfo);
  464. }
  465. else
  466. return DV_ERR_NOMEM;
  467. }
  468. return DV_ERR_OK;
  469. }
  470. // Called by AVICap and AVICap32 to get driver strings
  471. // Returns:
  472. // DV_ERR_OK on success
  473. // DV_ERR_BADINSTALL if the driver at the specified index is not found
  474. DWORD WINAPI videoCapDriverDescAndVer (
  475. DWORD dwDeviceID,
  476. LPTSTR lpszDesc, UINT cbDesc,
  477. LPTSTR lpszVer, UINT cbVer)
  478. {
  479. DWORD dwR = DV_ERR_OK;
  480. if (lpszDesc && IsBadWritePtr (lpszDesc, cbDesc))
  481. return DV_ERR_NONSPECIFIC;
  482. else if (lpszDesc)
  483. *lpszDesc = '\0';
  484. if (lpszVer && IsBadWritePtr (lpszVer, cbVer))
  485. return DV_ERR_NONSPECIFIC;
  486. else if (lpszVer)
  487. *lpszVer = '\0';
  488. if (!wTotalVideoDevs)
  489. dwR = videoCreateDriverList ();
  490. if (dwR != DV_ERR_OK)
  491. return dwR;
  492. if ((WORD) dwDeviceID >= wTotalVideoDevs)
  493. return DV_ERR_BADDEVICEID;
  494. dwR = videoGetDriverDescAndVer (aCapDriverList[(int)dwDeviceID]);
  495. if (dwR == DV_ERR_OK) {
  496. if (lpszDesc)
  497. lstrcpyn (lpszDesc, aCapDriverList[(int)dwDeviceID]->szDriverDescription, cbDesc);
  498. if (lpszVer)
  499. lstrcpyn (lpszVer, aCapDriverList[(int)dwDeviceID]->szDriverVersion, cbVer);
  500. }
  501. return (dwR);
  502. }
  503. /*****************************************************************************
  504. * @doc EXTERNAL VIDEO
  505. *
  506. * @func DWORD | videoMessage | This function sends messages to a
  507. * video device channel.
  508. *
  509. * @parm HVIDEO | hVideo | Specifies the handle to the video device channel.
  510. *
  511. * @parm UINT | wMsg | Specifies the message to send.
  512. *
  513. * @parm DWORD | dwP1 | Specifies the first parameter for the message.
  514. *
  515. * @parm DWORD | dwP2 | Specifies the second parameter for the message.
  516. *
  517. * @rdesc Returns the message specific value returned from the driver.
  518. *
  519. * @comm This function is used for configuration messages such as
  520. * <m DVM_SRC_RECT> and <m DVM_DST_RECT>, and
  521. * device specific messages.
  522. *
  523. * @xref <f videoConfigure>
  524. *
  525. ****************************************************************************/
  526. DWORD WINAPI videoMessage(HVIDEO hVideo, UINT msg, DWORD dwP1, DWORD dwP2)
  527. {
  528. if (!hVideo)
  529. return DV_ERR_INVALHANDLE;
  530. return SendDriverMessage ((HDRVR)hVideo, msg, dwP1, dwP2);
  531. }
  532. /*****************************************************************************
  533. * @doc EXTERNAL VIDEO
  534. *
  535. * @api DWORD | videoGetNumDevs | This function returns the number of MSVIDEO
  536. * devices installed.
  537. *
  538. * @rdesc Returns the number of MSVIDEO devices listed in the
  539. * [drivers] (or [drivers32] for NT) section of the SYSTEM.INI file
  540. * plus drivers listed in the registry.
  541. *
  542. * @comm Because the indexes of the MSVIDEO devices in the SYSTEM.INI
  543. * file can be non-contiguous, applications should not assume
  544. * the indexes range between zero and the number of devices minus
  545. * one.
  546. *
  547. * @xref <f videoOpen>
  548. ****************************************************************************/
  549. DWORD WINAPI videoGetNumDevs(void)
  550. {
  551. if (wTotalVideoDevs)
  552. return (DWORD)wTotalVideoDevs;
  553. videoCreateDriverList ();
  554. return (DWORD)wTotalVideoDevs;
  555. }
  556. /*****************************************************************************
  557. * @doc EXTERNAL VIDEO
  558. *
  559. * @func DWORD | videoGetErrorText | This function retrieves a
  560. * description of the error identified by the error number.
  561. *
  562. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  563. * This might be NULL if the error is not device specific.
  564. *
  565. * @parm UINT | wError | Specifies the error number.
  566. *
  567. * @parm LPSTR | lpText | Specifies a far pointer to a buffer used to
  568. * return the zero-terminated string corresponding to the error number.
  569. *
  570. * @parm UINT | wSize | Specifies the length, in bytes, of the buffer
  571. * referenced by <p lpText>.
  572. *
  573. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  574. * an error number. The following error is defined:
  575. * @flag DV_ERR_BADERRNUM | Specified error number is out of range.
  576. * @flag DV_ERR_SIZEFIELD | The return buffer is not large enough
  577. * to handle the error text.
  578. *
  579. * @comm If the error description is longer than the buffer,
  580. * the description is truncated. The returned error string is always
  581. * zero-terminated. If <p wSize> is zero, nothing is copied and zero
  582. * is returned.
  583. ****************************************************************************/
  584. #if defined _WIN32
  585. //
  586. // for WIN32 this is the ansi entry point
  587. //
  588. DWORD WINAPI videoGetErrorTextA (HVIDEO hVideo,
  589. UINT wError, LPSTR lpText, UINT wSize)
  590. {
  591. VIDEO_GETERRORTEXT_PARMS vet;
  592. if (IsBadWritePtr (lpText, wSize))
  593. return DV_ERR_PARAM1;
  594. lpText[0] = 0;
  595. if (((wError >= DV_ERR_BASE) && (wError <= DV_ERR_LASTERROR))) {
  596. if (wSize > 1) {
  597. if (!LoadStringA(ghInst, wError, lpText, wSize))
  598. return DV_ERR_BADERRNUM;
  599. else
  600. return DV_ERR_OK;
  601. }
  602. else
  603. return DV_ERR_SIZEFIELD;
  604. }
  605. else if (wError >= DV_ERR_USER_MSG && hVideo) {
  606. DWORD dwResult;
  607. LPWSTR lpwstr = LocalAlloc(LPTR, wSize*sizeof(WCHAR));
  608. if (NULL == lpwstr) {
  609. return(DV_ERR_NOMEM);
  610. }
  611. vet.dwError = (DWORD) wError;
  612. vet.lpText = lpwstr;
  613. vet.dwLength = (DWORD) wSize;
  614. dwResult = videoMessage (hVideo, DVM_GETERRORTEXT, (DWORD) (LPVOID) &vet,
  615. (DWORD) NULL);
  616. if (DV_ERR_OK == dwResult) {
  617. wcstombs(lpText, lpwstr, wSize);
  618. }
  619. LocalFree(lpwstr);
  620. return(dwResult);
  621. }
  622. else
  623. return DV_ERR_BADERRNUM;
  624. }
  625. #endif
  626. //
  627. // The unicode/Win16 equivalent of the above
  628. //
  629. #ifdef _WIN32
  630. DWORD WINAPI videoGetErrorTextW (HVIDEO hVideo, UINT wError,
  631. LPWSTR lpText, UINT wSize)
  632. #else
  633. DWORD WINAPI videoGetErrorText (HVIDEO hVideo, UINT wError,
  634. LPSTR lpText, UINT wSize)
  635. #endif
  636. {
  637. VIDEO_GETERRORTEXT_PARMS vet;
  638. lpText[0] = 0;
  639. if (((wError > DV_ERR_BASE) && (wError <= DV_ERR_LASTERROR))) {
  640. if (wSize > 1) {
  641. #ifdef _WIN32
  642. LPSTR lpsz = LocalAlloc (LPTR, wSize);
  643. UINT cch;
  644. if (!lpsz)
  645. return DV_ERR_NOMEM;
  646. cch = LoadString (ghInst, wError, lpsz, wSize);
  647. lpsz[cch] = 0;
  648. mbstowcs (lpText, lpsz, cch+1);
  649. LocalFree (lpsz);
  650. if (!cch)
  651. #else
  652. if (!LoadString(ghInst, wError, lpText, wSize))
  653. #endif
  654. return DV_ERR_BADERRNUM;
  655. else
  656. return DV_ERR_OK;
  657. }
  658. else
  659. return DV_ERR_SIZEFIELD;
  660. }
  661. else if (wError >= DV_ERR_USER_MSG && hVideo) {
  662. vet.dwError = (DWORD) wError;
  663. vet.lpText = lpText;
  664. vet.dwLength = wSize;
  665. return videoMessage (hVideo, DVM_GETERRORTEXT, (DWORD) (LPVOID) &vet,
  666. (DWORD) NULL);
  667. }
  668. else
  669. return DV_ERR_BADERRNUM;
  670. }
  671. /*****************************************************************************
  672. * @doc EXTERNAL VIDEO
  673. *
  674. * @func DWORD | videoGetChannelCaps | This function retrieves a
  675. * description of the capabilities of a channel.
  676. *
  677. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  678. *
  679. * @parm LPCHANNEL_CAPS | lpChannelCaps | Specifies a far pointer to a
  680. * <t CHANNEL_CAPS> structure.
  681. *
  682. * @parm DWORD | dwSize | Specifies the size, in bytes, of the
  683. * <t CHANNEL_CAPS> structure.
  684. *
  685. * @rdesc Returns zero if the function is successful. Otherwise, it returns
  686. * an error number. The following errors are defined:
  687. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  688. * @flag DV_ERR_UNSUPPORTED | Function is not supported.
  689. *
  690. * @comm The <t CHANNEL_CAPS> structure returns the capability
  691. * information. For example, capability information might
  692. * include whether or not the channel can crop and scale images,
  693. * or show overlay.
  694. ****************************************************************************/
  695. DWORD WINAPI videoGetChannelCaps(HVIDEO hVideo, LPCHANNEL_CAPS lpChannelCaps,
  696. DWORD dwSize)
  697. {
  698. if (!hVideo)
  699. return DV_ERR_INVALHANDLE;
  700. if (IsBadWritePtr (lpChannelCaps, sizeof (CHANNEL_CAPS)))
  701. return DV_ERR_PARAM1;
  702. // _fmemset (lpChannelCaps, 0, sizeof (CHANNEL_CAPS));
  703. lpChannelCaps->dwFlags = 0;
  704. lpChannelCaps->dwSrcRectXMod = 0;
  705. lpChannelCaps->dwSrcRectYMod = 0;
  706. lpChannelCaps->dwSrcRectWidthMod = 0;
  707. lpChannelCaps->dwSrcRectHeightMod = 0;
  708. lpChannelCaps->dwDstRectXMod = 0;
  709. lpChannelCaps->dwDstRectYMod = 0;
  710. lpChannelCaps->dwDstRectWidthMod = 0;
  711. lpChannelCaps->dwDstRectHeightMod = 0;
  712. return videoMessage(hVideo, DVM_GET_CHANNEL_CAPS, (DWORD) lpChannelCaps,
  713. (DWORD) dwSize);
  714. }
  715. /*****************************************************************************
  716. * @doc EXTERNAL VIDEO
  717. *
  718. * @func DWORD | videoUpdate | This function directs a channel to
  719. * repaint the display. It applies only to VIDEO_EXTERNALOUT channels.
  720. *
  721. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  722. *
  723. * @parm HWND | hWnd | Specifies the handle of the window to be used
  724. * by the channel for image display.
  725. *
  726. * @parm HDC | hDC | Specifies a handle to a device context.
  727. *
  728. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  729. * an error number. The following errors are defined:
  730. * @flag DV_ERR_UNSUPPORTED | Specified message is unsupported.
  731. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  732. *
  733. * @comm This message is normally sent
  734. * whenever the client window receives a <m WM_MOVE>, <m WM_SIZE>,
  735. * or <m WM_PAINT> message.
  736. ****************************************************************************/
  737. DWORD WINAPI videoUpdate (HVIDEO hVideo, HWND hWnd, HDC hDC)
  738. {
  739. if ((!hVideo) || (!hWnd) || (!hDC) )
  740. return DV_ERR_INVALHANDLE;
  741. return videoMessage(hVideo, DVM_UPDATE, (DWORD) hWnd, (DWORD) hDC);
  742. }
  743. /*****************************************************************************
  744. * @doc EXTERNAL VIDEO
  745. *
  746. * @api DWORD | videoOpen | This function opens a channel on the
  747. * specified video device.
  748. *
  749. * @parm LPHVIDEO | lphvideo | Specifies a far pointer to a buffer
  750. * used to return an <t HVIDEO> handle. The video capture driver
  751. * uses this location to return
  752. * a handle that uniquely identifies the opened video device channel.
  753. * Use the returned handle to identify the device channel when
  754. * calling other video functions.
  755. *
  756. * @parm DWORD | dwDeviceID | Identifies the video device to open.
  757. * The value of <p dwDeviceID> varies from zero to one less
  758. * than the number of video capture devices installed in the system.
  759. *
  760. * @parm DWORD | dwFlags | Specifies flags for opening the device.
  761. * The following flags are defined:
  762. *
  763. * @flag VIDEO_EXTERNALIN| Specifies the channel is opened
  764. * for external input. Typically, external input channels
  765. * capture images into a frame buffer.
  766. *
  767. * @flag VIDEO_EXTERNALOUT| Specifies the channel is opened
  768. * for external output. Typically, external output channels
  769. * display images stored in a frame buffer on an auxilary monitor
  770. * or overlay.
  771. *
  772. * @flag VIDEO_IN| Specifies the channel is opened
  773. * for video input. Video input channels transfer images
  774. * from a frame buffer to system memory buffers.
  775. *
  776. * @flag VIDEO_OUT| Specifies the channel is opened
  777. * for video output. Video output channels transfer images
  778. * from system memory buffers to a frame buffer.
  779. *
  780. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  781. * an error number. The following errors are defined:
  782. * @flag DV_ERR_BADDEVICEID | Indicates the specified device ID is out of range.
  783. * @flag DV_ERR_ALLOCATED | Indicates the specified resource is already allocated.
  784. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  785. *
  786. * @comm
  787. * At a minimum, all capture drivers support a VIDEO_EXTERNALIN
  788. * and a VIDEO_IN channel.
  789. * Use <f videoGetNumDevs> to determine the number of video
  790. * devices present in the system.
  791. *
  792. * @xref <f videoClose>
  793. ****************************************************************************/
  794. DWORD WINAPI videoOpen (LPHVIDEO lphVideo, DWORD dwDeviceID, DWORD dwFlags)
  795. {
  796. UINT w;
  797. VIDEO_OPEN_PARMS vop; // Same as IC_OPEN struct!!!
  798. DWORD dwVersion = VIDEOAPIVERSION;
  799. if (IsBadWritePtr ((LPVOID) lphVideo, sizeof (HVIDEO)) )
  800. return DV_ERR_PARAM1;
  801. vop.dwSize = sizeof (VIDEO_OPEN_PARMS);
  802. vop.fccType = OPEN_TYPE_VCAP; // "vcap"
  803. vop.fccComp = 0L;
  804. vop.dwVersion = VIDEOAPIVERSION;
  805. vop.dwFlags = dwFlags; // In, Out, External In, External Out
  806. vop.dwError = DV_ERR_OK;
  807. w = (UINT) dwDeviceID;
  808. *lphVideo = NULL;
  809. if (!wTotalVideoDevs) // trying to open without finding how many devs.
  810. videoGetNumDevs();
  811. if (!wTotalVideoDevs) // No drivers installed
  812. return DV_ERR_BADINSTALL;
  813. if (w >= wTotalVideoDevs)
  814. return DV_ERR_BADDEVICEID;
  815. // New for Chicago, drivers are passed a Devnode if PnP at Open time
  816. vop.dnDevNode = aCapDriverList[w]->dnDevNode;
  817. #ifdef UNICODE
  818. *lphVideo = (HVIDEO) OpenDriver(aCapDriverList[w]->szDriverName,
  819. NULL, (LPARAM) (LPVOID) &vop);
  820. #else
  821. #if defined _WIN32
  822. *lphVideo = (HVIDEO) OpenDriverA(aCapDriverList[w]->szDriverName,
  823. NULL, (LPARAM) (LPVOID) &vop);
  824. #else
  825. *lphVideo = (HVIDEO) OpenDriver(aCapDriverList[w]->szDriverName,
  826. NULL, (LPARAM) (LPVOID) &vop);
  827. #endif
  828. #endif
  829. if( ! *lphVideo ) {
  830. if (vop.dwError) // if driver returned an error code...
  831. return vop.dwError;
  832. else {
  833. #ifdef _WIN32
  834. if (GetFileAttributes(aCapDriverList[w]->szDriverName) == (DWORD) -1)
  835. #else
  836. OFSTRUCT of;
  837. if (OpenFile (aCapDriverList[w]->szDriverName, &of, OF_EXIST) == HFILE_ERROR)
  838. #endif
  839. return (DV_ERR_BADINSTALL);
  840. else
  841. return (DV_ERR_NOTDETECTED);
  842. }
  843. }
  844. return DV_ERR_OK;
  845. }
  846. /*****************************************************************************
  847. * @doc EXTERNAL VIDEO
  848. *
  849. * @api DWORD | videoClose | This function closes the specified video
  850. * device channel.
  851. *
  852. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  853. * If this function is successful, the handle is invalid
  854. * after this call.
  855. *
  856. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  857. * an error number. The following errors are defined:
  858. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  859. * @flag DV_ERR_NONSPECIFIC | The driver failed to close the channel.
  860. *
  861. * @comm If buffers have been sent with <f videoStreamAddBuffer> and
  862. * they haven't been returned to the application,
  863. * the close operation fails. You can use <f videoStreamReset> to mark all
  864. * pending buffers as done.
  865. *
  866. * @xref <f videoOpen> <f videoStreamInit> <f videoStreamFini> <f videoStreamReset>
  867. ****************************************************************************/
  868. DWORD WINAPI videoClose (HVIDEO hVideo)
  869. {
  870. if (!hVideo)
  871. return DV_ERR_INVALHANDLE;
  872. if (CloseDriver((HDRVR)hVideo, 0L, 0L ))
  873. return DV_ERR_OK;
  874. return DV_ERR_NONSPECIFIC;
  875. }
  876. /*****************************************************************************
  877. * @doc EXTERNAL VIDEO
  878. *
  879. * @api DWORD | videoConfigure | This function sets or retrieves
  880. * the options for a configurable driver.
  881. *
  882. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  883. *
  884. * @parm UINT | msg | Specifies the option to set or retrieve. The
  885. * following options are defined:
  886. *
  887. * @flag DVM_PALETTE | Indicates a palette is being sent to the driver
  888. * or retrieved from the driver.
  889. *
  890. * @flag DVM_PALETTERGB555 | Indicates an RGB555 palette is being
  891. * sent to the driver.
  892. *
  893. * @flag DVM_FORMAT | Indicates format information is being sent to
  894. * the driver or retrieved from the driver.
  895. *
  896. * @parm DWORD | dwFlags | Specifies flags for configuring or
  897. * interrogating the device driver. The following flags are defined:
  898. *
  899. * @flag VIDEO_CONFIGURE_SET | Indicates values are being sent to the driver.
  900. *
  901. * @flag VIDEO_CONFIGURE_GET | Indicates values are being obtained from the driver.
  902. *
  903. * @flag VIDEO_CONFIGURE_QUERY | Determines if the
  904. * driver supports the option specified by <p msg>. This flag
  905. * should be combined with either the VIDEO_CONFIGURE_SET or
  906. * VIDEO_CONFIGURE_GET flag. If this flag is
  907. * set, the <p lpData1>, <p dwSize1>, <p lpData2>, and <p dwSize2>
  908. * parameters are ignored.
  909. *
  910. * @flag VIDEO_CONFIGURE_QUERYSIZE | Returns the size, in bytes,
  911. * of the configuration option in <p lpdwReturn>. This flag is only valid if
  912. * the VIDEO_CONFIGURE_GET flag is also set.
  913. *
  914. * @flag VIDEO_CONFIGURE_CURRENT | Requests the current value.
  915. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  916. * @flag VIDEO_CONFIGURE_NOMINAL | Requests the nominal value.
  917. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  918. * @flag VIDEO_CONFIGURE_MIN | Requests the minimum value.
  919. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  920. * @flag VIDEO_CONFIGURE_MAX | Get the maximum value.
  921. * This flag is valid only if the VIDEO_CONFIGURE_GET flag is also set.
  922. *
  923. * @parm LPDWORD | lpdwReturn | Points to a DWORD used for returning information
  924. * from the driver. If
  925. * the VIDEO_CONFIGURE_QUERYSIZE flag is set, <p lpdwReturn> is
  926. * filled with the size of the configuration option.
  927. *
  928. * @parm LPVOID | lpData1 |Specifies a pointer to message specific data.
  929. *
  930. * @parm DWORD | dwSize1 | Specifies the size, in bytes, of the <p lpData1>
  931. * buffer.
  932. *
  933. * @parm LPVOID | lpData2 | Specifies a pointer to message specific data.
  934. *
  935. * @parm DWORD | dwSize2 | Specifies the size, in bytes, of the <p lpData2>
  936. * buffer.
  937. *
  938. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  939. * an error number. The following errors are defined:
  940. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  941. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  942. *
  943. * @xref <f videoOpen> <f videoMessage>
  944. *
  945. ****************************************************************************/
  946. DWORD WINAPI videoConfigure (HVIDEO hVideo, UINT msg, DWORD dwFlags,
  947. LPDWORD lpdwReturn, LPVOID lpData1, DWORD dwSize1,
  948. LPVOID lpData2, DWORD dwSize2)
  949. {
  950. VIDEOCONFIGPARMS vcp;
  951. if (!hVideo)
  952. return DV_ERR_INVALHANDLE;
  953. if (lpData1)
  954. if (IsBadHugeReadPtr (lpData1, dwSize1))
  955. return DV_ERR_CONFIG1;
  956. if (lpData2)
  957. if (IsBadHugeReadPtr (lpData2, dwSize2))
  958. return DV_ERR_CONFIG2;
  959. if (dwFlags & VIDEO_CONFIGURE_QUERYSIZE) {
  960. if (!lpdwReturn)
  961. return DV_ERR_NONSPECIFIC;
  962. if (IsBadWritePtr (lpdwReturn, sizeof (DWORD)) )
  963. return DV_ERR_NONSPECIFIC;
  964. }
  965. vcp.lpdwReturn = lpdwReturn;
  966. vcp.lpData1 = lpData1;
  967. vcp.dwSize1 = dwSize1;
  968. vcp.lpData2 = lpData2;
  969. vcp.dwSize2 = dwSize2;
  970. return videoMessage(hVideo, msg, dwFlags,
  971. (DWORD)(LPVIDEOCONFIGPARMS)&vcp );
  972. }
  973. /*****************************************************************************
  974. * @doc EXTERNAL VIDEO
  975. *
  976. * @api DWORD | videoConfigureStorage | This function saves or loads
  977. * all configurable options for a channel. Options
  978. * can be saved and recalled for each application or each application
  979. * instance.
  980. *
  981. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  982. *
  983. * @parm LPSTR | lpstrIdent | Identifies the application or instance.
  984. * Use an arbitrary string which uniquely identifies your application
  985. * or instance.
  986. *
  987. * @parm DWORD | dwFlags | Specifies any flags for the function. The following
  988. * flags are defined:
  989. * @flag VIDEO_CONFIGURE_GET | Requests that the values be loaded.
  990. * @flag VIDEO_CONFIGURE_SET | Requests that the values be saved.
  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 | Specified device handle is invalid.
  995. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  996. *
  997. * @comm The method used by a driver to save configuration options is
  998. * device dependent.
  999. *
  1000. * @xref <f videoOpen>
  1001. ****************************************************************************/
  1002. #if defined _WIN32
  1003. //
  1004. // for win32 this is the ansi entry point
  1005. //
  1006. DWORD WINAPI videoConfigureStorageA (
  1007. HVIDEO hVideo,
  1008. LPSTR lpstrIdent,
  1009. DWORD dwFlags)
  1010. {
  1011. DWORD ret;
  1012. LPWSTR lpwstr;
  1013. if (!hVideo)
  1014. return DV_ERR_INVALHANDLE;
  1015. // Convert the input string to Unicode
  1016. // Call the driver, free the Unicode string and return the result
  1017. ret = strlen(lpstrIdent);
  1018. lpwstr = LocalAlloc(LPTR, ret*sizeof(WCHAR));
  1019. if (!lpwstr) {
  1020. return(DV_ERR_NOMEM);
  1021. }
  1022. mbstowcs(lpwstr, lpstrIdent, ret);
  1023. ret = videoMessage(hVideo, DVM_CONFIGURESTORAGE,
  1024. (DWORD)lpwstr, dwFlags);
  1025. LocalFree(lpwstr);
  1026. return(ret);
  1027. }
  1028. #endif // _WIN32
  1029. // this code is correct for WIN32 UNICODE and for win16
  1030. // messages we send are expected to contain unicode strings.
  1031. // so send them off...
  1032. //
  1033. #ifdef _WIN32
  1034. DWORD WINAPI videoConfigureStorageW (HVIDEO hVideo,
  1035. LPWSTR lpstrIdent, DWORD dwFlags)
  1036. #else
  1037. DWORD WINAPI videoConfigureStorage (HVIDEO hVideo,
  1038. LPSTR lpstrIdent, DWORD dwFlags)
  1039. #endif
  1040. {
  1041. if (!hVideo)
  1042. return DV_ERR_INVALHANDLE;
  1043. return videoMessage(hVideo, DVM_CONFIGURESTORAGE,
  1044. (DWORD)lpstrIdent, dwFlags);
  1045. }
  1046. /*****************************************************************************
  1047. * @doc EXTERNAL VIDEO
  1048. *
  1049. * @api DWORD | videoDialog | This function displays a channel-specific
  1050. * dialog box used to set configuration parameters.
  1051. *
  1052. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1053. *
  1054. * @parm HWND | hWndParent | Specifies the parent window handle.
  1055. *
  1056. * @parm DWORD | dwFlags | Specifies flags for the dialog box. The
  1057. * following flag is defined:
  1058. * @flag VIDEO_DLG_QUERY | If this flag is set, the driver immediately
  1059. * returns zero if it supplies a dialog box for the channel,
  1060. * or DV_ERR_NOTSUPPORTED if it does not.
  1061. *
  1062. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1063. * an error number. The following errors are defined:
  1064. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  1065. * @flag DV_ERR_NOTSUPPORTED | Function is not supported.
  1066. *
  1067. * @comm Typically, each dialog box displayed by this
  1068. * function lets the user select options appropriate for the channel.
  1069. * For example, a VIDEO_IN channel dialog box lets the user select
  1070. * the image dimensions and bit depth.
  1071. *
  1072. * @xref <f videoOpen> <f videoConfigureStorage>
  1073. ****************************************************************************/
  1074. DWORD WINAPI videoDialog (HVIDEO hVideo, HWND hWndParent, DWORD dwFlags)
  1075. {
  1076. if (!hVideo)
  1077. return DV_ERR_INVALHANDLE;
  1078. if ((!hWndParent) || (!IsWindow (hWndParent)) )
  1079. return DV_ERR_INVALHANDLE;
  1080. return videoMessage(hVideo, DVM_DIALOG, (DWORD)hWndParent, dwFlags);
  1081. }
  1082. //////////////////////////////////////////////////////////////////////////
  1083. //////////////////////////////////////////////////////////////////////////
  1084. /*****************************************************************************
  1085. * @doc INTERNAL VIDEO
  1086. *
  1087. * @api DWORD | videoPrepareHeader | This function prepares the
  1088. * header and data
  1089. * by performing a <f GlobalPageLock>.
  1090. *
  1091. * @rdesc Returns zero if the function was successful. Otherwise, it
  1092. * specifies an error number.
  1093. ****************************************************************************/
  1094. DWORD WINAPI videoPrepareHeader(LPVIDEOHDR lpVideoHdr, DWORD dwSize)
  1095. {
  1096. if (!HugePageLock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR)))
  1097. return DV_ERR_NOMEM;
  1098. if (!HugePageLock(lpVideoHdr->lpData, lpVideoHdr->dwBufferLength)) {
  1099. HugePageUnlock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR));
  1100. return DV_ERR_NOMEM;
  1101. }
  1102. lpVideoHdr->dwFlags |= VHDR_PREPARED;
  1103. return DV_ERR_OK;
  1104. }
  1105. /*****************************************************************************
  1106. * @doc INTERNAL VIDEO
  1107. *
  1108. * @api DWORD | videoUnprepareHeader | This function unprepares the header and
  1109. * data if the driver returns DV_ERR_NOTSUPPORTED.
  1110. *
  1111. * @rdesc Currently always returns DV_ERR_OK.
  1112. ****************************************************************************/
  1113. DWORD WINAPI videoUnprepareHeader(LPVIDEOHDR lpVideoHdr, DWORD dwSize)
  1114. {
  1115. HugePageUnlock(lpVideoHdr->lpData, lpVideoHdr->dwBufferLength);
  1116. HugePageUnlock(lpVideoHdr, (DWORD)sizeof(VIDEOHDR));
  1117. lpVideoHdr->dwFlags &= ~VHDR_PREPARED;
  1118. return DV_ERR_OK;
  1119. }
  1120. //////////////////////////////////////////////////////////////////////////
  1121. //////////////////////////////////////////////////////////////////////////
  1122. /*****************************************************************************
  1123. * @doc EXTERNAL VIDEO
  1124. *
  1125. * @api DWORD | videoStreamAllocHdrAndBuffer | This function is used to allow
  1126. * drivers to optionally allocate video buffers. Normally, the client
  1127. * application is responsible for allocating buffer memory, but devices
  1128. * which have on-board memory may optionally allocate headers and buffers
  1129. * using this function. Generally, this will avoid an additional data copy,
  1130. * resulting in faster capture rates.
  1131. *
  1132. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1133. * device channel.
  1134. *
  1135. * @parm LPVIDEOHDR FAR * | plpvideoHdr | Specifies a pointer to the address of a
  1136. * <t VIDEOHDR> structure. The driver saves the buffer address in this
  1137. * location, or NULL if it cannot allocate a buffer.
  1138. *
  1139. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure
  1140. * and associated video buffer in bytes.
  1141. *
  1142. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1143. * an error number. The following errors are defined:
  1144. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1145. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  1146. * @flag DV_ERR_NOTSUPPORTED | Indicates the driver does not have on-board memory.
  1147. *
  1148. * @comm If the driver
  1149. * allocates buffers via this method, the <f videoStreamPrepareHeader> and
  1150. * <f videoStreamUnprepareHeader> functions must not be used.
  1151. *
  1152. * The buffer allocated must be accessible for DMA by the host.
  1153. *
  1154. * @xref <f videoStreamFreeHdrAndBuffer>
  1155. ****************************************************************************/
  1156. DWORD WINAPI videoStreamAllocHdrAndBuffer(HVIDEO hVideo,
  1157. LPVIDEOHDR FAR * plpvideoHdr, DWORD dwSize)
  1158. {
  1159. DWORD wRet;
  1160. if (!hVideo)
  1161. return DV_ERR_INVALHANDLE;
  1162. if (IsBadWritePtr (plpvideoHdr, sizeof (VIDEOHDR *)) )
  1163. return DV_ERR_PARAM1;
  1164. *plpvideoHdr = NULL; // Init to NULL ptr
  1165. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_ALLOCHDRANDBUFFER,
  1166. (DWORD)plpvideoHdr, (DWORD)dwSize);
  1167. if (*plpvideoHdr == NULL ||
  1168. IsBadHugeWritePtr (*plpvideoHdr, dwSize)) {
  1169. DebugErr(DBF_WARNING,"videoStreamAllocHdrAndBuffer: Allocation failed.");
  1170. *plpvideoHdr = NULL;
  1171. return wRet;
  1172. }
  1173. if (IsVideoHeaderPrepared(HVIDEO, *plpvideoHdr))
  1174. {
  1175. DebugErr(DBF_WARNING,"videoStreamAllocHdrAndBuffer: header is already prepared.");
  1176. return DV_ERR_OK;
  1177. }
  1178. (*plpvideoHdr)->dwFlags = 0;
  1179. if (wRet == DV_ERR_OK)
  1180. MarkVideoHeaderPrepared(hVideo, *plpvideoHdr);
  1181. return wRet;
  1182. }
  1183. /*****************************************************************************
  1184. * @doc EXTERNAL VIDEO
  1185. *
  1186. * @api DWORD | videoStreamFreeHdrAndBuffer | This function is used to free
  1187. * buffers allocated by the driver using the <f videoStreamAllocHdrAndBuffer>
  1188. * function.
  1189. *
  1190. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1191. * device channel.
  1192. *
  1193. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to the
  1194. * <t VIDEOHDR> structure and associated buffer to be freed.
  1195. *
  1196. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1197. * an error number. The following errors are defined:
  1198. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1199. * @flag DV_ERR_NOTSUPPORTED | Indicates the driver does not have on-board memory.
  1200. *
  1201. * @comm If the driver
  1202. * allocates buffers via this method, the <f videoStreamPrepareHeader> and
  1203. * <f videoStreamUnprepareHeader> functions must not be used.
  1204. *
  1205. * @xref <f videoStreamAllocHdrAndBuffer>
  1206. ****************************************************************************/
  1207. DWORD WINAPI videoStreamFreeHdrAndBuffer(HVIDEO hVideo,
  1208. LPVIDEOHDR lpvideoHdr)
  1209. {
  1210. DWORD wRet;
  1211. if (!hVideo)
  1212. return DV_ERR_INVALHANDLE;
  1213. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1214. return DV_ERR_PARAM1;
  1215. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  1216. {
  1217. DebugErr(DBF_WARNING, "videoStreamFreeHdrAndBuffer: buffer still in queue.");
  1218. return DV_ERR_STILLPLAYING;
  1219. }
  1220. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  1221. {
  1222. DebugErr(DBF_WARNING,"videoStreamFreeHdrAndBuffer: header is not prepared.");
  1223. }
  1224. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_FREEHDRANDBUFFER,
  1225. (DWORD)lpvideoHdr, (DWORD)0);
  1226. if (wRet != DV_ERR_OK)
  1227. {
  1228. DebugErr(DBF_WARNING,"videoStreamFreeHdrAndBuffer: Error freeing buffer.");
  1229. }
  1230. return wRet;
  1231. }
  1232. /*****************************************************************************
  1233. * @doc EXTERNAL VIDEO
  1234. *
  1235. * @api DWORD | videoStreamPrepareHeader | This function prepares a buffer
  1236. * for video streaming.
  1237. *
  1238. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1239. * device channel.
  1240. *
  1241. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to a
  1242. * <t VIDEOHDR> structure identifying the buffer to be prepared.
  1243. *
  1244. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  1245. *
  1246. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1247. * an error number. The following errors are defined:
  1248. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1249. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  1250. *
  1251. * @comm Use this function after <f videoStreamInit> or
  1252. * after <f videoStreamReset> to prepare the data buffers
  1253. * for streaming data.
  1254. *
  1255. * The <t VIDEOHDR> data structure and the data block pointed to by its
  1256. * <e VIDEOHDR.lpData> member must be allocated with <f GlobalAlloc> using the
  1257. * GMEM_MOVEABLE and GMEM_SHARE flags, and locked with <f GlobalLock>.
  1258. * Preparing a header that has already been prepared will have no effect
  1259. * and the function will return zero. Typically, this function is used
  1260. * to ensure that the buffer will be available for use at interrupt time.
  1261. *
  1262. * @xref <f videoStreamUnprepareHeader>
  1263. ****************************************************************************/
  1264. DWORD WINAPI videoStreamPrepareHeader(HVIDEO hVideo,
  1265. LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  1266. {
  1267. DWORD wRet;
  1268. if (!hVideo)
  1269. return DV_ERR_INVALHANDLE;
  1270. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1271. return DV_ERR_PARAM1;
  1272. if (IsVideoHeaderPrepared(HVIDEO, lpvideoHdr))
  1273. {
  1274. DebugErr(DBF_WARNING,"videoStreamPrepareHeader: header is already prepared.");
  1275. return DV_ERR_OK;
  1276. }
  1277. lpvideoHdr->dwFlags = 0;
  1278. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_PREPAREHEADER,
  1279. (DWORD)lpvideoHdr, (DWORD)dwSize);
  1280. if (wRet == DV_ERR_NOTSUPPORTED)
  1281. wRet = videoPrepareHeader(lpvideoHdr, dwSize);
  1282. if (wRet == DV_ERR_OK)
  1283. MarkVideoHeaderPrepared(hVideo, lpvideoHdr);
  1284. return wRet;
  1285. }
  1286. /*****************************************************************************
  1287. * @doc EXTERNAL VIDEO
  1288. *
  1289. * @api DWORD | videoStreamUnprepareHeader | This function clears the
  1290. * preparation performed by <f videoStreamPrepareHeader>.
  1291. *
  1292. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1293. * device channel.
  1294. *
  1295. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a pointer to a <t VIDEOHDR>
  1296. * structure identifying the data buffer to be unprepared.
  1297. *
  1298. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  1299. *
  1300. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1301. * an error number. The following errors are defined:
  1302. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1303. * @flag DV_ERR_STILLPLAYING | Indicates the structure identified by <p lpvideoHdr>
  1304. * is still in the queue.
  1305. *
  1306. * @comm This function is the complementary function to <f videoStreamPrepareHeader>.
  1307. * You must call this function before freeing the data buffer with <f GlobalFree>.
  1308. * After passing a buffer to the device driver with <f videoStreamAddBuffer>, you
  1309. * must wait until the driver is finished with the buffer before calling
  1310. * <f videoStreamUnprepareHeader>. Unpreparing a buffer that has not been
  1311. * prepared or has been already unprepared has no effect,
  1312. * and the function returns zero.
  1313. *
  1314. * @xref <f videoStreamPrepareHeader>
  1315. ****************************************************************************/
  1316. DWORD WINAPI videoStreamUnprepareHeader(HVIDEO hVideo, LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  1317. {
  1318. DWORD wRet;
  1319. if (!hVideo)
  1320. return DV_ERR_INVALHANDLE;
  1321. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1322. return DV_ERR_PARAM1;
  1323. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  1324. {
  1325. DebugErr(DBF_WARNING, "videoStreamUnprepareHeader: buffer still in queue.");
  1326. return DV_ERR_STILLPLAYING;
  1327. }
  1328. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  1329. {
  1330. DebugErr(DBF_WARNING,"videoStreamUnprepareHeader: header is not prepared.");
  1331. return DV_ERR_OK;
  1332. }
  1333. wRet = (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_UNPREPAREHEADER,
  1334. (DWORD)lpvideoHdr, (DWORD)dwSize);
  1335. if (wRet == DV_ERR_NOTSUPPORTED)
  1336. wRet = videoUnprepareHeader(lpvideoHdr, dwSize);
  1337. if (wRet == DV_ERR_OK)
  1338. MarkVideoHeaderUnprepared(hVideo, lpvideoHdr);
  1339. return wRet;
  1340. }
  1341. /*****************************************************************************
  1342. * @doc EXTERNAL VIDEO
  1343. *
  1344. * @api DWORD | videoStreamAddBuffer | This function sends a buffer to a
  1345. * video-capture device. After the buffer is filled by the device,
  1346. * the device sends it back to the application.
  1347. *
  1348. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1349. *
  1350. * @parm LPVIDEOHDR | lpvideoHdr | Specifies a far pointer to a <t VIDEOHDR>
  1351. * structure that identifies the buffer.
  1352. *
  1353. * @parm DWORD | dwSize | Specifies the size of the <t VIDEOHDR> structure in bytes.
  1354. *
  1355. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1356. * an error number. The following errors are defined:
  1357. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1358. * @flag DV_ERR_UNPREPARED | Indicates the <p lpvideoHdr> structure hasn't been prepared.
  1359. * @flag DV_ERR_STILLPLAYING | Indicates a buffer is still in the queue.
  1360. * @flag DV_ERR_PARAM1 | The <p lpvideoHdr> parameter is invalid or
  1361. * the <e VIDEOHDR.dwBufferLength> member of the <t VIDEOHDR>
  1362. * structure is not set to the proper value.
  1363. *
  1364. * @comm The data buffer must be prepared with <f videoStreamPrepareHeader>
  1365. * before it is passed to <f videoStreamAddBuffer>. The <t VIDEOHDR> data
  1366. * structure and the data buffer referenced by its <e VIDEOHDR.lpData>
  1367. * member must be allocated with <f GlobalAlloc> using the GMEM_MOVEABLE
  1368. * and GMEM_SHARE flags, and locked with <f GlobalLock>. Set the
  1369. * <e VIDEOHDR.dwBufferLength> member to the size of the header.
  1370. *
  1371. * @xref <f videoStreamPrepareHeader>
  1372. ****************************************************************************/
  1373. DWORD WINAPI videoStreamAddBuffer(HVIDEO hVideo, LPVIDEOHDR lpvideoHdr, DWORD dwSize)
  1374. {
  1375. if (!hVideo)
  1376. return DV_ERR_INVALHANDLE;
  1377. if (IsBadWritePtr (lpvideoHdr, sizeof (VIDEOHDR)) )
  1378. return DV_ERR_PARAM1;
  1379. if (!IsVideoHeaderPrepared(hVideo, lpvideoHdr))
  1380. {
  1381. DebugErr(DBF_WARNING, "videoStreamAddBuffer: buffer not prepared.");
  1382. return DV_ERR_UNPREPARED;
  1383. }
  1384. if (lpvideoHdr->dwFlags & VHDR_INQUEUE)
  1385. {
  1386. DebugErr(DBF_WARNING, "videoStreamAddBuffer: buffer already in queue.");
  1387. return DV_ERR_STILLPLAYING;
  1388. }
  1389. return (DWORD)videoMessage((HVIDEO)hVideo, DVM_STREAM_ADDBUFFER, (DWORD)lpvideoHdr, (DWORD)dwSize);
  1390. }
  1391. /*****************************************************************************
  1392. * @doc EXTERNAL VIDEO
  1393. *
  1394. * @api DWORD | videoStreamStop | This function stops streaming on a video channel.
  1395. *
  1396. * @parm HVIDEO | hVideo | Specifies a handle to the video
  1397. * device channel.
  1398. *
  1399. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1400. * an error number. The following error is defined:
  1401. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1402. *
  1403. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1404. * function.
  1405. * @comm If there are any buffers in the queue, the current buffer will be
  1406. * marked as done (the <e VIDEOHDR.dwBytesRecorded> member in
  1407. * the <t VIDEOHDR> header will contain the actual length of data), but any
  1408. * empty buffers in the queue will remain there. Calling this
  1409. * function when the channel is not started has no effect, and the
  1410. * function returns zero.
  1411. *
  1412. * @xref <f videoStreamStart> <f videoStreamReset>
  1413. ****************************************************************************/
  1414. DWORD WINAPI videoStreamStop(HVIDEO hVideo)
  1415. {
  1416. if (!hVideo)
  1417. return DV_ERR_INVALHANDLE;
  1418. return videoMessage((HVIDEO)hVideo, DVM_STREAM_STOP, 0L, 0L);
  1419. }
  1420. /*****************************************************************************
  1421. * @doc EXTERNAL VIDEO
  1422. *
  1423. * @api DWORD | videoStreamReset | This function stops streaming
  1424. * on the specified video device channel and resets the current position
  1425. * to zero. All pending buffers are marked as done and
  1426. * are returned to the application.
  1427. *
  1428. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1429. *
  1430. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1431. * an error number. The following errors are defined:
  1432. *
  1433. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1434. *
  1435. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1436. * function.
  1437. *
  1438. * @xref <f videoStreamReset> <f videoStreamStop> <f videoStreamAddBuffer> <f videoStreamClose>
  1439. /****************************************************************************/
  1440. DWORD WINAPI videoStreamReset(HVIDEO hVideo)
  1441. {
  1442. if (!hVideo)
  1443. return DV_ERR_INVALHANDLE;
  1444. return videoMessage((HVIDEO)hVideo, DVM_STREAM_RESET, 0L, 0L);
  1445. }
  1446. /*****************************************************************************
  1447. * @doc EXTERNAL VIDEO
  1448. *
  1449. * @api DWORD | videoStreamGetPosition | This function retrieves the current
  1450. * position of the specified video device channel.
  1451. *
  1452. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1453. *
  1454. * @parm LPMMTIME | lpInfo | Specifies a far pointer to an <t MMTIME>
  1455. * structure.
  1456. *
  1457. * @parm DWORD | dwSize | Specifies the size of the <t MMTIME> structure in bytes.
  1458. *
  1459. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1460. * an error number. The following errors are defined:
  1461. *
  1462. * @flag DV_ERR_INVALHANDLE | Indicates the specified device handle is invalid.
  1463. *
  1464. * @comm Before using <f videoStreamGetPosition>, set the
  1465. * <e MMTIME.wType> member of the <t MMTIME> structure to indicate
  1466. * the time format desired. After
  1467. * <f videoStreamGetPosition> returns, check the <e MMTIME.wType>
  1468. * member to determine if the your time format is supported. If
  1469. * not, <e MMTIME.wType> specifies an alternate format.
  1470. * Video capture drivers typically provide the millisecond time
  1471. * format.
  1472. *
  1473. * The position is set to zero when streaming is started with
  1474. * <f videoStreamStart>.
  1475. ****************************************************************************/
  1476. DWORD WINAPI videoStreamGetPosition(HVIDEO hVideo, LPMMTIME lpInfo, DWORD dwSize)
  1477. {
  1478. if (!hVideo)
  1479. return DV_ERR_INVALHANDLE;
  1480. if (IsBadWritePtr (lpInfo, sizeof (MMTIME)) )
  1481. return DV_ERR_PARAM1;
  1482. return videoMessage(hVideo, DVM_STREAM_GETPOSITION,
  1483. (DWORD)lpInfo, (DWORD)dwSize);
  1484. }
  1485. // ============================================
  1486. /*****************************************************************************
  1487. * @doc EXTERNAL VIDEO
  1488. *
  1489. * @api DWORD | videoStreamInit | This function initializes a video
  1490. * device channel for streaming.
  1491. *
  1492. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1493. *
  1494. * @parm DWORD | dwMicroSecPerFrame | Specifies the number of microseconds
  1495. * between frames.
  1496. *
  1497. * @parm DWORD | dwCallback | Specifies the address of a callback
  1498. * function or a handle to a window called during video
  1499. * streaming. The callback function or window processes
  1500. * messages related to the progress of streaming.
  1501. *
  1502. * @parm DWORD | dwCallbackInstance | Specifies user
  1503. * instance data passed to the callback function. This parameter is not
  1504. * used with window callbacks.
  1505. *
  1506. * @parm DWORD | dwFlags | Specifies flags for opening the device channel.
  1507. * The following flags are defined:
  1508. * @flag CALLBACK_WINDOW | If this flag is specified, <p dwCallback> is
  1509. * a window handle.
  1510. * @flag CALLBACK_FUNCTION | If this flag is specified, <p dwCallback> is
  1511. * a callback procedure address.
  1512. *
  1513. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1514. * an error number. The following errors are defined:
  1515. * @flag DV_ERR_BADDEVICEID | Indicates the device ID specified in
  1516. * <p hVideo> is not valid.
  1517. * @flag DV_ERR_ALLOCATED | Indicates the resource specified is already allocated.
  1518. * @flag DV_ERR_NOMEM | Indicates the device is unable to allocate or lock memory.
  1519. *
  1520. * @comm If a window or function is chosen to receive callback information, the following
  1521. * messages are sent to it to indicate the
  1522. * progress of video input:
  1523. *
  1524. * <m MM_DRVM_OPEN> is sent at the time of <f videoStreamInit>
  1525. *
  1526. * <m MM_DRVM_CLOSE> is sent at the time of <f videoStreamFini>
  1527. *
  1528. * <m MM_DRVM_DATA> is sent when a buffer of image data is available
  1529. *
  1530. * <m MM_DRVM_ERROR> is sent when an error occurs
  1531. *
  1532. * Callback functions must reside in a DLL.
  1533. * You do not have to use <f MakeProcInstance> to get
  1534. * a procedure-instance address for the callback function.
  1535. *
  1536. * @cb void CALLBACK | videoFunc | <f videoFunc> is a placeholder for an
  1537. * application-supplied function name. The actual name must be exported by
  1538. * including it in an EXPORTS statement in the DLL's module-definition file.
  1539. * This is used only when a callback function is specified in
  1540. * <f videoStreamInit>.
  1541. *
  1542. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel
  1543. * associated with the callback.
  1544. *
  1545. * @parm DWORD | wMsg | Specifies the <m MM_DRVM_> messages. Messages indicate
  1546. * errors and when image data is available. For information on
  1547. * these messages, see <f videoStreamInit>.
  1548. *
  1549. * @parm DWORD | dwInstance | Specifies the user instance
  1550. * data specified with <f videoStreamInit>.
  1551. *
  1552. * @parm DWORD | dwParam1 | Specifies a parameter for the message.
  1553. *
  1554. * @parm DWORD | dwParam2 | Specifies a parameter for the message.
  1555. *
  1556. * @comm Because the callback is accessed at interrupt time, it must reside
  1557. * in a DLL and its code segment must be specified as FIXED in the
  1558. * module-definition file for the DLL. Any data the callback accesses
  1559. * must be in a FIXED data segment as well. The callback may not make any
  1560. * system calls except for <f PostMessage>, <f timeGetSystemTime>,
  1561. * <f timeGetTime>, <f timeSetEvent>, <f timeKillEvent>,
  1562. * <f midiOutShortMsg>, <f midiOutLongMsg>, and <f OutputDebugStr>.
  1563. *
  1564. * @xref <f videoOpen> <f videoStreamFini> <f videoClose>
  1565. ****************************************************************************/
  1566. DWORD WINAPI videoStreamInit(HVIDEO hVideo,
  1567. DWORD dwMicroSecPerFrame, DWORD_PTR dwCallback,
  1568. DWORD_PTR dwCallbackInst, DWORD dwFlags)
  1569. {
  1570. VIDEO_STREAM_INIT_PARMS vsip;
  1571. if (!hVideo)
  1572. return DV_ERR_INVALHANDLE;
  1573. if (dwCallback && ((dwFlags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) ) {
  1574. if (IsBadCodePtr ((FARPROC) dwCallback) )
  1575. return DV_ERR_PARAM2;
  1576. if (!dwCallbackInst)
  1577. return DV_ERR_PARAM2;
  1578. }
  1579. if (dwCallback && ((dwFlags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) ) {
  1580. if (!IsWindow((HWND) dwCallback) )
  1581. return DV_ERR_PARAM2;
  1582. }
  1583. vsip.dwMicroSecPerFrame = dwMicroSecPerFrame;
  1584. vsip.dwCallback = dwCallback;
  1585. vsip.dwCallbackInst = dwCallbackInst;
  1586. vsip.dwFlags = dwFlags;
  1587. vsip.hVideo = (DWORD_PTR)hVideo;
  1588. return videoMessage(hVideo, DVM_STREAM_INIT,
  1589. (DWORD_PTR) (LPVIDEO_STREAM_INIT_PARMS) &vsip,
  1590. (DWORD) sizeof (VIDEO_STREAM_INIT_PARMS));
  1591. }
  1592. /*****************************************************************************
  1593. * @doc EXTERNAL VIDEO
  1594. *
  1595. * @api DWORD | videoStreamFini | This function terminates streaming
  1596. * from the specified device channel.
  1597. *
  1598. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1599. *
  1600. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1601. * an error number. The following errors are defined:
  1602. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1603. * @flag DV_ERR_STILLPLAYING | Indicates there are still buffers in the queue.
  1604. *
  1605. * @comm If there are buffers that have been sent with
  1606. * <f videoStreamAddBuffer> that haven't been returned to the application,
  1607. * this operation will fail. Use <f videoStreamReset> to return all
  1608. * pending buffers.
  1609. *
  1610. * Each call to <f videoStreamInit> must be matched with a call to
  1611. * <f videoStreamFini>.
  1612. *
  1613. * For VIDEO_EXTERNALIN channels, this function is used to
  1614. * halt capturing of data to the frame buffer.
  1615. *
  1616. * For VIDEO_EXTERNALOUT channels supporting overlay,
  1617. * this function is used to disable the overlay.
  1618. *
  1619. * @xref <f videoStreamInit>
  1620. ****************************************************************************/
  1621. DWORD WINAPI videoStreamFini(HVIDEO hVideo)
  1622. {
  1623. if (!hVideo)
  1624. return DV_ERR_INVALHANDLE;
  1625. return videoMessage(hVideo, DVM_STREAM_FINI, 0L, 0L);
  1626. }
  1627. /*****************************************************************************
  1628. * @doc EXTERNAL VIDEO
  1629. *
  1630. * @api DWORD | videoStreamStart | This function starts streaming on the
  1631. * specified video device channel.
  1632. *
  1633. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1634. *
  1635. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1636. * an error number. The following errors are defined:
  1637. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1638. *
  1639. * @flag DV_ERR_NOTSUPPORTED | Indicates the device does not support this
  1640. * function.
  1641. *
  1642. * @xref <f videoStreamReset> <f videoStreamStop> <f videoStreamAddBuffer> <f videoStreamClose>
  1643. /****************************************************************************/
  1644. DWORD WINAPI videoStreamStart(HVIDEO hVideo)
  1645. {
  1646. if (!hVideo)
  1647. return DV_ERR_INVALHANDLE;
  1648. return videoMessage(hVideo, DVM_STREAM_START, 0L, 0L);
  1649. }
  1650. /*****************************************************************************
  1651. * @doc EXTERNAL VIDEO
  1652. *
  1653. * @api DWORD | videoStreamGetError | This function returns the error
  1654. * most recently encountered.
  1655. *
  1656. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1657. *
  1658. * @parm LPDWORD | lpdwErrorID | Specifies a far pointer to the <t DWORD>
  1659. * used to return the error ID.
  1660. *
  1661. * @parm LPDWORD | lpdwErrorValue | Specifies a far pointer to the <t DWORD>
  1662. * used to return the number of frames skipped.
  1663. *
  1664. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1665. * an error number. The following error is defined:
  1666. * @flag DV_ERR_INVALHANDLE | Indicates the device handle specified is invalid.
  1667. *
  1668. * @comm While streaming video data, a capture
  1669. * driver can fill buffers faster than the client application can
  1670. * save the buffers to disk. In this case, the
  1671. * DV_ERR_NO_BUFFERS error is returned in <p lpdwErrorID>
  1672. * and <p lpdwErrorValue> contains a count of the number of
  1673. * frames missed. After
  1674. * receiving this message and returning the error status, a driver
  1675. * should reset its internal error flag to DV_ERR_OK and
  1676. * the count of missed frames to zero.
  1677. *
  1678. * Applications should send this message frequently during capture
  1679. * since some drivers which do not have access to interrupts use
  1680. * this message to trigger buffer processing.
  1681. *
  1682. * @xref <f videoOpen>
  1683. /****************************************************************************/
  1684. DWORD WINAPI videoStreamGetError(HVIDEO hVideo, LPDWORD lpdwError,
  1685. LPDWORD lpdwFramesSkipped)
  1686. {
  1687. if (!hVideo)
  1688. return DV_ERR_INVALHANDLE;
  1689. if (IsBadWritePtr (lpdwError, sizeof (DWORD)) )
  1690. return DV_ERR_PARAM1;
  1691. if (IsBadWritePtr (lpdwFramesSkipped, sizeof (DWORD)) )
  1692. return DV_ERR_PARAM2;
  1693. return videoMessage(hVideo, DVM_STREAM_GETERROR, (DWORD) lpdwError,
  1694. (DWORD) lpdwFramesSkipped);
  1695. }
  1696. /*****************************************************************************
  1697. * @doc EXTERNAL VIDEO
  1698. *
  1699. * @api DWORD | videoFrame | This function transfers a single frame
  1700. * to or from a video device channel.
  1701. *
  1702. * @parm HVIDEO | hVideo | Specifies a handle to the video device channel.
  1703. * The channel must be of type VIDEO_IN or VIDEO_OUT.
  1704. *
  1705. * @parm LPVIDEOHDR | lpVHdr | Specifies a far pointer to an <t VIDEOHDR>
  1706. * structure.
  1707. *
  1708. * @rdesc Returns zero if the function was successful. Otherwise, it returns
  1709. * an error number. The following errors are defined:
  1710. * @flag DV_ERR_INVALHANDLE | Specified device handle is invalid.
  1711. * @flag DV_ERR_PARAM1 | The <p lpVDHdr> parameter is invalid or
  1712. * the <e VIDEOHDR.dwBufferLength> member of the <t VIDEOHDR>
  1713. * structure is not set to the proper value.
  1714. *
  1715. * @comm Use this function with a VIDEO_IN channel to transfer a single
  1716. * image from the frame buffer.
  1717. * Use this function with a VIDEO_OUT channel to transfer a single
  1718. * image to the frame buffer.
  1719. *
  1720. * @xref <f videoOpen>
  1721. /****************************************************************************/
  1722. DWORD WINAPI videoFrame (HVIDEO hVideo, LPVIDEOHDR lpVHdr)
  1723. {
  1724. if (!hVideo)
  1725. return DV_ERR_INVALHANDLE;
  1726. if (!lpVHdr)
  1727. return DV_ERR_PARAM1;
  1728. if (IsBadWritePtr (lpVHdr, sizeof (VIDEOHDR)) )
  1729. return DV_ERR_PARAM1;
  1730. return videoMessage(hVideo, DVM_FRAME, (DWORD) lpVHdr,
  1731. sizeof(VIDEOHDR));
  1732. }
  1733. #endif // ifdef WIN16
  1734. /**************************************************************************
  1735. * @doc INTERNAL VIDEO
  1736. *
  1737. * @api void | videoCleanup | clean up video stuff
  1738. * called in MSVIDEOs WEP()
  1739. *
  1740. **************************************************************************/
  1741. void FAR PASCAL videoCleanup(HTASK hTask)
  1742. {
  1743. #ifdef WIN16
  1744. videoFreeDriverList();
  1745. #endif
  1746. }