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