~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/third_party/BaseClasses/amfilter.h

  • Committer: Package Import Robot
  • Author(s): Francois Marier, Francois Marier, Mark Purcell
  • Date: 2014-10-18 15:08:50 UTC
  • mfrom: (1.1.12)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20141018150850-2exfk34ckb15pcwi
Tags: 1.4.1-0.1
[ Francois Marier ]
* Non-maintainer upload
* New upstream release (closes: #759576, #741130)
  - debian/rules +PJPROJECT_VERSION := 2.2.1
  - add upstream patch to fix broken TLS support
  - add patch to fix pjproject regression

[ Mark Purcell ]
* Build-Depends:
  - sflphone-daemon + libavformat-dev, libavcodec-dev, libswscale-dev,
  libavdevice-dev, libavutil-dev
  - sflphone-gnome + libclutter-gtk-1.0-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//------------------------------------------------------------------------------
2
 
// File: AMFilter.h
3
 
//
4
 
// Desc: DirectShow base classes - efines class hierarchy for streams
5
 
//       architecture.
6
 
//
7
 
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
8
 
//------------------------------------------------------------------------------
9
 
 
10
 
 
11
 
#ifndef __FILTER__
12
 
#define __FILTER__
13
 
 
14
 
/* The following classes are declared in this header: */
15
 
 
16
 
class CBaseMediaFilter;     // IMediaFilter support
17
 
class CBaseFilter;          // IBaseFilter,IMediaFilter support
18
 
class CBasePin;             // Abstract base class for IPin interface
19
 
class CEnumPins;            // Enumerate input and output pins
20
 
class CEnumMediaTypes;      // Enumerate the pin's preferred formats
21
 
class CBaseOutputPin;       // Adds data provider member functions
22
 
class CBaseInputPin;        // Implements IMemInputPin interface
23
 
class CMediaSample;         // Basic transport unit for IMemInputPin
24
 
class CBaseAllocator;       // General list guff for most allocators
25
 
class CMemAllocator;        // Implements memory buffer allocation
26
 
 
27
 
 
28
 
//=====================================================================
29
 
//=====================================================================
30
 
//
31
 
// QueryFilterInfo and QueryPinInfo AddRef the interface pointers
32
 
// they return.  You can use the macro below to release the interface.
33
 
//
34
 
//=====================================================================
35
 
//=====================================================================
36
 
 
37
 
#define QueryFilterInfoReleaseGraph(fi) if ((fi).pGraph) (fi).pGraph->Release();
38
 
 
39
 
#define QueryPinInfoReleaseFilter(pi) if ((pi).pFilter) (pi).pFilter->Release();
40
 
 
41
 
//=====================================================================
42
 
//=====================================================================
43
 
// Defines CBaseMediaFilter
44
 
//
45
 
// Abstract base class implementing IMediaFilter.
46
 
//
47
 
// Typically you will derive your filter from CBaseFilter rather than
48
 
// this,  unless you are implementing an object such as a plug-in
49
 
// distributor that needs to support IMediaFilter but not IBaseFilter.
50
 
//
51
 
// Note that IMediaFilter is derived from IPersist to allow query of
52
 
// class id.
53
 
//=====================================================================
54
 
//=====================================================================
55
 
 
56
 
class AM_NOVTABLE CBaseMediaFilter : public CUnknown,
57
 
                                     public IMediaFilter
58
 
{
59
 
 
60
 
protected:
61
 
 
62
 
    FILTER_STATE    m_State;            // current state: running, paused
63
 
    IReferenceClock *m_pClock;          // this filter's reference clock
64
 
    // note: all filters in a filter graph use the same clock
65
 
 
66
 
    // offset from stream time to reference time
67
 
    CRefTime        m_tStart;
68
 
 
69
 
    CLSID           m_clsid;            // This filters clsid
70
 
                                        // used for serialization
71
 
    CCritSec        *m_pLock;           // Object we use for locking
72
 
 
73
 
public:
74
 
 
75
 
    CBaseMediaFilter(
76
 
        __in_opt LPCTSTR pName,
77
 
        __inout_opt LPUNKNOWN pUnk,
78
 
        __in CCritSec  *pLock,
79
 
        REFCLSID   clsid);
80
 
 
81
 
    virtual ~CBaseMediaFilter();
82
 
 
83
 
    DECLARE_IUNKNOWN
84
 
 
85
 
    // override this to say what interfaces we support where
86
 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
87
 
 
88
 
    //
89
 
    // --- IPersist method ---
90
 
    //
91
 
 
92
 
    STDMETHODIMP GetClassID(__out CLSID *pClsID);
93
 
 
94
 
    // --- IMediaFilter methods ---
95
 
 
96
 
    STDMETHODIMP GetState(DWORD dwMSecs, __out FILTER_STATE *State);
97
 
 
98
 
    STDMETHODIMP SetSyncSource(__inout_opt IReferenceClock *pClock);
99
 
 
100
 
    STDMETHODIMP GetSyncSource(__deref_out_opt IReferenceClock **pClock);
101
 
 
102
 
    // default implementation of Stop and Pause just record the
103
 
    // state. Override to activate or de-activate your filter.
104
 
    // Note that Run when called from Stopped state will call Pause
105
 
    // to ensure activation, so if you are a source or transform
106
 
    // you will probably not need to override Run.
107
 
    STDMETHODIMP Stop();
108
 
    STDMETHODIMP Pause();
109
 
 
110
 
 
111
 
    // the start parameter is the difference to be added to the
112
 
    // sample's stream time to get the reference time for
113
 
    // its presentation
114
 
    STDMETHODIMP Run(REFERENCE_TIME tStart);
115
 
 
116
 
    // --- helper methods ---
117
 
 
118
 
    // return the current stream time - ie find out what
119
 
    // stream time should be appearing now
120
 
    virtual HRESULT StreamTime(CRefTime& rtStream);
121
 
 
122
 
    // Is the filter currently active? (running or paused)
123
 
    BOOL IsActive() {
124
 
        CAutoLock cObjectLock(m_pLock);
125
 
        return ((m_State == State_Paused) || (m_State == State_Running));
126
 
    };
127
 
};
128
 
 
129
 
//=====================================================================
130
 
//=====================================================================
131
 
// Defines CBaseFilter
132
 
//
133
 
// An abstract class providing basic IBaseFilter support for pin
134
 
// enumeration and filter information reading.
135
 
//
136
 
// We cannot derive from CBaseMediaFilter since methods in IMediaFilter
137
 
// are also in IBaseFilter and would be ambiguous. Since much of the code
138
 
// assumes that they derive from a class that has m_State and other state
139
 
// directly available, we duplicate code from CBaseMediaFilter rather than
140
 
// having a member variable.
141
 
//
142
 
// Derive your filter from this, or from a derived object such as
143
 
// CTransformFilter.
144
 
//=====================================================================
145
 
//=====================================================================
146
 
 
147
 
 
148
 
class AM_NOVTABLE CBaseFilter : public CUnknown,        // Handles an IUnknown
149
 
                    public IBaseFilter,     // The Filter Interface
150
 
                    public IAMovieSetup     // For un/registration
151
 
{
152
 
 
153
 
friend class CBasePin;
154
 
 
155
 
protected:
156
 
    FILTER_STATE    m_State;            // current state: running, paused
157
 
    IReferenceClock *m_pClock;          // this graph's ref clock
158
 
    CRefTime        m_tStart;           // offset from stream time to reference time
159
 
    CLSID           m_clsid;            // This filters clsid
160
 
                                        // used for serialization
161
 
    CCritSec        *m_pLock;           // Object we use for locking
162
 
 
163
 
    WCHAR           *m_pName;           // Full filter name
164
 
    IFilterGraph    *m_pGraph;          // Graph we belong to
165
 
    IMediaEventSink *m_pSink;           // Called with notify events
166
 
    LONG            m_PinVersion;       // Current pin version
167
 
 
168
 
public:
169
 
 
170
 
    CBaseFilter(
171
 
        __in_opt LPCTSTR pName,   // Object description
172
 
        __inout_opt LPUNKNOWN pUnk,  // IUnknown of delegating object
173
 
        __in CCritSec  *pLock,    // Object who maintains lock
174
 
        REFCLSID   clsid);        // The clsid to be used to serialize this filter
175
 
 
176
 
    CBaseFilter(
177
 
        __in_opt LPCTSTR pName,    // Object description
178
 
        __in_opt LPUNKNOWN pUnk,  // IUnknown of delegating object
179
 
        __in CCritSec  *pLock,    // Object who maintains lock
180
 
        REFCLSID   clsid,         // The clsid to be used to serialize this filter
181
 
        __inout HRESULT   *phr);  // General OLE return code
182
 
#ifdef UNICODE
183
 
    CBaseFilter(
184
 
        __in_opt LPCSTR pName,    // Object description
185
 
        __in_opt LPUNKNOWN pUnk,  // IUnknown of delegating object
186
 
        __in CCritSec  *pLock,    // Object who maintains lock
187
 
        REFCLSID   clsid);        // The clsid to be used to serialize this filter
188
 
 
189
 
    CBaseFilter(
190
 
        __in_opt LPCSTR pName,     // Object description
191
 
        __in_opt LPUNKNOWN pUnk,  // IUnknown of delegating object
192
 
        __in CCritSec  *pLock,    // Object who maintains lock
193
 
        REFCLSID   clsid,         // The clsid to be used to serialize this filter
194
 
        __inout HRESULT   *phr);  // General OLE return code
195
 
#endif
196
 
    ~CBaseFilter();
197
 
 
198
 
    DECLARE_IUNKNOWN
199
 
 
200
 
    // override this to say what interfaces we support where
201
 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
202
 
#ifdef DEBUG
203
 
    STDMETHODIMP_(ULONG) NonDelegatingRelease();
204
 
#endif
205
 
 
206
 
    //
207
 
    // --- IPersist method ---
208
 
    //
209
 
 
210
 
    STDMETHODIMP GetClassID(__out CLSID *pClsID);
211
 
 
212
 
    // --- IMediaFilter methods ---
213
 
 
214
 
    STDMETHODIMP GetState(DWORD dwMSecs, __out FILTER_STATE *State);
215
 
 
216
 
    STDMETHODIMP SetSyncSource(__in_opt IReferenceClock *pClock);
217
 
 
218
 
    STDMETHODIMP GetSyncSource(__deref_out_opt IReferenceClock **pClock);
219
 
 
220
 
 
221
 
    // override Stop and Pause so we can activate the pins.
222
 
    // Note that Run will call Pause first if activation needed.
223
 
    // Override these if you want to activate your filter rather than
224
 
    // your pins.
225
 
    STDMETHODIMP Stop();
226
 
    STDMETHODIMP Pause();
227
 
 
228
 
    // the start parameter is the difference to be added to the
229
 
    // sample's stream time to get the reference time for
230
 
    // its presentation
231
 
    STDMETHODIMP Run(REFERENCE_TIME tStart);
232
 
 
233
 
    // --- helper methods ---
234
 
 
235
 
    // return the current stream time - ie find out what
236
 
    // stream time should be appearing now
237
 
    virtual HRESULT StreamTime(CRefTime& rtStream);
238
 
 
239
 
    // Is the filter currently active?
240
 
    BOOL IsActive() {
241
 
        CAutoLock cObjectLock(m_pLock);
242
 
        return ((m_State == State_Paused) || (m_State == State_Running));
243
 
    };
244
 
 
245
 
    // Is this filter stopped (without locking)
246
 
    BOOL IsStopped() {
247
 
        return (m_State == State_Stopped);
248
 
    };
249
 
 
250
 
    //
251
 
    // --- IBaseFilter methods ---
252
 
    //
253
 
 
254
 
    // pin enumerator
255
 
    STDMETHODIMP EnumPins(
256
 
                    __deref_out IEnumPins ** ppEnum);
257
 
 
258
 
 
259
 
    // default behaviour of FindPin assumes pin ids are their names
260
 
    STDMETHODIMP FindPin(
261
 
        LPCWSTR Id,
262
 
        __deref_out IPin ** ppPin
263
 
    );
264
 
 
265
 
    STDMETHODIMP QueryFilterInfo(
266
 
                    __out FILTER_INFO * pInfo);
267
 
 
268
 
    STDMETHODIMP JoinFilterGraph(
269
 
                    __inout_opt IFilterGraph * pGraph,
270
 
                    __in_opt LPCWSTR pName);
271
 
 
272
 
    // return a Vendor information string. Optional - may return E_NOTIMPL.
273
 
    // memory returned should be freed using CoTaskMemFree
274
 
    // default implementation returns E_NOTIMPL
275
 
    STDMETHODIMP QueryVendorInfo(
276
 
                    __deref_out LPWSTR* pVendorInfo
277
 
            );
278
 
 
279
 
    // --- helper methods ---
280
 
 
281
 
    // send an event notification to the filter graph if we know about it.
282
 
    // returns S_OK if delivered, S_FALSE if the filter graph does not sink
283
 
    // events, or an error otherwise.
284
 
    HRESULT NotifyEvent(
285
 
        long EventCode,
286
 
        LONG_PTR EventParam1,
287
 
        LONG_PTR EventParam2);
288
 
 
289
 
    // return the filter graph we belong to
290
 
    __out_opt IFilterGraph *GetFilterGraph() {
291
 
        return m_pGraph;
292
 
    }
293
 
 
294
 
    // Request reconnect
295
 
    // pPin is the pin to reconnect
296
 
    // pmt is the type to reconnect with - can be NULL
297
 
    // Calls ReconnectEx on the filter graph
298
 
    HRESULT ReconnectPin(IPin *pPin, __in_opt AM_MEDIA_TYPE const *pmt);
299
 
 
300
 
    // find out the current pin version (used by enumerators)
301
 
    virtual LONG GetPinVersion();
302
 
    void IncrementPinVersion();
303
 
 
304
 
    // you need to supply these to access the pins from the enumerator
305
 
    // and for default Stop and Pause/Run activation.
306
 
    virtual int GetPinCount() PURE;
307
 
    virtual CBasePin *GetPin(int n) PURE;
308
 
 
309
 
    // --- IAMovieSetup methods ---
310
 
 
311
 
    STDMETHODIMP Register();    // ask filter to register itself
312
 
    STDMETHODIMP Unregister();  // and unregister itself
313
 
 
314
 
    // --- setup helper methods ---
315
 
    // (override to return filters setup data)
316
 
 
317
 
    virtual __out_opt LPAMOVIESETUP_FILTER GetSetupData(){ return NULL; }
318
 
 
319
 
};
320
 
 
321
 
 
322
 
//=====================================================================
323
 
//=====================================================================
324
 
// Defines CBasePin
325
 
//
326
 
// Abstract class that supports the basics of IPin
327
 
//=====================================================================
328
 
//=====================================================================
329
 
 
330
 
class  AM_NOVTABLE CBasePin : public CUnknown, public IPin, public IQualityControl
331
 
{
332
 
 
333
 
protected:
334
 
 
335
 
    WCHAR *         m_pName;                    // This pin's name
336
 
    IPin            *m_Connected;               // Pin we have connected to
337
 
    PIN_DIRECTION   m_dir;                      // Direction of this pin
338
 
    CCritSec        *m_pLock;                   // Object we use for locking
339
 
    bool            m_bRunTimeError;            // Run time error generated
340
 
    bool            m_bCanReconnectWhenActive;  // OK to reconnect when active
341
 
    bool            m_bTryMyTypesFirst;         // When connecting enumerate
342
 
                                                // this pin's types first
343
 
    CBaseFilter    *m_pFilter;                  // Filter we were created by
344
 
    IQualityControl *m_pQSink;                  // Target for Quality messages
345
 
    LONG            m_TypeVersion;              // Holds current type version
346
 
    CMediaType      m_mt;                       // Media type of connection
347
 
 
348
 
    CRefTime        m_tStart;                   // time from NewSegment call
349
 
    CRefTime        m_tStop;                    // time from NewSegment
350
 
    double          m_dRate;                    // rate from NewSegment
351
 
 
352
 
#ifdef DEBUG
353
 
    LONG            m_cRef;                     // Ref count tracing
354
 
#endif
355
 
 
356
 
    // displays pin connection information
357
 
 
358
 
#ifdef DEBUG
359
 
    void DisplayPinInfo(IPin *pReceivePin);
360
 
    void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt);
361
 
#else
362
 
    void DisplayPinInfo(IPin *pReceivePin) {};
363
 
    void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) {};
