Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
5.9 KiB

  1. /****************************************************************************
  2. *
  3. * capframe.c
  4. *
  5. * Single frame capture
  6. *
  7. * Microsoft Video for Windows Sample Capture Class
  8. *
  9. * Copyright (c) 1992, 1993 Microsoft Corporation. All Rights Reserved.
  10. *
  11. * You have a royalty-free right to use, modify, reproduce and
  12. * distribute the Sample Files (and/or any modified version) in
  13. * any way you find useful, provided that you agree that
  14. * Microsoft has no warranty obligations or liability for any
  15. * Sample Application Files which are modified.
  16. *
  17. ***************************************************************************/
  18. #include <windows.h>
  19. #include <windowsx.h>
  20. #include <mmsystem.h>
  21. #include <memory.h> // for _fmemset
  22. #include <stdlib.h>
  23. #include <ctype.h>
  24. #include <string.h>
  25. #include <msvideo.h>
  26. #include <drawdib.h>
  27. #include <mmddk.h>
  28. #include <avifmt.h>
  29. #include "avicap.h"
  30. #include "avicapi.h"
  31. #ifdef _DEBUG
  32. #define DSTATUS(lpcs, sz) statusUpdateStatus(lpcs, IDS_CAP_INFO, (LPSTR) sz)
  33. #else
  34. #define DSTATUS(lpcs, sz)
  35. #endif
  36. /*
  37. * SingleFrameCaptureOpen
  38. *
  39. */
  40. BOOL FAR PASCAL SingleFrameCaptureOpen (LPCAPSTREAM lpcs)
  41. {
  42. if (lpcs-> fCapturingNow || lpcs-> fFrameCapturingNow) {
  43. lpcs-> dwReturn = IDS_CAP_FILE_OPEN_ERROR;
  44. goto EarlyExit;
  45. }
  46. /* Warm up the compressor function */
  47. if (lpcs->CompVars.hic) {
  48. if (ICSeqCompressFrameStart(&lpcs->CompVars, lpcs->lpBitsInfo) == FALSE) {
  49. lpcs-> dwReturn = IDS_CAP_COMPRESSOR_ERROR;
  50. goto EarlyExit;
  51. }
  52. // Kludge, offset the lpBitsOut ptr
  53. // Compman allocates the compress buffer too large by
  54. // 2048 + 16 so we will still have room
  55. ((LPBYTE) lpcs->CompVars.lpBitsOut) += 8;
  56. }
  57. if (!AVIFileInit(lpcs)) {
  58. lpcs-> dwReturn = IDS_CAP_FILE_OPEN_ERROR;
  59. goto EarlyExit;
  60. }
  61. lpcs-> fCapturingNow = TRUE;
  62. lpcs-> fFrameCapturingNow = TRUE;
  63. lpcs-> dwReturn = DV_ERR_OK;
  64. statusUpdateStatus(lpcs, IDS_CAP_BEGIN); // Always the first message
  65. return TRUE;
  66. EarlyExit:
  67. errorUpdateError(lpcs, (WORD) lpcs->dwReturn);
  68. return FALSE;
  69. }
  70. /*
  71. * SingleFrameCaptureClose
  72. *
  73. *
  74. */
  75. BOOL FAR PASCAL SingleFrameCaptureClose (LPCAPSTREAM lpcs)
  76. {
  77. if ((!lpcs-> fCapturingNow) && (!lpcs-> fFrameCapturingNow)) {
  78. lpcs-> dwReturn = IDS_CAP_FILE_OPEN_ERROR;
  79. errorUpdateError(lpcs, (WORD) lpcs->dwReturn);
  80. return FALSE;
  81. }
  82. AVIFileFini(lpcs, FALSE /* fWroteJunkChunks */, FALSE /* fAbort */);
  83. if (lpcs->CompVars.hic) {
  84. // Kludge, offset the lpBitsOut ptr
  85. if (lpcs->CompVars.lpBitsOut)
  86. ((LPBYTE) lpcs->CompVars.lpBitsOut) -= 8;
  87. ICSeqCompressFrameEnd(&lpcs->CompVars);
  88. }
  89. lpcs->fCapFileExists = (lpcs-> dwReturn == DV_ERR_OK);
  90. lpcs->fCapturingNow = FALSE;
  91. lpcs->fFrameCapturingNow = FALSE;
  92. statusUpdateStatus(lpcs, IDS_CAP_END); // Always the last message
  93. return TRUE;
  94. }
  95. // Writes compressed or uncompressed frames to the AVI file
  96. // returns TRUE if no error, FALSE if end of file,
  97. // and sets pfKey and plSize on exit.
  98. BOOL SingleFrameWrite (
  99. LPCAPSTREAM lpcs, // capture stream
  100. LPVIDEOHDR lpVidHdr, // input header
  101. BOOL FAR *pfKey, // did it end up being a key frame?
  102. LONG FAR *plSize) // size of returned image
  103. {
  104. MMCKINFO ck;
  105. BOOL fOK = TRUE;
  106. DWORD dwBytesUsed;
  107. BOOL fKeyFrame;
  108. LPSTR lpBits;
  109. if ((!lpcs-> fCapturingNow) ||
  110. (!(lpcs-> fStepCapturingNow || lpcs-> fFrameCapturingNow)) ||
  111. (!lpcs->hmmio)) {
  112. lpcs-> dwReturn = IDS_CAP_FILE_OPEN_ERROR;
  113. return FALSE;
  114. }
  115. /* Now compress the DIB to the format they chose */
  116. if (lpcs->CompVars.hic) {
  117. dwBytesUsed = 0; // don't force a data rate
  118. lpBits = ICSeqCompressFrame(&lpcs->CompVars, 0,
  119. lpcs->lpBits, &fKeyFrame, &dwBytesUsed);
  120. /* They don't want it compressed */
  121. } else {
  122. // Use current values for writing the DIB to disk
  123. dwBytesUsed = lpcs->VidHdr.dwBytesUsed;
  124. fKeyFrame = (BOOL)(lpcs->VidHdr.dwFlags & VHDR_KEYFRAME);
  125. lpBits = lpcs->lpBits;
  126. }
  127. /* Create DIB Bits chunk */
  128. ck.cksize = dwBytesUsed;
  129. ck.ckid = MAKEAVICKID(cktypeDIBbits,0);
  130. ck.fccType = 0;
  131. if (mmioCreateChunk(lpcs->hmmio,&ck,0)) {
  132. fOK = FALSE;
  133. }
  134. /* Write DIB data */
  135. if (fOK && mmioWrite(lpcs->hmmio, lpBits, dwBytesUsed) !=
  136. (LONG) dwBytesUsed) {
  137. fOK = FALSE;
  138. }
  139. if (fOK && mmioAscend(lpcs->hmmio, &ck, 0)) {
  140. fOK = FALSE;
  141. }
  142. *pfKey = fKeyFrame;
  143. *plSize = dwBytesUsed;
  144. return fOK;
  145. }
  146. /*
  147. * SingleFrameCapture
  148. *
  149. * Append to the open single frame capture file.
  150. */
  151. BOOL FAR PASCAL SingleFrameCapture (LPCAPSTREAM lpcs)
  152. {
  153. LPVIDEOHDR lpVidHdr = &lpcs->VidHdr;
  154. BOOL fOK = FALSE;
  155. BOOL fKey;
  156. LONG lSize;
  157. if ((!lpcs-> fCapturingNow) ||
  158. (!(lpcs-> fStepCapturingNow || lpcs-> fFrameCapturingNow)) ||
  159. (!lpcs->hmmio)) {
  160. lpcs-> dwReturn = IDS_CAP_FILE_OPEN_ERROR;
  161. errorUpdateError(lpcs, (WORD) lpcs->dwReturn);
  162. return FALSE;
  163. }
  164. videoFrame( lpcs->hVideoIn, &lpcs->VidHdr );
  165. InvalidateRect( lpcs->hwnd, NULL, TRUE);
  166. if (lpVidHdr-> dwBytesUsed) {
  167. if (lpcs->CallbackOnVideoFrame)
  168. (*(lpcs->CallbackOnVideoFrame)) (lpcs->hwnd, lpVidHdr);
  169. if (!SingleFrameWrite (lpcs, lpVidHdr, &fKey, &lSize)) {
  170. // "ERROR: Could not write to file."
  171. errorUpdateError(lpcs, IDS_CAP_FILE_WRITE_ERROR);
  172. }
  173. else {
  174. fOK = IndexVideo(lpcs, lSize, fKey);
  175. statusUpdateStatus (lpcs, IDS_CAP_STAT_CAP_L_FRAMES,
  176. lpcs-> dwVideoChunkCount);
  177. }
  178. } // if the frame is done
  179. else
  180. errorUpdateError (lpcs, IDS_CAP_RECORDING_ERROR2);
  181. return fOK;
  182. }
  183.