Home | History | Annotate | Download | only in OMXCameraAdapter
      1 /*
      2  * Copyright (C) Texas Instruments - http://www.ti.com/
      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 /**
     18 * @file OMXCapture.cpp
     19 *
     20 * This file contains functionality for handling image capture.
     21 *
     22 */
     23 
     24 #undef LOG_TAG
     25 
     26 #define LOG_TAG "CameraHAL"
     27 
     28 #include "CameraHal.h"
     29 #include "OMXCameraAdapter.h"
     30 #include "ErrorUtils.h"
     31 
     32 
     33 namespace android {
     34 
     35 status_t OMXCameraAdapter::setParametersCapture(const CameraParameters &params,
     36                                                 BaseCameraAdapter::AdapterState state)
     37 {
     38     status_t ret = NO_ERROR;
     39     const char *str = NULL;
     40     int w, h;
     41     OMX_COLOR_FORMATTYPE pixFormat;
     42     const char *valstr = NULL;
     43     int varint = 0;
     44 
     45     LOG_FUNCTION_NAME;
     46 
     47     OMXCameraPortParameters *cap;
     48     cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
     49 
     50     params.getPictureSize(&w, &h);
     51 
     52     if ( ( w != ( int ) cap->mWidth ) ||
     53           ( h != ( int ) cap->mHeight ) )
     54         {
     55         mPendingCaptureSettings |= SetFormat;
     56         }
     57 
     58     cap->mWidth = w;
     59     cap->mHeight = h;
     60     //TODO: Support more pixelformats
     61     //cap->mStride = 2;
     62 
     63     CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth);
     64     CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight);
     65 
     66     if ((valstr = params.getPictureFormat()) != NULL) {
     67         if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
     68             CAMHAL_LOGDA("CbYCrY format selected");
     69             pixFormat = OMX_COLOR_FormatCbYCrY;
     70             mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_YUV422I;
     71         } else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
     72             CAMHAL_LOGDA("YUV420SP format selected");
     73             pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
     74             mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_YUV420SP;
     75         } else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
     76             CAMHAL_LOGDA("RGB565 format selected");
     77             pixFormat = OMX_COLOR_Format16bitRGB565;
     78             mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_RGB565;
     79         } else if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
     80             CAMHAL_LOGDA("JPEG format selected");
     81             pixFormat = OMX_COLOR_FormatUnused;
     82             mCodingMode = CodingNone;
     83             mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_JPEG;
     84         } else if (strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_JPS) == 0) {
     85             CAMHAL_LOGDA("JPS format selected");
     86             pixFormat = OMX_COLOR_FormatUnused;
     87             mCodingMode = CodingJPS;
     88             mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_JPS;
     89         } else if (strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_MPO) == 0) {
     90             CAMHAL_LOGDA("MPO format selected");
     91             pixFormat = OMX_COLOR_FormatUnused;
     92             mCodingMode = CodingMPO;
     93             mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_MPO;
     94         } else if (strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW) == 0) {
     95             CAMHAL_LOGDA("RAW Picture format selected");
     96             pixFormat = OMX_COLOR_FormatRawBayer10bit;
     97             mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_RAW;
     98         } else {
     99             CAMHAL_LOGEA("Invalid format, JPEG format selected as default");
    100             pixFormat = OMX_COLOR_FormatUnused;
    101             mPictureFormatFromClient = NULL;
    102         }
    103     } else {
    104         CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG");
    105         pixFormat = OMX_COLOR_FormatUnused;
    106         mPictureFormatFromClient = NULL;
    107     }
    108 
    109     // JPEG capture is not supported in video mode by OMX Camera
    110     // Set capture format to yuv422i...jpeg encode will
    111     // be done on A9
    112     valstr = params.get(TICameraParameters::KEY_CAP_MODE);
    113     if ( (valstr && !strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE)) &&
    114          (pixFormat == OMX_COLOR_FormatUnused) ) {
    115         CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
    116         pixFormat = OMX_COLOR_FormatCbYCrY;
    117     }
    118 
    119     if ( pixFormat != cap->mColorFormat )
    120         {
    121         mPendingCaptureSettings |= SetFormat;
    122         cap->mColorFormat = pixFormat;
    123         }
    124 
    125 #ifdef OMAP_ENHANCEMENT
    126 
    127     str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
    128     if ( NULL != str ) {
    129         parseExpRange(str, mExposureBracketingValues, EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
    130     } else {
    131         // if bracketing was previously set...we set again before capturing to clear
    132         if (mExposureBracketingValidEntries) mPendingCaptureSettings |= SetExpBracket;
    133         mExposureBracketingValidEntries = 0;
    134     }
    135 
    136 #endif
    137 
    138     varint = params.getInt(CameraParameters::KEY_ROTATION);
    139     if ( varint != -1 )
    140         {
    141         if ( ( unsigned int )  varint != mPictureRotation) {
    142             mPendingCaptureSettings |= SetRotation;
    143         }
    144         mPictureRotation = varint;
    145         }
    146     else
    147         {
    148         if (mPictureRotation) mPendingCaptureSettings |= SetRotation;
    149         mPictureRotation = 0;
    150         }
    151 
    152     CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation);
    153 
    154 #ifdef OMAP_ENHANCEMENT
    155 
    156     // Read Sensor Orientation and set it based on perating mode
    157 
    158      varint = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
    159      if (( varint != -1 ) && (mCapMode == OMXCameraAdapter::VIDEO_MODE))
    160         {
    161          mSensorOrientation = varint;
    162          if (mSensorOrientation == 270 ||mSensorOrientation==90)
    163              {
    164              CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation  to Ducati");
    165              mSensorOrientation +=180;
    166              mSensorOrientation%=360;
    167               }
    168          }
    169      else
    170         {
    171          mSensorOrientation = 0;
    172         }
    173 
    174      CAMHAL_LOGVB("Sensor Orientation  set : %d", mSensorOrientation);
    175 
    176     varint = params.getInt(TICameraParameters::KEY_BURST);
    177     if ( varint >= 1 )
    178         {
    179         if (varint != mBurstFrames) {
    180             mPendingCaptureSettings |= SetExpBracket;
    181         }
    182         mBurstFrames = varint;
    183         }
    184     else
    185         {
    186         if (mBurstFrames != 1) mPendingCaptureSettings |= SetExpBracket;
    187         mBurstFrames = 1;
    188         }
    189 
    190     CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames);
    191 
    192 #endif
    193 
    194     varint = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
    195     if ( ( varint >= MIN_JPEG_QUALITY ) &&
    196          ( varint  <= MAX_JPEG_QUALITY ) )
    197         {
    198         if ( ( unsigned int ) varint != mPictureQuality) {
    199             mPendingCaptureSettings |= SetQuality;
    200         }
    201         mPictureQuality = varint;
    202         }
    203     else
    204         {
    205         if (mPictureQuality != MAX_JPEG_QUALITY) mPendingCaptureSettings |= SetQuality;
    206         mPictureQuality = MAX_JPEG_QUALITY;
    207         }
    208 
    209     CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality);
    210 
    211     varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
    212     if ( varint >= 0 )
    213         {
    214         if ( ( unsigned int ) varint != mThumbWidth) {
    215             mPendingCaptureSettings |= SetThumb;
    216         }
    217         mThumbWidth = varint;
    218         }
    219     else
    220         {
    221         if (mThumbWidth != DEFAULT_THUMB_WIDTH) mPendingCaptureSettings |= SetThumb;
    222         mThumbWidth = DEFAULT_THUMB_WIDTH;
    223         }
    224 
    225 
    226     CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth);
    227 
    228     varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
    229     if ( varint >= 0 )
    230         {
    231         if ( ( unsigned int ) varint != mThumbHeight) {
    232             mPendingCaptureSettings |= SetThumb;
    233         }
    234         mThumbHeight = varint;
    235         }
    236     else
    237         {
    238         if (mThumbHeight != DEFAULT_THUMB_HEIGHT) mPendingCaptureSettings |= SetThumb;
    239         mThumbHeight = DEFAULT_THUMB_HEIGHT;
    240         }
    241 
    242 
    243     CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight);
    244 
    245     varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
    246     if ( ( varint >= MIN_JPEG_QUALITY ) &&
    247          ( varint <= MAX_JPEG_QUALITY ) )
    248         {
    249         if ( ( unsigned int ) varint != mThumbQuality) {
    250             mPendingCaptureSettings |= SetThumb;
    251         }
    252         mThumbQuality = varint;
    253         }
    254     else
    255         {
    256         if (mThumbQuality != MAX_JPEG_QUALITY) mPendingCaptureSettings |= SetThumb;
    257         mThumbQuality = MAX_JPEG_QUALITY;
    258         }
    259 
    260     CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality);
    261 
    262     if (mFirstTimeInit) {
    263         mPendingCaptureSettings = ECapturesettingsAll;
    264     }
    265 
    266     if (mPendingCaptureSettings) {
    267         disableImagePort();
    268         if ( NULL != mReleaseImageBuffersCallback ) {
    269             mReleaseImageBuffersCallback(mReleaseData);
    270         }
    271     }
    272 
    273     LOG_FUNCTION_NAME_EXIT;
    274 
    275     return ret;
    276 }
    277 
    278 status_t OMXCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount)
    279 {
    280     status_t ret = NO_ERROR;
    281     OMXCameraPortParameters *imgCaptureData = NULL;
    282     OMX_ERRORTYPE eError = OMX_ErrorNone;
    283 
    284     LOG_FUNCTION_NAME;
    285 
    286     if ( NO_ERROR == ret )
    287         {
    288         imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    289 
    290         imgCaptureData->mNumBufs = bufferCount;
    291 
    292         // check if image port is already configured...
    293         // if it already configured then we don't have to query again
    294         if (!mCaptureConfigured) {
    295             ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
    296         }
    297 
    298         if ( ret == NO_ERROR )
    299             {
    300             length = imgCaptureData->mBufSize;
    301             }
    302         else
    303             {
    304             CAMHAL_LOGEB("setFormat() failed 0x%x", ret);
    305             length = 0;
    306             }
    307         }
    308 
    309     CAMHAL_LOGDB("getPictureBufferSize %d", length);
    310 
    311     LOG_FUNCTION_NAME_EXIT;
    312 
    313     return ret;
    314 }
    315 
    316 status_t OMXCameraAdapter::parseExpRange(const char *rangeStr,
    317                                          int * expRange,
    318                                          size_t count,
    319                                          size_t &validEntries)
    320 {
    321     status_t ret = NO_ERROR;
    322     char *ctx, *expVal;
    323     char *tmp = NULL;
    324     size_t i = 0;
    325 
    326     LOG_FUNCTION_NAME;
    327 
    328     if ( NULL == rangeStr )
    329         {
    330         return -EINVAL;
    331         }
    332 
    333     if ( NULL == expRange )
    334         {
    335         return -EINVAL;
    336         }
    337 
    338     if ( NO_ERROR == ret )
    339         {
    340         tmp = ( char * ) malloc( strlen(rangeStr) + 1 );
    341 
    342         if ( NULL == tmp )
    343             {
    344             CAMHAL_LOGEA("No resources for temporary buffer");
    345             return -1;
    346             }
    347         memset(tmp, '\0', strlen(rangeStr) + 1);
    348 
    349         }
    350 
    351     if ( NO_ERROR == ret )
    352         {
    353         strncpy(tmp, rangeStr, strlen(rangeStr) );
    354         expVal = strtok_r( (char *) tmp, CameraHal::PARAMS_DELIMITER, &ctx);
    355 
    356         i = 0;
    357         while ( ( NULL != expVal ) && ( i < count ) )
    358             {
    359             expRange[i] = atoi(expVal);
    360             expVal = strtok_r(NULL, CameraHal::PARAMS_DELIMITER, &ctx);
    361             i++;
    362             }
    363         validEntries = i;
    364         }
    365 
    366     if ( NULL != tmp )
    367         {
    368         free(tmp);
    369         }
    370 
    371     LOG_FUNCTION_NAME_EXIT;
    372 
    373     return ret;
    374 }
    375 
    376 status_t OMXCameraAdapter::setExposureBracketing(int *evValues,
    377                                                  size_t evCount,
    378                                                  size_t frameCount)
    379 {
    380     status_t ret = NO_ERROR;
    381     OMX_ERRORTYPE eError = OMX_ErrorNone;
    382     OMX_CONFIG_CAPTUREMODETYPE expCapMode;
    383     OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
    384 
    385     LOG_FUNCTION_NAME;
    386 
    387     if ( OMX_StateInvalid == mComponentState )
    388         {
    389         CAMHAL_LOGEA("OMX component is in invalid state");
    390         ret = -EINVAL;
    391         }
    392 
    393     if ( NULL == evValues )
    394         {
    395         CAMHAL_LOGEA("Exposure compensation values pointer is invalid");
    396         ret = -EINVAL;
    397         }
    398 
    399     if ( NO_ERROR == ret )
    400         {
    401         OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
    402         expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
    403 
    404         /// If frameCount>0 but evCount<=0, then this is the case of HQ burst.
    405         //Otherwise, it is normal HQ capture
    406         ///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing.
    407         if ( 0 == evCount && 0 == frameCount )
    408             {
    409             expCapMode.bFrameLimited = OMX_FALSE;
    410             }
    411         else
    412             {
    413             expCapMode.bFrameLimited = OMX_TRUE;
    414             expCapMode.nFrameLimit = frameCount;
    415             }
    416 
    417         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    418                                 OMX_IndexConfigCaptureMode,
    419                                 &expCapMode);
    420         if ( OMX_ErrorNone != eError )
    421             {
    422             CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
    423             }
    424         else
    425             {
    426             CAMHAL_LOGDA("Camera capture mode configured successfully");
    427             }
    428         }
    429 
    430     if ( NO_ERROR == ret )
    431         {
    432         OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
    433         extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
    434 
    435         if ( 0 == evCount )
    436             {
    437             extExpCapMode.bEnableBracketing = OMX_FALSE;
    438             }
    439         else
    440             {
    441             extExpCapMode.bEnableBracketing = OMX_TRUE;
    442             extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketExposureRelativeInEV;
    443             extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1;
    444             }
    445 
    446         for ( unsigned int i = 0 ; i < evCount ; i++ )
    447             {
    448             extExpCapMode.tBracketConfigType.nBracketValues[i]  =  ( evValues[i] * ( 1 << Q16_OFFSET ) )  / 10;
    449             }
    450 
    451         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    452                                 ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
    453                                 &extExpCapMode);
    454         if ( OMX_ErrorNone != eError )
    455             {
    456             CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
    457             }
    458         else
    459             {
    460             CAMHAL_LOGDA("Extended camera capture mode configured successfully");
    461             }
    462         }
    463 
    464     LOG_FUNCTION_NAME_EXIT;
    465 
    466     return ret;
    467 }
    468 
    469 status_t OMXCameraAdapter::setShutterCallback(bool enabled)
    470 {
    471     status_t ret = NO_ERROR;
    472     OMX_ERRORTYPE eError = OMX_ErrorNone;
    473     OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback;
    474 
    475     LOG_FUNCTION_NAME;
    476 
    477     if ( OMX_StateExecuting != mComponentState )
    478         {
    479         CAMHAL_LOGEA("OMX component not in executing state");
    480         ret = -1;
    481         }
    482 
    483     if ( NO_ERROR == ret )
    484         {
    485 
    486         OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
    487         shutterRequstCallback.nPortIndex = OMX_ALL;
    488 
    489         if ( enabled )
    490             {
    491             shutterRequstCallback.bEnable = OMX_TRUE;
    492             shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
    493             CAMHAL_LOGDA("Enabling shutter callback");
    494             }
    495         else
    496             {
    497             shutterRequstCallback.bEnable = OMX_FALSE;
    498             shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
    499             CAMHAL_LOGDA("Disabling shutter callback");
    500             }
    501 
    502         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    503                                 ( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest,
    504                                 &shutterRequstCallback);
    505         if ( OMX_ErrorNone != eError )
    506             {
    507             CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError);
    508             ret = -1;
    509             }
    510         else
    511             {
    512             CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully",
    513                          OMX_TI_IndexConfigShutterCallback);
    514             }
    515         }
    516 
    517     LOG_FUNCTION_NAME_EXIT;
    518 
    519     return ret;
    520 }
    521 
    522 status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader,
    523                                         CameraFrame::FrameType typeOfFrame)
    524 {
    525     status_t ret = NO_ERROR;
    526     int currentBufferIdx, nextBufferIdx;
    527     OMXCameraPortParameters * imgCaptureData = NULL;
    528 
    529     LOG_FUNCTION_NAME;
    530 
    531     imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    532 
    533     if ( OMX_StateExecuting != mComponentState )
    534         {
    535         CAMHAL_LOGEA("OMX component is not in executing state");
    536         ret = -EINVAL;
    537         }
    538 
    539     if ( NO_ERROR == ret )
    540         {
    541         currentBufferIdx = ( unsigned int ) pBuffHeader->pAppPrivate;
    542 
    543         if ( currentBufferIdx >= imgCaptureData->mNumBufs)
    544             {
    545             CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx);
    546             ret = -EINVAL;
    547             }
    548         }
    549 
    550     if ( NO_ERROR == ret )
    551         {
    552         mBracketingBuffersQueued[currentBufferIdx] = false;
    553         mBracketingBuffersQueuedCount--;
    554 
    555         if ( 0 >= mBracketingBuffersQueuedCount )
    556             {
    557             nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs;
    558             mBracketingBuffersQueued[nextBufferIdx] = true;
    559             mBracketingBuffersQueuedCount++;
    560             mLastBracetingBufferIdx = nextBufferIdx;
    561             setFrameRefCount(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame, 1);
    562             returnFrame(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame);
    563             }
    564         }
    565 
    566     LOG_FUNCTION_NAME_EXIT;
    567 
    568     return ret;
    569 }
    570 
    571 status_t OMXCameraAdapter::sendBracketFrames()
    572 {
    573     status_t ret = NO_ERROR;
    574     int currentBufferIdx;
    575     OMXCameraPortParameters * imgCaptureData = NULL;
    576 
    577     LOG_FUNCTION_NAME;
    578 
    579     imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    580 
    581     if ( OMX_StateExecuting != mComponentState )
    582         {
    583         CAMHAL_LOGEA("OMX component is not in executing state");
    584         ret = -EINVAL;
    585         }
    586 
    587     if ( NO_ERROR == ret )
    588         {
    589 
    590         currentBufferIdx = mLastBracetingBufferIdx;
    591         do
    592             {
    593             currentBufferIdx++;
    594             currentBufferIdx %= imgCaptureData->mNumBufs;
    595             if (!mBracketingBuffersQueued[currentBufferIdx] )
    596                 {
    597                 CameraFrame cameraFrame;
    598                 sendCallBacks(cameraFrame,
    599                               imgCaptureData->mBufferHeader[currentBufferIdx],
    600                               imgCaptureData->mImageType,
    601                               imgCaptureData);
    602                 }
    603             } while ( currentBufferIdx != mLastBracetingBufferIdx );
    604 
    605         }
    606 
    607     LOG_FUNCTION_NAME_EXIT;
    608 
    609     return ret;
    610 }
    611 
    612 status_t OMXCameraAdapter::startBracketing(int range)
    613 {
    614     status_t ret = NO_ERROR;
    615     OMXCameraPortParameters * imgCaptureData = NULL;
    616 
    617     LOG_FUNCTION_NAME;
    618 
    619     imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    620 
    621     if ( OMX_StateExecuting != mComponentState )
    622         {
    623         CAMHAL_LOGEA("OMX component is not in executing state");
    624         ret = -EINVAL;
    625         }
    626 
    627         {
    628         Mutex::Autolock lock(mBracketingLock);
    629 
    630         if ( mBracketingEnabled )
    631             {
    632             return ret;
    633             }
    634         }
    635 
    636     if ( 0 == imgCaptureData->mNumBufs )
    637         {
    638         CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs);
    639         ret = -EINVAL;
    640         }
    641 
    642     if ( mPending3Asettings )
    643         apply3Asettings(mParameters3A);
    644 
    645     if ( NO_ERROR == ret )
    646         {
    647         Mutex::Autolock lock(mBracketingLock);
    648 
    649         mBracketingRange = range;
    650         mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs];
    651         if ( NULL == mBracketingBuffersQueued )
    652             {
    653             CAMHAL_LOGEA("Unable to allocate bracketing management structures");
    654             ret = -1;
    655             }
    656 
    657         if ( NO_ERROR == ret )
    658             {
    659             mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs;
    660             mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1;
    661 
    662             for ( int i = 0 ; i  < imgCaptureData->mNumBufs ; i++ )
    663                 {
    664                 mBracketingBuffersQueued[i] = true;
    665                 }
    666 
    667             }
    668         }
    669 
    670     if ( NO_ERROR == ret )
    671         {
    672 
    673         ret = startImageCapture();
    674             {
    675             Mutex::Autolock lock(mBracketingLock);
    676 
    677             if ( NO_ERROR == ret )
    678                 {
    679                 mBracketingEnabled = true;
    680                 }
    681             else
    682                 {
    683                 mBracketingEnabled = false;
    684                 }
    685             }
    686         }
    687 
    688     LOG_FUNCTION_NAME_EXIT;
    689 
    690     return ret;
    691 }
    692 
    693 status_t OMXCameraAdapter::stopBracketing()
    694 {
    695   status_t ret = NO_ERROR;
    696 
    697     LOG_FUNCTION_NAME;
    698 
    699     Mutex::Autolock lock(mBracketingLock);
    700 
    701     if ( NULL != mBracketingBuffersQueued )
    702     {
    703         delete [] mBracketingBuffersQueued;
    704     }
    705 
    706     ret = stopImageCapture();
    707 
    708     mBracketingBuffersQueued = NULL;
    709     mBracketingEnabled = false;
    710     mBracketingBuffersQueuedCount = 0;
    711     mLastBracetingBufferIdx = 0;
    712 
    713     LOG_FUNCTION_NAME_EXIT;
    714 
    715     return ret;
    716 }
    717 
    718 status_t OMXCameraAdapter::startImageCapture()
    719 {
    720     status_t ret = NO_ERROR;
    721     OMX_ERRORTYPE eError = OMX_ErrorNone;
    722     OMXCameraPortParameters * capData = NULL;
    723     OMX_CONFIG_BOOLEANTYPE bOMX;
    724 
    725     LOG_FUNCTION_NAME;
    726 
    727     if(!mCaptureConfigured)
    728         {
    729         ///Image capture was cancelled before we could start
    730         return NO_ERROR;
    731         }
    732 
    733     if ( 0 != mStartCaptureSem.Count() )
    734         {
    735         CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count());
    736         return NO_INIT;
    737         }
    738 
    739     if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) {
    740         CAMHAL_LOGDA("trying starting capture when already canceled");
    741         return NO_ERROR;
    742     }
    743 
    744     // Camera framework doesn't expect face callbacks once capture is triggered
    745     pauseFaceDetection(true);
    746 
    747     //During bracketing image capture is already active
    748     {
    749     Mutex::Autolock lock(mBracketingLock);
    750     if ( mBracketingEnabled )
    751         {
    752         //Stop bracketing, activate normal burst for the remaining images
    753         mBracketingEnabled = false;
    754         mCapturedFrames = mBracketingRange;
    755         ret = sendBracketFrames();
    756         if(ret != NO_ERROR)
    757             goto EXIT;
    758         else
    759             return ret;
    760         }
    761     }
    762 
    763     if ( NO_ERROR == ret ) {
    764         if (mPendingCaptureSettings & SetRotation) {
    765             mPendingCaptureSettings &= ~SetRotation;
    766             ret = setPictureRotation(mPictureRotation);
    767             if ( NO_ERROR != ret ) {
    768                 CAMHAL_LOGEB("Error configuring image rotation %x", ret);
    769             }
    770         }
    771     }
    772 
    773     // need to enable wb data for video snapshot to fill in exif data
    774     if ((ret == NO_ERROR) && (mCapMode == VIDEO_MODE)) {
    775         // video snapshot uses wb data from snapshot frame
    776         ret = setExtraData(true, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance);
    777     }
    778 
    779     //OMX shutter callback events are only available in hq mode
    780     if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
    781         {
    782 
    783         if ( NO_ERROR == ret )
    784             {
    785             ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
    786                                         (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
    787                                         OMX_ALL,
    788                                         OMX_TI_IndexConfigShutterCallback,
    789                                         mStartCaptureSem);
    790             }
    791 
    792         if ( NO_ERROR == ret )
    793             {
    794             ret = setShutterCallback(true);
    795             }
    796 
    797         }
    798 
    799     if ( NO_ERROR == ret ) {
    800         capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    801 
    802         ///Queue all the buffers on capture port
    803         for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
    804             CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x",
    805                          ( unsigned int ) capData->mBufferHeader[index]->pBuffer);
    806             eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
    807                         (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
    808 
    809             GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
    810         }
    811 
    812         mWaitingForSnapshot = true;
    813         mCaptureSignalled = false;
    814 
    815         // Capturing command is not needed when capturing in video mode
    816         // Only need to queue buffers on image ports
    817         if (mCapMode != VIDEO_MODE) {
    818             OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
    819             bOMX.bEnabled = OMX_TRUE;
    820 
    821             /// sending Capturing Command to the component
    822             eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    823                                    OMX_IndexConfigCapturing,
    824                                    &bOMX);
    825 
    826             CAMHAL_LOGDB("Capture set - 0x%x", eError);
    827 
    828             GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
    829         }
    830     }
    831 
    832     //OMX shutter callback events are only available in hq mode
    833     if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
    834         {
    835 
    836         if ( NO_ERROR == ret )
    837             {
    838             ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
    839             }
    840 
    841         //If something bad happened while we wait
    842         if (mComponentState != OMX_StateExecuting)
    843           {
    844             CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!");
    845             goto EXIT;
    846           }
    847 
    848         if ( NO_ERROR == ret )
    849             {
    850             CAMHAL_LOGDA("Shutter callback received");
    851             notifyShutterSubscribers();
    852             }
    853         else
    854             {
    855             ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
    856                                (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
    857                                OMX_ALL,
    858                                OMX_TI_IndexConfigShutterCallback,
    859                                NULL);
    860             CAMHAL_LOGEA("Timeout expired on shutter callback");
    861             goto EXIT;
    862             }
    863 
    864         }
    865 
    866     return (ret | ErrorUtils::omxToAndroidError(eError));
    867 
    868 EXIT:
    869     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
    870     setExtraData(false, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance);
    871     mWaitingForSnapshot = false;
    872     mCaptureSignalled = false;
    873     performCleanupAfterError();
    874     LOG_FUNCTION_NAME_EXIT;
    875     return (ret | ErrorUtils::omxToAndroidError(eError));
    876 }
    877 
    878 status_t OMXCameraAdapter::stopImageCapture()
    879 {
    880     status_t ret = NO_ERROR;
    881     OMX_ERRORTYPE eError = OMX_ErrorNone;
    882     OMX_CONFIG_BOOLEANTYPE bOMX;
    883     OMXCameraPortParameters *imgCaptureData = NULL;
    884 
    885     LOG_FUNCTION_NAME;
    886 
    887     if (!mCaptureConfigured) {
    888         //Capture is not ongoing, return from here
    889         return NO_ERROR;
    890     }
    891 
    892     if ( 0 != mStopCaptureSem.Count() ) {
    893         CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count());
    894         goto EXIT;
    895     }
    896 
    897     //Disable the callback first
    898     mWaitingForSnapshot = false;
    899     mSnapshotCount = 0;
    900 
    901     // OMX shutter callback events are only available in hq mode
    902     if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
    903         //Disable the callback first
    904         ret = setShutterCallback(false);
    905 
    906         // if anybody is waiting on the shutter callback
    907         // signal them and then recreate the semaphore
    908         if ( 0 != mStartCaptureSem.Count() ) {
    909 
    910             for (int i = mStartCaptureSem.Count(); i < 0; i++) {
    911             ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
    912                                (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
    913                                OMX_ALL,
    914                                OMX_TI_IndexConfigShutterCallback,
    915                                NULL );
    916             }
    917             mStartCaptureSem.Create(0);
    918         }
    919     }
    920 
    921     // After capture, face detection should be disabled
    922     // and application needs to restart face detection
    923     stopFaceDetection();
    924 
    925     //Wait here for the capture to be done, in worst case timeout and proceed with cleanup
    926     mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
    927 
    928     //If somethiing bad happened while we wait
    929     if (mComponentState == OMX_StateInvalid)
    930       {
    931         CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!");
    932         goto EXIT;
    933       }
    934 
    935     // Disable image capture
    936     // Capturing command is not needed when capturing in video mode
    937     if (mCapMode != VIDEO_MODE) {
    938         OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
    939         bOMX.bEnabled = OMX_FALSE;
    940         imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    941         eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    942                                OMX_IndexConfigCapturing,
    943                                &bOMX);
    944         if ( OMX_ErrorNone != eError ) {
    945             CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
    946             ret = -1;
    947             goto EXIT;
    948         }
    949     }
    950 
    951     // had to enable wb data for video snapshot to fill in exif data
    952     // now that we are done...disable
    953     if ((ret == NO_ERROR) && (mCapMode == VIDEO_MODE)) {
    954         ret = setExtraData(false, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance);
    955     }
    956 
    957     CAMHAL_LOGDB("Capture set - 0x%x", eError);
    958 
    959     mCaptureSignalled = true; //set this to true if we exited because of timeout
    960 
    961     {
    962         Mutex::Autolock lock(mFrameCountMutex);
    963         mFrameCount = 0;
    964         mFirstFrameCondition.broadcast();
    965     }
    966 
    967     return (ret | ErrorUtils::omxToAndroidError(eError));
    968 
    969 EXIT:
    970     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
    971     //Release image buffers
    972     if ( NULL != mReleaseImageBuffersCallback ) {
    973         mReleaseImageBuffersCallback(mReleaseData);
    974     }
    975 
    976     {
    977         Mutex::Autolock lock(mFrameCountMutex);
    978         mFrameCount = 0;
    979         mFirstFrameCondition.broadcast();
    980     }
    981 
    982     performCleanupAfterError();
    983     LOG_FUNCTION_NAME_EXIT;
    984     return (ret | ErrorUtils::omxToAndroidError(eError));
    985 }
    986 
    987 status_t OMXCameraAdapter::disableImagePort(){
    988     status_t ret = NO_ERROR;
    989     OMX_ERRORTYPE eError = OMX_ErrorNone;
    990     OMXCameraPortParameters *imgCaptureData = NULL;
    991 
    992     if (!mCaptureConfigured) {
    993         return NO_ERROR;
    994     }
    995 
    996     mCaptureConfigured = false;
    997     imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    998 
    999     ///Register for Image port Disable event
   1000     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
   1001                                 OMX_EventCmdComplete,
   1002                                 OMX_CommandPortDisable,
   1003                                 mCameraAdapterParameters.mImagePortIndex,
   1004                                 mStopCaptureSem);
   1005     ///Disable Capture Port
   1006     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
   1007                                 OMX_CommandPortDisable,
   1008                                 mCameraAdapterParameters.mImagePortIndex,
   1009                                 NULL);
   1010 
   1011     ///Free all the buffers on capture port
   1012     if (imgCaptureData) {
   1013         CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
   1014         for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
   1015             CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
   1016                          ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
   1017             eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
   1018                                     mCameraAdapterParameters.mImagePortIndex,
   1019                                     (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
   1020 
   1021             GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
   1022         }
   1023     }
   1024     CAMHAL_LOGDA("Waiting for port disable");
   1025     //Wait for the image port enable event
   1026     ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
   1027 
   1028     //If somethiing bad happened while we wait
   1029     if (mComponentState == OMX_StateInvalid)
   1030       {
   1031         CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
   1032         goto EXIT;
   1033       }
   1034 
   1035     if ( NO_ERROR == ret ) {
   1036         CAMHAL_LOGDA("Port disabled");
   1037     } else {
   1038         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
   1039                            OMX_EventCmdComplete,
   1040                            OMX_CommandPortDisable,
   1041                            mCameraAdapterParameters.mImagePortIndex,
   1042                            NULL);
   1043         CAMHAL_LOGDA("Timeout expired on port disable");
   1044         goto EXIT;
   1045     }
   1046 
   1047  EXIT:
   1048     return (ret | ErrorUtils::omxToAndroidError(eError));
   1049 }
   1050 
   1051 
   1052 status_t OMXCameraAdapter::UseBuffersCapture(void* bufArr, int num)
   1053 {
   1054     LOG_FUNCTION_NAME;
   1055 
   1056     status_t ret = NO_ERROR;
   1057     OMX_ERRORTYPE eError = OMX_ErrorNone;
   1058     OMXCameraPortParameters * imgCaptureData = NULL;
   1059     uint32_t *buffers = (uint32_t*)bufArr;
   1060     OMXCameraPortParameters cap;
   1061 
   1062     imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
   1063 
   1064     if ( 0 != mUseCaptureSem.Count() )
   1065         {
   1066         CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
   1067         return BAD_VALUE;
   1068         }
   1069 
   1070     // capture is already configured...we can skip this step
   1071     if (mCaptureConfigured) {
   1072 
   1073         if ( NO_ERROR == ret )
   1074             {
   1075             ret = setupEXIF();
   1076             if ( NO_ERROR != ret )
   1077                 {
   1078                 CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
   1079                 }
   1080             }
   1081 
   1082         mCapturedFrames = mBurstFrames;
   1083         return NO_ERROR;
   1084     }
   1085 
   1086     imgCaptureData->mNumBufs = num;
   1087 
   1088     //TODO: Support more pixelformats
   1089 
   1090     CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
   1091     CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mWidth);
   1092 
   1093     if (mPendingCaptureSettings & SetFormat) {
   1094         mPendingCaptureSettings &= ~SetFormat;
   1095         ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
   1096         if ( ret != NO_ERROR ) {
   1097             CAMHAL_LOGEB("setFormat() failed %d", ret);
   1098             LOG_FUNCTION_NAME_EXIT;
   1099             return ret;
   1100         }
   1101     }
   1102 
   1103     if (mPendingCaptureSettings & SetThumb) {
   1104         mPendingCaptureSettings &= ~SetThumb;
   1105         ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
   1106         if ( NO_ERROR != ret) {
   1107             CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
   1108             return ret;
   1109         }
   1110     }
   1111 
   1112     if (mPendingCaptureSettings & SetExpBracket) {
   1113         mPendingCaptureSettings &= ~SetExpBracket;
   1114         ret = setExposureBracketing( mExposureBracketingValues,
   1115                                      mExposureBracketingValidEntries, mBurstFrames);
   1116         if ( ret != NO_ERROR ) {
   1117             CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
   1118             goto EXIT;
   1119         }
   1120     }
   1121 
   1122     if (mPendingCaptureSettings & SetQuality) {
   1123         mPendingCaptureSettings &= ~SetQuality;
   1124         ret = setImageQuality(mPictureQuality);
   1125         if ( NO_ERROR != ret) {
   1126             CAMHAL_LOGEB("Error configuring image quality %x", ret);
   1127             goto EXIT;
   1128         }
   1129     }
   1130 
   1131     ///Register for Image port ENABLE event
   1132     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
   1133                            OMX_EventCmdComplete,
   1134                            OMX_CommandPortEnable,
   1135                            mCameraAdapterParameters.mImagePortIndex,
   1136                            mUseCaptureSem);
   1137 
   1138     ///Enable Capture Port
   1139     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
   1140                              OMX_CommandPortEnable,
   1141                              mCameraAdapterParameters.mImagePortIndex,
   1142                              NULL);
   1143 
   1144     CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
   1145     GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
   1146 
   1147     for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++ )
   1148     {
   1149         OMX_BUFFERHEADERTYPE *pBufferHdr;
   1150         CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
   1151                      (unsigned int)buffers[index],
   1152                      (int)imgCaptureData->mBufSize);
   1153 
   1154         eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
   1155                                &pBufferHdr,
   1156                                mCameraAdapterParameters.mImagePortIndex,
   1157                                0,
   1158                                mCaptureBuffersLength,
   1159                                (OMX_U8*)buffers[index]);
   1160 
   1161         CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
   1162         GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
   1163 
   1164         pBufferHdr->pAppPrivate = (OMX_PTR) index;
   1165         pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
   1166         pBufferHdr->nVersion.s.nVersionMajor = 1 ;
   1167         pBufferHdr->nVersion.s.nVersionMinor = 1 ;
   1168         pBufferHdr->nVersion.s.nRevision = 0;
   1169         pBufferHdr->nVersion.s.nStep =  0;
   1170         imgCaptureData->mBufferHeader[index] = pBufferHdr;
   1171     }
   1172 
   1173     //Wait for the image port enable event
   1174     CAMHAL_LOGDA("Waiting for port enable");
   1175     ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
   1176 
   1177     //If somethiing bad happened while we wait
   1178     if (mComponentState == OMX_StateInvalid)
   1179       {
   1180         CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!");
   1181         goto EXIT;
   1182       }
   1183 
   1184     if ( ret == NO_ERROR )
   1185         {
   1186         CAMHAL_LOGDA("Port enabled");
   1187         }
   1188     else
   1189         {
   1190         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
   1191                            OMX_EventCmdComplete,
   1192                            OMX_CommandPortEnable,
   1193                            mCameraAdapterParameters.mImagePortIndex,
   1194                            NULL);
   1195         CAMHAL_LOGDA("Timeout expired on port enable");
   1196         goto EXIT;
   1197         }
   1198 
   1199     if ( NO_ERROR == ret )
   1200         {
   1201         ret = setupEXIF();
   1202         if ( NO_ERROR != ret )
   1203             {
   1204             CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
   1205             }
   1206         }
   1207 
   1208     mCapturedFrames = mBurstFrames;
   1209     mCaptureConfigured = true;
   1210 
   1211     return (ret | ErrorUtils::omxToAndroidError(eError));
   1212 
   1213 EXIT:
   1214     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
   1215     //Release image buffers
   1216     if ( NULL != mReleaseImageBuffersCallback ) {
   1217         mReleaseImageBuffersCallback(mReleaseData);
   1218     }
   1219     performCleanupAfterError();
   1220     LOG_FUNCTION_NAME_EXIT;
   1221     return (ret | ErrorUtils::omxToAndroidError(eError));
   1222 
   1223 }
   1224 
   1225 };
   1226