blob: 0c152be2c3d6341feb9ed7698a21e9755b25f70c [file] [log] [blame]
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001/*
2** Copyright 2008, Google Inc.
Apurva Rajguru08383852010-05-17 14:25:39 -07003** Copyright (c) 2009-2010 Code Aurora Forum. All rights reserved.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
Mohan Kandrabad0eaa2010-02-04 15:11:54 -080019#define LOG_NIDEBUG 0
Apurva Rajguruf0593dd2010-07-27 17:50:23 -070020
Priya Komarlingamb85535d2009-11-30 13:06:01 -080021#define LOG_TAG "QualcommCameraHardware"
22#include <utils/Log.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080023#include "QualcommCameraHardware.h"
24
25#include <utils/Errors.h>
26#include <utils/threads.h>
27#include <binder/MemoryHeapPmem.h>
28#include <utils/String16.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <unistd.h>
Sravankb4f5f1c2010-01-21 11:06:17 +053032#include <fcntl.h>
Apurva Rajguru8d1773b2009-12-02 14:21:23 -080033#include <cutils/properties.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080034#include <math.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080035#if HAVE_ANDROID_OS
36#include <linux/android_pmem.h>
37#endif
38#include <linux/ioctl.h>
Priya Komarlingam9bb2d492010-06-23 19:21:52 -070039#include <camera/CameraParameters.h>
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +053040#include <media/mediarecorder.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080041
Mohan Kandra284966d2010-01-05 13:39:15 -080042#include "linux/msm_mdp.h"
43#include <linux/fb.h>
44
Priya Komarlingamb85535d2009-11-30 13:06:01 -080045#define LIKELY(exp) __builtin_expect(!!(exp), 1)
46#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
47
48extern "C" {
49#include <fcntl.h>
50#include <time.h>
51#include <pthread.h>
52#include <stdio.h>
53#include <string.h>
54#include <unistd.h>
55#include <termios.h>
56#include <assert.h>
57#include <stdlib.h>
58#include <ctype.h>
59#include <signal.h>
60#include <errno.h>
61#include <sys/mman.h>
62#include <sys/system_properties.h>
63#include <sys/time.h>
64#include <stdlib.h>
65
66#include <media/msm_camera.h>
67
68#include <camera.h>
69#include <camframe.h>
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +053070#include <liveshot.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080071#include <mm-still/jpeg/jpege.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080072#include <jpeg_encoder.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080073
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +053074#define DUMP_LIVESHOT_JPEG_FILE 0
75
Nishant Pandit2eedc1b2010-09-25 04:47:39 +053076#define DEFAULT_PICTURE_WIDTH 640
77#define DEFAULT_PICTURE_HEIGHT 480
Priya Komarlingamb85535d2009-11-30 13:06:01 -080078#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
79#define MAX_ZOOM_LEVEL 5
80#define NOT_FOUND -1
Sravankb4f5f1c2010-01-21 11:06:17 +053081// Number of video buffers held by kernal (initially 1,2 &3)
82#define ACTIVE_VIDEO_BUFFERS 3
83
Nishant Panditc6fd2c22010-08-03 00:10:47 +053084#define PAD_TO_2K(x) (((x)+2047)& ~2047)
Nishant Panditbde07612010-07-28 00:16:28 +053085
Priya Komarlingamb85535d2009-11-30 13:06:01 -080086#if DLOPEN_LIBMMCAMERA
87#include <dlfcn.h>
88
89void* (*LINK_cam_conf)(void *data);
90void* (*LINK_cam_frame)(void *data);
91bool (*LINK_jpeg_encoder_init)();
92void (*LINK_jpeg_encoder_join)();
93bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
94 const uint8_t *thumbnailbuf, int thumbnailfd,
95 const uint8_t *snapshotbuf, int snapshotfd,
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080096 common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
Mohan Kandra1659b0c2010-07-18 16:36:25 -070097 int exif_table_numEntries, int jpegPadding, const int32_t cbcroffset);
Kiran Kumar H N7ac84e32010-02-01 10:58:47 -080098void (*LINK_camframe_terminate)(void);
Sravankb4f5f1c2010-01-21 11:06:17 +053099//for 720p
100// Function to add a video buffer to free Q
101void (*LINK_camframe_free_video)(struct msm_frame *frame);
102// Function pointer , called by camframe when a video frame is available.
103void (**LINK_camframe_video_callback)(struct msm_frame * frame);
104// To flush free Q in cam frame.
105void (*LINK_cam_frame_flush_free_video)(void);
106
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800107int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
108int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
109int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
Mohan Kandra02486042010-06-18 16:49:43 -0700110int8_t (*LINK_jpeg_encoder_get_buffer_offset)(uint32_t width, uint32_t height,
111 uint32_t* p_y_offset,
112 uint32_t* p_cbcr_offset,
113 uint32_t* p_buf_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800114int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
115const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
116int (*LINK_launch_cam_conf_thread)(void);
117int (*LINK_release_cam_conf_thread)(void);
Deepak Kurieneb58c682010-11-01 15:26:02 -0700118mm_camera_status_t (*LINK_mm_camera_init)(mm_camera_config *, mm_camera_notify*, mm_camera_ops*);
119mm_camera_status_t (*LINK_mm_camera_deinit)(mm_camera_config *, mm_camera_notify*, mm_camera_ops*);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800120int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
121 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
122
123// callbacks
124void (**LINK_mmcamera_camframe_callback)(struct msm_frame *frame);
Nishant Pandit741742b2010-09-21 03:24:20 +0530125void (**LINK_mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800126void (**LINK_mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
127 uint32_t buff_size);
128void (**LINK_mmcamera_jpeg_callback)(jpeg_event_t status);
129void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
Mohan Kandra3dd524f2010-09-20 13:41:42 -0700130void (**LINK_camframe_error_callback)(camera_error_type err);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530131void (**LINK_mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
132void (**LINK_cancel_liveshot)(void);
133int8_t (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data,
134 int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800135#else
136#define LINK_cam_conf cam_conf
137#define LINK_cam_frame cam_frame
138#define LINK_jpeg_encoder_init jpeg_encoder_init
139#define LINK_jpeg_encoder_join jpeg_encoder_join
140#define LINK_jpeg_encoder_encode jpeg_encoder_encode
141#define LINK_camframe_terminate camframe_terminate
142#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
143#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
144#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
Mohan Kandra02486042010-06-18 16:49:43 -0700145#define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800146#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
147#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
148#define LINK_launch_cam_conf_thread launch_cam_conf_thread
149#define LINK_release_cam_conf_thread release_cam_conf_thread
150#define LINK_zoom_crop_upscale zoom_crop_upscale
Deepak Kurieneb58c682010-11-01 15:26:02 -0700151#define LINK_mm_camera_init mm_camera_config_init
152#define LINK_mm_camera_deinit mm_camera_config_deinit
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800153extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
Nishant Pandit741742b2010-09-21 03:24:20 +0530154extern void (*mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800155extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
156 uint32_t buff_size);
157extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
158extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530159extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
160#define LINK_set_liveshot_params set_liveshot_params
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800161#endif
162
163} // extern "C"
164
165#ifndef HAVE_CAMERA_SIZE_TYPE
166struct camera_size_type {
167 int width;
168 int height;
169};
170#endif
171
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800172typedef struct crop_info_struct {
Mohan Kandra29834532010-10-14 16:12:44 -0700173 int32_t x;
174 int32_t y;
175 int32_t w;
176 int32_t h;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800177} zoom_crop_info;
178
Mohan Kandra740cfce2010-01-07 12:58:24 -0800179union zoomimage
Mohan Kandra284966d2010-01-05 13:39:15 -0800180{
181 char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
182 struct mdp_blit_req_list list;
183} zoomImage;
184
Nishant Pandit11282b52010-10-07 06:56:42 +0530185//Default to VGA
186#define DEFAULT_PREVIEW_WIDTH 640
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800187#define DEFAULT_PREVIEW_HEIGHT 480
188
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700189//Default FPS
190#define MINIMUM_FPS 5
Mohan Kandrae3077162010-10-05 17:01:25 -0700191#define MAXIMUM_FPS 31
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700192#define DEFAULT_FPS MAXIMUM_FPS
193
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800194/*
195 * Modifying preview size requires modification
196 * in bitmasks for boardproperties
197 */
198
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800199static const camera_size_type preview_sizes[] = {
Nishant Pandit2f7681e2010-08-18 02:44:54 +0530200 { 1920, 1088 }, //1080p
Srinivasan Kannanfa7edae2009-12-16 18:02:01 -0800201 { 1280, 720 }, // 720P, reserved
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800202 { 800, 480 }, // WVGA
Srinivasan Kannan613301c2010-02-10 17:08:53 -0800203 { 768, 432 },
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800204 { 720, 480 },
205 { 640, 480 }, // VGA
206 { 576, 432 },
207 { 480, 320 }, // HVGA
208 { 384, 288 },
209 { 352, 288 }, // CIF
210 { 320, 240 }, // QVGA
211 { 240, 160 }, // SQVGA
212 { 176, 144 }, // QCIF
213};
214#define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(camera_size_type))
215
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800216static camera_size_type supportedPreviewSizes[PREVIEW_SIZE_COUNT];
217static unsigned int previewSizeCount;
218
219board_property boardProperties[] = {
Apurva Rajgurue5965c42010-09-09 14:24:54 -0700220 {TARGET_MSM7625, 0x00000fff, false, false},
221 {TARGET_MSM7627, 0x000006ff, false, false},
222 {TARGET_MSM7630, 0x00000fff, true, true},
223 {TARGET_MSM8660, 0x00001fff, true, true},
224 {TARGET_QSD8250, 0x00000fff, false, false}
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800225};
226
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800227//static const camera_size_type* picture_sizes;
228//static int PICTURE_SIZE_COUNT;
229/* TODO
230 * Ideally this should be a populated by lower layers.
231 * But currently this is no API to do that at lower layer.
232 * Hence populating with default sizes for now. This needs
233 * to be changed once the API is supported.
234 */
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800235//sorted on column basis
Nishant Pandit741742b2010-09-21 03:24:20 +0530236static camera_size_type* picture_sizes;
237static unsigned int PICTURE_SIZE_COUNT;
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800238static const camera_size_type * picture_sizes_ptr;
239static int supportedPictureSizesCount;
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530240static liveshotState liveshot_state = LIVESHOT_DONE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800241
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800242#ifdef Q12
243#undef Q12
244#endif
245
246#define Q12 4096
247
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800248static const target_map targetList [] = {
249 { "msm7625", TARGET_MSM7625 },
250 { "msm7627", TARGET_MSM7627 },
251 { "qsd8250", TARGET_QSD8250 },
Nishant Pandit3c278cd2010-07-13 15:56:04 +0530252 { "msm7630", TARGET_MSM7630 },
253 { "msm8660", TARGET_MSM8660 }
254
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800255};
256static targetType mCurrentTarget = TARGET_MAX;
257
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800258typedef struct {
259 uint32_t aspect_ratio;
260 uint32_t width;
261 uint32_t height;
262} thumbnail_size_type;
263
264static thumbnail_size_type thumbnail_sizes[] = {
265 { 7281, 512, 288 }, //1.777778
266 { 6826, 480, 288 }, //1.666667
Vamshidhar Kondraedee25d2010-10-19 11:32:01 +0530267 { 6808, 256, 154 }, //1.662337
Kiran Kumar H Nb49af212010-02-17 15:12:17 -0800268 { 6144, 432, 288 }, //1.5
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800269 { 5461, 512, 384 }, //1.333333
270 { 5006, 352, 288 }, //1.222222
271};
272#define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
273#define DEFAULT_THUMBNAIL_SETTING 2
274#define THUMBNAIL_WIDTH_STR "512"
275#define THUMBNAIL_HEIGHT_STR "384"
276#define THUMBNAIL_SMALL_HEIGHT 144
Srinivasan Kannan264376e2010-08-13 18:54:35 -0700277static camera_size_type jpeg_thumbnail_sizes[] = {
278 { 512, 288 },
279 { 480, 288 },
280 { 432, 288 },
281 { 512, 384 },
282 { 352, 288 },
283 {0,0}
284};
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800285
Srinivasan Kannan264376e2010-08-13 18:54:35 -0700286#define JPEG_THUMBNAIL_SIZE_COUNT (sizeof(jpeg_thumbnail_sizes)/sizeof(camera_size_type))
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800287static int attr_lookup(const str_map arr[], int len, const char *name)
288{
289 if (name) {
290 for (int i = 0; i < len; i++) {
291 if (!strcmp(arr[i].desc, name))
292 return arr[i].val;
293 }
294 }
295 return NOT_FOUND;
296}
297
298// round to the next power of two
299static inline unsigned clp2(unsigned x)
300{
301 x = x - 1;
302 x = x | (x >> 1);
303 x = x | (x >> 2);
304 x = x | (x >> 4);
305 x = x | (x >> 8);
306 x = x | (x >>16);
307 return x + 1;
308}
309
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800310static int exif_table_numEntries = 0;
Srinivasan Kannan09de3382010-08-16 16:42:00 -0700311#define MAX_EXIF_TABLE_ENTRIES 11
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800312exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800313static zoom_crop_info zoomCropInfo;
314static void *mLastQueuedFrame = NULL;
Haynes George7dbe49d2010-08-09 12:33:12 -0700315#define RECORD_BUFFERS 9
Vinay Kaliaba3555f2010-07-21 11:37:36 -0700316#define RECORD_BUFFERS_8x50 8
Apurva Rajguruc73c1722010-04-15 17:39:11 -0700317static int kRecordBufferCount;
Mohan Kandra39fad8d2010-07-15 12:29:19 -0700318/* controls whether VPE is avialable for the target
319 * under consideration.
320 * 1: VPE support is available
321 * 0: VPE support is not available (default)
322 */
323static bool mVpeEnabled;
Apurva Rajguruc73c1722010-04-15 17:39:11 -0700324
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800325namespace android {
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800326
327static const int PICTURE_FORMAT_JPEG = 1;
328static const int PICTURE_FORMAT_RAW = 2;
329
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800330// from aeecamera.h
331static const str_map whitebalance[] = {
332 { CameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
333 { CameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
334 { CameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
335 { CameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
336 { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
337};
338
339// from camera_effect_t. This list must match aeecamera.h
340static const str_map effects[] = {
341 { CameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
342 { CameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
343 { CameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
344 { CameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
345 { CameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
346 { CameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
347 { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
348 { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
349 { CameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA }
350};
351
352// from qcamera/common/camera.h
Apurva Rajguru55562b02009-12-03 12:25:35 -0800353static const str_map autoexposure[] = {
354 { CameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
355 { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
356 { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
357};
358
359// from qcamera/common/camera.h
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800360static const str_map antibanding[] = {
361 { CameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
362 { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
363 { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
364 { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
365};
366
367/* Mapping from MCC to antibanding type */
368struct country_map {
369 uint32_t country_code;
370 camera_antibanding_type type;
371};
372
373static struct country_map country_numeric[] = {
374 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
375 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
376 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
377 { 208, CAMERA_ANTIBANDING_50HZ }, // France
378 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
379 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
380 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
381 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
382 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
383 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
384 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
385 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
386 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
387 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
388 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
389 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
390 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
391 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
392 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
393 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
394 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
395 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
396 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
397 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
398 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
399 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
400 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
401 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
402 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
403 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
404 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
405 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
406 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
407 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
408 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
409 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
410 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
411 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
412 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
413 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
414 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
415 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
416 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
417 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
418 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
419 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
420 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
421 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
422 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
423 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
424 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
425 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
426 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
427 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
428 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
429 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
430 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
431 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
432 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
433 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
434 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
435 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
436 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
437 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
438 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
439 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
440 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
441 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
442 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
443 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
444 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
445 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
446 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
447 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
448 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
449 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
450 { 404, CAMERA_ANTIBANDING_50HZ }, // India
451 { 405, CAMERA_ANTIBANDING_50HZ }, // India
452 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
453 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
454 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
455 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
456 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
457 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
458 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
459 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
460 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
461 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
462 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
463 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
464 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
465 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
466 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
467 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
468 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
469 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
470 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
471 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
472 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
473 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
474 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
475 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
476 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
477 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
478 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
479 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
480 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
481 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
482 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
483 { 460, CAMERA_ANTIBANDING_50HZ }, // China
484 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
485 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
486 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
487 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
488 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
489 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
490 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
491 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
492 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
493 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
494 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
495 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
496 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
497 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
498 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
499 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
500 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
501 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
502 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
503 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
504 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
505 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
506 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
507 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
508 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
509 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
510 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
511 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
512 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
513 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
514 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
515 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
516 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
517 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
518 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
519 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
520 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
521 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
522 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
523 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
524 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
525 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
526 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
527 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
528 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
529 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
530 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
531 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
532 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
533 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
534 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
535 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
536 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
537 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
538 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
539 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
540 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
541 { 647, CAMERA_ANTIBANDING_50HZ }, // France
542 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
543 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
544 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
545 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
546 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
547 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
548 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
549 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
550 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
551 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
552 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
553 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
554 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
555 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
556 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
557 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
558 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
559 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
560 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
561 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
562 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
563 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
564 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
565 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
566 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
567 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
568 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
569 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
570 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
571};
572
Apurva Rajguru08383852010-05-17 14:25:39 -0700573static const str_map scenemode[] = {
574 { CameraParameters::SCENE_MODE_AUTO, CAMERA_BESTSHOT_OFF },
575 { CameraParameters::SCENE_MODE_ACTION, CAMERA_BESTSHOT_ACTION },
576 { CameraParameters::SCENE_MODE_PORTRAIT, CAMERA_BESTSHOT_PORTRAIT },
577 { CameraParameters::SCENE_MODE_LANDSCAPE, CAMERA_BESTSHOT_LANDSCAPE },
578 { CameraParameters::SCENE_MODE_NIGHT, CAMERA_BESTSHOT_NIGHT },
579 { CameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
580 { CameraParameters::SCENE_MODE_THEATRE, CAMERA_BESTSHOT_THEATRE },
581 { CameraParameters::SCENE_MODE_BEACH, CAMERA_BESTSHOT_BEACH },
582 { CameraParameters::SCENE_MODE_SNOW, CAMERA_BESTSHOT_SNOW },
583 { CameraParameters::SCENE_MODE_SUNSET, CAMERA_BESTSHOT_SUNSET },
584 { CameraParameters::SCENE_MODE_STEADYPHOTO, CAMERA_BESTSHOT_ANTISHAKE },
585 { CameraParameters::SCENE_MODE_FIREWORKS , CAMERA_BESTSHOT_FIREWORKS },
586 { CameraParameters::SCENE_MODE_SPORTS , CAMERA_BESTSHOT_SPORTS },
587 { CameraParameters::SCENE_MODE_PARTY, CAMERA_BESTSHOT_PARTY },
588 { CameraParameters::SCENE_MODE_CANDLELIGHT, CAMERA_BESTSHOT_CANDLELIGHT },
589 { CameraParameters::SCENE_MODE_BACKLIGHT, CAMERA_BESTSHOT_BACKLIGHT },
590 { CameraParameters::SCENE_MODE_FLOWERS, CAMERA_BESTSHOT_FLOWERS },
591};
592
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700593static const str_map scenedetect[] = {
594 { CameraParameters::SCENE_DETECT_OFF, FALSE },
595 { CameraParameters::SCENE_DETECT_ON, TRUE },
596};
597
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800598#define country_number (sizeof(country_numeric) / sizeof(country_map))
Srinivasan Kannan264376e2010-08-13 18:54:35 -0700599/* TODO : setting dummy values as of now, need to query for correct
600 * values from sensor in future
601 */
602#define CAMERA_FOCAL_LENGTH_DEFAULT 4.31
603#define CAMERA_HORIZONTAL_VIEW_ANGLE_DEFAULT 54.8
604#define CAMERA_VERTICAL_VIEW_ANGLE_DEFAULT 42.5
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800605
606/* Look up pre-sorted antibanding_type table by current MCC. */
607static camera_antibanding_type camera_get_location(void) {
608 char value[PROP_VALUE_MAX];
609 char country_value[PROP_VALUE_MAX];
610 uint32_t country_code, count;
611 memset(value, 0x00, sizeof(value));
612 memset(country_value, 0x00, sizeof(country_value));
613 if (!__system_property_get("gsm.operator.numeric", value)) {
614 return CAMERA_ANTIBANDING_60HZ;
615 }
616 memcpy(country_value, value, 3);
617 country_code = atoi(country_value);
618 LOGD("value:%s, country value:%s, country code:%d\n",
619 value, country_value, country_code);
620 int left = 0;
621 int right = country_number - 1;
622 while (left <= right) {
623 int index = (left + right) >> 1;
624 if (country_numeric[index].country_code == country_code)
625 return country_numeric[index].type;
626 else if (country_numeric[index].country_code > country_code)
627 right = index - 1;
628 else
629 left = index + 1;
630 }
631 return CAMERA_ANTIBANDING_60HZ;
632}
633
634// from camera.h, led_mode_t
635static const str_map flash[] = {
636 { CameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
637 { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
Srinivasan Kannanda9a7052010-07-09 10:12:31 -0700638 { CameraParameters::FLASH_MODE_ON, LED_MODE_ON },
639 { CameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800640};
641
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530642// from mm-camera/common/camera.h.
643static const str_map iso[] = {
644 { CameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
645 { CameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
646 { CameraParameters::ISO_100, CAMERA_ISO_100},
647 { CameraParameters::ISO_200, CAMERA_ISO_200},
648 { CameraParameters::ISO_400, CAMERA_ISO_400},
Mohan Kandra61db0d02010-04-28 18:28:30 -0700649 { CameraParameters::ISO_800, CAMERA_ISO_800 },
650 { CameraParameters::ISO_1600, CAMERA_ISO_1600 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530651};
652
653
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800654#define DONT_CARE 0
655static const str_map focus_modes[] = {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800656 { CameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
657 { CameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
658 { CameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL },
659 { CameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800660};
661
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530662static const str_map lensshade[] = {
663 { CameraParameters::LENSSHADE_ENABLE, TRUE },
664 { CameraParameters::LENSSHADE_DISABLE, FALSE }
665};
666
Nishant Pandit741742b2010-09-21 03:24:20 +0530667static const str_map histogram[] = {
668 { CameraParameters::HISTOGRAM_ENABLE, TRUE },
669 { CameraParameters::HISTOGRAM_DISABLE, FALSE }
670};
671
Priyanka Kharate8dd0d62010-09-27 09:52:34 -0700672static const str_map skinToneEnhancement[] = {
673 { CameraParameters::SKIN_TONE_ENHANCEMENT_ENABLE, TRUE },
674 { CameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE, FALSE }
675};
676
Apurva Rajguru7b949c92010-05-26 15:46:57 -0700677static const str_map continuous_af[] = {
678 { CameraParameters::CONTINUOUS_AF_OFF, FALSE },
679 { CameraParameters::CONTINUOUS_AF_ON, TRUE }
680};
681
Apurva Rajgurue5965c42010-09-09 14:24:54 -0700682static const str_map selectable_zone_af[] = {
683 { CameraParameters::SELECTABLE_ZONE_AF_AUTO, AUTO },
684 { CameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT },
685 { CameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED },
686 { CameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE }
687};
688
Apurva Rajguru0a2cb922010-06-08 15:33:22 -0700689#define DONT_CARE_COORDINATE -1
690static const str_map touchafaec[] = {
691 { CameraParameters::TOUCH_AF_AEC_OFF, FALSE },
692 { CameraParameters::TOUCH_AF_AEC_ON, TRUE }
693};
694
Srinivasan Kannan71229622009-12-04 12:05:58 -0800695struct SensorType {
696 const char *name;
697 int rawPictureWidth;
698 int rawPictureHeight;
699 bool hasAutoFocusSupport;
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800700 int max_supported_snapshot_width;
701 int max_supported_snapshot_height;
Apurva Rajguruffe264a2010-03-09 13:50:53 -0800702 int bitMask;
Srinivasan Kannan71229622009-12-04 12:05:58 -0800703};
704
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -0700705
706/*
707 * Values based on aec.c
708 */
709
Nishant Pandit741742b2010-09-21 03:24:20 +0530710#define CAMERA_HISTOGRAM_ENABLE 1
711#define CAMERA_HISTOGRAM_DISABLE 0
712#define HISTOGRAM_STATS_SIZE 257
713
Apurva Rajguruf9317f22010-10-27 15:16:54 -0700714//Dx,Dy should be same as defined in res/layout/camera.xml
715#define FOCUS_RECTANGLE_DX 100
716#define FOCUS_RECTANGLE_DY 100
717
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -0700718#define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
719#define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
720#define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
721#define EXPOSURE_COMPENSATION_DENOMINATOR 6
722#define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
723
Srinivasan Kannan71229622009-12-04 12:05:58 -0800724static SensorType sensorTypes[] = {
Priyanka Kharat0fa7f9f2010-08-30 19:00:35 -0700725 { "12mp", 5464, 3120, true, 4000, 3000,0x00001fff },
Yen-Pin Hsiaoa6612f12010-07-19 15:17:21 -0700726 { "12mp_sn12m0pz",4032, 3024, true, 4000, 3000,0x00000fff },
Apurva Rajguruffe264a2010-03-09 13:50:53 -0800727 { "5mp", 2608, 1960, true, 2592, 1944,0x00000fff },
728 { "3mp", 2064, 1544, false, 2048, 1536,0x000007ff },
Nishant Pandit2eedc1b2010-09-25 04:47:39 +0530729 { "2mp", 3200, 1200, false, 1600, 1200,0x000007ff },
730 { "ov7692", 640, 480, false, 640, 480, 0x000000ff } }; //Web Camera
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800731
Srinivasan Kannan71229622009-12-04 12:05:58 -0800732
733static SensorType * sensorType;
734
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800735static const str_map picture_formats[] = {
736 {CameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
737 {CameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
738};
739
Mohan Kandrabf6146d2010-07-20 18:48:37 -0700740static const str_map frame_rate_modes[] = {
741 {CameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
742 {CameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
743};
744
Mohan Kandra7110c242010-07-18 15:34:48 -0700745static int mPreviewFormat;
746static const str_map preview_formats[] = {
747 {CameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21},
748 {CameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO}
749};
750
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800751static bool parameter_string_initialized = false;
752static String8 preview_size_values;
753static String8 picture_size_values;
Srinivasan Kannan264376e2010-08-13 18:54:35 -0700754static String8 jpeg_thumbnail_size_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800755static String8 antibanding_values;
756static String8 effect_values;
Apurva Rajguru55562b02009-12-03 12:25:35 -0800757static String8 autoexposure_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800758static String8 whitebalance_values;
759static String8 flash_values;
760static String8 focus_mode_values;
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530761static String8 iso_values;
762static String8 lensshade_values;
Nishant Pandit741742b2010-09-21 03:24:20 +0530763static String8 histogram_values;
Priyanka Kharate8dd0d62010-09-27 09:52:34 -0700764static String8 skinToneEnhancement_values;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -0700765static String8 touchafaec_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800766static String8 picture_format_values;
Apurva Rajguru08383852010-05-17 14:25:39 -0700767static String8 scenemode_values;
Apurva Rajguru7b949c92010-05-26 15:46:57 -0700768static String8 continuous_af_values;
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700769static String8 zoom_ratio_values;
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700770static String8 preview_frame_rate_values;
Mohan Kandrabf6146d2010-07-20 18:48:37 -0700771static String8 frame_rate_mode_values;
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700772static String8 scenedetect_values;
Mohan Kandra7110c242010-07-18 15:34:48 -0700773static String8 preview_format_values;
Apurva Rajgurue5965c42010-09-09 14:24:54 -0700774static String8 selectable_zone_af_values;
Deepak Kurieneb58c682010-11-01 15:26:02 -0700775mm_camera_notify mCamNotify;
776mm_camera_ops mCamOps;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800777static String8 create_sizes_str(const camera_size_type *sizes, int len) {
778 String8 str;
779 char buffer[32];
780
781 if (len > 0) {
782 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
783 str.append(buffer);
784 }
785 for (int i = 1; i < len; i++) {
786 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
787 str.append(buffer);
788 }
789 return str;
790}
791
792static String8 create_values_str(const str_map *values, int len) {
793 String8 str;
794
795 if (len > 0) {
796 str.append(values[0].desc);
797 }
798 for (int i = 1; i < len; i++) {
799 str.append(",");
800 str.append(values[i].desc);
801 }
802 return str;
803}
804
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700805
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700806static String8 create_str(int16_t *arr, int length){
807 String8 str;
808 char buffer[32];
809
810 if(length > 0){
811 snprintf(buffer, sizeof(buffer), "%d", arr[0]);
812 str.append(buffer);
813 }
814
815 for (int i =1;i<length;i++){
816 snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
817 str.append(buffer);
818 }
819 return str;
820}
821
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700822static String8 create_values_range_str(int min, int max){
823 String8 str;
824 char buffer[32];
825
826 if(min <= max){
827 snprintf(buffer, sizeof(buffer), "%d", min);
828 str.append(buffer);
829
830 for (int i = min + 1; i <= max; i++) {
831 snprintf(buffer, sizeof(buffer), ",%d", i);
832 str.append(buffer);
833 }
834 }
835 return str;
836}
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700837
Sravankb4f5f1c2010-01-21 11:06:17 +0530838extern "C" {
839//------------------------------------------------------------------------
840// : 720p busyQ funcitons
841// --------------------------------------------------------------------
842static struct fifo_queue g_busy_frame_queue =
843 {0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
844};
845/*===========================================================================
846 * FUNCTION cam_frame_wait_video
847 *
848 * DESCRIPTION this function waits a video in the busy queue
849 * ===========================================================================*/
850
851static void cam_frame_wait_video (void)
852{
853 LOGV("cam_frame_wait_video E ");
854 if ((g_busy_frame_queue.num_of_frames) <=0){
855 pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut));
856 }
857 LOGV("cam_frame_wait_video X");
858 return;
859}
860
861/*===========================================================================
862 * FUNCTION cam_frame_flush_video
863 *
864 * DESCRIPTION this function deletes all the buffers in busy queue
865 * ===========================================================================*/
866void cam_frame_flush_video (void)
867{
868 LOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames);
869 pthread_mutex_lock(&(g_busy_frame_queue.mut));
870
871 while (g_busy_frame_queue.front)
872 {
873 //dequeue from the busy queue
874 struct fifo_node *node = dequeue (&g_busy_frame_queue);
875 if(node)
876 free(node);
877
878 LOGV("cam_frame_flush_video: node \n");
879 }
880 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
881 LOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames);
882 return ;
883}
884/*===========================================================================
885 * FUNCTION cam_frame_get_video
886 *
887 * DESCRIPTION this function returns a video frame from the head
888 * ===========================================================================*/
889static struct msm_frame * cam_frame_get_video()
890{
891 struct msm_frame *p = NULL;
892 LOGV("cam_frame_get_video... in\n");
893 LOGV("cam_frame_get_video... got lock\n");
894 if (g_busy_frame_queue.front)
895 {
896 //dequeue
897 struct fifo_node *node = dequeue (&g_busy_frame_queue);
898 if (node)
899 {
900 p = (struct msm_frame *)node->f;
901 free (node);
902 }
903 LOGV("cam_frame_get_video... out = %x\n", p->buffer);
904 }
905 return p;
906}
907
908/*===========================================================================
909 * FUNCTION cam_frame_post_video
910 *
911 * DESCRIPTION this function add a busy video frame to the busy queue tails
912 * ===========================================================================*/
913static void cam_frame_post_video (struct msm_frame *p)
914{
915 if (!p)
916 {
917 LOGE("post video , buffer is null");
918 return;
919 }
920 LOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer));
921 pthread_mutex_lock(&(g_busy_frame_queue.mut));
922 LOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames);
923 //enqueue to busy queue
924 struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node));
925 if (node)
926 {
927 LOGV(" post video , enqueing in busy queue");
928 node->f = p;
929 node->next = NULL;
930 enqueue (&g_busy_frame_queue, node);
931 LOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames);
932 }
933 else
934 {
935 LOGE("cam_frame_post_video error... out of memory\n");
936 }
937
938 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
939 pthread_cond_signal(&(g_busy_frame_queue.wait));
940
941 LOGV("cam_frame_post_video... out = %x\n", p->buffer);
942
943 return;
944}
945
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800946void QualcommCameraHardware::storeTargetType(void) {
947 char mDeviceName[PROPERTY_VALUE_MAX];
948 property_get("ro.product.device",mDeviceName," ");
949 mCurrentTarget = TARGET_MAX;
950 for( int i = 0; i < TARGET_MAX ; i++) {
951 if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) {
952 mCurrentTarget = targetList[i].targetEnum;
953 break;
954 }
955 }
956 LOGV(" Storing the current target type as %d ", mCurrentTarget );
957 return;
958}
959
Sravankb4f5f1c2010-01-21 11:06:17 +0530960//-------------------------------------------------------------------------------------
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800961static Mutex singleton_lock;
962static bool singleton_releasing;
Srinivasan Kannan78444e42010-06-10 15:39:29 -0700963static nsecs_t singleton_releasing_start_time;
964static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5);
965static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800966static Condition singleton_wait;
967
968static void receive_camframe_callback(struct msm_frame *frame);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530969static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size);
Nishant Pandit741742b2010-09-21 03:24:20 +0530970static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo);
Sravankb4f5f1c2010-01-21 11:06:17 +0530971static void receive_camframe_video_callback(struct msm_frame *frame); // 720p
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800972static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size);
973static void receive_jpeg_callback(jpeg_event_t status);
974static void receive_shutter_callback(common_crop_t *crop);
Mohan Kandra3dd524f2010-09-20 13:41:42 -0700975static void receive_camframe_error_callback(camera_error_type err);
Mohan Kandra284966d2010-01-05 13:39:15 -0800976static int fb_fd = -1;
977static int32_t mMaxZoom = 0;
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700978static bool zoomSupported = false;
Mohan Kandrad9efed92010-01-15 19:08:39 -0800979static int dstOffset = 0;
980
Deepak Kurieneb58c682010-11-01 15:26:02 -0700981static int16_t * zoomRatios;
Brian Steuer07704892009-12-18 18:07:33 -0800982static int camerafd;
983pthread_t w_thread;
984
985void *opencamerafd(void *data) {
986 camerafd = open(MSM_CAMERA_CONTROL, O_RDWR);
987 return NULL;
988}
989
Mohan Kandrad9efed92010-01-15 19:08:39 -0800990/* When using MDP zoom, double the preview buffers. The usage of these
991 * buffers is as follows:
992 * 1. As all the buffers comes under a single FD, and at initial registration,
993 * this FD will be passed to surface flinger, surface flinger can have access
994 * to all the buffers when needed.
995 * 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the
996 * camera driver to receive preview frames. The remaining buffers (DstSet),
997 * will be used at HAL and by surface flinger only when crop information
998 * is present in the frame.
999 * 3. When there is no crop information, there will be no call to MDP zoom,
1000 * and the buffers in SrcSet will be passed to surface flinger to display.
1001 * 4. With crop information present, MDP zoom will be called, and the final
1002 * data will be placed in a buffer from DstSet, and this buffer will be given
1003 * to surface flinger to display.
1004 */
1005#define NUM_MORE_BUFS 2
1006
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001007QualcommCameraHardware::QualcommCameraHardware()
1008 : mParameters(),
1009 mCameraRunning(false),
1010 mPreviewInitialized(false),
1011 mFrameThreadRunning(false),
Mohan Kandra156d0ac2010-01-25 16:59:17 -08001012 mVideoThreadRunning(false),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001013 mSnapshotThreadRunning(false),
Mohan Kandra1659b0c2010-07-18 16:36:25 -07001014 mEncodePending(false),
Mohan Kandraca2e7a92010-06-21 15:48:45 -07001015 mJpegThreadRunning(false),
Mohan Kandra62429cc2010-07-19 10:21:05 -07001016 mInSnapshotMode(false),
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001017 mSnapshotFormat(0),
Priyanka Kharat02807662010-10-13 23:44:47 -07001018 mFirstFrame(true),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001019 mReleasedRecordingFrame(false),
1020 mPreviewFrameSize(0),
1021 mRawSize(0),
Mohan Kandra1659b0c2010-07-18 16:36:25 -07001022 mCbCrOffsetRaw(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001023 mCameraControlFd(-1),
1024 mAutoFocusThreadRunning(false),
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001025 mBrightness(0),
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07001026 mSkinToneEnhancement(0),
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07001027 mHJR(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001028 mInPreviewCallback(false),
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001029 mUseOverlay(0),
1030 mOverlay(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001031 mMsgEnabled(0),
1032 mNotifyCallback(0),
1033 mDataCallback(0),
1034 mDataCallbackTimestamp(0),
Mohan Kandra740cfce2010-01-07 12:58:24 -08001035 mCallbackCookie(0),
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001036 mInitialized(false),
Apurva Rajguru3da1a702010-07-28 12:32:42 -07001037 mDebugFps(0),
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001038 mSnapshotDone(0),
1039 mDisEnabled(0),
Mohan Kandra9aff1f42010-09-02 19:00:41 -07001040 mRotation(0),
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07001041 mResetOverlayCrop(false),
1042 mThumbnailWidth(0),
Deepak Kurieneb58c682010-11-01 15:26:02 -07001043 mThumbnailHeight(0),
Mohan Kandra4ebb9102010-11-09 17:52:30 -08001044 mHasAutoFocusSupport(0),
1045 strTexturesOn(false)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001046{
Mohan Kandra0d115d12010-08-19 11:47:15 -07001047 LOGI("QualcommCameraHardware constructor E");
Brian Steuer07704892009-12-18 18:07:33 -08001048 // Start opening camera device in a separate thread/ Since this
1049 // initializes the sensor hardware, this can take a long time. So,
1050 // start the process here so it will be ready by the time it's
1051 // needed.
1052 if ((pthread_create(&w_thread, NULL, opencamerafd, NULL)) != 0) {
1053 LOGE("Camera open thread creation failed");
1054 }
1055
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001056 memset(&mDimension, 0, sizeof(mDimension));
1057 memset(&mCrop, 0, sizeof(mCrop));
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001058 memset(&zoomCropInfo, 0, sizeof(zoom_crop_info));
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08001059 storeTargetType();
Mohan Kandra740cfce2010-01-07 12:58:24 -08001060 char value[PROPERTY_VALUE_MAX];
1061 property_get("persist.debug.sf.showfps", value, "0");
1062 mDebugFps = atoi(value);
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301063 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) {
Sravankb4f5f1c2010-01-21 11:06:17 +05301064 kPreviewBufferCountActual = kPreviewBufferCount;
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301065 kRecordBufferCount = RECORD_BUFFERS;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001066 recordframes = new msm_frame[kRecordBufferCount];
Mohan Kandra1fd90f92010-06-17 14:54:17 -07001067 record_buffers_tracking_flag = new bool[kRecordBufferCount];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001068 }
1069 else {
Sravankb4f5f1c2010-01-21 11:06:17 +05301070 kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001071 if( mCurrentTarget == TARGET_QSD8250 ) {
1072 kRecordBufferCount = RECORD_BUFFERS_8x50;
1073 recordframes = new msm_frame[kRecordBufferCount];
Mohan Kandra1fd90f92010-06-17 14:54:17 -07001074 record_buffers_tracking_flag = new bool[kRecordBufferCount];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001075 }
1076 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001077
1078 switch(mCurrentTarget){
1079 case TARGET_MSM7627:
Sravanka7b89c82010-10-06 16:13:28 +05301080 jpegPadding = 0; // to be checked.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001081 break;
1082 case TARGET_QSD8250:
1083 case TARGET_MSM7630:
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301084 case TARGET_MSM8660:
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001085 jpegPadding = 0;
1086 break;
1087 default:
1088 jpegPadding = 0;
1089 break;
1090 }
Mohan Kandra7110c242010-07-18 15:34:48 -07001091 // Initialize with default format values. The format values can be
1092 // overriden when application requests.
1093 mDimension.prev_format = CAMERA_YUV_420_NV21;
1094 mPreviewFormat = CAMERA_YUV_420_NV21;
1095 mDimension.enc_format = CAMERA_YUV_420_NV21;
Mohan Kandra88db27a2010-08-22 12:33:36 -07001096 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
Mohan Kandra7110c242010-07-18 15:34:48 -07001097 mDimension.enc_format = CAMERA_YUV_420_NV12;
1098
1099 mDimension.main_img_format = CAMERA_YUV_420_NV21;
1100 mDimension.thumb_format = CAMERA_YUV_420_NV21;
1101
Mohan Kandrafdbc2192010-08-24 20:39:59 -07001102 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001103 /* DIS is enabled all the time in VPE support targets.
1104 * No provision for the user to control this.
1105 */
1106 mDisEnabled = 1;
Mohan Kandraec958742010-08-19 10:56:05 -07001107 /* Get the DIS value from properties, to check whether
1108 * DIS is disabled or not
1109 */
1110 property_get("persist.camera.hal.dis", value, "1");
1111 mDisEnabled = atoi(value);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001112 mVpeEnabled = 1;
1113 }
1114
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001115 LOGV("constructor EX");
1116}
1117
Deepak Kurieneb58c682010-11-01 15:26:02 -07001118void QualcommCameraHardware::hasAutoFocusSupport(){
1119 if( !mCamOps.mm_camera_is_supported(CAMERA_OPS_FOCUS)){
1120 LOGE("AutoFocus is not supported");
1121 mHasAutoFocusSupport = false;
1122 }else {
1123 mHasAutoFocusSupport = true;
1124 }
1125}
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001126void QualcommCameraHardware::filterPreviewSizes(){
1127
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001128 unsigned int boardMask = 0;
Mohan Kandra62429cc2010-07-19 10:21:05 -07001129 unsigned int prop = 0;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001130 for(prop=0;prop<sizeof(boardProperties)/sizeof(board_property);prop++){
1131 if(mCurrentTarget == boardProperties[prop].target){
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001132 boardMask = boardProperties[prop].previewSizeMask;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001133 break;
1134 }
1135 }
1136
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001137 int bitMask = boardMask & sensorType->bitMask;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001138 if(bitMask){
1139 unsigned int mask = 1<<(PREVIEW_SIZE_COUNT-1);
1140 previewSizeCount=0;
1141 unsigned int i = 0;
1142 while(mask){
1143 if(mask&bitMask)
1144 supportedPreviewSizes[previewSizeCount++] =
1145 preview_sizes[i];
1146 i++;
1147 mask = mask >> 1;
1148 }
1149 }
1150}
1151
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001152//filter Picture sizes based on max width and height
1153void QualcommCameraHardware::filterPictureSizes(){
1154 int i;
1155 for(i=0;i<PICTURE_SIZE_COUNT;i++){
1156 if(((picture_sizes[i].width <=
1157 sensorType->max_supported_snapshot_width) &&
1158 (picture_sizes[i].height <=
1159 sensorType->max_supported_snapshot_height))){
1160 picture_sizes_ptr = picture_sizes + i;
1161 supportedPictureSizesCount = PICTURE_SIZE_COUNT - i ;
1162 return ;
1163 }
1164 }
1165}
1166
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001167bool QualcommCameraHardware::supportsSceneDetection() {
1168 int prop = 0;
1169 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
1170 if((mCurrentTarget == boardProperties[prop].target)
1171 && boardProperties[prop].hasSceneDetect == true) {
1172 return true;
1173 break;
1174 }
1175 }
1176 return false;
1177}
1178
Apurva Rajgurue5965c42010-09-09 14:24:54 -07001179bool QualcommCameraHardware::supportsSelectableZoneAf() {
1180 int prop = 0;
1181 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
1182 if((mCurrentTarget == boardProperties[prop].target)
1183 && boardProperties[prop].hasSelectableZoneAf == true) {
1184 return true;
1185 break;
1186 }
1187 }
1188 return false;
1189}
1190
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001191void QualcommCameraHardware::initDefaultParameters()
1192{
Mohan Kandra0d115d12010-08-19 11:47:15 -07001193 LOGI("initDefaultParameters E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001194
Apurva Rajguru59ec7122010-08-25 13:03:30 -07001195 findSensorType();
Deepak Kurieneb58c682010-11-01 15:26:02 -07001196 hasAutoFocusSupport();
Nishant Pandit2eedc1b2010-09-25 04:47:39 +05301197 //Disable DIS for Web Camera
1198 if(!strcmp(sensorType->name, "ov7692"))
1199 mDisEnabled = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001200 // Initialize constant parameter strings. This will happen only once in the
1201 // lifetime of the mediaserver process.
1202 if (!parameter_string_initialized) {
1203 antibanding_values = create_values_str(
1204 antibanding, sizeof(antibanding) / sizeof(str_map));
1205 effect_values = create_values_str(
1206 effects, sizeof(effects) / sizeof(str_map));
Apurva Rajguru55562b02009-12-03 12:25:35 -08001207 autoexposure_values = create_values_str(
1208 autoexposure, sizeof(autoexposure) / sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001209 whitebalance_values = create_values_str(
1210 whitebalance, sizeof(whitebalance) / sizeof(str_map));
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001211
1212 //filter preview sizes
1213 filterPreviewSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001214 preview_size_values = create_sizes_str(
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001215 supportedPreviewSizes, previewSizeCount);
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001216 //filter picture sizes
1217 filterPictureSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001218 picture_size_values = create_sizes_str(
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001219 picture_sizes_ptr, supportedPictureSizesCount);
1220
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001221 flash_values = create_values_str(
1222 flash, sizeof(flash) / sizeof(str_map));
Deepak Kurieneb58c682010-11-01 15:26:02 -07001223 if(mHasAutoFocusSupport){
Srinivasan Kannan71229622009-12-04 12:05:58 -08001224 focus_mode_values = create_values_str(
1225 focus_modes, sizeof(focus_modes) / sizeof(str_map));
1226 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301227 iso_values = create_values_str(
1228 iso,sizeof(iso)/sizeof(str_map));
1229 lensshade_values = create_values_str(
1230 lensshade,sizeof(lensshade)/sizeof(str_map));
Nishant Pandit741742b2010-09-21 03:24:20 +05301231 //Currently Enabling Histogram for 8x60
1232 if(mCurrentTarget == TARGET_MSM8660) {
1233 histogram_values = create_values_str(
1234 histogram,sizeof(histogram)/sizeof(str_map));
1235 }
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07001236 //Currently Enabling Skin Tone Enhancement for 8x60 and 7630
1237 if((mCurrentTarget == TARGET_MSM8660)||(mCurrentTarget == TARGET_MSM7630)) {
1238 skinToneEnhancement_values = create_values_str(
1239 skinToneEnhancement,sizeof(skinToneEnhancement)/sizeof(str_map));
1240 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07001241 if(mHasAutoFocusSupport){
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07001242 touchafaec_values = create_values_str(
1243 touchafaec,sizeof(touchafaec)/sizeof(str_map));
1244 }
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001245
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001246 picture_format_values = create_values_str(
1247 picture_formats, sizeof(picture_formats)/sizeof(str_map));
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001248
Deepak Kurieneb58c682010-11-01 15:26:02 -07001249 if(mHasAutoFocusSupport){
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001250 continuous_af_values = create_values_str(
1251 continuous_af, sizeof(continuous_af) / sizeof(str_map));
1252 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07001253 if( mCfgControl.mm_camera_query_parms(CAMERA_PARM_ZOOM_RATIO, (void **)&zoomRatios, (uint32_t *) &mMaxZoom) == MM_CAMERA_SUCCESS)
1254 {
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001255 zoomSupported = true;
Deepak Kurieneb58c682010-11-01 15:26:02 -07001256 if( mMaxZoom >0) {
1257 LOGE("Maximum zoom value is %d", mMaxZoom);
1258 if(zoomRatios != NULL) {
1259 zoom_ratio_values = create_str(zoomRatios, mMaxZoom);
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001260 } else {
Deepak Kurieneb58c682010-11-01 15:26:02 -07001261 LOGE("Failed to get zoomratios ..");
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001262 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07001263 } else {
1264 zoomSupported = false;
1265 }
1266 } else {
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001267 zoomSupported = false;
1268 LOGE("Failed to get maximum zoom value...setting max "
1269 "zoom to zero");
1270 mMaxZoom = 0;
1271 }
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001272 preview_frame_rate_values = create_values_range_str(
1273 MINIMUM_FPS, MAXIMUM_FPS);
Apurva Rajguru08383852010-05-17 14:25:39 -07001274
1275 scenemode_values = create_values_str(
1276 scenemode, sizeof(scenemode) / sizeof(str_map));
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001277
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001278 if(supportsSceneDetection()) {
1279 scenedetect_values = create_values_str(
1280 scenedetect, sizeof(scenedetect) / sizeof(str_map));
1281 }
1282
Deepak Kurieneb58c682010-11-01 15:26:02 -07001283 if(mHasAutoFocusSupport && supportsSelectableZoneAf()){
Apurva Rajgurue5965c42010-09-09 14:24:54 -07001284 selectable_zone_af_values = create_values_str(
1285 selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
1286 }
1287
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001288 parameter_string_initialized = true;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001289 }
1290
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001291 mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
1292 mDimension.display_width = DEFAULT_PREVIEW_WIDTH;
1293 mDimension.display_height = DEFAULT_PREVIEW_HEIGHT;
1294
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001295 mParameters.setPreviewFrameRate(DEFAULT_FPS);
Deepak Kurieneb58c682010-11-01 15:26:02 -07001296 if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07001297 mParameters.set(
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001298 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
1299 preview_frame_rate_values.string());
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001300 } else {
1301 mParameters.set(
1302 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
1303 DEFAULT_FPS);
1304 }
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001305 mParameters.setPreviewFrameRateMode("frame-rate-auto");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001306 mParameters.setPreviewFormat("yuv420sp"); // informative
1307
1308 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
1309 mParameters.setPictureFormat("jpeg"); // informative
1310
Mohan Kandra785619a2010-02-01 21:52:42 -08001311 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001312 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
1313 THUMBNAIL_WIDTH_STR); // informative
1314 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
1315 THUMBNAIL_HEIGHT_STR); // informative
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08001316 mDimension.ui_thumbnail_width =
1317 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
1318 mDimension.ui_thumbnail_height =
1319 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001320 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
1321
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001322 String8 valuesStr = create_sizes_str(jpeg_thumbnail_sizes, JPEG_THUMBNAIL_SIZE_COUNT);
1323 mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
1324 valuesStr.string());
1325
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001326 if(zoomSupported){
1327 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true");
Mohan Kandra6599e352010-11-15 12:23:36 -08001328 LOGV("max zoom is %d", mMaxZoom-1);
1329 /* mMaxZoom value that the query interface returns is the size
1330 * of zoom table. So the actual max zoom value will be one
1331 * less than that value.
1332 */
Deepak Kurieneb58c682010-11-01 15:26:02 -07001333 mParameters.set("max-zoom",mMaxZoom-1);
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001334 mParameters.set(CameraParameters::KEY_ZOOM_RATIOS,
1335 zoom_ratio_values);
1336 } else {
1337 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "false");
1338 }
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001339 /* Enable zoom support for video application if VPE enabled */
1340 if(zoomSupported && mVpeEnabled) {
1341 mParameters.set("video-zoom-support", "true");
1342 } else {
1343 mParameters.set("video-zoom-support", "false");
1344 }
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001345
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001346 mParameters.set(CameraParameters::KEY_ANTIBANDING,
Mohan Kandra785619a2010-02-01 21:52:42 -08001347 CameraParameters::ANTIBANDING_OFF);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001348 mParameters.set(CameraParameters::KEY_EFFECT,
1349 CameraParameters::EFFECT_NONE);
Apurva Rajguru55562b02009-12-03 12:25:35 -08001350 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
1351 CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001352 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
1353 CameraParameters::WHITE_BALANCE_AUTO);
1354 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
1355 CameraParameters::FOCUS_MODE_AUTO);
Mohan Kandra7110c242010-07-18 15:34:48 -07001356 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_QSD8250) ) {
Priya Komarlingam044c7b52010-01-22 18:21:23 -08001357 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1358 "yuv420sp");
Mohan Kandra7110c242010-07-18 15:34:48 -07001359 }
1360 else {
1361 preview_format_values = create_values_str(
1362 preview_formats, sizeof(preview_formats) / sizeof(str_map));
1363 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1364 preview_format_values.string());
1365 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001366
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001367 frame_rate_mode_values = create_values_str(
1368 frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
Deepak Kurieneb58c682010-11-01 15:26:02 -07001369 if( mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE)){
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001370 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
1371 frame_rate_mode_values.string());
1372 }
1373
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001374 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
1375 preview_size_values.string());
1376 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
1377 picture_size_values.string());
1378 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
1379 antibanding_values);
1380 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
Apurva Rajguru55562b02009-12-03 12:25:35 -08001381 mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001382 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
1383 whitebalance_values);
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001384
Deepak Kurieneb58c682010-11-01 15:26:02 -07001385 if(mHasAutoFocusSupport)
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001386 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001387 focus_mode_values);
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001388 else
1389 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
1390 CameraParameters::FOCUS_MODE_INFINITY);
1391
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001392 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1393 picture_format_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001394
1395 if (mSensorInfo.flash_enabled) {
1396 mParameters.set(CameraParameters::KEY_FLASH_MODE,
1397 CameraParameters::FLASH_MODE_OFF);
1398 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
1399 flash_values);
1400 }
1401
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08001402 mParameters.set(CameraParameters::KEY_MAX_SHARPNESS,
1403 CAMERA_MAX_SHARPNESS);
1404 mParameters.set(CameraParameters::KEY_MAX_CONTRAST,
1405 CAMERA_MAX_CONTRAST);
1406 mParameters.set(CameraParameters::KEY_MAX_SATURATION,
1407 CAMERA_MAX_SATURATION);
1408
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07001409 mParameters.set(
1410 CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
1411 EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
1412 mParameters.set(
1413 CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
1414 EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
1415 mParameters.set(
1416 CameraParameters::KEY_EXPOSURE_COMPENSATION,
1417 EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
1418 mParameters.setFloat(
1419 CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
1420 EXPOSURE_COMPENSATION_STEP);
1421
Apurva Rajguru07185952010-01-22 15:40:07 -08001422 mParameters.set("luma-adaptation", "3");
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07001423 mParameters.set("skinToneEnhancement", "0");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001424 mParameters.set("zoom-supported", "true");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001425 mParameters.set("zoom", 0);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001426 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT,
1427 CameraParameters::PIXEL_FORMAT_JPEG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001428
Kiran Kumar H N595970b2010-01-12 10:41:09 -08001429 mParameters.set(CameraParameters::KEY_SHARPNESS,
1430 CAMERA_DEF_SHARPNESS);
1431 mParameters.set(CameraParameters::KEY_CONTRAST,
1432 CAMERA_DEF_CONTRAST);
1433 mParameters.set(CameraParameters::KEY_SATURATION,
1434 CAMERA_DEF_SATURATION);
1435
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301436 mParameters.set(CameraParameters::KEY_ISO_MODE,
1437 CameraParameters::ISO_AUTO);
1438 mParameters.set(CameraParameters::KEY_LENSSHADE,
1439 CameraParameters::LENSSHADE_ENABLE);
1440 mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
1441 iso_values);
1442 mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
1443 lensshade_values);
Nishant Pandit741742b2010-09-21 03:24:20 +05301444 mParameters.set(CameraParameters::KEY_HISTOGRAM,
1445 CameraParameters::HISTOGRAM_DISABLE);
1446 mParameters.set(CameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
1447 histogram_values);
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07001448 mParameters.set(CameraParameters::KEY_SKIN_TONE_ENHANCEMENT,
1449 CameraParameters::SKIN_TONE_ENHANCEMENT_DISABLE);
1450 mParameters.set(CameraParameters::KEY_SUPPORTED_SKIN_TONE_ENHANCEMENT_MODES,
1451 skinToneEnhancement_values);
Apurva Rajguru08383852010-05-17 14:25:39 -07001452 mParameters.set(CameraParameters::KEY_SCENE_MODE,
1453 CameraParameters::SCENE_MODE_AUTO);
Mohan Kandra7110c242010-07-18 15:34:48 -07001454 mParameters.set("strtextures", "OFF");
1455
Apurva Rajguru08383852010-05-17 14:25:39 -07001456 mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
1457 scenemode_values);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001458 mParameters.set(CameraParameters::KEY_CONTINUOUS_AF,
1459 CameraParameters::CONTINUOUS_AF_OFF);
1460 mParameters.set(CameraParameters::KEY_SUPPORTED_CONTINUOUS_AF,
1461 continuous_af_values);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001462 mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC,
1463 CameraParameters::TOUCH_AF_AEC_OFF);
1464 mParameters.set(CameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
1465 touchafaec_values);
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07001466 mParameters.setTouchIndexAec(-1, -1);
1467 mParameters.setTouchIndexAf(-1, -1);
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001468 mParameters.set(CameraParameters::KEY_SCENE_DETECT,
1469 CameraParameters::SCENE_DETECT_OFF);
1470 mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_DETECT,
1471 scenedetect_values);
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001472 mParameters.setFloat(CameraParameters::KEY_FOCAL_LENGTH,
1473 CAMERA_FOCAL_LENGTH_DEFAULT);
1474 mParameters.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
1475 CAMERA_HORIZONTAL_VIEW_ANGLE_DEFAULT);
1476 mParameters.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE,
1477 CAMERA_VERTICAL_VIEW_ANGLE_DEFAULT);
Apurva Rajgurue5965c42010-09-09 14:24:54 -07001478 mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF,
1479 CameraParameters::SELECTABLE_ZONE_AF_AUTO);
1480 mParameters.set(CameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
1481 selectable_zone_af_values);
Priyanka Kharat67cfe532010-03-29 17:28:22 -07001482 if (setParameters(mParameters) != NO_ERROR) {
1483 LOGE("Failed to set default parameters?!");
1484 }
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001485 mUseOverlay = useOverlay();
1486
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001487 /* Initialize the camframe_timeout_flag*/
1488 Mutex::Autolock l(&mCamframeTimeoutLock);
1489 camframe_timeout_flag = FALSE;
Priyanka Kharat02807662010-10-13 23:44:47 -07001490 mPostViewHeap = NULL;
1491 mDisplayHeap = NULL;
1492 mThumbnailHeap = NULL;
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001493
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001494 mInitialized = true;
Mohan Kandra4ebb9102010-11-09 17:52:30 -08001495 strTexturesOn = false;
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001496
Mohan Kandra0d115d12010-08-19 11:47:15 -07001497 LOGI("initDefaultParameters X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001498}
1499
Srinivasan Kannan71229622009-12-04 12:05:58 -08001500void QualcommCameraHardware::findSensorType(){
1501 mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
1502 mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
Deepak Kurieneb58c682010-11-01 15:26:02 -07001503 bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
1504 sizeof(cam_ctrl_dimension_t),(void *) &mDimension);
Srinivasan Kannan71229622009-12-04 12:05:58 -08001505 if (ret) {
1506 unsigned int i;
1507 for (i = 0; i < sizeof(sensorTypes) / sizeof(SensorType); i++) {
1508 if (sensorTypes[i].rawPictureHeight
1509 == mDimension.raw_picture_height) {
1510 sensorType = sensorTypes + i;
1511 return;
1512 }
1513 }
1514 }
1515 //default to 5 mp
1516 sensorType = sensorTypes;
1517 return;
1518}
1519
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001520#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
1521
1522bool QualcommCameraHardware::startCamera()
1523{
1524 LOGV("startCamera E");
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08001525 if( mCurrentTarget == TARGET_MAX ) {
1526 LOGE(" Unable to determine the target type. Camera will not work ");
1527 return false;
1528 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001529#if DLOPEN_LIBMMCAMERA
1530 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
Priya Komarlingam9bb2d492010-06-23 19:21:52 -07001531
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001532 LOGV("loading liboemcamera at %p", libmmcamera);
1533 if (!libmmcamera) {
1534 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1535 return false;
1536 }
1537
1538 *(void **)&LINK_cam_frame =
1539 ::dlsym(libmmcamera, "cam_frame");
1540 *(void **)&LINK_camframe_terminate =
1541 ::dlsym(libmmcamera, "camframe_terminate");
1542
1543 *(void **)&LINK_jpeg_encoder_init =
1544 ::dlsym(libmmcamera, "jpeg_encoder_init");
1545
1546 *(void **)&LINK_jpeg_encoder_encode =
1547 ::dlsym(libmmcamera, "jpeg_encoder_encode");
1548
1549 *(void **)&LINK_jpeg_encoder_join =
1550 ::dlsym(libmmcamera, "jpeg_encoder_join");
1551
1552 *(void **)&LINK_mmcamera_camframe_callback =
1553 ::dlsym(libmmcamera, "mmcamera_camframe_callback");
1554
1555 *LINK_mmcamera_camframe_callback = receive_camframe_callback;
1556
Nishant Pandit741742b2010-09-21 03:24:20 +05301557 *(void **)&LINK_mmcamera_camstats_callback =
1558 ::dlsym(libmmcamera, "mmcamera_camstats_callback");
1559
1560 *LINK_mmcamera_camstats_callback = receive_camstats_callback;
1561
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001562 *(void **)&LINK_mmcamera_jpegfragment_callback =
1563 ::dlsym(libmmcamera, "mmcamera_jpegfragment_callback");
1564
1565 *LINK_mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
1566
1567 *(void **)&LINK_mmcamera_jpeg_callback =
1568 ::dlsym(libmmcamera, "mmcamera_jpeg_callback");
1569
1570 *LINK_mmcamera_jpeg_callback = receive_jpeg_callback;
1571
Mohan Kandra3dd524f2010-09-20 13:41:42 -07001572 *(void **)&LINK_camframe_error_callback =
1573 ::dlsym(libmmcamera, "camframe_error_callback");
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001574
Mohan Kandra3dd524f2010-09-20 13:41:42 -07001575 *LINK_camframe_error_callback = receive_camframe_error_callback;
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001576
Sravankb4f5f1c2010-01-21 11:06:17 +05301577 // 720 p new recording functions
1578 *(void **)&LINK_cam_frame_flush_free_video = ::dlsym(libmmcamera, "cam_frame_flush_free_video");
1579
1580 *(void **)&LINK_camframe_free_video = ::dlsym(libmmcamera, "cam_frame_add_free_video");
1581
1582 *(void **)&LINK_camframe_video_callback = ::dlsym(libmmcamera, "mmcamera_camframe_videocallback");
1583 *LINK_camframe_video_callback = receive_camframe_video_callback;
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08001584
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001585 *(void **)&LINK_mmcamera_shutter_callback =
1586 ::dlsym(libmmcamera, "mmcamera_shutter_callback");
1587
1588 *LINK_mmcamera_shutter_callback = receive_shutter_callback;
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08001589
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001590 *(void**)&LINK_jpeg_encoder_setMainImageQuality =
1591 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
Kiran Kumar H N8861f302010-01-05 12:01:41 -08001592
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001593 *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
1594 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
1595
1596 *(void**)&LINK_jpeg_encoder_setRotation =
1597 ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
1598
Mohan Kandra02486042010-06-18 16:49:43 -07001599 *(void**)&LINK_jpeg_encoder_get_buffer_offset =
1600 ::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset");
1601
Kiran Kumar H N8861f302010-01-05 12:01:41 -08001602/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001603 *(void**)&LINK_jpeg_encoder_setLocation =
1604 ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001605*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001606 *(void **)&LINK_cam_conf =
1607 ::dlsym(libmmcamera, "cam_conf");
1608
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001609/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001610 *(void **)&LINK_default_sensor_get_snapshot_sizes =
1611 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001612*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001613 *(void **)&LINK_launch_cam_conf_thread =
1614 ::dlsym(libmmcamera, "launch_cam_conf_thread");
1615
1616 *(void **)&LINK_release_cam_conf_thread =
1617 ::dlsym(libmmcamera, "release_cam_conf_thread");
Deepak Kurieneb58c682010-11-01 15:26:02 -07001618 *(void **)&LINK_mm_camera_init =
1619 ::dlsym(libmmcamera, "mm_camera_init");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001620
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301621 *(void **)&LINK_mmcamera_liveshot_callback =
1622 ::dlsym(libmmcamera, "mmcamera_liveshot_callback");
1623
1624 *LINK_mmcamera_liveshot_callback = receive_liveshot_callback;
1625
1626 *(void **)&LINK_cancel_liveshot =
1627 ::dlsym(libmmcamera, "cancel_liveshot");
1628
1629 *(void **)&LINK_set_liveshot_params =
1630 ::dlsym(libmmcamera, "set_liveshot_params");
1631
Deepak Kurieneb58c682010-11-01 15:26:02 -07001632 *(void **)&LINK_mm_camera_deinit =
1633 ::dlsym(libmmcamera, "mm_camera_deinit");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001634/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001635 *(void **)&LINK_zoom_crop_upscale =
1636 ::dlsym(libmmcamera, "zoom_crop_upscale");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001637*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001638
1639#else
1640 mmcamera_camframe_callback = receive_camframe_callback;
Nishant Pandit741742b2010-09-21 03:24:20 +05301641 mmcamera_camstats_callback = receive_camstats_callback;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001642 mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
1643 mmcamera_jpeg_callback = receive_jpeg_callback;
1644 mmcamera_shutter_callback = receive_shutter_callback;
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301645 mmcamera_liveshot_callback = receive_liveshot_callback;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001646#endif // DLOPEN_LIBMMCAMERA
1647
1648 /* The control thread is in libcamera itself. */
Brian Steuer07704892009-12-18 18:07:33 -08001649 if (pthread_join(w_thread, NULL) != 0) {
1650 LOGE("Camera open thread exit failed");
1651 return false;
1652 }
1653 mCameraControlFd = camerafd;
1654
Kiran Kumar H N585bc362010-01-19 13:04:44 -08001655 if (mCameraControlFd < 0) {
1656 LOGE("startCamera X: %s open failed: %s!",
1657 MSM_CAMERA_CONTROL,
1658 strerror(errno));
1659 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001660 }
1661
Deepak Kurieneb58c682010-11-01 15:26:02 -07001662 if (MM_CAMERA_SUCCESS != LINK_mm_camera_init(&mCfgControl, &mCamNotify, &mCamOps)) {
1663 LOGE("startCamera: mm_camera_init failed:");
Nishant Pandit741742b2010-09-21 03:24:20 +05301664 return FALSE;
1665 }
1666
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301667 if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){
Mohan Kandra284966d2010-01-05 13:39:15 -08001668 fb_fd = open("/dev/graphics/fb0", O_RDWR);
1669 if (fb_fd < 0) {
1670 LOGE("startCamera: fb0 open failed: %s!", strerror(errno));
1671 return FALSE;
1672 }
1673 }
1674
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001675 /* This will block until the control thread is launched. After that, sensor
1676 * information becomes available.
1677 */
1678
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001679 memset(&mSensorInfo, 0, sizeof(mSensorInfo));
1680 if (ioctl(mCameraControlFd,
1681 MSM_CAM_IOCTL_GET_SENSOR_INFO,
1682 &mSensorInfo) < 0)
1683 LOGW("%s: cannot retrieve sensor info!", __FUNCTION__);
1684 else
1685 LOGI("%s: camsensor name %s, flash %d", __FUNCTION__,
1686 mSensorInfo.name, mSensorInfo.flash_enabled);
Nishant Pandit741742b2010-09-21 03:24:20 +05301687
1688 mCfgControl.mm_camera_query_parms(CAMERA_PARM_PICT_SIZE, (void **)&picture_sizes, &PICTURE_SIZE_COUNT);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001689 if (!picture_sizes || !PICTURE_SIZE_COUNT) {
1690 LOGE("startCamera X: could not get snapshot sizes");
1691 return false;
1692 }
Nishant Pandit741742b2010-09-21 03:24:20 +05301693 LOGV("startCamera picture_sizes %p PICTURE_SIZE_COUNT %d", picture_sizes, PICTURE_SIZE_COUNT);
1694
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001695 LOGV("startCamera X");
1696 return true;
1697}
1698
1699status_t QualcommCameraHardware::dump(int fd,
1700 const Vector<String16>& args) const
1701{
1702 const size_t SIZE = 256;
1703 char buffer[SIZE];
1704 String8 result;
1705
1706 // Dump internal primitives.
1707 result.append("QualcommCameraHardware::dump");
1708 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
1709 result.append(buffer);
1710 int width, height;
1711 mParameters.getPreviewSize(&width, &height);
1712 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
1713 result.append(buffer);
1714 mParameters.getPictureSize(&width, &height);
1715 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
1716 result.append(buffer);
1717 snprintf(buffer, 255,
1718 "preview frame size(%d), raw size (%d), jpeg size (%d) "
1719 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
1720 mJpegSize, mJpegMaxSize);
1721 result.append(buffer);
1722 write(fd, result.string(), result.size());
1723
1724 // Dump internal objects.
Mohan Kandrad9efed92010-01-15 19:08:39 -08001725 if (mPreviewHeap != 0) {
1726 mPreviewHeap->dump(fd, args);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001727 }
1728 if (mRawHeap != 0) {
1729 mRawHeap->dump(fd, args);
1730 }
1731 if (mJpegHeap != 0) {
1732 mJpegHeap->dump(fd, args);
1733 }
1734 mParameters.dump(fd, args);
1735 return NO_ERROR;
1736}
1737
Deepak Kurieneb58c682010-11-01 15:26:02 -07001738/* Issue ioctl calls related to starting Camera Operations*/
1739bool static native_start_ops(mm_camera_ops_type_t type, void* value)
Mohan Kandra284966d2010-01-05 13:39:15 -08001740{
Deepak Kurieneb58c682010-11-01 15:26:02 -07001741 if(mCamOps.mm_camera_start(type, value,NULL) != MM_CAMERA_SUCCESS) {
1742 LOGE("native_start_ops: type %d error %s",
1743 type,strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001744 return false;
1745 }
1746 return true;
1747}
1748
Deepak Kurieneb58c682010-11-01 15:26:02 -07001749/* Issue ioctl calls related to stopping Camera Operations*/
1750bool static native_stop_ops(mm_camera_ops_type_t type, void* value)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001751{
Deepak Kurieneb58c682010-11-01 15:26:02 -07001752 if(mCamOps.mm_camera_stop(type, value,NULL) != MM_CAMERA_SUCCESS) {
1753 LOGE("native_stop_ops: type %d error %s",
1754 type,strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001755 return false;
1756 }
Sravankb4f5f1c2010-01-21 11:06:17 +05301757 return true;
1758}
1759/*==========================================================================*/
1760
1761static cam_frame_start_parms frame_parms;
1762static int recordingState = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001763
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001764#define GPS_PROCESSING_METHOD_SIZE 101
1765#define FOCAL_LENGTH_DECIMAL_PRECISON 100
1766
1767static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
1768#define EXIF_ASCII_PREFIX_SIZE (sizeof(ExifAsciiPrefix))
1769
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001770static rat_t latitude[3];
1771static rat_t longitude[3];
1772static char lonref[2];
1773static char latref[2];
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001774static rat_t altitude;
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001775static rat_t gpsTimestamp[3];
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001776static char gpsDatestamp[20];
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001777static char dateTime[20];
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001778static rat_t focalLength;
1779static char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
1780
1781
1782
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001783static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
1784 uint32_t count, uint8_t copy, void *data) {
1785
1786 if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
1787 LOGE("Number of entries exceeded limit");
1788 return;
1789 }
1790
1791 int index = exif_table_numEntries;
1792 exif_data[index].tag_id = tagid;
1793 exif_data[index].tag_entry.type = type;
1794 exif_data[index].tag_entry.count = count;
1795 exif_data[index].tag_entry.copy = copy;
1796 if((type == EXIF_RATIONAL) && (count > 1))
1797 exif_data[index].tag_entry.data._rats = (rat_t *)data;
1798 if((type == EXIF_RATIONAL) && (count == 1))
1799 exif_data[index].tag_entry.data._rat = *(rat_t *)data;
1800 else if(type == EXIF_ASCII)
1801 exif_data[index].tag_entry.data._ascii = (char *)data;
1802 else if(type == EXIF_BYTE)
1803 exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
1804
1805 // Increase number of entries
1806 exif_table_numEntries++;
1807}
1808
1809static void parseLatLong(const char *latlonString, int *pDegrees,
1810 int *pMinutes, int *pSeconds ) {
1811
1812 double value = atof(latlonString);
1813 value = fabs(value);
1814 int degrees = (int) value;
1815
1816 double remainder = value - degrees;
1817 int minutes = (int) (remainder * 60);
1818 int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
1819
1820 *pDegrees = degrees;
1821 *pMinutes = minutes;
1822 *pSeconds = seconds;
1823}
1824
1825static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
1826
1827 int degrees, minutes, seconds;
1828
1829 parseLatLong(latlonString, &degrees, &minutes, &seconds);
1830
1831 rat_t value[3] = { {degrees, 1},
1832 {minutes, 1},
1833 {seconds, 1000} };
1834
1835 if(tag == EXIFTAGID_GPS_LATITUDE) {
1836 memcpy(latitude, value, sizeof(latitude));
1837 addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
1838 1, (void *)latitude);
1839 } else {
1840 memcpy(longitude, value, sizeof(longitude));
1841 addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
1842 1, (void *)longitude);
1843 }
1844}
1845
1846void QualcommCameraHardware::setGpsParameters() {
1847 const char *str = NULL;
1848
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001849 str = mParameters.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1850
1851 if(str!=NULL ){
1852 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
1853 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str,
1854 GPS_PROCESSING_METHOD_SIZE-1);
1855 gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0';
1856 addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII,
1857 EXIF_ASCII_PREFIX_SIZE + strlen(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1,
1858 1, (void *)gpsProcessingMethod);
1859 }
1860
1861 str = NULL;
1862
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001863 //Set Latitude
1864 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE);
1865 if(str != NULL) {
1866 setLatLon(EXIFTAGID_GPS_LATITUDE, str);
1867 //set Latitude Ref
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001868 float latitudeValue = mParameters.getFloat(CameraParameters::KEY_GPS_LATITUDE);
1869 latref[0] = 'N';
1870 if(latitudeValue < 0 ){
1871 latref[0] = 'S';
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001872 }
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001873 latref[1] = '\0';
1874 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latref);
1875 addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
1876 1, (void *)latref);
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001877 }
1878
1879 //set Longitude
1880 str = NULL;
1881 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE);
1882 if(str != NULL) {
1883 setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
1884 //set Longitude Ref
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001885 float longitudeValue = mParameters.getFloat(CameraParameters::KEY_GPS_LONGITUDE);
1886 lonref[0] = 'E';
1887 if(longitudeValue < 0){
1888 lonref[0] = 'W';
1889 }
1890 lonref[1] = '\0';
1891 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, lonref);
1892 addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
1893 1, (void *)lonref);
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001894 }
1895
1896 //set Altitude
1897 str = NULL;
1898 str = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE);
1899 if(str != NULL) {
1900 int value = atoi(str);
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001901 int ref = 0;
1902 if(value < 0){
1903 ref = 1;
1904 value = -value;
1905 }
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001906 rat_t alt_value = {value, 1000};
1907 memcpy(&altitude, &alt_value, sizeof(altitude));
1908 addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
1909 1, (void *)&altitude);
1910 //set AltitudeRef
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001911 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, ref);
1912 addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
1913 1, (void *)&ref);
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001914 }
1915
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001916 //set Gps TimeStamp
1917 str = NULL;
1918 str = mParameters.get(CameraParameters::KEY_GPS_TIMESTAMP);
1919 if(str != NULL) {
1920
1921 long value = atol(str);
1922 time_t unixTime;
1923 struct tm *UTCTimestamp;
1924
1925 unixTime = (time_t)value;
1926 UTCTimestamp = gmtime(&unixTime);
1927
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001928 strftime(gpsDatestamp, sizeof(gpsDatestamp), "%Y:%m:%d", UTCTimestamp);
1929 addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII,
1930 strlen(gpsDatestamp)+1 , 1, (void *)&gpsDatestamp);
1931
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001932 rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1},
1933 {UTCTimestamp->tm_min, 1},
1934 {UTCTimestamp->tm_sec, 1} };
1935
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001936
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001937 memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp));
1938 addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
1939 3, 1, (void *)&gpsTimestamp);
1940 }
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001941
1942}
1943
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001944bool QualcommCameraHardware::native_jpeg_encode(void)
1945{
1946 int jpeg_quality = mParameters.getInt("jpeg-quality");
1947 if (jpeg_quality >= 0) {
1948 LOGV("native_jpeg_encode, current jpeg main img quality =%d",
1949 jpeg_quality);
1950 if(!LINK_jpeg_encoder_setMainImageQuality(jpeg_quality)) {
1951 LOGE("native_jpeg_encode set jpeg-quality failed");
1952 return false;
1953 }
1954 }
1955
1956 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
1957 if (thumbnail_quality >= 0) {
1958 LOGV("native_jpeg_encode, current jpeg thumbnail quality =%d",
1959 thumbnail_quality);
1960 if(!LINK_jpeg_encoder_setThumbnailQuality(thumbnail_quality)) {
1961 LOGE("native_jpeg_encode set thumbnail-quality failed");
1962 return false;
1963 }
1964 }
1965
Priyanka Kharat32409f72010-08-25 18:11:03 -07001966 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM7627) && (mCurrentTarget != TARGET_MSM8660) ) {
Mohan Kandra02486042010-06-18 16:49:43 -07001967 int rotation = mParameters.getInt("rotation");
1968 if (rotation >= 0) {
1969 LOGV("native_jpeg_encode, rotation = %d", rotation);
1970 if(!LINK_jpeg_encoder_setRotation(rotation)) {
1971 LOGE("native_jpeg_encode set rotation failed");
1972 return false;
1973 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001974 }
1975 }
1976
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001977 jpeg_set_location();
1978
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001979 //set TimeStamp
1980 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
1981 if(str != NULL) {
1982 strncpy(dateTime, str, 19);
1983 dateTime[19] = '\0';
1984 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
1985 20, 1, (void *)dateTime);
1986 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07001987
Srinivasan Kannan09de3382010-08-16 16:42:00 -07001988 int focalLengthValue = (int) (mParameters.getFloat(
1989 CameraParameters::KEY_FOCAL_LENGTH) * FOCAL_LENGTH_DECIMAL_PRECISON);
1990 rat_t focalLengthRational = {focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISON};
1991 memcpy(&focalLength, &focalLengthRational, sizeof(focalLengthRational));
1992 addExifTag(EXIFTAGID_FOCAL_LENGTH, EXIF_RATIONAL, 1,
1993 1, (void *)&focalLength);
1994
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001995 uint8_t * thumbnailHeap = NULL;
1996 int thumbfd = -1;
1997
1998 int width = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1999 int height = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
2000
2001 LOGV("width %d and height %d", width , height);
2002
2003 if(width != 0 && height != 0){
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002004 if((mCurrentTarget == TARGET_MSM7630) ||
2005 (mCurrentTarget == TARGET_MSM8660) ||
Sravanka7b89c82010-10-06 16:13:28 +05302006 (mCurrentTarget == TARGET_MSM7627) ||
Mohan Kandra4ebb9102010-11-09 17:52:30 -08002007 (strTexturesOn == true)) {
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002008 thumbnailHeap = (uint8_t *)mRawHeap->mHeap->base();
2009 thumbfd = mRawHeap->mHeap->getHeapID();
2010 } else {
2011 thumbnailHeap = (uint8_t *)mThumbnailHeap->mHeap->base();
2012 thumbfd = mThumbnailHeap->mHeap->getHeapID();
2013 }
2014 }else {
2015 thumbnailHeap = NULL;
2016 thumbfd = 0;
2017 }
2018
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002019 if( (mCurrentTarget == TARGET_MSM7630) ||
2020 (mCurrentTarget == TARGET_MSM8660) ||
Sravanka7b89c82010-10-06 16:13:28 +05302021 (mCurrentTarget == TARGET_MSM7627) ||
Mohan Kandra4ebb9102010-11-09 17:52:30 -08002022 (strTexturesOn == true) ) {
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002023 // Pass the main image as thumbnail buffer, so that jpeg encoder will
2024 // generate thumbnail based on main image.
2025 // Set the input and output dimensions for thumbnail generation to main
2026 // image dimensions and required thumbanail size repectively, for the
2027 // encoder to do downscaling of the main image accordingly.
2028 mCrop.in1_w = mDimension.orig_picture_dx;
2029 mCrop.in1_h = mDimension.orig_picture_dy;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002030 /* For Adreno format on targets that don't use VFE other output
2031 * for postView, thumbnail_width and thumbnail_height has the
2032 * actual thumbnail dimensions.
2033 */
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002034 mCrop.out1_w = mDimension.thumbnail_width;
2035 mCrop.out1_h = mDimension.thumbnail_height;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002036 /* For targets, that uses VFE other output for postview,
2037 * thumbnail_width and thumbnail_height has values based on postView
2038 * dimensions(mostly previewWidth X previewHeight), but not based on
2039 * required thumbnail dimensions. So, while downscaling, we need to
2040 * pass the actual thumbnail dimensions, not the postview dimensions.
2041 * mThumbnailWidth/Height has the required thumbnail dimensions, so
2042 * use them here.
2043 */
2044 if( (mCurrentTarget == TARGET_MSM7630)||
Sravanka7b89c82010-10-06 16:13:28 +05302045 (mCurrentTarget == TARGET_MSM7627) ||
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002046 (mCurrentTarget == TARGET_MSM8660)) {
2047 mCrop.out1_w = mThumbnailWidth;
2048 mCrop.out1_h = mThumbnailHeight;
2049 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002050 mDimension.thumbnail_width = mDimension.orig_picture_dx;
2051 mDimension.thumbnail_height = mDimension.orig_picture_dy;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002052 LOGV("mCrop.in1_w = %d, mCrop.in1_h = %d", mCrop.in1_w, mCrop.in1_h);
2053 LOGV("mCrop.out1_w = %d, mCrop.out1_h = %d", mCrop.out1_w, mCrop.out1_h);
2054 LOGV("mDimension.thumbnail_width = %d, mDimension.thumbnail_height = %d", mDimension.thumbnail_width, mDimension.thumbnail_height);
2055 int CbCrOffset = -1;
2056 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)
2057 CbCrOffset = mCbCrOffsetRaw;
Vamshidhar Kondra8e703082010-11-02 15:46:54 +05302058 mCrop.in1_w = mDimension.orig_picture_dx - jpegPadding; // when cropping is enabled
2059 mCrop.in1_h = mDimension.orig_picture_dy - jpegPadding; // when cropping is enabled
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002060
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002061 if (!LINK_jpeg_encoder_encode(&mDimension,
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002062 thumbnailHeap,
2063 thumbfd,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002064 (uint8_t *)mRawHeap->mHeap->base(),
2065 mRawHeap->mHeap->getHeapID(),
2066 &mCrop, exif_data, exif_table_numEntries,
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002067 jpegPadding/2, CbCrOffset)) {
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002068 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
2069 return false;
2070 }
2071 } else {
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002072 if (!LINK_jpeg_encoder_encode(&mDimension,
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002073 thumbnailHeap,
2074 thumbfd,
2075 (uint8_t *)mRawHeap->mHeap->base(),
2076 mRawHeap->mHeap->getHeapID(),
2077 &mCrop, exif_data, exif_table_numEntries,
2078 jpegPadding/2, -1)) {
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002079 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
2080 return false;
2081 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002082 }
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002083
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002084 return true;
2085}
2086
Deepak Kurieneb58c682010-11-01 15:26:02 -07002087bool QualcommCameraHardware::native_set_parms(
2088 mm_camera_parm_type_t type, uint16_t length, void *value)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002089{
Deepak Kurieneb58c682010-11-01 15:26:02 -07002090 if(mCfgControl.mm_camera_set_parm(type,value) != MM_CAMERA_SUCCESS) {
2091 LOGE("native_set_parms failed: type %d error %s",
2092 type,strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002093 return false;
2094 }
2095 return true;
Deepak Kurieneb58c682010-11-01 15:26:02 -07002096
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002097}
Deepak Kurieneb58c682010-11-01 15:26:02 -07002098bool QualcommCameraHardware::native_set_parms(
2099 mm_camera_parm_type_t type, uint16_t length, void *value, int *result)
Deepak Kuriencbd25d92010-10-08 10:16:08 -07002100{
Deepak Kurieneb58c682010-11-01 15:26:02 -07002101 mm_camera_status_t status;
2102 status = mCfgControl.mm_camera_set_parm(type,value);
2103 LOGV("native_set_parms status = %d", status);
2104 if( status == MM_CAMERA_SUCCESS || status == MM_CAMERA_ERR_INVALID_OPERATION){
2105 *result = status ;
Deepak Kuriencbd25d92010-10-08 10:16:08 -07002106 return true;
Deepak Kuriencbd25d92010-10-08 10:16:08 -07002107 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07002108 LOGE("%s: type %d, status %d", __FUNCTION__, strerror(errno), status);
2109 *result = status;
2110 return false;
Deepak Kuriencbd25d92010-10-08 10:16:08 -07002111}
Deepak Kurieneb58c682010-11-01 15:26:02 -07002112
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002113void QualcommCameraHardware::jpeg_set_location()
2114{
2115 bool encode_location = true;
2116 camera_position_type pt;
2117
2118#define PARSE_LOCATION(what,type,fmt,desc) do { \
2119 pt.what = 0; \
2120 const char *what##_str = mParameters.get("gps-"#what); \
2121 LOGV("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
2122 if (what##_str) { \
2123 type what = 0; \
2124 if (sscanf(what##_str, fmt, &what) == 1) \
2125 pt.what = what; \
2126 else { \
2127 LOGE("GPS " #what " %s could not" \
2128 " be parsed as a " #desc, what##_str); \
2129 encode_location = false; \
2130 } \
2131 } \
2132 else { \
2133 LOGV("GPS " #what " not specified: " \
2134 "defaulting to zero in EXIF header."); \
2135 encode_location = false; \
2136 } \
2137 } while(0)
2138
2139 PARSE_LOCATION(timestamp, long, "%ld", "long");
2140 if (!pt.timestamp) pt.timestamp = time(NULL);
2141 PARSE_LOCATION(altitude, short, "%hd", "short");
2142 PARSE_LOCATION(latitude, double, "%lf", "double float");
2143 PARSE_LOCATION(longitude, double, "%lf", "double float");
2144
2145#undef PARSE_LOCATION
2146
2147 if (encode_location) {
2148 LOGD("setting image location ALT %d LAT %lf LON %lf",
2149 pt.altitude, pt.latitude, pt.longitude);
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002150
2151 setGpsParameters();
2152 /* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002153 if (!LINK_jpeg_encoder_setLocation(&pt)) {
2154 LOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
2155 }
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002156 */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002157 }
2158 else LOGV("not setting image location");
2159}
2160
2161void QualcommCameraHardware::runFrameThread(void *data)
2162{
2163 LOGV("runFrameThread E");
2164
2165 int cnt;
2166
2167#if DLOPEN_LIBMMCAMERA
2168 // We need to maintain a reference to libqcamera.so for the duration of the
2169 // frame thread, because we do not know when it will exit relative to the
2170 // lifetime of this object. We do not want to dlclose() libqcamera while
2171 // LINK_cam_frame is still running.
2172 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
2173 LOGV("FRAME: loading libqcamera at %p", libhandle);
2174 if (!libhandle) {
2175 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
2176 }
2177 if (libhandle)
2178#endif
2179 {
2180 LINK_cam_frame(data);
2181 }
2182
Mohan Kandrad9efed92010-01-15 19:08:39 -08002183 mPreviewHeap.clear();
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302184 if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660))
Sravankb4f5f1c2010-01-21 11:06:17 +05302185 mRecordHeap.clear();
2186
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002187#if DLOPEN_LIBMMCAMERA
2188 if (libhandle) {
2189 ::dlclose(libhandle);
2190 LOGV("FRAME: dlclose(libqcamera)");
2191 }
2192#endif
2193
2194 mFrameThreadWaitLock.lock();
2195 mFrameThreadRunning = false;
2196 mFrameThreadWait.signal();
2197 mFrameThreadWaitLock.unlock();
2198
2199 LOGV("runFrameThread X");
2200}
2201
Sravankb4f5f1c2010-01-21 11:06:17 +05302202void QualcommCameraHardware::runVideoThread(void *data)
2203{
2204 LOGD("runVideoThread E");
2205 msm_frame* vframe = NULL;
2206
2207 while(true) {
2208 pthread_mutex_lock(&(g_busy_frame_queue.mut));
2209
Srinivasan Kannanfc3915c2010-03-18 10:54:40 -07002210 // Exit the thread , in case of stop recording..
2211 mVideoThreadWaitLock.lock();
2212 if(mVideoThreadExit){
2213 LOGV("Exiting video thread..");
2214 mVideoThreadWaitLock.unlock();
2215 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
2216 break;
2217 }
2218 mVideoThreadWaitLock.unlock();
2219
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002220 LOGV("in video_thread : wait for video frame ");
Sravankb4f5f1c2010-01-21 11:06:17 +05302221 // check if any frames are available in busyQ and give callback to
2222 // services/video encoder
2223 cam_frame_wait_video();
2224 LOGV("video_thread, wait over..");
2225
2226 // Exit the thread , in case of stop recording..
2227 mVideoThreadWaitLock.lock();
2228 if(mVideoThreadExit){
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002229 LOGV("Exiting video thread..");
Sravankb4f5f1c2010-01-21 11:06:17 +05302230 mVideoThreadWaitLock.unlock();
2231 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
2232 break;
2233 }
2234 mVideoThreadWaitLock.unlock();
2235
2236 // Get the video frame to be encoded
2237 vframe = cam_frame_get_video ();
Apurva Rajgurud9b0b302010-02-19 11:22:56 -08002238 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Sravankb4f5f1c2010-01-21 11:06:17 +05302239 LOGV("in video_thread : got video frame ");
2240
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08002241 if (UNLIKELY(mDebugFps)) {
2242 debugShowVideoFPS();
2243 }
2244
Sravankb4f5f1c2010-01-21 11:06:17 +05302245 if(vframe != NULL) {
2246 // Find the offset within the heap of the current buffer.
2247 LOGV("Got video frame : buffer %d base %d ", vframe->buffer, mRecordHeap->mHeap->base());
2248 ssize_t offset =
2249 (ssize_t)vframe->buffer - (ssize_t)mRecordHeap->mHeap->base();
2250 LOGV("offset = %d , alignsize = %d , offset later = %d", offset, mRecordHeap->mAlignedBufferSize, (offset / mRecordHeap->mAlignedBufferSize));
2251
2252 offset /= mRecordHeap->mAlignedBufferSize;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07002253
2254 //set the track flag to true for this video buffer
2255 record_buffers_tracking_flag[offset] = true;
2256
Mohan Kandra1307f312010-04-29 10:18:42 -07002257 /* Extract the timestamp of this frame */
2258 nsecs_t timeStamp = nsecs_t(vframe->ts.tv_sec)*1000000000LL + vframe->ts.tv_nsec;
Sravankb4f5f1c2010-01-21 11:06:17 +05302259
2260 // dump frames for test purpose
2261#ifdef DUMP_VIDEO_FRAMES
2262 static int frameCnt = 0;
2263 if (frameCnt >= 11 && frameCnt <= 13 ) {
2264 char buf[128];
2265 sprintf(buf, "/data/%d_v.yuv", frameCnt);
2266 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2267 LOGV("dumping video frame %d", frameCnt);
2268 if (file_fd < 0) {
2269 LOGE("cannot open file\n");
2270 }
2271 else
2272 {
2273 write(file_fd, (const void *)vframe->buffer,
2274 vframe->cbcr_off * 3 / 2);
2275 }
2276 close(file_fd);
2277 }
2278 frameCnt++;
2279#endif
2280 // Enable IF block to give frames to encoder , ELSE block for just simulation
2281#if 1
2282 LOGV("in video_thread : got video frame, before if check giving frame to services/encoder");
2283 mCallbackLock.lock();
2284 int msgEnabled = mMsgEnabled;
2285 data_callback_timestamp rcb = mDataCallbackTimestamp;
2286 void *rdata = mCallbackCookie;
2287 mCallbackLock.unlock();
2288
2289 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
2290 LOGV("in video_thread : got video frame, giving frame to services/encoder");
Mohan Kandra1307f312010-04-29 10:18:42 -07002291 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[offset], rdata);
Sravankb4f5f1c2010-01-21 11:06:17 +05302292 }
2293#else
2294 // 720p output2 : simulate release frame here:
2295 LOGE("in video_thread simulation , releasing the video frame");
2296 LINK_camframe_free_video(vframe);
2297#endif
2298
2299 } else LOGE("in video_thread get frame returned null");
2300
Sravankb4f5f1c2010-01-21 11:06:17 +05302301
2302 } // end of while loop
Mohan Kandra156d0ac2010-01-25 16:59:17 -08002303
2304 mVideoThreadWaitLock.lock();
2305 mVideoThreadRunning = false;
2306 mVideoThreadWait.signal();
2307 mVideoThreadWaitLock.unlock();
2308
Sravankb4f5f1c2010-01-21 11:06:17 +05302309 LOGV("runVideoThread X");
2310}
2311
2312void *video_thread(void *user)
2313{
2314 LOGV("video_thread E");
2315 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2316 if (obj != 0) {
2317 obj->runVideoThread(user);
2318 }
2319 else LOGE("not starting video thread: the object went away!");
2320 LOGV("video_thread X");
2321 return NULL;
2322}
2323
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002324void *frame_thread(void *user)
2325{
2326 LOGD("frame_thread E");
2327 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2328 if (obj != 0) {
2329 obj->runFrameThread(user);
2330 }
2331 else LOGW("not starting frame thread: the object went away!");
2332 LOGD("frame_thread X");
2333 return NULL;
2334}
2335
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002336static int parse_size(const char *str, int &width, int &height)
2337{
2338 // Find the width.
2339 char *end;
2340 int w = (int)strtol(str, &end, 10);
2341 // If an 'x' or 'X' does not immediately follow, give up.
2342 if ( (*end != 'x') && (*end != 'X') )
2343 return -1;
2344
2345 // Find the height, immediately after the 'x'.
2346 int h = (int)strtol(end+1, 0, 10);
2347
2348 width = w;
2349 height = h;
2350
2351 return 0;
2352}
2353
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002354bool QualcommCameraHardware::initPreview()
2355{
2356 // See comments in deinitPreview() for why we have to wait for the frame
2357 // thread here, and why we can't use pthread_join().
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302358 const char * pmem_region;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002359 mParameters.getPreviewSize(&previewWidth, &previewHeight);
Sravankb4f5f1c2010-01-21 11:06:17 +05302360
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002361 //Get the Record sizes
2362 const char *recordSize = NULL;
2363 recordSize = mParameters.get("record-size");
2364 if(!recordSize) {
2365 //If application didn't set this parameter string, use the values from
2366 //getPreviewSize() as video dimensions.
Mohan Kandra2cd34e62010-10-06 18:15:56 -07002367 LOGV("No Record Size requested, use the preview dimensions");
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002368 videoWidth = previewWidth;
2369 videoHeight = previewHeight;
2370 } else {
2371 //Extract the record witdh and height that application requested.
2372 if(!parse_size(recordSize, videoWidth, videoHeight)) {
2373 //VFE output1 shouldn't be greater than VFE output2.
2374 if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) {
2375 //Set preview sizes as record sizes.
2376 LOGI("Preview size %dx%d is greater than record size %dx%d,\
2377 resetting preview size to record size",previewWidth,\
2378 previewHeight, videoWidth, videoHeight);
2379 previewWidth = videoWidth;
2380 previewHeight = videoHeight;
2381 mParameters.setPreviewSize(previewWidth, previewHeight);
2382 }
2383 if( (mCurrentTarget != TARGET_MSM7630)
2384 && (mCurrentTarget != TARGET_QSD8250)
2385 && (mCurrentTarget != TARGET_MSM8660) ) {
2386 //For Single VFE output targets, use record dimensions as preview dimensions.
2387 previewWidth = videoWidth;
2388 previewHeight = videoHeight;
2389 mParameters.setPreviewSize(previewWidth, previewHeight);
2390 }
2391 } else {
2392 LOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize);
2393 return false;
2394 }
2395 }
2396
Mohan Kandra0d115d12010-08-19 11:47:15 -07002397 mDimension.display_width = previewWidth;
2398 mDimension.display_height= previewHeight;
2399
Sravankb4f5f1c2010-01-21 11:06:17 +05302400 LOGV("initPreview E: preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, videoWidth, videoHeight );
2401
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302402 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07002403 mDimension.video_width = CEILING16(videoWidth);
2404 /* Backup the video dimensions, as video dimensions in mDimension
2405 * will be modified when DIS is supported. Need the actual values
2406 * to pass ap part of VPE config
2407 */
2408 videoWidth = mDimension.video_width;
Sravankb4f5f1c2010-01-21 11:06:17 +05302409 mDimension.video_height = videoHeight;
2410 LOGV("initPreview : preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, mDimension.video_width, mDimension.video_height );
2411 }
2412
2413
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002414 mFrameThreadWaitLock.lock();
2415 while (mFrameThreadRunning) {
2416 LOGV("initPreview: waiting for old frame thread to complete.");
2417 mFrameThreadWait.wait(mFrameThreadWaitLock);
2418 LOGV("initPreview: old frame thread completed.");
2419 }
2420 mFrameThreadWaitLock.unlock();
2421
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002422 mInSnapshotModeWaitLock.lock();
2423 while (mInSnapshotMode) {
2424 LOGV("initPreview: waiting for snapshot mode to complete.");
2425 mInSnapshotModeWait.wait(mInSnapshotModeWaitLock);
2426 LOGV("initPreview: snapshot mode completed.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002427 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002428 mInSnapshotModeWaitLock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002429
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302430 /*Temporary migrating the preview buffers to smi pool for 8x60 till the bug is resolved in the pmem_adsp pool*/
2431 if(mCurrentTarget == TARGET_MSM8660)
2432 pmem_region = "/dev/pmem_smipool";
2433 else
2434 pmem_region = "/dev/pmem_adsp";
2435
2436
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002437 int cnt = 0;
2438 mPreviewFrameSize = previewWidth * previewHeight * 3/2;
Mohan Kandra02486042010-06-18 16:49:43 -07002439 int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
Mohan Kandra7110c242010-07-18 15:34:48 -07002440
2441 //Pass the yuv formats, display dimensions,
2442 //so that vfe will be initialized accordingly.
2443 mDimension.display_luma_width = previewWidth;
2444 mDimension.display_luma_height = previewHeight;
2445 mDimension.display_chroma_width = previewWidth;
2446 mDimension.display_chroma_height = previewHeight;
2447 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
2448 mPreviewFrameSize = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)) +
2449 2 * (CEILING32(previewWidth/2) * CEILING32(previewHeight/2));
2450 CbCrOffset = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight));
2451 mDimension.prev_format = CAMERA_YUV_420_NV21_ADRENO;
2452 mDimension.display_luma_width = CEILING32(previewWidth);
2453 mDimension.display_luma_height = CEILING32(previewHeight);
2454 mDimension.display_chroma_width = 2 * CEILING32(previewWidth/2);
2455 //Chroma Height is not needed as of now. Just sending with other dimensions.
2456 mDimension.display_chroma_height = CEILING32(previewHeight/2);
2457 }
2458 LOGV("mDimension.prev_format = %d", mDimension.prev_format);
2459 LOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
2460 LOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
2461 LOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
2462 LOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
2463
Mohan Kandrad9efed92010-01-15 19:08:39 -08002464 dstOffset = 0;
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302465 mPreviewHeap = new PmemPool(pmem_region,
Mohan Kandra284966d2010-01-05 13:39:15 -08002466 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
2467 mCameraControlFd,
Sravankb4f5f1c2010-01-21 11:06:17 +05302468 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
Mohan Kandra284966d2010-01-05 13:39:15 -08002469 mPreviewFrameSize,
Mohan Kandrad9efed92010-01-15 19:08:39 -08002470 kPreviewBufferCountActual,
Mohan Kandra284966d2010-01-05 13:39:15 -08002471 mPreviewFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002472 CbCrOffset,
2473 0,
Mohan Kandrad9efed92010-01-15 19:08:39 -08002474 "preview");
Mohan Kandra284966d2010-01-05 13:39:15 -08002475
Mohan Kandrad9efed92010-01-15 19:08:39 -08002476 if (!mPreviewHeap->initialized()) {
2477 mPreviewHeap.clear();
Mohan Kandra284966d2010-01-05 13:39:15 -08002478 LOGE("initPreview X: could not initialize Camera preview heap.");
2479 return false;
2480 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002481
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002482 //set DIS value to get the updated video width and height to calculate
2483 //the required record buffer size
2484 if(mVpeEnabled) {
2485 bool status = setDIS();
2486 if(status) {
2487 LOGE("Failed to set DIS");
2488 return false;
2489 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002490 }
Sravankb4f5f1c2010-01-21 11:06:17 +05302491
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002492 //Pass the original video width and height and get the required width
2493 //and height for record buffer allocation
2494 mDimension.orig_video_width = videoWidth;
2495 mDimension.orig_video_height = videoHeight;
2496
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002497 // mDimension will be filled with thumbnail_width, thumbnail_height,
2498 // orig_picture_dx, and orig_picture_dy after this function call. We need to
2499 // keep it for jpeg_encoder_encode.
Deepak Kurieneb58c682010-11-01 15:26:02 -07002500 bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002501 sizeof(cam_ctrl_dimension_t), &mDimension);
2502
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002503 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
2504
2505 // Allocate video buffers after allocating preview buffers.
Mohan Kandra6599e352010-11-15 12:23:36 -08002506 bool status = initRecord();
2507 if(status != true) {
2508 LOGE("Failed to allocate video bufers");
2509 return false;
2510 }
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002511 }
2512
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002513 if (ret) {
2514 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
Mohan Kandrad9efed92010-01-15 19:08:39 -08002515 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002516 frames[cnt].buffer =
Mohan Kandrad9efed92010-01-15 19:08:39 -08002517 (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002518 frames[cnt].y_off = 0;
Mohan Kandra02486042010-06-18 16:49:43 -07002519 frames[cnt].cbcr_off = CbCrOffset;
Sravankb4f5f1c2010-01-21 11:06:17 +05302520 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002521 }
2522
2523 mFrameThreadWaitLock.lock();
2524 pthread_attr_t attr;
2525 pthread_attr_init(&attr);
2526 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Sravankb4f5f1c2010-01-21 11:06:17 +05302527
2528 frame_parms.frame = frames[kPreviewBufferCount - 1];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002529
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302530 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660)
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002531 frame_parms.video_frame = recordframes[kPreviewBufferCount - 1];
2532 else
2533 frame_parms.video_frame = frames[kPreviewBufferCount - 1];
Sravankb4f5f1c2010-01-21 11:06:17 +05302534
2535 LOGV ("initpreview before cam_frame thread carete , video frame buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
2536 (unsigned long)frame_parms.video_frame.buffer, frame_parms.video_frame.fd, frame_parms.video_frame.y_off,
2537 frame_parms.video_frame.cbcr_off);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002538 mFrameThreadRunning = !pthread_create(&mFrameThread,
2539 &attr,
2540 frame_thread,
Sravankb4f5f1c2010-01-21 11:06:17 +05302541 (void*)&(frame_parms));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002542 ret = mFrameThreadRunning;
2543 mFrameThreadWaitLock.unlock();
2544 }
Priyanka Kharat02807662010-10-13 23:44:47 -07002545 mFirstFrame = true;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002546
2547 LOGV("initPreview X: %d", ret);
2548 return ret;
2549}
2550
2551void QualcommCameraHardware::deinitPreview(void)
2552{
2553 LOGI("deinitPreview E");
2554
2555 // When we call deinitPreview(), we signal to the frame thread that it
2556 // needs to exit, but we DO NOT WAIT for it to complete here. The problem
2557 // is that deinitPreview is sometimes called from the frame-thread's
2558 // callback, when the refcount on the Camera client reaches zero. If we
2559 // called pthread_join(), we would deadlock. So, we just call
2560 // LINK_camframe_terminate() in deinitPreview(), which makes sure that
2561 // after the preview callback returns, the camframe thread will exit. We
2562 // could call pthread_join() in initPreview() to join the last frame
2563 // thread. However, we would also have to call pthread_join() in release
2564 // as well, shortly before we destroy the object; this would cause the same
2565 // deadlock, since release(), like deinitPreview(), may also be called from
2566 // the frame-thread's callback. This we have to make the frame thread
2567 // detached, and use a separate mechanism to wait for it to complete.
2568
Kiran Kumar H N7ac84e32010-02-01 10:58:47 -08002569 LINK_camframe_terminate();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002570 LOGI("deinitPreview X");
2571}
2572
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002573bool QualcommCameraHardware::initRawSnapshot()
2574{
2575 LOGV("initRawSnapshot E");
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302576 const char * pmem_region;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002577
2578 //get width and height from Dimension Object
Deepak Kurieneb58c682010-11-01 15:26:02 -07002579 bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002580 sizeof(cam_ctrl_dimension_t), &mDimension);
2581
Deepak Kurieneb58c682010-11-01 15:26:02 -07002582
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002583 if(!ret){
2584 LOGE("initRawSnapshot X: failed to set dimension");
2585 return false;
2586 }
2587 int rawSnapshotSize = mDimension.raw_picture_height *
2588 mDimension.raw_picture_width;
2589
2590 LOGV("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
2591 "raw_picture_width = %d",
2592 rawSnapshotSize, mDimension.raw_picture_height,
2593 mDimension.raw_picture_width);
2594
2595 if (mRawSnapShotPmemHeap != NULL) {
2596 LOGV("initRawSnapshot: clearing old mRawSnapShotPmemHeap.");
2597 mRawSnapShotPmemHeap.clear();
2598 }
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302599 if(mCurrentTarget == TARGET_MSM8660)
Priyanka Kharat02807662010-10-13 23:44:47 -07002600 pmem_region = "/dev/pmem_smipool";
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302601 else
Priyanka Kharat02807662010-10-13 23:44:47 -07002602 pmem_region = "/dev/pmem_adsp";
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002603
2604 //Pmem based pool for Camera Driver
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302605 mRawSnapShotPmemHeap = new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002606 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002607 mCameraControlFd,
2608 MSM_PMEM_RAW_MAINIMG,
2609 rawSnapshotSize,
2610 1,
2611 rawSnapshotSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002612 0,
2613 0,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002614 "raw pmem snapshot camera");
2615
2616 if (!mRawSnapShotPmemHeap->initialized()) {
2617 mRawSnapShotPmemHeap.clear();
2618 LOGE("initRawSnapshot X: error initializing mRawSnapshotHeap");
2619 return false;
2620 }
2621 LOGV("initRawSnapshot X");
2622 return true;
2623
2624}
2625
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002626bool QualcommCameraHardware::initRaw(bool initJpegHeap)
2627{
2628 int rawWidth, rawHeight;
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302629 const char * pmem_region;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08002630
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002631 mParameters.getPictureSize(&rawWidth, &rawHeight);
2632 LOGV("initRaw E: picture size=%dx%d", rawWidth, rawHeight);
2633
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002634 int thumbnailBufferSize;
2635 //Thumbnail height should be smaller than Picture height
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002636 if (rawHeight > (int)thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height){
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002637 mDimension.ui_thumbnail_width =
2638 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
2639 mDimension.ui_thumbnail_height =
2640 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
2641 uint32_t pictureAspectRatio = (uint32_t)((rawWidth * Q12) / rawHeight);
2642 uint32_t i;
2643 for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ )
2644 {
2645 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio)
2646 {
2647 mDimension.ui_thumbnail_width = thumbnail_sizes[i].width;
2648 mDimension.ui_thumbnail_height = thumbnail_sizes[i].height;
2649 break;
2650 }
2651 }
2652 }
2653 else{
2654 mDimension.ui_thumbnail_height = THUMBNAIL_SMALL_HEIGHT;
2655 mDimension.ui_thumbnail_width =
2656 (THUMBNAIL_SMALL_HEIGHT * rawWidth)/ rawHeight;
2657 }
2658
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002659 if((mCurrentTarget == TARGET_MSM7630) ||
Sravanka7b89c82010-10-06 16:13:28 +05302660 (mCurrentTarget == TARGET_MSM7627) ||
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002661 (mCurrentTarget == TARGET_MSM8660)) {
2662 if(rawHeight < previewHeight) {
2663 mDimension.ui_thumbnail_height = THUMBNAIL_SMALL_HEIGHT;
2664 mDimension.ui_thumbnail_width =
2665 (THUMBNAIL_SMALL_HEIGHT * rawWidth)/ rawHeight;
2666 }
2667 /* store the thumbanil dimensions which are needed
2668 * by the jpeg downscaler to generate thumbnails from
2669 * main YUV image.
2670 */
2671 mThumbnailWidth = mDimension.ui_thumbnail_width;
2672 mThumbnailHeight = mDimension.ui_thumbnail_height;
2673 /* As thumbnail is generated from main YUV image,
2674 * configure and use the VFE other output to get
2675 * an image of preview dimensions for postView use.
2676 * So, mThumbnailHeap will be used for postview rather than
2677 * as thumbnail(Not changing the terminology to keep changes minimum).
2678 */
Vamshidhar Kondraf55cbfb2010-10-28 15:21:38 +05302679 if((rawHeight >= previewHeight) &&
2680 (mCurrentTarget != TARGET_MSM7627)) {
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002681 mDimension.ui_thumbnail_height = previewHeight;
Mohan Kandra2cd34e62010-10-06 18:15:56 -07002682 mDimension.ui_thumbnail_width =
2683 (previewHeight * rawWidth) / rawHeight;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002684 }
2685 }
2686
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002687 LOGV("Thumbnail Size Width %d Height %d",
2688 mDimension.ui_thumbnail_width,
2689 mDimension.ui_thumbnail_height);
2690
Mohan Kandra7110c242010-07-18 15:34:48 -07002691 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002692 mDimension.main_img_format = CAMERA_YUV_420_NV21_ADRENO;
2693 mDimension.thumb_format = CAMERA_YUV_420_NV21_ADRENO;
Mohan Kandra7110c242010-07-18 15:34:48 -07002694 }
Mohan Kandra2cd34e62010-10-06 18:15:56 -07002695
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002696 // mDimension will be filled with thumbnail_width, thumbnail_height,
2697 // orig_picture_dx, and orig_picture_dy after this function call. We need to
2698 // keep it for jpeg_encoder_encode.
Deepak Kurieneb58c682010-11-01 15:26:02 -07002699 bool ret = native_set_parms(CAMERA_PARM_DIMENSION,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002700 sizeof(cam_ctrl_dimension_t), &mDimension);
Deepak Kurieneb58c682010-11-01 15:26:02 -07002701
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002702 if(!ret) {
2703 LOGE("initRaw X: failed to set dimension");
2704 return false;
2705 }
2706
Mohan Kandra2cd34e62010-10-06 18:15:56 -07002707 thumbnailBufferSize = mDimension.ui_thumbnail_width *
2708 mDimension.ui_thumbnail_height * 3 / 2;
2709 int CbCrOffsetThumb = PAD_TO_WORD(mDimension.ui_thumbnail_width *
2710 mDimension.ui_thumbnail_height);
2711 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
2712 thumbnailBufferSize = PAD_TO_4K(CEILING32(mDimension.ui_thumbnail_width) *
2713 CEILING32(mDimension.ui_thumbnail_height)) +
2714 2 * (CEILING32(mDimension.ui_thumbnail_width/2) *
2715 CEILING32(mDimension.ui_thumbnail_height/2));
2716 CbCrOffsetThumb = PAD_TO_4K(CEILING32(mDimension.ui_thumbnail_width) *
2717 CEILING32(mDimension.ui_thumbnail_height));
2718 }
2719
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002720 if (mJpegHeap != NULL) {
2721 LOGV("initRaw: clearing old mJpegHeap.");
2722 mJpegHeap.clear();
2723 }
2724
2725 // Snapshot
2726 mRawSize = rawWidth * rawHeight * 3 / 2;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002727 mCbCrOffsetRaw = PAD_TO_WORD(rawWidth * rawHeight);
Mohan Kandra7110c242010-07-18 15:34:48 -07002728 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
2729 mRawSize = PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight)) +
2730 2 * (CEILING32(rawWidth/2) * CEILING32(rawHeight/2));
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002731 mCbCrOffsetRaw = PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight));
Mohan Kandra7110c242010-07-18 15:34:48 -07002732 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002733 if( mCurrentTarget == TARGET_MSM7627 )
Mohan Kandra7110c242010-07-18 15:34:48 -07002734 mJpegMaxSize = CEILING16(rawWidth) * CEILING16(rawHeight) * 3 / 2;
2735 else {
2736 mJpegMaxSize = rawWidth * rawHeight * 3 / 2;
2737 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
2738 mJpegMaxSize =
2739 PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight)) +
2740 2 * (CEILING32(rawWidth/2) * CEILING32(rawHeight/2));
2741 }
2742 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002743
Mohan Kandra02486042010-06-18 16:49:43 -07002744 //For offline jpeg hw encoder, jpeg encoder will provide us the
2745 //required offsets and buffer size depending on the rotation.
2746 int yOffset = 0;
Priyanka Kharat32409f72010-08-25 18:11:03 -07002747 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM7627) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra02486042010-06-18 16:49:43 -07002748 int rotation = mParameters.getInt("rotation");
2749 if (rotation >= 0) {
2750 LOGV("initRaw, jpeg_rotation = %d", rotation);
2751 if(!LINK_jpeg_encoder_setRotation(rotation)) {
2752 LOGE("native_jpeg_encode set rotation failed");
2753 return false;
2754 }
2755 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002756 //Don't call the get_buffer_offset() for ADRENO, as the width and height
2757 //for Adreno format will be of CEILING32.
2758 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002759 LINK_jpeg_encoder_get_buffer_offset(rawWidth, rawHeight, (uint32_t *)&yOffset,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002760 (uint32_t *)&mCbCrOffsetRaw, (uint32_t *)&mRawSize);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002761 mJpegMaxSize = mRawSize;
2762 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002763 LOGV("initRaw: yOffset = %d, mCbCrOffsetRaw = %d, mRawSize = %d",
2764 yOffset, mCbCrOffsetRaw, mRawSize);
2765 }
Mohan Kandra02486042010-06-18 16:49:43 -07002766
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302767 if(mCurrentTarget == TARGET_MSM8660)
Priyanka Kharat02807662010-10-13 23:44:47 -07002768 pmem_region = "/dev/pmem_smipool";
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302769 else
Priyanka Kharat02807662010-10-13 23:44:47 -07002770 pmem_region = "/dev/pmem_adsp";
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302771
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002772 LOGV("initRaw: initializing mRawHeap.");
2773 mRawHeap =
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302774 new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002775 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002776 mCameraControlFd,
2777 MSM_PMEM_MAINIMG,
2778 mJpegMaxSize,
2779 kRawBufferCount,
2780 mRawSize,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002781 mCbCrOffsetRaw,
Mohan Kandra02486042010-06-18 16:49:43 -07002782 yOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002783 "snapshot camera");
2784
2785 if (!mRawHeap->initialized()) {
Priyanka Kharat02807662010-10-13 23:44:47 -07002786 LOGE("initRaw X failed ");
2787 mRawHeap.clear();
2788 LOGE("initRaw X: error initializing mRawHeap");
2789 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002790 }
2791
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002792 //This is kind of workaround for the GPU limitation, as it can't
2793 //output in line to correct NV21 adreno formula for some snapshot
2794 //sizes (like 3264x2448). This change of cbcr offset will ensure that
2795 //chroma plane always starts at the beginning of a row.
2796 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO)
2797 mCbCrOffsetRaw = CEILING32(rawWidth) * CEILING32(rawHeight);
2798
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002799 LOGV("do_mmap snapshot pbuf = %p, pmem_fd = %d",
2800 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mHeap->getHeapID());
2801
2802 // Jpeg
2803
2804 if (initJpegHeap) {
2805 LOGV("initRaw: initializing mJpegHeap.");
2806 mJpegHeap =
2807 new AshmemPool(mJpegMaxSize,
2808 kJpegBufferCount,
2809 0, // we do not know how big the picture will be
2810 "jpeg");
2811
2812 if (!mJpegHeap->initialized()) {
2813 mJpegHeap.clear();
2814 mRawHeap.clear();
2815 LOGE("initRaw X failed: error initializing mJpegHeap.");
2816 return false;
2817 }
2818
2819 // Thumbnails
Mohan Kandra1552afe2010-09-02 12:54:01 -07002820 /* With the recent jpeg encoder downscaling changes for thumbnail padding,
2821 * HAL needs to call this API to get the offsets and buffer size.
2822 */
2823 int yOffsetThumb = 0;
2824 if((mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO)
2825 && (mCurrentTarget != TARGET_MSM7630)
2826 && (mCurrentTarget != TARGET_MSM8660)) {
2827 LINK_jpeg_encoder_get_buffer_offset(mDimension.thumbnail_width,
2828 mDimension.thumbnail_height,
2829 (uint32_t *)&yOffsetThumb,
2830 (uint32_t *)&CbCrOffsetThumb,
2831 (uint32_t *)&thumbnailBufferSize);
2832 }
Priyanka Kharat02807662010-10-13 23:44:47 -07002833 pmem_region = "/dev/pmem_adsp";
Mohan Kandra1552afe2010-09-02 12:54:01 -07002834
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002835 mThumbnailHeap =
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302836 new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002837 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002838 mCameraControlFd,
2839 MSM_PMEM_THUMBNAIL,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002840 thumbnailBufferSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002841 1,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002842 thumbnailBufferSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002843 CbCrOffsetThumb,
Mohan Kandra1552afe2010-09-02 12:54:01 -07002844 yOffsetThumb,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002845 "thumbnail");
2846
2847 if (!mThumbnailHeap->initialized()) {
2848 mThumbnailHeap.clear();
2849 mJpegHeap.clear();
2850 mRawHeap.clear();
2851 LOGE("initRaw X failed: error initializing mThumbnailHeap.");
2852 return false;
2853 }
2854 }
2855
2856 LOGV("initRaw X");
2857 return true;
2858}
2859
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002860
2861void QualcommCameraHardware::deinitRawSnapshot()
2862{
2863 LOGV("deinitRawSnapshot E");
2864 mRawSnapShotPmemHeap.clear();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002865 LOGV("deinitRawSnapshot X");
2866}
2867
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002868void QualcommCameraHardware::deinitRaw()
2869{
2870 LOGV("deinitRaw E");
2871
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002872 mJpegHeap.clear();
2873 mRawHeap.clear();
Priyanka Kharat02807662010-10-13 23:44:47 -07002874 if(mCurrentTarget != TARGET_MSM8660){
2875 mThumbnailHeap.clear();
2876 mDisplayHeap.clear();
2877 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002878
2879 LOGV("deinitRaw X");
2880}
2881
2882void QualcommCameraHardware::release()
2883{
Mohan Kandra0d115d12010-08-19 11:47:15 -07002884 LOGI("release E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002885 Mutex::Autolock l(&mLock);
2886
2887#if DLOPEN_LIBMMCAMERA
2888 if (libmmcamera == NULL) {
2889 LOGE("ERROR: multiple release!");
2890 return;
2891 }
2892#else
2893#warning "Cannot detect multiple release when not dlopen()ing libqcamera!"
2894#endif
2895
2896 int cnt, rc;
2897 struct msm_ctrl_cmd ctrlCmd;
Mohan Kandra0d115d12010-08-19 11:47:15 -07002898 LOGI("release: mCameraRunning = %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002899 if (mCameraRunning) {
2900 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
2901 mRecordFrameLock.lock();
2902 mReleasedRecordingFrame = true;
2903 mRecordWait.signal();
2904 mRecordFrameLock.unlock();
2905 }
2906 stopPreviewInternal();
Mohan Kandra0d115d12010-08-19 11:47:15 -07002907 LOGI("release: stopPreviewInternal done.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002908 }
Priyanka Kharat02807662010-10-13 23:44:47 -07002909 if(mCurrentTarget == TARGET_MSM8660) {
2910 LOGV("release : Clearing the mThumbnailHeap and mDisplayHeap");
2911 mPostViewHeap.clear();
2912 mPostViewHeap = NULL;
2913 mThumbnailHeap.clear();
2914 mThumbnailHeap = NULL;
2915 mDisplayHeap.clear();
2916 mDisplayHeap = NULL;
2917 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002918 LINK_jpeg_encoder_join();
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002919 //Signal the snapshot thread
2920 mJpegThreadWaitLock.lock();
2921 mJpegThreadRunning = false;
2922 mJpegThreadWait.signal();
2923 mJpegThreadWaitLock.unlock();
2924
Mohan Kandra4a55a832010-10-20 17:45:47 -07002925 // Wait for snapshot thread to complete before clearing the
2926 // resources.
2927 mSnapshotThreadWaitLock.lock();
2928 while (mSnapshotThreadRunning) {
2929 LOGV("takePicture: waiting for old snapshot thread to complete.");
2930 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
2931 LOGV("takePicture: old snapshot thread completed.");
2932 }
2933 mSnapshotThreadWaitLock.unlock();
2934
2935 {
2936 Mutex::Autolock l (&mRawPictureHeapLock);
2937 deinitRaw();
2938 }
2939
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002940 deinitRawSnapshot();
Mohan Kandra0d115d12010-08-19 11:47:15 -07002941 LOGI("release: clearing resources done.");
Deepak Kurieneb58c682010-11-01 15:26:02 -07002942 LINK_mm_camera_deinit(&mCfgControl, &mCamNotify, &mCamOps);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002943 close(mCameraControlFd);
2944 mCameraControlFd = -1;
Mohan Kandra284966d2010-01-05 13:39:15 -08002945 if(fb_fd >= 0) {
2946 close(fb_fd);
2947 fb_fd = -1;
2948 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002949#if DLOPEN_LIBMMCAMERA
2950 if (libmmcamera) {
2951 ::dlclose(libmmcamera);
2952 LOGV("dlclose(libqcamera)");
2953 libmmcamera = NULL;
2954 }
2955#endif
2956
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07002957 singleton_lock.lock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002958 singleton_releasing = true;
Srinivasan Kannan78444e42010-06-10 15:39:29 -07002959 singleton_releasing_start_time = systemTime();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07002960 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002961
Mohan Kandra0d115d12010-08-19 11:47:15 -07002962 LOGI("release X: mCameraRunning = %d, mFrameThreadRunning = %d", mCameraRunning, mFrameThreadRunning);
2963 LOGI("mVideoThreadRunning = %d, mSnapshotThreadRunning = %d, mJpegThreadRunning = %d", mVideoThreadRunning, mSnapshotThreadRunning, mJpegThreadRunning);
2964 LOGI("camframe_timeout_flag = %d, mAutoFocusThreadRunning = %d", camframe_timeout_flag, mAutoFocusThreadRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002965}
2966
2967QualcommCameraHardware::~QualcommCameraHardware()
2968{
Mohan Kandra0d115d12010-08-19 11:47:15 -07002969 LOGI("~QualcommCameraHardware E");
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07002970 singleton_lock.lock();
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002971
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302972 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660 ) {
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002973 delete [] recordframes;
2974 recordframes = NULL;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07002975 delete [] record_buffers_tracking_flag;
2976 record_buffers_tracking_flag = NULL;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002977 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002978 singleton.clear();
2979 singleton_releasing = false;
Srinivasan Kannan78444e42010-06-10 15:39:29 -07002980 singleton_releasing_start_time = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002981 singleton_wait.signal();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07002982 singleton_lock.unlock();
Mohan Kandra0d115d12010-08-19 11:47:15 -07002983 LOGI("~QualcommCameraHardware X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002984}
2985
2986sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
2987{
2988 LOGV("getRawHeap");
2989 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
2990}
2991
2992sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
2993{
2994 LOGV("getPreviewHeap");
Mohan Kandrad9efed92010-01-15 19:08:39 -08002995 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002996}
2997
Deepak Kurieneb58c682010-11-01 15:26:02 -07002998
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002999status_t QualcommCameraHardware::startPreviewInternal()
3000{
Sravankb4f5f1c2010-01-21 11:06:17 +05303001 LOGV("in startPreviewInternal : E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003002 if(mCameraRunning) {
3003 LOGV("startPreview X: preview already running.");
3004 return NO_ERROR;
3005 }
3006
3007 if (!mPreviewInitialized) {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08003008 mLastQueuedFrame = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003009 mPreviewInitialized = initPreview();
3010 if (!mPreviewInitialized) {
3011 LOGE("startPreview X initPreview failed. Not starting preview.");
3012 return UNKNOWN_ERROR;
3013 }
3014 }
3015
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003016 {
3017 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3018 if(( mCurrentTarget != TARGET_MSM7630 ) &&
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303019 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
Deepak Kurieneb58c682010-11-01 15:26:02 -07003020 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003021 else
Deepak Kurieneb58c682010-11-01 15:26:02 -07003022 mCameraRunning = native_start_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003023 }
Sravankb4f5f1c2010-01-21 11:06:17 +05303024
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003025 if(!mCameraRunning) {
3026 deinitPreview();
3027 mPreviewInitialized = false;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08003028 mOverlay = NULL;
Deepak Kurieneb58c682010-11-01 15:26:02 -07003029 LOGE("startPreview X: native_start_ops: CAMERA_OPS_STREAMING_PREVIEW ioctl failed!");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003030 return UNKNOWN_ERROR;
3031 }
3032
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08003033 //Reset the Gps Information
3034 exif_table_numEntries = 0;
Mohan Kandra284966d2010-01-05 13:39:15 -08003035
Sravankb4f5f1c2010-01-21 11:06:17 +05303036 LOGV("startPreviewInternal X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003037 return NO_ERROR;
3038}
3039
3040status_t QualcommCameraHardware::startPreview()
3041{
3042 LOGV("startPreview E");
3043 Mutex::Autolock l(&mLock);
3044 return startPreviewInternal();
3045}
3046
3047void QualcommCameraHardware::stopPreviewInternal()
3048{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003049 LOGI("stopPreviewInternal E: %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003050 if (mCameraRunning) {
3051 // Cancel auto focus.
3052 {
3053 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
3054 cancelAutoFocusInternal();
3055 }
3056 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003057
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003058 Mutex::Autolock l(&mCamframeTimeoutLock);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003059 {
3060 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3061 if(!camframe_timeout_flag) {
3062 if (( mCurrentTarget != TARGET_MSM7630 ) &&
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303063 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
Deepak Kurieneb58c682010-11-01 15:26:02 -07003064 mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_PREVIEW, NULL);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003065 else
Deepak Kurieneb58c682010-11-01 15:26:02 -07003066 mCameraRunning = !native_stop_ops(CAMERA_OPS_STREAMING_VIDEO, NULL);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003067 } else {
3068 /* This means that the camframetimeout was issued.
3069 * But we did not issue native_stop_preview(), so we
3070 * need to update mCameraRunning to indicate that
3071 * Camera is no longer running. */
3072 mCameraRunning = 0;
3073 }
3074 }
Sravankb4f5f1c2010-01-21 11:06:17 +05303075
Kiran Kumar H Nac2f4952009-12-17 01:16:53 -08003076 if (!mCameraRunning && mPreviewInitialized) {
3077 deinitPreview();
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303078 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra156d0ac2010-01-25 16:59:17 -08003079 mVideoThreadWaitLock.lock();
3080 LOGV("in stopPreviewInternal: making mVideoThreadExit 1");
3081 mVideoThreadExit = 1;
3082 mVideoThreadWaitLock.unlock();
3083 // 720p : signal the video thread , and check in video thread if stop is called, if so exit video thread.
3084 pthread_mutex_lock(&(g_busy_frame_queue.mut));
3085 pthread_cond_signal(&(g_busy_frame_queue.wait));
3086 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Mohan Kandra1ade9a82010-03-02 10:11:26 -08003087 /* Flush the Busy Q */
3088 cam_frame_flush_video();
3089 /* Flush the Free Q */
3090 LINK_cam_frame_flush_free_video();
Mohan Kandra156d0ac2010-01-25 16:59:17 -08003091 }
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003092 mPreviewInitialized = false;
3093 }
Kiran Kumar H Nac2f4952009-12-17 01:16:53 -08003094 else LOGE("stopPreviewInternal: failed to stop preview");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003095 }
Mohan Kandra2cd34e62010-10-06 18:15:56 -07003096
Mohan Kandra0d115d12010-08-19 11:47:15 -07003097 LOGI("stopPreviewInternal X: %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003098}
3099
3100void QualcommCameraHardware::stopPreview()
3101{
3102 LOGV("stopPreview: E");
3103 Mutex::Autolock l(&mLock);
3104 {
3105 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
3106 return;
3107 }
3108 stopPreviewInternal();
3109 LOGV("stopPreview: X");
3110}
3111
3112void QualcommCameraHardware::runAutoFocus()
3113{
3114 bool status = true;
3115 void *libhandle = NULL;
Srinivasan Kannan71229622009-12-04 12:05:58 -08003116 isp3a_af_mode_t afMode;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003117
3118 mAutoFocusThreadLock.lock();
3119 // Skip autofocus if focus mode is infinity.
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003120 if ((mParameters.get(CameraParameters::KEY_FOCUS_MODE) == 0)
3121 || (strcmp(mParameters.get(CameraParameters::KEY_FOCUS_MODE),
3122 CameraParameters::FOCUS_MODE_INFINITY) == 0)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003123 goto done;
3124 }
3125
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003126#if DLOPEN_LIBMMCAMERA
3127 // We need to maintain a reference to libqcamera.so for the duration of the
3128 // AF thread, because we do not know when it will exit relative to the
3129 // lifetime of this object. We do not want to dlclose() libqcamera while
3130 // LINK_cam_frame is still running.
3131 libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
3132 LOGV("AF: loading libqcamera at %p", libhandle);
3133 if (!libhandle) {
3134 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003135 mAutoFocusThreadRunning = false;
3136 mAutoFocusThreadLock.unlock();
3137 return;
3138 }
3139#endif
3140
Srinivasan Kannan71229622009-12-04 12:05:58 -08003141 afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
3142 sizeof(focus_modes) / sizeof(str_map),
3143 mParameters.get(CameraParameters::KEY_FOCUS_MODE));
3144
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003145 /* This will block until either AF completes or is cancelled. */
Deepak Kurieneb58c682010-11-01 15:26:02 -07003146 LOGV("af start (mode %d)", afMode);
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003147 status_t err;
3148 err = mAfLock.tryLock();
3149 if(err == NO_ERROR) {
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003150 {
3151 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3152 if(mCameraRunning){
3153 LOGV("Start AF");
Deepak Kurieneb58c682010-11-01 15:26:02 -07003154 status = native_start_ops(CAMERA_OPS_FOCUS ,(void *)&afMode);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003155 }else{
3156 LOGV("As Camera preview is not running, AF not issued");
3157 status = false;
3158 }
3159 }
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003160 mAfLock.unlock();
3161 }
3162 else{
3163 //AF Cancel would have acquired the lock,
3164 //so, no need to perform any AF
Srinivasan Kannan99e82422010-02-28 15:32:16 -08003165 LOGV("As Cancel auto focus is in progress, auto focus request "
3166 "is ignored");
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003167 status = FALSE;
3168 }
3169
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003170 LOGV("af done: %d", (int)status);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003171
3172done:
3173 mAutoFocusThreadRunning = false;
3174 mAutoFocusThreadLock.unlock();
3175
3176 mCallbackLock.lock();
3177 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
3178 notify_callback cb = mNotifyCallback;
3179 void *data = mCallbackCookie;
3180 mCallbackLock.unlock();
3181 if (autoFocusEnabled)
3182 cb(CAMERA_MSG_FOCUS, status, 0, data);
3183
3184#if DLOPEN_LIBMMCAMERA
3185 if (libhandle) {
3186 ::dlclose(libhandle);
3187 LOGV("AF: dlclose(libqcamera)");
3188 }
3189#endif
3190}
3191
3192status_t QualcommCameraHardware::cancelAutoFocusInternal()
3193{
3194 LOGV("cancelAutoFocusInternal E");
3195
Deepak Kurieneb58c682010-11-01 15:26:02 -07003196 if(!mHasAutoFocusSupport){
Srinivasan Kannan71229622009-12-04 12:05:58 -08003197 LOGV("cancelAutoFocusInternal X");
3198 return NO_ERROR;
3199 }
3200
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003201 status_t rc = NO_ERROR;
3202 status_t err;
3203 err = mAfLock.tryLock();
3204 if(err == NO_ERROR) {
3205 //Got Lock, means either AF hasn't started or
3206 // AF is done. So no need to cancel it, just change the state
Srinivasan Kannan99e82422010-02-28 15:32:16 -08003207 LOGV("As Auto Focus is not in progress, Cancel Auto Focus "
3208 "is ignored");
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003209 mAfLock.unlock();
3210 }
3211 else {
3212 //AF is in Progess, So cancel it
3213 LOGV("Lock busy...cancel AF");
Deepak Kurieneb58c682010-11-01 15:26:02 -07003214 rc = native_stop_ops(CAMERA_OPS_FOCUS, NULL) ?
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003215 NO_ERROR :
3216 UNKNOWN_ERROR;
3217 }
3218
3219
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003220
3221 LOGV("cancelAutoFocusInternal X: %d", rc);
3222 return rc;
3223}
3224
3225void *auto_focus_thread(void *user)
3226{
3227 LOGV("auto_focus_thread E");
3228 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3229 if (obj != 0) {
3230 obj->runAutoFocus();
3231 }
3232 else LOGW("not starting autofocus: the object went away!");
3233 LOGV("auto_focus_thread X");
3234 return NULL;
3235}
3236
3237status_t QualcommCameraHardware::autoFocus()
3238{
3239 LOGV("autoFocus E");
3240 Mutex::Autolock l(&mLock);
3241
Deepak Kurieneb58c682010-11-01 15:26:02 -07003242 if(!mHasAutoFocusSupport){
Srinivasan Kannandf085222009-12-09 18:31:00 -08003243 bool status = false;
3244 mCallbackLock.lock();
3245 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
3246 notify_callback cb = mNotifyCallback;
3247 void *data = mCallbackCookie;
3248 mCallbackLock.unlock();
3249 if (autoFocusEnabled)
3250 cb(CAMERA_MSG_FOCUS, status, 0, data);
Srinivasan Kannan71229622009-12-04 12:05:58 -08003251 LOGV("autoFocus X");
3252 return NO_ERROR;
3253 }
3254
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003255 if (mCameraControlFd < 0) {
3256 LOGE("not starting autofocus: main control fd %d", mCameraControlFd);
3257 return UNKNOWN_ERROR;
3258 }
3259
3260 {
3261 mAutoFocusThreadLock.lock();
3262 if (!mAutoFocusThreadRunning) {
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003263
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003264 // Create a detached thread here so that we don't have to wait
3265 // for it when we cancel AF.
3266 pthread_t thr;
3267 pthread_attr_t attr;
3268 pthread_attr_init(&attr);
3269 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3270 mAutoFocusThreadRunning =
3271 !pthread_create(&thr, &attr,
3272 auto_focus_thread, NULL);
3273 if (!mAutoFocusThreadRunning) {
3274 LOGE("failed to start autofocus thread");
3275 mAutoFocusThreadLock.unlock();
3276 return UNKNOWN_ERROR;
3277 }
3278 }
3279 mAutoFocusThreadLock.unlock();
3280 }
3281
3282 LOGV("autoFocus X");
3283 return NO_ERROR;
3284}
3285
3286status_t QualcommCameraHardware::cancelAutoFocus()
3287{
3288 LOGV("cancelAutoFocus E");
3289 Mutex::Autolock l(&mLock);
3290
3291 int rc = NO_ERROR;
3292 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
3293 rc = cancelAutoFocusInternal();
3294 }
3295
3296 LOGV("cancelAutoFocus X");
3297 return rc;
3298}
3299
3300void QualcommCameraHardware::runSnapshotThread(void *data)
3301{
Mohan Kandra6c04d092010-10-26 17:11:26 -07003302 bool ret = true;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003303 LOGV("runSnapshotThread E");
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003304#if DLOPEN_LIBMMCAMERA
3305 // We need to maintain a reference to libqcamera.so for the duration of the
3306 // Snapshot thread, because we do not know when it will exit relative to the
3307 // lifetime of this object. We do not want to dlclose() libqcamera while
3308 // LINK_cam_frame is still running.
3309 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
3310 LOGV("SNAPSHOT: loading libqcamera at %p", libhandle);
3311 if (!libhandle) {
3312 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
3313 }
3314#endif
3315
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003316 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
Deepak Kurieneb58c682010-11-01 15:26:02 -07003317 if (native_start_ops(CAMERA_OPS_SNAPSHOT, NULL))
Mohan Kandra6c04d092010-10-26 17:11:26 -07003318 ret = receiveRawPicture();
3319 else {
Deepak Kurieneb58c682010-11-01 15:26:02 -07003320 LOGE("main: snapshot failed! [CAMERA_OPS_SNAPSHOT]");
Mohan Kandra6c04d092010-10-26 17:11:26 -07003321 ret = false;
3322 }
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003323 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
Deepak Kurieneb58c682010-11-01 15:26:02 -07003324 if (native_start_ops(CAMERA_OPS_RAW_SNAPSHOT, NULL)) {
Mohan Kandra6c04d092010-10-26 17:11:26 -07003325 ret = receiveRawSnapshot();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003326 } else {
Deepak Kurieneb58c682010-11-01 15:26:02 -07003327 LOGE("main: raw_snapshot failed! [ CAMERA_OPS_RAW_SNAPSHOT]");
Mohan Kandra6c04d092010-10-26 17:11:26 -07003328 ret = false;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003329 }
3330 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003331 mInSnapshotModeWaitLock.lock();
3332 mInSnapshotMode = false;
3333 mInSnapshotModeWait.signal();
3334 mInSnapshotModeWaitLock.unlock();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003335
3336 mSnapshotFormat = 0;
Mohan Kandra4ebb9102010-11-09 17:52:30 -08003337 if(strTexturesOn != true ) {
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003338 mJpegThreadWaitLock.lock();
3339 while (mJpegThreadRunning) {
3340 LOGV("runSnapshotThread: waiting for jpeg thread to complete.");
3341 mJpegThreadWait.wait(mJpegThreadWaitLock);
3342 LOGV("runSnapshotThread: jpeg thread completed.");
3343 }
3344 mJpegThreadWaitLock.unlock();
3345 //clear the resources
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003346#if DLOPEN_LIBMMCAMERA
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003347 if(libhandle)
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003348#endif
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003349 {
3350 LINK_jpeg_encoder_join();
3351 }
3352 deinitRaw();
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003353 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003354
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003355 mSnapshotThreadWaitLock.lock();
3356 mSnapshotThreadRunning = false;
3357 mSnapshotThreadWait.signal();
3358 mSnapshotThreadWaitLock.unlock();
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003359#if DLOPEN_LIBMMCAMERA
3360 if (libhandle) {
3361 ::dlclose(libhandle);
3362 LOGV("SNAPSHOT: dlclose(libqcamera)");
3363 }
3364#endif
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003365
Mohan Kandra6c04d092010-10-26 17:11:26 -07003366 if( (ret == false) && mDataCallback
3367 && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
3368 /* get picture failed. Give jpeg callback with NULL data
3369 * to the application to restore to preview mode
3370 */
3371 LOGE("get picture failed, giving jpeg callback with NULL data");
3372 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, NULL, mCallbackCookie);
3373 }
3374
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003375 LOGV("runSnapshotThread X");
3376}
3377
3378void *snapshot_thread(void *user)
3379{
3380 LOGD("snapshot_thread E");
3381 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3382 if (obj != 0) {
3383 obj->runSnapshotThread(user);
3384 }
3385 else LOGW("not starting snapshot thread: the object went away!");
3386 LOGD("snapshot_thread X");
3387 return NULL;
3388}
3389
3390status_t QualcommCameraHardware::takePicture()
3391{
3392 LOGV("takePicture(%d)", mMsgEnabled);
3393 Mutex::Autolock l(&mLock);
3394
Mohan Kandra4ebb9102010-11-09 17:52:30 -08003395 if(strTexturesOn == true){
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003396 mEncodePendingWaitLock.lock();
3397 while(mEncodePending) {
3398 LOGE("takePicture: Frame given to application, waiting for encode call");
3399 mEncodePendingWait.wait(mEncodePendingWaitLock);
3400 LOGE("takePicture: Encode of the application data is done");
3401 }
3402 mEncodePendingWaitLock.unlock();
3403 }
3404
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003405 // Wait for old snapshot thread to complete.
3406 mSnapshotThreadWaitLock.lock();
3407 while (mSnapshotThreadRunning) {
3408 LOGV("takePicture: waiting for old snapshot thread to complete.");
3409 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
3410 LOGV("takePicture: old snapshot thread completed.");
3411 }
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003412 //mSnapshotFormat is protected by mSnapshotThreadWaitLock
3413 if(mParameters.getPictureFormat() != 0 &&
3414 !strcmp(mParameters.getPictureFormat(),
3415 CameraParameters::PIXEL_FORMAT_RAW))
3416 mSnapshotFormat = PICTURE_FORMAT_RAW;
3417 else
3418 mSnapshotFormat = PICTURE_FORMAT_JPEG;
3419
3420 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
Apurva Rajguru019a0a72010-10-26 16:26:48 -07003421 if(!native_start_ops(CAMERA_OPS_PREPARE_SNAPSHOT, NULL)) {
3422 mSnapshotThreadWaitLock.unlock();
3423 LOGE("PREPARE SNAPSHOT: CAMERA_OPS_PREPARE_SNAPSHOT ioctl Failed");
3424 return UNKNOWN_ERROR;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003425 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003426 }
Priyanka Kharat02807662010-10-13 23:44:47 -07003427 if(mCurrentTarget == TARGET_MSM8660) {
3428 /* Store the last frame queued for preview. This
3429 * shall be used as postview */
3430 if (!(storePreviewFrameForPostview()))
3431 return UNKNOWN_ERROR;
3432 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003433 stopPreviewInternal();
3434
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003435 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3436 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
3437 LOGE("initRaw failed. Not taking picture.");
3438 mSnapshotThreadWaitLock.unlock();
3439 return UNKNOWN_ERROR;
3440 }
3441 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
3442 if(!initRawSnapshot()){
3443 LOGE("initRawSnapshot failed. Not taking picture.");
3444 mSnapshotThreadWaitLock.unlock();
3445 return UNKNOWN_ERROR;
3446 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003447 }
3448
3449 mShutterLock.lock();
3450 mShutterPending = true;
3451 mShutterLock.unlock();
3452
3453 pthread_attr_t attr;
3454 pthread_attr_init(&attr);
3455 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3456 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
3457 &attr,
3458 snapshot_thread,
3459 NULL);
3460 mSnapshotThreadWaitLock.unlock();
3461
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003462 mInSnapshotModeWaitLock.lock();
3463 mInSnapshotMode = true;
3464 mInSnapshotModeWaitLock.unlock();
3465
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003466 LOGV("takePicture: X");
3467 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
3468}
3469
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05303470void QualcommCameraHardware::set_liveshot_exifinfo()
3471{
3472 setGpsParameters();
3473 //set TimeStamp
3474 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
3475 if(str != NULL) {
3476 strncpy(dateTime, str, 19);
3477 dateTime[19] = '\0';
3478 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
3479 20, 1, (void *)dateTime);
3480 }
3481}
3482
3483status_t QualcommCameraHardware::takeLiveSnapshot()
3484{
3485 LOGV("takeLiveSnapshot: E ");
3486 Mutex::Autolock l(&mLock);
3487
3488 if(liveshot_state == LIVESHOT_IN_PROGRESS || !recordingState) {
3489 return NO_ERROR;
3490 }
3491
3492 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)) {
3493 LOGI("LiveSnapshot not supported on this target");
3494 liveshot_state = LIVESHOT_STOPPED;
3495 return NO_ERROR;
3496 }
3497
3498 liveshot_state = LIVESHOT_IN_PROGRESS;
3499
3500 if (!initLiveSnapshot(videoWidth, videoHeight)) {
3501 LOGE("takeLiveSnapshot: Jpeg Heap Memory allocation failed. Not taking Live Snapshot.");
3502 liveshot_state = LIVESHOT_STOPPED;
3503 return UNKNOWN_ERROR;
3504 }
3505
3506 uint32_t maxjpegsize = videoWidth * videoHeight *1.5;
3507 set_liveshot_exifinfo();
3508 if(!LINK_set_liveshot_params(videoWidth, videoHeight,
3509 exif_data, exif_table_numEntries,
3510 (uint8_t *)mJpegHeap->mHeap->base(), maxjpegsize)) {
3511 LOGE("Link_set_liveshot_params failed.");
3512 mJpegHeap.clear();
3513 return NO_ERROR;
3514 }
3515
Deepak Kurieneb58c682010-11-01 15:26:02 -07003516 if(!native_start_ops(CAMERA_OPS_LIVESHOT, NULL)) {
3517 LOGE("start_liveshot ioctl failed");
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05303518 liveshot_state = LIVESHOT_STOPPED;
3519 mJpegHeap.clear();
3520 return UNKNOWN_ERROR;
3521 }
3522
3523 LOGV("takeLiveSnapshot: X");
3524 return NO_ERROR;
3525}
3526
3527bool QualcommCameraHardware::initLiveSnapshot(int videowidth, int videoheight)
3528{
3529 LOGV("initLiveSnapshot E");
3530
3531 if (mJpegHeap != NULL) {
3532 LOGV("initLiveSnapshot: clearing old mJpegHeap.");
3533 mJpegHeap.clear();
3534 }
3535
3536 mJpegMaxSize = videowidth * videoheight * 1.5;
3537
3538 LOGV("initLiveSnapshot: initializing mJpegHeap.");
3539 mJpegHeap =
3540 new AshmemPool(mJpegMaxSize,
3541 kJpegBufferCount,
3542 0, // we do not know how big the picture will be
3543 "jpeg");
3544
3545 if (!mJpegHeap->initialized()) {
3546 mJpegHeap.clear();
3547 LOGE("initLiveSnapshot X failed: error initializing mJpegHeap.");
3548 return false;
3549 }
3550
3551 LOGV("initLiveSnapshot X");
3552 return true;
3553}
3554
3555
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003556status_t QualcommCameraHardware::cancelPicture()
3557{
3558 status_t rc;
3559 LOGV("cancelPicture: E");
Apurva Rajguru3da1a702010-07-28 12:32:42 -07003560 if (mCurrentTarget == TARGET_MSM7627) {
3561 mSnapshotDone = TRUE;
3562 mSnapshotThreadWaitLock.lock();
3563 while (mSnapshotThreadRunning) {
3564 LOGV("cancelPicture: waiting for snapshot thread to complete.");
3565 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
3566 LOGV("cancelPicture: snapshot thread completed.");
3567 }
3568 mSnapshotThreadWaitLock.unlock();
3569 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07003570 rc = native_stop_ops(CAMERA_OPS_SNAPSHOT, NULL) ? NO_ERROR : UNKNOWN_ERROR;
Apurva Rajguru3da1a702010-07-28 12:32:42 -07003571 mSnapshotDone = FALSE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003572 LOGV("cancelPicture: X: %d", rc);
3573 return rc;
3574}
3575
3576status_t QualcommCameraHardware::setParameters(const CameraParameters& params)
3577{
3578 LOGV("setParameters: E params = %p", &params);
3579
3580 Mutex::Autolock l(&mLock);
3581 status_t rc, final_rc = NO_ERROR;
3582
3583 if ((rc = setPreviewSize(params))) final_rc = rc;
3584 if ((rc = setPictureSize(params))) final_rc = rc;
Srinivasan Kannan264376e2010-08-13 18:54:35 -07003585 if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003586 if ((rc = setJpegQuality(params))) final_rc = rc;
Vamshidhar Kondrae7b9b5a2010-02-25 15:40:37 +05303587 if ((rc = setEffect(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003588 if ((rc = setGpsLocation(params))) final_rc = rc;
3589 if ((rc = setRotation(params))) final_rc = rc;
3590 if ((rc = setZoom(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003591 if ((rc = setOrientation(params))) final_rc = rc;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05303592 if ((rc = setLensshadeValue(params))) final_rc = rc;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003593 if ((rc = setPictureFormat(params))) final_rc = rc;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08003594 if ((rc = setSharpness(params))) final_rc = rc;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08003595 if ((rc = setSaturation(params))) final_rc = rc;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07003596 if ((rc = setContinuousAf(params))) final_rc = rc;
Apurva Rajgurue5965c42010-09-09 14:24:54 -07003597 if ((rc = setSelectableZoneAf(params))) final_rc = rc;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07003598 if ((rc = setTouchAfAec(params))) final_rc = rc;
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003599 if ((rc = setSceneMode(params))) final_rc = rc;
Apurva Rajguru08383852010-05-17 14:25:39 -07003600 if ((rc = setContrast(params))) final_rc = rc;
Mohan Kandra091d5ab2010-07-14 16:53:25 -07003601 if ((rc = setRecordSize(params))) final_rc = rc;
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07003602 if ((rc = setSceneDetect(params))) final_rc = rc;
Mohan Kandra7110c242010-07-18 15:34:48 -07003603 if ((rc = setStrTextures(params))) final_rc = rc;
3604 if ((rc = setPreviewFormat(params))) final_rc = rc;
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07003605 if ((rc = setSkinToneEnhancement(params))) final_rc = rc;
Deepak Kuriencbd25d92010-10-08 10:16:08 -07003606 if ((rc = setAntibanding(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003607
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003608 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
3609 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
3610
3611 if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF)) {
3612 if ((rc = setPreviewFrameRate(params))) final_rc = rc;
3613 if ((rc = setPreviewFrameRateMode(params))) final_rc = rc;
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003614 if ((rc = setAutoExposure(params))) final_rc = rc;
3615 if ((rc = setExposureCompensation(params))) final_rc = rc;
3616 if ((rc = setWhiteBalance(params))) final_rc = rc;
3617 if ((rc = setFlash(params))) final_rc = rc;
3618 if ((rc = setFocusMode(params))) final_rc = rc;
3619 if ((rc = setBrightness(params))) final_rc = rc;
3620 if ((rc = setISOValue(params))) final_rc = rc;
3621 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003622 LOGV("setParameters: X");
3623 return final_rc;
3624}
3625
3626CameraParameters QualcommCameraHardware::getParameters() const
3627{
3628 LOGV("getParameters: EX");
3629 return mParameters;
3630}
Nishant Pandit741742b2010-09-21 03:24:20 +05303631status_t QualcommCameraHardware::setHistogramOn()
3632{
3633 LOGV("setHistogramOn: EX");
3634
3635 mStatsWaitLock.lock();
3636 mSendData = true;
3637 if(mStatsOn == CAMERA_HISTOGRAM_ENABLE) {
3638 mStatsWaitLock.unlock();
3639 return NO_ERROR;
3640 }
3641
3642 if (mStatHeap != NULL) {
3643 LOGV("setHistogram on: clearing old mStatHeap.");
3644 mStatHeap.clear();
3645 }
3646
3647 mStatSize = sizeof(uint32_t)* HISTOGRAM_STATS_SIZE;
3648 mCurrent = -1;
3649 /*Currently the Ashmem is multiplying the buffer size with total number
3650 of buffers and page aligning. This causes a crash in JNI as each buffer
3651 individually expected to be page aligned */
3652 int page_size_minus_1 = getpagesize() - 1;
3653 int32_t mAlignedStatSize = ((mStatSize + page_size_minus_1) & (~page_size_minus_1));
3654
3655 mStatHeap =
3656 new AshmemPool(mAlignedStatSize,
3657 3,
3658 mStatSize,
3659 "stat");
3660 if (!mStatHeap->initialized()) {
3661 LOGE("Stat Heap X failed ");
3662 mStatHeap.clear();
3663 LOGE("setHistogramOn X: error initializing mStatHeap");
3664 mStatsWaitLock.unlock();
3665 return UNKNOWN_ERROR;
3666 }
3667 mStatsOn = CAMERA_HISTOGRAM_ENABLE;
3668
3669 mStatsWaitLock.unlock();
3670 mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn);
3671 return NO_ERROR;
3672
3673}
3674
3675status_t QualcommCameraHardware::setHistogramOff()
3676{
3677 LOGV("setHistogramOff: EX");
3678 mStatsWaitLock.lock();
3679 if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) {
3680 mStatsWaitLock.unlock();
3681 return NO_ERROR;
3682 }
3683 mStatsOn = CAMERA_HISTOGRAM_DISABLE;
3684 mStatsWaitLock.unlock();
3685
3686 mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn);
3687
3688 mStatsWaitLock.lock();
3689 mStatHeap.clear();
3690 mStatsWaitLock.unlock();
3691
3692 return NO_ERROR;
3693}
3694
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003695
3696status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
3697 int32_t arg2)
3698{
3699 LOGV("sendCommand: EX");
Nishant Pandit741742b2010-09-21 03:24:20 +05303700 Mutex::Autolock l(&mLock);
3701
3702 switch(command) {
3703
3704 case CAMERA_CMD_HISTOGRAM_ON:
3705 LOGV("histogram set to on");
3706 return setHistogramOn();
3707 case CAMERA_CMD_HISTOGRAM_OFF:
3708 LOGV("histogram set to off");
3709 return setHistogramOff();
3710 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
3711 mStatsWaitLock.lock();
3712 if(mStatsOn == CAMERA_HISTOGRAM_ENABLE)
3713 mSendData = true;
3714 mStatsWaitLock.unlock();
3715 return NO_ERROR;
3716 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003717 return BAD_VALUE;
3718}
3719
3720extern "C" sp<CameraHardwareInterface> openCameraHardware()
3721{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003722 LOGI("openCameraHardware: call createInstance");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003723 return QualcommCameraHardware::createInstance();
3724}
3725
3726wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
3727
3728// If the hardware already exists, return a strong pointer to the current
3729// object. If not, create a new hardware object, put it in the singleton,
3730// and return it.
3731sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
3732{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003733 LOGI("createInstance: E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003734
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003735 singleton_lock.lock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003736
3737 // Wait until the previous release is done.
3738 while (singleton_releasing) {
Srinivasan Kannan78444e42010-06-10 15:39:29 -07003739 if((singleton_releasing_start_time != 0) &&
3740 (systemTime() - singleton_releasing_start_time) > SINGLETON_RELEASING_WAIT_TIME){
3741 LOGV("in createinstance system time is %lld %lld %lld ",
3742 systemTime(), singleton_releasing_start_time, SINGLETON_RELEASING_WAIT_TIME);
3743 singleton_lock.unlock();
3744 LOGE("Previous singleton is busy and time out exceeded. Returning null");
3745 return NULL;
3746 }
3747 LOGI("Wait for previous release.");
3748 singleton_wait.waitRelative(singleton_lock, SINGLETON_RELEASING_RECHECK_TIMEOUT);
3749 LOGI("out of Wait for previous release.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003750 }
3751
3752 if (singleton != 0) {
3753 sp<CameraHardwareInterface> hardware = singleton.promote();
3754 if (hardware != 0) {
3755 LOGD("createInstance: X return existing hardware=%p", &(*hardware));
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003756 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003757 return hardware;
3758 }
3759 }
3760
3761 {
3762 struct stat st;
3763 int rc = stat("/dev/oncrpc", &st);
3764 if (rc < 0) {
3765 LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003766 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003767 return NULL;
3768 }
3769 }
3770
3771 QualcommCameraHardware *cam = new QualcommCameraHardware();
3772 sp<QualcommCameraHardware> hardware(cam);
3773 singleton = hardware;
3774
Mohan Kandra0d115d12010-08-19 11:47:15 -07003775 LOGI("createInstance: created hardware=%p", &(*hardware));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003776 if (!cam->startCamera()) {
3777 LOGE("%s: startCamera failed!", __FUNCTION__);
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003778 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003779 return NULL;
3780 }
3781
3782 cam->initDefaultParameters();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003783 singleton_lock.unlock();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003784 LOGI("createInstance: X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003785 return hardware;
3786}
3787
3788// For internal use only, hence the strong pointer to the derived type.
3789sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
3790{
3791 sp<CameraHardwareInterface> hardware = singleton.promote();
3792 if (hardware != 0) {
3793 // LOGV("getInstance: X old instance of hardware");
3794 return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
3795 } else {
3796 LOGV("getInstance: X new instance of hardware");
3797 return sp<QualcommCameraHardware>();
3798 }
3799}
Sravankb4f5f1c2010-01-21 11:06:17 +05303800void QualcommCameraHardware::receiveRecordingFrame(struct msm_frame *frame)
3801{
3802 LOGV("receiveRecordingFrame E");
3803 // post busy frame
3804 if (frame)
3805 {
3806 cam_frame_post_video (frame);
3807 }
3808 else LOGE("in receiveRecordingFrame frame is NULL");
3809 LOGV("receiveRecordingFrame X");
3810}
3811
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003812
Mohan Kandrad9efed92010-01-15 19:08:39 -08003813bool QualcommCameraHardware::native_zoom_image(int fd, int srcOffset, int dstOffSet, common_crop_t *crop)
Mohan Kandra284966d2010-01-05 13:39:15 -08003814{
3815 int result = 0;
3816 struct mdp_blit_req *e;
3817 struct timeval td1, td2;
3818
Mohan Kandra284966d2010-01-05 13:39:15 -08003819 /* Initialize yuv structure */
3820 zoomImage.list.count = 1;
3821
3822 e = &zoomImage.list.req[0];
3823
3824 e->src.width = previewWidth;
3825 e->src.height = previewHeight;
3826 e->src.format = MDP_Y_CBCR_H2V2;
Mohan Kandrad9efed92010-01-15 19:08:39 -08003827 e->src.offset = srcOffset;
3828 e->src.memory_id = fd;
Mohan Kandra284966d2010-01-05 13:39:15 -08003829
3830 e->dst.width = previewWidth;
3831 e->dst.height = previewHeight;
3832 e->dst.format = MDP_Y_CBCR_H2V2;
Mohan Kandrad9efed92010-01-15 19:08:39 -08003833 e->dst.offset = dstOffSet;
3834 e->dst.memory_id = fd;
Mohan Kandra284966d2010-01-05 13:39:15 -08003835
3836 e->transp_mask = 0xffffffff;
3837 e->flags = 0;
3838 e->alpha = 0xff;
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07003839 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07003840 e->src_rect.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
3841 e->src_rect.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
3842 e->src_rect.w = crop->in1_w;
3843 e->src_rect.h = crop->in1_h;
Mohan Kandra284966d2010-01-05 13:39:15 -08003844 } else {
3845 e->src_rect.x = 0;
3846 e->src_rect.y = 0;
3847 e->src_rect.w = previewWidth;
3848 e->src_rect.h = previewHeight;
3849 }
Mohan Kandrad9efed92010-01-15 19:08:39 -08003850 //LOGV(" native_zoom : SRC_RECT : x,y = %d,%d \t w,h = %d, %d",
3851 // e->src_rect.x, e->src_rect.y, e->src_rect.w, e->src_rect.h);
Mohan Kandra284966d2010-01-05 13:39:15 -08003852
3853 e->dst_rect.x = 0;
3854 e->dst_rect.y = 0;
3855 e->dst_rect.w = previewWidth;
3856 e->dst_rect.h = previewHeight;
3857
3858 result = ioctl(fb_fd, MSMFB_BLIT, &zoomImage.list);
3859 if (result < 0) {
3860 LOGE("MSM_FBIOBLT failed! line=%d\n", __LINE__);
3861 return FALSE;
3862 }
3863 return TRUE;
3864}
3865
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003866void QualcommCameraHardware::debugShowPreviewFPS() const
Mohan Kandra740cfce2010-01-07 12:58:24 -08003867{
3868 static int mFrameCount;
3869 static int mLastFrameCount = 0;
3870 static nsecs_t mLastFpsTime = 0;
3871 static float mFps = 0;
3872 mFrameCount++;
3873 nsecs_t now = systemTime();
3874 nsecs_t diff = now - mLastFpsTime;
3875 if (diff > ms2ns(250)) {
3876 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003877 LOGI("Preview Frames Per Second: %.4f", mFps);
Mohan Kandra740cfce2010-01-07 12:58:24 -08003878 mLastFpsTime = now;
3879 mLastFrameCount = mFrameCount;
3880 }
3881}
3882
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003883void QualcommCameraHardware::debugShowVideoFPS() const
3884{
3885 static int mFrameCount;
3886 static int mLastFrameCount = 0;
3887 static nsecs_t mLastFpsTime = 0;
3888 static float mFps = 0;
3889 mFrameCount++;
3890 nsecs_t now = systemTime();
3891 nsecs_t diff = now - mLastFpsTime;
3892 if (diff > ms2ns(250)) {
3893 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
3894 LOGI("Video Frames Per Second: %.4f", mFps);
3895 mLastFpsTime = now;
3896 mLastFrameCount = mFrameCount;
3897 }
3898}
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05303899
3900void QualcommCameraHardware::receiveLiveSnapshot(uint32_t jpeg_size)
3901{
3902 LOGV("receiveLiveSnapshot E");
3903
3904#ifdef DUMP_LIVESHOT_JPEG_FILE
3905 int file_fd = open("/data/LiveSnapshot.jpg", O_RDWR | O_CREAT, 0777);
3906 LOGV("dumping live shot image in /data/LiveSnapshot.jpg");
3907 if (file_fd < 0) {
3908 LOGE("cannot open file\n");
3909 }
3910 else
3911 {
3912 write(file_fd, (uint8_t *)mJpegHeap->mHeap->base(),jpeg_size);
3913 }
3914 close(file_fd);
3915#endif
3916
3917 Mutex::Autolock cbLock(&mCallbackLock);
3918 if (mDataCallback && (mMsgEnabled & MEDIA_RECORDER_MSG_COMPRESSED_IMAGE)) {
3919 sp<MemoryBase> buffer = new
3920 MemoryBase(mJpegHeap->mHeap,
3921 0,
3922 jpeg_size);
3923 mDataCallback(MEDIA_RECORDER_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
3924 buffer = NULL;
3925 }
3926 else LOGV("JPEG callback was cancelled--not delivering image.");
3927
3928 //Reset the Gps Information & relieve memory
3929 exif_table_numEntries = 0;
3930 mJpegHeap.clear();
3931
3932 liveshot_state = LIVESHOT_DONE;
3933
3934 LOGV("receiveLiveSnapshot X");
3935}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003936void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
3937{
3938// LOGV("receivePreviewFrame E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003939 if (!mCameraRunning) {
3940 LOGE("ignoring preview callback--camera has been stopped");
3941 return;
3942 }
3943
Mohan Kandra740cfce2010-01-07 12:58:24 -08003944 if (UNLIKELY(mDebugFps)) {
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003945 debugShowPreviewFPS();
Mohan Kandra740cfce2010-01-07 12:58:24 -08003946 }
3947
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003948 mCallbackLock.lock();
3949 int msgEnabled = mMsgEnabled;
3950 data_callback pcb = mDataCallback;
3951 void *pdata = mCallbackCookie;
3952 data_callback_timestamp rcb = mDataCallbackTimestamp;
3953 void *rdata = mCallbackCookie;
3954 mCallbackLock.unlock();
3955
3956 // Find the offset within the heap of the current buffer.
Mohan Kandra284966d2010-01-05 13:39:15 -08003957 ssize_t offset_addr =
Mohan Kandrad9efed92010-01-15 19:08:39 -08003958 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
3959 ssize_t offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
Mohan Kandra284966d2010-01-05 13:39:15 -08003960
3961 common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303962#ifdef DUMP_PREVIEW_FRAMES
3963 static int frameCnt = 0;
3964 int written;
3965 if (frameCnt >= 0 && frameCnt <= 10 ) {
3966 char buf[128];
3967 sprintf(buf, "/data/%d_preview.yuv", frameCnt);
3968 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
3969 LOGV("dumping preview frame %d", frameCnt);
3970 if (file_fd < 0) {
3971 LOGE("cannot open file\n");
3972 }
3973 else
3974 {
3975 LOGV("dumping data");
3976 written = write(file_fd, (uint8_t *)frame->buffer,
3977 mPreviewFrameSize );
3978 if(written < 0)
3979 LOGE("error in data write");
3980 }
3981 close(file_fd);
3982 }
3983 frameCnt++;
3984#endif
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003985 mInPreviewCallback = true;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003986 if(mUseOverlay) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07003987 if(mOverlay != NULL) {
3988 mOverlayLock.lock();
Mohan Kandra54e2a022010-07-06 16:23:58 -07003989 mOverlay->setFd(mPreviewHeap->mHeap->getHeapID());
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07003990 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07003991 zoomCropInfo.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
3992 zoomCropInfo.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
3993 zoomCropInfo.w = crop->in1_w;
3994 zoomCropInfo.h = crop->in1_h;
Mohan Kandra29834532010-10-14 16:12:44 -07003995 /* There can be scenarios where the in1_wXin1_h and
3996 * out1_wXout1_h are same. In those cases, reset the
3997 * x and y to zero instead of negative for proper zooming
3998 */
3999 if(zoomCropInfo.x < 0) zoomCropInfo.x = 0;
4000 if(zoomCropInfo.y < 0) zoomCropInfo.y = 0;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004001 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004002 zoomCropInfo.w, zoomCropInfo.h);
Mohan Kandra9aff1f42010-09-02 19:00:41 -07004003 /* Set mResetOverlayCrop to true, so that when there is
4004 * no crop information, setCrop will be called
4005 * with zero crop values.
4006 */
4007 mResetOverlayCrop = true;
4008
Apurva Rajguru905b8532010-08-02 18:29:38 -07004009 } else {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08004010 // Reset zoomCropInfo variables. This will ensure that
4011 // stale values wont be used for postview
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004012 zoomCropInfo.w = crop->in1_w;
4013 zoomCropInfo.h = crop->in1_h;
Mohan Kandra9aff1f42010-09-02 19:00:41 -07004014 /* This reset is required, if not, overlay driver continues
4015 * to use the old crop information for these preview
4016 * frames which is not the correct behavior. To avoid
4017 * multiple calls, reset once.
4018 */
4019 if(mResetOverlayCrop == true){
4020 mOverlay->setCrop(0, 0,previewWidth, previewHeight);
4021 mResetOverlayCrop = false;
4022 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08004023 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004024 mOverlay->queueBuffer((void *)offset_addr);
Priyanka Kharat02807662010-10-13 23:44:47 -07004025 /* To overcome a timing case where we could be having the overlay refer to deallocated
4026 mDisplayHeap(and showing corruption), the mDisplayHeap is not deallocated untill the
4027 first preview frame is queued to the overlay in 8660 */
4028 if ((mCurrentTarget == TARGET_MSM8660)&&(mFirstFrame == true)) {
4029 LOGD(" receivePreviewFrame : first frame queued, display heap being deallocated");
4030 mThumbnailHeap.clear();
4031 mDisplayHeap.clear();
4032 mFirstFrame = false;
4033 mPostViewHeap.clear();
4034 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08004035 mLastQueuedFrame = (void *)frame->buffer;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004036 mOverlayLock.unlock();
4037 }
Mohan Kandra284966d2010-01-05 13:39:15 -08004038 } else {
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07004039 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004040 dstOffset = (dstOffset + 1) % NUM_MORE_BUFS;
4041 offset = kPreviewBufferCount + dstOffset;
4042 ssize_t dstOffset_addr = offset * mPreviewHeap->mAlignedBufferSize;
4043 if( !native_zoom_image(mPreviewHeap->mHeap->getHeapID(),
4044 offset_addr, dstOffset_addr, crop)) {
4045 LOGE(" Error while doing MDP zoom ");
Kiran Kumar H N1ece71c2010-03-30 10:31:21 -07004046 offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004047 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004048 }
4049 if (mCurrentTarget == TARGET_MSM7627) {
4050 mLastQueuedFrame = (void *)mPreviewHeap->mBuffers[offset]->pointer();
4051 }
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08004052 }
Mohan Kandrad9efed92010-01-15 19:08:39 -08004053 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
4054 pcb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap->mBuffers[offset],
4055 pdata);
4056
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304057 // If output is NOT enabled (targets otherthan 7x30 , 8x50 and 8x60 currently..)
4058 if( (mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304059 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
4060 rcb(systemTime(), CAMERA_MSG_VIDEO_FRAME, mPreviewHeap->mBuffers[offset], rdata);
4061 Mutex::Autolock rLock(&mRecordFrameLock);
4062 if (mReleasedRecordingFrame != true) {
4063 LOGV("block waiting for frame release");
4064 mRecordWait.wait(mRecordFrameLock);
4065 LOGV("frame released, continuing");
4066 }
4067 mReleasedRecordingFrame = false;
4068 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004069 }
4070 mInPreviewCallback = false;
4071
4072// LOGV("receivePreviewFrame X");
4073}
Nishant Pandit741742b2010-09-21 03:24:20 +05304074void QualcommCameraHardware::receiveCameraStats(camstats_type stype, camera_preview_histogram_info* histinfo)
4075{
4076 // LOGV("receiveCameraStats E");
4077
4078 if (!mCameraRunning) {
4079 LOGE("ignoring stats callback--camera has been stopped");
4080 return;
4081 }
4082
4083 if(mOverlay == NULL) {
4084 return;
4085 }
4086 mCallbackLock.lock();
4087 int msgEnabled = mMsgEnabled;
4088 data_callback scb = mDataCallback;
4089 void *sdata = mCallbackCookie;
4090 mCallbackLock.unlock();
4091 mStatsWaitLock.lock();
4092 if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) {
4093 mStatsWaitLock.unlock();
4094 return;
4095 }
4096 if(!mSendData) {
4097 mStatsWaitLock.unlock();
4098 } else {
4099 mSendData = false;
4100 mCurrent = (mCurrent+1)%3;
4101 // The first element of the array will contain the maximum hist value provided by driver.
4102 *(uint32_t *)(mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)) = histinfo->max_value;
4103 memcpy((uint32_t *)((unsigned int)mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)+ sizeof(int32_t)), (uint32_t *)histinfo->buffer,(sizeof(int32_t) * 256));
4104
4105 mStatsWaitLock.unlock();
4106
4107 if (scb != NULL && (msgEnabled & CAMERA_MSG_STATS_DATA))
4108 scb(CAMERA_MSG_STATS_DATA, mStatHeap->mBuffers[mCurrent],
4109 sdata);
4110 }
4111 // LOGV("receiveCameraStats X");
4112}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004113
Sravankb4f5f1c2010-01-21 11:06:17 +05304114
4115bool QualcommCameraHardware::initRecord()
4116{
Mohan Kandra62429cc2010-07-19 10:21:05 -07004117 const char *pmem_region;
Nishant Panditbde07612010-07-28 00:16:28 +05304118 int CbCrOffset;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004119 int recordBufferSize;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004120
Sravankb4f5f1c2010-01-21 11:06:17 +05304121 LOGV("initREcord E");
4122
Vinay Kaliaba3555f2010-07-21 11:37:36 -07004123 if(mCurrentTarget == TARGET_MSM8660)
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004124 pmem_region = "/dev/pmem_smipool";
4125 else
4126 pmem_region = "/dev/pmem_adsp";
4127
Nishant Panditbde07612010-07-28 00:16:28 +05304128 // for 8x60 the Encoder expects the CbCr offset should be aligned to 2K.
4129 if(mCurrentTarget == TARGET_MSM8660) {
4130 CbCrOffset = PAD_TO_2K(mDimension.video_width * mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004131 recordBufferSize = CbCrOffset + PAD_TO_2K((mDimension.video_width * mDimension.video_height)/2);
Nishant Panditbde07612010-07-28 00:16:28 +05304132 } else {
4133 CbCrOffset = PAD_TO_WORD(mDimension.video_width * mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004134 recordBufferSize = (mDimension.video_width * mDimension.video_height *3)/2;
Nishant Panditbde07612010-07-28 00:16:28 +05304135 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004136 LOGV("initRecord: mDimension.video_width = %d mDimension.video_height = %d",
4137 mDimension.video_width, mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004138
4139 /* Buffersize and frameSize will be different when DIS is ON.
4140 * We need to pass the actual framesize with video heap, as the same
4141 * is used at camera MIO when negotiating with encoder.
4142 */
4143 mRecordFrameSize = recordBufferSize;
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004144 if(mVpeEnabled && mDisEnabled){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004145 mRecordFrameSize = videoWidth * videoHeight * 3 / 2;
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004146 if(mCurrentTarget == TARGET_MSM8660){
4147 mRecordFrameSize = PAD_TO_2K(videoWidth * videoHeight)
4148 + PAD_TO_2K((videoWidth * videoHeight)/2);
4149 }
4150 }
4151 LOGV("mRecordFrameSize = %d", mRecordFrameSize);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004152
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004153 mRecordHeap = new PmemPool(pmem_region,
Sravankb4f5f1c2010-01-21 11:06:17 +05304154 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
4155 mCameraControlFd,
4156 MSM_PMEM_VIDEO,
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004157 recordBufferSize,
Sravankb4f5f1c2010-01-21 11:06:17 +05304158 kRecordBufferCount,
4159 mRecordFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07004160 CbCrOffset,
4161 0,
Sravankb4f5f1c2010-01-21 11:06:17 +05304162 "record");
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004163
Sravankb4f5f1c2010-01-21 11:06:17 +05304164 if (!mRecordHeap->initialized()) {
4165 mRecordHeap.clear();
4166 LOGE("initRecord X: could not initialize record heap.");
4167 return false;
4168 }
4169 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
4170 recordframes[cnt].fd = mRecordHeap->mHeap->getHeapID();
4171 recordframes[cnt].buffer =
4172 (uint32_t)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
4173 recordframes[cnt].y_off = 0;
Nishant Panditbde07612010-07-28 00:16:28 +05304174 recordframes[cnt].cbcr_off = CbCrOffset;
Sravankb4f5f1c2010-01-21 11:06:17 +05304175 recordframes[cnt].path = OUTPUT_TYPE_V;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004176 record_buffers_tracking_flag[cnt] = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304177 LOGV ("initRecord : record heap , video buffers buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
4178 (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
4179 recordframes[cnt].cbcr_off);
4180 }
4181
4182 // initial setup : buffers 1,2,3 with kernel , 4 with camframe , 5,6,7,8 in free Q
4183 // flush the busy Q
4184 cam_frame_flush_video();
4185
Mohan Kandra156d0ac2010-01-25 16:59:17 -08004186 mVideoThreadWaitLock.lock();
4187 while (mVideoThreadRunning) {
4188 LOGV("initRecord: waiting for old video thread to complete.");
4189 mVideoThreadWait.wait(mVideoThreadWaitLock);
4190 LOGV("initRecord : old video thread completed.");
4191 }
4192 mVideoThreadWaitLock.unlock();
4193
Sravankdf7a9202010-02-08 15:02:51 +05304194 // flush free queue and add 5,6,7,8 buffers.
4195 LINK_cam_frame_flush_free_video();
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004196 if(mVpeEnabled) {
4197 //If VPE is enabled, the VPE buffer shouldn't be added to Free Q initally.
4198 for(int i=ACTIVE_VIDEO_BUFFERS+1;i <kRecordBufferCount-1; i++)
4199 LINK_camframe_free_video(&recordframes[i]);
4200 } else {
4201 for(int i=ACTIVE_VIDEO_BUFFERS+1;i <kRecordBufferCount; i++)
4202 LINK_camframe_free_video(&recordframes[i]);
4203 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304204 LOGV("initREcord X");
4205
4206 return true;
4207}
4208
Mohan Kandracedd6cc2010-09-14 14:37:08 -07004209
4210status_t QualcommCameraHardware::setDIS() {
4211 LOGV("setDIS E");
4212
4213 video_dis_param_ctrl_t disCtrl;
4214 bool ret = true;
Mohan Kandra2cd34e62010-10-06 18:15:56 -07004215 LOGV("mDisEnabled = %d", mDisEnabled);
Mohan Kandracedd6cc2010-09-14 14:37:08 -07004216
4217 int video_frame_cbcroffset;
4218 video_frame_cbcroffset = PAD_TO_WORD(videoWidth * videoHeight);
4219 if(mCurrentTarget == TARGET_MSM8660)
4220 video_frame_cbcroffset = PAD_TO_2K(videoWidth * videoHeight);
4221
4222 disCtrl.dis_enable = mDisEnabled;
4223 disCtrl.video_rec_width = videoWidth;
4224 disCtrl.video_rec_height = videoHeight;
4225 disCtrl.output_cbcr_offset = video_frame_cbcroffset;
4226
Deepak Kurieneb58c682010-11-01 15:26:02 -07004227 ret = native_set_parms( CAMERA_PARM_VIDEO_DIS,
Mohan Kandracedd6cc2010-09-14 14:37:08 -07004228 sizeof(disCtrl), &disCtrl);
Deepak Kurieneb58c682010-11-01 15:26:02 -07004229
Mohan Kandracedd6cc2010-09-14 14:37:08 -07004230 LOGV("setDIS X (%d)", ret);
4231 return ret ? NO_ERROR : UNKNOWN_ERROR;
4232}
4233
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004234status_t QualcommCameraHardware::setVpeParameters()
4235{
4236 LOGV("setVpeParameters E");
4237
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004238 video_rotation_param_ctrl_t rotCtrl;
Mohan Kandraec958742010-08-19 10:56:05 -07004239 bool ret = true;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004240 LOGV("videoWidth = %d, videoHeight = %d", videoWidth, videoHeight);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004241 rotCtrl.rotation = (mRotation == 0) ? ROT_NONE :
4242 ((mRotation == 90) ? ROT_CLOCKWISE_90 :
4243 ((mRotation == 180) ? ROT_CLOCKWISE_180 : ROT_CLOCKWISE_270));
4244
Mohan Kandraec958742010-08-19 10:56:05 -07004245 if( ((videoWidth == 1280 && videoHeight == 720) || (videoWidth == 800 && videoHeight == 480))
4246 && (mRotation == 90 || mRotation == 270) ){
4247 /* Due to a limitation at video core to support heights greater than 720, adding this check.
4248 * This is a temporary hack, need to be removed once video core support is available
4249 */
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004250 LOGI("video resolution (%dx%d) with rotation (%d) is not supported, setting rotation to NONE",
Mohan Kandraec958742010-08-19 10:56:05 -07004251 videoWidth, videoHeight, mRotation);
4252 rotCtrl.rotation = ROT_NONE;
Mohan Kandraec958742010-08-19 10:56:05 -07004253 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004254 LOGV("rotCtrl.rotation = %d", rotCtrl.rotation);
4255
Deepak Kurieneb58c682010-11-01 15:26:02 -07004256 ret = native_set_parms(CAMERA_PARM_VIDEO_ROT,
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004257 sizeof(rotCtrl), &rotCtrl);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004258
4259 LOGV("setVpeParameters X (%d)", ret);
4260 return ret ? NO_ERROR : UNKNOWN_ERROR;
4261}
4262
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004263status_t QualcommCameraHardware::startRecording()
4264{
4265 LOGV("startRecording E");
Sravankb4f5f1c2010-01-21 11:06:17 +05304266 int ret;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004267 Mutex::Autolock l(&mLock);
4268 mReleasedRecordingFrame = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304269 if( (ret=startPreviewInternal())== NO_ERROR){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004270 if(mVpeEnabled){
4271 LOGI("startRecording: VPE enabled, setting vpe parameters");
4272 bool status = setVpeParameters();
4273 if(status) {
4274 LOGE("Failed to set VPE parameters");
4275 return status;
4276 }
4277 }
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304278 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07004279 LOGV(" in startREcording : calling start_recording");
4280 native_start_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
Sravankb4f5f1c2010-01-21 11:06:17 +05304281 recordingState = 1;
Sravank64461e82010-02-25 15:10:09 +05304282 // Remove the left out frames in busy Q and them in free Q.
4283 // this should be done before starting video_thread so that,
4284 // frames in previous recording are flushed out.
4285 LOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames);
4286 while((g_busy_frame_queue.num_of_frames) >0){
4287 msm_frame* vframe = cam_frame_get_video ();
4288 LINK_camframe_free_video(vframe);
4289 }
4290 LOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames);
4291
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004292 //Clear the dangling buffers and put them in free queue
4293 for(int cnt = 0; cnt < kRecordBufferCount; cnt++) {
4294 if(record_buffers_tracking_flag[cnt] == true) {
Mohan Kandra62429cc2010-07-19 10:21:05 -07004295 LOGI("Dangling buffer: offset = %d, buffer = %d", cnt, (unsigned int)recordframes[cnt].buffer);
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004296 LINK_camframe_free_video(&recordframes[cnt]);
4297 record_buffers_tracking_flag[cnt] = false;
4298 }
4299 }
4300
Sravankdf7a9202010-02-08 15:02:51 +05304301 // Start video thread and wait for busy frames to be encoded, this thread
4302 // should be closed in stopRecording
4303 mVideoThreadWaitLock.lock();
4304 mVideoThreadExit = 0;
4305 pthread_attr_t attr;
4306 pthread_attr_init(&attr);
4307 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4308 mVideoThreadRunning = pthread_create(&mVideoThread,
4309 &attr,
4310 video_thread,
4311 NULL);
4312 mVideoThreadWaitLock.unlock();
4313 // Remove the left out frames in busy Q and them in free Q.
Sravankb4f5f1c2010-01-21 11:06:17 +05304314 }
4315 }
4316 return ret;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004317}
4318
4319void QualcommCameraHardware::stopRecording()
4320{
4321 LOGV("stopRecording: E");
4322 Mutex::Autolock l(&mLock);
4323 {
4324 mRecordFrameLock.lock();
4325 mReleasedRecordingFrame = true;
4326 mRecordWait.signal();
4327 mRecordFrameLock.unlock();
4328
Sravankdf7a9202010-02-08 15:02:51 +05304329 if(mDataCallback && !(mCurrentTarget == TARGET_QSD8250) &&
4330 (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004331 LOGV("stopRecording: X, preview still in progress");
4332 return;
4333 }
4334 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304335 // If output2 enabled, exit video thread, invoke stop recording ioctl
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304336 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304337 mVideoThreadWaitLock.lock();
4338 mVideoThreadExit = 1;
4339 mVideoThreadWaitLock.unlock();
Deepak Kurieneb58c682010-11-01 15:26:02 -07004340 native_stop_ops(CAMERA_OPS_VIDEO_RECORDING, NULL);
Srinivasan Kannanfc3915c2010-03-18 10:54:40 -07004341
4342 pthread_mutex_lock(&(g_busy_frame_queue.mut));
4343 pthread_cond_signal(&(g_busy_frame_queue.wait));
4344 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Sravankb4f5f1c2010-01-21 11:06:17 +05304345 }
4346 else // for other targets where output2 is not enabled
4347 stopPreviewInternal();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004348
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05304349 if (mJpegHeap != NULL) {
4350 LOGV("stopRecording: clearing old mJpegHeap.");
4351 mJpegHeap.clear();
4352 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304353 recordingState = 0; // recording not started
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004354 LOGV("stopRecording: X");
4355}
4356
4357void QualcommCameraHardware::releaseRecordingFrame(
4358 const sp<IMemory>& mem __attribute__((unused)))
4359{
4360 LOGV("releaseRecordingFrame E");
4361 Mutex::Autolock rLock(&mRecordFrameLock);
4362 mReleasedRecordingFrame = true;
4363 mRecordWait.signal();
Sravankb4f5f1c2010-01-21 11:06:17 +05304364
4365 // Ff 7x30 : add the frame to the free camframe queue
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304366 if( (mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304367 ssize_t offset;
4368 size_t size;
4369 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
4370 msm_frame* releaseframe = NULL;
4371 LOGV(" in release recording frame : heap base %d offset %d buffer %d ", heap->base(), offset, heap->base() + offset );
4372 int cnt;
4373 for (cnt = 0; cnt < kRecordBufferCount; cnt++) {
Mohan Kandra62429cc2010-07-19 10:21:05 -07004374 if((unsigned int)recordframes[cnt].buffer == ((unsigned int)heap->base()+ offset)){
Sravankb4f5f1c2010-01-21 11:06:17 +05304375 LOGV("in release recording frame found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer);
4376 releaseframe = &recordframes[cnt];
4377 break;
4378 }
4379 }
4380 if(cnt < kRecordBufferCount) {
4381 // do this only if frame thread is running
4382 mFrameThreadWaitLock.lock();
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004383 if(mFrameThreadRunning ) {
4384 //Reset the track flag for this frame buffer
4385 record_buffers_tracking_flag[cnt] = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304386 LINK_camframe_free_video(releaseframe);
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004387 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304388
4389 mFrameThreadWaitLock.unlock();
4390 } else {
4391 LOGE("in release recordingframe XXXXX error , buffer not found");
4392 for (int i=0; i< kRecordBufferCount; i++) {
4393 LOGE(" recordframes[%d].buffer = %d", i, (unsigned int)recordframes[i].buffer);
4394 }
4395 }
4396 }
4397
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004398 LOGV("releaseRecordingFrame X");
4399}
4400
4401bool QualcommCameraHardware::recordingEnabled()
4402{
4403 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
4404}
4405
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004406void QualcommCameraHardware::notifyShutter(common_crop_t *crop, bool mPlayShutterSoundOnly)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004407{
4408 mShutterLock.lock();
4409 image_rect_type size;
4410
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004411 if(mPlayShutterSoundOnly) {
4412 /* At this point, invoke Notify Callback to play shutter sound only.
4413 * We want to call notify callback again when we have the
4414 * yuv picture ready. This is to reduce blanking at the time
4415 * of displaying postview frame. Using ext2 to indicate whether
4416 * to play shutter sound only or register the postview buffers.
4417 */
4418 mNotifyCallback(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly,
4419 mCallbackCookie);
4420 mShutterLock.unlock();
4421 return;
4422 }
4423
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004424 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
Deepak Kurienc1e3cd42010-10-01 12:09:52 -07004425 if (mSnapshotFormat == PICTURE_FORMAT_RAW) {
4426 size.width = previewWidth;
4427 size.height = previewHeight;
4428 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
4429 mCallbackCookie);
4430 mShutterPending = false;
4431 mShutterLock.unlock();
4432 return;
4433 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004434 LOGV("out2_w=%d, out2_h=%d, in2_w=%d, in2_h=%d",
4435 crop->out2_w, crop->out2_h, crop->in2_w, crop->in2_h);
4436 LOGV("out1_w=%d, out1_h=%d, in1_w=%d, in1_h=%d",
4437 crop->out1_w, crop->out1_h, crop->in1_w, crop->in1_h);
4438
4439 // To workaround a bug in MDP which happens if either
4440 // dimension > 2048, we display the thumbnail instead.
Apurva Rajguru905b8532010-08-02 18:29:38 -07004441
4442 if (mCurrentTarget == TARGET_MSM7627)
Sravanka7b89c82010-10-06 16:13:28 +05304443 mDisplayHeap = mThumbnailHeap;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004444 else
4445 mDisplayHeap = mRawHeap;
4446
Sravanka7b89c82010-10-06 16:13:28 +05304447 // In case of 7x27, we use output2 for postview , which is of
4448 // preview size. Output2 was used for thumbnail previously.
4449 // Now thumbnail is generated from main image for 7x27.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004450 if (crop->in1_w == 0 || crop->in1_h == 0) {
4451 // Full size
Sravanka7b89c82010-10-06 16:13:28 +05304452 if (mCurrentTarget == TARGET_MSM7627) {
Vamshidhar Kondra8e703082010-11-02 15:46:54 +05304453 jpegPadding = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004454 size.width = mDimension.ui_thumbnail_width;
4455 size.height = mDimension.ui_thumbnail_height;
Sravanka7b89c82010-10-06 16:13:28 +05304456 } else {
4457 size.width = mDimension.picture_width;
4458 size.height = mDimension.picture_height;
4459 if (size.width > 2048 || size.height > 2048) {
4460 size.width = mDimension.ui_thumbnail_width;
4461 size.height = mDimension.ui_thumbnail_height;
4462 mDisplayHeap = mThumbnailHeap;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004463 }
4464 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004465 } else {
4466 // Cropped
Sravanka7b89c82010-10-06 16:13:28 +05304467 if (mCurrentTarget == TARGET_MSM7627) {
Vamshidhar Kondra8e703082010-11-02 15:46:54 +05304468 jpegPadding = 8;
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004469 size.width = (crop->in1_w + jpegPadding) & ~1;
4470 size.height = (crop->in1_h + jpegPadding) & ~1;
Sravanka7b89c82010-10-06 16:13:28 +05304471 } else {
4472 size.width = (crop->in2_w + jpegPadding) & ~1;
4473 size.height = (crop->in2_h + jpegPadding) & ~1;
4474 if (size.width > 2048 || size.height > 2048) {
4475 size.width = (crop->in1_w + jpegPadding) & ~1;
4476 size.height = (crop->in1_h + jpegPadding) & ~1;
4477 mDisplayHeap = mThumbnailHeap;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004478 }
4479 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004480 }
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004481 //We need to create overlay with dimensions that the VFE output
4482 //is configured for post view.
4483 if((mCurrentTarget == TARGET_MSM7630) ||
4484 (mCurrentTarget == TARGET_MSM8660)) {
4485 size.width = mDimension.ui_thumbnail_width;
4486 size.height = mDimension.ui_thumbnail_height;
4487 //Make ThumbnailHeap as Displayheap for post view.
4488 mDisplayHeap = mThumbnailHeap;
4489 }
4490
Mohan Kandra4ebb9102010-11-09 17:52:30 -08004491 //For streaming textures, we need to pass the main image in all the cases.
4492 if(strTexturesOn == true) {
Mohan Kandra73875f02010-09-24 17:34:54 -07004493 int rawWidth, rawHeight;
4494 mParameters.getPictureSize(&rawWidth, &rawHeight);
4495 size.width = rawWidth;
4496 size.height = rawHeight;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004497 mDisplayHeap = mRawHeap;
Mohan Kandra73875f02010-09-24 17:34:54 -07004498 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004499
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004500 /* Now, invoke Notify Callback to unregister preview buffer
4501 * and register postview buffer with surface flinger. Set ext2
4502 * as 0 to indicate not to play shutter sound.
4503 */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004504 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
4505 mCallbackCookie);
4506 mShutterPending = false;
4507 }
4508 mShutterLock.unlock();
4509}
4510
4511static void receive_shutter_callback(common_crop_t *crop)
4512{
4513 LOGV("receive_shutter_callback: E");
4514 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
4515 if (obj != 0) {
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004516 /* Just play shutter sound at this time */
4517 obj->notifyShutter(crop, TRUE);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004518 }
4519 LOGV("receive_shutter_callback: X");
4520}
4521
4522// Crop the picture in place.
4523static void crop_yuv420(uint32_t width, uint32_t height,
4524 uint32_t cropped_width, uint32_t cropped_height,
Apurva Rajguru905b8532010-08-02 18:29:38 -07004525 uint8_t *image, const char *name)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004526{
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004527 int32_t i;
4528 uint32_t x, y;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004529 uint8_t* chroma_src, *chroma_dst;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004530 int yOffsetSrc, yOffsetDst, CbCrOffsetSrc, CbCrOffsetDst;
4531 int mSrcSize, mDstSize;
4532
4533 //check if all fields needed eg. size and also how to set y offset. If condition for 7x27
4534 //and need to check if needed for 7x30.
4535
4536 LINK_jpeg_encoder_get_buffer_offset(width, height, (uint32_t *)&yOffsetSrc,
4537 (uint32_t *)&CbCrOffsetSrc, (uint32_t *)&mSrcSize);
4538
4539 LINK_jpeg_encoder_get_buffer_offset(cropped_width, cropped_height, (uint32_t *)&yOffsetDst,
4540 (uint32_t *)&CbCrOffsetDst, (uint32_t *)&mDstSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004541
4542 // Calculate the start position of the cropped area.
4543 x = (width - cropped_width) / 2;
4544 y = (height - cropped_height) / 2;
4545 x &= ~1;
4546 y &= ~1;
4547
Apurva Rajguru905b8532010-08-02 18:29:38 -07004548 if((mCurrentTarget == TARGET_MSM7627)
Priyanka Kharat32409f72010-08-25 18:11:03 -07004549 || (mCurrentTarget == TARGET_MSM7630)
4550 || (mCurrentTarget == TARGET_MSM8660)) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07004551 if (!strcmp("snapshot camera", name)) {
4552 chroma_src = image + CbCrOffsetSrc;
4553 chroma_dst = image + CbCrOffsetDst;
4554 } else {
4555 chroma_src = image + width * height;
4556 chroma_dst = image + cropped_width * cropped_height;
Apurva Rajgurubfc04522010-08-11 16:22:25 -07004557 yOffsetSrc = 0;
4558 yOffsetDst = 0;
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004559 CbCrOffsetSrc = width * height;
4560 CbCrOffsetDst = cropped_width * cropped_height;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004561 }
4562 } else {
4563 chroma_src = image + CbCrOffsetSrc;
4564 chroma_dst = image + CbCrOffsetDst;
4565 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004566
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004567 int32_t bufDst = yOffsetDst;
4568 int32_t bufSrc = yOffsetSrc + (width * y) + x;
4569
4570 if( bufDst > bufSrc ){
4571 LOGV("crop yuv Y destination position follows source position");
4572 /*
4573 * If buffer destination follows buffer source, memcpy
4574 * of lines will lead to overwriting subsequent lines. In order
4575 * to prevent this, reverse copying of lines is performed
4576 * for the set of lines where destination follows source and
4577 * forward copying of lines is performed for lines where source
4578 * follows destination. To calculate the position to switch,
4579 * the initial difference between source and destination is taken
4580 * and divided by difference between width and cropped width. For
4581 * every line copied the difference between source destination
4582 * drops by width - cropped width
4583 */
4584 //calculating inversion
4585 int position = ( bufDst - bufSrc ) / (width - cropped_width);
4586 // Copy luma component.
4587 for(i=position+1; i < cropped_height; i++){
4588 memmove(image + yOffsetDst + i * cropped_width,
4589 image + yOffsetSrc + width * (y + i) + x,
4590 cropped_width);
4591 }
4592 for(i=position; i>=0; i--){
4593 memmove(image + yOffsetDst + i * cropped_width,
4594 image + yOffsetSrc + width * (y + i) + x,
4595 cropped_width);
4596 }
4597 } else {
4598 // Copy luma component.
4599 for(i = 0; i < cropped_height; i++)
4600 memcpy(image + yOffsetDst + i * cropped_width,
4601 image + yOffsetSrc + width * (y + i) + x,
4602 cropped_width);
4603 }
4604
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004605 // Copy chroma components.
4606 cropped_height /= 2;
4607 y /= 2;
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004608
4609 bufDst = CbCrOffsetDst;
4610 bufSrc = CbCrOffsetSrc + (width * y) + x;
4611
4612 if( bufDst > bufSrc ) {
4613 LOGV("crop yuv Chroma destination position follows source position");
4614 /*
4615 * Similar to y
4616 */
4617 int position = ( bufDst - bufSrc ) / (width - cropped_width);
4618 for(i=position+1; i < cropped_height; i++){
4619 memmove(chroma_dst + i * cropped_width,
4620 chroma_src + width * (y + i) + x,
4621 cropped_width);
4622 }
4623 for(i=position; i >=0; i--){
4624 memmove(chroma_dst + i * cropped_width,
4625 chroma_src + width * (y + i) + x,
4626 cropped_width);
4627 }
4628 } else {
4629 for(i = 0; i < cropped_height; i++)
4630 memcpy(chroma_dst + i * cropped_width,
4631 chroma_src + width * (y + i) + x,
4632 cropped_width);
4633 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004634}
4635
Mohan Kandra6c04d092010-10-26 17:11:26 -07004636bool QualcommCameraHardware::receiveRawSnapshot(){
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004637 LOGV("receiveRawSnapshot E");
4638
4639 Mutex::Autolock cbLock(&mCallbackLock);
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004640 /* Issue notifyShutter with mPlayShutterSoundOnly as TRUE */
4641 notifyShutter(&mCrop, TRUE);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004642
4643 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4644
Deepak Kurieneb58c682010-11-01 15:26:02 -07004645 if(native_start_ops(CAMERA_OPS_GET_PICTURE, &mCrop) == false) {
4646 LOGE("receiveRawSnapshot X: CAMERA_OPS_GET_PICTURE ioctl failed!");
Mohan Kandra6c04d092010-10-26 17:11:26 -07004647 return false;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004648 }
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004649 /* Its necessary to issue another notifyShutter here with
4650 * mPlayShutterSoundOnly as FALSE, since that is when the
4651 * preview buffers are unregistered with the surface flinger.
4652 * That is necessary otherwise the preview memory wont be
4653 * deallocated.
4654 */
4655 notifyShutter(&mCrop, FALSE);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004656
Kiran Kumar H N03dbb9c2010-10-25 17:38:14 -07004657 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))
4658 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mRawSnapShotPmemHeap->mBuffers[0],
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004659 mCallbackCookie);
4660
4661 }
4662
4663 //cleanup
4664 deinitRawSnapshot();
4665
4666 LOGV("receiveRawSnapshot X");
Mohan Kandra6c04d092010-10-26 17:11:26 -07004667 return true;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004668}
4669
Mohan Kandra6c04d092010-10-26 17:11:26 -07004670bool QualcommCameraHardware::receiveRawPicture()
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004671{
4672 LOGV("receiveRawPicture: E");
4673
4674 Mutex::Autolock cbLock(&mCallbackLock);
Apurva Rajguru3da1a702010-07-28 12:32:42 -07004675 if (mDataCallback && ((mMsgEnabled & CAMERA_MSG_RAW_IMAGE) || mSnapshotDone)) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07004676 if(native_start_ops(CAMERA_OPS_GET_PICTURE, &mCrop) == false) {
4677 LOGE("getPicture: CAMERA_OPS_GET_PICTURE ioctl failed!");
Mohan Kandra6c04d092010-10-26 17:11:26 -07004678 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004679 }
Apurva Rajguru3da1a702010-07-28 12:32:42 -07004680 mSnapshotDone = FALSE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004681 mCrop.in1_w &= ~1;
4682 mCrop.in1_h &= ~1;
4683 mCrop.in2_w &= ~1;
4684 mCrop.in2_h &= ~1;
4685
Deepak Kurieneb58c682010-11-01 15:26:02 -07004686 LOGV("crop: in1_w %d", mCrop.in1_w);
4687 LOGV("crop: in1_h %d", mCrop.in1_h);
4688 LOGV("crop: out1_w %d", mCrop.out1_w);
4689 LOGV("crop: out1_h %d", mCrop.out1_h);
4690
4691 LOGV("crop: in2_w %d", mCrop.in2_w);
4692 LOGV("crop: in2_h %d", mCrop.in2_h);
4693 LOGV("crop: out2_w %d", mCrop.out2_w);
4694 LOGV("crop: out2_h %d", mCrop.out2_h);
4695
4696 LOGV("crop: update %d", mCrop.update_flag);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004697
4698 // Crop the image if zoomed.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004699 if (mCrop.in2_w != 0 && mCrop.in2_h != 0 &&
4700 ((mCrop.in2_w + jpegPadding) < mCrop.out2_w) &&
4701 ((mCrop.in2_h + jpegPadding) < mCrop.out2_h) &&
4702 ((mCrop.in1_w + jpegPadding) < mCrop.out1_w) &&
4703 ((mCrop.in1_h + jpegPadding) < mCrop.out1_h) ) {
4704
4705 // By the time native_get_picture returns, picture is taken. Call
4706 // shutter callback if cam config thread has not done that.
4707 notifyShutter(&mCrop, FALSE);
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004708 {
4709 Mutex::Autolock l(&mRawPictureHeapLock);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004710 if(mRawHeap != NULL){
4711 crop_yuv420(mCrop.out2_w, mCrop.out2_h, (mCrop.in2_w + jpegPadding), (mCrop.in2_h + jpegPadding),
Apurva Rajguru905b8532010-08-02 18:29:38 -07004712 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mName);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004713 }
4714 if( (mThumbnailHeap != NULL) &&
4715 (mCurrentTarget != TARGET_MSM7630) &&
4716 (mCurrentTarget != TARGET_MSM8660) ) {
4717 //Don't crop the mThumbnailHeap for 7630. As this heap
4718 //is used for postview rather than for thumbnail. (thumbnail is generated from main image).
4719 //overlay's setCrop will take of cropping while displaying postview.
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004720 crop_yuv420(mCrop.out1_w, mCrop.out1_h, (mCrop.in1_w + jpegPadding), (mCrop.in1_h + jpegPadding),
Apurva Rajguru905b8532010-08-02 18:29:38 -07004721 (uint8_t *)mThumbnailHeap->mHeap->base(), mThumbnailHeap->mName);
4722 }
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004723 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004724
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004725 // We do not need jpeg encoder to upscale the image. Set the new
4726 // dimension for encoder.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004727 mDimension.orig_picture_dx = mCrop.in2_w + jpegPadding;
4728 mDimension.orig_picture_dy = mCrop.in2_h + jpegPadding;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004729 /* Don't update the thumbnail_width/height, if jpeg downscaling
4730 * is used to generate thumbnail. These parameters should contain
4731 * the original thumbnail dimensions.
4732 */
Mohan Kandra4ebb9102010-11-09 17:52:30 -08004733 if(strTexturesOn != true) {
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004734 mDimension.thumbnail_width = mCrop.in1_w + jpegPadding;
4735 mDimension.thumbnail_height = mCrop.in1_h + jpegPadding;
4736 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004737 }else {
4738 memset(&mCrop, 0 ,sizeof(mCrop));
4739 // By the time native_get_picture returns, picture is taken. Call
4740 // shutter callback if cam config thread has not done that.
4741 notifyShutter(&mCrop, FALSE);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004742 }
4743
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004744 if( mUseOverlay && (mOverlay != NULL) ) {
4745 mOverlay->setFd(mDisplayHeap->mHeap->getHeapID());
4746 int cropX = 0;
4747 int cropY = 0;
4748 int cropW = 0;
4749 int cropH = 0;
4750 //Caculate the crop dimensions from mCrop.
4751 //mCrop will have the crop dimensions for VFE's
4752 //postview output.
Mohan Kandra57861442010-10-13 17:49:00 -07004753 if (mCrop.in1_w != 0 && mCrop.in1_h != 0) {
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004754 cropX = (mCrop.out1_w - mCrop.in1_w + 1) / 2 - 1;
4755 cropY = (mCrop.out1_h - mCrop.in1_h + 1) / 2 - 1;
Mohan Kandra29834532010-10-14 16:12:44 -07004756 if(cropX < 0) cropX = 0;
4757 if(cropY < 0) cropY = 0;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004758 cropW = mCrop.in1_w;
4759 cropH = mCrop.in1_h;
4760 mOverlay->setCrop(cropX, cropY, cropW, cropH);
Mohan Kandra57861442010-10-13 17:49:00 -07004761 mResetOverlayCrop = true;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004762 }
4763 LOGV(" Queueing Postview for display ");
4764 mOverlay->queueBuffer((void *)0);
4765 }
4766 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE))
4767 mDataCallback(CAMERA_MSG_RAW_IMAGE, mDisplayHeap->mBuffers[0],
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004768 mCallbackCookie);
Mohan Kandra4ebb9102010-11-09 17:52:30 -08004769 if(strTexturesOn == true) {
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004770 LOGI("Raw Data given to app for processing...will wait for jpeg encode call");
4771 mEncodePendingWaitLock.lock();
4772 mEncodePending = true;
4773 mEncodePendingWaitLock.unlock();
4774 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004775 }
4776 else LOGV("Raw-picture callback was canceled--skipping.");
4777
Mohan Kandra4ebb9102010-11-09 17:52:30 -08004778 if(strTexturesOn != true) {
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004779 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4780 mJpegSize = 0;
4781 mJpegThreadWaitLock.lock();
4782 if (LINK_jpeg_encoder_init()) {
4783 mJpegThreadRunning = true;
4784 mJpegThreadWaitLock.unlock();
4785 if(native_jpeg_encode()) {
4786 LOGV("receiveRawPicture: X (success)");
Mohan Kandra6c04d092010-10-26 17:11:26 -07004787 return true;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004788 }
4789 LOGE("jpeg encoding failed");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004790 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004791 else {
4792 LOGE("receiveRawPicture X: jpeg_encoder_init failed.");
4793 mJpegThreadWaitLock.unlock();
4794 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004795 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004796 else LOGV("JPEG callback is NULL, not encoding image.");
4797 deinitRaw();
Mohan Kandra6c04d092010-10-26 17:11:26 -07004798 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004799 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004800 LOGV("receiveRawPicture: X");
Mohan Kandra6c04d092010-10-26 17:11:26 -07004801 return true;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004802}
4803
4804void QualcommCameraHardware::receiveJpegPictureFragment(
4805 uint8_t *buff_ptr, uint32_t buff_size)
4806{
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05304807 LOGV("receiveJpegPictureFragment size %d", buff_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004808 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
4809 remaining -= mJpegSize;
4810 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
4811
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004812 if (buff_size > remaining) {
4813 LOGE("receiveJpegPictureFragment: size %d exceeds what "
4814 "remains in JPEG heap (%d), truncating",
4815 buff_size,
4816 remaining);
4817 buff_size = remaining;
4818 }
4819 memcpy(base + mJpegSize, buff_ptr, buff_size);
4820 mJpegSize += buff_size;
4821}
4822
4823void QualcommCameraHardware::receiveJpegPicture(void)
4824{
4825 LOGV("receiveJpegPicture: E image (%d uint8_ts out of %d)",
4826 mJpegSize, mJpegHeap->mBufferSize);
4827 Mutex::Autolock cbLock(&mCallbackLock);
4828
4829 int index = 0, rc;
4830
4831 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4832 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
4833 // that the JPEG image's size will probably change from one snapshot
4834 // to the next, so we cannot reuse the MemoryBase object.
4835 sp<MemoryBase> buffer = new
4836 MemoryBase(mJpegHeap->mHeap,
4837 index * mJpegHeap->mBufferSize +
4838 0,
4839 mJpegSize);
4840 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
4841 buffer = NULL;
4842 }
4843 else LOGV("JPEG callback was cancelled--not delivering image.");
4844
Mohan Kandraca2e7a92010-06-21 15:48:45 -07004845 mJpegThreadWaitLock.lock();
4846 mJpegThreadRunning = false;
4847 mJpegThreadWait.signal();
4848 mJpegThreadWaitLock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004849
4850 LOGV("receiveJpegPicture: X callback done.");
4851}
4852
4853bool QualcommCameraHardware::previewEnabled()
4854{
Kiran Kumar H N280d4de2010-05-05 13:40:15 -07004855 /* If overlay is used the message CAMERA_MSG_PREVIEW_FRAME would
4856 * be disabled at CameraService layer. Hence previewEnabled would
4857 * return FALSE even though preview is running. Hence check for
4858 * mOverlay not being NULL to ensure that previewEnabled returns
4859 * accurate information.
4860 */
4861 return mCameraRunning && mDataCallback &&
4862 ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) || (mOverlay != NULL));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004863}
Mohan Kandra091d5ab2010-07-14 16:53:25 -07004864status_t QualcommCameraHardware::setRecordSize(const CameraParameters& params)
4865{
4866 int width, height;
4867 const char *str = params.get("record-size");
4868 if(str) {
4869 LOGV("Requested Record size %s", str);
4870 mParameters.set("record-size" , str);
4871 } else {
4872 //set the record-size value to null.
4873 //This is required as the application can request
4874 //to reset this value, so that it won't be carried
4875 //when switched to camera.
4876 mParameters.set("record-size", "");
4877 }
4878 return NO_ERROR;
4879}
4880
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004881
4882status_t QualcommCameraHardware::setPreviewSize(const CameraParameters& params)
4883{
4884 int width, height;
4885 params.getPreviewSize(&width, &height);
4886 LOGV("requested preview size %d x %d", width, height);
4887
4888 // Validate the preview size
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08004889 for (size_t i = 0; i < previewSizeCount; ++i) {
4890 if (width == supportedPreviewSizes[i].width
4891 && height == supportedPreviewSizes[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004892 mParameters.setPreviewSize(width, height);
Mohan Kandra091d5ab2010-07-14 16:53:25 -07004893 mDimension.display_width = width;
4894 mDimension.display_height= height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004895 return NO_ERROR;
4896 }
4897 }
4898 LOGE("Invalid preview size requested: %dx%d", width, height);
4899 return BAD_VALUE;
4900}
4901
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004902status_t QualcommCameraHardware::setPreviewFrameRate(const CameraParameters& params)
4903{
Deepak Kurieneb58c682010-11-01 15:26:02 -07004904 if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
4905 LOGI("Set fps is not supported for this sensor");
Srinivasan Kannan2c99dba2010-07-28 13:50:53 -07004906 return NO_ERROR;
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07004907 }
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004908 uint16_t previousFps = (uint16_t)mParameters.getPreviewFrameRate();
4909 uint16_t fps = (uint16_t)params.getPreviewFrameRate();
4910 LOGV("requested preview frame rate is %u", fps);
4911
4912 if(mInitialized && (fps == previousFps)){
4913 LOGV("fps same as previous fps");
4914 return NO_ERROR;
4915 }
4916
4917 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
4918 mParameters.setPreviewFrameRate(fps);
Deepak Kurieneb58c682010-11-01 15:26:02 -07004919 bool ret = native_set_parms(CAMERA_PARM_FPS,
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004920 sizeof(fps), (void *)&fps);
4921 return ret ? NO_ERROR : UNKNOWN_ERROR;
4922 }
4923 return BAD_VALUE;
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004924}
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004925
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004926status_t QualcommCameraHardware::setPreviewFrameRateMode(const CameraParameters& params) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07004927 if( !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS_MODE) && !mCfgControl.mm_camera_is_supported(CAMERA_PARM_FPS)){
4928 LOGI("set fps mode is not supported for this sensor");
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004929 return NO_ERROR;
4930 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07004931
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004932 const char *previousMode = mParameters.getPreviewFrameRateMode();
4933 const char *str = params.getPreviewFrameRateMode();
4934 if( mInitialized && !strcmp(previousMode, str)) {
4935 LOGV("frame rate mode same as previous mode %s", previousMode);
4936 return NO_ERROR;
4937 }
4938 int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str);
4939 if(frameRateMode != NOT_FOUND) {
4940 LOGV("setPreviewFrameRateMode: %s ", str);
4941 mParameters.setPreviewFrameRateMode(str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07004942 bool ret = native_set_parms(CAMERA_PARM_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode);
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004943 if(!ret) return ret;
4944 //set the fps value when chaging modes
4945 int16_t fps = (uint16_t)params.getPreviewFrameRate();
4946 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
4947 mParameters.setPreviewFrameRate(fps);
Deepak Kurieneb58c682010-11-01 15:26:02 -07004948 ret = native_set_parms(CAMERA_PARM_FPS,
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004949 sizeof(fps), (void *)&fps);
4950 return ret ? NO_ERROR : UNKNOWN_ERROR;
4951 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07004952 LOGE("Invalid preview frame rate value: %d", fps);
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004953 return BAD_VALUE;
4954 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07004955 LOGE("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str);
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004956 return BAD_VALUE;
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004957}
4958
Srinivasan Kannan264376e2010-08-13 18:54:35 -07004959status_t QualcommCameraHardware::setJpegThumbnailSize(const CameraParameters& params){
4960 int width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
4961 int height = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
4962 LOGV("requested jpeg thumbnail size %d x %d", width, height);
4963
4964 // Validate the picture size
4965 for (int i = 0; i < JPEG_THUMBNAIL_SIZE_COUNT; ++i) {
4966 if (width == jpeg_thumbnail_sizes[i].width
4967 && height == jpeg_thumbnail_sizes[i].height) {
4968 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
4969 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
4970 return NO_ERROR;
4971 }
4972 }
4973 return BAD_VALUE;
4974}
4975
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004976status_t QualcommCameraHardware::setPictureSize(const CameraParameters& params)
4977{
4978 int width, height;
4979 params.getPictureSize(&width, &height);
4980 LOGV("requested picture size %d x %d", width, height);
4981
4982 // Validate the picture size
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08004983 for (int i = 0; i < supportedPictureSizesCount; ++i) {
4984 if (width == picture_sizes_ptr[i].width
4985 && height == picture_sizes_ptr[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004986 mParameters.setPictureSize(width, height);
4987 mDimension.picture_width = width;
4988 mDimension.picture_height = height;
4989 return NO_ERROR;
4990 }
4991 }
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08004992 /* Dimension not among the ones in the list. Check if
4993 * its a valid dimension, if it is, then configure the
4994 * camera accordingly. else reject it.
4995 */
4996 if( isValidDimension(width, height) ) {
4997 mParameters.setPictureSize(width, height);
4998 mDimension.picture_width = width;
4999 mDimension.picture_height = height;
5000 return NO_ERROR;
5001 } else
5002 LOGE("Invalid picture size requested: %dx%d", width, height);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005003 return BAD_VALUE;
5004}
5005
5006status_t QualcommCameraHardware::setJpegQuality(const CameraParameters& params) {
5007 status_t rc = NO_ERROR;
5008 int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
5009 if (quality > 0 && quality <= 100) {
5010 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
5011 } else {
5012 LOGE("Invalid jpeg quality=%d", quality);
5013 rc = BAD_VALUE;
5014 }
5015
5016 quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
5017 if (quality > 0 && quality <= 100) {
5018 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
5019 } else {
5020 LOGE("Invalid jpeg thumbnail quality=%d", quality);
5021 rc = BAD_VALUE;
5022 }
5023 return rc;
5024}
5025
5026status_t QualcommCameraHardware::setEffect(const CameraParameters& params)
5027{
5028 const char *str = params.get(CameraParameters::KEY_EFFECT);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005029 int result;
Apurva Rajguru7360db42010-04-09 16:37:36 -07005030
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005031 if (str != NULL) {
5032 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
5033 if (value != NOT_FOUND) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07005034 if( !mCfgControl.mm_camera_is_parm_supported(CAMERA_PARM_EFFECT, (void *) &value)){
5035 LOGE("Camera Effect - %s mode is not supported for this sensor",str);
Apurva Rajguru7360db42010-04-09 16:37:36 -07005036 return NO_ERROR;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005037 }else {
Apurva Rajguru7360db42010-04-09 16:37:36 -07005038 mParameters.set(CameraParameters::KEY_EFFECT, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005039 bool ret = native_set_parms(CAMERA_PARM_EFFECT, sizeof(value),
5040 (void *)&value,(int *)&result);
5041 if(result == MM_CAMERA_ERR_INVALID_OPERATION) {
5042 LOGI("Camera Effect: %s is not set as the selected value is not supported ", str);
5043 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07005044 return ret ? NO_ERROR : UNKNOWN_ERROR;
5045 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005046 }
5047 }
5048 LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
5049 return BAD_VALUE;
5050}
5051
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07005052status_t QualcommCameraHardware::setExposureCompensation(
5053 const CameraParameters & params){
Deepak Kurieneb58c682010-11-01 15:26:02 -07005054 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_EXPOSURE_COMPENSATION)) {
5055 LOGI("Exposure Compensation is not supported for this sensor");
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07005056 return NO_ERROR;
5057 }
5058
5059 int numerator = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
5060 if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator &&
5061 numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
5062 int16_t numerator16 = (int16_t)(numerator & 0x0000ffff);
5063 uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
5064 uint32_t value = 0;
5065 value = numerator16 << 16 | denominator16;
5066
5067 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
5068 numerator);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005069 bool ret = native_set_parms(CAMERA_PARM_EXPOSURE_COMPENSATION,
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07005070 sizeof(value), (void *)&value);
5071 return ret ? NO_ERROR : UNKNOWN_ERROR;
5072 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005073 LOGE("Invalid Exposure Compensation");
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07005074 return BAD_VALUE;
5075}
5076
Apurva Rajguru55562b02009-12-03 12:25:35 -08005077status_t QualcommCameraHardware::setAutoExposure(const CameraParameters& params)
5078{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005079 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_EXPOSURE)) {
5080 LOGI("Auto Exposure not supported for this sensor");
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005081 return NO_ERROR;
5082 }
Apurva Rajguru55562b02009-12-03 12:25:35 -08005083 const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
5084 if (str != NULL) {
5085 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
5086 if (value != NOT_FOUND) {
5087 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005088 bool ret = native_set_parms(CAMERA_PARM_EXPOSURE, sizeof(value),
Apurva Rajguru55562b02009-12-03 12:25:35 -08005089 (void *)&value);
5090 return ret ? NO_ERROR : UNKNOWN_ERROR;
5091 }
5092 }
5093 LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
5094 return BAD_VALUE;
5095}
5096
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005097status_t QualcommCameraHardware::setSharpness(const CameraParameters& params)
5098{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005099 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SHARPNESS)) {
5100 LOGI("Sharpness not supported for this sensor");
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005101 return NO_ERROR;
5102 }
5103 int sharpness = params.getInt(CameraParameters::KEY_SHARPNESS);
5104 if((sharpness < CAMERA_MIN_SHARPNESS
5105 || sharpness > CAMERA_MAX_SHARPNESS))
5106 return UNKNOWN_ERROR;
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005107
5108 LOGV("setting sharpness %d", sharpness);
5109 mParameters.set(CameraParameters::KEY_SHARPNESS, sharpness);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005110 bool ret = native_set_parms(CAMERA_PARM_SHARPNESS, sizeof(sharpness),
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005111 (void *)&sharpness);
5112 return ret ? NO_ERROR : UNKNOWN_ERROR;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005113}
5114
5115status_t QualcommCameraHardware::setContrast(const CameraParameters& params)
5116{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005117 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_CONTRAST)) {
5118 LOGI("Contrast not supported for this sensor");
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005119 return NO_ERROR;
5120 }
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005121
Apurva Rajguru08383852010-05-17 14:25:39 -07005122 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
5123 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
5124
5125 if(value == CAMERA_BESTSHOT_OFF) {
5126 int contrast = params.getInt(CameraParameters::KEY_CONTRAST);
5127 if((contrast < CAMERA_MIN_CONTRAST)
5128 || (contrast > CAMERA_MAX_CONTRAST))
5129 return UNKNOWN_ERROR;
5130
5131 LOGV("setting contrast %d", contrast);
5132 mParameters.set(CameraParameters::KEY_CONTRAST, contrast);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005133 bool ret = native_set_parms(CAMERA_PARM_CONTRAST, sizeof(contrast),
Apurva Rajguru08383852010-05-17 14:25:39 -07005134 (void *)&contrast);
5135 return ret ? NO_ERROR : UNKNOWN_ERROR;
5136 } else {
Deepak Kurieneb58c682010-11-01 15:26:02 -07005137 LOGI(" Contrast value will not be set " \
Apurva Rajguru08383852010-05-17 14:25:39 -07005138 "when the scenemode selected is %s", str);
5139 return NO_ERROR;
5140 }
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005141}
5142
5143status_t QualcommCameraHardware::setSaturation(const CameraParameters& params)
5144{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005145 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SATURATION)) {
5146 LOGI("Saturation not supported for this sensor");
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005147 return NO_ERROR;
5148 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005149 int result;
5150 int saturation = params.getInt(CameraParameters::KEY_SATURATION);
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005151
Deepak Kurieneb58c682010-11-01 15:26:02 -07005152 if((saturation < CAMERA_MIN_SATURATION)
5153 || (saturation > CAMERA_MAX_SATURATION))
5154 return UNKNOWN_ERROR;
Kiran Kumar H Nf87cf862010-01-27 14:34:34 -08005155
Deepak Kurieneb58c682010-11-01 15:26:02 -07005156 LOGV("Setting saturation %d", saturation);
5157 mParameters.set(CameraParameters::KEY_SATURATION, saturation);
5158 bool ret = native_set_parms(CAMERA_PARM_SATURATION, sizeof(saturation),
5159 (void *)&saturation, (int *)&result);
5160 if(result == MM_CAMERA_ERR_INVALID_OPERATION)
5161 LOGI("Saturation Value: %d is not set as the selected value is not supported", saturation);
Kiran Kumar H Nf87cf862010-01-27 14:34:34 -08005162
Deepak Kurieneb58c682010-11-01 15:26:02 -07005163 return ret ? NO_ERROR : UNKNOWN_ERROR;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005164}
5165
Mohan Kandra7110c242010-07-18 15:34:48 -07005166status_t QualcommCameraHardware::setPreviewFormat(const CameraParameters& params) {
5167 const char *str = params.getPreviewFormat();
5168 int32_t previewFormat = attr_lookup(preview_formats, sizeof(preview_formats) / sizeof(str_map), str);
5169 if(previewFormat != NOT_FOUND) {
5170 mParameters.set(CameraParameters::KEY_PREVIEW_FORMAT, str);
5171 mPreviewFormat = previewFormat;
5172 return NO_ERROR;
5173 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005174 LOGE("Invalid preview format value: %s", (str == NULL) ? "NULL" : str);
Mohan Kandra7110c242010-07-18 15:34:48 -07005175 return BAD_VALUE;
5176}
5177
5178status_t QualcommCameraHardware::setStrTextures(const CameraParameters& params) {
5179 const char *str = params.get("strtextures");
5180 if(str != NULL) {
Mohan Kandra2cd34e62010-10-06 18:15:56 -07005181 LOGV("strtextures = %s", str);
Mohan Kandra7110c242010-07-18 15:34:48 -07005182 mParameters.set("strtextures", str);
Mohan Kandra4ebb9102010-11-09 17:52:30 -08005183 if(!strncmp(str, "on", 2) || !strncmp(str, "ON", 2)) {
5184 LOGI("Resetting mUseOverlay to false");
5185 strTexturesOn = true;
5186 mUseOverlay = false;
5187 } else if (!strncmp(str, "off", 3) || !strncmp(str, "OFF", 3)) {
5188 strTexturesOn = false;
5189 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
5190 mUseOverlay = true;
Mohan Kandra7110c242010-07-18 15:34:48 -07005191 }
5192 }
5193 return NO_ERROR;
5194}
5195
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305196status_t QualcommCameraHardware::setBrightness(const CameraParameters& params) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07005197 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BRIGHTNESS)) {
5198 LOGI("Set Brightness not supported for this sensor");
5199 return NO_ERROR;
5200 }
5201 int brightness = params.getInt("luma-adaptation");
5202 if (mBrightness != brightness) {
5203 LOGV(" new brightness value : %d ", brightness);
5204 mBrightness = brightness;
5205 bool ret = native_set_parms(CAMERA_PARM_BRIGHTNESS, sizeof(mBrightness),
5206 (void *)&mBrightness);
5207 return ret ? NO_ERROR : UNKNOWN_ERROR;
5208 }
5209 return NO_ERROR;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305210}
5211
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07005212status_t QualcommCameraHardware::setSkinToneEnhancement(const CameraParameters& params) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07005213 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_SCE_FACTOR)) {
5214 LOGI("SkinToneEnhancement not supported for this sensor");
5215 return NO_ERROR;
5216 }
5217 int skinToneValue = params.getInt("skinToneEnhancement");
5218 if (mSkinToneEnhancement != skinToneValue) {
5219 LOGV(" new skinTone correction value : %d ", skinToneValue);
5220 mSkinToneEnhancement = skinToneValue;
5221 mParameters.set("skinToneEnhancement", skinToneValue);
5222 bool ret = native_set_parms(CAMERA_PARM_SCE_FACTOR, sizeof(mSkinToneEnhancement),
5223 (void *)&mSkinToneEnhancement);
5224 return ret ? NO_ERROR : UNKNOWN_ERROR;
5225 }
5226 return NO_ERROR;
Priyanka Kharate8dd0d62010-09-27 09:52:34 -07005227}
5228
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005229status_t QualcommCameraHardware::setWhiteBalance(const CameraParameters& params)
5230{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005231 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_WHITE_BALANCE)) {
5232 LOGI("WhiteBalance not supported for this sensor");
5233 return NO_ERROR;
5234 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07005235
Deepak Kurieneb58c682010-11-01 15:26:02 -07005236 int result;
Apurva Rajguru7360db42010-04-09 16:37:36 -07005237
Deepak Kurieneb58c682010-11-01 15:26:02 -07005238 const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
5239 if (str != NULL) {
5240 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
5241 if (value != NOT_FOUND) {
5242 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
5243 bool ret = native_set_parms(CAMERA_PARM_WHITE_BALANCE, sizeof(value),
5244 (void *)&value, (int *)&result);
5245 if(result == MM_CAMERA_ERR_INVALID_OPERATION) {
5246 LOGI("WhiteBalance Value: %s is not set as the selected value is not supported ", str);
Apurva Rajguru7360db42010-04-09 16:37:36 -07005247 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005248 return ret ? NO_ERROR : UNKNOWN_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005249 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005250 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07005251 LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
5252 return BAD_VALUE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005253}
5254
5255status_t QualcommCameraHardware::setFlash(const CameraParameters& params)
5256{
5257 if (!mSensorInfo.flash_enabled) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07005258 LOGI("%s: flash not supported", __FUNCTION__);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005259 return NO_ERROR;
5260 }
5261
5262 const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
5263 if (str != NULL) {
5264 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
5265 if (value != NOT_FOUND) {
5266 mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005267 bool ret = native_set_parms(CAMERA_PARM_LED_MODE,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005268 sizeof(value), (void *)&value);
5269 return ret ? NO_ERROR : UNKNOWN_ERROR;
5270 }
5271 }
5272 LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
5273 return BAD_VALUE;
5274}
5275
5276status_t QualcommCameraHardware::setAntibanding(const CameraParameters& params)
Deepak Kuriencbd25d92010-10-08 10:16:08 -07005277{ int result;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005278 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ANTIBANDING)) {
5279 LOGI("Parameter AntiBanding is not supported for this sensor");
Srinivasan Kannan2229d272010-01-05 14:58:28 -08005280 return NO_ERROR;
5281 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005282 const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
5283 if (str != NULL) {
5284 int value = (camera_antibanding_type)attr_lookup(
5285 antibanding, sizeof(antibanding) / sizeof(str_map), str);
5286 if (value != NOT_FOUND) {
5287 camera_antibanding_type temp = (camera_antibanding_type) value;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005288 mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005289 bool ret = native_set_parms(CAMERA_PARM_ANTIBANDING,
5290 sizeof(camera_antibanding_type), (void *)&temp ,(int *)&result);
5291 if(result == MM_CAMERA_ERR_INVALID_OPERATION) {
5292 LOGI("AntiBanding Value: %s is not supported for the given BestShot Mode", str);
Srinivasan Kannan2229d272010-01-05 14:58:28 -08005293 }
5294 return ret ? NO_ERROR : UNKNOWN_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005295 }
5296 }
5297 LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
5298 return BAD_VALUE;
5299}
5300
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305301status_t QualcommCameraHardware::setLensshadeValue(const CameraParameters& params)
5302{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005303 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ROLLOFF)) {
Mohan Kandra1307f312010-04-29 10:18:42 -07005304 LOGI("Parameter Rolloff is not supported for this sensor");
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005305 return NO_ERROR;
5306 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005307
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305308 const char *str = params.get(CameraParameters::KEY_LENSSHADE);
5309 if (str != NULL) {
5310 int value = attr_lookup(lensshade,
5311 sizeof(lensshade) / sizeof(str_map), str);
5312 if (value != NOT_FOUND) {
5313 int8_t temp = (int8_t)value;
5314 mParameters.set(CameraParameters::KEY_LENSSHADE, str);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005315
Deepak Kurieneb58c682010-11-01 15:26:02 -07005316 native_set_parms(CAMERA_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305317 return NO_ERROR;
5318 }
5319 }
5320 LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
5321 return BAD_VALUE;
5322}
5323
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005324status_t QualcommCameraHardware::setContinuousAf(const CameraParameters& params)
5325{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005326 if(mHasAutoFocusSupport){
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005327 const char *str = params.get(CameraParameters::KEY_CONTINUOUS_AF);
5328 if (str != NULL) {
5329 int value = attr_lookup(continuous_af,
5330 sizeof(continuous_af) / sizeof(str_map), str);
5331 if (value != NOT_FOUND) {
5332 int8_t temp = (int8_t)value;
5333 mParameters.set(CameraParameters::KEY_CONTINUOUS_AF, str);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005334
Deepak Kurieneb58c682010-11-01 15:26:02 -07005335 native_set_parms(CAMERA_PARM_CONTINUOUS_AF, sizeof(int8_t), (void *)&temp);
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005336 return NO_ERROR;
5337 }
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005338 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005339 LOGE("Invalid continuous Af value: %s", (str == NULL) ? "NULL" : str);
5340 return BAD_VALUE;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005341 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005342 return NO_ERROR;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005343}
5344
Apurva Rajgurue5965c42010-09-09 14:24:54 -07005345status_t QualcommCameraHardware::setSelectableZoneAf(const CameraParameters& params)
5346{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005347 if(mHasAutoFocusSupport && supportsSelectableZoneAf()) {
Apurva Rajgurue5965c42010-09-09 14:24:54 -07005348 const char *str = params.get(CameraParameters::KEY_SELECTABLE_ZONE_AF);
5349 if (str != NULL) {
5350 int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str);
5351 if (value != NOT_FOUND) {
5352 mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005353 bool ret = native_set_parms(CAMERA_PARM_FOCUS_RECT, sizeof(value),
Apurva Rajgurue5965c42010-09-09 14:24:54 -07005354 (void *)&value);
5355 return ret ? NO_ERROR : UNKNOWN_ERROR;
5356 }
5357 }
5358 LOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str);
5359 return BAD_VALUE;
5360 }
5361 return NO_ERROR;
5362}
5363
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005364status_t QualcommCameraHardware::setTouchAfAec(const CameraParameters& params)
5365{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005366 if(mHasAutoFocusSupport){
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005367 int xAec, yAec, xAf, yAf;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005368
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005369 params.getTouchIndexAec(&xAec, &yAec);
5370 params.getTouchIndexAf(&xAf, &yAf);
5371 const char *str = params.get(CameraParameters::KEY_TOUCH_AF_AEC);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005372
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005373 if (str != NULL) {
5374 int value = attr_lookup(touchafaec,
5375 sizeof(touchafaec) / sizeof(str_map), str);
5376 if (value != NOT_FOUND) {
5377 mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC, str);
5378 mParameters.setTouchIndexAec(xAec, yAec);
5379 mParameters.setTouchIndexAf(xAf, yAf);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005380
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005381 cam_set_aec_roi_t aec_roi_value;
5382 roi_info_t af_roi_value;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005383
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005384 memset(&af_roi_value, 0, sizeof(roi_info_t));
5385
5386 //If touch AF/AEC is enabled and touch event has occured then
5387 //call the ioctl with valid values.
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005388 if (value == true
5389 && (xAec >= 0 && yAec >= 0)
5390 && (xAf >= 0 && yAf >= 0)) {
Apurva Rajguruf9317f22010-10-27 15:16:54 -07005391 //Set Touch AEC params (Pass the center co-ordinate)
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005392 aec_roi_value.aec_roi_enable = AEC_ROI_ON;
5393 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
5394 aec_roi_value.aec_roi_position.coordinate.x = xAec;
5395 aec_roi_value.aec_roi_position.coordinate.y = yAec;
5396
Apurva Rajguruf9317f22010-10-27 15:16:54 -07005397 //Set Touch AF params (Pass the top left co-ordinate)
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005398 af_roi_value.num_roi = 1;
Apurva Rajguruf9317f22010-10-27 15:16:54 -07005399 if ((xAf-50) < 0)
5400 af_roi_value.roi[0].x = 1;
5401 else
5402 af_roi_value.roi[0].x = xAf - (FOCUS_RECTANGLE_DX/2);
5403
5404 if ((yAf-50) < 0)
5405 af_roi_value.roi[0].y = 1;
5406 else
5407 af_roi_value.roi[0].y = yAf - (FOCUS_RECTANGLE_DY/2);
5408
5409 af_roi_value.roi[0].dx = FOCUS_RECTANGLE_DX;
5410 af_roi_value.roi[0].dy = FOCUS_RECTANGLE_DY;
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005411 }
5412 else {
5413 //Set Touch AEC params
5414 aec_roi_value.aec_roi_enable = AEC_ROI_OFF;
5415 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
5416 aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE;
5417 aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE;
5418
5419 //Set Touch AF params
5420 af_roi_value.num_roi = 0;
5421 }
Deepak Kurieneb58c682010-11-01 15:26:02 -07005422 native_set_parms(CAMERA_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value);
5423 native_set_parms(CAMERA_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005424 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005425 return NO_ERROR;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005426 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005427 LOGE("Invalid Touch AF/AEC value: %s", (str == NULL) ? "NULL" : str);
5428 return BAD_VALUE;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005429 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005430 return NO_ERROR;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005431}
5432
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305433status_t QualcommCameraHardware::setISOValue(const CameraParameters& params) {
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005434 int8_t temp_hjr;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005435 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ISO)) {
5436 LOGE("Parameter ISO Value is not supported for this sensor");
Deepak Kurien38e6bb02010-10-05 21:25:22 -07005437 return NO_ERROR;
5438 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305439 const char *str = params.get(CameraParameters::KEY_ISO_MODE);
5440 if (str != NULL) {
5441 int value = (camera_iso_mode_type)attr_lookup(
5442 iso, sizeof(iso) / sizeof(str_map), str);
5443 if (value != NOT_FOUND) {
5444 camera_iso_mode_type temp = (camera_iso_mode_type) value;
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005445 if (value == CAMERA_ISO_DEBLUR) {
5446 temp_hjr = true;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005447 native_set_parms(CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005448 mHJR = value;
5449 }
5450 else {
5451 if (mHJR == CAMERA_ISO_DEBLUR) {
5452 temp_hjr = false;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005453 native_set_parms(CAMERA_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005454 mHJR = value;
5455 }
5456 }
5457
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305458 mParameters.set(CameraParameters::KEY_ISO_MODE, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005459 native_set_parms(CAMERA_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305460 return NO_ERROR;
5461 }
5462 }
5463 LOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
5464 return BAD_VALUE;
5465}
5466
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005467status_t QualcommCameraHardware::setSceneDetect(const CameraParameters& params)
5468{
5469
5470 bool retParm1, retParm2;
5471 if (supportsSceneDetection()) {
Deepak Kurieneb58c682010-11-01 15:26:02 -07005472 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BL_DETECTION) && !mCfgControl.mm_camera_is_supported(CAMERA_PARM_SNOW_DETECTION)) {
5473 LOGE("Parameter Auto Scene Detection is not supported for this sensor");
Apurva Rajguru0d400562010-09-13 14:12:02 -07005474 return NO_ERROR;
5475 }
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005476 const char *str = params.get(CameraParameters::KEY_SCENE_DETECT);
5477 if (str != NULL) {
5478 int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str);
5479 if (value != NOT_FOUND) {
5480 mParameters.set(CameraParameters::KEY_SCENE_DETECT, str);
5481
Deepak Kurieneb58c682010-11-01 15:26:02 -07005482 retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value),
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005483 (void *)&value);
5484
Deepak Kurieneb58c682010-11-01 15:26:02 -07005485 retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value),
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005486 (void *)&value);
5487
5488 //All Auto Scene detection modes should be all ON or all OFF.
5489 if(retParm1 == false || retParm2 == false) {
5490 value = !value;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005491 retParm1 = native_set_parms(CAMERA_PARM_BL_DETECTION, sizeof(value),
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005492 (void *)&value);
5493
Deepak Kurieneb58c682010-11-01 15:26:02 -07005494 retParm2 = native_set_parms(CAMERA_PARM_SNOW_DETECTION, sizeof(value),
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005495 (void *)&value);
5496 }
5497 return (retParm1 && retParm2) ? NO_ERROR : UNKNOWN_ERROR;
5498 }
5499 }
5500 LOGE("Invalid auto scene detection value: %s", (str == NULL) ? "NULL" : str);
5501 return BAD_VALUE;
5502 }
5503 return NO_ERROR;
5504}
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305505
Apurva Rajguru08383852010-05-17 14:25:39 -07005506status_t QualcommCameraHardware::setSceneMode(const CameraParameters& params)
5507{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005508 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_BESTSHOT_MODE)) {
5509 LOGE("Parameter Scenemode is not supported for this sensor");
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005510 return NO_ERROR;
5511 }
5512
Apurva Rajguru08383852010-05-17 14:25:39 -07005513 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
5514
5515 if (str != NULL) {
5516 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
5517 if (value != NOT_FOUND) {
5518 mParameters.set(CameraParameters::KEY_SCENE_MODE, str);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005519 bool ret = native_set_parms(CAMERA_PARM_BESTSHOT_MODE, sizeof(value),
Apurva Rajguru08383852010-05-17 14:25:39 -07005520 (void *)&value);
5521 return ret ? NO_ERROR : UNKNOWN_ERROR;
5522 }
5523 }
5524 LOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str);
5525 return BAD_VALUE;
5526}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005527status_t QualcommCameraHardware::setGpsLocation(const CameraParameters& params)
5528{
Srinivasan Kannan09de3382010-08-16 16:42:00 -07005529 const char *method = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
5530 if (method) {
5531 mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, method);
5532 }
5533
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005534 const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
5535 if (latitude) {
5536 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
5537 }
5538
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005539 const char *latitudeRef = params.get(CameraParameters::KEY_GPS_LATITUDE_REF);
5540 if (latitudeRef) {
5541 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
5542 }
5543
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005544 const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
5545 if (longitude) {
5546 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
5547 }
5548
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005549 const char *longitudeRef = params.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
5550 if (longitudeRef) {
5551 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
5552 }
5553
5554 const char *altitudeRef = params.get(CameraParameters::KEY_GPS_ALTITUDE_REF);
5555 if (altitudeRef) {
5556 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
5557 }
5558
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005559 const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
5560 if (altitude) {
5561 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
5562 }
5563
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005564 const char *status = params.get(CameraParameters::KEY_GPS_STATUS);
5565 if (status) {
5566 mParameters.set(CameraParameters::KEY_GPS_STATUS, status);
5567 }
5568
5569 const char *dateTime = params.get(CameraParameters::KEY_EXIF_DATETIME);
5570 if (dateTime) {
5571 mParameters.set(CameraParameters::KEY_EXIF_DATETIME, dateTime);
5572 }
5573
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005574 const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
5575 if (timestamp) {
5576 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
5577 }
5578 return NO_ERROR;
5579}
5580
5581status_t QualcommCameraHardware::setRotation(const CameraParameters& params)
5582{
5583 status_t rc = NO_ERROR;
5584 int rotation = params.getInt(CameraParameters::KEY_ROTATION);
5585 if (rotation != NOT_FOUND) {
5586 if (rotation == 0 || rotation == 90 || rotation == 180
5587 || rotation == 270) {
5588 mParameters.set(CameraParameters::KEY_ROTATION, rotation);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005589 mRotation = rotation;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005590 } else {
5591 LOGE("Invalid rotation value: %d", rotation);
5592 rc = BAD_VALUE;
5593 }
5594 }
5595 return rc;
5596}
5597
5598status_t QualcommCameraHardware::setZoom(const CameraParameters& params)
5599{
Deepak Kurieneb58c682010-11-01 15:26:02 -07005600 if(!mCfgControl.mm_camera_is_supported(CAMERA_PARM_ZOOM)) {
5601 LOGE("Parameter setZoom is not supported for this sensor");
5602 return NO_ERROR;
5603 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005604 status_t rc = NO_ERROR;
5605 // No matter how many different zoom values the driver can provide, HAL
5606 // provides applictations the same number of zoom levels. The maximum driver
5607 // zoom value depends on sensor output (VFE input) and preview size (VFE
5608 // output) because VFE can only crop and cannot upscale. If the preview size
5609 // is bigger, the maximum zoom ratio is smaller. However, we want the
5610 // zoom ratio of each zoom level is always the same whatever the preview
5611 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
5612 // we need to have a fixed maximum zoom value and do read it from the
5613 // driver.
Mohan Kandra284966d2010-01-05 13:39:15 -08005614 static const int ZOOM_STEP = 1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005615 int32_t zoom_level = params.getInt("zoom");
Mohan Kandra6599e352010-11-15 12:23:36 -08005616 if(zoom_level >= 0 && zoom_level <= mMaxZoom-1) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005617 mParameters.set("zoom", zoom_level);
5618 int32_t zoom_value = ZOOM_STEP * zoom_level;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005619 bool ret = native_set_parms(CAMERA_PARM_ZOOM,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005620 sizeof(zoom_value), (void *)&zoom_value);
5621 rc = ret ? NO_ERROR : UNKNOWN_ERROR;
5622 } else {
5623 rc = BAD_VALUE;
5624 }
5625
5626 return rc;
5627}
5628
5629status_t QualcommCameraHardware::setFocusMode(const CameraParameters& params)
5630{
5631 const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
5632 if (str != NULL) {
5633 int32_t value = attr_lookup(focus_modes,
5634 sizeof(focus_modes) / sizeof(str_map), str);
5635 if (value != NOT_FOUND) {
5636 mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
5637 // Focus step is reset to infinity when preview is started. We do
5638 // not need to do anything now.
5639 return NO_ERROR;
5640 }
5641 }
5642 LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
5643 return BAD_VALUE;
5644}
5645
5646status_t QualcommCameraHardware::setOrientation(const CameraParameters& params)
5647{
5648 const char *str = params.get("orientation");
5649
5650 if (str != NULL) {
5651 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
5652 // Camera service needs this to decide if the preview frames and raw
5653 // pictures should be rotated.
5654 mParameters.set("orientation", str);
5655 } else {
5656 LOGE("Invalid orientation value: %s", str);
5657 return BAD_VALUE;
5658 }
5659 }
5660 return NO_ERROR;
5661}
5662
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08005663status_t QualcommCameraHardware::setPictureFormat(const CameraParameters& params)
5664{
5665 const char * str = params.get(CameraParameters::KEY_PICTURE_FORMAT);
5666
5667 if(str != NULL){
5668 int32_t value = attr_lookup(picture_formats,
5669 sizeof(picture_formats) / sizeof(str_map), str);
5670 if(value != NOT_FOUND){
5671 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT, str);
5672 } else {
5673 LOGE("Invalid Picture Format value: %s", str);
5674 return BAD_VALUE;
5675 }
5676 }
5677 return NO_ERROR;
5678}
5679
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005680QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
5681 int frame_size,
5682 const char *name) :
5683 mBufferSize(buffer_size),
5684 mNumBuffers(num_buffers),
5685 mFrameSize(frame_size),
5686 mBuffers(NULL), mName(name)
5687{
5688 int page_size_minus_1 = getpagesize() - 1;
5689 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
5690}
5691
5692void QualcommCameraHardware::MemPool::completeInitialization()
5693{
5694 // If we do not know how big the frame will be, we wait to allocate
5695 // the buffers describing the individual frames until we do know their
5696 // size.
5697
5698 if (mFrameSize > 0) {
5699 mBuffers = new sp<MemoryBase>[mNumBuffers];
5700 for (int i = 0; i < mNumBuffers; i++) {
5701 mBuffers[i] = new
5702 MemoryBase(mHeap,
5703 i * mAlignedBufferSize,
5704 mFrameSize);
5705 }
5706 }
5707}
5708
5709QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
5710 int frame_size,
5711 const char *name) :
5712 QualcommCameraHardware::MemPool(buffer_size,
5713 num_buffers,
5714 frame_size,
5715 name)
5716{
5717 LOGV("constructing MemPool %s backed by ashmem: "
5718 "%d frames @ %d uint8_ts, "
5719 "buffer size %d",
5720 mName,
5721 num_buffers, frame_size, buffer_size);
5722
5723 int page_mask = getpagesize() - 1;
5724 int ashmem_size = buffer_size * num_buffers;
5725 ashmem_size += page_mask;
5726 ashmem_size &= ~page_mask;
5727
5728 mHeap = new MemoryHeapBase(ashmem_size);
5729
5730 completeInitialization();
5731}
5732
5733static bool register_buf(int camfd,
5734 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08005735 int frame_size,
Mohan Kandra02486042010-06-18 16:49:43 -07005736 int cbcr_offset,
5737 int yoffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005738 int pmempreviewfd,
5739 uint32_t offset,
5740 uint8_t *buf,
5741 int pmem_type,
5742 bool vfe_can_write,
5743 bool register_buffer = true);
5744
5745QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
5746 int flags,
5747 int camera_control_fd,
5748 int pmem_type,
5749 int buffer_size, int num_buffers,
Mohan Kandra02486042010-06-18 16:49:43 -07005750 int frame_size, int cbcr_offset,
5751 int yOffset, const char *name) :
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005752 QualcommCameraHardware::MemPool(buffer_size,
5753 num_buffers,
5754 frame_size,
5755 name),
5756 mPmemType(pmem_type),
Mohan Kandra02486042010-06-18 16:49:43 -07005757 mCbCrOffset(cbcr_offset),
5758 myOffset(yOffset),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005759 mCameraControlFd(dup(camera_control_fd))
5760{
Mohan Kandra2cd34e62010-10-06 18:15:56 -07005761 LOGI("constructing MemPool %s backed by pmem pool %s: "
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005762 "%d frames @ %d bytes, buffer size %d",
5763 mName,
5764 pmem_pool, num_buffers, frame_size,
5765 buffer_size);
5766
5767 LOGV("%s: duplicating control fd %d --> %d",
5768 __FUNCTION__,
5769 camera_control_fd, mCameraControlFd);
5770
5771 // Make a new mmap'ed heap that can be shared across processes.
5772 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
5773 mAlignedSize = mAlignedBufferSize * num_buffers;
5774
5775 sp<MemoryHeapBase> masterHeap =
5776 new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
5777
5778 if (masterHeap->getHeapID() < 0) {
5779 LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
5780 masterHeap.clear();
5781 return;
5782 }
5783
5784 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
5785 if (pmemHeap->getHeapID() >= 0) {
5786 pmemHeap->slap();
5787 masterHeap.clear();
5788 mHeap = pmemHeap;
5789 pmemHeap.clear();
5790
5791 mFd = mHeap->getHeapID();
5792 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
5793 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
5794 pmem_pool,
5795 ::strerror(errno), errno);
5796 mHeap.clear();
5797 return;
5798 }
5799
5800 LOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
5801 pmem_pool,
5802 mFd,
5803 mSize.len);
Mohan Kandra284966d2010-01-05 13:39:15 -08005804 LOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005805 // Unregister preview buffers with the camera drivers. Allow the VFE to write
5806 // to all preview buffers except for the last one.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08005807 // Only Register the preview, snapshot and thumbnail buffers with the kernel.
Mohan Kandrad9efed92010-01-15 19:08:39 -08005808 if( (strcmp("postview", mName) != 0) ){
5809 int num_buf = num_buffers;
5810 if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount;
Brian Steuerb62adbd2010-02-02 14:47:08 -08005811 LOGD("num_buffers = %d", num_buf);
Mohan Kandrad9efed92010-01-15 19:08:39 -08005812 for (int cnt = 0; cnt < num_buf; ++cnt) {
Sravankb4f5f1c2010-01-21 11:06:17 +05305813 int active = 1;
5814 if(pmem_type == MSM_PMEM_VIDEO){
5815 active = (cnt<ACTIVE_VIDEO_BUFFERS);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005816 //When VPE is enabled, set the last record
5817 //buffer as active and pmem type as PMEM_VIDEO_VPE
5818 //as this is a requirement from VPE operation.
Mohan Kandra88db27a2010-08-22 12:33:36 -07005819 //No need to set this pmem type to VIDEO_VPE while unregistering,
5820 //because as per camera stack design: "the VPE AXI is also configured
5821 //when VFE is configured for VIDEO, which is as part of preview
5822 //initialization/start. So during this VPE AXI config camera stack
5823 //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and
5824 //change it's type to PMEM_VIDEO".
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005825 if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
5826 active = 1;
5827 pmem_type = MSM_PMEM_VIDEO_VPE;
5828 }
Sravankb4f5f1c2010-01-21 11:06:17 +05305829 LOGV(" pmempool creating video buffers : active %d ", active);
5830 }
5831 else if (pmem_type == MSM_PMEM_PREVIEW){
5832 active = (cnt < (num_buf-1));
5833 }
Mohan Kandra284966d2010-01-05 13:39:15 -08005834 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005835 mBufferSize,
Mohan Kandra02486042010-06-18 16:49:43 -07005836 mFrameSize, mCbCrOffset, myOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005837 mHeap->getHeapID(),
5838 mAlignedBufferSize * cnt,
5839 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
5840 pmem_type,
Sravankb4f5f1c2010-01-21 11:06:17 +05305841 active);
Mohan Kandra284966d2010-01-05 13:39:15 -08005842 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005843 }
5844
5845 completeInitialization();
5846 }
5847 else LOGE("pmem pool %s error: could not create master heap!",
5848 pmem_pool);
Mohan Kandra2cd34e62010-10-06 18:15:56 -07005849 LOGI("%s: (%s) X ", __FUNCTION__, mName);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005850}
5851
5852QualcommCameraHardware::PmemPool::~PmemPool()
5853{
Mohan Kandra2cd34e62010-10-06 18:15:56 -07005854 LOGI("%s: %s E", __FUNCTION__, mName);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005855 if (mHeap != NULL) {
5856 // Unregister preview buffers with the camera drivers.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08005857 // Only Unregister the preview, snapshot and thumbnail
5858 // buffers with the kernel.
Mohan Kandrad9efed92010-01-15 19:08:39 -08005859 if( (strcmp("postview", mName) != 0) ){
5860 int num_buffers = mNumBuffers;
5861 if(!strcmp("preview", mName)) num_buffers = kPreviewBufferCount;
5862 for (int cnt = 0; cnt < num_buffers; ++cnt) {
Mohan Kandra284966d2010-01-05 13:39:15 -08005863 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005864 mBufferSize,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08005865 mFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07005866 mCbCrOffset,
5867 myOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005868 mHeap->getHeapID(),
5869 mAlignedBufferSize * cnt,
5870 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
5871 mPmemType,
5872 false,
5873 false /* unregister */);
Mohan Kandra284966d2010-01-05 13:39:15 -08005874 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005875 }
5876 }
5877 LOGV("destroying PmemPool %s: closing control fd %d",
5878 mName,
5879 mCameraControlFd);
5880 close(mCameraControlFd);
Mohan Kandra2cd34e62010-10-06 18:15:56 -07005881 LOGI("%s: %s X", __FUNCTION__, mName);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005882}
5883
5884QualcommCameraHardware::MemPool::~MemPool()
5885{
5886 LOGV("destroying MemPool %s", mName);
5887 if (mFrameSize > 0)
5888 delete [] mBuffers;
5889 mHeap.clear();
5890 LOGV("destroying MemPool %s completed", mName);
5891}
5892
5893static bool register_buf(int camfd,
5894 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08005895 int frame_size,
Mohan Kandra02486042010-06-18 16:49:43 -07005896 int cbcr_offset,
5897 int yoffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005898 int pmempreviewfd,
5899 uint32_t offset,
5900 uint8_t *buf,
5901 int pmem_type,
5902 bool vfe_can_write,
5903 bool register_buffer)
5904{
5905 struct msm_pmem_info pmemBuf;
5906
5907 pmemBuf.type = pmem_type;
5908 pmemBuf.fd = pmempreviewfd;
5909 pmemBuf.offset = offset;
5910 pmemBuf.len = size;
5911 pmemBuf.vaddr = buf;
Mohan Kandra02486042010-06-18 16:49:43 -07005912 pmemBuf.y_off = yoffset;
5913 pmemBuf.cbcr_off = cbcr_offset;
Srinivasan Kannanb36a4fe2010-01-29 19:34:09 -08005914
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005915 pmemBuf.active = vfe_can_write;
5916
5917 LOGV("register_buf: camfd = %d, reg = %d buffer = %p",
5918 camfd, !register_buffer, buf);
Deepak Kurieneb58c682010-11-01 15:26:02 -07005919 if(native_start_ops(register_buffer ? CAMERA_OPS_REGISTER_BUFFER :
5920 CAMERA_OPS_UNREGISTER_BUFFER ,(void *)&pmemBuf) < 0) {
5921 LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM fd %d error %s",
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005922 camfd,
5923 strerror(errno));
Deepak Kurieneb58c682010-11-01 15:26:02 -07005924 return false;
5925 }
5926
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005927 return true;
Deepak Kurieneb58c682010-11-01 15:26:02 -07005928
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005929}
5930
5931status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
5932{
5933 const size_t SIZE = 256;
5934 char buffer[SIZE];
5935 String8 result;
5936 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
5937 result.append(buffer);
5938 if (mName) {
5939 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
5940 result.append(buffer);
5941 }
5942 if (mHeap != 0) {
5943 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
5944 mHeap->getBase(), mHeap->getSize(),
5945 mHeap->getFlags(), mHeap->getDevice());
5946 result.append(buffer);
5947 }
5948 snprintf(buffer, 255,
5949 "buffer size (%d), number of buffers (%d), frame size(%d)",
5950 mBufferSize, mNumBuffers, mFrameSize);
5951 result.append(buffer);
5952 write(fd, result.string(), result.size());
5953 return NO_ERROR;
5954}
5955
5956static void receive_camframe_callback(struct msm_frame *frame)
5957{
5958 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5959 if (obj != 0) {
5960 obj->receivePreviewFrame(frame);
5961 }
5962}
5963
Nishant Pandit741742b2010-09-21 03:24:20 +05305964static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo)
5965{
5966 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5967 if (obj != 0) {
5968 obj->receiveCameraStats(stype,histinfo);
5969 }
5970}
5971
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05305972static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size)
5973{
5974 if(status == LIVESHOT_SUCCESS) {
5975 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5976 if (obj != 0) {
5977 obj->receiveLiveSnapshot(jpeg_size);
5978 }
5979 }
5980 else
5981 LOGE("Liveshot not succesful");
5982}
5983
5984
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005985static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size)
5986{
5987 LOGV("receive_jpeg_fragment_callback E");
5988 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5989 if (obj != 0) {
5990 obj->receiveJpegPictureFragment(buff_ptr, buff_size);
5991 }
5992 LOGV("receive_jpeg_fragment_callback X");
5993}
5994
5995static void receive_jpeg_callback(jpeg_event_t status)
5996{
5997 LOGV("receive_jpeg_callback E (completion status %d)", status);
5998 if (status == JPEG_EVENT_DONE) {
5999 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6000 if (obj != 0) {
6001 obj->receiveJpegPicture();
6002 }
6003 }
6004 LOGV("receive_jpeg_callback X");
6005}
Sravankb4f5f1c2010-01-21 11:06:17 +05306006// 720p : video frame calbback from camframe
6007static void receive_camframe_video_callback(struct msm_frame *frame)
6008{
6009 LOGV("receive_camframe_video_callback E");
6010 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6011 if (obj != 0) {
6012 obj->receiveRecordingFrame(frame);
6013 }
6014 LOGV("receive_camframe_video_callback X");
6015}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006016
6017void QualcommCameraHardware::setCallbacks(notify_callback notify_cb,
6018 data_callback data_cb,
6019 data_callback_timestamp data_cb_timestamp,
6020 void* user)
6021{
6022 Mutex::Autolock lock(mLock);
6023 mNotifyCallback = notify_cb;
6024 mDataCallback = data_cb;
6025 mDataCallbackTimestamp = data_cb_timestamp;
6026 mCallbackCookie = user;
6027}
6028
6029void QualcommCameraHardware::enableMsgType(int32_t msgType)
6030{
6031 Mutex::Autolock lock(mLock);
6032 mMsgEnabled |= msgType;
6033}
6034
6035void QualcommCameraHardware::disableMsgType(int32_t msgType)
6036{
6037 Mutex::Autolock lock(mLock);
6038 mMsgEnabled &= ~msgType;
6039}
6040
6041bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
6042{
6043 return (mMsgEnabled & msgType);
6044}
6045
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08006046bool QualcommCameraHardware::useOverlay(void)
6047{
Nishant Pandit3c278cd2010-07-13 15:56:04 +05306048 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) {
6049 /* 7x30 and 8x60 supports Overlay */
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08006050 mUseOverlay = TRUE;
6051 } else
6052 mUseOverlay = FALSE;
6053
6054 LOGV(" Using Overlay : %s ", mUseOverlay ? "YES" : "NO" );
6055 return mUseOverlay;
6056}
6057
6058status_t QualcommCameraHardware::setOverlay(const sp<Overlay> &Overlay)
6059{
6060 if( Overlay != NULL) {
6061 LOGV(" Valid overlay object ");
6062 mOverlayLock.lock();
6063 mOverlay = Overlay;
6064 mOverlayLock.unlock();
6065 } else {
Apurva Rajguruc73c1722010-04-15 17:39:11 -07006066 LOGV(" Overlay object NULL. returning ");
Mohan Kandrad9efed92010-01-15 19:08:39 -08006067 mOverlay = NULL;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08006068 return UNKNOWN_ERROR;
6069 }
6070 return NO_ERROR;
6071}
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006072
Mohan Kandra3dd524f2010-09-20 13:41:42 -07006073void QualcommCameraHardware::receive_camframe_error_timeout(void) {
6074 LOGI("receive_camframe_error_timeout: E");
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006075 Mutex::Autolock l(&mCamframeTimeoutLock);
Mohan Kandra1307f312010-04-29 10:18:42 -07006076 LOGE(" Camframe timed out. Not receiving any frames from camera driver ");
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006077 camframe_timeout_flag = TRUE;
Priyanka Kharatae03c212010-05-19 15:32:50 -07006078 mNotifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_UKNOWN, 0,
6079 mCallbackCookie);
Mohan Kandra3dd524f2010-09-20 13:41:42 -07006080 LOGI("receive_camframe_error_timeout: X");
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006081}
6082
Mohan Kandra3dd524f2010-09-20 13:41:42 -07006083static void receive_camframe_error_callback(camera_error_type err) {
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006084 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6085 if (obj != 0) {
Mohan Kandra3dd524f2010-09-20 13:41:42 -07006086 if ((err == CAMERA_ERROR_TIMEOUT) ||
6087 (err == CAMERA_ERROR_ESD)) {
6088 /* Handling different error types is dependent on the requirement.
6089 * Do the same action by default
6090 */
6091 obj->receive_camframe_error_timeout();
6092 }
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006093 }
6094}
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08006095
Priyanka Kharat02807662010-10-13 23:44:47 -07006096bool QualcommCameraHardware::storePreviewFrameForPostview(void) {
6097 LOGV("storePreviewFrameForPostview : E ");
6098
6099 /* Since there is restriction on the maximum overlay dimensions
6100 * that can be created, we use the last preview frame as postview
6101 * for 7x30. */
6102 LOGV("Copying the preview buffer to postview buffer %d ",
6103 mPreviewFrameSize);
6104 if(mPostViewHeap == NULL) {
6105 int CbCrOffset = PAD_TO_WORD(mPreviewFrameSize * 2/3);
6106 mPostViewHeap =
6107 new PmemPool("/dev/pmem_adsp",
6108 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
6109 mCameraControlFd,
6110 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
6111 mPreviewFrameSize,
6112 1,
6113 mPreviewFrameSize,
6114 CbCrOffset,
6115 0,
6116 "postview");
6117
6118 if (!mPostViewHeap->initialized()) {
6119 mPostViewHeap.clear();
6120 LOGE(" Failed to initialize Postview Heap");
6121 return false;
6122 }
6123 }
6124
6125 if( mPostViewHeap != NULL && mLastQueuedFrame != NULL) {
6126 memcpy(mPostViewHeap->mHeap->base(),
6127 (uint8_t *)mLastQueuedFrame, mPreviewFrameSize );
6128
6129 if( mUseOverlay && (mOverlay != NULL)){
6130 mOverlay->setFd(mPostViewHeap->mHeap->getHeapID());
6131 if( zoomCropInfo.w !=0 && zoomCropInfo.h !=0) {
6132 LOGD("zoomCropInfo non-zero, setting crop ");
6133 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
6134 zoomCropInfo.w, zoomCropInfo.h);
6135 }
6136 LOGV("Queueing Postview with last frame till the snapshot is done ");
6137 mOverlay->queueBuffer((void *)0);
6138 }
6139 } else
6140 LOGE("Failed to store Preview frame. No Postview ");
6141 LOGV("storePreviewFrameForPostview : X ");
6142 return true;
6143}
6144
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006145bool QualcommCameraHardware::isValidDimension(int width, int height) {
6146 bool retVal = FALSE;
6147 /* This function checks if a given resolution is valid or not.
6148 * A particular resolution is considered valid if it satisfies
6149 * the following conditions:
6150 * 1. width & height should be multiple of 16.
6151 * 2. width & height should be less than/equal to the dimensions
6152 * supported by the camera sensor.
6153 * 3. the aspect ratio is a valid aspect ratio and is among the
6154 * commonly used aspect ratio as determined by the thumbnail_sizes
6155 * data structure.
6156 */
6157
6158 if( (width == CEILING16(width)) && (height == CEILING16(height))
6159 && (width <= sensorType->max_supported_snapshot_width)
6160 && (height <= sensorType->max_supported_snapshot_height) )
6161 {
6162 uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height);
Mohan Kandra62429cc2010-07-19 10:21:05 -07006163 for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) {
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006164 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) {
6165 retVal = TRUE;
6166 break;
6167 }
6168 }
6169 }
6170 return retVal;
6171}
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006172status_t QualcommCameraHardware::getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize) {
6173 status_t ret;
6174 LOGV(" getBufferInfo : E ");
Nishant Pandit3c278cd2010-07-13 15:56:04 +05306175 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660) )
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306176 {
6177 if( mRecordHeap != NULL){
6178 LOGV(" Setting valid buffer information ");
6179 Frame = mRecordHeap->mBuffers[0];
6180 if( alignedSize != NULL) {
6181 *alignedSize = mRecordHeap->mAlignedBufferSize;
6182 LOGV(" HAL : alignedSize = %d ", *alignedSize);
6183 ret = NO_ERROR;
6184 } else {
6185 LOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
6186 ret = UNKNOWN_ERROR;
6187 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006188 } else {
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306189 LOGE(" RecordHeap is null. Buffer information wont be updated ");
6190 Frame = NULL;
6191 ret = UNKNOWN_ERROR;
6192 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006193 } else {
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306194 if(mPreviewHeap != NULL) {
6195 LOGV(" Setting valid buffer information ");
6196 Frame = mPreviewHeap->mBuffers[0];
6197 if( alignedSize != NULL) {
6198 *alignedSize = mPreviewHeap->mAlignedBufferSize;
6199 LOGV(" HAL : alignedSize = %d ", *alignedSize);
6200 ret = NO_ERROR;
6201 } else {
6202 LOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
6203 ret = UNKNOWN_ERROR;
6204 }
6205 } else {
6206 LOGE(" PreviewHeap is null. Buffer information wont be updated ");
6207 Frame = NULL;
6208 ret = UNKNOWN_ERROR;
6209 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006210 }
6211 LOGV(" getBufferInfo : X ");
6212 return ret;
6213}
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006214
Mohan Kandra1659b0c2010-07-18 16:36:25 -07006215void QualcommCameraHardware::encodeData() {
6216 LOGV("encodeData: E");
6217
6218 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
6219 mJpegSize = 0;
6220 mJpegThreadWaitLock.lock();
6221 if (LINK_jpeg_encoder_init()) {
6222 mJpegThreadRunning = true;
6223 mJpegThreadWaitLock.unlock();
6224 if(native_jpeg_encode()) {
6225 LOGV("encodeData: X (success)");
6226 //Wait until jpeg encoding is done and call jpeg join
6227 //in this context. Also clear the resources.
6228 mJpegThreadWaitLock.lock();
6229 while (mJpegThreadRunning) {
6230 LOGV("encodeData: waiting for jpeg thread to complete.");
6231 mJpegThreadWait.wait(mJpegThreadWaitLock);
6232 LOGV("encodeData: jpeg thread completed.");
6233 }
6234 mJpegThreadWaitLock.unlock();
6235 //Call jpeg join in this thread context
6236 LINK_jpeg_encoder_join();
6237 }
6238 LOGE("encodeData: jpeg encoding failed");
6239 }
6240 else {
6241 LOGE("encodeData X: jpeg_encoder_init failed.");
6242 mJpegThreadWaitLock.unlock();
6243 }
6244 }
6245 else LOGV("encodeData: JPEG callback is NULL, not encoding image.");
6246 //clear the resources
6247 deinitRaw();
6248 //Encoding is done.
6249 mEncodePendingWaitLock.lock();
6250 mEncodePending = false;
6251 mEncodePendingWait.signal();
6252 mEncodePendingWaitLock.unlock();
6253
6254 LOGV("encodeData: X");
6255}
6256
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006257}; // namespace android
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05306258