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

📄 dcampkt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
            &pDataFormatVideoToVerify->DataFormat.SubFormat)) {
               DbgMsg2(("\'%d) AdapterVerifyFormat: SubFormat mismatch!\n", j));
               continue;
        }

        if (!IsEqualGUID (&pDataRangeVideo->DataRange.Specifier,
            &pDataFormatVideoToVerify->DataFormat.Specifier)) {
               DbgMsg2(("\'%d) AdapterVerifyFormat: Specifier mismatch!\n", j));
               continue;
        }

        if(pDataFormatVideoToVerify->DataFormat.FormatSize < 
            sizeof(KS_DATAFORMAT_VIDEOINFOHEADER))
            continue;

        //
        // Only if we get here, we are certain that we are dealing with video info.
        //

        // We do not support scaling or cropping so the dimension 
        // (biWidth, biHeight, biBitCount and biCompression)
        // must match.
        // 
        pbmiHeader         = &pDataRangeVideo->VideoInfoHeader.bmiHeader;
        pbmiHeaderToVerify = &pDataFormatVideoToVerify->VideoInfoHeader.bmiHeader;

        if(pbmiHeader->biWidth       != pbmiHeaderToVerify->biWidth    ||
           pbmiHeader->biHeight      != pbmiHeaderToVerify->biHeight   ||
           pbmiHeader->biBitCount    != pbmiHeaderToVerify->biBitCount ||
           pbmiHeader->biCompression != pbmiHeaderToVerify->biCompression
           ) {

            DbgMsg2(("AdapterVerifyFormat: Supported: %dx%dx%d [%x] != ToVerify: %dx%dx%d [%x]\n",
                    pbmiHeader->biWidth, pbmiHeader->biHeight,  pbmiHeader->biBitCount, pbmiHeader->biCompression,
                    pbmiHeaderToVerify->biWidth, pbmiHeaderToVerify->biHeight,  pbmiHeaderToVerify->biBitCount, pbmiHeaderToVerify->biCompression));
            continue;
        }

        // biSizeImage must be to be BIG ENOUGH
        if(pbmiHeaderToVerify->biSizeImage < pbmiHeader->biSizeImage) {

            DbgMsg2(("AdapterVerifyFormat: biSizeImageToVerify %d < required %x\n", 
                pbmiHeaderToVerify->biSizeImage, pbmiHeader->biSizeImage));
            continue;
        }

        // Frame rate needs to be within range
        pConfigCaps = &pDataRangeVideo->ConfigCaps;
        if(pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame > pConfigCaps->MaxFrameInterval &&
           pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame < pConfigCaps->MinFrameInterval) {

           DbgMsg2(("\'format index %d) AdapterVerifyFormat: Frame rate %ld is not within range(%ld, %ld)!\n", 
              j, pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame,
              pConfigCaps->MaxFrameInterval, pConfigCaps->MinFrameInterval));
           continue;
        }


        //
        // The format passed all of the tests, so we support it
        //

        DbgMsg2(("\'(format idx %d) AdapterVerifyFormat: Verify!! Width=%d, Height=%d, biBitCount=%d, biSizeImage=%d\n", j,
            pbmiHeaderToVerify->biWidth, pbmiHeaderToVerify->biHeight, pbmiHeaderToVerify->biBitCount,pbmiHeaderToVerify->biSizeImage));
        DbgMsg2(("AdapterVerifyFormat: AvgTimePerFrame = %ld\n", pDataFormatVideoToVerify->VideoInfoHeader.AvgTimePerFrame));
        DbgMsg2(("AdapterVerifyFormat: (Max %ld\n", pConfigCaps->MaxFrameInterval));
        DbgMsg2(("AdapterVerifyFormat:               Min %ld)\n", pConfigCaps->MinFrameInterval));

        return TRUE;
    } 

    //
    // The format requested didn't match any of our listed ranges,
    // so refuse the connection.
    //
    DbgMsg2(("AdapterVerifyFormat: This format is not supported!\n"));

    return FALSE;
}



