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