blob: 266e5163fac951800c47808300e1a766ef4de0f5 [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"
Igor Murashkin2fba5842013-04-22 14:03:54 -070030#include "ZslProcessorInterface.h"
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070031
32namespace android {
33namespace camera2 {
34
35/** Public members */
36
37CaptureSequencer::CaptureSequencer(wp<Camera2Client> client):
38 Thread(false),
39 mStartCapture(false),
40 mBusy(false),
41 mNewAEState(false),
42 mNewFrameReceived(false),
43 mNewCaptureReceived(false),
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -070044 mShutterNotified(false),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070045 mClient(client),
46 mCaptureState(IDLE),
47 mTriggerId(0),
48 mTimeoutCount(0),
Igor Murashkin786a8da2012-11-26 10:50:55 -080049 mCaptureId(Camera2Client::kCaptureRequestIdStart),
50 mMsgType(0) {
James Painterc3dbf1a2012-09-05 18:02:32 -070051 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070052}
53
54CaptureSequencer::~CaptureSequencer() {
55 ALOGV("%s: Exit", __FUNCTION__);
56}
57
Igor Murashkin2fba5842013-04-22 14:03:54 -070058void CaptureSequencer::setZslProcessor(wp<ZslProcessorInterface> processor) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070059 Mutex::Autolock l(mInputMutex);
60 mZslProcessor = processor;
61}
62
Igor Murashkin786a8da2012-11-26 10:50:55 -080063status_t CaptureSequencer::startCapture(int msgType) {
James Painterc3dbf1a2012-09-05 18:02:32 -070064 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070065 ATRACE_CALL();
66 Mutex::Autolock l(mInputMutex);
67 if (mBusy) {
68 ALOGE("%s: Already busy capturing!", __FUNCTION__);
69 return INVALID_OPERATION;
70 }
71 if (!mStartCapture) {
Igor Murashkin786a8da2012-11-26 10:50:55 -080072 mMsgType = msgType;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070073 mStartCapture = true;
74 mStartCaptureSignal.signal();
75 }
76 return OK;
77}
78
Eino-Ville Talvalae0493842012-10-05 12:03:10 -070079status_t CaptureSequencer::waitUntilIdle(nsecs_t timeout) {
80 ATRACE_CALL();
81 ALOGV("%s: Waiting for idle", __FUNCTION__);
82 Mutex::Autolock l(mStateMutex);
83 status_t res = -1;
84 while (mCaptureState != IDLE) {
85 nsecs_t startTime = systemTime();
86
87 res = mStateChanged.waitRelative(mStateMutex, timeout);
88 if (res != OK) return res;
89
90 timeout -= (systemTime() - startTime);
91 }
92 ALOGV("%s: Now idle", __FUNCTION__);
93 return OK;
94}
95
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070096void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
97 ATRACE_CALL();
98 Mutex::Autolock l(mInputMutex);
99 mAEState = newState;
100 mAETriggerId = triggerId;
101 if (!mNewAEState) {
102 mNewAEState = true;
103 mNewNotifySignal.signal();
104 }
105}
106
107void CaptureSequencer::onFrameAvailable(int32_t frameId,
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700108 const CameraMetadata &frame) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700109 ALOGV("%s: Listener found new frame", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700110 ATRACE_CALL();
111 Mutex::Autolock l(mInputMutex);
112 mNewFrameId = frameId;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700113 mNewFrame = frame;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700114 if (!mNewFrameReceived) {
115 mNewFrameReceived = true;
116 mNewFrameSignal.signal();
117 }
118}
119
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700120void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
121 sp<MemoryBase> captureBuffer) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700122 ATRACE_CALL();
James Painterc3dbf1a2012-09-05 18:02:32 -0700123 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700124 Mutex::Autolock l(mInputMutex);
125 mCaptureTimestamp = timestamp;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700126 mCaptureBuffer = captureBuffer;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700127 if (!mNewCaptureReceived) {
128 mNewCaptureReceived = true;
129 mNewCaptureSignal.signal();
130 }
131}
132
133
Igor Murashkinebe3f692012-10-12 16:56:11 -0700134void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700135 String8 result;
136 if (mCaptureRequest.entryCount() != 0) {
137 result = " Capture request:\n";
138 write(fd, result.string(), result.size());
139 mCaptureRequest.dump(fd, 2, 6);
140 } else {
141 result = " Capture request: undefined\n";
142 write(fd, result.string(), result.size());
143 }
144 result = String8::format(" Current capture state: %s\n",
145 kStateNames[mCaptureState]);
146 result.append(" Latest captured frame:\n");
147 write(fd, result.string(), result.size());
148 mNewFrame.dump(fd, 2, 6);
149}
150
151/** Private members */
152
153const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
154{
155 "IDLE",
156 "START",
157 "ZSL_START",
158 "ZSL_WAITING",
159 "ZSL_REPROCESSING",
160 "STANDARD_START",
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700161 "STANDARD_PRECAPTURE_WAIT",
162 "STANDARD_CAPTURE",
163 "STANDARD_CAPTURE_WAIT",
James Painterc3dbf1a2012-09-05 18:02:32 -0700164 "BURST_CAPTURE_START",
165 "BURST_CAPTURE_WAIT",
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700166 "DONE",
167 "ERROR",
168 "UNKNOWN"
169};
170
171const CaptureSequencer::StateManager
172 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
173 &CaptureSequencer::manageIdle,
174 &CaptureSequencer::manageStart,
175 &CaptureSequencer::manageZslStart,
176 &CaptureSequencer::manageZslWaiting,
177 &CaptureSequencer::manageZslReprocessing,
178 &CaptureSequencer::manageStandardStart,
179 &CaptureSequencer::manageStandardPrecaptureWait,
180 &CaptureSequencer::manageStandardCapture,
181 &CaptureSequencer::manageStandardCaptureWait,
James Painterc3dbf1a2012-09-05 18:02:32 -0700182 &CaptureSequencer::manageBurstCaptureStart,
183 &CaptureSequencer::manageBurstCaptureWait,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700184 &CaptureSequencer::manageDone,
185};
186
187bool CaptureSequencer::threadLoop() {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700188
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
Igor Murashkinebe3f692012-10-12 16:56:11 -0700218CaptureSequencer::CaptureState CaptureSequencer::manageIdle(
219 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700220 status_t res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700221 Mutex::Autolock l(mInputMutex);
222 while (!mStartCapture) {
223 res = mStartCaptureSignal.waitRelative(mInputMutex,
224 kWaitDuration);
225 if (res == TIMED_OUT) break;
226 }
227 if (mStartCapture) {
228 mStartCapture = false;
229 mBusy = true;
230 return START;
231 }
232 return IDLE;
233}
234
235CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700236 status_t res = OK;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700237 ATRACE_CALL();
238 mCaptureId++;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700239 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
240 mCaptureId = Camera2Client::kCaptureRequestIdStart;
241 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700242 {
243 Mutex::Autolock l(mInputMutex);
244 mBusy = false;
245 }
246
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700247 {
248 SharedParameters::Lock l(client->getParameters());
249 switch (l.mParameters.state) {
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700250 case Parameters::DISCONNECTED:
251 ALOGW("%s: Camera %d: Discarding image data during shutdown ",
252 __FUNCTION__, client->getCameraId());
253 res = INVALID_OPERATION;
254 break;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700255 case Parameters::STILL_CAPTURE:
256 l.mParameters.state = Parameters::STOPPED;
257 break;
258 case Parameters::VIDEO_SNAPSHOT:
259 l.mParameters.state = Parameters::RECORD;
260 break;
261 default:
262 ALOGE("%s: Camera %d: Still image produced unexpectedly "
263 "in state %s!",
264 __FUNCTION__, client->getCameraId(),
265 Parameters::getStateName(l.mParameters.state));
266 res = INVALID_OPERATION;
267 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700268 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700269 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700270 if (processor != 0) {
Igor Murashkin2fba5842013-04-22 14:03:54 -0700271 ALOGV("%s: Memory optimization, clearing ZSL queue",
272 __FUNCTION__);
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700273 processor->clearZslQueue();
274 }
275
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700276 /**
277 * Fire the jpegCallback in Camera#takePicture(..., jpegCallback)
278 */
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700279 if (mCaptureBuffer != 0 && res == OK) {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800280 Camera2Client::SharedCameraCallbacks::Lock
281 l(client->mSharedCameraCallbacks);
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700282 ALOGV("%s: Sending still image to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800283 if (l.mRemoteCallback != 0) {
284 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700285 mCaptureBuffer, NULL);
286 } else {
287 ALOGV("%s: No client!", __FUNCTION__);
288 }
289 }
290 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700291
292 return IDLE;
293}
294
295CaptureSequencer::CaptureState CaptureSequencer::manageStart(
296 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700297 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700298 status_t res;
299 ATRACE_CALL();
300 SharedParameters::Lock l(client->getParameters());
301 CaptureState nextState = DONE;
302
303 res = updateCaptureRequest(l.mParameters, client);
304 if (res != OK ) {
305 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
306 __FUNCTION__, client->getCameraId(), strerror(-res), res);
307 return DONE;
308 }
309
James Painterc3dbf1a2012-09-05 18:02:32 -0700310 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
311 l.mParameters.state == Parameters::STILL_CAPTURE) {
312 nextState = BURST_CAPTURE_START;
313 }
314 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700315 l.mParameters.state == Parameters::STILL_CAPTURE &&
316 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700317 nextState = ZSL_START;
318 } else {
319 nextState = STANDARD_START;
320 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700321 mShutterNotified = false;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700322
323 return nextState;
324}
325
326CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
327 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700328 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700329 status_t res;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700330 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700331 if (processor == 0) {
332 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
333 return DONE;
334 }
335
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700336 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700337 this);
338
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700339 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700340 res = processor->pushToReprocess(mCaptureId);
341 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700342 if (res == NOT_ENOUGH_DATA) {
343 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
344 "falling back to normal capture", __FUNCTION__,
345 client->getCameraId());
346 } else {
347 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
348 __FUNCTION__, client->getCameraId(), strerror(-res), res);
349 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700350 return STANDARD_START;
351 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700352
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700353 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800354 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800355 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700356 mShutterNotified = true;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700357 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
358 return STANDARD_CAPTURE_WAIT;
359}
360
361CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700362 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700363 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700364 return DONE;
365}
366
367CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700368 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700369 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700370 return START;
371}
372
373CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
374 sp<Camera2Client> &client) {
375 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700376
377 // Get the onFrameAvailable callback when the requestID == mCaptureId
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700378 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700379 this);
380 {
381 SharedParameters::Lock l(client->getParameters());
382 mTriggerId = l.mParameters.precaptureTriggerCounter++;
383 }
384 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
385
386 mAeInPrecapture = false;
387 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
388 return STANDARD_PRECAPTURE_WAIT;
389}
390
391CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700392 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700393 status_t res;
394 ATRACE_CALL();
395 Mutex::Autolock l(mInputMutex);
396 while (!mNewAEState) {
397 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
398 if (res == TIMED_OUT) {
399 mTimeoutCount--;
400 break;
401 }
402 }
403 if (mTimeoutCount <= 0) {
404 ALOGW("Timed out waiting for precapture %s",
405 mAeInPrecapture ? "end" : "start");
406 return STANDARD_CAPTURE;
407 }
408 if (mNewAEState) {
409 if (!mAeInPrecapture) {
410 // Waiting to see PRECAPTURE state
411 if (mAETriggerId == mTriggerId &&
412 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
413 ALOGV("%s: Got precapture start", __FUNCTION__);
414 mAeInPrecapture = true;
415 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
416 }
417 } else {
418 // Waiting to see PRECAPTURE state end
419 if (mAETriggerId == mTriggerId &&
420 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
421 ALOGV("%s: Got precapture end", __FUNCTION__);
422 return STANDARD_CAPTURE;
423 }
424 }
425 mNewAEState = false;
426 }
427 return STANDARD_PRECAPTURE_WAIT;
428}
429
430CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
431 sp<Camera2Client> &client) {
432 status_t res;
433 ATRACE_CALL();
434 SharedParameters::Lock l(client->getParameters());
435 Vector<uint8_t> outputStreams;
436
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700437 /**
438 * Set up output streams in the request
439 * - preview
440 * - capture/jpeg
441 * - callback (if preview callbacks enabled)
442 * - recording (if recording enabled)
443 */
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700444 outputStreams.push(client->getPreviewStreamId());
445 outputStreams.push(client->getCaptureStreamId());
446
447 if (l.mParameters.previewCallbackFlags &
448 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
449 outputStreams.push(client->getCallbackStreamId());
450 }
451
452 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
453 outputStreams.push(client->getRecordingStreamId());
454 }
455
456 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
457 outputStreams);
458 if (res == OK) {
459 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
460 &mCaptureId, 1);
461 }
462 if (res == OK) {
463 res = mCaptureRequest.sort();
464 }
465
466 if (res != OK) {
467 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
468 __FUNCTION__, client->getCameraId(), strerror(-res), res);
469 return DONE;
470 }
471
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700472 // Create a capture copy since CameraDeviceBase#capture takes ownership
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700473 CameraMetadata captureCopy = mCaptureRequest;
474 if (captureCopy.entryCount() == 0) {
475 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
476 __FUNCTION__, client->getCameraId());
477 return DONE;
478 }
479
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700480 /**
481 * Clear the streaming request for still-capture pictures
482 * (as opposed to i.e. video snapshots)
483 */
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700484 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700485 // API definition of takePicture() - stop preview before taking pic
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700486 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700487 if (res != OK) {
488 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
489 "%s (%d)",
490 __FUNCTION__, client->getCameraId(), strerror(-res), res);
491 return DONE;
492 }
493 }
494 // TODO: Capture should be atomic with setStreamingRequest here
495 res = client->getCameraDevice()->capture(captureCopy);
496 if (res != OK) {
497 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
498 "%s (%d)",
499 __FUNCTION__, client->getCameraId(), strerror(-res), res);
500 return DONE;
501 }
502
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700503 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
504 return STANDARD_CAPTURE_WAIT;
505}
506
507CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
508 sp<Camera2Client> &client) {
509 status_t res;
510 ATRACE_CALL();
511 Mutex::Autolock l(mInputMutex);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700512
513 // Wait for new metadata result (mNewFrame)
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700514 while (!mNewFrameReceived) {
515 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
516 if (res == TIMED_OUT) {
517 mTimeoutCount--;
518 break;
519 }
520 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700521
522 // Approximation of the shutter being closed
523 // - TODO: use the hal3 exposure callback in Camera3Device instead
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700524 if (mNewFrameReceived && !mShutterNotified) {
525 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800526 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800527 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700528 mShutterNotified = true;
529 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700530
531 // Wait until jpeg was captured by JpegProcessor
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700532 while (mNewFrameReceived && !mNewCaptureReceived) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700533 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
534 if (res == TIMED_OUT) {
535 mTimeoutCount--;
536 break;
537 }
538 }
539 if (mTimeoutCount <= 0) {
540 ALOGW("Timed out waiting for capture to complete");
541 return DONE;
542 }
543 if (mNewFrameReceived && mNewCaptureReceived) {
544 if (mNewFrameId != mCaptureId) {
545 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
546 mCaptureId, mNewFrameId);
547 }
548 camera_metadata_entry_t entry;
549 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
550 if (entry.count == 0) {
551 ALOGE("No timestamp field in capture frame!");
552 }
553 if (entry.data.i64[0] != mCaptureTimestamp) {
554 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700555 " captured buffer %lld",
556 entry.data.i64[0],
557 mCaptureTimestamp);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700558 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700559 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700560
561 mNewFrameReceived = false;
562 mNewCaptureReceived = false;
563 return DONE;
564 }
565 return STANDARD_CAPTURE_WAIT;
566}
567
James Painterc3dbf1a2012-09-05 18:02:32 -0700568CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
569 sp<Camera2Client> &client) {
570 ALOGV("%s", __FUNCTION__);
571 status_t res;
572 ATRACE_CALL();
573
574 // check which burst mode is set, create respective burst object
575 {
576 SharedParameters::Lock l(client->getParameters());
577
578 res = updateCaptureRequest(l.mParameters, client);
579 if(res != OK) {
580 return DONE;
581 }
582
583 //
584 // check for burst mode type in mParameters here
585 //
586 mBurstCapture = new BurstCapture(client, this);
587 }
588
589 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
590 if (res == OK) {
591 res = mCaptureRequest.sort();
592 }
593 if (res != OK) {
594 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
595 __FUNCTION__, client->getCameraId(), strerror(-res), res);
596 return DONE;
597 }
598
599 CameraMetadata captureCopy = mCaptureRequest;
600 if (captureCopy.entryCount() == 0) {
601 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
602 __FUNCTION__, client->getCameraId());
603 return DONE;
604 }
605
606 Vector<CameraMetadata> requests;
607 requests.push(mCaptureRequest);
608 res = mBurstCapture->start(requests, mCaptureId);
609 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
610 return BURST_CAPTURE_WAIT;
611}
612
613CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700614 sp<Camera2Client> &/*client*/) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700615 status_t res;
616 ATRACE_CALL();
617
618 while (!mNewCaptureReceived) {
619 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
620 if (res == TIMED_OUT) {
621 mTimeoutCount--;
622 break;
623 }
624 }
625
626 if (mTimeoutCount <= 0) {
627 ALOGW("Timed out waiting for burst capture to complete");
628 return DONE;
629 }
630 if (mNewCaptureReceived) {
631 mNewCaptureReceived = false;
632 // TODO: update mCaptureId to last burst's capture ID + 1?
633 return DONE;
634 }
635
636 return BURST_CAPTURE_WAIT;
637}
638
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700639status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
640 sp<Camera2Client> &client) {
641 ATRACE_CALL();
642 status_t res;
643 if (mCaptureRequest.entryCount() == 0) {
644 res = client->getCameraDevice()->createDefaultRequest(
645 CAMERA2_TEMPLATE_STILL_CAPTURE,
646 &mCaptureRequest);
647 if (res != OK) {
648 ALOGE("%s: Camera %d: Unable to create default still image request:"
649 " %s (%d)", __FUNCTION__, client->getCameraId(),
650 strerror(-res), res);
651 return res;
652 }
653 }
654
655 res = params.updateRequest(&mCaptureRequest);
656 if (res != OK) {
657 ALOGE("%s: Camera %d: Unable to update common entries of capture "
658 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
659 strerror(-res), res);
660 return res;
661 }
662
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700663 res = params.updateRequestJpeg(&mCaptureRequest);
664 if (res != OK) {
665 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
666 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
667 strerror(-res), res);
668 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700669 }
670
671 return OK;
672}
673
Igor Murashkin707c3e32012-09-20 15:18:50 -0700674/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
Igor Murashkin786a8da2012-11-26 10:50:55 -0800675 sp<Camera2Client> client, int msgType) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700676 ATRACE_CALL();
677
Igor Murashkin786a8da2012-11-26 10:50:55 -0800678 if (params.state == Parameters::STILL_CAPTURE
679 && params.playShutterSound
680 && (msgType & CAMERA_MSG_SHUTTER)) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700681 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
682 }
683
684 {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800685 Camera2Client::SharedCameraCallbacks::Lock
686 l(client->mSharedCameraCallbacks);
Igor Murashkin707c3e32012-09-20 15:18:50 -0700687
688 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800689 if (l.mRemoteCallback != 0) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700690 // ShutterCallback
Igor Murashkina2e203b2013-03-01 16:22:28 -0800691 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700692 /*ext1*/0, /*ext2*/0);
693
694 // RawCallback with null buffer
Igor Murashkina2e203b2013-03-01 16:22:28 -0800695 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700696 /*ext1*/0, /*ext2*/0);
697 } else {
698 ALOGV("%s: No client!", __FUNCTION__);
699 }
700 }
701}
702
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700703
704}; // namespace camera2
705}; // namespace android