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
291
292
293
294
|
/**************************************************************************
AVStream Simulated Hardware Sample
Copyright (c) 2001, Microsoft Corporation.
File:
device.h
Abstract:
The header for the device level of the simulated hardware. This is
not actually the hardware simulation itself. The hardware simulation
is contained in hwsim.*, image.*.
History:
created 3/9/2001
**************************************************************************/
class CCaptureDevice :
public IHardwareSink {
private:
//
// The AVStream device we're associated with.
//
PKSDEVICE m_Device;
//
// Number of pins with resources acquired. This is used as a locking
// mechanism for resource acquisition on the device.
//
LONG m_PinsWithResources;
//
// Since we don't have physical hardware, this provides the hardware
// simulation. m_HardwareSimulation provides the fake ISR, fake DPC,
// etc... m_ImageSynth provides RGB24 and UYVY image synthesis and
// overlay in software.
//
CHardwareSimulation *m_HardwareSimulation;
CImageSynthesizer *m_ImageSynth;
//
// The number of ISR's that have occurred since capture started.
//
ULONG m_InterruptTime;
//
// The last reading of mappings completed.
//
ULONG m_LastMappingsCompleted;
//
// The Dma adapter object we acquired through IoGetDmaAdapter() during
// Pnp start. This must be initialized with AVStream in order to perform
// Dma directly into the capture buffers.
//
PADAPTER_OBJECT m_DmaAdapterObject;
//
// The number of map registers returned from IoGetDmaAdapter().
//
ULONG m_NumberOfMapRegisters;
//
// The capture sink. When we complete scatter / gather mappings, we
// notify the capture sink.
//
ICaptureSink *m_CaptureSink;
//
// The video info header we're basing hardware settings on. The pin
// provides this to us when acquiring resources and must guarantee its
// stability until resources are released.
//
PKS_VIDEOINFOHEADER m_VideoInfoHeader;
//
// Cleanup():
//
// This is the free callback for the bagged capture device. Not providing
// one will call ExFreePool, which is not what we want for a constructed
// C++ object. This simply deletes the capture device.
//
static
void
Cleanup (
IN CCaptureDevice *CapDevice
)
{
delete CapDevice;
}
//
// PnpStart():
//
// This is the Pnp start routine for our simulated hardware. Note that
// DispatchStart bridges to here in the context of the CCaptureDevice.
//
NTSTATUS
PnpStart (
IN PCM_RESOURCE_LIST TranslatedResourceList,
IN PCM_RESOURCE_LIST UntranslatedResourceList
);
//
// PnpStop():
//
// This is the Pnp stop routine for our simulated hardware. Note that
// DispatchStop bridges to here in the context of the CCaptureDevice.
//
void
PnpStop (
);
public:
//
// CCaptureDevice():
//
// The capture device class constructor. Since everything should have
// been zero'ed by the new operator, don't bother setting anything to
// zero or NULL. Only initialize non-NULL, non-0 fields.
//
CCaptureDevice (
IN PKSDEVICE Device
) :
m_Device (Device)
{
}
//
// ~CCaptureDevice():
//
// The capture device destructor.
//
~CCaptureDevice (
)
{
}
//
// DispatchCreate():
//
// This is the Add Device dispatch for the capture device. It creates
// the CCaptureDevice and associates it with the device via the bag.
//
static
NTSTATUS
DispatchCreate (
IN PKSDEVICE Device
);
//
// DispatchPnpStart():
//
// This is the Pnp Start dispatch for the capture device. It simply
// bridges to PnpStart() in the context of the CCaptureDevice.
//
static
NTSTATUS
DispatchPnpStart (
IN PKSDEVICE Device,
IN PIRP Irp,
IN PCM_RESOURCE_LIST TranslatedResourceList,
IN PCM_RESOURCE_LIST UntranslatedResourceList
)
{
return
(reinterpret_cast <CCaptureDevice *> (Device -> Context)) ->
PnpStart (
TranslatedResourceList,
UntranslatedResourceList
);
}
//
// DispatchPnpStop():
//
// This is the Pnp stop dispatch for the capture device. It simply
// bridges to PnpStop() in the context of the CCaptureDevice.
//
static
void
DispatchPnpStop (
IN PKSDEVICE Device,
IN PIRP Irp
)
{
return
(reinterpret_cast <CCaptureDevice *> (Device -> Context)) ->
PnpStop (
);
}
//
// AcquireHardwareResources():
//
// Called to acquire hardware resources for the device based on a given
// video info header. This will fail if another object has already
// acquired hardware resources since we emulate a single capture
// device.
//
NTSTATUS
AcquireHardwareResources (
IN ICaptureSink *CaptureSink,
IN PKS_VIDEOINFOHEADER VideoInfoHeader
);
//
// ReleaseHardwareResources():
//
// Called to release hardware resources for the device.
//
void
ReleaseHardwareResources (
);
//
// Start():
//
// Called to start the hardware simulation. This causes us to simulate
// interrupts, simulate filling buffers with synthesized data, etc...
//
NTSTATUS
Start (
);
//
// Pause():
//
// Called to pause or unpause the hardware simulation. This will be
// indentical to a start or stop but it will not reset formats and
// counters.
//
NTSTATUS
Pause (
IN BOOLEAN Pausing
);
//
// Stop():
//
// Called to stop the hardware simulation. This causes interrupts to
// stop issuing. When this call returns, the "fake" hardware has
// stopped accessing all s/g buffers, etc...
//
NTSTATUS
Stop (
);
//
// ProgramScatterGatherMappings():
//
// Called to program the hardware simulation's scatter / gather table.
// This synchronizes with the "fake" ISR and hardware simulation via
// a spinlock.
//
ULONG
ProgramScatterGatherMappings (
IN PKSSTREAM_POINTER Clone,
IN PUCHAR *Buffer,
IN PKSMAPPING Mappings,
IN ULONG MappingsCount
);
//
// QueryInterruptTime():
//
// Determine the frame number that this frame corresponds to.
//
ULONG
QueryInterruptTime (
);
//
// IHardwareSink::Interrupt():
//
// The interrupt service routine as called through the hardware sink
// interface. The "fake" hardware uses this method to inform the device
// of a "fake" ISR. The routine is called at dispatch level and must
// be in locked code.
//
virtual
void
Interrupt (
);
LONG GetDroppedFrameCount(){return m_HardwareSimulation->GetSkippedFrameCount();};
};
|