📄 intelcam.c
字号:
streamNumber = intersectInfo->StreamNumber;
dataRange = intersectInfo->DataRange;
//
// Check that the stream number is valid
//
if (streamNumber >= DRIVER_STREAM_COUNT) {
ntStatus = Srb->Status = STATUS_INVALID_PARAMETER;
return ntStatus;
}
INTELCAM_KdPrint (MAX_TRACE, ("'AdapterFormatFromRange: Stream=%d\n",
streamNumber));
numberOfFormatArrayEntries =
Streams[streamNumber].NumberOfFormatArrayEntries;
//
// Get the pointer to the array of available formats
//
availableFormats =
Streams[streamNumber].StreamFormatsArray;
//
// Walk the formats supported by the stream searching for a match
// of the three GUIDs which together define a DATARANGE
//
for (j = 0; j < numberOfFormatArrayEntries; j++, availableFormats++) {
INTELCAM_KdPrint (MAX_TRACE, ("'checking format %d\n",j));
if (!AdapterCompareGUIDsAndFormatSize(dataRange,*availableFormats)) {
// not the format we want
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) *availableFormats;
PKS_DATAFORMAT_VIDEOINFOHEADER DataFormatVideoInfoHeaderOut;
INTELCAM_KdPrint (MAX_TRACE, ("'guid matched\n"));
//
// 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))) {
// not the format want
INTELCAM_KdPrint (MAX_TRACE, ("'format does not match\n"));
continue;
}
if ( (dataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biWidth !=
dataRangeVideo->VideoInfoHeader.bmiHeader.biWidth ) ||
(dataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biHeight !=
dataRangeVideo->VideoInfoHeader.bmiHeader.biHeight )) {
continue;
}
//
// KS_SIZE_VIDEOHEADER() below is relying on bmiHeader.biSize from
// the caller's data range. This **MUST** be validated; the
// extended bmiHeader size (biSize) must not extend past the end
// of the range buffer. Arithmetic overflow is also checked for.
// (overflow occurs if (a + b) < a, where a and b are unsigned values)
{
DWORD dwVideoHeaderSize =
KS_SIZE_VIDEOHEADER (&dataRangeVideoToVerify->VideoInfoHeader);
DWORD dwDataRangeSize = FIELD_OFFSET (KS_DATARANGE_VIDEO, VideoInfoHeader) +
dwVideoHeaderSize;
if (dwVideoHeaderSize < dataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biSize ||
dwDataRangeSize < dwVideoHeaderSize ||
dwDataRangeSize > dataRangeVideoToVerify->DataRange.FormatSize) {
ntStatus = Srb->Status = STATUS_INVALID_PARAMETER;
return ntStatus;
}
}
INTELCAM_KdPrint (MAX_TRACE, ("'match found\n"));
formatSize = sizeof (KSDATAFORMAT) +
KS_SIZE_VIDEOHEADER (&dataRangeVideoToVerify->VideoInfoHeader);
// we found a match.
bMatchFound = TRUE;
//
// Is the return buffer size = 0 ?
//
if(intersectInfo->SizeOfDataFormatBuffer == 0) {
ntStatus = Srb->Status = STATUS_BUFFER_OVERFLOW;
// the proxy wants to know the actuall buffer size to allocate.
Srb->ActualBytesTransferred = formatSize;
return ntStatus;
}
//
// this time the proxy should have allocated enough space...
//
if (intersectInfo->SizeOfDataFormatBuffer < formatSize) {
ntStatus = Srb->Status = STATUS_BUFFER_TOO_SMALL;
INTELCAM_KdPrint (MIN_TRACE, ("size of data format buffer is too small\n"));
return ntStatus;
}
DataFormatVideoInfoHeaderOut = (PKS_DATAFORMAT_VIDEOINFOHEADER) intersectInfo->DataFormatBuffer;
// Copy over the KSDATAFORMAT, followed by the
// actual VideoInfoHeader
RtlCopyMemory(
&DataFormatVideoInfoHeaderOut->DataFormat,
&dataRangeVideoToVerify->DataRange,
sizeof (KSDATARANGE));
DataFormatVideoInfoHeaderOut->DataFormat.FormatSize = formatSize;
Srb->ActualBytesTransferred = formatSize;
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);
//
// Perform other validation such as cropping and scaling checks
//
// we will not allow setting FPS below our minimum FPS.
if ((DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame >
dataRangeVideo->ConfigCaps.MaxFrameInterval) ) {
DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame =
dataRangeVideo->ConfigCaps.MaxFrameInterval;
DataFormatVideoInfoHeaderOut->VideoInfoHeader.dwBitRate =
dataRangeVideo->ConfigCaps.MinBitsPerSecond;
}
// we will not allow setting FPS above our maximum FPS.
if ((DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame <
dataRangeVideo->ConfigCaps.MinFrameInterval) ) {
DataFormatVideoInfoHeaderOut->VideoInfoHeader.AvgTimePerFrame =
dataRangeVideo->ConfigCaps.MinFrameInterval;
DataFormatVideoInfoHeaderOut->VideoInfoHeader.dwBitRate =
dataRangeVideo->ConfigCaps.MaxBitsPerSecond;
}
break;
}
} // End of loop on all formats for this stream
if (!bMatchFound) {
Srb->Status = ntStatus = STATUS_NOT_FOUND;
INTELCAM_KdPrint (MIN_TRACE, ("no Format match\n"));
}
INTELCAM_KdPrint (MAX_TRACE, ("'AdapterFormatFromRange ret %x\n", ntStatus));
return ntStatus;
}
/*
** 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 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(
PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormatToVerify,
ULONG StreamNumber
)
{
PKSDATAFORMAT *pAvailableFormats;
int NumberOfFormatArrayEntries;
int j;
// Make sure a format has been specified
if (!pKSDataFormatToVerify)
{
return FALSE;
}
//
// Make sure the stream index is valid
//
if (StreamNumber >= DRIVER_STREAM_COUNT) {
return FALSE;
}
if (!pKSDataFormatToVerify) {
INTELCAM_KdPrint (MIN_TRACE, ("WARNING: 'AdapterVerifyFormat: Received NULL pKSDataFormatToVerify param\n"));
return FALSE;
}
//
// How many formats does this stream support?
//
NumberOfFormatArrayEntries =
Streams[StreamNumber].NumberOfFormatArrayEntries;
INTELCAM_KdPrint (MAX_TRACE, ("'AdapterVerifyFormat: Stream=%d\n",
StreamNumber));
INTELCAM_KdPrint (MAX_TRACE, ("'AdapterVerifyFormat: FormatSize=%d\n",
pKSDataFormatToVerify->DataFormat.FormatSize));
INTELCAM_KdPrint (MAX_TRACE, ("'AdapterVerifyFormat: MajorFormat=%x\n",
pKSDataFormatToVerify->DataFormat.MajorFormat));
//
// Get the pointer to the array of available formats
//
pAvailableFormats = Streams[StreamNumber].StreamFormatsArray;
//
// Walk the array, searching for a match
//
for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++)
{
PKS_DATARANGE_VIDEO pKSDataRange = (PKS_DATARANGE_VIDEO) *pAvailableFormats;
PKS_VIDEOINFOHEADER pVideoInfoHdr = &pKSDataRange->VideoInfoHeader;
KS_VIDEO_STREAM_CONFIG_CAPS *pConfigCaps = &pKSDataRange->ConfigCaps;
//
// Check for matching size, Major Type, Sub Type, and Specifier
//
if (!IsEqualGUID (&pKSDataRange->DataRange.MajorFormat,
&pKSDataFormatToVerify->DataFormat.MajorFormat))
{
continue;
}
if (!IsEqualGUID (&pKSDataRange->DataRange.SubFormat,
&pKSDataFormatToVerify->DataFormat.SubFormat))
{
continue;
}
if (!IsEqualGUID (&pKSDataRange->DataRange.Specifier,
&pKSDataFormatToVerify->DataFormat.Specifier))
{
continue;
}
// --------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -