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