summaryrefslogtreecommitdiff
path: root/avstream/avshws/hwsim.h
blob: 21ddcb41971ad2431e18d9371652174ee631605c (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/**************************************************************************

    AVStream Simulated Hardware Sample

    Copyright (c) 2001, Microsoft Corporation.

    File:

        hwsim.cpp

    Abstract:
        
        This file is the hardware simulation header.  

        The simulation fakes "DMA" transfers, scatter gather mapping handling, 
        ISR's, etc...  The ISR routine in here will be called when an ISR 
        would be generated by the fake hardware and it will directly call into 
        the device level ISR for more accurate simulation.

    History:

        created 3/9/2001

**************************************************************************/

//
// SCATTER_GATHER_MAPPINGS_MAX:
//
// The maximum number of entries in the hardware's scatter/gather list.  I
// am making this so large for a few reasons:
//
//     1) we're faking this with uncompressed surfaces -- 
//            these are large buffers which will map to a lot of s/g entries
//     2) the fake hardware implementation requires at least one frame's
//            worth of s/g entries to generate a frame
//
#define SCATTER_GATHER_MAPPINGS_MAX 128

//
// SCATTER_GATHER_ENTRY:
//
// This structure is used to keep the scatter gather table for the fake
// hardware as a doubly linked list.
//
typedef struct _SCATTER_GATHER_ENTRY {

    LIST_ENTRY ListEntry;
    PKSSTREAM_POINTER CloneEntry;
    PUCHAR Virtual;
    ULONG ByteCount;

} SCATTER_GATHER_ENTRY, *PSCATTER_GATHER_ENTRY;

//
// CHardwareSimulation:
//
// The hardware simulation class.
//
class CHardwareSimulation {

private:

    //
    // The image synthesizer.  This is a piece of code which actually draws
    // the requested images.
    //
    CImageSynthesizer *m_ImageSynth;

    //
    // The synthesis buffer.  This is a private buffer we use to generate the
    // capture image in.  The fake "scatter / gather" mappings are filled
    // in from this buffer during each interrupt.
    //
    PUCHAR m_SynthesisBuffer;

    //
    // Key information regarding the frames we generate.
    //
    LONGLONG m_TimePerFrame;
    ULONG m_Width;
    ULONG m_Height;
    ULONG m_ImageSize;

    //
    // Scatter gather mappings for the simulated hardware.
    //
    KSPIN_LOCK m_ListLock;
    LIST_ENTRY m_ScatterGatherMappings;

    //
    // Lookaside for memory for the scatter / gather entries on the scatter /
    // gather list.
    //
    NPAGED_LOOKASIDE_LIST m_ScatterGatherLookaside;

    //
    // The current state of the fake hardware.
    //
    HARDWARE_STATE m_HardwareState;

    //
    // The pause / stop hardware flag and event.
    //
    BOOLEAN m_StopHardware;
    KEVENT m_HardwareEvent;

    //
    // Maximum number of scatter / gather mappins in the s/g table of the
    // fake hardware.
    //
    ULONG m_ScatterGatherMappingsMax;

    //
    // Number of scatter / gather mappings that have been completed (total)
    // since the start of the hardware or any reset.
    //
    ULONG m_NumMappingsCompleted;

    //
    // Number of scatter / gather mappings that are queued for this hardware.
    //
    ULONG m_ScatterGatherMappingsQueued;
    ULONG m_ScatterGatherBytesQueued;

    //
    // Number of frames skipped due to lack of scatter / gather mappings.
    //
    ULONG m_NumFramesSkipped;

    //
    // The "Interrupt Time".  Number of "fake" interrupts that have occurred
    // since the hardware was started.
    // 
    ULONG m_InterruptTime;

    //
    // The system time at start.
    //
    LARGE_INTEGER m_StartTime;
    
    //
    // The DPC used to "fake" ISR
    //
    KDPC m_IsrFakeDpc;
    KTIMER m_IsrTimer;

    //
    // The hardware sink that will be used for interrupt notifications.
    //
    IHardwareSink *m_HardwareSink;

    //
    // FillScatterGatherBuffers():
    //
    // This is called by the hardware simulation to fill a series of scatter /
    // gather buffers with synthesized data.
    //
    NTSTATUS
    FillScatterGatherBuffers (
        );

public:

    LONG GetSkippedFrameCount()
    {
        return InterlockedExchange((LONG*)&this->m_NumFramesSkipped, this->m_NumFramesSkipped);
    }
    //
    // CHardwareSimulation():
    //
    // The hardware simulation constructor.  Since the new operator will
    // have zeroed the memory, only initialize non-NULL, non-0 fields. 
    //
    CHardwareSimulation (
        IN IHardwareSink *HardwareSink
        );

    //
    // ~CHardwareSimulation():
    //
    // The hardware simulation destructor.
    //
    ~CHardwareSimulation (
        )
    {
    }

    //
    // Cleanup():
    //
    // This is the free callback for the bagged hardware sim.  Not providing
    // one will call ExFreePool, which is not what we want for a constructed
    // C++ object.  This simply deletes the simulation.
    //
    static
    void
    Cleanup (
        IN CHardwareSimulation *HwSim
        )
    {
        delete HwSim;
    }

    //
    // FakeHardware():
    //
    // Called from the simulated interrupt.  First we fake the hardware's
    // actions (at DPC) then we call the "Interrupt service routine" on
    // the hardware sink.
    //
    void
    FakeHardware (
        );

    //
    // Start():
    //
    // "Start" the fake hardware.  This will start issuing interrupts and 
    // DPC's. 
    //
    // The frame rate, image size, and a synthesizer must be provided.
    //
    NTSTATUS
    Start (
        CImageSynthesizer *ImageSynth,
        IN LONGLONG TimePerFrame,
        IN ULONG Width,
        IN ULONG Height,
        IN ULONG ImageSize
        );

    //
    // Pause():
    //
    // "Pause" or "unpause" the fake hardware.  This will stop issuing 
    // interrupts or DPC's on a pause and restart them on an unpause.  Note
    // that this will not reset counters as a Stop() would.
    //
    NTSTATUS
    Pause (
        IN BOOLEAN Pausing
        );

    //
    // Stop():
    //
    // "Stop" the fake hardware.  This will stop issuing interrupts and
    // DPC's.
    //
    NTSTATUS
    Stop (
        );

    //
    // ProgramScatterGatherMappings():
    //
    // Program a series of scatter gather mappings into the fake hardware.
    //
    ULONG
    ProgramScatterGatherMappings (
        IN PKSSTREAM_POINTER Clone,
        IN PUCHAR *Buffer,
        IN PKSMAPPING Mappings,
        IN ULONG MappingsCount,
        IN ULONG MappingStride
        );

    //
    // Initialize():
    //
    // Initialize a piece of simulated hardware.
    //
    static 
    CHardwareSimulation *
    Initialize (
        IN KSOBJECT_BAG Bag,
        IN IHardwareSink *HardwareSink
        );

    //
    // ReadNumberOfMappingsCompleted():
    //
    // Read the number of mappings completed since the last hardware reset.
    //
    ULONG
    ReadNumberOfMappingsCompleted (
        );

};