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