软件工程

本类阅读TOP10

·PHP4 + MYSQL + APACHE 在 WIN 系统下的安装、配置
·Linux 入门常用命令(1)
·Linux 入门常用命令(2)
·使用 DCPROMO/FORCEREMOVAL 命令强制将 Active Directory 域控制器降级
·DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析
·基于ICE方式SIP信令穿透Symmetric NAT技术研究
·Windows 2003网络负载均衡的实现
·一网打尽Win十四种系统故障解决方法
·数百种 Windows 软件的免费替代品列表
·收藏---行百里半九十

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析
1.      
CRendererInputPin[renbase.h/renbase.cpp]
派生自CBaseInputPin

a)        成员变量:
CBaseRenderer
*m_pRenderer;

b)        IPin接口和继承的函数
HRESULT BreakConnect();
{
    HRESULT hr = m_pRenderer->BreakConnect();
    return CBaseInputPin::BreakConnect();
}
HRESULT CompleteConnect(IPin *pReceivePin);
{
    HRESULT hr = m_pRenderer->CompleteConnect(pReceivePin);
    return CBaseInputPin::CompleteConnect(pReceivePin);
}
HRESULT SetMediaType(const CMediaType *pmt);
{
    HRESULT hr = CBaseInputPin::SetMediaType(pmt);
    return m_pRenderer->SetMediaType(pmt);
}
HRESULT CheckMediaType(const CMediaType *pmt);
{
return m_pRenderer->CheckMediaType(pmt); }
HRESULT Active();{ return m_pRenderer->Active();}
HRESULT Inactive();
{
    ASSERT(CritCheckIn(&m_pRenderer->m_InterfaceLock));
    m_bRunTimeError = FALSE;
    return m_pRenderer->Inactive();
}
STDMETHODIMP QueryId(LPWSTR *Id);
{
    *Id = (LPWSTR)CoTaskMemAlloc(8);
    lstrcpyW(*Id, L"In");
}
STDMETHODIMP EndOfStream();
{
    CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
    CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
    HRESULT hr = CheckStreaming();
    hr = m_pRenderer->EndOfStream();
    hr = CBaseInputPin::EndOfStream();
}
STDMETHODIMP BeginFlush();
{
    HRESULT hr = m_pRenderer->EndFlush();
    hr = CBaseInputPin::EndFlush();
}
STDMETHODIMP EndFlush();
{
    CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
    CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
    CBaseInputPin::BeginFlush();
    m_pRenderer->BeginFlush();
    return m_pRenderer->ResetEndOfStream();
}
STDMETHODIMP Receive(IMediaSample *pMediaSample);
{
    HRESULT hr = m_pRenderer->Receive(pSample);
    if (FAILED(hr)) {
        ASSERT(CritCheckOut(&m_pRenderer->m_RendererLock));
        CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
       if (!IsStopped() && !IsFlushing() && !m_pRenderer->m_bAbort && !m_bRunTimeError)
       {
            m_pRenderer->NotifyEvent(EC_ERRORABORT,hr,0);
            CAutoLock alRendererLock(&m_pRenderer->m_RendererLock);
            if (m_pRenderer->IsStreaming() && !m_pRenderer->IsEndOfStreamDelivered())
            { m_pRenderer->NotifyEndOfStream();}
           
m_bRunTimeError = TRUE;
       }
    }
}

2.       CBaseRender[renbase.h/renbase.cpp]
派生自CBaseFilter

a)        成员变量
CRendererPosPassThru
*m_pPosition;  // Media seeking pass by object
CRendererPosPassThru派生自CPosPassThru,后者继承自接口IMediaSeeking和类CMediaPosition。而类CMediaPosition实现了接口IMediaPosition。具体实现见ctlutil.h
CAMEvent m_RenderEvent;             // Used to signal timer events
CAMEvent m_ThreadSignal;            // Signalled to release worker thread
CAMEvent m_evComplete;              // Signalled when state complete
BOOL m_bAbort;                      // Stop us from rendering more data
BOOL m_bStreaming;                  // Are we currently streaming
DWORD_PTR m_dwAdvise;                   // Timer advise cookie
IMediaSample *m_pMediaSample;       // Current image media sample
BOOL m_bEOS;                        // Any more samples in the stream
BOOL m_bEOSDelivered;               // Have we delivered an EC_COMPLETE
CRendererInputPin *m_pInputPin;     // Our renderer input pin object
CCritSec m_InterfaceLock;           // Critical section for interfaces
CCritSec m_RendererLock;            // Controls access to internals
IQualityControl * m_pQSink;         // QualityControl sink
BOOL m_bRepaintStatus;              // Can we signal an EC_REPAINT
//  Avoid some deadlocks by tracking filter during stop
volatile BOOL  m_bInReceive;        // Inside Receive between PrepareReceive
                                    // And actually processing the sample
