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.

264 lines
8.8 KiB

  1. //==========================================================================;
  2. //
  3. // CWDMVideoCaptureStream - Video Capture Stream class implementation
  4. //
  5. // $Date: 05 Aug 1998 11:11:00 $
  6. // $Revision: 1.0 $
  7. // $Author: Tashjian $
  8. //
  9. // $Copyright: (c) 1997 - 1998 ATI Technologies Inc. All Rights Reserved. $
  10. //
  11. //==========================================================================;
  12. extern "C"
  13. {
  14. #include "strmini.h"
  15. #include "ksmedia.h"
  16. #include "ddkmapi.h"
  17. }
  18. #include "wdmvdec.h"
  19. #include "wdmdrv.h"
  20. #include "aticonfg.h"
  21. #include "capdebug.h"
  22. #include "defaults.h"
  23. #include "winerror.h"
  24. CWDMVideoCaptureStream::CWDMVideoCaptureStream(PHW_STREAM_OBJECT pStreamObject,
  25. CWDMVideoDecoder * pCWDMVideoDecoder,
  26. PKSDATAFORMAT pKSDataFormat,
  27. PUINT puiErrorCode)
  28. : CWDMCaptureStream(pStreamObject, pCWDMVideoDecoder, puiErrorCode)
  29. {
  30. m_stateChange = Initializing;
  31. DBGTRACE(("CWDMVideoCaptureStream::Startup()\n"));
  32. PKS_DATAFORMAT_VIDEOINFOHEADER pVideoInfoHeader =
  33. (PKS_DATAFORMAT_VIDEOINFOHEADER) pKSDataFormat;
  34. PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
  35. &pVideoInfoHeader->VideoInfoHeader;
  36. // Since the VIDEOINFOHEADER is of potentially variable size
  37. // allocate memory for it
  38. UINT nSize = KS_SIZE_VIDEOHEADER(pVideoInfoHdrRequested);
  39. DBGINFO(("pVideoInfoHdrRequested=%x\n", pVideoInfoHdrRequested));
  40. DBGINFO(("KS_VIDEOINFOHEADER size=%d\n", nSize));
  41. DBGINFO(("Width=%d Height=%d BitCount=%d\n",
  42. pVideoInfoHdrRequested->bmiHeader.biWidth,
  43. pVideoInfoHdrRequested->bmiHeader.biHeight,
  44. pVideoInfoHdrRequested->bmiHeader.biBitCount));
  45. DBGINFO(("biSizeImage=%d\n",
  46. pVideoInfoHdrRequested->bmiHeader.biSizeImage));
  47. DBGINFO(("AvgTimePerFrame=%d\n",
  48. pVideoInfoHdrRequested->AvgTimePerFrame));
  49. m_pVideoInfoHeader = (PKS_VIDEOINFOHEADER)ExAllocatePool(NonPagedPool, nSize);
  50. if (m_pVideoInfoHeader == NULL) {
  51. DBGERROR(("ExAllocatePool failed\n"));
  52. *puiErrorCode = WDMMINI_ERROR_MEMORYALLOCATION;
  53. return;
  54. }
  55. // Copy the VIDEOINFOHEADER requested to our storage
  56. RtlCopyMemory(
  57. m_pVideoInfoHeader,
  58. pVideoInfoHdrRequested,
  59. nSize);
  60. MRect t(0, 0, pVideoInfoHdrRequested->bmiHeader.biWidth,
  61. pVideoInfoHdrRequested->bmiHeader.biHeight);
  62. m_pDevice->SetRect(t);
  63. Startup(puiErrorCode);
  64. }
  65. CWDMVideoCaptureStream::~CWDMVideoCaptureStream()
  66. {
  67. DBGTRACE(("CWDMVideoCaptureStream::~CWDMVideoCaptureStream()\n"));
  68. Shutdown();
  69. if (m_pVideoInfoHeader) {
  70. ExFreePool(m_pVideoInfoHeader);
  71. m_pVideoInfoHeader = NULL;
  72. }
  73. }
  74. BOOL CWDMVideoCaptureStream::GetCaptureHandle()
  75. {
  76. int streamNumber = m_pStreamObject->StreamNumber;
  77. if (m_hCapture == 0)
  78. {
  79. DBGTRACE(("Stream %d getting capture handle\n", streamNumber));
  80. DDOPENVPCAPTUREDEVICEIN ddOpenCaptureIn;
  81. DDOPENVPCAPTUREDEVICEOUT ddOpenCaptureOut;
  82. RtlZeroMemory(&ddOpenCaptureIn, sizeof(ddOpenCaptureIn));
  83. RtlZeroMemory(&ddOpenCaptureOut, sizeof(ddOpenCaptureOut));
  84. ddOpenCaptureIn.hDirectDraw = m_pVideoPort->GetDirectDrawHandle();
  85. ddOpenCaptureIn.hVideoPort = m_pVideoPort->GetVideoPortHandle();
  86. ddOpenCaptureIn.pfnCaptureClose = DirectDrawEventCallback;
  87. ddOpenCaptureIn.pContext = this;
  88. if ((!ddOpenCaptureIn.hDirectDraw)||
  89. (!ddOpenCaptureIn.hVideoPort)||
  90. (!ddOpenCaptureIn.pfnCaptureClose)||
  91. (!ddOpenCaptureIn.pContext))
  92. {
  93. return FALSE;
  94. }
  95. // Now to get the size, etc
  96. RECT rcImage;
  97. /*
  98. ** HOW BIG IS THE IMAGE REQUESTED (pseudocode follows)
  99. **
  100. ** if (IsRectEmpty (&rcTarget) {
  101. ** SetRect (&rcImage, 0, 0,
  102. ** BITMAPINFOHEADER.biWidth,
  103. BITMAPINFOHEADER.biHeight);
  104. ** }
  105. ** else {
  106. ** // Probably rendering to a DirectDraw surface,
  107. ** // where biWidth is used to expressed the "stride"
  108. ** // in units of pixels (not bytes) of the destination surface.
  109. ** // Therefore, use rcTarget to get the actual image size
  110. **
  111. ** rcImage = rcTarget;
  112. ** }
  113. */
  114. if ((m_pVideoInfoHeader->rcTarget.right -
  115. m_pVideoInfoHeader->rcTarget.left <= 0) ||
  116. (m_pVideoInfoHeader->rcTarget.bottom -
  117. m_pVideoInfoHeader->rcTarget.top <= 0)) {
  118. rcImage.left = rcImage.top = 0;
  119. rcImage.right = m_pVideoInfoHeader->bmiHeader.biWidth - 1;
  120. rcImage.bottom = m_pVideoInfoHeader->bmiHeader.biHeight - 1;
  121. }
  122. else {
  123. rcImage = m_pVideoInfoHeader->rcTarget;
  124. }
  125. int xOrigin, yOrigin;
  126. m_pDevice->GetVideoSurfaceOrigin(&xOrigin, &yOrigin);
  127. ddOpenCaptureIn.dwStartLine = rcImage.top + yOrigin;
  128. ddOpenCaptureIn.dwEndLine = rcImage.bottom + yOrigin;
  129. // Fail-safe
  130. if (ddOpenCaptureIn.dwStartLine > 500)
  131. {
  132. DBGERROR(("Unexpected capture start line. Using default\n"));
  133. ddOpenCaptureIn.dwStartLine = 0;
  134. }
  135. if (ddOpenCaptureIn.dwEndLine > 500)
  136. {
  137. DBGERROR(("Unexpected capture end line. Using default\n"));
  138. ddOpenCaptureIn.dwEndLine = m_pDevice->GetDecoderHeight() - 1;
  139. }
  140. DBGINFO(("Video surface: %d, %d\n",
  141. ddOpenCaptureIn.dwStartLine,
  142. ddOpenCaptureIn.dwEndLine));
  143. ddOpenCaptureIn.dwFlags = DDOPENCAPTURE_VIDEO;
  144. // Integer math, so it will throw away fractional part
  145. m_everyNFields = min (max ( 1,
  146. (ULONG) m_pVideoInfoHeader->AvgTimePerFrame/NTSCFieldDuration),
  147. MAXULONG);
  148. // Now look at that fractional part. If there was a significant
  149. // amount, we'll need to round down to the next nearest
  150. // frame rate (i.e., skip additional field)
  151. // 'Significant' is currently assumed to be 1 uS. That
  152. // is '10' in units of 100ns
  153. if ((m_pVideoInfoHeader->AvgTimePerFrame -
  154. (NTSCFieldDuration * m_everyNFields)) > 10)
  155. {
  156. m_everyNFields++;
  157. }
  158. ddOpenCaptureIn.dwCaptureEveryNFields = m_everyNFields;
  159. DBGINFO(("Capturing every %d fields\n",
  160. ddOpenCaptureIn.dwCaptureEveryNFields));
  161. DxApi(DD_DXAPI_OPENVPCAPTUREDEVICE, &ddOpenCaptureIn, sizeof(ddOpenCaptureIn), &ddOpenCaptureOut, sizeof(ddOpenCaptureOut));
  162. if (ddOpenCaptureOut.ddRVal != DD_OK)
  163. {
  164. m_hCapture = 0;
  165. DBGERROR(("DD_DXAPI_OPENVPCAPTUREDEVICE failed.\n"));
  166. // TRAP();
  167. return FALSE;
  168. }
  169. else
  170. {
  171. m_hCapture = ddOpenCaptureOut.hCapture;
  172. }
  173. }
  174. return TRUE;
  175. }
  176. VOID CWDMVideoCaptureStream::SetFrameInfo(PHW_STREAM_REQUEST_BLOCK pSrb)
  177. {
  178. int streamNumber = m_pStreamObject->StreamNumber;
  179. PSRB_DATA_EXTENSION pSrbExt = (PSRB_DATA_EXTENSION)pSrb->SRBExtension;
  180. PKSSTREAM_HEADER pDataPacket = pSrb->CommandData.DataBufferArray;
  181. LONGLONG droppedThisTime = 0;
  182. PKS_FRAME_INFO pFrameInfo = (PKS_FRAME_INFO) (pDataPacket + 1);
  183. m_FrameInfo.dwFrameFlags = 0;
  184. m_FrameInfo.ExtendedHeaderSize = pFrameInfo->ExtendedHeaderSize;
  185. // Set the discontinuity flag if frames have been previously dropped.
  186. if ((m_FrameInfo.PictureNumber + 1) <
  187. pSrbExt->ddCapBuffInfo.dwFieldNumber/m_everyNFields)
  188. {
  189. droppedThisTime =
  190. pSrbExt->ddCapBuffInfo.dwFieldNumber/m_everyNFields -
  191. (m_FrameInfo.PictureNumber + 1);
  192. m_FrameInfo.DropCount += droppedThisTime;
  193. pDataPacket->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY;
  194. #ifdef DEBUG
  195. static int j;
  196. DBGPRINTF((" D%d ", droppedThisTime));
  197. if ((++j % 10) == 0)
  198. {
  199. DBGERROR(("\n"));
  200. }
  201. #endif
  202. }
  203. m_FrameInfo.PictureNumber = pSrbExt->ddCapBuffInfo.dwFieldNumber/m_everyNFields;
  204. m_FrameInfo.dwFrameFlags |= KS_VIDEO_FLAG_FRAME;
  205. *pFrameInfo = (KS_FRAME_INFO)m_FrameInfo;
  206. }
  207. void CWDMVideoCaptureStream::ResetFrameCounters()
  208. {
  209. m_FrameInfo.PictureNumber = 0;
  210. m_FrameInfo.DropCount = 0;
  211. }
  212. void CWDMVideoCaptureStream::GetDroppedFrames(PKSPROPERTY_DROPPEDFRAMES_CURRENT_S pDroppedFrames)
  213. {
  214. pDroppedFrames->PictureNumber = m_FrameInfo.PictureNumber;
  215. pDroppedFrames->DropCount = m_FrameInfo.DropCount;
  216. pDroppedFrames->AverageFrameSize = m_pVideoInfoHeader->bmiHeader.biSizeImage;
  217. }