summaryrefslogtreecommitdiffstats
path: root/camera/CameraHal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/CameraHal.cpp')
-rw-r--r--camera/CameraHal.cpp5012
1 files changed, 5012 insertions, 0 deletions
diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp
new file mode 100644
index 0000000..7e7cf9d
--- /dev/null
+++ b/camera/CameraHal.cpp
@@ -0,0 +1,5012 @@
+/*
+ * 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 CameraHal.cpp
+*
+* This file maps the Camera Hardware Interface to V4L2.
+*
+*/
+
+#include "CameraHal.h"
+#include "ANativeWindowDisplayAdapter.h"
+#include "BufferSourceAdapter.h"
+#include "TICameraParameters.h"
+#include "CameraProperties.h"
+#include <cutils/properties.h>
+
+#include <poll.h>
+#include <math.h>
+
+namespace Ti {
+namespace Camera {
+
+extern "C" CameraAdapter* OMXCameraAdapter_Factory(size_t);
+extern "C" CameraAdapter* V4LCameraAdapter_Factory(size_t, CameraHal*);
+
+/*****************************************************************************/
+
+////Constant definitions and declarations
+////@todo Have a CameraProperties class to store these parameters as constants for every camera
+//// Currently, they are hard-coded
+
+const int CameraHal::NO_BUFFERS_PREVIEW = MAX_CAMERA_BUFFERS;
+const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 5;
+const int CameraHal::SW_SCALING_FPS_LIMIT = 15;
+
+const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 16;
+
+const uint32_t MessageNotifier::FRAME_BIT_FIELD_POSITION = 0;
+
+// TODO(XXX): Temporarily increase number of buffers we can allocate from ANW
+// until faux-NPA mode is implemented
+const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15;
+
+#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
+// HACK: Default path to directory where RAW images coming from video port will be saved to.
+// If directory not exists the saving is skipped and video port frame is ignored.
+// The directory name is choosed in so weird way to enable RAW images saving only when
+// directory has been created explicitly by user.
+extern const char * const kRawImagesOutputDirPath = "/data/misc/camera/RaW_PiCtUrEs";
+extern const char * const kYuvImagesOutputDirPath = "/data/misc/camera/YuV_PiCtUrEs";
+#endif
+
+/******************************************************************************/
+
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+static int dummy_update_and_get_buffer(preview_stream_ops_t*, buffer_handle_t**, int*,int*) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_release_buffer(preview_stream_ops_t*, int slot) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_get_buffer_dimension(preview_stream_ops_t*, int*, int*) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_get_buffer_format(preview_stream_ops_t*, int*) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_set_metadata(preview_stream_ops_t*, const camera_memory_t*) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_get_id(preview_stream_ops_t*, char *data, unsigned int dataSize) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_get_buffer_count(preview_stream_ops_t*, int *count) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_get_crop(preview_stream_ops_t*,
+ int *, int *, int *, int *) {
+ return INVALID_OPERATION;
+}
+
+static int dummy_get_current_size(preview_stream_ops_t*,
+ int *, int *) {
+ return INVALID_OPERATION;
+}
+#endif
+
+
+CameraHal::SocFamily CameraHal::getSocFamily() {
+ static const struct {
+ const char *name;
+ const CameraHal::SocFamily value;
+ } socFamilyArray[] = {
+ {"OMAP4430", SocFamily_Omap4430},
+ {"OMAP4460", SocFamily_Omap4460},
+ {"OMAP4470", SocFamily_Omap4470}
+ };
+ // lets get the soc family string from sysfs
+ static const char *sysfsNode = "/sys/board_properties/soc/family";
+ FILE *sysfsFd = fopen(sysfsNode, "r");
+ static const int bufSize = 128;
+ char buf[bufSize];
+ if (sysfsFd == NULL) {
+ CAMHAL_LOGEA("'%s' Not Available", sysfsNode);
+ return SocFamily_Undefined;
+ }
+ const char *res = fgets(buf, bufSize, sysfsFd);
+ fclose(sysfsFd);
+ if (res == NULL) {
+ CAMHAL_LOGEA("Error reading '%s'", sysfsNode);
+ return SocFamily_Undefined;
+ }
+ // translate it to CameraHal::SocFamily enum
+ for (int i = 0; i < SocFamily_ElementCount; ++i) {
+ if (strncmp(socFamilyArray[i].name, buf, strlen(socFamilyArray[i].name)) == 0) {
+ return socFamilyArray[i].value;
+ }
+ }
+ return SocFamily_Undefined;
+}
+
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+static preview_stream_extended_ops_t dummyPreviewStreamExtendedOps = {
+#ifdef OMAP_ENHANCEMENT_CPCAM
+ dummy_update_and_get_buffer,
+ dummy_release_buffer,
+ dummy_get_buffer_dimension,
+ dummy_get_buffer_format,
+ dummy_set_metadata,
+ dummy_get_id,
+ dummy_get_buffer_count,
+ dummy_get_crop,
+ dummy_get_current_size,
+#endif
+};
+#endif
+
+
+DisplayAdapter::DisplayAdapter()
+{
+#ifdef OMAP_ENHANCEMENT_CPCAM
+ mExtendedOps = &dummyPreviewStreamExtendedOps;
+#endif
+}
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+void DisplayAdapter::setExtendedOps(preview_stream_extended_ops_t * extendedOps) {
+ mExtendedOps = extendedOps ? extendedOps : &dummyPreviewStreamExtendedOps;
+}
+#endif
+
+
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+struct timeval CameraHal::mStartPreview;
+struct timeval CameraHal::mStartFocus;
+struct timeval CameraHal::mStartCapture;
+
+#endif
+
+static void orientation_cb(uint32_t orientation, uint32_t tilt, void* cookie) {
+ CameraHal *camera = NULL;
+
+ if (cookie) {
+ camera = (CameraHal*) cookie;
+ camera->onOrientationEvent(orientation, tilt);
+ }
+
+}
+
+/*-------------Camera Hal Interface Method definitions STARTS here--------------------*/
+
+/**
+ Callback function to receive orientation events from SensorListener
+ */
+void CameraHal::onOrientationEvent(uint32_t orientation, uint32_t tilt) {
+ LOG_FUNCTION_NAME;
+
+ if ( NULL != mCameraAdapter ) {
+ mCameraAdapter->onOrientationEvent(orientation, tilt);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Set the notification and data callbacks
+
+ @param[in] notify_cb Notify callback for notifying the app about events and errors
+ @param[in] data_cb Buffer callback for sending the preview/raw frames to the app
+ @param[in] data_cb_timestamp Buffer callback for sending the video frames w/ timestamp
+ @param[in] user Callback cookie
+ @return none
+
+ */
+void CameraHal::setCallbacks(camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
+ void *user)
+{
+ LOG_FUNCTION_NAME;
+
+ if ( NULL != mAppCallbackNotifier.get() )
+ {
+ mAppCallbackNotifier->setCallbacks(this,
+ notify_cb,
+ data_cb,
+ data_cb_timestamp,
+ get_memory,
+ user);
+ }
+
+ if ( NULL != mCameraAdapter ) {
+ mCameraAdapter->setSharedAllocator(get_memory);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Enable a message, or set of messages.
+
+ @param[in] msgtype Bitmask of the messages to enable (defined in include/ui/Camera.h)
+ @return none
+
+ */
+void CameraHal::enableMsgType(int32_t msgType)
+{
+ LOG_FUNCTION_NAME;
+
+ if ( ( msgType & CAMERA_MSG_SHUTTER ) && ( !mShutterEnabled ) )
+ {
+ msgType &= ~CAMERA_MSG_SHUTTER;
+ }
+
+ // ignoring enable focus message from camera service
+ // we will enable internally in autoFocus call
+ msgType &= ~CAMERA_MSG_FOCUS;
+#ifdef ANDROID_API_JB_OR_LATER
+ msgType &= ~CAMERA_MSG_FOCUS_MOVE;
+#endif
+
+ {
+ android::AutoMutex lock(mLock);
+ mMsgEnabled |= msgType;
+ }
+
+ if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
+ {
+ if(mDisplayPaused)
+ {
+ CAMHAL_LOGDA("Preview currently paused...will enable preview callback when restarted");
+ msgType &= ~CAMERA_MSG_PREVIEW_FRAME;
+ }else
+ {
+ CAMHAL_LOGDA("Enabling Preview Callback");
+ }
+ }
+ else
+ {
+ CAMHAL_LOGDB("Preview callback not enabled %x", msgType);
+ }
+
+
+ ///Configure app callback notifier with the message callback required
+ mAppCallbackNotifier->enableMsgType (msgType);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Disable a message, or set of messages.
+
+ @param[in] msgtype Bitmask of the messages to disable (defined in include/ui/Camera.h)
+ @return none
+
+ */
+void CameraHal::disableMsgType(int32_t msgType)
+{
+ LOG_FUNCTION_NAME;
+
+ {
+ android::AutoMutex lock(mLock);
+ mMsgEnabled &= ~msgType;
+ }
+
+ if( msgType & CAMERA_MSG_PREVIEW_FRAME)
+ {
+ CAMHAL_LOGDA("Disabling Preview Callback");
+ }
+
+ ///Configure app callback notifier
+ mAppCallbackNotifier->disableMsgType (msgType);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Query whether a message, or a set of messages, is enabled.
+
+ Note that this is operates as an AND, if any of the messages queried are off, this will
+ return false.
+
+ @param[in] msgtype Bitmask of the messages to query (defined in include/ui/Camera.h)
+ @return true If all message types are enabled
+ false If any message type
+
+ */
+int CameraHal::msgTypeEnabled(int32_t msgType)
+{
+ int32_t msgEnabled = 0;
+
+ LOG_FUNCTION_NAME;
+ android::AutoMutex lock(mLock);
+
+ msgEnabled = mMsgEnabled;
+ if (!previewEnabled() && !mPreviewInitializationDone) {
+ msgEnabled &= ~(CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_PREVIEW_METADATA);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+ return (msgEnabled & msgType);
+}
+
+/**
+ @brief Set the camera parameters.
+
+ @param[in] params Camera parameters to configure the camera
+ @return NO_ERROR
+ @todo Define error codes
+
+ */
+int CameraHal::setParameters(const char* parameters)
+{
+
+ LOG_FUNCTION_NAME;
+
+ android::CameraParameters params;
+
+ android::String8 str_params(parameters);
+ params.unflatten(str_params);
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return setParameters(params);
+}
+
+/**
+ @brief Set the camera parameters.
+
+ @param[in] params Camera parameters to configure the camera
+ @return NO_ERROR
+ @todo Define error codes
+
+ */
+int CameraHal::setParameters(const android::CameraParameters& params)
+{
+
+ LOG_FUNCTION_NAME;
+
+ int w, h;
+ int framerate;
+ const char *valstr = NULL;
+ int varint = 0;
+ status_t ret = NO_ERROR;
+ // Needed for KEY_RECORDING_HINT
+ bool restartPreviewRequired = false;
+ bool updateRequired = false;
+ android::CameraParameters oldParams = mParameters;
+#ifdef MOTOROLA_CAMERA
+ char value[PROPERTY_VALUE_MAX];
+#endif
+
+#ifdef V4L_CAMERA_ADAPTER
+ if (strcmp (V4L_CAMERA_NAME_USB, mCameraProperties->get(CameraProperties::CAMERA_NAME)) == 0 ) {
+ updateRequired = true;
+ }
+#endif
+
+ {
+ android::AutoMutex lock(mLock);
+
+ ///Ensure that preview is not enabled when the below parameters are changed.
+ if(!previewEnabled())
+ {
+ if ((valstr = params.getPreviewFormat()) != NULL) {
+ if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS))) {
+ mParameters.setPreviewFormat(valstr);
+ CAMHAL_LOGDB("PreviewFormat set %s", valstr);
+ } else {
+ CAMHAL_LOGEB("Invalid preview format: %s. Supported: %s", valstr,
+ mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
+ return BAD_VALUE;
+ }
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_VNF)) != NULL) {
+ if (strcmp(mCameraProperties->get(CameraProperties::VNF_SUPPORTED),
+ android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGDB("VNF %s", valstr);
+ mParameters.set(TICameraParameters::KEY_VNF, valstr);
+ } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGEB("ERROR: Invalid VNF: %s", valstr);
+ return BAD_VALUE;
+ } else {
+ mParameters.set(TICameraParameters::KEY_VNF,
+ android::CameraParameters::FALSE);
+ }
+ }
+
+ if ((valstr = params.get(android::CameraParameters::KEY_VIDEO_STABILIZATION)) != NULL) {
+ // make sure we support vstab...if we don't and application is trying to set
+ // vstab then return an error
+ if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
+ android::CameraParameters::TRUE) != 0 &&
+ strcmp(valstr, android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGEB("ERROR: Invalid VSTAB: %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_CAP_MODE)) != NULL) {
+
+ if (strcmp(TICameraParameters::VIDEO_MODE, valstr)) {
+ mCapModeBackup = valstr;
+ }
+
+ CAMHAL_LOGDB("Capture mode set %s", valstr);
+
+ const char *currentMode = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+ if ( NULL != currentMode ) {
+ if ( strcmp(currentMode, valstr) != 0 ) {
+ updateRequired = true;
+ }
+ } else {
+ updateRequired = true;
+ }
+
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, valstr);
+ } else if (!mCapModeBackup.isEmpty()) {
+ // Restore previous capture mode after stopPreview()
+ mParameters.set(TICameraParameters::KEY_CAP_MODE,
+ mCapModeBackup.string());
+ updateRequired = true;
+ }
+
+#ifdef OMAP_ENHANCEMENT_VTC
+ if ((valstr = params.get(TICameraParameters::KEY_VTC_HINT)) != NULL ) {
+ mParameters.set(TICameraParameters::KEY_VTC_HINT, valstr);
+ if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
+ mVTCUseCase = true;
+ } else {
+ mVTCUseCase = false;
+ }
+ CAMHAL_LOGDB("VTC Hint = %d", mVTCUseCase);
+ }
+
+ if (mVTCUseCase) {
+ if ((valstr = params.get(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE)) != NULL ) {
+ mParameters.set(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE, valstr);
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT)) != NULL ) {
+ mParameters.set(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT, valstr);
+ }
+ }
+#endif
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_IPP)) != NULL) {
+ if (isParameterValid(valstr,mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES))) {
+ if ((mParameters.get(TICameraParameters::KEY_IPP) == NULL) ||
+ (strcmp(valstr, mParameters.get(TICameraParameters::KEY_IPP)))) {
+ CAMHAL_LOGDB("IPP mode set %s", params.get(TICameraParameters::KEY_IPP));
+ mParameters.set(TICameraParameters::KEY_IPP, valstr);
+ restartPreviewRequired = true;
+ }
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid IPP mode: %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if ( (valstr = params.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)) != NULL )
+ {
+ if (strcmp(valstr, mParameters.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)))
+ {
+ CAMHAL_LOGDB("Stereo 3D preview image layout is %s", valstr);
+ mParameters.set(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT, valstr);
+ restartPreviewRequired = true;
+ }
+ }
+
+#ifdef OMAP_ENHANCEMENT
+ int orientation =0;
+ if((valstr = params.get(TICameraParameters::KEY_SENSOR_ORIENTATION)) != NULL)
+ {
+ doesSetParameterNeedUpdate(valstr,
+ mParameters.get(TICameraParameters::KEY_SENSOR_ORIENTATION),
+ updateRequired);
+
+ orientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
+ if ( orientation < 0 || orientation >= 360 || (orientation%90) != 0 ) {
+ CAMHAL_LOGE("Invalid sensor orientation: %s. Value must be one of: [0, 90, 180, 270]", valstr);
+ return BAD_VALUE;
+ }
+
+ CAMHAL_LOGD("Sensor Orientation is set to %d", orientation);
+ mParameters.set(TICameraParameters::KEY_SENSOR_ORIENTATION, valstr);
+ }
+#endif
+
+ params.getPreviewSize(&w, &h);
+ if (w == -1 && h == -1) {
+ CAMHAL_LOGEA("Unable to get preview size");
+ return BAD_VALUE;
+ }
+
+ mVideoWidth = w;
+ mVideoHeight = h;
+
+ // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
+ valstr = params.get(android::CameraParameters::KEY_RECORDING_HINT);
+ if(valstr != NULL)
+ {
+ CAMHAL_LOGDB("Recording Hint is set to %s", valstr);
+ if(strcmp(valstr, android::CameraParameters::TRUE) == 0)
+ {
+ CAMHAL_LOGVB("Video Resolution: %d x %d", mVideoWidth, mVideoHeight);
+ mParameters.set(android::CameraParameters::KEY_RECORDING_HINT, valstr);
+ restartPreviewRequired |= setVideoModeParameters(params);
+ }
+ else if(strcmp(valstr, android::CameraParameters::FALSE) == 0)
+ {
+ mParameters.set(android::CameraParameters::KEY_RECORDING_HINT, valstr);
+ restartPreviewRequired |= resetVideoModeParameters();
+ }
+ else
+ {
+ CAMHAL_LOGEA("Invalid RECORDING_HINT");
+ return BAD_VALUE;
+ }
+ }
+ else
+ {
+ // This check is required in following case.
+ // If VideoRecording activity sets KEY_RECORDING_HINT to TRUE and
+ // ImageCapture activity doesnot set KEY_RECORDING_HINT to FALSE (i.e. simply NULL),
+ // then Video Mode parameters may remain present in ImageCapture activity as well.
+ CAMHAL_LOGDA("Recording Hint is set to NULL");
+ mParameters.set(android::CameraParameters::KEY_RECORDING_HINT, "");
+ restartPreviewRequired |= resetVideoModeParameters();
+ }
+
+ if ( (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
+ && (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SUBSAMPLED_SIZES)))
+ && (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES)))
+ && (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_TOPBOTTOM_SIZES))) ) {
+ CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
+ return BAD_VALUE;
+ }
+
+ int oldWidth, oldHeight;
+ mParameters.getPreviewSize(&oldWidth, &oldHeight);
+ if ( ( oldWidth != w ) || ( oldHeight != h ) )
+ {
+ mParameters.setPreviewSize(w, h);
+ restartPreviewRequired = true;
+ }
+
+ CAMHAL_LOGDB("Preview Resolution: %d x %d", w, h);
+
+ if ((valstr = params.get(android::CameraParameters::KEY_FOCUS_MODE)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES))) {
+ CAMHAL_LOGDB("Focus mode set %s", valstr);
+
+ // we need to take a decision on the capture mode based on whether CAF picture or
+ // video is chosen so the behavior of each is consistent to the application
+ if(strcmp(valstr, android::CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0){
+ restartPreviewRequired |= resetVideoModeParameters();
+ } else if (strcmp(valstr, android::CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0){
+ restartPreviewRequired |= setVideoModeParameters(params);
+ }
+
+ mParameters.set(android::CameraParameters::KEY_FOCUS_MODE, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid FOCUS mode = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ mRawCapture = false;
+
+#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
+ valstr = params.get(TICameraParameters::KEY_CAP_MODE);
+ if ( (!valstr || strcmp(valstr, TICameraParameters::HIGH_QUALITY_MODE) == 0) &&
+ access(kRawImagesOutputDirPath, F_OK) != -1 ) {
+ mRawCapture = true;
+ }
+#endif
+
+ if ( (valstr = params.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT)) != NULL )
+ {
+ CAMHAL_LOGDB("Stereo 3D capture image layout is %s", valstr);
+ mParameters.set(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT, valstr);
+ }
+
+ params.getPictureSize(&w, &h);
+ if ( (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES)))
+ || (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SUBSAMPLED_SIZES)))
+ || (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_TOPBOTTOM_SIZES)))
+ || (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIDEBYSIDE_SIZES))) ) {
+ mParameters.setPictureSize(w, h);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid picture resolution %d x %d", w, h);
+ return BAD_VALUE;
+ }
+
+ CAMHAL_LOGDB("Picture Size by App %d x %d", w, h);
+
+ if ( (valstr = params.getPictureFormat()) != NULL ) {
+ if (isParameterValid(valstr,mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS))) {
+ if ((strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) &&
+ mCameraProperties->get(CameraProperties::MAX_PICTURE_WIDTH) &&
+ mCameraProperties->get(CameraProperties::MAX_PICTURE_HEIGHT)) {
+ unsigned int width = 0, height = 0;
+ // Set picture size to full frame for raw bayer capture
+ width = atoi(mCameraProperties->get(CameraProperties::MAX_PICTURE_WIDTH));
+ height = atoi(mCameraProperties->get(CameraProperties::MAX_PICTURE_HEIGHT));
+ mParameters.setPictureSize(width,height);
+ }
+ mParameters.setPictureFormat(valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid picture format: %s",valstr);
+ ret = BAD_VALUE;
+ }
+ }
+
+#ifdef OMAP_ENHANCEMENT_BURST_CAPTURE
+ if ((valstr = params.get(TICameraParameters::KEY_BURST)) != NULL) {
+ if (params.getInt(TICameraParameters::KEY_BURST) >=0) {
+ CAMHAL_LOGDB("Burst set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_BURST, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Burst value: %s",valstr);
+ return BAD_VALUE;
+ }
+ }
+#endif
+
+ // Variable framerate ranges have higher priority over
+ // deprecated constant FPS.
+ // There is possible 3 situations :
+ // 1) User change FPS range and HAL use it for fps port value (don't care about
+ // changed or not const FPS).
+ // 2) User change single FPS and not change FPS range - will be applyed single FPS value
+ // to port.
+ // 3) Both FPS range and const FPS are unchanged - FPS range will be applied to port.
+
+ int curFramerate = 0;
+ bool frameRangeUpdated = false, fpsUpdated = false;
+ int curMaxFPS = 0, curMinFPS = 0, maxFPS = 0, minFPS = 0;
+
+ mParameters.getPreviewFpsRange(&curMinFPS, &curMaxFPS);
+ params.getPreviewFpsRange(&minFPS, &maxFPS);
+
+ curFramerate = mParameters.getPreviewFrameRate();
+ framerate = params.getPreviewFrameRate();
+
+ valstr = params.get(android::CameraParameters::KEY_PREVIEW_FPS_RANGE);
+ if (valstr != NULL && strlen(valstr) &&
+ ((curMaxFPS != maxFPS) || (curMinFPS != minFPS))) {
+ CAMHAL_LOGDB("## current minFPS = %d; maxFPS=%d", curMinFPS, curMaxFPS);
+ CAMHAL_LOGDB("## requested minFPS = %d; maxFPS=%d", minFPS, maxFPS);
+ if (!isFpsRangeValid(minFPS, maxFPS, params.get(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE)) &&
+ !isFpsRangeValid(minFPS, maxFPS, params.get(TICameraParameters::KEY_FRAMERATE_RANGES_EXT_SUPPORTED))) {
+ CAMHAL_LOGEA("Trying to set invalid FPS Range (%d,%d)", minFPS, maxFPS);
+ return BAD_VALUE;
+ }
+ mParameters.set(android::CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
+ CAMHAL_LOGDB("FPS Range = %s", valstr);
+ if ( curMaxFPS == (FRAME_RATE_HIGH_HD * CameraHal::VFR_SCALE) &&
+ maxFPS < (FRAME_RATE_HIGH_HD * CameraHal::VFR_SCALE) ) {
+ restartPreviewRequired = true;
+ }
+ frameRangeUpdated = true;
+ }
+
+ valstr = params.get(android::CameraParameters::KEY_PREVIEW_FRAME_RATE);
+ if (valstr != NULL && strlen(valstr) && (framerate != curFramerate)) {
+ CAMHAL_LOGD("current framerate = %d reqested framerate = %d", curFramerate, framerate);
+ if (!isParameterValid(framerate, params.get(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)) &&
+ !isParameterValid(framerate, params.get(TICameraParameters::KEY_FRAMERATES_EXT_SUPPORTED))) {
+ CAMHAL_LOGEA("Trying to set invalid frame rate %d", framerate);
+ return BAD_VALUE;
+ }
+ mParameters.setPreviewFrameRate(framerate);
+ CAMHAL_LOGDB("Set frame rate %d", framerate);
+ fpsUpdated = true;
+ }
+
+ if (frameRangeUpdated) {
+ mParameters.set(TICameraParameters::KEY_PREVIEW_FRAME_RATE_RANGE,
+ mParameters.get(android::CameraParameters::KEY_PREVIEW_FPS_RANGE));
+ } else if (fpsUpdated) {
+ char tmpBuffer[MAX_PROP_VALUE_LENGTH];
+ sprintf(tmpBuffer, "%d,%d", framerate * CameraHal::VFR_SCALE, framerate * CameraHal::VFR_SCALE);
+ mParameters.set(TICameraParameters::KEY_PREVIEW_FRAME_RATE_RANGE, tmpBuffer);
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_GBCE)) != NULL) {
+ if (strcmp(mCameraProperties->get(CameraProperties::SUPPORTED_GBCE),
+ android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGDB("GBCE %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GBCE, valstr);
+ } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGEB("ERROR: Invalid GBCE: %s", valstr);
+ return BAD_VALUE;
+ } else {
+ mParameters.set(TICameraParameters::KEY_GBCE, android::CameraParameters::FALSE);
+ }
+ } else {
+ mParameters.set(TICameraParameters::KEY_GBCE, android::CameraParameters::FALSE);
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_GLBCE)) != NULL) {
+ if (strcmp(mCameraProperties->get(CameraProperties::SUPPORTED_GLBCE),
+ android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGDB("GLBCE %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GLBCE, valstr);
+ } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
+ CAMHAL_LOGEB("ERROR: Invalid GLBCE: %s", valstr);
+ return BAD_VALUE;
+ } else {
+ mParameters.set(TICameraParameters::KEY_GLBCE, android::CameraParameters::FALSE);
+ }
+ } else {
+ mParameters.set(TICameraParameters::KEY_GLBCE, android::CameraParameters::FALSE);
+ }
+
+#ifdef OMAP_ENHANCEMENT_S3D
+ ///Update the current parameter set
+ if ( (valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE_MODE)) != NULL ) {
+ CAMHAL_LOGDB("AutoConvergence mode set = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, valstr);
+ }
+
+ if ( (valstr = params.get(TICameraParameters::KEY_MANUAL_CONVERGENCE)) != NULL ) {
+ int manualConvergence = (int)strtol(valstr, 0, 0);
+
+ if ( ( manualConvergence < strtol(mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MIN), 0, 0) ) ||
+ ( manualConvergence > strtol(mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MAX), 0, 0) ) ) {
+ CAMHAL_LOGEB("ERROR: Invalid Manual Convergence = %d", manualConvergence);
+ return BAD_VALUE;
+ } else {
+ CAMHAL_LOGDB("ManualConvergence Value = %d", manualConvergence);
+ mParameters.set(TICameraParameters::KEY_MANUAL_CONVERGENCE, valstr);
+ }
+ }
+
+ if((valstr = params.get(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION)) != NULL) {
+ if ( strcmp(mCameraProperties->get(CameraProperties::MECHANICAL_MISALIGNMENT_CORRECTION_SUPPORTED),
+ android::CameraParameters::TRUE) == 0 ) {
+ CAMHAL_LOGDB("Mechanical Mialignment Correction is %s", valstr);
+ mParameters.set(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION, valstr);
+ } else {
+ mParameters.remove(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION);
+ }
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_EXPOSURE_MODE)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES))) {
+ CAMHAL_LOGDB("Exposure mode set = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_EXPOSURE_MODE, valstr);
+ if (!strcmp(valstr, TICameraParameters::EXPOSURE_MODE_MANUAL)) {
+ int manualVal;
+ if ((valstr = params.get(TICameraParameters::KEY_MANUAL_EXPOSURE)) != NULL) {
+ manualVal = params.getInt(TICameraParameters::KEY_MANUAL_EXPOSURE);
+ if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN) ||
+ manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MAX)) {
+ CAMHAL_LOGEB("ERROR: Manual Exposure = %s is out of range - "
+ "setting minimum supported value", valstr);
+ valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN);
+ }
+ CAMHAL_LOGDB("Manual Exposure = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_MANUAL_EXPOSURE, valstr);
+ }
+ if ((valstr = params.get(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT)) != NULL) {
+ manualVal = params.getInt(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT);
+ if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN) ||
+ manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MAX)) {
+ CAMHAL_LOGEB("ERROR: Manual Exposure right = %s is out of range - "
+ "setting minimum supported value", valstr);
+ valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN);
+ }
+ CAMHAL_LOGDB("Manual Exposure right = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT, valstr);
+ }
+ if ((valstr = params.get(TICameraParameters::KEY_MANUAL_GAIN_ISO)) != NULL) {
+ manualVal = params.getInt(TICameraParameters::KEY_MANUAL_GAIN_ISO);
+ if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN) ||
+ manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX)) {
+ CAMHAL_LOGEB("ERROR: Manual Gain = %s is out of range - "
+ "setting minimum supported value", valstr);
+ valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN);
+ }
+ CAMHAL_LOGDB("Manual Gain = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_MANUAL_GAIN_ISO, valstr);
+ }
+ if ((valstr = params.get(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT)) != NULL) {
+ manualVal = params.getInt(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT);
+ if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN) ||
+ manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX)) {
+ CAMHAL_LOGEB("ERROR: Manual Gain right = %s is out of range - "
+ "setting minimum supported value", valstr);
+ valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN);
+ }
+ CAMHAL_LOGDB("Manual Gain right = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT, valstr);
+ }
+ }
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Exposure mode = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+#endif
+
+ if ((valstr = params.get(android::CameraParameters::KEY_WHITE_BALANCE)) != NULL) {
+ if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE))) {
+ CAMHAL_LOGDB("White balance set %s", valstr);
+ mParameters.set(android::CameraParameters::KEY_WHITE_BALANCE, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid white balance = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+#ifdef OMAP_ENHANCEMENT
+ if ((valstr = params.get(TICameraParameters::KEY_CONTRAST)) != NULL) {
+ if (params.getInt(TICameraParameters::KEY_CONTRAST) >= 0 ) {
+ CAMHAL_LOGDB("Contrast set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_CONTRAST, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Contrast = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if ((valstr =params.get(TICameraParameters::KEY_SHARPNESS)) != NULL) {
+ if (params.getInt(TICameraParameters::KEY_SHARPNESS) >= 0 ) {
+ CAMHAL_LOGDB("Sharpness set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_SHARPNESS, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Sharpness = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_SATURATION)) != NULL) {
+ if (params.getInt(TICameraParameters::KEY_SATURATION) >= 0 ) {
+ CAMHAL_LOGDB("Saturation set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_SATURATION, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Saturation = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if ((valstr = params.get(TICameraParameters::KEY_BRIGHTNESS)) != NULL) {
+ if (params.getInt(TICameraParameters::KEY_BRIGHTNESS) >= 0 ) {
+ CAMHAL_LOGDB("Brightness set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_BRIGHTNESS, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Brightness = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+#endif
+
+ if ((valstr = params.get(android::CameraParameters::KEY_ANTIBANDING)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING))) {
+ CAMHAL_LOGDB("Antibanding set %s", valstr);
+ mParameters.set(android::CameraParameters::KEY_ANTIBANDING, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Antibanding = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+#ifdef OMAP_ENHANCEMENT
+ if ((valstr = params.get(TICameraParameters::KEY_ISO)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES))) {
+ CAMHAL_LOGDB("ISO set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ISO, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid ISO = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+#endif
+
+ if( (valstr = params.get(android::CameraParameters::KEY_FOCUS_AREAS)) != NULL )
+ {
+ CAMHAL_LOGDB("Focus areas position set %s", params.get(android::CameraParameters::KEY_FOCUS_AREAS));
+ mParameters.set(android::CameraParameters::KEY_FOCUS_AREAS, valstr);
+ }
+
+#ifdef OMAP_ENHANCEMENT
+ if( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
+ {
+ CAMHAL_LOGDB("Measurements set to %s", valstr);
+ mParameters.set(TICameraParameters::KEY_MEASUREMENT_ENABLE, valstr);
+
+ if (strcmp(valstr, android::CameraParameters::TRUE) == 0)
+ {
+ mMeasurementEnabled = true;
+ }
+ else if (strcmp(valstr, android::CameraParameters::FALSE) == 0)
+ {
+ mMeasurementEnabled = false;
+ }
+ else
+ {
+ mMeasurementEnabled = false;
+ }
+
+ }
+#endif
+
+ if( (valstr = params.get(android::CameraParameters::KEY_EXPOSURE_COMPENSATION)) != NULL)
+ {
+ CAMHAL_LOGDB("Exposure compensation set %s", params.get(android::CameraParameters::KEY_EXPOSURE_COMPENSATION));
+ mParameters.set(android::CameraParameters::KEY_EXPOSURE_COMPENSATION, valstr);
+ }
+
+ if ((valstr = params.get(android::CameraParameters::KEY_SCENE_MODE)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES))) {
+ CAMHAL_LOGDB("Scene mode set %s", valstr);
+ doesSetParameterNeedUpdate(valstr,
+ mParameters.get(android::CameraParameters::KEY_SCENE_MODE),
+ updateRequired);
+ mParameters.set(android::CameraParameters::KEY_SCENE_MODE, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Scene mode = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if ((valstr = params.get(android::CameraParameters::KEY_FLASH_MODE)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES))) {
+ CAMHAL_LOGDB("Flash mode set %s", valstr);
+ mParameters.set(android::CameraParameters::KEY_FLASH_MODE, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Flash mode = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if ((valstr = params.get(android::CameraParameters::KEY_EFFECT)) != NULL) {
+ if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS))) {
+ CAMHAL_LOGDB("Effect set %s", valstr);
+ mParameters.set(android::CameraParameters::KEY_EFFECT, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Effect = %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ varint = params.getInt(android::CameraParameters::KEY_ROTATION);
+ if ( varint >= 0 ) {
+ CAMHAL_LOGDB("Rotation set %d", varint);
+ mParameters.set(android::CameraParameters::KEY_ROTATION, varint);
+ }
+
+ varint = params.getInt(android::CameraParameters::KEY_JPEG_QUALITY);
+ if ( varint >= 0 ) {
+ CAMHAL_LOGDB("Jpeg quality set %d", varint);
+ mParameters.set(android::CameraParameters::KEY_JPEG_QUALITY, varint);
+ }
+
+ varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
+ if ( varint >= 0 ) {
+ CAMHAL_LOGDB("Thumbnail width set %d", varint);
+ mParameters.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, varint);
+ }
+
+ varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
+ if ( varint >= 0 ) {
+ CAMHAL_LOGDB("Thumbnail width set %d", varint);
+ mParameters.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, varint);
+ }
+
+ varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+ if ( varint >= 0 ) {
+ CAMHAL_LOGDB("Thumbnail quality set %d", varint);
+ mParameters.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, varint);
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_GPS_LATITUDE)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS latitude set %s", params.get(android::CameraParameters::KEY_GPS_LATITUDE));
+ mParameters.set(android::CameraParameters::KEY_GPS_LATITUDE, valstr);
+ }else{
+ mParameters.remove(android::CameraParameters::KEY_GPS_LATITUDE);
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_GPS_LONGITUDE)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS longitude set %s", params.get(android::CameraParameters::KEY_GPS_LONGITUDE));
+ mParameters.set(android::CameraParameters::KEY_GPS_LONGITUDE, valstr);
+ }else{
+ mParameters.remove(android::CameraParameters::KEY_GPS_LONGITUDE);
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_GPS_ALTITUDE)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS altitude set %s", params.get(android::CameraParameters::KEY_GPS_ALTITUDE));
+ mParameters.set(android::CameraParameters::KEY_GPS_ALTITUDE, valstr);
+ }else{
+ mParameters.remove(android::CameraParameters::KEY_GPS_ALTITUDE);
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_GPS_TIMESTAMP)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS timestamp set %s", params.get(android::CameraParameters::KEY_GPS_TIMESTAMP));
+ mParameters.set(android::CameraParameters::KEY_GPS_TIMESTAMP, valstr);
+ }else{
+ mParameters.remove(android::CameraParameters::KEY_GPS_TIMESTAMP);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_GPS_DATESTAMP)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS datestamp set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GPS_DATESTAMP, valstr);
+ }else{
+ mParameters.remove(TICameraParameters::KEY_GPS_DATESTAMP);
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_GPS_PROCESSING_METHOD)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS processing method set %s", params.get(android::CameraParameters::KEY_GPS_PROCESSING_METHOD));
+ mParameters.set(android::CameraParameters::KEY_GPS_PROCESSING_METHOD, valstr);
+ }else{
+ mParameters.remove(android::CameraParameters::KEY_GPS_PROCESSING_METHOD);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_GPS_MAPDATUM )) != NULL )
+ {
+ CAMHAL_LOGDB("GPS MAPDATUM set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GPS_MAPDATUM, valstr);
+ }else{
+ mParameters.remove(TICameraParameters::KEY_GPS_MAPDATUM);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_GPS_VERSION)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS MAPDATUM set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GPS_VERSION, valstr);
+ }else{
+ mParameters.remove(TICameraParameters::KEY_GPS_VERSION);
+ }
+
+#ifndef MOTOROLA_CAMERA
+ if( (valstr = params.get(TICameraParameters::KEY_EXIF_MODEL)) != NULL )
+ {
+ CAMHAL_LOGDB("EXIF Model set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_EXIF_MODEL, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_EXIF_MAKE)) != NULL )
+ {
+ CAMHAL_LOGDB("EXIF Make set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_EXIF_MAKE, valstr);
+ }
+#else
+ if( (property_get("ro.product.model",value,0) > 0))
+ {
+ CAMHAL_LOGDB("EXIF Model set %s",value);
+ mParameters.set(TICameraParameters::KEY_EXIF_MODEL, value);
+ }
+
+ if( (property_get("ro.product.manufacturer",value,0) > 0) )
+ {
+ CAMHAL_LOGDB("EXIF Make set %s",value);
+ mParameters.set(TICameraParameters::KEY_EXIF_MAKE, value);
+ }
+
+ // enabled/disabled similar parameters:
+ // KEY_MOT_LEDFLASH // int: 0..100 percent
+ if((params.get(TICameraParameters::KEY_MOT_LEDFLASH) != NULL)
+ && (params.getInt(TICameraParameters::KEY_MOT_LEDFLASH) >=0)
+ && (params.getInt(TICameraParameters::KEY_MOT_LEDFLASH) <=100))
+ {
+ CAMHAL_LOGDB("Led Flash : %s",params.get(TICameraParameters::KEY_MOT_LEDFLASH));
+ mParameters.set(TICameraParameters::KEY_MOT_LEDFLASH,
+ params.get(TICameraParameters::KEY_MOT_LEDFLASH));
+ }
+
+ // KEY_MOT_LEDTORCH // int: 0..100 percent
+ if((params.get(TICameraParameters::KEY_MOT_LEDTORCH) != NULL)
+ && (params.getInt(TICameraParameters::KEY_MOT_LEDTORCH) >=0)
+ && (params.getInt(TICameraParameters::KEY_MOT_LEDTORCH) <=100))
+ {
+ CAMHAL_LOGDB("Led Torch : %s",params.get(TICameraParameters::KEY_MOT_LEDTORCH));
+ mParameters.set(TICameraParameters::KEY_MOT_LEDTORCH,
+ params.get(TICameraParameters::KEY_MOT_LEDTORCH));
+ }
+#endif
+
+#ifdef OMAP_ENHANCEMENT
+ if( (valstr = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL )
+ {
+ CAMHAL_LOGDB("Exposure Bracketing set %s", params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE));
+ mParameters.set(TICameraParameters::KEY_EXP_BRACKETING_RANGE, valstr);
+ mParameters.remove(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE);
+ }
+ else if ((valstr = params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE)) != NULL) {
+ CAMHAL_LOGDB("ABS Exposure+Gain Bracketing set %s", params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE));
+ mParameters.set(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE, valstr);
+ mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
+ } else
+ {
+ mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE)) != NULL ) {
+ CAMHAL_LOGDB("Zoom Bracketing range %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE, valstr);
+ } else {
+ mParameters.remove(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE);
+ }
+#endif
+
+ if ((valstr = params.get(android::CameraParameters::KEY_ZOOM)) != NULL ) {
+ varint = atoi(valstr);
+ if ( varint >= 0 && varint <= mMaxZoomSupported ) {
+ CAMHAL_LOGDB("Zoom set %d", varint);
+ doesSetParameterNeedUpdate(valstr,
+ mParameters.get(android::CameraParameters::KEY_ZOOM),
+ updateRequired);
+ mParameters.set(android::CameraParameters::KEY_ZOOM, valstr);
+ } else {
+ CAMHAL_LOGEB("ERROR: Invalid Zoom: %s", valstr);
+ return BAD_VALUE;
+ }
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
+ {
+ CAMHAL_LOGDB("Auto Exposure Lock set %s", valstr);
+ doesSetParameterNeedUpdate(valstr,
+ mParameters.get(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK),
+ updateRequired);
+ mParameters.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
+ }
+
+ if( (valstr = params.get(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
+ {
+ CAMHAL_LOGDB("Auto WhiteBalance Lock set %s", valstr);
+ doesSetParameterNeedUpdate(valstr,
+ mParameters.get(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK),
+ updateRequired);
+ mParameters.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
+ }
+ if( (valstr = params.get(android::CameraParameters::KEY_METERING_AREAS)) != NULL )
+ {
+ CAMHAL_LOGDB("Metering areas position set %s", params.get(android::CameraParameters::KEY_METERING_AREAS));
+ mParameters.set(android::CameraParameters::KEY_METERING_AREAS, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::RAW_WIDTH)) != NULL ) {
+ CAMHAL_LOGDB("Raw image width set %s", params.get(TICameraParameters::RAW_WIDTH));
+ mParameters.set(TICameraParameters::RAW_WIDTH, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::RAW_HEIGHT)) != NULL ) {
+ CAMHAL_LOGDB("Raw image height set %s", params.get(TICameraParameters::RAW_HEIGHT));
+ mParameters.set(TICameraParameters::RAW_HEIGHT, valstr);
+ }
+
+ //TI extensions for enable/disable algos
+ if( (valstr = params.get(TICameraParameters::KEY_ALGO_EXTERNAL_GAMMA)) != NULL )
+ {
+ CAMHAL_LOGDB("External Gamma set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ALGO_EXTERNAL_GAMMA, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_ALGO_NSF1)) != NULL )
+ {
+ CAMHAL_LOGDB("NSF1 set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ALGO_NSF1, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_ALGO_NSF2)) != NULL )
+ {
+ CAMHAL_LOGDB("NSF2 set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ALGO_NSF2, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_ALGO_SHARPENING)) != NULL )
+ {
+ CAMHAL_LOGDB("Sharpening set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ALGO_SHARPENING, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_ALGO_THREELINCOLORMAP)) != NULL )
+ {
+ CAMHAL_LOGDB("Color Conversion set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ALGO_THREELINCOLORMAP, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_ALGO_GIC)) != NULL )
+ {
+ CAMHAL_LOGDB("Green Inballance Correction set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_ALGO_GIC, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_GAMMA_TABLE)) != NULL )
+ {
+ CAMHAL_LOGDB("Manual gamma table set %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GAMMA_TABLE, valstr);
+ }
+
+ android::CameraParameters adapterParams = mParameters;
+
+#ifdef OMAP_ENHANCEMENT
+ if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS) )
+ {
+ int posBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS);
+ if ( 0 < posBracketRange )
+ {
+ mBracketRangePositive = posBracketRange;
+ }
+ }
+ CAMHAL_LOGDB("Positive bracketing range %d", mBracketRangePositive);
+
+
+ if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG) )
+ {
+ int negBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG);
+ if ( 0 < negBracketRange )
+ {
+ mBracketRangeNegative = negBracketRange;
+ }
+ }
+ CAMHAL_LOGDB("Negative bracketing range %d", mBracketRangeNegative);
+
+ if( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL) &&
+ ( strcmp(valstr, android::CameraParameters::TRUE) == 0 )) {
+ if ( !mBracketingEnabled ) {
+ CAMHAL_LOGDA("Enabling bracketing");
+ mBracketingEnabled = true;
+ } else {
+ CAMHAL_LOGDA("Bracketing already enabled");
+ }
+ adapterParams.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
+ mParameters.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
+ } else if ( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL ) &&
+ ( strcmp(valstr, android::CameraParameters::FALSE) == 0 )) {
+ CAMHAL_LOGDA("Disabling bracketing");
+
+ adapterParams.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
+ mParameters.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
+ mBracketingEnabled = false;
+ if ( mBracketingRunning ) {
+ stopImageBracketing();
+ }
+
+ } else {
+ adapterParams.remove(TICameraParameters::KEY_TEMP_BRACKETING);
+ mParameters.remove(TICameraParameters::KEY_TEMP_BRACKETING);
+ }
+#endif
+
+#ifdef OMAP_ENHANCEMENT_VTC
+ if (mVTCUseCase && !mTunnelSetup && (mCameraAdapter != NULL) &&
+ ((mParameters.get(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE)) != NULL )&&
+ ((mParameters.get(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT)) != NULL )) {
+
+ uint32_t sliceHeight = mParameters.getInt(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT);
+ uint32_t encoderHandle = mParameters.getInt(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE);
+ int w, h;
+ mParameters.getPreviewSize(&w, &h);
+ status_t done = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SETUP_TUNNEL, sliceHeight, encoderHandle, w, h);
+ if (done == NO_ERROR) mTunnelSetup = true;
+ ret |= done;
+ }
+#endif
+
+ // Only send parameters to adapter if preview is already
+ // enabled or doesSetParameterNeedUpdate says so. Initial setParameters to camera adapter,
+ // will be called in startPreview()
+ // TODO(XXX): Need to identify other parameters that need update from camera adapter
+ if ( (NULL != mCameraAdapter) &&
+ (mPreviewEnabled || updateRequired) &&
+ (!(mPreviewEnabled && restartPreviewRequired)) ) {
+ ret |= mCameraAdapter->setParameters(adapterParams);
+ }
+
+#ifdef OMAP_ENHANCEMENT
+ if( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
+ ( strcmp(valstr, android::CameraParameters::TRUE) == 0 ))
+ {
+ CAMHAL_LOGDA("Enabling shutter sound");
+
+ mShutterEnabled = true;
+ mMsgEnabled |= CAMERA_MSG_SHUTTER;
+ mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
+ }
+ else if ( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
+ ( strcmp(valstr, android::CameraParameters::FALSE) == 0 ))
+ {
+ CAMHAL_LOGDA("Disabling shutter sound");
+
+ mShutterEnabled = false;
+ mMsgEnabled &= ~CAMERA_MSG_SHUTTER;
+ mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
+ }
+#endif
+ }
+
+ //On fail restore old parameters
+ if ( NO_ERROR != ret ) {
+ mParameters = oldParams;
+ }
+
+ // Restart Preview if needed by KEY_RECODING_HINT only if preview is already running.
+ // If preview is not started yet, Video Mode parameters will take effect on next startPreview()
+ if (restartPreviewRequired && previewEnabled() && !mRecordingEnabled) {
+ CAMHAL_LOGDA("Restarting Preview");
+ ret = restartPreview();
+ } else if (restartPreviewRequired && !previewEnabled() &&
+ mDisplayPaused && !mRecordingEnabled) {
+ CAMHAL_LOGDA("Restarting preview in paused mode");
+ ret = restartPreview();
+
+ // TODO(XXX): If there is some delay between the restartPreview call and the code
+ // below, then the user could see some preview frames and callbacks. Let's find
+ // a better place to put this later...
+ if (ret == NO_ERROR) {
+ mDisplayPaused = true;
+ mPreviewEnabled = false;
+ ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
+ }
+ }
+
+ if ( !mBracketingRunning && mBracketingEnabled ) {
+ startImageBracketing();
+ }
+
+ if (ret != NO_ERROR)
+ {
+ CAMHAL_LOGEA("Failed to restart Preview");
+ return ret;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::allocPreviewBufs(int width, int height, const char* previewFormat,
+ unsigned int buffercount, unsigned int &max_queueable)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if(mDisplayAdapter.get() == NULL)
+ {
+ // Memory allocation of preview buffers is now placed in gralloc
+ // CameraHal should not allocate preview buffers without DisplayAdapter
+ return NO_MEMORY;
+ }
+
+ if(!mPreviewBuffers)
+ {
+ mPreviewLength = 0;
+ mPreviewBuffers = mDisplayAdapter->allocateBufferList(width, height,
+ previewFormat,
+ mPreviewLength,
+ buffercount);
+ if (NULL == mPreviewBuffers ) {
+ CAMHAL_LOGEA("Couldn't allocate preview buffers");
+ return NO_MEMORY;
+ }
+
+ mPreviewOffsets = (uint32_t *) mDisplayAdapter->getOffsets();
+ if ( NULL == mPreviewOffsets ) {
+ CAMHAL_LOGEA("Buffer mapping failed");
+ return BAD_VALUE;
+ }
+
+ mBufProvider = (BufferProvider*) mDisplayAdapter.get();
+
+ ret = mDisplayAdapter->maxQueueableBuffers(max_queueable);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::freePreviewBufs()
+{
+ status_t ret = NO_ERROR;
+ LOG_FUNCTION_NAME;
+
+ CAMHAL_LOGDB("mPreviewBuffers = %p", mPreviewBuffers);
+ if(mPreviewBuffers)
+ {
+ ret = mBufProvider->freeBufferList(mPreviewBuffers);
+ mPreviewBuffers = NULL;
+ LOG_FUNCTION_NAME_EXIT;
+ return ret;
+ }
+ LOG_FUNCTION_NAME_EXIT;
+ return ret;
+}
+
+
+status_t CameraHal::allocPreviewDataBufs(size_t size, size_t bufferCount)
+{
+ status_t ret = NO_ERROR;
+ int bytes;
+
+ LOG_FUNCTION_NAME;
+
+ bytes = size;
+
+ if ( NO_ERROR == ret )
+ {
+ if( NULL != mPreviewDataBuffers )
+ {
+ ret = freePreviewDataBufs();
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ bytes = ((bytes+4095)/4096)*4096;
+ mPreviewDataBuffers = mMemoryManager->allocateBufferList(0, 0, NULL, bytes, bufferCount);
+
+ CAMHAL_LOGDB("Size of Preview data buffer = %d", bytes);
+ if( NULL == mPreviewDataBuffers )
+ {
+ CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
+ ret = -NO_MEMORY;
+ }
+ else
+ {
+ bytes = size;
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mPreviewDataFd = mMemoryManager->getFd();
+ mPreviewDataLength = bytes;
+ mPreviewDataOffsets = mMemoryManager->getOffsets();
+ }
+ else
+ {
+ mPreviewDataFd = -1;
+ mPreviewDataLength = 0;
+ mPreviewDataOffsets = NULL;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::freePreviewDataBufs()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NO_ERROR == ret )
+ {
+
+ if( NULL != mPreviewDataBuffers )
+ {
+
+ ret = mMemoryManager->freeBufferList(mPreviewDataBuffers);
+ mPreviewDataBuffers = NULL;
+
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size_t size,
+ const char* previewFormat, unsigned int bufferCount)
+{
+ status_t ret = NO_ERROR;
+ int bytes = size;
+
+ LOG_FUNCTION_NAME;
+
+ // allocate image buffers only if not already allocated
+ if(NULL != mImageBuffers) {
+ return NO_ERROR;
+ }
+
+ if ( NO_ERROR == ret ) {
+ bytes = ((bytes+4095)/4096)*4096;
+ mImageBuffers = mMemoryManager->allocateBufferList(0, 0, previewFormat, bytes, bufferCount);
+ CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
+ if( NULL == mImageBuffers ) {
+ CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
+ ret = -NO_MEMORY;
+ } else {
+ bytes = size;
+ }
+ }
+
+ if ( NO_ERROR == ret ) {
+ mImageFd = mMemoryManager->getFd();
+ mImageLength = bytes;
+ mImageOffsets = mMemoryManager->getOffsets();
+ mImageCount = bufferCount;
+ } else {
+ mImageFd = -1;
+ mImageLength = 0;
+ mImageOffsets = NULL;
+ mImageCount = 0;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::allocVideoBufs(uint32_t width, uint32_t height, uint32_t bufferCount)
+{
+ status_t ret = NO_ERROR;
+ LOG_FUNCTION_NAME;
+
+ if( NULL != mVideoBuffers ){
+ ret = freeVideoBufs(mVideoBuffers);
+ mVideoBuffers = NULL;
+ }
+
+ if ( NO_ERROR == ret ){
+ int32_t stride;
+ CameraBuffer *buffers = new CameraBuffer [bufferCount];
+
+ memset (buffers, 0, sizeof(CameraBuffer) * bufferCount);
+
+ if (buffers != NULL){
+ for (unsigned int i = 0; i< bufferCount; i++){
+ android::GraphicBufferAllocator &GrallocAlloc = android::GraphicBufferAllocator::get();
+ buffer_handle_t handle;
+ ret = GrallocAlloc.alloc(width, height, HAL_PIXEL_FORMAT_NV12, CAMHAL_GRALLOC_USAGE, &handle, &stride);
+ if (ret != NO_ERROR){
+ CAMHAL_LOGEA("Couldn't allocate video buffers using Gralloc");
+ ret = -NO_MEMORY;
+ for (unsigned int j=0; j< i; j++){
+ CAMHAL_LOGEB("Freeing Gralloc Buffer %p", buffers[i].opaque);
+ GrallocAlloc.free((buffer_handle_t)buffers[i].opaque);
+ }
+ delete [] buffers;
+ goto exit;
+ }
+ buffers[i].type = CAMERA_BUFFER_GRALLOC;
+ buffers[i].opaque = (void *)handle;
+ CAMHAL_LOGVB("*** Gralloc Handle =0x%x ***", handle);
+ }
+
+ mVideoBuffers = buffers;
+ }
+ else{
+ CAMHAL_LOGEA("Couldn't allocate video buffers ");
+ ret = -NO_MEMORY;
+ }
+ }
+
+ exit:
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::allocRawBufs(int width, int height, const char* previewFormat, int bufferCount)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME
+
+
+ ///@todo Enhance this method allocImageBufs() to take in a flag for burst capture
+ ///Always allocate the buffers for image capture using MemoryManager
+ if (NO_ERROR == ret) {
+ if(( NULL != mVideoBuffers )) {
+ // Re-use the buffer for raw capture.
+ return ret;
+ }
+ }
+
+ if ( NO_ERROR == ret ) {
+ mVideoLength = 0;
+ mVideoLength = (((width * height * 2) + 4095)/4096)*4096;
+ mVideoBuffers = mMemoryManager->allocateBufferList(width, height, previewFormat,
+ mVideoLength, bufferCount);
+
+ CAMHAL_LOGDB("Size of Video cap buffer (used for RAW capture) %d", mVideoLength);
+ if( NULL == mVideoBuffers ) {
+ CAMHAL_LOGEA("Couldn't allocate Video buffers using memory manager");
+ ret = -NO_MEMORY;
+ }
+ }
+
+ if ( NO_ERROR == ret ) {
+ mVideoFd = mMemoryManager->getFd();
+ mVideoOffsets = mMemoryManager->getOffsets();
+ } else {
+ mVideoFd = -1;
+ mVideoOffsets = NULL;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+void endImageCapture( void *userData)
+{
+ LOG_FUNCTION_NAME;
+
+ if ( NULL != userData )
+ {
+ CameraHal *c = reinterpret_cast<CameraHal *>(userData);
+ c->signalEndImageCapture();
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+void releaseImageBuffers(void *userData)
+{
+ LOG_FUNCTION_NAME;
+
+ if (NULL != userData) {
+ CameraHal *c = reinterpret_cast<CameraHal *>(userData);
+ c->freeImageBufs();
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+status_t CameraHal::signalEndImageCapture()
+{
+ status_t ret = NO_ERROR;
+ int w,h;
+ android::AutoMutex lock(mLock);
+
+ LOG_FUNCTION_NAME;
+
+ if (mBufferSourceAdapter_Out.get()) {
+ mBufferSourceAdapter_Out->disableDisplay();
+ }
+
+ if (mBufferSourceAdapter_In.get()) {
+ mBufferSourceAdapter_In->disableDisplay();
+ }
+
+ if ( mBracketingRunning ) {
+ stopImageBracketing();
+ } else {
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::freeImageBufs()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if (NULL == mImageBuffers) {
+ return -EINVAL;
+ }
+
+ if (mBufferSourceAdapter_Out.get()) {
+ mBufferSourceAdapter_Out = 0;
+ } else {
+ ret = mMemoryManager->freeBufferList(mImageBuffers);
+ }
+
+ mImageBuffers = NULL;
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::freeVideoBufs(CameraBuffer *bufs)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
+ if(bufs == NULL)
+ {
+ CAMHAL_LOGEA("NULL pointer passed to freeVideoBuffer");
+ LOG_FUNCTION_NAME_EXIT;
+ return BAD_VALUE;
+ }
+
+ android::GraphicBufferAllocator &GrallocAlloc = android::GraphicBufferAllocator::get();
+
+ for(int i = 0; i < count; i++){
+ CAMHAL_LOGVB("Free Video Gralloc Handle 0x%x", bufs[i].opaque);
+ GrallocAlloc.free((buffer_handle_t)bufs[i].opaque);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::freeRawBufs()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME
+
+ if ( NO_ERROR == ret ) {
+ if( NULL != mVideoBuffers ) {
+ ///@todo Pluralise the name of this method to freeBuffers
+ ret = mMemoryManager->freeBufferList(mVideoBuffers);
+ mVideoBuffers = NULL;
+ } else {
+ ret = -EINVAL;
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT
+
+ return ret;
+}
+
+/**
+ @brief Start preview mode.
+
+ @param none
+ @return NO_ERROR Camera switched to VF mode
+ @todo Update function header with the different errors that are possible
+
+ */
+status_t CameraHal::startPreview() {
+ LOG_FUNCTION_NAME;
+
+ // When tunneling is enabled during VTC, startPreview happens in 2 steps:
+ // When the application sends the command CAMERA_CMD_PREVIEW_INITIALIZATION,
+ // cameraPreviewInitialization() is called, which in turn causes the CameraAdapter
+ // to move from loaded to idle state. And when the application calls startPreview,
+ // the CameraAdapter moves from idle to executing state.
+ //
+ // If the application calls startPreview() without sending the command
+ // CAMERA_CMD_PREVIEW_INITIALIZATION, then the function cameraPreviewInitialization()
+ // AND startPreview() are executed. In other words, if the application calls
+ // startPreview() without sending the command CAMERA_CMD_PREVIEW_INITIALIZATION,
+ // then the CameraAdapter moves from loaded to idle to executing state in one shot.
+ status_t ret = cameraPreviewInitialization();
+
+ // The flag mPreviewInitializationDone is set to true at the end of the function
+ // cameraPreviewInitialization(). Therefore, if everything goes alright, then the
+ // flag will be set. Sometimes, the function cameraPreviewInitialization() may
+ // return prematurely if all the resources are not available for starting preview.
+ // For example, if the preview window is not set, then it would return NO_ERROR.
+ // Under such circumstances, one should return from startPreview as well and should
+ // not continue execution. That is why, we check the flag and not the return value.
+ if (!mPreviewInitializationDone) return ret;
+
+ // Once startPreview is called, there is no need to continue to remember whether
+ // the function cameraPreviewInitialization() was called earlier or not. And so
+ // the flag mPreviewInitializationDone is reset here. Plus, this preserves the
+ // current behavior of startPreview under the circumstances where the application
+ // calls startPreview twice or more.
+ mPreviewInitializationDone = false;
+
+ ///Enable the display adapter if present, actual overlay enable happens when we post the buffer
+ if(mDisplayAdapter.get() != NULL) {
+ CAMHAL_LOGDA("Enabling display");
+ int width, height;
+ mParameters.getPreviewSize(&width, &height);
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+ ret = mDisplayAdapter->enableDisplay(width, height, &mStartPreview);
+#else
+ ret = mDisplayAdapter->enableDisplay(width, height, NULL);
+#endif
+
+ if ( ret != NO_ERROR ) {
+ CAMHAL_LOGEA("Couldn't enable display");
+
+ // FIXME: At this stage mStateSwitchLock is locked and unlock is supposed to be called
+ // only from mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW)
+ // below. But this will never happen because of goto error. Thus at next
+ // startPreview() call CameraHAL will be deadlocked.
+ // Need to revisit mStateSwitch lock, for now just abort the process.
+ CAMHAL_ASSERT_X(false,
+ "At this stage mCameraAdapter->mStateSwitchLock is still locked, "
+ "deadlock is guaranteed");
+
+ goto error;
+ }
+
+ }
+
+ ///Send START_PREVIEW command to adapter
+ CAMHAL_LOGDA("Starting CameraAdapter preview mode");
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW);
+
+ if(ret!=NO_ERROR) {
+ CAMHAL_LOGEA("Couldn't start preview w/ CameraAdapter");
+ goto error;
+ }
+ CAMHAL_LOGDA("Started preview");
+
+ mPreviewEnabled = true;
+ mPreviewStartInProgress = false;
+ return ret;
+
+ error:
+
+ CAMHAL_LOGEA("Performing cleanup after error");
+
+ //Do all the cleanup
+ freePreviewBufs();
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
+ if(mDisplayAdapter.get() != NULL) {
+ mDisplayAdapter->disableDisplay(false);
+ }
+ mAppCallbackNotifier->stop();
+ mPreviewStartInProgress = false;
+ mPreviewEnabled = false;
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+////////////
+/**
+ @brief Set preview mode related initialization
+ -> Camera Adapter set params
+ -> Allocate buffers
+ -> Set use buffers for preview
+ @param none
+ @return NO_ERROR
+ @todo Update function header with the different errors that are possible
+
+ */
+status_t CameraHal::cameraPreviewInitialization()
+{
+
+ status_t ret = NO_ERROR;
+ CameraAdapter::BuffersDescriptor desc;
+ CameraFrame frame;
+ unsigned int required_buffer_count;
+ unsigned int max_queueble_buffers;
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+ gettimeofday(&mStartPreview, NULL);
+#endif
+
+ LOG_FUNCTION_NAME;
+
+ if (mPreviewInitializationDone) {
+ return NO_ERROR;
+ }
+
+ if ( mPreviewEnabled ){
+ CAMHAL_LOGDA("Preview already running");
+ LOG_FUNCTION_NAME_EXIT;
+ return ALREADY_EXISTS;
+ }
+
+ if ( NULL != mCameraAdapter ) {
+ ret = mCameraAdapter->setParameters(mParameters);
+ }
+
+ if ((mPreviewStartInProgress == false) && (mDisplayPaused == false)){
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW,( int ) &frame);
+ if ( NO_ERROR != ret ){
+ CAMHAL_LOGEB("Error: CAMERA_QUERY_RESOLUTION_PREVIEW %d", ret);
+ return ret;
+ }
+
+ ///Update the current preview width and height
+ mPreviewWidth = frame.mWidth;
+ mPreviewHeight = frame.mHeight;
+ }
+
+ ///If we don't have the preview callback enabled and display adapter,
+ if(!mSetPreviewWindowCalled || (mDisplayAdapter.get() == NULL)){
+ CAMHAL_LOGD("Preview not started. Preview in progress flag set");
+ mPreviewStartInProgress = true;
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SWITCH_TO_EXECUTING);
+ if ( NO_ERROR != ret ){
+ CAMHAL_LOGEB("Error: CAMERA_SWITCH_TO_EXECUTING %d", ret);
+ return ret;
+ }
+ return NO_ERROR;
+ }
+
+ if( (mDisplayAdapter.get() != NULL) && ( !mPreviewEnabled ) && ( mDisplayPaused ) )
+ {
+ CAMHAL_LOGDA("Preview is in paused state");
+
+ mDisplayPaused = false;
+ mPreviewEnabled = true;
+ if ( NO_ERROR == ret )
+ {
+ ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
+
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("Display adapter resume failed %x", ret);
+ }
+ }
+ //restart preview callbacks
+ if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
+ {
+ mAppCallbackNotifier->enableMsgType (CAMERA_MSG_PREVIEW_FRAME);
+ }
+
+ signalEndImageCapture();
+ return ret;
+ }
+
+ required_buffer_count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
+
+ ///Allocate the preview buffers
+ ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count, max_queueble_buffers);
+
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEA("Couldn't allocate buffers for Preview");
+ goto error;
+ }
+
+ if ( mMeasurementEnabled )
+ {
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA,
+ ( int ) &frame,
+ required_buffer_count);
+ if ( NO_ERROR != ret )
+ {
+ return ret;
+ }
+
+ ///Allocate the preview data buffers
+ ret = allocPreviewDataBufs(frame.mLength, required_buffer_count);
+ if ( NO_ERROR != ret ) {
+ CAMHAL_LOGEA("Couldn't allocate preview data buffers");
+ goto error;
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ desc.mBuffers = mPreviewDataBuffers;
+ desc.mOffsets = mPreviewDataOffsets;
+ desc.mFd = mPreviewDataFd;
+ desc.mLength = mPreviewDataLength;
+ desc.mCount = ( size_t ) required_buffer_count;
+ desc.mMaxQueueable = (size_t) required_buffer_count;
+
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW_DATA,
+ ( int ) &desc);
+ }
+
+ }
+
+ ///Pass the buffers to Camera Adapter
+ desc.mBuffers = mPreviewBuffers;
+ desc.mOffsets = mPreviewOffsets;
+ desc.mFd = mPreviewFd;
+ desc.mLength = mPreviewLength;
+ desc.mCount = ( size_t ) required_buffer_count;
+ desc.mMaxQueueable = (size_t) max_queueble_buffers;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW,
+ ( int ) &desc);
+
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("Failed to register preview buffers: 0x%x", ret);
+ freePreviewBufs();
+ return ret;
+ }
+
+ ///Start the callback notifier
+ ret = mAppCallbackNotifier->start();
+
+ if( ALREADY_EXISTS == ret )
+ {
+ //Already running, do nothing
+ CAMHAL_LOGDA("AppCallbackNotifier already running");
+ ret = NO_ERROR;
+ }
+ else if ( NO_ERROR == ret ) {
+ CAMHAL_LOGDA("Started AppCallbackNotifier..");
+ mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
+ }
+ else
+ {
+ CAMHAL_LOGDA("Couldn't start AppCallbackNotifier");
+ goto error;
+ }
+
+ if (ret == NO_ERROR) mPreviewInitializationDone = true;
+
+ mAppCallbackNotifier->startPreviewCallbacks(mParameters, mPreviewBuffers, mPreviewOffsets, mPreviewFd, mPreviewLength, required_buffer_count);
+
+ return ret;
+
+ error:
+
+ CAMHAL_LOGEA("Performing cleanup after error");
+
+ //Do all the cleanup
+ freePreviewBufs();
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
+ if(mDisplayAdapter.get() != NULL)
+ {
+ mDisplayAdapter->disableDisplay(false);
+ }
+ mAppCallbackNotifier->stop();
+ mPreviewStartInProgress = false;
+ mPreviewEnabled = false;
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Sets ANativeWindow object.
+
+ Preview buffers provided to CameraHal via this object. DisplayAdapter will be interfacing with it
+ to render buffers to display.
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window)
+{
+ status_t ret = NO_ERROR;
+ CameraAdapter::BuffersDescriptor desc;
+
+ LOG_FUNCTION_NAME;
+ mSetPreviewWindowCalled = true;
+
+ ///If the Camera service passes a null window, we destroy existing window and free the DisplayAdapter
+ if(!window)
+ {
+ if(mDisplayAdapter.get() != NULL)
+ {
+ ///NULL window passed, destroy the display adapter if present
+ CAMHAL_LOGD("NULL window passed, destroying display adapter");
+ mDisplayAdapter.clear();
+ ///@remarks If there was a window previously existing, we usually expect another valid window to be passed by the client
+ ///@remarks so, we will wait until it passes a valid window to begin the preview again
+ mSetPreviewWindowCalled = false;
+ }
+ CAMHAL_LOGD("NULL ANativeWindow passed to setPreviewWindow");
+ return NO_ERROR;
+ }else if(mDisplayAdapter.get() == NULL)
+ {
+ // Need to create the display adapter since it has not been created
+ // Create display adapter
+ ANativeWindowDisplayAdapter* displayAdapter = new ANativeWindowDisplayAdapter();
+ displayAdapter->setExternalLocking(mExternalLocking);
+ if (NULL != mAppCallbackNotifier.get()) {
+ mAppCallbackNotifier->setExternalLocking(mExternalLocking);
+ } else {
+ CAMHAL_LOGE("Can't apply locking policy on AppCallbackNotifier");
+ CAMHAL_ASSERT(0);
+ }
+ mDisplayAdapter = displayAdapter;
+#ifdef OMAP_ENHANCEMENT_CPCAM
+ mDisplayAdapter->setExtendedOps(mExtendedPreviewStreamOps);
+#endif
+ ret = NO_ERROR;
+ if(!mDisplayAdapter.get() || ((ret=mDisplayAdapter->initialize())!=NO_ERROR))
+ {
+ if(ret!=NO_ERROR)
+ {
+ mDisplayAdapter.clear();
+ CAMHAL_LOGEA("DisplayAdapter initialize failed");
+ LOG_FUNCTION_NAME_EXIT;
+ return ret;
+ }
+ else
+ {
+ CAMHAL_LOGEA("Couldn't create DisplayAdapter");
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_MEMORY;
+ }
+ }
+
+ // DisplayAdapter needs to know where to get the CameraFrames from inorder to display
+ // Since CameraAdapter is the one that provides the frames, set it as the frame provider for DisplayAdapter
+ mDisplayAdapter->setFrameProvider(mCameraAdapter);
+
+ // Any dynamic errors that happen during the camera use case has to be propagated back to the application
+ // via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that notifies such errors to the application
+ // Set it as the error handler for the DisplayAdapter
+ mDisplayAdapter->setErrorHandler(mAppCallbackNotifier.get());
+
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = mDisplayAdapter->setPreviewWindow(window);
+ if(ret!=NO_ERROR)
+ {
+ CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
+ }
+
+ if(mPreviewStartInProgress)
+ {
+ CAMHAL_LOGDA("setPreviewWindow called when preview running");
+ // Start the preview since the window is now available
+ ret = startPreview();
+ }
+ } else {
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = mDisplayAdapter->setPreviewWindow(window);
+ if ( (NO_ERROR == ret) && previewEnabled() ) {
+ restartPreview();
+ } else if (ret == ALREADY_EXISTS) {
+ // ALREADY_EXISTS should be treated as a noop in this case
+ ret = NO_ERROR;
+ }
+ }
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+
+}
+
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+void CameraHal::setExtendedPreviewStreamOps(preview_stream_extended_ops_t *ops)
+{
+ mExtendedPreviewStreamOps = ops;
+}
+
+/**
+ @brief Sets Tapout Surfaces.
+
+ Buffers provided to CameraHal via this object for tap-out
+ functionality.
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::setTapoutLocked(struct preview_stream_ops *tapout)
+{
+ status_t ret = NO_ERROR;
+ int index = -1;
+
+ LOG_FUNCTION_NAME;
+
+ if (!tapout) {
+ CAMHAL_LOGD("Missing argument");
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_ERROR;
+ }
+
+ // Set tapout point
+ // 1. Check name of tap-out
+ // 2. If not already set, then create a new one
+ // 3. Allocate buffers. If user is re-setting the surface, free buffers first and re-allocate
+ // in case dimensions have changed
+
+ for (unsigned int i = 0; i < mOutAdapters.size(); i++) {
+ android::sp<DisplayAdapter> out;
+ out = mOutAdapters.itemAt(i);
+ ret = out->setPreviewWindow(tapout);
+ if (ret == ALREADY_EXISTS) {
+ CAMHAL_LOGD("Tap Out already set at index = %d", i);
+ index = i;
+ ret = NO_ERROR;
+ }
+ }
+
+ if (index < 0) {
+ android::sp<DisplayAdapter> out = new BufferSourceAdapter();
+
+ ret = out->initialize();
+ if (ret != NO_ERROR) {
+ out.clear();
+ CAMHAL_LOGEA("DisplayAdapter initialize failed");
+ goto exit;
+ }
+
+ // BufferSourceAdapter will be handler of the extended OPS
+ out->setExtendedOps(mExtendedPreviewStreamOps);
+
+ // CameraAdapter will be the frame provider for BufferSourceAdapter
+ out->setFrameProvider(mCameraAdapter);
+
+ // BufferSourceAdapter will use ErrorHandler to send errors back to
+ // the application
+ out->setErrorHandler(mAppCallbackNotifier.get());
+
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = out->setPreviewWindow(tapout);
+ if(ret != NO_ERROR) {
+ CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
+ goto exit;
+ }
+
+ if (NULL != mCameraAdapter) {
+ unsigned int bufferCount, max_queueable;
+ CameraFrame frame;
+
+ bufferCount = out->getBufferCount();
+ if (bufferCount < 1) bufferCount = NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
+ ( int ) &frame,
+ bufferCount);
+ if (NO_ERROR != ret) {
+ CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
+ }
+ if (NO_ERROR == ret) {
+ CameraBuffer *bufs = NULL;
+ unsigned int stride;
+ unsigned int height = frame.mHeight;
+ int size = frame.mLength;
+
+ stride = frame.mAlignment / getBPP(mParameters.getPictureFormat());
+ bufs = out->allocateBufferList(stride,
+ height,
+ mParameters.getPictureFormat(),
+ size,
+ bufferCount);
+ if (bufs == NULL){
+ CAMHAL_LOGEB("error allocating buffer list");
+ goto exit;
+ }
+ }
+ }
+ mOutAdapters.add(out);
+ }
+
+exit:
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Releases Tapout Surfaces.
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::releaseTapoutLocked(struct preview_stream_ops *tapout)
+{
+ status_t ret = NO_ERROR;
+ char id[OP_STR_SIZE];
+
+ LOG_FUNCTION_NAME;
+
+ if (!tapout) {
+ CAMHAL_LOGD("Missing argument");
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_ERROR;
+ }
+
+ // Get the name of tapout
+ ret = mExtendedPreviewStreamOps->get_id(tapout, id, sizeof(id));
+ if (NO_ERROR != ret) {
+ CAMHAL_LOGEB("get_id OPS returned error %d", ret);
+ return ret;
+ }
+
+ // 1. Check name of tap-out
+ // 2. If exist, then free buffers and then remove it
+ if (mBufferSourceAdapter_Out.get() && mBufferSourceAdapter_Out->match(id)) {
+ CAMHAL_LOGD("REMOVE tap out %p previously set as current", tapout);
+ mBufferSourceAdapter_Out.clear();
+ }
+ for (unsigned int i = 0; i < mOutAdapters.size(); i++) {
+ android::sp<DisplayAdapter> out;
+ out = mOutAdapters.itemAt(i);
+ if (out->match(id)) {
+ CAMHAL_LOGD("REMOVE tap out %p \"%s\" at position %d", tapout, id, i);
+ mOutAdapters.removeAt(i);
+ break;
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Sets Tapin Surfaces.
+
+ Buffers provided to CameraHal via this object for tap-in
+ functionality.
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::setTapinLocked(struct preview_stream_ops *tapin)
+{
+ status_t ret = NO_ERROR;
+ int index = -1;
+
+ LOG_FUNCTION_NAME;
+
+ if (!tapin) {
+ CAMHAL_LOGD("Missing argument");
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_ERROR;
+ }
+
+ // 1. Set tapin point
+ // 1. Check name of tap-in
+ // 2. If not already set, then create a new one
+ // 3. Allocate buffers. If user is re-setting the surface, free buffers first and re-allocate
+ // in case dimensions have changed
+ for (unsigned int i = 0; i < mInAdapters.size(); i++) {
+ android::sp<DisplayAdapter> in;
+ in = mInAdapters.itemAt(i);
+ ret = in->setPreviewWindow(tapin);
+ if (ret == ALREADY_EXISTS) {
+ CAMHAL_LOGD("Tap In already set at index = %d", i);
+ index = i;
+ ret = NO_ERROR;
+ }
+ }
+
+ if (index < 0) {
+ android::sp<DisplayAdapter> in = new BufferSourceAdapter();
+
+ ret = in->initialize();
+ if (ret != NO_ERROR) {
+ in.clear();
+ CAMHAL_LOGEA("DisplayAdapter initialize failed");
+ goto exit;
+ }
+
+ // BufferSourceAdapter will be handler of the extended OPS
+ in->setExtendedOps(mExtendedPreviewStreamOps);
+
+ // CameraAdapter will be the frame provider for BufferSourceAdapter
+ in->setFrameProvider(mCameraAdapter);
+
+ // BufferSourceAdapter will use ErrorHandler to send errors back to
+ // the application
+ in->setErrorHandler(mAppCallbackNotifier.get());
+
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = in->setPreviewWindow(tapin);
+ if(ret != NO_ERROR) {
+ CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
+ goto exit;
+ }
+
+ mInAdapters.add(in);
+ }
+
+exit:
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+
+/**
+ @brief Releases Tapin Surfaces.
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::releaseTapinLocked(struct preview_stream_ops *tapin)
+{
+ status_t ret = NO_ERROR;
+ char id[OP_STR_SIZE];
+
+ LOG_FUNCTION_NAME;
+
+ if (!tapin) {
+ CAMHAL_LOGD("Missing argument");
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_ERROR;
+ }
+
+ // Get the name of tapin
+ ret = mExtendedPreviewStreamOps->get_id(tapin, id, sizeof(id));
+ if (NO_ERROR != ret) {
+ CAMHAL_LOGEB("get_id OPS returned error %d", ret);
+ return ret;
+ }
+
+ // 1. Check name of tap-in
+ // 2. If exist, then free buffers and then remove it
+ if (mBufferSourceAdapter_In.get() && mBufferSourceAdapter_In->match(id)) {
+ CAMHAL_LOGD("REMOVE tap in %p previously set as current", tapin);
+ mBufferSourceAdapter_In.clear();
+ }
+ for (unsigned int i = 0; i < mInAdapters.size(); i++) {
+ android::sp<DisplayAdapter> in;
+ in = mInAdapters.itemAt(i);
+ if (in->match(id)) {
+ CAMHAL_LOGD("REMOVE tap in %p \"%s\" at position %d", tapin, id, i);
+ mInAdapters.removeAt(i);
+ break;
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+
+/**
+ @brief Sets ANativeWindow object.
+
+ Buffers provided to CameraHal via this object for tap-in/tap-out
+ functionality.
+
+ TODO(XXX): this is just going to use preview_stream_ops for now, but we
+ most likely need to extend it when we want more functionality
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::setBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout)
+{
+ status_t ret = NO_ERROR;
+ int index = -1;
+
+ LOG_FUNCTION_NAME;
+
+ android::AutoMutex lock(mLock);
+
+ CAMHAL_LOGD ("setBufferSource(%p, %p)", tapin, tapout);
+
+ ret = setTapoutLocked(tapout);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("setTapoutLocked returned error 0x%x", ret);
+ goto exit;
+ }
+
+ ret = setTapinLocked(tapin);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("setTapinLocked returned error 0x%x", ret);
+ goto exit;
+ }
+
+exit:
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+
+/**
+ @brief Releases ANativeWindow object.
+
+ Release Buffers previously released with setBufferSource()
+
+ TODO(XXX): this is just going to use preview_stream_ops for now, but we
+ most likely need to extend it when we want more functionality
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::releaseBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout)
+{
+ status_t ret = NO_ERROR;
+ int index = -1;
+
+ LOG_FUNCTION_NAME;
+
+ android::AutoMutex lock(mLock);
+ CAMHAL_LOGD ("releaseBufferSource(%p, %p)", tapin, tapout);
+ if (tapout) {
+ ret |= releaseTapoutLocked(tapout);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("Error %d to release tap out", ret);
+ }
+ }
+
+ if (tapin) {
+ ret |= releaseTapinLocked(tapin);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("Error %d to release tap in", ret);
+ }
+ }
+
+exit:
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+#endif
+
+
+/**
+ @brief Stop a previously started preview.
+
+ @param none
+ @return none
+
+ */
+void CameraHal::stopPreview()
+{
+ LOG_FUNCTION_NAME;
+
+ if( (!previewEnabled() && !mDisplayPaused) || mRecordingEnabled)
+ {
+ LOG_FUNCTION_NAME_EXIT;
+ return;
+ }
+
+ bool imageCaptureRunning = (mCameraAdapter->getState() & CameraAdapter::CAPTURE_STATE) &&
+ (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE);
+ if(mDisplayPaused && !imageCaptureRunning)
+ {
+ // Display is paused, which essentially means there is no preview active.
+ // Note: this is done so that when stopPreview is called by client after
+ // an image capture, we do not de-initialize the camera adapter and
+ // restart over again.
+
+ return;
+ }
+
+ forceStopPreview();
+
+ // Reset Capture-Mode to default, so that when we switch from VideoRecording
+ // to ImageCapture, CAPTURE_MODE is not left to VIDEO_MODE.
+ CAMHAL_LOGDA("Resetting Capture-Mode to default");
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Returns true if preview is enabled
+
+ @param none
+ @return true If preview is running currently
+ false If preview has been stopped
+
+ */
+bool CameraHal::previewEnabled()
+{
+ LOG_FUNCTION_NAME;
+
+ return (mPreviewEnabled || mPreviewStartInProgress);
+}
+
+/**
+ @brief Start record mode.
+
+ When a record image is available a CAMERA_MSG_VIDEO_FRAME message is sent with
+ the corresponding frame. Every record frame must be released by calling
+ releaseRecordingFrame().
+
+ @param none
+ @return NO_ERROR If recording could be started without any issues
+ @todo Update the header with possible error values in failure scenarios
+
+ */
+status_t CameraHal::startRecording( )
+{
+ int w, h;
+ const char *valstr = NULL;
+ bool restartPreviewRequired = false;
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&mStartPreview, NULL);
+
+#endif
+
+ if(!previewEnabled())
+ {
+ return NO_INIT;
+ }
+
+ // set internal recording hint in case camera adapter needs to make some
+ // decisions....(will only be sent to camera adapter if camera restart is required)
+ mParameters.set(TICameraParameters::KEY_RECORDING_HINT, android::CameraParameters::TRUE);
+
+ // if application starts recording in continuous focus picture mode...
+ // then we need to force default capture mode (as opposed to video mode)
+ if ( ((valstr = mParameters.get(android::CameraParameters::KEY_FOCUS_MODE)) != NULL) &&
+ (strcmp(valstr, android::CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0) ){
+ restartPreviewRequired = resetVideoModeParameters();
+ }
+
+ // only need to check recording hint if preview restart is not already needed
+ valstr = mParameters.get(android::CameraParameters::KEY_RECORDING_HINT);
+ if ( !restartPreviewRequired &&
+ (!valstr || (valstr && (strcmp(valstr, android::CameraParameters::TRUE) != 0))) ) {
+ restartPreviewRequired = setVideoModeParameters(mParameters);
+ }
+
+ if (restartPreviewRequired) {
+ {
+ android::AutoMutex lock(mLock);
+ mCapModeBackup = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+ }
+ ret = restartPreview();
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
+ mParameters.getPreviewSize(&w, &h);
+ CAMHAL_LOGDB("%s Video Width=%d Height=%d", __FUNCTION__, mVideoWidth, mVideoHeight);
+
+ if ((w != mVideoWidth) && (h != mVideoHeight))
+ {
+ ret = allocVideoBufs(mVideoWidth, mVideoHeight, count);
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
+ mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
+ return ret;
+ }
+
+ mAppCallbackNotifier->useVideoBuffers(true);
+ mAppCallbackNotifier->setVideoRes(mVideoWidth, mVideoHeight);
+ ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBuffers, mPreviewOffsets, mPreviewFd, mPreviewLength, count, mVideoBuffers);
+ }
+ else
+ {
+ mAppCallbackNotifier->useVideoBuffers(false);
+ mAppCallbackNotifier->setVideoRes(mPreviewWidth, mPreviewHeight);
+ ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBuffers, mPreviewOffsets, mPreviewFd, mPreviewLength, count, NULL);
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ ret = mAppCallbackNotifier->startRecording();
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ ///Buffers for video capture (if different from preview) are expected to be allocated within CameraAdapter
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_VIDEO);
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mRecordingEnabled = true;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Set the camera parameters specific to Video Recording.
+
+ This function checks for the camera parameters which have to be set for recording.
+ Video Recording needs CAPTURE_MODE to be VIDEO_MODE. This function sets it.
+ This function also enables Video Recording specific functions like VSTAB & VNF.
+
+ @param none
+ @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
+ @todo Modify the policies for enabling VSTAB & VNF usecase based later.
+
+ */
+bool CameraHal::setVideoModeParameters(const android::CameraParameters& params)
+{
+ const char *valstr = NULL;
+ const char *valstrRemote = NULL;
+ bool restartPreviewRequired = false;
+
+ LOG_FUNCTION_NAME;
+
+ // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
+ valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+ if ( (valstr == NULL) ||
+ ( (valstr != NULL) && ( (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) != 0) &&
+ (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE_HQ ) != 0) ) ) ) {
+ CAMHAL_LOGDA("Set CAPTURE_MODE to VIDEO_MODE");
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, (const char *) TICameraParameters::VIDEO_MODE);
+ restartPreviewRequired = true;
+ }
+
+ // set VSTAB, restart is required if VSTAB value has changed
+ int prevWidth, prevHeight;
+ params.getPreviewSize(&prevWidth, &prevHeight);
+ valstr = mParameters.get(android::CameraParameters::KEY_VIDEO_STABILIZATION);
+ if (prevWidth == 1920 &&
+ (mSocFamily == SocFamily_Omap4430 || mSocFamily == SocFamily_Omap4460)) {
+ // forcibly set to false because of not enough memory for needed buffer size in this case
+ CAMHAL_LOGDA("Forcing VSTAB off");
+ if (strcmp(valstr, android::CameraParameters::FALSE) != 0) {
+ restartPreviewRequired = true;
+ }
+ mParameters.set(android::CameraParameters::KEY_VIDEO_STABILIZATION,
+ android::CameraParameters::FALSE);
+ } else {
+ if ((valstrRemote = params.get(android::CameraParameters::KEY_VIDEO_STABILIZATION)) != NULL) {
+ // make sure we support vstab
+ if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
+ android::CameraParameters::TRUE) == 0) {
+ if (strcmp(valstr, valstrRemote) != 0) {
+ restartPreviewRequired = true;
+ }
+ mParameters.set(android::CameraParameters::KEY_VIDEO_STABILIZATION,
+ valstrRemote);
+ }
+ } else if (mParameters.get(android::CameraParameters::KEY_VIDEO_STABILIZATION)) {
+ // vstab was configured but now unset
+ restartPreviewRequired = true;
+ mParameters.remove(android::CameraParameters::KEY_VIDEO_STABILIZATION);
+ }
+ }
+
+ // Set VNF
+ if ((valstrRemote = params.get(TICameraParameters::KEY_VNF)) == NULL) {
+ CAMHAL_LOGDA("Enable VNF");
+ mParameters.set(TICameraParameters::KEY_VNF, android::CameraParameters::TRUE);
+ restartPreviewRequired = true;
+ } else {
+ valstr = mParameters.get(TICameraParameters::KEY_VNF);
+ if (valstr && strcmp(valstr, valstrRemote) != 0) {
+ restartPreviewRequired = true;
+ }
+ mParameters.set(TICameraParameters::KEY_VNF, valstrRemote);
+ }
+
+#if !defined(OMAP_ENHANCEMENT) && !defined(ENHANCED_DOMX)
+ // For VSTAB alone for 1080p resolution, padded width goes > 2048, which cannot be rendered by GPU.
+ // In such case, there is support in Ducati for combination of VSTAB & VNF requiring padded width < 2048.
+ // So we are forcefully enabling VNF, if VSTAB is enabled for 1080p resolution.
+ int w, h;
+ params.getPreviewSize(&w, &h);
+ valstr = mParameters.get(android::CameraParameters::KEY_VIDEO_STABILIZATION);
+ if (valstr && (strcmp(valstr, android::CameraParameters::TRUE) == 0) && (w == 1920)) {
+ CAMHAL_LOGDA("Force Enable VNF for 1080p");
+ const char *valKeyVnf = mParameters.get(TICameraParameters::KEY_VNF);
+ if(!valKeyVnf || (strcmp(valKeyVnf, android::CameraParameters::TRUE) != 0)) {
+ mParameters.set(TICameraParameters::KEY_VNF, android::CameraParameters::TRUE);
+ restartPreviewRequired = true;
+ }
+ }
+#endif
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return restartPreviewRequired;
+}
+
+/**
+ @brief Reset the camera parameters specific to Video Recording.
+
+ This function resets CAPTURE_MODE and disables Recording specific functions like VSTAB & VNF.
+
+ @param none
+ @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
+
+ */
+bool CameraHal::resetVideoModeParameters()
+{
+ const char *valstr = NULL;
+ bool restartPreviewRequired = false;
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ // ignore this if we are already recording
+ if (mRecordingEnabled) {
+ return false;
+ }
+
+ // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
+ valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+ if ((valstr != NULL) && (strcmp(valstr, TICameraParameters::VIDEO_MODE) == 0)) {
+ CAMHAL_LOGDA("Reset Capture-Mode to default");
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
+ restartPreviewRequired = true;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return restartPreviewRequired;
+}
+
+/**
+ @brief Restart the preview with setParameter.
+
+ This function restarts preview, for some VIDEO_MODE parameters to take effect.
+
+ @param none
+ @return NO_ERROR If recording parameters could be set without any issues
+
+ */
+status_t CameraHal::restartPreview()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ // Retain CAPTURE_MODE before calling stopPreview(), since it is reset in stopPreview().
+
+ forceStopPreview();
+
+ {
+ android::AutoMutex lock(mLock);
+ if (!mCapModeBackup.isEmpty()) {
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, mCapModeBackup.string());
+ } else {
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
+ }
+ mCameraAdapter->setParameters(mParameters);
+ }
+
+ ret = startPreview();
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Stop a previously started recording.
+
+ @param none
+ @return none
+
+ */
+void CameraHal::stopRecording()
+{
+ CameraAdapter::AdapterState currentState;
+
+ LOG_FUNCTION_NAME;
+
+ android::AutoMutex lock(mLock);
+
+ if (!mRecordingEnabled )
+ {
+ return;
+ }
+
+ currentState = mCameraAdapter->getState();
+ if (currentState == CameraAdapter::VIDEO_CAPTURE_STATE) {
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
+ }
+
+ mAppCallbackNotifier->stopRecording();
+
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_VIDEO);
+
+ mRecordingEnabled = false;
+
+ if ( mAppCallbackNotifier->getUesVideoBuffers() ){
+ freeVideoBufs(mVideoBuffers);
+ if (mVideoBuffers){
+ CAMHAL_LOGVB(" FREEING mVideoBuffers %p", mVideoBuffers);
+ delete [] mVideoBuffers;
+ }
+ mVideoBuffers = NULL;
+ }
+
+ // reset internal recording hint in case camera adapter needs to make some
+ // decisions....(will only be sent to camera adapter if camera restart is required)
+ mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Returns true if recording is enabled.
+
+ @param none
+ @return true If recording is currently running
+ false If recording has been stopped
+
+ */
+int CameraHal::recordingEnabled()
+{
+ LOG_FUNCTION_NAME;
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return mRecordingEnabled;
+}
+
+/**
+ @brief Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+
+ @param[in] mem MemoryBase pointer to the frame being released. Must be one of the buffers
+ previously given by CameraHal
+ @return none
+
+ */
+void CameraHal::releaseRecordingFrame(const void* mem)
+{
+ LOG_FUNCTION_NAME;
+
+ //CAMHAL_LOGDB(" 0x%x", mem->pointer());
+
+ if ( ( mRecordingEnabled ) && mem != NULL)
+ {
+ mAppCallbackNotifier->releaseRecordingFrame(mem);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return;
+}
+
+/**
+ @brief Start auto focus
+
+ This call asynchronous.
+ The notification callback routine is called with CAMERA_MSG_FOCUS once when
+ focusing is complete. autoFocus() will be called again if another auto focus is
+ needed.
+
+ @param none
+ @return NO_ERROR
+ @todo Define the error codes if the focus is not locked
+
+ */
+status_t CameraHal::autoFocus()
+{
+ status_t ret = NO_ERROR;
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&mStartFocus, NULL);
+
+#endif
+
+ LOG_FUNCTION_NAME;
+
+ android::AutoMutex lock(mLock);
+
+ mMsgEnabled |= CAMERA_MSG_FOCUS;
+
+ if ( NULL == mCameraAdapter )
+ {
+ ret = -1;
+ goto EXIT;
+ }
+
+ CameraAdapter::AdapterState state;
+ ret = mCameraAdapter->getState(state);
+ if (ret != NO_ERROR)
+ {
+ goto EXIT;
+ }
+
+ if ((state == CameraAdapter::AF_STATE) || (state == CameraAdapter::VIDEO_AF_STATE))
+ {
+ CAMHAL_LOGI("Ignoring start-AF (already in progress)");
+ goto EXIT;
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ //pass the autoFocus timestamp along with the command to camera adapter
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS, ( int ) &mStartFocus);
+
+#else
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS);
+
+#endif
+
+EXIT:
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Cancels auto-focus function.
+
+ If the auto-focus is still in progress, this function will cancel it.
+ Whether the auto-focus is in progress or not, this function will return the
+ focus position to the default. If the camera does not support auto-focus, this is a no-op.
+
+
+ @param none
+ @return NO_ERROR If the cancel succeeded
+ @todo Define error codes if cancel didnt succeed
+
+ */
+status_t CameraHal::cancelAutoFocus()
+{
+ LOG_FUNCTION_NAME;
+
+ android::AutoMutex lock(mLock);
+ android::CameraParameters adapterParams = mParameters;
+ mMsgEnabled &= ~CAMERA_MSG_FOCUS;
+
+ if( NULL != mCameraAdapter )
+ {
+ adapterParams.set(TICameraParameters::KEY_AUTO_FOCUS_LOCK, android::CameraParameters::FALSE);
+ mCameraAdapter->setParameters(adapterParams);
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_CANCEL_AUTOFOCUS);
+ mAppCallbackNotifier->flushEventQueue();
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_ERROR;
+}
+
+void CameraHal::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
+{
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL != mEventProvider )
+ {
+ mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
+ delete mEventProvider;
+ mEventProvider = NULL;
+ }
+
+ mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
+ if ( NULL == mEventProvider )
+ {
+ CAMHAL_LOGEA("Error in creating EventProvider");
+ }
+ else
+ {
+ mEventProvider->enableEventNotification(eventMask);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+void CameraHal::eventCallbackRelay(CameraHalEvent* event)
+{
+ LOG_FUNCTION_NAME;
+
+ CameraHal *appcbn = ( CameraHal * ) (event->mCookie);
+ appcbn->eventCallback(event );
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+void CameraHal::eventCallback(CameraHalEvent* event)
+{
+ LOG_FUNCTION_NAME;
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+status_t CameraHal::startImageBracketing()
+{
+ status_t ret = NO_ERROR;
+ CameraFrame frame;
+ CameraAdapter::BuffersDescriptor desc;
+ unsigned int max_queueable = 0;
+
+
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&mStartCapture, NULL);
+
+#endif
+
+ LOG_FUNCTION_NAME;
+
+ if(!previewEnabled() && !mDisplayPaused)
+ {
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_INIT;
+ }
+
+ if ( !mBracketingEnabled )
+ {
+ return ret;
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mBracketingRunning = true;
+ }
+
+ if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
+ {
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
+ ( int ) &frame,
+ ( mBracketRangeNegative + 1 ));
+
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ if ( NULL != mAppCallbackNotifier.get() )
+ {
+ mAppCallbackNotifier->setBurst(true);
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mParameters.getPictureSize(( int * ) &frame.mWidth,
+ ( int * ) &frame.mHeight);
+
+ ret = allocImageBufs(frame.mWidth,
+ frame.mHeight,
+ frame.mLength,
+ mParameters.getPictureFormat(),
+ ( mBracketRangeNegative + 1 ));
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
+ }
+ }
+
+ if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
+ {
+
+ desc.mBuffers = mImageBuffers;
+ desc.mOffsets = mImageOffsets;
+ desc.mFd = mImageFd;
+ desc.mLength = mImageLength;
+ desc.mCount = ( size_t ) ( mBracketRangeNegative + 1 );
+ desc.mMaxQueueable = ( size_t ) ( mBracketRangeNegative + 1 );
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
+ ( int ) &desc);
+
+ if ( NO_ERROR == ret )
+ {
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ //pass capture timestamp along with the camera adapter command
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE, ( mBracketRangePositive + 1 ), (int) &mStartCapture);
+
+#else
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE, ( mBracketRangePositive + 1 ));
+
+#endif
+
+ }
+ }
+
+ return ret;
+}
+
+status_t CameraHal::stopImageBracketing()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if( !previewEnabled() )
+ {
+ return NO_INIT;
+ }
+
+ mBracketingRunning = false;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_BRACKET_CAPTURE);
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Take a picture.
+
+ @param none
+ @return NO_ERROR If able to switch to image capture
+ @todo Define error codes if unable to switch to image capture
+
+ */
+status_t CameraHal::takePicture(const char *params)
+{
+ // cancel AF state if needed (before any operation and mutex lock)
+ if ((mCameraAdapter->getState() == CameraAdapter::AF_STATE) ||
+ (mCameraAdapter->getState() == CameraAdapter::VIDEO_AF_STATE)) {
+ cancelAutoFocus();
+ }
+
+ android::AutoMutex lock(mLock);
+ return __takePicture(params);
+}
+
+/**
+ @brief Internal function for getting a captured image.
+ shared by takePicture and reprocess.
+ @param none
+ @return NO_ERROR If able to switch to image capture
+ @todo Define error codes if unable to switch to image capture
+
+ */
+status_t CameraHal::__takePicture(const char *params, struct timeval *captureStart)
+{
+ status_t ret = NO_ERROR;
+ CameraFrame frame;
+ CameraAdapter::BuffersDescriptor desc;
+ int burst = -1;
+ const char *valstr = NULL;
+ unsigned int bufferCount = 1;
+ unsigned int max_queueable = 0;
+ unsigned int rawBufferCount = 1;
+ bool isCPCamMode = false;
+ android::sp<DisplayAdapter> outAdapter = 0;
+ bool reuseTapout = false;
+#ifdef MOTOROLA_CAMERA
+ unsigned int intensity = DEFAULT_INTENSITY;
+#endif
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ if ( NULL == captureStart ) {
+ gettimeofday(&mStartCapture, NULL);
+ } else {
+ memcpy(&mStartCapture, captureStart, sizeof(struct timeval));
+ }
+
+#endif
+
+ LOG_FUNCTION_NAME;
+
+ if(!previewEnabled() && !mDisplayPaused)
+ {
+ LOG_FUNCTION_NAME_EXIT;
+ CAMHAL_LOGEA("Preview not started...");
+ return NO_INIT;
+ }
+
+ valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+
+ isCPCamMode = valstr && !strcmp(valstr, TICameraParameters::CP_CAM_MODE);
+
+ // return error if we are already capturing
+ // however, we can queue a capture when in cpcam mode
+ if ( ((mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
+ mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) ||
+ (mCameraAdapter->getState() == CameraAdapter::VIDEO_CAPTURE_STATE &&
+ mCameraAdapter->getNextState() != CameraAdapter::VIDEO_STATE)) &&
+ !isCPCamMode) {
+ CAMHAL_LOGEA("Already capturing an image...");
+ return NO_INIT;
+ }
+
+ // we only support video snapshot if we are in video mode (recording hint is set)
+ if ( (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) &&
+ (valstr && ( strcmp(valstr, TICameraParameters::VIDEO_MODE) &&
+ strcmp(valstr, TICameraParameters::VIDEO_MODE_HQ ) ) ) ) {
+ CAMHAL_LOGEA("Trying to capture while recording without recording hint set...");
+ return INVALID_OPERATION;
+ }
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+ // check if camera application is using shots parameters
+ // api. parameters set here override anything set using setParameters
+ // TODO(XXX): Just going to use legacy TI parameters for now. Need
+ // add new APIs in CameraHal to utilize android::ShotParameters later, so
+ // we don't have to parse through the whole set of parameters
+ // in camera adapter
+ if (strlen(params) > 0) {
+ android::ShotParameters shotParams;
+ const char *valStr;
+ const char *valExpComp, *valExpGain;
+ int valNum;
+
+ android::String8 shotParams8(params);
+
+ shotParams.unflatten(shotParams8);
+ mParameters.remove(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE);
+ mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
+
+ valExpGain = shotParams.get(android::ShotParameters::KEY_EXP_GAIN_PAIRS);
+ valExpComp = shotParams.get(android::ShotParameters::KEY_EXP_COMPENSATION);
+ if (NULL != valExpComp) {
+ mParameters.set(TICameraParameters::KEY_EXP_BRACKETING_RANGE, valExpComp);
+ } else if (NULL != valExpGain) {
+ mParameters.set(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE, valExpGain);
+ }
+
+ valNum = shotParams.getInt(android::ShotParameters::KEY_BURST);
+ if (valNum >= 0) {
+ mParameters.set(TICameraParameters::KEY_BURST, valNum);
+ burst = valNum;
+ }
+
+ valStr = shotParams.get(android::ShotParameters::KEY_FLUSH_CONFIG);
+ if (valStr!= NULL) {
+ if ( 0 == strcmp(valStr, android::ShotParameters::TRUE) ) {
+ mParameters.set(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE,
+ android::CameraParameters::TRUE);
+ } else if ( 0 == strcmp(valStr, android::ShotParameters::FALSE) ) {
+ mParameters.set(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE,
+ android::CameraParameters::FALSE);
+ }
+ }
+
+ valStr = shotParams.get(android::ShotParameters::KEY_CURRENT_TAP_OUT);
+ if (valStr != NULL) {
+ int index = -1;
+ for (unsigned int i = 0; i < mOutAdapters.size(); i++) {
+ if(mOutAdapters.itemAt(i)->match(valStr)) {
+ index = i;
+ break;
+ }
+ }
+ if (index < 0) {
+ CAMHAL_LOGE("Invalid tap out surface passed to camerahal");
+ return BAD_VALUE;
+ }
+ CAMHAL_LOGD("Found matching out adapter at %d", index);
+ outAdapter = mOutAdapters.itemAt(index);
+ if ( outAdapter == mBufferSourceAdapter_Out ) {
+ reuseTapout = true;
+ }
+ }
+
+ mCameraAdapter->setParameters(mParameters);
+ } else
+#endif
+ {
+ // TODO(XXX): Should probably reset burst and bracketing params
+ // when we remove legacy TI parameters implementation
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ CameraHal::PPM("Takepicture parameters set: ", &mStartCapture);
+
+#endif
+
+ // if we are already in the middle of a capture and using the same
+ // tapout ST...then we just need setParameters and start image
+ // capture to queue more shots
+ if (((mCameraAdapter->getState() & CameraAdapter::CAPTURE_STATE) ==
+ CameraAdapter::CAPTURE_STATE) &&
+ (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) &&
+ (reuseTapout) ) {
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+ //pass capture timestamp along with the camera adapter command
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE,
+ (int) &mStartCapture);
+#else
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE);
+#endif
+ return ret;
+ }
+
+ if ( !mBracketingRunning )
+ {
+ // if application didn't set burst through android::ShotParameters
+ // then query from TICameraParameters
+ if ((burst == -1) && (NO_ERROR == ret)) {
+ burst = mParameters.getInt(TICameraParameters::KEY_BURST);
+ }
+
+ //Allocate all buffers only in burst capture case
+ if ( burst > 0 ) {
+ // For CPCam mode...allocate for worst case burst
+ bufferCount = isCPCamMode || (burst > CameraHal::NO_BUFFERS_IMAGE_CAPTURE) ?
+ CameraHal::NO_BUFFERS_IMAGE_CAPTURE : burst;
+
+ if (outAdapter.get()) {
+ if ( reuseTapout ) {
+ bufferCount = mImageCount;
+ } else {
+ bufferCount = outAdapter->getBufferCount();
+ if (bufferCount < 1) {
+ bufferCount = NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;
+ }
+ }
+ }
+
+ if ( NULL != mAppCallbackNotifier.get() ) {
+ mAppCallbackNotifier->setBurst(true);
+ }
+ } else if ( mBracketingEnabled ) {
+ bufferCount = mBracketRangeNegative + 1;
+ if ( NULL != mAppCallbackNotifier.get() ) {
+ mAppCallbackNotifier->setBurst(false);
+ }
+ } else {
+ if ( NULL != mAppCallbackNotifier.get() ) {
+ mAppCallbackNotifier->setBurst(false);
+ }
+ }
+
+ // pause preview during normal image capture
+ // do not pause preview if recording (video state)
+ if ( (NO_ERROR == ret) && (NULL != mDisplayAdapter.get()) ) {
+ if ((mCameraAdapter->getState() != CameraAdapter::VIDEO_STATE) &&
+ (mCameraAdapter->getState() != CameraAdapter::VIDEO_AF_STATE)) {
+ mDisplayPaused = true;
+ mPreviewEnabled = false;
+ ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
+ // since preview is paused we should stop sending preview frames too
+ if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
+ mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
+ }
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+ mDisplayAdapter->setSnapshotTimeRef(&mStartCapture);
+#endif
+ }
+
+ // if we taking video snapshot...
+ if ((NO_ERROR == ret) && ((mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) ||
+ (mCameraAdapter->getState() == CameraAdapter::VIDEO_AF_STATE))) {
+ // enable post view frames if not already enabled so we can internally
+ // save snapshot frames for generating thumbnail
+ if((mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) == 0) {
+ mAppCallbackNotifier->enableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
+ }
+ }
+
+ if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) )
+ {
+#ifdef MOTOROLA_CAMERA
+ intensity = getFlashIntensity();
+
+ if (intensity == 0)
+ {
+ //notification callback can be triggered with this to inform user
+ mParameters.set(android::CameraParameters::KEY_FLASH_MODE, android::CameraParameters::FLASH_MODE_OFF);
+ }
+ else if (intensity <= DEFAULT_INTENSITY)
+ {
+ mParameters.set(TICameraParameters::KEY_MOT_LEDFLASH, (int) intensity);
+ mParameters.set(TICameraParameters::KEY_MOT_LEDTORCH, (int) intensity);
+ }
+#endif
+
+ if ( NO_ERROR == ret )
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
+ ( int ) &frame,
+ bufferCount);
+
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
+ }
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ CameraHal::PPM("Takepicture buffer size queried: ", &mStartCapture);
+
+#endif
+
+ if (outAdapter.get()) {
+ // Avoid locking the tapout again when reusing it
+ if (!reuseTapout) {
+ // Need to reset buffers if we are switching adapters since we don't know
+ // the state of the new buffer list
+ ret = outAdapter->maxQueueableBuffers(max_queueable);
+ if (NO_ERROR != ret) {
+ CAMHAL_LOGE("Couldn't get max queuable");
+ return ret;
+ }
+ mImageBuffers = outAdapter->getBuffers(true);
+ mImageOffsets = outAdapter->getOffsets();
+ mImageFd = outAdapter->getFd();
+ mImageLength = outAdapter->getSize();
+ mImageCount = bufferCount;
+ mBufferSourceAdapter_Out = outAdapter;
+ }
+ } else {
+ mBufferSourceAdapter_Out.clear();
+ // allocImageBufs will only allocate new buffers if mImageBuffers is NULL
+ if ( NO_ERROR == ret ) {
+ max_queueable = bufferCount;
+ ret = allocImageBufs(frame.mAlignment / getBPP(mParameters.getPictureFormat()),
+ frame.mHeight,
+ frame.mLength,
+ mParameters.getPictureFormat(),
+ bufferCount);
+ if ( NO_ERROR != ret ) {
+ CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
+ }
+ }
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ CameraHal::PPM("Takepicture buffers allocated: ", &mStartCapture);
+ memcpy(&mImageBuffers->ppmStamp, &mStartCapture, sizeof(struct timeval));
+
+#endif
+
+ if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
+ {
+ desc.mBuffers = mImageBuffers;
+ desc.mOffsets = mImageOffsets;
+ desc.mFd = mImageFd;
+ desc.mLength = mImageLength;
+ desc.mCount = ( size_t ) bufferCount;
+ desc.mMaxQueueable = ( size_t ) max_queueable;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
+ ( int ) &desc);
+ }
+ if (mRawCapture) {
+ if ( NO_ERROR == ret ) {
+ CAMHAL_LOGDB("Raw capture buffers setup - %s", mParameters.getPictureFormat());
+ ret = allocRawBufs(mParameters.getInt(TICameraParameters::RAW_WIDTH),
+ mParameters.getInt(TICameraParameters::RAW_HEIGHT),
+ android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB,
+ rawBufferCount);
+
+ if ( NO_ERROR != ret ) {
+ CAMHAL_LOGEB("allocRawBufs (for RAW capture) returned error 0x%x", ret);
+ }
+ }
+
+ if ((NO_ERROR == ret) && ( NULL != mCameraAdapter )) {
+ desc.mBuffers = mVideoBuffers;
+ desc.mOffsets = mVideoOffsets;
+ desc.mFd = mVideoFd;
+ desc.mLength = mVideoLength;
+ desc.mCount = ( size_t ) rawBufferCount;
+ desc.mMaxQueueable = ( size_t ) rawBufferCount;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_VIDEO_CAPTURE,
+ ( int ) &desc);
+ }
+ }
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ CameraHal::PPM("Takepicture buffers registered: ", &mStartCapture);
+
+#endif
+
+ if ((ret == NO_ERROR) && mBufferSourceAdapter_Out.get()) {
+ mBufferSourceAdapter_Out->enableDisplay(0, 0, NULL);
+ }
+
+ if ((NO_ERROR == ret) && (NULL != mCameraAdapter)) {
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ //pass capture timestamp along with the camera adapter command
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE, (int) &mStartCapture);
+
+ CameraHal::PPM("Takepicture capture started: ", &mStartCapture);
+
+#else
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE);
+
+#endif
+
+ }
+
+ return ret;
+}
+
+/**
+ @brief Cancel a picture that was started with takePicture.
+
+ Calling this method when no picture is being taken is a no-op.
+
+ @param none
+ @return NO_ERROR If cancel succeeded. Cancel can succeed if image callback is not sent
+ @todo Define error codes
+
+ */
+status_t CameraHal::cancelPicture( )
+{
+ LOG_FUNCTION_NAME;
+ status_t ret = NO_ERROR;
+
+ ret = signalEndImageCapture();
+ return NO_ERROR;
+}
+
+/**
+ @brief Return the camera parameters.
+
+ @param none
+ @return Currently configured camera parameters
+
+ */
+char* CameraHal::getParameters()
+{
+ android::String8 params_str8;
+ char* params_string;
+ const char * valstr = NULL;
+
+ LOG_FUNCTION_NAME;
+
+ if( NULL != mCameraAdapter )
+ {
+ mCameraAdapter->getParameters(mParameters);
+ }
+
+ if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT)) != NULL ) {
+ if (!strcmp(TICameraParameters::S3D_TB_FULL, valstr)) {
+ mParameters.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PICTURE_TOPBOTTOM_SIZES));
+ } else if (!strcmp(TICameraParameters::S3D_SS_FULL, valstr)) {
+ mParameters.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PICTURE_SIDEBYSIDE_SIZES));
+ } else if ((!strcmp(TICameraParameters::S3D_TB_SUBSAMPLED, valstr))
+ || (!strcmp(TICameraParameters::S3D_SS_SUBSAMPLED, valstr))) {
+ mParameters.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PICTURE_SUBSAMPLED_SIZES));
+ }
+ }
+
+ if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)) != NULL ) {
+ if (!strcmp(TICameraParameters::S3D_TB_FULL, valstr)) {
+ mParameters.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PREVIEW_TOPBOTTOM_SIZES));
+ } else if (!strcmp(TICameraParameters::S3D_SS_FULL, valstr)) {
+ mParameters.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES));
+ } else if ((!strcmp(TICameraParameters::S3D_TB_SUBSAMPLED, valstr))
+ || (!strcmp(TICameraParameters::S3D_SS_SUBSAMPLED, valstr))) {
+ mParameters.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PREVIEW_SUBSAMPLED_SIZES));
+ }
+ }
+
+ android::CameraParameters mParams = mParameters;
+
+ // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
+ valstr = mParameters.get(android::CameraParameters::KEY_RECORDING_HINT);
+ if(valstr != NULL)
+ {
+ if(strcmp(valstr, android::CameraParameters::TRUE) == 0)
+ {
+ //HACK FOR MMS MODE
+ resetPreviewRes(&mParams);
+ }
+ }
+
+ // do not send internal parameters to upper layers
+ mParams.remove(TICameraParameters::KEY_RECORDING_HINT);
+ mParams.remove(TICameraParameters::KEY_AUTO_FOCUS_LOCK);
+
+ params_str8 = mParams.flatten();
+
+ // camera service frees this string...
+ params_string = (char*) malloc(sizeof(char) * (params_str8.length()+1));
+ strcpy(params_string, params_str8.string());
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ ///Return the current set of parameters
+
+ return params_string;
+}
+
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+/**
+ @brief Starts reprocessing operation.
+ */
+status_t CameraHal::reprocess(const char *params)
+{
+ status_t ret = NO_ERROR;
+ int bufferCount = 0;
+ CameraAdapter::BuffersDescriptor desc;
+ CameraBuffer *reprocBuffers = NULL;
+ android::ShotParameters shotParams;
+ const char *valStr = NULL;
+ struct timeval startReprocess;
+
+ android::AutoMutex lock(mLock);
+
+ LOG_FUNCTION_NAME;
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&startReprocess, NULL);
+
+#endif
+
+ // 0. Get tap in surface
+ if (strlen(params) > 0) {
+ android::String8 shotParams8(params);
+ shotParams.unflatten(shotParams8);
+ }
+
+ valStr = shotParams.get(android::ShotParameters::KEY_CURRENT_TAP_IN);
+ if (valStr != NULL) {
+ int index = -1;
+ for (unsigned int i = 0; i < mInAdapters.size(); i++) {
+ if(mInAdapters.itemAt(i)->match(valStr)) {
+ index = i;
+ break;
+ }
+ }
+ if (index < 0) {
+ CAMHAL_LOGE("Invalid tap in surface passed to camerahal");
+ return BAD_VALUE;
+ }
+ CAMHAL_LOGD("Found matching in adapter at %d", index);
+ mBufferSourceAdapter_In = mInAdapters.itemAt(index);
+ } else {
+ CAMHAL_LOGE("No tap in surface sent with shot config!");
+ return BAD_VALUE;
+ }
+
+ // 1. Get buffers
+ if (mBufferSourceAdapter_In.get()) {
+ reprocBuffers = mBufferSourceAdapter_In->getBufferList(&bufferCount);
+ }
+
+ if (!reprocBuffers) {
+ CAMHAL_LOGE("Error: couldn't get input buffers for reprocess()");
+ goto exit;
+ }
+
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ CameraHal::PPM("Got reprocess buffers: ", &startReprocess);
+
+#endif
+
+ // 2. Get buffer information and parse parameters
+ {
+ shotParams.setBurst(bufferCount);
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ memcpy(&reprocBuffers->ppmStamp, &startReprocess, sizeof(struct timeval));
+
+#endif
+
+ // 3. Give buffer to camera adapter
+ desc.mBuffers = reprocBuffers;
+ desc.mOffsets = 0;
+ desc.mFd = 0;
+ desc.mLength = 0;
+ desc.mCount = (size_t) bufferCount;
+ desc.mMaxQueueable = (size_t) bufferCount;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_REPROCESS, (int) &desc);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("Error calling camera use buffers");
+ goto exit;
+ }
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ CameraHal::PPM("Reprocess buffers registered: ", &startReprocess);
+
+#endif
+
+ // 4. Start reprocessing
+ ret = mBufferSourceAdapter_In->enableDisplay(0, 0, NULL);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("Error enabling tap in point");
+ goto exit;
+ }
+
+ // 4.5. cancel AF state if needed (before any operation and mutex lock)
+ if ((mCameraAdapter->getState() == CameraAdapter::AF_STATE) ||
+ (mCameraAdapter->getState() == CameraAdapter::VIDEO_AF_STATE)) {
+ cancelAutoFocus();
+ }
+
+ // 5. Start capturing
+ ret = __takePicture(shotParams.flatten().string(), &startReprocess);
+
+exit:
+ return ret;
+}
+
+/**
+ @brief Cancels current reprocessing operation
+
+ */
+status_t CameraHal::cancel_reprocess( )
+{
+ LOG_FUNCTION_NAME;
+ status_t ret = NO_ERROR;
+
+ ret = signalEndImageCapture();
+ return NO_ERROR;
+}
+#endif
+
+
+void CameraHal::putParameters(char *parms)
+{
+ free(parms);
+}
+
+/**
+ @brief Send command to camera driver.
+
+ @param none
+ @return NO_ERROR If the command succeeds
+ @todo Define the error codes that this function can return
+
+ */
+status_t CameraHal::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if ( ( NO_ERROR == ret ) && ( NULL == mCameraAdapter ) )
+ {
+ CAMHAL_LOGEA("No CameraAdapter instance");
+ return -EINVAL;
+ }
+
+ ///////////////////////////////////////////////////////
+ // Following commands NEED preview to be started
+ ///////////////////////////////////////////////////////
+
+ if ((!previewEnabled()) && ((cmd == CAMERA_CMD_START_SMOOTH_ZOOM)
+ || (cmd == CAMERA_CMD_STOP_SMOOTH_ZOOM)
+ || (cmd == CAMERA_CMD_START_FACE_DETECTION)
+#ifdef OMAP_ENHANCEMENT_VTC
+ || (cmd == CAMERA_CMD_PREVIEW_DEINITIALIZATION)
+#endif
+ ))
+ {
+ CAMHAL_LOGEA("sendCommand with cmd = 0x%x need preview to be started", cmd);
+ return BAD_VALUE;
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ switch(cmd)
+ {
+ case CAMERA_CMD_START_SMOOTH_ZOOM:
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_SMOOTH_ZOOM, arg1);
+
+ break;
+
+ case CAMERA_CMD_STOP_SMOOTH_ZOOM:
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM);
+
+ break;
+
+ case CAMERA_CMD_START_FACE_DETECTION:
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_FD);
+
+ break;
+
+ case CAMERA_CMD_STOP_FACE_DETECTION:
+ if (previewEnabled()) {
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
+ }
+
+ break;
+
+#ifdef OMAP_ENHANCEMENT_VTC
+ case CAMERA_CMD_PREVIEW_DEINITIALIZATION:
+ if(mDisplayAdapter.get() != NULL) {
+ ///Stop the buffer display first
+ mDisplayAdapter->disableDisplay();
+ }
+
+ if(mAppCallbackNotifier.get() != NULL) {
+ //Stop the callback sending
+ mAppCallbackNotifier->stop();
+ mAppCallbackNotifier->flushAndReturnFrames();
+ mAppCallbackNotifier->stopPreviewCallbacks();
+ }
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_DESTROY_TUNNEL);
+ mTunnelSetup = false;
+
+ break;
+
+ case CAMERA_CMD_PREVIEW_INITIALIZATION:
+ ret = cameraPreviewInitialization();
+
+ break;
+#endif
+
+#ifdef ANDROID_API_JB_OR_LATER
+ case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
+ {
+ const bool enable = static_cast<bool>(arg1);
+ android::AutoMutex lock(mLock);
+ if ( enable ) {
+ mMsgEnabled |= CAMERA_MSG_FOCUS_MOVE;
+ } else {
+ mMsgEnabled &= ~CAMERA_MSG_FOCUS_MOVE;
+ }
+ break;
+ }
+#endif
+
+ default:
+ break;
+ };
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/**
+ @brief Release the hardware resources owned by this object.
+
+ Note that this is *not* done in the destructor.
+
+ @param none
+ @return none
+
+ */
+void CameraHal::release()
+{
+ LOG_FUNCTION_NAME;
+ ///@todo Investigate on how release is used by CameraService. Vaguely remember that this is called
+ ///just before CameraHal object destruction
+ deinitialize();
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+
+/**
+ @brief Dump state of the camera hardware
+
+ @param[in] fd File descriptor
+ @param[in] args Arguments
+ @return NO_ERROR Dump succeeded
+ @todo Error codes for dump fail
+
+ */
+status_t CameraHal::dump(int fd) const
+{
+ LOG_FUNCTION_NAME;
+ ///Implement this method when the h/w dump function is supported on Ducati side
+ return NO_ERROR;
+}
+
+/*-------------Camera Hal Interface Method definitions ENDS here--------------------*/
+
+
+
+
+/*-------------Camera Hal Internal Method definitions STARTS here--------------------*/
+
+/**
+ @brief Constructor of CameraHal
+
+ Member variables are initialized here. No allocations should be done here as we
+ don't use c++ exceptions in the code.
+
+ */
+CameraHal::CameraHal(int cameraId)
+ : mSocFamily(getSocFamily())
+{
+ LOG_FUNCTION_NAME;
+
+ ///Initialize all the member variables to their defaults
+ mPreviewEnabled = false;
+ mPreviewBuffers = NULL;
+ mImageBuffers = NULL;
+ mBufProvider = NULL;
+ mPreviewStartInProgress = false;
+ mVideoBuffers = NULL;
+ mVideoBufProvider = NULL;
+ mRecordingEnabled = false;
+ mDisplayPaused = false;
+ mSetPreviewWindowCalled = false;
+ mMsgEnabled = 0;
+ mAppCallbackNotifier = NULL;
+ mMemoryManager = NULL;
+ mCameraAdapter = NULL;
+ mBracketingEnabled = false;
+ mBracketingRunning = false;
+ mEventProvider = NULL;
+ mBracketRangePositive = 1;
+ mBracketRangeNegative = 1;
+ mMaxZoomSupported = 0;
+ mShutterEnabled = true;
+ mMeasurementEnabled = false;
+ mPreviewDataBuffers = NULL;
+ mCameraProperties = NULL;
+ mCurrentTime = 0;
+ mFalsePreview = 0;
+ mImageOffsets = NULL;
+ mImageLength = 0;
+ mImageFd = 0;
+ mImageCount = 0;
+ mVideoOffsets = NULL;
+ mVideoFd = 0;
+ mVideoLength = 0;
+ mPreviewDataOffsets = NULL;
+ mPreviewDataFd = 0;
+ mPreviewDataLength = 0;
+ mPreviewFd = 0;
+ mPreviewWidth = 0;
+ mPreviewHeight = 0;
+ mPreviewLength = 0;
+ mPreviewOffsets = NULL;
+ mPreviewRunning = 0;
+ mPreviewStateOld = 0;
+ mRecordingEnabled = 0;
+ mRecordEnabled = 0;
+ mSensorListener = NULL;
+ mVideoWidth = 0;
+ mVideoHeight = 0;
+#ifdef OMAP_ENHANCEMENT_VTC
+ mVTCUseCase = false;
+ mTunnelSetup = false;
+#endif
+ mPreviewInitializationDone = false;
+
+#ifdef OMAP_ENHANCEMENT_CPCAM
+ mExtendedPreviewStreamOps = 0;
+#endif
+
+ //These values depends on the sensor characteristics
+
+ mRawCapture = false;
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ //Initialize the CameraHAL constructor timestamp, which is used in the
+ // PPM() method as time reference if the user does not supply one.
+ gettimeofday(&ppm_start, NULL);
+
+#endif
+
+ mCameraIndex = cameraId;
+
+ mExternalLocking = false;
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Destructor of CameraHal
+
+ This function simply calls deinitialize() to free up memory allocate during construct
+ phase
+ */
+CameraHal::~CameraHal()
+{
+ LOG_FUNCTION_NAME;
+
+ ///Call de-initialize here once more - it is the last chance for us to relinquish all the h/w and s/w resources
+ deinitialize();
+
+ if ( NULL != mEventProvider )
+ {
+ mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
+ delete mEventProvider;
+ mEventProvider = NULL;
+ }
+
+ /// Free the callback notifier
+ mAppCallbackNotifier.clear();
+
+ /// Free the display adapter
+ mDisplayAdapter.clear();
+
+ if ( NULL != mCameraAdapter ) {
+ int strongCount = mCameraAdapter->getStrongCount();
+
+ mCameraAdapter->decStrong(mCameraAdapter);
+
+ mCameraAdapter = NULL;
+ }
+
+ freeImageBufs();
+ freeRawBufs();
+
+ /// Free the memory manager
+ mMemoryManager.clear();
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Initialize the Camera HAL
+
+ Creates CameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager
+
+ @param None
+ @return NO_ERROR - On success
+ NO_MEMORY - On failure to allocate memory for any of the objects
+ @remarks Camera Hal internal function
+
+ */
+
+status_t CameraHal::initialize(CameraProperties::Properties* properties)
+{
+ LOG_FUNCTION_NAME;
+
+ int sensor_index = 0;
+ const char* sensor_name = NULL;
+
+ ///Initialize the event mask used for registering an event provider for AppCallbackNotifier
+ ///Currently, registering all events as to be coming from CameraAdapter
+ int32_t eventMask = CameraHalEvent::ALL_EVENTS;
+
+ // Get my camera properties
+ mCameraProperties = properties;
+
+ if(!mCameraProperties)
+ {
+ goto fail_loop;
+ }
+
+ // Dump the properties of this Camera
+ // will only print if DEBUG macro is defined
+ mCameraProperties->dump();
+
+ if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)) != 0 )
+ {
+ sensor_index = atoi(mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX));
+ }
+
+ if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_NAME)) != 0 ) {
+ sensor_name = mCameraProperties->get(CameraProperties::CAMERA_NAME);
+ }
+ CAMHAL_LOGDB("Sensor index= %d; Sensor name= %s", sensor_index, sensor_name);
+
+ if (strcmp(sensor_name, V4L_CAMERA_NAME_USB) == 0) {
+#ifdef V4L_CAMERA_ADAPTER
+ mCameraAdapter = V4LCameraAdapter_Factory(sensor_index, this);
+#endif
+ }
+ else {
+#ifdef OMX_CAMERA_ADAPTER
+ mCameraAdapter = OMXCameraAdapter_Factory(sensor_index);
+#endif
+ }
+
+ if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties)!=NO_ERROR))
+ {
+ CAMHAL_LOGEA("Unable to create or initialize CameraAdapter");
+ mCameraAdapter = NULL;
+ goto fail_loop;
+ }
+
+ mCameraAdapter->incStrong(mCameraAdapter);
+ mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);
+ mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this);
+
+ if(!mAppCallbackNotifier.get())
+ {
+ /// Create the callback notifier
+ mAppCallbackNotifier = new AppCallbackNotifier();
+ if( ( NULL == mAppCallbackNotifier.get() ) || ( mAppCallbackNotifier->initialize() != NO_ERROR))
+ {
+ CAMHAL_LOGEA("Unable to create or initialize AppCallbackNotifier");
+ goto fail_loop;
+ }
+ }
+
+ if(!mMemoryManager.get())
+ {
+ /// Create Memory Manager
+ mMemoryManager = new MemoryManager();
+ if( ( NULL == mMemoryManager.get() ) || ( mMemoryManager->initialize() != NO_ERROR))
+ {
+ CAMHAL_LOGEA("Unable to create or initialize MemoryManager");
+ goto fail_loop;
+ }
+ }
+
+ ///Setup the class dependencies...
+
+ ///AppCallbackNotifier has to know where to get the Camera frames and the events like auto focus lock etc from.
+ ///CameraAdapter is the one which provides those events
+ ///Set it as the frame and event providers for AppCallbackNotifier
+ ///@remarks setEventProvider API takes in a bit mask of events for registering a provider for the different events
+ /// That way, if events can come from DisplayAdapter in future, we will be able to add it as provider
+ /// for any event
+ mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);
+ mAppCallbackNotifier->setFrameProvider(mCameraAdapter);
+
+ ///Any dynamic errors that happen during the camera use case has to be propagated back to the application
+ ///via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that notifies such errors to the application
+ ///Set it as the error handler for CameraAdapter
+ mCameraAdapter->setErrorHandler(mAppCallbackNotifier.get());
+
+ ///Start the callback notifier
+ if(mAppCallbackNotifier->start() != NO_ERROR)
+ {
+ CAMHAL_LOGEA("Couldn't start AppCallbackNotifier");
+ goto fail_loop;
+ }
+
+ CAMHAL_LOGDA("Started AppCallbackNotifier..");
+ mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
+
+ ///Initialize default parameters
+ initDefaultParameters();
+
+
+ if ( setParameters(mParameters) != NO_ERROR )
+ {
+ CAMHAL_LOGEA("Failed to set default parameters?!");
+ }
+
+ // register for sensor events
+ mSensorListener = new SensorListener();
+ if (mSensorListener.get()) {
+ if (mSensorListener->initialize() == NO_ERROR) {
+ mSensorListener->setCallbacks(orientation_cb, this);
+ mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);
+ } else {
+ CAMHAL_LOGEA("Error initializing SensorListener. not fatal, continuing");
+ mSensorListener.clear();
+ mSensorListener = NULL;
+ }
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return NO_ERROR;
+
+ fail_loop:
+
+ ///Free up the resources because we failed somewhere up
+ deinitialize();
+ LOG_FUNCTION_NAME_EXIT;
+
+ return NO_MEMORY;
+
+}
+
+bool CameraHal::isResolutionValid(unsigned int width, unsigned int height, const char *supportedResolutions)
+{
+ bool ret = false;
+ status_t status = NO_ERROR;
+ char tmpBuffer[MAX_PROP_VALUE_LENGTH];
+ char *pos = NULL;
+
+ LOG_FUNCTION_NAME;
+
+ if (NULL == supportedResolutions) {
+ CAMHAL_LOGEA("Invalid supported resolutions string");
+ goto exit;
+ }
+
+ status = snprintf(tmpBuffer, MAX_PROP_VALUE_LENGTH - 1, "%dx%d", width, height);
+ if (0 > status) {
+ CAMHAL_LOGEA("Error encountered while generating validation string");
+ goto exit;
+ }
+
+ ret = isParameterValid(tmpBuffer, supportedResolutions);
+
+exit:
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+bool CameraHal::isFpsRangeValid(int fpsMin, int fpsMax, const char *supportedFpsRanges)
+{
+ bool ret = false;
+ char supported[MAX_PROP_VALUE_LENGTH];
+ char *pos;
+ int suppFpsRangeArray[2];
+ int i = 0;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL == supportedFpsRanges ) {
+ CAMHAL_LOGEA("Invalid supported FPS ranges string");
+ return false;
+ }
+
+ if (fpsMin <= 0 || fpsMax <= 0 || fpsMin > fpsMax) {
+ return false;
+ }
+
+ strncpy(supported, supportedFpsRanges, MAX_PROP_VALUE_LENGTH);
+ pos = strtok(supported, " (,)");
+ while (pos != NULL) {
+ suppFpsRangeArray[i] = atoi(pos);
+ if (i++) {
+ if (fpsMin >= suppFpsRangeArray[0] && fpsMax <= suppFpsRangeArray[1]) {
+ ret = true;
+ break;
+ }
+ i = 0;
+ }
+ pos = strtok(NULL, " (,)");
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+bool CameraHal::isParameterValid(const char *param, const char *supportedParams)
+{
+ bool ret = false;
+ char *pos;
+ char supported[MAX_PROP_VALUE_LENGTH];
+
+ LOG_FUNCTION_NAME;
+
+ if (NULL == supportedParams) {
+ CAMHAL_LOGEA("Invalid supported parameters string");
+ goto exit;
+ }
+
+ if (NULL == param) {
+ CAMHAL_LOGEA("Invalid parameter string");
+ goto exit;
+ }
+
+ strncpy(supported, supportedParams, MAX_PROP_VALUE_LENGTH - 1);
+
+ pos = strtok(supported, ",");
+ while (pos != NULL) {
+ if (!strcmp(pos, param)) {
+ ret = true;
+ break;
+ }
+ pos = strtok(NULL, ",");
+ }
+
+exit:
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+bool CameraHal::isParameterValid(int param, const char *supportedParams)
+{
+ bool ret = false;
+ status_t status;
+ char tmpBuffer[MAX_PROP_VALUE_LENGTH];
+
+ LOG_FUNCTION_NAME;
+
+ if (NULL == supportedParams) {
+ CAMHAL_LOGEA("Invalid supported parameters string");
+ goto exit;
+ }
+
+ status = snprintf(tmpBuffer, MAX_PROP_VALUE_LENGTH - 1, "%d", param);
+ if (0 > status) {
+ CAMHAL_LOGEA("Error encountered while generating validation string");
+ goto exit;
+ }
+
+ ret = isParameterValid(tmpBuffer, supportedParams);
+
+exit:
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::doesSetParameterNeedUpdate(const char* new_param, const char* old_param, bool& update) {
+ if (!new_param || !old_param) {
+ return -EINVAL;
+ }
+
+ // if params mismatch we should update parameters for camera adapter
+ if ((strcmp(new_param, old_param) != 0)) {
+ update = true;
+ }
+
+ return NO_ERROR;
+}
+
+status_t CameraHal::parseResolution(const char *resStr, int &width, int &height)
+{
+ status_t ret = NO_ERROR;
+ char *ctx, *pWidth, *pHeight;
+ const char *sep = "x";
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL == resStr )
+ {
+ return -EINVAL;
+ }
+
+ //This fixes "Invalid input resolution"
+ char *resStr_copy = (char *)malloc(strlen(resStr) + 1);
+ if ( NULL != resStr_copy )
+ {
+ strcpy(resStr_copy, resStr);
+ pWidth = strtok_r(resStr_copy, sep, &ctx);
+
+ if ( NULL != pWidth )
+ {
+ width = atoi(pWidth);
+ }
+ else
+ {
+ CAMHAL_LOGEB("Invalid input resolution %s", resStr);
+ ret = -EINVAL;
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ pHeight = strtok_r(NULL, sep, &ctx);
+
+ if ( NULL != pHeight )
+ {
+ height = atoi(pHeight);
+ }
+ else
+ {
+ CAMHAL_LOGEB("Invalid input resolution %s", resStr);
+ ret = -EINVAL;
+ }
+ }
+
+ free(resStr_copy);
+ resStr_copy = NULL;
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+void CameraHal::insertSupportedParams()
+{
+ LOG_FUNCTION_NAME;
+
+ android::CameraParameters &p = mParameters;
+
+ ///Set the name of the camera
+ p.set(TICameraParameters::KEY_CAMERA_NAME, mCameraProperties->get(CameraProperties::CAMERA_NAME));
+
+ mMaxZoomSupported = atoi(mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
+
+ p.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS));
+ p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
+ p.set(TICameraParameters::KEY_SUPPORTED_PICTURE_SUBSAMPLED_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SUBSAMPLED_SIZES));
+ p.set(TICameraParameters::KEY_SUPPORTED_PICTURE_SIDEBYSIDE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIDEBYSIDE_SIZES));
+ p.set(TICameraParameters::KEY_SUPPORTED_PICTURE_TOPBOTTOM_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_TOPBOTTOM_SIZES));
+ p.set(TICameraParameters::KEY_SUPPORTED_PREVIEW_SUBSAMPLED_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SUBSAMPLED_SIZES));
+ p.set(TICameraParameters::KEY_SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES));
+ p.set(TICameraParameters::KEY_SUPPORTED_PREVIEW_TOPBOTTOM_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_TOPBOTTOM_SIZES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));
+ p.set(TICameraParameters::KEY_FRAMERATES_EXT_SUPPORTED, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES_EXT));
+ p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
+ p.set(TICameraParameters::KEY_FRAMERATE_RANGES_EXT_SUPPORTED, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_EXT_SUPPORTED));
+ p.set(android::CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_THUMBNAIL_SIZES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE));
+ p.set(android::CameraParameters::KEY_SUPPORTED_EFFECTS, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS));
+ p.set(android::CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_FLASH_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES));
+ p.set(android::CameraParameters::KEY_SUPPORTED_ANTIBANDING, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING));
+ p.set(android::CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MAX));
+ p.set(android::CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MIN));
+ p.set(android::CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_EV_STEP));
+ p.set(TICameraParameters::KEY_SUPPORTED_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MIN));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MAX, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MAX));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_STEP));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MIN));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MAX));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_STEP));
+ p.set(TICameraParameters::KEY_SUPPORTED_ISO_VALUES, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES));
+ p.set(android::CameraParameters::KEY_ZOOM_RATIOS, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_RATIOS));
+ p.set(android::CameraParameters::KEY_MAX_ZOOM, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
+ p.set(android::CameraParameters::KEY_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::ZOOM_SUPPORTED));
+ p.set(android::CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::SMOOTH_ZOOM_SUPPORTED));
+ p.set(TICameraParameters::KEY_SUPPORTED_IPP, mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES));
+ p.set(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT_VALUES, mCameraProperties->get(CameraProperties::S3D_PRV_FRAME_LAYOUT_VALUES));
+ p.set(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT_VALUES, mCameraProperties->get(CameraProperties::S3D_CAP_FRAME_LAYOUT_VALUES));
+ p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE_VALUES, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE_VALUES));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_CONVERGENCE_MIN, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MIN));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_CONVERGENCE_MAX, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MAX));
+ p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_CONVERGENCE_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_STEP));
+ p.set(android::CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED, mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED));
+ p.set(TICameraParameters::KEY_VNF_SUPPORTED, mCameraProperties->get(CameraProperties::VNF_SUPPORTED));
+ p.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK_SUPPORTED));
+ p.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK_SUPPORTED));
+ p.set(android::CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, mCameraProperties->get(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED));
+ p.set(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION_SUPPORTED, mCameraProperties->get(CameraProperties::MECHANICAL_MISALIGNMENT_CORRECTION_SUPPORTED));
+ p.set(TICameraParameters::KEY_CAP_MODE_VALUES, mCameraProperties->get(CameraProperties::CAP_MODE_VALUES));
+
+ LOG_FUNCTION_NAME_EXIT;
+
+}
+
+void CameraHal::initDefaultParameters()
+{
+ //Purpose of this function is to initialize the default current and supported parameters for the currently
+ //selected camera.
+
+ android::CameraParameters &p = mParameters;
+ int currentRevision, adapterRevision;
+ status_t ret = NO_ERROR;
+ int width, height;
+ const char *valstr;
+
+ LOG_FUNCTION_NAME;
+
+ insertSupportedParams();
+
+ ret = parseResolution(mCameraProperties->get(CameraProperties::PREVIEW_SIZE), width, height);
+
+ if ( NO_ERROR == ret )
+ {
+ p.setPreviewSize(width, height);
+ }
+ else
+ {
+ p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
+ }
+
+ ret = parseResolution(mCameraProperties->get(CameraProperties::PICTURE_SIZE), width, height);
+
+ if ( NO_ERROR == ret )
+ {
+ p.setPictureSize(width, height);
+ }
+ else
+ {
+ p.setPictureSize(PICTURE_WIDTH, PICTURE_HEIGHT);
+ }
+
+ ret = parseResolution(mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_SIZE), width, height);
+
+ if ( NO_ERROR == ret )
+ {
+ p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
+ p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
+ }
+ else
+ {
+ p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, MIN_WIDTH);
+ p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, MIN_HEIGHT);
+ }
+
+ //Insert default values
+ p.setPreviewFrameRate(atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)));
+ p.set(android::CameraParameters::KEY_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
+ p.set(TICameraParameters::KEY_PREVIEW_FRAME_RATE_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
+ p.setPreviewFormat(mCameraProperties->get(CameraProperties::PREVIEW_FORMAT));
+ p.setPictureFormat(mCameraProperties->get(CameraProperties::PICTURE_FORMAT));
+ p.set(android::CameraParameters::KEY_JPEG_QUALITY, mCameraProperties->get(CameraProperties::JPEG_QUALITY));
+ p.set(android::CameraParameters::KEY_WHITE_BALANCE, mCameraProperties->get(CameraProperties::WHITEBALANCE));
+ p.set(android::CameraParameters::KEY_EFFECT, mCameraProperties->get(CameraProperties::EFFECT));
+ p.set(android::CameraParameters::KEY_ANTIBANDING, mCameraProperties->get(CameraProperties::ANTIBANDING));
+ p.set(android::CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
+ p.set(android::CameraParameters::KEY_FOCUS_MODE, mCameraProperties->get(CameraProperties::FOCUS_MODE));
+ p.set(android::CameraParameters::KEY_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::EV_COMPENSATION));
+ p.set(android::CameraParameters::KEY_SCENE_MODE, mCameraProperties->get(CameraProperties::SCENE_MODE));
+ p.set(android::CameraParameters::KEY_ZOOM, mCameraProperties->get(CameraProperties::ZOOM));
+ p.set(TICameraParameters::KEY_CONTRAST, mCameraProperties->get(CameraProperties::CONTRAST));
+ p.set(TICameraParameters::KEY_SATURATION, mCameraProperties->get(CameraProperties::SATURATION));
+ p.set(TICameraParameters::KEY_BRIGHTNESS, mCameraProperties->get(CameraProperties::BRIGHTNESS));
+ p.set(TICameraParameters::KEY_SHARPNESS, mCameraProperties->get(CameraProperties::SHARPNESS));
+ p.set(TICameraParameters::KEY_EXPOSURE_MODE, mCameraProperties->get(CameraProperties::EXPOSURE_MODE));
+ p.set(TICameraParameters::KEY_MANUAL_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MIN));
+ p.set(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MIN));
+ p.set(TICameraParameters::KEY_MANUAL_GAIN_ISO, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MIN));
+ p.set(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MIN));
+ p.set(TICameraParameters::KEY_ISO, mCameraProperties->get(CameraProperties::ISO_MODE));
+ p.set(TICameraParameters::KEY_IPP, mCameraProperties->get(CameraProperties::IPP));
+ p.set(TICameraParameters::KEY_GBCE, mCameraProperties->get(CameraProperties::GBCE));
+ p.set(TICameraParameters::KEY_GBCE_SUPPORTED, mCameraProperties->get(CameraProperties::SUPPORTED_GBCE));
+ p.set(TICameraParameters::KEY_GLBCE, mCameraProperties->get(CameraProperties::GLBCE));
+ p.set(TICameraParameters::KEY_GLBCE_SUPPORTED, mCameraProperties->get(CameraProperties::SUPPORTED_GLBCE));
+ p.set(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT, mCameraProperties->get(CameraProperties::S3D_PRV_FRAME_LAYOUT));
+ p.set(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT, mCameraProperties->get(CameraProperties::S3D_CAP_FRAME_LAYOUT));
+ p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE));
+ p.set(TICameraParameters::KEY_MANUAL_CONVERGENCE, mCameraProperties->get(CameraProperties::MANUAL_CONVERGENCE));
+ p.set(android::CameraParameters::KEY_VIDEO_STABILIZATION, mCameraProperties->get(CameraProperties::VSTAB));
+ p.set(TICameraParameters::KEY_VNF, mCameraProperties->get(CameraProperties::VNF));
+ p.set(android::CameraParameters::KEY_FOCAL_LENGTH, mCameraProperties->get(CameraProperties::FOCAL_LENGTH));
+ p.set(android::CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::HOR_ANGLE));
+ p.set(android::CameraParameters::KEY_VERTICAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::VER_ANGLE));
+ p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
+ p.set(TICameraParameters::KEY_EXIF_MAKE, mCameraProperties->get(CameraProperties::EXIF_MAKE));
+ p.set(TICameraParameters::KEY_EXIF_MODEL, mCameraProperties->get(CameraProperties::EXIF_MODEL));
+ p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_QUALITY));
+ p.set(android::CameraParameters::KEY_VIDEO_FRAME_FORMAT, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar");
+ p.set(android::CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, mCameraProperties->get(CameraProperties::MAX_FD_HW_FACES));
+ p.set(android::CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, mCameraProperties->get(CameraProperties::MAX_FD_SW_FACES));
+ p.set(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION, mCameraProperties->get(CameraProperties::MECHANICAL_MISALIGNMENT_CORRECTION));
+ // Only one area a.k.a Touch AF for now.
+ // TODO: Add support for multiple focus areas.
+ p.set(android::CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, mCameraProperties->get(CameraProperties::MAX_FOCUS_AREAS));
+ p.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK));
+ p.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK));
+ p.set(android::CameraParameters::KEY_MAX_NUM_METERING_AREAS, mCameraProperties->get(CameraProperties::MAX_NUM_METERING_AREAS));
+ p.set(TICameraParameters::RAW_WIDTH, mCameraProperties->get(CameraProperties::RAW_WIDTH));
+ p.set(TICameraParameters::RAW_HEIGHT,mCameraProperties->get(CameraProperties::RAW_HEIGHT));
+
+ // TI extensions for enable/disable algos
+ // Hadcoded for now
+ p.set(TICameraParameters::KEY_ALGO_EXTERNAL_GAMMA, android::CameraParameters::FALSE);
+ p.set(TICameraParameters::KEY_ALGO_NSF1, android::CameraParameters::TRUE);
+ p.set(TICameraParameters::KEY_ALGO_NSF2, android::CameraParameters::TRUE);
+ p.set(TICameraParameters::KEY_ALGO_SHARPENING, android::CameraParameters::TRUE);
+ p.set(TICameraParameters::KEY_ALGO_THREELINCOLORMAP, android::CameraParameters::TRUE);
+ p.set(TICameraParameters::KEY_ALGO_GIC, android::CameraParameters::TRUE);
+
+#ifdef MOTOROLA_CAMERA
+ p.set(TICameraParameters::KEY_MOT_LEDFLASH, DEFAULT_INTENSITY);
+ p.set(TICameraParameters::KEY_MOT_LEDTORCH, DEFAULT_INTENSITY);
+#endif
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Stop a previously started preview.
+ @param none
+ @return none
+
+ */
+void CameraHal::forceStopPreview()
+{
+ LOG_FUNCTION_NAME;
+
+ // stop bracketing if it is running
+ if ( mBracketingRunning ) {
+ stopImageBracketing();
+ }
+
+ if(mDisplayAdapter.get() != NULL) {
+ ///Stop the buffer display first
+ mDisplayAdapter->disableDisplay();
+ }
+
+ if(mAppCallbackNotifier.get() != NULL) {
+ //Stop the callback sending
+ mAppCallbackNotifier->stop();
+ mAppCallbackNotifier->flushAndReturnFrames();
+ mAppCallbackNotifier->stopPreviewCallbacks();
+ }
+
+ if ( NULL != mCameraAdapter ) {
+ // only need to send these control commands to state machine if we are
+ // passed the LOADED_PREVIEW_STATE
+ if (mCameraAdapter->getState() > CameraAdapter::LOADED_PREVIEW_STATE) {
+ // according to javadoc...FD should be stopped in stopPreview
+ // and application needs to call startFaceDection again
+ // to restart FD
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
+ }
+
+ mCameraAdapter->rollbackToInitializedState();
+
+ }
+
+ freePreviewBufs();
+ freePreviewDataBufs();
+
+ mPreviewEnabled = false;
+ mDisplayPaused = false;
+ mPreviewStartInProgress = false;
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+/**
+ @brief Deallocates memory for all the resources held by Camera HAL.
+
+ Frees the following objects- CameraAdapter, AppCallbackNotifier, DisplayAdapter,
+ and Memory Manager
+
+ @param none
+ @return none
+
+ */
+void CameraHal::deinitialize()
+{
+ LOG_FUNCTION_NAME;
+
+ if ( mPreviewEnabled || mDisplayPaused ) {
+ forceStopPreview();
+ }
+
+ mSetPreviewWindowCalled = false;
+
+ if (mSensorListener.get()) {
+ mSensorListener->disableSensor(SensorListener::SENSOR_ORIENTATION);
+ mSensorListener.clear();
+ mSensorListener = NULL;
+ }
+
+ mBufferSourceAdapter_Out.clear();
+ mBufferSourceAdapter_In.clear();
+ mOutAdapters.clear();
+ mInAdapters.clear();
+
+ LOG_FUNCTION_NAME_EXIT;
+
+}
+
+status_t CameraHal::storeMetaDataInBuffers(bool enable)
+{
+ LOG_FUNCTION_NAME;
+
+ return mAppCallbackNotifier->useMetaDataBufferMode(enable);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+void CameraHal::setExternalLocking(bool extBuffLocking)
+{
+ mExternalLocking = extBuffLocking;
+}
+
+void CameraHal::resetPreviewRes(android::CameraParameters *params)
+{
+ LOG_FUNCTION_NAME;
+
+ if ( (mVideoWidth <= 320) && (mVideoHeight <= 240)){
+ params->setPreviewSize(mVideoWidth, mVideoHeight);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+#ifdef MOTOROLA_CAMERA
+#include <cutils/properties.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+#define EXT_MODULE_VENDOR_STRING "SHARP,OV8820"
+#define INT_MODULE_VENDOR_STRING "SEMCO,OV7739"
+
+#define DCM_CAM_CONFIG_FILE "/data/system/dcm_camera.config"
+#define CAMERA_ENABLED 0x73
+#define CAMERA_DISABLED 0x45
+
+#define MOT_BURST_COUNT "mot-burst-picture-count"
+#define MOT_BURST_COUNT_VALUES "mot-burst-picture-count-values"
+#define MOT_MAX_BURST_SIZE "mot-max-burst-size"
+//Wide screen aspect ratio (16:9)
+#define WIDE_AR 1.7
+
+// TI supports arbitrary burst limits, so we
+// go with what we've used on other platforms
+#define SUPPORTED_BURSTS "0,1,3,6,9"
+
+#define TORCH_DRIVER_DEVICE "/dev/i2c-3"
+#define TORCH_DEVICE_SLAVE_ADDR 0x53
+#define TORCH_DEVICE_CONTROL_REG 0x10
+#define TORCH_BRIGHTNESS_CONTROL_REG 0xA0
+#define TORCH_DEFAULT_BRIGHTNESS 0x02
+#define TORCH_ENABLE 0x0A
+#define TORCH_DISABLE 0x0
+#define MAX_EXPOSURE_COMPENSATION 30
+
+bool CameraHal::i2cRW(int read_size, int write_size, unsigned char *read_data, unsigned char *write_data)
+{
+
+ int i2cfd = -1;
+ int i,j;
+ int ioctl_ret;
+ struct i2c_msg msgs[2];
+ struct i2c_rdwr_ioctl_data i2c_trans;
+ bool retL = 0;
+
+ enum { I2C_WRITE, I2C_READ };
+ enum { ARG_BUS = 1, ARG_ADDR, ARG_READCNT, ARG_DATA };
+
+ msgs[0].addr = TORCH_DEVICE_SLAVE_ADDR;
+ msgs[0].flags = 0;
+ msgs[0].len = write_size;
+ msgs[0].buf = write_data;
+
+ msgs[1].addr = TORCH_DEVICE_SLAVE_ADDR;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].len = read_size;
+ msgs[1].buf = read_data;
+
+ i2c_trans.msgs = NULL;
+ i2c_trans.nmsgs = 0;
+
+ if ((i2cfd = open(TORCH_DRIVER_DEVICE, O_RDWR)) < 0) {
+ CAMHAL_LOGD("failed to open %s", TORCH_DRIVER_DEVICE);
+ return 1;
+ }
+
+ if ( write_size && read_size ) {
+ i2c_trans.msgs = &msgs[0];
+ i2c_trans.nmsgs = 2;
+ }
+ else if (write_size) {
+ i2c_trans.msgs = &msgs[0];
+ i2c_trans.nmsgs = 1;
+ }
+ else if (read_size) {
+ i2c_trans.msgs = &msgs[1];
+ i2c_trans.nmsgs = 1;
+ }
+ else {
+ goto done;
+ }
+
+ if ( write_size > 0 ) {
+ CAMHAL_LOGD("I2C_WRITE");
+ for( i = 0; i < write_size; i++ )
+ {
+ CAMHAL_LOGD( "%02X ", write_data[i] );
+ }
+ }
+
+ if( (ioctl_ret = ioctl( i2cfd, I2C_RDWR, &(i2c_trans))) < 0 )
+ {
+ CAMHAL_LOGD("* failed driver call: ioctl returned %d", ioctl_ret);
+ retL = 1;
+ goto done;
+ }
+
+
+ if ( read_size > 0 ) {
+ CAMHAL_LOGD("I2C_READ");
+ for( i = 0; i < read_size; i++ )
+ {
+ CAMHAL_LOGD( "%02X ", read_data[i] );
+ }
+ }
+
+done:
+ /* close the hardware */
+ close(i2cfd);
+
+ return retL;
+
+}
+
+unsigned int CameraHal::getFlashIntensity()
+{
+ unsigned int flashIntensity = DEFAULT_INTENSITY;
+ char value[PROPERTY_VALUE_MAX];
+ unsigned long minFlashThreshold;
+
+ if (property_get("ro.media.capture.flashIntensity", value, 0) > 0)
+ {
+ flashIntensity = atoi(value);
+ }
+ if (property_get("ro.media.capture.flashMinV", value, 0) > 0)
+ {
+ minFlashThreshold = atoi(value);
+ }
+ else
+ {
+ minFlashThreshold = FLASH_VOLTAGE_THRESHOLD2;
+ }
+ if ( minFlashThreshold != 0)
+ {
+ int fd = open("/sys/class/power_supply/battery/voltage_now", O_RDONLY);
+ if (fd < 0)
+ {
+ CAMHAL_LOGE("Battery status is unavailable, defaulting Flash intensity to MAX");
+ }
+ else
+ {
+ char buf[8];
+ if ( read(fd, buf, 8) < 0 )
+ {
+ CAMHAL_LOGE("Unable to read battery status, defaulting flash intensity to MAX\n");
+ }
+ else
+ {
+ unsigned long batteryLevel;
+ buf[7] = '\0';
+ batteryLevel = atol(buf);
+ CAMHAL_LOGE("Current battery Level, %d uv", batteryLevel);
+ if (batteryLevel < minFlashThreshold)
+ {
+ CAMHAL_LOGE("Disabling flash due to low Battery");
+ flashIntensity = 0;
+ }
+ else if (batteryLevel < FLASH_VOLTAGE_THRESHOLD1)
+ {
+ flashIntensity = flashIntensity >> 1 ;
+ }
+ }
+ close(fd);
+ }
+ }
+ CAMHAL_LOGE("flashIntensity = %d", flashIntensity);
+ return flashIntensity;
+}
+
+bool CameraHal::SetFlashLedTorch( unsigned intensity )
+{
+ android::CameraParameters params;
+ mCameraAdapter->getParameters(params);
+ CAMHAL_LOGE("CameraHalTI::SetFlashLedTorch %d", intensity);
+ unsigned char write_data[2];
+
+ if (intensity == 0)
+ {
+ write_data[0] = TORCH_DEVICE_CONTROL_REG;
+ write_data[1] = TORCH_DISABLE;
+ i2cRW(0, 2, NULL, write_data);
+ }
+ else
+ {
+ write_data[0] = TORCH_BRIGHTNESS_CONTROL_REG;
+ write_data[1] = TORCH_DEFAULT_BRIGHTNESS;
+ i2cRW(0, 2, NULL, write_data);
+
+ write_data[0] = TORCH_DEVICE_CONTROL_REG;
+ write_data[1] = TORCH_ENABLE;
+ i2cRW(0, 2, NULL, write_data);
+ }
+
+ return true;
+}
+
+#endif
+
+void *
+camera_buffer_get_omx_ptr (CameraBuffer *buffer)
+{
+ CAMHAL_LOGV("buffer_type %d opaque %p", buffer->type, buffer->opaque);
+
+ if (buffer->type == CAMERA_BUFFER_ANW) {
+ buffer_handle_t *handle = (buffer_handle_t *)buffer->opaque;
+ CAMHAL_LOGV("anw %08x", *handle);
+ return (void *)*handle;
+ } else if (buffer->type == CAMERA_BUFFER_ION) {
+ return (void *)buffer->fd;
+ } else {
+ CAMHAL_LOGV("other %08x", buffer->opaque);
+ return (void *)buffer->opaque;
+ }
+}
+
+} // namespace Camera
+} // namespace Ti