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

📄 hwcappin.cpp

📁 2个avstream类型驱动演示
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Comments:
//  Static method called on format verification BEFORE the object is created.
//
NTSTATUS  HwcapPin::OnSetDataFormat(
				PKSPIN Pin,
				const KSDATARANGE* DataRange, 
				const KSATTRIBUTE_LIST* AttributeRange)
{
	g_Trace << "HwcapPin::OnSetDataFormat VERIFY, id=" << Pin->Id << EOL;

	const GUID VideoInfoSpecifier = 
        {STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO)};

    if (IsEqualGUID (Pin -> ConnectionFormat -> Specifier, VideoInfoSpecifier)) {

        PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat =
            reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER> 
                (Pin -> ConnectionFormat);

        //
        // DataRange comes out of OUR data range list, so it should be OK 
        //
        const KS_DATARANGE_VIDEO *VIRange =
            reinterpret_cast <const KS_DATARANGE_VIDEO *>
                (DataRange);

        //
        // Check that the format is a match for the selected range. 
        //
        if (
            (ConnectionFormat -> VideoInfoHeader.bmiHeader.biWidth !=
                VIRange -> VideoInfoHeader.bmiHeader.biWidth) ||

            (ConnectionFormat -> VideoInfoHeader.bmiHeader.biHeight !=
                VIRange -> VideoInfoHeader.bmiHeader.biHeight) ||

            (ConnectionFormat -> VideoInfoHeader.bmiHeader.biCompression !=
                VIRange -> VideoInfoHeader.bmiHeader.biCompression) 

            ) {

            return STATUS_NO_MATCH;

        } 
	}

	return STATUS_SUCCESS;
};

///////////////////////////////////////////////////////////////////////
// HwcapPin::OnSetDataFormat
//
// Parameters:
// 	OldFormat            - The previous format used on this pin. 
// 	OldAttributeList     - The old attribute list for the prior format
// 	DataRange            - A range out of our list of data ranges which was 
//                         determined to be at least a partial match for Pin -> ConnectionFormat.
// 	AttributeRange       - The attribute range
// Returns:
// 	STATUS_SUCCESS if Pin's ConnectionFormat member matches the range 
//  that was passed to this routine.
//  STATUS_NO_MATCH if ConnectionFormat does not match the passed range. 
// Comments:
//  Called on format change.
//
NTSTATUS  HwcapPin::OnSetDataFormat(
				PKSDATAFORMAT OldFormat, 
				PKSMULTIPLE_ITEM OldAttributeList, 
				const KSDATARANGE* DataRange, 
				const KSATTRIBUTE_LIST* AttributeRange)
{
	ASSERT (OldFormat); // would be a Framework bug

	g_Trace << "HwcapPin::OnSetDataFormat CHANGE, id=" << PKSPIN(*this)->Id << EOL;

	PKSPIN Pin = PKSPIN(*this);

	// verify if the format is acceptable

	if ( OnSetDataFormat(Pin, DataRange, AttributeRange) == STATUS_SUCCESS ) {

		// OK. Set the new format by caching the new video header
		// Don't accept dynamic changes

        if (Pin -> DeviceState == KSSTATE_STOP)  {
			if (m_VideoInfoHeader)
				delete m_VideoInfoHeader;
			m_VideoInfoHeader = new (Pin) KsVideoInfoHeader;
			if (m_VideoInfoHeader==NULL)
				return STATUS_INSUFFICIENT_RESOURCES;
		}
		else {
			ASSERT(!"Should be here");
			return STATUS_INVALID_DEVICE_STATE;
		}

	}
	else
		return STATUS_NO_MATCH;

	return STATUS_SUCCESS;
}


