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