⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wdmvdec.cpp

📁 传说中的 视频抓取驱动源码 啊啊啊啊啊啊啊啊啊啊啊啊啊
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    //
    // 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 + -