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.

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