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 /**
     19 * @file OMXFocus.cpp
     20 *
     21 * This file contains functionality for handling focus configurations.
     22 *
     23 */
     24 
     25 #include "CameraHal.h"
     26 #include "OMXCameraAdapter.h"
     27 #include "ErrorUtils.h"
     28 
     29 #define TOUCH_FOCUS_RANGE 0xFF
     30 #define AF_IMAGE_CALLBACK_TIMEOUT 5000000 //5 seconds timeout
     31 #define AF_VIDEO_CALLBACK_TIMEOUT 2800000 //2.8 seconds timeout
     32 
     33 namespace Ti {
     34 namespace Camera {
     35 
     36 const nsecs_t OMXCameraAdapter::CANCEL_AF_TIMEOUT =  seconds_to_nanoseconds(1);
     37 
     38 status_t OMXCameraAdapter::setParametersFocus(const android::CameraParameters &params,
     39                                               BaseCameraAdapter::AdapterState state)
     40 {
     41     status_t ret = NO_ERROR;
     42     const char *str = NULL;
     43     android::Vector<android::sp<CameraArea> > tempAreas;
     44     size_t MAX_FOCUS_AREAS;
     45 
     46     LOG_FUNCTION_NAME;
     47 
     48     android::AutoMutex lock(mFocusAreasLock);
     49 
     50     str = params.get(android::CameraParameters::KEY_FOCUS_AREAS);
     51 
     52     MAX_FOCUS_AREAS = atoi(params.get(android::CameraParameters::KEY_MAX_NUM_FOCUS_AREAS));
     53 
     54     if ( NULL != str ) {
     55         ret = CameraArea::parseAreas(str, ( strlen(str) + 1 ), tempAreas);
     56     }
     57 
     58     if ( (NO_ERROR == ret) && CameraArea::areAreasDifferent(mFocusAreas, tempAreas) ) {
     59         mFocusAreas.clear();
     60         mFocusAreas = tempAreas;
     61         if ( MAX_FOCUS_AREAS < mFocusAreas.size() ) {
     62             CAMHAL_LOGEB("Focus areas supported %d, focus areas set %d",
     63                          MAX_FOCUS_AREAS,
     64                          mFocusAreas.size());
     65             ret = -EINVAL;
     66         }
     67         else {
     68             if ( !mFocusAreas.isEmpty() ) {
     69                 setTouchFocus();
     70             }
     71         }
     72     }
     73 
     74     LOG_FUNCTION_NAME_EXIT;
     75 
     76     return ret;
     77 }
     78 
     79 status_t OMXCameraAdapter::doAutoFocus()
     80 {
     81     status_t ret = NO_ERROR;
     82     OMX_ERRORTYPE eError = OMX_ErrorNone;
     83     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
     84     OMX_PARAM_FOCUSSTATUSTYPE focusStatus;
     85     OMX_CONFIG_BOOLEANTYPE bOMX;
     86     CameraAdapter::AdapterState state;
     87     nsecs_t timeout = 0;
     88 
     89     LOG_FUNCTION_NAME;
     90 
     91     if ( OMX_StateInvalid == mComponentState )
     92       {
     93         CAMHAL_LOGEA("OMX component in Invalid state");
     94         returnFocusStatus(false);
     95         return -EINVAL;
     96       }
     97 
     98     if ( OMX_StateExecuting != mComponentState )
     99         {
    100         CAMHAL_LOGEA("OMX component not in executing state");
    101         returnFocusStatus(false);
    102         return NO_ERROR;
    103         }
    104 
    105     if( ((AF_ACTIVE & getState()) != AF_ACTIVE) && ((AF_ACTIVE & getNextState()) != AF_ACTIVE) ) {
    106        CAMHAL_LOGDA("Auto focus got canceled before doAutoFocus could be called");
    107        return NO_ERROR;
    108     }
    109 
    110     // AF when fixed focus modes are set should be a no-op.
    111     if ( ( mParameters3A.Focus == OMX_IMAGE_FocusControlOff ) ||
    112          ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) ||
    113          ( mParameters3A.Focus == OMX_IMAGE_FocusControlHyperfocal ) ) {
    114         returnFocusStatus(true);
    115         return NO_ERROR;
    116     }
    117 
    118     OMX_INIT_STRUCT_PTR (&focusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
    119 
    120     // If the app calls autoFocus, the camera will stop sending face callbacks.
    121     pauseFaceDetection(true);
    122 
    123     // This is needed for applying FOCUS_REGION correctly
    124     if ( (!mFocusAreas.isEmpty()) && (!mFocusAreas.itemAt(0)->isZeroArea()))
    125     {
    126     //Disable face priority
    127     setAlgoPriority(FACE_PRIORITY, FOCUS_ALGO, false);
    128 
    129     //Enable region algorithm priority
    130     setAlgoPriority(REGION_PRIORITY, FOCUS_ALGO, true);
    131     }
    132 
    133     OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
    134     focusControl.eFocusControl = ( OMX_IMAGE_FOCUSCONTROLTYPE ) mParameters3A.Focus;
    135 
    136     if (mParameters3A.FocusLock) {
    137         // this basically means user never called cancelAutoFocus after a scan...
    138         // if this is the case we need to unlock AF to ensure we will do a scan
    139         if (set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_FALSE) != NO_ERROR) {
    140             CAMHAL_LOGEA("Error Unlocking 3A locks");
    141         } else {
    142             CAMHAL_LOGDA("AE/AWB unlocked successfully");
    143         }
    144 
    145     } else if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAuto ) {
    146         // In case we have CAF running we should first check the AF status.
    147         // If it has managed to lock, then do as usual and return status
    148         // immediately.
    149         ret = checkFocus(&focusStatus);
    150         if ( NO_ERROR != ret ) {
    151             CAMHAL_LOGEB("Focus status check failed 0x%x!", ret);
    152             return ret;
    153         } else {
    154             CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus);
    155         }
    156     }
    157 
    158     if ( (focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto &&
    159          ( focusStatus.eFocusStatus == OMX_FocusStatusRequest ||
    160            focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach ||
    161            focusStatus.eFocusStatus == OMX_FocusStatusLost ) ) ||
    162             (mParameters3A.Focus !=  (OMX_IMAGE_FOCUSCONTROLTYPE)OMX_IMAGE_FocusControlAuto) ) {
    163         OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
    164         bOMX.bEnabled = OMX_TRUE;
    165 
    166         //Enable focus scanning
    167         eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    168                                (OMX_INDEXTYPE)OMX_TI_IndexConfigAutofocusEnable,
    169                                &bOMX);
    170         if ( OMX_ErrorNone != eError ) {
    171             return Utils::ErrorUtils::omxToAndroidError(eError);
    172         }
    173 
    174         {
    175             android::AutoMutex lock(mDoAFMutex);
    176 
    177         // force AF, Ducati will take care of whether CAF
    178         // or AF will be performed, depending on light conditions
    179         if ( focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto &&
    180              ( focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach ||
    181                focusStatus.eFocusStatus == OMX_FocusStatusLost ) ) {
    182             focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock;
    183         }
    184 
    185             eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    186                                     OMX_IndexConfigFocusControl,
    187                                     &focusControl);
    188 
    189             if ( OMX_ErrorNone != eError ) {
    190                 CAMHAL_LOGEB("Error while starting focus 0x%x", eError);
    191                 return INVALID_OPERATION;
    192             } else {
    193                 CAMHAL_LOGDA("Autofocus started successfully");
    194             }
    195 
    196             // No need to wait if preview is about to stop
    197             getNextState(state);
    198             if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE ) {
    199                 return NO_ERROR;
    200             }
    201 
    202             // configure focus timeout based on capture mode
    203             timeout = (mCapMode == VIDEO_MODE) || (mCapMode == VIDEO_MODE_HQ) ?
    204                             ( ( nsecs_t ) AF_VIDEO_CALLBACK_TIMEOUT * 1000 ) :
    205                             ( ( nsecs_t ) AF_IMAGE_CALLBACK_TIMEOUT * 1000 );
    206 
    207 
    208             ret = mDoAFCond.waitRelative(mDoAFMutex, timeout);
    209         }
    210 
    211         //If somethiing bad happened while we wait
    212         if (mComponentState == OMX_StateInvalid) {
    213           CAMHAL_LOGEA("Invalid State after Auto Focus Exitting!!!");
    214           return -EINVAL;
    215         }
    216 
    217         if(ret != NO_ERROR) {
    218             CAMHAL_LOGEA("Autofocus callback timeout expired");
    219             ret = returnFocusStatus(true);
    220         } else {
    221             CAMHAL_LOGDA("Autofocus callback received");
    222             ret = returnFocusStatus(false);
    223         }
    224     } else { // Focus mode in continuous
    225         if ( NO_ERROR == ret ) {
    226             ret = returnFocusStatus(true);
    227             mPending3Asettings |= SetFocus;
    228         }
    229     }
    230 
    231     LOG_FUNCTION_NAME_EXIT;
    232 
    233     return ret;
    234 }
    235 
    236 status_t OMXCameraAdapter::stopAutoFocus()
    237 {
    238     OMX_ERRORTYPE eError = OMX_ErrorNone;
    239     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
    240 
    241     LOG_FUNCTION_NAME;
    242 
    243     if ( OMX_StateInvalid == mComponentState )  {
    244         CAMHAL_LOGEA("OMX component in Invalid state");
    245         returnFocusStatus(false);
    246         return -EINVAL;
    247     }
    248 
    249     if ( OMX_StateExecuting != mComponentState ) {
    250           CAMHAL_LOGEA("OMX component not in executing state");
    251         return NO_ERROR;
    252     }
    253 
    254     if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) {
    255         // No need to stop focus if we are in infinity mode. Nothing to stop.
    256         return NO_ERROR;
    257     }
    258 
    259     OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
    260     focusControl.eFocusControl = OMX_IMAGE_FocusControlOff;
    261 
    262     eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    263                             OMX_IndexConfigFocusControl,
    264                             &focusControl);
    265     if ( OMX_ErrorNone != eError ) {
    266         CAMHAL_LOGEB("Error while stopping focus 0x%x", eError);
    267         return Utils::ErrorUtils::omxToAndroidError(eError);
    268     }
    269 #ifdef CAMERAHAL_TUNA
    270     else {
    271         // This is a WA. Usually the OMX Camera component should
    272         // generate AF status change OMX event fairly quickly
    273         // ( after one preview frame ) and this notification should
    274         // actually come from 'handleFocusCallback()'.
    275         android::AutoMutex lock(mDoAFMutex);
    276         mDoAFCond.broadcast();
    277     }
    278 #endif
    279 
    280     LOG_FUNCTION_NAME_EXIT;
    281 
    282     return NO_ERROR;
    283 }
    284 
    285 status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode)
    286 {;
    287     OMX_ERRORTYPE eError = OMX_ErrorNone;
    288 
    289     LOG_FUNCTION_NAME;
    290 
    291     if ( OMX_StateInvalid == mComponentState ) {
    292         CAMHAL_LOGEA("OMX component is in invalid state");
    293         return NO_INIT;
    294     }
    295 
    296     OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
    297     focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
    298 
    299     eError =  OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    300                             OMX_IndexConfigFocusControl,
    301                             &focusMode);
    302 
    303     if ( OMX_ErrorNone != eError ) {
    304         CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError);
    305     }
    306 
    307     LOG_FUNCTION_NAME_EXIT;
    308 
    309     return Utils::ErrorUtils::omxToAndroidError(eError);
    310 }
    311 
    312 status_t OMXCameraAdapter::cancelAutoFocus()
    313 {
    314     status_t ret = NO_ERROR;
    315     OMX_ERRORTYPE eError = OMX_ErrorNone;
    316     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode;
    317 
    318     LOG_FUNCTION_NAME;
    319 
    320     ret = getFocusMode(focusMode);
    321     if ( NO_ERROR != ret ) {
    322         return ret;
    323     }
    324 
    325     //Stop the AF only for modes other than CAF, Inifinity or Off
    326     if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
    327          ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
    328                  OMX_IMAGE_FocusControlAutoInfinity ) &&
    329          ( focusMode.eFocusControl != OMX_IMAGE_FocusControlOff ) ) {
    330         android::AutoMutex lock(mCancelAFMutex);
    331         stopAutoFocus();
    332         ret = mCancelAFCond.waitRelative(mCancelAFMutex, CANCEL_AF_TIMEOUT);
    333         if ( NO_ERROR != ret ) {
    334             CAMHAL_LOGE("Cancel AF timeout!");
    335         }
    336     } else if (focusMode.eFocusControl == OMX_IMAGE_FocusControlAuto) {
    337        // This re-enabling of CAF doesn't seem to
    338        // be needed any more.
    339        // re-apply CAF after unlocking and canceling
    340        // mPending3Asettings |= SetFocus;
    341     }
    342 
    343     {
    344         // Signal to 'doAutoFocus()'
    345         android::AutoMutex lock(mDoAFMutex);
    346         mDoAFCond.broadcast();
    347     }
    348 
    349     // If the apps call #cancelAutoFocus()}, the face callbacks will also resume.
    350     pauseFaceDetection(false);
    351 
    352     LOG_FUNCTION_NAME_EXIT;
    353 
    354     return ret;
    355 
    356 }
    357 
    358 status_t OMXCameraAdapter::setFocusCallback(bool enabled)
    359 {
    360     status_t ret = NO_ERROR;
    361     OMX_ERRORTYPE eError = OMX_ErrorNone;
    362     OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback;
    363 
    364     LOG_FUNCTION_NAME;
    365 
    366     if ( OMX_StateInvalid == mComponentState )
    367       {
    368         CAMHAL_LOGEA("OMX component in Invalid state");
    369         ret = -EINVAL;
    370       }
    371 
    372     if ( OMX_StateExecuting != mComponentState )
    373         {
    374           CAMHAL_LOGEA("OMX component not in executing state");
    375         return NO_ERROR;
    376         }
    377 
    378     if ( NO_ERROR == ret )
    379         {
    380 
    381         OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
    382         focusRequstCallback.nPortIndex = OMX_ALL;
    383         focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus;
    384 
    385         if ( enabled )
    386             {
    387             focusRequstCallback.bEnable = OMX_TRUE;
    388             }
    389         else
    390             {
    391             focusRequstCallback.bEnable = OMX_FALSE;
    392             }
    393 
    394         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    395                                 (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
    396                                 &focusRequstCallback);
    397         if ( OMX_ErrorNone != eError )
    398             {
    399             CAMHAL_LOGEB("Error registering focus callback 0x%x", eError);
    400             ret = -1;
    401             }
    402         else
    403             {
    404             CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully",
    405                          OMX_IndexConfigCommonFocusStatus);
    406             }
    407         }
    408 
    409     LOG_FUNCTION_NAME_EXIT;
    410 
    411     return ret;
    412 }
    413 
    414 status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached)
    415 {
    416     status_t ret = NO_ERROR;
    417     OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus;
    418     CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
    419     BaseCameraAdapter::AdapterState state, nextState;
    420     BaseCameraAdapter::getState(state);
    421     BaseCameraAdapter::getNextState(nextState);
    422 
    423     LOG_FUNCTION_NAME;
    424 
    425     OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
    426 
    427     if( ((AF_ACTIVE & state ) != AF_ACTIVE) && ((AF_ACTIVE & nextState ) != AF_ACTIVE) )
    428        {
    429         /// We don't send focus callback if focus was not started
    430        CAMHAL_LOGDA("Not sending focus callback because focus was not started");
    431        return NO_ERROR;
    432        }
    433 
    434     if ( NO_ERROR == ret )
    435         {
    436 
    437         if ( !timeoutReached )
    438             {
    439             ret = checkFocus(&eFocusStatus);
    440 
    441             if ( NO_ERROR != ret )
    442                 {
    443                 CAMHAL_LOGEA("Focus status check failed!");
    444                 }
    445             }
    446         }
    447 
    448     if ( NO_ERROR == ret )
    449         {
    450 
    451         if ( timeoutReached )
    452             {
    453             focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
    454             }
    455         else
    456             {
    457             switch (eFocusStatus.eFocusStatus)
    458                 {
    459                     case OMX_FocusStatusReached:
    460                         {
    461                         focusStatus = CameraHalEvent::FOCUS_STATUS_SUCCESS;
    462                         break;
    463                         }
    464                     case OMX_FocusStatusOff: // AF got canceled
    465                         return NO_ERROR;
    466                     case OMX_FocusStatusUnableToReach:
    467                     case OMX_FocusStatusRequest:
    468                     default:
    469                         {
    470                         focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
    471                         break;
    472                         }
    473                 }
    474             // Lock CAF after AF call
    475             if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_TRUE) != NO_ERROR) {
    476                 CAMHAL_LOGEA("Error Applying 3A locks");
    477             } else {
    478                 CAMHAL_LOGDA("Focus locked. Applied focus locks successfully");
    479             }
    480 
    481             stopAutoFocus();
    482             }
    483         //Query current focus distance after AF is complete
    484         updateFocusDistances(mParameters);
    485        }
    486 
    487     ret =  BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS);
    488     if ( NO_ERROR == ret )
    489         {
    490         ret = BaseCameraAdapter::commitState();
    491         }
    492     else
    493         {
    494         ret |= BaseCameraAdapter::rollbackState();
    495         }
    496 
    497     if ( NO_ERROR == ret )
    498         {
    499         notifyFocusSubscribers(focusStatus);
    500         }
    501 
    502     // After focus, face detection will resume sending face callbacks
    503     pauseFaceDetection(false);
    504 
    505     LOG_FUNCTION_NAME_EXIT;
    506 
    507     return ret;
    508 }
    509 
    510 status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus)
    511 {
    512     status_t ret = NO_ERROR;
    513     OMX_ERRORTYPE eError = OMX_ErrorNone;
    514 
    515     LOG_FUNCTION_NAME;
    516 
    517     if ( NULL == eFocusStatus )
    518         {
    519         CAMHAL_LOGEA("Invalid focus status");
    520         ret = -EINVAL;
    521         }
    522 
    523     if ( OMX_StateInvalid == mComponentState )
    524       {
    525         CAMHAL_LOGEA("OMX component in Invalid state");
    526         ret = -EINVAL;
    527       }
    528 
    529     if ( OMX_StateExecuting != mComponentState )
    530         {
    531         CAMHAL_LOGEA("OMX component not in executing state");
    532         ret = NO_ERROR;
    533         }
    534 
    535     if ( NO_ERROR == ret )
    536         {
    537         OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
    538 
    539         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    540                                OMX_IndexConfigCommonFocusStatus,
    541                                eFocusStatus);
    542         if ( OMX_ErrorNone != eError )
    543             {
    544             CAMHAL_LOGEB("Error while retrieving focus status: 0x%x", eError);
    545             ret = -1;
    546             }
    547         }
    548 
    549     if ( NO_ERROR == ret )
    550         {
    551         CAMHAL_LOGDB("Focus Status: %d", eFocusStatus->eFocusStatus);
    552         }
    553 
    554     LOG_FUNCTION_NAME_EXIT;
    555 
    556     return ret;
    557 }
    558 
    559 status_t OMXCameraAdapter::updateFocusDistances(android::CameraParameters &params)
    560 {
    561     OMX_U32 focusNear, focusOptimal, focusFar;
    562     status_t ret = NO_ERROR;
    563 
    564     LOG_FUNCTION_NAME;
    565 
    566     ret = getFocusDistances(focusNear, focusOptimal, focusFar);
    567     if ( NO_ERROR == ret)
    568         {
    569         ret = addFocusDistances(focusNear, focusOptimal, focusFar, params);
    570             if ( NO_ERROR != ret )
    571                 {
    572                 CAMHAL_LOGEB("Error in call to addFocusDistances() 0x%x", ret);
    573                 }
    574         }
    575     else
    576         {
    577         CAMHAL_LOGEB("Error in call to getFocusDistances() 0x%x", ret);
    578         }
    579 
    580     LOG_FUNCTION_NAME_EXIT;
    581 
    582     return ret;
    583 }
    584 
    585 status_t OMXCameraAdapter::getFocusDistances(OMX_U32 &near,OMX_U32 &optimal, OMX_U32 &far)
    586 {
    587     status_t ret = NO_ERROR;
    588     OMX_ERRORTYPE eError;
    589 
    590     OMX_TI_CONFIG_FOCUSDISTANCETYPE focusDist;
    591 
    592     LOG_FUNCTION_NAME;
    593 
    594     if ( OMX_StateInvalid == mComponentState )
    595         {
    596         CAMHAL_LOGEA("OMX component is in invalid state");
    597         ret = UNKNOWN_ERROR;
    598         }
    599 
    600     if ( NO_ERROR == ret )
    601         {
    602         OMX_INIT_STRUCT_PTR(&focusDist, OMX_TI_CONFIG_FOCUSDISTANCETYPE);
    603         focusDist.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
    604 
    605         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    606                                ( OMX_INDEXTYPE ) OMX_TI_IndexConfigFocusDistance,
    607                                &focusDist);
    608         if ( OMX_ErrorNone != eError )
    609             {
    610             CAMHAL_LOGEB("Error while querying focus distances 0x%x", eError);
    611             ret = UNKNOWN_ERROR;
    612             }
    613 
    614         }
    615 
    616     if ( NO_ERROR == ret )
    617         {
    618         near = focusDist.nFocusDistanceNear;
    619         optimal = focusDist.nFocusDistanceOptimal;
    620         far = focusDist.nFocusDistanceFar;
    621         }
    622 
    623     LOG_FUNCTION_NAME_EXIT;
    624 
    625     return ret;
    626 }
    627 
    628 status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_t length)
    629 {
    630     status_t ret = NO_ERROR;
    631     uint32_t focusScale = 1000;
    632     float distFinal;
    633 
    634     LOG_FUNCTION_NAME;
    635 
    636     if(mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity)
    637         {
    638         dist=0;
    639         }
    640 
    641     if ( NO_ERROR == ret )
    642         {
    643         if ( 0 == dist )
    644             {
    645             strncpy(buffer, android::CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 ));
    646             }
    647         else
    648             {
    649             distFinal = dist;
    650             distFinal /= focusScale;
    651             snprintf(buffer, ( length - 1 ) , "%5.3f", distFinal);
    652             }
    653         }
    654 
    655     LOG_FUNCTION_NAME_EXIT;
    656 
    657     return ret;
    658 }
    659 
    660 status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near,
    661                                              OMX_U32 &optimal,
    662                                              OMX_U32 &far,
    663                                              android::CameraParameters& params)
    664 {
    665     status_t ret = NO_ERROR;
    666 
    667     LOG_FUNCTION_NAME;
    668 
    669     if ( NO_ERROR == ret )
    670         {
    671         ret = encodeFocusDistance(near, mFocusDistNear, FOCUS_DIST_SIZE);
    672         if ( NO_ERROR != ret )
    673             {
    674             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
    675             }
    676         }
    677 
    678     if ( NO_ERROR == ret )
    679         {
    680         ret = encodeFocusDistance(optimal, mFocusDistOptimal, FOCUS_DIST_SIZE);
    681         if ( NO_ERROR != ret )
    682             {
    683             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
    684             }
    685         }
    686 
    687     if ( NO_ERROR == ret )
    688         {
    689         ret = encodeFocusDistance(far, mFocusDistFar, FOCUS_DIST_SIZE);
    690         if ( NO_ERROR != ret )
    691             {
    692             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
    693             }
    694         }
    695 
    696     if ( NO_ERROR == ret )
    697         {
    698         snprintf(mFocusDistBuffer, ( FOCUS_DIST_BUFFER_SIZE - 1) ,"%s,%s,%s", mFocusDistNear,
    699                                                                               mFocusDistOptimal,
    700                                                                               mFocusDistFar);
    701 
    702         params.set(android::CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer);
    703         }
    704 
    705     LOG_FUNCTION_NAME_EXIT;
    706 
    707     return ret;
    708 }
    709 
    710 status_t OMXCameraAdapter::setTouchFocus()
    711 {
    712     status_t ret = NO_ERROR;
    713     OMX_ERRORTYPE eError = OMX_ErrorNone;
    714 
    715     OMX_ALGOAREASTYPE *focusAreas;
    716     OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer;
    717     CameraBuffer *bufferlist;
    718     int areasSize = 0;
    719 
    720     LOG_FUNCTION_NAME;
    721 
    722     if ( OMX_StateInvalid == mComponentState )
    723         {
    724         CAMHAL_LOGEA("OMX component is in invalid state");
    725         ret = -1;
    726         }
    727 
    728     if ( NO_ERROR == ret )
    729         {
    730 
    731         areasSize = ((sizeof(OMX_ALGOAREASTYPE)+4095)/4096)*4096;
    732         bufferlist = mMemMgr.allocateBufferList(0, 0, NULL, areasSize, 1);
    733         focusAreas = (OMX_ALGOAREASTYPE*) bufferlist[0].opaque;
    734 
    735         OMXCameraPortParameters * mPreviewData = NULL;
    736         mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
    737 
    738         if (!focusAreas)
    739             {
    740             CAMHAL_LOGEB("Error allocating buffer for focus areas %d", eError);
    741             return -ENOMEM;
    742             }
    743 
    744         OMX_INIT_STRUCT_PTR (focusAreas, OMX_ALGOAREASTYPE);
    745 
    746         focusAreas->nPortIndex = OMX_ALL;
    747         focusAreas->nNumAreas = mFocusAreas.size();
    748         focusAreas->nAlgoAreaPurpose = OMX_AlgoAreaFocus;
    749 
    750         // If the area is the special case of (0, 0, 0, 0, 0), then
    751         // the algorithm needs nNumAreas to be set to 0,
    752         // in order to automatically choose the best fitting areas.
    753         if ( mFocusAreas.itemAt(0)->isZeroArea() )
    754             {
    755             focusAreas->nNumAreas = 0;
    756             }
    757 
    758         for ( unsigned int n = 0; n < mFocusAreas.size(); n++) {
    759             int widthDivisor = 1;
    760             int heightDivisor = 1;
    761 
    762             if (mPreviewData->mFrameLayoutType == OMX_TI_StereoFrameLayoutTopBottom) {
    763                 heightDivisor = 2;
    764             }
    765             if (mPreviewData->mFrameLayoutType == OMX_TI_StereoFrameLayoutLeftRight) {
    766                 widthDivisor = 2;
    767             }
    768 
    769             // transform the coordinates to 3A-type coordinates
    770             mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth/widthDivisor,
    771                                             (size_t)mPreviewData->mHeight/heightDivisor,
    772                                             (size_t&)focusAreas->tAlgoAreas[n].nTop,
    773                                             (size_t&)focusAreas->tAlgoAreas[n].nLeft,
    774                                             (size_t&)focusAreas->tAlgoAreas[n].nWidth,
    775                                             (size_t&)focusAreas->tAlgoAreas[n].nHeight);
    776 
    777             focusAreas->tAlgoAreas[n].nLeft =
    778                     ( focusAreas->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth;
    779             focusAreas->tAlgoAreas[n].nTop =
    780                     ( focusAreas->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight;
    781             focusAreas->tAlgoAreas[n].nWidth =
    782                     ( focusAreas->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth;
    783             focusAreas->tAlgoAreas[n].nHeight =
    784                     ( focusAreas->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight;
    785             focusAreas->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight();
    786 
    787              CAMHAL_LOGDB("Focus area %d : top = %d left = %d width = %d height = %d prio = %d",
    788                     n, (int)focusAreas->tAlgoAreas[n].nTop, (int)focusAreas->tAlgoAreas[n].nLeft,
    789                     (int)focusAreas->tAlgoAreas[n].nWidth, (int)focusAreas->tAlgoAreas[n].nHeight,
    790                     (int)focusAreas->tAlgoAreas[n].nPriority);
    791         }
    792 
    793         OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER);
    794 
    795         sharedBuffer.nPortIndex = OMX_ALL;
    796         sharedBuffer.nSharedBuffSize = areasSize;
    797         sharedBuffer.pSharedBuff = (OMX_U8 *) camera_buffer_get_omx_ptr (&bufferlist[0]);
    798 
    799         if ( NULL == sharedBuffer.pSharedBuff )
    800             {
    801             CAMHAL_LOGEA("No resources to allocate OMX shared buffer");
    802             ret = -ENOMEM;
    803             goto EXIT;
    804             }
    805 
    806             eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    807                                       (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgoAreas, &sharedBuffer);
    808 
    809         if ( OMX_ErrorNone != eError )
    810             {
    811             CAMHAL_LOGEB("Error while setting Focus Areas configuration 0x%x", eError);
    812             ret = -EINVAL;
    813             }
    814 
    815     EXIT:
    816         if (NULL != bufferlist)
    817             {
    818             mMemMgr.freeBufferList (bufferlist);
    819             }
    820         }
    821 
    822     LOG_FUNCTION_NAME_EXIT;
    823 
    824     return ret;
    825 }
    826 
    827 void OMXCameraAdapter::handleFocusCallback() {
    828     OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus;
    829     CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
    830     status_t ret = NO_ERROR;
    831     BaseCameraAdapter::AdapterState nextState;
    832     BaseCameraAdapter::getNextState(nextState);
    833 
    834     OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
    835 
    836     ret = checkFocus(&eFocusStatus);
    837 
    838     if (NO_ERROR != ret) {
    839         CAMHAL_LOGEA("Focus status check failed!");
    840         // signal and unblock doAutoFocus
    841         if (AF_ACTIVE & nextState) {
    842             android::AutoMutex lock(mDoAFMutex);
    843             mDoAFCond.broadcast();
    844         }
    845         return;
    846     }
    847 
    848     if ( eFocusStatus.eFocusStatus == OMX_FocusStatusOff ) {
    849         android::AutoMutex lock(mCancelAFMutex);
    850         mCancelAFCond.signal();
    851         return;
    852     }
    853 
    854     if (eFocusStatus.eFocusStatus != OMX_FocusStatusRequest) {
    855         // signal doAutoFocus when a end of scan message comes
    856         // ignore start of scan
    857         android::AutoMutex lock(mDoAFMutex);
    858         mDoAFCond.broadcast();
    859     }
    860 
    861     if (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE) OMX_IMAGE_FocusControlAuto) {
    862        CAMHAL_LOGDA("unregistered focus callback when not in CAF or doAutoFocus... not handling");
    863        return;
    864     }
    865 
    866     // Handling for CAF Callbacks
    867     switch (eFocusStatus.eFocusStatus) {
    868         case OMX_FocusStatusRequest:
    869             focusStatus = CameraHalEvent::FOCUS_STATUS_PENDING;
    870             break;
    871         case OMX_FocusStatusReached:
    872         case OMX_FocusStatusOff:
    873         case OMX_FocusStatusUnableToReach:
    874         default:
    875             focusStatus = CameraHalEvent::FOCUS_STATUS_DONE;
    876             break;
    877     }
    878 
    879     notifyFocusSubscribers(focusStatus);
    880 }
    881 
    882 } // namespace Camera
    883 } // namespace Ti
    884