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