1225 lines
38 KiB
C++
1225 lines
38 KiB
C++
/*
|
|
* Copyright (C) Texas Instruments - http://www.ti.com/
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @file OMXCapture.cpp
|
|
*
|
|
* This file contains functionality for handling image capture.
|
|
*
|
|
*/
|
|
|
|
#undef LOG_TAG
|
|
|
|
#define LOG_TAG "CameraHAL"
|
|
|
|
#include "CameraHal.h"
|
|
#include "OMXCameraAdapter.h"
|
|
#include "ErrorUtils.h"
|
|
|
|
|
|
namespace android {
|
|
|
|
status_t OMXCameraAdapter::setParametersCapture(const CameraParameters ¶ms,
|
|
BaseCameraAdapter::AdapterState state)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
const char *str = NULL;
|
|
int w, h;
|
|
OMX_COLOR_FORMATTYPE pixFormat;
|
|
const char *valstr = NULL;
|
|
int varint = 0;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
OMXCameraPortParameters *cap;
|
|
cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
params.getPictureSize(&w, &h);
|
|
|
|
if ( ( w != ( int ) cap->mWidth ) ||
|
|
( h != ( int ) cap->mHeight ) )
|
|
{
|
|
mPendingCaptureSettings |= SetFormat;
|
|
}
|
|
|
|
cap->mWidth = w;
|
|
cap->mHeight = h;
|
|
//TODO: Support more pixelformats
|
|
//cap->mStride = 2;
|
|
|
|
CAMHAL_LOGVB("Image: cap.mWidth = %d", (int)cap->mWidth);
|
|
CAMHAL_LOGVB("Image: cap.mHeight = %d", (int)cap->mHeight);
|
|
|
|
if ((valstr = params.getPictureFormat()) != NULL) {
|
|
if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
|
|
CAMHAL_LOGDA("CbYCrY format selected");
|
|
pixFormat = OMX_COLOR_FormatCbYCrY;
|
|
mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_YUV422I;
|
|
} else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
|
|
CAMHAL_LOGDA("YUV420SP format selected");
|
|
pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
|
|
mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_YUV420SP;
|
|
} else if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
|
|
CAMHAL_LOGDA("RGB565 format selected");
|
|
pixFormat = OMX_COLOR_Format16bitRGB565;
|
|
mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_RGB565;
|
|
} else if (strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
|
|
CAMHAL_LOGDA("JPEG format selected");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
mCodingMode = CodingNone;
|
|
mPictureFormatFromClient = CameraParameters::PIXEL_FORMAT_JPEG;
|
|
} else if (strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_JPS) == 0) {
|
|
CAMHAL_LOGDA("JPS format selected");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
mCodingMode = CodingJPS;
|
|
mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_JPS;
|
|
} else if (strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_MPO) == 0) {
|
|
CAMHAL_LOGDA("MPO format selected");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
mCodingMode = CodingMPO;
|
|
mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_MPO;
|
|
} else if (strcmp(valstr, (const char *) TICameraParameters::PIXEL_FORMAT_RAW) == 0) {
|
|
CAMHAL_LOGDA("RAW Picture format selected");
|
|
pixFormat = OMX_COLOR_FormatRawBayer10bit;
|
|
mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_RAW;
|
|
} else {
|
|
CAMHAL_LOGEA("Invalid format, JPEG format selected as default");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
mPictureFormatFromClient = NULL;
|
|
}
|
|
} else {
|
|
CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
mPictureFormatFromClient = NULL;
|
|
}
|
|
|
|
// JPEG capture is not supported in video mode by OMX Camera
|
|
// Set capture format to yuv422i...jpeg encode will
|
|
// be done on A9
|
|
valstr = params.get(TICameraParameters::KEY_CAP_MODE);
|
|
if ( (valstr && !strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE)) &&
|
|
(pixFormat == OMX_COLOR_FormatUnused) ) {
|
|
CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
|
|
pixFormat = OMX_COLOR_FormatCbYCrY;
|
|
}
|
|
|
|
if ( pixFormat != cap->mColorFormat )
|
|
{
|
|
mPendingCaptureSettings |= SetFormat;
|
|
cap->mColorFormat = pixFormat;
|
|
}
|
|
|
|
#ifdef OMAP_ENHANCEMENT
|
|
|
|
str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
|
|
if ( NULL != str ) {
|
|
parseExpRange(str, mExposureBracketingValues, EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
|
|
} else {
|
|
// if bracketing was previously set...we set again before capturing to clear
|
|
if (mExposureBracketingValidEntries) mPendingCaptureSettings |= SetExpBracket;
|
|
mExposureBracketingValidEntries = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
varint = params.getInt(CameraParameters::KEY_ROTATION);
|
|
if ( varint != -1 )
|
|
{
|
|
if ( ( unsigned int ) varint != mPictureRotation) {
|
|
mPendingCaptureSettings |= SetRotation;
|
|
}
|
|
mPictureRotation = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mPictureRotation) mPendingCaptureSettings |= SetRotation;
|
|
mPictureRotation = 0;
|
|
}
|
|
|
|
CAMHAL_LOGVB("Picture Rotation set %d", mPictureRotation);
|
|
|
|
#ifdef OMAP_ENHANCEMENT
|
|
|
|
// Read Sensor Orientation and set it based on perating mode
|
|
|
|
varint = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
|
|
if (( varint != -1 ) && (mCapMode == OMXCameraAdapter::VIDEO_MODE))
|
|
{
|
|
mSensorOrientation = varint;
|
|
if (mSensorOrientation == 270 ||mSensorOrientation==90)
|
|
{
|
|
CAMHAL_LOGEA(" Orientation is 270/90. So setting counter rotation to Ducati");
|
|
mSensorOrientation +=180;
|
|
mSensorOrientation%=360;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mSensorOrientation = 0;
|
|
}
|
|
|
|
CAMHAL_LOGVB("Sensor Orientation set : %d", mSensorOrientation);
|
|
|
|
varint = params.getInt(TICameraParameters::KEY_BURST);
|
|
if ( varint >= 1 )
|
|
{
|
|
if (varint != mBurstFrames) {
|
|
mPendingCaptureSettings |= SetExpBracket;
|
|
}
|
|
mBurstFrames = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mBurstFrames != 1) mPendingCaptureSettings |= SetExpBracket;
|
|
mBurstFrames = 1;
|
|
}
|
|
|
|
CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames);
|
|
|
|
#endif
|
|
|
|
varint = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
|
|
if ( ( varint >= MIN_JPEG_QUALITY ) &&
|
|
( varint <= MAX_JPEG_QUALITY ) )
|
|
{
|
|
if ( ( unsigned int ) varint != mPictureQuality) {
|
|
mPendingCaptureSettings |= SetQuality;
|
|
}
|
|
mPictureQuality = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mPictureQuality != MAX_JPEG_QUALITY) mPendingCaptureSettings |= SetQuality;
|
|
mPictureQuality = MAX_JPEG_QUALITY;
|
|
}
|
|
|
|
CAMHAL_LOGVB("Picture Quality set %d", mPictureQuality);
|
|
|
|
varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
|
|
if ( varint >= 0 )
|
|
{
|
|
if ( ( unsigned int ) varint != mThumbWidth) {
|
|
mPendingCaptureSettings |= SetThumb;
|
|
}
|
|
mThumbWidth = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mThumbWidth != DEFAULT_THUMB_WIDTH) mPendingCaptureSettings |= SetThumb;
|
|
mThumbWidth = DEFAULT_THUMB_WIDTH;
|
|
}
|
|
|
|
|
|
CAMHAL_LOGVB("Picture Thumb width set %d", mThumbWidth);
|
|
|
|
varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
|
|
if ( varint >= 0 )
|
|
{
|
|
if ( ( unsigned int ) varint != mThumbHeight) {
|
|
mPendingCaptureSettings |= SetThumb;
|
|
}
|
|
mThumbHeight = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mThumbHeight != DEFAULT_THUMB_HEIGHT) mPendingCaptureSettings |= SetThumb;
|
|
mThumbHeight = DEFAULT_THUMB_HEIGHT;
|
|
}
|
|
|
|
|
|
CAMHAL_LOGVB("Picture Thumb height set %d", mThumbHeight);
|
|
|
|
varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
|
|
if ( ( varint >= MIN_JPEG_QUALITY ) &&
|
|
( varint <= MAX_JPEG_QUALITY ) )
|
|
{
|
|
if ( ( unsigned int ) varint != mThumbQuality) {
|
|
mPendingCaptureSettings |= SetThumb;
|
|
}
|
|
mThumbQuality = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mThumbQuality != MAX_JPEG_QUALITY) mPendingCaptureSettings |= SetThumb;
|
|
mThumbQuality = MAX_JPEG_QUALITY;
|
|
}
|
|
|
|
CAMHAL_LOGDB("Thumbnail Quality set %d", mThumbQuality);
|
|
|
|
if (mFirstTimeInit) {
|
|
mPendingCaptureSettings = ECapturesettingsAll;
|
|
}
|
|
|
|
if (mPendingCaptureSettings) {
|
|
disableImagePort();
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMXCameraPortParameters *imgCaptureData = NULL;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
imgCaptureData->mNumBufs = bufferCount;
|
|
|
|
// check if image port is already configured...
|
|
// if it already configured then we don't have to query again
|
|
if (!mCaptureConfigured) {
|
|
ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
|
|
}
|
|
|
|
if ( ret == NO_ERROR )
|
|
{
|
|
length = imgCaptureData->mBufSize;
|
|
}
|
|
else
|
|
{
|
|
CAMHAL_LOGEB("setFormat() failed 0x%x", ret);
|
|
length = 0;
|
|
}
|
|
}
|
|
|
|
CAMHAL_LOGDB("getPictureBufferSize %d", length);
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::parseExpRange(const char *rangeStr,
|
|
int * expRange,
|
|
size_t count,
|
|
size_t &validEntries)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
char *ctx, *expVal;
|
|
char *tmp = NULL;
|
|
size_t i = 0;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if ( NULL == rangeStr )
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ( NULL == expRange )
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
tmp = ( char * ) malloc( strlen(rangeStr) + 1 );
|
|
|
|
if ( NULL == tmp )
|
|
{
|
|
CAMHAL_LOGEA("No resources for temporary buffer");
|
|
return -1;
|
|
}
|
|
memset(tmp, '\0', strlen(rangeStr) + 1);
|
|
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
strncpy(tmp, rangeStr, strlen(rangeStr) );
|
|
expVal = strtok_r( (char *) tmp, CameraHal::PARAMS_DELIMITER, &ctx);
|
|
|
|
i = 0;
|
|
while ( ( NULL != expVal ) && ( i < count ) )
|
|
{
|
|
expRange[i] = atoi(expVal);
|
|
expVal = strtok_r(NULL, CameraHal::PARAMS_DELIMITER, &ctx);
|
|
i++;
|
|
}
|
|
validEntries = i;
|
|
}
|
|
|
|
if ( NULL != tmp )
|
|
{
|
|
free(tmp);
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::setExposureBracketing(int *evValues,
|
|
size_t evCount,
|
|
size_t frameCount)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_CONFIG_CAPTUREMODETYPE expCapMode;
|
|
OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if ( OMX_StateInvalid == mComponentState )
|
|
{
|
|
CAMHAL_LOGEA("OMX component is in invalid state");
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
if ( NULL == evValues )
|
|
{
|
|
CAMHAL_LOGEA("Exposure compensation values pointer is invalid");
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
|
|
expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
|
|
/// If frameCount>0 but evCount<=0, then this is the case of HQ burst.
|
|
//Otherwise, it is normal HQ capture
|
|
///If frameCount>0 and evCount>0 then this is the cause of HQ Exposure bracketing.
|
|
if ( 0 == evCount && 0 == frameCount )
|
|
{
|
|
expCapMode.bFrameLimited = OMX_FALSE;
|
|
}
|
|
else
|
|
{
|
|
expCapMode.bFrameLimited = OMX_TRUE;
|
|
expCapMode.nFrameLimit = frameCount;
|
|
}
|
|
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
OMX_IndexConfigCaptureMode,
|
|
&expCapMode);
|
|
if ( OMX_ErrorNone != eError )
|
|
{
|
|
CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
|
|
}
|
|
else
|
|
{
|
|
CAMHAL_LOGDA("Camera capture mode configured successfully");
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
|
|
extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
|
|
if ( 0 == evCount )
|
|
{
|
|
extExpCapMode.bEnableBracketing = OMX_FALSE;
|
|
}
|
|
else
|
|
{
|
|
extExpCapMode.bEnableBracketing = OMX_TRUE;
|
|
extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketExposureRelativeInEV;
|
|
extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1;
|
|
}
|
|
|
|
for ( unsigned int i = 0 ; i < evCount ; i++ )
|
|
{
|
|
extExpCapMode.tBracketConfigType.nBracketValues[i] = ( evValues[i] * ( 1 << Q16_OFFSET ) ) / 10;
|
|
}
|
|
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
( OMX_INDEXTYPE ) OMX_IndexConfigExtCaptureMode,
|
|
&extExpCapMode);
|
|
if ( OMX_ErrorNone != eError )
|
|
{
|
|
CAMHAL_LOGEB("Error while configuring extended capture mode 0x%x", eError);
|
|
}
|
|
else
|
|
{
|
|
CAMHAL_LOGDA("Extended camera capture mode configured successfully");
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::setShutterCallback(bool enabled)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_CONFIG_CALLBACKREQUESTTYPE shutterRequstCallback;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if ( OMX_StateExecuting != mComponentState )
|
|
{
|
|
CAMHAL_LOGEA("OMX component not in executing state");
|
|
ret = -1;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
|
|
OMX_INIT_STRUCT_PTR (&shutterRequstCallback, OMX_CONFIG_CALLBACKREQUESTTYPE);
|
|
shutterRequstCallback.nPortIndex = OMX_ALL;
|
|
|
|
if ( enabled )
|
|
{
|
|
shutterRequstCallback.bEnable = OMX_TRUE;
|
|
shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
|
|
CAMHAL_LOGDA("Enabling shutter callback");
|
|
}
|
|
else
|
|
{
|
|
shutterRequstCallback.bEnable = OMX_FALSE;
|
|
shutterRequstCallback.nIndex = ( OMX_INDEXTYPE ) OMX_TI_IndexConfigShutterCallback;
|
|
CAMHAL_LOGDA("Disabling shutter callback");
|
|
}
|
|
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
( OMX_INDEXTYPE ) OMX_IndexConfigCallbackRequest,
|
|
&shutterRequstCallback);
|
|
if ( OMX_ErrorNone != eError )
|
|
{
|
|
CAMHAL_LOGEB("Error registering shutter callback 0x%x", eError);
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
CAMHAL_LOGDB("Shutter callback for index 0x%x registered successfully",
|
|
OMX_TI_IndexConfigShutterCallback);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::doBracketing(OMX_BUFFERHEADERTYPE *pBuffHeader,
|
|
CameraFrame::FrameType typeOfFrame)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
int currentBufferIdx, nextBufferIdx;
|
|
OMXCameraPortParameters * imgCaptureData = NULL;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
if ( OMX_StateExecuting != mComponentState )
|
|
{
|
|
CAMHAL_LOGEA("OMX component is not in executing state");
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
currentBufferIdx = ( unsigned int ) pBuffHeader->pAppPrivate;
|
|
|
|
if ( currentBufferIdx >= imgCaptureData->mNumBufs)
|
|
{
|
|
CAMHAL_LOGEB("Invalid bracketing buffer index 0x%x", currentBufferIdx);
|
|
ret = -EINVAL;
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
mBracketingBuffersQueued[currentBufferIdx] = false;
|
|
mBracketingBuffersQueuedCount--;
|
|
|
|
if ( 0 >= mBracketingBuffersQueuedCount )
|
|
{
|
|
nextBufferIdx = ( currentBufferIdx + 1 ) % imgCaptureData->mNumBufs;
|
|
mBracketingBuffersQueued[nextBufferIdx] = true;
|
|
mBracketingBuffersQueuedCount++;
|
|
mLastBracetingBufferIdx = nextBufferIdx;
|
|
setFrameRefCount(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame, 1);
|
|
returnFrame(imgCaptureData->mBufferHeader[nextBufferIdx]->pBuffer, typeOfFrame);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::sendBracketFrames()
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
int currentBufferIdx;
|
|
OMXCameraPortParameters * imgCaptureData = NULL;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
if ( OMX_StateExecuting != mComponentState )
|
|
{
|
|
CAMHAL_LOGEA("OMX component is not in executing state");
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
|
|
currentBufferIdx = mLastBracetingBufferIdx;
|
|
do
|
|
{
|
|
currentBufferIdx++;
|
|
currentBufferIdx %= imgCaptureData->mNumBufs;
|
|
if (!mBracketingBuffersQueued[currentBufferIdx] )
|
|
{
|
|
CameraFrame cameraFrame;
|
|
sendCallBacks(cameraFrame,
|
|
imgCaptureData->mBufferHeader[currentBufferIdx],
|
|
imgCaptureData->mImageType,
|
|
imgCaptureData);
|
|
}
|
|
} while ( currentBufferIdx != mLastBracetingBufferIdx );
|
|
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::startBracketing(int range)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMXCameraPortParameters * imgCaptureData = NULL;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
if ( OMX_StateExecuting != mComponentState )
|
|
{
|
|
CAMHAL_LOGEA("OMX component is not in executing state");
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
{
|
|
Mutex::Autolock lock(mBracketingLock);
|
|
|
|
if ( mBracketingEnabled )
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if ( 0 == imgCaptureData->mNumBufs )
|
|
{
|
|
CAMHAL_LOGEB("Image capture buffers set to %d", imgCaptureData->mNumBufs);
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
if ( mPending3Asettings )
|
|
apply3Asettings(mParameters3A);
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
Mutex::Autolock lock(mBracketingLock);
|
|
|
|
mBracketingRange = range;
|
|
mBracketingBuffersQueued = new bool[imgCaptureData->mNumBufs];
|
|
if ( NULL == mBracketingBuffersQueued )
|
|
{
|
|
CAMHAL_LOGEA("Unable to allocate bracketing management structures");
|
|
ret = -1;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
mBracketingBuffersQueuedCount = imgCaptureData->mNumBufs;
|
|
mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1;
|
|
|
|
for ( int i = 0 ; i < imgCaptureData->mNumBufs ; i++ )
|
|
{
|
|
mBracketingBuffersQueued[i] = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
|
|
ret = startImageCapture();
|
|
{
|
|
Mutex::Autolock lock(mBracketingLock);
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
mBracketingEnabled = true;
|
|
}
|
|
else
|
|
{
|
|
mBracketingEnabled = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::stopBracketing()
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
Mutex::Autolock lock(mBracketingLock);
|
|
|
|
if ( NULL != mBracketingBuffersQueued )
|
|
{
|
|
delete [] mBracketingBuffersQueued;
|
|
}
|
|
|
|
ret = stopImageCapture();
|
|
|
|
mBracketingBuffersQueued = NULL;
|
|
mBracketingEnabled = false;
|
|
mBracketingBuffersQueuedCount = 0;
|
|
mLastBracetingBufferIdx = 0;
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::startImageCapture()
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMXCameraPortParameters * capData = NULL;
|
|
OMX_CONFIG_BOOLEANTYPE bOMX;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if(!mCaptureConfigured)
|
|
{
|
|
///Image capture was cancelled before we could start
|
|
return NO_ERROR;
|
|
}
|
|
|
|
if ( 0 != mStartCaptureSem.Count() )
|
|
{
|
|
CAMHAL_LOGEB("Error mStartCaptureSem semaphore count %d", mStartCaptureSem.Count());
|
|
return NO_INIT;
|
|
}
|
|
|
|
if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) {
|
|
CAMHAL_LOGDA("trying starting capture when already canceled");
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Camera framework doesn't expect face callbacks once capture is triggered
|
|
pauseFaceDetection(true);
|
|
|
|
//During bracketing image capture is already active
|
|
{
|
|
Mutex::Autolock lock(mBracketingLock);
|
|
if ( mBracketingEnabled )
|
|
{
|
|
//Stop bracketing, activate normal burst for the remaining images
|
|
mBracketingEnabled = false;
|
|
mCapturedFrames = mBracketingRange;
|
|
ret = sendBracketFrames();
|
|
if(ret != NO_ERROR)
|
|
goto EXIT;
|
|
else
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret ) {
|
|
if (mPendingCaptureSettings & SetRotation) {
|
|
mPendingCaptureSettings &= ~SetRotation;
|
|
ret = setPictureRotation(mPictureRotation);
|
|
if ( NO_ERROR != ret ) {
|
|
CAMHAL_LOGEB("Error configuring image rotation %x", ret);
|
|
}
|
|
}
|
|
}
|
|
|
|
// need to enable wb data for video snapshot to fill in exif data
|
|
if ((ret == NO_ERROR) && (mCapMode == VIDEO_MODE)) {
|
|
// video snapshot uses wb data from snapshot frame
|
|
ret = setExtraData(true, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance);
|
|
}
|
|
|
|
//OMX shutter callback events are only available in hq mode
|
|
if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
|
|
{
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
|
|
OMX_ALL,
|
|
OMX_TI_IndexConfigShutterCallback,
|
|
mStartCaptureSem);
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
ret = setShutterCallback(true);
|
|
}
|
|
|
|
}
|
|
|
|
if ( NO_ERROR == ret ) {
|
|
capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
///Queue all the buffers on capture port
|
|
for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
|
|
CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x",
|
|
( unsigned int ) capData->mBufferHeader[index]->pBuffer);
|
|
eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
|
|
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
}
|
|
|
|
mWaitingForSnapshot = true;
|
|
mCaptureSignalled = false;
|
|
|
|
// Capturing command is not needed when capturing in video mode
|
|
// Only need to queue buffers on image ports
|
|
if (mCapMode != VIDEO_MODE) {
|
|
OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
|
|
bOMX.bEnabled = OMX_TRUE;
|
|
|
|
/// sending Capturing Command to the component
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
OMX_IndexConfigCapturing,
|
|
&bOMX);
|
|
|
|
CAMHAL_LOGDB("Capture set - 0x%x", eError);
|
|
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
}
|
|
}
|
|
|
|
//OMX shutter callback events are only available in hq mode
|
|
if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
|
|
{
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
ret = mStartCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
|
|
}
|
|
|
|
//If something bad happened while we wait
|
|
if (mComponentState != OMX_StateExecuting)
|
|
{
|
|
CAMHAL_LOGEA("Invalid State after Image Capture Exitting!!!");
|
|
goto EXIT;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
CAMHAL_LOGDA("Shutter callback received");
|
|
notifyShutterSubscribers();
|
|
}
|
|
else
|
|
{
|
|
ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
|
|
OMX_ALL,
|
|
OMX_TI_IndexConfigShutterCallback,
|
|
NULL);
|
|
CAMHAL_LOGEA("Timeout expired on shutter callback");
|
|
goto EXIT;
|
|
}
|
|
|
|
}
|
|
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
|
|
EXIT:
|
|
CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
|
|
setExtraData(false, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance);
|
|
mWaitingForSnapshot = false;
|
|
mCaptureSignalled = false;
|
|
performCleanupAfterError();
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::stopImageCapture()
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_CONFIG_BOOLEANTYPE bOMX;
|
|
OMXCameraPortParameters *imgCaptureData = NULL;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if (!mCaptureConfigured) {
|
|
//Capture is not ongoing, return from here
|
|
return NO_ERROR;
|
|
}
|
|
|
|
if ( 0 != mStopCaptureSem.Count() ) {
|
|
CAMHAL_LOGEB("Error mStopCaptureSem semaphore count %d", mStopCaptureSem.Count());
|
|
goto EXIT;
|
|
}
|
|
|
|
//Disable the callback first
|
|
mWaitingForSnapshot = false;
|
|
mSnapshotCount = 0;
|
|
|
|
// OMX shutter callback events are only available in hq mode
|
|
if ((HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) {
|
|
//Disable the callback first
|
|
ret = setShutterCallback(false);
|
|
|
|
// if anybody is waiting on the shutter callback
|
|
// signal them and then recreate the semaphore
|
|
if ( 0 != mStartCaptureSem.Count() ) {
|
|
|
|
for (int i = mStartCaptureSem.Count(); i < 0; i++) {
|
|
ret |= SignalEvent(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
|
|
OMX_ALL,
|
|
OMX_TI_IndexConfigShutterCallback,
|
|
NULL );
|
|
}
|
|
mStartCaptureSem.Create(0);
|
|
}
|
|
}
|
|
|
|
// After capture, face detection should be disabled
|
|
// and application needs to restart face detection
|
|
stopFaceDetection();
|
|
|
|
//Wait here for the capture to be done, in worst case timeout and proceed with cleanup
|
|
mCaptureSem.WaitTimeout(OMX_CAPTURE_TIMEOUT);
|
|
|
|
//If somethiing bad happened while we wait
|
|
if (mComponentState == OMX_StateInvalid)
|
|
{
|
|
CAMHAL_LOGEA("Invalid State Image Capture Stop Exitting!!!");
|
|
goto EXIT;
|
|
}
|
|
|
|
// Disable image capture
|
|
// Capturing command is not needed when capturing in video mode
|
|
if (mCapMode != VIDEO_MODE) {
|
|
OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
|
|
bOMX.bEnabled = OMX_FALSE;
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
OMX_IndexConfigCapturing,
|
|
&bOMX);
|
|
if ( OMX_ErrorNone != eError ) {
|
|
CAMHAL_LOGDB("Error during SetConfig- 0x%x", eError);
|
|
ret = -1;
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
// had to enable wb data for video snapshot to fill in exif data
|
|
// now that we are done...disable
|
|
if ((ret == NO_ERROR) && (mCapMode == VIDEO_MODE)) {
|
|
ret = setExtraData(false, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance);
|
|
}
|
|
|
|
CAMHAL_LOGDB("Capture set - 0x%x", eError);
|
|
|
|
mCaptureSignalled = true; //set this to true if we exited because of timeout
|
|
|
|
{
|
|
Mutex::Autolock lock(mFrameCountMutex);
|
|
mFrameCount = 0;
|
|
mFirstFrameCondition.broadcast();
|
|
}
|
|
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
|
|
EXIT:
|
|
CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
|
|
//Release image buffers
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
|
|
{
|
|
Mutex::Autolock lock(mFrameCountMutex);
|
|
mFrameCount = 0;
|
|
mFirstFrameCondition.broadcast();
|
|
}
|
|
|
|
performCleanupAfterError();
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::disableImagePort(){
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMXCameraPortParameters *imgCaptureData = NULL;
|
|
|
|
if (!mCaptureConfigured) {
|
|
return NO_ERROR;
|
|
}
|
|
|
|
mCaptureConfigured = false;
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
///Register for Image port Disable event
|
|
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
|
|
OMX_EventCmdComplete,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
mStopCaptureSem);
|
|
///Disable Capture Port
|
|
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
NULL);
|
|
|
|
///Free all the buffers on capture port
|
|
if (imgCaptureData) {
|
|
CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgCaptureData->mNumBufs);
|
|
for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++) {
|
|
CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x",
|
|
( unsigned int ) imgCaptureData->mBufferHeader[index]->pBuffer);
|
|
eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
(OMX_BUFFERHEADERTYPE*)imgCaptureData->mBufferHeader[index]);
|
|
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
}
|
|
}
|
|
CAMHAL_LOGDA("Waiting for port disable");
|
|
//Wait for the image port enable event
|
|
ret = mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
|
|
|
|
//If somethiing bad happened while we wait
|
|
if (mComponentState == OMX_StateInvalid)
|
|
{
|
|
CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
|
|
goto EXIT;
|
|
}
|
|
|
|
if ( NO_ERROR == ret ) {
|
|
CAMHAL_LOGDA("Port disabled");
|
|
} else {
|
|
ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
|
|
OMX_EventCmdComplete,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
NULL);
|
|
CAMHAL_LOGDA("Timeout expired on port disable");
|
|
goto EXIT;
|
|
}
|
|
|
|
EXIT:
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
|
|
status_t OMXCameraAdapter::UseBuffersCapture(void* bufArr, int num)
|
|
{
|
|
LOG_FUNCTION_NAME;
|
|
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMXCameraPortParameters * imgCaptureData = NULL;
|
|
uint32_t *buffers = (uint32_t*)bufArr;
|
|
OMXCameraPortParameters cap;
|
|
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
if ( 0 != mUseCaptureSem.Count() )
|
|
{
|
|
CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
// capture is already configured...we can skip this step
|
|
if (mCaptureConfigured) {
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
ret = setupEXIF();
|
|
if ( NO_ERROR != ret )
|
|
{
|
|
CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
|
|
}
|
|
}
|
|
|
|
mCapturedFrames = mBurstFrames;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
imgCaptureData->mNumBufs = num;
|
|
|
|
//TODO: Support more pixelformats
|
|
|
|
CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
|
|
CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mWidth);
|
|
|
|
if (mPendingCaptureSettings & SetFormat) {
|
|
mPendingCaptureSettings &= ~SetFormat;
|
|
ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
|
|
if ( ret != NO_ERROR ) {
|
|
CAMHAL_LOGEB("setFormat() failed %d", ret);
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (mPendingCaptureSettings & SetThumb) {
|
|
mPendingCaptureSettings &= ~SetThumb;
|
|
ret = setThumbnailParams(mThumbWidth, mThumbHeight, mThumbQuality);
|
|
if ( NO_ERROR != ret) {
|
|
CAMHAL_LOGEB("Error configuring thumbnail size %x", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (mPendingCaptureSettings & SetExpBracket) {
|
|
mPendingCaptureSettings &= ~SetExpBracket;
|
|
ret = setExposureBracketing( mExposureBracketingValues,
|
|
mExposureBracketingValidEntries, mBurstFrames);
|
|
if ( ret != NO_ERROR ) {
|
|
CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
if (mPendingCaptureSettings & SetQuality) {
|
|
mPendingCaptureSettings &= ~SetQuality;
|
|
ret = setImageQuality(mPictureQuality);
|
|
if ( NO_ERROR != ret) {
|
|
CAMHAL_LOGEB("Error configuring image quality %x", ret);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
///Register for Image port ENABLE event
|
|
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
|
|
OMX_EventCmdComplete,
|
|
OMX_CommandPortEnable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
mUseCaptureSem);
|
|
|
|
///Enable Capture Port
|
|
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
|
|
OMX_CommandPortEnable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
NULL);
|
|
|
|
CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
|
|
GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
|
|
|
|
for ( int index = 0 ; index < imgCaptureData->mNumBufs ; index++ )
|
|
{
|
|
OMX_BUFFERHEADERTYPE *pBufferHdr;
|
|
CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
|
|
(unsigned int)buffers[index],
|
|
(int)imgCaptureData->mBufSize);
|
|
|
|
eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
|
|
&pBufferHdr,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
0,
|
|
mCaptureBuffersLength,
|
|
(OMX_U8*)buffers[index]);
|
|
|
|
CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
|
|
GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
|
|
|
|
pBufferHdr->pAppPrivate = (OMX_PTR) index;
|
|
pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
|
|
pBufferHdr->nVersion.s.nVersionMajor = 1 ;
|
|
pBufferHdr->nVersion.s.nVersionMinor = 1 ;
|
|
pBufferHdr->nVersion.s.nRevision = 0;
|
|
pBufferHdr->nVersion.s.nStep = 0;
|
|
imgCaptureData->mBufferHeader[index] = pBufferHdr;
|
|
}
|
|
|
|
//Wait for the image port enable event
|
|
CAMHAL_LOGDA("Waiting for port enable");
|
|
ret = mUseCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
|
|
|
|
//If somethiing bad happened while we wait
|
|
if (mComponentState == OMX_StateInvalid)
|
|
{
|
|
CAMHAL_LOGEA("Invalid State after Enable Image Port Exitting!!!");
|
|
goto EXIT;
|
|
}
|
|
|
|
if ( ret == NO_ERROR )
|
|
{
|
|
CAMHAL_LOGDA("Port enabled");
|
|
}
|
|
else
|
|
{
|
|
ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
|
|
OMX_EventCmdComplete,
|
|
OMX_CommandPortEnable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
NULL);
|
|
CAMHAL_LOGDA("Timeout expired on port enable");
|
|
goto EXIT;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
ret = setupEXIF();
|
|
if ( NO_ERROR != ret )
|
|
{
|
|
CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
|
|
}
|
|
}
|
|
|
|
mCapturedFrames = mBurstFrames;
|
|
mCaptureConfigured = true;
|
|
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
|
|
EXIT:
|
|
CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
|
|
//Release image buffers
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
performCleanupAfterError();
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return (ret | ErrorUtils::omxToAndroidError(eError));
|
|
|
|
}
|
|
|
|
};
|