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