blob: a849246e3f634afca3bab1bc9ef063bd6416903f [file] [log] [blame]
Eino-Ville Talvalada6665c2012-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 Talvala4bb81182012-09-24 09:46:53 -070017#define LOG_TAG "Camera2-CaptureSequencer"
Eino-Ville Talvalada6665c2012-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 Paintere5382062012-09-05 18:02:32 -070026#include "BurstCapture.h"
Eino-Ville Talvalada6665c2012-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 Talvala4865c522012-10-02 13:30:28 -070047 mCaptureId(Camera2Client::kCaptureRequestIdStart) {
James Paintere5382062012-09-05 18:02:32 -070048 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-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 Paintere5382062012-09-05 18:02:32 -070061 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-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
75void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
76 ATRACE_CALL();
77 Mutex::Autolock l(mInputMutex);
78 mAEState = newState;
79 mAETriggerId = triggerId;
80 if (!mNewAEState) {
81 mNewAEState = true;
82 mNewNotifySignal.signal();
83 }
84}
85
86void CaptureSequencer::onFrameAvailable(int32_t frameId,
Eino-Ville Talvala4865c522012-10-02 13:30:28 -070087 const CameraMetadata &frame) {
James Paintere5382062012-09-05 18:02:32 -070088 ALOGV("%s: Listener found new frame", __FUNCTION__);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070089 ATRACE_CALL();
90 Mutex::Autolock l(mInputMutex);
91 mNewFrameId = frameId;
Eino-Ville Talvala4865c522012-10-02 13:30:28 -070092 mNewFrame = frame;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070093 if (!mNewFrameReceived) {
94 mNewFrameReceived = true;
95 mNewFrameSignal.signal();
96 }
97}
98
Eino-Ville Talvalafe580e52012-09-19 17:09:15 -070099void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
100 sp<MemoryBase> captureBuffer) {
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700101 ATRACE_CALL();
James Paintere5382062012-09-05 18:02:32 -0700102 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700103 Mutex::Autolock l(mInputMutex);
104 mCaptureTimestamp = timestamp;
Eino-Ville Talvalafe580e52012-09-19 17:09:15 -0700105 mCaptureBuffer = captureBuffer;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700106 if (!mNewCaptureReceived) {
107 mNewCaptureReceived = true;
108 mNewCaptureSignal.signal();
109 }
110}
111
112
113void CaptureSequencer::dump(int fd, const Vector<String16>& args) {
114 String8 result;
115 if (mCaptureRequest.entryCount() != 0) {
116 result = " Capture request:\n";
117 write(fd, result.string(), result.size());
118 mCaptureRequest.dump(fd, 2, 6);
119 } else {
120 result = " Capture request: undefined\n";
121 write(fd, result.string(), result.size());
122 }
123 result = String8::format(" Current capture state: %s\n",
124 kStateNames[mCaptureState]);
125 result.append(" Latest captured frame:\n");
126 write(fd, result.string(), result.size());
127 mNewFrame.dump(fd, 2, 6);
128}
129
130/** Private members */
131
132const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
133{
134 "IDLE",
135 "START",
136 "ZSL_START",
137 "ZSL_WAITING",
138 "ZSL_REPROCESSING",
139 "STANDARD_START",
140 "STANDARD_PRECAPTURE",
141 "STANDARD_CAPTURING",
James Paintere5382062012-09-05 18:02:32 -0700142 "BURST_CAPTURE_START",
143 "BURST_CAPTURE_WAIT",
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700144 "DONE",
145 "ERROR",
146 "UNKNOWN"
147};
148
149const CaptureSequencer::StateManager
150 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
151 &CaptureSequencer::manageIdle,
152 &CaptureSequencer::manageStart,
153 &CaptureSequencer::manageZslStart,
154 &CaptureSequencer::manageZslWaiting,
155 &CaptureSequencer::manageZslReprocessing,
156 &CaptureSequencer::manageStandardStart,
157 &CaptureSequencer::manageStandardPrecaptureWait,
158 &CaptureSequencer::manageStandardCapture,
159 &CaptureSequencer::manageStandardCaptureWait,
James Paintere5382062012-09-05 18:02:32 -0700160 &CaptureSequencer::manageBurstCaptureStart,
161 &CaptureSequencer::manageBurstCaptureWait,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700162 &CaptureSequencer::manageDone,
163};
164
165bool CaptureSequencer::threadLoop() {
166 status_t res;
167
168 sp<Camera2Client> client = mClient.promote();
169 if (client == 0) return false;
170
171 if (mCaptureState < ERROR) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700172 CaptureState oldState = mCaptureState;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700173 mCaptureState = (this->*kStateManagers[mCaptureState])(client);
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700174 if (ATRACE_ENABLED() && oldState != mCaptureState) {
175 ATRACE_INT("cam2_capt_state", mCaptureState);
176 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700177 } else {
178 ALOGE("%s: Bad capture state: %s",
179 __FUNCTION__, kStateNames[mCaptureState]);
180 return false;
181 }
182
183 return true;
184}
185
186CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
187 status_t res;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700188 Mutex::Autolock l(mInputMutex);
189 while (!mStartCapture) {
190 res = mStartCaptureSignal.waitRelative(mInputMutex,
191 kWaitDuration);
192 if (res == TIMED_OUT) break;
193 }
194 if (mStartCapture) {
195 mStartCapture = false;
196 mBusy = true;
197 return START;
198 }
199 return IDLE;
200}
201
202CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvalafe580e52012-09-19 17:09:15 -0700203 status_t res = OK;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700204 ATRACE_CALL();
205 mCaptureId++;
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700206 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
207 mCaptureId = Camera2Client::kCaptureRequestIdStart;
208 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700209 {
210 Mutex::Autolock l(mInputMutex);
211 mBusy = false;
212 }
213
Eino-Ville Talvalafe580e52012-09-19 17:09:15 -0700214 {
215 SharedParameters::Lock l(client->getParameters());
216 switch (l.mParameters.state) {
217 case Parameters::STILL_CAPTURE:
218 l.mParameters.state = Parameters::STOPPED;
219 break;
220 case Parameters::VIDEO_SNAPSHOT:
221 l.mParameters.state = Parameters::RECORD;
222 break;
223 default:
224 ALOGE("%s: Camera %d: Still image produced unexpectedly "
225 "in state %s!",
226 __FUNCTION__, client->getCameraId(),
227 Parameters::getStateName(l.mParameters.state));
228 res = INVALID_OPERATION;
229 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700230 }
Eino-Ville Talvala768cf092012-09-19 17:11:04 -0700231 sp<ZslProcessor> processor = mZslProcessor.promote();
232 if (processor != 0) {
233 processor->clearZslQueue();
234 }
235
Eino-Ville Talvalafe580e52012-09-19 17:09:15 -0700236 if (mCaptureBuffer != 0 && res == OK) {
237 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
238 ALOGV("%s: Sending still image to client", __FUNCTION__);
239 if (l.mCameraClient != 0) {
240 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
241 mCaptureBuffer, NULL);
242 } else {
243 ALOGV("%s: No client!", __FUNCTION__);
244 }
245 }
246 mCaptureBuffer.clear();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700247
248 return IDLE;
249}
250
251CaptureSequencer::CaptureState CaptureSequencer::manageStart(
252 sp<Camera2Client> &client) {
James Paintere5382062012-09-05 18:02:32 -0700253 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700254 status_t res;
255 ATRACE_CALL();
256 SharedParameters::Lock l(client->getParameters());
257 CaptureState nextState = DONE;
258
259 res = updateCaptureRequest(l.mParameters, client);
260 if (res != OK ) {
261 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
262 __FUNCTION__, client->getCameraId(), strerror(-res), res);
263 return DONE;
264 }
265
James Paintere5382062012-09-05 18:02:32 -0700266 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
267 l.mParameters.state == Parameters::STILL_CAPTURE) {
268 nextState = BURST_CAPTURE_START;
269 }
270 else if (l.mParameters.zslMode &&
Eino-Ville Talvala6b367f22012-09-21 16:30:42 -0700271 l.mParameters.state == Parameters::STILL_CAPTURE &&
272 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700273 nextState = ZSL_START;
274 } else {
275 nextState = STANDARD_START;
276 }
277
278 return nextState;
279}
280
281CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
282 sp<Camera2Client> &client) {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700283 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700284 status_t res;
285 sp<ZslProcessor> processor = mZslProcessor.promote();
286 if (processor == 0) {
287 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
288 return DONE;
289 }
290
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700291 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700292 this);
293
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700294 // TODO: Actually select the right thing here.
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700295 res = processor->pushToReprocess(mCaptureId);
296 if (res != OK) {
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700297 if (res == NOT_ENOUGH_DATA) {
298 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
299 "falling back to normal capture", __FUNCTION__,
300 client->getCameraId());
301 } else {
302 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
303 __FUNCTION__, client->getCameraId(), strerror(-res), res);
304 }
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700305 return STANDARD_START;
306 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700307
Eino-Ville Talvalada1c5c12012-09-19 17:12:50 -0700308 SharedParameters::Lock l(client->getParameters());
Igor Murashkin1b65ae92012-09-20 15:18:50 -0700309 /* warning: this also locks a SharedCameraClient */
310 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvalada1c5c12012-09-19 17:12:50 -0700311
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700312 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
313 return STANDARD_CAPTURE_WAIT;
314}
315
316CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
317 sp<Camera2Client> &client) {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700318 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700319 return DONE;
320}
321
322CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
323 sp<Camera2Client> &client) {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700324 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700325 return START;
326}
327
328CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
329 sp<Camera2Client> &client) {
330 ATRACE_CALL();
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700331 client->registerFrameListener(mCaptureId, mCaptureId + 1,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700332 this);
333 {
334 SharedParameters::Lock l(client->getParameters());
335 mTriggerId = l.mParameters.precaptureTriggerCounter++;
336 }
337 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
338
339 mAeInPrecapture = false;
340 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
341 return STANDARD_PRECAPTURE_WAIT;
342}
343
344CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
345 sp<Camera2Client> &client) {
346 status_t res;
347 ATRACE_CALL();
348 Mutex::Autolock l(mInputMutex);
349 while (!mNewAEState) {
350 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
351 if (res == TIMED_OUT) {
352 mTimeoutCount--;
353 break;
354 }
355 }
356 if (mTimeoutCount <= 0) {
357 ALOGW("Timed out waiting for precapture %s",
358 mAeInPrecapture ? "end" : "start");
359 return STANDARD_CAPTURE;
360 }
361 if (mNewAEState) {
362 if (!mAeInPrecapture) {
363 // Waiting to see PRECAPTURE state
364 if (mAETriggerId == mTriggerId &&
365 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
366 ALOGV("%s: Got precapture start", __FUNCTION__);
367 mAeInPrecapture = true;
368 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
369 }
370 } else {
371 // Waiting to see PRECAPTURE state end
372 if (mAETriggerId == mTriggerId &&
373 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
374 ALOGV("%s: Got precapture end", __FUNCTION__);
375 return STANDARD_CAPTURE;
376 }
377 }
378 mNewAEState = false;
379 }
380 return STANDARD_PRECAPTURE_WAIT;
381}
382
383CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
384 sp<Camera2Client> &client) {
385 status_t res;
386 ATRACE_CALL();
387 SharedParameters::Lock l(client->getParameters());
388 Vector<uint8_t> outputStreams;
389
390 outputStreams.push(client->getPreviewStreamId());
391 outputStreams.push(client->getCaptureStreamId());
392
393 if (l.mParameters.previewCallbackFlags &
394 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
395 outputStreams.push(client->getCallbackStreamId());
396 }
397
398 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
399 outputStreams.push(client->getRecordingStreamId());
400 }
401
402 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
403 outputStreams);
404 if (res == OK) {
405 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
406 &mCaptureId, 1);
407 }
408 if (res == OK) {
409 res = mCaptureRequest.sort();
410 }
411
412 if (res != OK) {
413 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
414 __FUNCTION__, client->getCameraId(), strerror(-res), res);
415 return DONE;
416 }
417
418 CameraMetadata captureCopy = mCaptureRequest;
419 if (captureCopy.entryCount() == 0) {
420 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
421 __FUNCTION__, client->getCameraId());
422 return DONE;
423 }
424
425 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700426 res = client->stopStream();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700427 if (res != OK) {
428 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
429 "%s (%d)",
430 __FUNCTION__, client->getCameraId(), strerror(-res), res);
431 return DONE;
432 }
433 }
434 // TODO: Capture should be atomic with setStreamingRequest here
435 res = client->getCameraDevice()->capture(captureCopy);
436 if (res != OK) {
437 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
438 "%s (%d)",
439 __FUNCTION__, client->getCameraId(), strerror(-res), res);
440 return DONE;
441 }
442
Igor Murashkin1b65ae92012-09-20 15:18:50 -0700443 /* warning: this also locks a SharedCameraClient */
444 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvala609acc02012-09-06 18:26:58 -0700445
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700446 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
447 return STANDARD_CAPTURE_WAIT;
448}
449
450CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
451 sp<Camera2Client> &client) {
452 status_t res;
453 ATRACE_CALL();
454 Mutex::Autolock l(mInputMutex);
455 while (!mNewFrameReceived) {
456 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
457 if (res == TIMED_OUT) {
458 mTimeoutCount--;
459 break;
460 }
461 }
462 while (!mNewCaptureReceived) {
463 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
464 if (res == TIMED_OUT) {
465 mTimeoutCount--;
466 break;
467 }
468 }
469 if (mTimeoutCount <= 0) {
470 ALOGW("Timed out waiting for capture to complete");
471 return DONE;
472 }
473 if (mNewFrameReceived && mNewCaptureReceived) {
474 if (mNewFrameId != mCaptureId) {
475 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
476 mCaptureId, mNewFrameId);
477 }
478 camera_metadata_entry_t entry;
479 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
480 if (entry.count == 0) {
481 ALOGE("No timestamp field in capture frame!");
482 }
483 if (entry.data.i64[0] != mCaptureTimestamp) {
484 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
485 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
486 }
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700487 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700488
489 mNewFrameReceived = false;
490 mNewCaptureReceived = false;
491 return DONE;
492 }
493 return STANDARD_CAPTURE_WAIT;
494}
495
James Paintere5382062012-09-05 18:02:32 -0700496CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
497 sp<Camera2Client> &client) {
498 ALOGV("%s", __FUNCTION__);
499 status_t res;
500 ATRACE_CALL();
501
502 // check which burst mode is set, create respective burst object
503 {
504 SharedParameters::Lock l(client->getParameters());
505
506 res = updateCaptureRequest(l.mParameters, client);
507 if(res != OK) {
508 return DONE;
509 }
510
511 //
512 // check for burst mode type in mParameters here
513 //
514 mBurstCapture = new BurstCapture(client, this);
515 }
516
517 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
518 if (res == OK) {
519 res = mCaptureRequest.sort();
520 }
521 if (res != OK) {
522 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
523 __FUNCTION__, client->getCameraId(), strerror(-res), res);
524 return DONE;
525 }
526
527 CameraMetadata captureCopy = mCaptureRequest;
528 if (captureCopy.entryCount() == 0) {
529 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
530 __FUNCTION__, client->getCameraId());
531 return DONE;
532 }
533
534 Vector<CameraMetadata> requests;
535 requests.push(mCaptureRequest);
536 res = mBurstCapture->start(requests, mCaptureId);
537 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
538 return BURST_CAPTURE_WAIT;
539}
540
541CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
542 sp<Camera2Client> &client) {
543 status_t res;
544 ATRACE_CALL();
545
546 while (!mNewCaptureReceived) {
547 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
548 if (res == TIMED_OUT) {
549 mTimeoutCount--;
550 break;
551 }
552 }
553
554 if (mTimeoutCount <= 0) {
555 ALOGW("Timed out waiting for burst capture to complete");
556 return DONE;
557 }
558 if (mNewCaptureReceived) {
559 mNewCaptureReceived = false;
560 // TODO: update mCaptureId to last burst's capture ID + 1?
561 return DONE;
562 }
563
564 return BURST_CAPTURE_WAIT;
565}
566
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700567status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
568 sp<Camera2Client> &client) {
569 ATRACE_CALL();
570 status_t res;
571 if (mCaptureRequest.entryCount() == 0) {
572 res = client->getCameraDevice()->createDefaultRequest(
573 CAMERA2_TEMPLATE_STILL_CAPTURE,
574 &mCaptureRequest);
575 if (res != OK) {
576 ALOGE("%s: Camera %d: Unable to create default still image request:"
577 " %s (%d)", __FUNCTION__, client->getCameraId(),
578 strerror(-res), res);
579 return res;
580 }
581 }
582
583 res = params.updateRequest(&mCaptureRequest);
584 if (res != OK) {
585 ALOGE("%s: Camera %d: Unable to update common entries of capture "
586 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
587 strerror(-res), res);
588 return res;
589 }
590
Eino-Ville Talvalaec771082012-10-04 13:21:08 -0700591 res = params.updateRequestJpeg(&mCaptureRequest);
592 if (res != OK) {
593 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
594 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
595 strerror(-res), res);
596 return res;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700597 }
598
599 return OK;
600}
601
Igor Murashkin1b65ae92012-09-20 15:18:50 -0700602/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
603 sp<Camera2Client> client) {
604 ATRACE_CALL();
605
606 if (params.state == Parameters::STILL_CAPTURE && params.playShutterSound) {
607 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
608 }
609
610 {
611 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
612
613 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
614 if (l.mCameraClient != 0) {
615 // ShutterCallback
616 l.mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER,
617 /*ext1*/0, /*ext2*/0);
618
619 // RawCallback with null buffer
620 l.mCameraClient->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
621 /*ext1*/0, /*ext2*/0);
622 } else {
623 ALOGV("%s: No client!", __FUNCTION__);
624 }
625 }
626}
627
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700628
629}; // namespace camera2
630}; // namespace android