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_CALLBACK_TIMEOUT 5000000 //5 seconds timeout
     35 
     36 namespace android {
     37 
     38 status_t OMXCameraAdapter::setParametersFocus(const CameraParameters &params,
     39                                               BaseCameraAdapter::AdapterState state)
     40 {
     41     status_t ret = NO_ERROR;
     42     const char *str = NULL;
     43     Vector< sp<CameraArea> > tempAreas;
     44     size_t MAX_FOCUS_AREAS;
     45 
     46     LOG_FUNCTION_NAME;
     47 
     48     Mutex::Autolock lock(mFocusAreasLock);
     49 
     50     str = params.get(CameraParameters::KEY_FOCUS_AREAS);
     51 
     52     MAX_FOCUS_AREAS = atoi(params.get(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;
     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 
     86     LOG_FUNCTION_NAME;
     87 
     88     if ( OMX_StateInvalid == mComponentState )
     89       {
     90         CAMHAL_LOGEA("OMX component in Invalid state");
     91         returnFocusStatus(false);
     92         return -EINVAL;
     93       }
     94 
     95     if ( OMX_StateExecuting != mComponentState )
     96         {
     97         CAMHAL_LOGEA("OMX component not in executing state");
     98         returnFocusStatus(false);
     99         return NO_ERROR;
    100         }
    101 
    102     if ( 0 != mDoAFSem.Count() )
    103         {
    104         CAMHAL_LOGEB("Error mDoAFSem semaphore count %d", mDoAFSem.Count());
    105         return NO_INIT;
    106         }
    107 
    108     if( ((AF_ACTIVE & getState()) != AF_ACTIVE) && ((AF_ACTIVE & getNextState()) != AF_ACTIVE) ) {
    109        CAMHAL_LOGDA("Auto focus got canceled before doAutoFocus could be called");
    110        return NO_ERROR;
    111     }
    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. If lock is not available, then switch temporarily
    142         // to 'autolock' and do normal AF.
    143         ret = checkFocus(&focusStatus);
    144         if ( NO_ERROR != ret ) {
    145             CAMHAL_LOGEB("Focus status check failed 0x%x!", ret);
    146             return ret;
    147         } else {
    148             CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus);
    149         }
    150     }
    151 
    152     if ( ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
    153          ( focusControl.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
    154                  OMX_IMAGE_FocusControlAutoInfinity ) ) {
    155 
    156         ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
    157                                     (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
    158                                     OMX_ALL,
    159                                     OMX_IndexConfigCommonFocusStatus,
    160                                     mDoAFSem);
    161 
    162         if ( NO_ERROR == ret ) {
    163             ret = setFocusCallback(true);
    164         }
    165 
    166         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    167                                 OMX_IndexConfigFocusControl,
    168                                 &focusControl);
    169 
    170         if ( OMX_ErrorNone != eError ) {
    171             CAMHAL_LOGEB("Error while starting focus 0x%x", eError);
    172             return INVALID_OPERATION;
    173         } else {
    174             CAMHAL_LOGDA("Autofocus started successfully");
    175         }
    176 
    177        if(mDoAFSem.WaitTimeout(AF_CALLBACK_TIMEOUT) != NO_ERROR) {
    178             //If somethiing bad happened while we wait
    179             if (mComponentState == OMX_StateInvalid) {
    180                 CAMHAL_LOGEA("Invalid State after Auto Focus Exitting!!!");
    181                 return EINVAL;
    182             }
    183 
    184             //Disable auto focus callback from Ducati
    185             setFocusCallback(false);
    186             CAMHAL_LOGEA("Autofocus callback timeout expired");
    187             RemoveEvent(mCameraAdapterParameters.mHandleComp,
    188                                         (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
    189                                         OMX_ALL,
    190                                         OMX_IndexConfigCommonFocusStatus,
    191                                         NULL );
    192             returnFocusStatus(true);
    193         } else {
    194             CAMHAL_LOGDA("Autofocus callback received");
    195             //Disable auto focus callback from Ducati
    196             setFocusCallback(false);
    197             ret = returnFocusStatus(false);
    198         }
    199     } else { // Focus mode in continuous
    200         if ( NO_ERROR == ret ) {
    201             ret = returnFocusStatus(false);
    202             mPending3Asettings |= SetFocus;
    203         }
    204     }
    205 
    206     LOG_FUNCTION_NAME_EXIT;
    207 
    208     return ret;
    209 }
    210 
    211 status_t OMXCameraAdapter::stopAutoFocus()
    212 {
    213     status_t ret = NO_ERROR;
    214     OMX_ERRORTYPE eError = OMX_ErrorNone;
    215     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
    216 
    217     LOG_FUNCTION_NAME;
    218 
    219     if ( OMX_StateInvalid == mComponentState )
    220       {
    221         CAMHAL_LOGEA("OMX component in Invalid state");
    222         returnFocusStatus(false);
    223         return -EINVAL;
    224       }
    225 
    226     if ( OMX_StateExecuting != mComponentState )
    227         {
    228           CAMHAL_LOGEA("OMX component not in executing state");
    229         return NO_ERROR;
    230         }
    231 
    232     if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) {
    233         // No need to stop focus if we are in infinity mode. Nothing to stop.
    234         return NO_ERROR;
    235     }
    236 
    237     if ( NO_ERROR == ret )
    238        {
    239        //Disable the callback first
    240        ret = setFocusCallback(false);
    241        }
    242 
    243     if ( NO_ERROR == ret )
    244         {
    245         OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
    246         focusControl.eFocusControl = OMX_IMAGE_FocusControlOff;
    247 
    248         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    249                                 OMX_IndexConfigFocusControl,
    250                                 &focusControl);
    251         if ( OMX_ErrorNone != eError )
    252             {
    253             CAMHAL_LOGEB("Error while stopping focus 0x%x", eError);
    254             return ErrorUtils::omxToAndroidError(eError);
    255             }
    256         }
    257 
    258     LOG_FUNCTION_NAME_EXIT;
    259 
    260     return ret;
    261 }
    262 
    263 status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode)
    264 {;
    265     OMX_ERRORTYPE eError = OMX_ErrorNone;
    266 
    267     LOG_FUNCTION_NAME;
    268 
    269     if ( OMX_StateInvalid == mComponentState ) {
    270         CAMHAL_LOGEA("OMX component is in invalid state");
    271         return NO_INIT;
    272     }
    273 
    274     OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
    275     focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
    276 
    277     eError =  OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    278                             OMX_IndexConfigFocusControl,
    279                             &focusMode);
    280 
    281     if ( OMX_ErrorNone != eError ) {
    282         CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError);
    283     }
    284 
    285     LOG_FUNCTION_NAME_EXIT;
    286 
    287     return ErrorUtils::omxToAndroidError(eError);
    288 }
    289 
    290 status_t OMXCameraAdapter::cancelAutoFocus()
    291 {
    292     status_t ret = NO_ERROR;
    293     OMX_ERRORTYPE eError = OMX_ErrorNone;
    294     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode;
    295 
    296     LOG_FUNCTION_NAME;
    297 
    298     ret = getFocusMode(focusMode);
    299     if ( NO_ERROR != ret ) {
    300         return ret;
    301     }
    302 
    303     //Stop the AF only for modes other than CAF  or Inifinity
    304     if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
    305          ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
    306                  OMX_IMAGE_FocusControlAutoInfinity ) ) {
    307         stopAutoFocus();
    308         //Signal a dummy AF event so that in case the callback from ducati
    309         //does come then it doesnt crash after
    310         //exiting this function since eventSem will go out of scope.
    311         ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
    312                                     (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
    313                                     OMX_ALL,
    314                                     OMX_IndexConfigCommonFocusStatus,
    315                                     NULL );
    316     } else if (focusMode.eFocusControl == OMX_IMAGE_FocusControlAuto) {
    317        // re-apply CAF after unlocking and canceling
    318        mPending3Asettings |= SetFocus;
    319     }
    320 
    321     // If the apps call #cancelAutoFocus()}, the face callbacks will also resume.
    322     pauseFaceDetection(false);
    323 
    324     LOG_FUNCTION_NAME_EXIT;
    325 
    326     return ret;
    327 
    328 }
    329 
    330 status_t OMXCameraAdapter::setFocusCallback(bool enabled)
    331 {
    332     status_t ret = NO_ERROR;
    333     OMX_ERRORTYPE eError = OMX_ErrorNone;
    334     OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback;
    335 
    336     LOG_FUNCTION_NAME;
    337 
    338     if ( OMX_StateInvalid == mComponentState )
    339       {
    340         CAMHAL_LOGEA("OMX component in Invalid state");
    341         ret = -EINVAL;
    342       }
    343 
    344     if ( OMX_StateExecuting != mComponentState )
    345         {
    346           CAMHAL_LOGEA("OMX component not in executing state");
    347         ret = NO_ERROR;
    348         }
    349 
    350     if ( NO_ERROR == ret )
    351         {
    352 
    353         OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
    354         focusRequstCallback.nPortIndex = OMX_ALL;
    355         focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus;
    356 
    357         if ( enabled )
    358             {
    359             focusRequstCallback.bEnable = OMX_TRUE;
    360             }
    361         else
    362             {
    363             focusRequstCallback.bEnable = OMX_FALSE;
    364             }
    365 
    366         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    367                                 (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
    368                                 &focusRequstCallback);
    369         if ( OMX_ErrorNone != eError )
    370             {
    371             CAMHAL_LOGEB("Error registering focus callback 0x%x", eError);
    372             ret = -1;
    373             }
    374         else
    375             {
    376             CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully",
    377                          OMX_IndexConfigCommonFocusStatus);
    378             }
    379         }
    380 
    381     LOG_FUNCTION_NAME_EXIT;
    382 
    383     return ret;
    384 }
    385 
    386 status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached)
    387 {
    388     status_t ret = NO_ERROR;
    389     OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus;
    390     bool focusStatus = false;
    391     BaseCameraAdapter::AdapterState state, nextState;
    392     BaseCameraAdapter::getState(state);
    393     BaseCameraAdapter::getNextState(nextState);
    394 
    395     LOG_FUNCTION_NAME;
    396 
    397     OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
    398 
    399     if( ((AF_ACTIVE & state ) != AF_ACTIVE) && ((AF_ACTIVE & nextState ) != AF_ACTIVE) )
    400        {
    401         /// We don't send focus callback if focus was not started
    402        CAMHAL_LOGDA("Not sending focus callback because focus was not started");
    403        return NO_ERROR;
    404        }
    405 
    406     if ( NO_ERROR == ret )
    407         {
    408 
    409         if ( !timeoutReached )
    410             {
    411             ret = checkFocus(&eFocusStatus);
    412 
    413             if ( NO_ERROR != ret )
    414                 {
    415                 CAMHAL_LOGEA("Focus status check failed!");
    416                 }
    417             }
    418         }
    419 
    420     if ( NO_ERROR == ret )
    421         {
    422 
    423         if ( timeoutReached )
    424             {
    425             focusStatus = false;
    426             }
    427         else
    428             {
    429             switch (eFocusStatus.eFocusStatus)
    430                 {
    431                     case OMX_FocusStatusReached:
    432                         {
    433                         focusStatus = true;
    434                         break;
    435                         }
    436                     case OMX_FocusStatusOff:
    437                     case OMX_FocusStatusUnableToReach:
    438                     case OMX_FocusStatusRequest:
    439                     default:
    440                         {
    441                         focusStatus = false;
    442                         break;
    443                         }
    444                 }
    445             // Lock CAF after AF call
    446             if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_TRUE) != NO_ERROR) {
    447                 CAMHAL_LOGEA("Error Applying 3A locks");
    448             } else {
    449                 CAMHAL_LOGDA("Focus locked. Applied focus locks successfully");
    450             }
    451 
    452             stopAutoFocus();
    453             }
    454         //Query current focus distance after AF is complete
    455         updateFocusDistances(mParameters);
    456        }
    457 
    458     ret =  BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS);
    459     if ( NO_ERROR == ret )
    460         {
    461         ret = BaseCameraAdapter::commitState();
    462         }
    463     else
    464         {
    465         ret |= BaseCameraAdapter::rollbackState();
    466         }
    467 
    468     if ( NO_ERROR == ret )
    469         {
    470         notifyFocusSubscribers(focusStatus);
    471         }
    472 
    473     // After focus, face detection will resume sending face callbacks
    474     pauseFaceDetection(false);
    475 
    476     LOG_FUNCTION_NAME_EXIT;
    477 
    478     return ret;
    479 }
    480 
    481 status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus)
    482 {
    483     status_t ret = NO_ERROR;
    484     OMX_ERRORTYPE eError = OMX_ErrorNone;
    485 
    486     LOG_FUNCTION_NAME;
    487 
    488     if ( NULL == eFocusStatus )
    489         {
    490         CAMHAL_LOGEA("Invalid focus status");
    491         ret = -EINVAL;
    492         }
    493 
    494     if ( OMX_StateInvalid == mComponentState )
    495       {
    496         CAMHAL_LOGEA("OMX component in Invalid state");
    497         ret = -EINVAL;
    498       }
    499 
    500     if ( OMX_StateExecuting != mComponentState )
    501         {
    502         CAMHAL_LOGEA("OMX component not in executing state");
    503         ret = NO_ERROR;
    504         }
    505 
    506     if ( NO_ERROR == ret )
    507         {
    508         OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
    509 
    510         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    511                                OMX_IndexConfigCommonFocusStatus,
    512                                eFocusStatus);
    513         if ( OMX_ErrorNone != eError )
    514             {
    515             CAMHAL_LOGEB("Error while retrieving focus status: 0x%x", eError);
    516             ret = -1;
    517             }
    518         }
    519 
    520     if ( NO_ERROR == ret )
    521         {
    522         CAMHAL_LOGDB("Focus Status: %d", eFocusStatus->eFocusStatus);
    523         }
    524 
    525     LOG_FUNCTION_NAME_EXIT;
    526 
    527     return ret;
    528 }
    529 
    530 status_t OMXCameraAdapter::updateFocusDistances(CameraParameters &params)
    531 {
    532     OMX_U32 focusNear, focusOptimal, focusFar;
    533     status_t ret = NO_ERROR;
    534 
    535     LOG_FUNCTION_NAME;
    536 
    537     ret = getFocusDistances(focusNear, focusOptimal, focusFar);
    538     if ( NO_ERROR == ret)
    539         {
    540         ret = addFocusDistances(focusNear, focusOptimal, focusFar, params);
    541             if ( NO_ERROR != ret )
    542                 {
    543                 CAMHAL_LOGEB("Error in call to addFocusDistances() 0x%x", ret);
    544                 }
    545         }
    546     else
    547         {
    548         CAMHAL_LOGEB("Error in call to getFocusDistances() 0x%x", ret);
    549         }
    550 
    551     LOG_FUNCTION_NAME_EXIT;
    552 
    553     return ret;
    554 }
    555 
    556 status_t OMXCameraAdapter::getFocusDistances(OMX_U32 &near,OMX_U32 &optimal, OMX_U32 &far)
    557 {
    558     status_t ret = NO_ERROR;
    559     OMX_ERRORTYPE eError;
    560 
    561     OMX_TI_CONFIG_FOCUSDISTANCETYPE focusDist;
    562 
    563     LOG_FUNCTION_NAME;
    564 
    565     if ( OMX_StateInvalid == mComponentState )
    566         {
    567         CAMHAL_LOGEA("OMX component is in invalid state");
    568         ret = UNKNOWN_ERROR;
    569         }
    570 
    571     if ( NO_ERROR == ret )
    572         {
    573         OMX_INIT_STRUCT_PTR(&focusDist, OMX_TI_CONFIG_FOCUSDISTANCETYPE);
    574         focusDist.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
    575 
    576         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    577                                ( OMX_INDEXTYPE ) OMX_TI_IndexConfigFocusDistance,
    578                                &focusDist);
    579         if ( OMX_ErrorNone != eError )
    580             {
    581             CAMHAL_LOGEB("Error while querying focus distances 0x%x", eError);
    582             ret = UNKNOWN_ERROR;
    583             }
    584 
    585         }
    586 
    587     if ( NO_ERROR == ret )
    588         {
    589         near = focusDist.nFocusDistanceNear;
    590         optimal = focusDist.nFocusDistanceOptimal;
    591         far = focusDist.nFocusDistanceFar;
    592         }
    593 
    594     LOG_FUNCTION_NAME_EXIT;
    595 
    596     return ret;
    597 }
    598 
    599 status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_t length)
    600 {
    601     status_t ret = NO_ERROR;
    602     uint32_t focusScale = 1000;
    603     float distFinal;
    604 
    605     LOG_FUNCTION_NAME;
    606 
    607     if(mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity)
    608         {
    609         dist=0;
    610         }
    611 
    612     if ( NO_ERROR == ret )
    613         {
    614         if ( 0 == dist )
    615             {
    616             strncpy(buffer, CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 ));
    617             }
    618         else
    619             {
    620             distFinal = dist;
    621             distFinal /= focusScale;
    622             snprintf(buffer, ( length - 1 ) , "%5.3f", distFinal);
    623             }
    624         }
    625 
    626     LOG_FUNCTION_NAME_EXIT;
    627 
    628     return ret;
    629 }
    630 
    631 status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near,
    632                                              OMX_U32 &optimal,
    633                                              OMX_U32 &far,
    634                                              CameraParameters& params)
    635 {
    636     status_t ret = NO_ERROR;
    637 
    638     LOG_FUNCTION_NAME;
    639 
    640     if ( NO_ERROR == ret )
    641         {
    642         ret = encodeFocusDistance(near, mFocusDistNear, FOCUS_DIST_SIZE);
    643         if ( NO_ERROR != ret )
    644             {
    645             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
    646             }
    647         }
    648 
    649     if ( NO_ERROR == ret )
    650         {
    651         ret = encodeFocusDistance(optimal, mFocusDistOptimal, FOCUS_DIST_SIZE);
    652         if ( NO_ERROR != ret )
    653             {
    654             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
    655             }
    656         }
    657 
    658     if ( NO_ERROR == ret )
    659         {
    660         ret = encodeFocusDistance(far, mFocusDistFar, FOCUS_DIST_SIZE);
    661         if ( NO_ERROR != ret )
    662             {
    663             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
    664             }
    665         }
    666 
    667     if ( NO_ERROR == ret )
    668         {
    669         snprintf(mFocusDistBuffer, ( FOCUS_DIST_BUFFER_SIZE - 1) ,"%s,%s,%s", mFocusDistNear,
    670                                                                               mFocusDistOptimal,
    671                                                                               mFocusDistFar);
    672 
    673         params.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer);
    674         }
    675 
    676     LOG_FUNCTION_NAME_EXIT;
    677 
    678     return ret;
    679 }
    680 
    681 status_t OMXCameraAdapter::setTouchFocus()
    682 {
    683     status_t ret = NO_ERROR;
    684     OMX_ERRORTYPE eError = OMX_ErrorNone;
    685 
    686     OMX_ALGOAREASTYPE **focusAreas;
    687     OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer;
    688     MemoryManager memMgr;
    689     int areasSize = 0;
    690 
    691     LOG_FUNCTION_NAME;
    692 
    693     if ( OMX_StateInvalid == mComponentState )
    694         {
    695         CAMHAL_LOGEA("OMX component is in invalid state");
    696         ret = -1;
    697         }
    698 
    699     if ( NO_ERROR == ret )
    700         {
    701 
    702         areasSize = ((sizeof(OMX_ALGOAREASTYPE)+4095)/4096)*4096;
    703         focusAreas = (OMX_ALGOAREASTYPE**) memMgr.allocateBuffer(0, 0, NULL, areasSize, 1);
    704 
    705         OMXCameraPortParameters * mPreviewData = NULL;
    706         mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
    707 
    708         if (!focusAreas)
    709             {
    710             CAMHAL_LOGEB("Error allocating buffer for focus areas %d", eError);
    711             return -ENOMEM;
    712             }
    713 
    714         OMX_INIT_STRUCT_PTR (focusAreas[0], OMX_ALGOAREASTYPE);
    715 
    716         focusAreas[0]->nPortIndex = OMX_ALL;
    717         focusAreas[0]->nNumAreas = mFocusAreas.size();
    718         focusAreas[0]->nAlgoAreaPurpose = OMX_AlgoAreaFocus;
    719 
    720         // If the area is the special case of (0, 0, 0, 0, 0), then
    721         // the algorithm needs nNumAreas to be set to 0,
    722         // in order to automatically choose the best fitting areas.
    723         if ( mFocusAreas.itemAt(0)->isZeroArea() )
    724             {
    725             focusAreas[0]->nNumAreas = 0;
    726             }
    727 
    728         for ( unsigned int n = 0; n < mFocusAreas.size(); n++)
    729             {
    730             // transform the coordinates to 3A-type coordinates
    731             mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth,
    732                                             (size_t)mPreviewData->mHeight,
    733                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nTop,
    734                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nLeft,
    735                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nWidth,
    736                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nHeight);
    737 
    738             focusAreas[0]->tAlgoAreas[n].nLeft =
    739                     ( focusAreas[0]->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth;
    740             focusAreas[0]->tAlgoAreas[n].nTop =
    741                     ( focusAreas[0]->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight;
    742             focusAreas[0]->tAlgoAreas[n].nWidth =
    743                     ( focusAreas[0]->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth;
    744             focusAreas[0]->tAlgoAreas[n].nHeight =
    745                     ( focusAreas[0]->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight;
    746             focusAreas[0]->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight();
    747 
    748              CAMHAL_LOGDB("Focus area %d : top = %d left = %d width = %d height = %d prio = %d",
    749                     n, (int)focusAreas[0]->tAlgoAreas[n].nTop, (int)focusAreas[0]->tAlgoAreas[n].nLeft,
    750                     (int)focusAreas[0]->tAlgoAreas[n].nWidth, (int)focusAreas[0]->tAlgoAreas[n].nHeight,
    751                     (int)focusAreas[0]->tAlgoAreas[n].nPriority);
    752              }
    753 
    754         OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER);
    755 
    756         sharedBuffer.nPortIndex = OMX_ALL;
    757         sharedBuffer.nSharedBuffSize = areasSize;
    758         sharedBuffer.pSharedBuff = (OMX_U8 *) focusAreas[0];
    759 
    760         if ( NULL == sharedBuffer.pSharedBuff )
    761             {
    762             CAMHAL_LOGEA("No resources to allocate OMX shared buffer");
    763             ret = -ENOMEM;
    764             goto EXIT;
    765             }
    766 
    767             eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    768                                       (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgoAreas, &sharedBuffer);
    769 
    770         if ( OMX_ErrorNone != eError )
    771             {
    772             CAMHAL_LOGEB("Error while setting Focus Areas configuration 0x%x", eError);
    773             ret = -EINVAL;
    774             }
    775 
    776     EXIT:
    777         if (NULL != focusAreas)
    778             {
    779             memMgr.freeBuffer((void*) focusAreas);
    780             focusAreas = NULL;
    781             }
    782         }
    783 
    784     LOG_FUNCTION_NAME_EXIT;
    785 
    786     return ret;
    787 }
    788 
    789 };
    790