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