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