📄 strminfo.cpp
字号:
NULL, // HwEventRoutine
},
}
};
extern const ULONG NumStreams = SIZEOF_ARRAY(Streams);
//---------------------------------------------------------------------------
// Topology
//---------------------------------------------------------------------------
// Categories define what the device does.
static GUID Categories[] = {
STATIC_KSCATEGORY_VIDEO,
STATIC_KSCATEGORY_CAPTURE,
STATIC_KSCATEGORY_CROSSBAR,
};
#define NUMBER_OF_CATEGORIES SIZEOF_ARRAY (Categories)
KSTOPOLOGY Topology = {
NUMBER_OF_CATEGORIES, // CategoriesCount
(GUID*) &Categories, // Categories
0, // TopologyNodesCount
NULL, // TopologyNodes
0, // TopologyConnectionsCount
NULL, // TopologyConnections
NULL, // TopologyNodesNames
0, // Reserved
};
/*
** 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 AdapterCompareGUIDsAndFormatSize(
IN PKSDATARANGE DataRange1,
IN PKSDATARANGE DataRange2,
BOOL fCompareFormatSize
)
{
return (
IsEqualGUID (
DataRange1->MajorFormat,
DataRange2->MajorFormat) &&
IsEqualGUID (
DataRange1->SubFormat,
DataRange2->SubFormat) &&
IsEqualGUID (
DataRange1->Specifier,
DataRange2->Specifier) &&
(fCompareFormatSize ?
(DataRange1->FormatSize == DataRange2->FormatSize) : TRUE));
}
/*
** MultiplyCheckOverflow()
**
** Perform a 32-bit unsigned multiplication with status indicating whether overflow occured.
**
** Arguments:
**
** a - first operand
** b - second operand
** pab - result
**
** Returns:
**
** TRUE - no overflow
** FALSE - overflow occurred
**
*/
BOOL
MultiplyCheckOverflow(
ULONG a,
ULONG b,
ULONG *pab
)
{
*pab = a * b;
if ((a == 0) || (((*pab) / a) == b)) {
return TRUE;
}
return FALSE;
}
/*
** 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 AdapterVerifyFormat(PKSDATAFORMAT pKSDataFormatToVerify, int StreamNumber)
{
BOOL fOK = FALSE;
ULONG j;
ULONG NumberOfFormatArrayEntries;
PKSDATAFORMAT *pAvailableFormats;
//
// Check that the stream number is valid
//
if (StreamNumber >= NumStreams) {
TRAP();
return FALSE;
}
NumberOfFormatArrayEntries =
Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
//
// Get the pointer to the array of available formats
//
pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;
DBGINFO(("AdapterVerifyFormat, Stream=%d\n", StreamNumber));
DBGINFO(("FormatSize=%d\n",
pKSDataFormatToVerify->FormatSize));
DBGINFO(("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) &&
pKSDataFormatToVerify->FormatSize >= sizeof(KS_DATAFORMAT_VIDEOINFOHEADER)) {
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;
// Validate each step of the size calculations for arithmetic overflow,
// and verify that the specified sizes correlate
// (with unsigned math, a+b < b iff an arithmetic overflow occured)
{
ULONG VideoHeaderSize = pVideoInfoHdrToVerify->bmiHeader.biSize +
FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader);
ULONG FormatSize = VideoHeaderSize +
FIELD_OFFSET(KS_DATAFORMAT_VIDEOINFOHEADER,VideoInfoHeader);
if (VideoHeaderSize < FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader) ||
FormatSize < FIELD_OFFSET(KS_DATAFORMAT_VIDEOINFOHEADER,VideoInfoHeader) ||
FormatSize > pKSDataFormatToVerify->FormatSize) {
fOK = FALSE;
break;
}
}
// Validate the image size and dimension parameters
// (the equivalent of using the KS_DIBSIZE macro)
{
ULONG ImageSize = 0;
if (!MultiplyCheckOverflow(
(ULONG)pVideoInfoHdrToVerify->bmiHeader.biWidth,
(ULONG)pVideoInfoHdrToVerify->bmiHeader.biBitCount,
&ImageSize
)) {
fOK = FALSE;
break;
}
// Convert bits to an even multiple of 4 bytes
ImageSize = ((ImageSize / 8) + 3) & ~3;
// Now calculate the full size
if (!MultiplyCheckOverflow(
ImageSize,
(ULONG)abs(pVideoInfoHdrToVerify->bmiHeader.biHeight),
&ImageSize
)) {
fOK = FALSE;
break;
}
// Finally, is the specified image size big enough?
if (pDataFormatVideoInfoHeader->DataFormat.SampleSize < ImageSize ||
pVideoInfoHdrToVerify->bmiHeader.biSizeImage < ImageSize
) {
fOK = FALSE;
break;
}
}
fOK = TRUE;
break;
} // End of VIDEOINFOHEADER specifier
// -------------------------------------------------------------------
// Specifier FORMAT_VideoInfo for VBIINFOHEADER
// -------------------------------------------------------------------
if (IsEqualGUID (pKSDataFormatToVerify->Specifier, KSDATAFORMAT_SPECIFIER_VBI) &&
pKSDataFormatToVerify->FormatSize >= sizeof(KS_DATAFORMAT_VBIINFOHEADER)) {
PKS_DATAFORMAT_VBIINFOHEADER pKSVBIDataFormat =
(PKS_DATAFORMAT_VBIINFOHEADER)pKSDataFormatToVerify;
PKS_VBIINFOHEADER pVBIInfoHeader =
&pKSVBIDataFormat->VBIInfoHeader;
// Validate the VBI format and sample size parameters
{
ULONG SampleSize = 0;
// Do the StartLine and Endline values make sense?
if (pVBIInfoHeader->StartLine > pVBIInfoHeader->EndLine ||
pVBIInfoHeader->StartLine < (VREFDiscard + 1) ||
pVBIInfoHeader->EndLine - (VREFDiscard + 1) > 500
) {
fOK = FALSE;
break;
}
// Calculate the sample size
if (!MultiplyCheckOverflow(
pVBIInfoHeader->EndLine - pVBIInfoHeader->StartLine + 1,
pVBIInfoHeader->SamplesPerLine,
&SampleSize
)) {
fOK = FALSE;
break;
}
// Are the size parameters big enough?
if (pKSVBIDataFormat->DataFormat.SampleSize < SampleSize ||
pVBIInfoHeader->BufferSize < SampleSize
) {
fOK = FALSE;
break;
}
}
fOK = TRUE;
break;
} // End of VBI specifier
// -------------------------------------------------------------------
// Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
// -------------------------------------------------------------------
if (IsEqualGUID (pKSDataFormatToVerify->Specifier, KSDATAFORMAT_SPECIFIER_ANALOGVIDEO) &&
pKSDataFormatToVerify->FormatSize >= sizeof(KS_DATARANGE_ANALOGVIDEO)) {
fOK = TRUE;
break;
} // End of KS_ANALOGVIDEOINFO specifier
// -------------------------------------------------------------------
// Specifier STATIC_KSDATAFORMAT_TYPE_VIDEO for Video Port
// -------------------------------------------------------------------
if (IsEqualGUID (pKSDataFormatToVerify->Specifier, KSDATAFORMAT_SPECIFIER_NONE) &&
IsEqualGUID (pKSDataFormatToVerify->SubFormat, KSDATAFORMAT_SUBTYPE_VPVideo)) {
fOK = TRUE;
break;
} // End of Video port section
// -------------------------------------------------------------------
// Specifier KSDATAFORMAT_SPECIFIER_NONE for VP VBI
// -------------------------------------------------------------------
if (IsEqualGUID (pKSDataFormatToVerify->Specifier, KSDATAFORMAT_SPECIFIER_NONE) &&
IsEqualGUID (pKSDataFormatToVerify->SubFormat, KSDATAFORMAT_SUBTYPE_VPVBI)) {
fOK = TRUE;
break;
} // End of VP VBI section
} // End of loop on all formats for this stream
return fOK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -