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