• 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_IMAGE_CALLBACK_TIMEOUT 5000000 //5 seconds timeout
35 #define AF_VIDEO_CALLBACK_TIMEOUT 2800000 //2.8 seconds timeout
36 
37 namespace android {
38 
setParametersFocus(const CameraParameters & params,BaseCameraAdapter::AdapterState state)39 status_t OMXCameraAdapter::setParametersFocus(const CameraParameters &params,
40                                               BaseCameraAdapter::AdapterState state)
41 {
42     status_t ret = NO_ERROR;
43     const char *str = NULL;
44     Vector< sp<CameraArea> > tempAreas;
45     size_t MAX_FOCUS_AREAS;
46 
47     LOG_FUNCTION_NAME;
48 
49     Mutex::Autolock lock(mFocusAreasLock);
50 
51     str = params.get(CameraParameters::KEY_FOCUS_AREAS);
52 
53     MAX_FOCUS_AREAS = atoi(params.get(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS));
54 
55     if ( NULL != str ) {
56         ret = CameraArea::parseAreas(str, ( strlen(str) + 1 ), tempAreas);
57     }
58 
59     if ( (NO_ERROR == ret) && CameraArea::areAreasDifferent(mFocusAreas, tempAreas) ) {
60         mFocusAreas.clear();
61         mFocusAreas = tempAreas;
62         if ( MAX_FOCUS_AREAS < mFocusAreas.size() ) {
63             CAMHAL_LOGEB("Focus areas supported %d, focus areas set %d",
64                          MAX_FOCUS_AREAS,
65                          mFocusAreas.size());
66             ret = -EINVAL;
67         }
68         else {
69             if ( !mFocusAreas.isEmpty() ) {
70                 setTouchFocus();
71             }
72         }
73     }
74 
75     LOG_FUNCTION_NAME;
76 
77     return ret;
78 }
79 
doAutoFocus()80 status_t OMXCameraAdapter::doAutoFocus()
81 {
82     status_t ret = NO_ERROR;
83     OMX_ERRORTYPE eError = OMX_ErrorNone;
84     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
85     OMX_PARAM_FOCUSSTATUSTYPE focusStatus;
86     OMX_CONFIG_BOOLEANTYPE bOMX;
87     nsecs_t timeout = 0;
88 
89     LOG_FUNCTION_NAME;
90 
91     if ( OMX_StateInvalid == mComponentState )
92       {
93         CAMHAL_LOGEA("OMX component in Invalid state");
94         returnFocusStatus(false);
95         return -EINVAL;
96       }
97 
98     if ( OMX_StateExecuting != mComponentState )
99         {
100         CAMHAL_LOGEA("OMX component not in executing state");
101         returnFocusStatus(false);
102         return NO_ERROR;
103         }
104 
105 
106     if( ((AF_ACTIVE & getState()) != AF_ACTIVE) && ((AF_ACTIVE & getNextState()) != AF_ACTIVE) ) {
107        CAMHAL_LOGDA("Auto focus got canceled before doAutoFocus could be called");
108        return NO_ERROR;
109     }
110 
111     OMX_INIT_STRUCT_PTR (&focusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
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.
142         ret = checkFocus(&focusStatus);
143         if ( NO_ERROR != ret ) {
144             CAMHAL_LOGEB("Focus status check failed 0x%x!", ret);
145             return ret;
146         } else {
147             CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus);
148         }
149     }
150 
151     if ( (focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto &&
152          ( focusStatus.eFocusStatus == OMX_FocusStatusRequest ||
153            focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach ||
154            focusStatus.eFocusStatus == OMX_FocusStatusLost ) ) ||
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         // force AF, Ducati will take care of whether CAF
166         // or AF will be performed, depending on light conditions
167         if ( focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto &&
168              ( focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach ||
169                focusStatus.eFocusStatus == OMX_FocusStatusLost ) ) {
170             focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock;
171         }
172 
173         if ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto )
174             {
175             eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
176                                     OMX_IndexConfigFocusControl,
177                                     &focusControl);
178             }
179 
180         if ( OMX_ErrorNone != eError ) {
181             CAMHAL_LOGEB("Error while starting focus 0x%x", eError);
182             return INVALID_OPERATION;
183         } else {
184             CAMHAL_LOGDA("Autofocus started successfully");
185         }
186 
187         // configure focus timeout based on capture mode
188         timeout = (mCapMode == VIDEO_MODE) ?
189                         ( ( nsecs_t ) AF_VIDEO_CALLBACK_TIMEOUT * 1000 ) :
190                         ( ( nsecs_t ) AF_IMAGE_CALLBACK_TIMEOUT * 1000 );
191 
192             {
193             Mutex::Autolock lock(mDoAFMutex);
194             ret = mDoAFCond.waitRelative(mDoAFMutex, timeout);
195             }
196 
197         //If somethiing bad happened while we wait
198         if (mComponentState == OMX_StateInvalid) {
199           CAMHAL_LOGEA("Invalid State after Auto Focus Exitting!!!");
200           return -EINVAL;
201         }
202 
203         if(ret != NO_ERROR) {
204             CAMHAL_LOGEA("Autofocus callback timeout expired");
205             ret = returnFocusStatus(true);
206         } else {
207             ret = returnFocusStatus(false);
208         }
209     } else { // Focus mode in continuous
210         if ( NO_ERROR == ret ) {
211             ret = returnFocusStatus(true);
212             mPending3Asettings |= SetFocus;
213         }
214     }
215 
216     LOG_FUNCTION_NAME_EXIT;
217 
218     return ret;
219 }
220 
stopAutoFocus()221 status_t OMXCameraAdapter::stopAutoFocus()
222 {
223     OMX_ERRORTYPE eError = OMX_ErrorNone;
224     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl;
225 
226     LOG_FUNCTION_NAME;
227 
228     if ( OMX_StateInvalid == mComponentState )
229       {
230         CAMHAL_LOGEA("OMX component in Invalid state");
231         returnFocusStatus(false);
232         return -EINVAL;
233       }
234 
235     if ( OMX_StateExecuting != mComponentState )
236         {
237           CAMHAL_LOGEA("OMX component not in executing state");
238         return NO_ERROR;
239         }
240 
241     if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) {
242         // No need to stop focus if we are in infinity mode. Nothing to stop.
243         return NO_ERROR;
244     }
245 
246     OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
247     focusControl.eFocusControl = OMX_IMAGE_FocusControlOff;
248 
249     eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
250                             OMX_IndexConfigFocusControl,
251                             &focusControl);
252     if ( OMX_ErrorNone != eError )
253         {
254         CAMHAL_LOGEB("Error while stopping focus 0x%x", eError);
255         return ErrorUtils::omxToAndroidError(eError);
256     } else {
257         // This is a WA. Usually the OMX Camera component should
258         // generate AF status change OMX event fairly quickly
259         // ( after one preview frame ) and this notification should
260         // actually come from 'handleFocusCallback()'.
261         Mutex::Autolock lock(mDoAFMutex);
262         mDoAFCond.broadcast();
263     }
264 
265 
266     LOG_FUNCTION_NAME_EXIT;
267 
268     return NO_ERROR;
269 }
270 
getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE & focusMode)271 status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode)
272 {;
273     OMX_ERRORTYPE eError = OMX_ErrorNone;
274 
275     LOG_FUNCTION_NAME;
276 
277     if ( OMX_StateInvalid == mComponentState ) {
278         CAMHAL_LOGEA("OMX component is in invalid state");
279         return NO_INIT;
280     }
281 
282     OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE);
283     focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
284 
285     eError =  OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
286                             OMX_IndexConfigFocusControl,
287                             &focusMode);
288 
289     if ( OMX_ErrorNone != eError ) {
290         CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError);
291     }
292 
293     LOG_FUNCTION_NAME_EXIT;
294 
295     return ErrorUtils::omxToAndroidError(eError);
296 }
297 
cancelAutoFocus()298 status_t OMXCameraAdapter::cancelAutoFocus()
299 {
300     status_t ret = NO_ERROR;
301     OMX_ERRORTYPE eError = OMX_ErrorNone;
302     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode;
303 
304     LOG_FUNCTION_NAME;
305 
306     ret = getFocusMode(focusMode);
307     if ( NO_ERROR != ret ) {
308         return ret;
309     }
310 
311     //Stop the AF only for modes other than CAF  or Inifinity
312     if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) &&
313          ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE )
314                  OMX_IMAGE_FocusControlAutoInfinity ) ) {
315         stopAutoFocus();
316     } else if (focusMode.eFocusControl == OMX_IMAGE_FocusControlAuto) {
317        // This re-enabling of CAF doesn't seem to
318        // be needed any more.
319        // re-apply CAF after unlocking and canceling
320        // mPending3Asettings |= SetFocus;
321     }
322     // If the apps call #cancelAutoFocus()}, the face callbacks will also resume.
323     pauseFaceDetection(false);
324 
325     LOG_FUNCTION_NAME_EXIT;
326 
327     return ret;
328 
329 }
330 
setFocusCallback(bool enabled)331 status_t OMXCameraAdapter::setFocusCallback(bool enabled)
332 {
333     status_t ret = NO_ERROR;
334     OMX_ERRORTYPE eError = OMX_ErrorNone;
335     OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback;
336 
337     LOG_FUNCTION_NAME;
338 
339     if ( OMX_StateInvalid == mComponentState )
340       {
341         CAMHAL_LOGEA("OMX component in Invalid state");
342         ret = -EINVAL;
343       }
344 
345     if ( OMX_StateExecuting != mComponentState )
346         {
347           CAMHAL_LOGEA("OMX component not in executing state");
348         ret = NO_ERROR;
349         }
350 
351     if ( NO_ERROR == ret )
352         {
353 
354         OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
355         focusRequstCallback.nPortIndex = OMX_ALL;
356         focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus;
357 
358         if ( enabled )
359             {
360             focusRequstCallback.bEnable = OMX_TRUE;
361             }
362         else
363             {
364             focusRequstCallback.bEnable = OMX_FALSE;
365             }
366 
367         eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
368                                 (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
369                                 &focusRequstCallback);
370         if ( OMX_ErrorNone != eError )
371             {
372             CAMHAL_LOGEB("Error registering focus callback 0x%x", eError);
373             ret = -1;
374             }
375         else
376             {
377             CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully",
378                          OMX_IndexConfigCommonFocusStatus);
379             }
380         }
381 
382     LOG_FUNCTION_NAME_EXIT;
383 
384     return ret;
385 }
386 
returnFocusStatus(bool timeoutReached)387 status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached)
388 {
389     status_t ret = NO_ERROR;
390     OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus;
391     CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
392     BaseCameraAdapter::AdapterState state, nextState;
393     BaseCameraAdapter::getState(state);
394     BaseCameraAdapter::getNextState(nextState);
395 
396     LOG_FUNCTION_NAME;
397 
398     OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
399 
400     if( ((AF_ACTIVE & state ) != AF_ACTIVE) && ((AF_ACTIVE & nextState ) != AF_ACTIVE) )
401        {
402         /// We don't send focus callback if focus was not started
403        CAMHAL_LOGDA("Not sending focus callback because focus was not started");
404        return NO_ERROR;
405        }
406 
407     if ( NO_ERROR == ret )
408         {
409 
410         if ( !timeoutReached )
411             {
412             ret = checkFocus(&eFocusStatus);
413 
414             if ( NO_ERROR != ret )
415                 {
416                 CAMHAL_LOGEA("Focus status check failed!");
417                 }
418             }
419         }
420 
421     if ( NO_ERROR == ret )
422         {
423 
424         if ( timeoutReached )
425             {
426             focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
427             }
428         else
429             {
430             switch (eFocusStatus.eFocusStatus)
431                 {
432                     case OMX_FocusStatusReached:
433                         {
434                         focusStatus = CameraHalEvent::FOCUS_STATUS_SUCCESS;
435                         break;
436                         }
437                     case OMX_FocusStatusOff: // AF got canceled
438                         return NO_ERROR;
439                     case OMX_FocusStatusUnableToReach:
440                     case OMX_FocusStatusRequest:
441                     default:
442                         {
443                         focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
444                         break;
445                         }
446                 }
447             // Lock CAF after AF call
448             if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_TRUE) != NO_ERROR) {
449                 CAMHAL_LOGEA("Error Applying 3A locks");
450             } else {
451                 CAMHAL_LOGDA("Focus locked. Applied focus locks successfully");
452             }
453             stopAutoFocus();
454             }
455 
456         //Query current focus distance after AF is complete
457         updateFocusDistances(mParameters);
458        }
459 
460     ret =  BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS);
461     if ( NO_ERROR == ret )
462         {
463         ret = BaseCameraAdapter::commitState();
464         }
465     else
466         {
467         ret |= BaseCameraAdapter::rollbackState();
468         }
469 
470     if ( NO_ERROR == ret )
471         {
472         notifyFocusSubscribers(focusStatus);
473         }
474 
475     // After focus, face detection will resume sending face callbacks
476     pauseFaceDetection(false);
477 
478     LOG_FUNCTION_NAME_EXIT;
479 
480     return ret;
481 }
482 
checkFocus(OMX_PARAM_FOCUSSTATUSTYPE * eFocusStatus)483 status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus)
484 {
485     status_t ret = NO_ERROR;
486     OMX_ERRORTYPE eError = OMX_ErrorNone;
487 
488     LOG_FUNCTION_NAME;
489 
490     if ( NULL == eFocusStatus )
491         {
492         CAMHAL_LOGEA("Invalid focus status");
493         ret = -EINVAL;
494         }
495 
496     if ( OMX_StateInvalid == mComponentState )
497       {
498         CAMHAL_LOGEA("OMX component in Invalid state");
499         ret = -EINVAL;
500       }
501 
502     if ( OMX_StateExecuting != mComponentState )
503         {
504         CAMHAL_LOGEA("OMX component not in executing state");
505         ret = NO_ERROR;
506         }
507 
508     if ( NO_ERROR == ret )
509         {
510         OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
511         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
512                                OMX_IndexConfigCommonFocusStatus,
513                                eFocusStatus);
514         if ( OMX_ErrorNone != eError )
515             {
516             CAMHAL_LOGEB("Error while retrieving focus status: 0x%x", eError);
517             ret = -1;
518             }
519         }
520 
521     if ( NO_ERROR == ret )
522         {
523         CAMHAL_LOGDB("Focus Status: %d", eFocusStatus->eFocusStatus);
524         }
525 
526     LOG_FUNCTION_NAME_EXIT;
527 
528     return ret;
529 }
530 
updateFocusDistances(CameraParameters & params)531 status_t OMXCameraAdapter::updateFocusDistances(CameraParameters &params)
532 {
533     OMX_U32 focusNear, focusOptimal, focusFar;
534     status_t ret = NO_ERROR;
535 
536     LOG_FUNCTION_NAME;
537 
538     ret = getFocusDistances(focusNear, focusOptimal, focusFar);
539     if ( NO_ERROR == ret)
540         {
541         ret = addFocusDistances(focusNear, focusOptimal, focusFar, params);
542             if ( NO_ERROR != ret )
543                 {
544                 CAMHAL_LOGEB("Error in call to addFocusDistances() 0x%x", ret);
545                 }
546         }
547     else
548         {
549         CAMHAL_LOGEB("Error in call to getFocusDistances() 0x%x", ret);
550         }
551 
552     LOG_FUNCTION_NAME_EXIT;
553 
554     return ret;
555 }
556 
getFocusDistances(OMX_U32 & near,OMX_U32 & optimal,OMX_U32 & far)557 status_t OMXCameraAdapter::getFocusDistances(OMX_U32 &near,OMX_U32 &optimal, OMX_U32 &far)
558 {
559     status_t ret = NO_ERROR;
560     OMX_ERRORTYPE eError;
561 
562     OMX_TI_CONFIG_FOCUSDISTANCETYPE focusDist;
563 
564     LOG_FUNCTION_NAME;
565 
566     if ( OMX_StateInvalid == mComponentState )
567         {
568         CAMHAL_LOGEA("OMX component is in invalid state");
569         ret = UNKNOWN_ERROR;
570         }
571 
572     if ( NO_ERROR == ret )
573         {
574         OMX_INIT_STRUCT_PTR(&focusDist, OMX_TI_CONFIG_FOCUSDISTANCETYPE);
575         focusDist.nPortIndex = mCameraAdapterParameters.mPrevPortIndex;
576 
577         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
578                                ( OMX_INDEXTYPE ) OMX_TI_IndexConfigFocusDistance,
579                                &focusDist);
580         if ( OMX_ErrorNone != eError )
581             {
582             CAMHAL_LOGEB("Error while querying focus distances 0x%x", eError);
583             ret = UNKNOWN_ERROR;
584             }
585 
586         }
587 
588     if ( NO_ERROR == ret )
589         {
590         near = focusDist.nFocusDistanceNear;
591         optimal = focusDist.nFocusDistanceOptimal;
592         far = focusDist.nFocusDistanceFar;
593         }
594 
595     LOG_FUNCTION_NAME_EXIT;
596 
597     return ret;
598 }
599 
encodeFocusDistance(OMX_U32 dist,char * buffer,size_t length)600 status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_t length)
601 {
602     status_t ret = NO_ERROR;
603     uint32_t focusScale = 1000;
604     float distFinal;
605 
606     LOG_FUNCTION_NAME;
607 
608     if(mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity)
609         {
610         dist=0;
611         }
612 
613     if ( NO_ERROR == ret )
614         {
615         if ( 0 == dist )
616             {
617             strncpy(buffer, CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 ));
618             }
619         else
620             {
621             distFinal = dist;
622             distFinal /= focusScale;
623             snprintf(buffer, ( length - 1 ) , "%5.3f", distFinal);
624             }
625         }
626 
627     LOG_FUNCTION_NAME_EXIT;
628 
629     return ret;
630 }
631 
addFocusDistances(OMX_U32 & near,OMX_U32 & optimal,OMX_U32 & far,CameraParameters & params)632 status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near,
633                                              OMX_U32 &optimal,
634                                              OMX_U32 &far,
635                                              CameraParameters& params)
636 {
637     status_t ret = NO_ERROR;
638 
639     LOG_FUNCTION_NAME;
640 
641     if ( NO_ERROR == ret )
642         {
643         ret = encodeFocusDistance(near, mFocusDistNear, FOCUS_DIST_SIZE);
644         if ( NO_ERROR != ret )
645             {
646             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
647             }
648         }
649 
650     if ( NO_ERROR == ret )
651         {
652         ret = encodeFocusDistance(optimal, mFocusDistOptimal, FOCUS_DIST_SIZE);
653         if ( NO_ERROR != ret )
654             {
655             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
656             }
657         }
658 
659     if ( NO_ERROR == ret )
660         {
661         ret = encodeFocusDistance(far, mFocusDistFar, FOCUS_DIST_SIZE);
662         if ( NO_ERROR != ret )
663             {
664             CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret);
665             }
666         }
667 
668     if ( NO_ERROR == ret )
669         {
670         snprintf(mFocusDistBuffer, ( FOCUS_DIST_BUFFER_SIZE - 1) ,"%s,%s,%s", mFocusDistNear,
671                                                                               mFocusDistOptimal,
672                                                                               mFocusDistFar);
673 
674         params.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer);
675         }
676 
677     LOG_FUNCTION_NAME_EXIT;
678 
679     return ret;
680 }
681 
setTouchFocus()682 status_t OMXCameraAdapter::setTouchFocus()
683 {
684     status_t ret = NO_ERROR;
685     OMX_ERRORTYPE eError = OMX_ErrorNone;
686 
687     OMX_ALGOAREASTYPE **focusAreas;
688     OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer;
689     MemoryManager memMgr;
690     int areasSize = 0;
691 
692     LOG_FUNCTION_NAME;
693 
694     if ( OMX_StateInvalid == mComponentState )
695         {
696         CAMHAL_LOGEA("OMX component is in invalid state");
697         ret = -1;
698         }
699 
700     if ( NO_ERROR == ret )
701         {
702 
703         areasSize = ((sizeof(OMX_ALGOAREASTYPE)+4095)/4096)*4096;
704         focusAreas = (OMX_ALGOAREASTYPE**) memMgr.allocateBuffer(0, 0, NULL, areasSize, 1);
705 
706         OMXCameraPortParameters * mPreviewData = NULL;
707         mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex];
708 
709         if (!focusAreas)
710             {
711             CAMHAL_LOGEB("Error allocating buffer for focus areas %d", eError);
712             return -ENOMEM;
713             }
714 
715         OMX_INIT_STRUCT_PTR (focusAreas[0], OMX_ALGOAREASTYPE);
716 
717         focusAreas[0]->nPortIndex = OMX_ALL;
718         focusAreas[0]->nNumAreas = mFocusAreas.size();
719         focusAreas[0]->nAlgoAreaPurpose = OMX_AlgoAreaFocus;
720 
721         // If the area is the special case of (0, 0, 0, 0, 0), then
722         // the algorithm needs nNumAreas to be set to 0,
723         // in order to automatically choose the best fitting areas.
724         if ( mFocusAreas.itemAt(0)->isZeroArea() )
725             {
726             focusAreas[0]->nNumAreas = 0;
727             }
728 
729         for ( unsigned int n = 0; n < mFocusAreas.size(); n++)
730             {
731             // transform the coordinates to 3A-type coordinates
732             mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth,
733                                             (size_t)mPreviewData->mHeight,
734                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nTop,
735                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nLeft,
736                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nWidth,
737                                             (size_t&)focusAreas[0]->tAlgoAreas[n].nHeight);
738 
739             focusAreas[0]->tAlgoAreas[n].nLeft =
740                     ( focusAreas[0]->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth;
741             focusAreas[0]->tAlgoAreas[n].nTop =
742                     ( focusAreas[0]->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight;
743             focusAreas[0]->tAlgoAreas[n].nWidth =
744                     ( focusAreas[0]->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth;
745             focusAreas[0]->tAlgoAreas[n].nHeight =
746                     ( focusAreas[0]->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight;
747             focusAreas[0]->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight();
748 
749              CAMHAL_LOGDB("Focus area %d : top = %d left = %d width = %d height = %d prio = %d",
750                     n, (int)focusAreas[0]->tAlgoAreas[n].nTop, (int)focusAreas[0]->tAlgoAreas[n].nLeft,
751                     (int)focusAreas[0]->tAlgoAreas[n].nWidth, (int)focusAreas[0]->tAlgoAreas[n].nHeight,
752                     (int)focusAreas[0]->tAlgoAreas[n].nPriority);
753              }
754 
755         OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER);
756 
757         sharedBuffer.nPortIndex = OMX_ALL;
758         sharedBuffer.nSharedBuffSize = areasSize;
759         sharedBuffer.pSharedBuff = (OMX_U8 *) focusAreas[0];
760 
761         if ( NULL == sharedBuffer.pSharedBuff )
762             {
763             CAMHAL_LOGEA("No resources to allocate OMX shared buffer");
764             ret = -ENOMEM;
765             goto EXIT;
766             }
767 
768             eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
769                                       (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgoAreas, &sharedBuffer);
770 
771         if ( OMX_ErrorNone != eError )
772             {
773             CAMHAL_LOGEB("Error while setting Focus Areas configuration 0x%x", eError);
774             ret = -EINVAL;
775             }
776 
777     EXIT:
778         if (NULL != focusAreas)
779             {
780             memMgr.freeBuffer((void*) focusAreas);
781             focusAreas = NULL;
782             }
783         }
784 
785     LOG_FUNCTION_NAME_EXIT;
786 
787     return ret;
788 }
789 
handleFocusCallback()790 void OMXCameraAdapter::handleFocusCallback() {
791     OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus;
792     CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL;
793     status_t ret = NO_ERROR;
794     BaseCameraAdapter::AdapterState nextState;
795     BaseCameraAdapter::getNextState(nextState);
796 
797     OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE);
798 
799     ret = checkFocus(&eFocusStatus);
800 
801     if (NO_ERROR != ret) {
802         CAMHAL_LOGEA("Focus status check failed!");
803         // signal and unblock doAutoFocus
804         if (AF_ACTIVE & nextState) {
805             Mutex::Autolock lock(mDoAFMutex);
806             mDoAFCond.broadcast();
807         }
808         return;
809     }
810 
811     if ( ( eFocusStatus.eFocusStatus != OMX_FocusStatusRequest ) &&
812          ( eFocusStatus.eFocusStatus != OMX_FocusStatusOff ) ) {
813         // signal doAutoFocus when a end of scan message comes
814         // ignore start of scan
815         Mutex::Autolock lock(mDoAFMutex);
816         mDoAFCond.broadcast();
817     }
818 
819     if (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE) OMX_IMAGE_FocusControlAuto) {
820        CAMHAL_LOGDA("unregistered focus callback when not in CAF or doAutoFocus... not handling");
821        return;
822     }
823 
824     // Handling for CAF Callbacks
825     switch (eFocusStatus.eFocusStatus) {
826         case OMX_FocusStatusRequest:
827             focusStatus = CameraHalEvent::FOCUS_STATUS_PENDING;
828             break;
829         case OMX_FocusStatusReached:
830         case OMX_FocusStatusOff:
831         case OMX_FocusStatusUnableToReach:
832         default:
833             focusStatus = CameraHalEvent::FOCUS_STATUS_DONE;
834             break;
835     }
836 
837     notifyFocusSubscribers(focusStatus);
838 }
839 
840 };
841