OMXFocus.cpp revision bbdc0fa0b8720bcfcf602861f62802c1fa1995c4
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_CALLBACK_TIMEOUT 5000000 //5 seconds timeout 35 36namespace android { 37 38status_t OMXCameraAdapter::setParametersFocus(const CameraParameters ¶ms, 39 BaseCameraAdapter::AdapterState state) 40{ 41 status_t ret = NO_ERROR; 42 const char *str = NULL; 43 Mutex::Autolock lock(mFocusAreasLock); 44 size_t MAX_FOCUS_AREAS; 45 46 47 LOG_FUNCTION_NAME; 48 49 str = params.get(CameraParameters::KEY_FOCUS_AREAS); 50 51 MAX_FOCUS_AREAS = atoi(params.get(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS)); 52 53 mFocusAreas.clear(); 54 if ( NULL != str ) { 55 ret = CameraArea::parseAreas(str, ( strlen(str) + 1 ), mFocusAreas); 56 } 57 58 if ( NO_ERROR == ret ) { 59 if ( MAX_FOCUS_AREAS < mFocusAreas.size() ) { 60 CAMHAL_LOGEB("Focus areas supported %d, focus areas set %d", 61 MAX_FOCUS_AREAS, 62 mFocusAreas.size()); 63 ret = -EINVAL; 64 } 65 } 66 67 LOG_FUNCTION_NAME; 68 69 return ret; 70} 71 72status_t OMXCameraAdapter::doAutoFocus() 73{ 74 status_t ret = NO_ERROR; 75 OMX_ERRORTYPE eError = OMX_ErrorNone; 76 OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl; 77 OMX_PARAM_FOCUSSTATUSTYPE focusStatus; 78 79 LOG_FUNCTION_NAME; 80 81 if ( OMX_StateExecuting != mComponentState ) 82 { 83 CAMHAL_LOGEA("OMX component not in executing state"); 84 returnFocusStatus(false); 85 return NO_INIT; 86 } 87 88 if ( 0 != mDoAFSem.Count() ) 89 { 90 CAMHAL_LOGEB("Error mDoAFSem semaphore count %d", mDoAFSem.Count()); 91 return NO_INIT; 92 } 93 94 // If the app calls autoFocus, the camera will stop sending face callbacks. 95 pauseFaceDetection(true); 96 97 OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE); 98 focusControl.eFocusControl = ( OMX_IMAGE_FOCUSCONTROLTYPE ) mParameters3A.Focus; 99 100 if (mParameters3A.FocusLock) { 101 // this basically means user never called cancelAutoFocus after a scan... 102 // if this is the case we need to unlock AF to ensure we will do a scan 103 if (set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_FALSE) != NO_ERROR) { 104 CAMHAL_LOGEA("Error Unlocking 3A locks"); 105 } else { 106 CAMHAL_LOGDA("AE/AWB unlocked successfully"); 107 } 108 109 // if we are in CAF...then force normal AF 110 if (mParameters3A.Focus == OMX_IMAGE_FocusControlAuto) { 111 focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock; 112 } 113 } else if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAuto ) { 114 // In case we have CAF running we should first check the AF status. 115 // If it has managed to lock, then do as usual and return status 116 // immediately. If lock is not available, then switch temporarily 117 // to 'autolock' and do normal AF. 118 ret = checkFocus(&focusStatus); 119 if ( NO_ERROR != ret ) { 120 CAMHAL_LOGEB("Focus status check failed 0x%x!", ret); 121 return ret; 122 } else { 123 CAMHAL_LOGDB("Focus status check 0x%x!", focusStatus.eFocusStatus); 124 } 125 126 if ( OMX_FocusStatusReached != focusStatus.eFocusStatus ) { 127 focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock; 128 } 129 } 130 131 if ( ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) && 132 ( focusControl.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE ) 133 OMX_IMAGE_FocusControlAutoInfinity ) ) { 134 135 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 136 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 137 OMX_ALL, 138 OMX_IndexConfigCommonFocusStatus, 139 mDoAFSem); 140 141 if ( NO_ERROR == ret ) { 142 ret = setFocusCallback(true); 143 } 144 145 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 146 OMX_IndexConfigFocusControl, 147 &focusControl); 148 149 if ( OMX_ErrorNone != eError ) { 150 CAMHAL_LOGEB("Error while starting focus 0x%x", eError); 151 return INVALID_OPERATION; 152 } else { 153 CAMHAL_LOGDA("Autofocus started successfully"); 154 } 155 156 if(mDoAFSem.WaitTimeout(AF_CALLBACK_TIMEOUT) != NO_ERROR) { 157 //If somethiing bad happened while we wait 158 if (mComponentState == OMX_StateInvalid) { 159 CAMHAL_LOGEA("Invalid State after Auto Focus Exitting!!!"); 160 return EINVAL; 161 } 162 163 //Disable auto focus callback from Ducati 164 setFocusCallback(false); 165 CAMHAL_LOGEA("Autofocus callback timeout expired"); 166 RemoveEvent(mCameraAdapterParameters.mHandleComp, 167 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 168 OMX_ALL, 169 OMX_IndexConfigCommonFocusStatus, 170 NULL ); 171 returnFocusStatus(true); 172 } else { 173 CAMHAL_LOGDA("Autofocus callback received"); 174 //Disable auto focus callback from Ducati 175 setFocusCallback(false); 176 ret = returnFocusStatus(false); 177 } 178 } else { // Focus mode in continuous 179 if ( NO_ERROR == ret ) { 180 ret = returnFocusStatus(false); 181 } 182 } 183 184 //Restore CAF if needed 185 if ( ( mParameters3A.Focus == OMX_IMAGE_FocusControlAuto ) && 186 ( focusControl.eFocusControl == OMX_IMAGE_FocusControlAutoLock ) ) { 187 mPending3Asettings |= SetFocus; 188 } 189 190 LOG_FUNCTION_NAME_EXIT; 191 192 return ret; 193} 194 195status_t OMXCameraAdapter::stopAutoFocus() 196{ 197 status_t ret = NO_ERROR; 198 OMX_ERRORTYPE eError = OMX_ErrorNone; 199 OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl; 200 201 LOG_FUNCTION_NAME; 202 203 if ( OMX_StateExecuting != mComponentState ) 204 { 205 CAMHAL_LOGEA("OMX component not in executing state"); 206 return NO_INIT; 207 } 208 209 if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) { 210 // No need to stop focus if we are in infinity mode. Nothing to stop. 211 return NO_ERROR; 212 } 213 214 if ( NO_ERROR == ret ) 215 { 216 //Disable the callback first 217 ret = setFocusCallback(false); 218 } 219 220 if ( NO_ERROR == ret ) 221 { 222 OMX_INIT_STRUCT_PTR (&focusControl, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE); 223 focusControl.eFocusControl = OMX_IMAGE_FocusControlOff; 224 225 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 226 OMX_IndexConfigFocusControl, 227 &focusControl); 228 if ( OMX_ErrorNone != eError ) 229 { 230 CAMHAL_LOGEB("Error while stopping focus 0x%x", eError); 231 return ErrorUtils::omxToAndroidError(eError); 232 } 233 } 234 235 //Query current focus distance after AF is complete 236 updateFocusDistances(mParameters); 237 238 LOG_FUNCTION_NAME_EXIT; 239 240 return ret; 241} 242 243status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode) 244{; 245 OMX_ERRORTYPE eError = OMX_ErrorNone; 246 247 LOG_FUNCTION_NAME; 248 249 if ( OMX_StateInvalid == mComponentState ) { 250 CAMHAL_LOGEA("OMX component is in invalid state"); 251 return NO_INIT; 252 } 253 254 OMX_INIT_STRUCT_PTR (&focusMode, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE); 255 focusMode.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 256 257 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 258 OMX_IndexConfigFocusControl, 259 &focusMode); 260 261 if ( OMX_ErrorNone != eError ) { 262 CAMHAL_LOGEB("Error while retrieving focus mode 0x%x", eError); 263 } 264 265 LOG_FUNCTION_NAME_EXIT; 266 267 return ErrorUtils::omxToAndroidError(eError); 268} 269 270status_t OMXCameraAdapter::cancelAutoFocus() 271{ 272 status_t ret = NO_ERROR; 273 OMX_ERRORTYPE eError = OMX_ErrorNone; 274 OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusMode; 275 276 LOG_FUNCTION_NAME; 277 // Unlock 3A locks since they were locked by AF conditionally 278 if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_FALSE) != NO_ERROR) { 279 CAMHAL_LOGEA("Error Unlocking 3A locks"); 280 } 281 else{ 282 CAMHAL_LOGDA("AE/AWB unlocked successfully"); 283 } 284 285 ret = getFocusMode(focusMode); 286 if ( NO_ERROR != ret ) { 287 return ret; 288 } 289 290 //Stop the AF only for modes other than CAF or Inifinity 291 if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) && 292 ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE ) 293 OMX_IMAGE_FocusControlAutoInfinity ) ) { 294 stopAutoFocus(); 295 //Signal a dummy AF event so that in case the callback from ducati 296 //does come then it doesnt crash after 297 //exiting this function since eventSem will go out of scope. 298 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 299 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 300 OMX_ALL, 301 OMX_IndexConfigCommonFocusStatus, 302 NULL ); 303 } 304 305 // If the apps call #cancelAutoFocus()}, the face callbacks will also resume. 306 pauseFaceDetection(false); 307 308 LOG_FUNCTION_NAME_EXIT; 309 310 return ret; 311 312} 313 314status_t OMXCameraAdapter::setFocusCallback(bool enabled) 315{ 316 status_t ret = NO_ERROR; 317 OMX_ERRORTYPE eError = OMX_ErrorNone; 318 OMX_CONFIG_CALLBACKREQUESTTYPE focusRequstCallback; 319 320 LOG_FUNCTION_NAME; 321 322 if ( OMX_StateExecuting != mComponentState ) 323 { 324 CAMHAL_LOGEA("OMX component not in executing state"); 325 ret = -1; 326 } 327 328 if ( NO_ERROR == ret ) 329 { 330 331 OMX_INIT_STRUCT_PTR (&focusRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE); 332 focusRequstCallback.nPortIndex = OMX_ALL; 333 focusRequstCallback.nIndex = OMX_IndexConfigCommonFocusStatus; 334 335 if ( enabled ) 336 { 337 focusRequstCallback.bEnable = OMX_TRUE; 338 } 339 else 340 { 341 focusRequstCallback.bEnable = OMX_FALSE; 342 } 343 344 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 345 (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest, 346 &focusRequstCallback); 347 if ( OMX_ErrorNone != eError ) 348 { 349 CAMHAL_LOGEB("Error registering focus callback 0x%x", eError); 350 ret = -1; 351 } 352 else 353 { 354 CAMHAL_LOGDB("Autofocus callback for index 0x%x registered successfully", 355 OMX_IndexConfigCommonFocusStatus); 356 } 357 } 358 359 LOG_FUNCTION_NAME_EXIT; 360 361 return ret; 362} 363 364status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached) 365{ 366 status_t ret = NO_ERROR; 367 OMX_PARAM_FOCUSSTATUSTYPE eFocusStatus; 368 bool focusStatus = false; 369 BaseCameraAdapter::AdapterState state, nextState; 370 BaseCameraAdapter::getState(state); 371 BaseCameraAdapter::getNextState(nextState); 372 373 LOG_FUNCTION_NAME; 374 375 OMX_INIT_STRUCT(eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 376 377 if( ((AF_ACTIVE & state ) != AF_ACTIVE) && ((AF_ACTIVE & nextState ) != AF_ACTIVE) ) 378 { 379 /// We don't send focus callback if focus was not started 380 CAMHAL_LOGDA("Not sending focus callback because focus was not started"); 381 return NO_ERROR; 382 } 383 384 if ( NO_ERROR == ret ) 385 { 386 387 if ( !timeoutReached ) 388 { 389 ret = checkFocus(&eFocusStatus); 390 391 if ( NO_ERROR != ret ) 392 { 393 CAMHAL_LOGEA("Focus status check failed!"); 394 } 395 } 396 } 397 398 if ( NO_ERROR == ret ) 399 { 400 401 if ( timeoutReached ) 402 { 403 focusStatus = false; 404 } 405 else 406 { 407 switch (eFocusStatus.eFocusStatus) 408 { 409 case OMX_FocusStatusReached: 410 { 411 focusStatus = true; 412 break; 413 } 414 case OMX_FocusStatusOff: 415 case OMX_FocusStatusUnableToReach: 416 case OMX_FocusStatusRequest: 417 default: 418 { 419 focusStatus = false; 420 break; 421 } 422 } 423 // Lock CAF after AF call 424 if( set3ALock(mUserSetExpLock, mUserSetWbLock, OMX_TRUE) != NO_ERROR) { 425 CAMHAL_LOGEA("Error Applying 3A locks"); 426 } else { 427 CAMHAL_LOGDA("Focus locked. Applied focus locks successfully"); 428 } 429 430 stopAutoFocus(); 431 } 432 } 433 434 ret = BaseCameraAdapter::setState(CAMERA_CANCEL_AUTOFOCUS); 435 if ( NO_ERROR == ret ) 436 { 437 ret = BaseCameraAdapter::commitState(); 438 } 439 else 440 { 441 ret |= BaseCameraAdapter::rollbackState(); 442 } 443 444 if ( NO_ERROR == ret ) 445 { 446 notifyFocusSubscribers(focusStatus); 447 } 448 449 // After focus, face detection will resume sending face callbacks 450 pauseFaceDetection(false); 451 452 LOG_FUNCTION_NAME_EXIT; 453 454 return ret; 455} 456 457status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus) 458{ 459 status_t ret = NO_ERROR; 460 OMX_ERRORTYPE eError = OMX_ErrorNone; 461 462 LOG_FUNCTION_NAME; 463 464 if ( NULL == eFocusStatus ) 465 { 466 CAMHAL_LOGEA("Invalid focus status"); 467 ret = -EINVAL; 468 } 469 470 if ( OMX_StateExecuting != mComponentState ) 471 { 472 CAMHAL_LOGEA("OMX component not in executing state"); 473 ret = -EINVAL; 474 } 475 476 if ( NO_ERROR == ret ) 477 { 478 OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); 479 480 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 481 OMX_IndexConfigCommonFocusStatus, 482 eFocusStatus); 483 if ( OMX_ErrorNone != eError ) 484 { 485 CAMHAL_LOGEB("Error while retrieving focus status: 0x%x", eError); 486 ret = -1; 487 } 488 } 489 490 if ( NO_ERROR == ret ) 491 { 492 CAMHAL_LOGDB("Focus Status: %d", eFocusStatus->eFocusStatus); 493 } 494 495 LOG_FUNCTION_NAME_EXIT; 496 497 return ret; 498} 499 500status_t OMXCameraAdapter::updateFocusDistances(CameraParameters ¶ms) 501{ 502 OMX_U32 focusNear, focusOptimal, focusFar; 503 status_t ret = NO_ERROR; 504 505 LOG_FUNCTION_NAME; 506 507 ret = getFocusDistances(focusNear, focusOptimal, focusFar); 508 if ( NO_ERROR == ret) 509 { 510 ret = addFocusDistances(focusNear, focusOptimal, focusFar, params); 511 if ( NO_ERROR != ret ) 512 { 513 CAMHAL_LOGEB("Error in call to addFocusDistances() 0x%x", ret); 514 } 515 } 516 else 517 { 518 CAMHAL_LOGEB("Error in call to getFocusDistances() 0x%x", ret); 519 } 520 521 LOG_FUNCTION_NAME_EXIT; 522 523 return ret; 524} 525 526status_t OMXCameraAdapter::getFocusDistances(OMX_U32 &near,OMX_U32 &optimal, OMX_U32 &far) 527{ 528 status_t ret = NO_ERROR; 529 OMX_ERRORTYPE eError; 530 531 OMX_TI_CONFIG_FOCUSDISTANCETYPE focusDist; 532 533 LOG_FUNCTION_NAME; 534 535 if ( OMX_StateInvalid == mComponentState ) 536 { 537 CAMHAL_LOGEA("OMX component is in invalid state"); 538 ret = UNKNOWN_ERROR; 539 } 540 541 if ( NO_ERROR == ret ) 542 { 543 OMX_INIT_STRUCT_PTR(&focusDist, OMX_TI_CONFIG_FOCUSDISTANCETYPE); 544 focusDist.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 545 546 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 547 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigFocusDistance, 548 &focusDist); 549 if ( OMX_ErrorNone != eError ) 550 { 551 CAMHAL_LOGEB("Error while querying focus distances 0x%x", eError); 552 ret = UNKNOWN_ERROR; 553 } 554 555 } 556 557 if ( NO_ERROR == ret ) 558 { 559 near = focusDist.nFocusDistanceNear; 560 optimal = focusDist.nFocusDistanceOptimal; 561 far = focusDist.nFocusDistanceFar; 562 } 563 564 LOG_FUNCTION_NAME_EXIT; 565 566 return ret; 567} 568 569status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_t length) 570{ 571 status_t ret = NO_ERROR; 572 uint32_t focusScale = 1000; 573 float distFinal; 574 575 LOG_FUNCTION_NAME; 576 577 if(mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity) 578 { 579 dist=0; 580 } 581 582 if ( NO_ERROR == ret ) 583 { 584 if ( 0 == dist ) 585 { 586 strncpy(buffer, CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 )); 587 } 588 else 589 { 590 distFinal = dist; 591 distFinal /= focusScale; 592 snprintf(buffer, ( length - 1 ) , "%5.3f", distFinal); 593 } 594 } 595 596 LOG_FUNCTION_NAME_EXIT; 597 598 return ret; 599} 600 601status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near, 602 OMX_U32 &optimal, 603 OMX_U32 &far, 604 CameraParameters& params) 605{ 606 status_t ret = NO_ERROR; 607 608 LOG_FUNCTION_NAME; 609 610 if ( NO_ERROR == ret ) 611 { 612 ret = encodeFocusDistance(near, mFocusDistNear, FOCUS_DIST_SIZE); 613 if ( NO_ERROR != ret ) 614 { 615 CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret); 616 } 617 } 618 619 if ( NO_ERROR == ret ) 620 { 621 ret = encodeFocusDistance(optimal, mFocusDistOptimal, FOCUS_DIST_SIZE); 622 if ( NO_ERROR != ret ) 623 { 624 CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret); 625 } 626 } 627 628 if ( NO_ERROR == ret ) 629 { 630 ret = encodeFocusDistance(far, mFocusDistFar, FOCUS_DIST_SIZE); 631 if ( NO_ERROR != ret ) 632 { 633 CAMHAL_LOGEB("Error encoding near focus distance 0x%x", ret); 634 } 635 } 636 637 if ( NO_ERROR == ret ) 638 { 639 snprintf(mFocusDistBuffer, ( FOCUS_DIST_BUFFER_SIZE - 1) ,"%s,%s,%s", mFocusDistNear, 640 mFocusDistOptimal, 641 mFocusDistFar); 642 643 params.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer); 644 } 645 646 LOG_FUNCTION_NAME_EXIT; 647 648 return ret; 649} 650 651status_t OMXCameraAdapter::setTouchFocus() 652{ 653 status_t ret = NO_ERROR; 654 OMX_ERRORTYPE eError = OMX_ErrorNone; 655 656 OMX_ALGOAREASTYPE **focusAreas; 657 OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer; 658 MemoryManager memMgr; 659 int areasSize = 0; 660 661 LOG_FUNCTION_NAME; 662 663 if ( OMX_StateInvalid == mComponentState ) 664 { 665 CAMHAL_LOGEA("OMX component is in invalid state"); 666 ret = -1; 667 } 668 669 if ( NO_ERROR == ret ) 670 { 671 672 areasSize = ((sizeof(OMX_ALGOAREASTYPE)+4095)/4096)*4096; 673 focusAreas = (OMX_ALGOAREASTYPE**) memMgr.allocateBuffer(0, 0, NULL, areasSize, 1); 674 675 OMXCameraPortParameters * mPreviewData = NULL; 676 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 677 678 if (!focusAreas) 679 { 680 CAMHAL_LOGEB("Error allocating buffer for focus areas %d", eError); 681 return -ENOMEM; 682 } 683 684 OMX_INIT_STRUCT_PTR (focusAreas[0], OMX_ALGOAREASTYPE); 685 686 focusAreas[0]->nPortIndex = OMX_ALL; 687 focusAreas[0]->nNumAreas = mFocusAreas.size(); 688 focusAreas[0]->nAlgoAreaPurpose = OMX_AlgoAreaFocus; 689 690 // If the area is the special case of (0, 0, 0, 0, 0), then 691 // the algorithm needs nNumAreas to be set to 0, 692 // in order to automatically choose the best fitting areas. 693 if ( mFocusAreas.itemAt(0)->isZeroArea() ) 694 { 695 focusAreas[0]->nNumAreas = 0; 696 } 697 698 for ( unsigned int n = 0; n < mFocusAreas.size(); n++) 699 { 700 // transform the coordinates to 3A-type coordinates 701 mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth, 702 (size_t)mPreviewData->mHeight, 703 (size_t&)focusAreas[0]->tAlgoAreas[n].nTop, 704 (size_t&)focusAreas[0]->tAlgoAreas[n].nLeft, 705 (size_t&)focusAreas[0]->tAlgoAreas[n].nWidth, 706 (size_t&)focusAreas[0]->tAlgoAreas[n].nHeight); 707 708 focusAreas[0]->tAlgoAreas[n].nLeft = 709 ( focusAreas[0]->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; 710 focusAreas[0]->tAlgoAreas[n].nTop = 711 ( focusAreas[0]->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; 712 focusAreas[0]->tAlgoAreas[n].nWidth = 713 ( focusAreas[0]->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; 714 focusAreas[0]->tAlgoAreas[n].nHeight = 715 ( focusAreas[0]->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; 716 focusAreas[0]->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight(); 717 718 CAMHAL_LOGDB("Focus area %d : top = %d left = %d width = %d height = %d prio = %d", 719 n, (int)focusAreas[0]->tAlgoAreas[n].nTop, (int)focusAreas[0]->tAlgoAreas[n].nLeft, 720 (int)focusAreas[0]->tAlgoAreas[n].nWidth, (int)focusAreas[0]->tAlgoAreas[n].nHeight, 721 (int)focusAreas[0]->tAlgoAreas[n].nPriority); 722 } 723 724 OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER); 725 726 sharedBuffer.nPortIndex = OMX_ALL; 727 sharedBuffer.nSharedBuffSize = areasSize; 728 sharedBuffer.pSharedBuff = (OMX_U8 *) focusAreas[0]; 729 730 if ( NULL == sharedBuffer.pSharedBuff ) 731 { 732 CAMHAL_LOGEA("No resources to allocate OMX shared buffer"); 733 ret = -ENOMEM; 734 goto EXIT; 735 } 736 737 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 738 (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgoAreas, &sharedBuffer); 739 740 if ( OMX_ErrorNone != eError ) 741 { 742 CAMHAL_LOGEB("Error while setting Focus Areas configuration 0x%x", eError); 743 ret = -EINVAL; 744 } 745 746 EXIT: 747 if (NULL != focusAreas) 748 { 749 memMgr.freeBuffer((void*) focusAreas); 750 focusAreas = NULL; 751 } 752 } 753 754 LOG_FUNCTION_NAME_EXIT; 755 756 return ret; 757} 758 759}; 760