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