📄 capmain.c
字号:
//
AdapterSetProperty (pSrb);
break;
case SRB_PAGING_OUT_DRIVER:
//
// The driver is being paged out
// Disable Interrupts if you have them!
//
DbgLogInfo(("'Testcap: Receiving SRB_PAGING_OUT_DRIVER -- SRB=%x\n", pSrb));
break;
case SRB_CHANGE_POWER_STATE:
//
// Changing the device power state, D0 ... D3
//
DbgLogInfo(("'Testcap: Receiving SRB_CHANGE_POWER_STATE ------ SRB=%x\n", pSrb));
AdapterPowerState(pSrb);
break;
case SRB_INITIALIZATION_COMPLETE:
//
// Stream class has finished initialization.
// Now create DShow Medium interface BLOBs.
// This needs to be done at low priority since it uses the registry
//
DbgLogInfo(("'Testcap: Receiving SRB_INITIALIZATION_COMPLETE-- SRB=%x\n", pSrb));
AdapterCompleteInitialization (pSrb);
break;
case SRB_UNKNOWN_DEVICE_COMMAND:
default:
//
// this is a request that we do not understand. Indicate invalid
// command and complete the request
//
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
//
// Indicate back to the Stream Class that we're done with this SRB
//
CompleteDeviceSRB (pSrb);
//
// See if there's anything else on the queue
//
Busy = RemoveFromListIfAvailable (
&pSrb,
&pHwDevExt->AdapterSpinLock,
&pHwDevExt->ProcessingAdapterSRB,
&pHwDevExt->AdapterSRBList);
if (!Busy) {
break;
}
} // end of while there's anything in the queue
}
/*
** AdapterCancelPacket ()
**
** Request to cancel a packet that is currently in process in the minidriver
**
** Arguments:
**
** pSrb - pointer to request packet to cancel
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterCancelPacket(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
PSTREAMEX pStrmEx;
int StreamNumber;
BOOL Found = FALSE;
//
// Run through all the streams the driver has available
//
for (StreamNumber = 0; !Found && (StreamNumber < DRIVER_STREAM_COUNT); StreamNumber++) {
//
// Check to see if the stream is in use
//
if (pStrmEx = (PSTREAMEX) pHwDevExt->pStrmEx[StreamNumber]) {
Found = VideoQueueCancelOneSRB (
pStrmEx,
pSrb
);
} // if the stream is open
} // for all streams
DbgLogInfo(("TestCap: Cancelling SRB %8x Succeeded=%d\n", pSrb, Found));
}
/*
** AdapterTimeoutPacket()
**
** This routine is called when a packet has been in the minidriver for
** too long. The adapter must decide what to do with the packet
**
** Arguments:
**
** pSrb - pointer to the request packet that timed out
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterTimeoutPacket(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
//
// Unlike most devices, we need to hold onto data SRBs indefinitely,
// since the graph could be in a pause state indefinitely
//
DbgLogInfo(("TestCap: Timeout Adapter SRB %8x\n", pSrb));
pSrb->TimeoutCounter = pSrb->TimeoutOriginal;
}
/*
** CompleteDeviceSRB ()
**
** This routine is called when a packet is being completed.
** The optional second notification type is used to indicate ReadyForNext
**
** Arguments:
**
** pSrb - pointer to the request packet that timed out
**
** Returns:
**
** Side Effects:
**
*/
VOID
STREAMAPI
CompleteDeviceSRB (
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
DbgLogTrace(("TestCap: Completing Adapter SRB %8x\n", pSrb));
StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
}
/*
** IsEqualOrWildGUID()
**
** Compares two GUIDS like IsEqualGUID(), except allows wildcard matches
**
** Arguments:
**
** IN GUID *g1
** IN GUID *g2
**
** Returns:
**
** TRUE if both GUIDs match or only one is a wildcard
** FALSE if GUIDs are different or both are wildcards
**
** Side Effects: none
*/
BOOL
STREAMAPI
IsEqualOrWildGUID(IN GUID *g1, IN GUID *g2)
{
return (IsEqualGUID(g1, g2) && !IsEqualGUID(g1, &KSDATAFORMAT_TYPE_WILDCARD)
|| ((IsEqualGUID(g1, &KSDATAFORMAT_TYPE_WILDCARD)
|| IsEqualGUID(g2, &KSDATAFORMAT_TYPE_WILDCARD))
&& !IsEqualGUID(g1, g2))
);
}
/*
** AdapterCompareGUIDsAndFormatSize()
**
** Checks for a match on the three GUIDs and FormatSize
**
** Arguments:
**
** IN DataRange1
** IN DataRange2
** BOOL fCompareFormatSize - TRUE when comparing ranges
** - FALSE when comparing formats
**
** Returns:
**
** TRUE if all elements match
** FALSE if any are different
**
** Side Effects: none
*/
BOOL
STREAMAPI
AdapterCompareGUIDsAndFormatSize(
IN PKSDATARANGE DataRange1,
IN PKSDATARANGE DataRange2,
BOOL fCompareFormatSize
)
{
return (
IsEqualOrWildGUID (
&DataRange1->MajorFormat,
&DataRange2->MajorFormat) &&
IsEqualOrWildGUID (
&DataRange1->SubFormat,
&DataRange2->SubFormat) &&
IsEqualOrWildGUID (
&DataRange1->Specifier,
&DataRange2->Specifier) &&
(fCompareFormatSize ?
(DataRange1->FormatSize == DataRange2->FormatSize) : TRUE ));
}
/*
** AdapterVerifyFormat()
**
** Checks the validity of a format request by walking through the
** array of supported KSDATA_RANGEs for a given stream.
**
** Arguments:
**
** pKSDataFormat - pointer of a KSDATAFORMAT structure.
** StreamNumber - index of the stream being queried / opened.
**
** Returns:
**
** TRUE if the format is supported
** FALSE if the format cannot be suppored
**
** Side Effects: none
*/
BOOL
STREAMAPI
AdapterVerifyFormat(
PKSDATAFORMAT pKSDataFormatToVerify,
int StreamNumber
)
{
BOOL fOK = FALSE;
ULONG j;
ULONG NumberOfFormatArrayEntries;
PKSDATAFORMAT *pAvailableFormats;
//
// Check that the stream number is valid
//
if (StreamNumber >= DRIVER_STREAM_COUNT) {
TRAP;
return FALSE;
}
NumberOfFormatArrayEntries =
Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
//
// Get the pointer to the array of available formats
//
pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;
DbgLogInfo(("TestCap: AdapterVerifyFormat, Stream=%d\n", StreamNumber));
DbgLogInfo(("TestCap: FormatSize=%d\n", pKSDataFormatToVerify->FormatSize));
DbgLogInfo(("TestCap: MajorFormat=%x\n", pKSDataFormatToVerify->MajorFormat));
//
// Walk the formats supported by the stream
//
for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++) {
// Check for a match on the three GUIDs and format size
if (!AdapterCompareGUIDsAndFormatSize(
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;
DbgLogInfo(("TestCap: AdapterVerifyFormat\n"));
DbgLogInfo(("TestCap: pVideoInfoHdrToVerify=%x\n", pVideoInfoHdrToVerify));
DbgLogInfo(("TestCap: KS_VIDEOINFOHEADER size=%d\n",
KS_SIZE_VIDEOHEADER (pVideoInfoHdrToVerify)));
DbgLogInfo(("TestCap: Width=%d Height=%d BitCount=%d\n",
pVideoInfoHdrToVerify->bmiHeader.biWidth,
pVideoInfoHdrToVerify->bmiHeader.biHeight,
pVideoInfoHdrToVerify->bmiHeader.biBitCount));
DbgLogInfo(("TestCap: biSizeImage=%d\n",
pVideoInfoHdrToVerify->bmiHeader.biSizeImage));
/*
** 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;
}
//
// 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;
//
// Perform all other verification tests here!!!
//
fOK = TRUE;
break;
} // End of KS_ANALOGVIDEOINFO specifier
// -------------------------------------------------------------------
// Specifier FORMAT_VBI for KS_VIDEO_VBI
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormatToVerify->Specifier,
&KSDATAFORMAT_SPECIFIER_VBI))
{
//
// Do some VBI-specific tests
//
PKS_DATAFORMAT_VBIINFOHEADER pKSVBIDataFormat;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -