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