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