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.

1967 lines
58 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //==========================================================================;
  11. #include "strmini.h"
  12. #include "ksmedia.h"
  13. #include "capmain.h"
  14. #include "mediums.h"
  15. #include "capstrm.h"
  16. #include "capprop.h"
  17. #include "capdebug.h"
  18. #ifdef TOSHIBA
  19. #include "bert.h"
  20. ULONG CurrentOSType; // 0:Win98 1:NT5.0
  21. #endif//TOSHIBA
  22. #ifdef TOSHIBA
  23. VOID
  24. DevicePowerON (
  25. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  26. )
  27. {
  28. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  29. DWORD dwAddr;
  30. CameraChkandON(pHwDevExt, MODE_VFW);
  31. VC_Delay(100);
  32. ImageSetInputImageSize(pHwDevExt, &(pHwDevExt->SrcRect));
  33. ImageSetOutputImageSize(pHwDevExt, pHwDevExt->ulWidth, pHwDevExt->ulHeight);
  34. BertFifoConfig(pHwDevExt, pHwDevExt->Format);
  35. ImageSetHueBrightnessContrastSat(pHwDevExt);
  36. if ( pHwDevExt->ColorEnable ) {
  37. if ( get_AblFilter( pHwDevExt ) ) {
  38. set_filtering( pHwDevExt, TRUE );
  39. } else {
  40. set_filtering( pHwDevExt, FALSE );
  41. pHwDevExt->ColorEnable = 0;
  42. }
  43. } else {
  44. set_filtering( pHwDevExt, FALSE );
  45. }
  46. dwAddr = (DWORD)pHwDevExt->pPhysRpsDMABuf.LowPart;
  47. #if 0
  48. dwAddr = (dwAddr + 0x1FFF) & 0xFFFFE000;
  49. #endif
  50. pHwDevExt->s_physDmaActiveFlag = dwAddr + 0X1860;
  51. if( pHwDevExt->dblBufflag ){
  52. BertTriBuildNodes(pHwDevExt); // Add 97-04-08(Tue)
  53. }
  54. else{
  55. BertBuildNodes(pHwDevExt); // Add 97-04-08(Tue)
  56. }
  57. pHwDevExt->IsRPSReady = TRUE;
  58. BertInterruptEnable(pHwDevExt, TRUE);
  59. BertDMARestart(pHwDevExt);
  60. }
  61. VOID
  62. CameraPowerON (
  63. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  64. )
  65. {
  66. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  67. CameraChkandON(pHwDevExt, MODE_VFW);
  68. VC_Delay(100);
  69. }
  70. VOID
  71. CameraPowerOFF (
  72. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  73. )
  74. {
  75. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  76. CameraChkandOFF(pHwDevExt, MODE_VFW);
  77. }
  78. VOID
  79. QueryOSTypeFromRegistry()
  80. {
  81. NTSTATUS ntStatus = STATUS_SUCCESS;
  82. LONG RegVals[2];
  83. PLONG pRegVal;
  84. WCHAR BasePath[] = L"\\Registry\\MACHINE\\SOFTWARE\\Toshiba\\Tsbvcap";
  85. RTL_QUERY_REGISTRY_TABLE Table[2];
  86. UNICODE_STRING RegPath;
  87. //
  88. // Get the actual values for the controls
  89. //
  90. RtlZeroMemory (Table, sizeof(Table));
  91. CurrentOSType = 1; // Assume NT5.0
  92. RegVals[0] = CurrentOSType;
  93. pRegVal = RegVals; // for convenience sake
  94. RegPath.Buffer = BasePath;
  95. #ifdef TOSHIBA // '99-01-08 Modified
  96. RegPath.MaximumLength = sizeof(BasePath) + (32 * sizeof(WCHAR)); //32 chars for keys
  97. #else //TOSHIBA
  98. RegPath.MaximumLength = sizeof(BasePath + 32); //32 chars for keys
  99. #endif//TOSHIBA
  100. RegPath.Length = 0;
  101. Table[0].Name = L"CurrentOSType";
  102. Table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  103. Table[0].EntryContext = pRegVal++;
  104. ntStatus = RtlQueryRegistryValues(
  105. RTL_REGISTRY_ABSOLUTE,
  106. RegPath.Buffer,
  107. Table,
  108. NULL,
  109. NULL );
  110. if( NT_SUCCESS(ntStatus))
  111. {
  112. CurrentOSType = RegVals[0];
  113. }
  114. }
  115. VOID
  116. QueryControlsFromRegistry(
  117. PHW_DEVICE_EXTENSION pHwDevExt
  118. )
  119. {
  120. NTSTATUS ntStatus = STATUS_SUCCESS;
  121. LONG RegVals[6];
  122. PLONG pRegVal;
  123. WCHAR BasePath[] = L"\\Registry\\MACHINE\\SOFTWARE\\Toshiba\\Tsbvcap";
  124. RTL_QUERY_REGISTRY_TABLE Table[6];
  125. UNICODE_STRING RegPath;
  126. //
  127. // Get the actual values for the controls
  128. //
  129. RtlZeroMemory (Table, sizeof(Table));
  130. RegVals[0] = pHwDevExt->Brightness;
  131. RegVals[1] = pHwDevExt->Contrast;
  132. RegVals[2] = pHwDevExt->Hue;
  133. RegVals[3] = pHwDevExt->Saturation;
  134. RegVals[4] = pHwDevExt->ColorEnable;
  135. pRegVal = RegVals; // for convenience sake
  136. RegPath.Buffer = BasePath;
  137. #ifdef TOSHIBA // '99-01-08 Modified
  138. RegPath.MaximumLength = sizeof(BasePath) + (32 * sizeof(WCHAR)); //32 chars for keys
  139. #else //TOSHIBA
  140. RegPath.MaximumLength = sizeof(BasePath + 32); //32 chars for keys
  141. #endif//TOSHIBA
  142. RegPath.Length = 0;
  143. Table[0].Name = L"Brightness";
  144. Table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  145. Table[0].EntryContext = pRegVal++;
  146. Table[1].Name = L"Contrast";
  147. Table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  148. Table[1].EntryContext = pRegVal++;
  149. Table[2].Name = L"Hue";
  150. Table[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  151. Table[2].EntryContext = pRegVal++;
  152. Table[3].Name = L"Saturation";
  153. Table[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
  154. Table[3].EntryContext = pRegVal++;
  155. Table[4].Name = L"FilterEnable";
  156. Table[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
  157. Table[4].EntryContext = pRegVal++;
  158. ntStatus = RtlQueryRegistryValues(
  159. RTL_REGISTRY_ABSOLUTE,
  160. RegPath.Buffer,
  161. Table,
  162. NULL,
  163. NULL );
  164. if( NT_SUCCESS(ntStatus))
  165. {
  166. pHwDevExt->Brightness = RegVals[0];
  167. pHwDevExt->Contrast = RegVals[1];
  168. pHwDevExt->Hue = RegVals[2];
  169. pHwDevExt->Saturation = RegVals[3];
  170. pHwDevExt->ColorEnable = RegVals[4];
  171. }
  172. }
  173. VOID
  174. SaveControlsToRegistry(
  175. PHW_DEVICE_EXTENSION pHwDevExt
  176. )
  177. {
  178. LONG Value;
  179. WCHAR BasePath[] = L"\\Registry\\MACHINE\\SOFTWARE\\Toshiba\\Tsbvcap";
  180. UNICODE_STRING RegPath;
  181. RegPath.Buffer = BasePath;
  182. #ifdef TOSHIBA // '99-01-08 Modified
  183. RegPath.MaximumLength = sizeof(BasePath) + (32 * sizeof(WCHAR)); //32 chars for keys
  184. #else //TOSHIBA
  185. RegPath.MaximumLength = sizeof(BasePath + 32); //32 chars for keys
  186. #endif//TOSHIBA
  187. RegPath.Length = 0;
  188. Value = pHwDevExt->Brightness;
  189. RtlWriteRegistryValue(
  190. RTL_REGISTRY_ABSOLUTE,
  191. RegPath.Buffer,
  192. L"Brightness",
  193. REG_DWORD,
  194. &Value,
  195. sizeof (ULONG));
  196. Value = pHwDevExt->Contrast;
  197. RtlWriteRegistryValue(
  198. RTL_REGISTRY_ABSOLUTE,
  199. RegPath.Buffer,
  200. L"Contrast",
  201. REG_DWORD,
  202. &Value,
  203. sizeof (ULONG));
  204. Value = pHwDevExt->Hue;
  205. RtlWriteRegistryValue(
  206. RTL_REGISTRY_ABSOLUTE,
  207. RegPath.Buffer,
  208. L"Hue",
  209. REG_DWORD,
  210. &Value,
  211. sizeof (ULONG));
  212. Value = pHwDevExt->Saturation;
  213. RtlWriteRegistryValue(
  214. RTL_REGISTRY_ABSOLUTE,
  215. RegPath.Buffer,
  216. L"Saturation",
  217. REG_DWORD,
  218. &Value,
  219. sizeof (ULONG));
  220. Value = pHwDevExt->ColorEnable;
  221. RtlWriteRegistryValue(
  222. RTL_REGISTRY_ABSOLUTE,
  223. RegPath.Buffer,
  224. L"FilterEnable",
  225. REG_DWORD,
  226. &Value,
  227. sizeof (ULONG));
  228. }
  229. #endif//TOSHIBA
  230. /*
  231. ** DriverEntry()
  232. **
  233. ** This routine is called when the driver is first loaded by PnP.
  234. ** It in turn, calls upon the stream class to perform registration services.
  235. **
  236. ** Arguments:
  237. **
  238. ** DriverObject -
  239. ** Driver object for this driver
  240. **
  241. ** RegistryPath -
  242. ** Registry path string for this driver's key
  243. **
  244. ** Returns:
  245. **
  246. ** Results of StreamClassRegisterAdapter()
  247. **
  248. ** Side Effects: none
  249. */
  250. ULONG
  251. DriverEntry (
  252. IN PDRIVER_OBJECT DriverObject,
  253. IN PUNICODE_STRING RegistryPath
  254. )
  255. {
  256. HW_INITIALIZATION_DATA HwInitData;
  257. ULONG ReturnValue;
  258. KdPrint(("TsbVcap: DriverEntry\n"));
  259. RtlZeroMemory(&HwInitData, sizeof(HwInitData));
  260. HwInitData.HwInitializationDataSize = sizeof(HwInitData);
  261. //
  262. // Set the Adapter entry points for the driver
  263. //
  264. #ifdef TOSHIBA
  265. QueryOSTypeFromRegistry();
  266. HwInitData.HwInterrupt = HwInterrupt;
  267. #else //TOSHIBA
  268. HwInitData.HwInterrupt = NULL; // HwInterrupt;
  269. #endif//TOSHIBA
  270. HwInitData.HwReceivePacket = AdapterReceivePacket;
  271. HwInitData.HwCancelPacket = AdapterCancelPacket;
  272. HwInitData.HwRequestTimeoutHandler = AdapterTimeoutPacket;
  273. HwInitData.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
  274. HwInitData.PerRequestExtensionSize = sizeof(SRB_EXTENSION);
  275. HwInitData.FilterInstanceExtensionSize = 0;
  276. HwInitData.PerStreamExtensionSize = sizeof(STREAMEX);
  277. HwInitData.BusMasterDMA = FALSE;
  278. HwInitData.Dma24BitAddresses = FALSE;
  279. HwInitData.BufferAlignment = 3;
  280. #ifdef TOSHIBA
  281. if ( CurrentOSType ) { // NT5.0
  282. HwInitData.DmaBufferSize = 8192 * 2;
  283. } else {
  284. HwInitData.DmaBufferSize = 8192 * 2 + MAX_CAPTURE_BUFFER_SIZE;
  285. }
  286. #else //TOSHIBA
  287. HwInitData.DmaBufferSize = 0;
  288. #endif//TOSHIBA
  289. // Don't rely on the stream class using raised IRQL to synchronize
  290. // execution. This single paramter most affects the overall structure
  291. // of the driver.
  292. HwInitData.TurnOffSynchronization = TRUE;
  293. ReturnValue = StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData);
  294. KdPrint(("TsbVcap: StreamClassRegisterAdapter = %x\n", ReturnValue));
  295. return ReturnValue;
  296. }
  297. //==========================================================================;
  298. // Adapter Based Request Handling Routines
  299. //==========================================================================;
  300. /*
  301. ** HwInitialize()
  302. **
  303. ** This routine is called when an SRB_INITIALIZE_DEVICE request is received
  304. **
  305. ** Arguments:
  306. **
  307. ** pSrb - pointer to stream request block for the Initialize command
  308. **
  309. ** Returns:
  310. **
  311. ** Side Effects: none
  312. */
  313. BOOL
  314. STREAMAPI
  315. HwInitialize (
  316. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  317. )
  318. {
  319. STREAM_PHYSICAL_ADDRESS adr;
  320. ULONG Size;
  321. PUCHAR pDmaBuf;
  322. int j;
  323. PPORT_CONFIGURATION_INFORMATION ConfigInfo = pSrb->CommandData.ConfigInfo;
  324. PHW_DEVICE_EXTENSION pHwDevExt =
  325. (PHW_DEVICE_EXTENSION)ConfigInfo->HwDeviceExtension;
  326. KdPrint(("TsbVcap: HwInitialize()\n"));
  327. #ifdef TOSHIBA
  328. if (ConfigInfo->NumberOfAccessRanges == 0) {
  329. #else //TOSHIBA
  330. if (ConfigInfo->NumberOfAccessRanges != 0) {
  331. #endif//TOSHIBA
  332. KdPrint(("TsbVcap: illegal config info\n"));
  333. pSrb->Status = STATUS_NO_SUCH_DEVICE;
  334. return (FALSE);
  335. }
  336. KdPrint(("TsbVcap: Number of access ranges = %lx\n", ConfigInfo->NumberOfAccessRanges));
  337. KdPrint(("TsbVcap: Memory Range = %lx\n", pHwDevExt->ioBaseLocal));
  338. KdPrint(("TsbVcap: IRQ = %lx\n", ConfigInfo->BusInterruptLevel));
  339. if (ConfigInfo->NumberOfAccessRanges != 0) {
  340. pHwDevExt->ioBaseLocal
  341. = (PULONG)(ConfigInfo->AccessRanges[0].RangeStart.LowPart);
  342. }
  343. pHwDevExt->Irq = (USHORT)(ConfigInfo->BusInterruptLevel);
  344. ConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) +
  345. DRIVER_STREAM_COUNT * sizeof (HW_STREAM_INFORMATION);
  346. pDmaBuf = StreamClassGetDmaBuffer(pHwDevExt);
  347. adr = StreamClassGetPhysicalAddress(pHwDevExt,
  348. NULL, pDmaBuf, DmaBuffer, &Size);
  349. #ifdef TOSHIBA
  350. if ( CurrentOSType ) { // NT5.0
  351. pHwDevExt->pRpsDMABuf = pDmaBuf;
  352. pHwDevExt->pPhysRpsDMABuf = adr;
  353. pHwDevExt->pCaptureBufferY = NULL;
  354. pHwDevExt->pCaptureBufferU = NULL;
  355. pHwDevExt->pCaptureBufferV = NULL;
  356. pHwDevExt->pPhysCaptureBufferY.LowPart = 0;
  357. pHwDevExt->pPhysCaptureBufferY.HighPart = 0;
  358. pHwDevExt->pPhysCaptureBufferU.LowPart = 0;
  359. pHwDevExt->pPhysCaptureBufferU.HighPart = 0;
  360. pHwDevExt->pPhysCaptureBufferV.LowPart = 0;
  361. pHwDevExt->pPhysCaptureBufferV.HighPart = 0;
  362. pHwDevExt->BufferSize = 0;
  363. } else {
  364. pHwDevExt->pRpsDMABuf = pDmaBuf;
  365. pHwDevExt->pCaptureBufferY = pDmaBuf + (8192 * 2);
  366. pHwDevExt->pPhysRpsDMABuf = adr;
  367. adr.LowPart += 8192 * 2;
  368. pHwDevExt->pPhysCaptureBufferY = adr;
  369. pHwDevExt->BufferSize = 0;
  370. }
  371. InitializeConfigDefaults(pHwDevExt);
  372. pHwDevExt->NeedHWInit = TRUE;
  373. if(!SetupPCILT(pHwDevExt))
  374. {
  375. pSrb->Status = STATUS_NO_SUCH_DEVICE;
  376. return (FALSE);
  377. }
  378. pHwDevExt->dblBufflag=FALSE;
  379. BertInitializeHardware(pHwDevExt);
  380. if(SetASICRev(pHwDevExt) != TRUE )
  381. {
  382. pSrb->Status = STATUS_NO_SUCH_DEVICE;
  383. return (FALSE);
  384. }
  385. BertSetDMCHE(pHwDevExt);
  386. #if 0 // move to CameraPowerON()
  387. if( !CameraChkandON(pHwDevExt, MODE_VFW) )
  388. {
  389. pSrb->Status = STATUS_NO_SUCH_DEVICE;
  390. return (FALSE);
  391. }
  392. #endif
  393. HWInit(pHwDevExt);
  394. #endif//TOSHIBA
  395. #ifdef TOSHIBA
  396. // Init VideoProcAmp properties
  397. pHwDevExt->Brightness = 0x80;
  398. pHwDevExt->BrightnessFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
  399. pHwDevExt->Contrast = 0x80;
  400. pHwDevExt->ContrastFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
  401. pHwDevExt->Hue = 0x80;
  402. pHwDevExt->HueFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
  403. pHwDevExt->Saturation = 0x80;
  404. pHwDevExt->SaturationFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
  405. pHwDevExt->ColorEnable = ColorEnableDefault;
  406. pHwDevExt->ColorEnableFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
  407. #ifdef TOSHIBA // '98-12-09 Added, for Bug-Report 253529
  408. pHwDevExt->BrightnessRange = BrightnessRangeAndStep[0].Bounds;
  409. pHwDevExt->ContrastRange = ContrastRangeAndStep[0].Bounds;
  410. pHwDevExt->HueRange = HueRangeAndStep[0].Bounds;
  411. pHwDevExt->SaturationRange = SaturationRangeAndStep[0].Bounds;
  412. #endif//TOSHIBA
  413. // Init VideoControl properties
  414. pHwDevExt->VideoControlMode = 0;
  415. #else //TOSHIBA
  416. // Init Crossbar properties
  417. pHwDevExt->VideoInputConnected = 0; // TvTuner video is the default
  418. pHwDevExt->AudioInputConnected = 5; // TvTuner audio is the default
  419. // Init VideoProcAmp properties
  420. pHwDevExt->Brightness = BrightnessDefault;
  421. pHwDevExt->BrightnessFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
  422. pHwDevExt->Contrast = ContrastDefault;
  423. pHwDevExt->ContrastFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
  424. pHwDevExt->ColorEnable = ColorEnableDefault;
  425. pHwDevExt->ColorEnableFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
  426. // Init CameraControl properties
  427. pHwDevExt->Focus = FocusDefault;
  428. pHwDevExt->FocusFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
  429. pHwDevExt->Zoom = ZoomDefault;
  430. pHwDevExt->ZoomFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
  431. // Init TvTuner properties
  432. pHwDevExt->TunerInput = 0;
  433. pHwDevExt->Busy = 0;
  434. // Init TvAudio properties
  435. pHwDevExt->TVAudioMode = KS_TVAUDIO_MODE_MONO |
  436. KS_TVAUDIO_MODE_LANG_A ;
  437. // Init AnalogVideoDecoder properties
  438. pHwDevExt->VideoDecoderVideoStandard = KS_AnalogVideo_NTSC_M;
  439. pHwDevExt->VideoDecoderOutputEnable = FALSE;
  440. pHwDevExt->VideoDecoderVCRTiming = FALSE;
  441. // Init VideoControl properties
  442. pHwDevExt->VideoControlMode = 0;
  443. #endif//TOSHIBA
  444. // Init VideoCompression properties
  445. pHwDevExt->CompressionSettings.CompressionKeyFrameRate = 15;
  446. pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame = 3;
  447. pHwDevExt->CompressionSettings.CompressionQuality = 5000;
  448. pHwDevExt->PDO = ConfigInfo->PhysicalDeviceObject;
  449. KdPrint(("TsbVcap: Physical Device Object = %lx\n", pHwDevExt->PDO));
  450. #ifdef TOSHIBA
  451. IoInitializeDpcRequest(pHwDevExt->PDO, DeferredRoutine);
  452. #endif//TOSHIBA
  453. for (j = 0; j < MAX_TSBVCAP_STREAMS; j++){
  454. // For each stream, maintain a separate queue for data and control
  455. InitializeListHead (&pHwDevExt->StreamSRBList[j]);
  456. InitializeListHead (&pHwDevExt->StreamControlSRBList[j]);
  457. KeInitializeSpinLock (&pHwDevExt->StreamSRBSpinLock[j]);
  458. pHwDevExt->StreamSRBListSize[j] = 0;
  459. }
  460. KdPrint(("TsbVcap: Exit, HwInitialize()\n"));
  461. pSrb->Status = STATUS_SUCCESS;
  462. return (TRUE);
  463. }
  464. /*
  465. ** HwUnInitialize()
  466. **
  467. ** This routine is called when an SRB_UNINITIALIZE_DEVICE request is received
  468. **
  469. ** Arguments:
  470. **
  471. ** pSrb - pointer to stream request block for the UnInitialize command
  472. **
  473. ** Returns:
  474. **
  475. ** Side Effects: none
  476. */
  477. BOOL
  478. STREAMAPI
  479. HwUnInitialize (
  480. PHW_STREAM_REQUEST_BLOCK pSrb
  481. )
  482. {
  483. #ifdef TOSHIBA
  484. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  485. if ( CurrentOSType ) { // NT5.0
  486. if ( pHwDevExt->pCaptureBufferY )
  487. {
  488. // free frame buffer
  489. MmFreeContiguousMemory(pHwDevExt->pCaptureBufferY);
  490. pHwDevExt->pCaptureBufferY = NULL;
  491. pHwDevExt->pPhysCaptureBufferY.LowPart = 0;
  492. pHwDevExt->pPhysCaptureBufferY.HighPart = 0;
  493. }
  494. if ( pHwDevExt->pCaptureBufferU )
  495. {
  496. // free frame buffer
  497. MmFreeContiguousMemory(pHwDevExt->pCaptureBufferU);
  498. pHwDevExt->pCaptureBufferU = NULL;
  499. pHwDevExt->pPhysCaptureBufferU.LowPart = 0;
  500. pHwDevExt->pPhysCaptureBufferU.HighPart = 0;
  501. }
  502. if ( pHwDevExt->pCaptureBufferV )
  503. {
  504. // free frame buffer
  505. MmFreeContiguousMemory(pHwDevExt->pCaptureBufferV);
  506. pHwDevExt->pCaptureBufferV = NULL;
  507. pHwDevExt->pPhysCaptureBufferV.LowPart = 0;
  508. pHwDevExt->pPhysCaptureBufferV.HighPart = 0;
  509. }
  510. }
  511. #endif//TOSHIBA
  512. pSrb->Status = STATUS_SUCCESS;
  513. return TRUE;
  514. }
  515. /*
  516. ** AdapterPowerState()
  517. **
  518. ** This routine is called when an SRB_CHANGE_POWER_STATE request is received
  519. **
  520. ** Arguments:
  521. **
  522. ** pSrb - pointer to stream request block for the Change Power state command
  523. **
  524. ** Returns:
  525. **
  526. ** Side Effects: none
  527. */
  528. BOOLEAN
  529. STREAMAPI
  530. AdapterPowerState (
  531. PHW_STREAM_REQUEST_BLOCK pSrb
  532. )
  533. {
  534. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  535. #ifdef TOSHIBA
  536. int Counter;
  537. PSTREAMEX pStrmEx;
  538. #endif//TOSHIBA
  539. pHwDevExt->DeviceState = pSrb->CommandData.DeviceState;
  540. #ifdef TOSHIBA
  541. for (Counter = 0; Counter < DRIVER_STREAM_COUNT; Counter++) {
  542. if ( pStrmEx = (PSTREAMEX)pHwDevExt->pStrmEx[Counter] ) {
  543. //
  544. // Only when it is not streaming, its power state can be changed.
  545. // We have "DontSuspendIfStreamsAreRunning" turn on in the INF.
  546. //
  547. if (pStrmEx->KSState == KSSTATE_PAUSE ||
  548. pStrmEx->KSState == KSSTATE_RUN) {
  549. if (pHwDevExt->DeviceState == PowerDeviceD3) {
  550. if (pHwDevExt->bVideoIn == TRUE) {
  551. // disable the RPS_INT and field interrupts
  552. BertInterruptEnable(pHwDevExt, FALSE);
  553. BertDMAEnable(pHwDevExt, FALSE);
  554. // wait for the current data xfer to complete
  555. pHwDevExt->bVideoIn = FALSE;
  556. }
  557. VideoQueueCancelAllSRBs (pStrmEx);
  558. break;
  559. } else if (pHwDevExt->DeviceState == PowerDeviceD0) {
  560. pHwDevExt->bVideoIn = TRUE;
  561. #ifdef TOSHIBA // '99-01-20 Modified
  562. DevicePowerON( pSrb );
  563. #else //TOSHIBA
  564. StreamClassCallAtNewPriority(
  565. NULL,
  566. pSrb->HwDeviceExtension,
  567. Low,
  568. (PHW_PRIORITY_ROUTINE) DevicePowerON,
  569. pSrb
  570. );
  571. #endif//TOSHIBA
  572. }
  573. }
  574. }
  575. }
  576. #endif//TOSHIBA
  577. return TRUE;
  578. }
  579. /*
  580. ** AdapterSetInstance()
  581. **
  582. ** This routine is called to set all of the Medium instance fields
  583. **
  584. ** Arguments:
  585. **
  586. ** pSrb - pointer to stream request block
  587. **
  588. ** Returns:
  589. **
  590. ** Side Effects: none
  591. */
  592. VOID
  593. STREAMAPI
  594. AdapterSetInstance (
  595. PHW_STREAM_REQUEST_BLOCK pSrb
  596. )
  597. {
  598. int j;
  599. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  600. // Use our HwDevExt as the instance data on the Mediums
  601. // This allows multiple instances to be uniquely identified and
  602. // connected. The value used in .Id is not important, only that
  603. // it is unique for each hardware connection
  604. #ifdef TOSHIBA
  605. for (j = 0; j < SIZEOF_ARRAY (CaptureMediums); j++) {
  606. CaptureMediums[j].Id = 0; //(ULONG) pHwDevExt;
  607. }
  608. #else //TOSHIBA
  609. for (j = 0; j < SIZEOF_ARRAY (TVTunerMediums); j++) {
  610. TVTunerMediums[j].Id = 0; //(ULONG) pHwDevExt;
  611. }
  612. for (j = 0; j < SIZEOF_ARRAY (TVAudioMediums); j++) {
  613. TVAudioMediums[j].Id = 0; //(ULONG) pHwDevExt;
  614. }
  615. for (j = 0; j < SIZEOF_ARRAY (CrossbarMediums); j++) {
  616. CrossbarMediums[j].Id = 0; //(ULONG) pHwDevExt;
  617. }
  618. for (j = 0; j < SIZEOF_ARRAY (CaptureMediums); j++) {
  619. CaptureMediums[j].Id = 0; //(ULONG) pHwDevExt;
  620. }
  621. pHwDevExt->AnalogVideoInputMedium = CaptureMediums[2];
  622. #endif//TOSHIBA
  623. }
  624. /*
  625. ** AdapterCompleteInitialization()
  626. **
  627. ** This routine is called when an SRB_COMPLETE_INITIALIZATION request is received
  628. **
  629. ** Arguments:
  630. **
  631. ** pSrb - pointer to stream request block
  632. **
  633. ** Returns:
  634. **
  635. ** Side Effects: none
  636. */
  637. VOID
  638. STREAMAPI
  639. AdapterCompleteInitialization (
  640. PHW_STREAM_REQUEST_BLOCK pSrb
  641. )
  642. {
  643. NTSTATUS Status;
  644. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  645. KIRQL KIrql;
  646. KIrql = KeGetCurrentIrql();
  647. // The following allows multiple instance of identical hardware
  648. // to be installed
  649. AdapterSetInstance (pSrb);
  650. // Create the Registry blobs that DShow uses to create
  651. // graphs via Mediums
  652. #ifndef TOSHIBA
  653. // Register the TVTuner
  654. Status = StreamClassRegisterFilterWithNoKSPins (
  655. pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
  656. &KSCATEGORY_TVTUNER, // IN GUID * InterfaceClassGUID,
  657. SIZEOF_ARRAY (TVTunerMediums), // IN ULONG PinCount,
  658. TVTunerPinDirection, // IN ULONG * Flags,
  659. TVTunerMediums, // IN KSPIN_MEDIUM * MediumList,
  660. NULL // IN GUID * CategoryList
  661. );
  662. // Register the Crossbar
  663. Status = StreamClassRegisterFilterWithNoKSPins (
  664. pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
  665. &KSCATEGORY_CROSSBAR, // IN GUID * InterfaceClassGUID,
  666. SIZEOF_ARRAY (CrossbarMediums), // IN ULONG PinCount,
  667. CrossbarPinDirection, // IN ULONG * Flags,
  668. CrossbarMediums, // IN KSPIN_MEDIUM * MediumList,
  669. NULL // IN GUID * CategoryList
  670. );
  671. // Register the TVAudio decoder
  672. Status = StreamClassRegisterFilterWithNoKSPins (
  673. pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
  674. &KSCATEGORY_TVAUDIO, // IN GUID * InterfaceClassGUID,
  675. SIZEOF_ARRAY (TVAudioMediums), // IN ULONG PinCount,
  676. TVAudioPinDirection, // IN ULONG * Flags,
  677. TVAudioMediums, // IN KSPIN_MEDIUM * MediumList,
  678. NULL // IN GUID * CategoryList
  679. );
  680. // Register the Capture filter
  681. // Note: This should be done automatically be MSKsSrv.sys,
  682. // when that component comes on line (if ever) ...
  683. Status = StreamClassRegisterFilterWithNoKSPins (
  684. pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
  685. &KSCATEGORY_CAPTURE, // IN GUID * InterfaceClassGUID,
  686. SIZEOF_ARRAY (CaptureMediums), // IN ULONG PinCount,
  687. CapturePinDirection, // IN ULONG * Flags,
  688. CaptureMediums, // IN KSPIN_MEDIUM * MediumList,
  689. NULL // IN GUID * CategoryList
  690. );
  691. #endif//TOSHIBA
  692. }
  693. /*
  694. ** AdapterOpenStream()
  695. **
  696. ** This routine is called when an OpenStream SRB request is received.
  697. ** A stream is identified by a stream number, which indexes an array
  698. ** of KSDATARANGE structures. The particular KSDATAFORMAT format to
  699. ** be used is also passed in, which should be verified for validity.
  700. **
  701. ** Arguments:
  702. **
  703. ** pSrb - pointer to stream request block for the Open command
  704. **
  705. ** Returns:
  706. **
  707. ** Side Effects: none
  708. */
  709. VOID
  710. STREAMAPI
  711. AdapterOpenStream (
  712. PHW_STREAM_REQUEST_BLOCK pSrb
  713. )
  714. {
  715. //
  716. // the stream extension structure is allocated by the stream class driver
  717. //
  718. PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
  719. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  720. int StreamNumber = pSrb->StreamObject->StreamNumber;
  721. PKSDATAFORMAT pKSDataFormat = pSrb->CommandData.OpenFormat;
  722. #ifdef TOSHIBA
  723. int Counter;
  724. BOOL First = TRUE;
  725. #endif//TOSHIBA
  726. RtlZeroMemory(pStrmEx, sizeof(STREAMEX));
  727. KdPrint(("TsbVcap: ------- ADAPTEROPENSTREAM ------- StreamNumber=%d\n", StreamNumber));
  728. //
  729. // check that the stream index requested isn't too high
  730. // or that the maximum number of instances hasn't been exceeded
  731. //
  732. if (StreamNumber >= DRIVER_STREAM_COUNT || StreamNumber < 0) {
  733. pSrb->Status = STATUS_INVALID_PARAMETER;
  734. return;
  735. }
  736. //
  737. // Check that we haven't exceeded the instance count for this stream
  738. //
  739. if (pHwDevExt->ActualInstances[StreamNumber] >=
  740. Streams[StreamNumber].hwStreamInfo.NumberOfPossibleInstances) {
  741. pSrb->Status = STATUS_INVALID_PARAMETER;
  742. return;
  743. }
  744. //
  745. // Check the validity of the format being requested
  746. //
  747. if (!AdapterVerifyFormat (pKSDataFormat, StreamNumber)) {
  748. pSrb->Status = STATUS_INVALID_PARAMETER;
  749. return;
  750. }
  751. #ifdef TOSHIBA
  752. QueryControlsFromRegistry(pHwDevExt);
  753. #endif//TOSHIBA
  754. //
  755. // And set the format for the stream
  756. //
  757. if (!VideoSetFormat (pSrb)) {
  758. return;
  759. }
  760. ASSERT (pHwDevExt->pStrmEx [StreamNumber] == NULL);
  761. #ifdef TOSHIBA
  762. for (Counter = 0; Counter < DRIVER_STREAM_COUNT; Counter++) {
  763. if ( pHwDevExt->pStrmEx[Counter] ) {
  764. First = FALSE;
  765. break;
  766. }
  767. } // for all streams
  768. #endif//TOSHIBA
  769. // Maintain an array of all the StreamEx structures in the HwDevExt
  770. // so that we can cancel IRPs from any stream
  771. pHwDevExt->pStrmEx [StreamNumber] = (PSTREAMX) pStrmEx;
  772. // Set up pointers to the handlers for the stream data and control handlers
  773. pSrb->StreamObject->ReceiveDataPacket =
  774. (PVOID) Streams[StreamNumber].hwStreamObject.ReceiveDataPacket;
  775. pSrb->StreamObject->ReceiveControlPacket =
  776. (PVOID) Streams[StreamNumber].hwStreamObject.ReceiveControlPacket;
  777. //
  778. // The DMA flag must be set when the device will be performing DMA directly
  779. // to the data buffer addresses passed in to the ReceiceDataPacket routines.
  780. //
  781. pSrb->StreamObject->Dma = Streams[StreamNumber].hwStreamObject.Dma;
  782. //
  783. // The PIO flag must be set when the mini driver will be accessing the data
  784. // buffers passed in using logical addressing
  785. //
  786. pSrb->StreamObject->Pio = Streams[StreamNumber].hwStreamObject.Pio;
  787. //
  788. // How many extra bytes will be passed up from the driver for each frame?
  789. //
  790. pSrb->StreamObject->StreamHeaderMediaSpecific =
  791. Streams[StreamNumber].hwStreamObject.StreamHeaderMediaSpecific;
  792. pSrb->StreamObject->StreamHeaderWorkspace =
  793. Streams[StreamNumber].hwStreamObject.StreamHeaderWorkspace;
  794. //
  795. // Indicate the clock support available on this stream
  796. //
  797. pSrb->StreamObject->HwClockObject =
  798. Streams[StreamNumber].hwStreamObject.HwClockObject;
  799. //
  800. // Increment the instance count on this stream
  801. //
  802. pHwDevExt->ActualInstances[StreamNumber]++;
  803. // Retain a private copy of the HwDevExt and StreamObject in the stream extension
  804. // so we can use a timer
  805. pStrmEx->pHwDevExt = pHwDevExt; // For timer use
  806. pStrmEx->pStreamObject = pSrb->StreamObject; // For timer use
  807. // Initialize the compression settings
  808. // These may have been changed from the default values in the HwDevExt
  809. // before the stream was opened
  810. pStrmEx->CompressionSettings.CompressionKeyFrameRate =
  811. pHwDevExt->CompressionSettings.CompressionKeyFrameRate;
  812. pStrmEx->CompressionSettings.CompressionPFramesPerKeyFrame =
  813. pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame;
  814. pStrmEx->CompressionSettings.CompressionQuality =
  815. pHwDevExt->CompressionSettings.CompressionQuality;
  816. // Init VideoControl properties
  817. pStrmEx->VideoControlMode = pHwDevExt->VideoControlMode;
  818. #ifdef TOSHIBA
  819. if ( First ) {
  820. #ifdef TOSHIBA // '99-01-20 Modified
  821. CameraPowerON( pSrb );
  822. #else //TOSHIBA
  823. StreamClassCallAtNewPriority(
  824. NULL,
  825. pSrb->HwDeviceExtension,
  826. Low,
  827. (PHW_PRIORITY_ROUTINE) CameraPowerON,
  828. pSrb
  829. );
  830. #endif//TOSHIBA
  831. }
  832. #endif//TOSHIBA
  833. KdPrint(("TsbVcap: AdapterOpenStream Exit\n"));
  834. }
  835. /*
  836. ** AdapterCloseStream()
  837. **
  838. ** Close the requested data stream.
  839. **
  840. ** Note that a stream could be closed arbitrarily in the midst of streaming
  841. ** if a user mode app crashes. Therefore, you must release all outstanding
  842. ** resources, disable interrupts, complete all pending SRBs, and put the
  843. ** stream back into a quiescent condition.
  844. **
  845. ** Arguments:
  846. **
  847. ** pSrb the request block requesting to close the stream
  848. **
  849. ** Returns:
  850. **
  851. ** Side Effects: none
  852. */
  853. VOID
  854. STREAMAPI
  855. AdapterCloseStream (
  856. PHW_STREAM_REQUEST_BLOCK pSrb
  857. )
  858. {
  859. PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
  860. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  861. int StreamNumber = pSrb->StreamObject->StreamNumber;
  862. PKSDATAFORMAT pKSDataFormat = pSrb->CommandData.OpenFormat;
  863. KS_VIDEOINFOHEADER *pVideoInfoHdr = pStrmEx->pVideoInfoHeader;
  864. #ifdef TOSHIBA
  865. int Counter;
  866. BOOL ClosedAll = TRUE;
  867. #endif//TOSHIBA
  868. KdPrint(("TsbVcap: -------- ADAPTERCLOSESTREAM ------ StreamNumber=%d\n", StreamNumber));
  869. if (pHwDevExt->StreamSRBListSize > 0) {
  870. VideoQueueCancelAllSRBs (pStrmEx);
  871. KdPrint(("TsbVcap: Outstanding SRBs at stream close!!!\n"));
  872. }
  873. pHwDevExt->ActualInstances[StreamNumber]--;
  874. ASSERT (pHwDevExt->pStrmEx [StreamNumber] != 0);
  875. pHwDevExt->pStrmEx [StreamNumber] = 0;
  876. //
  877. // the minidriver should free any resources that were allocate at
  878. // open stream time etc.
  879. //
  880. // Free the variable length VIDEOINFOHEADER
  881. if (pVideoInfoHdr) {
  882. ExFreePool(pVideoInfoHdr);
  883. pStrmEx->pVideoInfoHeader = NULL;
  884. }
  885. // Make sure we no longer reference the clock
  886. pStrmEx->hMasterClock = NULL;
  887. // Make sure the state is reset to stopped,
  888. pStrmEx->KSState = KSSTATE_STOP;
  889. #ifdef TOSHIBA
  890. for (Counter = 0; Counter < DRIVER_STREAM_COUNT; Counter++) {
  891. if ( pHwDevExt->pStrmEx[Counter] ) {
  892. ClosedAll = FALSE;
  893. break;
  894. }
  895. } // for all streams
  896. if ( ClosedAll ) {
  897. if( pHwDevExt->dblBufflag ){
  898. Free_TriBuffer(pHwDevExt);
  899. pHwDevExt->IsRPSReady = FALSE;
  900. pHwDevExt->dblBufflag = FALSE;
  901. }
  902. #ifdef TOSHIBA // '99-01-20 Modified
  903. CameraPowerOFF( pSrb );
  904. #else //TOSHIBA
  905. StreamClassCallAtNewPriority(
  906. NULL,
  907. pSrb->HwDeviceExtension,
  908. Low,
  909. (PHW_PRIORITY_ROUTINE) CameraPowerOFF,
  910. pSrb
  911. );
  912. #endif//TOSHIBA
  913. SaveControlsToRegistry(pHwDevExt);
  914. }
  915. #endif//TOSHIBA
  916. }
  917. /*
  918. ** AdapterStreamInfo()
  919. **
  920. ** Returns the information of all streams that are supported by the
  921. ** mini-driver
  922. **
  923. ** Arguments:
  924. **
  925. ** pSrb - Pointer to the STREAM_REQUEST_BLOCK
  926. ** pSrb->HwDeviceExtension - will be the hardware device extension for
  927. ** as initialised in HwInitialise
  928. **
  929. ** Returns:
  930. **
  931. ** Side Effects: none
  932. */
  933. VOID
  934. STREAMAPI
  935. AdapterStreamInfo (
  936. PHW_STREAM_REQUEST_BLOCK pSrb
  937. )
  938. {
  939. int j;
  940. PHW_DEVICE_EXTENSION pHwDevExt =
  941. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  942. //
  943. // pick up the pointer to header which preceeds the stream info structs
  944. //
  945. PHW_STREAM_HEADER pstrhdr =
  946. (PHW_STREAM_HEADER)&(pSrb->CommandData.StreamBuffer->StreamHeader);
  947. //
  948. // pick up the pointer to the array of stream information data structures
  949. //
  950. PHW_STREAM_INFORMATION pstrinfo =
  951. (PHW_STREAM_INFORMATION)&(pSrb->CommandData.StreamBuffer->StreamInfo);
  952. //
  953. // verify that the buffer is large enough to hold our return data
  954. //
  955. DEBUG_ASSERT (pSrb->NumberOfBytesToTransfer >=
  956. sizeof (HW_STREAM_HEADER) +
  957. sizeof (HW_STREAM_INFORMATION) * DRIVER_STREAM_COUNT);
  958. #ifndef TOSHIBA
  959. // Ugliness. To allow mulitple instances, modify the pointer to the
  960. // AnalogVideoMedium and save it in our device extension
  961. Streams[STREAM_AnalogVideoInput].hwStreamInfo.Mediums =
  962. &pHwDevExt->AnalogVideoInputMedium;
  963. pHwDevExt->AnalogVideoInputMedium = CrossbarMediums[9];
  964. pHwDevExt->AnalogVideoInputMedium.Id = 0; //(ULONG) pHwDevExt;
  965. #endif//TOSHIBA
  966. //
  967. // Set the header
  968. //
  969. StreamHeader.NumDevPropArrayEntries = NUMBER_OF_ADAPTER_PROPERTY_SETS;
  970. StreamHeader.DevicePropertiesArray = (PKSPROPERTY_SET) AdapterPropertyTable;
  971. *pstrhdr = StreamHeader;
  972. //
  973. // stuff the contents of each HW_STREAM_INFORMATION struct
  974. //
  975. for (j = 0; j < DRIVER_STREAM_COUNT; j++) {
  976. *pstrinfo++ = Streams[j].hwStreamInfo;
  977. }
  978. }
  979. /*
  980. ** AdapterReceivePacket()
  981. **
  982. ** Main entry point for receiving adapter based request SRBs. This routine
  983. ** will always be called at Passive level.
  984. **
  985. ** Note: This is an asyncronous entry point. The request does not necessarily
  986. ** complete on return from this function, the request only completes when a
  987. ** StreamClassDeviceNotification on this request block, of type
  988. ** DeviceRequestComplete, is issued.
  989. **
  990. ** Arguments:
  991. **
  992. ** pSrb - Pointer to the STREAM_REQUEST_BLOCK
  993. ** pSrb->HwDeviceExtension - will be the hardware device extension for
  994. ** as initialised in HwInitialise
  995. **
  996. ** Returns:
  997. **
  998. ** Side Effects: none
  999. */
  1000. VOID
  1001. STREAMAPI
  1002. AdapterReceivePacket(
  1003. IN PHW_STREAM_REQUEST_BLOCK pSrb
  1004. )
  1005. {
  1006. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  1007. BOOL Busy;
  1008. DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
  1009. KdPrint(("TsbVcap: Receiving Adapter SRB %8x, %x\n", pSrb, pSrb->Command));
  1010. // The very first time through, we need to initialize the adapter spinlock
  1011. // and queue
  1012. if (!pHwDevExt->AdapterQueueInitialized) {
  1013. InitializeListHead (&pHwDevExt->AdapterSRBList);
  1014. KeInitializeSpinLock (&pHwDevExt->AdapterSpinLock);
  1015. pHwDevExt->AdapterQueueInitialized = TRUE;
  1016. pHwDevExt->ProcessingAdapterSRB = FALSE;
  1017. }
  1018. //
  1019. // If we're already processing an SRB, add it to the queue
  1020. //
  1021. Busy = AddToListIfBusy (
  1022. pSrb,
  1023. &pHwDevExt->AdapterSpinLock,
  1024. &pHwDevExt->ProcessingAdapterSRB,
  1025. &pHwDevExt->AdapterSRBList);
  1026. if (Busy) {
  1027. return;
  1028. }
  1029. //
  1030. // This will run until the queue is empty
  1031. //
  1032. while (TRUE) {
  1033. //
  1034. // Assume success
  1035. //
  1036. pSrb->Status = STATUS_SUCCESS;
  1037. //
  1038. // determine the type of packet.
  1039. //
  1040. switch (pSrb->Command)
  1041. {
  1042. case SRB_INITIALIZE_DEVICE:
  1043. // open the device
  1044. HwInitialize(pSrb);
  1045. break;
  1046. case SRB_UNINITIALIZE_DEVICE:
  1047. // close the device.
  1048. HwUnInitialize(pSrb);
  1049. break;
  1050. case SRB_OPEN_STREAM:
  1051. // open a stream
  1052. AdapterOpenStream(pSrb);
  1053. break;
  1054. case SRB_CLOSE_STREAM:
  1055. // close a stream
  1056. AdapterCloseStream(pSrb);
  1057. break;
  1058. case SRB_GET_STREAM_INFO:
  1059. //
  1060. // return a block describing all the streams
  1061. //
  1062. AdapterStreamInfo(pSrb);
  1063. break;
  1064. case SRB_GET_DATA_INTERSECTION:
  1065. //
  1066. // Return a format, given a range
  1067. //
  1068. AdapterFormatFromRange(pSrb);
  1069. break;
  1070. case SRB_OPEN_DEVICE_INSTANCE:
  1071. case SRB_CLOSE_DEVICE_INSTANCE:
  1072. //
  1073. // We should never get these since this is a single instance device
  1074. //
  1075. TRAP
  1076. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1077. break;
  1078. case SRB_GET_DEVICE_PROPERTY:
  1079. //
  1080. // Get adapter wide properties
  1081. //
  1082. AdapterGetProperty (pSrb);
  1083. break;
  1084. case SRB_SET_DEVICE_PROPERTY:
  1085. //
  1086. // Set adapter wide properties
  1087. //
  1088. AdapterSetProperty (pSrb);
  1089. break;
  1090. case SRB_PAGING_OUT_DRIVER:
  1091. //
  1092. // The driver is being paged out
  1093. // Disable Interrupts if you have them!
  1094. //
  1095. KdPrint(("'TsbVcap: Receiving SRB_PAGING_OUT_DRIVER -- SRB=%x\n", pSrb));
  1096. break;
  1097. case SRB_CHANGE_POWER_STATE:
  1098. //
  1099. // Changing the device power state, D0 ... D3
  1100. //
  1101. KdPrint(("'TsbVcap: Receiving SRB_CHANGE_POWER_STATE ------ SRB=%x\n", pSrb));
  1102. AdapterPowerState(pSrb);
  1103. break;
  1104. case SRB_INITIALIZATION_COMPLETE:
  1105. //
  1106. // Stream class has finished initialization.
  1107. // Now create DShow Medium interface BLOBs.
  1108. // This needs to be done at low priority since it uses the registry
  1109. //
  1110. KdPrint(("'TsbVcap: Receiving SRB_INITIALIZATION_COMPLETE-- SRB=%x\n", pSrb));
  1111. AdapterCompleteInitialization (pSrb);
  1112. break;
  1113. case SRB_UNKNOWN_DEVICE_COMMAND:
  1114. default:
  1115. //
  1116. // this is a request that we do not understand. Indicate invalid
  1117. // command and complete the request
  1118. //
  1119. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1120. }
  1121. //
  1122. // Indicate back to the Stream Class that we're done with this SRB
  1123. //
  1124. CompleteDeviceSRB (pSrb);
  1125. //
  1126. // See if there's anything else on the queue
  1127. //
  1128. Busy = RemoveFromListIfAvailable (
  1129. &pSrb,
  1130. &pHwDevExt->AdapterSpinLock,
  1131. &pHwDevExt->ProcessingAdapterSRB,
  1132. &pHwDevExt->AdapterSRBList);
  1133. if (!Busy) {
  1134. break;
  1135. }
  1136. } // end of while there's anything in the queue
  1137. }
  1138. /*
  1139. ** AdapterCancelPacket ()
  1140. **
  1141. ** Request to cancel a packet that is currently in process in the minidriver
  1142. **
  1143. ** Arguments:
  1144. **
  1145. ** pSrb - pointer to request packet to cancel
  1146. **
  1147. ** Returns:
  1148. **
  1149. ** Side Effects: none
  1150. */
  1151. VOID
  1152. STREAMAPI
  1153. AdapterCancelPacket(
  1154. PHW_STREAM_REQUEST_BLOCK pSrb
  1155. )
  1156. {
  1157. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  1158. PSTREAMEX pStrmEx;
  1159. int StreamNumber;
  1160. BOOL Found = FALSE;
  1161. //
  1162. // Run through all the streams the driver has available
  1163. //
  1164. for (StreamNumber = 0; !Found && (StreamNumber < DRIVER_STREAM_COUNT); StreamNumber++) {
  1165. //
  1166. // Check to see if the stream is in use
  1167. //
  1168. if (pStrmEx = (PSTREAMEX) pHwDevExt->pStrmEx[StreamNumber]) {
  1169. Found = VideoQueueCancelOneSRB (
  1170. pStrmEx,
  1171. pSrb
  1172. );
  1173. } // if the stream is open
  1174. } // for all streams
  1175. KdPrint(("TsbVcap: Cancelling SRB %8x Succeeded=%d\n", pSrb, Found));
  1176. }
  1177. /*
  1178. ** AdapterTimeoutPacket()
  1179. **
  1180. ** This routine is called when a packet has been in the minidriver for
  1181. ** too long. The adapter must decide what to do with the packet
  1182. **
  1183. ** Arguments:
  1184. **
  1185. ** pSrb - pointer to the request packet that timed out
  1186. **
  1187. ** Returns:
  1188. **
  1189. ** Side Effects: none
  1190. */
  1191. VOID
  1192. STREAMAPI
  1193. AdapterTimeoutPacket(
  1194. PHW_STREAM_REQUEST_BLOCK pSrb
  1195. )
  1196. {
  1197. //
  1198. // Unlike most devices, we need to hold onto data SRBs indefinitely,
  1199. // since the graph could be in a pause state indefinitely
  1200. //
  1201. KdPrint(("TsbVcap: Timeout Adapter SRB %8x\n", pSrb));
  1202. pSrb->TimeoutCounter = pSrb->TimeoutOriginal;
  1203. }
  1204. /*
  1205. ** CompleteDeviceSRB ()
  1206. **
  1207. ** This routine is called when a packet is being completed.
  1208. ** The optional second notification type is used to indicate ReadyForNext
  1209. **
  1210. ** Arguments:
  1211. **
  1212. ** pSrb - pointer to the request packet that timed out
  1213. **
  1214. ** Returns:
  1215. **
  1216. ** Side Effects:
  1217. **
  1218. */
  1219. VOID
  1220. STREAMAPI
  1221. CompleteDeviceSRB (
  1222. IN PHW_STREAM_REQUEST_BLOCK pSrb
  1223. )
  1224. {
  1225. KdPrint(("TsbVcap: Completing Adapter SRB %8x\n", pSrb));
  1226. StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
  1227. }
  1228. /*
  1229. ** AdapterCompareGUIDsAndFormatSize()
  1230. **
  1231. ** Checks for a match on the three GUIDs and FormatSize
  1232. **
  1233. ** Arguments:
  1234. **
  1235. ** IN DataRange1
  1236. ** IN DataRange2
  1237. ** BOOL fCompareFormatSize - TRUE when comparing ranges
  1238. ** - FALSE when comparing formats
  1239. **
  1240. ** Returns:
  1241. **
  1242. ** TRUE if all elements match
  1243. ** FALSE if any are different
  1244. **
  1245. ** Side Effects: none
  1246. */
  1247. BOOL
  1248. STREAMAPI
  1249. AdapterCompareGUIDsAndFormatSize(
  1250. IN PKSDATARANGE DataRange1,
  1251. IN PKSDATARANGE DataRange2,
  1252. BOOL fCompareFormatSize
  1253. )
  1254. {
  1255. return (
  1256. IsEqualGUID (
  1257. &DataRange1->MajorFormat,
  1258. &DataRange2->MajorFormat) &&
  1259. IsEqualGUID (
  1260. &DataRange1->SubFormat,
  1261. &DataRange2->SubFormat) &&
  1262. IsEqualGUID (
  1263. &DataRange1->Specifier,
  1264. &DataRange2->Specifier) &&
  1265. (fCompareFormatSize ?
  1266. (DataRange1->FormatSize == DataRange2->FormatSize) : TRUE ));
  1267. }
  1268. /*
  1269. ** AdapterVerifyFormat()
  1270. **
  1271. ** Checks the validity of a format request by walking through the
  1272. ** array of supported KSDATA_RANGEs for a given stream.
  1273. **
  1274. ** Arguments:
  1275. **
  1276. ** pKSDataFormat - pointer of a KSDATAFORMAT structure.
  1277. ** StreamNumber - index of the stream being queried / opened.
  1278. **
  1279. ** Returns:
  1280. **
  1281. ** TRUE if the format is supported
  1282. ** FALSE if the format cannot be suppored
  1283. **
  1284. ** Side Effects: none
  1285. */
  1286. BOOL
  1287. STREAMAPI
  1288. AdapterVerifyFormat(
  1289. PKSDATAFORMAT pKSDataFormatToVerify,
  1290. int StreamNumber
  1291. )
  1292. {
  1293. BOOL fOK = FALSE;
  1294. ULONG j;
  1295. ULONG NumberOfFormatArrayEntries;
  1296. PKSDATAFORMAT *pAvailableFormats;
  1297. //
  1298. // Check that the stream number is valid
  1299. //
  1300. if (StreamNumber >= DRIVER_STREAM_COUNT) {
  1301. TRAP;
  1302. return FALSE;
  1303. }
  1304. NumberOfFormatArrayEntries =
  1305. Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
  1306. //
  1307. // Get the pointer to the array of available formats
  1308. //
  1309. pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;
  1310. KdPrint(("TsbVcap: AdapterVerifyFormat, Stream=%d\n", StreamNumber));
  1311. KdPrint(("TsbVcap: FormatSize=%d\n", pKSDataFormatToVerify->FormatSize));
  1312. KdPrint(("TsbVcap: MajorFormat=%x\n", pKSDataFormatToVerify->MajorFormat));
  1313. //
  1314. // Walk the formats supported by the stream
  1315. //
  1316. for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++) {
  1317. // Check for a match on the three GUIDs and format size
  1318. if (!AdapterCompareGUIDsAndFormatSize(
  1319. pKSDataFormatToVerify,
  1320. *pAvailableFormats,
  1321. FALSE /* CompareFormatSize */ )) {
  1322. continue;
  1323. }
  1324. //
  1325. // Now that the three GUIDs match, switch on the Specifier
  1326. // to do a further type-specific check
  1327. //
  1328. // -------------------------------------------------------------------
  1329. // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
  1330. // -------------------------------------------------------------------
  1331. if (IsEqualGUID (&pKSDataFormatToVerify->Specifier,
  1332. &KSDATAFORMAT_SPECIFIER_VIDEOINFO)) {
  1333. PKS_DATAFORMAT_VIDEOINFOHEADER pDataFormatVideoInfoHeader =
  1334. (PKS_DATAFORMAT_VIDEOINFOHEADER) pKSDataFormatToVerify;
  1335. PKS_VIDEOINFOHEADER pVideoInfoHdrToVerify =
  1336. (PKS_VIDEOINFOHEADER) &pDataFormatVideoInfoHeader->VideoInfoHeader;
  1337. PKS_DATARANGE_VIDEO pKSDataRangeVideo = (PKS_DATARANGE_VIDEO) *pAvailableFormats;
  1338. KS_VIDEO_STREAM_CONFIG_CAPS *pConfigCaps = &pKSDataRangeVideo->ConfigCaps;
  1339. RECT rcImage;
  1340. KdPrint(("TsbVcap: AdapterVerifyFormat\n"));
  1341. KdPrint(("TsbVcap: pVideoInfoHdrToVerify=%x\n", pVideoInfoHdrToVerify));
  1342. KdPrint(("TsbVcap: KS_VIDEOINFOHEADER size=%d\n",
  1343. KS_SIZE_VIDEOHEADER (pVideoInfoHdrToVerify)));
  1344. KdPrint(("TsbVcap: Width=%d Height=%d BitCount=%d\n",
  1345. pVideoInfoHdrToVerify->bmiHeader.biWidth,
  1346. pVideoInfoHdrToVerify->bmiHeader.biHeight,
  1347. pVideoInfoHdrToVerify->bmiHeader.biBitCount));
  1348. KdPrint(("TsbVcap: biSizeImage=%d\n",
  1349. pVideoInfoHdrToVerify->bmiHeader.biSizeImage));
  1350. /*
  1351. ** HOW BIG IS THE IMAGE REQUESTED (pseudocode follows)
  1352. **
  1353. ** if (IsRectEmpty (&rcTarget) {
  1354. ** SetRect (&rcImage, 0, 0,
  1355. ** BITMAPINFOHEADER.biWidth,
  1356. BITMAPINFOHEADER.biHeight);
  1357. ** }
  1358. ** else {
  1359. ** // Probably rendering to a DirectDraw surface,
  1360. ** // where biWidth is used to expressed the "stride"
  1361. ** // in units of pixels (not bytes) of the destination surface.
  1362. ** // Therefore, use rcTarget to get the actual image size
  1363. **
  1364. ** rcImage = rcTarget;
  1365. ** }
  1366. */
  1367. if ((pVideoInfoHdrToVerify->rcTarget.right -
  1368. pVideoInfoHdrToVerify->rcTarget.left <= 0) ||
  1369. (pVideoInfoHdrToVerify->rcTarget.bottom -
  1370. pVideoInfoHdrToVerify->rcTarget.top <= 0)) {
  1371. rcImage.left = rcImage.top = 0;
  1372. rcImage.right = pVideoInfoHdrToVerify->bmiHeader.biWidth;
  1373. rcImage.bottom = pVideoInfoHdrToVerify->bmiHeader.biHeight;
  1374. }
  1375. else {
  1376. rcImage = pVideoInfoHdrToVerify->rcTarget;
  1377. }
  1378. //
  1379. // TODO, perform all other verification tests here!!!
  1380. //
  1381. //
  1382. // HOORAY, the format passed all of the tests, so we support it
  1383. //
  1384. fOK = TRUE;
  1385. break;
  1386. } // End of VIDEOINFOHEADER specifier
  1387. #ifndef TOSHIBA
  1388. // -------------------------------------------------------------------
  1389. // Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
  1390. // -------------------------------------------------------------------
  1391. else if (IsEqualGUID (&pKSDataFormatToVerify->Specifier,
  1392. &KSDATAFORMAT_SPECIFIER_ANALOGVIDEO)) {
  1393. //
  1394. // For analog video, the DataRange and DataFormat
  1395. // are identical, so just copy the whole structure
  1396. //
  1397. PKS_DATARANGE_ANALOGVIDEO DataRangeVideo =
  1398. (PKS_DATARANGE_ANALOGVIDEO) *pAvailableFormats;
  1399. //
  1400. // TODO, perform all other verification tests here!!!
  1401. //
  1402. fOK = TRUE;
  1403. break;
  1404. } // End of KS_ANALOGVIDEOINFO specifier
  1405. #endif//TOSHIBA
  1406. } // End of loop on all formats for this stream
  1407. return fOK;
  1408. }
  1409. /*
  1410. ** AdapterFormatFromRange()
  1411. **
  1412. ** Produces a DATAFORMAT given a DATARANGE.
  1413. **
  1414. ** Think of a DATARANGE as a multidimensional space of all of the possible image
  1415. ** sizes, cropping, scaling, and framerate possibilities. Here, the caller
  1416. ** is saying "Out of this set of possibilities, could you verify that my
  1417. ** request is acceptable?". The resulting singular output is a DATAFORMAT.
  1418. ** Note that each different colorspace (YUV vs RGB8 vs RGB24)
  1419. ** must be represented as a separate DATARANGE.
  1420. **
  1421. ** Generally, the resulting DATAFORMAT will be immediately used to open a stream
  1422. ** in that format.
  1423. **
  1424. ** Arguments:
  1425. **
  1426. ** IN PHW_STREAM_REQUEST_BLOCK pSrb
  1427. **
  1428. ** Returns:
  1429. **
  1430. ** TRUE if the format is supported
  1431. ** FALSE if the format cannot be suppored
  1432. **
  1433. ** Side Effects: none
  1434. */
  1435. BOOL
  1436. STREAMAPI
  1437. AdapterFormatFromRange(
  1438. IN PHW_STREAM_REQUEST_BLOCK pSrb
  1439. )
  1440. {
  1441. PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
  1442. PKSDATARANGE DataRange;
  1443. BOOL OnlyWantsSize;
  1444. BOOL MatchFound = FALSE;
  1445. ULONG FormatSize;
  1446. ULONG StreamNumber;
  1447. ULONG j;
  1448. ULONG NumberOfFormatArrayEntries;
  1449. PKSDATAFORMAT *pAvailableFormats;
  1450. IntersectInfo = pSrb->CommandData.IntersectInfo;
  1451. StreamNumber = IntersectInfo->StreamNumber;
  1452. DataRange = IntersectInfo->DataRange;
  1453. //
  1454. // Check that the stream number is valid
  1455. //
  1456. if (StreamNumber >= DRIVER_STREAM_COUNT) {
  1457. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  1458. TRAP;
  1459. return FALSE;
  1460. }
  1461. NumberOfFormatArrayEntries =
  1462. Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
  1463. //
  1464. // Get the pointer to the array of available formats
  1465. //
  1466. pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;
  1467. //
  1468. // Is the caller trying to get the format, or the size of the format?
  1469. //
  1470. OnlyWantsSize = (IntersectInfo->SizeOfDataFormatBuffer == sizeof(ULONG));
  1471. //
  1472. // Walk the formats supported by the stream searching for a match
  1473. // of the three GUIDs which together define a DATARANGE
  1474. //
  1475. for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++) {
  1476. if (!AdapterCompareGUIDsAndFormatSize(
  1477. DataRange,
  1478. *pAvailableFormats,
  1479. TRUE /* CompareFormatSize */)) {
  1480. continue;
  1481. }
  1482. //
  1483. // Now that the three GUIDs match, switch on the Specifier
  1484. // to do a further type-specific check
  1485. //
  1486. // -------------------------------------------------------------------
  1487. // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
  1488. // -------------------------------------------------------------------
  1489. if (IsEqualGUID (&DataRange->Specifier,
  1490. &KSDATAFORMAT_SPECIFIER_VIDEOINFO)) {
  1491. PKS_DATARANGE_VIDEO DataRangeVideoToVerify =
  1492. (PKS_DATARANGE_VIDEO) DataRange;
  1493. PKS_DATARANGE_VIDEO DataRangeVideo =
  1494. (PKS_DATARANGE_VIDEO) *pAvailableFormats;
  1495. PKS_DATAFORMAT_VIDEOINFOHEADER DataFormatVideoInfoHeaderOut;
  1496. //
  1497. // Check that the other fields match
  1498. //
  1499. if ((DataRangeVideoToVerify->bFixedSizeSamples != DataRangeVideo->bFixedSizeSamples) ||
  1500. (DataRangeVideoToVerify->bTemporalCompression != DataRangeVideo->bTemporalCompression) ||
  1501. (DataRangeVideoToVerify->StreamDescriptionFlags != DataRangeVideo->StreamDescriptionFlags) ||
  1502. (DataRangeVideoToVerify->MemoryAllocationFlags != DataRangeVideo->MemoryAllocationFlags) ||
  1503. (RtlCompareMemory (&DataRangeVideoToVerify->ConfigCaps,
  1504. &DataRangeVideo->ConfigCaps,
  1505. sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) !=
  1506. sizeof (KS_VIDEO_STREAM_CONFIG_CAPS))) {
  1507. continue;
  1508. }
  1509. // MATCH FOUND!
  1510. MatchFound = TRUE;
  1511. FormatSize = sizeof (KSDATAFORMAT) +
  1512. KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader);
  1513. if (OnlyWantsSize) {
  1514. break;
  1515. }
  1516. // Caller wants the full data format
  1517. if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
  1518. pSrb->Status = STATUS_BUFFER_TOO_SMALL;
  1519. return FALSE;
  1520. }
  1521. // Copy over the KSDATAFORMAT, followed by the
  1522. // actual VideoInfoHeader
  1523. DataFormatVideoInfoHeaderOut = (PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer;
  1524. // Copy over the KSDATAFORMAT
  1525. RtlCopyMemory(
  1526. &DataFormatVideoInfoHeaderOut->DataFormat,
  1527. &DataRangeVideoToVerify->DataRange,
  1528. sizeof (KSDATARANGE));
  1529. DataFormatVideoInfoHeaderOut->DataFormat.FormatSize = FormatSize;
  1530. // Copy over the callers requested VIDEOINFOHEADER
  1531. RtlCopyMemory(
  1532. &DataFormatVideoInfoHeaderOut->VideoInfoHeader,
  1533. &DataRangeVideoToVerify->VideoInfoHeader,
  1534. KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader));
  1535. // Calculate biSizeImage for this request, and put the result in both
  1536. // the biSizeImage field of the bmiHeader AND in the SampleSize field
  1537. // of the DataFormat.
  1538. //
  1539. // Note that for compressed sizes, this calculation will probably not
  1540. // be just width * height * bitdepth
  1541. DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader.biSizeImage =
  1542. DataFormatVideoInfoHeaderOut->DataFormat.SampleSize =
  1543. KS_DIBSIZE(DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader);
  1544. //
  1545. // TODO Perform other validation such as cropping and scaling checks
  1546. //
  1547. break;
  1548. } // End of VIDEOINFOHEADER specifier
  1549. #ifndef TOSHIBA
  1550. // -------------------------------------------------------------------
  1551. // Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
  1552. // -------------------------------------------------------------------
  1553. else if (IsEqualGUID (&DataRange->Specifier,
  1554. &KSDATAFORMAT_SPECIFIER_ANALOGVIDEO)) {
  1555. //
  1556. // For analog video, the DataRange and DataFormat
  1557. // are identical, so just copy the whole structure
  1558. //
  1559. PKS_DATARANGE_ANALOGVIDEO DataRangeVideo =
  1560. (PKS_DATARANGE_ANALOGVIDEO) *pAvailableFormats;
  1561. // MATCH FOUND!
  1562. MatchFound = TRUE;
  1563. FormatSize = sizeof (KS_DATARANGE_ANALOGVIDEO);
  1564. if (OnlyWantsSize) {
  1565. break;
  1566. }
  1567. // Caller wants the full data format
  1568. if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
  1569. pSrb->Status = STATUS_BUFFER_TOO_SMALL;
  1570. return FALSE;
  1571. }
  1572. RtlCopyMemory(
  1573. IntersectInfo->DataFormatBuffer,
  1574. DataRangeVideo,
  1575. sizeof (KS_DATARANGE_ANALOGVIDEO));
  1576. ((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
  1577. break;
  1578. } // End of KS_ANALOGVIDEOINFO specifier
  1579. #endif//TOSHIBA
  1580. else {
  1581. pSrb->Status = STATUS_NO_MATCH;
  1582. return FALSE;
  1583. }
  1584. } // End of loop on all formats for this stream
  1585. if (OnlyWantsSize) {
  1586. *(PULONG) IntersectInfo->DataFormatBuffer = FormatSize;
  1587. pSrb->ActualBytesTransferred = sizeof(ULONG);
  1588. return TRUE;
  1589. }
  1590. pSrb->ActualBytesTransferred = FormatSize;
  1591. return TRUE;
  1592. }
  1593.