364
 
#endif
365
 
 
366
 
    // used to agree a media type for a pin connection
367
 
 
368
 
    // given a specific media type, attempt a connection (includes
369
 
    // checking that the type is acceptable to this pin)
370
 
    HRESULT
371
 
    AttemptConnection(
372
 
        IPin* pReceivePin,      // connect to this pin
373
 
        const CMediaType* pmt   // using this type
374
 
    );
375
 
 
376
 
    // try all the media types in this enumerator - for each that
377
 
    // we accept, try to connect using ReceiveConnection.
378
 
    HRESULT TryMediaTypes(
379
 
                        IPin *pReceivePin,          // connect to this pin
380
 
                        __in_opt const CMediaType *pmt,  // proposed type from Connect
381
 
                        IEnumMediaTypes *pEnum);    // try this enumerator
382
 
 
383
 
    // establish a connection with a suitable mediatype. Needs to
384
 
    // propose a media type if the pmt pointer is null or partially
385
 
    // specified - use TryMediaTypes on both our and then the other pin's
386
 
    // enumerator until we find one that works.
387
 
    HRESULT AgreeMediaType(
388
 
                        IPin *pReceivePin,      // connect to this pin
389
 
                        const CMediaType *pmt);      // proposed type from Connect
390
 
 
391
 
