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 "OMXDCC.h" 27 #include "ErrorUtils.h" 28 #include "TICameraParameters.h" 29 #include <signal.h> 30 #include <math.h> 31 32 #include <cutils/properties.h> 33 #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 34 static int mDebugFps = 0; 35 static int mDebugFcs = 0; 36 37 #define HERE(Msg) {CAMHAL_LOGEB("--===line %d, %s===--\n", __LINE__, Msg);} 38 39 namespace Ti { 40 namespace Camera { 41 42 #ifdef CAMERAHAL_OMX_PROFILING 43 44 const char OMXCameraAdapter::DEFAULT_PROFILE_PATH[] = "/data/dbg/profile_data.bin"; 45 46 #endif 47 48 //frames skipped before recalculating the framerate 49 #define FPS_PERIOD 30 50 51 android::Mutex gAdapterLock; 52 /*--------------------Camera Adapter Class STARTS here-----------------------------*/ 53 54 status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps) 55 { 56 LOG_FUNCTION_NAME; 57 58 char value[PROPERTY_VALUE_MAX]; 59 const char *mountOrientationString = NULL; 60 61 property_get("debug.camera.showfps", value, "0"); 62 mDebugFps = atoi(value); 63 property_get("debug.camera.framecounts", value, "0"); 64 mDebugFcs = atoi(value); 65 66 #ifdef CAMERAHAL_OMX_PROFILING 67 68 property_get("debug.camera.profile", value, "0"); 69 mDebugProfile = atoi(value); 70 71 #endif 72 73 TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone; 74 OMX_ERRORTYPE eError = OMX_ErrorNone; 75 status_t ret = NO_ERROR; 76 77 mLocalVersionParam.s.nVersionMajor = 0x1; 78 mLocalVersionParam.s.nVersionMinor = 0x1; 79 mLocalVersionParam.s.nRevision = 0x0 ; 80 mLocalVersionParam.s.nStep = 0x0; 81 82 mPending3Asettings = 0;//E3AsettingsAll; 83 mPendingCaptureSettings = 0; 84 mPendingPreviewSettings = 0; 85 mPendingReprocessSettings = 0; 86 87 ret = mMemMgr.initialize(); 88 if ( ret != OK ) { 89 CAMHAL_LOGE("MemoryManager initialization failed, error: %d", ret); 90 return ret; 91 } 92 93 if ( 0 != mInitSem.Count() ) 94 { 95 CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count()); 96 LOG_FUNCTION_NAME_EXIT; 97 return NO_INIT; 98 } 99 100 ///Update the preview and image capture port indexes 101 mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW; 102 // temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE; 103 mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE; 104 mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT; 105 //currently not supported use preview port instead 106 mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_VIDEO; 107 mCameraAdapterParameters.mVideoInPortIndex = OMX_CAMERA_PORT_VIDEO_IN_VIDEO; 108 109 eError = OMX_Init(); 110 if (eError != OMX_ErrorNone) { 111 CAMHAL_LOGEB("OMX_Init() failed, error: 0x%x", eError); 112 return Utils::ErrorUtils::omxToAndroidError(eError); 113 } 114 mOmxInitialized = true; 115 116 // Initialize the callback handles 117 OMX_CALLBACKTYPE callbacks; 118 callbacks.EventHandler = Camera::OMXCameraAdapterEventHandler; 119 callbacks.EmptyBufferDone = Camera::OMXCameraAdapterEmptyBufferDone; 120 callbacks.FillBufferDone = Camera::OMXCameraAdapterFillBufferDone; 121 122 ///Get the handle to the OMX Component 123 eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, this, callbacks); 124 if(eError != OMX_ErrorNone) { 125 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError); 126 } 127 GOTO_EXIT_IF((eError != OMX_ErrorNone), eError); 128 129 mComponentState = OMX_StateLoaded; 130 131 CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex); 132 initDccFileDataSave(&mCameraAdapterParameters.mHandleComp, mCameraAdapterParameters.mPrevPortIndex); 133 134 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 135 OMX_CommandPortDisable, 136 OMX_ALL, 137 NULL); 138 139 if(eError != OMX_ErrorNone) { 140 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError); 141 } 142 GOTO_EXIT_IF((eError != OMX_ErrorNone), eError); 143 144 // Register for port enable event 145 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 146 OMX_EventCmdComplete, 147 OMX_CommandPortEnable, 148 mCameraAdapterParameters.mPrevPortIndex, 149 mInitSem); 150 if(ret != NO_ERROR) { 151 CAMHAL_LOGEB("Error in registering for event %d", ret); 152 goto EXIT; 153 } 154 155 // Enable PREVIEW Port 156 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 157 OMX_CommandPortEnable, 158 mCameraAdapterParameters.mPrevPortIndex, 159 NULL); 160 if(eError != OMX_ErrorNone) { 161 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 162 } 163 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 164 165 // Wait for the port enable event to occur 166 ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT); 167 if ( NO_ERROR == ret ) { 168 CAMHAL_LOGDA("-Port enable event arrived"); 169 } else { 170 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 171 OMX_EventCmdComplete, 172 OMX_CommandPortEnable, 173 mCameraAdapterParameters.mPrevPortIndex, 174 NULL); 175 CAMHAL_LOGEA("Timeout for enabling preview port expired!"); 176 goto EXIT; 177 } 178 179 // Select the sensor 180 OMX_CONFIG_SENSORSELECTTYPE sensorSelect; 181 OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE); 182 sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex; 183 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect); 184 if ( OMX_ErrorNone != eError ) { 185 CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError); 186 return BAD_VALUE; 187 } else { 188 CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex); 189 } 190 191 #ifdef CAMERAHAL_DEBUG 192 193 printComponentVersion(mCameraAdapterParameters.mHandleComp); 194 195 #endif 196 197 mBracketingEnabled = false; 198 mZoomBracketingEnabled = false; 199 mBracketingBuffersQueuedCount = 0; 200 mBracketingRange = 1; 201 mLastBracetingBufferIdx = 0; 202 mBracketingBuffersQueued = NULL; 203 mOMXStateSwitch = false; 204 mBracketingSet = false; 205 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 206 mRawCapture = false; 207 mYuvCapture = false; 208 #endif 209 210 mCaptureSignalled = false; 211 mCaptureConfigured = false; 212 mReprocConfigured = false; 213 mRecording = false; 214 mWaitingForSnapshot = false; 215 mPictureFormatFromClient = NULL; 216 217 mCapabilitiesOpMode = MODE_MAX; 218 mCapMode = INITIAL_MODE; 219 mIPP = IPP_NULL; 220 mVstabEnabled = false; 221 mVnfEnabled = false; 222 mBurstFrames = 1; 223 mFlushShotConfigQueue = false; 224 mPictureQuality = 100; 225 mCurrentZoomIdx = 0; 226 mTargetZoomIdx = 0; 227 mPreviousZoomIndx = 0; 228 mReturnZoomStatus = false; 229 mZoomInc = 1; 230 mZoomParameterIdx = 0; 231 mExposureBracketingValidEntries = 0; 232 mZoomBracketingValidEntries = 0; 233 mSensorOverclock = false; 234 mAutoConv = OMX_TI_AutoConvergenceModeMax; 235 mManualConv = 0; 236 237 #ifdef CAMERAHAL_TUNA 238 mIternalRecordingHint = false; 239 #endif 240 241 mDeviceOrientation = 0; 242 mFaceOrientation = 0; 243 mCapabilities = caps; 244 mZoomUpdating = false; 245 mZoomUpdate = false; 246 mGBCE = BRIGHTNESS_OFF; 247 mGLBCE = BRIGHTNESS_OFF; 248 mParameters3A.ExposureLock = OMX_FALSE; 249 mParameters3A.WhiteBalanceLock = OMX_FALSE; 250 251 mEXIFData.mGPSData.mAltitudeValid = false; 252 mEXIFData.mGPSData.mDatestampValid = false; 253 mEXIFData.mGPSData.mLatValid = false; 254 mEXIFData.mGPSData.mLongValid = false; 255 mEXIFData.mGPSData.mMapDatumValid = false; 256 mEXIFData.mGPSData.mProcMethodValid = false; 257 mEXIFData.mGPSData.mVersionIdValid = false; 258 mEXIFData.mGPSData.mTimeStampValid = false; 259 mEXIFData.mModelValid = false; 260 mEXIFData.mMakeValid = false; 261 262 mCapturedFrames = 0; 263 mBurstFramesAccum = 0; 264 mBurstFramesQueued = 0; 265 266 //update the mDeviceOrientation with the sensor mount orientation. 267 //So that the face detect will work before onOrientationEvent() 268 //get triggered. 269 CAMHAL_ASSERT(mCapabilities); 270 mountOrientationString = mCapabilities->get(CameraProperties::ORIENTATION_INDEX); 271 CAMHAL_ASSERT(mountOrientationString); 272 mDeviceOrientation = atoi(mountOrientationString); 273 mFaceOrientation = atoi(mountOrientationString); 274 275 if (mSensorIndex != 2) { 276 mCapabilities->setMode(MODE_HIGH_SPEED); 277 } 278 279 if (mCapabilities->get(CameraProperties::SUPPORTED_ZOOM_STAGES) != NULL) { 280 mMaxZoomSupported = mCapabilities->getInt(CameraProperties::SUPPORTED_ZOOM_STAGES) + 1; 281 } else { 282 mMaxZoomSupported = 1; 283 } 284 285 // initialize command handling thread 286 if(mCommandHandler.get() == NULL) 287 mCommandHandler = new CommandHandler(this); 288 289 if ( NULL == mCommandHandler.get() ) 290 { 291 CAMHAL_LOGEA("Couldn't create command handler"); 292 return NO_MEMORY; 293 } 294 295 ret = mCommandHandler->run("CallbackThread", android::PRIORITY_URGENT_DISPLAY); 296 if ( ret != NO_ERROR ) 297 { 298 if( ret == INVALID_OPERATION){ 299 CAMHAL_LOGDA("command handler thread already runnning!!"); 300 ret = NO_ERROR; 301 } else { 302 CAMHAL_LOGEA("Couldn't run command handlerthread"); 303 return ret; 304 } 305 } 306 307 // initialize omx callback handling thread 308 if(mOMXCallbackHandler.get() == NULL) 309 mOMXCallbackHandler = new OMXCallbackHandler(this); 310 311 if ( NULL == mOMXCallbackHandler.get() ) 312 { 313 CAMHAL_LOGEA("Couldn't create omx callback handler"); 314 return NO_MEMORY; 315 } 316 317 ret = mOMXCallbackHandler->run("OMXCallbackThread", android::PRIORITY_URGENT_DISPLAY); 318 if ( ret != NO_ERROR ) 319 { 320 if( ret == INVALID_OPERATION){ 321 CAMHAL_LOGDA("omx callback handler thread already runnning!!"); 322 ret = NO_ERROR; 323 } else { 324 CAMHAL_LOGEA("Couldn't run omx callback handler thread"); 325 return ret; 326 } 327 } 328 329 OMX_INIT_STRUCT_PTR (&mRegionPriority, OMX_TI_CONFIG_3A_REGION_PRIORITY); 330 OMX_INIT_STRUCT_PTR (&mFacePriority, OMX_TI_CONFIG_3A_FACE_PRIORITY); 331 mRegionPriority.nPortIndex = OMX_ALL; 332 mFacePriority.nPortIndex = OMX_ALL; 333 334 //Setting this flag will that the first setParameter call will apply all 3A settings 335 //and will not conditionally apply based on current values. 336 mFirstTimeInit = true; 337 338 //Flag to avoid calling setVFramerate() before OMX_SetParameter(OMX_IndexParamPortDefinition) 339 //Ducati will return an error otherwise. 340 mSetFormatDone = false; 341 342 memset(mExposureBracketingValues, 0, EXP_BRACKET_RANGE*sizeof(int)); 343 memset(mZoomBracketingValues, 0, ZOOM_BRACKET_RANGE*sizeof(int)); 344 mMeasurementEnabled = false; 345 mFaceDetectionRunning = false; 346 mFaceDetectionPaused = false; 347 mFDSwitchAlgoPriority = false; 348 349 metadataLastAnalogGain = -1; 350 metadataLastExposureTime = -1; 351 352 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters)); 353 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters)); 354 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex], 0, sizeof(OMXCameraPortParameters)); 355 memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex], 0, sizeof(OMXCameraPortParameters)); 356 357 // initialize 3A defaults 358 mParameters3A.Effect = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EFFECT, EffLUT); 359 mParameters3A.FlashMode = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_FLASH_MODE, FlashLUT); 360 mParameters3A.SceneMode = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_SCENE_MODE, SceneLUT); 361 mParameters3A.EVCompensation = atoi(OMXCameraAdapter::DEFAULT_EV_COMPENSATION); 362 mParameters3A.Focus = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_FOCUS_MODE, FocusLUT); 363 mParameters3A.ISO = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_ISO_MODE, IsoLUT); 364 mParameters3A.Flicker = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_ANTIBANDING, FlickerLUT); 365 mParameters3A.Brightness = atoi(OMXCameraAdapter::DEFAULT_BRIGHTNESS); 366 mParameters3A.Saturation = atoi(OMXCameraAdapter::DEFAULT_SATURATION) - SATURATION_OFFSET; 367 mParameters3A.Sharpness = atoi(OMXCameraAdapter::DEFAULT_SHARPNESS) - SHARPNESS_OFFSET; 368 mParameters3A.Contrast = atoi(OMXCameraAdapter::DEFAULT_CONTRAST) - CONTRAST_OFFSET; 369 mParameters3A.WhiteBallance = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_WB, WBalLUT); 370 mParameters3A.Exposure = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EXPOSURE_MODE, ExpLUT); 371 mParameters3A.ExposureLock = OMX_FALSE; 372 mParameters3A.FocusLock = OMX_FALSE; 373 mParameters3A.WhiteBalanceLock = OMX_FALSE; 374 375 mParameters3A.ManualExposure = 0; 376 mParameters3A.ManualExposureRight = 0; 377 mParameters3A.ManualGain = 0; 378 mParameters3A.ManualGainRight = 0; 379 380 mParameters3A.AlgoExternalGamma = OMX_FALSE; 381 mParameters3A.AlgoNSF1 = OMX_TRUE; 382 mParameters3A.AlgoNSF2 = OMX_TRUE; 383 mParameters3A.AlgoSharpening = OMX_TRUE; 384 mParameters3A.AlgoThreeLinColorMap = OMX_TRUE; 385 mParameters3A.AlgoGIC = OMX_TRUE; 386 memset(&mParameters3A.mGammaTable, 0, sizeof(mParameters3A.mGammaTable)); 387 388 LOG_FUNCTION_NAME_EXIT; 389 return Utils::ErrorUtils::omxToAndroidError(eError); 390 391 EXIT: 392 393 CAMHAL_LOGDB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 394 performCleanupAfterError(); 395 LOG_FUNCTION_NAME_EXIT; 396 return Utils::ErrorUtils::omxToAndroidError(eError); 397 } 398 399 void OMXCameraAdapter::performCleanupAfterError() 400 { 401 if(mCameraAdapterParameters.mHandleComp) 402 { 403 ///Free the OMX component handle in case of error 404 OMX_FreeHandle(mCameraAdapterParameters.mHandleComp); 405 mCameraAdapterParameters.mHandleComp = NULL; 406 } 407 408 ///De-init the OMX 409 OMX_Deinit(); 410 mComponentState = OMX_StateInvalid; 411 } 412 413 OMXCameraAdapter::OMXCameraPortParameters *OMXCameraAdapter::getPortParams(CameraFrame::FrameType frameType) 414 { 415 OMXCameraAdapter::OMXCameraPortParameters *ret = NULL; 416 417 switch ( frameType ) 418 { 419 case CameraFrame::IMAGE_FRAME: 420 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 421 break; 422 case CameraFrame::RAW_FRAME: 423 if (mRawCapture) { 424 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; 425 } else { 426 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 427 } 428 break; 429 case CameraFrame::PREVIEW_FRAME_SYNC: 430 case CameraFrame::SNAPSHOT_FRAME: 431 case CameraFrame::VIDEO_FRAME_SYNC: 432 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 433 break; 434 case CameraFrame::FRAME_DATA_SYNC: 435 ret = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 436 break; 437 default: 438 break; 439 }; 440 441 return ret; 442 } 443 444 status_t OMXCameraAdapter::fillThisBuffer(CameraBuffer * frameBuf, CameraFrame::FrameType frameType) 445 { 446 LOG_FUNCTION_NAME; 447 448 status_t ret = NO_ERROR; 449 OMXCameraPortParameters *port = NULL; 450 OMX_ERRORTYPE eError = OMX_ErrorNone; 451 BaseCameraAdapter::AdapterState state; 452 BaseCameraAdapter::getState(state); 453 bool isCaptureFrame = false; 454 455 if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE ) 456 { 457 return NO_INIT; 458 } 459 460 if ( NULL == frameBuf ) 461 { 462 return -EINVAL; 463 } 464 465 isCaptureFrame = (CameraFrame::IMAGE_FRAME == frameType) || 466 (CameraFrame::RAW_FRAME == frameType); 467 468 if ( NO_ERROR == ret ) 469 { 470 port = getPortParams(frameType); 471 if ( NULL == port ) 472 { 473 CAMHAL_LOGEB("Invalid frameType 0x%x", frameType); 474 ret = -EINVAL; 475 } 476 } 477 478 if ( NO_ERROR == ret ) { 479 for ( int i = 0 ; i < port->mNumBufs ; i++) { 480 if ((CameraBuffer *) port->mBufferHeader[i]->pAppPrivate == frameBuf) { 481 if ( isCaptureFrame && !mBracketingEnabled ) { 482 android::AutoMutex lock(mBurstLock); 483 if ((1 > mCapturedFrames) && !mBracketingEnabled && (mCapMode != CP_CAM)) { 484 // Signal end of image capture 485 if ( NULL != mEndImageCaptureCallback) { 486 mEndImageCaptureCallback(mEndCaptureData); 487 } 488 port->mStatus[i] = OMXCameraPortParameters::IDLE; 489 return NO_ERROR; 490 } else if (mBurstFramesQueued >= mBurstFramesAccum) { 491 port->mStatus[i] = OMXCameraPortParameters::IDLE; 492 return NO_ERROR; 493 } 494 mBurstFramesQueued++; 495 } 496 port->mStatus[i] = OMXCameraPortParameters::FILL; 497 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, port->mBufferHeader[i]); 498 if ( eError != OMX_ErrorNone ) 499 { 500 CAMHAL_LOGEB("OMX_FillThisBuffer 0x%x", eError); 501 goto EXIT; 502 } 503 mFramesWithDucati++; 504 break; 505 } 506 } 507 } 508 509 LOG_FUNCTION_NAME_EXIT; 510 return ret; 511 512 EXIT: 513 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 514 performCleanupAfterError(); 515 //Since fillthisbuffer is called asynchronously, make sure to signal error to the app 516 mErrorNotifier->errorNotify(CAMERA_ERROR_HARD); 517 LOG_FUNCTION_NAME_EXIT; 518 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 519 } 520 521 void OMXCameraAdapter::setParamS3D(OMX_U32 port, const char *valstr) 522 { 523 OMXCameraPortParameters *cap; 524 525 LOG_FUNCTION_NAME; 526 527 cap = &mCameraAdapterParameters.mCameraPortParams[port]; 528 if (valstr != NULL) 529 { 530 if (strcmp(valstr, TICameraParameters::S3D_TB_FULL) == 0) 531 { 532 cap->mFrameLayoutType = OMX_TI_StereoFrameLayoutTopBottom; 533 } 534 else if (strcmp(valstr, TICameraParameters::S3D_SS_FULL) == 0) 535 { 536 cap->mFrameLayoutType = OMX_TI_StereoFrameLayoutLeftRight; 537 } 538 else if (strcmp(valstr, TICameraParameters::S3D_TB_SUBSAMPLED) == 0) 539 { 540 cap->mFrameLayoutType = OMX_TI_StereoFrameLayoutTopBottomSubsample; 541 } 542 else if (strcmp(valstr, TICameraParameters::S3D_SS_SUBSAMPLED) == 0) 543 { 544 cap->mFrameLayoutType = OMX_TI_StereoFrameLayoutLeftRightSubsample; 545 } 546 else 547 { 548 cap->mFrameLayoutType = OMX_TI_StereoFrameLayout2D; 549 } 550 } 551 else 552 { 553 cap->mFrameLayoutType = OMX_TI_StereoFrameLayout2D; 554 } 555 556 LOG_FUNCTION_NAME_EXIT; 557 } 558 559 status_t OMXCameraAdapter::setParameters(const android::CameraParameters ¶ms) 560 { 561 LOG_FUNCTION_NAME; 562 563 int mode = 0; 564 status_t ret = NO_ERROR; 565 bool updateImagePortParams = false; 566 int minFramerate, maxFramerate, frameRate; 567 const char *valstr = NULL; 568 int w, h; 569 OMX_COLOR_FORMATTYPE pixFormat; 570 BaseCameraAdapter::AdapterState state; 571 BaseCameraAdapter::getState(state); 572 573 ///@todo Include more camera parameters 574 if ( (valstr = params.getPreviewFormat()) != NULL ) { 575 if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || 576 strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420P) == 0 || 577 strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { 578 CAMHAL_LOGDA("YUV420SP format selected"); 579 pixFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; 580 } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) { 581 CAMHAL_LOGDA("RGB565 format selected"); 582 pixFormat = OMX_COLOR_Format16bitRGB565; 583 } else { 584 CAMHAL_LOGDA("Invalid format, CbYCrY format selected as default"); 585 pixFormat = OMX_COLOR_FormatCbYCrY; 586 } 587 } else { 588 CAMHAL_LOGEA("Preview format is NULL, defaulting to CbYCrY"); 589 pixFormat = OMX_COLOR_FormatCbYCrY; 590 } 591 592 OMXCameraPortParameters *cap; 593 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 594 595 params.getPreviewSize(&w, &h); 596 frameRate = params.getPreviewFrameRate(); 597 params.getPreviewFpsRange(&minFramerate, &maxFramerate); 598 minFramerate /= CameraHal::VFR_SCALE; 599 maxFramerate /= CameraHal::VFR_SCALE; 600 if ( ( 0 < minFramerate ) && ( 0 < maxFramerate ) ) { 601 if ( minFramerate > maxFramerate ) { 602 CAMHAL_LOGEA(" Min FPS set higher than MAX. So setting MIN and MAX to the higher value"); 603 maxFramerate = minFramerate; 604 } 605 606 if ( 0 >= frameRate ) { 607 frameRate = maxFramerate; 608 } 609 610 if ( ( cap->mMinFrameRate != (OMX_U32) minFramerate ) || 611 ( cap->mMaxFrameRate != (OMX_U32) maxFramerate ) ) { 612 cap->mMinFrameRate = minFramerate; 613 cap->mMaxFrameRate = maxFramerate; 614 setVFramerate(cap->mMinFrameRate, cap->mMaxFrameRate); 615 } 616 } 617 618 if ( 0 < frameRate ) 619 { 620 cap->mColorFormat = pixFormat; 621 cap->mWidth = w; 622 cap->mHeight = h; 623 cap->mFrameRate = frameRate; 624 625 CAMHAL_LOGVB("Prev: cap.mColorFormat = %d", (int)cap->mColorFormat); 626 CAMHAL_LOGVB("Prev: cap.mWidth = %d", (int)cap->mWidth); 627 CAMHAL_LOGVB("Prev: cap.mHeight = %d", (int)cap->mHeight); 628 CAMHAL_LOGVB("Prev: cap.mFrameRate = %d", (int)cap->mFrameRate); 629 630 //TODO: Add an additional parameter for video resolution 631 //use preview resolution for now 632 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 633 cap->mColorFormat = pixFormat; 634 cap->mWidth = w; 635 cap->mHeight = h; 636 cap->mFrameRate = frameRate; 637 638 CAMHAL_LOGVB("Video: cap.mColorFormat = %d", (int)cap->mColorFormat); 639 CAMHAL_LOGVB("Video: cap.mWidth = %d", (int)cap->mWidth); 640 CAMHAL_LOGVB("Video: cap.mHeight = %d", (int)cap->mHeight); 641 CAMHAL_LOGVB("Video: cap.mFrameRate = %d", (int)cap->mFrameRate); 642 643 ///mStride is set from setBufs() while passing the APIs 644 cap->mStride = 4096; 645 cap->mBufSize = cap->mStride * cap->mHeight; 646 } 647 648 if ( ( cap->mWidth >= 1920 ) && 649 ( cap->mHeight >= 1080 ) && 650 ( cap->mFrameRate >= FRAME_RATE_FULL_HD ) && 651 ( !mSensorOverclock ) ) 652 { 653 mOMXStateSwitch = true; 654 } 655 else if ( ( ( cap->mWidth < 1920 ) || 656 ( cap->mHeight < 1080 ) || 657 ( cap->mFrameRate < FRAME_RATE_FULL_HD ) ) && 658 ( mSensorOverclock ) ) 659 { 660 mOMXStateSwitch = true; 661 } 662 663 #ifdef CAMERAHAL_TUNA 664 valstr = params.get(TICameraParameters::KEY_RECORDING_HINT); 665 if (!valstr || (valstr && (strcmp(valstr, android::CameraParameters::FALSE)))) { 666 mIternalRecordingHint = false; 667 } else { 668 mIternalRecordingHint = true; 669 } 670 #endif 671 672 #ifdef OMAP_ENHANCEMENT 673 if ( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL ) 674 { 675 if (strcmp(valstr, android::CameraParameters::TRUE) == 0) 676 { 677 mMeasurementEnabled = true; 678 } 679 else if (strcmp(valstr, android::CameraParameters::FALSE) == 0) 680 { 681 mMeasurementEnabled = false; 682 } 683 else 684 { 685 mMeasurementEnabled = false; 686 } 687 } 688 else 689 { 690 //Disable measurement data by default 691 mMeasurementEnabled = false; 692 } 693 #endif 694 695 #ifdef OMAP_ENHANCEMENT_S3D 696 setParamS3D(mCameraAdapterParameters.mPrevPortIndex, 697 params.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)); 698 #endif 699 700 ret |= setParametersCapture(params, state); 701 702 ret |= setParameters3A(params, state); 703 704 ret |= setParametersAlgo(params, state); 705 706 ret |= setParametersFocus(params, state); 707 708 ret |= setParametersFD(params, state); 709 710 ret |= setParametersZoom(params, state); 711 712 ret |= setParametersEXIF(params, state); 713 714 mParams = params; 715 mFirstTimeInit = false; 716 717 if ( MODE_MAX != mCapabilitiesOpMode ) { 718 mCapabilities->setMode(mCapabilitiesOpMode); 719 } 720 721 LOG_FUNCTION_NAME_EXIT; 722 return ret; 723 } 724 725 void saveFile(unsigned char *buff, int width, int height, int format) { 726 static int counter = 1; 727 int fd = -1; 728 char fn[256]; 729 730 LOG_FUNCTION_NAME; 731 732 fn[0] = 0; 733 sprintf(fn, "/preview%03d.yuv", counter); 734 fd = open(fn, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777); 735 if(fd < 0) { 736 CAMHAL_LOGE("Unable to open file %s: %s", fn, strerror(fd)); 737 return; 738 } 739 740 CAMHAL_LOGVB("Copying from 0x%x, size=%d x %d", buff, width, height); 741 742 //method currently supports only nv12 dumping 743 int stride = width; 744 uint8_t *bf = (uint8_t*) buff; 745 for(int i=0;i<height;i++) 746 { 747 write(fd, bf, width); 748 bf += 4096; 749 } 750 751 for(int i=0;i<height/2;i++) 752 { 753 write(fd, bf, stride); 754 bf += 4096; 755 } 756 757 close(fd); 758 759 760 counter++; 761 762 LOG_FUNCTION_NAME_EXIT; 763 } 764 765 766 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 767 static status_t saveBufferToFile(const void *buf, int size, const char *filename) 768 { 769 if (size < 0) { 770 CAMHAL_LOGE("Wrong buffer size: %d", size); 771 return BAD_VALUE; 772 } 773 774 const int fd = open(filename, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0644); 775 if (fd < 0) { 776 CAMHAL_LOGE("ERROR: %s, Unable to save raw file", strerror(fd)); 777 return BAD_VALUE; 778 } 779 780 if (write(fd, buf, size) != (signed)size) { 781 CAMHAL_LOGE("ERROR: Unable to write to raw file: %s ", strerror(errno)); 782 close(fd); 783 return NO_MEMORY; 784 } 785 786 CAMHAL_LOGD("buffer=%p, size=%d stored at %s", buf, size, filename); 787 788 close(fd); 789 return OK; 790 } 791 #endif 792 793 794 void OMXCameraAdapter::getParameters(android::CameraParameters& params) 795 { 796 status_t ret = NO_ERROR; 797 OMX_CONFIG_EXPOSUREVALUETYPE exp; 798 OMX_ERRORTYPE eError = OMX_ErrorNone; 799 BaseCameraAdapter::AdapterState state; 800 BaseCameraAdapter::getState(state); 801 const char *valstr = NULL; 802 LOG_FUNCTION_NAME; 803 804 if( mParameters3A.SceneMode != OMX_Manual ) { 805 const char *valstr_supported = NULL; 806 807 if (mCapabilities) { 808 const SceneModesEntry* entry = NULL; 809 entry = getSceneModeEntry(mCapabilities->get(CameraProperties::CAMERA_NAME), 810 (OMX_SCENEMODETYPE) mParameters3A.SceneMode); 811 if(entry) { 812 mParameters3A.Focus = entry->focus; 813 mParameters3A.FlashMode = entry->flash; 814 mParameters3A.WhiteBallance = entry->wb; 815 } 816 } 817 818 valstr = getLUTvalue_OMXtoHAL(mParameters3A.WhiteBallance, WBalLUT); 819 valstr_supported = mParams.get(android::CameraParameters::KEY_SUPPORTED_WHITE_BALANCE); 820 if (valstr && valstr_supported && strstr(valstr_supported, valstr)) 821 params.set(android::CameraParameters::KEY_WHITE_BALANCE , valstr); 822 823 valstr = getLUTvalue_OMXtoHAL(mParameters3A.FlashMode, FlashLUT); 824 valstr_supported = mParams.get(android::CameraParameters::KEY_SUPPORTED_FLASH_MODES); 825 if (valstr && valstr_supported && strstr(valstr_supported, valstr)) 826 params.set(android::CameraParameters::KEY_FLASH_MODE, valstr); 827 828 if ((mParameters3A.Focus == OMX_IMAGE_FocusControlAuto) && 829 ( (mCapMode != OMXCameraAdapter::VIDEO_MODE) && 830 (mCapMode != OMXCameraAdapter::VIDEO_MODE_HQ) ) ) { 831 valstr = android::CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE; 832 } else { 833 valstr = getLUTvalue_OMXtoHAL(mParameters3A.Focus, FocusLUT); 834 } 835 valstr_supported = mParams.get(android::CameraParameters::KEY_SUPPORTED_FOCUS_MODES); 836 if (valstr && valstr_supported && strstr(valstr_supported, valstr)) 837 params.set(android::CameraParameters::KEY_FOCUS_MODE, valstr); 838 } 839 840 //Query focus distances only when focus is running 841 if ( ( AF_ACTIVE & state ) || 842 ( NULL == mParameters.get(android::CameraParameters::KEY_FOCUS_DISTANCES) ) ) 843 { 844 updateFocusDistances(params); 845 } 846 else 847 { 848 params.set(android::CameraParameters::KEY_FOCUS_DISTANCES, 849 mParameters.get(android::CameraParameters::KEY_FOCUS_DISTANCES)); 850 } 851 852 #ifdef OMAP_ENHANCEMENT 853 OMX_INIT_STRUCT_PTR (&exp, OMX_CONFIG_EXPOSUREVALUETYPE); 854 exp.nPortIndex = OMX_ALL; 855 856 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 857 OMX_IndexConfigCommonExposureValue, 858 &exp); 859 if ( OMX_ErrorNone == eError ) 860 { 861 params.set(TICameraParameters::KEY_CURRENT_ISO, exp.nSensitivity); 862 } 863 else 864 { 865 CAMHAL_LOGEB("OMX error 0x%x, while retrieving current ISO value", eError); 866 } 867 #endif 868 869 { 870 android::AutoMutex lock(mZoomLock); 871 //Immediate zoom should not be avaialable while smooth zoom is running 872 if ( ZOOM_ACTIVE & state ) 873 { 874 if ( mZoomParameterIdx != mCurrentZoomIdx ) 875 { 876 mZoomParameterIdx += mZoomInc; 877 } 878 params.set(android::CameraParameters::KEY_ZOOM, mZoomParameterIdx); 879 if ( ( mCurrentZoomIdx == mTargetZoomIdx ) && 880 ( mZoomParameterIdx == mCurrentZoomIdx ) ) 881 { 882 883 if ( NO_ERROR == ret ) 884 { 885 886 ret = BaseCameraAdapter::setState(CAMERA_STOP_SMOOTH_ZOOM); 887 888 if ( NO_ERROR == ret ) 889 { 890 ret = BaseCameraAdapter::commitState(); 891 } 892 else 893 { 894 ret |= BaseCameraAdapter::rollbackState(); 895 } 896 897 } 898 899 } 900 901 CAMHAL_LOGDB("CameraParameters Zoom = %d", mCurrentZoomIdx); 902 } 903 else 904 { 905 params.set(android::CameraParameters::KEY_ZOOM, mCurrentZoomIdx); 906 } 907 } 908 909 //Populate current lock status 910 if ( mUserSetExpLock || mParameters3A.ExposureLock ) { 911 params.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK, 912 android::CameraParameters::TRUE); 913 } else { 914 params.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK, 915 android::CameraParameters::FALSE); 916 } 917 918 if ( mUserSetWbLock || mParameters3A.WhiteBalanceLock ) { 919 params.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, 920 android::CameraParameters::TRUE); 921 } else { 922 params.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, 923 android::CameraParameters::FALSE); 924 } 925 926 // Update Picture size capabilities dynamically 927 params.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, 928 mCapabilities->get(CameraProperties::SUPPORTED_PICTURE_SIZES)); 929 930 // Update framerate capabilities dynamically 931 params.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, 932 mCapabilities->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES)); 933 934 params.set(TICameraParameters::KEY_FRAMERATES_EXT_SUPPORTED, 935 mCapabilities->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES_EXT)); 936 937 params.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, 938 mCapabilities->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED)); 939 940 params.set(TICameraParameters::KEY_FRAMERATE_RANGES_EXT_SUPPORTED, 941 mCapabilities->get(CameraProperties::FRAMERATE_RANGE_EXT_SUPPORTED)); 942 943 LOG_FUNCTION_NAME_EXIT; 944 } 945 946 status_t OMXCameraAdapter::setupTunnel(uint32_t SliceHeight, uint32_t EncoderHandle, uint32_t width, uint32_t height) { 947 LOG_FUNCTION_NAME; 948 949 status_t ret = NO_ERROR; 950 OMX_ERRORTYPE eError = OMX_ErrorNone; 951 OMX_HANDLETYPE *encoderHandle = (OMX_HANDLETYPE *)EncoderHandle; 952 953 CAMHAL_LOGDB("\n %s: SliceHeight:%d, EncoderHandle:%d width:%d height:%d \n", __FUNCTION__, SliceHeight, EncoderHandle, width, height); 954 955 if (SliceHeight == 0){ 956 CAMHAL_LOGEA("\n\n #### Encoder Slice Height Not received, Dont Setup Tunnel $$$$\n\n"); 957 return BAD_VALUE; 958 } 959 960 if (encoderHandle == NULL) { 961 CAMHAL_LOGEA("Encoder Handle not set \n\n"); 962 return BAD_VALUE; 963 } 964 965 if ( 0 != mInitSem.Count() ) { 966 CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count()); 967 LOG_FUNCTION_NAME_EXIT; 968 return NO_INIT; 969 } 970 971 // Register for port enable event 972 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 973 OMX_EventCmdComplete, 974 OMX_CommandPortEnable, 975 mCameraAdapterParameters.mVideoPortIndex, 976 mInitSem); 977 if(ret != NO_ERROR) { 978 CAMHAL_LOGEB("Error in registering for event %d", ret); 979 return UNKNOWN_ERROR; 980 } 981 982 // Enable VIDEO Port 983 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 984 OMX_CommandPortEnable, 985 mCameraAdapterParameters.mVideoPortIndex, 986 NULL); 987 if(eError != OMX_ErrorNone) { 988 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 989 return BAD_VALUE; 990 } 991 992 // Wait for the port enable event to occur 993 ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT); 994 if ( NO_ERROR == ret ) { 995 CAMHAL_LOGDA("-Port enable event arrived"); 996 } else { 997 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 998 OMX_EventCmdComplete, 999 OMX_CommandPortEnable, 1000 mCameraAdapterParameters.mVideoPortIndex, 1001 NULL); 1002 CAMHAL_LOGEA("Timeout for enabling preview port expired!"); 1003 return UNKNOWN_ERROR; 1004 } 1005 1006 //Set the Video Port Params 1007 OMX_PARAM_PORTDEFINITIONTYPE portCheck; 1008 OMX_INIT_STRUCT_PTR (&portCheck, OMX_PARAM_PORTDEFINITIONTYPE); 1009 portCheck.nPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_VIDEO; 1010 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, 1011 OMX_IndexParamPortDefinition, &portCheck); 1012 if (eError!=OMX_ErrorNone) { 1013 CAMHAL_LOGEB("OMX_GetParameter OMX_IndexParamPortDefinition Error - %x", eError); 1014 } 1015 1016 portCheck.format.video.nFrameWidth = width; 1017 portCheck.format.video.nFrameHeight = height; 1018 portCheck.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar; 1019 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1020 OMX_IndexParamPortDefinition, &portCheck); 1021 if (eError!=OMX_ErrorNone) { 1022 CAMHAL_LOGEB("OMX_SetParameter OMX_IndexParamPortDefinition Error- %x", eError); 1023 } 1024 1025 //Slice Configuration 1026 OMX_TI_PARAM_VTCSLICE VTCSlice; 1027 OMX_INIT_STRUCT_PTR(&VTCSlice, OMX_TI_PARAM_VTCSLICE); 1028 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexParamVtcSlice, &VTCSlice); 1029 if (eError!=OMX_ErrorNone) { 1030 CAMHAL_LOGEB("OMX_GetParameter OMX_TI_IndexParamVtcSlice Error - %x", eError); 1031 } 1032 1033 VTCSlice.nSliceHeight = SliceHeight; 1034 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexParamVtcSlice, &VTCSlice); 1035 if (OMX_ErrorNone != eError ) { 1036 CAMHAL_LOGEB("OMX_SetParameter on OMX_TI_IndexParamVtcSlice returned error: 0x%x", eError); 1037 return BAD_VALUE; 1038 } 1039 1040 eError = OMX_SetupTunnel(mCameraAdapterParameters.mHandleComp, 1041 mCameraAdapterParameters.mVideoPortIndex, encoderHandle, 0); 1042 if (OMX_ErrorNone != eError ) { 1043 CAMHAL_LOGEB("OMX_SetupTunnel returned error: 0x%x", eError); 1044 return BAD_VALUE; 1045 } 1046 1047 return NO_ERROR; 1048 } 1049 1050 status_t OMXCameraAdapter::setSensorQuirks(int orientation, 1051 OMXCameraPortParameters &portParams, 1052 bool &portConfigured) 1053 { 1054 status_t overclockStatus = NO_ERROR; 1055 int sensorID = -1; 1056 size_t overclockWidth; 1057 size_t overclockHeight; 1058 OMX_ERRORTYPE eError = OMX_ErrorNone; 1059 OMX_PARAM_PORTDEFINITIONTYPE portCheck; 1060 1061 LOG_FUNCTION_NAME; 1062 1063 portConfigured = false; 1064 OMX_INIT_STRUCT_PTR (&portCheck, OMX_PARAM_PORTDEFINITIONTYPE); 1065 1066 portCheck.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 1067 1068 eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp, 1069 OMX_IndexParamPortDefinition, 1070 &portCheck); 1071 1072 if ( eError != OMX_ErrorNone ) { 1073 CAMHAL_LOGEB("OMX_GetParameter - %x", eError); 1074 return Utils::ErrorUtils::omxToAndroidError(eError); 1075 } 1076 1077 if ( ( orientation == 90 ) || ( orientation == 270 ) ) { 1078 overclockWidth = 1080; 1079 overclockHeight = 1920; 1080 } else { 1081 overclockWidth = 1920; 1082 overclockHeight = 1080; 1083 } 1084 1085 sensorID = mCapabilities->getInt(CameraProperties::CAMERA_SENSOR_ID); 1086 if( ( ( sensorID == SENSORID_IMX060 ) && 1087 ( portParams.mWidth >= overclockWidth ) && 1088 ( portParams.mHeight >= overclockHeight ) && 1089 ( portParams.mFrameRate >= FRAME_RATE_FULL_HD ) ) || 1090 (( sensorID == SENSORID_OV14825) && 1091 ( portParams.mFrameRate >= FRAME_RATE_HIGH_HD ))|| 1092 ( ( sensorID == SENSORID_OV5640 ) && 1093 ( portParams.mWidth >= overclockWidth ) && 1094 ( portParams.mHeight >= overclockHeight ) ) ) { 1095 overclockStatus = setSensorOverclock(true); 1096 } else { 1097 1098 //WA: If the next port resolution doesn't require 1099 // sensor overclocking, but the previous resolution 1100 // needed it, then we have to first set new port 1101 // resolution and then disable sensor overclocking. 1102 if( ( ( sensorID == SENSORID_IMX060 ) && 1103 ( portCheck.format.video.nFrameWidth >= overclockWidth ) && 1104 ( portCheck.format.video.nFrameHeight >= overclockHeight ) && 1105 ( ( portCheck.format.video.xFramerate >> 16 ) >= FRAME_RATE_FULL_HD ) ) || 1106 (( sensorID == SENSORID_OV14825) && 1107 (( portCheck.format.video.xFramerate >> 16) >= FRAME_RATE_HIGH_HD ))|| 1108 ( ( sensorID == SENSORID_OV5640 ) && 1109 ( portCheck.format.video.nFrameWidth >= overclockWidth ) && 1110 ( portCheck.format.video.nFrameHeight >= overclockHeight ) ) ) { 1111 status_t ret = setFormat(mCameraAdapterParameters.mPrevPortIndex, 1112 portParams); 1113 if ( NO_ERROR != ret ) { 1114 return ret; 1115 } 1116 1117 // Another WA: Setting the port definition will reset the VFR 1118 // configuration. 1119 setVFramerate(portParams.mMinFrameRate, portParams.mMaxFrameRate); 1120 1121 portConfigured = true; 1122 } 1123 1124 overclockStatus = setSensorOverclock(false); 1125 } 1126 1127 LOG_FUNCTION_NAME_EXIT; 1128 1129 return overclockStatus; 1130 } 1131 status_t OMXCameraAdapter::setFormat(OMX_U32 port, OMXCameraPortParameters &portParams) 1132 { 1133 LOG_FUNCTION_NAME; 1134 1135 status_t ret = NO_ERROR; 1136 size_t bufferCount; 1137 OMX_ERRORTYPE eError = OMX_ErrorNone; 1138 OMX_PARAM_PORTDEFINITIONTYPE portCheck; 1139 1140 OMX_INIT_STRUCT_PTR (&portCheck, OMX_PARAM_PORTDEFINITIONTYPE); 1141 1142 portCheck.nPortIndex = port; 1143 1144 eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp, 1145 OMX_IndexParamPortDefinition, &portCheck); 1146 if (eError!=OMX_ErrorNone) { 1147 CAMHAL_LOGEB("OMX_GetParameter - %x", eError); 1148 } 1149 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1150 1151 if (OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW == port) { 1152 portCheck.format.video.nFrameWidth = portParams.mWidth; 1153 portCheck.format.video.nFrameHeight = portParams.mHeight; 1154 portCheck.format.video.eColorFormat = portParams.mColorFormat; 1155 portCheck.format.video.nStride = portParams.mStride; 1156 1157 portCheck.format.video.xFramerate = portParams.mFrameRate<<16; 1158 portCheck.nBufferSize = portParams.mStride * portParams.mHeight; 1159 portCheck.nBufferCountActual = portParams.mNumBufs; 1160 mFocusThreshold = FOCUS_THRESHOLD * portParams.mFrameRate; 1161 // Used for RAW capture 1162 } else if (OMX_CAMERA_PORT_VIDEO_OUT_VIDEO == port) { 1163 portCheck.format.video.nFrameWidth = portParams.mWidth; 1164 portCheck.format.video.nFrameHeight = portParams.mHeight; 1165 portCheck.format.video.eColorFormat = OMX_COLOR_FormatRawBayer10bit; // portParams.mColorFormat; 1166 portCheck.nBufferCountActual = 1; // portParams.mNumBufs; 1167 } else if (OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port) { 1168 portCheck.format.image.nFrameWidth = portParams.mWidth; 1169 portCheck.format.image.nFrameHeight = portParams.mHeight; 1170 if (OMX_COLOR_FormatUnused == portParams.mColorFormat) { 1171 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 1172 if (mCodingMode == CodingJPEG) { 1173 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG; 1174 } else if (mCodingMode == CodingJPS) { 1175 portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingJPS; 1176 } else if (mCodingMode == CodingMPO) { 1177 portCheck.format.image.eCompressionFormat = (OMX_IMAGE_CODINGTYPE) OMX_TI_IMAGE_CodingMPO; 1178 } else { 1179 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; 1180 } 1181 } else { 1182 portCheck.format.image.eColorFormat = portParams.mColorFormat; 1183 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; 1184 } 1185 1186 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 1187 // RAW + YUV Capture 1188 if (mYuvCapture) { 1189 portCheck.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY; 1190 portCheck.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; 1191 } 1192 #endif 1193 //Stride for 1D tiler buffer is zero 1194 portCheck.format.image.nStride = 0; 1195 portCheck.nBufferCountActual = portParams.mNumBufs; 1196 } else if (OMX_CAMERA_PORT_VIDEO_IN_VIDEO == port) { 1197 portCheck.format.video.nFrameWidth = portParams.mWidth; 1198 portCheck.format.video.nStride = portParams.mStride; 1199 portCheck.format.video.nFrameHeight = portParams.mHeight; 1200 portCheck.format.video.eColorFormat = portParams.mColorFormat; 1201 portCheck.format.video.xFramerate = 30 << 16; 1202 portCheck.nBufferCountActual = portParams.mNumBufs; 1203 } else { 1204 CAMHAL_LOGEB("Unsupported port index (%lu)", port); 1205 } 1206 1207 if (( mSensorIndex == OMX_TI_StereoSensor ) && (OMX_CAMERA_PORT_VIDEO_OUT_VIDEO != port)) { 1208 ret = setS3DFrameLayout(port); 1209 if ( NO_ERROR != ret ) 1210 { 1211 CAMHAL_LOGEA("Error configuring stereo 3D frame layout"); 1212 return ret; 1213 } 1214 } 1215 1216 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1217 OMX_IndexParamPortDefinition, &portCheck); 1218 if (eError!=OMX_ErrorNone) { 1219 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 1220 } 1221 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1222 1223 /* check if parameters are set correctly by calling GetParameter() */ 1224 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, 1225 OMX_IndexParamPortDefinition, &portCheck); 1226 if (eError!=OMX_ErrorNone) { 1227 CAMHAL_LOGEB("OMX_GetParameter - %x", eError); 1228 } 1229 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1230 1231 portParams.mBufSize = portCheck.nBufferSize; 1232 portParams.mStride = portCheck.format.image.nStride; 1233 1234 if (OMX_CAMERA_PORT_IMAGE_OUT_IMAGE == port) { 1235 CAMHAL_LOGDB("\n *** IMG Width = %ld", portCheck.format.image.nFrameWidth); 1236 CAMHAL_LOGDB("\n *** IMG Height = %ld", portCheck.format.image.nFrameHeight); 1237 1238 CAMHAL_LOGDB("\n *** IMG IMG FMT = %x", portCheck.format.image.eColorFormat); 1239 CAMHAL_LOGDB("\n *** IMG portCheck.nBufferSize = %ld\n",portCheck.nBufferSize); 1240 CAMHAL_LOGDB("\n *** IMG portCheck.nBufferCountMin = %ld\n", 1241 portCheck.nBufferCountMin); 1242 CAMHAL_LOGDB("\n *** IMG portCheck.nBufferCountActual = %ld\n", 1243 portCheck.nBufferCountActual); 1244 CAMHAL_LOGDB("\n *** IMG portCheck.format.image.nStride = %ld\n", 1245 portCheck.format.image.nStride); 1246 } else if (OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW == port) { 1247 CAMHAL_LOGDB("\n *** PRV Width = %ld", portCheck.format.video.nFrameWidth); 1248 CAMHAL_LOGDB("\n *** PRV Height = %ld", portCheck.format.video.nFrameHeight); 1249 1250 CAMHAL_LOGDB("\n *** PRV IMG FMT = %x", portCheck.format.video.eColorFormat); 1251 CAMHAL_LOGDB("\n *** PRV portCheck.nBufferSize = %ld\n",portCheck.nBufferSize); 1252 CAMHAL_LOGDB("\n *** PRV portCheck.nBufferCountMin = %ld\n", 1253 portCheck.nBufferCountMin); 1254 CAMHAL_LOGDB("\n *** PRV portCheck.nBufferCountActual = %ld\n", 1255 portCheck.nBufferCountActual); 1256 CAMHAL_LOGDB("\n ***PRV portCheck.format.video.nStride = %ld\n", 1257 portCheck.format.video.nStride); 1258 } else { 1259 CAMHAL_LOGDB("\n *** VID Width = %ld", portCheck.format.video.nFrameWidth); 1260 CAMHAL_LOGDB("\n *** VID Height = %ld", portCheck.format.video.nFrameHeight); 1261 1262 CAMHAL_LOGDB("\n *** VID IMG FMT = %x", portCheck.format.video.eColorFormat); 1263 CAMHAL_LOGDB("\n *** VID portCheck.nBufferSize = %ld\n",portCheck.nBufferSize); 1264 CAMHAL_LOGDB("\n *** VID portCheck.nBufferCountMin = %ld\n", 1265 portCheck.nBufferCountMin); 1266 CAMHAL_LOGDB("\n *** VID portCheck.nBufferCountActual = %ld\n", 1267 portCheck.nBufferCountActual); 1268 CAMHAL_LOGDB("\n *** VID portCheck.format.video.nStride = %ld\n", 1269 portCheck.format.video.nStride); 1270 } 1271 1272 mSetFormatDone = true; 1273 1274 LOG_FUNCTION_NAME_EXIT; 1275 1276 return Utils::ErrorUtils::omxToAndroidError(eError); 1277 1278 EXIT: 1279 1280 CAMHAL_LOGEB("Exiting function %s because of eError = 0x%x", __FUNCTION__, eError); 1281 1282 LOG_FUNCTION_NAME_EXIT; 1283 1284 return Utils::ErrorUtils::omxToAndroidError(eError); 1285 } 1286 1287 status_t OMXCameraAdapter::flushBuffers(OMX_U32 nPort) 1288 { 1289 LOG_FUNCTION_NAME; 1290 1291 status_t ret = NO_ERROR; 1292 OMX_ERRORTYPE eError = OMX_ErrorNone; 1293 1294 if ( 0 != mFlushSem.Count() ) 1295 { 1296 CAMHAL_LOGEB("Error mFlushSem semaphore count %d", mFlushSem.Count()); 1297 LOG_FUNCTION_NAME_EXIT; 1298 return NO_INIT; 1299 } 1300 1301 OMXCameraPortParameters * mPreviewData = NULL; 1302 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[nPort]; 1303 1304 ///Register for the FLUSH event 1305 ///This method just inserts a message in Event Q, which is checked in the callback 1306 ///The sempahore passed is signalled by the callback 1307 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1308 OMX_EventCmdComplete, 1309 OMX_CommandFlush, 1310 nPort, 1311 mFlushSem); 1312 if(ret!=NO_ERROR) 1313 { 1314 CAMHAL_LOGEB("Error in registering for event %d", ret); 1315 goto EXIT; 1316 } 1317 1318 ///Send FLUSH command to preview port 1319 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp, 1320 OMX_CommandFlush, 1321 nPort, 1322 NULL); 1323 1324 if(eError!=OMX_ErrorNone) 1325 { 1326 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandFlush)-0x%x", eError); 1327 } 1328 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1329 1330 CAMHAL_LOGDA("Waiting for flush event"); 1331 1332 ///Wait for the FLUSH event to occur 1333 ret = mFlushSem.WaitTimeout(OMX_CMD_TIMEOUT); 1334 1335 //If somethiing bad happened while we wait 1336 if (mComponentState == OMX_StateInvalid) 1337 { 1338 CAMHAL_LOGEA("Invalid State after Flush Exitting!!!"); 1339 goto EXIT; 1340 } 1341 1342 if ( NO_ERROR == ret ) 1343 { 1344 CAMHAL_LOGDA("Flush event received"); 1345 } 1346 else 1347 { 1348 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1349 OMX_EventCmdComplete, 1350 OMX_CommandFlush, 1351 nPort, 1352 NULL); 1353 CAMHAL_LOGDA("Flush event timeout expired"); 1354 goto EXIT; 1355 } 1356 1357 mOMXCallbackHandler->flush(); 1358 1359 LOG_FUNCTION_NAME_EXIT; 1360 1361 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1362 1363 EXIT: 1364 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1365 performCleanupAfterError(); 1366 LOG_FUNCTION_NAME_EXIT; 1367 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1368 } 1369 1370 ///API to give the buffers to Adapter 1371 status_t OMXCameraAdapter::useBuffers(CameraMode mode, CameraBuffer * bufArr, int num, size_t length, unsigned int queueable) 1372 { 1373 OMX_ERRORTYPE eError = OMX_ErrorNone; 1374 status_t ret = NO_ERROR; 1375 1376 LOG_FUNCTION_NAME; 1377 1378 switch(mode) 1379 { 1380 case CAMERA_PREVIEW: 1381 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mNumBufs = num; 1382 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex].mMaxQueueable = queueable; 1383 ret = UseBuffersPreview(bufArr, num); 1384 break; 1385 1386 case CAMERA_IMAGE_CAPTURE: 1387 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mMaxQueueable = queueable; 1388 ret = UseBuffersCapture(bufArr, num); 1389 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mNumBufs = num; 1390 break; 1391 1392 case CAMERA_VIDEO: 1393 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex].mNumBufs = num; 1394 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex].mMaxQueueable = queueable; 1395 ret = UseBuffersRawCapture(bufArr, num); 1396 break; 1397 1398 case CAMERA_MEASUREMENT: 1399 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mNumBufs = num; 1400 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex].mMaxQueueable = queueable; 1401 ret = UseBuffersPreviewData(bufArr, num); 1402 break; 1403 1404 case CAMERA_REPROCESS: 1405 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex].mNumBufs = num; 1406 mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex].mMaxQueueable = queueable; 1407 ret = UseBuffersReprocess(bufArr, num); 1408 break; 1409 } 1410 1411 LOG_FUNCTION_NAME_EXIT; 1412 1413 return ret; 1414 } 1415 1416 status_t OMXCameraAdapter::UseBuffersPreviewData(CameraBuffer * bufArr, int num) 1417 { 1418 status_t ret = NO_ERROR; 1419 OMX_ERRORTYPE eError = OMX_ErrorNone; 1420 OMXCameraPortParameters * measurementData = NULL; 1421 android::AutoMutex lock(mPreviewDataBufferLock); 1422 1423 LOG_FUNCTION_NAME; 1424 1425 if ( mComponentState != OMX_StateLoaded ) 1426 { 1427 CAMHAL_LOGEA("Calling UseBuffersPreviewData() when not in LOADED state"); 1428 return BAD_VALUE; 1429 } 1430 1431 if ( NULL == bufArr ) 1432 { 1433 CAMHAL_LOGEA("NULL pointer passed for buffArr"); 1434 return BAD_VALUE; 1435 } 1436 1437 if ( 0 != mUsePreviewDataSem.Count() ) 1438 { 1439 CAMHAL_LOGEB("Error mUsePreviewDataSem semaphore count %d", mUsePreviewDataSem.Count()); 1440 LOG_FUNCTION_NAME_EXIT; 1441 return NO_INIT; 1442 } 1443 1444 if ( NO_ERROR == ret ) 1445 { 1446 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1447 measurementData->mNumBufs = num ; 1448 } 1449 1450 if ( NO_ERROR == ret ) 1451 { 1452 ///Register for port enable event on measurement port 1453 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1454 OMX_EventCmdComplete, 1455 OMX_CommandPortEnable, 1456 mCameraAdapterParameters.mMeasurementPortIndex, 1457 mUsePreviewDataSem); 1458 1459 if ( ret == NO_ERROR ) 1460 { 1461 CAMHAL_LOGDB("Registering for event %d", ret); 1462 } 1463 else 1464 { 1465 CAMHAL_LOGEB("Error in registering for event %d", ret); 1466 goto EXIT; 1467 } 1468 } 1469 1470 if ( NO_ERROR == ret ) 1471 { 1472 ///Enable MEASUREMENT Port 1473 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1474 OMX_CommandPortEnable, 1475 mCameraAdapterParameters.mMeasurementPortIndex, 1476 NULL); 1477 1478 if ( eError == OMX_ErrorNone ) 1479 { 1480 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 1481 } 1482 else 1483 { 1484 CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError); 1485 goto EXIT; 1486 } 1487 } 1488 1489 if ( NO_ERROR == ret ) 1490 { 1491 ret = mUsePreviewDataSem.WaitTimeout(OMX_CMD_TIMEOUT); 1492 1493 //If somethiing bad happened while we wait 1494 if (mComponentState == OMX_StateInvalid) 1495 { 1496 CAMHAL_LOGEA("Invalid State after measurement port enable Exitting!!!"); 1497 goto EXIT; 1498 } 1499 1500 if ( NO_ERROR == ret ) 1501 { 1502 CAMHAL_LOGDA("Port enable event arrived on measurement port"); 1503 } 1504 else 1505 { 1506 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1507 OMX_EventCmdComplete, 1508 OMX_CommandPortEnable, 1509 mCameraAdapterParameters.mMeasurementPortIndex, 1510 NULL); 1511 CAMHAL_LOGEA("Timeout expoired during port enable on measurement port"); 1512 goto EXIT; 1513 } 1514 1515 CAMHAL_LOGDA("Port enable event arrived on measurement port"); 1516 } 1517 1518 LOG_FUNCTION_NAME_EXIT; 1519 1520 return ret; 1521 EXIT: 1522 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1523 performCleanupAfterError(); 1524 LOG_FUNCTION_NAME_EXIT; 1525 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1526 } 1527 1528 status_t OMXCameraAdapter::switchToExecuting() 1529 { 1530 status_t ret = NO_ERROR; 1531 Utils::Message msg; 1532 1533 LOG_FUNCTION_NAME; 1534 1535 mStateSwitchLock.lock(); 1536 msg.command = CommandHandler::CAMERA_SWITCH_TO_EXECUTING; 1537 msg.arg1 = mErrorNotifier; 1538 ret = mCommandHandler->put(&msg); 1539 1540 LOG_FUNCTION_NAME_EXIT; 1541 1542 return ret; 1543 } 1544 1545 status_t OMXCameraAdapter::doSwitchToExecuting() 1546 { 1547 status_t ret = NO_ERROR; 1548 OMX_ERRORTYPE eError = OMX_ErrorNone; 1549 LOG_FUNCTION_NAME; 1550 1551 if ( (mComponentState == OMX_StateExecuting) || (mComponentState == OMX_StateInvalid) ){ 1552 CAMHAL_LOGDA("Already in OMX_Executing state or OMX_StateInvalid state"); 1553 mStateSwitchLock.unlock(); 1554 return NO_ERROR; 1555 } 1556 1557 if ( 0 != mSwitchToExecSem.Count() ){ 1558 CAMHAL_LOGEB("Error mSwitchToExecSem semaphore count %d", mSwitchToExecSem.Count()); 1559 goto EXIT; 1560 } 1561 1562 ///Register for Preview port DISABLE event 1563 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1564 OMX_EventCmdComplete, 1565 OMX_CommandPortDisable, 1566 mCameraAdapterParameters.mPrevPortIndex, 1567 mSwitchToExecSem); 1568 if ( NO_ERROR != ret ){ 1569 CAMHAL_LOGEB("Error in registering Port Disable for event %d", ret); 1570 goto EXIT; 1571 } 1572 ///Disable Preview Port 1573 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1574 OMX_CommandPortDisable, 1575 mCameraAdapterParameters.mPrevPortIndex, 1576 NULL); 1577 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT); 1578 if (ret != NO_ERROR){ 1579 CAMHAL_LOGEB("Timeout PREVIEW PORT DISABLE %d", ret); 1580 } 1581 1582 CAMHAL_LOGVB("PREV PORT DISABLED %d", ret); 1583 1584 ///Register for IDLE state switch event 1585 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1586 OMX_EventCmdComplete, 1587 OMX_CommandStateSet, 1588 OMX_StateIdle, 1589 mSwitchToExecSem); 1590 if(ret!=NO_ERROR) 1591 { 1592 CAMHAL_LOGEB("Error in IDLE STATE SWITCH %d", ret); 1593 goto EXIT; 1594 } 1595 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp , 1596 OMX_CommandStateSet, 1597 OMX_StateIdle, 1598 NULL); 1599 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1600 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT); 1601 if (ret != NO_ERROR){ 1602 CAMHAL_LOGEB("Timeout IDLE STATE SWITCH %d", ret); 1603 goto EXIT; 1604 } 1605 mComponentState = OMX_StateIdle; 1606 CAMHAL_LOGVB("OMX_SendCommand(OMX_StateIdle) 0x%x", eError); 1607 1608 ///Register for EXECUTING state switch event 1609 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1610 OMX_EventCmdComplete, 1611 OMX_CommandStateSet, 1612 OMX_StateExecuting, 1613 mSwitchToExecSem); 1614 if(ret!=NO_ERROR) 1615 { 1616 CAMHAL_LOGEB("Error in EXECUTING STATE SWITCH %d", ret); 1617 goto EXIT; 1618 } 1619 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp , 1620 OMX_CommandStateSet, 1621 OMX_StateExecuting, 1622 NULL); 1623 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1624 ret = mSwitchToExecSem.WaitTimeout(OMX_CMD_TIMEOUT); 1625 if (ret != NO_ERROR){ 1626 CAMHAL_LOGEB("Timeout EXEC STATE SWITCH %d", ret); 1627 goto EXIT; 1628 } 1629 mComponentState = OMX_StateExecuting; 1630 CAMHAL_LOGVB("OMX_SendCommand(OMX_StateExecuting) 0x%x", eError); 1631 1632 mStateSwitchLock.unlock(); 1633 1634 LOG_FUNCTION_NAME_EXIT; 1635 return ret; 1636 1637 EXIT: 1638 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1639 performCleanupAfterError(); 1640 mStateSwitchLock.unlock(); 1641 LOG_FUNCTION_NAME_EXIT; 1642 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1643 } 1644 1645 status_t OMXCameraAdapter::switchToIdle() { 1646 status_t ret = NO_ERROR; 1647 OMX_ERRORTYPE eError = OMX_ErrorNone; 1648 1649 LOG_FUNCTION_NAME; 1650 1651 android::AutoMutex lock(mIdleStateSwitchLock); 1652 1653 if ( mComponentState == OMX_StateIdle || mComponentState == OMX_StateLoaded || mComponentState == OMX_StateInvalid) { 1654 CAMHAL_LOGDA("Already in OMX_StateIdle, OMX_Loaded state or OMX_StateInvalid state"); 1655 return NO_ERROR; 1656 } 1657 1658 if ( 0 != mSwitchToLoadedSem.Count() ) 1659 { 1660 CAMHAL_LOGEB("Error mSwitchToLoadedSem semaphore count %d", mSwitchToLoadedSem.Count()); 1661 goto EXIT; 1662 } 1663 1664 ///Register for EXECUTING state transition. 1665 ///This method just inserts a message in Event Q, which is checked in the callback 1666 ///The sempahore passed is signalled by the callback 1667 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1668 OMX_EventCmdComplete, 1669 OMX_CommandStateSet, 1670 OMX_StateIdle, 1671 mSwitchToLoadedSem); 1672 1673 if(ret!=NO_ERROR) 1674 { 1675 CAMHAL_LOGEB("Error in registering for event %d", ret); 1676 goto EXIT; 1677 } 1678 1679 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp, 1680 OMX_CommandStateSet, 1681 OMX_StateIdle, 1682 NULL); 1683 1684 if(eError!=OMX_ErrorNone) 1685 { 1686 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateIdle) - %x", eError); 1687 } 1688 1689 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1690 1691 ///Wait for the EXECUTING ->IDLE transition to arrive 1692 1693 CAMHAL_LOGDA("EXECUTING->IDLE state changed"); 1694 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT); 1695 1696 //If somethiing bad happened while we wait 1697 if (mComponentState == OMX_StateInvalid) 1698 { 1699 CAMHAL_LOGEA("Invalid State after EXECUTING->IDLE Exitting!!!"); 1700 goto EXIT; 1701 } 1702 1703 if ( NO_ERROR == ret ) 1704 { 1705 CAMHAL_LOGDA("EXECUTING->IDLE state changed"); 1706 } 1707 else 1708 { 1709 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1710 OMX_EventCmdComplete, 1711 OMX_CommandStateSet, 1712 OMX_StateIdle, 1713 NULL); 1714 CAMHAL_LOGEA("Timeout expired on EXECUTING->IDLE state change"); 1715 goto EXIT; 1716 } 1717 1718 mComponentState = OMX_StateIdle; 1719 1720 return NO_ERROR; 1721 1722 EXIT: 1723 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1724 performCleanupAfterError(); 1725 LOG_FUNCTION_NAME_EXIT; 1726 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1727 } 1728 1729 1730 1731 status_t OMXCameraAdapter::prevPortEnable() { 1732 status_t ret = NO_ERROR; 1733 OMX_ERRORTYPE eError = OMX_ErrorNone; 1734 1735 LOG_FUNCTION_NAME; 1736 1737 ///Register for Preview port ENABLE event 1738 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1739 OMX_EventCmdComplete, 1740 OMX_CommandPortEnable, 1741 mCameraAdapterParameters.mPrevPortIndex, 1742 mSwitchToLoadedSem); 1743 1744 if ( NO_ERROR != ret ) 1745 { 1746 CAMHAL_LOGEB("Error in registering for event %d", ret); 1747 goto EXIT; 1748 } 1749 1750 ///Enable Preview Port 1751 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1752 OMX_CommandPortEnable, 1753 mCameraAdapterParameters.mPrevPortIndex, 1754 NULL); 1755 1756 1757 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError); 1758 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1759 1760 CAMHAL_LOGDA("Enabling Preview port"); 1761 ///Wait for state to switch to idle 1762 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT); 1763 1764 //If somethiing bad happened while we wait 1765 if (mComponentState == OMX_StateInvalid) 1766 { 1767 CAMHAL_LOGEA("Invalid State after Enabling Preview port Exitting!!!"); 1768 goto EXIT; 1769 } 1770 1771 if ( NO_ERROR == ret ) 1772 { 1773 CAMHAL_LOGDA("Preview port enabled!"); 1774 } 1775 else 1776 { 1777 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1778 OMX_EventCmdComplete, 1779 OMX_CommandPortEnable, 1780 mCameraAdapterParameters.mPrevPortIndex, 1781 NULL); 1782 CAMHAL_LOGEA("Preview enable timedout"); 1783 1784 goto EXIT; 1785 } 1786 1787 LOG_FUNCTION_NAME_EXIT; 1788 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1789 1790 EXIT: 1791 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1792 performCleanupAfterError(); 1793 LOG_FUNCTION_NAME_EXIT; 1794 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1795 } 1796 1797 status_t OMXCameraAdapter::switchToLoaded(bool bPortEnableRequired) { 1798 status_t ret = NO_ERROR; 1799 OMX_ERRORTYPE eError = OMX_ErrorNone; 1800 1801 LOG_FUNCTION_NAME; 1802 1803 android::AutoMutex lock(mStateSwitchLock); 1804 if ( mComponentState == OMX_StateLoaded || mComponentState == OMX_StateInvalid) { 1805 CAMHAL_LOGDA("Already in OMX_Loaded state or OMX_StateInvalid state"); 1806 return NO_ERROR; 1807 } 1808 1809 if ( mComponentState != OMX_StateIdle) { 1810 ret = switchToIdle(); 1811 if (ret != NO_ERROR) return ret; 1812 } 1813 1814 if ( 0 != mSwitchToLoadedSem.Count() ) { 1815 CAMHAL_LOGEB("Error mSwitchToLoadedSem semaphore count %d", mSwitchToLoadedSem.Count()); 1816 goto EXIT; 1817 } 1818 1819 ///Register for LOADED state transition. 1820 ///This method just inserts a message in Event Q, which is checked in the callback 1821 ///The sempahore passed is signalled by the callback 1822 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1823 OMX_EventCmdComplete, 1824 OMX_CommandStateSet, 1825 OMX_StateLoaded, 1826 mSwitchToLoadedSem); 1827 1828 if(ret!=NO_ERROR) 1829 { 1830 CAMHAL_LOGEB("Error in registering for event %d", ret); 1831 goto EXIT; 1832 } 1833 1834 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp, 1835 OMX_CommandStateSet, 1836 OMX_StateLoaded, 1837 NULL); 1838 1839 if(eError!=OMX_ErrorNone) 1840 { 1841 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateLoaded) - %x", eError); 1842 } 1843 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1844 1845 if ( !bPortEnableRequired ) { 1846 OMXCameraPortParameters *mCaptureData , *mPreviewData, *measurementData; 1847 mCaptureData = mPreviewData = measurementData = NULL; 1848 1849 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 1850 mCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 1851 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1852 1853 ///Free the OMX Buffers 1854 for ( int i = 0 ; i < mPreviewData->mNumBufs ; i++ ) { 1855 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 1856 mCameraAdapterParameters.mPrevPortIndex, 1857 mPreviewData->mBufferHeader[i]); 1858 1859 if(eError!=OMX_ErrorNone) { 1860 CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError); 1861 } 1862 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1863 } 1864 1865 if ( mMeasurementEnabled ) { 1866 1867 for ( int i = 0 ; i < measurementData->mNumBufs ; i++ ) { 1868 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 1869 mCameraAdapterParameters.mMeasurementPortIndex, 1870 measurementData->mBufferHeader[i]); 1871 if(eError!=OMX_ErrorNone) { 1872 CAMHAL_LOGEB("OMX_FreeBuffer - %x", eError); 1873 } 1874 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1875 } 1876 1877 { 1878 android::AutoMutex lock(mPreviewDataBufferLock); 1879 mPreviewDataBuffersAvailable.clear(); 1880 } 1881 1882 } 1883 } 1884 1885 CAMHAL_LOGDA("Switching IDLE->LOADED state"); 1886 ret = mSwitchToLoadedSem.WaitTimeout(OMX_CMD_TIMEOUT); 1887 1888 //If somethiing bad happened while we wait 1889 if (mComponentState == OMX_StateInvalid) 1890 { 1891 CAMHAL_LOGEA("Invalid State after IDLE->LOADED Exitting!!!"); 1892 goto EXIT; 1893 } 1894 1895 if ( NO_ERROR == ret ) 1896 { 1897 CAMHAL_LOGDA("IDLE->LOADED state changed"); 1898 } 1899 else 1900 { 1901 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1902 OMX_EventCmdComplete, 1903 OMX_CommandStateSet, 1904 OMX_StateLoaded, 1905 NULL); 1906 CAMHAL_LOGEA("Timeout expired on IDLE->LOADED state change"); 1907 goto EXIT; 1908 } 1909 1910 mComponentState = OMX_StateLoaded; 1911 if (bPortEnableRequired == true) { 1912 prevPortEnable(); 1913 } 1914 1915 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1916 1917 EXIT: 1918 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1919 { 1920 android::AutoMutex lock(mPreviewBufferLock); 1921 ///Clear all the available preview buffers 1922 mPreviewBuffersAvailable.clear(); 1923 } 1924 performCleanupAfterError(); 1925 LOG_FUNCTION_NAME_EXIT; 1926 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1927 } 1928 1929 status_t OMXCameraAdapter::UseBuffersPreview(CameraBuffer * bufArr, int num) 1930 { 1931 status_t ret = NO_ERROR; 1932 OMX_ERRORTYPE eError = OMX_ErrorNone; 1933 int tmpHeight, tmpWidth; 1934 1935 LOG_FUNCTION_NAME; 1936 1937 if(!bufArr) 1938 { 1939 CAMHAL_LOGEA("NULL pointer passed for buffArr"); 1940 LOG_FUNCTION_NAME_EXIT; 1941 return BAD_VALUE; 1942 } 1943 1944 OMXCameraPortParameters * mPreviewData = NULL; 1945 OMXCameraPortParameters *measurementData = NULL; 1946 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 1947 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 1948 mPreviewData->mNumBufs = num ; 1949 1950 if ( 0 != mUsePreviewSem.Count() ) 1951 { 1952 CAMHAL_LOGEB("Error mUsePreviewSem semaphore count %d", mUsePreviewSem.Count()); 1953 LOG_FUNCTION_NAME_EXIT; 1954 return NO_INIT; 1955 } 1956 1957 if(mPreviewData->mNumBufs != num) 1958 { 1959 CAMHAL_LOGEA("Current number of buffers doesnt equal new num of buffers passed!"); 1960 LOG_FUNCTION_NAME_EXIT; 1961 return BAD_VALUE; 1962 } 1963 1964 mStateSwitchLock.lock(); 1965 1966 if ( mComponentState == OMX_StateLoaded ) { 1967 1968 if (mPendingPreviewSettings & SetLDC) { 1969 mPendingPreviewSettings &= ~SetLDC; 1970 ret = setLDC(mIPP); 1971 if ( NO_ERROR != ret ) { 1972 CAMHAL_LOGEB("setLDC() failed %d", ret); 1973 } 1974 } 1975 1976 if (mPendingPreviewSettings & SetNSF) { 1977 mPendingPreviewSettings &= ~SetNSF; 1978 ret = setNSF(mIPP); 1979 if ( NO_ERROR != ret ) { 1980 CAMHAL_LOGEB("setNSF() failed %d", ret); 1981 } 1982 } 1983 1984 if (mPendingPreviewSettings & SetCapMode) { 1985 mPendingPreviewSettings &= ~SetCapMode; 1986 ret = setCaptureMode(mCapMode); 1987 if ( NO_ERROR != ret ) { 1988 CAMHAL_LOGEB("setCaptureMode() failed %d", ret); 1989 } 1990 } 1991 1992 if( (mCapMode == OMXCameraAdapter::VIDEO_MODE) || 1993 (mCapMode == OMXCameraAdapter::VIDEO_MODE_HQ) ) { 1994 1995 if (mPendingPreviewSettings & SetVNF) { 1996 mPendingPreviewSettings &= ~SetVNF; 1997 ret = enableVideoNoiseFilter(mVnfEnabled); 1998 if ( NO_ERROR != ret){ 1999 CAMHAL_LOGEB("Error configuring VNF %x", ret); 2000 } 2001 } 2002 2003 if (mPendingPreviewSettings & SetVSTAB) { 2004 mPendingPreviewSettings &= ~SetVSTAB; 2005 ret = enableVideoStabilization(mVstabEnabled); 2006 if ( NO_ERROR != ret) { 2007 CAMHAL_LOGEB("Error configuring VSTAB %x", ret); 2008 } 2009 } 2010 2011 } 2012 } 2013 2014 ret = setSensorOrientation(mSensorOrientation); 2015 if ( NO_ERROR != ret ) 2016 { 2017 CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret); 2018 mSensorOrientation = 0; 2019 } 2020 2021 if ( mComponentState == OMX_StateLoaded ) 2022 { 2023 ///Register for IDLE state switch event 2024 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 2025 OMX_EventCmdComplete, 2026 OMX_CommandStateSet, 2027 OMX_StateIdle, 2028 mUsePreviewSem); 2029 2030 if(ret!=NO_ERROR) 2031 { 2032 CAMHAL_LOGEB("Error in registering for event %d", ret); 2033 goto EXIT; 2034 } 2035 2036 ///Once we get the buffers, move component state to idle state and pass the buffers to OMX comp using UseBuffer 2037 eError = OMX_SendCommand (mCameraAdapterParameters.mHandleComp , 2038 OMX_CommandStateSet, 2039 OMX_StateIdle, 2040 NULL); 2041 2042 CAMHAL_LOGDB("OMX_SendCommand(OMX_CommandStateSet) 0x%x", eError); 2043 2044 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2045 2046 mComponentState = OMX_StateIdle; 2047 } 2048 else 2049 { 2050 ///Register for Preview port ENABLE event 2051 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 2052 OMX_EventCmdComplete, 2053 OMX_CommandPortEnable, 2054 mCameraAdapterParameters.mPrevPortIndex, 2055 mUsePreviewSem); 2056 2057 if ( NO_ERROR != ret ) 2058 { 2059 CAMHAL_LOGEB("Error in registering for event %d", ret); 2060 goto EXIT; 2061 } 2062 2063 ///Enable Preview Port 2064 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 2065 OMX_CommandPortEnable, 2066 mCameraAdapterParameters.mPrevPortIndex, 2067 NULL); 2068 } 2069 2070 2071 ///Configure DOMX to use either gralloc handles or vptrs 2072 OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles; 2073 OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER); 2074 2075 domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 2076 domxUseGrallocHandles.bEnable = OMX_TRUE; 2077 2078 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 2079 (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles); 2080 if(eError!=OMX_ErrorNone) 2081 { 2082 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 2083 } 2084 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2085 2086 OMX_BUFFERHEADERTYPE *pBufferHdr; 2087 for(int index=0;index<num;index++) { 2088 OMX_U8 *ptr; 2089 2090 ptr = (OMX_U8 *)camera_buffer_get_omx_ptr (&bufArr[index]); 2091 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp, 2092 &pBufferHdr, 2093 mCameraAdapterParameters.mPrevPortIndex, 2094 0, 2095 mPreviewData->mBufSize, 2096 ptr); 2097 if(eError!=OMX_ErrorNone) 2098 { 2099 CAMHAL_LOGEB("OMX_UseBuffer-0x%x", eError); 2100 } 2101 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2102 2103 pBufferHdr->pAppPrivate = (OMX_PTR)&bufArr[index]; 2104 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2105 pBufferHdr->nVersion.s.nVersionMajor = 1 ; 2106 pBufferHdr->nVersion.s.nVersionMinor = 1 ; 2107 pBufferHdr->nVersion.s.nRevision = 0 ; 2108 pBufferHdr->nVersion.s.nStep = 0; 2109 mPreviewData->mBufferHeader[index] = pBufferHdr; 2110 } 2111 2112 if ( mMeasurementEnabled ) 2113 { 2114 2115 for( int i = 0; i < num; i++ ) 2116 { 2117 OMX_BUFFERHEADERTYPE *pBufHdr; 2118 OMX_U8 *ptr; 2119 2120 ptr = (OMX_U8 *)camera_buffer_get_omx_ptr (&mPreviewDataBuffers[i]); 2121 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp, 2122 &pBufHdr, 2123 mCameraAdapterParameters.mMeasurementPortIndex, 2124 0, 2125 measurementData->mBufSize, 2126 ptr); 2127 2128 if ( eError == OMX_ErrorNone ) 2129 { 2130 pBufHdr->pAppPrivate = (OMX_PTR *)&mPreviewDataBuffers[i]; 2131 pBufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2132 pBufHdr->nVersion.s.nVersionMajor = 1 ; 2133 pBufHdr->nVersion.s.nVersionMinor = 1 ; 2134 pBufHdr->nVersion.s.nRevision = 0 ; 2135 pBufHdr->nVersion.s.nStep = 0; 2136 measurementData->mBufferHeader[i] = pBufHdr; 2137 } 2138 else 2139 { 2140 CAMHAL_LOGEB("OMX_UseBuffer -0x%x", eError); 2141 ret = BAD_VALUE; 2142 break; 2143 } 2144 } 2145 2146 } 2147 2148 CAMHAL_LOGDA("Registering preview buffers"); 2149 2150 ret = mUsePreviewSem.WaitTimeout(OMX_CMD_TIMEOUT); 2151 2152 //If somethiing bad happened while we wait 2153 if (mComponentState == OMX_StateInvalid) 2154 { 2155 CAMHAL_LOGEA("Invalid State after Registering preview buffers Exitting!!!"); 2156 goto EXIT; 2157 } 2158 2159 if ( NO_ERROR == ret ) 2160 { 2161 CAMHAL_LOGDA("Preview buffer registration successfull"); 2162 } 2163 else 2164 { 2165 if ( mComponentState == OMX_StateLoaded ) 2166 { 2167 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 2168 OMX_EventCmdComplete, 2169 OMX_CommandStateSet, 2170 OMX_StateIdle, 2171 NULL); 2172 } 2173 else 2174 { 2175 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 2176 OMX_EventCmdComplete, 2177 OMX_CommandPortEnable, 2178 mCameraAdapterParameters.mPrevPortIndex, 2179 NULL); 2180 } 2181 CAMHAL_LOGEA("Timeout expired on preview buffer registration"); 2182 goto EXIT; 2183 } 2184 2185 LOG_FUNCTION_NAME_EXIT; 2186 2187 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2188 2189 ///If there is any failure, we reach here. 2190 ///Here, we do any resource freeing and convert from OMX error code to Camera Hal error code 2191 EXIT: 2192 mStateSwitchLock.unlock(); 2193 2194 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 2195 performCleanupAfterError(); 2196 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 2197 2198 LOG_FUNCTION_NAME_EXIT; 2199 2200 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2201 } 2202 2203 status_t OMXCameraAdapter::startPreview() 2204 { 2205 status_t ret = NO_ERROR; 2206 OMX_ERRORTYPE eError = OMX_ErrorNone; 2207 OMXCameraPortParameters *mPreviewData = NULL; 2208 OMXCameraPortParameters *measurementData = NULL; 2209 2210 LOG_FUNCTION_NAME; 2211 2212 if( 0 != mStartPreviewSem.Count() ) 2213 { 2214 CAMHAL_LOGEB("Error mStartPreviewSem semaphore count %d", mStartPreviewSem.Count()); 2215 ret = NO_INIT; 2216 goto EXIT; 2217 } 2218 2219 // Enable all preview mode extra data. 2220 if ( OMX_ErrorNone == eError) { 2221 ret |= setExtraData(true, mCameraAdapterParameters.mPrevPortIndex, OMX_AncillaryData); 2222 ret |= setExtraData(true, OMX_ALL, OMX_TI_VectShotInfo); 2223 } 2224 2225 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 2226 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 2227 2228 if( OMX_StateIdle == mComponentState ) 2229 { 2230 ///Register for EXECUTING state transition. 2231 ///This method just inserts a message in Event Q, which is checked in the callback 2232 ///The sempahore passed is signalled by the callback 2233 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 2234 OMX_EventCmdComplete, 2235 OMX_CommandStateSet, 2236 OMX_StateExecuting, 2237 mStartPreviewSem); 2238 2239 if(ret!=NO_ERROR) 2240 { 2241 CAMHAL_LOGEB("Error in registering for event %d", ret); 2242 goto EXIT; 2243 } 2244 2245 ///Switch to EXECUTING state 2246 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 2247 OMX_CommandStateSet, 2248 OMX_StateExecuting, 2249 NULL); 2250 2251 if(eError!=OMX_ErrorNone) 2252 { 2253 CAMHAL_LOGEB("OMX_SendCommand(OMX_StateExecuting)-0x%x", eError); 2254 } 2255 2256 CAMHAL_LOGDA("+Waiting for component to go into EXECUTING state"); 2257 ret = mStartPreviewSem.WaitTimeout(OMX_CMD_TIMEOUT); 2258 2259 //If somethiing bad happened while we wait 2260 if (mComponentState == OMX_StateInvalid) 2261 { 2262 CAMHAL_LOGEA("Invalid State after IDLE_EXECUTING Exitting!!!"); 2263 goto EXIT; 2264 } 2265 2266 if ( NO_ERROR == ret ) 2267 { 2268 CAMHAL_LOGDA("+Great. Component went into executing state!!"); 2269 } 2270 else 2271 { 2272 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 2273 OMX_EventCmdComplete, 2274 OMX_CommandStateSet, 2275 OMX_StateExecuting, 2276 NULL); 2277 CAMHAL_LOGDA("Timeout expired on executing state switch!"); 2278 goto EXIT; 2279 } 2280 2281 mComponentState = OMX_StateExecuting; 2282 2283 } 2284 2285 mStateSwitchLock.unlock(); 2286 2287 //Queue all the buffers on preview port 2288 for(int index=0;index< mPreviewData->mMaxQueueable;index++) 2289 { 2290 CAMHAL_LOGDB("Queuing buffer on Preview port - 0x%x", (uint32_t)mPreviewData->mBufferHeader[index]->pBuffer); 2291 mPreviewData->mStatus[index] = OMXCameraPortParameters::FILL; 2292 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 2293 (OMX_BUFFERHEADERTYPE*)mPreviewData->mBufferHeader[index]); 2294 if(eError!=OMX_ErrorNone) 2295 { 2296 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError); 2297 } 2298 mFramesWithDucati++; 2299 #ifdef CAMERAHAL_DEBUG 2300 mBuffersWithDucati.add((int)mPreviewData->mBufferHeader[index]->pBuffer,1); 2301 #endif 2302 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2303 } 2304 2305 if ( mMeasurementEnabled ) 2306 { 2307 2308 for(int index=0;index< mPreviewData->mNumBufs;index++) 2309 { 2310 CAMHAL_LOGDB("Queuing buffer on Measurement port - 0x%x", (uint32_t) measurementData->mBufferHeader[index]->pBuffer); 2311 measurementData->mStatus[index] = OMXCameraPortParameters::FILL; 2312 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 2313 (OMX_BUFFERHEADERTYPE*) measurementData->mBufferHeader[index]); 2314 if(eError!=OMX_ErrorNone) 2315 { 2316 CAMHAL_LOGEB("OMX_FillThisBuffer-0x%x", eError); 2317 } 2318 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 2319 } 2320 2321 } 2322 2323 setFocusCallback(true); 2324 2325 //reset frame rate estimates 2326 mFPS = 0.0f; 2327 mLastFPS = 0.0f; 2328 // start frame count from 0. i.e first frame after 2329 // startPreview will be the 0th reference frame 2330 // this way we will wait for second frame until 2331 // takePicture/autoFocus is allowed to run. we 2332 // are seeing SetConfig/GetConfig fail after 2333 // calling after the first frame and not failing 2334 // after the second frame 2335 mFrameCount = -1; 2336 mLastFrameCount = 0; 2337 mIter = 1; 2338 mLastFPSTime = systemTime(); 2339 mTunnelDestroyed = false; 2340 2341 LOG_FUNCTION_NAME_EXIT; 2342 2343 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2344 2345 EXIT: 2346 2347 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 2348 performCleanupAfterError(); 2349 mStateSwitchLock.unlock(); 2350 LOG_FUNCTION_NAME_EXIT; 2351 2352 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2353 2354 } 2355 2356 status_t OMXCameraAdapter::destroyTunnel() 2357 { 2358 LOG_FUNCTION_NAME; 2359 2360 OMX_ERRORTYPE eError = OMX_ErrorNone; 2361 status_t ret = NO_ERROR; 2362 2363 OMXCameraPortParameters *mCaptureData , *mPreviewData, *measurementData; 2364 mCaptureData = mPreviewData = measurementData = NULL; 2365 2366 mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; 2367 mCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 2368 measurementData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mMeasurementPortIndex]; 2369 2370 if (mAdapterState == LOADED_PREVIEW_STATE) { 2371 // Something happened in CameraHal between UseBuffers and startPreview 2372 // this means that state switch is still locked..so we need to unlock else 2373 // deadlock will occur on the next start preview 2374 mStateSwitchLock.unlock(); 2375 return ALREADY_EXISTS; 2376 } 2377 2378 if ( mComponentState != OMX_StateExecuting ) 2379 { 2380 CAMHAL_LOGEA("Calling StopPreview() when not in EXECUTING state"); 2381 LOG_FUNCTION_NAME_EXIT; 2382 return NO_INIT; 2383 } 2384 2385 { 2386 android::AutoMutex lock(mFrameCountMutex); 2387 // we should wait for the first frame to come before trying to stopPreview...if not 2388 // we might put OMXCamera in a bad state (IDLE->LOADED timeout). Seeing this a lot 2389 // after a capture 2390 if (mFrameCount < 1) { 2391 // I want to wait for at least two frames.... 2392 mFrameCount = -1; 2393 2394 // first frame may time some time to come...so wait for an adequate amount of time 2395 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover. 2396 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex, 2397 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000); 2398 } 2399 // even if we timeout waiting for the first frame...go ahead with trying to stop preview 2400 // signal anybody that might be waiting 2401 mFrameCount = 0; 2402 mFirstFrameCondition.broadcast(); 2403 } 2404 2405 { 2406 android::AutoMutex lock(mDoAFMutex); 2407 mDoAFCond.broadcast(); 2408 } 2409 2410 OMX_CONFIG_FOCUSASSISTTYPE focusAssist; 2411 OMX_INIT_STRUCT_PTR (&focusAssist, OMX_CONFIG_FOCUSASSISTTYPE); 2412 focusAssist.nPortIndex = OMX_ALL; 2413 focusAssist.bFocusAssist = OMX_FALSE; 2414 CAMHAL_LOGDB("Configuring AF Assist mode 0x%x", focusAssist.bFocusAssist); 2415 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 2416 (OMX_INDEXTYPE) OMX_IndexConfigFocusAssist, 2417 &focusAssist); 2418 if ( OMX_ErrorNone != eError ) 2419 { 2420 CAMHAL_LOGEB("Error while configuring AF Assist mode 0x%x", eError); 2421 } 2422 else 2423 { 2424 CAMHAL_LOGDA("Camera AF Assist mode configured successfully"); 2425 } 2426 2427 if ( 0 != mStopPreviewSem.Count() ) 2428 { 2429 CAMHAL_LOGEB("Error mStopPreviewSem semaphore count %d", mStopPreviewSem.Count()); 2430 LOG_FUNCTION_NAME_EXIT; 2431 return NO_INIT; 2432 } 2433 2434 ret = disableImagePort(); 2435 if ( NO_ERROR != ret ) { 2436 CAMHAL_LOGEB("disable image port failed 0x%x", ret); 2437 goto EXIT; 2438 } 2439 2440 CAMHAL_LOGDB("Average framerate: %f", mFPS); 2441 2442 //Avoid state switching of the OMX Component 2443 ret = flushBuffers(); 2444 if ( NO_ERROR != ret ) 2445 { 2446 CAMHAL_LOGEB("Flush Buffers failed 0x%x", ret); 2447 goto EXIT; 2448 } 2449 2450 switchToIdle(); 2451 2452 mTunnelDestroyed = true; 2453 LOG_FUNCTION_NAME_EXIT; 2454 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2455 2456 EXIT: 2457 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 2458 { 2459 android::AutoMutex lock(mPreviewBufferLock); 2460 ///Clear all the available preview buffers 2461 mPreviewBuffersAvailable.clear(); 2462 } 2463 performCleanupAfterError(); 2464 LOG_FUNCTION_NAME_EXIT; 2465 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2466 2467 } 2468 2469 status_t OMXCameraAdapter::stopPreview() { 2470 LOG_FUNCTION_NAME; 2471 2472 OMX_ERRORTYPE eError = OMX_ErrorNone; 2473 status_t ret = NO_ERROR; 2474 2475 if (mTunnelDestroyed == false){ 2476 ret = destroyTunnel(); 2477 if (ret == ALREADY_EXISTS) { 2478 // Special case to handle invalid stopping preview in LOADED_PREVIEW_STATE 2479 return NO_ERROR; 2480 } 2481 if (ret != NO_ERROR) { 2482 CAMHAL_LOGEB(" destroyTunnel returned error "); 2483 return ret; 2484 } 2485 } 2486 2487 mTunnelDestroyed = false; 2488 2489 { 2490 android::AutoMutex lock(mPreviewBufferLock); 2491 ///Clear all the available preview buffers 2492 mPreviewBuffersAvailable.clear(); 2493 } 2494 2495 switchToLoaded(); 2496 2497 mFirstTimeInit = true; 2498 mPendingCaptureSettings = 0; 2499 mPendingReprocessSettings = 0; 2500 mFramesWithDucati = 0; 2501 mFramesWithDisplay = 0; 2502 mFramesWithEncoder = 0; 2503 2504 LOG_FUNCTION_NAME_EXIT; 2505 2506 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 2507 } 2508 2509 status_t OMXCameraAdapter::setSensorOverclock(bool enable) 2510 { 2511 status_t ret = NO_ERROR; 2512 OMX_ERRORTYPE eError = OMX_ErrorNone; 2513 OMX_CONFIG_BOOLEANTYPE bOMX; 2514 2515 LOG_FUNCTION_NAME; 2516 2517 if ( OMX_StateLoaded != mComponentState ) 2518 { 2519 CAMHAL_LOGDA("OMX component is not in loaded state"); 2520 return ret; 2521 } 2522 2523 if ( NO_ERROR == ret ) 2524 { 2525 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 2526 2527 if ( enable ) 2528 { 2529 bOMX.bEnabled = OMX_TRUE; 2530 } 2531 else 2532 { 2533 bOMX.bEnabled = OMX_FALSE; 2534 } 2535 2536 CAMHAL_LOGDB("Configuring Sensor overclock mode 0x%x", bOMX.bEnabled); 2537 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParamSensorOverClockMode, &bOMX); 2538 if ( OMX_ErrorNone != eError ) 2539 { 2540 CAMHAL_LOGEB("Error while setting Sensor overclock 0x%x", eError); 2541 } 2542 else 2543 { 2544 mSensorOverclock = enable; 2545 } 2546 } 2547 2548 LOG_FUNCTION_NAME_EXIT; 2549 2550 return Utils::ErrorUtils::omxToAndroidError(eError); 2551 } 2552 2553 status_t OMXCameraAdapter::printComponentVersion(OMX_HANDLETYPE handle) 2554 { 2555 status_t ret = NO_ERROR; 2556 OMX_ERRORTYPE eError = OMX_ErrorNone; 2557 OMX_VERSIONTYPE compVersion; 2558 char compName[OMX_MAX_STRINGNAME_SIZE]; 2559 char *currentUUID = NULL; 2560 size_t offset = 0; 2561 2562 LOG_FUNCTION_NAME; 2563 2564 if ( NULL == handle ) 2565 { 2566 CAMHAL_LOGEB("Invalid OMX Handle =0x%x", ( unsigned int ) handle); 2567 ret = -EINVAL; 2568 } 2569 2570 mCompUUID[0] = 0; 2571 2572 if ( NO_ERROR == ret ) 2573 { 2574 eError = OMX_GetComponentVersion(handle, 2575 compName, 2576 &compVersion, 2577 &mCompRevision, 2578 &mCompUUID 2579 ); 2580 if ( OMX_ErrorNone != eError ) 2581 { 2582 CAMHAL_LOGEB("OMX_GetComponentVersion returned 0x%x", eError); 2583 ret = BAD_VALUE; 2584 } 2585 } 2586 2587 if ( NO_ERROR == ret ) 2588 { 2589 CAMHAL_LOGVB("OMX Component name: [%s]", compName); 2590 CAMHAL_LOGVB("OMX Component version: [%u]", ( unsigned int ) compVersion.nVersion); 2591 CAMHAL_LOGVB("Spec version: [%u]", ( unsigned int ) mCompRevision.nVersion); 2592 CAMHAL_LOGVB("Git Commit ID: [%s]", mCompUUID); 2593 currentUUID = ( char * ) mCompUUID; 2594 } 2595 2596 if ( NULL != currentUUID ) 2597 { 2598 offset = strlen( ( const char * ) mCompUUID) + 1; 2599 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE ) 2600 { 2601 currentUUID += offset; 2602 CAMHAL_LOGVB("Git Branch: [%s]", currentUUID); 2603 } 2604 else 2605 { 2606 ret = BAD_VALUE; 2607 } 2608 } 2609 2610 if ( NO_ERROR == ret ) 2611 { 2612 offset = strlen( ( const char * ) currentUUID) + 1; 2613 2614 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE ) 2615 { 2616 currentUUID += offset; 2617 CAMHAL_LOGVB("Build date and time: [%s]", currentUUID); 2618 } 2619 else 2620 { 2621 ret = BAD_VALUE; 2622 } 2623 } 2624 2625 if ( NO_ERROR == ret ) 2626 { 2627 offset = strlen( ( const char * ) currentUUID) + 1; 2628 2629 if ( (int)currentUUID + (int)offset - (int)mCompUUID < OMX_MAX_STRINGNAME_SIZE ) 2630 { 2631 currentUUID += offset; 2632 CAMHAL_LOGVB("Build description: [%s]", currentUUID); 2633 } 2634 else 2635 { 2636 ret = BAD_VALUE; 2637 } 2638 } 2639 2640 LOG_FUNCTION_NAME_EXIT; 2641 2642 return ret; 2643 } 2644 2645 status_t OMXCameraAdapter::setS3DFrameLayout(OMX_U32 port) const 2646 { 2647 OMX_ERRORTYPE eError = OMX_ErrorNone; 2648 OMX_TI_FRAMELAYOUTTYPE frameLayout; 2649 const OMXCameraPortParameters *cap = 2650 &mCameraAdapterParameters.mCameraPortParams[port]; 2651 2652 LOG_FUNCTION_NAME; 2653 2654 OMX_INIT_STRUCT_PTR (&frameLayout, OMX_TI_FRAMELAYOUTTYPE); 2655 frameLayout.nPortIndex = port; 2656 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, 2657 (OMX_INDEXTYPE)OMX_TI_IndexParamStereoFrmLayout, &frameLayout); 2658 if (eError != OMX_ErrorNone) 2659 { 2660 CAMHAL_LOGEB("Error while getting S3D frame layout: 0x%x", eError); 2661 return -EINVAL; 2662 } 2663 2664 if (cap->mFrameLayoutType == OMX_TI_StereoFrameLayoutTopBottomSubsample) 2665 { 2666 frameLayout.eFrameLayout = OMX_TI_StereoFrameLayoutTopBottom; 2667 frameLayout.nSubsampleRatio = 2; 2668 } 2669 else if (cap->mFrameLayoutType == 2670 OMX_TI_StereoFrameLayoutLeftRightSubsample) 2671 { 2672 frameLayout.eFrameLayout = OMX_TI_StereoFrameLayoutLeftRight; 2673 frameLayout.nSubsampleRatio = 2; 2674 } 2675 else 2676 { 2677 frameLayout.eFrameLayout = cap->mFrameLayoutType; 2678 frameLayout.nSubsampleRatio = 1; 2679 } 2680 frameLayout.nSubsampleRatio = frameLayout.nSubsampleRatio << 7; 2681 2682 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 2683 (OMX_INDEXTYPE)OMX_TI_IndexParamStereoFrmLayout, &frameLayout); 2684 if (eError != OMX_ErrorNone) 2685 { 2686 CAMHAL_LOGEB("Error while setting S3D frame layout: 0x%x", eError); 2687 return -EINVAL; 2688 } 2689 else 2690 { 2691 CAMHAL_LOGDB("S3D frame layout %d applied successfully on port %lu", 2692 frameLayout.eFrameLayout, port); 2693 } 2694 2695 LOG_FUNCTION_NAME_EXIT; 2696 2697 return NO_ERROR; 2698 } 2699 2700 status_t OMXCameraAdapter::autoFocus() 2701 { 2702 status_t ret = NO_ERROR; 2703 Utils::Message msg; 2704 2705 LOG_FUNCTION_NAME; 2706 2707 { 2708 android::AutoMutex lock(mFrameCountMutex); 2709 if (mFrameCount < 1) { 2710 // first frame may time some time to come...so wait for an adequate amount of time 2711 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover. 2712 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex, 2713 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000); 2714 if ((NO_ERROR != ret) || (mFrameCount == 0)) { 2715 goto EXIT; 2716 } 2717 } 2718 } 2719 2720 msg.command = CommandHandler::CAMERA_PERFORM_AUTOFOCUS; 2721 msg.arg1 = mErrorNotifier; 2722 ret = mCommandHandler->put(&msg); 2723 2724 EXIT: 2725 2726 LOG_FUNCTION_NAME_EXIT; 2727 2728 return ret; 2729 } 2730 2731 status_t OMXCameraAdapter::takePicture() 2732 { 2733 status_t ret = NO_ERROR; 2734 Utils::Message msg; 2735 2736 LOG_FUNCTION_NAME; 2737 2738 if (mNextState != REPROCESS_STATE) { 2739 android::AutoMutex lock(mFrameCountMutex); 2740 if (mFrameCount < 1) { 2741 // first frame may time some time to come...so wait for an adequate amount of time 2742 // which 2 * OMX_CAPTURE_TIMEOUT * 1000 will cover. 2743 ret = mFirstFrameCondition.waitRelative(mFrameCountMutex, 2744 (nsecs_t) 2 * OMX_CAPTURE_TIMEOUT * 1000); 2745 if ((NO_ERROR != ret) || (mFrameCount == 0)) { 2746 goto EXIT; 2747 } 2748 } 2749 } 2750 2751 // TODO(XXX): re-using take picture to kick off reprocessing pipe 2752 // Need to rethink this approach during reimplementation 2753 if (mNextState == REPROCESS_STATE) { 2754 msg.command = CommandHandler::CAMERA_START_REPROCESS; 2755 } else { 2756 msg.command = CommandHandler::CAMERA_START_IMAGE_CAPTURE; 2757 } 2758 2759 msg.arg1 = mErrorNotifier; 2760 msg.arg2 = cacheCaptureParameters(); 2761 ret = mCommandHandler->put(&msg); 2762 2763 EXIT: 2764 LOG_FUNCTION_NAME_EXIT; 2765 2766 return ret; 2767 } 2768 2769 status_t OMXCameraAdapter::startVideoCapture() 2770 { 2771 return BaseCameraAdapter::startVideoCapture(); 2772 } 2773 2774 status_t OMXCameraAdapter::stopVideoCapture() 2775 { 2776 return BaseCameraAdapter::stopVideoCapture(); 2777 } 2778 2779 //API to get the frame size required to be allocated. This size is used to override the size passed 2780 //by camera service when VSTAB/VNF is turned ON for example 2781 status_t OMXCameraAdapter::getFrameSize(size_t &width, size_t &height) 2782 { 2783 status_t ret = NO_ERROR; 2784 OMX_ERRORTYPE eError = OMX_ErrorNone; 2785 OMX_CONFIG_RECTTYPE tFrameDim; 2786 2787 LOG_FUNCTION_NAME; 2788 2789 OMX_INIT_STRUCT_PTR (&tFrameDim, OMX_CONFIG_RECTTYPE); 2790 tFrameDim.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; 2791 2792 if ( mOMXStateSwitch ) 2793 { 2794 ret = switchToLoaded(true); 2795 if ( NO_ERROR != ret ) 2796 { 2797 CAMHAL_LOGEB("switchToLoaded() failed 0x%x", ret); 2798 goto exit; 2799 } 2800 2801 mOMXStateSwitch = false; 2802 } 2803 2804 if ( OMX_StateLoaded == mComponentState ) 2805 { 2806 2807 if (mPendingPreviewSettings & SetLDC) { 2808 mPendingPreviewSettings &= ~SetLDC; 2809 ret = setLDC(mIPP); 2810 if ( NO_ERROR != ret ) { 2811 CAMHAL_LOGEB("setLDC() failed %d", ret); 2812 LOG_FUNCTION_NAME_EXIT; 2813 goto exit; 2814 } 2815 } 2816 2817 if (mPendingPreviewSettings & SetNSF) { 2818 mPendingPreviewSettings &= ~SetNSF; 2819 ret = setNSF(mIPP); 2820 if ( NO_ERROR != ret ) { 2821 CAMHAL_LOGEB("setNSF() failed %d", ret); 2822 LOG_FUNCTION_NAME_EXIT; 2823 goto exit; 2824 } 2825 } 2826 2827 if (mPendingPreviewSettings & SetCapMode) { 2828 mPendingPreviewSettings &= ~SetCapMode; 2829 ret = setCaptureMode(mCapMode); 2830 if ( NO_ERROR != ret ) { 2831 CAMHAL_LOGEB("setCaptureMode() failed %d", ret); 2832 } 2833 } 2834 2835 if((mCapMode == OMXCameraAdapter::VIDEO_MODE) || 2836 (mCapMode == OMXCameraAdapter::VIDEO_MODE_HQ) ) { 2837 2838 if (mPendingPreviewSettings & SetVNF) { 2839 mPendingPreviewSettings &= ~SetVNF; 2840 ret = enableVideoNoiseFilter(mVnfEnabled); 2841 if ( NO_ERROR != ret){ 2842 CAMHAL_LOGEB("Error configuring VNF %x", ret); 2843 } 2844 } 2845 2846 if (mPendingPreviewSettings & SetVSTAB) { 2847 mPendingPreviewSettings &= ~SetVSTAB; 2848 ret = enableVideoStabilization(mVstabEnabled); 2849 if ( NO_ERROR != ret) { 2850 CAMHAL_LOGEB("Error configuring VSTAB %x", ret); 2851 } 2852 } 2853 2854 } 2855 } 2856 2857 ret = setSensorOrientation(mSensorOrientation); 2858 if ( NO_ERROR != ret ) 2859 { 2860 CAMHAL_LOGEB("Error configuring Sensor Orientation %x", ret); 2861 mSensorOrientation = 0; 2862 } 2863 2864 if ( NO_ERROR == ret ) 2865 { 2866 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexParam2DBufferAllocDimension, &tFrameDim); 2867 if ( OMX_ErrorNone == eError) 2868 { 2869 width = tFrameDim.nWidth; 2870 height = tFrameDim.nHeight; 2871 } 2872 } 2873 2874 exit: 2875 2876 CAMHAL_LOGDB("Required frame size %dx%d", width, height); 2877 LOG_FUNCTION_NAME_EXIT; 2878 2879 return ret; 2880 } 2881 2882 status_t OMXCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount) 2883 { 2884 status_t ret = NO_ERROR; 2885 OMX_PARAM_PORTDEFINITIONTYPE portCheck; 2886 OMX_ERRORTYPE eError = OMX_ErrorNone; 2887 2888 LOG_FUNCTION_NAME; 2889 2890 if ( OMX_StateLoaded != mComponentState ) 2891 { 2892 CAMHAL_LOGEA("Calling getFrameDataSize() when not in LOADED state"); 2893 dataFrameSize = 0; 2894 ret = BAD_VALUE; 2895 } 2896 2897 if ( NO_ERROR == ret ) 2898 { 2899 OMX_INIT_STRUCT_PTR(&portCheck, OMX_PARAM_PORTDEFINITIONTYPE); 2900 portCheck.nPortIndex = mCameraAdapterParameters.mMeasurementPortIndex; 2901 2902 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck); 2903 if ( OMX_ErrorNone != eError ) 2904 { 2905 CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError); 2906 dataFrameSize = 0; 2907 ret = BAD_VALUE; 2908 } 2909 } 2910 2911 if ( NO_ERROR == ret ) 2912 { 2913 portCheck.nBufferCountActual = bufferCount; 2914 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck); 2915 if ( OMX_ErrorNone != eError ) 2916 { 2917 CAMHAL_LOGEB("OMX_SetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError); 2918 dataFrameSize = 0; 2919 ret = BAD_VALUE; 2920 } 2921 } 2922 2923 if ( NO_ERROR == ret ) 2924 { 2925 eError = OMX_GetParameter(mCameraAdapterParameters.mHandleComp, OMX_IndexParamPortDefinition, &portCheck); 2926 if ( OMX_ErrorNone != eError ) 2927 { 2928 CAMHAL_LOGEB("OMX_GetParameter on OMX_IndexParamPortDefinition returned: 0x%x", eError); 2929 ret = BAD_VALUE; 2930 } 2931 else 2932 { 2933 mCameraAdapterParameters.mCameraPortParams[portCheck.nPortIndex].mBufSize = portCheck.nBufferSize; 2934 dataFrameSize = portCheck.nBufferSize; 2935 } 2936 } 2937 2938 LOG_FUNCTION_NAME_EXIT; 2939 2940 return ret; 2941 } 2942 2943 void OMXCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt) 2944 { 2945 LOG_FUNCTION_NAME; 2946 2947 static const unsigned int DEGREES_TILT_IGNORE = 45; 2948 2949 // if tilt angle is greater than DEGREES_TILT_IGNORE 2950 // we are going to ignore the orientation returned from 2951 // sensor. the orientation returned from sensor is not 2952 // reliable. Value of DEGREES_TILT_IGNORE may need adjusting 2953 if (tilt > DEGREES_TILT_IGNORE) { 2954 return; 2955 } 2956 2957 int mountOrientation = 0; 2958 bool isFront = false; 2959 if (mCapabilities) { 2960 const char * const mountOrientationString = 2961 mCapabilities->get(CameraProperties::ORIENTATION_INDEX); 2962 if (mountOrientationString) { 2963 mountOrientation = atoi(mountOrientationString); 2964 } 2965 2966 const char * const facingString = mCapabilities->get(CameraProperties::FACING_INDEX); 2967 if (facingString) { 2968 isFront = strcmp(facingString, TICameraParameters::FACING_FRONT) == 0; 2969 } 2970 } 2971 2972 // direction is a constant sign for facing, meaning the rotation direction relative to device 2973 // +1 (clockwise) for back sensor and -1 (counter-clockwise) for front sensor 2974 const int direction = isFront ? -1 : 1; 2975 2976 int rotation = mountOrientation + direction*orientation; 2977 2978 // crop the calculated value to [0..360) range 2979 while ( rotation < 0 ) rotation += 360; 2980 rotation %= 360; 2981 2982 if (rotation != mDeviceOrientation) { 2983 mDeviceOrientation = rotation; 2984 2985 // restart face detection with new rotation 2986 setFaceDetectionOrientation(mDeviceOrientation); 2987 } 2988 CAMHAL_LOGVB("orientation = %d tilt = %d device_orientation = %d", orientation, tilt, mDeviceOrientation); 2989 2990 LOG_FUNCTION_NAME_EXIT; 2991 } 2992 2993 /* Application callback Functions */ 2994 /*========================================================*/ 2995 /* @ fn SampleTest_EventHandler :: Application callback */ 2996 /*========================================================*/ 2997 OMX_ERRORTYPE OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent, 2998 OMX_IN OMX_PTR pAppData, 2999 OMX_IN OMX_EVENTTYPE eEvent, 3000 OMX_IN OMX_U32 nData1, 3001 OMX_IN OMX_U32 nData2, 3002 OMX_IN OMX_PTR pEventData) 3003 { 3004 LOG_FUNCTION_NAME; 3005 3006 CAMHAL_LOGDB("Event %d", eEvent); 3007 3008 OMX_ERRORTYPE ret = OMX_ErrorNone; 3009 OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData; 3010 ret = oca->OMXCameraAdapterEventHandler(hComponent, eEvent, nData1, nData2, pEventData); 3011 3012 LOG_FUNCTION_NAME_EXIT; 3013 return ret; 3014 } 3015 3016 /* Application callback Functions */ 3017 /*========================================================*/ 3018 /* @ fn SampleTest_EventHandler :: Application callback */ 3019 /*========================================================*/ 3020 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent, 3021 OMX_IN OMX_EVENTTYPE eEvent, 3022 OMX_IN OMX_U32 nData1, 3023 OMX_IN OMX_U32 nData2, 3024 OMX_IN OMX_PTR pEventData) 3025 { 3026 3027 LOG_FUNCTION_NAME; 3028 3029 OMX_ERRORTYPE eError = OMX_ErrorNone; 3030 CAMHAL_LOGDB("+OMX_Event %x, %d %d", eEvent, (int)nData1, (int)nData2); 3031 3032 switch (eEvent) { 3033 case OMX_EventCmdComplete: 3034 CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d", (int)nData1, (int)nData2); 3035 3036 if (OMX_CommandStateSet == nData1) { 3037 mCameraAdapterParameters.mState = (OMX_STATETYPE) nData2; 3038 3039 } else if (OMX_CommandFlush == nData1) { 3040 CAMHAL_LOGDB("OMX_CommandFlush received for port %d", (int)nData2); 3041 3042 } else if (OMX_CommandPortDisable == nData1) { 3043 CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d", (int)nData2); 3044 3045 } else if (OMX_CommandPortEnable == nData1) { 3046 CAMHAL_LOGDB("OMX_CommandPortEnable received for port %d", (int)nData2); 3047 3048 } else if (OMX_CommandMarkBuffer == nData1) { 3049 ///This is not used currently 3050 } 3051 3052 CAMHAL_LOGDA("-OMX_EventCmdComplete"); 3053 break; 3054 3055 case OMX_EventIndexSettingChanged: 3056 CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x", 3057 ( unsigned int ) nData1, ( unsigned int ) nData2); 3058 break; 3059 3060 case OMX_EventError: 3061 CAMHAL_LOGDB("OMX interface failed to execute OMX command %d", (int)nData1); 3062 CAMHAL_LOGDA("See OMX_INDEXTYPE for reference"); 3063 if ( NULL != mErrorNotifier && ( ( OMX_U32 ) OMX_ErrorHardware == nData1 ) && mComponentState != OMX_StateInvalid) 3064 { 3065 CAMHAL_LOGEA("***Got Fatal Error Notification***\n"); 3066 mComponentState = OMX_StateInvalid; 3067 /* 3068 Remove any unhandled events and 3069 unblock any waiting semaphores 3070 */ 3071 if ( !mEventSignalQ.isEmpty() ) 3072 { 3073 for (unsigned int i = 0 ; i < mEventSignalQ.size(); i++ ) 3074 { 3075 CAMHAL_LOGEB("***Removing %d EVENTS***** \n", mEventSignalQ.size()); 3076 //remove from queue and free msg 3077 Utils::Message *msg = mEventSignalQ.itemAt(i); 3078 if ( NULL != msg ) 3079 { 3080 Utils::Semaphore *sem = (Utils::Semaphore*) msg->arg3; 3081 if ( sem ) 3082 { 3083 sem->Signal(); 3084 } 3085 free(msg); 3086 } 3087 } 3088 mEventSignalQ.clear(); 3089 } 3090 ///Report Error to App 3091 mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL); 3092 } 3093 break; 3094 3095 case OMX_EventMark: 3096 break; 3097 3098 case OMX_EventPortSettingsChanged: 3099 break; 3100 3101 case OMX_EventBufferFlag: 3102 break; 3103 3104 case OMX_EventResourcesAcquired: 3105 break; 3106 3107 case OMX_EventComponentResumed: 3108 break; 3109 3110 case OMX_EventDynamicResourcesAvailable: 3111 break; 3112 3113 case OMX_EventPortFormatDetected: 3114 break; 3115 3116 default: 3117 break; 3118 } 3119 3120 ///Signal to the thread(s) waiting that the event has occured 3121 SignalEvent(hComponent, eEvent, nData1, nData2, pEventData); 3122 3123 LOG_FUNCTION_NAME_EXIT; 3124 return eError; 3125 3126 EXIT: 3127 3128 CAMHAL_LOGEB("Exiting function %s because of eError=%x", __FUNCTION__, eError); 3129 LOG_FUNCTION_NAME_EXIT; 3130 return eError; 3131 } 3132 3133 OMX_ERRORTYPE OMXCameraAdapter::SignalEvent(OMX_IN OMX_HANDLETYPE hComponent, 3134 OMX_IN OMX_EVENTTYPE eEvent, 3135 OMX_IN OMX_U32 nData1, 3136 OMX_IN OMX_U32 nData2, 3137 OMX_IN OMX_PTR pEventData) 3138 { 3139 android::AutoMutex lock(mEventLock); 3140 Utils::Message *msg; 3141 bool eventSignalled = false; 3142 3143 LOG_FUNCTION_NAME; 3144 3145 if ( !mEventSignalQ.isEmpty() ) 3146 { 3147 CAMHAL_LOGDA("Event queue not empty"); 3148 3149 for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ ) 3150 { 3151 msg = mEventSignalQ.itemAt(i); 3152 if ( NULL != msg ) 3153 { 3154 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) ) 3155 && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 ) 3156 && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 ) 3157 && msg->arg3) 3158 { 3159 Utils::Semaphore *sem = (Utils::Semaphore*) msg->arg3; 3160 CAMHAL_LOGDA("Event matched, signalling sem"); 3161 mEventSignalQ.removeAt(i); 3162 //Signal the semaphore provided 3163 sem->Signal(); 3164 free(msg); 3165 eventSignalled = true; 3166 break; 3167 } 3168 } 3169 } 3170 } 3171 else 3172 { 3173 CAMHAL_LOGDA("Event queue empty!!!"); 3174 } 3175 3176 // Special handling for any unregistered events 3177 if (!eventSignalled) { 3178 // Handling for focus callback 3179 if ((nData2 == OMX_IndexConfigCommonFocusStatus) && 3180 (eEvent == (OMX_EVENTTYPE) OMX_EventIndexSettingChanged)) { 3181 Utils::Message msg; 3182 msg.command = OMXCallbackHandler::CAMERA_FOCUS_STATUS; 3183 msg.arg1 = NULL; 3184 msg.arg2 = NULL; 3185 mOMXCallbackHandler->put(&msg); 3186 } 3187 } 3188 3189 LOG_FUNCTION_NAME_EXIT; 3190 3191 return OMX_ErrorNone; 3192 } 3193 3194 OMX_ERRORTYPE OMXCameraAdapter::RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent, 3195 OMX_IN OMX_EVENTTYPE eEvent, 3196 OMX_IN OMX_U32 nData1, 3197 OMX_IN OMX_U32 nData2, 3198 OMX_IN OMX_PTR pEventData) 3199 { 3200 android::AutoMutex lock(mEventLock); 3201 Utils::Message *msg; 3202 LOG_FUNCTION_NAME; 3203 3204 if ( !mEventSignalQ.isEmpty() ) 3205 { 3206 CAMHAL_LOGDA("Event queue not empty"); 3207 3208 for ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ ) 3209 { 3210 msg = mEventSignalQ.itemAt(i); 3211 if ( NULL != msg ) 3212 { 3213 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( eEvent ) ) 3214 && ( !msg->arg1 || ( OMX_U32 ) msg->arg1 == nData1 ) 3215 && ( !msg->arg2 || ( OMX_U32 ) msg->arg2 == nData2 ) 3216 && msg->arg3) 3217 { 3218 Utils::Semaphore *sem = (Utils::Semaphore*) msg->arg3; 3219 CAMHAL_LOGDA("Event matched, signalling sem"); 3220 mEventSignalQ.removeAt(i); 3221 free(msg); 3222 break; 3223 } 3224 } 3225 } 3226 } 3227 else 3228 { 3229 CAMHAL_LOGEA("Event queue empty!!!"); 3230 } 3231 LOG_FUNCTION_NAME_EXIT; 3232 3233 return OMX_ErrorNone; 3234 } 3235 3236 3237 status_t OMXCameraAdapter::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent, 3238 OMX_IN OMX_EVENTTYPE eEvent, 3239 OMX_IN OMX_U32 nData1, 3240 OMX_IN OMX_U32 nData2, 3241 OMX_IN Utils::Semaphore &semaphore) 3242 { 3243 status_t ret = NO_ERROR; 3244 ssize_t res; 3245 android::AutoMutex lock(mEventLock); 3246 3247 LOG_FUNCTION_NAME; 3248 Utils::Message * msg = ( struct Utils::Message * ) malloc(sizeof(struct Utils::Message)); 3249 if ( NULL != msg ) 3250 { 3251 msg->command = ( unsigned int ) eEvent; 3252 msg->arg1 = ( void * ) nData1; 3253 msg->arg2 = ( void * ) nData2; 3254 msg->arg3 = ( void * ) &semaphore; 3255 msg->arg4 = ( void * ) hComponent; 3256 res = mEventSignalQ.add(msg); 3257 if ( NO_MEMORY == res ) 3258 { 3259 CAMHAL_LOGEA("No ressources for inserting OMX events"); 3260 free(msg); 3261 ret = -ENOMEM; 3262 } 3263 } 3264 3265 LOG_FUNCTION_NAME_EXIT; 3266 3267 return ret; 3268 } 3269 3270 /*========================================================*/ 3271 /* @ fn SampleTest_EmptyBufferDone :: Application callback*/ 3272 /*========================================================*/ 3273 OMX_ERRORTYPE OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 3274 OMX_IN OMX_PTR pAppData, 3275 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 3276 { 3277 LOG_FUNCTION_NAME; 3278 3279 OMX_ERRORTYPE eError = OMX_ErrorNone; 3280 3281 OMXCameraAdapter *oca = (OMXCameraAdapter*)pAppData; 3282 eError = oca->OMXCameraAdapterEmptyBufferDone(hComponent, pBuffHeader); 3283 3284 LOG_FUNCTION_NAME_EXIT; 3285 return eError; 3286 } 3287 3288 3289 /*========================================================*/ 3290 /* @ fn SampleTest_EmptyBufferDone :: Application callback*/ 3291 /*========================================================*/ 3292 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 3293 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 3294 { 3295 3296 LOG_FUNCTION_NAME; 3297 status_t stat = NO_ERROR; 3298 status_t res1, res2; 3299 OMXCameraPortParameters *pPortParam; 3300 CameraFrame::FrameType typeOfFrame = CameraFrame::ALL_FRAMES; 3301 unsigned int refCount = 0; 3302 unsigned int mask = 0xFFFF; 3303 CameraFrame cameraFrame; 3304 OMX_TI_PLATFORMPRIVATE *platformPrivate; 3305 3306 res1 = res2 = NO_ERROR; 3307 3308 if (!pBuffHeader || !pBuffHeader->pBuffer) { 3309 CAMHAL_LOGE("NULL Buffer from OMX"); 3310 return OMX_ErrorNone; 3311 } 3312 3313 pPortParam = &(mCameraAdapterParameters.mCameraPortParams[pBuffHeader->nInputPortIndex]); 3314 platformPrivate = (OMX_TI_PLATFORMPRIVATE*) pBuffHeader->pPlatformPrivate; 3315 3316 if (pBuffHeader->nInputPortIndex == OMX_CAMERA_PORT_VIDEO_IN_VIDEO) { 3317 typeOfFrame = CameraFrame::REPROCESS_INPUT_FRAME; 3318 mask = (unsigned int)CameraFrame::REPROCESS_INPUT_FRAME; 3319 3320 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3321 } 3322 3323 LOG_FUNCTION_NAME_EXIT; 3324 3325 return OMX_ErrorNone; 3326 } 3327 3328 static void debugShowFPS() 3329 { 3330 static int mFrameCount = 0; 3331 static int mLastFrameCount = 0; 3332 static nsecs_t mLastFpsTime = 0; 3333 static float mFps = 0; 3334 mFrameCount++; 3335 if (!(mFrameCount & 0x1F)) { 3336 nsecs_t now = systemTime(); 3337 nsecs_t diff = now - mLastFpsTime; 3338 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 3339 mLastFpsTime = now; 3340 mLastFrameCount = mFrameCount; 3341 CAMHAL_LOGI("Camera %d Frames, %f FPS", mFrameCount, mFps); 3342 } 3343 // XXX: mFPS has the value we want 3344 } 3345 3346 /*========================================================*/ 3347 /* @ fn SampleTest_FillBufferDone :: Application callback*/ 3348 /*========================================================*/ 3349 OMX_ERRORTYPE OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 3350 OMX_IN OMX_PTR pAppData, 3351 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 3352 { 3353 Utils::Message msg; 3354 OMX_ERRORTYPE eError = OMX_ErrorNone; 3355 3356 if (UNLIKELY(mDebugFps)) { 3357 debugShowFPS(); 3358 } 3359 3360 OMXCameraAdapter *adapter = ( OMXCameraAdapter * ) pAppData; 3361 if ( NULL != adapter ) 3362 { 3363 msg.command = OMXCameraAdapter::OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE; 3364 msg.arg1 = ( void * ) hComponent; 3365 msg.arg2 = ( void * ) pBuffHeader; 3366 adapter->mOMXCallbackHandler->put(&msg); 3367 } 3368 3369 return eError; 3370 } 3371 3372 #ifdef CAMERAHAL_OMX_PROFILING 3373 3374 status_t OMXCameraAdapter::storeProfilingData(OMX_BUFFERHEADERTYPE* pBuffHeader) { 3375 OMX_TI_PLATFORMPRIVATE *platformPrivate = NULL; 3376 OMX_OTHER_EXTRADATATYPE *extraData = NULL; 3377 FILE *fd = NULL; 3378 3379 LOG_FUNCTION_NAME 3380 3381 if ( UNLIKELY( mDebugProfile ) ) { 3382 3383 platformPrivate = static_cast<OMX_TI_PLATFORMPRIVATE *> (pBuffHeader->pPlatformPrivate); 3384 extraData = getExtradata(platformPrivate->pMetaDataBuffer, 3385 static_cast<OMX_EXTRADATATYPE> (OMX_TI_ProfilerData)); 3386 3387 if ( NULL != extraData ) { 3388 if( extraData->eType == static_cast<OMX_EXTRADATATYPE> (OMX_TI_ProfilerData) ) { 3389 3390 fd = fopen(DEFAULT_PROFILE_PATH, "ab"); 3391 if ( NULL != fd ) { 3392 fwrite(extraData->data, 1, extraData->nDataSize, fd); 3393 fclose(fd); 3394 } else { 3395 return -errno; 3396 } 3397 3398 } else { 3399 return NOT_ENOUGH_DATA; 3400 } 3401 } else { 3402 return NOT_ENOUGH_DATA; 3403 } 3404 } 3405 3406 LOG_FUNCTION_NAME_EXIT 3407 3408 return NO_ERROR; 3409 } 3410 3411 #endif 3412 3413 /*========================================================*/ 3414 /* @ fn SampleTest_FillBufferDone :: Application callback*/ 3415 /*========================================================*/ 3416 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLETYPE hComponent, 3417 OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) 3418 { 3419 3420 status_t stat = NO_ERROR; 3421 status_t res1, res2; 3422 OMXCameraPortParameters *pPortParam; 3423 OMX_ERRORTYPE eError = OMX_ErrorNone; 3424 CameraFrame::FrameType typeOfFrame = CameraFrame::ALL_FRAMES; 3425 unsigned int refCount = 0; 3426 BaseCameraAdapter::AdapterState state, nextState; 3427 BaseCameraAdapter::getState(state); 3428 BaseCameraAdapter::getNextState(nextState); 3429 android::sp<CameraMetadataResult> metadataResult = NULL; 3430 unsigned int mask = 0xFFFF; 3431 CameraFrame cameraFrame; 3432 OMX_OTHER_EXTRADATATYPE *extraData; 3433 OMX_TI_ANCILLARYDATATYPE *ancillaryData = NULL; 3434 bool snapshotFrame = false; 3435 3436 if ( NULL == pBuffHeader ) { 3437 return OMX_ErrorBadParameter; 3438 } 3439 3440 #ifdef CAMERAHAL_OMX_PROFILING 3441 3442 storeProfilingData(pBuffHeader); 3443 3444 #endif 3445 3446 res1 = res2 = NO_ERROR; 3447 3448 if ( !pBuffHeader || !pBuffHeader->pBuffer ) { 3449 CAMHAL_LOGEA("NULL Buffer from OMX"); 3450 return OMX_ErrorNone; 3451 } 3452 3453 pPortParam = &(mCameraAdapterParameters.mCameraPortParams[pBuffHeader->nOutputPortIndex]); 3454 3455 // Find buffer and mark it as filled 3456 for (int i = 0; i < pPortParam->mNumBufs; i++) { 3457 if (pPortParam->mBufferHeader[i] == pBuffHeader) { 3458 pPortParam->mStatus[i] = OMXCameraPortParameters::DONE; 3459 } 3460 } 3461 3462 if (pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW) 3463 { 3464 3465 if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE ) 3466 { 3467 return OMX_ErrorNone; 3468 } 3469 3470 if ( mWaitingForSnapshot ) { 3471 extraData = getExtradata(pBuffHeader->pPlatformPrivate, 3472 (OMX_EXTRADATATYPE) OMX_AncillaryData); 3473 3474 if ( NULL != extraData ) { 3475 ancillaryData = (OMX_TI_ANCILLARYDATATYPE*) extraData->data; 3476 if ((OMX_2D_Snap == ancillaryData->eCameraView) 3477 || (OMX_3D_Left_Snap == ancillaryData->eCameraView) 3478 || (OMX_3D_Right_Snap == ancillaryData->eCameraView)) { 3479 snapshotFrame = OMX_TRUE; 3480 } else { 3481 snapshotFrame = OMX_FALSE; 3482 } 3483 mPending3Asettings |= SetFocus; 3484 } 3485 } 3486 3487 ///Prepare the frames to be sent - initialize CameraFrame object and reference count 3488 // TODO(XXX): ancillary data for snapshot frame is not being sent for video snapshot 3489 // if we are waiting for a snapshot and in video mode...go ahead and send 3490 // this frame as a snapshot 3491 if( mWaitingForSnapshot && (mCapturedFrames > 0) && 3492 (snapshotFrame || (mCapMode == VIDEO_MODE) || (mCapMode == VIDEO_MODE_HQ ) )) 3493 { 3494 typeOfFrame = CameraFrame::SNAPSHOT_FRAME; 3495 mask = (unsigned int)CameraFrame::SNAPSHOT_FRAME; 3496 3497 // video snapshot gets ancillary data and wb info from last snapshot frame 3498 mCaptureAncillaryData = ancillaryData; 3499 mWhiteBalanceData = NULL; 3500 extraData = getExtradata(pBuffHeader->pPlatformPrivate, 3501 (OMX_EXTRADATATYPE) OMX_WhiteBalance); 3502 if ( NULL != extraData ) 3503 { 3504 mWhiteBalanceData = (OMX_TI_WHITEBALANCERESULTTYPE*) extraData->data; 3505 } 3506 } 3507 else 3508 { 3509 typeOfFrame = CameraFrame::PREVIEW_FRAME_SYNC; 3510 mask = (unsigned int)CameraFrame::PREVIEW_FRAME_SYNC; 3511 } 3512 3513 if (mRecording) 3514 { 3515 mask |= (unsigned int)CameraFrame::VIDEO_FRAME_SYNC; 3516 mFramesWithEncoder++; 3517 } 3518 3519 //CAMHAL_LOGV("FBD pBuffer = 0x%x", pBuffHeader->pBuffer); 3520 3521 if( mWaitingForSnapshot ) 3522 { 3523 if ( !mBracketingEnabled && 3524 ((HIGH_SPEED == mCapMode) || 3525 (VIDEO_MODE == mCapMode) || 3526 (VIDEO_MODE_HQ == mCapMode)) ) 3527 { 3528 notifyShutterSubscribers(); 3529 } 3530 } 3531 3532 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3533 mFramesWithDisplay++; 3534 3535 mFramesWithDucati--; 3536 3537 #ifdef CAMERAHAL_DEBUG 3538 if(mBuffersWithDucati.indexOfKey((uint32_t)pBuffHeader->pBuffer)<0) 3539 { 3540 CAMHAL_LOGE("Buffer was never with Ducati!! %p", pBuffHeader->pBuffer); 3541 for(unsigned int i=0;i<mBuffersWithDucati.size();i++) CAMHAL_LOGE("0x%x", mBuffersWithDucati.keyAt(i)); 3542 } 3543 mBuffersWithDucati.removeItem((int)pBuffHeader->pBuffer); 3544 #endif 3545 3546 if(mDebugFcs) 3547 CAMHAL_LOGEB("C[%d] D[%d] E[%d]", mFramesWithDucati, mFramesWithDisplay, mFramesWithEncoder); 3548 3549 recalculateFPS(); 3550 3551 createPreviewMetadata(pBuffHeader, metadataResult, pPortParam->mWidth, pPortParam->mHeight); 3552 if ( NULL != metadataResult.get() ) { 3553 notifyMetadataSubscribers(metadataResult); 3554 metadataResult.clear(); 3555 } 3556 3557 { 3558 android::AutoMutex lock(mFaceDetectionLock); 3559 if ( mFDSwitchAlgoPriority ) { 3560 3561 //Disable region priority and enable face priority for AF 3562 setAlgoPriority(REGION_PRIORITY, FOCUS_ALGO, false); 3563 setAlgoPriority(FACE_PRIORITY, FOCUS_ALGO , true); 3564 3565 //Disable Region priority and enable Face priority 3566 setAlgoPriority(REGION_PRIORITY, EXPOSURE_ALGO, false); 3567 setAlgoPriority(FACE_PRIORITY, EXPOSURE_ALGO, true); 3568 mFDSwitchAlgoPriority = false; 3569 } 3570 } 3571 3572 sniffDccFileDataSave(pBuffHeader); 3573 3574 stat |= advanceZoom(); 3575 3576 // On the fly update to 3A settings not working 3577 // Do not update 3A here if we are in the middle of a capture 3578 // or in the middle of transitioning to it 3579 if( mPending3Asettings && 3580 ( (nextState & CAPTURE_ACTIVE) == 0 ) && 3581 ( (state & CAPTURE_ACTIVE) == 0 ) ) { 3582 apply3Asettings(mParameters3A); 3583 } 3584 3585 } 3586 else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT ) 3587 { 3588 typeOfFrame = CameraFrame::FRAME_DATA_SYNC; 3589 mask = (unsigned int)CameraFrame::FRAME_DATA_SYNC; 3590 3591 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3592 } 3593 else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_IMAGE_OUT_IMAGE ) 3594 { 3595 OMX_COLOR_FORMATTYPE pixFormat; 3596 const char *valstr = NULL; 3597 3598 pixFormat = pPortParam->mColorFormat; 3599 3600 if ( OMX_COLOR_FormatUnused == pixFormat ) 3601 { 3602 typeOfFrame = CameraFrame::IMAGE_FRAME; 3603 mask = (unsigned int) CameraFrame::IMAGE_FRAME; 3604 } else if ( pixFormat == OMX_COLOR_FormatCbYCrY && 3605 ((mPictureFormatFromClient && 3606 !strcmp(mPictureFormatFromClient, 3607 android::CameraParameters::PIXEL_FORMAT_JPEG)) || 3608 !mPictureFormatFromClient) ) { 3609 // signals to callbacks that this needs to be coverted to jpeg 3610 // before returning to framework 3611 typeOfFrame = CameraFrame::IMAGE_FRAME; 3612 mask = (unsigned int) CameraFrame::IMAGE_FRAME; 3613 cameraFrame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG; 3614 cameraFrame.mQuirks |= CameraFrame::FORMAT_YUV422I_UYVY; 3615 3616 // populate exif data and pass to subscribers via quirk 3617 // subscriber is in charge of freeing exif data 3618 ExifElementsTable* exif = new ExifElementsTable(); 3619 setupEXIF_libjpeg(exif, mCaptureAncillaryData, mWhiteBalanceData); 3620 cameraFrame.mQuirks |= CameraFrame::HAS_EXIF_DATA; 3621 cameraFrame.mCookie2 = (void*) exif; 3622 } else { 3623 typeOfFrame = CameraFrame::RAW_FRAME; 3624 mask = (unsigned int) CameraFrame::RAW_FRAME; 3625 } 3626 3627 pPortParam->mImageType = typeOfFrame; 3628 3629 if((mCapturedFrames>0) && !mCaptureSignalled) 3630 { 3631 mCaptureSignalled = true; 3632 mCaptureSem.Signal(); 3633 } 3634 3635 if( ( CAPTURE_ACTIVE & state ) != CAPTURE_ACTIVE ) 3636 { 3637 goto EXIT; 3638 } 3639 3640 { 3641 android::AutoMutex lock(mBracketingLock); 3642 if ( mBracketingEnabled ) 3643 { 3644 doBracketing(pBuffHeader, typeOfFrame); 3645 return eError; 3646 } 3647 } 3648 3649 if (mZoomBracketingEnabled) { 3650 doZoom(mZoomBracketingValues[mCurrentZoomBracketing]); 3651 CAMHAL_LOGDB("Current Zoom Bracketing: %d", mZoomBracketingValues[mCurrentZoomBracketing]); 3652 mCurrentZoomBracketing++; 3653 if (mCurrentZoomBracketing == ARRAY_SIZE(mZoomBracketingValues)) { 3654 mZoomBracketingEnabled = false; 3655 } 3656 } 3657 3658 if ( 1 > mCapturedFrames ) 3659 { 3660 goto EXIT; 3661 } 3662 3663 #ifdef OMAP_ENHANCEMENT_CPCAM 3664 if ( NULL != mSharedAllocator ) { 3665 cameraFrame.mMetaData = new CameraMetadataResult(getMetaData(pBuffHeader->pPlatformPrivate, mSharedAllocator)); 3666 } 3667 #endif 3668 3669 CAMHAL_LOGDB("Captured Frames: %d", mCapturedFrames); 3670 3671 mCapturedFrames--; 3672 3673 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 3674 if (mYuvCapture) { 3675 struct timeval timeStampUsec; 3676 gettimeofday(&timeStampUsec, NULL); 3677 3678 time_t saveTime; 3679 time(&saveTime); 3680 const struct tm * const timeStamp = gmtime(&saveTime); 3681 3682 char filename[256]; 3683 snprintf(filename,256, "%s/yuv_%d_%d_%d_%lu.yuv", 3684 kYuvImagesOutputDirPath, 3685 timeStamp->tm_hour, 3686 timeStamp->tm_min, 3687 timeStamp->tm_sec, 3688 timeStampUsec.tv_usec); 3689 3690 const status_t saveBufferStatus = saveBufferToFile(((CameraBuffer*)pBuffHeader->pAppPrivate)->mapped, 3691 pBuffHeader->nFilledLen, filename); 3692 3693 if (saveBufferStatus != OK) { 3694 CAMHAL_LOGE("ERROR: %d, while saving yuv!", saveBufferStatus); 3695 } else { 3696 CAMHAL_LOGD("yuv_%d_%d_%d_%lu.yuv successfully saved in %s", 3697 timeStamp->tm_hour, 3698 timeStamp->tm_min, 3699 timeStamp->tm_sec, 3700 timeStampUsec.tv_usec, 3701 kYuvImagesOutputDirPath); 3702 } 3703 } 3704 #endif 3705 3706 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3707 #ifdef OMAP_ENHANCEMENT_CPCAM 3708 if ( NULL != cameraFrame.mMetaData.get() ) { 3709 cameraFrame.mMetaData.clear(); 3710 } 3711 #endif 3712 3713 } 3714 else if (pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_VIDEO_OUT_VIDEO) { 3715 typeOfFrame = CameraFrame::RAW_FRAME; 3716 pPortParam->mImageType = typeOfFrame; 3717 { 3718 android::AutoMutex lock(mLock); 3719 if( ( CAPTURE_ACTIVE & state ) != CAPTURE_ACTIVE ) { 3720 goto EXIT; 3721 } 3722 } 3723 3724 CAMHAL_LOGD("RAW buffer done on video port, length = %d", pBuffHeader->nFilledLen); 3725 3726 mask = (unsigned int) CameraFrame::RAW_FRAME; 3727 3728 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 3729 if ( mRawCapture ) { 3730 struct timeval timeStampUsec; 3731 gettimeofday(&timeStampUsec, NULL); 3732 3733 time_t saveTime; 3734 time(&saveTime); 3735 const struct tm * const timeStamp = gmtime(&saveTime); 3736 3737 char filename[256]; 3738 snprintf(filename,256, "%s/raw_%d_%d_%d_%lu.raw", 3739 kRawImagesOutputDirPath, 3740 timeStamp->tm_hour, 3741 timeStamp->tm_min, 3742 timeStamp->tm_sec, 3743 timeStampUsec.tv_usec); 3744 3745 const status_t saveBufferStatus = saveBufferToFile( ((CameraBuffer*)pBuffHeader->pAppPrivate)->mapped, 3746 pBuffHeader->nFilledLen, filename); 3747 3748 if (saveBufferStatus != OK) { 3749 CAMHAL_LOGE("ERROR: %d , while saving raw!", saveBufferStatus); 3750 } else { 3751 CAMHAL_LOGD("raw_%d_%d_%d_%lu.raw successfully saved in %s", 3752 timeStamp->tm_hour, 3753 timeStamp->tm_min, 3754 timeStamp->tm_sec, 3755 timeStampUsec.tv_usec, 3756 kRawImagesOutputDirPath); 3757 stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); 3758 } 3759 } 3760 #endif 3761 } else { 3762 CAMHAL_LOGEA("Frame received for non-(preview/capture/measure) port. This is yet to be supported"); 3763 goto EXIT; 3764 } 3765 3766 if ( NO_ERROR != stat ) 3767 { 3768 CameraBuffer *camera_buffer; 3769 3770 camera_buffer = (CameraBuffer *)pBuffHeader->pAppPrivate; 3771 3772 CAMHAL_LOGDB("sendFrameToSubscribers error: %d", stat); 3773 returnFrame(camera_buffer, typeOfFrame); 3774 } 3775 3776 return eError; 3777 3778 EXIT: 3779 3780 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, stat, eError); 3781 3782 if ( NO_ERROR != stat ) 3783 { 3784 if ( NULL != mErrorNotifier ) 3785 { 3786 mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN); 3787 } 3788 } 3789 3790 return eError; 3791 } 3792 3793 status_t OMXCameraAdapter::recalculateFPS() 3794 { 3795 float currentFPS; 3796 3797 { 3798 android::AutoMutex lock(mFrameCountMutex); 3799 mFrameCount++; 3800 if (mFrameCount == 1) { 3801 mFirstFrameCondition.broadcast(); 3802 } 3803 } 3804 3805 if ( ( mFrameCount % FPS_PERIOD ) == 0 ) 3806 { 3807 nsecs_t now = systemTime(); 3808 nsecs_t diff = now - mLastFPSTime; 3809 currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 3810 mLastFPSTime = now; 3811 mLastFrameCount = mFrameCount; 3812 3813 if ( 1 == mIter ) 3814 { 3815 mFPS = currentFPS; 3816 } 3817 else 3818 { 3819 //cumulative moving average 3820 mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter; 3821 } 3822 3823 mLastFPS = mFPS; 3824 mIter++; 3825 } 3826 3827 return NO_ERROR; 3828 } 3829 3830 status_t OMXCameraAdapter::sendCallBacks(CameraFrame frame, OMX_IN OMX_BUFFERHEADERTYPE *pBuffHeader, unsigned int mask, OMXCameraPortParameters *port) 3831 { 3832 status_t ret = NO_ERROR; 3833 3834 LOG_FUNCTION_NAME; 3835 3836 if ( NULL == port) 3837 { 3838 CAMHAL_LOGEA("Invalid portParam"); 3839 return -EINVAL; 3840 } 3841 3842 if ( NULL == pBuffHeader ) 3843 { 3844 CAMHAL_LOGEA("Invalid Buffer header"); 3845 return -EINVAL; 3846 } 3847 3848 android::AutoMutex lock(mSubscriberLock); 3849 3850 //frame.mFrameType = typeOfFrame; 3851 frame.mFrameMask = mask; 3852 frame.mBuffer = (CameraBuffer *)pBuffHeader->pAppPrivate; 3853 frame.mLength = pBuffHeader->nFilledLen; 3854 frame.mAlignment = port->mStride; 3855 frame.mOffset = pBuffHeader->nOffset; 3856 frame.mWidth = port->mWidth; 3857 frame.mHeight = port->mHeight; 3858 frame.mYuv[0] = NULL; 3859 frame.mYuv[1] = NULL; 3860 3861 if ( onlyOnce && mRecording ) 3862 { 3863 mTimeSourceDelta = (pBuffHeader->nTimeStamp * 1000) - systemTime(SYSTEM_TIME_MONOTONIC); 3864 onlyOnce = false; 3865 } 3866 3867 frame.mTimestamp = (pBuffHeader->nTimeStamp * 1000) - mTimeSourceDelta; 3868 3869 ret = setInitFrameRefCount(frame.mBuffer, mask); 3870 3871 if (ret != NO_ERROR) { 3872 CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret); 3873 } else { 3874 ret = sendFrameToSubscribers(&frame); 3875 } 3876 3877 CAMHAL_LOGVB("B 0x%x T %llu", frame.mBuffer, pBuffHeader->nTimeStamp); 3878 3879 LOG_FUNCTION_NAME_EXIT; 3880 3881 return ret; 3882 } 3883 3884 bool OMXCameraAdapter::CommandHandler::Handler() 3885 { 3886 Utils::Message msg; 3887 volatile int forever = 1; 3888 status_t stat; 3889 ErrorNotifier *errorNotify = NULL; 3890 3891 LOG_FUNCTION_NAME; 3892 3893 while ( forever ) 3894 { 3895 stat = NO_ERROR; 3896 CAMHAL_LOGDA("Handler: waiting for messsage..."); 3897 Utils::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1); 3898 { 3899 android::AutoMutex lock(mLock); 3900 mCommandMsgQ.get(&msg); 3901 } 3902 CAMHAL_LOGDB("msg.command = %d", msg.command); 3903 switch ( msg.command ) { 3904 case CommandHandler::CAMERA_START_IMAGE_CAPTURE: 3905 { 3906 OMXCameraAdapter::CachedCaptureParameters* cap_params = 3907 static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2); 3908 stat = mCameraAdapter->startImageCapture(false, cap_params); 3909 delete cap_params; 3910 break; 3911 } 3912 case CommandHandler::CAMERA_PERFORM_AUTOFOCUS: 3913 { 3914 stat = mCameraAdapter->doAutoFocus(); 3915 break; 3916 } 3917 case CommandHandler::COMMAND_EXIT: 3918 { 3919 CAMHAL_LOGDA("Exiting command handler"); 3920 forever = 0; 3921 break; 3922 } 3923 case CommandHandler::CAMERA_SWITCH_TO_EXECUTING: 3924 { 3925 stat = mCameraAdapter->doSwitchToExecuting(); 3926 break; 3927 } 3928 case CommandHandler::CAMERA_START_REPROCESS: 3929 { 3930 OMXCameraAdapter::CachedCaptureParameters* cap_params = 3931 static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2); 3932 stat = mCameraAdapter->startReprocess(); 3933 stat = mCameraAdapter->startImageCapture(false, cap_params); 3934 delete cap_params; 3935 break; 3936 } 3937 } 3938 3939 } 3940 3941 LOG_FUNCTION_NAME_EXIT; 3942 3943 return false; 3944 } 3945 3946 bool OMXCameraAdapter::OMXCallbackHandler::Handler() 3947 { 3948 Utils::Message msg; 3949 volatile int forever = 1; 3950 status_t ret = NO_ERROR; 3951 3952 LOG_FUNCTION_NAME; 3953 3954 while(forever){ 3955 Utils::MessageQueue::waitForMsg(&mCommandMsgQ, NULL, NULL, -1); 3956 { 3957 android::AutoMutex lock(mLock); 3958 mCommandMsgQ.get(&msg); 3959 mIsProcessed = false; 3960 } 3961 3962 switch ( msg.command ) { 3963 case OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE: 3964 { 3965 ret = mCameraAdapter->OMXCameraAdapterFillBufferDone(( OMX_HANDLETYPE ) msg.arg1, 3966 ( OMX_BUFFERHEADERTYPE *) msg.arg2); 3967 break; 3968 } 3969 case OMXCallbackHandler::CAMERA_FOCUS_STATUS: 3970 { 3971 mCameraAdapter->handleFocusCallback(); 3972 break; 3973 } 3974 case CommandHandler::COMMAND_EXIT: 3975 { 3976 CAMHAL_LOGDA("Exiting OMX callback handler"); 3977 forever = 0; 3978 break; 3979 } 3980 } 3981 3982 { 3983 android::AutoMutex locker(mLock); 3984 CAMHAL_UNUSED(locker); 3985 3986 mIsProcessed = mCommandMsgQ.isEmpty(); 3987 if ( mIsProcessed ) 3988 mCondition.signal(); 3989 } 3990 } 3991 3992 // force the condition to wake 3993 { 3994 android::AutoMutex locker(mLock); 3995 CAMHAL_UNUSED(locker); 3996 3997 mIsProcessed = true; 3998 mCondition.signal(); 3999 } 4000 4001 LOG_FUNCTION_NAME_EXIT; 4002 return false; 4003 } 4004 4005 void OMXCameraAdapter::OMXCallbackHandler::flush() 4006 { 4007 LOG_FUNCTION_NAME; 4008 4009 android::AutoMutex locker(mLock); 4010 CAMHAL_UNUSED(locker); 4011 4012 if ( mIsProcessed ) 4013 return; 4014 4015 mCondition.wait(mLock); 4016 } 4017 4018 status_t OMXCameraAdapter::setExtraData(bool enable, OMX_U32 nPortIndex, OMX_EXT_EXTRADATATYPE eType) { 4019 status_t ret = NO_ERROR; 4020 OMX_ERRORTYPE eError = OMX_ErrorNone; 4021 OMX_CONFIG_EXTRADATATYPE extraDataControl; 4022 4023 LOG_FUNCTION_NAME; 4024 4025 if ( ( OMX_StateInvalid == mComponentState ) || 4026 ( NULL == mCameraAdapterParameters.mHandleComp ) ) { 4027 CAMHAL_LOGEA("OMX component is in invalid state"); 4028 return -EINVAL; 4029 } 4030 4031 OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE); 4032 4033 extraDataControl.nPortIndex = nPortIndex; 4034 extraDataControl.eExtraDataType = eType; 4035 #ifdef CAMERAHAL_TUNA 4036 extraDataControl.eCameraView = OMX_2D; 4037 #endif 4038 4039 if (enable) { 4040 extraDataControl.bEnable = OMX_TRUE; 4041 } else { 4042 extraDataControl.bEnable = OMX_FALSE; 4043 } 4044 4045 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 4046 (OMX_INDEXTYPE) OMX_IndexConfigOtherExtraDataControl, 4047 &extraDataControl); 4048 4049 LOG_FUNCTION_NAME_EXIT; 4050 4051 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 4052 } 4053 4054 OMX_OTHER_EXTRADATATYPE *OMXCameraAdapter::getExtradata(const OMX_PTR ptrPrivate, OMX_EXTRADATATYPE type) const 4055 { 4056 if ( NULL != ptrPrivate ) { 4057 const OMX_TI_PLATFORMPRIVATE *platformPrivate = (const OMX_TI_PLATFORMPRIVATE *) ptrPrivate; 4058 4059 CAMHAL_LOGVB("Size = %d, sizeof = %d, pAuxBuf = 0x%x, pAuxBufSize= %d, pMetaDataBufer = 0x%x, nMetaDataSize = %d", 4060 platformPrivate->nSize, 4061 sizeof(OMX_TI_PLATFORMPRIVATE), 4062 platformPrivate->pAuxBuf1, 4063 platformPrivate->pAuxBufSize1, 4064 platformPrivate->pMetaDataBuffer, 4065 platformPrivate->nMetaDataSize); 4066 if ( sizeof(OMX_TI_PLATFORMPRIVATE) == platformPrivate->nSize ) { 4067 if ( 0 < platformPrivate->nMetaDataSize ) { 4068 OMX_U32 remainingSize = platformPrivate->nMetaDataSize; 4069 OMX_OTHER_EXTRADATATYPE *extraData = (OMX_OTHER_EXTRADATATYPE *) platformPrivate->pMetaDataBuffer; 4070 if ( NULL != extraData ) { 4071 while ( extraData->eType && extraData->nDataSize && extraData->data && 4072 (remainingSize >= extraData->nSize)) { 4073 if ( type == extraData->eType ) { 4074 return extraData; 4075 } 4076 remainingSize -= extraData->nSize; 4077 extraData = (OMX_OTHER_EXTRADATATYPE*) ((char*)extraData + extraData->nSize); 4078 } 4079 } else { 4080 CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE pMetaDataBuffer is NULL"); 4081 } 4082 } else { 4083 CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE nMetaDataSize is size is %d", 4084 ( unsigned int ) platformPrivate->nMetaDataSize); 4085 } 4086 } else { 4087 CAMHAL_LOGEB("OMX_TI_PLATFORMPRIVATE size mismatch: expected = %d, received = %d", 4088 ( unsigned int ) sizeof(OMX_TI_PLATFORMPRIVATE), 4089 ( unsigned int ) platformPrivate->nSize); 4090 } 4091 } else { 4092 CAMHAL_LOGEA("Invalid OMX_TI_PLATFORMPRIVATE"); 4093 } 4094 4095 // Required extradata type wasn't found 4096 return NULL; 4097 } 4098 4099 OMXCameraAdapter::CachedCaptureParameters* OMXCameraAdapter::cacheCaptureParameters() { 4100 CachedCaptureParameters* params = new CachedCaptureParameters(); 4101 4102 params->mPendingCaptureSettings = mPendingCaptureSettings; 4103 params->mPictureRotation = mPictureRotation; 4104 memcpy(params->mExposureBracketingValues, 4105 mExposureBracketingValues, 4106 sizeof(mExposureBracketingValues)); 4107 memcpy(params->mExposureGainBracketingValues, 4108 mExposureGainBracketingValues, 4109 sizeof(mExposureGainBracketingValues)); 4110 memcpy(params->mExposureGainBracketingModes, 4111 mExposureGainBracketingModes, 4112 sizeof(mExposureGainBracketingModes)); 4113 params->mExposureBracketingValidEntries = mExposureBracketingValidEntries; 4114 params->mExposureBracketMode = mExposureBracketMode; 4115 params->mBurstFrames = mBurstFrames; 4116 params->mFlushShotConfigQueue = mFlushShotConfigQueue; 4117 4118 return params; 4119 } 4120 4121 OMXCameraAdapter::OMXCameraAdapter(size_t sensor_index) 4122 { 4123 LOG_FUNCTION_NAME; 4124 4125 mOmxInitialized = false; 4126 mComponentState = OMX_StateInvalid; 4127 mSensorIndex = sensor_index; 4128 mPictureRotation = 0; 4129 // Initial values 4130 mTimeSourceDelta = 0; 4131 onlyOnce = true; 4132 mDccData.pData = NULL; 4133 4134 mInitSem.Create(0); 4135 mFlushSem.Create(0); 4136 mUsePreviewDataSem.Create(0); 4137 mUsePreviewSem.Create(0); 4138 mUseCaptureSem.Create(0); 4139 mUseReprocessSem.Create(0); 4140 mStartPreviewSem.Create(0); 4141 mStopPreviewSem.Create(0); 4142 mStartCaptureSem.Create(0); 4143 mStopCaptureSem.Create(0); 4144 mStopReprocSem.Create(0); 4145 mSwitchToLoadedSem.Create(0); 4146 mCaptureSem.Create(0); 4147 4148 mSwitchToExecSem.Create(0); 4149 4150 mCameraAdapterParameters.mHandleComp = 0; 4151 4152 mUserSetExpLock = OMX_FALSE; 4153 mUserSetWbLock = OMX_FALSE; 4154 4155 mFramesWithDucati = 0; 4156 mFramesWithDisplay = 0; 4157 mFramesWithEncoder = 0; 4158 4159 #ifdef CAMERAHAL_OMX_PROFILING 4160 4161 mDebugProfile = 0; 4162 4163 #endif 4164 4165 mPreviewPortInitialized = false; 4166 4167 LOG_FUNCTION_NAME_EXIT; 4168 } 4169 4170 OMXCameraAdapter::~OMXCameraAdapter() 4171 { 4172 LOG_FUNCTION_NAME; 4173 4174 android::AutoMutex lock(gAdapterLock); 4175 4176 if ( mOmxInitialized ) { 4177 // return to OMX Loaded state 4178 switchToLoaded(); 4179 4180 saveDccFileDataSave(); 4181 4182 closeDccFileDataSave(); 4183 // deinit the OMX 4184 if ( mComponentState == OMX_StateLoaded || mComponentState == OMX_StateInvalid ) { 4185 // free the handle for the Camera component 4186 if ( mCameraAdapterParameters.mHandleComp ) { 4187 OMX_FreeHandle(mCameraAdapterParameters.mHandleComp); 4188 mCameraAdapterParameters.mHandleComp = NULL; 4189 } 4190 } 4191 4192 OMX_Deinit(); 4193 mOmxInitialized = false; 4194 } 4195 4196 //Remove any unhandled events 4197 if ( !mEventSignalQ.isEmpty() ) 4198 { 4199 for (unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ ) 4200 { 4201 Utils::Message *msg = mEventSignalQ.itemAt(i); 4202 //remove from queue and free msg 4203 if ( NULL != msg ) 4204 { 4205 Utils::Semaphore *sem = (Utils::Semaphore*) msg->arg3; 4206 sem->Signal(); 4207 free(msg); 4208 4209 } 4210 } 4211 mEventSignalQ.clear(); 4212 } 4213 4214 //Exit and free ref to command handling thread 4215 if ( NULL != mCommandHandler.get() ) 4216 { 4217 Utils::Message msg; 4218 msg.command = CommandHandler::COMMAND_EXIT; 4219 msg.arg1 = mErrorNotifier; 4220 mCommandHandler->clearCommandQ(); 4221 mCommandHandler->put(&msg); 4222 mCommandHandler->requestExitAndWait(); 4223 mCommandHandler.clear(); 4224 } 4225 4226 //Exit and free ref to callback handling thread 4227 if ( NULL != mOMXCallbackHandler.get() ) 4228 { 4229 Utils::Message msg; 4230 msg.command = OMXCallbackHandler::COMMAND_EXIT; 4231 //Clear all messages pending first 4232 mOMXCallbackHandler->clearCommandQ(); 4233 mOMXCallbackHandler->put(&msg); 4234 mOMXCallbackHandler->requestExitAndWait(); 4235 mOMXCallbackHandler.clear(); 4236 } 4237 4238 LOG_FUNCTION_NAME_EXIT; 4239 } 4240 4241 extern "C" CameraAdapter* OMXCameraAdapter_Factory(size_t sensor_index) 4242 { 4243 CameraAdapter *adapter = NULL; 4244 android::AutoMutex lock(gAdapterLock); 4245 4246 LOG_FUNCTION_NAME; 4247 4248 adapter = new OMXCameraAdapter(sensor_index); 4249 if ( adapter ) { 4250 CAMHAL_LOGDB("New OMX Camera adapter instance created for sensor %d",sensor_index); 4251 } else { 4252 CAMHAL_LOGEA("OMX Camera adapter create failed for sensor index = %d!",sensor_index); 4253 } 4254 4255 LOG_FUNCTION_NAME_EXIT; 4256 4257 return adapter; 4258 } 4259 4260 OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE *handle, OMX_PTR pAppData, 4261 const OMX_CALLBACKTYPE & callbacks) 4262 { 4263 OMX_ERRORTYPE eError = OMX_ErrorUndefined; 4264 4265 for ( int i = 0; i < 5; ++i ) { 4266 if ( i > 0 ) { 4267 // sleep for 100 ms before next attempt 4268 usleep(100000); 4269 } 4270 4271 // setup key parameters to send to Ducati during init 4272 OMX_CALLBACKTYPE oCallbacks = callbacks; 4273 4274 // get handle 4275 eError = OMX_GetHandle(handle, (OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA", pAppData, &oCallbacks); 4276 if ( eError == OMX_ErrorNone ) { 4277 return OMX_ErrorNone; 4278 } 4279 4280 CAMHAL_LOGEB("OMX_GetHandle() failed, error: 0x%x", eError); 4281 } 4282 4283 *handle = 0; 4284 return eError; 4285 } 4286 4287 4288 class CapabilitiesHandler 4289 { 4290 public: 4291 CapabilitiesHandler() 4292 { 4293 mComponent = 0; 4294 } 4295 4296 const OMX_HANDLETYPE & component() const 4297 { 4298 return mComponent; 4299 } 4300 4301 OMX_HANDLETYPE & componentRef() 4302 { 4303 return mComponent; 4304 } 4305 4306 status_t fetchCapabiltiesForMode(OMX_CAMOPERATINGMODETYPE mode, 4307 int sensorId, 4308 CameraProperties::Properties * properties) 4309 { 4310 OMX_CONFIG_CAMOPERATINGMODETYPE camMode; 4311 4312 OMX_INIT_STRUCT_PTR (&camMode, OMX_CONFIG_CAMOPERATINGMODETYPE); 4313 camMode.eCamOperatingMode = mode; 4314 4315 OMX_ERRORTYPE eError = OMX_SetParameter(component(), 4316 ( OMX_INDEXTYPE ) OMX_IndexCameraOperatingMode, 4317 &camMode); 4318 4319 if ( OMX_ErrorNone != eError ) { 4320 CAMHAL_LOGE("Error while configuring camera mode in CameraAdapter_Capabilities 0x%x", eError); 4321 return BAD_VALUE; 4322 } 4323 4324 // get and fill capabilities 4325 OMXCameraAdapter::getCaps(sensorId, properties, component()); 4326 4327 return NO_ERROR; 4328 } 4329 4330 status_t fetchCapabilitiesForSensor(int sensorId, 4331 CameraProperties::Properties * properties) 4332 { 4333 // sensor select 4334 OMX_CONFIG_SENSORSELECTTYPE sensorSelect; 4335 OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE); 4336 sensorSelect.eSensor = (OMX_SENSORSELECT)sensorId; 4337 4338 CAMHAL_LOGD("Selecting sensor %d...", sensorId); 4339 const OMX_ERRORTYPE sensorSelectError = OMX_SetConfig(component(), 4340 (OMX_INDEXTYPE)OMX_TI_IndexConfigSensorSelect, &sensorSelect); 4341 CAMHAL_LOGD("Selecting sensor %d... DONE", sensorId); 4342 4343 if ( sensorSelectError != OMX_ErrorNone ) { 4344 CAMHAL_LOGD("Max supported sensor number reached: %d", sensorId); 4345 return BAD_VALUE; 4346 } 4347 4348 status_t err = NO_ERROR; 4349 if ( sensorId == 2 ) { 4350 CAMHAL_LOGD("Camera mode: STEREO"); 4351 properties->setMode(MODE_STEREO); 4352 err = fetchCapabiltiesForMode(OMX_CaptureStereoImageCapture, 4353 sensorId, 4354 properties); 4355 } else { 4356 CAMHAL_LOGD("Camera MONO"); 4357 4358 CAMHAL_LOGD("Camera mode: HQ "); 4359 properties->setMode(MODE_HIGH_QUALITY); 4360 err = fetchCapabiltiesForMode(OMX_CaptureImageProfileBase, 4361 sensorId, 4362 properties); 4363 if ( NO_ERROR != err ) { 4364 return err; 4365 } 4366 4367 CAMHAL_LOGD("Camera mode: VIDEO "); 4368 properties->setMode(MODE_VIDEO); 4369 err = fetchCapabiltiesForMode(OMX_CaptureVideo, 4370 sensorId, 4371 properties); 4372 if ( NO_ERROR != err ) { 4373 return err; 4374 } 4375 4376 CAMHAL_LOGD("Camera mode: ZSL "); 4377 properties->setMode(MODE_ZEROSHUTTERLAG); 4378 err = fetchCapabiltiesForMode(OMX_TI_CaptureImageProfileZeroShutterLag, 4379 sensorId, 4380 properties); 4381 if ( NO_ERROR != err ) { 4382 return err; 4383 } 4384 4385 CAMHAL_LOGD("Camera mode: HS "); 4386 properties->setMode(MODE_HIGH_SPEED); 4387 err = fetchCapabiltiesForMode(OMX_CaptureImageHighSpeedTemporalBracketing, 4388 sensorId, 4389 properties); 4390 if ( NO_ERROR != err ) { 4391 return err; 4392 } 4393 4394 CAMHAL_LOGD("Camera mode: CPCAM "); 4395 properties->setMode(MODE_CPCAM); 4396 err = fetchCapabiltiesForMode(OMX_TI_CPCam, 4397 sensorId, 4398 properties); 4399 if ( NO_ERROR != err ) { 4400 return err; 4401 } 4402 4403 #ifdef CAMERAHAL_OMAP5_CAPTURE_MODES 4404 4405 CAMHAL_LOGD("Camera mode: VIDEO HQ "); 4406 properties->setMode(MODE_VIDEO_HIGH_QUALITY); 4407 err = fetchCapabiltiesForMode(OMX_CaptureHighQualityVideo, 4408 sensorId, 4409 properties); 4410 if ( NO_ERROR != err ) { 4411 return err; 4412 } 4413 4414 #endif 4415 4416 } 4417 4418 return err; 4419 } 4420 4421 private: 4422 OMX_HANDLETYPE mComponent; 4423 OMX_STATETYPE mState; 4424 }; 4425 4426 extern "C" status_t OMXCameraAdapter_Capabilities( 4427 CameraProperties::Properties * const properties_array, 4428 const int starting_camera, const int max_camera, int & supportedCameras) 4429 { 4430 LOG_FUNCTION_NAME; 4431 4432 supportedCameras = 0; 4433 4434 int num_cameras_supported = 0; 4435 OMX_ERRORTYPE eError = OMX_ErrorNone; 4436 4437 android::AutoMutex lock(gAdapterLock); 4438 4439 if (!properties_array) { 4440 CAMHAL_LOGEB("invalid param: properties = 0x%p", properties_array); 4441 LOG_FUNCTION_NAME_EXIT; 4442 return BAD_VALUE; 4443 } 4444 4445 eError = OMX_Init(); 4446 if (eError != OMX_ErrorNone) { 4447 CAMHAL_LOGEB("Error OMX_Init -0x%x", eError); 4448 return Utils::ErrorUtils::omxToAndroidError(eError); 4449 } 4450 4451 CapabilitiesHandler handler; 4452 OMX_CALLBACKTYPE callbacks; 4453 callbacks.EventHandler = 0; 4454 callbacks.EmptyBufferDone = 0; 4455 callbacks.FillBufferDone = 0; 4456 4457 eError = OMXCameraAdapter::OMXCameraGetHandle(&handler.componentRef(), &handler, callbacks); 4458 if (eError != OMX_ErrorNone) { 4459 CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError); 4460 goto EXIT; 4461 } 4462 4463 DCCHandler dcc_handler; 4464 dcc_handler.loadDCC(handler.componentRef()); 4465 4466 // Continue selecting sensor and then querying OMX Camera for it's capabilities 4467 // When sensor select returns an error, we know to break and stop 4468 while (eError == OMX_ErrorNone && 4469 (starting_camera + num_cameras_supported) < max_camera) { 4470 4471 const int sensorId = num_cameras_supported; 4472 CameraProperties::Properties * properties = properties_array + starting_camera + sensorId; 4473 const status_t err = handler.fetchCapabilitiesForSensor(sensorId, properties); 4474 4475 if ( err != NO_ERROR ) 4476 break; 4477 4478 num_cameras_supported++; 4479 CAMHAL_LOGEB("Number of OMX Cameras detected = %d \n",num_cameras_supported); 4480 } 4481 4482 // clean up 4483 if(handler.component()) { 4484 CAMHAL_LOGD("Freeing the component..."); 4485 OMX_FreeHandle(handler.component()); 4486 CAMHAL_LOGD("Freeing the component... DONE"); 4487 handler.componentRef() = NULL; 4488 } 4489 4490 EXIT: 4491 CAMHAL_LOGD("Deinit..."); 4492 OMX_Deinit(); 4493 CAMHAL_LOGD("Deinit... DONE"); 4494 4495 if ( eError != OMX_ErrorNone ) 4496 { 4497 CAMHAL_LOGE("Error: 0x%x", eError); 4498 LOG_FUNCTION_NAME_EXIT; 4499 return Utils::ErrorUtils::omxToAndroidError(eError); 4500 } 4501 4502 supportedCameras = num_cameras_supported; 4503 4504 LOG_FUNCTION_NAME_EXIT; 4505 4506 return NO_ERROR; 4507 } 4508 4509 } // namespace Camera 4510 } // namespace Ti 4511 4512 4513 /*--------------------Camera Adapter Class ENDS here-----------------------------*/ 4514 4515