📄 splitter.h
字号:
//==========================================================================;//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR// PURPOSE.//// Copyright (c) 1996 - 1997 Microsoft Corporation. All Rights Reserved.////--------------------------------------------------------------------------;/* Parser class - this class defines the object that actually splits out the data*//* CBaseParser class This is the object that determines the nature of the data and actually splits the stream*//* Simple stream reader class */class CParseReader{public: /* Set the position */ virtual HRESULT Length(LONGLONG *pLength) = 0; virtual HRESULT SetPointer(LONGLONG) = 0; virtual HRESULT Read(PBYTE pbData, DWORD cbData) = 0;};/* Parsing reader from CAsyncReader */class CParseReaderFromAsync : public CParseReader{public: CParseReaderFromAsync(IAsyncReader *pRdr) : m_pReader(pRdr), m_llPos(0) {}; HRESULT Length(LONGLONG *pLength) { LONGLONG llAvailable; return m_pReader->Length(pLength, &llAvailable); } HRESULT SetPointer(LONGLONG llPos) { m_llPos = 0; return S_OK; } HRESULT Read(PBYTE pbData, DWORD cbData) { HRESULT hr = m_pReader->SyncRead(m_llPos, (LONG)cbData, pbData); if (S_OK == hr) { m_llPos += cbData; } return hr; }private: IAsyncReader *m_pReader; LONGLONG m_llPos;};class CParserNotify;class CBaseParser{public: /* Instantiate a parser pNotify - to call back the calling object to create streams etc */ CBaseParser(CParserNotify *pNotify, HRESULT *phr) : m_pNotify(pNotify) {}; /* Initialize a parser pmt - type of stream if known - can be NULL pRdr - way to read the source medium - can be NULL */ virtual HRESULT Init( CParseReader *pRdr ) = 0; /* Get the size and count of buffers preferred based on the actual content */ virtual void GetSizeAndCount(LONG *plSize, LONG *plCount) = 0; /* Call this to reinitialize for a new stream */ virtual void StreamReset() = 0; /* Call this to pass new stream data : pbData - pointer to data lData - length of data plProcessed - Amount of data consumed */ virtual HRESULT Process( const BYTE *pbData, LONG lData, LONG *plProcessed ) = 0;protected: CParserNotify * const m_pNotify;};/* Parser calls back to create streams and spit out buffers*/class CStreamNotify;class CParserNotify{public: /* Create an output stream with type *pmt, notifications to this stream passed to the **pStreamNotify object */ virtual HRESULT CreateStream( LPCWSTR pszName, CStreamNotify **pStreamNotify) = 0;};class CStreamNotify{public: virtual HRESULT SendSample( const BYTE *pbData, LONG lData, REFERENCE_TIME rtStart, BOOL bSync ) = 0; /* Add a media type that's supported */ virtual HRESULT AddMediaType(CMediaType const *pmt) = 0; /* Return the current type */ virtual void CurrentMediaType(AM_MEDIA_TYPE *pmt) = 0;};/* Splitter filter base classes *//* Design : A splitter filter will have 1 input pin and multiple output pins CBaseSplitterFilter defines a base filter with 1 input pin and a list of output pins. This base class provides for pin enumeration, correct distribution of EndOfStream and handling of errors. The object structure is : IsA CBaseSplitterFilter <-------- CBaseFilter Allocators: This class relies on use CSequentialAllocator The input pin is designed around CPullPin which hooks up to IAsyncReader on the upstream output pin*/class CBaseSplitterFilter;class CBaseParser;/* Input pin stuff The input pin deletes all the output pins when it's disconnected On connection the output pins are created based on the media type and possibly on the file content The base class handles things like flushing and end of stream*//* Special output pin type to handle lifetime */class CSplitterOutputPin : public CBaseOutputPin{public: // Constructor CSplitterOutputPin( CBaseSplitterFilter *pFilter, HRESULT *phr, LPCWSTR pName); ~CSplitterOutputPin(); // CUnknown methods STDMETHODIMP_(ULONG) NonDelegatingAddRef(); STDMETHODIMP_(ULONG) NonDelegatingRelease(); // CBaseOutputPin methods - we just override these to do // our own hack allocator STDMETHOD(Notify)(IBaseFilter* pSender, Quality q); // override this to set the buffer size and count. Return an error // if the size/count is not to your liking virtual HRESULT DecideBufferSize( IMemAllocator * pAlloc, ALLOCATOR_PROPERTIES * pProp); // negotiate the allocator and its buffer size/count // calls DecideBufferSize to call SetCountAndSize virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc); // override this to control the connection virtual HRESULT InitAllocator(IMemAllocator **ppAlloc); // Check the media type proposed HRESULT CheckMediaType(const CMediaType *); // returns the preferred formats for a pin HRESULT GetMediaType(int iPosition,CMediaType *pMediaType); // Send sample generated by parser HRESULT SendSample( const BYTE *pbData, LONG lData, REFERENCE_TIME rtStart, BOOL bSync ); /* Add a media type */ HRESULT AddMediaType( CMediaType const *pmt ); HRESULT DeliverEndOfStream() { m_pOutputQueue->EOS(); return S_OK; } // Delete our output queue on inactive HRESULT Inactive() { HRESULT hr = CBaseOutputPin::Inactive(); if (FAILED(hr)) { return hr; } delete m_pOutputQueue; m_pOutputQueue = NULL; return S_OK; } /* Wrapper to call output queue to flush samples */ void SendAnyway() { if (NULL != m_pOutputQueue) { m_pOutputQueue->SendAnyway(); } } // Override Active and EndFlush to set the discontinuity flag HRESULT Active() { m_bDiscontinuity = TRUE; /* If we're not connected we don't participate so it's OK */ if (!IsConnected()) { return S_OK; } HRESULT hr = CBaseOutputPin::Active(); if (FAILED(hr)) { return hr; } /* Create our batch list */ ASSERT(m_pOutputQueue == NULL); hr = S_OK; m_pOutputQueue = new COutputQueue(GetConnected(), // input pin &hr, // return code FALSE, // Auto detect TRUE, // ignored 50, // batch size TRUE, // exact batch 50); // queue size if (m_pOutputQueue == NULL) { return E_OUTOFMEMORY; } if (FAILED(hr)) { delete m_pOutputQueue; m_pOutputQueue = NULL; } return hr; } HRESULT DeliverBeginFlush() { /* We're already locked via the input pin */ m_pOutputQueue->BeginFlush(); return S_OK; } HRESULT DeliverEndFlush() { /* We're already locked via the input pin */ m_bDiscontinuity = TRUE; m_pOutputQueue->EndFlush(); return S_OK; } // Get our notify object CStreamNotify *GetNotify()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -