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

📄 filter.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
Return Value:

    None

--*/

{

    PAGED_CODE();

    //
    // Initialize any variables used by the timer DPC.
    //
    m_Tick = 0;
    m_TimerInterval = TimerInterval;
    KeQuerySystemTime (&m_StartTime);

    //
    // Schedule the DPC to happen one frame time from now.
    //
    LARGE_INTEGER NextTime;
    NextTime.QuadPart = m_StartTime.QuadPart + m_TimerInterval;

    KeSetTimer (&m_Timer, NextTime, &m_TimerDpc);

}

/*************************************************/


void
CCaptureFilter::
StopDPC (
    )

/*++

Routine Description:

    Stop the timer DPC from firing.  After this routine returns, there is
    a guarantee that no more timer DPC's will fire and no more processing
    attempts will occur.  Note that this routine does block.

Arguments:

    None

Return Value:

    None

--*/

{

    PAGED_CODE();

    m_StoppingDPC = TRUE;

    KeWaitForSingleObject (
        &m_StopDPCEvent,
        Suspended,
        KernelMode,
        FALSE,
        NULL
        );

    ASSERT (m_StoppingDPC == FALSE);

}

/**************************************************************************

    LOCKED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg()
#endif // ALLOC_PRAGMA


LONGLONG
CCaptureFilter::
GetTimerInterval (
    )

/*++

Routine Description:

    Return the timer interval being used to fire DPC's.

Arguments:

    None

Return Value:

    The timer interval being used to fire DPC's.

--*/

{

    return m_TimerInterval;

}

/*************************************************/


NTSTATUS
CCaptureFilter::
Process (
    IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex
    )

/*++

Routine Description:

    This is the processing function for the capture filter.  It is responsible
    for copying synthesized image data into the image buffers.  The timer DPC
    will attempt to trigger processing (and hence indirectly call this routine)
    to trigger a capture.

Arguments:

    ProcessPinsIndex -
        Contains a pointer to an array of process pin index entries.  This
        array is indexed by pin ID.  An index entry indicates the number
        of pin instances for the corresponding filter type and points to the
        first corresponding process pin structure in the ProcessPins array.
        This allows the process pin structure to be quickly accessed by pin ID
        when the number of instances per type is not known in advance.

Return Value:

    Indication of whether more processing should be done if frames are
    available.  A value of STATUS_PENDING indicates that processing should not
    continue even if frames are available on all required queues. 
    STATUS_SUCCESS indicates processing should continue if frames are available
    on all required queues.

--*/

{

    //
    // The audio and video pins do not necessarily need to exist (one could
    // be capturing video w/o audio or vice-versa).  Do not assume the
    // existence by checking Index[ID].Pins[0].  Always check the Count
    // field first.
    //
    PKSPROCESSPIN VideoPin = NULL;
    CCapturePin *VidCapPin = NULL;
    PKSPROCESSPIN AudioPin = NULL;
    CCapturePin *AudCapPin = NULL;
    ULONG VidCapDrop = 0;
    ULONG AudCapDrop = (ULONG)-1;

    if (ProcessPinsIndex [VIDEO_PIN_ID].Count != 0) {
        //
        // There can be at most one instance via the possible instances field,
        // so the below is safe.
        //
        VideoPin = ProcessPinsIndex [VIDEO_PIN_ID].Pins [0];
        VidCapPin = 
            reinterpret_cast <CCapturePin *> (VideoPin -> Pin -> Context);
    }

    //
    // The audio pin only exists on the filter if the wave object does.
    // They're tied together at filter create time.
    //
    if (m_WaveObject && ProcessPinsIndex [m_AudioPinId].Count != 0) {
        //
        // There can be at most one instance via the possible instances field,
        // so the below is safe.
        //
        AudioPin = ProcessPinsIndex [m_AudioPinId].Pins [0];
        AudCapPin =
            reinterpret_cast <CCapturePin *> (AudioPin -> Pin -> Context);
    }

    if (VidCapPin) {
        VidCapDrop = VidCapPin -> QueryFrameDrop ();
    } 
    
    if (AudCapPin) {
        AudCapDrop = AudCapPin -> QueryFrameDrop ();
    }

    //
    // If there's a video pin around, trigger capture on it.  We call the
    // pin object to actually synthesize the frame; however, we could just
    // as easily have done that here.
    //
    if (VidCapPin) {
        //
        // This is used to notify the pin how many frames have been dropped
        // on each pin to allow that to be rendered.
        //
        VidCapPin -> NotifyDrops (VidCapDrop, AudCapDrop);
        VidCapPin -> CaptureFrame (VideoPin, m_Tick);
    }

    //
    // If there's an audio pin around, trigger capture on it.  Since the
    // audio capture pin isn't necessary for capture, there might be an
    // instance which is connected and is in the stop state when we get 
    // called [there will never be one in acquire or pause since we specify
    // KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY].  Don't bother triggering capture
    // on the pin unless it's actually running.
    //
    // On DX8.x platforms, the Pin -> ClientState field does not exist.
    // Hence, we check the state we maintain ourselves.  DeviceState is not
    // the right thing to check here.
    //
    if (AudioPin && AudCapPin -> GetState () == KSSTATE_RUN) {
        AudCapPin -> CaptureFrame (AudioPin, m_Tick);
    }

    //
    // STATUS_PENDING indicates that we do not want to be called back if
    // there is more data available.  We only want to trigger processing
    // (and hence capture) on the timer ticks.
    //
    return STATUS_PENDING;

}

/*************************************************/


void
CCaptureFilter::
TimerDpc (
    )

/*++

Routine Description:

    This is the timer function for our timer (bridged to from TimerRoutine
    in the context of the appropriate CCaptureFilter).  It is called every
    1/Nth of a second as specified in StartDpc() to trigger capture of a video
    frame.

Arguments:

    None

Return Value:

    None

--*/

{

    //
    // Increment the tick counter.  This keeps track of the number of ticks
    // that have happened since the timer DPC started running.  Note that the
    // timer DPC starts running before the pins go into run state and this
    // variable gets incremented from the original start point.
    //
    m_Tick++;

    //
    // Trigger processing on the filter.  Since the filter is prepared to
    // run at DPC, we do not request asynchronous processing.  Thus, if 
    // possible, processing will occur in the context of this DPC.
    //
    KsFilterAttemptProcessing (m_Filter, FALSE);

    //
    // Reschedule the timer if the hardware isn't being stopped.
    //
    if (!m_StoppingDPC) {
        
        LARGE_INTEGER NextTime;

        NextTime.QuadPart = m_StartTime.QuadPart +
            (m_TimerInterval * (m_Tick + 1));

        KeSetTimer (&m_Timer, NextTime, &m_TimerDpc);

    } else {

        //
        // If another thread is waiting on the DPC to stop running, raise
        // the stop event and clear the flag.
        //
        m_StoppingDPC = FALSE;
        KeSetEvent (&m_StopDPCEvent, IO_NO_INCREMENT, FALSE);

    }

}

/**************************************************************************

    DESCRIPTOR AND DISPATCH LAYOUT

**************************************************************************/

GUID g_PINNAME_VIDEO_CAPTURE = {STATIC_PINNAME_VIDEO_CAPTURE};

//
// CaptureFilterCategories:
//
// The list of category GUIDs for the capture filter.
//
const
GUID
CaptureFilterCategories [CAPTURE_FILTER_CATEGORIES_COUNT] = {
    STATICGUIDOF (KSCATEGORY_VIDEO),
    STATICGUIDOF (KSCATEGORY_CAPTURE)
};

//
// CaptureFilterPinDescriptors:
//
// The list of pin descriptors on the capture filter.  
//
const 
KSPIN_DESCRIPTOR_EX
CaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT] = {
    //
    // Video Capture Pin
    //
    {
        &VideoCapturePinDispatch,
        NULL,             
        {
            NULL,                           // Interfaces (NULL, 0 == default)
            0,
            NULL,                           // Mediums (NULL, 0 == default)
            0,
            SIZEOF_ARRAY (VideoCapturePinDataRanges), // Range Count
            VideoCapturePinDataRanges,      // Ranges
            KSPIN_DATAFLOW_OUT,             // Dataflow
            KSPIN_COMMUNICATION_BOTH,       // Communication
            &KSCATEGORY_VIDEO,              // Category
            &g_PINNAME_VIDEO_CAPTURE,       // Name
            0                               // Reserved
        },
        KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING | // Flags
            KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING |
            KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY,
        1,                                  // Instances Possible
        1,                                  // Instances Necessary
        &VideoCapturePinAllocatorFraming,   // Allocator Framing
        reinterpret_cast <PFNKSINTERSECTHANDLEREX> 
            (CVideoCapturePin::IntersectHandler)
    }
};

//
// CaptureFilterDispatch:
//
// This is the dispatch table for the capture filter.  It provides notification
// of creation, closure, processing, and resets.
//
const 
KSFILTER_DISPATCH
CaptureFilterDispatch = {
    CCaptureFilter::DispatchCreate,         // Filter Create
    NULL,                                   // Filter Close
    CCaptureFilter::DispatchProcess,        // Filter Process
    NULL                                    // Filter Reset
};

//
// CaptureFilterDescription:
//
// The descriptor for the capture filter.  We don't specify any topology
// since there's only one pin on the filter.  Realistically, there would
// be some topological relationships here because there would be input 
// pins from crossbars and the like.
//
const 
KSFILTER_DESCRIPTOR 
CaptureFilterDescriptor = {
    &CaptureFilterDispatch,                 // Dispatch Table
    NULL,                                   // Automation Table
    KSFILTER_DESCRIPTOR_VERSION,            // Version
    KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING,// Flags
    &KSNAME_Filter,                         // Reference GUID
    DEFINE_KSFILTER_PIN_DESCRIPTORS (CaptureFilterPinDescriptors),
    DEFINE_KSFILTER_CATEGORIES (CaptureFilterCategories),

    DEFINE_KSFILTER_NODE_DESCRIPTORS_NULL,
    DEFINE_KSFILTER_DEFAULT_CONNECTIONS,

    NULL                                    // Component ID
};


⌨️ 快捷键说明

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