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