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

📄 capmain.c

📁 一个视频采集驱动程序的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    // the stream extension structure is allocated by the stream class driver
    //

    PSTREAMEX               pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
    PHW_DEVICE_EXTENSION    pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
    int                     StreamNumber = pSrb->StreamObject->StreamNumber;
    PKSDATAFORMAT           pKSDataFormat = pSrb->CommandData.OpenFormat;


    RtlZeroMemory(pStrmEx, sizeof(STREAMEX));

    DbgLogInfo(("TestCap: ------- ADAPTEROPENSTREAM ------- StreamNumber=%d\n", StreamNumber));

    //
    // check that the stream index requested isn't too high
    // or that the maximum number of instances hasn't been exceeded
    //

    if (StreamNumber >= DRIVER_STREAM_COUNT || StreamNumber < 0) {

        pSrb->Status = STATUS_INVALID_PARAMETER;

        return;
    }

    //
    // Check that we haven't exceeded the instance count for this stream
    //

    if (pHwDevExt->ActualInstances[StreamNumber] >=
        Streams[StreamNumber].hwStreamInfo.NumberOfPossibleInstances) {

        pSrb->Status = STATUS_INVALID_PARAMETER;

        return;
    }

    //
    // Check the validity of the format being requested
    //

    if (!AdapterVerifyFormat (pKSDataFormat, StreamNumber)) {

        pSrb->Status = STATUS_INVALID_PARAMETER;

        return;
    }

    //
    // And set the format for the stream
    //

    if (!VideoSetFormat (pSrb)) {

        return;
    }

    ASSERT (pHwDevExt->pStrmEx [StreamNumber] == NULL);

    // Maintain an array of all the StreamEx structures in the HwDevExt
    // so that we can cancel IRPs from any stream

    pHwDevExt->pStrmEx [StreamNumber] = (PSTREAMX) pStrmEx;

    // Set up pointers to the handlers for the stream data and control handlers

    pSrb->StreamObject->ReceiveDataPacket =
            (PVOID) Streams[StreamNumber].hwStreamObject.ReceiveDataPacket;
    pSrb->StreamObject->ReceiveControlPacket =
            (PVOID) Streams[StreamNumber].hwStreamObject.ReceiveControlPacket;

    //
    // The DMA flag must be set when the device will be performing DMA directly
    // to the data buffer addresses passed in to the ReceiceDataPacket routines.
    //

    pSrb->StreamObject->Dma = Streams[StreamNumber].hwStreamObject.Dma;

    //
    // The PIO flag must be set when the mini driver will be accessing the data
    // buffers passed in using logical addressing
    //

    pSrb->StreamObject->Pio = Streams[StreamNumber].hwStreamObject.Pio;

    //
    // How many extra bytes will be passed up from the driver for each frame?
    //

    pSrb->StreamObject->StreamHeaderMediaSpecific =
                Streams[StreamNumber].hwStreamObject.StreamHeaderMediaSpecific;

    pSrb->StreamObject->StreamHeaderWorkspace =
                Streams[StreamNumber].hwStreamObject.StreamHeaderWorkspace;

    //
    // Indicate the clock support available on this stream
    //

    pSrb->StreamObject->HwClockObject =
                Streams[StreamNumber].hwStreamObject.HwClockObject;

    //
    // Increment the instance count on this stream
    //
    pHwDevExt->ActualInstances[StreamNumber]++;


    // Retain a private copy of the HwDevExt and StreamObject in the stream extension
    // so we can use a timer

    pStrmEx->pHwDevExt = pHwDevExt;                     // For timer use
    pStrmEx->pStreamObject = pSrb->StreamObject;        // For timer use

    // Initialize the compression settings
    // These may have been changed from the default values in the HwDevExt
    // before the stream was opened
    pStrmEx->CompressionSettings.CompressionKeyFrameRate =
        pHwDevExt->CompressionSettings.CompressionKeyFrameRate;
    pStrmEx->CompressionSettings.CompressionPFramesPerKeyFrame =
        pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame;
    pStrmEx->CompressionSettings.CompressionQuality =
        pHwDevExt->CompressionSettings.CompressionQuality;

    // Init VideoControl properties
    pStrmEx->VideoControlMode = pHwDevExt->VideoControlMode;

    // Init VBI variables
    pStrmEx->SentVBIInfoHeader = 0;

    DbgLogInfo(("TestCap: AdapterOpenStream Exit\n"));

}

