OMXCameraAdapter.cpp revision d8bf3dc07ef357eb0761cfdacab458f2358907aa
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* @file OMXCameraAdapter.cpp 19* 20* This file maps the Camera Hardware Interface to OMX. 21* 22*/ 23 24#include "CameraHal.h" 25#include "OMXCameraAdapter.h" 26#include "ErrorUtils.h" 27#include "TICameraParameters.h" 28#include <signal.h> 29#include <math.h> 30 31#include <cutils/properties.h> 32#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 33static int mDebugFps = 0; 34static int mDebugFcs = 0; 35 36 37#define HERE(Msg) {CAMHAL_LOGEB("--===line %d, %s===--\n", __LINE__, Msg);} 38 39namespace android { 40 41#undef LOG_TAG 42///Maintain a separate tag for OMXCameraAdapter logs to isolate issues OMX specific 43#define LOG_TAG "CameraHAL" 44 45//frames skipped before recalculating the framerate 46#define FPS_PERIOD 30 47 48Mutex gAdapterLock; 49/*--------------------Camera Adapter Class STARTS here-----------------------------*/ 50 51status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps) 52{ 53 LOG_FUNCTION_NAME; 54 55 char value[PROPERTY_VALUE_MAX]; 56 property_get("debug.camera.showfps", value, "0"); 57 mDebugFps = atoi(value); 58 property_get("debug.camera.framecounts", value, "0"); 59 mDebugFcs = atoi(value); 60 61 TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone; 62 OMX_ERRORTYPE eError = OMX_ErrorNone; 63 status_t ret = NO_ERROR; 64 65 66 mLocalVersionParam.s.nVersionMajor = 0x1; 67 mLocalVersionParam.s.nVersionMinor = 0x1; 68 mLocalVersionParam.s.nRevision = 0x0 ; 69 mLocalVersionParam.s.nStep = 0x0; 70 71 mPending3Asettings = 0;//E3AsettingsAll; 72 mPendingCaptureSettings = 0; 73 74 if ( 0 != mInitSem.Count() ) 75 { 76 CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count()); 77 LOG_FUNCTION_NAME_EXIT; 78 return NO_INIT; 79 } 80 81 ///Update the preview and image capture port indexes 82 mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW; 83 // temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE; 84 mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE; 85 mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT; 86 //currently not supported use preview port instead 87 mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW; 88 89 eError = OMX_Init(); 90 if (eError != OMX_ErrorNone) { 91 CAMHAL_LOGEB("OMX_Init() failed, error: 0x%x", eError); 92 return ErrorUtils::omxToAndroidError(eError); 93 } 94 mOmxInitialized = true; 95 96 ///Get the handle to the OMX Component 97 eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, (OMX_PTR)this); 98 if(eError != OMX_ErrorNone) { 99 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError); 100 } 101 GOTO_EXIT_IF((eError != OMX_ErrorNone), eError); 102 103 mComponentState = OMX_StateLoaded; 104 105 CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex); 106 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 107 OMX_CommandPortDisable, 108 OMX_ALL, 109 NULL); 110 111 if(eError != OMX_ErrorNone) { 112 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError); 113 } 114 GOTO_EXIT_IF((eError != OMX_ErrorNone), eError); 115 116 // Register for port enable event 117 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 118 OMX_EventCmdComplete, 119 OMX_CommandPortEnable, 120 mCameraAdapterParameters.mPrevPortIndex, 121 mInitSem); 122 if(ret != NO_ERROR) { 123 CAMHAL_LOGEB("Error in registering for event %d", ret); 124 goto EXIT; 125 } 126 127 // Enable PREVIEW Port 128 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 129 OMX_CommandPortEnable, 130 mCameraAdapterParameters.mPrevPortIndex, 131 NULL); 132 if(eError != OMX_ErrorNone) { 133 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 134 } 135 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 136 137 // Wait for the port enable event to occur 138 ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT); 139 if ( NO_ERROR == ret ) { 140 CAMHAL_LOGDA("-Port enable event arrived"); 141 } else { 142 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 143 OMX_EventCmdComplete, 144 OMX_CommandPortEnable, 145 mCameraAdapterParameters.mPrevPortIndex, 146 NULL); 147 CAMHAL_LOGEA("Timeout for enabling preview port expired!"); 148 goto EXIT; 149 } 150 151 // Select the sensor 152 OMX_CONFIG_SENSORSELECTTYPE sensorSelect; 153 OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE); 154 sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex; 155 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect); 156 if ( OMX_ErrorNone != eError ) { 157 CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError); 158 return BAD_VALUE; 159 } else { 160 CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex); 161 } 162 163 printComponentVersion(mCameraAdapterParameters.mHandleComp); 164 165 mBracketingEnabled = false; 166 mBracketingBuffersQueuedCount = 0; 167 mBracketingRange = 1; 168 mLastBracetingBufferIdx = 0; 169 mOMXStateSwitch = false; 170 171 mCaptureSignalled = false; 172 mCaptureConfigured = false; 173 mRecording = false; 174 mWaitingForSnapshot = false; 175 mSnapshotCount = 0; 176 177 mCapMode = HIGH_QUALITY; 178 mIPP = IPP_NULL; 179 mVstabEnabled = false; 180 mVnfEnabled = false; 181 mBurstFrames = 1; 182 mCapturedFrames = 0; 183 mPictureQuality = 100; 184 mCurrentZoomIdx = 0; 185 mTargetZoomIdx = 0; 186 mPreviousZoomIndx = 0; 187 mReturnZoomStatus = false; 188 mZoomInc = 1; 189 mZoomParameterIdx = 0; 190 mExposureBracketingValidEntries = 0; 191 mSensorOverclock = false; 192 193 mDeviceOrientation = 0; 194 mCapabilities = caps; 195 mZoomUpdating = false; 196 mZoomUpdate = false; 197 198 mEXIFData.mGPSData.mAltitudeValid = false; 199 mEXIFData.mGPSData.mDatestampValid = false; 200 mEXIFData.mGPSData.mLatValid = false; 201 mEXIFData.mGPSData.mLongValid = false; 202 mEXIFData.mGPSData.mMapDatumValid = false; 203 mEXIFData.mGPSData.mProcMethodValid = false; 204 mEXIFData.mGPSData.mVersionIdValid = false; 205 mEXIFData.mGPSData.mTimeStampValid = false; 206 mEXIFData.mModelValid = false; 207 mEXIFData.mMakeValid = false; 208 209 // initialize command handling thread 210 if(mCommandHandler.get() == NULL) 211 mCommandHandler = new CommandHandler(this); 212 213 if ( NULL == mCommandHandler.get() ) 214 { 215 CAMHAL_LOGEA("Couldn't create command handler"); 216 return NO_MEMORY; 217 } 218 219 ret = mCommandHandler->run("CallbackThread", PRIORITY_URGENT_DISPLAY); 220 if ( ret != NO_ERROR ) 221 { 222 if( ret == INVALID_OPERATION){ 223 CAMHAL_LOGDA("command handler thread already runnning!!"); 224 ret = NO_ERROR; 225 } else 226 { 227 CAMHAL_LOGEA("Couldn't run command handlerthread"); 228 return ret; 229 } 230 } 231 232 // initialize omx callback handling thread 233 if(mOMXCallbackHandler.get() == NULL) 234 mOMXCallbackHandler = new OMXCallbackHandler(this); 235 236 if ( NULL == mOMXCallbackHandler.get() ) 237 { 238 CAMHAL_LOGEA("Couldn't create omx callback handler"); 239 return NO_MEMORY; 240 } 241 242 ret = mOMXCallbackHandler->run("OMXCallbackThread", PRIORITY_URGENT_DISPLAY); 243 if ( ret != NO_ERROR ) 244 { 245 if( ret == INVALID_OPERATION){ 246 CAMHAL_LOGDA("omx callback handler thread already runnning!!"); 247 ret = NO_ERROR; 248 }else 249 { 250 CAMHAL_LOGEA("Couldn't run omx callback handler thread"); 251 return ret; 252 } 253 } 254 255 //Remove any unhandled events 256 if (!mEventSignalQ.isEmpty()) { 257 for (unsigned int i = 0 ;i < mEventSignalQ.size(); i++ ) { 258 TIUTILS::Message *msg = mEventSignalQ.itemAt(i); 259 //remove from queue and free msg 260 if ( NULL != msg ) { 261 free(msg); 262 } 263 } 264 mEventSignalQ.clear(); 265 } 266 267 OMX_INIT_STRUCT_PTR (&mRegionPriority, OMX_TI_CONFIG_3A_REGION_PRIORITY); 268 OMX_INIT_STRUCT_PTR (&mFacePriority, OMX_TI_CONFIG_3A_FACE_PRIORITY); 269 mRegionPriority.nPortIndex = OMX_ALL; 270 mFacePriority.nPortIndex = OMX_ALL; 271 272 //Setting this flag will that the first setParameter call will apply all 3A settings 273 //and will not conditionally apply based on current values. 274 mFirstTimeInit = true; 275 276 memset(mExposureBracketingValues, 0, EXP_BRACKET_RANGE*sizeof(int)); 277 mMeasurementEnabled = false; 278 mFaceDetectionRunning = false; 279 mFaceDetectionPaused = false; 280 mFDSwitchAlgoPriority = false; 281 282 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters)); 283 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters)); 284 285 //Initialize 3A defaults 286 ret = init3AParams(mParameters3A); 287 if ( NO_ERROR != ret ) { 288 CAMHAL_LOGEA("Couldn't init 3A params!"); 289 goto EXIT; 290 } 291 292 LOG_FUNCTION_NAME_EXIT; 293 return ErrorUtils::omxToAndroidError(eError); 294 295 EXIT: 296 297 CAMHAL_LOGDB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 298 performCleanupAfterError(); 299 LOG_FUNCTION_NAME_EXIT; 300 return ErrorUtils::omxToAndroidError(eError); 301} 302 303void OMXCameraAdapter::performCleanupAfterError() 304{ 305 if(mCameraAdapterParameters.mHandleComp) 306 { 307 ///Free the OMX component handle in case of error 308 OMX_FreeHandle(mCameraAdapterParameters.mHandleComp); 309 mCameraAdapterParameters.mHandleComp = NULL; 310 } 311 312 ///De-init the OMX 313 OMX_Deinit(); 314 mComponentState = OMX_StateInvalid; 315} 316 317OMXCameraAdapter::OMXCameraPortParameters *OMXCameraAdapter::getPortParams(CameraFrame::FrameType frameType) 318{ 319 OMXCameraAdapter::OMXCameraPortParameters *ret = NULL; 320 321 switch ( frameType ) 322 { 323 case CameraFrame::IMAGE_FRAME: 324 case CameraFrame::RAW_FRAME: 325 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 326 break; 327 case CameraFrame::PREVIEW_FRAME_SYNC: 328 case CameraFrame::SNAPSHOT_FRAME: 329 case CameraFrame::VIDEO_FRAME_SYNC: 330 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 331 break; 332 case CameraFrame::FRAME_DATA_SYNC: 333 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 334 break; 335 default: 336 break; 337 }; 338 339 return ret; 340} 341 342status_t OMXCameraAdapter::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType) 343{ 344 status_t ret = NO_ERROR; 345 OMXCameraPortParameters *port = NULL; 346 OMX_ERRORTYPE eError = OMX_ErrorNone; 347 BaseCameraAdapter::AdapterState state; 348 BaseCameraAdapter::getState(state); 349 350 if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE ) 351 { 352 return NO_INIT; 353 } 354 355 if ( NULL == frameBuf ) 356 { 357 return -EINVAL; 358 } 359 360 if ( (NO_ERROR == ret) && 361 ((CameraFrame::IMAGE_FRAME == frameType) || (CameraFrame::RAW_FRAME == frameType)) && 362 (1 > mCapturedFrames) && 363 (!mBracketingEnabled)) { 364 // Signal end of image capture 365 if ( NULL != mEndImageCaptureCallback) { 366 mEndImageCaptureCallback(mEndCaptureData); 367 } 368 return NO_ERROR; 369 } 370 371 if ( NO_ERROR == ret ) 372 { 373 port = getPortParams(frameType); 374 if ( NULL == port ) 375 { 376 CAMHAL_LOGEB("Invalid frameType 0x%x", frameType); 377 ret = -EINVAL; 378 } 379 } 380 381 if ( NO_ERROR == ret ) 382 { 383 384 for ( int i = 0 ; i < port->mNumBufs ; i++) 385 { 386 if ( port->mBufferHeader[i]->pBuffer == frameBuf ) 387 { 388 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, port->mBufferHeader[i]); 389 if ( eError != OMX_ErrorNone ) 390 { 391 CAMHAL_LOGEB("OMX_FillThisBuffer 0x%x", eError); 392 goto EXIT; 393 } 394 mFramesWithDucati++; 395 break; 396 } 397 } 398 399 } 400 401 LOG_FUNCTION_NAME_EXIT; 402 return ret; 403 404EXIT: 405 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 406 performCleanupAfterError(); 407 //Since fillthisbuffer is called asynchronously, make sure to signal error to the app 408 mErrorNotifier->errorNotify(CAMERA_ERROR_HARD); 409 LOG_FUNCTION_NAME_EXIT; 410 return (ret | ErrorUtils::omxToAndroidError(eError)); 411} 412 413status_t OMXCameraAdapter::setParameters(const CameraParameters ¶ms) 414{ 415 LOG_FUNCTION_NAME; 416 417 const char * str = NULL; 418 int mode = 0; 419 status_t ret = NO_ERROR; 420 bool updateImagePortParams = false; 421 int minFramerate, maxFramerate, frameRate; 422 const char *valstr = NULL; 423 const char *oldstr = NULL; 424 int w, h; 425 OMX_COLOR_FORMATTYPE pixFormat; 426 BaseCameraAdapter::AdapterState state; 427 BaseCameraAdapter::getState(state); 428 429 ///@todo Include more camera parameters 430 if ( (valstr = params.getPreviewFormat()) != NULL ) 431 { 432 if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) 433 { 434 CAMHAL_LOGDA("CbYCrY format selected"); 435 pixFormat = OMX_COLOR_FormatCbYCrY; 436 } 437 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || 438 strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0) 439 { 440 CAMHAL_LOGDA("YUV420SP format selected"); 441 pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; 442 } 443 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) 444 { 445 CAMHAL_LOGDA("RGB565 format selected"); 446 pixFormat = OMX_COLOR_Format16bitRGB565; 447 } 448 else 449 { 450 CAMHAL_LOGDA("Invalid format, CbYCrY format selected as default"); 451 pixFormat = OMX_COLOR_FormatCbYCrY; 452 } 453 } 454 else 455 { 456 CAMHAL_LOGEA("Preview format is NULL, defaulting to CbYCrY"); 457 pixFormat = OMX_COLOR_FormatCbYCrY; 458 } 459 460 OMXCameraPortParameters *cap; 461 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 462 463 params.getPreviewSize(&w, &h); 464 frameRate = params.getPreviewFrameRate(); 465 minFramerate = params.getInt(TICameraParameters::KEY_MINFRAMERATE); 466 maxFramerate = params.getInt(TICameraParameters::KEY_MAXFRAMERATE); 467 if ( ( 0 < minFramerate ) && 468 ( 0 < maxFramerate ) ) 469 { 470 if ( minFramerate > maxFramerate ) 471 { 472 CAMHAL_LOGEA(" Min FPS set higher than MAX. So setting MIN and MAX to the higher value"); 473 maxFramerate = minFramerate; 474 } 475 476 if ( 0 >= frameRate ) 477 { 478 frameRate = maxFramerate; 479 } 480 481 if( ( cap->mMinFrameRate != minFramerate ) || 482 ( cap->mMaxFrameRate != maxFramerate ) ) 483 { 484 cap->mMinFrameRate = minFramerate; 485 cap->mMaxFrameRate = maxFramerate; 486 setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate); 487 } 488 } 489 490 // TODO(XXX): Limiting 1080p to (24,24) or (15,15) for now. Need to remove later. 491 if ((w >= 1920) && (h >= 1080)) { 492 cap->mMaxFrameRate = cap->mMinFrameRate; 493 setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate); 494 } 495 496 if ( 0 < frameRate ) 497 { 498 cap->mColorFormat = pixFormat; 499 cap->mWidth = w; 500 cap->mHeight = h; 501 cap->mFrameRate = frameRate; 502 503 CAMHAL_LOGVB("Prev: cap.mColorFormat = %d", (int)cap->mColorFormat); 504 CAMHAL_LOGVB("Prev: cap.mWidth = %d", (int)cap->mWidth); 505 CAMHAL_LOGVB("Prev: cap.mHeight = %d", (int)cap->mHeight); 506 CAMHAL_LOGVB("Prev: cap.mFrameRate = %d", (int)cap->mFrameRate); 507 508 //TODO: Add an additional parameter for video resolution 509 //use preview resolution for now 510 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 511 cap->mColorFormat = pixFormat; 512 cap->mWidth = w; 513 cap->mHeight = h; 514 cap->mFrameRate = frameRate; 515 516 CAMHAL_LOGVB("Video: cap.mColorFormat = %d", (int)cap->mColorFormat); 517 CAMHAL_LOGVB("Video: cap.mWidth = %d", (int)cap->mWidth); 518 CAMHAL_LOGVB("Video: cap.mHeight = %d", (int)cap->mHeight); 519 CAMHAL_LOGVB("Video: cap.mFrameRate = %d", (int)cap->mFrameRate); 520 521 ///mStride is set from setBufs() while passing the APIs 522 cap->mStride = 4096; 523 cap->mBufSize = cap->mStride * cap->mHeight; 524 } 525 526 if ( ( cap->mWidth >= 1920 ) && 527 ( cap->mHeight >= 1080 ) && 528 ( cap->mFrameRate >= FRAME_RATE_FULL_HD ) && 529 ( !mSensorOverclock ) ) 530 { 531 mOMXStateSwitch = true; 532 } 533 else if ( ( ( cap->mWidth < 1920 ) || 534 ( cap->mHeight < 1080 ) || 535 ( cap->mFrameRate < FRAME_RATE_FULL_HD ) ) && 536 ( mSensorOverclock ) ) 537 { 538 mOMXStateSwitch = true; 539 } 540 541#ifdef OMAP_ENHANCEMENT 542 543 if ( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL ) 544 { 545 if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_ENABLE) == 0) 546 { 547 mMeasurementEnabled = true; 548 } 549 else if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_DISABLE) == 0) 550 { 551 mMeasurementEnabled = false; 552 } 553 else 554 { 555 mMeasurementEnabled = false; 556 } 557 } 558 else 559 { 560 //Disable measurement data by default 561 mMeasurementEnabled = false; 562 } 563 564#endif 565 566 ret |= setParametersCapture(params, state); 567 568 ret |= setParameters3A(params, state); 569 570 ret |= setParametersAlgo(params, state); 571 572 ret |= setParametersFocus(params, state); 573 574 ret |= setParametersFD(params, state); 575 576 ret |= setParametersZoom(params, state); 577 578 ret |= setParametersEXIF(params, state); 579 580 mParams = params; 581 mFirstTimeInit = false; 582 583 LOG_FUNCTION_NAME_EXIT; 584 return ret; 585} 586 587void saveFile(unsigned char *buff, int width, int height, int format) { 588 static int counter = 1; 589 int fd = -1; 590 char fn[256]; 591 592 LOG_FUNCTION_NAME; 593 594 fn[0] = 0; 595 sprintf(fn, "/preview%03d.yuv", counter); 596 fd = open(fn, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777); 597 if(fd < 0) { 598 ALOGE("Unable to open file %s: %s", fn, strerror(fd)); 599 return; 600 } 601 602 CAMHAL_LOGVB("Copying from 0x%x, size=%d x %d", buff, width, height); 603 604 //method currently supports only nv12 dumping 605 int stride = width; 606 uint8_t *bf = (uint8_t*) buff; 607 for(int i=0;i<height;i++) 608 { 609 write(fd, bf, width); 610 bf += 4096; 611 } 612 613 for(int i=0;i<height/2;i++) 614 { 615 write(fd, bf, stride); 616 bf += 4096; 617 } 618 619 close(fd); 620 621 622 counter++; 623 624 LOG_FUNCTION_NAME_EXIT; 625} 626 627void OMXCameraAdapter::getParameters(CameraParameters& params) 628{ 629 status_t ret = NO_ERROR; 630 OMX_CONFIG_EXPOSUREVALUETYPE exp; 631 OMX_ERRORTYPE eError = OMX_ErrorNone; 632 BaseCameraAdapter::AdapterState state; 633 BaseCameraAdapter::getState(state); 634 const char *valstr = NULL; 635 LOG_FUNCTION_NAME; 636 637 if( mParameters3A.SceneMode != OMX_Manual ) { 638 const char *valstr_supported = NULL; 639 640 // if preview is not started...we still need to feedback the proper params 641 // look up the settings in the LUT 642 if (((state & PREVIEW_ACTIVE) == 0) && mCapabilities) { 643 const SceneModesEntry* entry = NULL; 644 entry = getSceneModeEntry(mCapabilities->get(CameraProperties::CAMERA_NAME), 645 (OMX_SCENEMODETYPE) mParameters3A.SceneMode); 646 if(entry) { 647 mParameters3A.Focus = entry->focus; 648 mParameters3A.FlashMode = entry->flash; 649 mParameters3A.WhiteBallance = entry->wb; 650 } 651 } 652 653 valstr = getLUTvalue_OMXtoHAL(mParameters3A.WhiteBallance, WBalLUT); 654 valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE); 655 if (valstr && valstr_supported && strstr(valstr_supported, valstr)) 656 params.set(CameraParameters::KEY_WHITE_BALANCE , valstr); 657 658 valstr = getLUTvalue_OMXtoHAL(mParameters3A.FlashMode, FlashLUT); 659 valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES); 660 if (valstr && valstr_supported && strstr(valstr_supported, valstr)) 661 params.set(CameraParameters::KEY_FLASH_MODE, valstr); 662 663 if ((mParameters3A.Focus == OMX_IMAGE_FocusControlAuto) && 664 (mCapMode != OMXCameraAdapter::VIDEO_MODE)) { 665 valstr = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE; 666 } else { 667 valstr = getLUTvalue_OMXtoHAL(mParameters3A.Focus, FocusLUT); 668 } 669 valstr_supported = mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES); 670 if (valstr && valstr_supported && strstr(valstr_supported, valstr)) 671 params.set(CameraParameters::KEY_FOCUS_MODE, valstr); 672 } 673 674 //Query focus distances only when focus is running 675 if ( ( AF_ACTIVE & state ) || 676 ( NULL == mParameters.get(CameraParameters::KEY_FOCUS_DISTANCES) ) ) 677 { 678 updateFocusDistances(params); 679 } 680 else 681 { 682 params.set(CameraParameters::KEY_FOCUS_DISTANCES, 683 mParameters.get(CameraParameters::KEY_FOCUS_DISTANCES)); 684 } 685 686#ifdef OMAP_ENHANCEMENT 687 688 OMX_INIT_STRUCT_PTR (&exp, OMX_CONFIG_EXPOSUREVALUETYPE); 689 exp.nPortIndex = OMX_ALL; 690 691 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 692 OMX_IndexConfigCommonExposureValue, 693 &exp); 694 if ( OMX_ErrorNone == eError ) 695 { 696 params.set(TICameraParameters::KEY_CURRENT_ISO, exp.nSensitivity); 697 } 698 else 699 { 700 CAMHAL_LOGEB("OMX error 0x%x, while retrieving current ISO value", eError); 701 } 702 703#endif 704 705 { 706 Mutex::Autolock lock(mZoomLock); 707 //Immediate zoom should not be avaialable while smooth zoom is running 708 if ( ZOOM_ACTIVE & state ) 709 { 710 if ( mZoomParameterIdx != mCurrentZoomIdx ) 711 { 712 mZoomParameterIdx += mZoomInc; 713 } 714 params.set( CameraParameters::KEY_ZOOM, mZoomParameterIdx); 715 if ( ( mCurrentZoomIdx == mTargetZoomIdx ) && 716 ( mZoomParameterIdx == mCurrentZoomIdx ) ) 717 { 718 719 if ( NO_ERROR == ret ) 720 { 721 722 ret = BaseCameraAdapter::setState(CAMERA_STOP_SMOOTH_ZOOM); 723 724 if ( NO_ERROR == ret ) 725 { 726 ret = BaseCameraAdapter::commitState(); 727 } 728 else 729 { 730 ret |= BaseCameraAdapter::rollbackState(); 731 } 732 733 } 734 735 } 736 737 CAMHAL_LOGDB("CameraParameters Zoom = %d", mCurrentZoomIdx); 738 } 739 else 740 { 741 params.set( CameraParameters::KEY_ZOOM, mCurrentZoomIdx); 742 } 743 } 744 745 //Populate current lock status 746 if( (valstr = mParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL ) 747 { 748 CAMHAL_LOGDB("Auto Exposure Lock get %s", mParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)); 749 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr); 750 } 751 752 if( (valstr = mParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL ) 753 { 754 CAMHAL_LOGDB("Auto WhiteBalance Lock get %s", mParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)); 755 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr); 756 } 757 758 LOG_FUNCTION_NAME_EXIT; 759} 760 761status_t OMXCameraAdapter::setFormat(OMX_U32 port, OMXCameraPortParameters &portParams) 762{ 763 size_t bufferCount; 764 765 LOG_FUNCTION_NAME; 766 767 OMX_ERRORTYPE eError = OMX_ErrorNone; 768 OMX_PARAM_PORTDEFINITIONTYPE portCheck; 769 770 OMX_INIT_STRUCT_PTR (&portCheck, OMX_PARAM_PORTDEFINITIONTYPE); 771 772 portCheck.nPortIndex = port; 773 774 eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp, 775 OMX_IndexParamPortDefinition, &portCheck); 776 if(eError!=OMX_ErrorNone) 777 { 778 CAMHAL_LOGEB("OMX_GetParameter - %x", eError); 779 } 780 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 781 782 if ( OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW == port ) 783 { 784 portCheck.format.video.nFrameWidth = portParams.mWidth; 785 portCheck.format.video.nFrameHeight = portParams.mHeight; 786 portCheck.format.video.eColorFormat = portParams.mColorFormat; 787 portCheck.format.video.nStride = portParams.mStride; 788 if( ( portCheck.format.video.nFrameWidth >= 1920 ) && 789 ( portCheck.format.video.nFrameHeight >= 1080 ) && 790 ( portParams.mFrameRate >= FRAME_RATE_FULL_HD ) ) 791 { 792 setSensorOverclock(true); 793 } 794 else 795 { 796 setSensorOverclock(false); 797 } 798 799 portCheck.format.video.xFramerate = portParams.mFrameRate<<16; 800 portCheck.nBufferSize = portParams.mStride * portParams.mHeight; 801 portCheck.nBufferCountActual = portParams.mNumBufs; 802 mFocusThreshold = FOCUS_THRESHOLD * portParams.mFrameRate; 803 } 804 else if ( OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port ) 805 { 806 portCheck.format.image.nFrameWidth = portParams.mWidth; 807 portCheck.format.image.nFrameHeight = portParams.mHeight; 808 if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingNone ) 809 { 810 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 811 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG; 812 } 813 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingJPS ) 814 { 815 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 816 portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingJPS; 817 } 818 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingMPO ) 819 { 820 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 821 portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingMPO; 822 } 823 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingRAWJPEG ) 824 { 825 //TODO: OMX_IMAGE_CodingJPEG should be changed to OMX_IMAGE_CodingRAWJPEG when 826 // RAW format is supported 827 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 828 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG; 829 } 830 else if ( OMX_COLOR_FormatUnused == portParams.mColorFormat && mCodingMode == CodingRAWMPO ) 831 { 832 //TODO: OMX_IMAGE_CodingJPEG should be changed to OMX_IMAGE_CodingRAWMPO when 833 // RAW format is supported 834 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 835 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG; 836 } 837 else 838 { 839 portCheck.format.image.eColorFormat = portParams.mColorFormat; 840 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; 841 } 842 843 //Stride for 1D tiler buffer is zero 844 portCheck.format.image.nStride = 0; 845 portCheck.nBufferSize = portParams.mStride * portParams.mWidth * portParams.mHeight; 846 portCheck.nBufferCountActual = portParams.mNumBufs; 847 } 848 else 849 { 850 CAMHAL_LOGEB("Unsupported port index 0x%x", (unsigned int)port); 851 } 852 853 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 854 OMX_IndexParamPortDefinition, &portCheck); 855 if(eError!=OMX_ErrorNone) 856 { 857 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 858 } 859 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 860 861 /* check if parameters are set correctly by calling GetParameter() */ 862 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, 863 OMX_IndexParamPortDefinition, &portCheck); 864 if(eError!=OMX_ErrorNone) 865 { 866 CAMHAL_LOGEB("OMX_GetParameter - %x", eError); 867 } 868 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 869 870 portParams.mBufSize = portCheck.nBufferSize; 871 portParams.mStride = portCheck.format.image.nStride; 872 873 if ( OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port ) 874 { 875 CAMHAL_LOGDB("\n *** IMG Width = %ld", portCheck.format.image.nFrameWidth); 876 CAMHAL_LOGDB("\n ***IMG Height = %ld", portCheck.format.image.nFrameHeight); 877 878 CAMHAL_LOGDB("\n ***IMG IMG FMT = %x", portCheck.format.image.eColorFormat); 879 CAMHAL_LOGDB("\n ***IMG portCheck.nBufferSize = %ld\n",portCheck.nBufferSize); 880 CAMHAL_LOGDB("\n ***IMG portCheck.nBufferCountMin = %ld\n", 881 portCheck.nBufferCountMin); 882 CAMHAL_LOGDB("\n ***IMG portCheck.nBufferCountActual = %ld\n", 883 portCheck.nBufferCountActual); 884 CAMHAL_LOGDB("\n ***IMG portCheck.format.image.nStride = %ld\n", 885 portCheck.format.image.nStride); 886 } 887 else 888 { 889 CAMHAL_LOGDB("\n *** PRV Width = %ld", portCheck.format.video.nFrameWidth); 890 CAMHAL_LOGDB("\n ***PRV Height = %ld", portCheck.format.video.nFrameHeight); 891 892 CAMHAL_LOGDB("\n ***PRV IMG FMT = %x", portCheck.format.video.eColorFormat); 893 CAMHAL_LOGDB("\n ***PRV portCheck.nBufferSize = %ld\n",portCheck.nBufferSize); 894 CAMHAL_LOGDB("\n ***PRV portCheck.nBufferCountMin = %ld\n", 895 portCheck.nBufferCountMin); 896 CAMHAL_LOGDB("\n ***PRV portCheck.nBufferCountActual = %ld\n", 897 portCheck.nBufferCountActual); 898 CAMHAL_LOGDB("\n ***PRV portCheck.format.video.nStride = %ld\n", 899 portCheck.format.video.nStride); 900 } 901 902 LOG_FUNCTION_NAME_EXIT; 903 904 return ErrorUtils::omxToAndroidError(eError); 905 906 EXIT: 907 908 CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError); 909 910 LOG_FUNCTION_NAME_EXIT; 911 912 return ErrorUtils::omxToAndroidError(eError); 913} 914 915status_t OMXCameraAdapter::flushBuffers() 916{ 917 status_t ret = NO_ERROR; 918 OMX_ERRORTYPE eError = OMX_ErrorNone; 919 TIMM_OSAL_ERRORTYPE err; 920 TIMM_OSAL_U32 uRequestedEvents = OMXCameraAdapter::CAMERA_PORT_FLUSH; 921 TIMM_OSAL_U32 pRetrievedEvents; 922 923 if ( 0 != mFlushSem.Count() ) 924 { 925 CAMHAL_LOGEB("Error mFlushSem semaphore count %d", mFlushSem.Count()); 926 LOG_FUNCTION_NAME_EXIT; 927 return NO_INIT; 928 } 929 930 LOG_FUNCTION_NAME; 931 932 OMXCameraPortParameters * mPreviewData = NULL; 933 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 934 935 ///Register for the FLUSH event 936 ///This method just inserts a message in Event Q, which is checked in the callback 937 ///The sempahore passed is signalled by the callback 938 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 939 OMX_EventCmdComplete, 940 OMX_CommandFlush, 941 OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW, 942 mFlushSem); 943 if(ret!=NO_ERROR) 944 { 945 CAMHAL_LOGEB("Error in registering for event %d", ret); 946 goto EXIT; 947 } 948 949 ///Send FLUSH command to preview port 950 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp, 951 OMX_CommandFlush, 952 mCameraAdapterParameters.mPrevPortIndex, 953 NULL); 954 955 if(eError!=OMX_ErrorNone) 956 { 957 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandFlush)-0x%x", eError); 958 } 959 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 960 961 CAMHAL_LOGDA("Waiting for flush event"); 962 963 ///Wait for the FLUSH event to occur 964 ret = mFlushSem.WaitTimeout(OMX_CMD_TIMEOUT); 965 966 //If somethiing bad happened while we wait 967 if (mComponentState == OMX_StateInvalid) 968 { 969 CAMHAL_LOGEA("Invalid State after Flush Exitting!!!"); 970 goto EXIT; 971 } 972 973 if ( NO_ERROR == ret ) 974 { 975 CAMHAL_LOGDA("Flush event received"); 976 } 977 else 978 { 979 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 980 OMX_EventCmdComplete, 981 OMX_CommandFlush, 982 OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW, 983 NULL); 984 CAMHAL_LOGDA("Flush event timeout expired"); 985 goto EXIT; 986 } 987 988 LOG_FUNCTION_NAME_EXIT; 989 990 return (ret | ErrorUtils::omxToAndroidError(eError)); 991 992 EXIT: 993 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 994 performCleanupAfterError(); 995 LOG_FUNCTION_NAME_EXIT; 996 return (ret | ErrorUtils::omxToAndroidError(eError)); 997} 998 999///API to give the buffers to Adapter 1000status_t OMXCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable) 1001{ 1002 OMX_ERRORTYPE eError = OMX_ErrorNone; 1003 status_t ret = NO_ERROR; 1004 1005 LOG_FUNCTION_NAME; 1006 1007 switch(mode) 1008 { 1009 case CAMERA_PREVIEW: 1010 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs = num; 1011 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable; 1012 ret = UseBuffersPreview(bufArr, num); 1013 break; 1014 1015 case CAMERA_IMAGE_CAPTURE: 1016 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mNumBufs = num; 1017 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mMaxQueueable = queueable; 1018 ret = UseBuffersCapture(bufArr, num); 1019 break; 1020 1021 case CAMERA_VIDEO: 1022 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs = num; 1023 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable; 1024 ret = UseBuffersPreview(bufArr, num); 1025 break; 1026 1027 case CAMERA_MEASUREMENT: 1028 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mNumBufs = num; 1029 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mMaxQueueable = queueable; 1030 ret = UseBuffersPreviewData(bufArr, num); 1031 break; 1032 1033 } 1034 1035 LOG_FUNCTION_NAME_EXIT; 1036 1037 return ret; 1038} 1039 1040status_t OMXCameraAdapter::UseBuffersPreviewData(void* bufArr, int num) 1041{ 1042 status_t ret = NO_ERROR; 1043 OMX_ERRORTYPE eError = OMX_ErrorNone; 1044 OMXCameraPortParameters * measurementData = NULL; 1045 uint32_t *buffers; 1046 Mutex::Autolock lock( mPreviewDataBufferLock); 1047 1048 LOG_FUNCTION_NAME; 1049 1050 if ( mComponentState != OMX_StateLoaded ) 1051 { 1052 CAMHAL_LOGEA("Calling UseBuffersPreviewData() when not in LOADED state"); 1053 return BAD_VALUE; 1054 } 1055 1056 if ( NULL == bufArr ) 1057 { 1058 CAMHAL_LOGEA("NULL pointer passed for buffArr"); 1059 return BAD_VALUE; 1060 } 1061 1062 if ( 0 != mUsePreviewDataSem.Count() ) 1063 { 1064 CAMHAL_LOGEB("Error mUsePreviewDataSem semaphore count %d", mUsePreviewDataSem.Count()); 1065 LOG_FUNCTION_NAME_EXIT; 1066 return NO_INIT; 1067 } 1068 1069 if ( NO_ERROR == ret ) 1070 { 1071 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1072 measurementData->mNumBufs = num ; 1073 buffers= (uint32_t*) bufArr; 1074 } 1075 1076 if ( NO_ERROR == ret ) 1077 { 1078 ///Register for port enable event on measurement port 1079 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1080 OMX_EventCmdComplete, 1081 OMX_CommandPortEnable, 1082 mCameraAdapterParameters.mMeasurementPortIndex, 1083 mUsePreviewDataSem); 1084 1085 if ( ret == NO_ERROR ) 1086 { 1087 CAMHAL_LOGDB("Registering for event %d", ret); 1088 } 1089 else 1090 { 1091 CAMHAL_LOGEB("Error in registering for event %d", ret); 1092 goto EXIT; 1093 } 1094 } 1095 1096 if ( NO_ERROR == ret ) 1097 { 1098 ///Enable MEASUREMENT Port 1099 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1100 OMX_CommandPortEnable, 1101 mCameraAdapterParameters.mMeasurementPortIndex, 1102 NULL); 1103 1104 if ( eError == OMX_ErrorNone ) 1105 { 1106 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 1107 } 1108 else 1109 { 1110 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 1111 goto EXIT; 1112 } 1113 } 1114 1115 if ( NO_ERROR == ret ) 1116 { 1117 ret = mUsePreviewDataSem.WaitTimeout(OMX_CMD_TIMEOUT); 1118 1119 //If somethiing bad happened while we wait 1120 if (mComponentState == OMX_StateInvalid) 1121 { 1122 CAMHAL_LOGEA("Invalid State after measurement port enable Exitting!!!"); 1123 goto EXIT; 1124 } 1125 1126 if ( NO_ERROR == ret ) 1127 { 1128 CAMHAL_LOGDA("Port enable event arrived on measurement port"); 1129 } 1130 else 1131 { 1132 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1133 OMX_EventCmdComplete, 1134 OMX_CommandPortEnable, 1135 mCameraAdapterParameters.mMeasurementPortIndex, 1136 NULL); 1137 CAMHAL_LOGEA("Timeout expoired during port enable on measurement port"); 1138 goto EXIT; 1139 } 1140 1141 CAMHAL_LOGDA("Port enable event arrived on measurement port"); 1142 } 1143 1144 LOG_FUNCTION_NAME_EXIT; 1145 1146 return ret; 1147EXIT: 1148 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1149 performCleanupAfterError(); 1150 LOG_FUNCTION_NAME_EXIT; 1151 return (ret | ErrorUtils::omxToAndroidError(eError)); 1152} 1153 1154status_t OMXCameraAdapter::switchToExecuting() 1155{ 1156 status_t ret = NO_ERROR; 1157 TIUTILS::Message msg; 1158 1159 LOG_FUNCTION_NAME; 1160 1161 mStateSwitchLock.lock(); 1162 msg.command = CommandHandler::CAMERA_SWITCH_TO_EXECUTING; 1163 msg.arg1 = mErrorNotifier; 1164 ret = mCommandHandler->put(&msg); 1165 1166 LOG_FUNCTION_NAME; 1167 1168 return ret; 1169} 1170 1171status_t OMXCameraAdapter::doSwitchToExecuting() 1172{ 1173 status_t ret = NO_ERROR; 1174 OMX_ERRORTYPE eError = OMX_ErrorNone; 1175 LOG_FUNCTION_NAME; 1176 1177 if ( (mComponentState == OMX_StateExecuting) || (mComponentState == OMX_StateInvalid) ){ 1178 CAMHAL_LOGDA("Already in OMX_Executing state or OMX_StateInvalid state"); 1179 mStateSwitchLock.unlock(); 1180 return NO_ERROR; 1181 } 1182 1183 if ( 0 != mSwitchToExecSem.Count() ){ 1184 CAMHAL_LOGEB("Error mSwitchToExecSem semaphore count %d", mSwitchToExecSem.Count()); 1185 goto EXIT; 1186 } 1187 1188 ///Register for Preview port DISABLE event 1189 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1190 OMX_EventCmdComplete, 1191 OMX_CommandPortDisable, 1192 mCameraAdapterParameters.mPrevPortIndex, 1193 mSwitchToExecSem); 1194 if ( NO_ERROR != ret ){ 1195 CAMHAL_LOGEB("Error in registering Port Disable for event %d", ret); 1196 goto EXIT; 1197 } 1198 ///Disable Preview Port 1199 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1200 OMX_CommandPortDisable, 1201 mCameraAdapterParameters.mPrevPortIndex, 1202 NULL); 1203 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT); 1204 if (ret != NO_ERROR){ 1205 CAMHAL_LOGEB("Timeout PREVIEW PORT DISABLE %d", ret); 1206 } 1207 1208 CAMHAL_LOGVB("PREV PORT DISABLED %d", ret); 1209 1210 ///Register for IDLE state switch event 1211 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1212 OMX_EventCmdComplete, 1213 OMX_CommandStateSet, 1214 OMX_StateIdle, 1215 mSwitchToExecSem); 1216 if(ret!=NO_ERROR) 1217 { 1218 CAMHAL_LOGEB("Error in IDLE STATE SWITCH %d", ret); 1219 goto EXIT; 1220 } 1221 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp , 1222 OMX_CommandStateSet, 1223 OMX_StateIdle, 1224 NULL); 1225 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1226 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT); 1227 if (ret != NO_ERROR){ 1228 CAMHAL_LOGEB("Timeout IDLE STATE SWITCH %d", ret); 1229 goto EXIT; 1230 } 1231 mComponentState = OMX_StateIdle; 1232 CAMHAL_LOGVB("OMX_SendCommand(OMX_StateIdle) 0x%x", eError); 1233 1234 ///Register for EXECUTING state switch event 1235 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1236 OMX_EventCmdComplete, 1237 OMX_CommandStateSet, 1238 OMX_StateExecuting, 1239 mSwitchToExecSem); 1240 if(ret!=NO_ERROR) 1241 { 1242 CAMHAL_LOGEB("Error in EXECUTING STATE SWITCH %d", ret); 1243 goto EXIT; 1244 } 1245 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp , 1246 OMX_CommandStateSet, 1247 OMX_StateExecuting, 1248 NULL); 1249 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1250 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT); 1251 if (ret != NO_ERROR){ 1252 CAMHAL_LOGEB("Timeout EXEC STATE SWITCH %d", ret); 1253 goto EXIT; 1254 } 1255 mComponentState = OMX_StateExecuting; 1256 CAMHAL_LOGVB("OMX_SendCommand(OMX_StateExecuting) 0x%x", eError); 1257 1258 mStateSwitchLock.unlock(); 1259 1260 LOG_FUNCTION_NAME_EXIT; 1261 return ret; 1262 1263 EXIT: 1264 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1265 performCleanupAfterError(); 1266 mStateSwitchLock.unlock(); 1267 LOG_FUNCTION_NAME_EXIT; 1268 return (ret | ErrorUtils::omxToAndroidError(eError)); 1269} 1270 1271status_t OMXCameraAdapter::switchToLoaded() 1272{ 1273 status_t ret = NO_ERROR; 1274 OMX_ERRORTYPE eError = OMX_ErrorNone; 1275 1276 LOG_FUNCTION_NAME; 1277 1278 Mutex::Autolock lock(mStateSwitchLock); 1279 1280 if ( mComponentState == OMX_StateLoaded || mComponentState == OMX_StateInvalid) 1281 { 1282 CAMHAL_LOGDA("Already in OMX_Loaded state or OMX_StateInvalid state"); 1283 return NO_ERROR; 1284 } 1285 1286 if ( 0 != mSwitchToLoadedSem.Count() ) 1287 { 1288 CAMHAL_LOGEB("Error mSwitchToLoadedSem semaphore count %d", mSwitchToLoadedSem.Count()); 1289 goto EXIT; 1290 } 1291 1292 ///Register for EXECUTING state transition. 1293 ///This method just inserts a message in Event Q, which is checked in the callback 1294 ///The sempahore passed is signalled by the callback 1295 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1296 OMX_EventCmdComplete, 1297 OMX_CommandStateSet, 1298 OMX_StateIdle, 1299 mSwitchToLoadedSem); 1300 1301 if(ret!=NO_ERROR) 1302 { 1303 CAMHAL_LOGEB("Error in registering for event %d", ret); 1304 goto EXIT; 1305 } 1306 1307 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp, 1308 OMX_CommandStateSet, 1309 OMX_StateIdle, 1310 NULL); 1311 1312 if(eError!=OMX_ErrorNone) 1313 { 1314 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateIdle) - %x", eError); 1315 } 1316 1317 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1318 1319 ///Wait for the EXECUTING ->IDLE transition to arrive 1320 1321 CAMHAL_LOGDA("EXECUTING->IDLE state changed"); 1322 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT); 1323 1324 //If somethiing bad happened while we wait 1325 if (mComponentState == OMX_StateInvalid) 1326 { 1327 CAMHAL_LOGEA("Invalid State after EXECUTING->IDLE Exitting!!!"); 1328 goto EXIT; 1329 } 1330 1331 if ( NO_ERROR == ret ) 1332 { 1333 CAMHAL_LOGDA("EXECUTING->IDLE state changed"); 1334 } 1335 else 1336 { 1337 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1338 OMX_EventCmdComplete, 1339 OMX_CommandStateSet, 1340 OMX_StateIdle, 1341 NULL); 1342 CAMHAL_LOGEA("Timeout expired on EXECUTING->IDLE state change"); 1343 goto EXIT; 1344 } 1345 1346 ///Register for LOADED state transition. 1347 ///This method just inserts a message in Event Q, which is checked in the callback 1348 ///The sempahore passed is signalled by the callback 1349 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1350 OMX_EventCmdComplete, 1351 OMX_CommandStateSet, 1352 OMX_StateLoaded, 1353 mSwitchToLoadedSem); 1354 1355 if(ret!=NO_ERROR) 1356 { 1357 CAMHAL_LOGEB("Error in registering for event %d", ret); 1358 goto EXIT; 1359 } 1360 1361 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp, 1362 OMX_CommandStateSet, 1363 OMX_StateLoaded, 1364 NULL); 1365 1366 if(eError!=OMX_ErrorNone) 1367 { 1368 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateLoaded) - %x", eError); 1369 } 1370 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1371 1372 CAMHAL_LOGDA("Switching IDLE->LOADED state"); 1373 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT); 1374 1375 //If somethiing bad happened while we wait 1376 if (mComponentState == OMX_StateInvalid) 1377 { 1378 CAMHAL_LOGEA("Invalid State after IDLE->LOADED Exitting!!!"); 1379 goto EXIT; 1380 } 1381 1382 if ( NO_ERROR == ret ) 1383 { 1384 CAMHAL_LOGDA("IDLE->LOADED state changed"); 1385 } 1386 else 1387 { 1388 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1389 OMX_EventCmdComplete, 1390 OMX_CommandStateSet, 1391 OMX_StateLoaded, 1392 NULL); 1393 CAMHAL_LOGEA("Timeout expired on IDLE->LOADED state change"); 1394 goto EXIT; 1395 } 1396 1397 mComponentState = OMX_StateLoaded; 1398 1399 ///Register for Preview port ENABLE event 1400 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1401 OMX_EventCmdComplete, 1402 OMX_CommandPortEnable, 1403 mCameraAdapterParameters.mPrevPortIndex, 1404 mSwitchToLoadedSem); 1405 1406 if ( NO_ERROR != ret ) 1407 { 1408 CAMHAL_LOGEB("Error in registering for event %d", ret); 1409 goto EXIT; 1410 } 1411 1412 ///Enable Preview Port 1413 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1414 OMX_CommandPortEnable, 1415 mCameraAdapterParameters.mPrevPortIndex, 1416 NULL); 1417 1418 1419 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError); 1420 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1421 1422 CAMHAL_LOGDA("Enabling Preview port"); 1423 ///Wait for state to switch to idle 1424 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT); 1425 1426 //If somethiing bad happened while we wait 1427 if (mComponentState == OMX_StateInvalid) 1428 { 1429 CAMHAL_LOGEA("Invalid State after Enabling Preview port Exitting!!!"); 1430 goto EXIT; 1431 } 1432 1433 if ( NO_ERROR == ret ) 1434 { 1435 CAMHAL_LOGDA("Preview port enabled!"); 1436 } 1437 else 1438 { 1439 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1440 OMX_EventCmdComplete, 1441 OMX_CommandPortEnable, 1442 mCameraAdapterParameters.mPrevPortIndex, 1443 NULL); 1444 CAMHAL_LOGEA("Preview enable timedout"); 1445 1446 goto EXIT; 1447 } 1448 1449 return (ret | ErrorUtils::omxToAndroidError(eError)); 1450 1451EXIT: 1452 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1453 performCleanupAfterError(); 1454 LOG_FUNCTION_NAME_EXIT; 1455 return (ret | ErrorUtils::omxToAndroidError(eError)); 1456} 1457 1458status_t OMXCameraAdapter::UseBuffersPreview(void* bufArr, int num) 1459{ 1460 status_t ret = NO_ERROR; 1461 OMX_ERRORTYPE eError = OMX_ErrorNone; 1462 int tmpHeight, tmpWidth; 1463 1464 LOG_FUNCTION_NAME; 1465 1466 ///Flag to determine whether it is 3D camera or not 1467 bool isS3d = false; 1468 const char *valstr = NULL; 1469 if ( (valstr = mParams.get(TICameraParameters::KEY_S3D_SUPPORTED)) != NULL) { 1470 isS3d = (strcmp(valstr, "true") == 0); 1471 } 1472 1473 if(!bufArr) 1474 { 1475 CAMHAL_LOGEA("NULL pointer passed for buffArr"); 1476 LOG_FUNCTION_NAME_EXIT; 1477 return BAD_VALUE; 1478 } 1479 1480 OMXCameraPortParameters * mPreviewData = NULL; 1481 OMXCameraPortParameters *measurementData = NULL; 1482 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 1483 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1484 mPreviewData->mNumBufs = num ; 1485 uint32_t *buffers = (uint32_t*)bufArr; 1486 1487 if ( 0 != mUsePreviewSem.Count() ) 1488 { 1489 CAMHAL_LOGEB("Error mUsePreviewSem semaphore count %d", mUsePreviewSem.Count()); 1490 LOG_FUNCTION_NAME_EXIT; 1491 return NO_INIT; 1492 } 1493 1494 if(mPreviewData->mNumBufs != num) 1495 { 1496 CAMHAL_LOGEA("Current number of buffers doesnt equal new num of buffers passed!"); 1497 LOG_FUNCTION_NAME_EXIT; 1498 return BAD_VALUE; 1499 } 1500 1501 mStateSwitchLock.lock(); 1502 1503 if ( mComponentState == OMX_StateLoaded ) 1504 { 1505 1506 ret = setLDC(mIPP); 1507 if ( NO_ERROR != ret ) 1508 { 1509 CAMHAL_LOGEB("setLDC() failed %d", ret); 1510 LOG_FUNCTION_NAME_EXIT; 1511 return ret; 1512 } 1513 1514 ret = setNSF(mIPP); 1515 if ( NO_ERROR != ret ) 1516 { 1517 CAMHAL_LOGEB("setNSF() failed %d", ret); 1518 LOG_FUNCTION_NAME_EXIT; 1519 return ret; 1520 } 1521 1522 ret = setCaptureMode(mCapMode); 1523 if ( NO_ERROR != ret ) 1524 { 1525 CAMHAL_LOGEB("setCaptureMode() failed %d", ret); 1526 LOG_FUNCTION_NAME_EXIT; 1527 return ret; 1528 } 1529 1530 CAMHAL_LOGDB("Camera Mode = %d", mCapMode); 1531 1532 if( ( mCapMode == OMXCameraAdapter::VIDEO_MODE ) || 1533 ( isS3d && (mCapMode == OMXCameraAdapter::HIGH_QUALITY)) ) 1534 { 1535 ///Enable/Disable Video Noise Filter 1536 ret = enableVideoNoiseFilter(mVnfEnabled); 1537 if ( NO_ERROR != ret) 1538 { 1539 CAMHAL_LOGEB("Error configuring VNF %x", ret); 1540 return ret; 1541 } 1542 1543 ///Enable/Disable Video Stabilization 1544 ret = enableVideoStabilization(mVstabEnabled); 1545 if ( NO_ERROR != ret) 1546 { 1547 CAMHAL_LOGEB("Error configuring VSTAB %x", ret); 1548 return ret; 1549 } 1550 } 1551 else 1552 { 1553 ret = enableVideoNoiseFilter(false); 1554 if ( NO_ERROR != ret) 1555 { 1556 CAMHAL_LOGEB("Error configuring VNF %x", ret); 1557 return ret; 1558 } 1559 ///Enable/Disable Video Stabilization 1560 ret = enableVideoStabilization(false); 1561 if ( NO_ERROR != ret) 1562 { 1563 CAMHAL_LOGEB("Error configuring VSTAB %x", ret); 1564 return ret; 1565 } 1566 } 1567 } 1568 1569 ret = setSensorOrientation(mSensorOrientation); 1570 if ( NO_ERROR != ret ) 1571 { 1572 CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret); 1573 mSensorOrientation = 0; 1574 } 1575 1576 ret = setVFramerate(mPreviewData->mMinFrameRate, mPreviewData->mMaxFrameRate); 1577 if ( ret != NO_ERROR ) 1578 { 1579 CAMHAL_LOGEB("VFR configuration failed 0x%x", ret); 1580 LOG_FUNCTION_NAME_EXIT; 1581 return ret; 1582 } 1583 1584 if ( mComponentState == OMX_StateLoaded ) 1585 { 1586 ///Register for IDLE state switch event 1587 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1588 OMX_EventCmdComplete, 1589 OMX_CommandStateSet, 1590 OMX_StateIdle, 1591 mUsePreviewSem); 1592 1593 if(ret!=NO_ERROR) 1594 { 1595 CAMHAL_LOGEB("Error in registering for event %d", ret); 1596 goto EXIT; 1597 } 1598 1599 ///Once we get the buffers, move component state to idle state and pass the buffers to OMX comp using UseBuffer 1600 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp , 1601 OMX_CommandStateSet, 1602 OMX_StateIdle, 1603 NULL); 1604 1605 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError); 1606 1607 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1608 1609 mComponentState = OMX_StateIdle; 1610 } 1611 else 1612 { 1613 ///Register for Preview port ENABLE event 1614 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1615 OMX_EventCmdComplete, 1616 OMX_CommandPortEnable, 1617 mCameraAdapterParameters.mPrevPortIndex, 1618 mUsePreviewSem); 1619 1620 if ( NO_ERROR != ret ) 1621 { 1622 CAMHAL_LOGEB("Error in registering for event %d", ret); 1623 goto EXIT; 1624 } 1625 1626 ///Enable Preview Port 1627 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1628 OMX_CommandPortEnable, 1629 mCameraAdapterParameters.mPrevPortIndex, 1630 NULL); 1631 } 1632 1633 1634 ///Configure DOMX to use either gralloc handles or vptrs 1635 OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles; 1636 OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER); 1637 1638 domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 1639 domxUseGrallocHandles.bEnable = OMX_TRUE; 1640 1641 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1642 (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles); 1643 if(eError!=OMX_ErrorNone) 1644 { 1645 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 1646 } 1647 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1648 1649 OMX_BUFFERHEADERTYPE *pBufferHdr; 1650 for(int index=0;index<num;index++) { 1651 1652 CAMHAL_LOGDB("OMX_UseBuffer(0x%x)", buffers[index]); 1653 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp, 1654 &pBufferHdr, 1655 mCameraAdapterParameters.mPrevPortIndex, 1656 0, 1657 mPreviewData->mBufSize, 1658 (OMX_U8*)buffers[index]); 1659 if(eError!=OMX_ErrorNone) 1660 { 1661 CAMHAL_LOGEB("OMX_UseBuffer-0x%x", eError); 1662 } 1663 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1664 1665 //pBufferHdr->pAppPrivate = (OMX_PTR)pBufferHdr; 1666 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 1667 pBufferHdr->nVersion.s.nVersionMajor = 1 ; 1668 pBufferHdr->nVersion.s.nVersionMinor = 1 ; 1669 pBufferHdr->nVersion.s.nRevision = 0 ; 1670 pBufferHdr->nVersion.s.nStep = 0; 1671 mPreviewData->mBufferHeader[index] = pBufferHdr; 1672 } 1673 1674 if ( mMeasurementEnabled ) 1675 { 1676 1677 for( int i = 0; i < num; i++ ) 1678 { 1679 OMX_BUFFERHEADERTYPE *pBufHdr; 1680 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp, 1681 &pBufHdr, 1682 mCameraAdapterParameters.mMeasurementPortIndex, 1683 0, 1684 measurementData->mBufSize, 1685 (OMX_U8*)(mPreviewDataBuffers[i])); 1686 1687 if ( eError == OMX_ErrorNone ) 1688 { 1689 pBufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 1690 pBufHdr->nVersion.s.nVersionMajor = 1 ; 1691 pBufHdr->nVersion.s.nVersionMinor = 1 ; 1692 pBufHdr->nVersion.s.nRevision = 0 ; 1693 pBufHdr->nVersion.s.nStep = 0; 1694 measurementData->mBufferHeader[i] = pBufHdr; 1695 } 1696 else 1697 { 1698 CAMHAL_LOGEB("OMX_UseBuffer -0x%x", eError); 1699 ret = BAD_VALUE; 1700 break; 1701 } 1702 } 1703 1704 } 1705 1706 CAMHAL_LOGDA("Registering preview buffers"); 1707 1708 ret = mUsePreviewSem.WaitTimeout(OMX_CMD_TIMEOUT); 1709 1710 //If somethiing bad happened while we wait 1711 if (mComponentState == OMX_StateInvalid) 1712 { 1713 CAMHAL_LOGEA("Invalid State after Registering preview buffers Exitting!!!"); 1714 goto EXIT; 1715 } 1716 1717 if ( NO_ERROR == ret ) 1718 { 1719 CAMHAL_LOGDA("Preview buffer registration successfull"); 1720 } 1721 else 1722 { 1723 if ( mComponentState == OMX_StateLoaded ) 1724 { 1725 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1726 OMX_EventCmdComplete, 1727 OMX_CommandStateSet, 1728 OMX_StateIdle, 1729 NULL); 1730 } 1731 else 1732 { 1733 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 1734 OMX_EventCmdComplete, 1735 OMX_CommandPortEnable, 1736 mCameraAdapterParameters.mPrevPortIndex, 1737 NULL); 1738 } 1739 CAMHAL_LOGEA("Timeout expired on preview buffer registration"); 1740 goto EXIT; 1741 } 1742 1743 LOG_FUNCTION_NAME_EXIT; 1744 1745 return (ret | ErrorUtils::omxToAndroidError(eError)); 1746 1747 ///If there is any failure, we reach here. 1748 ///Here, we do any resource freeing and convert from OMX error code to Camera Hal error code 1749EXIT: 1750 mStateSwitchLock.unlock(); 1751 1752 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1753 performCleanupAfterError(); 1754 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1755 1756 LOG_FUNCTION_NAME_EXIT; 1757 1758 return (ret | ErrorUtils::omxToAndroidError(eError)); 1759} 1760 1761status_t OMXCameraAdapter::startPreview() 1762{ 1763 status_t ret = NO_ERROR; 1764 OMX_ERRORTYPE eError = OMX_ErrorNone; 1765 OMXCameraPortParameters *mPreviewData = NULL; 1766 OMXCameraPortParameters *measurementData = NULL; 1767 1768 LOG_FUNCTION_NAME; 1769 1770 if( 0 != mStartPreviewSem.Count() ) 1771 { 1772 CAMHAL_LOGEB("Error mStartPreviewSem semaphore count %d", mStartPreviewSem.Count()); 1773 ret = NO_INIT; 1774 goto EXIT; 1775 } 1776 1777 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 1778 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1779 1780 if( OMX_StateIdle == mComponentState ) 1781 { 1782 ///Register for EXECUTING state transition. 1783 ///This method just inserts a message in Event Q, which is checked in the callback 1784 ///The sempahore passed is signalled by the callback 1785 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1786 OMX_EventCmdComplete, 1787 OMX_CommandStateSet, 1788 OMX_StateExecuting, 1789 mStartPreviewSem); 1790 1791 if(ret!=NO_ERROR) 1792 { 1793 CAMHAL_LOGEB("Error in registering for event %d", ret); 1794 goto EXIT; 1795 } 1796 1797 ///Switch to EXECUTING state 1798 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1799 OMX_CommandStateSet, 1800 OMX_StateExecuting, 1801 NULL); 1802 1803 if(eError!=OMX_ErrorNone) 1804 { 1805 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateExecuting)-0x%x", eError); 1806 } 1807 1808 CAMHAL_LOGDA("+Waiting for component to go into EXECUTING state"); 1809 ret = mStartPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT); 1810 1811 //If somethiing bad happened while we wait 1812 if (mComponentState == OMX_StateInvalid) 1813 { 1814 CAMHAL_LOGEA("Invalid State after IDLE_EXECUTING Exitting!!!"); 1815 goto EXIT; 1816 } 1817 1818 if ( NO_ERROR == ret ) 1819 { 1820 CAMHAL_LOGDA("+Great. Component went into executing state!!"); 1821 } 1822 else 1823 { 1824 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1825 OMX_EventCmdComplete, 1826 OMX_CommandStateSet, 1827 OMX_StateExecuting, 1828 NULL); 1829 CAMHAL_LOGDA("Timeout expired on executing state switch!"); 1830 goto EXIT; 1831 } 1832 1833 mComponentState = OMX_StateExecuting; 1834 1835 } 1836 1837 mStateSwitchLock.unlock(); 1838 1839 apply3Asettings(mParameters3A); 1840 //Queue all the buffers on preview port 1841 for(int index=0;index< mPreviewData->mMaxQueueable;index++) 1842 { 1843 CAMHAL_LOGDB("Queuing buffer on Preview port - 0x%x", (uint32_t)mPreviewData->mBufferHeader[index]->pBuffer); 1844 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 1845 (OMX_BUFFERHEADERTYPE*)mPreviewData->mBufferHeader[index]); 1846 if(eError!=OMX_ErrorNone) 1847 { 1848 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError); 1849 } 1850 mFramesWithDucati++; 1851#ifdef DEGUG_LOG 1852 mBuffersWithDucati.add((uint32_t)mPreviewData->mBufferHeader[index]->pBuffer,1); 1853#endif 1854 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1855 } 1856 1857 if ( mMeasurementEnabled ) 1858 { 1859 1860 for(int index=0;index< mPreviewData->mNumBufs;index++) 1861 { 1862 CAMHAL_LOGDB("Queuing buffer on Measurement port - 0x%x", (uint32_t) measurementData->mBufferHeader[index]->pBuffer); 1863 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 1864 (OMX_BUFFERHEADERTYPE*) measurementData->mBufferHeader[index]); 1865 if(eError!=OMX_ErrorNone) 1866 { 1867 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError); 1868 } 1869 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1870 } 1871 1872 } 1873 1874 // Enable Ancillary data. The nDCCStatus field is used to signify 1875 // whether the preview frame is a snapshot 1876 if ( OMX_ErrorNone == eError) 1877 { 1878 ret = setExtraData(true, OMX_ALL, OMX_AncillaryData); 1879 } 1880 1881 1882 if ( mPending3Asettings ) 1883 apply3Asettings(mParameters3A); 1884 1885 // enable focus callbacks just once here 1886 // fixes an issue with slow callback registration in Ducati 1887 if ( NO_ERROR == ret ) { 1888 ret = setFocusCallback(true); 1889 } 1890 1891 //reset frame rate estimates 1892 mFPS = 0.0f; 1893 mLastFPS = 0.0f; 1894 // start frame count from 0. i.e first frame after 1895 // startPreview will be the 0th reference frame 1896 // this way we will wait for second frame until 1897 // takePicture/autoFocus is allowed to run. we 1898 // are seeing SetConfig/GetConfig fail after 1899 // calling after the first frame and not failing 1900 // after the second frame 1901 mFrameCount = -1; 1902 mLastFrameCount = 0; 1903 mIter = 1; 1904 mLastFPSTime = systemTime(); 1905 1906 LOG_FUNCTION_NAME_EXIT; 1907 1908 return (ret | ErrorUtils::omxToAndroidError(eError)); 1909 1910 EXIT: 1911 1912 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1913 performCleanupAfterError(); 1914 mStateSwitchLock.unlock(); 1915 LOG_FUNCTION_NAME_EXIT; 1916 1917 return (ret | ErrorUtils::omxToAndroidError(eError)); 1918 1919} 1920 1921status_t OMXCameraAdapter::stopPreview() 1922{ 1923 LOG_FUNCTION_NAME; 1924 1925 OMX_ERRORTYPE eError = OMX_ErrorNone; 1926 status_t ret = NO_ERROR; 1927 1928 OMXCameraPortParameters *mCaptureData , *mPreviewData, *measurementData; 1929 mCaptureData = mPreviewData = measurementData = NULL; 1930 1931 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 1932 mCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 1933 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1934 1935 if (mAdapterState == LOADED_PREVIEW_STATE) { 1936 // Something happened in CameraHal between UseBuffers and startPreview 1937 // this means that state switch is still locked..so we need to unlock else 1938 // deadlock will occur on the next start preview 1939 mStateSwitchLock.unlock(); 1940 return NO_ERROR; 1941 } 1942 1943 if ( mComponentState != OMX_StateExecuting ) 1944 { 1945 CAMHAL_LOGEA("Calling StopPreview() when not in EXECUTING state"); 1946 LOG_FUNCTION_NAME_EXIT; 1947 return NO_INIT; 1948 } 1949 1950 { 1951 Mutex::Autolock lock(mFrameCountMutex); 1952 // we should wait for the first frame to come before trying to stopPreview...if not 1953 // we might put OMXCamera in a bad state (IDLE->LOADED timeout). Seeing this a lot 1954 // after a capture 1955 if (mFrameCount < 1) { 1956 // I want to wait for at least two frames.... 1957 mFrameCount = -1; 1958 1959 // first frame may time some time to come...so wait for an adequate amount of time 1960 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover. 1961 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex, 1962 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000); 1963 } 1964 // even if we timeout waiting for the first frame...go ahead with trying to stop preview 1965 // signal anybody that might be waiting 1966 mFrameCount = 0; 1967 mFirstFrameCondition.broadcast(); 1968 } 1969 1970 ret = cancelAutoFocus(); 1971 if(ret!=NO_ERROR) 1972 { 1973 CAMHAL_LOGEB("Error canceling autofocus %d", ret); 1974 // Error, but we probably still want to continue to stop preview 1975 } 1976 1977 OMX_CONFIG_FOCUSASSISTTYPE focusAssist; 1978 OMX_INIT_STRUCT_PTR (&focusAssist, OMX_CONFIG_FOCUSASSISTTYPE); 1979 focusAssist.nPortIndex = OMX_ALL; 1980 focusAssist.bFocusAssist = OMX_FALSE; 1981 CAMHAL_LOGDB("Configuring AF Assist mode 0x%x", focusAssist.bFocusAssist); 1982 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 1983 (OMX_INDEXTYPE) OMX_IndexConfigFocusAssist, 1984 &focusAssist); 1985 if ( OMX_ErrorNone != eError ) 1986 { 1987 CAMHAL_LOGEB("Error while configuring AF Assist mode 0x%x", eError); 1988 } 1989 else 1990 { 1991 CAMHAL_LOGDA("Camera AF Assist mode configured successfully"); 1992 } 1993 1994 if ( 0 != mStopPreviewSem.Count() ) 1995 { 1996 CAMHAL_LOGEB("Error mStopPreviewSem semaphore count %d", mStopPreviewSem.Count()); 1997 LOG_FUNCTION_NAME_EXIT; 1998 return NO_INIT; 1999 } 2000 2001 ret = disableImagePort(); 2002 if ( NO_ERROR != ret ) { 2003 CAMHAL_LOGEB("disable image port failed 0x%x", ret); 2004 goto EXIT; 2005 } 2006 2007 CAMHAL_LOGDB("Average framerate: %f", mFPS); 2008 2009 //Avoid state switching of the OMX Component 2010 ret = flushBuffers(); 2011 if ( NO_ERROR != ret ) 2012 { 2013 CAMHAL_LOGEB("Flush Buffers failed 0x%x", ret); 2014 goto EXIT; 2015 } 2016 2017 ///Register for Preview port Disable event 2018 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 2019 OMX_EventCmdComplete, 2020 OMX_CommandPortDisable, 2021 mCameraAdapterParameters.mPrevPortIndex, 2022 mStopPreviewSem); 2023 2024 ///Disable Preview Port 2025 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 2026 OMX_CommandPortDisable, 2027 mCameraAdapterParameters.mPrevPortIndex, 2028 NULL); 2029 2030 ///Free the OMX Buffers 2031 for ( int i = 0 ; i < mPreviewData->mNumBufs ; i++ ) 2032 { 2033 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 2034 mCameraAdapterParameters.mPrevPortIndex, 2035 mPreviewData->mBufferHeader[i]); 2036 2037 if(eError!=OMX_ErrorNone) 2038 { 2039 CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError); 2040 } 2041 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2042 } 2043 2044 if ( mMeasurementEnabled ) 2045 { 2046 2047 for ( int i = 0 ; i < measurementData->mNumBufs ; i++ ) 2048 { 2049 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 2050 mCameraAdapterParameters.mMeasurementPortIndex, 2051 measurementData->mBufferHeader[i]); 2052 if(eError!=OMX_ErrorNone) 2053 { 2054 CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError); 2055 } 2056 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2057 } 2058 2059 { 2060 Mutex::Autolock lock(mPreviewDataBufferLock); 2061 mPreviewDataBuffersAvailable.clear(); 2062 } 2063 2064 } 2065 2066 CAMHAL_LOGDA("Disabling preview port"); 2067 ret = mStopPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT); 2068 2069 //If somethiing bad happened while we wait 2070 if (mComponentState == OMX_StateInvalid) 2071 { 2072 CAMHAL_LOGEA("Invalid State after Disabling preview port Exitting!!!"); 2073 goto EXIT; 2074 } 2075 2076 if ( NO_ERROR == ret ) 2077 { 2078 CAMHAL_LOGDA("Preview port disabled"); 2079 } 2080 else 2081 { 2082 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 2083 OMX_EventCmdComplete, 2084 OMX_CommandPortDisable, 2085 mCameraAdapterParameters.mPrevPortIndex, 2086 NULL); 2087 CAMHAL_LOGEA("Timeout expired on preview port disable"); 2088 goto EXIT; 2089 } 2090 2091 { 2092 Mutex::Autolock lock(mPreviewBufferLock); 2093 ///Clear all the available preview buffers 2094 mPreviewBuffersAvailable.clear(); 2095 } 2096 2097 switchToLoaded(); 2098 2099 2100 mFirstTimeInit = true; 2101 mPendingCaptureSettings = 0; 2102 mFramesWithDucati = 0; 2103 mFramesWithDisplay = 0; 2104 mFramesWithEncoder = 0; 2105 2106 LOG_FUNCTION_NAME_EXIT; 2107 2108 return (ret | ErrorUtils::omxToAndroidError(eError)); 2109 2110EXIT: 2111 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 2112 { 2113 Mutex::Autolock lock(mPreviewBufferLock); 2114 ///Clear all the available preview buffers 2115 mPreviewBuffersAvailable.clear(); 2116 } 2117 performCleanupAfterError(); 2118 LOG_FUNCTION_NAME_EXIT; 2119 return (ret | ErrorUtils::omxToAndroidError(eError)); 2120 2121} 2122 2123status_t OMXCameraAdapter::setSensorOverclock(bool enable) 2124{ 2125 status_t ret = NO_ERROR; 2126 OMX_ERRORTYPE eError = OMX_ErrorNone; 2127 OMX_CONFIG_BOOLEANTYPE bOMX; 2128 2129 LOG_FUNCTION_NAME; 2130 2131 if ( OMX_StateLoaded != mComponentState ) 2132 { 2133 CAMHAL_LOGDA("OMX component is not in loaded state"); 2134 return ret; 2135 } 2136 2137 if ( NO_ERROR == ret ) 2138 { 2139 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 2140 2141 if ( enable ) 2142 { 2143 bOMX.bEnabled = OMX_TRUE; 2144 } 2145 else 2146 { 2147 bOMX.bEnabled = OMX_FALSE; 2148 } 2149 2150 CAMHAL_LOGDB("Configuring Sensor overclock mode 0x%x", bOMX.bEnabled); 2151 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParamSensorOverClockMode, &bOMX); 2152 if ( OMX_ErrorNone != eError ) 2153 { 2154 CAMHAL_LOGEB("Error while setting Sensor overclock 0x%x", eError); 2155 ret = BAD_VALUE; 2156 } 2157 else 2158 { 2159 mSensorOverclock = enable; 2160 } 2161 } 2162 2163 LOG_FUNCTION_NAME_EXIT; 2164 2165 return ret; 2166} 2167 2168status_t OMXCameraAdapter::printComponentVersion(OMX_HANDLETYPE handle) 2169{ 2170 status_t ret = NO_ERROR; 2171 OMX_ERRORTYPE eError = OMX_ErrorNone; 2172 OMX_VERSIONTYPE compVersion; 2173 char compName[OMX_MAX_STRINGNAME_SIZE]; 2174 char *currentUUID = NULL; 2175 size_t offset = 0; 2176 2177 LOG_FUNCTION_NAME; 2178 2179 if ( NULL == handle ) 2180 { 2181 CAMHAL_LOGEB("Invalid OMX Handle =0x%x", ( unsigned int ) handle); 2182 ret = -EINVAL; 2183 } 2184 2185 mCompUUID[0] = 0; 2186 2187 if ( NO_ERROR == ret ) 2188 { 2189 eError = OMX_GetComponentVersion(handle, 2190 compName, 2191 &compVersion, 2192 &mCompRevision, 2193 &mCompUUID 2194 ); 2195 if ( OMX_ErrorNone != eError ) 2196 { 2197 CAMHAL_LOGEB("OMX_GetComponentVersion returned 0x%x", eError); 2198 ret = BAD_VALUE; 2199 } 2200 } 2201 2202 if ( NO_ERROR == ret ) 2203 { 2204 CAMHAL_LOGVB("OMX Component name: [%s]", compName); 2205 CAMHAL_LOGVB("OMX Component version: [%u]", ( unsigned int ) compVersion.nVersion); 2206 CAMHAL_LOGVB("Spec version: [%u]", ( unsigned int ) mCompRevision.nVersion); 2207 CAMHAL_LOGVB("Git Commit ID: [%s]", mCompUUID); 2208 currentUUID = ( char * ) mCompUUID; 2209 } 2210 2211 if ( NULL != currentUUID ) 2212 { 2213 offset = strlen( ( const char * ) mCompUUID) + 1; 2214 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE ) 2215 { 2216 currentUUID += offset; 2217 CAMHAL_LOGVB("Git Branch: [%s]", currentUUID); 2218 } 2219 else 2220 { 2221 ret = BAD_VALUE; 2222 } 2223 } 2224 2225 if ( NO_ERROR == ret ) 2226 { 2227 offset = strlen( ( const char * ) currentUUID) + 1; 2228 2229 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE ) 2230 { 2231 currentUUID += offset; 2232 CAMHAL_LOGVB("Build date and time: [%s]", currentUUID); 2233 } 2234 else 2235 { 2236 ret = BAD_VALUE; 2237 } 2238 } 2239 2240 if ( NO_ERROR == ret ) 2241 { 2242 offset = strlen( ( const char * ) currentUUID) + 1; 2243 2244 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE ) 2245 { 2246 currentUUID += offset; 2247 CAMHAL_LOGVB("Build description: [%s]", currentUUID); 2248 } 2249 else 2250 { 2251 ret = BAD_VALUE; 2252 } 2253 } 2254 2255 LOG_FUNCTION_NAME_EXIT; 2256 2257 return ret; 2258} 2259 2260status_t OMXCameraAdapter::autoFocus() 2261{ 2262 status_t ret = NO_ERROR; 2263 TIUTILS::Message msg; 2264 2265 LOG_FUNCTION_NAME; 2266 2267 { 2268 Mutex::Autolock lock(mFrameCountMutex); 2269 if (mFrameCount < 1) { 2270 // first frame may time some time to come...so wait for an adequate amount of time 2271 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover. 2272 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex, 2273 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000); 2274 if ((NO_ERROR != ret) || (mFrameCount == 0)) { 2275 goto EXIT; 2276 } 2277 } 2278 } 2279 2280 msg.command = CommandHandler::CAMERA_PERFORM_AUTOFOCUS; 2281 msg.arg1 = mErrorNotifier; 2282 ret = mCommandHandler->put(&msg); 2283 2284 EXIT: 2285 2286 LOG_FUNCTION_NAME; 2287 2288 return ret; 2289} 2290 2291status_t OMXCameraAdapter::takePicture() 2292{ 2293 status_t ret = NO_ERROR; 2294 TIUTILS::Message msg; 2295 2296 LOG_FUNCTION_NAME; 2297 2298 { 2299 Mutex::Autolock lock(mFrameCountMutex); 2300 if (mFrameCount < 1) { 2301 // first frame may time some time to come...so wait for an adequate amount of time 2302 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover. 2303 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex, 2304 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000); 2305 if ((NO_ERROR != ret) || (mFrameCount == 0)) { 2306 goto EXIT; 2307 } 2308 } 2309 } 2310 2311 msg.command = CommandHandler::CAMERA_START_IMAGE_CAPTURE; 2312 msg.arg1 = mErrorNotifier; 2313 ret = mCommandHandler->put(&msg); 2314 2315 EXIT: 2316 LOG_FUNCTION_NAME_EXIT; 2317 2318 return ret; 2319} 2320 2321status_t OMXCameraAdapter::startVideoCapture() 2322{ 2323 return BaseCameraAdapter::startVideoCapture(); 2324} 2325 2326status_t OMXCameraAdapter::stopVideoCapture() 2327{ 2328 return BaseCameraAdapter::stopVideoCapture(); 2329} 2330 2331//API to get the frame size required to be allocated. This size is used to override the size passed 2332//by camera service when VSTAB/VNF is turned ON for example 2333status_t OMXCameraAdapter::getFrameSize(size_t &width, size_t &height) 2334{ 2335 status_t ret = NO_ERROR; 2336 OMX_ERRORTYPE eError = OMX_ErrorNone; 2337 OMX_CONFIG_RECTTYPE tFrameDim; 2338 2339 LOG_FUNCTION_NAME; 2340 2341 OMX_INIT_STRUCT_PTR (&tFrameDim, OMX_CONFIG_RECTTYPE); 2342 tFrameDim.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 2343 2344 if ( mOMXStateSwitch ) 2345 { 2346 ret = switchToLoaded(); 2347 if ( NO_ERROR != ret ) 2348 { 2349 CAMHAL_LOGEB("switchToLoaded() failed 0x%x", ret); 2350 goto exit; 2351 } 2352 2353 mOMXStateSwitch = false; 2354 } 2355 2356 if ( OMX_StateLoaded == mComponentState ) 2357 { 2358 2359 ret = setLDC(mIPP); 2360 if ( NO_ERROR != ret ) 2361 { 2362 CAMHAL_LOGEB("setLDC() failed %d", ret); 2363 LOG_FUNCTION_NAME_EXIT; 2364 goto exit; 2365 } 2366 2367 ret = setNSF(mIPP); 2368 if ( NO_ERROR != ret ) 2369 { 2370 CAMHAL_LOGEB("setNSF() failed %d", ret); 2371 LOG_FUNCTION_NAME_EXIT; 2372 goto exit; 2373 } 2374 2375 ret = setCaptureMode(mCapMode); 2376 if ( NO_ERROR != ret ) 2377 { 2378 CAMHAL_LOGEB("setCaptureMode() failed %d", ret); 2379 } 2380 2381 if(mCapMode == OMXCameraAdapter::VIDEO_MODE) 2382 { 2383 if ( NO_ERROR == ret ) 2384 { 2385 ///Enable/Disable Video Noise Filter 2386 ret = enableVideoNoiseFilter(mVnfEnabled); 2387 } 2388 2389 if ( NO_ERROR != ret) 2390 { 2391 CAMHAL_LOGEB("Error configuring VNF %x", ret); 2392 } 2393 2394 if ( NO_ERROR == ret ) 2395 { 2396 ///Enable/Disable Video Stabilization 2397 ret = enableVideoStabilization(mVstabEnabled); 2398 } 2399 2400 if ( NO_ERROR != ret) 2401 { 2402 CAMHAL_LOGEB("Error configuring VSTAB %x", ret); 2403 } 2404 } 2405 else 2406 { 2407 if ( NO_ERROR == ret ) 2408 { 2409 ///Enable/Disable Video Noise Filter 2410 ret = enableVideoNoiseFilter(false); 2411 } 2412 2413 if ( NO_ERROR != ret) 2414 { 2415 CAMHAL_LOGEB("Error configuring VNF %x", ret); 2416 } 2417 2418 if ( NO_ERROR == ret ) 2419 { 2420 ///Enable/Disable Video Stabilization 2421 ret = enableVideoStabilization(false); 2422 } 2423 2424 if ( NO_ERROR != ret) 2425 { 2426 CAMHAL_LOGEB("Error configuring VSTAB %x", ret); 2427 } 2428 } 2429 2430 } 2431 2432 ret = setSensorOrientation(mSensorOrientation); 2433 if ( NO_ERROR != ret ) 2434 { 2435 CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret); 2436 mSensorOrientation = 0; 2437 } 2438 2439 if ( NO_ERROR == ret ) 2440 { 2441 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParam2DBufferAllocDimension, &tFrameDim); 2442 if ( OMX_ErrorNone == eError) 2443 { 2444 width = tFrameDim.nWidth; 2445 height = tFrameDim.nHeight; 2446 } 2447 } 2448 2449exit: 2450 2451 CAMHAL_LOGDB("Required frame size %dx%d", width, height); 2452 LOG_FUNCTION_NAME_EXIT; 2453 2454 return ret; 2455} 2456 2457status_t OMXCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount) 2458{ 2459 status_t ret = NO_ERROR; 2460 OMX_PARAM_PORTDEFINITIONTYPE portCheck; 2461 OMX_ERRORTYPE eError = OMX_ErrorNone; 2462 2463 LOG_FUNCTION_NAME; 2464 2465 if ( OMX_StateLoaded != mComponentState ) 2466 { 2467 CAMHAL_LOGEA("Calling getFrameDataSize() when not in LOADED state"); 2468 dataFrameSize = 0; 2469 ret = BAD_VALUE; 2470 } 2471 2472 if ( NO_ERROR == ret ) 2473 { 2474 OMX_INIT_STRUCT_PTR(&portCheck, OMX_PARAM_PORTDEFINITIONTYPE); 2475 portCheck.nPortIndex = mCameraAdapterParameters.mMeasurementPortIndex; 2476 2477 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck); 2478 if ( OMX_ErrorNone != eError ) 2479 { 2480 CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError); 2481 dataFrameSize = 0; 2482 ret = BAD_VALUE; 2483 } 2484 } 2485 2486 if ( NO_ERROR == ret ) 2487 { 2488 portCheck.nBufferCountActual = bufferCount; 2489 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck); 2490 if ( OMX_ErrorNone != eError ) 2491 { 2492 CAMHAL_LOGEB("OMX_SetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError); 2493 dataFrameSize = 0; 2494 ret = BAD_VALUE; 2495 } 2496 } 2497 2498 if ( NO_ERROR == ret ) 2499 { 2500 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck); 2501 if ( OMX_ErrorNone != eError ) 2502 { 2503 CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError); 2504 ret = BAD_VALUE; 2505 } 2506 else 2507 { 2508 mCameraAdapterParameters.mCameraPortParams[portCheck.nPortIndex].mBufSize = portCheck.nBufferSize; 2509 dataFrameSize = portCheck.nBufferSize; 2510 } 2511 } 2512 2513 LOG_FUNCTION_NAME_EXIT; 2514 2515 return ret; 2516} 2517 2518void OMXCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt) 2519{ 2520 LOG_FUNCTION_NAME; 2521 2522 static const unsigned int DEGREES_TILT_IGNORE = 45; 2523 int device_orientation = 0; 2524 int mount_orientation = 0; 2525 const char *facing_direction = NULL; 2526 2527 // if tilt angle is greater than DEGREES_TILT_IGNORE 2528 // we are going to ignore the orientation returned from 2529 // sensor. the orientation returned from sensor is not 2530 // reliable. Value of DEGREES_TILT_IGNORE may need adjusting 2531 if (tilt > DEGREES_TILT_IGNORE) { 2532 return; 2533 } 2534 2535 if (mCapabilities) { 2536 if (mCapabilities->get(CameraProperties::ORIENTATION_INDEX)) { 2537 mount_orientation = atoi(mCapabilities->get(CameraProperties::ORIENTATION_INDEX)); 2538 } 2539 facing_direction = mCapabilities->get(CameraProperties::FACING_INDEX); 2540 } 2541 2542 // calculate device orientation relative to the sensor orientation 2543 // front camera display is mirrored...needs to be accounted for when orientation 2544 // is 90 or 270...since this will result in a flip on orientation otherwise 2545 if (facing_direction && !strcmp(facing_direction, TICameraParameters::FACING_FRONT) && 2546 (orientation == 90 || orientation == 270)) { 2547 device_orientation = (orientation - mount_orientation + 360) % 360; 2548 } else { // back-facing camera 2549 device_orientation = (orientation + mount_orientation) % 360; 2550 } 2551 2552 if (device_orientation != mDeviceOrientation) { 2553 mDeviceOrientation = device_orientation; 2554 2555 mFaceDetectionLock.lock(); 2556 if (mFaceDetectionRunning) { 2557 // restart face detection with new rotation 2558 setFaceDetection(true, mDeviceOrientation); 2559 } 2560 mFaceDetectionLock.unlock(); 2561 } 2562 CAMHAL_LOGVB("orientation = %d tilt = %d device_orientation = %d", orientation, tilt, mDeviceOrientation); 2563 2564 LOG_FUNCTION_NAME_EXIT; 2565} 2566 2567/* Application callback Functions */ 2568/*========================================================*/ 2569/* @ fn SampleTest_EventHandler :: Application callback */ 2570/*========================================================*/ 2571OMX_ERRORTYPE OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent, 2572 OMX_IN OMX_PTR pAppData, 2573 OMX_IN OMX_EVENTTYPE eEvent, 2574 OMX_IN OMX_U32 nData1, 2575 OMX_IN OMX_U32 nData2, 2576 OMX_IN OMX_PTR pEventData) 2577{ 2578 LOG_FUNCTION_NAME; 2579 2580 CAMHAL_LOGDB("Event %d", eEvent); 2581 2582 OMX_ERRORTYPE ret = OMX_ErrorNone; 2583 OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData; 2584 ret = oca->OMXCameraAdapterEventHandler(hComponent, eEvent, nData1, nData2, pEventData); 2585 2586 LOG_FUNCTION_NAME_EXIT; 2587 return ret; 2588} 2589 2590/* Application callback Functions */ 2591/*========================================================*/ 2592/* @ fn SampleTest_EventHandler :: Application callback */ 2593/*========================================================*/ 2594OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent, 2595 OMX_IN OMX_EVENTTYPE eEvent, 2596 OMX_IN OMX_U32 nData1, 2597 OMX_IN OMX_U32 nData2, 2598 OMX_IN OMX_PTR pEventData) 2599{ 2600 2601 LOG_FUNCTION_NAME; 2602 2603 OMX_ERRORTYPE eError = OMX_ErrorNone; 2604 CAMHAL_LOGDB("+OMX_Event %x, %d %d", eEvent, (int)nData1, (int)nData2); 2605 2606 switch (eEvent) { 2607 case OMX_EventCmdComplete: 2608 CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d", (int)nData1, (int)nData2); 2609 2610 if (OMX_CommandStateSet == nData1) { 2611 mCameraAdapterParameters.mState = (OMX_STATETYPE) nData2; 2612 2613 } else if (OMX_CommandFlush == nData1) { 2614 CAMHAL_LOGDB("OMX_CommandFlush received for port %d", (int)nData2); 2615 2616 } else if (OMX_CommandPortDisable == nData1) { 2617 CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d", (int)nData2); 2618 2619 } else if (OMX_CommandPortEnable == nData1) { 2620 CAMHAL_LOGDB("OMX_CommandPortEnable received for port %d", (int)nData2); 2621 2622 } else if (OMX_CommandMarkBuffer == nData1) { 2623 ///This is not used currently 2624 } 2625 2626 CAMHAL_LOGDA("-OMX_EventCmdComplete"); 2627 break; 2628 2629 case OMX_EventIndexSettingChanged: 2630 CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x", 2631 ( unsigned int ) nData1, ( unsigned int ) nData2); 2632 break; 2633 2634 case OMX_EventError: 2635 CAMHAL_LOGDB("OMX interface failed to execute OMX command %d", (int)nData1); 2636 CAMHAL_LOGDA("See OMX_INDEXTYPE for reference"); 2637 if ( NULL != mErrorNotifier && ( ( OMX_U32 ) OMX_ErrorHardware == nData1 ) && mComponentState != OMX_StateInvalid) 2638 { 2639 CAMHAL_LOGEA("***Got Fatal Error Notification***\n"); 2640 mComponentState = OMX_StateInvalid; 2641 /* 2642 Remove any unhandled events and 2643 unblock any waiting semaphores 2644 */ 2645 if ( !mEventSignalQ.isEmpty() ) 2646 { 2647 for (unsigned int i = 0 ; i < mEventSignalQ.size(); i++ ) 2648 { 2649 CAMHAL_LOGEB("***Removing %d EVENTS***** \n", mEventSignalQ.size()); 2650 //remove from queue and free msg 2651 TIUTILS::Message *msg = mEventSignalQ.itemAt(i); 2652 if ( NULL != msg ) 2653 { 2654 Semaphore *sem = (Semaphore*) msg->arg3; 2655 if ( sem ) 2656 { 2657 sem->Signal(); 2658 } 2659 free(msg); 2660 } 2661 } 2662 mEventSignalQ.clear(); 2663 } 2664 ///Report Error to App 2665 mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL); 2666 } 2667 break; 2668 2669 case OMX_EventMark: 2670 break; 2671 2672 case OMX_EventPortSettingsChanged: 2673 break; 2674 2675 case OMX_EventBufferFlag: 2676 break; 2677 2678 case OMX_EventResourcesAcquired: 2679 break; 2680 2681 case OMX_EventComponentResumed: 2682 break; 2683 2684 case OMX_EventDynamicResourcesAvailable: 2685 break; 2686 2687 case OMX_EventPortFormatDetected: 2688 break; 2689 2690 default: 2691 break; 2692 } 2693 2694 ///Signal to the thread(s) waiting that the event has occured 2695 SignalEvent(hComponent, eEvent, nData1, nData2, pEventData); 2696 2697 LOG_FUNCTION_NAME_EXIT; 2698 return eError; 2699 2700 EXIT: 2701 2702 CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError); 2703 LOG_FUNCTION_NAME_EXIT; 2704 return eError; 2705} 2706 2707OMX_ERRORTYPE OMXCameraAdapter::SignalEvent(OMX_IN OMX_HANDLETYPE hComponent, 2708 OMX_IN OMX_EVENTTYPE eEvent, 2709 OMX_IN OMX_U32 nData1, 2710 OMX_IN OMX_U32 nData2, 2711 OMX_IN OMX_PTR pEventData) 2712{ 2713 Mutex::Autolock lock(mEventLock); 2714 TIUTILS::Message *msg; 2715 bool eventSignalled = false; 2716 2717 LOG_FUNCTION_NAME; 2718 2719 if ( !mEventSignalQ.isEmpty() ) 2720 { 2721 CAMHAL_LOGDA("Event queue not empty"); 2722 2723 for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ ) 2724 { 2725 msg = mEventSignalQ.itemAt(i); 2726 if ( NULL != msg ) 2727 { 2728 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) ) 2729 && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 ) 2730 && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 ) 2731 && msg->arg3) 2732 { 2733 Semaphore *sem = (Semaphore*) msg->arg3; 2734 CAMHAL_LOGDA("Event matched, signalling sem"); 2735 mEventSignalQ.removeAt(i); 2736 //Signal the semaphore provided 2737 sem->Signal(); 2738 free(msg); 2739 eventSignalled = true; 2740 break; 2741 } 2742 } 2743 } 2744 } 2745 else 2746 { 2747 CAMHAL_LOGDA("Event queue empty!!!"); 2748 } 2749 2750 // Special handling for any unregistered events 2751 if (!eventSignalled) { 2752 // Handling for focus callback 2753 if ((nData2 == OMX_IndexConfigCommonFocusStatus) && 2754 (eEvent == (OMX_EVENTTYPE) OMX_EventIndexSettingChanged)) { 2755 TIUTILS::Message msg; 2756 msg.command = OMXCallbackHandler::CAMERA_FOCUS_STATUS; 2757 msg.arg1 = NULL; 2758 msg.arg2 = NULL; 2759 mOMXCallbackHandler->put(&msg); 2760 } 2761 } 2762 2763 LOG_FUNCTION_NAME_EXIT; 2764 2765 return OMX_ErrorNone; 2766} 2767 2768OMX_ERRORTYPE OMXCameraAdapter::RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent, 2769 OMX_IN OMX_EVENTTYPE eEvent, 2770 OMX_IN OMX_U32 nData1, 2771 OMX_IN OMX_U32 nData2, 2772 OMX_IN OMX_PTR pEventData) 2773{ 2774 Mutex::Autolock lock(mEventLock); 2775 TIUTILS::Message *msg; 2776 LOG_FUNCTION_NAME; 2777 2778 if ( !mEventSignalQ.isEmpty() ) 2779 { 2780 CAMHAL_LOGDA("Event queue not empty"); 2781 2782 for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ ) 2783 { 2784 msg = mEventSignalQ.itemAt(i); 2785 if ( NULL != msg ) 2786 { 2787 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) ) 2788 && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 ) 2789 && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 ) 2790 && msg->arg3) 2791 { 2792 Semaphore *sem = (Semaphore*) msg->arg3; 2793 CAMHAL_LOGDA("Event matched, signalling sem"); 2794 mEventSignalQ.removeAt(i); 2795 free(msg); 2796 break; 2797 } 2798 } 2799 } 2800 } 2801 else 2802 { 2803 CAMHAL_LOGEA("Event queue empty!!!"); 2804 } 2805 LOG_FUNCTION_NAME_EXIT; 2806 2807 return OMX_ErrorNone; 2808} 2809 2810 2811status_t OMXCameraAdapter::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent, 2812 OMX_IN OMX_EVENTTYPE eEvent, 2813 OMX_IN OMX_U32 nData1, 2814 OMX_IN OMX_U32 nData2, 2815 OMX_IN Semaphore &semaphore) 2816{ 2817 status_t ret = NO_ERROR; 2818 ssize_t res; 2819 Mutex::Autolock lock(mEventLock); 2820 2821 LOG_FUNCTION_NAME; 2822 TIUTILS::Message * msg = ( struct TIUTILS::Message * ) malloc(sizeof(struct TIUTILS::Message)); 2823 if ( NULL != msg ) 2824 { 2825 msg->command = ( unsigned int ) eEvent; 2826 msg->arg1 = ( void * ) nData1; 2827 msg->arg2 = ( void * ) nData2; 2828 msg->arg3 = ( void * ) &semaphore; 2829 msg->arg4 = ( void * ) hComponent; 2830 res = mEventSignalQ.add(msg); 2831 if ( NO_MEMORY == res ) 2832 { 2833 CAMHAL_LOGEA("No ressources for inserting OMX events"); 2834 free(msg); 2835 ret = -ENOMEM; 2836 } 2837 } 2838 2839 LOG_FUNCTION_NAME_EXIT; 2840 2841 return ret; 2842} 2843 2844/*========================================================*/ 2845/* @ fn SampleTest_EmptyBufferDone :: Application callback*/ 2846/*========================================================*/ 2847OMX_ERRORTYPE OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 2848 OMX_IN OMX_PTR pAppData, 2849 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 2850{ 2851 LOG_FUNCTION_NAME; 2852 2853 OMX_ERRORTYPE eError = OMX_ErrorNone; 2854 2855 OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData; 2856 eError = oca->OMXCameraAdapterEmptyBufferDone(hComponent, pBuffHeader); 2857 2858 LOG_FUNCTION_NAME_EXIT; 2859 return eError; 2860} 2861 2862 2863/*========================================================*/ 2864/* @ fn SampleTest_EmptyBufferDone :: Application callback*/ 2865/*========================================================*/ 2866OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 2867 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 2868{ 2869 2870 LOG_FUNCTION_NAME; 2871 2872 LOG_FUNCTION_NAME_EXIT; 2873 2874 return OMX_ErrorNone; 2875} 2876 2877static void debugShowFPS() 2878{ 2879 static int mFrameCount = 0; 2880 static int mLastFrameCount = 0; 2881 static nsecs_t mLastFpsTime = 0; 2882 static float mFps = 0; 2883 mFrameCount++; 2884 if (!(mFrameCount & 0x1F)) { 2885 nsecs_t now = systemTime(); 2886 nsecs_t diff = now - mLastFpsTime; 2887 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 2888 mLastFpsTime = now; 2889 mLastFrameCount = mFrameCount; 2890 ALOGD("Camera %d Frames, %f FPS", mFrameCount, mFps); 2891 } 2892 // XXX: mFPS has the value we want 2893} 2894 2895/*========================================================*/ 2896/* @ fn SampleTest_FillBufferDone :: Application callback*/ 2897/*========================================================*/ 2898OMX_ERRORTYPE OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 2899 OMX_IN OMX_PTR pAppData, 2900 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 2901{ 2902 TIUTILS::Message msg; 2903 OMX_ERRORTYPE eError = OMX_ErrorNone; 2904 2905 if (UNLIKELY(mDebugFps)) { 2906 debugShowFPS(); 2907 } 2908 2909 OMXCameraAdapter *adapter = ( OMXCameraAdapter * ) pAppData; 2910 if ( NULL != adapter ) 2911 { 2912 msg.command = OMXCameraAdapter::OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE; 2913 msg.arg1 = ( void * ) hComponent; 2914 msg.arg2 = ( void * ) pBuffHeader; 2915 adapter->mOMXCallbackHandler->put(&msg); 2916 } 2917 2918 return eError; 2919} 2920 2921/*========================================================*/ 2922/* @ fn SampleTest_FillBufferDone :: Application callback*/ 2923/*========================================================*/ 2924OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 2925 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 2926{ 2927 2928 status_t stat = NO_ERROR; 2929 status_t res1, res2; 2930 OMXCameraPortParameters *pPortParam; 2931 OMX_ERRORTYPE eError = OMX_ErrorNone; 2932 CameraFrame::FrameType typeOfFrame = CameraFrame::ALL_FRAMES; 2933 unsigned int refCount = 0; 2934 BaseCameraAdapter::AdapterState state, nextState; 2935 BaseCameraAdapter::getState(state); 2936 BaseCameraAdapter::getNextState(nextState); 2937 sp<CameraFDResult> fdResult = NULL; 2938 unsigned int mask = 0xFFFF; 2939 CameraFrame cameraFrame; 2940 OMX_TI_PLATFORMPRIVATE *platformPrivate; 2941 OMX_OTHER_EXTRADATATYPE *extraData; 2942 OMX_TI_ANCILLARYDATATYPE *ancillaryData = NULL; 2943 bool snapshotFrame = false; 2944 2945 res1 = res2 = NO_ERROR; 2946 pPortParam = &(mCameraAdapterParameters.mCameraPortParams[pBuffHeader->nOutputPortIndex]); 2947 2948 if ( !pBuffHeader || !pBuffHeader->pBuffer ) { 2949 CAMHAL_LOGEA("NULL Buffer from OMX"); 2950 return OMX_ErrorNone; 2951 } 2952 2953 if (pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW) 2954 { 2955 2956 if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE ) 2957 { 2958 return OMX_ErrorNone; 2959 } 2960 2961 if ( mWaitingForSnapshot ) 2962 { 2963 platformPrivate = (OMX_TI_PLATFORMPRIVATE*) pBuffHeader->pPlatformPrivate; 2964 extraData = getExtradata((OMX_OTHER_EXTRADATATYPE*) platformPrivate->pMetaDataBuffer, 2965 (OMX_EXTRADATATYPE) OMX_AncillaryData); 2966 2967 if ( NULL != extraData ) 2968 { 2969 ancillaryData = (OMX_TI_ANCILLARYDATATYPE*) extraData->data; 2970 snapshotFrame = ancillaryData->nDCCStatus; 2971 mPending3Asettings |= SetFocus; 2972 } 2973 } 2974 2975 recalculateFPS(); 2976 { 2977 Mutex::Autolock lock(mFaceDetectionLock); 2978 if ( mFaceDetectionRunning && !mFaceDetectionPaused ) { 2979 detectFaces(pBuffHeader, fdResult, pPortParam->mWidth, pPortParam->mHeight); 2980 if ( NULL != fdResult.get() ) { 2981 notifyFaceSubscribers(fdResult); 2982 fdResult.clear(); 2983 } 2984 if ( mFDSwitchAlgoPriority ) { 2985 2986 //Disable region priority and enable face priority for AF 2987 setAlgoPriority(REGION_PRIORITY, FOCUS_ALGO, false); 2988 setAlgoPriority(FACE_PRIORITY, FOCUS_ALGO , true); 2989 2990 //Disable Region priority and enable Face priority 2991 setAlgoPriority(REGION_PRIORITY, EXPOSURE_ALGO, false); 2992 setAlgoPriority(FACE_PRIORITY, EXPOSURE_ALGO, true); 2993 mFDSwitchAlgoPriority = false; 2994 } 2995 } 2996 } 2997 2998 ///Prepare the frames to be sent - initialize CameraFrame object and reference count 2999 // TODO(XXX): ancillary data for snapshot frame is not being sent for video snapshot 3000 // if we are waiting for a snapshot and in video mode...go ahead and send 3001 // this frame as a snapshot 3002 if( mWaitingForSnapshot && (mCapturedFrames > 0) && 3003 (snapshotFrame || (mCapMode == VIDEO_MODE))) 3004 { 3005 typeOfFrame = CameraFrame::SNAPSHOT_FRAME; 3006 mask = (unsigned int)CameraFrame::SNAPSHOT_FRAME; 3007 3008 // video snapshot gets ancillary data and wb info from last snapshot frame 3009 mCaptureAncillaryData = ancillaryData; 3010 mWhiteBalanceData = NULL; 3011 extraData = getExtradata((OMX_OTHER_EXTRADATATYPE*) platformPrivate->pMetaDataBuffer, 3012 (OMX_EXTRADATATYPE) OMX_WhiteBalance); 3013 if ( NULL != extraData ) 3014 { 3015 mWhiteBalanceData = (OMX_TI_WHITEBALANCERESULTTYPE*) extraData->data; 3016 } 3017 } 3018 else 3019 { 3020 typeOfFrame = CameraFrame::PREVIEW_FRAME_SYNC; 3021 mask = (unsigned int)CameraFrame::PREVIEW_FRAME_SYNC; 3022 } 3023 3024 if (mRecording) 3025 { 3026 mask |= (unsigned int)CameraFrame::VIDEO_FRAME_SYNC; 3027 mFramesWithEncoder++; 3028 } 3029 3030 //ALOGV("FBD pBuffer = 0x%x", pBuffHeader->pBuffer); 3031 3032 if( mWaitingForSnapshot ) 3033 { 3034 mSnapshotCount++; 3035 3036 if ( (mSnapshotCount == 1) && 3037 ((HIGH_SPEED == mCapMode) || (VIDEO_MODE == mCapMode)) ) 3038 { 3039 notifyShutterSubscribers(); 3040 } 3041 } 3042 3043 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3044 mFramesWithDisplay++; 3045 3046 mFramesWithDucati--; 3047 3048#ifdef DEBUG_LOG 3049 if(mBuffersWithDucati.indexOfKey((int)pBuffHeader->pBuffer)<0) 3050 { 3051 ALOGE("Buffer was never with Ducati!! 0x%x", pBuffHeader->pBuffer); 3052 for(int i=0;i<mBuffersWithDucati.size();i++) ALOGE("0x%x", mBuffersWithDucati.keyAt(i)); 3053 } 3054 mBuffersWithDucati.removeItem((int)pBuffHeader->pBuffer); 3055#endif 3056 3057 if(mDebugFcs) 3058 CAMHAL_LOGEB("C[%d] D[%d] E[%d]", mFramesWithDucati, mFramesWithDisplay, mFramesWithEncoder); 3059 3060 stat |= advanceZoom(); 3061 3062 // On the fly update to 3A settings not working 3063 // Do not update 3A here if we are in the middle of a capture 3064 // or in the middle of transitioning to it 3065 if( mPending3Asettings && 3066 ( (nextState & CAPTURE_ACTIVE) == 0 ) && 3067 ( (state & CAPTURE_ACTIVE) == 0 ) ) 3068 { 3069 apply3Asettings(mParameters3A); 3070 } 3071 3072 } 3073 else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT ) 3074 { 3075 typeOfFrame = CameraFrame::FRAME_DATA_SYNC; 3076 mask = (unsigned int)CameraFrame::FRAME_DATA_SYNC; 3077 3078 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3079 } 3080 else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_IMAGE_OUT_IMAGE ) 3081 { 3082 OMX_COLOR_FORMATTYPE pixFormat; 3083 const char *valstr = NULL; 3084 3085 pixFormat = mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat; 3086 valstr = mParams.getPictureFormat(); 3087 3088 if ( OMX_COLOR_FormatUnused == pixFormat ) 3089 { 3090 typeOfFrame = CameraFrame::IMAGE_FRAME; 3091 mask = (unsigned int) CameraFrame::IMAGE_FRAME; 3092 } 3093 else if ( pixFormat == OMX_COLOR_FormatCbYCrY && 3094 ((valstr && !strcmp(valstr, CameraParameters::PIXEL_FORMAT_JPEG)) || 3095 !valstr) ) 3096 { 3097 // signals to callbacks that this needs to be coverted to jpeg 3098 // before returning to framework 3099 typeOfFrame = CameraFrame::IMAGE_FRAME; 3100 mask = (unsigned int) CameraFrame::IMAGE_FRAME; 3101 cameraFrame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG; 3102 3103 // populate exif data and pass to subscribers via quirk 3104 // subscriber is in charge of freeing exif data 3105 ExifElementsTable* exif = new ExifElementsTable(); 3106 setupEXIF_libjpeg(exif, mCaptureAncillaryData, mWhiteBalanceData); 3107 cameraFrame.mQuirks |= CameraFrame::HAS_EXIF_DATA; 3108 cameraFrame.mCookie2 = (void*) exif; 3109 } 3110 else 3111 { 3112 typeOfFrame = CameraFrame::RAW_FRAME; 3113 mask = (unsigned int) CameraFrame::RAW_FRAME; 3114 } 3115 3116 pPortParam->mImageType = typeOfFrame; 3117 3118 if((mCapturedFrames>0) && !mCaptureSignalled) 3119 { 3120 mCaptureSignalled = true; 3121 mCaptureSem.Signal(); 3122 } 3123 3124 if( ( CAPTURE_ACTIVE & state ) != CAPTURE_ACTIVE ) 3125 { 3126 goto EXIT; 3127 } 3128 3129 { 3130 Mutex::Autolock lock(mBracketingLock); 3131 if ( mBracketingEnabled ) 3132 { 3133 doBracketing(pBuffHeader, typeOfFrame); 3134 return eError; 3135 } 3136 } 3137 3138 if ( 1 > mCapturedFrames ) 3139 { 3140 goto EXIT; 3141 } 3142 3143 CAMHAL_LOGDB("Captured Frames: %d", mCapturedFrames); 3144 3145 mCapturedFrames--; 3146 3147 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3148 3149 } 3150 else 3151 { 3152 CAMHAL_LOGEA("Frame received for non-(preview/capture/measure) port. This is yet to be supported"); 3153 goto EXIT; 3154 } 3155 3156 if ( NO_ERROR != stat ) 3157 { 3158 CAMHAL_LOGDB("sendFrameToSubscribers error: %d", stat); 3159 returnFrame(pBuffHeader->pBuffer, typeOfFrame); 3160 } 3161 3162 return eError; 3163 3164 EXIT: 3165 3166 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, stat, eError); 3167 3168 if ( NO_ERROR != stat ) 3169 { 3170 if ( NULL != mErrorNotifier ) 3171 { 3172 mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN); 3173 } 3174 } 3175 3176 return eError; 3177} 3178 3179status_t OMXCameraAdapter::recalculateFPS() 3180{ 3181 float currentFPS; 3182 3183 { 3184 Mutex::Autolock lock(mFrameCountMutex); 3185 mFrameCount++; 3186 if (mFrameCount == 1) { 3187 mFirstFrameCondition.broadcast(); 3188 } 3189 } 3190 3191 if ( ( mFrameCount % FPS_PERIOD ) == 0 ) 3192 { 3193 nsecs_t now = systemTime(); 3194 nsecs_t diff = now - mLastFPSTime; 3195 currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 3196 mLastFPSTime = now; 3197 mLastFrameCount = mFrameCount; 3198 3199 if ( 1 == mIter ) 3200 { 3201 mFPS = currentFPS; 3202 } 3203 else 3204 { 3205 //cumulative moving average 3206 mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter; 3207 } 3208 3209 mLastFPS = mFPS; 3210 mIter++; 3211 } 3212 3213 return NO_ERROR; 3214} 3215 3216status_t OMXCameraAdapter::sendFrame(CameraFrame &frame) 3217{ 3218 status_t ret = NO_ERROR; 3219 3220 LOG_FUNCTION_NAME; 3221 3222 3223 if ( NO_ERROR == ret ) 3224 { 3225 ret = sendFrameToSubscribers(&frame); 3226 } 3227 3228 LOG_FUNCTION_NAME_EXIT; 3229 3230 return ret; 3231} 3232 3233status_t OMXCameraAdapter::sendCallBacks(CameraFrame frame, OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader, unsigned int mask, OMXCameraPortParameters *port) 3234{ 3235 status_t ret = NO_ERROR; 3236 3237 LOG_FUNCTION_NAME; 3238 3239 if ( NULL == port) 3240 { 3241 CAMHAL_LOGEA("Invalid portParam"); 3242 return -EINVAL; 3243 } 3244 3245 if ( NULL == pBuffHeader ) 3246 { 3247 CAMHAL_LOGEA("Invalid Buffer header"); 3248 return -EINVAL; 3249 } 3250 3251 Mutex::Autolock lock(mSubscriberLock); 3252 3253 //frame.mFrameType = typeOfFrame; 3254 frame.mFrameMask = mask; 3255 frame.mBuffer = pBuffHeader->pBuffer; 3256 frame.mLength = pBuffHeader->nFilledLen; 3257 frame.mAlignment = port->mStride; 3258 frame.mOffset = pBuffHeader->nOffset; 3259 frame.mWidth = port->mWidth; 3260 frame.mHeight = port->mHeight; 3261 frame.mYuv[0] = NULL; 3262 frame.mYuv[1] = NULL; 3263 3264 if ( onlyOnce && mRecording ) 3265 { 3266 mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC); 3267 onlyOnce = false; 3268 } 3269 3270 frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta; 3271 3272 ret = setInitFrameRefCount(frame.mBuffer, mask); 3273 3274 if (ret != NO_ERROR) { 3275 CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret); 3276 } else { 3277 ret = sendFrameToSubscribers(&frame); 3278 } 3279 3280 CAMHAL_LOGVB("B 0x%x T %llu", frame.mBuffer, pBuffHeader->nTimeStamp); 3281 3282 LOG_FUNCTION_NAME_EXIT; 3283 3284 return ret; 3285} 3286 3287status_t OMXCameraAdapter::initCameraFrame( CameraFrame &frame, 3288 OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader, 3289 int typeOfFrame, 3290 OMXCameraPortParameters *port) 3291{ 3292 status_t ret = NO_ERROR; 3293 3294 LOG_FUNCTION_NAME; 3295 3296 if ( NULL == port) 3297 { 3298 CAMHAL_LOGEA("Invalid portParam"); 3299 return -EINVAL; 3300 } 3301 3302 if ( NULL == pBuffHeader ) 3303 { 3304 CAMHAL_LOGEA("Invalid Buffer header"); 3305 return -EINVAL; 3306 } 3307 3308 frame.mFrameType = typeOfFrame; 3309 frame.mBuffer = pBuffHeader->pBuffer; 3310 frame.mLength = pBuffHeader->nFilledLen; 3311 frame.mAlignment = port->mStride; 3312 frame.mOffset = pBuffHeader->nOffset; 3313 frame.mWidth = port->mWidth; 3314 frame.mHeight = port->mHeight; 3315 3316 // Timestamp in pBuffHeader->nTimeStamp is derived on DUCATI side, which is 3317 // is not same time value as derived using systemTime. It would be ideal to use 3318 // exactly same time source across Android and Ducati, which is limited by 3319 // system now. So, workaround for now is to find the time offset between the two 3320 // time sources and compensate the difference, along with the latency involved 3321 // in camera buffer reaching CameraHal. Also, Do timeset offset calculation only 3322 // when recording is in progress, when nTimestamp will be populated by Camera 3323 if ( onlyOnce && mRecording ) 3324 { 3325 mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC); 3326 mTimeSourceDelta += kCameraBufferLatencyNs; 3327 onlyOnce = false; 3328 } 3329 3330 // Calculating the new video timestamp based on offset from ducati source. 3331 frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta; 3332 3333 LOG_FUNCTION_NAME_EXIT; 3334 3335 return ret; 3336} 3337 3338bool OMXCameraAdapter::CommandHandler::Handler() 3339{ 3340 TIUTILS::Message msg; 3341 volatile int forever = 1; 3342 status_t stat; 3343 ErrorNotifier *errorNotify = NULL; 3344 3345 LOG_FUNCTION_NAME; 3346 3347 while ( forever ) 3348 { 3349 stat = NO_ERROR; 3350 CAMHAL_LOGDA("Handler: waiting for messsage..."); 3351 TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1); 3352 { 3353 Mutex::Autolock lock(mLock); 3354 mCommandMsgQ.get(&msg); 3355 } 3356 CAMHAL_LOGDB("msg.command = %d", msg.command); 3357 switch ( msg.command ) { 3358 case CommandHandler::CAMERA_START_IMAGE_CAPTURE: 3359 { 3360 stat = mCameraAdapter->startImageCapture(); 3361 break; 3362 } 3363 case CommandHandler::CAMERA_PERFORM_AUTOFOCUS: 3364 { 3365 stat = mCameraAdapter->doAutoFocus(); 3366 break; 3367 } 3368 case CommandHandler::COMMAND_EXIT: 3369 { 3370 CAMHAL_LOGDA("Exiting command handler"); 3371 forever = 0; 3372 break; 3373 } 3374 case CommandHandler::CAMERA_SWITCH_TO_EXECUTING: 3375 { 3376 stat = mCameraAdapter->doSwitchToExecuting(); 3377 break; 3378 } 3379 } 3380 3381 } 3382 3383 LOG_FUNCTION_NAME_EXIT; 3384 3385 return false; 3386} 3387 3388bool OMXCameraAdapter::OMXCallbackHandler::Handler() 3389{ 3390 TIUTILS::Message msg; 3391 volatile int forever = 1; 3392 status_t ret = NO_ERROR; 3393 3394 LOG_FUNCTION_NAME; 3395 3396 while(forever){ 3397 TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1); 3398 { 3399 Mutex::Autolock lock(mLock); 3400 mCommandMsgQ.get(&msg); 3401 } 3402 3403 switch ( msg.command ) { 3404 case OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE: 3405 { 3406 ret = mCameraAdapter->OMXCameraAdapterFillBufferDone(( OMX_HANDLETYPE ) msg.arg1, 3407 ( OMX_BUFFERHEADERTYPE *) msg.arg2); 3408 break; 3409 } 3410 case OMXCallbackHandler::CAMERA_FOCUS_STATUS: 3411 { 3412 mCameraAdapter->handleFocusCallback(); 3413 break; 3414 } 3415 case CommandHandler::COMMAND_EXIT: 3416 { 3417 CAMHAL_LOGDA("Exiting OMX callback handler"); 3418 forever = 0; 3419 break; 3420 } 3421 } 3422 } 3423 3424 LOG_FUNCTION_NAME_EXIT; 3425 return false; 3426} 3427 3428status_t OMXCameraAdapter::setExtraData(bool enable, OMX_U32 nPortIndex, OMX_EXT_EXTRADATATYPE eType) { 3429 status_t ret = NO_ERROR; 3430 OMX_ERRORTYPE eError = OMX_ErrorNone; 3431 OMX_CONFIG_EXTRADATATYPE extraDataControl; 3432 3433 LOG_FUNCTION_NAME; 3434 3435 if ( ( OMX_StateInvalid == mComponentState ) || 3436 ( NULL == mCameraAdapterParameters.mHandleComp ) ) { 3437 CAMHAL_LOGEA("OMX component is in invalid state"); 3438 return -EINVAL; 3439 } 3440 3441 OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE); 3442 3443 extraDataControl.nPortIndex = nPortIndex; 3444 extraDataControl.eExtraDataType = eType; 3445 extraDataControl.eCameraView = OMX_2D; 3446 3447 if (enable) { 3448 extraDataControl.bEnable = OMX_TRUE; 3449 } else { 3450 extraDataControl.bEnable = OMX_FALSE; 3451 } 3452 3453 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 3454 (OMX_INDEXTYPE) OMX_IndexConfigOtherExtraDataControl, 3455 &extraDataControl); 3456 3457 LOG_FUNCTION_NAME_EXIT; 3458 3459 return (ret | ErrorUtils::omxToAndroidError(eError)); 3460} 3461 3462 3463OMX_OTHER_EXTRADATATYPE *OMXCameraAdapter::getExtradata(OMX_OTHER_EXTRADATATYPE *extraData, OMX_EXTRADATATYPE type) 3464{ 3465 if ( NULL != extraData ) 3466 { 3467 while ( extraData->nDataSize != 0 ) 3468 { 3469 if ( type == extraData->eType ) 3470 { 3471 return extraData; 3472 } 3473 extraData = (OMX_OTHER_EXTRADATATYPE*) ((char*)extraData + extraData->nSize); 3474 } 3475 } 3476 // Required extradata type wasn't found 3477 return NULL; 3478} 3479 3480OMXCameraAdapter::OMXCameraAdapter(size_t sensor_index) 3481{ 3482 LOG_FUNCTION_NAME; 3483 3484 mOmxInitialized = false; 3485 mComponentState = OMX_StateInvalid; 3486 mSensorIndex = sensor_index; 3487 mPictureRotation = 0; 3488 // Initial values 3489 mTimeSourceDelta = 0; 3490 onlyOnce = true; 3491 3492 mInitSem.Create(0); 3493 mFlushSem.Create(0); 3494 mUsePreviewDataSem.Create(0); 3495 mUsePreviewSem.Create(0); 3496 mUseCaptureSem.Create(0); 3497 mStartPreviewSem.Create(0); 3498 mStopPreviewSem.Create(0); 3499 mStartCaptureSem.Create(0); 3500 mStopCaptureSem.Create(0); 3501 mSwitchToLoadedSem.Create(0); 3502 mCaptureSem.Create(0); 3503 3504 mSwitchToExecSem.Create(0); 3505 3506 mCameraAdapterParameters.mHandleComp = 0; 3507 3508 mUserSetExpLock = OMX_FALSE; 3509 mUserSetWbLock = OMX_FALSE; 3510 3511 mFramesWithDucati = 0; 3512 mFramesWithDisplay = 0; 3513 mFramesWithEncoder = 0; 3514 3515 LOG_FUNCTION_NAME_EXIT; 3516} 3517 3518OMXCameraAdapter::~OMXCameraAdapter() 3519{ 3520 LOG_FUNCTION_NAME; 3521 3522 Mutex::Autolock lock(gAdapterLock); 3523 3524 if ( mOmxInitialized ) { 3525 // return to OMX Loaded state 3526 switchToLoaded(); 3527 3528 // deinit the OMX 3529 if ( mComponentState == OMX_StateLoaded || mComponentState == OMX_StateInvalid ) { 3530 // free the handle for the Camera component 3531 if ( mCameraAdapterParameters.mHandleComp ) { 3532 OMX_FreeHandle(mCameraAdapterParameters.mHandleComp); 3533 mCameraAdapterParameters.mHandleComp = NULL; 3534 } 3535 } 3536 3537 OMX_Deinit(); 3538 mOmxInitialized = false; 3539 } 3540 3541 //Remove any unhandled events 3542 if ( !mEventSignalQ.isEmpty() ) 3543 { 3544 for (unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ ) 3545 { 3546 TIUTILS::Message *msg = mEventSignalQ.itemAt(i); 3547 //remove from queue and free msg 3548 if ( NULL != msg ) 3549 { 3550 Semaphore *sem = (Semaphore*) msg->arg3; 3551 sem->Signal(); 3552 free(msg); 3553 3554 } 3555 } 3556 mEventSignalQ.clear(); 3557 } 3558 3559 //Exit and free ref to command handling thread 3560 if ( NULL != mCommandHandler.get() ) 3561 { 3562 TIUTILS::Message msg; 3563 msg.command = CommandHandler::COMMAND_EXIT; 3564 msg.arg1 = mErrorNotifier; 3565 mCommandHandler->clearCommandQ(); 3566 mCommandHandler->put(&msg); 3567 mCommandHandler->requestExitAndWait(); 3568 mCommandHandler.clear(); 3569 } 3570 3571 //Exit and free ref to callback handling thread 3572 if ( NULL != mOMXCallbackHandler.get() ) 3573 { 3574 TIUTILS::Message msg; 3575 msg.command = OMXCallbackHandler::COMMAND_EXIT; 3576 //Clear all messages pending first 3577 mOMXCallbackHandler->clearCommandQ(); 3578 mOMXCallbackHandler->put(&msg); 3579 mOMXCallbackHandler->requestExitAndWait(); 3580 mOMXCallbackHandler.clear(); 3581 } 3582 3583 LOG_FUNCTION_NAME_EXIT; 3584} 3585 3586extern "C" CameraAdapter* CameraAdapter_Factory(size_t sensor_index) 3587{ 3588 CameraAdapter *adapter = NULL; 3589 Mutex::Autolock lock(gAdapterLock); 3590 3591 LOG_FUNCTION_NAME; 3592 3593 adapter = new OMXCameraAdapter(sensor_index); 3594 if ( adapter ) { 3595 CAMHAL_LOGDB("New OMX Camera adapter instance created for sensor %d",sensor_index); 3596 } else { 3597 CAMHAL_LOGEA("Camera adapter create failed!"); 3598 } 3599 3600 LOG_FUNCTION_NAME_EXIT; 3601 3602 return adapter; 3603} 3604 3605OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE *handle, OMX_PTR pAppData ) 3606{ 3607 OMX_ERRORTYPE eError = OMX_ErrorUndefined; 3608 3609 for ( int i = 0; i < 5; ++i ) { 3610 if ( i > 0 ) { 3611 // sleep for 100 ms before next attempt 3612 usleep(100000); 3613 } 3614 3615 // setup key parameters to send to Ducati during init 3616 OMX_CALLBACKTYPE oCallbacks; 3617 3618 // initialize the callback handles 3619 oCallbacks.EventHandler = android::OMXCameraAdapterEventHandler; 3620 oCallbacks.EmptyBufferDone = android::OMXCameraAdapterEmptyBufferDone; 3621 oCallbacks.FillBufferDone = android::OMXCameraAdapterFillBufferDone; 3622 3623 // get handle 3624 eError = OMX_GetHandle(handle, (OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA", pAppData, &oCallbacks); 3625 if ( eError == OMX_ErrorNone ) { 3626 return OMX_ErrorNone; 3627 } 3628 3629 CAMHAL_LOGEB("OMX_GetHandle() failed, error: 0x%x", eError); 3630 } 3631 3632 *handle = 0; 3633 return eError; 3634} 3635 3636extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array, 3637 const unsigned int starting_camera, 3638 const unsigned int max_camera) { 3639 int num_cameras_supported = 0; 3640 CameraProperties::Properties* properties = NULL; 3641 OMX_ERRORTYPE eError = OMX_ErrorNone; 3642 OMX_HANDLETYPE handle = NULL; 3643 OMX_TI_CAPTYPE caps; 3644 3645 LOG_FUNCTION_NAME; 3646 3647 Mutex::Autolock lock(gAdapterLock); 3648 3649 if (!properties_array) { 3650 CAMHAL_LOGEB("invalid param: properties = 0x%p", properties_array); 3651 LOG_FUNCTION_NAME_EXIT; 3652 return -EINVAL; 3653 } 3654 3655 eError = OMX_Init(); 3656 if (eError != OMX_ErrorNone) { 3657 CAMHAL_LOGEB("Error OMX_Init -0x%x", eError); 3658 return eError; 3659 } 3660 3661 eError = OMXCameraAdapter::OMXCameraGetHandle(&handle); 3662 if (eError != OMX_ErrorNone) { 3663 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError); 3664 goto EXIT; 3665 } 3666 3667 // Continue selecting sensor and then querying OMX Camera for it's capabilities 3668 // When sensor select returns an error, we know to break and stop 3669 while (eError == OMX_ErrorNone && 3670 (starting_camera + num_cameras_supported) < max_camera) { 3671 // sensor select 3672 OMX_CONFIG_SENSORSELECTTYPE sensorSelect; 3673 OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE); 3674 sensorSelect.eSensor = (OMX_SENSORSELECT) num_cameras_supported; 3675 eError = OMX_SetConfig(handle, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect); 3676 3677 if ( OMX_ErrorNone != eError ) { 3678 break; 3679 } 3680 3681 // get and fill capabilities 3682 properties = properties_array + starting_camera + num_cameras_supported; 3683 OMXCameraAdapter::getCaps(properties, handle); 3684 3685 // need to fill facing information 3686 // assume that only sensor 0 is back facing 3687 if (num_cameras_supported == 0) { 3688 properties->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_BACK); 3689 } else { 3690 properties->set(CameraProperties::FACING_INDEX, TICameraParameters::FACING_FRONT); 3691 } 3692 3693 num_cameras_supported++; 3694 } 3695 3696 EXIT: 3697 // clean up 3698 if(handle) { 3699 OMX_FreeHandle(handle); 3700 handle=NULL; 3701 } 3702 OMX_Deinit(); 3703 3704 LOG_FUNCTION_NAME_EXIT; 3705 3706 return num_cameras_supported; 3707} 3708 3709}; 3710 3711 3712/*--------------------Camera Adapter Class ENDS here-----------------------------*/ 3713