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