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