blob: 19dfc509f1d38aad4f726df1448ee0480b1e4265 [file] [log] [blame]
/*
** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
**
** 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.
*/
//#define ALOG_NDEBUG 0
#define ALOG_NIDEBUG 0
#define LOG_TAG "QCameraHWI_Parm"
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/threads.h>
//#include <binder/MemoryHeapPmem.h>
#include <utils/String16.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <cutils/properties.h>
#include <math.h>
#if HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
#include <linux/ioctl.h>
#include "QCameraParameters.h"
#include <media/mediarecorder.h>
#include <gralloc_priv.h>
#include "linux/msm_mdp.h"
#include <linux/fb.h>
#include <limits.h>
extern "C" {
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/system_properties.h>
#include <sys/time.h>
#include <stdlib.h>
#include <linux/msm_ion.h>
} // extern "C"
#include "QCameraHWI.h"
#include "QCameraStream.h"
/* QCameraHardwareInterface class implementation goes here*/
/* following code implements the parameter logic of this class*/
#define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
#define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
#define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
#define EXPOSURE_COMPENSATION_DENOMINATOR 6
#define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
#define DEFAULT_CAMERA_AREA "(0, 0, 0, 0, 0)"
#define HDR_HAL_FRAME 2
#define BURST_INTREVAL_MIN 1
#define BURST_INTREVAL_MAX 10
#define BURST_INTREVAL_DEFAULT 1
//Default FPS
#define MINIMUM_FPS 5
#define MAXIMUM_FPS 30
#define DEFAULT_FIXED_FPS 30
#define DEFAULT_FPS 30
//Default Picture Width
#define DEFAULT_PICTURE_WIDTH 640
#define DEFAULT_PICTURE_HEIGHT 480
//Default Video Width
#define DEFAULT_VIDEO_WIDTH 1920
#define DEFAULT_VIDEO_HEIGHT 1088
#define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
#define DEFAULT_THUMBNAIL_SETTING 4
#define THUMBNAIL_WIDTH_STR "512"
#define THUMBNAIL_HEIGHT_STR "384"
#define THUMBNAIL_SMALL_HEIGHT 144
#define DONT_CARE_COORDINATE -1
//for histogram stats
#define HISTOGRAM_STATS_SIZE 257
//Supported preview fps ranges should be added to this array in the form (minFps,maxFps)
static android::FPSRange FpsRangesSupported[] = {
android::FPSRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000)
};
#define FPS_RANGES_SUPPORTED_COUNT (sizeof(FpsRangesSupported)/sizeof(FpsRangesSupported[0]))
typedef struct {
uint32_t aspect_ratio;
uint32_t width;
uint32_t height;
} thumbnail_size_type;
static thumbnail_size_type thumbnail_sizes[] = {
{ 7281, 512, 288 }, //1.777778
{ 6826, 480, 288 }, //1.666667
{ 6808, 256, 154 }, //1.66233
{ 6144, 432, 288 }, //1.5
{ 5461, 512, 384 }, //1.333333
{ 5006, 352, 288 }, //1.222222
{ 5461, 320, 240 }, //1.33333
{ 5006, 176, 144 }, //1.222222
};
static struct camera_size_type zsl_picture_sizes[] = {
{ 1280, 960}, // 1.3MP
{ 800, 600}, //SVGA
{ 800, 480}, // WVGA
{ 640, 480}, // VGA
{ 352, 288}, //CIF
{ 320, 240}, // QVGA
{ 176, 144} // QCIF
};
static camera_size_type default_picture_sizes[] = {
{ 4000, 3000}, // 12MP
{ 3264, 2448}, // 8MP
{ 3264, 1836}, // Picture Size to match 1080p,720p AR
{ 3264, 2176}, // Picture Size to match 480p AR
{ 2592, 1944}, // 5MP
{ 2048, 1536}, // 3MP QXGA
{ 1920, 1080}, // HD1080
{ 1600, 1200}, // 2MP UXGA
{ 1280, 960}, // 1.3MP
{ 1280, 720},
{ 720, 480},
{ 800, 480}, // WVGA
{ 640, 480}, // VGA
{ 352, 288}, // CIF
{ 320, 240}, // QVGA
{ 176, 144} // QCIF
};
static int iso_speed_values[] = {
0, 1, 100, 200, 400, 800, 1600
};
extern int HAL_numOfCameras;
extern qcamera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS];
extern mm_camera_t * HAL_camerahandle[MSM_MAX_CAMERA_SENSORS];
namespace android {
static uint32_t HFR_SIZE_COUNT=2;
static const int PICTURE_FORMAT_JPEG = 1;
static const int PICTURE_FORMAT_RAW = 2;
/********************************************************************/
static const str_map effects[] = {
{ QCameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
{ QCameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
{ QCameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
{ QCameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
{ QCameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
{ QCameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
{ QCameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
{ QCameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
{ QCameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA },
{ QCameraParameters::EFFECT_EMBOSS, CAMERA_EFFECT_EMBOSS },
{ QCameraParameters::EFFECT_SKETCH, CAMERA_EFFECT_SKETCH },
{ QCameraParameters::EFFECT_NEON, CAMERA_EFFECT_NEON }
};
static const str_map iso[] = {
{ QCameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
{ QCameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
{ QCameraParameters::ISO_100, CAMERA_ISO_100},
{ QCameraParameters::ISO_200, CAMERA_ISO_200},
{ QCameraParameters::ISO_400, CAMERA_ISO_400},
{ QCameraParameters::ISO_800, CAMERA_ISO_800 },
{ QCameraParameters::ISO_1600, CAMERA_ISO_1600 }
};
static const str_map scenemode[] = {
{ QCameraParameters::SCENE_MODE_AUTO, CAMERA_BESTSHOT_OFF },
{ QCameraParameters::SCENE_MODE_ASD, CAMERA_BESTSHOT_AUTO },
{ QCameraParameters::SCENE_MODE_ACTION, CAMERA_BESTSHOT_ACTION },
{ QCameraParameters::SCENE_MODE_PORTRAIT, CAMERA_BESTSHOT_PORTRAIT },
{ QCameraParameters::SCENE_MODE_LANDSCAPE, CAMERA_BESTSHOT_LANDSCAPE },
{ QCameraParameters::SCENE_MODE_NIGHT, CAMERA_BESTSHOT_NIGHT },
{ QCameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
{ QCameraParameters::SCENE_MODE_THEATRE, CAMERA_BESTSHOT_THEATRE },
{ QCameraParameters::SCENE_MODE_BEACH, CAMERA_BESTSHOT_BEACH },
{ QCameraParameters::SCENE_MODE_SNOW, CAMERA_BESTSHOT_SNOW },
{ QCameraParameters::SCENE_MODE_SUNSET, CAMERA_BESTSHOT_SUNSET },
{ QCameraParameters::SCENE_MODE_STEADYPHOTO, CAMERA_BESTSHOT_ANTISHAKE },
{ QCameraParameters::SCENE_MODE_FIREWORKS , CAMERA_BESTSHOT_FIREWORKS },
{ QCameraParameters::SCENE_MODE_SPORTS , CAMERA_BESTSHOT_SPORTS },
{ QCameraParameters::SCENE_MODE_PARTY, CAMERA_BESTSHOT_PARTY },
{ QCameraParameters::SCENE_MODE_CANDLELIGHT, CAMERA_BESTSHOT_CANDLELIGHT },
{ QCameraParameters::SCENE_MODE_BACKLIGHT, CAMERA_BESTSHOT_BACKLIGHT },
{ QCameraParameters::SCENE_MODE_FLOWERS, CAMERA_BESTSHOT_FLOWERS },
{ QCameraParameters::SCENE_MODE_AR, CAMERA_BESTSHOT_AR },
{ QCameraParameters::SCENE_MODE_HDR, CAMERA_BESTSHOT_AUTO },
};
static const str_map scenedetect[] = {
{ QCameraParameters::SCENE_DETECT_OFF, false },
{ QCameraParameters::SCENE_DETECT_ON, true },
};
#define DONT_CARE AF_MODE_MAX
static const str_map focus_modes[] = {
{ QCameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
{ QCameraParameters::FOCUS_MODE_INFINITY, AF_MODE_INFINITY },
{ QCameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL },
{ QCameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO },
{ QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, AF_MODE_CAF},
{ QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, AF_MODE_CAF }
};
static const str_map selectable_zone_af[] = {
{ QCameraParameters::SELECTABLE_ZONE_AF_AUTO, AUTO },
{ QCameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT },
{ QCameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED },
{ QCameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE }
};
static const str_map autoexposure[] = {
{ QCameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
{ QCameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
{ QCameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
};
// from aeecamera.h
static const str_map whitebalance[] = {
{ QCameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
{ QCameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
{ QCameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
{ QCameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
{ QCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
};
static const str_map antibanding[] = {
{ QCameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
{ QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
{ QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
{ QCameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
};
static const str_map frame_rate_modes[] = {
{QCameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
{QCameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
};
static const str_map touchafaec[] = {
{ QCameraParameters::TOUCH_AF_AEC_OFF, false },
{ QCameraParameters::TOUCH_AF_AEC_ON, true }
};
static const str_map hfr[] = {
{ QCameraParameters::VIDEO_HFR_OFF, CAMERA_HFR_MODE_OFF },
{ QCameraParameters::VIDEO_HFR_2X, CAMERA_HFR_MODE_60FPS },
{ QCameraParameters::VIDEO_HFR_3X, CAMERA_HFR_MODE_90FPS },
{ QCameraParameters::VIDEO_HFR_4X, CAMERA_HFR_MODE_120FPS },
};
static const int HFR_VALUES_COUNT = (sizeof(hfr)/sizeof(str_map));
static const str_map flash[] = {
{ QCameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
{ QCameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
{ QCameraParameters::FLASH_MODE_ON, LED_MODE_ON },
{ QCameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
};
static const str_map lensshade[] = {
{ QCameraParameters::LENSSHADE_ENABLE, true },
{ QCameraParameters::LENSSHADE_DISABLE, false }
};
static const str_map mce[] = {
{ QCameraParameters::MCE_ENABLE, true },
{ QCameraParameters::MCE_DISABLE, false }
};
static const str_map histogram[] = {
{ QCameraParameters::HISTOGRAM_ENABLE, true },
{ QCameraParameters::HISTOGRAM_DISABLE, false }
};
static const str_map skinToneEnhancement[] = {
{ QCameraParameters::SKIN_TONE_ENHANCEMENT_ENABLE, true },
{ QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE, false }
};
static const str_map denoise[] = {
{ QCameraParameters::DENOISE_OFF, false },
{ QCameraParameters::DENOISE_ON, true }
};
static const str_map facedetection[] = {
{ QCameraParameters::FACE_DETECTION_OFF, false },
{ QCameraParameters::FACE_DETECTION_ON, true }
};
static const str_map redeye_reduction[] = {
{ QCameraParameters::REDEYE_REDUCTION_ENABLE, true },
{ QCameraParameters::REDEYE_REDUCTION_DISABLE, false }
};
static const str_map picture_formats[] = {
{QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
{QCameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
};
static const str_map recording_Hints[] = {
{"false", false},
{"true", true}
};
static const str_map preview_formats[] = {
{QCameraParameters::PIXEL_FORMAT_YUV420SP, HAL_PIXEL_FORMAT_YCrCb_420_SP},
{QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO},
{QCameraParameters::PIXEL_FORMAT_YV12, HAL_PIXEL_FORMAT_YV12},
{QCameraParameters::PIXEL_FORMAT_YUV420P,HAL_PIXEL_FORMAT_YV12},
{QCameraParameters::PIXEL_FORMAT_NV12, HAL_PIXEL_FORMAT_YCbCr_420_SP}
};
static const preview_format_info_t preview_format_info_list[] = {
{HAL_PIXEL_FORMAT_YCrCb_420_SP, CAMERA_YUV_420_NV21, CAMERA_PAD_TO_WORD, 2},
{HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO, CAMERA_YUV_420_NV21, CAMERA_PAD_TO_4K, 2},
{HAL_PIXEL_FORMAT_YCbCr_420_SP, CAMERA_YUV_420_NV12, CAMERA_PAD_TO_WORD, 2},
{HAL_PIXEL_FORMAT_YV12, CAMERA_YUV_420_YV12, CAMERA_PAD_TO_WORD, 3}
};
static const str_map zsl_modes[] = {
{ QCameraParameters::ZSL_OFF, false },
{ QCameraParameters::ZSL_ON, true },
};
static const str_map hdr_bracket[] = {
{ QCameraParameters::AE_BRACKET_HDR_OFF,HDR_BRACKETING_OFF},
{ QCameraParameters::AE_BRACKET_HDR,HDR_MODE },
};
typedef enum {
NORMAL_POWER,
LOW_POWER
} power_mode;
static const str_map power_modes[] = {
{ QCameraParameters::NORMAL_POWER,NORMAL_POWER },
{ QCameraParameters::LOW_POWER,LOW_POWER }
};
/**************************************************************************/
static int attr_lookup(const str_map arr[], int len, const char *name)
{
if (name) {
for (int i = 0; i < len; i++) {
if (!strcmp(arr[i].desc, name))
return arr[i].val;
}
}
return NOT_FOUND;
}
bool QCameraHardwareInterface::native_set_parms(
mm_camera_parm_type_t type, uint16_t length, void *value)
{
ALOGV("%s : type : %d Value : %d",__func__,type,*((int *)value));
if(MM_CAMERA_OK != cam_config_set_parm(mCameraId, type,value )) {
ALOGE("native_set_parms failed: type %d length %d error %s",
type, length, strerror(errno));
return false;
}
return true;
}
bool QCameraHardwareInterface::native_set_parms(
mm_camera_parm_type_t type, uint16_t length, void *value, int *result)
{
*result= cam_config_set_parm(mCameraId, type,value );
if(MM_CAMERA_OK == *result) {
ALOGV("native_set_parms: succeeded : %d", *result);
return true;
}
ALOGE("native_set_parms failed: type %d length %d error str %s error# %d",
type, length, strerror(errno), errno);
return false;
}
//Filter Picture sizes based on max width and height
/* TBD: do we still need this - except for ZSL? */
void QCameraHardwareInterface::filterPictureSizes(){
unsigned int i;
if(mPictureSizeCount <= 0)
return;
maxSnapshotWidth = mPictureSizes[0].width;
maxSnapshotHeight = mPictureSizes[0].height;
// Iterate through all the width and height to find the max value
for(i =0; i<mPictureSizeCount;i++){
if(((maxSnapshotWidth < mPictureSizes[i].width) &&
(maxSnapshotHeight <= mPictureSizes[i].height))){
maxSnapshotWidth = mPictureSizes[i].width;
maxSnapshotHeight = mPictureSizes[i].height;
}
}
if(myMode & CAMERA_ZSL_MODE){
// due to lack of PMEM we restrict to lower resolution
mPictureSizesPtr = zsl_picture_sizes;
mSupportedPictureSizesCount = 7;
}else{
mPictureSizesPtr = mPictureSizes;
mSupportedPictureSizesCount = mPictureSizeCount;
}
}
static String8 create_sizes_str(const camera_size_type *sizes, int len) {
String8 str;
char buffer[32];
if (len > 0) {
snprintf(buffer, sizeof(buffer), "%dx%d", sizes[0].width, sizes[0].height);
str.append(buffer);
}
for (int i = 1; i < len; i++) {
snprintf(buffer, sizeof(buffer), ",%dx%d", sizes[i].width, sizes[i].height);
str.append(buffer);
}
return str;
}
String8 QCameraHardwareInterface::create_values_str(const str_map *values, int len) {
String8 str;
if (len > 0) {
str.append(values[0].desc);
}
for (int i = 1; i < len; i++) {
str.append(",");
str.append(values[i].desc);
}
return str;
}
static String8 create_fps_str(const android:: FPSRange* fps, int len) {
String8 str;
char buffer[32];
if (len > 0) {
snprintf(buffer, sizeof(buffer), "(%d,%d)", fps[0].minFPS, fps[0].maxFPS);
str.append(buffer);
}
for (int i = 1; i < len; i++) {
snprintf(buffer, sizeof(buffer), ",(%d,%d)", fps[i].minFPS, fps[i].maxFPS);
str.append(buffer);
}
return str;
}
static String8 create_values_range_str(int min, int max){
String8 str;
char buffer[32];
if(min <= max){
snprintf(buffer, sizeof(buffer), "%d", min);
str.append(buffer);
for (int i = min + 1; i <= max; i++) {
snprintf(buffer, sizeof(buffer), ",%d", i);
str.append(buffer);
}
}
return str;
}
static int parse_size(const char *str, int &width, int &height)
{
// Find the width.
char *end;
int w = (int)strtol(str, &end, 10);
// If an 'x' or 'X' does not immediately follow, give up.
if ( (*end != 'x') && (*end != 'X') )
return -1;
// Find the height, immediately after the 'x'.
int h = (int)strtol(end+1, 0, 10);
width = w;
height = h;
return 0;
}
bool QCameraHardwareInterface::isValidDimension(int width, int height) {
bool retVal = false;
/* This function checks if a given resolution is valid or not.
* A particular resolution is considered valid if it satisfies
* the following conditions:
* 1. width & height should be multiple of 16.
* 2. width & height should be less than/equal to the dimensions
* supported by the camera sensor.
* 3. the aspect ratio is a valid aspect ratio and is among the
* commonly used aspect ratio as determined by the thumbnail_sizes
* data structure.
*/
if( (width == CEILING16(width)) && (height == CEILING16(height))
&& (width <= maxSnapshotWidth)
&& (height <= maxSnapshotHeight) )
{
uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height);
for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) {
if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) {
retVal = true;
break;
}
}
}
return retVal;
}
void QCameraHardwareInterface::hasAutoFocusSupport(){
ALOGV("%s",__func__);
if(isZSLMode()){
mHasAutoFocusSupport = false;
return;
}
if(cam_ops_is_op_supported (mCameraId, MM_CAMERA_OPS_FOCUS )) {
mHasAutoFocusSupport = true;
}
else {
ALOGV("AutoFocus is not supported");
mHasAutoFocusSupport = false;
}
ALOGV("%s:rc= %d",__func__, mHasAutoFocusSupport);
}
bool QCameraHardwareInterface::supportsSceneDetection() {
bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_ASD_ENABLE);
return rc;
}
bool QCameraHardwareInterface::supportsFaceDetection() {
bool rc;
status_t ret = NO_ERROR;
mm_camera_op_mode_type_t op_mode;
ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_OP_MODE, &op_mode);
if(ret != NO_ERROR){
ALOGE("%s: Failed to get Op Mode", __func__);
}
ALOGV("%s: OP_Mode is %d, ret=%d, mHdrMode=%d",__func__,op_mode,ret,mHdrMode);
if ((ret == NO_ERROR) && (op_mode == MM_CAMERA_OP_MODE_VIDEO) && (mHdrMode != HDR_MODE))
{
ALOGV("%s: Video mode : FD not supported",__func__);
return false;
}
else{
rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_FD);
ALOGV("%s: Still mode : FD supported : %d",__func__,rc);
return rc;
}
}
bool QCameraHardwareInterface::supportsSelectableZoneAf() {
bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_FOCUS_RECT);
return rc;
}
bool QCameraHardwareInterface::supportsRedEyeReduction() {
bool rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_REDEYE_REDUCTION);
return rc;
}
static String8 create_str(int16_t *arr, int length){
String8 str;
char buffer[32] = {0};
if(length > 0){
snprintf(buffer, sizeof(buffer), "%d", arr[0]);
str.append(buffer);
}
for (int i =1;i<length;i++){
snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
str.append(buffer);
}
return str;
}
bool QCameraHardwareInterface::getMaxPictureDimension(mm_camera_dimension_t *maxDim)
{
bool ret = NO_ERROR;
mm_camera_dimension_t dim;
ret = cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_MAX_PICTURE_SIZE, &dim);
if (ret != NO_ERROR)
return ret;
/* Find the first dimension in the mPictureSizes
* array which is smaller than the max dimension.
* This will be the valid max picture resolution */
for (unsigned int i = 0; i < mPictureSizeCount; i++) {
if ((mPictureSizes[i].width <= dim.width) &&
(mPictureSizes[i].height <= dim.height)) {
maxDim->height = mPictureSizes[i].height;
maxDim->width = mPictureSizes[i].width;
break;
}
}
ALOGV("%s: Found Max Picture dimension: %d x %d", __func__,
maxDim->width, maxDim->height);
return ret;
}
void QCameraHardwareInterface::loadTables()
{
bool ret = NO_ERROR;
ALOGV("%s: E", __func__);
ret = cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_PREVIEW_SIZES_CNT, &preview_sizes_count);
default_sizes_tbl_t preview_sizes_tbl;
preview_sizes_tbl.tbl_size=preview_sizes_count;
preview_sizes_tbl.sizes_tbl=&default_preview_sizes[0];
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_DEF_PREVIEW_SIZES, &preview_sizes_tbl)){
ALOGE("%s:Failed to get default preview sizes",__func__);
}
ret = cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_VIDEO_SIZES_CNT, &video_sizes_count);
default_sizes_tbl_t video_sizes_tbl;
video_sizes_tbl.tbl_size=video_sizes_count;
video_sizes_tbl.sizes_tbl=&default_video_sizes[0];
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_DEF_VIDEO_SIZES, &video_sizes_tbl)){
ALOGE("%s:Failed to get default video sizes",__func__);
}
ret = cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_THUMB_SIZES_CNT, &thumbnail_sizes_count);
default_sizes_tbl_t thumbnail_sizes_tbl;
thumbnail_sizes_tbl.tbl_size=thumbnail_sizes_count;
thumbnail_sizes_tbl.sizes_tbl=&default_thumbnail_sizes[0];
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_DEF_THUMB_SIZES, &thumbnail_sizes_tbl)){
ALOGE("%s:Failed to get default thumbnail sizes",__func__);
}
ret = cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_HFR_SIZES_CNT, &hfr_sizes_count);
default_sizes_tbl_t hfr_sizes_tbl;
hfr_sizes_tbl.tbl_size=hfr_sizes_count;
hfr_sizes_tbl.sizes_tbl=&default_hfr_sizes[0];
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_DEF_HFR_SIZES, &hfr_sizes_tbl)){
ALOGE("%s:Failed to get default HFR sizes",__func__);
}
ALOGV("%s: X", __func__);
}
rat_t getRational(int num, int denom)
{
rat_t temp = {num, denom};
return temp;
}
void QCameraHardwareInterface::initDefaultParameters()
{
bool ret;
char prop[PROPERTY_VALUE_MAX];
mm_camera_dimension_t maxDim;
int rc = MM_CAMERA_OK;
ALOGV("%s: E", __func__);
memset(&maxDim, 0, sizeof(mm_camera_dimension_t));
ret = getMaxPictureDimension(&maxDim);
if (ret != NO_ERROR) {
ALOGE("%s: Cannot get Max picture size supported", __func__);
return;
}
if (!maxDim.width || !maxDim.height) {
maxDim.width = DEFAULT_LIVESHOT_WIDTH;
maxDim.height = DEFAULT_LIVESHOT_HEIGHT;
}
memset(prop, 0, sizeof(prop));
property_get("persist.camera.snap.format", prop, "0");
mSnapshotFormat = atoi(prop);
ALOGV("%s: prop =(%s), snap_format=%d", __func__, prop, mSnapshotFormat);
//cam_ctrl_dimension_t dim;
mHFRLevel = 0;
memset(&mDimension, 0, sizeof(cam_ctrl_dimension_t));
memset(&mPreviewFormatInfo, 0, sizeof(preview_format_info_t));
mDimension.video_width = DEFAULT_VIDEO_WIDTH;
mDimension.video_height = DEFAULT_VIDEO_HEIGHT;
// mzhu mDimension.picture_width = DEFAULT_STREAM_WIDTH;
// mzhu mDimension.picture_height = DEFAULT_STREAM_HEIGHT;
mDimension.picture_width = maxDim.width;
mDimension.picture_height = maxDim.height;
mDimension.display_width = DEFAULT_STREAM_WIDTH;
mDimension.display_height = DEFAULT_STREAM_HEIGHT;
mDimension.orig_picture_dx = mDimension.picture_width;
mDimension.orig_picture_dy = mDimension.picture_height;
mDimension.ui_thumbnail_width = DEFAULT_STREAM_WIDTH;
mDimension.ui_thumbnail_height = DEFAULT_STREAM_HEIGHT;
mDimension.orig_video_width = DEFAULT_STREAM_WIDTH;
mDimension.orig_video_height = DEFAULT_STREAM_HEIGHT;
mDimension.prev_format = CAMERA_YUV_420_NV21;
mDimension.enc_format = CAMERA_YUV_420_NV12;
if (mSnapshotFormat == 1) {
mDimension.main_img_format = CAMERA_YUV_422_NV61;
} else {
mDimension.main_img_format = CAMERA_YUV_420_NV21;
}
mDimension.thumb_format = CAMERA_YUV_420_NV21;
ALOGV("%s: main_img_format =%d, thumb_format=%d", __func__,
mDimension.main_img_format, mDimension.thumb_format);
mDimension.prev_padding_format = CAMERA_PAD_TO_WORD;
ret = native_set_parms(MM_CAMERA_PARM_DIMENSION,
sizeof(cam_ctrl_dimension_t), (void *) &mDimension);
if(!ret) {
ALOGE("MM_CAMERA_PARM_DIMENSION Failed.");
return;
}
hasAutoFocusSupport();
// Initialize constant parameter strings. This will happen only once in the
// lifetime of the mediaserver process.
if (true/*!mParamStringInitialized*/) {
//filter picture sizes
filterPictureSizes();
mPictureSizeValues = create_sizes_str(
mPictureSizesPtr, mSupportedPictureSizesCount);
mPreviewSizeValues = create_sizes_str(
mPreviewSizes, mPreviewSizeCount);
mVideoSizeValues = create_sizes_str(
mVideoSizes, mVideoSizeCount);
//Query for max HFR value
camera_hfr_mode_t maxHFR;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_MAX_HFR_MODE, (void *)&maxHFR);
//Filter HFR values and build parameter string
String8 str;
for(int i=0; i<HFR_VALUES_COUNT; i++){
if(hfr[i].val <= maxHFR){
if(i>0) str.append(",");
str.append(hfr[i].desc);
}
}
mHfrValues = str;
mHfrSizeValues = create_sizes_str(
default_hfr_sizes, hfr_sizes_count);
mFpsRangesSupportedValues = create_fps_str(
FpsRangesSupported,FPS_RANGES_SUPPORTED_COUNT );
mParameters.set(
QCameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
mFpsRangesSupportedValues);
mParameters.setPreviewFpsRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000);
mFlashValues = create_values_str(
flash, sizeof(flash) / sizeof(str_map));
mLensShadeValues = create_values_str(
lensshade,sizeof(lensshade)/sizeof(str_map));
mMceValues = create_values_str(
mce,sizeof(mce)/sizeof(str_map));
mEffectValues = create_values_str(effects, sizeof(effects) / sizeof(str_map));
mAntibandingValues = create_values_str(
antibanding, sizeof(antibanding) / sizeof(str_map));
mIsoValues = create_values_str(iso,sizeof(iso)/sizeof(str_map));
mAutoExposureValues = create_values_str(
autoexposure, sizeof(autoexposure) / sizeof(str_map));
mWhitebalanceValues = create_values_str(
whitebalance, sizeof(whitebalance) / sizeof(str_map));
if(mHasAutoFocusSupport){
mFocusModeValues = create_values_str(
focus_modes, sizeof(focus_modes) / sizeof(str_map));
}
mSceneModeValues = create_values_str(scenemode, sizeof(scenemode) / sizeof(str_map));
if(mHasAutoFocusSupport){
mTouchAfAecValues = create_values_str(
touchafaec,sizeof(touchafaec)/sizeof(str_map));
}
//Currently Enabling Histogram for 8x60
mHistogramValues = create_values_str(
histogram,sizeof(histogram)/sizeof(str_map));
mSkinToneEnhancementValues = create_values_str(
skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map));
mPictureFormatValues = create_values_str(
picture_formats, sizeof(picture_formats)/sizeof(str_map));
mZoomSupported=false;
mMaxZoom=0;
mm_camera_zoom_tbl_t zmt;
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_MAXZOOM, &mMaxZoom)){
ALOGE("%s:Failed to get max zoom",__func__);
}else{
ALOGV("Max Zoom:%d",mMaxZoom);
/* Kernel driver limits the max amount of data that can be retreived through a control
command to 260 bytes hence we conservatively limit to 110 zoom ratios */
if(mMaxZoom>MAX_ZOOM_RATIOS) {
ALOGV("%s:max zoom is larger than sizeof zoomRatios table",__func__);
mMaxZoom=MAX_ZOOM_RATIOS-1;
}
zmt.size=mMaxZoom;
zmt.zoom_ratio_tbl=&zoomRatios[0];
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_ZOOM_RATIO, &zmt)){
ALOGE("%s:Failed to get max zoom ratios",__func__);
}else{
mZoomSupported=true;
mZoomRatioValues = create_str(zoomRatios, mMaxZoom);
}
}
ALOGV("Zoom supported:%d",mZoomSupported);
denoise_value = create_values_str(
denoise, sizeof(denoise) / sizeof(str_map));
if(supportsFaceDetection()) {
mFaceDetectionValues = create_values_str(
facedetection, sizeof(facedetection) / sizeof(str_map));
}
if(mHasAutoFocusSupport){
mSelectableZoneAfValues = create_values_str(
selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
}
mSceneDetectValues = create_values_str(scenedetect, sizeof(scenedetect) / sizeof(str_map));
mRedeyeReductionValues = create_values_str(
redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map));
mZslValues = create_values_str(
zsl_modes,sizeof(zsl_modes)/sizeof(str_map));
mParamStringInitialized = true;
}
//set supported video sizes
mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_SIZES, mVideoSizeValues.string());
//set default video size to first one in supported table
String8 vSize = create_sizes_str(&mVideoSizes[0], 1);
mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, vSize.string());
//Set Preview size
int default_preview_width, default_preview_height;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DEFAULT_PREVIEW_WIDTH,
&default_preview_width);
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DEFAULT_PREVIEW_HEIGHT,
&default_preview_height);
mParameters.setPreviewSize(default_preview_width, default_preview_height);
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
mPreviewSizeValues.string());
mDimension.display_width = default_preview_width;
mDimension.display_height = default_preview_height;
//Set Preview Frame Rate
if(mFps >= MINIMUM_FPS && mFps <= MAXIMUM_FPS) {
mPreviewFrameRateValues = create_values_range_str(
MINIMUM_FPS, mFps);
}else{
mPreviewFrameRateValues = create_values_range_str(
MINIMUM_FPS, MAXIMUM_FPS);
}
if (cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS)) {
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
mPreviewFrameRateValues.string());
} else {
mParameters.set(
QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
DEFAULT_FIXED_FPS);
}
//Set Preview Frame Rate Modes
mParameters.setPreviewFrameRateMode("frame-rate-auto");
mFrameRateModeValues = create_values_str(
frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
if(cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS_MODE)){
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
mFrameRateModeValues.string());
}
//Set Preview Format
//mParameters.setPreviewFormat("yuv420sp"); // informative
mParameters.setPreviewFormat(QCameraParameters::PIXEL_FORMAT_YUV420SP);
mPreviewFormatValues = create_values_str(
preview_formats, sizeof(preview_formats) / sizeof(str_map));
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
mPreviewFormatValues.string());
//Set Overlay Format
mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
mParameters.set("max-num-detected-faces-hw", "2");
// Set supported max faces
int maxNumFaces = 0;
if (supportsFaceDetection()) {
//Query the maximum number of faces supported by hardware.
if(MM_CAMERA_OK != cam_config_get_parm(mCameraId,
MM_CAMERA_PARM_MAX_NUM_FACES_DECT, &maxNumFaces)){
ALOGE("%s:Failed to get max number of faces supported",__func__);
}
}
mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, maxNumFaces);
//This paramtere is set to default here. This will be changed by application
//if it needs to support specific number of faces. See also setParameters.
mParameters.set(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES, 2);
// Set camera features supported flag
int32_t featureFlag = 0;
if (supportsFaceDetection()) {
featureFlag |= 0x00000001; // bit 0 indicate faciral feature
}
mParameters.set(QCameraParameters::KEY_SUPPORTED_CAMERA_FEATURES, featureFlag);
//Set Picture Size
mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
mPictureSizeValues.string());
//Set Preview Frame Rate
if(mFps >= MINIMUM_FPS && mFps <= MAXIMUM_FPS) {
mParameters.setPreviewFrameRate(mFps);
}else{
mParameters.setPreviewFrameRate(DEFAULT_FPS);
}
//Set Picture Format
mParameters.setPictureFormat("jpeg"); // informative
mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
mPictureFormatValues);
mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, "90"); // max quality
mJpegQuality = 90;
//Set Video Format
mParameters.set(QCameraParameters::KEY_VIDEO_FRAME_FORMAT, "yuv420sp");
//Set Thumbnail parameters
mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
THUMBNAIL_WIDTH_STR); // informative
mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
THUMBNAIL_HEIGHT_STR); // informative
mDimension.ui_thumbnail_width =
thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
mDimension.ui_thumbnail_height =
thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
String8 valuesStr = create_sizes_str(default_thumbnail_sizes, thumbnail_sizes_count);
mParameters.set(QCameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
valuesStr.string());
// Define CAMERA_SMOOTH_ZOOM in Android.mk file , to enable smoothzoom
#ifdef CAMERA_SMOOTH_ZOOM
mParameters.set(QCameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, "true");
#endif
if(mZoomSupported){
mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "true");
ALOGV("max zoom is %d", mMaxZoom-1);
/* mMaxZoom value that the query interface returns is the size
ALOGV("max zoom is %d", mMaxZoom-1);
* mMaxZoom value that the query interface returns is the size
* of zoom table. So the actual max zoom value will be one
* less than that value. */
mParameters.set("max-zoom",mMaxZoom-1);
mParameters.set(QCameraParameters::KEY_ZOOM_RATIOS,
mZoomRatioValues);
} else
{
mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "false");
}
/* Enable zoom support for video application if VPE enabled */
if(mZoomSupported) {
mParameters.set("video-zoom-support", "true");
} else {
mParameters.set("video-zoom-support", "false");
}
//8960 supports Power modes : Low power, Normal Power.
mParameters.set("power-mode-supported", "true");
//Set Live shot support
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_LIVESHOT_MAIN);
if(!rc) {
ALOGV("%s:LIVESHOT is not supported", __func__);
mParameters.set("video-snapshot-supported", "false");
} else {
mParameters.set("video-snapshot-supported", "true");
}
//Set default power mode
mParameters.set(QCameraParameters::KEY_POWER_MODE,"Low_Power");
//Set Wnr on
mParameters.set(QCameraParameters::KEY_DENOISE,true);
//Set Camera Mode
mParameters.set(QCameraParameters::KEY_CAMERA_MODE,1);
mParameters.set(QCameraParameters::KEY_AE_BRACKET_HDR,"Off");
//Set Antibanding
mParameters.set(QCameraParameters::KEY_ANTIBANDING,
QCameraParameters::ANTIBANDING_AUTO);
mParameters.set(QCameraParameters::KEY_SUPPORTED_ANTIBANDING,
mAntibandingValues);
//Set Effect
mParameters.set(QCameraParameters::KEY_EFFECT,
QCameraParameters::EFFECT_NONE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_EFFECTS, mEffectValues);
//Set Auto Exposure
mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE,
QCameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED);
mParameters.set(QCameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, mAutoExposureValues);
//Set WhiteBalance
mParameters.set(QCameraParameters::KEY_WHITE_BALANCE,
QCameraParameters::WHITE_BALANCE_AUTO);
mParameters.set(QCameraParameters::KEY_SUPPORTED_WHITE_BALANCE,mWhitebalanceValues);
//Set AEC_LOCK
mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE_LOCK, "false");
if(cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_AEC_LOCK)){
mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "true");
} else {
mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "false");
}
//Set AWB_LOCK
mParameters.set(QCameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, "false");
if(cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_AWB_LOCK))
mParameters.set(QCameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "true");
else
mParameters.set(QCameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "false");
//Set Focus Mode
if(mHasAutoFocusSupport){
mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
QCameraParameters::FOCUS_MODE_AUTO);
mFocusMode = AF_MODE_AUTO;
mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
mFocusModeValues);
mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
mParameters.set(QCameraParameters::KEY_MAX_NUM_METERING_AREAS, "1");
} else {
mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
QCameraParameters::FOCUS_MODE_INFINITY);
mFocusMode = DONT_CARE;
mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
QCameraParameters::FOCUS_MODE_INFINITY);
mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "0");
mParameters.set(QCameraParameters::KEY_MAX_NUM_METERING_AREAS, "0");
}
mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, DEFAULT_CAMERA_AREA);
mParameters.set(QCameraParameters::KEY_METERING_AREAS, DEFAULT_CAMERA_AREA);
//Set Flash
if (cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_LED_MODE)) {
mParameters.set(QCameraParameters::KEY_FLASH_MODE,
QCameraParameters::FLASH_MODE_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_FLASH_MODES,
mFlashValues);
}
//Set Sharpness
mParameters.set(QCameraParameters::KEY_MAX_SHARPNESS,
CAMERA_MAX_SHARPNESS);
mParameters.set(QCameraParameters::KEY_SHARPNESS,
CAMERA_DEF_SHARPNESS);
//Set Contrast
mParameters.set(QCameraParameters::KEY_MAX_CONTRAST,
CAMERA_MAX_CONTRAST);
mParameters.set(QCameraParameters::KEY_CONTRAST,
CAMERA_DEF_CONTRAST);
//Set Saturation
mParameters.set(QCameraParameters::KEY_MAX_SATURATION,
CAMERA_MAX_SATURATION);
mParameters.set(QCameraParameters::KEY_SATURATION,
CAMERA_DEF_SATURATION);
//Set Brightness/luma-adaptaion
mParameters.set("luma-adaptation", "3");
mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT,
QCameraParameters::PIXEL_FORMAT_JPEG);
//Set Lensshading
mParameters.set(QCameraParameters::KEY_LENSSHADE,
QCameraParameters::LENSSHADE_ENABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
mLensShadeValues);
//Set ISO Mode
mParameters.set(QCameraParameters::KEY_ISO_MODE,
QCameraParameters::ISO_AUTO);
mParameters.set(QCameraParameters::KEY_SUPPORTED_ISO_MODES,
mIsoValues);
//Set MCE
mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT,
QCameraParameters::MCE_ENABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_MEM_COLOR_ENHANCE_MODES,
mMceValues);
//Set HFR
if (cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_HFR)) {
mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE,
QCameraParameters::VIDEO_HFR_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,
mHfrSizeValues.string());
mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_HIGH_FRAME_RATE_MODES,
mHfrValues);
} else{
mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,"");
}
//Set Histogram
mParameters.set(QCameraParameters::KEY_HISTOGRAM,
QCameraParameters::HISTOGRAM_DISABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
mHistogramValues);
//Set SkinTone Enhancement
mParameters.set(QCameraParameters::KEY_SKIN_TONE_ENHANCEMENT,
QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE);
mParameters.set("skinToneEnhancement", "0");
mParameters.set(QCameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES,
mSkinToneEnhancementValues);
//Set Scene Mode
mParameters.set(QCameraParameters::KEY_SCENE_MODE,
QCameraParameters::SCENE_MODE_AUTO);
mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_MODES,
mSceneModeValues);
//Set Streaming Textures
mParameters.set("strtextures", "OFF");
//Set Denoise
mParameters.set(QCameraParameters::KEY_DENOISE,
QCameraParameters::DENOISE_ON);
mParameters.set(QCameraParameters::KEY_SUPPORTED_DENOISE,
denoise_value);
//Set Touch AF/AEC
mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC,
QCameraParameters::TOUCH_AF_AEC_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
mTouchAfAecValues);
/* touch-AF ROI for reducing af fail case */
mParameters.set("touchAfAec-dx","200");
mParameters.set("touchAfAec-dy","200");
//Set Scene Detection
mParameters.set(QCameraParameters::KEY_SCENE_DETECT,
QCameraParameters::SCENE_DETECT_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_DETECT,
mSceneDetectValues);
//Set Selectable Zone AF
mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF,
QCameraParameters::SELECTABLE_ZONE_AF_AUTO);
mParameters.set(QCameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
mSelectableZoneAfValues);
//Set Face Detection
if(supportsFaceDetection()){
mParameters.set(QCameraParameters::KEY_FACE_DETECTION,
QCameraParameters::FACE_DETECTION_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_FACE_DETECTION,
mFaceDetectionValues);
}
//Set Red Eye Reduction
mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION,
QCameraParameters::REDEYE_REDUCTION_DISABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_REDEYE_REDUCTION,
mRedeyeReductionValues);
//Set ZSL
mParameters.set(QCameraParameters::KEY_ZSL,
QCameraParameters::ZSL_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_ZSL_MODES,
mZslValues);
//Set Focal length, horizontal and vertical view angles
focus_distances_info_t focalLength;
float horizontalViewAngle = 0.0f;
float verticalViewAngle = 0.0f;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_FOCAL_LENGTH,
(void *)&focalLength);
mParameters.setFloat(QCameraParameters::KEY_FOCAL_LENGTH,
focalLength.focus_distance[0]);
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE,
(void *)&horizontalViewAngle);
mParameters.setFloat(QCameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
horizontalViewAngle);
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE,
(void *)&verticalViewAngle);
mParameters.setFloat(QCameraParameters::KEY_VERTICAL_VIEW_ANGLE,
verticalViewAngle);
//Set Aperture
float f_number = 0.0f;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_F_NUMBER,
(void *)&f_number);
mExifValues.f_number = getRational(f_number*F_NUMBER_DECIMAL_PRECISION, F_NUMBER_DECIMAL_PRECISION);
//Set Exposure Compensation
mParameters.set(
QCameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
mParameters.set(
QCameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
mParameters.set(
QCameraParameters::KEY_EXPOSURE_COMPENSATION,
EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
mParameters.setFloat(
QCameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
EXPOSURE_COMPENSATION_STEP);
mParameters.set("num-snaps-per-shutter", 1);
mParameters.set("capture-burst-captures-values", getZSLQueueDepth());
mParameters.set("capture-burst-interval-supported", "true");
mParameters.set("capture-burst-interval-max", BURST_INTREVAL_MAX); /*skip frames*/
mParameters.set("capture-burst-interval-min", BURST_INTREVAL_MIN); /*skip frames*/
mParameters.set("capture-burst-interval", BURST_INTREVAL_DEFAULT); /*skip frames*/
mParameters.set("capture-burst-retroactive", 0);
mParameters.set("capture-burst-retroactive-max", getZSLQueueDepth());
mParameters.set("capture-burst-exposures", "");
mParameters.set("capture-burst-exposures-values",
"-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12");
{
String8 CamModeStr;
char buffer[32];
int flag = 0;
for (int i = 0; i < HAL_CAM_MODE_MAX; i++) {
if ( 0 ) { /*exclude some conflicting case*/
} else {
if (flag == 0) { /*first item*/
snprintf(buffer, sizeof(buffer), "%d", i);
} else {
snprintf(buffer, sizeof(buffer), ",%d", i);
}
flag = 1;
CamModeStr.append(buffer);
}
}
mParameters.set("camera-mode-values", CamModeStr);
}
mParameters.set("ae-bracket-hdr-values",
create_values_str(hdr_bracket, sizeof(hdr_bracket)/sizeof(str_map) ));
// if(mIs3DModeOn)
// mParameters.set("3d-frame-format", "left-right");
mParameters.set("no-display-mode", 0);
//mUseOverlay = useOverlay();
mParameters.set("zoom", 0);
int mNuberOfVFEOutputs;
ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_VFE_OUTPUT_ENABLE, &mNuberOfVFEOutputs);
if(ret != MM_CAMERA_OK) {
ALOGE("get parm MM_CAMERA_PARM_VFE_OUTPUT_ENABLE failed");
ret = BAD_VALUE;
}
if(mNuberOfVFEOutputs == 1)
{
mParameters.set(QCameraParameters::KEY_SINGLE_ISP_OUTPUT_ENABLED, "true");
} else {
mParameters.set(QCameraParameters::KEY_SINGLE_ISP_OUTPUT_ENABLED, "false");
}
if (setParameters(mParameters) != NO_ERROR) {
ALOGE("Failed to set default parameters?!");
}
mNoDisplayMode = 0;
mLedStatusForZsl = LED_MODE_OFF;
mInitialized = true;
strTexturesOn = false;
ALOGV("%s: X", __func__);
return;
}
/**
* Set the camera parameters. This returns BAD_VALUE if any parameter is
* invalid or not supported.
*/
int QCameraHardwareInterface::setParameters(const char *parms)
{
QCameraParameters param;
String8 str = String8(parms);
param.unflatten(str);
status_t ret = setParameters(param);
if(ret == NO_ERROR)
return 0;
else
return -1;
}
/**
* Set the camera parameters. This returns BAD_VALUE if any parameter is
* invalid or not supported. */
status_t QCameraHardwareInterface::setParameters(const QCameraParameters& params)
{
status_t ret = NO_ERROR;
ALOGV("%s: E", __func__);
// Mutex::Autolock l(&mLock);
status_t rc, final_rc = NO_ERROR;
if ((rc = setPowerMode(params))) final_rc = rc;
if ((rc = setPreviewSize(params))) final_rc = rc;
if ((rc = setVideoSize(params))) final_rc = rc;
if ((rc = setPictureSize(params))) final_rc = rc;
if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
if ((rc = setJpegQuality(params))) final_rc = rc;
if ((rc = setEffect(params))) final_rc = rc;
if ((rc = setGpsLocation(params))) final_rc = rc;
if ((rc = setRotation(params))) final_rc = rc;
if ((rc = setZoom(params))) final_rc = rc;
if ((rc = setOrientation(params))) final_rc = rc;
if ((rc = setLensshadeValue(params))) final_rc = rc;
if ((rc = setMCEValue(params))) final_rc = rc;
if ((rc = setPictureFormat(params))) final_rc = rc;
if ((rc = setSharpness(params))) final_rc = rc;
if ((rc = setSaturation(params))) final_rc = rc;
if ((rc = setSceneMode(params))) final_rc = rc;
if ((rc = setContrast(params))) final_rc = rc;
// if ((rc = setFaceDetect(params))) final_rc = rc;
if ((rc = setStrTextures(params))) final_rc = rc;
if ((rc = setPreviewFormat(params))) final_rc = rc;
if ((rc = setSkinToneEnhancement(params))) final_rc = rc;
if ((rc = setWaveletDenoise(params))) final_rc = rc;
if ((rc = setAntibanding(params))) final_rc = rc;
// if ((rc = setOverlayFormats(params))) final_rc = rc;
if ((rc = setRedeyeReduction(params))) final_rc = rc;
if ((rc = setCaptureBurstExp())) final_rc = rc;
const char *str_val = params.get("capture-burst-exposures");
if ( str_val == NULL || strlen(str_val)==0 ) {
char burst_exp[PROPERTY_VALUE_MAX];
memset(burst_exp, 0, sizeof(burst_exp));
property_get("persist.capture.burst.exposures", burst_exp, "");
if ( strlen(burst_exp)>0 ) {
mParameters.set("capture-burst-exposures", burst_exp);
}
} else {
mParameters.set("capture-burst-exposures", str_val);
}
mParameters.set("num-snaps-per-shutter", params.get("num-snaps-per-shutter"));
if ((rc = setAEBracket(params))) final_rc = rc;
// if ((rc = setDenoise(params))) final_rc = rc;
if ((rc = setPreviewFpsRange(params))) final_rc = rc;
if((rc = setRecordingHint(params))) final_rc = rc;
if ((rc = setNumOfSnapshot(params))) final_rc = rc;
if ((rc = setAecAwbLock(params))) final_rc = rc;
if ((rc = setWhiteBalance(params))) final_rc = rc;
const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF )) {
//if ((rc = setPreviewFrameRateMode(params))) final_rc = rc;
if ((rc = setPreviewFrameRate(params))) final_rc = rc;
if ((rc = setBrightness(params))) final_rc = rc;
if ((rc = setISOValue(params))) final_rc = rc;
if ((rc = setFocusAreas(params))) final_rc = rc;
if ((rc = setMeteringAreas(params))) final_rc = rc;
}
if ((rc = setFocusMode(params))) final_rc = rc;
if ((rc = setAutoExposure(params))) final_rc = rc;
if ((rc = setExposureCompensation(params))) final_rc = rc;
if ((rc = setFlash(params))) final_rc = rc;
//selectableZoneAF needs to be invoked after continuous AF
if ((rc = setSelectableZoneAf(params))) final_rc = rc;
// setHighFrameRate needs to be done at end, as there can
// be a preview restart, and need to use the updated parameters
if ((rc = setHighFrameRate(params))) final_rc = rc;
if ((rc = setZSLBurstLookBack(params))) final_rc = rc;
if ((rc = setZSLBurstInterval(params))) final_rc = rc;
if ((rc = setNoDisplayMode(params))) final_rc = rc;
//Update Exiftag values.
setExifTags();
ALOGV("%s: X", __func__);
return final_rc;
}
/** Retrieve the camera parameters. The buffer returned by the camera HAL
must be returned back to it with put_parameters, if put_parameters
is not NULL.
*/
int QCameraHardwareInterface::getParameters(char **parms)
{
char* rc = NULL;
String8 str;
QCameraParameters param = getParameters();
//param.dump();
str = param.flatten( );
rc = (char *)malloc(sizeof(char)*(str.length()+1));
if(rc != NULL){
memset(rc, 0, sizeof(char)*(str.length()+1));
strncpy(rc, str.string(), str.length());
rc[str.length()] = 0;
*parms = rc;
}
return 0;
}
/** The camera HAL uses its own memory to pass us the parameters when we
call get_parameters. Use this function to return the memory back to
the camera HAL, if put_parameters is not NULL. If put_parameters
is NULL, then you have to use free() to release the memory.
*/
void QCameraHardwareInterface::putParameters(char *rc)
{
free(rc);
rc = NULL;
}
QCameraParameters& QCameraHardwareInterface::getParameters()
{
Mutex::Autolock lock(mLock);
mParameters.set(QCameraParameters::KEY_FOCUS_DISTANCES, mFocusDistance.string());
const char *str = mParameters.get(QCameraParameters::KEY_SCENE_MODE);
if (mHasAutoFocusSupport && strcmp(str, "auto")) {
mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE);
}
return mParameters;
}
status_t QCameraHardwareInterface::runFaceDetection()
{
bool ret = true;
const char *str = mParameters.get(QCameraParameters::KEY_FACE_DETECTION);
if (str != NULL) {
int value = attr_lookup(facedetection,
sizeof(facedetection) / sizeof(str_map), str);
fd_set_parm_t fd_set_parm;
int requested_faces = mParameters.getInt(QCameraParameters::KEY_MAX_NUM_REQUESTED_FACES);
fd_set_parm.fd_mode = value;
fd_set_parm.num_fd = requested_faces;
ret = native_set_parms(MM_CAMERA_PARM_FD, sizeof(fd_set_parm_t), (void *)&fd_set_parm);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
ALOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setSharpness(const QCameraParameters& params)
{
bool ret = false;
int rc = MM_CAMERA_OK;
ALOGV("%s",__func__);
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_SHARPNESS);
if(!rc) {
ALOGV("%s:CONTRAST not supported", __func__);
return NO_ERROR;
}
int sharpness = params.getInt(QCameraParameters::KEY_SHARPNESS);
if((sharpness < CAMERA_MIN_SHARPNESS
|| sharpness > CAMERA_MAX_SHARPNESS))
return UNKNOWN_ERROR;
ALOGV("setting sharpness %d", sharpness);
mParameters.set(QCameraParameters::KEY_SHARPNESS, sharpness);
ret = native_set_parms(MM_CAMERA_PARM_SHARPNESS, sizeof(sharpness),
(void *)&sharpness);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
status_t QCameraHardwareInterface::setSaturation(const QCameraParameters& params)
{
bool ret = false;
int rc = MM_CAMERA_OK;
ALOGV("%s",__func__);
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_SATURATION);
if(!rc) {
ALOGV("%s:MM_CAMERA_PARM_SATURATION not supported", __func__);
return NO_ERROR;
}
int result;
int saturation = params.getInt(QCameraParameters::KEY_SATURATION);
if((saturation < CAMERA_MIN_SATURATION)
|| (saturation > CAMERA_MAX_SATURATION))
return UNKNOWN_ERROR;
ALOGV("Setting saturation %d", saturation);
mParameters.set(QCameraParameters::KEY_SATURATION, saturation);
ret = native_set_parms(MM_CAMERA_PARM_SATURATION, sizeof(saturation),
(void *)&saturation, (int *)&result);
if(result != MM_CAMERA_OK)
ALOGV("Saturation Value: %d is not set as the selected value is not supported", saturation);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
status_t QCameraHardwareInterface::setContrast(const QCameraParameters& params)
{
ALOGV("%s E", __func__ );
int rc = MM_CAMERA_OK;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_CONTRAST);
if(!rc) {
ALOGV("%s:CONTRAST not supported", __func__);
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
ALOGV("Contrast : %s",str);
int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
if(value == CAMERA_BESTSHOT_OFF) {
int contrast = params.getInt(QCameraParameters::KEY_CONTRAST);
if((contrast < CAMERA_MIN_CONTRAST)
|| (contrast > CAMERA_MAX_CONTRAST))
{
ALOGV("Contrast Value not matching");
return UNKNOWN_ERROR;
}
ALOGV("setting contrast %d", contrast);
mParameters.set(QCameraParameters::KEY_CONTRAST, contrast);
ALOGV("Calling Contrast set on Lower layer");
bool ret = native_set_parms(MM_CAMERA_PARM_CONTRAST, sizeof(contrast),
(void *)&contrast);
ALOGV("Lower layer returned %d", ret);
int bestshot_reconfigure;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
&bestshot_reconfigure);
if(bestshot_reconfigure) {
if (mContrast != contrast) {
mContrast = contrast;
if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED && ret) {
mRestartPreview = 1;
pausePreviewForZSL();
}
}
}
return ret ? NO_ERROR : UNKNOWN_ERROR;
} else {
ALOGV(" Contrast value will not be set " \
"when the scenemode selected is %s", str);
return NO_ERROR;
}
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setSceneDetect(const QCameraParameters& params)
{
ALOGV("%s",__func__);
bool retParm;
int rc = MM_CAMERA_OK;
rc = cam_config_is_parm_supported(mCameraId,MM_CAMERA_PARM_ASD_ENABLE);
if(!rc) {
ALOGV("%s:MM_CAMERA_PARM_ASD_ENABLE not supported", __func__);
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_SCENE_DETECT);
ALOGV("Scene Detect string : %s",str);
if (str != NULL) {
int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str);
ALOGV("Scenedetect Value : %d",value);
if (value != NOT_FOUND) {
mParameters.set(QCameraParameters::KEY_SCENE_DETECT, str);
retParm = native_set_parms(MM_CAMERA_PARM_ASD_ENABLE, sizeof(value),
(void *)&value);
return retParm ? NO_ERROR : UNKNOWN_ERROR;
}
}
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setZoom(const QCameraParameters& params)
{
status_t rc = NO_ERROR;
ALOGV("%s: E",__func__);
if( !( cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ZOOM))) {
ALOGV("%s:MM_CAMERA_PARM_ZOOM not supported", __func__);
return NO_ERROR;
}
// No matter how many different zoom values the driver can provide, HAL
// provides applictations the same number of zoom levels. The maximum driver
// zoom value depends on sensor output (VFE input) and preview size (VFE
// output) because VFE can only crop and cannot upscale. If the preview size
// is bigger, the maximum zoom ratio is smaller. However, we want the
// zoom ratio of each zoom level is always the same whatever the preview
// size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
// we need to have a fixed maximum zoom value and do read it from the
// driver.
static const int ZOOM_STEP = 1;
int32_t zoom_level = params.getInt("zoom");
if(zoom_level >= 0 && zoom_level <= mMaxZoom-1) {
mParameters.set("zoom", zoom_level);
int32_t zoom_value = ZOOM_STEP * zoom_level;
bool ret = native_set_parms(MM_CAMERA_PARM_ZOOM,
sizeof(zoom_value), (void *)&zoom_value);
if(ret) {
mCurrentZoom=zoom_level;
}
rc = ret ? NO_ERROR : UNKNOWN_ERROR;
} else {
rc = BAD_VALUE;
}
ALOGV("%s X",__func__);
return rc;
}
status_t QCameraHardwareInterface::setISOValue(const QCameraParameters& params) {
status_t rc = NO_ERROR;
ALOGV("%s",__func__);
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ISO);
if(!rc) {
ALOGV("%s:MM_CAMERA_PARM_ISO not supported", __func__);
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_ISO_MODE);
ALOGV("ISO string : %s", str);
int8_t temp_hjr;
if (str != NULL) {
int value = (camera_iso_mode_type)attr_lookup(
iso, sizeof(iso) / sizeof(str_map), str);
ALOGV("ISO string : %s", str);
if (value != NOT_FOUND) {
camera_iso_mode_type temp = (camera_iso_mode_type) value;
if (value == CAMERA_ISO_DEBLUR) {
temp_hjr = true;
native_set_parms(MM_CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
mHJR = value;
}
else {
if (mHJR == CAMERA_ISO_DEBLUR) {
temp_hjr = false;
native_set_parms(MM_CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
mHJR = value;
}
}
mParameters.set(QCameraParameters::KEY_ISO_MODE, str);
native_set_parms(MM_CAMERA_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
mIsoValue = (int)temp;
return NO_ERROR;
}
}
return BAD_VALUE;
}
status_t QCameraHardwareInterface::updateFocusDistances()
{
ALOGV("%s: IN", __FUNCTION__);
focus_distances_info_t focusDistances;
if(cam_config_get_parm(mCameraId, MM_CAMERA_PARM_FOCUS_DISTANCES,
&focusDistances) == MM_CAMERA_OK) {
String8 str;
char buffer[32] = {0};
//set all distances to infinity if focus mode is infinity
if(mFocusMode == AF_MODE_INFINITY) {
snprintf(buffer, sizeof(buffer), "Infinity,");
str.append(buffer);
snprintf(buffer, sizeof(buffer), "Infinity,");
str.append(buffer);
snprintf(buffer, sizeof(buffer), "Infinity");
str.append(buffer);
} else {
snprintf(buffer, sizeof(buffer), "%f", focusDistances.focus_distance[0]);
str.append(buffer);
snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[1]);
str.append(buffer);
snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[2]);
str.append(buffer);
}
ALOGV("%s: setting KEY_FOCUS_DISTANCES as %s", __FUNCTION__, str.string());
mFocusDistance = str;
return NO_ERROR;
}
ALOGE("%s: get CAMERA_PARM_FOCUS_DISTANCES failed!!!", __FUNCTION__);
return BAD_VALUE;
}
// Parse string like "(1, 2, 3, 4, ..., N)"
// num is pointer to an allocated array of size N
static int parseNDimVector(const char *str, int *num, int N, char delim = ',')
{
char *start, *end;
if(num == NULL) {
ALOGE("Invalid output array (num == NULL)");
return -1;
}
//check if string starts and ends with parantheses
if(str[0] != '(' || str[strlen(str)-1] != ')') {
ALOGE("Invalid format of string %s, valid format is (n1, n2, n3, n4 ...)", str);
return -1;
}
start = (char*) str;
start++;
for(int i=0; i<N; i++) {
*(num+i) = (int) strtol(start, &end, 10);
if(*end != delim && i < N-1) {
ALOGE("Cannot find delimeter '%c' in string \"%s\". end = %c", delim, str, *end);
return -1;
}
start = end+1;
}
return 0;
}
// parse string like "(1, 2, 3, 4, 5),(1, 2, 3, 4, 5),..."
static int parseCameraAreaString(const char* str, int max_num_areas,
camera_area_t *pAreas, int *num_areas_found)
{
char area_str[32];
const char *start, *end, *p;
start = str; end = NULL;
int values[5], index=0;
*num_areas_found = 0;
while(start != NULL) {
if(*start != '(') {
ALOGE("%s: error: Ill formatted area string: %s", __func__, str);
return -1;
}
end = strchr(start, ')');
if(end == NULL) {
ALOGE("%s: error: Ill formatted area string: %s", __func__, str);
return -1;
}
int i;
for (i=0,p=start; p<=end; p++, i++) {
area_str[i] = *p;
}
area_str[i] = '\0';
if(parseNDimVector(area_str, values, 5) < 0){
ALOGE("%s: error: Failed to parse the area string: %s", __func__, area_str);
return -1;
}
// no more areas than max_num_areas are accepted.
if(index >= max_num_areas) {
ALOGE("%s: error: too many areas specified %s", __func__, str);
return -1;
}
pAreas[index].x1 = values[0];
pAreas[index].y1 = values[1];
pAreas[index].x2 = values[2];
pAreas[index].y2 = values[3];
pAreas[index].weight = values[4];
index++;
start = strchr(end, '('); // serach for next '('
}
(*num_areas_found) = index;
return 0;
}
static bool validateCameraAreas(camera_area_t *areas, int num_areas)
{
for(int i=0; i<num_areas; i++) {
// handle special case (0, 0, 0, 0, 0)
if((areas[i].x1 == 0) && (areas[i].y1 == 0)
&& (areas[i].x2 == 0) && (areas[i].y2 == 0) && (areas[i].weight == 0)) {
continue;
}
if(areas[i].x1 < -1000) return false; // left should be >= -1000
if(areas[i].y1 < -1000) return false; // top should be >= -1000
if(areas[i].x2 > 1000) return false; // right should be <= 1000
if(areas[i].y2 > 1000) return false; // bottom should be <= 1000
if(areas[i].weight <= 0 || areas[i].weight > 1000) // weight should be in [1, 1000]
return false;
if(areas[i].x1 >= areas[i].x2) { // left should be < right
return false;
}
if(areas[i].y1 >= areas[i].y2) // top should be < bottom
return false;
}
return true;
}
status_t QCameraHardwareInterface::setFocusAreas(const QCameraParameters& params)
{
ALOGV("%s: E", __func__);
status_t rc;
int max_num_af_areas = mParameters.getInt(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS);
if(max_num_af_areas == 0) {
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_FOCUS_AREAS);
if (str == NULL) {
ALOGE("%s: Parameter string is null", __func__);
rc = NO_ERROR;
} else {
camera_area_t *areas = new camera_area_t[max_num_af_areas];
int num_areas_found=0;
if(parseCameraAreaString(str, max_num_af_areas, areas, &num_areas_found) < 0) {
ALOGE("%s: Failed to parse the string: %s", __func__, str);
delete areas;
return BAD_VALUE;
}
for(int i=0; i<num_areas_found; i++) {
ALOGV("FocusArea[%d] = (%d, %d, %d, %d, %d)", i, (areas[i].x1), (areas[i].y1),
(areas[i].x2), (areas[i].y2), (areas[i].weight));
}
if(validateCameraAreas(areas, num_areas_found) == false) {
ALOGE("%s: invalid areas specified : %s", __func__, str);
delete areas;
return BAD_VALUE;
}
mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, str);
num_areas_found = 1; //temp; need to change after the multi-roi is enabled
//if the native_set_parms is called when preview is not started, it
//crashes in lower layer, so return of preview is not started
if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED) {
delete areas;
return NO_ERROR;
}
//for special area string (0, 0, 0, 0, 0), set the num_areas_found to 0,
//so no action is takenby the lower layer
if(num_areas_found == 1 && (areas[0].x1 == 0) && (areas[0].y1 == 0)
&& (areas[0].x2 == 0) && (areas[0].y2 == 0) && (areas[0].weight == 0)) {
num_areas_found = 0;
}
#if 1 //temp solution
roi_info_t af_roi_value;
memset(&af_roi_value, 0, sizeof(roi_info_t));
uint16_t x1, x2, y1, y2, dx, dy;
int previewWidth, previewHeight;
this->getPreviewSize(&previewWidth, &previewHeight);
//transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
x1 = (uint16_t)((areas[0].x1 + 1000.0f)*(previewWidth/2000.0f));
y1 = (uint16_t)((areas[0].y1 + 1000.0f)*(previewHeight/2000.0f));
x2 = (uint16_t)((areas[0].x2 + 1000.0f)*(previewWidth/2000.0f));
y2 = (uint16_t)((areas[0].y2 + 1000.0f)*(previewHeight/2000.0f));
dx = x2 - x1;
dy = y2 - y1;
af_roi_value.num_roi = num_areas_found;
af_roi_value.roi[0].x = x1;
af_roi_value.roi[0].y = y1;
af_roi_value.roi[0].dx = dx;
af_roi_value.roi[0].dy = dy;
af_roi_value.is_multiwindow = 0;
if (native_set_parms(MM_CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value))
rc = NO_ERROR;
else
rc = BAD_VALUE;
delete areas;
#endif
#if 0 //better solution with multi-roi, to be enabled later
af_mtr_area_t afArea;
afArea.num_area = num_areas_found;
uint16_t x1, x2, y1, y2, dx, dy;
int previewWidth, previewHeight;
this->getPreviewSize(&previewWidth, &previewHeight);
for(int i=0; i<num_areas_found; i++) {
//transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
x1 = (uint16_t)((areas[i].x1 + 1000.0f)*(previewWidth/2000.0f));
y1 = (uint16_t)((areas[i].y1 + 1000.0f)*(previewHeight/2000.0f));
x2 = (uint16_t)((areas[i].x2 + 1000.0f)*(previewWidth/2000.0f));
y2 = (uint16_t)((areas[i].y2 + 1000.0f)*(previewHeight/2000.0f));
dx = x2 - x1;
dy = y2 - y1;
afArea.mtr_area[i].x = x1;
afArea.mtr_area[i].y = y1;
afArea.mtr_area[i].dx = dx;
afArea.mtr_area[i].dy = dy;
afArea.weight[i] = areas[i].weight;
}
if(native_set_parms(MM_CAMERA_PARM_AF_MTR_AREA, sizeof(af_mtr_area_t), (void*)&afArea))
rc = NO_ERROR;
else
rc = BAD_VALUE;*/
#endif
}
ALOGV("%s: X", __func__);
return rc;
}
status_t QCameraHardwareInterface::setMeteringAreas(const QCameraParameters& params)
{
ALOGV("%s: E", __func__);
status_t rc;
int max_num_mtr_areas = mParameters.getInt(QCameraParameters::KEY_MAX_NUM_METERING_AREAS);
if(max_num_mtr_areas == 0) {
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_METERING_AREAS);
if (str == NULL) {
ALOGE("%s: Parameter string is null", __func__);
rc = NO_ERROR;
} else {
camera_area_t *areas = new camera_area_t[max_num_mtr_areas];
int num_areas_found=0;
if(parseCameraAreaString(str, max_num_mtr_areas, areas, &num_areas_found) < 0) {
ALOGE("%s: Failed to parse the string: %s", __func__, str);
delete areas;
return BAD_VALUE;
}
for(int i=0; i<num_areas_found; i++) {
ALOGV("MeteringArea[%d] = (%d, %d, %d, %d, %d)", i, (areas[i].x1), (areas[i].y1),
(areas[i].x2), (areas[i].y2), (areas[i].weight));
}
if(validateCameraAreas(areas, num_areas_found) == false) {
ALOGE("%s: invalid areas specified : %s", __func__, str);
delete areas;
return BAD_VALUE;
}
mParameters.set(QCameraParameters::KEY_METERING_AREAS, str);
//if the native_set_parms is called when preview is not started, it
//crashes in lower layer, so return of preview is not started
if(mPreviewState == QCAMERA_HAL_PREVIEW_STOPPED) {
delete areas;
return NO_ERROR;
}
num_areas_found = 1; //temp; need to change after the multi-roi is enabled
//for special area string (0, 0, 0, 0, 0), set the num_areas_found to 0,
//so no action is takenby the lower layer
if(num_areas_found == 1 && (areas[0].x1 == 0) && (areas[0].y1 == 0)
&& (areas[0].x2 == 0) && (areas[0].y2 == 0) && (areas[0].weight == 0)) {
num_areas_found = 0;
}
#if 1
cam_set_aec_roi_t aec_roi_value;
uint16_t x1, x2, y1, y2;
int previewWidth, previewHeight;
this->getPreviewSize(&previewWidth, &previewHeight);
//transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
x1 = (uint16_t)((areas[0].x1 + 1000.0f)*(previewWidth/2000.0f));
y1 = (uint16_t)((areas[0].y1 + 1000.0f)*(previewHeight/2000.0f));
x2 = (uint16_t)((areas[0].x2 + 1000.0f)*(previewWidth/2000.0f));
y2 = (uint16_t)((areas[0].y2 + 1000.0f)*(previewHeight/2000.0f));
delete areas;
if(num_areas_found == 1) {
aec_roi_value.aec_roi_enable = AEC_ROI_ON;
aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
aec_roi_value.aec_roi_position.coordinate.x = (x1+x2)/2;
aec_roi_value.aec_roi_position.coordinate.y = (y1+y2)/2;
} else {
aec_roi_value.aec_roi_enable = AEC_ROI_OFF;
aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE;
aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE;
}
if(native_set_parms(MM_CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value))
rc = NO_ERROR;
else
rc = BAD_VALUE;
#endif
#if 0 //solution including multi-roi, to be enabled later
aec_mtr_area_t aecArea;
aecArea.num_area = num_areas_found;
uint16_t x1, x2, y1, y2, dx, dy;
int previewWidth, previewHeight;
this->getPreviewSize(&previewWidth, &previewHeight);
for(int i=0; i<num_areas_found; i++) {
//transform the coords from (-1000, 1000) to (0, previewWidth or previewHeight)
x1 = (uint16_t)((areas[i].x1 + 1000.0f)*(previewWidth/2000.0f));
y1 = (uint16_t)((areas[i].y1 + 1000.0f)*(previewHeight/2000.0f));
x2 = (uint16_t)((areas[i].x2 + 1000.0f)*(previewWidth/2000.0f));
y2 = (uint16_t)((areas[i].y2 + 1000.0f)*(previewHeight/2000.0f));
dx = x2 - x1;
dy = y2 - y1;
aecArea.mtr_area[i].x = x1;
aecArea.mtr_area[i].y = y1;
aecArea.mtr_area[i].dx = dx;
aecArea.mtr_area[i].dy = dy;
aecArea.weight[i] = areas[i].weight;
}
delete areas;
if(native_set_parms(MM_CAMERA_PARM_AEC_MTR_AREA, sizeof(aec_mtr_area_t), (void*)&aecArea))
rc = NO_ERROR;
else
rc = BAD_VALUE;
#endif
}
ALOGV("%s: X", __func__);
return rc;
}
status_t QCameraHardwareInterface::setFocusMode(const QCameraParameters& params)
{
const char *str = params.get(QCameraParameters::KEY_FOCUS_MODE);
const char *prev_str = mParameters.get(QCameraParameters::KEY_FOCUS_MODE);
ALOGV("%s",__func__);
if (str != NULL) {
ALOGV("Focus mode %s",str);
int32_t value = attr_lookup(focus_modes,
sizeof(focus_modes) / sizeof(str_map), str);
if (value != NOT_FOUND) {
mParameters.set(QCameraParameters::KEY_FOCUS_MODE, str);
mFocusMode = value;
if(updateFocusDistances() != NO_ERROR) {
ALOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, str);
return UNKNOWN_ERROR;
}
mParameters.set(QCameraParameters::KEY_FOCUS_DISTANCES, mFocusDistance.string());
if(mHasAutoFocusSupport){
bool ret = native_set_parms(MM_CAMERA_PARM_FOCUS_MODE,
sizeof(value),
(void *)&value);
int cafSupport = false;
int caf_type=0;
const char *str_hdr = mParameters.get(QCameraParameters::KEY_SCENE_MODE);
if(!strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ||
!strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)){
cafSupport = true;
bool rc = false;
if(!strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO))
{
caf_type = 1;
rc = native_set_parms(MM_CAMERA_PARM_CAF_TYPE, sizeof(caf_type), (void *)&caf_type);
}
else if(!strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE))
{
caf_type = 2;
rc = native_set_parms(MM_CAMERA_PARM_CAF_TYPE, sizeof(caf_type), (void *)&caf_type);
}
ALOGV("caf_type %d rc %d", caf_type, rc);
}
ALOGV("Continuous Auto Focus %d", cafSupport);
if(mAutoFocusRunning && cafSupport){
mAutoFocusRunning = false;
if(MM_CAMERA_OK!=cam_ops_action(mCameraId,false,MM_CAMERA_OPS_FOCUS,NULL )) {
ALOGE("%s: AF command failed err:%d error %s",__func__, errno,strerror(errno));
}
}
ret = native_set_parms(MM_CAMERA_PARM_CONTINUOUS_AF, sizeof(cafSupport),
(void *)&cafSupport);
}
return NO_ERROR;
}
ALOGV("%s:Could not look up str value",__func__);
}
ALOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setSceneMode(const QCameraParameters& params)
{
status_t rc = NO_ERROR;
ALOGV("%s",__func__);
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_BESTSHOT_MODE);
if(!rc) {
ALOGV("%s:Parameter Scenemode is not supported for this sensor", __func__);
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
const char *oldstr = mParameters.get(QCameraParameters::KEY_SCENE_MODE);
if (str != NULL && oldstr != NULL) {
int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
if (value != NOT_FOUND) {
/* Check to see if there was a change of scene mode */
if(strcmp(str,oldstr)) {
ALOGV("%s: valued changed from %s to %s",__func__,oldstr, str);
/* Check if we are either transitioning to/from HDR state
if yes preview needs restart*/
if(!strcmp(str, "hdr") || !strcmp(oldstr, "hdr") ) {
ALOGV("Changed between HDR/non-HDR states");
/* Restart only if preview already running*/
if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED) {
ALOGV("Preview in progress,restarting for HDR transition");
mParameters.set(QCameraParameters::KEY_SCENE_MODE, str);
mRestartPreview = 1;
pausePreviewForZSL();
}
}
}
mParameters.set(QCameraParameters::KEY_SCENE_MODE, str);
bool ret = native_set_parms(MM_CAMERA_PARM_BESTSHOT_MODE, sizeof(value),
(void *)&value);
int bestshot_reconfigure;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
&bestshot_reconfigure);
if(bestshot_reconfigure) {
if (mBestShotMode != value) {
mBestShotMode = value;
if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED && ret) {
ALOGV("%s:Bestshot trigerring restart",__func__);
mRestartPreview = 1;
pausePreviewForZSL();
}
}
}
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
}
ALOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setSelectableZoneAf(const QCameraParameters& params)
{
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
if(mHasAutoFocusSupport) {
const char *str = params.get(QCameraParameters::KEY_SELECTABLE_ZONE_AF);
if (str != NULL) {
int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str);
if (value != NOT_FOUND) {
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FOCUS_RECT);
if(!rc) {
ALOGV("SelectableZoneAF is not supported for this sensor");
return NO_ERROR;
}else {
mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF, str);
bool ret = native_set_parms(MM_CAMERA_PARM_FOCUS_RECT, sizeof(value),
(void *)&value);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
}
}
ALOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
return NO_ERROR;
}
status_t QCameraHardwareInterface::setEffect(const QCameraParameters& params)
{
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
const char *str = params.get(QCameraParameters::KEY_EFFECT);
int result;
if (str != NULL) {
ALOGV("Setting effect %s",str);
int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
if (value != NOT_FOUND) {
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_EFFECT);
if(!rc) {
ALOGV("Camera Effect - %s mode is not supported for this sensor",str);
return NO_ERROR;
}else {
mParameters.set(QCameraParameters::KEY_EFFECT, str);
bool ret = native_set_parms(MM_CAMERA_PARM_EFFECT, sizeof(value),
(void *)&value,(int *)&result);
if(result != MM_CAMERA_OK) {
ALOGE("Camera Effect: %s is not set as the selected value is not supported ", str);
}
int bestshot_reconfigure;
cam_config_get_parm(mCameraId, MM_CAMERA_PARM_BESTSHOT_RECONFIGURE,
&bestshot_reconfigure);
if(bestshot_reconfigure) {
if (mEffects != value) {
mEffects = value;
if (mPreviewState == QCAMERA_HAL_PREVIEW_STARTED && ret) {
mRestartPreview = 1;
pausePreviewForZSL();
}
}
}
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
}
}
ALOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
ALOGV("setEffect X");
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setBrightness(const QCameraParameters& params) {
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_BRIGHTNESS);
if(!rc) {
ALOGV("MM_CAMERA_PARM_BRIGHTNESS mode is not supported for this sensor");
return NO_ERROR;
}
int brightness = params.getInt("luma-adaptation");
if (mBrightness != brightness) {
ALOGV(" new brightness value : %d ", brightness);
mBrightness = brightness;
mParameters.set("luma-adaptation", brightness);
bool ret = native_set_parms(MM_CAMERA_PARM_BRIGHTNESS, sizeof(mBrightness),
(void *)&mBrightness);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
return NO_ERROR;
}
status_t QCameraHardwareInterface::setAutoExposure(const QCameraParameters& params)
{
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_EXPOSURE);
if(!rc) {
ALOGV("MM_CAMERA_PARM_EXPOSURE mode is not supported for this sensor");
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_AUTO_EXPOSURE);
if (str != NULL) {
int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
if (value != NOT_FOUND) {
mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE, str);
bool ret = native_set_parms(MM_CAMERA_PARM_EXPOSURE, sizeof(value),
(void *)&value);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
}
ALOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setExposureCompensation(
const QCameraParameters & params){
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_EXPOSURE_COMPENSATION);
if(!rc) {
ALOGV("MM_CAMERA_PARM_EXPOSURE_COMPENSATION mode is not supported for this sensor");
return NO_ERROR;
}
int numerator = params.getInt(QCameraParameters::KEY_EXPOSURE_COMPENSATION);
if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator &&
numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
int16_t numerator16 = (int16_t)(numerator & 0x0000ffff);
uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
uint32_t value = 0;
value = numerator16 << 16 | denominator16;
const char *sce_str = params.get(QCameraParameters::KEY_SCENE_MODE);
if (sce_str != NULL) {
if(!strcmp(sce_str, "sunset")){
//Exposure comp value in sunset scene mode
mParameters.set(QCameraParameters::KEY_EXPOSURE_COMPENSATION,
-6);
}else{
//Exposure comp value for other
mParameters.set(QCameraParameters::KEY_EXPOSURE_COMPENSATION,
numerator);
}
}else {
mParameters.set(QCameraParameters::KEY_EXPOSURE_COMPENSATION,
numerator);
}
bool ret = native_set_parms(MM_CAMERA_PARM_EXPOSURE_COMPENSATION,
sizeof(value), (void *)&value);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
ALOGE("Invalid Exposure Compensation");
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setWhiteBalance(const QCameraParameters& params)
{
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
int result;
const char *str = NULL;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_WHITE_BALANCE);
if(!rc) {
ALOGV("MM_CAMERA_PARM_WHITE_BALANCE mode is not supported for this sensor");
return NO_ERROR;
}
const char *sce_str = params.get(QCameraParameters::KEY_SCENE_MODE);
if (sce_str != NULL) {
if(!strcmp(sce_str, "sunset")){
//AWB value in sunset scene mode
str = QCameraParameters::WHITE_BALANCE_DAYLIGHT;
mParameters.set(QCameraParameters::KEY_WHITE_BALANCE, str);
}else if(!strcmp(sce_str, "auto")){
str = params.get(QCameraParameters::KEY_WHITE_BALANCE);
}else{
//AWB in other scene Mode
str = QCameraParameters::WHITE_BALANCE_AUTO;
mParameters.set(QCameraParameters::KEY_WHITE_BALANCE, str);
}
}else {
str = params.get(QCameraParameters::KEY_WHITE_BALANCE);
}
if (str != NULL) {
int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
if (value != NOT_FOUND) {
mParameters.set(QCameraParameters::KEY_WHITE_BALANCE, str);
bool ret = native_set_parms(MM_CAMERA_PARM_WHITE_BALANCE, sizeof(value),
(void *)&value, (int *)&result);
if(result != MM_CAMERA_OK) {
ALOGE("WhiteBalance Value: %s is not set as the selected value is not supported ", str);
}
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
}
ALOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setAntibanding(const QCameraParameters& params)
{
int result;
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_ANTIBANDING);
if(!rc) {
ALOGV("ANTIBANDING mode is not supported for this sensor");
return NO_ERROR;
}
const char *str = params.get(QCameraParameters::KEY_ANTIBANDING);
if (str != NULL) {
int value = (camera_antibanding_type)attr_lookup(
antibanding, sizeof(antibanding) / sizeof(str_map), str);
if (value != NOT_FOUND) {
camera_antibanding_type temp = (camera_antibanding_type) value;
ALOGV("Antibanding Value : %d",value);
mParameters.set(QCameraParameters::KEY_ANTIBANDING, str);
bool ret = native_set_parms(MM_CAMERA_PARM_ANTIBANDING,
sizeof(camera_antibanding_type), (void *)&value ,(int *)&result);
if(result != MM_CAMERA_OK) {
ALOGE("AntiBanding Value: %s is not supported for the given BestShot Mode", str);
}
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
}
ALOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setPreviewFrameRate(const QCameraParameters& params)
{
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS);
if(!rc) {
ALOGV("MM_CAMERA_PARM_FPS is not supported for this sensor");
return NO_ERROR;
}
uint16_t previousFps = (uint16_t)mParameters.getPreviewFrameRate();
uint16_t fps = (uint16_t)params.getPreviewFrameRate();
ALOGV("requested preview frame rate is %u", fps);
if(mInitialized && (fps == previousFps)){
ALOGV("No change is FPS Value %d",fps );
return NO_ERROR;
}
if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
mParameters.setPreviewFrameRate(fps);
bool ret = native_set_parms(MM_CAMERA_PARM_FPS,
sizeof(fps), (void *)&fps);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setPreviewFrameRateMode(const QCameraParameters& params) {
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS);
if(!rc) {
ALOGV(" CAMERA FPS mode is not supported for this sensor");
return NO_ERROR;
}
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FPS_MODE);
if(!rc) {
ALOGV("CAMERA FPS MODE mode is not supported for this sensor");
return NO_ERROR;
}
const char *previousMode = mParameters.getPreviewFrameRateMode();
const char *str = params.getPreviewFrameRateMode();
if (NULL == previousMode) {
ALOGV("Preview Frame Rate Mode is NULL\n");
return NO_ERROR;
}
if (NULL == str) {
ALOGV("Preview Frame Rate Mode is NULL\n");
return NO_ERROR;
}
int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str);
if(frameRateMode != NOT_FOUND) {
ALOGV("setPreviewFrameRateMode: %s ", str);
mParameters.setPreviewFrameRateMode(str);
bool ret = native_set_parms(MM_CAMERA_PARM_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode);
if(!ret) return ret;
//set the fps value when chaging modes
int16_t fps = (uint16_t)params.getPreviewFrameRate();
if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
mParameters.setPreviewFrameRate(fps);
ret = native_set_parms(MM_CAMERA_PARM_FPS,
sizeof(fps), (void *)&fps);
return ret ? NO_ERROR : UNKNOWN_ERROR;
}
ALOGE("Invalid preview frame rate value: %d", fps);
return BAD_VALUE;
}
ALOGE("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str);
return BAD_VALUE;
}
status_t QCameraHardwareInterface::setSkinToneEnhancement(const QCameraParameters& params) {
ALOGV("%s",__func__);
status_t rc = NO_ERROR;
rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_SCE_FACTOR);
if(!rc) {
ALOGV("SkinToneEnhancement is not supported for this sensor");
return NO_ERROR;
}
int skinToneValue = params.getInt("skinToneEnhancement");
if (mSkinToneEnhancement != skinToneValue) {
ALOGV(" new skinTone correction value : %d ", skinToneValue);