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 OMXCapture.cpp 19 * 20 * This file contains functionality for handling image capture. 21 * 22 */ 23 24 #include "CameraHal.h" 25 #include "OMXCameraAdapter.h" 26 #include "ErrorUtils.h" 27 28 29 namespace Ti { 30 namespace Camera { 31 32 status_t OMXCameraAdapter::setParametersCapture(const android::CameraParameters ¶ms, 33 BaseCameraAdapter::AdapterState state) 34 { 35 status_t ret = NO_ERROR; 36 const char *str = NULL; 37 int w, h; 38 OMX_COLOR_FORMATTYPE pixFormat; 39 CodingMode codingMode = mCodingMode; 40 const char *valstr = NULL; 41 int varint = 0; 42 OMX_TI_STEREOFRAMELAYOUTTYPE capFrmLayout; 43 bool inCaptureState = false; 44 45 LOG_FUNCTION_NAME; 46 47 OMXCameraPortParameters *cap; 48 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 49 50 capFrmLayout = cap->mFrameLayoutType; 51 setParamS3D(mCameraAdapterParameters.mImagePortIndex, 52 params.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT)); 53 if (capFrmLayout != cap->mFrameLayoutType) { 54 mPendingCaptureSettings |= SetFormat; 55 } 56 57 params.getPictureSize(&w, &h); 58 59 if ( ( w != ( int ) cap->mWidth ) || 60 ( h != ( int ) cap->mHeight ) ) 61 { 62 mPendingCaptureSettings |= SetFormat; 63 } 64 65 cap->mWidth = w; 66 cap->mHeight = h; 67 //TODO: Support more pixelformats 68 //cap->mStride = 2; 69 70 CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth); 71 CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight); 72 73 if ((valstr = params.getPictureFormat()) != NULL) { 74 if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { 75 CAMHAL_LOGDA("CbYCrY format selected"); 76 pixFormat = OMX_COLOR_FormatCbYCrY; 77 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV422I; 78 } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 79 CAMHAL_LOGDA("YUV420SP format selected"); 80 pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; 81 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV420SP; 82 } else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) { 83 CAMHAL_LOGDA("RGB565 format selected"); 84 pixFormat = OMX_COLOR_Format16bitRGB565; 85 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_RGB565; 86 } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_JPEG) == 0) { 87 CAMHAL_LOGDA("JPEG format selected"); 88 pixFormat = OMX_COLOR_FormatUnused; 89 codingMode = CodingJPEG; 90 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_JPEG; 91 } else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_JPS) == 0) { 92 CAMHAL_LOGDA("JPS format selected"); 93 pixFormat = OMX_COLOR_FormatUnused; 94 codingMode = CodingJPS; 95 mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_JPS; 96 } else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_MPO) == 0) { 97 CAMHAL_LOGDA("MPO format selected"); 98 pixFormat = OMX_COLOR_FormatUnused; 99 codingMode = CodingMPO; 100 mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_MPO; 101 } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) { 102 CAMHAL_LOGDA("RAW Picture format selected"); 103 pixFormat = OMX_COLOR_FormatRawBayer10bit; 104 mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB; 105 } else { 106 CAMHAL_LOGEA("Invalid format, JPEG format selected as default"); 107 pixFormat = OMX_COLOR_FormatUnused; 108 codingMode = CodingJPEG; 109 mPictureFormatFromClient = NULL; 110 } 111 } else { 112 CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG"); 113 pixFormat = OMX_COLOR_FormatUnused; 114 codingMode = CodingJPEG; 115 mPictureFormatFromClient = NULL; 116 } 117 118 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 119 mRawCapture = false; 120 mYuvCapture = false; 121 122 valstr = params.get(TICameraParameters::KEY_CAP_MODE); 123 if ( (!valstr || strcmp(valstr, TICameraParameters::HIGH_QUALITY_MODE) == 0) && 124 access(kRawImagesOutputDirPath, F_OK) != -1 ) { 125 mRawCapture = true; 126 } 127 128 if (mRawCapture && (access(kYuvImagesOutputDirPath, F_OK) != -1)) { 129 pixFormat = OMX_COLOR_FormatCbYCrY; 130 mYuvCapture = true; 131 } 132 #endif 133 // JPEG capture is not supported in video mode by OMX Camera 134 // Set capture format to yuv422i...jpeg encode will 135 // be done on A9 136 valstr = params.get(TICameraParameters::KEY_CAP_MODE); 137 if ( (valstr && ( strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) == 0 || 138 strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE_HQ) == 0 ) ) && 139 (pixFormat == OMX_COLOR_FormatUnused) ) { 140 CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i"); 141 pixFormat = OMX_COLOR_FormatCbYCrY; 142 } 143 144 if (pixFormat != cap->mColorFormat || codingMode != mCodingMode) { 145 mPendingCaptureSettings |= SetFormat; 146 cap->mColorFormat = pixFormat; 147 mCodingMode = codingMode; 148 } 149 150 #ifdef OMAP_ENHANCEMENT 151 str = params.get(TICameraParameters::KEY_TEMP_BRACKETING); 152 if ( ( str != NULL ) && 153 ( strcmp(str, android::CameraParameters::TRUE) == 0 ) ) { 154 155 if ( !mBracketingSet ) { 156 mPendingCaptureSettings |= SetBurstExpBracket; 157 } 158 159 mBracketingSet = true; 160 } else { 161 162 if ( mBracketingSet ) { 163 mPendingCaptureSettings |= SetBurstExpBracket; 164 } 165 166 mBracketingSet = false; 167 } 168 169 if ( (str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL ) { 170 parseExpRange(str, mExposureBracketingValues, NULL, 171 mExposureGainBracketingModes, 172 EXP_BRACKET_RANGE, mExposureBracketingValidEntries); 173 if (mCapMode == OMXCameraAdapter::CP_CAM) { 174 mExposureBracketMode = OMX_BracketVectorShot; 175 } else { 176 mExposureBracketMode = OMX_BracketExposureRelativeInEV; 177 } 178 mPendingCaptureSettings |= SetBurstExpBracket; 179 } else if ( (str = params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE)) != NULL) { 180 parseExpRange(str, mExposureBracketingValues, mExposureGainBracketingValues, 181 mExposureGainBracketingModes, 182 EXP_BRACKET_RANGE, mExposureBracketingValidEntries); 183 if (mCapMode == OMXCameraAdapter::CP_CAM) { 184 mExposureBracketMode = OMX_BracketVectorShot; 185 } else { 186 mExposureBracketMode = OMX_BracketExposureGainAbsolute; 187 } 188 mPendingCaptureSettings |= SetBurstExpBracket; 189 } else { 190 // always set queued shot config in CPCAM mode 191 if (mCapMode == OMXCameraAdapter::CP_CAM) { 192 mExposureBracketMode = OMX_BracketVectorShot; 193 mPendingCaptureSettings |= SetBurstExpBracket; 194 } 195 // if bracketing was previously set...we set again before capturing to clear 196 if (mExposureBracketingValidEntries) { 197 mPendingCaptureSettings |= SetBurstExpBracket; 198 mExposureBracketingValidEntries = 0; 199 } 200 } 201 202 str = params.get(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE); 203 if ( NULL != str ) { 204 parseExpRange(str, mZoomBracketingValues, NULL, NULL, 205 ZOOM_BRACKET_RANGE, mZoomBracketingValidEntries); 206 mCurrentZoomBracketing = 0; 207 mZoomBracketingEnabled = true; 208 } else { 209 if (mZoomBracketingValidEntries) { 210 mZoomBracketingValidEntries = 0; 211 } 212 mZoomBracketingEnabled = false; 213 } 214 #endif 215 216 // Flush config queue 217 // If TRUE: Flush queue and abort processing before enqueing 218 valstr = params.get(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE); 219 if ( NULL != valstr ) { 220 if ( 0 == strcmp(valstr, android::CameraParameters::TRUE) ) { 221 mFlushShotConfigQueue = true; 222 } else if ( 0 == strcmp(valstr, android::CameraParameters::FALSE) ) { 223 mFlushShotConfigQueue = false; 224 } else { 225 CAMHAL_LOGE("Missing flush shot config parameter. Will use current (%s)", 226 mFlushShotConfigQueue ? "true" : "false"); 227 } 228 } 229 230 if ( params.getInt(android::CameraParameters::KEY_ROTATION) != -1 ) 231 { 232 if (params.getInt(android::CameraParameters::KEY_ROTATION) != (int) mPictureRotation) { 233 mPendingCaptureSettings |= SetRotation; 234 } 235 mPictureRotation = params.getInt(android::CameraParameters::KEY_ROTATION); 236 } 237 else 238 { 239 if (mPictureRotation) mPendingCaptureSettings |= SetRotation; 240 mPictureRotation = 0; 241 } 242 243 CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation); 244 245 #ifdef OMAP_ENHANCEMENT 246 // Read Sensor Orientation and set it based on perating mode 247 varint = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION); 248 if ( varint != -1 ) 249 { 250 mSensorOrientation = varint; 251 if (mSensorOrientation == 270 ||mSensorOrientation==90) 252 { 253 CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation to Ducati"); 254 mSensorOrientation +=180; 255 mSensorOrientation%=360; 256 } 257 } 258 else 259 { 260 mSensorOrientation = 0; 261 } 262 263 CAMHAL_LOGVB("Sensor Orientation set : %d", mSensorOrientation); 264 #endif 265 266 #ifdef OMAP_ENHANCEMENT_BURST_CAPTURE 267 varint = params.getInt(TICameraParameters::KEY_BURST); 268 if ( varint >= 1 ) 269 { 270 if (varint != (int) mBurstFrames) { 271 mPendingCaptureSettings |= SetBurstExpBracket; 272 } 273 mBurstFrames = varint; 274 } 275 else 276 { 277 if (mBurstFrames != 1) mPendingCaptureSettings |= SetBurstExpBracket; 278 mBurstFrames = 1; 279 } 280 281 CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames); 282 #endif 283 284 varint = params.getInt(android::CameraParameters::KEY_JPEG_QUALITY); 285 if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) { 286 if (varint != mPictureQuality) { 287 mPendingCaptureSettings |= SetQuality; 288 mPictureQuality = varint; 289 } 290 } else { 291 if (mPictureQuality != MAX_JPEG_QUALITY) { 292 mPendingCaptureSettings |= SetQuality; 293 mPictureQuality = MAX_JPEG_QUALITY; 294 } 295 } 296 297 CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality); 298 299 varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); 300 if ( varint >= 0 ) { 301 if (varint != mThumbWidth) { 302 mPendingCaptureSettings |= SetThumb; 303 mThumbWidth = varint; 304 } 305 } else { 306 if (mThumbWidth != DEFAULT_THUMB_WIDTH) { 307 mPendingCaptureSettings |= SetThumb; 308 mThumbWidth = DEFAULT_THUMB_WIDTH; 309 } 310 } 311 312 CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth); 313 314 varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); 315 if ( varint >= 0 ) { 316 if (varint != mThumbHeight) { 317 mPendingCaptureSettings |= SetThumb; 318 mThumbHeight = varint; 319 } 320 } else { 321 if (mThumbHeight != DEFAULT_THUMB_HEIGHT) { 322 mPendingCaptureSettings |= SetThumb; 323 mThumbHeight = DEFAULT_THUMB_HEIGHT; 324 } 325 } 326 327 CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight); 328 329 varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); 330 if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) { 331 if (varint != mThumbQuality) { 332 mPendingCaptureSettings |= SetThumb; 333 mThumbQuality = varint; 334 } 335 } else { 336 if (mThumbQuality != MAX_JPEG_QUALITY) { 337 mPendingCaptureSettings |= SetThumb; 338 mThumbQuality = MAX_JPEG_QUALITY; 339 } 340 } 341 342 CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality); 343 344 if (mFirstTimeInit) { 345 mPendingCaptureSettings = ECapturesettingsAll; 346 } 347 348 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; 349 cap->mWidth = params.getInt(TICameraParameters::RAW_WIDTH); 350 cap->mHeight = params.getInt(TICameraParameters::RAW_HEIGHT); 351 352 LOG_FUNCTION_NAME_EXIT; 353 354 return ret; 355 } 356 357 status_t OMXCameraAdapter::getPictureBufferSize(CameraFrame &frame, size_t bufferCount) 358 { 359 status_t ret = NO_ERROR; 360 OMXCameraPortParameters *imgCaptureData = NULL; 361 OMX_ERRORTYPE eError = OMX_ErrorNone; 362 363 LOG_FUNCTION_NAME; 364 365 if ( NO_ERROR == ret ) 366 { 367 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 368 369 370 // If any settings have changed that need to be set with SetParam, 371 // we will need to disable the port to set them 372 if ((mPendingCaptureSettings & ECaptureParamSettings)) { 373 disableImagePort(); 374 if ( NULL != mReleaseImageBuffersCallback ) { 375 mReleaseImageBuffersCallback(mReleaseData); 376 } 377 } 378 379 if (mPendingCaptureSettings & SetFormat) { 380 ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData); 381 } 382 383 if ( ret == NO_ERROR ) 384 { 385 frame.mLength = imgCaptureData->mBufSize; 386 frame.mWidth = imgCaptureData->mWidth; 387 frame.mHeight = imgCaptureData->mHeight; 388 frame.mAlignment = imgCaptureData->mStride; 389 CAMHAL_LOGDB("getPictureBufferSize: width:%u height:%u alignment:%u length:%u", 390 frame.mWidth, frame.mHeight, frame.mAlignment, frame.mLength); 391 } 392 else 393 { 394 CAMHAL_LOGEB("setFormat() failed 0x%x", ret); 395 } 396 } 397 398 LOG_FUNCTION_NAME_EXIT; 399 400 return ret; 401 } 402 403 int OMXCameraAdapter::getBracketingValueMode(const char *a, const char *b) const 404 { 405 BracketingValueMode bvm = BracketingValueAbsolute; 406 407 if ( (NULL != b) && 408 (NULL != a) && 409 (a < b) && 410 ( (NULL != memchr(a, '+', b - a)) || 411 (NULL != memchr(a, '-', b - a)) ) ) { 412 bvm = BracketingValueRelative; 413 } 414 return bvm; 415 } 416 417 status_t OMXCameraAdapter::parseExpRange(const char *rangeStr, 418 int *expRange, 419 int *gainRange, 420 int *expGainModes, 421 size_t count, 422 size_t &validEntries) 423 { 424 status_t ret = NO_ERROR; 425 char *end = NULL; 426 const char *startPtr = NULL; 427 size_t i = 0; 428 429 LOG_FUNCTION_NAME; 430 431 if ( NULL == rangeStr ){ 432 return -EINVAL; 433 } 434 435 if ( NULL == expRange ){ 436 return -EINVAL; 437 } 438 439 if ( NO_ERROR == ret ) { 440 startPtr = rangeStr; 441 do { 442 // Relative Exposure example: "-30,-10, 0, 10, 30" 443 // Absolute Gain ex. (exposure,gain) pairs: "(100,300),(200,300),(400,300),(800,300),(1600,300)" 444 // Relative Gain ex. (exposure,gain) pairs: "(-30,+0),(-10, +0),(+0,+0),(+10,+0),(+30,+0)" 445 // Forced relative Exposure example: "-30F,-10F, 0F, 10F, 30F" 446 // Forced absolute Gain ex. (exposure,gain) pairs: "(100,300)F,(200,300)F,(400,300)F,(800,300)F,(1600,300)F" 447 // Forced relative Gain ex. (exposure,gain) pairs: "(-30,+0)F,(-10, +0)F,(+0,+0)F,(+10,+0)F,(+30,+0)F" 448 449 // skip '(' and ',' 450 while ((*startPtr == '(') || (*startPtr == ',')) startPtr++; 451 452 expRange[i] = (int)strtol(startPtr, &end, 10); 453 454 if (expGainModes) { 455 // if gainRange is given rangeStr should be (exposure, gain) pair 456 if (gainRange) { 457 int bvm_exp = getBracketingValueMode(startPtr, end); 458 startPtr = end + 1; // for the ',' 459 gainRange[i] = (int)strtol(startPtr, &end, 10); 460 461 if (BracketingValueAbsolute == bvm_exp) { 462 expGainModes[i] = getBracketingValueMode(startPtr, end); 463 } else { 464 expGainModes[i] = bvm_exp; 465 } 466 } else { 467 expGainModes[i] = BracketingValueCompensation; 468 } 469 } 470 startPtr = end; 471 472 // skip ')' 473 while (*startPtr == ')') startPtr++; 474 475 // Check for "forced" key 476 if (expGainModes) { 477 while ((*startPtr == 'F') || (*startPtr == 'f')) { 478 if ( BracketingValueAbsolute == expGainModes[i] ) { 479 expGainModes[i] = BracketingValueAbsoluteForced; 480 } else if ( BracketingValueRelative == expGainModes[i] ) { 481 expGainModes[i] = BracketingValueRelativeForced; 482 } else if ( BracketingValueCompensation == expGainModes[i] ) { 483 expGainModes[i] = BracketingValueCompensationForced; 484 } else { 485 CAMHAL_LOGE("Unexpected old mode 0x%x", expGainModes[i]); 486 } 487 startPtr++; 488 } 489 } 490 491 i++; 492 493 } while ((startPtr[0] != '\0') && (i < count)); 494 validEntries = i; 495 } 496 497 LOG_FUNCTION_NAME_EXIT; 498 499 return ret; 500 } 501 502 status_t OMXCameraAdapter::doExposureBracketing(int *evValues, 503 int *evValues2, 504 int *evModes2, 505 size_t evCount, 506 size_t frameCount, 507 bool flush, 508 OMX_BRACKETMODETYPE bracketMode) 509 { 510 status_t ret = NO_ERROR; 511 512 LOG_FUNCTION_NAME; 513 514 if ( OMX_StateInvalid == mComponentState ) { 515 CAMHAL_LOGEA("OMX component is in invalid state"); 516 ret = -EINVAL; 517 } 518 519 if ( NULL == evValues ) { 520 CAMHAL_LOGEA("Exposure compensation values pointer is invalid"); 521 ret = -EINVAL; 522 } 523 524 if ( NO_ERROR == ret ) { 525 if (bracketMode == OMX_BracketVectorShot) { 526 ret = setVectorShot(evValues, evValues2, evModes2, evCount, frameCount, flush, bracketMode); 527 } else { 528 ret = setExposureBracketing(evValues, evValues2, evCount, frameCount, bracketMode); 529 } 530 } 531 532 LOG_FUNCTION_NAME_EXIT; 533 534 return ret; 535 } 536 537 status_t OMXCameraAdapter::setVectorStop(bool toPreview) 538 { 539 status_t ret = NO_ERROR; 540 OMX_ERRORTYPE eError = OMX_ErrorNone; 541 OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE vecShotStop; 542 543 544 LOG_FUNCTION_NAME; 545 546 OMX_INIT_STRUCT_PTR(&vecShotStop, OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE); 547 548 vecShotStop.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 549 if (toPreview) { 550 vecShotStop.eStopMethod = OMX_TI_VECTSHOTSTOPMETHOD_GOTO_PREVIEW; 551 } else { 552 vecShotStop.eStopMethod = OMX_TI_VECTSHOTSTOPMETHOD_WAIT_IN_CAPTURE; 553 } 554 555 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 556 (OMX_INDEXTYPE) OMX_TI_IndexConfigVectShotStopMethod, 557 &vecShotStop); 558 if (OMX_ErrorNone != eError) { 559 CAMHAL_LOGEB("Error while configuring bracket shot 0x%x", eError); 560 } else { 561 CAMHAL_LOGDA("Bracket shot configured successfully"); 562 } 563 564 LOG_FUNCTION_NAME_EXIT; 565 566 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 567 } 568 569 status_t OMXCameraAdapter::initVectorShot() 570 { 571 status_t ret = NO_ERROR; 572 OMX_ERRORTYPE eError = OMX_ErrorNone; 573 OMX_CONFIG_CAPTUREMODETYPE expCapMode; 574 OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode; 575 576 LOG_FUNCTION_NAME; 577 578 if (NO_ERROR == ret) { 579 OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE); 580 expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 581 582 expCapMode.bFrameLimited = OMX_FALSE; 583 584 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 585 OMX_IndexConfigCaptureMode, 586 &expCapMode); 587 if (OMX_ErrorNone != eError) { 588 CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError); 589 goto exit; 590 } else { 591 CAMHAL_LOGDA("Camera capture mode configured successfully"); 592 } 593 } 594 595 if (NO_ERROR == ret) { 596 OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE); 597 extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 598 599 extExpCapMode.bEnableBracketing = OMX_TRUE; 600 extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketVectorShot; 601 602 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 603 ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode, 604 &extExpCapMode); 605 if ( OMX_ErrorNone != eError ) { 606 CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError); 607 goto exit; 608 } else { 609 CAMHAL_LOGDA("Extended camera capture mode configured successfully"); 610 } 611 } 612 613 614 if (NO_ERROR == ret) { 615 // set vector stop method to stop in capture 616 ret = setVectorStop(false); 617 } 618 619 exit: 620 LOG_FUNCTION_NAME_EXIT; 621 622 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 623 } 624 625 status_t OMXCameraAdapter::setVectorShot(int *evValues, 626 int *evValues2, 627 int *evModes2, 628 size_t evCount, 629 size_t frameCount, 630 bool flush, 631 OMX_BRACKETMODETYPE bracketMode) 632 { 633 status_t ret = NO_ERROR; 634 OMX_ERRORTYPE eError = OMX_ErrorNone; 635 OMX_TI_CONFIG_ENQUEUESHOTCONFIGS enqueueShotConfigs; 636 OMX_TI_CONFIG_QUERYAVAILABLESHOTS queryAvailableShots; 637 bool doFlush = flush; 638 639 LOG_FUNCTION_NAME; 640 641 OMX_INIT_STRUCT_PTR(&enqueueShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS); 642 OMX_INIT_STRUCT_PTR(&queryAvailableShots, OMX_TI_CONFIG_QUERYAVAILABLESHOTS); 643 644 queryAvailableShots.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 645 eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, 646 (OMX_INDEXTYPE) OMX_TI_IndexConfigQueryAvailableShots, 647 &queryAvailableShots); 648 if (OMX_ErrorNone != eError) { 649 CAMHAL_LOGE("Error getting available shots 0x%x", eError); 650 goto exit; 651 } else { 652 CAMHAL_LOGD("AVAILABLE SHOTS: %d", queryAvailableShots.nAvailableShots); 653 if (queryAvailableShots.nAvailableShots < evCount) { 654 // TODO(XXX): Need to implement some logic to handle this error 655 CAMHAL_LOGE("Not enough available shots to fulfill this queue request"); 656 ret = -ENOSPC; 657 goto exit; 658 } 659 } 660 661 for ( unsigned int confID = 0; confID < evCount; ) { 662 unsigned int i; 663 for ( i = 0 ; (i < ARRAY_SIZE(enqueueShotConfigs.nShotConfig)) && (confID < evCount); i++, confID++ ) { 664 CAMHAL_LOGD("%2u: (%7d,%4d) mode: %d", confID, evValues[confID], evValues2[confID], evModes2[confID]); 665 enqueueShotConfigs.nShotConfig[i].nConfigId = confID; 666 enqueueShotConfigs.nShotConfig[i].nFrames = 1; 667 if ( (BracketingValueCompensation == evModes2[confID]) || 668 (BracketingValueCompensationForced == evModes2[confID]) ) { 669 // EV compensation 670 enqueueShotConfigs.nShotConfig[i].nEC = evValues[confID]; 671 enqueueShotConfigs.nShotConfig[i].nExp = 0; 672 enqueueShotConfigs.nShotConfig[i].nGain = 0; 673 } else { 674 // exposure,gain pair 675 enqueueShotConfigs.nShotConfig[i].nEC = 0; 676 enqueueShotConfigs.nShotConfig[i].nExp = evValues[confID]; 677 enqueueShotConfigs.nShotConfig[i].nGain = evValues2[confID]; 678 } 679 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE; 680 switch (evModes2[confID]) { 681 case BracketingValueAbsolute: // (exp,gain) pairs directly program sensor values 682 default : 683 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE; 684 break; 685 case BracketingValueRelative: // (exp,gain) pairs relative to AE settings and constraints 686 case BracketingValueCompensation: // EV compensation relative to AE settings and constraints 687 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE; 688 break; 689 case BracketingValueAbsoluteForced: // (exp,gain) pairs directly program sensor values 690 // are forced over constraints due to flicker, etc. 691 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_ABSOLUTE; 692 break; 693 case BracketingValueRelativeForced: // (exp, gain) pairs relative to AE settings AND settings 694 case BracketingValueCompensationForced: // EV compensation relative to AE settings and constraints 695 // are forced over constraints due to flicker, etc. 696 enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_RELATIVE; 697 break; 698 } 699 enqueueShotConfigs.nShotConfig[i].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable 700 } 701 702 // Repeat last exposure and again 703 if ((confID == evCount) && (evCount > 0) && (frameCount > evCount) && (0 != i)) { 704 enqueueShotConfigs.nShotConfig[i-1].nFrames = frameCount - evCount; 705 } 706 707 enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 708 enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE; 709 enqueueShotConfigs.nNumConfigs = i; 710 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 711 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs, 712 &enqueueShotConfigs); 713 if ( OMX_ErrorNone != eError ) { 714 CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError); 715 goto exit; 716 } else { 717 CAMHAL_LOGDA("Enqueue shot configured successfully"); 718 } 719 // Flush only first time 720 doFlush = false; 721 } 722 723 // Handle burst capture (no any bracketing) case 724 if (0 == evCount) { 725 CAMHAL_LOGE("Handle burst capture (no any bracketing) case"); 726 enqueueShotConfigs.nShotConfig[0].nConfigId = 0; 727 enqueueShotConfigs.nShotConfig[0].nFrames = frameCount; 728 enqueueShotConfigs.nShotConfig[0].nEC = 0; 729 enqueueShotConfigs.nShotConfig[0].nExp = 0; 730 enqueueShotConfigs.nShotConfig[0].nGain = 0; 731 enqueueShotConfigs.nShotConfig[0].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE; 732 enqueueShotConfigs.nShotConfig[0].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable 733 enqueueShotConfigs.nNumConfigs = 1; 734 enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 735 enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE; 736 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 737 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs, 738 &enqueueShotConfigs); 739 if ( OMX_ErrorNone != eError ) { 740 CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError); 741 goto exit; 742 } else { 743 CAMHAL_LOGDA("Enqueue shot configured successfully"); 744 } 745 } 746 747 exit: 748 LOG_FUNCTION_NAME_EXIT; 749 750 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 751 } 752 753 status_t OMXCameraAdapter::setExposureBracketing(int *evValues, 754 int *evValues2, 755 size_t evCount, 756 size_t frameCount, 757 OMX_BRACKETMODETYPE bracketMode) 758 { 759 status_t ret = NO_ERROR; 760 OMX_ERRORTYPE eError = OMX_ErrorNone; 761 OMX_CONFIG_CAPTUREMODETYPE expCapMode; 762 OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode; 763 764 LOG_FUNCTION_NAME; 765 766 if ( NO_ERROR == ret ) 767 { 768 OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE); 769 expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 770 771 /// If frameCount>0 but evCount<=0, then this is the case of HQ burst. 772 //Otherwise, it is normal HQ capture 773 ///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing. 774 if ( 0 == evCount && 0 == frameCount ) 775 { 776 expCapMode.bFrameLimited = OMX_FALSE; 777 } 778 else 779 { 780 expCapMode.bFrameLimited = OMX_TRUE; 781 expCapMode.nFrameLimit = frameCount; 782 } 783 784 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 785 OMX_IndexConfigCaptureMode, 786 &expCapMode); 787 if ( OMX_ErrorNone != eError ) 788 { 789 CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError); 790 } 791 else 792 { 793 CAMHAL_LOGDA("Camera capture mode configured successfully"); 794 } 795 } 796 797 if ( NO_ERROR == ret ) 798 { 799 OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE); 800 extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 801 802 if ( 0 == evCount ) 803 { 804 extExpCapMode.bEnableBracketing = OMX_FALSE; 805 } 806 else 807 { 808 extExpCapMode.bEnableBracketing = OMX_TRUE; 809 extExpCapMode.tBracketConfigType.eBracketMode = bracketMode; 810 extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1; 811 } 812 813 for ( unsigned int i = 0 ; i < evCount ; i++ ) 814 { 815 if (bracketMode == OMX_BracketExposureGainAbsolute) { 816 extExpCapMode.tBracketConfigType.nBracketValues[i] = evValues[i]; 817 extExpCapMode.tBracketConfigType.nBracketValues2[i] = evValues2[i]; 818 } else { 819 // assuming OMX_BracketExposureRelativeInEV 820 extExpCapMode.tBracketConfigType.nBracketValues[i] = ( evValues[i] * ( 1 << Q16_OFFSET ) ) / 10; 821 } 822 } 823 824 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 825 ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode, 826 &extExpCapMode); 827 if ( OMX_ErrorNone != eError ) 828 { 829 CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError); 830 } 831 else 832 { 833 CAMHAL_LOGDA("Extended camera capture mode configured successfully"); 834 } 835 } 836 837 LOG_FUNCTION_NAME_EXIT; 838 839 return ret; 840 } 841 842 status_t OMXCameraAdapter::setShutterCallback(bool enabled) 843 { 844 status_t ret = NO_ERROR; 845 OMX_ERRORTYPE eError = OMX_ErrorNone; 846 OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback; 847 848 LOG_FUNCTION_NAME; 849 850 if ( OMX_StateExecuting != mComponentState ) 851 { 852 CAMHAL_LOGEA("OMX component not in executing state"); 853 ret = -1; 854 } 855 856 if ( NO_ERROR == ret ) 857 { 858 859 OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE); 860 shutterRequstCallback.nPortIndex = OMX_ALL; 861 862 if ( enabled ) 863 { 864 shutterRequstCallback.bEnable = OMX_TRUE; 865 shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback; 866 CAMHAL_LOGDA("Enabling shutter callback"); 867 } 868 else 869 { 870 shutterRequstCallback.bEnable = OMX_FALSE; 871 shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback; 872 CAMHAL_LOGDA("Disabling shutter callback"); 873 } 874 875 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 876 ( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest, 877 &shutterRequstCallback); 878 if ( OMX_ErrorNone != eError ) 879 { 880 CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError); 881 ret = -1; 882 } 883 else 884 { 885 CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully", 886 OMX_TI_IndexConfigShutterCallback); 887 } 888 } 889 890 LOG_FUNCTION_NAME_EXIT; 891 892 return ret; 893 } 894 895 status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader, 896 CameraFrame::FrameType typeOfFrame) 897 { 898 status_t ret = NO_ERROR; 899 int currentBufferIdx, nextBufferIdx; 900 OMXCameraPortParameters * imgCaptureData = NULL; 901 902 LOG_FUNCTION_NAME; 903 904 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 905 906 if ( OMX_StateExecuting != mComponentState ) 907 { 908 CAMHAL_LOGEA("OMX component is not in executing state"); 909 ret = -EINVAL; 910 } 911 912 if ( NO_ERROR == ret ) 913 { 914 CameraBuffer *buffer = (CameraBuffer *)pBuffHeader->pAppPrivate; 915 currentBufferIdx = buffer->index; 916 917 if ( currentBufferIdx >= imgCaptureData->mNumBufs) 918 { 919 CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx); 920 ret = -EINVAL; 921 } 922 } 923 924 if ( NO_ERROR == ret ) 925 { 926 mBracketingBuffersQueued[currentBufferIdx] = false; 927 mBracketingBuffersQueuedCount--; 928 929 if ( 0 >= mBracketingBuffersQueuedCount ) 930 { 931 nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs; 932 mBracketingBuffersQueued[nextBufferIdx] = true; 933 mBracketingBuffersQueuedCount++; 934 mLastBracetingBufferIdx = nextBufferIdx; 935 setFrameRefCount((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame, 1); 936 returnFrame((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame); 937 } 938 } 939 940 LOG_FUNCTION_NAME_EXIT; 941 942 return ret; 943 } 944 945 status_t OMXCameraAdapter::sendBracketFrames(size_t &framesSent) 946 { 947 status_t ret = NO_ERROR; 948 int currentBufferIdx; 949 OMXCameraPortParameters * imgCaptureData = NULL; 950 951 LOG_FUNCTION_NAME; 952 953 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 954 framesSent = 0; 955 956 if ( OMX_StateExecuting != mComponentState ) 957 { 958 CAMHAL_LOGEA("OMX component is not in executing state"); 959 ret = -EINVAL; 960 } 961 962 if ( NO_ERROR == ret ) 963 { 964 965 currentBufferIdx = mLastBracetingBufferIdx; 966 do 967 { 968 currentBufferIdx++; 969 currentBufferIdx %= imgCaptureData->mNumBufs; 970 if (!mBracketingBuffersQueued[currentBufferIdx] ) 971 { 972 CameraFrame cameraFrame; 973 sendCallBacks(cameraFrame, 974 imgCaptureData->mBufferHeader[currentBufferIdx], 975 imgCaptureData->mImageType, 976 imgCaptureData); 977 framesSent++; 978 } 979 } while ( currentBufferIdx != mLastBracetingBufferIdx ); 980 981 } 982 983 LOG_FUNCTION_NAME_EXIT; 984 985 return ret; 986 } 987 988 status_t OMXCameraAdapter::startBracketing(int range) 989 { 990 status_t ret = NO_ERROR; 991 OMXCameraPortParameters * imgCaptureData = NULL; 992 993 LOG_FUNCTION_NAME; 994 995 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 996 997 if ( OMX_StateExecuting != mComponentState ) 998 { 999 CAMHAL_LOGEA("OMX component is not in executing state"); 1000 ret = -EINVAL; 1001 } 1002 1003 { 1004 android::AutoMutex lock(mBracketingLock); 1005 1006 if ( mBracketingEnabled ) 1007 { 1008 return ret; 1009 } 1010 } 1011 1012 if ( 0 == imgCaptureData->mNumBufs ) 1013 { 1014 CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs); 1015 ret = -EINVAL; 1016 } 1017 1018 if ( mPending3Asettings ) 1019 apply3Asettings(mParameters3A); 1020 1021 if ( NO_ERROR == ret ) 1022 { 1023 android::AutoMutex lock(mBracketingLock); 1024 1025 mBracketingRange = range; 1026 mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs]; 1027 if ( NULL == mBracketingBuffersQueued ) 1028 { 1029 CAMHAL_LOGEA("Unable to allocate bracketing management structures"); 1030 ret = -1; 1031 } 1032 1033 if ( NO_ERROR == ret ) 1034 { 1035 mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs; 1036 mBurstFramesAccum = imgCaptureData->mNumBufs; 1037 mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1; 1038 1039 for ( int i = 0 ; i < imgCaptureData->mNumBufs ; i++ ) 1040 { 1041 mBracketingBuffersQueued[i] = true; 1042 } 1043 1044 } 1045 } 1046 1047 if ( NO_ERROR == ret ) 1048 { 1049 CachedCaptureParameters* cap_params = cacheCaptureParameters(); 1050 ret = startImageCapture(true, cap_params); 1051 delete cap_params; 1052 { 1053 android::AutoMutex lock(mBracketingLock); 1054 1055 if ( NO_ERROR == ret ) 1056 { 1057 mBracketingEnabled = true; 1058 } 1059 else 1060 { 1061 mBracketingEnabled = false; 1062 } 1063 } 1064 } 1065 1066 LOG_FUNCTION_NAME_EXIT; 1067 1068 return ret; 1069 } 1070 1071 status_t OMXCameraAdapter::stopBracketing() 1072 { 1073 status_t ret = NO_ERROR; 1074 1075 LOG_FUNCTION_NAME; 1076 1077 ret = stopImageCapture(); 1078 1079 android::AutoMutex lock(mBracketingLock); 1080 1081 if ( NULL != mBracketingBuffersQueued ) 1082 { 1083 delete [] mBracketingBuffersQueued; 1084 } 1085 1086 mBracketingBuffersQueued = NULL; 1087 mBracketingEnabled = false; 1088 mBracketingBuffersQueuedCount = 0; 1089 mLastBracetingBufferIdx = 0; 1090 1091 LOG_FUNCTION_NAME_EXIT; 1092 1093 return ret; 1094 } 1095 1096 status_t OMXCameraAdapter::startImageCapture(bool bracketing, CachedCaptureParameters* capParams) 1097 { 1098 status_t ret = NO_ERROR; 1099 OMX_ERRORTYPE eError = OMX_ErrorNone; 1100 OMXCameraPortParameters * capData = NULL; 1101 OMX_CONFIG_BOOLEANTYPE bOMX; 1102 size_t bracketingSent = 0; 1103 1104 LOG_FUNCTION_NAME; 1105 1106 android::AutoMutex lock(mImageCaptureLock); 1107 1108 if(!mCaptureConfigured) 1109 { 1110 ///Image capture was cancelled before we could start 1111 return NO_ERROR; 1112 } 1113 1114 if ( 0 != mStartCaptureSem.Count() ) 1115 { 1116 CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count()); 1117 return NO_INIT; 1118 } 1119 1120 if ( !bracketing ) { 1121 if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) { 1122 CAMHAL_LOGDA("trying starting capture when already canceled"); 1123 return NO_ERROR; 1124 } 1125 } 1126 1127 if (!capParams) { 1128 CAMHAL_LOGE("Invalid cached parameters sent!"); 1129 return BAD_VALUE; 1130 } 1131 1132 // Camera framework doesn't expect face callbacks once capture is triggered 1133 pauseFaceDetection(true); 1134 1135 //During bracketing image capture is already active 1136 { 1137 android::AutoMutex lock(mBracketingLock); 1138 if ( mBracketingEnabled ) 1139 { 1140 //Stop bracketing, activate normal burst for the remaining images 1141 mBracketingEnabled = false; 1142 ret = sendBracketFrames(bracketingSent); 1143 1144 // Check if we accumulated enough buffers 1145 if ( bracketingSent < ( mBracketingRange - 1 ) ) 1146 { 1147 mCapturedFrames = mBracketingRange + ( ( mBracketingRange - 1 ) - bracketingSent ); 1148 } 1149 else 1150 { 1151 mCapturedFrames = mBracketingRange; 1152 } 1153 mBurstFramesQueued = 0; 1154 mBurstFramesAccum = mCapturedFrames; 1155 1156 if(ret != NO_ERROR) 1157 goto EXIT; 1158 else 1159 return ret; 1160 } 1161 } 1162 1163 if ( NO_ERROR == ret ) { 1164 if (capParams->mPendingCaptureSettings & SetRotation) { 1165 mPendingCaptureSettings &= ~SetRotation; 1166 ret = setPictureRotation(mPictureRotation); 1167 if ( NO_ERROR != ret ) { 1168 CAMHAL_LOGEB("Error configuring image rotation %x", ret); 1169 } 1170 } 1171 1172 if (capParams->mPendingCaptureSettings & SetBurstExpBracket) { 1173 mPendingCaptureSettings &= ~SetBurstExpBracket; 1174 if ( mBracketingSet ) { 1175 ret = doExposureBracketing(capParams->mExposureBracketingValues, 1176 capParams->mExposureGainBracketingValues, 1177 capParams->mExposureGainBracketingModes, 1178 0, 1179 0, 1180 capParams->mFlushShotConfigQueue, 1181 capParams->mExposureBracketMode); 1182 } else { 1183 ret = doExposureBracketing(capParams->mExposureBracketingValues, 1184 capParams->mExposureGainBracketingValues, 1185 capParams->mExposureGainBracketingModes, 1186 capParams->mExposureBracketingValidEntries, 1187 capParams->mBurstFrames, 1188 capParams->mFlushShotConfigQueue, 1189 capParams->mExposureBracketMode); 1190 } 1191 1192 if ( ret != NO_ERROR ) { 1193 CAMHAL_LOGEB("setExposureBracketing() failed %d", ret); 1194 goto EXIT; 1195 } 1196 } 1197 } 1198 1199 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS 1200 CameraHal::PPM("startImageCapture bracketing configs done: ", &mStartCapture); 1201 #endif 1202 1203 capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 1204 1205 //OMX shutter callback events are only available in hq mode 1206 if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) { 1207 if ( NO_ERROR == ret ) 1208 { 1209 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1210 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 1211 OMX_ALL, 1212 OMX_TI_IndexConfigShutterCallback, 1213 mStartCaptureSem); 1214 } 1215 1216 if ( NO_ERROR == ret ) 1217 { 1218 ret = setShutterCallback(true); 1219 } 1220 1221 } 1222 1223 if (mPending3Asettings) { 1224 apply3Asettings(mParameters3A); 1225 } 1226 1227 if (ret == NO_ERROR) { 1228 int index = 0; 1229 int queued = 0; 1230 android::AutoMutex lock(mBurstLock); 1231 1232 if (capParams->mFlushShotConfigQueue) { 1233 // reset shot queue 1234 mCapturedFrames = mBurstFrames; 1235 mBurstFramesAccum = mBurstFrames; 1236 mBurstFramesQueued = 0; 1237 for ( int index = 0 ; index < capData->mNumBufs ; index++ ) { 1238 if (OMXCameraPortParameters::FILL == capData->mStatus[index]) { 1239 mBurstFramesQueued++; 1240 } 1241 } 1242 } else { 1243 mCapturedFrames += mBurstFrames; 1244 mBurstFramesAccum += mBurstFrames; 1245 } 1246 CAMHAL_LOGD("mBurstFramesQueued = %d mBurstFramesAccum = %d index = %d " 1247 "capData->mNumBufs = %d queued = %d capData->mMaxQueueable = %d", 1248 mBurstFramesQueued,mBurstFramesAccum,index, 1249 capData->mNumBufs,queued,capData->mMaxQueueable); 1250 CAMHAL_LOGD("%d", (mBurstFramesQueued < mBurstFramesAccum) 1251 && (index < capData->mNumBufs) 1252 && (queued < capData->mMaxQueueable)); 1253 while ((mBurstFramesQueued < mBurstFramesAccum) && 1254 (index < capData->mNumBufs) && 1255 (queued < capData->mMaxQueueable)) { 1256 if (capData->mStatus[index] == OMXCameraPortParameters::IDLE) { 1257 CAMHAL_LOGDB("Queuing buffer on Capture port - %p", 1258 capData->mBufferHeader[index]->pBuffer); 1259 capData->mStatus[index] = OMXCameraPortParameters::FILL; 1260 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 1261 (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]); 1262 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1263 mBurstFramesQueued++; 1264 queued++; 1265 } else if (OMXCameraPortParameters::FILL == capData->mStatus[index]) { 1266 CAMHAL_LOGE("Not queueing index = %d", index); 1267 queued++; 1268 } 1269 index++; 1270 } 1271 1272 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 1273 if (mRawCapture) { 1274 capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; 1275 1276 ///Queue all the buffers on capture port 1277 for ( int index = 0 ; index < capData->mNumBufs ; index++ ) { 1278 CAMHAL_LOGDB("Queuing buffer on Video port (for RAW capture) - 0x%x", ( unsigned int ) capData->mBufferHeader[index]->pBuffer); 1279 capData->mStatus[index] = OMXCameraPortParameters::FILL; 1280 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 1281 (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]); 1282 1283 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1284 } 1285 } 1286 #endif 1287 1288 mWaitingForSnapshot = true; 1289 mCaptureSignalled = false; 1290 1291 // Capturing command is not needed when capturing in video mode 1292 // Only need to queue buffers on image ports 1293 if ( ( mCapMode != VIDEO_MODE ) && ( mCapMode != VIDEO_MODE_HQ ) ) { 1294 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 1295 bOMX.bEnabled = OMX_TRUE; 1296 1297 /// sending Capturing Command to the component 1298 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 1299 OMX_IndexConfigCapturing, 1300 &bOMX); 1301 1302 CAMHAL_LOGDB("Capture set - 0x%x", eError); 1303 1304 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1305 } 1306 } 1307 1308 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS 1309 CameraHal::PPM("startImageCapture image buffers queued and capture enabled: ", &mStartCapture); 1310 #endif 1311 1312 //OMX shutter callback events are only available in hq mode 1313 1314 if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) 1315 { 1316 if ( NO_ERROR == ret ) 1317 { 1318 ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT); 1319 } 1320 1321 //If something bad happened while we wait 1322 if (mComponentState != OMX_StateExecuting) 1323 { 1324 CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!"); 1325 goto EXIT; 1326 } 1327 1328 if ( NO_ERROR == ret ) 1329 { 1330 CAMHAL_LOGDA("Shutter callback received"); 1331 notifyShutterSubscribers(); 1332 } 1333 else 1334 { 1335 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1336 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 1337 OMX_ALL, 1338 OMX_TI_IndexConfigShutterCallback, 1339 NULL); 1340 CAMHAL_LOGEA("Timeout expired on shutter callback"); 1341 goto EXIT; 1342 } 1343 1344 } 1345 1346 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS 1347 CameraHal::PPM("startImageCapture shutter event received: ", &mStartCapture); 1348 #endif 1349 1350 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1351 1352 EXIT: 1353 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1354 mWaitingForSnapshot = false; 1355 mCaptureSignalled = false; 1356 performCleanupAfterError(); 1357 LOG_FUNCTION_NAME_EXIT; 1358 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1359 } 1360 1361 status_t OMXCameraAdapter::stopImageCapture() 1362 { 1363 status_t ret = NO_ERROR; 1364 OMX_ERRORTYPE eError = OMX_ErrorNone; 1365 OMX_CONFIG_BOOLEANTYPE bOMX; 1366 OMXCameraPortParameters *imgCaptureData = NULL; 1367 1368 LOG_FUNCTION_NAME; 1369 1370 android::AutoMutex lock(mImageCaptureLock); 1371 1372 if (!mCaptureConfigured) { 1373 //Capture is not ongoing, return from here 1374 return NO_ERROR; 1375 } 1376 1377 if ( 0 != mStopCaptureSem.Count() ) { 1378 CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count()); 1379 goto EXIT; 1380 } 1381 1382 // TODO(XXX): Reprocessing is currently piggy-backing capture commands 1383 if (mAdapterState == REPROCESS_STATE) { 1384 ret = stopReprocess(); 1385 } 1386 1387 //Disable the callback first 1388 mWaitingForSnapshot = false; 1389 1390 // OMX shutter callback events are only available in hq mode 1391 if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) { 1392 //Disable the callback first 1393 ret = setShutterCallback(false); 1394 1395 // if anybody is waiting on the shutter callback 1396 // signal them and then recreate the semaphore 1397 if ( 0 != mStartCaptureSem.Count() ) { 1398 1399 for (int i = mStartCaptureSem.Count(); i < 0; i++) { 1400 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 1401 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 1402 OMX_ALL, 1403 OMX_TI_IndexConfigShutterCallback, 1404 NULL ); 1405 } 1406 mStartCaptureSem.Create(0); 1407 } 1408 } else if (CP_CAM == mCapMode) { 1409 // Reset shot config queue 1410 OMX_TI_CONFIG_ENQUEUESHOTCONFIGS resetShotConfigs; 1411 OMX_INIT_STRUCT_PTR(&resetShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS); 1412 1413 resetShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 1414 resetShotConfigs.bFlushQueue = OMX_TRUE; 1415 resetShotConfigs.nNumConfigs = 0; 1416 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 1417 ( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs, 1418 &resetShotConfigs); 1419 if ( OMX_ErrorNone != eError ) { 1420 CAMHAL_LOGEB("Error while reset shot config 0x%x", eError); 1421 goto EXIT; 1422 } else { 1423 CAMHAL_LOGDA("Shot config reset successfully"); 1424 } 1425 } 1426 1427 //Wait here for the capture to be done, in worst case timeout and proceed with cleanup 1428 mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT); 1429 1430 //If somethiing bad happened while we wait 1431 if (mComponentState == OMX_StateInvalid) 1432 { 1433 CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!"); 1434 goto EXIT; 1435 } 1436 1437 // Disable image capture 1438 // Capturing command is not needed when capturing in video mode 1439 if ( ( mCapMode != VIDEO_MODE ) && ( mCapMode != VIDEO_MODE_HQ ) ) { 1440 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 1441 bOMX.bEnabled = OMX_FALSE; 1442 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 1443 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 1444 OMX_IndexConfigCapturing, 1445 &bOMX); 1446 if ( OMX_ErrorNone != eError ) { 1447 CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError); 1448 ret = -1; 1449 goto EXIT; 1450 } 1451 } 1452 1453 CAMHAL_LOGDB("Capture set - 0x%x", eError); 1454 1455 mCaptureSignalled = true; //set this to true if we exited because of timeout 1456 1457 { 1458 android::AutoMutex lock(mFrameCountMutex); 1459 mFrameCount = 0; 1460 mFirstFrameCondition.broadcast(); 1461 } 1462 1463 // Stop is always signalled externally in CPCAM mode 1464 // We need to make sure we really stop 1465 if ((mCapMode == CP_CAM)) { 1466 disableReprocess(); 1467 disableImagePort(); 1468 if ( NULL != mReleaseImageBuffersCallback ) { 1469 mReleaseImageBuffersCallback(mReleaseData); 1470 } 1471 } 1472 1473 // Moving code for below commit here as an optimization for continuous capture, 1474 // so focus settings don't have to reapplied after each capture 1475 // c78fa2a CameraHAL: Always reset focus mode after capture 1476 // Workaround when doing many consecutive shots, CAF wasn't getting restarted. 1477 mPending3Asettings |= SetFocus; 1478 1479 mCapturedFrames = 0; 1480 mBurstFramesAccum = 0; 1481 mBurstFramesQueued = 0; 1482 1483 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1484 1485 EXIT: 1486 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1487 //Release image buffers 1488 if ( NULL != mReleaseImageBuffersCallback ) { 1489 mReleaseImageBuffersCallback(mReleaseData); 1490 } 1491 1492 { 1493 android::AutoMutex lock(mFrameCountMutex); 1494 mFrameCount = 0; 1495 mFirstFrameCondition.broadcast(); 1496 } 1497 1498 performCleanupAfterError(); 1499 LOG_FUNCTION_NAME_EXIT; 1500 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1501 } 1502 1503 status_t OMXCameraAdapter::disableImagePort(){ 1504 status_t ret = NO_ERROR; 1505 OMX_ERRORTYPE eError = OMX_ErrorNone; 1506 OMXCameraPortParameters *imgCaptureData = NULL; 1507 OMXCameraPortParameters *imgRawCaptureData = NULL; 1508 1509 if (!mCaptureConfigured) { 1510 return NO_ERROR; 1511 } 1512 1513 mCaptureConfigured = false; 1514 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 1515 imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; // for RAW capture 1516 1517 ///Register for Image port Disable event 1518 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1519 OMX_EventCmdComplete, 1520 OMX_CommandPortDisable, 1521 mCameraAdapterParameters.mImagePortIndex, 1522 mStopCaptureSem); 1523 ///Disable Capture Port 1524 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1525 OMX_CommandPortDisable, 1526 mCameraAdapterParameters.mImagePortIndex, 1527 NULL); 1528 1529 ///Free all the buffers on capture port 1530 if (imgCaptureData) { 1531 CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs); 1532 for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) { 1533 CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x", 1534 ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer); 1535 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 1536 mCameraAdapterParameters.mImagePortIndex, 1537 (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]); 1538 1539 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1540 } 1541 } 1542 CAMHAL_LOGDA("Waiting for port disable"); 1543 //Wait for the image port enable event 1544 ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT); 1545 1546 //If somethiing bad happened while we wait 1547 if (mComponentState == OMX_StateInvalid) 1548 { 1549 CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!"); 1550 goto EXIT; 1551 } 1552 1553 if ( NO_ERROR == ret ) { 1554 CAMHAL_LOGDA("Port disabled"); 1555 } else { 1556 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1557 OMX_EventCmdComplete, 1558 OMX_CommandPortDisable, 1559 mCameraAdapterParameters.mImagePortIndex, 1560 NULL); 1561 CAMHAL_LOGDA("Timeout expired on port disable"); 1562 goto EXIT; 1563 } 1564 1565 deinitInternalBuffers(mCameraAdapterParameters.mImagePortIndex); 1566 1567 // since port settings are not persistent after port is disabled... 1568 mPendingCaptureSettings |= SetFormat; 1569 1570 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 1571 1572 if (mRawCapture) { 1573 ///Register for Video port Disable event 1574 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1575 OMX_EventCmdComplete, 1576 OMX_CommandPortDisable, 1577 mCameraAdapterParameters.mVideoPortIndex, 1578 mStopCaptureSem); 1579 ///Disable RawCapture Port 1580 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1581 OMX_CommandPortDisable, 1582 mCameraAdapterParameters.mVideoPortIndex, 1583 NULL); 1584 1585 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1586 1587 ///Free all the buffers on RawCapture port 1588 if (imgRawCaptureData) { 1589 CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgRawCaptureData->mNumBufs); 1590 for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++) { 1591 CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x", ( unsigned int ) imgRawCaptureData->mBufferHeader[index]->pBuffer); 1592 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 1593 mCameraAdapterParameters.mVideoPortIndex, 1594 (OMX_BUFFERHEADERTYPE*)imgRawCaptureData->mBufferHeader[index]); 1595 1596 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1597 } 1598 } 1599 CAMHAL_LOGDA("Waiting for Video port disable"); 1600 //Wait for the image port enable event 1601 mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT); 1602 CAMHAL_LOGDA("Video Port disabled"); 1603 } 1604 #endif 1605 1606 EXIT: 1607 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1608 } 1609 1610 status_t OMXCameraAdapter::initInternalBuffers(OMX_U32 portIndex) 1611 { 1612 OMX_ERRORTYPE eError = OMX_ErrorNone; 1613 int index = 0; 1614 OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc; 1615 1616 /* Indicate to Ducati that we're planning to use dynamically-mapped buffers */ 1617 OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR); 1618 bufferdesc.nPortIndex = portIndex; 1619 bufferdesc.bEnabled = OMX_FALSE; 1620 bufferdesc.eBufferType = OMX_TI_BufferTypePhysicalPageList; 1621 1622 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1623 (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor, 1624 &bufferdesc); 1625 if (eError!=OMX_ErrorNone) { 1626 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 1627 return -EINVAL; 1628 } 1629 1630 CAMHAL_LOGDA("Initializing internal buffers"); 1631 do { 1632 OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc; 1633 OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferallocset; 1634 OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE); 1635 bufferalloc.nPortIndex = portIndex; 1636 bufferalloc.nIndex = index; 1637 1638 eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp, 1639 (OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation, 1640 &bufferalloc); 1641 if (eError == OMX_ErrorNoMore) { 1642 return NO_ERROR; 1643 } 1644 if (eError != OMX_ErrorNone) { 1645 CAMHAL_LOGE("GetParameter failed error = 0x%x", eError); 1646 break; 1647 } 1648 1649 CAMHAL_LOGDB("Requesting buftype %d of size %dx%d", 1650 (int)bufferalloc.eBufType, (int)bufferalloc.nAllocWidth, 1651 (int)bufferalloc.nAllocLines); 1652 1653 bufferalloc.eBufType = OMX_TI_BufferTypeHardwareReserved1D; 1654 1655 OMX_INIT_STRUCT_PTR (&bufferallocset, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE); 1656 bufferallocset.nPortIndex = portIndex; 1657 bufferallocset.nIndex = index; 1658 bufferallocset.eBufType = OMX_TI_BufferTypeHardwareReserved1D; 1659 bufferallocset.nAllocWidth = bufferalloc.nAllocWidth; 1660 bufferallocset.nAllocLines = bufferalloc.nAllocLines; 1661 1662 eError = OMX_SetParameter (mCameraAdapterParameters.mHandleComp, 1663 (OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation, 1664 &bufferallocset); 1665 if (eError != OMX_ErrorNone) { 1666 CAMHAL_LOGE("SetParameter failed, error=%08x", eError); 1667 if (eError == OMX_ErrorNoMore) return NO_ERROR; 1668 break; 1669 } 1670 1671 index++; 1672 1673 /* 1 is an arbitrary limit */ 1674 } while (index < 1); 1675 1676 CAMHAL_LOGV("Ducati requested too many (>1) internal buffers"); 1677 1678 return -EINVAL; 1679 } 1680 1681 status_t OMXCameraAdapter::deinitInternalBuffers(OMX_U32 portIndex) 1682 { 1683 OMX_ERRORTYPE eError = OMX_ErrorNone; 1684 OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc; 1685 1686 OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR); 1687 bufferdesc.nPortIndex = portIndex; 1688 bufferdesc.bEnabled = OMX_FALSE; 1689 bufferdesc.eBufferType = OMX_TI_BufferTypeDefault; 1690 1691 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1692 (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor, 1693 &bufferdesc); 1694 if (eError!=OMX_ErrorNone) { 1695 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 1696 return -EINVAL; 1697 } 1698 1699 OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc; 1700 OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE); 1701 bufferalloc.nPortIndex = portIndex; 1702 bufferalloc.eBufType = OMX_TI_BufferTypeDefault; 1703 bufferalloc.nAllocWidth = 1; 1704 bufferalloc.nAllocLines = 1; 1705 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1706 (OMX_INDEXTYPE) OMX_TI_IndexParamComponentBufferAllocation, 1707 &bufferalloc); 1708 if (eError!=OMX_ErrorNone) { 1709 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 1710 return -EINVAL; 1711 } 1712 1713 return Utils::ErrorUtils::omxToAndroidError(eError); 1714 } 1715 1716 status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num) 1717 { 1718 LOG_FUNCTION_NAME; 1719 1720 status_t ret = NO_ERROR; 1721 OMX_ERRORTYPE eError = OMX_ErrorNone; 1722 OMXCameraPortParameters * imgCaptureData = NULL; 1723 OMXCameraPortParameters cap; 1724 1725 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 1726 1727 if ( 0 != mUseCaptureSem.Count() ) 1728 { 1729 CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count()); 1730 return BAD_VALUE; 1731 } 1732 1733 CAMHAL_ASSERT(num > 0); 1734 1735 // if some setting that requires a SetParameter (including 1736 // changing buffer types) then we need to disable the port 1737 // before being allowed to apply the settings 1738 if ((mPendingCaptureSettings & ECaptureParamSettings) || 1739 bufArr[0].type != imgCaptureData->mBufferType || 1740 imgCaptureData->mNumBufs != num) { 1741 if (mCaptureConfigured) { 1742 disableImagePort(); 1743 if ( NULL != mReleaseImageBuffersCallback ) { 1744 mReleaseImageBuffersCallback(mReleaseData); 1745 } 1746 } 1747 1748 imgCaptureData->mBufferType = bufArr[0].type; 1749 imgCaptureData->mNumBufs = num; 1750 1751 CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth); 1752 CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mHeight); 1753 1754 if (mPendingCaptureSettings & SetFormat) { 1755 mPendingCaptureSettings &= ~SetFormat; 1756 ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData); 1757 if ( ret != NO_ERROR ) { 1758 CAMHAL_LOGEB("setFormat() failed %d", ret); 1759 LOG_FUNCTION_NAME_EXIT; 1760 return ret; 1761 } 1762 } 1763 1764 if (mPendingCaptureSettings & SetThumb) { 1765 mPendingCaptureSettings &= ~SetThumb; 1766 ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality); 1767 if ( NO_ERROR != ret) { 1768 CAMHAL_LOGEB("Error configuring thumbnail size %x", ret); 1769 return ret; 1770 } 1771 } 1772 1773 if (mPendingCaptureSettings & SetQuality) { 1774 mPendingCaptureSettings &= ~SetQuality; 1775 ret = setImageQuality(mPictureQuality); 1776 if ( NO_ERROR != ret) { 1777 CAMHAL_LOGEB("Error configuring image quality %x", ret); 1778 goto EXIT; 1779 } 1780 } 1781 1782 // Configure DOMX to use either gralloc handles or vptrs 1783 { 1784 OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles; 1785 OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER); 1786 1787 domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 1788 if (bufArr[0].type == CAMERA_BUFFER_ANW) { 1789 CAMHAL_LOGD ("Using ANW Buffers"); 1790 initInternalBuffers(mCameraAdapterParameters.mImagePortIndex); 1791 domxUseGrallocHandles.bEnable = OMX_TRUE; 1792 } else { 1793 CAMHAL_LOGD ("Using ION Buffers"); 1794 domxUseGrallocHandles.bEnable = OMX_FALSE; 1795 } 1796 1797 eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, 1798 (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles); 1799 if (eError!=OMX_ErrorNone) { 1800 CAMHAL_LOGEB("OMX_SetParameter - %x", eError); 1801 } 1802 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 1803 } 1804 1805 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS 1806 1807 CameraHal::PPM("Takepicture image port configuration: ", &bufArr->ppmStamp); 1808 1809 #endif 1810 1811 // Register for Image port ENABLE event 1812 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1813 OMX_EventCmdComplete, 1814 OMX_CommandPortEnable, 1815 mCameraAdapterParameters.mImagePortIndex, 1816 mUseCaptureSem); 1817 1818 // Enable Capture Port 1819 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1820 OMX_CommandPortEnable, 1821 mCameraAdapterParameters.mImagePortIndex, 1822 NULL); 1823 1824 CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError); 1825 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError); 1826 1827 for (int index = 0 ; index < imgCaptureData->mNumBufs ; index++) { 1828 OMX_BUFFERHEADERTYPE *pBufferHdr; 1829 CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d", 1830 (unsigned int)bufArr[index].opaque, 1831 (int)imgCaptureData->mBufSize); 1832 1833 eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp, 1834 &pBufferHdr, 1835 mCameraAdapterParameters.mImagePortIndex, 1836 0, 1837 imgCaptureData->mBufSize, 1838 (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index])); 1839 1840 CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError); 1841 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError); 1842 1843 pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index]; 1844 bufArr[index].index = index; 1845 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 1846 pBufferHdr->nVersion.s.nVersionMajor = 1 ; 1847 pBufferHdr->nVersion.s.nVersionMinor = 1 ; 1848 pBufferHdr->nVersion.s.nRevision = 0; 1849 pBufferHdr->nVersion.s.nStep = 0; 1850 imgCaptureData->mBufferHeader[index] = pBufferHdr; 1851 imgCaptureData->mStatus[index] = OMXCameraPortParameters::IDLE; 1852 } 1853 1854 // Wait for the image port enable event 1855 CAMHAL_LOGDA("Waiting for port enable"); 1856 ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT); 1857 1858 // If somethiing bad happened while we wait 1859 if (mComponentState == OMX_StateInvalid) { 1860 CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!"); 1861 goto EXIT; 1862 } 1863 1864 if (ret != NO_ERROR) { 1865 ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, 1866 OMX_EventCmdComplete, 1867 OMX_CommandPortEnable, 1868 mCameraAdapterParameters.mImagePortIndex, 1869 NULL); 1870 CAMHAL_LOGDA("Timeout expired on port enable"); 1871 goto EXIT; 1872 } 1873 CAMHAL_LOGDA("Port enabled"); 1874 1875 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS 1876 1877 CameraHal::PPM("Takepicture image port enabled and buffers registered: ", &bufArr->ppmStamp); 1878 1879 #endif 1880 1881 if (mNextState != LOADED_REPROCESS_CAPTURE_STATE) { 1882 // Enable WB and vector shot extra data for metadata 1883 setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance); 1884 setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable); 1885 } 1886 1887 // CPCam mode only supports vector shot 1888 // Regular capture is not supported 1889 if ( (mCapMode == CP_CAM) && (mNextState != LOADED_REPROCESS_CAPTURE_STATE) ) { 1890 initVectorShot(); 1891 } 1892 1893 mCaptureBuffersAvailable.clear(); 1894 for (unsigned int i = 0; i < imgCaptureData->mMaxQueueable; i++ ) { 1895 mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 0); 1896 } 1897 1898 // initial ref count for undeqeueued buffers is 1 since buffer provider 1899 // is still holding on to it 1900 for (unsigned int i = imgCaptureData->mMaxQueueable; i < imgCaptureData->mNumBufs; i++ ) { 1901 mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 1); 1902 } 1903 } 1904 1905 if ( NO_ERROR == ret ) 1906 { 1907 ret = setupEXIF(); 1908 if ( NO_ERROR != ret ) 1909 { 1910 CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret); 1911 } 1912 } 1913 1914 // Choose proper single preview mode for cp capture (reproc or hs) 1915 if (( NO_ERROR == ret) && (OMXCameraAdapter::CP_CAM == mCapMode)) { 1916 OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE singlePrevMode; 1917 OMX_INIT_STRUCT_PTR (&singlePrevMode, OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE); 1918 if (mNextState == LOADED_CAPTURE_STATE) { 1919 singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed; 1920 } else if (mNextState == LOADED_REPROCESS_CAPTURE_STATE) { 1921 singlePrevMode.eMode = OMX_TI_SinglePreviewMode_Reprocess; 1922 } else { 1923 CAMHAL_LOGE("Wrong state trying to start a capture in CPCAM mode?"); 1924 singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed; 1925 } 1926 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 1927 (OMX_INDEXTYPE) OMX_TI_IndexConfigSinglePreviewMode, 1928 &singlePrevMode); 1929 if ( OMX_ErrorNone != eError ) { 1930 CAMHAL_LOGEB("Error while configuring single preview mode 0x%x", eError); 1931 ret = Utils::ErrorUtils::omxToAndroidError(eError); 1932 } else { 1933 CAMHAL_LOGDA("single preview mode configured successfully"); 1934 } 1935 } 1936 1937 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS 1938 1939 CameraHal::PPM("Takepicture extra configs on image port done: ", &bufArr->ppmStamp); 1940 1941 #endif 1942 1943 mCaptureConfigured = true; 1944 1945 #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING 1946 if (mRawCapture) { 1947 mCaptureConfigured = false; 1948 } 1949 #endif 1950 1951 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1952 1953 EXIT: 1954 CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); 1955 setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance); 1956 // TODO: WA: if domx client disables VectShotInfo metadata on the image port, this causes 1957 // VectShotInfo to be disabled internally on preview port also. Remove setting in OMXCapture 1958 // setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_VectShotInfo); 1959 setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable); 1960 //Release image buffers 1961 if ( NULL != mReleaseImageBuffersCallback ) { 1962 mReleaseImageBuffersCallback(mReleaseData); 1963 } 1964 performCleanupAfterError(); 1965 LOG_FUNCTION_NAME_EXIT; 1966 return (ret | Utils::ErrorUtils::omxToAndroidError(eError)); 1967 1968 } 1969 status_t OMXCameraAdapter::UseBuffersRawCapture(CameraBuffer *bufArr, int num) 1970 { 1971 LOG_FUNCTION_NAME 1972 status_t ret; 1973 OMX_ERRORTYPE eError; 1974 OMXCameraPortParameters * imgRawCaptureData = NULL; 1975 Utils::Semaphore camSem; 1976 OMXCameraPortParameters cap; 1977 1978 imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; 1979 1980 if (mCaptureConfigured) { 1981 return NO_ERROR; 1982 } 1983 1984 camSem.Create(); 1985 1986 // mWaitingForSnapshot is true only when we're in the process of capturing 1987 if (mWaitingForSnapshot) { 1988 ///Register for Video port Disable event 1989 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1990 (OMX_EVENTTYPE) OMX_EventCmdComplete, 1991 OMX_CommandPortDisable, 1992 mCameraAdapterParameters.mVideoPortIndex, 1993 camSem); 1994 1995 ///Disable Capture Port 1996 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1997 OMX_CommandPortDisable, 1998 mCameraAdapterParameters.mVideoPortIndex, 1999 NULL); 2000 2001 CAMHAL_LOGDA("Waiting for port disable"); 2002 //Wait for the image port enable event 2003 camSem.Wait(); 2004 CAMHAL_LOGDA("Port disabled"); 2005 } 2006 2007 imgRawCaptureData->mNumBufs = num; 2008 2009 CAMHAL_LOGDB("RAW Max sensor width = %d", (int)imgRawCaptureData->mWidth); 2010 CAMHAL_LOGDB("RAW Max sensor height = %d", (int)imgRawCaptureData->mHeight); 2011 2012 ret = setFormat(OMX_CAMERA_PORT_VIDEO_OUT_VIDEO, *imgRawCaptureData); 2013 2014 if (ret != NO_ERROR) { 2015 CAMHAL_LOGEB("setFormat() failed %d", ret); 2016 LOG_FUNCTION_NAME_EXIT 2017 return ret; 2018 } 2019 2020 ///Register for Video port ENABLE event 2021 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 2022 (OMX_EVENTTYPE) OMX_EventCmdComplete, 2023 OMX_CommandPortEnable, 2024 mCameraAdapterParameters.mVideoPortIndex, 2025 camSem); 2026 2027 ///Enable Video Capture Port 2028 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 2029 OMX_CommandPortEnable, 2030 mCameraAdapterParameters.mVideoPortIndex, 2031 NULL); 2032 2033 mCaptureBuffersLength = (int)imgRawCaptureData->mBufSize; 2034 for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++ ) { 2035 OMX_BUFFERHEADERTYPE *pBufferHdr; 2036 CAMHAL_LOGDB("OMX_UseBuffer rawCapture address: 0x%x, size = %d ", 2037 (unsigned int)bufArr[index].opaque, 2038 (int)imgRawCaptureData->mBufSize ); 2039 2040 eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp, 2041 &pBufferHdr, 2042 mCameraAdapterParameters.mVideoPortIndex, 2043 0, 2044 mCaptureBuffersLength, 2045 (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index])); 2046 if (eError != OMX_ErrorNone) { 2047 CAMHAL_LOGEB("OMX_UseBuffer = 0x%x", eError); 2048 } 2049 2050 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError); 2051 2052 pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index]; 2053 bufArr[index].index = index; 2054 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2055 pBufferHdr->nVersion.s.nVersionMajor = 1 ; 2056 pBufferHdr->nVersion.s.nVersionMinor = 1 ; 2057 pBufferHdr->nVersion.s.nRevision = 0; 2058 pBufferHdr->nVersion.s.nStep = 0; 2059 imgRawCaptureData->mBufferHeader[index] = pBufferHdr; 2060 2061 } 2062 2063 //Wait for the image port enable event 2064 CAMHAL_LOGDA("Waiting for port enable"); 2065 camSem.Wait(); 2066 CAMHAL_LOGDA("Port enabled"); 2067 2068 if (NO_ERROR == ret) { 2069 ret = setupEXIF(); 2070 if ( NO_ERROR != ret ) { 2071 CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret); 2072 } 2073 } 2074 2075 mCapturedFrames = mBurstFrames; 2076 mBurstFramesQueued = 0; 2077 mCaptureConfigured = true; 2078 2079 EXIT: 2080 2081 if (eError != OMX_ErrorNone) { 2082 if ( NULL != mErrorNotifier ) 2083 { 2084 mErrorNotifier->errorNotify(eError); 2085 } 2086 } 2087 2088 LOG_FUNCTION_NAME_EXIT 2089 2090 return ret; 2091 } 2092 2093 } // namespace Camera 2094 } // namespace Ti 2095