/*
* 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 OMXCameraAdapter.cpp
*
* This file maps the Camera Hardware Interface to OMX.
*
*/
#include "CameraHal.h"
#include "OMXCameraAdapter.h"
#include "ErrorUtils.h"
#include "TICameraParameters.h"
#include <signal.h>
#include <math.h>
#include <cutils/properties.h>
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
static int mDebugFps = 0;
static int mDebugFcs = 0;
#undef TRUE
#undef FALSE
#define HERE(Msg) {CAMHAL_LOGEB("--===line %d, %s===--\n", __LINE__, Msg);}
namespace android {
#undef LOG_TAG
///Maintain a separate tag for OMXCameraAdapter logs to isolate issues OMX specific
#define LOG_TAG "CameraHAL"
//frames skipped before recalculating the framerate
#define FPS_PERIOD 30
Mutex gAdapterLock;
/*--------------------Camera Adapter Class STARTS here-----------------------------*/
status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps)
{
LOG_FUNCTION_NAME;
char value[PROPERTY_VALUE_MAX];
property_get("debug.camera.showfps", value, "0");
mDebugFps = atoi(value);
property_get("debug.camera.framecounts", value, "0");
mDebugFcs = atoi(value);
TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone;
OMX_ERRORTYPE eError = OMX_ErrorNone;
status_t ret = NO_ERROR;
mLocalVersionParam.s.nVersionMajor = 0x1;
mLocalVersionParam.s.nVersionMinor = 0x1;
mLocalVersionParam.s.nRevision = 0x0 ;
mLocalVersionParam.s.nStep = 0x0;
mPending3Asettings = 0;//E3AsettingsAll;
mPendingCaptureSettings = 0;
if ( 0 != mInitSem.Count() )
{
CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count());
LOG_FUNCTION_NAME_EXIT;
return NO_INIT;
}
///Update the preview and image capture port indexes
mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
// temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
//currently not supported use preview port instead
mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
eError = OMX_Init();
if (eError != OMX_ErrorNone) {
CAMHAL_LOGEB("OMX_Init() failed, error: 0x%x", eError);
return ErrorUtils::omxToAndroidError(eError);
}
mOmxInitialized = true;
///Get the handle to the OMX Component
eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, (OMX_PTR)this);
if(eError != OMX_ErrorNone) {
CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
}
GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);
mComponentState = OMX_StateLoaded;
CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex);
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
OMX_CommandPortDisable,
OMX_ALL,
NULL);
if(eError != OMX_ErrorNone) {
CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError);
}
GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);
// Register for port enable event
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
OMX_EventCmdComplete,
OMX_CommandPortEnable,
mCameraAdapterParameters.mPrevPortIndex,
mInitSem);
if(ret != NO_ERROR) {
CAMHAL_LOGEB("Error in registering for event %d", ret);
goto EXIT;
}
// Enable PREVIEW Port
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
OMX_CommandPortEnable,
mCameraAdapterParameters.mPrevPortIndex,
NULL);
if(eError != OMX_ErrorNone) {
CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
}
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
// Wait for the port enable event to occur
ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
if ( NO_ERROR == ret ) {
CAMHAL_LOGDA("-Port enable event arrived");
} else {
ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
OMX_EventCmdComplete,
OMX_CommandPortEnable,
mCameraAdapterParameters.mPrevPortIndex,
NULL);
CAMHAL_LOGEA("Timeout for enabling preview port expired!");
goto EXIT;
}
// Select the sensor
OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex;
eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
if ( OMX_ErrorNone != eError ) {
CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError);
return BAD_VALUE;
} else {
CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex);
}
printComponentVersion(mCameraAdapterParameters.mHandleComp);
mBracketingEnabled = false;
mBracketingBuffersQueuedCount = 0;
mBracketingRange = 1;
mLastBracetingBufferIdx = 0;
mOMXStateSwitch = false;
mCaptureSignalled = false;
mCaptureConfigured = false;
mRecording = false;
mWaitingForSnapshot = false;
mSnapshotCount = 0;
mCapMode = HIGH_QUALITY;
mIPP = IPP_NULL;
mVstabEnabled = false;
mVnfEnabled = false;
mBurstFrames = 1;
mCapturedFrames = 0;
mPictureQuality = 100;
mCurrentZoomIdx = 0;
mTargetZoomIdx = 0;
mPreviousZoomIndx = 0;
mReturnZoomStatus = false;
mZoomInc = 1;
mZoomParameterIdx = 0;
mExposureBracketingValidEntries = 0;
mSensorOverclock = false;
mIternalRecordingHint = false;
mDeviceOrientation = 0;
mCapabilities = caps;
mZoomUpdating = false;
mZoomUpdate = false;
mEXIFData.mGPSData.mAltitudeValid = false;
mEXIFData.mGPSData.mDatestampValid = false;
mEXIFData.mGPSData.mLatValid = false;
mEXIFData.mGPSData.mLongValid = false;
mEXIFData.mGPSData.mMapDatumValid = false;
mEXIFData.mGPSData.mProcMethodValid = false;
mEXIFData.mGPSData.mVersionIdValid = false;
mEXIFData.mGPSData.mTimeStampValid = false;
mEXIFData.mModelValid = false;
mEXIFData.mMakeValid = false;
// initialize command handling thread
if(mCommandHandler.get() == NULL)
mCommandHandler = new CommandHandler(this);
if ( NULL == mCommandHandler.get() )
{
CAMHAL_LOGEA("Couldn't create command handler");
return NO_MEMORY;
}
ret = mCommandHandler->run("CallbackThread", PRIORITY_URGENT_DISPLAY);
if ( ret != NO_ERROR )
{
if( ret == INVALID_OPERATION){
CAMHAL_LOGDA("command handler thread already runnning!!");
ret = NO_ERROR;
} else
{
CAMHAL_LOGEA("Couldn't run command handlerthread");
return ret;
}
}
// initialize omx callback handling thread
if(mOMXCallbackHandler.get() == NULL)
mOMXCallbackHandler =