⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basestrm.cpp

📁 采集卡的驱动编程,具有较大的参考价值,特别开发视频采集的软件工程师有用
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    StreamClassScheduleTimer (
            m_pClassObject,										// StreamObject
            Adapter(),											// HwDeviceExtension
            (ULONG) (m_pVideoInfoHeader->AvgTimePerFrame / 20), // Microseconds
            VideoTimerRoutine,									// TimerRoutine
            this);												// Context

	//  -- excessive tracing... use during DEBUG only! --
	//	#ifdef __VIDCAP_TRACEON__
	//	TVS << TraceInfo << "VidcapBaseStream::OnVideoTimer -- End\n";
	//	#endif

}


NTSTATUS VidcapBaseStream::OnOpen(PHW_STREAM_REQUEST_BLOCK pSrb)
{
	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::OnOpen -- Start\n";
	#endif

    PKSDATAFORMAT           pKSDataFormat = pSrb->CommandData.OpenFormat;
    int                     StreamNumber = pSrb->StreamObject->StreamNumber;

	pSrb->Status = VerifyFormat(pSrb->CommandData.OpenFormat) ?
		STATUS_SUCCESS : STATUS_INVALID_PARAMETER;

	if (IsEqualGUID (pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_VIDEOINFO))
	{   
		#ifdef __VIDCAP_TRACEON__
		TVS << TraceAlways << "VidcapBaseStream::OnOpen -- Format == KSDATAFORMAT_SPECIFIER_VIDEOINFO\n";
		#endif
		
		PKS_DATAFORMAT_VIDEOINFOHEADER  pVideoInfoHeader = 
					(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
		PKS_VIDEOINFOHEADER pVideoInfoHdrRequested = &pVideoInfoHeader->VideoInfoHeader;
	
		ULONG nSize = KS_SIZE_VIDEOHEADER (pVideoInfoHdrRequested);

		m_pVideoInfoHeader = (PKS_VIDEOINFOHEADER) new(NonPagedPool) UCHAR[nSize];

		if (m_pVideoInfoHeader == NULL)
			pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;

		// Copy the VIDEOINFOHEADER requested to our storage
		RtlCopyMemory(m_pVideoInfoHeader, pVideoInfoHdrRequested, nSize);
	}

	// -------------------------------------------------------------------
	// Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
	// -------------------------------------------------------------------
	else if (IsEqualGUID (pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_ANALOGVIDEO))
	{
	  
		//
		// AnalogVideo DataRange == DataFormat!
		//

		// For now, don't even cache this
		// BUGBUG
		//
		#ifdef __VIDCAP_TRACEON__
		TVS << TraceAlways << "VidcapBaseStream::OnOpen -- Format == KSDATAFORMAT_SPECIFIER_ANALOGVIDEO\n";
		#endif

		PKS_DATARANGE_ANALOGVIDEO pDataFormatAnalogVideo = 
					(PKS_DATARANGE_ANALOGVIDEO) pSrb->CommandData.OpenFormat;
	}

	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::OnOpen -- End\n";
	#endif

	return pSrb->Status;
}

BOOL VidcapBaseStream::VerifyFormat(PKSDATAFORMAT pKSDataFormatToVerify)
{
	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::VerifyFormat -- Start\n";
	#endif

	BOOL                        fOK = FALSE;
	ULONG                       i;
	PKSDATAFORMAT*				pAvailableFormats = StreamFormatsArray();

	KdPrint(("TestCap: FormatSize=%d\n",  pKSDataFormatToVerify->FormatSize));
	KdPrint(("TestCap: MajorFormat=%x\n", pKSDataFormatToVerify->MajorFormat));

	//
	// Walk the formats supported by the stream
	//

	for (i = 0; i < NumberOfStreamFormats(); i++, pAvailableFormats++)
	{
		// Check for a match on the three GUIDs and format size

		if (!CompareGUIDsAndFormatSize(
				pKSDataFormatToVerify, 
				*pAvailableFormats,
				FALSE /* CompareFormatSize */ ))
			continue;

		//
		// Now that the three GUIDs match, switch on the Specifier
		// to do a further type-specific check
		//

		// -------------------------------------------------------------------
		// Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
		// -------------------------------------------------------------------

		if (IsEqualGUID (pKSDataFormatToVerify->Specifier, 
				KSDATAFORMAT_SPECIFIER_VIDEOINFO))
		{				
			PKS_DATAFORMAT_VIDEOINFOHEADER  pDataFormatVideoInfoHeader = 
					(PKS_DATAFORMAT_VIDEOINFOHEADER) pKSDataFormatToVerify;
			PKS_VIDEOINFOHEADER  pVideoInfoHdrToVerify = 
					 (PKS_VIDEOINFOHEADER) &pDataFormatVideoInfoHeader->VideoInfoHeader;
			PKS_DATARANGE_VIDEO             pKSDataRangeVideo = (PKS_DATARANGE_VIDEO) *pAvailableFormats;
			KS_VIDEO_STREAM_CONFIG_CAPS    *pConfigCaps = &pKSDataRangeVideo->ConfigCaps;
			RECT                            rcImage;
	

			/* 
			**  HOW BIG IS THE IMAGE REQUESTED (pseudocode follows)
			**
			**  if (IsRectEmpty (&rcTarget) {
			**      SetRect (&rcImage, 0, 0, 
			**              BITMAPINFOHEADER.biWidth,
							BITMAPINFOHEADER.biHeight);
			**  }
			**  else {
			**      // Probably rendering to a DirectDraw surface,
			**      // where biWidth is used to expressed the "stride" 
			**      // in units of pixels (not bytes) of the destination surface.
			**      // Therefore, use rcTarget to get the actual image size 
			**      
			**      rcImage = rcTarget;
			**  }
			*/
		
			if ((pVideoInfoHdrToVerify->rcTarget.right - 
				 pVideoInfoHdrToVerify->rcTarget.left <= 0) ||
				(pVideoInfoHdrToVerify->rcTarget.bottom - 
				 pVideoInfoHdrToVerify->rcTarget.top <= 0)) {
			
				 rcImage.left = rcImage.top = 0;
				 rcImage.right = pVideoInfoHdrToVerify->bmiHeader.biWidth;
				 rcImage.bottom = pVideoInfoHdrToVerify->bmiHeader.biHeight;
			}
			else {
				 rcImage = pVideoInfoHdrToVerify->rcTarget;
			}

			//
			// BUGBUG, perform all other verification tests here!!!
			//

			//
			// HOORAY, the format passed all of the tests, so we support it
			//

			fOK = TRUE;
			break;

		} // End of VIDEOINFOHEADER specifier

		// -------------------------------------------------------------------
		// Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
		// -------------------------------------------------------------------

		else if (IsEqualGUID (pKSDataFormatToVerify->Specifier, 
				KSDATAFORMAT_SPECIFIER_ANALOGVIDEO)) {
	  
			//
			// For analog video, the DataRange and DataFormat
			// are identical, so just copy the whole structure
			//

			PKS_DATARANGE_ANALOGVIDEO DataRangeVideo = 
					(PKS_DATARANGE_ANALOGVIDEO) *pAvailableFormats;

			//
			// BUGBUG, perform all other verification tests here!!!
			//

			fOK = TRUE;
			break;

		} // End of KS_ANALOGVIDEOINFO specifier

	} // End of loop on all formats for this stream

	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::VerifyFormat -- End\n";
	#endif

	return fOK;
}


BOOL VidcapBaseStream::CompareGUIDsAndFormatSize(
	IN PKSDATARANGE DataRange1,
	IN PKSDATARANGE DataRange2,
	BOOL fCompareFormatSize
	)
{

	return (
		IsEqualGUID (
			DataRange1->MajorFormat, 
			DataRange2->MajorFormat) &&
		IsEqualGUID (
			DataRange1->SubFormat, 
			DataRange2->SubFormat) &&
		IsEqualGUID (
			DataRange1->Specifier, 
			DataRange2->Specifier) && 
		(fCompareFormatSize ? 
				(DataRange1->FormatSize == DataRange2->FormatSize) : TRUE ));
}



NTSTATUS VidcapBaseStream::GetDataIntersection(PHW_STREAM_REQUEST_BLOCK pSrb)
{
	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::GetDataIntersection -- Start\n";
	#endif

	PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
	PKSDATARANGE                DataRange;
	BOOL                        OnlyWantsSize;
	BOOL                        MatchFound = FALSE;
	ULONG                       FormatSize;
	PKSDATAFORMAT*              pAvailableFormats;

	IntersectInfo = pSrb->CommandData.IntersectInfo;
	DataRange = IntersectInfo->DataRange;

	//
	// Get the pointer to the array of available formats
	//
	pAvailableFormats = StreamFormatsArray();

	//
	// Is the caller trying to get the format, or the size of the format?
	//

	OnlyWantsSize = (IntersectInfo->SizeOfDataFormatBuffer == sizeof(ULONG));

	//
	// Walk the formats supported by the stream searching for a match
	// of the three GUIDs which together define a DATARANGE
	//

	for (ULONG i = 0; i < NumberOfStreamFormats(); i++, pAvailableFormats++) {

		if (!CompareGUIDsAndFormatSize(
				DataRange, 
				*pAvailableFormats,
				TRUE /* CompareFormatSize */))
		{
			continue;
		}

		//
		// Now that the three GUIDs match, switch on the Specifier
		// to do a further type-specific check
		//

		// -------------------------------------------------------------------
		// Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
		// -------------------------------------------------------------------

		if (IsEqualGUID (DataRange->Specifier, KSDATAFORMAT_SPECIFIER_VIDEOINFO))
		{
			PKS_DATARANGE_VIDEO DataRangeVideoToVerify = 
					(PKS_DATARANGE_VIDEO) DataRange;
			PKS_DATARANGE_VIDEO DataRangeVideo = 
					(PKS_DATARANGE_VIDEO) *pAvailableFormats;
			PKS_DATAFORMAT_VIDEOINFOHEADER DataFormatVideoInfoHeaderOut;

			//
			// Check that the other fields match
			//
			if ((DataRangeVideoToVerify->bFixedSizeSamples != DataRangeVideo->bFixedSizeSamples) ||
				(DataRangeVideoToVerify->bTemporalCompression != DataRangeVideo->bTemporalCompression) ||
				(DataRangeVideoToVerify->StreamDescriptionFlags != DataRangeVideo->StreamDescriptionFlags) ||
				(DataRangeVideoToVerify->MemoryAllocationFlags != DataRangeVideo->MemoryAllocationFlags) ||
				(RtlCompareMemory (&DataRangeVideoToVerify->ConfigCaps,
						&DataRangeVideo->ConfigCaps,
						sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) != 
						sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)))
			{
				continue;
			}
			
			// MATCH FOUND!
			MatchFound = TRUE;            
			FormatSize = sizeof (KSDATAFORMAT) + 
				KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader);

			if (OnlyWantsSize)
				break;
			
			// Caller wants the full data format
			if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize)
				return(STATUS_BUFFER_TOO_SMALL);

			// Copy over the KSDATAFORMAT, followed by the 
			// actual VideoInfoHeader
				
			DataFormatVideoInfoHeaderOut = (PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer;

			// Copy over the KSDATAFORMAT 
			RtlCopyMemory(
				&DataFormatVideoInfoHeaderOut->DataFormat,
				&DataRangeVideoToVerify->DataRange,
				sizeof (KSDATARANGE));

			DataFormatVideoInfoHeaderOut->DataFormat.FormatSize = FormatSize;

			// Copy over the callers requested VIDEOINFOHEADER

			RtlCopyMemory(
				&DataFormatVideoInfoHeaderOut->VideoInfoHeader,
				&DataRangeVideoToVerify->VideoInfoHeader,
				KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader));

			// Calculate biSizeImage for this request, and put the result in both
			// the biSizeImage field of the bmiHeader AND in the SampleSize field
			// of the DataFormat.
			//
			// Note that for compressed sizes, this calculation will probably not
			// be just width * height * bitdepth

			DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader.biSizeImage =
				DataFormatVideoInfoHeaderOut->DataFormat.SampleSize = 
				KS_DIBSIZE(DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader);

			//
			// BUGBUG Perform other validation such as cropping and scaling checks
			// 

			break;

		} // End of VIDEOINFOHEADER specifier

		// -------------------------------------------------------------------
		// Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
		// -------------------------------------------------------------------

		else if (IsEqualGUID (DataRange->Specifier, 
				KSDATAFORMAT_SPECIFIER_ANALOGVIDEO))
		{
			//
			// For analog video, the DataRange and DataFormat
			// are identical, so just copy the whole structure
			//

			PKS_DATARANGE_ANALOGVIDEO DataRangeVideo = 
					(PKS_DATARANGE_ANALOGVIDEO) *pAvailableFormats;

			// MATCH FOUND!
			MatchFound = TRUE;            
			FormatSize = sizeof (KS_DATARANGE_ANALOGVIDEO);

			if (OnlyWantsSize)
				break;
			
			// Caller wants the full data format
			if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize)
				return(STATUS_BUFFER_TOO_SMALL);

			RtlCopyMemory(
				IntersectInfo->DataFormatBuffer,
				DataRangeVideo,
				sizeof (KS_DATARANGE_ANALOGVIDEO));

			((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;

			break;

		} // End of KS_ANALOGVIDEOINFO specifier

		else
		{
			#ifdef __VIDCAP_TRACEON__
			TVS << TraceAlways << "VidcapBaseStream::GetDataIntersection -- End, Returning STATUS_NO_MATCH\n";
			#endif
			return(STATUS_NO_MATCH);
		}

	} // End of loop on all formats for this stream
	
	if (OnlyWantsSize)
	{
		*(PULONG) IntersectInfo->DataFormatBuffer = FormatSize;
		pSrb->ActualBytesTransferred = sizeof(ULONG);

		#ifdef __VIDCAP_TRACEON__
		TVS << TraceInfo << "VidcapBaseStream::GetDataIntersection -- End, Size Only, STATUS_SUCCESS\n";
		#endif

		return(STATUS_SUCCESS);
	}        

	pSrb->ActualBytesTransferred = FormatSize;

	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::GetDataIntersection -- End, Returning STATUS_SUCCESS\n";
	#endif

	return(STATUS_SUCCESS);
}

void VidcapBaseStream::GetConnectionProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
{
	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::GetConnectionProperty -- Start\n";
	#endif


    PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
    ULONG Id = pSPD->Property->Id;              // index of the property

    switch (Id)
	{
    case KSPROPERTY_CONNECTION_ALLOCATORFRAMING:
        if (NULL != m_pVideoInfoHeader)
		{
			#ifdef __VIDCAP_TRACEON__
			TVS << TraceInfo << "VidcapBaseStream::GetConnectionProperty -- Got ALLOCATORFRAMING\n";
			#endif

            PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING) pSPD->PropertyInfo;
            Framing->RequirementsFlags =
                KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |
                KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER |
                KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY;
            Framing->PoolType = PagedPool;
            Framing->Frames = 1;
            Framing->FrameSize = m_pVideoInfoHeader->bmiHeader.biSizeImage;
            Framing->FileAlignment = 0; // FILE_LONG_ALIGNMENT???;
            Framing->Reserved = 0;
            pSrb->ActualBytesTransferred = sizeof (KSALLOCATOR_FRAMING);
			pSrb->Status = STATUS_SUCCESS;
			#ifdef __VIDCAP_TRACEON__
			TVS << TraceInfo << "VidcapBaseStream::GetConnectionProperty -- STATUS_SUCCESS\n";
			#endif
        }
        else
		{
			#ifdef __VIDCAP_TRACEON__
			TVS << TraceInfo << "VidcapBaseStream::GetConnectionProperty -- KSPROPERTY_CONNECTION_ALLOCATORFRAMING Invalid Parameter\n";
			#endif
            pSrb->Status = STATUS_INVALID_PARAMETER;
        }
        break;

    default:
		#ifdef __VIDCAP_TRACEON__
		TVS << TraceInfo << "VidcapBaseStream::GetConnectionProperty -- STATUS_NOT_IMPLEMENTED\n";
		#endif
		pSrb->Status = STATUS_NOT_IMPLEMENTED;
        break;
    }

	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::GetConnectionProperty -- End\n";
	#endif

}

void VidcapBaseStream::GetDroppedFramesProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
{
	#ifdef __VIDCAP_TRACEON__
	TVS << TraceInfo << "VidcapBaseStream::GetDroppedFramesProperty -- Start\n";
	#endif

    PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
    ULONG Id = pSPD->Property->Id;              // index of the property

    switch (Id)
	{
    case KSPROPERTY_DROPPEDFRAMES_CURRENT:
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -