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