blob: 915ded34b7af5b9d7ec0e8b3f41451c0c9cde12a [file] [log] [blame]
/*
** Copyright 2008, Google Inc.
** 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 "QualcommCameraHardware"
#include <utils/Log.h>
#include "QualcommCameraHardware.h"
#include <utils/Errors.h>
#include <utils/threads.h>
#include <binder/MemoryHeapPmem.h>
#if 0
#include <binder/MemoryHeapIon.h>
#endif
#include <camera/Camera.h>
#include <hardware/camera.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 <genlock.h>
#include "linux/msm_mdp.h"
#include <linux/fb.h>
#define LIKELY(exp) __builtin_expect(!!(exp), 1)
#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
#define CAMERA_HAL_UNUSED(expr) do { (void)(expr); } while (0)
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 <camera.h>
#include <cam_fifo.h>
#include <liveshot.h>
#include <jpege.h>
#include <jpeg_encoder.h>
#define DUMP_LIVESHOT_JPEG_FILE 0
#define DEFAULT_PICTURE_WIDTH 640
#define DEFAULT_PICTURE_HEIGHT 480
#define DEFAULT_PICTURE_WIDTH_3D 1920
#define DEFAULT_PICTURE_HEIGHT_3D 1080
#define INITIAL_PREVIEW_HEIGHT 144
#define INITIAL_PREVIEW_WIDTH 176
#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
#define MAX_ZOOM_LEVEL 5
#define NOT_FOUND -1
// Number of video buffers held by kernal (initially 1,2 &3)
#define ACTIVE_VIDEO_BUFFERS 3
#define ACTIVE_PREVIEW_BUFFERS 3
#define ACTIVE_ZSL_BUFFERS 3
#define APP_ORIENTATION 90
#define HDR_HAL_FRAME 2
#define FLASH_AUTO 24
#define FLASH_SNAP 32
#define DUMMY_CAMERA_STARTED 1;
#define DUMMY_CAMERA_STOPPED 0;
#define FLOOR16(X) ((X) & 0xFFF0)
#if DLOPEN_LIBMMCAMERA
#include <dlfcn.h>
// Conversion routines from YV420sp to YV12 format
int (*LINK_yuv_convert_ycrcb420sp_to_yv12_inplace) (yuv_image_type* yuvStructPtr);
int (*LINK_yuv_convert_ycrcb420sp_to_yv12) (yuv_image_type* yuvStructPtrin, yuv_image_type* yuvStructPtrout);
#define NUM_YV12_FRAMES 1
#define FOCUS_AREA_INIT "(-1000,-1000,1000,1000,1000)"
void *libmmcamera;
void* (*LINK_cam_conf)(void *data);
void* (*LINK_cam_frame)(void *data);
void* (*LINK_wait_cam_frame_thread_ready)(void);
void* (*LINK_cam_frame_set_exit_flag)(int flag);
bool (*LINK_jpeg_encoder_init)();
void (*LINK_jpeg_encoder_join)();
bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
const uint8_t *thumbnailbuf, int thumbnailfd,
const uint8_t *snapshotbuf, int snapshotfd,
common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
int exif_table_numEntries, int jpegPadding, const int32_t cbcroffset,int zsl_enable);
void (*LINK_camframe_terminate)(void);
//for 720p
// Function pointer , called by camframe when a video frame is available.
void (**LINK_camframe_video_callback)(struct msm_frame * frame);
// Function to add a frame to free Q
void (*LINK_camframe_add_frame)(cam_frame_type_t type,struct msm_frame *frame);
void (*LINK_camframe_release_all_frames)(cam_frame_type_t type);
int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
int8_t (*LINK_jpeg_encoder_get_buffer_offset)(uint32_t width, uint32_t height,
uint32_t* p_y_offset,
uint32_t* p_cbcr_offset,
uint32_t* p_buf_size);
int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
void (*LINK_jpeg_encoder_set_3D_info)(cam_3d_frame_format_t format);
const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
int (*LINK_launch_cam_conf_thread)(void);
int (*LINK_release_cam_conf_thread)(void);
mm_camera_status_t (*LINK_mm_camera_init)(mm_camera_config *, mm_camera_notify*, mm_camera_ops*,uint8_t);
mm_camera_status_t (*LINK_mm_camera_deinit)();
mm_camera_status_t (*LINK_mm_camera_destroy)();
mm_camera_status_t (*LINK_mm_camera_exec)();
mm_camera_status_t (*LINK_mm_camera_get_camera_info) (qcamera_info_t* p_cam_info, int* p_num_cameras);
int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
// callbacks
void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
void (**LINK_cancel_liveshot)(void);
int8_t (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data,
int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size);
void (*LINK_set_liveshot_frame)(struct msm_frame *liveshot_frame);
#else
#define LINK_cam_conf cam_conf
#define LINK_cam_frame cam_frame
#define LINK_wait_cam_frame_thread_ready wait_cam_frame_thread_ready
#define LINK_cam_frame cam_frame_set_exit_flag
#define LINK_jpeg_encoder_init jpeg_encoder_init
#define LINK_jpeg_encoder_join jpeg_encoder_join
#define LINK_jpeg_encoder_encode jpeg_encoder_encode
#define LINK_camframe_terminate camframe_terminate
#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
#define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset
#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
#define LINK_jpeg_encoder_set_3D_info jpeg_encoder_set_3D_info
#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
#define LINK_launch_cam_conf_thread launch_cam_conf_thread
#define LINK_release_cam_conf_thread release_cam_conf_thread
#define LINK_zoom_crop_upscale zoom_crop_upscale
#define LINK_mm_camera_init mm_camera_config_init
#define LINK_mm_camera_deinit mm_camera_config_deinit
#define LINK_mm_camera_destroy mm_camera_config_destroy
#define LINK_mm_camera_exec mm_camera_exec
#define LINK_camframe_add_frame camframe_add_frame
#define LINK_camframe_release_all_frames camframe_release_all_frames
#define LINK_mm_camera_get_camera_info mm_camera_get_camera_info
extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
extern void (*mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
uint32_t buff_size);
extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
#define LINK_set_liveshot_params set_liveshot_params
#define LINK_set_liveshot_frame set_liveshot_frame
#endif
} // extern "C"
#ifndef HAVE_CAMERA_SIZE_TYPE
struct camera_size_type {
int width;
int height;
};
#endif
#if 0
typedef struct crop_info_struct {
int32_t x;
int32_t y;
int32_t w;
int32_t h;
} zoom_crop_info;
#endif
union zoomimage
{
char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
struct mdp_blit_req_list list;
} zoomImage;
//Default to VGA
#define DEFAULT_PREVIEW_WIDTH 640
#define DEFAULT_PREVIEW_HEIGHT 480
#define DEFAULT_PREVIEW_WIDTH_3D 1280
#define DEFAULT_PREVIEW_HEIGHT_3D 720
//Default FPS
#define MINIMUM_FPS 5
#define MAXIMUM_FPS 31
#define DEFAULT_FPS MAXIMUM_FPS
#define DEFAULT_FIXED_FPS_VALUE 30
/*
* Modifying preview size requires modification
* in bitmasks for boardproperties
*/
static uint32_t PREVIEW_SIZE_COUNT;
static uint32_t HFR_SIZE_COUNT;
board_property boardProperties[] = {
{TARGET_MSM7625, 0x00000fff, false, false, false},
{TARGET_MSM7625A, 0x00000fff, false, false, false},
{TARGET_MSM7627, 0x000006ff, false, false, false},
{TARGET_MSM7627A, 0x000006ff, false, false, false},
{TARGET_MSM7630, 0x00000fff, true, true, false},
{TARGET_MSM8660, 0x00001fff, true, true, false},
{TARGET_QSD8250, 0x00000fff, false, false, false}
};
//static const camera_size_type* picture_sizes;
//static int PICTURE_SIZE_COUNT;
/* TODO
* Ideally this should be a populated by lower layers.
* But currently this is no API to do that at lower layer.
* Hence populating with default sizes for now. This needs
* to be changed once the API is supported.
*/
//sorted on column basis
static struct camera_size_type zsl_picture_sizes[] = {
{ 1024, 768}, // 1MP XGA
{ 800, 600}, //SVGA
{ 800, 480}, // WVGA
{ 640, 480}, // VGA
{ 352, 288}, //CIF
{ 320, 240}, // QVGA
{ 176, 144} // QCIF
};
static struct camera_size_type for_3D_picture_sizes[] = {
{ 1920, 1080},
};
static int data_counter = 0;
static int sensor_rotation = 0;
static int record_flag = 0;
static camera_size_type* picture_sizes;
static camera_size_type* preview_sizes;
static camera_size_type* hfr_sizes;
static unsigned int PICTURE_SIZE_COUNT;
static const camera_size_type * picture_sizes_ptr;
static int supportedPictureSizesCount;
static liveshotState liveshot_state = LIVESHOT_DONE;
#ifdef Q12
#undef Q12
#endif
#define Q12 4096
static const target_map targetList [] = {
{ "msm7625", TARGET_MSM7625 },
{ "msm7625a", TARGET_MSM7625A },
{ "msm7627", TARGET_MSM7627 },
{ "msm7627a", TARGET_MSM7627A },
{ "qsd8250", TARGET_QSD8250 },
{ "msm7630", TARGET_MSM7630 },
{ "msm8660", TARGET_MSM8660 }
};
static targetType mCurrentTarget = TARGET_MAX;
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.662337
{ 6144, 432, 288 }, //1.5
{ 5461, 512, 384 }, //1.333333
{ 5006, 352, 288 }, //1.222222
};
#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
static camera_size_type jpeg_thumbnail_sizes[] = {
{ 512, 288 },
{ 480, 288 },
{ 432, 288 },
{ 512, 384 },
{ 352, 288 },
{0,0}
};
//supported preview fps ranges should be added to this array in the form (minFps,maxFps)
static android::FPSRange FpsRangesSupported[] = {{MINIMUM_FPS*1000,MAXIMUM_FPS*1000}};
#define FPS_RANGES_SUPPORTED_COUNT (sizeof(FpsRangesSupported)/sizeof(FpsRangesSupported[0]))
#define JPEG_THUMBNAIL_SIZE_COUNT (sizeof(jpeg_thumbnail_sizes)/sizeof(camera_size_type))
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;
}
// round to the next power of two
static inline unsigned clp2(unsigned x)
{
x = x - 1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return x + 1;
}
static int exif_table_numEntries = 0;
#define MAX_EXIF_TABLE_ENTRIES 14
exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
//static zoom_crop_info zoomCropInfo;
static android_native_rect_t zoomCropInfo;
static void *mLastQueuedFrame = NULL;
#define RECORD_BUFFERS 9
#define RECORD_BUFFERS_8x50 8
static int kRecordBufferCount;
/* controls whether VPE is avialable for the target
* under consideration.
* 1: VPE support is available
* 0: VPE support is not available (default)
*/
static bool mVpeEnabled;
static cam_frame_start_parms camframeParams;
static int HAL_numOfCameras;
static qcamera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS];
static int HAL_currentCameraId;
static int HAL_currentCameraMode;
static mm_camera_config mCfgControl;
static bool mCameraOpen;
static int HAL_currentSnapshotMode;
static int previewWidthToNativeZoom;
static int previewHeightToNativeZoom;
#define CAMERA_SNAPSHOT_NONZSL 0x04
#define CAMERA_SNAPSHOT_ZSL 0x08
namespace android {
extern void native_send_data_callback(int32_t msgType,
camera_memory_t * framebuffer,
void* user);
extern camera_memory_t* get_mem(int fd,size_t buf_size,
unsigned int num_bufs,
void *user);
static const int PICTURE_FORMAT_JPEG = 1;
static const int PICTURE_FORMAT_RAW = 2;
// 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 }
};
// from camera_effect_t. This list must match aeecamera.h
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 }
};
// from qcamera/common/camera.h
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 qcamera/common/camera.h
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 antibanding_3D[] = {
{ QCameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
{ QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
{ QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ }
};
/* Mapping from MCC to antibanding type */
struct country_map {
uint32_t country_code;
camera_antibanding_type type;
};
#if 0 //not using this function. keeping this as this came from Google.
static struct country_map country_numeric[] = {
{ 202, CAMERA_ANTIBANDING_50HZ }, // Greece
{ 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
{ 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
{ 208, CAMERA_ANTIBANDING_50HZ }, // France
{ 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
{ 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
{ 214, CAMERA_ANTIBANDING_50HZ }, // Spain
{ 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
{ 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
{ 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
{ 222, CAMERA_ANTIBANDING_50HZ }, // Italy
{ 226, CAMERA_ANTIBANDING_50HZ }, // Romania
{ 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
{ 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
{ 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
{ 232, CAMERA_ANTIBANDING_50HZ }, // Austria
{ 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
{ 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
{ 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
{ 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
{ 242, CAMERA_ANTIBANDING_50HZ }, // Norway
{ 244, CAMERA_ANTIBANDING_50HZ }, // Finland
{ 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
{ 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
{ 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
{ 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
{ 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
{ 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
{ 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
{ 260, CAMERA_ANTIBANDING_50HZ }, // Poland
{ 262, CAMERA_ANTIBANDING_50HZ }, // Germany
{ 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
{ 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
{ 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
{ 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
{ 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
{ 276, CAMERA_ANTIBANDING_50HZ }, // Albania
{ 278, CAMERA_ANTIBANDING_50HZ }, // Malta
{ 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
{ 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
{ 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
{ 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
{ 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
{ 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
{ 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
{ 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
{ 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
{ 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
{ 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
{ 302, CAMERA_ANTIBANDING_60HZ }, // Canada
{ 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
{ 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
{ 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
{ 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
{ 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
{ 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
{ 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
{ 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
{ 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
{ 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
{ 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
{ 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
{ 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
{ 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
{ 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
{ 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
{ 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
{ 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
{ 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
{ 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
{ 404, CAMERA_ANTIBANDING_50HZ }, // India
{ 405, CAMERA_ANTIBANDING_50HZ }, // India
{ 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
{ 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
{ 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
{ 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
{ 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
{ 417, CAMERA_ANTIBANDING_50HZ }, // Syria
{ 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
{ 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
{ 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
{ 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
{ 422, CAMERA_ANTIBANDING_50HZ }, // Oman
{ 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
{ 425, CAMERA_ANTIBANDING_50HZ }, // Israel
{ 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
{ 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
{ 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
{ 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
{ 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
{ 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
{ 432, CAMERA_ANTIBANDING_50HZ }, // Iran
{ 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
{ 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
{ 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
{ 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
{ 440, CAMERA_ANTIBANDING_60HZ }, // Japan
{ 441, CAMERA_ANTIBANDING_60HZ }, // Japan
{ 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
{ 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
{ 455, CAMERA_ANTIBANDING_50HZ }, // Macao
{ 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
{ 457, CAMERA_ANTIBANDING_50HZ }, // Laos
{ 460, CAMERA_ANTIBANDING_50HZ }, // China
{ 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
{ 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
{ 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
{ 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
{ 505, CAMERA_ANTIBANDING_50HZ }, // Australia
{ 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
{ 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
{ 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
{ 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
{ 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
{ 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
{ 535, CAMERA_ANTIBANDING_60HZ }, // Guam
{ 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
{ 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
{ 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
{ 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
{ 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
{ 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
{ 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
{ 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
{ 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
{ 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
{ 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
{ 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
{ 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
{ 606, CAMERA_ANTIBANDING_50HZ }, // Libya
{ 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
{ 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
{ 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
{ 610, CAMERA_ANTIBANDING_50HZ }, // Mali
{ 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
{ 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
{ 614, CAMERA_ANTIBANDING_50HZ }, // Niger
{ 616, CAMERA_ANTIBANDING_50HZ }, // Benin
{ 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
{ 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
{ 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
{ 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
{ 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
{ 622, CAMERA_ANTIBANDING_50HZ }, // Chad
{ 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
{ 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
{ 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
{ 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
{ 631, CAMERA_ANTIBANDING_50HZ }, // Angola
{ 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
{ 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
{ 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
{ 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
{ 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
{ 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
{ 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
{ 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
{ 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
{ 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
{ 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
{ 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
{ 647, CAMERA_ANTIBANDING_50HZ }, // France
{ 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
{ 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
{ 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
{ 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
{ 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
{ 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
{ 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
{ 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
{ 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
{ 702, CAMERA_ANTIBANDING_60HZ }, // Belize
{ 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
{ 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
{ 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
{ 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
{ 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
{ 714, CAMERA_ANTIBANDING_60HZ }, // Panama
{ 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
{ 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
{ 730, CAMERA_ANTIBANDING_50HZ }, // Chile
{ 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
{ 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
{ 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
{ 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
{ 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
{ 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
{ 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
{ 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
{ 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
{ 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
};
#define country_number (sizeof(country_numeric) / sizeof(country_map))
/* Look up pre-sorted antibanding_type table by current MCC. */
static camera_antibanding_type camera_get_location(void) {
char value[PROP_VALUE_MAX];
char country_value[PROP_VALUE_MAX];
uint32_t country_code;
memset(value, 0x00, sizeof(value));
memset(country_value, 0x00, sizeof(country_value));
if (!__system_property_get("gsm.operator.numeric", value)) {
return CAMERA_ANTIBANDING_60HZ;
}
memcpy(country_value, value, 3);
country_code = atoi(country_value);
ALOGD("value:%s, country value:%s, country code:%d\n",
value, country_value, country_code);
int left = 0;
int right = country_number - 1;
while (left <= right) {
int index = (left + right) >> 1;
if (country_numeric[index].country_code == country_code)
return country_numeric[index].type;
else if (country_numeric[index].country_code > country_code)
right = index - 1;
else
left = index + 1;
}
return CAMERA_ANTIBANDING_60HZ;
}
#endif
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 },
};
static const str_map scenedetect[] = {
{ QCameraParameters::SCENE_DETECT_OFF, FALSE },
{ QCameraParameters::SCENE_DETECT_ON, TRUE },
};
// from camera.h, led_mode_t
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}
};
// from mm-camera/common/camera.h.
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 iso_3D[] = {
{ QCameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
{ 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 }
};
#define DONT_CARE AF_MODE_MAX
static const str_map focus_modes[] = {
{ QCameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
{ QCameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
{ 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, DONT_CARE }
};
static const str_map lensshade[] = {
{ QCameraParameters::LENSSHADE_ENABLE, TRUE },
{ QCameraParameters::LENSSHADE_DISABLE, FALSE }
};
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 str_map mce[] = {
{ QCameraParameters::MCE_ENABLE, TRUE },
{ QCameraParameters::MCE_DISABLE, FALSE }
};
static const str_map hdr[] = {
{ QCameraParameters::HDR_ENABLE, TRUE },
{ QCameraParameters::HDR_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 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 facedetection[] = {
{ QCameraParameters::FACE_DETECTION_OFF, FALSE },
{ QCameraParameters::FACE_DETECTION_ON, TRUE }
};
#define DONT_CARE_COORDINATE -1
static const str_map touchafaec[] = {
{ QCameraParameters::TOUCH_AF_AEC_OFF, FALSE },
{ QCameraParameters::TOUCH_AF_AEC_ON, TRUE }
};
static const str_map redeye_reduction[] = {
{ QCameraParameters::REDEYE_REDUCTION_ENABLE, TRUE },
{ QCameraParameters::REDEYE_REDUCTION_DISABLE, FALSE }
};
static const str_map zsl_modes[] = {
{ QCameraParameters::ZSL_OFF, FALSE },
{ QCameraParameters::ZSL_ON, TRUE },
};
/*
* Values based on aec.c
*/
#define DONT_CARE_COORDINATE -1
#define CAMERA_HISTOGRAM_ENABLE 1
#define CAMERA_HISTOGRAM_DISABLE 0
#define HISTOGRAM_STATS_SIZE 257
/*
* Values based on aec.c
*/
#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)
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 picture_formats_zsl[] = {
{QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG}
};
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 int mPreviewFormat;
static const str_map preview_formats[] = {
{QCameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21},
{QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO},
{QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12}
};
static const str_map preview_formats1[] = {
{QCameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21},
{QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12}
};
static const str_map app_preview_formats[] = {
{QCameraParameters::PIXEL_FORMAT_YUV420SP, HAL_PIXEL_FORMAT_YCrCb_420_SP}, //nv21
//{QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO}, //nv21_adreno
{QCameraParameters::PIXEL_FORMAT_YUV420P, HAL_PIXEL_FORMAT_YV12}, //YV12
};
static bool parameter_string_initialized = false;
static String8 preview_size_values;
static String8 hfr_size_values;
static String8 picture_size_values;
static String8 fps_ranges_supported_values;
static String8 jpeg_thumbnail_size_values;
static String8 antibanding_values;
static String8 effect_values;
static String8 autoexposure_values;
static String8 whitebalance_values;
static String8 flash_values;
static String8 focus_mode_values;
static String8 iso_values;
static String8 lensshade_values;
static String8 mce_values;
static String8 hdr_values;
static String8 histogram_values;
static String8 skinToneEnhancement_values;
static String8 touchafaec_values;
static String8 picture_format_values;
static String8 scenemode_values;
static String8 denoise_values;
static String8 zoom_ratio_values;
static String8 preview_frame_rate_values;
static String8 frame_rate_mode_values;
static String8 scenedetect_values;
static String8 preview_format_values;
static String8 selectable_zone_af_values;
static String8 facedetection_values;
static String8 hfr_values;
static String8 redeye_reduction_values;
static String8 zsl_values;
mm_camera_notify mCamNotify;
mm_camera_ops mCamOps;
static mm_camera_buffer_t mEncodeOutputBuffer[MAX_SNAPSHOT_BUFFERS];
static encode_params_t mImageEncodeParms;
static capture_params_t mImageCaptureParms;
static raw_capture_params_t mRawCaptureParms;
static zsl_capture_params_t mZslCaptureParms;
static zsl_params_t mZslParms;
static yv12_format_parms_t myv12_params;
static String8 create_sizes_str(const camera_size_type *sizes, int len) {
String8 str;
char buffer[32];
if (len > 0) {
sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
str.append(buffer);
}
for (int i = 1; i < len; i++) {
sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
str.append(buffer);
}
return str;
}
static String8 create_fps_str(const android:: FPSRange* fps, int len) {
String8 str;
char buffer[32];
if (len > 0) {
sprintf(buffer, "(%d,%d)", fps[0].minFPS, fps[0].maxFPS);
str.append(buffer);
}
for (int i = 1; i < len; i++) {
sprintf(buffer, ",(%d,%d)", fps[i].minFPS, fps[i].maxFPS);
str.append(buffer);
}
return str;
}
static String8 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_str(int16_t *arr, int length){
String8 str;
char buffer[32];
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;
}
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;
}
extern "C" {
//------------------------------------------------------------------------
// : 720p busyQ funcitons
// --------------------------------------------------------------------
static struct fifo_queue g_busy_frame_queue =
{0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, (char *)"video_busy_q"};
};
static void cam_frame_wait_video (void)
{
ALOGV("cam_frame_wait_video E ");
if ((g_busy_frame_queue.num_of_frames) <=0){
pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut));
}
ALOGV("cam_frame_wait_video X");
return;
}
void cam_frame_flush_video (void)
{
ALOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames);
pthread_mutex_lock(&(g_busy_frame_queue.mut));
while (g_busy_frame_queue.front)
{
//dequeue from the busy queue
struct fifo_node *node = dequeue (&g_busy_frame_queue);
if(node)
free(node);
ALOGV("cam_frame_flush_video: node \n");
}
pthread_mutex_unlock(&(g_busy_frame_queue.mut));
ALOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames);
return ;
}
static struct msm_frame * cam_frame_get_video()
{
struct msm_frame *p = NULL;
ALOGV("cam_frame_get_video... in\n");
ALOGV("cam_frame_get_video... got lock\n");
if (g_busy_frame_queue.front)
{
//dequeue
struct fifo_node *node = dequeue (&g_busy_frame_queue);
if (node)
{
p = (struct msm_frame *)node->f;
free (node);
}
ALOGV("cam_frame_get_video... out = %x\n", p->buffer);
}
return p;
}
// Parse string like "(1, 2, 3, 4, ..., N)"
// num is pointer to an allocated array of size N
static int parseNDimVector_HAL(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;
}
static int countChar(const char *str , char ch )
{
int noOfChar = 0;
for ( int i = 0; str[i] != '\0'; i++) {
if ( str[i] == ch )
noOfChar = noOfChar + 1;
}
return noOfChar;
}
int checkAreaParameters(const char *str)
{
int areaValues[6];
int left, right, top, bottom, weight;
if(countChar(str, ',') > 4) {
ALOGE("%s: No of area parameters exceeding the expected number %s", __FUNCTION__, str);
return -1;
}
if(parseNDimVector_HAL(str, areaValues, 5) !=0) {
ALOGE("%s: Failed to parse the input string %s", __FUNCTION__, str);
return -1;
}
ALOGV("%s: Area values are %d,%d,%d,%d,%d", __FUNCTION__,
areaValues[0], areaValues[1], areaValues[2], areaValues[3], areaValues[4]);
left = areaValues[0];
top = areaValues[1];
right = areaValues[2];
bottom = areaValues[3];
weight = areaValues[4];
// left should >= -1000
if (!(left >= -1000))
return -1;
// top should >= -1000
if(!(top >= -1000))
return -1;
// right should <= 1000
if(!(right <= 1000))
return -1;
// bottom should <= 1000
if(!(bottom <= 1000))
return -1;
// weight should >= 1
// weight should <= 1000
if(!((1 <= weight) && (weight <= 1000)))
return -1;
// left should < right
if(!(left < right))
return -1;
// top should < bottom
if(!(top < bottom))
return -1;
return 0;
}
static void cam_frame_post_video (struct msm_frame *p)
{
if (!p)
{
ALOGE("post video , buffer is null");
return;
}
ALOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer));
pthread_mutex_lock(&(g_busy_frame_queue.mut));
ALOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames);
//enqueue to busy queue
struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node));
if (node)
{
ALOGV(" post video , enqueing in busy queue");
node->f = p;
node->next = NULL;
enqueue (&g_busy_frame_queue, node);
ALOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames);
}
else
{
ALOGE("cam_frame_post_video error... out of memory\n");
}
pthread_mutex_unlock(&(g_busy_frame_queue.mut));
pthread_cond_signal(&(g_busy_frame_queue.wait));
ALOGV("cam_frame_post_video... out = %x\n", p->buffer);
return;
}
QualcommCameraHardware::FrameQueue::FrameQueue(){
mInitialized = false;
}
QualcommCameraHardware::FrameQueue::~FrameQueue(){
flush();
}
void QualcommCameraHardware::FrameQueue::init(){
Mutex::Autolock l(&mQueueLock);
mInitialized = true;
mQueueWait.signal();
}
void QualcommCameraHardware::FrameQueue::deinit(){
Mutex::Autolock l(&mQueueLock);
mInitialized = false;
mQueueWait.signal();
}
bool QualcommCameraHardware::FrameQueue::isInitialized(){
Mutex::Autolock l(&mQueueLock);
return mInitialized;
}
bool QualcommCameraHardware::FrameQueue::add(
struct msm_frame * element){
Mutex::Autolock l(&mQueueLock);
if(mInitialized == false)
return false;
mContainer.add(element);
mQueueWait.signal();
return true;
}
struct msm_frame * QualcommCameraHardware::FrameQueue::get(){
struct msm_frame *frame;
mQueueLock.lock();
while(mInitialized && mContainer.isEmpty()){
mQueueWait.wait(mQueueLock);
}
if(!mInitialized){
mQueueLock.unlock();
return NULL;
}
frame = mContainer.itemAt(0);
mContainer.removeAt(0);
mQueueLock.unlock();
return frame;
}
void QualcommCameraHardware::FrameQueue::flush(){
Mutex::Autolock l(&mQueueLock);
mContainer.clear();
}
void QualcommCameraHardware::storeTargetType(void) {
char mDeviceName[PROPERTY_VALUE_MAX];
property_get("ro.product.device",mDeviceName," ");
mCurrentTarget = TARGET_MAX;
for( int i = 0; i < TARGET_MAX ; i++) {
if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) {
mCurrentTarget = targetList[i].targetEnum;
if(mCurrentTarget == TARGET_MSM7625) {
if(!strncmp(mDeviceName, "msm7625a" , 8))
mCurrentTarget = TARGET_MSM7625A;
}
if(mCurrentTarget == TARGET_MSM7627) {
if(!strncmp(mDeviceName, "msm7627a" , 8))
mCurrentTarget = TARGET_MSM7627A;
}
break;
}
}
ALOGV(" Storing the current target type as %d ", mCurrentTarget );
return;
}
void *openCamera(void *data) {
ALOGV(" openCamera : E");
mCameraOpen = false;
if (!libmmcamera) {
ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
return false;
}
*(void **)&LINK_mm_camera_init =
::dlsym(libmmcamera, "mm_camera_init");
*(void **)&LINK_mm_camera_exec =
::dlsym(libmmcamera, "mm_camera_exec");
*(void **)&LINK_mm_camera_deinit =
::dlsym(libmmcamera, "mm_camera_deinit");
if (MM_CAMERA_SUCCESS != LINK_mm_camera_init(&mCfgControl, &mCamNotify, &mCamOps, 0)) {
ALOGE("startCamera: mm_camera_init failed:");
return false;
//pthread_exit((void*) ret_val);
}
uint8_t camera_id8 = (uint8_t)HAL_currentCameraId;
if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_CAMERA_ID, &camera_id8)) {
ALOGE("setting camera id failed");
LINK_mm_camera_deinit();
return false;
//pthread_exit((void*) ret_val);
}
//camera_mode_t mode = (camera_mode_t)HAL_currentCameraMode;
camera_mode_t mode = CAMERA_MODE_2D;
if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_MODE, &mode)) {
ALOGE("startCamera: CAMERA_PARM_MODE failed:");
LINK_mm_camera_deinit();
return false;
//pthread_exit((void*) ret_val);
}
if (MM_CAMERA_SUCCESS != LINK_mm_camera_exec()) {
ALOGE("startCamera: mm_camera_exec failed:");
return false;
//pthread_exit((void*) ret_val);
}
mCameraOpen = true;
ALOGV(" openCamera : X");
if (CAMERA_MODE_3D == mode) {
camera_3d_frame_t snapshotFrame;
snapshotFrame.frame_type = CAM_SNAPSHOT_FRAME;
if(MM_CAMERA_SUCCESS !=
mCfgControl.mm_camera_get_parm(CAMERA_PARM_3D_FRAME_FORMAT,
(void *)&snapshotFrame)){
ALOGE("%s: get 3D format failed", __func__);
LINK_mm_camera_deinit();
return false;
//pthread_exit((void*) ret_val);
}
QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
if (obj != 0) {
obj->mSnapshot3DFormat = snapshotFrame.format;
ALOGI("%s: 3d format snapshot %d", __func__, obj->mSnapshot3DFormat);
}
}
ALOGV("openCamera : X");
// pthread_exit((void*) ret_val);
return NULL;
}
//-------------------------------------------------------------------------------------
static Mutex singleton_lock;
static bool singleton_releasing;
static nsecs_t singleton_releasing_start_time;
static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5);
static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1);
static Condition singleton_wait;
static void receive_camframe_callback(struct msm_frame *frame);
static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size);
static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo);
static void receive_camframe_video_callback(struct msm_frame *frame); // 720p
static int8_t receive_event_callback(mm_camera_event* event);
static void receive_shutter_callback(common_crop_t *crop);
static void receive_camframe_error_callback(camera_error_type err);
static int fb_fd = -1;
static int32_t mMaxZoom = 0;
static bool zoomSupported = false;
static int dstOffset = 0;
static int16_t * zoomRatios;
/* When using MDP zoom, double the preview buffers. The usage of these
* buffers is as follows:
* 1. As all the buffers comes under a single FD, and at initial registration,
* this FD will be passed to surface flinger, surface flinger can have access
* to all the buffers when needed.
* 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the
* camera driver to receive preview frames. The remaining buffers (DstSet),
* will be used at HAL and by surface flinger only when crop information
* is present in the frame.
* 3. When there is no crop information, there will be no call to MDP zoom,
* and the buffers in SrcSet will be passed to surface flinger to display.
* 4. With crop information present, MDP zoom will be called, and the final
* data will be placed in a buffer from DstSet, and this buffer will be given
* to surface flinger to display.
*/
#define NUM_MORE_BUFS 2
QualcommCameraHardware::QualcommCameraHardware()
: mParameters(),
mCameraRunning(false),
mPreviewInitialized(false),
mPreviewThreadRunning(false),
mHFRThreadRunning(false),
mFrameThreadRunning(false),
mVideoThreadRunning(false),
mSnapshotThreadRunning(false),
mJpegThreadRunning(false),
mSmoothzoomThreadRunning(false),
mSmoothzoomThreadExit(false),
mInSnapshotMode(false),
mEncodePending(false),
mBuffersInitialized(false),
mSnapshotFormat(0),
mFirstFrame(true),
mReleasedRecordingFrame(false),
mPreviewFrameSize(0),
mRawSize(0),
mCbCrOffsetRaw(0),
mYOffset(0),
mAutoFocusThreadRunning(false),
mInitialized(false),
mBrightness(0),
mSkinToneEnhancement(0),
mHJR(0),
mInPreviewCallback(false),
//mUseOverlay(0),
mIs3DModeOn(0),
//mOverlay(0),
mMsgEnabled(0),
mNotifyCallback(0),
mDataCallback(0),
mDataCallbackTimestamp(0),
mCallbackCookie(0),
mDebugFps(0),
mSnapshotDone(0),
maxSnapshotWidth(0),
maxSnapshotHeight(0),
mHasAutoFocusSupport(0),
mDisEnabled(0),
mRotation(0),
mResetWindowCrop(false),
mThumbnailWidth(0),
mThumbnailHeight(0),
strTexturesOn(false),
mPictureWidth(0),
mPictureHeight(0),
mPostviewWidth(0),
mPostviewHeight(0),
mPreviewWindow(NULL),
mTotalPreviewBufferCount(0),
mZslFlashEnable(false),
mZslPanorama(false),
mSnapshotCancel(false),
mHFRMode(false),
mActualPictWidth(0),
mActualPictHeight(0),
mDenoiseValue(0),
mPreviewStopping(false),
mInHFRThread(false),
mPrevHeapDeallocRunning(false),
mHdrMode(false ),
mExpBracketMode(false),
mZslEnable(false),
mStoreMetaDataInFrame(0),
mRecordingState(0)
{
ALOGI("QualcommCameraHardware constructor E");
mMMCameraDLRef = MMCameraDL::getInstance();
libmmcamera = mMMCameraDLRef->pointer();
char value[PROPERTY_VALUE_MAX];
mCameraOpen = false;
/*if(HAL_currentSnapshotMode == CAMERA_SNAPSHOT_ZSL) {
ALOGI("%s: this is ZSL mode", __FUNCTION__);
mZslEnable = true;
}*/
property_get("persist.camera.hal.multitouchaf", value, "0");
mMultiTouch = atoi(value);
storeTargetType();
for(int i=0; i< MAX_SNAPSHOT_BUFFERS; i++) {
mRawMapped[i] = NULL;
mJpegMapped[i] = NULL;
mThumbnailMapped[i] = NULL;
}
mRawSnapshotMapped = NULL;
mJpegCopyMapped = NULL;
for(int i=0; i< RECORD_BUFFERS; i++) {
mRecordMapped[i] = NULL;
}
for(int i=0; i<3; i++)
mStatsMapped[i] = NULL;
mJpegLiveSnapMapped = NULL;
if(HAL_currentCameraMode == CAMERA_SUPPORT_MODE_3D){
mIs3DModeOn = true;
}
/* TODO: Will remove this command line interface at end */
property_get("persist.camera.hal.3dmode", value, "0");
int mode = atoi(value);
if( mode == 1) {
mIs3DModeOn = true;
HAL_currentCameraMode = CAMERA_MODE_3D;
}
if( (pthread_create(&mDeviceOpenThread, NULL, openCamera, NULL)) != 0) {
ALOGE(" openCamera thread creation failed ");
}
memset(&mDimension, 0, sizeof(mDimension));
memset(&mCrop, 0, sizeof(mCrop));
memset(&zoomCropInfo, 0, sizeof(android_native_rect_t));
//storeTargetType();
property_get("persist.debug.sf.showfps", value, "0");
mDebugFps = atoi(value);
if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) {
kPreviewBufferCountActual = kPreviewBufferCount;
kRecordBufferCount = RECORD_BUFFERS;
recordframes = new msm_frame[kRecordBufferCount];
record_buffers_tracking_flag = new bool[kRecordBufferCount];
}
else {
kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS;
if( mCurrentTarget == TARGET_QSD8250 ) {
kRecordBufferCount = RECORD_BUFFERS_8x50;
recordframes = new msm_frame[kRecordBufferCount];
record_buffers_tracking_flag = new bool[kRecordBufferCount];
}
}
mTotalPreviewBufferCount = kTotalPreviewBufferCount;
if((mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250)
&& (mCurrentTarget != TARGET_MSM8660)) {
for (int i = 0; i < mTotalPreviewBufferCount; i++)
metadata_memory[i] = NULL;
}
else {
for (int i = 0; i < kRecordBufferCount; i++)
metadata_memory[i] = NULL;
}
switch(mCurrentTarget){
case TARGET_MSM7627:
case TARGET_MSM7627A:
jpegPadding = 0; // to be checked.
break;
case TARGET_QSD8250:
case TARGET_MSM7630:
case TARGET_MSM8660:
jpegPadding = 0;
break;
default:
jpegPadding = 0;
break;
}
// Initialize with default format values. The format values can be
// overriden when application requests.
mDimension.prev_format = CAMERA_YUV_420_NV21;
mPreviewFormat = CAMERA_YUV_420_NV21;
mDimension.enc_format = CAMERA_YUV_420_NV21;
if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
mDimension.enc_format = CAMERA_YUV_420_NV12;
mDimension.main_img_format = CAMERA_YUV_420_NV21;
mDimension.thumb_format = CAMERA_YUV_420_NV21;
if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){
/* DIS is disabled all the time in VPE support targets.
* No provision for the user to control this.
*/
mDisEnabled = 0;
/* Get the DIS value from properties, to check whether
* DIS is disabled or not. If the property is not found
* default to DIS disabled.*/
property_get("persist.camera.hal.dis", value, "0");
mDisEnabled = atoi(value);
mVpeEnabled = 1;
}
if(mIs3DModeOn) {
mDisEnabled = 0;
}
ALOGV("constructor EX");
}
void QualcommCameraHardware::hasAutoFocusSupport(){
if( !mCamOps.mm_camera_is_supported(CAMERA_OPS_FOCUS)){
ALOGI("AutoFocus is not supported");
mHasAutoFocusSupport = false;
}else {
mHasAutoFocusSupport = true;
}
if(mZslEnable)
mHasAutoFocusSupport = false;
}
//filter Picture sizes based on max width and height
void QualcommCameraHardware::filterPictureSizes(){
unsigned int i;
if(PICTURE_SIZE_COUNT <= 0)
return;
maxSnapshotWidth = picture_sizes[0].width;
maxSnapshotHeight = picture_sizes[0].height;
// Iterate through all the width and height to find the max value
for(i =0; i<PICTURE_SIZE_COUNT;i++){
if(((maxSnapshotWidth < picture_sizes[i].width) &&
(maxSnapshotHeight <= picture_sizes[i].height))){
maxSnapshotWidth = picture_sizes[i].width;
maxSnapshotHeight = picture_sizes[i].height;
}
}
if(mZslEnable){
// due to lack of PMEM we restrict to lower resolution
picture_sizes_ptr = zsl_picture_sizes;
supportedPictureSizesCount = 7;
}
else if(mIs3DModeOn){
// In 3D mode we only want 1080p picture size
picture_sizes_ptr = for_3D_picture_sizes;
supportedPictureSizesCount = 1;
}
else{
picture_sizes_ptr = picture_sizes;
supportedPictureSizesCount = PICTURE_SIZE_COUNT;
}
}
bool QualcommCameraHardware::supportsSceneDetection() {
unsigned int prop = 0;
for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
if((mCurrentTarget == boardProperties[prop].target)
&& boardProperties[prop].hasSceneDetect == true) {
return true;
break;
}
}
return false;
}
bool QualcommCameraHardware::supportsSelectableZoneAf() {
unsigned int prop = 0;
for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
if((mCurrentTarget == boardProperties[prop].target)
&& boardProperties[prop].hasSelectableZoneAf == true) {
return true;
break;
}
}
return false;
}
bool QualcommCameraHardware::supportsFaceDetection() {
unsigned int prop = 0;
for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
if((mCurrentTarget == boardProperties[prop].target)
&& boardProperties[prop].hasFaceDetect == true) {
return true;
break;
}
}
return false;
}
void QualcommCameraHardware::initDefaultParameters()
{
ALOGV("initDefaultParameters E");
mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
mDimension.ui_thumbnail_width =
thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
mDimension.ui_thumbnail_height =
thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
sizeof(cam_ctrl_dimension_t),(void *) &mDimension);
if(ret != true) {
ALOGE("CAMERA_PARM_DIMENSION failed!!!");
return;
}
hasAutoFocusSupport();
//Disable DIS for Web Camera
if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_VIDEO_DIS)){
ALOGI("DISABLE DIS");
mDisEnabled = 0;
}else {
ALOGI("Enable DIS");
}
// Initialize constant parameter strings. This will happen only once in the
// lifetime of the mediaserver process.
if (!parameter_string_initialized) {
if(mIs3DModeOn){
antibanding_values = create_values_str(
antibanding_3D, sizeof(antibanding_3D) / sizeof(str_map));
} else{
antibanding_values = create_values_str(
antibanding, sizeof(antibanding) / sizeof(str_map));
}
effect_values = create_values_str(
effects, sizeof(effects) / sizeof(str_map));
autoexposure_values = create_values_str(
autoexposure, sizeof(autoexposure) / sizeof(str_map));
whitebalance_values = create_values_str(
whitebalance, sizeof(whitebalance) / sizeof(str_map));
//filter picture sizes
filterPictureSizes();
picture_size_values = create_sizes_str(
picture_sizes_ptr, supportedPictureSizesCount);
preview_size_values = create_sizes_str(
preview_sizes, PREVIEW_SIZE_COUNT);
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
preview_size_values.string());
mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
preview_size_values.string());
mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
picture_size_values.string());
mParameters.set(QCameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
"true");
mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
QCameraParameters::FOCUS_MODE_INFINITY);
mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
QCameraParameters::FOCUS_MODE_INFINITY);
mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, FOCUS_AREA_INIT);
mParameters.set(QCameraParameters::KEY_METERING_AREAS, FOCUS_AREA_INIT);
if(!mIs3DModeOn){
hfr_size_values = create_sizes_str(
hfr_sizes, HFR_SIZE_COUNT);
}
fps_ranges_supported_values = create_fps_str(
FpsRangesSupported,FPS_RANGES_SUPPORTED_COUNT );
mParameters.set(
QCameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
fps_ranges_supported_values);
mParameters.setPreviewFpsRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000);
flash_values = create_values_str(
flash, sizeof(flash) / sizeof(str_map));
if(mHasAutoFocusSupport){
focus_mode_values = create_values_str(
focus_modes, sizeof(focus_modes) / sizeof(str_map));
}
if(mIs3DModeOn){
iso_values = create_values_str(
iso_3D,sizeof(iso_3D)/sizeof(str_map));
} else{
iso_values = create_values_str(
iso,sizeof(iso)/sizeof(str_map));
}
lensshade_values = create_values_str(
lensshade,sizeof(lensshade)/sizeof(str_map));
mce_values = create_values_str(
mce,sizeof(mce)/sizeof(str_map));
if(!mIs3DModeOn){
hfr_values = create_values_str(
hfr,sizeof(hfr)/sizeof(str_map));
}
if(mCurrentTarget == TARGET_MSM8660)
hdr_values = create_values_str(
hdr,sizeof(hdr)/sizeof(str_map));
//Currently Enabling Histogram for 8x60
if(mCurrentTarget == TARGET_MSM8660) {
histogram_values = create_values_str(
histogram,sizeof(histogram)/sizeof(str_map));
}
//Currently Enabling Skin Tone Enhancement for 8x60 and 7630
if((mCurrentTarget == TARGET_MSM8660)||(mCurrentTarget == TARGET_MSM7630)) {
skinToneEnhancement_values = create_values_str(
skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map));
}
if(mHasAutoFocusSupport){
touchafaec_values = create_values_str(
touchafaec,sizeof(touchafaec)/sizeof(str_map));
}
zsl_values = create_values_str(
zsl_modes,sizeof(zsl_modes)/sizeof(str_map));
if(mZslEnable){
picture_format_values = create_values_str(
picture_formats_zsl, sizeof(picture_formats_zsl)/sizeof(str_map));
} else{
picture_format_values = create_values_str(
picture_formats, sizeof(picture_formats)/sizeof(str_map));
}
if(mCurrentTarget == TARGET_MSM8660 ||
(mCurrentTarget == TARGET_MSM7625A ||
mCurrentTarget == TARGET_MSM7627A)) {
denoise_values = create_values_str(
denoise, sizeof(denoise) / sizeof(str_map));
}
if(mCfgControl.mm_camera_query_parms(CAMERA_PARM_ZOOM_RATIO,
(void **)&zoomRatios, (uint32_t *) &mMaxZoom) == MM_CAMERA_SUCCESS) {
zoomSupported = true;
if( mMaxZoom >0) {
ALOGI("Maximum zoom value is %d", mMaxZoom);
if(zoomRatios != NULL) {
zoom_ratio_values = create_str(zoomRatios, mMaxZoom);
} else {
ALOGE("Failed to get zoomratios ..");
}
} else {
zoomSupported = false;
}
} else {
zoomSupported = false;
ALOGE("Failed to get maximum zoom value...setting max "
"zoom to zero");
mMaxZoom = 0;
}
preview_frame_rate_values = create_values_range_str(
MINIMUM_FPS, MAXIMUM_FPS);
scenemode_values = create_values_str(
scenemode, sizeof(scenemode) / sizeof(str_map));
if(supportsSceneDetection()) {
scenedetect_values = create_values_str(
scenedetect, sizeof(scenedetect) / sizeof(str_map));
}
if(mHasAutoFocusSupport && supportsSelectableZoneAf()){
selectable_zone_af_values = create_values_str(
selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
}
if(mHasAutoFocusSupport && supportsFaceDetection()) {
facedetection_values = create_values_str(
facedetection, sizeof(facedetection) / sizeof(str_map));
}
redeye_reduction_values = create_values_str(
redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map));
parameter_string_initialized = true;
}
//set video size
if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
String8 vSize = create_sizes_str(preview_sizes, 1);
mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, vSize.string());
}
if(mIs3DModeOn){
ALOGI("In initDefaultParameters - 3D mode on so set the default preview to 1280 x 720");
mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH_3D, DEFAULT_PREVIEW_HEIGHT_3D);
mDimension.display_width = DEFAULT_PREVIEW_WIDTH_3D;
mDimension.display_height = DEFAULT_PREVIEW_HEIGHT_3D;
} else{
mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
mDimension.display_width = DEFAULT_PREVIEW_WIDTH;
mDimension.display_height = DEFAULT_PREVIEW_HEIGHT;
}
mParameters.setPreviewFrameRate(DEFAULT_FPS);
if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
mParameters.set(
QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
preview_frame_rate_values.string());
} else {
mParameters.setPreviewFrameRate(DEFAULT_FIXED_FPS_VALUE);
mParameters.set(
QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
DEFAULT_FIXED_FPS_VALUE);
}
mParameters.setPreviewFrameRateMode("frame-rate-auto");
mParameters.setPreviewFormat("yuv420sp"); // informative
mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
if(mIs3DModeOn){
mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH_3D, DEFAULT_PICTURE_HEIGHT_3D);
} else{
mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
}
mParameters.setPictureFormat("jpeg"); // informative
mParameters.set(QCameraParameters::KEY_VIDEO_FRAME_FORMAT, "yuv420sp");
mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
mParameters.set("power-mode-supported", "false");
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(jpeg_thumbnail_sizes, JPEG_THUMBNAIL_SIZE_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(zoomSupported){
mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "true");
ALOGI("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,
zoom_ratio_values);
} else {
mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "false");
}
/* Enable zoom support for video application if VPE enabled */
if(zoomSupported && mVpeEnabled) {
mParameters.set("video-zoom-support", "true");
} else {
mParameters.set("video-zoom-support", "false");
}
mParameters.set(QCameraParameters::KEY_CAMERA_MODE,0);
mParameters.set(QCameraParameters::KEY_ANTIBANDING,
QCameraParameters::ANTIBANDING_OFF);
mParameters.set(QCameraParameters::KEY_EFFECT,
QCameraParameters::EFFECT_NONE);
mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE,
QCameraParameters::AUTO_EXPOSURE_FRAME_AVG);
mParameters.set(QCameraParameters::KEY_WHITE_BALANCE,
QCameraParameters::WHITE_BALANCE_AUTO);
if( (mCurrentTarget != TARGET_MSM7630)
&& (mCurrentTarget != TARGET_QSD8250)
&& (mCurrentTarget != TARGET_MSM8660)
&& (mCurrentTarget != TARGET_MSM7627A)) {
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
"yuv420sp");
} else if(mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) {
preview_format_values = create_values_str(
preview_formats1, sizeof(preview_formats1) / sizeof(str_map));
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
preview_format_values.string());
} else {
preview_format_values = create_values_str(
preview_formats, sizeof(preview_formats) / sizeof(str_map));
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
preview_format_values.string());
}
frame_rate_mode_values = create_values_str(
frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE)){
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
frame_rate_mode_values.string());
}
mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
preview_size_values.string());
mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
picture_size_values.string());
mParameters.set(QCameraParameters::KEY_SUPPORTED_ANTIBANDING,
antibanding_values);
mParameters.set(QCameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
mParameters.set(QCameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
mParameters.set(QCameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
whitebalance_values);
if(mHasAutoFocusSupport){
mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
focus_mode_values);
mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
QCameraParameters::FOCUS_MODE_AUTO);
} else {
mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
QCameraParameters::FOCUS_MODE_INFINITY);
mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
QCameraParameters::FOCUS_MODE_INFINITY);
}
mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
picture_format_values);
if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_LED_MODE)) {
mParameters.set(QCameraParameters::KEY_FLASH_MODE,
QCameraParameters::FLASH_MODE_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_FLASH_MODES,
flash_values);
}
mParameters.set(QCameraParameters::KEY_MAX_SHARPNESS,
CAMERA_MAX_SHARPNESS);
mParameters.set(QCameraParameters::KEY_MAX_CONTRAST,
CAMERA_MAX_CONTRAST);
mParameters.set(QCameraParameters::KEY_MAX_SATURATION,
CAMERA_MAX_SATURATION);
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("luma-adaptation", "3");
mParameters.set("skinToneEnhancement", "0");
mParameters.set("zoom-supported", "true");
mParameters.set("zoom", 0);
mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT,
QCameraParameters::PIXEL_FORMAT_JPEG);
mParameters.set(QCameraParameters::KEY_SHARPNESS,
CAMERA_DEF_SHARPNESS);
mParameters.set(QCameraParameters::KEY_CONTRAST,
CAMERA_DEF_CONTRAST);
mParameters.set(QCameraParameters::KEY_SATURATION,
CAMERA_DEF_SATURATION);
mParameters.set(QCameraParameters::KEY_ISO_MODE,
QCameraParameters::ISO_AUTO);
mParameters.set(QCameraParameters::KEY_LENSSHADE,
QCameraParameters::LENSSHADE_ENABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_ISO_MODES,
iso_values);
mParameters.set(QCameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
lensshade_values);
mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT,
QCameraParameters::MCE_ENABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_MEM_COLOR_ENHANCE_MODES,
mce_values);
if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_HFR) && !(mIs3DModeOn)) {
mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE,
QCameraParameters::VIDEO_HFR_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,
hfr_size_values.string());
mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_HIGH_FRAME_RATE_MODES,
hfr_values);
} else
mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,"");
mParameters.set(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING,
QCameraParameters::MCE_DISABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_HDR_IMAGING_MODES,
hdr_values);
mParameters.set(QCameraParameters::KEY_HISTOGRAM,
QCameraParameters::HISTOGRAM_DISABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
histogram_values);
mParameters.set(QCameraParameters::KEY_SKIN_TONE_ENHANCEMENT,
QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES,
skinToneEnhancement_values);
mParameters.set(QCameraParameters::KEY_SCENE_MODE,
QCameraParameters::SCENE_MODE_AUTO);
mParameters.set("strtextures", "OFF");
mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_MODES,
scenemode_values);
mParameters.set(QCameraParameters::KEY_DENOISE,
QCameraParameters::DENOISE_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_DENOISE,
denoise_values);
//touch af/aec parameters
mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC,
QCameraParameters::TOUCH_AF_AEC_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
touchafaec_values);
mParameters.set("touchAfAec-dx","100");
mParameters.set("touchAfAec-dy","100");
mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
mParameters.set(QCameraParameters::KEY_MAX_NUM_METERING_AREAS, "1");
mParameters.set(QCameraParameters::KEY_SCENE_DETECT,
QCameraParameters::SCENE_DETECT_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_DETECT,
scenedetect_values);
mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF,
QCameraParameters::SELECTABLE_ZONE_AF_AUTO);
mParameters.set(QCameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
selectable_zone_af_values);
mParameters.set(QCameraParameters::KEY_FACE_DETECTION,
QCameraParameters::FACE_DETECTION_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_FACE_DETECTION,
facedetection_values);
mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION,
QCameraParameters::REDEYE_REDUCTION_DISABLE);
mParameters.set(QCameraParameters::KEY_SUPPORTED_REDEYE_REDUCTION,
redeye_reduction_values);
mParameters.set(QCameraParameters::KEY_ZSL,
QCameraParameters::ZSL_OFF);
mParameters.set(QCameraParameters::KEY_SUPPORTED_ZSL_MODES,
zsl_values);
float focalLength = 0.0f;
float horizontalViewAngle = 0.0f;
float verticalViewAngle = 0.0f;
mCfgControl.mm_camera_get_parm(CAMERA_PARM_FOCAL_LENGTH,
(void *)&focalLength);
mParameters.setFloat(QCameraParameters::KEY_FOCAL_LENGTH,
focalLength);
mCfgControl.mm_camera_get_parm(CAMERA_PARM_HORIZONTAL_VIEW_ANGLE,
(void *)&horizontalViewAngle);
mParameters.setFloat(QCameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
horizontalViewAngle);
mCfgControl.mm_camera_get_parm(CAMERA_PARM_VERTICAL_VIEW_ANGLE,
(void *)&verticalViewAngle);
mParameters.setFloat(QCameraParameters::KEY_VERTICAL_VIEW_ANGLE,
verticalViewAngle);
numCapture = 1;
if(mZslEnable) {
int maxSnapshot = MAX_SNAPSHOT_BUFFERS - 2;
char value[5];
property_get("persist.camera.hal.capture", value, "1");
numCapture = atoi(value);
if(numCapture > maxSnapshot)
numCapture = maxSnapshot;
else if(numCapture < 1)
numCapture = 1;
mParameters.set("capture-burst-captures-values", maxSnapshot);
mParameters.set("capture-burst-interval-supported", "false");
}
mParameters.set("num-snaps-per-shutter", numCapture);
ALOGI("%s: setting num-snaps-per-shutter to %d", __FUNCTION__, numCapture);
if(mIs3DModeOn)
mParameters.set("3d-frame-format", "left-right");
switch(mCurrentTarget){
case TARGET_MSM7627:
case TARGET_QSD8250:
case TARGET_MSM7630:
mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "800x480");
break;
case TARGET_MSM7627A:
mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "864x480");
break;
case TARGET_MSM8660:
mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1920x1088");
break;
default:
mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "640x480");
break;
}
if (setParameters(mParameters) != NO_ERROR) {
ALOGE("Failed to set default parameters?!");
}
/* Initialize the camframe_timeout_flag*/
Mutex::Autolock l(&mCamframeTimeoutLock);
camframe_timeout_flag = FALSE;
mPostviewHeap = NULL;
mDisplayHeap = NULL;
mLastPreviewFrameHeap = NULL;
mThumbnailHeap = NULL;
mInitialized = true;
strTexturesOn = false;
ALOGV("initDefaultParameters X");
}
#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
bool QualcommCameraHardware::startCamera()
{
ALOGV("startCamera E");
if( mCurrentTarget == TARGET_MAX ) {
ALOGE(" Unable to determine the target type. Camera will not work ");
return false;
}
#if DLOPEN_LIBMMCAMERA
ALOGV("loading liboemcamera at %p", libmmcamera);
if (!libmmcamera) {
ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
return false;
}
*(void **)&LINK_cam_frame =
::dlsym(libmmcamera, "cam_frame");
*(void **)&LINK_wait_cam_frame_thread_ready =
::dlsym(libmmcamera, "wait_cam_frame_thread_ready");
*(void **)&LINK_cam_frame_set_exit_flag =
::dlsym(libmmcamera, "cam_frame_set_exit_flag");
*(void **)&LINK_camframe_terminate =
::dlsym(libmmcamera, "camframe_terminate");
*(void **)&LINK_jpeg_encoder_init =
::dlsym(libmmcamera, "jpeg_encoder_init");
*(void **)&LINK_jpeg_encoder_encode =
::dlsym(libmmcamera, "jpeg_encoder_encode");
*(void **)&LINK_jpeg_encoder_join =
::dlsym(libmmcamera, "jpeg_encoder_join");
mCamNotify.preview_frame_cb = &receive_camframe_callback;
mCamNotify.camstats_cb = &receive_camstats_callback;
mCamNotify.on_event = &receive_event_callback;
mCamNotify.on_error_event = &receive_camframe_error_callback;
// 720 p new recording functions
mCamNotify.video_frame_cb = &receive_camframe_video_callback;
// 720 p new recording functions
*(void **)&LINK_camframe_add_frame = ::dlsym(libmmcamera, "camframe_add_frame");
*(void **)&LINK_camframe_release_all_frames = ::dlsym(libmmcamera, "camframe_release_all_frames");
*(void **)&LINK_mmcamera_shutter_callback =
::dlsym(libmmcamera, "mmcamera_shutter_callback");
*LINK_mmcamera_shutter_callback = receive_shutter_callback;
*(void**)&LINK_jpeg_encoder_setMainImageQuality =
::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
*(void**)&LINK_jpeg_encoder_setThumbnailQuality =
::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
*(void**)&LINK_jpeg_encoder_setRotation =
::dlsym(libmmcamera, "jpeg_encoder_setRotation");
*(void**)&LINK_jpeg_encoder_get_buffer_offset =
::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset");
*(void**)&LINK_jpeg_encoder_set_3D_info =
::dlsym(libmmcamera, "jpeg_encoder_set_3D_info");
/* Disabling until support is available.
*(void**)&LINK_jpeg_encoder_setLocation =
::dlsym(libmmcamera, "jpeg_encoder_setLocation");
*/
*(void **)&LINK_cam_conf =
::dlsym(libmmcamera, "cam_conf");
/* Disabling until support is available.
*(void **)&LINK_default_sensor_get_snapshot_sizes =
::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
*/
*(void **)&LINK_launch_cam_conf_thread =
::dlsym(libmmcamera, "launch_cam_conf_thread");
*(void **)&LINK_release_cam_conf_thread =
::dlsym(libmmcamera, "release_cam_conf_thread");
mCamNotify.on_liveshot_event = &receive_liveshot_callback;
*(void **)&LINK_cancel_liveshot =
::dlsym(libmmcamera, "cancel_liveshot");
*(void **)&LINK_set_liveshot_params =
::dlsym(libmmcamera, "set_liveshot_params");
*(void **)&LINK_set_liveshot_frame =
::dlsym(libmmcamera, "set_liveshot_frame");
*(void **)&LINK_mm_camera_destroy =
::dlsym(libmmcamera, "mm_camera_destroy");
*(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12_inplace =
::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12");
*(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12 =
::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12_ver2");
/* Disabling until support is available.*/
*(void **)&LINK_zoom_crop_upscale =
::dlsym(libmmcamera, "zoom_crop_upscale");
#else
mCamNotify.preview_frame_cb = &receive_camframe_callback;
mCamNotify.camstats_cb = &receive_camstats_callback;
mCamNotify.on_event = &receive_event_callback;
mmcamera_shutter_callback = receive_shutter_callback;
mCamNotify.on_liveshot_event = &receive_liveshot_callback;
mCamNotify.video_frame_cb = &receive_camframe_video_callback;
#endif // DLOPEN_LIBMMCAMERA
#if 0 //commenting this for now as not getting graphics permission
if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){
fb_fd = open("/dev/graphics/fb0", O_RDWR);
if (fb_fd < 0) {
ALOGE("startCamera: fb0 open failed: %s!", strerror(errno));
return FALSE;
}
}
#endif
int ret_val;
if (pthread_join(mDeviceOpenThread, (void**)&ret_val) != 0) {
ALOGE("openCamera thread exit failed");
return false;
}
if (!mCameraOpen) {
ALOGE("openCamera() failed");
return false;
}
mCfgControl.mm_camera_query_parms(CAMERA_PARM_PICT_SIZE, (void **)&picture_sizes, &PICTURE_SIZE_COUNT);
if ((picture_sizes == NULL) || (!PICTURE_SIZE_COUNT)) {
ALOGE("startCamera X: could not get snapshot sizes");
return false;
}
ALOGI("startCamera picture_sizes %p PICTURE_SIZE_COUNT %d", picture_sizes, PICTURE_SIZE_COUNT);
mCfgControl.mm_camera_query_parms(CAMERA_PARM_PREVIEW_SIZE, (void **)&preview_sizes, &PREVIEW_SIZE_COUNT);
if ((preview_sizes == NULL) || (!PREVIEW_SIZE_COUNT)) {
ALOGE("startCamera X: could not get preview sizes");
return false;
}
ALOGI("startCamera preview_sizes %p previewSizeCount %d", preview_sizes, PREVIEW_SIZE_COUNT);
mCfgControl.mm_camera_query_parms(CAMERA_PARM_HFR_SIZE, (void **)&hfr_sizes, &HFR_SIZE_COUNT);
if ((hfr_sizes == NULL) || (!HFR_SIZE_COUNT)) {
ALOGE("startCamera X: could not get hfr sizes");
return false;
}
ALOGI("startCamera hfr_sizes %p hfrSizeCount %d", hfr_sizes, HFR_SIZE_COUNT);
ALOGV("startCamera X");
return true;
}
status_t QualcommCameraHardware::dump(int fd,
const Vector<String16>& args) const
{
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
#if 0
// Dump internal primitives.
result.append("QualcommCameraHardware::dump");
snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
result.append(buffer);
int width, height;
mParameters.getPreviewSize(&width, &height);
snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
result.append(buffer);
mParameters.getPictureSize(&width, &height);
snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
result.append(buffer);
snprintf(buffer, 255,
"preview frame size(%d), raw size (%d), jpeg size (%d) "
"and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
mJpegSize, mJpegMaxSize);
result.append(buffer);
write(fd, result.string(), result.size());
// Dump internal objects.
if (mPreviewHeap[0] != 0) {
mPreviewHeap[0]->dump(fd, args);
}
if (mRawHeap != 0) {
mRawHeap->dump(fd, args);
}
if (mJpegHeap != 0) {
mJpegHeap->dump(fd, args);
}
mParameters.dump(fd, args);
#endif
return NO_ERROR;
}
/* Issue ioctl calls related to starting Camera Operations*/
bool static native_start_ops(mm_camera_ops_type_t type, void* value)
{
if(mCamOps.mm_camera_start(type, value,NULL) != MM_CAMERA_SUCCESS) {
ALOGE("native_start_ops: type %d error %s",
type,strerror(errno));
return false;
}
return true;
}
/* Issue ioctl calls related to stopping Camera Operations*/
bool static native_stop_ops(mm_camera_ops_type_t type, void* value)
{
if(mCamOps.mm_camera_stop(type, value,NULL) != MM_CAMERA_SUCCESS) {
ALOGE("native_stop_ops: type %d error %s",
type,strerror(errno));
return false;
}
return true;
}
/*==========================================================================*/
#define GPS_PROCESSING_METHOD_SIZE 101
#define FOCAL_LENGTH_DECIMAL_PRECISON 100
static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
#define EXIF_ASCII_PREFIX_SIZE (sizeof(ExifAsciiPrefix))
static rat_t latitude[3];
static rat_t longitude[3];
static char lonref[2];
static char latref[2];
static rat_t altitude;
static rat_t gpsTimestamp[3];
static char gpsDatestamp[20];
static char dateTime[20];
static rat_t focalLength;
static uint16_t flashMode;
static int iso_arr[] = {0,1,100,200,400,800,1600};
static uint16_t isoMode;
static char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
uint32_t count, uint8_t copy, void *data) {
if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
ALOGE("Number of entries exceeded limit");
return;
}
int index = exif_table_numEntries;
exif_data[index].tag_id = tagid;
exif_data[index].tag_entry.type = type;
exif_data[index].tag_entry.count = count;
exif_data[index].tag_entry.copy = copy;
if((type == EXIF_RATIONAL) && (count > 1))
exif_data[index].tag_entry.data._rats = (rat_t *)data;
if((type == EXIF_RATIONAL) && (count == 1))
exif_data[index].tag_entry.data._rat = *(rat_t *)data;
else if(type == EXIF_ASCII)
exif_data[index].tag_entry.data._ascii = (char *)data;
else if(type == EXIF_BYTE)
exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
else if((type == EXIF_SHORT) && (count > 1))
exif_data[index].tag_entry.data._shorts = (uint16_t *)data;
else if((type == EXIF_SHORT) && (count == 1))
exif_data[index].tag_entry.data._short = *(uint16_t *)data;
// Increase number of entries
exif_table_numEntries++;
}
static void parseLatLong(const char *latlonString, int *pDegrees,
int *pMinutes, int *pSeconds ) {
double value = atof(latlonString);
value = fabs(value);
int degrees = (int) value;
double remainder = value - degrees;
int minutes = (int) (remainder * 60);
int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
*pDegrees = degrees;
*pMinutes = minutes;
*pSeconds = seconds;
}
static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
int degrees, minutes, seconds;
parseLatLong(latlonString, &degrees, &minutes, &seconds);
rat_t value[3] = { {degrees, 1},
{minutes, 1},
{seconds, 1000} };
if(tag == EXIFTAGID_GPS_LATITUDE) {
memcpy(latitude, value, sizeof(latitude));
addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
1, (void *)latitude);
} else {
memcpy(longitude, value, sizeof(longitude));
addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
1, (void *)longitude);
}
}
void QualcommCameraHardware::setGpsParameters() {
const char *str = NULL;
str = mParameters.get(QCameraParameters::KEY_GPS_PROCESSING_METHOD);
if(str!=NULL ){
memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str,
GPS_PROCESSING_METHOD_SIZE - 1);
gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0';
addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII,
EXIF_ASCII_PREFIX_SIZE + strlen(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1,
1, (void *)gpsProcessingMethod);
}
str = NULL;
//Set Latitude
str = mParameters.get(QCameraParameters::KEY_GPS_LATITUDE);
if(str != NULL) {
setLatLon(EXIFTAGID_GPS_LATITUDE, str);
//set Latitude Ref
float latitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LATITUDE);
latref[0] = 'N';
if(latitudeValue < 0 ){
latref[0] = 'S';
}
latref[1] = '\0';
mParameters.set(QCameraParameters::KEY_GPS_LATITUDE_REF, latref);
addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
1, (void *)latref);
}
//set Longitude
str = NULL;
str = mParameters.get(QCameraParameters::KEY_GPS_LONGITUDE);
if(str != NULL) {
setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
//set Longitude Ref
float longitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LONGITUDE);
lonref[0] = 'E';
if(longitudeValue < 0){
lonref[0] = 'W';
}
lonref[1] = '\0';
mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE_REF, lonref);
addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
1, (void *)lonref);
}
//set Altitude
str = NULL;
str = mParameters.get(QCameraParameters::KEY_GPS_ALTITUDE);
if(str != NULL) {
double value = atof(str);
int ref = 0;
if(value < 0){
ref = 1;
value = -value;
}
uint32_t value_meter = value * 1000;
rat_t alt_value = {value_meter, 1000};
memcpy(&altitude, &alt_value, sizeof(altitude));
addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
1, (void *)&altitude);
//set AltitudeRef
mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE_REF, ref);
addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
1, (void *)&ref);
}
//set Gps TimeStamp
str = NULL;
str = mParameters.get(QCameraParameters::KEY_GPS_TIMESTAMP);
if(str != NULL) {
long value = atol(str);
time_t unixTime;
struct tm *UTCTimestamp;
unixTime = (time_t)value;
UTCTimestamp = gmtime(&unixTime);
strftime(gpsDatestamp, sizeof(gpsDatestamp), "%Y:%m:%d", UTCTimestamp);
addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII,
strlen(gpsDatestamp)+1 , 1, (void *)&gpsDatestamp);
rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1},
{UTCTimestamp->tm_min, 1},
{UTCTimestamp->tm_sec, 1} };
memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp));
addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
3, 1, (void *)&gpsTimestamp);
}
}
bool QualcommCameraHardware::initZslParameter(void)
{ ALOGV("%s: E", __FUNCTION__);
mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
ALOGI("initZslParamter E: picture size=%dx%d", mPictureWidth, mPictureHeight);
if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) {
mDimension.picture_width = mPictureWidth;
mDimension.picture_height = mPictureHeight;
}
/* use the default thumbnail sizes */
mZslParms.picture_width = mPictureWidth;
mZslParms.picture_height = mPictureHeight;
mZslParms.preview_width = mDimension.display_width;
mZslParms.preview_height = mDimension.display_height;
mZslParms.useExternalBuffers = TRUE;
/* fill main image size, thumbnail size, postview size into capture_params_t*/
memset(&mZslCaptureParms, 0, sizeof(zsl_capture_params_t));
mZslCaptureParms.thumbnail_height = mPostviewHeight;
mZslCaptureParms.thumbnail_width = mPostviewWidth;
ALOGI("Number of snapshot to capture: %d",numCapture);
mZslCaptureParms.num_captures = numCapture;
return true;
}
bool QualcommCameraHardware::initImageEncodeParameters(int size)
{
ALOGV("%s: E", __FUNCTION__);
memset(&mImageEncodeParms, 0, sizeof(encode_params_t));
int jpeg_quality = mParameters.getInt("jpeg-quality");