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
|
/**************************************************************************
A/V Stream Camera Sample
Copyright (c) 2001, Microsoft Corporation.
File:
hwsim.h
Abstract:
This file contains the definition of the base class, CHardwareSimulation,
used to simulate a camera's capture stream.
Our simulation cannot mimic a real camera with any precision. A real
camera would likely have dedicated hardware to provide interrupts, do
DMA transfers of frames from an internal buffer as well as do scaling
and on-the-fly colorspace and planar format conversions so as to supply
frames for preview, video and photo in varying resolutions and
colorspaces.
This simulation does not have such hardware, so instead it synthesizes
a frame on the fly for each local pin as required. The frame is
synthesized from common state information, so the images produced
should be comparable from pin to pin. CHardwareSimulation is used as
a base class for each simulated pin / hardware.
A CHardwareSimulation contains state, a list of frame bufferss and a
timer that is used in place of a hardware interrupt. The timer
schedules a workitem that is used to synthesize an image, select a
buffer and copy that image into the buffer.
Specializations of CHardwareSimulation provide differing metadata and
implement specialized functionality for photo sequence and variable
photo sequence.
History:
created 3/9/2001
**************************************************************************/
#define SCATTER_GATHER_MAPPINGS_MAX 128
// forward class references
class CSensor;
class CHardwareSimulation;
class CHwSimTimer;
// internal structure definitions
// Face metadata structure. Face metadata can be synthesized on any pin.
class CAMERA_METADATA_FACE_DETECTION
: public CAMERA_METADATA_FACEHEADER
{
public:
METADATA_FACEDATA Data[MAX_FACES];
};
// Information about each frame buffer in the queue.
typedef struct _SCATTER_GATHER_ENTRY
{
LIST_ENTRY ListEntry;
PKSSTREAM_POINTER CloneEntry;
PUCHAR Virtual;
ULONG ByteCount;
PHOTOCONFIRMATION_INFO PhotoConfirmationInfo;
} SCATTER_GATHER_ENTRY, *PSCATTER_GATHER_ENTRY;
//
// A specialization of a KPassiveTimer that holds a back pointer to the
// CHardwareSimulation that owns it.
//
class CHwSimTimer
: public KPassiveTimer
{
CHardwareSimulation *m_Parent;
public:
CHwSimTimer(
_In_ CHardwareSimulation *Parent
);
//
// Sets the timer
//
BOOLEAN
Set(
_In_ LARGE_INTEGER DueTime
);
private:
static
void
Handler(
_In_opt_ PVOID Context
);
};
class CHardwareSimulation
{
protected:
CSynthesizer *m_Synthesizer; // Synthesizer for various formats.
LONGLONG m_TimePerFrame;
ULONG m_Width;
ULONG m_Height;
ULONG m_ImageSize;
LONG m_PinID;
KMutex m_ListLock;
LIST_ENTRY m_ScatterGatherMappings;
NPAGED_LOOKASIDE_LIST m_ScatterGatherLookaside;
PIN_STATE m_PinState;
ULONG m_ScatterGatherMappingsMax;
ULONG m_NumMappingsCompleted;
ULONG m_ScatterGatherMappingsQueued;
ULONG m_ScatterGatherBytesQueued;
LONGLONG m_NumFramesSkipped;
LONGLONG m_InterruptTime;
LARGE_INTEGER m_StartTime;
CSensor *m_Sensor;
CHwSimTimer m_IsrTimer;
PHOTOCONFIRMATION_INFO m_PhotoConfirmationEntry;
// Cached values used for Locking simulated state.
LONGLONG m_LastReportedExposureTime;
ULONG m_LastReportedWhiteBalance;
// Used to simulate the skipping of frames when reporting face detection data.
ULONG m_FaceDetectionDelay;
CAMERA_METADATA_FACE_DETECTION m_LastFaceDetect;
// Copy a synthesized framebuffer.
virtual
NTSTATUS
FillScatterGatherBuffers();
// Overloadable function for attaching metadata to a frame.
virtual
void
EmitMetadata(
_Inout_ PKSSTREAM_HEADER pStreamHeader
);
virtual
bool
CheckForAvailableBuffer();
virtual
NTSTATUS
CommitImageData(PSCATTER_GATHER_ENTRY sGEntry, ULONG stride);
virtual
NTSTATUS
ValidateBuffer(PSCATTER_GATHER_ENTRY sGEntry);
// Helper function to generate random face metadata.
void
EmitFaceMetadata(
_Inout_ PKSSTREAM_HEADER pStreamHeader,
_In_ ULONG Count,
_In_ ULONGLONG Flags,
_In_ ULONG DelayLimit=30
);
// Release an entry from our queue.
void
FreeSGEntry(
_In_ PLIST_ENTRY Entry,
_In_ PCWSTR EventName=L"StreamPointer freed",
_In_opt_ LPCGUID Activity=NULL,
_In_ ULONG DataUsed=0
);
// Release our entire queue.
void
FreeSGList(
_In_ PLIST_ENTRY List,
_In_ PCWSTR EventName=L"StreamPointer freed",
_In_opt_ LPCGUID Activity=NULL
);
public:
// Debug helper
LONGLONG GetSkippedFrameCount()
{
return m_NumFramesSkipped;
}
// Constructor
CHardwareSimulation (
_Inout_ CSensor *Sensor,
_In_ LONG PinID
);
// Destructor
virtual
~CHardwareSimulation ();
// Periodic interrupt handling
virtual
void
FakeHardware (
);
// Start streaming.
virtual
NTSTATUS
Start (
CSynthesizer *ImageSynth,
IN LONGLONG TimePerFrame,
IN ULONG Width,
IN ULONG Height,
IN ULONG ImageSize
);
// Pause streaming
virtual
NTSTATUS
Pause (
IN BOOLEAN Pausing
);
// Stop streaming.
virtual
NTSTATUS
Stop();
// Reset streaming.
virtual
NTSTATUS
Reset(
IN PKSPIN Pin
);
// Reset streaming.
virtual
NTSTATUS
Reset();
// Add a frame buffer to our queue.
virtual
ULONG
ProgramScatterGatherMappings (
IN PKSSTREAM_POINTER *Clone,
IN PUCHAR *Buffer,
IN PKSMAPPING Mappings,
IN ULONG MappingsCount,
IN ULONG MappingStride
);
// Initialization.
virtual
BOOLEAN
Initialize();
// Number of frames completed during this run.
ULONG
ReadNumberOfMappingsCompleted();
// Get the QPC measured in 100ns units.
ULONGLONG
ConvertQPCtoTimeStamp(
_In_opt_ PLARGE_INTEGER pQpcTime
);
// Get the current frame settings.
virtual
ISP_FRAME_SETTINGS *
GetIspSettings(void);
// So a photo sim can ask a preview sim for a confirmation frame.
NTSTATUS
GeneratePhotoConfirmation(
_In_ ULONG PfsFrameNumber,
_In_ LONGLONG time
);
// Get the exposure value for the current frame.
LONGLONG
GetCurrentExposureTime();
// Get the White balance for the current frame.
ULONG
GetCurrentWhiteBalance();
// Get the ISO Speed value for the current frame.
ULONG
GetCurrentISOSpeed();
// Get the Lens position for the current frame.
ULONG
GetCurrentLensPosition();
// Get the Scene Mode for the current frame.
ULONG
GetCurrentSceneMode();
// Translate Exposure Mode to an Exif Exposure Program value
USHORT
GetExposureProgram();
// Pin state accessor...
PIN_STATE
GetState()
{
return m_PinState;
}
friend class CHwSimTimer;
};
//
// Sets the timer using our callback and our parent CHardwareSimulation.
//
inline
BOOLEAN
CHwSimTimer::
Set(
_In_ LARGE_INTEGER DueTime
)
{
return KPassiveTimer::Set( DueTime, Handler, m_Parent );
}
|