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