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