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

📄 dcampkt.c

📁 a sample WDM stream class video capture driver that supports two IEEE 1394 digital cameras. The sam
💻 C
📖 第 1 页 / 共 5 页
字号:

/*++

Routine Description:

    Returns more processing required so the IO Manager will leave us alone

Arguments:

    DriverObject - Pointer to driver object created by system.

    pIrp - Irp that just completed

    pDCamIoContext - Context 

Return Value:

    None.

--*/

{
    PDCAM_EXTENSION pDevExt;
    NTSTATUS Status;
    PIRB pIrb; 
    PIO_STACK_LOCATION NextIrpStack;

#ifdef WAIT_FOR_SLOW_DEVICE
    KeStallExecutionProcessor(5000);  // 5 msec
#endif

    DbgMsg2(("\'DCamStartListenCR: pIrp->IoStatus.Status=%x\n", pIrp->IoStatus.Status));

    if(STATUS_SUCCESS != pIrp->IoStatus.Status) {

        pDevExt = pDCamIoContext->pDevExt;
        pIrb = pDCamIoContext->pIrb;

        if(pDevExt->lRetries > 0) {

            pDevExt->lRetries--;
            DbgMsg1(("DCamStartListenCR: Try DCAM_RUNSTATE_SET_REQUEST_ISOCH_LISTEN again!\n"));
            
            pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN;
            pIrb->Flags = 0;
            pIrb->u.IsochListen.hResource = pDevExt->hResource;
            pIrb->u.IsochListen.fulFlags = 0;

            NextIrpStack = IoGetNextIrpStackLocation(pIrp);
            NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
            NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
            NextIrpStack->Parameters.Others.Argument1 = pIrb;

            IoSetCompletionRoutine(
                pIrp,
                DCamStartListenCR,
                pDCamIoContext,
                TRUE,
                TRUE,
                TRUE
                );

            Status =
                IoCallDriver(
                    pDevExt->BusDeviceObject, 
                    pIrp);

            return STATUS_MORE_PROCESSING_REQUIRED;

        } else {
            ERROR_LOG(("Start Listening has failed Status=%x; try again in next read.\n", pIrp->IoStatus.Status)); 
            pDCamIoContext->pDevExt->bNeedToListen = TRUE;
        }
    }

    DCamFreeIrbIrpAndContext(pDCamIoContext, pDCamIoContext->pIrb, pIrp);

    // No StreamClassDeviceNotification() here since 
    // this is local initiated Irb (as part of AttachBufferCR().

    return STATUS_MORE_PROCESSING_REQUIRED;

}





/*
** AdapterCompareGUIDsAndFormatSize()
**
**   Checks for a match on the three GUIDs and FormatSize
**
** Arguments:
**
**         IN DataRange1
**         IN DataRange2
**
** Returns:
** 
**   TRUE if all elements match
**   FALSE if any are different
**
** Side Effects:  none
*/

BOOL 
AdapterCompareGUIDsAndFormatSize(
    IN PKSDATARANGE DataRange1,
    IN PKSDATARANGE DataRange2)
{
    PAGED_CODE();

    return (
        IsEqualGUID (
            &DataRange1->MajorFormat, 
            &DataRange2->MajorFormat) &&
        IsEqualGUID (
            &DataRange1->SubFormat, 
            &DataRange2->SubFormat) &&
        IsEqualGUID (
            &DataRange1->Specifier, 
            &DataRange2->Specifier) &&
        (DataRange1->FormatSize == DataRange2->FormatSize));
}

/*
** AdapterVerifyFormat()
**
**   Checks the validity of a format request by walking through the
**       array of supported PKSDATARANGEs for a given stream.
**
** Arguments:
**
**   pKSDataFormatVideoToVerify - pointer of a KS_DATAFORMAT_VIDEOINFOHEADER structure.
**   StreamNumber - index of the stream being queried / opened.
**
** Returns:
** 
**   TRUE if the format is supported
**   FALSE if the format cannot be suppored
**
** Side Effects:  none
*/

BOOL 
AdapterVerifyFormat(
    ULONG VideoModesSupported,
    PKSDATAFORMAT  *pDCamStrmModesSupported,
    PKS_DATAFORMAT_VIDEOINFOHEADER pDataFormatVideoToVerify, 
    int StreamNumber)
{
    PKS_VIDEOINFOHEADER         pVideoInfoHdrToVerify = &pDataFormatVideoToVerify->VideoInfoHeader;
    PKSDATAFORMAT               *paDataFormatsVideoAvail;  // an array of PKSDATAFORMAT (not PKS_DATARANGE_VIDEO !!)
    PKS_DATARANGE_VIDEO         pDataRangeVideo;
    KS_VIDEO_STREAM_CONFIG_CAPS *pConfigCaps; 
    PKS_BITMAPINFOHEADER        pbmiHeader, 
                                pbmiHeaderToVerify;
    int                         j;

    PAGED_CODE();
    
    //
    // Make sure the stream index is valid
    // We only has one capure pin/stream (index 0).
    //
    if (StreamNumber >= 1) {
        return FALSE;
    }

    //
    // Get the pointer to the array of available formats
    //
    paDataFormatsVideoAvail = &pDCamStrmModesSupported[0]; // &pDevExt->DCamStrmModes[0];


    //
    // Walk the array, searching for a match
    //
    for (j = 0; j < (LONG) VideoModesSupported; j++, paDataFormatsVideoAvail++) {

        pDataRangeVideo = (PKS_DATARANGE_VIDEO) *paDataFormatsVideoAvail;
        
        //
        // Check for matching size, Major Type, Sub Type, and Specifier
        //

        //
        // Check for matching size, Major Type, Sub Type, and Specifier
        //

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

        if (!IsEqualGUID (&pDataRangeVideo->DataRange.SubFormat, 
            &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(

⌨️ 快捷键说明

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