📄 dcampkt.c
字号:
/*++
Routine Description:
Returns more processing required so the IO Manager will leave us alone
Arguments:
DriverObject - Pointer to driver object created by system.
pIrp - Irp that just completed
pDCamIoContext - Context
Return Value:
None.
--*/
{
PDCAM_EXTENSION pDevExt;
NTSTATUS Status;
PIRB pIrb;
PIO_STACK_LOCATION NextIrpStack;
#ifdef WAIT_FOR_SLOW_DEVICE
KeStallExecutionProcessor(5000); // 5 msec
#endif
DbgMsg2(("\'DCamStartListenCR: pIrp->IoStatus.Status=%x\n", pIrp->IoStatus.Status));
if(STATUS_SUCCESS != pIrp->IoStatus.Status) {
pDevExt = pDCamIoContext->pDevExt;
pIrb = pDCamIoContext->pIrb;
if(pDevExt->lRetries > 0) {
pDevExt->lRetries--;
DbgMsg1(("DCamStartListenCR: Try DCAM_RUNSTATE_SET_REQUEST_ISOCH_LISTEN again!\n"));
pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN;
pIrb->Flags = 0;
pIrb->u.IsochListen.hResource = pDevExt->hResource;
pIrb->u.IsochListen.fulFlags = 0;
NextIrpStack = IoGetNextIrpStackLocation(pIrp);
NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
NextIrpStack->Parameters.Others.Argument1 = pIrb;
IoSetCompletionRoutine(
pIrp,
DCamStartListenCR,
pDCamIoContext,
TRUE,
TRUE,
TRUE
);
Status =
IoCallDriver(
pDevExt->BusDeviceObject,
pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
} else {
ERROR_LOG(("Start Listening has failed Status=%x; try again in next read.\n", pIrp->IoStatus.Status));
pDCamIoContext->pDevExt->bNeedToListen = TRUE;
}
}
DCamFreeIrbIrpAndContext(pDCamIoContext, pDCamIoContext->pIrb, pIrp);
// No StreamClassDeviceNotification() here since
// this is local initiated Irb (as part of AttachBufferCR().
return STATUS_MORE_PROCESSING_REQUIRED;
}
/*
** AdapterCompareGUIDsAndFormatSize()
**
** Checks for a match on the three GUIDs and FormatSize
**
** Arguments:
**
** IN DataRange1
** IN DataRange2
**
** Returns:
**
** TRUE if all elements match
** FALSE if any are different
**
** Side Effects: none
*/
BOOL
AdapterCompareGUIDsAndFormatSize(
IN PKSDATARANGE DataRange1,
IN PKSDATARANGE DataRange2)
{
PAGED_CODE();
return (
IsEqualGUID (
&DataRange1->MajorFormat,
&DataRange2->MajorFormat) &&
IsEqualGUID (
&DataRange1->SubFormat,
&DataRange2->SubFormat) &&
IsEqualGUID (
&DataRange1->Specifier,
&DataRange2->Specifier) &&
(DataRange1->FormatSize == DataRange2->FormatSize));
}
/*
** AdapterVerifyFormat()
**
** Checks the validity of a format request by walking through the
** array of supported PKSDATARANGEs for a given stream.
**
** Arguments:
**
** pKSDataFormatVideoToVerify - pointer of a KS_DATAFORMAT_VIDEOINFOHEADER 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
AdapterVerifyFormat(
ULONG VideoModesSupported,
PKSDATAFORMAT *pDCamStrmModesSupported,
PKS_DATAFORMAT_VIDEOINFOHEADER pDataFormatVideoToVerify,
int StreamNumber)
{
PKS_VIDEOINFOHEADER pVideoInfoHdrToVerify = &pDataFormatVideoToVerify->VideoInfoHeader;
PKSDATAFORMAT *paDataFormatsVideoAvail; // an array of PKSDATAFORMAT (not PKS_DATARANGE_VIDEO !!)
PKS_DATARANGE_VIDEO pDataRangeVideo;
KS_VIDEO_STREAM_CONFIG_CAPS *pConfigCaps;
PKS_BITMAPINFOHEADER pbmiHeader,
pbmiHeaderToVerify;
int j;
PAGED_CODE();
//
// Make sure the stream index is valid
// We only has one capure pin/stream (index 0).
//
if (StreamNumber >= 1) {
return FALSE;
}
//
// Get the pointer to the array of available formats
//
paDataFormatsVideoAvail = &pDCamStrmModesSupported[0]; // &pDevExt->DCamStrmModes[0];
//
// Walk the array, searching for a match
//
for (j = 0; j < (LONG) VideoModesSupported; j++, paDataFormatsVideoAvail++) {
pDataRangeVideo = (PKS_DATARANGE_VIDEO) *paDataFormatsVideoAvail;
//
// Check for matching size, Major Type, Sub Type, and Specifier
//
//
// Check for matching size, Major Type, Sub Type, and Specifier
//
if (!IsEqualGUID (&pDataRangeVideo->DataRange.MajorFormat,
&pDataFormatVideoToVerify->DataFormat.MajorFormat)) {
DbgMsg2(("\'%d) AdapterVerifyFormat: MajorFormat mismatch!\n", j));
continue;
}
if (!IsEqualGUID (&pDataRangeVideo->DataRange.SubFormat,
&pDataFormatVideoToVerify->DataFormat.SubFormat)) {
DbgMsg2(("\'%d) AdapterVerifyFormat: SubFormat mismatch!\n", j));
continue;
}
if (!IsEqualGUID (&pDataRangeVideo->DataRange.Specifier,
&pDataFormatVideoToVerify->DataFormat.Specifier)) {
DbgMsg2(("\'%d) AdapterVerifyFormat: Specifier mismatch!\n", j));
continue;
}
if(pDataFormatVideoToVerify->DataFormat.FormatSize <
sizeof(KS_DATAFORMAT_VIDEOINFOHEADER))
continue;
//
// Only if we get here, we are certain that we are dealing with video info.
//
// We do not support scaling or cropping so the dimension
// (biWidth, biHeight, biBitCount and biCompression)
// must match.
//
pbmiHeader = &pDataRangeVideo->VideoInfoHeader.bmiHeader;
pbmiHeaderToVerify = &pDataFormatVideoToVerify->VideoInfoHeader.bmiHeader;
if(pbmiHeader->biWidth != pbmiHeaderToVerify->biWidth ||
pbmiHeader->biHeight != pbmiHeaderToVerify->biHeight ||
pbmiHeader->biBitCount != pbmiHeaderToVerify->biBitCount ||
pbmiHeader->biCompression != pbmiHeaderToVerify->biCompression
) {
DbgMsg2(("AdapterVerifyFormat: Supported: %dx%dx%d [%x] != ToVerify: %dx%dx%d [%x]\n",
pbmiHeader->biWidth, pbmiHeader->biHeight, pbmiHeader->biBitCount, pbmiHeader->biCompression,
pbmiHeaderToVerify->biWidth, pbmiHeaderToVerify->biHeight, pbmiHeaderToVerify->biBitCount, pbmiHeaderToVerify->biCompression));
continue;
}
// biSizeImage must be to be BIG ENOUGH
if(pbmiHeaderToVerify->biSizeImage < pbmiHeader->biSizeImage) {
DbgMsg2(("AdapterVerifyFormat: biSizeImageToVerify %d < required %x\n",
pbmiHeaderToVerify->biSizeImage, pbmiHeader->biSizeImage));
continue;
}
// Frame rate needs to be within range
pConfigCaps = &pDataRangeVideo->ConfigCaps;
if(pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame > pConfigCaps->MaxFrameInterval &&
pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame < pConfigCaps->MinFrameInterval) {
DbgMsg2(("\'format index %d) AdapterVerifyFormat: Frame rate %ld is not within range(%ld, %ld)!\n",
j, pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame,
pConfigCaps->MaxFrameInterval, pConfigCaps->MinFrameInterval));
continue;
}
//
// The format passed all of the tests, so we support it
//
DbgMsg2(("\'(format idx %d) AdapterVerifyFormat: Verify!! Width=%d, Height=%d, biBitCount=%d, biSizeImage=%d\n", j,
pbmiHeaderToVerify->biWidth, pbmiHeaderToVerify->biHeight, pbmiHeaderToVerify->biBitCount,pbmiHeaderToVerify->biSizeImage));
DbgMsg2(("AdapterVerifyFormat: AvgTimePerFrame = %ld\n", pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame));
DbgMsg2(("AdapterVerifyFormat: (Max %ld\n", pConfigCaps->MaxFrameInterval));
DbgMsg2(("AdapterVerifyFormat: Min %ld)\n", pConfigCaps->MinFrameInterval));
return TRUE;
}
//
// The format requested didn't match any of our listed ranges,
// so refuse the connection.
//
DbgMsg2(("AdapterVerifyFormat: This format is not supported!\n"));
return FALSE;
}
/*
** AdapterFormatFromRange()
**
** Examine the given data format with many key fields and
** return a complete data format that can be used to open a stream.
**
** Arguments:
**
** IN PHW_STREAM_REQUEST_BLOCK Srb
**
** Returns:
**
** TRUE if the format is supported
** FALSE if the format cannot be suppored
**
** Side Effects: none
*/
BOOL
AdapterFormatFromRange(
IN PHW_STREAM_REQUEST_BLOCK Srb)
{
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) Srb->HwDeviceExtension;
PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
PKSDATARANGE DataRange,
*pAvailableFormats; // KSDATARANGE == KSDATAFORMAT
PKS_DATARANGE_VIDEO DataRangeVideoToVerify,
DataRangeVideo;
PKS_BITMAPINFOHEADER pbmiHeader,
pbmiHeaderToVerify;
ULONG FormatSize;
BOOL MatchFound = FALSE;
ULONG j;
PAGED_CODE();
Srb->Status = STATUS_SUCCESS;
IntersectInfo = Srb->CommandData.IntersectInfo;
DataRange = IntersectInfo->DataRange;
DbgMsg2(("IntersectIfo->DataFormatBuffer=%x, size=%d\n", IntersectInfo->DataFormatBuffer, IntersectInfo->SizeOfDataFormatBuffer));
//
// Check that the stream number is valid
// We support only one capture pin/stream (index 0)
//
if (IntersectInfo->StreamNumber >= 1) {
Srb->Status = STATUS_NOT_IMPLEMENTED;
ERROR_LOG(("\'AdapterFormatFromRange: StreamNumber(=%d) is not implemented.\n", IntersectInfo->StreamNumber));
ASSERT(FALSE);
return FALSE;
}
//
// Get the pointer to the array of available formats
//
pAvailableFormats = &pDevExt->DCamStrmModes[0];
//
// Walk the formats supported by the stream searching for a match
// of the three GUIDs which together define a DATARANGE
//
DataRangeVideoToVerify = (PKS_DATARANGE_VIDEO) DataRange;
for (j = 0; j < pDevExt->ModeSupported; j++, pAvailableFormats++) {
DataRangeVideo = (PKS_DATARANGE_VIDEO) *pAvailableFormats;
//
// STREAM_DATA_INTERSECT_INFO
// [IN] ULONG StreamNumber;
// [IN] PKSDATARANGE DataRange;
// [OUT] PVOID DataFormatBuffer; // == PKS_DATAFORMAT_VIDEOINFOHEADER
// [OUT] ULONG SizeOfDataFormatBuffer;
//
//
// KS_DATAFORMAT_VIDEOINFOHEADER:
// fields marked with 'm' must match;
// marked with 'r' must within range;
// marked with 'f' is filled by us
//
// KSDATAFORMAT == KSDATARANGE
// m ULONG FormatSize;
// ULONG Flags;
// ULONG SampleSize;
// ULONG Reserved;
// m GUID MajorFormat;
// m GUID SubFormat;
// m GUID Specifier;.
// m BOOL bFixedSizeSamples; // all samples same size?
// m BOOL bTemporalCompression; // all I frames?
// m DWORD StreamDescriptionFlags; // KS_VIDEO_DESC_*
// m DWORD MemoryAllocationFlags; // KS_VIDEO_ALLOC_*
// m KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps;
// KS_VIDEOINFOHEADER
// RECT rcSource; // The bit we really want to use
// RECT rcTarget; // Where the video should go
// DWORD dwBitRate; // Approximate bit data rate
// DWORD dwBitErrorRate; // Bit error rate for this stream
// r/f REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units)
// KS_BITMAPINFOHEADER bmiHeader;
// DWORD biSize;
// m LONG biWidth;
// m LONG biHeight;
// WORD biPlanes;
// m WORD biBitCount;
// m DWORD biCompression;
// f DWORD biSizeImage;
// LONG biXPelsPerMeter;
// LONG biYPelsPerMeter;
// DWORD biClrUsed;
// DWORD biClrImportant;
//
// Verify that it is a VIDEO format/range.
if (!AdapterCompareGUIDsAndFormatSize((PKSDATARANGE)DataRangeVideoToVerify, (PKSDATARANGE)DataRangeVideo)) {
continue;
}
//
// It is valid video format/range; now 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(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -