00001
00002
00003
00004
00005 #ifndef __FILTER__
00006 #define __FILTER__
00007
00008 class CBaseMediaFilter;
00009 class CBaseFilter;
00010 class CBasePin;
00011 class CEnumPins;
00012 class CEnumMediaTypes;
00013 class CBaseOutputPin;
00014 class CBaseInputPin;
00015 class CMediaSample;
00016 class CBaseAllocator;
00017 class CMemAllocator;
00018
00019 #define QueryFilterInfoReleaseGraph(fi) if ((fi).pGraph) (fi).pGraph->Release();
00020
00021 #define QueryPinInfoReleaseFilter(pi) if ((pi).pFilter) (pi).pFilter->Release();
00022
00023 class AM_NOVTABLE CBaseMediaFilter : public CUnknown,
00024 public IMediaFilter
00025 {
00026
00027 protected:
00028
00029 FILTER_STATE m_State;
00030 IReferenceClock *m_pClock;
00031
00032
00033
00034 CRefTime m_tStart;
00035
00036 CLSID m_clsid;
00037
00038 CCritSec *m_pLock;
00039
00040 public:
00041
00042 CBaseMediaFilter(
00043 const TCHAR *pName,
00044 LPUNKNOWN pUnk,
00045 CCritSec *pLock,
00046 REFCLSID clsid);
00047
00048 virtual ~CBaseMediaFilter();
00049
00050 DECLARE_IUNKNOWN
00051
00052
00053 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
00054
00055
00056
00057
00058
00059 STDMETHODIMP GetClassID(CLSID *pClsID);
00060
00061
00062
00063 STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State);
00064
00065 STDMETHODIMP SetSyncSource(IReferenceClock *pClock);
00066
00067 STDMETHODIMP GetSyncSource(IReferenceClock **pClock);
00068
00069
00070
00071
00072
00073
00074 STDMETHODIMP Stop();
00075 STDMETHODIMP Pause();
00076
00077
00078
00079
00080 STDMETHODIMP Run(REFERENCE_TIME tStart);
00081
00082
00083
00084
00085
00086 virtual HRESULT StreamTime(CRefTime& rtStream);
00087
00088
00089 BOOL IsActive() {
00090 CAutoLock cObjectLock(m_pLock);
00091 return ((m_State == State_Paused) || (m_State == State_Running));
00092 };
00093 };
00094
00095 class AM_NOVTABLE CBaseFilter : public CUnknown,
00096 public IBaseFilter,
00097 public IAMovieSetup
00098 {
00099
00100 friend class CBasePin;
00101
00102 protected:
00103 FILTER_STATE m_State;
00104 IReferenceClock *m_pClock;
00105 CRefTime m_tStart;
00106 CLSID m_clsid;
00107
00108 CCritSec *m_pLock;
00109
00110 WCHAR *m_pName;
00111 IFilterGraph *m_pGraph;
00112 IMediaEventSink *m_pSink;
00113 LONG m_PinVersion;
00114
00115 public:
00116
00117 CBaseFilter(
00118 const TCHAR *pName,
00119 LPUNKNOWN pUnk,
00120 CCritSec *pLock,
00121 REFCLSID clsid);
00122
00123 CBaseFilter(
00124 TCHAR *pName,
00125 LPUNKNOWN pUnk,
00126 CCritSec *pLock,
00127 REFCLSID clsid,
00128 HRESULT *phr);
00129 #ifdef UNICODE
00130 CBaseFilter(
00131 const CHAR *pName,
00132 LPUNKNOWN pUnk,
00133 CCritSec *pLock,
00134 REFCLSID clsid);
00135
00136 CBaseFilter(
00137 CHAR *pName,
00138 LPUNKNOWN pUnk,
00139 CCritSec *pLock,
00140 REFCLSID clsid,
00141 HRESULT *phr);
00142 #endif
00143 ~CBaseFilter();
00144
00145 DECLARE_IUNKNOWN
00146
00147
00148 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
00149 #ifdef DEBUG
00150 STDMETHODIMP_(ULONG) NonDelegatingRelease();
00151 #endif
00152
00153
00154
00155
00156
00157 STDMETHODIMP GetClassID(CLSID *pClsID);
00158
00159
00160
00161 STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State);
00162
00163 STDMETHODIMP SetSyncSource(IReferenceClock *pClock);
00164
00165 STDMETHODIMP GetSyncSource(IReferenceClock **pClock);
00166
00167
00168
00169
00170
00171 STDMETHODIMP Stop();
00172 STDMETHODIMP Pause();
00173
00174
00175
00176
00177 STDMETHODIMP Run(REFERENCE_TIME tStart);
00178
00179
00180
00181
00182
00183 virtual HRESULT StreamTime(CRefTime& rtStream);
00184
00185
00186 BOOL IsActive() {
00187 CAutoLock cObjectLock(m_pLock);
00188 return ((m_State == State_Paused) || (m_State == State_Running));
00189 };
00190
00191
00192 BOOL IsStopped() {
00193 return (m_State == State_Stopped);
00194 };
00195
00196
00197
00198
00199
00200
00201 STDMETHODIMP EnumPins(
00202 IEnumPins ** ppEnum);
00203
00204
00205 STDMETHODIMP FindPin(
00206 LPCWSTR Id,
00207 IPin ** ppPin
00208 );
00209
00210 STDMETHODIMP QueryFilterInfo(
00211 FILTER_INFO * pInfo);
00212
00213 STDMETHODIMP JoinFilterGraph(
00214 IFilterGraph * pGraph,
00215 LPCWSTR pName);
00216
00217
00218
00219
00220 STDMETHODIMP QueryVendorInfo(
00221 LPWSTR* pVendorInfo
00222 );
00223
00224
00225
00226
00227
00228
00229 HRESULT NotifyEvent(
00230 long EventCode,
00231 LONG_PTR EventParam1,
00232 LONG_PTR EventParam2);
00233
00234
00235 IFilterGraph *GetFilterGraph() {
00236 return m_pGraph;
00237 }
00238
00239
00240
00241
00242
00243 HRESULT ReconnectPin(IPin *pPin, AM_MEDIA_TYPE const *pmt);
00244
00245
00246 virtual LONG GetPinVersion();
00247 void IncrementPinVersion();
00248
00249
00250
00251 virtual int GetPinCount() PURE;
00252 virtual CBasePin *GetPin(int n) PURE;
00253
00254
00255
00256 STDMETHODIMP Register();
00257 STDMETHODIMP Unregister();
00258
00259
00260
00261
00262 virtual LPAMOVIESETUP_FILTER GetSetupData(){ return NULL; }
00263
00264 };
00265
00266 class AM_NOVTABLE CBasePin : public CUnknown, public IPin, public IQualityControl
00267 {
00268
00269 protected:
00270
00271 WCHAR * m_pName;
00272 IPin *m_Connected;
00273 PIN_DIRECTION m_dir;
00274 CCritSec *m_pLock;
00275 bool m_bRunTimeError;
00276 bool m_bCanReconnectWhenActive;
00277 bool m_bTryMyTypesFirst;
00278
00279 CBaseFilter *m_pFilter;
00280 IQualityControl *m_pQSink;
00281 LONG m_TypeVersion;
00282 CMediaType m_mt;
00283
00284 CRefTime m_tStart;
00285 CRefTime m_tStop;
00286 double m_dRate;
00287
00288 #ifdef DEBUG
00289 LONG m_cRef;
00290 #endif
00291
00292
00293
00294 #ifdef DEBUG
00295 void DisplayPinInfo(IPin *pReceivePin);
00296 void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt);
00297 #else
00298 void DisplayPinInfo(IPin *pReceivePin) {};
00299 void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) {};
00300 #endif
00301
00302
00303
00304
00305
00306 HRESULT
00307 AttemptConnection(
00308 IPin* pReceivePin,
00309 const CMediaType* pmt
00310 );
00311
00312
00313
00314 HRESULT TryMediaTypes(
00315 IPin *pReceivePin,
00316 const CMediaType *pmt,
00317 IEnumMediaTypes *pEnum);
00318
00319
00320
00321
00322
00323 HRESULT AgreeMediaType(
00324 IPin *pReceivePin,
00325 const CMediaType *pmt);
00326
00327 public:
00328
00329 CBasePin(
00330 TCHAR *pObjectName,
00331 CBaseFilter *pFilter,
00332 CCritSec *pLock,
00333 HRESULT *phr,
00334 LPCWSTR pName,
00335 PIN_DIRECTION dir);
00336 #ifdef UNICODE
00337 CBasePin(
00338 CHAR *pObjectName,
00339 CBaseFilter *pFilter,
00340 CCritSec *pLock,
00341 HRESULT *phr,
00342 LPCWSTR pName,
00343 PIN_DIRECTION dir);
00344 #endif
00345 virtual ~CBasePin();
00346
00347 DECLARE_IUNKNOWN
00348
00349 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
00350 STDMETHODIMP_(ULONG) NonDelegatingRelease();
00351 STDMETHODIMP_(ULONG) NonDelegatingAddRef();
00352
00353
00354
00355
00356
00357
00358 STDMETHODIMP Connect(
00359 IPin * pReceivePin,
00360 const AM_MEDIA_TYPE *pmt
00361 );
00362
00363
00364 STDMETHODIMP ReceiveConnection(
00365 IPin * pConnector,
00366 const AM_MEDIA_TYPE *pmt
00367 );
00368
00369 STDMETHODIMP Disconnect();
00370
00371 STDMETHODIMP ConnectedTo(IPin **pPin);
00372
00373 STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt);
00374
00375 STDMETHODIMP QueryPinInfo(
00376 PIN_INFO * pInfo
00377 );
00378
00379 STDMETHODIMP QueryDirection(
00380 PIN_DIRECTION * pPinDir
00381 );
00382
00383 STDMETHODIMP QueryId(
00384 LPWSTR * Id
00385 );
00386
00387
00388 STDMETHODIMP QueryAccept(
00389 const AM_MEDIA_TYPE *pmt
00390 );
00391
00392
00393 STDMETHODIMP EnumMediaTypes(
00394 IEnumMediaTypes **ppEnum
00395 );
00396
00397
00398
00399
00400
00401
00402
00403
00404 STDMETHODIMP QueryInternalConnections(
00405 IPin* *apPin,
00406 ULONG *nPin
00407
00408 ) { return E_NOTIMPL; }
00409
00410
00411 STDMETHODIMP EndOfStream(void);
00412
00413
00414
00415
00416
00417
00418
00419 STDMETHODIMP NewSegment(
00420 REFERENCE_TIME tStart,
00421 REFERENCE_TIME tStop,
00422 double dRate);
00423
00424
00425
00426
00427
00428 STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
00429
00430 STDMETHODIMP SetSink(IQualityControl * piqc);
00431
00432
00433
00434
00435 BOOL IsConnected(void) {return (m_Connected != NULL); };
00436
00437 IPin * GetConnected() { return m_Connected; };
00438
00439
00440 BOOL IsStopped() {
00441 return (m_pFilter->m_State == State_Stopped);
00442 };
00443
00444
00445 virtual LONG GetMediaTypeVersion();
00446 void IncrementTypeVersion();
00447
00448
00449
00450 virtual HRESULT Active(void);
00451
00452
00453 virtual HRESULT Inactive(void);
00454
00455
00456 virtual HRESULT Run(REFERENCE_TIME tStart);
00457
00458
00459 virtual HRESULT CheckMediaType(const CMediaType *) PURE;
00460
00461
00462 virtual HRESULT SetMediaType(const CMediaType *);
00463
00464
00465
00466 virtual HRESULT CheckConnect(IPin *);
00467
00468
00469 virtual HRESULT BreakConnect();
00470 virtual HRESULT CompleteConnect(IPin *pReceivePin);
00471
00472
00473 virtual HRESULT GetMediaType(int iPosition,CMediaType *pMediaType);
00474
00475
00476 REFERENCE_TIME CurrentStopTime() {
00477 return m_tStop;
00478 }
00479 REFERENCE_TIME CurrentStartTime() {
00480 return m_tStart;
00481 }
00482 double CurrentRate() {
00483 return m_dRate;
00484 }
00485
00486
00487 LPWSTR Name() { return m_pName; };
00488
00489
00490 void SetReconnectWhenActive(bool bCanReconnect)
00491 {
00492 m_bCanReconnectWhenActive = bCanReconnect;
00493 }
00494
00495 bool CanReconnectWhenActive()
00496 {
00497 return m_bCanReconnectWhenActive;
00498 }
00499
00500 protected:
00501 STDMETHODIMP DisconnectInternal();
00502 };
00503
00504 class CEnumPins : public IEnumPins
00505 {
00506 int m_Position;
00507 int m_PinCount;
00508 CBaseFilter *m_pFilter;
00509 LONG m_Version;
00510 LONG m_cRef;
00511
00512 typedef CGenericList<CBasePin> CPinList;
00513
00514 CPinList m_PinCache;
00515
00516
00517
00518 #ifdef DEBUG
00519 DWORD m_dwCookie;
00520 #endif
00521
00522
00523
00524 BOOL AreWeOutOfSync() {
00525 return (m_pFilter->GetPinVersion() == m_Version ? FALSE : TRUE);
00526 };
00527
00528
00529
00530 STDMETHODIMP Refresh();
00531
00532 public:
00533
00534 CEnumPins(
00535 CBaseFilter *pFilter,
00536 CEnumPins *pEnumPins);
00537
00538 virtual ~CEnumPins();
00539
00540
00541 STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
00542 STDMETHODIMP_(ULONG) AddRef();
00543 STDMETHODIMP_(ULONG) Release();
00544
00545
00546 STDMETHODIMP Next(
00547 ULONG cPins,
00548 IPin ** ppPins,
00549 ULONG * pcFetched
00550 );
00551
00552 STDMETHODIMP Skip(ULONG cPins);
00553 STDMETHODIMP Reset();
00554 STDMETHODIMP Clone(IEnumPins **ppEnum);
00555
00556 };
00557
00558 class CEnumMediaTypes : public IEnumMediaTypes
00559 {
00560 int m_Position;
00561 CBasePin *m_pPin;
00562 LONG m_Version;
00563 LONG m_cRef;
00564 #ifdef DEBUG
00565 DWORD m_dwCookie;
00566 #endif
00567
00568
00569
00570 BOOL AreWeOutOfSync() {
00571 return (m_pPin->GetMediaTypeVersion() == m_Version ? FALSE : TRUE);
00572 };
00573
00574 public:
00575
00576 CEnumMediaTypes(
00577 CBasePin *pPin,
00578 CEnumMediaTypes *pEnumMediaTypes);
00579
00580 virtual ~CEnumMediaTypes();
00581
00582
00583 STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
00584 STDMETHODIMP_(ULONG) AddRef();
00585 STDMETHODIMP_(ULONG) Release();
00586
00587
00588 STDMETHODIMP Next(
00589 ULONG cMediaTypes,
00590 AM_MEDIA_TYPE ** ppMediaTypes,
00591 ULONG * pcFetched
00592 );
00593
00594 STDMETHODIMP Skip(ULONG cMediaTypes);
00595 STDMETHODIMP Reset();
00596 STDMETHODIMP Clone(IEnumMediaTypes **ppEnum);
00597 };
00598
00599 class AM_NOVTABLE CBaseOutputPin : public CBasePin
00600 {
00601
00602 protected:
00603
00604 IMemAllocator *m_pAllocator;
00605 IMemInputPin *m_pInputPin;
00606
00607
00608 public:
00609
00610 CBaseOutputPin(
00611 TCHAR *pObjectName,
00612 CBaseFilter *pFilter,
00613 CCritSec *pLock,
00614 HRESULT *phr,
00615 LPCWSTR pName);
00616 #ifdef UNICODE
00617 CBaseOutputPin(
00618 CHAR *pObjectName,
00619 CBaseFilter *pFilter,
00620 CCritSec *pLock,
00621 HRESULT *phr,
00622 LPCWSTR pName);
00623 #endif
00624
00625 virtual HRESULT CompleteConnect(IPin *pReceivePin);
00626
00627
00628
00629 virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc);
00630
00631
00632
00633
00634
00635
00636 virtual HRESULT DecideBufferSize(
00637 IMemAllocator * pAlloc,
00638 ALLOCATOR_PROPERTIES * ppropInputRequest
00639 ) PURE;
00640
00641
00642 virtual HRESULT GetDeliveryBuffer(IMediaSample ** ppSample,
00643 REFERENCE_TIME * pStartTime,
00644 REFERENCE_TIME * pEndTime,
00645 DWORD dwFlags);
00646
00647
00648
00649
00650
00651 virtual HRESULT Deliver(IMediaSample *);
00652
00653
00654 virtual HRESULT InitAllocator(IMemAllocator **ppAlloc);
00655 HRESULT CheckConnect(IPin *pPin);
00656 HRESULT BreakConnect();
00657
00658
00659 HRESULT Active(void);
00660 HRESULT Inactive(void);
00661
00662
00663
00664 STDMETHODIMP EndOfStream(void);
00665
00666
00667
00668 virtual HRESULT DeliverEndOfStream(void);
00669
00670
00671
00672
00673 STDMETHODIMP BeginFlush(void);
00674 STDMETHODIMP EndFlush(void);
00675 virtual HRESULT DeliverBeginFlush(void);
00676 virtual HRESULT DeliverEndFlush(void);
00677
00678
00679
00680 virtual HRESULT DeliverNewSegment(
00681 REFERENCE_TIME tStart,
00682 REFERENCE_TIME tStop,
00683 double dRate);
00684
00685
00686
00687
00688
00689
00690
00691
00692 };
00693
00694 class AM_NOVTABLE CBaseInputPin : public CBasePin,
00695 public IMemInputPin
00696 {
00697
00698 protected:
00699
00700 IMemAllocator *m_pAllocator;
00701
00702
00703
00704
00705 BYTE m_bReadOnly;
00706
00707
00708
00709 BYTE m_bFlushing;
00710
00711
00712 AM_SAMPLE2_PROPERTIES m_SampleProps;
00713
00714 public:
00715
00716 CBaseInputPin(
00717 TCHAR *pObjectName,
00718 CBaseFilter *pFilter,
00719 CCritSec *pLock,
00720 HRESULT *phr,
00721 LPCWSTR pName);
00722 #ifdef UNICODE
00723 CBaseInputPin(
00724 CHAR *pObjectName,
00725 CBaseFilter *pFilter,
00726 CCritSec *pLock,
00727 HRESULT *phr,
00728 LPCWSTR pName);
00729 #endif
00730 virtual ~CBaseInputPin();
00731
00732 DECLARE_IUNKNOWN
00733
00734
00735 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
00736
00737
00738
00739 STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator);
00740
00741
00742
00743 STDMETHODIMP NotifyAllocator(
00744 IMemAllocator * pAllocator,
00745 BOOL bReadOnly);
00746
00747
00748 STDMETHODIMP Receive(IMediaSample *pSample);
00749
00750
00751 STDMETHODIMP ReceiveMultiple (
00752 IMediaSample **pSamples,
00753 long nSamples,
00754 long *nSamplesProcessed);
00755
00756
00757 STDMETHODIMP ReceiveCanBlock();
00758
00759
00760
00761
00762
00763 STDMETHODIMP BeginFlush(void);
00764
00765
00766
00767
00768
00769
00770 STDMETHODIMP EndFlush(void);
00771
00772
00773
00774
00775
00776 STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps);
00777
00778
00779 HRESULT BreakConnect();
00780
00781
00782 BOOL IsReadOnly() {
00783 return m_bReadOnly;
00784 };
00785
00786
00787 BOOL IsFlushing() {
00788 return m_bFlushing;
00789 };
00790
00791
00792
00793 virtual HRESULT CheckStreaming();
00794
00795
00796 HRESULT PassNotify(Quality& q);
00797
00798
00799
00800
00801
00802 STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
00803
00804
00805
00806
00807
00808 virtual HRESULT Inactive(void);
00809
00810
00811 AM_SAMPLE2_PROPERTIES * SampleProps() {
00812 ASSERT(m_SampleProps.cbData != 0);
00813 return &m_SampleProps;
00814 }
00815
00816 };
00817
00818 class CDynamicOutputPin : public CBaseOutputPin,
00819 public IPinFlowControl
00820 {
00821 public:
00822 #ifdef UNICODE
00823 CDynamicOutputPin(
00824 CHAR *pObjectName,
00825 CBaseFilter *pFilter,
00826 CCritSec *pLock,
00827 HRESULT *phr,
00828 LPCWSTR pName);
00829 #endif
00830
00831 CDynamicOutputPin(
00832 TCHAR *pObjectName,
00833 CBaseFilter *pFilter,
00834 CCritSec *pLock,
00835 HRESULT *phr,
00836 LPCWSTR pName);
00837
00838 ~CDynamicOutputPin();
00839
00840
00841 DECLARE_IUNKNOWN
00842 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
00843
00844
00845 STDMETHODIMP Disconnect(void);
00846
00847
00848 STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent);
00849
00850
00851 void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent);
00852
00853 #ifdef DEBUG
00854 virtual HRESULT Deliver(IMediaSample *pSample);
00855 virtual HRESULT DeliverEndOfStream(void);
00856 virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
00857 #endif
00858
00859 HRESULT DeliverBeginFlush(void);
00860 HRESULT DeliverEndFlush(void);
00861
00862 HRESULT Inactive(void);
00863 HRESULT Active(void);
00864 virtual HRESULT CompleteConnect(IPin *pReceivePin);
00865
00866 virtual HRESULT StartUsingOutputPin(void);
00867 virtual void StopUsingOutputPin(void);
00868 virtual bool StreamingThreadUsingOutputPin(void);
00869
00870 HRESULT ChangeOutputFormat
00871 (
00872 const AM_MEDIA_TYPE *pmt,
00873 REFERENCE_TIME tSegmentStart,
00874 REFERENCE_TIME tSegmentStop,
00875 double dSegmentRate
00876 );
00877 HRESULT ChangeMediaType(const CMediaType *pmt);
00878 HRESULT DynamicReconnect(const CMediaType *pmt);
00879
00880 protected:
00881 HRESULT SynchronousBlockOutputPin(void);
00882 HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent);
00883 HRESULT UnblockOutputPin(void);
00884
00885 void BlockOutputPin(void);
00886 void ResetBlockState(void);
00887
00888 static HRESULT WaitEvent(HANDLE hEvent);
00889
00890 enum BLOCK_STATE
00891 {
00892 NOT_BLOCKED,
00893 PENDING,
00894 BLOCKED
00895 };
00896
00897
00898
00899
00900 CCritSec m_BlockStateLock;
00901
00902
00903
00904
00905
00906 HANDLE m_hUnblockOutputPinEvent;
00907
00908
00909
00910
00911
00912 HANDLE m_hNotifyCallerPinBlockedEvent;
00913
00914
00915 BLOCK_STATE m_BlockState;
00916
00917
00918
00919
00920 DWORD m_dwBlockCallerThreadID;
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 DWORD m_dwNumOutstandingOutputPinUsers;
00931
00932
00933
00934
00935 HANDLE m_hStopEvent;
00936 IGraphConfig* m_pGraphConfig;
00937
00938
00939
00940
00941 BOOL m_bPinUsesReadOnlyAllocator;
00942
00943 private:
00944 HRESULT Initialize(void);
00945 HRESULT ChangeMediaTypeHelper(const CMediaType *pmt);
00946
00947 #ifdef DEBUG
00948 void AssertValid(void);
00949 #endif
00950 };
00951
00952 class CAutoUsingOutputPin
00953 {
00954 public:
00955 CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr );
00956 ~CAutoUsingOutputPin();
00957
00958 private:
00959 CDynamicOutputPin* m_pOutputPin;
00960 };
00961
00962 inline CAutoUsingOutputPin::CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ) :
00963 m_pOutputPin(NULL)
00964 {
00965
00966 ASSERT( NULL != pOutputPin );
00967 ASSERT( NULL != phr );
00968
00969
00970 ASSERT( S_OK == *phr );
00971
00972 HRESULT hr = pOutputPin->StartUsingOutputPin();
00973 if( FAILED( hr ) )
00974 {
00975 *phr = hr;
00976 return;
00977 }
00978
00979 m_pOutputPin = pOutputPin;
00980 }
00981
00982 inline CAutoUsingOutputPin::~CAutoUsingOutputPin()
00983 {
00984 if( NULL != m_pOutputPin )
00985 {
00986 m_pOutputPin->StopUsingOutputPin();
00987 }
00988 }
00989
00990 #ifdef DEBUG
00991
00992 inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample)
00993 {
00994
00995
00996 ASSERT(StreamingThreadUsingOutputPin());
00997
00998 return CBaseOutputPin::Deliver(pSample);
00999 }
01000
01001 inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void)
01002 {
01003
01004
01005 ASSERT( StreamingThreadUsingOutputPin() );
01006
01007 return CBaseOutputPin::DeliverEndOfStream();
01008 }
01009
01010 inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
01011 {
01012
01013
01014 ASSERT(StreamingThreadUsingOutputPin());
01015
01016 return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate);
01017 }
01018
01019 #endif
01020
01021 class CMediaSample : public IMediaSample2
01022 {
01023
01024 protected:
01025
01026 friend class CBaseAllocator;
01027
01028
01029 enum { Sample_SyncPoint = 0x01,
01030 Sample_Preroll = 0x02,
01031 Sample_Discontinuity = 0x04,
01032 Sample_TypeChanged = 0x08,
01033 Sample_TimeValid = 0x10,
01034 Sample_MediaTimeValid = 0x20,
01035 Sample_TimeDiscontinuity = 0x40,
01036 Sample_StopValid = 0x100,
01037 Sample_ValidFlags = 0x1FF
01038 };
01039
01040
01041
01042 DWORD m_dwFlags;
01043
01044 DWORD m_dwTypeSpecificFlags;
01045 LPBYTE m_pBuffer;
01046 LONG m_lActual;
01047 LONG m_cbBuffer;
01048 CBaseAllocator *m_pAllocator;
01049 CMediaSample *m_pNext;
01050 REFERENCE_TIME m_Start;
01051 REFERENCE_TIME m_End;
01052 LONGLONG m_MediaStart;
01053 LONG m_MediaEnd;
01054 AM_MEDIA_TYPE *m_pMediaType;
01055 DWORD m_dwStreamId;
01056 public:
01057 LONG m_cRef;
01058
01059 public:
01060
01061 CMediaSample(
01062 TCHAR *pName,
01063 CBaseAllocator *pAllocator,
01064 HRESULT *phr,
01065 LPBYTE pBuffer = NULL,
01066 LONG length = 0);
01067 #ifdef UNICODE
01068 CMediaSample(
01069 CHAR *pName,
01070 CBaseAllocator *pAllocator,
01071 HRESULT *phr,
01072 LPBYTE pBuffer = NULL,
01073 LONG length = 0);
01074 #endif
01075
01076 virtual ~CMediaSample();
01077
01078
01079
01080 STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
01081 STDMETHODIMP_(ULONG) AddRef();
01082 STDMETHODIMP_(ULONG) Release();
01083
01084
01085
01086
01087
01088 HRESULT SetPointer(BYTE * ptr, LONG cBytes);
01089
01090
01091 STDMETHODIMP GetPointer(BYTE ** ppBuffer);
01092
01093 STDMETHODIMP_(LONG) GetSize(void);
01094
01095
01096 STDMETHODIMP GetTime(
01097 REFERENCE_TIME * pTimeStart,
01098 REFERENCE_TIME * pTimeEnd
01099 );
01100
01101
01102 STDMETHODIMP SetTime(
01103 REFERENCE_TIME * pTimeStart,
01104 REFERENCE_TIME * pTimeEnd
01105 );
01106 STDMETHODIMP IsSyncPoint(void);
01107 STDMETHODIMP SetSyncPoint(BOOL bIsSyncPoint);
01108 STDMETHODIMP IsPreroll(void);
01109 STDMETHODIMP SetPreroll(BOOL bIsPreroll);
01110
01111 STDMETHODIMP_(LONG) GetActualDataLength(void);
01112 STDMETHODIMP SetActualDataLength(LONG lActual);
01113
01114
01115
01116 STDMETHODIMP GetMediaType(AM_MEDIA_TYPE **ppMediaType);
01117 STDMETHODIMP SetMediaType(AM_MEDIA_TYPE *pMediaType);
01118
01119
01120
01121
01122 STDMETHODIMP IsDiscontinuity(void);
01123
01124
01125 STDMETHODIMP SetDiscontinuity(BOOL bDiscontinuity);
01126
01127
01128 STDMETHODIMP GetMediaTime(
01129 LONGLONG * pTimeStart,
01130 LONGLONG * pTimeEnd
01131 );
01132
01133
01134 STDMETHODIMP SetMediaTime(
01135 LONGLONG * pTimeStart,
01136 LONGLONG * pTimeEnd
01137 );
01138
01139
01140 STDMETHODIMP GetProperties(
01141 DWORD cbProperties,
01142 BYTE * pbProperties
01143 );
01144
01145 STDMETHODIMP SetProperties(
01146 DWORD cbProperties,
01147 const BYTE * pbProperties
01148 );
01149 };
01150
01151 class AM_NOVTABLE CBaseAllocator : public CUnknown,
01152 public IMemAllocatorCallbackTemp,
01153 public CCritSec
01154 {
01155 class CSampleList;
01156 friend class CSampleList;
01157
01158
01159 static CMediaSample * &NextSample(CMediaSample *pSample)
01160 {
01161 return pSample->m_pNext;
01162 };
01163
01164
01165 class CSampleList
01166 {
01167 public:
01168 CSampleList() : m_List(NULL), m_nOnList(0) {};
01169 #ifdef DEBUG
01170 ~CSampleList()
01171 {
01172 ASSERT(m_nOnList == 0);
01173 };
01174 #endif
01175 CMediaSample *Head() const { return m_List; };
01176 CMediaSample *Next(CMediaSample *pSample) const { return CBaseAllocator::NextSample(pSample); };
01177 int GetCount() const { return m_nOnList; };
01178 void Add(CMediaSample *pSample)
01179 {
01180 ASSERT(pSample != NULL);
01181 CBaseAllocator::NextSample(pSample) = m_List;
01182 m_List = pSample;
01183 m_nOnList++;
01184 };
01185 CMediaSample *RemoveHead()
01186 {
01187 CMediaSample *pSample = m_List;
01188 if (pSample != NULL) {
01189 m_List = CBaseAllocator::NextSample(m_List);
01190 m_nOnList--;
01191 }
01192 return pSample;
01193 };
01194 void Remove(CMediaSample *pSample);
01195
01196 public:
01197 CMediaSample *m_List;
01198 int m_nOnList;
01199 };
01200 protected:
01201
01202 CSampleList m_lFree;
01203
01204
01205
01206 HANDLE m_hSem;
01207 long m_lWaiting;
01208 long m_lCount;
01209 long m_lAllocated;
01210 long m_lSize;
01211 long m_lAlignment;
01212 long m_lPrefix;
01213 BOOL m_bChanged;
01214
01215
01216 BOOL m_bCommitted;
01217
01218
01219 BOOL m_bDecommitInProgress;
01220
01221
01222 IMemAllocatorNotifyCallbackTemp *m_pNotify;
01223
01224 BOOL m_fEnableReleaseCallback;
01225
01226
01227
01228 virtual void Free(void) PURE;
01229
01230
01231 virtual HRESULT Alloc(void);
01232
01233 public:
01234
01235 CBaseAllocator(
01236 TCHAR *, LPUNKNOWN, HRESULT *,
01237 BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);
01238 #ifdef UNICODE
01239 CBaseAllocator(
01240 CHAR *, LPUNKNOWN, HRESULT *,
01241 BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);
01242 #endif
01243 virtual ~CBaseAllocator();
01244
01245 DECLARE_IUNKNOWN
01246
01247
01248 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
01249
01250 STDMETHODIMP SetProperties(
01251 ALLOCATOR_PROPERTIES* pRequest,
01252 ALLOCATOR_PROPERTIES* pActual);
01253
01254
01255 STDMETHODIMP GetProperties(
01256 ALLOCATOR_PROPERTIES* pProps);
01257
01258
01259
01260 STDMETHODIMP Commit();
01261
01262
01263
01264 STDMETHODIMP Decommit();
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 STDMETHODIMP GetBuffer(IMediaSample **ppBuffer,
01276 REFERENCE_TIME * pStartTime,
01277 REFERENCE_TIME * pEndTime,
01278 DWORD dwFlags);
01279
01280
01281 STDMETHODIMP ReleaseBuffer(IMediaSample *pBuffer);
01282
01283
01284 STDMETHODIMP SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify);
01285
01286 STDMETHODIMP GetFreeCount(LONG *plBuffersFree);
01287
01288
01289 void NotifySample();
01290
01291
01292 void SetWaiting() { m_lWaiting++; };
01293 };
01294
01295 STDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator);
01296
01297 class CMemAllocator : public CBaseAllocator
01298 {
01299
01300 protected:
01301
01302 LPBYTE m_pBuffer;
01303
01304
01305
01306 void Free(void);
01307
01308
01309
01310 void ReallyFree(void);
01311
01312
01313 HRESULT Alloc(void);
01314
01315 public:
01316
01317 static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *);
01318
01319 STDMETHODIMP SetProperties(
01320 ALLOCATOR_PROPERTIES* pRequest,
01321 ALLOCATOR_PROPERTIES* pActual);
01322
01323 CMemAllocator(TCHAR *, LPUNKNOWN, HRESULT *);
01324 #ifdef UNICODE
01325 CMemAllocator(CHAR *, LPUNKNOWN, HRESULT *);
01326 #endif
01327 ~CMemAllocator();
01328 };
01329
01330 STDAPI
01331 AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata
01332 , IFilterMapper * pIFM
01333 , BOOL bRegister );
01334
01335 #endif
01336