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, °rees, &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", ¶ms);
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