blob: e5a011c9348a59768aeb612342fd7c2c421709a5 [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:
Eino-Ville Talvala26bc9082013-06-13 18:04:28 -0700256 res = client->getCameraDevice()->waitUntilDrained();
257 if (res != OK) {
258 ALOGE("%s: Camera %d: Can't idle after still capture: "
259 "%s (%d)", __FUNCTION__, client->getCameraId(),
260 strerror(-res), res);
261 }
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700262 l.mParameters.state = Parameters::STOPPED;
263 break;
264 case Parameters::VIDEO_SNAPSHOT:
265 l.mParameters.state = Parameters::RECORD;
266 break;
267 default:
268 ALOGE("%s: Camera %d: Still image produced unexpectedly "
269 "in state %s!",
270 __FUNCTION__, client->getCameraId(),
271 Parameters::getStateName(l.mParameters.state));
272 res = INVALID_OPERATION;
273 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700274 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700275 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700276 if (processor != 0) {
Igor Murashkin2fba5842013-04-22 14:03:54 -0700277 ALOGV("%s: Memory optimization, clearing ZSL queue",
278 __FUNCTION__);
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700279 processor->clearZslQueue();
280 }
281
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700282 /**
283 * Fire the jpegCallback in Camera#takePicture(..., jpegCallback)
284 */
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700285 if (mCaptureBuffer != 0 && res == OK) {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800286 Camera2Client::SharedCameraCallbacks::Lock
287 l(client->mSharedCameraCallbacks);
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700288 ALOGV("%s: Sending still image to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800289 if (l.mRemoteCallback != 0) {
290 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700291 mCaptureBuffer, NULL);
292 } else {
293 ALOGV("%s: No client!", __FUNCTION__);
294 }
295 }
296 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700297
298 return IDLE;
299}
300
301CaptureSequencer::CaptureState CaptureSequencer::manageStart(
302 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700303 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700304 status_t res;
305 ATRACE_CALL();
306 SharedParameters::Lock l(client->getParameters());
307 CaptureState nextState = DONE;
308
309 res = updateCaptureRequest(l.mParameters, client);
310 if (res != OK ) {
311 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
312 __FUNCTION__, client->getCameraId(), strerror(-res), res);
313 return DONE;
314 }
315
James Painterc3dbf1a2012-09-05 18:02:32 -0700316 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
317 l.mParameters.state == Parameters::STILL_CAPTURE) {
318 nextState = BURST_CAPTURE_START;
319 }
320 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700321 l.mParameters.state == Parameters::STILL_CAPTURE &&
322 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700323 nextState = ZSL_START;
324 } else {
325 nextState = STANDARD_START;
326 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700327 mShutterNotified = false;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700328
329 return nextState;
330}
331
332CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
333 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700334 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700335 status_t res;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700336 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700337 if (processor == 0) {
338 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
339 return DONE;
340 }
341
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700342 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700343 this);
344
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700345 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700346 res = processor->pushToReprocess(mCaptureId);
347 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700348 if (res == NOT_ENOUGH_DATA) {
349 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
350 "falling back to normal capture", __FUNCTION__,
351 client->getCameraId());
352 } else {
353 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
354 __FUNCTION__, client->getCameraId(), strerror(-res), res);
355 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700356 return STANDARD_START;
357 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700358
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700359 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800360 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800361 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700362 mShutterNotified = true;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700363 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
364 return STANDARD_CAPTURE_WAIT;
365}
366
367CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
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 DONE;
371}
372
373CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700374 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700375 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700376 return START;
377}
378
379CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
380 sp<Camera2Client> &client) {
381 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700382
383 // Get the onFrameAvailable callback when the requestID == mCaptureId
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700384 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700385 this);
386 {
387 SharedParameters::Lock l(client->getParameters());
388 mTriggerId = l.mParameters.precaptureTriggerCounter++;
389 }
390 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
391
392 mAeInPrecapture = false;
393 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
394 return STANDARD_PRECAPTURE_WAIT;
395}
396
397CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700398 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700399 status_t res;
400 ATRACE_CALL();
401 Mutex::Autolock l(mInputMutex);
402 while (!mNewAEState) {
403 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
404 if (res == TIMED_OUT) {
405 mTimeoutCount--;
406 break;
407 }
408 }
409 if (mTimeoutCount <= 0) {
410 ALOGW("Timed out waiting for precapture %s",
411 mAeInPrecapture ? "end" : "start");
412 return STANDARD_CAPTURE;
413 }
414 if (mNewAEState) {
415 if (!mAeInPrecapture) {
416 // Waiting to see PRECAPTURE state
417 if (mAETriggerId == mTriggerId &&
418 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
419 ALOGV("%s: Got precapture start", __FUNCTION__);
420 mAeInPrecapture = true;
421 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
422 }
423 } else {
424 // Waiting to see PRECAPTURE state end
425 if (mAETriggerId == mTriggerId &&
426 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
427 ALOGV("%s: Got precapture end", __FUNCTION__);
428 return STANDARD_CAPTURE;
429 }
430 }
431 mNewAEState = false;
432 }
433 return STANDARD_PRECAPTURE_WAIT;
434}
435
436CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
437 sp<Camera2Client> &client) {
438 status_t res;
439 ATRACE_CALL();
440 SharedParameters::Lock l(client->getParameters());
441 Vector<uint8_t> outputStreams;
442
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700443 /**
444 * Set up output streams in the request
445 * - preview
446 * - capture/jpeg
447 * - callback (if preview callbacks enabled)
448 * - recording (if recording enabled)
449 */
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700450 outputStreams.push(client->getPreviewStreamId());
451 outputStreams.push(client->getCaptureStreamId());
452
453 if (l.mParameters.previewCallbackFlags &
454 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
455 outputStreams.push(client->getCallbackStreamId());
456 }
457
458 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
459 outputStreams.push(client->getRecordingStreamId());
460 }
461
462 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
463 outputStreams);
464 if (res == OK) {
465 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
466 &mCaptureId, 1);
467 }
468 if (res == OK) {
469 res = mCaptureRequest.sort();
470 }
471
472 if (res != OK) {
473 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
474 __FUNCTION__, client->getCameraId(), strerror(-res), res);
475 return DONE;
476 }
477
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700478 // Create a capture copy since CameraDeviceBase#capture takes ownership
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700479 CameraMetadata captureCopy = mCaptureRequest;
480 if (captureCopy.entryCount() == 0) {
481 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
482 __FUNCTION__, client->getCameraId());
483 return DONE;
484 }
485
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700486 /**
487 * Clear the streaming request for still-capture pictures
488 * (as opposed to i.e. video snapshots)
489 */
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700490 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700491 // API definition of takePicture() - stop preview before taking pic
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700492 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700493 if (res != OK) {
494 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
495 "%s (%d)",
496 __FUNCTION__, client->getCameraId(), strerror(-res), res);
497 return DONE;
498 }
499 }
500 // TODO: Capture should be atomic with setStreamingRequest here
501 res = client->getCameraDevice()->capture(captureCopy);
502 if (res != OK) {
503 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
504 "%s (%d)",
505 __FUNCTION__, client->getCameraId(), strerror(-res), res);
506 return DONE;
507 }
508
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700509 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
510 return STANDARD_CAPTURE_WAIT;
511}
512
513CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
514 sp<Camera2Client> &client) {
515 status_t res;
516 ATRACE_CALL();
517 Mutex::Autolock l(mInputMutex);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700518
519 // Wait for new metadata result (mNewFrame)
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700520 while (!mNewFrameReceived) {
521 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
522 if (res == TIMED_OUT) {
523 mTimeoutCount--;
524 break;
525 }
526 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700527
528 // Approximation of the shutter being closed
529 // - TODO: use the hal3 exposure callback in Camera3Device instead
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700530 if (mNewFrameReceived && !mShutterNotified) {
531 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800532 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800533 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700534 mShutterNotified = true;
535 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700536
537 // Wait until jpeg was captured by JpegProcessor
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700538 while (mNewFrameReceived && !mNewCaptureReceived) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700539 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
540 if (res == TIMED_OUT) {
541 mTimeoutCount--;
542 break;
543 }
544 }
545 if (mTimeoutCount <= 0) {
546 ALOGW("Timed out waiting for capture to complete");
547 return DONE;
548 }
549 if (mNewFrameReceived && mNewCaptureReceived) {
550 if (mNewFrameId != mCaptureId) {
551 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
552 mCaptureId, mNewFrameId);
553 }
554 camera_metadata_entry_t entry;
555 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
556 if (entry.count == 0) {
557 ALOGE("No timestamp field in capture frame!");
558 }
559 if (entry.data.i64[0] != mCaptureTimestamp) {
560 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700561 " captured buffer %lld",
562 entry.data.i64[0],
563 mCaptureTimestamp);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700564 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700565 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700566
567 mNewFrameReceived = false;
568 mNewCaptureReceived = false;
569 return DONE;
570 }
571 return STANDARD_CAPTURE_WAIT;
572}
573
James Painterc3dbf1a2012-09-05 18:02:32 -0700574CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
575 sp<Camera2Client> &client) {
576 ALOGV("%s", __FUNCTION__);
577 status_t res;
578 ATRACE_CALL();
579
580 // check which burst mode is set, create respective burst object
581 {
582 SharedParameters::Lock l(client->getParameters());
583
584 res = updateCaptureRequest(l.mParameters, client);
585 if(res != OK) {
586 return DONE;
587 }
588
589 //
590 // check for burst mode type in mParameters here
591 //
592 mBurstCapture = new BurstCapture(client, this);
593 }
594
595 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
596 if (res == OK) {
597 res = mCaptureRequest.sort();
598 }
599 if (res != OK) {
600 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
601 __FUNCTION__, client->getCameraId(), strerror(-res), res);
602 return DONE;
603 }
604
605 CameraMetadata captureCopy = mCaptureRequest;
606 if (captureCopy.entryCount() == 0) {
607 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
608 __FUNCTION__, client->getCameraId());
609 return DONE;
610 }
611
612 Vector<CameraMetadata> requests;
613 requests.push(mCaptureRequest);
614 res = mBurstCapture->start(requests, mCaptureId);
615 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
616 return BURST_CAPTURE_WAIT;
617}
618
619CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700620 sp<Camera2Client> &/*client*/) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700621 status_t res;
622 ATRACE_CALL();
623
624 while (!mNewCaptureReceived) {
625 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
626 if (res == TIMED_OUT) {
627 mTimeoutCount--;
628 break;
629 }
630 }
631
632 if (mTimeoutCount <= 0) {
633 ALOGW("Timed out waiting for burst capture to complete");
634 return DONE;
635 }
636 if (mNewCaptureReceived) {
637 mNewCaptureReceived = false;
638 // TODO: update mCaptureId to last burst's capture ID + 1?
639 return DONE;
640 }
641
642 return BURST_CAPTURE_WAIT;
643}
644
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700645status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
646 sp<Camera2Client> &client) {
647 ATRACE_CALL();
648 status_t res;
649 if (mCaptureRequest.entryCount() == 0) {
650 res = client->getCameraDevice()->createDefaultRequest(
651 CAMERA2_TEMPLATE_STILL_CAPTURE,
652 &mCaptureRequest);
653 if (res != OK) {
654 ALOGE("%s: Camera %d: Unable to create default still image request:"
655 " %s (%d)", __FUNCTION__, client->getCameraId(),
656 strerror(-res), res);
657 return res;
658 }
659 }
660
661 res = params.updateRequest(&mCaptureRequest);
662 if (res != OK) {
663 ALOGE("%s: Camera %d: Unable to update common entries of capture "
664 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
665 strerror(-res), res);
666 return res;
667 }
668
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700669 res = params.updateRequestJpeg(&mCaptureRequest);
670 if (res != OK) {
671 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
672 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
673 strerror(-res), res);
674 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700675 }
676
677 return OK;
678}
679
Igor Murashkin707c3e32012-09-20 15:18:50 -0700680/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
Igor Murashkin786a8da2012-11-26 10:50:55 -0800681 sp<Camera2Client> client, int msgType) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700682 ATRACE_CALL();
683
Igor Murashkin786a8da2012-11-26 10:50:55 -0800684 if (params.state == Parameters::STILL_CAPTURE
685 && params.playShutterSound
686 && (msgType & CAMERA_MSG_SHUTTER)) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700687 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
688 }
689
690 {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800691 Camera2Client::SharedCameraCallbacks::Lock
692 l(client->mSharedCameraCallbacks);
Igor Murashkin707c3e32012-09-20 15:18:50 -0700693
694 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800695 if (l.mRemoteCallback != 0) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700696 // ShutterCallback
Igor Murashkina2e203b2013-03-01 16:22:28 -0800697 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700698 /*ext1*/0, /*ext2*/0);
699
700 // RawCallback with null buffer
Igor Murashkina2e203b2013-03-01 16:22:28 -0800701 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700702 /*ext1*/0, /*ext2*/0);
703 } else {
704 ALOGV("%s: No client!", __FUNCTION__);
705 }
706 }
707}
708
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700709
710}; // namespace camera2
711}; // namespace android