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