public:
392
 
 
393
 
    CBasePin(
394
 
        __in_opt LPCTSTR pObjectName,         // Object description
395
 
        __in CBaseFilter *pFilter,       // Owning filter who knows about pins
396
 
        __in CCritSec *pLock,            // Object who implements the lock
397
 
        __inout HRESULT *phr,               // General OLE return code
398
 
        __in_opt LPCWSTR pName,              // Pin name for us
399
 
        PIN_DIRECTION dir);         // Either PINDIR_INPUT or PINDIR_OUTPUT
400
 
#ifdef UNICODE
401
 
    CBasePin(
402
 
        __in_opt LPCSTR pObjectName,         // Object description
403
 
        __in CBaseFilter *pFilter,       // Owning filter who knows about pins
404
 
        __in CCritSec *pLock,            // Object who implements the lock
405
 
        __inout HRESULT *phr,               // General OLE return code
406
 
        __in_opt LPCWSTR pName,              // Pin name for us
407
 
        PIN_DIRECTION dir);         // Either PINDIR_INPUT or PINDIR_OUTPUT
408
 
#endif
409
 
    virtual ~CBasePin();
410
 
 
411
 
    DECLARE_IUNKNOWN
412
 
 
413
 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
414
 
    STDMETHODIMP_(ULONG) NonDelegatingRelease();
415
 
    STDMETHODIMP_(ULONG) NonDelegatingAddRef();
416
 
 
417
 
    // --- IPin methods ---
418
 
 
419
 
    // take lead role in establishing a connection. Media type pointer
420
 
    // may be null, or may point to partially-specified mediatype
421
 
    // (subtype or format type may be GUID_NULL).
422
 
    STDMETHODIMP Connect(
423
 
        IPin * pReceivePin,
424
 
        __in_opt const AM_MEDIA_TYPE *pmt   // optional media type
425
 
    );
426
 
 
427
 
    // (passive) accept a connection from another pin
428
 
    STDMETHODIMP ReceiveConnection(
429
 
        IPin * pConnector,      // this is the initiating connecting pin
430
 
        const AM_MEDIA_TYPE *pmt   // this is the media type we will exchange
431
 
    );
432
 
 
433
 
    STDMETHODIMP Disconnect();
434
 
 
435
 
    STDMETHODIMP ConnectedTo(__deref_out IPin **pPin);
436
 
 
437
 
    STDMETHODIMP ConnectionMediaType(__out AM_MEDIA_TYPE *pmt);
438
 
 
439
 
    STDMETHODIMP QueryPinInfo(
440
 
        __out PIN_INFO * pInfo
441
 
    );
442
 
 
443
 
    STDMETHODIMP QueryDirection(
444
 
        __out PIN_DIRECTION * pPinDir
445
 
    );
446
 
 
447
 
    STDMETHODIMP QueryId(
448
 
        __deref_out LPWSTR * Id
449
 
    );
450
 
 
451
 
    // does the pin support this media type
452
 
    STDMETHODIMP QueryAccept(
453
 
        const AM_MEDIA_TYPE *pmt
454
 
    );
455
 
 
456
 
    // return an enumerator for this pins preferred media types
457
 
    STDMETHODIMP EnumMediaTypes(
458
 
        __deref_out IEnumMediaTypes **ppEnum
459
 
    );
460
 
 
461
 
    // return an array of IPin* - the pins that this pin internally connects to
462
 
    // All pins put in the array must be AddReffed (but no others)
463
 
    // Errors: "Can't say" - FAIL, not enough slots - return S_FALSE
464
 
    // Default: return E_NOTIMPL
465
 
    // The filter graph will interpret NOT_IMPL as any input pin connects to
466
 
    // all visible output pins and vice versa.
467
 
    // apPin can be NULL if nPin==0 (not otherwise).
468
 
    STDMETHODIMP QueryInternalConnections(
469
 
        __out_ecount_part(*nPin,*nPin) IPin* *apPin,     // array of IPin*
470
 
        __inout ULONG *nPin                  // on input, the number of slots
471
 
                                             // on output  the number of pins
472
 
    ) { return E_NOTIMPL; }
473
 
 
474
 
    // Called when no more data will be sent
475
 
    STDMETHODIMP EndOfStream(void);
476
 
 
477
 
    // Begin/EndFlush still PURE
478
 
 
479
 
    // NewSegment notifies of the start/stop/rate applying to the data
480
 
    // about to be received. Default implementation records data and
481
 
    // returns S_OK.
482
 
    // Override this to pass downstream.
483
 
    STDMETHODIMP NewSegment(
484
 
                    REFERENCE_TIME tStart,
485
 
                    REFERENCE_TIME tStop,
486
 
                    double dRate);
487
 
 
488
 
    //================================================================================
489
 
    // IQualityControl methods
490
 
    //================================================================================
491
 
 
492
 
    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
493
 
 
494
 
    STDMETHODIMP SetSink(IQualityControl * piqc);
495
 
 
496
 
    // --- helper methods ---
497
 
 
498
 
    // Returns true if the pin is connected. false otherwise.
499
 
    BOOL IsConnected(void) {return (m_Connected != NULL); };
500
 
    // Return the pin this is connected to (if any)
501
 
    IPin * GetConnected() { return m_Connected; };
502
 
 
503
 
    // Check if our filter is currently stopped
504
 
    BOOL IsStopped() {
505
 
        return (m_pFilter->m_State == State_Stopped);
506
 
    };
507
 
 
508
 
    // find out the current type version (used by enumerators)
509
 
    virtual LONG GetMediaTypeVersion();
510
 
    void IncrementTypeVersion();
511
 
 
512
 
    // switch the pin to active (paused or running) mode
513
 
    // not an error to call this if already active
514
 
    virtual HRESULT Active(void);
515
 
 
516
 
    // switch the pin to inactive state - may already be inactive
517
 
    virtual HRESULT Inactive(void);
518
 
 
519
 
    // Notify of Run() from filter
520
 
    virtual HRESULT Run(REFERENCE_TIME tStart);
521
 
 
522
 
    // check if the pin can support this specific proposed type and format
523
 
    virtual HRESULT CheckMediaType(const CMediaType *) PURE;
524
 
 
525
 
    // set the connection to use this format (previously agreed)
526
 
    virtual HRESULT SetMediaType(const CMediaType *);
527
 
 
528
 
    // check that the connection is ok before verifying it
529
 
    // can be overridden eg to check what interfaces will be supported.
530
 
    virtual HRESULT CheckConnect(IPin *);
531
 
 
532
 
    // Set and release resources required for a connection
533
 
    virtual HRESULT BreakConnect();
534
 
    virtual HRESULT CompleteConnect(IPin *pReceivePin);
535
 
 
536
 
    // returns the preferred formats for a pin
537
 
    virtual HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType);
538
 
 
539
 
    // access to NewSegment values
540
 
    REFERENCE_TIME CurrentStopTime() {
541
 
        return m_tStop;
542
 
    }
543
 
    REFERENCE_TIME CurrentStartTime() {
544
 
        return m_tStart;
545
 
    }
546
 
    double CurrentRate() {
547
 
        return m_dRate;
548
 
    }
549
 
 
550
 
    //  Access name
551
 
    LPWSTR Name() { return m_pName; };
552
 
 
553
 
    //  Can reconnectwhen active?
554
 
    void SetReconnectWhenActive(bool bCanReconnect)
555
 
    {
556
 
        m_bCanReconnectWhenActive = bCanReconnect;
557
 
    }
558
 
 
559
 
    bool CanReconnectWhenActive()
560
 
    {
561
 
        return m_bCanReconnectWhenActive;
562
 
    }
563
 
 
564
 
protected:
565
 
    STDMETHODIMP DisconnectInternal();
566
 
};
567
 
 
568
 
 
569
 
//=====================================================================
570
 
//=====================================================================
571
 
// Defines CEnumPins
572
 
//
573
 
// Pin enumerator class that works by calling CBaseFilter. This interface
574
 
// is provided by CBaseFilter::EnumPins and calls GetPinCount() and
575
 
// GetPin() to enumerate existing pins. Needs to be a separate object so
576
 
// that it can be cloned (creating an existing object at the same
577
 
// position in the enumeration)
578
 
//
579
 
//=====================================================================
580
 
//=====================================================================
581
 
 
582
 
class CEnumPins : public IEnumPins      // The interface we support
583
 
