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

📄 filter.cpp

📁 audio and video stream driver for windows. Tool: winddk
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    _DbgPrintF(DEBUGLVL_BLAB,("FilterClose"));

    PAGED_CODE();

    ASSERT(Filter);
    ASSERT(Irp);
    
    CCapFilter *filter = reinterpret_cast<CCapFilter *>(Filter->Context);
    ASSERT(filter);
    
    delete filter;
                    
    return STATUS_SUCCESS;
}


NTSTATUS
CCapFilter::
CaptureVideoInfoHeader(
    IN PKS_VIDEOINFOHEADER VideoInfoHeader
    )
/*++

Routine Description:
    Retrieve a copy of the Video Header Info

Arguments:
    IN PKS_VIDEOINFOHEADER VideoInfoHeader -
        Video Info Header copy

Return:
    STATUS_SUCCESS

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("CaptureVideoInfoHeader"));
    
    //
    // There could be one of these already if a pin was created and closed.
    //
    if (m_VideoInfoHeader) {
        ExFreePool(m_VideoInfoHeader);
    }

    m_VideoInfoHeader =
        (PKS_VIDEOINFOHEADER) 
            ExAllocatePoolWithTag( 
                NonPagedPool, 
                KS_SIZE_VIDEOHEADER( VideoInfoHeader ),
                'fChS' );
    
    NTSTATUS Status;

    if (m_VideoInfoHeader) {
        RtlCopyMemory( 
            m_VideoInfoHeader, 
            VideoInfoHeader, 
            KS_SIZE_VIDEOHEADER( VideoInfoHeader ) );
        Status = STATUS_SUCCESS;            
    } else {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }

    return Status;
}

static const WCHAR ClockTypeName[] = KSSTRING_Clock;


NTSTATUS
VideoPinCreate(
    IN OUT PKSPIN Pin,
    IN PIRP Irp
    )
/*++

Routine Description:
    Handle specific processing on Video Pin creation

Arguments:
    IN OUT PKSPIN Pin -
        Pin instance data
        
    IN PIRP Irp -
        Creation request

Return:
    STATUS_SUCCESS

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("VideoPinCreate"));
    
    NTSTATUS status = STATUS_SUCCESS;
    
    _DbgPrintF(DEBUGLVL_VERBOSE,("PinCreate filter %d as %s", Pin->Id, (Pin->Communication == KSPIN_COMMUNICATION_SOURCE) ? "SOURCE" : "SINK"));

    PAGED_CODE();

    ASSERT(Pin);
    ASSERT(Irp);

    //
    // Indicate the extended header size.
    //
    Pin->StreamHeaderSize = sizeof(KSSTREAM_HEADER) + sizeof(KS_FRAME_INFO);
    
    //
    // Use the same context as the filter (the shell copies this for us).
    //
    CCapFilter *filter = reinterpret_cast<CCapFilter *>(Pin->Context);

    status = filter->CaptureVideoInfoHeader(&(PKS_DATAFORMAT_VIDEOINFOHEADER(Pin->ConnectionFormat )->VideoInfoHeader));

    if (NT_SUCCESS(status)) 
    {
        status = KsEdit(Pin,&Pin->Descriptor,'aChS');
        if (NT_SUCCESS(status)) 
        {
            status = KsEdit(Pin,&Pin->Descriptor->AllocatorFraming,'aChS');
        }
        if (NT_SUCCESS(status)) 
        {
            PKS_VIDEOINFOHEADER VideoInfoHeader = &(PKS_DATAFORMAT_VIDEOINFOHEADER(Pin->ConnectionFormat)->VideoInfoHeader);

            PKSALLOCATOR_FRAMING_EX framing = const_cast<PKSALLOCATOR_FRAMING_EX>(Pin->Descriptor->AllocatorFraming);
            framing->FramingItem[0].Frames = 2;
            framing->FramingItem[0].PhysicalRange.MinFrameSize = VideoInfoHeader->bmiHeader.biSizeImage;
            framing->FramingItem[0].PhysicalRange.MaxFrameSize = VideoInfoHeader->bmiHeader.biSizeImage;
            framing->FramingItem[0].PhysicalRange.Stepping = 0;
            framing->FramingItem[0].FramingRange.Range.MinFrameSize =  VideoInfoHeader->bmiHeader.biSizeImage;
            framing->FramingItem[0].FramingRange.Range.MaxFrameSize = VideoInfoHeader->bmiHeader.biSizeImage;
            framing->FramingItem[0].FramingRange.Range.Stepping = 0;
        }
    }        
                    
    return status;
}


NTSTATUS
AudioPinCreate(
    IN OUT PKSPIN Pin,
    IN PIRP Irp
    )
/*++

Routine Description:
    Handle specific processing on Audio Pin creation

Arguments:
    IN OUT PKSPIN Pin -
        Pin instance data
        
    IN PIRP Irp -
        Creation request

Return:
    STATUS_SUCCESS

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("AudioPinCreate filter %d as %s",Pin->Id,(Pin->Communication == KSPIN_COMMUNICATION_SOURCE) ? "SOURCE" : "SINK"));

    PAGED_CODE();

    ASSERT(Pin);
    ASSERT(Irp);
    
    return STATUS_SUCCESS;
}



NTSTATUS
CCapFilter::CancelTimer()
{
    //
    // let Timer's Dpc we are stopped and cancel the timer
    // (REVIEW - we should be sure no Dpc is pending when 
    // this function exits)
    //
    InterlockedExchange(&m_Active,FALSE);
    if (InterlockedExchange(&m_TimerScheduled,FALSE)) 
    {
        _DbgPrintF(DEBUGLVL_TERSE,("cancelling timer"));
        KeCancelTimer(&m_TimerObject);
        _DbgPrintF(DEBUGLVL_TERSE,("timer cancelled"));
        return(STATUS_SUCCESS);
    }
    
    return(!STATUS_SUCCESS);
}


NTSTATUS
CCapFilter::Run(
    IN PKSPIN Pin,
    IN KSSTATE FromState 
    )
/*++

Routine Description:
    Handle pin statetransition to Run state

Arguments:
    IN PKSPIN Pin -
        Pin instance data
        
    IN KSSTATE FromState -
        Current pin state

Return:
    STATUS_SUCCESS

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("filter to KSSTATE_RUN Pin->Id:%d From:%d", Pin->Id, FromState));

#if 0
    //
    // initialize timer to drive transfer
    //
    InterlockedExchange(&m_Active, TRUE);
    //
    // comput transfer time points and start timer for first transfer
    //
    LARGE_INTEGER NextTime;
    KeQuerySystemTime(&NextTime);
    //
    // Fix the System time against the Physical time on the clock.
    //
    ////KsPinSetPinClockState(Pin,KSSTATE_RUN,NextTime.QuadPart);
    //
    // Determine how long the filter was not running in order to
    // update the start time, and therefore what the next frame
    // timestamp should be. The start and stop times are initially
    // zeroed, which means the start time initially is set to the
    // current system time.
    //
    m_llStartTime = NextTime.QuadPart - (m_iTick * m_VideoInfoHeader->AvgTimePerFrame);
    //
    // Set the offset to production of the first frame. This is produced
    // at the end of the period for which the frame is stamped, though it
    // could be produced earlier of course, even at the beginning of the
    // period.
    //
    NextTime.QuadPart = m_llStartTime + m_VideoInfoHeader->AvgTimePerFrame;
    KeSetTimer(&m_TimerObject,NextTime,&m_TimerDpc);
#endif

    return STATUS_SUCCESS;    
}    


NTSTATUS
CCapFilter::Pause(
    IN PKSPIN Pin,
    IN KSSTATE FromState                 
    )
/*++

Routine Description:
    Handle pin statetransition to Run state

Arguments:
    IN PKSPIN Pin -
        Pin instance data
        
    IN KSSTATE FromState -
        Current pin state

Return:
    STATUS_SUCCESS

--*/
{
    ASSERT(Pin);
    
    _DbgPrintF(DEBUGLVL_BLAB,("filter to KSSTATE_PAUSE Pin->Id:%d From:%d", Pin->Id, FromState));
    
    if (FromState == KSSTATE_RUN) 
    {
        CancelTimer();
        //
        // Unfix the System time from the Physical time on the clock.
        // Ignores partial frame times.
        //
//        KsPinSetPinClockState(
//            Pin,
//            KSSTATE_PAUSE,
//            m_iTick * m_VideoInfoHeader->AvgTimePerFrame);
    }
    else
    {
        //
        // initialize timer to drive transfer
        //
        InterlockedExchange(&m_Active, TRUE);
        //
        // comput transfer time points and start timer for first transfer
        //
        LARGE_INTEGER NextTime;
        KeQuerySystemTime(&NextTime);
        //
        // Fix the System time against the Physical time on the clock.
        //
        ////KsPinSetPinClockState(Pin,KSSTATE_RUN,NextTime.QuadPart);
        //
        // Determine how long the filter was not running in order to
        // update the start time, and therefore what the next frame
        // timestamp should be. The start and stop times are initially
        // zeroed, which means the start time initially is set to the
        // current system time.
        //
        m_llStartTime = NextTime.QuadPart - (m_iTick * m_VideoInfoHeader->AvgTimePerFrame);
        //
        // Set the offset to production of the first frame. This is produced
        // at the end of the period for which the frame is stamped, though it
        // could be produced earlier of course, even at the beginning of the
        // period.
        //
        NextTime.QuadPart = m_llStartTime + m_VideoInfoHeader->AvgTimePerFrame;
        KeSetTimer(&m_TimerObject,NextTime,&m_TimerDpc);
        _DbgPrintF(DEBUGLVL_BLAB,("CCapFilter::Pause KeSetTimer(%x, %d, %x)", &m_TimerObject, NextTime, &m_TimerDpc));
    }
    
    return STATUS_SUCCESS;
}


