2094 lines
76 KiB
C++
2094 lines
76 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.
|
|
*
|
|
*/
|
|
|
|
#include "CameraHal.h"
|
|
#include "OMXCameraAdapter.h"
|
|
#include "ErrorUtils.h"
|
|
|
|
|
|
namespace Ti {
|
|
namespace Camera {
|
|
|
|
status_t OMXCameraAdapter::setParametersCapture(const android::CameraParameters ¶ms,
|
|
BaseCameraAdapter::AdapterState state)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
const char *str = NULL;
|
|
int w, h;
|
|
OMX_COLOR_FORMATTYPE pixFormat;
|
|
CodingMode codingMode = mCodingMode;
|
|
const char *valstr = NULL;
|
|
int varint = 0;
|
|
OMX_TI_STEREOFRAMELAYOUTTYPE capFrmLayout;
|
|
bool inCaptureState = false;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
OMXCameraPortParameters *cap;
|
|
cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
capFrmLayout = cap->mFrameLayoutType;
|
|
setParamS3D(mCameraAdapterParameters.mImagePortIndex,
|
|
params.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT));
|
|
if (capFrmLayout != cap->mFrameLayoutType) {
|
|
mPendingCaptureSettings |= SetFormat;
|
|
}
|
|
|
|
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, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
|
|
CAMHAL_LOGDA("CbYCrY format selected");
|
|
pixFormat = OMX_COLOR_FormatCbYCrY;
|
|
mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV422I;
|
|
} else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
|
|
CAMHAL_LOGDA("YUV420SP format selected");
|
|
pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
|
|
mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_YUV420SP;
|
|
} else if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) {
|
|
CAMHAL_LOGDA("RGB565 format selected");
|
|
pixFormat = OMX_COLOR_Format16bitRGB565;
|
|
mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_RGB565;
|
|
} else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
|
|
CAMHAL_LOGDA("JPEG format selected");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
codingMode = CodingJPEG;
|
|
mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_JPEG;
|
|
} else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_JPS) == 0) {
|
|
CAMHAL_LOGDA("JPS format selected");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
codingMode = CodingJPS;
|
|
mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_JPS;
|
|
} else if (strcmp(valstr, TICameraParameters::PIXEL_FORMAT_MPO) == 0) {
|
|
CAMHAL_LOGDA("MPO format selected");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
codingMode = CodingMPO;
|
|
mPictureFormatFromClient = TICameraParameters::PIXEL_FORMAT_MPO;
|
|
} else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) {
|
|
CAMHAL_LOGDA("RAW Picture format selected");
|
|
pixFormat = OMX_COLOR_FormatRawBayer10bit;
|
|
mPictureFormatFromClient = android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
|
|
} else {
|
|
CAMHAL_LOGEA("Invalid format, JPEG format selected as default");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
codingMode = CodingJPEG;
|
|
mPictureFormatFromClient = NULL;
|
|
}
|
|
} else {
|
|
CAMHAL_LOGEA("Picture format is NULL, defaulting to JPEG");
|
|
pixFormat = OMX_COLOR_FormatUnused;
|
|
codingMode = CodingJPEG;
|
|
mPictureFormatFromClient = NULL;
|
|
}
|
|
|
|
#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
|
|
mRawCapture = false;
|
|
mYuvCapture = false;
|
|
|
|
valstr = params.get(TICameraParameters::KEY_CAP_MODE);
|
|
if ( (!valstr || strcmp(valstr, TICameraParameters::HIGH_QUALITY_MODE) == 0) &&
|
|
access(kRawImagesOutputDirPath, F_OK) != -1 ) {
|
|
mRawCapture = true;
|
|
}
|
|
|
|
if (mRawCapture && (access(kYuvImagesOutputDirPath, F_OK) != -1)) {
|
|
pixFormat = OMX_COLOR_FormatCbYCrY;
|
|
mYuvCapture = true;
|
|
}
|
|
#endif
|
|
// 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) == 0 ||
|
|
strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE_HQ) == 0 ) ) &&
|
|
(pixFormat == OMX_COLOR_FormatUnused) ) {
|
|
CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
|
|
pixFormat = OMX_COLOR_FormatCbYCrY;
|
|
}
|
|
|
|
if (pixFormat != cap->mColorFormat || codingMode != mCodingMode) {
|
|
mPendingCaptureSettings |= SetFormat;
|
|
cap->mColorFormat = pixFormat;
|
|
mCodingMode = codingMode;
|
|
}
|
|
|
|
#ifdef OMAP_ENHANCEMENT
|
|
str = params.get(TICameraParameters::KEY_TEMP_BRACKETING);
|
|
if ( ( str != NULL ) &&
|
|
( strcmp(str, android::CameraParameters::TRUE) == 0 ) ) {
|
|
|
|
if ( !mBracketingSet ) {
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
}
|
|
|
|
mBracketingSet = true;
|
|
} else {
|
|
|
|
if ( mBracketingSet ) {
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
}
|
|
|
|
mBracketingSet = false;
|
|
}
|
|
|
|
if ( (str = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL ) {
|
|
parseExpRange(str, mExposureBracketingValues, NULL,
|
|
mExposureGainBracketingModes,
|
|
EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
|
|
if (mCapMode == OMXCameraAdapter::CP_CAM) {
|
|
mExposureBracketMode = OMX_BracketVectorShot;
|
|
} else {
|
|
mExposureBracketMode = OMX_BracketExposureRelativeInEV;
|
|
}
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
} else if ( (str = params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE)) != NULL) {
|
|
parseExpRange(str, mExposureBracketingValues, mExposureGainBracketingValues,
|
|
mExposureGainBracketingModes,
|
|
EXP_BRACKET_RANGE, mExposureBracketingValidEntries);
|
|
if (mCapMode == OMXCameraAdapter::CP_CAM) {
|
|
mExposureBracketMode = OMX_BracketVectorShot;
|
|
} else {
|
|
mExposureBracketMode = OMX_BracketExposureGainAbsolute;
|
|
}
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
} else {
|
|
// always set queued shot config in CPCAM mode
|
|
if (mCapMode == OMXCameraAdapter::CP_CAM) {
|
|
mExposureBracketMode = OMX_BracketVectorShot;
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
}
|
|
// if bracketing was previously set...we set again before capturing to clear
|
|
if (mExposureBracketingValidEntries) {
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
mExposureBracketingValidEntries = 0;
|
|
}
|
|
}
|
|
|
|
str = params.get(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE);
|
|
if ( NULL != str ) {
|
|
parseExpRange(str, mZoomBracketingValues, NULL, NULL,
|
|
ZOOM_BRACKET_RANGE, mZoomBracketingValidEntries);
|
|
mCurrentZoomBracketing = 0;
|
|
mZoomBracketingEnabled = true;
|
|
} else {
|
|
if (mZoomBracketingValidEntries) {
|
|
mZoomBracketingValidEntries = 0;
|
|
}
|
|
mZoomBracketingEnabled = false;
|
|
}
|
|
#endif
|
|
|
|
// Flush config queue
|
|
// If TRUE: Flush queue and abort processing before enqueing
|
|
valstr = params.get(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE);
|
|
if ( NULL != valstr ) {
|
|
if ( 0 == strcmp(valstr, android::CameraParameters::TRUE) ) {
|
|
mFlushShotConfigQueue = true;
|
|
} else if ( 0 == strcmp(valstr, android::CameraParameters::FALSE) ) {
|
|
mFlushShotConfigQueue = false;
|
|
} else {
|
|
CAMHAL_LOGE("Missing flush shot config parameter. Will use current (%s)",
|
|
mFlushShotConfigQueue ? "true" : "false");
|
|
}
|
|
}
|
|
|
|
if ( params.getInt(android::CameraParameters::KEY_ROTATION) != -1 )
|
|
{
|
|
if (params.getInt(android::CameraParameters::KEY_ROTATION) != (int) mPictureRotation) {
|
|
mPendingCaptureSettings |= SetRotation;
|
|
}
|
|
mPictureRotation = params.getInt(android::CameraParameters::KEY_ROTATION);
|
|
}
|
|
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 )
|
|
{
|
|
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);
|
|
#endif
|
|
|
|
#ifdef OMAP_ENHANCEMENT_BURST_CAPTURE
|
|
varint = params.getInt(TICameraParameters::KEY_BURST);
|
|
if ( varint >= 1 )
|
|
{
|
|
if (varint != (int) mBurstFrames) {
|
|
mPendingCaptureSettings |= SetBurstExpBracket;
|
|
}
|
|
mBurstFrames = varint;
|
|
}
|
|
else
|
|
{
|
|
if (mBurstFrames != 1) mPendingCaptureSettings |= SetBurstExpBracket;
|
|
mBurstFrames = 1;
|
|
}
|
|
|
|
CAMHAL_LOGVB("Burst Frames set %d", mBurstFrames);
|
|
#endif
|
|
|
|
varint = params.getInt(android::CameraParameters::KEY_JPEG_QUALITY);
|
|
if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) {
|
|
if (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(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
|
|
if ( varint >= 0 ) {
|
|
if (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(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
|
|
if ( varint >= 0 ) {
|
|
if (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(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
|
|
if ( varint >= MIN_JPEG_QUALITY && varint <= MAX_JPEG_QUALITY ) {
|
|
if (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;
|
|
}
|
|
|
|
cap = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
|
|
cap->mWidth = params.getInt(TICameraParameters::RAW_WIDTH);
|
|
cap->mHeight = params.getInt(TICameraParameters::RAW_HEIGHT);
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::getPictureBufferSize(CameraFrame &frame, 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];
|
|
|
|
|
|
// If any settings have changed that need to be set with SetParam,
|
|
// we will need to disable the port to set them
|
|
if ((mPendingCaptureSettings & ECaptureParamSettings)) {
|
|
disableImagePort();
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
}
|
|
|
|
if (mPendingCaptureSettings & SetFormat) {
|
|
ret = setFormat(OMX_CAMERA_PORT_IMAGE_OUT_IMAGE, *imgCaptureData);
|
|
}
|
|
|
|
if ( ret == NO_ERROR )
|
|
{
|
|
frame.mLength = imgCaptureData->mBufSize;
|
|
frame.mWidth = imgCaptureData->mWidth;
|
|
frame.mHeight = imgCaptureData->mHeight;
|
|
frame.mAlignment = imgCaptureData->mStride;
|
|
CAMHAL_LOGDB("getPictureBufferSize: width:%u height:%u alignment:%u length:%u",
|
|
frame.mWidth, frame.mHeight, frame.mAlignment, frame.mLength);
|
|
}
|
|
else
|
|
{
|
|
CAMHAL_LOGEB("setFormat() failed 0x%x", ret);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int OMXCameraAdapter::getBracketingValueMode(const char *a, const char *b) const
|
|
{
|
|
BracketingValueMode bvm = BracketingValueAbsolute;
|
|
|
|
if ( (NULL != b) &&
|
|
(NULL != a) &&
|
|
(a < b) &&
|
|
( (NULL != memchr(a, '+', b - a)) ||
|
|
(NULL != memchr(a, '-', b - a)) ) ) {
|
|
bvm = BracketingValueRelative;
|
|
}
|
|
return bvm;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::parseExpRange(const char *rangeStr,
|
|
int *expRange,
|
|
int *gainRange,
|
|
int *expGainModes,
|
|
size_t count,
|
|
size_t &validEntries)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
char *end = NULL;
|
|
const char *startPtr = NULL;
|
|
size_t i = 0;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if ( NULL == rangeStr ){
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ( NULL == expRange ){
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ( NO_ERROR == ret ) {
|
|
startPtr = rangeStr;
|
|
do {
|
|
// Relative Exposure example: "-30,-10, 0, 10, 30"
|
|
// Absolute Gain ex. (exposure,gain) pairs: "(100,300),(200,300),(400,300),(800,300),(1600,300)"
|
|
// Relative Gain ex. (exposure,gain) pairs: "(-30,+0),(-10, +0),(+0,+0),(+10,+0),(+30,+0)"
|
|
// Forced relative Exposure example: "-30F,-10F, 0F, 10F, 30F"
|
|
// Forced absolute Gain ex. (exposure,gain) pairs: "(100,300)F,(200,300)F,(400,300)F,(800,300)F,(1600,300)F"
|
|
// Forced relative Gain ex. (exposure,gain) pairs: "(-30,+0)F,(-10, +0)F,(+0,+0)F,(+10,+0)F,(+30,+0)F"
|
|
|
|
// skip '(' and ','
|
|
while ((*startPtr == '(') || (*startPtr == ',')) startPtr++;
|
|
|
|
expRange[i] = (int)strtol(startPtr, &end, 10);
|
|
|
|
if (expGainModes) {
|
|
// if gainRange is given rangeStr should be (exposure, gain) pair
|
|
if (gainRange) {
|
|
int bvm_exp = getBracketingValueMode(startPtr, end);
|
|
startPtr = end + 1; // for the ','
|
|
gainRange[i] = (int)strtol(startPtr, &end, 10);
|
|
|
|
if (BracketingValueAbsolute == bvm_exp) {
|
|
expGainModes[i] = getBracketingValueMode(startPtr, end);
|
|
} else {
|
|
expGainModes[i] = bvm_exp;
|
|
}
|
|
} else {
|
|
expGainModes[i] = BracketingValueCompensation;
|
|
}
|
|
}
|
|
startPtr = end;
|
|
|
|
// skip ')'
|
|
while (*startPtr == ')') startPtr++;
|
|
|
|
// Check for "forced" key
|
|
if (expGainModes) {
|
|
while ((*startPtr == 'F') || (*startPtr == 'f')) {
|
|
if ( BracketingValueAbsolute == expGainModes[i] ) {
|
|
expGainModes[i] = BracketingValueAbsoluteForced;
|
|
} else if ( BracketingValueRelative == expGainModes[i] ) {
|
|
expGainModes[i] = BracketingValueRelativeForced;
|
|
} else if ( BracketingValueCompensation == expGainModes[i] ) {
|
|
expGainModes[i] = BracketingValueCompensationForced;
|
|
} else {
|
|
CAMHAL_LOGE("Unexpected old mode 0x%x", expGainModes[i]);
|
|
}
|
|
startPtr++;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
|
|
} while ((startPtr[0] != '\0') && (i < count));
|
|
validEntries = i;
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::doExposureBracketing(int *evValues,
|
|
int *evValues2,
|
|
int *evModes2,
|
|
size_t evCount,
|
|
size_t frameCount,
|
|
bool flush,
|
|
OMX_BRACKETMODETYPE bracketMode)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
|
|
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 ) {
|
|
if (bracketMode == OMX_BracketVectorShot) {
|
|
ret = setVectorShot(evValues, evValues2, evModes2, evCount, frameCount, flush, bracketMode);
|
|
} else {
|
|
ret = setExposureBracketing(evValues, evValues2, evCount, frameCount, bracketMode);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::setVectorStop(bool toPreview)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE vecShotStop;
|
|
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
OMX_INIT_STRUCT_PTR(&vecShotStop, OMX_TI_CONFIG_VECTSHOTSTOPMETHODTYPE);
|
|
|
|
vecShotStop.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
if (toPreview) {
|
|
vecShotStop.eStopMethod = OMX_TI_VECTSHOTSTOPMETHOD_GOTO_PREVIEW;
|
|
} else {
|
|
vecShotStop.eStopMethod = OMX_TI_VECTSHOTSTOPMETHOD_WAIT_IN_CAPTURE;
|
|
}
|
|
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE) OMX_TI_IndexConfigVectShotStopMethod,
|
|
&vecShotStop);
|
|
if (OMX_ErrorNone != eError) {
|
|
CAMHAL_LOGEB("Error while configuring bracket shot 0x%x", eError);
|
|
} else {
|
|
CAMHAL_LOGDA("Bracket shot configured successfully");
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::initVectorShot()
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_CONFIG_CAPTUREMODETYPE expCapMode;
|
|
OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
if (NO_ERROR == ret) {
|
|
OMX_INIT_STRUCT_PTR (&expCapMode, OMX_CONFIG_CAPTUREMODETYPE);
|
|
expCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
|
|
expCapMode.bFrameLimited = OMX_FALSE;
|
|
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
OMX_IndexConfigCaptureMode,
|
|
&expCapMode);
|
|
if (OMX_ErrorNone != eError) {
|
|
CAMHAL_LOGEB("Error while configuring capture mode 0x%x", eError);
|
|
goto exit;
|
|
} else {
|
|
CAMHAL_LOGDA("Camera capture mode configured successfully");
|
|
}
|
|
}
|
|
|
|
if (NO_ERROR == ret) {
|
|
OMX_INIT_STRUCT_PTR (&extExpCapMode, OMX_CONFIG_EXTCAPTUREMODETYPE);
|
|
extExpCapMode.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
|
|
extExpCapMode.bEnableBracketing = OMX_TRUE;
|
|
extExpCapMode.tBracketConfigType.eBracketMode = OMX_BracketVectorShot;
|
|
|
|
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);
|
|
goto exit;
|
|
} else {
|
|
CAMHAL_LOGDA("Extended camera capture mode configured successfully");
|
|
}
|
|
}
|
|
|
|
|
|
if (NO_ERROR == ret) {
|
|
// set vector stop method to stop in capture
|
|
ret = setVectorStop(false);
|
|
}
|
|
|
|
exit:
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::setVectorShot(int *evValues,
|
|
int *evValues2,
|
|
int *evModes2,
|
|
size_t evCount,
|
|
size_t frameCount,
|
|
bool flush,
|
|
OMX_BRACKETMODETYPE bracketMode)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_TI_CONFIG_ENQUEUESHOTCONFIGS enqueueShotConfigs;
|
|
OMX_TI_CONFIG_QUERYAVAILABLESHOTS queryAvailableShots;
|
|
bool doFlush = flush;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
OMX_INIT_STRUCT_PTR(&enqueueShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS);
|
|
OMX_INIT_STRUCT_PTR(&queryAvailableShots, OMX_TI_CONFIG_QUERYAVAILABLESHOTS);
|
|
|
|
queryAvailableShots.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE) OMX_TI_IndexConfigQueryAvailableShots,
|
|
&queryAvailableShots);
|
|
if (OMX_ErrorNone != eError) {
|
|
CAMHAL_LOGE("Error getting available shots 0x%x", eError);
|
|
goto exit;
|
|
} else {
|
|
CAMHAL_LOGD("AVAILABLE SHOTS: %d", queryAvailableShots.nAvailableShots);
|
|
if (queryAvailableShots.nAvailableShots < evCount) {
|
|
// TODO(XXX): Need to implement some logic to handle this error
|
|
CAMHAL_LOGE("Not enough available shots to fulfill this queue request");
|
|
ret = -ENOSPC;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
for ( unsigned int confID = 0; confID < evCount; ) {
|
|
unsigned int i;
|
|
for ( i = 0 ; (i < ARRAY_SIZE(enqueueShotConfigs.nShotConfig)) && (confID < evCount); i++, confID++ ) {
|
|
CAMHAL_LOGD("%2u: (%7d,%4d) mode: %d", confID, evValues[confID], evValues2[confID], evModes2[confID]);
|
|
enqueueShotConfigs.nShotConfig[i].nConfigId = confID;
|
|
enqueueShotConfigs.nShotConfig[i].nFrames = 1;
|
|
if ( (BracketingValueCompensation == evModes2[confID]) ||
|
|
(BracketingValueCompensationForced == evModes2[confID]) ) {
|
|
// EV compensation
|
|
enqueueShotConfigs.nShotConfig[i].nEC = evValues[confID];
|
|
enqueueShotConfigs.nShotConfig[i].nExp = 0;
|
|
enqueueShotConfigs.nShotConfig[i].nGain = 0;
|
|
} else {
|
|
// exposure,gain pair
|
|
enqueueShotConfigs.nShotConfig[i].nEC = 0;
|
|
enqueueShotConfigs.nShotConfig[i].nExp = evValues[confID];
|
|
enqueueShotConfigs.nShotConfig[i].nGain = evValues2[confID];
|
|
}
|
|
enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE;
|
|
switch (evModes2[confID]) {
|
|
case BracketingValueAbsolute: // (exp,gain) pairs directly program sensor values
|
|
default :
|
|
enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_ABSOLUTE;
|
|
break;
|
|
case BracketingValueRelative: // (exp,gain) pairs relative to AE settings and constraints
|
|
case BracketingValueCompensation: // EV compensation relative to AE settings and constraints
|
|
enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE;
|
|
break;
|
|
case BracketingValueAbsoluteForced: // (exp,gain) pairs directly program sensor values
|
|
// are forced over constraints due to flicker, etc.
|
|
enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_ABSOLUTE;
|
|
break;
|
|
case BracketingValueRelativeForced: // (exp, gain) pairs relative to AE settings AND settings
|
|
case BracketingValueCompensationForced: // EV compensation relative to AE settings and constraints
|
|
// are forced over constraints due to flicker, etc.
|
|
enqueueShotConfigs.nShotConfig[i].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_FORCE_RELATIVE;
|
|
break;
|
|
}
|
|
enqueueShotConfigs.nShotConfig[i].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable
|
|
}
|
|
|
|
// Repeat last exposure and again
|
|
if ((confID == evCount) && (evCount > 0) && (frameCount > evCount) && (0 != i)) {
|
|
enqueueShotConfigs.nShotConfig[i-1].nFrames = frameCount - evCount;
|
|
}
|
|
|
|
enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE;
|
|
enqueueShotConfigs.nNumConfigs = i;
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
|
|
&enqueueShotConfigs);
|
|
if ( OMX_ErrorNone != eError ) {
|
|
CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError);
|
|
goto exit;
|
|
} else {
|
|
CAMHAL_LOGDA("Enqueue shot configured successfully");
|
|
}
|
|
// Flush only first time
|
|
doFlush = false;
|
|
}
|
|
|
|
// Handle burst capture (no any bracketing) case
|
|
if (0 == evCount) {
|
|
CAMHAL_LOGE("Handle burst capture (no any bracketing) case");
|
|
enqueueShotConfigs.nShotConfig[0].nConfigId = 0;
|
|
enqueueShotConfigs.nShotConfig[0].nFrames = frameCount;
|
|
enqueueShotConfigs.nShotConfig[0].nEC = 0;
|
|
enqueueShotConfigs.nShotConfig[0].nExp = 0;
|
|
enqueueShotConfigs.nShotConfig[0].nGain = 0;
|
|
enqueueShotConfigs.nShotConfig[0].eExpGainApplyMethod = OMX_TI_EXPGAINAPPLYMETHOD_RELATIVE;
|
|
enqueueShotConfigs.nShotConfig[0].bNoSnapshot = OMX_FALSE; // TODO: Make this configurable
|
|
enqueueShotConfigs.nNumConfigs = 1;
|
|
enqueueShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
enqueueShotConfigs.bFlushQueue = doFlush ? OMX_TRUE : OMX_FALSE;
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
|
|
&enqueueShotConfigs);
|
|
if ( OMX_ErrorNone != eError ) {
|
|
CAMHAL_LOGEB("Error while configuring enqueue shot 0x%x", eError);
|
|
goto exit;
|
|
} else {
|
|
CAMHAL_LOGDA("Enqueue shot configured successfully");
|
|
}
|
|
}
|
|
|
|
exit:
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::setExposureBracketing(int *evValues,
|
|
int *evValues2,
|
|
size_t evCount,
|
|
size_t frameCount,
|
|
OMX_BRACKETMODETYPE bracketMode)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_CONFIG_CAPTUREMODETYPE expCapMode;
|
|
OMX_CONFIG_EXTCAPTUREMODETYPE extExpCapMode;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
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 = bracketMode;
|
|
extExpCapMode.tBracketConfigType.nNbrBracketingValues = evCount - 1;
|
|
}
|
|
|
|
for ( unsigned int i = 0 ; i < evCount ; i++ )
|
|
{
|
|
if (bracketMode == OMX_BracketExposureGainAbsolute) {
|
|
extExpCapMode.tBracketConfigType.nBracketValues[i] = evValues[i];
|
|
extExpCapMode.tBracketConfigType.nBracketValues2[i] = evValues2[i];
|
|
} else {
|
|
// assuming OMX_BracketExposureRelativeInEV
|
|
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 )
|
|
{
|
|
CameraBuffer *buffer = (CameraBuffer *)pBuffHeader->pAppPrivate;
|
|
currentBufferIdx = buffer->index;
|
|
|
|
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((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame, 1);
|
|
returnFrame((CameraBuffer *)imgCaptureData->mBufferHeader[nextBufferIdx]->pAppPrivate, typeOfFrame);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::sendBracketFrames(size_t &framesSent)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
int currentBufferIdx;
|
|
OMXCameraPortParameters * imgCaptureData = NULL;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
framesSent = 0;
|
|
|
|
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);
|
|
framesSent++;
|
|
}
|
|
} 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;
|
|
}
|
|
|
|
{
|
|
android::AutoMutex 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 )
|
|
{
|
|
android::AutoMutex 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;
|
|
mBurstFramesAccum = imgCaptureData->mNumBufs;
|
|
mLastBracetingBufferIdx = mBracketingBuffersQueuedCount - 1;
|
|
|
|
for ( int i = 0 ; i < imgCaptureData->mNumBufs ; i++ )
|
|
{
|
|
mBracketingBuffersQueued[i] = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
CachedCaptureParameters* cap_params = cacheCaptureParameters();
|
|
ret = startImageCapture(true, cap_params);
|
|
delete cap_params;
|
|
{
|
|
android::AutoMutex 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;
|
|
|
|
ret = stopImageCapture();
|
|
|
|
android::AutoMutex lock(mBracketingLock);
|
|
|
|
if ( NULL != mBracketingBuffersQueued )
|
|
{
|
|
delete [] mBracketingBuffersQueued;
|
|
}
|
|
|
|
mBracketingBuffersQueued = NULL;
|
|
mBracketingEnabled = false;
|
|
mBracketingBuffersQueuedCount = 0;
|
|
mLastBracetingBufferIdx = 0;
|
|
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::startImageCapture(bool bracketing, CachedCaptureParameters* capParams)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMXCameraPortParameters * capData = NULL;
|
|
OMX_CONFIG_BOOLEANTYPE bOMX;
|
|
size_t bracketingSent = 0;
|
|
|
|
LOG_FUNCTION_NAME;
|
|
|
|
android::AutoMutex lock(mImageCaptureLock);
|
|
|
|
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 ( !bracketing ) {
|
|
if ((getNextState() & (CAPTURE_ACTIVE|BRACKETING_ACTIVE)) == 0) {
|
|
CAMHAL_LOGDA("trying starting capture when already canceled");
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
|
|
if (!capParams) {
|
|
CAMHAL_LOGE("Invalid cached parameters sent!");
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
// Camera framework doesn't expect face callbacks once capture is triggered
|
|
pauseFaceDetection(true);
|
|
|
|
//During bracketing image capture is already active
|
|
{
|
|
android::AutoMutex lock(mBracketingLock);
|
|
if ( mBracketingEnabled )
|
|
{
|
|
//Stop bracketing, activate normal burst for the remaining images
|
|
mBracketingEnabled = false;
|
|
ret = sendBracketFrames(bracketingSent);
|
|
|
|
// Check if we accumulated enough buffers
|
|
if ( bracketingSent < ( mBracketingRange - 1 ) )
|
|
{
|
|
mCapturedFrames = mBracketingRange + ( ( mBracketingRange - 1 ) - bracketingSent );
|
|
}
|
|
else
|
|
{
|
|
mCapturedFrames = mBracketingRange;
|
|
}
|
|
mBurstFramesQueued = 0;
|
|
mBurstFramesAccum = mCapturedFrames;
|
|
|
|
if(ret != NO_ERROR)
|
|
goto EXIT;
|
|
else
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret ) {
|
|
if (capParams->mPendingCaptureSettings & SetRotation) {
|
|
mPendingCaptureSettings &= ~SetRotation;
|
|
ret = setPictureRotation(mPictureRotation);
|
|
if ( NO_ERROR != ret ) {
|
|
CAMHAL_LOGEB("Error configuring image rotation %x", ret);
|
|
}
|
|
}
|
|
|
|
if (capParams->mPendingCaptureSettings & SetBurstExpBracket) {
|
|
mPendingCaptureSettings &= ~SetBurstExpBracket;
|
|
if ( mBracketingSet ) {
|
|
ret = doExposureBracketing(capParams->mExposureBracketingValues,
|
|
capParams->mExposureGainBracketingValues,
|
|
capParams->mExposureGainBracketingModes,
|
|
0,
|
|
0,
|
|
capParams->mFlushShotConfigQueue,
|
|
capParams->mExposureBracketMode);
|
|
} else {
|
|
ret = doExposureBracketing(capParams->mExposureBracketingValues,
|
|
capParams->mExposureGainBracketingValues,
|
|
capParams->mExposureGainBracketingModes,
|
|
capParams->mExposureBracketingValidEntries,
|
|
capParams->mBurstFrames,
|
|
capParams->mFlushShotConfigQueue,
|
|
capParams->mExposureBracketMode);
|
|
}
|
|
|
|
if ( ret != NO_ERROR ) {
|
|
CAMHAL_LOGEB("setExposureBracketing() failed %d", ret);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
|
|
CameraHal::PPM("startImageCapture bracketing configs done: ", &mStartCapture);
|
|
#endif
|
|
|
|
capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
//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 (mPending3Asettings) {
|
|
apply3Asettings(mParameters3A);
|
|
}
|
|
|
|
if (ret == NO_ERROR) {
|
|
int index = 0;
|
|
int queued = 0;
|
|
android::AutoMutex lock(mBurstLock);
|
|
|
|
if (capParams->mFlushShotConfigQueue) {
|
|
// reset shot queue
|
|
mCapturedFrames = mBurstFrames;
|
|
mBurstFramesAccum = mBurstFrames;
|
|
mBurstFramesQueued = 0;
|
|
for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
|
|
if (OMXCameraPortParameters::FILL == capData->mStatus[index]) {
|
|
mBurstFramesQueued++;
|
|
}
|
|
}
|
|
} else {
|
|
mCapturedFrames += mBurstFrames;
|
|
mBurstFramesAccum += mBurstFrames;
|
|
}
|
|
CAMHAL_LOGD("mBurstFramesQueued = %d mBurstFramesAccum = %d index = %d "
|
|
"capData->mNumBufs = %d queued = %d capData->mMaxQueueable = %d",
|
|
mBurstFramesQueued,mBurstFramesAccum,index,
|
|
capData->mNumBufs,queued,capData->mMaxQueueable);
|
|
CAMHAL_LOGD("%d", (mBurstFramesQueued < mBurstFramesAccum)
|
|
&& (index < capData->mNumBufs)
|
|
&& (queued < capData->mMaxQueueable));
|
|
while ((mBurstFramesQueued < mBurstFramesAccum) &&
|
|
(index < capData->mNumBufs) &&
|
|
(queued < capData->mMaxQueueable)) {
|
|
if (capData->mStatus[index] == OMXCameraPortParameters::IDLE) {
|
|
CAMHAL_LOGDB("Queuing buffer on Capture port - %p",
|
|
capData->mBufferHeader[index]->pBuffer);
|
|
capData->mStatus[index] = OMXCameraPortParameters::FILL;
|
|
eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
mBurstFramesQueued++;
|
|
queued++;
|
|
} else if (OMXCameraPortParameters::FILL == capData->mStatus[index]) {
|
|
CAMHAL_LOGE("Not queueing index = %d", index);
|
|
queued++;
|
|
}
|
|
index++;
|
|
}
|
|
|
|
#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
|
|
if (mRawCapture) {
|
|
capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
|
|
|
|
///Queue all the buffers on capture port
|
|
for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
|
|
CAMHAL_LOGDB("Queuing buffer on Video port (for RAW capture) - 0x%x", ( unsigned int ) capData->mBufferHeader[index]->pBuffer);
|
|
capData->mStatus[index] = OMXCameraPortParameters::FILL;
|
|
eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
|
|
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
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 ) && ( mCapMode != VIDEO_MODE_HQ ) ) {
|
|
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);
|
|
}
|
|
}
|
|
|
|
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
|
|
CameraHal::PPM("startImageCapture image buffers queued and capture enabled: ", &mStartCapture);
|
|
#endif
|
|
|
|
//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;
|
|
}
|
|
|
|
}
|
|
|
|
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
|
|
CameraHal::PPM("startImageCapture shutter event received: ", &mStartCapture);
|
|
#endif
|
|
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
|
|
EXIT:
|
|
CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
|
|
mWaitingForSnapshot = false;
|
|
mCaptureSignalled = false;
|
|
performCleanupAfterError();
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return (ret | Utils::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;
|
|
|
|
android::AutoMutex lock(mImageCaptureLock);
|
|
|
|
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;
|
|
}
|
|
|
|
// TODO(XXX): Reprocessing is currently piggy-backing capture commands
|
|
if (mAdapterState == REPROCESS_STATE) {
|
|
ret = stopReprocess();
|
|
}
|
|
|
|
//Disable the callback first
|
|
mWaitingForSnapshot = false;
|
|
|
|
// 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);
|
|
}
|
|
} else if (CP_CAM == mCapMode) {
|
|
// Reset shot config queue
|
|
OMX_TI_CONFIG_ENQUEUESHOTCONFIGS resetShotConfigs;
|
|
OMX_INIT_STRUCT_PTR(&resetShotConfigs, OMX_TI_CONFIG_ENQUEUESHOTCONFIGS);
|
|
|
|
resetShotConfigs.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
resetShotConfigs.bFlushQueue = OMX_TRUE;
|
|
resetShotConfigs.nNumConfigs = 0;
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
( OMX_INDEXTYPE ) OMX_TI_IndexConfigEnqueueShotConfigs,
|
|
&resetShotConfigs);
|
|
if ( OMX_ErrorNone != eError ) {
|
|
CAMHAL_LOGEB("Error while reset shot config 0x%x", eError);
|
|
goto EXIT;
|
|
} else {
|
|
CAMHAL_LOGDA("Shot config reset successfully");
|
|
}
|
|
}
|
|
|
|
//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 ) && ( mCapMode != VIDEO_MODE_HQ ) ) {
|
|
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;
|
|
}
|
|
}
|
|
|
|
CAMHAL_LOGDB("Capture set - 0x%x", eError);
|
|
|
|
mCaptureSignalled = true; //set this to true if we exited because of timeout
|
|
|
|
{
|
|
android::AutoMutex lock(mFrameCountMutex);
|
|
mFrameCount = 0;
|
|
mFirstFrameCondition.broadcast();
|
|
}
|
|
|
|
// Stop is always signalled externally in CPCAM mode
|
|
// We need to make sure we really stop
|
|
if ((mCapMode == CP_CAM)) {
|
|
disableReprocess();
|
|
disableImagePort();
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
}
|
|
|
|
// Moving code for below commit here as an optimization for continuous capture,
|
|
// so focus settings don't have to reapplied after each capture
|
|
// c78fa2a CameraHAL: Always reset focus mode after capture
|
|
// Workaround when doing many consecutive shots, CAF wasn't getting restarted.
|
|
mPending3Asettings |= SetFocus;
|
|
|
|
mCapturedFrames = 0;
|
|
mBurstFramesAccum = 0;
|
|
mBurstFramesQueued = 0;
|
|
|
|
return (ret | Utils::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);
|
|
}
|
|
|
|
{
|
|
android::AutoMutex lock(mFrameCountMutex);
|
|
mFrameCount = 0;
|
|
mFirstFrameCondition.broadcast();
|
|
}
|
|
|
|
performCleanupAfterError();
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::disableImagePort(){
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMXCameraPortParameters *imgCaptureData = NULL;
|
|
OMXCameraPortParameters *imgRawCaptureData = NULL;
|
|
|
|
if (!mCaptureConfigured) {
|
|
return NO_ERROR;
|
|
}
|
|
|
|
mCaptureConfigured = false;
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex]; // for RAW capture
|
|
|
|
///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;
|
|
}
|
|
|
|
deinitInternalBuffers(mCameraAdapterParameters.mImagePortIndex);
|
|
|
|
// since port settings are not persistent after port is disabled...
|
|
mPendingCaptureSettings |= SetFormat;
|
|
|
|
#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
|
|
|
|
if (mRawCapture) {
|
|
///Register for Video port Disable event
|
|
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
|
|
OMX_EventCmdComplete,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
mStopCaptureSem);
|
|
///Disable RawCapture Port
|
|
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
NULL);
|
|
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
|
|
///Free all the buffers on RawCapture port
|
|
if (imgRawCaptureData) {
|
|
CAMHAL_LOGDB("Freeing buffer on Capture port - %d", imgRawCaptureData->mNumBufs);
|
|
for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++) {
|
|
CAMHAL_LOGDB("Freeing buffer on Capture port - 0x%x", ( unsigned int ) imgRawCaptureData->mBufferHeader[index]->pBuffer);
|
|
eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
(OMX_BUFFERHEADERTYPE*)imgRawCaptureData->mBufferHeader[index]);
|
|
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
}
|
|
}
|
|
CAMHAL_LOGDA("Waiting for Video port disable");
|
|
//Wait for the image port enable event
|
|
mStopCaptureSem.WaitTimeout(OMX_CMD_TIMEOUT);
|
|
CAMHAL_LOGDA("Video Port disabled");
|
|
}
|
|
#endif
|
|
|
|
EXIT:
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
}
|
|
|
|
status_t OMXCameraAdapter::initInternalBuffers(OMX_U32 portIndex)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
int index = 0;
|
|
OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc;
|
|
|
|
/* Indicate to Ducati that we're planning to use dynamically-mapped buffers */
|
|
OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR);
|
|
bufferdesc.nPortIndex = portIndex;
|
|
bufferdesc.bEnabled = OMX_FALSE;
|
|
bufferdesc.eBufferType = OMX_TI_BufferTypePhysicalPageList;
|
|
|
|
eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor,
|
|
&bufferdesc);
|
|
if (eError!=OMX_ErrorNone) {
|
|
CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
|
|
return -EINVAL;
|
|
}
|
|
|
|
CAMHAL_LOGDA("Initializing internal buffers");
|
|
do {
|
|
OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc;
|
|
OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferallocset;
|
|
OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
|
|
bufferalloc.nPortIndex = portIndex;
|
|
bufferalloc.nIndex = index;
|
|
|
|
eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation,
|
|
&bufferalloc);
|
|
if (eError == OMX_ErrorNoMore) {
|
|
return NO_ERROR;
|
|
}
|
|
if (eError != OMX_ErrorNone) {
|
|
CAMHAL_LOGE("GetParameter failed error = 0x%x", eError);
|
|
break;
|
|
}
|
|
|
|
CAMHAL_LOGDB("Requesting buftype %d of size %dx%d",
|
|
(int)bufferalloc.eBufType, (int)bufferalloc.nAllocWidth,
|
|
(int)bufferalloc.nAllocLines);
|
|
|
|
bufferalloc.eBufType = OMX_TI_BufferTypeHardwareReserved1D;
|
|
|
|
OMX_INIT_STRUCT_PTR (&bufferallocset, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
|
|
bufferallocset.nPortIndex = portIndex;
|
|
bufferallocset.nIndex = index;
|
|
bufferallocset.eBufType = OMX_TI_BufferTypeHardwareReserved1D;
|
|
bufferallocset.nAllocWidth = bufferalloc.nAllocWidth;
|
|
bufferallocset.nAllocLines = bufferalloc.nAllocLines;
|
|
|
|
eError = OMX_SetParameter (mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE)OMX_TI_IndexParamComponentBufferAllocation,
|
|
&bufferallocset);
|
|
if (eError != OMX_ErrorNone) {
|
|
CAMHAL_LOGE("SetParameter failed, error=%08x", eError);
|
|
if (eError == OMX_ErrorNoMore) return NO_ERROR;
|
|
break;
|
|
}
|
|
|
|
index++;
|
|
|
|
/* 1 is an arbitrary limit */
|
|
} while (index < 1);
|
|
|
|
CAMHAL_LOGV("Ducati requested too many (>1) internal buffers");
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
status_t OMXCameraAdapter::deinitInternalBuffers(OMX_U32 portIndex)
|
|
{
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc;
|
|
|
|
OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR);
|
|
bufferdesc.nPortIndex = portIndex;
|
|
bufferdesc.bEnabled = OMX_FALSE;
|
|
bufferdesc.eBufferType = OMX_TI_BufferTypeDefault;
|
|
|
|
eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor,
|
|
&bufferdesc);
|
|
if (eError!=OMX_ErrorNone) {
|
|
CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
|
|
return -EINVAL;
|
|
}
|
|
|
|
OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc;
|
|
OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE);
|
|
bufferalloc.nPortIndex = portIndex;
|
|
bufferalloc.eBufType = OMX_TI_BufferTypeDefault;
|
|
bufferalloc.nAllocWidth = 1;
|
|
bufferalloc.nAllocLines = 1;
|
|
eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE) OMX_TI_IndexParamComponentBufferAllocation,
|
|
&bufferalloc);
|
|
if (eError!=OMX_ErrorNone) {
|
|
CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return Utils::ErrorUtils::omxToAndroidError(eError);
|
|
}
|
|
|
|
status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num)
|
|
{
|
|
LOG_FUNCTION_NAME;
|
|
|
|
status_t ret = NO_ERROR;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMXCameraPortParameters * imgCaptureData = NULL;
|
|
OMXCameraPortParameters cap;
|
|
|
|
imgCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
|
|
|
|
if ( 0 != mUseCaptureSem.Count() )
|
|
{
|
|
CAMHAL_LOGEB("Error mUseCaptureSem semaphore count %d", mUseCaptureSem.Count());
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
CAMHAL_ASSERT(num > 0);
|
|
|
|
// if some setting that requires a SetParameter (including
|
|
// changing buffer types) then we need to disable the port
|
|
// before being allowed to apply the settings
|
|
if ((mPendingCaptureSettings & ECaptureParamSettings) ||
|
|
bufArr[0].type != imgCaptureData->mBufferType ||
|
|
imgCaptureData->mNumBufs != num) {
|
|
if (mCaptureConfigured) {
|
|
disableImagePort();
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
}
|
|
|
|
imgCaptureData->mBufferType = bufArr[0].type;
|
|
imgCaptureData->mNumBufs = num;
|
|
|
|
CAMHAL_LOGDB("Params Width = %d", (int)imgCaptureData->mWidth);
|
|
CAMHAL_LOGDB("Params Height = %d", (int)imgCaptureData->mHeight);
|
|
|
|
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 & SetQuality) {
|
|
mPendingCaptureSettings &= ~SetQuality;
|
|
ret = setImageQuality(mPictureQuality);
|
|
if ( NO_ERROR != ret) {
|
|
CAMHAL_LOGEB("Error configuring image quality %x", ret);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
// Configure DOMX to use either gralloc handles or vptrs
|
|
{
|
|
OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles;
|
|
OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER);
|
|
|
|
domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
|
|
if (bufArr[0].type == CAMERA_BUFFER_ANW) {
|
|
CAMHAL_LOGD ("Using ANW Buffers");
|
|
initInternalBuffers(mCameraAdapterParameters.mImagePortIndex);
|
|
domxUseGrallocHandles.bEnable = OMX_TRUE;
|
|
} else {
|
|
CAMHAL_LOGD ("Using ION Buffers");
|
|
domxUseGrallocHandles.bEnable = OMX_FALSE;
|
|
}
|
|
|
|
eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles);
|
|
if (eError!=OMX_ErrorNone) {
|
|
CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
|
|
}
|
|
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
|
|
}
|
|
|
|
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
|
|
|
|
CameraHal::PPM("Takepicture image port configuration: ", &bufArr->ppmStamp);
|
|
|
|
#endif
|
|
|
|
// 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)bufArr[index].opaque,
|
|
(int)imgCaptureData->mBufSize);
|
|
|
|
eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
|
|
&pBufferHdr,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
0,
|
|
imgCaptureData->mBufSize,
|
|
(OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
|
|
|
|
CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
|
|
GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
|
|
|
|
pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
|
|
bufArr[index].index = 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;
|
|
imgCaptureData->mStatus[index] = OMXCameraPortParameters::IDLE;
|
|
}
|
|
|
|
// 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) {
|
|
ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
|
|
OMX_EventCmdComplete,
|
|
OMX_CommandPortEnable,
|
|
mCameraAdapterParameters.mImagePortIndex,
|
|
NULL);
|
|
CAMHAL_LOGDA("Timeout expired on port enable");
|
|
goto EXIT;
|
|
}
|
|
CAMHAL_LOGDA("Port enabled");
|
|
|
|
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
|
|
|
|
CameraHal::PPM("Takepicture image port enabled and buffers registered: ", &bufArr->ppmStamp);
|
|
|
|
#endif
|
|
|
|
if (mNextState != LOADED_REPROCESS_CAPTURE_STATE) {
|
|
// Enable WB and vector shot extra data for metadata
|
|
setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance);
|
|
setExtraData(true, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable);
|
|
}
|
|
|
|
// CPCam mode only supports vector shot
|
|
// Regular capture is not supported
|
|
if ( (mCapMode == CP_CAM) && (mNextState != LOADED_REPROCESS_CAPTURE_STATE) ) {
|
|
initVectorShot();
|
|
}
|
|
|
|
mCaptureBuffersAvailable.clear();
|
|
for (unsigned int i = 0; i < imgCaptureData->mMaxQueueable; i++ ) {
|
|
mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 0);
|
|
}
|
|
|
|
// initial ref count for undeqeueued buffers is 1 since buffer provider
|
|
// is still holding on to it
|
|
for (unsigned int i = imgCaptureData->mMaxQueueable; i < imgCaptureData->mNumBufs; i++ ) {
|
|
mCaptureBuffersAvailable.add(&mCaptureBuffers[i], 1);
|
|
}
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
ret = setupEXIF();
|
|
if ( NO_ERROR != ret )
|
|
{
|
|
CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
|
|
}
|
|
}
|
|
|
|
// Choose proper single preview mode for cp capture (reproc or hs)
|
|
if (( NO_ERROR == ret) && (OMXCameraAdapter::CP_CAM == mCapMode)) {
|
|
OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE singlePrevMode;
|
|
OMX_INIT_STRUCT_PTR (&singlePrevMode, OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE);
|
|
if (mNextState == LOADED_CAPTURE_STATE) {
|
|
singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed;
|
|
} else if (mNextState == LOADED_REPROCESS_CAPTURE_STATE) {
|
|
singlePrevMode.eMode = OMX_TI_SinglePreviewMode_Reprocess;
|
|
} else {
|
|
CAMHAL_LOGE("Wrong state trying to start a capture in CPCAM mode?");
|
|
singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed;
|
|
}
|
|
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_INDEXTYPE) OMX_TI_IndexConfigSinglePreviewMode,
|
|
&singlePrevMode);
|
|
if ( OMX_ErrorNone != eError ) {
|
|
CAMHAL_LOGEB("Error while configuring single preview mode 0x%x", eError);
|
|
ret = Utils::ErrorUtils::omxToAndroidError(eError);
|
|
} else {
|
|
CAMHAL_LOGDA("single preview mode configured successfully");
|
|
}
|
|
}
|
|
|
|
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
|
|
|
|
CameraHal::PPM("Takepicture extra configs on image port done: ", &bufArr->ppmStamp);
|
|
|
|
#endif
|
|
|
|
mCaptureConfigured = true;
|
|
|
|
#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
|
|
if (mRawCapture) {
|
|
mCaptureConfigured = false;
|
|
}
|
|
#endif
|
|
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
|
|
EXIT:
|
|
CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
|
|
setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_WhiteBalance);
|
|
// TODO: WA: if domx client disables VectShotInfo metadata on the image port, this causes
|
|
// VectShotInfo to be disabled internally on preview port also. Remove setting in OMXCapture
|
|
// setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_VectShotInfo);
|
|
setExtraData(false, mCameraAdapterParameters.mImagePortIndex, OMX_TI_LSCTable);
|
|
//Release image buffers
|
|
if ( NULL != mReleaseImageBuffersCallback ) {
|
|
mReleaseImageBuffersCallback(mReleaseData);
|
|
}
|
|
performCleanupAfterError();
|
|
LOG_FUNCTION_NAME_EXIT;
|
|
return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
|
|
|
|
}
|
|
status_t OMXCameraAdapter::UseBuffersRawCapture(CameraBuffer *bufArr, int num)
|
|
{
|
|
LOG_FUNCTION_NAME
|
|
status_t ret;
|
|
OMX_ERRORTYPE eError;
|
|
OMXCameraPortParameters * imgRawCaptureData = NULL;
|
|
Utils::Semaphore camSem;
|
|
OMXCameraPortParameters cap;
|
|
|
|
imgRawCaptureData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex];
|
|
|
|
if (mCaptureConfigured) {
|
|
return NO_ERROR;
|
|
}
|
|
|
|
camSem.Create();
|
|
|
|
// mWaitingForSnapshot is true only when we're in the process of capturing
|
|
if (mWaitingForSnapshot) {
|
|
///Register for Video port Disable event
|
|
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_EVENTTYPE) OMX_EventCmdComplete,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
camSem);
|
|
|
|
///Disable Capture Port
|
|
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
|
|
OMX_CommandPortDisable,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
NULL);
|
|
|
|
CAMHAL_LOGDA("Waiting for port disable");
|
|
//Wait for the image port enable event
|
|
camSem.Wait();
|
|
CAMHAL_LOGDA("Port disabled");
|
|
}
|
|
|
|
imgRawCaptureData->mNumBufs = num;
|
|
|
|
CAMHAL_LOGDB("RAW Max sensor width = %d", (int)imgRawCaptureData->mWidth);
|
|
CAMHAL_LOGDB("RAW Max sensor height = %d", (int)imgRawCaptureData->mHeight);
|
|
|
|
ret = setFormat(OMX_CAMERA_PORT_VIDEO_OUT_VIDEO, *imgRawCaptureData);
|
|
|
|
if (ret != NO_ERROR) {
|
|
CAMHAL_LOGEB("setFormat() failed %d", ret);
|
|
LOG_FUNCTION_NAME_EXIT
|
|
return ret;
|
|
}
|
|
|
|
///Register for Video port ENABLE event
|
|
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
|
|
(OMX_EVENTTYPE) OMX_EventCmdComplete,
|
|
OMX_CommandPortEnable,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
camSem);
|
|
|
|
///Enable Video Capture Port
|
|
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
|
|
OMX_CommandPortEnable,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
NULL);
|
|
|
|
mCaptureBuffersLength = (int)imgRawCaptureData->mBufSize;
|
|
for ( int index = 0 ; index < imgRawCaptureData->mNumBufs ; index++ ) {
|
|
OMX_BUFFERHEADERTYPE *pBufferHdr;
|
|
CAMHAL_LOGDB("OMX_UseBuffer rawCapture address: 0x%x, size = %d ",
|
|
(unsigned int)bufArr[index].opaque,
|
|
(int)imgRawCaptureData->mBufSize );
|
|
|
|
eError = OMX_UseBuffer( mCameraAdapterParameters.mHandleComp,
|
|
&pBufferHdr,
|
|
mCameraAdapterParameters.mVideoPortIndex,
|
|
0,
|
|
mCaptureBuffersLength,
|
|
(OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
|
|
if (eError != OMX_ErrorNone) {
|
|
CAMHAL_LOGEB("OMX_UseBuffer = 0x%x", eError);
|
|
}
|
|
|
|
GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
|
|
|
|
pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
|
|
bufArr[index].index = 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;
|
|
imgRawCaptureData->mBufferHeader[index] = pBufferHdr;
|
|
|
|
}
|
|
|
|
//Wait for the image port enable event
|
|
CAMHAL_LOGDA("Waiting for port enable");
|
|
camSem.Wait();
|
|
CAMHAL_LOGDA("Port enabled");
|
|
|
|
if (NO_ERROR == ret) {
|
|
ret = setupEXIF();
|
|
if ( NO_ERROR != ret ) {
|
|
CAMHAL_LOGEB("Error configuring EXIF Buffer %x", ret);
|
|
}
|
|
}
|
|
|
|
mCapturedFrames = mBurstFrames;
|
|
mBurstFramesQueued = 0;
|
|
mCaptureConfigured = true;
|
|
|
|
EXIT:
|
|
|
|
if (eError != OMX_ErrorNone) {
|
|
if ( NULL != mErrorNotifier )
|
|
{
|
|
mErrorNotifier->errorNotify(eError);
|
|
}
|
|
}
|
|
|
|
LOG_FUNCTION_NAME_EXIT
|
|
|
|
return ret;
|
|
}
|
|
|
|
} // namespace Camera
|
|
} // namespace Ti
|