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 "CaptureSequencer.h"
26 #include "BurstCapture.h"
27 #include "../Camera2Device.h"
28 #include "../Camera2Client.h"
29 #include "Parameters.h"
30 #include "ZslProcessorInterface.h"
31
32 namespace android {
33 namespace camera2 {
34
35 /** Public members */
36
CaptureSequencer(wp<Camera2Client> client)37 CaptureSequencer::CaptureSequencer(wp<Camera2Client> client):
38 Thread(false),
39 mStartCapture(false),
40 mBusy(false),
41 mNewAEState(false),
42 mNewFrameReceived(false),
43 mNewCaptureReceived(false),
44 mShutterNotified(false),
45 mClient(client),
46 mCaptureState(IDLE),
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 frameId,const CameraMetadata & frame)107 void CaptureSequencer::onFrameAvailable(int32_t frameId,
108 const CameraMetadata &frame) {
109 ALOGV("%s: Listener found new frame", __FUNCTION__);
110 ATRACE_CALL();
111 Mutex::Autolock l(mInputMutex);
112 mNewFrameId = frameId;
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 mCaptureState = currentState;
203 ATRACE_INT("cam2_capt_state", mCaptureState);
204 ALOGV("Camera %d: New capture state %s",
205 client->getCameraId(), kStateNames[mCaptureState]);
206 mStateChanged.signal();
207 }
208
209 if (mCaptureState == ERROR) {
210 ALOGE("Camera %d: Stopping capture sequencer due to error",
211 client->getCameraId());
212 return false;
213 }
214
215 return true;
216 }
217
manageIdle(sp<Camera2Client> &)218 CaptureSequencer::CaptureState CaptureSequencer::manageIdle(
219 sp<Camera2Client> &/*client*/) {
220 status_t res;
221 Mutex::Autolock l(mInputMutex);
222 while (!mStartCapture) {
223 res = mStartCaptureSignal.waitRelative(mInputMutex,
224 kWaitDuration);
225 if (res == TIMED_OUT) break;
226 }
227 if (mStartCapture) {
228 mStartCapture = false;
229 mBusy = true;
230 return START;
231 }
232 return IDLE;
233 }
234
manageDone(sp<Camera2Client> & client)235 CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
236 status_t res = OK;
237 ATRACE_CALL();
238 mCaptureId++;
239 if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) {
240 mCaptureId = Camera2Client::kCaptureRequestIdStart;
241 }
242 {
243 Mutex::Autolock l(mInputMutex);
244 mBusy = false;
245 }
246
247 {
248 SharedParameters::Lock l(client->getParameters());
249 switch (l.mParameters.state) {
250 case Parameters::DISCONNECTED:
251 ALOGW("%s: Camera %d: Discarding image data during shutdown ",
252 __FUNCTION__, client->getCameraId());
253 res = INVALID_OPERATION;
254 break;
255 case Parameters::STILL_CAPTURE:
256 l.mParameters.state = Parameters::STOPPED;
257 break;
258 case Parameters::VIDEO_SNAPSHOT:
259 l.mParameters.state = Parameters::RECORD;
260 break;
261 default:
262 ALOGE("%s: Camera %d: Still image produced unexpectedly "
263 "in state %s!",
264 __FUNCTION__, client->getCameraId(),
265 Parameters::getStateName(l.mParameters.state));
266 res = INVALID_OPERATION;
267 }
268 }
269 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
270 if (processor != 0) {
271 ALOGV("%s: Memory optimization, clearing ZSL queue",
272 __FUNCTION__);
273 processor->clearZslQueue();
274 }
275
276 /**
277 * Fire the jpegCallback in Camera#takePicture(..., jpegCallback)
278 */
279 if (mCaptureBuffer != 0 && res == OK) {
280 Camera2Client::SharedCameraCallbacks::Lock
281 l(client->mSharedCameraCallbacks);
282 ALOGV("%s: Sending still image to client", __FUNCTION__);
283 if (l.mRemoteCallback != 0) {
284 l.mRemoteCallback->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
285 mCaptureBuffer, NULL);
286 } else {
287 ALOGV("%s: No client!", __FUNCTION__);
288 }
289 }
290 mCaptureBuffer.clear();
291
292 return IDLE;
293 }
294
manageStart(sp<Camera2Client> & client)295 CaptureSequencer::CaptureState CaptureSequencer::manageStart(
296 sp<Camera2Client> &client) {
297 ALOGV("%s", __FUNCTION__);
298 status_t res;
299 ATRACE_CALL();
300 SharedParameters::Lock l(client->getParameters());
301 CaptureState nextState = DONE;
302
303 res = updateCaptureRequest(l.mParameters, client);
304 if (res != OK ) {
305 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
306 __FUNCTION__, client->getCameraId(), strerror(-res), res);
307 return DONE;
308 }
309
310 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
311 l.mParameters.state == Parameters::STILL_CAPTURE) {
312 nextState = BURST_CAPTURE_START;
313 }
314 else if (l.mParameters.zslMode &&
315 l.mParameters.state == Parameters::STILL_CAPTURE &&
316 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
317 nextState = ZSL_START;
318 } else {
319 nextState = STANDARD_START;
320 }
321 mShutterNotified = false;
322
323 return nextState;
324 }
325
manageZslStart(sp<Camera2Client> & client)326 CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
327 sp<Camera2Client> &client) {
328 ALOGV("%s", __FUNCTION__);
329 status_t res;
330 sp<ZslProcessorInterface> processor = mZslProcessor.promote();
331 if (processor == 0) {
332 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
333 return DONE;
334 }
335
336 client->registerFrameListener(mCaptureId, mCaptureId + 1,
337 this);
338
339 // TODO: Actually select the right thing here.
340 res = processor->pushToReprocess(mCaptureId);
341 if (res != OK) {
342 if (res == NOT_ENOUGH_DATA) {
343 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
344 "falling back to normal capture", __FUNCTION__,
345 client->getCameraId());
346 } else {
347 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
348 __FUNCTION__, client->getCameraId(), strerror(-res), res);
349 }
350 return STANDARD_START;
351 }
352
353 SharedParameters::Lock l(client->getParameters());
354 /* warning: this also locks a SharedCameraCallbacks */
355 shutterNotifyLocked(l.mParameters, client, mMsgType);
356 mShutterNotified = true;
357 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
358 return STANDARD_CAPTURE_WAIT;
359 }
360
manageZslWaiting(sp<Camera2Client> &)361 CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
362 sp<Camera2Client> &/*client*/) {
363 ALOGV("%s", __FUNCTION__);
364 return DONE;
365 }
366
manageZslReprocessing(sp<Camera2Client> &)367 CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
368 sp<Camera2Client> &/*client*/) {
369 ALOGV("%s", __FUNCTION__);
370 return START;
371 }
372
manageStandardStart(sp<Camera2Client> & client)373 CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
374 sp<Camera2Client> &client) {
375 ATRACE_CALL();
376
377 // Get the onFrameAvailable callback when the requestID == mCaptureId
378 client->registerFrameListener(mCaptureId, mCaptureId + 1,
379 this);
380 {
381 SharedParameters::Lock l(client->getParameters());
382 mTriggerId = l.mParameters.precaptureTriggerCounter++;
383 }
384 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
385
386 mAeInPrecapture = false;
387 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
388 return STANDARD_PRECAPTURE_WAIT;
389 }
390
manageStandardPrecaptureWait(sp<Camera2Client> &)391 CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
392 sp<Camera2Client> &/*client*/) {
393 status_t res;
394 ATRACE_CALL();
395 Mutex::Autolock l(mInputMutex);
396 while (!mNewAEState) {
397 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
398 if (res == TIMED_OUT) {
399 mTimeoutCount--;
400 break;
401 }
402 }
403 if (mTimeoutCount <= 0) {
404 ALOGW("Timed out waiting for precapture %s",
405 mAeInPrecapture ? "end" : "start");
406 return STANDARD_CAPTURE;
407 }
408 if (mNewAEState) {
409 if (!mAeInPrecapture) {
410 // Waiting to see PRECAPTURE state
411 if (mAETriggerId == mTriggerId &&
412 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
413 ALOGV("%s: Got precapture start", __FUNCTION__);
414 mAeInPrecapture = true;
415 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
416 }
417 } else {
418 // Waiting to see PRECAPTURE state end
419 if (mAETriggerId == mTriggerId &&
420 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
421 ALOGV("%s: Got precapture end", __FUNCTION__);
422 return STANDARD_CAPTURE;
423 }
424 }
425 mNewAEState = false;
426 }
427 return STANDARD_PRECAPTURE_WAIT;
428 }
429
manageStandardCapture(sp<Camera2Client> & client)430 CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
431 sp<Camera2Client> &client) {
432 status_t res;
433 ATRACE_CALL();
434 SharedParameters::Lock l(client->getParameters());
435 Vector<uint8_t> outputStreams;
436
437 /**
438 * Set up output streams in the request
439 * - preview
440 * - capture/jpeg
441 * - callback (if preview callbacks enabled)
442 * - recording (if recording enabled)
443 */
444 outputStreams.push(client->getPreviewStreamId());
445 outputStreams.push(client->getCaptureStreamId());
446
447 if (l.mParameters.previewCallbackFlags &
448 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
449 outputStreams.push(client->getCallbackStreamId());
450 }
451
452 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
453 outputStreams.push(client->getRecordingStreamId());
454 }
455
456 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
457 outputStreams);
458 if (res == OK) {
459 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
460 &mCaptureId, 1);
461 }
462 if (res == OK) {
463 res = mCaptureRequest.sort();
464 }
465
466 if (res != OK) {
467 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
468 __FUNCTION__, client->getCameraId(), strerror(-res), res);
469 return DONE;
470 }
471
472 // Create a capture copy since CameraDeviceBase#capture takes ownership
473 CameraMetadata captureCopy = mCaptureRequest;
474 if (captureCopy.entryCount() == 0) {
475 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
476 __FUNCTION__, client->getCameraId());
477 return DONE;
478 }
479
480 /**
481 * Clear the streaming request for still-capture pictures
482 * (as opposed to i.e. video snapshots)
483 */
484 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
485 // API definition of takePicture() - stop preview before taking pic
486 res = client->stopStream();
487 if (res != OK) {
488 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
489 "%s (%d)",
490 __FUNCTION__, client->getCameraId(), strerror(-res), res);
491 return DONE;
492 }
493 }
494 // TODO: Capture should be atomic with setStreamingRequest here
495 res = client->getCameraDevice()->capture(captureCopy);
496 if (res != OK) {
497 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
498 "%s (%d)",
499 __FUNCTION__, client->getCameraId(), strerror(-res), res);
500 return DONE;
501 }
502
503 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
504 return STANDARD_CAPTURE_WAIT;
505 }
506
manageStandardCaptureWait(sp<Camera2Client> & client)507 CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
508 sp<Camera2Client> &client) {
509 status_t res;
510 ATRACE_CALL();
511 Mutex::Autolock l(mInputMutex);
512
513 // Wait for new metadata result (mNewFrame)
514 while (!mNewFrameReceived) {
515 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
516 if (res == TIMED_OUT) {
517 mTimeoutCount--;
518 break;
519 }
520 }
521
522 // Approximation of the shutter being closed
523 // - TODO: use the hal3 exposure callback in Camera3Device instead
524 if (mNewFrameReceived && !mShutterNotified) {
525 SharedParameters::Lock l(client->getParameters());
526 /* warning: this also locks a SharedCameraCallbacks */
527 shutterNotifyLocked(l.mParameters, client, mMsgType);
528 mShutterNotified = true;
529 }
530
531 // Wait until jpeg was captured by JpegProcessor
532 while (mNewFrameReceived && !mNewCaptureReceived) {
533 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
534 if (res == TIMED_OUT) {
535 mTimeoutCount--;
536 break;
537 }
538 }
539 if (mTimeoutCount <= 0) {
540 ALOGW("Timed out waiting for capture to complete");
541 return DONE;
542 }
543 if (mNewFrameReceived && mNewCaptureReceived) {
544 if (mNewFrameId != mCaptureId) {
545 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
546 mCaptureId, mNewFrameId);
547 }
548 camera_metadata_entry_t entry;
549 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
550 if (entry.count == 0) {
551 ALOGE("No timestamp field in capture frame!");
552 }
553 if (entry.data.i64[0] != mCaptureTimestamp) {
554 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
555 " captured buffer %lld",
556 entry.data.i64[0],
557 mCaptureTimestamp);
558 }
559 client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
560
561 mNewFrameReceived = false;
562 mNewCaptureReceived = false;
563 return DONE;
564 }
565 return STANDARD_CAPTURE_WAIT;
566 }
567
manageBurstCaptureStart(sp<Camera2Client> & client)568 CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
569 sp<Camera2Client> &client) {
570 ALOGV("%s", __FUNCTION__);
571 status_t res;
572 ATRACE_CALL();
573
574 // check which burst mode is set, create respective burst object
575 {
576 SharedParameters::Lock l(client->getParameters());
577
578 res = updateCaptureRequest(l.mParameters, client);
579 if(res != OK) {
580 return DONE;
581 }
582
583 //
584 // check for burst mode type in mParameters here
585 //
586 mBurstCapture = new BurstCapture(client, this);
587 }
588
589 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
590 if (res == OK) {
591 res = mCaptureRequest.sort();
592 }
593 if (res != OK) {
594 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
595 __FUNCTION__, client->getCameraId(), strerror(-res), res);
596 return DONE;
597 }
598
599 CameraMetadata captureCopy = mCaptureRequest;
600 if (captureCopy.entryCount() == 0) {
601 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
602 __FUNCTION__, client->getCameraId());
603 return DONE;
604 }
605
606 Vector<CameraMetadata> requests;
607 requests.push(mCaptureRequest);
608 res = mBurstCapture->start(requests, mCaptureId);
609 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
610 return BURST_CAPTURE_WAIT;
611 }
612
manageBurstCaptureWait(sp<Camera2Client> &)613 CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
614 sp<Camera2Client> &/*client*/) {
615 status_t res;
616 ATRACE_CALL();
617
618 while (!mNewCaptureReceived) {
619 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
620 if (res == TIMED_OUT) {
621 mTimeoutCount--;
622 break;
623 }
624 }
625
626 if (mTimeoutCount <= 0) {
627 ALOGW("Timed out waiting for burst capture to complete");
628 return DONE;
629 }
630 if (mNewCaptureReceived) {
631 mNewCaptureReceived = false;
632 // TODO: update mCaptureId to last burst's capture ID + 1?
633 return DONE;
634 }
635
636 return BURST_CAPTURE_WAIT;
637 }
638
updateCaptureRequest(const Parameters & params,sp<Camera2Client> & client)639 status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms,
640 sp<Camera2Client> &client) {
641 ATRACE_CALL();
642 status_t res;
643 if (mCaptureRequest.entryCount() == 0) {
644 res = client->getCameraDevice()->createDefaultRequest(
645 CAMERA2_TEMPLATE_STILL_CAPTURE,
646 &mCaptureRequest);
647 if (res != OK) {
648 ALOGE("%s: Camera %d: Unable to create default still image request:"
649 " %s (%d)", __FUNCTION__, client->getCameraId(),
650 strerror(-res), res);
651 return res;
652 }
653 }
654
655 res = params.updateRequest(&mCaptureRequest);
656 if (res != OK) {
657 ALOGE("%s: Camera %d: Unable to update common entries of capture "
658 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
659 strerror(-res), res);
660 return res;
661 }
662
663 res = params.updateRequestJpeg(&mCaptureRequest);
664 if (res != OK) {
665 ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
666 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
667 strerror(-res), res);
668 return res;
669 }
670
671 return OK;
672 }
673
shutterNotifyLocked(const Parameters & params,sp<Camera2Client> client,int msgType)674 /*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters ¶ms,
675 sp<Camera2Client> client, int msgType) {
676 ATRACE_CALL();
677
678 if (params.state == Parameters::STILL_CAPTURE
679 && params.playShutterSound
680 && (msgType & CAMERA_MSG_SHUTTER)) {
681 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
682 }
683
684 {
685 Camera2Client::SharedCameraCallbacks::Lock
686 l(client->mSharedCameraCallbacks);
687
688 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
689 if (l.mRemoteCallback != 0) {
690 // ShutterCallback
691 l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
692 /*ext1*/0, /*ext2*/0);
693
694 // RawCallback with null buffer
695 l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
696 /*ext1*/0, /*ext2*/0);
697 } else {
698 ALOGV("%s: No client!", __FUNCTION__);
699 }
700 }
701 }
702
703
704 }; // namespace camera2
705 }; // namespace android
706