DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析(转载)

转载 2007年10月14日 10:20:00
转自http://blog.csdn.net/alvachien/archive/2005/02/25/301913.aspx
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_pPosition和m_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();
}
 

三十八、100行python代码实现机器学习自动分类

现在朋友圈、公众号、微博信息应接不暇,以微信公众号举例,看技术极客是怎么自动筛出自己想看的文章的,100行机器学习代码就能自动帮你归好类,要想找出想看的和不想看的,你再也不用刷朋友圈了 请尊重原创,...
  • jiangjingxuan
  • jiangjingxuan
  • 2017年01月25日 11:56
  • 2289

一个清华学子写的关于directshow的学习心得【转】

学习DirectShow有一段时间了,把这段学习过程中翻译出来的SDK与大家分享,同时也希望专家们指出我理解上的错误,万分感谢。 1. DirectShow介绍     DirectShow是一个wi...
  • wishfly
  • wishfly
  • 2015年11月18日 10:30
  • 9759

机器学习的各种分类器,MATLAB实现代码

train_data是训练特征数据, train_label是分类标签。 Predict_label是预测的标签。 MatLab训练数据, 得到语义标签向量 Scores(概率输出)。 ...
  • xs1997
  • xs1997
  • 2017年03月29日 14:51
  • 1400

DirectShow 学习之 CSource类和其一个具体实现例子的源代码分析

1.       CSourceStream类,是CSource类的OutputPin[source.h/source.cpp] 派生自CAMThread和CBaseOutputPin l    ...
  • shejingjing
  • shejingjing
  • 2011年09月13日 15:25
  • 290

DirectShow PIN 連接教學

毛毛     DirectShow PIN 連接教學   一個寫作機會,順便看了一下 DirectShow 發現它.. 太強大了... 但覺得還是自己用...
  • l5201314131413141314
  • l5201314131413141314
  • 2011年12月22日 14:35
  • 668

DirectShow Filter 最简单的示例+两个 PIN 的实现

  • 2014年05月27日 17:09
  • 20KB
  • 下载

摘要 MAC,PIN,磁道密钥 在平时的工作中,很少接触安全这块内容,最近需要自己独立完成安全这块内容,在开发中遇到的问题会在下面的理解中得到相应的解决。 在交易平台中,基于安全考

摘要 MAC,PIN,磁道密钥     在平时的工作中,很少接触安全这块内容,最近需要自己独立完成安全这块内容,在开发中遇到的问题会在下面的理解中得到相应的解决。     在交易平...
  • qq_33038541
  • qq_33038541
  • 2016年04月20日 10:50
  • 368

DirectShow 学习笔记&lt; 一&gt; -- 第一个程序 源代码

  • 2013年08月28日 15:52
  • 528KB
  • 下载

划分聚类分析: K均值和基于中心点的划分(PAM) 及相应代码

  • 2017年12月03日 09:52
  • 222KB
  • 下载

【live555】WISInput类及其重要相关类分析

(1)WISInput作为WIS-STREAMER的最为重要的类,代表数据输入和获取。 // An interface to the WIS GO7007 capture device. // C++...
  • commshare
  • commshare
  • 2013年12月02日 16:43
  • 861
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析(转载)
举报原因:
原因补充:

(最多只允许输入30个字)