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