~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/samples/winrt/ImageManipulations/MediaExtensions/Common/OpQueue.h

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// OpQueue.h
 
4
// Async operation queue.
 
5
//
 
6
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
 
7
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 
8
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 
9
// PARTICULAR PURPOSE.
 
10
//
 
11
// Copyright (c) Microsoft Corporation. All rights reserved.
 
12
//
 
13
//////////////////////////////////////////////////////////////////////////
 
14
 
 
15
#pragma once
 
16
 
 
17
#pragma warning( push )
 
18
#pragma warning( disable : 4355 )  // 'this' used in base member initializer list
 
19
 
 
20
/*
 
21
    This header file defines an object to help queue and serialize
 
22
    asynchronous operations.
 
23
 
 
24
    Background:
 
25
 
 
26
    To perform an operation asynchronously in Media Foundation, an object
 
27
    does one of the following:
 
28
 
 
29
        1. Calls MFPutWorkItem(Ex), using either a standard work queue
 
30
           identifier or a caller-allocated work queue. The work-queue
 
31
           thread invokes the object's callback.
 
32
 
 
33
        2. Creates an async result object (IMFAsyncResult) and calls
 
34
           MFInvokeCallback to invoke the object's callback.
 
35
 
 
36
    Ultimately, either of these cause the object's callback to be invoked
 
37
    from a work-queue thread. The object can then complete the operation
 
38
    inside the callback.
 
39
 
 
40
    However, the Media Foundation platform may dispatch async callbacks in
 
41
    parallel on several threads. Putting an item on a work queue does NOT
 
42
    guarantee that one operation will complete before the next one starts,
 
43
    or even that work items will be dispatched in the same order they were
 
44
    called.
 
45
 
 
46
    To serialize async operations that should not overlap, an object should
 
47
    use a queue. While one operation is pending, subsequent operations are
 
48
    put on the queue, and only dispatched after the previous operation is
 
49
    complete.
 
50
 
 
51
    The granularity of a single "operation" depends on the requirements of
 
52
    that particular object. A single operation might involve several
 
53
    asynchronous calls before the object dispatches the next operation on
 
54
    the queue.
 
55
 
 
56
 
 
57
*/
 
58
 
 
59
 
 
60
 
 
61
//-------------------------------------------------------------------
 
62
// OpQueue class template
 
63
//
 
64
// Base class for an async operation queue.
 
65
//
 
66
// TOperation: The class used to describe operations. This class must
 
67
//          implement IUnknown.
 
68
//
 
69
// The OpQueue class is an abstract class. The derived class must
 
70
// implement the following pure-virtual methods:
 
71
//
 
72
// - IUnknown methods (AddRef, Release, QI)
 
73
//
 
74
// - DispatchOperation:
 
75
//
 
76
//      Performs the asynchronous operation specified by pOp.
 
77
//
 
78
//      At the end of each operation, the derived class must call
 
79
//      ProcessQueue to process the next operation in the queue.
 
80
//
 
81
//      NOTE: An operation is not required to complete inside the
 
82
//      DispatchOperation method. A single operation might consist
 
83
//      of several asynchronous method calls.
 
84
//
 
85
// - ValidateOperation:
 
86
//
 
87
//      Checks whether the object can perform the operation specified
 
88
//      by pOp at this time.
 
89
//
 
90
//      If the object cannot perform the operation now (e.g., because
 
91
//      another operation is still in progress) the method should
 
92
//      return MF_E_NOTACCEPTING.
 
93
//
 
94
//-------------------------------------------------------------------
 
95
#include "linklist.h"
 
96
#include "AsyncCB.h"
 
97
 
 
98
template <class T, class TOperation>
 
99
class OpQueue //: public IUnknown
 