{
584
 
    int m_Position;                 // Current ordinal position
585
 
    int m_PinCount;                 // Number of pins available
586
 
    CBaseFilter *m_pFilter;         // The filter who owns us
587
 
    LONG m_Version;                 // Pin version information
588
 
    LONG m_cRef;
589
 
 
590
 
    typedef CGenericList<CBasePin> CPinList;
591
 
 
592
 
    CPinList m_PinCache;            // These pointers have not been AddRef'ed and
593
 
                                    // so they should not be dereferenced.  They are
594
 
                                    // merely kept to ID which pins have been enumerated.
595
 
 
596
 
#ifdef DEBUG
597
 
    DWORD m_dwCookie;
598
 
#endif
599
 
 
600
 
    /* If while we are retrieving a pin for example from the filter an error
601
 
       occurs we assume that our internal state is stale with respect to the
602
 
       filter (someone may have deleted all the pins). We can check before
603
 
       starting whether or not the operation is likely to fail by asking the
604
 
       filter what it's current version number is. If the filter has not
605
 
       overriden the GetPinVersion method then this will always match */
606
 
 
607
 
    BOOL AreWeOutOfSync() {
608
 
        return (m_pFilter->GetPinVersion() == m_Version ? FALSE : TRUE);
609
 
    };
610
 
 
611
 
    /* This method performs the same operations as Reset, except is does not clear
612
 
       the cache of pins already enumerated. */
613
 
 
614
 
    STDMETHODIMP Refresh();
615
 
 
616
 
public:
617
 
 
618
 
    CEnumPins(
619
 
        __in CBaseFilter *pFilter,
620
 
        __in_opt CEnumPins *pEnumPins);
621
 
 
622
 
    virtual ~CEnumPins();
623
 
 
624
 
    // IUnknown
625
 
    STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv);
626
 
    STDMETHODIMP_(ULONG) AddRef();
627
 
    STDMETHODIMP_(ULONG) Release();
628
 
 
629
 
    // IEnumPins
630
 
    STDMETHODIMP Next(
631
 
        ULONG cPins,         // place this many pins...
632
 
        __out_ecount(cPins) IPin ** ppPins,    // ...in this array of IPin*
633
 
        __out_opt ULONG * pcFetched    // actual count passed returned here
634
 
    );
635
 
 
636
 
    STDMETHODIMP Skip(ULONG cPins);
637
 
    STDMETHODIMP Reset();
638
 
    STDMETHODIMP Clone(__deref_out IEnumPins **ppEnum);
639
 
 
640
 
 
641
 
};
642
 
 
643
 
 
644
 
//=====================================================================
645
 
//=====================================================================
646
 
// Defines CEnumMediaTypes
647
 
//
648
 
// Enumerates the preferred formats for input and output pins
649
 
//=====================================================================
650
 
//=====================================================================
651
 
 
652
 
class CEnumMediaTypes : public IEnumMediaTypes    // The interface we support
653
 
{
654
 
    int m_Position;           // Current ordinal position
655
 
    CBasePin *m_pPin;         // The pin who owns us
656
 
    LONG m_Version;           // Media type version value
657
 
    LONG m_cRef;
658
 
#ifdef DEBUG
659
 
    DWORD m_dwCookie;
660
 
#endif
661
 
 
662
 
    /* The media types a filter supports can be quite dynamic so we add to
663
 
       the general IEnumXXXX interface the ability to be signaled when they
664
 
       change via an event handle the connected filter supplies. Until the
665
 
       Reset method is called after the state changes all further calls to
666
 
       the enumerator (except Reset) will return E_UNEXPECTED error code */
667
 
 
668
 
    BOOL AreWeOutOfSync() {
669
 
        return (m_pPin->GetMediaTypeVersion() == m_Version ? FALSE : TRUE);
670
 
    };
671
 
 
672
 
public:
673
 
 
674
 
    CEnumMediaTypes(
675
 
        __in CBasePin *pPin,
676
 
        __in_opt CEnumMediaTypes *pEnumMediaTypes);
677
 
 
678
 
    virtual ~CEnumMediaTypes();
679
 
 
680
 
    // IUnknown
681
 
    STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv);
682
 
    STDMETHODIMP_(ULONG) AddRef();
683
 
    STDMETHODIMP_(ULONG) Release();
684
 
 
685
 
    // IEnumMediaTypes
686
 
    STDMETHODIMP Next(
687
 
        ULONG cMediaTypes,          // place this many pins...
688
 
        __out_ecount(cMediaTypes) AM_MEDIA_TYPE ** ppMediaTypes,  // ...in this array
689
 
        __out_opt ULONG * pcFetched           // actual count passed
690
 
    );
691
 
 
692
 
    STDMETHODIMP Skip(ULONG cMediaTypes);
693
 
    STDMETHODIMP Reset();
694
 
    STDMETHODIMP Clone(__deref_out IEnumMediaTypes **ppEnum);
695
 
};
696
 
 
697
 
 
698
 
 
699
 
 
700
 
//=====================================================================
701
 
//=====================================================================
702
 
// Defines CBaseOutputPin
703
 
//
704
 
// class derived from CBasePin that can pass buffers to a connected pin
705
 
// that supports IMemInputPin. Supports IPin.
706
 
//
707
 
// Derive your output pin from this.
708
 
//
709
 
//=====================================================================
710
 
//=====================================================================
711
 
 
712
 
class  AM_NOVTABLE CBaseOutputPin : public CBasePin
713
 
{
714
 
 
715
 
protected:
716
 
 
717
 
    IMemAllocator *m_pAllocator;
718
 
    IMemInputPin *m_pInputPin;        // interface on the downstreaminput pin
719
 
                                      // set up in CheckConnect when we connect.
720
 
 
721
 
public:
722
 
 
723
 
    CBaseOutputPin(
724
 
        __in_opt LPCTSTR pObjectName,
725
 
        __in CBaseFilter *pFilter,
726
 
        __in CCritSec *pLock,
727
 
        __inout HRESULT *phr,
728
 
        __in_opt LPCWSTR pName);
729
 
#ifdef UNICODE
730
 
    CBaseOutputPin(
731
 
        __in_opt LPCSTR pObjectName,
732
 
        __in CBaseFilter *pFilter,
733
 
        __in CCritSec *pLock,
734
 
        __inout HRESULT *phr,
735
 
        __in_opt LPCWSTR pName);
736
 
#endif
737
 
    // override CompleteConnect() so we can negotiate an allocator
738
 
    virtual HRESULT CompleteConnect(IPin *pReceivePin);
739
 
 
740
 
    // negotiate the allocator and its buffer size/count and other properties
741
 
    // Calls DecideBufferSize to set properties
742
 
    virtual HRESULT DecideAllocator(IMemInputPin * pPin, __deref_out IMemAllocator ** pAlloc);
743
 
 
744
 
    // override this to set the buffer size and count. Return an error
745
 
    // if the size/count is not to your liking.
746
 
    // The allocator properties passed in are those requested by the
747
 
    // input pin - use eg the alignment and prefix members if you have
748
 
    // no preference on these.
749
 
    virtual HRESULT DecideBufferSize(
750
 
        IMemAllocator * pAlloc,
751
 
        __inout ALLOCATOR_PROPERTIES * ppropInputRequest
752
 
    ) PURE;
753
 
 
754
 
    // returns an empty sample buffer from the allocator
755
 
    virtual HRESULT GetDeliveryBuffer(__deref_out IMediaSample ** ppSample,
756
 
                                      __in_opt REFERENCE_TIME * pStartTime,
757
 
                                      __in_opt REFERENCE_TIME * pEndTime,
758
 
                                      DWORD dwFlags);
759
 
 
760
 
    // deliver a filled-in sample to the connected input pin
761
 
    // note - you need to release it after calling this. The receiving
762
 
    // pin will addref the sample if it needs to hold it beyond the
763
 
    // call.
764
 
    virtual HRESULT Deliver(IMediaSample *);
765
 
 
766
 
    // override this to control the connection
767
 
    virtual HRESULT InitAllocator(__deref_out IMemAllocator **ppAlloc);
768
 
    HRESULT CheckConnect(IPin *pPin);
769
 
    HRESULT BreakConnect();
770
 
 
771
 
    // override to call Commit and Decommit
772
 
    HRESULT Active(void);
773
 
    HRESULT Inactive(void);
774
 
 
775
 
    // we have a default handling of EndOfStream which is to return
776
 
    // an error, since this should be called on input pins only
777
 
    STDMETHODIMP EndOfStream(void);
778
 
 
779
 
    // called from elsewhere in our filter to pass EOS downstream to
780
 
    // our connected input pin
781
 
    virtual HRESULT DeliverEndOfStream(void);
782
 
 
783
 
    // same for Begin/EndFlush - we handle Begin/EndFlush since it
784
 
    // is an error on an output pin, and we have Deliver methods to
785
 
    // call the methods on the connected pin
786
 
    STDMETHODIMP BeginFlush(void);
787
 
    STDMETHODIMP EndFlush(void);
788
 
    virtual HRESULT DeliverBeginFlush(void);
789
 
    virtual HRESULT DeliverEndFlush(void);
790
 
 
791
 
    // deliver NewSegment to connected pin - you will need to
792
 
    // override this if you queue any data in your output pin.
793
 
    virtual HRESULT DeliverNewSegment(
794
 
                        REFERENCE_TIME tStart,
795
 
                        REFERENCE_TIME tStop,
796
 
                        double dRate);
797
 
 
798
 
    //================================================================================
799
 
    // IQualityControl methods
800
 
    //================================================================================
801
 
 
802
 
    // All inherited from CBasePin and not overridden here.
803
 
    // STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
804
 
    // STDMETHODIMP SetSink(IQualityControl * piqc);
805
 
};
806
 
 
807
 
 
808
 
