- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# BaseSplitter.h

    00001 /*
    00002  *      Copyright (C) 2003-2005 Gabest
    00003  *      http://www.gabest.org
    00004  *
    00005  *  This Program is free software; you can redistribute it and/or modify
    00006  *  it under the terms of the GNU General Public License as published by
    00007  *  the Free Software Foundation; either version 2, or (at your option)
    00008  *  any later version.
    00009  *
    00010  *  This Program is distributed in the hope that it will be useful,
    00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    00013  *  GNU General Public License for more details.
    00014  *
    00015  *  You should have received a copy of the GNU General Public License
    00016  *  along with GNU Make; see the file COPYING.  If not, write to
    00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    00018  *  http://www.gnu.org/copyleft/gpl.html
    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         // please only use DeliverPacket from the derived class
    00115     HRESULT GetDeliveryBuffer(IMediaSample** ppSample, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags);
    00116     HRESULT Deliver(IMediaSample* pSample);
    00117
    00118         // bitrate stats
    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         // override this if you need some second level stream specific demuxing (optional)
    00134         // the default implementation will send the sample as is
    00135         virtual HRESULT DeliverPacket(CAutoPtr<Packet> p);
    00136
    00137         // IMediaSeeking
    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         // Queueing
    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         // returns true for everything which (the lack of) would not block other streams (subtitle streams, basically)
    00192         virtual bool IsDiscontinuous();
    00193
    00194         // returns IStreamsSwitcherInputPin::IsActive(), when it can find one downstream
    00195         bool IsActive();
    00196
    00197         // IBitRateInfo
    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; // override this ...
    00240
    00241         LONGLONG m_nOpenProgress;
    00242         bool m_fAbort;
    00243
    00244         REFERENCE_TIME m_rtDuration; // derived filter should set this at the end of CreateOutputs
    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         // ... and also override all these too
    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         // IFileSourceFilter
    00291
    00292         STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE* pmt);
    00293         STDMETHODIMP GetCurFile(LPOLESTR* ppszFileName, AM_MEDIA_TYPE* pmt);
    00294
    00295         // IMediaSeeking
    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         // IAMOpenProgress
    00325
    00326         STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
    00327         STDMETHODIMP AbortOperation();
    00328
    00329         // IDispatch
    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         // IAMMediaContent
    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         // IAMExtendedSeeking
    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         // IKeyFrameInfo
    00363
    00364         STDMETHODIMP_(HRESULT) GetKeyFrameCount(UINT& nKFs);
    00365         STDMETHODIMP_(HRESULT) GetKeyFrames(const GUID* pFormat, REFERENCE_TIME* pKFs, UINT& nKFs);
    00366
    00367         // IBufferInfo
    00368
    00369         STDMETHODIMP_(int) GetCount();
    00370         STDMETHODIMP GetStatus(int i, int& samples, int& size);
    00371         STDMETHODIMP_(DWORD) GetPriority();
    00372 };
    00373