blob: ee03329953ea9cbc1ab89801fc6509c264817880 [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
Igor Murashkinebe3f692012-10-12 16:56:11 -0700133void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700134 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() {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700187
188 sp<Camera2Client> client = mClient.promote();
189 if (client == 0) return false;
190
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700191 CaptureState currentState;
192 {
193 Mutex::Autolock l(mStateMutex);
194 currentState = mCaptureState;
195 }
196
197 currentState = (this->*kStateManagers[currentState])(client);
198
199 Mutex::Autolock l(mStateMutex);
200 if (currentState != mCaptureState) {
201 mCaptureState = currentState;
202 ATRACE_INT("cam2_capt_state", mCaptureState);
203 ALOGV("Camera %d: New capture state %s",
204 client->getCameraId(), kStateNames[mCaptureState]);
205 mStateChanged.signal();
206 }
207
208 if (mCaptureState == ERROR) {
209 ALOGE("Camera %d: Stopping capture sequencer due to error",
210 client->getCameraId());
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700211 return false;
212 }
213
214 return true;
215}
216
Igor Murashkinebe3f692012-10-12 16:56:11 -0700217CaptureSequencer::CaptureState CaptureSequencer::manageIdle(
218 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700219 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
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700273 /**
274 * Fire the jpegCallback in Camera#takePicture(..., jpegCallback)
275 */
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700276 if (mCaptureBuffer != 0 && res == OK) {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800277 Camera2Client::SharedCameraCallbacks::Lock
278 l(client->mSharedCameraCallbacks);
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700279 ALOGV("%s: Sending still image to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800280 if (l.mRemoteCallback != 0) {
281 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700282 mCaptureBuffer, NULL);
283 } else {
284 ALOGV("%s: No client!", __FUNCTION__);
285 }
286 }
287 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700288
289 return IDLE;
290}
291
292CaptureSequencer::CaptureState CaptureSequencer::manageStart(
293 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700294 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700295 status_t res;
296 ATRACE_CALL();
297 SharedParameters::Lock l(client->getParameters());
298 CaptureState nextState = DONE;
299
300 res = updateCaptureRequest(l.mParameters, client);
301 if (res != OK ) {
302 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
303 __FUNCTION__, client->getCameraId(), strerror(-res), res);
304 return DONE;
305 }
306
James Painterc3dbf1a2012-09-05 18:02:32 -0700307 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
308 l.mParameters.state == Parameters::STILL_CAPTURE) {
309 nextState = BURST_CAPTURE_START;
310 }
311 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700312 l.mParameters.state == Parameters::STILL_CAPTURE &&
313 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700314 nextState = ZSL_START;
315 } else {
316 nextState = STANDARD_START;
317 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700318 mShutterNotified = false;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700319
320 return nextState;
321}
322
323CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
324 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700325 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700326 status_t res;
327 sp<ZslProcessor> processor = mZslProcessor.promote();
328 if (processor == 0) {
329 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
330 return DONE;
331 }
332
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700333 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700334 this);
335
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700336 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700337 res = processor->pushToReprocess(mCaptureId);
338 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700339 if (res == NOT_ENOUGH_DATA) {
340 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
341 "falling back to normal capture", __FUNCTION__,
342 client->getCameraId());
343 } else {
344 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
345 __FUNCTION__, client->getCameraId(), strerror(-res), res);
346 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700347 return STANDARD_START;
348 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700349
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700350 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800351 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800352 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700353 mShutterNotified = true;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700354 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
355 return STANDARD_CAPTURE_WAIT;
356}
357
358CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700359 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 DONE;
362}
363
364CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700365 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700366 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700367 return START;
368}
369
370CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
371 sp<Camera2Client> &client) {
372 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700373
374 // Get the onFrameAvailable callback when the requestID == mCaptureId
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700375 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700376 this);
377 {
378 SharedParameters::Lock l(client->getParameters());
379 mTriggerId = l.mParameters.precaptureTriggerCounter++;
380 }
381 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
382
383 mAeInPrecapture = false;
384 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
385 return STANDARD_PRECAPTURE_WAIT;
386}
387
388CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700389 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700390 status_t res;
391 ATRACE_CALL();
392 Mutex::Autolock l(mInputMutex);
393 while (!mNewAEState) {
394 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
395 if (res == TIMED_OUT) {
396 mTimeoutCount--;
397 break;
398 }
399 }
400 if (mTimeoutCount <= 0) {
401 ALOGW("Timed out waiting for precapture %s",
402 mAeInPrecapture ? "end" : "start");
403 return STANDARD_CAPTURE;
404 }
405 if (mNewAEState) {
406 if (!mAeInPrecapture) {
407 // Waiting to see PRECAPTURE state
408 if (mAETriggerId == mTriggerId &&
409 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
410 ALOGV("%s: Got precapture start", __FUNCTION__);
411 mAeInPrecapture = true;
412 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
413 }
414 } else {
415 // Waiting to see PRECAPTURE state end
416 if (mAETriggerId == mTriggerId &&
417 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
418 ALOGV("%s: Got precapture end", __FUNCTION__);
419 return STANDARD_CAPTURE;
420 }
421 }
422 mNewAEState = false;
423 }
424 return STANDARD_PRECAPTURE_WAIT;
425}
426
427CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
428 sp<Camera2Client> &client) {
429 status_t res;
430 ATRACE_CALL();
431 SharedParameters::Lock l(client->getParameters());
432 Vector<uint8_t> outputStreams;
433
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700434 /**
435 * Set up output streams in the request
436 * - preview
437 * - capture/jpeg
438 * - callback (if preview callbacks enabled)
439 * - recording (if recording enabled)
440 */
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700441 outputStreams.push(client->getPreviewStreamId());
442 outputStreams.push(client->getCaptureStreamId());
443
444 if (l.mParameters.previewCallbackFlags &
445 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
446 outputStreams.push(client->getCallbackStreamId());
447 }
448
449 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
450 outputStreams.push(client->getRecordingStreamId());
451 }
452
453 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
454 outputStreams);
455 if (res == OK) {
456 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
457 &mCaptureId, 1);
458 }
459 if (res == OK) {
460 res = mCaptureRequest.sort();
461 }
462
463 if (res != OK) {
464 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
465 __FUNCTION__, client->getCameraId(), strerror(-res), res);
466 return DONE;
467 }
468
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700469 // Create a capture copy since CameraDeviceBase#capture takes ownership
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700470 CameraMetadata captureCopy = mCaptureRequest;
471 if (captureCopy.entryCount() == 0) {
472 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
473 __FUNCTION__, client->getCameraId());
474 return DONE;
475 }
476
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700477 /**
478 * Clear the streaming request for still-capture pictures
479 * (as opposed to i.e. video snapshots)
480 */
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700481 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700482 // API definition of takePicture() - stop preview before taking pic
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700483 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700484 if (res != OK) {
485 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
486 "%s (%d)",
487 __FUNCTION__, client->getCameraId(), strerror(-res), res);
488 return DONE;
489 }
490 }
491 // TODO: Capture should be atomic with setStreamingRequest here
492 res = client->getCameraDevice()->capture(captureCopy);
493 if (res != OK) {
494 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
495 "%s (%d)",
496 __FUNCTION__, client->getCameraId(), strerror(-res), res);
497 return DONE;
498 }
499
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700500 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
501 return STANDARD_CAPTURE_WAIT;
502}
503
504CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
505 sp<Camera2Client> &client) {
506 status_t res;
507 ATRACE_CALL();
508 Mutex::Autolock l(mInputMutex);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700509
510 // Wait for new metadata result (mNewFrame)
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700511 while (!mNewFrameReceived) {
512 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
513 if (res == TIMED_OUT) {
514 mTimeoutCount--;
515 break;
516 }
517 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700518
519 // Approximation of the shutter being closed
520 // - TODO: use the hal3 exposure callback in Camera3Device instead
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700521 if (mNewFrameReceived && !mShutterNotified) {
522 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800523 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800524 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700525 mShutterNotified = true;
526 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700527
528 // Wait until jpeg was captured by JpegProcessor
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700529 while (mNewFrameReceived && !mNewCaptureReceived) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700530 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
531 if (res == TIMED_OUT) {
532 mTimeoutCount--;
533 break;
534 }
535 }
536 if (mTimeoutCount <= 0) {
537 ALOGW("Timed out waiting for capture to complete");
538 return DONE;
539 }
540 if (mNewFrameReceived && mNewCaptureReceived) {
541 if (mNewFrameId != mCaptureId) {
542 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
543 mCaptureId, mNewFrameId);
544 }
545 camera_metadata_entry_t entry;
546 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
547 if (entry.count == 0) {
548 ALOGE("No timestamp field in capture frame!");
549 }
550 if (entry.data.i64[0] != mCaptureTimestamp) {
551 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700552 " captured buffer %lld",
553 entry.data.i64[0],
554 mCaptureTimestamp);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700555 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700556 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700557
558 mNewFrameReceived = false;
559 mNewCaptureReceived = false;
560 return DONE;
561 }
562 return STANDARD_CAPTURE_WAIT;
563}
564
James Painterc3dbf1a2012-09-05 18:02:32 -0700565CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
566 sp<Camera2Client> &client) {
567 ALOGV("%s", __FUNCTION__);
568 status_t res;
569 ATRACE_CALL();
570
571 // check which burst mode is set, create respective burst object
572 {
573 SharedParameters::Lock l(client->getParameters());
574
575 res = updateCaptureRequest(l.mParameters, client);
576 if(res != OK) {
577 return DONE;
578 }
579
580 //
581 // check for burst mode type in mParameters here
582 //
583 mBurstCapture = new BurstCapture(client, this);
584 }
585
586 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
587 if (res == OK) {
588 res = mCaptureRequest.sort();
589 }
590 if (res != OK) {
591 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
592 __FUNCTION__, client->getCameraId(), strerror(-res), res);
593 return DONE;
594 }
595
596 CameraMetadata captureCopy = mCaptureRequest;
597 if (captureCopy.entryCount() == 0) {
598 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
599 __FUNCTION__, client->getCameraId());
600 return DONE;
601 }
602
603 Vector<CameraMetadata> requests;
604 requests.push(mCaptureRequest);
605 res = mBurstCapture->start(requests, mCaptureId);
606 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
607 return BURST_CAPTURE_WAIT;
608}
609
610CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700611 sp<Camera2Client> &/*client*/) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700612 status_t res;
613 ATRACE_CALL();
614
615 while (!mNewCaptureReceived) {
616 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
617 if (res == TIMED_OUT) {
618 mTimeoutCount--;
619 break;
620 }
621 }
622
623 if (mTimeoutCount <= 0) {
624 ALOGW("Timed out waiting for burst capture to complete");
625 return DONE;
626 }
627 if (mNewCaptureReceived) {
628 mNewCaptureReceived = false;
629 // TODO: update mCaptureId to last burst's capture ID + 1?
630 return DONE;
631 }
632
633 return BURST_CAPTURE_WAIT;
634}
635
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700636status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
637 sp<Camera2Client> &client) {
638 ATRACE_CALL();
639 status_t res;
640 if (mCaptureRequest.entryCount() == 0) {
641 res = client->getCameraDevice()->createDefaultRequest(
642 CAMERA2_TEMPLATE_STILL_CAPTURE,
643 &mCaptureRequest);
644 if (res != OK) {
645 ALOGE("%s: Camera %d: Unable to create default still image request:"
646 " %s (%d)", __FUNCTION__, client->getCameraId(),
647 strerror(-res), res);
648 return res;
649 }
650 }
651
652 res = params.updateRequest(&mCaptureRequest);
653 if (res != OK) {
654 ALOGE("%s: Camera %d: Unable to update common entries of capture "
655 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
656 strerror(-res), res);
657 return res;
658 }
659
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700660 res = params.updateRequestJpeg(&mCaptureRequest);
661 if (res != OK) {
662 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
663 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
664 strerror(-res), res);
665 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700666 }
667
668 return OK;
669}
670
Igor Murashkin707c3e32012-09-20 15:18:50 -0700671/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
Igor Murashkin786a8da2012-11-26 10:50:55 -0800672 sp<Camera2Client> client, int msgType) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700673 ATRACE_CALL();
674
Igor Murashkin786a8da2012-11-26 10:50:55 -0800675 if (params.state == Parameters::STILL_CAPTURE
676 && params.playShutterSound
677 && (msgType & CAMERA_MSG_SHUTTER)) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700678 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
679 }
680
681 {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800682 Camera2Client::SharedCameraCallbacks::Lock
683 l(client->mSharedCameraCallbacks);
Igor Murashkin707c3e32012-09-20 15:18:50 -0700684
685 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800686 if (l.mRemoteCallback != 0) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700687 // ShutterCallback
Igor Murashkina2e203b2013-03-01 16:22:28 -0800688 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700689 /*ext1*/0, /*ext2*/0);
690
691 // RawCallback with null buffer
Igor Murashkina2e203b2013-03-01 16:22:28 -0800692 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700693 /*ext1*/0, /*ext2*/0);
694 } else {
695 ALOGV("%s: No client!", __FUNCTION__);
696 }
697 }
698}
699
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700700
701}; // namespace camera2
702}; // namespace android