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