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 ¶ms,
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 ¶ms)
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