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