OMXFocus.cpp revision 057f4fd59ec05ded909e9eb9a3363d9ea345b0ca
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. 145 ret = checkFocus(&focusStatus); 146 if ( NO_ERROR != ret ) { 147 CAMHAL_LOGEB("Focus status check failed 0x%x!", ret); 148 return ret; 149 } else { 150 CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus); 151 } 152 } 153 154 if ( (focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto 155 && (focusStatus.eFocusStatus == OMX_FocusStatusRequest 156 || focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach) ) || 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 // force AF, Ducati will take care of whether CAF 168 // or AF will be performed, depending on light conditions 169 if ( focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto 170 && focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach ) 171 { 172 focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock; 173 } 174 175 if ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) 176 { 177 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 178 OMX_IndexConfigFocusControl, 179 &focusControl); 180 } 181 182 if ( OMX_ErrorNone != eError ) { 183 CAMHAL_LOGEB("Error while starting focus 0x%x", eError); 184 return INVALID_OPERATION; 185 } else { 186 CAMHAL_LOGDA("Autofocus started successfully"); 187 } 188 189 // configure focus timeout based on capture mode 190 timeout = (mCapMode == VIDEO_MODE) ? AF_VIDEO_CALLBACK_TIMEOUT : AF_IMAGE_CALLBACK_TIMEOUT; 191 192 ret = mDoAFSem.WaitTimeout(timeout); 193 //If somethiing bad happened while we wait 194 if (mComponentState == OMX_StateInvalid) { 195 CAMHAL_LOGEA("Invalid State after Auto Focus Exitting!!!"); 196 return -EINVAL; 197 } 198 199 if(ret != NO_ERROR) { 200 //Disable auto focus callback from Ducati 201 setFocusCallback(false); 202 CAMHAL_LOGEA("Autofocus callback timeout expired"); 203 ret = returnFocusStatus(true); 204 } else { 205 ret = returnFocusStatus(false); 206 } 207 } else { // Focus mode in continuous 208 if ( NO_ERROR == ret ) { 209 ret = returnFocusStatus(false); 210 mPending3Asettings |= SetFocus; 211 } 212 } 213 214 LOG_FUNCTION_NAME_EXIT; 215 216 return ret; 217} 218 219status_t OMXCameraAdapter::stopAutoFocus() 220{ 221 status_t ret = NO_ERROR; 222 OMX_ERRORTYPE eError = OMX_ErrorNone; 223 OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl; 224 225 LOG_FUNCTION_NAME; 226 227 if ( OMX_StateInvalid == mComponentState ) 228 { 229 CAMHAL_LOGEA("OMX component in Invalid state"); 230 returnFocusStatus(false); 231 return -EINVAL; 232 } 233 234 if ( OMX_StateExecuting != mComponentState ) 235 { 236 CAMHAL_LOGEA("OMX component not in executing state"); 237 return NO_ERROR; 238 } 239 240 if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) { 241 // No need to stop focus if we are in infinity mode. Nothing to stop. 242 return NO_ERROR; 243 } 244 245 if ( NO_ERROR == ret ) 246 { 247 OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE); 248 focusControl.eFocusControl = OMX_IMAGE_FocusControlOff; 249 250 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 251 OMX_IndexConfigFocusControl, 252 &focusControl); 253 if ( OMX_ErrorNone != eError ) 254 { 255 CAMHAL_LOGEB("Error while stopping focus 0x%x", eError); 256 return ErrorUtils::omxToAndroidError(eError); 257 } 258 } 259 260 LOG_FUNCTION_NAME_EXIT; 261 262 return ret; 263} 264 265status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode) 266{; 267 OMX_ERRORTYPE eError = OMX_ErrorNone; 268 269 LOG_FUNCTION_NAME; 270 271 if ( OMX_StateInvalid == mComponentState ) { 272 CAMHAL_LOGEA("OMX component is in invalid state"); 273 return NO_INIT; 274 } 275 276 OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE); 277 focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 278 279 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 280 OMX_IndexConfigFocusControl, 281 &focusMode); 282 283 if ( OMX_ErrorNone != eError ) { 284 CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError); 285 } 286 287 LOG_FUNCTION_NAME_EXIT; 288 289 return ErrorUtils::omxToAndroidError(eError); 290} 291 292status_t OMXCameraAdapter::cancelAutoFocus() 293{ 294 status_t ret = NO_ERROR; 295 OMX_ERRORTYPE eError = OMX_ErrorNone; 296 OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode; 297 298 LOG_FUNCTION_NAME; 299 300 ret = getFocusMode(focusMode); 301 if ( NO_ERROR != ret ) { 302 return ret; 303 } 304 305 //Stop the AF only for modes other than CAF or Inifinity 306 if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) && 307 ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE ) 308 OMX_IMAGE_FocusControlAutoInfinity ) ) { 309 stopAutoFocus(); 310 //Signal a dummy AF event so that in case the callback from ducati 311 //does come then it doesnt crash after 312 //exiting this function since eventSem will go out of scope. 313 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 314 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 315 OMX_ALL, 316 OMX_IndexConfigCommonFocusStatus, 317 NULL ); 318 } else if (focusMode.eFocusControl == OMX_IMAGE_FocusControlAuto) { 319 // re-apply CAF after unlocking and canceling 320 mPending3Asettings |= SetFocus; 321 } 322 323 // If the apps call #cancelAutoFocus()}, the face callbacks will also resume. 324 pauseFaceDetection(false); 325 326 LOG_FUNCTION_NAME_EXIT; 327 328 return ret; 329 330} 331 332status_t OMXCameraAdapter::setFocusCallback(bool enabled) 333{ 334 status_t ret = NO_ERROR; 335 OMX_ERRORTYPE eError = OMX_ErrorNone; 336 OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback; 337 338 LOG_FUNCTION_NAME; 339 340 if ( OMX_StateInvalid == mComponentState ) 341 { 342 CAMHAL_LOGEA("OMX component in Invalid state"); 343 ret = -EINVAL; 344 } 345 346 if ( OMX_StateExecuting != mComponentState ) 347 { 348 CAMHAL_LOGEA("OMX component not in executing state"); 349 ret = NO_ERROR; 350 } 351 352 if ( NO_ERROR == ret ) 353 { 354 355 OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE); 356 focusRequstCallback.nPortIndex = OMX_ALL; 357 focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus; 358 359 if ( enabled ) 360 { 361 focusRequstCallback.bEnable = OMX_TRUE; 362 } 363 else 364 { 365 focusRequstCallback.bEnable = OMX_FALSE; 366 } 367 368 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 369 (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest, 370 &focusRequstCallback); 371 if ( OMX_ErrorNone != eError ) 372 { 373 CAMHAL_LOGEB("Error registering focus callback 0x%x", eError); 374 ret = -1; 375 } 376 else 377 { 378 CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully", 379 OMX_IndexConfigCommonFocusStatus); 380 } 381 } 382 383 LOG_FUNCTION_NAME_EXIT; 384 385 return ret; 386} 387 388status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached) 389{ 390 status_t ret = NO_ERROR; 391 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 392 CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 393 BaseCameraAdapter::AdapterState state, nextState; 394 BaseCameraAdapter::getState(state); 395 BaseCameraAdapter::getNextState(nextState); 396 397 LOG_FUNCTION_NAME; 398 399 OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 400 401 if( ((AF_ACTIVE & state ) != AF_ACTIVE) && ((AF_ACTIVE & nextState ) != AF_ACTIVE) ) 402 { 403 /// We don't send focus callback if focus was not started 404 CAMHAL_LOGDA("Not sending focus callback because focus was not started"); 405 return NO_ERROR; 406 } 407 408 if ( NO_ERROR == ret ) 409 { 410 411 if ( !timeoutReached ) 412 { 413 ret = checkFocus(&eFocusStatus); 414 415 if ( NO_ERROR != ret ) 416 { 417 CAMHAL_LOGEA("Focus status check failed!"); 418 } 419 } 420 } 421 422 if ( NO_ERROR == ret ) 423 { 424 425 if ( timeoutReached ) 426 { 427 focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 428 } 429 else 430 { 431 switch (eFocusStatus.eFocusStatus) 432 { 433 case OMX_FocusStatusReached: 434 { 435 focusStatus = CameraHalEvent::FOCUS_STATUS_SUCCESS; 436 break; 437 } 438 case OMX_FocusStatusOff: 439 case OMX_FocusStatusUnableToReach: 440 case OMX_FocusStatusRequest: 441 default: 442 { 443 focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 444 break; 445 } 446 } 447 // Lock CAF after AF call 448 if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_TRUE) != NO_ERROR) { 449 CAMHAL_LOGEA("Error Applying 3A locks"); 450 } else { 451 CAMHAL_LOGDA("Focus locked. Applied focus locks successfully"); 452 } 453 454 stopAutoFocus(); 455 } 456 //Query current focus distance after AF is complete 457 updateFocusDistances(mParameters); 458 } 459 460 ret = BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS); 461 if ( NO_ERROR == ret ) 462 { 463 ret = BaseCameraAdapter::commitState(); 464 } 465 else 466 { 467 ret |= BaseCameraAdapter::rollbackState(); 468 } 469 470 if ( NO_ERROR == ret ) 471 { 472 notifyFocusSubscribers(focusStatus); 473 } 474 475 // After focus, face detection will resume sending face callbacks 476 pauseFaceDetection(false); 477 478 LOG_FUNCTION_NAME_EXIT; 479 480 return ret; 481} 482 483status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus) 484{ 485 status_t ret = NO_ERROR; 486 OMX_ERRORTYPE eError = OMX_ErrorNone; 487 488 LOG_FUNCTION_NAME; 489 490 if ( NULL == eFocusStatus ) 491 { 492 CAMHAL_LOGEA("Invalid focus status"); 493 ret = -EINVAL; 494 } 495 496 if ( OMX_StateInvalid == mComponentState ) 497 { 498 CAMHAL_LOGEA("OMX component in Invalid state"); 499 ret = -EINVAL; 500 } 501 502 if ( OMX_StateExecuting != mComponentState ) 503 { 504 CAMHAL_LOGEA("OMX component not in executing state"); 505 ret = NO_ERROR; 506 } 507 508 if ( NO_ERROR == ret ) 509 { 510 OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 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 790void OMXCameraAdapter::handleFocusCallback() { 791 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 792 CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 793 status_t ret = NO_ERROR; 794 BaseCameraAdapter::AdapterState nextState; 795 BaseCameraAdapter::getNextState(nextState); 796 797 OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 798 799 ret = checkFocus(&eFocusStatus); 800 801 if (NO_ERROR != ret) { 802 CAMHAL_LOGEA("Focus status check failed!"); 803 // signal and unblock doAutoFocus 804 if (AF_ACTIVE & nextState) { 805 mDoAFSem.Signal(); 806 } 807 return; 808 } else if (AF_ACTIVE & nextState) { // Handling for AF callback 809 // signal doAutoFocus when a end of scan message comes 810 // ignore start of scan 811 if (eFocusStatus.eFocusStatus != OMX_FocusStatusRequest) { 812 mDoAFSem.Signal(); 813 } 814 return; 815 } 816 817 if (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE) OMX_IMAGE_FocusControlAuto) { 818 CAMHAL_LOGDA("unregistered focus callback when not in CAF or doAutoFocus... not handling"); 819 return; 820 } 821 822 // Handling for CAF Callbacks 823 switch (eFocusStatus.eFocusStatus) { 824 case OMX_FocusStatusRequest: 825 focusStatus = CameraHalEvent::FOCUS_STATUS_PENDING; 826 break; 827 case OMX_FocusStatusReached: 828 case OMX_FocusStatusOff: 829 case OMX_FocusStatusUnableToReach: 830 default: 831 focusStatus = CameraHalEvent::FOCUS_STATUS_DONE; 832 break; 833 } 834 835 notifyFocusSubscribers(focusStatus); 836} 837 838}; 839