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