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 #include <linux/ioctl.h>
     42 #include "QCameraParameters.h"
     43 #include <media/mediarecorder.h>
     44 #include <gralloc_priv.h>
     45 #include <genlock.h>
     46 
     47 #include "linux/msm_mdp.h"
     48 #include <linux/fb.h>
     49 #define LIKELY(exp)   __builtin_expect(!!(exp), 1)
     50 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
     51 #define CAMERA_HAL_UNUSED(expr) do { (void)(expr); } while (0)
     52 
     53 extern "C" {
     54 #include <fcntl.h>
     55 #include <time.h>
     56 #include <pthread.h>
     57 #include <stdio.h>
     58 #include <string.h>
     59 #include <unistd.h>
     60 #include <termios.h>
     61 #include <assert.h>
     62 #include <stdlib.h>
     63 #include <ctype.h>
     64 #include <signal.h>
     65 #include <errno.h>
     66 #include <sys/mman.h>
     67 #include <sys/system_properties.h>
     68 #include <sys/time.h>
     69 #include <stdlib.h>
     70 
     71 
     72 #include <camera.h>
     73 #include <cam_fifo.h>
     74 #include <liveshot.h>
     75 #include <jpege.h>
     76 #include <jpeg_encoder.h>
     77 
     78 #define DUMP_LIVESHOT_JPEG_FILE 0
     79 
     80 #define DEFAULT_PICTURE_WIDTH  640
     81 #define DEFAULT_PICTURE_HEIGHT 480
     82 #define DEFAULT_PICTURE_WIDTH_3D 1920
     83 #define DEFAULT_PICTURE_HEIGHT_3D 1080
     84 #define INITIAL_PREVIEW_HEIGHT 144
     85 #define INITIAL_PREVIEW_WIDTH 176
     86 
     87 #define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
     88 #define MAX_ZOOM_LEVEL 5
     89 #define NOT_FOUND -1
     90 // Number of video buffers held by kernal (initially 1,2 &3)
     91 #define ACTIVE_VIDEO_BUFFERS 3
     92 #define ACTIVE_PREVIEW_BUFFERS 3
     93 #define ACTIVE_ZSL_BUFFERS 3
     94 #define APP_ORIENTATION 90
     95 #define HDR_HAL_FRAME 2
     96 
     97 #define FLASH_AUTO 24
     98 #define FLASH_SNAP 32
     99 
    100 #define DUMMY_CAMERA_STARTED 1;
    101 #define DUMMY_CAMERA_STOPPED 0;
    102 #define FLOOR16(X) ((X) & 0xFFF0)
    103 #if DLOPEN_LIBMMCAMERA
    104 #include <dlfcn.h>
    105 
    106 
    107 // Conversion routines from YV420sp to YV12 format
    108 int (*LINK_yuv_convert_ycrcb420sp_to_yv12_inplace) (yuv_image_type* yuvStructPtr);
    109 int (*LINK_yuv_convert_ycrcb420sp_to_yv12) (yuv_image_type* yuvStructPtrin, yuv_image_type* yuvStructPtrout);
    110 #define NUM_YV12_FRAMES 1
    111 #define FOCUS_AREA_INIT "(-1000,-1000,1000,1000,1000)"
    112 
    113 void *libmmcamera;
    114 void* (*LINK_cam_conf)(void *data);
    115 void* (*LINK_cam_frame)(void *data);
    116 void* (*LINK_wait_cam_frame_thread_ready)(void);
    117 void* (*LINK_cam_frame_set_exit_flag)(int flag);
    118 bool  (*LINK_jpeg_encoder_init)();
    119 void  (*LINK_jpeg_encoder_join)();
    120 bool  (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
    121                 const uint8_t *thumbnailbuf, int thumbnailfd,
    122                 const uint8_t *snapshotbuf, int snapshotfd,
    123                 common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
    124                 int exif_table_numEntries, int jpegPadding, const int32_t cbcroffset,int zsl_enable);
    125 void (*LINK_camframe_terminate)(void);
    126 //for 720p
    127 // Function pointer , called by camframe when a video frame is available.
    128 void (**LINK_camframe_video_callback)(struct msm_frame * frame);
    129 // Function to add a frame to free Q
    130 void (*LINK_camframe_add_frame)(cam_frame_type_t type,struct msm_frame *frame);
    131 
    132 void (*LINK_camframe_release_all_frames)(cam_frame_type_t type);
    133 
    134 int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
    135 int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
    136 int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
    137 int8_t (*LINK_jpeg_encoder_get_buffer_offset)(uint32_t width, uint32_t height,
    138                                                uint32_t* p_y_offset,
    139                                                 uint32_t* p_cbcr_offset,
    140                                                  uint32_t* p_buf_size);
    141 int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
    142 void (*LINK_jpeg_encoder_set_3D_info)(cam_3d_frame_format_t format);
    143 const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
    144 int (*LINK_launch_cam_conf_thread)(void);
    145 int (*LINK_release_cam_conf_thread)(void);
    146 mm_camera_status_t (*LINK_mm_camera_init)(mm_camera_config *, mm_camera_notify*, mm_camera_ops*,uint8_t);
    147 mm_camera_status_t (*LINK_mm_camera_deinit)();
    148 mm_camera_status_t (*LINK_mm_camera_destroy)();
    149 mm_camera_status_t (*LINK_mm_camera_exec)();
    150 mm_camera_status_t (*LINK_mm_camera_get_camera_info) (qcamera_info_t* p_cam_info, int* p_num_cameras);
    151 
    152 int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
    153     uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
    154 
    155 // callbacks
    156 void  (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
    157 void  (**LINK_cancel_liveshot)(void);
    158 int8_t  (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data,
    159                          int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size);
    160 void (*LINK_set_liveshot_frame)(struct msm_frame *liveshot_frame);
    161 #else
    162 #define LINK_cam_conf cam_conf
    163 #define LINK_cam_frame cam_frame
    164 #define LINK_wait_cam_frame_thread_ready wait_cam_frame_thread_ready
    165 #define LINK_cam_frame cam_frame_set_exit_flag
    166 #define LINK_jpeg_encoder_init jpeg_encoder_init
    167 #define LINK_jpeg_encoder_join jpeg_encoder_join
    168 #define LINK_jpeg_encoder_encode jpeg_encoder_encode
    169 #define LINK_camframe_terminate camframe_terminate
    170 #define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
    171 #define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
    172 #define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
    173 #define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset
    174 #define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
    175 #define LINK_jpeg_encoder_set_3D_info jpeg_encoder_set_3D_info
    176 #define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
    177 #define LINK_launch_cam_conf_thread launch_cam_conf_thread
    178 #define LINK_release_cam_conf_thread release_cam_conf_thread
    179 #define LINK_zoom_crop_upscale zoom_crop_upscale
    180 #define LINK_mm_camera_init mm_camera_config_init
    181 #define LINK_mm_camera_deinit mm_camera_config_deinit
    182 #define LINK_mm_camera_destroy mm_camera_config_destroy
    183 #define LINK_mm_camera_exec mm_camera_exec
    184 #define LINK_camframe_add_frame camframe_add_frame
    185 #define LINK_camframe_release_all_frames camframe_release_all_frames
    186 #define LINK_mm_camera_get_camera_info mm_camera_get_camera_info
    187 
    188 extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
    189 extern void (*mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
    190 extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
    191                                       uint32_t buff_size);
    192 extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
    193 extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
    194 extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
    195 #define LINK_set_liveshot_params set_liveshot_params
    196 #define LINK_set_liveshot_frame set_liveshot_frame
    197 #endif
    198 
    199 } // extern "C"
    200 
    201 #ifndef HAVE_CAMERA_SIZE_TYPE
    202 struct camera_size_type {
    203     int width;
    204     int height;
    205 };
    206 #endif
    207 #if 0
    208 typedef struct crop_info_struct {
    209     int32_t x;
    210     int32_t y;
    211     int32_t w;
    212     int32_t h;
    213 } zoom_crop_info;
    214 #endif
    215 union zoomimage
    216 {
    217     char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
    218     struct mdp_blit_req_list list;
    219 } zoomImage;
    220 
    221 //Default to VGA
    222 #define DEFAULT_PREVIEW_WIDTH 640
    223 #define DEFAULT_PREVIEW_HEIGHT 480
    224 #define DEFAULT_PREVIEW_WIDTH_3D 1280
    225 #define DEFAULT_PREVIEW_HEIGHT_3D 720
    226 
    227 //Default FPS
    228 #define MINIMUM_FPS 5
    229 #define MAXIMUM_FPS 31
    230 #define DEFAULT_FPS MAXIMUM_FPS
    231 #define DEFAULT_FIXED_FPS_VALUE 30
    232 /*
    233  * Modifying preview size requires modification
    234  * in bitmasks for boardproperties
    235  */
    236 static uint32_t  PREVIEW_SIZE_COUNT;
    237 static uint32_t  HFR_SIZE_COUNT;
    238 
    239 board_property boardProperties[] = {
    240         {TARGET_MSM7625, 0x00000fff, false, false, false},
    241         {TARGET_MSM7625A, 0x00000fff, false, false, false},
    242         {TARGET_MSM7627, 0x000006ff, false, false, false},
    243         {TARGET_MSM7627A, 0x000006ff, false, false, false},
    244         {TARGET_MSM7630, 0x00000fff, true, true, false},
    245         {TARGET_MSM8660, 0x00001fff, true, true, false},
    246         {TARGET_QSD8250, 0x00000fff, false, false, false}
    247 };
    248 
    249 //static const camera_size_type* picture_sizes;
    250 //static int PICTURE_SIZE_COUNT;
    251 /*       TODO
    252  * Ideally this should be a populated by lower layers.
    253  * But currently this is no API to do that at lower layer.
    254  * Hence populating with default sizes for now. This needs
    255  * to be changed once the API is supported.
    256  */
    257 //sorted on column basis
    258 static struct camera_size_type zsl_picture_sizes[] = {
    259   { 1024, 768}, // 1MP XGA
    260   { 800, 600}, //SVGA
    261   { 800, 480}, // WVGA
    262   { 640, 480}, // VGA
    263   { 352, 288}, //CIF
    264   { 320, 240}, // QVGA
    265   { 176, 144} // QCIF
    266 };
    267 
    268 static struct camera_size_type for_3D_picture_sizes[] = {
    269   { 1920, 1080},
    270 };
    271 
    272 static int data_counter = 0;
    273 static int sensor_rotation = 0;
    274 static int record_flag = 0;
    275 static camera_size_type* picture_sizes;
    276 static camera_size_type* preview_sizes;
    277 static camera_size_type* hfr_sizes;
    278 static unsigned int PICTURE_SIZE_COUNT;
    279 static const camera_size_type * picture_sizes_ptr;
    280 static int supportedPictureSizesCount;
    281 static liveshotState liveshot_state = LIVESHOT_DONE;
    282 
    283 #ifdef Q12
    284 #undef Q12
    285 #endif
    286 
    287 #define Q12 4096
    288 
    289 static const target_map targetList [] = {
    290     { "msm7625", TARGET_MSM7625 },
    291     { "msm7625a", TARGET_MSM7625A },
    292     { "msm7627", TARGET_MSM7627 },
    293     { "msm7627a", TARGET_MSM7627A },
    294     { "qsd8250", TARGET_QSD8250 },
    295     { "msm7630", TARGET_MSM7630 },
    296     { "msm8660", TARGET_MSM8660 }
    297 
    298 };
    299 static targetType mCurrentTarget = TARGET_MAX;
    300 
    301 typedef struct {
    302     uint32_t aspect_ratio;
    303     uint32_t width;
    304     uint32_t height;
    305 } thumbnail_size_type;
    306 
    307 static thumbnail_size_type thumbnail_sizes[] = {
    308     { 7281, 512, 288 }, //1.777778
    309     { 6826, 480, 288 }, //1.666667
    310     { 6808, 256, 154 }, //1.662337
    311     { 6144, 432, 288 }, //1.5
    312     { 5461, 512, 384 }, //1.333333
    313     { 5006, 352, 288 }, //1.222222
    314 };
    315 #define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
    316 #define DEFAULT_THUMBNAIL_SETTING 4
    317 #define THUMBNAIL_WIDTH_STR "512"
    318 #define THUMBNAIL_HEIGHT_STR "384"
    319 #define THUMBNAIL_SMALL_HEIGHT 144
    320 static camera_size_type jpeg_thumbnail_sizes[]  = {
    321     { 512, 288 },
    322     { 480, 288 },
    323     { 432, 288 },
    324     { 512, 384 },
    325     { 352, 288 },
    326     {0,0}
    327 };
    328 //supported preview fps ranges should be added to this array in the form (minFps,maxFps)
    329 static  android::FPSRange FpsRangesSupported[] = {{MINIMUM_FPS*1000,MAXIMUM_FPS*1000}};
    330 
    331 #define FPS_RANGES_SUPPORTED_COUNT (sizeof(FpsRangesSupported)/sizeof(FpsRangesSupported[0]))
    332 
    333 #define JPEG_THUMBNAIL_SIZE_COUNT (sizeof(jpeg_thumbnail_sizes)/sizeof(camera_size_type))
    334 static int attr_lookup(const str_map arr[], int len, const char *name)
    335 {
    336     if (name) {
    337         for (int i = 0; i < len; i++) {
    338             if (!strcmp(arr[i].desc, name))
    339                 return arr[i].val;
    340         }
    341     }
    342     return NOT_FOUND;
    343 }
    344 
    345 // round to the next power of two
    346 static inline unsigned clp2(unsigned x)
    347 {
    348     x = x - 1;
    349     x = x | (x >> 1);
    350     x = x | (x >> 2);
    351     x = x | (x >> 4);
    352     x = x | (x >> 8);
    353     x = x | (x >>16);
    354     return x + 1;
    355 }
    356 
    357 static int exif_table_numEntries = 0;
    358 #define MAX_EXIF_TABLE_ENTRIES 14
    359 exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
    360 //static zoom_crop_info zoomCropInfo;
    361 static android_native_rect_t zoomCropInfo;
    362 static void *mLastQueuedFrame = NULL;
    363 #define RECORD_BUFFERS 9
    364 #define RECORD_BUFFERS_8x50 8
    365 static int kRecordBufferCount;
    366 /* controls whether VPE is avialable for the target
    367  * under consideration.
    368  * 1: VPE support is available
    369  * 0: VPE support is not available (default)
    370  */
    371 static bool mVpeEnabled;
    372 static cam_frame_start_parms camframeParams;
    373 
    374 static int HAL_numOfCameras;
    375 static qcamera_info_t HAL_cameraInfo[MSM_MAX_CAMERA_SENSORS];
    376 static int HAL_currentCameraId;
    377 static int HAL_currentCameraMode;
    378 static mm_camera_config mCfgControl;
    379 static bool mCameraOpen;
    380 
    381 static int HAL_currentSnapshotMode;
    382 static int previewWidthToNativeZoom;
    383 static int previewHeightToNativeZoom;
    384 #define CAMERA_SNAPSHOT_NONZSL 0x04
    385 #define CAMERA_SNAPSHOT_ZSL 0x08
    386 
    387 namespace android {
    388 	extern void native_send_data_callback(int32_t msgType,
    389                               camera_memory_t * framebuffer,
    390 	                              void* user);
    391 
    392 	extern camera_memory_t* get_mem(int fd,size_t buf_size,
    393 	                                unsigned int num_bufs,
    394 	                                void *user);
    395 
    396 static const int PICTURE_FORMAT_JPEG = 1;
    397 static const int PICTURE_FORMAT_RAW = 2;
    398 
    399 // from aeecamera.h
    400 static const str_map whitebalance[] = {
    401     { QCameraParameters::WHITE_BALANCE_AUTO,            CAMERA_WB_AUTO },
    402     { QCameraParameters::WHITE_BALANCE_INCANDESCENT,    CAMERA_WB_INCANDESCENT },
    403     { QCameraParameters::WHITE_BALANCE_FLUORESCENT,     CAMERA_WB_FLUORESCENT },
    404     { QCameraParameters::WHITE_BALANCE_DAYLIGHT,        CAMERA_WB_DAYLIGHT },
    405     { QCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
    406 };
    407 
    408 // from camera_effect_t. This list must match aeecamera.h
    409 static const str_map effects[] = {
    410     { QCameraParameters::EFFECT_NONE,       CAMERA_EFFECT_OFF },
    411     { QCameraParameters::EFFECT_MONO,       CAMERA_EFFECT_MONO },
    412     { QCameraParameters::EFFECT_NEGATIVE,   CAMERA_EFFECT_NEGATIVE },
    413     { QCameraParameters::EFFECT_SOLARIZE,   CAMERA_EFFECT_SOLARIZE },
    414     { QCameraParameters::EFFECT_SEPIA,      CAMERA_EFFECT_SEPIA },
    415     { QCameraParameters::EFFECT_POSTERIZE,  CAMERA_EFFECT_POSTERIZE },
    416     { QCameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
    417     { QCameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
    418     { QCameraParameters::EFFECT_AQUA,       CAMERA_EFFECT_AQUA }
    419 };
    420 
    421 // from qcamera/common/camera.h
    422 static const str_map autoexposure[] = {
    423     { QCameraParameters::AUTO_EXPOSURE_FRAME_AVG,  CAMERA_AEC_FRAME_AVERAGE },
    424     { QCameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
    425     { QCameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
    426 };
    427 
    428 // from qcamera/common/camera.h
    429 static const str_map antibanding[] = {
    430     { QCameraParameters::ANTIBANDING_OFF,  CAMERA_ANTIBANDING_OFF },
    431     { QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
    432     { QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
    433     { QCameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
    434 };
    435 
    436 static const str_map antibanding_3D[] = {
    437     { QCameraParameters::ANTIBANDING_OFF,  CAMERA_ANTIBANDING_OFF },
    438     { QCameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
    439     { QCameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ }
    440 };
    441 
    442 /* Mapping from MCC to antibanding type */
    443 struct country_map {
    444     uint32_t country_code;
    445     camera_antibanding_type type;
    446 };
    447 
    448 #if 0 //not using this function. keeping this as this came from Google.
    449 static struct country_map country_numeric[] = {
    450     { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
    451     { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
    452     { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
    453     { 208, CAMERA_ANTIBANDING_50HZ }, // France
    454     { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
    455     { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
    456     { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
    457     { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
    458     { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
    459     { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
    460     { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
    461     { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
    462     { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
    463     { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
    464     { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
    465     { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
    466     { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
    467     { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
    468     { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
    469     { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
    470     { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
    471     { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
    472     { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
    473     { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
    474     { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
    475     { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
    476     { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
    477     { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
    478     { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
    479     { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
    480     { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
    481     { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
    482     { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
    483     { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
    484     { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
    485     { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
    486     { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
    487     { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
    488     { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
    489     { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
    490     { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
    491     { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
    492     { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
    493     { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
    494     { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
    495     { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
    496     { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
    497     { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
    498     { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
    499     { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
    500     { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
    501     { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
    502     { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
    503     { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
    504     { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
    505     { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
    506     { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
    507     { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
    508     { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
    509     { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
    510     { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
    511     { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
    512     { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
    513     { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
    514     { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
    515     { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
    516     { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
    517     { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
    518     { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
    519     { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
    520     { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
    521     { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
    522     { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
    523     { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
    524     { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
    525     { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
    526     { 404, CAMERA_ANTIBANDING_50HZ }, // India
    527     { 405, CAMERA_ANTIBANDING_50HZ }, // India
    528     { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
    529     { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
    530     { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
    531     { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
    532     { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
    533     { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
    534     { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
    535     { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
    536     { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
    537     { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
    538     { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
    539     { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
    540     { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
    541     { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
    542     { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
    543     { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
    544     { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
    545     { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
    546     { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
    547     { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
    548     { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
    549     { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
    550     { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
    551     { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
    552     { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
    553     { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
    554     { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
    555     { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
    556     { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
    557     { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
    558     { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
    559     { 460, CAMERA_ANTIBANDING_50HZ }, // China
    560     { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
    561     { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
    562     { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
    563     { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
    564     { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
    565     { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
    566     { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
    567     { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
    568     { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
    569     { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
    570     { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
    571     { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
    572     { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
    573     { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
    574     { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
    575     { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
    576     { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
    577     { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
    578     { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
    579     { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
    580     { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
    581     { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
    582     { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
    583     { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
    584     { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
    585     { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
    586     { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
    587     { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
    588     { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
    589     { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
    590     { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
    591     { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
    592     { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
    593     { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
    594     { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
    595     { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
    596     { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
    597     { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
    598     { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
    599     { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
    600     { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
    601     { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
    602     { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
    603     { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
    604     { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
    605     { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
    606     { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
    607     { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
    608     { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
    609     { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
    610     { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
    611     { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
    612     { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
    613     { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
    614     { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
    615     { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
    616     { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
    617     { 647, CAMERA_ANTIBANDING_50HZ }, // France
    618     { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
    619     { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
    620     { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
    621     { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
    622     { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
    623     { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
    624     { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
    625     { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
    626     { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
    627     { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
    628     { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
    629     { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
    630     { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
    631     { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
    632     { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
    633     { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
    634     { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
    635     { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
    636     { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
    637     { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
    638     { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
    639     { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
    640     { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
    641     { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
    642     { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
    643     { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
    644     { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
    645     { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
    646     { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
    647 };
    648 #define country_number (sizeof(country_numeric) / sizeof(country_map))
    649 /* Look up pre-sorted antibanding_type table by current MCC. */
    650 static camera_antibanding_type camera_get_location(void) {
    651     char value[PROP_VALUE_MAX];
    652     char country_value[PROP_VALUE_MAX];
    653     uint32_t country_code;
    654     memset(value, 0x00, sizeof(value));
    655     memset(country_value, 0x00, sizeof(country_value));
    656     if (!__system_property_get("gsm.operator.numeric", value)) {
    657         return CAMERA_ANTIBANDING_60HZ;
    658     }
    659     memcpy(country_value, value, 3);
    660     country_code = atoi(country_value);
    661     ALOGD("value:%s, country value:%s, country code:%d\n",
    662             value, country_value, country_code);
    663     int left = 0;
    664     int right = country_number - 1;
    665     while (left <= right) {
    666         int index = (left + right) >> 1;
    667         if (country_numeric[index].country_code == country_code)
    668             return country_numeric[index].type;
    669         else if (country_numeric[index].country_code > country_code)
    670             right = index - 1;
    671         else
    672             left = index + 1;
    673     }
    674     return CAMERA_ANTIBANDING_60HZ;
    675 }
    676 #endif
    677 
    678 static const str_map scenemode[] = {
    679     { QCameraParameters::SCENE_MODE_AUTO,           CAMERA_BESTSHOT_OFF },
    680     { QCameraParameters::SCENE_MODE_ASD,           CAMERA_BESTSHOT_AUTO },
    681     { QCameraParameters::SCENE_MODE_ACTION,         CAMERA_BESTSHOT_ACTION },
    682     { QCameraParameters::SCENE_MODE_PORTRAIT,       CAMERA_BESTSHOT_PORTRAIT },
    683     { QCameraParameters::SCENE_MODE_LANDSCAPE,      CAMERA_BESTSHOT_LANDSCAPE },
    684     { QCameraParameters::SCENE_MODE_NIGHT,          CAMERA_BESTSHOT_NIGHT },
    685     { QCameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
    686     { QCameraParameters::SCENE_MODE_THEATRE,        CAMERA_BESTSHOT_THEATRE },
    687     { QCameraParameters::SCENE_MODE_BEACH,          CAMERA_BESTSHOT_BEACH },
    688     { QCameraParameters::SCENE_MODE_SNOW,           CAMERA_BESTSHOT_SNOW },
    689     { QCameraParameters::SCENE_MODE_SUNSET,         CAMERA_BESTSHOT_SUNSET },
    690     { QCameraParameters::SCENE_MODE_STEADYPHOTO,    CAMERA_BESTSHOT_ANTISHAKE },
    691     { QCameraParameters::SCENE_MODE_FIREWORKS ,     CAMERA_BESTSHOT_FIREWORKS },
    692     { QCameraParameters::SCENE_MODE_SPORTS ,        CAMERA_BESTSHOT_SPORTS },
    693     { QCameraParameters::SCENE_MODE_PARTY,          CAMERA_BESTSHOT_PARTY },
    694     { QCameraParameters::SCENE_MODE_CANDLELIGHT,    CAMERA_BESTSHOT_CANDLELIGHT },
    695     { QCameraParameters::SCENE_MODE_BACKLIGHT,      CAMERA_BESTSHOT_BACKLIGHT },
    696     { QCameraParameters::SCENE_MODE_FLOWERS,        CAMERA_BESTSHOT_FLOWERS },
    697     { QCameraParameters::SCENE_MODE_AR,             CAMERA_BESTSHOT_AR },
    698 };
    699 
    700 static const str_map scenedetect[] = {
    701     { QCameraParameters::SCENE_DETECT_OFF, FALSE  },
    702     { QCameraParameters::SCENE_DETECT_ON, TRUE },
    703 };
    704 
    705 // from camera.h, led_mode_t
    706 static const str_map flash[] = {
    707     { QCameraParameters::FLASH_MODE_OFF,  LED_MODE_OFF },
    708     { QCameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
    709     { QCameraParameters::FLASH_MODE_ON, LED_MODE_ON },
    710     { QCameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
    711 };
    712 
    713 // from mm-camera/common/camera.h.
    714 static const str_map iso[] = {
    715     { QCameraParameters::ISO_AUTO,  CAMERA_ISO_AUTO},
    716     { QCameraParameters::ISO_HJR,   CAMERA_ISO_DEBLUR},
    717     { QCameraParameters::ISO_100,   CAMERA_ISO_100},
    718     { QCameraParameters::ISO_200,   CAMERA_ISO_200},
    719     { QCameraParameters::ISO_400,   CAMERA_ISO_400},
    720     { QCameraParameters::ISO_800,   CAMERA_ISO_800 },
    721     { QCameraParameters::ISO_1600,  CAMERA_ISO_1600 }
    722 };
    723 
    724 static const str_map iso_3D[] = {
    725     { QCameraParameters::ISO_AUTO,  CAMERA_ISO_AUTO},
    726     { QCameraParameters::ISO_100,   CAMERA_ISO_100},
    727     { QCameraParameters::ISO_200,   CAMERA_ISO_200},
    728     { QCameraParameters::ISO_400,   CAMERA_ISO_400},
    729     { QCameraParameters::ISO_800,   CAMERA_ISO_800 },
    730     { QCameraParameters::ISO_1600,  CAMERA_ISO_1600 }
    731 };
    732 
    733 
    734 #define DONT_CARE AF_MODE_MAX
    735 static const str_map focus_modes[] = {
    736     { QCameraParameters::FOCUS_MODE_AUTO,     AF_MODE_AUTO},
    737     { QCameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
    738     { QCameraParameters::FOCUS_MODE_NORMAL,   AF_MODE_NORMAL },
    739     { QCameraParameters::FOCUS_MODE_MACRO,    AF_MODE_MACRO },
    740     { QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, AF_MODE_CAF },
    741     { QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, DONT_CARE }
    742 };
    743 
    744 static const str_map lensshade[] = {
    745     { QCameraParameters::LENSSHADE_ENABLE, TRUE },
    746     { QCameraParameters::LENSSHADE_DISABLE, FALSE }
    747 };
    748 
    749 static const str_map hfr[] = {
    750     { QCameraParameters::VIDEO_HFR_OFF, CAMERA_HFR_MODE_OFF },
    751     { QCameraParameters::VIDEO_HFR_2X, CAMERA_HFR_MODE_60FPS },
    752     { QCameraParameters::VIDEO_HFR_3X, CAMERA_HFR_MODE_90FPS },
    753     { QCameraParameters::VIDEO_HFR_4X, CAMERA_HFR_MODE_120FPS },
    754 };
    755 
    756 static const str_map mce[] = {
    757     { QCameraParameters::MCE_ENABLE, TRUE },
    758     { QCameraParameters::MCE_DISABLE, FALSE }
    759 };
    760 
    761 static const str_map hdr[] = {
    762     { QCameraParameters::HDR_ENABLE, TRUE },
    763     { QCameraParameters::HDR_DISABLE, FALSE }
    764 };
    765 
    766 static const str_map histogram[] = {
    767     { QCameraParameters::HISTOGRAM_ENABLE, TRUE },
    768     { QCameraParameters::HISTOGRAM_DISABLE, FALSE }
    769 };
    770 
    771 static const str_map skinToneEnhancement[] = {
    772     { QCameraParameters::SKIN_TONE_ENHANCEMENT_ENABLE, TRUE },
    773     { QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE, FALSE }
    774 };
    775 
    776 static const str_map denoise[] = {
    777     { QCameraParameters::DENOISE_OFF, FALSE },
    778     { QCameraParameters::DENOISE_ON, TRUE }
    779 };
    780 
    781 static const str_map selectable_zone_af[] = {
    782     { QCameraParameters::SELECTABLE_ZONE_AF_AUTO,  AUTO },
    783     { QCameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT },
    784     { QCameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED },
    785     { QCameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE }
    786 };
    787 
    788 static const str_map facedetection[] = {
    789     { QCameraParameters::FACE_DETECTION_OFF, FALSE },
    790     { QCameraParameters::FACE_DETECTION_ON, TRUE }
    791 };
    792 
    793 #define DONT_CARE_COORDINATE -1
    794 static const str_map touchafaec[] = {
    795     { QCameraParameters::TOUCH_AF_AEC_OFF, FALSE },
    796     { QCameraParameters::TOUCH_AF_AEC_ON, TRUE }
    797 };
    798 
    799 static const str_map redeye_reduction[] = {
    800     { QCameraParameters::REDEYE_REDUCTION_ENABLE, TRUE },
    801     { QCameraParameters::REDEYE_REDUCTION_DISABLE, FALSE }
    802 };
    803 
    804 static const str_map zsl_modes[] = {
    805     { QCameraParameters::ZSL_OFF, FALSE  },
    806     { QCameraParameters::ZSL_ON, TRUE },
    807 };
    808 
    809 /*
    810  * Values based on aec.c
    811  */
    812 #define DONT_CARE_COORDINATE -1
    813 #define CAMERA_HISTOGRAM_ENABLE 1
    814 #define CAMERA_HISTOGRAM_DISABLE 0
    815 #define HISTOGRAM_STATS_SIZE 257
    816 
    817 /*
    818  * Values based on aec.c
    819  */
    820 #define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
    821 #define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
    822 #define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
    823 #define EXPOSURE_COMPENSATION_DENOMINATOR 6
    824 #define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
    825 
    826 static const str_map picture_formats[] = {
    827         {QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
    828         {QCameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
    829 };
    830 
    831 static const str_map recording_Hints[] = {
    832         {"false", FALSE},
    833         {"true",  TRUE}
    834 };
    835 
    836 static const str_map picture_formats_zsl[] = {
    837         {QCameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG}
    838 };
    839 
    840 static const str_map frame_rate_modes[] = {
    841         {QCameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
    842         {QCameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
    843 };
    844 
    845 static int mPreviewFormat;
    846 static const str_map preview_formats[] = {
    847         {QCameraParameters::PIXEL_FORMAT_YUV420SP,   CAMERA_YUV_420_NV21},
    848         {QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO},
    849         {QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12}
    850 };
    851 static const str_map preview_formats1[] = {
    852         {QCameraParameters::PIXEL_FORMAT_YUV420SP,   CAMERA_YUV_420_NV21},
    853         {QCameraParameters::PIXEL_FORMAT_YUV420P, CAMERA_YUV_420_YV12}
    854 };
    855 
    856 static const str_map app_preview_formats[] = {
    857 {QCameraParameters::PIXEL_FORMAT_YUV420SP,   HAL_PIXEL_FORMAT_YCrCb_420_SP}, //nv21
    858 //{QCameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO}, //nv21_adreno
    859 {QCameraParameters::PIXEL_FORMAT_YUV420P, HAL_PIXEL_FORMAT_YV12}, //YV12
    860 };
    861 
    862 
    863 static bool parameter_string_initialized = false;
    864 static String8 preview_size_values;
    865 static String8 hfr_size_values;
    866 static String8 picture_size_values;
    867 static String8 fps_ranges_supported_values;
    868 static String8 jpeg_thumbnail_size_values;
    869 static String8 antibanding_values;
    870 static String8 effect_values;
    871 static String8 autoexposure_values;
    872 static String8 whitebalance_values;
    873 static String8 flash_values;
    874 static String8 focus_mode_values;
    875 static String8 iso_values;
    876 static String8 lensshade_values;
    877 static String8 mce_values;
    878 static String8 hdr_values;
    879 static String8 histogram_values;
    880 static String8 skinToneEnhancement_values;
    881 static String8 touchafaec_values;
    882 static String8 picture_format_values;
    883 static String8 scenemode_values;
    884 static String8 denoise_values;
    885 static String8 zoom_ratio_values;
    886 static String8 preview_frame_rate_values;
    887 static String8 frame_rate_mode_values;
    888 static String8 scenedetect_values;
    889 static String8 preview_format_values;
    890 static String8 selectable_zone_af_values;
    891 static String8 facedetection_values;
    892 static String8 hfr_values;
    893 static String8 redeye_reduction_values;
    894 static String8 zsl_values;
    895 
    896 mm_camera_notify mCamNotify;
    897 mm_camera_ops mCamOps;
    898 static mm_camera_buffer_t mEncodeOutputBuffer[MAX_SNAPSHOT_BUFFERS];
    899 static encode_params_t mImageEncodeParms;
    900 static capture_params_t mImageCaptureParms;
    901 static raw_capture_params_t mRawCaptureParms;
    902 static zsl_capture_params_t mZslCaptureParms;
    903 static zsl_params_t mZslParms;
    904 static yv12_format_parms_t myv12_params;
    905 
    906 static String8 create_sizes_str(const camera_size_type *sizes, int len) {
    907     String8 str;
    908     char buffer[32];
    909 
    910     if (len > 0) {
    911         sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
    912         str.append(buffer);
    913     }
    914     for (int i = 1; i < len; i++) {
    915         sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
    916         str.append(buffer);
    917     }
    918     return str;
    919 }
    920 
    921 static String8 create_fps_str(const android:: FPSRange* fps, int len) {
    922     String8 str;
    923     char buffer[32];
    924 
    925     if (len > 0) {
    926         sprintf(buffer, "(%d,%d)", fps[0].minFPS, fps[0].maxFPS);
    927         str.append(buffer);
    928     }
    929     for (int i = 1; i < len; i++) {
    930         sprintf(buffer, ",(%d,%d)", fps[i].minFPS, fps[i].maxFPS);
    931         str.append(buffer);
    932     }
    933     return str;
    934 }
    935 
    936 static String8 create_values_str(const str_map *values, int len) {
    937     String8 str;
    938 
    939     if (len > 0) {
    940         str.append(values[0].desc);
    941     }
    942     for (int i = 1; i < len; i++) {
    943         str.append(",");
    944         str.append(values[i].desc);
    945     }
    946     return str;
    947 }
    948 
    949 
    950 static String8 create_str(int16_t *arr, int length){
    951     String8 str;
    952     char buffer[32];
    953 
    954     if(length > 0){
    955         snprintf(buffer, sizeof(buffer), "%d", arr[0]);
    956         str.append(buffer);
    957     }
    958 
    959     for (int i =1;i<length;i++){
    960         snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
    961         str.append(buffer);
    962     }
    963     return str;
    964 }
    965 
    966 static String8 create_values_range_str(int min, int max){
    967     String8 str;
    968     char buffer[32];
    969 
    970     if(min <= max){
    971         snprintf(buffer, sizeof(buffer), "%d", min);
    972         str.append(buffer);
    973 
    974         for (int i = min + 1; i <= max; i++) {
    975             snprintf(buffer, sizeof(buffer), ",%d", i);
    976             str.append(buffer);
    977         }
    978     }
    979     return str;
    980 }
    981 
    982 extern "C" {
    983 //------------------------------------------------------------------------
    984 //   : 720p busyQ funcitons
    985 //   --------------------------------------------------------------------
    986 static struct fifo_queue g_busy_frame_queue =
    987     {0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, (char *)"video_busy_q"};
    988 };
    989 
    990 static void cam_frame_wait_video (void)
    991 {
    992     ALOGV("cam_frame_wait_video E ");
    993     if ((g_busy_frame_queue.num_of_frames) <=0){
    994         pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut));
    995     }
    996     ALOGV("cam_frame_wait_video X");
    997     return;
    998 }
    999 
   1000 void cam_frame_flush_video (void)
   1001 {
   1002     ALOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames);
   1003     pthread_mutex_lock(&(g_busy_frame_queue.mut));
   1004 
   1005     while (g_busy_frame_queue.front)
   1006     {
   1007        //dequeue from the busy queue
   1008        struct fifo_node *node  = dequeue (&g_busy_frame_queue);
   1009        if(node)
   1010            free(node);
   1011 
   1012        ALOGV("cam_frame_flush_video: node \n");
   1013     }
   1014     pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   1015     ALOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames);
   1016     return ;
   1017 }
   1018 
   1019 static struct msm_frame * cam_frame_get_video()
   1020 {
   1021     struct msm_frame *p = NULL;
   1022     ALOGV("cam_frame_get_video... in\n");
   1023     ALOGV("cam_frame_get_video... got lock\n");
   1024     if (g_busy_frame_queue.front)
   1025     {
   1026         //dequeue
   1027        struct fifo_node *node  = dequeue (&g_busy_frame_queue);
   1028        if (node)
   1029        {
   1030            p = (struct msm_frame *)node->f;
   1031            free (node);
   1032        }
   1033        ALOGV("cam_frame_get_video... out = %x\n", p->buffer);
   1034     }
   1035     return p;
   1036 }
   1037 
   1038 // Parse string like "(1, 2, 3, 4, ..., N)"
   1039 // num is pointer to an allocated array of size N
   1040 static int parseNDimVector_HAL(const char *str, int *num, int N, char delim = ',')
   1041 {
   1042     char *start, *end;
   1043     if(num == NULL) {
   1044         ALOGE("Invalid output array (num == NULL)");
   1045         return -1;
   1046     }
   1047     //check if string starts and ends with parantheses
   1048     if(str[0] != '(' || str[strlen(str)-1] != ')') {
   1049         ALOGE("Invalid format of string %s, valid format is (n1, n2, n3, n4 ...)", str);
   1050         return -1;
   1051     }
   1052     start = (char*) str;
   1053     start++;
   1054     for(int i=0; i<N; i++) {
   1055         *(num+i) = (int) strtol(start, &end, 10);
   1056         if(*end != delim && i < N-1) {
   1057             ALOGE("Cannot find delimeter '%c' in string \"%s\". end = %c", delim, str, *end);
   1058             return -1;
   1059         }
   1060         start = end+1;
   1061     }
   1062     return 0;
   1063 }
   1064 static int countChar(const char *str , char ch )
   1065 {
   1066     int noOfChar = 0;
   1067 
   1068     for ( int i = 0; str[i] != '\0'; i++) {
   1069         if ( str[i] == ch )
   1070           noOfChar = noOfChar + 1;
   1071     }
   1072 
   1073     return noOfChar;
   1074 }
   1075 int checkAreaParameters(const char *str)
   1076 {
   1077     int areaValues[6];
   1078     int left, right, top, bottom, weight;
   1079 
   1080     if(countChar(str, ',') > 4) {
   1081         ALOGE("%s: No of area parameters exceeding the expected number %s", __FUNCTION__, str);
   1082         return -1;
   1083     }
   1084 
   1085     if(parseNDimVector_HAL(str, areaValues, 5) !=0) {
   1086         ALOGE("%s: Failed to parse the input string %s", __FUNCTION__, str);
   1087         return -1;
   1088     }
   1089 
   1090     ALOGV("%s: Area values are %d,%d,%d,%d,%d", __FUNCTION__,
   1091           areaValues[0], areaValues[1], areaValues[2], areaValues[3], areaValues[4]);
   1092 
   1093     left = areaValues[0];
   1094     top = areaValues[1];
   1095     right = areaValues[2];
   1096     bottom = areaValues[3];
   1097     weight = areaValues[4];
   1098 
   1099     // left should >= -1000
   1100     if (!(left >= -1000))
   1101         return -1;
   1102     // top should >= -1000
   1103     if(!(top >= -1000))
   1104         return -1;
   1105     // right should <= 1000
   1106     if(!(right <= 1000))
   1107         return -1;
   1108     // bottom should <= 1000
   1109     if(!(bottom <= 1000))
   1110         return -1;
   1111     // weight should >= 1
   1112     // weight should <= 1000
   1113     if(!((1 <= weight) && (weight <= 1000)))
   1114         return -1;
   1115     // left should < right
   1116     if(!(left < right))
   1117         return -1;
   1118     // top should < bottom
   1119     if(!(top < bottom))
   1120         return -1;
   1121 
   1122     return 0;
   1123 }
   1124 
   1125 static void cam_frame_post_video (struct msm_frame *p)
   1126 {
   1127     if (!p)
   1128     {
   1129         ALOGE("post video , buffer is null");
   1130         return;
   1131     }
   1132     ALOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer));
   1133     pthread_mutex_lock(&(g_busy_frame_queue.mut));
   1134     ALOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames);
   1135     //enqueue to busy queue
   1136     struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node));
   1137     if (node)
   1138     {
   1139         ALOGV(" post video , enqueing in busy queue");
   1140         node->f = p;
   1141         node->next = NULL;
   1142         enqueue (&g_busy_frame_queue, node);
   1143         ALOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames);
   1144     }
   1145     else
   1146     {
   1147         ALOGE("cam_frame_post_video error... out of memory\n");
   1148     }
   1149 
   1150     pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   1151     pthread_cond_signal(&(g_busy_frame_queue.wait));
   1152 
   1153     ALOGV("cam_frame_post_video... out = %x\n", p->buffer);
   1154 
   1155     return;
   1156 }
   1157 
   1158 QualcommCameraHardware::FrameQueue::FrameQueue(){
   1159     mInitialized = false;
   1160 }
   1161 
   1162 QualcommCameraHardware::FrameQueue::~FrameQueue(){
   1163     flush();
   1164 }
   1165 
   1166 void QualcommCameraHardware::FrameQueue::init(){
   1167     Mutex::Autolock l(&mQueueLock);
   1168     mInitialized = true;
   1169     mQueueWait.signal();
   1170 }
   1171 
   1172 void QualcommCameraHardware::FrameQueue::deinit(){
   1173     Mutex::Autolock l(&mQueueLock);
   1174     mInitialized = false;
   1175     mQueueWait.signal();
   1176 }
   1177 
   1178 bool QualcommCameraHardware::FrameQueue::isInitialized(){
   1179    Mutex::Autolock l(&mQueueLock);
   1180    return mInitialized;
   1181 }
   1182 
   1183 bool QualcommCameraHardware::FrameQueue::add(
   1184                 struct msm_frame * element){
   1185     Mutex::Autolock l(&mQueueLock);
   1186     if(mInitialized == false)
   1187         return false;
   1188 
   1189     mContainer.add(element);
   1190     mQueueWait.signal();
   1191     return true;
   1192 }
   1193 
   1194 struct msm_frame * QualcommCameraHardware::FrameQueue::get(){
   1195 
   1196     struct msm_frame *frame;
   1197     mQueueLock.lock();
   1198     while(mInitialized && mContainer.isEmpty()){
   1199         mQueueWait.wait(mQueueLock);
   1200     }
   1201 
   1202     if(!mInitialized){
   1203         mQueueLock.unlock();
   1204         return NULL;
   1205     }
   1206 
   1207     frame = mContainer.itemAt(0);
   1208     mContainer.removeAt(0);
   1209     mQueueLock.unlock();
   1210     return frame;
   1211 }
   1212 
   1213 void QualcommCameraHardware::FrameQueue::flush(){
   1214     Mutex::Autolock l(&mQueueLock);
   1215     mContainer.clear();
   1216 
   1217 }
   1218 
   1219 
   1220 void QualcommCameraHardware::storeTargetType(void) {
   1221     char mDeviceName[PROPERTY_VALUE_MAX];
   1222     property_get("ro.product.device",mDeviceName," ");
   1223     mCurrentTarget = TARGET_MAX;
   1224     for( int i = 0; i < TARGET_MAX ; i++) {
   1225        if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) {
   1226          mCurrentTarget = targetList[i].targetEnum;
   1227          if(mCurrentTarget == TARGET_MSM7625) {
   1228            if(!strncmp(mDeviceName, "msm7625a" , 8))
   1229              mCurrentTarget = TARGET_MSM7625A;
   1230             }
   1231            if(mCurrentTarget == TARGET_MSM7627) {
   1232              if(!strncmp(mDeviceName, "msm7627a" , 8))
   1233                mCurrentTarget = TARGET_MSM7627A;
   1234            }
   1235            break;
   1236        }
   1237     }
   1238     ALOGV(" Storing the current target type as %d ", mCurrentTarget );
   1239     return;
   1240 }
   1241 
   1242 void *openCamera(void *data) {
   1243     ALOGV(" openCamera : E");
   1244     mCameraOpen = false;
   1245 
   1246     if (!libmmcamera) {
   1247         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   1248         return false;
   1249     }
   1250 
   1251     *(void **)&LINK_mm_camera_init =
   1252         ::dlsym(libmmcamera, "mm_camera_init");
   1253 
   1254     *(void **)&LINK_mm_camera_exec =
   1255         ::dlsym(libmmcamera, "mm_camera_exec");
   1256 
   1257     *(void **)&LINK_mm_camera_deinit =
   1258         ::dlsym(libmmcamera, "mm_camera_deinit");
   1259 
   1260 
   1261     if (MM_CAMERA_SUCCESS != LINK_mm_camera_init(&mCfgControl, &mCamNotify, &mCamOps, 0)) {
   1262         ALOGE("startCamera: mm_camera_init failed:");
   1263         return false;
   1264         //pthread_exit((void*) ret_val);
   1265     }
   1266 
   1267     uint8_t camera_id8 = (uint8_t)HAL_currentCameraId;
   1268     if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_CAMERA_ID, &camera_id8)) {
   1269         ALOGE("setting camera id failed");
   1270         LINK_mm_camera_deinit();
   1271         return false;
   1272         //pthread_exit((void*) ret_val);
   1273     }
   1274 
   1275     //camera_mode_t mode = (camera_mode_t)HAL_currentCameraMode;
   1276     camera_mode_t mode = CAMERA_MODE_2D;
   1277     if (MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_MODE, &mode)) {
   1278         ALOGE("startCamera: CAMERA_PARM_MODE failed:");
   1279         LINK_mm_camera_deinit();
   1280         return false;
   1281         //pthread_exit((void*) ret_val);
   1282     }
   1283 
   1284     if (MM_CAMERA_SUCCESS != LINK_mm_camera_exec()) {
   1285         ALOGE("startCamera: mm_camera_exec failed:");
   1286         return false;
   1287         //pthread_exit((void*) ret_val);
   1288     }
   1289     mCameraOpen = true;
   1290     ALOGV(" openCamera : X");
   1291     if (CAMERA_MODE_3D == mode) {
   1292         camera_3d_frame_t snapshotFrame;
   1293         snapshotFrame.frame_type = CAM_SNAPSHOT_FRAME;
   1294         if(MM_CAMERA_SUCCESS !=
   1295             mCfgControl.mm_camera_get_parm(CAMERA_PARM_3D_FRAME_FORMAT,
   1296                 (void *)&snapshotFrame)){
   1297             ALOGE("%s: get 3D format failed", __func__);
   1298             LINK_mm_camera_deinit();
   1299             return false;
   1300             //pthread_exit((void*) ret_val);
   1301         }
   1302         QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   1303         if (obj != 0) {
   1304             obj->mSnapshot3DFormat = snapshotFrame.format;
   1305             ALOGI("%s: 3d format  snapshot %d", __func__, obj->mSnapshot3DFormat);
   1306         }
   1307     }
   1308 
   1309     ALOGV("openCamera : X");
   1310 //    pthread_exit((void*) ret_val);
   1311 
   1312     return NULL;
   1313 }
   1314 //-------------------------------------------------------------------------------------
   1315 static Mutex singleton_lock;
   1316 static bool singleton_releasing;
   1317 static nsecs_t singleton_releasing_start_time;
   1318 static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5);
   1319 static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1);
   1320 static Condition singleton_wait;
   1321 
   1322 static void receive_camframe_callback(struct msm_frame *frame);
   1323 static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size);
   1324 static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo);
   1325 static void receive_camframe_video_callback(struct msm_frame *frame); // 720p
   1326 static int8_t receive_event_callback(mm_camera_event* event);
   1327 static void receive_shutter_callback(common_crop_t *crop);
   1328 static void receive_camframe_error_callback(camera_error_type err);
   1329 static int fb_fd = -1;
   1330 static int32_t mMaxZoom = 0;
   1331 static bool zoomSupported = false;
   1332 static int dstOffset = 0;
   1333 
   1334 static int16_t * zoomRatios;
   1335 
   1336 
   1337 /* When using MDP zoom, double the preview buffers. The usage of these
   1338  * buffers is as follows:
   1339  * 1. As all the buffers comes under a single FD, and at initial registration,
   1340  * this FD will be passed to surface flinger, surface flinger can have access
   1341  * to all the buffers when needed.
   1342  * 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the
   1343  * camera driver to receive preview frames. The remaining buffers (DstSet),
   1344  * will be used at HAL and by surface flinger only when crop information
   1345  * is present in the frame.
   1346  * 3. When there is no crop information, there will be no call to MDP zoom,
   1347  * and the buffers in SrcSet will be passed to surface flinger to display.
   1348  * 4. With crop information present, MDP zoom will be called, and the final
   1349  * data will be placed in a buffer from DstSet, and this buffer will be given
   1350  * to surface flinger to display.
   1351  */
   1352 #define NUM_MORE_BUFS 2
   1353 
   1354 QualcommCameraHardware::QualcommCameraHardware()
   1355     : mParameters(),
   1356       mCameraRunning(false),
   1357       mPreviewInitialized(false),
   1358       mPreviewThreadRunning(false),
   1359       mHFRThreadRunning(false),
   1360       mFrameThreadRunning(false),
   1361       mVideoThreadRunning(false),
   1362       mSnapshotThreadRunning(false),
   1363       mJpegThreadRunning(false),
   1364       mSmoothzoomThreadRunning(false),
   1365       mSmoothzoomThreadExit(false),
   1366       mInSnapshotMode(false),
   1367       mEncodePending(false),
   1368       mBuffersInitialized(false),
   1369       mSnapshotFormat(0),
   1370       mFirstFrame(true),
   1371       mReleasedRecordingFrame(false),
   1372       mPreviewFrameSize(0),
   1373       mRawSize(0),
   1374       mCbCrOffsetRaw(0),
   1375       mYOffset(0),
   1376       mAutoFocusThreadRunning(false),
   1377       mInitialized(false),
   1378       mBrightness(0),
   1379       mSkinToneEnhancement(0),
   1380       mHJR(0),
   1381       mInPreviewCallback(false),
   1382       //mUseOverlay(0),
   1383       mIs3DModeOn(0),
   1384       //mOverlay(0),
   1385       mMsgEnabled(0),
   1386       mNotifyCallback(0),
   1387       mDataCallback(0),
   1388       mDataCallbackTimestamp(0),
   1389       mCallbackCookie(0),
   1390       mDebugFps(0),
   1391       mSnapshotDone(0),
   1392       maxSnapshotWidth(0),
   1393       maxSnapshotHeight(0),
   1394       mHasAutoFocusSupport(0),
   1395       mDisEnabled(0),
   1396       mRotation(0),
   1397       mResetWindowCrop(false),
   1398       mThumbnailWidth(0),
   1399       mThumbnailHeight(0),
   1400       strTexturesOn(false),
   1401       mPictureWidth(0),
   1402       mPictureHeight(0),
   1403       mPostviewWidth(0),
   1404       mPostviewHeight(0),
   1405       mPreviewWindow(NULL),
   1406       mTotalPreviewBufferCount(0),
   1407       mZslFlashEnable(false),
   1408       mZslPanorama(false),
   1409       mSnapshotCancel(false),
   1410       mHFRMode(false),
   1411       mActualPictWidth(0),
   1412       mActualPictHeight(0),
   1413       mDenoiseValue(0),
   1414       mPreviewStopping(false),
   1415       mInHFRThread(false),
   1416       mPrevHeapDeallocRunning(false),
   1417       mHdrMode(false ),
   1418       mExpBracketMode(false),
   1419       mZslEnable(false),
   1420       mStoreMetaDataInFrame(0),
   1421       mRecordingState(0)
   1422 {
   1423     ALOGI("QualcommCameraHardware constructor E");
   1424     mMMCameraDLRef = MMCameraDL::getInstance();
   1425     libmmcamera = mMMCameraDLRef->pointer();
   1426     char value[PROPERTY_VALUE_MAX];
   1427     mCameraOpen = false;
   1428     /*if(HAL_currentSnapshotMode == CAMERA_SNAPSHOT_ZSL) {
   1429         ALOGI("%s: this is ZSL mode", __FUNCTION__);
   1430         mZslEnable = true;
   1431     }*/
   1432 
   1433     property_get("persist.camera.hal.multitouchaf", value, "0");
   1434     mMultiTouch = atoi(value);
   1435 
   1436     storeTargetType();
   1437     for(int i=0; i< MAX_SNAPSHOT_BUFFERS; i++) {
   1438        mRawMapped[i] = NULL;
   1439        mJpegMapped[i] = NULL;
   1440        mThumbnailMapped[i] = NULL;
   1441     }
   1442     mRawSnapshotMapped = NULL;
   1443     mJpegCopyMapped = NULL;
   1444 	for(int i=0; i< RECORD_BUFFERS; i++) {
   1445         mRecordMapped[i] = NULL;
   1446     }
   1447 
   1448     for(int i=0; i<3; i++)
   1449         mStatsMapped[i] = NULL;
   1450 
   1451     mJpegLiveSnapMapped = NULL;
   1452     if(HAL_currentCameraMode == CAMERA_SUPPORT_MODE_3D){
   1453         mIs3DModeOn = true;
   1454     }
   1455     /* TODO: Will remove this command line interface at end */
   1456     property_get("persist.camera.hal.3dmode", value, "0");
   1457     int mode = atoi(value);
   1458     if( mode  == 1) {
   1459         mIs3DModeOn = true;
   1460         HAL_currentCameraMode = CAMERA_MODE_3D;
   1461     }
   1462 
   1463     if( (pthread_create(&mDeviceOpenThread, NULL, openCamera, NULL)) != 0) {
   1464         ALOGE(" openCamera thread creation failed ");
   1465     }
   1466     memset(&mDimension, 0, sizeof(mDimension));
   1467     memset(&mCrop, 0, sizeof(mCrop));
   1468     memset(&zoomCropInfo, 0, sizeof(android_native_rect_t));
   1469     //storeTargetType();
   1470     property_get("persist.debug.sf.showfps", value, "0");
   1471     mDebugFps = atoi(value);
   1472     if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) {
   1473         kPreviewBufferCountActual = kPreviewBufferCount;
   1474         kRecordBufferCount = RECORD_BUFFERS;
   1475         recordframes = new msm_frame[kRecordBufferCount];
   1476         record_buffers_tracking_flag = new bool[kRecordBufferCount];
   1477     }
   1478     else {
   1479         kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS;
   1480         if( mCurrentTarget == TARGET_QSD8250 ) {
   1481             kRecordBufferCount = RECORD_BUFFERS_8x50;
   1482             recordframes = new msm_frame[kRecordBufferCount];
   1483             record_buffers_tracking_flag = new bool[kRecordBufferCount];
   1484         }
   1485     }
   1486     mTotalPreviewBufferCount = kTotalPreviewBufferCount;
   1487     if((mCurrentTarget != TARGET_MSM7630 ) &&  (mCurrentTarget != TARGET_QSD8250)
   1488       && (mCurrentTarget != TARGET_MSM8660)) {
   1489         for (int i = 0; i < mTotalPreviewBufferCount; i++)
   1490           metadata_memory[i] = NULL;
   1491     }
   1492     else {
   1493         for (int i = 0; i < kRecordBufferCount; i++)
   1494           metadata_memory[i] = NULL;
   1495     }
   1496     switch(mCurrentTarget){
   1497         case TARGET_MSM7627:
   1498         case TARGET_MSM7627A:
   1499             jpegPadding = 0; // to be checked.
   1500             break;
   1501         case TARGET_QSD8250:
   1502         case TARGET_MSM7630:
   1503         case TARGET_MSM8660:
   1504             jpegPadding = 0;
   1505             break;
   1506         default:
   1507             jpegPadding = 0;
   1508             break;
   1509     }
   1510     // Initialize with default format values. The format values can be
   1511     // overriden when application requests.
   1512     mDimension.prev_format     = CAMERA_YUV_420_NV21;
   1513     mPreviewFormat             = CAMERA_YUV_420_NV21;
   1514     mDimension.enc_format      = CAMERA_YUV_420_NV21;
   1515     if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
   1516         mDimension.enc_format  = CAMERA_YUV_420_NV12;
   1517     mDimension.main_img_format = CAMERA_YUV_420_NV21;
   1518     mDimension.thumb_format    = CAMERA_YUV_420_NV21;
   1519 
   1520     if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){
   1521         /* DIS is disabled all the time in VPE support targets.
   1522          * No provision for the user to control this.
   1523          */
   1524         mDisEnabled = 0;
   1525         /* Get the DIS value from properties, to check whether
   1526          * DIS is disabled or not. If the property is not found
   1527          * default to DIS disabled.*/
   1528         property_get("persist.camera.hal.dis", value, "0");
   1529         mDisEnabled = atoi(value);
   1530         mVpeEnabled = 1;
   1531     }
   1532     if(mIs3DModeOn) {
   1533         mDisEnabled = 0;
   1534     }
   1535     ALOGV("constructor EX");
   1536 }
   1537 
   1538 void QualcommCameraHardware::hasAutoFocusSupport(){
   1539     if( !mCamOps.mm_camera_is_supported(CAMERA_OPS_FOCUS)){
   1540         ALOGI("AutoFocus is not supported");
   1541         mHasAutoFocusSupport = false;
   1542     }else {
   1543         mHasAutoFocusSupport = true;
   1544     }
   1545     if(mZslEnable)
   1546         mHasAutoFocusSupport = false;
   1547 }
   1548 
   1549 //filter Picture sizes based on max width and height
   1550 void QualcommCameraHardware::filterPictureSizes(){
   1551     unsigned int i;
   1552     if(PICTURE_SIZE_COUNT <= 0)
   1553         return;
   1554     maxSnapshotWidth = picture_sizes[0].width;
   1555     maxSnapshotHeight = picture_sizes[0].height;
   1556    // Iterate through all the width and height to find the max value
   1557     for(i =0; i<PICTURE_SIZE_COUNT;i++){
   1558         if(((maxSnapshotWidth < picture_sizes[i].width) &&
   1559             (maxSnapshotHeight <= picture_sizes[i].height))){
   1560             maxSnapshotWidth = picture_sizes[i].width;
   1561             maxSnapshotHeight = picture_sizes[i].height;
   1562         }
   1563     }
   1564     if(mZslEnable){
   1565         // due to lack of PMEM we restrict to lower resolution
   1566         picture_sizes_ptr = zsl_picture_sizes;
   1567         supportedPictureSizesCount = 7;
   1568     }
   1569     else if(mIs3DModeOn){
   1570      // In 3D mode we only want 1080p picture size
   1571       picture_sizes_ptr = for_3D_picture_sizes;
   1572       supportedPictureSizesCount = 1;
   1573     }
   1574     else{
   1575     picture_sizes_ptr = picture_sizes;
   1576     supportedPictureSizesCount = PICTURE_SIZE_COUNT;
   1577     }
   1578 }
   1579 
   1580 bool QualcommCameraHardware::supportsSceneDetection() {
   1581    unsigned int prop = 0;
   1582    for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
   1583        if((mCurrentTarget == boardProperties[prop].target)
   1584           && boardProperties[prop].hasSceneDetect == true) {
   1585            return true;
   1586            break;
   1587        }
   1588    }
   1589    return false;
   1590 }
   1591 
   1592 bool QualcommCameraHardware::supportsSelectableZoneAf() {
   1593    unsigned int prop = 0;
   1594    for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
   1595        if((mCurrentTarget == boardProperties[prop].target)
   1596           && boardProperties[prop].hasSelectableZoneAf == true) {
   1597            return true;
   1598            break;
   1599        }
   1600    }
   1601    return false;
   1602 }
   1603 
   1604 bool QualcommCameraHardware::supportsFaceDetection() {
   1605    unsigned int prop = 0;
   1606    for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
   1607        if((mCurrentTarget == boardProperties[prop].target)
   1608           && boardProperties[prop].hasFaceDetect == true) {
   1609            return true;
   1610            break;
   1611        }
   1612    }
   1613    return false;
   1614 }
   1615 
   1616 void QualcommCameraHardware::initDefaultParameters()
   1617 {
   1618     ALOGV("initDefaultParameters E");
   1619     mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
   1620     mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
   1621     mDimension.ui_thumbnail_width =
   1622             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
   1623     mDimension.ui_thumbnail_height =
   1624             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   1625     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   1626                sizeof(cam_ctrl_dimension_t),(void *) &mDimension);
   1627     if(ret != true) {
   1628         ALOGE("CAMERA_PARM_DIMENSION failed!!!");
   1629         return;
   1630     }
   1631     hasAutoFocusSupport();
   1632     //Disable DIS for Web Camera
   1633     if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_VIDEO_DIS)){
   1634         ALOGI("DISABLE DIS");
   1635         mDisEnabled = 0;
   1636     }else {
   1637         ALOGI("Enable DIS");
   1638     }
   1639     // Initialize constant parameter strings. This will happen only once in the
   1640     // lifetime of the mediaserver process.
   1641     if (!parameter_string_initialized) {
   1642         if(mIs3DModeOn){
   1643           antibanding_values = create_values_str(
   1644             antibanding_3D, sizeof(antibanding_3D) / sizeof(str_map));
   1645         } else{
   1646         antibanding_values = create_values_str(
   1647             antibanding, sizeof(antibanding) / sizeof(str_map));
   1648         }
   1649         effect_values = create_values_str(
   1650             effects, sizeof(effects) / sizeof(str_map));
   1651         autoexposure_values = create_values_str(
   1652             autoexposure, sizeof(autoexposure) / sizeof(str_map));
   1653         whitebalance_values = create_values_str(
   1654             whitebalance, sizeof(whitebalance) / sizeof(str_map));
   1655         //filter picture sizes
   1656         filterPictureSizes();
   1657         picture_size_values = create_sizes_str(
   1658                 picture_sizes_ptr, supportedPictureSizesCount);
   1659         preview_size_values = create_sizes_str(
   1660                 preview_sizes,  PREVIEW_SIZE_COUNT);
   1661         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
   1662                             preview_size_values.string());
   1663 
   1664         mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
   1665                             preview_size_values.string());
   1666 
   1667         mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
   1668                             picture_size_values.string());
   1669         mParameters.set(QCameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
   1670                             "true");
   1671         mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   1672                        QCameraParameters::FOCUS_MODE_INFINITY);
   1673         mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   1674                        QCameraParameters::FOCUS_MODE_INFINITY);
   1675         mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
   1676 
   1677         mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, FOCUS_AREA_INIT);
   1678         mParameters.set(QCameraParameters::KEY_METERING_AREAS, FOCUS_AREA_INIT);
   1679 
   1680         if(!mIs3DModeOn){
   1681         hfr_size_values = create_sizes_str(
   1682                 hfr_sizes, HFR_SIZE_COUNT);
   1683         }
   1684         fps_ranges_supported_values = create_fps_str(
   1685             FpsRangesSupported,FPS_RANGES_SUPPORTED_COUNT );
   1686         mParameters.set(
   1687             QCameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
   1688             fps_ranges_supported_values);
   1689         mParameters.setPreviewFpsRange(MINIMUM_FPS*1000,MAXIMUM_FPS*1000);
   1690 
   1691         flash_values = create_values_str(
   1692             flash, sizeof(flash) / sizeof(str_map));
   1693         if(mHasAutoFocusSupport){
   1694             focus_mode_values = create_values_str(
   1695                     focus_modes, sizeof(focus_modes) / sizeof(str_map));
   1696         }
   1697         if(mIs3DModeOn){
   1698           iso_values = create_values_str(
   1699               iso_3D,sizeof(iso_3D)/sizeof(str_map));
   1700         } else{
   1701            iso_values = create_values_str(
   1702               iso,sizeof(iso)/sizeof(str_map));
   1703         }
   1704         lensshade_values = create_values_str(
   1705             lensshade,sizeof(lensshade)/sizeof(str_map));
   1706         mce_values = create_values_str(
   1707             mce,sizeof(mce)/sizeof(str_map));
   1708         if(!mIs3DModeOn){
   1709           hfr_values = create_values_str(
   1710             hfr,sizeof(hfr)/sizeof(str_map));
   1711         }
   1712         if(mCurrentTarget == TARGET_MSM8660)
   1713             hdr_values = create_values_str(
   1714                 hdr,sizeof(hdr)/sizeof(str_map));
   1715         //Currently Enabling Histogram for 8x60
   1716         if(mCurrentTarget == TARGET_MSM8660) {
   1717             histogram_values = create_values_str(
   1718                 histogram,sizeof(histogram)/sizeof(str_map));
   1719         }
   1720         //Currently Enabling Skin Tone Enhancement for 8x60 and 7630
   1721         if((mCurrentTarget == TARGET_MSM8660)||(mCurrentTarget == TARGET_MSM7630)) {
   1722             skinToneEnhancement_values = create_values_str(
   1723                 skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map));
   1724         }
   1725         if(mHasAutoFocusSupport){
   1726             touchafaec_values = create_values_str(
   1727                 touchafaec,sizeof(touchafaec)/sizeof(str_map));
   1728         }
   1729         zsl_values = create_values_str(
   1730             zsl_modes,sizeof(zsl_modes)/sizeof(str_map));
   1731 
   1732         if(mZslEnable){
   1733            picture_format_values = create_values_str(
   1734                picture_formats_zsl, sizeof(picture_formats_zsl)/sizeof(str_map));
   1735         } else{
   1736            picture_format_values = create_values_str(
   1737                picture_formats, sizeof(picture_formats)/sizeof(str_map));
   1738         }
   1739         if(mCurrentTarget == TARGET_MSM8660 ||
   1740           (mCurrentTarget == TARGET_MSM7625A ||
   1741            mCurrentTarget == TARGET_MSM7627A)) {
   1742             denoise_values = create_values_str(
   1743                 denoise, sizeof(denoise) / sizeof(str_map));
   1744         }
   1745        if(mCfgControl.mm_camera_query_parms(CAMERA_PARM_ZOOM_RATIO,
   1746            (void **)&zoomRatios, (uint32_t *) &mMaxZoom) == MM_CAMERA_SUCCESS) {
   1747             zoomSupported = true;
   1748             if( mMaxZoom >0) {
   1749                 ALOGI("Maximum zoom value is %d", mMaxZoom);
   1750                 if(zoomRatios != NULL) {
   1751                     zoom_ratio_values =  create_str(zoomRatios, mMaxZoom);
   1752                 } else {
   1753                     ALOGE("Failed to get zoomratios ..");
   1754                 }
   1755            } else {
   1756                zoomSupported = false;
   1757            }
   1758        } else {
   1759             zoomSupported = false;
   1760             ALOGE("Failed to get maximum zoom value...setting max "
   1761                     "zoom to zero");
   1762             mMaxZoom = 0;
   1763         }
   1764         preview_frame_rate_values = create_values_range_str(
   1765             MINIMUM_FPS, MAXIMUM_FPS);
   1766 
   1767         scenemode_values = create_values_str(
   1768             scenemode, sizeof(scenemode) / sizeof(str_map));
   1769 
   1770         if(supportsSceneDetection()) {
   1771             scenedetect_values = create_values_str(
   1772                 scenedetect, sizeof(scenedetect) / sizeof(str_map));
   1773         }
   1774 
   1775         if(mHasAutoFocusSupport && supportsSelectableZoneAf()){
   1776             selectable_zone_af_values = create_values_str(
   1777                 selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
   1778         }
   1779 
   1780         if(mHasAutoFocusSupport && supportsFaceDetection()) {
   1781             facedetection_values = create_values_str(
   1782                 facedetection, sizeof(facedetection) / sizeof(str_map));
   1783         }
   1784 
   1785         redeye_reduction_values = create_values_str(
   1786             redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map));
   1787 
   1788         parameter_string_initialized = true;
   1789     }
   1790     //set video size
   1791     if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   1792        String8 vSize = create_sizes_str(preview_sizes, 1);
   1793        mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, vSize.string());
   1794     }
   1795     if(mIs3DModeOn){
   1796        ALOGI("In initDefaultParameters - 3D mode on so set the default preview to 1280 x 720");
   1797        mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH_3D, DEFAULT_PREVIEW_HEIGHT_3D);
   1798        mDimension.display_width = DEFAULT_PREVIEW_WIDTH_3D;
   1799        mDimension.display_height = DEFAULT_PREVIEW_HEIGHT_3D;
   1800     } else{
   1801        mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
   1802        mDimension.display_width = DEFAULT_PREVIEW_WIDTH;
   1803        mDimension.display_height = DEFAULT_PREVIEW_HEIGHT;
   1804     }
   1805     mParameters.setPreviewFrameRate(DEFAULT_FPS);
   1806     if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
   1807         mParameters.set(
   1808             QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
   1809             preview_frame_rate_values.string());
   1810      } else {
   1811         mParameters.setPreviewFrameRate(DEFAULT_FIXED_FPS_VALUE);
   1812         mParameters.set(
   1813             QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
   1814             DEFAULT_FIXED_FPS_VALUE);
   1815      }
   1816     mParameters.setPreviewFrameRateMode("frame-rate-auto");
   1817     mParameters.setPreviewFormat("yuv420sp"); // informative
   1818     mParameters.set("overlay-format", HAL_PIXEL_FORMAT_YCbCr_420_SP);
   1819     if(mIs3DModeOn){
   1820       mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH_3D, DEFAULT_PICTURE_HEIGHT_3D);
   1821     } else{
   1822       mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
   1823     }
   1824     mParameters.setPictureFormat("jpeg"); // informative
   1825 
   1826     mParameters.set(QCameraParameters::KEY_VIDEO_FRAME_FORMAT, "yuv420sp");
   1827 
   1828     mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
   1829 
   1830     mParameters.set("power-mode-supported", "false");
   1831 
   1832     mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
   1833                     THUMBNAIL_WIDTH_STR); // informative
   1834     mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
   1835                     THUMBNAIL_HEIGHT_STR); // informative
   1836     mDimension.ui_thumbnail_width =
   1837             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
   1838     mDimension.ui_thumbnail_height =
   1839             thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   1840     mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
   1841 
   1842     String8 valuesStr = create_sizes_str(jpeg_thumbnail_sizes, JPEG_THUMBNAIL_SIZE_COUNT);
   1843     mParameters.set(QCameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
   1844                 valuesStr.string());
   1845 
   1846     // Define CAMERA_SMOOTH_ZOOM in Android.mk file , to enable smoothzoom
   1847 #ifdef CAMERA_SMOOTH_ZOOM
   1848     mParameters.set(QCameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, "true");
   1849 #endif
   1850 
   1851     if(zoomSupported){
   1852         mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "true");
   1853         ALOGI("max zoom is %d", mMaxZoom-1);
   1854         /* mMaxZoom value that the query interface returns is the size
   1855          * of zoom table. So the actual max zoom value will be one
   1856          * less than that value.
   1857          */
   1858         mParameters.set("max-zoom",mMaxZoom-1);
   1859         mParameters.set(QCameraParameters::KEY_ZOOM_RATIOS,
   1860                             zoom_ratio_values);
   1861     } else {
   1862         mParameters.set(QCameraParameters::KEY_ZOOM_SUPPORTED, "false");
   1863     }
   1864     /* Enable zoom support for video application if VPE enabled */
   1865     if(zoomSupported && mVpeEnabled) {
   1866         mParameters.set("video-zoom-support", "true");
   1867     } else {
   1868         mParameters.set("video-zoom-support", "false");
   1869     }
   1870 
   1871     mParameters.set(QCameraParameters::KEY_CAMERA_MODE,0);
   1872 
   1873     mParameters.set(QCameraParameters::KEY_ANTIBANDING,
   1874                     QCameraParameters::ANTIBANDING_OFF);
   1875     mParameters.set(QCameraParameters::KEY_EFFECT,
   1876                     QCameraParameters::EFFECT_NONE);
   1877     mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE,
   1878                     QCameraParameters::AUTO_EXPOSURE_FRAME_AVG);
   1879     mParameters.set(QCameraParameters::KEY_WHITE_BALANCE,
   1880                     QCameraParameters::WHITE_BALANCE_AUTO);
   1881     if( (mCurrentTarget != TARGET_MSM7630)
   1882         && (mCurrentTarget != TARGET_QSD8250)
   1883         && (mCurrentTarget != TARGET_MSM8660)
   1884         && (mCurrentTarget != TARGET_MSM7627A)) {
   1885         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
   1886                     "yuv420sp");
   1887     } else if(mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) {
   1888         preview_format_values = create_values_str(
   1889             preview_formats1, sizeof(preview_formats1) / sizeof(str_map));
   1890         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
   1891                 preview_format_values.string());
   1892     } else {
   1893         preview_format_values = create_values_str(
   1894             preview_formats, sizeof(preview_formats) / sizeof(str_map));
   1895         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
   1896                 preview_format_values.string());
   1897     }
   1898 
   1899     frame_rate_mode_values = create_values_str(
   1900             frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
   1901  if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE)){
   1902         mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
   1903                     frame_rate_mode_values.string());
   1904     }
   1905 
   1906     mParameters.set(QCameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
   1907                     preview_size_values.string());
   1908     mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
   1909                     picture_size_values.string());
   1910     mParameters.set(QCameraParameters::KEY_SUPPORTED_ANTIBANDING,
   1911                     antibanding_values);
   1912     mParameters.set(QCameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
   1913     mParameters.set(QCameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
   1914     mParameters.set(QCameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
   1915                     whitebalance_values);
   1916 
   1917     if(mHasAutoFocusSupport){
   1918        mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   1919                     focus_mode_values);
   1920        mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   1921                     QCameraParameters::FOCUS_MODE_AUTO);
   1922     } else {
   1923        mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   1924                    QCameraParameters::FOCUS_MODE_INFINITY);
   1925        mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   1926                    QCameraParameters::FOCUS_MODE_INFINITY);
   1927     }
   1928 
   1929     mParameters.set(QCameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
   1930                     picture_format_values);
   1931 
   1932     if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_LED_MODE)) {
   1933         mParameters.set(QCameraParameters::KEY_FLASH_MODE,
   1934                         QCameraParameters::FLASH_MODE_OFF);
   1935         mParameters.set(QCameraParameters::KEY_SUPPORTED_FLASH_MODES,
   1936                         flash_values);
   1937     }
   1938 
   1939     mParameters.set(QCameraParameters::KEY_MAX_SHARPNESS,
   1940             CAMERA_MAX_SHARPNESS);
   1941     mParameters.set(QCameraParameters::KEY_MAX_CONTRAST,
   1942             CAMERA_MAX_CONTRAST);
   1943     mParameters.set(QCameraParameters::KEY_MAX_SATURATION,
   1944             CAMERA_MAX_SATURATION);
   1945 
   1946     mParameters.set(
   1947             QCameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
   1948             EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
   1949     mParameters.set(
   1950             QCameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
   1951             EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
   1952     mParameters.set(
   1953             QCameraParameters::KEY_EXPOSURE_COMPENSATION,
   1954             EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
   1955     mParameters.setFloat(
   1956             QCameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
   1957             EXPOSURE_COMPENSATION_STEP);
   1958 
   1959     mParameters.set("luma-adaptation", "3");
   1960     mParameters.set("skinToneEnhancement", "0");
   1961     mParameters.set("zoom-supported", "true");
   1962     mParameters.set("zoom", 0);
   1963     mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT,
   1964                     QCameraParameters::PIXEL_FORMAT_JPEG);
   1965 
   1966     mParameters.set(QCameraParameters::KEY_SHARPNESS,
   1967                     CAMERA_DEF_SHARPNESS);
   1968     mParameters.set(QCameraParameters::KEY_CONTRAST,
   1969                     CAMERA_DEF_CONTRAST);
   1970     mParameters.set(QCameraParameters::KEY_SATURATION,
   1971                     CAMERA_DEF_SATURATION);
   1972 
   1973     mParameters.set(QCameraParameters::KEY_ISO_MODE,
   1974                     QCameraParameters::ISO_AUTO);
   1975     mParameters.set(QCameraParameters::KEY_LENSSHADE,
   1976                     QCameraParameters::LENSSHADE_ENABLE);
   1977     mParameters.set(QCameraParameters::KEY_SUPPORTED_ISO_MODES,
   1978                     iso_values);
   1979     mParameters.set(QCameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
   1980                     lensshade_values);
   1981     mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT,
   1982                     QCameraParameters::MCE_ENABLE);
   1983     mParameters.set(QCameraParameters::KEY_SUPPORTED_MEM_COLOR_ENHANCE_MODES,
   1984                     mce_values);
   1985     if(mCfgControl.mm_camera_is_supported(CAMERA_PARM_HFR) && !(mIs3DModeOn)) {
   1986         mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE,
   1987                     QCameraParameters::VIDEO_HFR_OFF);
   1988         mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,
   1989                     hfr_size_values.string());
   1990         mParameters.set(QCameraParameters::KEY_SUPPORTED_VIDEO_HIGH_FRAME_RATE_MODES,
   1991                     hfr_values);
   1992     } else
   1993         mParameters.set(QCameraParameters::KEY_SUPPORTED_HFR_SIZES,"");
   1994 
   1995     mParameters.set(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING,
   1996                     QCameraParameters::MCE_DISABLE);
   1997     mParameters.set(QCameraParameters::KEY_SUPPORTED_HDR_IMAGING_MODES,
   1998                     hdr_values);
   1999     mParameters.set(QCameraParameters::KEY_HISTOGRAM,
   2000                     QCameraParameters::HISTOGRAM_DISABLE);
   2001     mParameters.set(QCameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
   2002                     histogram_values);
   2003     mParameters.set(QCameraParameters::KEY_SKIN_TONE_ENHANCEMENT,
   2004                     QCameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE);
   2005     mParameters.set(QCameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES,
   2006                     skinToneEnhancement_values);
   2007     mParameters.set(QCameraParameters::KEY_SCENE_MODE,
   2008                     QCameraParameters::SCENE_MODE_AUTO);
   2009     mParameters.set("strtextures", "OFF");
   2010 
   2011     mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_MODES,
   2012                     scenemode_values);
   2013     mParameters.set(QCameraParameters::KEY_DENOISE,
   2014                     QCameraParameters::DENOISE_OFF);
   2015     mParameters.set(QCameraParameters::KEY_SUPPORTED_DENOISE,
   2016                     denoise_values);
   2017 
   2018     //touch af/aec parameters
   2019     mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC,
   2020                     QCameraParameters::TOUCH_AF_AEC_OFF);
   2021     mParameters.set(QCameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
   2022                     touchafaec_values);
   2023     mParameters.set("touchAfAec-dx","100");
   2024     mParameters.set("touchAfAec-dy","100");
   2025     mParameters.set(QCameraParameters::KEY_MAX_NUM_FOCUS_AREAS, "1");
   2026     mParameters.set(QCameraParameters::KEY_MAX_NUM_METERING_AREAS, "1");
   2027 
   2028     mParameters.set(QCameraParameters::KEY_SCENE_DETECT,
   2029                     QCameraParameters::SCENE_DETECT_OFF);
   2030     mParameters.set(QCameraParameters::KEY_SUPPORTED_SCENE_DETECT,
   2031                     scenedetect_values);
   2032     mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF,
   2033                     QCameraParameters::SELECTABLE_ZONE_AF_AUTO);
   2034     mParameters.set(QCameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
   2035                     selectable_zone_af_values);
   2036     mParameters.set(QCameraParameters::KEY_FACE_DETECTION,
   2037                     QCameraParameters::FACE_DETECTION_OFF);
   2038     mParameters.set(QCameraParameters::KEY_SUPPORTED_FACE_DETECTION,
   2039                     facedetection_values);
   2040     mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION,
   2041                     QCameraParameters::REDEYE_REDUCTION_DISABLE);
   2042     mParameters.set(QCameraParameters::KEY_SUPPORTED_REDEYE_REDUCTION,
   2043                     redeye_reduction_values);
   2044     mParameters.set(QCameraParameters::KEY_ZSL,
   2045                     QCameraParameters::ZSL_OFF);
   2046     mParameters.set(QCameraParameters::KEY_SUPPORTED_ZSL_MODES,
   2047                     zsl_values);
   2048 
   2049     float focalLength = 0.0f;
   2050     float horizontalViewAngle = 0.0f;
   2051     float verticalViewAngle = 0.0f;
   2052 
   2053     mCfgControl.mm_camera_get_parm(CAMERA_PARM_FOCAL_LENGTH,
   2054             (void *)&focalLength);
   2055     mParameters.setFloat(QCameraParameters::KEY_FOCAL_LENGTH,
   2056                     focalLength);
   2057     mCfgControl.mm_camera_get_parm(CAMERA_PARM_HORIZONTAL_VIEW_ANGLE,
   2058             (void *)&horizontalViewAngle);
   2059     mParameters.setFloat(QCameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
   2060                     horizontalViewAngle);
   2061     mCfgControl.mm_camera_get_parm(CAMERA_PARM_VERTICAL_VIEW_ANGLE,
   2062             (void *)&verticalViewAngle);
   2063     mParameters.setFloat(QCameraParameters::KEY_VERTICAL_VIEW_ANGLE,
   2064                     verticalViewAngle);
   2065     numCapture = 1;
   2066     if(mZslEnable) {
   2067         int maxSnapshot = MAX_SNAPSHOT_BUFFERS - 2;
   2068         char value[5];
   2069         property_get("persist.camera.hal.capture", value, "1");
   2070         numCapture = atoi(value);
   2071         if(numCapture > maxSnapshot)
   2072             numCapture = maxSnapshot;
   2073         else if(numCapture < 1)
   2074             numCapture = 1;
   2075         mParameters.set("capture-burst-captures-values", maxSnapshot);
   2076         mParameters.set("capture-burst-interval-supported", "false");
   2077     }
   2078     mParameters.set("num-snaps-per-shutter", numCapture);
   2079     ALOGI("%s: setting num-snaps-per-shutter to %d", __FUNCTION__, numCapture);
   2080     if(mIs3DModeOn)
   2081         mParameters.set("3d-frame-format", "left-right");
   2082 
   2083     switch(mCurrentTarget){
   2084         case TARGET_MSM7627:
   2085         case TARGET_QSD8250:
   2086         case TARGET_MSM7630:
   2087            mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "800x480");
   2088            break;
   2089         case TARGET_MSM7627A:
   2090             mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "864x480");
   2091             break;
   2092         case TARGET_MSM8660:
   2093             mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1920x1088");
   2094             break;
   2095         default:
   2096             mParameters.set(QCameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "640x480");
   2097             break;
   2098     }
   2099     if (setParameters(mParameters) != NO_ERROR) {
   2100         ALOGE("Failed to set default parameters?!");
   2101     }
   2102 
   2103     /* Initialize the camframe_timeout_flag*/
   2104     Mutex::Autolock l(&mCamframeTimeoutLock);
   2105     camframe_timeout_flag = FALSE;
   2106     mPostviewHeap = NULL;
   2107     mDisplayHeap = NULL;
   2108     mLastPreviewFrameHeap = NULL;
   2109     mThumbnailHeap = NULL;
   2110 
   2111     mInitialized = true;
   2112     strTexturesOn = false;
   2113 
   2114     ALOGV("initDefaultParameters X");
   2115 }
   2116 
   2117 
   2118 #define ROUND_TO_PAGE(x)  (((x)+0xfff)&~0xfff)
   2119 
   2120 bool QualcommCameraHardware::startCamera()
   2121 {
   2122     ALOGV("startCamera E");
   2123     if( mCurrentTarget == TARGET_MAX ) {
   2124         ALOGE(" Unable to determine the target type. Camera will not work ");
   2125         return false;
   2126     }
   2127 #if DLOPEN_LIBMMCAMERA
   2128 
   2129     ALOGV("loading liboemcamera at %p", libmmcamera);
   2130     if (!libmmcamera) {
   2131         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   2132         return false;
   2133     }
   2134 
   2135     *(void **)&LINK_cam_frame =
   2136         ::dlsym(libmmcamera, "cam_frame");
   2137     *(void **)&LINK_wait_cam_frame_thread_ready =
   2138 	::dlsym(libmmcamera, "wait_cam_frame_thread_ready");
   2139     *(void **)&LINK_cam_frame_set_exit_flag =
   2140         ::dlsym(libmmcamera, "cam_frame_set_exit_flag");
   2141     *(void **)&LINK_camframe_terminate =
   2142         ::dlsym(libmmcamera, "camframe_terminate");
   2143 
   2144     *(void **)&LINK_jpeg_encoder_init =
   2145         ::dlsym(libmmcamera, "jpeg_encoder_init");
   2146 
   2147     *(void **)&LINK_jpeg_encoder_encode =
   2148         ::dlsym(libmmcamera, "jpeg_encoder_encode");
   2149 
   2150     *(void **)&LINK_jpeg_encoder_join =
   2151         ::dlsym(libmmcamera, "jpeg_encoder_join");
   2152 
   2153     mCamNotify.preview_frame_cb = &receive_camframe_callback;
   2154 
   2155     mCamNotify.camstats_cb = &receive_camstats_callback;
   2156 
   2157     mCamNotify.on_event =  &receive_event_callback;
   2158 
   2159     mCamNotify.on_error_event = &receive_camframe_error_callback;
   2160 
   2161     // 720 p new recording functions
   2162     mCamNotify.video_frame_cb = &receive_camframe_video_callback;
   2163      // 720 p new recording functions
   2164 
   2165     *(void **)&LINK_camframe_add_frame = ::dlsym(libmmcamera, "camframe_add_frame");
   2166 
   2167     *(void **)&LINK_camframe_release_all_frames = ::dlsym(libmmcamera, "camframe_release_all_frames");
   2168 
   2169     *(void **)&LINK_mmcamera_shutter_callback =
   2170         ::dlsym(libmmcamera, "mmcamera_shutter_callback");
   2171 
   2172     *LINK_mmcamera_shutter_callback = receive_shutter_callback;
   2173 
   2174     *(void**)&LINK_jpeg_encoder_setMainImageQuality =
   2175         ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
   2176 
   2177     *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
   2178         ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
   2179 
   2180     *(void**)&LINK_jpeg_encoder_setRotation =
   2181         ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
   2182 
   2183     *(void**)&LINK_jpeg_encoder_get_buffer_offset =
   2184         ::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset");
   2185 
   2186     *(void**)&LINK_jpeg_encoder_set_3D_info =
   2187         ::dlsym(libmmcamera, "jpeg_encoder_set_3D_info");
   2188 
   2189 /* Disabling until support is available.
   2190     *(void**)&LINK_jpeg_encoder_setLocation =
   2191         ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
   2192 */
   2193     *(void **)&LINK_cam_conf =
   2194         ::dlsym(libmmcamera, "cam_conf");
   2195 
   2196 /* Disabling until support is available.
   2197     *(void **)&LINK_default_sensor_get_snapshot_sizes =
   2198         ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
   2199 */
   2200     *(void **)&LINK_launch_cam_conf_thread =
   2201         ::dlsym(libmmcamera, "launch_cam_conf_thread");
   2202 
   2203     *(void **)&LINK_release_cam_conf_thread =
   2204         ::dlsym(libmmcamera, "release_cam_conf_thread");
   2205 
   2206     mCamNotify.on_liveshot_event = &receive_liveshot_callback;
   2207 
   2208     *(void **)&LINK_cancel_liveshot =
   2209         ::dlsym(libmmcamera, "cancel_liveshot");
   2210 
   2211     *(void **)&LINK_set_liveshot_params =
   2212         ::dlsym(libmmcamera, "set_liveshot_params");
   2213 
   2214     *(void **)&LINK_set_liveshot_frame =
   2215         ::dlsym(libmmcamera, "set_liveshot_frame");
   2216 
   2217     *(void **)&LINK_mm_camera_destroy =
   2218         ::dlsym(libmmcamera, "mm_camera_destroy");
   2219 
   2220     *(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12_inplace =
   2221         ::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12");
   2222 
   2223     *(void **)&LINK_yuv_convert_ycrcb420sp_to_yv12 =
   2224         ::dlsym(libmmcamera, "yuv_convert_ycrcb420sp_to_yv12_ver2");
   2225 
   2226     /* Disabling until support is available.*/
   2227     *(void **)&LINK_zoom_crop_upscale =
   2228         ::dlsym(libmmcamera, "zoom_crop_upscale");
   2229 
   2230 
   2231 #else
   2232     mCamNotify.preview_frame_cb = &receive_camframe_callback;
   2233     mCamNotify.camstats_cb = &receive_camstats_callback;
   2234     mCamNotify.on_event =  &receive_event_callback;
   2235 
   2236     mmcamera_shutter_callback = receive_shutter_callback;
   2237      mCamNotify.on_liveshot_event = &receive_liveshot_callback;
   2238      mCamNotify.video_frame_cb = &receive_camframe_video_callback;
   2239 
   2240 #endif // DLOPEN_LIBMMCAMERA
   2241 #if 0 //commenting this for now as not getting graphics permission
   2242     if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){
   2243         fb_fd = open("/dev/graphics/fb0", O_RDWR);
   2244         if (fb_fd < 0) {
   2245             ALOGE("startCamera: fb0 open failed: %s!", strerror(errno));
   2246             return FALSE;
   2247         }
   2248     }
   2249 #endif
   2250     int ret_val;
   2251     if (pthread_join(mDeviceOpenThread, (void**)&ret_val) != 0) {
   2252          ALOGE("openCamera thread exit failed");
   2253          return false;
   2254     }
   2255 
   2256     if (!mCameraOpen) {
   2257         ALOGE("openCamera() failed");
   2258         return false;
   2259     }
   2260 
   2261 
   2262     mCfgControl.mm_camera_query_parms(CAMERA_PARM_PICT_SIZE, (void **)&picture_sizes, &PICTURE_SIZE_COUNT);
   2263     if ((picture_sizes == NULL) || (!PICTURE_SIZE_COUNT)) {
   2264         ALOGE("startCamera X: could not get snapshot sizes");
   2265         return false;
   2266     }
   2267      ALOGI("startCamera picture_sizes %p PICTURE_SIZE_COUNT %d", picture_sizes, PICTURE_SIZE_COUNT);
   2268     mCfgControl.mm_camera_query_parms(CAMERA_PARM_PREVIEW_SIZE, (void **)&preview_sizes, &PREVIEW_SIZE_COUNT);
   2269     if ((preview_sizes == NULL) || (!PREVIEW_SIZE_COUNT)) {
   2270         ALOGE("startCamera X: could not get preview sizes");
   2271         return false;
   2272     }
   2273     ALOGI("startCamera preview_sizes %p previewSizeCount %d", preview_sizes, PREVIEW_SIZE_COUNT);
   2274 
   2275     mCfgControl.mm_camera_query_parms(CAMERA_PARM_HFR_SIZE, (void **)&hfr_sizes, &HFR_SIZE_COUNT);
   2276     if ((hfr_sizes == NULL) || (!HFR_SIZE_COUNT)) {
   2277         ALOGE("startCamera X: could not get hfr sizes");
   2278         return false;
   2279     }
   2280     ALOGI("startCamera hfr_sizes %p hfrSizeCount %d", hfr_sizes, HFR_SIZE_COUNT);
   2281 
   2282 
   2283     ALOGV("startCamera X");
   2284     return true;
   2285 }
   2286 
   2287 status_t QualcommCameraHardware::dump(int fd,
   2288                                       const Vector<String16>& args) const
   2289 {
   2290     const size_t SIZE = 256;
   2291     char buffer[SIZE];
   2292     String8 result;
   2293 #if 0
   2294     // Dump internal primitives.
   2295     result.append("QualcommCameraHardware::dump");
   2296     snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
   2297     result.append(buffer);
   2298     int width, height;
   2299     mParameters.getPreviewSize(&width, &height);
   2300     snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
   2301     result.append(buffer);
   2302     mParameters.getPictureSize(&width, &height);
   2303     snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
   2304     result.append(buffer);
   2305     snprintf(buffer, 255,
   2306              "preview frame size(%d), raw size (%d), jpeg size (%d) "
   2307              "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
   2308              mJpegSize, mJpegMaxSize);
   2309     result.append(buffer);
   2310     write(fd, result.string(), result.size());
   2311 
   2312     // Dump internal objects.
   2313     if (mPreviewHeap[0] != 0) {
   2314         mPreviewHeap[0]->dump(fd, args);
   2315     }
   2316     if (mRawHeap != 0) {
   2317         mRawHeap->dump(fd, args);
   2318     }
   2319     if (mJpegHeap != 0) {
   2320         mJpegHeap->dump(fd, args);
   2321     }
   2322     mParameters.dump(fd, args);
   2323 #endif
   2324     return NO_ERROR;
   2325 }
   2326 
   2327 /* Issue ioctl calls related to starting Camera Operations*/
   2328 bool static native_start_ops(mm_camera_ops_type_t  type, void* value)
   2329 {
   2330     if(mCamOps.mm_camera_start(type, value,NULL) != MM_CAMERA_SUCCESS) {
   2331         ALOGE("native_start_ops: type %d error %s",
   2332             type,strerror(errno));
   2333         return false;
   2334     }
   2335     return true;
   2336 }
   2337 
   2338 /* Issue ioctl calls related to stopping Camera Operations*/
   2339 bool static native_stop_ops(mm_camera_ops_type_t  type, void* value)
   2340 {
   2341      if(mCamOps.mm_camera_stop(type, value,NULL) != MM_CAMERA_SUCCESS) {
   2342         ALOGE("native_stop_ops: type %d error %s",
   2343             type,strerror(errno));
   2344         return false;
   2345     }
   2346     return true;
   2347 }
   2348 /*==========================================================================*/
   2349 
   2350 
   2351 #define GPS_PROCESSING_METHOD_SIZE  101
   2352 #define FOCAL_LENGTH_DECIMAL_PRECISON 100
   2353 
   2354 static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
   2355 #define EXIF_ASCII_PREFIX_SIZE (sizeof(ExifAsciiPrefix))
   2356 
   2357 static rat_t latitude[3];
   2358 static rat_t longitude[3];
   2359 static char lonref[2];
   2360 static char latref[2];
   2361 static rat_t altitude;
   2362 static rat_t gpsTimestamp[3];
   2363 static char gpsDatestamp[20];
   2364 static char dateTime[20];
   2365 static rat_t focalLength;
   2366 static uint16_t flashMode;
   2367 static int iso_arr[] = {0,1,100,200,400,800,1600};
   2368 static uint16_t isoMode;
   2369 static char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
   2370 static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
   2371                         uint32_t count, uint8_t copy, void *data) {
   2372 
   2373     if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
   2374         ALOGE("Number of entries exceeded limit");
   2375         return;
   2376     }
   2377 
   2378     int index = exif_table_numEntries;
   2379     exif_data[index].tag_id = tagid;
   2380     exif_data[index].tag_entry.type = type;
   2381     exif_data[index].tag_entry.count = count;
   2382     exif_data[index].tag_entry.copy = copy;
   2383     if((type == EXIF_RATIONAL) && (count > 1))
   2384         exif_data[index].tag_entry.data._rats = (rat_t *)data;
   2385     if((type == EXIF_RATIONAL) && (count == 1))
   2386         exif_data[index].tag_entry.data._rat = *(rat_t *)data;
   2387     else if(type == EXIF_ASCII)
   2388         exif_data[index].tag_entry.data._ascii = (char *)data;
   2389     else if(type == EXIF_BYTE)
   2390         exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
   2391     else if((type == EXIF_SHORT) && (count > 1))
   2392         exif_data[index].tag_entry.data._shorts = (uint16_t *)data;
   2393     else if((type == EXIF_SHORT) && (count == 1))
   2394         exif_data[index].tag_entry.data._short = *(uint16_t *)data;
   2395     // Increase number of entries
   2396     exif_table_numEntries++;
   2397 }
   2398 
   2399 static void parseLatLong(const char *latlonString, int *pDegrees,
   2400                            int *pMinutes, int *pSeconds ) {
   2401 
   2402     double value = atof(latlonString);
   2403     value = fabs(value);
   2404     int degrees = (int) value;
   2405 
   2406     double remainder = value - degrees;
   2407     int minutes = (int) (remainder * 60);
   2408     int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
   2409 
   2410     *pDegrees = degrees;
   2411     *pMinutes = minutes;
   2412     *pSeconds = seconds;
   2413 }
   2414 
   2415 static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
   2416 
   2417     int degrees, minutes, seconds;
   2418 
   2419     parseLatLong(latlonString, &degrees, &minutes, &seconds);
   2420 
   2421     rat_t value[3] = { {degrees, 1},
   2422                        {minutes, 1},
   2423                        {seconds, 1000} };
   2424 
   2425     if(tag == EXIFTAGID_GPS_LATITUDE) {
   2426         memcpy(latitude, value, sizeof(latitude));
   2427         addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
   2428                     1, (void *)latitude);
   2429     } else {
   2430         memcpy(longitude, value, sizeof(longitude));
   2431         addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
   2432                     1, (void *)longitude);
   2433     }
   2434 }
   2435 
   2436 void QualcommCameraHardware::setGpsParameters() {
   2437     const char *str = NULL;
   2438 
   2439     str = mParameters.get(QCameraParameters::KEY_GPS_PROCESSING_METHOD);
   2440 
   2441     if(str!=NULL ){
   2442        memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
   2443        strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str,
   2444            GPS_PROCESSING_METHOD_SIZE - 1);
   2445        gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0';
   2446        addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII,
   2447            EXIF_ASCII_PREFIX_SIZE + strlen(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1,
   2448            1, (void *)gpsProcessingMethod);
   2449     }
   2450 
   2451     str = NULL;
   2452 
   2453     //Set Latitude
   2454     str = mParameters.get(QCameraParameters::KEY_GPS_LATITUDE);
   2455     if(str != NULL) {
   2456         setLatLon(EXIFTAGID_GPS_LATITUDE, str);
   2457         //set Latitude Ref
   2458         float latitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LATITUDE);
   2459         latref[0] = 'N';
   2460         if(latitudeValue < 0 ){
   2461             latref[0] = 'S';
   2462         }
   2463         latref[1] = '\0';
   2464         mParameters.set(QCameraParameters::KEY_GPS_LATITUDE_REF, latref);
   2465         addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
   2466                                 1, (void *)latref);
   2467     }
   2468 
   2469     //set Longitude
   2470     str = NULL;
   2471     str = mParameters.get(QCameraParameters::KEY_GPS_LONGITUDE);
   2472     if(str != NULL) {
   2473         setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
   2474         //set Longitude Ref
   2475         float longitudeValue = mParameters.getFloat(QCameraParameters::KEY_GPS_LONGITUDE);
   2476         lonref[0] = 'E';
   2477         if(longitudeValue < 0){
   2478             lonref[0] = 'W';
   2479         }
   2480         lonref[1] = '\0';
   2481         mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE_REF, lonref);
   2482         addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
   2483                                 1, (void *)lonref);
   2484     }
   2485 
   2486     //set Altitude
   2487     str = NULL;
   2488     str = mParameters.get(QCameraParameters::KEY_GPS_ALTITUDE);
   2489     if(str != NULL) {
   2490         double value = atof(str);
   2491         int ref = 0;
   2492         if(value < 0){
   2493             ref = 1;
   2494             value = -value;
   2495         }
   2496         uint32_t value_meter = value * 1000;
   2497         rat_t alt_value = {value_meter, 1000};
   2498         memcpy(&altitude, &alt_value, sizeof(altitude));
   2499         addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
   2500                     1, (void *)&altitude);
   2501         //set AltitudeRef
   2502         mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE_REF, ref);
   2503         addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
   2504                     1, (void *)&ref);
   2505     }
   2506 
   2507     //set Gps TimeStamp
   2508     str = NULL;
   2509     str = mParameters.get(QCameraParameters::KEY_GPS_TIMESTAMP);
   2510     if(str != NULL) {
   2511 
   2512       long value = atol(str);
   2513       time_t unixTime;
   2514       struct tm *UTCTimestamp;
   2515 
   2516       unixTime = (time_t)value;
   2517       UTCTimestamp = gmtime(&unixTime);
   2518 
   2519       strftime(gpsDatestamp, sizeof(gpsDatestamp), "%Y:%m:%d", UTCTimestamp);
   2520       addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII,
   2521                           strlen(gpsDatestamp)+1 , 1, (void *)&gpsDatestamp);
   2522 
   2523       rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1},
   2524                               {UTCTimestamp->tm_min, 1},
   2525                               {UTCTimestamp->tm_sec, 1} };
   2526 
   2527 
   2528       memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp));
   2529       addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
   2530                   3, 1, (void *)&gpsTimestamp);
   2531     }
   2532 
   2533 }
   2534 
   2535 
   2536 bool QualcommCameraHardware::initZslParameter(void)
   2537     {  ALOGV("%s: E", __FUNCTION__);
   2538        mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
   2539        ALOGI("initZslParamter E: picture size=%dx%d", mPictureWidth, mPictureHeight);
   2540        if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) {
   2541          mDimension.picture_width = mPictureWidth;
   2542          mDimension.picture_height = mPictureHeight;
   2543        }
   2544 
   2545        /* use the default thumbnail sizes */
   2546         mZslParms.picture_width = mPictureWidth;
   2547         mZslParms.picture_height = mPictureHeight;
   2548         mZslParms.preview_width =  mDimension.display_width;
   2549         mZslParms.preview_height = mDimension.display_height;
   2550         mZslParms.useExternalBuffers = TRUE;
   2551           /* fill main image size, thumbnail size, postview size into capture_params_t*/
   2552         memset(&mZslCaptureParms, 0, sizeof(zsl_capture_params_t));
   2553         mZslCaptureParms.thumbnail_height = mPostviewHeight;
   2554         mZslCaptureParms.thumbnail_width = mPostviewWidth;
   2555         ALOGI("Number of snapshot to capture: %d",numCapture);
   2556         mZslCaptureParms.num_captures = numCapture;
   2557 
   2558         return true;
   2559     }
   2560 
   2561 
   2562 bool QualcommCameraHardware::initImageEncodeParameters(int size)
   2563 {
   2564     ALOGV("%s: E", __FUNCTION__);
   2565     memset(&mImageEncodeParms, 0, sizeof(encode_params_t));
   2566     int jpeg_quality = mParameters.getInt("jpeg-quality");
   2567     bool ret;
   2568     if (jpeg_quality >= 0) {
   2569         ALOGI("initJpegParameters, current jpeg main img quality =%d",
   2570              jpeg_quality);
   2571         //Application can pass quality of zero
   2572         //when there is no back sensor connected.
   2573         //as jpeg quality of zero is not accepted at
   2574         //camera stack, pass default value.
   2575         if(jpeg_quality == 0) jpeg_quality = 85;
   2576         mImageEncodeParms.quality = jpeg_quality;
   2577         ret = native_set_parms(CAMERA_PARM_JPEG_MAINIMG_QUALITY, sizeof(int), &jpeg_quality);
   2578         if(!ret){
   2579           ALOGE("initJpegParametersX: failed to set main image quality");
   2580           return false;
   2581         }
   2582     }
   2583 
   2584     int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
   2585     if (thumbnail_quality >= 0) {
   2586         //Application can pass quality of zero
   2587         //when there is no back sensor connected.
   2588         //as quality of zero is not accepted at
   2589         //camera stack, pass default value.
   2590         if(thumbnail_quality == 0) thumbnail_quality = 85;
   2591         ALOGI("initJpegParameters, current jpeg thumbnail quality =%d",
   2592              thumbnail_quality);
   2593         /* TODO: check with mm-camera? */
   2594         mImageEncodeParms.quality = thumbnail_quality;
   2595         ret = native_set_parms(CAMERA_PARM_JPEG_THUMB_QUALITY, sizeof(int), &thumbnail_quality);
   2596         if(!ret){
   2597           ALOGE("initJpegParameters X: failed to set thumbnail quality");
   2598           return false;
   2599         }
   2600     }
   2601 
   2602     int rotation = mParameters.getInt("rotation");
   2603     char mDeviceName[PROPERTY_VALUE_MAX];
   2604     property_get("ro.hw_plat", mDeviceName, "");
   2605     if(!strcmp(mDeviceName,"7x25A"))
   2606         rotation = (rotation + 90)%360;
   2607 
   2608     if (mIs3DModeOn)
   2609         rotation = 0;
   2610     if (rotation >= 0) {
   2611         ALOGI("initJpegParameters, rotation = %d", rotation);
   2612         mImageEncodeParms.rotation = rotation;
   2613     }
   2614 
   2615     jpeg_set_location();
   2616 
   2617     //set TimeStamp
   2618     const char *str = mParameters.get(QCameraParameters::KEY_EXIF_DATETIME);
   2619     if(str != NULL) {
   2620       strncpy(dateTime, str, 19);
   2621       dateTime[19] = '\0';
   2622       addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   2623                   20, 1, (void *)dateTime);
   2624     }
   2625 
   2626     int focalLengthValue = (int) (mParameters.getFloat(
   2627                 QCameraParameters::KEY_FOCAL_LENGTH) * FOCAL_LENGTH_DECIMAL_PRECISON);
   2628     rat_t focalLengthRational = {focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISON};
   2629     memcpy(&focalLength, &focalLengthRational, sizeof(focalLengthRational));
   2630     addExifTag(EXIFTAGID_FOCAL_LENGTH, EXIF_RATIONAL, 1,
   2631                 1, (void *)&focalLength);
   2632     //Adding ExifTag for ISOSpeedRating
   2633     const char *iso_str = mParameters.get(QCameraParameters::KEY_ISO_MODE);
   2634     int iso_value = attr_lookup(iso, sizeof(iso) / sizeof(str_map), iso_str);
   2635     isoMode = iso_arr[iso_value];
   2636     addExifTag(EXIFTAGID_ISO_SPEED_RATING,EXIF_SHORT,1,1,(void *)&isoMode);
   2637 
   2638     if (mUseJpegDownScaling) {
   2639       ALOGI("initImageEncodeParameters: update main image", __func__);
   2640       mImageEncodeParms.output_picture_width = mActualPictWidth;
   2641       mImageEncodeParms.output_picture_height = mActualPictHeight;
   2642     }
   2643     mImageEncodeParms.cbcr_offset = mCbCrOffsetRaw;
   2644     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)
   2645         mImageEncodeParms.cbcr_offset = mCbCrOffsetRaw;
   2646     /* TODO: check this */
   2647     mImageEncodeParms.y_offset = 0;
   2648     for(int i = 0; i < size; i++){
   2649         memset(&mEncodeOutputBuffer[i], 0, sizeof(mm_camera_buffer_t));
   2650         mEncodeOutputBuffer[i].ptr = (uint8_t *)mJpegMapped[i]->data;
   2651         mEncodeOutputBuffer[i].filled_size = mJpegMaxSize;
   2652         mEncodeOutputBuffer[i].size = mJpegMaxSize;
   2653         mEncodeOutputBuffer[i].fd = mJpegfd[i];
   2654         mEncodeOutputBuffer[i].offset = 0;
   2655     }
   2656     mImageEncodeParms.p_output_buffer = mEncodeOutputBuffer;
   2657     mImageEncodeParms.exif_data = exif_data;
   2658     mImageEncodeParms.exif_numEntries = exif_table_numEntries;
   2659 
   2660     mImageEncodeParms.format3d = mIs3DModeOn;
   2661     return true;
   2662 }
   2663 
   2664 bool QualcommCameraHardware::native_set_parms(
   2665     camera_parm_type_t type, uint16_t length, void *value)
   2666 {
   2667     if(mCfgControl.mm_camera_set_parm(type,value) != MM_CAMERA_SUCCESS) {
   2668         ALOGE("native_set_parms failed: type %d length %d error %s",
   2669             type, length, strerror(errno));
   2670         return false;
   2671     }
   2672     return true;
   2673 
   2674 }
   2675 bool QualcommCameraHardware::native_set_parms(
   2676     camera_parm_type_t type, uint16_t length, void *value, int *result)
   2677 {
   2678     mm_camera_status_t status;
   2679     status = mCfgControl.mm_camera_set_parm(type,value);
   2680     ALOGI("native_set_parms status = %d", status);
   2681     if( status == MM_CAMERA_SUCCESS || status == MM_CAMERA_ERR_INVALID_OPERATION){
   2682         *result = status ;
   2683         return true;
   2684     }
   2685     ALOGE("%s: type %d length %d error %s, status %d", __FUNCTION__,
   2686                                        type, length, strerror(errno), status);
   2687    *result = status;
   2688     return false;
   2689 }
   2690 
   2691 void QualcommCameraHardware::jpeg_set_location()
   2692 {
   2693     bool encode_location = true;
   2694     camera_position_type pt;
   2695 
   2696 #define PARSE_LOCATION(what,type,fmt,desc) do {                                \
   2697         pt.what = 0;                                                           \
   2698         const char *what##_str = mParameters.get("gps-"#what);                 \
   2699         ALOGI("GPS PARM %s --> [%s]", "gps-"#what, what##_str);                 \
   2700         if (what##_str) {                                                      \
   2701             type what = 0;                                                     \
   2702             if (sscanf(what##_str, fmt, &what) == 1)                           \
   2703                 pt.what = what;                                                \
   2704             else {                                                             \
   2705                 ALOGE("GPS " #what " %s could not"                              \
   2706                      " be parsed as a " #desc, what##_str);                    \
   2707                 encode_location = false;                                       \
   2708             }                                                                  \
   2709         }                                                                      \
   2710         else {                                                                 \
   2711             ALOGI("GPS " #what " not specified: "                               \
   2712                  "defaulting to zero in EXIF header.");                        \
   2713             encode_location = false;                                           \
   2714        }                                                                       \
   2715     } while(0)
   2716 
   2717     PARSE_LOCATION(timestamp, long, "%ld", "long");
   2718     if (!pt.timestamp) pt.timestamp = time(NULL);
   2719     PARSE_LOCATION(altitude, short, "%hd", "short");
   2720     PARSE_LOCATION(latitude, double, "%lf", "double float");
   2721     PARSE_LOCATION(longitude, double, "%lf", "double float");
   2722 
   2723 #undef PARSE_LOCATION
   2724 
   2725     if (encode_location) {
   2726         ALOGI("setting image location ALT %d LAT %lf LON %lf",
   2727              pt.altitude, pt.latitude, pt.longitude);
   2728 
   2729         setGpsParameters();
   2730         /* Disabling until support is available.
   2731         if (!LINK_jpeg_encoder_setLocation(&pt)) {
   2732             ALOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
   2733         }
   2734         */
   2735     }
   2736     else ALOGI("not setting image location");
   2737 }
   2738 
   2739 static bool register_buf(int size,
   2740                          int frame_size,
   2741                          int cbcr_offset,
   2742                          int yoffset,
   2743                          int pmempreviewfd,
   2744                          uint32_t offset,
   2745                          uint8_t *buf,
   2746                          int pmem_type,
   2747                          bool vfe_can_write,
   2748                          bool register_buffer,
   2749                          bool use_all_chnls)
   2750 {
   2751     struct msm_pmem_info pmemBuf;
   2752     CAMERA_HAL_UNUSED(frame_size);
   2753 
   2754     memset(&pmemBuf, 0, sizeof(struct msm_pmem_info));
   2755     pmemBuf.type     = pmem_type;
   2756     pmemBuf.fd       = pmempreviewfd;
   2757     pmemBuf.offset   = offset;
   2758     pmemBuf.len      = size;
   2759     pmemBuf.vaddr    = buf;
   2760     pmemBuf.planar0_off = yoffset;
   2761      if(!use_all_chnls) {
   2762        ALOGI("use_all_chnls = %d\n", use_all_chnls);
   2763        pmemBuf.planar1_off = cbcr_offset;
   2764        pmemBuf.planar2_off = yoffset;
   2765                } else {
   2766        pmemBuf.planar1_off = myv12_params.CbOffset;
   2767        pmemBuf.planar2_off = myv12_params.CrOffset;
   2768                }
   2769        ALOGI("register_buf: CbOff = 0x%x CrOff = 0x%x",
   2770        pmemBuf.planar1_off, pmemBuf.planar2_off);
   2771 
   2772     pmemBuf.active   = vfe_can_write;
   2773 
   2774     ALOGI("register_buf:  reg = %d buffer = %p",
   2775          !register_buffer, buf);
   2776     if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER :
   2777         CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) {
   2778          ALOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM  error %s",
   2779                strerror(errno));
   2780          return false;
   2781          }
   2782 
   2783     return true;
   2784 
   2785 }
   2786 
   2787 static bool register_buf(int size,
   2788                          int frame_size,
   2789                          int cbcr_offset,
   2790                          int yoffset,
   2791                          int pmempreviewfd,
   2792                          uint32_t offset,
   2793                          uint8_t *buf,
   2794                          int pmem_type,
   2795                          bool vfe_can_write,
   2796                          bool register_buffer = true,
   2797                          bool use_all_chnls = false);
   2798 
   2799 void QualcommCameraHardware::runFrameThread(void *data)
   2800 {
   2801     ALOGV("runFrameThread E");
   2802     int type;
   2803     int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   2804 
   2805     if(libmmcamera)
   2806     {
   2807         LINK_cam_frame(data);
   2808     }
   2809     //waiting for preview thread to complete before clearing of the buffers
   2810     mPreviewThreadWaitLock.lock();
   2811     while (mPreviewThreadRunning) {
   2812         ALOGI("runframethread: waiting for preview  thread to complete.");
   2813         mPreviewThreadWait.wait(mPreviewThreadWaitLock);
   2814         ALOGI("initPreview: old preview thread completed.");
   2815     }
   2816     mPreviewThreadWaitLock.unlock();
   2817 
   2818     // Cancelling previewBuffers and returning them to display before stopping preview
   2819     // This will ensure that all preview buffers are available for dequeing when
   2820     //startPreview is called again with the same ANativeWindow object (snapshot case). If the
   2821     //ANativeWindow is a new one(camera-camcorder switch case) because the app passed a new
   2822     //surface then buffers will be re-allocated and not returned from the old pool.
   2823     relinquishBuffers();
   2824     mPreviewBusyQueue.flush();
   2825     /* Flush the Free Q */
   2826     LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   2827 
   2828     if(mIs3DModeOn != true) {
   2829 #if 0
   2830         if(mInHFRThread == false)
   2831         {
   2832              mPmemWaitLock.lock();
   2833              //mPreviewHeap.clear();
   2834 // TODO do properly
   2835              mPrevHeapDeallocRunning = true;
   2836              mPmemWait.signal();
   2837              mPmemWaitLock.unlock();
   2838 
   2839             if(( mPreviewFormat == CAMERA_YUV_420_YV12 )&&
   2840                 ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627) &&
   2841                 previewWidth%32 != 0 )
   2842                 mYV12Heap.clear();
   2843 
   2844         }
   2845         else
   2846 #endif
   2847         {
   2848            int mBufferSize = previewWidth * previewHeight * 3/2;
   2849            int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   2850            ALOGI("unregistering all preview buffers");
   2851             //unregister preview buffers. we are not deallocating here.
   2852             for (int cnt = 0; cnt < mTotalPreviewBufferCount; ++cnt) {
   2853                 register_buf(mBufferSize,
   2854                          mBufferSize,
   2855                          mCbCrOffset,
   2856                          0,
   2857                          frames[cnt].fd,
   2858                          0,
   2859                          (uint8_t *)frames[cnt].buffer,
   2860                          MSM_PMEM_PREVIEW,
   2861                          false,
   2862                          false,
   2863                          true);
   2864             //mPreviewHeap[cnt].clear();
   2865              // TODO : clean properly
   2866             }
   2867         }
   2868     }
   2869     if(!mZslEnable) {
   2870     if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)){
   2871         if(mHFRMode != true) {
   2872 #if 0
   2873             mRecordHeap.clear();
   2874             mRecordHeap = NULL;
   2875 #endif
   2876         } else {
   2877             ALOGI("%s: unregister record buffers with camera driver", __FUNCTION__);
   2878             register_record_buffers(false);
   2879         }
   2880         int CbCrOffset = PAD_TO_2K(mDimension.video_width  * mDimension.video_height);
   2881 	    for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   2882 #if 0
   2883 	if (mRecordfd[cnt] > 0) {
   2884 	    ALOGE("Unregistering buffer %d with kernel",cnt);
   2885 	    register_buf(mRecordFrameSize,
   2886 		mRecordFrameSize, CbCrOffset, 0,
   2887 		mRecordfd[cnt],
   2888 		0,
   2889 		(uint8_t *)recordframes[cnt].buffer,
   2890 		MSM_PMEM_VIDEO,
   2891 		false, false);
   2892 	    ALOGE("Came back from register call to kernel");
   2893 	  }
   2894 #endif
   2895              type = MSM_PMEM_VIDEO;
   2896              ALOGI("%s: unregister record buffers[%d] with camera driver", __FUNCTION__, cnt);
   2897              if(recordframes) {
   2898                register_buf(mRecordFrameSize,
   2899                   mRecordFrameSize, CbCrOffset, 0,
   2900                   recordframes[cnt].fd,
   2901                   0,
   2902                   (uint8_t *)recordframes[cnt].buffer,
   2903                   type,
   2904                   false,false);
   2905                if(mRecordMapped[cnt]) {
   2906                    mRecordMapped[cnt]->release(mRecordMapped[cnt]);
   2907                    mRecordMapped[cnt] = NULL;
   2908                    close(mRecordfd[cnt]);
   2909                    if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   2910                        struct encoder_media_buffer_type * packet =
   2911                                (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   2912                        native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   2913                        metadata_memory[cnt]->release(metadata_memory[cnt]);
   2914                        metadata_memory[cnt] = NULL;
   2915                    }
   2916 #ifdef USE_ION
   2917                    deallocate_ion_memory(&record_main_ion_fd[cnt], &record_ion_info_fd[cnt]);
   2918 #endif
   2919                }
   2920             }
   2921 	    }
   2922     }
   2923 	}
   2924 
   2925     mFrameThreadWaitLock.lock();
   2926     mFrameThreadRunning = false;
   2927     mFrameThreadWait.signal();
   2928     mFrameThreadWaitLock.unlock();
   2929 
   2930     ALOGV("runFrameThread X");
   2931 }
   2932 
   2933 
   2934 void QualcommCameraHardware::runPreviewThread(void *data)
   2935 {
   2936     static int hfr_count = 0;
   2937     msm_frame* frame = NULL;
   2938     status_t retVal = NO_ERROR;
   2939     CAMERA_HAL_UNUSED(data);
   2940     android_native_buffer_t *buffer;
   2941 	buffer_handle_t *handle = NULL;
   2942     int bufferIndex = 0;
   2943 
   2944     while((frame = mPreviewBusyQueue.get()) != NULL) {
   2945         if (UNLIKELY(mDebugFps)) {
   2946             debugShowPreviewFPS();
   2947         }
   2948         mCallbackLock.lock();
   2949         int msgEnabled = mMsgEnabled;
   2950         camera_data_callback pcb = mDataCallback;
   2951         void *pdata = mCallbackCookie;
   2952         camera_data_timestamp_callback rcb = mDataCallbackTimestamp;
   2953         void *rdata = mCallbackCookie;
   2954         camera_data_callback mcb = mDataCallback;
   2955         void *mdata = mCallbackCookie;
   2956         mCallbackLock.unlock();
   2957 
   2958         // signal smooth zoom thread , that a new preview frame is available
   2959         mSmoothzoomThreadWaitLock.lock();
   2960         if(mSmoothzoomThreadRunning) {
   2961             mSmoothzoomThreadWait.signal();
   2962         }
   2963         mSmoothzoomThreadWaitLock.unlock();
   2964 
   2965         // Find the offset within the heap of the current buffer.
   2966         ssize_t offset_addr = 0; // TODO , use proper value
   2967       //      (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
   2968      //   ssize_t offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
   2969         common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
   2970 #ifdef DUMP_PREVIEW_FRAMES
   2971         static int frameCnt = 0;
   2972         int written;
   2973                 if (frameCnt >= 0 && frameCnt <= 10 ) {
   2974                     char buf[128];
   2975                     snprintf(buffer, sizeof(buf), "/data/%d_preview.yuv", frameCnt);
   2976                     int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
   2977                     ALOGI("dumping preview frame %d", frameCnt);
   2978                     if (file_fd < 0) {
   2979                         ALOGE("cannot open file\n");
   2980                     }
   2981                     else
   2982                     {
   2983                         ALOGI("dumping data");
   2984                         written = write(file_fd, (uint8_t *)frame->buffer,
   2985                             mPreviewFrameSize );
   2986                         if(written < 0)
   2987                           ALOGE("error in data write");
   2988                     }
   2989                     close(file_fd);
   2990               }
   2991               frameCnt++;
   2992 #endif
   2993         mInPreviewCallback = true;
   2994          if (crop->in1_w != 0 && crop->in1_h != 0) {
   2995              zoomCropInfo.left = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
   2996              zoomCropInfo.top = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
   2997              /* There can be scenarios where the in1_wXin1_h and
   2998               * out1_wXout1_h are same. In those cases, reset the
   2999               * x and y to zero instead of negative for proper zooming
   3000               */
   3001              if(zoomCropInfo.left < 0) zoomCropInfo.left = 0;
   3002              if(zoomCropInfo.top < 0) zoomCropInfo.top = 0;
   3003              zoomCropInfo.right = zoomCropInfo.left + crop->in1_w;
   3004              zoomCropInfo.bottom = zoomCropInfo.top + crop->in1_h;
   3005              mPreviewWindow-> set_crop (mPreviewWindow,
   3006                                        zoomCropInfo.left,
   3007                                        zoomCropInfo.top,
   3008                                        zoomCropInfo.right,
   3009                                        zoomCropInfo.bottom);
   3010              /* Set mResetOverlayCrop to true, so that when there is
   3011               * no crop information, setCrop will be called
   3012               * with zero crop values.
   3013               */
   3014              mResetWindowCrop = true;
   3015 
   3016          } else {
   3017              // Reset zoomCropInfo variables. This will ensure that
   3018              // stale values wont be used for postview
   3019              zoomCropInfo.left = 0;
   3020              zoomCropInfo.top = 0;
   3021              zoomCropInfo.right = crop->in1_w;
   3022              zoomCropInfo.bottom = crop->in1_h;
   3023              /* This reset is required, if not, overlay driver continues
   3024               * to use the old crop information for these preview
   3025               * frames which is not the correct behavior. To avoid
   3026               * multiple calls, reset once.
   3027               */
   3028              if(mResetWindowCrop == true){
   3029                 mPreviewWindow-> set_crop (mPreviewWindow,
   3030                                       zoomCropInfo.left,
   3031                                       zoomCropInfo.top,
   3032                                       zoomCropInfo.right,
   3033                                       zoomCropInfo.bottom);
   3034                  mResetWindowCrop = false;
   3035              }
   3036          }
   3037          /* To overcome a timing case where we could be having the overlay refer to deallocated
   3038             mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the
   3039             first preview frame is queued to the overlay in 8660. Also adding the condition
   3040             to check if snapshot is currently in progress ensures that the resources being
   3041             used by the snapshot thread are not incorrectly deallocated by preview thread*/
   3042          if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) {
   3043              ALOGD(" receivePreviewFrame : first frame queued, display heap being deallocated");
   3044               mThumbnailHeap.clear();
   3045               mDisplayHeap.clear();
   3046               if(!mZslEnable){
   3047                  mDisplayHeap.clear();
   3048                  mPostviewHeap.clear();
   3049              }
   3050              mFirstFrame = false;
   3051          }
   3052          mLastQueuedFrame = (void *)frame->buffer;
   3053          bufferIndex = mapBuffer(frame);
   3054 
   3055          // if 7x27A && yv12 is set as preview format use convert routines to
   3056          // convert from YUV420sp to YV12
   3057          yuv_image_type in_buf, out_buf;
   3058          int conversion_result = 0;
   3059 
   3060          if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) &&
   3061            ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 )){
   3062             // if the width is not multiple of 32,
   3063             //we cannot do inplace conversion as sizes of 420sp and YV12 frames differ
   3064             if(previewWidth%32){
   3065 #if 0 //TODO :
   3066                ALOGE("YV12::Doing not inplace conversion from 420sp to yv12");
   3067                in_buf.imgPtr = (unsigned char*)mPreviewMapped[bufferIndex]->data;
   3068                in_buf.dx = out_buf.dx = previewWidth;
   3069                in_buf.dy = in_buf.dy = previewHeight;
   3070                conversion_result = LINK_yuv_convert_ycrcb420sp_to_yv12(&in_buf, &out_buf);
   3071 #endif
   3072             } else {
   3073                ALOGI("Doing inplace conversion from 420sp to yv12");
   3074                in_buf.imgPtr = (unsigned char *)mPreviewMapped[bufferIndex]->data;
   3075                in_buf.dx  = previewWidth;
   3076                in_buf.dy  = previewHeight;
   3077                conversion_result = LINK_yuv_convert_ycrcb420sp_to_yv12_inplace(&in_buf);
   3078             }
   3079          }
   3080 
   3081          if(bufferIndex >= 0) {
   3082            //Need to encapsulate this in IMemory object and send
   3083 
   3084          if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
   3085              int previewBufSize;
   3086              /* for CTS : Forcing preview memory buffer lenth to be
   3087                           'previewWidth * previewHeight * 3/2'. Needed when gralloc allocated extra memory.*/
   3088              if( mPreviewFormat == CAMERA_YUV_420_NV21 || mPreviewFormat == CAMERA_YUV_420_YV12) {
   3089                previewBufSize = previewWidth * previewHeight * 3/2;
   3090                camera_memory_t *previewMem = mGetMemory(frames[bufferIndex].fd, previewBufSize,
   3091                                                         1, mCallbackCookie);
   3092                if (!previewMem || !previewMem->data) {
   3093                  ALOGE("%s: mGetMemory failed.\n", __func__);
   3094                } else {
   3095                    pcb(CAMERA_MSG_PREVIEW_FRAME,previewMem,0,NULL,pdata);
   3096                    previewMem->release(previewMem);
   3097                }
   3098              } else
   3099                  pcb(CAMERA_MSG_PREVIEW_FRAME,(camera_memory_t *) mPreviewMapped[bufferIndex],0,NULL,pdata);
   3100          }
   3101 
   3102            // TODO : may have to reutn proper frame as pcb
   3103            mDisplayLock.lock();
   3104            if( mPreviewWindow != NULL) {
   3105                 if (BUFFER_LOCKED == frame_buffer[bufferIndex].lockState) {
   3106                     if (GENLOCK_FAILURE == genlock_unlock_buffer(
   3107                            (native_handle_t*)(*(frame_buffer[bufferIndex].buffer)))) {
   3108                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   3109                        mDisplayLock.unlock();
   3110                     } else {
   3111                        frame_buffer[bufferIndex].lockState = BUFFER_UNLOCKED;
   3112                     }
   3113                 } else {
   3114                     ALOGI("%s: buffer to be enqueued is unlocked", __FUNCTION__);
   3115                     mDisplayLock.unlock();
   3116                 }
   3117              const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
   3118              if(str != NULL){
   3119                  int is_hfr_off = 0;
   3120                  hfr_count++;
   3121                  if(!strcmp(str, QCameraParameters::VIDEO_HFR_OFF)) {
   3122                     is_hfr_off = 1;
   3123                     retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   3124                                                frame_buffer[bufferIndex].buffer);
   3125                  } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_2X)) {
   3126                     hfr_count %= 2;
   3127                  } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_3X)) {
   3128                     hfr_count %= 3;
   3129                  } else if (!strcmp(str, QCameraParameters::VIDEO_HFR_4X)) {
   3130                     hfr_count %= 4;
   3131                  }
   3132                  if(hfr_count == 0)
   3133                      retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   3134                                                 frame_buffer[bufferIndex].buffer);
   3135                  else if(!is_hfr_off)
   3136                      retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   3137                                                 frame_buffer[bufferIndex].buffer);
   3138              } else
   3139                    retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   3140                                               frame_buffer[bufferIndex].buffer);
   3141              if( retVal != NO_ERROR)
   3142                ALOGE("%s: Failed while queueing buffer %d for display."
   3143                          " Error = %d", __FUNCTION__,
   3144                          frames[bufferIndex].fd, retVal);
   3145              int stride;
   3146              retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   3147                                                 &(handle),&(stride));
   3148              private_handle_t *bhandle = (private_handle_t *)(*handle);
   3149              if( retVal != NO_ERROR) {
   3150                ALOGE("%s: Failed while dequeueing buffer from display."
   3151                         " Error = %d", __FUNCTION__, retVal);
   3152              } else {
   3153                retVal = mPreviewWindow->lock_buffer(mPreviewWindow,handle);
   3154                //yyan todo use handle to find out buffer
   3155                  if(retVal != NO_ERROR)
   3156                    ALOGE("%s: Failed while dequeueing buffer from"
   3157                       "display. Error = %d", __FUNCTION__, retVal);
   3158              }
   3159            }
   3160            mDisplayLock.unlock();
   3161          } else
   3162            ALOGE("Could not find the buffer");
   3163 
   3164         // If output  is NOT enabled (targets otherthan 7x30 , 8x50 and 8x60 currently..)
   3165 
   3166         nsecs_t timeStamp = nsecs_t(frame->ts.tv_sec)*1000000000LL + frame->ts.tv_nsec;
   3167 
   3168         if( (mCurrentTarget != TARGET_MSM7630 ) &&  (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
   3169             int flagwait = 1;
   3170             if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) && (record_flag)) {
   3171                 if(mStoreMetaDataInFrame){
   3172                     flagwait = 1;
   3173                     if(metadata_memory[bufferIndex]!= NULL)
   3174                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, metadata_memory[bufferIndex],0,rdata);
   3175                     else flagwait = 0;
   3176                 } else {
   3177                     rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mPreviewMapped[bufferIndex],0, rdata);
   3178                 }
   3179                 if(flagwait){
   3180                     Mutex::Autolock rLock(&mRecordFrameLock);
   3181                         if (mReleasedRecordingFrame != true) {
   3182                             mRecordWait.wait(mRecordFrameLock);
   3183                         }
   3184                         mReleasedRecordingFrame = false;
   3185                 }
   3186             }
   3187         }
   3188 
   3189         if ( mCurrentTarget == TARGET_MSM8660 ) {
   3190             mMetaDataWaitLock.lock();
   3191             if (mFaceDetectOn == true && mSendMetaData == true) {
   3192                 mSendMetaData = false;
   3193                 fd_roi_t *roi = (fd_roi_t *)(frame->roi_info.info);
   3194 
   3195                 switch (roi->type) {
   3196                 case FD_ROI_TYPE_HEADER:
   3197                     {
   3198                         mNumFDRcvd = 0;
   3199                         memset(mFaceArray, -1, sizeof(mFaceArray));
   3200                         mFaceArray[0] = 0; //faces_detected * 4;
   3201 
   3202                         mFacesDetected = roi->d.hdr.num_face_detected;
   3203                         if(mFacesDetected > MAX_ROI)
   3204                           mFacesDetected = MAX_ROI;
   3205                     }
   3206                     break;
   3207                 case FD_ROI_TYPE_DATA:
   3208                     {
   3209                         int idx = roi->d.data.idx;
   3210                         if (idx < mFacesDetected) {
   3211                             mFaceArray[idx*4+1]   = roi->d.data.face.face_boundary.x;
   3212                             mFaceArray[idx*4+2] = roi->d.data.face.face_boundary.y;
   3213                             mFaceArray[idx*4+3] = roi->d.data.face.face_boundary.x;
   3214                             mFaceArray[idx*4+4] = roi->d.data.face.face_boundary.y;
   3215                             mNumFDRcvd++;
   3216                             if (mNumFDRcvd == mFacesDetected) {
   3217                                 mFaceArray[0] = mFacesDetected * 4;
   3218                                 if(mMetaDataHeap != NULL){
   3219                                     ALOGV("runPreviewThread mMetaDataHEap is non-NULL");
   3220                                     memcpy((uint32_t *)mMetaDataHeap->mHeap->base(), (uint32_t *)mFaceArray, sizeof(mFaceArray));
   3221                                 }
   3222                             }
   3223                         }
   3224                     }
   3225                     break;
   3226                 }
   3227             }
   3228             mMetaDataWaitLock.unlock();
   3229         }
   3230         bufferIndex = mapFrame(handle);
   3231         if(bufferIndex >= 0) {
   3232            LINK_camframe_add_frame(CAM_PREVIEW_FRAME, &frames[bufferIndex]);
   3233            private_handle_t *bhandle = (private_handle_t *)(*handle);
   3234            if (GENLOCK_NO_ERROR != genlock_lock_buffer(bhandle, GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   3235                 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
   3236                 frame_buffer[bufferIndex].lockState = BUFFER_UNLOCKED;
   3237            } else {
   3238                 frame_buffer[bufferIndex].lockState = BUFFER_LOCKED;
   3239            }
   3240         } else {
   3241           ALOGE("Could not find the Frame");
   3242 
   3243           // Special Case: Stoppreview is issued which causes thumbnail buffer
   3244           // to be cancelled. Frame thread has still not exited. In preview thread
   3245           // dequeue returns incorrect buffer id (previously cancelled thumbnail buffer)
   3246           // This will throw error "Could not find frame". We need to cancel the incorrectly
   3247           // dequeued buffer here to ensure that all buffers are available for the next
   3248           // startPreview call.
   3249 
   3250           mDisplayLock.lock();
   3251           ALOGV(" error Cancelling preview buffers  ");
   3252 	    retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   3253 		          handle);
   3254           if(retVal != NO_ERROR)
   3255               ALOGE("%s:  cancelBuffer failed for buffer", __FUNCTION__);
   3256           mDisplayLock.unlock();
   3257         }
   3258       }
   3259     mPreviewThreadWaitLock.lock();
   3260     mPreviewThreadRunning = false;
   3261     mPreviewThreadWait.signal();
   3262     mPreviewThreadWaitLock.unlock();
   3263 }
   3264 int QualcommCameraHardware::mapBuffer(struct msm_frame *frame) {
   3265   int ret = -1;
   3266   for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   3267      if (frame_buffer[cnt].frame->buffer == frame->buffer) {
   3268         ret = cnt;
   3269         break;
   3270        }
   3271     }
   3272   return ret;
   3273 }
   3274 int QualcommCameraHardware::mapvideoBuffer(struct msm_frame *frame)
   3275 {
   3276   int ret = -1;
   3277   for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   3278      if ((unsigned int)mRecordMapped[cnt]->data == (unsigned int)frame->buffer) {
   3279        ret = cnt;
   3280        ALOGI("found match returning %d", ret);
   3281        break;
   3282      }
   3283   }
   3284   return ret;
   3285 
   3286 }
   3287 int QualcommCameraHardware::mapRawBuffer(struct msm_frame *frame)
   3288 {
   3289   int ret = -1;
   3290   for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   3291      if ((unsigned int)mRawMapped[cnt]->data == (unsigned int)frame->buffer) {
   3292        ret = cnt;
   3293        ALOGI("found match returning %d", ret);
   3294        break;
   3295      }
   3296   }
   3297   return ret;
   3298 }
   3299 int QualcommCameraHardware::mapThumbnailBuffer(struct msm_frame *frame)
   3300 {
   3301   int ret = -1;
   3302   for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   3303      if ((unsigned int)(uint8_t *)mThumbnailMapped[cnt] == (unsigned int)frame->buffer) {
   3304        ret = cnt;
   3305        ALOGI("found match returning %d", ret);
   3306        break;
   3307      }
   3308   }
   3309   if(ret < 0) ALOGE("mapThumbnailBuffer, could not find match");
   3310   return ret;
   3311 }
   3312 int QualcommCameraHardware::mapJpegBuffer(mm_camera_buffer_t *encode_buffer)
   3313 {
   3314   int ret = -1;
   3315   for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   3316      if ((unsigned int)mJpegMapped[cnt]->data == (unsigned int)encode_buffer->ptr) {
   3317        ret = cnt;
   3318        ALOGI("found match returning %d", ret);
   3319        break;
   3320      }
   3321   }
   3322   return ret;
   3323 }
   3324 int QualcommCameraHardware::mapFrame(buffer_handle_t *buffer) {
   3325   int ret = -1;
   3326   for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   3327      if (frame_buffer[cnt].buffer == buffer) {
   3328        ret = cnt;
   3329        break;
   3330      }
   3331   }
   3332   return ret;
   3333 }
   3334 
   3335 void *preview_thread(void *user)
   3336 {
   3337     ALOGV("preview_thread E");
   3338     QualcommCameraHardware  *obj = QualcommCameraHardware::getInstance();
   3339     if (obj != 0) {
   3340         obj->runPreviewThread(user);
   3341     }
   3342     else ALOGE("not starting preview thread: the object went away!");
   3343     ALOGV("preview_thread X");
   3344     return NULL;
   3345 }
   3346 
   3347 void *hfr_thread(void *user)
   3348 {
   3349     ALOGV("hfr_thread E");
   3350     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   3351     if (obj != 0) {
   3352         obj->runHFRThread(user);
   3353     }
   3354     else ALOGE("not starting hfr thread: the object went away!");
   3355     ALOGV("hfr_thread X");
   3356     return NULL;
   3357 }
   3358 
   3359 void QualcommCameraHardware::runHFRThread(void *data)
   3360 {
   3361     ALOGV("runHFRThread E");
   3362     mInHFRThread = true;
   3363     CAMERA_HAL_UNUSED(data);
   3364     ALOGI("%s: stopping Preview", __FUNCTION__);
   3365     stopPreviewInternal();
   3366 
   3367     // Release thumbnail Buffers
   3368     if( mPreviewWindow != NULL ) {
   3369         private_handle_t *handle;
   3370         for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   3371             if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) {
   3372                 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   3373                 ALOGV("%s:  Cancelling postview buffer %d ", __FUNCTION__, handle->fd);
   3374                 ALOGV("runHfrThread : display lock");
   3375                 mDisplayLock.lock();
   3376                 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) {
   3377                     if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   3378                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   3379                        mDisplayLock.unlock();
   3380                        continue;
   3381                     } else {
   3382                        mThumbnailLockState[cnt] = BUFFER_UNLOCKED;
   3383                     }
   3384                 }
   3385                 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   3386                                                               mThumbnailBuffer[cnt]);
   3387                 if(retVal != NO_ERROR)
   3388                     ALOGE("%s: cancelBuffer failed for postview buffer %d",
   3389                                                      __FUNCTION__, handle->fd);
   3390                 // unregister , unmap and release as well
   3391                 int mBufferSize = previewWidth * previewHeight * 3/2;
   3392                 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   3393                 if(mThumbnailMapped[cnt] && (mSnapshotFormat == PICTURE_FORMAT_JPEG)) {
   3394                     ALOGI("%s:  Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd);
   3395                     register_buf(mBufferSize,
   3396                         mBufferSize, mCbCrOffset, 0,
   3397                         handle->fd,
   3398                         0,
   3399                         (uint8_t *)mThumbnailMapped[cnt],
   3400                         MSM_PMEM_THUMBNAIL,
   3401                         false, false);
   3402                     if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) {
   3403                       ALOGE("StopPreview : Error un-mmapping the thumbnail buffer %d", index);
   3404                     }
   3405                     mThumbnailBuffer[cnt] = NULL;
   3406                     mThumbnailMapped[cnt] = NULL;
   3407                 }
   3408                 ALOGV("runHfrThread : display unlock");
   3409                 mDisplayLock.unlock();
   3410           }
   3411        }
   3412     }
   3413 
   3414     ALOGV("%s: setting parameters", __FUNCTION__);
   3415     setParameters(mParameters);
   3416     ALOGV("%s: starting Preview", __FUNCTION__);
   3417     if( mPreviewWindow == NULL)
   3418     {
   3419         startPreviewInternal();
   3420     }
   3421     else {
   3422         getBuffersAndStartPreview();
   3423     }
   3424 
   3425     mHFRMode = false;
   3426     mInHFRThread = false;
   3427 }
   3428 
   3429 void QualcommCameraHardware::runVideoThread(void *data)
   3430 {
   3431     ALOGV("runVideoThread E");
   3432     msm_frame* vframe = NULL;
   3433     CAMERA_HAL_UNUSED(data);
   3434 
   3435     while(true) {
   3436         pthread_mutex_lock(&(g_busy_frame_queue.mut));
   3437 
   3438         // Exit the thread , in case of stop recording..
   3439         mVideoThreadWaitLock.lock();
   3440         if(mVideoThreadExit){
   3441             ALOGV("Exiting video thread..");
   3442             mVideoThreadWaitLock.unlock();
   3443             pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   3444             break;
   3445         }
   3446         mVideoThreadWaitLock.unlock();
   3447 
   3448         ALOGV("in video_thread : wait for video frame ");
   3449         // check if any frames are available in busyQ and give callback to
   3450         // services/video encoder
   3451         cam_frame_wait_video();
   3452         ALOGV("video_thread, wait over..");
   3453 
   3454         // Exit the thread , in case of stop recording..
   3455         mVideoThreadWaitLock.lock();
   3456         if(mVideoThreadExit){
   3457             ALOGV("Exiting video thread..");
   3458             mVideoThreadWaitLock.unlock();
   3459             pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   3460             break;
   3461         }
   3462         mVideoThreadWaitLock.unlock();
   3463 
   3464         // Get the video frame to be encoded
   3465         vframe = cam_frame_get_video ();
   3466         pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   3467         ALOGI("in video_thread : got video frame %x",vframe);
   3468 
   3469         /*if (UNLIKELY(mDebugFps)) {
   3470             debugShowVideoFPS();
   3471         }*/
   3472 
   3473         if(vframe != NULL) {
   3474             // Find the offset within the heap of the current buffer.
   3475             //ALOGV("Got video frame :  buffer %d base %d ", vframe->buffer,
   3476               //(unsigned long int)mRecordHeap->mHeap->base());
   3477             //ssize_t offset =
   3478             //    (ssize_t)vframe->buffer - (ssize_t)mRecordHeap->mHeap->base();
   3479             //ALOGV("offset = %d , alignsize = %d , new_offset = %d", (int)offset, mRecordHeap->mAlignedBufferSize,
   3480              // (int)(offset / mRecordHeap->mAlignedBufferSize));
   3481 
   3482             //offset /= mRecordHeap->mAlignedBufferSize;
   3483 
   3484             //set the track flag to true for this video buffer
   3485             //record_buffers_tracking_flag[offset] = true;
   3486 
   3487             /* Extract the timestamp of this frame */
   3488             nsecs_t timeStamp = nsecs_t(vframe->ts.tv_sec)*1000000000LL + vframe->ts.tv_nsec;
   3489 
   3490             // dump frames for test purpose
   3491 #if 0
   3492             static int frameCnt = 0;
   3493             if (frameCnt >= 11 && frameCnt <= 13 ) {
   3494                 char buf[128];
   3495                 sprintf(buf,  "/data/%d_v.yuv", frameCnt);
   3496                 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
   3497                 ALOGV("dumping video frame %d", frameCnt);
   3498                 if (file_fd < 0) {
   3499                     ALOGE("cannot open file\n");
   3500                 }
   3501                 else
   3502                 {
   3503                     write(file_fd, (const void *)vframe->buffer,
   3504                         vframe->cbcr_off * 3 / 2);
   3505                 }
   3506                 close(file_fd);
   3507           }
   3508           frameCnt++;
   3509 #endif
   3510 #if 0
   3511           if(mIs3DModeOn ) {
   3512               /* VPE will be taking care of zoom, so no need to
   3513                * use overlay's setCrop interface for zoom
   3514                * functionality.
   3515                */
   3516               /* get the offset of current video buffer for rendering */
   3517               ssize_t offset_addr = (ssize_t)vframe->buffer -
   3518                                       (ssize_t)mRecordHeap->mHeap->base();
   3519               /* To overcome a timing case where we could be having the overlay refer to deallocated
   3520                  mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the
   3521                  first preview frame is queued to the overlay in 8660 */
   3522               if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) {
   3523                   ALOGD(" receivePreviewFrame : first frame queued, display heap being deallocated");
   3524                   mThumbnailHeap.clear();
   3525                   mDisplayHeap.clear();
   3526                   mFirstFrame = false;
   3527                   mPostviewHeap.clear();
   3528               }
   3529               mLastQueuedFrame = (void *)vframe->buffer;
   3530           }
   3531 #endif
   3532             // Enable IF block to give frames to encoder , ELSE block for just simulation
   3533 #if 1
   3534             ALOGV("in video_thread : got video frame, before if check giving frame to services/encoder");
   3535             mCallbackLock.lock();
   3536             int msgEnabled = mMsgEnabled;
   3537             camera_data_timestamp_callback rcb = mDataCallbackTimestamp;
   3538             void *rdata = mCallbackCookie;
   3539             mCallbackLock.unlock();
   3540 
   3541             /* When 3D mode is ON, the video thread will be ON even in preview
   3542              * mode. We need to distinguish when recording is started. So, when
   3543              * 3D mode is ON, check for the recordingState (which will be set
   3544              * with start recording and reset in stop recording), before
   3545              * calling rcb.
   3546              */
   3547             int index = mapvideoBuffer(vframe);
   3548             if(!mIs3DModeOn) {
   3549                 record_buffers_tracking_flag[index] = true;
   3550                 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
   3551                     ALOGV("in video_thread : got video frame, giving frame to services/encoder index = %d", index);
   3552                     if(mStoreMetaDataInFrame){
   3553                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, metadata_memory[index],0,rdata);
   3554                     } else {
   3555                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordMapped[index],0,rdata);
   3556                     }
   3557                 }
   3558             }
   3559 #if 0
   3560             else {
   3561                 mCallbackLock.lock();
   3562                 msgEnabled = mMsgEnabled;
   3563                 data_callback pcb = mDataCallback;
   3564                 void *pdata = mCallbackCookie;
   3565                 mCallbackLock.unlock();
   3566                 if (pcb != NULL) {
   3567                     ALOGE("pcb is not null");
   3568                     static int count = 0;
   3569                     //if(msgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
   3570                     if (!count) {
   3571                         ALOGE("Giving first frame to app");
   3572                         pcb(CAMERA_MSG_PREVIEW_FRAME, mRecordHeap->mBuffers[offset],
   3573                                 pdata);
   3574                         count++;
   3575                     }
   3576                 }
   3577                 if(mRecordingState == 1) {
   3578                     if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
   3579                         ALOGV("in video_thread 3D mode : got video frame, giving frame to services/encoder");
   3580                         rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[offset], rdata);
   3581                     }
   3582                 } else {
   3583                     /* When in preview mode, put the video buffer back into
   3584                      * free Q, for next availability.
   3585                      */
   3586                     ALOGV("in video_thread 3D mode : got video frame, putting frame to Free Q");
   3587                     record_buffers_tracking_flag[offset] = false;
   3588                     LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe);
   3589                 }
   3590             }
   3591 #endif
   3592 #else
   3593             // 720p output2  : simulate release frame here:
   3594             ALOGI("in video_thread simulation , releasing the video frame");
   3595             LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe);
   3596 #endif
   3597 
   3598         } else ALOGE("in video_thread get frame returned null");
   3599 
   3600 
   3601     } // end of while loop
   3602 
   3603     mVideoThreadWaitLock.lock();
   3604     mVideoThreadRunning = false;
   3605     mVideoThreadWait.signal();
   3606     mVideoThreadWaitLock.unlock();
   3607 
   3608     ALOGV("runVideoThread X");
   3609 }
   3610 
   3611 void *video_thread(void *user)
   3612 {
   3613     ALOGV("video_thread E");
   3614     CAMERA_HAL_UNUSED(user);
   3615 
   3616     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   3617     if (obj != 0) {
   3618         obj->runVideoThread(user);
   3619     }
   3620     else ALOGE("not starting video thread: the object went away!");
   3621     ALOGV("video_thread X");
   3622     return NULL;
   3623 }
   3624 
   3625 void *frame_thread(void *user)
   3626 {
   3627     ALOGD("frame_thread E");
   3628     CAMERA_HAL_UNUSED(user);
   3629     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   3630     if (obj != 0) {
   3631         obj->runFrameThread(user);
   3632     }
   3633     else ALOGW("not starting frame thread: the object went away!");
   3634     ALOGD("frame_thread X");
   3635     return NULL;
   3636 }
   3637 
   3638 static int parse_size(const char *str, int &width, int &height)
   3639 {
   3640     // Find the width.
   3641     char *end;
   3642     int w = (int)strtol(str, &end, 10);
   3643     // If an 'x' or 'X' does not immediately follow, give up.
   3644     if ( (*end != 'x') && (*end != 'X') )
   3645         return -1;
   3646 
   3647     // Find the height, immediately after the 'x'.
   3648     int h = (int)strtol(end+1, 0, 10);
   3649 
   3650     width = w;
   3651     height = h;
   3652 
   3653     return 0;
   3654 }
   3655 QualcommCameraHardware* hardware;
   3656 
   3657 int QualcommCameraHardware::allocate_ion_memory(int *main_ion_fd, struct ion_allocation_data* alloc,
   3658      struct ion_fd_data* ion_info_fd, int ion_type, int size, int *memfd)
   3659 {
   3660     int rc = 0;
   3661     struct ion_handle_data handle_data;
   3662 
   3663     *main_ion_fd = open("/dev/ion", O_RDONLY | O_SYNC);
   3664     if (*main_ion_fd < 0) {
   3665       ALOGE("Ion dev open failed\n");
   3666       ALOGE("Error is %s\n", strerror(errno));
   3667       goto ION_OPEN_FAILED;
   3668     }
   3669     alloc->len = size;
   3670     /* to make it page size aligned */
   3671     alloc->len = (alloc->len + 4095) & (~4095);
   3672     alloc->align = 4096;
   3673     alloc->flags = 0;
   3674     alloc->heap_id_mask = (0x1 << ion_type | 0x1 << ION_IOMMU_HEAP_ID);
   3675 
   3676     rc = ioctl(*main_ion_fd, ION_IOC_ALLOC, alloc);
   3677     if (rc < 0) {
   3678       ALOGE("ION allocation failed\n");
   3679       goto ION_ALLOC_FAILED;
   3680     }
   3681 
   3682     ion_info_fd->handle = alloc->handle;
   3683     rc = ioctl(*main_ion_fd, ION_IOC_SHARE, ion_info_fd);
   3684     if (rc < 0) {
   3685       ALOGE("ION map failed %s\n", strerror(errno));
   3686       goto ION_MAP_FAILED;
   3687     }
   3688     *memfd = ion_info_fd->fd;
   3689     return 0;
   3690 
   3691 ION_MAP_FAILED:
   3692     handle_data.handle = ion_info_fd->handle;
   3693     ioctl(*main_ion_fd, ION_IOC_FREE, &handle_data);
   3694 ION_ALLOC_FAILED:
   3695     close(*main_ion_fd);
   3696 ION_OPEN_FAILED:
   3697     return -1;
   3698 }
   3699 int QualcommCameraHardware::deallocate_ion_memory(int *main_ion_fd, struct ion_fd_data* ion_info_fd)
   3700 {
   3701     struct ion_handle_data handle_data;
   3702     int rc = 0;
   3703 
   3704     handle_data.handle = ion_info_fd->handle;
   3705     ioctl(*main_ion_fd, ION_IOC_FREE, &handle_data);
   3706     close(*main_ion_fd);
   3707     return rc;
   3708 }
   3709 
   3710 bool QualcommCameraHardware::initPreview()
   3711 {
   3712     const char * pmem_region;
   3713     int CbCrOffset = 0;
   3714     int ion_heap;
   3715     mParameters.getPreviewSize(&previewWidth, &previewHeight);
   3716     const char *recordSize = NULL;
   3717     recordSize = mParameters.get(QCameraParameters::KEY_VIDEO_SIZE);
   3718 ALOGI("%s Got preview dimension as %d x %d ", __func__, previewWidth, previewHeight);
   3719     if(!recordSize) {
   3720          //If application didn't set this parameter string, use the values from
   3721          //getPreviewSize() as video dimensions.
   3722          ALOGV("No Record Size requested, use the preview dimensions");
   3723          videoWidth = previewWidth;
   3724          videoHeight = previewHeight;
   3725      } else {
   3726          //Extract the record witdh and height that application requested.
   3727          if(!parse_size(recordSize, videoWidth, videoHeight)) {
   3728              //VFE output1 shouldn't be greater than VFE output2.
   3729              if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) {
   3730                  //Set preview sizes as record sizes.
   3731                  ALOGI("Preview size %dx%d is greater than record size %dx%d,\
   3732                     resetting preview size to record size",previewWidth,\
   3733                       previewHeight, videoWidth, videoHeight);
   3734                  previewWidth = videoWidth;
   3735                  previewHeight = videoHeight;
   3736                  mParameters.setPreviewSize(previewWidth, previewHeight);
   3737              }
   3738              if( (mCurrentTarget != TARGET_MSM7630)
   3739                  && (mCurrentTarget != TARGET_QSD8250)
   3740                   && (mCurrentTarget != TARGET_MSM8660) ) {
   3741                  //For Single VFE output targets, use record dimensions as preview dimensions.
   3742                  previewWidth = videoWidth;
   3743                  previewHeight = videoHeight;
   3744                  mParameters.setPreviewSize(previewWidth, previewHeight);
   3745              }
   3746          } else {
   3747              ALOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize);
   3748              return false;
   3749          }
   3750      }
   3751 
   3752      mDimension.display_width = previewWidth;
   3753      mDimension.display_height= previewHeight;
   3754      mDimension.ui_thumbnail_width =
   3755              thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
   3756      mDimension.ui_thumbnail_height =
   3757              thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   3758 
   3759     ALOGV("initPreview E: preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, videoWidth, videoHeight );
   3760 
   3761     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   3762         mDimension.video_width = CEILING16(videoWidth);
   3763         /* Backup the video dimensions, as video dimensions in mDimension
   3764          * will be modified when DIS is supported. Need the actual values
   3765          * to pass ap part of VPE config
   3766          */
   3767         videoWidth = mDimension.video_width;
   3768         mDimension.video_height = videoHeight;
   3769         ALOGV("initPreview : preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight,
   3770           mDimension.video_width, mDimension.video_height);
   3771     }
   3772 
   3773     // See comments in deinitPreview() for why we have to wait for the frame
   3774     // thread here, and why we can't use pthread_join().
   3775     mFrameThreadWaitLock.lock();
   3776     while (mFrameThreadRunning) {
   3777         ALOGI("initPreview: waiting for old frame thread to complete.");
   3778         mFrameThreadWait.wait(mFrameThreadWaitLock);
   3779         ALOGI("initPreview: old frame thread completed.");
   3780     }
   3781     mFrameThreadWaitLock.unlock();
   3782 
   3783     mInSnapshotModeWaitLock.lock();
   3784     while (mInSnapshotMode) {
   3785         ALOGI("initPreview: waiting for snapshot mode to complete.");
   3786         mInSnapshotModeWait.wait(mInSnapshotModeWaitLock);
   3787         ALOGI("initPreview: snapshot mode completed.");
   3788     }
   3789     mInSnapshotModeWaitLock.unlock();
   3790 
   3791     pmem_region = "/dev/pmem_adsp";
   3792     ion_heap = ION_CAMERA_HEAP_ID;
   3793 
   3794     int cnt = 0;
   3795 
   3796     memset(&myv12_params, 0, sizeof(yv12_format_parms_t));
   3797     mPreviewFrameSize = previewWidth * previewHeight * 3/2;
   3798     ALOGI("Width = %d Height = %d \n", previewWidth, previewHeight);
   3799     if(mPreviewFormat == CAMERA_YUV_420_YV12) {
   3800        myv12_params.CbOffset = PAD_TO_WORD(previewWidth * previewHeight);
   3801        myv12_params.CrOffset = myv12_params.CbOffset + PAD_TO_WORD((previewWidth * previewHeight)/4);
   3802        mDimension.prev_format = CAMERA_YUV_420_YV12;
   3803        ALOGI("CbOffset = 0x%x CrOffset = 0x%x \n",myv12_params.CbOffset, myv12_params.CrOffset);
   3804     } else {
   3805       CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   3806       }
   3807 
   3808     //Pass the yuv formats, display dimensions,
   3809     //so that vfe will be initialized accordingly.
   3810     mDimension.display_luma_width = previewWidth;
   3811     mDimension.display_luma_height = previewHeight;
   3812     mDimension.display_chroma_width = previewWidth;
   3813     mDimension.display_chroma_height = previewHeight;
   3814     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   3815         mPreviewFrameSize = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)) +
   3816                                      2 * (CEILING32(previewWidth/2) * CEILING32(previewHeight/2));
   3817         CbCrOffset = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight));
   3818         mDimension.prev_format = CAMERA_YUV_420_NV21_ADRENO;
   3819         mDimension.display_luma_width = CEILING32(previewWidth);
   3820         mDimension.display_luma_height = CEILING32(previewHeight);
   3821         mDimension.display_chroma_width = 2 * CEILING32(previewWidth/2);
   3822         //Chroma Height is not needed as of now. Just sending with other dimensions.
   3823         mDimension.display_chroma_height = CEILING32(previewHeight/2);
   3824     }
   3825     ALOGV("mDimension.prev_format = %d", mDimension.prev_format);
   3826     ALOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
   3827     ALOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
   3828     ALOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
   3829     ALOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
   3830 
   3831     dstOffset = 0;
   3832     //set DIS value to get the updated video width and height to calculate
   3833     //the required record buffer size
   3834     if(mVpeEnabled) {
   3835         bool status = setDIS();
   3836         if(status) {
   3837             ALOGE("Failed to set DIS");
   3838             return false;
   3839         }
   3840     }
   3841 
   3842   //Pass the original video width and height and get the required width
   3843     //and height for record buffer allocation
   3844     mDimension.orig_video_width = videoWidth;
   3845     mDimension.orig_video_height = videoHeight;
   3846     if(mZslEnable){
   3847         //Limitation of ZSL  where the thumbnail and display dimensions should be the same
   3848         mDimension.ui_thumbnail_width = mDimension.display_width;
   3849         mDimension.ui_thumbnail_height = mDimension.display_height;
   3850         mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
   3851         if (updatePictureDimension(mParameters, mPictureWidth,
   3852           mPictureHeight)) {
   3853           mDimension.picture_width = mPictureWidth;
   3854           mDimension.picture_height = mPictureHeight;
   3855         }
   3856     }
   3857     // mDimension will be filled with thumbnail_width, thumbnail_height,
   3858     // orig_picture_dx, and orig_picture_dy after this function call. We need to
   3859     // keep it for jpeg_encoder_encode.
   3860     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   3861                                sizeof(cam_ctrl_dimension_t), &mDimension);
   3862 #if 0
   3863     if(mIs3DModeOn != true) {
   3864       if(mInHFRThread == false)
   3865       {
   3866         mPrevHeapDeallocRunning = false;
   3867 #ifdef USE_ION
   3868         mPreviewHeap = new IonPool(ion_heap,
   3869                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3870                                 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
   3871                                 mPreviewFrameSize,
   3872                                 kPreviewBufferCountActual,
   3873                                 mPreviewFrameSize,
   3874                                 CbCrOffset,
   3875                                 0,
   3876                                 "preview");
   3877 #else
   3878         mPreviewHeap = new PmemPool(pmem_region,
   3879                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3880                                 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
   3881                                 mPreviewFrameSize,
   3882                                 kPreviewBufferCountActual,
   3883                                 mPreviewFrameSize,
   3884                                 CbCrOffset,
   3885                                 0,
   3886                                 "preview");
   3887 #endif
   3888         if (!mPreviewHeap->initialized()) {
   3889           mPreviewHeap.clear();
   3890           ALOGE("initPreview X: could not initialize Camera preview heap.");
   3891           return false;
   3892         }
   3893       }
   3894       else
   3895       {
   3896           for (int cnt = 0; cnt < kPreviewBufferCountActual; ++cnt) {
   3897               bool status;
   3898               int active = (cnt < ACTIVE_PREVIEW_BUFFERS);
   3899               status = register_buf(mPreviewFrameSize,
   3900                        mPreviewFrameSize,
   3901                        CbCrOffset,
   3902                        0,
   3903                        mPreviewHeap->mHeap->getHeapID(),
   3904                        mPreviewHeap->mAlignedBufferSize * cnt,
   3905                        (uint8_t *)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt,
   3906                        MSM_PMEM_PREVIEW,
   3907                        active,
   3908                        true);
   3909               if(status == false){
   3910                   ALOGE("Registring Preview Buffers failed for HFR mode");
   3911                   return false;
   3912               }
   3913           }
   3914       }
   3915       // if 7x27A , YV12 format is set as preview format , if width is not 32
   3916       // bit aligned , we need seperate buffer to hold YV12 data
   3917     yv12framesize = (previewWidth*previewHeight)
   3918           + 2* ( CEILING16(previewWidth/2) * (previewHeight/2)) ;
   3919     if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) &&
   3920         ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 ) &&
   3921         previewWidth%32 != 0 ){
   3922         ALOGE("initpreview : creating YV12 heap as previewwidth %d not 32 aligned", previewWidth);
   3923 #ifdef USE_ION
   3924         mYV12Heap = new IonPool(ion_heap,
   3925                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3926                                 MSM_PMEM_PREVIEW,
   3927                                 yv12framesize,
   3928                                 NUM_YV12_FRAMES,
   3929                                 yv12framesize,
   3930                                 CbCrOffset,
   3931                                 0,
   3932                                 "postview");
   3933 #else
   3934         mYV12Heap = new PmemPool(pmem_region,
   3935                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   3936                                 MSM_PMEM_PREVIEW,
   3937                                 yv12framesize,
   3938                                 NUM_YV12_FRAMES,
   3939                                 yv12framesize,
   3940                                 CbCrOffset,
   3941                                 0,
   3942                                 "postview");
   3943 #endif
   3944             if (!mYV12Heap->initialized()) {
   3945                 mYV12Heap.clear();
   3946                 ALOGE("initPreview X: could not initialize YV12 Camera preview heap.");
   3947                 return false;
   3948             }
   3949         }
   3950     }
   3951 #endif
   3952 
   3953     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   3954 
   3955         // Allocate video buffers after allocating preview buffers.
   3956         bool status = initRecord();
   3957         if(status != true) {
   3958             ALOGE("Failed to allocate video bufers");
   3959             return false;
   3960         }
   3961     }
   3962 
   3963     if (ret) {
   3964         if(mIs3DModeOn != true) {
   3965             for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
   3966 #if 0
   3967                 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
   3968                 frames[cnt].buffer =
   3969                     (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
   3970                 frames[cnt].y_off = 0;
   3971                 frames[cnt].cbcr_off = CbCrOffset;
   3972                 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
   3973 #endif
   3974         }
   3975 
   3976             mPreviewBusyQueue.init();
   3977             LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   3978             for(int i=ACTIVE_PREVIEW_BUFFERS ;i <kPreviewBufferCount; i++)
   3979                 LINK_camframe_add_frame(CAM_PREVIEW_FRAME,&frames[i]);
   3980 
   3981             mPreviewThreadWaitLock.lock();
   3982             pthread_attr_t pattr;
   3983             pthread_attr_init(&pattr);
   3984             pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
   3985 
   3986             mPreviewThreadRunning = !pthread_create(&mPreviewThread,
   3987                                       &pattr,
   3988                                       preview_thread,
   3989                                       (void*)NULL);
   3990             ret = mPreviewThreadRunning;
   3991             mPreviewThreadWaitLock.unlock();
   3992 
   3993             if(ret == false)
   3994                 return ret;
   3995         }
   3996 
   3997 
   3998         mFrameThreadWaitLock.lock();
   3999         pthread_attr_t attr;
   4000         pthread_attr_init(&attr);
   4001         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   4002         camframeParams.cammode = CAMERA_MODE_2D;
   4003 
   4004         if (mIs3DModeOn) {
   4005             camframeParams.cammode = CAMERA_MODE_3D;
   4006         } else {
   4007             camframeParams.cammode = CAMERA_MODE_2D;
   4008         }
   4009         LINK_cam_frame_set_exit_flag(0);
   4010 
   4011         mFrameThreadRunning = !pthread_create(&mFrameThread,
   4012                                               &attr,
   4013                                               frame_thread,
   4014                                               &camframeParams);
   4015         ret = mFrameThreadRunning;
   4016         mFrameThreadWaitLock.unlock();
   4017         LINK_wait_cam_frame_thread_ready();
   4018     }
   4019     mFirstFrame = true;
   4020 
   4021     ALOGV("initPreview X: %d", ret);
   4022     return ret;
   4023 }
   4024 
   4025 void QualcommCameraHardware::deinitPreview(void)
   4026 {
   4027     ALOGV("deinitPreview E");
   4028 
   4029     mPreviewBusyQueue.deinit();
   4030 
   4031     // When we call deinitPreview(), we signal to the frame thread that it
   4032     // needs to exit, but we DO NOT WAIT for it to complete here.  The problem
   4033     // is that deinitPreview is sometimes called from the frame-thread's
   4034     // callback, when the refcount on the Camera client reaches zero.  If we
   4035     // called pthread_join(), we would deadlock.  So, we just call
   4036     // LINK_camframe_terminate() in deinitPreview(), which makes sure that
   4037     // after the preview callback returns, the camframe thread will exit.  We
   4038     // could call pthread_join() in initPreview() to join the last frame
   4039     // thread.  However, we would also have to call pthread_join() in release
   4040     // as well, shortly before we destroy the object; this would cause the same
   4041     // deadlock, since release(), like deinitPreview(), may also be called from
   4042     // the frame-thread's callback.  This we have to make the frame thread
   4043     // detached, and use a separate mechanism to wait for it to complete.
   4044 
   4045     LINK_camframe_terminate();
   4046     ALOGV("deinitPreview X");
   4047 }
   4048 
   4049 bool QualcommCameraHardware::initRawSnapshot()
   4050 {
   4051     ALOGV("initRawSnapshot E");
   4052     const char * pmem_region;
   4053 
   4054     //get width and height from Dimension Object
   4055     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   4056                                sizeof(cam_ctrl_dimension_t), &mDimension);
   4057 
   4058 
   4059     if(!ret){
   4060         ALOGE("initRawSnapshot X: failed to set dimension");
   4061         return false;
   4062     }
   4063     int rawSnapshotSize = mDimension.raw_picture_height *
   4064                            mDimension.raw_picture_width;
   4065 
   4066     ALOGI("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
   4067          "raw_picture_width = %d",
   4068           rawSnapshotSize, mDimension.raw_picture_height,
   4069           mDimension.raw_picture_width);
   4070 
   4071     // Create Memory for Raw Snapshot
   4072     if( createSnapshotMemory(numCapture, numCapture, false, PICTURE_FORMAT_RAW) == false ) // TODO : check if the numbers are correct
   4073     {
   4074         ALOGE("ERROR :  initRawSnapshot , createSnapshotMemory failed");
   4075         return false;
   4076     }
   4077 
   4078     mRawCaptureParms.num_captures = 1;
   4079     mRawCaptureParms.raw_picture_width = mDimension.raw_picture_width;
   4080     mRawCaptureParms.raw_picture_height = mDimension.raw_picture_height;
   4081 
   4082     ALOGV("initRawSnapshot X");
   4083     return true;
   4084 
   4085 }
   4086 bool QualcommCameraHardware::initZslBuffers(bool initJpegHeap){
   4087     ALOGV("Init ZSL buffers E");
   4088     const char * pmem_region;
   4089     int ion_heap = ION_CP_MM_HEAP_ID;
   4090     int postViewBufferSize;
   4091 
   4092     mPostviewWidth = mDimension.display_width;
   4093     mPostviewHeight =  mDimension.display_height;
   4094 
   4095     //postview buffer initialization
   4096     postViewBufferSize  = mPostviewWidth * mPostviewHeight * 3 / 2;
   4097     int CbCrOffsetPostview = PAD_TO_WORD(mPostviewWidth * mPostviewHeight);
   4098     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   4099         postViewBufferSize  = PAD_TO_4K(CEILING32(mPostviewWidth) * CEILING32(mPostviewHeight)) +
   4100                                   2 * (CEILING32(mPostviewWidth/2) * CEILING32(mPostviewHeight/2));
   4101         int CbCrOffsetPostview = PAD_TO_4K(CEILING32(mPostviewWidth) * CEILING32(mPostviewHeight));
   4102     }
   4103 
   4104     //Snapshot buffer initialization
   4105     mRawSize = mPictureWidth * mPictureHeight * 3 / 2;
   4106     mCbCrOffsetRaw = PAD_TO_WORD(mPictureWidth * mPictureHeight);
   4107     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   4108         mRawSize = PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)) +
   4109                             2 * (CEILING32(mPictureWidth/2) * CEILING32(mPictureHeight/2));
   4110         mCbCrOffsetRaw = PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight));
   4111     }
   4112 
   4113     //Jpeg buffer initialization
   4114     if( mCurrentTarget == TARGET_MSM7627 ||
   4115        (mCurrentTarget == TARGET_MSM7625A ||
   4116         mCurrentTarget == TARGET_MSM7627A))
   4117         mJpegMaxSize = CEILING16(mPictureWidth) * CEILING16(mPictureHeight) * 3 / 2;
   4118     else {
   4119         mJpegMaxSize = mPictureWidth * mPictureHeight * 3 / 2;
   4120         if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
   4121             mJpegMaxSize =
   4122                PAD_TO_4K(CEILING32(mPictureWidth) * CEILING32(mPictureHeight)) +
   4123                     2 * (CEILING32(mPictureWidth/2) * CEILING32(mPictureHeight/2));
   4124         }
   4125     }
   4126 
   4127     cam_buf_info_t buf_info;
   4128     int yOffset = 0;
   4129     buf_info.resolution.width = mPictureWidth;
   4130     buf_info.resolution.height = mPictureHeight;
   4131     if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
   4132         mCfgControl.mm_camera_get_parm(CAMERA_PARM_BUFFER_INFO, (void *)&buf_info);
   4133         mRawSize = buf_info.size;
   4134         mJpegMaxSize = mRawSize;
   4135         mCbCrOffsetRaw = buf_info.cbcr_offset;
   4136         yOffset = buf_info.yoffset;
   4137     }
   4138 
   4139     ALOGV("initZslBuffer: initializing mRawHeap.");
   4140     if(mCurrentTarget == TARGET_MSM8660) {
   4141        pmem_region = "/dev/pmem_smipool";
   4142     } else {
   4143        pmem_region = "/dev/pmem_adsp";
   4144     }
   4145     //Main Raw Image
   4146     #if 0
   4147 #ifdef USE_ION
   4148     mRawHeap =
   4149         new IonPool( ion_heap,
   4150                      MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4151                      MSM_PMEM_MAINIMG,
   4152                      mJpegMaxSize,
   4153                      MAX_SNAPSHOT_BUFFERS,
   4154                      mRawSize,
   4155                      mCbCrOffsetRaw,
   4156                      yOffset,
   4157                      "snapshot camera");
   4158 #else
   4159     mRawHeap =
   4160         new PmemPool(pmem_region,
   4161                      MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4162                      MSM_PMEM_MAINIMG,
   4163                      mJpegMaxSize,
   4164                      MAX_SNAPSHOT_BUFFERS,
   4165                      mRawSize,
   4166                      mCbCrOffsetRaw,
   4167                      yOffset,
   4168                      "snapshot camera");
   4169 #endif
   4170     if (!mRawHeap->initialized()) {
   4171        ALOGE("initZslBuffer X failed ");
   4172        mRawHeap.clear();
   4173        ALOGE("initRaw X: error initializing mRawHeap");
   4174        return false;
   4175     }
   4176 
   4177 
   4178     // Jpeg
   4179     if (initJpegHeap) {
   4180         ALOGV("initZslRaw: initializing mJpegHeap.");
   4181         mJpegHeap =
   4182             new AshmemPool(mJpegMaxSize,
   4183                            (MAX_SNAPSHOT_BUFFERS - 2),  // It is the max number of snapshot supported.
   4184                            0, // we do not know how big the picture will be
   4185                            "jpeg");
   4186 
   4187         if (!mJpegHeap->initialized()) {
   4188             mJpegHeap.clear();
   4189             mRawHeap.clear();
   4190             ALOGE("initZslRaw X failed: error initializing mJpegHeap.");
   4191             return false;
   4192         }
   4193     }
   4194 
   4195     //PostView
   4196     pmem_region = "/dev/pmem_adsp";
   4197     ion_heap = ION_HEAP_ADSP_ID;
   4198 #ifdef USE_ION
   4199     mPostviewHeap =
   4200             new IonPool(ion_heap,
   4201                         MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4202                         MSM_PMEM_THUMBNAIL,
   4203                         postViewBufferSize,
   4204                         MAX_SNAPSHOT_BUFFERS,
   4205                         postViewBufferSize,
   4206                         CbCrOffsetPostview,
   4207                         0,
   4208                         "thumbnail");
   4209 #else
   4210     mPostviewHeap =
   4211             new PmemPool(pmem_region,
   4212                          MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   4213                          MSM_PMEM_THUMBNAIL,
   4214                          postViewBufferSize,
   4215                          MAX_SNAPSHOT_BUFFERS,
   4216                          postViewBufferSize,
   4217                          CbCrOffsetPostview,
   4218                          0,
   4219                          "thumbnail");
   4220 #endif
   4221 
   4222     if (!mPostviewHeap->initialized()) {
   4223         mPostviewHeap.clear();
   4224         mJpegHeap.clear();
   4225         mRawHeap.clear();
   4226         ALOGE("initZslBuffer X failed: error initializing mPostviewHeap.");
   4227         return false;
   4228     }
   4229 #endif
   4230     if( createSnapshotMemory(MAX_SNAPSHOT_BUFFERS, MAX_SNAPSHOT_BUFFERS, initJpegHeap) == false ) // TODO : check if the numbers are correct
   4231     {
   4232         ALOGE("ERROR :  initZslraw , createSnapshotMemory failed");
   4233         return false;
   4234     }
   4235     /* frame all the exif and encode information into encode_params_t */
   4236     initImageEncodeParameters(MAX_SNAPSHOT_BUFFERS);
   4237 
   4238     ALOGV("initZslRaw X");
   4239     return true;
   4240 }
   4241 
   4242 bool QualcommCameraHardware::deinitZslBuffers()
   4243 {
   4244     ALOGV("deinitZslBuffers E");
   4245     for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   4246        if(NULL != mRawMapped[cnt]) {
   4247          ALOGI("Unregister MAIN_IMG");
   4248          register_buf(mJpegMaxSize,
   4249                   mRawSize,mCbCrOffsetRaw,0,
   4250                   mRawfd[cnt],0,
   4251                   (uint8_t *)mRawMapped[cnt]->data,
   4252                   MSM_PMEM_MAINIMG,
   4253                   0, 0);
   4254             mRawMapped[cnt]->release(mRawMapped[cnt]);
   4255             mRawMapped[cnt] = NULL;
   4256             close(mRawfd[cnt]);
   4257 #ifdef USE_ION
   4258             deallocate_ion_memory(&raw_main_ion_fd[cnt], &raw_ion_info_fd[cnt]);
   4259 #endif
   4260         }
   4261     }
   4262     for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS) : numCapture); cnt++) {
   4263         if(mJpegMapped[cnt]) {
   4264             mJpegMapped[cnt]->release(mJpegMapped[cnt]);
   4265             mJpegMapped[cnt] = NULL;
   4266         }
   4267     }
   4268     ALOGV("deinitZslBuffers X");
   4269     return true;
   4270 }
   4271 
   4272 bool QualcommCameraHardware::createSnapshotMemory (int numberOfRawBuffers, int numberOfJpegBuffers,
   4273                                                    bool initJpegHeap, int snapshotFormat)
   4274 {
   4275     char * pmem_region;
   4276     int ret;
   4277     int ion_heap = ION_CP_MM_HEAP_ID;
   4278     if(mCurrentTarget == TARGET_MSM8660) {
   4279        pmem_region = "/dev/pmem_smipool";
   4280     } else {
   4281        pmem_region = "/dev/pmem_adsp";
   4282     }
   4283     if( snapshotFormat == PICTURE_FORMAT_JPEG) {
   4284         // Create Raw memory for snapshot
   4285         for(int cnt = 0; cnt < numberOfRawBuffers; cnt++)
   4286         {
   4287         #ifdef USE_ION
   4288             if (allocate_ion_memory(&raw_main_ion_fd[cnt], &raw_alloc[cnt], &raw_ion_info_fd[cnt],
   4289                                     ion_heap, mJpegMaxSize, &mRawfd[cnt]) < 0){
   4290               ALOGE("do_mmap: Open device %s failed!\n",pmem_region);
   4291               return NULL;
   4292             }
   4293         #else
   4294             mRawfd[cnt] = open(pmem_region, O_RDWR|O_SYNC);
   4295             if (mRawfd[cnt] <= 0) {
   4296                 ALOGE("%s: Open device %s failed!\n",__func__, pmem_region);
   4297                     return false;
   4298             }
   4299         #endif
   4300             ALOGI("%s  Raw memory index: %d , fd is %d ", __func__, cnt, mRawfd[cnt]);
   4301             mRawMapped[cnt]=mGetMemory(mRawfd[cnt], mJpegMaxSize,1,mCallbackCookie);
   4302             if(mRawMapped[cnt] == NULL) {
   4303                 ALOGE("Failed to get camera memory for mRawMapped heap index: %d", cnt);
   4304                 return false;
   4305             }else{
   4306                ALOGI("Received following info for raw mapped data:%p,handle:%p, size:%d,release:%p",
   4307                mRawMapped[cnt]->data ,mRawMapped[cnt]->handle, mRawMapped[cnt]->size, mRawMapped[cnt]->release);
   4308             }
   4309             // Register Raw frames
   4310             ALOGI("Registering buffer %d with fd :%d with kernel",cnt,mRawfd[cnt]);
   4311             int active = (cnt < ACTIVE_ZSL_BUFFERS);  // TODO check ?
   4312             register_buf(mJpegMaxSize,
   4313                 mRawSize,
   4314                 mCbCrOffsetRaw,
   4315                 mYOffset,
   4316                 mRawfd[cnt],0,
   4317                 (uint8_t *)mRawMapped[cnt]->data,
   4318                 MSM_PMEM_MAINIMG,
   4319                 active);
   4320         }
   4321         // Create Jpeg memory for snapshot
   4322         if (initJpegHeap)
   4323         {
   4324             for(int cnt = 0; cnt < numberOfJpegBuffers; cnt++)
   4325             {
   4326                 ALOGI("%s  Jpeg memory index: %d , fd is %d ", __func__, cnt, mJpegfd[cnt]);
   4327                 mJpegMapped[cnt]=mGetMemory(-1, mJpegMaxSize,1,mCallbackCookie);
   4328                 if(mJpegMapped[cnt] == NULL) {
   4329                     ALOGE("Failed to get camera memory for mJpegMapped heap index: %d", cnt);
   4330                     return false;
   4331                 }else{
   4332                    ALOGI("Received following info for jpeg mapped data:%p,handle:%p, size:%d,release:%p",
   4333                    mJpegMapped[cnt]->data ,mJpegMapped[cnt]->handle, mJpegMapped[cnt]->size, mJpegMapped[cnt]->release);
   4334                 }
   4335             }
   4336         }
   4337         // Lock Thumbnail buffers, and register them
   4338         ALOGI("Locking and registering Thumbnail buffer(s)");
   4339         for(int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   4340             // TODO : change , lock all thumbnail buffers
   4341             if((mPreviewWindow != NULL) && (mThumbnailBuffer[cnt] != NULL)) {
   4342                 ALOGI("createsnapshotbuffers : display lock");
   4343                 mDisplayLock.lock();
   4344                 /* Lock the postview buffer before use */
   4345                 ALOGI(" Locking thumbnail/postview buffer %d", cnt);
   4346                 if( (ret = mPreviewWindow->lock_buffer(mPreviewWindow,
   4347                                  mThumbnailBuffer[cnt])) != NO_ERROR) {
   4348                     ALOGE(" Error locking postview buffer. Error = %d ", ret);
   4349                     ALOGE("createsnapshotbuffers : display unlock error");
   4350                     mDisplayLock.unlock();
   4351                     return false;
   4352                 }
   4353                 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t*)(*mThumbnailBuffer[cnt]),
   4354                                                            GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   4355                     ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
   4356                     mDisplayLock.unlock();
   4357                     return -EINVAL;
   4358                 } else {
   4359                     mThumbnailLockState[cnt] = BUFFER_LOCKED;
   4360                 }
   4361                 mDisplayLock.unlock();
   4362                 ALOGE("createsnapshotbuffers : display unlock");
   4363             }
   4364 
   4365             private_handle_t *thumbnailHandle;
   4366             int mBufferSize = previewWidth * previewHeight * 3/2;
   4367             int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4368 
   4369             if(mThumbnailBuffer[cnt]) {
   4370                 thumbnailHandle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   4371                 ALOGI("fd thumbnailhandle fd %d size %d", thumbnailHandle->fd, thumbnailHandle->size);
   4372                 mThumbnailMapped [cnt]= (unsigned int) mmap(0, thumbnailHandle->size, PROT_READ|PROT_WRITE,
   4373                 MAP_SHARED, thumbnailHandle->fd, 0);
   4374                 if((void *)mThumbnailMapped[cnt] == MAP_FAILED){
   4375                     ALOGE(" Couldnt map Thumbnail buffer %d", errno);
   4376                     return false;
   4377                 }
   4378                 register_buf(mBufferSize,
   4379                     mBufferSize, mCbCrOffset, 0,
   4380                     thumbnailHandle->fd,
   4381                     0,
   4382                     (uint8_t *)mThumbnailMapped[cnt],
   4383                     MSM_PMEM_THUMBNAIL,
   4384                     (cnt < ACTIVE_ZSL_BUFFERS));
   4385             }
   4386         } // for loop locking and registering thumbnail buffers
   4387     }  else { // End if Format is Jpeg , start if format is RAW
   4388          if(numberOfRawBuffers ==1) {
   4389              int rawSnapshotSize = mDimension.raw_picture_height * mDimension.raw_picture_width;
   4390 #ifdef USE_ION
   4391             if (allocate_ion_memory(&raw_snapshot_main_ion_fd, &raw_snapshot_alloc, &raw_snapshot_ion_info_fd,
   4392                                     ion_heap, rawSnapshotSize, &mRawSnapshotfd) < 0){
   4393               ALOGE("do_mmap: Open device %s failed!\n",pmem_region);
   4394               return false;
   4395             }
   4396 #else
   4397             mRawSnapshotfd = open(pmem_region, O_RDWR|O_SYNC);
   4398             if (mRawSnapshotfd <= 0) {
   4399                 ALOGE("%s: Open device %s failed for rawnspashot!\n",__func__, pmem_region);
   4400                 return false;
   4401             }
   4402 #endif
   4403             ALOGI("%s  Raw snapshot memory , fd is %d ", __func__, mRawSnapshotfd);
   4404             mRawSnapshotMapped=mGetMemory(mRawSnapshotfd,
   4405                                           rawSnapshotSize,
   4406                                           1,
   4407                                           mCallbackCookie);
   4408             if(mRawSnapshotMapped == NULL) {
   4409                 ALOGE("Failed to get camera memory for mRawSnapshotMapped ");
   4410                 return false;
   4411             }else{
   4412                ALOGI("Received following info for raw mapped data:%p,handle:%p, size:%d,release:%p",
   4413                mRawSnapshotMapped->data ,mRawSnapshotMapped->handle, mRawSnapshotMapped->size, mRawSnapshotMapped->release);
   4414             }
   4415                         // Register Raw frames
   4416             ALOGI("Registering RawSnapshot buffer with fd :%d with kernel",mRawSnapshotfd);
   4417             int active = 1;  // TODO check ?
   4418             register_buf(     rawSnapshotSize,
   4419                               rawSnapshotSize,
   4420                                             0,
   4421                                             0,
   4422                               mRawSnapshotfd,
   4423                                             0,
   4424                               (uint8_t *)mRawSnapshotMapped->data,
   4425                               MSM_PMEM_RAW_MAINIMG,
   4426                                         active);
   4427          } else {
   4428              ALOGE("Multiple raw snapshot capture not supported for now....");
   4429              return false;
   4430          }
   4431     } // end else , if RAW format
   4432     return true;
   4433 }
   4434 bool QualcommCameraHardware::initRaw(bool initJpegHeap)
   4435 {
   4436     const char * pmem_region;
   4437     int ion_heap;
   4438     int postViewBufferSize;
   4439     uint32_t pictureAspectRatio;
   4440     uint32_t i;
   4441     mParameters.getPictureSize(&mPictureWidth, &mPictureHeight);
   4442     mActualPictWidth = mPictureWidth;
   4443     mActualPictHeight = mPictureHeight;
   4444     if (updatePictureDimension(mParameters, mPictureWidth, mPictureHeight)) {
   4445         mDimension.picture_width = mPictureWidth;
   4446         mDimension.picture_height = mPictureHeight;
   4447     }
   4448     ALOGV("initRaw E: picture size=%dx%d", mPictureWidth, mPictureHeight);
   4449     int w_scale_factor = (mIs3DModeOn && mSnapshot3DFormat == SIDE_BY_SIDE_FULL) ? 2 : 1;
   4450 
   4451     /* use the default thumbnail sizes */
   4452     mThumbnailHeight = thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
   4453     mThumbnailWidth = (mThumbnailHeight * mPictureWidth)/ mPictureHeight;
   4454     /* see if we can get better thumbnail sizes (not mandatory?) */
   4455     pictureAspectRatio = (uint32_t)((mPictureWidth * Q12) / mPictureHeight);
   4456     for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ){
   4457         if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio)
   4458         {
   4459             mThumbnailWidth = thumbnail_sizes[i].width;
   4460             mThumbnailHeight = thumbnail_sizes[i].height;
   4461             break;
   4462         }
   4463     }
   4464     /* calculate thumbnail aspect ratio */
   4465     if(mCurrentTarget == TARGET_MSM7627 ) {
   4466         int thumbnail_aspect_ratio =
   4467         (uint32_t)((mThumbnailWidth * Q12) / mThumbnailHeight);
   4468 
   4469        if (thumbnail_aspect_ratio < pictureAspectRatio) {
   4470 
   4471           /* if thumbnail is narrower than main image, in other words wide mode
   4472            * snapshot then we want to adjust the height of the thumbnail to match
   4473            * the main image aspect ratio. */
   4474            mThumbnailHeight =
   4475            (mThumbnailWidth * Q12) / pictureAspectRatio;
   4476        } else if (thumbnail_aspect_ratio != pictureAspectRatio) {
   4477 
   4478           /* if thumbnail is wider than main image we want to adjust width of the
   4479            * thumbnail to match main image aspect ratio */
   4480            mThumbnailWidth  =
   4481            (mThumbnailHeight * pictureAspectRatio) / Q12;
   4482        }
   4483        /* make the dimensions multiple of 16 - JPEG requirement */
   4484        mThumbnailWidth = FLOOR16(mThumbnailWidth);
   4485        mThumbnailHeight = FLOOR16(mThumbnailHeight);
   4486        ALOGV("the thumbnail sizes are %dx%d",mThumbnailWidth,mThumbnailHeight);
   4487     }
   4488 
   4489     /* calculate postView size */
   4490     mPostviewWidth = mThumbnailWidth;
   4491     mPostviewHeight = mThumbnailHeight;
   4492     /* Try to keep the postview dimensions near to preview for better
   4493      * performance and userexperience. If the postview and preview dimensions
   4494      * are same, then we can try to use the same overlay of preview for
   4495      * postview also. If not, we need to reset the overlay for postview.
   4496      * we will be getting the same dimensions for preview and postview
   4497      * in most of the cases. The only exception is for applications
   4498      * which won't use optimalPreviewSize based on picture size.
   4499     */
   4500     if((mPictureHeight >= previewHeight) &&
   4501        (mCurrentTarget != TARGET_MSM7627) && !mIs3DModeOn) {
   4502         mPostviewHeight = previewHeight;
   4503         mPostviewWidth = (previewHeight * mPictureWidth) / mPictureHeight;
   4504     }else if(mActualPictHeight < mThumbnailHeight){
   4505         mPostviewHeight = THUMBNAIL_SMALL_HEIGHT;
   4506         mPostviewWidth = (THUMBNAIL_SMALL_HEIGHT * mActualPictWidth)/ mActualPictHeight;
   4507         mThumbnailWidth = mPostviewWidth;
   4508         mThumbnailHeight = mPostviewHeight;
   4509     }
   4510 
   4511     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
   4512         mDimension.main_img_format = CAMERA_YUV_420_NV21_ADRENO;
   4513         mDimension.thumb_format = CAMERA_YUV_420_NV21_ADRENO;
   4514     }
   4515 
   4516     mDimension.ui_thumbnail_width = mPostviewWidth;
   4517     mDimension.ui_thumbnail_height = mPostviewHeight;
   4518 
   4519     // mDimension will be filled with thumbnail_width, thumbnail_height,
   4520     // orig_picture_dx, and orig_picture_dy after this function call. We need to
   4521     // keep it for jpeg_encoder_encode.
   4522     bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
   4523                                sizeof(cam_ctrl_dimension_t), &mDimension);
   4524 
   4525     if(!ret) {
   4526         ALOGE("initRaw X: failed to set dimension");
   4527         return false;
   4528     }
   4529 #if 0
   4530     if (mJpegHeap != NULL) {
   4531         ALOGV("initRaw: clearing old mJpegHeap.");
   4532         mJpegHeap.clear();
   4533     }
   4534 #endif
   4535     //postview buffer initialization
   4536     postViewBufferSize  = mPostviewWidth * w_scale_factor * mPostviewHeight * 3 / 2;
   4537     int CbCrOffsetPostview = PAD_TO_WORD(mPostviewWidth * w_scale_factor * mPostviewHeight);
   4538 
   4539     //Snapshot buffer initialization
   4540     mRawSize = mPictureWidth * w_scale_factor * mPictureHeight * 3 / 2;
   4541     mCbCrOffsetRaw = PAD_TO_WORD(mPictureWidth * w_scale_factor * mPictureHeight);
   4542     if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
   4543         mRawSize = PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)) +
   4544                             2 * (CEILING32(mPictureWidth * w_scale_factor/2) * CEILING32(mPictureHeight/2));
   4545         mCbCrOffsetRaw = PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight));
   4546     }
   4547 
   4548     //Jpeg buffer initialization
   4549     if( mCurrentTarget == TARGET_MSM7627 ||
   4550        (mCurrentTarget == TARGET_MSM7625A ||
   4551         mCurrentTarget == TARGET_MSM7627A))
   4552         mJpegMaxSize = CEILING16(mPictureWidth * w_scale_factor) * CEILING16(mPictureHeight) * 3 / 2;
   4553     else {
   4554         mJpegMaxSize = mPictureWidth * w_scale_factor * mPictureHeight * 3 / 2;
   4555         if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
   4556             mJpegMaxSize =
   4557                PAD_TO_4K(CEILING32(mPictureWidth * w_scale_factor) * CEILING32(mPictureHeight)) +
   4558                     2 * (CEILING32(mPictureWidth * w_scale_factor/2) * CEILING32(mPictureHeight/2));
   4559         }
   4560     }
   4561 
   4562     int rotation = mParameters.getInt("rotation");
   4563     char mDeviceName[PROPERTY_VALUE_MAX];
   4564     property_get("ro.hw_plat", mDeviceName, "");
   4565     if(!strcmp(mDeviceName,"7x25A"))
   4566         rotation = (rotation + 90)%360;
   4567 
   4568     if (mIs3DModeOn)
   4569         rotation = 0;
   4570     ret = native_set_parms(CAMERA_PARM_JPEG_ROTATION, sizeof(int), &rotation);
   4571     if(!ret){
   4572         ALOGE("setting camera id failed");
   4573         return false;
   4574     }
   4575     cam_buf_info_t buf_info;
   4576     if(mIs3DModeOn == false)
   4577     {
   4578         buf_info.resolution.width = mPictureWidth * w_scale_factor;
   4579         buf_info.resolution.height = mPictureHeight;
   4580         mCfgControl.mm_camera_get_parm(CAMERA_PARM_BUFFER_INFO, (void *)&buf_info);
   4581         mRawSize = buf_info.size;
   4582         mJpegMaxSize = mRawSize;
   4583         mCbCrOffsetRaw = buf_info.cbcr_offset;
   4584         mYOffset = buf_info.yoffset;
   4585     }
   4586     int mBufferSize;
   4587     int CbCrOffset;
   4588     if(mCurrentTarget != TARGET_MSM7627 && mCurrentTarget != TARGET_MSM7627A){
   4589         mParameters.getPreviewSize(&previewWidth, &previewHeight);
   4590         mBufferSize = previewWidth * previewHeight * 3/2;
   4591         CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4592     }
   4593     else {
   4594         mBufferSize = mPostviewWidth * mPostviewHeight * 3/2;
   4595         CbCrOffset = PAD_TO_WORD(mPostviewWidth * mPostviewHeight);
   4596     }
   4597 
   4598     ALOGV("initRaw: initializing mRawHeap.");
   4599 
   4600     //PostView
   4601     pmem_region = "/dev/pmem_adsp";
   4602     ion_heap = ION_CAMERA_HEAP_ID;
   4603     // Create memory for Raw YUV frames and Jpeg images
   4604     if( createSnapshotMemory(numCapture, numCapture, initJpegHeap) == false )
   4605     {
   4606         ALOGE("ERROR :  initraw , createSnapshotMemory failed");
   4607         return false;
   4608     }
   4609     /* frame all the exif and encode information into encode_params_t */
   4610 
   4611     initImageEncodeParameters(numCapture);
   4612     /* fill main image size, thumbnail size, postview size into capture_params_t*/
   4613     memset(&mImageCaptureParms, 0, sizeof(capture_params_t));
   4614     mImageCaptureParms.num_captures = numCapture;
   4615     mImageCaptureParms.picture_width = mPictureWidth;
   4616     mImageCaptureParms.picture_height = mPictureHeight;
   4617     mImageCaptureParms.postview_width = mPostviewWidth;
   4618     mImageCaptureParms.postview_height = mPostviewHeight;
   4619 
   4620     int width = mParameters.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
   4621     int height = mParameters.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
   4622     if((width != 0) && (height != 0)) {
   4623         mImageCaptureParms.thumbnail_width = mThumbnailWidth;
   4624         mImageCaptureParms.thumbnail_height = mThumbnailHeight;
   4625     } else {
   4626         mImageCaptureParms.thumbnail_width = 0;
   4627         mImageCaptureParms.thumbnail_height = 0;
   4628     }
   4629 
   4630     ALOGI("%s: picture size=%dx%d",__FUNCTION__,
   4631         mImageCaptureParms.picture_width, mImageCaptureParms.picture_height);
   4632     ALOGI("%s: postview size=%dx%d",__FUNCTION__,
   4633         mImageCaptureParms.postview_width, mImageCaptureParms.postview_height);
   4634     ALOGI("%s: thumbnail size=%dx%d",__FUNCTION__,
   4635         mImageCaptureParms.thumbnail_width, mImageCaptureParms.thumbnail_height);
   4636 
   4637     ALOGV("initRaw X");
   4638     return true;
   4639 }
   4640 
   4641 
   4642 void QualcommCameraHardware::deinitRawSnapshot()
   4643 {
   4644     ALOGV("deinitRawSnapshot E");
   4645 
   4646     int rawSnapshotSize = mDimension.raw_picture_height * mDimension.raw_picture_width;
   4647      // Unregister and de allocated memory for Raw Snapshot
   4648     if(mRawSnapshotMapped) {
   4649         register_buf(         rawSnapshotSize,
   4650                               rawSnapshotSize,
   4651                                             0,
   4652                                             0,
   4653                                mRawSnapshotfd,
   4654                                             0,
   4655           (uint8_t *)mRawSnapshotMapped->data,
   4656                          MSM_PMEM_RAW_MAINIMG,
   4657                                         false,
   4658                                         false);
   4659         mRawSnapshotMapped->release(mRawSnapshotMapped);
   4660         mRawSnapshotMapped = NULL;
   4661         close(mRawSnapshotfd);
   4662 #ifdef USE_ION
   4663         deallocate_ion_memory(&raw_snapshot_main_ion_fd, &raw_snapshot_ion_info_fd);
   4664 #endif
   4665     }
   4666     ALOGV("deinitRawSnapshot X");
   4667 }
   4668 
   4669 void QualcommCameraHardware::deinitRaw()
   4670 {
   4671     ALOGV("deinitRaw E");
   4672     ALOGV("deinitRaw , clearing raw memory and jpeg memory");
   4673     for (int cnt = 0; cnt < (mZslEnable? MAX_SNAPSHOT_BUFFERS : numCapture); cnt++) {
   4674        if(NULL != mRawMapped[cnt]) {
   4675          ALOGI("Unregister MAIN_IMG");
   4676          register_buf(mJpegMaxSize,
   4677                   mRawSize,mCbCrOffsetRaw,0,
   4678                   mRawfd[cnt],0,
   4679                   (uint8_t *)mRawMapped[cnt]->data,
   4680                   MSM_PMEM_MAINIMG,
   4681                   0, 0);
   4682             mRawMapped[cnt]->release(mRawMapped[cnt]);
   4683             mRawMapped[cnt] = NULL;
   4684             close(mRawfd[cnt]);
   4685 #ifdef USE_ION
   4686             deallocate_ion_memory(&raw_main_ion_fd[cnt], &raw_ion_info_fd[cnt]);
   4687 #endif
   4688         }
   4689     }
   4690     for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS) : numCapture); cnt++) {
   4691         if(NULL != mJpegMapped[cnt]) {
   4692             mJpegMapped[cnt]->release(mJpegMapped[cnt]);
   4693             mJpegMapped[cnt] = NULL;
   4694         }
   4695     }
   4696     if( mPreviewWindow != NULL ) {
   4697         ALOGI("deinitRaw , clearing/cancelling thumbnail buffers:");
   4698         private_handle_t *handle;
   4699         for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   4700             if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) {
   4701                 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   4702                 ALOGI("%s:  Cancelling postview buffer %d ", __FUNCTION__, handle->fd);
   4703                 ALOGI("deinitraw : display lock");
   4704                 mDisplayLock.lock();
   4705                 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) {
   4706                     if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   4707                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   4708                     } else {
   4709                        mThumbnailLockState[cnt] = BUFFER_UNLOCKED;
   4710                     }
   4711                 }
   4712                 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   4713                                                               mThumbnailBuffer[cnt]);
   4714                 if(retVal != NO_ERROR)
   4715                     ALOGE("%s: cancelBuffer failed for postview buffer %d",
   4716                                                      __FUNCTION__, handle->fd);
   4717                    if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   4718                        struct encoder_media_buffer_type * packet =
   4719                                (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   4720                        native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   4721                        metadata_memory[cnt]->release(metadata_memory[cnt]);
   4722                        metadata_memory[cnt] = NULL;
   4723                    }
   4724                 // unregister , unmap and release as well
   4725 
   4726                 int mBufferSize = previewWidth * previewHeight * 3/2;
   4727                 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4728                 if(mThumbnailMapped[cnt]) {
   4729                     ALOGI("%s:  Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd);
   4730                     register_buf(mBufferSize,
   4731                         mBufferSize, mCbCrOffset, 0,
   4732                         handle->fd,
   4733                         0,
   4734                         (uint8_t *)mThumbnailMapped[cnt],
   4735                         MSM_PMEM_THUMBNAIL,
   4736                         false, false);
   4737                      if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) {
   4738                        ALOGE("deinitraw : Error un-mmapping the thumbnail buffer %d", index);
   4739                      }
   4740                      mThumbnailBuffer[cnt] = NULL;
   4741                      mThumbnailMapped[cnt] = NULL;
   4742                 }
   4743                 ALOGI("deinitraw : display unlock");
   4744                 mDisplayLock.unlock();
   4745             }
   4746         }
   4747     }
   4748     ALOGV("deinitRaw X");
   4749 }
   4750 
   4751 void QualcommCameraHardware::relinquishBuffers()
   4752 {
   4753     status_t retVal;
   4754     ALOGV("%s: E ", __FUNCTION__);
   4755     mDisplayLock.lock();
   4756     if( mPreviewWindow != NULL) {
   4757       for(int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   4758          if (BUFFER_LOCKED == frame_buffer[cnt].lockState) {
   4759             ALOGI(" Cancelling preview buffers %d ",frames[cnt].fd);
   4760             if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
   4761                                               (*(frame_buffer[cnt].buffer)))) {
   4762                 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   4763             } else {
   4764                 frame_buffer[cnt].lockState = BUFFER_UNLOCKED;
   4765             }
   4766          }
   4767          retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   4768 	                         frame_buffer[cnt].buffer);
   4769          mPreviewMapped[cnt]->release(mPreviewMapped[cnt]);
   4770          if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   4771              struct encoder_media_buffer_type * packet =
   4772                   (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   4773              native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   4774              metadata_memory[cnt]->release(metadata_memory[cnt]);
   4775              metadata_memory[cnt] = NULL;
   4776          }
   4777          ALOGI("release preview buffers");
   4778          if(retVal != NO_ERROR)
   4779            ALOGE("%s: cancelBuffer failed for preview buffer %d ",
   4780              __FUNCTION__, frames[cnt].fd);
   4781       }
   4782     } else {
   4783       ALOGV(" PreviewWindow is null, will not cancelBuffers ");
   4784     }
   4785     mDisplayLock.unlock();
   4786     ALOGV("%s: X ", __FUNCTION__);
   4787 }
   4788 status_t QualcommCameraHardware::set_PreviewWindow(void* param)
   4789 {
   4790   ALOGV(": set_preview_window");
   4791   preview_stream_ops_t* window = (preview_stream_ops_t*)param;
   4792   return setPreviewWindow(window);
   4793 }
   4794 
   4795 status_t QualcommCameraHardware::setPreviewWindow(preview_stream_ops_t* window)
   4796 {
   4797     status_t retVal = NO_ERROR;
   4798     ALOGV(" %s: E ", __FUNCTION__);
   4799     if( window == NULL) {
   4800         ALOGW(" Setting NULL preview window ");
   4801         /* Current preview window will be invalidated.
   4802          * Release all the buffers back */
   4803         //@TODO: We may need to this to avoid leak
   4804        /*if(mPreviewWindow!=NULL)
   4805          relinquishBuffers();*/
   4806     }
   4807     ALOGI("Set preview window:: ");
   4808     mDisplayLock.lock();
   4809     mPreviewWindow = window;
   4810     mDisplayLock.unlock();
   4811 
   4812     if( (mPreviewWindow != NULL) && mCameraRunning) {
   4813         /* Initial preview in progress. Stop it and start
   4814          * the actual preview */
   4815          stopInitialPreview();
   4816          retVal = getBuffersAndStartPreview();
   4817     }
   4818     ALOGV(" %s : X ", __FUNCTION__ );
   4819     return retVal;
   4820 }
   4821 
   4822 status_t QualcommCameraHardware::getBuffersAndStartPreview() {
   4823     status_t retVal = NO_ERROR;
   4824 	int stride;
   4825     bool all_chnls = false;
   4826     ALOGI(" %s : E ", __FUNCTION__);
   4827     mFrameThreadWaitLock.lock();
   4828     while (mFrameThreadRunning) {
   4829         ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__);
   4830         mFrameThreadWait.wait(mFrameThreadWaitLock);
   4831         ALOGV("%s: old frame thread completed.",__FUNCTION__);
   4832     }
   4833     mFrameThreadWaitLock.unlock();
   4834 
   4835     if( mPreviewWindow!= NULL) {
   4836         ALOGV("%s: Calling native_window_set_buffer", __FUNCTION__);
   4837 
   4838         android_native_buffer_t *mPreviewBuffer;
   4839         int32_t previewFormat;
   4840         const char *str = mParameters.getPreviewFormat();
   4841         int numMinUndequeuedBufs = 0;
   4842 
   4843         int err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,
   4844 	    &numMinUndequeuedBufs);
   4845 
   4846         if (err != 0) {
   4847             ALOGW("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
   4848                     strerror(-err), -err);
   4849             return err;
   4850         }
   4851         mTotalPreviewBufferCount = kPreviewBufferCount + numMinUndequeuedBufs;
   4852 
   4853         previewFormat = attr_lookup(app_preview_formats,
   4854         sizeof(app_preview_formats) / sizeof(str_map), str);
   4855         if (previewFormat ==  NOT_FOUND) {
   4856           previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
   4857         }
   4858 
   4859 	    retVal = mPreviewWindow->set_buffer_count(mPreviewWindow,
   4860 	                     mTotalPreviewBufferCount +
   4861                                 (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture) ); //1);
   4862 
   4863         if(retVal != NO_ERROR) {
   4864             ALOGE("%s: Error while setting buffer count to %d ", __FUNCTION__, kPreviewBufferCount + 1);
   4865             return retVal;
   4866         }
   4867         mParameters.getPreviewSize(&previewWidth, &previewHeight);
   4868 
   4869         retVal = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
   4870 	              previewWidth, previewHeight, previewFormat);
   4871 
   4872         if(retVal != NO_ERROR) {
   4873             ALOGE("%s: Error while setting buffer geometry ", __FUNCTION__);
   4874             return retVal;
   4875         }
   4876 
   4877 #ifdef USE_ION
   4878         mPreviewWindow->set_usage (mPreviewWindow,
   4879             GRALLOC_USAGE_PRIVATE_CAMERA_HEAP |
   4880             GRALLOC_USAGE_PRIVATE_UNCACHED);
   4881 #else
   4882         mPreviewWindow->set_usage (mPreviewWindow,
   4883             GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
   4884             GRALLOC_USAGE_PRIVATE_UNCACHED);
   4885 #endif
   4886         int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4887         int cnt = 0, active = 1;
   4888         int mBufferSize = previewWidth * previewHeight * 3/2;
   4889         for (cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   4890 	            //const native_handle *nh = (native_handle *)malloc (sizeof(native_handle));
   4891 	            buffer_handle_t *bhandle =NULL;// &nh; ;
   4892 	            //buffer_handle_t *bh_handle=&handle;
   4893 	            retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   4894 	                                            &(bhandle),
   4895 	                                            &(stride));
   4896 
   4897 	        if((retVal == NO_ERROR)) {
   4898                 /* Acquire lock on the buffer if it was successfully
   4899                  * dequeued from gralloc */
   4900                 ALOGV(" Locking buffer %d ", cnt);
   4901                 retVal = mPreviewWindow->lock_buffer(mPreviewWindow,
   4902                                             bhandle);
   4903                 // lock the buffer using genlock
   4904                 if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*bhandle),
   4905                                                       GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   4906                     ALOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
   4907                     return -EINVAL;
   4908                 }
   4909                 ALOGI(" Locked buffer %d successfully", cnt);
   4910 	//yyan todo use handle to find out mPreviewBuffer
   4911 
   4912             } else {
   4913                 ALOGE("%s: dequeueBuffer failed for preview buffer. Error = %d",
   4914                       __FUNCTION__, retVal);
   4915                 return retVal;
   4916             }
   4917 			if(retVal == NO_ERROR) {
   4918                 private_handle_t *handle = (private_handle_t *)(*bhandle);//(private_handle_t *)mPreviewBuffer->handle;
   4919                 ALOGI("Handle %p, Fd passed:%d, Base:%p, Size %p",
   4920                 handle,handle->fd,handle->base,handle->size);
   4921 
   4922                 if(handle) {
   4923 
   4924                   //thumbnailHandle = (private_handle_t *)mThumbnailBuffer->handle;
   4925                   ALOGV("fd mmap fd %d size %d", handle->fd, handle->size/*thumbnailHandle->size*/);
   4926                   mPreviewMapped[cnt]= mGetMemory(handle->fd,handle->size,1,mCallbackCookie);
   4927 
   4928                   if((void *)mPreviewMapped[cnt] == NULL){
   4929                       ALOGE(" Failed to get camera memory for  Preview buffer %d ",cnt);
   4930                   }else{
   4931                       ALOGI(" Mapped Preview buffer %d", cnt);
   4932                   }
   4933                   ALOGI("Got the following from get_mem data: %p, handle :%d, release : %p, size: %d",
   4934                        mPreviewMapped[cnt]->data,
   4935                        mPreviewMapped[cnt]->handle,
   4936                        mPreviewMapped[cnt]->release,
   4937                        mPreviewMapped[cnt]->size);
   4938                   ALOGI(" getbuffersandrestartpreview deQ %d", handle->fd);
   4939                   frames[cnt].fd = handle->fd;
   4940                   frames[cnt].buffer = (unsigned int)mPreviewMapped[cnt]->data;//(unsigned int)mPreviewHeap[cnt]->mHeap->base();
   4941                   if(((void *)frames[cnt].buffer == MAP_FAILED)
   4942                      || (frames[cnt].buffer == 0)) {
   4943                       ALOGE("%s: Couldnt map preview buffers", __FUNCTION__);
   4944                       return UNKNOWN_ERROR;
   4945                   }
   4946 
   4947                   if(mPreviewFormat == CAMERA_YUV_420_YV12 && mCurrentTarget != TARGET_MSM7627A) {
   4948                     myv12_params.CbOffset = PAD_TO_WORD(previewWidth * previewHeight);
   4949                     myv12_params.CrOffset = myv12_params.CbOffset + PAD_TO_WORD((previewWidth * previewHeight)/4);
   4950                     ALOGI("CbOffset = 0x%x CrOffset = 0x%x \n",myv12_params.CbOffset, myv12_params.CrOffset);
   4951                     frames[cnt].planar0_off = 0;
   4952                     frames[cnt].planar1_off = myv12_params.CbOffset;
   4953                     frames[cnt].planar2_off = myv12_params.CrOffset;
   4954                     frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
   4955                     all_chnls = true;
   4956                   }else{
   4957                     frames[cnt].planar0_off = 0;
   4958                     frames[cnt].planar1_off= CbCrOffset;
   4959                     frames[cnt].planar2_off = 0;
   4960                     frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
   4961                   }
   4962                   frame_buffer[cnt].frame = &frames[cnt];
   4963                   frame_buffer[cnt].buffer = bhandle;
   4964                   frame_buffer[cnt].size = handle->size;
   4965                   frame_buffer[cnt].lockState = BUFFER_LOCKED;
   4966                   active = (cnt < ACTIVE_PREVIEW_BUFFERS);
   4967 
   4968                   ALOGI("Registering buffer %d with fd :%d with kernel",cnt,handle->fd);
   4969                   register_buf(mBufferSize,
   4970                              mBufferSize, CbCrOffset, 0,
   4971                              handle->fd,
   4972                              0,
   4973                              (uint8_t *)frames[cnt].buffer/*(uint8_t *)mThumbnailMapped*/,
   4974                              MSM_PMEM_PREVIEW,
   4975                              active,true,all_chnls);
   4976                   ALOGI("Came back from register call to kernel");
   4977                 } else
   4978                     ALOGE("%s: setPreviewWindow: Could not get buffer handle", __FUNCTION__);
   4979             } else {
   4980                 ALOGE("%s: lockBuffer failed for preview buffer. Error = %d",
   4981                          __FUNCTION__, retVal);
   4982                 return retVal;
   4983             }
   4984         }
   4985 
   4986 
   4987  // Dequeue Thumbnail/Postview  Buffers here , Consider ZSL/Multishot cases
   4988         for (cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   4989 
   4990             retVal = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   4991                                      &mThumbnailBuffer[cnt], &(stride));
   4992             private_handle_t* handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   4993             ALOGI(" : dequeing thumbnail buffer fd %d", handle->fd);
   4994             if(retVal != NO_ERROR) {
   4995                 ALOGE("%s: dequeueBuffer failed for postview buffer. Error = %d ",
   4996                                                             __FUNCTION__, retVal);
   4997             return retVal;
   4998             }
   4999         }
   5000 
   5001         // Cancel minUndequeuedBufs.
   5002         for (cnt = kPreviewBufferCount; cnt < mTotalPreviewBufferCount; cnt++) {
   5003             if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)(*(frame_buffer[cnt].buffer)))) {
   5004                 ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   5005                 return -EINVAL;
   5006             }
   5007             frame_buffer[cnt].lockState = BUFFER_UNLOCKED;
   5008             status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   5009                                 frame_buffer[cnt].buffer);
   5010             ALOGI(" Cancelling preview buffers %d ",frame_buffer[cnt].frame->fd);
   5011         }
   5012     } else {
   5013         ALOGE("%s: Could not get Buffer from Surface", __FUNCTION__);
   5014         return UNKNOWN_ERROR;
   5015     }
   5016     mPreviewBusyQueue.init();
   5017     LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   5018     for(int i=ACTIVE_PREVIEW_BUFFERS ;i < kPreviewBufferCount; i++)
   5019         LINK_camframe_add_frame(CAM_PREVIEW_FRAME,&frames[i]);
   5020 
   5021     mBuffersInitialized = true;
   5022 
   5023     //Starting preview now as the preview buffers are allocated
   5024  //   if(!mPreviewInitialized && !mCameraRunning) {   // TODO just for testing
   5025         ALOGI("setPreviewWindow: Starting preview after buffer allocation");
   5026         startPreviewInternal();
   5027  //   }
   5028     ALOGV(" %s : X ",__FUNCTION__);
   5029     return NO_ERROR;
   5030 }
   5031 void QualcommCameraHardware::release()
   5032 {
   5033     ALOGV("release E");
   5034     Mutex::Autolock l(&mLock);
   5035 #if 0
   5036     {
   5037         Mutex::Autolock checkLock(&singleton_lock);
   5038         if(singleton_releasing){
   5039             ALOGE("ERROR: multiple release!");
   5040             return;
   5041         }
   5042     }
   5043 #endif
   5044     ALOGI("release: mCameraRunning = %d", mCameraRunning);
   5045     if (mCameraRunning) {
   5046         if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
   5047             mRecordFrameLock.lock();
   5048             mReleasedRecordingFrame = true;
   5049             mRecordWait.signal();
   5050             mRecordFrameLock.unlock();
   5051         }
   5052         stopPreviewInternal();
   5053         ALOGI("release: stopPreviewInternal done.");
   5054     }
   5055     LINK_jpeg_encoder_join();
   5056     mm_camera_ops_type_t current_ops_type = (mSnapshotFormat
   5057             == PICTURE_FORMAT_JPEG) ? CAMERA_OPS_CAPTURE_AND_ENCODE
   5058             : CAMERA_OPS_RAW_CAPTURE;
   5059     mCamOps.mm_camera_deinit(current_ops_type, NULL, NULL);
   5060 
   5061     //Signal the snapshot thread
   5062     mJpegThreadWaitLock.lock();
   5063     mJpegThreadRunning = false;
   5064     mJpegThreadWait.signal();
   5065     mJpegThreadWaitLock.unlock();
   5066 
   5067     // Wait for snapshot thread to complete before clearing the
   5068     // resources.
   5069     mSnapshotThreadWaitLock.lock();
   5070     while (mSnapshotThreadRunning) {
   5071         ALOGV("release: waiting for old snapshot thread to complete.");
   5072         mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
   5073         ALOGV("release: old snapshot thread completed.");
   5074     }
   5075     mSnapshotThreadWaitLock.unlock();
   5076 
   5077     {
   5078         Mutex::Autolock l (&mRawPictureHeapLock);
   5079         deinitRaw();
   5080     }
   5081 
   5082     deinitRawSnapshot();
   5083     ALOGI("release: clearing resources done.");
   5084     if(mCurrentTarget == TARGET_MSM8660) {
   5085        ALOGV("release : Clearing the mThumbnailHeap and mDisplayHeap");
   5086        mLastPreviewFrameHeap.clear();
   5087        mLastPreviewFrameHeap = NULL;
   5088        mThumbnailHeap.clear();
   5089        mThumbnailHeap = NULL;
   5090        mPostviewHeap.clear();
   5091        mPostviewHeap = NULL;
   5092        mDisplayHeap.clear();
   5093        mDisplayHeap = NULL;
   5094     }
   5095     LINK_mm_camera_deinit();
   5096     if(fb_fd >= 0) {
   5097         close(fb_fd);
   5098         fb_fd = -1;
   5099     }
   5100     singleton_lock.lock();
   5101     singleton_releasing = true;
   5102     singleton_releasing_start_time = systemTime();
   5103     singleton_lock.unlock();
   5104 
   5105     ALOGI("release X: mCameraRunning = %d, mFrameThreadRunning = %d", mCameraRunning, mFrameThreadRunning);
   5106     ALOGI("mVideoThreadRunning = %d, mSnapshotThreadRunning = %d, mJpegThreadRunning = %d", mVideoThreadRunning, mSnapshotThreadRunning, mJpegThreadRunning);
   5107     ALOGI("camframe_timeout_flag = %d, mAutoFocusThreadRunning = %d", camframe_timeout_flag, mAutoFocusThreadRunning);
   5108     mFrameThreadWaitLock.lock();
   5109     while (mFrameThreadRunning) {
   5110         ALOGV("release: waiting for old frame thread to complete.");
   5111         mFrameThreadWait.wait(mFrameThreadWaitLock);
   5112         ALOGV("release: old frame thread completed.");
   5113     }
   5114     mFrameThreadWaitLock.unlock();
   5115 
   5116 }
   5117 
   5118 QualcommCameraHardware::~QualcommCameraHardware()
   5119 {
   5120     ALOGI("~QualcommCameraHardware E");
   5121 
   5122     //singleton_lock.lock();
   5123     if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660 ) {
   5124         delete [] recordframes;
   5125         recordframes = NULL;
   5126         delete [] record_buffers_tracking_flag;
   5127     }
   5128     mMMCameraDLRef.clear();
   5129     //singleton.clear();
   5130     //singleton_releasing = false;
   5131     //singleton_releasing_start_time = 0;
   5132     //singleton_wait.signal();
   5133     //singleton_lock.unlock();
   5134     ALOGI("~QualcommCameraHardware X");
   5135 }
   5136 #if 0
   5137 IMemoryHeap* QualcommCameraHardware::getRawHeap() const
   5138 {
   5139 #if 0
   5140     ALOGV("getRawHeap");
   5141     return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
   5142 #endif
   5143 }
   5144 
   5145 IMemoryHeap* QualcommCameraHardware::getPreviewHeap() const
   5146 {
   5147 #if 0
   5148     ALOGV("getPreviewHeap");
   5149     return mPreviewHeap[0] != NULL ? mPreviewHeap[0]->mHeap : NULL;
   5150     if(mIs3DModeOn != true) {
   5151         if(( mPreviewFormat == CAMERA_YUV_420_YV12 ) &&
   5152             ( mCurrentTarget == TARGET_MSM7627A || mCurrentTarget == TARGET_MSM7627 ) &&
   5153             previewWidth%32 != 0 )
   5154             return mYV12Heap->mHeap;
   5155 
   5156         return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
   5157     } else
   5158         return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL;
   5159 
   5160 #endif
   5161 }
   5162 #endif
   5163 #if 0
   5164 status_t QualcommCameraHardware::startInitialPreview() {
   5165    ALOGV(" %s : E", __FUNCTION__);
   5166    const char * pmem_region = "/dev/pmem_smipool";
   5167    int initialPreviewWidth = INITIAL_PREVIEW_WIDTH;
   5168    int initialPreviewHeight = INITIAL_PREVIEW_HEIGHT;
   5169    int previewFrameSize = initialPreviewWidth * initialPreviewHeight * 3/2;
   5170    int CbCrOffset = PAD_TO_WORD(initialPreviewWidth * initialPreviewHeight);
   5171    mFrameThreadWaitLock.lock();
   5172     while (mFrameThreadRunning) {
   5173         ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__);
   5174         mFrameThreadWait.wait(mFrameThreadWaitLock);
   5175         ALOGV("%s: old frame thread completed.",__FUNCTION__);
   5176     }
   5177     mFrameThreadWaitLock.unlock();
   5178 
   5179     mInitialPreviewHeap = new PmemPool(pmem_region,
   5180                                MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   5181                                 MSM_PMEM_PREVIEW,
   5182                                 previewFrameSize,
   5183                                 kPreviewBufferCount,
   5184                                 previewFrameSize,
   5185                                 CbCrOffset,
   5186                                 0,
   5187                                 "initial preview");
   5188 
   5189     mDimension.display_width  = initialPreviewWidth;
   5190     mDimension.display_height = initialPreviewHeight;
   5191     mDimension.video_width  = initialPreviewWidth;
   5192     mDimension.video_height = initialPreviewHeight;
   5193     mDimension.display_luma_width = initialPreviewWidth;
   5194     mDimension.display_luma_height = initialPreviewHeight;
   5195     mDimension.display_chroma_width = initialPreviewWidth;
   5196     mDimension.display_chroma_height = initialPreviewHeight;
   5197     mDimension.orig_video_width = initialPreviewWidth;
   5198     mDimension.orig_video_height = initialPreviewHeight;
   5199     ALOGV("mDimension.prev_format = %d", mDimension.prev_format);
   5200     ALOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
   5201     ALOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
   5202     ALOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
   5203     ALOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
   5204 
   5205     native_set_parms(CAMERA_PARM_DIMENSION,
   5206               sizeof(cam_ctrl_dimension_t), &mDimension);
   5207     ALOGV(" %s : mDimension.video_width = %d mDimension.video_height = %d", __FUNCTION__,
   5208              mDimension.video_width, mDimension.video_height);
   5209     mRecordFrameSize = previewFrameSize;
   5210     ALOGV("mRecordFrameSize = %d", mRecordFrameSize);
   5211 
   5212     mRecordHeap = new PmemPool(pmem_region,
   5213                                MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   5214                                MSM_PMEM_VIDEO,
   5215                                previewFrameSize,
   5216                                kRecordBufferCount,
   5217                                previewFrameSize,
   5218                                CbCrOffset,
   5219                                0,
   5220                                "initial record");
   5221 
   5222     if (!mRecordHeap->initialized()) {
   5223         mRecordHeap.clear();
   5224         ALOGE("%s X: could not initialize record heap.", __FUNCTION__);
   5225         return false;
   5226     }
   5227     {
   5228         Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5229         mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5230     }
   5231 
   5232     ALOGV(" %s : X", __FUNCTION__);
   5233     return NO_ERROR;
   5234 }
   5235 #endif
   5236 status_t QualcommCameraHardware::startPreviewInternal()
   5237 {
   5238    ALOGV("in startPreviewInternal : E");
   5239    if (!mBuffersInitialized) {
   5240      ALOGE("startPreviewInternal: Buffers not allocated. Cannot start preview");
   5241      return NO_ERROR;
   5242    }
   5243    mPreviewStopping = false;
   5244 #if 0
   5245    if(mZslEnable && !mZslPanorama){
   5246        ALOGE("start zsl Preview called");
   5247        mCamOps.mm_camera_start(CAMERA_OPS_ZSL_STREAMING_CB,NULL, NULL);
   5248        if (mCurrentTarget == TARGET_MSM8660) {
   5249            if(mLastPreviewFrameHeap != NULL)
   5250            mLastPreviewFrameHeap.clear();
   5251     }
   5252     }
   5253 #endif
   5254     if(mCameraRunning) {
   5255         ALOGV("startPreview X: preview already running.");
   5256         return NO_ERROR;
   5257     }
   5258     if(mZslEnable){
   5259          //call init
   5260          ALOGI("ZSL Enable called");
   5261          uint8_t is_zsl = 1;
   5262           mm_camera_status_t status;
   5263           if(MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_ZSL_ENABLE,
   5264                      (void *)&is_zsl)){
   5265               ALOGE("ZSL Enable failed");
   5266           return UNKNOWN_ERROR;
   5267           }
   5268     }
   5269 
   5270     if (!mPreviewInitialized) {
   5271         mLastQueuedFrame = NULL;
   5272         mPreviewInitialized = initPreview();
   5273         if (!mPreviewInitialized) {
   5274             ALOGE("startPreview X initPreview failed.  Not starting preview.");
   5275             mPreviewBusyQueue.deinit();
   5276             return UNKNOWN_ERROR;
   5277         }
   5278     }
   5279 
   5280     /* For 3D mode, start the video output, as this need to be
   5281      * used for display also.
   5282      */
   5283     if(mIs3DModeOn) {
   5284         startRecordingInternal();
   5285         if(!mVideoThreadRunning) {
   5286             ALOGE("startPreview X startRecording failed.  Not starting preview.");
   5287             return UNKNOWN_ERROR;
   5288         }
   5289     }
   5290 
   5291     {
   5292         Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5293         if(( mCurrentTarget != TARGET_MSM7630 ) &&
   5294                 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
   5295             mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL);
   5296         else {
   5297             if(!mZslEnable){
   5298                 ALOGI("Calling CAMERA_OPS_STREAMING_VIDEO");
   5299                 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5300                 ALOGI(": Calling CAMERA_OPS_STREAMING_VIDEO %d", mCameraRunning);
   5301         }else {
   5302                 initZslParameter();
   5303                  mCameraRunning = false;
   5304                  if (MM_CAMERA_SUCCESS == mCamOps.mm_camera_init(CAMERA_OPS_STREAMING_ZSL,
   5305                         (void *)&mZslParms, NULL)) {
   5306                         //register buffers for ZSL
   5307                         bool status = initZslBuffers(true);
   5308                         if(status != true) {
   5309                              ALOGE("Failed to allocate ZSL buffers");
   5310                              return false;
   5311                         }
   5312                         if(MM_CAMERA_SUCCESS == mCamOps.mm_camera_start(CAMERA_OPS_STREAMING_ZSL,NULL, NULL)){
   5313                             mCameraRunning = true;
   5314                         }
   5315                 }
   5316                 if(mCameraRunning == false)
   5317                     ALOGE("Starting  ZSL CAMERA_OPS_STREAMING_ZSL failed!!!");
   5318             }
   5319         }
   5320     }
   5321 
   5322     if(!mCameraRunning) {
   5323         deinitPreview();
   5324         if(mZslEnable){
   5325             //deinit
   5326             ALOGI("ZSL DISABLE called");
   5327            uint8_t is_zsl = 0;
   5328             mm_camera_status_t status;
   5329             if( MM_CAMERA_SUCCESS != mCfgControl.mm_camera_set_parm(CAMERA_PARM_ZSL_ENABLE,
   5330                      (void *)&is_zsl)){
   5331                 ALOGE("ZSL_Disable failed!!");
   5332                 return UNKNOWN_ERROR;
   5333             }
   5334         }
   5335         /* Flush the Busy Q */
   5336         cam_frame_flush_video();
   5337         /* Need to flush the free Qs as these are initalized in initPreview.*/
   5338         LINK_camframe_release_all_frames(CAM_VIDEO_FRAME);
   5339         LINK_camframe_release_all_frames(CAM_PREVIEW_FRAME);
   5340         mPreviewInitialized = false;
   5341         mOverlayLock.lock();
   5342         //mOverlay = NULL;
   5343         mOverlayLock.unlock();
   5344         ALOGE("startPreview X: native_start_ops: CAMERA_OPS_STREAMING_PREVIEW ioctl failed!");
   5345         return UNKNOWN_ERROR;
   5346     }
   5347 
   5348     //Reset the Gps Information
   5349     exif_table_numEntries = 0;
   5350     previewWidthToNativeZoom = previewWidth;
   5351     previewHeightToNativeZoom = previewHeight;
   5352 
   5353     ALOGV("startPreviewInternal X");
   5354     return NO_ERROR;
   5355 }
   5356 status_t QualcommCameraHardware::startInitialPreview() {
   5357    mCameraRunning = DUMMY_CAMERA_STARTED;
   5358    return NO_ERROR;
   5359 }
   5360 status_t QualcommCameraHardware::startPreview()
   5361 {
   5362   status_t result;
   5363   ALOGV("startPreview E");
   5364   Mutex::Autolock l(&mLock);
   5365   if( mPreviewWindow == NULL) {
   5366     /* startPreview has been called before setting the preview
   5367      * window. Start the camera with initial buffers because the
   5368      * CameraService expects the preview to be enabled while
   5369      * setting a valid preview window */
   5370     ALOGV(" %s : Starting preview with initial buffers ", __FUNCTION__);
   5371     result = startInitialPreview();
   5372   } else {
   5373       /* startPreview has been issued after a valid preview window
   5374        * is set. Get the preview buffers from gralloc and start
   5375        * preview normally */
   5376     ALOGV(" %s : Starting normal preview ", __FUNCTION__);
   5377     result = getBuffersAndStartPreview();
   5378   }
   5379   ALOGV("startPreview X");
   5380   return result;
   5381 }
   5382 
   5383 void QualcommCameraHardware::stopInitialPreview() {
   5384    mCameraRunning = 0;//!native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5385 #if 0
   5386     ALOGV(" %s : E ", __FUNCTION__);
   5387     if (mCameraRunning) {
   5388         ALOGV(" %s : Camera was running. Stopping ", __FUNCTION__);
   5389         {
   5390             Mutex::Autolock l(&mCamframeTimeoutLock);
   5391            {
   5392       Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5393       if(!camframe_timeout_flag) {
   5394                     mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5395                 }
   5396        }
   5397     }
   5398     mInitialPreviewHeap.clear();
   5399     mRecordHeap.clear();
   5400   }
   5401   ALOGV(" %s : X ", __FUNCTION__);
   5402 #endif
   5403 }
   5404 
   5405 void QualcommCameraHardware::stopPreviewInternal()
   5406 {
   5407     ALOGV("stopPreviewInternal E: %d", mCameraRunning);
   5408     mPreviewStopping = true;
   5409     if (mCameraRunning && mPreviewWindow!=NULL) {
   5410         /* For 3D mode, we need to exit the video thread.*/
   5411         if(mIs3DModeOn) {
   5412             mRecordingState = 0;
   5413             mVideoThreadWaitLock.lock();
   5414             ALOGI("%s: 3D mode, exit video thread", __FUNCTION__);
   5415             mVideoThreadExit = 1;
   5416             mVideoThreadWaitLock.unlock();
   5417 
   5418             pthread_mutex_lock(&(g_busy_frame_queue.mut));
   5419             pthread_cond_signal(&(g_busy_frame_queue.wait));
   5420             pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   5421         }
   5422 
   5423         // Cancel auto focus.
   5424         {
   5425             if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
   5426                 cancelAutoFocusInternal();
   5427             }
   5428         }
   5429 
   5430         // make mSmoothzoomThreadExit true
   5431         mSmoothzoomThreadLock.lock();
   5432         mSmoothzoomThreadExit = true;
   5433         mSmoothzoomThreadLock.unlock();
   5434         // singal smooth zoom thread , so that it can exit gracefully
   5435         mSmoothzoomThreadWaitLock.lock();
   5436         if(mSmoothzoomThreadRunning)
   5437             mSmoothzoomThreadWait.signal();
   5438 
   5439         mSmoothzoomThreadWaitLock.unlock();
   5440 
   5441         Mutex::Autolock l(&mCamframeTimeoutLock);
   5442         {
   5443             Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5444             if(!camframe_timeout_flag) {
   5445                 if (( mCurrentTarget != TARGET_MSM7630 ) &&
   5446                         (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
   5447                          mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL);
   5448                 else{
   5449                     if(!mZslEnable){
   5450                         ALOGI("%s ops_streaming mCameraRunning b= %d",__FUNCTION__, mCameraRunning);
   5451                         mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
   5452                         ALOGI("%s ops_streaming mCameraRunning = %d",__FUNCTION__, mCameraRunning);
   5453                     }else {
   5454                         mCameraRunning = true;
   5455                         if(MM_CAMERA_SUCCESS == mCamOps.mm_camera_stop(CAMERA_OPS_STREAMING_ZSL,NULL, NULL)){
   5456                             deinitZslBuffers();
   5457                             if (MM_CAMERA_SUCCESS == mCamOps.mm_camera_deinit(CAMERA_OPS_STREAMING_ZSL,
   5458                                     (void *)&mZslParms, NULL)) {
   5459                                 mCameraRunning = false;
   5460                             }
   5461                         }
   5462                         if(mCameraRunning ==true)
   5463                             ALOGE("Starting  ZSL CAMERA_OPS_STREAMING_ZSL failed!!!");
   5464                     }
   5465                 }
   5466             } else {
   5467                 /* This means that the camframetimeout was issued.
   5468                  * But we did not issue native_stop_preview(), so we
   5469                  * need to update mCameraRunning to indicate that
   5470                  * Camera is no longer running. */
   5471                 ALOGE("%s, : MAKE MCAMER_RUNNING FALSE!!!",__FUNCTION__);
   5472                 mCameraRunning = 0;
   5473             }
   5474         }
   5475     }
   5476     /* in 3D mode, wait for the video thread before clearing resources.*/
   5477     if(mIs3DModeOn) {
   5478         mVideoThreadWaitLock.lock();
   5479         while (mVideoThreadRunning) {
   5480             ALOGI("%s: waiting for video thread to complete.", __FUNCTION__);
   5481             mVideoThreadWait.wait(mVideoThreadWaitLock);
   5482             ALOGI("%s : video thread completed.", __FUNCTION__);
   5483         }
   5484         mVideoThreadWaitLock.unlock();
   5485     }
   5486     ALOGI("%s, J_mCameraRunning = %d", __FUNCTION__, mCameraRunning);
   5487     if (!mCameraRunning) {
   5488         ALOGI("%s, before calling deinitpre mPreviewInitialized = %d", __FUNCTION__, mPreviewInitialized);
   5489         if(mPreviewInitialized) {
   5490             ALOGI("before calling deinitpreview");
   5491             deinitPreview();
   5492             if( ( mCurrentTarget == TARGET_MSM7630 ) ||
   5493                 (mCurrentTarget == TARGET_QSD8250) ||
   5494                 (mCurrentTarget == TARGET_MSM8660)) {
   5495                 mVideoThreadWaitLock.lock();
   5496                 ALOGV("in stopPreviewInternal: making mVideoThreadExit 1");
   5497                 mVideoThreadExit = 1;
   5498                 mVideoThreadWaitLock.unlock();
   5499                 //720p : signal the video thread , and check in video thread
   5500                 //if stop is called, if so exit video thread.
   5501                 pthread_mutex_lock(&(g_busy_frame_queue.mut));
   5502                 pthread_cond_signal(&(g_busy_frame_queue.wait));
   5503                 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   5504 
   5505                 ALOGI(" flush video and release all frames");
   5506                 /* Flush the Busy Q */
   5507                 cam_frame_flush_video();
   5508                 /* Flush the Free Q */
   5509                 LINK_camframe_release_all_frames(CAM_VIDEO_FRAME);
   5510             }
   5511             mPreviewInitialized = false;
   5512         }
   5513     }
   5514     else ALOGI("stopPreviewInternal: Preview is stopped already");
   5515 
   5516     ALOGV("stopPreviewInternal X: %d", mCameraRunning);
   5517 }
   5518 
   5519 void QualcommCameraHardware::stopPreview()
   5520 {
   5521     ALOGV("stopPreview: E");
   5522     Mutex::Autolock l(&mLock);
   5523     {
   5524         if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
   5525             return;
   5526     }
   5527     if( mSnapshotThreadRunning ) {
   5528         ALOGV("In stopPreview during snapshot");
   5529         return;
   5530     }
   5531     if( mPreviewWindow != NULL ) {
   5532         private_handle_t *handle;
   5533         for (int cnt = 0; cnt < (mZslEnable? (MAX_SNAPSHOT_BUFFERS-2) : numCapture); cnt++) {
   5534             if(mPreviewWindow != NULL && mThumbnailBuffer[cnt] != NULL) {
   5535                 handle = (private_handle_t *)(*mThumbnailBuffer[cnt]);
   5536                 ALOGI("%s:  Cancelling postview buffer %d ", __FUNCTION__, handle->fd);
   5537                 ALOGI("stoppreview : display lock");
   5538                 mDisplayLock.lock();
   5539                 if (BUFFER_LOCKED == mThumbnailLockState[cnt]) {
   5540                     if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   5541                        ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   5542                        mDisplayLock.unlock();
   5543                        continue;
   5544                     } else {
   5545                        mThumbnailLockState[cnt] = BUFFER_UNLOCKED;
   5546                     }
   5547                 }
   5548                 status_t retVal = mPreviewWindow->cancel_buffer(mPreviewWindow,
   5549                                                               mThumbnailBuffer[cnt]);
   5550                 ALOGI("stopPreview : after cancelling thumbnail buffer");
   5551                 if(retVal != NO_ERROR)
   5552                     ALOGE("%s: cancelBuffer failed for postview buffer %d",
   5553                                                      __FUNCTION__, handle->fd);
   5554                 // unregister , unmap and release as well
   5555                 int mBufferSize = previewWidth * previewHeight * 3/2;
   5556                 int mCbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
   5557                 if(mThumbnailMapped[cnt]  && (mSnapshotFormat == PICTURE_FORMAT_JPEG)
   5558                           || mZslEnable) {
   5559                     ALOGI("%s:  Unregistering Thumbnail Buffer %d ", __FUNCTION__, handle->fd);
   5560                     register_buf(mBufferSize,
   5561                         mBufferSize, mCbCrOffset, 0,
   5562                         handle->fd,
   5563                         0,
   5564                         (uint8_t *)mThumbnailMapped[cnt],
   5565                         MSM_PMEM_THUMBNAIL,
   5566                         false, false);
   5567                     if (munmap((void *)(mThumbnailMapped[cnt]),handle->size ) == -1) {
   5568                       ALOGE("StopPreview : Error un-mmapping the thumbnail buffer %d", index);
   5569                     }
   5570                     mThumbnailMapped[cnt] = NULL;
   5571                  }
   5572                 mThumbnailBuffer[cnt] = NULL;
   5573                 ALOGI("stoppreview : display unlock");
   5574                 mDisplayLock.unlock();
   5575           }
   5576        }
   5577     }
   5578     stopPreviewInternal();
   5579     ALOGV("stopPreview: X");
   5580 }
   5581 
   5582 void QualcommCameraHardware::runAutoFocus()
   5583 {
   5584     bool status = true;
   5585     void *libhandle = NULL;
   5586     isp3a_af_mode_t afMode = AF_MODE_AUTO;
   5587 
   5588     mAutoFocusThreadLock.lock();
   5589     // Skip autofocus if focus mode is infinity.
   5590 
   5591     const char * focusMode = mParameters.get(QCameraParameters::KEY_FOCUS_MODE);
   5592     if ((mParameters.get(QCameraParameters::KEY_FOCUS_MODE) == 0)
   5593            || (strcmp(focusMode, QCameraParameters::FOCUS_MODE_INFINITY) == 0)
   5594            || (strcmp(focusMode, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0)) {
   5595         goto done;
   5596     }
   5597 
   5598     if(!libmmcamera){
   5599         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   5600         mAutoFocusThreadRunning = false;
   5601         mAutoFocusThreadLock.unlock();
   5602         return;
   5603     }
   5604 
   5605     afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
   5606                                 sizeof(focus_modes) / sizeof(str_map),
   5607                                 mParameters.get(QCameraParameters::KEY_FOCUS_MODE));
   5608 
   5609     /* This will block until either AF completes or is cancelled. */
   5610     ALOGV("af start (mode %d)", afMode);
   5611     status_t err;
   5612     err = mAfLock.tryLock();
   5613     if(err == NO_ERROR) {
   5614         {
   5615             Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
   5616             if(mCameraRunning){
   5617                 ALOGV("Start AF");
   5618                 status =  native_start_ops(CAMERA_OPS_FOCUS ,(void *)&afMode);
   5619             }else{
   5620                 ALOGV("As Camera preview is not running, AF not issued");
   5621                 status = false;
   5622             }
   5623         }
   5624         mAfLock.unlock();
   5625     }
   5626     else{
   5627         //AF Cancel would have acquired the lock,
   5628         //so, no need to perform any AF
   5629         ALOGV("As Cancel auto focus is in progress, auto focus request "
   5630                 "is ignored");
   5631         status = FALSE;
   5632     }
   5633     {
   5634         Mutex::Autolock pl(&mParametersLock);
   5635         if(mHasAutoFocusSupport && (updateFocusDistances(focusMode) != NO_ERROR)) {
   5636             ALOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, focusMode);
   5637         }
   5638     }
   5639 
   5640     ALOGV("af done: %d", (int)status);
   5641 
   5642 done:
   5643     mAutoFocusThreadRunning = false;
   5644     mAutoFocusThreadLock.unlock();
   5645 
   5646     mCallbackLock.lock();
   5647     bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
   5648     camera_notify_callback cb = mNotifyCallback;
   5649     void *data = mCallbackCookie;
   5650     mCallbackLock.unlock();
   5651     if (autoFocusEnabled)
   5652         cb(CAMERA_MSG_FOCUS, status, 0, data);
   5653 
   5654 }
   5655 
   5656 status_t QualcommCameraHardware::cancelAutoFocusInternal()
   5657 {
   5658     ALOGV("cancelAutoFocusInternal E");
   5659     bool afRunning = true;
   5660 
   5661     if(!mHasAutoFocusSupport){
   5662         ALOGV("cancelAutoFocusInternal X");
   5663         return NO_ERROR;
   5664     }
   5665 
   5666     status_t rc = NO_ERROR;
   5667     status_t err;
   5668 
   5669     do {
   5670       err = mAfLock.tryLock();
   5671       if(err == NO_ERROR) {
   5672           //Got Lock, means either AF hasn't started or
   5673           // AF is done. So no need to cancel it, just change the state
   5674           ALOGV("Auto Focus is not in progress, Cancel Auto Focus is ignored");
   5675           mAfLock.unlock();
   5676 
   5677           mAutoFocusThreadLock.lock();
   5678           afRunning = mAutoFocusThreadRunning;
   5679           mAutoFocusThreadLock.unlock();
   5680           if(afRunning) {
   5681             usleep( 5000 );
   5682           }
   5683       }
   5684     } while ( err == NO_ERROR && afRunning );
   5685     if(afRunning) {
   5686         //AF is in Progess, So cancel it
   5687         ALOGV("Lock busy...cancel AF");
   5688         rc = native_stop_ops(CAMERA_OPS_FOCUS, NULL) ?
   5689           NO_ERROR : UNKNOWN_ERROR;
   5690 
   5691         /*now just wait for auto focus thread to be finished*/
   5692         mAutoFocusThreadLock.lock();
   5693         mAutoFocusThreadLock.unlock();
   5694     }
   5695     ALOGV("cancelAutoFocusInternal X: %d", rc);
   5696     return rc;
   5697 }
   5698 
   5699 void *auto_focus_thread(void *user)
   5700 {
   5701     ALOGV("auto_focus_thread E");
   5702     CAMERA_HAL_UNUSED(user);
   5703     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   5704     if (obj != 0) {
   5705         obj->runAutoFocus();
   5706     }
   5707     else ALOGW("not starting autofocus: the object went away!");
   5708     ALOGV("auto_focus_thread X");
   5709     return NULL;
   5710 }
   5711 
   5712 status_t QualcommCameraHardware::autoFocus()
   5713 {
   5714     ALOGV("autoFocus E");
   5715     Mutex::Autolock l(&mLock);
   5716 
   5717     if(!mHasAutoFocusSupport){
   5718        /*
   5719         * If autofocus is not supported HAL defaults
   5720         * focus mode to infinity and supported mode to
   5721         * infinity also. In this mode and fixed mode app
   5722         * should not call auto focus.
   5723         */
   5724         ALOGI("Auto Focus not supported");
   5725         ALOGV("autoFocus X");
   5726         return INVALID_OPERATION;
   5727     }
   5728     {
   5729         mAutoFocusThreadLock.lock();
   5730         if (!mAutoFocusThreadRunning) {
   5731 
   5732             // Create a detached thread here so that we don't have to wait
   5733             // for it when we cancel AF.
   5734             pthread_t thr;
   5735             pthread_attr_t attr;
   5736             pthread_attr_init(&attr);
   5737             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   5738             mAutoFocusThreadRunning =
   5739                 !pthread_create(&thr, &attr,
   5740                                 auto_focus_thread, NULL);
   5741             if (!mAutoFocusThreadRunning) {
   5742                 ALOGE("failed to start autofocus thread");
   5743                 mAutoFocusThreadLock.unlock();
   5744                 return UNKNOWN_ERROR;
   5745             }
   5746         }
   5747         mAutoFocusThreadLock.unlock();
   5748     }
   5749 
   5750     ALOGV("autoFocus X");
   5751     return NO_ERROR;
   5752 }
   5753 
   5754 status_t QualcommCameraHardware::cancelAutoFocus()
   5755 {
   5756     ALOGV("cancelAutoFocus E");
   5757     Mutex::Autolock l(&mLock);
   5758 
   5759     int rc = NO_ERROR;
   5760     if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
   5761         rc = cancelAutoFocusInternal();
   5762     }
   5763 
   5764     ALOGV("cancelAutoFocus X");
   5765     return rc;
   5766 }
   5767 
   5768 void QualcommCameraHardware::runSnapshotThread(void *data)
   5769 {
   5770     bool ret = true;
   5771     CAMERA_HAL_UNUSED(data);
   5772     ALOGI("runSnapshotThread E");
   5773 
   5774     if(!libmmcamera){
   5775         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   5776     }
   5777     mSnapshotCancelLock.lock();
   5778     if(mSnapshotCancel == true) {
   5779         mSnapshotCancel = false;
   5780         mSnapshotCancelLock.unlock();
   5781         ALOGI("%s: cancelpicture has been called..so abort taking snapshot", __FUNCTION__);
   5782         deinitRaw();
   5783         mInSnapshotModeWaitLock.lock();
   5784         mInSnapshotMode = false;
   5785         mInSnapshotModeWait.signal();
   5786         mInSnapshotModeWaitLock.unlock();
   5787         mSnapshotThreadWaitLock.lock();
   5788         mSnapshotThreadRunning = false;
   5789         mSnapshotThreadWait.signal();
   5790         mSnapshotThreadWaitLock.unlock();
   5791         return;
   5792     }
   5793     mSnapshotCancelLock.unlock();
   5794 
   5795     mJpegThreadWaitLock.lock();
   5796     mJpegThreadRunning = true;
   5797     mJpegThreadWait.signal();
   5798     mJpegThreadWaitLock.unlock();
   5799     mm_camera_ops_type_t current_ops_type = (mSnapshotFormat == PICTURE_FORMAT_JPEG) ?
   5800                                              CAMERA_OPS_CAPTURE_AND_ENCODE :
   5801                                               CAMERA_OPS_RAW_CAPTURE;
   5802     if(strTexturesOn == true) {
   5803         current_ops_type = CAMERA_OPS_CAPTURE;
   5804         mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms,
   5805                          NULL);
   5806     } else if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
   5807         if(!mZslEnable || mZslFlashEnable){
   5808             mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms,
   5809                  (void *)&mImageEncodeParms);
   5810             }else{
   5811                 notifyShutter(TRUE);
   5812                 initZslParameter();
   5813                 ALOGI("snapshot mZslCapture.thumbnail %d %d %d",mZslCaptureParms.thumbnail_width,
   5814                                      mZslCaptureParms.thumbnail_height,mZslCaptureParms.num_captures);
   5815                 mCamOps.mm_camera_start(current_ops_type,(void *)&mZslCaptureParms,
   5816                       (void *)&mImageEncodeParms);
   5817            }
   5818         mJpegThreadWaitLock.lock();
   5819         while (mJpegThreadRunning) {
   5820             ALOGV("%s: waiting for jpeg callback.", __FUNCTION__);
   5821             mJpegThreadWait.wait(mJpegThreadWaitLock);
   5822             ALOGV("%s: jpeg callback received.", __FUNCTION__);
   5823         }
   5824         mJpegThreadWaitLock.unlock();
   5825 
   5826         //cleanup
   5827        if(!mZslEnable || mZslFlashEnable)
   5828             deinitRaw();
   5829     }else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
   5830         notifyShutter(TRUE);
   5831         mCamOps.mm_camera_start(current_ops_type,(void *)&mRawCaptureParms,
   5832                                  NULL);
   5833         // Waiting for callback to come
   5834         ALOGV("runSnapshotThread : waiting for callback to come");
   5835         mJpegThreadWaitLock.lock();
   5836         while (mJpegThreadRunning) {
   5837             ALOGV("%s: waiting for jpeg callback.", __FUNCTION__);
   5838             mJpegThreadWait.wait(mJpegThreadWaitLock);
   5839             ALOGV("%s: jpeg callback received.", __FUNCTION__);
   5840         }
   5841         mJpegThreadWaitLock.unlock();
   5842         ALOGV("runSnapshotThread : calling deinitRawSnapshot");
   5843         deinitRawSnapshot();
   5844 
   5845     }
   5846 
   5847     if(!mZslEnable || mZslFlashEnable)
   5848         mCamOps.mm_camera_deinit(current_ops_type, NULL, NULL);
   5849     mZslFlashEnable  = false;
   5850     mSnapshotThreadWaitLock.lock();
   5851     mSnapshotThreadRunning = false;
   5852     mSnapshotThreadWait.signal();
   5853     mSnapshotThreadWaitLock.unlock();
   5854     ALOGV("runSnapshotThread X");
   5855 }
   5856 
   5857 void *snapshot_thread(void *user)
   5858 {
   5859     ALOGD("snapshot_thread E");
   5860     CAMERA_HAL_UNUSED(user);
   5861     QualcommCameraHardware *obj = QualcommCameraHardware::getInstance();
   5862     if (obj != 0) {
   5863         obj->runSnapshotThread(user);
   5864     }
   5865     else ALOGW("not starting snapshot thread: the object went away!");
   5866     ALOGD("snapshot_thread X");
   5867     return NULL;
   5868 }
   5869 
   5870 status_t QualcommCameraHardware::takePicture()
   5871 {
   5872     ALOGE("takePicture(%d)", mMsgEnabled);
   5873     Mutex::Autolock l(&mLock);
   5874     if(mRecordingState ) {
   5875       return takeLiveSnapshotInternal( );
   5876     }
   5877 
   5878     if(strTexturesOn == true){
   5879         mEncodePendingWaitLock.lock();
   5880         while(mEncodePending) {
   5881             ALOGI("takePicture: Frame given to application, waiting for encode call");
   5882             mEncodePendingWait.wait(mEncodePendingWaitLock);
   5883             ALOGI("takePicture: Encode of the application data is done");
   5884         }
   5885         mEncodePendingWaitLock.unlock();
   5886     }
   5887 
   5888     // Wait for old snapshot thread to complete.
   5889     mSnapshotThreadWaitLock.lock();
   5890     while (mSnapshotThreadRunning) {
   5891         ALOGV("takePicture: waiting for old snapshot thread to complete.");
   5892         mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
   5893         ALOGV("takePicture: old snapshot thread completed.");
   5894     }
   5895     // if flash is enabled then run snapshot as normal mode and not zsl mode.
   5896     // App should expect only 1 callback as multi snapshot in normal mode is not supported
   5897     mZslFlashEnable = false;
   5898     if(mZslEnable){
   5899         int is_flash_needed = 0;
   5900         mm_camera_status_t status;
   5901         status = mCfgControl.mm_camera_get_parm(CAMERA_PARM_QUERY_FALSH4SNAP,
   5902                       (void *)&is_flash_needed);
   5903         if(is_flash_needed) {
   5904             mZslFlashEnable = true;
   5905         }
   5906     }
   5907     //Adding ExifTag for Flash
   5908     const char *flash_str = mParameters.get(QCameraParameters::KEY_FLASH_MODE);
   5909     if(flash_str){
   5910         int is_flash_fired = 0;
   5911         if(mCfgControl.mm_camera_get_parm(CAMERA_PARM_QUERY_FALSH4SNAP,
   5912                       (void *)&is_flash_fired) != MM_CAMERA_SUCCESS){
   5913             flashMode = FLASH_SNAP ; //for No Flash support,bit 5 will be 1
   5914         } else {
   5915             if(!strcmp(flash_str,"on"))
   5916                 flashMode = 1;
   5917 
   5918             if(!strcmp(flash_str,"off"))
   5919                 flashMode = 0;
   5920 
   5921             if(!strcmp(flash_str,"auto")){
   5922                 //for AUTO bits 3 and 4 will be 1
   5923                 //for flash fired bit 0 will be 1, else 0
   5924                 flashMode  = FLASH_AUTO;
   5925                 if(is_flash_fired)
   5926                    flashMode = (is_flash_fired>>1) | flashMode ;
   5927             }
   5928         }
   5929         addExifTag(EXIFTAGID_FLASH,EXIF_SHORT,1,1,(void *)&flashMode);
   5930     }
   5931 
   5932     if(mParameters.getPictureFormat() != 0 &&
   5933             !strcmp(mParameters.getPictureFormat(),
   5934                     QCameraParameters::PIXEL_FORMAT_RAW)){
   5935         mSnapshotFormat = PICTURE_FORMAT_RAW;
   5936       {
   5937        // HACK: Raw ZSL capture is not supported yet
   5938         mZslFlashEnable = true;
   5939       }
   5940     }
   5941     else
   5942         mSnapshotFormat = PICTURE_FORMAT_JPEG;
   5943 
   5944     if(!mZslEnable || mZslFlashEnable){
   5945         if((mSnapshotFormat == PICTURE_FORMAT_JPEG)){
   5946             if(!native_start_ops(CAMERA_OPS_PREPARE_SNAPSHOT, NULL)) {
   5947                 mSnapshotThreadWaitLock.unlock();
   5948                 ALOGE("PREPARE SNAPSHOT: CAMERA_OPS_PREPARE_SNAPSHOT ioctl Failed");
   5949                 return UNKNOWN_ERROR;
   5950             }
   5951         }
   5952     }
   5953     else {
   5954         int rotation = mParameters.getInt("rotation");
   5955         native_set_parms(CAMERA_PARM_JPEG_ROTATION, sizeof(int), &rotation);
   5956     }
   5957 #if 0    // TODO for ICS
   5958     if(mCurrentTarget == TARGET_MSM8660) {
   5959        /* Store the last frame queued for preview. This
   5960         * shall be used as postview */
   5961         if (!(storePreviewFrameForPostview()))
   5962         return UNKNOWN_ERROR;
   5963     }
   5964 #endif
   5965     if(!mZslEnable || mZslFlashEnable)
   5966         stopPreviewInternal();
   5967 #if 0
   5968     else if(mZslEnable && !mZslPanorama) {
   5969         /* Dont stop preview if ZSL Panorama is enabled for
   5970          * Continuous viewfinder support*/
   5971         ALOGE("Calling stop preview");
   5972         mCamOps.mm_camera_stop(CAMERA_OPS_ZSL_STREAMING_CB,NULL, NULL);
   5973     }
   5974 #endif
   5975 
   5976 
   5977     mFrameThreadWaitLock.unlock();
   5978 
   5979     mm_camera_ops_type_t current_ops_type = (mSnapshotFormat == PICTURE_FORMAT_JPEG) ?
   5980                                              CAMERA_OPS_CAPTURE_AND_ENCODE :
   5981                                               CAMERA_OPS_RAW_CAPTURE;
   5982     if(strTexturesOn == true)
   5983         current_ops_type = CAMERA_OPS_CAPTURE;
   5984 
   5985     if( !mZslEnable || mZslFlashEnable)
   5986         mCamOps.mm_camera_init(current_ops_type, NULL, NULL);
   5987 
   5988     if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
   5989       if(!mZslEnable || mZslFlashEnable) {
   5990         if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
   5991           ALOGE("initRaw failed.  Not taking picture.");
   5992           mSnapshotThreadWaitLock.unlock();
   5993           return UNKNOWN_ERROR;
   5994         }
   5995       }
   5996     } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
   5997         if(!initRawSnapshot()){
   5998             ALOGE("initRawSnapshot failed. Not taking picture.");
   5999             mSnapshotThreadWaitLock.unlock();
   6000             return UNKNOWN_ERROR;
   6001         }
   6002     }
   6003 
   6004     mShutterLock.lock();
   6005     mShutterPending = true;
   6006     mShutterLock.unlock();
   6007 
   6008     mSnapshotCancelLock.lock();
   6009     mSnapshotCancel = false;
   6010     mSnapshotCancelLock.unlock();
   6011 
   6012     numJpegReceived = 0;
   6013     pthread_attr_t attr;
   6014     pthread_attr_init(&attr);
   6015     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   6016     mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
   6017                                              &attr,
   6018                                              snapshot_thread,
   6019                                              NULL);
   6020     mSnapshotThreadWaitLock.unlock();
   6021 
   6022     mInSnapshotModeWaitLock.lock();
   6023     mInSnapshotMode = true;
   6024     mInSnapshotModeWaitLock.unlock();
   6025 
   6026     ALOGV("takePicture: X");
   6027     return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
   6028 }
   6029 
   6030 void QualcommCameraHardware::set_liveshot_exifinfo()
   6031 {
   6032 
   6033     setGpsParameters();
   6034     //set TimeStamp
   6035     const char *str = mParameters.get(QCameraParameters::KEY_EXIF_DATETIME);
   6036     if(str != NULL) {
   6037         strncpy(dateTime, str, 19);
   6038         dateTime[19] = '\0';
   6039         addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
   6040                    20, 1, (void *)dateTime);
   6041     }
   6042 }
   6043 
   6044 
   6045 status_t QualcommCameraHardware::takeLiveSnapshotInternal()
   6046 {
   6047     ALOGV("takeLiveSnapshotInternal : E");
   6048     if(liveshot_state == LIVESHOT_IN_PROGRESS || !mRecordingState) {
   6049         return NO_ERROR;
   6050     }
   6051 
   6052     if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660) && (mCurrentTarget != TARGET_MSM7627A)) {
   6053         ALOGI("LiveSnapshot not supported on this target");
   6054         liveshot_state = LIVESHOT_STOPPED;
   6055         return NO_ERROR;
   6056     }
   6057 
   6058     liveshot_state = LIVESHOT_IN_PROGRESS;
   6059 
   6060     if (!initLiveSnapshot(videoWidth, videoHeight)) {
   6061         ALOGE("takeLiveSnapshot: Jpeg Heap Memory allocation failed.  Not taking Live Snapshot.");
   6062         liveshot_state = LIVESHOT_STOPPED;
   6063         return UNKNOWN_ERROR;
   6064     }
   6065     uint32_t maxjpegsize = videoWidth * videoHeight *1.5;
   6066     set_liveshot_exifinfo();
   6067     if(!LINK_set_liveshot_params(videoWidth, videoHeight,
   6068                                 exif_data, exif_table_numEntries,
   6069       (uint8_t *)mJpegLiveSnapMapped->data, maxjpegsize)) {
   6070         ALOGE("Link_set_liveshot_params failed.");
   6071         if (NULL != mJpegLiveSnapMapped) {
   6072               ALOGV("initLiveSnapshot: clearing old mJpegHeap.");
   6073               mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   6074               mJpegLiveSnapMapped = NULL;
   6075         }
   6076         return NO_ERROR;
   6077     }
   6078       if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) {
   6079           if(!native_start_ops(CAMERA_OPS_LIVESHOT, NULL)) {
   6080             ALOGE("start_liveshot ioctl failed");
   6081             liveshot_state = LIVESHOT_STOPPED;
   6082             if (NULL != mJpegLiveSnapMapped) {
   6083               ALOGV("initLiveSnapshot: clearing old mJpegHeap.");
   6084               mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   6085               mJpegLiveSnapMapped = NULL;
   6086             }
   6087             return UNKNOWN_ERROR;
   6088           }
   6089       }
   6090 
   6091     ALOGV("takeLiveSnapshotInternal: X");
   6092     return NO_ERROR;
   6093 }
   6094 
   6095 status_t QualcommCameraHardware::takeLiveSnapshot()
   6096 {
   6097   ALOGV("takeLiveSnapshot: E ");
   6098   Mutex::Autolock l(&mLock);
   6099   ALOGV("takeLiveSnapshot: X ");
   6100   return takeLiveSnapshotInternal( );
   6101 }
   6102 
   6103 bool QualcommCameraHardware::initLiveSnapshot(int videowidth, int videoheight)
   6104 {
   6105     ALOGV("initLiveSnapshot E");
   6106 
   6107     if (NULL != mJpegLiveSnapMapped) {
   6108         ALOGV("initLiveSnapshot: clearing old mJpegHeap.");
   6109         mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   6110         mJpegLiveSnapMapped = NULL;
   6111     }
   6112 
   6113     mJpegMaxSize = videowidth * videoheight * 1.5;
   6114     ALOGV("initLiveSnapshot: initializing mJpegHeap.");
   6115     mJpegLiveSnapMapped = mGetMemory(-1, mJpegMaxSize,1,mCallbackCookie);
   6116     if(mJpegLiveSnapMapped == NULL) {
   6117         ALOGE("Failed to get camera memory for mJpegLibeSnapMapped" );
   6118         return false;
   6119     }
   6120     ALOGV("initLiveSnapshot X");
   6121     return true;
   6122 }
   6123 
   6124 
   6125 status_t QualcommCameraHardware::cancelPicture()
   6126 {
   6127     status_t rc;
   6128     ALOGV("cancelPicture: E");
   6129 
   6130     mSnapshotCancelLock.lock();
   6131     ALOGI("%s: setting mSnapshotCancel to true", __FUNCTION__);
   6132     mSnapshotCancel = true;
   6133     mSnapshotCancelLock.unlock();
   6134 
   6135     if (mCurrentTarget == TARGET_MSM7627 ||
   6136        (mCurrentTarget == TARGET_MSM7625A ||
   6137         mCurrentTarget == TARGET_MSM7627A)) {
   6138         mSnapshotDone = TRUE;
   6139         mSnapshotThreadWaitLock.lock();
   6140         while (mSnapshotThreadRunning) {
   6141             ALOGV("cancelPicture: waiting for snapshot thread to complete.");
   6142             mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
   6143             ALOGV("cancelPicture: snapshot thread completed.");
   6144         }
   6145         mSnapshotThreadWaitLock.unlock();
   6146     }
   6147     rc = native_stop_ops(CAMERA_OPS_CAPTURE, NULL) ? NO_ERROR : UNKNOWN_ERROR;
   6148     mSnapshotDone = FALSE;
   6149     ALOGV("cancelPicture: X: %d", rc);
   6150     return rc;
   6151 }
   6152 
   6153 status_t QualcommCameraHardware::setParameters(const QCameraParameters& params)
   6154 {
   6155     ALOGV("setParameters: E params = %p", &params);
   6156 
   6157     Mutex::Autolock l(&mLock);
   6158     Mutex::Autolock pl(&mParametersLock);
   6159     status_t rc, final_rc = NO_ERROR;
   6160     if (mSnapshotThreadRunning) {
   6161         if ((rc = setCameraMode(params)))  final_rc = rc;
   6162         if ((rc = setPreviewSize(params)))  final_rc = rc;
   6163         if ((rc = setRecordSize(params)))  final_rc = rc;
   6164         if ((rc = setPictureSize(params)))  final_rc = rc;
   6165         if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
   6166         if ((rc = setJpegQuality(params)))  final_rc = rc;
   6167         return final_rc;
   6168     }
   6169     if ((rc = setCameraMode(params)))  final_rc = rc;
   6170     if ((rc = setPreviewSize(params)))  final_rc = rc;
   6171     if ((rc = setRecordSize(params)))  final_rc = rc;
   6172     if ((rc = setPictureSize(params)))  final_rc = rc;
   6173     if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
   6174     if ((rc = setJpegQuality(params)))  final_rc = rc;
   6175 	if ((rc = setPictureFormat(params))) final_rc = rc;
   6176 	if ((rc = setRecordSize(params)))  final_rc = rc;
   6177 	if ((rc = setPreviewFormat(params)))   final_rc = rc;
   6178     if ((rc = setEffect(params)))       final_rc = rc;
   6179     if ((rc = setGpsLocation(params)))  final_rc = rc;
   6180     if ((rc = setRotation(params)))     final_rc = rc;
   6181     if ((rc = setZoom(params)))         final_rc = rc;
   6182     if ((rc = setOrientation(params)))  final_rc = rc;
   6183     if ((rc = setLensshadeValue(params)))  final_rc = rc;
   6184     if ((rc = setMCEValue(params)))  final_rc = rc;
   6185     //if ((rc = setHDRImaging(params)))  final_rc = rc;
   6186     if ((rc = setExpBracketing(params)))  final_rc = rc;
   6187     if ((rc = setPictureFormat(params))) final_rc = rc;
   6188     if ((rc = setSharpness(params)))    final_rc = rc;
   6189     if ((rc = setSaturation(params)))   final_rc = rc;
   6190     if ((rc = setTouchAfAec(params)))   final_rc = rc;
   6191     if ((rc = setSceneMode(params)))    final_rc = rc;
   6192     if ((rc = setContrast(params)))     final_rc = rc;
   6193     if ((rc = setRecordSize(params)))  final_rc = rc;
   6194     if ((rc = setSceneDetect(params)))  final_rc = rc;
   6195     if ((rc = setStrTextures(params)))   final_rc = rc;
   6196     if ((rc = setPreviewFormat(params)))   final_rc = rc;
   6197     if ((rc = setSkinToneEnhancement(params)))   final_rc = rc;
   6198     if ((rc = setAntibanding(params)))  final_rc = rc;
   6199     if ((rc = setRedeyeReduction(params)))  final_rc = rc;
   6200     if ((rc = setDenoise(params)))  final_rc = rc;
   6201     if ((rc = setPreviewFpsRange(params)))  final_rc = rc;
   6202     if ((rc = setZslParam(params)))  final_rc = rc;
   6203     if ((rc = setSnapshotCount(params)))  final_rc = rc;
   6204     if((rc = setRecordingHint(params)))   final_rc = rc;
   6205     const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
   6206     int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
   6207 
   6208     if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF)) {
   6209         if ((rc = setPreviewFrameRate(params))) final_rc = rc;
   6210     //    if ((rc = setPreviewFrameRateMode(params))) final_rc = rc;
   6211         if ((rc = setAutoExposure(params))) final_rc = rc;
   6212         if ((rc = setExposureCompensation(params))) final_rc = rc;
   6213         if ((rc = setWhiteBalance(params))) final_rc = rc;
   6214         if ((rc = setFlash(params)))        final_rc = rc;
   6215         if ((rc = setFocusMode(params)))    final_rc = rc;
   6216         if ((rc = setBrightness(params)))   final_rc = rc;
   6217         if ((rc = setISOValue(params)))  final_rc = rc;
   6218         if ((rc = setFocusAreas(params)))  final_rc = rc;
   6219         if ((rc = setMeteringAreas(params)))  final_rc = rc;
   6220     }
   6221     //selectableZoneAF needs to be invoked after continuous AF
   6222     if ((rc = setSelectableZoneAf(params)))   final_rc = rc;
   6223     // setHighFrameRate needs to be done at end, as there can
   6224     // be a preview restart, and need to use the updated parameters
   6225     if ((rc = setHighFrameRate(params)))  final_rc = rc;
   6226 
   6227     ALOGV("setParameters: X");
   6228     return final_rc;
   6229 }
   6230 
   6231 QCameraParameters QualcommCameraHardware::getParameters() const
   6232 {
   6233     ALOGV("getParameters: EX");
   6234     return mParameters;
   6235 }
   6236 status_t QualcommCameraHardware::setHistogramOn()
   6237 {
   6238     ALOGV("setHistogramOn: EX");
   6239     mStatsWaitLock.lock();
   6240     mSendData = true;
   6241     if(mStatsOn == CAMERA_HISTOGRAM_ENABLE) {
   6242         mStatsWaitLock.unlock();
   6243         return NO_ERROR;
   6244      }
   6245 #if 0
   6246     if (mStatHeap != NULL) {
   6247         ALOGV("setHistogram on: clearing old mStatHeap.");
   6248         mStatHeap.clear();
   6249     }
   6250 #endif
   6251 
   6252     mStatSize = sizeof(uint32_t)* HISTOGRAM_STATS_SIZE;
   6253     mCurrent = -1;
   6254     /*Currently the Ashmem is multiplying the buffer size with total number
   6255     of buffers and page aligning. This causes a crash in JNI as each buffer
   6256     individually expected to be page aligned  */
   6257     int page_size_minus_1 = getpagesize() - 1;
   6258     int32_t mAlignedStatSize = ((mStatSize + page_size_minus_1) & (~page_size_minus_1));
   6259 #if 0
   6260     mStatHeap =
   6261             new AshmemPool(mAlignedStatSize,
   6262                            3,
   6263                            mStatSize,
   6264                            "stat");
   6265       if (!mStatHeap->initialized()) {
   6266           ALOGE("Stat Heap X failed ");
   6267           mStatHeap.clear();
   6268           ALOGE("setHistogramOn X: error initializing mStatHeap");
   6269           mStatsWaitLock.unlock();
   6270           return UNKNOWN_ERROR;
   6271       }
   6272 #endif
   6273     for(int cnt = 0; cnt<3; cnt++) {
   6274             mStatsMapped[cnt]=mGetMemory(-1, mStatSize,1,mCallbackCookie);
   6275             if(mStatsMapped[cnt] == NULL) {
   6276                 ALOGE("Failed to get camera memory for stats heap index: %d", cnt);
   6277                 mStatsWaitLock.unlock();
   6278                 return false;
   6279             }else{
   6280                ALOGV("Received following info for stats mapped data:%p,handle:%p, size:%d,release:%p",
   6281                mStatsMapped[cnt]->data ,mStatsMapped[cnt]->handle, mStatsMapped[cnt]->size, mStatsMapped[cnt]->release);
   6282             }
   6283     }
   6284     mStatsOn = CAMERA_HISTOGRAM_ENABLE;
   6285     mStatsWaitLock.unlock();
   6286     mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn);
   6287     return NO_ERROR;
   6288 }
   6289 
   6290 status_t QualcommCameraHardware::setHistogramOff()
   6291 {
   6292     ALOGV("setHistogramOff: EX");
   6293     mStatsWaitLock.lock();
   6294     if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) {
   6295     mStatsWaitLock.unlock();
   6296         return NO_ERROR;
   6297      }
   6298     mStatsOn = CAMERA_HISTOGRAM_DISABLE;
   6299     mStatsWaitLock.unlock();
   6300 
   6301     mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn);
   6302 
   6303     mStatsWaitLock.lock();
   6304 //    mStatHeap.clear();
   6305     for(int i=0; i<3; i++){
   6306         if(mStatsMapped[i] != NULL){
   6307             mStatsMapped[i]->release(mStatsMapped[i]);
   6308             mStatsMapped[i] = NULL;
   6309         }
   6310     }
   6311 
   6312     mStatsWaitLock.unlock();
   6313     return NO_ERROR;
   6314 }
   6315 
   6316 
   6317 status_t QualcommCameraHardware::runFaceDetection()
   6318 {
   6319     bool ret = true;
   6320 #if 0
   6321     const char *str = mParameters.get(QCameraParameters::KEY_FACE_DETECTION);
   6322     if (str != NULL) {
   6323         int value = attr_lookup(facedetection,
   6324                 sizeof(facedetection) / sizeof(str_map), str);
   6325 
   6326         mMetaDataWaitLock.lock();
   6327         if (value == true) {
   6328             if(mMetaDataHeap != NULL)
   6329                 mMetaDataHeap.clear();
   6330 
   6331             mMetaDataHeap =
   6332                 new AshmemPool((sizeof(int)*(MAX_ROI*4+1)),
   6333                         1,
   6334                         (sizeof(int)*(MAX_ROI*4+1)),
   6335                         "metadata");
   6336             if (!mMetaDataHeap->initialized()) {
   6337                 ALOGE("Meta Data Heap allocation failed ");
   6338                 mMetaDataHeap.clear();
   6339                 ALOGE("runFaceDetection X: error initializing mMetaDataHeap");
   6340                 mMetaDataWaitLock.unlock();
   6341                 return UNKNOWN_ERROR;
   6342             }
   6343             mSendMetaData = true;
   6344         } else {
   6345             if(mMetaDataHeap != NULL)
   6346                 mMetaDataHeap.clear();
   6347         }
   6348         mMetaDataWaitLock.unlock();
   6349         ret = native_set_parms(CAMERA_PARM_FD, sizeof(int8_t), (void *)&value);
   6350         return ret ? NO_ERROR : UNKNOWN_ERROR;
   6351     }
   6352     ALOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
   6353  #endif
   6354 	return BAD_VALUE;
   6355 }
   6356 
   6357 void* smoothzoom_thread(void* user)
   6358 {
   6359     // call runsmoothzoomthread
   6360     ALOGV("smoothzoom_thread E");
   6361     CAMERA_HAL_UNUSED(user);
   6362 
   6363     QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   6364     if (obj != 0) {
   6365         obj->runSmoothzoomThread(user);
   6366     }
   6367     else ALOGE("not starting smooth zoom thread: the object went away!");
   6368     ALOGV("Smoothzoom_thread X");
   6369     return NULL;
   6370 }
   6371 
   6372 status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
   6373                                              int32_t arg2)
   6374 {
   6375     ALOGV("sendCommand: EX");
   6376     CAMERA_HAL_UNUSED(arg1);
   6377     CAMERA_HAL_UNUSED(arg2);
   6378     Mutex::Autolock l(&mLock);
   6379 
   6380     switch(command)  {
   6381       case CAMERA_CMD_HISTOGRAM_ON:
   6382                                    ALOGV("histogram set to on");
   6383                                    return setHistogramOn();
   6384       case CAMERA_CMD_HISTOGRAM_OFF:
   6385                                    ALOGV("histogram set to off");
   6386                                    return setHistogramOff();
   6387       case CAMERA_CMD_HISTOGRAM_SEND_DATA:
   6388                                    mStatsWaitLock.lock();
   6389                                    if(mStatsOn == CAMERA_HISTOGRAM_ENABLE)
   6390                                        mSendData = true;
   6391                                    mStatsWaitLock.unlock();
   6392                                    return NO_ERROR;
   6393 #if 0
   6394       case CAMERA_CMD_FACE_DETECTION_ON:
   6395                                    if(supportsFaceDetection() == false){
   6396                                         ALOGI("face detection support is not available");
   6397                                         return NO_ERROR;
   6398                                    }
   6399 
   6400                                    setFaceDetection("on");
   6401                                    return runFaceDetection();
   6402       case CAMERA_CMD_FACE_DETECTION_OFF:
   6403                                    if(supportsFaceDetection() == false){
   6404                                         ALOGI("face detection support is not available");
   6405                                         return NO_ERROR;
   6406                                    }
   6407                                    setFaceDetection("off");
   6408                                    return runFaceDetection();
   6409       case CAMERA_CMD_SEND_META_DATA:
   6410                                    mMetaDataWaitLock.lock();
   6411                                    if(mFaceDetectOn == true) {
   6412                                        mSendMetaData = true;
   6413                                    }
   6414                                    mMetaDataWaitLock.unlock();
   6415                                    return NO_ERROR;
   6416       case CAMERA_CMD_START_SMOOTH_ZOOM :
   6417              ALOGV("HAL sendcmd start smooth zoom %d %d", arg1 , arg2);
   6418              mTargetSmoothZoom = arg1;
   6419              if(!mPreviewStopping) {
   6420                  // create smooth zoom thread
   6421                  mSmoothzoomThreadLock.lock();
   6422                  mSmoothzoomThreadExit = false;
   6423                  pthread_attr_t attr;
   6424                  pthread_attr_init(&attr);
   6425                  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   6426                  pthread_create(&mSmoothzoomThread,
   6427                                     &attr,
   6428                                     smoothzoom_thread,
   6429                                     NULL);
   6430                  mSmoothzoomThreadLock.unlock();
   6431              } else
   6432                  ALOGV(" Not creating smooth zoom thread "
   6433                       " since preview is stopping ");
   6434              mTargetSmoothZoom = arg1;
   6435              return NO_ERROR;
   6436 
   6437       case CAMERA_CMD_STOP_SMOOTH_ZOOM :
   6438              mSmoothzoomThreadLock.lock();
   6439              mSmoothzoomThreadExit = true;
   6440              mSmoothzoomThreadLock.unlock();
   6441              ALOGV("HAL sendcmd stop smooth zoom");
   6442              return NO_ERROR;
   6443 #endif
   6444    }
   6445    return BAD_VALUE;
   6446 }
   6447 
   6448 void QualcommCameraHardware::runSmoothzoomThread(void * data) {
   6449 
   6450     ALOGV("runSmoothzoomThread: Current zoom %d - "
   6451           "Target %d", mParameters.getInt("zoom"), mTargetSmoothZoom);
   6452     int current_zoom = mParameters.getInt("zoom");
   6453     int step = (current_zoom > mTargetSmoothZoom)? -1: 1;
   6454 
   6455     if(current_zoom == mTargetSmoothZoom) {
   6456         ALOGV("Smoothzoom target zoom value is same as "
   6457              "current zoom value, return...");
   6458         if(!mPreviewStopping)
   6459             mNotifyCallback(CAMERA_MSG_ZOOM,
   6460                 current_zoom, 1, mCallbackCookie);
   6461         else
   6462             ALOGV("Not issuing callback since preview is stopping");
   6463         return;
   6464     }
   6465 
   6466     QCameraParameters p = getParameters();
   6467 
   6468     mSmoothzoomThreadWaitLock.lock();
   6469     mSmoothzoomThreadRunning = true;
   6470     mSmoothzoomThreadWaitLock.unlock();
   6471 
   6472     int i = current_zoom;
   6473     while(1) {  // Thread loop
   6474         mSmoothzoomThreadLock.lock();
   6475         if(mSmoothzoomThreadExit) {
   6476             ALOGV("Exiting smoothzoom thread, as stop smoothzoom called");
   6477             mSmoothzoomThreadLock.unlock();
   6478             break;
   6479         }
   6480         mSmoothzoomThreadLock.unlock();
   6481 
   6482         if((i < 0) || (i > mMaxZoom)) {
   6483             ALOGE(" ERROR : beyond supported zoom values, break..");
   6484             break;
   6485         }
   6486         // update zoom
   6487         p.set("zoom", i);
   6488         setZoom(p);
   6489         if(!mPreviewStopping) {
   6490             // give call back to zoom listener in app
   6491             mNotifyCallback(CAMERA_MSG_ZOOM, i, (mTargetSmoothZoom-i == 0)?1:0,
   6492                     mCallbackCookie);
   6493         } else {
   6494             ALOGV("Preview is stopping. Breaking out of smooth zoom loop");
   6495             break;
   6496         }
   6497         if(i == mTargetSmoothZoom)
   6498             break;
   6499 
   6500         i+=step;
   6501 
   6502         /* wait on singal, which will be signalled on
   6503          * receiving next preview frame */
   6504         mSmoothzoomThreadWaitLock.lock();
   6505         mSmoothzoomThreadWait.wait(mSmoothzoomThreadWaitLock);
   6506         mSmoothzoomThreadWaitLock.unlock();
   6507     } // while loop over, exiting thread
   6508 
   6509     mSmoothzoomThreadWaitLock.lock();
   6510     mSmoothzoomThreadRunning = false;
   6511     mSmoothzoomThreadWaitLock.unlock();
   6512     ALOGV("Exiting Smooth Zoom Thread");
   6513 }
   6514 
   6515 extern "C" QualcommCameraHardware* HAL_openCameraHardware(int cameraId)
   6516 {
   6517     int i;
   6518     ALOGI("openCameraHardware: call createInstance");
   6519     for(i = 0; i < HAL_numOfCameras; i++) {
   6520         if(i == cameraId) {
   6521             ALOGI("openCameraHardware:Valid camera ID %d", cameraId);
   6522             parameter_string_initialized = false;
   6523             HAL_currentCameraId = cameraId;
   6524             /* The least significant two bits of mode parameter indicates the sensor mode
   6525                of 2D or 3D. The next two bits indicates the snapshot mode of
   6526                ZSL or NONZSL
   6527                */
   6528 #if 0
   6529             int sensorModeMask = 0x03 & mode;
   6530             if(sensorModeMask & HAL_cameraInfo[i].modes_supported){
   6531                 HAL_currentCameraMode = sensorModeMask;
   6532             }else{
   6533                 ALOGE("openCameraHardware:Invalid camera mode (%d) requested", mode);
   6534                 return NULL;
   6535             }
   6536 #endif
   6537             HAL_currentCameraMode = CAMERA_MODE_2D;
   6538             HAL_currentSnapshotMode = CAMERA_SNAPSHOT_NONZSL;
   6539             //Remove values set by app other than  supported values
   6540             //mode = mode & HAL_cameraInfo[cameraId].modes_supported;
   6541             //if((mode & CAMERA_SNAPSHOT_ZSL) == CAMERA_SNAPSHOT_ZSL)
   6542               //  HAL_currentSnapshotMode = CAMERA_SNAPSHOT_ZSL;
   6543             ALOGI("%s: HAL_currentSnapshotMode = %d HAL_currentCameraMode = %d", __FUNCTION__, HAL_currentSnapshotMode,
   6544                  HAL_currentCameraMode);
   6545             return QualcommCameraHardware::createInstance();
   6546         }
   6547     }
   6548     ALOGE("openCameraHardware:Invalid camera ID %d", cameraId);
   6549     return NULL;
   6550 }
   6551 
   6552 //wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
   6553 
   6554 // If the hardware already exists, return a strong pointer to the current
   6555 // object. If not, create a new hardware object, put it in the singleton,
   6556 // and return it.
   6557 QualcommCameraHardware* QualcommCameraHardware::createInstance()
   6558 {
   6559     ALOGV("createInstance: E");
   6560 #if 0
   6561     singleton_lock.lock();
   6562 
   6563     // Wait until the previous release is done.
   6564     while (singleton_releasing) {
   6565         if((singleton_releasing_start_time != 0) &&
   6566                 (systemTime() - singleton_releasing_start_time) > SINGLETON_RELEASING_WAIT_TIME){
   6567             ALOGV("in createinstance system time is %lld %lld %lld ",
   6568                     systemTime(), singleton_releasing_start_time, SINGLETON_RELEASING_WAIT_TIME);
   6569             singleton_lock.unlock();
   6570             ALOGE("Previous singleton is busy and time out exceeded. Returning null");
   6571             return NULL;
   6572         }
   6573         ALOGI("Wait for previous release.");
   6574         singleton_wait.waitRelative(singleton_lock, SINGLETON_RELEASING_RECHECK_TIMEOUT);
   6575         ALOGI("out of Wait for previous release.");
   6576     }
   6577 
   6578     if (singleton != 0) {
   6579         sp<CameraHardwareInterface> hardware = singleton.promote();
   6580         if (hardware != 0) {
   6581             ALOGD("createInstance: X return existing hardware=%p", &(*hardware));
   6582             singleton_lock.unlock();
   6583             return hardware;
   6584         }
   6585     }
   6586 #endif
   6587     {
   6588         struct stat st;
   6589         int rc = stat("/dev/oncrpc", &st);
   6590         if (rc < 0) {
   6591             ALOGD("createInstance: X failed to create hardware: %s", strerror(errno));
   6592             singleton_lock.unlock();
   6593             return NULL;
   6594         }
   6595     }
   6596 
   6597     QualcommCameraHardware *cam = new QualcommCameraHardware();
   6598     hardware=cam;
   6599 
   6600 
   6601     ALOGI("createInstance: created hardware=%p", cam);
   6602     if (!cam->startCamera()) {
   6603         ALOGE("%s: startCamera failed!", __FUNCTION__);
   6604         //singleton_lock.unlock();
   6605         delete cam;
   6606         return NULL;
   6607     }
   6608 
   6609     cam->initDefaultParameters();
   6610     //singleton_lock.unlock();
   6611     ALOGV("createInstance: X");
   6612     return cam;
   6613 }
   6614 
   6615 // For internal use only, hence the strong pointer to the derived type.
   6616 QualcommCameraHardware* QualcommCameraHardware::getInstance()
   6617 {
   6618     //QualcommCameraHardware* hardware = singleton.promote();
   6619     if (hardware != 0) {
   6620         //    ALOGV("getInstance: X old instance of hardware");
   6621       //  return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
   6622 	  return hardware;
   6623     } else {
   6624         ALOGV("getInstance: X new instance of hardware");
   6625         return new QualcommCameraHardware();
   6626     }
   6627 }
   6628 void QualcommCameraHardware::receiveRecordingFrame(struct msm_frame *frame)
   6629 {
   6630     ALOGV("receiveRecordingFrame E");
   6631     // post busy frame
   6632     if (frame)
   6633     {
   6634         cam_frame_post_video (frame);
   6635     }
   6636     else ALOGE("in  receiveRecordingFrame frame is NULL");
   6637     ALOGV("receiveRecordingFrame X");
   6638 }
   6639 
   6640 
   6641 bool QualcommCameraHardware::native_zoom_image(int fd, int srcOffset, int dstOffSet, common_crop_t *crop)
   6642 {
   6643     int result = 0;
   6644     struct mdp_blit_req *e;
   6645 
   6646     /* Initialize yuv structure */
   6647     zoomImage.list.count = 1;
   6648 
   6649     e = &zoomImage.list.req[0];
   6650 
   6651     e->src.width = previewWidth;
   6652     e->src.height = previewHeight;
   6653     e->src.format = MDP_Y_CBCR_H2V2;
   6654     e->src.offset = srcOffset;
   6655     e->src.memory_id = fd;
   6656 
   6657     e->dst.width = previewWidth;
   6658     e->dst.height = previewHeight;
   6659     e->dst.format = MDP_Y_CBCR_H2V2;
   6660     e->dst.offset = dstOffSet;
   6661     e->dst.memory_id = fd;
   6662 
   6663     e->transp_mask = 0xffffffff;
   6664     e->flags = 0;
   6665     e->alpha = 0xff;
   6666     if (crop->in1_w != 0 && crop->in1_h != 0) {
   6667         e->src_rect.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
   6668         e->src_rect.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
   6669         e->src_rect.w = crop->in1_w;
   6670         e->src_rect.h = crop->in1_h;
   6671     } else {
   6672         e->src_rect.x = 0;
   6673         e->src_rect.y = 0;
   6674         e->src_rect.w = previewWidth;
   6675         e->src_rect.h = previewHeight;
   6676     }
   6677     //ALOGV(" native_zoom : SRC_RECT : x,y = %d,%d \t w,h = %d, %d",
   6678     //        e->src_rect.x, e->src_rect.y, e->src_rect.w, e->src_rect.h);
   6679 
   6680     e->dst_rect.x = 0;
   6681     e->dst_rect.y = 0;
   6682     e->dst_rect.w = previewWidth;
   6683     e->dst_rect.h = previewHeight;
   6684 
   6685     result = ioctl(fb_fd, MSMFB_BLIT, &zoomImage.list);
   6686     if (result < 0) {
   6687         ALOGE("MSM_FBIOBLT failed! line=%d\n", __LINE__);
   6688         return FALSE;
   6689     }
   6690     return TRUE;
   6691 }
   6692 
   6693 void QualcommCameraHardware::debugShowPreviewFPS() const
   6694 {
   6695     static int mFrameCount;
   6696     static int mLastFrameCount = 0;
   6697     static nsecs_t mLastFpsTime = 0;
   6698     static float mFps = 0;
   6699     mFrameCount++;
   6700     nsecs_t now = systemTime();
   6701     nsecs_t diff = now - mLastFpsTime;
   6702     if (diff > ms2ns(250)) {
   6703         mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
   6704         ALOGI("Preview Frames Per Second: %.4f", mFps);
   6705         mLastFpsTime = now;
   6706         mLastFrameCount = mFrameCount;
   6707     }
   6708 }
   6709 
   6710 void QualcommCameraHardware::debugShowVideoFPS() const
   6711 {
   6712     static int mFrameCount;
   6713     static int mLastFrameCount = 0;
   6714     static nsecs_t mLastFpsTime = 0;
   6715     static float mFps = 0;
   6716     mFrameCount++;
   6717     nsecs_t now = systemTime();
   6718     nsecs_t diff = now - mLastFpsTime;
   6719     if (diff > ms2ns(250)) {
   6720         mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
   6721         ALOGI("Video Frames Per Second: %.4f", mFps);
   6722         mLastFpsTime = now;
   6723         mLastFrameCount = mFrameCount;
   6724     }
   6725 }
   6726 
   6727 void QualcommCameraHardware::receiveLiveSnapshot(uint32_t jpeg_size)
   6728 {
   6729     ALOGV("receiveLiveSnapshot E");
   6730 #if DUMP_LIVESHOT_JPEG_FILE
   6731     int file_fd = open("/data/LiveSnapshot.jpg", O_RDWR | O_CREAT, 0777);
   6732     ALOGV("dumping live shot image in /data/LiveSnapshot.jpg");
   6733     if (file_fd < 0) {
   6734         ALOGE("cannot open file\n");
   6735     }
   6736     else
   6737     {
   6738         write(file_fd, (uint8_t *)mJpegLiveSnapMapped->data,jpeg_size);
   6739     }
   6740     close(file_fd);
   6741 #endif
   6742     Mutex::Autolock cbLock(&mCallbackLock);
   6743     if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
   6744           mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mJpegLiveSnapMapped ,data_counter,
   6745                           NULL, mCallbackCookie);
   6746 
   6747     }
   6748     else ALOGV("JPEG callback was cancelled--not delivering image.");
   6749 
   6750     //Reset the Gps Information & relieve memory
   6751     exif_table_numEntries = 0;
   6752     mJpegHeap.clear();
   6753 
   6754     liveshot_state = LIVESHOT_DONE;
   6755 
   6756     ALOGV("receiveLiveSnapshot X");
   6757 }
   6758 void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
   6759 {
   6760     ALOGV("receivePreviewFrame E");
   6761     if (!mCameraRunning) {
   6762         ALOGI("ignoring preview callback--camera has been stopped");
   6763         LINK_camframe_add_frame(CAM_PREVIEW_FRAME,frame);
   6764         return;
   6765     }
   6766     if((mCurrentTarget == TARGET_MSM7627A) && ( liveshot_state == LIVESHOT_IN_PROGRESS)) {
   6767         LINK_set_liveshot_frame(frame);
   6768     }
   6769     if(mPreviewBusyQueue.add(frame) == false)
   6770         LINK_camframe_add_frame(CAM_PREVIEW_FRAME,frame);
   6771 
   6772 
   6773     ALOGV("receivePreviewFrame X");
   6774 }
   6775 void QualcommCameraHardware::receiveCameraStats(camstats_type stype, camera_preview_histogram_info* histinfo)
   6776 {
   6777   //  ALOGV("receiveCameraStats E");
   6778     CAMERA_HAL_UNUSED(stype);
   6779 
   6780     if (!mCameraRunning) {
   6781         ALOGE("ignoring stats callback--camera has been stopped");
   6782         return;
   6783     }
   6784 
   6785     mCallbackLock.lock();
   6786     int msgEnabled = mMsgEnabled;
   6787     camera_data_callback scb = mDataCallback;
   6788     void *sdata = mCallbackCookie;
   6789     mCallbackLock.unlock();
   6790     mStatsWaitLock.lock();
   6791     if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) {
   6792       mStatsWaitLock.unlock();
   6793       return;
   6794     }
   6795     if(!mSendData) {
   6796         mStatsWaitLock.unlock();
   6797      } else {
   6798         mSendData = false;
   6799         mCurrent = (mCurrent+1)%3;
   6800     // The first element of the array will contain the maximum hist value provided by driver.
   6801     //    *(uint32_t *)((unsigned int)mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)) = histinfo->max_value;
   6802     //    memcpy((uint32_t *)((unsigned int)mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)+ sizeof(int32_t)), (uint32_t *)histinfo->buffer,(sizeof(int32_t) * 256));
   6803         *(uint32_t *)((unsigned int)(mStatsMapped[mCurrent]->data)) = histinfo->max_value;
   6804         memcpy((uint32_t *)((unsigned int)mStatsMapped[mCurrent]->data + sizeof(int32_t)), (uint32_t *)histinfo->buffer,(sizeof(int32_t) * 256));
   6805 
   6806         mStatsWaitLock.unlock();
   6807 
   6808         if (scb != NULL && (msgEnabled & CAMERA_MSG_STATS_DATA))
   6809             scb(CAMERA_MSG_STATS_DATA, mStatsMapped[mCurrent], data_counter, NULL,sdata);
   6810 
   6811      }
   6812   //  ALOGV("receiveCameraStats X");
   6813 }
   6814 /*===========================================================================
   6815  * FUNCTION    - do_mmap -
   6816  *
   6817  * DESCRIPTION:  retured virtual addresss
   6818  *==========================================================================*/
   6819 uint8_t *mm_camera_do_mmap(uint32_t size, int *pmemFd)
   6820 {
   6821     void *ret; /* returned virtual address */
   6822     int pmem_fd;
   6823 
   6824     if(mCurrentTarget == TARGET_MSM8660)
   6825         pmem_fd = open("/dev/pmem_smipool", O_RDWR|O_SYNC);
   6826     else
   6827         pmem_fd = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
   6828     if (pmem_fd <= 0) {
   6829         ALOGE("do_mmap: Open device /dev/pmem_smipool failed!\n");
   6830         return NULL;
   6831     }
   6832     /* to make it page size aligned */
   6833     size = (size + 4095) & (~4095);
   6834   ret = mmap(NULL,
   6835     size,
   6836     PROT_READ  | PROT_WRITE,
   6837     MAP_SHARED,
   6838     pmem_fd,
   6839     0);
   6840     if (ret == MAP_FAILED) {
   6841         ALOGE("do_mmap: pmem mmap() failed: %s (%d)\n", strerror(errno), errno);
   6842         close(pmem_fd);
   6843         return NULL;
   6844     }
   6845     ALOGI("do_mmap: pmem mmap fd %d ptr %p len %u\n", pmem_fd, ret, size);
   6846     *pmemFd = pmem_fd;
   6847     return(uint8_t *)ret;
   6848 }
   6849 
   6850 
   6851 bool QualcommCameraHardware::initRecord()
   6852 {
   6853     const char *pmem_region;
   6854     int ion_heap = ION_CP_MM_HEAP_ID;
   6855     int CbCrOffset;
   6856     int recordBufferSize;
   6857 	int active, type =0;
   6858 
   6859     ALOGV("initREcord E");
   6860     if(mZslEnable){
   6861        ALOGV("initRecord X.. Not intializing Record buffers in ZSL mode");
   6862        return true;
   6863     }
   6864 
   6865     if(mCurrentTarget == TARGET_MSM8660) {
   6866         pmem_region = "/dev/pmem_smipool";
   6867     } else {
   6868         pmem_region = "/dev/pmem_adsp";
   6869     }
   6870 
   6871     ALOGI("initRecord: mDimension.video_width = %d mDimension.video_height = %d",
   6872              mDimension.video_width, mDimension.video_height);
   6873     // for 8x60 the Encoder expects the CbCr offset should be aligned to 2K.
   6874     if(mCurrentTarget == TARGET_MSM8660) {
   6875         CbCrOffset = PAD_TO_2K(mDimension.video_width  * mDimension.video_height);
   6876         recordBufferSize = CbCrOffset + PAD_TO_2K((mDimension.video_width * mDimension.video_height)/2);
   6877     } else {
   6878         CbCrOffset = PAD_TO_WORD(mDimension.video_width  * mDimension.video_height);
   6879         recordBufferSize = (mDimension.video_width  * mDimension.video_height *3)/2;
   6880     }
   6881 
   6882     /* Buffersize and frameSize will be different when DIS is ON.
   6883      * We need to pass the actual framesize with video heap, as the same
   6884      * is used at camera MIO when negotiating with encoder.
   6885      */
   6886     mRecordFrameSize = PAD_TO_4K(recordBufferSize);
   6887     bool dis_disable = 0;
   6888     const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
   6889     if((str != NULL) && (strcmp(str, QCameraParameters::VIDEO_HFR_OFF))) {
   6890         ALOGI("%s: HFR is ON, DIS has to be OFF", __FUNCTION__);
   6891         dis_disable = 1;
   6892     }
   6893     if((mVpeEnabled && mDisEnabled && (!dis_disable))|| mIs3DModeOn){
   6894         mRecordFrameSize = videoWidth * videoHeight * 3 / 2;
   6895         if(mCurrentTarget == TARGET_MSM8660){
   6896             mRecordFrameSize = PAD_TO_4K(PAD_TO_2K(videoWidth * videoHeight)
   6897                                 + PAD_TO_2K((videoWidth * videoHeight)/2));
   6898         }
   6899     }
   6900     ALOGV("mRecordFrameSize = %d", mRecordFrameSize);
   6901     //if(mRecordHeap == NULL) {
   6902     #if 0
   6903 #ifdef USE_ION
   6904         mRecordHeap = new IonPool(ion_heap,
   6905                                 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   6906                                 MSM_PMEM_VIDEO,
   6907                                 recordBufferSize,
   6908                                 kRecordBufferCount,
   6909                                 mRecordFrameSize,
   6910                                 CbCrOffset,
   6911                                 0,
   6912                                 "record");
   6913 #endif
   6914 
   6915         mRecordHeap = new PmemPool(pmem_region,
   6916                                MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   6917                                 MSM_PMEM_VIDEO,
   6918                                 recordBufferSize,
   6919                                 kRecordBufferCount,
   6920                                 mRecordFrameSize,
   6921                                 CbCrOffset,
   6922                                 0,
   6923                                 "record");
   6924 
   6925         if (!mRecordHeap->initialized()) {
   6926             mRecordHeap.clear();
   6927             mRecordHeap = NULL;
   6928             ALOGE("initRecord X: could not initialize record heap.");
   6929             return false;
   6930         }
   6931 
   6932     } else {
   6933         if(mHFRMode == true) {
   6934             ALOGI("%s: register record buffers with camera driver", __FUNCTION__);
   6935             register_record_buffers(true);
   6936             mHFRMode = false;
   6937         }
   6938     }
   6939 #endif
   6940 
   6941     for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   6942 #if 0
   6943        //recordframes[cnt].fd = mRecordHeap->mHeap->getHeapID();
   6944        recordframes[cnt].buffer = (unsigned long)mm_camera_do_mmap(mRecordFrameSize, &(recordframes[cnt].fd));
   6945            //(uint32_t)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
   6946        if(!recordframes[cnt].buffer)
   6947        {
   6948          ALOGE("Buffer allocation for record fram %d failed",cnt);
   6949          return false;
   6950        }
   6951 #endif
   6952 #ifdef USE_ION
   6953     if (allocate_ion_memory(&record_main_ion_fd[cnt], &record_alloc[cnt], &record_ion_info_fd[cnt],
   6954                             ion_heap, mRecordFrameSize, &mRecordfd[cnt]) < 0){
   6955       ALOGE("do_mmap: Open device %s failed!\n",pmem_region);
   6956       return NULL;
   6957     }
   6958 #else
   6959     mRecordfd[cnt] = open(pmem_region, O_RDWR|O_SYNC);
   6960     if (mRecordfd[cnt] <= 0) {
   6961         ALOGE("%s: Open device %s failed!\n",__func__, pmem_region);
   6962 	        return NULL;
   6963     }
   6964 #endif
   6965     ALOGI("%s  Record fd is %d ", __func__, mRecordfd[cnt]);
   6966         mRecordMapped[cnt]=mGetMemory(mRecordfd[cnt], mRecordFrameSize,1,mCallbackCookie);
   6967         if(mRecordMapped[cnt]==NULL) {
   6968             ALOGE("Failed to get camera memory for mRecordMapped heap");
   6969         }else{
   6970         ALOGI("Received following info for record mapped data:%p,handle:%p, size:%d,release:%p",
   6971            mRecordMapped[cnt]->data ,mRecordMapped[cnt]->handle, mRecordMapped[cnt]->size, mRecordMapped[cnt]->release);
   6972         }
   6973 #if 1
   6974         recordframes[cnt].buffer = (unsigned int)mRecordMapped[cnt]->data;
   6975         recordframes[cnt].fd = mRecordfd[cnt];
   6976 #endif
   6977         recordframes[cnt].planar0_off = 0;
   6978         recordframes[cnt].planar1_off = CbCrOffset;
   6979         recordframes[cnt].planar2_off = 0;
   6980         recordframes[cnt].path = OUTPUT_TYPE_V;
   6981         record_buffers_tracking_flag[cnt] = false;
   6982         ALOGV ("initRecord :  record heap , video buffers  buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
   6983           (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].planar0_off,
   6984           recordframes[cnt].planar1_off);
   6985         active=(cnt<ACTIVE_VIDEO_BUFFERS);
   6986         type = MSM_PMEM_VIDEO;
   6987         if((mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
   6988             type = MSM_PMEM_VIDEO_VPE;
   6989             active = 1;
   6990         }
   6991         ALOGI("Registering buffer %d with kernel",cnt);
   6992                   register_buf(mRecordFrameSize,
   6993                              mRecordFrameSize, CbCrOffset, 0,
   6994                              recordframes[cnt].fd,
   6995                              0,
   6996                              (uint8_t *)recordframes[cnt].buffer,
   6997                              type,
   6998                              active);
   6999                   ALOGI("Came back from register call to kernel");
   7000     }
   7001 
   7002     // initial setup : buffers 1,2,3 with kernel , 4 with camframe , 5,6,7,8 in free Q
   7003     // flush the busy Q
   7004     cam_frame_flush_video();
   7005 
   7006     mVideoThreadWaitLock.lock();
   7007     while (mVideoThreadRunning) {
   7008         ALOGV("initRecord: waiting for old video thread to complete.");
   7009         mVideoThreadWait.wait(mVideoThreadWaitLock);
   7010         ALOGV("initRecord : old video thread completed.");
   7011     }
   7012     mVideoThreadWaitLock.unlock();
   7013 
   7014     // flush free queue and add 5,6,7,8 buffers.
   7015     LINK_camframe_release_all_frames(CAM_VIDEO_FRAME);
   7016     if(mVpeEnabled) {
   7017         //If VPE is enabled, the VPE buffer shouldn't be added to Free Q initally.
   7018         for(int i=ACTIVE_VIDEO_BUFFERS;i <kRecordBufferCount-1; i++)
   7019             LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[i]);
   7020     } else {
   7021         for(int i=ACTIVE_VIDEO_BUFFERS;i <kRecordBufferCount; i++)
   7022             LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[i]);
   7023     }
   7024     ALOGV("initREcord X");
   7025 
   7026     return true;
   7027 }
   7028 
   7029 
   7030 status_t QualcommCameraHardware::setDIS() {
   7031     ALOGV("setDIS E");
   7032 
   7033     video_dis_param_ctrl_t disCtrl;
   7034     bool ret = true;
   7035     ALOGV("mDisEnabled = %d", mDisEnabled);
   7036 
   7037     int video_frame_cbcroffset;
   7038     video_frame_cbcroffset = PAD_TO_WORD(videoWidth * videoHeight);
   7039     if(mCurrentTarget == TARGET_MSM8660)
   7040         video_frame_cbcroffset = PAD_TO_2K(videoWidth * videoHeight);
   7041 
   7042     disCtrl.dis_enable = mDisEnabled;
   7043     const char *str = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
   7044     if((str != NULL) && (strcmp(str, QCameraParameters::VIDEO_HFR_OFF))) {
   7045         ALOGI("%s: HFR is ON, setting DIS as OFF", __FUNCTION__);
   7046         disCtrl.dis_enable = 0;
   7047     }
   7048     disCtrl.video_rec_width = videoWidth;
   7049     disCtrl.video_rec_height = videoHeight;
   7050     disCtrl.output_cbcr_offset = video_frame_cbcroffset;
   7051 
   7052     ret = native_set_parms( CAMERA_PARM_VIDEO_DIS,
   7053                        sizeof(disCtrl), &disCtrl);
   7054 
   7055     ALOGV("setDIS X (%d)", ret);
   7056     return ret ? NO_ERROR : UNKNOWN_ERROR;
   7057 }
   7058 
   7059 status_t QualcommCameraHardware::setVpeParameters()
   7060 {
   7061     ALOGV("setVpeParameters E");
   7062 
   7063     video_rotation_param_ctrl_t rotCtrl;
   7064     bool ret = true;
   7065     ALOGV("videoWidth = %d, videoHeight = %d", videoWidth, videoHeight);
   7066     int rotation = (mRotation + sensor_rotation)%360;
   7067     rotCtrl.rotation = (rotation == 0) ? ROT_NONE :
   7068                        ((rotation == 90) ? ROT_CLOCKWISE_90 :
   7069                   ((rotation == 180) ? ROT_CLOCKWISE_180 : ROT_CLOCKWISE_270));
   7070 
   7071     if( ((videoWidth == 1280 && videoHeight == 720) || (videoWidth == 800 && videoHeight == 480))
   7072         && (rotation == 90 || rotation == 270) ){
   7073         /* Due to a limitation at video core to support heights greater than 720, adding this check.
   7074          * This is a temporary hack, need to be removed once video core support is available
   7075          */
   7076         ALOGI("video resolution (%dx%d) with rotation (%d) is not supported, setting rotation to NONE",
   7077             videoWidth, videoHeight, rotation);
   7078         rotCtrl.rotation = ROT_NONE;
   7079     }
   7080     ALOGV("rotCtrl.rotation = %d", rotCtrl.rotation);
   7081 
   7082     ret = native_set_parms(CAMERA_PARM_VIDEO_ROT,
   7083                            sizeof(rotCtrl), &rotCtrl);
   7084 
   7085     ALOGV("setVpeParameters X (%d)", ret);
   7086     return ret ? NO_ERROR : UNKNOWN_ERROR;
   7087 }
   7088 
   7089 status_t QualcommCameraHardware::startRecording()
   7090 {
   7091     ALOGV("startRecording E");
   7092     int ret;
   7093     Mutex::Autolock l(&mLock);
   7094     mReleasedRecordingFrame = false;
   7095     if( (ret=startPreviewInternal())== NO_ERROR){
   7096       if(mVpeEnabled){
   7097         ALOGI("startRecording: VPE enabled, setting vpe parameters");
   7098         bool status = setVpeParameters();
   7099         if(status) {
   7100           ALOGE("Failed to set VPE parameters");
   7101           return status;
   7102         }
   7103       }
   7104       if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) ||
   7105         (mCurrentTarget == TARGET_MSM8660))  {
   7106         for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   7107             if(mStoreMetaDataInFrame)
   7108             {
   7109                 ALOGI("startRecording : meta data mode enabled");
   7110                 metadata_memory[cnt] = mGetMemory(-1,  sizeof(struct encoder_media_buffer_type), 1, mCallbackCookie);
   7111                 struct encoder_media_buffer_type * packet =
   7112                                   (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   7113                 packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
   7114                 packet->buffer_type = kMetadataBufferTypeCameraSource;
   7115                 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
   7116                 nh->data[0] = mRecordfd[cnt];
   7117                 nh->data[1] = 0;
   7118                 nh->data[2] = mRecordFrameSize;
   7119             }
   7120         }
   7121         ALOGV(" in startREcording : calling start_recording");
   7122         native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
   7123         mRecordingState = 1;
   7124         // Remove the left out frames in busy Q and them in free Q.
   7125         // this should be done before starting video_thread so that,
   7126         // frames in previous recording are flushed out.
   7127         ALOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames);
   7128         while((g_busy_frame_queue.num_of_frames) >0){
   7129           msm_frame* vframe = cam_frame_get_video ();
   7130           LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe);
   7131         }
   7132         ALOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames);
   7133         //Clear the dangling buffers and put them in free queue
   7134          for(int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   7135             if(record_buffers_tracking_flag[cnt] == true) {
   7136               ALOGI("Dangling buffer: offset = %d, buffer = %d", cnt,
   7137                 (unsigned int)recordframes[cnt].buffer);
   7138               LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[cnt]);
   7139               record_buffers_tracking_flag[cnt] = false;
   7140             }
   7141          }
   7142           mVideoThreadWaitLock.lock();
   7143           mVideoThreadExit = 0;
   7144           pthread_attr_t attr;
   7145           pthread_attr_init(&attr);
   7146           pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   7147           mVideoThreadRunning = pthread_create(&mVideoThread,
   7148                 &attr,
   7149                 video_thread,
   7150                 NULL);
   7151           mVideoThreadWaitLock.unlock();
   7152       } else if ( mCurrentTarget == TARGET_MSM7627A ) {
   7153         for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   7154             if(mStoreMetaDataInFrame
   7155                 && (metadata_memory[cnt] == NULL))
   7156             {
   7157                 ALOGI("startRecording : meta data mode enabled filling metadata memory ");
   7158                 metadata_memory[cnt] = mGetMemory(-1,  sizeof(struct encoder_media_buffer_type), 1, mCallbackCookie);
   7159                 struct encoder_media_buffer_type * packet =
   7160                                   (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   7161                 packet->meta_handle = native_handle_create(1, 3); //1 fd, 1 offset and 1 size
   7162                 packet->buffer_type = kMetadataBufferTypeCameraSource;
   7163                 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
   7164                 nh->data[0] = frames[cnt].fd;
   7165                 nh->data[1] = 0;
   7166                 nh->data[2] = previewWidth * previewHeight * 3/2;
   7167                 nh->data[3] = (unsigned int)mPreviewMapped[cnt]->data;
   7168             }
   7169         }
   7170       }
   7171       record_flag = 1;
   7172     }
   7173     return ret;
   7174 }
   7175 
   7176 status_t QualcommCameraHardware::startRecordingInternal()
   7177 {
   7178     ALOGV("%s: E", __FUNCTION__);
   7179     mReleasedRecordingFrame = false;
   7180 
   7181     /* In 3D mode, the video thread has to be started as part
   7182      * of preview itself, because video buffers and video callback
   7183      * need to be used for both display and encoding.
   7184      * startRecordingInternal() will be called as part of startPreview().
   7185      * This check is needed to support both 3D and non-3D mode.
   7186      */
   7187     if(mVideoThreadRunning) {
   7188         ALOGI("Video Thread is in progress");
   7189         return NO_ERROR;
   7190     }
   7191 
   7192     if(mVpeEnabled){
   7193         ALOGI("startRecording: VPE enabled, setting vpe parameters");
   7194         bool status = setVpeParameters();
   7195         if(status) {
   7196             ALOGE("Failed to set VPE parameters");
   7197             return status;
   7198         }
   7199     }
   7200     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660))  {
   7201         // Remove the left out frames in busy Q and them in free Q.
   7202         // this should be done before starting video_thread so that,
   7203         // frames in previous recording are flushed out.
   7204         ALOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames);
   7205         while((g_busy_frame_queue.num_of_frames) >0){
   7206             msm_frame* vframe = cam_frame_get_video ();
   7207             LINK_camframe_add_frame(CAM_VIDEO_FRAME,vframe);
   7208         }
   7209         ALOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames);
   7210 
   7211         //Clear the dangling buffers and put them in free queue
   7212         for(int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   7213             if(record_buffers_tracking_flag[cnt] == true) {
   7214                 ALOGI("Dangling buffer: offset = %d, buffer = %d", cnt, (unsigned int)recordframes[cnt].buffer);
   7215                 LINK_camframe_add_frame(CAM_VIDEO_FRAME,&recordframes[cnt]);
   7216                 record_buffers_tracking_flag[cnt] = false;
   7217             }
   7218         }
   7219 
   7220         ALOGI(" in startREcording : calling start_recording");
   7221         if(!mIs3DModeOn)
   7222             native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
   7223 
   7224         // Start video thread and wait for busy frames to be encoded, this thread
   7225         // should be closed in stopRecording
   7226         mVideoThreadWaitLock.lock();
   7227         mVideoThreadExit = 0;
   7228         pthread_attr_t attr;
   7229         pthread_attr_init(&attr);
   7230         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   7231         mVideoThreadRunning = !pthread_create(&mVideoThread,
   7232                                               &attr,
   7233                                               video_thread,
   7234                                               NULL);
   7235         mVideoThreadWaitLock.unlock();
   7236         // Remove the left out frames in busy Q and them in free Q.
   7237     }
   7238     ALOGV("%s: E", __FUNCTION__);
   7239     return NO_ERROR;
   7240 }
   7241 
   7242 void QualcommCameraHardware::stopRecording()
   7243 {
   7244     ALOGV("stopRecording: E");
   7245     record_flag = 0;
   7246     Mutex::Autolock l(&mLock);
   7247     {
   7248         mRecordFrameLock.lock();
   7249         mReleasedRecordingFrame = true;
   7250         mRecordWait.signal();
   7251         mRecordFrameLock.unlock();
   7252 
   7253         if(mDataCallback && !(mCurrentTarget == TARGET_QSD8250) &&
   7254                          (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
   7255             ALOGV("stopRecording: X, preview still in progress");
   7256             return;
   7257         }
   7258     }
   7259     if (NULL != mJpegLiveSnapMapped) {
   7260         ALOGI("initLiveSnapshot: clearing old mJpegHeap.");
   7261         mJpegLiveSnapMapped->release(mJpegLiveSnapMapped);
   7262         mJpegLiveSnapMapped = NULL;
   7263     }
   7264 
   7265     // If output2 enabled, exit video thread, invoke stop recording ioctl
   7266     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660))  {
   7267         /* when 3D mode is ON, don't exit the video thread, as
   7268          * we need to support the preview mode. Just set the recordingState
   7269          * to zero, so that there won't be any rcb callbacks. video thread
   7270          * will be terminated as part of stop preview.
   7271          */
   7272         if(mIs3DModeOn) {
   7273             ALOGV("%s: 3D mode on, so don't exit video thread", __FUNCTION__);
   7274             mRecordingState = 0;
   7275             return;
   7276         }
   7277 
   7278         mVideoThreadWaitLock.lock();
   7279         mVideoThreadExit = 1;
   7280         mVideoThreadWaitLock.unlock();
   7281         native_stop_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
   7282 
   7283         pthread_mutex_lock(&(g_busy_frame_queue.mut));
   7284         pthread_cond_signal(&(g_busy_frame_queue.wait));
   7285         pthread_mutex_unlock(&(g_busy_frame_queue.mut));
   7286       for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
   7287         if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   7288           struct encoder_media_buffer_type * packet =
   7289               (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   7290           native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   7291           metadata_memory[cnt]->release(metadata_memory[cnt]);
   7292           metadata_memory[cnt] = NULL;
   7293         }
   7294       }
   7295     }
   7296     else if(mCurrentTarget == TARGET_MSM7627A) {
   7297        for (int cnt = 0; cnt < mTotalPreviewBufferCount; cnt++) {
   7298           if(mStoreMetaDataInFrame && (metadata_memory[cnt] != NULL)){
   7299             struct encoder_media_buffer_type * packet =
   7300                 (struct encoder_media_buffer_type  *)metadata_memory[cnt]->data;
   7301             native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
   7302             metadata_memory[cnt]->release(metadata_memory[cnt]);
   7303             metadata_memory[cnt] = NULL;
   7304           }
   7305         }
   7306     }
   7307 #if 0
   7308     else  // for other targets where output2 is not enabled
   7309         stopPreviewInternal();
   7310     if (mJpegHeap != NULL) {
   7311         ALOGV("stopRecording: clearing old mJpegHeap.");
   7312         mJpegHeap.clear();
   7313     }
   7314 #endif
   7315     mRecordingState = 0; // recording not started
   7316     ALOGV("stopRecording: X");
   7317 }
   7318 
   7319 void QualcommCameraHardware::releaseRecordingFrame(const void *opaque)
   7320 {
   7321     ALOGI("%s : BEGIN, opaque = 0x%p",__func__, opaque);
   7322     Mutex::Autolock rLock(&mRecordFrameLock);
   7323     mReleasedRecordingFrame = true;
   7324     mRecordWait.signal();
   7325 
   7326     // Ff 7x30 : add the frame to the free camframe queue
   7327     if( (mCurrentTarget == TARGET_MSM7630 )  || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
   7328         ssize_t offset;
   7329         size_t size;
   7330         //sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
   7331         msm_frame* releaseframe = NULL;
   7332         int cnt;
   7333         for (cnt = 0; cnt < kRecordBufferCount; cnt++) {
   7334             if(mStoreMetaDataInFrame){
   7335                 if(metadata_memory[cnt] && metadata_memory[cnt]->data == opaque){
   7336                     ALOGV("in release recording frame(meta) found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer);
   7337                     releaseframe = &recordframes[cnt];
   7338                     break;
   7339                 }
   7340             }else {
   7341                 if(recordframes[cnt].buffer && ((unsigned long)opaque == recordframes[cnt].buffer) ){
   7342                     ALOGV("in release recording frame found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer);
   7343                     releaseframe = &recordframes[cnt];
   7344                     break;
   7345                 }
   7346             }
   7347         }
   7348         if(cnt < kRecordBufferCount) {
   7349             // do this only if frame thread is running
   7350             mFrameThreadWaitLock.lock();
   7351             if(mFrameThreadRunning ) {
   7352                 //Reset the track flag for this frame buffer
   7353                 record_buffers_tracking_flag[cnt] = false;
   7354                 LINK_camframe_add_frame(CAM_VIDEO_FRAME,releaseframe);
   7355             }
   7356 
   7357             mFrameThreadWaitLock.unlock();
   7358         } else {
   7359             ALOGE("in release recordingframe XXXXX error , buffer not found");
   7360             for (int i=0; i< kRecordBufferCount; i++) {
   7361                  ALOGE(" recordframes[%d].buffer = %d", i, (unsigned int)recordframes[i].buffer);
   7362             }
   7363         }
   7364     }
   7365 
   7366     ALOGV("releaseRecordingFrame X");
   7367 }
   7368 
   7369 bool QualcommCameraHardware::recordingEnabled()
   7370 {
   7371     return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
   7372 }
   7373 
   7374 void QualcommCameraHardware::notifyShutter(bool mPlayShutterSoundOnly)
   7375 {
   7376     private_handle_t *thumbnailHandle;
   7377     if(mThumbnailBuffer) {
   7378         thumbnailHandle = (private_handle_t *) (*mThumbnailBuffer);
   7379     }
   7380     mShutterLock.lock();
   7381     //image_rect_type size;
   7382 
   7383     if(mPlayShutterSoundOnly) {
   7384         /* At this point, invoke Notify Callback to play shutter sound only.
   7385          * We want to call notify callback again when we have the
   7386          * yuv picture ready. This is to reduce blanking at the time
   7387          * of displaying postview frame. Using ext2 to indicate whether
   7388          * to play shutter sound only or register the postview buffers.
   7389          */
   7390         mNotifyCallback(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly,
   7391                             mCallbackCookie);
   7392         mShutterLock.unlock();
   7393         return;
   7394     }
   7395 
   7396     if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
   7397         //mDisplayHeap = mThumbnailHeap;
   7398 #if 0
   7399         if (crop != NULL && (crop->in1_w != 0 && crop->in1_h != 0)) {
   7400             size.width = crop->in1_w;
   7401             size.height = crop->in1_h;
   7402         }
   7403         else {
   7404             size.width = mPostviewWidth;
   7405             size.height = mPostviewHeight;
   7406         }
   7407 #endif
   7408 /*
   7409         if(strTexturesOn == true) {
   7410             mDisplayHeap = mRawHeap;
   7411             size.width = mPictureWidth;
   7412             size.height = mPictureHeight;
   7413         }
   7414 */
   7415         /* Now, invoke Notify Callback to unregister preview buffer
   7416          * and register postview buffer with surface flinger. Set ext2
   7417          * as 0 to indicate not to play shutter sound.
   7418          */
   7419         mNotifyCallback(CAMERA_MSG_SHUTTER, 0, 0,
   7420                         mCallbackCookie);
   7421         mShutterPending = false;
   7422     }
   7423     mShutterLock.unlock();
   7424 }
   7425 
   7426 static void receive_shutter_callback(common_crop_t *crop)
   7427 {
   7428     ALOGV("receive_shutter_callback: E");
   7429     QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   7430     if (obj != 0) {
   7431         /* Just play shutter sound at this time */
   7432         obj->notifyShutter(TRUE);
   7433     }
   7434     ALOGV("receive_shutter_callback: X");
   7435 }
   7436 
   7437 // Crop the picture in place.
   7438 static void crop_yuv420(uint32_t width, uint32_t height,
   7439                  uint32_t cropped_width, uint32_t cropped_height,
   7440                  uint8_t *image, const char *name)
   7441 {
   7442     uint32_t i;
   7443     uint32_t x, y;
   7444     uint8_t* chroma_src, *chroma_dst;
   7445     int yOffsetSrc, yOffsetDst, CbCrOffsetSrc, CbCrOffsetDst;
   7446     int mSrcSize, mDstSize;
   7447 
   7448     //check if all fields needed eg. size and also how to set y offset. If condition for 7x27
   7449     //and need to check if needed for 7x30.
   7450 
   7451     LINK_jpeg_encoder_get_buffer_offset(width, height, (uint32_t *)&yOffsetSrc,
   7452                                        (uint32_t *)&CbCrOffsetSrc, (uint32_t *)&mSrcSize);
   7453 
   7454     LINK_jpeg_encoder_get_buffer_offset(cropped_width, cropped_height, (uint32_t *)&yOffsetDst,
   7455                                        (uint32_t *)&CbCrOffsetDst, (uint32_t *)&mDstSize);
   7456 
   7457     // Calculate the start position of the cropped area.
   7458     x = (width - cropped_width) / 2;
   7459     y = (height - cropped_height) / 2;
   7460     x &= ~1;
   7461     y &= ~1;
   7462 
   7463     if((mCurrentTarget == TARGET_MSM7627)
   7464        || (mCurrentTarget == TARGET_MSM7625A)
   7465        || (mCurrentTarget == TARGET_MSM7627A)
   7466        || (mCurrentTarget == TARGET_MSM7630)
   7467        || (mCurrentTarget == TARGET_MSM8660)) {
   7468         if (!strcmp("snapshot camera", name)) {
   7469             chroma_src = image + CbCrOffsetSrc;
   7470             chroma_dst = image + CbCrOffsetDst;
   7471         } else {
   7472             chroma_src = image + width * height;
   7473             chroma_dst = image + cropped_width * cropped_height;
   7474             yOffsetSrc = 0;
   7475             yOffsetDst = 0;
   7476             CbCrOffsetSrc = width * height;
   7477             CbCrOffsetDst = cropped_width * cropped_height;
   7478         }
   7479     } else {
   7480        chroma_src = image + CbCrOffsetSrc;
   7481        chroma_dst = image + CbCrOffsetDst;
   7482     }
   7483 
   7484     int32_t bufDst = yOffsetDst;
   7485     int32_t bufSrc = yOffsetSrc + (width * y) + x;
   7486 
   7487     if( bufDst > bufSrc ){
   7488         ALOGV("crop yuv Y destination position follows source position");
   7489         /*
   7490          * If buffer destination follows buffer source, memcpy
   7491          * of lines will lead to overwriting subsequent lines. In order
   7492          * to prevent this, reverse copying of lines is performed
   7493          * for the set of lines where destination follows source and
   7494          * forward copying of lines is performed for lines where source
   7495          * follows destination. To calculate the position to switch,
   7496          * the initial difference between source and destination is taken
   7497          * and divided by difference between width and cropped width. For
   7498          * every line copied the difference between source destination
   7499          * drops by width - cropped width
   7500          */
   7501         //calculating inversion
   7502         int position = ( bufDst - bufSrc ) / (width - cropped_width);
   7503         // Copy luma component.
   7504         for(i=position+1; i < cropped_height; i++){
   7505             memmove(image + yOffsetDst + i * cropped_width,
   7506                     image + yOffsetSrc + width * (y + i) + x,
   7507                     cropped_width);
   7508         }
   7509         for(int j=position; j>=0; j--){
   7510             memmove(image + yOffsetDst + j * cropped_width,
   7511                     image + yOffsetSrc + width * (y + j) + x,
   7512                     cropped_width);
   7513         }
   7514     } else {
   7515         // Copy luma component.
   7516         for(i = 0; i < cropped_height; i++)
   7517             memcpy(image + yOffsetDst + i * cropped_width,
   7518                    image + yOffsetSrc + width * (y + i) + x,
   7519                    cropped_width);
   7520     }
   7521 
   7522     // Copy chroma components.
   7523     cropped_height /= 2;
   7524     y /= 2;
   7525 
   7526     bufDst = CbCrOffsetDst;
   7527     bufSrc = CbCrOffsetSrc + (width * y) + x;
   7528 
   7529     if( bufDst > bufSrc ) {
   7530         ALOGV("crop yuv Chroma destination position follows source position");
   7531         /*
   7532          * Similar to y
   7533          */
   7534         int position = ( bufDst - bufSrc ) / (width - cropped_width);
   7535         for(i=position+1; i < cropped_height; i++){
   7536             memmove(chroma_dst + i * cropped_width,
   7537                     chroma_src + width * (y + i) + x,
   7538                     cropped_width);
   7539         }
   7540         for(int j=position; j >=0; j--){
   7541             memmove(chroma_dst + j * cropped_width,
   7542                     chroma_src + width * (y + j) + x,
   7543                     cropped_width);
   7544         }
   7545     } else {
   7546         for(i = 0; i < cropped_height; i++)
   7547             memcpy(chroma_dst + i * cropped_width,
   7548                    chroma_src + width * (y + i) + x,
   7549                    cropped_width);
   7550     }
   7551 }
   7552 // ReceiveRawPicture for ICS
   7553 void QualcommCameraHardware::receiveRawPicture(status_t status,struct msm_frame *postviewframe, struct msm_frame *mainframe)
   7554 {
   7555     ALOGV("%s: E", __FUNCTION__);
   7556 
   7557     void* cropp;
   7558     mSnapshotThreadWaitLock.lock();
   7559     if(mSnapshotThreadRunning == false) {
   7560         ALOGE("%s called in wrong state, ignore", __FUNCTION__);
   7561         return;
   7562     }
   7563     mSnapshotThreadWaitLock.unlock();
   7564 
   7565     if(status != NO_ERROR){
   7566         ALOGE("%s: Failed to get Snapshot Image", __FUNCTION__);
   7567         if(mDataCallback &&
   7568             (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
   7569             /* get picture failed. Give jpeg callback with NULL data
   7570              * to the application to restore to preview mode
   7571              */
   7572             ALOGE("get picture failed, giving jpeg callback with NULL data");
   7573             mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, NULL, data_counter, NULL, mCallbackCookie);
   7574         }
   7575         mShutterLock.lock();
   7576         mShutterPending = false;
   7577         mShutterLock.unlock();
   7578         mJpegThreadWaitLock.lock();
   7579         mJpegThreadRunning = false;
   7580         mJpegThreadWait.signal();
   7581         mJpegThreadWaitLock.unlock();
   7582         mInSnapshotModeWaitLock.lock();
   7583         mInSnapshotMode = false;
   7584         mInSnapshotModeWait.signal();
   7585         mInSnapshotModeWaitLock.unlock();
   7586         return;
   7587     }
   7588     /* call notifyShutter to config surface and overlay
   7589      * for postview rendering.
   7590      * Its necessary to issue another notifyShutter here with
   7591      * mPlayShutterSoundOnly as FALSE, since that is when the
   7592      * preview buffers are unregistered with the surface flinger.
   7593      * That is necessary otherwise the preview memory wont be
   7594      * deallocated.
   7595      */
   7596     cropp =postviewframe->cropinfo;
   7597     notifyShutter(FALSE);
   7598 
   7599     if(mSnapshotFormat == PICTURE_FORMAT_JPEG) {
   7600         if(cropp != NULL){
   7601             common_crop_t *crop = (common_crop_t *)cropp;
   7602             if (crop->in1_w != 0 && crop->in1_h != 0) {
   7603                 zoomCropInfo.left = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
   7604                 zoomCropInfo.top = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
   7605                 if(zoomCropInfo.left < 0) zoomCropInfo.left = 0;
   7606                 if(zoomCropInfo.top < 0) zoomCropInfo.top = 0;
   7607                 zoomCropInfo.right = zoomCropInfo.left + crop->in1_w;
   7608                 zoomCropInfo.bottom = zoomCropInfo.top + crop->in1_h;
   7609                 mPreviewWindow->set_crop(mPreviewWindow,
   7610                             zoomCropInfo.left,
   7611                             zoomCropInfo.top,
   7612                             zoomCropInfo.right,
   7613                             zoomCropInfo.bottom);
   7614                 mResetWindowCrop = true;
   7615             } else {
   7616                 zoomCropInfo.left = 0;
   7617                 zoomCropInfo.top = 0;
   7618                 zoomCropInfo.right = mPostviewWidth;
   7619                 zoomCropInfo.bottom = mPostviewHeight;
   7620                 mPreviewWindow->set_crop(mPreviewWindow,
   7621                                  zoomCropInfo.left,
   7622                                  zoomCropInfo.top,
   7623                                  zoomCropInfo.right,
   7624                                  zoomCropInfo.bottom);
   7625             }
   7626         }
   7627         ALOGI("receiverawpicture : display lock");
   7628         mDisplayLock.lock();
   7629         int index = mapThumbnailBuffer(postviewframe);
   7630         ALOGI("receiveRawPicture : mapThumbnailBuffer returned %d", index);
   7631         private_handle_t *handle;
   7632         if(mThumbnailBuffer[index] != NULL && mZslEnable == false) {
   7633             handle = (private_handle_t *)(*mThumbnailBuffer[index]);
   7634             ALOGV("%s: Queueing postview buffer for display %d",
   7635                                            __FUNCTION__,handle->fd);
   7636             if (BUFFER_LOCKED == mThumbnailLockState[index]) {
   7637                 if (GENLOCK_FAILURE == genlock_unlock_buffer(handle)) {
   7638                     ALOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
   7639                     mDisplayLock.unlock();
   7640                     return;
   7641                 } else {
   7642                      mThumbnailLockState[index] = BUFFER_UNLOCKED;
   7643                 }
   7644             }
   7645             status_t retVal = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   7646                                                          mThumbnailBuffer[index]);
   7647             ALOGI(" enQ thumbnailbuffer");
   7648             if( retVal != NO_ERROR) {
   7649                 ALOGE("%s: Queuebuffer failed for postview buffer", __FUNCTION__);
   7650             }
   7651 
   7652         }
   7653         mDisplayLock.unlock();
   7654         ALOGI("receiverawpicture : display unlock");
   7655         /* Give the main Image as raw to upper layers */
   7656         //Either CAMERA_MSG_RAW_IMAGE or CAMERA_MSG_RAW_IMAGE_NOTIFY will be set not both
   7657         if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE))
   7658             mDataCallback(CAMERA_MSG_RAW_IMAGE, mRawMapped[index],data_counter,
   7659                           NULL, mCallbackCookie);
   7660         else if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE_NOTIFY))
   7661             mNotifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0,
   7662                             mCallbackCookie);
   7663 
   7664         if(strTexturesOn == true) {
   7665             ALOGI("Raw Data given to app for processing...will wait for jpeg encode call");
   7666             mEncodePending = true;
   7667             mEncodePendingWaitLock.unlock();
   7668             mJpegThreadWaitLock.lock();
   7669             mJpegThreadWait.signal();
   7670             mJpegThreadWaitLock.unlock();
   7671         }
   7672     } else {  // Not Jpeg snapshot, it is Raw Snapshot , handle later
   7673             ALOGV("ReceiveRawPicture : raw snapshot not Jpeg, sending callback up");
   7674              if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))
   7675                 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
   7676                                        mRawSnapshotMapped,
   7677                                              data_counter,
   7678                                                      NULL,
   7679                                          mCallbackCookie);
   7680 
   7681               // TEMP
   7682              ALOGI("receiveRawPicture : gave raw frame to app, giving signal");
   7683               mJpegThreadWaitLock.lock();
   7684               mJpegThreadRunning = false;
   7685               mJpegThreadWait.signal();
   7686               mJpegThreadWaitLock.unlock();
   7687 
   7688     }
   7689     /* can start preview at this stage? early preview? */
   7690     mInSnapshotModeWaitLock.lock();
   7691     mInSnapshotMode = false;
   7692     mInSnapshotModeWait.signal();
   7693     mInSnapshotModeWaitLock.unlock();
   7694 
   7695     ALOGV("%s: X", __FUNCTION__);
   7696 
   7697 }
   7698 
   7699 
   7700 void QualcommCameraHardware::receiveJpegPicture(status_t status, mm_camera_buffer_t *encoded_buffer)
   7701 {
   7702     Mutex::Autolock cbLock(&mCallbackLock);
   7703     numJpegReceived++;
   7704     uint32_t offset ;
   7705     int32_t index = -1;
   7706     int32_t buffer_size = 0;
   7707     if(encoded_buffer && status == NO_ERROR) {
   7708       buffer_size = encoded_buffer->filled_size;
   7709       ALOGV("receiveJpegPicture: E buffer_size %d mJpegMaxSize = %d",buffer_size, mJpegMaxSize);
   7710 
   7711         index = mapJpegBuffer(encoded_buffer);
   7712         ALOGI("receiveJpegPicutre : mapJpegBuffer index : %d", index);
   7713     }
   7714     if((index < 0) || (index >= (MAX_SNAPSHOT_BUFFERS-2))){
   7715         ALOGE("Jpeg index is not valid or fails. ");
   7716         if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
   7717           mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, NULL, data_counter, NULL, mCallbackCookie);
   7718         }
   7719         mJpegThreadWaitLock.lock();
   7720         mJpegThreadRunning = false;
   7721         mJpegThreadWait.signal();
   7722         mJpegThreadWaitLock.unlock();
   7723     } else {
   7724       ALOGV("receiveJpegPicture: Index of Jpeg is %d",index);
   7725 
   7726       if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
   7727           if(status == NO_ERROR) {
   7728             ALOGI("receiveJpegPicture : giving jpeg image callback to services");
   7729             mJpegCopyMapped = mGetMemory(-1, encoded_buffer->filled_size,1, mCallbackCookie);
   7730             if(!mJpegCopyMapped){
   7731               ALOGE("%s: mGetMemory failed.\n", __func__);
   7732             }
   7733             memcpy(mJpegCopyMapped->data, mJpegMapped[index]->data, encoded_buffer->filled_size );
   7734             mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE,mJpegCopyMapped,data_counter,NULL,mCallbackCookie);
   7735              if(NULL != mJpegCopyMapped) {
   7736                mJpegCopyMapped->release(mJpegCopyMapped);
   7737                mJpegCopyMapped = NULL;
   7738              }
   7739           }
   7740       } else {
   7741         ALOGI("JPEG callback was cancelled--not delivering image.");
   7742       }
   7743       if(numJpegReceived == numCapture){
   7744           mJpegThreadWaitLock.lock();
   7745           mJpegThreadRunning = false;
   7746           mJpegThreadWait.signal();
   7747           mJpegThreadWaitLock.unlock();
   7748       }
   7749     }
   7750 
   7751     ALOGV("receiveJpegPicture: X callback done.");
   7752 }
   7753 bool QualcommCameraHardware::previewEnabled()
   7754 {
   7755     /* If overlay is used the message CAMERA_MSG_PREVIEW_FRAME would
   7756      * be disabled at CameraService layer. Hence previewEnabled would
   7757      * return FALSE even though preview is running. Hence check for
   7758      * mOverlay not being NULL to ensure that previewEnabled returns
   7759      * accurate information.
   7760      */
   7761 
   7762 //    return mCameraRunning && mDataCallback &&
   7763 //           ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) || (mOverlay != NULL));
   7764     ALOGI(" : mCameraRunning : %d mPreviewWindow = %x",mCameraRunning,mPreviewWindow);
   7765     return mCameraRunning;// || (mPreviewWindow != NULL);
   7766 }
   7767 status_t QualcommCameraHardware::setRecordSize(const QCameraParameters& params)
   7768 {
   7769     const char *recordSize = NULL;
   7770     recordSize = params.get(QCameraParameters::KEY_VIDEO_SIZE);
   7771     if(!recordSize) {
   7772         mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, "");
   7773         //If application didn't set this parameter string, use the values from
   7774         //getPreviewSize() as video dimensions.
   7775         ALOGV("No Record Size requested, use the preview dimensions");
   7776         videoWidth = previewWidth;
   7777         videoHeight = previewHeight;
   7778     } else {
   7779         //Extract the record witdh and height that application requested.
   7780         ALOGI("%s: requested record size %s", __FUNCTION__, recordSize);
   7781         if(!parse_size(recordSize, videoWidth, videoHeight)) {
   7782             mParameters.set(QCameraParameters::KEY_VIDEO_SIZE , recordSize);
   7783             //VFE output1 shouldn't be greater than VFE output2.
   7784             if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) {
   7785                 //Set preview sizes as record sizes.
   7786                 ALOGI("Preview size %dx%d is greater than record size %dx%d,\
   7787                    resetting preview size to record size",previewWidth,\
   7788                      previewHeight, videoWidth, videoHeight);
   7789                 previewWidth = videoWidth;
   7790                 previewHeight = videoHeight;
   7791                 mParameters.setPreviewSize(previewWidth, previewHeight);
   7792             }
   7793             if( (mCurrentTarget != TARGET_MSM7630)
   7794                 && (mCurrentTarget != TARGET_QSD8250)
   7795                  && (mCurrentTarget != TARGET_MSM8660) ) {
   7796                 //For Single VFE output targets, use record dimensions as preview dimensions.
   7797                 previewWidth = videoWidth;
   7798                 previewHeight = videoHeight;
   7799                 mParameters.setPreviewSize(previewWidth, previewHeight);
   7800             }
   7801             if(mIs3DModeOn == true) {
   7802                 /* As preview and video frames are same in 3D mode,
   7803                  * preview size should be same as video size. This
   7804                  * cahnge is needed to take of video resolutions
   7805                  * like 720P and 1080p where the application can
   7806                  * request different preview sizes like 768x432
   7807                  */
   7808                 previewWidth = videoWidth;
   7809                 previewHeight = videoHeight;
   7810                 mParameters.setPreviewSize(previewWidth, previewHeight);
   7811             }
   7812         } else {
   7813             mParameters.set(QCameraParameters::KEY_VIDEO_SIZE, "");
   7814             ALOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize);
   7815             return BAD_VALUE;
   7816         }
   7817     }
   7818     ALOGI("%s: preview dimensions: %dx%d", __FUNCTION__, previewWidth, previewHeight);
   7819     ALOGI("%s: video dimensions: %dx%d", __FUNCTION__, videoWidth, videoHeight);
   7820     mDimension.display_width = previewWidth;
   7821     mDimension.display_height= previewHeight;
   7822     return NO_ERROR;
   7823 }
   7824 
   7825 status_t  QualcommCameraHardware::setCameraMode(const QCameraParameters& params) {
   7826     int32_t value = params.getInt(QCameraParameters::KEY_CAMERA_MODE);
   7827     mParameters.set(QCameraParameters::KEY_CAMERA_MODE,value);
   7828 
   7829     ALOGI("ZSL is enabled  %d", value);
   7830     if( value != mZslEnable) {
   7831         mFrameThreadWaitLock.lock();
   7832         while (mFrameThreadRunning) {
   7833           ALOGI("initPreview: waiting for old frame thread to complete.");
   7834           mFrameThreadWait.wait(mFrameThreadWaitLock);
   7835           ALOGI("initPreview: old frame thread completed.");
   7836         }
   7837         mFrameThreadWaitLock.unlock();
   7838     }
   7839     if(value == 1) {
   7840         mZslEnable = true;
   7841        /* mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   7842                        QCameraParameters::FOCUS_MODE_INFINITY);
   7843         mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   7844                        QCameraParameters::FOCUS_MODE_INFINITY);*/
   7845     }else{
   7846         mZslEnable = false;
   7847         /*mParameters.set(QCameraParameters::KEY_SUPPORTED_FOCUS_MODES,
   7848                     focus_mode_values);
   7849         mParameters.set(QCameraParameters::KEY_FOCUS_MODE,
   7850                     QCameraParameters::FOCUS_MODE_AUTO);*/
   7851     }
   7852     return NO_ERROR;
   7853 }
   7854 
   7855 status_t QualcommCameraHardware::setPreviewSize(const QCameraParameters& params)
   7856 {
   7857     int width, height;
   7858     params.getPreviewSize(&width, &height);
   7859     ALOGV("requested preview size %d x %d", width, height);
   7860 
   7861     // Validate the preview size
   7862     for (size_t i = 0; i <  PREVIEW_SIZE_COUNT; ++i) {
   7863         if (width ==  preview_sizes[i].width
   7864            && height ==  preview_sizes[i].height) {
   7865             mParameters.setPreviewSize(width, height);
   7866             //previewWidth = width;
   7867             //previewHeight = height;
   7868             mDimension.display_width = width;
   7869             mDimension.display_height= height;
   7870             return NO_ERROR;
   7871         }
   7872     }
   7873     ALOGE("Invalid preview size requested: %dx%d", width, height);
   7874     return BAD_VALUE;
   7875 }
   7876 status_t QualcommCameraHardware::setPreviewFpsRange(const QCameraParameters& params)
   7877 {
   7878     int minFps,maxFps;
   7879     params.getPreviewFpsRange(&minFps,&maxFps);
   7880     ALOGI("FPS Range Values: %dx%d", minFps, maxFps);
   7881 
   7882     for(size_t i=0;i<FPS_RANGES_SUPPORTED_COUNT;i++)
   7883     {
   7884         if(minFps==FpsRangesSupported[i].minFPS && maxFps == FpsRangesSupported[i].maxFPS){
   7885             mParameters.setPreviewFpsRange(minFps,maxFps);
   7886             return NO_ERROR;
   7887         }
   7888     }
   7889     return BAD_VALUE;
   7890 }
   7891 
   7892 status_t QualcommCameraHardware::setPreviewFrameRate(const QCameraParameters& params)
   7893 {
   7894     if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
   7895          ALOGI("Set fps is not supported for this sensor");
   7896         return NO_ERROR;
   7897     }
   7898     uint16_t previousFps = (uint16_t)mParameters.getPreviewFrameRate();
   7899     uint16_t fps = (uint16_t)params.getPreviewFrameRate();
   7900     ALOGV("requested preview frame rate  is %u", fps);
   7901 
   7902     if(mInitialized && (fps == previousFps)){
   7903         ALOGV("fps same as previous fps");
   7904         return NO_ERROR;
   7905     }
   7906 
   7907     if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
   7908         mParameters.setPreviewFrameRate(fps);
   7909         bool ret = native_set_parms(CAMERA_PARM_FPS,
   7910                 sizeof(fps), (void *)&fps);
   7911         return ret ? NO_ERROR : UNKNOWN_ERROR;
   7912     }
   7913     return BAD_VALUE;
   7914 }
   7915 
   7916 status_t QualcommCameraHardware::setPreviewFrameRateMode(const QCameraParameters& params) {
   7917     if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE) &&  !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
   7918          ALOGI("set fps mode is not supported for this sensor");
   7919         return NO_ERROR;
   7920     }
   7921 
   7922     const char *previousMode = mParameters.getPreviewFrameRateMode();
   7923     const char *str = params.getPreviewFrameRateMode();
   7924     if( mInitialized && !strcmp(previousMode, str)) {
   7925         ALOGV("frame rate mode same as previous mode %s", previousMode);
   7926         return NO_ERROR;
   7927     }
   7928     int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str);
   7929     if(frameRateMode != NOT_FOUND) {
   7930         ALOGV("setPreviewFrameRateMode: %s ", str);
   7931         mParameters.setPreviewFrameRateMode(str);
   7932         bool ret = native_set_parms(CAMERA_PARM_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode);
   7933         if(!ret) return ret;
   7934         //set the fps value when chaging modes
   7935         int16_t fps = (uint16_t)params.getPreviewFrameRate();
   7936         if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
   7937             mParameters.setPreviewFrameRate(fps);
   7938             ret = native_set_parms(CAMERA_PARM_FPS,
   7939                                         sizeof(fps), (void *)&fps);
   7940             return ret ? NO_ERROR : UNKNOWN_ERROR;
   7941         }
   7942         ALOGE("Invalid preview frame rate value: %d", fps);
   7943         return BAD_VALUE;
   7944     }
   7945     ALOGE("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str);
   7946     return BAD_VALUE;
   7947 }
   7948 
   7949 status_t QualcommCameraHardware::setJpegThumbnailSize(const QCameraParameters& params){
   7950     int width = params.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
   7951     int height = params.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
   7952     ALOGV("requested jpeg thumbnail size %d x %d", width, height);
   7953 
   7954     // Validate the picture size
   7955     for (unsigned int i = 0; i < JPEG_THUMBNAIL_SIZE_COUNT; ++i) {
   7956        if (width == jpeg_thumbnail_sizes[i].width
   7957          && height == jpeg_thumbnail_sizes[i].height) {
   7958            mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
   7959            mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
   7960            return NO_ERROR;
   7961        }
   7962     }
   7963     return BAD_VALUE;
   7964 }
   7965 
   7966 bool QualcommCameraHardware::updatePictureDimension(const QCameraParameters& params, int& width, int& height)
   7967 {
   7968     bool retval = false;
   7969     int previewWidth, previewHeight;
   7970     params.getPreviewSize(&previewWidth, &previewHeight);
   7971     ALOGV("updatePictureDimension: %dx%d <- %dx%d", width, height,
   7972       previewWidth, previewHeight);
   7973     if ((width < previewWidth) && (height < previewHeight)) {
   7974     /*As we donot support jpeg downscaling for picture dimension < previewdimesnion/8 ,
   7975      Adding support for the same for cts testcases*/
   7976       mActualPictWidth = width;
   7977       mActualPictHeight = height;
   7978       if((previewWidth /8) > width ) {
   7979         int ratio = previewWidth/width;
   7980         int i;
   7981         for(i =0 ; i < ratio ; i++) {
   7982           if((ratio >> i) < 8)
   7983             break;
   7984           }
   7985           width = width *i*2;
   7986           height = height *i*2;
   7987         }
   7988       else {
   7989         width = previewWidth;
   7990         height = previewHeight;
   7991       }
   7992      mUseJpegDownScaling = true;
   7993      retval = true;
   7994     } else
   7995         mUseJpegDownScaling = false;
   7996     return retval;
   7997 }
   7998 
   7999 status_t QualcommCameraHardware::setPictureSize(const QCameraParameters& params)
   8000 {
   8001     int width, height;
   8002     params.getPictureSize(&width, &height);
   8003     ALOGV("requested picture size %d x %d", width, height);
   8004 
   8005     // Validate the picture size
   8006     for (int i = 0; i < supportedPictureSizesCount; ++i) {
   8007         if (width == picture_sizes_ptr[i].width
   8008           && height == picture_sizes_ptr[i].height) {
   8009             mParameters.setPictureSize(width, height);
   8010             mDimension.picture_width = width;
   8011             mDimension.picture_height = height;
   8012             return NO_ERROR;
   8013         }
   8014     }
   8015     /* Dimension not among the ones in the list. Check if
   8016      * its a valid dimension, if it is, then configure the
   8017      * camera accordingly. else reject it.
   8018      */
   8019     if( isValidDimension(width, height) ) {
   8020         mParameters.setPictureSize(width, height);
   8021         mDimension.picture_width = width;
   8022         mDimension.picture_height = height;
   8023         return NO_ERROR;
   8024     } else
   8025         ALOGE("Invalid picture size requested: %dx%d", width, height);
   8026     return BAD_VALUE;
   8027 }
   8028 
   8029 status_t QualcommCameraHardware::setJpegQuality(const QCameraParameters& params) {
   8030     status_t rc = NO_ERROR;
   8031     int quality = params.getInt(QCameraParameters::KEY_JPEG_QUALITY);
   8032     if (quality >= 0 && quality <= 100) {
   8033         mParameters.set(QCameraParameters::KEY_JPEG_QUALITY, quality);
   8034     } else {
   8035         ALOGE("Invalid jpeg quality=%d", quality);
   8036         rc = BAD_VALUE;
   8037     }
   8038 
   8039     quality = params.getInt(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
   8040     if (quality >= 0 && quality <= 100) {
   8041         mParameters.set(QCameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
   8042     } else {
   8043         ALOGE("Invalid jpeg thumbnail quality=%d", quality);
   8044         rc = BAD_VALUE;
   8045     }
   8046     return rc;
   8047 }
   8048 
   8049 status_t QualcommCameraHardware::setEffect(const QCameraParameters& params)
   8050 {
   8051     const char *str = params.get(QCameraParameters::KEY_EFFECT);
   8052     int result;
   8053 
   8054     if (str != NULL) {
   8055         int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
   8056         if (value != NOT_FOUND) {
   8057            if( !mCfgControl.mm_camera_is_parm_supported(CAMERA_PARM_EFFECT, (void *) &value)){
   8058                ALOGI("Camera Effect - %s mode is not supported for this sensor",str);
   8059                return NO_ERROR;
   8060            }else {
   8061                mParameters.set(QCameraParameters::KEY_EFFECT, str);
   8062                bool ret = native_set_parms(CAMERA_PARM_EFFECT, sizeof(value),
   8063                                            (void *)&value,(int *)&result);
   8064                 if(result == MM_CAMERA_ERR_INVALID_OPERATION) {
   8065                     ALOGI("Camera Effect: %s is not set as the selected value is not supported ", str);
   8066                 }
   8067                return ret ? NO_ERROR : UNKNOWN_ERROR;
   8068           }
   8069         }
   8070     }
   8071     ALOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
   8072     return BAD_VALUE;
   8073 }
   8074 
   8075 status_t QualcommCameraHardware::setRecordingHint(const QCameraParameters& params)
   8076 {
   8077 
   8078   const char * str = params.get(QCameraParameters::KEY_RECORDING_HINT);
   8079 
   8080   if(str != NULL){
   8081       int32_t value = attr_lookup(recording_Hints,
   8082                                   sizeof(recording_Hints) / sizeof(str_map), str);
   8083       if(value != NOT_FOUND){
   8084 
   8085         native_set_parms(CAMERA_PARM_RECORDING_HINT, sizeof(value),
   8086                                                (void *)&value);
   8087         /*native_set_parms(CAMERA_PARM_CAF_ENABLE, sizeof(value),
   8088                                                (void *)&value);*/
   8089         mParameters.set(QCameraParameters::KEY_RECORDING_HINT, str);
   8090       } else {
   8091           ALOGE("Invalid Picture Format value: %s", str);
   8092           return BAD_VALUE;
   8093       }
   8094   }
   8095   return NO_ERROR;
   8096 }
   8097 
   8098 status_t QualcommCameraHardware::setExposureCompensation(
   8099         const QCameraParameters & params){
   8100     ALOGV("DEBBUG: %s E",__FUNCTION__);
   8101     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_EXPOSURE_COMPENSATION)) {
   8102         ALOGI("Exposure Compensation is not supported for this sensor");
   8103         return NO_ERROR;
   8104     }
   8105 
   8106     int numerator = params.getInt(QCameraParameters::KEY_EXPOSURE_COMPENSATION);
   8107     if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator &&
   8108             numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
   8109         int16_t  numerator16 = (int16_t)(numerator & 0x0000ffff);
   8110         uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
   8111         uint32_t  value = 0;
   8112         value = numerator16 << 16 | denominator16;
   8113 
   8114         mParameters.set(QCameraParameters::KEY_EXPOSURE_COMPENSATION,
   8115                             numerator);
   8116        bool ret = native_set_parms(CAMERA_PARM_EXPOSURE_COMPENSATION,
   8117                                     sizeof(value), (void *)&value);
   8118        ALOGI("DEBBUG: %s ret = %d X",__FUNCTION__, ret);
   8119        return ret ? NO_ERROR : UNKNOWN_ERROR;
   8120     }
   8121     ALOGE("Invalid Exposure Compensation");
   8122     return BAD_VALUE;
   8123 }
   8124 
   8125 status_t QualcommCameraHardware::setAutoExposure(const QCameraParameters& params)
   8126 {
   8127     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_EXPOSURE)) {
   8128         ALOGI("Auto Exposure not supported for this sensor");
   8129         return NO_ERROR;
   8130     }
   8131     const char *str = params.get(QCameraParameters::KEY_AUTO_EXPOSURE);
   8132     if (str != NULL) {
   8133         int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
   8134         if (value != NOT_FOUND) {
   8135             mParameters.set(QCameraParameters::KEY_AUTO_EXPOSURE, str);
   8136             bool ret = native_set_parms(CAMERA_PARM_EXPOSURE, sizeof(value),
   8137                                        (void *)&value);
   8138             return ret ? NO_ERROR : UNKNOWN_ERROR;
   8139         }
   8140     }
   8141     ALOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
   8142     return BAD_VALUE;
   8143 }
   8144 
   8145 status_t QualcommCameraHardware::setSharpness(const QCameraParameters& params)
   8146 {
   8147      if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SHARPNESS)) {
   8148         ALOGI("Sharpness not supported for this sensor");
   8149         return NO_ERROR;
   8150     }
   8151     int sharpness = params.getInt(QCameraParameters::KEY_SHARPNESS);
   8152     if((sharpness < CAMERA_MIN_SHARPNESS
   8153             || sharpness > CAMERA_MAX_SHARPNESS))
   8154         return UNKNOWN_ERROR;
   8155 
   8156     ALOGV("setting sharpness %d", sharpness);
   8157     mParameters.set(QCameraParameters::KEY_SHARPNESS, sharpness);
   8158     bool ret = native_set_parms(CAMERA_PARM_SHARPNESS, sizeof(sharpness),
   8159                                (void *)&sharpness);
   8160     return ret ? NO_ERROR : UNKNOWN_ERROR;
   8161 }
   8162 
   8163 status_t QualcommCameraHardware::setContrast(const QCameraParameters& params)
   8164 {
   8165      if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_CONTRAST)) {
   8166         ALOGI("Contrast not supported for this sensor");
   8167         return NO_ERROR;
   8168     }
   8169 
   8170     const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
   8171     int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
   8172 
   8173     if(value == CAMERA_BESTSHOT_OFF) {
   8174         int contrast = params.getInt(QCameraParameters::KEY_CONTRAST);
   8175         if((contrast < CAMERA_MIN_CONTRAST)
   8176                 || (contrast > CAMERA_MAX_CONTRAST))
   8177             return UNKNOWN_ERROR;
   8178 
   8179         ALOGV("setting contrast %d", contrast);
   8180         mParameters.set(QCameraParameters::KEY_CONTRAST, contrast);
   8181         bool ret = native_set_parms(CAMERA_PARM_CONTRAST, sizeof(contrast),
   8182                                    (void *)&contrast);
   8183         return ret ? NO_ERROR : UNKNOWN_ERROR;
   8184     } else {
   8185           ALOGI(" Contrast value will not be set " \
   8186           "when the scenemode selected is %s", str);
   8187     return NO_ERROR;
   8188     }
   8189 }
   8190 
   8191 status_t QualcommCameraHardware::setSaturation(const QCameraParameters& params)
   8192 {
   8193     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SATURATION)) {
   8194         ALOGI("Saturation not supported for this sensor");
   8195         return NO_ERROR;
   8196     }
   8197     int result;
   8198     int saturation = params.getInt(QCameraParameters::KEY_SATURATION);
   8199 
   8200     if((saturation < CAMERA_MIN_SATURATION)
   8201         || (saturation > CAMERA_MAX_SATURATION))
   8202     return UNKNOWN_ERROR;
   8203 
   8204     ALOGV("Setting saturation %d", saturation);
   8205     mParameters.set(QCameraParameters::KEY_SATURATION, saturation);
   8206     bool ret = native_set_parms(CAMERA_PARM_SATURATION, sizeof(saturation),
   8207         (void *)&saturation, (int *)&result);
   8208     if(result == MM_CAMERA_ERR_INVALID_OPERATION)
   8209         ALOGI("Saturation Value: %d is not set as the selected value is not supported", saturation);
   8210 
   8211     return ret ? NO_ERROR : UNKNOWN_ERROR;
   8212 }
   8213 
   8214 status_t QualcommCameraHardware::setPreviewFormat(const QCameraParameters& params) {
   8215     const char *str = params.getPreviewFormat();
   8216     int32_t previewFormat = attr_lookup(preview_formats, sizeof(preview_formats) / sizeof(str_map), str);
   8217     if(previewFormat != NOT_FOUND) {
   8218         mParameters.set(QCameraParameters::KEY_PREVIEW_FORMAT, str);
   8219         mPreviewFormat = previewFormat;
   8220         if(HAL_currentCameraMode != CAMERA_MODE_3D) {
   8221             ALOGI("Setting preview format to native");
   8222             bool ret = native_set_parms(CAMERA_PARM_PREVIEW_FORMAT, sizeof(previewFormat),
   8223                                        (void *)&previewFormat);
   8224         }else{
   8225             ALOGI("Skipping set preview format call to native");
   8226         }
   8227         return NO_ERROR;
   8228     }
   8229     ALOGE("Invalid preview format value: %s", (str == NULL) ? "NULL" : str);
   8230     return BAD_VALUE;
   8231 }
   8232 
   8233 status_t QualcommCameraHardware::setStrTextures(const QCameraParameters& params) {
   8234     const char *str = params.get("strtextures");
   8235     if(str != NULL) {
   8236         ALOGV("strtextures = %s", str);
   8237         mParameters.set("strtextures", str);
   8238         if(!strncmp(str, "on", 2) || !strncmp(str, "ON", 2)) {
   8239             strTexturesOn = true;
   8240         } else if (!strncmp(str, "off", 3) || !strncmp(str, "OFF", 3)) {
   8241             strTexturesOn = false;
   8242         }
   8243     }
   8244     return NO_ERROR;
   8245 }
   8246 
   8247 status_t QualcommCameraHardware::setBrightness(const QCameraParameters& params) {
   8248     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BRIGHTNESS)) {
   8249         ALOGI("Set Brightness not supported for this sensor");
   8250         return NO_ERROR;
   8251     }
   8252     int brightness = params.getInt("luma-adaptation");
   8253     if (mBrightness !=  brightness) {
   8254         ALOGV(" new brightness value : %d ", brightness);
   8255         mBrightness =  brightness;
   8256         mParameters.set("luma-adaptation", brightness);
   8257     bool ret = native_set_parms(CAMERA_PARM_BRIGHTNESS, sizeof(mBrightness),
   8258                                    (void *)&mBrightness);
   8259         return ret ? NO_ERROR : UNKNOWN_ERROR;
   8260     }
   8261     return NO_ERROR;
   8262 }
   8263 
   8264 status_t QualcommCameraHardware::setSkinToneEnhancement(const QCameraParameters& params) {
   8265      if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SCE_FACTOR)) {
   8266         ALOGI("SkinToneEnhancement not supported for this sensor");
   8267         return NO_ERROR;
   8268      }
   8269      int skinToneValue = params.getInt("skinToneEnhancement");
   8270      if (mSkinToneEnhancement != skinToneValue) {
   8271           ALOGV(" new skinTone correction value : %d ", skinToneValue);
   8272           mSkinToneEnhancement = skinToneValue;
   8273           mParameters.set("skinToneEnhancement", skinToneValue);
   8274           bool ret = native_set_parms(CAMERA_PARM_SCE_FACTOR, sizeof(mSkinToneEnhancement),
   8275                         (void *)&mSkinToneEnhancement);
   8276           return ret ? NO_ERROR : UNKNOWN_ERROR;
   8277     }
   8278     return NO_ERROR;
   8279 }
   8280 
   8281 status_t QualcommCameraHardware::setWhiteBalance(const QCameraParameters& params)
   8282 {
   8283     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_WHITE_BALANCE)) {
   8284         ALOGI("WhiteBalance not supported for this sensor");
   8285         return NO_ERROR;
   8286     }
   8287 
   8288     int result;
   8289 
   8290     const char *str = params.get(QCameraParameters::KEY_WHITE_BALANCE);
   8291     if (str != NULL) {
   8292         int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
   8293         if (value != NOT_FOUND) {
   8294             mParameters.set(QCameraParameters::KEY_WHITE_BALANCE, str);
   8295             bool ret = native_set_parms(CAMERA_PARM_WHITE_BALANCE, sizeof(value),
   8296                                        (void *)&value, (int *)&result);
   8297             if(result == MM_CAMERA_ERR_INVALID_OPERATION) {
   8298                 ALOGI("WhiteBalance Value: %s is not set as the selected value is not supported ", str);
   8299             }
   8300             return ret ? NO_ERROR : UNKNOWN_ERROR;
   8301         }
   8302     }
   8303         ALOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
   8304         return BAD_VALUE;
   8305 
   8306 }
   8307 
   8308 status_t QualcommCameraHardware::setFlash(const QCameraParameters& params)
   8309 {
   8310     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_LED_MODE)) {
   8311         ALOGI("%s: flash not supported", __FUNCTION__);
   8312         return NO_ERROR;
   8313     }
   8314 
   8315     const char *str = params.get(QCameraParameters::KEY_FLASH_MODE);
   8316     if (str != NULL) {
   8317         int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
   8318         if (value != NOT_FOUND) {
   8319             mParameters.set(QCameraParameters::KEY_FLASH_MODE, str);
   8320             bool ret = native_set_parms(CAMERA_PARM_LED_MODE,
   8321                                        sizeof(value), (void *)&value);
   8322             if(mZslEnable && (value != LED_MODE_OFF)){
   8323                     mParameters.set("num-snaps-per-shutter", "1");
   8324                     ALOGI("%s Setting num-snaps-per-shutter to 1", __FUNCTION__);
   8325                     numCapture = 1;
   8326             }
   8327             return ret ? NO_ERROR : UNKNOWN_ERROR;
   8328         }
   8329     }
   8330     ALOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
   8331     return BAD_VALUE;
   8332 }
   8333 
   8334 status_t QualcommCameraHardware::setAntibanding(const QCameraParameters& params)
   8335 {
   8336     int result;
   8337     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ANTIBANDING)) {
   8338         ALOGI("Parameter AntiBanding is not supported for this sensor");
   8339         return NO_ERROR;
   8340     }
   8341     const char *str = params.get(QCameraParameters::KEY_ANTIBANDING);
   8342     if (str != NULL) {
   8343         int value = (camera_antibanding_type)attr_lookup(
   8344           antibanding, sizeof(antibanding) / sizeof(str_map), str);
   8345         if (value != NOT_FOUND) {
   8346             camera_antibanding_type temp = (camera_antibanding_type) value;
   8347             mParameters.set(QCameraParameters::KEY_ANTIBANDING, str);
   8348             bool ret = native_set_parms(CAMERA_PARM_ANTIBANDING,
   8349                        sizeof(camera_antibanding_type), (void *)&temp ,(int *)&result);
   8350             if(result == MM_CAMERA_ERR_INVALID_OPERATION) {
   8351                 ALOGI("AntiBanding Value: %s is not supported for the given BestShot Mode", str);
   8352             }
   8353             return ret ? NO_ERROR : UNKNOWN_ERROR;
   8354         }
   8355     }
   8356     ALOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
   8357     return BAD_VALUE;
   8358 }
   8359 
   8360 status_t QualcommCameraHardware::setMCEValue(const QCameraParameters& params)
   8361 {
   8362     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_MCE)) {
   8363         ALOGI("Parameter MCE is not supported for this sensor");
   8364         return NO_ERROR;
   8365     }
   8366 
   8367     const char *str = params.get(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT);
   8368     if (str != NULL) {
   8369         int value = attr_lookup(mce, sizeof(mce) / sizeof(str_map), str);
   8370         if (value != NOT_FOUND) {
   8371             int8_t temp = (int8_t)value;
   8372             ALOGI("%s: setting MCE value of %s", __FUNCTION__, str);
   8373             mParameters.set(QCameraParameters::KEY_MEMORY_COLOR_ENHANCEMENT, str);
   8374 
   8375             native_set_parms(CAMERA_PARM_MCE, sizeof(int8_t), (void *)&temp);
   8376             return NO_ERROR;
   8377         }
   8378     }
   8379     ALOGE("Invalid MCE value: %s", (str == NULL) ? "NULL" : str);
   8380     return BAD_VALUE;
   8381 }
   8382 
   8383 status_t QualcommCameraHardware::setHighFrameRate(const QCameraParameters& params)
   8384 {
   8385     if((!mCfgControl.mm_camera_is_supported(CAMERA_PARM_HFR)) || (mIs3DModeOn)) {
   8386         ALOGI("Parameter HFR is not supported for this sensor");
   8387         return NO_ERROR;
   8388     }
   8389 
   8390     const char *str = params.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
   8391     if (str != NULL) {
   8392         int value = attr_lookup(hfr, sizeof(hfr) / sizeof(str_map), str);
   8393         if (value != NOT_FOUND) {
   8394             int32_t temp = (int32_t)value;
   8395             ALOGI("%s: setting HFR value of %s(%d)", __FUNCTION__, str, temp);
   8396             //Check for change in HFR value
   8397             const char *oldHfr = mParameters.get(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE);
   8398             if(strcmp(oldHfr, str)){
   8399                 ALOGI("%s: old HFR: %s, new HFR %s", __FUNCTION__, oldHfr, str);
   8400                 mParameters.set(QCameraParameters::KEY_VIDEO_HIGH_FRAME_RATE, str);
   8401                 mHFRMode = true;
   8402                 if(mCameraRunning == true) {
   8403                     mHFRThreadWaitLock.lock();
   8404                     pthread_attr_t pattr;
   8405                     pthread_attr_init(&pattr);
   8406                     pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
   8407                     mHFRThreadRunning = !pthread_create(&mHFRThread,
   8408                                       &pattr,
   8409                                       hfr_thread,
   8410                                       (void*)NULL);
   8411                     mHFRThreadWaitLock.unlock();
   8412                     return NO_ERROR;
   8413                 }
   8414             }
   8415             native_set_parms(CAMERA_PARM_HFR, sizeof(int32_t), (void *)&temp);
   8416             return NO_ERROR;
   8417         }
   8418     }
   8419     ALOGE("Invalid HFR value: %s", (str == NULL) ? "NULL" : str);
   8420     return BAD_VALUE;
   8421 }
   8422 
   8423 status_t QualcommCameraHardware::setHDRImaging(const QCameraParameters& params)
   8424 {
   8425     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_HDR) && mZslEnable) {
   8426         ALOGI("Parameter HDR is not supported for this sensor/ ZSL mode");
   8427         return NO_ERROR;
   8428     }
   8429     const char *str = params.get(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING);
   8430     if (str != NULL) {
   8431         int value = attr_lookup(hdr, sizeof(hdr) / sizeof(str_map), str);
   8432         if (value != NOT_FOUND) {
   8433             exp_bracketing_t temp;
   8434             memset(&temp, 0, sizeof(temp));
   8435             temp.hdr_enable= (int32_t)value;
   8436             temp.mode = HDR_MODE;
   8437             temp.total_frames = 3;
   8438             temp.total_hal_frames = HDR_HAL_FRAME;
   8439             mHdrMode = temp.hdr_enable;
   8440             ALOGI("%s: setting HDR value of %s", __FUNCTION__, str);
   8441             mParameters.set(QCameraParameters::KEY_HIGH_DYNAMIC_RANGE_IMAGING, str);
   8442             if(mHdrMode){
   8443                 numCapture = temp.total_hal_frames;
   8444             } else
   8445                 numCapture = 1;
   8446             native_set_parms(CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
   8447             return NO_ERROR;
   8448         }
   8449     }
   8450     ALOGE("Invalid HDR value: %s", (str == NULL) ? "NULL" : str);
   8451     return BAD_VALUE;
   8452 }
   8453 
   8454 status_t QualcommCameraHardware::setExpBracketing(const QCameraParameters& params)
   8455 {
   8456     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_HDR) && mZslEnable) {
   8457         ALOGI("Parameter Exposure Bracketing is not supported for this sensor/ZSL mode");
   8458         return NO_ERROR;
   8459     }
   8460     const char *str = params.get("capture-burst-exposures");
   8461     if ((str != NULL) && (!mHdrMode)) {
   8462         char  exp_val[MAX_EXP_BRACKETING_LENGTH];
   8463         exp_bracketing_t temp;
   8464         memset(&temp, 0, sizeof(temp));
   8465 
   8466         mExpBracketMode = true;
   8467         temp.mode = EXP_BRACKETING_MODE;
   8468         temp.hdr_enable = true;
   8469         /* App sets values separated by comma.
   8470            Thus total number of snapshot to capture is strlen(str)/2
   8471            eg: "-1,1,2" */
   8472         strlcpy(exp_val, str, sizeof(exp_val));
   8473         temp.total_frames = (strlen(exp_val) >  MAX_SNAPSHOT_BUFFERS -2) ?
   8474             MAX_SNAPSHOT_BUFFERS -2 : strlen(exp_val);
   8475         temp.total_hal_frames = temp.total_frames;
   8476         strlcpy(temp.values, exp_val, MAX_EXP_BRACKETING_LENGTH);
   8477         ALOGI("%s: setting Exposure Bracketing value of %s", __FUNCTION__, temp.values);
   8478         mParameters.set("capture-burst-exposures", str);
   8479         if(!mZslEnable){
   8480             numCapture = temp.total_frames;
   8481         }
   8482         native_set_parms(CAMERA_PARM_HDR, sizeof(exp_bracketing_t), (void *)&temp);
   8483         return NO_ERROR;
   8484     } else
   8485         mExpBracketMode = false;
   8486     return NO_ERROR;
   8487 }
   8488 
   8489 status_t QualcommCameraHardware::setLensshadeValue(const QCameraParameters& params)
   8490 {
   8491     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ROLLOFF)) {
   8492         ALOGI("Parameter Rolloff is not supported for this sensor");
   8493         return NO_ERROR;
   8494     }
   8495 
   8496     const char *str = params.get(QCameraParameters::KEY_LENSSHADE);
   8497     if (str != NULL) {
   8498         int value = attr_lookup(lensshade,
   8499                                     sizeof(lensshade) / sizeof(str_map), str);
   8500         if (value != NOT_FOUND) {
   8501             int8_t temp = (int8_t)value;
   8502             mParameters.set(QCameraParameters::KEY_LENSSHADE, str);
   8503 
   8504             native_set_parms(CAMERA_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
   8505             return NO_ERROR;
   8506         }
   8507     }
   8508     ALOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
   8509     return NO_ERROR;
   8510 }
   8511 
   8512 status_t QualcommCameraHardware::setSelectableZoneAf(const QCameraParameters& params)
   8513 {
   8514     if(mHasAutoFocusSupport && supportsSelectableZoneAf()) {
   8515         const char *str = params.get(QCameraParameters::KEY_SELECTABLE_ZONE_AF);
   8516         if (str != NULL) {
   8517             int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str);
   8518             if (value != NOT_FOUND) {
   8519                 mParameters.set(QCameraParameters::KEY_SELECTABLE_ZONE_AF, str);
   8520                 bool ret = native_set_parms(CAMERA_PARM_FOCUS_RECT, sizeof(value),
   8521                         (void *)&value);
   8522                 return ret ? NO_ERROR : UNKNOWN_ERROR;
   8523             }
   8524         }
   8525         ALOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str);
   8526         return BAD_VALUE;
   8527     }
   8528     return NO_ERROR;
   8529 }
   8530 
   8531 status_t QualcommCameraHardware::setTouchAfAec(const QCameraParameters& params)
   8532 {
   8533     ALOGV("%s",__func__);
   8534     if(mHasAutoFocusSupport){
   8535         int xAec, yAec, xAf, yAf;
   8536         int cx, cy;
   8537         int width, height;
   8538         params.getMeteringAreaCenter(&cx, &cy);
   8539         mParameters.getPreviewSize(&width, &height);
   8540 
   8541         // @Punit
   8542         // The coords sent from upper layer is in range (-1000, -1000) to (1000, 1000)
   8543         // So, they are transformed to range (0, 0) to (previewWidth, previewHeight)
   8544         cx = cx + 1000;
   8545         cy = cy + 1000;
   8546         cx = cx * (width / 2000.0f);
   8547         cy = cy * (height / 2000.0f);
   8548 
   8549         //Negative values are invalid and does not update anything
   8550         ALOGV("Touch Area Center (cx, cy) = (%d, %d)", cx, cy);
   8551 
   8552         //Currently using same values for AF and AEC
   8553         xAec = cx; yAec = cy;
   8554         xAf = cx; yAf = cy;
   8555 
   8556         const char *str = params.get(QCameraParameters::KEY_TOUCH_AF_AEC);
   8557         if (str != NULL) {
   8558             int value = attr_lookup(touchafaec,
   8559                     sizeof(touchafaec) / sizeof(str_map), str);
   8560             if (value != NOT_FOUND) {
   8561 
   8562                 //Dx,Dy will be same as defined in res/layout/camera.xml
   8563                 //passed down to HAL in a key.value pair.
   8564                 int FOCUS_RECTANGLE_DX = params.getInt("touchAfAec-dx");
   8565                 int FOCUS_RECTANGLE_DY = params.getInt("touchAfAec-dy");
   8566                 mParameters.set(QCameraParameters::KEY_TOUCH_AF_AEC, str);
   8567                 mParameters.setTouchIndexAec(xAec, yAec);
   8568                 mParameters.setTouchIndexAf(xAf, yAf);
   8569 
   8570                 cam_set_aec_roi_t aec_roi_value;
   8571                 roi_info_t af_roi_value;
   8572 
   8573                 memset(&af_roi_value, 0, sizeof(roi_info_t));
   8574 
   8575                 //If touch AF/AEC is enabled and touch event has occured then
   8576                 //call the ioctl with valid values.
   8577                 if (value == true
   8578                         && (xAec >= 0 && yAec >= 0)
   8579                         && (xAf >= 0 && yAf >= 0)) {
   8580                     //Set Touch AEC params (Pass the center co-ordinate)
   8581                     aec_roi_value.aec_roi_enable = AEC_ROI_ON;
   8582                     aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
   8583                     aec_roi_value.aec_roi_position.coordinate.x = xAec;
   8584                     aec_roi_value.aec_roi_position.coordinate.y = yAec;
   8585 
   8586                     //Set Touch AF params (Pass the top left co-ordinate)
   8587                     af_roi_value.num_roi = 1;
   8588                     if ((xAf-(FOCUS_RECTANGLE_DX/2)) < 0)
   8589                         af_roi_value.roi[0].x = 1;
   8590                     else
   8591                         af_roi_value.roi[0].x = xAf - (FOCUS_RECTANGLE_DX/2);
   8592 
   8593                     if ((yAf-(FOCUS_RECTANGLE_DY/2)) < 0)
   8594                         af_roi_value.roi[0].y = 1;
   8595                     else
   8596                         af_roi_value.roi[0].y = yAf - (FOCUS_RECTANGLE_DY/2);
   8597 
   8598                     af_roi_value.roi[0].dx = FOCUS_RECTANGLE_DX;
   8599                     af_roi_value.roi[0].dy = FOCUS_RECTANGLE_DY;
   8600                     af_roi_value.is_multiwindow = mMultiTouch;
   8601                     native_set_parms(CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value);
   8602                     native_set_parms(CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value);
   8603                 }
   8604                 else if(value == false) {
   8605                     //Set Touch AEC params
   8606                     aec_roi_value.aec_roi_enable = AEC_ROI_OFF;
   8607                     aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
   8608                     aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE;
   8609                     aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE;
   8610 
   8611                     //Set Touch AF params
   8612                     af_roi_value.num_roi = 0;
   8613                     native_set_parms(CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value);
   8614                     native_set_parms(CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value);
   8615                 }
   8616                 //@Punit: If the values are negative, we dont send anything to the lower layer
   8617             }
   8618             return NO_ERROR;
   8619         }
   8620         ALOGE("Invalid Touch AF/AEC value: %s", (str == NULL) ? "NULL" : str);
   8621         return BAD_VALUE;
   8622     }
   8623     return NO_ERROR;
   8624 }
   8625 
   8626 status_t QualcommCameraHardware::setFaceDetection(const char *str)
   8627 {
   8628     if(supportsFaceDetection() == false){
   8629         ALOGI("Face detection is not enabled");
   8630         return NO_ERROR;
   8631     }
   8632     if (str != NULL) {
   8633         int value = attr_lookup(facedetection,
   8634                                     sizeof(facedetection) / sizeof(str_map), str);
   8635         if (value != NOT_FOUND) {
   8636             mMetaDataWaitLock.lock();
   8637             mFaceDetectOn = value;
   8638             mMetaDataWaitLock.unlock();
   8639             mParameters.set(QCameraParameters::KEY_FACE_DETECTION, str);
   8640             return NO_ERROR;
   8641         }
   8642     }
   8643     ALOGE("Invalid Face Detection value: %s", (str == NULL) ? "NULL" : str);
   8644     return BAD_VALUE;
   8645 }
   8646 
   8647 status_t QualcommCameraHardware::setRedeyeReduction(const QCameraParameters& params)
   8648 {
   8649     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_REDEYE_REDUCTION)) {
   8650         ALOGI("Parameter Redeye Reduction is not supported for this sensor");
   8651         return NO_ERROR;
   8652     }
   8653 
   8654     const char *str = params.get(QCameraParameters::KEY_REDEYE_REDUCTION);
   8655     if (str != NULL) {
   8656         int value = attr_lookup(redeye_reduction, sizeof(redeye_reduction) / sizeof(str_map), str);
   8657         if (value != NOT_FOUND) {
   8658             int8_t temp = (int8_t)value;
   8659             ALOGI("%s: setting Redeye Reduction value of %s", __FUNCTION__, str);
   8660             mParameters.set(QCameraParameters::KEY_REDEYE_REDUCTION, str);
   8661 
   8662             native_set_parms(CAMERA_PARM_REDEYE_REDUCTION, sizeof(int8_t), (void *)&temp);
   8663             return NO_ERROR;
   8664         }
   8665     }
   8666     ALOGE("Invalid Redeye Reduction value: %s", (str == NULL) ? "NULL" : str);
   8667     return BAD_VALUE;
   8668 }
   8669 
   8670 status_t  QualcommCameraHardware::setISOValue(const QCameraParameters& params) {
   8671     int8_t temp_hjr;
   8672     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ISO)) {
   8673             ALOGI("Parameter ISO Value is not supported for this sensor");
   8674             return NO_ERROR;
   8675         }
   8676     const char *str = params.get(QCameraParameters::KEY_ISO_MODE);
   8677     if (str != NULL) {
   8678         int value = (camera_iso_mode_type)attr_lookup(
   8679           iso, sizeof(iso) / sizeof(str_map), str);
   8680         if (value != NOT_FOUND) {
   8681             camera_iso_mode_type temp = (camera_iso_mode_type) value;
   8682             if (value == CAMERA_ISO_DEBLUR) {
   8683                temp_hjr = true;
   8684                native_set_parms(CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
   8685                mHJR = value;
   8686             }
   8687             else {
   8688                if (mHJR == CAMERA_ISO_DEBLUR) {
   8689                    temp_hjr = false;
   8690                    native_set_parms(CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
   8691                    mHJR = value;
   8692                }
   8693             }
   8694 
   8695             mParameters.set(QCameraParameters::KEY_ISO_MODE, str);
   8696             native_set_parms(CAMERA_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
   8697             return NO_ERROR;
   8698         }
   8699     }
   8700     ALOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
   8701     return BAD_VALUE;
   8702 }
   8703 
   8704 status_t QualcommCameraHardware::setSceneDetect(const QCameraParameters& params)
   8705 {
   8706     bool retParm1, retParm2;
   8707     if (supportsSceneDetection()) {
   8708         if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BL_DETECTION) && !mCfgControl.mm_camera_is_supported(CAMERA_PARM_SNOW_DETECTION)) {
   8709             ALOGI("Parameter Auto Scene Detection is not supported for this sensor");
   8710             return NO_ERROR;
   8711         }
   8712         const char *str = params.get(QCameraParameters::KEY_SCENE_DETECT);
   8713         if (str != NULL) {
   8714             int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str);
   8715             if (value != NOT_FOUND) {
   8716                 mParameters.set(QCameraParameters::KEY_SCENE_DETECT, str);
   8717 
   8718                 retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value),
   8719                                            (void *)&value);
   8720 
   8721                 retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value),
   8722                                            (void *)&value);
   8723 
   8724                 //All Auto Scene detection modes should be all ON or all OFF.
   8725                 if(retParm1 == false || retParm2 == false) {
   8726                     value = !value;
   8727                     retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value),
   8728                                                (void *)&value);
   8729 
   8730                     retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value),
   8731                                                (void *)&value);
   8732                 }
   8733                 return (retParm1 && retParm2) ? NO_ERROR : UNKNOWN_ERROR;
   8734             }
   8735         }
   8736     ALOGE("Invalid auto scene detection value: %s", (str == NULL) ? "NULL" : str);
   8737     return BAD_VALUE;
   8738     }
   8739     return NO_ERROR;
   8740 }
   8741 
   8742 status_t QualcommCameraHardware::setSceneMode(const QCameraParameters& params)
   8743 {
   8744     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BESTSHOT_MODE)) {
   8745         ALOGI("Parameter Scenemode is not supported for this sensor");
   8746         return NO_ERROR;
   8747     }
   8748 
   8749     const char *str = params.get(QCameraParameters::KEY_SCENE_MODE);
   8750 
   8751     if (str != NULL) {
   8752         int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
   8753         int32_t asd_val;
   8754         if (value != NOT_FOUND) {
   8755             mParameters.set(QCameraParameters::KEY_SCENE_MODE, str);
   8756             bool ret = native_set_parms(CAMERA_PARM_BESTSHOT_MODE, sizeof(value),
   8757                                        (void *)&value);
   8758 
   8759             if (ret == NO_ERROR) {
   8760               int retParm1,  retParm2;
   8761               /*if value is auto, set ASD on, else set ASD off*/
   8762               if (value == CAMERA_BESTSHOT_AUTO ) {
   8763                 asd_val = TRUE;
   8764               } else {
   8765                 asd_val = FALSE;
   8766               }
   8767 
   8768               /*note: we need to simplify this logic by using a single ctrl as in 8960*/
   8769               retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value),
   8770                                          (void *)&asd_val);
   8771               retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value),
   8772                                          (void *)&asd_val);
   8773             }
   8774             return ret ? NO_ERROR : UNKNOWN_ERROR;
   8775         }
   8776     }
   8777     ALOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str);
   8778     return BAD_VALUE;
   8779 }
   8780 status_t QualcommCameraHardware::setGpsLocation(const QCameraParameters& params)
   8781 {
   8782     const char *method = params.get(QCameraParameters::KEY_GPS_PROCESSING_METHOD);
   8783     if (method) {
   8784         mParameters.set(QCameraParameters::KEY_GPS_PROCESSING_METHOD, method);
   8785     }else {
   8786          mParameters.remove(QCameraParameters::KEY_GPS_PROCESSING_METHOD);
   8787     }
   8788 
   8789     const char *latitude = params.get(QCameraParameters::KEY_GPS_LATITUDE);
   8790     if (latitude) {
   8791         ALOGI("latitude %s",latitude);
   8792         mParameters.set(QCameraParameters::KEY_GPS_LATITUDE, latitude);
   8793     }else {
   8794          mParameters.remove(QCameraParameters::KEY_GPS_LATITUDE);
   8795     }
   8796 
   8797     const char *latitudeRef = params.get(QCameraParameters::KEY_GPS_LATITUDE_REF);
   8798     if (latitudeRef) {
   8799         mParameters.set(QCameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
   8800     }else {
   8801          mParameters.remove(QCameraParameters::KEY_GPS_LATITUDE_REF);
   8802     }
   8803 
   8804     const char *longitude = params.get(QCameraParameters::KEY_GPS_LONGITUDE);
   8805     if (longitude) {
   8806         mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE, longitude);
   8807     }else {
   8808          mParameters.remove(QCameraParameters::KEY_GPS_LONGITUDE);
   8809     }
   8810 
   8811     const char *longitudeRef = params.get(QCameraParameters::KEY_GPS_LONGITUDE_REF);
   8812     if (longitudeRef) {
   8813         mParameters.set(QCameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
   8814     }else {
   8815          mParameters.remove(QCameraParameters::KEY_GPS_LONGITUDE_REF);
   8816     }
   8817 
   8818     const char *altitudeRef = params.get(QCameraParameters::KEY_GPS_ALTITUDE_REF);
   8819     if (altitudeRef) {
   8820         mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
   8821     }else {
   8822          mParameters.remove(QCameraParameters::KEY_GPS_ALTITUDE_REF);
   8823     }
   8824 
   8825     const char *altitude = params.get(QCameraParameters::KEY_GPS_ALTITUDE);
   8826     if (altitude) {
   8827         mParameters.set(QCameraParameters::KEY_GPS_ALTITUDE, altitude);
   8828     }else {
   8829          mParameters.remove(QCameraParameters::KEY_GPS_ALTITUDE);
   8830     }
   8831 
   8832     const char *status = params.get(QCameraParameters::KEY_GPS_STATUS);
   8833     if (status) {
   8834         mParameters.set(QCameraParameters::KEY_GPS_STATUS, status);
   8835     }
   8836 
   8837     const char *dateTime = params.get(QCameraParameters::KEY_EXIF_DATETIME);
   8838     if (dateTime) {
   8839         mParameters.set(QCameraParameters::KEY_EXIF_DATETIME, dateTime);
   8840     }else {
   8841          mParameters.remove(QCameraParameters::KEY_EXIF_DATETIME);
   8842     }
   8843 
   8844     const char *timestamp = params.get(QCameraParameters::KEY_GPS_TIMESTAMP);
   8845     if (timestamp) {
   8846         mParameters.set(QCameraParameters::KEY_GPS_TIMESTAMP, timestamp);
   8847     }else {
   8848          mParameters.remove(QCameraParameters::KEY_GPS_TIMESTAMP);
   8849     }
   8850 
   8851     return NO_ERROR;
   8852 
   8853 }
   8854 
   8855 status_t QualcommCameraHardware::setRotation(const QCameraParameters& params)
   8856 {
   8857     status_t rc = NO_ERROR;
   8858     int sensor_mount_angle = HAL_cameraInfo[HAL_currentCameraId].sensor_mount_angle;
   8859     int rotation = params.getInt(QCameraParameters::KEY_ROTATION);
   8860     if (rotation != NOT_FOUND) {
   8861         if (rotation == 0 || rotation == 90 || rotation == 180
   8862             || rotation == 270) {
   8863           rotation = (rotation + sensor_mount_angle)%360;
   8864           mParameters.set(QCameraParameters::KEY_ROTATION, rotation);
   8865           mRotation = rotation;
   8866         } else {
   8867             ALOGE("Invalid rotation value: %d", rotation);
   8868             rc = BAD_VALUE;
   8869         }
   8870     }
   8871     return rc;
   8872 }
   8873 
   8874 status_t QualcommCameraHardware::setZoom(const QCameraParameters& params)
   8875 {
   8876     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ZOOM)) {
   8877         ALOGI("Parameter setZoom is not supported for this sensor");
   8878         return NO_ERROR;
   8879     }
   8880     status_t rc = NO_ERROR;
   8881     // No matter how many different zoom values the driver can provide, HAL
   8882     // provides applictations the same number of zoom levels. The maximum driver
   8883     // zoom value depends on sensor output (VFE input) and preview size (VFE
   8884     // output) because VFE can only crop and cannot upscale. If the preview size
   8885     // is bigger, the maximum zoom ratio is smaller. However, we want the
   8886     // zoom ratio of each zoom level is always the same whatever the preview
   8887     // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
   8888     // we need to have a fixed maximum zoom value and do read it from the
   8889     // driver.
   8890     static const int ZOOM_STEP = 1;
   8891     int32_t zoom_level = params.getInt("zoom");
   8892     if(zoom_level >= 0 && zoom_level <= mMaxZoom-1) {
   8893         mParameters.set("zoom", zoom_level);
   8894         int32_t zoom_value = ZOOM_STEP * zoom_level;
   8895         bool ret = native_set_parms(CAMERA_PARM_ZOOM,
   8896             sizeof(zoom_value), (void *)&zoom_value);
   8897         rc = ret ? NO_ERROR : UNKNOWN_ERROR;
   8898     } else {
   8899         rc = BAD_VALUE;
   8900     }
   8901 
   8902     return rc;
   8903 }
   8904 
   8905 status_t QualcommCameraHardware::setDenoise(const QCameraParameters& params)
   8906 {
   8907     if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_WAVELET_DENOISE)) {
   8908         ALOGI("Wavelet Denoise is not supported for this sensor");
   8909         return NO_ERROR;
   8910     }
   8911     const char *str = params.get(QCameraParameters::KEY_DENOISE);
   8912     if (str != NULL) {
   8913         int value = attr_lookup(denoise,
   8914         sizeof(denoise) / sizeof(str_map), str);
   8915         if ((value != NOT_FOUND) &&  (mDenoiseValue != value)) {
   8916         mDenoiseValue =  value;
   8917         mParameters.set(QCameraParameters::KEY_DENOISE, str);
   8918         bool ret = native_set_parms(CAMERA_PARM_WAVELET_DENOISE, sizeof(value),
   8919                                                (void *)&value);
   8920         return ret ? NO_ERROR : UNKNOWN_ERROR;
   8921         }
   8922         return NO_ERROR;
   8923     }
   8924     ALOGE("Invalid Denoise value: %s", (str == NULL) ? "NULL" : str);
   8925     return BAD_VALUE;
   8926 }
   8927 
   8928 status_t QualcommCameraHardware::setZslParam(const QCameraParameters& params)
   8929 {
   8930     if(!mZslEnable) {
   8931         ALOGV("Zsl is not enabled");
   8932         return NO_ERROR;
   8933     }
   8934     /* This ensures that restart of Preview doesnt happen when taking
   8935      * Snapshot for continuous viewfinder */
   8936     const char *str = params.get("continuous-temporal-bracketing");
   8937     if(str !=NULL) {
   8938         if(!strncmp(str, "enable", 8))
   8939             mZslPanorama = true;
   8940         else
   8941             mZslPanorama = false;
   8942         return NO_ERROR;
   8943     }
   8944     mZslPanorama = false;
   8945     return NO_ERROR;
   8946 
   8947 }
   8948 
   8949 status_t QualcommCameraHardware::setSnapshotCount(const QCameraParameters& params)
   8950 {
   8951     int value;
   8952     char snapshotCount[5];
   8953     if(!mZslEnable){
   8954         value = numCapture;
   8955     } else {
   8956         /* ZSL case: Get value from App */
   8957         const char *str = params.get("num-snaps-per-shutter");
   8958         if (str != NULL) {
   8959             value = atoi(str);
   8960         } else
   8961             value = 1;
   8962     }
   8963     /* Sanity check */
   8964     if(value > MAX_SNAPSHOT_BUFFERS -2)
   8965         value = MAX_SNAPSHOT_BUFFERS -2;
   8966     else if(value < 1)
   8967         value = 1;
   8968     snprintf(snapshotCount, sizeof(snapshotCount),"%d",value);
   8969     numCapture = value;
   8970     mParameters.set("num-snaps-per-shutter", snapshotCount);
   8971     ALOGI("%s setting num-snaps-per-shutter to %s", __FUNCTION__, snapshotCount);
   8972     return NO_ERROR;
   8973 
   8974 }
   8975 
   8976 status_t QualcommCameraHardware::updateFocusDistances(const char *focusmode)
   8977 {
   8978     ALOGV("%s: IN", __FUNCTION__);
   8979     focus_distances_info_t focusDistances;
   8980     if( mCfgControl.mm_camera_get_parm(CAMERA_PARM_FOCUS_DISTANCES,
   8981         (void *)&focusDistances) == MM_CAMERA_SUCCESS) {
   8982         String8 str;
   8983         char buffer[32];
   8984         snprintf(buffer, sizeof(buffer), "%f", focusDistances.focus_distance[0]);
   8985         str.append(buffer);
   8986         snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[1]);
   8987         str.append(buffer);
   8988         if(strcmp(focusmode, QCameraParameters::FOCUS_MODE_INFINITY) == 0)
   8989             snprintf(buffer, sizeof(buffer), ",%s", "Infinity");
   8990         else
   8991             snprintf(buffer, sizeof(buffer), ",%f", focusDistances.focus_distance[2]);
   8992         str.append(buffer);
   8993         ALOGI("%s: setting KEY_FOCUS_DISTANCES as %s", __FUNCTION__, str.string());
   8994         mParameters.set(QCameraParameters::KEY_FOCUS_DISTANCES, str.string());
   8995         return NO_ERROR;
   8996     }
   8997     ALOGE("%s: get CAMERA_PARM_FOCUS_DISTANCES failed!!!", __FUNCTION__);
   8998     return BAD_VALUE;
   8999 }
   9000 
   9001 status_t QualcommCameraHardware::setMeteringAreas(const QCameraParameters& params)
   9002 {
   9003     const char *str = params.get(QCameraParameters::KEY_METERING_AREAS);
   9004     if (str == NULL || (strcmp(str, "0") == 0)) {
   9005         ALOGE("%s: Parameter string is null", __FUNCTION__);
   9006     }
   9007     else {
   9008         // handling default string
   9009         if ((strcmp("(-2000,-2000,-2000,-2000,0)", str) == 0) ||
   9010             (strcmp("(0,0,0,0,0)", str) == 0)){
   9011           mParameters.set(QCameraParameters::KEY_METERING_AREAS, NULL);
   9012           return NO_ERROR;
   9013         }
   9014         if(checkAreaParameters(str) != 0) {
   9015           ALOGE("%s: Failed to parse the input string '%s'", __FUNCTION__, str);
   9016           return BAD_VALUE;
   9017         }
   9018         mParameters.set(QCameraParameters::KEY_METERING_AREAS, str);
   9019     }
   9020 
   9021     return NO_ERROR;
   9022 }
   9023 
   9024 status_t QualcommCameraHardware::setFocusAreas(const QCameraParameters& params)
   9025 {
   9026     const char *str = params.get(QCameraParameters::KEY_FOCUS_AREAS);
   9027 
   9028     if (str == NULL || (strcmp(str, "0") == 0)) {
   9029         ALOGE("%s: Parameter string is null", __FUNCTION__);
   9030     }
   9031     else {
   9032         // handling default string
   9033         if ((strcmp("(-2000,-2000,-2000,-2000,0)", str) == 0) ||
   9034             (strcmp("(0,0,0,0,0)", str) == 0)) {
   9035           mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, NULL);
   9036           return NO_ERROR;
   9037         }
   9038 
   9039         if(checkAreaParameters(str) != 0) {
   9040           ALOGE("%s: Failed to parse the input string '%s'", __FUNCTION__, str);
   9041           return BAD_VALUE;
   9042         }
   9043 
   9044         mParameters.set(QCameraParameters::KEY_FOCUS_AREAS, str);
   9045     }
   9046 
   9047     return NO_ERROR;
   9048 }
   9049 status_t QualcommCameraHardware::setFocusMode(const QCameraParameters& params)
   9050 {
   9051     const char *str = params.get(QCameraParameters::KEY_FOCUS_MODE);
   9052     if (str != NULL) {
   9053       ALOGI("FocusMode =%s", str);
   9054         int32_t value = attr_lookup(focus_modes,
   9055                                     sizeof(focus_modes) / sizeof(str_map), str);
   9056         if (value != NOT_FOUND) {
   9057             mParameters.set(QCameraParameters::KEY_FOCUS_MODE, str);
   9058 
   9059             if(mHasAutoFocusSupport && (updateFocusDistances(str) != NO_ERROR)) {
   9060                 ALOGE("%s: updateFocusDistances failed for %s", __FUNCTION__, str);
   9061                 return UNKNOWN_ERROR;
   9062             }
   9063 
   9064             if(mHasAutoFocusSupport){
   9065                 int cafSupport = FALSE;
   9066                 if(!strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ||
   9067                    !strcmp(str, QCameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)){
   9068                     cafSupport = TRUE;
   9069                 }
   9070                 ALOGV("Continuous Auto Focus %d", cafSupport);
   9071                 native_set_parms(CAMERA_PARM_CONTINUOUS_AF, sizeof(int8_t), (void *)&cafSupport);
   9072             }
   9073             // Focus step is reset to infinity when preview is started. We do
   9074             // not need to do anything now.
   9075             return NO_ERROR;
   9076         }
   9077     }
   9078     ALOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
   9079     return BAD_VALUE;
   9080 
   9081 }
   9082 QualcommCameraHardware::DispMemPool::DispMemPool(int fd, int buffer_size,
   9083                                                int num_buffers, int frame_size,
   9084                                                const char *name) :
   9085     QualcommCameraHardware::MemPool(buffer_size,
   9086                                     num_buffers,
   9087                                     frame_size,
   9088                                     name),
   9089     mFD(fd)
   9090 {
   9091 #if 0
   9092     ALOGV("constructing MemPool %s from gralloc memory: "
   9093          "%d frames @ %d size "
   9094          "buffer size %d",
   9095          mName,
   9096          num_buffers, frame_size, buffer_size);
   9097     /* Use the fd given by gralloc and ask MemoryHeapBase to map it
   9098      * in this process space */
   9099     mHeap = new MemoryHeapBase(mFD, buffer_size, MemoryHeapBase::NO_CACHING, 0);
   9100     completeInitialization();
   9101 #endif
   9102 }
   9103 
   9104 QualcommCameraHardware::DispMemPool::~DispMemPool()
   9105 {
   9106     /* Not much to do in destructor for now */
   9107     ALOGV(" ~DispMemPool : E ");
   9108     mFD = -1;
   9109     ALOGV(" ~DispMemPool : X ");
   9110 }
   9111 status_t QualcommCameraHardware::setOrientation(const QCameraParameters& params)
   9112 {
   9113     const char *str = params.get("orientation");
   9114 
   9115     if (str != NULL) {
   9116         if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
   9117             // Camera service needs this to decide if the preview frames and raw
   9118             // pictures should be rotated.
   9119             mParameters.set("orientation", str);
   9120         } else {
   9121             ALOGE("Invalid orientation value: %s", str);
   9122             return BAD_VALUE;
   9123         }
   9124     }
   9125     return NO_ERROR;
   9126 }
   9127 
   9128 status_t QualcommCameraHardware::setPictureFormat(const QCameraParameters& params)
   9129 {
   9130     const char * str = params.get(QCameraParameters::KEY_PICTURE_FORMAT);
   9131 
   9132     if(str != NULL){
   9133         int32_t value = attr_lookup(picture_formats,
   9134                                     sizeof(picture_formats) / sizeof(str_map), str);
   9135         if(value != NOT_FOUND){
   9136             mParameters.set(QCameraParameters::KEY_PICTURE_FORMAT, str);
   9137         } else {
   9138             ALOGE("Invalid Picture Format value: %s", str);
   9139             return BAD_VALUE;
   9140         }
   9141     }
   9142     return NO_ERROR;
   9143 }
   9144 
   9145 QualcommCameraHardware::MMCameraDL::MMCameraDL(){
   9146     ALOGV("MMCameraDL: E");
   9147     libmmcamera = NULL;
   9148 #if DLOPEN_LIBMMCAMERA
   9149     libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
   9150 #endif
   9151     ALOGV("Open MM camera DL libeomcamera loaded at %p ", libmmcamera);
   9152     ALOGV("MMCameraDL: X");
   9153 }
   9154 
   9155 void * QualcommCameraHardware::MMCameraDL::pointer(){
   9156     return libmmcamera;
   9157 }
   9158 
   9159 QualcommCameraHardware::MMCameraDL::~MMCameraDL(){
   9160     ALOGV("~MMCameraDL: E");
   9161     LINK_mm_camera_destroy();
   9162     if (libmmcamera != NULL) {
   9163         ::dlclose(libmmcamera);
   9164         ALOGV("closed MM Camera DL ");
   9165     }
   9166     libmmcamera = NULL;
   9167     ALOGV("~MMCameraDL: X");
   9168 }
   9169 
   9170 wp<QualcommCameraHardware::MMCameraDL> QualcommCameraHardware::MMCameraDL::instance;
   9171 Mutex QualcommCameraHardware::MMCameraDL::singletonLock;
   9172 
   9173 
   9174 sp<QualcommCameraHardware::MMCameraDL> QualcommCameraHardware::MMCameraDL::getInstance(){
   9175     Mutex::Autolock instanceLock(singletonLock);
   9176     sp<MMCameraDL> mmCamera = instance.promote();
   9177     if(mmCamera == NULL){
   9178         mmCamera = new MMCameraDL();
   9179         instance = mmCamera;
   9180     }
   9181     return mmCamera;
   9182 }
   9183 
   9184 QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
   9185                                          int frame_size,
   9186                                          const char *name) :
   9187     mBufferSize(buffer_size),
   9188     mNumBuffers(num_buffers),
   9189     mFrameSize(frame_size),
   9190     mBuffers(NULL), mName(name)
   9191 {
   9192     int page_size_minus_1 = getpagesize() - 1;
   9193     mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
   9194 }
   9195 
   9196 void QualcommCameraHardware::MemPool::completeInitialization()
   9197 {
   9198     // If we do not know how big the frame will be, we wait to allocate
   9199     // the buffers describing the individual frames until we do know their
   9200     // size.
   9201 
   9202     if (mFrameSize > 0) {
   9203 	    ALOGI("Before new Mem BASE #buffers :%d",mNumBuffers);
   9204         mBuffers = new sp<MemoryBase>[mNumBuffers];
   9205         for (int i = 0; i < mNumBuffers; i++) {
   9206             mBuffers[i] = new
   9207                 MemoryBase(mHeap,
   9208                            i * mAlignedBufferSize,
   9209                            mFrameSize);
   9210         }
   9211     }
   9212 }
   9213 
   9214 QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
   9215                                                int frame_size,
   9216                                                const char *name) :
   9217     QualcommCameraHardware::MemPool(buffer_size,
   9218                                     num_buffers,
   9219                                     frame_size,
   9220                                     name)
   9221 {
   9222     ALOGV("constructing MemPool %s backed by ashmem: "
   9223          "%d frames @ %d uint8_ts, "
   9224          "buffer size %d",
   9225          mName,
   9226          num_buffers, frame_size, buffer_size);
   9227 
   9228     int page_mask = getpagesize() - 1;
   9229     int ashmem_size = buffer_size * num_buffers;
   9230     ashmem_size += page_mask;
   9231     ashmem_size &= ~page_mask;
   9232 
   9233     mHeap = new MemoryHeapBase(ashmem_size);
   9234 
   9235     completeInitialization();
   9236 }
   9237 
   9238 bool QualcommCameraHardware::register_record_buffers(bool register_buffer) {
   9239     ALOGI("%s: (%d) E", __FUNCTION__, register_buffer);
   9240     struct msm_pmem_info pmemBuf;
   9241 #if 0
   9242     for (int cnt = 0; cnt < kRecordBufferCount; ++cnt) {
   9243         pmemBuf.type     = MSM_PMEM_VIDEO;
   9244         pmemBuf.fd       = mRecordHeap->mHeap->getHeapID();
   9245         pmemBuf.offset   = mRecordHeap->mAlignedBufferSize * cnt;
   9246         pmemBuf.len      = mRecordHeap->mBufferSize;
   9247         pmemBuf.vaddr    = (uint8_t *)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
   9248         pmemBuf.planar0_off    = 0;
   9249         pmemBuf.planar1_off = recordframes[0].planar1_off;
   9250         pmemBuf.planar2_off = 0;
   9251         if(register_buffer == true) {
   9252             pmemBuf.active   = (cnt<ACTIVE_VIDEO_BUFFERS);
   9253             if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
   9254                 pmemBuf.type = MSM_PMEM_VIDEO_VPE;
   9255                 pmemBuf.active = 1;
   9256             }
   9257         } else {
   9258             pmemBuf.active   = false;
   9259         }
   9260 
   9261         ALOGV("register_buf:  reg = %d buffer = %p", !register_buffer,
   9262           (void *)pmemBuf.vaddr);
   9263         if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER :
   9264                 CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) {
   9265             ALOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM  error %s",
   9266                 strerror(errno));
   9267             return false;
   9268         }
   9269     }
   9270 #endif
   9271     return true;
   9272 }
   9273 
   9274 QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
   9275                                            int flags,
   9276                                            int pmem_type,
   9277                                            int buffer_size, int num_buffers,
   9278                                            int frame_size, int cbcr_offset,
   9279                                            int yOffset, const char *name) :
   9280     QualcommCameraHardware::MemPool(buffer_size,
   9281                                     num_buffers,
   9282                                     frame_size,
   9283                                     name),
   9284     mPmemType(pmem_type),
   9285     mCbCrOffset(cbcr_offset),
   9286     myOffset(yOffset)
   9287 {
   9288     bool all_chnls = false;
   9289     ALOGI("constructing MemPool %s backed by pmem pool %s: "
   9290          "%d frames @ %d bytes, buffer size %d",
   9291          mName,
   9292          pmem_pool, num_buffers, frame_size,
   9293          buffer_size);
   9294 
   9295     mMMCameraDLRef = QualcommCameraHardware::MMCameraDL::getInstance();
   9296 
   9297 
   9298     // Make a new mmap'ed heap that can be shared across processes.
   9299     // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
   9300     mAlignedSize = mAlignedBufferSize * num_buffers;
   9301 
   9302     sp<MemoryHeapBase> masterHeap =
   9303         new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
   9304 
   9305     if (masterHeap->getHeapID() < 0) {
   9306         ALOGE("failed to construct master heap for pmem pool %s", pmem_pool);
   9307         masterHeap.clear();
   9308         return;
   9309     }
   9310 
   9311     sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
   9312     if (pmemHeap->getHeapID() >= 0) {
   9313         pmemHeap->slap();
   9314         masterHeap.clear();
   9315         mHeap = pmemHeap;
   9316         pmemHeap.clear();
   9317 
   9318         mFd = mHeap->getHeapID();
   9319         if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
   9320             ALOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
   9321                  pmem_pool,
   9322                  ::strerror(errno), errno);
   9323             mHeap.clear();
   9324             return;
   9325         }
   9326 
   9327         ALOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
   9328              pmem_pool,
   9329              mFd,
   9330              mSize.len);
   9331         ALOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
   9332         // Unregister preview buffers with the camera drivers.  Allow the VFE to write
   9333         // to all preview buffers except for the last one.
   9334         // Only Register the preview, snapshot and thumbnail buffers with the kernel.
   9335         if( (strcmp("postview", mName) != 0) ){
   9336             int num_buf = num_buffers;
   9337             if(!strcmp("preview", mName)) num_buf = kTotalPreviewBufferCount;
   9338             ALOGD("num_buffers = %d", num_buf);
   9339             for (int cnt = 0; cnt < num_buf; ++cnt) {
   9340                 int active = 1;
   9341                 if(pmem_type == MSM_PMEM_VIDEO){
   9342                      active = (cnt<ACTIVE_VIDEO_BUFFERS);
   9343                      //When VPE is enabled, set the last record
   9344                      //buffer as active and pmem type as PMEM_VIDEO_VPE
   9345                      //as this is a requirement from VPE operation.
   9346                      //No need to set this pmem type to VIDEO_VPE while unregistering,
   9347                      //because as per camera stack design: "the VPE AXI is also configured
   9348                      //when VFE is configured for VIDEO, which is as part of preview
   9349                      //initialization/start. So during this VPE AXI config camera stack
   9350                      //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and
   9351                      //change it's type to PMEM_VIDEO".
   9352                      if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
   9353                          active = 1;
   9354                          pmem_type = MSM_PMEM_VIDEO_VPE;
   9355                      }
   9356                      ALOGV(" pmempool creating video buffers : active %d ", active);
   9357                 }
   9358                 else if (pmem_type == MSM_PMEM_PREVIEW){
   9359                     active = (cnt < ACTIVE_PREVIEW_BUFFERS);
   9360                 }
   9361                 else if ((pmem_type == MSM_PMEM_MAINIMG)
   9362                      || (pmem_type == MSM_PMEM_THUMBNAIL)){
   9363                     active = (cnt < ACTIVE_ZSL_BUFFERS);
   9364                 }
   9365                  if (pmem_type == MSM_PMEM_PREVIEW &&
   9366                        mPreviewFormat == CAMERA_YUV_420_YV12 && mCurrentTarget != TARGET_MSM7627A)
   9367                        all_chnls = true;
   9368 
   9369                 register_buf(mBufferSize,
   9370                          mFrameSize, mCbCrOffset, myOffset,
   9371                          mHeap->getHeapID(),
   9372                          mAlignedBufferSize * cnt,
   9373                          (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
   9374                          pmem_type,
   9375                          active,true,
   9376                          all_chnls);
   9377             }
   9378         }
   9379 
   9380         completeInitialization();
   9381     }
   9382     else ALOGE("pmem pool %s error: could not create master heap!",
   9383               pmem_pool);
   9384     ALOGV("%s: (%s) X ", __FUNCTION__, mName);
   9385 }
   9386 
   9387 QualcommCameraHardware::PmemPool::~PmemPool()
   9388 {
   9389     ALOGI("%s: %s E", __FUNCTION__, mName);
   9390     if (mHeap != NULL) {
   9391         // Unregister preview buffers with the camera drivers.
   9392         //  Only Unregister the preview, snapshot and thumbnail
   9393         //  buffers with the kernel.
   9394         if( (strcmp("postview", mName) != 0) ){
   9395             int num_buffers = mNumBuffers;
   9396             if(!strcmp("preview", mName)) num_buffers = kTotalPreviewBufferCount;
   9397             for (int cnt = 0; cnt < num_buffers; ++cnt) {
   9398                 register_buf(mBufferSize,
   9399                          mFrameSize,
   9400                          mCbCrOffset,
   9401                          myOffset,
   9402                          mHeap->getHeapID(),
   9403                          mAlignedBufferSize * cnt,
   9404                          (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
   9405                          mPmemType,
   9406                          false,
   9407                          false,/* unregister */
   9408                          false);
   9409             }
   9410         }
   9411     }
   9412     mMMCameraDLRef.clear();
   9413     ALOGI("%s: %s X", __FUNCTION__, mName);
   9414 }
   9415 #if 0
   9416 #ifdef USE_ION
   9417 const char QualcommCameraHardware::IonPool::mIonDevName[] = "/dev/ion";
   9418 QualcommCameraHardware::IonPool::IonPool(int ion_heap_id, int flags,
   9419                                            int ion_type,
   9420                                            int buffer_size, int num_buffers,
   9421                                            int frame_size, int cbcr_offset,
   9422                                            int yOffset, const char *name) :
   9423     QualcommCameraHardware::MemPool(buffer_size,
   9424                                     num_buffers,
   9425                                     frame_size,
   9426                                     name),
   9427     mIonType(ion_type),
   9428     mCbCrOffset(cbcr_offset),
   9429     myOffset(yOffset)
   9430 {
   9431     ALOGI("constructing MemPool %s backed by pmem pool %s: "
   9432          "%d frames @ %d bytes, buffer size %d",
   9433          mName,
   9434          mIonDevName, num_buffers, frame_size,
   9435          buffer_size);
   9436 
   9437     mMMCameraDLRef = QualcommCameraHardware::MMCameraDL::getInstance();
   9438 
   9439 
   9440     // Make a new mmap'ed heap that can be shared across processes.
   9441     // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
   9442     mAlignedSize = mAlignedBufferSize * num_buffers;
   9443     sp<MemoryHeapIon> ionHeap = new MemoryHeapIon(mIonDevName, mAlignedSize,
   9444                                                   flags, 0x1<<ion_heap_id);
   9445     if (ionHeap->getHeapID() >= 0) {
   9446         mHeap = ionHeap;
   9447         ionHeap.clear();
   9448 
   9449         mFd = mHeap->getHeapID();
   9450         ALOGE("ion pool %s fd = %d", mIonDevName, mFd);
   9451         ALOGE("mBufferSize=%d, mAlignedBufferSize=%d\n",
   9452                       mBufferSize, mAlignedBufferSize);
   9453 
   9454         // Unregister preview buffers with the camera drivers.  Allow the VFE to write
   9455         // to all preview buffers except for the last one.
   9456         // Only Register the preview, snapshot and thumbnail buffers with the kernel.
   9457         if( (strcmp("postview", mName) != 0) ){
   9458             int num_buf = num_buffers;
   9459             if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount;
   9460             ALOGD("num_buffers = %d", num_buf);
   9461             for (int cnt = 0; cnt < num_buf; ++cnt) {
   9462                 int active = 1;
   9463                 if(ion_type == MSM_PMEM_VIDEO){
   9464                      active = (cnt<ACTIVE_VIDEO_BUFFERS);
   9465                      //When VPE is enabled, set the last record
   9466                      //buffer as active and pmem type as PMEM_VIDEO_VPE
   9467                      //as this is a requirement from VPE operation.
   9468                      //No need to set this pmem type to VIDEO_VPE while unregistering,
   9469                      //because as per camera stack design: "the VPE AXI is also configured
   9470                      //when VFE is configured for VIDEO, which is as part of preview
   9471                      //initialization/start. So during this VPE AXI config camera stack
   9472                      //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and
   9473                      //change it's type to PMEM_VIDEO".
   9474                      if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
   9475                          active = 1;
   9476                          ion_type = MSM_PMEM_VIDEO_VPE;
   9477                      }
   9478                      ALOGV(" pmempool creating video buffers : active %d ", active);
   9479                 }
   9480                 else if (ion_type == MSM_PMEM_PREVIEW){
   9481                     active = (cnt < ACTIVE_PREVIEW_BUFFERS);
   9482                 }
   9483                 else if ((ion_type == MSM_PMEM_MAINIMG)
   9484                      || (ion_type == MSM_PMEM_THUMBNAIL)){
   9485                     active = (cnt < ACTIVE_ZSL_BUFFERS);
   9486                 }
   9487                 register_buf(mBufferSize,
   9488                          mFrameSize, mCbCrOffset, myOffset,
   9489                          mHeap->getHeapID(),
   9490                          mAlignedBufferSize * cnt,
   9491                          (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
   9492                          ion_type,
   9493                          active);
   9494             }
   9495         }
   9496 
   9497         completeInitialization();
   9498     }
   9499     else ALOGE("pmem pool %s error: could not create master heap!",
   9500               mIonDevName);
   9501     ALOGI("%s: (%s) X ", __FUNCTION__, mName);
   9502 }
   9503 
   9504 QualcommCameraHardware::IonPool::~IonPool()
   9505 {
   9506     ALOGI("%s: %s E", __FUNCTION__, mName);
   9507     if (mHeap != NULL) {
   9508         // Unregister preview buffers with the camera drivers.
   9509         //  Only Unregister the preview, snapshot and thumbnail
   9510         //  buffers with the kernel.
   9511         if( (strcmp("postview", mName) != 0) ){
   9512             int num_buffers = mNumBuffers;
   9513             if(!strcmp("preview", mName)) num_buffers = kPreviewBufferCount;
   9514             for (int cnt = 0; cnt < num_buffers; ++cnt) {
   9515                 register_buf(mBufferSize,
   9516                          mFrameSize,
   9517                          mCbCrOffset,
   9518                          myOffset,
   9519                          mHeap->getHeapID(),
   9520                          mAlignedBufferSize * cnt,
   9521                          (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
   9522                          mIonType,
   9523                          false,
   9524                          false /* unregister */);
   9525             }
   9526         }
   9527     }
   9528     mMMCameraDLRef.clear();
   9529     ALOGI("%s: %s X", __FUNCTION__, mName);
   9530 }
   9531 #endif
   9532 #endif
   9533 QualcommCameraHardware::MemPool::~MemPool()
   9534 {
   9535     ALOGV("destroying MemPool %s", mName);
   9536     if (mFrameSize > 0)
   9537         delete [] mBuffers;
   9538     mHeap.clear();
   9539     ALOGV("destroying MemPool %s completed", mName);
   9540 }
   9541 
   9542 status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
   9543 {
   9544     const size_t SIZE = 256;
   9545     char buffer[SIZE];
   9546     String8 result;
   9547     CAMERA_HAL_UNUSED(args);
   9548     snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
   9549     result.append(buffer);
   9550     if (mName) {
   9551         snprintf(buffer, 255, "mem pool name (%s)\n", mName);
   9552         result.append(buffer);
   9553     }
   9554     if (mHeap != 0) {
   9555         snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
   9556                  mHeap->getBase(), mHeap->getSize(),
   9557                  mHeap->getFlags(), mHeap->getDevice());
   9558         result.append(buffer);
   9559     }
   9560     snprintf(buffer, 255,
   9561              "buffer size (%d), number of buffers (%d), frame size(%d)",
   9562              mBufferSize, mNumBuffers, mFrameSize);
   9563     result.append(buffer);
   9564     write(fd, result.string(), result.size());
   9565     return NO_ERROR;
   9566 }
   9567 
   9568 static void receive_camframe_callback(struct msm_frame *frame)
   9569 {
   9570     QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9571     if (obj != 0) {
   9572         obj->receivePreviewFrame(frame);
   9573     }
   9574 }
   9575 
   9576 static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo)
   9577 {
   9578     QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9579     if (obj != 0) {
   9580         obj->receiveCameraStats(stype,histinfo);
   9581     }
   9582 }
   9583 
   9584 static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size)
   9585 {
   9586     if(status == LIVESHOT_SUCCESS) {
   9587         QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9588         if (obj != 0) {
   9589             obj->receiveLiveSnapshot(jpeg_size);
   9590         }
   9591     }
   9592     else
   9593         ALOGE("Liveshot not succesful");
   9594 }
   9595 
   9596 
   9597 static int8_t receive_event_callback(mm_camera_event* event)
   9598 {
   9599     ALOGV("%s: E", __FUNCTION__);
   9600     if(event == NULL) {
   9601         ALOGE("%s: event is NULL!", __FUNCTION__);
   9602         return FALSE;
   9603     }
   9604     switch(event->event_type) {
   9605         case SNAPSHOT_DONE:
   9606         {
   9607             /* postview buffer is received */
   9608             QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9609             if (obj != 0) {
   9610 
   9611                 obj->receiveRawPicture(NO_ERROR, event->event_data.yuv_frames[0], event->event_data.yuv_frames[0]);
   9612             }
   9613         }
   9614         break;
   9615         case SNAPSHOT_FAILED:
   9616         {
   9617             /* postview buffer is received */
   9618             QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9619             if (obj != 0) {
   9620 
   9621                 obj->receiveRawPicture(UNKNOWN_ERROR, NULL, NULL);
   9622             }
   9623         }
   9624         break;
   9625         case JPEG_ENC_DONE:
   9626         {
   9627             QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9628             if (obj != 0) {
   9629                 obj->receiveJpegPicture(NO_ERROR, event->event_data.encoded_frame);
   9630             }
   9631         }
   9632         break;
   9633         case JPEG_ENC_FAILED:
   9634         {
   9635             QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9636             if (obj != 0) {
   9637                 obj->receiveJpegPicture(UNKNOWN_ERROR, 0);
   9638             }
   9639         }
   9640         break;
   9641         default:
   9642             ALOGE("%s: ignore default case", __FUNCTION__);
   9643     }
   9644     return TRUE;
   9645     ALOGV("%s: X", __FUNCTION__);
   9646 }
   9647 // 720p : video frame calbback from camframe
   9648 static void receive_camframe_video_callback(struct msm_frame *frame)
   9649 {
   9650     ALOGV("receive_camframe_video_callback E");
   9651     QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9652     if (obj != 0) {
   9653             obj->receiveRecordingFrame(frame);
   9654          }
   9655     ALOGV("receive_camframe_video_callback X");
   9656 }
   9657 
   9658 
   9659 int QualcommCameraHardware::storeMetaDataInBuffers(int enable)
   9660 {
   9661         /* this is a dummy func now. fix me later */
   9662     ALOGI("in storeMetaDataInBuffers : enable %d", enable);
   9663     mStoreMetaDataInFrame = enable;
   9664     return 0;
   9665 }
   9666 
   9667 void QualcommCameraHardware::setCallbacks(camera_notify_callback notify_cb,
   9668                              camera_data_callback data_cb,
   9669                              camera_data_timestamp_callback data_cb_timestamp,
   9670                              camera_request_memory get_memory,
   9671                              void* user)
   9672 {
   9673     Mutex::Autolock lock(mLock);
   9674     mNotifyCallback = notify_cb;
   9675     mDataCallback = data_cb;
   9676     mDataCallbackTimestamp = data_cb_timestamp;
   9677 	mGetMemory = get_memory;
   9678     mCallbackCookie = user;
   9679 }
   9680 int32_t QualcommCameraHardware::getNumberOfVideoBuffers() {
   9681     ALOGI("getNumOfVideoBuffers: %d", kRecordBufferCount);
   9682     return kRecordBufferCount;
   9683 }
   9684 
   9685 sp<IMemory> QualcommCameraHardware::getVideoBuffer(int32_t index) {
   9686    if(index > kRecordBufferCount)
   9687      return NULL;
   9688    else
   9689      return NULL;
   9690 #if 0
   9691         return  mRecordHeap->mBuffers[index];
   9692 #endif
   9693 }
   9694 void QualcommCameraHardware::enableMsgType(int32_t msgType)
   9695 {
   9696     Mutex::Autolock lock(mLock);
   9697     mMsgEnabled |= msgType;
   9698     if( (mCurrentTarget != TARGET_MSM7630 ) &&  (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
   9699       if(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME){
   9700         native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
   9701         mRecordingState = 1;
   9702       }
   9703     }
   9704 }
   9705 
   9706 void QualcommCameraHardware::disableMsgType(int32_t msgType)
   9707 {
   9708     Mutex::Autolock lock(mLock);
   9709     if( (mCurrentTarget != TARGET_MSM7630 ) &&  (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
   9710       if(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME){
   9711         native_stop_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
   9712         mRecordingState = 0;
   9713       }
   9714     }
   9715     mMsgEnabled &= ~msgType;
   9716 }
   9717 
   9718 bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
   9719 {
   9720     return (mMsgEnabled & msgType);
   9721 }
   9722 
   9723 
   9724 void QualcommCameraHardware::receive_camframe_error_timeout(void) {
   9725     ALOGI("receive_camframe_error_timeout: E");
   9726     Mutex::Autolock l(&mCamframeTimeoutLock);
   9727     ALOGE(" Camframe timed out. Not receiving any frames from camera driver ");
   9728     camframe_timeout_flag = TRUE;
   9729     mNotifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_UNKNOWN, 0,
   9730                     mCallbackCookie);
   9731     ALOGI("receive_camframe_error_timeout: X");
   9732 }
   9733 
   9734 static void receive_camframe_error_callback(camera_error_type err) {
   9735     QualcommCameraHardware* obj = QualcommCameraHardware::getInstance();
   9736     if (obj != 0) {
   9737         if ((err == CAMERA_ERROR_TIMEOUT) ||
   9738             (err == CAMERA_ERROR_ESD)) {
   9739             /* Handling different error types is dependent on the requirement.
   9740              * Do the same action by default
   9741              */
   9742             obj->receive_camframe_error_timeout();
   9743         }
   9744     }
   9745 }
   9746 
   9747 bool QualcommCameraHardware::storePreviewFrameForPostview(void) {
   9748     ALOGV("storePreviewFrameForPostview : E ");
   9749 
   9750     /* Since there is restriction on the maximum overlay dimensions
   9751      * that can be created, we use the last preview frame as postview
   9752      * for 7x30. */
   9753     ALOGV("Copying the preview buffer to postview buffer %d  ",
   9754          mPreviewFrameSize);
   9755     if(mLastPreviewFrameHeap == NULL) {
   9756         int CbCrOffset = PAD_TO_WORD(mPreviewFrameSize * 2/3);
   9757 #if 0
   9758 #ifdef USE_ION
   9759 
   9760         mLastPreviewFrameHeap =
   9761            new IonPool(ION_HEAP_ADSP_ID,
   9762            MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   9763            MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
   9764            mPreviewFrameSize,
   9765            1,
   9766            mPreviewFrameSize,
   9767            CbCrOffset,
   9768            0,
   9769            "postview");
   9770 #else
   9771         mLastPreviewFrameHeap =
   9772            new PmemPool("/dev/pmem_adsp",
   9773            MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
   9774            MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
   9775            mPreviewFrameSize,
   9776            1,
   9777            mPreviewFrameSize,
   9778            CbCrOffset,
   9779            0,
   9780            "postview");
   9781 #endif
   9782            if (!mLastPreviewFrameHeap->initialized()) {
   9783                mLastPreviewFrameHeap.clear();
   9784                ALOGE(" Failed to initialize Postview Heap");
   9785                return false;
   9786             }
   9787 #endif
   9788     }
   9789 #if 0
   9790     if( mLastPreviewFrameHeap != NULL && mLastQueuedFrame != NULL) {
   9791         memcpy(mLastPreviewFrameHeap->mHeap->base(),
   9792                (uint8_t *)mLastQueuedFrame, mPreviewFrameSize );
   9793 
   9794         if(mUseOverlay && !mZslPanorama) {
   9795             //mOverlayLock.lock();
   9796             //if(mOverlay != NULL){
   9797                 //mOverlay->setFd(mLastPreviewFrameHeap->mHeap->getHeapID());
   9798                 if( zoomCropInfo.w !=0 && zoomCropInfo.h !=0) {
   9799                     ALOGE("zoomCropInfo non-zero, setting crop ");
   9800                     ALOGE("setCrop with %dx%d and %dx%d", zoomCropInfo.x, zoomCropInfo.y, zoomCropInfo.w, zoomCropInfo.h);
   9801                    // mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
   9802                                //zoomCropInfo.w, zoomCropInfo.h);
   9803                 }
   9804                 ALOGV("Queueing Postview with last frame till the snapshot is done ");
   9805                 //mOverlay->queueBuffer((void *)0);
   9806             }
   9807             //mOverlayLock.unlock();
   9808         }
   9809 
   9810     } else
   9811         ALOGE("Failed to store Preview frame. No Postview ");
   9812 #endif
   9813     ALOGV("storePreviewFrameForPostview : X ");
   9814     return true;
   9815 }
   9816 
   9817 bool QualcommCameraHardware::isValidDimension(int width, int height) {
   9818     bool retVal = FALSE;
   9819     /* This function checks if a given resolution is valid or not.
   9820      * A particular resolution is considered valid if it satisfies
   9821      * the following conditions:
   9822      * 1. width & height should be multiple of 16.
   9823      * 2. width & height should be less than/equal to the dimensions
   9824      *    supported by the camera sensor.
   9825      * 3. the aspect ratio is a valid aspect ratio and is among the
   9826      *    commonly used aspect ratio as determined by the thumbnail_sizes
   9827      *    data structure.
   9828      */
   9829 
   9830     if( (width == CEILING16(width)) && (height == CEILING16(height))
   9831      && (width <= maxSnapshotWidth)
   9832     && (height <= maxSnapshotHeight) )
   9833     {
   9834         uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height);
   9835         for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) {
   9836             if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) {
   9837                 retVal = TRUE;
   9838                 break;
   9839             }
   9840         }
   9841     }
   9842     return retVal;
   9843 }
   9844 status_t QualcommCameraHardware::getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize) {
   9845     status_t ret;
   9846     ALOGV(" getBufferInfo : E ");
   9847     if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660) )
   9848     {
   9849     if( mRecordHeap != NULL){
   9850         ALOGV(" Setting valid buffer information ");
   9851         Frame = mRecordHeap->mBuffers[0];
   9852         if( alignedSize != NULL) {
   9853             *alignedSize = mRecordHeap->mAlignedBufferSize;
   9854             ALOGV(" HAL : alignedSize = %d ", *alignedSize);
   9855             ret = NO_ERROR;
   9856         } else {
   9857                 ALOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
   9858                 ret = UNKNOWN_ERROR;
   9859         }
   9860         } else {
   9861         ALOGE(" RecordHeap is null. Buffer information wont be updated ");
   9862         Frame = NULL;
   9863         ret = UNKNOWN_ERROR;
   9864     }
   9865     } else {
   9866     if(mPreviewHeap != NULL) {
   9867         ALOGV(" Setting valid buffer information ");
   9868        // Frame = mPreviewHeap->mBuffers[0];
   9869         if( alignedSize != NULL) {
   9870             //*alignedSize = mPreviewHeap->mAlignedBufferSize;
   9871                 ALOGV(" HAL : alignedSize = %d ", *alignedSize);
   9872                 ret = NO_ERROR;
   9873             } else {
   9874                 ALOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
   9875                 ret = UNKNOWN_ERROR;
   9876             }
   9877     } else {
   9878             ALOGE(" PreviewHeap is null. Buffer information wont be updated ");
   9879             Frame = NULL;
   9880             ret = UNKNOWN_ERROR;
   9881     }
   9882     }
   9883     ALOGV(" getBufferInfo : X ");
   9884     return ret;
   9885 }
   9886 
   9887 void QualcommCameraHardware::encodeData() {
   9888     ALOGV("encodeData: E");
   9889 
   9890     if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
   9891         mJpegThreadWaitLock.lock();
   9892             mJpegThreadRunning = true;
   9893             mJpegThreadWaitLock.unlock();
   9894             mm_camera_ops_type_t current_ops_type = CAMERA_OPS_ENCODE;
   9895             mCamOps.mm_camera_start(current_ops_type,(void *)&mImageCaptureParms,
   9896                                      (void *)&mImageEncodeParms);
   9897             //Wait until jpeg encoding is done and clear the resources.
   9898             mJpegThreadWaitLock.lock();
   9899             while (mJpegThreadRunning) {
   9900                 ALOGV("encodeData: waiting for jpeg thread to complete.");
   9901                 mJpegThreadWait.wait(mJpegThreadWaitLock);
   9902                 ALOGV("encodeData: jpeg thread completed.");
   9903             }
   9904             mJpegThreadWaitLock.unlock();
   9905     }
   9906     else ALOGV("encodeData: JPEG callback is NULL, not encoding image.");
   9907 
   9908     mCamOps.mm_camera_deinit(CAMERA_OPS_CAPTURE, NULL, NULL);
   9909     //clear the resources
   9910     deinitRaw();
   9911     //Encoding is done.
   9912     mEncodePendingWaitLock.lock();
   9913     mEncodePending = false;
   9914     mEncodePendingWait.signal();
   9915     mEncodePendingWaitLock.unlock();
   9916 
   9917     ALOGV("encodeData: X");
   9918 }
   9919 
   9920 void QualcommCameraHardware::getCameraInfo()
   9921 {
   9922     ALOGI("getCameraInfo: IN");
   9923     mm_camera_status_t status;
   9924 
   9925 #if DLOPEN_LIBMMCAMERA
   9926     void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
   9927     ALOGI("getCameraInfo: loading libqcamera at %p", libhandle);
   9928     if (!libhandle) {
   9929         ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
   9930     }
   9931     *(void **)&LINK_mm_camera_get_camera_info =
   9932         ::dlsym(libhandle, "mm_camera_get_camera_info");
   9933 #endif
   9934     storeTargetType();
   9935     status = LINK_mm_camera_get_camera_info(HAL_cameraInfo, &HAL_numOfCameras);
   9936     ALOGI("getCameraInfo: numOfCameras = %d", HAL_numOfCameras);
   9937     for(int i = 0; i < HAL_numOfCameras; i++) {
   9938         if((HAL_cameraInfo[i].position == BACK_CAMERA )&&
   9939             mCurrentTarget == TARGET_MSM8660){
   9940             HAL_cameraInfo[i].modes_supported |= CAMERA_ZSL_MODE;
   9941         } else{
   9942             HAL_cameraInfo[i].modes_supported |= CAMERA_NONZSL_MODE;
   9943         }
   9944         ALOGI("Camera sensor %d info:", i);
   9945         ALOGI("camera_id: %d", HAL_cameraInfo[i].camera_id);
   9946         ALOGI("modes_supported: %x", HAL_cameraInfo[i].modes_supported);
   9947         ALOGI("position: %d", HAL_cameraInfo[i].position);
   9948         ALOGI("sensor_mount_angle: %d", HAL_cameraInfo[i].sensor_mount_angle);
   9949     }
   9950 
   9951 #if DLOPEN_LIBMMCAMERA
   9952     if (libhandle) {
   9953         ::dlclose(libhandle);
   9954         ALOGV("getCameraInfo: dlclose(libqcamera)");
   9955     }
   9956 #endif
   9957     ALOGI("getCameraInfo: OUT");
   9958 }
   9959 
   9960 extern "C" int HAL_isIn3DMode()
   9961 {
   9962     return HAL_currentCameraMode == CAMERA_MODE_3D;
   9963 }
   9964 
   9965 extern "C" int HAL_getNumberOfCameras()
   9966 {
   9967     QualcommCameraHardware::getCameraInfo();
   9968     return HAL_numOfCameras;
   9969 }
   9970 
   9971 extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
   9972 {
   9973     int i;
   9974     char mDeviceName[PROPERTY_VALUE_MAX];
   9975     if(cameraInfo == NULL) {
   9976         ALOGE("cameraInfo is NULL");
   9977         return;
   9978     }
   9979 
   9980     property_get("ro.board.platform",mDeviceName," ");
   9981 
   9982     for(i = 0; i < HAL_numOfCameras; i++) {
   9983         if(i == cameraId) {
   9984             ALOGI("Found a matching camera info for ID %d", cameraId);
   9985             cameraInfo->facing = (HAL_cameraInfo[i].position == BACK_CAMERA)?
   9986                                    CAMERA_FACING_BACK : CAMERA_FACING_FRONT;
   9987             // App Orientation not needed for 7x27 , sensor mount angle 0 is
   9988             // enough.
   9989             if(cameraInfo->facing == CAMERA_FACING_FRONT)
   9990                 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
   9991             else if( !strncmp(mDeviceName, "msm7625a", 8))
   9992                 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
   9993             else if( !strncmp(mDeviceName, "msm7627a", 8))
   9994                 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
   9995             else if( !strncmp(mDeviceName, "msm7627", 7))
   9996                 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
   9997             else if( !strncmp(mDeviceName, "msm8660", 7))
   9998                 cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
   9999             else
   10000                 cameraInfo->orientation = ((APP_ORIENTATION - HAL_cameraInfo[i].sensor_mount_angle) + 360)%360;
   10001 
   10002             ALOGI("%s: orientation = %d", __FUNCTION__, cameraInfo->orientation);
   10003             sensor_rotation = HAL_cameraInfo[i].sensor_mount_angle;
   10004             cameraInfo->mode = 0;
   10005             if(HAL_cameraInfo[i].modes_supported & CAMERA_MODE_2D)
   10006                 cameraInfo->mode |= CAMERA_SUPPORT_MODE_2D;
   10007             if(HAL_cameraInfo[i].modes_supported & CAMERA_MODE_3D)
   10008                 cameraInfo->mode |= CAMERA_SUPPORT_MODE_3D;
   10009             if((HAL_cameraInfo[i].position == BACK_CAMERA )&&
   10010                 !strncmp(mDeviceName, "msm8660", 7)){
   10011                 cameraInfo->mode |= CAMERA_ZSL_MODE;
   10012             } else{
   10013                 cameraInfo->mode |= CAMERA_NONZSL_MODE;
   10014             }
   10015 
   10016             ALOGI("%s: modes supported = %d", __FUNCTION__, cameraInfo->mode);
   10017 
   10018             return;
   10019         }
   10020     }
   10021 //    ALOGE("Unable to find matching camera info for ID %d", cameraId);
   10022 }
   10023 
   10024 }; // namespace android
   10025