/*
** AdapterFormatFromRange()
**
**   Examine the given data format with many key fields and 
**   return a complete data format that can be used to open a stream.
**
** Arguments:
**
**   IN PHW_STREAM_REQUEST_BLOCK Srb 
**
** Returns:
** 
**   TRUE if the format is supported
**   FALSE if the format cannot be suppored
**
** Side Effects:  none
*/
BOOL 
AdapterFormatFromRange(
    IN PHW_STREAM_REQUEST_BLOCK Srb)
{
    PDCAM_EXTENSION             pDevExt = (PDCAM_EXTENSION) Srb->HwDeviceExtension;
    PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
    PKSDATARANGE                DataRange,
                                *pAvailableFormats;  // KSDATARANGE == KSDATAFORMAT
    PKS_DATARANGE_VIDEO         DataRangeVideoToVerify,
                                DataRangeVideo;
    PKS_BITMAPINFOHEADER        pbmiHeader, 
                                pbmiHeaderToVerify;
    ULONG                       FormatSize;
    BOOL                        MatchFound = FALSE;
    ULONG                       j;


    PAGED_CODE();

    Srb->Status = STATUS_SUCCESS;
    IntersectInfo = Srb->CommandData.IntersectInfo;
    DataRange = IntersectInfo->DataRange;
    DbgMsg2(("IntersectIfo->DataFormatBuffer=%x, size=%d\n", IntersectInfo->DataFormatBuffer, IntersectInfo->SizeOfDataFormatBuffer));


    //
    // Check that the stream number is valid
    // We support only one capture pin/stream (index 0)
    //

    if (IntersectInfo->StreamNumber >= 1) {

        Srb->Status = STATUS_NOT_IMPLEMENTED;
        ERROR_LOG(("\'AdapterFormatFromRange: StreamNumber(=%d) is not implemented.\n", IntersectInfo->StreamNumber));
        ASSERT(FALSE);
        return FALSE;
    }


    //
    // Get the pointer to the array of available formats
    //

    pAvailableFormats = &pDevExt->DCamStrmModes[0];


    //
    // Walk the formats supported by the stream searching for a match
    // of the three GUIDs which together define a DATARANGE
    //
    
    DataRangeVideoToVerify = (PKS_DATARANGE_VIDEO) DataRange;

    for (j = 0; j < pDevExt->ModeSupported; j++, pAvailableFormats++) {
       
        DataRangeVideo = (PKS_DATARANGE_VIDEO) *pAvailableFormats;

        //
        // STREAM_DATA_INTERSECT_INFO
        //  [IN]   ULONG        StreamNumber;
        //  [IN]   PKSDATARANGE DataRange;   
        //  [OUT]  PVOID        DataFormatBuffer;   // == PKS_DATAFORMAT_VIDEOINFOHEADER
        //  [OUT]  ULONG        SizeOfDataFormatBuffer;
        //
        
        //
        // KS_DATAFORMAT_VIDEOINFOHEADER:
        //    fields marked with 'm' must match; 
        //           marked with 'r' must within range;
        //           marked with 'f' is filled by us
        //
        //     KSDATAFORMAT == KSDATARANGE
        //       m ULONG   FormatSize;
        //         ULONG   Flags;
        //         ULONG   SampleSize;
        //         ULONG   Reserved;
        //       m GUID    MajorFormat;
        //       m GUID    SubFormat;
        //       m GUID    Specifier;.
        //  m  BOOL                         bFixedSizeSamples;      // all samples same size?
        //  m  BOOL                         bTemporalCompression;   // all I frames?
        //  m  DWORD                        StreamDescriptionFlags; // KS_VIDEO_DESC_*
        //  m  DWORD                        MemoryAllocationFlags;  // KS_VIDEO_ALLOC_*
        //  m  KS_VIDEO_STREAM_CONFIG_CAPS  ConfigCaps;
        //     KS_VIDEOINFOHEADER 
        //         RECT                rcSource;          // The bit we really want to use
        //         RECT                rcTarget;          // Where the video should go
        //         DWORD               dwBitRate;         // Approximate bit data rate
        //         DWORD               dwBitErrorRate;    // Bit error rate for this stream
        //     r/f REFERENCE_TIME      AvgTimePerFrame;   // Average time per frame (100ns units)
        //         KS_BITMAPINFOHEADER bmiHeader;
        //             DWORD      biSize;
        //       m     LONG       biWidth;
        //       m     LONG       biHeight;
        //             WORD       biPlanes;
        //       m     WORD       biBitCount;
        //       m     DWORD      biCompression;
        //       f     DWORD      biSizeImage;
        //             LONG       biXPelsPerMeter;
        //             LONG       biYPelsPerMeter;
        //             DWORD      biClrUsed;
        //             DWORD      biClrImportant;
        //     

        // Verify that it is a VIDEO format/range.
        if (!AdapterCompareGUIDsAndFormatSize((PKSDATARANGE)DataRangeVideoToVerify, (PKSDATARANGE)DataRangeVideo)) {
            continue;
        }
    
        //
        // It is valid video format/range; now 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;
        }

        //
        // We do not support scaling or cropping so the dimension 
        // (biWidth, biHeight, biBitCount and biCompression)
        // must match, and we will filled in the biSizeImage and others.
        // 
        pbmiHeader         = &DataRangeVideo->VideoInfoHeader.bmiHeader;
        pbmiHeaderToVerify = &DataRangeVideoToVerify->VideoInfoHeader.bmiHeader;

        if(pbmiHeader->biWidth       != pbmiHeaderToVerify->biWidth    ||
           abs(pbmiHeader->biHeight) != abs(pbmiHeaderToVerify->biHeight)  ||
           pbmiHeader->biBitCount    != pbmiHeaderToVerify->biBitCount ||
           pbmiHeader->biCompression != pbmiHeaderToVerify->biCompression
           ) {

            DbgMsg1(("AdapterFormatFromRange: Supported: %dx%dx%d [%x] != ToVerify: %dx%dx%d [%x]\n",
                    pbmiHeader->biWidth, pbmiHeader->biHeight,  pbmiHeader->biBitCount, pbmiHeader->biCompression,
                    pbmiHeaderToVerify->biWidth, pbmiHeaderToVerify->biHeight,  pbmiHeaderToVerify->biBitCount, pbmiHeaderToVerify->biCompression));
            continue;
        }


        // MATCH FOUND!
        MatchFound = TRUE; 
        


        // KS_DATAFORMAT_VIDEOINFOHEADER
        //    KSDATAFORMAT            DataFormat;
        //    KS_VIDEOINFOHEADER      VideoInfoHeader;

        //
        // intsafe version of 
        // FormatSize = sizeof (KSDATAFORMAT) +  KS_SIZE_VIDEOHEADER (&DataRangeVideo->VideoInfoHeader);
        //
        if (!NT_SUCCESS(RTL_SAFE_KS_SIZE_VIDEOHEADER(&DataRangeVideo->VideoInfoHeader, &FormatSize)) ||
            !NT_SUCCESS(RtlULongAdd(FormatSize, sizeof (KSDATAFORMAT), &FormatSize))) {

            Srb->Status = STATUS_INTEGER_OVERFLOW;
            return FALSE;
        }

        //    
        // 1st query:  Srb->ActualBytesTransferred = FormatSize
        //

        if(IntersectInfo->SizeOfDataFormatBuffer == 0) {

            Srb->Status = STATUS_BUFFER_OVERFLOW;
            // We actually have not returned this much data,
            // this "size" will be used by Ksproxy to send down 
            // a buffer of that size in next query.
            Srb->ActualBytesTransferred = FormatSize;
            break;
        }


        //
        // 2nd time: pass back the format information
        //

        if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
            Srb->Status = STATUS_BUFFER_TOO_SMALL;
            DbgMsg2(("IntersectInfo->SizeOfDataFormatBuffer=%d, FormatSize=%d\n", IntersectInfo->SizeOfDataFormatBuffer, FormatSize));
            return FALSE;
        }

        //
        // A match is found,  Copy from our supported/matched data range and set frame rate:
        // KS_DATAFORMAT_VIDEOINFOHEADER
        //    KSDATAFORMAT            DataFormat;
        //    KS_VIDEOINFOHEADER      VideoInfoHeader;
        //
        
        RtlCopyMemory(
            &((PKS_DATAFORMAT_VIDEOINFOHEADER)IntersectInfo->DataFormatBuffer)->DataFormat,
            &DataRangeVideo->DataRange,
            sizeof (KSDATAFORMAT));

        RtlCopyMemory(
            &((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader,  // KS_VIDEOINFOHEADER
            &DataRangeVideo->VideoInfoHeader,                                                      // KS_VIDEOINFOHEADER
            KS_SIZE_VIDEOHEADER (&DataRangeVideo->VideoInfoHeader));  // Use KS_SIZE_VIDEOHEADER() since this is variable size       

        //
        // Special atttention to these two fields: biSizeImage and AvgTimePerFrame.
        // We do not scale or stretch so biSizeImage is fixed.
        // However, AvgTimePerFrame (FrameRate) can/need to be within (ConfigCaps.MinFrameInterval, ConfigCaps.MaxFrameInterval)
        //

        if (DataRangeVideoToVerify->VideoInfoHeader.AvgTimePerFrame > DataRangeVideoToVerify->ConfigCaps.MaxFrameInterval ||      
            DataRangeVideoToVerify->VideoInfoHeader.AvgTimePerFrame < DataRangeVideoToVerify->ConfigCaps.MinFrameInterval) {
         
            ((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader.AvgTimePerFrame = 
                 DataRangeVideo->VideoInfoHeader.AvgTimePerFrame;
            DbgMsg2(("AdapterFormatFromRange: out of range; so set it to default (%ld)\n",DataRangeVideo->VideoInfoHeader.AvgTimePerFrame));
        } else {

            ((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader.AvgTimePerFrame = 
                  DataRangeVideoToVerify->VideoInfoHeader.AvgTimePerFrame;
        }

        ((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
        Srb->ActualBytesTransferred = FormatSize;

        DbgMsg2(("AdapterFormatFromRange: match found: [%x], %dx%dx%d=%d, AvgTimePerFrame %ld\n",
                pbmiHeader->biCompression, pbmiHeader->biWidth, pbmiHeader->biHeight,  pbmiHeader->biBitCount, pbmiHeader->biSizeImage,
                ((PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer)->VideoInfoHeader.AvgTimePerFrame));
        break;

    } // End of loop on all formats for this stream

    if(!MatchFound) {

        DbgMsg2(("AdapterFormatFromRange: No match !!\n"));
        Srb->Status = STATUS_NO_MATCH;
        return FALSE;
    }

    return TRUE;
}

BOOL
DCamBuildFormatTable(
    PDCAM_EXTENSION pDevExt,
    PIRB pIrb
    )
/*
    Description:

        Query Video format and mode supported by the camera.

    Return:

       TRUE: support at least one mode
       FALSE: failed to read mode register or do not support any mode.
*/
{
    // Initialize 
    pDevExt->ModeSupported = 0;

    if(DCamGetVideoMode(pDevExt, pIrb)) {

        //
        // Select preferred format (UYVY) first
        //

        // Mode1: 320x240 (4:2:2)
        if(pDevExt->DCamVModeInq0.VMode.Mode1 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode1 == 1) {
            pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_1;
            pDevExt->ModeSupported++;
        }

        // Mode3: 640x480 (4:2:2)
        if(pDevExt->DCamVModeInq0.VMode.Mode3 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode3 == 1) {
            pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_3;        
            pDevExt->ModeSupported++;
        }

#ifdef SUPPORT_YUV411
        // Mode2: 640x480 (4:1:1)
        if(pDevExt->DCamVModeInq0.VMode.Mode2 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode2 == 1) {
            pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_2;
            pDevExt->ModeSupported++;
        }
#endif

#ifdef SUPPORT_RGB24
        // Mode4: 640x480 (RGB24)
        if(pDevExt->DCamVModeInq0.VMode.Mode4 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode4 == 1) {
            pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_4;
            pDevExt->ModeSupported++;
        }
#endif

#ifdef SUPPORT_YUV444
        // Mode0: 160x120 (4:4:4)
        if(pDevExt->DCamVModeInq0.VMode.Mode0 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode0 == 1) {
            pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_0;
            pDevExt->ModeSupported++;
        }
#endif

#ifdef SUPPORT_YUV800
        // Mode5: 640x480 (Y800)
        if(pDevExt->DCamVModeInq0.VMode.Mode5 == 1 && pDevExt->DecoderDCamVModeInq0.VMode.Mode5 == 1) {
            pDevExt->DCamStrmModes[pDevExt->ModeSupported] = (PKSDATAFORMAT) &DCAM_StreamMode_5;
            pDevExt->ModeSupported++;
        }
#endif
    } 

    DbgMsg1(("\'Support %d modes; ->DCamStrmModes[]:%x\n", pDevExt->ModeSupported, &pDevExt->DCamStrmModes[0]));
    ASSERT(pDevExt->ModeSupported > 0);

    return (pDevEx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -