OMXCapture.cpp revision ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf
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#undef LOG_TAG 25 26#define LOG_TAG "CameraHAL" 27 28#include "CameraHal.h" 29#include "OMXCameraAdapter.h" 30 31namespace android { 32 33status_t OMXCameraAdapter::setParametersCapture(const CameraParameters ¶ms, 34 BaseCameraAdapter::AdapterState state) 35{ 36 status_t ret = NO_ERROR; 37 const char *str = NULL; 38 int w, h; 39 OMX_COLOR_FORMATTYPE pixFormat; 40 const char *valstr = NULL; 41 bool updateImagePortParams = false; 42 43 LOG_FUNCTION_NAME; 44 45 OMXCameraPortParameters *cap; 46 cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 47 48 params.getPictureSize(&w, &h); 49 50 if ( ( w != ( int ) cap->mWidth ) || 51 ( h != ( int ) cap->mHeight ) ) 52 { 53 updateImagePortParams = true; 54 } 55 56 cap->mWidth = w; 57 cap->mHeight = h; 58 //TODO: Support more pixelformats 59 cap->mStride = 2; 60 61 CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth); 62 CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight); 63 64 if ( (valstr = params.getPictureFormat()) != NULL ) 65 { 66 if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) 67 { 68 CAMHAL_LOGDA("CbYCrY format selected"); 69 pixFormat = OMX_COLOR_FormatCbYCrY; 70 } 71 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) 72 { 73 CAMHAL_LOGDA("YUV420SP format selected"); 74 pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; 75 } 76 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) 77 { 78 CAMHAL_LOGDA("RGB565 format selected"); 79 pixFormat = OMX_COLOR_Format16bitRGB565; 80 } 81 else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_JPEG) == 0) 82 { 83 CAMHAL_LOGDA("JPEG format selected"); 84 pixFormat = OMX_COLOR_FormatUnused; 85 mCodingMode = CodingNone; 86 } 87 else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_JPS) == 0) 88 { 89 CAMHAL_LOGDA("JPS format selected"); 90 pixFormat = OMX_COLOR_FormatUnused; 91 mCodingMode = CodingJPS; 92 } 93 else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_MPO) == 0) 94 { 95 CAMHAL_LOGDA("MPO format selected"); 96 pixFormat = OMX_COLOR_FormatUnused; 97 mCodingMode = CodingMPO; 98 } 99 else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW_JPEG) == 0) 100 { 101 CAMHAL_LOGDA("RAW + JPEG format selected"); 102 pixFormat = OMX_COLOR_FormatUnused; 103 mCodingMode = CodingRAWJPEG; 104 } 105 else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW_MPO) == 0) 106 { 107 CAMHAL_LOGDA("RAW + MPO format selected"); 108 pixFormat = OMX_COLOR_FormatUnused; 109 mCodingMode = CodingRAWMPO; 110 } 111 else if(strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW) == 0) 112 { 113 CAMHAL_LOGDA("RAW Picture format selected"); 114 pixFormat = OMX_COLOR_FormatRawBayer10bit; 115 } 116 else 117 { 118 CAMHAL_LOGEA("Invalid format, JPEG format selected as default"); 119 pixFormat = OMX_COLOR_FormatUnused; 120 } 121 } 122 else 123 { 124 CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG"); 125 pixFormat = OMX_COLOR_FormatUnused; 126 } 127 128 // JPEG capture is not supported in video mode by OMX Camera 129 // Set capture format to yuv422i...jpeg encode will 130 // be done on A9 131 valstr = params.get(TICameraParameters::KEY_CAP_MODE); 132 if ( (valstr && !strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE)) && 133 (pixFormat == OMX_COLOR_FormatUnused) ) { 134 CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i"); 135 pixFormat = OMX_COLOR_FormatCbYCrY; 136 } 137 138 if ( pixFormat != cap->mColorFormat ) 139 { 140 updateImagePortParams = true; 141 cap->mColorFormat = pixFormat; 142 } 143 144 if ( updateImagePortParams ) 145 { 146 if ( ( CAPTURE_ACTIVE & state ) != CAPTURE_ACTIVE ) 147 { 148 setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *cap); 149 } 150 } 151 152 str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE); 153 if ( NULL != str ) { 154 parseExpRange(str, mExposureBracketingValues, EXP_BRACKET_RANGE, mExposureBracketingValidEntries); 155 } else { 156 mExposureBracketingValidEntries = 0; 157 } 158 159 if ( params.getInt(CameraParameters::KEY_ROTATION) != -1 ) 160 { 161 mPictureRotation = params.getInt(CameraParameters::KEY_ROTATION); 162 } 163 else 164 { 165 mPictureRotation = 0; 166 } 167 168 CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation); 169 170 // Read Sensor Orientation and set it based on perating mode 171 172 if (( params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION) != -1 ) && (mCapMode == OMXCameraAdapter::VIDEO_MODE)) 173 { 174 mSensorOrientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION); 175 if (mSensorOrientation == 270 ||mSensorOrientation==90) 176 { 177 CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation to Ducati"); 178 mSensorOrientation +=180; 179 mSensorOrientation%=360; 180 } 181 } 182 else 183 { 184 mSensorOrientation = 0; 185 } 186 187 CAMHAL_LOGVB("Sensor Orientation set : %d", mSensorOrientation); 188 189 if ( params.getInt(TICameraParameters::KEY_BURST) >= 1 ) 190 { 191 mBurstFrames = params.getInt(TICameraParameters::KEY_BURST); 192 } 193 else 194 { 195 mBurstFrames = 1; 196 } 197 198 CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames); 199 200 if ( ( params.getInt(CameraParameters::KEY_JPEG_QUALITY) >= MIN_JPEG_QUALITY ) && 201 ( params.getInt(CameraParameters::KEY_JPEG_QUALITY) <= MAX_JPEG_QUALITY ) ) 202 { 203 mPictureQuality = params.getInt(CameraParameters::KEY_JPEG_QUALITY); 204 } 205 else 206 { 207 mPictureQuality = MAX_JPEG_QUALITY; 208 } 209 210 CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality); 211 212 if ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH) >= 0 ) 213 { 214 mThumbWidth = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); 215 } 216 else 217 { 218 mThumbWidth = DEFAULT_THUMB_WIDTH; 219 } 220 221 222 CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth); 223 224 if ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT) >= 0 ) 225 { 226 mThumbHeight = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); 227 } 228 else 229 { 230 mThumbHeight = DEFAULT_THUMB_HEIGHT; 231 } 232 233 234 CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight); 235 236 if ( ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY) >= MIN_JPEG_QUALITY ) && 237 ( params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY) <= MAX_JPEG_QUALITY ) ) 238 { 239 mThumbQuality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); 240 } 241 else 242 { 243 mThumbQuality = MAX_JPEG_QUALITY; 244 } 245 246 CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality); 247 248 LOG_FUNCTION_NAME_EXIT; 249 250 return ret; 251} 252 253status_t OMXCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount) 254{ 255 status_t ret = NO_ERROR; 256 OMXCameraPortParameters *imgCaptureData = NULL; 257 OMX_ERRORTYPE eError = OMX_ErrorNone; 258 259 LOG_FUNCTION_NAME; 260 261 if ( NO_ERROR == ret ) 262 { 263 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 264 265 imgCaptureData->mNumBufs = bufferCount; 266 ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData); 267 if ( ret == NO_ERROR ) 268 { 269 length = imgCaptureData->mBufSize; 270 } 271 else 272 { 273 CAMHAL_LOGEB("setFormat() failed 0x%x", ret); 274 length = 0; 275 } 276 } 277 278 CAMHAL_LOGDB("getPictureBufferSize %d", length); 279 280 LOG_FUNCTION_NAME_EXIT; 281 282 return ret; 283} 284 285status_t OMXCameraAdapter::parseExpRange(const char *rangeStr, 286 int * expRange, 287 size_t count, 288 size_t &validEntries) 289{ 290 status_t ret = NO_ERROR; 291 char *ctx, *expVal; 292 char *tmp = NULL; 293 size_t i = 0; 294 295 LOG_FUNCTION_NAME; 296 297 if ( NULL == rangeStr ) 298 { 299 return -EINVAL; 300 } 301 302 if ( NULL == expRange ) 303 { 304 return -EINVAL; 305 } 306 307 if ( NO_ERROR == ret ) 308 { 309 tmp = ( char * ) malloc( strlen(rangeStr) + 1 ); 310 311 if ( NULL == tmp ) 312 { 313 CAMHAL_LOGEA("No resources for temporary buffer"); 314 return -1; 315 } 316 memset(tmp, '\0', strlen(rangeStr) + 1); 317 318 } 319 320 if ( NO_ERROR == ret ) 321 { 322 strncpy(tmp, rangeStr, strlen(rangeStr) ); 323 expVal = strtok_r( (char *) tmp, CameraHal::PARAMS_DELIMITER, &ctx); 324 325 i = 0; 326 while ( ( NULL != expVal ) && ( i < count ) ) 327 { 328 expRange[i] = atoi(expVal); 329 expVal = strtok_r(NULL, CameraHal::PARAMS_DELIMITER, &ctx); 330 i++; 331 } 332 validEntries = i; 333 } 334 335 if ( NULL != tmp ) 336 { 337 free(tmp); 338 } 339 340 LOG_FUNCTION_NAME_EXIT; 341 342 return ret; 343} 344 345status_t OMXCameraAdapter::setExposureBracketing(int *evValues, 346 size_t evCount, 347 size_t frameCount) 348{ 349 status_t ret = NO_ERROR; 350 OMX_ERRORTYPE eError = OMX_ErrorNone; 351 OMX_CONFIG_CAPTUREMODETYPE expCapMode; 352 OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode; 353 354 LOG_FUNCTION_NAME; 355 356 if ( OMX_StateInvalid == mComponentState ) 357 { 358 CAMHAL_LOGEA("OMX component is in invalid state"); 359 ret = -EINVAL; 360 } 361 362 if ( NULL == evValues ) 363 { 364 CAMHAL_LOGEA("Exposure compensation values pointer is invalid"); 365 ret = -EINVAL; 366 } 367 368 if ( NO_ERROR == ret ) 369 { 370 OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE); 371 expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 372 373 /// If frameCount>0 but evCount<=0, then this is the case of HQ burst. 374 //Otherwise, it is normal HQ capture 375 ///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing. 376 if ( 0 == evCount && 0 == frameCount ) 377 { 378 expCapMode.bFrameLimited = OMX_FALSE; 379 } 380 else 381 { 382 expCapMode.bFrameLimited = OMX_TRUE; 383 expCapMode.nFrameLimit = frameCount; 384 } 385 386 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 387 OMX_IndexConfigCaptureMode, 388 &expCapMode); 389 if ( OMX_ErrorNone != eError ) 390 { 391 CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError); 392 } 393 else 394 { 395 CAMHAL_LOGDA("Camera capture mode configured successfully"); 396 } 397 } 398 399 if ( NO_ERROR == ret ) 400 { 401 OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE); 402 extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex; 403 404 if ( 0 == evCount ) 405 { 406 extExpCapMode.bEnableBracketing = OMX_FALSE; 407 } 408 else 409 { 410 extExpCapMode.bEnableBracketing = OMX_TRUE; 411 extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketExposureRelativeInEV; 412 extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1; 413 } 414 415 for ( unsigned int i = 0 ; i < evCount ; i++ ) 416 { 417 extExpCapMode.tBracketConfigType.nBracketValues[i] = ( evValues[i] * ( 1 << Q16_OFFSET ) ) / 10; 418 } 419 420 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 421 ( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode, 422 &extExpCapMode); 423 if ( OMX_ErrorNone != eError ) 424 { 425 CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError); 426 } 427 else 428 { 429 CAMHAL_LOGDA("Extended camera capture mode configured successfully"); 430 } 431 } 432 433 LOG_FUNCTION_NAME_EXIT; 434 435 return ret; 436} 437 438status_t OMXCameraAdapter::setShutterCallback(bool enabled) 439{ 440 status_t ret = NO_ERROR; 441 OMX_ERRORTYPE eError = OMX_ErrorNone; 442 OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback; 443 444 LOG_FUNCTION_NAME; 445 446 if ( OMX_StateExecuting != mComponentState ) 447 { 448 CAMHAL_LOGEA("OMX component not in executing state"); 449 ret = -1; 450 } 451 452 if ( NO_ERROR == ret ) 453 { 454 455 OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE); 456 shutterRequstCallback.nPortIndex = OMX_ALL; 457 458 if ( enabled ) 459 { 460 shutterRequstCallback.bEnable = OMX_TRUE; 461 shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback; 462 CAMHAL_LOGDA("Enabling shutter callback"); 463 } 464 else 465 { 466 shutterRequstCallback.bEnable = OMX_FALSE; 467 shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback; 468 CAMHAL_LOGDA("Disabling shutter callback"); 469 } 470 471 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 472 ( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest, 473 &shutterRequstCallback); 474 if ( OMX_ErrorNone != eError ) 475 { 476 CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError); 477 ret = -1; 478 } 479 else 480 { 481 CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully", 482 OMX_TI_IndexConfigShutterCallback); 483 } 484 } 485 486 LOG_FUNCTION_NAME_EXIT; 487 488 return ret; 489} 490 491status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader, 492 CameraFrame::FrameType typeOfFrame) 493{ 494 status_t ret = NO_ERROR; 495 int currentBufferIdx, nextBufferIdx; 496 OMXCameraPortParameters * imgCaptureData = NULL; 497 498 LOG_FUNCTION_NAME; 499 500 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 501 502 if ( OMX_StateExecuting != mComponentState ) 503 { 504 CAMHAL_LOGEA("OMX component is not in executing state"); 505 ret = -EINVAL; 506 } 507 508 if ( NO_ERROR == ret ) 509 { 510 currentBufferIdx = ( unsigned int ) pBuffHeader->pAppPrivate; 511 512 if ( currentBufferIdx >= imgCaptureData->mNumBufs) 513 { 514 CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx); 515 ret = -EINVAL; 516 } 517 } 518 519 if ( NO_ERROR == ret ) 520 { 521 mBracketingBuffersQueued[currentBufferIdx] = false; 522 mBracketingBuffersQueuedCount--; 523 524 if ( 0 >= mBracketingBuffersQueuedCount ) 525 { 526 nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs; 527 mBracketingBuffersQueued[nextBufferIdx] = true; 528 mBracketingBuffersQueuedCount++; 529 mLastBracetingBufferIdx = nextBufferIdx; 530 setFrameRefCount(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame, 1); 531 returnFrame(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame); 532 } 533 } 534 535 LOG_FUNCTION_NAME_EXIT; 536 537 return ret; 538} 539 540status_t OMXCameraAdapter::sendBracketFrames() 541{ 542 status_t ret = NO_ERROR; 543 int currentBufferIdx; 544 OMXCameraPortParameters * imgCaptureData = NULL; 545 546 LOG_FUNCTION_NAME; 547 548 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 549 550 if ( OMX_StateExecuting != mComponentState ) 551 { 552 CAMHAL_LOGEA("OMX component is not in executing state"); 553 ret = -EINVAL; 554 } 555 556 if ( NO_ERROR == ret ) 557 { 558 559 currentBufferIdx = mLastBracetingBufferIdx; 560 do 561 { 562 currentBufferIdx++; 563 currentBufferIdx %= imgCaptureData->mNumBufs; 564 if (!mBracketingBuffersQueued[currentBufferIdx] ) 565 { 566 CameraFrame cameraFrame; 567 initCameraFrame(cameraFrame, 568 imgCaptureData->mBufferHeader[currentBufferIdx], 569 imgCaptureData->mImageType, 570 imgCaptureData); 571 sendFrame(cameraFrame); 572 } 573 } while ( currentBufferIdx != mLastBracetingBufferIdx ); 574 575 } 576 577 LOG_FUNCTION_NAME_EXIT; 578 579 return ret; 580} 581 582status_t OMXCameraAdapter::startBracketing(int range) 583{ 584 status_t ret = NO_ERROR; 585 OMXCameraPortParameters * imgCaptureData = NULL; 586 587 LOG_FUNCTION_NAME; 588 589 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 590 591 if ( OMX_StateExecuting != mComponentState ) 592 { 593 CAMHAL_LOGEA("OMX component is not in executing state"); 594 ret = -EINVAL; 595 } 596 597 { 598 Mutex::Autolock lock(mBracketingLock); 599 600 if ( mBracketingEnabled ) 601 { 602 return ret; 603 } 604 } 605 606 if ( 0 == imgCaptureData->mNumBufs ) 607 { 608 CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs); 609 ret = -EINVAL; 610 } 611 612 if ( mPending3Asettings ) 613 apply3Asettings(mParameters3A); 614 615 if ( NO_ERROR == ret ) 616 { 617 Mutex::Autolock lock(mBracketingLock); 618 619 mBracketingRange = range; 620 mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs]; 621 if ( NULL == mBracketingBuffersQueued ) 622 { 623 CAMHAL_LOGEA("Unable to allocate bracketing management structures"); 624 ret = -1; 625 } 626 627 if ( NO_ERROR == ret ) 628 { 629 mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs; 630 mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1; 631 632 for ( int i = 0 ; i < imgCaptureData->mNumBufs ; i++ ) 633 { 634 mBracketingBuffersQueued[i] = true; 635 } 636 637 } 638 } 639 640 if ( NO_ERROR == ret ) 641 { 642 643 ret = startImageCapture(); 644 { 645 Mutex::Autolock lock(mBracketingLock); 646 647 if ( NO_ERROR == ret ) 648 { 649 mBracketingEnabled = true; 650 } 651 else 652 { 653 mBracketingEnabled = false; 654 } 655 } 656 } 657 658 LOG_FUNCTION_NAME_EXIT; 659 660 return ret; 661} 662 663status_t OMXCameraAdapter::stopBracketing() 664{ 665 status_t ret = NO_ERROR; 666 667 LOG_FUNCTION_NAME; 668 669 Mutex::Autolock lock(mBracketingLock); 670 671 if ( mBracketingEnabled ) 672 { 673 674 if ( NULL != mBracketingBuffersQueued ) 675 { 676 delete [] mBracketingBuffersQueued; 677 } 678 679 ret = stopImageCapture(); 680 681 mBracketingBuffersQueued = NULL; 682 mBracketingEnabled = false; 683 mBracketingBuffersQueuedCount = 0; 684 mLastBracetingBufferIdx = 0; 685 686 } 687 688 LOG_FUNCTION_NAME_EXIT; 689 690 return ret; 691} 692 693status_t OMXCameraAdapter::startImageCapture() 694{ 695 status_t ret = NO_ERROR; 696 OMX_ERRORTYPE eError = OMX_ErrorNone; 697 OMXCameraPortParameters * capData = NULL; 698 OMX_CONFIG_BOOLEANTYPE bOMX; 699 700 LOG_FUNCTION_NAME; 701 702 if(!mCaptureConfigured) 703 { 704 ///Image capture was cancelled before we could start 705 return NO_ERROR; 706 } 707 708 if ( 0 != mStartCaptureSem.Count() ) 709 { 710 CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count()); 711 return NO_INIT; 712 } 713 714 // Camera framework doesn't expect face callbacks once capture is triggered 715 pauseFaceDetection(true); 716 717 //During bracketing image capture is already active 718 { 719 Mutex::Autolock lock(mBracketingLock); 720 if ( mBracketingEnabled ) 721 { 722 //Stop bracketing, activate normal burst for the remaining images 723 mBracketingEnabled = false; 724 mCapturedFrames = mBracketingRange; 725 ret = sendBracketFrames(); 726 goto EXIT; 727 } 728 } 729 730 if ( NO_ERROR == ret ) 731 { 732 ret = setPictureRotation(mPictureRotation); 733 if ( NO_ERROR != ret ) 734 { 735 CAMHAL_LOGEB("Error configuring image rotation %x", ret); 736 } 737 } 738 739 //OMX shutter callback events are only available in hq mode 740 if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) 741 { 742 743 if ( NO_ERROR == ret ) 744 { 745 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 746 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 747 OMX_ALL, 748 OMX_TI_IndexConfigShutterCallback, 749 mStartCaptureSem); 750 } 751 752 if ( NO_ERROR == ret ) 753 { 754 ret = setShutterCallback(true); 755 } 756 757 } 758 759 if ( NO_ERROR == ret ) { 760 capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 761 762 ///Queue all the buffers on capture port 763 for ( int index = 0 ; index < capData->mNumBufs ; index++ ) { 764 CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x", 765 ( unsigned int ) capData->mBufferHeader[index]->pBuffer); 766 eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, 767 (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]); 768 769 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 770 } 771 772 mWaitingForSnapshot = true; 773 mCaptureSignalled = false; 774 775 // Capturing command is not needed when capturing in video mode 776 // Only need to queue buffers on image ports 777 if (mCapMode != VIDEO_MODE) { 778 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 779 bOMX.bEnabled = OMX_TRUE; 780 781 /// sending Capturing Command to the component 782 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 783 OMX_IndexConfigCapturing, 784 &bOMX); 785 786 CAMHAL_LOGDB("Capture set - 0x%x", eError); 787 788 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 789 } 790 } 791 792 //OMX shutter callback events are only available in hq mode 793 if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) 794 { 795 796 if ( NO_ERROR == ret ) 797 { 798 ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT); 799 } 800 801 if ( NO_ERROR == ret ) 802 { 803 CAMHAL_LOGDA("Shutter callback received"); 804 notifyShutterSubscribers(); 805 } 806 else 807 { 808 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 809 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 810 OMX_ALL, 811 OMX_TI_IndexConfigShutterCallback, 812 NULL); 813 CAMHAL_LOGEA("Timeout expired on shutter callback"); 814 goto EXIT; 815 } 816 817 } 818 819 EXIT: 820 821 if ( eError != OMX_ErrorNone ) 822 { 823 824 mWaitingForSnapshot = false; 825 mCaptureSignalled = false; 826 827 } 828 829 LOG_FUNCTION_NAME_EXIT; 830 831 return ret; 832} 833 834status_t OMXCameraAdapter::stopImageCapture() 835{ 836 status_t ret = NO_ERROR; 837 OMX_ERRORTYPE eError; 838 OMX_CONFIG_BOOLEANTYPE bOMX; 839 OMXCameraPortParameters *imgCaptureData = NULL; 840 841 LOG_FUNCTION_NAME; 842 843 if (!mCaptureConfigured) { 844 //Capture is not ongoing, return from here 845 return NO_ERROR; 846 } 847 848 if ( 0 != mStopCaptureSem.Count() ) { 849 CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count()); 850 goto EXIT; 851 } 852 853 //Disable the callback first 854 mWaitingForSnapshot = false; 855 mSnapshotCount = 0; 856 857 //Disable the callback first 858 ret = setShutterCallback(false); 859 860 //release any 3A locks if locked 861 ret = set3ALock(OMX_FALSE); 862 if(ret!=NO_ERROR) 863 { 864 CAMHAL_LOGEB("Error Releaseing 3A locks%d", ret); 865 } 866 867 // After capture, face detection should be disabled 868 // and application needs to restart face detection 869 stopFaceDetection(); 870 871 //Wait here for the capture to be done, in worst case timeout and proceed with cleanup 872 ret = mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT); 873 if ( NO_ERROR != ret ) { 874 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 875 (OMX_EVENTTYPE) OMX_EventIndexSettingChanged, 876 OMX_ALL, 877 OMX_TI_IndexConfigShutterCallback, 878 NULL); 879 CAMHAL_LOGEA("Timeout expired on shutter callback"); 880 } 881 882 //Disable image capture 883 OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); 884 bOMX.bEnabled = OMX_FALSE; 885 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 886 eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, 887 OMX_IndexConfigCapturing, 888 &bOMX); 889 if ( OMX_ErrorNone != eError ) { 890 CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError); 891 ret = -1; 892 } 893 894 CAMHAL_LOGDB("Capture set - 0x%x", eError); 895 896 mCaptureSignalled = true; //set this to true if we exited because of timeout 897 898 mCaptureConfigured = false; 899 900 ///Register for Image port Disable event 901 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 902 OMX_EventCmdComplete, 903 OMX_CommandPortDisable, 904 mCameraAdapterParameters.mImagePortIndex, 905 mStopCaptureSem); 906 ///Disable Capture Port 907 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 908 OMX_CommandPortDisable, 909 mCameraAdapterParameters.mImagePortIndex, 910 NULL); 911 912 ///Free all the buffers on capture port 913 if (imgCaptureData) { 914 CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs); 915 for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) { 916 CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x", 917 ( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer); 918 eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, 919 mCameraAdapterParameters.mImagePortIndex, 920 (OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]); 921 922 GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); 923 } 924 } 925 CAMHAL_LOGDA("Waiting for port disable"); 926 //Wait for the image port enable event 927 ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT); 928 if ( NO_ERROR == ret ) { 929 CAMHAL_LOGDA("Port disabled"); 930 } else { 931 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 932 OMX_EventCmdComplete, 933 OMX_CommandPortDisable, 934 mCameraAdapterParameters.mImagePortIndex, 935 NULL); 936 CAMHAL_LOGDA("Timeout expired on port disable"); 937 goto EXIT; 938 } 939 940 EXIT: 941 942 //Release image buffers 943 if ( NULL != mReleaseImageBuffersCallback ) { 944 mReleaseImageBuffersCallback(mReleaseData); 945 } 946 947 LOG_FUNCTION_NAME_EXIT; 948 949 return ret; 950} 951 952status_t OMXCameraAdapter::UseBuffersCapture(void* bufArr, int num) 953{ 954 LOG_FUNCTION_NAME; 955 956 status_t ret = NO_ERROR; 957 OMX_ERRORTYPE eError; 958 OMXCameraPortParameters * imgCaptureData = NULL; 959 uint32_t *buffers = (uint32_t*)bufArr; 960 OMXCameraPortParameters cap; 961 962 imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; 963 964 if ( 0 != mUseCaptureSem.Count() ) 965 { 966 CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count()); 967 goto EXIT; 968 } 969 970 imgCaptureData->mNumBufs = num; 971 972 //TODO: Support more pixelformats 973 974 CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth); 975 CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mWidth); 976 977 ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData); 978 if ( ret != NO_ERROR ) 979 { 980 CAMHAL_LOGEB("setFormat() failed %d", ret); 981 LOG_FUNCTION_NAME_EXIT; 982 return ret; 983 } 984 985 ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality); 986 if ( NO_ERROR != ret) 987 { 988 CAMHAL_LOGEB("Error configuring thumbnail size %x", ret); 989 return ret; 990 } 991 992 ret = setExposureBracketing( mExposureBracketingValues, 993 mExposureBracketingValidEntries, mBurstFrames); 994 if ( ret != NO_ERROR ) 995 { 996 CAMHAL_LOGEB("setExposureBracketing() failed %d", ret); 997 return ret; 998 } 999 1000 ret = setImageQuality(mPictureQuality); 1001 if ( NO_ERROR != ret) 1002 { 1003 CAMHAL_LOGEB("Error configuring image quality %x", ret); 1004 return ret; 1005 } 1006 1007 ///Register for Image port ENABLE event 1008 ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, 1009 OMX_EventCmdComplete, 1010 OMX_CommandPortEnable, 1011 mCameraAdapterParameters.mImagePortIndex, 1012 mUseCaptureSem); 1013 1014 ///Enable Capture Port 1015 eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, 1016 OMX_CommandPortEnable, 1017 mCameraAdapterParameters.mImagePortIndex, 1018 NULL); 1019 1020 for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++ ) 1021 { 1022 OMX_BUFFERHEADERTYPE *pBufferHdr; 1023 CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d", 1024 (unsigned int)buffers[index], 1025 (int)imgCaptureData->mBufSize); 1026 1027 eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp, 1028 &pBufferHdr, 1029 mCameraAdapterParameters.mImagePortIndex, 1030 0, 1031 mCaptureBuffersLength, 1032 (OMX_U8*)buffers[index]); 1033 1034 CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError); 1035 1036 GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError); 1037 1038 pBufferHdr->pAppPrivate = (OMX_PTR) index; 1039 pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 1040 pBufferHdr->nVersion.s.nVersionMajor = 1 ; 1041 pBufferHdr->nVersion.s.nVersionMinor = 1 ; 1042 pBufferHdr->nVersion.s.nRevision = 0; 1043 pBufferHdr->nVersion.s.nStep = 0; 1044 imgCaptureData->mBufferHeader[index] = pBufferHdr; 1045 } 1046 1047 //Wait for the image port enable event 1048 CAMHAL_LOGDA("Waiting for port enable"); 1049 ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT); 1050 if ( ret == NO_ERROR ) 1051 { 1052 CAMHAL_LOGDA("Port enabled"); 1053 } 1054 else 1055 { 1056 ret |= SignalEvent(mCameraAdapterParameters.mHandleComp, 1057 OMX_EventCmdComplete, 1058 OMX_CommandPortEnable, 1059 mCameraAdapterParameters.mImagePortIndex, 1060 NULL); 1061 CAMHAL_LOGDA("Timeout expired on port enable"); 1062 goto EXIT; 1063 } 1064 1065 if ( NO_ERROR == ret ) 1066 { 1067 ret = setupEXIF(); 1068 if ( NO_ERROR != ret ) 1069 { 1070 CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret); 1071 } 1072 } 1073 1074 mCapturedFrames = mBurstFrames; 1075 mCaptureConfigured = true; 1076 1077 EXIT: 1078 1079 LOG_FUNCTION_NAME_EXIT; 1080 1081 return ret; 1082} 1083 1084}; 1085