summaryrefslogtreecommitdiffstats
path: root/thirdparties/win32/include/directshow/outputq.h
blob: 7e60b53a990963a8680104399d8ec5c6c6c43855 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//------------------------------------------------------------------------------
// File: OutputQ.h
//
// Desc: DirectShow base classes -  defines the COutputQueue class, which
//       makes a queue of samples and sends them to an output pin.  The 
//       class will optionally send the samples to the pin directly.
//
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


typedef CGenericList<IMediaSample> CSampleList;

class COutputQueue : public CCritSec
{
public:
    //  Constructor
    COutputQueue(IPin      *pInputPin,          //  Pin to send stuff to
                 __inout HRESULT *phr,          //  'Return code'
                 BOOL       bAuto = TRUE,       //  Ask pin if blocks
                 BOOL       bQueue = TRUE,      //  Send through queue (ignored if
                                                //  bAuto set)
                 LONG       lBatchSize = 1,     //  Batch
                 BOOL       bBatchExact = FALSE,//  Batch exactly to BatchSize
                 LONG       lListSize =         //  Likely number in the list
                                DEFAULTCACHE,
                 DWORD      dwPriority =        //  Priority of thread to create
                                THREAD_PRIORITY_NORMAL,
                 bool       bFlushingOpt = false // flushing optimization
                );
    ~COutputQueue();

    // enter flush state - discard all data
    void BeginFlush();      // Begin flushing samples

    // re-enable receives (pass this downstream)
    void EndFlush();        // Complete flush of samples - downstream
                            // pin guaranteed not to block at this stage

    void EOS();             // Call this on End of stream

    void SendAnyway();      // Send batched samples anyway (if bBatchExact set)

    void NewSegment(
            REFERENCE_TIME tStart,
            REFERENCE_TIME tStop,
            double dRate);

    HRESULT Receive(IMediaSample *pSample);

    // do something with these media samples
    HRESULT ReceiveMultiple (
        __in_ecount(nSamples) IMediaSample **pSamples,
        long nSamples,
        __out long *nSamplesProcessed);

    void Reset();           // Reset m_hr ready for more data

    //  See if its idle or not
    BOOL IsIdle();

    // give the class an event to fire after everything removed from the queue
    void SetPopEvent(HANDLE hEvent);

protected:
    static DWORD WINAPI InitialThreadProc(__in LPVOID pv);
    DWORD ThreadProc();
    BOOL  IsQueued()
    {
        return m_List != NULL;
    };

    //  The critical section MUST be held when this is called
    void QueueSample(IMediaSample *pSample);

    BOOL IsSpecialSample(IMediaSample *pSample)
    {
        return (DWORD_PTR)pSample > (DWORD_PTR)(LONG_PTR)(-16);
    };

    //  Remove and Release() batched and queued samples
    void FreeSamples();

    //  Notify the thread there is something to do
    void NotifyThread();


protected:
    //  Queue 'messages'
    #define SEND_PACKET      ((IMediaSample *)(LONG_PTR)(-2))  // Send batch
    #define EOS_PACKET       ((IMediaSample *)(LONG_PTR)(-3))  // End of stream
    #define RESET_PACKET     ((IMediaSample *)(LONG_PTR)(-4))  // Reset m_hr
    #define NEW_SEGMENT      ((IMediaSample *)(LONG_PTR)(-5))  // send NewSegment

    // new segment packet is always followed by one of these
    struct NewSegmentPacket {
        REFERENCE_TIME tStart;
        REFERENCE_TIME tStop;
        double dRate;
    };

    // Remember input stuff
    IPin          * const m_pPin;
    IMemInputPin  *       m_pInputPin;
    BOOL            const m_bBatchExact;
    LONG            const m_lBatchSize;

    CSampleList   *       m_List;
    HANDLE                m_hSem;
    CAMEvent                m_evFlushComplete;
    HANDLE                m_hThread;
    __field_ecount_opt(m_lBatchSize) IMediaSample  **      m_ppSamples;
    __range(0, m_lBatchSize)         LONG                  m_nBatched;

    //  Wait optimization
    LONG                  m_lWaiting;
    //  Flush synchronization
    BOOL                  m_bFlushing;

    // flushing optimization. some downstream filters have trouble
    // with the queue's flushing optimization. other rely on it
    BOOL                  m_bFlushed;
    bool                  m_bFlushingOpt;

    //  Terminate now
    BOOL                  m_bTerminate;

    //  Send anyway flag for batching
    BOOL                  m_bSendAnyway;

    //  Deferred 'return code'
    HRESULT volatile         m_hr;

    // an event that can be fired after every deliver
    HANDLE m_hEventPop;
};

OpenPOWER on IntegriCloud