NTSTATUS
CCapFilter::Stop(
    IN PKSPIN Pin,
    IN KSSTATE FromState 
    )
/*++

Routine Description:
    Handle pin state transition to Stop

Arguments:
    IN PKSPIN Pin -
        Pin instance data
        
    IN KSSTATE FromState -
        Current pin state

Return:
    STATUS_SUCCESS

--*/
{
    _DbgPrintF(DEBUGLVL_BLAB,("filter to KSSTATE_STOP Pin->Id:%d From:%d", Pin->Id, FromState));

    CancelTimer();
    
    //
    // reinitialize transfer counters
    //
    m_iTick = 0;
    m_ullNextAudioPos = 0;
    m_ulAudioBufferOffset = 0;
    m_FrameInfo.PictureNumber = 0;
    m_FrameInfo.DropCount = 0;
    m_ulAudioDroppedFrames = 0;
    m_ulVideoDroppedFrames = 0;
    //
    // dump debug timestamps
    //
    for (ULONG iTs = 0; iTs < m_iTimestamp; iTs++) {
        DbgPrint(
            "TS[%lu] = %I64d, %I64d, %I64d\n", 
            iTs, 
            m_rgTimestamps[iTs].Abs,
            m_rgTimestamps[iTs].Rel,
            m_rgTimestamps[iTs].Int);
    }
    m_iTimestamp = 0;
    return STATUS_SUCCESS;
}


NTSTATUS
PinSetDeviceState(
    IN PKSPIN Pin,
    IN KSSTATE ToState,
    IN KSSTATE FromState
    )
/*++

Routine Description:
    Handle pin state transitions

Arguments:
    IN PKSPIN Pin -
        Pin instance data
        
    IN KSSTATE ToState -
        State to be set on pin        
        
    IN KSSTATE FromState -
        Current pin state

Return:
    STATUS_SUCCESS

--*/
{
    NTSTATUS  Status;
    
    _DbgPrintF(DEBUGLVL_BLAB,("PinSetDeviceState Pin->Id:%d From:%d To:%d",Pin->Id, FromState, ToState));

    PAGED_CODE();

    ASSERT(Pin);
    
    CCapFilter *filter = reinterpret_cast<CCapFilter *>(Pin->Context);
    
    Status = STATUS_SUCCESS;
    
    switch (ToState) 
    {
        case KSSTATE_STOP:

⌨️ 快捷键说明

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