OMXFocus.cpp revision 796f0f82433a3040198f216d15fd9ce17c04f360
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 // This re-enabling of CAF doesn't seem to 315 // be needed any more. 316 // re-apply CAF after unlocking and canceling 317 // mPending3Asettings |= SetFocus; 318 } 319 // If the apps call #cancelAutoFocus()}, the face callbacks will also resume. 320 pauseFaceDetection(false); 321 322 LOG_FUNCTION_NAME_EXIT; 323 324 return ret; 325 326} 327 328status_t OMXCameraAdapter::setFocusCallback(bool enabled) 329{ 330 status_t ret = NO_ERROR; 331 OMX_ERRORTYPE eError = OMX_ErrorNone; 332 OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback; 333 334 LOG_FUNCTION_NAME; 335 336 if ( OMX_StateInvalid == mComponentState ) 337 { 338 CAMHAL_LOGEA("OMX component in Invalid state"); 339 ret = -EINVAL; 340 } 341 342 if ( OMX_StateExecuting != mComponentState ) 343 { 344 CAMHAL_LOGEA("OMX component not in executing state"); 345 ret = NO_ERROR; 346 } 347 348 if ( NO_ERROR == ret ) 349 { 350 351 OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE); 352 focusRequstCallback.nPortIndex = OMX_ALL; 353 focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus; 354 355 if ( enabled ) 356 { 357 focusRequstCallback.bEnable = OMX_TRUE; 358 } 359 else 360 { 361 focusRequstCallback.bEnable = OMX_FALSE; 362 } 363 364 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 365 (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest, 366 &focusRequstCallback); 367 if ( OMX_ErrorNone != eError ) 368 { 369 CAMHAL_LOGEB("Error registering focus callback 0x%x", eError); 370 ret = -1; 371 } 372 else 373 { 374 CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully", 375 OMX_IndexConfigCommonFocusStatus); 376 } 377 } 378 379 LOG_FUNCTION_NAME_EXIT; 380 381 return ret; 382} 383 384status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached) 385{ 386 status_t ret = NO_ERROR; 387 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 388 CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 389 BaseCameraAdapter::AdapterState state, nextState; 390 BaseCameraAdapter::getState(state); 391 BaseCameraAdapter::getNextState(nextState); 392 393 LOG_FUNCTION_NAME; 394 395 OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 396 397 if( ((AF_ACTIVE & state ) != AF_ACTIVE) && ((AF_ACTIVE & nextState ) != AF_ACTIVE) ) 398 { 399 /// We don't send focus callback if focus was not started 400 CAMHAL_LOGDA("Not sending focus callback because focus was not started"); 401 return NO_ERROR; 402 } 403 404 if ( NO_ERROR == ret ) 405 { 406 407 if ( !timeoutReached ) 408 { 409 ret = checkFocus(&eFocusStatus); 410 411 if ( NO_ERROR != ret ) 412 { 413 CAMHAL_LOGEA("Focus status check failed!"); 414 } 415 } 416 } 417 418 if ( NO_ERROR == ret ) 419 { 420 421 if ( timeoutReached ) 422 { 423 focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 424 } 425 else 426 { 427 switch (eFocusStatus.eFocusStatus) 428 { 429 case OMX_FocusStatusReached: 430 { 431 focusStatus = CameraHalEvent::FOCUS_STATUS_SUCCESS; 432 break; 433 } 434 case OMX_FocusStatusOff: // AF got canceled 435 return NO_ERROR; 436 case OMX_FocusStatusUnableToReach: 437 case OMX_FocusStatusRequest: 438 default: 439 { 440 focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 441 break; 442 } 443 } 444 // Lock CAF after AF call 445 if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_TRUE) != NO_ERROR) { 446 CAMHAL_LOGEA("Error Applying 3A locks"); 447 } else { 448 CAMHAL_LOGDA("Focus locked. Applied focus locks successfully"); 449 } 450 stopAutoFocus(); 451 } 452 453 //Query current focus distance after AF is complete 454 updateFocusDistances(mParameters); 455 } 456 457 ret = BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS); 458 if ( NO_ERROR == ret ) 459 { 460 ret = BaseCameraAdapter::commitState(); 461 } 462 else 463 { 464 ret |= BaseCameraAdapter::rollbackState(); 465 } 466 467 if ( NO_ERROR == ret ) 468 { 469 notifyFocusSubscribers(focusStatus); 470 } 471 472 // After focus, face detection will resume sending face callbacks 473 pauseFaceDetection(false); 474 475 LOG_FUNCTION_NAME_EXIT; 476 477 return ret; 478} 479 480status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus) 481{ 482 status_t ret = NO_ERROR; 483 OMX_ERRORTYPE eError = OMX_ErrorNone; 484 485 LOG_FUNCTION_NAME; 486 487 if ( NULL == eFocusStatus ) 488 { 489 CAMHAL_LOGEA("Invalid focus status"); 490 ret = -EINVAL; 491 } 492 493 if ( OMX_StateInvalid == mComponentState ) 494 { 495 CAMHAL_LOGEA("OMX component in Invalid state"); 496 ret = -EINVAL; 497 } 498 499 if ( OMX_StateExecuting != mComponentState ) 500 { 501 CAMHAL_LOGEA("OMX component not in executing state"); 502 ret = NO_ERROR; 503 } 504 505 if ( NO_ERROR == ret ) 506 { 507 OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 508 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 509 OMX_IndexConfigCommonFocusStatus, 510 eFocusStatus); 511 if ( OMX_ErrorNone != eError ) 512 { 513 CAMHAL_LOGEB("Error while retrieving focus status: 0x%x", eError); 514 ret = -1; 515 } 516 } 517 518 if ( NO_ERROR == ret ) 519 { 520 CAMHAL_LOGDB("Focus Status: %d", eFocusStatus->eFocusStatus); 521 } 522 523 LOG_FUNCTION_NAME_EXIT; 524 525 return ret; 526} 527 528status_t OMXCameraAdapter::updateFocusDistances(CameraParameters ¶ms) 529{ 530 OMX_U32 focusNear, focusOptimal, focusFar; 531 status_t ret = NO_ERROR; 532 533 LOG_FUNCTION_NAME; 534 535 ret = getFocusDistances(focusNear, focusOptimal, focusFar); 536 if ( NO_ERROR == ret) 537 { 538 ret = addFocusDistances(focusNear, focusOptimal, focusFar, params); 539 if ( NO_ERROR != ret ) 540 { 541 CAMHAL_LOGEB("Error in call to addFocusDistances() 0x%x", ret); 542 } 543 } 544 else 545 { 546 CAMHAL_LOGEB("Error in call to getFocusDistances() 0x%x", ret); 547 } 548 549 LOG_FUNCTION_NAME_EXIT; 550 551 return ret; 552} 553 554status_t OMXCameraAdapter::getFocusDistances(OMX_U32 &near,OMX_U32 &optimal, OMX_U32 &far) 555{ 556 status_t ret = NO_ERROR; 557 OMX_ERRORTYPE eError; 558 559 OMX_TI_CONFIG_FOCUSDISTANCETYPE focusDist; 560 561 LOG_FUNCTION_NAME; 562 563 if ( OMX_StateInvalid == mComponentState ) 564 { 565 CAMHAL_LOGEA("OMX component is in invalid state"); 566 ret = UNKNOWN_ERROR; 567 } 568 569 if ( NO_ERROR == ret ) 570 { 571 OMX_INIT_STRUCT_PTR(&focusDist, OMX_TI_CONFIG_FOCUSDISTANCETYPE); 572 focusDist.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 573 574 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 575 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigFocusDistance, 576 &focusDist); 577 if ( OMX_ErrorNone != eError ) 578 { 579 CAMHAL_LOGEB("Error while querying focus distances 0x%x", eError); 580 ret = UNKNOWN_ERROR; 581 } 582 583 } 584 585 if ( NO_ERROR == ret ) 586 { 587 near = focusDist.nFocusDistanceNear; 588 optimal = focusDist.nFocusDistanceOptimal; 589 far = focusDist.nFocusDistanceFar; 590 } 591 592 LOG_FUNCTION_NAME_EXIT; 593 594 return ret; 595} 596 597status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_t length) 598{ 599 status_t ret = NO_ERROR; 600 uint32_t focusScale = 1000; 601 float distFinal; 602 603 LOG_FUNCTION_NAME; 604 605 if(mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity) 606 { 607 dist=0; 608 } 609 610 if ( NO_ERROR == ret ) 611 { 612 if ( 0 == dist ) 613 { 614 strncpy(buffer, CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 )); 615 } 616 else 617 { 618 distFinal = dist; 619 distFinal /= focusScale; 620 snprintf(buffer, ( length - 1 ) , "%5.3f", distFinal); 621 } 622 } 623 624 LOG_FUNCTION_NAME_EXIT; 625 626 return ret; 627} 628 629status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near, 630 OMX_U32 &optimal, 631 OMX_U32 &far, 632 CameraParameters& params) 633{ 634 status_t ret = NO_ERROR; 635 636 LOG_FUNCTION_NAME; 637 638 if ( NO_ERROR == ret ) 639 { 640 ret = encodeFocusDistance(near, mFocusDistNear, FOCUS_DIST_SIZE); 641 if ( NO_ERROR != ret ) 642 { 643 CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret); 644 } 645 } 646 647 if ( NO_ERROR == ret ) 648 { 649 ret = encodeFocusDistance(optimal, mFocusDistOptimal, FOCUS_DIST_SIZE); 650 if ( NO_ERROR != ret ) 651 { 652 CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret); 653 } 654 } 655 656 if ( NO_ERROR == ret ) 657 { 658 ret = encodeFocusDistance(far, mFocusDistFar, FOCUS_DIST_SIZE); 659 if ( NO_ERROR != ret ) 660 { 661 CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret); 662 } 663 } 664 665 if ( NO_ERROR == ret ) 666 { 667 snprintf(mFocusDistBuffer, ( FOCUS_DIST_BUFFER_SIZE - 1) ,"%s,%s,%s", mFocusDistNear, 668 mFocusDistOptimal, 669 mFocusDistFar); 670 671 params.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer); 672 } 673 674 LOG_FUNCTION_NAME_EXIT; 675 676 return ret; 677} 678 679status_t OMXCameraAdapter::setTouchFocus() 680{ 681 status_t ret = NO_ERROR; 682 OMX_ERRORTYPE eError = OMX_ErrorNone; 683 684 OMX_ALGOAREASTYPE **focusAreas; 685 OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer; 686 MemoryManager memMgr; 687 int areasSize = 0; 688 689 LOG_FUNCTION_NAME; 690 691 if ( OMX_StateInvalid == mComponentState ) 692 { 693 CAMHAL_LOGEA("OMX component is in invalid state"); 694 ret = -1; 695 } 696 697 if ( NO_ERROR == ret ) 698 { 699 700 areasSize = ((sizeof(OMX_ALGOAREASTYPE)+4095)/4096)*4096; 701 focusAreas = (OMX_ALGOAREASTYPE**) memMgr.allocateBuffer(0, 0, NULL, areasSize, 1); 702 703 OMXCameraPortParameters * mPreviewData = NULL; 704 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 705 706 if (!focusAreas) 707 { 708 CAMHAL_LOGEB("Error allocating buffer for focus areas %d", eError); 709 return -ENOMEM; 710 } 711 712 OMX_INIT_STRUCT_PTR (focusAreas[0], OMX_ALGOAREASTYPE); 713 714 focusAreas[0]->nPortIndex = OMX_ALL; 715 focusAreas[0]->nNumAreas = mFocusAreas.size(); 716 focusAreas[0]->nAlgoAreaPurpose = OMX_AlgoAreaFocus; 717 718 // If the area is the special case of (0, 0, 0, 0, 0), then 719 // the algorithm needs nNumAreas to be set to 0, 720 // in order to automatically choose the best fitting areas. 721 if ( mFocusAreas.itemAt(0)->isZeroArea() ) 722 { 723 focusAreas[0]->nNumAreas = 0; 724 } 725 726 for ( unsigned int n = 0; n < mFocusAreas.size(); n++) 727 { 728 // transform the coordinates to 3A-type coordinates 729 mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth, 730 (size_t)mPreviewData->mHeight, 731 (size_t&)focusAreas[0]->tAlgoAreas[n].nTop, 732 (size_t&)focusAreas[0]->tAlgoAreas[n].nLeft, 733 (size_t&)focusAreas[0]->tAlgoAreas[n].nWidth, 734 (size_t&)focusAreas[0]->tAlgoAreas[n].nHeight); 735 736 focusAreas[0]->tAlgoAreas[n].nLeft = 737 ( focusAreas[0]->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; 738 focusAreas[0]->tAlgoAreas[n].nTop = 739 ( focusAreas[0]->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; 740 focusAreas[0]->tAlgoAreas[n].nWidth = 741 ( focusAreas[0]->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; 742 focusAreas[0]->tAlgoAreas[n].nHeight = 743 ( focusAreas[0]->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; 744 focusAreas[0]->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight(); 745 746 CAMHAL_LOGDB("Focus area %d : top = %d left = %d width = %d height = %d prio = %d", 747 n, (int)focusAreas[0]->tAlgoAreas[n].nTop, (int)focusAreas[0]->tAlgoAreas[n].nLeft, 748 (int)focusAreas[0]->tAlgoAreas[n].nWidth, (int)focusAreas[0]->tAlgoAreas[n].nHeight, 749 (int)focusAreas[0]->tAlgoAreas[n].nPriority); 750 } 751 752 OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER); 753 754 sharedBuffer.nPortIndex = OMX_ALL; 755 sharedBuffer.nSharedBuffSize = areasSize; 756 sharedBuffer.pSharedBuff = (OMX_U8 *) focusAreas[0]; 757 758 if ( NULL == sharedBuffer.pSharedBuff ) 759 { 760 CAMHAL_LOGEA("No resources to allocate OMX shared buffer"); 761 ret = -ENOMEM; 762 goto EXIT; 763 } 764 765 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 766 (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgoAreas, &sharedBuffer); 767 768 if ( OMX_ErrorNone != eError ) 769 { 770 CAMHAL_LOGEB("Error while setting Focus Areas configuration 0x%x", eError); 771 ret = -EINVAL; 772 } 773 774 EXIT: 775 if (NULL != focusAreas) 776 { 777 memMgr.freeBuffer((void*) focusAreas); 778 focusAreas = NULL; 779 } 780 } 781 782 LOG_FUNCTION_NAME_EXIT; 783 784 return ret; 785} 786 787void OMXCameraAdapter::handleFocusCallback() { 788 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 789 CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 790 status_t ret = NO_ERROR; 791 BaseCameraAdapter::AdapterState nextState; 792 BaseCameraAdapter::getNextState(nextState); 793 794 OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 795 796 ret = checkFocus(&eFocusStatus); 797 798 if (NO_ERROR != ret) { 799 CAMHAL_LOGEA("Focus status check failed!"); 800 // signal and unblock doAutoFocus 801 if (AF_ACTIVE & nextState) { 802 Mutex::Autolock lock(mDoAFMutex); 803 mDoAFCond.broadcast(); 804 } 805 return; 806 } 807 808 if ( ( eFocusStatus.eFocusStatus != OMX_FocusStatusRequest ) && 809 ( eFocusStatus.eFocusStatus != OMX_FocusStatusOff ) ) { 810 // signal doAutoFocus when a end of scan message comes 811 // ignore start of scan 812 Mutex::Autolock lock(mDoAFMutex); 813 mDoAFCond.broadcast(); 814 } 815 816 if (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE) OMX_IMAGE_FocusControlAuto) { 817 CAMHAL_LOGDA("unregistered focus callback when not in CAF or doAutoFocus... not handling"); 818 return; 819 } 820 821 // Handling for CAF Callbacks 822 switch (eFocusStatus.eFocusStatus) { 823 case OMX_FocusStatusRequest: 824 focusStatus = CameraHalEvent::FOCUS_STATUS_PENDING; 825 break; 826 case OMX_FocusStatusReached: 827 case OMX_FocusStatusOff: 828 case OMX_FocusStatusUnableToReach: 829 default: 830 focusStatus = CameraHalEvent::FOCUS_STATUS_DONE; 831 break; 832 } 833 834 notifyFocusSubscribers(focusStatus); 835} 836 837}; 838