📄 dcampkt.c
字号:
&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(KS_VIDEO_STREAM_CONFIG_CAPS))) {
continue;
}
//
// We do not support scaling or cropping so the dimension
// (biWidth, biHeight, biBitCount and biCompression)
// must match, and we will filled in the biSizeImage and others.
//
pbmiHeader = &DataRangeVideo->VideoInfoHeader.bmiHeader;
pbmiHeaderToVerify = &DataRangeVideoToVerify->VideoInfoHeader.bmiHeader;
if(pbmiHeader->biWidth != pbmiHeaderToVerify->biWidth ||
abs(pbmiHeader->biHeight) != abs(pbmiHeaderToVerify->biHeight) ||
pbmiHeader->biBitCount != pbmiHeaderToVerify->biBitCount ||
pbmiHeader->biCompression != pbmiHeaderToVerify->biCompression
) {
DbgMsg1(("AdapterFormatFromRange: 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;
}
// MATCH FOUND!
MatchFound = TRUE;
// KS_DATAFORMAT_VIDEOINFOHEADER
// KSDATAFORMAT DataFormat;
// KS_VIDEOINFOHEADER VideoInfoHeader;
//
// intsafe version of
// FormatSize = sizeof (KSDATAFORMAT) + KS_SIZE_VIDEOHEADER (&DataRangeVideo->VideoInfoHeader);
//
if (!NT_SUCCESS(RTL_SAFE_KS_SIZE_VIDEOHEADER(&DataRangeVideo->VideoInfoHeader, &FormatSize)) ||
!NT_SUCCESS(RtlULongAdd(FormatSize, sizeof (KSDATAFORMAT), &FormatSize))) {
Srb->Status = STATUS_INTEGER_OVERFLOW;
return FALSE;
}
//
// 1st query: Srb->ActualBytesTransferred = FormatSize
//
if(IntersectInfo->SizeOfDataFormatBuffer == 0) {
Srb->Status = STATUS_BUFFER_OVERFLOW;
// We actually have not returned this much data,
// this "size" will be used by Ksproxy to send down
// a buffer of that size in next query.
Srb->ActualBytesTransferred = FormatSize;
break;
}
//
// 2nd time: pass back the format information
//
if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
Srb->Status = STATUS_BUFFER_TOO_SMALL;
DbgMsg2(("IntersectInfo->SizeOfDataFormatBuffer=%d, FormatSize=%d\n", IntersectInfo->SizeOfDataFormatBuffer, FormatSize));
return FALSE;
}
//
// A match is found, Copy from our supported/matched data range and set frame rate:
// KS_DATAFORMAT_VIDEOINFOHEADER
// KSDATAFORMAT DataFormat;
// KS_VIDEOINFOHEADER VideoInfoHeader;
//
RtlCopyMemory(
&((PKS_DATAFORMAT_VIDEOINFOHEADER)IntersectInfo->DataFormatBuffer)->DataFormat,
&DataRangeVideo->DataRange,
sizeof (KSDATAFORMAT));
RtlCopyMemory(
&((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader, // KS_VIDEOINFOHEADER
&DataRangeVideo->VideoInfoHeader, // KS_VIDEOINFOHEADER
KS_SIZE_VIDEOHEADER (&DataRangeVideo->VideoInfoHeader)); // Use KS_SIZE_VIDEOHEADER() since this is variable size
//
// Special atttention to these two fields: biSizeImage and AvgTimePerFrame.
// We do not scale or stretch so biSizeImage is fixed.
// However, AvgTimePerFrame (FrameRate) can/need to be within (ConfigCaps.MinFrameInterval, ConfigCaps.MaxFrameInterval)
//
if (DataRangeVideoToVerify->VideoInfoHeader.AvgTimePerFrame > DataRangeVideoToVerify->ConfigCaps.MaxFrameInterval ||
DataRangeVideoToVerify->VideoInfoHeader.AvgTimePerFrame < DataRangeVideoToVerify->ConfigCaps.MinFrameInterval) {
((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader.AvgTimePerFrame =
DataRangeVideo->VideoInfoHeader.AvgTimePerFrame;
DbgMsg2(("AdapterFormatFromRange: out of range; so set it to default (%ld)\n",DataRangeVideo->VideoInfoHeader.AvgTimePerFrame));
} else {
((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader.AvgTimePerFrame =
DataRangeVideoToVerify->VideoInfoHeader.AvgTimePerFrame;
}
((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
Srb->ActualBytesTransferred = FormatSize;
DbgMsg2(("AdapterFormatFromRange: match found: [%x], %dx%dx%d=%d, AvgTimePerFrame %ld\n",
pbmiHeader->biCompression, pbmiHeader->biWidth, pbmiHeader->biHeight, pbmiHeader->biBitCount, pbmiHeader->biSizeImage,
((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader.AvgTimePerFrame));
break;
} // End of loop on all formats for this stream
if(!MatchFound) {
DbgMsg2(("AdapterFormatFromRange: No match !!\n"));
Srb->Status = STATUS_NO_MATCH;
return FALSE;
}
return TRUE;
}
BOOL
DCamBuildFormatTable(
PDCAM_EXTENSION pDevExt,
PIRB pIrb
)
/*
Description:
Query Video format and mode supported by the camera.
Return:
TRUE: support at least one mode
FALSE: failed to read mode register or do not support any mode.
*/
{
// Initialize
pDevExt->ModeSupported = 0;
if(DCamGetVideoMode(pDevExt, pIrb)) {
//
// Select preferred format (UYVY) first
//
// Mode1: 320x240 (4:2:2)
if(pDevExt->DCamVModeInq0.VMode.Mode1 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode1 == 1) {
pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_1;
pDevExt->ModeSupported++;
}
// Mode3: 640x480 (4:2:2)
if(pDevExt->DCamVModeInq0.VMode.Mode3 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode3 == 1) {
pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_3;
pDevExt->ModeSupported++;
}
#ifdef SUPPORT_YUV411
// Mode2: 640x480 (4:1:1)
if(pDevExt->DCamVModeInq0.VMode.Mode2 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode2 == 1) {
pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_2;
pDevExt->ModeSupported++;
}
#endif
#ifdef SUPPORT_RGB24
// Mode4: 640x480 (RGB24)
if(pDevExt->DCamVModeInq0.VMode.Mode4 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode4 == 1) {
pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_4;
pDevExt->ModeSupported++;
}
#endif
#ifdef SUPPORT_YUV444
// Mode0: 160x120 (4:4:4)
if(pDevExt->DCamVModeInq0.VMode.Mode0 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode0 == 1) {
pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_0;
pDevExt->ModeSupported++;
}
#endif
#ifdef SUPPORT_YUV800
// Mode5: 640x480 (Y800)
if(pDevExt->DCamVModeInq0.VMode.Mode5 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode5 == 1) {
pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_5;
pDevExt->ModeSupported++;
}
#endif
}
DbgMsg1(("\'Support %d modes; ->DCamStrmModes[]:%x\n", pDevExt->ModeSupported, &pDevExt->DCamStrmModes[0]));
ASSERT(pDevExt->ModeSupported > 0);
return (pDevEx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -