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

📄 filter.cpp

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

    AVStream Filter-Centric Sample

    Copyright (c) 1999 - 2001, Microsoft Corporation

    File:

        filter.cpp

    Abstract:

        This file contails the capture filter implementation (including
        frame synthesis) for the fake capture filter.

    History:

        created 5/31/01

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

#include "avssamp.h"

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

    PAGEABLE CODE

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

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


CCaptureFilter::
CCaptureFilter (
    IN PKSFILTER Filter
    ) :
    m_Filter (Filter)

/*++

Routine Description:

    This is the constructor for the capture filter.  It initializes all the
    structures necessary to kick off timer DPC's for capture.

Arguments:

    Filter -
        The AVStream filter being created.

Return Value:

    None

--*/

{

    //
    // Initialize the DPC's, timers, and events necessary to cause a 
    // capture trigger to happen.
    //
    KeInitializeDpc (
        &m_TimerDpc,
        reinterpret_cast <PKDEFERRED_ROUTINE> (
            CCaptureFilter::TimerRoutine
            ),
        this
        );

    KeInitializeEvent (
        &m_StopDPCEvent,
        SynchronizationEvent,
        FALSE
        );

    KeInitializeTimer (&m_Timer);

}

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


NTSTATUS
CCaptureFilter::
DispatchCreate (
    IN PKSFILTER Filter,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the creation dispatch for the capture filter.  It creates
    the CCaptureFilter object, associates it with the AVStream filter
    object, and bag the CCaptureFilter for later cleanup.

Arguments:

    Filter -
        The AVStream filter being created

    Irp -
        The creation Irp

Return Value:
    
    Success / failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    CCaptureFilter *CapFilter = new (NonPagedPool) CCaptureFilter (Filter);

    if (!CapFilter) {
        //
        // Return failure if we couldn't create the filter.
        //
        Status = STATUS_INSUFFICIENT_RESOURCES;

    } else {
        //
        // Add the item to the object bag if we we were successful. 
        // Whenever the filter closes, the bag is cleaned up and we will be
        // freed.
        //
        Status = KsAddItemToObjectBag (
            Filter -> Bag,
            reinterpret_cast <PVOID> (CapFilter),
            reinterpret_cast <PFNKSFREE> (CCaptureFilter::Cleanup)
            );

        if (!NT_SUCCESS (Status)) {
            delete CapFilter;
        } else {
            Filter -> Context = reinterpret_cast <PVOID> (CapFilter);
        }

    }

    //
    // Create the wave reader.  We need it at this point because the data
    // ranges exposed on the audio pin need to change dynamically right
    // now.
    //
    if (NT_SUCCESS (Status)) {

        CapFilter -> m_WaveObject =  
            new (NonPagedPool, 'evaW') CWaveObject (
                L"\\DosDevices\\c:\\avssamp.wav"
                );

        if (!CapFilter -> m_WaveObject) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        } else {
            Status = CapFilter -> m_WaveObject -> ParseAndRead ();

            //
            // If the file cannot be found, don't fail to create the filter.
            // This simply means that audio cannot be synthesized.
            //
            if (Status == STATUS_OBJECT_NAME_NOT_FOUND ||
                Status == STATUS_ACCESS_DENIED) {
                delete CapFilter -> m_WaveObject;
                CapFilter -> m_WaveObject = NULL;
                Status = STATUS_SUCCESS;
            }
            
        }

    }

    if (NT_SUCCESS (Status) && CapFilter -> m_WaveObject) {
        //
        // Add the wave object to the filter's bag for auto-cleanup.
        //
        Status = KsAddItemToObjectBag (
            Filter -> Bag,
            reinterpret_cast <PVOID> (CapFilter -> m_WaveObject),
            reinterpret_cast <PFNKSFREE> (CWaveObject::Cleanup)
            );

        if (!NT_SUCCESS (Status)) {
            delete CapFilter -> m_WaveObject;
            CapFilter -> m_WaveObject = NULL;
        } else {
            Status = CapFilter -> BindAudioToWaveObject ();
        }
    }

    return Status;

}

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


NTSTATUS
CCaptureFilter::
BindAudioToWaveObject (
    )

/*++

Routine Description:

    Create an audio pin directly bound to m_WaveObject (aka: it only exposes
    the format (channels, frequency, etc...) that m_WaveObject represents.
    This will actually create a pin on the filter dynamically.

Arguments:

    None

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    ASSERT (m_WaveObject);

    NTSTATUS Status = STATUS_SUCCESS;

    //
    // Build a pin descriptor from the template.  This descriptor is
    // temporary scratch space because the call to AVStream to create the
    // pin will actually duplicate the descriptor.
    //
    KSPIN_DESCRIPTOR_EX PinDescriptor = AudioPinDescriptorTemplate;

    //
    // The data range must be dynamically created since we're basing it
    // on dynamic reading of a wave file!
    //
    PKSDATARANGE_AUDIO DataRangeAudio = 
        reinterpret_cast <PKSDATARANGE_AUDIO> (
            ExAllocatePool (PagedPool, sizeof (KSDATARANGE_AUDIO))
            );

    PKSDATARANGE_AUDIO *DataRanges =
        reinterpret_cast <PKSDATARANGE_AUDIO *> (
            ExAllocatePool (PagedPool, sizeof (PKSDATARANGE_AUDIO))
            );

    PKSALLOCATOR_FRAMING_EX Framing =
        reinterpret_cast <PKSALLOCATOR_FRAMING_EX> (
            ExAllocatePool (PagedPool, sizeof (KSALLOCATOR_FRAMING_EX))
            );

    if (DataRangeAudio && DataRanges && Framing) {
        DataRangeAudio -> DataRange.FormatSize = sizeof (KSDATARANGE_AUDIO);
        DataRangeAudio -> DataRange.Flags = 0;
        DataRangeAudio -> DataRange.SampleSize = 0;
        DataRangeAudio -> DataRange.Reserved = 0;
        DataRangeAudio -> DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
        DataRangeAudio -> DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
        DataRangeAudio -> DataRange.Specifier = 
            KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;

        m_WaveObject -> WriteRange (DataRangeAudio);

        *DataRanges = DataRangeAudio;

    } else {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }

    if (NT_SUCCESS (Status)) {
        //
        // Bag the newly created range information in the filter's bag since
        // this will be alive for the lifetime of the filter.
        //
        Status = KsAddItemToObjectBag (
            m_Filter -> Bag,
            DataRangeAudio,
            NULL
            );

        if (!NT_SUCCESS (Status)) {
            ExFreePool (DataRangeAudio);
            ExFreePool (DataRanges);
            ExFreePool (Framing);
        }

    }

    if (NT_SUCCESS (Status)) {

        Status = KsAddItemToObjectBag (
            m_Filter -> Bag,
            DataRanges,
            NULL
            );

        if (!NT_SUCCESS (Status)) {
            ExFreePool (DataRanges);
            ExFreePool (Framing);
        }

    }

    if (NT_SUCCESS (Status)) {
        
        Status = KsAddItemToObjectBag (
            m_Filter -> Bag,
            Framing,
            NULL
            );

        if (!NT_SUCCESS (Status)) {
            ExFreePool (Framing);
        }

    }

    if (NT_SUCCESS (Status)) {
        //
        // The physical and optimal ranges must block aligned and 
        // the size of 1/(fps) * bytes_per_sec in size.  It's true
        // that we don't know the frame rate at this point due
        // to the fact that the video pin doesn't exist yet; however, that
        // would also be true if this were edited at audio pin creation.
        //
        // Thus, we instead adjust the allocator for the minimum frame rate
        // we support (which is 1/30 of a second).
        //
        *Framing = *PinDescriptor.AllocatorFraming;

        Framing -> FramingItem [0].PhysicalRange.MinFrameSize =
            Framing -> FramingItem [0].PhysicalRange.MaxFrameSize =
            Framing -> FramingItem [0].FramingRange.Range.MinFrameSize =
            Framing -> FramingItem [0].FramingRange.Range.MaxFrameSize =
                ((DataRangeAudio -> MaximumSampleFrequency *
                DataRangeAudio -> MaximumBitsPerSample *
                DataRangeAudio -> MaximumChannels) + 29) / 30;

        Framing -> FramingItem [0].PhysicalRange.Stepping = 
            Framing -> FramingItem [0].FramingRange.Range.Stepping =
            0;

        PinDescriptor.AllocatorFraming = Framing;

        PinDescriptor.PinDescriptor.DataRangesCount = 1;
        PinDescriptor.PinDescriptor.DataRanges = 
            reinterpret_cast <const PKSDATARANGE *> (DataRanges);

        //
        // Create the actual pin.  We need to save the pin id returned.  It
        // is how we refer to the audio pin in the future.
        //
        Status = KsFilterCreatePinFactory (
            m_Filter, 
            &PinDescriptor, 
            &m_AudioPinId
            );

    }

    return Status;

}


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


void
CCaptureFilter::
StartDPC (
    IN LONGLONG TimerInterval
    )

/*++

Routine Description:

    This routine starts the timer DPC running at a specified interval.  The 
    specified interval is the amount of time between triggering frame captures.
    Once this routine returns, the timer DPC should be running and attempting
    to trigger processing on the capture filter as a whole.

Arguments:

    TimerInterval -
        The amount of time between timer DPC's.  This is the amount of delay
        between one frame and the next.  Since the DPC is driven off the 
        video capture pin, this should be an amount of time specified by
        the video info header.

⌨️ 快捷键说明

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