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.

1177 lines
36 KiB

  1. // $Header: G:/SwDev/WDM/Video/bt848/rcs/Capvideo.c 1.11 1998/05/08 00:11:02 tomz Exp $
  2. //==========================================================================;
  3. //
  4. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  5. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  6. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  7. // PURPOSE.
  8. //
  9. // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
  10. //
  11. //==========================================================================;
  12. extern "C" {
  13. #include "strmini.h"
  14. #include "ksmedia.h"
  15. #include "ddkmapi.h"
  16. }
  17. #include "capdebug.h"
  18. #include "device.h"
  19. #include "capmain.h"
  20. #define DD_OK 0
  21. ErrorCode VerifyVideoStream( const KS_DATAFORMAT_VIDEOINFOHEADER &vidHDR );
  22. ErrorCode VerifyVideoStream2( const KS_DATAFORMAT_VIDEOINFOHEADER2 &vidHDR );
  23. ErrorCode VerifyVBIStream( const KS_DATAFORMAT_VBIINFOHEADER &rKSDataFormat );
  24. void CheckSrbStatus( PHW_STREAM_REQUEST_BLOCK pSrb );
  25. // notify class we are ready to rock
  26. void STREAMAPI StreamCompleterData( PHW_STREAM_REQUEST_BLOCK pSrb )
  27. {
  28. Trace t("StreamCompleterData()");
  29. DebugOut((1, "*** 1 *** completing SRB %x\n", pSrb));
  30. CheckSrbStatus( pSrb );
  31. StreamClassStreamNotification( StreamRequestComplete, pSrb->StreamObject, pSrb );
  32. StreamClassStreamNotification( ReadyForNextStreamDataRequest, pSrb->StreamObject );
  33. }
  34. // notify class we are ready to rock
  35. void STREAMAPI StreamCompleterControl( PHW_STREAM_REQUEST_BLOCK pSrb )
  36. {
  37. Trace t("StreamCompleterControl()");
  38. CheckSrbStatus( pSrb );
  39. StreamClassStreamNotification( StreamRequestComplete, pSrb->StreamObject, pSrb );
  40. StreamClassStreamNotification( ReadyForNextStreamControlRequest, pSrb->StreamObject );
  41. }
  42. /* Function: ProposeDataFormat
  43. * Purpose: Verifies that data format can be supported
  44. * Input: SRB
  45. */
  46. void ProposeDataFormat( PHW_STREAM_REQUEST_BLOCK pSrb )
  47. {
  48. Trace t("ProposeDataFormat()");
  49. PHW_DEVICE_EXTENSION HwDeviceExtension =
  50. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  51. PsDevice *adapter = HwDeviceExtension->psdevice;
  52. VideoStream StreamNumber = (VideoStream)pSrb->StreamObject->StreamNumber;
  53. if ( StreamNumber == STREAM_IDX_VBI ) {
  54. const KS_DATAFORMAT_VBIINFOHEADER &rKSVBIDataFormat =
  55. *(PKS_DATAFORMAT_VBIINFOHEADER) pSrb->CommandData.OpenFormat;
  56. if ( VerifyVBIStream( rKSVBIDataFormat ) != Success )
  57. pSrb->Status = STATUS_INVALID_PARAMETER;
  58. return;
  59. }
  60. const KS_DATAFORMAT_VIDEOINFOHEADER &rKSDataFormat =
  61. *(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
  62. const KS_DATAFORMAT_VIDEOINFOHEADER2 &rKSDataFormat2 =
  63. *(PKS_DATAFORMAT_VIDEOINFOHEADER2) pSrb->CommandData.OpenFormat;
  64. DebugOut((1, "Proposed Data format\n"));
  65. if ( VerifyVideoStream( rKSDataFormat ) != Success )
  66. {
  67. if ( VerifyVideoStream2( rKSDataFormat2 ) != Success )
  68. {
  69. pSrb->Status = STATUS_INVALID_PARAMETER;
  70. }
  71. else
  72. {
  73. pSrb->ActualBytesTransferred = sizeof( KS_DATAFORMAT_VIDEOINFOHEADER2 );
  74. }
  75. }
  76. else
  77. {
  78. pSrb->ActualBytesTransferred = sizeof( KS_DATAFORMAT_VIDEOINFOHEADER );
  79. }
  80. }
  81. /***************************************************************************
  82. Data Packet Handling Routines
  83. ***************************************************************************/
  84. /*
  85. ** VideoReceiveDataPacket()
  86. **
  87. ** Receives Video data packet commands
  88. **
  89. ** Arguments:
  90. **
  91. ** pSrb - Stream request block for the Video device
  92. **
  93. ** Returns:
  94. **
  95. ** Side Effects: none
  96. */
  97. void MockStampVBI( PHW_STREAM_REQUEST_BLOCK pSrb )
  98. {
  99. PKSSTREAM_HEADER pDataPacket = pSrb->CommandData.DataBufferArray;
  100. pDataPacket->PresentationTime.Numerator = 1;
  101. pDataPacket->PresentationTime.Denominator = 1;
  102. pDataPacket->OptionsFlags &= ~KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
  103. pDataPacket->OptionsFlags &= ~KSSTREAM_HEADER_OPTIONSF_TIMEVALID;
  104. pDataPacket->OptionsFlags &= ~KS_VBI_FLAG_TVTUNER_CHANGE;
  105. pDataPacket->OptionsFlags &= ~KS_VBI_FLAG_VBIINFOHEADER_CHANGE;
  106. pDataPacket->PresentationTime.Time = 0;
  107. pDataPacket->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT;
  108. pSrb->Status = STATUS_SUCCESS;
  109. CheckSrbStatus( pSrb );
  110. StreamClassStreamNotification( StreamRequestComplete, pSrb->StreamObject, pSrb );
  111. }
  112. VOID STREAMAPI VideoReceiveDataPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  113. {
  114. Trace t("VideoReceiveDataPacket()");
  115. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  116. PHW_DEVICE_EXTENSION HwDeviceExtension =
  117. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  118. PsDevice *adapter = HwDeviceExtension->psdevice;
  119. VideoStream StreamNumber = (VideoStream)pSrb->StreamObject->StreamNumber;
  120. //
  121. // make sure we have a device extension
  122. //
  123. DEBUG_ASSERT((ULONG)adapter);
  124. // default to success
  125. pSrb->Status = STATUS_SUCCESS;
  126. //
  127. // determine the type of packet.
  128. //
  129. DebugOut((1, "VideoReceiveDataPacket(%x) cmd(%x)\n", pSrb, pSrb->Command));
  130. switch ( pSrb->Command ) {
  131. case SRB_READ_DATA:
  132. //
  133. // remember the current srb
  134. //
  135. DebugOut((1, "PsDevice::VideoReceiveDataPacket - SRB_READ_DATA\n"));
  136. chan->SetSRB( pSrb );
  137. adapter->AddBuffer( *chan, pSrb );
  138. break;
  139. default:
  140. //
  141. // invalid / unsupported command. Fail it as such
  142. //
  143. DebugOut((1, "PsDevice::VideoReceiveDataPacket - unknown command(%x)\n", pSrb->Command));
  144. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  145. StreamCompleterData( pSrb );
  146. }
  147. }
  148. /*
  149. ** VideoReceiveCtrlPacket()
  150. **
  151. ** Receives packet commands that control the Video stream
  152. **
  153. ** Arguments:
  154. **
  155. ** pSrb - The stream request block for the Video stream
  156. **
  157. ** Returns:
  158. **
  159. ** Side Effects: none
  160. */
  161. VOID STREAMAPI VideoReceiveCtrlPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  162. {
  163. Trace t("VideoReceiveCtrlPacket()");
  164. PHW_DEVICE_EXTENSION HwDeviceExtension =
  165. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  166. PsDevice *adapter = HwDeviceExtension->psdevice;
  167. DEBUG_ASSERT((ULONG)adapter);
  168. // default to success
  169. pSrb->Status = STATUS_SUCCESS;
  170. //
  171. // determine the type of packet.
  172. //
  173. DebugOut((1, "VideoReceiveCtrlPacket(%x) cmd(%x)\n", pSrb, pSrb->Command));
  174. int Command = pSrb->Command;
  175. switch ( Command ) {
  176. case SRB_SET_STREAM_STATE:
  177. adapter->SetVideoState( pSrb );
  178. break;
  179. case SRB_GET_STREAM_STATE:
  180. adapter->GetVideoState( pSrb );
  181. break;
  182. case SRB_PROPOSE_DATA_FORMAT:
  183. DebugOut((1, "Propose Data Format\n"));
  184. ProposeDataFormat( pSrb );
  185. break;
  186. case SRB_SET_DATA_FORMAT:
  187. DebugOut((1, "Set Data Format\n"));
  188. // should re-validate just in case ?
  189. adapter->ProcessSetDataFormat( pSrb );
  190. break;
  191. case SRB_GET_STREAM_PROPERTY:
  192. adapter->GetStreamProperty( pSrb );
  193. break;
  194. case SRB_SET_STREAM_PROPERTY:
  195. DebugOut(( 0, "SRB_SET_STREAM_PROPERTY\n" ));
  196. break;
  197. /*
  198. case SRB_OPEN_MASTER_CLOCK:
  199. case SRB_CLOSE_MASTER_CLOCK:
  200. //
  201. // This stream is being selected to provide a Master clock
  202. //
  203. adapter->SetClockMaster( pSrb );
  204. break;
  205. */
  206. case SRB_INDICATE_MASTER_CLOCK:
  207. //
  208. // Assigns a clock to a stream
  209. //
  210. adapter->SetClockMaster( pSrb );
  211. break;
  212. default:
  213. //
  214. // invalid / unsupported command. Fail it as such
  215. //
  216. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  217. break;
  218. }
  219. if ( Command != SRB_SET_STREAM_STATE &&
  220. Command != SRB_SET_STREAM_PROPERTY &&
  221. Command != SRB_SET_DATA_FORMAT )
  222. StreamCompleterControl( pSrb );
  223. }
  224. /*
  225. ** GetVideoState()
  226. **
  227. ** Gets the current state of the requested stream
  228. **
  229. ** Arguments:
  230. **
  231. ** pSrb - pointer to the stream request block for properties
  232. **
  233. ** Returns:
  234. **
  235. ** Side Effects: none
  236. */
  237. VOID PsDevice::GetVideoState( PHW_STREAM_REQUEST_BLOCK pSrb )
  238. {
  239. Trace t("PsDevice::GetVideoState()");
  240. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  241. pSrb->Status = STATUS_SUCCESS;
  242. pSrb->CommandData.StreamState = chan->GetKSState();
  243. pSrb->ActualBytesTransferred = sizeof (KSSTATE);
  244. // A very odd rule:
  245. // When transitioning from stop to pause, DShow tries to preroll
  246. // the graph. Capture sources can't preroll, and indicate this
  247. // by returning VFW_S_CANT_CUE in user mode. To indicate this
  248. // condition from drivers, they must return ERROR_NO_DATA_DETECTED
  249. //
  250. // [TMZ] JayBo says KSSTATE_ACQUIRE should return success
  251. if (pSrb->CommandData.StreamState == KSSTATE_PAUSE) {
  252. pSrb->Status = STATUS_NO_DATA_DETECTED;
  253. }
  254. }
  255. /*
  256. ** SetVideoState()
  257. **
  258. ** Sets the current state of the requested stream
  259. **
  260. ** Arguments:
  261. **
  262. ** pSrb - pointer to the stream request block for properties
  263. **
  264. ** Returns:
  265. **
  266. ** Side Effects: none
  267. */
  268. VOID PrintState(StreamState st)
  269. {
  270. switch( st ) {
  271. case Started:
  272. DebugOut((1, "*** Streamstate was STARTED\n"));
  273. break;
  274. case Created:
  275. DebugOut((1, "*** Streamstate was CREATED\n"));
  276. break;
  277. case Paused:
  278. DebugOut((1, "*** Streamstate was PAUSED\n"));
  279. break;
  280. case Open:
  281. DebugOut((1, "*** Streamstate was OPEN\n"));
  282. break;
  283. default:
  284. DebugOut((1, "*** Streamstate was ??? (%x)\n", st));
  285. break;
  286. }
  287. }
  288. VOID PsDevice::SetVideoState( PHW_STREAM_REQUEST_BLOCK pSrb )
  289. {
  290. Trace t("PsDevice::SetVideoState()");
  291. PHW_DEVICE_EXTENSION HwDeviceExtension =
  292. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  293. PsDevice *adapter = HwDeviceExtension->psdevice;
  294. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  295. VideoStream StreamNumber = (VideoStream)pSrb->StreamObject->StreamNumber;
  296. //
  297. // determine which new state is requested
  298. //
  299. pSrb->Status = STATUS_SUCCESS;
  300. chan->SetKSState( pSrb->CommandData.StreamState );
  301. switch ( pSrb->CommandData.StreamState ) {
  302. case KSSTATE_ACQUIRE: // Documented as "same as pause for most minidrivers"
  303. DebugOut((1, "*** KSSTATE_ACQUIRE(%d) state(%d) falling through to PAUSE\n", StreamNumber, chan->GetState()));
  304. case KSSTATE_PAUSE:
  305. // PrintState(chan->GetState());
  306. DebugOut((1, "*** KSSTATE_PAUSE(%d) state(%d)\n", StreamNumber, chan->GetState()));
  307. switch ( chan->GetState() ) {
  308. case Started:
  309. if ( StreamNumber == 2 )
  310. {
  311. DebugOut((1, "#############################################################\n"));
  312. DebugOut((1, "About to pause channel %d\n", StreamNumber ));
  313. //adapter->CaptureContrll_.DumpRiscPrograms();
  314. }
  315. Pause( *chan ); // intentional fall-through
  316. if ( StreamNumber == 2 )
  317. {
  318. DebugOut((1, "Done pausing channel %d\n", StreamNumber ));
  319. DebugOut((1, "#############################################################\n"));
  320. //adapter->CaptureContrll_.DumpRiscPrograms();
  321. }
  322. case Created:
  323. case Paused: // 2 PAUSE in a row; ignore
  324. StreamCompleterControl( pSrb );
  325. break;
  326. case Open:
  327. StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, Low,
  328. PHW_PRIORITY_ROUTINE( CreateVideo ), pSrb );
  329. break;
  330. }
  331. break;
  332. case KSSTATE_STOP:
  333. // PrintState(chan->GetState());
  334. DebugOut((1, "*** KSSTATE_STOP(%d) state(%d)\n", StreamNumber, chan->GetState()));
  335. //
  336. // stop the video
  337. //
  338. switch ( chan->GetState() ) {
  339. default:
  340. if ( StreamNumber == 2 )
  341. {
  342. DebugOut((1, "'#############################################################\n"));
  343. DebugOut((1, "'About to pause channel %d\n", StreamNumber ));
  344. //adapter->CaptureContrll_.DumpRiscPrograms();
  345. }
  346. Pause( *chan ); // intentional fall-through
  347. if ( StreamNumber == 2 )
  348. {
  349. DebugOut((1, "'Done pausing channel %d\n", StreamNumber ));
  350. DebugOut((1, "'#############################################################\n"));
  351. //adapter->CaptureContrll_.DumpRiscPrograms();
  352. }
  353. case Paused:
  354. case Created:
  355. StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, Low,
  356. PHW_PRIORITY_ROUTINE( DestroyVideo ), pSrb );
  357. break;
  358. }
  359. break;
  360. case KSSTATE_RUN: {
  361. // PrintState(chan->GetState());
  362. {
  363. VideoStream nStreamNumber = (VideoStream)pSrb->StreamObject->StreamNumber;
  364. DebugOut((1, "*** KSSTATE_RUN(%d)\n", nStreamNumber));
  365. }
  366. //
  367. // play the video
  368. //
  369. StreamState st = chan->GetState();
  370. if ( st != Created && st != Paused ) {
  371. DebugOut((1, "*** KSSTATE_RUN Error (st == %d)\n", st));
  372. pSrb->Status = STATUS_IO_DEVICE_ERROR;
  373. } else {
  374. Start( *chan );
  375. }
  376. StreamCompleterControl( pSrb );
  377. }
  378. break;
  379. default:
  380. DebugOut((0, "*** KSSTATE_??? (%x)\n", pSrb->CommandData.StreamState));
  381. pSrb->Status = STATUS_SUCCESS;
  382. StreamCompleterControl( pSrb );
  383. break;
  384. }
  385. // when going to paused mode from open and stopping, notification is done in callback
  386. }
  387. /* Method: PsDevice::StartVideo
  388. * Purpose: Starts a stream
  389. * Input: pSrb
  390. */
  391. void STREAMAPI PsDevice::StartVideo( PHW_STREAM_REQUEST_BLOCK pSrb )
  392. {
  393. Trace t("PsDevice::StartVideo()");
  394. PHW_DEVICE_EXTENSION HwDeviceExtension =
  395. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  396. PsDevice *adapter = HwDeviceExtension->psdevice;
  397. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  398. // restart the stream
  399. adapter->Start( *chan );
  400. adapter->Pause( *chan );
  401. // finally, can complete the SET dataformat SRB
  402. // StreamCompleterControl( pSrb );
  403. // cannot call any other class' services; have to schedule a callback
  404. StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, LowToHigh,
  405. PHW_PRIORITY_ROUTINE( StreamCompleterControl ), pSrb );
  406. }
  407. /* Method: PsDevice::CreateVideo
  408. * Purpose: Starts a stream
  409. * Input: pSrb
  410. */
  411. void STREAMAPI PsDevice::CreateVideo( PHW_STREAM_REQUEST_BLOCK pSrb )
  412. {
  413. Trace t("PsDevice::CreateVideo()");
  414. PHW_DEVICE_EXTENSION HwDeviceExtension =
  415. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  416. PsDevice *adapter = HwDeviceExtension->psdevice;
  417. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  418. if ( adapter->Create( *chan ) != Success )
  419. pSrb->Status = STATUS_IO_DEVICE_ERROR;
  420. // cannot call any other class' services; have to schedule a callback
  421. StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, LowToHigh,
  422. PHW_PRIORITY_ROUTINE( StreamCompleterControl ), pSrb );
  423. }
  424. /* Method: PsDevice::DestroyVideo
  425. * Purpose: Called at low priority to stop video and free the resources
  426. */
  427. void STREAMAPI PsDevice::DestroyVideoNoComplete( PHW_STREAM_REQUEST_BLOCK pSrb )
  428. {
  429. Trace t("PsDevice::DestroyVideoNoComplete()");
  430. PHW_DEVICE_EXTENSION HwDeviceExtension =
  431. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  432. PsDevice *adapter = HwDeviceExtension->psdevice;
  433. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  434. // have all resources freed
  435. adapter->Stop( *chan );
  436. // set new format
  437. KS_DATAFORMAT_VIDEOINFOHEADER &rDataVideoInfHdr =
  438. *(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
  439. KS_DATAFORMAT_VIDEOINFOHEADER2 &rDataVideoInfHdr2 =
  440. *(PKS_DATAFORMAT_VIDEOINFOHEADER2) pSrb->CommandData.OpenFormat;
  441. if ( IsEqualGUID( rDataVideoInfHdr.DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_VIDEOINFO ) )
  442. {
  443. chan->SetVidHdr( rDataVideoInfHdr.VideoInfoHeader );
  444. }
  445. else
  446. {
  447. chan->SetVidHdr2( rDataVideoInfHdr2.VideoInfoHeader2 );
  448. }
  449. // re-create the stream
  450. if ( adapter->Create( *chan ) != Success ) {
  451. pSrb->Status = STATUS_IO_DEVICE_ERROR;
  452. StreamCompleterControl( pSrb );
  453. } else {
  454. DebugOut((1, "1 pSrb = %lx\n", pSrb));
  455. DebugOut((1, "1 pSrb->StreamObject = %lx\n", pSrb->StreamObject));
  456. DebugOut((1, "1 chan = %lx\n", chan));
  457. DebugOut((1, "1 HwStreamExtension = %lx\n", pSrb->StreamObject->HwStreamExtension));
  458. // we're already at low priority ???
  459. // StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, Low,
  460. // PHW_PRIORITY_ROUTINE( StartVideo ), pSrb );
  461. // StartVideo( pSrb);
  462. // cannot call any other class' services; have to schedule a callback
  463. StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, LowToHigh,
  464. PHW_PRIORITY_ROUTINE( StreamCompleterControl ), pSrb );
  465. }
  466. }
  467. /* Method: PsDevice::DestroyVideo
  468. * Purpose: Called at low priority to stop video and free the resources
  469. */
  470. void STREAMAPI PsDevice::DestroyVideo( PHW_STREAM_REQUEST_BLOCK pSrb )
  471. {
  472. Trace t("PsDevice::DestroyVideo()");
  473. PHW_DEVICE_EXTENSION HwDeviceExtension =
  474. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  475. PsDevice *adapter = HwDeviceExtension->psdevice;
  476. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  477. adapter->Stop( *chan );
  478. // cannot call any other class' services; have to schedule a callback
  479. StreamClassCallAtNewPriority( pSrb->StreamObject, HwDeviceExtension, LowToHigh,
  480. PHW_PRIORITY_ROUTINE( StreamCompleterControl ), pSrb );
  481. }
  482. /*
  483. ** VideoGetProperty()
  484. **
  485. ** Routine to process video property requests
  486. **
  487. ** Arguments:
  488. **
  489. ** pSrb - pointer to the stream request block for properties
  490. **
  491. ** Returns:
  492. **
  493. ** Side Effects: none
  494. */
  495. void PsDevice::GetStreamProperty( PHW_STREAM_REQUEST_BLOCK pSrb )
  496. {
  497. Trace t("PsDevice::GetStreamProperty()");
  498. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  499. if ( IsEqualGUID( KSPROPSETID_Connection, pSPD->Property->Set ) ) {
  500. GetStreamConnectionProperty( pSrb );
  501. } else {
  502. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  503. }
  504. }
  505. /* Method: PsDevice::ProcessSetDataFormat
  506. * Purpose: Implements SET KSPROPERTY_CONNECTION_DATAFORMAT
  507. * Input: chan: VideoChannel &
  508. * VidInfHdr: KS_VIDEOINFOHEADER &
  509. */
  510. void PsDevice::ProcessSetDataFormat( PHW_STREAM_REQUEST_BLOCK pSrb )
  511. {
  512. Trace t("PsDevice::ProcessSetDataFormat()");
  513. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  514. // have to stop first
  515. Pause( *chan );
  516. // destroy at low prioriy
  517. StreamClassCallAtNewPriority( pSrb->StreamObject, pSrb->HwDeviceExtension, Low,
  518. PHW_PRIORITY_ROUTINE( DestroyVideoNoComplete ), pSrb );
  519. }
  520. /* Method: PsDevice::GetStreamConnectionProperty
  521. * Purpose: Obtains allocator and state properties
  522. */
  523. void PsDevice::GetStreamConnectionProperty( PHW_STREAM_REQUEST_BLOCK pSrb )
  524. {
  525. Trace t("PsDevice::GetStreamConnectionProperty()");
  526. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  527. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  528. ULONG Id = pSPD->Property->Id; // index of the property
  529. switch ( Id ) {
  530. case KSPROPERTY_CONNECTION_ALLOCATORFRAMING: {
  531. //KdPrint(( "KSPROPERTY_CONNECTION_ALLOCATORFRAMING\n" ));
  532. PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING) pSPD->PropertyInfo;
  533. Framing->RequirementsFlags =
  534. KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY |
  535. KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER |
  536. KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY;
  537. Framing->PoolType = NonPagedPool;
  538. //KdPrint(( "Framing->Frames == 0x%08X\n", Framing->Frames ));
  539. if( (VideoStream)pSrb->StreamObject->StreamNumber == STREAM_IDX_VBI )
  540. {
  541. Framing->Frames = 8;
  542. }
  543. else
  544. {
  545. //if( Framing->Frames == 0 )
  546. //{
  547. // Framing->Frames = 1;
  548. //}
  549. //else
  550. //{
  551. Framing->Frames = 3;
  552. //}
  553. }
  554. if( chan->IsVideoInfo2() )
  555. {
  556. Framing->FrameSize = chan->GetVidHdr2()->bmiHeader.biSizeImage;
  557. }
  558. else
  559. {
  560. Framing->FrameSize = chan->GetVidHdr()->bmiHeader.biSizeImage;
  561. }
  562. Framing->FileAlignment = 0;//FILE_QUAD_ALIGNMENT;// PAGE_SIZE - 1;
  563. Framing->Reserved = 0;
  564. pSrb->ActualBytesTransferred = sizeof( KSALLOCATOR_FRAMING );
  565. }
  566. break;
  567. default:
  568. break;
  569. }
  570. }
  571. void PsDevice::SetClockMaster( PHW_STREAM_REQUEST_BLOCK pSrb )
  572. {
  573. Trace t("PsDevice::SetClockMaster()");
  574. VideoChannel *chan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  575. chan->SetClockMaster( pSrb->CommandData.MasterClockHandle );
  576. }
  577. /* Method: AnalogReceiveDataPacket
  578. * Purpose: Receives data packets for analog stream ( tuner change notifications )
  579. * Input: SRB
  580. */
  581. VOID STREAMAPI AnalogReceiveDataPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  582. {
  583. Trace t("AnalogReceiveDataPacket()");
  584. pSrb->Status = STATUS_SUCCESS;
  585. PHW_DEVICE_EXTENSION HwDeviceExtension =
  586. (PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension;
  587. PsDevice *adapter = HwDeviceExtension->psdevice;
  588. DebugOut((1, "AnalogReceiveDataPacket(%x) cmd(%x)\n", pSrb, pSrb->Command));
  589. switch ( pSrb->Command ) {
  590. case SRB_READ_DATA:
  591. break;
  592. case SRB_WRITE_DATA:
  593. //
  594. // This data packet contains the channel change information
  595. // passed on the AnalogVideoIn
  596. //
  597. if ( pSrb->CommandData.DataBufferArray->FrameExtent ==
  598. sizeof( KS_TVTUNER_CHANGE_INFO ) )
  599. adapter->ChangeNotifyChannels( pSrb );
  600. break;
  601. default:
  602. //
  603. // invalid / unsupported command. Fail it as such
  604. //
  605. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  606. }
  607. StreamCompleterData( pSrb );
  608. }
  609. /* Method: AnalogReceiveCtrlPacket
  610. * Purpose: Receives control packets for analog stream ( are there any ? )
  611. * Input: SRB
  612. */
  613. VOID STREAMAPI AnalogReceiveCtrlPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  614. {
  615. Trace t("AnalogReceiveCtrlPacket()");
  616. DebugOut((1, "AnalogReceiveCtrlPacket(%x) cmd(%x)\n", pSrb, pSrb->Command));
  617. pSrb->Status = STATUS_SUCCESS;
  618. StreamCompleterControl( pSrb );
  619. }
  620. #ifdef ENABLE_DDRAW_STUFF
  621. DWORD FAR PASCAL
  622. DirectDrawEventCallback( DWORD dwEvent, PVOID pContext, DWORD dwParam1, DWORD dwParam2 )
  623. {
  624. switch( dwEvent )
  625. {
  626. case DDNOTIFY_PRERESCHANGE:
  627. {
  628. VideoChannel* pChan = (VideoChannel*)pContext;
  629. KdPrint(( "DDNOTIFY_PRERESCHANGE; stream = %d\n", pChan->pSRB_->StreamObject->StreamNumber ));
  630. pChan->bPreEventOccurred = TRUE;
  631. }
  632. break;
  633. case DDNOTIFY_POSTRESCHANGE:
  634. {
  635. VideoChannel* pChan = (VideoChannel*)pContext;
  636. KdPrint(( "DDNOTIFY_POSTRESCHANGE; stream = %d\n", pChan->pSRB_->StreamObject->StreamNumber ));
  637. pChan->bPostEventOccurred = TRUE;
  638. KdPrint(( "before Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n" ));
  639. // AttemptRenegotiation(pStrmEx);
  640. KdPrint(( "after Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n" ));
  641. }
  642. break;
  643. case DDNOTIFY_PREDOSBOX:
  644. {
  645. VideoChannel* pChan = (VideoChannel*)pContext;
  646. KdPrint(( "DDNOTIFY_PREDOSBOX; stream = %d\n", pChan->pSRB_->StreamObject->StreamNumber ));
  647. pChan->bPreEventOccurred = TRUE;
  648. }
  649. break;
  650. case DDNOTIFY_POSTDOSBOX:
  651. {
  652. VideoChannel* pChan = (VideoChannel*)pContext;
  653. KdPrint(( "DDNOTIFY_POSTDOSBOX; stream = %d\n", pChan->pSRB_->StreamObject->StreamNumber ));
  654. pChan->bPostEventOccurred = TRUE;
  655. KdPrint(( "before Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n" ));
  656. // AttemptRenegotiation(pStrmEx);
  657. KdPrint(( "after Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n" ));
  658. }
  659. break;
  660. case DDNOTIFY_CLOSEDIRECTDRAW:
  661. {
  662. VideoChannel* pChan = (VideoChannel*)pContext;
  663. KdPrint(( "DDNOTIFY_CLOSEDIRECTDRAW\n" ));
  664. pChan->hKernelDirectDrawHandle = 0;
  665. pChan->hUserDirectDrawHandle = 0;
  666. }
  667. break;
  668. case DDNOTIFY_CLOSESURFACE:
  669. {
  670. VideoChannel* pChan = (VideoChannel*)pContext;
  671. PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pChan->pSRB_->SRBExtension;
  672. KdPrint(( "DDNOTIFY_CLOSESURFACE\n" ));
  673. pSrbExt->hKernelSurfaceHandle = 0;
  674. }
  675. break;
  676. default:
  677. KdPrint(( "unknown/unhandled ddraw event\n" ));
  678. break;
  679. }
  680. return 0;
  681. }
  682. BOOL RegisterForDirectDrawEvents( PHW_STREAM_REQUEST_BLOCK pSrb )
  683. {
  684. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  685. DDREGISTERCALLBACK ddRegisterCallback;
  686. DWORD ddOut;
  687. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  688. KdPrint(( "stream %d registering for DirectDraw events\n", pSrb->StreamObject->StreamNumber ));
  689. // =============== DDEVENT_PRERESCHANGE ===============
  690. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  691. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  692. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  693. ddRegisterCallback.dwEvents = DDEVENT_PRERESCHANGE;
  694. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  695. ddRegisterCallback.pContext = pChan;
  696. DxApi( DD_DXAPI_REGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  697. if( ddOut != DD_OK )
  698. {
  699. KdPrint(( "DD_DXAPI_REGISTER_CALLBACK failed.\n" ));
  700. return FALSE;
  701. }
  702. // =============== DDEVENT_POSTRESCHANGE ==============
  703. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  704. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  705. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  706. ddRegisterCallback.dwEvents = DDEVENT_POSTRESCHANGE;
  707. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  708. ddRegisterCallback.pContext = pChan;
  709. DxApi(DD_DXAPI_REGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  710. if( ddOut != DD_OK )
  711. {
  712. KdPrint(( "DD_DXAPI_REGISTER_CALLBACK failed.\n" ));
  713. return FALSE;
  714. }
  715. // =============== DDEVENT_PREDOSBOX =================
  716. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  717. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  718. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  719. ddRegisterCallback.dwEvents = DDEVENT_PREDOSBOX;
  720. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  721. ddRegisterCallback.pContext = pChan;
  722. DxApi( DD_DXAPI_REGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  723. if( ddOut != DD_OK )
  724. {
  725. KdPrint(( "DD_DXAPI_REGISTER_CALLBACK failed.\n" ));
  726. return FALSE;
  727. }
  728. // =============== DDEVENT_POSTDOSBOX ================
  729. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  730. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  731. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  732. ddRegisterCallback.dwEvents = DDEVENT_POSTDOSBOX;
  733. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  734. ddRegisterCallback.pContext = pChan;
  735. DxApi( DD_DXAPI_REGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  736. if( ddOut != DD_OK )
  737. {
  738. KdPrint(( "DD_DXAPI_REGISTER_CALLBACK failed.\n" ));
  739. return FALSE;
  740. }
  741. pChan->bKernelDirectDrawRegistered = TRUE;
  742. return TRUE;
  743. }
  744. BOOL UnregisterForDirectDrawEvents( PHW_STREAM_REQUEST_BLOCK pSrb )
  745. {
  746. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  747. DDREGISTERCALLBACK ddRegisterCallback;
  748. DWORD ddOut;
  749. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  750. KdPrint(( "stream %d un-registering for DirectDraw events\n", pSrb->StreamObject->StreamNumber ));
  751. // =============== DDEVENT_PRERESCHANGE ===============
  752. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  753. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  754. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  755. ddRegisterCallback.dwEvents = DDEVENT_PRERESCHANGE;
  756. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  757. ddRegisterCallback.pContext = pChan;
  758. DxApi( DD_DXAPI_UNREGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut));
  759. if( ddOut != DD_OK )
  760. {
  761. KdPrint(( "DD_DXAPI_UNREGISTER_CALLBACK failed.\n" ));
  762. return FALSE;
  763. }
  764. // =============== DDEVENT_POSTRESCHANGE ==============
  765. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  766. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  767. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  768. ddRegisterCallback.dwEvents = DDEVENT_POSTRESCHANGE;
  769. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  770. ddRegisterCallback.pContext = pChan;
  771. DxApi( DD_DXAPI_UNREGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  772. if( ddOut != DD_OK )
  773. {
  774. KdPrint(( "DD_DXAPI_UNREGISTER_CALLBACK failed.\n" ));
  775. return FALSE;
  776. }
  777. // =============== DDEVENT_PREDOSBOX ==================
  778. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  779. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  780. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  781. ddRegisterCallback.dwEvents = DDEVENT_PREDOSBOX;
  782. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  783. ddRegisterCallback.pContext = pChan;
  784. DxApi( DD_DXAPI_UNREGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  785. if( ddOut != DD_OK )
  786. {
  787. KdPrint(( "DD_DXAPI_UNREGISTER_CALLBACK failed.\n" ));
  788. return FALSE;
  789. }
  790. // =============== DDEVENT_POSTDOSBOX =================
  791. RtlZeroMemory( &ddRegisterCallback, sizeof(ddRegisterCallback) );
  792. RtlZeroMemory( &ddOut, sizeof(ddOut) );
  793. ddRegisterCallback.hDirectDraw = pChan->hKernelDirectDrawHandle;
  794. ddRegisterCallback.dwEvents = DDEVENT_POSTDOSBOX;
  795. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  796. ddRegisterCallback.pContext = pChan;
  797. DxApi( DD_DXAPI_UNREGISTER_CALLBACK, (DWORD) &ddRegisterCallback, sizeof(ddRegisterCallback), (DWORD)&ddOut, sizeof(ddOut) );
  798. if( ddOut != DD_OK )
  799. {
  800. KdPrint(( "DD_DXAPI_UNREGISTER_CALLBACK failed.\n" ));
  801. return FALSE;
  802. }
  803. pChan->bKernelDirectDrawRegistered = FALSE;
  804. return TRUE;
  805. }
  806. BOOL OpenKernelDirectDraw( PHW_STREAM_REQUEST_BLOCK pSrb )
  807. {
  808. /*
  809. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  810. if( pChan->hUserDirectDrawHandle != 0 )
  811. {
  812. DDOPENDIRECTDRAWIN ddOpenIn;
  813. DDOPENDIRECTDRAWOUT ddOpenOut;
  814. ASSERT( pChan->hKernelDirectDrawHandle == 0 );
  815. KdPrint(( "stream %d getting kernel ddraw handle\n", pSrb->StreamObject->StreamNumber ));
  816. RtlZeroMemory( &ddOpenIn, sizeof(ddOpenIn) );
  817. RtlZeroMemory( &ddOpenOut, sizeof(ddOpenOut) );
  818. ddOpenIn.dwDirectDrawHandle = (DWORD)pChan->hUserDirectDrawHandle;
  819. ddOpenIn.pfnDirectDrawClose = DirectDrawEventCallback;
  820. ddOpenIn.pContext = pChan;
  821. DxApi( DD_DXAPI_OPENDIRECTDRAW, (DWORD)&ddOpenIn, sizeof(ddOpenIn), (DWORD)&ddOpenOut, sizeof(ddOpenOut) );
  822. if( ddOpenOut.ddRVal != DD_OK )
  823. {
  824. KdPrint(( "DD_DXAPI_OPENDIRECTDRAW failed.\n" ));
  825. }
  826. else
  827. {
  828. pChan->hKernelDirectDrawHandle = ddOpenOut.hDirectDraw;
  829. return TRUE;
  830. }
  831. }
  832. */
  833. return FALSE;
  834. }
  835. BOOL CloseKernelDirectDraw( PHW_STREAM_REQUEST_BLOCK pSrb )
  836. {
  837. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  838. /*
  839. if( pChan->hKernelDirectDrawHandle != 0 )
  840. {
  841. DWORD ddOut;
  842. DDCLOSEHANDLE ddClose;
  843. KdPrint(( "stream %d CloseKernelDirectDraw\n", pSrb->StreamObject->StreamNumber ));
  844. ddClose.hHandle = pChan->hKernelDirectDrawHandle;
  845. DxApi( DD_DXAPI_CLOSEHANDLE, (DWORD)&ddClose, sizeof(ddClose), (DWORD) &ddOut, sizeof(ddOut) );
  846. pChan->hKernelDirectDrawHandle = 0;
  847. if( ddOut != DD_OK )
  848. {
  849. KdPrint(( "CloseKernelDirectDraw FAILED.\n" ));
  850. return FALSE;
  851. }
  852. }
  853. */
  854. return TRUE;
  855. }
  856. BOOL IsKernelLockAndFlipAvailable( PHW_STREAM_REQUEST_BLOCK pSrb )
  857. {
  858. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  859. if( pChan->hKernelDirectDrawHandle != 0 )
  860. {
  861. DDGETKERNELCAPSOUT ddGetKernelCapsOut;
  862. KdPrint(( "stream %d getting Kernel Caps\n", pSrb->StreamObject->StreamNumber ));
  863. RtlZeroMemory( &ddGetKernelCapsOut, sizeof(ddGetKernelCapsOut) );
  864. DxApi(
  865. DD_DXAPI_GETKERNELCAPS,
  866. (DWORD) &pChan->hKernelDirectDrawHandle,
  867. sizeof(pChan->hKernelDirectDrawHandle),
  868. (DWORD)&ddGetKernelCapsOut,
  869. sizeof(ddGetKernelCapsOut)
  870. );
  871. if( ddGetKernelCapsOut.ddRVal != DD_OK )
  872. {
  873. //KdPrint(( "DDGETKERNELCAPSOUT failed.\n" ));
  874. }
  875. else
  876. {
  877. //KdPrint(( "stream %d KernelCaps = %x\n", pSrb->StreamObject->StreamNumber, ddGetKernelCapsOut.dwCaps ));
  878. // TODO:, check the flags here
  879. // if (ddGetKernelCapsOut.dwCaps & ???)
  880. return TRUE;
  881. }
  882. }
  883. return FALSE;
  884. }
  885. BOOL OpenKernelDDrawSurfaceHandle( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  886. {
  887. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  888. PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
  889. ASSERT( pChan->hKernelDirectDrawHandle != 0 );
  890. ASSERT( pSrbExt->hUserSurfaceHandle != 0 );
  891. if( pSrbExt->hUserSurfaceHandle == 0 )
  892. {
  893. DDOPENSURFACEIN ddOpenSurfaceIn;
  894. DDOPENSURFACEOUT ddOpenSurfaceOut;
  895. //KdPrint(( "stream %d getting Kernel surface handle\n", pSrb->StreamObject->StreamNumber ));
  896. RtlZeroMemory( &ddOpenSurfaceIn, sizeof(ddOpenSurfaceIn) );
  897. RtlZeroMemory( &ddOpenSurfaceOut, sizeof(ddOpenSurfaceOut) );
  898. ddOpenSurfaceIn.hDirectDraw = pChan->hUserDirectDrawHandle;
  899. ddOpenSurfaceIn.pfnSurfaceClose = DirectDrawEventCallback;
  900. ddOpenSurfaceIn.pContext = pSrb;
  901. ddOpenSurfaceIn.dwSurfaceHandle = (DWORD)pSrbExt->hUserSurfaceHandle;
  902. DxApi( DD_DXAPI_OPENSURFACE, (DWORD)&ddOpenSurfaceIn, sizeof(ddOpenSurfaceIn), (DWORD)&ddOpenSurfaceOut, sizeof(ddOpenSurfaceOut) );
  903. if( ddOpenSurfaceOut.ddRVal != DD_OK )
  904. {
  905. pSrbExt->hKernelSurfaceHandle = 0;
  906. //KdPrint(( "DD_DXAPI_OPENSURFACE failed.\n" ));
  907. }
  908. else
  909. {
  910. pSrbExt->hKernelSurfaceHandle = ddOpenSurfaceOut.hSurface;
  911. return TRUE;
  912. }
  913. }
  914. return FALSE;
  915. }
  916. BOOL CloseKernelDDrawSurfaceHandle( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  917. {
  918. VideoChannel* pChan = (VideoChannel *)((PSTREAMEX)pSrb->StreamObject->HwStreamExtension)->videochannel;
  919. PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
  920. ASSERT( pChan->hKernelDirectDrawHandle != 0 );
  921. ASSERT( pSrbExt->hUserSurfaceHandle != 0 );
  922. ASSERT( pSrbExt->hKernelSurfaceHandle != 0 );
  923. if( pSrbExt->hKernelSurfaceHandle != 0 )
  924. {
  925. DWORD ddOut;
  926. DDCLOSEHANDLE ddClose;
  927. //KdPrint(( "stream %d ReleaseKernelDDrawSurfaceHandle\n", pSrb->StreamObject->StreamNumber ));
  928. ddClose.hHandle = pSrbExt->hKernelSurfaceHandle;
  929. DxApi( DD_DXAPI_CLOSEHANDLE, (DWORD)&ddClose, sizeof(ddClose), (DWORD) &ddOut, sizeof(ddOut) );
  930. pSrbExt->hKernelSurfaceHandle = 0; // what else can we do?
  931. if( ddOut != DD_OK )
  932. {
  933. //KdPrint(( "ReleaseKernelDDrawSurfaceHandle() FAILED.\n" ));
  934. return FALSE;
  935. }
  936. else
  937. {
  938. return TRUE;
  939. }
  940. }
  941. return FALSE;
  942. }
  943. BOOL FlipOverlay( HANDLE hDirectDraw, HANDLE hCurrentSurface, HANDLE hTargetSurface )
  944. {
  945. DDFLIPOVERLAY ddFlipOverlay;
  946. DWORD ddOut;
  947. RtlZeroMemory( &ddFlipOverlay, sizeof(ddFlipOverlay) );
  948. ddFlipOverlay.hDirectDraw = hDirectDraw;
  949. ddFlipOverlay.hCurrentSurface = hCurrentSurface;
  950. ddFlipOverlay.hTargetSurface = hTargetSurface;
  951. ddFlipOverlay.dwFlags = 0;
  952. DxApi( DD_DXAPI_FLIP_OVERLAY, (DWORD)&ddFlipOverlay, sizeof(ddFlipOverlay), (DWORD)&ddOut, sizeof(ddOut) );
  953. if( ddOut != DD_OK )
  954. {
  955. //KdPrint(( "FlipOverlay() FAILED.\n" ));
  956. return FALSE;
  957. }
  958. else
  959. {
  960. return TRUE;
  961. }
  962. }
  963. #endif