blob: 64c8667aa8062ea7bc242f6368d32105c83b55c3
1 | /* |
2 | * Copyright (C) 2012 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H |
18 | #define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H |
19 | |
20 | /* |
21 | * Contains declaration of a class EmulatedFakeCamera2 that encapsulates |
22 | * functionality of a fake camera that implements version 2 of the camera device |
23 | * interface. |
24 | */ |
25 | |
26 | #include "EmulatedCamera2.h" |
27 | #include "fake-pipeline2/Base.h" |
28 | #include "fake-pipeline2/Sensor.h" |
29 | #include "fake-pipeline2/JpegCompressor.h" |
30 | #include <utils/Condition.h> |
31 | #include <utils/KeyedVector.h> |
32 | #include <utils/String8.h> |
33 | #include <utils/String16.h> |
34 | |
35 | namespace android { |
36 | |
37 | /* Encapsulates functionality of an advanced fake camera. This camera contains |
38 | * a simple simulation of a scene, sensor, and image processing pipeline. |
39 | */ |
40 | class EmulatedFakeCamera2 : public EmulatedCamera2 { |
41 | public: |
42 | /* Constructs EmulatedFakeCamera instance. */ |
43 | EmulatedFakeCamera2(int cameraId, bool facingBack, struct hw_module_t* module); |
44 | |
45 | /* Destructs EmulatedFakeCamera instance. */ |
46 | ~EmulatedFakeCamera2(); |
47 | |
48 | /**************************************************************************** |
49 | * EmulatedCamera2 virtual overrides. |
50 | ***************************************************************************/ |
51 | |
52 | public: |
53 | /* Initializes EmulatedFakeCamera2 instance. */ |
54 | status_t Initialize(); |
55 | |
56 | /**************************************************************************** |
57 | * Camera Module API and generic hardware device API implementation |
58 | ***************************************************************************/ |
59 | public: |
60 | |
61 | virtual status_t connectCamera(hw_device_t** device); |
62 | |
63 | virtual status_t plugCamera(); |
64 | virtual status_t unplugCamera(); |
65 | virtual camera_device_status_t getHotplugStatus(); |
66 | |
67 | virtual status_t closeCamera(); |
68 | |
69 | virtual status_t getCameraInfo(struct camera_info *info); |
70 | |
71 | /**************************************************************************** |
72 | * EmulatedCamera2 abstract API implementation. |
73 | ***************************************************************************/ |
74 | protected: |
75 | /** Request input queue */ |
76 | |
77 | virtual int requestQueueNotify(); |
78 | |
79 | /** Count of requests in flight */ |
80 | virtual int getInProgressCount(); |
81 | |
82 | /** Cancel all captures in flight */ |
83 | //virtual int flushCapturesInProgress(); |
84 | |
85 | /** Construct default request */ |
86 | virtual int constructDefaultRequest( |
87 | int request_template, |
88 | camera_metadata_t **request); |
89 | |
90 | virtual int allocateStream( |
91 | uint32_t width, |
92 | uint32_t height, |
93 | int format, |
94 | const camera2_stream_ops_t *stream_ops, |
95 | uint32_t *stream_id, |
96 | uint32_t *format_actual, |
97 | uint32_t *usage, |
98 | uint32_t *max_buffers); |
99 | |
100 | virtual int registerStreamBuffers( |
101 | uint32_t stream_id, |
102 | int num_buffers, |
103 | buffer_handle_t *buffers); |
104 | |
105 | virtual int releaseStream(uint32_t stream_id); |
106 | |
107 | // virtual int allocateReprocessStream( |
108 | // uint32_t width, |
109 | // uint32_t height, |
110 | // uint32_t format, |
111 | // const camera2_stream_ops_t *stream_ops, |
112 | // uint32_t *stream_id, |
113 | // uint32_t *format_actual, |
114 | // uint32_t *usage, |
115 | // uint32_t *max_buffers); |
116 | |
117 | virtual int allocateReprocessStreamFromStream( |
118 | uint32_t output_stream_id, |
119 | const camera2_stream_in_ops_t *stream_ops, |
120 | uint32_t *stream_id); |
121 | |
122 | virtual int releaseReprocessStream(uint32_t stream_id); |
123 | |
124 | virtual int triggerAction(uint32_t trigger_id, |
125 | int32_t ext1, |
126 | int32_t ext2); |
127 | |
128 | /** Debug methods */ |
129 | |
130 | virtual int dump(int fd); |
131 | |
132 | public: |
133 | /**************************************************************************** |
134 | * Utility methods called by configure/readout threads and pipeline |
135 | ***************************************************************************/ |
136 | |
137 | // Get information about a given stream. Will lock mMutex |
138 | const Stream &getStreamInfo(uint32_t streamId); |
139 | const ReprocessStream &getReprocessStreamInfo(uint32_t streamId); |
140 | |
141 | // Notifies rest of camera subsystem of serious error |
142 | void signalError(); |
143 | |
144 | private: |
145 | /**************************************************************************** |
146 | * Utility methods |
147 | ***************************************************************************/ |
148 | /** Construct static camera metadata, two-pass */ |
149 | status_t constructStaticInfo( |
150 | camera_metadata_t **info, |
151 | bool sizeRequest) const; |
152 | |
153 | /** Two-pass implementation of constructDefaultRequest */ |
154 | status_t constructDefaultRequest( |
155 | int request_template, |
156 | camera_metadata_t **request, |
157 | bool sizeRequest) const; |
158 | /** Helper function for constructDefaultRequest */ |
159 | static status_t addOrSize( camera_metadata_t *request, |
160 | bool sizeRequest, |
161 | size_t *entryCount, |
162 | size_t *dataCount, |
163 | uint32_t tag, |
164 | const void *entry_data, |
165 | size_t entry_count); |
166 | |
167 | /** Determine if the stream id is listed in any currently-in-flight |
168 | * requests. Assumes mMutex is locked */ |
169 | bool isStreamInUse(uint32_t streamId); |
170 | |
171 | /** Determine if the reprocess stream id is listed in any |
172 | * currently-in-flight requests. Assumes mMutex is locked */ |
173 | bool isReprocessStreamInUse(uint32_t streamId); |
174 | |
175 | /**************************************************************************** |
176 | * Pipeline controller threads |
177 | ***************************************************************************/ |
178 | |
179 | class ConfigureThread: public Thread { |
180 | public: |
181 | ConfigureThread(EmulatedFakeCamera2 *parent); |
182 | ~ConfigureThread(); |
183 | |
184 | status_t waitUntilRunning(); |
185 | status_t newRequestAvailable(); |
186 | status_t readyToRun(); |
187 | |
188 | bool isStreamInUse(uint32_t id); |
189 | int getInProgressCount(); |
190 | private: |
191 | EmulatedFakeCamera2 *mParent; |
192 | static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms |
193 | |
194 | bool mRunning; |
195 | bool threadLoop(); |
196 | |
197 | bool setupCapture(); |
198 | bool setupReprocess(); |
199 | |
200 | bool configureNextCapture(); |
201 | bool configureNextReprocess(); |
202 | |
203 | bool getBuffers(); |
204 | |
205 | Mutex mInputMutex; // Protects mActive, mRequestCount |
206 | Condition mInputSignal; |
207 | bool mActive; // Whether we're waiting for input requests or actively |
208 | // working on them |
209 | size_t mRequestCount; |
210 | |
211 | camera_metadata_t *mRequest; |
212 | |
213 | Mutex mInternalsMutex; // Lock before accessing below members. |
214 | bool mWaitingForReadout; |
215 | bool mNextNeedsJpeg; |
216 | bool mNextIsCapture; |
217 | int32_t mNextFrameNumber; |
218 | int64_t mNextExposureTime; |
219 | int64_t mNextFrameDuration; |
220 | int32_t mNextSensitivity; |
221 | Buffers *mNextBuffers; |
222 | }; |
223 | |
224 | class ReadoutThread: public Thread, private JpegCompressor::JpegListener { |
225 | public: |
226 | ReadoutThread(EmulatedFakeCamera2 *parent); |
227 | ~ReadoutThread(); |
228 | |
229 | status_t readyToRun(); |
230 | |
231 | // Input |
232 | status_t waitUntilRunning(); |
233 | bool waitForReady(nsecs_t timeout); |
234 | void setNextOperation(bool isCapture, |
235 | camera_metadata_t *request, |
236 | Buffers *buffers); |
237 | bool isStreamInUse(uint32_t id); |
238 | int getInProgressCount(); |
239 | private: |
240 | EmulatedFakeCamera2 *mParent; |
241 | |
242 | bool mRunning; |
243 | bool threadLoop(); |
244 | |
245 | bool readyForNextCapture(); |
246 | status_t collectStatisticsMetadata(camera_metadata_t *frame); |
247 | |
248 | // Inputs |
249 | Mutex mInputMutex; // Protects mActive, mInFlightQueue, mRequestCount |
250 | Condition mInputSignal; |
251 | Condition mReadySignal; |
252 | |
253 | bool mActive; |
254 | |
255 | static const int kInFlightQueueSize = 4; |
256 | struct InFlightQueue { |
257 | bool isCapture; |
258 | camera_metadata_t *request; |
259 | Buffers *buffers; |
260 | } *mInFlightQueue; |
261 | |
262 | size_t mInFlightHead; |
263 | size_t mInFlightTail; |
264 | |
265 | size_t mRequestCount; |
266 | |
267 | // Internals |
268 | Mutex mInternalsMutex; |
269 | |
270 | bool mIsCapture; |
271 | camera_metadata_t *mRequest; |
272 | Buffers *mBuffers; |
273 | |
274 | // Jpeg completion listeners |
275 | void onJpegDone(const StreamBuffer &jpegBuffer, bool success); |
276 | void onJpegInputDone(const StreamBuffer &inputBuffer); |
277 | nsecs_t mJpegTimestamp; |
278 | }; |
279 | |
280 | // 3A management thread (auto-exposure, focus, white balance) |
281 | class ControlThread: public Thread { |
282 | public: |
283 | ControlThread(EmulatedFakeCamera2 *parent); |
284 | ~ControlThread(); |
285 | |
286 | status_t readyToRun(); |
287 | |
288 | status_t waitUntilRunning(); |
289 | |
290 | // Interpret request's control parameters and override |
291 | // capture settings as needed |
292 | status_t processRequest(camera_metadata_t *request); |
293 | |
294 | status_t triggerAction(uint32_t msgType, |
295 | int32_t ext1, int32_t ext2); |
296 | private: |
297 | ControlThread(const ControlThread &t); |
298 | ControlThread& operator=(const ControlThread &t); |
299 | |
300 | // Constants controlling fake 3A behavior |
301 | static const nsecs_t kControlCycleDelay; |
302 | static const nsecs_t kMinAfDuration; |
303 | static const nsecs_t kMaxAfDuration; |
304 | static const float kAfSuccessRate; |
305 | static const float kContinuousAfStartRate; |
306 | |
307 | static const float kAeScanStartRate; |
308 | static const nsecs_t kMinAeDuration; |
309 | static const nsecs_t kMaxAeDuration; |
310 | static const nsecs_t kMinPrecaptureAeDuration; |
311 | static const nsecs_t kMaxPrecaptureAeDuration; |
312 | |
313 | static const nsecs_t kNormalExposureTime; |
314 | static const nsecs_t kExposureJump; |
315 | static const nsecs_t kMinExposureTime; |
316 | |
317 | EmulatedFakeCamera2 *mParent; |
318 | |
319 | bool mRunning; |
320 | bool threadLoop(); |
321 | |
322 | Mutex mInputMutex; // Protects input methods |
323 | Condition mInputSignal; |
324 | |
325 | // Trigger notifications |
326 | bool mStartAf; |
327 | bool mCancelAf; |
328 | bool mStartPrecapture; |
329 | |
330 | // Latest state for 3A request fields |
331 | uint8_t mControlMode; |
332 | |
333 | uint8_t mEffectMode; |
334 | uint8_t mSceneMode; |
335 | |
336 | uint8_t mAfMode; |
337 | bool mAfModeChange; |
338 | |
339 | uint8_t mAwbMode; |
340 | uint8_t mAeMode; |
341 | |
342 | // Latest trigger IDs |
343 | int32_t mAfTriggerId; |
344 | int32_t mPrecaptureTriggerId; |
345 | |
346 | // Current state for 3A algorithms |
347 | uint8_t mAfState; |
348 | uint8_t mAeState; |
349 | uint8_t mAwbState; |
350 | bool mAeLock; |
351 | |
352 | // Current control parameters |
353 | nsecs_t mExposureTime; |
354 | |
355 | // Private to threadLoop and its utility methods |
356 | |
357 | nsecs_t mAfScanDuration; |
358 | nsecs_t mAeScanDuration; |
359 | bool mLockAfterPassiveScan; |
360 | |
361 | // Utility methods for AF |
362 | int processAfTrigger(uint8_t afMode, uint8_t afState); |
363 | int maybeStartAfScan(uint8_t afMode, uint8_t afState); |
364 | int updateAfScan(uint8_t afMode, uint8_t afState, nsecs_t *maxSleep); |
365 | void updateAfState(uint8_t newState, int32_t triggerId); |
366 | |
367 | // Utility methods for precapture trigger |
368 | int processPrecaptureTrigger(uint8_t aeMode, uint8_t aeState); |
369 | int maybeStartAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState); |
370 | int updateAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState, |
371 | nsecs_t *maxSleep); |
372 | void updateAeState(uint8_t newState, int32_t triggerId); |
373 | }; |
374 | |
375 | /**************************************************************************** |
376 | * Static configuration information |
377 | ***************************************************************************/ |
378 | private: |
379 | static const uint32_t kMaxRawStreamCount = 1; |
380 | static const uint32_t kMaxProcessedStreamCount = 3; |
381 | static const uint32_t kMaxJpegStreamCount = 1; |
382 | static const uint32_t kMaxReprocessStreamCount = 2; |
383 | static const uint32_t kMaxBufferCount = 4; |
384 | static const uint32_t kAvailableFormats[]; |
385 | static const uint32_t kAvailableRawSizes[]; |
386 | static const uint64_t kAvailableRawMinDurations[]; |
387 | static const uint32_t kAvailableProcessedSizesBack[]; |
388 | static const uint32_t kAvailableProcessedSizesFront[]; |
389 | static const uint64_t kAvailableProcessedMinDurations[]; |
390 | static const uint32_t kAvailableJpegSizesBack[]; |
391 | static const uint32_t kAvailableJpegSizesFront[]; |
392 | static const uint64_t kAvailableJpegMinDurations[]; |
393 | |
394 | /**************************************************************************** |
395 | * Data members. |
396 | ***************************************************************************/ |
397 | |
398 | protected: |
399 | /* Facing back (true) or front (false) switch. */ |
400 | bool mFacingBack; |
401 | |
402 | private: |
403 | bool mIsConnected; |
404 | |
405 | /** Stream manipulation */ |
406 | uint32_t mNextStreamId; |
407 | uint32_t mRawStreamCount; |
408 | uint32_t mProcessedStreamCount; |
409 | uint32_t mJpegStreamCount; |
410 | |
411 | uint32_t mNextReprocessStreamId; |
412 | uint32_t mReprocessStreamCount; |
413 | |
414 | KeyedVector<uint32_t, Stream> mStreams; |
415 | KeyedVector<uint32_t, ReprocessStream> mReprocessStreams; |
416 | |
417 | /** Simulated hardware interfaces */ |
418 | sp<Sensor> mSensor; |
419 | sp<JpegCompressor> mJpegCompressor; |
420 | |
421 | /** Pipeline control threads */ |
422 | sp<ConfigureThread> mConfigureThread; |
423 | sp<ReadoutThread> mReadoutThread; |
424 | sp<ControlThread> mControlThread; |
425 | }; |
426 | |
427 | }; /* namespace android */ |
428 | |
429 | #endif /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H */ |
430 |