100
{
 
101
public:
 
102
 
 
103
    typedef ComPtrList<TOperation>   OpList;
 
104
 
 
105
    HRESULT QueueOperation(TOperation *pOp);
 
106
 
 
107
protected:
 
108
 
 
109
    HRESULT ProcessQueue();
 
110
    HRESULT ProcessQueueAsync(IMFAsyncResult *pResult);
 
111
 
 
112
    virtual HRESULT DispatchOperation(TOperation *pOp) = 0;
 
113
    virtual HRESULT ValidateOperation(TOperation *pOp) = 0;
 
114
 
 
115
    OpQueue(CRITICAL_SECTION& critsec)
 
116
        : m_OnProcessQueue(static_cast<T *>(this), &OpQueue::ProcessQueueAsync),
 
117
          m_critsec(critsec)
 
118
    {
 
119
    }
 
120
 
 
121
    virtual ~OpQueue()
 
122
    {
 
123
    }
 
124
 
 
125
protected:
 
126
    OpList                  m_OpQueue;         // Queue of operations.
 
127
    CRITICAL_SECTION&       m_critsec;         // Protects the queue state.
 
128
    AsyncCallback<T>  m_OnProcessQueue;  // ProcessQueueAsync callback.
 
129
};
 
130
 
 
131
 
 
132
 
 
133
//-------------------------------------------------------------------
 
134
// Place an operation on the queue.
 
135
// Public method.
 
136
//-------------------------------------------------------------------
 
137
 
 
138
template <class T, class TOperation>
 
139
HRESULT OpQueue<T, TOperation>::QueueOperation(TOperation *pOp)
 
140
{
 
141
    HRESULT hr = S_OK;
 
142
 
 
143
    EnterCriticalSection(&m_critsec);
 
144
 
 
145
    hr = m_OpQueue.InsertBack(pOp);
 
146
    if (SUCCEEDED(hr))
 
147
    {
 
148
        hr = ProcessQueue();
 
149
    }
 
150
 
 
151
    LeaveCriticalSection(&m_critsec);
 
152
    return hr;
 
153
}
 
154
 
 
155
 
 
156
//-------------------------------------------------------------------
 
157
// Process the next operation on the queue.
 
158
// Protected method.
 
159
//
 
160
// Note: This method dispatches the operation to a work queue.
 
161
//-------------------------------------------------------------------
 
162
 
 
163
template <class T, class TOperation>
 
164
HRESULT OpQueue<T, TOperation>::ProcessQueue()
 
165
{
 
166
    HRESULT hr = S_OK;
 
167
    if (m_OpQueue.GetCount() > 0)
 
168
    {
 
169
        hr = MFPutWorkItem2(
 
170
            MFASYNC_CALLBACK_QUEUE_STANDARD,    // Use the standard work queue.
 
171
            0,                                  // Default priority
 
172
            &m_OnProcessQueue,                  // Callback method.
 
173
            nullptr                             // State object.
 
174
            );
 
175
    }
 
176
    return hr;
 
177
}
 
178
 
 
179
 
 
180
//-------------------------------------------------------------------
 
181
// Process the next operation on the queue.
 
182
// Protected method.
 
183
//
 
184
// Note: This method is called from a work-queue thread.
 
185
//-------------------------------------------------------------------
 
186
 
 
187
template <class T, class TOperation>
 
188
HRESULT OpQueue<T, TOperation>::ProcessQueueAsync(IMFAsyncResult *pResult)
 
189
{
 
190
    HRESULT hr = S_OK;
 
191
    TOperation *pOp = nullptr;
 
192
 
 
193
    EnterCriticalSection(&m_critsec);
 
194
 
 
195
    if (m_OpQueue.GetCount() > 0)
 
196
    {
 
197
        hr = m_OpQueue.GetFront(&pOp);
 
198
 
 
199
        if (SUCCEEDED(hr))
 
200
        {
 
201
            hr = ValidateOperation(pOp);
 
202
        }
 
203
        if (SUCCEEDED(hr))
 
204
        {
 
205
            hr = m_OpQueue.RemoveFront(nullptr);
 
206
        }
 
207
        if (SUCCEEDED(hr))
 
208
        {
 
209
            (void)DispatchOperation(pOp);
 
210
        }
 
211
    }
 
212
 
 
213
    if (pOp != nullptr)
 
214
    {
 
215
        pOp->Release();
 
216
    }
 
217
 
 
218
    LeaveCriticalSection(&m_critsec);
 
219
    return hr;
 
220
}
 
221
 
 
222
#pragma warning( pop )