REFERENCE_TIME m_SignalTime;        // Time when we signal EC_COMPLETE
UINT m_EndOfStreamTimer;            // Used to signal end of stream
CCritSec m_ObjectCreationLock;      // This lock protects the creation and
// of m_pPosition and m_pInputPin.  It
ensures that two threads cannot create
// either object simultaneously.
构造函数中,对各成员初始化,m_evComplete(TRUE), m_bAbort(FALSE), m_pPosition(NULL),  m_ThreadSignal(TRUE), m_bStreaming(FALSE), m_bEOS(FALSE), m_bEOSDelivered(FALSE), m_pMediaSample(NULL), m_dwAdvise(0), m_pQSink(NULL), m_pInputPin(NULL), m_bRepaintStatus(TRUE), m_SignalTime(0), m_bInReceive(FALSE), m_EndOfStreamTimer(0)析构函数中调用StopStreamingClearPendingSample;并删除m_pPositionm_pInputPin

b)        新增加的virtual函数
// Overriden to say what interfaces we support and where
virtual HRESULT GetMediaPositionInterface(REFIID riid,void **ppv);
{
    CAutoLock cObjectCreationLock(&m_ObjectCreationLock);
    if (m_pPosition) {
        return m_pPosition->NonDelegatingQueryInterface(riid,ppv);
    }
    m_pPosition = new CRendererPosPassThru(NAME("Renderer CPosPassThru"),
         CBaseFilter::GetOwner(),(HRESULT *) &hr, GetPin(0));
    return GetMediaPositionInterface(riid,ppv);
}
virtual HRESULT SourceThreadCanWait(BOOL bCanWait);
{
    if (bCanWait == TRUE) m_ThreadSignal.Reset();
   
else m_ThreadSignal.Set();
}
virtual HRESULT WaitForRenderTime();
{
    HANDLE WaitObjects[] = { m_ThreadSignal, m_RenderEvent };
    OnWaitStart();
   while (Result == WAIT_TIMEOUT) {
        Result = WaitForMultipleObjects(2,WaitObjects,FALSE,RENDER_TIMEOUT);}
    OnWaitEnd();
    if (Result == WAIT_OBJECT_0) {return VFW_E_STATE_CHANGED;}
    SignalTimerFired();
}
virtual HRESULT CompleteStateChange(FILTER_STATE OldState);
{
    if (m_pInputPin->IsConnected() == FALSE) {Ready();return S_OK;}
    if (IsEndOfStream() == TRUE) {Ready();return S_OK;}
    if (HaveCurrentSample() == TRUE) {
        if (OldState != State_Stopped) { Ready();return S_OK;}
    }
    NotReady();
}
virtual void OnReceiveFirstSample(IMediaSample *pMediaSample) {};
virtual void OnRenderStart(IMediaSample *pMediaSample){}
virtual void OnRenderEnd(IMediaSample *pMediaSample){}
virtual HRESULT OnStartStreaming() { return NOERROR; };
virtual HRESULT OnStopStreaming() { return NOERROR; };
virtual void OnWaitStart() {};
virtual void OnWaitEnd() {};
virtual void PrepareRender() {};
// Quality management implementation for scheduling rendering
virtual BOOL ScheduleSample(IMediaSample *pMediaSample);
{
    REFERENCE_TIME StartSample, EndSample;
    if (pMediaSample == NULL) {return FALSE;}
    HRESULT hr = GetSampleTimes(pMediaSample, &StartSample, &EndSample);
    if (FAILED(hr)) {return FALSE;}
    if (hr == S_OK) {EXECUTE_ASSERT(SetEvent((HANDLE) m_RenderEvent));
        return TRUE;}
    ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));
    hr = m_pClock->AdviseTime(
            (REFERENCE_TIME) m_tStart,          // Start run time
            StartSample,                        // Stream time
            (HEVENT)(HANDLE) m_RenderEvent,     // Render notification
            &m_dwAdvise);                       // Advise cookie
    if (SUCCEEDED(hr)) {return TRUE;}
    return FALSE;
}
virtual HRESULT GetSampleTimes(IMediaSample *pMediaSample,
                               REFERENCE_TIME *pStartTime,
                               REFERENCE_TIME *pEndTime);
{
    if (SUCCEEDED(pMediaSample->GetTime(pStartTime, pEndTime))) {
        if (*pEndTime < *pStartTime) {return VFW_E_START_TIME_AFTER_END;}
    } else {return S_OK;}
    if (m_pClock == NULL) {return S_OK;}
    return ShouldDrawSampleNow(pMediaSample,pStartTime,pEndTime);
}
virtual HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample,
                                    REFERENCE_TIME *ptrStart,
                                    REFERENCE_TIME *ptrEnd);{ return S_FALSE;}
