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