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