virtual HRESULT SendEndOfStream();
{
    ASSERT(CritCheckIn(&m_RendererLock));
    if (m_bEOS == FALSE || m_bEOSDelivered || m_EndOfStreamTimer) {
        return NOERROR;}
    if (m_pClock == NULL) {return NotifyEndOfStream();}
    REFERENCE_TIME Signal = m_tStart + m_SignalTime;
    REFERENCE_TIME CurrentTime;
    m_pClock->GetTime(&CurrentTime);
    LONG Delay = LONG((Signal - CurrentTime) / 10000);
    if (Delay < TIMEOUT_DELIVERYWAIT) {return NotifyEndOfStream();}
    m_EndOfStreamTimer = CompatibleTimeSetEvent((UINT) Delay, // Period of timer
                                      TIMEOUT_RESOLUTION,     // Timer resolution
                                      EndOfStreamTimer,       // Callback function
                                      DWORD_PTR(this),        // Used information
                                      TIME_ONESHOT);          // Type of callback
    if (m_EndOfStreamTimer == 0) {return NotifyEndOfStream();}
}
virtual HRESULT ResetEndOfStream();
{
    ResetEndOfStreamTimer();
    CAutoLock cRendererLock(&m_RendererLock);
    m_bEOS = FALSE;
    m_bEOSDelivered = FALSE;
    m_SignalTime = 0;
}
virtual HRESULT EndOfStream();
{
    m_bEOS = TRUE;
    Ready();
    if (m_pMediaSample) { return NOERROR;}
    if (m_bStreaming) { SendEndOfStream();}
}
virtual HRESULT CancelNotification();
{
    ASSERT(m_dwAdvise == 0 || m_pClock);
    DWORD_PTR dwAdvise = m_dwAdvise;
    if (m_dwAdvise) {
        m_pClock->Unadvise(m_dwAdvise);
        SignalTimerFired();}
    m_RenderEvent.Reset();
    return (dwAdvise ? S_OK : S_FALSE);
}
virtual HRESULT ClearPendingSample();
{
    CAutoLock cRendererLock(&m_RendererLock);
    if (m_pMediaSample) {
        m_pMediaSample->Release();
        m_pMediaSample = NULL;}
}
virtual HRESULT PrepareReceive(IMediaSample *pMediaSample);
{
    CAutoLock cInterfaceLock(&m_InterfaceLock);
    m_bInReceive = TRUE;
    HRESULT hr = m_pInputPin->CBaseInputPin::Receive(pMediaSample);
    if (hr != NOERROR) {m_bInReceive = FALSE; return E_FAIL;}
    if (m_pInputPin->SampleProps()->pMediaType) {
        hr = m_pInputPin->SetMediaType(
                (CMediaType *)m_pInputPin->SampleProps()->pMediaType);
        if (FAILED(hr)) {
            m_bInReceive = FALSE;
            return hr;
        }
    }
    CAutoLock cSampleLock(&m_RendererLock);
    if (m_pMediaSample || m_bEOS || m_bAbort) {
        Ready();m_bInReceive = FALSE; return E_UNEXPECTED;}
    if (m_pPosition) m_pPosition->RegisterMediaTime(pMediaSample);
    if ((m_bStreaming == TRUE) && (ScheduleSample(pMediaSample) == FALSE)) {
        ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));
        ASSERT(CancelNotification() == S_FALSE);
        m_bInReceive = FALSE;
        return VFW_E_SAMPLE_REJECTED;
    }
    m_SignalTime = m_pInputPin->SampleProps()->tStop;
    m_pMediaSample = pMediaSample;
    m_pMediaSample->AddRef();
    if (m_bStreaming == FALSE) {SetRepaintStatus(TRUE);}
}
virtual BOOL HaveCurrentSample();
{
// Checks if there is a sample waiting at the renderer
    CAutoLock cRendererLock(&m_RendererLock);
    return (m_pMediaSample == NULL ? FALSE : TRUE);
}
virtual IMediaSample *GetCurrentSample();
{
    CAutoLock cRendererLock(&m_RendererLock);
    if (m_pMediaSample) {m_pMediaSample->AddRef();}
    return m_pMediaSample;
}
virtual HRESULT Render(IMediaSample *pMediaSample);
{
    if (pMediaSample == NULL) {return S_FALSE;}
    if (m_bStreaming == FALSE) {return S_FALSE;}
    OnRenderStart(pMediaSample);
    DoRenderSample(pMediaSample);
    OnRenderEnd(pMediaSample);
}
virtual HRESULT DoRenderSample(IMediaSample *pMediaSample) PURE;

c)        IBaseFilter接口函数以及继承函数
virtual int GetPinCount();{1}
virtual CBasePin *GetPin(int n);
{
    CAutoLock cObjectCreationLock(&m_ObjectCreationLock);
    if (m_pInputPin == NULL) {
        m_pInputPin = new CRendererInputPin(this,&hr,L"In");}
    return m_pInputPin;
}
STDMETHODIMP Stop();
{
    CAutoLock cRendererLock(&m_InterfaceLock);
    if (m_State == State_Stopped) { return NOERROR;}
    if (m_pInputPin->IsConnected() == FALSE) {
        m_State = State_Stopped;
        return NOERROR;}
    CBaseFilter::Stop();
    if (m_pInputPin->Allocator()) { m_pInputPin->Allocator()->Decommit();}
    SetRepaintStatus(TRUE);
    StopStreaming();
    SourceThreadCanWait(FALSE);
    ResetEndOfStream();
    CancelNotification();
    Ready();
    WaitForReceiveToComplete();
    m_bAbort = FALSE;
}
STDMETHODIMP Pause();
{
    CAutoLock cRendererLock(&m_InterfaceLock);
    FILTER_STATE OldState = m_State;
    if (m_State == State_Paused) { return CompleteStateChange(State_Paused);}
    if (m_pInputPin->IsConnected() == FALSE) {
        m_State = State_Paused;
        return CompleteStateChange(State_Paused);
    }
    HRESULT hr = CBaseFilter::Pause();
    SetRepaintStatus(TRUE);
    StopStreaming();
    SourceThreadCanWait(TRUE);
    CancelNotification();
    ResetEndOfStreamTimer();
    if (m_pInputPin->Allocator()) { m_pInputPin->Allocator()->Commit();}
    if (OldState == State_Stopped) {
        m_bAbort = FALSE;
        ClearPendingSample();}
    return CompleteStateChange(OldState);
}
STDMETHODIMP Run(REFERENCE_TIME StartTime);
{
    CAutoLock cRendererLock(&m_InterfaceLock);
    FILTER_STATE OldState = m_State;
    if (m_pInputPin->IsConnected() == FALSE) {
        NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this);
        m_State = State_Running;
        return NOERROR;}
    Ready();
    HRESULT hr = CBaseFilter::Run(StartTime);
    SourceThreadCanWait(TRUE);
    SetRepaintStatus(FALSE);
    if (m_pInputPin->Allocator()) { m_pInputPin->Allocator()->Commit();}
    if (OldState == State_Stopped) {
        m_bAbort = FALSE;
        ClearPendingSample();}
    return StartStreaming ();
}
STDMETHODIMP GetState(DWORD dwMSecs,FILTER_STATE *State);
{
   CheckPointer(State,E_POINTER);
    if (WaitDispatchingMessages(m_evComplete, dwMSecs) == WAIT_TIMEOUT) {
        *State = m_State;
        return VFW_S_STATE_INTERMEDIATE;}
    *State = m_State;
}
STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin);
{
    if (0==lstrcmpW(Id,L"In")) { *ppPin = GetPin(0); (*ppPin)->AddRef();}
}
virtual HRESULT Active();{return NOERROR;}
virtual HRESULT Inactive();
{
    if (m_pPosition) { m_pPosition->ResetMediaTime();}
    ClearPendingSample();
}
virtual HRESULT StartStreaming();
{
    CAutoLock cRendererLock(&m_RendererLock);
    if (m_bStreaming == TRUE) {return NOERROR;}
    m_bStreaming = TRUE;
    timeBeginPeriod(1);
    OnStartStreaming();
    ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));
    ASSERT(CancelNotification() == S_FALSE);
    if (m_pMediaSample == NULL) {return SendEndOfStream();}
    if (!ScheduleSample(m_pMediaSample)) m_RenderEvent.Set();
}
virtual HRESULT StopStreaming();
{
    CAutoLock cRendererLock(&m_RendererLock);
    m_bEOSDelivered = FALSE;
    if (m_bStreaming == TRUE) {
        m_bStreaming = FALSE;
        OnStopStreaming();
        timeEndPeriod(1);}
}
virtual HRESULT BeginFlush();
{
    if (m_State == State_Paused) { NotReady();}
    SourceThreadCanWait(FALSE);
    CancelNotification();
    ClearPendingSample();
    WaitForReceiveToComplete();
}
virtual HRESULT EndFlush();
{
    if (m_pPosition) m_pPosition->ResetMediaTime();
    SourceThreadCanWait(TRUE);
}
virtual HRESULT BreakConnect();
{
    if (m_pQSink) {m_pQSink->Release();m_pQSink = NULL;}
    if (m_pInputPin->IsConnected() == FALSE) {return S_FALSE;}
    if (m_State != State_Stopped && !m_pInputPin->CanReconnectWhenActive()) {
        return VFW_E_NOT_STOPPED;}
    SetRepaintStatus(FALSE);
    ResetEndOfStream();
    ClearPendingSample();
    m_bAbort = FALSE;
    if (State_Running == m_State) {StopStreaming();}
}
virtual HRESULT SetMediaType(const CMediaType *pmt);{ return NOERROR;}
virtual HRESULT CompleteConnect(IPin *pReceivePin);
{
    ASSERT(CritCheckIn(&m_InterfaceLock));
    m_bAbort = FALSE;
    if (State_Running == GetRealState()) {
        HRESULT hr = StartStreaming();
       SetRepaintStatus(FALSE);
    } else { SetRepaintStatus(TRUE);}
}
virtual HRESULT Receive(IMediaSample *pMediaSample);
{
    HRESULT hr = PrepareReceive(pSample);
    if (m_State == State_Paused) {
        PrepareRender();
        m_bInReceive = FALSE;
        {
           
// We must hold both these locks
            CAutoLock cRendererLock(&m_InterfaceLock);
            if (m_State == State_Stopped) return NOERROR;
            m_bInReceive = TRUE;
            CAutoLock cSampleLock(&m_RendererLock);
            OnReceiveFirstSample(pSample);
        }
        Ready();
    }
    hr = WaitForRenderTime();
    if (FAILED(hr)) {m_bInReceive = FALSE; return NOERROR;}
    PrepareRender();
    m_bInReceive = FALSE;
    CAutoLock cRendererLock(&m_InterfaceLock);
    if (m_State == State_Stopped) return NOERROR;
    CAutoLock cSampleLock(&m_RendererLock);
    Render(m_pMediaSample);
    ClearPendingSample();
    SendEndOfStream();
    CancelNotification();
}
virtual HRESULT CheckMediaType(const CMediaType *) PURE;