//=====================================================================
809
 
//=====================================================================
810
 
// Defines CBaseInputPin
811
 
//
812
 
// derive your standard input pin from this.
813
 
// you need to supply GetMediaType and CheckConnect etc (see CBasePin),
814
 
// and you need to supply Receive to do something more useful.
815
 
//
816
 
//=====================================================================
817
 
//=====================================================================
818
 
 
819
 
class AM_NOVTABLE CBaseInputPin : public CBasePin,
820
 
                                  public IMemInputPin
821
 
{
822
 
 
823
 
protected:
824
 
 
825
 
    IMemAllocator *m_pAllocator;    // Default memory allocator
826
 
 
827
 
    // allocator is read-only, so received samples
828
 
    // cannot be modified (probably only relevant to in-place
829
 
    // transforms
830
 
    BYTE m_bReadOnly;
831
 
 
832
 
    // in flushing state (between BeginFlush and EndFlush)
833
 
    // if TRUE, all Receives are returned with S_FALSE
834
 
    BYTE m_bFlushing;
835
 
 
836
 
    // Sample properties - initalized in Receive
837
 
    AM_SAMPLE2_PROPERTIES m_SampleProps;
838
 
 
839
 
public:
840
 
 
841
 
    CBaseInputPin(
842
 
        __in_opt LPCTSTR pObjectName,
843
 
        __in CBaseFilter *pFilter,
844
 
        __in CCritSec *pLock,
845
 
        __inout HRESULT *phr,
846
 
        __in_opt LPCWSTR pName);
847
 
#ifdef UNICODE
848
 
    CBaseInputPin(
849
 
        __in_opt LPCSTR pObjectName,
850
 
        __in CBaseFilter *pFilter,
851
 
        __in CCritSec *pLock,
852
 
        __inout HRESULT *phr,
853
 
        __in_opt LPCWSTR pName);
854
 
#endif
855
 
    virtual ~CBaseInputPin();
856
 
 
857
 
    DECLARE_IUNKNOWN
858
 
 
859
 
    // override this to publicise our interfaces
860
 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
861
 
 
862
 
    // return the allocator interface that this input pin
863
 
    // would like the output pin to use
864
 
    STDMETHODIMP GetAllocator(__deref_out IMemAllocator ** ppAllocator);
865
 
 
866
 
    // tell the input pin which allocator the output pin is actually
867
 
    // going to use.
868
 
    STDMETHODIMP NotifyAllocator(
869
 
                    IMemAllocator * pAllocator,
870
 
                    BOOL bReadOnly);
871
 
 
872
 
    // do something with this media sample
873
 
    STDMETHODIMP Receive(IMediaSample *pSample);
874
 
 
875
 
    // do something with these media samples
876
 
    STDMETHODIMP ReceiveMultiple (
877
 
        __in_ecount(nSamples) IMediaSample **pSamples,
878
 
        long nSamples,
879
 
        __out long *nSamplesProcessed);
880
 
 
881
 
    // See if Receive() blocks
882
 
    STDMETHODIMP ReceiveCanBlock();
883
 
 
884
 
    // Default handling for BeginFlush - call at the beginning
885
 
    // of your implementation (makes sure that all Receive calls
886
 
    // fail). After calling this, you need to free any queued data
887
 
    // and then call downstream.
888
 
    STDMETHODIMP BeginFlush(void);
889
 
 
890
 
    // default handling for EndFlush - call at end of your implementation
891
 
    // - before calling this, ensure that there is no queued data and no thread
892
 
    // pushing any more without a further receive, then call downstream,
893
 
    // then call this method to clear the m_bFlushing flag and re-enable
894
 
    // receives
895
 
    STDMETHODIMP EndFlush(void);
896
 
 
897
 
    // this method is optional (can return E_NOTIMPL).
898
 
    // default implementation returns E_NOTIMPL. Override if you have
899
 
    // specific alignment or prefix needs, but could use an upstream
900
 
    // allocator
901
 
    STDMETHODIMP GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES*pProps);
902
 
 
903
 
    // Release the pin's allocator.
904
 
    HRESULT BreakConnect();
905
 
 
906
 
    // helper method to check the read-only flag
907
 
    BOOL IsReadOnly() {
908
 
        return m_bReadOnly;
909
 
    };
910
 
 
911
 
    // helper method to see if we are flushing
912
 
    BOOL IsFlushing() {
913
 
        return m_bFlushing;
914
 
    };
915
 
 
916
 
    //  Override this for checking whether it's OK to process samples
917
 
    //  Also call this from EndOfStream.
918
 
    virtual HRESULT CheckStreaming();
919
 
 
920
 
    // Pass a Quality notification on to the appropriate sink
921
 
    HRESULT PassNotify(Quality& q);
922
 
 
923
 
 
924
 
    //================================================================================
925
 
    // IQualityControl methods (from CBasePin)
926
 
    //================================================================================
927
 
 
928
 
    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
929
 
 
930
 
    // no need to override:
931
 
    // STDMETHODIMP SetSink(IQualityControl * piqc);
932
 
 
933
 
 
934
 
    // switch the pin to inactive state - may already be inactive
935
 
    virtual HRESULT Inactive(void);
936
 
 
937
 
    // Return sample properties pointer
938
 
    AM_SAMPLE2_PROPERTIES * SampleProps() {
939
 
        ASSERT(m_SampleProps.cbData != 0);
940
 
        return &m_SampleProps;
941
 
    }
942
 
 
943
 
};
944
 
 
945
 
///////////////////////////////////////////////////////////////////////////
946
 
// CDynamicOutputPin
947
 
//
948
 
 
949
 
class CDynamicOutputPin : public CBaseOutputPin,
950
 
                          public IPinFlowControl
951
 
{
952
 
public:
953
 
#ifdef UNICODE
954
 
    CDynamicOutputPin(
955
 
        __in_opt LPCSTR pObjectName,
956
 
        __in CBaseFilter *pFilter,
957
 
        __in CCritSec *pLock,
958
 
        __inout HRESULT *phr,
959
 
        __in_opt LPCWSTR pName);
960
 
#endif
961
 
 
962
 
    CDynamicOutputPin(
963
 
        __in_opt LPCTSTR pObjectName,
964
 
        __in CBaseFilter *pFilter,
965
 
        __in CCritSec *pLock,
966
 
        __inout HRESULT *phr,
967
 
        __in_opt LPCWSTR pName);
968
 
 
969
 
    ~CDynamicOutputPin();
970
 
 
971
 
    // IUnknown Methods
972
 
    DECLARE_IUNKNOWN
973
 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
974
 
 
975
 
    // IPin Methods
976
 
    STDMETHODIMP Disconnect(void);
977
 
 
978
 
    // IPinFlowControl Methods
979
 
    STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent);
980
 
 
981
 
    //  Set graph config info
982
 
    void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent);
983
 
 
984
 
    #ifdef DEBUG
985
 
    virtual HRESULT Deliver(IMediaSample *pSample);
986
 
    virtual HRESULT DeliverEndOfStream(void);
987
 
    virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
988
 
    #endif // DEBUG
989
 
 
990
 
    HRESULT DeliverBeginFlush(void);
991
 
    HRESULT DeliverEndFlush(void);
992
 
 
993
 
    HRESULT Inactive(void);
994
 
    HRESULT Active(void);
995
 
    virtual HRESULT CompleteConnect(IPin *pReceivePin);
996
 
 
997
 
    virtual HRESULT StartUsingOutputPin(void);
998
 
    virtual void StopUsingOutputPin(void);
999
 
    virtual bool StreamingThreadUsingOutputPin(void);
1000
 
 
1001
 
    HRESULT ChangeOutputFormat
1002
 
        (
1003
 
        const AM_MEDIA_TYPE *pmt,
1004
 
        REFERENCE_TIME tSegmentStart,
1005
 
        REFERENCE_TIME tSegmentStop,
1006
 
        double dSegmentRate
1007
 
        );
1008
 
    HRESULT ChangeMediaType(const CMediaType *pmt);
1009
 
    HRESULT DynamicReconnect(const CMediaType *pmt);
1010
 
 
1011
 
protected:
1012
 
    HRESULT SynchronousBlockOutputPin(void);
1013
 
    HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent);
1014
 
    HRESULT UnblockOutputPin(void);
1015
 
 
1016
 
    void BlockOutputPin(void);
1017
 
    void ResetBlockState(void);
1018
 
 
1019
 
    static HRESULT WaitEvent(HANDLE hEvent);
1020
 
 
1021
 
    enum BLOCK_STATE
1022
 
    {
1023
 
        NOT_BLOCKED,
1024
 
        PENDING,
1025
 
        BLOCKED
1026
 
    };
