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 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 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 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 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 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 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 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 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 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 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 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 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 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 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