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