00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #pragma once
00023
00024 #include <atlbase.h>
00025 #include <atlcoll.h>
00026 #include <afxtempl.h>
00027 #include <qnetwork.h>
00028 #include "..\..\..\..\include\IKeyFrameInfo.h"
00029 #include "..\..\..\..\include\IBufferInfo.h"
00030 #include "..\..\..\..\include\IBitRateInfo.h"
00031 #include "BaseSplitterFileEx.h"
00032 #include "AsyncReader.h"
00033 #include "..\..\..\DSUtil\DSMPropertyBag.h"
00034 #include "..\..\..\DSUtil\FontInstaller.h"
00035
00036 class Packet
00037 {
00038 public:
00039 DWORD TrackNumber;
00040 BOOL bDiscontinuity, bSyncPoint, bAppendable;
00041 static const REFERENCE_TIME INVALID_TIME = _I64_MIN;
00042 REFERENCE_TIME rtStart, rtStop;
00043 CArray<BYTE> pData;
00044 AM_MEDIA_TYPE* pmt;
00045 Packet() {pmt = NULL; bDiscontinuity = bAppendable = FALSE;}
00046 virtual ~Packet() {if(pmt) DeleteMediaType(pmt);}
00047 virtual int GetSize() {return pData.GetSize();}
00048 };
00049
00050 class CPacketQueue
00051 : public CCritSec
00052 , protected CAutoPtrList<Packet>
00053 {
00054 int m_size;
00055 public:
00056 CPacketQueue();
00057 void Add(CAutoPtr<Packet> p);
00058 CAutoPtr<Packet> Remove();
00059 void RemoveAll();
00060 int GetCount(), GetSize();
00061 };
00062
00063 class CBaseSplitterFilter;
00064
00065 class CBaseSplitterInputPin
00066 : public CBasePin
00067 {
00068 protected:
00069 CComQIPtr<IAsyncReader> m_pAsyncReader;
00070
00071 public:
00072 CBaseSplitterInputPin(TCHAR* pName, CBaseSplitterFilter* pFilter, CCritSec* pLock, HRESULT* phr);
00073 virtual ~CBaseSplitterInputPin();
00074
00075 HRESULT GetAsyncReader(IAsyncReader** ppAsyncReader);
00076
00077 DECLARE_IUNKNOWN;
00078 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
00079
00080 HRESULT CheckMediaType(const CMediaType* pmt);
00081
00082 HRESULT CheckConnect(IPin* pPin);
00083 HRESULT BreakConnect();
00084 HRESULT CompleteConnect(IPin* pPin);
00085
00086 STDMETHODIMP BeginFlush();
00087 STDMETHODIMP EndFlush();
00088 };
00089
00090 class CBaseSplitterOutputPin
00091 : public CBaseOutputPin
00092 , public IDSMPropertyBagImpl
00093 , protected CAMThread
00094 , public IMediaSeeking
00095 , public IBitRateInfo
00096 {
00097 protected:
00098 CArray<CMediaType> m_mts;
00099 int m_nBuffers;
00100
00101 private:
00102 CPacketQueue m_queue;
00103
00104 HRESULT m_hrDeliver;
00105
00106 bool m_fFlushing, m_fFlushed;
00107 CAMEvent m_eEndFlush;
00108
00109 enum {CMD_EXIT};
00110 DWORD ThreadProc();
00111
00112 void MakeISCRHappy();
00113
00114
00115 HRESULT GetDeliveryBuffer(IMediaSample** ppSample, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags);
00116 HRESULT Deliver(IMediaSample* pSample);
00117
00118
00119
00120 struct
00121 {
00122 UINT64 nTotalBytesDelivered;
00123 REFERENCE_TIME rtTotalTimeDelivered;
00124 UINT64 nBytesSinceLastDeliverTime;
00125 REFERENCE_TIME rtLastDeliverTime;
00126 DWORD nCurrentBitRate;
00127 DWORD nAverageBitRate;
00128 } m_brs;
00129
00130 protected:
00131 REFERENCE_TIME m_rtStart;
00132
00133
00134
00135 virtual HRESULT DeliverPacket(CAutoPtr<Packet> p);
00136
00137
00138
00139 STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
00140 STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
00141 STDMETHODIMP IsFormatSupported(const GUID* pFormat);
00142 STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
00143 STDMETHODIMP GetTimeFormat(GUID* pFormat);
00144 STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
00145 STDMETHODIMP SetTimeFormat(const GUID* pFormat);
00146 STDMETHODIMP GetDuration(LONGLONG* pDuration);
00147 STDMETHODIMP GetStopPosition(LONGLONG* pStop);
00148 STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
00149 STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
00150 STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
00151 STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
00152 STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
00153 STDMETHODIMP SetRate(double dRate);
00154 STDMETHODIMP GetRate(double* pdRate);
00155 STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
00156
00157 public:
00158 CBaseSplitterOutputPin(CArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0);
00159 CBaseSplitterOutputPin(LPCWSTR pName, CBaseFilter* pFilter, CCritSec* pLock, HRESULT* phr, int nBuffers = 0);
00160 virtual ~CBaseSplitterOutputPin();
00161
00162 DECLARE_IUNKNOWN;
00163 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
00164
00165 HRESULT SetName(LPCWSTR pName);
00166
00167 HRESULT DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties);
00168 HRESULT CheckMediaType(const CMediaType* pmt);
00169 HRESULT GetMediaType(int iPosition, CMediaType* pmt);
00170 CMediaType& CurrentMediaType() {return m_mt;}
00171
00172 STDMETHODIMP Notify(IBaseFilter* pSender, Quality q);
00173
00174
00175
00176 HANDLE GetThreadHandle() {ASSERT(m_hThread != NULL); return m_hThread;}
00177 void SetThreadPriority(int nPriority) {if(m_hThread) ::SetThreadPriority(m_hThread, nPriority);}
00178
00179 HRESULT Active();
00180 HRESULT Inactive();
00181
00182 HRESULT DeliverBeginFlush();
00183 HRESULT DeliverEndFlush();
00184 HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
00185
00186 int QueueCount();
00187 int QueueSize();
00188 HRESULT QueueEndOfStream();
00189 HRESULT QueuePacket(CAutoPtr<Packet> p);
00190
00191
00192 virtual bool IsDiscontinuous();
00193
00194
00195 bool IsActive();
00196
00197
00198
00199 STDMETHODIMP_(DWORD) GetCurrentBitRate() {return m_brs.nCurrentBitRate;}
00200 STDMETHODIMP_(DWORD) GetAverageBitRate() {return m_brs.nAverageBitRate;}
00201 };
00202
00203 class CBaseSplitterFilter
00204 : public CBaseFilter
00205 , public CCritSec
00206 , public IDSMPropertyBagImpl
00207 , public IDSMResourceBagImpl
00208 , public IDSMChapterBagImpl
00209 , protected CAMThread
00210 , public IFileSourceFilter
00211 , public IMediaSeeking
00212 , public IAMOpenProgress
00213 , public IAMMediaContent
00214 , public IAMExtendedSeeking
00215 , public IKeyFrameInfo
00216 , public IBufferInfo
00217 {
00218 CCritSec m_csPinMap;
00219 CAtlMap<DWORD, CBaseSplitterOutputPin*> m_pPinMap;
00220
00221 CCritSec m_csmtnew;
00222 CAtlMap<DWORD, CMediaType> m_mtnew;
00223
00224 CAutoPtrList<CBaseSplitterOutputPin> m_pRetiredOutputs;
00225
00226 CComQIPtr<ISyncReader> m_pSyncReader;
00227
00228 protected:
00229 CStringW m_fn;
00230
00231 CAutoPtr<CBaseSplitterInputPin> m_pInput;
00232 CAutoPtrList<CBaseSplitterOutputPin> m_pOutputs;
00233
00234 CBaseSplitterOutputPin* GetOutputPin(DWORD TrackNum);
00235 DWORD GetOutputTrackNum(CBaseSplitterOutputPin* pPin);
00236 HRESULT AddOutputPin(DWORD TrackNum, CAutoPtr<CBaseSplitterOutputPin> pPin);
00237 HRESULT RenameOutputPin(DWORD TrackNumSrc, DWORD TrackNumDst, const AM_MEDIA_TYPE* pmt);
00238 virtual HRESULT DeleteOutputs();
00239 virtual HRESULT CreateOutputs(IAsyncReader* pAsyncReader) = 0;
00240
00241 LONGLONG m_nOpenProgress;
00242 bool m_fAbort;
00243
00244 REFERENCE_TIME m_rtDuration;
00245 REFERENCE_TIME m_rtStart, m_rtStop, m_rtCurrent, m_rtNewStart, m_rtNewStop;
00246 double m_dRate;
00247
00248 CList<UINT64> m_bDiscontinuitySent;
00249 CList<CBaseSplitterOutputPin*> m_pActivePins;
00250
00251 CAMEvent m_eEndFlush;
00252 bool m_fFlushing;
00253
00254 void DeliverBeginFlush();
00255 void DeliverEndFlush();
00256 HRESULT DeliverPacket(CAutoPtr<Packet> p);
00257
00258 DWORD m_priority;
00259
00260 CFontInstaller m_fontinst;
00261
00262 protected:
00263 enum {CMD_EXIT, CMD_SEEK};
00264 DWORD ThreadProc();
00265
00266
00267 virtual bool DemuxInit() = 0;
00268 virtual void DemuxSeek(REFERENCE_TIME rt) = 0;
00269 virtual bool DemuxLoop() = 0;
00270
00271 public:
00272 CBaseSplitterFilter(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT* phr, const CLSID& clsid);
00273 virtual ~CBaseSplitterFilter();
00274
00275 DECLARE_IUNKNOWN;
00276 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
00277
00278 bool IsAnyPinDrying();
00279
00280 HRESULT BreakConnect(PIN_DIRECTION dir, CBasePin* pPin);
00281 HRESULT CompleteConnect(PIN_DIRECTION dir, CBasePin* pPin);
00282
00283 int GetPinCount();
00284 CBasePin* GetPin(int n);
00285
00286 STDMETHODIMP Stop();
00287 STDMETHODIMP Pause();
00288 STDMETHODIMP Run(REFERENCE_TIME tStart);
00289
00290
00291
00292 STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
00293 STDMETHODIMP GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt);
00294
00295
00296
00297 STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
00298 STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
00299 STDMETHODIMP IsFormatSupported(const GUID* pFormat);
00300 STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
00301 STDMETHODIMP GetTimeFormat(GUID* pFormat);
00302 STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
00303 STDMETHODIMP SetTimeFormat(const GUID* pFormat);
00304 STDMETHODIMP GetDuration(LONGLONG* pDuration);
00305 STDMETHODIMP GetStopPosition(LONGLONG* pStop);
00306 STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
00307 STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
00308 STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
00309 STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
00310 STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
00311 STDMETHODIMP SetRate(double dRate);
00312 STDMETHODIMP GetRate(double* pdRate);
00313 STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);
00314
00315 protected:
00316 friend class CBaseSplitterOutputPin;
00317 virtual HRESULT SetPositionsInternal(void* id, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
00318
00319 private:
00320 REFERENCE_TIME m_rtLastStart, m_rtLastStop;
00321 CList<void*> m_LastSeekers;
00322
00323 public:
00324
00325
00326 STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
00327 STDMETHODIMP AbortOperation();
00328
00329
00330
00331 STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) {return E_NOTIMPL;}
00332 STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {return E_NOTIMPL;}
00333 STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) {return E_NOTIMPL;}
00334 STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) {return E_NOTIMPL;}
00335
00336
00337
00338 STDMETHODIMP get_AuthorName(BSTR* pbstrAuthorName);
00339 STDMETHODIMP get_Title(BSTR* pbstrTitle);
00340 STDMETHODIMP get_Rating(BSTR* pbstrRating);
00341 STDMETHODIMP get_Description(BSTR* pbstrDescription);
00342 STDMETHODIMP get_Copyright(BSTR* pbstrCopyright);
00343 STDMETHODIMP get_BaseURL(BSTR* pbstrBaseURL) {return E_NOTIMPL;}
00344 STDMETHODIMP get_LogoURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
00345 STDMETHODIMP get_LogoIconURL(BSTR* pbstrLogoURL) {return E_NOTIMPL;}
00346 STDMETHODIMP get_WatermarkURL(BSTR* pbstrWatermarkURL) {return E_NOTIMPL;}
00347 STDMETHODIMP get_MoreInfoURL(BSTR* pbstrMoreInfoURL) {return E_NOTIMPL;}
00348 STDMETHODIMP get_MoreInfoBannerImage(BSTR* pbstrMoreInfoBannerImage) {return E_NOTIMPL;}
00349 STDMETHODIMP get_MoreInfoBannerURL(BSTR* pbstrMoreInfoBannerURL) {return E_NOTIMPL;}
00350 STDMETHODIMP get_MoreInfoText(BSTR* pbstrMoreInfoText) {return E_NOTIMPL;}
00351
00352
00353
00354 STDMETHODIMP get_ExSeekCapabilities(long* pExCapabilities);
00355 STDMETHODIMP get_MarkerCount(long* pMarkerCount);
00356 STDMETHODIMP get_CurrentMarker(long* pCurrentMarker);
00357 STDMETHODIMP GetMarkerTime(long MarkerNum, double* pMarkerTime);
00358 STDMETHODIMP GetMarkerName(long MarkerNum, BSTR* pbstrMarkerName);
00359 STDMETHODIMP put_PlaybackSpeed(double Speed) {return E_NOTIMPL;}
00360 STDMETHODIMP get_PlaybackSpeed(double* pSpeed) {return E_NOTIMPL;}
00361
00362
00363
00364 STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
00365 STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
00366
00367
00368
00369 STDMETHODIMP_(int) GetCount();
00370 STDMETHODIMP GetStatus(int i, int& samples, int& size);
00371 STDMETHODIMP_(DWORD) GetPriority();
00372 };
00373