///////////////////////////////////////////////////////////////////////
// HwcapPin::OnIntersection
//
// Parameters:
// 	Irp                  - IRP with the request
// 	CallerDataRange      - Ptr to one of the data ranges supplied by the client
// 	DescriptorDataRange  - Ptr to one of the data ranges from the pin descriptor
// 	BufferSize           - Size in bytes of the buffer pointed to by the Data
// 	Data                 - Pointer to the buffer to contain the data format
//					       structure representing the best format in the intersection of the
//						   two data ranges. Can be NULL.
// 	DataSize             - Resulting buffer size copied
// Returns:
// 	STATUS_SUCCESS if there is an intersection and it fits in the supplied
//  buffer, STATUS_BUFFER_OVERFLOW for successful size queries, STATUS_NO_MATCH
//  if the intersection is empty, or STATUS_BUFFER_TOO_SMALL if the supplied
//  buffer is too small.
// Comments:
// 	none
NTSTATUS HwcapPin::OnIntersection (KIrp /*Irp*/, 
			PKSDATARANGE CallerDataRange, 
			PKSDATARANGE DescriptorDataRange, 
			ULONG BufferSize, 
			PVOID Data, 
			PULONG DataSize)
{
	g_Trace << "HwcapPin::OnIntersection, BufSize=" << BufferSize << " " << EOL;

    PKS_DATAFORMAT_VIDEOINFOHEADER FormatVideoInfoHeader = PKS_DATAFORMAT_VIDEOINFOHEADER(Data);
    ULONG						   DataFormatSize;

    const GUID VideoInfoSpecifier = 
        {STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO)};
    

    // Make sure this is the videa data range

    if (!IsEqualGUID(CallerDataRange->Specifier, VideoInfoSpecifier ))  {
		    return STATUS_NO_MATCH;
	}

	
    PKS_DATARANGE_VIDEO callerDataRange = PKS_DATARANGE_VIDEO(CallerDataRange);
    PKS_DATARANGE_VIDEO descriptorDataRange = PKS_DATARANGE_VIDEO(DescriptorDataRange);

    //
    // Check that the other fields match
    //
    if ((callerDataRange->bFixedSizeSamples != 
            descriptorDataRange->bFixedSizeSamples) ||
        (callerDataRange->bTemporalCompression != 
            descriptorDataRange->bTemporalCompression) ||
        (callerDataRange->StreamDescriptionFlags != 
            descriptorDataRange->StreamDescriptionFlags) ||
        (callerDataRange->MemoryAllocationFlags != 
            descriptorDataRange->MemoryAllocationFlags) ||
        (RtlCompareMemory (&callerDataRange->ConfigCaps,
                &callerDataRange->ConfigCaps,
                sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) != 
                sizeof (KS_VIDEO_STREAM_CONFIG_CAPS))) 
    {
		g_Trace.Trace(TraceWarning, "Field mismatch OnIntersection()");
        return STATUS_NO_MATCH;
    }
    
	// get required size:

    DataFormatSize = sizeof( KSDATAFORMAT ) + KS_SIZE_VIDEOHEADER( &callerDataRange->VideoInfoHeader );

	// for size query, return the required size
        
    if (BufferSize == 0) 
    {
        *DataSize = DataFormatSize;
        g_Trace.Trace(TraceWarning, "Required size OnIntersection() = %d bytes\n", DataFormatSize);
        return STATUS_BUFFER_OVERFLOW;            
    } else if (BufferSize < DataFormatSize)  {

        return STATUS_BUFFER_TOO_SMALL;	// error

	}
    

    // Buffer is OK. Copy over the KSDATAFORMAT, followed by the actual VideoInfoHeader
        
    *DataSize = DataFormatSize;
        
    // Copy over the KSDATAFORMAT 
    
    memcpy(&FormatVideoInfoHeader->DataFormat, DescriptorDataRange, sizeof( KSDATARANGE ));
    FormatVideoInfoHeader->DataFormat.FormatSize = DataFormatSize;

    // Copy over the caller's requested VIDEOINFOHEADER

    memcpy(&FormatVideoInfoHeader->VideoInfoHeader, &callerDataRange->VideoInfoHeader,
        KS_SIZE_VIDEOHEADER( &callerDataRange->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.
	//
	// Adjust for compression if any

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

    return STATUS_SUCCESS;
}


///////////////////////////////////////////////////////////////////////
// HwcapPin::DeleteClones
//
// Parameters:
// 	none
// Returns:
// 	none
// Comments:
// 	none
void HwcapPin::DeleteClones()
{
	KsStreamPointer Clone = KsPin::GetFirstClone();

	while (Clone.IsValid()) {
			KsStreamPointer ThisClone = Clone;
			Clone = Clone.GetNextClone();
			ThisClone.Release();
	}
}

///////////////////////////////////////////////////////////////////////
// HwcapPin::DPC
//
// Parameters:
// 	none
// Returns:
// 	none
// Comments:
// 	Handle the "interrupt". 
//  Simulate image transfer into DMA buffers and satisfy pending cloned
//  stream pointers.
//
void HwcapPin::DPC()
{

	// Generate image into an internal frame store & fill the dma buffers 
	// with the image. 

	ULONG MappingsRemaining = m_pHardware->CompleteDma();

	// Walk over the list of clones and delete
	// the ones for each the mappings have been filled

	KsStreamPointer Clone = KsPin::GetFirstClone();

	while (MappingsRemaining && Clone.IsValid()) {


		// Update the stream header associated with given clone

		ULONG MappingsCompletedInThisClone = (MappingsRemaining > Clone.OffsetOut().Remaining) ?
			Clone.OffsetOut().Remaining : MappingsRemaining;

		for (ULONG i=0; i<MappingsCompletedInThisClone; i++)
			Clone.Header()->DataUsed += Clone.OffsetOut().Mappings[i].ByteCount;

		if (MappingsRemaining >= Clone.OffsetOut().Remaining) {

			// This clone is satisfied, fill the header 

			Clone.Header()->Duration = 
				PKS_VIDEOINFOHEADER(*m_VideoInfoHeader)->AvgTimePerFrame;
			Clone.Header()->PresentationTime.Numerator = 
				Clone.Header()->PresentationTime.Denominator = 1;
				PKS_VIDEOINFOHEADER(*m_VideoInfoHeader)->AvgTimePerFrame;

			// Timestamp it if we got the clocks assigned

			if (m_pClock) {

                Clone.Header()->PresentationTime.Time = m_pClock->GetTime();
                Clone.Header()->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
											   KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
			}
			else {
				Clone.Header()->PresentationTime.Time = 0;
			}

			// Delete this one and goto the next clone

			// g_Trace.Trace(TraceInfo, "HwcapPin::DPC() deleting clone %p\n", PKSSTREAM_POINTER(Clone));

			KsStreamPointer ThisClone = Clone;
			Clone = Clone.GetNextClone();
			ThisClone.Release();

			MappingsRemaining -= MappingsCompletedInThisClone;

		} else {

			// This clone has some more room to go: advance it and exit
			// g_Trace.Trace(TraceInfo, "HwcapPin::DPC() advancing clone %p\n", PKSSTREAM_POINTER(Clone));

			Clone.AdvanceOut(MappingsRemaining);

			break;
		}


	};

	if (m_bPending) {
		m_bPending = FALSE;
		::KsPinAttemptProcessing(*this, TRUE);
	}
}

⌨️ 快捷键说明

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