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