summaryrefslogtreecommitdiffstats
path: root/camera/CameraHal.cpp
diff options
context:
space:
mode:
authorIliyan Malchev <malchev@google.com>2011-08-08 11:24:41 -0700
committerIliyan Malchev <malchev@google.com>2011-08-08 11:46:17 -0700
commitc322989ae6ff6769490828de1b5eda12b749cce9 (patch)
treecfd1494d18791389b1a743242085f128e8a030fd /camera/CameraHal.cpp
parent8558b0909d3f42288f488e6fd1341877c639a594 (diff)
downloadhardware_ti_omap4xxx-c322989ae6ff6769490828de1b5eda12b749cce9.zip
hardware_ti_omap4xxx-c322989ae6ff6769490828de1b5eda12b749cce9.tar.gz
hardware_ti_omap4xxx-c322989ae6ff6769490828de1b5eda12b749cce9.tar.bz2
initial commit
Change-Id: I8f7a7eeece0e516efa486b77e9d97805c0e65d3e Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'camera/CameraHal.cpp')
-rwxr-xr-xcamera/CameraHal.cpp3030
1 files changed, 3030 insertions, 0 deletions
diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp
new file mode 100755
index 0000000..53bc377
--- /dev/null
+++ b/camera/CameraHal.cpp
@@ -0,0 +1,3030 @@
+/*
+ * 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.
+*
+*/
+
+#define LOG_TAG "CameraHAL"
+
+#include "CameraHal.h"
+#include "ANativeWindowDisplayAdapter.h"
+#include "TICameraParameters.h"
+#include "CameraProperties.h"
+#include <cutils/properties.h>
+
+#include <poll.h>
+#include <math.h>
+
+namespace android {
+
+extern "C" CameraAdapter* CameraAdapter_Factory();
+
+/*****************************************************************************/
+
+////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 = 2;
+
+const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 0;
+const uint32_t MessageNotifier::FRAME_BIT_FIELD_POSITION = 0;
+
+/******************************************************************************/
+
+#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);
+ }
+
+ 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;
+ }
+
+ {
+ Mutex::Autolock 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;
+
+ {
+ Mutex::Autolock 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)
+{
+ LOG_FUNCTION_NAME;
+ Mutex::Autolock lock(mLock);
+ LOG_FUNCTION_NAME_EXIT;
+ return (mMsgEnabled & 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;
+
+ CameraParameters params;
+
+ 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 CameraParameters& params)
+{
+
+ LOG_FUNCTION_NAME;
+
+ int w, h;
+ int w_orig, h_orig;
+ int framerate,minframerate;
+ bool framerateUpdated = true;
+ int maxFPS, minFPS;
+ int error;
+ int base;
+ const char *valstr = NULL;
+ const char *prevFormat;
+ char *af_coord;
+ TIUTILS::Message msg;
+ status_t ret = NO_ERROR;
+
+ Mutex::Autolock lock(mLock);
+
+ ///Ensure that preview is not enabled when the below parameters are changed.
+ if(!previewEnabled())
+ {
+
+ CAMHAL_LOGDB("PreviewFormat %s", params.getPreviewFormat());
+
+ if ( !isParameterValid(params.getPreviewFormat(), mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS)))
+ {
+ CAMHAL_LOGEB("Invalid preview format %s", mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
+ return -EINVAL;
+ }
+ else
+ {
+ if ( (valstr = params.getPreviewFormat()) != NULL)
+ mParameters.setPreviewFormat(valstr);
+ }
+
+ params.getPreviewSize(&w, &h);
+ if (w == -1 && h == -1) {
+ CAMHAL_LOGEA("Unable to get preview size");
+ return ret;
+ }
+
+ int orientation =0;
+ if((valstr = params.get(TICameraParameters::KEY_SENSOR_ORIENTATION)) != NULL)
+ {
+ CAMHAL_LOGDB("Sensor Orientation is set to %s", params.get(TICameraParameters::KEY_SENSOR_ORIENTATION));
+ mParameters.set(TICameraParameters::KEY_SENSOR_ORIENTATION, valstr);
+ orientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
+ }
+
+ if(orientation ==90 || orientation ==270)
+ {
+ if ( !isResolutionValid(h,w, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
+ {
+ CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
+ return -EINVAL;
+ }
+ else
+ {
+ mParameters.setPreviewSize(w, h);
+ }
+ }
+ else
+ {
+ if ( !isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
+ {
+ CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
+ return -EINVAL;
+ }
+ else
+ {
+ mParameters.setPreviewSize(w, h);
+ }
+ }
+
+ CAMHAL_LOGDB("PreviewResolution by App %d x %d", w, h);
+
+ if(( (valstr = params.get(TICameraParameters::KEY_VNF)) != NULL)
+ && ((params.getInt(TICameraParameters::KEY_VNF)==0) || (params.getInt(TICameraParameters::KEY_VNF)==1)))
+ {
+ CAMHAL_LOGDB("VNF set %s", params.get(TICameraParameters::KEY_VNF));
+ mParameters.set(TICameraParameters::KEY_VNF, valstr);
+ }
+
+ if(( (valstr = params.get(TICameraParameters::KEY_VSTAB)) != NULL)
+ && ((params.getInt(TICameraParameters::KEY_VSTAB)==0) || (params.getInt(TICameraParameters::KEY_VSTAB)==1)))
+ {
+ CAMHAL_LOGDB("VSTAB set %s", params.get(TICameraParameters::KEY_VSTAB));
+ mParameters.set(TICameraParameters::KEY_VSTAB, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_CAP_MODE)) != NULL)
+ {
+ CAMHAL_LOGDB("Capture mode set %s", params.get(TICameraParameters::KEY_CAP_MODE));
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, valstr);
+ }
+
+ if((valstr = params.get(TICameraParameters::KEY_IPP)) != NULL)
+ {
+ CAMHAL_LOGDB("IPP mode set %s", params.get(TICameraParameters::KEY_IPP));
+ mParameters.set(TICameraParameters::KEY_IPP, valstr);
+ }
+
+ if((valstr = params.get(TICameraParameters::KEY_S3D2D_PREVIEW)) != NULL)
+ {
+ CAMHAL_LOGDB("Stereo 3D->2D Preview mode is %s", params.get(TICameraParameters::KEY_S3D2D_PREVIEW));
+ mParameters.set(TICameraParameters::KEY_S3D2D_PREVIEW, valstr);
+ }
+
+ if((valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE)) != NULL)
+ {
+ CAMHAL_LOGDB("AutoConvergence mode is %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE));
+ mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE, valstr);
+ }
+ if((valstr = params.get(TICameraParameters::KEY_SENSOR_ORIENTATION)) != NULL)
+ {
+ CAMHAL_LOGDB("Sensor Orientation is set to %s", params.get(TICameraParameters::KEY_SENSOR_ORIENTATION));
+ mParameters.set(TICameraParameters::KEY_SENSOR_ORIENTATION, valstr);
+ }
+
+ }
+
+ ///Below parameters can be changed when the preview is running
+ if ( !isParameterValid(params.getPictureFormat(),
+ mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS)))
+ {
+ CAMHAL_LOGEA("Invalid picture format");
+ return -EINVAL;
+ }
+ else
+ {
+ valstr = params.getPictureFormat();
+ if (valstr)
+ mParameters.setPictureFormat(valstr);
+ }
+
+ params.getPictureSize(&w, &h);
+ if ( !isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES)))
+ {
+ CAMHAL_LOGEB("Invalid picture resolution %dx%d", w, h);
+ return -EINVAL;
+ }
+ else
+ {
+ mParameters.setPictureSize(w, h);
+ }
+
+ CAMHAL_LOGDB("Picture Size by App %d x %d", w, h);
+
+ if(( (valstr = params.get(TICameraParameters::KEY_BURST)) != NULL)
+ && (params.getInt(TICameraParameters::KEY_BURST) >=0))
+ {
+ CAMHAL_LOGDB("Burst set %s", params.get(TICameraParameters::KEY_BURST));
+ mParameters.set(TICameraParameters::KEY_BURST, valstr);
+ }
+
+ framerate = params.getPreviewFrameRate();
+ if ( isParameterValid(framerate, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES)))
+ {
+ if ( mLastPreviewFramerate != framerate )
+ {
+ mLastPreviewFramerate = framerate;
+ mParameters.setPreviewFrameRate(framerate);
+ framerateUpdated = true;
+ }
+ else
+ {
+ framerateUpdated = false;
+ }
+ }
+ else
+ {
+ framerateUpdated = false;
+ }
+
+ CAMHAL_LOGDB("FRAMERATE %d", framerate);
+
+ //If client uses fixed framerate than
+ //give it a higher piority than VFR.
+ if ( framerateUpdated )
+ {
+
+ minFPS = framerate;
+ maxFPS = framerate;
+
+ CAMHAL_LOGDB("FPS Range [%d, %d]", minFPS, maxFPS);
+ mParameters.set(TICameraParameters::KEY_MINFRAMERATE, minFPS);
+ mParameters.set(TICameraParameters::KEY_MAXFRAMERATE, maxFPS);
+ mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE));
+ }
+ else if ( ( valstr = params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE) ) != NULL )
+ {
+ CAMHAL_LOGDB("FPS Range = %s", valstr);
+ params.getPreviewFpsRange(&minFPS, &maxFPS);
+
+ if ( ( 0 > minFPS ) || ( 0 > maxFPS ) )
+ {
+ CAMHAL_LOGEA("FPS Range is negative!");
+ return -EINVAL;
+ }
+
+ minFPS /= CameraHal::VFR_SCALE;
+ maxFPS /= CameraHal::VFR_SCALE;
+
+ if ( ( 0 == minFPS ) || ( 0 == maxFPS ) )
+ {
+ CAMHAL_LOGEA("FPS Range is invalid!");
+ return -EINVAL;
+ }
+
+ if ( maxFPS < minFPS )
+ {
+ CAMHAL_LOGEA("Max FPS is smaller than Min FPS!");
+ return -EINVAL;
+ }
+
+ if ( maxFPS > framerate )
+ {
+ framerate = maxFPS;
+ mParameters.setPreviewFrameRate(framerate);
+ }
+
+ CAMHAL_LOGDB("FPS Range [%d, %d]", minFPS, maxFPS);
+ mParameters.set(TICameraParameters::KEY_MINFRAMERATE, minFPS);
+ mParameters.set(TICameraParameters::KEY_MAXFRAMERATE, maxFPS);
+ mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
+ }
+
+ if( ( valstr = params.get(TICameraParameters::KEY_GBCE) ) != NULL )
+ {
+ CAMHAL_LOGDB("GBCE Value = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GBCE, valstr);
+ }
+
+ if( ( valstr = params.get(TICameraParameters::KEY_GLBCE) ) != NULL )
+ {
+ CAMHAL_LOGDB("GLBCE Value = %s", valstr);
+ mParameters.set(TICameraParameters::KEY_GLBCE, valstr);
+ }
+
+ ///Update the current parameter set
+ if( (valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE)) != NULL)
+ {
+ CAMHAL_LOGDB("AutoConvergence Mode is set = %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE));
+ mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE, valstr);
+ }
+
+// if(params.get(TICameraParameters::KEY_AUTOCONVERGENCE_MODE)!=NULL)
+// {
+// CAMHAL_LOGDB("AutoConvergence Mode is set = %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE_MODE));
+// mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, params.get(TICameraParameters::KEY_AUTOCONVERGENCE_MODE));
+// }
+
+ if( (valstr = params.get(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES)) !=NULL )
+ {
+ CAMHAL_LOGDB("ManualConvergence Value = %s", params.get(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES));
+ mParameters.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, valstr);
+ }
+
+ if( ((valstr = params.get(TICameraParameters::KEY_EXPOSURE_MODE)) != NULL)
+ && isParameterValid(params.get(TICameraParameters::KEY_EXPOSURE_MODE),
+ mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES)))
+ {
+ CAMHAL_LOGDB("Exposure set = %s", params.get(TICameraParameters::KEY_EXPOSURE_MODE));
+ mParameters.set(TICameraParameters::KEY_EXPOSURE_MODE, valstr);
+ }
+
+ if( ((valstr = params.get(CameraParameters::KEY_WHITE_BALANCE)) != NULL)
+ && isParameterValid(params.get(CameraParameters::KEY_WHITE_BALANCE),
+ mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE)))
+ {
+ CAMHAL_LOGDB("White balance set %s", params.get(CameraParameters::KEY_WHITE_BALANCE));
+ mParameters.set(CameraParameters::KEY_WHITE_BALANCE, valstr);
+ }
+
+ if( ((valstr = params.get(TICameraParameters::KEY_CONTRAST)) != NULL)
+ && (params.getInt(TICameraParameters::KEY_CONTRAST) >= 0 ))
+ {
+ CAMHAL_LOGDB("Contrast set %s", params.get(TICameraParameters::KEY_CONTRAST));
+ mParameters.set(TICameraParameters::KEY_CONTRAST, valstr);
+ }
+
+ if( ((valstr =params.get(TICameraParameters::KEY_SHARPNESS)) != NULL) && params.getInt(TICameraParameters::KEY_SHARPNESS) >= 0 )
+ {
+ CAMHAL_LOGDB("Sharpness set %s", params.get(TICameraParameters::KEY_SHARPNESS));
+ mParameters.set(TICameraParameters::KEY_SHARPNESS, valstr);
+ }
+
+
+ if( ((valstr = params.get(TICameraParameters::KEY_SATURATION)) != NULL)
+ && (params.getInt(TICameraParameters::KEY_SATURATION) >= 0 ) )
+ {
+ CAMHAL_LOGDB("Saturation set %s", params.get(TICameraParameters::KEY_SATURATION));
+ mParameters.set(TICameraParameters::KEY_SATURATION, valstr);
+ }
+
+ if( ((valstr = params.get(TICameraParameters::KEY_BRIGHTNESS)) != NULL)
+ && (params.getInt(TICameraParameters::KEY_BRIGHTNESS) >= 0 ))
+ {
+ CAMHAL_LOGDB("Brightness set %s", params.get(TICameraParameters::KEY_BRIGHTNESS));
+ mParameters.set(TICameraParameters::KEY_BRIGHTNESS, valstr);
+ }
+
+
+ if( ((valstr = params.get(CameraParameters::KEY_ANTIBANDING)) != NULL)
+ && isParameterValid(params.get(CameraParameters::KEY_ANTIBANDING),
+ mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING)))
+ {
+ CAMHAL_LOGDB("Antibanding set %s", params.get(CameraParameters::KEY_ANTIBANDING));
+ mParameters.set(CameraParameters::KEY_ANTIBANDING, valstr);
+ }
+
+ if( ((valstr = params.get(TICameraParameters::KEY_ISO)) != NULL)
+ && isParameterValid(params.get(TICameraParameters::KEY_ISO),
+ mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES)))
+ {
+ CAMHAL_LOGDB("ISO set %s", params.get(TICameraParameters::KEY_ISO));
+ mParameters.set(TICameraParameters::KEY_ISO, valstr);
+ }
+
+ if( ((valstr = params.get(CameraParameters::KEY_FOCUS_MODE)) != NULL)
+ && isParameterValid(params.get(CameraParameters::KEY_FOCUS_MODE),
+ mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES)))
+ {
+ CAMHAL_LOGDB("Focus mode set %s", params.get(CameraParameters::KEY_FOCUS_MODE));
+ mParameters.set(CameraParameters::KEY_FOCUS_MODE, valstr);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_FOCUS_AREAS)) != NULL )
+ {
+ CAMHAL_LOGEB("Focus areas position set %s", params.get(CameraParameters::KEY_FOCUS_AREAS));
+ mParameters.set(CameraParameters::KEY_FOCUS_AREAS, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
+ {
+ CAMHAL_LOGDB("Measurements set to %s", params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE));
+ mParameters.set(TICameraParameters::KEY_MEASUREMENT_ENABLE, valstr);
+
+ if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_ENABLE) == 0)
+ {
+ mMeasurementEnabled = true;
+ }
+ else if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_DISABLE) == 0)
+ {
+ mMeasurementEnabled = false;
+ }
+ else
+ {
+ mMeasurementEnabled = false;
+ }
+
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_EXPOSURE_COMPENSATION)) != NULL)
+ {
+ CAMHAL_LOGDB("Exposure compensation set %s", params.get(CameraParameters::KEY_EXPOSURE_COMPENSATION));
+ mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_SCENE_MODE)) != NULL)
+ && isParameterValid(params.get(CameraParameters::KEY_SCENE_MODE),
+ mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES)))
+ {
+ CAMHAL_LOGDB("Scene mode set %s", params.get(CameraParameters::KEY_SCENE_MODE));
+ mParameters.set(CameraParameters::KEY_SCENE_MODE, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_FLASH_MODE)) != NULL)
+ && isParameterValid(params.get(CameraParameters::KEY_FLASH_MODE),
+ mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES)))
+ {
+ CAMHAL_LOGDB("Flash mode set %s", params.get(CameraParameters::KEY_FLASH_MODE));
+ mParameters.set(CameraParameters::KEY_FLASH_MODE, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_EFFECT)) != NULL)
+ && isParameterValid(params.get(CameraParameters::KEY_EFFECT),
+ mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS)))
+ {
+ CAMHAL_LOGDB("Effect set %s", params.get(CameraParameters::KEY_EFFECT));
+ mParameters.set(CameraParameters::KEY_EFFECT, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_ROTATION)) != NULL)
+ && (params.getInt(CameraParameters::KEY_ROTATION) >=0))
+ {
+ CAMHAL_LOGDB("Rotation set %s", params.get(CameraParameters::KEY_ROTATION));
+ mParameters.set(CameraParameters::KEY_ROTATION, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_JPEG_QUALITY)) != NULL)
+ && (params.getInt(CameraParameters::KEY_JPEG_QUALITY) >=0))
+ {
+ CAMHAL_LOGDB("Jpeg quality set %s", params.get(CameraParameters::KEY_JPEG_QUALITY));
+ mParameters.set(CameraParameters::KEY_JPEG_QUALITY, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH)) != NULL)
+ && (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH) >=0))
+ {
+ CAMHAL_LOGDB("Thumbnail width set %s", params.get(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH));
+ mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT)) != NULL)
+ && (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT) >=0))
+ {
+ CAMHAL_LOGDB("Thumbnail width set %s", params.get(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT));
+ mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, valstr);
+ }
+
+ if(( (valstr = params.get(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY)) != NULL )
+ && (params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY) >=0))
+ {
+ CAMHAL_LOGDB("Thumbnail quality set %s", params.get(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY));
+ mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, valstr);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_GPS_LATITUDE)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS latitude set %s", params.get(CameraParameters::KEY_GPS_LATITUDE));
+ mParameters.set(CameraParameters::KEY_GPS_LATITUDE, valstr);
+ }else{
+ mParameters.remove(CameraParameters::KEY_GPS_LATITUDE);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_GPS_LONGITUDE)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS longitude set %s", params.get(CameraParameters::KEY_GPS_LONGITUDE));
+ mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, valstr);
+ }else{
+ mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_GPS_ALTITUDE)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS altitude set %s", params.get(CameraParameters::KEY_GPS_ALTITUDE));
+ mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, valstr);
+ }else{
+ mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_GPS_TIMESTAMP)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS timestamp set %s", params.get(CameraParameters::KEY_GPS_TIMESTAMP));
+ mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, valstr);
+ }else{
+ mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_GPS_DATESTAMP)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS datestamp set %s", params.get(TICameraParameters::KEY_GPS_DATESTAMP));
+ mParameters.set(TICameraParameters::KEY_GPS_DATESTAMP, valstr);
+ }else{
+ mParameters.remove(TICameraParameters::KEY_GPS_DATESTAMP);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD)) != NULL )
+ {
+ CAMHAL_LOGDB("GPS processing method set %s", params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD));
+ mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, valstr);
+ }else{
+ mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_GPS_MAPDATUM )) != NULL )
+ {
+ CAMHAL_LOGDB("GPS MAPDATUM set %s", params.get(TICameraParameters::KEY_GPS_MAPDATUM));
+ 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", params.get(TICameraParameters::KEY_GPS_VERSION));
+ mParameters.set(TICameraParameters::KEY_GPS_VERSION, valstr);
+ }else{
+ mParameters.remove(TICameraParameters::KEY_GPS_VERSION);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_EXIF_MODEL)) != NULL )
+ {
+ CAMHAL_LOGDB("EXIF Model set %s", params.get(TICameraParameters::KEY_EXIF_MODEL));
+ mParameters.set(TICameraParameters::KEY_EXIF_MODEL, valstr);
+ }
+
+ if( (valstr = params.get(TICameraParameters::KEY_EXIF_MAKE)) != NULL )
+ {
+ CAMHAL_LOGDB("EXIF Make set %s", params.get(TICameraParameters::KEY_EXIF_MAKE));
+ mParameters.set(TICameraParameters::KEY_EXIF_MAKE, valstr);
+ }
+
+ 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);
+ }
+ else
+ {
+ mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
+ }
+
+ if( ( (valstr = params.get(CameraParameters::KEY_ZOOM)) != NULL )
+ && (params.getInt(CameraParameters::KEY_ZOOM) >= 0 )
+ && (params.getInt(CameraParameters::KEY_ZOOM) <= mMaxZoomSupported ) )
+ {
+ CAMHAL_LOGDB("Zoom set %s", params.get(CameraParameters::KEY_ZOOM));
+ mParameters.set(CameraParameters::KEY_ZOOM, valstr);
+ }
+ else
+ {
+ //CTS requirement: Invalid zoom values should always return an error.
+ ret = -EINVAL;
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
+ {
+ CAMHAL_LOGDB("Auto Exposure Lock set %s", params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
+ mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
+ }
+
+ if( (valstr = params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
+ {
+ CAMHAL_LOGDB("Auto WhiteBalance Lock set %s", params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
+ mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
+ }
+
+ CameraParameters adapterParams = mParameters;
+
+ //If the app has not set the capture mode, set the capture resolution as preview resolution
+ //so that black bars are not displayed in preview.
+ //Later in takePicture we will configure the correct picture size
+ if(params.get(TICameraParameters::KEY_CAP_MODE) == NULL)
+ {
+ CAMHAL_LOGDA("Capture mode not set by app, setting picture res to preview res");
+ mParameters.getPreviewSize(&w, &h);
+ adapterParams.setPictureSize(w,h);
+ }
+
+ // Only send parameters to adapter if preview is already
+ // enabled. Initial setParameters to camera adapter, will
+ // be called in startPreview()
+ if ( NULL != mCameraAdapter && mPreviewEnabled ) {
+ ret |= mCameraAdapter->setParameters(adapterParams);
+ }
+
+ 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, TICameraParameters::BRACKET_ENABLE) == 0 ))
+ {
+ if ( !mBracketingEnabled )
+ {
+ CAMHAL_LOGDA("Enabling bracketing");
+ mBracketingEnabled = true;
+
+ //Wait for AF events to enable bracketing
+ if ( NULL != mCameraAdapter )
+ {
+ setEventProvider( CameraHalEvent::ALL_EVENTS, mCameraAdapter );
+ }
+ }
+ else
+ {
+ CAMHAL_LOGDA("Bracketing already enabled");
+ }
+ }
+ else if ( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL ) &&
+ ( strcmp(valstr, TICameraParameters::BRACKET_DISABLE) == 0 ))
+ {
+ CAMHAL_LOGDA("Disabling bracketing");
+
+ mBracketingEnabled = false;
+ stopImageBracketing();
+
+ //Remove AF events subscription
+ if ( NULL != mEventProvider )
+ {
+ mEventProvider->disableEventNotification( CameraHalEvent::ALL_EVENTS );
+ delete mEventProvider;
+ mEventProvider = NULL;
+ }
+
+ }
+
+ if( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
+ ( strcmp(valstr, TICameraParameters::SHUTTER_ENABLE) == 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, TICameraParameters::SHUTTER_DISABLE) == 0 ))
+ {
+ CAMHAL_LOGDA("Disabling shutter sound");
+
+ mShutterEnabled = false;
+ mMsgEnabled &= ~CAMERA_MSG_SHUTTER;
+ mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
+ }
+
+ 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(!mPreviewBufs)
+ {
+ ///@todo Pluralise the name of this method to allocateBuffers
+ mPreviewLength = 0;
+ mPreviewBufs = (int32_t *) mDisplayAdapter->allocateBuffer(width, height,
+ previewFormat,
+ mPreviewLength,
+ buffercount);
+
+ if (NULL == mPreviewBufs ) {
+ 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;
+ }
+
+ mPreviewFd = mDisplayAdapter->getFd();
+ if ( -1 == mPreviewFd ) {
+ CAMHAL_LOGEA("Invalid handle");
+ 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("mPreviewBufs = 0x%x", (unsigned int)mPreviewBufs);
+ if(mPreviewBufs)
+ {
+ ///@todo Pluralise the name of this method to freeBuffers
+ ret = mBufProvider->freeBuffer(mPreviewBufs);
+ mPreviewBufs = 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 != mPreviewDataBufs )
+ {
+ ret = freePreviewDataBufs();
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mPreviewDataBufs = (int32_t *)mMemoryManager->allocateBuffer(0, 0, NULL, bytes, bufferCount);
+
+ CAMHAL_LOGDB("Size of Preview data buffer = %d", bytes);
+ if( NULL == mPreviewDataBufs )
+ {
+ 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;
+
+ return ret;
+}
+
+status_t CameraHal::freePreviewDataBufs()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NO_ERROR == ret )
+ {
+
+ if( NULL != mPreviewDataBufs )
+ {
+
+ ///@todo Pluralise the name of this method to freeBuffers
+ ret = mMemoryManager->freeBuffer(mPreviewDataBufs);
+ mPreviewDataBufs = NULL;
+
+ }
+ else
+ {
+ CAMHAL_LOGEA("Couldn't free PreviewDataBufs allocated by memory manager");
+ ret = -EINVAL;
+ }
+
+ }
+
+ 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;
+
+ LOG_FUNCTION_NAME;
+
+ bytes = size;
+
+ ///Always allocate the buffers for image capture using MemoryManager
+ if ( NO_ERROR == ret )
+ {
+ if( ( NULL != mImageBufs ) )
+ {
+ ret = freeImageBufs();
+ }
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mImageBufs = (int32_t *)mMemoryManager->allocateBuffer(0, 0, previewFormat, bytes, bufferCount);
+
+ CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
+ if( NULL == mImageBufs )
+ {
+ 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();
+ }
+ else
+ {
+ mImageFd = -1;
+ mImageLength = 0;
+ mImageOffsets = NULL;
+ }
+
+ LOG_FUNCTION_NAME;
+
+ 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;
+ CameraParameters adapterParams = mParameters;
+ Mutex::Autolock lock(mLock);
+
+ LOG_FUNCTION_NAME;
+
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
+
+ //If the app has not set the capture mode, restore the capture resolution
+ //back to the preview resolution to get rid of the black bars issue
+ if (mParameters.get(TICameraParameters::KEY_CAP_MODE) == NULL) {
+ CAMHAL_LOGDA("Capture mode not set by app, setting picture res back to preview res");
+ mParameters.getPreviewSize(&w, &h);
+ adapterParams.setPictureSize(w,h);
+ ret = mCameraAdapter->setParameters(adapterParams);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::freeImageBufs()
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NO_ERROR == ret )
+ {
+
+ if( NULL != mImageBufs )
+ {
+
+ ///@todo Pluralise the name of this method to freeBuffers
+ ret = mMemoryManager->freeBuffer(mImageBufs);
+ mImageBufs = 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()
+{
+
+ status_t ret = NO_ERROR;
+ CameraAdapter::BuffersDescriptor desc;
+ CameraFrame frame;
+ const char *valstr = NULL;
+ unsigned int required_buffer_count;
+ unsigned int max_queueble_buffers;
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&mStartPreview, NULL);
+
+#endif
+
+ LOG_FUNCTION_NAME;
+
+ 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);
+ }
+ return ret;
+
+ }
+ else if ( mPreviewEnabled )
+ {
+ CAMHAL_LOGDA("Preview already running");
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ALREADY_EXISTS;
+ }
+
+ ///If we don't have the preview callback enabled and display adapter,
+ if(!mSetPreviewWindowCalled || (mDisplayAdapter.get() == NULL))
+ {
+ CAMHAL_LOGEA("Preview not started. Preview in progress flag set");
+ mPreviewStartInProgress = true;
+ return NO_ERROR;
+ }
+
+ if ( NULL != mCameraAdapter ) {
+
+ CameraParameters adapterParams = mParameters;
+
+ //If the app has not set the capture mode, set the capture resolution as preview resolution
+ //so that black bars are not displayed in preview.
+ //Later in takePicture we will configure the correct picture size
+ if(mParameters.get(TICameraParameters::KEY_CAP_MODE) == NULL)
+ {
+ int w,h;
+ CAMHAL_LOGDA("Capture mode not set by app, setting picture res to preview res");
+ mParameters.getPreviewSize(&w, &h);
+ adapterParams.setPictureSize(w,h);
+ }
+
+ ret = mCameraAdapter->setParameters(adapterParams);
+ }
+
+ /// Ensure that buffers for preview are allocated before we start the camera
+ ///Get the updated size from Camera Adapter, to account for padding etc
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW,
+ ( int ) &frame);
+ if ( NO_ERROR != ret )
+ {
+ return ret;
+ }
+
+ ///Update the current preview width and height
+ mPreviewWidth = frame.mWidth;
+ mPreviewHeight = frame.mHeight;
+
+ //Update the padded width and height - required for VNF and VSTAB
+ mParameters.set(TICameraParameters::KEY_PADDED_WIDTH, mPreviewWidth);
+ mParameters.set(TICameraParameters::KEY_PADDED_HEIGHT, mPreviewHeight);
+
+ required_buffer_count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
+
+ ///Allocate the preview buffers
+ ret = allocPreviewBufs(frame.mWidth, frame.mHeight, 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 = mPreviewDataBufs;
+ 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 = mPreviewBufs;
+ desc.mOffsets = mPreviewOffsets;
+ desc.mFd = mPreviewFd;
+ desc.mLength = mPreviewLength;
+ desc.mCount = ( size_t ) required_buffer_count;
+ desc.mMaxQueueable = (size_t) max_queueble_buffers;
+
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW,
+ ( int ) &desc);
+
+ mAppCallbackNotifier->startPreviewCallbacks(mParameters, mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, required_buffer_count);
+
+ ///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;
+ }
+
+ ///Enable the display adapter if present, actual overlay enable happens when we post the buffer
+ if(mDisplayAdapter.get() != NULL)
+ {
+ CAMHAL_LOGDA("Enabling display");
+ bool isS3d = false;
+ DisplayAdapter::S3DParameters s3dParams;
+ int width, height;
+ mParameters.getPreviewSize(&width, &height);
+#if 0 //TODO: s3d is not part of bringup...will reenable
+ if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_SUPPORTED)) != NULL) {
+ isS3d = (strcmp(valstr, "true") == 0);
+ }
+ if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D2D_PREVIEW)) != NULL) {
+ if (strcmp(valstr, "off") == 0)
+ {
+ CAMHAL_LOGEA("STEREO 3D->2D PREVIEW MODE IS OFF");
+ //TODO: obtain the frame packing configuration from camera or user settings
+ //once side by side configuration is supported
+ s3dParams.mode = OVERLAY_S3D_MODE_ON;
+ s3dParams.framePacking = OVERLAY_S3D_FORMAT_OVERUNDER;
+ s3dParams.order = OVERLAY_S3D_ORDER_LF;
+ s3dParams.subSampling = OVERLAY_S3D_SS_NONE;
+ }
+ else
+ {
+ CAMHAL_LOGEA("STEREO 3D->2D PREVIEW MODE IS ON");
+ s3dParams.mode = OVERLAY_S3D_MODE_OFF;
+ s3dParams.framePacking = OVERLAY_S3D_FORMAT_OVERUNDER;
+ s3dParams.order = OVERLAY_S3D_ORDER_LF;
+ s3dParams.subSampling = OVERLAY_S3D_SS_NONE;
+ }
+ }
+#endif //if 0
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ ret = mDisplayAdapter->enableDisplay(width, height, &mStartPreview, isS3d ? &s3dParams : NULL);
+
+#else
+
+ ret = mDisplayAdapter->enableDisplay(width, height, NULL, isS3d ? &s3dParams : NULL);
+
+#endif
+
+ if ( ret != NO_ERROR )
+ {
+ CAMHAL_LOGEA("Couldn't enable display");
+ 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();
+ }
+ 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_LOGEA("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_LOGEA("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
+ mDisplayAdapter = new ANativeWindowDisplayAdapter();
+ 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
+ {
+ /* If mDisplayAdpater is already created. No need to do anything.
+ * We get a surface handle directly now, so we can reconfigure surface
+ * itself in DisplayAdapter if dimensions have changed
+ */
+ }
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+
+}
+
+
+/**
+ @brief Stop a previously started preview.
+
+ @param none
+ @return none
+
+ */
+void CameraHal::stopPreview()
+{
+ LOG_FUNCTION_NAME;
+
+ if(!previewEnabled() && !mDisplayPaused)
+ {
+ LOG_FUNCTION_NAME_EXIT;
+ return;
+ }
+
+ if(mDisplayPaused)
+ {
+ // 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();
+
+ 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;
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&mStartPreview, NULL);
+
+#endif
+
+ if(!previewEnabled())
+ {
+ return NO_INIT;
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ ret = setVideoModeParameters();
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS)));
+ }
+
+ 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 NO_ERROR If recording parameters could be set without any issues
+ @todo Modify the policies for enabling VSTAB & VNF usecase based later.
+
+ */
+status_t CameraHal::setVideoModeParameters()
+{
+ const char *valstr = NULL;
+ bool restartPreviewRequired = false;
+ status_t ret = NO_ERROR;
+
+ 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) ) )
+ {
+ CAMHAL_LOGDA("Set CAPTURE_MODE to VIDEO_MODE");
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, (const char *) TICameraParameters::VIDEO_MODE);
+ restartPreviewRequired = true;
+ }
+
+ // FIXME: This check is put since currently VSTAB and VNF are functional only for Primary Camera.
+ // Remove this check once VSTAB and VNF are functional for Secondary Camera as well.
+ if(mCameraIndex == 0)
+ {
+ // Check if CAPTURE_MODE is VIDEO_MODE, since VSTAB & VNF work only in VIDEO_MODE.
+ valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+ if (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) == 0)
+ {
+ // Enable VSTAB, if not enabled already
+ valstr = mParameters.get(TICameraParameters::KEY_VSTAB);
+ if ( (valstr == NULL) ||
+ ( (valstr != NULL) && (strcmp(valstr, "1") != 0) ) )
+ {
+ CAMHAL_LOGDA("Enable VSTAB");
+ mParameters.set(TICameraParameters::KEY_VSTAB, "1");
+ restartPreviewRequired = true;
+ }
+
+ // Enable VNF, if not enabled already
+ valstr = mParameters.get(TICameraParameters::KEY_VNF);
+ if ( (valstr == NULL) ||
+ ( (valstr != NULL) && (strcmp(valstr, "1") != 0) ) )
+ {
+ CAMHAL_LOGDA("Enable VNF");
+ mParameters.set(TICameraParameters::KEY_VNF, "1");
+ restartPreviewRequired = true;
+ }
+
+ // 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.
+ valstr = mParameters.get(TICameraParameters::KEY_VSTAB);
+ if ((valstr != NULL) && (strcmp(valstr, "1") == 0) && (mPreviewWidth == 1920))
+ {
+ CAMHAL_LOGDA("Force Enable VNF for 1080p");
+ mParameters.set(TICameraParameters::KEY_VNF, "1");
+ restartPreviewRequired = true;
+ }
+ }
+ }
+
+ if (restartPreviewRequired)
+ {
+ CAMHAL_LOGDA("Restarting preview");
+ stopPreview();
+ // Setting CAPTURE_MODE to VIDEO_MODE again, since it is reset in stopPreview()
+ mParameters.set(TICameraParameters::KEY_CAP_MODE, (const char *) TICameraParameters::VIDEO_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()
+{
+ LOG_FUNCTION_NAME;
+
+ if (!mRecordingEnabled )
+ {
+ return;
+ }
+
+ mAppCallbackNotifier->stopRecording();
+
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_VIDEO);
+
+ mRecordingEnabled = false;
+
+ 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;
+
+ if ( NULL != mCameraAdapter )
+ {
+
+#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
+
+ }
+ else
+ {
+ ret = -1;
+ }
+
+ 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;
+ if( NULL != mCameraAdapter )
+ {
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_CANCEL_AUTOFOCUS);
+ }
+ 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;
+
+ if ( NULL != event )
+ {
+ switch( event->mEventType )
+ {
+ case CameraHalEvent::EVENT_FOCUS_LOCKED:
+ case CameraHalEvent::EVENT_FOCUS_ERROR:
+ {
+ if ( mBracketingEnabled )
+ {
+ startImageBracketing();
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ };
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+status_t CameraHal::startImageBracketing()
+{
+ status_t ret = NO_ERROR;
+ CameraFrame frame;
+ CameraAdapter::BuffersDescriptor desc;
+
+#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 = mImageBufs;
+ 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 ( !mBracketingRunning )
+ {
+ return ret;
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ mBracketingRunning = false;
+ }
+
+ if(!previewEnabled() && !mDisplayPaused)
+ {
+ return NO_INIT;
+ }
+
+ if ( NO_ERROR == ret )
+ {
+ 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( )
+{
+ status_t ret = NO_ERROR;
+ CameraFrame frame;
+ CameraAdapter::BuffersDescriptor desc;
+ int burst;
+ unsigned int bufferCount = 1;
+
+ Mutex::Autolock lock(mLock);
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ gettimeofday(&mStartCapture, NULL);
+
+#endif
+
+ LOG_FUNCTION_NAME;
+
+ if(!previewEnabled() && !mDisplayPaused)
+ {
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_INIT;
+ }
+
+ //If capture has already started, then queue this call for later execution
+ if ( mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
+ mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) {
+ return NO_INIT;
+ }
+
+ if ( !mBracketingRunning )
+ {
+
+ if ( NO_ERROR == ret )
+ {
+ burst = mParameters.getInt(TICameraParameters::KEY_BURST);
+ }
+
+ //Allocate all buffers only in burst capture case
+ if ( burst > 1 )
+ {
+ bufferCount = CameraHal::NO_BUFFERS_IMAGE_CAPTURE;
+ if ( NULL != mAppCallbackNotifier.get() )
+ {
+ mAppCallbackNotifier->setBurst(true);
+ }
+ }
+ else
+ {
+ if ( NULL != mAppCallbackNotifier.get() )
+ {
+ mAppCallbackNotifier->setBurst(false);
+ }
+ }
+
+ //Pause Preview during capture
+ if ( (NO_ERROR == ret) && ( NULL != mDisplayAdapter.get() ) && ( burst < 1 ) )
+ {
+ mDisplayPaused = true;
+ mPreviewEnabled = false;
+ ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ mDisplayAdapter->setSnapshotTimeRef(&mStartCapture);
+
+#endif
+ // since preview is paused we should stop sending preview frames too
+ if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
+ {
+ mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
+ }
+ }
+
+ if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
+ {
+
+ //Configure the correct picture resolution now if the capture mode is not set
+ if(mParameters.get(TICameraParameters::KEY_CAP_MODE) == NULL)
+ {
+ ret = mCameraAdapter->setParameters(mParameters);
+ }
+
+ 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 ( NO_ERROR == ret )
+ {
+ mParameters.getPictureSize(( int * ) &frame.mWidth,
+ ( int * ) &frame.mHeight);
+
+ ret = allocImageBufs(frame.mWidth,
+ frame.mHeight,
+ frame.mLength,
+ mParameters.getPictureFormat(),
+ bufferCount);
+ if ( NO_ERROR != ret )
+ {
+ CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
+ }
+ }
+
+ if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
+ {
+ desc.mBuffers = mImageBufs;
+ desc.mOffsets = mImageOffsets;
+ desc.mFd = mImageFd;
+ desc.mLength = mImageLength;
+ desc.mCount = ( size_t ) bufferCount;
+ desc.mMaxQueueable = ( size_t ) bufferCount;
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
+ ( int ) &desc);
+ }
+ }
+ else
+ {
+ mBracketingRunning = false;
+ }
+
+ 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);
+
+#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;
+
+ Mutex::Autolock lock(mLock);
+
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
+
+ return NO_ERROR;
+}
+
+/**
+ @brief Return the camera parameters.
+
+ @param none
+ @return Currently configured camera parameters
+
+ */
+char* CameraHal::getParameters()
+{
+ CameraParameters params;
+ String8 params_str8;
+ char* params_string;
+
+ LOG_FUNCTION_NAME;
+
+ params = mParameters;
+ if( NULL != mCameraAdapter )
+ {
+ mCameraAdapter->getParameters(params);
+ }
+
+ params_str8 = params.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;
+}
+
+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");
+ ret = -EINVAL;
+ }
+
+ if ( ( NO_ERROR == ret ) && ( !previewEnabled() ))
+ {
+ CAMHAL_LOGEA("Preview is not running");
+ ret = -EINVAL;
+ }
+
+ 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);
+
+ case CAMERA_CMD_START_FACE_DETECTION:
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_FD);
+
+ break;
+
+ case CAMERA_CMD_STOP_FACE_DETECTION:
+
+ ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
+
+ break;
+
+ 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)
+{
+ LOG_FUNCTION_NAME;
+
+ ///Initialize all the member variables to their defaults
+ mPreviewEnabled = false;
+ mPreviewBufs = NULL;
+ mImageBufs = NULL;
+ mBufProvider = NULL;
+ mPreviewStartInProgress = false;
+ mVideoBufs = 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;
+ mPreviewDataBufs = NULL;
+ mCameraProperties = NULL;
+ mCurrentTime = 0;
+ mFalsePreview = 0;
+ mImageOffsets = NULL;
+ mImageLength = 0;
+ mImageFd = 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;
+
+#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;
+
+ 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 memory manager
+ mMemoryManager.clear();
+
+ /// Free the display adapter
+ mDisplayAdapter.clear();
+
+ if ( NULL != mCameraAdapter ) {
+ int strongCount = mCameraAdapter->getStrongCount();
+
+ mCameraAdapter->decStrong(mCameraAdapter);
+
+ mCameraAdapter = NULL;
+ }
+
+ 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;
+
+ mLastPreviewFramerate = 0;
+
+ ///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));
+ }
+
+ CAMHAL_LOGDB("Sensor index %d", sensor_index);
+
+ mCameraAdapter = CameraAdapter_Factory();
+ if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties, sensor_index)!=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 = true;
+ status_t status = NO_ERROR;
+ char tmpBuffer[PARAM_BUFFER + 1];
+ char *pos = NULL;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL == supportedResolutions )
+ {
+ CAMHAL_LOGEA("Invalid supported resolutions string");
+ ret = false;
+ goto exit;
+ }
+
+ status = snprintf(tmpBuffer, PARAM_BUFFER, "%dx%d", width, height);
+ if ( 0 > status )
+ {
+ CAMHAL_LOGEA("Error encountered while generating validation string");
+ ret = false;
+ goto exit;
+ }
+
+ pos = strstr(supportedResolutions, tmpBuffer);
+ if ( NULL == pos )
+ {
+ ret = false;
+ }
+ else
+ {
+ ret = true;
+ }
+
+exit:
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+bool CameraHal::isParameterValid(const char *param, const char *supportedParams)
+{
+ bool ret = true;
+ char *pos = NULL;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL == supportedParams )
+ {
+ CAMHAL_LOGEA("Invalid supported parameters string");
+ ret = false;
+ goto exit;
+ }
+
+ if ( NULL == param )
+ {
+ CAMHAL_LOGEA("Invalid parameter string");
+ ret = false;
+ goto exit;
+ }
+
+ pos = strstr(supportedParams, param);
+ if ( NULL == pos )
+ {
+ ret = false;
+ }
+ else
+ {
+ ret = true;
+ }
+
+exit:
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+bool CameraHal::isParameterValid(int param, const char *supportedParams)
+{
+ bool ret = true;
+ char *pos = NULL;
+ status_t status;
+ char tmpBuffer[PARAM_BUFFER + 1];
+
+ LOG_FUNCTION_NAME;
+
+ if ( NULL == supportedParams )
+ {
+ CAMHAL_LOGEA("Invalid supported parameters string");
+ ret = false;
+ goto exit;
+ }
+
+ status = snprintf(tmpBuffer, PARAM_BUFFER, "%d", param);
+ if ( 0 > status )
+ {
+ CAMHAL_LOGEA("Error encountered while generating validation string");
+ ret = false;
+ goto exit;
+ }
+
+ pos = strstr(supportedParams, tmpBuffer);
+ if ( NULL == pos )
+ {
+ ret = false;
+ }
+ else
+ {
+ ret = true;
+ }
+
+exit:
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t CameraHal::parseResolution(const char *resStr, int &width, int &height)
+{
+ status_t ret = NO_ERROR;
+ char *ctx, *pWidth, *pHeight;
+ const char *sep = "x";
+ char *tmp = NULL;
+
+ 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 ) {
+ if ( NO_ERROR == ret )
+ {
+ strcpy(resStr_copy, resStr);
+ pWidth = strtok_r( (char *) 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()
+{
+ char tmpBuffer[PARAM_BUFFER + 1];
+
+ LOG_FUNCTION_NAME;
+
+ 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(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES));
+ p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS));
+ p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES));
+ p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
+ p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));
+ p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_THUMBNAIL_SIZES));
+ p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE));
+ p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS));
+ p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
+ p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES));
+ p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES));
+ p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING));
+ p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MAX));
+ p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MIN));
+ p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_EV_STEP));
+ p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
+ p.set(TICameraParameters::KEY_SUPPORTED_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES));
+ p.set(TICameraParameters::KEY_SUPPORTED_ISO_VALUES, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES));
+ p.set(CameraParameters::KEY_ZOOM_RATIOS, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_RATIOS));
+ p.set(CameraParameters::KEY_MAX_ZOOM, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
+ p.set(CameraParameters::KEY_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::ZOOM_SUPPORTED));
+ p.set(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_SUPPORTED,mCameraProperties->get(CameraProperties::S3D_SUPPORTED));
+ p.set(TICameraParameters::KEY_S3D2D_PREVIEW_MODE,mCameraProperties->get(CameraProperties::S3D2D_PREVIEW_MODES));
+ p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE));
+ p.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, mCameraProperties->get(CameraProperties::MANUALCONVERGENCE_VALUES));
+ p.set(TICameraParameters::KEY_VSTAB,mCameraProperties->get(CameraProperties::VSTAB));
+ p.set(TICameraParameters::KEY_VSTAB_VALUES,mCameraProperties->get(CameraProperties::VSTAB_VALUES));
+ p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
+ p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
+ p.set(TICameraParameters::KEY_SENSOR_ORIENTATION_VALUES, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION_VALUES));
+ p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK_SUPPORTED));
+ p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK_SUPPORTED));
+
+ 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.
+
+ CameraParameters &p = mParameters;
+ int currentRevision, adapterRevision;
+ status_t ret = NO_ERROR;
+ int width, height;
+
+ LOG_FUNCTION_NAME;
+
+ 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(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
+ p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
+ }
+ else
+ {
+ p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, MIN_WIDTH);
+ p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, MIN_HEIGHT);
+ }
+
+ insertSupportedParams();
+
+ //Insert default values
+ p.setPreviewFrameRate(atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)));
+ p.setPreviewFormat(mCameraProperties->get(CameraProperties::PREVIEW_FORMAT));
+ p.setPictureFormat(mCameraProperties->get(CameraProperties::PICTURE_FORMAT));
+ p.set(CameraParameters::KEY_JPEG_QUALITY, mCameraProperties->get(CameraProperties::JPEG_QUALITY));
+ p.set(CameraParameters::KEY_WHITE_BALANCE, mCameraProperties->get(CameraProperties::WHITEBALANCE));
+ p.set(CameraParameters::KEY_EFFECT, mCameraProperties->get(CameraProperties::EFFECT));
+ p.set(CameraParameters::KEY_ANTIBANDING, mCameraProperties->get(CameraProperties::ANTIBANDING));
+ p.set(CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
+ p.set(CameraParameters::KEY_FOCUS_MODE, mCameraProperties->get(CameraProperties::FOCUS_MODE));
+ p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::EV_COMPENSATION));
+ p.set(CameraParameters::KEY_SCENE_MODE, mCameraProperties->get(CameraProperties::SCENE_MODE));
+ p.set(CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
+ p.set(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_ISO, mCameraProperties->get(CameraProperties::ISO_MODE));
+ p.set(TICameraParameters::KEY_IPP, mCameraProperties->get(CameraProperties::IPP));
+ p.set(TICameraParameters::KEY_S3D2D_PREVIEW, mCameraProperties->get(CameraProperties::S3D2D_PREVIEW));
+ p.set(TICameraParameters::KEY_AUTOCONVERGENCE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE));
+ p.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, mCameraProperties->get(CameraProperties::MANUALCONVERGENCE_VALUES));
+ p.set(TICameraParameters::KEY_VSTAB,mCameraProperties->get(CameraProperties::VSTAB));
+ p.set(TICameraParameters::KEY_VSTAB_VALUES,mCameraProperties->get(CameraProperties::VSTAB_VALUES));
+ p.set(CameraParameters::KEY_FOCAL_LENGTH, mCameraProperties->get(CameraProperties::FOCAL_LENGTH));
+ p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::HOR_ANGLE));
+ p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::VER_ANGLE));
+ p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
+ p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
+ p.set(TICameraParameters::KEY_SENSOR_ORIENTATION_VALUES, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION_VALUES));
+ p.set(TICameraParameters::KEY_EXIF_MAKE, mCameraProperties->get(CameraProperties::EXIF_MAKE));
+ p.set(TICameraParameters::KEY_EXIF_MODEL, mCameraProperties->get(CameraProperties::EXIF_MODEL));
+ p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_QUALITY));
+ p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar");
+ p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, mCameraProperties->get(CameraProperties::MAX_FD_HW_FACES));
+ p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, mCameraProperties->get(CameraProperties::MAX_FD_SW_FACES));
+
+ // Only one area a.k.a Touch AF for now.
+ // TODO: Add support for multiple focus areas.
+ p.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, mCameraProperties->get(CameraProperties::MAX_FOCUS_AREAS));
+ p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK));
+ p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK));
+ p.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS, mCameraProperties->get(CameraProperties::MAX_NUM_METERING_AREAS));
+
+ 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
+ stopImageBracketing();
+
+ if(mDisplayAdapter.get() != NULL) {
+ ///Stop the buffer display first
+ mDisplayAdapter->disableDisplay();
+ }
+
+ if(mAppCallbackNotifier.get() != NULL) {
+ //Stop the callback sending
+ mAppCallbackNotifier->stop();
+ mAppCallbackNotifier->stopPreviewCallbacks();
+ }
+
+ // since prerequisite for capturing is for camera system
+ // to be previewing...cancel all captures before stopping
+ // preview
+ if ( mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
+ mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) {
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
+ }
+
+ if ( NULL != mCameraAdapter ) {
+ cancelAutoFocus();
+ //Stop the source of frames
+ mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
+ }
+
+ freePreviewBufs();
+ freePreviewDataBufs();
+
+ mPreviewEnabled = false;
+ mDisplayPaused = 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 ) {
+ forceStopPreview();
+ }
+
+ freeImageBufs();
+
+ mSetPreviewWindowCalled = false;
+
+ if (mSensorListener.get()) {
+ mSensorListener->disableSensor(SensorListener::SENSOR_ORIENTATION);
+ mSensorListener.clear();
+ mSensorListener = NULL;
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+}
+
+status_t CameraHal::storeMetaDataInBuffers(bool enable)
+{
+ LOG_FUNCTION_NAME;
+
+ return mAppCallbackNotifier->useMetaDataBufferMode(enable);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
+};
+
+