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