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.

1956 lines
62 KiB

  1. /*++
  2. Copyright (c) 1997 1998 PHILIPS I&C
  3. Module Name: mcamdrv.c.c
  4. Abstract: driver for the philips camera.
  5. Author: Paul Oosterhof
  6. Environment: Kernel mode only
  7. Revision History:
  8. Date Reason
  9. Sept.22, 98 Optimized for NT5
  10. Nov.30 , Frozen video frame for corrupted usb frames
  11. Nov.30 , properties added to deliver VID/PID actual used camera to app
  12. --*/
  13. #include "mwarn.h"
  14. #include "wdm.h"
  15. #include "mcamdrv.h"
  16. #include "strmini.h"
  17. #include "mprpobj.h"
  18. #include "mprpobjx.h"
  19. #include "mprpftn.h"
  20. #include "mcodec.h"
  21. #include "mstreams.h"
  22. #include "mssidef.h"
  23. /*
  24. * Local function definitions
  25. */
  26. static USHORT
  27. MapFrPeriodFrRate(LONGLONG llFramePeriod);
  28. static NTSTATUS
  29. PHILIPSCAM_SetFrRate_AltInterface(IN PVOID DeviceContext);
  30. /*
  31. Here the mapping is defined to alternate interfaces dependent from
  32. picture format and framerate
  33. */
  34. UCHAR InterfaceMap[9][10] = {
  35. // Size
  36. //Framerate // CIF, QCIF, SQCIF, QQCIF, VGA, SIF, SSIF, QSIF, SQSIF, SCIF
  37. /* VGA */ { 0 , 0 , 0 , 0, 1, 0 , 0 , 0 , 0 , 0 },
  38. /* 3.75 */ { 4 , 0 , 0 , 0, 0, 4 , 4 , 0 , 0 , 4 },
  39. /* 5 */ { 7 , 8 , 8 , 8, 0, 7 , 7 , 8 , 8 , 7 },
  40. /* 7.5 */ { 6 , 7 , 7 , 7, 0, 6 , 6 , 7 , 7 , 6 },
  41. /* 10 */ { 4 , 6 , 7 , 7, 0, 4 , 4 , 6 , 7 , 4 },
  42. /* 12 */ { 3 , 5 , 6 , 6, 0, 3 , 3 , 5 , 6 , 3 },
  43. /* 15 */ { 2 , 4 , 5 , 5, 0, 2 , 2 , 4 , 5 , 2 },
  44. /* 20 */ { 0 , 1 , 3 , 3, 0, 0 , 0 , 1 , 3 , 0 },
  45. /* 24 */ { 0 , 1 , 3 , 3, 0, 0 , 0 , 1 , 3 , 0 },
  46. };
  47. //QCIF20 alt.intfc. 2 is sufficient, however 20Fr/sec is asked as default by PM;
  48. //to enable the user to select as well 24Fr/sec, also alt.intfc. 1 is selected
  49. //SQCIF20 alt.intfc. 4 is sufficient, however 20Fr/sec is asked as default by PM;
  50. //to enable the user to select as well 24Fr/sec, also alt.intfc. 3 is selected
  51. ULONG PHILIPSCAM_DebugTraceLevel
  52. #ifdef MAX_DEBUG
  53. = MAX_TRACE;
  54. #else
  55. = MIN_TRACE;
  56. #endif
  57. #ifndef mmioFOURCC
  58. #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
  59. ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
  60. ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
  61. #endif
  62. KSPIN_MEDIUM StandardMedium =
  63. {
  64. STATIC_KSMEDIUMSETID_Standard,
  65. 0, 0
  66. };
  67. // ------------------------------------------------------------------------
  68. // Property sets for all video capture streams
  69. // ------------------------------------------------------------------------
  70. DEFINE_KSPROPERTY_TABLE(VideoStreamConnectionProperties)
  71. {
  72. DEFINE_KSPROPERTY_ITEM
  73. (
  74. KSPROPERTY_CONNECTION_ALLOCATORFRAMING,
  75. TRUE, // GetSupported or Handler
  76. sizeof(KSPROPERTY), // MinProperty
  77. sizeof(KSALLOCATOR_FRAMING), // MinData
  78. FALSE, // SetSupported or Handler
  79. NULL, // Values
  80. 0, // RelationsCount
  81. NULL, // Relations
  82. NULL, // SupportHandler
  83. sizeof(ULONG) // SerializedSize
  84. ),
  85. };
  86. DEFINE_KSPROPERTY_TABLE(VideoStreamDroppedFramesProperties)
  87. {
  88. DEFINE_KSPROPERTY_ITEM
  89. (
  90. KSPROPERTY_DROPPEDFRAMES_CURRENT,
  91. TRUE, // GetSupported or Handler
  92. sizeof(KSPROPERTY_DROPPEDFRAMES_CURRENT_S),// MinProperty
  93. sizeof(KSPROPERTY_DROPPEDFRAMES_CURRENT_S),// MinData
  94. FALSE, // SetSupported or Handler
  95. NULL, // Values
  96. 0, // RelationsCount
  97. NULL, // Relations
  98. NULL, // SupportHandler
  99. 0 // SerializedSize
  100. ),
  101. };
  102. // ------------------------------------------------------------------------
  103. // Array of all of the property sets supported by video streams
  104. // ------------------------------------------------------------------------
  105. DEFINE_KSPROPERTY_SET_TABLE(VideoStreamProperties)
  106. {
  107. DEFINE_KSPROPERTY_SET
  108. (
  109. &KSPROPSETID_Connection, // Set
  110. SIZEOF_ARRAY(VideoStreamConnectionProperties), // PropertiesCount
  111. VideoStreamConnectionProperties, // PropertyItem
  112. 0, // FastIoCount
  113. NULL // FastIoTable
  114. ),
  115. DEFINE_KSPROPERTY_SET
  116. (
  117. &PROPSETID_VIDCAP_DROPPEDFRAMES, // Set
  118. SIZEOF_ARRAY(VideoStreamDroppedFramesProperties), // PropertiesCount
  119. VideoStreamDroppedFramesProperties, // PropertyItem
  120. 0, // FastIoCount
  121. NULL // FastIoTable
  122. ),
  123. };
  124. #define NUMBER_VIDEO_STREAM_PROPERTIES (SIZEOF_ARRAY(VideoStreamProperties))
  125. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_QCIF_I420 = STREAMFORMAT_QCIF_I420 ;
  126. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_CIF_I420 = STREAMFORMAT_CIF_I420;
  127. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_SQCIF_I420 = STREAMFORMAT_SQCIF_I420;
  128. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_QQCIF_I420 = STREAMFORMAT_QQCIF_I420;
  129. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_SIF_I420 = STREAMFORMAT_SIF_I420 ;
  130. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_SSIF_I420 = STREAMFORMAT_SSIF_I420 ;
  131. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_QSIF_I420 = STREAMFORMAT_QSIF_I420 ;
  132. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_SQSIF_I420 = STREAMFORMAT_SQSIF_I420 ;
  133. KS_DATARANGE_VIDEO PHILIPSCAM_StreamFormat_SCIF_I420 = STREAMFORMAT_SCIF_I420 ;
  134. static PKSDATAFORMAT PHILIPSCAM_MovingStreamFormats[]={
  135. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_QCIF_I420,
  136. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_CIF_I420,
  137. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_SQCIF_I420,
  138. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_QQCIF_I420,
  139. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_SIF_I420,
  140. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_SSIF_I420,
  141. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_QSIF_I420,
  142. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_SQSIF_I420,
  143. (PKSDATAFORMAT) &PHILIPSCAM_StreamFormat_SCIF_I420
  144. };
  145. #define NUM_PHILIPSCAM_STREAM_FORMATS (SIZEOF_ARRAY(PHILIPSCAM_MovingStreamFormats))
  146. //---------------------------------------------------------------------------
  147. // Create an array that holds the list of all of the streams supported
  148. //---------------------------------------------------------------------------
  149. HW_STREAM_INFORMATION Streams [] = {
  150. // -----------------------------------------------------------------
  151. // PHILIPSCAM_Moving_Stream
  152. // -----------------------------------------------------------------
  153. // HW_STREAM_INFORMATION -------------------------------------------
  154. 1, // NumberOfPossibleInstances
  155. KSPIN_DATAFLOW_OUT, // DataFlow
  156. TRUE, // DataAccessible
  157. NUM_PHILIPSCAM_STREAM_FORMATS, // NumberOfFormatArrayEntries
  158. PHILIPSCAM_MovingStreamFormats, // StreamFormatsArray
  159. NULL, // ClassReserved[0]
  160. NULL, // ClassReserved[1]
  161. NULL, // ClassReserved[2]
  162. NULL, // ClassReserved[3]
  163. NUMBER_VIDEO_STREAM_PROPERTIES, // NumStreamPropArrayEntries
  164. (PKSPROPERTY_SET) VideoStreamProperties,// StreamPropertiesArray
  165. 0, // NumStreamEventArrayEntries;
  166. 0, // StreamEventsArray;
  167. (GUID *)&PINNAME_VIDEO_CAPTURE, // Category;
  168. (GUID *)&PINNAME_VIDEO_CAPTURE, // Name;
  169. 0, // MediumsCount
  170. &StandardMedium, // Mediums
  171. FALSE, // BridgeStream
  172. 0, // Reserved[0]
  173. 0 // Reserved[1]
  174. };
  175. /*****************************************************************************/
  176. /*****************************************************************************/
  177. /************ Start of Function Blocks **********************/
  178. /*****************************************************************************/
  179. /*****************************************************************************/
  180. /*
  181. // This function searches the maximal framerate for a given picture format
  182. // dependent from the USB bus load and selects the belonging alternate interface.
  183. //
  184. */
  185. NTSTATUS
  186. PHILIPSCAM_SetFrRate_AltInterface(IN PVOID DeviceContext){
  187. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  188. NTSTATUS ntStatus = STATUS_SUCCESS;
  189. USHORT PhFormat = deviceContext->CamStatus.PictureFormat;
  190. USHORT PhFrameRate = deviceContext->CamStatus.PictureFrameRate;
  191. USHORT j;
  192. // reset permitted framerates
  193. for (j = FRRATEVGA; j <= FRRATE24; j++){
  194. deviceContext->FrrSupported[j] = FALSE;
  195. }
  196. // set permitted framerates dependent on selected format and sensortype
  197. switch (PhFormat) {
  198. case FORMATCIF:
  199. for ( j = FRRATE375 ; j <= PhFrameRate; j++){
  200. deviceContext->FrrSupported[j] = TRUE;
  201. }
  202. break;
  203. case FORMATQCIF:
  204. for ( j = FRRATE5 ; j <= PhFrameRate; j++){
  205. deviceContext->FrrSupported[j] = TRUE;
  206. }
  207. break;
  208. case FORMATSQCIF:
  209. for ( j = FRRATE5 ; j <= PhFrameRate; j++){
  210. deviceContext->FrrSupported[j] = TRUE;
  211. }
  212. break;
  213. case FORMATQQCIF:
  214. for ( j = FRRATE5 ; j <= PhFrameRate; j++){
  215. deviceContext->FrrSupported[j] = TRUE;
  216. }
  217. break;
  218. case FORMATSIF:
  219. for ( j = FRRATE375 ; j <= PhFrameRate; j++){
  220. deviceContext->FrrSupported[j] = TRUE;
  221. }
  222. break;
  223. case FORMATSSIF:
  224. for ( j = FRRATE375 ; j <= PhFrameRate; j++){
  225. deviceContext->FrrSupported[j] = TRUE;
  226. }
  227. break;
  228. case FORMATQSIF:
  229. for ( j = FRRATE5 ; j <= PhFrameRate; j++){
  230. deviceContext->FrrSupported[j] = TRUE;
  231. }
  232. break;
  233. case FORMATSQSIF:
  234. for ( j = FRRATE5 ; j <= PhFrameRate; j++){
  235. deviceContext->FrrSupported[j] = TRUE;
  236. }
  237. break;
  238. case FORMATSCIF:
  239. for ( j = FRRATE375 ; j <= PhFrameRate; j++){
  240. deviceContext->FrrSupported[j] = TRUE;
  241. }
  242. default:
  243. ; // no permitted framerates;
  244. }
  245. // select framerate dependent on available USB bandwidth
  246. ntStatus = STATUS_NOT_FOUND;
  247. for ( PhFrameRate ;
  248. (!NT_SUCCESS(ntStatus) && (PhFrameRate != FRRATEVGA));
  249. PhFrameRate --) {
  250. if (deviceContext->FrrSupported[PhFrameRate]){
  251. if ( InterfaceMap[PhFrameRate][PhFormat] != 0 ){
  252. deviceContext->Interface->AlternateSetting =
  253. InterfaceMap[PhFrameRate][PhFormat];
  254. ntStatus = USBCAMD_SelectAlternateInterface(
  255. deviceContext,
  256. deviceContext->Interface);
  257. }
  258. if (!NT_SUCCESS(ntStatus)){
  259. deviceContext->FrrSupported[PhFrameRate]= FALSE;
  260. }else{
  261. PHILIPSCAM_KdPrint (MIN_TRACE, ("Alt Setting # %d, Max.allowed FPS %s\n",
  262. InterfaceMap[PhFrameRate][PhFormat] , FRString(PhFrameRate)));
  263. deviceContext->CamStatus.PictureFrameRate = PhFrameRate ;
  264. }
  265. }
  266. }
  267. return ntStatus;
  268. }
  269. /*
  270. ** AdapterCompareGUIDsAndFormatSize()
  271. **
  272. ** Checks for a match on the three GUIDs and FormatSize
  273. **
  274. ** Arguments:
  275. **
  276. ** IN DataRange1
  277. ** IN DataRange2
  278. **
  279. ** Returns:
  280. **
  281. ** TRUE if all elements match
  282. ** FALSE if any are different
  283. **
  284. ** Side Effects: none
  285. */
  286. BOOLEAN
  287. AdapterCompareGUIDsAndFormatSize(
  288. IN PKSDATARANGE DataRange1,
  289. IN PKSDATARANGE DataRange2)
  290. {
  291. return (
  292. IsEqualGUID (
  293. &DataRange1->MajorFormat,
  294. &DataRange2->MajorFormat) &&
  295. IsEqualGUID (
  296. &DataRange1->SubFormat,
  297. &DataRange2->SubFormat) &&
  298. IsEqualGUID (
  299. &DataRange1->Specifier,
  300. &DataRange2->Specifier) &&
  301. (DataRange1->FormatSize == DataRange2->FormatSize));
  302. }
  303. /*
  304. ** AdapterFormatFromRange()
  305. **
  306. ** Returns a DATAFORMAT from a DATARANGE
  307. **
  308. ** Arguments:
  309. **
  310. ** IN PHW_STREAM_REQUEST_BLOCK pSrb
  311. **
  312. ** Returns:
  313. **
  314. ** STATUS_SUCCESS if format is supported
  315. **
  316. ** Side Effects: none
  317. */
  318. NTSTATUS
  319. AdapterFormatFromRange(
  320. IN PHW_STREAM_REQUEST_BLOCK Srb)
  321. {
  322. PSTREAM_DATA_INTERSECT_INFO intersectInfo;
  323. PKSDATARANGE dataRange;
  324. BOOL onlyWantsSize;
  325. ULONG formatSize = 0;
  326. ULONG streamNumber;
  327. ULONG j;
  328. ULONG numberOfFormatArrayEntries;
  329. PKSDATAFORMAT *availableFormats;
  330. NTSTATUS ntStatus = STATUS_NOT_FOUND;
  331. intersectInfo = Srb->CommandData.IntersectInfo;
  332. streamNumber = intersectInfo->StreamNumber;
  333. dataRange = intersectInfo->DataRange;
  334. //
  335. // Check that the stream number is valid
  336. //
  337. // ASSERT(streamNumber == 0);
  338. numberOfFormatArrayEntries = Streams[0].NumberOfFormatArrayEntries;
  339. //
  340. // Get the pointer to the array of available formats
  341. //
  342. availableFormats = Streams[0].StreamFormatsArray;
  343. //
  344. // Is the caller trying to get the format, or the size of the format?
  345. //
  346. onlyWantsSize =
  347. (intersectInfo->SizeOfDataFormatBuffer == sizeof(ULONG));
  348. //
  349. // Walk the formats supported by the stream searching for a match
  350. // of the three GUIDs which together define a DATARANGE
  351. //
  352. for (j = 0; j < numberOfFormatArrayEntries; j++, availableFormats++) {
  353. if (!AdapterCompareGUIDsAndFormatSize(dataRange,
  354. *availableFormats)) {
  355. // not the format we want
  356. continue;
  357. }
  358. //
  359. // Now that the three GUIDs match, switch on the Specifier
  360. // to do a further type specific check
  361. //
  362. // -------------------------------------------------------------------
  363. // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
  364. // -------------------------------------------------------------------
  365. if (IsEqualGUID (&dataRange->Specifier,
  366. &KSDATAFORMAT_SPECIFIER_VIDEOINFO)) {
  367. PKS_DATARANGE_VIDEO dataRangeVideoToVerify =
  368. (PKS_DATARANGE_VIDEO) dataRange;
  369. PKS_DATARANGE_VIDEO dataRangeVideo =
  370. (PKS_DATARANGE_VIDEO) *availableFormats;
  371. PKS_DATAFORMAT_VIDEOINFOHEADER DataFormatVideoInfoHeaderOut;
  372. ULONG videoHeaderSize;
  373. ULONG rangeSize;
  374. //
  375. // Check that the other fields match
  376. //
  377. if ((dataRangeVideoToVerify->bFixedSizeSamples !=
  378. dataRangeVideo->bFixedSizeSamples) ||
  379. (dataRangeVideoToVerify->bTemporalCompression !=
  380. dataRangeVideo->bTemporalCompression) ||
  381. (dataRangeVideoToVerify->StreamDescriptionFlags !=
  382. dataRangeVideo->StreamDescriptionFlags) ||
  383. (dataRangeVideoToVerify->MemoryAllocationFlags !=
  384. dataRangeVideo->MemoryAllocationFlags) ||
  385. (RtlCompareMemory (&dataRangeVideoToVerify->ConfigCaps,
  386. &dataRangeVideo->ConfigCaps,
  387. sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) !=
  388. sizeof (KS_VIDEO_STREAM_CONFIG_CAPS))) {
  389. // not the format want
  390. continue;
  391. }
  392. if ((dataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biWidth !=
  393. dataRangeVideo->VideoInfoHeader.bmiHeader.biWidth ) ||
  394. (dataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biHeight !=
  395. dataRangeVideo->VideoInfoHeader.bmiHeader.biHeight )) {
  396. continue;
  397. }
  398. // Validate each step of the size calculations for arithmetic overflow,
  399. // and verify that the specified sizes correlate
  400. // (with unsigned math, a+b < b iff an arithmetic overflow occured)
  401. videoHeaderSize = dataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biSize +
  402. FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader);
  403. rangeSize = videoHeaderSize +
  404. FIELD_OFFSET(KS_DATARANGE_VIDEO,VideoInfoHeader);
  405. if (videoHeaderSize < FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader) ||
  406. rangeSize < FIELD_OFFSET(KS_DATARANGE_VIDEO,VideoInfoHeader) ||
  407. rangeSize > dataRangeVideoToVerify->DataRange.FormatSize) {
  408. Srb->Status = ntStatus = STATUS_INVALID_PARAMETER;
  409. break;
  410. }
  411. formatSize = sizeof(KSDATAFORMAT) + videoHeaderSize;
  412. if (onlyWantsSize) {
  413. break;
  414. }
  415. // Is the return buffer size = 0 ?
  416. if(intersectInfo->SizeOfDataFormatBuffer == 0) {
  417. ntStatus = Srb->Status = STATUS_BUFFER_OVERFLOW;
  418. // the proxy wants to know the actual buffer size to allocate.
  419. Srb->ActualBytesTransferred = formatSize;
  420. break;
  421. }
  422. // Caller wants the full data format, make sure we have room
  423. if (intersectInfo->SizeOfDataFormatBuffer < formatSize) {
  424. Srb->Status = ntStatus = STATUS_BUFFER_TOO_SMALL;
  425. break;
  426. }
  427. DataFormatVideoInfoHeaderOut =
  428. (PKS_DATAFORMAT_VIDEOINFOHEADER) intersectInfo->DataFormatBuffer;
  429. // Copy over the KSDATAFORMAT, followed by the
  430. // actual VideoInfoHeader
  431. RtlCopyMemory(
  432. &DataFormatVideoInfoHeaderOut->DataFormat,
  433. &dataRangeVideoToVerify->DataRange,
  434. sizeof (KSDATARANGE));
  435. DataFormatVideoInfoHeaderOut->DataFormat.FormatSize = formatSize;
  436. RtlCopyMemory(
  437. &DataFormatVideoInfoHeaderOut->VideoInfoHeader,
  438. &dataRangeVideoToVerify->VideoInfoHeader,
  439. videoHeaderSize);
  440. // Calculate biSizeImage for this request, and put the result in both
  441. // the biSizeImage field of the bmiHeader AND in the SampleSize field
  442. // of the DataFormat.
  443. //
  444. // Note that for compressed sizes, this calculation will probably not
  445. // be just width * height * bitdepth
  446. DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader.biSizeImage =
  447. DataFormatVideoInfoHeaderOut->DataFormat.SampleSize =
  448. KS_DIBSIZE(DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader);
  449. //
  450. // Perform other validation such as cropping and scaling checks
  451. //
  452. // we will not allow setting FPS below our minimum FPS.
  453. if ((DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame >
  454. dataRangeVideo->ConfigCaps.MaxFrameInterval) ) {
  455. DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame =
  456. dataRangeVideo->ConfigCaps.MaxFrameInterval;
  457. DataFormatVideoInfoHeaderOut->VideoInfoHeader.dwBitRate =
  458. dataRangeVideo->ConfigCaps.MinBitsPerSecond;
  459. }
  460. // we will not allow setting FPS above our maximum FPS.
  461. if ((DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame <
  462. dataRangeVideo->ConfigCaps.MinFrameInterval) ) {
  463. DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame =
  464. dataRangeVideo->ConfigCaps.MinFrameInterval;
  465. DataFormatVideoInfoHeaderOut->VideoInfoHeader.dwBitRate =
  466. dataRangeVideo->ConfigCaps.MaxBitsPerSecond;
  467. }
  468. Srb->Status = ntStatus = STATUS_SUCCESS;
  469. break;
  470. }
  471. } // End of loop on all formats for this stream
  472. if (NT_SUCCESS(ntStatus)) {
  473. if (onlyWantsSize) {
  474. *(PULONG) intersectInfo->DataFormatBuffer = formatSize;
  475. Srb->ActualBytesTransferred = sizeof(ULONG);
  476. }else {
  477. Srb->ActualBytesTransferred = formatSize;
  478. }
  479. }
  480. return ntStatus;
  481. }
  482. /*
  483. ** AdapterVerifyFormat()
  484. **
  485. ** Checks the validity of a format request by walking through the
  486. ** array of supported KSDATA_RANGEs for a given stream.
  487. **
  488. ** Arguments:
  489. **
  490. ** pKSDataFormat - pointer of a KS_DATAFORMAT_VIDEOINFOHEADER structure.
  491. ** StreamNumber - index of the stream being queried / opened.
  492. **
  493. ** Returns:
  494. **
  495. ** TRUE if the format is supported
  496. ** FALSE if the format cannot be suppored
  497. **
  498. ** Side Effects: none
  499. */
  500. BOOL
  501. AdapterVerifyFormat(
  502. PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormatToVerify,
  503. int StreamNumber
  504. )
  505. {
  506. PKSDATAFORMAT *pAvailableFormats;
  507. int NumberOfFormatArrayEntries;
  508. int j;
  509. // Make sure a format has been specified
  510. if (!pKSDataFormatToVerify)
  511. {
  512. return FALSE;
  513. }
  514. //
  515. // Make sure the stream index is valid
  516. //
  517. if (StreamNumber >= 2 || StreamNumber < 0) {
  518. return FALSE;
  519. }
  520. //
  521. // How many formats does this stream support?
  522. //
  523. NumberOfFormatArrayEntries =
  524. Streams[StreamNumber].NumberOfFormatArrayEntries;
  525. PHILIPSCAM_KdPrint (MAX_TRACE, ("AdapterVerifyFormat: Stream=%d\n",
  526. StreamNumber));
  527. PHILIPSCAM_KdPrint (MAX_TRACE, ("AdapterVerifyFormat: FormatSize=%d\n",
  528. pKSDataFormatToVerify->DataFormat.FormatSize));
  529. PHILIPSCAM_KdPrint (MAX_TRACE, ("AdapterVerifyFormat: MajorFormat=%x\n",
  530. pKSDataFormatToVerify->DataFormat.MajorFormat));
  531. //
  532. // Get the pointer to the array of available formats
  533. //
  534. pAvailableFormats = Streams[StreamNumber].StreamFormatsArray;
  535. //
  536. // Walk the array, searching for a match
  537. //
  538. for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++) {
  539. PKS_DATARANGE_VIDEO pKSDataRange = (PKS_DATARANGE_VIDEO) *pAvailableFormats;
  540. PKS_VIDEOINFOHEADER pVideoInfoHdr = &pKSDataRange->VideoInfoHeader;
  541. KS_VIDEO_STREAM_CONFIG_CAPS *pConfigCaps = &pKSDataRange->ConfigCaps;
  542. //
  543. // Check for matching size, Major Type, Sub Type, and Specifier
  544. //
  545. if (!IsEqualGUID (&pKSDataRange->DataRange.MajorFormat,
  546. &pKSDataFormatToVerify->DataFormat.MajorFormat)) {
  547. continue;
  548. }
  549. if (!IsEqualGUID (&pKSDataRange->DataRange.SubFormat,
  550. &pKSDataFormatToVerify->DataFormat.SubFormat)) {
  551. continue;
  552. }
  553. if (!IsEqualGUID (&pKSDataRange->DataRange.Specifier,
  554. &pKSDataFormatToVerify->DataFormat.Specifier)) {
  555. continue;
  556. }
  557. // -------------------------------------------------------------------
  558. // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
  559. // -------------------------------------------------------------------
  560. if (IsEqualGUID(&pKSDataRange->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_VIDEOINFO))
  561. {
  562. PKS_VIDEOINFOHEADER pVideoInfoHdrToVerify;
  563. if (pKSDataFormatToVerify->DataFormat.FormatSize < sizeof(KS_DATAFORMAT_VIDEOINFOHEADER))
  564. {
  565. break; // considered a fatal error for this format
  566. }
  567. pVideoInfoHdrToVerify = &pKSDataFormatToVerify->VideoInfoHeader;
  568. PHILIPSCAM_KdPrint (MAX_TRACE, ("AdapterVerifyFormat: pVideoInfoHdrToVerify=%x\n",
  569. pVideoInfoHdrToVerify));
  570. PHILIPSCAM_KdPrint (MAX_TRACE, ("AdapterVerifyFormat: Width=%d Height=%d biBitCount=%d\n",
  571. pVideoInfoHdrToVerify->bmiHeader.biWidth,
  572. pVideoInfoHdrToVerify->bmiHeader.biHeight,
  573. pVideoInfoHdrToVerify->bmiHeader.biBitCount));
  574. PHILIPSCAM_KdPrint (MAX_TRACE, ("AdapterVerifyFormat: biSizeImage =%d\n",
  575. pVideoInfoHdrToVerify->bmiHeader.biSizeImage));
  576. // Calculate the actual format buffer size (includes bmiHeader.biSize).
  577. // Validate each step of the size calculations for arithmetic overflow,
  578. // and verify that the specified sizes correlate
  579. // (with unsigned math, a+b < b iff an arithmetic overflow occured).
  580. {
  581. ULONG VideoHeaderSize = pVideoInfoHdrToVerify->bmiHeader.biSize +
  582. FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader);
  583. ULONG FormatSize = VideoHeaderSize +
  584. FIELD_OFFSET(KS_DATAFORMAT_VIDEOINFOHEADER,VideoInfoHeader);
  585. if (VideoHeaderSize < FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader) ||
  586. FormatSize < FIELD_OFFSET(KS_DATAFORMAT_VIDEOINFOHEADER,VideoInfoHeader) ||
  587. FormatSize > pKSDataFormatToVerify->DataFormat.FormatSize) {
  588. break; // considered a fatal error for this format
  589. }
  590. }
  591. if ((pVideoInfoHdrToVerify->bmiHeader.biWidth !=
  592. pVideoInfoHdr->bmiHeader.biWidth ) ||
  593. (pVideoInfoHdrToVerify->bmiHeader.biHeight !=
  594. pVideoInfoHdr->bmiHeader.biHeight )) {
  595. continue;
  596. }
  597. if ( pVideoInfoHdrToVerify->bmiHeader.biSizeImage !=
  598. pVideoInfoHdr->bmiHeader.biSizeImage ||
  599. pVideoInfoHdrToVerify->bmiHeader.biSizeImage >
  600. pKSDataFormatToVerify->DataFormat.SampleSize) {
  601. PHILIPSCAM_KdPrint (MIN_TRACE, ("***Error**:Format mismatch Width=%d Height=%d image size=%d\n",
  602. pVideoInfoHdrToVerify->bmiHeader.biWidth,
  603. pVideoInfoHdrToVerify->bmiHeader.biHeight,
  604. pVideoInfoHdrToVerify->bmiHeader.biSizeImage));
  605. continue;
  606. }
  607. //
  608. // HOORAY, the format passed all of the tests, so we support it
  609. //
  610. return TRUE;
  611. }
  612. }
  613. //
  614. // The format requested didn't match any of our listed ranges,
  615. // so refuse the connection.
  616. //
  617. return FALSE;
  618. }
  619. //
  620. // hooks for stream SRBs
  621. //
  622. VOID STREAMAPI
  623. PHILIPSCAM_ReceiveDataPacket(
  624. IN PHW_STREAM_REQUEST_BLOCK Srb,
  625. IN PVOID DeviceContext,
  626. IN PBOOLEAN Completed
  627. )
  628. {
  629. // PHILIPSCAM_KdPrint (MAX_TRACE, ("P*_ReceiveDataPacket\n"));
  630. }
  631. VOID STREAMAPI
  632. PHILIPSCAM_ReceiveCtrlPacket(
  633. IN PHW_STREAM_REQUEST_BLOCK Srb,
  634. IN PVOID DeviceContext,
  635. IN PBOOLEAN Completed
  636. )
  637. {
  638. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  639. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("'PHILIPSCAM: Receive Ctrl SRB %x\n", Srb->Command));
  640. *Completed = TRUE;
  641. Srb->Status = STATUS_SUCCESS;
  642. switch (Srb->Command) {
  643. case SRB_PROPOSE_DATA_FORMAT:
  644. PHILIPSCAM_KdPrint(MIN_TRACE, ("'Receiving SRB_PROPOSE_DATA_FORMAT SRB \n"));
  645. if ( !(AdapterVerifyFormat (
  646. (PKS_DATAFORMAT_VIDEOINFOHEADER)Srb->CommandData.OpenFormat,
  647. Srb->StreamObject->StreamNumber))) {
  648. Srb->Status = STATUS_NO_MATCH;
  649. PHILIPSCAM_KdPrint(MIN_TRACE,("SRB_PROPOSE_DATA_FORMAT FAILED\n"));
  650. }
  651. break;
  652. case SRB_SET_DATA_FORMAT:
  653. {
  654. PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat =
  655. (PKS_DATAFORMAT_VIDEOINFOHEADER) Srb->CommandData.OpenFormat;
  656. PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
  657. &pKSDataFormat->VideoInfoHeader;
  658. PHILIPSCAM_KdPrint(MIN_TRACE, ("'SRB_SET_DATA_FORMAT\n"));
  659. if ((AdapterVerifyFormat(pKSDataFormat,Srb->StreamObject->StreamNumber))) {
  660. // if (deviceContext->UsbcamdInterface.USBCAMD_SetVideoFormat(DeviceContext,Srb)) {
  661. // deviceContext->CurrentProperty.Format.lWidth =
  662. // pVideoInfoHdrRequested->bmiHeader.biWidth;
  663. // deviceContext->CurrentProperty.Format.lHeight =
  664. // pVideoInfoHdrRequested->bmiHeader.biHeight;
  665. // }
  666. }else {
  667. Srb->Status = STATUS_NO_MATCH;
  668. PHILIPSCAM_KdPrint(MIN_TRACE,(" SRB_SET_DATA_FORMAT FAILED\n"));
  669. }
  670. }
  671. break;
  672. case SRB_GET_DATA_FORMAT:
  673. PHILIPSCAM_KdPrint(MIN_TRACE, ("' SRB_GET_DATA_FORMAT\n"));
  674. Srb->Status = STATUS_NOT_IMPLEMENTED;
  675. break;
  676. case SRB_SET_STREAM_STATE:
  677. case SRB_GET_STREAM_STATE:
  678. case SRB_GET_STREAM_PROPERTY:
  679. case SRB_SET_STREAM_PROPERTY:
  680. case SRB_INDICATE_MASTER_CLOCK:
  681. default:
  682. *Completed = FALSE; // let USBCAMD handle these control SRBs
  683. }
  684. if (*Completed == TRUE) {
  685. StreamClassStreamNotification(StreamRequestComplete,Srb->StreamObject,Srb);
  686. }
  687. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("P*_ReceiveCtrlPacket\n"));
  688. }
  689. // **
  690. // Describe the camera
  691. //
  692. USBCAMD_DEVICE_DATA PHILIPSCAM_DeviceData = {
  693. 0,
  694. PHILIPSCAM_Initialize,
  695. PHILIPSCAM_UnInitialize,
  696. PHILIPSCAM_ProcessUSBPacket,
  697. PHILIPSCAM_NewFrame,
  698. PHILIPSCAM_ProcessRawVideoFrame,
  699. PHILIPSCAM_StartVideoCapture,
  700. PHILIPSCAM_StopVideoCapture,
  701. PHILIPSCAM_Configure,
  702. PHILIPSCAM_SaveState,
  703. PHILIPSCAM_RestoreState,
  704. PHILIPSCAM_AllocateBandwidth,
  705. PHILIPSCAM_FreeBandwidth
  706. };
  707. /* Function Caller
  708. PHILIPSCAM_Initialize, USBCAMD.c : USBCAMD_ConfigureDevice()
  709. PHILIPSCAM_UnInitialize, USBCAMD.c : USBCAMD_RemoveDevice
  710. PHILIPSCAM_ProcessUSBPacket, iso.c : USBCAMD_TransferComplete()
  711. PHILIPSCAM_NewFrame, iso.c : USBCAMD_TransferComplete()
  712. PHILIPSCAM_ProcessRawVideoFrame, iso.c : USBCAMD_ProcessWorkItem()
  713. PHILIPSCAM_StartVideoCapture, USBCAMD.c : USBCAMD_PrepareChannel()
  714. reset.c USBCAMD_ResetPipes()
  715. PHILIPSCAM_StopVideoCapture, USBCAMD.c : USBCAMD_UnPrepareChannel()
  716. reset.c: USBCAMD_ResetPipes()
  717. PHILIPSCAM_Configure, USBCAMD.c : USBCAMD_SelectConfiguration()
  718. PHILIPSCAM_SaveState,
  719. PHILIPSCAM_RestoreState,
  720. PHILIPSCAM_AllocateBandwidth, <--+
  721. USBCAMD.c : USBCAMD_PrepareChannel() -+ <--+
  722. STREAM.c : AdapterOpenStream() -+ <--+
  723. USBCAMD_AdapterReceivePacket(SRB = SRB_OPEN_STREAM) -+
  724. PHILIPSCAM_FreeBandwidth USBCAMD.c : USBCAMD_UnPrepareChannel()
  725. */
  726. VOID
  727. PHILIPSCAM_AdapterReceivePacket( IN PHW_STREAM_REQUEST_BLOCK Srb ) {
  728. PPHILIPSCAM_DEVICE_CONTEXT deviceContext;
  729. PHW_STREAM_INFORMATION streamInformation =
  730. &(Srb->CommandData.StreamBuffer->StreamInfo);
  731. PHW_STREAM_HEADER streamHeader =
  732. &(Srb->CommandData.StreamBuffer->StreamHeader);
  733. PDEVICE_OBJECT deviceObject;
  734. switch (Srb->Command) {
  735. case SRB_GET_STREAM_INFO:
  736. //
  737. // this is a request for the driver to enumerate requested streams
  738. //
  739. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("P*_AdapterReceivePacket: SRB_GET_STREAM_INFO\n"));
  740. // get our device ext. from USBCAMD.
  741. deviceContext =
  742. USBCAMD_AdapterReceivePacket(Srb, NULL, NULL, FALSE);
  743. //
  744. // we support one stream
  745. //
  746. streamHeader->NumberOfStreams = 1;
  747. streamInformation->StreamFormatsArray =
  748. &PHILIPSCAM_MovingStreamFormats[0];
  749. streamInformation->NumberOfFormatArrayEntries =
  750. Streams[0].NumberOfFormatArrayEntries;
  751. //
  752. // set the property information for the video stream
  753. //
  754. streamHeader->DevicePropertiesArray =
  755. PHILIPSCAM_GetAdapterPropertyTable(&streamHeader->
  756. NumDevPropArrayEntries) ;
  757. // pass to usbcamd to finish the job
  758. deviceContext =
  759. USBCAMD_AdapterReceivePacket(Srb, &PHILIPSCAM_DeviceData, NULL, TRUE);
  760. ASSERT_DEVICE_CONTEXT(deviceContext);
  761. break;
  762. case SRB_GET_DEVICE_PROPERTY:
  763. //
  764. // we handle all the property stuff
  765. //
  766. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("P*_AdapterReceivePacket: SRB_GET_DEVICE_PROPERTY\n"));
  767. deviceContext =
  768. USBCAMD_AdapterReceivePacket(Srb, &PHILIPSCAM_DeviceData,
  769. &deviceObject, FALSE);
  770. ASSERT_DEVICE_CONTEXT(deviceContext);
  771. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("SRB_GET_STREAM_INFO\n"));
  772. PHILIPSCAM_PropertyRequest( FALSE, deviceObject, deviceContext, Srb);
  773. StreamClassDeviceNotification(DeviceRequestComplete,
  774. Srb->HwDeviceExtension,
  775. Srb);
  776. break;
  777. case SRB_SET_DEVICE_PROPERTY:
  778. //
  779. // we handle all the property stuff
  780. //
  781. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("P*_AdapterReceivePacket: SRB_SET_DEVICE_PROPERTY\n"));
  782. deviceContext =
  783. USBCAMD_AdapterReceivePacket(Srb, &PHILIPSCAM_DeviceData,
  784. &deviceObject, FALSE);
  785. ASSERT_DEVICE_CONTEXT(deviceContext);
  786. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("SRB_GET_STREAM_INFO\n"));
  787. PHILIPSCAM_PropertyRequest( TRUE, deviceObject, deviceContext, Srb);
  788. StreamClassDeviceNotification(DeviceRequestComplete,
  789. Srb->HwDeviceExtension,
  790. Srb);
  791. break;
  792. case SRB_OPEN_STREAM: {
  793. PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat =
  794. (PKS_DATAFORMAT_VIDEOINFOHEADER) Srb->CommandData.OpenFormat;
  795. PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
  796. &pKSDataFormat->VideoInfoHeader;
  797. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("P*_AdapterReceivePacket: SRB_OPEN_STREAM\n"));
  798. // pass to usbcamd to finish the job
  799. Srb->StreamObject->ReceiveDataPacket =
  800. (PVOID) PHILIPSCAM_ReceiveDataPacket;
  801. Srb->StreamObject->ReceiveControlPacket =
  802. (PVOID) PHILIPSCAM_ReceiveCtrlPacket;
  803. if (AdapterVerifyFormat(pKSDataFormat,
  804. Srb->StreamObject->StreamNumber)) {
  805. deviceContext =
  806. USBCAMD_AdapterReceivePacket(Srb, &PHILIPSCAM_DeviceData,
  807. NULL, TRUE);
  808. // deviceContext->StreamOpen = TRUE;
  809. }else{
  810. Srb->Status = STATUS_INVALID_PARAMETER;
  811. StreamClassDeviceNotification(DeviceRequestComplete,
  812. Srb->HwDeviceExtension,
  813. Srb);
  814. }
  815. }
  816. break;
  817. case SRB_GET_DATA_INTERSECTION:
  818. //
  819. // Return a format, given a range
  820. //
  821. //deviceContext =
  822. // USBCAMD_AdapterReceivePacket(Srb,
  823. // &PHILIPSCAM_DeviceData,
  824. // &deviceObject,
  825. // FALSE);
  826. PHILIPSCAM_KdPrint (MAX_TRACE, ("P*_AdapterReceivePacket: SRB_GET_DATA_INTERSECTION\n"));
  827. Srb->Status = AdapterFormatFromRange(Srb);
  828. StreamClassDeviceNotification(DeviceRequestComplete,
  829. Srb->HwDeviceExtension,
  830. Srb);
  831. break;
  832. case SRB_CLOSE_STREAM: // close the specified stream
  833. case SRB_CHANGE_POWER_STATE: // change power state
  834. case SRB_SET_STREAM_RATE: // set the rate at which the stream should run
  835. default:
  836. //
  837. // let usbcamd handle it
  838. //
  839. PHILIPSCAM_KdPrint (ULTRA_TRACE, ("P*_AdapterReceivePacket: SRB_HANDLED BY USBCAMD\n"));
  840. deviceContext =
  841. USBCAMD_AdapterReceivePacket(Srb,
  842. &PHILIPSCAM_DeviceData, NULL, TRUE);
  843. ASSERT_DEVICE_CONTEXT(deviceContext);
  844. }
  845. }
  846. /*
  847. ** DriverEntry()
  848. **
  849. ** This routine is called when the mini driver is first loaded. The driver
  850. ** should then call the StreamClassRegisterAdapter function to register with
  851. ** the stream class driver
  852. **
  853. ** Arguments:
  854. **
  855. ** Context1: The context arguments are private plug and play structures
  856. ** used by the stream class driver to find the resources for this
  857. ** adapter
  858. ** Context2:
  859. **
  860. ** Returns:
  861. **
  862. ** This routine returns an NT_STATUS value indicating the result of the
  863. ** registration attempt. If a value other than STATUS_SUCCESS is returned, the
  864. ** minidriver will be unloaded.
  865. **
  866. ** Side Effects: none
  867. */
  868. ULONG
  869. DriverEntry(
  870. PVOID Context1,
  871. PVOID Context2 ){
  872. PHILIPSCAM_KdPrint (MAX_TRACE, ("'Driver Entry\n"));
  873. return USBCAMD_DriverEntry(Context1,
  874. Context2,
  875. sizeof(PHILIPSCAM_DEVICE_CONTEXT),
  876. sizeof(PHILIPSCAM_FRAME_CONTEXT),
  877. PHILIPSCAM_AdapterReceivePacket);
  878. }
  879. /*
  880. ** PHILIPSCAM_Initialize()
  881. **
  882. ** On entry the device has been configured and the initial alt
  883. ** interface selected -- this is where we may send additional
  884. ** vendor commands to enable the device.
  885. **
  886. ** Philips actions:
  887. ** 1. Find out what type of camera is available, VGA or medium-Res
  888. ** This has consequences for the available streamformats.
  889. **
  890. ** Arguments:
  891. **
  892. ** BusDeviceObject - pdo associated with this device
  893. **
  894. ** DeviceContext - driver specific context
  895. **
  896. ** Returns:
  897. **
  898. ** NTSTATUS code
  899. **
  900. ** Side Effects: none
  901. */
  902. NTSTATUS
  903. PHILIPSCAM_Initialize( PDEVICE_OBJECT BusDeviceObject,
  904. PVOID DeviceContext ) {
  905. PPHILIPSCAM_DEVICE_CONTEXT deviceContext=DeviceContext;
  906. NTSTATUS ntStatus = STATUS_SUCCESS;
  907. ASSERT_DEVICE_CONTEXT(deviceContext);
  908. //
  909. // perform any hardware specific
  910. // initialization
  911. //
  912. ntStatus = PHILIPSCAM_GetSensorType(deviceContext);
  913. if (NT_SUCCESS(ntStatus)) {
  914. ntStatus = PHILIPSCAM_GetReleaseNumber(deviceContext);
  915. }
  916. deviceContext->EmptyPacketCounter = 0; // (Initialize this counter)
  917. if (NT_SUCCESS(ntStatus)) {
  918. ntStatus = PHILIPSCAM_InitPrpObj(deviceContext);
  919. }
  920. PHILIPSCAM_KdPrint (MIN_TRACE, ("'X P*_Initialize 0x%x\n", ntStatus));
  921. ILOGENTRY("inHW", 0, 0, ntStatus);
  922. return ntStatus;
  923. }
  924. /*
  925. ** PHILIPSCAM_UnInitialize()
  926. **
  927. ** Assume the device hardware is gone -- all that needs to be done is to
  928. ** free any allocated resources (like memory).
  929. **
  930. ** Arguments:
  931. **
  932. ** BusDeviceObject - pdo associated with this device
  933. **
  934. ** DeviceContext - driver specific context
  935. **
  936. ** Returns:
  937. **
  938. ** NTSTATUS code
  939. **
  940. ** Side Effects: none
  941. */
  942. NTSTATUS
  943. PHILIPSCAM_UnInitialize( PDEVICE_OBJECT BusDeviceObject,
  944. PVOID DeviceContext ) {
  945. PPHILIPSCAM_DEVICE_CONTEXT deviceContext;
  946. NTSTATUS ntStatus = STATUS_SUCCESS;
  947. deviceContext = DeviceContext;
  948. ASSERT_DEVICE_CONTEXT(deviceContext);
  949. if ( deviceContext->Interface) {
  950. ExFreePool(deviceContext->Interface);
  951. deviceContext->Interface = NULL;
  952. }
  953. PHILIPSCAM_KdPrint (MAX_TRACE, ("'P*_UnInitialize 0x%x\n", ntStatus));
  954. return ntStatus;
  955. }
  956. /*
  957. ** PHILIPSCAM_Configure()
  958. **
  959. ** Configure the iso streaming Interface:
  960. **
  961. ** Called just before the device is configured, this is where we tell
  962. ** usbcamd which interface and alternate setting to use for the idle state.
  963. **
  964. ** NOTE: The assumption here is that the device will have a single interface
  965. ** with multiple alt settings and each alt setting has the same number of
  966. ** pipes.
  967. **
  968. ** Arguments:
  969. **
  970. ** BusDeviceObject - device object created by the hub whe can submit
  971. ** urbs to our device through this deviceObject
  972. **
  973. ** DeviceContext - minidriver device context
  974. **
  975. ** Interface - USBD interface structure initialized with the proper values
  976. ** for select_configuration. This Interface structure corresponds
  977. ** a single iso interafce on the device. This is the drivers
  978. ** chance to pick a particular alternate setting and pipe
  979. ** parameters.
  980. **
  981. **
  982. ** ConfigurationDescriptor - USB configuration Descriptor for
  983. ** this device.
  984. **
  985. ** Returns:
  986. **
  987. ** NTSTATUS code
  988. **
  989. ** Side Effects: none
  990. */
  991. NTSTATUS
  992. PHILIPSCAM_Configure(IN PDEVICE_OBJECT BusDeviceObject,
  993. IN PVOID DeviceContext,
  994. IN OUT PUSBD_INTERFACE_INFORMATION Interface,
  995. IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
  996. IN OUT PLONG DataPipeIndex,
  997. IN OUT PLONG SyncPipeIndex ) {
  998. PPHILIPSCAM_DEVICE_CONTEXT deviceContext;
  999. NTSTATUS ntStatus = STATUS_SUCCESS;
  1000. deviceContext = DeviceContext;
  1001. deviceContext->Sig = PHILIPSCAM_DEVICE_SIG;
  1002. //
  1003. // initilialize any other context stuff
  1004. //
  1005. PHILIPSCAM_KdPrint (MAX_TRACE, ("'E P*_Configure \n"));
  1006. if ( Interface == NULL) {
  1007. //
  1008. // this is a signal from usbcamd that I need to free my previousely
  1009. // allocated space for interface descriptor due to error conditions
  1010. // during IRP_MN_START_DEVICE processing and driver will be unloaded soon.
  1011. //
  1012. if (deviceContext->Interface) {
  1013. ExFreePool(deviceContext->Interface);
  1014. deviceContext->Interface = NULL;
  1015. }
  1016. return ntStatus;
  1017. }
  1018. deviceContext->Interface = ExAllocatePool(NonPagedPool,
  1019. Interface->Length);
  1020. *DataPipeIndex = 1;
  1021. *SyncPipeIndex = -1; // no sync pipe
  1022. if (deviceContext->Interface) {
  1023. Interface->AlternateSetting = ALT_INTERFACE_0 ;
  1024. // This interface has two pipes,
  1025. // initialize input parameters to USBD for both pipes.
  1026. // The MaximumTransferSize is the size of the largest
  1027. // buffer we want to submit for a single iso urb
  1028. // request.
  1029. //
  1030. Interface->Pipes[PHILIPSCAM_SYNC_PIPE].MaximumTransferSize =
  1031. USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; // = PAGE SIZE ??
  1032. Interface->Pipes[PHILIPSCAM_DATA_PIPE].MaximumTransferSize =
  1033. // 1024*32; // 32k transfer per urb ??
  1034. 1024*198; // CIF: 352x288x16/8
  1035. RtlCopyMemory(deviceContext->Interface,
  1036. Interface,
  1037. Interface->Length);
  1038. PHILIPSCAM_KdPrint (MAX_TRACE, ("'size of interface request = %d\n",
  1039. Interface->Length));
  1040. }else{
  1041. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  1042. }
  1043. //
  1044. // return interface number and alternate setting
  1045. //
  1046. PHILIPSCAM_KdPrint (MIN_TRACE, ("'X P*_Configure 0x%x\n", ntStatus));
  1047. return ntStatus;
  1048. }
  1049. /*
  1050. ** PHILIPSCAM_StartVideoCapture()
  1051. **
  1052. ** Arguments:
  1053. **
  1054. ** BusDeviceObject - device object created by the hub we can submit
  1055. ** urbs to our device through this deviceObject
  1056. **
  1057. ** DeviceContext - minidriver device context
  1058. **
  1059. ** Returns:
  1060. **
  1061. ** NTSTATUS code
  1062. **
  1063. ** Side Effects: none
  1064. */
  1065. NTSTATUS
  1066. PHILIPSCAM_StartVideoCapture( IN PDEVICE_OBJECT BusDeviceObject,
  1067. IN PVOID DeviceContext ) {
  1068. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1069. NTSTATUS ntStatus= STATUS_SUCCESS;
  1070. ASSERT_DEVICE_CONTEXT(deviceContext);
  1071. //
  1072. // This is where we select the interface we need and send
  1073. // commands to start capturing
  1074. //
  1075. PHILIPSCAM_KdPrint (MAX_TRACE, ("'E P*_StartVideoCapture \n"));
  1076. PHILIPSCAM_KdPrint (MAX_TRACE, ("'X P*_StartVideocapture 0x%x\n", ntStatus));
  1077. return ntStatus;
  1078. }
  1079. /*
  1080. ** PHILIPSCAM_AllocateBandwidth()
  1081. **
  1082. ** Called just before the iso video capture stream is
  1083. ** started, here is where we select the appropriate
  1084. ** alternate interface and set up the device to stream.
  1085. **
  1086. ** Called in connection with the stream class RUN command
  1087. **
  1088. ** Arguments:
  1089. **
  1090. ** BusDeviceObject - device object created by the hub we can submit
  1091. ** urbs to our device through this deviceObject
  1092. **
  1093. ** DeviceContext - minidriver device context
  1094. **
  1095. ** RawFrameLength - pointer to be filled in with size of buffer needed to
  1096. ** receive the raw frame data from the packet stream.
  1097. **
  1098. ** Format - pointer to PKS_DATAFORMAT_VIDEOINFOHEADER associated with this
  1099. ** stream.
  1100. **
  1101. ** Returns:
  1102. **
  1103. ** NTSTATUS code
  1104. **
  1105. ** Side Effects: none
  1106. */
  1107. NTSTATUS
  1108. PHILIPSCAM_AllocateBandwidth( IN PDEVICE_OBJECT BusDeviceObject,
  1109. IN PVOID DeviceContext,
  1110. OUT PULONG RawFrameLength,
  1111. IN PVOID Format ){
  1112. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1113. NTSTATUS ntStatus = STATUS_SUCCESS;
  1114. PKS_DATAFORMAT_VIDEOINFOHEADER pdataFormatHeader;
  1115. PKS_BITMAPINFOHEADER bmInfoHeader;
  1116. LONGLONG llDefaultFramePeriod ;
  1117. USHORT usReqFrRate;
  1118. ASSERT_DEVICE_CONTEXT(deviceContext);
  1119. PHILIPSCAM_KdPrint (MAX_TRACE, ("'E P*_AllocateBandwidth \n"));
  1120. //
  1121. // This is where we select the interface we need and send
  1122. // commands to start capturing
  1123. //
  1124. *RawFrameLength = 0;
  1125. pdataFormatHeader = Format;
  1126. bmInfoHeader = &pdataFormatHeader->VideoInfoHeader.bmiHeader;
  1127. // deviceContext->pSelectedStreamFormat = &pdataFormatHeader->DataFormat; // removed RMR
  1128. RtlCopyMemory (&deviceContext->CamStatus.PictureSubFormat, // added RMR
  1129. &pdataFormatHeader->DataFormat.SubFormat,
  1130. sizeof (GUID));
  1131. PHILIPSCAM_KdPrint (MIN_TRACE,
  1132. ("'req.format %d x %d\n", bmInfoHeader->biWidth,
  1133. bmInfoHeader->biHeight));
  1134. switch (bmInfoHeader->biWidth) {
  1135. case QQCIF_X:
  1136. deviceContext->CamStatus.PictureFormat = FORMATQQCIF;
  1137. *RawFrameLength = (SQCIF_X * SQCIF_Y * 12)/8;
  1138. break;
  1139. case SQCIF_X:
  1140. deviceContext->CamStatus.PictureFormat = FORMATSQCIF;
  1141. *RawFrameLength = (SQCIF_X * SQCIF_Y * 12)/8;
  1142. break;
  1143. case QCIF_X:
  1144. deviceContext->CamStatus.PictureFormat = FORMATQCIF;
  1145. *RawFrameLength = (QCIF_X * QCIF_Y * 12)/8;
  1146. break;
  1147. case CIF_X:
  1148. deviceContext->CamStatus.PictureFormat = FORMATCIF;
  1149. *RawFrameLength = (CIF_X * CIF_Y * 12)/8;
  1150. break;
  1151. case SQSIF_X:
  1152. deviceContext->CamStatus.PictureFormat = FORMATSQSIF;
  1153. *RawFrameLength = (SQCIF_X * SQCIF_Y * 12)/8;
  1154. break;
  1155. case QSIF_X:
  1156. deviceContext->CamStatus.PictureFormat = FORMATQSIF;
  1157. *RawFrameLength = (QCIF_X * QCIF_Y * 12)/8;
  1158. break;
  1159. case SSIF_X:
  1160. if (bmInfoHeader->biHeight == SSIF_Y){
  1161. deviceContext->CamStatus.PictureFormat = FORMATSSIF;
  1162. }else{
  1163. deviceContext->CamStatus.PictureFormat = FORMATSCIF;
  1164. }
  1165. *RawFrameLength = (CIF_X * CIF_Y * 12)/8;
  1166. break;
  1167. case SIF_X:
  1168. deviceContext->CamStatus.PictureFormat = FORMATSIF;
  1169. *RawFrameLength = (CIF_X * CIF_Y * 12)/8;
  1170. break;
  1171. default:
  1172. deviceContext->CamStatus.PictureFormat = FORMATQCIF;
  1173. *RawFrameLength = (QCIF_X * QCIF_Y * 12)/8;
  1174. }
  1175. llDefaultFramePeriod = pdataFormatHeader->VideoInfoHeader.AvgTimePerFrame; // [100nS]
  1176. usReqFrRate = MapFrPeriodFrRate(llDefaultFramePeriod);
  1177. deviceContext->CamStatus.PictureFrameRate = usReqFrRate;
  1178. PHILIPSCAM_KdPrint (MIN_TRACE,("Req.frperiod: %d us \n",
  1179. llDefaultFramePeriod / 10));
  1180. PHILIPSCAM_KdPrint (MIN_TRACE,("Req.frperiod index: %d = %s fps\n",
  1181. usReqFrRate, FRString(usReqFrRate)));
  1182. // Define framerate based on available USB=bandwidth
  1183. // if not suff.BW, frame rate is decreased.
  1184. ntStatus = PHILIPSCAM_SetFrRate_AltInterface(deviceContext);
  1185. // Send from here the format/framerate to the camera hardware:
  1186. if (NT_SUCCESS(ntStatus)) {
  1187. ntStatus = PHILIPSCAM_SetFormatFramerate( deviceContext );
  1188. }
  1189. if (NT_SUCCESS(ntStatus)) {
  1190. ntStatus = PHILIPSCAM_StartCodec( deviceContext );
  1191. }
  1192. if (NT_SUCCESS(ntStatus)) {
  1193. deviceContext->FrameLength = *RawFrameLength;
  1194. }
  1195. PHILIPSCAM_KdPrint (MAX_TRACE, ("'X P*_AllocateBandwidth 0x%x\n", ntStatus));
  1196. return ntStatus;
  1197. }
  1198. /*
  1199. ** PHILIPSCAM_FreeBandwidth()
  1200. **
  1201. ** Called after the iso video stream is stopped, this is where we
  1202. ** select an alternate interface that uses no bandwidth.
  1203. **
  1204. ** Arguments:
  1205. **
  1206. ** BusDeviceObject - device object created by the hub we can submit
  1207. ** urbs to our device through this deviceObject
  1208. **
  1209. ** DeviceContext - minidriver device context
  1210. **
  1211. ** Returns:
  1212. **
  1213. ** NTSTATUS code
  1214. **
  1215. ** Side Effects: none
  1216. */
  1217. NTSTATUS
  1218. PHILIPSCAM_FreeBandwidth(
  1219. PDEVICE_OBJECT BusDeviceObject,
  1220. PVOID DeviceContext ){
  1221. NTSTATUS ntStatus;
  1222. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1223. // turn off streaming on the device
  1224. ASSERT_DEVICE_CONTEXT(deviceContext);
  1225. ntStatus = PHILIPSCAM_StopCodec(deviceContext);
  1226. deviceContext->Interface->AlternateSetting = ALT_INTERFACE_0 ;
  1227. ntStatus = USBCAMD_SelectAlternateInterface(
  1228. deviceContext,
  1229. deviceContext->Interface);
  1230. PHILIPSCAM_KdPrint (MAX_TRACE, ("'X P*_FreeBandWidth 0x%x\n", ntStatus));
  1231. return ntStatus;
  1232. }
  1233. /*
  1234. ** PHILIPSCAM_StopVideoCapture()
  1235. **
  1236. ** Called after the iso video stream is stopped, this is where we
  1237. ** select an alternate interface that uses no bandwidth.
  1238. **
  1239. ** Arguments:
  1240. **
  1241. ** BusDeviceObject - device object created by the hub we can submit
  1242. ** urbs to our device through this deviceObject
  1243. **
  1244. ** DeviceContext - minidriver device context
  1245. **
  1246. ** Returns:
  1247. **
  1248. ** NTSTATUS code
  1249. **
  1250. ** Side Effects: none
  1251. */
  1252. NTSTATUS
  1253. PHILIPSCAM_StopVideoCapture( PDEVICE_OBJECT BusDeviceObject,
  1254. PVOID DeviceContext ) {
  1255. NTSTATUS ntStatus = STATUS_SUCCESS;
  1256. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1257. // turn off streaming on the device
  1258. ASSERT_DEVICE_CONTEXT(deviceContext);
  1259. PHILIPSCAM_KdPrint (MAX_TRACE, ("'X P*_StopVideoCapture 0x%x\n", ntStatus));
  1260. return ntStatus;
  1261. }
  1262. /*
  1263. ** PHILIPSCAM_NewFrame()
  1264. **
  1265. ** called at DPC level to allow driver to initialize a new video frame
  1266. ** context structure
  1267. **
  1268. ** Arguments:
  1269. **
  1270. ** DeviceContext - minidriver device context
  1271. **
  1272. ** FrameContext - frame context to be initialized
  1273. **
  1274. ** Returns:
  1275. **
  1276. ** NTSTATUS code
  1277. **
  1278. ** Side Effects: none
  1279. */
  1280. VOID
  1281. PHILIPSCAM_NewFrame( PVOID DeviceContext,
  1282. PVOID FrameContext ){
  1283. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1284. PPHILIPSCAM_FRAME_CONTEXT pFrameContext = FrameContext;
  1285. pFrameContext->USBByteCounter = 0;
  1286. // PHILIPSCAM_KdPrint (MAX_TRACE, ("'P*_NewFrame\n"));
  1287. ASSERT_DEVICE_CONTEXT(deviceContext);
  1288. }
  1289. /*
  1290. ** PHILIPSCAM_ProcessUSBPacket()
  1291. **
  1292. ** called at DPC level to allow driver to determine if this packet is part
  1293. ** of the current video frame or a new video frame.
  1294. **
  1295. ** This function should complete as quickly as possible, any image processing
  1296. ** should be deferred to the ProcessRawFrame routine.
  1297. **
  1298. ** Arguments:
  1299. **
  1300. ** BusDeviceObject - device object created by the hub we can submit
  1301. ** urbs to our device through this deviceObject
  1302. **
  1303. ** DeviceContext - minidriver device context
  1304. **
  1305. ** CurrentFrameContext - some context for this particular frame
  1306. **
  1307. ** SyncPacket - iso packet descriptor from sync pipe, not used if the interface
  1308. ** has only one pipe.
  1309. **
  1310. ** SyncBuffer - pointer to data for the sync packet
  1311. **
  1312. ** DataPacket - iso packet descriptor from data pipe
  1313. **
  1314. ** DataBuffer - pointer to data for the data packet
  1315. **
  1316. ** FrameComplete - indicates to usbcamd that this is the first data packet
  1317. ** for a new video frame
  1318. **
  1319. ** Returns:
  1320. **
  1321. ** number of bytes that should be copied in to the rawFrameBuffer of FrameBuffer.
  1322. **
  1323. ** Side Effects: none
  1324. */
  1325. ULONG
  1326. PHILIPSCAM_ProcessUSBPacket(
  1327. PDEVICE_OBJECT BusDeviceObject,
  1328. PVOID DeviceContext,
  1329. PVOID CurrentFrameContext,
  1330. PUSBD_ISO_PACKET_DESCRIPTOR SyncPacket,
  1331. PVOID SyncBuffer,
  1332. PUSBD_ISO_PACKET_DESCRIPTOR DataPacket,
  1333. PVOID DataBuffer,
  1334. PBOOLEAN FrameComplete,
  1335. PBOOLEAN NextFrameIsStill ) {
  1336. static BOOLEAN EndOfFrameFound = FALSE;
  1337. static BOOLEAN StartOfFrameFound = FALSE;
  1338. static ULONG previous_packetSize= 0;
  1339. static ULONG ActualBytesReceived = 0 ;
  1340. #if DBG
  1341. #if DBGHARD
  1342. typedef struct {
  1343. ULONG PSize;
  1344. ULONG DeltaT;
  1345. } PACKETINFO;
  1346. #define MAXI 2048
  1347. static ULONG ulRcvdFrameSize[MAXI];
  1348. static ULONG ulPHistory[MAXI][2];
  1349. static ULONG ulPcktCntr = 0;
  1350. static ULONG ulFrSCntr = 0;
  1351. static LARGE_INTEGER liCurTicks, liPrevTicks;
  1352. static ULONG ElapsedTicks;
  1353. static ULONG TickPeriod ;
  1354. #endif
  1355. #endif
  1356. PUSBD_ISO_PACKET_DESCRIPTOR dataPacket = DataPacket;
  1357. PPHILIPSCAM_FRAME_CONTEXT pFrameContext = CurrentFrameContext;
  1358. ULONG packetSize;
  1359. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1360. *NextFrameIsStill = FALSE;
  1361. // PHILIPSCAM_KdPrint (MAX_TRACE, ("'E P*_ProcessPacket\n"));
  1362. ASSERT_DEVICE_CONTEXT(deviceContext);
  1363. packetSize = dataPacket->Length ;
  1364. // Synchronization:
  1365. // ----------------
  1366. if (packetSize != previous_packetSize){
  1367. //end or start of frame
  1368. if (packetSize < previous_packetSize) {
  1369. EndOfFrameFound = TRUE;
  1370. }else{
  1371. StartOfFrameFound = TRUE;
  1372. }
  1373. }
  1374. if ( StartOfFrameFound == TRUE ){
  1375. *FrameComplete = TRUE;
  1376. EndOfFrameFound = FALSE;
  1377. StartOfFrameFound = FALSE;
  1378. #if DBG
  1379. #if DBGHARD
  1380. ulRcvdFrameSize[ulFrSCntr] = ActualBytesReceived;
  1381. if (ulFrSCntr==MAXI) ulFrSCntr = 0;
  1382. #endif
  1383. #endif
  1384. if (pFrameContext)
  1385. pFrameContext->USBByteCounter = ActualBytesReceived;
  1386. ActualBytesReceived = 0;
  1387. }
  1388. ActualBytesReceived += packetSize;
  1389. #if DBG
  1390. #if DBGHARD
  1391. // KeQueryTickCount(&liCurTicks);
  1392. ElapsedTicks = (ULONG)( liCurTicks.QuadPart - liPrevTicks.QuadPart);
  1393. ulPHistory[ulPcktCntr][0] = packetSize;
  1394. ulPHistory[ulPcktCntr][1] = ElapsedTicks ;
  1395. liPrevTicks.QuadPart = liCurTicks.QuadPart;
  1396. ulPcktCntr++;
  1397. if (ulPcktCntr==MAXI) ulPcktCntr = 0;
  1398. #endif
  1399. #endif
  1400. // Added to improve robustness
  1401. if ( ActualBytesReceived > deviceContext->FrameLength){
  1402. *FrameComplete = TRUE;
  1403. ActualBytesReceived = 0;
  1404. }
  1405. previous_packetSize = packetSize;
  1406. return packetSize;
  1407. }
  1408. /*
  1409. ** PHILIPSCAM_ProcessRawVideoFrame()
  1410. **
  1411. ** Called at PASSIVE level to allow driver to perform any decoding of the
  1412. ** raw video frame.
  1413. **
  1414. ** This routine will convert the packetized data in to the fromat
  1415. ** the CODEC expects, ie y,u,v
  1416. **
  1417. ** data is always of the form 256y 64u 64v (384 byte chunks) regardless of USB
  1418. ** packet size.
  1419. **
  1420. **
  1421. ** Arguments:
  1422. **
  1423. ** DeviceContext - driver context
  1424. **
  1425. ** FrameContext - driver context for this frame
  1426. **
  1427. ** FrameBuffer - pointer to the buffer that should receive the final
  1428. ** processed video frame.
  1429. **
  1430. ** FrameLength - length of the Frame buffer (from the original read
  1431. ** request)
  1432. **
  1433. ** RawFrameBuffer - pointer to buffer containing the received USB packets
  1434. **
  1435. ** RawFrameLength - length of the raw frame.
  1436. **
  1437. ** NumberOfPackets - number of USB packets received in to the RawFrameBuffer
  1438. **
  1439. ** BytesReturned - pointer to value to return for number of bytes read.
  1440. **
  1441. ** Returns:
  1442. **
  1443. ** NT status completion code for the read irp
  1444. **
  1445. ** Side Effects: none
  1446. */
  1447. NTSTATUS
  1448. PHILIPSCAM_ProcessRawVideoFrame( PDEVICE_OBJECT BusDeviceObject,
  1449. PVOID DeviceContext,
  1450. PVOID FrameContext,
  1451. PVOID FrameBuffer,
  1452. ULONG FrameLength,
  1453. PVOID RawFrameBuffer,
  1454. ULONG RawFrameLength,
  1455. ULONG NumberOfPackets,
  1456. PULONG BytesReturned ) {
  1457. NTSTATUS ntStatus = STATUS_SUCCESS;
  1458. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1459. PPHILIPSCAM_FRAME_CONTEXT frameContext = FrameContext;
  1460. ULONG rawDataLength, processedDataLength;
  1461. PUCHAR frameBuffer = FrameBuffer;
  1462. PUCHAR rawFrameBuffer = RawFrameBuffer;
  1463. ULONG rawFrameLength = RawFrameLength;
  1464. ULONG frameLength = FrameLength;
  1465. ULONG ExpectedNumberOfBytes;
  1466. //TEST_TRAP();
  1467. ASSERT_DEVICE_CONTEXT(deviceContext);
  1468. switch (deviceContext->CamStatus.PictureFormat){
  1469. case FORMATCIF:
  1470. if ( deviceContext->CamStatus.PictureCompressing == COMPRESSION0 ){
  1471. ExpectedNumberOfBytes = CIF_X * CIF_Y * 3/2 ;
  1472. }else{
  1473. ExpectedNumberOfBytes = CIF_X * CIF_Y / 2 ;
  1474. }
  1475. break;
  1476. case FORMATQCIF:
  1477. ExpectedNumberOfBytes = QCIF_X * QCIF_Y * 3/2 ;
  1478. break;
  1479. case FORMATSQCIF:
  1480. ExpectedNumberOfBytes = SQCIF_X * SQCIF_Y * 3/2 ;
  1481. break;
  1482. case FORMATQQCIF:
  1483. ExpectedNumberOfBytes = SQCIF_X * SQCIF_Y * 3/2 ;
  1484. break;
  1485. case FORMATVGA:
  1486. ExpectedNumberOfBytes = VGA_X * VGA_Y * 3/2 ;
  1487. break;
  1488. case FORMATSIF:
  1489. if ( deviceContext->CamStatus.PictureCompressing == COMPRESSION0 ){
  1490. ExpectedNumberOfBytes = CIF_X * CIF_Y * 3/2 ;
  1491. }else{
  1492. ExpectedNumberOfBytes = CIF_X * CIF_Y / 2 ;
  1493. }
  1494. break;
  1495. case FORMATSSIF:
  1496. if ( deviceContext->CamStatus.PictureCompressing == COMPRESSION0 ){
  1497. ExpectedNumberOfBytes = CIF_X * CIF_Y * 3/2 ;
  1498. }else{
  1499. ExpectedNumberOfBytes = CIF_X * CIF_Y / 2 ;
  1500. }
  1501. break;
  1502. case FORMATSCIF:
  1503. if ( deviceContext->CamStatus.PictureCompressing == COMPRESSION0 ){
  1504. ExpectedNumberOfBytes = CIF_X * CIF_Y * 3/2 ;
  1505. }else{
  1506. ExpectedNumberOfBytes = CIF_X * CIF_Y / 2 ;
  1507. }
  1508. break;
  1509. case FORMATQSIF:
  1510. ExpectedNumberOfBytes = QCIF_X * QCIF_Y * 3/2 ;
  1511. break;
  1512. case FORMATSQSIF:
  1513. ExpectedNumberOfBytes = SQCIF_X * SQCIF_Y * 3/2 ;
  1514. break;
  1515. default:
  1516. ExpectedNumberOfBytes = 0;
  1517. }
  1518. if (ExpectedNumberOfBytes == frameContext->USBByteCounter ) {
  1519. ntStatus = PHILIPSCAM_DecodeUsbData(deviceContext,
  1520. frameBuffer,
  1521. frameLength,
  1522. rawFrameBuffer,
  1523. rawFrameLength);
  1524. *BytesReturned = frameLength ;
  1525. }else{
  1526. PHILIPSCAM_KdPrint (MIN_TRACE, ("Actual (%d) < Expected (%d) \n",
  1527. frameContext->USBByteCounter,ExpectedNumberOfBytes));
  1528. // Green screen complaints bug fix : At the moment USBCAMD delivers a frame for
  1529. // processing, we check whether the size of that frame is correct.
  1530. // If not we return to USBCAMD a framelength to be copied of zero and we won't
  1531. // process the frame.
  1532. // The workaround is to let USBCAMD copy the buffer with the actual buffer length
  1533. // and not to process the frame. Apparantly, returning a bufferlength zero has as
  1534. // consequence that USB packets gets lost.
  1535. // This causes subsequent frames to be incorrect, returning again bufferlength
  1536. // zero. And so on. Not processing buffers has as consequence that the renderer
  1537. // sees empty buffers resulting in a green screen.
  1538. // Sometimes, if this happens during streaming, old buffers are being rerendered.
  1539. *BytesReturned = 0 ;
  1540. // 2001/01/29: This workaround was causing the first few frames
  1541. // captured to remain uninitialized due to insufficient framelength.
  1542. // Returning 0 to indicate a dropped frame is the correct behavior.
  1543. //*BytesReturned = frameLength ;
  1544. }
  1545. return ntStatus;
  1546. }
  1547. /*
  1548. ** PHILIPSCAM_PropertyRequest()
  1549. **
  1550. ** Arguments:
  1551. **
  1552. ** DeviceContext - driver context
  1553. **
  1554. ** Returns:
  1555. **
  1556. ** NT status completion code for the read irp
  1557. **
  1558. ** Side Effects: none
  1559. */
  1560. NTSTATUS
  1561. PHILIPSCAM_PropertyRequest( BOOLEAN SetProperty,
  1562. PDEVICE_OBJECT BusDeviceObject,
  1563. PVOID DeviceContext,
  1564. PVOID PropertyContext ) {
  1565. NTSTATUS ntStatus = STATUS_SUCCESS;
  1566. PHW_STREAM_REQUEST_BLOCK srb = (PHW_STREAM_REQUEST_BLOCK)PropertyContext;
  1567. PSTREAM_PROPERTY_DESCRIPTOR propertyDescriptor;
  1568. propertyDescriptor = srb->CommandData.PropertyInfo;
  1569. //
  1570. // identify the property to set
  1571. //
  1572. PHILIPSCAM_KdPrint (MAX_TRACE, ("'E P*_PropertyRequest\n"));
  1573. if (IsEqualGUID(&PROPSETID_VIDCAP_VIDEOPROCAMP, &propertyDescriptor->Property->Set))
  1574. if (SetProperty)
  1575. ntStatus = PHILIPSCAM_SetCameraProperty(DeviceContext, srb);
  1576. else
  1577. ntStatus = PHILIPSCAM_GetCameraProperty(DeviceContext, srb);
  1578. else if (IsEqualGUID(&PROPSETID_PHILIPS_CUSTOM_PROP, &propertyDescriptor->Property->Set))
  1579. if (SetProperty)
  1580. ntStatus = PHILIPSCAM_SetCustomProperty(DeviceContext, srb);
  1581. else
  1582. ntStatus = PHILIPSCAM_GetCustomProperty(DeviceContext, srb);
  1583. else if (IsEqualGUID(&PROPSETID_PHILIPS_FACTORY_PROP, &propertyDescriptor->Property->Set))
  1584. if (SetProperty)
  1585. ntStatus = PHILIPSCAM_SetFactoryProperty(DeviceContext, srb);
  1586. else
  1587. ntStatus = PHILIPSCAM_GetFactoryProperty(DeviceContext, srb);
  1588. else if (IsEqualGUID(&PROPSETID_VIDCAP_VIDEOCONTROL, &propertyDescriptor->Property->Set))
  1589. {
  1590. if (SetProperty)
  1591. ntStatus = PHILIPSCAM_SetVideoControlProperty(DeviceContext, srb);
  1592. else
  1593. ntStatus = PHILIPSCAM_GetVideoControlProperty(DeviceContext, srb);
  1594. }
  1595. else
  1596. ntStatus = STATUS_NOT_SUPPORTED;
  1597. PHILIPSCAM_KdPrint (MAX_TRACE, ("'X P*_PropertyRequest 0x%x\n",ntStatus));
  1598. return ntStatus;
  1599. }
  1600. /*
  1601. ** PHILIPSCAM_SaveState()
  1602. **
  1603. ** Arguments:
  1604. **
  1605. ** Returns:
  1606. **
  1607. ** Side Effects: none
  1608. */
  1609. NTSTATUS
  1610. PHILIPSCAM_SaveState( PDEVICE_OBJECT BusDeviceObject,
  1611. PVOID DeviceContext ) {
  1612. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1613. PHILIPSCAM_KdPrint (MAX_TRACE, ("'P*_SaveState\n"));
  1614. return STATUS_SUCCESS;
  1615. }
  1616. /*
  1617. ** PHILIPSCAM_RestoreState()
  1618. **
  1619. ** Arguments:
  1620. **
  1621. ** Returns:
  1622. **
  1623. ** Side Effects: none
  1624. */
  1625. NTSTATUS
  1626. PHILIPSCAM_RestoreState( PDEVICE_OBJECT BusDeviceObject,
  1627. PVOID DeviceContext ) {
  1628. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1629. PHILIPSCAM_KdPrint (MAX_TRACE, ("'RestoreState\n"));
  1630. return STATUS_SUCCESS;
  1631. }
  1632. /*
  1633. ** PHILIPSCAM_ReadRegistry()
  1634. **
  1635. ** Arguments:
  1636. **
  1637. ** Returns:
  1638. **
  1639. ** Side Effects: none
  1640. */
  1641. NTSTATUS
  1642. PHILIPSCAM_ReadRegistry( PDEVICE_OBJECT BusDeviceObject,
  1643. PVOID DeviceContext ) {
  1644. PPHILIPSCAM_DEVICE_CONTEXT deviceContext = DeviceContext;
  1645. NTSTATUS ntStatus=STATUS_SUCCESS;
  1646. HANDLE handle;
  1647. return ntStatus;
  1648. }
  1649. USHORT
  1650. MapFrPeriodFrRate(LONGLONG llFramePeriod)
  1651. {
  1652. USHORT FrameRate;
  1653. if (llFramePeriod <= 420000 ){ // 41.6 rounded to 42 ms
  1654. FrameRate = FRRATE24;
  1655. }else if (llFramePeriod <= 510000 ){ // 50.0 rounded to 51 ma
  1656. FrameRate = FRRATE20;
  1657. }else if (llFramePeriod <= 670000 ){ // 66.6 rounded to 67 ms
  1658. FrameRate = FRRATE15;
  1659. }else if (llFramePeriod <= 840000 ){ // 83.3 rounded to 84 ms
  1660. FrameRate = FRRATE12;
  1661. }else if (llFramePeriod <= 1010000 ){ // 100.0 rounded to 101 ms
  1662. FrameRate = FRRATE10;
  1663. // HR: changed from 134 to 143ms.
  1664. }else if (llFramePeriod <= 1430000 ){ // 133.3 rounded to 134 ms
  1665. FrameRate = FRRATE75;
  1666. }else if (llFramePeriod <= 2010000 ){ // 200 rounded to 201 ms
  1667. FrameRate = FRRATE5;
  1668. }else {
  1669. FrameRate = FRRATE375;
  1670. }
  1671. // rounding was necessary as the OS returns e.g. #667.111 for 15 fps
  1672. return FrameRate;
  1673. }
  1674. #if DBG
  1675. PCHAR
  1676. FRString (
  1677. USHORT index
  1678. )
  1679. {
  1680. switch (index)
  1681. {
  1682. case FRRATEVGA: return "VGA";
  1683. case FRRATE375: return "3.75";
  1684. case FRRATE5: return "5";
  1685. case FRRATE75: return "7.5";
  1686. case FRRATE10: return "10";
  1687. case FRRATE12: return "12";
  1688. case FRRATE15: return "15";
  1689. case FRRATE20: return "20";
  1690. case FRRATE24:return "24";
  1691. default:
  1692. return "";break;
  1693. }
  1694. }
  1695. #endif