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