StreamSwitcher.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:9k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // Copyright 2003 Gabest.
  2. // http://www.gabest.org
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
  17. // http://www.gnu.org/copyleft/gpl.html
  18. #pragma once
  19. #include <afxtempl.h>
  20. #include <atlbase.h>
  21. #include <atlcoll.h>
  22. #define PauseGraph 
  23. CComQIPtr<IMediaControl> _pMC(m_pGraph); 
  24. OAFilterState _fs = -1; 
  25. if(_pMC) _pMC->GetState(1000, &_fs); 
  26. if(_fs == State_Running) 
  27. _pMC->Pause(); 
  28.  
  29. HRESULT _hr = E_FAIL; 
  30. CComQIPtr<IMediaSeeking> _pMS((IUnknown*)(INonDelegatingUnknown*)m_pGraph); 
  31. LONGLONG _rtNow = 0; 
  32. if(_pMS) _hr = _pMS->GetCurrentPosition(&_rtNow); 
  33. #define ResumeGraph 
  34. if(SUCCEEDED(_hr) && _pMS) 
  35. _hr = _pMS->SetPositions(&_rtNow, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); 
  36.  
  37. if(_fs == State_Running && _pMS) 
  38. _pMC->Run(); 
  39. class CStreamSwitcherFilter;
  40. class CStreamSwitcherPassThru : public IMediaSeeking, public CMediaPosition
  41. {
  42. protected:
  43. CStreamSwitcherFilter* m_pFilter;
  44. public:
  45.     CStreamSwitcherPassThru(LPUNKNOWN, HRESULT* phr, CStreamSwitcherFilter* pFilter);
  46. DECLARE_IUNKNOWN
  47.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  48.     // IMediaSeeking methods
  49.     STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
  50.     STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
  51.     STDMETHODIMP SetTimeFormat(const GUID* pFormat);
  52.     STDMETHODIMP GetTimeFormat(GUID* pFormat);
  53.     STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
  54.     STDMETHODIMP IsFormatSupported(const GUID* pFormat);
  55.     STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
  56.     STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
  57.     STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD CurrentFlags, LONGLONG* pStop, DWORD StopFlags);
  58.     STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
  59.     STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
  60.     STDMETHODIMP GetStopPosition(LONGLONG* pStop);
  61.     STDMETHODIMP SetRate(double dRate);
  62.     STDMETHODIMP GetRate(double* pdRate);
  63.     STDMETHODIMP GetDuration(LONGLONG* pDuration);
  64.     STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
  65.     STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
  66.     // IMediaPosition properties
  67.     STDMETHODIMP get_Duration(REFTIME* plength);
  68.     STDMETHODIMP put_CurrentPosition(REFTIME llTime);
  69.     STDMETHODIMP get_StopTime(REFTIME* pllTime);
  70.     STDMETHODIMP put_StopTime(REFTIME llTime);
  71.     STDMETHODIMP get_PrerollTime(REFTIME* pllTime);
  72.     STDMETHODIMP put_PrerollTime(REFTIME llTime);
  73.     STDMETHODIMP get_Rate(double* pdRate);
  74.     STDMETHODIMP put_Rate(double dRate);
  75.     STDMETHODIMP get_CurrentPosition(REFTIME* pllTime);
  76.     STDMETHODIMP CanSeekForward(LONG* pCanSeekForward);
  77.     STDMETHODIMP CanSeekBackward(LONG* pCanSeekBackward);
  78. };
  79. class CStreamSwitcherInputPin;
  80. class CStreamSwitcherAllocator : public CMemAllocator
  81. {
  82. protected:
  83.     CStreamSwitcherInputPin* m_pPin;
  84.     CMediaType m_mt;
  85. bool m_fMediaTypeChanged;
  86. public:
  87. CStreamSwitcherAllocator(CStreamSwitcherInputPin* pPin, HRESULT* phr);
  88. #ifdef DEBUG
  89. ~CStreamSwitcherAllocator();
  90. #endif
  91. STDMETHODIMP_(ULONG) NonDelegatingAddRef();
  92. STDMETHODIMP_(ULONG) NonDelegatingRelease();
  93. STDMETHODIMP GetBuffer(
  94. IMediaSample** ppBuffer, 
  95. REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, 
  96. DWORD dwFlags);
  97. void NotifyMediaType(const CMediaType& mt);
  98. };
  99. [uuid("DA395FA3-4A3E-4D85-805E-0BEFF53D4BCD")]
  100. interface IStreamSwitcherInputPin : public IUnknown
  101. {
  102. STDMETHOD_(bool, IsActive)() = 0;
  103. };
  104. class CStreamSwitcherInputPin : public CBaseInputPin, public IPinConnection, public IStreamSwitcherInputPin
  105. {
  106. friend class CStreamSwitcherAllocator;
  107. CStreamSwitcherAllocator m_Allocator;
  108. BOOL m_bSampleSkipped;
  109. BOOL m_bQualityChanged;
  110. BOOL m_bUsingOwnAllocator;
  111. CAMEvent m_evBlock;
  112. bool m_fCanBlock;
  113. HRESULT Active();
  114. HRESULT Inactive();
  115. HRESULT QueryAcceptDownstream(const AM_MEDIA_TYPE* pmt);
  116. HRESULT InitializeOutputSample(IMediaSample* pInSample, IMediaSample** ppOutSample);
  117. HANDLE m_hNotifyEvent;
  118. public:
  119.     CStreamSwitcherInputPin(CStreamSwitcherFilter* pFilter, HRESULT* phr, LPCWSTR pName);
  120. DECLARE_IUNKNOWN
  121.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  122.     CMediaType& CurrentMediaType() {return m_mt;}
  123. IMemAllocator* CurrentAllocator() {return m_pAllocator;}
  124. bool IsUsingOwnAllocator() {return m_bUsingOwnAllocator == TRUE;}
  125. void Block(bool fBlock);
  126. CCritSec m_csReceive;
  127. // pure virtual
  128. HRESULT CheckMediaType(const CMediaType* pmt);
  129. // virtual
  130. HRESULT CheckConnect(IPin* pPin);
  131. HRESULT CompleteConnect(IPin* pReceivePin);
  132. // IPin
  133. STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE* pmt);
  134. STDMETHODIMP ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt);
  135. STDMETHODIMP GetAllocator(IMemAllocator** ppAllocator);
  136. STDMETHODIMP NotifyAllocator(IMemAllocator* pAllocator, BOOL bReadOnly);
  137. STDMETHODIMP BeginFlush();
  138.     STDMETHODIMP EndFlush();
  139. STDMETHODIMP EndOfStream();
  140. // IMemInputPin
  141.     STDMETHODIMP Receive(IMediaSample* pSample);
  142. STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
  143. // IPinConnection
  144. STDMETHODIMP DynamicQueryAccept(const AM_MEDIA_TYPE* pmt);
  145. STDMETHODIMP NotifyEndOfStream(HANDLE hNotifyEvent);
  146. STDMETHODIMP IsEndPin();
  147. STDMETHODIMP DynamicDisconnect();
  148. // IStreamSwitcherInputPin
  149. STDMETHODIMP_(bool) IsActive();
  150. };
  151. class CStreamSwitcherOutputPin : public CBaseOutputPin, public IStreamBuilder
  152. {
  153. CComPtr<IUnknown> m_pStreamSwitcherPassThru;
  154. CComPtr<IPinConnection> m_pPinConnection;
  155. HRESULT QueryAcceptUpstream(const AM_MEDIA_TYPE* pmt);
  156. public:
  157.     CStreamSwitcherOutputPin(CStreamSwitcherFilter* pFilter, HRESULT* phr);
  158. DECLARE_IUNKNOWN
  159.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  160.     CMediaType& CurrentMediaType() {return m_mt;}
  161. IMemAllocator* CurrentAllocator() {return m_pAllocator;}
  162. IPinConnection* CurrentPinConnection() {return m_pPinConnection;}
  163. // pure virtual
  164. HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties);
  165. // virtual
  166. HRESULT CheckConnect(IPin* pPin);
  167. HRESULT BreakConnect();
  168. HRESULT CompleteConnect(IPin* pReceivePin);
  169. HRESULT CheckMediaType(const CMediaType* pmt);
  170. HRESULT GetMediaType(int iPosition, CMediaType* pmt);
  171. // IPin
  172. STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE* pmt);
  173. // IQualityControl
  174. STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
  175. // IStreamBuilder
  176. STDMETHODIMP Render(IPin* ppinOut, IGraphBuilder* pGraph);
  177. STDMETHODIMP Backout(IPin* ppinOut, IGraphBuilder* pGraph);
  178. };
  179. class CStreamSwitcherFilter : public CBaseFilter, public IAMStreamSelect
  180. {
  181. friend class CStreamSwitcherInputPin;
  182. friend class CStreamSwitcherOutputPin;
  183. friend class CStreamSwitcherPassThru;
  184. CList<CStreamSwitcherInputPin*> m_pInputs;
  185. CStreamSwitcherInputPin* m_pInput;
  186. CStreamSwitcherOutputPin* m_pOutput;
  187. CCritSec m_csState, m_csPins;
  188. HRESULT CompleteConnect(PIN_DIRECTION dir, CBasePin* pPin, IPin* pReceivePin);
  189. protected:
  190. void SelectInput(CStreamSwitcherInputPin* pInput);
  191. public:
  192. CStreamSwitcherFilter(LPUNKNOWN lpunk, HRESULT* phr, const CLSID& clsid);
  193. virtual ~CStreamSwitcherFilter();
  194. DECLARE_IUNKNOWN
  195.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  196. int GetPinCount();
  197. CBasePin* GetPin(int n);
  198. int GetConnectedInputPinCount();
  199. CStreamSwitcherInputPin* GetConnectedInputPin(int n);
  200. CStreamSwitcherInputPin* GetInputPin();
  201. CStreamSwitcherOutputPin* GetOutputPin();
  202. bool m_fResetOutputMediaType;
  203. void ResetOutputMediaType() {m_fResetOutputMediaType = true;}
  204. // override these
  205. virtual HRESULT CheckMediaType(const CMediaType* pmt) = 0;
  206. virtual HRESULT Transform(IMediaSample* pIn, IMediaSample* pOut);
  207. virtual CMediaType CreateNewOutputMediaType(CMediaType mt, long& cbBuffer);
  208. virtual void OnNewOutputMediaType(const CMediaType& mtIn, const CMediaType& mtOut) {}
  209. // IAMStreamSelect
  210.     STDMETHODIMP Count(DWORD* pcStreams);
  211.     STDMETHODIMP Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk);
  212.     STDMETHODIMP Enable(long lIndex, DWORD dwFlags);
  213. };