📄 splitter.h
字号:
{ return &m_Notify; }protected: // Get a pointer to our allocator CSubAllocator *Allocator() { return (CSubAllocator *)m_pAllocator; } // Get a properly cast pointer to our filter CBaseSplitterFilter *Filter() { return (CBaseSplitterFilter *)m_pFilter; }protected: // Stream notify stuff class CImplStreamNotify : public CStreamNotify { public: CImplStreamNotify(CSplitterOutputPin *pPin) : m_pPin(pPin) {} HRESULT SendSample( const BYTE *pbData, LONG lData, REFERENCE_TIME rtStart, BOOL bSync ) { return m_pPin->SendSample(pbData, lData, rtStart, bSync); } HRESULT AddMediaType(CMediaType const *pmt) { return m_pPin->AddMediaType(pmt); } void CurrentMediaType(AM_MEDIA_TYPE *pmt) { m_pPin->ConnectionMediaType(pmt); } private: CSplitterOutputPin * const m_pPin; }; CImplStreamNotify m_Notify; // Remember when to send NewSegment and discontinuity */ BOOL m_bDiscontinuity; // Output queue COutputQueue *m_pOutputQueue; // List of media types we support CGenericList<CMediaType> m_lTypes;};/* Base CSplitterInputPin on CPullPin*/class CSplitterInputPin : public CBaseInputPin{public: CSplitterInputPin( CBaseSplitterFilter *pFilter, HRESULT *phr); /* NonDelegating IUnknown methods - we don't support IMemInputPin */ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv) { if (riid == IID_IMemInputPin) { return E_NOINTERFACE; } return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); } /* IPin methods */ STDMETHODIMP EndOfStream(); STDMETHODIMP BeginFlush(); STDMETHODIMP EndFlush(); STDMETHODIMP Receive(IMediaSample *pSample); /* IMemInputPin methods */ /* Where we're told which allocator we are using */ STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator) { if (pAllocator != (IMemAllocator *)m_pAllocator) { return E_FAIL; } else { return S_OK; } } /* Say if we're blocking */ STDMETHODIMP ReceiveCanBlock() { return S_FALSE; } /* CBasePin methods */ HRESULT BreakConnect(); // Override to release puller HRESULT CheckConnect(IPin *pPin); // Override to connect to puller HRESULT Active(); HRESULT Inactive(); HRESULT CheckMediaType(const CMediaType *pmt); HRESULT CompleteConnect(IPin *pReceivePin); /* Report filter from reader */ void NotifyError(HRESULT hr) { if (FAILED(hr)) { m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0); } EndOfStream(); }; /* Convenient way to get the allocator */ CSequentialAllocator *Allocator() { return (CSequentialAllocator *)m_pAllocator; } /* Point to our media type */ CMediaType *MediaType() { return &m_mt; } /* Return our async reader */ IAsyncReader *Reader() { IAsyncReader *pReader = m_puller.GetReader(); pReader->Release(); return pReader; }private: // Get a properly case pointer to our filter CBaseSplitterFilter *Filter() { return (CBaseSplitterFilter *)m_pFilter; } // class to pull data from IAsyncReader if we detect that interface // on the output pin class CImplPullPin : public CPullPin { // forward everything to containing pin CSplitterInputPin * const m_pPin; public: CImplPullPin(CSplitterInputPin* pPin) : m_pPin(pPin) { }; // forward this to the pin's IMemInputPin::Receive HRESULT Receive(IMediaSample* pSample) { return m_pPin->Receive(pSample); }; // override this to handle end-of-stream HRESULT EndOfStream(void) { return m_pPin->EndOfStream(); }; // these errors have already been reported to the filtergraph // by the upstream filter so ignore them void OnError(HRESULT hr) { // ignore VFW_E_WRONG_STATE since this happens normally // during stopping and seeking if (hr != VFW_E_WRONG_STATE) { m_pPin->NotifyError(hr); } }; // flush the pin and all downstream HRESULT BeginFlush() { return m_pPin->BeginFlush(); }; // Tell the next guy we've finished flushing HRESULT EndFlush() { return m_pPin->EndFlush(); }; }; CImplPullPin m_puller;};class CBaseSplitterFilter : public CBaseFilter{friend class CSplitterOutputPin;friend class CSplitterInputPin;public: // Constructor and destructor CBaseSplitterFilter( TCHAR *pName, LPUNKNOWN pUnk, REFCLSID rclsid, HRESULT *phr); ~CBaseSplitterFilter(); // IMediaFilter methods - override these to manage locking STDMETHODIMP Stop(); STDMETHODIMP Pause(); /* Stream control stuff */ virtual HRESULT BeginFlush(); virtual HRESULT EndFlush(); virtual void EndOfStream(); virtual HRESULT Receive(IMediaSample *pSample); virtual HRESULT CheckInputType(const CMediaType *pmt) = 0; virtual HRESULT CompleteConnect(IPin *pReceivePin); // Create the parser virtual CBaseParser *CreateParser( CParserNotify *pNotify, CMediaType *pType) = 0; // CBaseFilter methods int GetPinCount(); // 0 pins CBasePin *GetPin(int iPin); /* Add a new output pin */ BOOL AddOutputPin(CSplitterOutputPin *pOutputPin); /* Destroy the output pins */ void DestroyOutputPins(); /* Destroy the input pin */ void DestroyInputPin(); /* Notify to create a new stream Called back through CParseNotify */ HRESULT CreateStream( LPCWSTR pszName, CStreamNotify **ppStreamNotify ); /* Called when BreakConnect called on the input pin */ virtual void BreakConnect();protected: /* Utility to get the allocator */ CSequentialAllocator *Allocator() { return InputPin()->Allocator(); } /* Reset the states of the allocator and parser ready to receive a new stream */ void ResetAllocatorAndParser() { Allocator()->Flush(); m_pParser->StreamReset(); } CSplitterInputPin *InputPin() { return (CSplitterInputPin *)m_pInput; }protected: // Our input pin - created by derived classes CBaseInputPin *m_pInput; // Our output pin list - Derived classes append to this CGenericList<CSplitterOutputPin> m_OutputPins; // Filter locking CCritSec m_csFilter; // Streaming lock CCritSec m_csStream; // Pin database lock CCritSec m_csPins; // Parser - created when we're connected CBaseParser *m_pParser; // Parser notify - use member variable to avoid mulitple inheritance class CImplParserNotify : public CParserNotify { public: CImplParserNotify(CBaseSplitterFilter *pFilter) : m_pFilter(pFilter) {}; HRESULT CreateStream( LPCWSTR pszName, CStreamNotify **ppStreamNotify ) { return m_pFilter->CreateStream(pszName, ppStreamNotify); } private: CBaseSplitterFilter * const m_pFilter; }; CImplParserNotify m_Notify;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -