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