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