1027
 
 
1028
 
    // This lock should be held when the following class members are
1029
 
    // being used: m_hNotifyCallerPinBlockedEvent, m_BlockState,
1030
 
    // m_dwBlockCallerThreadID and m_dwNumOutstandingOutputPinUsers.
1031
 
    CCritSec m_BlockStateLock;
1032
 
 
1033
 
    // This event should be signaled when the output pin is
1034
 
    // not blocked.  This is a manual reset event.  For more
1035
 
    // information on events, see the documentation for
1036
 
    // CreateEvent() in the Windows SDK.
1037
 
    HANDLE m_hUnblockOutputPinEvent;
1038
 
 
1039
 
    // This event will be signaled when block operation succeedes or
1040
 
    // when the user cancels the block operation.  The block operation
1041
 
    // can be canceled by calling IPinFlowControl2::Block( 0, NULL )
1042
 
    // while the block operation is pending.
1043
 
    HANDLE m_hNotifyCallerPinBlockedEvent;
1044
 
 
1045
 
    // The state of the current block operation.
1046
 
    BLOCK_STATE m_BlockState;
1047
 
 
1048
 
    // The ID of the thread which last called IPinFlowControl::Block().
1049
 
    // For more information on thread IDs, see the documentation for
1050
 
    // GetCurrentThreadID() in the Windows SDK.
1051
 
    DWORD m_dwBlockCallerThreadID;
1052
 
 
1053
 
    // The number of times StartUsingOutputPin() has been sucessfully
1054
 
    // called and a corresponding call to StopUsingOutputPin() has not
1055
 
    // been made.  When this variable is greater than 0, the streaming
1056
 
    // thread is calling IPin::NewSegment(), IPin::EndOfStream(),
1057
 
    // IMemInputPin::Receive() or IMemInputPin::ReceiveMultiple().  The
1058
 
    // streaming thread could also be calling: DynamicReconnect(),
1059
 
    // ChangeMediaType() or ChangeOutputFormat().  The output pin cannot
1060
 
    // be blocked while the output pin is being used.
1061
 
    DWORD m_dwNumOutstandingOutputPinUsers;
1062
 
 
1063
 
    // This event should be set when the IMediaFilter::Stop() is called.
1064
 
    // This is a manual reset event.  It is also set when the output pin
1065
 
    // delivers a flush to the connected input pin.
1066
 
    HANDLE m_hStopEvent;
1067
 
    IGraphConfig* m_pGraphConfig;
1068
 
 
1069
 
    // TRUE if the output pin's allocator's samples are read only.
1070
 
    // Otherwise FALSE.  For more information, see the documentation
1071
 
    // for IMemInputPin::NotifyAllocator().
1072
 
    BOOL m_bPinUsesReadOnlyAllocator;
1073
 
 
1074
 
private:
1075
 
    HRESULT Initialize(void);
1076
 
    HRESULT ChangeMediaTypeHelper(const CMediaType *pmt);
1077
 
 
1078
 
    #ifdef DEBUG
1079
 
    void AssertValid(void);
1080
 
    #endif // DEBUG
1081
 
};
1082
 
 
1083
 
class CAutoUsingOutputPin
1084
 
{
1085
 
public:
1086
 
    CAutoUsingOutputPin( __in CDynamicOutputPin* pOutputPin, __inout HRESULT* phr );
1087
 
    ~CAutoUsingOutputPin();
1088
 
 
1089
 
private:
1090
 
    CDynamicOutputPin* m_pOutputPin;
1091
 
};
1092
 
 
1093
 
inline CAutoUsingOutputPin::CAutoUsingOutputPin( __in CDynamicOutputPin* pOutputPin, __inout HRESULT* phr ) :
1094
 
    m_pOutputPin(NULL)
1095
 
{
1096
 
    // The caller should always pass in valid pointers.
1097
 
    ASSERT( NULL != pOutputPin );
1098
 
    ASSERT( NULL != phr );
1099
 
 
1100
 
    // Make sure the user initialized phr.
1101
 
    ASSERT( S_OK == *phr );
1102
 
 
1103
 
    HRESULT hr = pOutputPin->StartUsingOutputPin();
1104
 
    if( FAILED( hr ) )
1105
 
    {
1106
 
        *phr = hr;
1107
 
        return;
1108
 
    }
1109
 
 
1110
 
    m_pOutputPin = pOutputPin;
1111
 
}
1112
 
 
1113
 
inline CAutoUsingOutputPin::~CAutoUsingOutputPin()
1114
 
{
1115
 
    if( NULL != m_pOutputPin )
1116
 
    {
1117
 
        m_pOutputPin->StopUsingOutputPin();
1118
 
    }
1119
 
}
1120
 
 
1121
 
#ifdef DEBUG
1122
 
 
1123
 
inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample)
1124
 
{
1125
 
    // The caller should call StartUsingOutputPin() before calling this
1126
 
    // method.
1127
 
    ASSERT(StreamingThreadUsingOutputPin());
1128
 
 
1129
 
    return CBaseOutputPin::Deliver(pSample);
1130
 
}
1131
 
 
1132
 
inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void)
1133
 
{
1134
 
    // The caller should call StartUsingOutputPin() before calling this
1135
 
    // method.
1136
 
    ASSERT( StreamingThreadUsingOutputPin() );
1137
 
 
1138
 
    return CBaseOutputPin::DeliverEndOfStream();
1139
 
}
1140
 
 
1141
 
inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
1142
 
{
1143
 
    // The caller should call StartUsingOutputPin() before calling this
1144
 
    // method.
1145
 
    ASSERT(StreamingThreadUsingOutputPin());
1146
 
 
1147
 
    return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate);
1148
 
}
1149
 
 
1150
 
#endif // DEBUG
1151
 
 
1152
 
//=====================================================================
1153
 
//=====================================================================
1154
 
// Memory allocators
1155
 
//
1156
 
// the shared memory transport between pins requires the input pin
1157
 
// to provide a memory allocator that can provide sample objects. A
1158
 
// sample object supports the IMediaSample interface.
1159
 
//
1160
 
// CBaseAllocator handles the management of free and busy samples. It
1161
 
// allocates CMediaSample objects. CBaseAllocator is an abstract class:
1162
 
// in particular it has no method of initializing the list of free
1163
 
// samples. CMemAllocator is derived from CBaseAllocator and initializes
1164
 
// the list of samples using memory from the standard IMalloc interface.
1165
 
//
1166
 
// If you want your buffers to live in some special area of memory,
1167
 
// derive your allocator object from CBaseAllocator. If you derive your
1168
 
// IMemInputPin interface object from CBaseMemInputPin, you will get
1169
 
// CMemAllocator-based allocation etc for free and will just need to
1170
 
// supply the Receive handling, and media type / format negotiation.
1171
 
//=====================================================================
1172
 
//=====================================================================
1173
 
 
1174
 
 
1175
 
//=====================================================================
1176
 
//=====================================================================
1177
 
// Defines CMediaSample
1178
 
//
1179
 
// an object of this class supports IMediaSample and represents a buffer
1180
 
// for media data with some associated properties. Releasing it returns
1181
 
// it to a freelist managed by a CBaseAllocator derived object.
1182
 
//=====================================================================
1183
 
//=====================================================================
1184
 
 
1185
 
class CMediaSample : public IMediaSample2    // The interface we support
1186
 
