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 

Generated on Tue Dec 13 14:47:11 2005 for guliverkli by  doxygen 1.4.5