/*
** AdapterCloseStream()
**
**   Close the requested data stream.
**
**   Note that a stream could be closed arbitrarily in the midst of streaming
**   if a user mode app crashes.  Therefore, you must release all outstanding
**   resources, disable interrupts, complete all pending SRBs, and put the
**   stream back into a quiescent condition.
**
** Arguments:
**
**   pSrb the request block requesting to close the stream
**
** Returns:
**
** Side Effects:  none
*/

VOID
STREAMAPI
AdapterCloseStream (
    PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    PSTREAMEX               pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
    PHW_DEVICE_EXTENSION    pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
    int                     StreamNumber = pSrb->StreamObject->StreamNumber;
    PKSDATAFORMAT           pKSDataFormat = pSrb->CommandData.OpenFormat;
    KS_VIDEOINFOHEADER      *pVideoInfoHdr = pStrmEx->pVideoInfoHeader;

    DbgLogInfo(("TestCap: -------- ADAPTERCLOSESTREAM ------ StreamNumber=%d\n", StreamNumber));

    if (pHwDevExt->StreamSRBListSize > 0) {
        VideoQueueCancelAllSRBs (pStrmEx);
        DbgLogError(("TestCap: Outstanding SRBs at stream close!!!\n"));
    }

    pHwDevExt->ActualInstances[StreamNumber]--;

    ASSERT (pHwDevExt->pStrmEx [StreamNumber] != 0);

    pHwDevExt->pStrmEx [StreamNumber] = 0;

    //
    // the minidriver should free any resources that were allocate at
    // open stream time etc.
    //

    // Free the variable length VIDEOINFOHEADER

    if (pVideoInfoHdr) {
        ExFreePool(pVideoInfoHdr);
        pStrmEx->pVideoInfoHeader = NULL;
    }

    // Make sure we no longer reference the clock
    pStrmEx->hMasterClock = NULL;

    // Make sure the state is reset to stopped,
    pStrmEx->KSState = KSSTATE_STOP;

}


/*
** AdapterStreamInfo()
**
**   Returns the information of all streams that are supported by the
**   mini-driver
**
** Arguments:
**
**   pSrb - Pointer to the STREAM_REQUEST_BLOCK
**        pSrb->HwDeviceExtension - will be the hardware device extension for
**                                  as initialised in HwInitialise
**
** Returns:
**
** Side Effects:  none
*/

VOID
STREAMAPI
AdapterStreamInfo (
    PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    int j;

    PHW_DEVICE_EXTENSION pHwDevExt =
        ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);

    //
    // pick up the pointer to header which preceeds the stream info structs
    //

    PHW_STREAM_HEADER pstrhdr =
            (PHW_STREAM_HEADER)&(pSrb->CommandData.StreamBuffer->StreamHeader);

     //
     // pick up the pointer to the array of stream information data structures
     //

     PHW_STREAM_INFORMATION pstrinfo =
            (PHW_STREAM_INFORMATION)&(pSrb->CommandData.StreamBuffer->StreamInfo);


    //
    // verify that the buffer is large enough to hold our return data
    //

    DEBUG_ASSERT (pSrb->NumberOfBytesToTransfer >=
            sizeof (HW_STREAM_HEADER) +
            sizeof (HW_STREAM_INFORMATION) * DRIVER_STREAM_COUNT);

    // Ugliness.  To allow mulitple instances, modify the pointer to the
    // AnalogVideoMedium and save it in our device extension

    Streams[STREAM_AnalogVideoInput].hwStreamInfo.Mediums =
           &pHwDevExt->AnalogVideoInputMedium;
    // pHwDevExt->AnalogVideoInputMedium = CrossbarMediums[9];
    // pHwDevExt->AnalogVideoInputMedium.Id = pHwDevExt->DriverMediumInstanceCount;

     //
     // Set the header
     //

     StreamHeader.NumDevPropArrayEntries = NUMBER_OF_ADAPTER_PROPERTY_SETS;
     StreamHeader.DevicePropertiesArray = (PKSPROPERTY_SET) AdapterPropertyTable;
     *pstrhdr = StreamHeader;

     //
     // stuff the contents of each HW_STREAM_INFORMATION struct
     //

     for (j = 0; j < DRIVER_STREAM_COUNT; j++) {
        *pstrinfo++ = Streams[j].hwStreamInfo;
     }

}


