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