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

📄 wdmvdec.cpp

📁 传说中的 视频抓取驱动源码 啊啊啊啊啊啊啊啊啊啊啊啊啊
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//==========================================================================;
//
//  WDM Video Decoder common SRB dispatcher
//
//      $Date:   02 Oct 1998 23:00:24  $
//  $Revision:   1.2  $
//    $Author:   KLEBANOV  $
//
// $Copyright:  (c) 1997 - 1998  ATI Technologies Inc.  All Rights Reserved.  $
//
//==========================================================================;

extern "C"
{
#include "strmini.h"
#include "ksmedia.h"
}


#include "wdmvdec.h"
#include "wdmdrv.h"
#include "capdebug.h"
#include "VidStrm.h"

#include "DecProp.h"
#include "StrmInfo.h"

#include "Mediums.h"
#include "mytypes.h"

extern NTSTATUS STREAMAPI DeviceEventProc( PHW_EVENT_DESCRIPTOR pEventDescriptor);

CWDMVideoDecoder::CWDMVideoDecoder(PPORT_CONFIGURATION_INFORMATION pConfigInfo,
                                   CVideoDecoderDevice* pDevice)
    :   m_pDeviceObject(pConfigInfo->RealPhysicalDeviceObject),
        m_CDecoderVPort(pConfigInfo->RealPhysicalDeviceObject),
        m_pDevice(pDevice),
        m_TVTunerChangedSrb( NULL)
{
    DBGTRACE(("CWDMVideoDecoder:CWDMVideoDecoder() enter\n"));
    DBGINFO(("Physical Device Object = %lx\n", m_pDeviceObject));

    pConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) +
            NumStreams * sizeof (HW_STREAM_INFORMATION);

    InitializeListHead(&m_srbQueue);
    KeInitializeSpinLock(&m_spinLock);
    m_bSrbInProcess = FALSE;
        if (pDevice)
        {
            pDevice->SetVideoDecoder(this);
        }
}


CWDMVideoDecoder::~CWDMVideoDecoder()
{

    DBGTRACE(("CWDMVideoDecoder:~CWDMVideoDecoder()\n"));
}


void CWDMVideoDecoder::ReceivePacket(PHW_STREAM_REQUEST_BLOCK pSrb)
{
    KIRQL Irql;
    PSRB_DATA_EXTENSION pSrbExt;

    KeAcquireSpinLock(&m_spinLock, &Irql);
    if (m_bSrbInProcess)
    {
        pSrbExt = (PSRB_DATA_EXTENSION)pSrb->SRBExtension;
        pSrbExt->pSrb = pSrb;
        InsertTailList(&m_srbQueue, &pSrbExt->srbListEntry);
        KeReleaseSpinLock(&m_spinLock, Irql);
        return;
    }

    m_bSrbInProcess = TRUE;
    KeReleaseSpinLock(&m_spinLock, Irql);


    for (;;) {

        // Assume success. Might be changed below

        pSrb->Status = STATUS_SUCCESS;
        BOOL notify = TRUE;
        
        // determine the type of packet.
        switch(pSrb->Command)
        {
            case SRB_INITIALIZATION_COMPLETE:
                DBGTRACE(("SRB_INITIALIZATION_COMPLETE; SRB=%x\n", pSrb));

                // Stream class has finished initialization.
                // Now create DShow Medium interface BLOBs.
                // This needs to be done at low priority since it uses the registry
                //
                // Do we need to worry about synchronization here?

                SrbInitializationComplete(pSrb);
                break;
            case SRB_UNINITIALIZE_DEVICE:
                DBGTRACE(("SRB_UNINITIALIZE_DEVICE; SRB=%x\n", pSrb));
                // close the device.  

                break;
            case SRB_PAGING_OUT_DRIVER:
                DBGTRACE(("SRB_PAGING_OUT_DRIVER; SRB=%x\n", pSrb));
                //
                // The driver is being paged out
                // Disable Interrupts if you have them!
                //
                break;
            case SRB_CHANGE_POWER_STATE:
                DBGTRACE(("SRB_CHANGE_POWER_STATE. SRB=%x. State=%d\n",
                                                pSrb, pSrb->CommandData.DeviceState));

                SrbChangePowerState(pSrb);
                break;
    
            case SRB_OPEN_STREAM:
                DBGTRACE(("SRB_OPEN_STREAM; SRB=%x\n", pSrb));

                SrbOpenStream(pSrb);
                break;

            case SRB_CLOSE_STREAM:
                DBGTRACE(("SRB_CLOSE_STREAM; SRB=%x\n", pSrb));

                if (!IsListEmpty(&m_srbQueue))  // is this necessary ???
                {
                    TRAP();
                }

                SrbCloseStream(pSrb);
                break;
            case SRB_GET_DATA_INTERSECTION:
                DBGTRACE(("SRB_GET_DATA_INTERSECTION; SRB=%x\n", pSrb));

                SrbGetDataIntersection(pSrb);
                break;

            case SRB_GET_STREAM_INFO:
                SrbGetStreamInfo(pSrb);
                break;

            case SRB_GET_DEVICE_PROPERTY:
                SrbGetProperty(pSrb);
                break;        

            case SRB_SET_DEVICE_PROPERTY:
                SrbSetProperty(pSrb);
                break;

            case SRB_WRITE_DATA:

                DBGTRACE(("SRB_WRITE_DATA; SRB=%x\n", pSrb));

                SetTunerInfo(pSrb);
                StreamClassStreamNotification(StreamRequestComplete, pSrb->StreamObject, pSrb);
                notify = FALSE;
                break;

            case SRB_UNKNOWN_DEVICE_COMMAND:
                // not sure why this gets called every time.
                DBGTRACE(("SRB_UNKNOWN_DEVICE_COMMAND; SRB=%x\n", pSrb));

                // TRAP()();
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
                break;

            case SRB_OPEN_DEVICE_INSTANCE:
            case SRB_CLOSE_DEVICE_INSTANCE:
            default:
                TRAP();
                // this is a request that we do not understand.  Indicate invalid command and complete the request
                pSrb->Status = STATUS_NOT_IMPLEMENTED;
        }

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

        KeAcquireSpinLock(&m_spinLock, &Irql);
        if (IsListEmpty(&m_srbQueue))
        {
            m_bSrbInProcess = FALSE;
            KeReleaseSpinLock(&m_spinLock, Irql);
            return;
        }
        else
        {
            pSrbExt = (PSRB_DATA_EXTENSION)RemoveHeadList(&m_srbQueue);
            KeReleaseSpinLock(&m_spinLock, Irql);
            pSrb = pSrbExt->pSrb;
        }
    }
}


void CWDMVideoDecoder::CancelPacket( PHW_STREAM_REQUEST_BLOCK pSrbToCancel)
{
    CWDMVideoStream*    pVideoStream = ( CWDMVideoStream*)pSrbToCancel->StreamObject->HwStreamExtension;
 
    DBGINFO(( "Bt829: AdapterCancelPacket, Starting attempting to cancel Srb 0x%x\n",
        pSrbToCancel));

    if( pVideoStream == NULL)
    {
        //
        // Device command IRPs are not queued, so nothing to do
        //
        DBGINFO(( "Bt829: AdapterCancelPacketStart, no pVideoStream Srb 0x%x\n",
            pSrbToCancel));

        return;
    } 

    pVideoStream->CancelPacket( pSrbToCancel);

    DBGINFO(( "Bt829: AdapterCancelPacket, Exiting\n"));
}



void CWDMVideoDecoder::TimeoutPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
{
    CWDMVideoStream * pVideoStream = (CWDMVideoStream *)pSrb->StreamObject->HwStreamExtension;

    DBGTRACE(("Timeout. SRB %8x. \n", pSrb));
    pVideoStream->TimeoutPacket(pSrb);

    DBGTRACE(("TimeoutPacket: SRB %8x. Resetting.\n", pSrb));
    pSrb->TimeoutCounter = pSrb->TimeoutOriginal;
}


BOOL CWDMVideoDecoder::SrbInitializationComplete(PHW_STREAM_REQUEST_BLOCK pSrb)
{
    NTSTATUS                Status;
    ULONG *tmp = (ULONG *) &CrossbarPinDirection[0];

    // Create the Registry blobs that DShow uses to create
    // graphs via Mediums

    Status = StreamClassRegisterFilterWithNoKSPins (
                    m_pDeviceObject,                    // IN PDEVICE_OBJECT   DeviceObject,
                    &KSCATEGORY_CROSSBAR,               // IN GUID           * InterfaceClassGUID,
                    CrossbarPins(),     // IN ULONG            PinCount,
                    (int *) CrossbarPinDirection,       // IN ULONG          * Flags,
                    (KSPIN_MEDIUM *) CrossbarMediums,   // IN KSPIN_MEDIUM   * MediumList,
                    NULL                                // IN GUID           * CategoryList
            );

    // Register the Capture filter
    // Note:  This should be done automatically be MSKsSrv.sys, 
    // when that component comes on line (if ever) ...
    Status = StreamClassRegisterFilterWithNoKSPins (
                    m_pDeviceObject,                    // IN PDEVICE_OBJECT   DeviceObject,
                    &KSCATEGORY_CAPTURE,                // IN GUID           * InterfaceClassGUID,
                    CapturePins(),      // IN ULONG            PinCount,
                    (int *) CapturePinDirection,        // IN ULONG          * Flags,
                    (KSPIN_MEDIUM *) CaptureMediums,    // IN KSPIN_MEDIUM   * MediumList,
                    NULL                                // IN GUID           * CategoryList
            );
    pSrb->Status = STATUS_SUCCESS;
    return(TRUE);
}


BOOL CWDMVideoDecoder::SrbOpenStream(PHW_STREAM_REQUEST_BLOCK pSrb)
{
    DBGTRACE(("CWDMVideoDecoder:SrbOpenStream()\n"));
    PHW_STREAM_OBJECT       pStreamObject = pSrb->StreamObject;
    void *                  pStrmEx = pStreamObject->HwStreamExtension;
    int                     StreamNumber = pStreamObject->StreamNumber;
    PKSDATAFORMAT           pKSDataFormat = pSrb->CommandData.OpenFormat;
    CWDMVideoStream *       pVideoStream;
    CWDMVideoPortStream *   pVPVBIStream;
    UINT    nErrorCode;

    RtlZeroMemory(pStrmEx, streamDataExtensionSize);

    DBGINFO(("SRBOPENSTREAM ------- 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 >= (int)NumStreams || StreamNumber < 0) {

        pSrb->Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }


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

    if (!AdapterVerifyFormat (pKSDataFormat, StreamNumber)) {

        pSrb->Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

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

    pStreamObject->ReceiveDataPacket = VideoReceiveDataPacket;
    pStreamObject->ReceiveControlPacket = VideoReceiveCtrlPacket;

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

    pStreamObject->HwClockObject.HwClockFunction = NULL;
    pStreamObject->HwClockObject.ClockSupportFlags = 0;

    //
    // 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.
    //
    pStreamObject->Dma = Streams[StreamNumber].hwStreamObjectInfo.Dma;

    //
    // The PIO flag must be set when the mini driver will be accessing the data
    // buffers passed in using logical addressing
    //
    pStreamObject->Pio = Streams[StreamNumber].hwStreamObjectInfo.Pio;

    //
    // How many extra bytes will be passed up from the driver for each frame?
    //
    pStreamObject->StreamHeaderMediaSpecific = 
        Streams[StreamNumber].hwStreamObjectInfo.StreamHeaderMediaSpecific;

    pStreamObject->StreamHeaderWorkspace =
        Streams[StreamNumber].hwStreamObjectInfo.StreamHeaderWorkspace;

⌨️ 快捷键说明

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