/*
** AdapterReceivePacket()
**
**   Main entry point for receiving adapter based request SRBs.  This routine
**   will always be called at Passive level.
**
**   Note: This is an asyncronous entry point.  The request does not necessarily
**         complete on return from this function, the request only completes when a
**         StreamClassDeviceNotification on this request block, of type
**         DeviceRequestComplete, is issued.
**
** Arguments:
**
**   pSrb - Pointer to the STREAM_REQUEST_BLOCK
**        pSrb->HwDeviceExtension - will be the hardware device extension for
**                                  as initialised in HwInitialise
**
** Returns:
**
** Side Effects:  none
*/

VOID
STREAMAPI
AdapterReceivePacket(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    PHW_DEVICE_EXTENSION    pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
    BOOL                    Busy;

    DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    DbgLogTrace(("TestCap: Receiving Adapter  SRB %8x, %x\n", pSrb, pSrb->Command));

    // The very first time through, we need to initialize the adapter spinlock
    // and queue
    if (!pHwDevExt->AdapterQueueInitialized) {
        InitializeListHead (&pHwDevExt->AdapterSRBList);
        KeInitializeSpinLock (&pHwDevExt->AdapterSpinLock);
        pHwDevExt->AdapterQueueInitialized = TRUE;
        pHwDevExt->ProcessingAdapterSRB = FALSE;
    }

    //
    // If we're already processing an SRB, add it to the queue
    //
    Busy = AddToListIfBusy (
                    pSrb,
                    &pHwDevExt->AdapterSpinLock,
                    &pHwDevExt->ProcessingAdapterSRB,
                    &pHwDevExt->AdapterSRBList);

    if (Busy) {
        return;
    }

    //
    // This will run until the queue is empty
    //
    while (TRUE) {
        //
        // Assume success
        //
        pSrb->Status = STATUS_SUCCESS;

        //
        // determine the type of packet.
        //

        switch (pSrb->Command)
        {

        case SRB_INITIALIZE_DEVICE:

            // open the device

            HwInitialize(pSrb);

            break;

        case SRB_UNINITIALIZE_DEVICE:

            // close the device.

            HwUnInitialize(pSrb);

            break;

        case SRB_OPEN_STREAM:

            // open a stream

            AdapterOpenStream(pSrb);

            break;

        case SRB_CLOSE_STREAM:

            // close a stream

            AdapterCloseStream(pSrb);

            break;

        case SRB_GET_STREAM_INFO:

            //
            // return a block describing all the streams
            //

            AdapterStreamInfo(pSrb);

            break;

        case SRB_GET_DATA_INTERSECTION:

            //
            // Return a format, given a range
            //

            AdapterFormatFromRange(pSrb);

            break;

        case SRB_OPEN_DEVICE_INSTANCE:
        case SRB_CLOSE_DEVICE_INSTANCE:

            //
            // We should never get these since this is a single instance device
            //

            TRAP;
            pSrb->Status = STATUS_NOT_IMPLEMENTED;
            break;

        case SRB_GET_DEVICE_PROPERTY:

            //
            // Get adapter wide properties
            //

            AdapterGetProperty (pSrb);
            break;

        case SRB_SET_DEVICE_PROPERTY:

            //
            // Set adapter wide properties

⌨️ 快捷键说明

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