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

📄 capmain.c

📁 一个视频采集驱动程序的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

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