blob: 18809125b57a1be3c66238dc127cc198138f58ac [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
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700273 if (mCaptureBuffer != 0 && res == OK) {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800274 Camera2Client::SharedCameraCallbacks::Lock
275 l(client->mSharedCameraCallbacks);
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700276 ALOGV("%s: Sending still image to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800277 if (l.mRemoteCallback != 0) {
278 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700279 mCaptureBuffer, NULL);
280 } else {
281 ALOGV("%s: No client!", __FUNCTION__);
282 }
283 }
284 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700285
286 return IDLE;
287}
288
289CaptureSequencer::CaptureState CaptureSequencer::manageStart(
290 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700291 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700292 status_t res;
293 ATRACE_CALL();
294 SharedParameters::Lock l(client->getParameters());
295 CaptureState nextState = DONE;
296
297 res = updateCaptureRequest(l.mParameters, client);
298 if (res != OK ) {
299 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
300 __FUNCTION__, client->getCameraId(), strerror(-res), res);
301 return DONE;
302 }
303
James Painterc3dbf1a2012-09-05 18:02:32 -0700304 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
305 l.mParameters.state == Parameters::STILL_CAPTURE) {
306 nextState = BURST_CAPTURE_START;
307 }
308 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700309 l.mParameters.state == Parameters::STILL_CAPTURE &&
310 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700311 nextState = ZSL_START;
312 } else {
313 nextState = STANDARD_START;
314 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700315 mShutterNotified = false;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700316
317 return nextState;
318}
319
320CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
321 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700322 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700323 status_t res;
324 sp<ZslProcessor> processor = mZslProcessor.promote();
325 if (processor == 0) {
326 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
327 return DONE;
328 }
329
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700330 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700331 this);
332
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700333 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700334 res = processor->pushToReprocess(mCaptureId);
335 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700336 if (res == NOT_ENOUGH_DATA) {
337 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
338 "falling back to normal capture", __FUNCTION__,
339 client->getCameraId());
340 } else {
341 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
342 __FUNCTION__, client->getCameraId(), strerror(-res), res);
343 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700344 return STANDARD_START;
345 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700346
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700347 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800348 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800349 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700350 mShutterNotified = true;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700351 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
352 return STANDARD_CAPTURE_WAIT;
353}
354
355CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700356 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700357 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700358 return DONE;
359}
360
361CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
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 START;
365}
366
367CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
368 sp<Camera2Client> &client) {
369 ATRACE_CALL();
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700370 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700371 this);
372 {
373 SharedParameters::Lock l(client->getParameters());
374 mTriggerId = l.mParameters.precaptureTriggerCounter++;
375 }
376 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
377
378 mAeInPrecapture = false;
379 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
380 return STANDARD_PRECAPTURE_WAIT;
381}
382
383CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700384 sp<Camera2Client> &/*client*/) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700385 status_t res;
386 ATRACE_CALL();
387 Mutex::Autolock l(mInputMutex);
388 while (!mNewAEState) {
389 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
390 if (res == TIMED_OUT) {
391 mTimeoutCount--;
392 break;
393 }
394 }
395 if (mTimeoutCount <= 0) {
396 ALOGW("Timed out waiting for precapture %s",
397 mAeInPrecapture ? "end" : "start");
398 return STANDARD_CAPTURE;
399 }
400 if (mNewAEState) {
401 if (!mAeInPrecapture) {
402 // Waiting to see PRECAPTURE state
403 if (mAETriggerId == mTriggerId &&
404 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
405 ALOGV("%s: Got precapture start", __FUNCTION__);
406 mAeInPrecapture = true;
407 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
408 }
409 } else {
410 // Waiting to see PRECAPTURE state end
411 if (mAETriggerId == mTriggerId &&
412 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
413 ALOGV("%s: Got precapture end", __FUNCTION__);
414 return STANDARD_CAPTURE;
415 }
416 }
417 mNewAEState = false;
418 }
419 return STANDARD_PRECAPTURE_WAIT;
420}
421
422CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
423 sp<Camera2Client> &client) {
424 status_t res;
425 ATRACE_CALL();
426 SharedParameters::Lock l(client->getParameters());
427 Vector<uint8_t> outputStreams;
428
429 outputStreams.push(client->getPreviewStreamId());
430 outputStreams.push(client->getCaptureStreamId());
431
432 if (l.mParameters.previewCallbackFlags &
433 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
434 outputStreams.push(client->getCallbackStreamId());
435 }
436
437 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
438 outputStreams.push(client->getRecordingStreamId());
439 }
440
441 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
442 outputStreams);
443 if (res == OK) {
444 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
445 &mCaptureId, 1);
446 }
447 if (res == OK) {
448 res = mCaptureRequest.sort();
449 }
450
451 if (res != OK) {
452 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
453 __FUNCTION__, client->getCameraId(), strerror(-res), res);
454 return DONE;
455 }
456
457 CameraMetadata captureCopy = mCaptureRequest;
458 if (captureCopy.entryCount() == 0) {
459 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
460 __FUNCTION__, client->getCameraId());
461 return DONE;
462 }
463
464 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700465 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700466 if (res != OK) {
467 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
468 "%s (%d)",
469 __FUNCTION__, client->getCameraId(), strerror(-res), res);
470 return DONE;
471 }
472 }
473 // TODO: Capture should be atomic with setStreamingRequest here
474 res = client->getCameraDevice()->capture(captureCopy);
475 if (res != OK) {
476 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
477 "%s (%d)",
478 __FUNCTION__, client->getCameraId(), strerror(-res), res);
479 return DONE;
480 }
481
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700482 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
483 return STANDARD_CAPTURE_WAIT;
484}
485
486CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
487 sp<Camera2Client> &client) {
488 status_t res;
489 ATRACE_CALL();
490 Mutex::Autolock l(mInputMutex);
491 while (!mNewFrameReceived) {
492 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
493 if (res == TIMED_OUT) {
494 mTimeoutCount--;
495 break;
496 }
497 }
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700498 if (mNewFrameReceived && !mShutterNotified) {
499 SharedParameters::Lock l(client->getParameters());
Igor Murashkina2e203b2013-03-01 16:22:28 -0800500 /* warning: this also locks a SharedCameraCallbacks */
Igor Murashkin786a8da2012-11-26 10:50:55 -0800501 shutterNotifyLocked(l.mParameters, client, mMsgType);
Eino-Ville Talvalaad21da92012-10-07 22:43:48 -0700502 mShutterNotified = true;
503 }
504 while (mNewFrameReceived && !mNewCaptureReceived) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700505 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
506 if (res == TIMED_OUT) {
507 mTimeoutCount--;
508 break;
509 }
510 }
511 if (mTimeoutCount <= 0) {
512 ALOGW("Timed out waiting for capture to complete");
513 return DONE;
514 }
515 if (mNewFrameReceived && mNewCaptureReceived) {
516 if (mNewFrameId != mCaptureId) {
517 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
518 mCaptureId, mNewFrameId);
519 }
520 camera_metadata_entry_t entry;
521 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
522 if (entry.count == 0) {
523 ALOGE("No timestamp field in capture frame!");
524 }
525 if (entry.data.i64[0] != mCaptureTimestamp) {
526 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
527 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
528 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700529 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700530
531 mNewFrameReceived = false;
532 mNewCaptureReceived = false;
533 return DONE;
534 }
535 return STANDARD_CAPTURE_WAIT;
536}
537
James Painterc3dbf1a2012-09-05 18:02:32 -0700538CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
539 sp<Camera2Client> &client) {
540 ALOGV("%s", __FUNCTION__);
541 status_t res;
542 ATRACE_CALL();
543
544 // check which burst mode is set, create respective burst object
545 {
546 SharedParameters::Lock l(client->getParameters());
547
548 res = updateCaptureRequest(l.mParameters, client);
549 if(res != OK) {
550 return DONE;
551 }
552
553 //
554 // check for burst mode type in mParameters here
555 //
556 mBurstCapture = new BurstCapture(client, this);
557 }
558
559 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
560 if (res == OK) {
561 res = mCaptureRequest.sort();
562 }
563 if (res != OK) {
564 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
565 __FUNCTION__, client->getCameraId(), strerror(-res), res);
566 return DONE;
567 }
568
569 CameraMetadata captureCopy = mCaptureRequest;
570 if (captureCopy.entryCount() == 0) {
571 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
572 __FUNCTION__, client->getCameraId());
573 return DONE;
574 }
575
576 Vector<CameraMetadata> requests;
577 requests.push(mCaptureRequest);
578 res = mBurstCapture->start(requests, mCaptureId);
579 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
580 return BURST_CAPTURE_WAIT;
581}
582
583CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700584 sp<Camera2Client> &/*client*/) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700585 status_t res;
586 ATRACE_CALL();
587
588 while (!mNewCaptureReceived) {
589 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
590 if (res == TIMED_OUT) {
591 mTimeoutCount--;
592 break;
593 }
594 }
595
596 if (mTimeoutCount <= 0) {
597 ALOGW("Timed out waiting for burst capture to complete");
598 return DONE;
599 }
600 if (mNewCaptureReceived) {
601 mNewCaptureReceived = false;
602 // TODO: update mCaptureId to last burst's capture ID + 1?
603 return DONE;
604 }
605
606 return BURST_CAPTURE_WAIT;
607}
608
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700609status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
610 sp<Camera2Client> &client) {
611 ATRACE_CALL();
612 status_t res;
613 if (mCaptureRequest.entryCount() == 0) {
614 res = client->getCameraDevice()->createDefaultRequest(
615 CAMERA2_TEMPLATE_STILL_CAPTURE,
616 &mCaptureRequest);
617 if (res != OK) {
618 ALOGE("%s: Camera %d: Unable to create default still image request:"
619 " %s (%d)", __FUNCTION__, client->getCameraId(),
620 strerror(-res), res);
621 return res;
622 }
623 }
624
625 res = params.updateRequest(&mCaptureRequest);
626 if (res != OK) {
627 ALOGE("%s: Camera %d: Unable to update common entries of capture "
628 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
629 strerror(-res), res);
630 return res;
631 }
632
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700633 res = params.updateRequestJpeg(&mCaptureRequest);
634 if (res != OK) {
635 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
636 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
637 strerror(-res), res);
638 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700639 }
640
641 return OK;
642}
643
Igor Murashkin707c3e32012-09-20 15:18:50 -0700644/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
Igor Murashkin786a8da2012-11-26 10:50:55 -0800645 sp<Camera2Client> client, int msgType) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700646 ATRACE_CALL();
647
Igor Murashkin786a8da2012-11-26 10:50:55 -0800648 if (params.state == Parameters::STILL_CAPTURE
649 && params.playShutterSound
650 && (msgType & CAMERA_MSG_SHUTTER)) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700651 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
652 }
653
654 {
Igor Murashkina2e203b2013-03-01 16:22:28 -0800655 Camera2Client::SharedCameraCallbacks::Lock
656 l(client->mSharedCameraCallbacks);
Igor Murashkin707c3e32012-09-20 15:18:50 -0700657
658 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
Igor Murashkina2e203b2013-03-01 16:22:28 -0800659 if (l.mRemoteCallback != 0) {
Igor Murashkin707c3e32012-09-20 15:18:50 -0700660 // ShutterCallback
Igor Murashkina2e203b2013-03-01 16:22:28 -0800661 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700662 /*ext1*/0, /*ext2*/0);
663
664 // RawCallback with null buffer
Igor Murashkina2e203b2013-03-01 16:22:28 -0800665 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
Igor Murashkin707c3e32012-09-20 15:18:50 -0700666 /*ext1*/0, /*ext2*/0);
667 } else {
668 ALOGV("%s: No client!", __FUNCTION__);
669 }
670 }
671}
672
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700673
674}; // namespace camera2
675}; // namespace android