OMXFocus.cpp revision 96f2b555d2200fca7d8399c4c9a968590637aa31
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 OMX_INIT_STRUCT_PTR (&focusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 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. 142 ret = checkFocus(&focusStatus); 143 if ( NO_ERROR != ret ) { 144 CAMHAL_LOGEB("Focus status check failed 0x%x!", ret); 145 return ret; 146 } else { 147 CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus); 148 } 149 } 150 151 if ( (focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto 152 && (focusStatus.eFocusStatus == OMX_FocusStatusRequest 153 || focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach) ) || 154 (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE)OMX_IMAGE_FocusControlAuto) ) 155 { 156 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 157 bOMX.bEnabled = OMX_TRUE; 158 159 //Enable focus scanning 160 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 161 (OMX_INDEXTYPE)OMX_TI_IndexConfigAutofocusEnable, 162 &bOMX); 163 164 // force AF, Ducati will take care of whether CAF 165 // or AF will be performed, depending on light conditions 166 if ( focusControl.eFocusControl == OMX_IMAGE_FocusControlAuto 167 && focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach ) 168 { 169 focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock; 170 } 171 172 if ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) 173 { 174 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 175 OMX_IndexConfigFocusControl, 176 &focusControl); 177 } 178 179 if ( OMX_ErrorNone != eError ) { 180 CAMHAL_LOGEB("Error while starting focus 0x%x", eError); 181 return INVALID_OPERATION; 182 } else { 183 CAMHAL_LOGDA("Autofocus started successfully"); 184 } 185 186 // configure focus timeout based on capture mode 187 timeout = (mCapMode == VIDEO_MODE) ? 188 ( ( nsecs_t ) AF_VIDEO_CALLBACK_TIMEOUT * 1000 ) : 189 ( ( nsecs_t ) AF_IMAGE_CALLBACK_TIMEOUT * 1000 ); 190 191 { 192 Mutex::Autolock lock(mDoAFMutex); 193 ret = mDoAFCond.waitRelative(mDoAFMutex, timeout); 194 } 195 196 //If somethiing bad happened while we wait 197 if (mComponentState == OMX_StateInvalid) { 198 CAMHAL_LOGEA("Invalid State after Auto Focus Exitting!!!"); 199 return -EINVAL; 200 } 201 202 if(ret != NO_ERROR) { 203 CAMHAL_LOGEA("Autofocus callback timeout expired"); 204 ret = returnFocusStatus(true); 205 } else { 206 ret = returnFocusStatus(false); 207 } 208 } else { // Focus mode in continuous 209 if ( NO_ERROR == ret ) { 210 ret = returnFocusStatus(true); 211 mPending3Asettings |= SetFocus; 212 } 213 } 214 215 LOG_FUNCTION_NAME_EXIT; 216 217 return ret; 218} 219 220status_t OMXCameraAdapter::stopAutoFocus() 221{ 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 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 } else { 256 // This is a WA. Usually the OMX Camera component should 257 // generate AF status change OMX event fairly quickly 258 // ( after one preview frame ) and this notification should 259 // actually come from 'handleFocusCallback()'. 260 Mutex::Autolock lock(mDoAFMutex); 261 mDoAFCond.broadcast(); 262 } 263 264 265 LOG_FUNCTION_NAME_EXIT; 266 267 return NO_ERROR; 268} 269 270status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode) 271{; 272 OMX_ERRORTYPE eError = OMX_ErrorNone; 273 274 LOG_FUNCTION_NAME; 275 276 if ( OMX_StateInvalid == mComponentState ) { 277 CAMHAL_LOGEA("OMX component is in invalid state"); 278 return NO_INIT; 279 } 280 281 OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE); 282 focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 283 284 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 285 OMX_IndexConfigFocusControl, 286 &focusMode); 287 288 if ( OMX_ErrorNone != eError ) { 289 CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError); 290 } 291 292 LOG_FUNCTION_NAME_EXIT; 293 294 return ErrorUtils::omxToAndroidError(eError); 295} 296 297status_t OMXCameraAdapter::cancelAutoFocus() 298{ 299 status_t ret = NO_ERROR; 300 OMX_ERRORTYPE eError = OMX_ErrorNone; 301 OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode; 302 303 LOG_FUNCTION_NAME; 304 305 ret = getFocusMode(focusMode); 306 if ( NO_ERROR != ret ) { 307 return ret; 308 } 309 310 //Stop the AF only for modes other than CAF or Inifinity 311 if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) && 312 ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE ) 313 OMX_IMAGE_FocusControlAutoInfinity ) ) { 314 stopAutoFocus(); 315 } else if (focusMode.eFocusControl == OMX_IMAGE_FocusControlAuto) { 316 // This re-enabling of CAF doesn't seem to 317 // be needed any more. 318 // re-apply CAF after unlocking and canceling 319 // mPending3Asettings |= SetFocus; 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 330status_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 386status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached) 387{ 388 status_t ret = NO_ERROR; 389 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 390 CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 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 = CameraHalEvent::FOCUS_STATUS_FAIL; 426 } 427 else 428 { 429 switch (eFocusStatus.eFocusStatus) 430 { 431 case OMX_FocusStatusReached: 432 { 433 focusStatus = CameraHalEvent::FOCUS_STATUS_SUCCESS; 434 break; 435 } 436 case OMX_FocusStatusOff: // AF got canceled 437 return NO_ERROR; 438 case OMX_FocusStatusUnableToReach: 439 case OMX_FocusStatusRequest: 440 default: 441 { 442 focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 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 stopAutoFocus(); 453 } 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 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 530status_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 556status_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 599status_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 631status_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 681status_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 789void OMXCameraAdapter::handleFocusCallback() { 790 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 791 CameraHalEvent::FocusStatus focusStatus = CameraHalEvent::FOCUS_STATUS_FAIL; 792 status_t ret = NO_ERROR; 793 BaseCameraAdapter::AdapterState nextState; 794 BaseCameraAdapter::getNextState(nextState); 795 796 OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 797 798 ret = checkFocus(&eFocusStatus); 799 800 if (NO_ERROR != ret) { 801 CAMHAL_LOGEA("Focus status check failed!"); 802 // signal and unblock doAutoFocus 803 if (AF_ACTIVE & nextState) { 804 Mutex::Autolock lock(mDoAFMutex); 805 mDoAFCond.broadcast(); 806 } 807 return; 808 } 809 810 if ( ( eFocusStatus.eFocusStatus != OMX_FocusStatusRequest ) && 811 ( eFocusStatus.eFocusStatus != OMX_FocusStatusOff ) ) { 812 // signal doAutoFocus when a end of scan message comes 813 // ignore start of scan 814 Mutex::Autolock lock(mDoAFMutex); 815 mDoAFCond.broadcast(); 816 } 817 818 if (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE) OMX_IMAGE_FocusControlAuto) { 819 CAMHAL_LOGDA("unregistered focus callback when not in CAF or doAutoFocus... not handling"); 820 return; 821 } 822 823 // Handling for CAF Callbacks 824 switch (eFocusStatus.eFocusStatus) { 825 case OMX_FocusStatusRequest: 826 focusStatus = CameraHalEvent::FOCUS_STATUS_PENDING; 827 break; 828 case OMX_FocusStatusReached: 829 case OMX_FocusStatusOff: 830 case OMX_FocusStatusUnableToReach: 831 default: 832 focusStatus = CameraHalEvent::FOCUS_STATUS_DONE; 833 break; 834 } 835 836 notifyFocusSubscribers(focusStatus); 837} 838 839}; 840