blob: 072453b05bbfe8d4cbcb43716c6a8e52d59f84fd [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),
Igor Murashkin786a8da2012-11-26 10:50:55 -080048 mCaptureId(Camera2Client::kCaptureRequestIdStart),
49 mMsgType(0) {
James Painterc3dbf1a2012-09-05 18:02:32 -070050 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070051}
52
53CaptureSequencer::~CaptureSequencer() {
54 ALOGV("%s: Exit", __FUNCTION__);
55}
56
57void CaptureSequencer::setZslProcessor(wp<ZslProcessor> processor) {
58 Mutex::Autolock l(mInputMutex);
59 mZslProcessor = processor;
60}
61
Igor Murashkin786a8da2012-11-26 10:50:55 -080062status_t CaptureSequencer::startCapture(int msgType) {
James Painterc3dbf1a2012-09-05 18:02:32 -070063 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070064 ATRACE_CALL();
65 Mutex::Autolock l(mInputMutex);
66 if (mBusy) {
67 ALOGE("%s: Already busy capturing!", __FUNCTION__);
68 return INVALID_OPERATION;
69 }
70 if (!mStartCapture) {
Igor Murashkin786a8da2012-11-26 10:50:55 -080071 mMsgType = msgType;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070072 mStartCapture = true;
73 mStartCaptureSignal.signal();
74 }
75 return OK;
76}
77
Eino-Ville Talvalae0493842012-10-05 12:03:10 -070078status_t CaptureSequencer::waitUntilIdle(nsecs_t timeout) {
79 ATRACE_CALL();
80 ALOGV("%s: Waiting for idle", __FUNCTION__);
81 Mutex::Autolock l(mStateMutex);
82 status_t res = -1;
83 while (mCaptureState != IDLE) {
84 nsecs_t startTime = systemTime();
85
86 res = mStateChanged.waitRelative(mStateMutex, timeout);
87 if (res != OK) return res;
88
89 timeout -= (systemTime() - startTime);
90 }
91 ALOGV("%s: Now idle", __FUNCTION__);
92 return OK;
93}
94
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070095void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
96 ATRACE_CALL();
97 Mutex::Autolock l(mInputMutex);
98 mAEState = newState;
99 mAETriggerId = triggerId;
100 if (!mNewAEState) {
101 mNewAEState = true;
102 mNewNotifySignal.signal();
103 }
104}
105
106void CaptureSequencer::onFrameAvailable(int32_t frameId,
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700107 const CameraMetadata &frame) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700108 ALOGV("%s: Listener found new frame", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700109 ATRACE_CALL();
110 Mutex::Autolock l(mInputMutex);
111 mNewFrameId = frameId;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700112 mNewFrame = frame;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700113 if (!mNewFrameReceived) {
114 mNewFrameReceived = true;
115 mNewFrameSignal.signal();
116 }
117}
118
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700119void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
120 sp<MemoryBase> captureBuffer) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700121 ATRACE_CALL();
James Painterc3dbf1a2012-09-05 18:02:32 -0700122 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700123 Mutex::Autolock l(mInputMutex);
124 mCaptureTimestamp = timestamp;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700125 mCaptureBuffer = captureBuffer;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700126 if (!mNewCaptureReceived) {
127 mNewCaptureReceived = true;
128 mNewCaptureSignal.signal();
129 }
130}
131
132
133void CaptureSequencer::dump(int fd, const Vector<String16>& args) {
134 String8 result;
135 if (mCaptureRequest.entryCount() != 0) {
136 result = " Capture request:\n";
137 write(fd, result.string(), result.size());
138 mCaptureRequest.dump(fd, 2, 6);
139 } else {
140 result = " Capture request: undefined\n";
141 write(fd, result.string(), result.size());
142 }
143 result = String8::format(" Current capture state: %s\n",
144 kStateNames[mCaptureState]);
145 result.append(" Latest captured frame:\n");
146 write(fd, result.string(), result.size());
147 mNewFrame.dump(fd, 2, 6);
148}
149
150/** Private members */
151
152const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
153{
154 "IDLE",
155 "START",
156 "ZSL_START",
157 "ZSL_WAITING",
158 "ZSL_REPROCESSING",
159 "STANDARD_START",
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700160 "STANDARD_PRECAPTURE_WAIT",
161 "STANDARD_CAPTURE",
162 "STANDARD_CAPTURE_WAIT",
James Painterc3dbf1a2012-09-05 18:02:32 -0700163 "BURST_CAPTURE_START",
164 "BURST_CAPTURE_WAIT",
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700165 "DONE",
166 "ERROR",
167 "UNKNOWN"
168};
169
170const CaptureSequencer::StateManager
171 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
172 &CaptureSequencer::manageIdle,
173 &CaptureSequencer::manageStart,
174 &CaptureSequencer::manageZslStart,
175 &CaptureSequencer::manageZslWaiting,
176 &CaptureSequencer::manageZslReprocessing,
177 &CaptureSequencer::manageStandardStart,
178 &CaptureSequencer::manageStandardPrecaptureWait,
179 &CaptureSequencer::manageStandardCapture,
180 &CaptureSequencer::manageStandardCaptureWait,
James Painterc3dbf1a2012-09-05 18:02:32 -0700181 &CaptureSequencer::manageBurstCaptureStart,
182 &CaptureSequencer::manageBurstCaptureWait,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700183 &CaptureSequencer::manageDone,
184};
185
186bool CaptureSequencer::threadLoop() {
187 status_t res;
188
189 sp<Camera2Client> client = mClient.promote();
190 if (client == 0) return false;
191
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700192 CaptureState currentState;
193 {
194 Mutex::Autolock l(mStateMutex);
195 currentState = mCaptureState;
196 }
197
198 currentState = (this->*kStateManagers[currentState])(client);
199
200 Mutex::Autolock l(mStateMutex);
201 if (currentState != mCaptureState) {
202 mCaptureState = currentState;
203 ATRACE_INT("cam2_capt_state", mCaptureState);
204 ALOGV("Camera %d: New capture state %s",
205 client->getCameraId(), kStateNames[mCaptureState]);
206 mStateChanged.signal();
207 }
208
209 if (mCaptureState == ERROR) {
210 ALOGE("Camera %d: Stopping capture sequencer due to error",
211 client->getCameraId());
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700212 return false;
213 }
214
215 return true;
216}
217
218CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
219 status_t res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700220 Mutex::Autolock l(mInputMutex);
221 while (!mStartCapture) {
222 res = mStartCaptureSignal.waitRelative(mInputMutex,
223 kWaitDuration);
224 if (res == TIMED_OUT) break;
225 }
226 if (mStartCapture) {
227 mStartCapture = false;
228 mBusy = true;
229 return START;
230 }
231 return IDLE;
232}
233
234CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700235 status_t res = OK;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700236 ATRACE_CALL();
237 mCaptureId++;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700238 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
239 mCaptureId = Camera2Client::kCaptureRequestIdStart;
240 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700241 {
242 Mutex::Autolock l(mInputMutex);
243 mBusy = false;
244 }
245
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700246 {
247 SharedParameters::Lock l(client->getParameters());
248 switch (l.mParameters.state) {
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700249 case Parameters::DISCONNECTED:
250 ALOGW("%s: Camera %d: Discarding image data during shutdown ",
251 __FUNCTION__, client->getCameraId());
252 res = INVALID_OPERATION;
253 break;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700254 case Parameters::STILL_CAPTURE:
255 l.mParameters.state = Parameters::STOPPED;
256 break;
257 case Parameters::VIDEO_SNAPSHOT:
258 l.mParameters.state = Parameters::RECORD;
259 break;
260 default:
261 ALOGE("%s: Camera %d: Still image produced unexpectedly "
262 "in state %s!",
263 __FUNCTION__, client->getCameraId(),
264 Parameters::getStateName(l.mParameters.state));
265 res = INVALID_OPERATION;
266 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700267 }
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700268 sp<ZslProcessor> processor = mZslProcessor.promote();
269 if (processor != 0) {
270 processor->clearZslQueue();
271 }
272
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700273 if (mCaptureBuffer != 0 && res == OK) {
274 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
275 ALOGV("%s: Sending still image to client", __FUNCTION__);
276 if (l.mCameraClient != 0) {
277 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
278 mCaptureBuffer, NULL);
279 } else {
280 ALOGV("%s: No client!", __FUNCTION__);
281 }
282 }
283 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700284
285 return IDLE;
286}
287
288CaptureSequencer::CaptureState CaptureSequencer::manageStart(
289 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700290 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700291 status_t res;
292 ATRACE_CALL();
293 SharedParameters::Lock l(client->getParameters());
294 CaptureState nextState = DONE;
295
296 res = updateCaptureRequest(l.mParameters, client);
297 if (res != OK ) {
298 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
299 __FUNCTION__, client->getCameraId(), strerror(-res), res);
300 return DONE;
301 }
302
James Painterc3dbf1a2012-09-05 18:02:32 -0700303 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
304 l.mParameters.state == Parameters::STILL_CAPTURE) {
305 nextState = BURST_CAPTURE_START;
306 }
307 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700308 l.mParameters.state == Parameters::STILL_CAPTURE &&
309 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700310 nextState = ZSL_START;
311 } else {
312 nextState = STANDARD_START;
313 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700314 mShutterNotified = false;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700315
316 return nextState;
317}
318
319CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
320 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700321 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700322 status_t res;
323 sp<ZslProcessor> processor = mZslProcessor.promote();
324 if (processor == 0) {
325 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
326 return DONE;
327 }
328
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700329 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700330 this);
331
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700332 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700333 res = processor->pushToReprocess(mCaptureId);
334 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700335 if (res == NOT_ENOUGH_DATA) {
336 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
337 "falling back to normal capture", __FUNCTION__,
338 client->getCameraId());
339 } else {
340 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
341 __FUNCTION__, client->getCameraId(), strerror(-res), res);
342 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700343 return STANDARD_START;
344 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700345
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700346 SharedParameters::Lock l(client->getParameters());
Igor Murashkin707c3e32012-09-20 15:18:50 -0700347 /* warning: this also locks a SharedCameraClient */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800348 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700349 mShutterNotified = true;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700350 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
351 return STANDARD_CAPTURE_WAIT;
352}
353
354CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
355 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700356 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700357 return DONE;
358}
359
360CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
361 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700362 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700363 return START;
364}
365
366CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
367 sp<Camera2Client> &client) {
368 ATRACE_CALL();
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700369 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700370 this);
371 {
372 SharedParameters::Lock l(client->getParameters());
373 mTriggerId = l.mParameters.precaptureTriggerCounter++;
374 }
375 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
376
377 mAeInPrecapture = false;
378 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
379 return STANDARD_PRECAPTURE_WAIT;
380}
381
382CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
383 sp<Camera2Client> &client) {
384 status_t res;
385 ATRACE_CALL();
386 Mutex::Autolock l(mInputMutex);
387 while (!mNewAEState) {
388 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
389 if (res == TIMED_OUT) {
390 mTimeoutCount--;
391 break;
392 }
393 }
394 if (mTimeoutCount <= 0) {
395 ALOGW("Timed out waiting for precapture %s",
396 mAeInPrecapture ? "end" : "start");
397 return STANDARD_CAPTURE;
398 }
399 if (mNewAEState) {
400 if (!mAeInPrecapture) {
401 // Waiting to see PRECAPTURE state
402 if (mAETriggerId == mTriggerId &&
403 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
404 ALOGV("%s: Got precapture start", __FUNCTION__);
405 mAeInPrecapture = true;
406 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
407 }
408 } else {
409 // Waiting to see PRECAPTURE state end
410 if (mAETriggerId == mTriggerId &&
411 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
412 ALOGV("%s: Got precapture end", __FUNCTION__);
413 return STANDARD_CAPTURE;
414 }
415 }
416 mNewAEState = false;
417 }
418 return STANDARD_PRECAPTURE_WAIT;
419}
420
421CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
422 sp<Camera2Client> &client) {
423 status_t res;
424 ATRACE_CALL();
425 SharedParameters::Lock l(client->getParameters());
426 Vector<uint8_t> outputStreams;
427
428 outputStreams.push(client->getPreviewStreamId());
429 outputStreams.push(client->getCaptureStreamId());
430
431 if (l.mParameters.previewCallbackFlags &
432 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
433 outputStreams.push(client->getCallbackStreamId());
434 }
435
436 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
437 outputStreams.push(client->getRecordingStreamId());
438 }
439
440 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
441 outputStreams);
442 if (res == OK) {
443 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
444 &mCaptureId, 1);
445 }
446 if (res == OK) {
447 res = mCaptureRequest.sort();
448 }
449
450 if (res != OK) {
451 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
452 __FUNCTION__, client->getCameraId(), strerror(-res), res);
453 return DONE;
454 }
455
456 CameraMetadata captureCopy = mCaptureRequest;
457 if (captureCopy.entryCount() == 0) {
458 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
459 __FUNCTION__, client->getCameraId());
460 return DONE;
461 }
462
463 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700464 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700465 if (res != OK) {
466 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
467 "%s (%d)",
468 __FUNCTION__, client->getCameraId(), strerror(-res), res);
469 return DONE;
470 }
471 }
472 // TODO: Capture should be atomic with setStreamingRequest here
473 res = client->getCameraDevice()->capture(captureCopy);
474 if (res != OK) {
475 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
476 "%s (%d)",
477 __FUNCTION__, client->getCameraId(), strerror(-res), res);
478 return DONE;
479 }
480
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700481 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
482 return STANDARD_CAPTURE_WAIT;
483}
484
485CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
486 sp<Camera2Client> &client) {
487 status_t res;
488 ATRACE_CALL();
489 Mutex::Autolock l(mInputMutex);
490 while (!mNewFrameReceived) {
491 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
492 if (res == TIMED_OUT) {
493 mTimeoutCount--;
494 break;
495 }
496 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700497 if (mNewFrameReceived && !mShutterNotified) {
498 SharedParameters::Lock l(client->getParameters());
499 /* warning: this also locks a SharedCameraClient */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800500 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700501 mShutterNotified = true;
502 }
503 while (mNewFrameReceived && !mNewCaptureReceived) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700504 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
505 if (res == TIMED_OUT) {
506 mTimeoutCount--;
507 break;
508 }
509 }
510 if (mTimeoutCount <= 0) {
511 ALOGW("Timed out waiting for capture to complete");
512 return DONE;
513 }
514 if (mNewFrameReceived && mNewCaptureReceived) {
515 if (mNewFrameId != mCaptureId) {
516 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
517 mCaptureId, mNewFrameId);
518 }
519 camera_metadata_entry_t entry;
520 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
521 if (entry.count == 0) {
522 ALOGE("No timestamp field in capture frame!");
523 }
524 if (entry.data.i64[0] != mCaptureTimestamp) {
525 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
526 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
527 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700528 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700529
530 mNewFrameReceived = false;
531 mNewCaptureReceived = false;
532 return DONE;
533 }
534 return STANDARD_CAPTURE_WAIT;
535}
536
James Painterc3dbf1a2012-09-05 18:02:32 -0700537CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
538 sp<Camera2Client> &client) {
539 ALOGV("%s", __FUNCTION__);
540 status_t res;
541 ATRACE_CALL();
542
543 // check which burst mode is set, create respective burst object
544 {
545 SharedParameters::Lock l(client->getParameters());
546
547 res = updateCaptureRequest(l.mParameters, client);
548 if(res != OK) {
549 return DONE;
550 }
551
552 //
553 // check for burst mode type in mParameters here
554 //
555 mBurstCapture = new BurstCapture(client, this);
556 }
557
558 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
559 if (res == OK) {
560 res = mCaptureRequest.sort();
561 }
562 if (res != OK) {
563 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
564 __FUNCTION__, client->getCameraId(), strerror(-res), res);
565 return DONE;
566 }
567
568 CameraMetadata captureCopy = mCaptureRequest;
569 if (captureCopy.entryCount() == 0) {
570 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
571 __FUNCTION__, client->getCameraId());
572 return DONE;
573 }
574
575 Vector<CameraMetadata> requests;
576 requests.push(mCaptureRequest);
577 res = mBurstCapture->start(requests, mCaptureId);
578 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
579 return BURST_CAPTURE_WAIT;
580}
581
582CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
583 sp<Camera2Client> &client) {
584 status_t res;
585 ATRACE_CALL();
586
587 while (!mNewCaptureReceived) {
588 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
589 if (res == TIMED_OUT) {
590 mTimeoutCount--;
591 break;
592 }
593 }
594
595 if (mTimeoutCount <= 0) {
596 ALOGW("Timed out waiting for burst capture to complete");
597 return DONE;
598 }
599 if (mNewCaptureReceived) {
600 mNewCaptureReceived = false;
601 // TODO: update mCaptureId to last burst's capture ID + 1?
602 return DONE;
603 }
604
605 return BURST_CAPTURE_WAIT;
606}
607
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700608status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
609 sp<Camera2Client> &client) {
610 ATRACE_CALL();
611 status_t res;
612 if (mCaptureRequest.entryCount() == 0) {
613 res = client->getCameraDevice()->createDefaultRequest(
614 CAMERA2_TEMPLATE_STILL_CAPTURE,
615 &mCaptureRequest);
616 if (res != OK) {
617 ALOGE("%s: Camera %d: Unable to create default still image request:"
618 " %s (%d)", __FUNCTION__, client->getCameraId(),
619 strerror(-res), res);
620 return res;
621 }
622 }
623
624 res = params.updateRequest(&mCaptureRequest);
625 if (res != OK) {
626 ALOGE("%s: Camera %d: Unable to update common entries of capture "
627 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
628 strerror(-res), res);
629 return res;
630 }
631
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700632 res = params.updateRequestJpeg(&mCaptureRequest);
633 if (res != OK) {
634 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
635 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
636 strerror(-res), res);
637 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700638 }
639
640 return OK;
641}
642
Igor Murashkin707c3e32012-09-20 15:18:50 -0700643/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
Igor Murashkin786a8da2012-11-26 10:50:55 -0800644 sp<Camera2Client> client, int msgType) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700645 ATRACE_CALL();
646
Igor Murashkin786a8da2012-11-26 10:50:55 -0800647 if (params.state == Parameters::STILL_CAPTURE
648 && params.playShutterSound
649 && (msgType & CAMERA_MSG_SHUTTER)) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700650 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
651 }
652
653 {
654 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
655
656 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
657 if (l.mCameraClient != 0) {
658 // ShutterCallback
659 l.mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER,
660 /*ext1*/0, /*ext2*/0);
661
662 // RawCallback with null buffer
663 l.mCameraClient->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
664 /*ext1*/0, /*ext2*/0);
665 } else {
666 ALOGV("%s: No client!", __FUNCTION__);
667 }
668 }
669}
670
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700671
672}; // namespace camera2
673}; // namespace android