CaptureSequencer.cpp revision 2b07e0207da44d7b3cc63c369fd10c9f12a5e2cd
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        mStateTransitionCount(0),
47        mTriggerId(0),
48        mTimeoutCount(0),
49        mCaptureId(Camera2Client::kCaptureRequestIdStart),
50        mMsgType(0) {
51    ALOGV("%s", __FUNCTION__);
52}
53
54CaptureSequencer::~CaptureSequencer() {
55    ALOGV("%s: Exit", __FUNCTION__);
56}
57
58void CaptureSequencer::setZslProcessor(wp<ZslProcessorInterface> processor) {
59    Mutex::Autolock l(mInputMutex);
60    mZslProcessor = processor;
61}
62
63status_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
79status_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
96void 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
107void 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
120void 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
134void 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
153const 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
171const 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
187bool 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
224CaptureSequencer::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
241CaptureSequencer::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
311CaptureSequencer::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
342CaptureSequencer::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
377CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
378        sp<Camera2Client> &/*client*/) {
379    ALOGV("%s", __FUNCTION__);
380    return DONE;
381}
382
383CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
384        sp<Camera2Client> &/*client*/) {
385    ALOGV("%s", __FUNCTION__);
386    return START;
387}
388
389CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
390        sp<Camera2Client> &client) {
391    ATRACE_CALL();
392
393    // Get the onFrameAvailable callback when the requestID == mCaptureId
394    client->registerFrameListener(mCaptureId, mCaptureId + 1,
395            this);
396    {
397        SharedParameters::Lock l(client->getParameters());
398        mTriggerId = l.mParameters.precaptureTriggerCounter++;
399    }
400    client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
401
402    mAeInPrecapture = false;
403    mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
404    return STANDARD_PRECAPTURE_WAIT;
405}
406
407CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
408        sp<Camera2Client> &/*client*/) {
409    status_t res;
410    ATRACE_CALL();
411    Mutex::Autolock l(mInputMutex);
412    while (!mNewAEState) {
413        res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
414        if (res == TIMED_OUT) {
415            mTimeoutCount--;
416            break;
417        }
418    }
419    if (mTimeoutCount <= 0) {
420        ALOGW("Timed out waiting for precapture %s",
421                mAeInPrecapture ? "end" : "start");
422        return STANDARD_CAPTURE;
423    }
424    if (mNewAEState) {
425        if (!mAeInPrecapture) {
426            // Waiting to see PRECAPTURE state
427            if (mAETriggerId == mTriggerId &&
428                    mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
429                ALOGV("%s: Got precapture start", __FUNCTION__);
430                mAeInPrecapture = true;
431                mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
432            }
433        } else {
434            // Waiting to see PRECAPTURE state end
435            if (mAETriggerId == mTriggerId &&
436                    mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
437                ALOGV("%s: Got precapture end", __FUNCTION__);
438                return STANDARD_CAPTURE;
439            }
440        }
441        mNewAEState = false;
442    }
443    return STANDARD_PRECAPTURE_WAIT;
444}
445
446CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
447        sp<Camera2Client> &client) {
448    status_t res;
449    ATRACE_CALL();
450    SharedParameters::Lock l(client->getParameters());
451    Vector<int32_t> outputStreams;
452    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
453
454    /**
455     * Set up output streams in the request
456     *  - preview
457     *  - capture/jpeg
458     *  - callback (if preview callbacks enabled)
459     *  - recording (if recording enabled)
460     */
461    outputStreams.push(client->getPreviewStreamId());
462    outputStreams.push(client->getCaptureStreamId());
463
464    if (l.mParameters.previewCallbackFlags &
465            CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
466        outputStreams.push(client->getCallbackStreamId());
467    }
468
469    if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
470        outputStreams.push(client->getRecordingStreamId());
471        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
472    }
473
474    res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
475            outputStreams);
476    if (res == OK) {
477        res = mCaptureRequest.update(ANDROID_REQUEST_ID,
478                &mCaptureId, 1);
479    }
480    if (res == OK) {
481        res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT,
482                &captureIntent, 1);
483    }
484    if (res == OK) {
485        res = mCaptureRequest.sort();
486    }
487
488    if (res != OK) {
489        ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
490                __FUNCTION__, client->getCameraId(), strerror(-res), res);
491        return DONE;
492    }
493
494    // Create a capture copy since CameraDeviceBase#capture takes ownership
495    CameraMetadata captureCopy = mCaptureRequest;
496    if (captureCopy.entryCount() == 0) {
497        ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
498                __FUNCTION__, client->getCameraId());
499        return DONE;
500    }
501
502    /**
503     * Clear the streaming request for still-capture pictures
504     *   (as opposed to i.e. video snapshots)
505     */
506    if (l.mParameters.state == Parameters::STILL_CAPTURE) {
507        // API definition of takePicture() - stop preview before taking pic
508        res = client->stopStream();
509        if (res != OK) {
510            ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
511                    "%s (%d)",
512                    __FUNCTION__, client->getCameraId(), strerror(-res), res);
513            return DONE;
514        }
515    }
516    // TODO: Capture should be atomic with setStreamingRequest here
517    res = client->getCameraDevice()->capture(captureCopy);
518    if (res != OK) {
519        ALOGE("%s: Camera %d: Unable to submit still image capture request: "
520                "%s (%d)",
521                __FUNCTION__, client->getCameraId(), strerror(-res), res);
522        return DONE;
523    }
524
525    mTimeoutCount = kMaxTimeoutsForCaptureEnd;
526    return STANDARD_CAPTURE_WAIT;
527}
528
529CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
530        sp<Camera2Client> &client) {
531    status_t res;
532    ATRACE_CALL();
533    Mutex::Autolock l(mInputMutex);
534
535    // Wait for new metadata result (mNewFrame)
536    while (!mNewFrameReceived) {
537        res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
538        if (res == TIMED_OUT) {
539            mTimeoutCount--;
540            break;
541        }
542    }
543
544    // Approximation of the shutter being closed
545    // - TODO: use the hal3 exposure callback in Camera3Device instead
546    if (mNewFrameReceived && !mShutterNotified) {
547        SharedParameters::Lock l(client->getParameters());
548        /* warning: this also locks a SharedCameraCallbacks */
549        shutterNotifyLocked(l.mParameters, client, mMsgType);
550        mShutterNotified = true;
551    }
552
553    // Wait until jpeg was captured by JpegProcessor
554    while (mNewFrameReceived && !mNewCaptureReceived) {
555        res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
556        if (res == TIMED_OUT) {
557            mTimeoutCount--;
558            break;
559        }
560    }
561    if (mTimeoutCount <= 0) {
562        ALOGW("Timed out waiting for capture to complete");
563        return DONE;
564    }
565    if (mNewFrameReceived && mNewCaptureReceived) {
566        if (mNewFrameId != mCaptureId) {
567            ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
568                    mCaptureId, mNewFrameId);
569        }
570        camera_metadata_entry_t entry;
571        entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
572        if (entry.count == 0) {
573            ALOGE("No timestamp field in capture frame!");
574        }
575        if (entry.data.i64[0] != mCaptureTimestamp) {
576            ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
577                    " captured buffer %lld",
578                    entry.data.i64[0],
579                    mCaptureTimestamp);
580        }
581        client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
582
583        mNewFrameReceived = false;
584        mNewCaptureReceived = false;
585        return DONE;
586    }
587    return STANDARD_CAPTURE_WAIT;
588}
589
590CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
591        sp<Camera2Client> &client) {
592    ALOGV("%s", __FUNCTION__);
593    status_t res;
594    ATRACE_CALL();
595
596    // check which burst mode is set, create respective burst object
597    {
598        SharedParameters::Lock l(client->getParameters());
599
600        res = updateCaptureRequest(l.mParameters, client);
601        if(res != OK) {
602            return DONE;
603        }
604
605        //
606        // check for burst mode type in mParameters here
607        //
608        mBurstCapture = new BurstCapture(client, this);
609    }
610
611    res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
612    if (res == OK) {
613        res = mCaptureRequest.sort();
614    }
615    if (res != OK) {
616        ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
617                __FUNCTION__, client->getCameraId(), strerror(-res), res);
618        return DONE;
619    }
620
621    CameraMetadata captureCopy = mCaptureRequest;
622    if (captureCopy.entryCount() == 0) {
623        ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
624                __FUNCTION__, client->getCameraId());
625        return DONE;
626    }
627
628    Vector<CameraMetadata> requests;
629    requests.push(mCaptureRequest);
630    res = mBurstCapture->start(requests, mCaptureId);
631    mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
632    return BURST_CAPTURE_WAIT;
633}
634
635CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
636        sp<Camera2Client> &/*client*/) {
637    status_t res;
638    ATRACE_CALL();
639
640    while (!mNewCaptureReceived) {
641        res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
642        if (res == TIMED_OUT) {
643            mTimeoutCount--;
644            break;
645        }
646    }
647
648    if (mTimeoutCount <= 0) {
649        ALOGW("Timed out waiting for burst capture to complete");
650        return DONE;
651    }
652    if (mNewCaptureReceived) {
653        mNewCaptureReceived = false;
654        // TODO: update mCaptureId to last burst's capture ID + 1?
655        return DONE;
656    }
657
658    return BURST_CAPTURE_WAIT;
659}
660
661status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
662        sp<Camera2Client> &client) {
663    ATRACE_CALL();
664    status_t res;
665    if (mCaptureRequest.entryCount() == 0) {
666        res = client->getCameraDevice()->createDefaultRequest(
667                CAMERA2_TEMPLATE_STILL_CAPTURE,
668                &mCaptureRequest);
669        if (res != OK) {
670            ALOGE("%s: Camera %d: Unable to create default still image request:"
671                    " %s (%d)", __FUNCTION__, client->getCameraId(),
672                    strerror(-res), res);
673            return res;
674        }
675    }
676
677    res = params.updateRequest(&mCaptureRequest);
678    if (res != OK) {
679        ALOGE("%s: Camera %d: Unable to update common entries of capture "
680                "request: %s (%d)", __FUNCTION__, client->getCameraId(),
681                strerror(-res), res);
682        return res;
683    }
684
685    res = params.updateRequestJpeg(&mCaptureRequest);
686    if (res != OK) {
687        ALOGE("%s: Camera %d: Unable to update JPEG entries of capture "
688                "request: %s (%d)", __FUNCTION__, client->getCameraId(),
689                strerror(-res), res);
690        return res;
691    }
692
693    return OK;
694}
695
696/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
697            sp<Camera2Client> client, int msgType) {
698    ATRACE_CALL();
699
700    if (params.state == Parameters::STILL_CAPTURE
701        && params.playShutterSound
702        && (msgType & CAMERA_MSG_SHUTTER)) {
703        client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
704    }
705
706    {
707        Camera2Client::SharedCameraCallbacks::Lock
708            l(client->mSharedCameraCallbacks);
709
710        ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
711        if (l.mRemoteCallback != 0) {
712            // ShutterCallback
713            l.mRemoteCallback->notifyCallback(CAMERA_MSG_SHUTTER,
714                                            /*ext1*/0, /*ext2*/0);
715
716            // RawCallback with null buffer
717            l.mRemoteCallback->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
718                                            /*ext1*/0, /*ext2*/0);
719        } else {
720            ALOGV("%s: No client!", __FUNCTION__);
721        }
722    }
723}
724
725
726}; // namespace camera2
727}; // namespace android
728