Home | History | Annotate | Download | only in camera
      1 
      2 /*
      3 ** Copyright 2008, Google Inc.
      4 ** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
      5 **
      6 ** Licensed under the Apache License, Version 2.0 (the "License");
      7 ** you may not use this file except in compliance with the License.
      8 ** You may obtain a copy of the License at
      9 **
     10 **     http://www.apache.org/licenses/LICENSE-2.0
     11 **
     12 ** Unless required by applicable law or agreed to in writing, software
     13 ** distributed under the License is distributed on an "AS IS" BASIS,
     14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 ** See the License for the specific language governing permissions and
     16 ** limitations under the License.
     17 */
     18 
     19 #define ALOG_NDEBUG 0
     20 #define ALOG_NIDEBUG 0
     21 #define LOG_TAG "QualcommCameraHardware"
     22 #include <utils/Log.h>
     23 #include "QualcommCameraHardware.h"
     24 
     25 #include <utils/Errors.h>
     26 #include <utils/threads.h>
     27 
     28 #include <binder/MemoryHeapPmem.h>
     29 #if 0
     30 #include <binder/MemoryHeapIon.h>
     31 #endif
     32 #include <camera/Camera.h>
     33 #include <hardware/camera.h>
     34 #include <utils/String16.h>
     35 #include <sys/types.h>
     36 #include <sys/stat.h>
     37 #include <unistd.h>
     38 #include <fcntl.h>
     39 #include <cutils/properties.h>
     40 #include <math.h>
     41 #if HAVE_ANDROID_OS
     42 #include <linux/android_pmem.h>
     43 #endif
     44 #include <linux/ioctl.h>
     45 #include "QCameraParameters.h"
     46 #include <media/mediarecorder.h>
     47 #include <gralloc_priv.h>
     48 #include <genlock.h>
     49 
     50 #include "linux/msm_mdp.h"
     51 #include <linux/fb.h>
     52 #define LIKELY(exp)   __builtin_expect(!!(exp), 1)
     53 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
     54 #define CAMERA_HAL_UNUSED(expr) do { (void)(expr); } while (0)
     55 
     56 extern "C" {
     57 #include <fcntl.h>
     58 #include <time.h>
     59 #include <pthread.h>
     60 #include <stdio.h>
     61 #include <string.h>
     62 #include <unistd.h>
     63 #include <termios.h>
     64 #include <assert.h>
     65 #include <stdlib.h>
     66 #include <ctype.h>
     67 #include <signal.h>
     68 #include <errno.h>
     69 #include <sys/mman.h>
     70 #include <sys/system_properties.h>
     71 #include <sys/time.h>
     72 #include <stdlib.h>
     73 
     74 
     75 #include <camera.h>
     76 #include <cam_fifo.h>
     77 #include <liveshot.h>
     78 #include <jpege.h>
     79 #include <jpeg_encoder.h>
     80 
     81 #define DUMP_LIVESHOT_JPEG_FILE 0
     82 
     83 #define DEFAULT_PICTURE_WIDTH  640
     84 #define DEFAULT_PICTURE_HEIGHT 480
     85 #define DEFAULT_PICTURE_WIDTH_3D 1920
     86 #define DEFAULT_PICTURE_HEIGHT_3D 1080
     87 #define INITIAL_PREVIEW_HEIGHT 144
     88 #define INITIAL_PREVIEW_WIDTH 176
     89 
     90 #define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
     91 #define MAX_ZOOM_LEVEL 5
     92 #define NOT_FOUND -1
     93 // Number of video buffers held by kernal (initially 1,2 &3)
     94 #define ACTIVE_VIDEO_BUFFERS 3
     95 #define ACTIVE_PREVIEW_BUFFERS 3
     96 #define ACTIVE_ZSL_BUFFERS 3
     97 #define APP_ORIENTATION 90
     98 #define HDR_HAL_FRAME 2
     99 
    100 #define FLASH_AUTO 24
    101 #define FLASH_SNAP 32
    102 
    103 #define DUMMY_CAMERA_STARTED 1;
    104 #define DUMMY_CAMERA_STOPPED 0;
    105 #define FLOOR16(X) ((X) & 0xFFF0)
    106 #if DLOPEN_LIBMMCAMERA
    107 #include <dlfcn.h>
    108 
    109 
    110 // Conversion routines from YV420sp to YV12 format
    111 int (*LINK_yuv_convert_ycrcb420sp_to_yv12_inplace) (yuv_image_type* yuvStructPtr);
    112 int (*LINK_yuv_convert_ycrcb420sp_to_yv12) (yuv_image_type* yuvStructPtrin, yuv_image_type* yuvStructPtrout);
    113 #define NUM_YV12_FRAMES 1
    114 #define FOCUS_AREA_INIT "(-1000,-1000,1000,1000,1000)"
    115 
    116 void *libmmcamera;
    117 void* (*LINK_cam_conf)(void *data);
    118 void* (*LINK_cam_frame)(void *data);
    119 void* (*LINK_wait_cam_frame_thread_ready)(void);
    120 void* (*LINK_cam_frame_set_exit_flag)(int flag);
    121 bool  (*LINK_jpeg_encoder_init)();
    122 void  (*LINK_jpeg_encoder_join)();
    123 bool  (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
    124                 const uint8_t *thumbnailbuf, int thumbnailfd,
    125                 const uint8_t *snapshotbuf, int snapshotfd,
    126                 common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
    127                 int exif_table_numEntries, int jpegPadding, const int32_t cbcroffset,int zsl_enable);
    128 void (*LINK_camframe_terminate)(void);
    129 //for 720p
    130 // Function pointer , called by camframe when a video frame is available.
    131 void (**LINK_camframe_video_callback)(struct msm_frame * frame);
    132 // Function to add a frame to free Q
    133 void (*LINK_camframe_add_frame)(cam_frame_type_t type,struct msm_frame *frame);
    134 
    135 void (*LINK_camframe_release_all_frames)(cam_frame_type_t type);
    136 
    137 int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
    138 int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
    139 int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
    140 int8_t (*LINK_jpeg_encoder_get_buffer_offset)(uint32_t width, uint32_t height,
    141                                                uint32_t* p_y_offset,
    142                                                 uint32_t* p_cbcr_offset,
    143                                                  uint32_t* p_buf_size);
    144 int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
    145 void (*LINK_jpeg_encoder_set_3D_info)(cam_3d_frame_format_t format);
    146 const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
    147 int (*LINK_launch_cam_conf_thread)(void);
    148 int (*LINK_release_cam_conf_thread)(void);
    149 mm_camera_status_t (*LINK_mm_camera_init)(mm_camera_config *, mm_camera_notify*, mm_camera_ops*,uint8_t);
    150 mm_camera_status_t (*LINK_mm_camera_deinit)();
    151 mm_camera_status_t (*LINK_mm_camera_destroy)();
    152 mm_camera_status_t (*LINK_mm_camera_exec)();
    153 mm_camera_status_t (*LINK_mm_camera_get_camera_info) (qcamera_info_t* p_cam_info, int* p_num_cameras);
    154 
    155 int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
    156     uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
    157 
    158 // callbacks
    159 void  (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
    160 void  (**LINK_cancel_liveshot)(void);
    161 int8_t  (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data,
    162                          int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size);
    163 void (*LINK_set_liveshot_frame)(struct msm_frame *liveshot_frame);
    164 #else
    165 #define LINK_cam_conf cam_conf
    166 #define LINK_cam_frame cam_frame
    167 #define LINK_wait_cam_frame_thread_ready wait_cam_frame_thread_ready
    168 #define LINK_cam_frame cam_frame_set_exit_flag
    169 #define LINK_jpeg_encoder_init jpeg_encoder_init
    170 #define LINK_jpeg_encoder_join jpeg_encoder_join
    171 #define LINK_jpeg_encoder_encode jpeg_encoder_encode
    172 #define LINK_camframe_terminate camframe_terminate
    173 #define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
    174 #define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
    175 #define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
    176 #define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset
    177 #define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
    178 #define LINK_jpeg_encoder_set_3D_info jpeg_encoder_set_3D_info
    179 #define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
    180 #define LINK_launch_cam_conf_thread launch_cam_conf_thread
    181 #define LINK_release_cam_conf_thread release_cam_conf_thread
    182 #define LINK_zoom_crop_upscale zoom_crop_upscale
    183 #define LINK_mm_camera_init mm_camera_config_init
    184 #define LINK_mm_camera_deinit mm_camera_config_deinit
    185 #define LINK_mm_camera_destroy mm_camera_config_destroy
    186 #define LINK_mm_camera_exec mm_camera_exec
    187 #define LINK_camframe_add_frame camframe_add_frame
    188 #define LINK_camframe_release_all_frames camframe_release_all_frames
    189 #define LINK_mm_camera_get_camera_info mm_camera_get_camera_info
    190 
    191 extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
    192 extern void (*mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
    193 extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
    194                                       uint32_t buff_size);
    195 extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
    196 extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
    197 extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
    198 #define LINK_set_liveshot_params set_liveshot_params
    199 #define LINK_set_liveshot_frame set_liveshot_frame
    200 #endif
    201 
    202 } // extern "C"
    203 
    204 #ifndef HAVE_CAMERA_SIZE_TYPE
    205 struct camera_size_type {
    206     int width;
    207     int height;
    208 };
    209 #endif
    210 #if 0
    211 typedef struct crop_info_struct {
    212     int32_t x;
    213     int32_t y;
    214     int32_t w;
    215     int32_t h;
    216 } zoom_crop_info;
    217 #endif
    218 union zoomimage
    219 {
    220     char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
    221     struct mdp_blit_req_list list;
    222 } zoomImage;
    223 
    224 //Default to VGA
    225 #define DEFAULT_PREVIEW_WIDTH 640
    226 #define DEFAULT_PREVIEW_HEIGHT 480
    227 #define DEFAULT_PREVIEW_WIDTH_3D 1280
    228 #define DEFAULT_PREVIEW_HEIGHT_3D 720
    229 
    230 //Default FPS
    231 #define MINIMUM_FPS 5
    232 #define MAXIMUM_FPS 31
    233 #define DEFAULT_FPS MAXIMUM_FPS
    234 #define DEFAULT_FIXED_FPS_VALUE 30
    235 /*
    236  * Modifying preview size requires modification
    237  * in bitmasks for boardproperties
    238  */
    239 static uint32_t  PREVIEW_SIZE_COUNT;
    240 static uint32_t  HFR_SIZE_COUNT;
    241 
    242 board_property boardProperties[] = {
    243         {TARGET_MSM7625, 0x00000fff, false, false, false},
    244         {TARGET_MSM7625A, 0x00000fff, false, false, false},
    245         {TARGET_MSM7627, 0x000006ff, false, false, false},
    246         {TARGET_MSM7627A, 0x000006ff, false, false, false},
    247         {TARGET_MSM7630, 0x00000fff, true, true, false},
    248         {TARGET_MSM8660, 0x00001fff, true, true, false},
    249         {TARGET_QSD8250, 0x00000fff, false, false, false}
    250 };
    251 
    252 //static const camera_size_type* picture_sizes;
    253 //static int PICTURE_SIZE_COUNT;
    254 /*       TODO
    255  * Ideally this should be a populated by lower layers.
    256  * But currently this is no API to do that at lower layer.
    257  * Hence populating with default sizes for now. This needs
    258  * to be changed once the API is supported.
    259  */
    260 //sorted on column basis
    261 static struct camera_size_type zsl_picture_sizes[] = {
    262   { 1024, 768}, // 1MP XGA
    263   { 800, 600}, //SVGA
    264   { 800, 480}, // WVGA
    265   { 640, 480}, // VGA
    266   { 352, 288}, //CIF
    267   { 320, 240}, // QVGA
    268   { 176, 144} // QCIF
    269 };
    270 
    271 static struct camera_size_type for_3D_picture_sizes[] = {
    272   { 1920, 1080},
    273 };
    274 
    275 static int data_counter = 0;
    276 static int sensor_rotation = 0;
    277 static int record_flag = 0;
    278 static camera_size_type* picture_sizes;
    279 static camera_size_type* preview_sizes;
    280 static camera_size_type* hfr_sizes;
    281 static unsigned int PICTURE_SIZE_COUNT;
    282 static const camera_size_type * picture_sizes_ptr;
    283 static int supportedPictureSizesCount;
    284 static liveshotState liveshot_state = LIVESHOT_DONE;
    285 
    286 #ifdef Q12
    287 #undef Q12
    288 #endif
    289 
    290 #define Q12 4096
    291 
    292 static const target_map targetList [] = {
    293     { "msm7625", TARGET_MSM7625 },
    294     { "msm7625a", TARGET_MSM7625A },
    295     { "msm7627", TARGET_MSM7627 },
    296     { "msm7627a", TARGET_MSM7627A },
    297     { "qsd8250", TARGET_QSD8250 },
    298     { "msm7630", TARGET_MSM7630 },
    299     { "msm8660", TARGET_MSM8660 }
    300 
    301 };
    302 static targetType mCurrentTarget = TARGET_MAX;
    303 
    304 typedef struct {
    305     uint32_t aspect_ratio;
    306     uint32_t width;
    307     uint32_t height;
    308 } thumbnail_size_type;
    309 
    310 static thumbnail_size_type thumbnail_sizes[] = {
    311     { 7281, 512, 288 }, //1.777778
    312     { 6826, 480, 288 }, //1.666667
    313     { 6808, 256, 154 }, //1.662337
    314     { 6144, 432, 288 }, //1.5
    315     { 5461, 512, 384 }, //1.333333
    316     { 5006, 352, 288 }, //1.222222
    317 };
    318 #define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
    319 #define DEFAULT_THUMBNAIL_SETTING 4
    320 #define THUMBNAIL_WIDTH_STR "512"
    321 #define THUMBNAIL_HEIGHT_STR "384"
    322 #define THUMBNAIL_SMALL_HEIGHT 144
    323 static camera_size_type jpeg_thumbnail_sizes[]  = {
    324     { 512, 288 },
    325     { 480, 288 },
    326     { 432, 288 },
    327     { 512, 384 },
    328     { 352, 288 },
    329     {0,0}
    330 };
    331 //supported preview fps ranges should be added to this array in the form (minFps,maxFps)
    332 static  android::FPSRange FpsRangesSupported[] = {{MINIMUM_FPS*1000,MAXIMUM_FPS*1000}};
    333 
    334 #define FPS_RANGES_SUPPORTED_COUNT (sizeof(FpsRangesSupported)/sizeof(FpsRangesSupported[0]))
    335 
    336 #define JPEG_THUMBNAIL_SIZE_COUNT (sizeof(jpeg_thumbnail_sizes)/sizeof(camera_size_type))
    337 static int attr_lookup(const str_map arr[], int len, const char *name)
    338 {
    339     if (name) {
    340         for (int i = 0; i < len; i++) {
    341             if (!strcmp(arr[i].desc, name))
    342                 return arr[i].val;
    343         }
    344     }
    345     return NOT_FOUND;
    346 }
    347 
    348 // round to the next power of two
    349 static inline unsigned clp2(unsigned x)
    350 {
    351     x = x - 1;
    352     x = x | (x >> 1);
    353     x = x | (x >> 2);
    354     x = x | (x >> 4);
    355     x = x | (x >> 8);
    356     x = x | (x >>16);
    357     return x + 1;
    358 }
    359 
    360 static int exif_table_numEntries = 0;
    361 #define MAX_EXIF_TABLE_ENTRIES 14
    362 exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
    363 //static zoom_crop_info zoomCropInfo;
    364 static android_native_rect_t zoomCropInfo;
    365 static void *mLastQueuedFrame = NULL;
    366 #define RECORD_BUFFERS 9
    367 #define RECORD_BUFFERS_8x50 8
    368 static int kRecordBufferCount;
    369 /* controls whether VPE is avialable for the target
    370  * under consideration.
    371  * 1: VPE support is available
    372  * 0: VPE support is not available (default)
    373  */
    374 static bool mVpeEnabled;
    375 static cam_frame_start_parms camframeParams;
    376 
    377 static int HAL_numOfCameras;
    378 static qcamera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS];
    379 static int HAL_currentCameraId;
    380 static int HAL_currentCameraMode;
    381 static mm_camera_config mCfgControl;
    382 static bool mCameraOpen;
    383 
    384 static int HAL_currentSnapshotMode;
    385 static int previewWidthToNativeZoom;
    386 static int previewHeightToNativeZoom;
    387 #define CAMERA_SNAPSHOT_NONZSL 0x04
    388 #define CAMERA_SNAPSHOT_ZSL 0x08
    389 
    390 namespace android {
    391 	extern void native_send_data_callback(int32_t msgType,
    392                               camera_memory_t * framebuffer,
    393 	                              void* user);
    394 
    395 	extern camera_memory_t* get_mem(int fd,size_t buf_size,
    396 	                                unsigned int num_bufs,
    397 	                                void *user);
    398 
    399 static const int PICTURE_FORMAT_JPEG = 1;
    400 static const int PICTURE_FORMAT_RAW = 2;
    401 
    402 // from aeecamera.h
    403 static const str_map whitebalance[] = {
    404     { QCameraParameters::WHITE_BALANCE_AUTO,            CAMERA_WB_AUTO },
    405     { QCameraParameters::WHITE_BALANCE_INCANDESCENT,    CAMERA_WB_INCANDESCENT },
    406     { QCameraParameters::WHITE_BALANCE_FLUORESCENT,     CAMERA_WB_FLUORESCENT },
    407     { QCameraParameters::WHITE_BALANCE_DAYLIGHT,        CAMERA_WB_DAYLIGHT },
    408     { QCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
    409 };
    410 
    411 // from camera_effect_t. This list must match aeecamera.h
    412 static const str_map effects[] = {
    413     { QCameraParameters::EFFECT_NONE,       CAMERA_EFFECT_OFF },
    414     { QCameraParameters::EFFECT_MONO,       CAMERA_EFFECT_MONO },
    415     { QCameraParameters::EFFECT_NEGATIVE,   CAMERA_EFFECT_NEGATIVE },
    416     { QCameraParameters::EFFECT_SOLARIZE,   CAMERA_EFFECT_SOLARIZE },
    417     { QCameraParameters::EFFECT_SEPIA,      CAMERA_EFFECT_SEPIA },
    418     { QCameraParameters::EFFECT_POSTERIZE,  CAMERA_EFFECT_POSTERIZE },
    419     { QCameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
    420     { QCameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
    421     { QCameraParameters::EFFECT_AQUA,       CAMERA_EFFECT_AQUA }
    422 };
    423 
    424 // from qcamera/common/camera.h
    425 static const str_map autoexposure[] = {
    426     { QCameraParameters::AUTO_EXPOSURE_FRAME_AVG,  CAMERA_AEC_FRAME_AVERAGE },
    427     { QCameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
    428     { QCameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
    429 };
    430 
    431 // from qcamera/common/camera.h
    432 static const str_map antibanding[] = {
    433     { QCameraParameters::ANTIBANDING_OFF,  CAMERA_ANTIBANDING_OFF },
    434     { QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
    435     { QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
    436     { QCameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
    437 };
    438 
    439 static const str_map antibanding_3D[] = {
    440     { QCameraParameters::ANTIBANDING_OFF,  CAMERA_ANTIBANDING_OFF },
    441     { QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
    442     { QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ }
    443 };
    444 
    445 /* Mapping from MCC to antibanding type */
    446 struct country_map {
    447     uint32_t country_code;
    448     camera_antibanding_type type;
    449 };
    450 
    451 #if 0 //not using this function. keeping this as this came from Google.
    452 static struct country_map country_numeric[] = {
    453     { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
    454     { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
    455     { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
    456     { 208, CAMERA_ANTIBANDING_50HZ }, // France
    457     { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
    458     { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
    459     { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
    460     { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
    461     { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
    462     { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
    463     { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
    464     { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
    465     { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
    466     { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
    467     { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
    468     { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
    469     { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
    470     { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
    471     { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
    472     { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
    473     { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
    474     { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
    475     { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
    476     { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
    477     { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
    478     { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
    479     { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
    480     { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
    481     { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
    482     { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
    483     { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
    484     { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
    485     { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
    486     { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
    487     { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
    488     { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
    489     { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
    490     { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
    491     { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
    492     { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
    493     { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
    494     { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
    495     { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
    496     { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
    497     { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
    498     { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
    499     { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
    500     { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
    501     { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
    502     { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
    503     { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
    504     { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
    505     { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
    506     { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
    507     { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
    508     { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
    509     { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
    510     { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
    511     { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
    512     { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
    513     { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
    514     { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
    515     { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
    516     { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
    517     { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
    518     { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
    519     { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
    520     { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
    521     { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
    522     { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
    523     { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
    524     { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
    525     { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
    526     { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
    527     { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
    528     { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
    529     { 404, CAMERA_ANTIBANDING_50HZ }, // India
    530     { 405, CAMERA_ANTIBANDING_50HZ }, // India
    531     { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
    532     { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
    533     { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
    534     { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
    535     { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
    536     { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
    537     { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
    538     { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
    539     { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
    540     { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
    541     { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
    542     { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
    543     { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
    544     { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
    545     { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
    546     { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
    547     { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
    548     { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
    549     { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
    550     { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
    551     { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
    552     { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
    553     { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
    554     { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
    555     { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
    556     { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
    557     { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
    558     { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
    559     { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
    560     { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
    561     { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
    562     { 460, CAMERA_ANTIBANDING_50HZ }, // China
    563     { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
    564     { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
    565     { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
    566     { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
    567     { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
    568     { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
    569     { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
    570     { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
    571     { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
    572     { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
    573     { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
    574     { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
    575     { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
    576     { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
    577     { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
    578     { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
    579     { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
    580     { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
    581     { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
    582     { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
    583     { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
    584     { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
    585     { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
    586     { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
    587     { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
    588     { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
    589     { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
    590     { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
    591     { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
    592     { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
    593     { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
    594     { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
    595     { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
    596     { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
    597     { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
    598     { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
    599     { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
    600     { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
    601     { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
    602     { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
    603     { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
    604     { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
    605     { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
    606     { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
    607     { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
    608     { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
    609     { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
    610     { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
    611     { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
    612     { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
    613     { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
    614     { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
    615     { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
    616     { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
    617     { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
    618     { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
    619     { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
    620     { 647, CAMERA_ANTIBANDING_50HZ }, // France
    621     { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
    622     { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
    623     { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
    624     { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
    625     { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
    626     { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
    627     { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
    628     { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
    629     { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
    630     { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
    631     { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
    632     { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
    633     { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
    634     { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
    635     { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
    636     { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
    637     { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
    638     { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
    639     { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
    640     { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
    641     { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
    642     { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
    643     { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
    644     { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
    645     { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
    646     { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
    647     { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
    648     { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
    649     { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
    650 };
    651 #define country_number (sizeof(country_numeric) / sizeof(country_map))
    652 /* Look up pre-sorted antibanding_type table by current MCC. */
    653 static camera_antibanding_type camera_get_location(void) {
    654     char value[PROP_VALUE_MAX];
    655     char country_value[PROP_VALUE_MAX];
    656     uint32_t country_code;
    657     memset(value, 0x00, sizeof(value));
    658     memset(country_value, 0x00, sizeof(country_value));
    659     if (!__system_property_get("gsm.operator.numeric", value)) {
    660         return CAMERA_ANTIBANDING_60HZ;
    661     }
    662     memcpy(country_value, value, 3);
    663     country_code = atoi(country_value);
    664     ALOGD("value:%s, country value:%s, country code:%d\n",
    665             value, country_value, country_code);
    666     int left = 0;
    667     int right = country_number - 1;
    668     while (left <= right) {
    669         int index = (left + right) >> 1;
    670         if (country_numeric[index].country_code == country_code)
    671             return country_numeric[index].type;
    672         else if (country_numeric[index].country_code > country_code)
    673             right = index - 1;
    674         else
    675             left = index + 1;
    676     }
    677     return CAMERA_ANTIBANDING_60HZ;
    678 }
    679 #endif
    680 
    681 static const str_map scenemode[] = {
    682     { QCameraParameters::SCENE_MODE_AUTO,           CAMERA_BESTSHOT_OFF },
    683     { QCameraParameters::SCENE_MODE_ASD,           CAMERA_BESTSHOT_AUTO },
    684     { QCameraParameters::SCENE_MODE_ACTION,         CAMERA_BESTSHOT_ACTION },
    685     { QCameraParameters::SCENE_MODE_PORTRAIT,       CAMERA_BESTSHOT_PORTRAIT },
    686     { QCameraParameters::SCENE_MODE_LANDSCAPE,      CAMERA_BESTSHOT_LANDSCAPE },
    687     { QCameraParameters::SCENE_MODE_NIGHT,          CAMERA_BESTSHOT_NIGHT },
    688     { QCameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
    689     { QCameraParameters::SCENE_MODE_THEATRE,        CAMERA_BESTSHOT_THEATRE },
    690     { QCameraParameters::SCENE_MODE_BEACH,          CAMERA_BESTSHOT_BEACH },
    691     { QCameraParameters::SCENE_MODE_SNOW,           CAMERA_BESTSHOT_SNOW },
    692     { QCameraParameters::SCENE_MODE_SUNSET,         CAMERA_BESTSHOT_SUNSET },
    693     { QCameraParameters::SCENE_MODE_STEADYPHOTO,    CAMERA_BESTSHOT_ANTISHAKE },
    694     { QCameraParameters::SCENE_MODE_FIREWORKS ,     CAMERA_BESTSHOT_FIREWORKS },
    695     { QCameraParameters::SCENE_MODE_SPORTS ,        CAMERA_BESTSHOT_SPORTS },
    696     { QCameraParameters::SCENE_MODE_PARTY,          CAMERA_BESTSHOT_PARTY },
    697     { QCameraParameters::SCENE_MODE_CANDLELIGHT,    CAMERA_BESTSHOT_CANDLELIGHT },
    698     { QCameraParameters::SCENE_MODE_BACKLIGHT,      CAMERA_BESTSHOT_BACKLIGHT },
    699     { QCameraParameters::SCENE_MODE_FLOWERS,        CAMERA_BESTSHOT_FLOWERS },
    700     { QCameraParameters::SCENE_MODE_AR,             CAMERA_BESTSHOT_AR },
    701 };
    702 
    703 static const str_map scenedetect[] = {
    704     { QCameraParameters::SCENE_DETECT_OFF, FALSE  },
    705     { QCameraParameters::SCENE_DETECT_ON, TRUE },
    706 };
    707 
    708 // from camera.h, led_mode_t
    709 static const str_map flash[] = {
    710     { QCameraParameters::FLASH_MODE_OFF,  LED_MODE_OFF },
    711     { QCameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
    712     { QCameraParameters::FLASH_MODE_ON, LED_MODE_ON },
    713     { QCameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
    714 };
    715 
    716 // from mm-camera/common/camera.h.
    717 static const str_map iso[] = {
    718     { QCameraParameters::ISO_AUTO,  CAMERA_ISO_AUTO},
    719     { QCameraParameters::ISO_HJR,   CAMERA_ISO_DEBLUR},
    720     { QCameraParameters::ISO_100,   CAMERA_ISO_100},
    721     { QCameraParameters::ISO_200,   CAMERA_ISO_200},
    722     { QCameraParameters::ISO_400,   CAMERA_ISO_400},
    723     { QCameraParameters::ISO_800,   CAMERA_ISO_800 },
    724     { QCameraParameters::ISO_1600,  CAMERA_ISO_1600 }
    725 };
    726 
    727 static const str_map iso_3D[] = {
    728     { QCameraParameters::ISO_AUTO,  CAMERA_ISO_AUTO},
    729     { QCameraParameters::ISO_100,   CAMERA_ISO_100},
    730     { QCameraParameters::ISO_200,   CAMERA_ISO_200},
    731     { QCameraParameters::ISO_400,   CAMERA_ISO_400},
    732     { QCameraParameters::ISO_800,   CAMERA_ISO_800 },
    733     { QCameraParameters::ISO_1600,  CAMERA_ISO_1600 }
    734 };
    735 
    736 
    737 #define DONT_CARE AF_MODE_MAX
    738 static const str_map focus_modes[] = {
    739     { QCameraParameters::FOCUS_MODE_AUTO,     AF_MODE_AUTO},
    740     { QCameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
    741     { QCameraParameters::FOCUS_MODE_NORMAL,   AF_MODE_NORMAL },
    742     { QCameraParameters::FOCUS_MODE_MACRO,    AF_MODE_MACRO },
    743     { QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, AF_MODE_CAF },
    744     { QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, DONT_CARE }
    745 };
    746 
    747 static const str_map lensshade[] = {
    748     { QCameraParameters::LENSSHADE_ENABLE, TRUE },
    749     { QCameraParameters::LENSSHADE_DISABLE, FALSE }
    750 };
    751 
    752 static const str_map hfr[] = {
    753     { QCameraParameters::VIDEO_HFR_OFF, CAMERA_HFR_MODE_OFF },
    754     { QCameraParameters::VIDEO_HFR_2X, CAMERA_HFR_MODE_60FPS },
    755     { QCameraParameters::VIDEO_HFR_3X, CAMERA_HFR_MODE_90FPS },
    756     { QCameraParameters::VIDEO_HFR_4X, CAMERA_HFR_MODE_120FPS },
    757 };
    758 
    759 static const str_map mce[] = {
    760     { QCameraParameters::MCE_ENABLE, TRUE },
    761     { QCameraParameters::MCE_DISABLE, FALSE }
    762 };
    763 
    764 static const str_map hdr[] = {
    765     { QCameraParameters::HDR_ENABLE, TRUE },
    766     { QCameraParameters::HDR_DISABLE, FALSE }
    767 };
    768 
    769 static const str_map histogram[] = {
    770     { QCameraParameters::HISTOGRAM_ENABLE, TRUE },
    771     { QCameraParameters::HISTOGRAM_DISABLE, FALSE }
    772 };
    773 
    774 static const str_map skinToneEnhancement[] = {
    775     { QCameraParameters::SKIN_TONE_ENHANCEMENT_ENABLE, TRUE },
    776     { QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE, FALSE }
    777 };
    778 
    779 static const str_map denoise[] = {
    780     { QCameraParameters::DENOISE_OFF, FALSE },
    781     { QCameraParameters::DENOISE_ON, TRUE }
    782 };
    783 
    784 static const str_map selectable_zone_af[] = {
    785     { QCameraParameters::SELECTABLE_ZONE_AF_AUTO,  AUTO },
    786     { QCameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT },
    787     { QCameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED },
    788     { QCameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE }
    789 };
    790 
    791 static const str_map facedetection[] = {
    792     { QCameraParameters::FACE_DETECTION_OFF, FALSE },
    793     { QCameraParameters::FACE_DETECTION_ON, TRUE }
    794 };
    795 
    796 #define DONT_CARE_COORDINATE -1
    797 static const str_map touchafaec[] = {
    798     { QCameraParameters::TOUCH_AF_AEC_OFF, FALSE },
    799     { QCameraParameters::TOUCH_AF_AEC_ON, TRUE }
    800 };
    801 
    802 static const str_map redeye_reduction[] = {
    803     { QCameraParameters::REDEYE_REDUCTION_ENABLE, TRUE },
    804     { QCameraParameters::REDEYE_REDUCTION_DISABLE, FALSE }
    805 };
    806 
    807 static const str_map zsl_modes[] = {
    808     { QCameraParameters::ZSL_OFF, FALSE  },
    809     { QCameraParameters::ZSL_ON, TRUE },
    810 };
    811 
    812 /*
    813  * Values based on aec.c
    814  */
    815 #define DONT_CARE_COORDINATE -1
    816 #define CAMERA_HISTOGRAM_ENABLE 1
    817 #define CAMERA_HISTOGRAM_DISABLE 0
    818 #define HISTOGRAM_STATS_SIZE 257
    819 
    820 /*
    821  * Values based on aec.c
    822  */
    823 #define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
    824 #define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
    825 #define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
    826 #define EXPOSURE_COMPENSATION_DENOMINATOR 6
    827 #define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
    828 
    829 static const str_map picture_formats[] = {
    830         {QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
    831         {QCameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
    832 };
    833 
    834 static const str_map recording_Hints[] = {
    835         {"false", FALSE},
    836         {"true",  TRUE}
    837 };
    838 
    839 static const str_map picture_formats_zsl[] = {
    840         {QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG}
    841 };
    842 
    843 static const str_map frame_rate_modes[] = {
    844         {QCameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
    845         {QCameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
    846 };
    847 
    848 static int mPreviewFormat;
    849 static const str_map preview_formats[] = {
    850         {QCameraParameters::PIXEL_FORMAT_YUV420SP,   CAMERA_YUV_420_NV21},
    851         {QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO},
    852         {QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12}
    853 };
    854 static const str_map preview_formats1[] = {
    855         {QCameraParameters::PIXEL_FORMAT_YUV420SP,   CAMERA_YUV_420_NV21},
    856         {QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12}
    857 };
    858 
    859 static const str_map app_preview_formats[] = {
    860 {QCameraParameters::PIXEL_FORMAT_YUV420SP,   HAL_PIXEL_FORMAT_YCrCb_420_SP}, //nv21
    861 //{QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO}, //nv21_adreno
    862 {QCameraParameters::PIXEL_FORMAT_YUV420P, HAL_PIXEL_FORMAT_YV12}, //YV12
    863 };
    864 
    865 
    866 static bool parameter_string_initialized = false;
    867 static String8 preview_size_values;
    868 static String8 hfr_size_values;
    869 static String8 picture_size_values;
    870 static String8 fps_ranges_supported_values;
    871 static String8 jpeg_thumbnail_size_values;
    872 static String8 antibanding_values;
    873 static String8 effect_values;
    874 static String8 autoexposure_values;
    875 static String8 whitebalance_values;
    876 static String8 flash_values;
    877 static String8 focus_mode_values;
    878 static String8 iso_values;
    879 static String8 lensshade_values;
    880 static String8 mce_values;
    881 static String8 hdr_values;
    882 static String8 histogram_values;
    883 static String8 skinToneEnhancement_values;
    884 static String8 touchafaec_values;
    885 static String8 picture_format_values;
    886 static String8 scenemode_values;
    887 static String8 denoise_values;
    888 static String8 zoom_ratio_values;
    889 static String8 preview_frame_rate_values;
    890 static String8 frame_rate_mode_values;
    891 static String8 scenedetect_values;
    892 static String8 preview_format_values;
    893 static String8 selectable_zone_af_values;
    894 static String8 facedetection_values;
    895 static String8 hfr_values;
    896 static String8 redeye_reduction_values;
    897 static String8 zsl_values;
    898 
    899 mm_camera_notify mCamNotify;
    900 mm_camera_ops mCamOps;
    901 static mm_camera_buffer_t mEncodeOutputBuffer[MAX_SNAPSHOT_BUFFERS];
    902 static encode_params_t mImageEncodeParms;
    903 static capture_params_t mImageCaptureParms;
    904 static raw_capture_params_t mRawCaptureParms;
    905 static zsl_capture_params_t mZslCaptureParms;
    906 static zsl_params_t mZslParms;
    907 static yv12_format_parms_t myv12_params;
    908 
    909 static String8 create_sizes_str(const camera_size_type *sizes, int len) {
    910     String8 str;
    911     char buffer[32];
    912 
    913     if (len > 0) {
    914         sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
    915         str.append(buffer);
    916     }
    917     for (int i = 1; i < len; i++) {
    918         sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
    919         str.append(buffer);
    920     }
    921     return str;
    922 }
    923 
    924 static String8 create_fps_str(const android:: FPSRange* fps, int len) {
    925     String8 str;
    926     char buffer[32];
    927 
    928     if (len > 0) {
    929         sprintf(buffer, "(%d,%d)", fps[0].minFPS, fps[0].maxFPS);
    930         str.append(buffer);
    931     }
    932     for (int i = 1; i < len; i++) {
    933         sprintf(buffer, ",(%d,%d)", fps[i].minFPS, fps[i].maxFPS);
    934         str.append(buffer);
    935     }
    936     return str;
    937 }
    938 
    939 static String8 create_values_str(const str_map *values, int len) {
    940     String8 str;
    941 
    942     if (len > 0) {
    943         str.append(values[0].desc);
    944     }
    945     for (int i = 1; i < len; i++) {
    946         str.append(",");
    947         str.append(values[i].desc);
    948     }
    949     return str;
    950 }
    951 
    952 
    953 static String8 create_str(int16_t *arr, int length){
    954     String8 str;
    955     char buffer[32];
    956 
    957     if(length > 0){
    958         snprintf(buffer, sizeof(buffer), "%d", arr[0]);
    959         str.append(buffer);
    960     }
    961 
    962     for (int i =1;i<length;i++){
    963         snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
    964         str.append(buffer);
    965     }
    966     return str;
    967 }
    968 
    969 static String8 create_values_range_str(int min, int max){
    970     String8 str;
    971     char buffer[32];
    972 
    973     if(min <= max){
    974         snprintf(buffer, sizeof(buffer), "%d", min);
    975         str.append(buffer);
    976 
    977         for (int i = min + 1; i <= max; i++) {
    978             snprintf(buffer, sizeof(buffer), ",%d", i);
    979             str.append(buffer);
    980         }
    981     }
    982     return str;
    983 }
    984 
    985 extern "C" {
    986 //------------------------------------------------------------------------
    987 //   : 720p busyQ funcitons
    988 //   --------------------------------------------------------------------
    989 static struct fifo_queue g_busy_frame_queue =
    990     {0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, (char *)"video_busy_q"};
    991 };
    992 
    993 static void cam_frame_wait_video (void)
    994 {
    995     ALOGV("cam_frame_wait_video E ");
    996     if ((g_busy_frame_queue.num_of_frames) <=0){
    997         pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut));
    998     }
    999     ALOGV("cam_frame_wait_video X");
   1000     return;
   1001 }
   1002 
   1003 void cam_frame_flush_video (void)
   1004 {
   1005     ALOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames);
   1006     pthread_mutex_lock(&(g_busy_frame_queue.mut));
   1007 
   1008     while (g_busy_frame_queue.front)
   1009     {
   1010        //dequeue from the busy queue
   1011        struct fifo_node *node  = dequeue (&g_busy_frame_queue);
   1012        if(node)
   1013            free(node);
   1014 
   1015        ALOGV("cam_frame_flush_video: node \n");
   1016     }
   1017     pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   1018     ALOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames);
   1019     return ;
   1020 }
   1021 
   1022 static struct msm_frame * cam_frame_get_video()
   1023 {
   1024     struct msm_frame *p = NULL;
   1025     ALOGV("cam_frame_get_video... in\n");
   1026     ALOGV("cam_frame_get_video... got lock\n");
   1027     if (g_busy_frame_queue.front)
   1028     {
   1029         //dequeue
   1030        struct fifo_node *node  = dequeue (&g_busy_frame_queue);
   1031        if (node)
   1032        {
   1033            p = (struct msm_frame *)node->f;
   1034            free (node);
   1035        }
   1036        ALOGV("cam_frame_get_video... out = %x\n", p->buffer);
   1037     }
   1038     return p;
   1039 }
   1040 
   1041 // Parse string like "(1, 2, 3, 4, ..., N)"
   1042 // num is pointer to an allocated array of size N
   1043 static int parseNDimVector_HAL(const char *str, int *num, int N, char delim = ',')
   1044 {
   1045     char *start, *end;
   1046     if(num == NULL) {
   1047         ALOGE("Invalid output array (num == NULL)");
   1048         return -1;
   1049     }
   1050     //check if string starts and ends with parantheses
   1051     if(str[0] != '(' || str[strlen(str)-1] != ')') {
   1052         ALOGE("Invalid format of string %s, valid format is (n1, n2, n3, n4 ...)", str);
   1053         return -1;
   1054     }
   1055     start = (char*) str;
   1056     start++;
   1057     for(int i=0; i<N; i++) {
   1058         *(num+i) = (int) strtol(start, &end, 10);
   1059         if(*end != delim && i < N-1) {
   1060             ALOGE("Cannot find delimeter '%c' in string \"%s\". end = %c", delim, str, *end);
   1061             return -1;
   1062         }
   1063         start = end+1;
   1064     }
   1065     return 0;
   1066 }
   1067 static int countChar(const char *str , char ch )
   1068 {
   1069     int noOfChar = 0;
   1070 
   1071     for ( int i = 0; str[i] != '\0'; i++) {
   1072         if ( str[i] == ch )
   1073           noOfChar = noOfChar + 1;
   1074     }
   1075 
   1076     return noOfChar;
   1077 }
   1078 int checkAreaParameters(const char *str)
   1079 {
   1080     int areaValues[6];
   1081     int left, right, top, bottom, weight;
   1082 
   1083     if(countChar(str, ',') > 4) {
   1084         ALOGE("%s: No of area parameters exceeding the expected number %s", __FUNCTION__, str);
   1085         return -1;
   1086     }
   1087 
   1088     if(parseNDimVector_HAL(str, areaValues, 5) !=0) {
   1089         ALOGE("%s: Failed to parse the input string %s", __FUNCTION__, str);
   1090         return -1;
   1091     }
   1092 
   1093     ALOGV("%s: Area values are %d,%d,%d,%d,%d", __FUNCTION__,
   1094           areaValues[0], areaValues[1], areaValues[2], areaValues[3], areaValues[4]);
   1095 
   1096     left = areaValues[0];
   1097     top = areaValues[1];
   1098     right = areaValues[2];
   1099     bottom = areaValues[3];
   1100     weight = areaValues[4];
   1101 
   1102     // left should >= -1000
   1103     if (!(left >= -1000))
   1104         return -1;
   1105     // top should >= -1000
   1106     if(!(top >= -1000))
   1107         return -1;
   1108     // right should <= 1000
   1109     if(!(right <= 1000))
   1110         return -1;
   1111     // bottom should <= 1000
   1112     if(!(bottom <= 1000))
   1113         return -1;
   1114     // weight should >= 1
   1115     // weight should <= 1000
   1116     if(!((1 <= weight) && (weight <= 1000)))
   1117         return -1;
   1118     // left should < right
   1119     if(!(left < right))
   1120         return -1;
   1121     // top should < bottom
   1122     if(!(top < bottom))
   1123         return -1;
   1124 
   1125     return 0;
   1126 }
   1127 
   1128 static void cam_frame_post_video (struct msm_frame *p)
   1129 {
   1130     if (!p)
   1131     {
   1132         ALOGE("post video , buffer is null");
   1133         return;
   1134     }
   1135     ALOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer));
   1136     pthread_mutex_lock(&(g_busy_frame_queue.mut));
   1137     ALOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames);
   1138     //enqueue to busy queue
   1139     struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node));
   1140     if (node)
   1141     {
   1142         ALOGV(" post video , enqueing in busy queue");
   1143         node->f = p;
   1144         node->next = NULL;
   1145         enqueue (&g_busy_frame_queue, node);
   1146         ALOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames);
   1147     }
   1148     else
   1149     {
   1150         ALOGE("cam_frame_post_video error... out of memory\n");
   1151     }
   1152 
   1153     pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   1154     pthread_cond_signal(&(g_busy_frame_queue.wait));
   1155 
   1156     ALOGV("cam_frame_post_video... out = %x\n", p->buffer);
   1157 
   1158     return;
   1159 }
   1160 
   1161 QualcommCameraHardware::FrameQueue::FrameQueue(){
   1162     mInitialized = false;
   1163 }
   1164 
   1165 QualcommCameraHardware::FrameQueue::~FrameQueue(){
   1166     flush();
   1167 }
   1168 
   1169 void QualcommCameraHardware::FrameQueue::init(){
   1170     Mutex::Autolock l(&mQueueLock);
   1171     mInitialized = true;
   1172     mQueueWait.signal();
   1173 }
   1174 
   1175 void QualcommCameraHardware::FrameQueue::deinit(){
   1176     Mutex::Autolock l(&mQueueLock);
   1177     mInitialized = false;
   1178     mQueueWait.signal();
   1179 }
   1180 
   1181 bool QualcommCameraHardware::FrameQueue::isInitialized(){
   1182    Mutex::Autolock l(&mQueueLock);
   1183    return mInitialized;
   1184 }
   1185 
   1186 bool QualcommCameraHardware::FrameQueue::add(
   1187                 struct msm_frame * element){
   1188     Mutex::Autolock l(&mQueueLock);
   1189     if(mInitialized == false)
   1190         return false;
   1191 
   1192     mContainer.add(element);
   1193     mQueueWait.signal();
   1194     return true;
   1195 }
   1196 
   1197 struct msm_frame * QualcommCameraHardware::FrameQueue::get(){
   1198 
   1199     struct msm_frame *frame;
   1200     mQueueLock.lock();
   1201     while(mInitialized && mContainer.isEmpty()){
   1202         mQueueWait.wait(mQueueLock);
   1203     }
   1204 
   1205     if(!mInitialized){
   1206         mQueueLock.unlock();
   1207         return NULL;
   1208     }
   1209 
   1210     frame = mContainer.itemAt(0);
   1211     mContainer.removeAt(0);
   1212     mQueueLock.unlock();
   1213     return frame;
   1214 }
   1215 
   1216 void QualcommCameraHardware::FrameQueue::flush(){
   1217     Mutex::Autolock l(&mQueueLock);
   1218     mContainer.clear();
   1219 
   1220 }
   1221 
   1222 
   1223 void QualcommCameraHardware::storeTargetType(void) {
   1224     char mDeviceName[PROPERTY_VALUE_MAX];
   1225     property_get("ro.product.device",mDeviceName," ");
   1226     mCurrentTarget = TARGET_MAX;
   1227     for( int i = 0; i < TARGET_MAX ; i++) {
   1228        if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) {
   1229          mCurrentTarget = targetList[i].targetEnum;
   1230          if(mCurrentTarget == TARGET_MSM7625) {
   1231            if(!strncmp(mDeviceName, "msm7625a" , 8))
   1232              mCurrentTarget = TARGET_MSM7625A;
   1233             }
   1234            if(mCurrentTarget == TARGET_MSM7627) {
   1235              if(!strncmp(mDeviceName, "msm7627a" , 8))
   1236                mCurrentTarget = TARGET_MSM7627A;
   1237            }
   1238            break;
   1239        }
   1240     }
   1241     ALOGV(" Storing the current target type as %d ", mCurrentTarget );
   1242     return;
   1243 }
   1244 
   1245 void *openCamera(void *data) {
   1246     ALOGV(" openCamera : E");
   1247     mCameraOpen = false;
   1248 
   1249     if (!libmmcamera) {
   1250         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   1251         return false;
   1252     }
   1253 
   1254     *(void **)&LINK_mm_camera_init =
   1255         ::dlsym(libmmcamera, "mm_camera_init");
   1256 
   1257     *(void **)&LINK_mm_camera_exec =
   1258         ::dlsym(libmmcamera, "mm_camera_exec");
   1259 
   1260     *(void **)&LINK_mm_camera_deinit =
   1261         ::dlsym(libmmcamera, "mm_camera_deinit");
   1262 
   1263 
   1264     if (MM_CAMERA_SUCCESS != LINK_mm_camera_init(&mCfgControl, &mCamNotify, &mCamOps, 0)) {
   1265         ALOGE("startCamera: mm_camera_init failed:");
   1266         return false;
   1267         //pthread_exit((void*) ret_val);
   1268     }
   1269 
   1270     uint8_t camera_id8 = (uint8_t)HAL_currentCameraId;
   1271     if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_CAMERA_ID, &camera_id8)) {
   1272         ALOGE("setting camera id failed");
   1273         LINK_mm_camera_deinit();
   1274         return false;
   1275         //pthread_exit((void*) ret_val);
   1276     }
   1277 
   1278     //camera_mode_t mode = (camera_mode_t)HAL_currentCameraMode;
   1279     camera_mode_t mode = CAMERA_MODE_2D;
   1280     if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_MODE, &mode)) {
   1281         ALOGE("startCamera: CAMERA_PARM_MODE failed:");
   1282         LINK_mm_camera_deinit();
   1283         return false;
   1284         //pthread_exit((void*) ret_val);
   1285     }
   1286 
   1287     if (MM_CAMERA_SUCCESS != LINK_mm_camera_exec()) {
   1288         ALOGE("startCamera: mm_camera_exec failed:");
   1289         return false;
   1290         //pthread_exit((void*) ret_val);
   1291     }
   1292     mCameraOpen = true;
   1293     ALOGV(" openCamera : X");
   1294     if (CAMERA_MODE_3D == mode) {
   1295         camera_3d_frame_t snapshotFrame;
   1296         snapshotFrame.frame_type = CAM_SNAPSHOT_FRAME;
   1297         if(MM_CAMERA_SUCCESS !=
   1298             mCfgControl.mm_camera_get_parm(CAMERA_PARM_3D_FRAME_FORMAT,
   1299                 (void *)&snapshotFrame)){
   1300             ALOGE("%s: get 3D format failed", __func__);
   1301             LINK_mm_camera_deinit();
   1302             return false;
   1303             //pthread_exit((void*) ret_val);
   1304         }
   1305         QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   1306         if (obj != 0) {
   1307             obj->mSnapshot3DFormat = snapshotFrame.format;
   1308             ALOGI("%s: 3d format  snapshot %d", __func__, obj->mSnapshot3DFormat);
   1309         }
   1310     }
   1311 
   1312     ALOGV("openCamera : X");
   1313 //    pthread_exit((void*) ret_val);
   1314 
   1315     return NULL;
   1316 }
   1317 //-------------------------------------------------------------------------------------
   1318 static Mutex singleton_lock;
   1319 static bool singleton_releasing;
   1320 static nsecs_t singleton_releasing_start_time;
   1321 static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5);
   1322 static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1);
   1323 static Condition singleton_wait;
   1324 
   1325 static void receive_camframe_callback(struct msm_frame *frame);
   1326 static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size);
   1327 static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo);
   1328 static void receive_camframe_video_callback(struct msm_frame *frame); // 720p
   1329 static int8_t receive_event_callback(mm_camera_event* event);
   1330 static void receive_shutter_callback(common_crop_t *crop);
   1331 static void receive_camframe_error_callback(camera_error_type err);
   1332 static int fb_fd = -1;
   1333 static int32_t mMaxZoom = 0;
   1334 static bool zoomSupported = false;
   1335 static int dstOffset = 0;
   1336 
   1337 static int16_t * zoomRatios;
   1338 
   1339 
   1340 /* When using MDP zoom, double the preview buffers. The usage of these
   1341  * buffers is as follows:
   1342  * 1. As all the buffers comes under a single FD, and at initial registration,
   1343  * this FD will be passed to surface flinger, surface flinger can have access
   1344  * to all the buffers when needed.
   1345  * 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the
   1346  * camera driver to receive preview frames. The remaining buffers (DstSet),
   1347  * will be used at HAL and by surface flinger only when crop information
   1348  * is present in the frame.
   1349  * 3. When there is no crop information, there will be no call to MDP zoom,
   1350  * and the buffers in SrcSet will be passed to surface flinger to display.
   1351  * 4. With crop information present, MDP zoom will be called, and the final
   1352  * data will be placed in a buffer from DstSet, and this buffer will be given
   1353  * to surface flinger to display.
   1354  */
   1355 #define NUM_MORE_BUFS 2
   1356 
   1357 QualcommCameraHardware::QualcommCameraHardware()
   1358     : mParameters(),
   1359       mCameraRunning(false),
   1360       mPreviewInitialized(false),
   1361       mPreviewThreadRunning(false),
   1362       mHFRThreadRunning(false),
   1363       mFrameThreadRunning(false),
   1364       mVideoThreadRunning(false),
   1365       mSnapshotThreadRunning(false),
   1366       mJpegThreadRunning(false),
   1367       mSmoothzoomThreadRunning(false),
   1368       mSmoothzoomThreadExit(false),
   1369       mInSnapshotMode(false),
   1370       mEncodePending(false),
   1371       mBuffersInitialized(false),
   1372       mSnapshotFormat(0),
   1373       mFirstFrame(true),
   1374       mReleasedRecordingFrame(false),
   1375       mPreviewFrameSize(0),
   1376       mRawSize(0),
   1377       mCbCrOffsetRaw(0),
   1378       mYOffset(0),
   1379       mAutoFocusThreadRunning(false),
   1380       mInitialized(false),
   1381       mBrightness(0),
   1382       mSkinToneEnhancement(0),
   1383       mHJR(0),
   1384       mInPreviewCallback(false),
   1385       //mUseOverlay(0),
   1386       mIs3DModeOn(0),
   1387       //mOverlay(0),
   1388       mMsgEnabled(0),
   1389       mNotifyCallback(0),
   1390       mDataCallback(0),
   1391       mDataCallbackTimestamp(0),
   1392       mCallbackCookie(0),
   1393       mDebugFps(0),
   1394       mSnapshotDone(0),
   1395       maxSnapshotWidth(0),
   1396       maxSnapshotHeight(0),
   1397       mHasAutoFocusSupport(0),
   1398       mDisEnabled(0),
   1399       mRotation(0),
   1400       mResetWindowCrop(false),
   1401       mThumbnailWidth(0),
   1402       mThumbnailHeight(0),
   1403       strTexturesOn(false),
   1404       mPictureWidth(0),
   1405       mPictureHeight(0),
   1406       mPostviewWidth(0),
   1407       mPostviewHeight(0),
   1408       mPreviewWindow(NULL),
   1409       mTotalPreviewBufferCount(0),
   1410       mZslFlashEnable(false),
   1411       mZslPanorama(false),
   1412       mSnapshotCancel(false),
   1413       mHFRMode(false),
   1414       mActualPictWidth(0),
   1415       mActualPictHeight(0),
   1416       mDenoiseValue(0),
   1417       mPreviewStopping(false),
   1418       mInHFRThread(false),
   1419       mPrevHeapDeallocRunning(false),
   1420       mHdrMode(false ),
   1421       mExpBracketMode(false),
   1422       mZslEnable(false),
   1423       mStoreMetaDataInFrame(0),
   1424       mRecordingState(0)
   1425 {
   1426     ALOGI("QualcommCameraHardware constructor E");
   1427     mMMCameraDLRef = MMCameraDL::getInstance();
   1428     libmmcamera = mMMCameraDLRef->pointer();
   1429     char value[PROPERTY_VALUE_MAX];
   1430     mCameraOpen = false;
   1431     /*if(HAL_currentSnapshotMode == CAMERA_SNAPSHOT_ZSL) {
   1432         ALOGI("%s: this is ZSL mode", __FUNCTION__);
   1433         mZslEnable = true;
   1434     }*/
   1435 
   1436     property_get("persist.camera.hal.multitouchaf", value, "0");
   1437     mMultiTouch = atoi(value);
   1438 
   1439     storeTargetType();
   1440     for(int i=0; i< MAX_SNAPSHOT_BUFFERS; i++) {
   1441        mRawMapped[i] = NULL;
   1442        mJpegMapped[i] = NULL;
   1443        mThumbnailMapped[i] = NULL;
   1444     }
   1445     mRawSnapshotMapped = NULL;
   1446     mJpegCopyMapped = NULL;
   1447 	for(int i=0; i< RECORD_BUFFERS; i++) {
   1448         mRecordMapped[i] = NULL;
   1449     }
   1450 
   1451     for(int i=0; i<3; i++)
   1452         mStatsMapped[i] = NULL;
   1453 
   1454     mJpegLiveSnapMapped = NULL;
   1455     if(HAL_currentCameraMode == CAMERA_SUPPORT_MODE_3D){
   1456         mIs3DModeOn = true;
   1457     }
   1458     /* TODO: Will remove this command line interface at end */
   1459     property_get("persist.camera.hal.3dmode", value, "0");
   1460     int mode = atoi(value);
   1461     if( mode  == 1) {
   1462         mIs3DModeOn = true;
   1463         HAL_currentCameraMode = CAMERA_MODE_3D;
   1464     }
   1465 
   1466     if( (pthread_create(&mDeviceOpenThread, NULL, openCamera, NULL)) != 0) {
   1467         ALOGE(" openCamera thread creation failed ");
   1468     }
   1469     memset(&mDimension, 0, sizeof(mDimension));
   1470     memset(&mCrop, 0, sizeof(mCrop));
   1471     memset(&zoomCropInfo, 0, sizeof(android_native_rect_t));
   1472     //storeTargetType();
   1473     property_get("persist.debug.sf.showfps", value, "0");
   1474     mDebugFps = atoi(value);
   1475     if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) {
   1476         kPreviewBufferCountActual = kPreviewBufferCount;
   1477         kRecordBufferCount = RECORD_BUFFERS;
   1478         recordframes = new msm_frame[kRecordBufferCount];
   1479         record_buffers_tracking_flag = new bool[kRecordBufferCount];
   1480     }
   1481     else {
   1482         kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS;
   1483         if( mCurrentTarget == TARGET_QSD8250 ) {
   1484             kRecordBufferCount = RECORD_BUFFERS_8x50;
   1485             recordframes = new msm_frame[kRecordBufferCount];
   1486             record_buffers_tracking_flag = new bool[kRecordBufferCount];
   1487         }
   1488     }
   1489     mTotalPreviewBufferCount = kTotalPreviewBufferCount;
   1490     if((mCurrentTarget != TARGET_MSM7630 ) &&  (mCurrentTarget != TARGET_QSD8250)
   1491       && (mCurrentTarget != TARGET_MSM8660)) {
   1492         for (int i = 0; i < mTotalPreviewBufferCount; i++)
   1493           metadata_memory[i] = NULL;
   1494     }
   1495     else {
   1496         for (int i = 0; i < kRecordBufferCount; i++)
   1497           metadata_memory[i] = NULL;
   1498     }
   1499     switch(mCurrentTarget){
   1500         case TARGET_MSM7627:
   1501         case TARGET_MSM7627A:
   1502             jpegPadding = 0; // to be checked.
   1503             break;
   1504         case TARGET_QSD8250:
   1505         case TARGET_MSM7630:
   1506         case TARGET_MSM8660:
   1507             jpegPadding = 0;
   1508             break;
   1509         default:
   1510             jpegPadding = 0;
   1511             break;
   1512     }
   1513     // Initialize with default format values. The format values can be
   1514     // overriden when application requests.
   1515     mDimension.prev_format     = CAMERA_YUV_420_NV21;
   1516     mPreviewFormat             = CAMERA_YUV_420_NV21;
   1517     mDimension.enc_format      = CAMERA_YUV_420_NV21;
   1518     if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
   1519         mDimension.enc_format  = CAMERA_YUV_420_NV12;
   1520     mDimension.main_img_format = CAMERA_YUV_420_NV21;
   1521     mDimension.thumb_format    = CAMERA_YUV_420_NV21;
   1522 
   1523     if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){
   1524         /* DIS is disabled all the time in VPE support targets.
   1525          * No provision for the user to control this.
   1526          */
   1527         mDisEnabled = 0;
   1528         /* Get the DIS value from properties, to check whether
   1529          * DIS is disabled or not. If the property is not found
   1530          * default to DIS disabled.*/
   1531         property_get("persist.camera.hal.dis", value, "0");
   1532         mDisEnabled = atoi(value);
   1533         mVpeEnabled = 1;
   1534     }
   1535     if(mIs3DModeOn) {
   1536         mDisEnabled = 0;
   1537     }
   1538     ALOGV("constructor EX");
   1539 }
   1540 
   1541 void QualcommCameraHardware::hasAutoFocusSupport(){
   1542     if( !mCamOps.mm_camera_is_supported(CAMERA_OPS_FOCUS)){
   1543         ALOGI("AutoFocus is not supported");
   1544         mHasAutoFocusSupport = false;
   1545     }else {
   1546         mHasAutoFocusSupport = true;
   1547     }
   1548     if(mZslEnable)
   1549         mHasAutoFocusSupport = false;
   1550 }
   1551 
   1552 //filter Picture sizes based on max width and height
   1553 void QualcommCameraHardware::filterPictureSizes(){
   1554     unsigned int i;
   1555     if(PICTURE_SIZE_COUNT <= 0)
   1556         return;
   1557     maxSnapshotWidth = picture_sizes[0].width;
   1558     maxSnapshotHeight = picture_sizes[0].height;
   1559    // Iterate through all the width and height to find the max value
   1560     for(i =0; i<PICTURE_SIZE_COUNT;i++){
   1561         if(((maxSnapshotWidth < picture_sizes[i].width) &&
   1562             (maxSnapshotHeight <= picture_sizes[i].height))){
   1563             maxSnapshotWidth = picture_sizes[i].width;
   1564             maxSnapshotHeight = picture_sizes[i].height;
   1565         }
   1566     }
   1567     if(mZslEnable){
   1568         // due to lack of PMEM we restrict to lower resolution
   1569         picture_sizes_ptr = zsl_picture_sizes;
   1570         supportedPictureSizesCount = 7;
   1571     }
   1572     else if(mIs3DModeOn){
   1573      // In 3D mode we only want 1080p picture size
   1574       picture_sizes_ptr = for_3D_picture_sizes;
   1575       supportedPictureSizesCount = 1;
   1576     }
   1577     else{
   1578     picture_sizes_ptr = picture_sizes;
   1579     supportedPictureSizesCount = PICTURE_SIZE_COUNT;
   1580     }
   1581 }
   1582 
   1583 bool QualcommCameraHardware::supportsSceneDetection() {
   1584    unsigned int prop = 0;
   1585    for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
   1586        if((mCurrentTarget == boardProperties[prop].target)
   1587           && boardProperties[prop].hasSceneDetect == true) {
   1588            return true;
   1589            break;
   1590        }
   1591    }
   1592    return false;
   1593 }
   1594 
   1595 bool QualcommCameraHardware::supportsSelectableZoneAf() {
   1596    unsigned int prop = 0;
   1597    for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
   1598        if((mCurrentTarget == boardProperties[prop].target)
   1599           && boardProperties[prop].hasSelectableZoneAf == true) {
   1600            return true;
   1601            break;
   1602        }
   1603    }
   1604    return false;
   1605 }
   1606 
   1607 bool QualcommCameraHardware::supportsFaceDetection() {
   1608    unsigned int prop = 0;
   1609    for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
   1610        if((mCurrentTarget == boardProperties[prop].target)
   1611           && boardProperties[prop].hasFaceDetect == true) {
   1612            return true;
   1613            break;
   1614        }
   1615    }
   1616    return false;
   1617 }
   1618 
   1619 void QualcommCameraHardware::initDefaultParameters()
   1620 {
   1621     ALOGV("initDefaultParameters E");
   1622     mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
   1623     mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
   1624     mDimension.ui_thumbnail_width =
   1625             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
   1626     mDimension.ui_thumbnail_height =
   1627             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   1628     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   1629                sizeof(cam_ctrl_dimension_t),(void *) &mDimension);
   1630     if(ret != true) {
   1631         ALOGE("CAMERA_PARM_DIMENSION failed!!!");
   1632         return;
   1633     }
   1634     hasAutoFocusSupport();
   1635     //Disable DIS for Web Camera
   1636     if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_VIDEO_DIS)){
   1637         ALOGI("DISABLE DIS");
   1638         mDisEnabled = 0;
   1639     }else {
   1640         ALOGI("Enable DIS");
   1641     }
   1642     // Initialize constant parameter strings. This will happen only once in the
   1643     // lifetime of the mediaserver process.
   1644     if (!parameter_string_initialized) {
   1645         if(mIs3DModeOn){
   1646           antibanding_values = create_values_str(
   1647             antibanding_3D, sizeof(antibanding_3D) / sizeof(str_map));
   1648         } else{
   1649         antibanding_values = create_values_str(
   1650             antibanding, sizeof(antibanding) / sizeof(str_map));
   1651         }
   1652         effect_values = create_values_str(
   1653             effects, sizeof(effects) / sizeof(str_map));
   1654         autoexposure_values = create_values_str(
   1655             autoexposure, sizeof(autoexposure) / sizeof(str_map));
   1656         whitebalance_values = create_values_str(
   1657             whitebalance, sizeof(whitebalance) / sizeof(str_map));
   1658         //filter picture sizes
   1659         filterPictureSizes();
   1660         picture_size_values = create_sizes_str(
   1661                 picture_sizes_ptr, supportedPictureSizesCount);
   1662         preview_size_values = create_sizes_str(
   1663                 preview_sizes,  PREVIEW_SIZE_COUNT);
   1664         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
   1665                             preview_size_values.string());
   1666 
   1667         mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
   1668                             preview_size_values.string());
   1669 
   1670         mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
   1671                             picture_size_values.string());
   1672         mParameters.set(QCameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
   1673                             "true");
   1674         mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   1675                        QCameraParameters::FOCUS_MODE_INFINITY);
   1676         mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   1677                        QCameraParameters::FOCUS_MODE_INFINITY);
   1678         mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
   1679 
   1680         mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, FOCUS_AREA_INIT);
   1681         mParameters.set(QCameraParameters::KEY_METERING_AREAS, FOCUS_AREA_INIT);
   1682 
   1683         if(!mIs3DModeOn){
   1684         hfr_size_values = create_sizes_str(
   1685                 hfr_sizes, HFR_SIZE_COUNT);
   1686         }
   1687         fps_ranges_supported_values = create_fps_str(
   1688             FpsRangesSupported,FPS_RANGES_SUPPORTED_COUNT );
   1689         mParameters.set(
   1690             QCameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
   1691             fps_ranges_supported_values);
   1692         mParameters.setPreviewFpsRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000);
   1693 
   1694         flash_values = create_values_str(
   1695             flash, sizeof(flash) / sizeof(str_map));
   1696         if(mHasAutoFocusSupport){
   1697             focus_mode_values = create_values_str(
   1698                     focus_modes, sizeof(focus_modes) / sizeof(str_map));
   1699         }
   1700         if(mIs3DModeOn){
   1701           iso_values = create_values_str(
   1702               iso_3D,sizeof(iso_3D)/sizeof(str_map));
   1703         } else{
   1704            iso_values = create_values_str(
   1705               iso,sizeof(iso)/sizeof(str_map));
   1706         }
   1707         lensshade_values = create_values_str(
   1708             lensshade,sizeof(lensshade)/sizeof(str_map));
   1709         mce_values = create_values_str(
   1710             mce,sizeof(mce)/sizeof(str_map));
   1711         if(!mIs3DModeOn){
   1712           hfr_values = create_values_str(
   1713             hfr,sizeof(hfr)/sizeof(str_map));
   1714         }
   1715         if(mCurrentTarget == TARGET_MSM8660)
   1716             hdr_values = create_values_str(
   1717                 hdr,sizeof(hdr)/sizeof(str_map));
   1718         //Currently Enabling Histogram for 8x60
   1719         if(mCurrentTarget == TARGET_MSM8660) {
   1720             histogram_values = create_values_str(
   1721                 histogram,sizeof(histogram)/sizeof(str_map));
   1722         }
   1723         //Currently Enabling Skin Tone Enhancement for 8x60 and 7630
   1724         if((mCurrentTarget == TARGET_MSM8660)||(mCurrentTarget == TARGET_MSM7630)) {
   1725             skinToneEnhancement_values = create_values_str(
   1726                 skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map));
   1727         }
   1728         if(mHasAutoFocusSupport){
   1729             touchafaec_values = create_values_str(
   1730                 touchafaec,sizeof(touchafaec)/sizeof(str_map));
   1731         }
   1732         zsl_values = create_values_str(
   1733             zsl_modes,sizeof(zsl_modes)/sizeof(str_map));
   1734 
   1735         if(mZslEnable){
   1736            picture_format_values = create_values_str(
   1737                picture_formats_zsl, sizeof(picture_formats_zsl)/sizeof(str_map));
   1738         } else{
   1739            picture_format_values = create_values_str(
   1740                picture_formats, sizeof(picture_formats)/sizeof(str_map));
   1741         }
   1742         if(mCurrentTarget == TARGET_MSM8660 ||
   1743           (mCurrentTarget == TARGET_MSM7625A ||
   1744            mCurrentTarget == TARGET_MSM7627A)) {
   1745             denoise_values = create_values_str(
   1746                 denoise, sizeof(denoise) / sizeof(str_map));
   1747         }
   1748        if(mCfgControl.mm_camera_query_parms(CAMERA_PARM_ZOOM_RATIO,
   1749            (void **)&zoomRatios, (uint32_t *) &mMaxZoom) == MM_CAMERA_SUCCESS) {
   1750             zoomSupported = true;
   1751             if( mMaxZoom >0) {
   1752                 ALOGI("Maximum zoom value is %d", mMaxZoom);
   1753                 if(zoomRatios != NULL) {
   1754                     zoom_ratio_values =  create_str(zoomRatios, mMaxZoom);
   1755                 } else {
   1756                     ALOGE("Failed to get zoomratios ..");
   1757                 }
   1758            } else {
   1759                zoomSupported = false;
   1760            }
   1761        } else {
   1762             zoomSupported = false;
   1763             ALOGE("Failed to get maximum zoom value...setting max "
   1764                     "zoom to zero");
   1765             mMaxZoom = 0;
   1766         }
   1767         preview_frame_rate_values = create_values_range_str(
   1768             MINIMUM_FPS, MAXIMUM_FPS);
   1769 
   1770         scenemode_values = create_values_str(
   1771             scenemode, sizeof(scenemode) / sizeof(str_map));
   1772 
   1773         if(supportsSceneDetection()) {
   1774             scenedetect_values = create_values_str(
   1775                 scenedetect, sizeof(scenedetect) / sizeof(str_map));
   1776         }
   1777 
   1778         if(mHasAutoFocusSupport && supportsSelectableZoneAf()){
   1779             selectable_zone_af_values = create_values_str(
   1780                 selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
   1781         }
   1782 
   1783         if(mHasAutoFocusSupport && supportsFaceDetection()) {
   1784             facedetection_values = create_values_str(
   1785                 facedetection, sizeof(facedetection) / sizeof(str_map));
   1786         }
   1787 
   1788         redeye_reduction_values = create_values_str(
   1789             redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map));
   1790 
   1791         parameter_string_initialized = true;
   1792     }
   1793     //set video size
   1794     if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   1795        String8 vSize = create_sizes_str(preview_sizes, 1);
   1796        mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, vSize.string());
   1797     }
   1798     if(mIs3DModeOn){
   1799        ALOGI("In initDefaultParameters - 3D mode on so set the default preview to 1280 x 720");
   1800        mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH_3D, DEFAULT_PREVIEW_HEIGHT_3D);
   1801        mDimension.display_width = DEFAULT_PREVIEW_WIDTH_3D;
   1802        mDimension.display_height = DEFAULT_PREVIEW_HEIGHT_3D;
   1803     } else{
   1804        mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
   1805        mDimension.display_width = DEFAULT_PREVIEW_WIDTH;
   1806        mDimension.display_height = DEFAULT_PREVIEW_HEIGHT;
   1807     }
   1808     mParameters.setPreviewFrameRate(DEFAULT_FPS);
   1809     if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
   1810         mParameters.set(
   1811             QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
   1812             preview_frame_rate_values.string());
   1813      } else {
   1814         mParameters.setPreviewFrameRate(DEFAULT_FIXED_FPS_VALUE);
   1815         mParameters.set(
   1816             QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
   1817             DEFAULT_FIXED_FPS_VALUE);
   1818      }
   1819     mParameters.setPreviewFrameRateMode("frame-rate-auto");
   1820     mParameters.setPreviewFormat("yuv420sp"); // informative
   1821     mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
   1822     if(mIs3DModeOn){
   1823       mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH_3D, DEFAULT_PICTURE_HEIGHT_3D);
   1824     } else{
   1825       mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
   1826     }
   1827     mParameters.setPictureFormat("jpeg"); // informative
   1828 
   1829     mParameters.set(QCameraParameters::KEY_VIDEO_FRAME_FORMAT, "yuv420sp");
   1830 
   1831     mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
   1832 
   1833     mParameters.set("power-mode-supported", "false");
   1834 
   1835     mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
   1836                     THUMBNAIL_WIDTH_STR); // informative
   1837     mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
   1838                     THUMBNAIL_HEIGHT_STR); // informative
   1839     mDimension.ui_thumbnail_width =
   1840             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
   1841     mDimension.ui_thumbnail_height =
   1842             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   1843     mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
   1844 
   1845     String8 valuesStr = create_sizes_str(jpeg_thumbnail_sizes, JPEG_THUMBNAIL_SIZE_COUNT);
   1846     mParameters.set(QCameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
   1847                 valuesStr.string());
   1848 
   1849     // Define CAMERA_SMOOTH_ZOOM in Android.mk file , to enable smoothzoom
   1850 #ifdef CAMERA_SMOOTH_ZOOM
   1851     mParameters.set(QCameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, "true");
   1852 #endif
   1853 
   1854     if(zoomSupported){
   1855         mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "true");
   1856         ALOGI("max zoom is %d", mMaxZoom-1);
   1857         /* mMaxZoom value that the query interface returns is the size
   1858          * of zoom table. So the actual max zoom value will be one
   1859          * less than that value.
   1860          */
   1861         mParameters.set("max-zoom",mMaxZoom-1);
   1862         mParameters.set(QCameraParameters::KEY_ZOOM_RATIOS,
   1863                             zoom_ratio_values);
   1864     } else {
   1865         mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "false");
   1866     }
   1867     /* Enable zoom support for video application if VPE enabled */
   1868     if(zoomSupported && mVpeEnabled) {
   1869         mParameters.set("video-zoom-support", "true");
   1870     } else {
   1871         mParameters.set("video-zoom-support", "false");
   1872     }
   1873 
   1874     mParameters.set(QCameraParameters::KEY_CAMERA_MODE,0);
   1875 
   1876     mParameters.set(QCameraParameters::KEY_ANTIBANDING,
   1877                     QCameraParameters::ANTIBANDING_OFF);
   1878     mParameters.set(QCameraParameters::KEY_EFFECT,
   1879                     QCameraParameters::EFFECT_NONE);
   1880     mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE,
   1881                     QCameraParameters::AUTO_EXPOSURE_FRAME_AVG);
   1882     mParameters.set(QCameraParameters::KEY_WHITE_BALANCE,
   1883                     QCameraParameters::WHITE_BALANCE_AUTO);
   1884     if( (mCurrentTarget != TARGET_MSM7630)
   1885         && (mCurrentTarget != TARGET_QSD8250)
   1886         && (mCurrentTarget != TARGET_MSM8660)
   1887         && (mCurrentTarget != TARGET_MSM7627A)) {
   1888         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
   1889                     "yuv420sp");
   1890     } else if(mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) {
   1891         preview_format_values = create_values_str(
   1892             preview_formats1, sizeof(preview_formats1) / sizeof(str_map));
   1893         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
   1894                 preview_format_values.string());
   1895     } else {
   1896         preview_format_values = create_values_str(
   1897             preview_formats, sizeof(preview_formats) / sizeof(str_map));
   1898         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
   1899                 preview_format_values.string());
   1900     }
   1901 
   1902     frame_rate_mode_values = create_values_str(
   1903             frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
   1904  if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE)){
   1905         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
   1906                     frame_rate_mode_values.string());
   1907     }
   1908 
   1909     mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
   1910                     preview_size_values.string());
   1911     mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
   1912                     picture_size_values.string());
   1913     mParameters.set(QCameraParameters::KEY_SUPPORTED_ANTIBANDING,
   1914                     antibanding_values);
   1915     mParameters.set(QCameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
   1916     mParameters.set(QCameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
   1917     mParameters.set(QCameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
   1918                     whitebalance_values);
   1919 
   1920     if(mHasAutoFocusSupport){
   1921        mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   1922                     focus_mode_values);
   1923        mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   1924                     QCameraParameters::FOCUS_MODE_AUTO);
   1925     } else {
   1926        mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   1927                    QCameraParameters::FOCUS_MODE_INFINITY);
   1928        mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   1929                    QCameraParameters::FOCUS_MODE_INFINITY);
   1930     }
   1931 
   1932     mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
   1933                     picture_format_values);
   1934 
   1935     if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_LED_MODE)) {
   1936         mParameters.set(QCameraParameters::KEY_FLASH_MODE,
   1937                         QCameraParameters::FLASH_MODE_OFF);
   1938         mParameters.set(QCameraParameters::KEY_SUPPORTED_FLASH_MODES,
   1939                         flash_values);
   1940     }
   1941 
   1942     mParameters.set(QCameraParameters::KEY_MAX_SHARPNESS,
   1943             CAMERA_MAX_SHARPNESS);
   1944     mParameters.set(QCameraParameters::KEY_MAX_CONTRAST,
   1945             CAMERA_MAX_CONTRAST);
   1946     mParameters.set(QCameraParameters::KEY_MAX_SATURATION,
   1947             CAMERA_MAX_SATURATION);
   1948 
   1949     mParameters.set(
   1950             QCameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
   1951             EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
   1952     mParameters.set(
   1953             QCameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
   1954             EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
   1955     mParameters.set(
   1956             QCameraParameters::KEY_EXPOSURE_COMPENSATION,
   1957             EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
   1958     mParameters.setFloat(
   1959             QCameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
   1960             EXPOSURE_COMPENSATION_STEP);
   1961 
   1962     mParameters.set("luma-adaptation", "3");
   1963     mParameters.set("skinToneEnhancement", "0");
   1964     mParameters.set("zoom-supported", "true");
   1965     mParameters.set("zoom", 0);
   1966     mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT,
   1967                     QCameraParameters::PIXEL_FORMAT_JPEG);
   1968 
   1969     mParameters.set(QCameraParameters::KEY_SHARPNESS,
   1970                     CAMERA_DEF_SHARPNESS);
   1971     mParameters.set(QCameraParameters::KEY_CONTRAST,
   1972                     CAMERA_DEF_CONTRAST);
   1973     mParameters.set(QCameraParameters::KEY_SATURATION,
   1974                     CAMERA_DEF_SATURATION);
   1975 
   1976     mParameters.set(QCameraParameters::KEY_ISO_MODE,
   1977                     QCameraParameters::ISO_AUTO);
   1978     mParameters.set(QCameraParameters::KEY_LENSSHADE,
   1979                     QCameraParameters::LENSSHADE_ENABLE);
   1980     mParameters.set(QCameraParameters::KEY_SUPPORTED_ISO_MODES,
   1981                     iso_values);
   1982     mParameters.set(QCameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
   1983                     lensshade_values);
   1984     mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT,
   1985                     QCameraParameters::MCE_ENABLE);
   1986     mParameters.set(QCameraParameters::KEY_SUPPORTED_MEM_COLOR_ENHANCE_MODES,
   1987                     mce_values);
   1988     if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_HFR) && !(mIs3DModeOn)) {
   1989         mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE,
   1990                     QCameraParameters::VIDEO_HFR_OFF);
   1991         mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,
   1992                     hfr_size_values.string());
   1993         mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_HIGH_FRAME_RATE_MODES,
   1994                     hfr_values);
   1995     } else
   1996         mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,"");
   1997 
   1998     mParameters.set(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING,
   1999                     QCameraParameters::MCE_DISABLE);
   2000     mParameters.set(QCameraParameters::KEY_SUPPORTED_HDR_IMAGING_MODES,
   2001                     hdr_values);
   2002     mParameters.set(QCameraParameters::KEY_HISTOGRAM,
   2003                     QCameraParameters::HISTOGRAM_DISABLE);
   2004     mParameters.set(QCameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
   2005                     histogram_values);
   2006     mParameters.set(QCameraParameters::KEY_SKIN_TONE_ENHANCEMENT,
   2007                     QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE);
   2008     mParameters.set(QCameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES,
   2009                     skinToneEnhancement_values);
   2010     mParameters.set(QCameraParameters::KEY_SCENE_MODE,
   2011                     QCameraParameters::SCENE_MODE_AUTO);
   2012     mParameters.set("strtextures", "OFF");
   2013 
   2014     mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_MODES,
   2015                     scenemode_values);
   2016     mParameters.set(QCameraParameters::KEY_DENOISE,
   2017                     QCameraParameters::DENOISE_OFF);
   2018     mParameters.set(QCameraParameters::KEY_SUPPORTED_DENOISE,
   2019                     denoise_values);
   2020 
   2021     //touch af/aec parameters
   2022     mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC,
   2023                     QCameraParameters::TOUCH_AF_AEC_OFF);
   2024     mParameters.set(QCameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
   2025                     touchafaec_values);
   2026     mParameters.set("touchAfAec-dx","100");
   2027     mParameters.set("touchAfAec-dy","100");
   2028     mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
   2029     mParameters.set(QCameraParameters::KEY_MAX_NUM_METERING_AREAS, "1");
   2030 
   2031     mParameters.set(QCameraParameters::KEY_SCENE_DETECT,
   2032                     QCameraParameters::SCENE_DETECT_OFF);
   2033     mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_DETECT,
   2034                     scenedetect_values);
   2035     mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF,
   2036                     QCameraParameters::SELECTABLE_ZONE_AF_AUTO);
   2037     mParameters.set(QCameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
   2038                     selectable_zone_af_values);
   2039     mParameters.set(QCameraParameters::KEY_FACE_DETECTION,
   2040                     QCameraParameters::FACE_DETECTION_OFF);
   2041     mParameters.set(QCameraParameters::KEY_SUPPORTED_FACE_DETECTION,
   2042                     facedetection_values);
   2043     mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION,
   2044                     QCameraParameters::REDEYE_REDUCTION_DISABLE);
   2045     mParameters.set(QCameraParameters::KEY_SUPPORTED_REDEYE_REDUCTION,
   2046                     redeye_reduction_values);
   2047     mParameters.set(QCameraParameters::KEY_ZSL,
   2048                     QCameraParameters::ZSL_OFF);
   2049     mParameters.set(QCameraParameters::KEY_SUPPORTED_ZSL_MODES,
   2050                     zsl_values);
   2051 
   2052     float focalLength = 0.0f;
   2053     float horizontalViewAngle = 0.0f;
   2054     float verticalViewAngle = 0.0f;
   2055 
   2056     mCfgControl.mm_camera_get_parm(CAMERA_PARM_FOCAL_LENGTH,
   2057             (void *)&focalLength);
   2058     mParameters.setFloat(QCameraParameters::KEY_FOCAL_LENGTH,
   2059                     focalLength);
   2060     mCfgControl.mm_camera_get_parm(CAMERA_PARM_HORIZONTAL_VIEW_ANGLE,
   2061             (void *)&horizontalViewAngle);
   2062     mParameters.setFloat(QCameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
   2063                     horizontalViewAngle);
   2064     mCfgControl.mm_camera_get_parm(CAMERA_PARM_VERTICAL_VIEW_ANGLE,
   2065             (void *)&verticalViewAngle);
   2066     mParameters.setFloat(QCameraParameters::KEY_VERTICAL_VIEW_ANGLE,
   2067                     verticalViewAngle);
   2068     numCapture = 1;
   2069     if(mZslEnable) {
   2070         int maxSnapshot = MAX_SNAPSHOT_BUFFERS - 2;
   2071         char value[5];
   2072         property_get("persist.camera.hal.capture", value, "1");
   2073         numCapture = atoi(value);
   2074         if(numCapture > maxSnapshot)
   2075             numCapture = maxSnapshot;
   2076         else if(numCapture < 1)
   2077             numCapture = 1;
   2078         mParameters.set("capture-burst-captures-values", maxSnapshot);
   2079         mParameters.set("capture-burst-interval-supported", "false");
   2080     }
   2081     mParameters.set("num-snaps-per-shutter", numCapture);
   2082     ALOGI("%s: setting num-snaps-per-shutter to %d", __FUNCTION__, numCapture);
   2083     if(mIs3DModeOn)
   2084         mParameters.set("3d-frame-format", "left-right");
   2085 
   2086     switch(mCurrentTarget){
   2087         case TARGET_MSM7627:
   2088         case TARGET_QSD8250:
   2089         case TARGET_MSM7630:
   2090            mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "800x480");
   2091            break;
   2092         case TARGET_MSM7627A:
   2093             mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "864x480");
   2094             break;
   2095         case TARGET_MSM8660:
   2096             mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1920x1088");
   2097             break;
   2098         default:
   2099             mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "640x480");
   2100             break;
   2101     }
   2102     if (setParameters(mParameters) != NO_ERROR) {
   2103         ALOGE("Failed to set default parameters?!");
   2104     }
   2105 
   2106     /* Initialize the camframe_timeout_flag*/
   2107     Mutex::Autolock l(&mCamframeTimeoutLock);
   2108     camframe_timeout_flag = FALSE;
   2109     mPostviewHeap = NULL;
   2110     mDisplayHeap = NULL;
   2111     mLastPreviewFrameHeap = NULL;
   2112     mThumbnailHeap = NULL;
   2113 
   2114     mInitialized = true;
   2115     strTexturesOn = false;
   2116 
   2117     ALOGV("initDefaultParameters X");
   2118 }
   2119 
   2120 
   2121 #define ROUND_TO_PAGE(x)  (((x)+0xfff)&~0xfff)
   2122 
   2123 bool QualcommCameraHardware::startCamera()
   2124 {
   2125     ALOGV("startCamera E");
   2126     if( mCurrentTarget == TARGET_MAX ) {
   2127         ALOGE(" Unable to determine the target type. Camera will not work ");
   2128         return false;
   2129     }
   2130 #if DLOPEN_LIBMMCAMERA
   2131 
   2132     ALOGV("loading liboemcamera at %p", libmmcamera);
   2133     if (!libmmcamera) {
   2134         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   2135         return false;
   2136     }
   2137 
   2138     *(void **)&LINK_cam_frame =
   2139         ::dlsym(libmmcamera, "cam_frame");
   2140     *(void **)&LINK_wait_cam_frame_thread_ready =
   2141 	::dlsym(libmmcamera, "wait_cam_frame_thread_ready");
   2142     *(void **)&LINK_cam_frame_set_exit_flag =
   2143         ::dlsym(libmmcamera, "cam_frame_set_exit_flag");
   2144     *(void **)&LINK_camframe_terminate =
   2145         ::dlsym(libmmcamera, "camframe_terminate");
   2146 
   2147     *(void **)&LINK_jpeg_encoder_init =
   2148         ::dlsym(libmmcamera, "jpeg_encoder_init");
   2149 
   2150     *(void **)&LINK_jpeg_encoder_encode =
   2151         ::dlsym(libmmcamera, "jpeg_encoder_encode");
   2152 
   2153     *(void **)&LINK_jpeg_encoder_join =
   2154         ::dlsym(libmmcamera, "jpeg_encoder_join");
   2155 
   2156     mCamNotify.preview_frame_cb = &receive_camframe_callback;
   2157 
   2158     mCamNotify.camstats_cb = &receive_camstats_callback;
   2159 
   2160     mCamNotify.on_event =  &receive_event_callback;
   2161 
   2162     mCamNotify.on_error_event = &receive_camframe_error_callback;
   2163 
   2164     // 720 p new recording functions
   2165     mCamNotify.video_frame_cb = &receive_camframe_video_callback;
   2166      // 720 p new recording functions
   2167 
   2168     *(void **)&LINK_camframe_add_frame = ::dlsym(libmmcamera, "camframe_add_frame");
   2169 
   2170     *(void **)&LINK_camframe_release_all_frames = ::dlsym(libmmcamera, "camframe_release_all_frames");
   2171 
   2172     *(void **)&LINK_mmcamera_shutter_callback =
   2173         ::dlsym(libmmcamera, "mmcamera_shutter_callback");
   2174 
   2175     *LINK_mmcamera_shutter_callback = receive_shutter_callback;
   2176 
   2177     *(void**)&LINK_jpeg_encoder_setMainImageQuality =
   2178         ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
   2179 
   2180     *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
   2181         ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
   2182 
   2183     *(void**)&LINK_jpeg_encoder_setRotation =
   2184         ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
   2185 
   2186     *(void**)&LINK_jpeg_encoder_get_buffer_offset =
   2187         ::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset");
   2188 
   2189     *(void**)&LINK_jpeg_encoder_set_3D_info =
   2190         ::dlsym(libmmcamera, "jpeg_encoder_set_3D_info");
   2191 
   2192 /* Disabling until support is available.
   2193     *(void**)&LINK_jpeg_encoder_setLocation =
   2194         ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
   2195 */
   2196     *(void **)&LINK_cam_conf =
   2197         ::dlsym(libmmcamera, "cam_conf");
   2198 
   2199 /* Disabling until support is available.
   2200     *(void **)&LINK_default_sensor_get_snapshot_sizes =
   2201         ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
   2202 */
   2203     *(void **)&LINK_launch_cam_conf_thread =
   2204         ::dlsym(libmmcamera, "launch_cam_conf_thread");
   2205 
   2206     *(void **)&LINK_release_cam_conf_thread =
   2207         ::dlsym(libmmcamera, "release_cam_conf_thread");
   2208 
   2209     mCamNotify.on_liveshot_event = &receive_liveshot_callback;
   2210 
   2211     *(void **)&LINK_cancel_liveshot =
   2212         ::dlsym(libmmcamera, "cancel_liveshot");
   2213 
   2214     *(void **)&LINK_set_liveshot_params =
   2215         ::dlsym(libmmcamera, "set_liveshot_params");
   2216 
   2217     *(void **)&LINK_set_liveshot_frame =
   2218         ::dlsym(libmmcamera, "set_liveshot_frame");
   2219 
   2220     *(void **)&LINK_mm_camera_destroy =
   2221         ::dlsym(libmmcamera, "mm_camera_destroy");
   2222 
   2223     *(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12_inplace =
   2224         ::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12");
   2225 
   2226     *(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12 =
   2227         ::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12_ver2");
   2228 
   2229     /* Disabling until support is available.*/
   2230     *(void **)&LINK_zoom_crop_upscale =
   2231         ::dlsym(libmmcamera, "zoom_crop_upscale");
   2232 
   2233 
   2234 #else
   2235     mCamNotify.preview_frame_cb = &receive_camframe_callback;
   2236     mCamNotify.camstats_cb = &receive_camstats_callback;
   2237     mCamNotify.on_event =  &receive_event_callback;
   2238 
   2239     mmcamera_shutter_callback = receive_shutter_callback;
   2240      mCamNotify.on_liveshot_event = &receive_liveshot_callback;
   2241      mCamNotify.video_frame_cb = &receive_camframe_video_callback;
   2242 
   2243 #endif // DLOPEN_LIBMMCAMERA
   2244 #if 0 //commenting this for now as not getting graphics permission
   2245     if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){
   2246         fb_fd = open("/dev/graphics/fb0", O_RDWR);
   2247         if (fb_fd < 0) {
   2248             ALOGE("startCamera: fb0 open failed: %s!", strerror(errno));
   2249             return FALSE;
   2250         }
   2251     }
   2252 #endif
   2253     int ret_val;
   2254     if (pthread_join(mDeviceOpenThread, (void**)&ret_val) != 0) {
   2255          ALOGE("openCamera thread exit failed");
   2256          return false;
   2257     }
   2258 
   2259     if (!mCameraOpen) {
   2260         ALOGE("openCamera() failed");
   2261         return false;
   2262     }
   2263 
   2264 
   2265     mCfgControl.mm_camera_query_parms(CAMERA_PARM_PICT_SIZE, (void **)&picture_sizes, &PICTURE_SIZE_COUNT);
   2266     if ((picture_sizes == NULL) || (!PICTURE_SIZE_COUNT)) {
   2267         ALOGE("startCamera X: could not get snapshot sizes");
   2268         return false;
   2269     }
   2270      ALOGI("startCamera picture_sizes %p PICTURE_SIZE_COUNT %d", picture_sizes, PICTURE_SIZE_COUNT);
   2271     mCfgControl.mm_camera_query_parms(CAMERA_PARM_PREVIEW_SIZE, (void **)&preview_sizes, &PREVIEW_SIZE_COUNT);
   2272     if ((preview_sizes == NULL) || (!PREVIEW_SIZE_COUNT)) {
   2273         ALOGE("startCamera X: could not get preview sizes");
   2274         return false;
   2275     }
   2276     ALOGI("startCamera preview_sizes %p previewSizeCount %d", preview_sizes, PREVIEW_SIZE_COUNT);
   2277 
   2278     mCfgControl.mm_camera_query_parms(CAMERA_PARM_HFR_SIZE, (void **)&hfr_sizes, &HFR_SIZE_COUNT);
   2279     if ((hfr_sizes == NULL) || (!HFR_SIZE_COUNT)) {
   2280         ALOGE("startCamera X: could not get hfr sizes");
   2281         return false;
   2282     }
   2283     ALOGI("startCamera hfr_sizes %p hfrSizeCount %d", hfr_sizes, HFR_SIZE_COUNT);
   2284 
   2285 
   2286     ALOGV("startCamera X");
   2287     return true;
   2288 }
   2289 
   2290 status_t QualcommCameraHardware::dump(int fd,
   2291                                       const Vector<String16>& args) const
   2292 {
   2293     const size_t SIZE = 256;
   2294     char buffer[SIZE];
   2295     String8 result;
   2296 #if 0
   2297     // Dump internal primitives.
   2298     result.append("QualcommCameraHardware::dump");
   2299     snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
   2300     result.append(buffer);
   2301     int width, height;
   2302     mParameters.getPreviewSize(&width, &height);
   2303     snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
   2304     result.append(buffer);
   2305     mParameters.getPictureSize(&width, &height);
   2306     snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
   2307     result.append(buffer);
   2308     snprintf(buffer, 255,
   2309              "preview frame size(%d), raw size (%d), jpeg size (%d) "
   2310              "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
   2311              mJpegSize, mJpegMaxSize);
   2312     result.append(buffer);
   2313     write(fd, result.string(), result.size());
   2314 
   2315     // Dump internal objects.
   2316     if (mPreviewHeap[0] != 0) {
   2317         mPreviewHeap[0]->dump(fd, args);
   2318     }
   2319     if (mRawHeap != 0) {
   2320         mRawHeap->dump(fd, args);
   2321     }
   2322     if (mJpegHeap != 0) {
   2323         mJpegHeap->dump(fd, args);
   2324     }
   2325     mParameters.dump(fd, args);
   2326 #endif
   2327     return NO_ERROR;
   2328 }
   2329 
   2330 /* Issue ioctl calls related to starting Camera Operations*/
   2331 bool static native_start_ops(mm_camera_ops_type_t  type, void* value)
   2332 {
   2333     if(mCamOps.mm_camera_start(type, value,NULL) != MM_CAMERA_SUCCESS) {
   2334         ALOGE("native_start_ops: type %d error %s",
   2335             type,strerror(errno));
   2336         return false;
   2337     }
   2338     return true;
   2339 }
   2340 
   2341 /* Issue ioctl calls related to stopping Camera Operations*/
   2342 bool static native_stop_ops(mm_camera_ops_type_t  type, void* value)
   2343 {
   2344      if(mCamOps.mm_camera_stop(type, value,NULL) != MM_CAMERA_SUCCESS) {
   2345         ALOGE("native_stop_ops: type %d error %s",
   2346             type,strerror(errno));
   2347         return false;
   2348     }
   2349     return true;
   2350 }
   2351 /*==========================================================================*/
   2352 
   2353 
   2354 #define GPS_PROCESSING_METHOD_SIZE  101
   2355 #define FOCAL_LENGTH_DECIMAL_PRECISON 100
   2356 
   2357 static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
   2358 #define EXIF_ASCII_PREFIX_SIZE (sizeof(ExifAsciiPrefix))
   2359 
   2360 static rat_t latitude[3];
   2361 static rat_t longitude[3];
   2362 static char lonref[2];
   2363 static char latref[2];
   2364 static rat_t altitude;
   2365 static rat_t gpsTimestamp[3];
   2366 static char gpsDatestamp[20];
   2367 static char dateTime[20];
   2368 static rat_t focalLength;
   2369 static uint16_t flashMode;
   2370 static int iso_arr[] = {0,1,100,200,400,800,1600};
   2371 static uint16_t isoMode;
   2372 static char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
   2373 static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
   2374                         uint32_t count, uint8_t copy, void *data) {
   2375 
   2376     if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
   2377         ALOGE("Number of entries exceeded limit");
   2378         return;
   2379     }
   2380 
   2381     int index = exif_table_numEntries;
   2382     exif_data[index].tag_id = tagid;
   2383     exif_data[index].tag_entry.type = type;
   2384     exif_data[index].tag_entry.count = count;
   2385     exif_data[index].tag_entry.copy = copy;
   2386     if((type == EXIF_RATIONAL) && (count > 1))
   2387         exif_data[index].tag_entry.data._rats = (rat_t *)data;
   2388     if((type == EXIF_RATIONAL) && (count == 1))
   2389         exif_data[index].tag_entry.data._rat = *(rat_t *)data;
   2390     else if(type == EXIF_ASCII)
   2391         exif_data[index].tag_entry.data._ascii = (char *)data;
   2392     else if(type == EXIF_BYTE)
   2393         exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
   2394     else if((type == EXIF_SHORT) && (count > 1))
   2395         exif_data[index].tag_entry.data._shorts = (uint16_t *)data;
   2396     else if((type == EXIF_SHORT) && (count == 1))
   2397         exif_data[index].tag_entry.data._short = *(uint16_t *)data;
   2398     // Increase number of entries
   2399     exif_table_numEntries++;
   2400 }
   2401 
   2402 static void parseLatLong(const char *latlonString, int *pDegrees,
   2403                            int *pMinutes, int *pSeconds ) {
   2404 
   2405     double value = atof(latlonString);
   2406     value = fabs(value);
   2407     int degrees = (int) value;
   2408 
   2409     double remainder = value - degrees;
   2410     int minutes = (int) (remainder * 60);
   2411     int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
   2412 
   2413     *pDegrees = degrees;
   2414     *pMinutes = minutes;
   2415     *pSeconds = seconds;
   2416 }
   2417 
   2418 static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
   2419 
   2420     int degrees, minutes, seconds;
   2421 
   2422     parseLatLong(latlonString, &degrees, &minutes, &seconds);
   2423 
   2424     rat_t value[3] = { {degrees, 1},
   2425                        {minutes, 1},
   2426                        {seconds, 1000} };
   2427 
   2428     if(tag == EXIFTAGID_GPS_LATITUDE) {
   2429         memcpy(latitude, value, sizeof(latitude));
   2430         addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
   2431                     1, (void *)latitude);
   2432     } else {
   2433         memcpy(longitude, value, sizeof(longitude));
   2434         addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
   2435                     1, (void *)longitude);
   2436     }
   2437 }
   2438 
   2439 void QualcommCameraHardware::setGpsParameters() {
   2440     const char *str = NULL;
   2441 
   2442     str = mParameters.get(QCameraParameters::KEY_GPS_PROCESSING_METHOD);
   2443 
   2444     if(str!=NULL ){
   2445        memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
   2446        strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str,
   2447            GPS_PROCESSING_METHOD_SIZE - 1);
   2448        gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0';
   2449        addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII,
   2450            EXIF_ASCII_PREFIX_SIZE + strlen(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1,
   2451            1, (void *)gpsProcessingMethod);
   2452     }
   2453 
   2454     str = NULL;
   2455 
   2456     //Set Latitude
   2457     str = mParameters.get(QCameraParameters::KEY_GPS_LATITUDE);
   2458     if(str != NULL) {
   2459         setLatLon(EXIFTAGID_GPS_LATITUDE, str);
   2460         //set Latitude Ref
   2461         float latitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LATITUDE);
   2462         latref[0] = 'N';
   2463         if(latitudeValue < 0 ){
   2464             latref[0] = 'S';
   2465         }
   2466         latref[1] = '\0';
   2467         mParameters.set(QCameraParameters::KEY_GPS_LATITUDE_REF, latref);
   2468         addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
   2469                                 1, (void *)latref);
   2470     }
   2471 
   2472     //set Longitude
   2473     str = NULL;
   2474     str = mParameters.get(QCameraParameters::KEY_GPS_LONGITUDE);
   2475     if(str != NULL) {
   2476         setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
   2477         //set Longitude Ref
   2478         float longitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LONGITUDE);
   2479         lonref[0] = 'E';
   2480         if(longitudeValue < 0){
   2481             lonref[0] = 'W';
   2482         }
   2483         lonref[1] = '\0';
   2484         mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE_REF, lonref);
   2485         addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
   2486                                 1, (void *)lonref);
   2487     }
   2488 
   2489     //set Altitude
   2490     str = NULL;
   2491     str = mParameters.get(QCameraParameters::KEY_GPS_ALTITUDE);
   2492     if(str != NULL) {
   2493         double value = atof(str);
   2494         int ref = 0;
   2495         if(value < 0){
   2496             ref = 1;
   2497             value = -value;
   2498         }
   2499         uint32_t value_meter = value * 1000;
   2500         rat_t alt_value = {value_meter, 1000};
   2501         memcpy(&altitude, &alt_value, sizeof(altitude));
   2502         addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
   2503                     1, (void *)&altitude);
   2504         //set AltitudeRef
   2505         mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE_REF, ref);
   2506         addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
   2507                     1, (void *)&ref);
   2508     }
   2509 
   2510     //set Gps TimeStamp
   2511     str = NULL;
   2512     str = mParameters.get(QCameraParameters::KEY_GPS_TIMESTAMP);
   2513     if(str != NULL) {
   2514 
   2515       long value = atol(str);
   2516       time_t unixTime;
   2517       struct tm *UTCTimestamp;
   2518 
   2519       unixTime = (time_t)value;
   2520       UTCTimestamp = gmtime(&unixTime);
   2521 
   2522       strftime(gpsDatestamp, sizeof(gpsDatestamp), "%Y:%m:%d", UTCTimestamp);
   2523       addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII,
   2524                           strlen(gpsDatestamp)+1 , 1, (void *)&gpsDatestamp);
   2525 
   2526       rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1},
   2527                               {UTCTimestamp->tm_min, 1},
   2528                               {UTCTimestamp->tm_sec, 1} };
   2529 
   2530 
   2531       memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp));
   2532       addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
   2533                   3, 1, (void *)&gpsTimestamp);
   2534     }
   2535 
   2536 }
   2537 
   2538 
   2539 bool QualcommCameraHardware::initZslParameter(void)
   2540     {  ALOGV("%s: E", __FUNCTION__);
   2541        mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
   2542        ALOGI("initZslParamter E: picture size=%dx%d", mPictureWidth, mPictureHeight);
   2543        if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) {
   2544          mDimension.picture_width = mPictureWidth;
   2545          mDimension.picture_height = mPictureHeight;
   2546        }
   2547 
   2548        /* use the default thumbnail sizes */
   2549         mZslParms.picture_width = mPictureWidth;
   2550         mZslParms.picture_height = mPictureHeight;
   2551         mZslParms.preview_width =  mDimension.display_width;
   2552         mZslParms.preview_height = mDimension.display_height;
   2553         mZslParms.useExternalBuffers = TRUE;
   2554           /* fill main image size, thumbnail size, postview size into capture_params_t*/
   2555         memset(&mZslCaptureParms, 0, sizeof(zsl_capture_params_t));
   2556         mZslCaptureParms.thumbnail_height = mPostviewHeight;
   2557         mZslCaptureParms.thumbnail_width = mPostviewWidth;
   2558         ALOGI("Number of snapshot to capture: %d",numCapture);
   2559         mZslCaptureParms.num_captures = numCapture;
   2560 
   2561         return true;
   2562     }
   2563 
   2564 
   2565 bool QualcommCameraHardware::initImageEncodeParameters(int size)
   2566 {
   2567     ALOGV("%s: E", __FUNCTION__);
   2568     memset(&mImageEncodeParms, 0, sizeof(encode_params_t));
   2569     int jpeg_quality = mParameters.getInt("jpeg-quality");
   2570     bool ret;
   2571     if (jpeg_quality >= 0) {
   2572         ALOGI("initJpegParameters, current jpeg main img quality =%d",
   2573              jpeg_quality);
   2574         //Application can pass quality of zero
   2575         //when there is no back sensor connected.
   2576         //as jpeg quality of zero is not accepted at
   2577         //camera stack, pass default value.
   2578         if(jpeg_quality == 0) jpeg_quality = 85;
   2579         mImageEncodeParms.quality = jpeg_quality;
   2580         ret = native_set_parms(CAMERA_PARM_JPEG_MAINIMG_QUALITY, sizeof(int), &jpeg_quality);
   2581         if(!ret){
   2582           ALOGE("initJpegParametersX: failed to set main image quality");
   2583           return false;
   2584         }
   2585     }
   2586 
   2587     int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
   2588     if (thumbnail_quality >= 0) {
   2589         //Application can pass quality of zero
   2590         //when there is no back sensor connected.
   2591         //as quality of zero is not accepted at
   2592         //camera stack, pass default value.
   2593         if(thumbnail_quality == 0) thumbnail_quality = 85;
   2594         ALOGI("initJpegParameters, current jpeg thumbnail quality =%d",
   2595              thumbnail_quality);
   2596         /* TODO: check with mm-camera? */
   2597         mImageEncodeParms.quality = thumbnail_quality;
   2598         ret = native_set_parms(CAMERA_PARM_JPEG_THUMB_QUALITY, sizeof(int), &thumbnail_quality);
   2599         if(!ret){
   2600           ALOGE("initJpegParameters X: failed to set thumbnail quality");
   2601           return false;
   2602         }
   2603     }
   2604 
   2605     int rotation = mParameters.getInt("rotation");
   2606     char mDeviceName[PROPERTY_VALUE_MAX];
   2607     property_get("ro.hw_plat", mDeviceName, "");
   2608     if(!strcmp(mDeviceName,"7x25A"))
   2609         rotation = (rotation + 90)%360;
   2610 
   2611     if (mIs3DModeOn)
   2612         rotation = 0;
   2613     if (rotation >= 0) {
   2614         ALOGI("initJpegParameters, rotation = %d", rotation);
   2615         mImageEncodeParms.rotation = rotation;
   2616     }
   2617 
   2618     jpeg_set_location();
   2619 
   2620     //set TimeStamp
   2621     const char *str = mParameters.get(QCameraParameters::KEY_EXIF_DATETIME);
   2622     if(str != NULL) {
   2623       strncpy(dateTime, str, 19);
   2624       dateTime[19] = '\0';
   2625       addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   2626                   20, 1, (void *)dateTime);
   2627     }
   2628 
   2629     int focalLengthValue = (int) (mParameters.getFloat(
   2630                 QCameraParameters::KEY_FOCAL_LENGTH) * FOCAL_LENGTH_DECIMAL_PRECISON);
   2631     rat_t focalLengthRational = {focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISON};
   2632     memcpy(&focalLength, &focalLengthRational, sizeof(focalLengthRational));
   2633     addExifTag(EXIFTAGID_FOCAL_LENGTH, EXIF_RATIONAL, 1,
   2634                 1, (void *)&focalLength);
   2635     //Adding ExifTag for ISOSpeedRating
   2636     const char *iso_str = mParameters.get(QCameraParameters::KEY_ISO_MODE);
   2637     int iso_value = attr_lookup(iso, sizeof(iso) / sizeof(str_map), iso_str);
   2638     isoMode = iso_arr[iso_value];
   2639     addExifTag(EXIFTAGID_ISO_SPEED_RATING,EXIF_SHORT,1,1,(void *)&isoMode);
   2640 
   2641     if (mUseJpegDownScaling) {
   2642       ALOGI("initImageEncodeParameters: update main image", __func__);
   2643       mImageEncodeParms.output_picture_width = mActualPictWidth;
   2644       mImageEncodeParms.output_picture_height = mActualPictHeight;
   2645     }
   2646     mImageEncodeParms.cbcr_offset = mCbCrOffsetRaw;
   2647     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)
   2648         mImageEncodeParms.cbcr_offset = mCbCrOffsetRaw;
   2649     /* TODO: check this */
   2650     mImageEncodeParms.y_offset = 0;
   2651     for(int i = 0; i < size; i++){
   2652         memset(&mEncodeOutputBuffer[i], 0, sizeof(mm_camera_buffer_t));
   2653         mEncodeOutputBuffer[i].ptr = (uint8_t *)mJpegMapped[i]->data;
   2654         mEncodeOutputBuffer[i].filled_size = mJpegMaxSize;
   2655         mEncodeOutputBuffer[i].size = mJpegMaxSize;
   2656         mEncodeOutputBuffer[i].fd = mJpegfd[i];
   2657         mEncodeOutputBuffer[i].offset = 0;
   2658     }
   2659     mImageEncodeParms.p_output_buffer = mEncodeOutputBuffer;
   2660     mImageEncodeParms.exif_data = exif_data;
   2661     mImageEncodeParms.exif_numEntries = exif_table_numEntries;
   2662 
   2663     mImageEncodeParms.format3d = mIs3DModeOn;
   2664     return true;
   2665 }
   2666 
   2667 bool QualcommCameraHardware::native_set_parms(
   2668     camera_parm_type_t type, uint16_t length, void *value)
   2669 {
   2670     if(mCfgControl.mm_camera_set_parm(type,value) != MM_CAMERA_SUCCESS) {
   2671         ALOGE("native_set_parms failed: type %d length %d error %s",
   2672             type, length, strerror(errno));
   2673         return false;
   2674     }
   2675     return true;
   2676 
   2677 }
   2678 bool QualcommCameraHardware::native_set_parms(
   2679     camera_parm_type_t type, uint16_t length, void *value, int *result)
   2680 {
   2681     mm_camera_status_t status;
   2682     status = mCfgControl.mm_camera_set_parm(type,value);
   2683     ALOGI("native_set_parms status = %d", status);
   2684     if( status == MM_CAMERA_SUCCESS || status == MM_CAMERA_ERR_INVALID_OPERATION){
   2685         *result = status ;
   2686         return true;
   2687     }
   2688     ALOGE("%s: type %d length %d error %s, status %d", __FUNCTION__,
   2689                                        type, length, strerror(errno), status);
   2690    *result = status;
   2691     return false;
   2692 }
   2693 
   2694 void QualcommCameraHardware::jpeg_set_location()
   2695 {
   2696     bool encode_location = true;
   2697     camera_position_type pt;
   2698 
   2699 #define PARSE_LOCATION(what,type,fmt,desc) do {                                \
   2700         pt.what = 0;                                                           \
   2701         const char *what##_str = mParameters.get("gps-"#what);                 \
   2702         ALOGI("GPS PARM %s --> [%s]", "gps-"#what, what##_str);                 \
   2703         if (what##_str) {                                                      \
   2704             type what = 0;                                                     \
   2705             if (sscanf(what##_str, fmt, &what) == 1)                           \
   2706                 pt.what = what;                                                \
   2707             else {                                                             \
   2708                 ALOGE("GPS " #what " %s could not"                              \
   2709                      " be parsed as a " #desc, what##_str);                    \
   2710                 encode_location = false;                                       \
   2711             }                                                                  \
   2712         }                                                                      \
   2713         else {                                                                 \
   2714             ALOGI("GPS " #what " not specified: "                               \
   2715                  "defaulting to zero in EXIF header.");                        \
   2716             encode_location = false;                                           \
   2717        }                                                                       \
   2718     } while(0)
   2719 
   2720     PARSE_LOCATION(timestamp, long, "%ld", "long");
   2721     if (!pt.timestamp) pt.timestamp = time(NULL);
   2722     PARSE_LOCATION(altitude, short, "%hd", "short");
   2723     PARSE_LOCATION(latitude, double, "%lf", "double float");
   2724     PARSE_LOCATION(longitude, double, "%lf", "double float");
   2725 
   2726 #undef PARSE_LOCATION
   2727 
   2728     if (encode_location) {
   2729         ALOGI("setting image location ALT %d LAT %lf LON %lf",
   2730              pt.altitude, pt.latitude, pt.longitude);
   2731 
   2732         setGpsParameters();
   2733         /* Disabling until support is available.
   2734         if (!LINK_jpeg_encoder_setLocation(&pt)) {
   2735             ALOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
   2736         }
   2737         */
   2738     }
   2739     else ALOGI("not setting image location");
   2740 }
   2741 
   2742 static bool register_buf(int size,
   2743                          int frame_size,
   2744                          int cbcr_offset,
   2745                          int yoffset,
   2746                          int pmempreviewfd,
   2747                          uint32_t offset,
   2748                          uint8_t *buf,
   2749                          int pmem_type,
   2750                          bool vfe_can_write,
   2751                          bool register_buffer,
   2752                          bool use_all_chnls)
   2753 {
   2754     struct msm_pmem_info pmemBuf;
   2755     CAMERA_HAL_UNUSED(frame_size);
   2756 
   2757     memset(&pmemBuf, 0, sizeof(struct msm_pmem_info));
   2758     pmemBuf.type     = pmem_type;
   2759     pmemBuf.fd       = pmempreviewfd;
   2760     pmemBuf.offset   = offset;
   2761     pmemBuf.len      = size;
   2762     pmemBuf.vaddr    = buf;
   2763     pmemBuf.planar0_off = yoffset;
   2764      if(!use_all_chnls) {
   2765        ALOGI("use_all_chnls = %d\n", use_all_chnls);
   2766        pmemBuf.planar1_off = cbcr_offset;
   2767        pmemBuf.planar2_off = yoffset;
   2768                } else {
   2769        pmemBuf.planar1_off = myv12_params.CbOffset;
   2770        pmemBuf.planar2_off = myv12_params.CrOffset;
   2771                }
   2772        ALOGI("register_buf: CbOff = 0x%x CrOff = 0x%x",
   2773        pmemBuf.planar1_off, pmemBuf.planar2_off);
   2774 
   2775     pmemBuf.active   = vfe_can_write;
   2776 
   2777     ALOGI("register_buf:  reg = %d buffer = %p",
   2778          !register_buffer, buf);
   2779     if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER :
   2780         CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) {
   2781          ALOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM  error %s",
   2782                strerror(errno));
   2783          return false;
   2784          }
   2785 
   2786     return true;
   2787 
   2788 }
   2789 
   2790 static bool register_buf(int size,
   2791                          int frame_size,
   2792                          int cbcr_offset,
   2793                          int yoffset,
   2794                          int pmempreviewfd,
   2795                          uint32_t offset,
   2796                          uint8_t *buf,
   2797                          int pmem_type,
   2798                          bool vfe_can_write,
   2799                          bool register_buffer = true,
   2800                          bool use_all_chnls = false);
   2801 
   2802 void QualcommCameraHardware::runFrameThread(void *data)
   2803 {
   2804     ALOGV("runFrameThread E");
   2805     int type;
   2806     int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   2807 
   2808     if(libmmcamera)
   2809     {
   2810         LINK_cam_frame(data);
   2811     }
   2812     //waiting for preview thread to complete before clearing of the buffers
   2813     mPreviewThreadWaitLock.lock();
   2814     while (mPreviewThreadRunning) {
   2815         ALOGI("runframethread: waiting for preview  thread to complete.");
   2816         mPreviewThreadWait.wait(mPreviewThreadWaitLock);
   2817         ALOGI("initPreview: old preview thread completed.");
   2818     }
   2819     mPreviewThreadWaitLock.unlock();
   2820 
   2821     // Cancelling previewBuffers and returning them to display before stopping preview
   2822     // This will ensure that all preview buffers are available for dequeing when
   2823     //startPreview is called again with the same ANativeWindow object (snapshot case). If the
   2824     //ANativeWindow is a new one(camera-camcorder switch case) because the app passed a new
   2825     //surface then buffers will be re-allocated and not returned from the old pool.
   2826     relinquishBuffers();
   2827     mPreviewBusyQueue.flush();
   2828     /* Flush the Free Q */
   2829     LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   2830 
   2831     if(mIs3DModeOn != true) {
   2832 #if 0
   2833         if(mInHFRThread == false)
   2834         {
   2835              mPmemWaitLock.lock();
   2836              //mPreviewHeap.clear();
   2837 // TODO do properly
   2838              mPrevHeapDeallocRunning = true;
   2839              mPmemWait.signal();
   2840              mPmemWaitLock.unlock();
   2841 
   2842             if(( mPreviewFormat == CAMERA_YUV_420_YV12 )&&
   2843                 ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) &&
   2844                 previewWidth%32 != 0 )
   2845                 mYV12Heap.clear();
   2846 
   2847         }
   2848         else
   2849 #endif
   2850         {
   2851            int mBufferSize = previewWidth * previewHeight * 3/2;
   2852            int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   2853            ALOGI("unregistering all preview buffers");
   2854             //unregister preview buffers. we are not deallocating here.
   2855             for (int cnt = 0; cnt < mTotalPreviewBufferCount; ++cnt) {
   2856                 register_buf(mBufferSize,
   2857                          mBufferSize,
   2858                          mCbCrOffset,
   2859                          0,
   2860                          frames[cnt].fd,
   2861                          0,
   2862                          (uint8_t *)frames[cnt].buffer,
   2863                          MSM_PMEM_PREVIEW,
   2864                          false,
   2865                          false,
   2866                          true);
   2867             //mPreviewHeap[cnt].clear();
   2868              // TODO : clean properly
   2869             }
   2870         }
   2871     }
   2872     if(!mZslEnable) {
   2873     if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)){
   2874         if(mHFRMode != true) {
   2875 #if 0
   2876             mRecordHeap.clear();
   2877             mRecordHeap = NULL;
   2878 #endif
   2879         } else {
   2880             ALOGI("%s: unregister record buffers with camera driver", __FUNCTION__);
   2881             register_record_buffers(false);
   2882         }
   2883         int CbCrOffset = PAD_TO_2K(mDimension.video_width  * mDimension.video_height);
   2884 	    for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   2885 #if 0
   2886 	if (mRecordfd[cnt] > 0) {
   2887 	    ALOGE("Unregistering buffer %d with kernel",cnt);
   2888 	    register_buf(mRecordFrameSize,
   2889 		mRecordFrameSize, CbCrOffset, 0,
   2890 		mRecordfd[cnt],
   2891 		0,
   2892 		(uint8_t *)recordframes[cnt].buffer,
   2893 		MSM_PMEM_VIDEO,
   2894 		false, false);
   2895 	    ALOGE("Came back from register call to kernel");
   2896 	  }
   2897 #endif
   2898              type = MSM_PMEM_VIDEO;
   2899              ALOGI("%s: unregister record buffers[%d] with camera driver", __FUNCTION__, cnt);
   2900              if(recordframes) {
   2901                register_buf(mRecordFrameSize,
   2902                   mRecordFrameSize, CbCrOffset, 0,
   2903                   recordframes[cnt].fd,
   2904                   0,
   2905                   (uint8_t *)recordframes[cnt].buffer,
   2906                   type,
   2907                   false,false);
   2908                if(mRecordMapped[cnt]) {
   2909                    mRecordMapped[cnt]->release(mRecordMapped[cnt]);
   2910                    mRecordMapped[cnt] = NULL;
   2911                    close(mRecordfd[cnt]);
   2912                    if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   2913                        struct encoder_media_buffer_type * packet =
   2914                                (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   2915                        native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   2916                        metadata_memory[cnt]->release(metadata_memory[cnt]);
   2917                        metadata_memory[cnt] = NULL;
   2918                    }
   2919 #ifdef USE_ION
   2920                    deallocate_ion_memory(&record_main_ion_fd[cnt], &record_ion_info_fd[cnt]);
   2921 #endif
   2922                }
   2923             }
   2924 	    }
   2925     }
   2926 	}
   2927 
   2928     mFrameThreadWaitLock.lock();
   2929     mFrameThreadRunning = false;
   2930     mFrameThreadWait.signal();
   2931     mFrameThreadWaitLock.unlock();
   2932 
   2933     ALOGV("runFrameThread X");
   2934 }
   2935 
   2936 
   2937 void QualcommCameraHardware::runPreviewThread(void *data)
   2938 {
   2939     static int hfr_count = 0;
   2940     msm_frame* frame = NULL;
   2941     status_t retVal = NO_ERROR;
   2942     CAMERA_HAL_UNUSED(data);
   2943     android_native_buffer_t *buffer;
   2944 	buffer_handle_t *handle = NULL;
   2945     int bufferIndex = 0;
   2946 
   2947     while((frame = mPreviewBusyQueue.get()) != NULL) {
   2948         if (UNLIKELY(mDebugFps)) {
   2949             debugShowPreviewFPS();
   2950         }
   2951         mCallbackLock.lock();
   2952         int msgEnabled = mMsgEnabled;
   2953         camera_data_callback pcb = mDataCallback;
   2954         void *pdata = mCallbackCookie;
   2955         camera_data_timestamp_callback rcb = mDataCallbackTimestamp;
   2956         void *rdata = mCallbackCookie;
   2957         camera_data_callback mcb = mDataCallback;
   2958         void *mdata = mCallbackCookie;
   2959         mCallbackLock.unlock();
   2960 
   2961         // signal smooth zoom thread , that a new preview frame is available
   2962         mSmoothzoomThreadWaitLock.lock();
   2963         if(mSmoothzoomThreadRunning) {
   2964             mSmoothzoomThreadWait.signal();
   2965         }
   2966         mSmoothzoomThreadWaitLock.unlock();
   2967 
   2968         // Find the offset within the heap of the current buffer.
   2969         ssize_t offset_addr = 0; // TODO , use proper value
   2970       //      (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
   2971      //   ssize_t offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
   2972         common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
   2973 #ifdef DUMP_PREVIEW_FRAMES
   2974         static int frameCnt = 0;
   2975         int written;
   2976                 if (frameCnt >= 0 && frameCnt <= 10 ) {
   2977                     char buf[128];
   2978                     snprintf(buffer, sizeof(buf), "/data/%d_preview.yuv", frameCnt);
   2979                     int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
   2980                     ALOGI("dumping preview frame %d", frameCnt);
   2981                     if (file_fd < 0) {
   2982                         ALOGE("cannot open file\n");
   2983                     }
   2984                     else
   2985                     {
   2986                         ALOGI("dumping data");
   2987                         written = write(file_fd, (uint8_t *)frame->buffer,
   2988                             mPreviewFrameSize );
   2989                         if(written < 0)
   2990                           ALOGE("error in data write");
   2991                     }
   2992                     close(file_fd);
   2993               }
   2994               frameCnt++;
   2995 #endif
   2996         mInPreviewCallback = true;
   2997          if (crop->in1_w != 0 && crop->in1_h != 0) {
   2998              zoomCropInfo.left = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
   2999              zoomCropInfo.top = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
   3000              /* There can be scenarios where the in1_wXin1_h and
   3001               * out1_wXout1_h are same. In those cases, reset the
   3002               * x and y to zero instead of negative for proper zooming
   3003               */
   3004              if(zoomCropInfo.left < 0) zoomCropInfo.left = 0;
   3005              if(zoomCropInfo.top < 0) zoomCropInfo.top = 0;
   3006              zoomCropInfo.right = zoomCropInfo.left + crop->in1_w;
   3007              zoomCropInfo.bottom = zoomCropInfo.top + crop->in1_h;
   3008              mPreviewWindow-> set_crop (mPreviewWindow,
   3009                                        zoomCropInfo.left,
   3010                                        zoomCropInfo.top,
   3011                                        zoomCropInfo.right,
   3012                                        zoomCropInfo.bottom);
   3013              /* Set mResetOverlayCrop to true, so that when there is
   3014               * no crop information, setCrop will be called
   3015               * with zero crop values.
   3016               */
   3017              mResetWindowCrop = true;
   3018 
   3019          } else {
   3020              // Reset zoomCropInfo variables. This will ensure that
   3021              // stale values wont be used for postview
   3022              zoomCropInfo.left = 0;
   3023              zoomCropInfo.top = 0;
   3024              zoomCropInfo.right = crop->in1_w;
   3025              zoomCropInfo.bottom = crop->in1_h;
   3026              /* This reset is required, if not, overlay driver continues
   3027               * to use the old crop information for these preview
   3028               * frames which is not the correct behavior. To avoid
   3029               * multiple calls, reset once.
   3030               */
   3031              if(mResetWindowCrop == true){
   3032                 mPreviewWindow-> set_crop (mPreviewWindow,
   3033                                       zoomCropInfo.left,
   3034                                       zoomCropInfo.top,
   3035                                       zoomCropInfo.right,
   3036                                       zoomCropInfo.bottom);
   3037                  mResetWindowCrop = false;
   3038              }
   3039          }
   3040          /* To overcome a timing case where we could be having the overlay refer to deallocated
   3041             mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the
   3042             first preview frame is queued to the overlay in 8660. Also adding the condition
   3043             to check if snapshot is currently in progress ensures that the resources being
   3044             used by the snapshot thread are not incorrectly deallocated by preview thread*/
   3045          if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) {
   3046              ALOGD(" receivePreviewFrame : first frame queued, display heap being deallocated");
   3047               mThumbnailHeap.clear();
   3048               mDisplayHeap.clear();
   3049               if(!mZslEnable){
   3050                  mDisplayHeap.clear();
   3051                  mPostviewHeap.clear();
   3052              }
   3053              mFirstFrame = false;
   3054          }
   3055          mLastQueuedFrame = (void *)frame->buffer;
   3056          bufferIndex = mapBuffer(frame);
   3057 
   3058          // if 7x27A && yv12 is set as preview format use convert routines to
   3059          // convert from YUV420sp to YV12
   3060          yuv_image_type in_buf, out_buf;
   3061          int conversion_result = 0;
   3062 
   3063          if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) &&
   3064            ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 )){
   3065             // if the width is not multiple of 32,
   3066             //we cannot do inplace conversion as sizes of 420sp and YV12 frames differ
   3067             if(previewWidth%32){
   3068 #if 0 //TODO :
   3069                ALOGE("YV12::Doing not inplace conversion from 420sp to yv12");
   3070                in_buf.imgPtr = (unsigned char*)mPreviewMapped[bufferIndex]->data;
   3071                in_buf.dx = out_buf.dx = previewWidth;
   3072                in_buf.dy = in_buf.dy = previewHeight;
   3073                conversion_result = LINK_yuv_convert_ycrcb420sp_to_yv12(&in_buf, &out_buf);
   3074 #endif
   3075             } else {
   3076                ALOGI("Doing inplace conversion from 420sp to yv12");
   3077                in_buf.imgPtr = (unsigned char *)mPreviewMapped[bufferIndex]->data;
   3078                in_buf.dx  = previewWidth;
   3079                in_buf.dy  = previewHeight;
   3080                conversion_result = LINK_yuv_convert_ycrcb420sp_to_yv12_inplace(&in_buf);
   3081             }
   3082          }
   3083 
   3084          if(bufferIndex >= 0) {
   3085            //Need to encapsulate this in IMemory object and send
   3086 
   3087          if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
   3088              int previewBufSize;
   3089              /* for CTS : Forcing preview memory buffer lenth to be
   3090                           'previewWidth * previewHeight * 3/2'. Needed when gralloc allocated extra memory.*/
   3091              if( mPreviewFormat == CAMERA_YUV_420_NV21 || mPreviewFormat == CAMERA_YUV_420_YV12) {
   3092                previewBufSize = previewWidth * previewHeight * 3/2;
   3093                camera_memory_t *previewMem = mGetMemory(frames[bufferIndex].fd, previewBufSize,
   3094                                                         1, mCallbackCookie);
   3095                if (!previewMem || !previewMem->data) {
   3096                  ALOGE("%s: mGetMemory failed.\n", __func__);
   3097                } else {
   3098                    pcb(CAMERA_MSG_PREVIEW_FRAME,previewMem,0,NULL,pdata);
   3099                    previewMem->release(previewMem);
   3100                }
   3101              } else
   3102                  pcb(CAMERA_MSG_PREVIEW_FRAME,(camera_memory_t *) mPreviewMapped[bufferIndex],0,NULL,pdata);
   3103          }
   3104 
   3105            // TODO : may have to reutn proper frame as pcb
   3106            mDisplayLock.lock();
   3107            if( mPreviewWindow != NULL) {
   3108                 if (BUFFER_LOCKED == frame_buffer[bufferIndex].lockState) {
   3109                     if (GENLOCK_FAILURE == genlock_unlock_buffer(
   3110                            (native_handle_t*)(*(frame_buffer[bufferIndex].buffer)))) {
   3111                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   3112                        mDisplayLock.unlock();
   3113                     } else {
   3114                        frame_buffer[bufferIndex].lockState = BUFFER_UNLOCKED;
   3115                     }
   3116                 } else {
   3117                     ALOGI("%s: buffer to be enqueued is unlocked", __FUNCTION__);
   3118                     mDisplayLock.unlock();
   3119                 }
   3120              const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
   3121              if(str != NULL){
   3122                  int is_hfr_off = 0;
   3123                  hfr_count++;
   3124                  if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) {
   3125                     is_hfr_off = 1;
   3126                     retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   3127                                                frame_buffer[bufferIndex].buffer);
   3128                  } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) {
   3129                     hfr_count %= 2;
   3130                  } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) {
   3131                     hfr_count %= 3;
   3132                  } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) {
   3133                     hfr_count %= 4;
   3134                  }
   3135                  if(hfr_count == 0)
   3136                      retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   3137                                                 frame_buffer[bufferIndex].buffer);
   3138                  else if(!is_hfr_off)
   3139                      retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   3140                                                 frame_buffer[bufferIndex].buffer);
   3141              } else
   3142                    retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   3143                                               frame_buffer[bufferIndex].buffer);
   3144              if( retVal != NO_ERROR)
   3145                ALOGE("%s: Failed while queueing buffer %d for display."
   3146                          " Error = %d", __FUNCTION__,
   3147                          frames[bufferIndex].fd, retVal);
   3148              int stride;
   3149              retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   3150                                                 &(handle),&(stride));
   3151              private_handle_t *bhandle = (private_handle_t *)(*handle);
   3152              if( retVal != NO_ERROR) {
   3153                ALOGE("%s: Failed while dequeueing buffer from display."
   3154                         " Error = %d", __FUNCTION__, retVal);
   3155              } else {
   3156                retVal = mPreviewWindow->lock_buffer(mPreviewWindow,handle);
   3157                //yyan todo use handle to find out buffer
   3158                  if(retVal != NO_ERROR)
   3159                    ALOGE("%s: Failed while dequeueing buffer from"
   3160                       "display. Error = %d", __FUNCTION__, retVal);
   3161              }
   3162            }
   3163            mDisplayLock.unlock();
   3164          } else
   3165            ALOGE("Could not find the buffer");
   3166 
   3167         // If output  is NOT enabled (targets otherthan 7x30 , 8x50 and 8x60 currently..)
   3168 
   3169         nsecs_t timeStamp = nsecs_t(frame->ts.tv_sec)*1000000000LL + frame->ts.tv_nsec;
   3170 
   3171         if( (mCurrentTarget != TARGET_MSM7630 ) &&  (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
   3172             int flagwait = 1;
   3173             if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) && (record_flag)) {
   3174                 if(mStoreMetaDataInFrame){
   3175                     flagwait = 1;
   3176                     if(metadata_memory[bufferIndex]!= NULL)
   3177                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, metadata_memory[bufferIndex],0,rdata);
   3178                     else flagwait = 0;
   3179                 } else {
   3180                     rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mPreviewMapped[bufferIndex],0, rdata);
   3181                 }
   3182                 if(flagwait){
   3183                     Mutex::Autolock rLock(&mRecordFrameLock);
   3184                         if (mReleasedRecordingFrame != true) {
   3185                             mRecordWait.wait(mRecordFrameLock);
   3186                         }
   3187                         mReleasedRecordingFrame = false;
   3188                 }
   3189             }
   3190         }
   3191 
   3192         if ( mCurrentTarget == TARGET_MSM8660 ) {
   3193             mMetaDataWaitLock.lock();
   3194             if (mFaceDetectOn == true && mSendMetaData == true) {
   3195                 mSendMetaData = false;
   3196                 fd_roi_t *roi = (fd_roi_t *)(frame->roi_info.info);
   3197 
   3198                 switch (roi->type) {
   3199                 case FD_ROI_TYPE_HEADER:
   3200                     {
   3201                         mNumFDRcvd = 0;
   3202                         memset(mFaceArray, -1, sizeof(mFaceArray));
   3203                         mFaceArray[0] = 0; //faces_detected * 4;
   3204 
   3205                         mFacesDetected = roi->d.hdr.num_face_detected;
   3206                         if(mFacesDetected > MAX_ROI)
   3207                           mFacesDetected = MAX_ROI;
   3208                     }
   3209                     break;
   3210                 case FD_ROI_TYPE_DATA:
   3211                     {
   3212                         int idx = roi->d.data.idx;
   3213                         if (idx < mFacesDetected) {
   3214                             mFaceArray[idx*4+1]   = roi->d.data.face.face_boundary.x;
   3215                             mFaceArray[idx*4+2] = roi->d.data.face.face_boundary.y;
   3216                             mFaceArray[idx*4+3] = roi->d.data.face.face_boundary.x;
   3217                             mFaceArray[idx*4+4] = roi->d.data.face.face_boundary.y;
   3218                             mNumFDRcvd++;
   3219                             if (mNumFDRcvd == mFacesDetected) {
   3220                                 mFaceArray[0] = mFacesDetected * 4;
   3221                                 if(mMetaDataHeap != NULL){
   3222                                     ALOGV("runPreviewThread mMetaDataHEap is non-NULL");
   3223                                     memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)mFaceArray, sizeof(mFaceArray));
   3224                                 }
   3225                             }
   3226                         }
   3227                     }
   3228                     break;
   3229                 }
   3230             }
   3231             mMetaDataWaitLock.unlock();
   3232         }
   3233         bufferIndex = mapFrame(handle);
   3234         if(bufferIndex >= 0) {
   3235            LINK_camframe_add_frame(CAM_PREVIEW_FRAME, &frames[bufferIndex]);
   3236            private_handle_t *bhandle = (private_handle_t *)(*handle);
   3237            if (GENLOCK_NO_ERROR != genlock_lock_buffer(bhandle, GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   3238                 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
   3239                 frame_buffer[bufferIndex].lockState = BUFFER_UNLOCKED;
   3240            } else {
   3241                 frame_buffer[bufferIndex].lockState = BUFFER_LOCKED;
   3242            }
   3243         } else {
   3244           ALOGE("Could not find the Frame");
   3245 
   3246           // Special Case: Stoppreview is issued which causes thumbnail buffer
   3247           // to be cancelled. Frame thread has still not exited. In preview thread
   3248           // dequeue returns incorrect buffer id (previously cancelled thumbnail buffer)
   3249           // This will throw error "Could not find frame". We need to cancel the incorrectly
   3250           // dequeued buffer here to ensure that all buffers are available for the next
   3251           // startPreview call.
   3252 
   3253           mDisplayLock.lock();
   3254           ALOGV(" error Cancelling preview buffers  ");
   3255 	    retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   3256 		          handle);
   3257           if(retVal != NO_ERROR)
   3258               ALOGE("%s:  cancelBuffer failed for buffer", __FUNCTION__);
   3259           mDisplayLock.unlock();
   3260         }
   3261       }
   3262     mPreviewThreadWaitLock.lock();
   3263     mPreviewThreadRunning = false;
   3264     mPreviewThreadWait.signal();
   3265     mPreviewThreadWaitLock.unlock();
   3266 }
   3267 int QualcommCameraHardware::mapBuffer(struct msm_frame *frame) {
   3268   int ret = -1;
   3269   for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   3270      if (frame_buffer[cnt].frame->buffer == frame->buffer) {
   3271         ret = cnt;
   3272         break;
   3273        }
   3274     }
   3275   return ret;
   3276 }
   3277 int QualcommCameraHardware::mapvideoBuffer(struct msm_frame *frame)
   3278 {
   3279   int ret = -1;
   3280   for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   3281      if ((unsigned int)mRecordMapped[cnt]->data == (unsigned int)frame->buffer) {
   3282        ret = cnt;
   3283        ALOGI("found match returning %d", ret);
   3284        break;
   3285      }
   3286   }
   3287   return ret;
   3288 
   3289 }
   3290 int QualcommCameraHardware::mapRawBuffer(struct msm_frame *frame)
   3291 {
   3292   int ret = -1;
   3293   for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   3294      if ((unsigned int)mRawMapped[cnt]->data == (unsigned int)frame->buffer) {
   3295        ret = cnt;
   3296        ALOGI("found match returning %d", ret);
   3297        break;
   3298      }
   3299   }
   3300   return ret;
   3301 }
   3302 int QualcommCameraHardware::mapThumbnailBuffer(struct msm_frame *frame)
   3303 {
   3304   int ret = -1;
   3305   for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   3306      if ((unsigned int)(uint8_t *)mThumbnailMapped[cnt] == (unsigned int)frame->buffer) {
   3307        ret = cnt;
   3308        ALOGI("found match returning %d", ret);
   3309        break;
   3310      }
   3311   }
   3312   if(ret < 0) ALOGE("mapThumbnailBuffer, could not find match");
   3313   return ret;
   3314 }
   3315 int QualcommCameraHardware::mapJpegBuffer(mm_camera_buffer_t *encode_buffer)
   3316 {
   3317   int ret = -1;
   3318   for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   3319      if ((unsigned int)mJpegMapped[cnt]->data == (unsigned int)encode_buffer->ptr) {
   3320        ret = cnt;
   3321        ALOGI("found match returning %d", ret);
   3322        break;
   3323      }
   3324   }
   3325   return ret;
   3326 }
   3327 int QualcommCameraHardware::mapFrame(buffer_handle_t *buffer) {
   3328   int ret = -1;
   3329   for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   3330      if (frame_buffer[cnt].buffer == buffer) {
   3331        ret = cnt;
   3332        break;
   3333      }
   3334   }
   3335   return ret;
   3336 }
   3337 
   3338 void *preview_thread(void *user)
   3339 {
   3340     ALOGV("preview_thread E");
   3341     QualcommCameraHardware  *obj = QualcommCameraHardware::getInstance();
   3342     if (obj != 0) {
   3343         obj->runPreviewThread(user);
   3344     }
   3345     else ALOGE("not starting preview thread: the object went away!");
   3346     ALOGV("preview_thread X");
   3347     return NULL;
   3348 }
   3349 
   3350 void *hfr_thread(void *user)
   3351 {
   3352     ALOGV("hfr_thread E");
   3353     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   3354     if (obj != 0) {
   3355         obj->runHFRThread(user);
   3356     }
   3357     else ALOGE("not starting hfr thread: the object went away!");
   3358     ALOGV("hfr_thread X");
   3359     return NULL;
   3360 }
   3361 
   3362 void QualcommCameraHardware::runHFRThread(void *data)
   3363 {
   3364     ALOGV("runHFRThread E");
   3365     mInHFRThread = true;
   3366     CAMERA_HAL_UNUSED(data);
   3367     ALOGI("%s: stopping Preview", __FUNCTION__);
   3368     stopPreviewInternal();
   3369 
   3370     // Release thumbnail Buffers
   3371     if( mPreviewWindow != NULL ) {
   3372         private_handle_t *handle;
   3373         for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   3374             if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) {
   3375                 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   3376                 ALOGV("%s:  Cancelling postview buffer %d ", __FUNCTION__, handle->fd);
   3377                 ALOGV("runHfrThread : display lock");
   3378                 mDisplayLock.lock();
   3379                 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) {
   3380                     if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   3381                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   3382                        mDisplayLock.unlock();
   3383                        continue;
   3384                     } else {
   3385                        mThumbnailLockState[cnt] = BUFFER_UNLOCKED;
   3386                     }
   3387                 }
   3388                 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   3389                                                               mThumbnailBuffer[cnt]);
   3390                 if(retVal != NO_ERROR)
   3391                     ALOGE("%s: cancelBuffer failed for postview buffer %d",
   3392                                                      __FUNCTION__, handle->fd);
   3393                 // unregister , unmap and release as well
   3394                 int mBufferSize = previewWidth * previewHeight * 3/2;
   3395                 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   3396                 if(mThumbnailMapped[cnt] && (mSnapshotFormat == PICTURE_FORMAT_JPEG)) {
   3397                     ALOGI("%s:  Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd);
   3398                     register_buf(mBufferSize,
   3399                         mBufferSize, mCbCrOffset, 0,
   3400                         handle->fd,
   3401                         0,
   3402                         (uint8_t *)mThumbnailMapped[cnt],
   3403                         MSM_PMEM_THUMBNAIL,
   3404                         false, false);
   3405                     if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) {
   3406                       ALOGE("StopPreview : Error un-mmapping the thumbnail buffer %d", index);
   3407                     }
   3408                     mThumbnailBuffer[cnt] = NULL;
   3409                     mThumbnailMapped[cnt] = NULL;
   3410                 }
   3411                 ALOGV("runHfrThread : display unlock");
   3412                 mDisplayLock.unlock();
   3413           }
   3414        }
   3415     }
   3416 
   3417     ALOGV("%s: setting parameters", __FUNCTION__);
   3418     setParameters(mParameters);
   3419     ALOGV("%s: starting Preview", __FUNCTION__);
   3420     if( mPreviewWindow == NULL)
   3421     {
   3422         startPreviewInternal();
   3423     }
   3424     else {
   3425         getBuffersAndStartPreview();
   3426     }
   3427 
   3428     mHFRMode = false;
   3429     mInHFRThread = false;
   3430 }
   3431 
   3432 void QualcommCameraHardware::runVideoThread(void *data)
   3433 {
   3434     ALOGV("runVideoThread E");
   3435     msm_frame* vframe = NULL;
   3436     CAMERA_HAL_UNUSED(data);
   3437 
   3438     while(true) {
   3439         pthread_mutex_lock(&(g_busy_frame_queue.mut));
   3440 
   3441         // Exit the thread , in case of stop recording..
   3442         mVideoThreadWaitLock.lock();
   3443         if(mVideoThreadExit){
   3444             ALOGV("Exiting video thread..");
   3445             mVideoThreadWaitLock.unlock();
   3446             pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   3447             break;
   3448         }
   3449         mVideoThreadWaitLock.unlock();
   3450 
   3451         ALOGV("in video_thread : wait for video frame ");
   3452         // check if any frames are available in busyQ and give callback to
   3453         // services/video encoder
   3454         cam_frame_wait_video();
   3455         ALOGV("video_thread, wait over..");
   3456 
   3457         // Exit the thread , in case of stop recording..
   3458         mVideoThreadWaitLock.lock();
   3459         if(mVideoThreadExit){
   3460             ALOGV("Exiting video thread..");
   3461             mVideoThreadWaitLock.unlock();
   3462             pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   3463             break;
   3464         }
   3465         mVideoThreadWaitLock.unlock();
   3466 
   3467         // Get the video frame to be encoded
   3468         vframe = cam_frame_get_video ();
   3469         pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   3470         ALOGI("in video_thread : got video frame %x",vframe);
   3471 
   3472         /*if (UNLIKELY(mDebugFps)) {
   3473             debugShowVideoFPS();
   3474         }*/
   3475 
   3476         if(vframe != NULL) {
   3477             // Find the offset within the heap of the current buffer.
   3478             //ALOGV("Got video frame :  buffer %d base %d ", vframe->buffer,
   3479               //(unsigned long int)mRecordHeap->mHeap->base());
   3480             //ssize_t offset =
   3481             //    (ssize_t)vframe->buffer - (ssize_t)mRecordHeap->mHeap->base();
   3482             //ALOGV("offset = %d , alignsize = %d , new_offset = %d", (int)offset, mRecordHeap->mAlignedBufferSize,
   3483              // (int)(offset / mRecordHeap->mAlignedBufferSize));
   3484 
   3485             //offset /= mRecordHeap->mAlignedBufferSize;
   3486 
   3487             //set the track flag to true for this video buffer
   3488             //record_buffers_tracking_flag[offset] = true;
   3489 
   3490             /* Extract the timestamp of this frame */
   3491             nsecs_t timeStamp = nsecs_t(vframe->ts.tv_sec)*1000000000LL + vframe->ts.tv_nsec;
   3492 
   3493             // dump frames for test purpose
   3494 #if 0
   3495             static int frameCnt = 0;
   3496             if (frameCnt >= 11 && frameCnt <= 13 ) {
   3497                 char buf[128];
   3498                 sprintf(buf,  "/data/%d_v.yuv", frameCnt);
   3499                 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
   3500                 ALOGV("dumping video frame %d", frameCnt);
   3501                 if (file_fd < 0) {
   3502                     ALOGE("cannot open file\n");
   3503                 }
   3504                 else
   3505                 {
   3506                     write(file_fd, (const void *)vframe->buffer,
   3507                         vframe->cbcr_off * 3 / 2);
   3508                 }
   3509                 close(file_fd);
   3510           }
   3511           frameCnt++;
   3512 #endif
   3513 #if 0
   3514           if(mIs3DModeOn ) {
   3515               /* VPE will be taking care of zoom, so no need to
   3516                * use overlay's setCrop interface for zoom
   3517                * functionality.
   3518                */
   3519               /* get the offset of current video buffer for rendering */
   3520               ssize_t offset_addr = (ssize_t)vframe->buffer -
   3521                                       (ssize_t)mRecordHeap->mHeap->base();
   3522               /* To overcome a timing case where we could be having the overlay refer to deallocated
   3523                  mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the
   3524                  first preview frame is queued to the overlay in 8660 */
   3525               if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) {
   3526                   ALOGD(" receivePreviewFrame : first frame queued, display heap being deallocated");
   3527                   mThumbnailHeap.clear();
   3528                   mDisplayHeap.clear();
   3529                   mFirstFrame = false;
   3530                   mPostviewHeap.clear();
   3531               }
   3532               mLastQueuedFrame = (void *)vframe->buffer;
   3533           }
   3534 #endif
   3535             // Enable IF block to give frames to encoder , ELSE block for just simulation
   3536 #if 1
   3537             ALOGV("in video_thread : got video frame, before if check giving frame to services/encoder");
   3538             mCallbackLock.lock();
   3539             int msgEnabled = mMsgEnabled;
   3540             camera_data_timestamp_callback rcb = mDataCallbackTimestamp;
   3541             void *rdata = mCallbackCookie;
   3542             mCallbackLock.unlock();
   3543 
   3544             /* When 3D mode is ON, the video thread will be ON even in preview
   3545              * mode. We need to distinguish when recording is started. So, when
   3546              * 3D mode is ON, check for the recordingState (which will be set
   3547              * with start recording and reset in stop recording), before
   3548              * calling rcb.
   3549              */
   3550             int index = mapvideoBuffer(vframe);
   3551             if(!mIs3DModeOn) {
   3552                 record_buffers_tracking_flag[index] = true;
   3553                 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
   3554                     ALOGV("in video_thread : got video frame, giving frame to services/encoder index = %d", index);
   3555                     if(mStoreMetaDataInFrame){
   3556                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, metadata_memory[index],0,rdata);
   3557                     } else {
   3558                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordMapped[index],0,rdata);
   3559                     }
   3560                 }
   3561             }
   3562 #if 0
   3563             else {
   3564                 mCallbackLock.lock();
   3565                 msgEnabled = mMsgEnabled;
   3566                 data_callback pcb = mDataCallback;
   3567                 void *pdata = mCallbackCookie;
   3568                 mCallbackLock.unlock();
   3569                 if (pcb != NULL) {
   3570                     ALOGE("pcb is not null");
   3571                     static int count = 0;
   3572                     //if(msgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
   3573                     if (!count) {
   3574                         ALOGE("Giving first frame to app");
   3575                         pcb(CAMERA_MSG_PREVIEW_FRAME, mRecordHeap->mBuffers[offset],
   3576                                 pdata);
   3577                         count++;
   3578                     }
   3579                 }
   3580                 if(mRecordingState == 1) {
   3581                     if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
   3582                         ALOGV("in video_thread 3D mode : got video frame, giving frame to services/encoder");
   3583                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[offset], rdata);
   3584                     }
   3585                 } else {
   3586                     /* When in preview mode, put the video buffer back into
   3587                      * free Q, for next availability.
   3588                      */
   3589                     ALOGV("in video_thread 3D mode : got video frame, putting frame to Free Q");
   3590                     record_buffers_tracking_flag[offset] = false;
   3591                     LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe);
   3592                 }
   3593             }
   3594 #endif
   3595 #else
   3596             // 720p output2  : simulate release frame here:
   3597             ALOGI("in video_thread simulation , releasing the video frame");
   3598             LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe);
   3599 #endif
   3600 
   3601         } else ALOGE("in video_thread get frame returned null");
   3602 
   3603 
   3604     } // end of while loop
   3605 
   3606     mVideoThreadWaitLock.lock();
   3607     mVideoThreadRunning = false;
   3608     mVideoThreadWait.signal();
   3609     mVideoThreadWaitLock.unlock();
   3610 
   3611     ALOGV("runVideoThread X");
   3612 }
   3613 
   3614 void *video_thread(void *user)
   3615 {
   3616     ALOGV("video_thread E");
   3617     CAMERA_HAL_UNUSED(user);
   3618 
   3619     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   3620     if (obj != 0) {
   3621         obj->runVideoThread(user);
   3622     }
   3623     else ALOGE("not starting video thread: the object went away!");
   3624     ALOGV("video_thread X");
   3625     return NULL;
   3626 }
   3627 
   3628 void *frame_thread(void *user)
   3629 {
   3630     ALOGD("frame_thread E");
   3631     CAMERA_HAL_UNUSED(user);
   3632     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   3633     if (obj != 0) {
   3634         obj->runFrameThread(user);
   3635     }
   3636     else ALOGW("not starting frame thread: the object went away!");
   3637     ALOGD("frame_thread X");
   3638     return NULL;
   3639 }
   3640 
   3641 static int parse_size(const char *str, int &width, int &height)
   3642 {
   3643     // Find the width.
   3644     char *end;
   3645     int w = (int)strtol(str, &end, 10);
   3646     // If an 'x' or 'X' does not immediately follow, give up.
   3647     if ( (*end != 'x') && (*end != 'X') )
   3648         return -1;
   3649 
   3650     // Find the height, immediately after the 'x'.
   3651     int h = (int)strtol(end+1, 0, 10);
   3652 
   3653     width = w;
   3654     height = h;
   3655 
   3656     return 0;
   3657 }
   3658 QualcommCameraHardware* hardware;
   3659 
   3660 int QualcommCameraHardware::allocate_ion_memory(int *main_ion_fd, struct ion_allocation_data* alloc,
   3661      struct ion_fd_data* ion_info_fd, int ion_type, int size, int *memfd)
   3662 {
   3663     int rc = 0;
   3664     struct ion_handle_data handle_data;
   3665 
   3666     *main_ion_fd = open("/dev/ion", O_RDONLY | O_SYNC);
   3667     if (*main_ion_fd < 0) {
   3668       ALOGE("Ion dev open failed\n");
   3669       ALOGE("Error is %s\n", strerror(errno));
   3670       goto ION_OPEN_FAILED;
   3671     }
   3672     alloc->len = size;
   3673     /* to make it page size aligned */
   3674     alloc->len = (alloc->len + 4095) & (~4095);
   3675     alloc->align = 4096;
   3676     alloc->flags = 0;
   3677     alloc->heap_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID);
   3678 
   3679     rc = ioctl(*main_ion_fd, ION_IOC_ALLOC, alloc);
   3680     if (rc < 0) {
   3681       ALOGE("ION allocation failed\n");
   3682       goto ION_ALLOC_FAILED;
   3683     }
   3684 
   3685     ion_info_fd->handle = alloc->handle;
   3686     rc = ioctl(*main_ion_fd, ION_IOC_SHARE, ion_info_fd);
   3687     if (rc < 0) {
   3688       ALOGE("ION map failed %s\n", strerror(errno));
   3689       goto ION_MAP_FAILED;
   3690     }
   3691     *memfd = ion_info_fd->fd;
   3692     return 0;
   3693 
   3694 ION_MAP_FAILED:
   3695     handle_data.handle = ion_info_fd->handle;
   3696     ioctl(*main_ion_fd, ION_IOC_FREE, &handle_data);
   3697 ION_ALLOC_FAILED:
   3698     close(*main_ion_fd);
   3699 ION_OPEN_FAILED:
   3700     return -1;
   3701 }
   3702 int QualcommCameraHardware::deallocate_ion_memory(int *main_ion_fd, struct ion_fd_data* ion_info_fd)
   3703 {
   3704     struct ion_handle_data handle_data;
   3705     int rc = 0;
   3706 
   3707     handle_data.handle = ion_info_fd->handle;
   3708     ioctl(*main_ion_fd, ION_IOC_FREE, &handle_data);
   3709     close(*main_ion_fd);
   3710     return rc;
   3711 }
   3712 
   3713 bool QualcommCameraHardware::initPreview()
   3714 {
   3715     const char * pmem_region;
   3716     int CbCrOffset = 0;
   3717     int ion_heap;
   3718     mParameters.getPreviewSize(&previewWidth, &previewHeight);
   3719     const char *recordSize = NULL;
   3720     recordSize = mParameters.get(QCameraParameters::KEY_VIDEO_SIZE);
   3721 ALOGI("%s Got preview dimension as %d x %d ", __func__, previewWidth, previewHeight);
   3722     if(!recordSize) {
   3723          //If application didn't set this parameter string, use the values from
   3724          //getPreviewSize() as video dimensions.
   3725          ALOGV("No Record Size requested, use the preview dimensions");
   3726          videoWidth = previewWidth;
   3727          videoHeight = previewHeight;
   3728      } else {
   3729          //Extract the record witdh and height that application requested.
   3730          if(!parse_size(recordSize, videoWidth, videoHeight)) {
   3731              //VFE output1 shouldn't be greater than VFE output2.
   3732              if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) {
   3733                  //Set preview sizes as record sizes.
   3734                  ALOGI("Preview size %dx%d is greater than record size %dx%d,\
   3735                     resetting preview size to record size",previewWidth,\
   3736                       previewHeight, videoWidth, videoHeight);
   3737                  previewWidth = videoWidth;
   3738                  previewHeight = videoHeight;
   3739                  mParameters.setPreviewSize(previewWidth, previewHeight);
   3740              }
   3741              if( (mCurrentTarget != TARGET_MSM7630)
   3742                  && (mCurrentTarget != TARGET_QSD8250)
   3743                   && (mCurrentTarget != TARGET_MSM8660) ) {
   3744                  //For Single VFE output targets, use record dimensions as preview dimensions.
   3745                  previewWidth = videoWidth;
   3746                  previewHeight = videoHeight;
   3747                  mParameters.setPreviewSize(previewWidth, previewHeight);
   3748              }
   3749          } else {
   3750              ALOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize);
   3751              return false;
   3752          }
   3753      }
   3754 
   3755      mDimension.display_width = previewWidth;
   3756      mDimension.display_height= previewHeight;
   3757      mDimension.ui_thumbnail_width =
   3758              thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
   3759      mDimension.ui_thumbnail_height =
   3760              thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   3761 
   3762     ALOGV("initPreview E: preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, videoWidth, videoHeight );
   3763 
   3764     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   3765         mDimension.video_width = CEILING16(videoWidth);
   3766         /* Backup the video dimensions, as video dimensions in mDimension
   3767          * will be modified when DIS is supported. Need the actual values
   3768          * to pass ap part of VPE config
   3769          */
   3770         videoWidth = mDimension.video_width;
   3771         mDimension.video_height = videoHeight;
   3772         ALOGV("initPreview : preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight,
   3773           mDimension.video_width, mDimension.video_height);
   3774     }
   3775 
   3776     // See comments in deinitPreview() for why we have to wait for the frame
   3777     // thread here, and why we can't use pthread_join().
   3778     mFrameThreadWaitLock.lock();
   3779     while (mFrameThreadRunning) {
   3780         ALOGI("initPreview: waiting for old frame thread to complete.");
   3781         mFrameThreadWait.wait(mFrameThreadWaitLock);
   3782         ALOGI("initPreview: old frame thread completed.");
   3783     }
   3784     mFrameThreadWaitLock.unlock();
   3785 
   3786     mInSnapshotModeWaitLock.lock();
   3787     while (mInSnapshotMode) {
   3788         ALOGI("initPreview: waiting for snapshot mode to complete.");
   3789         mInSnapshotModeWait.wait(mInSnapshotModeWaitLock);
   3790         ALOGI("initPreview: snapshot mode completed.");
   3791     }
   3792     mInSnapshotModeWaitLock.unlock();
   3793 
   3794     pmem_region = "/dev/pmem_adsp";
   3795     ion_heap = ION_CAMERA_HEAP_ID;
   3796 
   3797     int cnt = 0;
   3798 
   3799     memset(&myv12_params, 0, sizeof(yv12_format_parms_t));
   3800     mPreviewFrameSize = previewWidth * previewHeight * 3/2;
   3801     ALOGI("Width = %d Height = %d \n", previewWidth, previewHeight);
   3802     if(mPreviewFormat == CAMERA_YUV_420_YV12) {
   3803        myv12_params.CbOffset = PAD_TO_WORD(previewWidth * previewHeight);
   3804        myv12_params.CrOffset = myv12_params.CbOffset + PAD_TO_WORD((previewWidth * previewHeight)/4);
   3805        mDimension.prev_format = CAMERA_YUV_420_YV12;
   3806        ALOGI("CbOffset = 0x%x CrOffset = 0x%x \n",myv12_params.CbOffset, myv12_params.CrOffset);
   3807     } else {
   3808       CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   3809       }
   3810 
   3811     //Pass the yuv formats, display dimensions,
   3812     //so that vfe will be initialized accordingly.
   3813     mDimension.display_luma_width = previewWidth;
   3814     mDimension.display_luma_height = previewHeight;
   3815     mDimension.display_chroma_width = previewWidth;
   3816     mDimension.display_chroma_height = previewHeight;
   3817     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   3818         mPreviewFrameSize = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)) +
   3819                                      2 * (CEILING32(previewWidth/2) * CEILING32(previewHeight/2));
   3820         CbCrOffset = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight));
   3821         mDimension.prev_format = CAMERA_YUV_420_NV21_ADRENO;
   3822         mDimension.display_luma_width = CEILING32(previewWidth);
   3823         mDimension.display_luma_height = CEILING32(previewHeight);
   3824         mDimension.display_chroma_width = 2 * CEILING32(previewWidth/2);
   3825         //Chroma Height is not needed as of now. Just sending with other dimensions.
   3826         mDimension.display_chroma_height = CEILING32(previewHeight/2);
   3827     }
   3828     ALOGV("mDimension.prev_format = %d", mDimension.prev_format);
   3829     ALOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
   3830     ALOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
   3831     ALOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
   3832     ALOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
   3833 
   3834     dstOffset = 0;
   3835     //set DIS value to get the updated video width and height to calculate
   3836     //the required record buffer size
   3837     if(mVpeEnabled) {
   3838         bool status = setDIS();
   3839         if(status) {
   3840             ALOGE("Failed to set DIS");
   3841             return false;
   3842         }
   3843     }
   3844 
   3845   //Pass the original video width and height and get the required width
   3846     //and height for record buffer allocation
   3847     mDimension.orig_video_width = videoWidth;
   3848     mDimension.orig_video_height = videoHeight;
   3849     if(mZslEnable){
   3850         //Limitation of ZSL  where the thumbnail and display dimensions should be the same
   3851         mDimension.ui_thumbnail_width = mDimension.display_width;
   3852         mDimension.ui_thumbnail_height = mDimension.display_height;
   3853         mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
   3854         if (updatePictureDimension(mParameters, mPictureWidth,
   3855           mPictureHeight)) {
   3856           mDimension.picture_width = mPictureWidth;
   3857           mDimension.picture_height = mPictureHeight;
   3858         }
   3859     }
   3860     // mDimension will be filled with thumbnail_width, thumbnail_height,
   3861     // orig_picture_dx, and orig_picture_dy after this function call. We need to
   3862     // keep it for jpeg_encoder_encode.
   3863     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   3864                                sizeof(cam_ctrl_dimension_t), &mDimension);
   3865 #if 0
   3866     if(mIs3DModeOn != true) {
   3867       if(mInHFRThread == false)
   3868       {
   3869         mPrevHeapDeallocRunning = false;
   3870 #ifdef USE_ION
   3871         mPreviewHeap = new IonPool(ion_heap,
   3872                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3873                                 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
   3874                                 mPreviewFrameSize,
   3875                                 kPreviewBufferCountActual,
   3876                                 mPreviewFrameSize,
   3877                                 CbCrOffset,
   3878                                 0,
   3879                                 "preview");
   3880 #else
   3881         mPreviewHeap = new PmemPool(pmem_region,
   3882                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3883                                 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
   3884                                 mPreviewFrameSize,
   3885                                 kPreviewBufferCountActual,
   3886                                 mPreviewFrameSize,
   3887                                 CbCrOffset,
   3888                                 0,
   3889                                 "preview");
   3890 #endif
   3891         if (!mPreviewHeap->initialized()) {
   3892           mPreviewHeap.clear();
   3893           ALOGE("initPreview X: could not initialize Camera preview heap.");
   3894           return false;
   3895         }
   3896       }
   3897       else
   3898       {
   3899           for (int cnt = 0; cnt < kPreviewBufferCountActual; ++cnt) {
   3900               bool status;
   3901               int active = (cnt < ACTIVE_PREVIEW_BUFFERS);
   3902               status = register_buf(mPreviewFrameSize,
   3903                        mPreviewFrameSize,
   3904                        CbCrOffset,
   3905                        0,
   3906                        mPreviewHeap->mHeap->getHeapID(),
   3907                        mPreviewHeap->mAlignedBufferSize * cnt,
   3908                        (uint8_t *)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt,
   3909                        MSM_PMEM_PREVIEW,
   3910                        active,
   3911                        true);
   3912               if(status == false){
   3913                   ALOGE("Registring Preview Buffers failed for HFR mode");
   3914                   return false;
   3915               }
   3916           }
   3917       }
   3918       // if 7x27A , YV12 format is set as preview format , if width is not 32
   3919       // bit aligned , we need seperate buffer to hold YV12 data
   3920     yv12framesize = (previewWidth*previewHeight)
   3921           + 2* ( CEILING16(previewWidth/2) * (previewHeight/2)) ;
   3922     if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) &&
   3923         ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 ) &&
   3924         previewWidth%32 != 0 ){
   3925         ALOGE("initpreview : creating YV12 heap as previewwidth %d not 32 aligned", previewWidth);
   3926 #ifdef USE_ION
   3927         mYV12Heap = new IonPool(ion_heap,
   3928                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3929                                 MSM_PMEM_PREVIEW,
   3930                                 yv12framesize,
   3931                                 NUM_YV12_FRAMES,
   3932                                 yv12framesize,
   3933                                 CbCrOffset,
   3934                                 0,
   3935                                 "postview");
   3936 #else
   3937         mYV12Heap = new PmemPool(pmem_region,
   3938                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3939                                 MSM_PMEM_PREVIEW,
   3940                                 yv12framesize,
   3941                                 NUM_YV12_FRAMES,
   3942                                 yv12framesize,
   3943                                 CbCrOffset,
   3944                                 0,
   3945                                 "postview");
   3946 #endif
   3947             if (!mYV12Heap->initialized()) {
   3948                 mYV12Heap.clear();
   3949                 ALOGE("initPreview X: could not initialize YV12 Camera preview heap.");
   3950                 return false;
   3951             }
   3952         }
   3953     }
   3954 #endif
   3955 
   3956     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   3957 
   3958         // Allocate video buffers after allocating preview buffers.
   3959         bool status = initRecord();
   3960         if(status != true) {
   3961             ALOGE("Failed to allocate video bufers");
   3962             return false;
   3963         }
   3964     }
   3965 
   3966     if (ret) {
   3967         if(mIs3DModeOn != true) {
   3968             for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
   3969 #if 0
   3970                 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
   3971                 frames[cnt].buffer =
   3972                     (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
   3973                 frames[cnt].y_off = 0;
   3974                 frames[cnt].cbcr_off = CbCrOffset;
   3975                 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
   3976 #endif
   3977         }
   3978 
   3979             mPreviewBusyQueue.init();
   3980             LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   3981             for(int i=ACTIVE_PREVIEW_BUFFERS ;i <kPreviewBufferCount; i++)
   3982                 LINK_camframe_add_frame(CAM_PREVIEW_FRAME,&frames[i]);
   3983 
   3984             mPreviewThreadWaitLock.lock();
   3985             pthread_attr_t pattr;
   3986             pthread_attr_init(&pattr);
   3987             pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
   3988 
   3989             mPreviewThreadRunning = !pthread_create(&mPreviewThread,
   3990                                       &pattr,
   3991                                       preview_thread,
   3992                                       (void*)NULL);
   3993             ret = mPreviewThreadRunning;
   3994             mPreviewThreadWaitLock.unlock();
   3995 
   3996             if(ret == false)
   3997                 return ret;
   3998         }
   3999 
   4000 
   4001         mFrameThreadWaitLock.lock();
   4002         pthread_attr_t attr;
   4003         pthread_attr_init(&attr);
   4004         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   4005         camframeParams.cammode = CAMERA_MODE_2D;
   4006 
   4007         if (mIs3DModeOn) {
   4008             camframeParams.cammode = CAMERA_MODE_3D;
   4009         } else {
   4010             camframeParams.cammode = CAMERA_MODE_2D;
   4011         }
   4012         LINK_cam_frame_set_exit_flag(0);
   4013 
   4014         mFrameThreadRunning = !pthread_create(&mFrameThread,
   4015                                               &attr,
   4016                                               frame_thread,
   4017                                               &camframeParams);
   4018         ret = mFrameThreadRunning;
   4019         mFrameThreadWaitLock.unlock();
   4020         LINK_wait_cam_frame_thread_ready();
   4021     }
   4022     mFirstFrame = true;
   4023 
   4024     ALOGV("initPreview X: %d", ret);
   4025     return ret;
   4026 }
   4027 
   4028 void QualcommCameraHardware::deinitPreview(void)
   4029 {
   4030     ALOGV("deinitPreview E");
   4031 
   4032     mPreviewBusyQueue.deinit();
   4033 
   4034     // When we call deinitPreview(), we signal to the frame thread that it
   4035     // needs to exit, but we DO NOT WAIT for it to complete here.  The problem
   4036     // is that deinitPreview is sometimes called from the frame-thread's
   4037     // callback, when the refcount on the Camera client reaches zero.  If we
   4038     // called pthread_join(), we would deadlock.  So, we just call
   4039     // LINK_camframe_terminate() in deinitPreview(), which makes sure that
   4040     // after the preview callback returns, the camframe thread will exit.  We
   4041     // could call pthread_join() in initPreview() to join the last frame
   4042     // thread.  However, we would also have to call pthread_join() in release
   4043     // as well, shortly before we destroy the object; this would cause the same
   4044     // deadlock, since release(), like deinitPreview(), may also be called from
   4045     // the frame-thread's callback.  This we have to make the frame thread
   4046     // detached, and use a separate mechanism to wait for it to complete.
   4047 
   4048     LINK_camframe_terminate();
   4049     ALOGV("deinitPreview X");
   4050 }
   4051 
   4052 bool QualcommCameraHardware::initRawSnapshot()
   4053 {
   4054     ALOGV("initRawSnapshot E");
   4055     const char * pmem_region;
   4056 
   4057     //get width and height from Dimension Object
   4058     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   4059                                sizeof(cam_ctrl_dimension_t), &mDimension);
   4060 
   4061 
   4062     if(!ret){
   4063         ALOGE("initRawSnapshot X: failed to set dimension");
   4064         return false;
   4065     }
   4066     int rawSnapshotSize = mDimension.raw_picture_height *
   4067                            mDimension.raw_picture_width;
   4068 
   4069     ALOGI("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
   4070          "raw_picture_width = %d",
   4071           rawSnapshotSize, mDimension.raw_picture_height,
   4072           mDimension.raw_picture_width);
   4073 
   4074     // Create Memory for Raw Snapshot
   4075     if( createSnapshotMemory(numCapture, numCapture, false, PICTURE_FORMAT_RAW) == false ) // TODO : check if the numbers are correct
   4076     {
   4077         ALOGE("ERROR :  initRawSnapshot , createSnapshotMemory failed");
   4078         return false;
   4079     }
   4080 
   4081     mRawCaptureParms.num_captures = 1;
   4082     mRawCaptureParms.raw_picture_width = mDimension.raw_picture_width;
   4083     mRawCaptureParms.raw_picture_height = mDimension.raw_picture_height;
   4084 
   4085     ALOGV("initRawSnapshot X");
   4086     return true;
   4087 
   4088 }
   4089 bool QualcommCameraHardware::initZslBuffers(bool initJpegHeap){
   4090     ALOGV("Init ZSL buffers E");
   4091     const char * pmem_region;
   4092     int ion_heap = ION_CP_MM_HEAP_ID;
   4093     int postViewBufferSize;
   4094 
   4095     mPostviewWidth = mDimension.display_width;
   4096     mPostviewHeight =  mDimension.display_height;
   4097 
   4098     //postview buffer initialization
   4099     postViewBufferSize  = mPostviewWidth * mPostviewHeight * 3 / 2;
   4100     int CbCrOffsetPostview = PAD_TO_WORD(mPostviewWidth * mPostviewHeight);
   4101     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   4102         postViewBufferSize  = PAD_TO_4K(CEILING32(mPostviewWidth) * CEILING32(mPostviewHeight)) +
   4103                                   2 * (CEILING32(mPostviewWidth/2) * CEILING32(mPostviewHeight/2));
   4104         int CbCrOffsetPostview = PAD_TO_4K(CEILING32(mPostviewWidth) * CEILING32(mPostviewHeight));
   4105     }
   4106 
   4107     //Snapshot buffer initialization
   4108     mRawSize = mPictureWidth * mPictureHeight * 3 / 2;
   4109     mCbCrOffsetRaw = PAD_TO_WORD(mPictureWidth * mPictureHeight);
   4110     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   4111         mRawSize = PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)) +
   4112                             2 * (CEILING32(mPictureWidth/2) * CEILING32(mPictureHeight/2));
   4113         mCbCrOffsetRaw = PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight));
   4114     }
   4115 
   4116     //Jpeg buffer initialization
   4117     if( mCurrentTarget == TARGET_MSM7627 ||
   4118        (mCurrentTarget == TARGET_MSM7625A ||
   4119         mCurrentTarget == TARGET_MSM7627A))
   4120         mJpegMaxSize = CEILING16(mPictureWidth) * CEILING16(mPictureHeight) * 3 / 2;
   4121     else {
   4122         mJpegMaxSize = mPictureWidth * mPictureHeight * 3 / 2;
   4123         if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
   4124             mJpegMaxSize =
   4125                PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)) +
   4126                     2 * (CEILING32(mPictureWidth/2) * CEILING32(mPictureHeight/2));
   4127         }
   4128     }
   4129 
   4130     cam_buf_info_t buf_info;
   4131     int yOffset = 0;
   4132     buf_info.resolution.width = mPictureWidth;
   4133     buf_info.resolution.height = mPictureHeight;
   4134     if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
   4135         mCfgControl.mm_camera_get_parm(CAMERA_PARM_BUFFER_INFO, (void *)&buf_info);
   4136         mRawSize = buf_info.size;
   4137         mJpegMaxSize = mRawSize;
   4138         mCbCrOffsetRaw = buf_info.cbcr_offset;
   4139         yOffset = buf_info.yoffset;
   4140     }
   4141 
   4142     ALOGV("initZslBuffer: initializing mRawHeap.");
   4143     if(mCurrentTarget == TARGET_MSM8660) {
   4144        pmem_region = "/dev/pmem_smipool";
   4145     } else {
   4146        pmem_region = "/dev/pmem_adsp";
   4147     }
   4148     //Main Raw Image
   4149     #if 0
   4150 #ifdef USE_ION
   4151     mRawHeap =
   4152         new IonPool( ion_heap,
   4153                      MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4154                      MSM_PMEM_MAINIMG,
   4155                      mJpegMaxSize,
   4156                      MAX_SNAPSHOT_BUFFERS,
   4157                      mRawSize,
   4158                      mCbCrOffsetRaw,
   4159                      yOffset,
   4160                      "snapshot camera");
   4161 #else
   4162     mRawHeap =
   4163         new PmemPool(pmem_region,
   4164                      MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4165                      MSM_PMEM_MAINIMG,
   4166                      mJpegMaxSize,
   4167                      MAX_SNAPSHOT_BUFFERS,
   4168                      mRawSize,
   4169                      mCbCrOffsetRaw,
   4170                      yOffset,
   4171                      "snapshot camera");
   4172 #endif
   4173     if (!mRawHeap->initialized()) {
   4174        ALOGE("initZslBuffer X failed ");
   4175        mRawHeap.clear();
   4176        ALOGE("initRaw X: error initializing mRawHeap");
   4177        return false;
   4178     }
   4179 
   4180 
   4181     // Jpeg
   4182     if (initJpegHeap) {
   4183         ALOGV("initZslRaw: initializing mJpegHeap.");
   4184         mJpegHeap =
   4185             new AshmemPool(mJpegMaxSize,
   4186                            (MAX_SNAPSHOT_BUFFERS - 2),  // It is the max number of snapshot supported.
   4187                            0, // we do not know how big the picture will be
   4188                            "jpeg");
   4189 
   4190         if (!mJpegHeap->initialized()) {
   4191             mJpegHeap.clear();
   4192             mRawHeap.clear();
   4193             ALOGE("initZslRaw X failed: error initializing mJpegHeap.");
   4194             return false;
   4195         }
   4196     }
   4197 
   4198     //PostView
   4199     pmem_region = "/dev/pmem_adsp";
   4200     ion_heap = ION_HEAP_ADSP_ID;
   4201 #ifdef USE_ION
   4202     mPostviewHeap =
   4203             new IonPool(ion_heap,
   4204                         MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4205                         MSM_PMEM_THUMBNAIL,
   4206                         postViewBufferSize,
   4207                         MAX_SNAPSHOT_BUFFERS,
   4208                         postViewBufferSize,
   4209                         CbCrOffsetPostview,
   4210                         0,
   4211                         "thumbnail");
   4212 #else
   4213     mPostviewHeap =
   4214             new PmemPool(pmem_region,
   4215                          MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4216                          MSM_PMEM_THUMBNAIL,
   4217                          postViewBufferSize,
   4218                          MAX_SNAPSHOT_BUFFERS,
   4219                          postViewBufferSize,
   4220                          CbCrOffsetPostview,
   4221                          0,
   4222                          "thumbnail");
   4223 #endif
   4224 
   4225     if (!mPostviewHeap->initialized()) {
   4226         mPostviewHeap.clear();
   4227         mJpegHeap.clear();
   4228         mRawHeap.clear();
   4229         ALOGE("initZslBuffer X failed: error initializing mPostviewHeap.");
   4230         return false;
   4231     }
   4232 #endif
   4233     if( createSnapshotMemory(MAX_SNAPSHOT_BUFFERS, MAX_SNAPSHOT_BUFFERS, initJpegHeap) == false ) // TODO : check if the numbers are correct
   4234     {
   4235         ALOGE("ERROR :  initZslraw , createSnapshotMemory failed");
   4236         return false;
   4237     }
   4238     /* frame all the exif and encode information into encode_params_t */
   4239     initImageEncodeParameters(MAX_SNAPSHOT_BUFFERS);
   4240 
   4241     ALOGV("initZslRaw X");
   4242     return true;
   4243 }
   4244 
   4245 bool QualcommCameraHardware::deinitZslBuffers()
   4246 {
   4247     ALOGV("deinitZslBuffers E");
   4248     for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   4249        if(NULL != mRawMapped[cnt]) {
   4250          ALOGI("Unregister MAIN_IMG");
   4251          register_buf(mJpegMaxSize,
   4252                   mRawSize,mCbCrOffsetRaw,0,
   4253                   mRawfd[cnt],0,
   4254                   (uint8_t *)mRawMapped[cnt]->data,
   4255                   MSM_PMEM_MAINIMG,
   4256                   0, 0);
   4257             mRawMapped[cnt]->release(mRawMapped[cnt]);
   4258             mRawMapped[cnt] = NULL;
   4259             close(mRawfd[cnt]);
   4260 #ifdef USE_ION
   4261             deallocate_ion_memory(&raw_main_ion_fd[cnt], &raw_ion_info_fd[cnt]);
   4262 #endif
   4263         }
   4264     }
   4265     for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS) : numCapture); cnt++) {
   4266         if(mJpegMapped[cnt]) {
   4267             mJpegMapped[cnt]->release(mJpegMapped[cnt]);
   4268             mJpegMapped[cnt] = NULL;
   4269         }
   4270     }
   4271     ALOGV("deinitZslBuffers X");
   4272     return true;
   4273 }
   4274 
   4275 bool QualcommCameraHardware::createSnapshotMemory (int numberOfRawBuffers, int numberOfJpegBuffers,
   4276                                                    bool initJpegHeap, int snapshotFormat)
   4277 {
   4278     char * pmem_region;
   4279     int ret;
   4280     int ion_heap = ION_CP_MM_HEAP_ID;
   4281     if(mCurrentTarget == TARGET_MSM8660) {
   4282        pmem_region = "/dev/pmem_smipool";
   4283     } else {
   4284        pmem_region = "/dev/pmem_adsp";
   4285     }
   4286     if( snapshotFormat == PICTURE_FORMAT_JPEG) {
   4287         // Create Raw memory for snapshot
   4288         for(int cnt = 0; cnt < numberOfRawBuffers; cnt++)
   4289         {
   4290         #ifdef USE_ION
   4291             if (allocate_ion_memory(&raw_main_ion_fd[cnt], &raw_alloc[cnt], &raw_ion_info_fd[cnt],
   4292                                     ion_heap, mJpegMaxSize, &mRawfd[cnt]) < 0){
   4293               ALOGE("do_mmap: Open device %s failed!\n",pmem_region);
   4294               return NULL;
   4295             }
   4296         #else
   4297             mRawfd[cnt] = open(pmem_region, O_RDWR|O_SYNC);
   4298             if (mRawfd[cnt] <= 0) {
   4299                 ALOGE("%s: Open device %s failed!\n",__func__, pmem_region);
   4300                     return false;
   4301             }
   4302         #endif
   4303             ALOGI("%s  Raw memory index: %d , fd is %d ", __func__, cnt, mRawfd[cnt]);
   4304             mRawMapped[cnt]=mGetMemory(mRawfd[cnt], mJpegMaxSize,1,mCallbackCookie);
   4305             if(mRawMapped[cnt] == NULL) {
   4306                 ALOGE("Failed to get camera memory for mRawMapped heap index: %d", cnt);
   4307                 return false;
   4308             }else{
   4309                ALOGI("Received following info for raw mapped data:%p,handle:%p, size:%d,release:%p",
   4310                mRawMapped[cnt]->data ,mRawMapped[cnt]->handle, mRawMapped[cnt]->size, mRawMapped[cnt]->release);
   4311             }
   4312             // Register Raw frames
   4313             ALOGI("Registering buffer %d with fd :%d with kernel",cnt,mRawfd[cnt]);
   4314             int active = (cnt < ACTIVE_ZSL_BUFFERS);  // TODO check ?
   4315             register_buf(mJpegMaxSize,
   4316                 mRawSize,
   4317                 mCbCrOffsetRaw,
   4318                 mYOffset,
   4319                 mRawfd[cnt],0,
   4320                 (uint8_t *)mRawMapped[cnt]->data,
   4321                 MSM_PMEM_MAINIMG,
   4322                 active);
   4323         }
   4324         // Create Jpeg memory for snapshot
   4325         if (initJpegHeap)
   4326         {
   4327             for(int cnt = 0; cnt < numberOfJpegBuffers; cnt++)
   4328             {
   4329                 ALOGI("%s  Jpeg memory index: %d , fd is %d ", __func__, cnt, mJpegfd[cnt]);
   4330                 mJpegMapped[cnt]=mGetMemory(-1, mJpegMaxSize,1,mCallbackCookie);
   4331                 if(mJpegMapped[cnt] == NULL) {
   4332                     ALOGE("Failed to get camera memory for mJpegMapped heap index: %d", cnt);
   4333                     return false;
   4334                 }else{
   4335                    ALOGI("Received following info for jpeg mapped data:%p,handle:%p, size:%d,release:%p",
   4336                    mJpegMapped[cnt]->data ,mJpegMapped[cnt]->handle, mJpegMapped[cnt]->size, mJpegMapped[cnt]->release);
   4337                 }
   4338             }
   4339         }
   4340         // Lock Thumbnail buffers, and register them
   4341         ALOGI("Locking and registering Thumbnail buffer(s)");
   4342         for(int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   4343             // TODO : change , lock all thumbnail buffers
   4344             if((mPreviewWindow != NULL) && (mThumbnailBuffer[cnt] != NULL)) {
   4345                 ALOGI("createsnapshotbuffers : display lock");
   4346                 mDisplayLock.lock();
   4347                 /* Lock the postview buffer before use */
   4348                 ALOGI(" Locking thumbnail/postview buffer %d", cnt);
   4349                 if( (ret = mPreviewWindow->lock_buffer(mPreviewWindow,
   4350                                  mThumbnailBuffer[cnt])) != NO_ERROR) {
   4351                     ALOGE(" Error locking postview buffer. Error = %d ", ret);
   4352                     ALOGE("createsnapshotbuffers : display unlock error");
   4353                     mDisplayLock.unlock();
   4354                     return false;
   4355                 }
   4356                 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t*)(*mThumbnailBuffer[cnt]),
   4357                                                            GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   4358                     ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
   4359                     mDisplayLock.unlock();
   4360                     return -EINVAL;
   4361                 } else {
   4362                     mThumbnailLockState[cnt] = BUFFER_LOCKED;
   4363                 }
   4364                 mDisplayLock.unlock();
   4365                 ALOGE("createsnapshotbuffers : display unlock");
   4366             }
   4367 
   4368             private_handle_t *thumbnailHandle;
   4369             int mBufferSize = previewWidth * previewHeight * 3/2;
   4370             int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4371 
   4372             if(mThumbnailBuffer[cnt]) {
   4373                 thumbnailHandle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   4374                 ALOGI("fd thumbnailhandle fd %d size %d", thumbnailHandle->fd, thumbnailHandle->size);
   4375                 mThumbnailMapped [cnt]= (unsigned int) mmap(0, thumbnailHandle->size, PROT_READ|PROT_WRITE,
   4376                 MAP_SHARED, thumbnailHandle->fd, 0);
   4377                 if((void *)mThumbnailMapped[cnt] == MAP_FAILED){
   4378                     ALOGE(" Couldnt map Thumbnail buffer %d", errno);
   4379                     return false;
   4380                 }
   4381                 register_buf(mBufferSize,
   4382                     mBufferSize, mCbCrOffset, 0,
   4383                     thumbnailHandle->fd,
   4384                     0,
   4385                     (uint8_t *)mThumbnailMapped[cnt],
   4386                     MSM_PMEM_THUMBNAIL,
   4387                     (cnt < ACTIVE_ZSL_BUFFERS));
   4388             }
   4389         } // for loop locking and registering thumbnail buffers
   4390     }  else { // End if Format is Jpeg , start if format is RAW
   4391          if(numberOfRawBuffers ==1) {
   4392              int rawSnapshotSize = mDimension.raw_picture_height * mDimension.raw_picture_width;
   4393 #ifdef USE_ION
   4394             if (allocate_ion_memory(&raw_snapshot_main_ion_fd, &raw_snapshot_alloc, &raw_snapshot_ion_info_fd,
   4395                                     ion_heap, rawSnapshotSize, &mRawSnapshotfd) < 0){
   4396               ALOGE("do_mmap: Open device %s failed!\n",pmem_region);
   4397               return false;
   4398             }
   4399 #else
   4400             mRawSnapshotfd = open(pmem_region, O_RDWR|O_SYNC);
   4401             if (mRawSnapshotfd <= 0) {
   4402                 ALOGE("%s: Open device %s failed for rawnspashot!\n",__func__, pmem_region);
   4403                 return false;
   4404             }
   4405 #endif
   4406             ALOGI("%s  Raw snapshot memory , fd is %d ", __func__, mRawSnapshotfd);
   4407             mRawSnapshotMapped=mGetMemory(mRawSnapshotfd,
   4408                                           rawSnapshotSize,
   4409                                           1,
   4410                                           mCallbackCookie);
   4411             if(mRawSnapshotMapped == NULL) {
   4412                 ALOGE("Failed to get camera memory for mRawSnapshotMapped ");
   4413                 return false;
   4414             }else{
   4415                ALOGI("Received following info for raw mapped data:%p,handle:%p, size:%d,release:%p",
   4416                mRawSnapshotMapped->data ,mRawSnapshotMapped->handle, mRawSnapshotMapped->size, mRawSnapshotMapped->release);
   4417             }
   4418                         // Register Raw frames
   4419             ALOGI("Registering RawSnapshot buffer with fd :%d with kernel",mRawSnapshotfd);
   4420             int active = 1;  // TODO check ?
   4421             register_buf(     rawSnapshotSize,
   4422                               rawSnapshotSize,
   4423                                             0,
   4424                                             0,
   4425                               mRawSnapshotfd,
   4426                                             0,
   4427                               (uint8_t *)mRawSnapshotMapped->data,
   4428                               MSM_PMEM_RAW_MAINIMG,
   4429                                         active);
   4430          } else {
   4431              ALOGE("Multiple raw snapshot capture not supported for now....");
   4432              return false;
   4433          }
   4434     } // end else , if RAW format
   4435     return true;
   4436 }
   4437 bool QualcommCameraHardware::initRaw(bool initJpegHeap)
   4438 {
   4439     const char * pmem_region;
   4440     int ion_heap;
   4441     int postViewBufferSize;
   4442     uint32_t pictureAspectRatio;
   4443     uint32_t i;
   4444     mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
   4445     mActualPictWidth = mPictureWidth;
   4446     mActualPictHeight = mPictureHeight;
   4447     if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) {
   4448         mDimension.picture_width = mPictureWidth;
   4449         mDimension.picture_height = mPictureHeight;
   4450     }
   4451     ALOGV("initRaw E: picture size=%dx%d", mPictureWidth, mPictureHeight);
   4452     int w_scale_factor = (mIs3DModeOn && mSnapshot3DFormat == SIDE_BY_SIDE_FULL) ? 2 : 1;
   4453 
   4454     /* use the default thumbnail sizes */
   4455     mThumbnailHeight = thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   4456     mThumbnailWidth = (mThumbnailHeight * mPictureWidth)/ mPictureHeight;
   4457     /* see if we can get better thumbnail sizes (not mandatory?) */
   4458     pictureAspectRatio = (uint32_t)((mPictureWidth * Q12) / mPictureHeight);
   4459     for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ){
   4460         if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio)
   4461         {
   4462             mThumbnailWidth = thumbnail_sizes[i].width;
   4463             mThumbnailHeight = thumbnail_sizes[i].height;
   4464             break;
   4465         }
   4466     }
   4467     /* calculate thumbnail aspect ratio */
   4468     if(mCurrentTarget == TARGET_MSM7627 ) {
   4469         int thumbnail_aspect_ratio =
   4470         (uint32_t)((mThumbnailWidth * Q12) / mThumbnailHeight);
   4471 
   4472        if (thumbnail_aspect_ratio < pictureAspectRatio) {
   4473 
   4474           /* if thumbnail is narrower than main image, in other words wide mode
   4475            * snapshot then we want to adjust the height of the thumbnail to match
   4476            * the main image aspect ratio. */
   4477            mThumbnailHeight =
   4478            (mThumbnailWidth * Q12) / pictureAspectRatio;
   4479        } else if (thumbnail_aspect_ratio != pictureAspectRatio) {
   4480 
   4481           /* if thumbnail is wider than main image we want to adjust width of the
   4482            * thumbnail to match main image aspect ratio */
   4483            mThumbnailWidth  =
   4484            (mThumbnailHeight * pictureAspectRatio) / Q12;
   4485        }
   4486        /* make the dimensions multiple of 16 - JPEG requirement */
   4487        mThumbnailWidth = FLOOR16(mThumbnailWidth);
   4488        mThumbnailHeight = FLOOR16(mThumbnailHeight);
   4489        ALOGV("the thumbnail sizes are %dx%d",mThumbnailWidth,mThumbnailHeight);
   4490     }
   4491 
   4492     /* calculate postView size */
   4493     mPostviewWidth = mThumbnailWidth;
   4494     mPostviewHeight = mThumbnailHeight;
   4495     /* Try to keep the postview dimensions near to preview for better
   4496      * performance and userexperience. If the postview and preview dimensions
   4497      * are same, then we can try to use the same overlay of preview for
   4498      * postview also. If not, we need to reset the overlay for postview.
   4499      * we will be getting the same dimensions for preview and postview
   4500      * in most of the cases. The only exception is for applications
   4501      * which won't use optimalPreviewSize based on picture size.
   4502     */
   4503     if((mPictureHeight >= previewHeight) &&
   4504        (mCurrentTarget != TARGET_MSM7627) && !mIs3DModeOn) {
   4505         mPostviewHeight = previewHeight;
   4506         mPostviewWidth = (previewHeight * mPictureWidth) / mPictureHeight;
   4507     }else if(mActualPictHeight < mThumbnailHeight){
   4508         mPostviewHeight = THUMBNAIL_SMALL_HEIGHT;
   4509         mPostviewWidth = (THUMBNAIL_SMALL_HEIGHT * mActualPictWidth)/ mActualPictHeight;
   4510         mThumbnailWidth = mPostviewWidth;
   4511         mThumbnailHeight = mPostviewHeight;
   4512     }
   4513 
   4514     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
   4515         mDimension.main_img_format = CAMERA_YUV_420_NV21_ADRENO;
   4516         mDimension.thumb_format = CAMERA_YUV_420_NV21_ADRENO;
   4517     }
   4518 
   4519     mDimension.ui_thumbnail_width = mPostviewWidth;
   4520     mDimension.ui_thumbnail_height = mPostviewHeight;
   4521 
   4522     // mDimension will be filled with thumbnail_width, thumbnail_height,
   4523     // orig_picture_dx, and orig_picture_dy after this function call. We need to
   4524     // keep it for jpeg_encoder_encode.
   4525     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   4526                                sizeof(cam_ctrl_dimension_t), &mDimension);
   4527 
   4528     if(!ret) {
   4529         ALOGE("initRaw X: failed to set dimension");
   4530         return false;
   4531     }
   4532 #if 0
   4533     if (mJpegHeap != NULL) {
   4534         ALOGV("initRaw: clearing old mJpegHeap.");
   4535         mJpegHeap.clear();
   4536     }
   4537 #endif
   4538     //postview buffer initialization
   4539     postViewBufferSize  = mPostviewWidth * w_scale_factor * mPostviewHeight * 3 / 2;
   4540     int CbCrOffsetPostview = PAD_TO_WORD(mPostviewWidth * w_scale_factor * mPostviewHeight);
   4541 
   4542     //Snapshot buffer initialization
   4543     mRawSize = mPictureWidth * w_scale_factor * mPictureHeight * 3 / 2;
   4544     mCbCrOffsetRaw = PAD_TO_WORD(mPictureWidth * w_scale_factor * mPictureHeight);
   4545     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   4546         mRawSize = PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)) +
   4547                             2 * (CEILING32(mPictureWidth * w_scale_factor/2) * CEILING32(mPictureHeight/2));
   4548         mCbCrOffsetRaw = PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight));
   4549     }
   4550 
   4551     //Jpeg buffer initialization
   4552     if( mCurrentTarget == TARGET_MSM7627 ||
   4553        (mCurrentTarget == TARGET_MSM7625A ||
   4554         mCurrentTarget == TARGET_MSM7627A))
   4555         mJpegMaxSize = CEILING16(mPictureWidth * w_scale_factor) * CEILING16(mPictureHeight) * 3 / 2;
   4556     else {
   4557         mJpegMaxSize = mPictureWidth * w_scale_factor * mPictureHeight * 3 / 2;
   4558         if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
   4559             mJpegMaxSize =
   4560                PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)) +
   4561                     2 * (CEILING32(mPictureWidth * w_scale_factor/2) * CEILING32(mPictureHeight/2));
   4562         }
   4563     }
   4564 
   4565     int rotation = mParameters.getInt("rotation");
   4566     char mDeviceName[PROPERTY_VALUE_MAX];
   4567     property_get("ro.hw_plat", mDeviceName, "");
   4568     if(!strcmp(mDeviceName,"7x25A"))
   4569         rotation = (rotation + 90)%360;
   4570 
   4571     if (mIs3DModeOn)
   4572         rotation = 0;
   4573     ret = native_set_parms(CAMERA_PARM_JPEG_ROTATION, sizeof(int), &rotation);
   4574     if(!ret){
   4575         ALOGE("setting camera id failed");
   4576         return false;
   4577     }
   4578     cam_buf_info_t buf_info;
   4579     if(mIs3DModeOn == false)
   4580     {
   4581         buf_info.resolution.width = mPictureWidth * w_scale_factor;
   4582         buf_info.resolution.height = mPictureHeight;
   4583         mCfgControl.mm_camera_get_parm(CAMERA_PARM_BUFFER_INFO, (void *)&buf_info);
   4584         mRawSize = buf_info.size;
   4585         mJpegMaxSize = mRawSize;
   4586         mCbCrOffsetRaw = buf_info.cbcr_offset;
   4587         mYOffset = buf_info.yoffset;
   4588     }
   4589     int mBufferSize;
   4590     int CbCrOffset;
   4591     if(mCurrentTarget != TARGET_MSM7627 && mCurrentTarget != TARGET_MSM7627A){
   4592         mParameters.getPreviewSize(&previewWidth, &previewHeight);
   4593         mBufferSize = previewWidth * previewHeight * 3/2;
   4594         CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4595     }
   4596     else {
   4597         mBufferSize = mPostviewWidth * mPostviewHeight * 3/2;
   4598         CbCrOffset = PAD_TO_WORD(mPostviewWidth * mPostviewHeight);
   4599     }
   4600 
   4601     ALOGV("initRaw: initializing mRawHeap.");
   4602 
   4603     //PostView
   4604     pmem_region = "/dev/pmem_adsp";
   4605     ion_heap = ION_CAMERA_HEAP_ID;
   4606     // Create memory for Raw YUV frames and Jpeg images
   4607     if( createSnapshotMemory(numCapture, numCapture, initJpegHeap) == false )
   4608     {
   4609         ALOGE("ERROR :  initraw , createSnapshotMemory failed");
   4610         return false;
   4611     }
   4612     /* frame all the exif and encode information into encode_params_t */
   4613 
   4614     initImageEncodeParameters(numCapture);
   4615     /* fill main image size, thumbnail size, postview size into capture_params_t*/
   4616     memset(&mImageCaptureParms, 0, sizeof(capture_params_t));
   4617     mImageCaptureParms.num_captures = numCapture;
   4618     mImageCaptureParms.picture_width = mPictureWidth;
   4619     mImageCaptureParms.picture_height = mPictureHeight;
   4620     mImageCaptureParms.postview_width = mPostviewWidth;
   4621     mImageCaptureParms.postview_height = mPostviewHeight;
   4622 
   4623     int width = mParameters.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
   4624     int height = mParameters.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
   4625     if((width != 0) && (height != 0)) {
   4626         mImageCaptureParms.thumbnail_width = mThumbnailWidth;
   4627         mImageCaptureParms.thumbnail_height = mThumbnailHeight;
   4628     } else {
   4629         mImageCaptureParms.thumbnail_width = 0;
   4630         mImageCaptureParms.thumbnail_height = 0;
   4631     }
   4632 
   4633     ALOGI("%s: picture size=%dx%d",__FUNCTION__,
   4634         mImageCaptureParms.picture_width, mImageCaptureParms.picture_height);
   4635     ALOGI("%s: postview size=%dx%d",__FUNCTION__,
   4636         mImageCaptureParms.postview_width, mImageCaptureParms.postview_height);
   4637     ALOGI("%s: thumbnail size=%dx%d",__FUNCTION__,
   4638         mImageCaptureParms.thumbnail_width, mImageCaptureParms.thumbnail_height);
   4639 
   4640     ALOGV("initRaw X");
   4641     return true;
   4642 }
   4643 
   4644 
   4645 void QualcommCameraHardware::deinitRawSnapshot()
   4646 {
   4647     ALOGV("deinitRawSnapshot E");
   4648 
   4649     int rawSnapshotSize = mDimension.raw_picture_height * mDimension.raw_picture_width;
   4650      // Unregister and de allocated memory for Raw Snapshot
   4651     if(mRawSnapshotMapped) {
   4652         register_buf(         rawSnapshotSize,
   4653                               rawSnapshotSize,
   4654                                             0,
   4655                                             0,
   4656                                mRawSnapshotfd,
   4657                                             0,
   4658           (uint8_t *)mRawSnapshotMapped->data,
   4659                          MSM_PMEM_RAW_MAINIMG,
   4660                                         false,
   4661                                         false);
   4662         mRawSnapshotMapped->release(mRawSnapshotMapped);
   4663         mRawSnapshotMapped = NULL;
   4664         close(mRawSnapshotfd);
   4665 #ifdef USE_ION
   4666         deallocate_ion_memory(&raw_snapshot_main_ion_fd, &raw_snapshot_ion_info_fd);
   4667 #endif
   4668     }
   4669     ALOGV("deinitRawSnapshot X");
   4670 }
   4671 
   4672 void QualcommCameraHardware::deinitRaw()
   4673 {
   4674     ALOGV("deinitRaw E");
   4675     ALOGV("deinitRaw , clearing raw memory and jpeg memory");
   4676     for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   4677        if(NULL != mRawMapped[cnt]) {
   4678          ALOGI("Unregister MAIN_IMG");
   4679          register_buf(mJpegMaxSize,
   4680                   mRawSize,mCbCrOffsetRaw,0,
   4681                   mRawfd[cnt],0,
   4682                   (uint8_t *)mRawMapped[cnt]->data,
   4683                   MSM_PMEM_MAINIMG,
   4684                   0, 0);
   4685             mRawMapped[cnt]->release(mRawMapped[cnt]);
   4686             mRawMapped[cnt] = NULL;
   4687             close(mRawfd[cnt]);
   4688 #ifdef USE_ION
   4689             deallocate_ion_memory(&raw_main_ion_fd[cnt], &raw_ion_info_fd[cnt]);
   4690 #endif
   4691         }
   4692     }
   4693     for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS) : numCapture); cnt++) {
   4694         if(NULL != mJpegMapped[cnt]) {
   4695             mJpegMapped[cnt]->release(mJpegMapped[cnt]);
   4696             mJpegMapped[cnt] = NULL;
   4697         }
   4698     }
   4699     if( mPreviewWindow != NULL ) {
   4700         ALOGI("deinitRaw , clearing/cancelling thumbnail buffers:");
   4701         private_handle_t *handle;
   4702         for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   4703             if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) {
   4704                 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   4705                 ALOGI("%s:  Cancelling postview buffer %d ", __FUNCTION__, handle->fd);
   4706                 ALOGI("deinitraw : display lock");
   4707                 mDisplayLock.lock();
   4708                 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) {
   4709                     if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   4710                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   4711                     } else {
   4712                        mThumbnailLockState[cnt] = BUFFER_UNLOCKED;
   4713                     }
   4714                 }
   4715                 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   4716                                                               mThumbnailBuffer[cnt]);
   4717                 if(retVal != NO_ERROR)
   4718                     ALOGE("%s: cancelBuffer failed for postview buffer %d",
   4719                                                      __FUNCTION__, handle->fd);
   4720                    if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   4721                        struct encoder_media_buffer_type * packet =
   4722                                (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   4723                        native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   4724                        metadata_memory[cnt]->release(metadata_memory[cnt]);
   4725                        metadata_memory[cnt] = NULL;
   4726                    }
   4727                 // unregister , unmap and release as well
   4728 
   4729                 int mBufferSize = previewWidth * previewHeight * 3/2;
   4730                 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4731                 if(mThumbnailMapped[cnt]) {
   4732                     ALOGI("%s:  Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd);
   4733                     register_buf(mBufferSize,
   4734                         mBufferSize, mCbCrOffset, 0,
   4735                         handle->fd,
   4736                         0,
   4737                         (uint8_t *)mThumbnailMapped[cnt],
   4738                         MSM_PMEM_THUMBNAIL,
   4739                         false, false);
   4740                      if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) {
   4741                        ALOGE("deinitraw : Error un-mmapping the thumbnail buffer %d", index);
   4742                      }
   4743                      mThumbnailBuffer[cnt] = NULL;
   4744                      mThumbnailMapped[cnt] = NULL;
   4745                 }
   4746                 ALOGI("deinitraw : display unlock");
   4747                 mDisplayLock.unlock();
   4748             }
   4749         }
   4750     }
   4751     ALOGV("deinitRaw X");
   4752 }
   4753 
   4754 void QualcommCameraHardware::relinquishBuffers()
   4755 {
   4756     status_t retVal;
   4757     ALOGV("%s: E ", __FUNCTION__);
   4758     mDisplayLock.lock();
   4759     if( mPreviewWindow != NULL) {
   4760       for(int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   4761          if (BUFFER_LOCKED == frame_buffer[cnt].lockState) {
   4762             ALOGI(" Cancelling preview buffers %d ",frames[cnt].fd);
   4763             if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
   4764                                               (*(frame_buffer[cnt].buffer)))) {
   4765                 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   4766             } else {
   4767                 frame_buffer[cnt].lockState = BUFFER_UNLOCKED;
   4768             }
   4769          }
   4770          retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   4771 	                         frame_buffer[cnt].buffer);
   4772          mPreviewMapped[cnt]->release(mPreviewMapped[cnt]);
   4773          if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   4774              struct encoder_media_buffer_type * packet =
   4775                   (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   4776              native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   4777              metadata_memory[cnt]->release(metadata_memory[cnt]);
   4778              metadata_memory[cnt] = NULL;
   4779          }
   4780          ALOGI("release preview buffers");
   4781          if(retVal != NO_ERROR)
   4782            ALOGE("%s: cancelBuffer failed for preview buffer %d ",
   4783              __FUNCTION__, frames[cnt].fd);
   4784       }
   4785     } else {
   4786       ALOGV(" PreviewWindow is null, will not cancelBuffers ");
   4787     }
   4788     mDisplayLock.unlock();
   4789     ALOGV("%s: X ", __FUNCTION__);
   4790 }
   4791 status_t QualcommCameraHardware::set_PreviewWindow(void* param)
   4792 {
   4793   ALOGV(": set_preview_window");
   4794   preview_stream_ops_t* window = (preview_stream_ops_t*)param;
   4795   return setPreviewWindow(window);
   4796 }
   4797 
   4798 status_t QualcommCameraHardware::setPreviewWindow(preview_stream_ops_t* window)
   4799 {
   4800     status_t retVal = NO_ERROR;
   4801     ALOGV(" %s: E ", __FUNCTION__);
   4802     if( window == NULL) {
   4803         ALOGW(" Setting NULL preview window ");
   4804         /* Current preview window will be invalidated.
   4805          * Release all the buffers back */
   4806         //@TODO: We may need to this to avoid leak
   4807        /*if(mPreviewWindow!=NULL)
   4808          relinquishBuffers();*/
   4809     }
   4810     ALOGI("Set preview window:: ");
   4811     mDisplayLock.lock();
   4812     mPreviewWindow = window;
   4813     mDisplayLock.unlock();
   4814 
   4815     if( (mPreviewWindow != NULL) && mCameraRunning) {
   4816         /* Initial preview in progress. Stop it and start
   4817          * the actual preview */
   4818          stopInitialPreview();
   4819          retVal = getBuffersAndStartPreview();
   4820     }
   4821     ALOGV(" %s : X ", __FUNCTION__ );
   4822     return retVal;
   4823 }
   4824 
   4825 status_t QualcommCameraHardware::getBuffersAndStartPreview() {
   4826     status_t retVal = NO_ERROR;
   4827 	int stride;
   4828     bool all_chnls = false;
   4829     ALOGI(" %s : E ", __FUNCTION__);
   4830     mFrameThreadWaitLock.lock();
   4831     while (mFrameThreadRunning) {
   4832         ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__);
   4833         mFrameThreadWait.wait(mFrameThreadWaitLock);
   4834         ALOGV("%s: old frame thread completed.",__FUNCTION__);
   4835     }
   4836     mFrameThreadWaitLock.unlock();
   4837 
   4838     if( mPreviewWindow!= NULL) {
   4839         ALOGV("%s: Calling native_window_set_buffer", __FUNCTION__);
   4840 
   4841         android_native_buffer_t *mPreviewBuffer;
   4842         int32_t previewFormat;
   4843         const char *str = mParameters.getPreviewFormat();
   4844         int numMinUndequeuedBufs = 0;
   4845 
   4846         int err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,
   4847 	    &numMinUndequeuedBufs);
   4848 
   4849         if (err != 0) {
   4850             ALOGW("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
   4851                     strerror(-err), -err);
   4852             return err;
   4853         }
   4854         mTotalPreviewBufferCount = kPreviewBufferCount + numMinUndequeuedBufs;
   4855 
   4856         previewFormat = attr_lookup(app_preview_formats,
   4857         sizeof(app_preview_formats) / sizeof(str_map), str);
   4858         if (previewFormat ==  NOT_FOUND) {
   4859           previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
   4860         }
   4861 
   4862 	    retVal = mPreviewWindow->set_buffer_count(mPreviewWindow,
   4863 	                     mTotalPreviewBufferCount +
   4864                                 (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture) ); //1);
   4865 
   4866         if(retVal != NO_ERROR) {
   4867             ALOGE("%s: Error while setting buffer count to %d ", __FUNCTION__, kPreviewBufferCount + 1);
   4868             return retVal;
   4869         }
   4870         mParameters.getPreviewSize(&previewWidth, &previewHeight);
   4871 
   4872         retVal = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
   4873 	              previewWidth, previewHeight, previewFormat);
   4874 
   4875         if(retVal != NO_ERROR) {
   4876             ALOGE("%s: Error while setting buffer geometry ", __FUNCTION__);
   4877             return retVal;
   4878         }
   4879 
   4880 #ifdef USE_ION
   4881         mPreviewWindow->set_usage (mPreviewWindow,
   4882             GRALLOC_USAGE_PRIVATE_CAMERA_HEAP |
   4883             GRALLOC_USAGE_PRIVATE_UNCACHED);
   4884 #else
   4885         mPreviewWindow->set_usage (mPreviewWindow,
   4886             GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
   4887             GRALLOC_USAGE_PRIVATE_UNCACHED);
   4888 #endif
   4889         int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4890         int cnt = 0, active = 1;
   4891         int mBufferSize = previewWidth * previewHeight * 3/2;
   4892         for (cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   4893 	            //const native_handle *nh = (native_handle *)malloc (sizeof(native_handle));
   4894 	            buffer_handle_t *bhandle =NULL;// &nh; ;
   4895 	            //buffer_handle_t *bh_handle=&handle;
   4896 	            retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   4897 	                                            &(bhandle),
   4898 	                                            &(stride));
   4899 
   4900 	        if((retVal == NO_ERROR)) {
   4901                 /* Acquire lock on the buffer if it was successfully
   4902                  * dequeued from gralloc */
   4903                 ALOGV(" Locking buffer %d ", cnt);
   4904                 retVal = mPreviewWindow->lock_buffer(mPreviewWindow,
   4905                                             bhandle);
   4906                 // lock the buffer using genlock
   4907                 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*bhandle),
   4908                                                       GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   4909                     ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
   4910                     return -EINVAL;
   4911                 }
   4912                 ALOGI(" Locked buffer %d successfully", cnt);
   4913 	//yyan todo use handle to find out mPreviewBuffer
   4914 
   4915             } else {
   4916                 ALOGE("%s: dequeueBuffer failed for preview buffer. Error = %d",
   4917                       __FUNCTION__, retVal);
   4918                 return retVal;
   4919             }
   4920 			if(retVal == NO_ERROR) {
   4921                 private_handle_t *handle = (private_handle_t *)(*bhandle);//(private_handle_t *)mPreviewBuffer->handle;
   4922                 ALOGI("Handle %p, Fd passed:%d, Base:%p, Size %p",
   4923                 handle,handle->fd,handle->base,handle->size);
   4924 
   4925                 if(handle) {
   4926 
   4927                   //thumbnailHandle = (private_handle_t *)mThumbnailBuffer->handle;
   4928                   ALOGV("fd mmap fd %d size %d", handle->fd, handle->size/*thumbnailHandle->size*/);
   4929                   mPreviewMapped[cnt]= mGetMemory(handle->fd,handle->size,1,mCallbackCookie);
   4930 
   4931                   if((void *)mPreviewMapped[cnt] == NULL){
   4932                       ALOGE(" Failed to get camera memory for  Preview buffer %d ",cnt);
   4933                   }else{
   4934                       ALOGI(" Mapped Preview buffer %d", cnt);
   4935                   }
   4936                   ALOGI("Got the following from get_mem data: %p, handle :%d, release : %p, size: %d",
   4937                        mPreviewMapped[cnt]->data,
   4938                        mPreviewMapped[cnt]->handle,
   4939                        mPreviewMapped[cnt]->release,
   4940                        mPreviewMapped[cnt]->size);
   4941                   ALOGI(" getbuffersandrestartpreview deQ %d", handle->fd);
   4942                   frames[cnt].fd = handle->fd;
   4943                   frames[cnt].buffer = (unsigned int)mPreviewMapped[cnt]->data;//(unsigned int)mPreviewHeap[cnt]->mHeap->base();
   4944                   if(((void *)frames[cnt].buffer == MAP_FAILED)
   4945                      || (frames[cnt].buffer == 0)) {
   4946                       ALOGE("%s: Couldnt map preview buffers", __FUNCTION__);
   4947                       return UNKNOWN_ERROR;
   4948                   }
   4949 
   4950                   if(mPreviewFormat == CAMERA_YUV_420_YV12 && mCurrentTarget != TARGET_MSM7627A) {
   4951                     myv12_params.CbOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4952                     myv12_params.CrOffset = myv12_params.CbOffset + PAD_TO_WORD((previewWidth * previewHeight)/4);
   4953                     ALOGI("CbOffset = 0x%x CrOffset = 0x%x \n",myv12_params.CbOffset, myv12_params.CrOffset);
   4954                     frames[cnt].planar0_off = 0;
   4955                     frames[cnt].planar1_off = myv12_params.CbOffset;
   4956                     frames[cnt].planar2_off = myv12_params.CrOffset;
   4957                     frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
   4958                     all_chnls = true;
   4959                   }else{
   4960                     frames[cnt].planar0_off = 0;
   4961                     frames[cnt].planar1_off= CbCrOffset;
   4962                     frames[cnt].planar2_off = 0;
   4963                     frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
   4964                   }
   4965                   frame_buffer[cnt].frame = &frames[cnt];
   4966                   frame_buffer[cnt].buffer = bhandle;
   4967                   frame_buffer[cnt].size = handle->size;
   4968                   frame_buffer[cnt].lockState = BUFFER_LOCKED;
   4969                   active = (cnt < ACTIVE_PREVIEW_BUFFERS);
   4970 
   4971                   ALOGI("Registering buffer %d with fd :%d with kernel",cnt,handle->fd);
   4972                   register_buf(mBufferSize,
   4973                              mBufferSize, CbCrOffset, 0,
   4974                              handle->fd,
   4975                              0,
   4976                              (uint8_t *)frames[cnt].buffer/*(uint8_t *)mThumbnailMapped*/,
   4977                              MSM_PMEM_PREVIEW,
   4978                              active,true,all_chnls);
   4979                   ALOGI("Came back from register call to kernel");
   4980                 } else
   4981                     ALOGE("%s: setPreviewWindow: Could not get buffer handle", __FUNCTION__);
   4982             } else {
   4983                 ALOGE("%s: lockBuffer failed for preview buffer. Error = %d",
   4984                          __FUNCTION__, retVal);
   4985                 return retVal;
   4986             }
   4987         }
   4988 
   4989 
   4990  // Dequeue Thumbnail/Postview  Buffers here , Consider ZSL/Multishot cases
   4991         for (cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   4992 
   4993             retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   4994                                      &mThumbnailBuffer[cnt], &(stride));
   4995             private_handle_t* handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   4996             ALOGI(" : dequeing thumbnail buffer fd %d", handle->fd);
   4997             if(retVal != NO_ERROR) {
   4998                 ALOGE("%s: dequeueBuffer failed for postview buffer. Error = %d ",
   4999                                                             __FUNCTION__, retVal);
   5000             return retVal;
   5001             }
   5002         }
   5003 
   5004         // Cancel minUndequeuedBufs.
   5005         for (cnt = kPreviewBufferCount; cnt < mTotalPreviewBufferCount; cnt++) {
   5006             if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)(*(frame_buffer[cnt].buffer)))) {
   5007                 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   5008                 return -EINVAL;
   5009             }
   5010             frame_buffer[cnt].lockState = BUFFER_UNLOCKED;
   5011             status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   5012                                 frame_buffer[cnt].buffer);
   5013             ALOGI(" Cancelling preview buffers %d ",frame_buffer[cnt].frame->fd);
   5014         }
   5015     } else {
   5016         ALOGE("%s: Could not get Buffer from Surface", __FUNCTION__);
   5017         return UNKNOWN_ERROR;
   5018     }
   5019     mPreviewBusyQueue.init();
   5020     LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   5021     for(int i=ACTIVE_PREVIEW_BUFFERS ;i < kPreviewBufferCount; i++)
   5022         LINK_camframe_add_frame(CAM_PREVIEW_FRAME,&frames[i]);
   5023 
   5024     mBuffersInitialized = true;
   5025 
   5026     //Starting preview now as the preview buffers are allocated
   5027  //   if(!mPreviewInitialized && !mCameraRunning) {   // TODO just for testing
   5028         ALOGI("setPreviewWindow: Starting preview after buffer allocation");
   5029         startPreviewInternal();
   5030  //   }
   5031     ALOGV(" %s : X ",__FUNCTION__);
   5032     return NO_ERROR;
   5033 }
   5034 void QualcommCameraHardware::release()
   5035 {
   5036     ALOGV("release E");
   5037     Mutex::Autolock l(&mLock);
   5038 #if 0
   5039     {
   5040         Mutex::Autolock checkLock(&singleton_lock);
   5041         if(singleton_releasing){
   5042             ALOGE("ERROR: multiple release!");
   5043             return;
   5044         }
   5045     }
   5046 #endif
   5047     ALOGI("release: mCameraRunning = %d", mCameraRunning);
   5048     if (mCameraRunning) {
   5049         if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
   5050             mRecordFrameLock.lock();
   5051             mReleasedRecordingFrame = true;
   5052             mRecordWait.signal();
   5053             mRecordFrameLock.unlock();
   5054         }
   5055         stopPreviewInternal();
   5056         ALOGI("release: stopPreviewInternal done.");
   5057     }
   5058     LINK_jpeg_encoder_join();
   5059     mm_camera_ops_type_t current_ops_type = (mSnapshotFormat
   5060             == PICTURE_FORMAT_JPEG) ? CAMERA_OPS_CAPTURE_AND_ENCODE
   5061             : CAMERA_OPS_RAW_CAPTURE;
   5062     mCamOps.mm_camera_deinit(current_ops_type, NULL, NULL);
   5063 
   5064     //Signal the snapshot thread
   5065     mJpegThreadWaitLock.lock();
   5066     mJpegThreadRunning = false;
   5067     mJpegThreadWait.signal();
   5068     mJpegThreadWaitLock.unlock();
   5069 
   5070     // Wait for snapshot thread to complete before clearing the
   5071     // resources.
   5072     mSnapshotThreadWaitLock.lock();
   5073     while (mSnapshotThreadRunning) {
   5074         ALOGV("release: waiting for old snapshot thread to complete.");
   5075         mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
   5076         ALOGV("release: old snapshot thread completed.");
   5077     }
   5078     mSnapshotThreadWaitLock.unlock();
   5079 
   5080     {
   5081         Mutex::Autolock l (&mRawPictureHeapLock);
   5082         deinitRaw();
   5083     }
   5084 
   5085     deinitRawSnapshot();
   5086     ALOGI("release: clearing resources done.");
   5087     if(mCurrentTarget == TARGET_MSM8660) {
   5088        ALOGV("release : Clearing the mThumbnailHeap and mDisplayHeap");
   5089        mLastPreviewFrameHeap.clear();
   5090        mLastPreviewFrameHeap = NULL;
   5091        mThumbnailHeap.clear();
   5092        mThumbnailHeap = NULL;
   5093        mPostviewHeap.clear();
   5094        mPostviewHeap = NULL;
   5095        mDisplayHeap.clear();
   5096        mDisplayHeap = NULL;
   5097     }
   5098     LINK_mm_camera_deinit();
   5099     if(fb_fd >= 0) {
   5100         close(fb_fd);
   5101         fb_fd = -1;
   5102     }
   5103     singleton_lock.lock();
   5104     singleton_releasing = true;
   5105     singleton_releasing_start_time = systemTime();
   5106     singleton_lock.unlock();
   5107 
   5108     ALOGI("release X: mCameraRunning = %d, mFrameThreadRunning = %d", mCameraRunning, mFrameThreadRunning);
   5109     ALOGI("mVideoThreadRunning = %d, mSnapshotThreadRunning = %d, mJpegThreadRunning = %d", mVideoThreadRunning, mSnapshotThreadRunning, mJpegThreadRunning);
   5110     ALOGI("camframe_timeout_flag = %d, mAutoFocusThreadRunning = %d", camframe_timeout_flag, mAutoFocusThreadRunning);
   5111     mFrameThreadWaitLock.lock();
   5112     while (mFrameThreadRunning) {
   5113         ALOGV("release: waiting for old frame thread to complete.");
   5114         mFrameThreadWait.wait(mFrameThreadWaitLock);
   5115         ALOGV("release: old frame thread completed.");
   5116     }
   5117     mFrameThreadWaitLock.unlock();
   5118 
   5119 }
   5120 
   5121 QualcommCameraHardware::~QualcommCameraHardware()
   5122 {
   5123     ALOGI("~QualcommCameraHardware E");
   5124 
   5125     //singleton_lock.lock();
   5126     if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660 ) {
   5127         delete [] recordframes;
   5128         recordframes = NULL;
   5129         delete [] record_buffers_tracking_flag;
   5130     }
   5131     mMMCameraDLRef.clear();
   5132     //singleton.clear();
   5133     //singleton_releasing = false;
   5134     //singleton_releasing_start_time = 0;
   5135     //singleton_wait.signal();
   5136     //singleton_lock.unlock();
   5137     ALOGI("~QualcommCameraHardware X");
   5138 }
   5139 #if 0
   5140 IMemoryHeap* QualcommCameraHardware::getRawHeap() const
   5141 {
   5142 #if 0
   5143     ALOGV("getRawHeap");
   5144     return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
   5145 #endif
   5146 }
   5147 
   5148 IMemoryHeap* QualcommCameraHardware::getPreviewHeap() const
   5149 {
   5150 #if 0
   5151     ALOGV("getPreviewHeap");
   5152     return mPreviewHeap[0] != NULL ? mPreviewHeap[0]->mHeap : NULL;
   5153     if(mIs3DModeOn != true) {
   5154         if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) &&
   5155             ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 ) &&
   5156             previewWidth%32 != 0 )
   5157             return mYV12Heap->mHeap;
   5158 
   5159         return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
   5160     } else
   5161         return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL;
   5162 
   5163 #endif
   5164 }
   5165 #endif
   5166 #if 0
   5167 status_t QualcommCameraHardware::startInitialPreview() {
   5168    ALOGV(" %s : E", __FUNCTION__);
   5169    const char * pmem_region = "/dev/pmem_smipool";
   5170    int initialPreviewWidth = INITIAL_PREVIEW_WIDTH;
   5171    int initialPreviewHeight = INITIAL_PREVIEW_HEIGHT;
   5172    int previewFrameSize = initialPreviewWidth * initialPreviewHeight * 3/2;
   5173    int CbCrOffset = PAD_TO_WORD(initialPreviewWidth * initialPreviewHeight);
   5174    mFrameThreadWaitLock.lock();
   5175     while (mFrameThreadRunning) {
   5176         ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__);
   5177         mFrameThreadWait.wait(mFrameThreadWaitLock);
   5178         ALOGV("%s: old frame thread completed.",__FUNCTION__);
   5179     }
   5180     mFrameThreadWaitLock.unlock();
   5181 
   5182     mInitialPreviewHeap = new PmemPool(pmem_region,
   5183                                MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   5184                                 MSM_PMEM_PREVIEW,
   5185                                 previewFrameSize,
   5186                                 kPreviewBufferCount,
   5187                                 previewFrameSize,
   5188                                 CbCrOffset,
   5189                                 0,
   5190                                 "initial preview");
   5191 
   5192     mDimension.display_width  = initialPreviewWidth;
   5193     mDimension.display_height = initialPreviewHeight;
   5194     mDimension.video_width  = initialPreviewWidth;
   5195     mDimension.video_height = initialPreviewHeight;
   5196     mDimension.display_luma_width = initialPreviewWidth;
   5197     mDimension.display_luma_height = initialPreviewHeight;
   5198     mDimension.display_chroma_width = initialPreviewWidth;
   5199     mDimension.display_chroma_height = initialPreviewHeight;
   5200     mDimension.orig_video_width = initialPreviewWidth;
   5201     mDimension.orig_video_height = initialPreviewHeight;
   5202     ALOGV("mDimension.prev_format = %d", mDimension.prev_format);
   5203     ALOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
   5204     ALOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
   5205     ALOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
   5206     ALOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
   5207 
   5208     native_set_parms(CAMERA_PARM_DIMENSION,
   5209               sizeof(cam_ctrl_dimension_t), &mDimension);
   5210     ALOGV(" %s : mDimension.video_width = %d mDimension.video_height = %d", __FUNCTION__,
   5211              mDimension.video_width, mDimension.video_height);
   5212     mRecordFrameSize = previewFrameSize;
   5213     ALOGV("mRecordFrameSize = %d", mRecordFrameSize);
   5214 
   5215     mRecordHeap = new PmemPool(pmem_region,
   5216                                MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   5217                                MSM_PMEM_VIDEO,
   5218                                previewFrameSize,
   5219                                kRecordBufferCount,
   5220                                previewFrameSize,
   5221                                CbCrOffset,
   5222                                0,
   5223                                "initial record");
   5224 
   5225     if (!mRecordHeap->initialized()) {
   5226         mRecordHeap.clear();
   5227         ALOGE("%s X: could not initialize record heap.", __FUNCTION__);
   5228         return false;
   5229     }
   5230     {
   5231         Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5232         mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5233     }
   5234 
   5235     ALOGV(" %s : X", __FUNCTION__);
   5236     return NO_ERROR;
   5237 }
   5238 #endif
   5239 status_t QualcommCameraHardware::startPreviewInternal()
   5240 {
   5241    ALOGV("in startPreviewInternal : E");
   5242    if (!mBuffersInitialized) {
   5243      ALOGE("startPreviewInternal: Buffers not allocated. Cannot start preview");
   5244      return NO_ERROR;
   5245    }
   5246    mPreviewStopping = false;
   5247 #if 0
   5248    if(mZslEnable && !mZslPanorama){
   5249        ALOGE("start zsl Preview called");
   5250        mCamOps.mm_camera_start(CAMERA_OPS_ZSL_STREAMING_CB,NULL, NULL);
   5251        if (mCurrentTarget == TARGET_MSM8660) {
   5252            if(mLastPreviewFrameHeap != NULL)
   5253            mLastPreviewFrameHeap.clear();
   5254     }
   5255     }
   5256 #endif
   5257     if(mCameraRunning) {
   5258         ALOGV("startPreview X: preview already running.");
   5259         return NO_ERROR;
   5260     }
   5261     if(mZslEnable){
   5262          //call init
   5263          ALOGI("ZSL Enable called");
   5264          uint8_t is_zsl = 1;
   5265           mm_camera_status_t status;
   5266           if(MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_ZSL_ENABLE,
   5267                      (void *)&is_zsl)){
   5268               ALOGE("ZSL Enable failed");
   5269           return UNKNOWN_ERROR;
   5270           }
   5271     }
   5272 
   5273     if (!mPreviewInitialized) {
   5274         mLastQueuedFrame = NULL;
   5275         mPreviewInitialized = initPreview();
   5276         if (!mPreviewInitialized) {
   5277             ALOGE("startPreview X initPreview failed.  Not starting preview.");
   5278             mPreviewBusyQueue.deinit();
   5279             return UNKNOWN_ERROR;
   5280         }
   5281     }
   5282 
   5283     /* For 3D mode, start the video output, as this need to be
   5284      * used for display also.
   5285      */
   5286     if(mIs3DModeOn) {
   5287         startRecordingInternal();
   5288         if(!mVideoThreadRunning) {
   5289             ALOGE("startPreview X startRecording failed.  Not starting preview.");
   5290             return UNKNOWN_ERROR;
   5291         }
   5292     }
   5293 
   5294     {
   5295         Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5296         if(( mCurrentTarget != TARGET_MSM7630 ) &&
   5297                 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
   5298             mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL);
   5299         else {
   5300             if(!mZslEnable){
   5301                 ALOGI("Calling CAMERA_OPS_STREAMING_VIDEO");
   5302                 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5303                 ALOGI(": Calling CAMERA_OPS_STREAMING_VIDEO %d", mCameraRunning);
   5304         }else {
   5305                 initZslParameter();
   5306                  mCameraRunning = false;
   5307                  if (MM_CAMERA_SUCCESS == mCamOps.mm_camera_init(CAMERA_OPS_STREAMING_ZSL,
   5308                         (void *)&mZslParms, NULL)) {
   5309                         //register buffers for ZSL
   5310                         bool status = initZslBuffers(true);
   5311                         if(status != true) {
   5312                              ALOGE("Failed to allocate ZSL buffers");
   5313                              return false;
   5314                         }
   5315                         if(MM_CAMERA_SUCCESS == mCamOps.mm_camera_start(CAMERA_OPS_STREAMING_ZSL,NULL, NULL)){
   5316                             mCameraRunning = true;
   5317                         }
   5318                 }
   5319                 if(mCameraRunning == false)
   5320                     ALOGE("Starting  ZSL CAMERA_OPS_STREAMING_ZSL failed!!!");
   5321             }
   5322         }
   5323     }
   5324 
   5325     if(!mCameraRunning) {
   5326         deinitPreview();
   5327         if(mZslEnable){
   5328             //deinit
   5329             ALOGI("ZSL DISABLE called");
   5330            uint8_t is_zsl = 0;
   5331             mm_camera_status_t status;
   5332             if( MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_ZSL_ENABLE,
   5333                      (void *)&is_zsl)){
   5334                 ALOGE("ZSL_Disable failed!!");
   5335                 return UNKNOWN_ERROR;
   5336             }
   5337         }
   5338         /* Flush the Busy Q */
   5339         cam_frame_flush_video();
   5340         /* Need to flush the free Qs as these are initalized in initPreview.*/
   5341         LINK_camframe_release_all_frames(CAM_VIDEO_FRAME);
   5342         LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   5343         mPreviewInitialized = false;
   5344         mOverlayLock.lock();
   5345         //mOverlay = NULL;
   5346         mOverlayLock.unlock();
   5347         ALOGE("startPreview X: native_start_ops: CAMERA_OPS_STREAMING_PREVIEW ioctl failed!");
   5348         return UNKNOWN_ERROR;
   5349     }
   5350 
   5351     //Reset the Gps Information
   5352     exif_table_numEntries = 0;
   5353     previewWidthToNativeZoom = previewWidth;
   5354     previewHeightToNativeZoom = previewHeight;
   5355 
   5356     ALOGV("startPreviewInternal X");
   5357     return NO_ERROR;
   5358 }
   5359 status_t QualcommCameraHardware::startInitialPreview() {
   5360    mCameraRunning = DUMMY_CAMERA_STARTED;
   5361    return NO_ERROR;
   5362 }
   5363 status_t QualcommCameraHardware::startPreview()
   5364 {
   5365   status_t result;
   5366   ALOGV("startPreview E");
   5367   Mutex::Autolock l(&mLock);
   5368   if( mPreviewWindow == NULL) {
   5369     /* startPreview has been called before setting the preview
   5370      * window. Start the camera with initial buffers because the
   5371      * CameraService expects the preview to be enabled while
   5372      * setting a valid preview window */
   5373     ALOGV(" %s : Starting preview with initial buffers ", __FUNCTION__);
   5374     result = startInitialPreview();
   5375   } else {
   5376       /* startPreview has been issued after a valid preview window
   5377        * is set. Get the preview buffers from gralloc and start
   5378        * preview normally */
   5379     ALOGV(" %s : Starting normal preview ", __FUNCTION__);
   5380     result = getBuffersAndStartPreview();
   5381   }
   5382   ALOGV("startPreview X");
   5383   return result;
   5384 }
   5385 
   5386 void QualcommCameraHardware::stopInitialPreview() {
   5387    mCameraRunning = 0;//!native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5388 #if 0
   5389     ALOGV(" %s : E ", __FUNCTION__);
   5390     if (mCameraRunning) {
   5391         ALOGV(" %s : Camera was running. Stopping ", __FUNCTION__);
   5392         {
   5393             Mutex::Autolock l(&mCamframeTimeoutLock);
   5394            {
   5395       Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5396       if(!camframe_timeout_flag) {
   5397                     mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5398                 }
   5399        }
   5400     }
   5401     mInitialPreviewHeap.clear();
   5402     mRecordHeap.clear();
   5403   }
   5404   ALOGV(" %s : X ", __FUNCTION__);
   5405 #endif
   5406 }
   5407 
   5408 void QualcommCameraHardware::stopPreviewInternal()
   5409 {
   5410     ALOGV("stopPreviewInternal E: %d", mCameraRunning);
   5411     mPreviewStopping = true;
   5412     if (mCameraRunning && mPreviewWindow!=NULL) {
   5413         /* For 3D mode, we need to exit the video thread.*/
   5414         if(mIs3DModeOn) {
   5415             mRecordingState = 0;
   5416             mVideoThreadWaitLock.lock();
   5417             ALOGI("%s: 3D mode, exit video thread", __FUNCTION__);
   5418             mVideoThreadExit = 1;
   5419             mVideoThreadWaitLock.unlock();
   5420 
   5421             pthread_mutex_lock(&(g_busy_frame_queue.mut));
   5422             pthread_cond_signal(&(g_busy_frame_queue.wait));
   5423             pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   5424         }
   5425 
   5426         // Cancel auto focus.
   5427         {
   5428             if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
   5429                 cancelAutoFocusInternal();
   5430             }
   5431         }
   5432 
   5433         // make mSmoothzoomThreadExit true
   5434         mSmoothzoomThreadLock.lock();
   5435         mSmoothzoomThreadExit = true;
   5436         mSmoothzoomThreadLock.unlock();
   5437         // singal smooth zoom thread , so that it can exit gracefully
   5438         mSmoothzoomThreadWaitLock.lock();
   5439         if(mSmoothzoomThreadRunning)
   5440             mSmoothzoomThreadWait.signal();
   5441 
   5442         mSmoothzoomThreadWaitLock.unlock();
   5443 
   5444         Mutex::Autolock l(&mCamframeTimeoutLock);
   5445         {
   5446             Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5447             if(!camframe_timeout_flag) {
   5448                 if (( mCurrentTarget != TARGET_MSM7630 ) &&
   5449                         (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
   5450                          mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL);
   5451                 else{
   5452                     if(!mZslEnable){
   5453                         ALOGI("%s ops_streaming mCameraRunning b= %d",__FUNCTION__, mCameraRunning);
   5454                         mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5455                         ALOGI("%s ops_streaming mCameraRunning = %d",__FUNCTION__, mCameraRunning);
   5456                     }else {
   5457                         mCameraRunning = true;
   5458                         if(MM_CAMERA_SUCCESS == mCamOps.mm_camera_stop(CAMERA_OPS_STREAMING_ZSL,NULL, NULL)){
   5459                             deinitZslBuffers();
   5460                             if (MM_CAMERA_SUCCESS == mCamOps.mm_camera_deinit(CAMERA_OPS_STREAMING_ZSL,
   5461                                     (void *)&mZslParms, NULL)) {
   5462                                 mCameraRunning = false;
   5463                             }
   5464                         }
   5465                         if(mCameraRunning ==true)
   5466                             ALOGE("Starting  ZSL CAMERA_OPS_STREAMING_ZSL failed!!!");
   5467                     }
   5468                 }
   5469             } else {
   5470                 /* This means that the camframetimeout was issued.
   5471                  * But we did not issue native_stop_preview(), so we
   5472                  * need to update mCameraRunning to indicate that
   5473                  * Camera is no longer running. */
   5474                 ALOGE("%s, : MAKE MCAMER_RUNNING FALSE!!!",__FUNCTION__);
   5475                 mCameraRunning = 0;
   5476             }
   5477         }
   5478     }
   5479     /* in 3D mode, wait for the video thread before clearing resources.*/
   5480     if(mIs3DModeOn) {
   5481         mVideoThreadWaitLock.lock();
   5482         while (mVideoThreadRunning) {
   5483             ALOGI("%s: waiting for video thread to complete.", __FUNCTION__);
   5484             mVideoThreadWait.wait(mVideoThreadWaitLock);
   5485             ALOGI("%s : video thread completed.", __FUNCTION__);
   5486         }
   5487         mVideoThreadWaitLock.unlock();
   5488     }
   5489     ALOGI("%s, J_mCameraRunning = %d", __FUNCTION__, mCameraRunning);
   5490     if (!mCameraRunning) {
   5491         ALOGI("%s, before calling deinitpre mPreviewInitialized = %d", __FUNCTION__, mPreviewInitialized);
   5492         if(mPreviewInitialized) {
   5493             ALOGI("before calling deinitpreview");
   5494             deinitPreview();
   5495             if( ( mCurrentTarget == TARGET_MSM7630 ) ||
   5496                 (mCurrentTarget == TARGET_QSD8250) ||
   5497                 (mCurrentTarget == TARGET_MSM8660)) {
   5498                 mVideoThreadWaitLock.lock();
   5499                 ALOGV("in stopPreviewInternal: making mVideoThreadExit 1");
   5500                 mVideoThreadExit = 1;
   5501                 mVideoThreadWaitLock.unlock();
   5502                 //720p : signal the video thread , and check in video thread
   5503                 //if stop is called, if so exit video thread.
   5504                 pthread_mutex_lock(&(g_busy_frame_queue.mut));
   5505                 pthread_cond_signal(&(g_busy_frame_queue.wait));
   5506                 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   5507 
   5508                 ALOGI(" flush video and release all frames");
   5509                 /* Flush the Busy Q */
   5510                 cam_frame_flush_video();
   5511                 /* Flush the Free Q */
   5512                 LINK_camframe_release_all_frames(CAM_VIDEO_FRAME);
   5513             }
   5514             mPreviewInitialized = false;
   5515         }
   5516     }
   5517     else ALOGI("stopPreviewInternal: Preview is stopped already");
   5518 
   5519     ALOGV("stopPreviewInternal X: %d", mCameraRunning);
   5520 }
   5521 
   5522 void QualcommCameraHardware::stopPreview()
   5523 {
   5524     ALOGV("stopPreview: E");
   5525     Mutex::Autolock l(&mLock);
   5526     {
   5527         if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
   5528             return;
   5529     }
   5530     if( mSnapshotThreadRunning ) {
   5531         ALOGV("In stopPreview during snapshot");
   5532         return;
   5533     }
   5534     if( mPreviewWindow != NULL ) {
   5535         private_handle_t *handle;
   5536         for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   5537             if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) {
   5538                 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   5539                 ALOGI("%s:  Cancelling postview buffer %d ", __FUNCTION__, handle->fd);
   5540                 ALOGI("stoppreview : display lock");
   5541                 mDisplayLock.lock();
   5542                 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) {
   5543                     if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   5544                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   5545                        mDisplayLock.unlock();
   5546                        continue;
   5547                     } else {
   5548                        mThumbnailLockState[cnt] = BUFFER_UNLOCKED;
   5549                     }
   5550                 }
   5551                 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   5552                                                               mThumbnailBuffer[cnt]);
   5553                 ALOGI("stopPreview : after cancelling thumbnail buffer");
   5554                 if(retVal != NO_ERROR)
   5555                     ALOGE("%s: cancelBuffer failed for postview buffer %d",
   5556                                                      __FUNCTION__, handle->fd);
   5557                 // unregister , unmap and release as well
   5558                 int mBufferSize = previewWidth * previewHeight * 3/2;
   5559                 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   5560                 if(mThumbnailMapped[cnt]  && (mSnapshotFormat == PICTURE_FORMAT_JPEG)
   5561                           || mZslEnable) {
   5562                     ALOGI("%s:  Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd);
   5563                     register_buf(mBufferSize,
   5564                         mBufferSize, mCbCrOffset, 0,
   5565                         handle->fd,
   5566                         0,
   5567                         (uint8_t *)mThumbnailMapped[cnt],
   5568                         MSM_PMEM_THUMBNAIL,
   5569                         false, false);
   5570                     if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) {
   5571                       ALOGE("StopPreview : Error un-mmapping the thumbnail buffer %d", index);
   5572                     }
   5573                     mThumbnailMapped[cnt] = NULL;
   5574                  }
   5575                 mThumbnailBuffer[cnt] = NULL;
   5576                 ALOGI("stoppreview : display unlock");
   5577                 mDisplayLock.unlock();
   5578           }
   5579        }
   5580     }
   5581     stopPreviewInternal();
   5582     ALOGV("stopPreview: X");
   5583 }
   5584 
   5585 void QualcommCameraHardware::runAutoFocus()
   5586 {
   5587     bool status = true;
   5588     void *libhandle = NULL;
   5589     isp3a_af_mode_t afMode = AF_MODE_AUTO;
   5590 
   5591     mAutoFocusThreadLock.lock();
   5592     // Skip autofocus if focus mode is infinity.
   5593 
   5594     const char * focusMode = mParameters.get(QCameraParameters::KEY_FOCUS_MODE);
   5595     if ((mParameters.get(QCameraParameters::KEY_FOCUS_MODE) == 0)
   5596            || (strcmp(focusMode, QCameraParameters::FOCUS_MODE_INFINITY) == 0)
   5597            || (strcmp(focusMode, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0)) {
   5598         goto done;
   5599     }
   5600 
   5601     if(!libmmcamera){
   5602         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   5603         mAutoFocusThreadRunning = false;
   5604         mAutoFocusThreadLock.unlock();
   5605         return;
   5606     }
   5607 
   5608     afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
   5609                                 sizeof(focus_modes) / sizeof(str_map),
   5610                                 mParameters.get(QCameraParameters::KEY_FOCUS_MODE));
   5611 
   5612     /* This will block until either AF completes or is cancelled. */
   5613     ALOGV("af start (mode %d)", afMode);
   5614     status_t err;
   5615     err = mAfLock.tryLock();
   5616     if(err == NO_ERROR) {
   5617         {
   5618             Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5619             if(mCameraRunning){
   5620                 ALOGV("Start AF");
   5621                 status =  native_start_ops(CAMERA_OPS_FOCUS ,(void *)&afMode);
   5622             }else{
   5623                 ALOGV("As Camera preview is not running, AF not issued");
   5624                 status = false;
   5625             }
   5626         }
   5627         mAfLock.unlock();
   5628     }
   5629     else{
   5630         //AF Cancel would have acquired the lock,
   5631         //so, no need to perform any AF
   5632         ALOGV("As Cancel auto focus is in progress, auto focus request "
   5633                 "is ignored");
   5634         status = FALSE;
   5635     }
   5636     {
   5637         Mutex::Autolock pl(&mParametersLock);
   5638         if(mHasAutoFocusSupport && (updateFocusDistances(focusMode) != NO_ERROR)) {
   5639             ALOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, focusMode);
   5640         }
   5641     }
   5642 
   5643     ALOGV("af done: %d", (int)status);
   5644 
   5645 done:
   5646     mAutoFocusThreadRunning = false;
   5647     mAutoFocusThreadLock.unlock();
   5648 
   5649     mCallbackLock.lock();
   5650     bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
   5651     camera_notify_callback cb = mNotifyCallback;
   5652     void *data = mCallbackCookie;
   5653     mCallbackLock.unlock();
   5654     if (autoFocusEnabled)
   5655         cb(CAMERA_MSG_FOCUS, status, 0, data);
   5656 
   5657 }
   5658 
   5659 status_t QualcommCameraHardware::cancelAutoFocusInternal()
   5660 {
   5661     ALOGV("cancelAutoFocusInternal E");
   5662     bool afRunning = true;
   5663 
   5664     if(!mHasAutoFocusSupport){
   5665         ALOGV("cancelAutoFocusInternal X");
   5666         return NO_ERROR;
   5667     }
   5668 
   5669     status_t rc = NO_ERROR;
   5670     status_t err;
   5671 
   5672     do {
   5673       err = mAfLock.tryLock();
   5674       if(err == NO_ERROR) {
   5675           //Got Lock, means either AF hasn't started or
   5676           // AF is done. So no need to cancel it, just change the state
   5677           ALOGV("Auto Focus is not in progress, Cancel Auto Focus is ignored");
   5678           mAfLock.unlock();
   5679 
   5680           mAutoFocusThreadLock.lock();
   5681           afRunning = mAutoFocusThreadRunning;
   5682           mAutoFocusThreadLock.unlock();
   5683           if(afRunning) {
   5684             usleep( 5000 );
   5685           }
   5686       }
   5687     } while ( err == NO_ERROR && afRunning );
   5688     if(afRunning) {
   5689         //AF is in Progess, So cancel it
   5690         ALOGV("Lock busy...cancel AF");
   5691         rc = native_stop_ops(CAMERA_OPS_FOCUS, NULL) ?
   5692           NO_ERROR : UNKNOWN_ERROR;
   5693 
   5694         /*now just wait for auto focus thread to be finished*/
   5695         mAutoFocusThreadLock.lock();
   5696         mAutoFocusThreadLock.unlock();
   5697     }
   5698     ALOGV("cancelAutoFocusInternal X: %d", rc);
   5699     return rc;
   5700 }
   5701 
   5702 void *auto_focus_thread(void *user)
   5703 {
   5704     ALOGV("auto_focus_thread E");
   5705     CAMERA_HAL_UNUSED(user);
   5706     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   5707     if (obj != 0) {
   5708         obj->runAutoFocus();
   5709     }
   5710     else ALOGW("not starting autofocus: the object went away!");
   5711     ALOGV("auto_focus_thread X");
   5712     return NULL;
   5713 }
   5714 
   5715 status_t QualcommCameraHardware::autoFocus()
   5716 {
   5717     ALOGV("autoFocus E");
   5718     Mutex::Autolock l(&mLock);
   5719 
   5720     if(!mHasAutoFocusSupport){
   5721        /*
   5722         * If autofocus is not supported HAL defaults
   5723         * focus mode to infinity and supported mode to
   5724         * infinity also. In this mode and fixed mode app
   5725         * should not call auto focus.
   5726         */
   5727         ALOGI("Auto Focus not supported");
   5728         ALOGV("autoFocus X");
   5729         return INVALID_OPERATION;
   5730     }
   5731     {
   5732         mAutoFocusThreadLock.lock();
   5733         if (!mAutoFocusThreadRunning) {
   5734 
   5735             // Create a detached thread here so that we don't have to wait
   5736             // for it when we cancel AF.
   5737             pthread_t thr;
   5738             pthread_attr_t attr;
   5739             pthread_attr_init(&attr);
   5740             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   5741             mAutoFocusThreadRunning =
   5742                 !pthread_create(&thr, &attr,
   5743                                 auto_focus_thread, NULL);
   5744             if (!mAutoFocusThreadRunning) {
   5745                 ALOGE("failed to start autofocus thread");
   5746                 mAutoFocusThreadLock.unlock();
   5747                 return UNKNOWN_ERROR;
   5748             }
   5749         }
   5750         mAutoFocusThreadLock.unlock();
   5751     }
   5752 
   5753     ALOGV("autoFocus X");
   5754     return NO_ERROR;
   5755 }
   5756 
   5757 status_t QualcommCameraHardware::cancelAutoFocus()
   5758 {
   5759     ALOGV("cancelAutoFocus E");
   5760     Mutex::Autolock l(&mLock);
   5761 
   5762     int rc = NO_ERROR;
   5763     if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
   5764         rc = cancelAutoFocusInternal();
   5765     }
   5766 
   5767     ALOGV("cancelAutoFocus X");
   5768     return rc;
   5769 }
   5770 
   5771 void QualcommCameraHardware::runSnapshotThread(void *data)
   5772 {
   5773     bool ret = true;
   5774     CAMERA_HAL_UNUSED(data);
   5775     ALOGI("runSnapshotThread E");
   5776 
   5777     if(!libmmcamera){
   5778         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   5779     }
   5780     mSnapshotCancelLock.lock();
   5781     if(mSnapshotCancel == true) {
   5782         mSnapshotCancel = false;
   5783         mSnapshotCancelLock.unlock();
   5784         ALOGI("%s: cancelpicture has been called..so abort taking snapshot", __FUNCTION__);
   5785         deinitRaw();
   5786         mInSnapshotModeWaitLock.lock();
   5787         mInSnapshotMode = false;
   5788         mInSnapshotModeWait.signal();
   5789         mInSnapshotModeWaitLock.unlock();
   5790         mSnapshotThreadWaitLock.lock();
   5791         mSnapshotThreadRunning = false;
   5792         mSnapshotThreadWait.signal();
   5793         mSnapshotThreadWaitLock.unlock();
   5794         return;
   5795     }
   5796     mSnapshotCancelLock.unlock();
   5797 
   5798     mJpegThreadWaitLock.lock();
   5799     mJpegThreadRunning = true;
   5800     mJpegThreadWait.signal();
   5801     mJpegThreadWaitLock.unlock();
   5802     mm_camera_ops_type_t current_ops_type = (mSnapshotFormat == PICTURE_FORMAT_JPEG) ?
   5803                                              CAMERA_OPS_CAPTURE_AND_ENCODE :
   5804                                               CAMERA_OPS_RAW_CAPTURE;
   5805     if(strTexturesOn == true) {
   5806         current_ops_type = CAMERA_OPS_CAPTURE;
   5807         mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms,
   5808                          NULL);
   5809     } else if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
   5810         if(!mZslEnable || mZslFlashEnable){
   5811             mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms,
   5812                  (void *)&mImageEncodeParms);
   5813             }else{
   5814                 notifyShutter(TRUE);
   5815                 initZslParameter();
   5816                 ALOGI("snapshot mZslCapture.thumbnail %d %d %d",mZslCaptureParms.thumbnail_width,
   5817                                      mZslCaptureParms.thumbnail_height,mZslCaptureParms.num_captures);
   5818                 mCamOps.mm_camera_start(current_ops_type,(void *)&mZslCaptureParms,
   5819                       (void *)&mImageEncodeParms);
   5820            }
   5821         mJpegThreadWaitLock.lock();
   5822         while (mJpegThreadRunning) {
   5823             ALOGV("%s: waiting for jpeg callback.", __FUNCTION__);
   5824             mJpegThreadWait.wait(mJpegThreadWaitLock);
   5825             ALOGV("%s: jpeg callback received.", __FUNCTION__);
   5826         }
   5827         mJpegThreadWaitLock.unlock();
   5828 
   5829         //cleanup
   5830        if(!mZslEnable || mZslFlashEnable)
   5831             deinitRaw();
   5832     }else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
   5833         notifyShutter(TRUE);
   5834         mCamOps.mm_camera_start(current_ops_type,(void *)&mRawCaptureParms,
   5835                                  NULL);
   5836         // Waiting for callback to come
   5837         ALOGV("runSnapshotThread : waiting for callback to come");
   5838         mJpegThreadWaitLock.lock();
   5839         while (mJpegThreadRunning) {
   5840             ALOGV("%s: waiting for jpeg callback.", __FUNCTION__);
   5841             mJpegThreadWait.wait(mJpegThreadWaitLock);
   5842             ALOGV("%s: jpeg callback received.", __FUNCTION__);
   5843         }
   5844         mJpegThreadWaitLock.unlock();
   5845         ALOGV("runSnapshotThread : calling deinitRawSnapshot");
   5846         deinitRawSnapshot();
   5847 
   5848     }
   5849 
   5850     if(!mZslEnable || mZslFlashEnable)
   5851         mCamOps.mm_camera_deinit(current_ops_type, NULL, NULL);
   5852     mZslFlashEnable  = false;
   5853     mSnapshotThreadWaitLock.lock();
   5854     mSnapshotThreadRunning = false;
   5855     mSnapshotThreadWait.signal();
   5856     mSnapshotThreadWaitLock.unlock();
   5857     ALOGV("runSnapshotThread X");
   5858 }
   5859 
   5860 void *snapshot_thread(void *user)
   5861 {
   5862     ALOGD("snapshot_thread E");
   5863     CAMERA_HAL_UNUSED(user);
   5864     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   5865     if (obj != 0) {
   5866         obj->runSnapshotThread(user);
   5867     }
   5868     else ALOGW("not starting snapshot thread: the object went away!");
   5869     ALOGD("snapshot_thread X");
   5870     return NULL;
   5871 }
   5872 
   5873 status_t QualcommCameraHardware::takePicture()
   5874 {
   5875     ALOGE("takePicture(%d)", mMsgEnabled);
   5876     Mutex::Autolock l(&mLock);
   5877     if(mRecordingState ) {
   5878       return takeLiveSnapshotInternal( );
   5879     }
   5880 
   5881     if(strTexturesOn == true){
   5882         mEncodePendingWaitLock.lock();
   5883         while(mEncodePending) {
   5884             ALOGI("takePicture: Frame given to application, waiting for encode call");
   5885             mEncodePendingWait.wait(mEncodePendingWaitLock);
   5886             ALOGI("takePicture: Encode of the application data is done");
   5887         }
   5888         mEncodePendingWaitLock.unlock();
   5889     }
   5890 
   5891     // Wait for old snapshot thread to complete.
   5892     mSnapshotThreadWaitLock.lock();
   5893     while (mSnapshotThreadRunning) {
   5894         ALOGV("takePicture: waiting for old snapshot thread to complete.");
   5895         mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
   5896         ALOGV("takePicture: old snapshot thread completed.");
   5897     }
   5898     // if flash is enabled then run snapshot as normal mode and not zsl mode.
   5899     // App should expect only 1 callback as multi snapshot in normal mode is not supported
   5900     mZslFlashEnable = false;
   5901     if(mZslEnable){
   5902         int is_flash_needed = 0;
   5903         mm_camera_status_t status;
   5904         status = mCfgControl.mm_camera_get_parm(CAMERA_PARM_QUERY_FALSH4SNAP,
   5905                       (void *)&is_flash_needed);
   5906         if(is_flash_needed) {
   5907             mZslFlashEnable = true;
   5908         }
   5909     }
   5910     //Adding ExifTag for Flash
   5911     const char *flash_str = mParameters.get(QCameraParameters::KEY_FLASH_MODE);
   5912     if(flash_str){
   5913         int is_flash_fired = 0;
   5914         if(mCfgControl.mm_camera_get_parm(CAMERA_PARM_QUERY_FALSH4SNAP,
   5915                       (void *)&is_flash_fired) != MM_CAMERA_SUCCESS){
   5916             flashMode = FLASH_SNAP ; //for No Flash support,bit 5 will be 1
   5917         } else {
   5918             if(!strcmp(flash_str,"on"))
   5919                 flashMode = 1;
   5920 
   5921             if(!strcmp(flash_str,"off"))
   5922                 flashMode = 0;
   5923 
   5924             if(!strcmp(flash_str,"auto")){
   5925                 //for AUTO bits 3 and 4 will be 1
   5926                 //for flash fired bit 0 will be 1, else 0
   5927                 flashMode  = FLASH_AUTO;
   5928                 if(is_flash_fired)
   5929                    flashMode = (is_flash_fired>>1) | flashMode ;
   5930             }
   5931         }
   5932         addExifTag(EXIFTAGID_FLASH,EXIF_SHORT,1,1,(void *)&flashMode);
   5933     }
   5934 
   5935     if(mParameters.getPictureFormat() != 0 &&
   5936             !strcmp(mParameters.getPictureFormat(),
   5937                     QCameraParameters::PIXEL_FORMAT_RAW)){
   5938         mSnapshotFormat = PICTURE_FORMAT_RAW;
   5939       {
   5940        // HACK: Raw ZSL capture is not supported yet
   5941         mZslFlashEnable = true;
   5942       }
   5943     }
   5944     else
   5945         mSnapshotFormat = PICTURE_FORMAT_JPEG;
   5946 
   5947     if(!mZslEnable || mZslFlashEnable){
   5948         if((mSnapshotFormat == PICTURE_FORMAT_JPEG)){
   5949             if(!native_start_ops(CAMERA_OPS_PREPARE_SNAPSHOT, NULL)) {
   5950                 mSnapshotThreadWaitLock.unlock();
   5951                 ALOGE("PREPARE SNAPSHOT: CAMERA_OPS_PREPARE_SNAPSHOT ioctl Failed");
   5952                 return UNKNOWN_ERROR;
   5953             }
   5954         }
   5955     }
   5956     else {
   5957         int rotation = mParameters.getInt("rotation");
   5958         native_set_parms(CAMERA_PARM_JPEG_ROTATION, sizeof(int), &rotation);
   5959     }
   5960 #if 0    // TODO for ICS
   5961     if(mCurrentTarget == TARGET_MSM8660) {
   5962        /* Store the last frame queued for preview. This
   5963         * shall be used as postview */
   5964         if (!(storePreviewFrameForPostview()))
   5965         return UNKNOWN_ERROR;
   5966     }
   5967 #endif
   5968     if(!mZslEnable || mZslFlashEnable)
   5969         stopPreviewInternal();
   5970 #if 0
   5971     else if(mZslEnable && !mZslPanorama) {
   5972         /* Dont stop preview if ZSL Panorama is enabled for
   5973          * Continuous viewfinder support*/
   5974         ALOGE("Calling stop preview");
   5975         mCamOps.mm_camera_stop(CAMERA_OPS_ZSL_STREAMING_CB,NULL, NULL);
   5976     }
   5977 #endif
   5978 
   5979 
   5980     mFrameThreadWaitLock.unlock();
   5981 
   5982     mm_camera_ops_type_t current_ops_type = (mSnapshotFormat == PICTURE_FORMAT_JPEG) ?
   5983                                              CAMERA_OPS_CAPTURE_AND_ENCODE :
   5984                                               CAMERA_OPS_RAW_CAPTURE;
   5985     if(strTexturesOn == true)
   5986         current_ops_type = CAMERA_OPS_CAPTURE;
   5987 
   5988     if( !mZslEnable || mZslFlashEnable)
   5989         mCamOps.mm_camera_init(current_ops_type, NULL, NULL);
   5990 
   5991     if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
   5992       if(!mZslEnable || mZslFlashEnable) {
   5993         if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
   5994           ALOGE("initRaw failed.  Not taking picture.");
   5995           mSnapshotThreadWaitLock.unlock();
   5996           return UNKNOWN_ERROR;
   5997         }
   5998       }
   5999     } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
   6000         if(!initRawSnapshot()){
   6001             ALOGE("initRawSnapshot failed. Not taking picture.");
   6002             mSnapshotThreadWaitLock.unlock();
   6003             return UNKNOWN_ERROR;
   6004         }
   6005     }
   6006 
   6007     mShutterLock.lock();
   6008     mShutterPending = true;
   6009     mShutterLock.unlock();
   6010 
   6011     mSnapshotCancelLock.lock();
   6012     mSnapshotCancel = false;
   6013     mSnapshotCancelLock.unlock();
   6014 
   6015     numJpegReceived = 0;
   6016     pthread_attr_t attr;
   6017     pthread_attr_init(&attr);
   6018     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   6019     mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
   6020                                              &attr,
   6021                                              snapshot_thread,
   6022                                              NULL);
   6023     mSnapshotThreadWaitLock.unlock();
   6024 
   6025     mInSnapshotModeWaitLock.lock();
   6026     mInSnapshotMode = true;
   6027     mInSnapshotModeWaitLock.unlock();
   6028 
   6029     ALOGV("takePicture: X");
   6030     return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
   6031 }
   6032 
   6033 void QualcommCameraHardware::set_liveshot_exifinfo()
   6034 {
   6035 
   6036     setGpsParameters();
   6037     //set TimeStamp
   6038     const char *str = mParameters.get(QCameraParameters::KEY_EXIF_DATETIME);
   6039     if(str != NULL) {
   6040         strncpy(dateTime, str, 19);
   6041         dateTime[19] = '\0';
   6042         addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   6043                    20, 1, (void *)dateTime);
   6044     }
   6045 }
   6046 
   6047 
   6048 status_t QualcommCameraHardware::takeLiveSnapshotInternal()
   6049 {
   6050     ALOGV("takeLiveSnapshotInternal : E");
   6051     if(liveshot_state == LIVESHOT_IN_PROGRESS || !mRecordingState) {
   6052         return NO_ERROR;
   6053     }
   6054 
   6055     if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660) && (mCurrentTarget != TARGET_MSM7627A)) {
   6056         ALOGI("LiveSnapshot not supported on this target");
   6057         liveshot_state = LIVESHOT_STOPPED;
   6058         return NO_ERROR;
   6059     }
   6060 
   6061     liveshot_state = LIVESHOT_IN_PROGRESS;
   6062 
   6063     if (!initLiveSnapshot(videoWidth, videoHeight)) {
   6064         ALOGE("takeLiveSnapshot: Jpeg Heap Memory allocation failed.  Not taking Live Snapshot.");
   6065         liveshot_state = LIVESHOT_STOPPED;
   6066         return UNKNOWN_ERROR;
   6067     }
   6068     uint32_t maxjpegsize = videoWidth * videoHeight *1.5;
   6069     set_liveshot_exifinfo();
   6070     if(!LINK_set_liveshot_params(videoWidth, videoHeight,
   6071                                 exif_data, exif_table_numEntries,
   6072       (uint8_t *)mJpegLiveSnapMapped->data, maxjpegsize)) {
   6073         ALOGE("Link_set_liveshot_params failed.");
   6074         if (NULL != mJpegLiveSnapMapped) {
   6075               ALOGV("initLiveSnapshot: clearing old mJpegHeap.");
   6076               mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   6077               mJpegLiveSnapMapped = NULL;
   6078         }
   6079         return NO_ERROR;
   6080     }
   6081       if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) {
   6082           if(!native_start_ops(CAMERA_OPS_LIVESHOT, NULL)) {
   6083             ALOGE("start_liveshot ioctl failed");
   6084             liveshot_state = LIVESHOT_STOPPED;
   6085             if (NULL != mJpegLiveSnapMapped) {
   6086               ALOGV("initLiveSnapshot: clearing old mJpegHeap.");
   6087               mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   6088               mJpegLiveSnapMapped = NULL;
   6089             }
   6090             return UNKNOWN_ERROR;
   6091           }
   6092       }
   6093 
   6094     ALOGV("takeLiveSnapshotInternal: X");
   6095     return NO_ERROR;
   6096 }
   6097 
   6098 status_t QualcommCameraHardware::takeLiveSnapshot()
   6099 {
   6100   ALOGV("takeLiveSnapshot: E ");
   6101   Mutex::Autolock l(&mLock);
   6102   ALOGV("takeLiveSnapshot: X ");
   6103   return takeLiveSnapshotInternal( );
   6104 }
   6105 
   6106 bool QualcommCameraHardware::initLiveSnapshot(int videowidth, int videoheight)
   6107 {
   6108     ALOGV("initLiveSnapshot E");
   6109 
   6110     if (NULL != mJpegLiveSnapMapped) {
   6111         ALOGV("initLiveSnapshot: clearing old mJpegHeap.");
   6112         mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   6113         mJpegLiveSnapMapped = NULL;
   6114     }
   6115 
   6116     mJpegMaxSize = videowidth * videoheight * 1.5;
   6117     ALOGV("initLiveSnapshot: initializing mJpegHeap.");
   6118     mJpegLiveSnapMapped = mGetMemory(-1, mJpegMaxSize,1,mCallbackCookie);
   6119     if(mJpegLiveSnapMapped == NULL) {
   6120         ALOGE("Failed to get camera memory for mJpegLibeSnapMapped" );
   6121         return false;
   6122     }
   6123     ALOGV("initLiveSnapshot X");
   6124     return true;
   6125 }
   6126 
   6127 
   6128 status_t QualcommCameraHardware::cancelPicture()
   6129 {
   6130     status_t rc;
   6131     ALOGV("cancelPicture: E");
   6132 
   6133     mSnapshotCancelLock.lock();
   6134     ALOGI("%s: setting mSnapshotCancel to true", __FUNCTION__);
   6135     mSnapshotCancel = true;
   6136     mSnapshotCancelLock.unlock();
   6137 
   6138     if (mCurrentTarget == TARGET_MSM7627 ||
   6139        (mCurrentTarget == TARGET_MSM7625A ||
   6140         mCurrentTarget == TARGET_MSM7627A)) {
   6141         mSnapshotDone = TRUE;
   6142         mSnapshotThreadWaitLock.lock();
   6143         while (mSnapshotThreadRunning) {
   6144             ALOGV("cancelPicture: waiting for snapshot thread to complete.");
   6145             mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
   6146             ALOGV("cancelPicture: snapshot thread completed.");
   6147         }
   6148         mSnapshotThreadWaitLock.unlock();
   6149     }
   6150     rc = native_stop_ops(CAMERA_OPS_CAPTURE, NULL) ? NO_ERROR : UNKNOWN_ERROR;
   6151     mSnapshotDone = FALSE;
   6152     ALOGV("cancelPicture: X: %d", rc);
   6153     return rc;
   6154 }
   6155 
   6156 status_t QualcommCameraHardware::setParameters(const QCameraParameters& params)
   6157 {
   6158     ALOGV("setParameters: E params = %p", &params);
   6159 
   6160     Mutex::Autolock l(&mLock);
   6161     Mutex::Autolock pl(&mParametersLock);
   6162     status_t rc, final_rc = NO_ERROR;
   6163     if (mSnapshotThreadRunning) {
   6164         if ((rc = setCameraMode(params)))  final_rc = rc;
   6165         if ((rc = setPreviewSize(params)))  final_rc = rc;
   6166         if ((rc = setRecordSize(params)))  final_rc = rc;
   6167         if ((rc = setPictureSize(params)))  final_rc = rc;
   6168         if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
   6169         if ((rc = setJpegQuality(params)))  final_rc = rc;
   6170         return final_rc;
   6171     }
   6172     if ((rc = setCameraMode(params)))  final_rc = rc;
   6173     if ((rc = setPreviewSize(params)))  final_rc = rc;
   6174     if ((rc = setRecordSize(params)))  final_rc = rc;
   6175     if ((rc = setPictureSize(params)))  final_rc = rc;
   6176     if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
   6177     if ((rc = setJpegQuality(params)))  final_rc = rc;
   6178 	if ((rc = setPictureFormat(params))) final_rc = rc;
   6179 	if ((rc = setRecordSize(params)))  final_rc = rc;
   6180 	if ((rc = setPreviewFormat(params)))   final_rc = rc;
   6181     if ((rc = setEffect(params)))       final_rc = rc;
   6182     if ((rc = setGpsLocation(params)))  final_rc = rc;
   6183     if ((rc = setRotation(params)))     final_rc = rc;
   6184     if ((rc = setZoom(params)))         final_rc = rc;
   6185     if ((rc = setOrientation(params)))  final_rc = rc;
   6186     if ((rc = setLensshadeValue(params)))  final_rc = rc;
   6187     if ((rc = setMCEValue(params)))  final_rc = rc;
   6188     //if ((rc = setHDRImaging(params)))  final_rc = rc;
   6189     if ((rc = setExpBracketing(params)))  final_rc = rc;
   6190     if ((rc = setPictureFormat(params))) final_rc = rc;
   6191     if ((rc = setSharpness(params)))    final_rc = rc;
   6192     if ((rc = setSaturation(params)))   final_rc = rc;
   6193     if ((rc = setTouchAfAec(params)))   final_rc = rc;
   6194     if ((rc = setSceneMode(params)))    final_rc = rc;
   6195     if ((rc = setContrast(params)))     final_rc = rc;
   6196     if ((rc = setRecordSize(params)))  final_rc = rc;
   6197     if ((rc = setSceneDetect(params)))  final_rc = rc;
   6198     if ((rc = setStrTextures(params)))   final_rc = rc;
   6199     if ((rc = setPreviewFormat(params)))   final_rc = rc;
   6200     if ((rc = setSkinToneEnhancement(params)))   final_rc = rc;
   6201     if ((rc = setAntibanding(params)))  final_rc = rc;
   6202     if ((rc = setRedeyeReduction(params)))  final_rc = rc;
   6203     if ((rc = setDenoise(params)))  final_rc = rc;
   6204     if ((rc = setPreviewFpsRange(params)))  final_rc = rc;
   6205     if ((rc = setZslParam(params)))  final_rc = rc;
   6206     if ((rc = setSnapshotCount(params)))  final_rc = rc;
   6207     if((rc = setRecordingHint(params)))   final_rc = rc;
   6208     const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
   6209     int32_t value =