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