1 /*
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
17 #define LOG_TAG "Camera2-CaptureSequencer"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include <inttypes.h>
22
23 #include <utils/Log.h>
24 #include <utils/Trace.h>
25 #include <utils/Vector.h>
26
27 #include "api1/Camera2Client.h"
28 #include "api1/client2/CaptureSequencer.h"
29 #include "api1/client2/BurstCapture.h"
30 #include "api1/client2/Parameters.h"
31 #include "api1/client2/ZslProcessorInterface.h"
32
33 namespace android {
34 namespace camera2 {
35
36 /** Public members */
37
CaptureSequencer(wp<Camera2Client> client)38 CaptureSequencer::CaptureSequencer(wp<Camera2Client> client):
39 Thread(false),
40 mStartCapture(false),
41 mBusy(false),
42 mNewAEState(false),
43 mNewFrameReceived(false),
44 mNewCaptureReceived(false),
45 mShutterNotified(false),
46 mClient(client),
47 mCaptureState(IDLE),
48 mStateTransitionCount(0),
49 mTriggerId(0),
50 mTimeoutCount(0),
51 mCaptureId(Camera2Client::kCaptureRequestIdStart),
52 mMsgType(0) {
53 ALOGV("%s", __FUNCTION__);
54 }
55
~CaptureSequencer()56 CaptureSequencer::~CaptureSequencer() {
57 ALOGV("%s: Exit", __FUNCTION__);
58 }
59
setZslProcessor(wp<ZslProcessorInterface> processor)60 void CaptureSequencer::setZslProcessor(wp<ZslProcessorInterface> processor) {
61 Mutex::Autolock l(mInputMutex);
62 mZslProcessor = processor;
63 }
64
startCapture(int msgType)65 status_t CaptureSequencer::startCapture(int msgType) {
66 ALOGV("%s", __FUNCTION__);
67 ATRACE_CALL();
68 Mutex::Autolock l(mInputMutex);
69 if (mBusy) {
70 ALOGE("%s: Already busy capturing!", __FUNCTION__);
71 return INVALID_OPERATION;
72 }
73 if (!mStartCapture) {
74 mMsgType = msgType;
75 mStartCapture = true;
76 mStartCaptureSignal.signal();
77 }
78 return OK;
79 }
80
waitUntilIdle(nsecs_t timeout)81 status_t CaptureSequencer::waitUntilIdle(nsecs_t timeout) {
82 ATRACE_CALL();
83 ALOGV("%s: Waiting for idle", __FUNCTION__);
84 Mutex::Autolock l(mStateMutex);
85 status_t res = -1;
86 while (mCaptureState != IDLE) {
87 nsecs_t startTime = systemTime();
88
89 res = mStateChanged.waitRelative(mStateMutex, timeout);
90 if (res != OK) return res;
91
92 timeout -= (systemTime() - startTime);
93 }
94 ALOGV("%s: Now idle", __FUNCTION__);
95 return OK;
96 }
97
notifyAutoExposure(uint8_t newState,int triggerId)98 void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
99 ATRACE_CALL();
100 Mutex::Autolock l(mInputMutex);
101 mAEState = newState;
102 mAETriggerId = triggerId;
103 if (!mNewAEState) {
104 mNewAEState = true;
105 mNewNotifySignal.signal();
106 }
107 }
108
onResultAvailable(const CaptureResult & result)109 void CaptureSequencer::onResultAvailable(const CaptureResult &result) {
110 ATRACE_CALL();
111 ALOGV("%s: New result available.", __FUNCTION__);
112 Mutex::Autolock l(mInputMutex);
113 mNewFrameId = result.mResultExtras.requestId;
114 mNewFrame = result.mMetadata;
115 if (!mNewFrameReceived) {
116 mNewFrameReceived = true;
117 mNewFrameSignal.signal();
118 }
119 }
120
onCaptureAvailable(nsecs_t timestamp,sp<MemoryBase> captureBuffer)121 void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
122 sp<MemoryBase> captureBuffer) {
123 ATRACE_CALL();
124 ALOGV("%s", __FUNCTION__);
125 Mutex::Autolock l(mInputMutex);
126 mCaptureTimestamp = timestamp;
127 mCaptureBuffer = captureBuffer;
128 if (!mNewCaptureReceived) {
129 mNewCaptureReceived = true;
130 mNewCaptureSignal.signal();
131 }
132 }
133
134
dump(int fd,const Vector<String16> &)135 void CaptureSequencer::dump(int fd, const Vector<String16>& /*args*/) {
136 String8 result;
137 if (mCaptureRequest.entryCount() != 0) {
138 result = " Capture request:\n";
139 write(fd, result.string(), result.size());
140 mCaptureRequest.dump(fd, 2, 6);
141 } else {
142 result = " Capture request: undefined\n";
143 write(fd, result.string(), result.size());
144 }
145 result = String8::format(" Current capture state: %s\n",
146 kStateNames[mCaptureState]);
147 result.append(" Latest captured frame:\n");
148 write(fd, result.string(), result.size());
149 mNewFrame.dump(fd, 2, 6);
150 }
151
152 /** Private members */
153
154 const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
155 {
156 "IDLE",
157 "START",
158 "ZSL_START",
159 "ZSL_WAITING",
160 "ZSL_REPROCESSING",
161 "STANDARD_START",
162 "STANDARD_PRECAPTURE_WAIT",
163 "STANDARD_CAPTURE",
164 "STANDARD_CAPTURE_WAIT",
165 "BURST_CAPTURE_START",
166 "BURST_CAPTURE_WAIT",
167 "DONE",
168 "ERROR",
169 "UNKNOWN"
170 };
171
172 const CaptureSequencer::StateManager
173 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
174 &CaptureSequencer::manageIdle,
175 &CaptureSequencer::manageStart,
176 &CaptureSequencer::manageZslStart,
177 &CaptureSequencer::manageZslWaiting,
178 &CaptureSequencer::manageZslReprocessing,
179 &CaptureSequencer::manageStandardStart,
180 &CaptureSequencer::manageStandardPrecaptureWait,
181 &CaptureSequencer::manageStandardCapture,
182 &CaptureSequencer::manageStandardCaptureWait,
183 &CaptureSequencer::manageBurstCaptureStart,
184 &CaptureSequencer::manageBurstCaptureWait,
185 &CaptureSequencer::manageDone,
186 };
187
threadLoop()188 bool CaptureSequencer::threadLoop() {
189
190 sp<Camera2Client> client = mClient.promote();
191 if (client == 0) return false;
192
193 CaptureState currentState;
194 {
195 Mutex::Autolock l(mStateMutex);
196 currentState = mCaptureState;
197 }
198
199 currentState = (this->*kStateManagers[currentState])(client);
200
201 Mutex::Autolock l(mStateMutex);
202 if (currentState != mCaptureState) {
203 if (mCaptureState != IDLE) {
204 ATRACE_ASYNC_END(kStateNames[mCaptureState], mStateTransitionCount);
205 }
206 mCaptureState = currentState;
207 mStateTransitionCount++;
208 if (mCaptureState != IDLE) {
209 ATRACE_ASYNC_BEGIN(kStateNames[mCaptureState], mStateTransitionCount);
210 }
211 ALOGV("Camera %d: New capture state %s",
212 client->getCameraId(), kStateNames[mCaptureState]);
213 mStateChanged.signal();
214 }
215
216 if (mCaptureState == ERROR) {
217 ALOGE("Camera %d: Stopping capture sequencer due to error",
218 client->getCameraId());
219 return false;
220 }
221
222 return true;
223 }
224
manageIdle(sp<Camera2Client> &)225 CaptureSequencer::CaptureState CaptureSequencer::manageIdle(
226 sp<Camera2Client> &/*client*/) {
227 status_t res;
228 Mutex::Autolock l(mInputMutex);
229 while (!mStartCapture) {
230 res = mStartCaptureSignal.waitRelative(mInputMutex,
231 kWaitDuration);
232 if (res == TIMED_OUT) break;
233 }
234 if (mStartCapture) {
235 mStartCapture = false;
236 mBusy = true;
237 return START;
238 }
239 return IDLE;
240 }
241
manageDone(sp<Camera2Client> & client)242 CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
243 status_t res = OK;
244 ATRACE_CALL();
245 mCaptureId++;
246 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
247 mCaptureId = Camera2Client::kCaptureRequestIdStart;
248 }
249 {
250 Mutex::Autolock l(mInputMutex);
251 mBusy = false;
252 }
253
254 int takePictureCounter = 0;
255 {
256 SharedParameters::Lock l(client->getParameters());
257 switch (l.mParameters.state) {
258 case Parameters::DISCONNECTED:
259 ALOGW("%s: Camera %d: Discarding image data during shutdown ",
260 __FUNCTION__, client->getCameraId());
261 res = INVALID_OPERATION;
262 break;
263 case Parameters::STILL_CAPTURE:
264 res = client->getCameraDevice()->waitUntilDrained();
265 if (res != OK) {
266 ALOGE("%s: Camera %d: Can't idle after still capture: "
267 "%s (%d)", __FUNCTION__, client->getCameraId(),
268 strerror(-res), res);
269 }
270 l.mParameters.state = Parameters::STOPPED;
271 break;
272 case Parameters::VIDEO_SNAPSHOT:
273 l.mParameters.state = Parameters::RECORD;
274 break;
275 default:
276 ALOGE("%s: Camera %d: Still image produced unexpectedly "
277 "in state %s!",
278 __FUNCTION__, client->getCameraId(),
279 Parameters::getStateName(l.mParameters.state));
280 res = INVALID_OPERATION;
281 }
282 takePictureCounter = l.mParameters.takePictureCounter;
283 }
284 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
285 if (processor != 0) {
286 ALOGV("%s: Memory optimization, clearing ZSL queue",
287 __FUNCTION__);
288 processor->clearZslQueue();
289 }
290
291 /**
292 * Fire the jpegCallback in Camera#takePicture(..., jpegCallback)
293 */
294 if (mCaptureBuffer != 0 && res == OK) {
295 ATRACE_ASYNC_END(Camera2Client::kTakepictureLabel, takePictureCounter);
296
297 Camera2Client::SharedCameraCallbacks::Lock
298 l(client->mSharedCameraCallbacks);
299 ALOGV("%s: Sending still image to client", __FUNCTION__);
300 if (l.mRemoteCallback != 0) {
301 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
302 mCaptureBuffer, NULL);
303 } else {
304 ALOGV("%s: No client!", __FUNCTION__);
305 }
306 }
307 mCaptureBuffer.clear();
308
309 return IDLE;
310 }
311
manageStart(sp<Camera2Client> & client)312 CaptureSequencer::CaptureState CaptureSequencer::manageStart(
313 sp<Camera2Client> &client) {
314 ALOGV("%s", __FUNCTION__);
315 status_t res;
316 ATRACE_CALL();
317 SharedParameters::Lock l(client->getParameters());
318 CaptureState nextState = DONE;
319
320 res = updateCaptureRequest(l.mParameters, client);
321 if (res != OK ) {
322 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
323 __FUNCTION__, client->getCameraId(), strerror(-res), res);
324 return DONE;
325 }
326
327 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
328 l.mParameters.state == Parameters::STILL_CAPTURE) {
329 nextState = BURST_CAPTURE_START;
330 }
331 else if (l.mParameters.zslMode &&
332 l.mParameters.state == Parameters::STILL_CAPTURE &&
333 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
334 nextState = ZSL_START;
335 } else {
336 nextState = STANDARD_START;
337 }
338 mShutterNotified = false;
339
340 return nextState;
341 }
342
manageZslStart(sp<Camera2Client> & client)343 CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
344 sp<Camera2Client> &client) {
345 ALOGV("%s", __FUNCTION__);
346 status_t res;
347 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
348 if (processor == 0) {
349 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
350 return DONE;
351 }
352
353 // We don't want to get partial results for ZSL capture.
354 client->registerFrameListener(mCaptureId, mCaptureId + 1,
355 this,
356 /*sendPartials*/false);
357
358 // TODO: Actually select the right thing here.
359 res = processor->pushToReprocess(mCaptureId);
360 if (res != OK) {
361 if (res == NOT_ENOUGH_DATA) {
362 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
363 "falling back to normal capture", __FUNCTION__,
364 client->getCameraId());
365 } else {
366 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
367 __FUNCTION__, client->getCameraId(), strerror(-res), res);
368 }
369 return STANDARD_START;
370 }
371
372 SharedParameters::Lock l(client->getParameters());
373 /* warning: this also locks a SharedCameraCallbacks */
374 shutterNotifyLocked(l.mParameters, client, mMsgType);
375 mShutterNotified = true;
376 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
377 return STANDARD_CAPTURE_WAIT;
378 }
379
manageZslWaiting(sp<Camera2Client> &)380 CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
381 sp<Camera2Client> &/*client*/) {
382 ALOGV("%s", __FUNCTION__);
383 return DONE;
384 }
385
manageZslReprocessing(sp<Camera2Client> &)386 CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
387 sp<Camera2Client> &/*client*/) {
388 ALOGV("%s", __FUNCTION__);
389 return START;
390 }
391
manageStandardStart(sp<Camera2Client> & client)392 CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
393 sp<Camera2Client> &client) {
394 ATRACE_CALL();
395
396 bool isAeConverged = false;
397 // Get the onFrameAvailable callback when the requestID == mCaptureId
398 // We don't want to get partial results for normal capture, as we need
399 // Get ANDROID_SENSOR_TIMESTAMP from the capture result, but partial
400 // result doesn't have to have this metadata available.
401 // TODO: Update to use the HALv3 shutter notification for remove the
402 // need for this listener and make it faster. see bug 12530628.
403 client->registerFrameListener(mCaptureId, mCaptureId + 1,
404 this,
405 /*sendPartials*/false);
406
407 {
408 Mutex::Autolock l(mInputMutex);
409 isAeConverged = (mAEState == ANDROID_CONTROL_AE_STATE_CONVERGED);
410 }
411
412 {
413 SharedParameters::Lock l(client->getParameters());
414 // Skip AE precapture when it is already converged and not in force flash mode.
415 if (l.mParameters.flashMode != Parameters::FLASH_MODE_ON && isAeConverged) {
416 return STANDARD_CAPTURE;
417 }
418
419 mTriggerId = l.mParameters.precaptureTriggerCounter++;
420 }
421 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
422
423 mAeInPrecapture = false;
424 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
425 return STANDARD_PRECAPTURE_WAIT;
426 }
427
manageStandardPrecaptureWait(sp<Camera2Client> &)428 CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
429 sp<Camera2Client> &/*client*/) {
430 status_t res;
431 ATRACE_CALL();
432 Mutex::Autolock l(mInputMutex);
433 while (!mNewAEState) {
434 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
435 if (res == TIMED_OUT) {
436 mTimeoutCount--;
437 break;
438 }
439 }
440 if (mTimeoutCount <= 0) {
441 ALOGW("Timed out waiting for precapture %s",
442 mAeInPrecapture ? "end" : "start");
443 return STANDARD_CAPTURE;
444 }
445 if (mNewAEState) {
446 if (!mAeInPrecapture) {
447 // Waiting to see PRECAPTURE state
448 if (mAETriggerId == mTriggerId) {
449 if (mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
450 ALOGV("%s: Got precapture start", __FUNCTION__);
451 mAeInPrecapture = true;
452 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
453 } else if (mAEState == ANDROID_CONTROL_AE_STATE_CONVERGED ||
454 mAEState == ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED) {
455 // It is legal to transit to CONVERGED or FLASH_REQUIRED
456 // directly after a trigger.
457 ALOGV("%s: AE is already in good state, start capture", __FUNCTION__);
458 return STANDARD_CAPTURE;
459 }
460 }
461 } else {
462 // Waiting to see PRECAPTURE state end
463 if (mAETriggerId == mTriggerId &&
464 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
465 ALOGV("%s: Got precapture end", __FUNCTION__);
466 return STANDARD_CAPTURE;
467 }
468 }
469 mNewAEState = false;
470 }
471 return STANDARD_PRECAPTURE_WAIT;
472 }
473
manageStandardCapture(sp<Camera2Client> & client)474 CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
475 sp<Camera2Client> &client) {
476 status_t res;
477 ATRACE_CALL();
478 SharedParameters::Lock l(client->getParameters());
479 Vector<int32_t> outputStreams;
480 uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
481
482 /**
483 * Set up output streams in the request
484 * - preview
485 * - capture/jpeg
486 * - callback (if preview callbacks enabled)
487 * - recording (if recording enabled)
488 */
489 outputStreams.push(client->getPreviewStreamId());
490 outputStreams.push(client->getCaptureStreamId());
491
492 if (l.mParameters.previewCallbackFlags &
493 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
494 outputStreams.push(client->getCallbackStreamId());
495 }
496
497 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
498 outputStreams.push(client->getRecordingStreamId());
499 captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
500 }
501
502 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
503 outputStreams);
504 if (res == OK) {
505 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
506 &mCaptureId, 1);
507 }
508 if (res == OK) {
509 res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT,
510 &captureIntent, 1);
511 }
512 if (res == OK) {
513 res = mCaptureRequest.sort();
514 }
515
516 if (res != OK) {
517 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
518 __FUNCTION__, client->getCameraId(), strerror(-res), res);
519 return DONE;
520 }
521
522 // Create a capture copy since CameraDeviceBase#capture takes ownership
523 CameraMetadata captureCopy = mCaptureRequest;
524 if (captureCopy.entryCount() == 0) {
525 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
526 __FUNCTION__, client->getCameraId());
527 return DONE;
528 }
529
530 /**
531 * Clear the streaming request for still-capture pictures
532 * (as opposed to i.e. video snapshots)
533 */
534 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
535 // API definition of takePicture() - stop preview before taking pic
536 res = client->stopStream();
537 if (res != OK) {
538 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
539 "%s (%d)",
540 __FUNCTION__, client->getCameraId(), strerror(-res), res);
541 return DONE;
542 }
543 }
544 // TODO: Capture should be atomic with setStreamingRequest here
545 res = client->getCameraDevice()->capture(captureCopy);
546 if (res != OK) {
547 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
548 "%s (%d)",
549 __FUNCTION__, client->getCameraId(), strerror(-res), res);
550 return DONE;
551 }
552
553 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
554 return STANDARD_CAPTURE_WAIT;
555 }
556
manageStandardCaptureWait(sp<Camera2Client> & client)557 CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
558 sp<Camera2Client> &client) {
559 status_t res;
560 ATRACE_CALL();
561 Mutex::Autolock l(mInputMutex);
562
563 // Wait for new metadata result (mNewFrame)
564 while (!mNewFrameReceived) {
565 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
566 if (res == TIMED_OUT) {
567 mTimeoutCount--;
568 break;
569 }
570 }
571
572 // Approximation of the shutter being closed
573 // - TODO: use the hal3 exposure callback in Camera3Device instead
574 if (mNewFrameReceived && !mShutterNotified) {
575 SharedParameters::Lock l(client->getParameters());
576 /* warning: this also locks a SharedCameraCallbacks */
577 shutterNotifyLocked(l.mParameters, client, mMsgType);
578 mShutterNotified = true;
579 }
580
581 // Wait until jpeg was captured by JpegProcessor
582 while (mNewFrameReceived && !mNewCaptureReceived) {
583 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
584 if (res == TIMED_OUT) {
585 mTimeoutCount--;
586 break;
587 }
588 }
589 if (mTimeoutCount <= 0) {
590 ALOGW("Timed out waiting for capture to complete");
591 return DONE;
592 }
593 if (mNewFrameReceived && mNewCaptureReceived) {
594 if (mNewFrameId != mCaptureId) {
595 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
596 mCaptureId, mNewFrameId);
597 }
598 camera_metadata_entry_t entry;
599 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
600 if (entry.count == 0) {
601 ALOGE("No timestamp field in capture frame!");
602 } else if (entry.count == 1) {
603 if (entry.data.i64[0] != mCaptureTimestamp) {
604 ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 ","
605 " captured buffer %" PRId64,
606 entry.data.i64[0],
607 mCaptureTimestamp);
608 }
609 } else {
610 ALOGE("Timestamp metadata is malformed!");
611 }
612 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
613
614 mNewFrameReceived = false;
615 mNewCaptureReceived = false;
616 return DONE;
617 }
618 return STANDARD_CAPTURE_WAIT;
619 }
620
manageBurstCaptureStart(sp<Camera2Client> & client)621 CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
622 sp<Camera2Client> &client) {
623 ALOGV("%s", __FUNCTION__);
624 status_t res;
625 ATRACE_CALL();
626
627 // check which burst mode is set, create respective burst object
628 {
629 SharedParameters::Lock l(client->getParameters());
630
631 res = updateCaptureRequest(l.mParameters, client);
632 if(res != OK) {
633 return DONE;
634 }
635
636 //
637 // check for burst mode type in mParameters here
638 //
639 mBurstCapture = new BurstCapture(client, this);
640 }
641
642 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
643 if (res == OK) {
644 res = mCaptureRequest.sort();
645 }
646 if (res != OK) {
647 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
648 __FUNCTION__, client->getCameraId(), strerror(-res), res);
649 return DONE;
650 }
651
652 CameraMetadata captureCopy = mCaptureRequest;
653 if (captureCopy.entryCount() == 0) {
654 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
655 __FUNCTION__, client->getCameraId());
656 return DONE;
657 }
658
659 Vector<CameraMetadata> requests;
660 requests.push(mCaptureRequest);
661 res = mBurstCapture->start(requests, mCaptureId);
662 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
663 return BURST_CAPTURE_WAIT;
664 }
665
manageBurstCaptureWait(sp<Camera2Client> &)666 CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
667 sp<Camera2Client> &/*client*/) {
668 status_t res;
669 ATRACE_CALL();
670
671 while (!mNewCaptureReceived) {
672 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
673 if (res == TIMED_OUT) {
674 mTimeoutCount--;
675 break;
676 }
677 }
678
679 if (mTimeoutCount <= 0) {
680 ALOGW("Timed out waiting for burst capture to complete");
681 return DONE;
682 }
683 if (mNewCaptureReceived) {
684 mNewCaptureReceived = false;
685 // TODO: update mCaptureId to last burst's capture ID + 1?
686 return DONE;
687 }
688
689 return BURST_CAPTURE_WAIT;
690 }
691
updateCaptureRequest(const Parameters & params,sp<Camera2Client> & client)692 status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms,
693 sp<Camera2Client> &client) {
694 ATRACE_CALL();
695 status_t res;
696 if (mCaptureRequest.entryCount() == 0) {
697 res = client->getCameraDevice()->createDefaultRequest(
698 CAMERA2_TEMPLATE_STILL_CAPTURE,
699 &mCaptureRequest);
700 if (res != OK) {
701 ALOGE("%s: Camera %d: Unable to create default still image request:"
702 " %s (%d)", __FUNCTION__, client->getCameraId(),
703 strerror(-res), res);
704 return res;
705 }
706 }
707
708 res = params.updateRequest(&mCaptureRequest);
709 if (res != OK) {
710 ALOGE("%s: Camera %d: Unable to update common entries of capture "
711 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
712 strerror(-res), res);
713 return res;
714 }
715
716 res = params.updateRequestJpeg(&mCaptureRequest);
717 if (res != OK) {
718 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
719 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
720 strerror(-res), res);
721 return res;
722 }
723
724 return OK;
725 }
726
shutterNotifyLocked(const Parameters & params,sp<Camera2Client> client,int msgType)727 /*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters ¶ms,
728 sp<Camera2Client> client, int msgType) {
729 ATRACE_CALL();
730
731 if (params.state == Parameters::STILL_CAPTURE
732 && params.playShutterSound
733 && (msgType & CAMERA_MSG_SHUTTER)) {
734 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
735 }
736
737 {
738 Camera2Client::SharedCameraCallbacks::Lock
739 l(client->mSharedCameraCallbacks);
740
741 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
742 if (l.mRemoteCallback != 0) {
743 // ShutterCallback
744 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
745 /*ext1*/0, /*ext2*/0);
746
747 // RawCallback with null buffer
748 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
749 /*ext1*/0, /*ext2*/0);
750 } else {
751 ALOGV("%s: No client!", __FUNCTION__);
752 }
753 }
754 }
755
756
757 }; // namespace camera2
758 }; // namespace android
759