blob: fe4abc0e44c08bec09a8f3d565a38e37dbcbdae8 [file] [log] [blame]
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001/*
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
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070017#define LOG_TAG "Camera2-CaptureSequencer"
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Trace.h>
23#include <utils/Vector.h>
24
25#include "CaptureSequencer.h"
James Painterc3dbf1a2012-09-05 18:02:32 -070026#include "BurstCapture.h"
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070027#include "../Camera2Device.h"
28#include "../Camera2Client.h"
29#include "Parameters.h"
30
31namespace android {
32namespace camera2 {
33
34/** Public members */
35
36CaptureSequencer::CaptureSequencer(wp<Camera2Client> client):
37 Thread(false),
38 mStartCapture(false),
39 mBusy(false),
40 mNewAEState(false),
41 mNewFrameReceived(false),
42 mNewCaptureReceived(false),
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -070043 mShutterNotified(false),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070044 mClient(client),
45 mCaptureState(IDLE),
46 mTriggerId(0),
47 mTimeoutCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -070048 mCaptureId(Camera2Client::kCaptureRequestIdStart) {
James Painterc3dbf1a2012-09-05 18:02:32 -070049 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070050}
51
52CaptureSequencer::~CaptureSequencer() {
53 ALOGV("%s: Exit", __FUNCTION__);
54}
55
56void CaptureSequencer::setZslProcessor(wp<ZslProcessor> processor) {
57 Mutex::Autolock l(mInputMutex);
58 mZslProcessor = processor;
59}
60
61status_t CaptureSequencer::startCapture() {
James Painterc3dbf1a2012-09-05 18:02:32 -070062 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070063 ATRACE_CALL();
64 Mutex::Autolock l(mInputMutex);
65 if (mBusy) {
66 ALOGE("%s: Already busy capturing!", __FUNCTION__);
67 return INVALID_OPERATION;
68 }
69 if (!mStartCapture) {
70 mStartCapture = true;
71 mStartCaptureSignal.signal();
72 }
73 return OK;
74}
75
Eino-Ville Talvalae0493842012-10-05 12:03:10 -070076status_t CaptureSequencer::waitUntilIdle(nsecs_t timeout) {
77 ATRACE_CALL();
78 ALOGV("%s: Waiting for idle", __FUNCTION__);
79 Mutex::Autolock l(mStateMutex);
80 status_t res = -1;
81 while (mCaptureState != IDLE) {
82 nsecs_t startTime = systemTime();
83
84 res = mStateChanged.waitRelative(mStateMutex, timeout);
85 if (res != OK) return res;
86
87 timeout -= (systemTime() - startTime);
88 }
89 ALOGV("%s: Now idle", __FUNCTION__);
90 return OK;
91}
92
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070093void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
94 ATRACE_CALL();
95 Mutex::Autolock l(mInputMutex);
96 mAEState = newState;
97 mAETriggerId = triggerId;
98 if (!mNewAEState) {
99 mNewAEState = true;
100 mNewNotifySignal.signal();
101 }
102}
103
104void CaptureSequencer::onFrameAvailable(int32_t frameId,
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700105 const CameraMetadata &frame) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700106 ALOGV("%s: Listener found new frame", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700107 ATRACE_CALL();
108 Mutex::Autolock l(mInputMutex);
109 mNewFrameId = frameId;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700110 mNewFrame = frame;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700111 if (!mNewFrameReceived) {
112 mNewFrameReceived = true;
113 mNewFrameSignal.signal();
114 }
115}
116
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700117void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
118 sp<MemoryBase> captureBuffer) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700119 ATRACE_CALL();
James Painterc3dbf1a2012-09-05 18:02:32 -0700120 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700121 Mutex::Autolock l(mInputMutex);
122 mCaptureTimestamp = timestamp;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700123 mCaptureBuffer = captureBuffer;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700124 if (!mNewCaptureReceived) {
125 mNewCaptureReceived = true;
126 mNewCaptureSignal.signal();
127 }
128}
129
130
131void CaptureSequencer::dump(int fd, const Vector<String16>& args) {
132 String8 result;
133 if (mCaptureRequest.entryCount() != 0) {
134 result = " Capture request:\n";
135 write(fd, result.string(), result.size());
136 mCaptureRequest.dump(fd, 2, 6);
137 } else {
138 result = " Capture request: undefined\n";
139 write(fd, result.string(), result.size());
140 }
141 result = String8::format(" Current capture state: %s\n",
142 kStateNames[mCaptureState]);
143 result.append(" Latest captured frame:\n");
144 write(fd, result.string(), result.size());
145 mNewFrame.dump(fd, 2, 6);
146}
147
148/** Private members */
149
150const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
151{
152 "IDLE",
153 "START",
154 "ZSL_START",
155 "ZSL_WAITING",
156 "ZSL_REPROCESSING",
157 "STANDARD_START",
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700158 "STANDARD_PRECAPTURE_WAIT",
159 "STANDARD_CAPTURE",
160 "STANDARD_CAPTURE_WAIT",
James Painterc3dbf1a2012-09-05 18:02:32 -0700161 "BURST_CAPTURE_START",
162 "BURST_CAPTURE_WAIT",
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700163 "DONE",
164 "ERROR",
165 "UNKNOWN"
166};
167
168const CaptureSequencer::StateManager
169 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
170 &CaptureSequencer::manageIdle,
171 &CaptureSequencer::manageStart,
172 &CaptureSequencer::manageZslStart,
173 &CaptureSequencer::manageZslWaiting,
174 &CaptureSequencer::manageZslReprocessing,
175 &CaptureSequencer::manageStandardStart,
176 &CaptureSequencer::manageStandardPrecaptureWait,
177 &CaptureSequencer::manageStandardCapture,
178 &CaptureSequencer::manageStandardCaptureWait,
James Painterc3dbf1a2012-09-05 18:02:32 -0700179 &CaptureSequencer::manageBurstCaptureStart,
180 &CaptureSequencer::manageBurstCaptureWait,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700181 &CaptureSequencer::manageDone,
182};
183
184bool CaptureSequencer::threadLoop() {
185 status_t res;
186
187 sp<Camera2Client> client = mClient.promote();
188 if (client == 0) return false;
189
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700190 CaptureState currentState;
191 {
192 Mutex::Autolock l(mStateMutex);
193 currentState = mCaptureState;
194 }
195
196 currentState = (this->*kStateManagers[currentState])(client);
197
198 Mutex::Autolock l(mStateMutex);
199 if (currentState != mCaptureState) {
200 mCaptureState = currentState;
201 ATRACE_INT("cam2_capt_state", mCaptureState);
202 ALOGV("Camera %d: New capture state %s",
203 client->getCameraId(), kStateNames[mCaptureState]);
204 mStateChanged.signal();
205 }
206
207 if (mCaptureState == ERROR) {
208 ALOGE("Camera %d: Stopping capture sequencer due to error",
209 client->getCameraId());
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700210 return false;
211 }
212
213 return true;
214}
215
216CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
217 status_t res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700218 Mutex::Autolock l(mInputMutex);
219 while (!mStartCapture) {
220 res = mStartCaptureSignal.waitRelative(mInputMutex,
221 kWaitDuration);
222 if (res == TIMED_OUT) break;
223 }
224 if (mStartCapture) {
225 mStartCapture = false;
226 mBusy = true;
227 return START;
228 }
229 return IDLE;
230}
231
232CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700233 status_t res = OK;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700234 ATRACE_CALL();
235 mCaptureId++;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700236 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
237 mCaptureId = Camera2Client::kCaptureRequestIdStart;
238 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700239 {
240 Mutex::Autolock l(mInputMutex);
241 mBusy = false;
242 }
243
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700244 {
245 SharedParameters::Lock l(client->getParameters());
246 switch (l.mParameters.state) {
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700247 case Parameters::DISCONNECTED:
248 ALOGW("%s: Camera %d: Discarding image data during shutdown ",
249 __FUNCTION__, client->getCameraId());
250 res = INVALID_OPERATION;
251 break;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700252 case Parameters::STILL_CAPTURE:
253 l.mParameters.state = Parameters::STOPPED;
254 break;
255 case Parameters::VIDEO_SNAPSHOT:
256 l.mParameters.state = Parameters::RECORD;
257 break;
258 default:
259 ALOGE("%s: Camera %d: Still image produced unexpectedly "
260 "in state %s!",
261 __FUNCTION__, client->getCameraId(),
262 Parameters::getStateName(l.mParameters.state));
263 res = INVALID_OPERATION;
264 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700265 }
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700266 sp<ZslProcessor> processor = mZslProcessor.promote();
267 if (processor != 0) {
268 processor->clearZslQueue();
269 }
270
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700271 if (mCaptureBuffer != 0 && res == OK) {
272 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
273 ALOGV("%s: Sending still image to client", __FUNCTION__);
274 if (l.mCameraClient != 0) {
275 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
276 mCaptureBuffer, NULL);
277 } else {
278 ALOGV("%s: No client!", __FUNCTION__);
279 }
280 }
281 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700282
283 return IDLE;
284}
285
286CaptureSequencer::CaptureState CaptureSequencer::manageStart(
287 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700288 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700289 status_t res;
290 ATRACE_CALL();
291 SharedParameters::Lock l(client->getParameters());
292 CaptureState nextState = DONE;
293
294 res = updateCaptureRequest(l.mParameters, client);
295 if (res != OK ) {
296 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
297 __FUNCTION__, client->getCameraId(), strerror(-res), res);
298 return DONE;
299 }
300
James Painterc3dbf1a2012-09-05 18:02:32 -0700301 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
302 l.mParameters.state == Parameters::STILL_CAPTURE) {
303 nextState = BURST_CAPTURE_START;
304 }
305 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700306 l.mParameters.state == Parameters::STILL_CAPTURE &&
307 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700308 nextState = ZSL_START;
309 } else {
310 nextState = STANDARD_START;
311 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700312 mShutterNotified = false;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700313
314 return nextState;
315}
316
317CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
318 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700319 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700320 status_t res;
321 sp<ZslProcessor> processor = mZslProcessor.promote();
322 if (processor == 0) {
323 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
324 return DONE;
325 }
326
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700327 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700328 this);
329
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700330 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700331 res = processor->pushToReprocess(mCaptureId);
332 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700333 if (res == NOT_ENOUGH_DATA) {
334 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
335 "falling back to normal capture", __FUNCTION__,
336 client->getCameraId());
337 } else {
338 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
339 __FUNCTION__, client->getCameraId(), strerror(-res), res);
340 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700341 return STANDARD_START;
342 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700343
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700344 SharedParameters::Lock l(client->getParameters());
Igor Murashkin707c3e32012-09-20 15:18:50 -0700345 /* warning: this also locks a SharedCameraClient */
346 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700347 mShutterNotified = true;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700348 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
349 return STANDARD_CAPTURE_WAIT;
350}
351
352CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
353 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700354 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700355 return DONE;
356}
357
358CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
359 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700360 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700361 return START;
362}
363
364CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
365 sp<Camera2Client> &client) {
366 ATRACE_CALL();
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700367 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700368 this);
369 {
370 SharedParameters::Lock l(client->getParameters());
371 mTriggerId = l.mParameters.precaptureTriggerCounter++;
372 }
373 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
374
375 mAeInPrecapture = false;
376 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
377 return STANDARD_PRECAPTURE_WAIT;
378}
379
380CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
381 sp<Camera2Client> &client) {
382 status_t res;
383 ATRACE_CALL();
384 Mutex::Autolock l(mInputMutex);
385 while (!mNewAEState) {
386 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
387 if (res == TIMED_OUT) {
388 mTimeoutCount--;
389 break;
390 }
391 }
392 if (mTimeoutCount <= 0) {
393 ALOGW("Timed out waiting for precapture %s",
394 mAeInPrecapture ? "end" : "start");
395 return STANDARD_CAPTURE;
396 }
397 if (mNewAEState) {
398 if (!mAeInPrecapture) {
399 // Waiting to see PRECAPTURE state
400 if (mAETriggerId == mTriggerId &&
401 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
402 ALOGV("%s: Got precapture start", __FUNCTION__);
403 mAeInPrecapture = true;
404 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
405 }
406 } else {
407 // Waiting to see PRECAPTURE state end
408 if (mAETriggerId == mTriggerId &&
409 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
410 ALOGV("%s: Got precapture end", __FUNCTION__);
411 return STANDARD_CAPTURE;
412 }
413 }
414 mNewAEState = false;
415 }
416 return STANDARD_PRECAPTURE_WAIT;
417}
418
419CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
420 sp<Camera2Client> &client) {
421 status_t res;
422 ATRACE_CALL();
423 SharedParameters::Lock l(client->getParameters());
424 Vector<uint8_t> outputStreams;
425
426 outputStreams.push(client->getPreviewStreamId());
427 outputStreams.push(client->getCaptureStreamId());
428
429 if (l.mParameters.previewCallbackFlags &
430 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
431 outputStreams.push(client->getCallbackStreamId());
432 }
433
434 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
435 outputStreams.push(client->getRecordingStreamId());
436 }
437
438 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
439 outputStreams);
440 if (res == OK) {
441 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
442 &mCaptureId, 1);
443 }
444 if (res == OK) {
445 res = mCaptureRequest.sort();
446 }
447
448 if (res != OK) {
449 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
450 __FUNCTION__, client->getCameraId(), strerror(-res), res);
451 return DONE;
452 }
453
454 CameraMetadata captureCopy = mCaptureRequest;
455 if (captureCopy.entryCount() == 0) {
456 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
457 __FUNCTION__, client->getCameraId());
458 return DONE;
459 }
460
461 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700462 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700463 if (res != OK) {
464 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
465 "%s (%d)",
466 __FUNCTION__, client->getCameraId(), strerror(-res), res);
467 return DONE;
468 }
469 }
470 // TODO: Capture should be atomic with setStreamingRequest here
471 res = client->getCameraDevice()->capture(captureCopy);
472 if (res != OK) {
473 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
474 "%s (%d)",
475 __FUNCTION__, client->getCameraId(), strerror(-res), res);
476 return DONE;
477 }
478
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700479 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
480 return STANDARD_CAPTURE_WAIT;
481}
482
483CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
484 sp<Camera2Client> &client) {
485 status_t res;
486 ATRACE_CALL();
487 Mutex::Autolock l(mInputMutex);
488 while (!mNewFrameReceived) {
489 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
490 if (res == TIMED_OUT) {
491 mTimeoutCount--;
492 break;
493 }
494 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700495 if (mNewFrameReceived && !mShutterNotified) {
496 SharedParameters::Lock l(client->getParameters());
497 /* warning: this also locks a SharedCameraClient */
498 shutterNotifyLocked(l.mParameters, client);
499 mShutterNotified = true;
500 }
501 while (mNewFrameReceived && !mNewCaptureReceived) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700502 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
503 if (res == TIMED_OUT) {
504 mTimeoutCount--;
505 break;
506 }
507 }
508 if (mTimeoutCount <= 0) {
509 ALOGW("Timed out waiting for capture to complete");
510 return DONE;
511 }
512 if (mNewFrameReceived && mNewCaptureReceived) {
513 if (mNewFrameId != mCaptureId) {
514 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
515 mCaptureId, mNewFrameId);
516 }
517 camera_metadata_entry_t entry;
518 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
519 if (entry.count == 0) {
520 ALOGE("No timestamp field in capture frame!");
521 }
522 if (entry.data.i64[0] != mCaptureTimestamp) {
523 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
524 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
525 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700526 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700527
528 mNewFrameReceived = false;
529 mNewCaptureReceived = false;
530 return DONE;
531 }
532 return STANDARD_CAPTURE_WAIT;
533}
534
James Painterc3dbf1a2012-09-05 18:02:32 -0700535CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
536 sp<Camera2Client> &client) {
537 ALOGV("%s", __FUNCTION__);
538 status_t res;
539 ATRACE_CALL();
540
541 // check which burst mode is set, create respective burst object
542 {
543 SharedParameters::Lock l(client->getParameters());
544
545 res = updateCaptureRequest(l.mParameters, client);
546 if(res != OK) {
547 return DONE;
548 }
549
550 //
551 // check for burst mode type in mParameters here
552 //
553 mBurstCapture = new BurstCapture(client, this);
554 }
555
556 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
557 if (res == OK) {
558 res = mCaptureRequest.sort();
559 }
560 if (res != OK) {
561 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
562 __FUNCTION__, client->getCameraId(), strerror(-res), res);
563 return DONE;
564 }
565
566 CameraMetadata captureCopy = mCaptureRequest;
567 if (captureCopy.entryCount() == 0) {
568 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
569 __FUNCTION__, client->getCameraId());
570 return DONE;
571 }
572
573 Vector<CameraMetadata> requests;
574 requests.push(mCaptureRequest);
575 res = mBurstCapture->start(requests, mCaptureId);
576 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
577 return BURST_CAPTURE_WAIT;
578}
579
580CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
581 sp<Camera2Client> &client) {
582 status_t res;
583 ATRACE_CALL();
584
585 while (!mNewCaptureReceived) {
586 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
587 if (res == TIMED_OUT) {
588 mTimeoutCount--;
589 break;
590 }
591 }
592
593 if (mTimeoutCount <= 0) {
594 ALOGW("Timed out waiting for burst capture to complete");
595 return DONE;
596 }
597 if (mNewCaptureReceived) {
598 mNewCaptureReceived = false;
599 // TODO: update mCaptureId to last burst's capture ID + 1?
600 return DONE;
601 }
602
603 return BURST_CAPTURE_WAIT;
604}
605
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700606status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
607 sp<Camera2Client> &client) {
608 ATRACE_CALL();
609 status_t res;
610 if (mCaptureRequest.entryCount() == 0) {
611 res = client->getCameraDevice()->createDefaultRequest(
612 CAMERA2_TEMPLATE_STILL_CAPTURE,
613 &mCaptureRequest);
614 if (res != OK) {
615 ALOGE("%s: Camera %d: Unable to create default still image request:"
616 " %s (%d)", __FUNCTION__, client->getCameraId(),
617 strerror(-res), res);
618 return res;
619 }
620 }
621
622 res = params.updateRequest(&mCaptureRequest);
623 if (res != OK) {
624 ALOGE("%s: Camera %d: Unable to update common entries of capture "
625 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
626 strerror(-res), res);
627 return res;
628 }
629
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700630 res = params.updateRequestJpeg(&mCaptureRequest);
631 if (res != OK) {
632 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
633 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
634 strerror(-res), res);
635 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700636 }
637
638 return OK;
639}
640
Igor Murashkin707c3e32012-09-20 15:18:50 -0700641/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
642 sp<Camera2Client> client) {
643 ATRACE_CALL();
644
645 if (params.state == Parameters::STILL_CAPTURE && params.playShutterSound) {
646 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
647 }
648
649 {
650 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
651
652 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
653 if (l.mCameraClient != 0) {
654 // ShutterCallback
655 l.mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER,
656 /*ext1*/0, /*ext2*/0);
657
658 // RawCallback with null buffer
659 l.mCameraClient->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
660 /*ext1*/0, /*ext2*/0);
661 } else {
662 ALOGV("%s: No client!", __FUNCTION__);
663 }
664 }
665}
666
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700667
668}; // namespace camera2
669}; // namespace android