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