{
1187
 
 
1188
 
protected:
1189
 
 
1190
 
    friend class CBaseAllocator;
1191
 
 
1192
 
    /*  Values for dwFlags - these are used for backward compatiblity
1193
 
        only now - use AM_SAMPLE_xxx
1194
 
    */
1195
 
    enum { Sample_SyncPoint       = 0x01,   /* Is this a sync point */
1196
 
           Sample_Preroll         = 0x02,   /* Is this a preroll sample */
1197
 
           Sample_Discontinuity   = 0x04,   /* Set if start of new segment */
1198
 
           Sample_TypeChanged     = 0x08,   /* Has the type changed */
1199
 
           Sample_TimeValid       = 0x10,   /* Set if time is valid */
1200
 
           Sample_MediaTimeValid  = 0x20,   /* Is the media time valid */
1201
 
           Sample_TimeDiscontinuity = 0x40, /* Time discontinuity */
1202
 
           Sample_StopValid       = 0x100,  /* Stop time valid */
1203
 
           Sample_ValidFlags      = 0x1FF
1204
 
         };
1205
 
 
1206
 
    /* Properties, the media sample class can be a container for a format
1207
 
       change in which case we take a copy of a type through the SetMediaType
1208
 
       interface function and then return it when GetMediaType is called. As
1209
 
       we do no internal processing on it we leave it as a pointer */
1210
 
 
1211
 
    DWORD            m_dwFlags;         /* Flags for this sample */
1212
 
                                        /* Type specific flags are packed
1213
 
                                           into the top word
1214
 
                                        */
1215
 
    DWORD            m_dwTypeSpecificFlags; /* Media type specific flags */
1216
 
    __field_ecount_opt(m_cbBuffer) LPBYTE           m_pBuffer;         /* Pointer to the complete buffer */
1217
 
    LONG             m_lActual;         /* Length of data in this sample */
1218
 
    LONG             m_cbBuffer;        /* Size of the buffer */
1219
 
    CBaseAllocator  *m_pAllocator;      /* The allocator who owns us */
1220
 
    CMediaSample     *m_pNext;          /* Chaining in free list */
1221
 
    REFERENCE_TIME   m_Start;           /* Start sample time */
1222
 
    REFERENCE_TIME   m_End;             /* End sample time */
1223
 
    LONGLONG         m_MediaStart;      /* Real media start position */
1224
 
    LONG             m_MediaEnd;        /* A difference to get the end */
1225
 
    AM_MEDIA_TYPE    *m_pMediaType;     /* Media type change data */
1226
 
    DWORD            m_dwStreamId;      /* Stream id */
1227
 
public:
1228
 
    LONG             m_cRef;            /* Reference count */
1229
 
 
1230
 
 
1231
 
public:
1232
 
 
1233
 
    CMediaSample(
1234
 
        __in_opt LPCTSTR pName,
1235
 
        __in_opt CBaseAllocator *pAllocator,
1236
 
        __inout_opt HRESULT *phr,
1237
 
        __in_bcount_opt(length) LPBYTE pBuffer = NULL,
1238
 
        LONG length = 0);
1239
 
#ifdef UNICODE
1240
 
    CMediaSample(
1241
 
        __in_opt LPCSTR pName,
1242
 
        __in_opt CBaseAllocator *pAllocator,
1243
 
        __inout_opt HRESULT *phr,
1244
 
        __in_bcount_opt(length) LPBYTE pBuffer = NULL,
1245
 
        LONG length = 0);
1246
 
#endif
1247
 
 
1248
 
    virtual ~CMediaSample();
1249
 
 
1250
 
    /* Note the media sample does not delegate to its owner */
1251
 
 
1252
 
    STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv);
1253
 
    STDMETHODIMP_(ULONG) AddRef();
1254
 
    STDMETHODIMP_(ULONG) Release();
1255
 
 
1256
 
    // set the buffer pointer and length. Used by allocators that
1257
 
    // want variable sized pointers or pointers into already-read data.
1258
 
    // This is only available through a CMediaSample* not an IMediaSample*
1259
 
    // and so cannot be changed by clients.
1260
 
    HRESULT SetPointer(__in_bcount(cBytes) BYTE * ptr, LONG cBytes);
1261
 
 
1262
 
    // Get me a read/write pointer to this buffer's memory.
1263
 
    STDMETHODIMP GetPointer(__deref_out BYTE ** ppBuffer);
1264
 
 
1265
 
    STDMETHODIMP_(LONG) GetSize(void);
1266
 
 
1267
 
    // get the stream time at which this sample should start and finish.
1268
 
    STDMETHODIMP GetTime(
1269
 
        __out REFERENCE_TIME * pTimeStart,     // put time here
1270
 
        __out REFERENCE_TIME * pTimeEnd
1271
 
    );
1272
 
 
1273
 
    // Set the stream time at which this sample should start and finish.
1274
 
    STDMETHODIMP SetTime(
1275
 
        __in_opt REFERENCE_TIME * pTimeStart,     // put time here
1276
 
        __in_opt REFERENCE_TIME * pTimeEnd
1277
 
    );
1278
 
    STDMETHODIMP IsSyncPoint(void);
1279
 
    STDMETHODIMP SetSyncPoint(BOOL bIsSyncPoint);
1280
 
    STDMETHODIMP IsPreroll(void);
1281
 
    STDMETHODIMP SetPreroll(BOOL bIsPreroll);
1282
 
 
1283
 
    STDMETHODIMP_(LONG) GetActualDataLength(void);
1284
 
    STDMETHODIMP SetActualDataLength(LONG lActual);
1285
 
 
1286
 
    // these allow for limited format changes in band
1287
 
 
1288
 
    STDMETHODIMP GetMediaType(__deref_out AM_MEDIA_TYPE **ppMediaType);
1289
 
    STDMETHODIMP SetMediaType(__in_opt AM_MEDIA_TYPE *pMediaType);
1290
 
 
1291
 
    // returns S_OK if there is a discontinuity in the data (this same is
1292
 
    // not a continuation of the previous stream of data
1293
 
    // - there has been a seek).
1294
 
    STDMETHODIMP IsDiscontinuity(void);
1295
 
    // set the discontinuity property - TRUE if this sample is not a
1296
 
    // continuation, but a new sample after a seek.
1297
 
    STDMETHODIMP SetDiscontinuity(BOOL bDiscontinuity);
1298
 
 
1299
 
    // get the media times for this sample
1300
 
    STDMETHODIMP GetMediaTime(
1301
 
        __out LONGLONG * pTimeStart,
1302
 
            __out LONGLONG * pTimeEnd
1303
 
    );
1304
 
 
1305
 
    // Set the media times for this sample
1306
 
    STDMETHODIMP SetMediaTime(
1307
 
        __in_opt LONGLONG * pTimeStart,
1308
 
            __in_opt LONGLONG * pTimeEnd
1309
 
    );
1310
 
 
1311
 
    // Set and get properties (IMediaSample2)
1312
 
    STDMETHODIMP GetProperties(
1313
 
        DWORD cbProperties,
1314
 
        __out_bcount(cbProperties) BYTE * pbProperties
1315
 
    );
1316
 
 
1317
 
    STDMETHODIMP SetProperties(
1318
 
        DWORD cbProperties,
1319
 
        __in_bcount(cbProperties) const BYTE * pbProperties
1320
 
    );
1321
 
};
1322
 
 
1323
 
 
1324
 
//=====================================================================
1325
 
//=====================================================================
1326
 
// Defines CBaseAllocator
1327
 
//
1328
 
// Abstract base class that manages a list of media samples
1329
 
//
1330
 
// This class provides support for getting buffers from the free list,
1331
 
// including handling of commit and (asynchronous) decommit.
1332
 
//
1333
 
// Derive from this class and override the Alloc and Free functions to
1334
 
// allocate your CMediaSample (or derived) objects and add them to the
1335
 
// free list, preparing them as necessary.
1336
 
//=====================================================================
1337
 
//=====================================================================
1338
 
 
1339
 
class AM_NOVTABLE CBaseAllocator : public CUnknown,// A non delegating IUnknown
1340
 
                       public IMemAllocatorCallbackTemp, // The interface we support
1341
 
                       public CCritSec             // Provides object locking
1342
 
