📄 wdmvdec.cpp
字号:
//
// Indicate the allocator support available on this stream
//
pStreamObject->Allocator = Streams[StreamNumber].hwStreamObjectInfo.Allocator;
//
// Indicate the event support available on this stream
//
pStreamObject->HwEventRoutine =
Streams[StreamNumber].hwStreamObjectInfo.HwEventRoutine;
switch (StreamNumber)
{
case STREAM_AnalogVideoInput:
ASSERT(IsEqualGUID(pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_ANALOGVIDEO));
pVideoStream = (CWDMVideoStream *)new(pStrmEx)
CWDMVideoStream(pStreamObject, this, &nErrorCode);
break;
case STREAM_VideoCapture:
ASSERT(IsEqualGUID(pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_VIDEOINFO));
m_pVideoCaptureStream = (CWDMVideoCaptureStream *)new(pStrmEx)
CWDMVideoCaptureStream(pStreamObject, this, pKSDataFormat, &nErrorCode);
if (m_pVideoPortStream)
{
m_pVideoPortStream->AttemptRenegotiation();
}
break;
case STREAM_VBICapture:
ASSERT(IsEqualGUID(pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_VBI));
m_pVBICaptureStream = (CWDMVBICaptureStream *)new(pStrmEx)
CWDMVBICaptureStream(pStreamObject, this, pKSDataFormat, &nErrorCode);
break;
case STREAM_VPVideo:
ASSERT(IsEqualGUID(pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_NONE) &&
IsEqualGUID(pKSDataFormat->SubFormat, KSDATAFORMAT_SUBTYPE_VPVideo));
m_pVideoPortStream = (CWDMVideoPortStream *)new(pStrmEx)
CWDMVideoPortStream(pStreamObject, this, &nErrorCode);
if (m_pVideoCaptureStream == NULL)
{
MRect t(0, 0, m_pDevice->GetDefaultDecoderWidth(),
m_pDevice->GetDefaultDecoderHeight());
m_pDevice->SetRect(t);
}
break;
case STREAM_VPVBI:
ASSERT(IsEqualGUID(pKSDataFormat->Specifier, KSDATAFORMAT_SPECIFIER_NONE) &&
IsEqualGUID(pKSDataFormat->SubFormat, KSDATAFORMAT_SUBTYPE_VPVBI));
pVPVBIStream = (CWDMVideoPortStream *)new(pStrmEx)
CWDMVideoPortStream(pStreamObject, this, &nErrorCode);
m_pDevice->SetVBIEN(TRUE);
m_pDevice->SetVBIFMT(TRUE);
break;
default:
pSrb->Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
if(nErrorCode == WDMMINI_NOERROR)
m_OpenStreams++;
else
pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
Exit:
DBGTRACE(("SrbOpenStream Exit\n"));
return(TRUE);
}
BOOL CWDMVideoDecoder::SrbCloseStream(PHW_STREAM_REQUEST_BLOCK pSrb)
{
int StreamNumber = pSrb->StreamObject->StreamNumber;
DBGTRACE(("CWDMVideoDecoder:SrbCloseStream()\n"));
DBGINFO(("SRBCLOSESTREAM ------- StreamNumber=%d\n", StreamNumber));
//
// the minidriver may wish to free any resources that were allocated at
// open stream time etc.
//
CWDMVideoStream * pVideoStream = (CWDMVideoStream *)pSrb->StreamObject->HwStreamExtension;
delete pVideoStream;
switch (StreamNumber)
{
case STREAM_AnalogVideoInput:
break;
case STREAM_VideoCapture:
m_pVideoCaptureStream = NULL;
break;
case STREAM_VBICapture:
m_pVBICaptureStream = NULL;
break;
case STREAM_VPVideo:
m_pVideoPortStream = NULL;
break;
case STREAM_VPVBI:
m_pDevice->SetVBIEN(FALSE);
m_pDevice->SetVBIFMT(FALSE);
break;
default:
pSrb->Status = STATUS_UNSUCCESSFUL;
return FALSE;
}
if (--m_OpenStreams == 0)
{
DBGINFO(("Last one out turns off the lights\n"));
m_CDecoderVPort.Close();
m_preEventOccurred = FALSE;
m_postEventOccurred = FALSE;
m_pDevice->SaveState();
}
pSrb->Status = STATUS_SUCCESS;
return TRUE;
}
BOOL CWDMVideoDecoder::SrbGetDataIntersection(PHW_STREAM_REQUEST_BLOCK pSrb)
{
DBGTRACE(("CWDMVideoDecoder:SrbGetDataIntersection()\n"));
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 >= NumStreams) {
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)) ||
(IntersectInfo->SizeOfDataFormatBuffer == 0) );
//
// 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, 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) *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;
}
// 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 = DataRangeVideoToVerify->VideoInfoHeader.bmiHeader.biSize +
FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader);
ULONG RangeSize = VideoHeaderSize +
FIELD_OFFSET(KS_DATARANGE_VIDEO,VideoInfoHeader);
if (VideoHeaderSize < FIELD_OFFSET(KS_VIDEOINFOHEADER,bmiHeader) ||
RangeSize < FIELD_OFFSET(KS_DATARANGE_VIDEO,VideoInfoHeader) ||
RangeSize > DataRangeVideoToVerify->DataRange.FormatSize) {
pSrb->Status = STATUS_INVALID_PARAMETER;
return FALSE;
}
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KSDATAFORMAT) +
VideoHeaderSize;
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 caller's requested VIDEOINFOHEADER
RtlCopyMemory(
&DataFormatVideoInfoHeaderOut->VideoInfoHeader,
&DataRangeVideoToVerify->VideoInfoHeader,
VideoHeaderSize);
// 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 STATIC_KSDATAFORMAT_TYPE_VIDEO for Video Port
// -------------------------------------------------------------------
else if (IsEqualGUID (DataRange->Specifier,
KSDATAFORMAT_SPECIFIER_NONE) &&
IsEqualGUID (DataRange->SubFormat, KSDATAFORMAT_SUBTYPE_VPVideo)) {
// MATCH FOUND!
MatchFound = TRUE;
FormatSize = sizeof (KSDATAFORMAT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -