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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
|
/**************************************************************************
A/V Stream Camera Sample
Copyright (c) 2001, Microsoft Corporation.
File:
device.h
Abstract:
This file contains the declaration of CCaptureDevice.
CCaptureDevice is the base device class object. It handles basic PnP
requests and constructs the filter factories.
History:
created 3/9/2001
**************************************************************************/
//
// Forward references...
//
class CSensor;
struct CSensorContext
{
PWSTR Name; // What to call this class of filter.
const KSFILTER_DESCRIPTOR *Descriptor; // The description of the filter.
AcpiPldPanel AcpiPosition; // Where the device is located.
AcpiPldRotation AcpiRotation; // How the device is oriented with respect to the panel.
};
static constexpr ULONG PnpAcpiPanelSideMap[]
{
1, // AcpiPldPanelTop
2, // AcpiPldPanelBottom
3, // AcpiPldPanelLeft
4, // AcpiPldPanelRight
5, // AcpiPldPanelFront
6, // AcpiPldPanelBack
0, // AcpiPldPanelUnknown
};
class CCaptureDevice
{
protected:
//
// The AVStream device we're associated with.
//
PKSDEVICE m_Device;
//
// Since we don't have physical hardware, this provides the hardware
// simulation. m_HardwareSimulation provides the fake ISR, fake DPC,
// etc... m_Synthesizer provides RGB24 and UYVY image synthesis and
// overlay in software.
//
//
// Number of pins with resources acquired. This is used as a locking
// mechanism for resource acquisition on the device.
//
// The capture pin. When we complete scatter / gather mappings, we
// notify the capture pin.
//
// Number of Filter descriptors & filter factories.
ULONG m_FilterDescriptorCount;
// Pointer to an array of filter descriptor pointers.
// Typically it's one sensor for each filter factory.
CSensorContext *m_Context;
// The sensor state for each camera.
CSensor **m_Sensor;
//
// 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;
//
// 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;
}
//
// Prepare():
//
// Called by CCaptureDevice::DispatchCreate to finish AddDevice processing,
// once the object is created.
//
// This is a seperate helper function to allow the derived DispatchCreate
// implementation to be as simple as is feasible.
//
virtual
NTSTATUS
Prepare();
public:
//
// 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
);
//
// DispatchStart():
//
// This is the Pnp Start dispatch for the capture device. It simply
// bridges to PnpStart() in the context of the CCaptureDevice.
//
static
NTSTATUS
DispatchStart (
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ PCM_RESOURCE_LIST TranslatedResourceList,
_In_ PCM_RESOURCE_LIST UntranslatedResourceList
);
//
// DispatchStop():
//
// This is the Pnp stop dispatch for the capture device. It simply
// bridges to PnpStop() in the context of the CCaptureDevice.
//
static
void
DispatchStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
NTSTATUS
DispatchPostStart(
_In_ PKSDEVICE Device
);
static
NTSTATUS
DispatchQueryStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
void
DispatchCancelStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
NTSTATUS
DispatchQueryRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
void
DispatchCancelRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
void
DispatchRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
void
DispatchSurpriseRemoval(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
static
NTSTATUS
DispatchQueryCapabilities(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_Inout_ PDEVICE_CAPABILITIES Capabilities
);
static
NTSTATUS
DispatchQueryPower(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE DeviceTo,
_In_ DEVICE_POWER_STATE DeviceFrom,
_In_ SYSTEM_POWER_STATE SystemTo,
_In_ SYSTEM_POWER_STATE SystemFrom,
_In_ POWER_ACTION Action
);
static
void
DispatchSetPower(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE To,
_In_ DEVICE_POWER_STATE From
);
static
NTSTATUS
DispatchQueryInterface(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
protected:
//
// PnpStart():
//
// This is the Pnp start routine for our simulated hardware. Note that
// DispatchStart bridges to here in the context of the CCaptureDevice.
//
virtual
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.
//
virtual
void
PnpStop (
_In_ PIRP Irp
);
virtual
NTSTATUS
PnpPostStart();
virtual
NTSTATUS
PnpQueryStop(
_In_ PIRP Irp
);
virtual
void
PnpCancelStop(
_In_ PIRP Irp
);
virtual
NTSTATUS
PnpQueryRemove(
_In_ PIRP Irp
);
virtual
void
PnpCancelRemove(
_In_ PIRP Irp
);
virtual
void
PnpRemove(
_In_ PIRP Irp
);
virtual
void
PnpSurpriseRemoval(
_In_ PIRP Irp
);
virtual
NTSTATUS
PnpQueryCapabilities(
_In_ PIRP Irp,
_Inout_ PDEVICE_CAPABILITIES Capabilities
);
virtual
NTSTATUS
PnpQueryPower(
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE DeviceTo,
_In_ DEVICE_POWER_STATE DeviceFrom,
_In_ SYSTEM_POWER_STATE SystemTo,
_In_ SYSTEM_POWER_STATE SystemFrom,
_In_ POWER_ACTION Action
);
virtual
void
PnpSetPower(
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE To,
_In_ DEVICE_POWER_STATE From
);
virtual
NTSTATUS
PnpQueryInterface(
_In_ PIRP Irp
);
protected:
virtual
CSensor *
CreateSensor(
_In_ const KSFILTER_DESCRIPTOR *Descriptors
);
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
);
//
// ~CCaptureDevice():
//
// The capture device destructor.
//
virtual
~CCaptureDevice();
virtual
NTSTATUS
Initialize();
//
// Recast():
//
// Helper function. Used to convert from a PKSDEVICE to a CCaptureDevice *
//
static
inline
CCaptureDevice *
Recast(
_In_ PKSDEVICE Device
)
{
return reinterpret_cast <CCaptureDevice *> (Device -> Context);
}
//
// QueryInterruptTime():
//
// Determine the frame number that this frame corresponds to.
//
ULONG
QueryInterruptTime (LONG ID,
_In_ PKSPIN Pin
);
virtual
PDEVICE_OBJECT
GetDeviceObject();
static IO_COMPLETION_ROUTINE IrpSynchronousCompletion;
virtual
_Must_inspect_result_
NTSTATUS
QueryForInterface(
_In_ PDEVICE_OBJECT TopOfStack,
_In_ const GUID* InterfaceType,
_Out_ PINTERFACE Interface,
_In_ USHORT Size,
_In_ USHORT Version,
_In_opt_ PVOID InterfaceSpecificData
);
ULONG
GetFilterIndex(PKSFILTER Filter);
ULONG
GetFilterCount()
{
return (ULONG) m_FilterDescriptorCount;
}
PCWSTR
GetFilterName(ULONG FilterIndex)
{
return (FilterIndex < m_FilterDescriptorCount) ? m_Context[FilterIndex].Name : nullptr;
}
CSensor *
GetSensor( PKSFILTER Filter )
{
ULONG Index = GetFilterIndex(Filter);
return ( Index < m_FilterDescriptorCount ) ? m_Sensor[ Index ] : nullptr;
}
};
//
// Define a dispatch table for a capture pin. It provides notifications
// about creation, closure, processing, data formats, etc...
//
#define DEFINE_CAMERA_KSDEVICE_DISPATCH( Table, Class ) \
const \
KSDEVICE_DISPATCH \
Table = \
{ \
Class::DispatchCreate, /* Pnp Add Device */ \
Class::DispatchStart, /* Pnp Start */ \
Class::DispatchPostStart, /* Post-Start */ \
Class::DispatchQueryStop, /* Pnp Query Stop */ \
Class::DispatchCancelStop, /* Pnp Cancel Stop */ \
Class::DispatchStop, /* Pnp Stop */ \
Class::DispatchQueryRemove, /* Pnp Query Remove */ \
Class::DispatchCancelRemove, /* Pnp Cancel Remove */ \
Class::DispatchRemove, /* Pnp Remove */ \
Class::DispatchQueryCapabilities, /* Pnp Query Capabilities */ \
Class::DispatchSurpriseRemoval, /* Pnp Surprise Removal */ \
Class::DispatchQueryPower, /* Power Query Power */ \
Class::DispatchSetPower, /* Power Set Power */ \
Class::DispatchQueryInterface /* Pnp Query Interface */ \
};
|