{
1343
 
    class CSampleList;
1344
 
    friend class CSampleList;
1345
 
 
1346
 
    /*  Trick to get at protected member in CMediaSample */
1347
 
    static CMediaSample * &NextSample(__in CMediaSample *pSample)
1348
 
    {
1349
 
        return pSample->m_pNext;
1350
 
    };
1351
 
 
1352
 
    /*  Mini list class for the free list */
1353
 
    class CSampleList
1354
 
    {
1355
 
    public:
1356
 
        CSampleList() : m_List(NULL), m_nOnList(0) {};
1357
 
#ifdef DEBUG
1358
 
        ~CSampleList()
1359
 
        {
1360
 
            ASSERT(m_nOnList == 0);
1361
 
        };
1362
 
#endif
1363
 
        CMediaSample *Head() const { return m_List; };
1364
 
        CMediaSample *Next(__in CMediaSample *pSample) const { return CBaseAllocator::NextSample(pSample); };
1365
 
        int GetCount() const { return m_nOnList; };
1366
 
        void Add(__inout CMediaSample *pSample)
1367
 
        {
1368
 
            ASSERT(pSample != NULL);
1369
 
            CBaseAllocator::NextSample(pSample) = m_List;
1370
 
            m_List = pSample;
1371
 
            m_nOnList++;
1372
 
        };
1373
 
        CMediaSample *RemoveHead()
1374
 
        {
1375
 
            CMediaSample *pSample = m_List;
1376
 
            if (pSample != NULL) {
1377
 
                m_List = CBaseAllocator::NextSample(m_List);
1378
 
                m_nOnList--;
1379
 
            }
1380
 
            return pSample;
1381
 
        };
1382
 
        void Remove(__inout CMediaSample *pSample);
1383
 
 
1384
 
    public:
1385
 
        CMediaSample *m_List;
1386
 
        int           m_nOnList;
1387
 
    };
1388
 
protected:
1389
 
 
1390
 
    CSampleList m_lFree;        // Free list
1391
 
 
1392
 
    /*  Note to overriders of CBaseAllocator.
1393
 
 
1394
 
        We use a lazy signalling mechanism for waiting for samples.
1395
 
        This means we don't call the OS if no waits occur.
1396
 
 
1397
 
        In order to implement this:
1398
 
 
1399
 
        1. When a new sample is added to m_lFree call NotifySample() which
1400
 
           calls ReleaseSemaphore on m_hSem with a count of m_lWaiting and
1401
 
           sets m_lWaiting to 0.
1402
 
           This must all be done holding the allocator's critical section.
1403
 
 
1404
 
        2. When waiting for a sample call SetWaiting() which increments
1405
 
           m_lWaiting BEFORE leaving the allocator's critical section.
1406
 
 
1407
 
        3. Actually wait by calling WaitForSingleObject(m_hSem, INFINITE)
1408
 
           having left the allocator's critical section.  The effect of
1409
 
           this is to remove 1 from the semaphore's count.  You MUST call
1410
 
           this once having incremented m_lWaiting.
1411
 
 
1412
 
        The following are then true when the critical section is not held :
1413
 
            (let nWaiting = number about to wait or waiting)
1414
 
 
1415
 
            (1) if (m_lFree.GetCount() != 0) then (m_lWaiting == 0)
1416
 
            (2) m_lWaiting + Semaphore count == nWaiting
1417
 
 
1418
 
        We would deadlock if
1419
 
           nWaiting != 0 &&
1420
 
           m_lFree.GetCount() != 0 &&
1421
 
           Semaphore count == 0
1422
 
 
1423
 
           But from (1) if m_lFree.GetCount() != 0 then m_lWaiting == 0 so
1424
 
           from (2) Semaphore count == nWaiting (which is non-0) so the
1425
 
           deadlock can't happen.
1426
 
    */
1427
 
 
1428
 
    HANDLE m_hSem;              // For signalling
1429
 
    long m_lWaiting;            // Waiting for a free element
1430
 
    long m_lCount;              // how many buffers we have agreed to provide
1431
 
    long m_lAllocated;          // how many buffers are currently allocated
1432
 
    long m_lSize;               // agreed size of each buffer
1433
 
    long m_lAlignment;          // agreed alignment
1434
 
    long m_lPrefix;             // agreed prefix (preceeds GetPointer() value)
1435
 
    BOOL m_bChanged;            // Have the buffer requirements changed
1436
 
 
1437
 
    // if true, we are decommitted and can't allocate memory
1438
 
    BOOL m_bCommitted;
1439
 
    // if true, the decommit has happened, but we haven't called Free yet
1440
 
    // as there are still outstanding buffers
1441
 
    BOOL m_bDecommitInProgress;
1442
 
 
1443
 
    //  Notification interface
1444
 
    IMemAllocatorNotifyCallbackTemp *m_pNotify;
1445
 
 
1446
 
    BOOL m_fEnableReleaseCallback;
1447
 
 
1448
 
    // called to decommit the memory when the last buffer is freed
1449
 
    // pure virtual - need to override this
1450
 
    virtual void Free(void) PURE;
1451
 
 
1452
 
    // override to allocate the memory when commit called
1453
 
    virtual HRESULT Alloc(void);
1454
 
 
1455
 
public:
1456
 
 
1457
 
    CBaseAllocator(
1458
 
        __in_opt LPCTSTR , __inout_opt LPUNKNOWN, __inout HRESULT *,
1459
 
        BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);
1460
 
#ifdef UNICODE
1461
 
    CBaseAllocator(
1462
 
        __in_opt LPCSTR , __inout_opt LPUNKNOWN, __inout HRESULT *,
1463
 
        BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);
1464
 
#endif
1465
 
    virtual ~CBaseAllocator();
1466
 
 
1467
 
    DECLARE_IUNKNOWN
1468
 
 
1469
 
    // override this to publicise our interfaces
1470
 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
1471
 
 
1472
 
    STDMETHODIMP SetProperties(
1473
 
                    __in ALLOCATOR_PROPERTIES* pRequest,
1474
 
                    __out ALLOCATOR_PROPERTIES* pActual);
1475
 
 
1476
 
    // return the properties actually being used on this allocator
1477
 
    STDMETHODIMP GetProperties(
1478
 
                    __out ALLOCATOR_PROPERTIES* pProps);
1479
 
 
1480
 
    // override Commit to allocate memory. We handle the GetBuffer
1481
 
    //state changes
1482
 
    STDMETHODIMP Commit();
1483
 
 
1484
 
    // override this to handle the memory freeing. We handle any outstanding
1485
 
    // GetBuffer calls
1486
 
    STDMETHODIMP Decommit();
1487
 
 
1488
 
    // get container for a sample. Blocking, synchronous call to get the
1489
 
    // next free buffer (as represented by an IMediaSample interface).
1490
 
    // on return, the time etc properties will be invalid, but the buffer
1491
 
    // pointer and size will be correct. The two time parameters are
1492
 
    // optional and either may be NULL, they may alternatively be set to
1493
 
    // the start and end times the sample will have attached to it
1494
 
    // bPrevFramesSkipped is not used (used only by the video renderer's
1495
 
    // allocator where it affects quality management in direct draw).
1496
 
 
1497
 
    STDMETHODIMP GetBuffer(__deref_out IMediaSample **ppBuffer,
1498
 
                           __in_opt REFERENCE_TIME * pStartTime,
1499
 
                           __in_opt REFERENCE_TIME * pEndTime,
1500
 
                           DWORD dwFlags);
1501
 
 
1502
 
    // final release of a CMediaSample will call this
1503
 
    STDMETHODIMP ReleaseBuffer(IMediaSample *pBuffer);
1504
 
    // obsolete:: virtual void PutOnFreeList(CMediaSample * pSample);
1505
 
 
1506
 
    STDMETHODIMP SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify);
1507
 
 
1508
 
    STDMETHODIMP GetFreeCount(__out LONG *plBuffersFree);
1509
 
 
1510
 
    // Notify that a sample is available
1511
 
    void NotifySample();
1512
 
 
1513
 
    // Notify that we're waiting for a sample
1514
 
    void SetWaiting() { m_lWaiting++; };
1515
 
};
1516
 
 
1517
 
 
1518
 
//=====================================================================
1519
 
//=====================================================================
1520
 
// Defines CMemAllocator
1521
 
//
1522
 
// this is an allocator based on CBaseAllocator that allocates sample
1523
 
// buffers in main memory (from 'new'). You must call SetProperties
1524
 
// before calling Commit.
1525
 
//
1526
 
// we don't free the memory when going into Decommit state. The simplest
1527
 
// way to implement this without complicating CBaseAllocator is to
1528
 
// have a Free() function, called to go into decommit state, that does
1529
 
// nothing and a ReallyFree function called from our destructor that
1530
 
// actually frees the memory.
1531
 
//=====================================================================
1532
 
//=====================================================================
1533
 
 
1534
 
//  Make me one from quartz.dll
1535
 
STDAPI CreateMemoryAllocator(__deref_out IMemAllocator **ppAllocator);
1536
 
 
1537
 
class CMemAllocator : public CBaseAllocator
1538
 
{
1539
 
 
1540
 
protected:
1541
 
 
1542
 
    LPBYTE m_pBuffer;   // combined memory for all buffers
1543
 
 
1544
 
    // override to free the memory when decommit completes
1545
 
    // - we actually do nothing, and save the memory until deletion.
1546
 
    void Free(void);
1547
 
 
1548
 
    // called from the destructor (and from Alloc if changing size/count) to
1549
 
    // actually free up the memory
1550
 
    void ReallyFree(void);
1551
 
 
1552
 
    // overriden to allocate the memory when commit called
1553
 
    HRESULT Alloc(void);
1554
 
 
1555
 
public:
1556
 
    /* This goes in the factory template table to create new instances */
1557
 
    static CUnknown *CreateInstance(__inout_opt LPUNKNOWN, __inout HRESULT *);
1558
 
 
1559
 
    STDMETHODIMP SetProperties(
1560
 
                    __in ALLOCATOR_PROPERTIES* pRequest,
1561
 
                    __out ALLOCATOR_PROPERTIES* pActual);
1562
 
 
1563
 
    CMemAllocator(__in_opt LPCTSTR , __inout_opt LPUNKNOWN, __inout HRESULT *);
1564
 
#ifdef UNICODE
1565
 
    CMemAllocator(__in_opt LPCSTR , __inout_opt LPUNKNOWN, __inout HRESULT *);
1566
 
#endif
1567
 
    ~CMemAllocator();
1568
 
};
1569
 
 
1570
 
// helper used by IAMovieSetup implementation
1571
 
STDAPI
1572
 
AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata
1573
 
                         , IFilterMapper *                  pIFM
1574
 
                         , BOOL                             bRegister  );
1575
 
 
1576
 
 
1577
 
///////////////////////////////////////////////////////////////////////////
1578
 
// ------------------------------------------------------------------------
1579
 
// ------------------------------------------------------------------------
1580
 
// ------------------------------------------------------------------------
1581
 
// ------------------------------------------------------------------------
1582
 
///////////////////////////////////////////////////////////////////////////
1583
 
 
1584
 
#endif /* __FILTER__ */
1585
 
 
1586
 
 
1587