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