d)        其他函数
BOOL IsEndOfStream() { return m_bEOS; };
BOOL IsEndOfStreamDelivered() { return m_bEOSDelivered; };
BOOL IsStreaming() { return m_bStreaming; };
void SetAbortSignal(BOOL bAbort) { m_bAbort = bAbort; };
CAMEvent *GetRenderEvent() { return &m_RenderEvent; };
// Permit access to the transition state
void Ready() { m_evComplete.Set(); };
void NotReady() { m_evComplete.Reset(); };
BOOL CheckReady() { return m_evComplete.Check(); };
FILTER_STATE GetRealState(){ return m_State; };
void SendRepaint();
{
    CAutoLock cSampleLock(&m_RendererLock);
    if (m_bAbort == FALSE) {
        if (m_pInputPin->IsConnected() == TRUE) {
            if (m_pInputPin->IsFlushing() == FALSE) {
                if (IsEndOfStream() == FALSE) {
                    if (m_bRepaintStatus == TRUE) {
                        IPin *pPin = (IPin *) m_pInputPin;
                        NotifyEvent(EC_REPAINT,(LONG_PTR) pPin,0);
                        SetRepaintStatus(FALSE);
}}}}}}
void SendNotifyWindow(IPin *pPin,HWND hwnd);
{
    IMediaEventSink *pSink;
    HRESULT hr = pPin->QueryInterface(IID_IMediaEventSink,(void **)&pSink);
    if (SUCCEEDED(hr)) {
        pSink->Notify(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0);
        pSink->Release();}
    NotifyEvent(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0);
}
BOOL OnDisplayChange();
{
    CAutoLock cSampleLock(&m_RendererLock);
    if (m_pInputPin->IsConnected() == FALSE) {return FALSE;}
    IPin *pPin = (IPin *) m_pInputPin;
    m_pInputPin->AddRef();
    NotifyEvent(EC_DISPLAY_CHANGED,(LONG_PTR) pPin,0);
    SetAbortSignal(TRUE);
    ClearPendingSample();
    m_pInputPin->Release();
}
void SetRepaintStatus(BOOL bRepaint);
{
    CAutoLock cSampleLock(&m_RendererLock);
    m_bRepaintStatus = bRepaint;
}
void TimerCallback();
{
    CAutoLock cRendererLock(&m_RendererLock);
    if (m_EndOfStreamTimer) {
        m_EndOfStreamTimer = 0;
        SendEndOfStream();}
}
void ResetEndOfStreamTimer();
{
    ASSERT(CritCheckOut(&m_RendererLock));
    if (m_EndOfStreamTimer) {
        timeKillEvent(m_EndOfStreamTimer);
        m_EndOfStreamTimer = 0;}
}
HRESULT NotifyEndOfStream();
{
    CAutoLock cRendererLock(&m_RendererLock);
    if (m_bStreaming == FALSE) {return NOERROR;}
    m_EndOfStreamTimer = 0;
    if (m_pPosition) m_pPosition->EOS();
    m_bEOSDelivered = TRUE;
    return NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this);
}
void SignalTimerFired();{m_dwAdvise = 0;}
void WaitForReceiveToComplete();
{
    for (;;) {
        if (!m_bInReceive) {break;}
        MSG msg;
        //  Receive all interthread sendmessages
        PeekMessage(&msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE);
        Sleep(1);
    }
    if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {
        PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
    }
}
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv)
{
  
if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) {
    
return GetMediaPositionInterface(riid,ppv);
   }
else { return CBaseFilter::NonDelegatingQueryInterface(riid,ppv); }
}

e)        友元函数
friend void CALLBACK EndOfStreamTimer(UINT uID,      // Timer identifier
                                      UINT uMsg,     // Not currently used
                                      DWORD_PTR dwUser,  // User information
                                      DWORD_PTR dw1,     // Windows reserved
                                      DWORD_PTR dw2);    // Is also reserved
{
    CBaseRenderer *pRenderer = (CBaseRenderer *) dwUser;
    pRenderer->TimerCallback();
}

 



前一篇: (七) CTransInPlaceFilter及相关联Pin类的源代码解析




相关文章

相关软件




月光软件源码下载编程文档电脑教程网站优化网址导航网络文学游戏天地生活休闲写作范文安妮宝贝站内搜索
电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

月光软件站·版权所有