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