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

📄 dcampkt.c

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

--*/

{
    DCamRegArea RegArea;
    NTSTATUS status;
    LONG lRetries = MAX_READ_REG_RETRIES;


    // If a device is removed, it is not available.
    if(pDevExt->bDevRemoved)
        return TRUE;

    do {
        RegArea.AsULONG = 0;
        status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, IsoEnable), &(RegArea.AsULONG));
#if DBG
        if(!NT_SUCCESS(status))
            ERROR_LOG(("**** DCamDeviceInUse: Status %x, ISO_ENABLE %x\n", status, RegArea.AsULONG));
#endif
    } while (--lRetries > 0 && !NT_SUCCESS(status));

    if(NT_SUCCESS(status)) 
        return ((RegArea.AsULONG & ISO_ENABLE_BIT) == ISO_ENABLE_BIT);

    // failed to query the device.
    return TRUE;  // Assume it is in use.
}


VOID
DCamOpenStream(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )

/*++

Routine Description:

    Called when an OpenStream Srb request is received

Arguments:

    pSrb - Pointer to Stream request block

Return Value:

    Nothing

--*/

{

    PIRB Irb;
    ULONG nSize;
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX pStrmEx;
    PKS_DATAFORMAT_VIDEOINFOHEADER  pKSDataFormat = 
                (PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
    PKS_VIDEOINFOHEADER     pVideoInfoHdrRequested = 
                &pKSDataFormat->VideoInfoHeader;


    PAGED_CODE();

    Irb = (PIRB) pSrb->SRBExtension;
    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;

    DbgMsg2(("\'DCamOpenStream: >>> !!! pDevEx %x; pStrmEx %x !!!\n", pDevExt, pStrmEx));


    //
    // Cache the stream extension.
    //

    pDevExt->pStrmEx = pStrmEx; 


    //
    // default to success
    //

    pSrb->Status = STATUS_SUCCESS;

    //
    // determine which stream number is being opened.  This number indicates
    // the offset into the array of streaminfo structures that was filled out
    // in the AdapterStreamInfo call.
    //
    // So:
    //   0 - Video data from camera
    //

    switch (pSrb->StreamObject->StreamNumber) {

    case 0:

         //
         // Make sure that this device is not in used 
         //
         if(DCamDeviceInUse(Irb, pDevExt)) {
             ERROR_LOG(("Device is in used! Open Stream fail!!\n"));
             pDevExt->pStrmEx = NULL; 
             pSrb->Status = STATUS_UNSUCCESSFUL;
             return;
         }


         //
         // Figure out what format they're trying to open first
         //

         if (!AdapterVerifyFormat (pDevExt->ModeSupported, pDevExt->DCamStrmModes, pKSDataFormat, pSrb->StreamObject->StreamNumber)) {
             pDevExt->pStrmEx = NULL; 
             ERROR_LOG(("DCamOpenStream: AdapterVerifyFormat failed.\n"));
             pSrb->Status = STATUS_INVALID_PARAMETER;
             return;
         }

         InitializeStreamExtension(pDevExt, pSrb->StreamObject, pStrmEx);

         // It should already been freed by DCamCloseStream()
         ASSERT(pStrmEx->pVideoInfoHeader == NULL);
         ASSERT(pVideoInfoHdrRequested != (PKS_VIDEOINFOHEADER) 0);

         // Use this instead of sizeof(KS_VIDEOINFOHEADER) to handle variable size structure
         nSize = KS_SIZE_VIDEOHEADER (pVideoInfoHdrRequested);

         pStrmEx->pVideoInfoHeader = ExAllocatePoolWithTag(NonPagedPool, nSize, 'macd');
         if (pStrmEx->pVideoInfoHeader == NULL) {

             ERROR_LOG(("DCamOpenStream: ExAllocatePool (->pVideoInfoHeader) failed!\n"));
             ASSERT(pStrmEx->pVideoInfoHeader != NULL);

             pDevExt->pStrmEx = NULL;

             pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
             return;
         }

         // Copy the VIDEOINFOHEADER requested to our storage
         RtlCopyMemory(
                    pStrmEx->pVideoInfoHeader,
                    pVideoInfoHdrRequested,
                    nSize);

         DbgMsg3(("\'DCamOpenStream: Copied biSizeImage=%d Duration=%ld (100ns)\n", 
                    pStrmEx->pVideoInfoHeader->bmiHeader.biSizeImage, (DWORD) pStrmEx->pVideoInfoHeader->AvgTimePerFrame));

         // Allocate ISOCH resource
         pSrb->Status = DCamAllocateIsochResource(pDevExt, pSrb->SRBExtension, TRUE);               
         
         if (pSrb->Status) {

             ERROR_LOG(("DCamOpenStream: !!!! Allocate ISOCH resource failed.  CanNOT STREAM!!!!!\n"));
             
             ExFreePool(pStrmEx->pVideoInfoHeader);
             pStrmEx->pVideoInfoHeader = NULL;             
             pDevExt->pStrmEx = NULL;
             pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;             
             return;
         } 

         pSrb->StreamObject->ReceiveDataPacket    = (PVOID) DCamReceiveDataPacket;
         pSrb->StreamObject->ReceiveControlPacket = (PVOID) DCamReceiveCtrlPacket;

         // If bus reset failed and user close the stream and reopen the stream successfully,
         // This must be reset !!
         if(pDevExt->bDevRemoved || pDevExt->bStopIsochCallback) {
            DbgMsg1(("Stream Open successful, reset bDevRemoved and bStopCallback!!\n"));
            pDevExt->bStopIsochCallback = FALSE;
            pDevExt->bDevRemoved = FALSE;
         }

         //
         // initialize the stream extension data handling information
         //

         break;

    default:
         ERROR_LOG(("DCamOpenStream: Hit a non-support pSrb->StreamObject->StreamNumber (%d).\n", pSrb->StreamObject->StreamNumber));
         ASSERT(FALSE);
         pDevExt->pStrmEx = NULL; 
         pSrb->Status = STATUS_INVALID_PARAMETER;
         return;
    }


    pSrb->StreamObject->HwClockObject.ClockSupportFlags = 0;

    // We don't use DMA.
    pSrb->StreamObject->Dma = FALSE;
    pSrb->StreamObject->StreamHeaderMediaSpecific = sizeof(KS_FRAME_INFO);

    //
    // The PIO flag must be set when the mini driver will be accessing the data
    // buffers passed in using logical addressing.  We are not going to touch these 
    // buffer at all.
    //
    pSrb->StreamObject->Pio = FALSE;


    //
    // Set to last saved configuration
    //
    SetCurrentDevicePropertyValues(pDevExt, (PIRB) pSrb->SRBExtension);


    DbgMsg1((" #OPEN_STREAM#: %s DCam, Status %x, pDevExt %x, pStrmEx %x, IsochDescriptorList is at %x\n", 
              pDevExt->pchVendorName, pSrb->Status, pDevExt, pDevExt->pStrmEx, &pDevExt->IsochDescriptorList));

    ASSERT(pSrb->Status == STATUS_SUCCESS);

}




VOID
DCamCloseStream(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
/*++

Routine Description:

    Called when an CloseStream Srb request is received.  We get this when calling user 
    application do a CloseHandle() on the pin connection handle.  This can happen after
    HwUninitialize().

Arguments:

    pSrb - Pointer to Stream request block

Return Value:

    Nothing

--*/
{
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX     pStrmEx;
    PIRB pIrb;

    PAGED_CODE();

    pSrb->Status = STATUS_SUCCESS;

    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    ASSERT(pDevExt);      
    if(!pDevExt) {
        StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
        return;
    }

    pStrmEx = (PSTREAMEX)pDevExt->pStrmEx;
    ASSERT(pStrmEx);
    if(!pStrmEx ) {
        StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
        return;    
    } 

    //
    // pDevExt->Irb might have been freed in HwUninitialize() 
    // due to Surprise removal; so we must use this:
    // 
    pIrb = (PIRB) pSrb->SRBExtension;


    //
    // If it is still in use (setting it to stop failed?),
    // we will diable ISO_ENABLE so other application can use it.
    //

    if(!pDevExt->bDevRemoved && 
       DCamDeviceInUse(pIrb, pDevExt)) {

        DbgMsg1(("DCamCloseStream: Is still in use! Disable it!\n"));
        // Disable EnableISO
        DCamIsoEnable(pIrb, pDevExt, FALSE);
    }


    //
    // Save current state and free resource alllocaed in OpenStream()
    //
    DCamSetPropertyValuesToRegistry(pDevExt);


    //
    // Free Isoch resource and master clock
    //

    DCamFreeIsochResource (pDevExt, pIrb, TRUE);
    if(pStrmEx->pVideoInfoHeader) {
        ExFreePool(pStrmEx->pVideoInfoHeader);
        pStrmEx->pVideoInfoHeader = NULL;
    }

    pStrmEx->hMasterClock = 0;
   

    //                                                 
    // If there are pening read, cancel them all.                                
    //
    if(pDevExt->PendingReadCount > 0) {

        DCamCancelAllPackets(
            pSrb,
            pDevExt,
            &pDevExt->PendingReadCount
            );
        
        pDevExt->pStrmEx = 0;

        return;  // SRB completed in CancelAllPackets       
    }
    
    pDevExt->pStrmEx = 0;

    StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);

}




VOID
DCamTimeoutHandler(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
/*++

Routine Description:

    This routine is called when a packet has been in the minidriver too long (Srb->TimeoutCounter == 0).
    We will cancel the SRB if we are in the RUN state; else set ->TimeoutCounter and return.
    We assume the cancel SRB is serialized and in the same order as it is read.  So this timeout is
    applying to the head of the queue.

Arguments:

    pSrb - Pointer to Stream request block that has timeout.

Return Value:

    Nothing

--*/

{
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX pStrmEx;

    // Called from StreamClass at DisptchLevel


    //
    // We only expect stream SRB, but not device SRB.  
    //

    if ( (pSrb->Flags & SRB_HW_FLAGS_STREAM_REQUEST) != SRB_HW_FLAGS_STREAM_REQUEST) {
        ERROR_LOG(("DCamTimeoutHandler: Device SRB %x (cmd:%x) timed out!\n", pSrb, pSrb->Command));
        return;
    } 


    //
    // StreamSRB only valid if we have a stream extension
    //

    pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
    ASSERT(pDevExt);
    pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;

    if(!pStrmEx) {
        ERROR_LOG(("DCamTimeoutHandler: Stream SRB %x timeout with pDevExt %x, pStrmEx %x\n", pSrb, pDevExt, pStrmEx));
        ASSERT(pStrmEx);
        return;
    }
 
    //
    // Cancel IRP only if in RUN state, BUT...
    // Note: if we are TIMEOUT and in RUN state, something is terribley wrong.  
    //       but I guess that can happen when it is being suspended;
    //       so we will extend the time out for all states.
    //

    DbgMsg2(("\'DCamTimeoutHandler: pSrb %x, %s state, PendingReadCount %d.\n", 
        pSrb, 
        pStrmEx->KSState == KSSTATE_RUN   ? "RUN" : 
        pStrmEx->KSState == KSSTATE_PAUSE ? "PAUSE":
        pStrmEx->KSState == KSSTATE_STOP  ? "STOP": "Unknown",
        pDevExt->PendingReadCount));   

    // ASSERT(pStrmEx->KSState == KSSTATE_PAUSE);


    //
    // Reset Timeout counter, or we are going to get this call immediately.
    //

    pSrb->TimeoutCounter = pSrb->TimeoutOriginal;

}


NTSTATUS
DCamStartListenCR(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
    IN PDCAM_IO_CONTEXT pDCamIoContext    
    )

⌨️ 快捷键说明

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