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

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #pragma once
  22. #include <atlbase.h>
  23. #include <atlcoll.h>
  24. #include <afxtempl.h>
  25. #include <qnetwork.h>
  26. #include "........includeIKeyFrameInfo.h"
  27. #include "........includeIBufferInfo.h"
  28. #include "........includeIBitRateInfo.h"
  29. #include "BaseSplitterFileEx.h"
  30. #include "AsyncReader.h"
  31. #include "......DSUtilDSMPropertyBag.h"
  32. #include "......DSUtilFontInstaller.h"
  33. class Packet
  34. {
  35. public:
  36. DWORD TrackNumber;
  37. BOOL bDiscontinuity, bSyncPoint, bAppendable;
  38. static const REFERENCE_TIME INVALID_TIME = _I64_MIN;
  39. REFERENCE_TIME rtStart, rtStop;
  40. CArray<BYTE> pData;
  41. AM_MEDIA_TYPE* pmt;
  42. Packet() {pmt = NULL; bDiscontinuity = bAppendable = FALSE;}
  43. virtual ~Packet() {if(pmt) DeleteMediaType(pmt);}
  44. virtual int GetSize() {return pData.GetSize();}
  45. };
  46. class CPacketQueue 
  47. : public CCritSec
  48. , protected CAutoPtrList<Packet>
  49. {
  50. int m_size;
  51. public:
  52. CPacketQueue();
  53. void Add(CAutoPtr<Packet> p);
  54. CAutoPtr<Packet> Remove();
  55. void RemoveAll();
  56. int GetCount(), GetSize();
  57. };
  58. class CBaseSplitterFilter;
  59. class CBaseSplitterInputPin 
  60. : public CBasePin
  61. {
  62. protected:
  63. CComQIPtr<IAsyncReader> m_pAsyncReader;
  64. public:
  65. CBaseSplitterInputPin(TCHAR* pName, CBaseSplitterFilter* pFilter, CCritSec* pLock, HRESULT* phr);
  66. virtual ~CBaseSplitterInputPin();
  67. HRESULT GetAsyncReader(IAsyncReader** ppAsyncReader);
  68. DECLARE_IUNKNOWN;
  69.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  70.     HRESULT CheckMediaType(const CMediaType* pmt);
  71.     HRESULT CheckConnect(IPin* pPin);
  72.     HRESULT BreakConnect();
  73. HRESULT CompleteConnect(IPin* pPin);
  74. STDMETHODIMP BeginFlush();
  75. STDMETHODIMP EndFlush();
  76. };
  77. class CBaseSplitterOutputPin 
  78. : public CBaseOutputPin
  79. , public IDSMPropertyBagImpl
  80. , protected CAMThread
  81. , public IMediaSeeking
  82. , public IBitRateInfo
  83. {
  84. protected:
  85. CArray<CMediaType> m_mts;
  86. int m_nBuffers;
  87. private:
  88. CPacketQueue m_queue;
  89. HRESULT m_hrDeliver;
  90. bool m_fFlushing, m_fFlushed;
  91. CAMEvent m_eEndFlush;
  92. enum {CMD_EXIT};
  93.     DWORD ThreadProc();
  94. void MakeISCRHappy();
  95. // please only use DeliverPacket from the derived class
  96.     HRESULT GetDeliveryBuffer(IMediaSample** ppSample, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags);
  97.     HRESULT Deliver(IMediaSample* pSample);
  98. // bitrate stats
  99. struct 
  100. {
  101. UINT64 nTotalBytesDelivered;
  102. REFERENCE_TIME rtTotalTimeDelivered;
  103. UINT64 nBytesSinceLastDeliverTime;
  104. REFERENCE_TIME rtLastDeliverTime;
  105. DWORD nCurrentBitRate;
  106. DWORD nAverageBitRate;
  107. } m_brs;
  108. protected:
  109. REFERENCE_TIME m_rtStart;
  110. // override this if you need some second level stream specific demuxing (optional)
  111. // the default implementation will send the sample as is
  112. virtual HRESULT DeliverPacket(CAutoPtr<Packet> p);
  113. // IMediaSeeking
  114. STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
  115. STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
  116. STDMETHODIMP IsFormatSupported(const GUID* pFormat);
  117. STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
  118. STDMETHODIMP GetTimeFormat(GUID* pFormat);
  119. STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
  120. STDMETHODIMP SetTimeFormat(const GUID* pFormat);
  121. STDMETHODIMP GetDuration(LONGLONG* pDuration);
  122. STDMETHODIMP GetStopPosition(LONGLONG* pStop);
  123. STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
  124. STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
  125. STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
  126. STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
  127. STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
  128. STDMETHODIMP SetRate(double dRate);
  129. STDMETHODIMP GetRate(double* pdRate);
  130. STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
  131. public:
  132. CBaseSplitterOutputPin(CArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0);
  133. CBaseSplitterOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0);
  134. virtual ~CBaseSplitterOutputPin();
  135. DECLARE_IUNKNOWN;
  136.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  137. HRESULT SetName(LPCWSTR pName);
  138.     HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
  139.     HRESULT CheckMediaType(const CMediaType* pmt);
  140.     HRESULT GetMediaType(int iPosition, CMediaType* pmt);
  141. CMediaType& CurrentMediaType() {return m_mt;}
  142. STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
  143. // Queueing
  144. HANDLE GetThreadHandle() {ASSERT(m_hThread != NULL); return m_hThread;}
  145. void SetThreadPriority(int nPriority) {if(m_hThread) ::SetThreadPriority(m_hThread, nPriority);}
  146. HRESULT Active();
  147.     HRESULT Inactive();
  148.     HRESULT DeliverBeginFlush();
  149. HRESULT DeliverEndFlush();
  150.     HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
  151. int QueueCount();
  152. int QueueSize();
  153.     HRESULT QueueEndOfStream();
  154. HRESULT QueuePacket(CAutoPtr<Packet> p);
  155. // returns true for everything which (the lack of) would not block other streams (subtitle streams, basically)
  156. virtual bool IsDiscontinuous();
  157. // returns IStreamsSwitcherInputPin::IsActive(), when it can find one downstream
  158. bool IsActive();
  159. // IBitRateInfo
  160. STDMETHODIMP_(DWORD) GetCurrentBitRate() {return m_brs.nCurrentBitRate;}
  161. STDMETHODIMP_(DWORD) GetAverageBitRate() {return m_brs.nAverageBitRate;}
  162. };
  163. class CBaseSplitterFilter 
  164. : public CBaseFilter
  165. , public CCritSec
  166. , public IDSMPropertyBagImpl
  167. , public IDSMResourceBagImpl
  168. , public IDSMChapterBagImpl
  169. , protected CAMThread
  170. , public IFileSourceFilter
  171. , public IMediaSeeking
  172. , public IAMOpenProgress
  173. , public IAMMediaContent
  174. , public IAMExtendedSeeking
  175. , public IKeyFrameInfo
  176. , public IBufferInfo
  177. {
  178. CCritSec m_csPinMap;
  179. CAtlMap<DWORD, CBaseSplitterOutputPin*> m_pPinMap;
  180. CCritSec m_csmtnew;
  181. CAtlMap<DWORD, CMediaType> m_mtnew;
  182. CAutoPtrList<CBaseSplitterOutputPin> m_pRetiredOutputs;
  183. CComQIPtr<ISyncReader> m_pSyncReader;
  184. protected:
  185. CStringW m_fn;
  186. CAutoPtr<CBaseSplitterInputPin> m_pInput;
  187. CAutoPtrList<CBaseSplitterOutputPin> m_pOutputs;
  188. CBaseSplitterOutputPin* GetOutputPin(DWORD TrackNum);
  189. DWORD GetOutputTrackNum(CBaseSplitterOutputPin* pPin);
  190. HRESULT AddOutputPin(DWORD TrackNum, CAutoPtr<CBaseSplitterOutputPin> pPin);
  191. HRESULT RenameOutputPin(DWORD TrackNumSrc, DWORD TrackNumDst, const AM_MEDIA_TYPE* pmt);
  192. virtual HRESULT DeleteOutputs();
  193. virtual HRESULT CreateOutputs(IAsyncReader* pAsyncReader) = 0; // override this ...
  194. LONGLONG m_nOpenProgress;
  195. bool m_fAbort;
  196. REFERENCE_TIME m_rtDuration; // derived filter should set this at the end of CreateOutputs
  197. REFERENCE_TIME m_rtStart, m_rtStop, m_rtCurrent, m_rtNewStart, m_rtNewStop;
  198. double m_dRate;
  199. CList<UINT64> m_bDiscontinuitySent;
  200. CList<CBaseSplitterOutputPin*> m_pActivePins;
  201. CAMEvent m_eEndFlush;
  202. bool m_fFlushing;
  203. void DeliverBeginFlush();
  204. void DeliverEndFlush();
  205. HRESULT DeliverPacket(CAutoPtr<Packet> p);
  206. DWORD m_priority;
  207. CFontInstaller m_fontinst;
  208. protected:
  209. enum {CMD_EXIT, CMD_SEEK};
  210.     DWORD ThreadProc();
  211. // ... and also override all these too
  212. virtual bool DemuxInit() = 0;
  213. virtual void DemuxSeek(REFERENCE_TIME rt) = 0;
  214. virtual bool DemuxLoop() = 0;
  215. public:
  216. CBaseSplitterFilter(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid);
  217. virtual ~CBaseSplitterFilter();
  218. DECLARE_IUNKNOWN;
  219.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
  220. bool IsAnyPinDrying();
  221. HRESULT BreakConnect(PIN_DIRECTION dir, CBasePin* pPin);
  222. HRESULT CompleteConnect(PIN_DIRECTION dir, CBasePin* pPin);
  223. int GetPinCount();
  224. CBasePin* GetPin(int n);
  225. STDMETHODIMP Stop();
  226. STDMETHODIMP Pause();
  227. STDMETHODIMP Run(REFERENCE_TIME tStart);
  228. // IFileSourceFilter
  229. STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
  230. STDMETHODIMP GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt);
  231. // IMediaSeeking
  232. STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
  233. STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
  234. STDMETHODIMP IsFormatSupported(const GUID* pFormat);
  235. STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
  236. STDMETHODIMP GetTimeFormat(GUID* pFormat);
  237. STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
  238. STDMETHODIMP SetTimeFormat(const GUID* pFormat);
  239. STDMETHODIMP GetDuration(LONGLONG* pDuration);
  240. STDMETHODIMP GetStopPosition(LONGLONG* pStop);
  241. STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
  242. STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
  243. STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
  244. STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
  245. STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
  246. STDMETHODIMP SetRate(double dRate);
  247. STDMETHODIMP GetRate(double* pdRate);
  248. STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
  249. protected:
  250. friend class CBaseSplitterOutputPin;
  251. virtual HRESULT SetPositionsInternal(void* id, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
  252. private:
  253. REFERENCE_TIME m_rtLastStart, m_rtLastStop;
  254. CList<void*> m_LastSeekers;
  255. public:
  256. // IAMOpenProgress
  257. STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
  258. STDMETHODIMP AbortOperation();
  259. // IDispatch
  260. STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
  261. STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {return E_NOTIMPL;}
  262. STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) {return E_NOTIMPL;}
  263. STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) {return E_NOTIMPL;}
  264. // IAMMediaContent
  265. STDMETHODIMP get_AuthorName(BSTR* pbstrAuthorName);
  266. STDMETHODIMP get_Title(BSTR* pbstrTitle);
  267. STDMETHODIMP get_Rating(BSTR* pbstrRating);
  268. STDMETHODIMP get_Description(BSTR* pbstrDescription);
  269. STDMETHODIMP get_Copyright(BSTR* pbstrCopyright);
  270. STDMETHODIMP get_BaseURL(BSTR* pbstrBaseURL) {return E_NOTIMPL;}
  271. STDMETHODIMP get_LogoURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
  272. STDMETHODIMP get_LogoIconURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
  273. STDMETHODIMP get_WatermarkURL(BSTR* pbstrWatermarkURL) {return E_NOTIMPL;}
  274. STDMETHODIMP get_MoreInfoURL(BSTR* pbstrMoreInfoURL) {return E_NOTIMPL;}
  275. STDMETHODIMP get_MoreInfoBannerImage(BSTR* pbstrMoreInfoBannerImage) {return E_NOTIMPL;}
  276. STDMETHODIMP get_MoreInfoBannerURL(BSTR* pbstrMoreInfoBannerURL) {return E_NOTIMPL;}
  277. STDMETHODIMP get_MoreInfoText(BSTR* pbstrMoreInfoText) {return E_NOTIMPL;}
  278. // IAMExtendedSeeking
  279. STDMETHODIMP get_ExSeekCapabilities(long* pExCapabilities);
  280. STDMETHODIMP get_MarkerCount(long* pMarkerCount);
  281. STDMETHODIMP get_CurrentMarker(long* pCurrentMarker);
  282. STDMETHODIMP GetMarkerTime(long MarkerNum, double* pMarkerTime);
  283. STDMETHODIMP GetMarkerName(long MarkerNum, BSTR* pbstrMarkerName);
  284. STDMETHODIMP put_PlaybackSpeed(double Speed) {return E_NOTIMPL;}
  285. STDMETHODIMP get_PlaybackSpeed(double* pSpeed) {return E_NOTIMPL;}
  286. // IKeyFrameInfo
  287. STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
  288. STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
  289. // IBufferInfo
  290. STDMETHODIMP_(int) GetCount();
  291. STDMETHODIMP GetStatus(int i, int& samples, int& size);
  292. STDMETHODIMP_(DWORD) GetPriority();
  293. };