summaryrefslogtreecommitdiff
path: root/avstream/avscamera/sys/hwsim.h
blob: b326702f2abb1acb7379b3b50bfaa400ceb2a9a7 (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
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 );
}