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