📄 capmain.c
字号:
DbgLogInfo(("Testcap: This is a VBIINFOHEADER format pin.\n" ));
pKSVBIDataFormat = (PKS_DATAFORMAT_VBIINFOHEADER)pKSDataFormatToVerify;
//
// Check VideoStandard, we only support NTSC_M
//
if (KS_AnalogVideo_NTSC_M
== pKSVBIDataFormat->VBIInfoHeader.VideoStandard)
{
fOK = TRUE;
break;
}
else
{
DbgLogError(
("Testcap: AdapterVerifyFormat : VideoStandard(%d) != NTSC_M\n",
pKSVBIDataFormat->VBIInfoHeader.VideoStandard));
}
}
// -------------------------------------------------------------------
// Type FORMAT_NABTS for NABTS pin
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormatToVerify->SubFormat,
&KSDATAFORMAT_SUBTYPE_NABTS))
{
fOK = TRUE;
break;
}
// -------------------------------------------------------------------
// for CC pin
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormatToVerify->SubFormat,
&KSDATAFORMAT_SUBTYPE_CC))
{
fOK = TRUE;
break;
}
} // End of loop on all formats for this stream
return fOK;
}
/*
** AdapterFormatFromRange()
**
** Produces a DATAFORMAT given a DATARANGE.
**
** Think of a DATARANGE as a multidimensional space of all of the possible image
** sizes, cropping, scaling, and framerate possibilities. Here, the caller
** is saying "Out of this set of possibilities, could you verify that my
** request is acceptable?". The resulting singular output is a DATAFORMAT.
** Note that each different colorspace (YUV vs RGB8 vs RGB24)
** must be represented as a separate DATARANGE.
**
** Generally, the resulting DATAFORMAT will be immediately used to open a stream
** in that format.
**
** Arguments:
**
** IN PHW_STREAM_REQUEST_BLOCK pSrb
**
** Returns:
**
** TRUE if the format is supported
** FALSE if the format cannot be suppored
**
** Side Effects: none
*/
BOOL
STREAMAPI
AdapterFormatFromRange(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
PKSDATARANGE DataRange;
BOOL OnlyWantsSize;
BOOL MatchFound = FALSE;
ULONG FormatSize;
ULONG StreamNumber;
ULONG j;
ULONG NumberOfFormatArrayEntries;
PKSDATAFORMAT *pAvailableFormats;
IntersectInfo = pSrb->CommandData.IntersectInfo;
StreamNumber = IntersectInfo->StreamNumber;
DataRange = IntersectInfo->DataRange;
//
// Check that the stream number is valid
//
if (StreamNumber >= DRIVER_STREAM_COUNT) {
pSrb->Status = STATUS_NOT_IMPLEMENTED;
TRAP;
return FALSE;
}
NumberOfFormatArrayEntries =
Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;
//
// Get the pointer to the array of available formats
//
pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;
//
// Is the caller trying to get the format, or the size of the format?
//
OnlyWantsSize = (IntersectInfo->SizeOfDataFormatBuffer == sizeof(ULONG));
//
// 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++, pAvailableFormats++) {
if (!AdapterCompareGUIDsAndFormatSize(
DataRange,
*pAvailableFormats,
TRUE /* CompareFormatSize */)) {
continue;
}
//
// Now that the three GUIDs match, 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) *pAvailableFormats;
PKS_DATAFORMAT_VIDEOINFOHEADER DataFormatVideoInfoHeaderOut;
//
// 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;
}
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KSDATAFORMAT) +
KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader);
if (OnlyWantsSize) {
break;
}
// Caller wants the full data format
if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
pSrb->Status = STATUS_BUFFER_TOO_SMALL;
return FALSE;
}
// Copy over the KSDATAFORMAT, followed by the
// actual VideoInfoHeader
DataFormatVideoInfoHeaderOut = (PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer;
// Copy over the KSDATAFORMAT
RtlCopyMemory(
&DataFormatVideoInfoHeaderOut->DataFormat,
&DataRangeVideoToVerify->DataRange,
sizeof (KSDATARANGE));
DataFormatVideoInfoHeaderOut->DataFormat.FormatSize = FormatSize;
// Copy over the callers requested VIDEOINFOHEADER
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
//
break;
} // End of VIDEOINFOHEADER specifier
// -------------------------------------------------------------------
// Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
// -------------------------------------------------------------------
else if (IsEqualGUID (&DataRange->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;
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KS_DATARANGE_ANALOGVIDEO);
if (OnlyWantsSize) {
break;
}
// Caller wants the full data format
if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
pSrb->Status = STATUS_BUFFER_TOO_SMALL;
return FALSE;
}
RtlCopyMemory(
IntersectInfo->DataFormatBuffer,
DataRangeVideo,
sizeof (KS_DATARANGE_ANALOGVIDEO));
((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
break;
} // End of KS_ANALOGVIDEOINFO specifier
// -------------------------------------------------------------------
// Specifier FORMAT_VBI for KS_VIDEO_VBI
// -------------------------------------------------------------------
else if (IsEqualGUID (&DataRange->Specifier,
&KSDATAFORMAT_SPECIFIER_VBI))
{
PKS_DATARANGE_VIDEO_VBI pDataRangeVBI =
(PKS_DATARANGE_VIDEO_VBI)*pAvailableFormats;
PKS_DATAFORMAT_VBIINFOHEADER InterVBIHdr =
(PKS_DATAFORMAT_VBIINFOHEADER)IntersectInfo->DataFormatBuffer;
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KS_DATAFORMAT_VBIINFOHEADER);
// Is the caller trying to get the format, or the size of it?
if (OnlyWantsSize)
break;
// Verify that there is enough room in the supplied buffer
// for the whole thing
if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize)
{
if (IntersectInfo->SizeOfDataFormatBuffer > 0) {
DbgLogError(
("Testcap::AdapterFormatFromRange: "
"Specifier==VBI, Buffer too small=%d vs. %d\n",
IntersectInfo->SizeOfDataFormatBuffer,
FormatSize));
}
pSrb->Status = STATUS_BUFFER_TOO_SMALL;
return FALSE;
}
// If there is room, go ahead...
RtlCopyMemory(&InterVBIHdr->DataFormat,
&pDataRangeVBI->DataRange,
sizeof (KSDATARANGE));
((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
RtlCopyMemory(&InterVBIHdr->VBIInfoHeader,
&pDataRangeVBI->VBIInfoHeader,
sizeof(KS_VBIINFOHEADER));
break;
} // End of KS_VIDEO_VBI specifier
// -------------------------------------------------------------------
// Type FORMAT_NABTS for NABTS pin
// -------------------------------------------------------------------
else if (IsEqualGUID (&DataRange->SubFormat,
&KSDATAFORMAT_SUBTYPE_NABTS))
{
PKSDATARANGE pDataRange = (PKSDATARANGE)*pAvailableFormats;
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KSDATAFORMAT);
// Is the caller trying to get the format, or the size of it?
if (OnlyWantsSize)
break;
// Verify that there is enough room in the supplied buffer
// for the whole thing
if (IntersectInfo->SizeOfDataFormatBuffer >= FormatSize)
{
RtlCopyMemory(IntersectInfo->DataFormatBuffer,
pDataRange,
FormatSize);
((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
}
else
{
if (IntersectInfo->SizeOfDataFormatBuffer > 0) {
DbgLogError(
("Testcap::AdapterFormatFromRange: "
"SubFormat==NABTS, Buffer too small=%d vs. %d\n",
IntersectInfo->SizeOfDataFormatBuffer,
FormatSize));
}
pSrb->Status = STATUS_BUFFER_TOO_SMALL;
return FALSE;
}
break;
} // End of KS_SUBTYPE_NABTS
// -------------------------------------------------------------------
// for CC pin
// -------------------------------------------------------------------
else if (IsEqualGUID (&DataRange->SubFormat,
&KSDATAFORMAT_SUBTYPE_CC))
{
PKSDATARANGE pDataRange = (PKSDATARANGE)*pAvailableFormats;
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KSDATAFORMAT);
// Is the caller trying to get the format, or the size of it?
if (OnlyWantsSize)
break;
// Verify that there is enough room in the supplied buffer
// for the whole thing
if (IntersectInfo->SizeOfDataFormatBuffer >= FormatSize)
{
RtlCopyMemory(IntersectInfo->DataFormatBuffer,
pDataRange,
FormatSize);
((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
}
else
{
if (IntersectInfo->SizeOfDataFormatBuffer > 0) {
DbgLogError(
("Testcap::AdapterFormatFromRange: "
"SubFormat==CC, Buffer too small=%d vs. %d\n",
IntersectInfo->SizeOfDataFormatBuffer,
FormatSize));
}
pSrb->Status = STATUS_BUFFER_TOO_SMALL;
return FALSE;
}
break;
} // End of CC pin format check
else {
pSrb->Status = STATUS_NO_MATCH;
return FALSE;
}
} // End of loop on all formats for this stream
if (!MatchFound) {
pSrb->Status = STATUS_NO_MATCH;
return FALSE;
}
if (OnlyWantsSize) {
*(PULONG) IntersectInfo->DataFormatBuffer = FormatSize;
FormatSize = sizeof(ULONG);
}
pSrb->ActualBytesTransferred = FormatSize;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -