blob: 5156539b30e5385187943b5d1daaf3bdaca3e0a2 [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),
43 mClient(client),
44 mCaptureState(IDLE),
45 mTriggerId(0),
46 mTimeoutCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -070047 mCaptureId(Camera2Client::kCaptureRequestIdStart) {
James Painterc3dbf1a2012-09-05 18:02:32 -070048 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070049}
50
51CaptureSequencer::~CaptureSequencer() {
52 ALOGV("%s: Exit", __FUNCTION__);
53}
54
55void CaptureSequencer::setZslProcessor(wp<ZslProcessor> processor) {
56 Mutex::Autolock l(mInputMutex);
57 mZslProcessor = processor;
58}
59
60status_t CaptureSequencer::startCapture() {
James Painterc3dbf1a2012-09-05 18:02:32 -070061 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070062 ATRACE_CALL();
63 Mutex::Autolock l(mInputMutex);
64 if (mBusy) {
65 ALOGE("%s: Already busy capturing!", __FUNCTION__);
66 return INVALID_OPERATION;
67 }
68 if (!mStartCapture) {
69 mStartCapture = true;
70 mStartCaptureSignal.signal();
71 }
72 return OK;
73}
74
Eino-Ville Talvalae0493842012-10-05 12:03:10 -070075status_t CaptureSequencer::waitUntilIdle(nsecs_t timeout) {
76 ATRACE_CALL();
77 ALOGV("%s: Waiting for idle", __FUNCTION__);
78 Mutex::Autolock l(mStateMutex);
79 status_t res = -1;
80 while (mCaptureState != IDLE) {
81 nsecs_t startTime = systemTime();
82
83 res = mStateChanged.waitRelative(mStateMutex, timeout);
84 if (res != OK) return res;
85
86 timeout -= (systemTime() - startTime);
87 }
88 ALOGV("%s: Now idle", __FUNCTION__);
89 return OK;
90}
91
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070092void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
93 ATRACE_CALL();
94 Mutex::Autolock l(mInputMutex);
95 mAEState = newState;
96 mAETriggerId = triggerId;
97 if (!mNewAEState) {
98 mNewAEState = true;
99 mNewNotifySignal.signal();
100 }
101}
102
103void CaptureSequencer::onFrameAvailable(int32_t frameId,
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700104 const CameraMetadata &frame) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700105 ALOGV("%s: Listener found new frame", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700106 ATRACE_CALL();
107 Mutex::Autolock l(mInputMutex);
108 mNewFrameId = frameId;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700109 mNewFrame = frame;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700110 if (!mNewFrameReceived) {
111 mNewFrameReceived = true;
112 mNewFrameSignal.signal();
113 }
114}
115
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700116void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
117 sp<MemoryBase> captureBuffer) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700118 ATRACE_CALL();
James Painterc3dbf1a2012-09-05 18:02:32 -0700119 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700120 Mutex::Autolock l(mInputMutex);
121 mCaptureTimestamp = timestamp;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700122 mCaptureBuffer = captureBuffer;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700123 if (!mNewCaptureReceived) {
124 mNewCaptureReceived = true;
125 mNewCaptureSignal.signal();
126 }
127}
128
129
130void CaptureSequencer::dump(int fd, const Vector<String16>& args) {
131 String8 result;
132 if (mCaptureRequest.entryCount() != 0) {
133 result = " Capture request:\n";
134 write(fd, result.string(), result.size());
135 mCaptureRequest.dump(fd, 2, 6);
136 } else {
137 result = " Capture request: undefined\n";
138 write(fd, result.string(), result.size());
139 }
140 result = String8::format(" Current capture state: %s\n",
141 kStateNames[mCaptureState]);
142 result.append(" Latest captured frame:\n");
143 write(fd, result.string(), result.size());
144 mNewFrame.dump(fd, 2, 6);
145}
146
147/** Private members */
148
149const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
150{
151 "IDLE",
152 "START",
153 "ZSL_START",
154 "ZSL_WAITING",
155 "ZSL_REPROCESSING",
156 "STANDARD_START",
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700157 "STANDARD_PRECAPTURE_WAIT",
158 "STANDARD_CAPTURE",
159 "STANDARD_CAPTURE_WAIT",
James Painterc3dbf1a2012-09-05 18:02:32 -0700160 "BURST_CAPTURE_START",
161 "BURST_CAPTURE_WAIT",
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700162 "DONE",
163 "ERROR",
164 "UNKNOWN"
165};
166
167const CaptureSequencer::StateManager
168 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
169 &CaptureSequencer::manageIdle,
170 &CaptureSequencer::manageStart,
171 &CaptureSequencer::manageZslStart,
172 &CaptureSequencer::manageZslWaiting,
173 &CaptureSequencer::manageZslReprocessing,
174 &CaptureSequencer::manageStandardStart,
175 &CaptureSequencer::manageStandardPrecaptureWait,
176 &CaptureSequencer::manageStandardCapture,
177 &CaptureSequencer::manageStandardCaptureWait,
James Painterc3dbf1a2012-09-05 18:02:32 -0700178 &CaptureSequencer::manageBurstCaptureStart,
179 &CaptureSequencer::manageBurstCaptureWait,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700180 &CaptureSequencer::manageDone,
181};
182
183bool CaptureSequencer::threadLoop() {
184 status_t res;
185
186 sp<Camera2Client> client = mClient.promote();
187 if (client == 0) return false;
188
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700189 CaptureState currentState;
190 {
191 Mutex::Autolock l(mStateMutex);
192 currentState = mCaptureState;
193 }
194
195 currentState = (this->*kStateManagers[currentState])(client);
196
197 Mutex::Autolock l(mStateMutex);
198 if (currentState != mCaptureState) {
199 mCaptureState = currentState;
200 ATRACE_INT("cam2_capt_state", mCaptureState);
201 ALOGV("Camera %d: New capture state %s",
202 client->getCameraId(), kStateNames[mCaptureState]);
203 mStateChanged.signal();
204 }
205
206 if (mCaptureState == ERROR) {
207 ALOGE("Camera %d: Stopping capture sequencer due to error",
208 client->getCameraId());
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700209 return false;
210 }
211
212 return true;
213}
214
215CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
216 status_t res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700217 Mutex::Autolock l(mInputMutex);
218 while (!mStartCapture) {
219 res = mStartCaptureSignal.waitRelative(mInputMutex,
220 kWaitDuration);
221 if (res == TIMED_OUT) break;
222 }
223 if (mStartCapture) {
224 mStartCapture = false;
225 mBusy = true;
226 return START;
227 }
228 return IDLE;
229}
230
231CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700232 status_t res = OK;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700233 ATRACE_CALL();
234 mCaptureId++;
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700235 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
236 mCaptureId = Camera2Client::kCaptureRequestIdStart;
237 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700238 {
239 Mutex::Autolock l(mInputMutex);
240 mBusy = false;
241 }
242
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700243 {
244 SharedParameters::Lock l(client->getParameters());
245 switch (l.mParameters.state) {
Eino-Ville Talvalae0493842012-10-05 12:03:10 -0700246 case Parameters::DISCONNECTED:
247 ALOGW("%s: Camera %d: Discarding image data during shutdown ",
248 __FUNCTION__, client->getCameraId());
249 res = INVALID_OPERATION;
250 break;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700251 case Parameters::STILL_CAPTURE:
252 l.mParameters.state = Parameters::STOPPED;
253 break;
254 case Parameters::VIDEO_SNAPSHOT:
255 l.mParameters.state = Parameters::RECORD;
256 break;
257 default:
258 ALOGE("%s: Camera %d: Still image produced unexpectedly "
259 "in state %s!",
260 __FUNCTION__, client->getCameraId(),
261 Parameters::getStateName(l.mParameters.state));
262 res = INVALID_OPERATION;
263 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700264 }
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700265 sp<ZslProcessor> processor = mZslProcessor.promote();
266 if (processor != 0) {
267 processor->clearZslQueue();
268 }
269
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700270 if (mCaptureBuffer != 0 && res == OK) {
271 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
272 ALOGV("%s: Sending still image to client", __FUNCTION__);
273 if (l.mCameraClient != 0) {
274 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
275 mCaptureBuffer, NULL);
276 } else {
277 ALOGV("%s: No client!", __FUNCTION__);
278 }
279 }
280 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700281
282 return IDLE;
283}
284
285CaptureSequencer::CaptureState CaptureSequencer::manageStart(
286 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700287 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700288 status_t res;
289 ATRACE_CALL();
290 SharedParameters::Lock l(client->getParameters());
291 CaptureState nextState = DONE;
292
293 res = updateCaptureRequest(l.mParameters, client);
294 if (res != OK ) {
295 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
296 __FUNCTION__, client->getCameraId(), strerror(-res), res);
297 return DONE;
298 }
299
James Painterc3dbf1a2012-09-05 18:02:32 -0700300 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
301 l.mParameters.state == Parameters::STILL_CAPTURE) {
302 nextState = BURST_CAPTURE_START;
303 }
304 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700305 l.mParameters.state == Parameters::STILL_CAPTURE &&
306 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700307 nextState = ZSL_START;
308 } else {
309 nextState = STANDARD_START;
310 }
311
312 return nextState;
313}
314
315CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
316 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700317 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700318 status_t res;
319 sp<ZslProcessor> processor = mZslProcessor.promote();
320 if (processor == 0) {
321 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
322 return DONE;
323 }
324
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700325 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700326 this);
327
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700328 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700329 res = processor->pushToReprocess(mCaptureId);
330 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700331 if (res == NOT_ENOUGH_DATA) {
332 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
333 "falling back to normal capture", __FUNCTION__,
334 client->getCameraId());
335 } else {
336 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
337 __FUNCTION__, client->getCameraId(), strerror(-res), res);
338 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700339 return STANDARD_START;
340 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700341
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700342 SharedParameters::Lock l(client->getParameters());
Igor Murashkin707c3e32012-09-20 15:18:50 -0700343 /* warning: this also locks a SharedCameraClient */
344 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700345
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700346 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
347 return STANDARD_CAPTURE_WAIT;
348}
349
350CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
351 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700352 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700353 return DONE;
354}
355
356CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
357 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700358 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700359 return START;
360}
361
362CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
363 sp<Camera2Client> &client) {
364 ATRACE_CALL();
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700365 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700366 this);
367 {
368 SharedParameters::Lock l(client->getParameters());
369 mTriggerId = l.mParameters.precaptureTriggerCounter++;
370 }
371 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
372
373 mAeInPrecapture = false;
374 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
375 return STANDARD_PRECAPTURE_WAIT;
376}
377
378CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
379 sp<Camera2Client> &client) {
380 status_t res;
381 ATRACE_CALL();
382 Mutex::Autolock l(mInputMutex);
383 while (!mNewAEState) {
384 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
385 if (res == TIMED_OUT) {
386 mTimeoutCount--;
387 break;
388 }
389 }
390 if (mTimeoutCount <= 0) {
391 ALOGW("Timed out waiting for precapture %s",
392 mAeInPrecapture ? "end" : "start");
393 return STANDARD_CAPTURE;
394 }
395 if (mNewAEState) {
396 if (!mAeInPrecapture) {
397 // Waiting to see PRECAPTURE state
398 if (mAETriggerId == mTriggerId &&
399 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
400 ALOGV("%s: Got precapture start", __FUNCTION__);
401 mAeInPrecapture = true;
402 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
403 }
404 } else {
405 // Waiting to see PRECAPTURE state end
406 if (mAETriggerId == mTriggerId &&
407 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
408 ALOGV("%s: Got precapture end", __FUNCTION__);
409 return STANDARD_CAPTURE;
410 }
411 }
412 mNewAEState = false;
413 }
414 return STANDARD_PRECAPTURE_WAIT;
415}
416
417CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
418 sp<Camera2Client> &client) {
419 status_t res;
420 ATRACE_CALL();
421 SharedParameters::Lock l(client->getParameters());
422 Vector<uint8_t> outputStreams;
423
424 outputStreams.push(client->getPreviewStreamId());
425 outputStreams.push(client->getCaptureStreamId());
426
427 if (l.mParameters.previewCallbackFlags &
428 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
429 outputStreams.push(client->getCallbackStreamId());
430 }
431
432 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
433 outputStreams.push(client->getRecordingStreamId());
434 }
435
436 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
437 outputStreams);
438 if (res == OK) {
439 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
440 &mCaptureId, 1);
441 }
442 if (res == OK) {
443 res = mCaptureRequest.sort();
444 }
445
446 if (res != OK) {
447 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
448 __FUNCTION__, client->getCameraId(), strerror(-res), res);
449 return DONE;
450 }
451
452 CameraMetadata captureCopy = mCaptureRequest;
453 if (captureCopy.entryCount() == 0) {
454 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
455 __FUNCTION__, client->getCameraId());
456 return DONE;
457 }
458
459 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700460 res = client->stopStream();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700461 if (res != OK) {
462 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
463 "%s (%d)",
464 __FUNCTION__, client->getCameraId(), strerror(-res), res);
465 return DONE;
466 }
467 }
468 // TODO: Capture should be atomic with setStreamingRequest here
469 res = client->getCameraDevice()->capture(captureCopy);
470 if (res != OK) {
471 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
472 "%s (%d)",
473 __FUNCTION__, client->getCameraId(), strerror(-res), res);
474 return DONE;
475 }
476
Igor Murashkin707c3e32012-09-20 15:18:50 -0700477 /* warning: this also locks a SharedCameraClient */
478 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvala33578832012-09-06 18:26:58 -0700479
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700480 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
481 return STANDARD_CAPTURE_WAIT;
482}
483
484CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
485 sp<Camera2Client> &client) {
486 status_t res;
487 ATRACE_CALL();
488 Mutex::Autolock l(mInputMutex);
489 while (!mNewFrameReceived) {
490 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
491 if (res == TIMED_OUT) {
492 mTimeoutCount--;
493 break;
494 }
495 }
496 while (!mNewCaptureReceived) {
497 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
498 if (res == TIMED_OUT) {
499 mTimeoutCount--;
500 break;
501 }
502 }
503 if (mTimeoutCount <= 0) {
504 ALOGW("Timed out waiting for capture to complete");
505 return DONE;
506 }
507 if (mNewFrameReceived && mNewCaptureReceived) {
508 if (mNewFrameId != mCaptureId) {
509 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
510 mCaptureId, mNewFrameId);
511 }
512 camera_metadata_entry_t entry;
513 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
514 if (entry.count == 0) {
515 ALOGE("No timestamp field in capture frame!");
516 }
517 if (entry.data.i64[0] != mCaptureTimestamp) {
518 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
519 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
520 }
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700521 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700522
523 mNewFrameReceived = false;
524 mNewCaptureReceived = false;
525 return DONE;
526 }
527 return STANDARD_CAPTURE_WAIT;
528}
529
James Painterc3dbf1a2012-09-05 18:02:32 -0700530CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
531 sp<Camera2Client> &client) {
532 ALOGV("%s", __FUNCTION__);
533 status_t res;
534 ATRACE_CALL();
535
536 // check which burst mode is set, create respective burst object
537 {
538 SharedParameters::Lock l(client->getParameters());
539
540 res = updateCaptureRequest(l.mParameters, client);
541 if(res != OK) {
542 return DONE;
543 }
544
545 //
546 // check for burst mode type in mParameters here
547 //
548 mBurstCapture = new BurstCapture(client, this);
549 }
550
551 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
552 if (res == OK) {
553 res = mCaptureRequest.sort();
554 }
555 if (res != OK) {
556 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
557 __FUNCTION__, client->getCameraId(), strerror(-res), res);
558 return DONE;
559 }
560
561 CameraMetadata captureCopy = mCaptureRequest;
562 if (captureCopy.entryCount() == 0) {
563 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
564 __FUNCTION__, client->getCameraId());
565 return DONE;
566 }
567
568 Vector<CameraMetadata> requests;
569 requests.push(mCaptureRequest);
570 res = mBurstCapture->start(requests, mCaptureId);
571 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
572 return BURST_CAPTURE_WAIT;
573}
574
575CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
576 sp<Camera2Client> &client) {
577 status_t res;
578 ATRACE_CALL();
579
580 while (!mNewCaptureReceived) {
581 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
582 if (res == TIMED_OUT) {
583 mTimeoutCount--;
584 break;
585 }
586 }
587
588 if (mTimeoutCount <= 0) {
589 ALOGW("Timed out waiting for burst capture to complete");
590 return DONE;
591 }
592 if (mNewCaptureReceived) {
593 mNewCaptureReceived = false;
594 // TODO: update mCaptureId to last burst's capture ID + 1?
595 return DONE;
596 }
597
598 return BURST_CAPTURE_WAIT;
599}
600
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700601status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
602 sp<Camera2Client> &client) {
603 ATRACE_CALL();
604 status_t res;
605 if (mCaptureRequest.entryCount() == 0) {
606 res = client->getCameraDevice()->createDefaultRequest(
607 CAMERA2_TEMPLATE_STILL_CAPTURE,
608 &mCaptureRequest);
609 if (res != OK) {
610 ALOGE("%s: Camera %d: Unable to create default still image request:"
611 " %s (%d)", __FUNCTION__, client->getCameraId(),
612 strerror(-res), res);
613 return res;
614 }
615 }
616
617 res = params.updateRequest(&mCaptureRequest);
618 if (res != OK) {
619 ALOGE("%s: Camera %d: Unable to update common entries of capture "
620 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
621 strerror(-res), res);
622 return res;
623 }
624
Eino-Ville Talvaladb30e682012-10-04 13:21:08 -0700625 res = params.updateRequestJpeg(&mCaptureRequest);
626 if (res != OK) {
627 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
628 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
629 strerror(-res), res);
630 return res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700631 }
632
633 return OK;
634}
635
Igor Murashkin707c3e32012-09-20 15:18:50 -0700636/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
637 sp<Camera2Client> client) {
638 ATRACE_CALL();
639
640 if (params.state == Parameters::STILL_CAPTURE && params.playShutterSound) {
641 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
642 }
643
644 {
645 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
646
647 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
648 if (l.mCameraClient != 0) {
649 // ShutterCallback
650 l.mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER,
651 /*ext1*/0, /*ext2*/0);
652
653 // RawCallback with null buffer
654 l.mCameraClient->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
655 /*ext1*/0, /*ext2*/0);
656 } else {
657 ALOGV("%s: No client!", __FUNCTION__);
658 }
659 }
660}
661
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700662
663}; // namespace camera2
664}; // namespace android