blob: 27553075411be612bc3e24a160ca227c744ae672 [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>
23
24#include "QualcommCameraHardware.h"
25
26#include <utils/Errors.h>
27#include <utils/threads.h>
28#include <binder/MemoryHeapPmem.h>
29#include <utils/String16.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <unistd.h>
Sravankb4f5f1c2010-01-21 11:06:17 +053033#include <fcntl.h>
Apurva Rajguru8d1773b2009-12-02 14:21:23 -080034#include <cutils/properties.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080035#include <math.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080036#if HAVE_ANDROID_OS
37#include <linux/android_pmem.h>
38#endif
39#include <linux/ioctl.h>
Priya Komarlingam9bb2d492010-06-23 19:21:52 -070040#include <camera/CameraParameters.h>
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +053041#include <media/mediarecorder.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080042
Mohan Kandra284966d2010-01-05 13:39:15 -080043#include "linux/msm_mdp.h"
44#include <linux/fb.h>
45
Priya Komarlingamb85535d2009-11-30 13:06:01 -080046#define LIKELY(exp) __builtin_expect(!!(exp), 1)
47#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
48
49extern "C" {
50#include <fcntl.h>
51#include <time.h>
52#include <pthread.h>
53#include <stdio.h>
54#include <string.h>
55#include <unistd.h>
56#include <termios.h>
57#include <assert.h>
58#include <stdlib.h>
59#include <ctype.h>
60#include <signal.h>
61#include <errno.h>
62#include <sys/mman.h>
63#include <sys/system_properties.h>
64#include <sys/time.h>
65#include <stdlib.h>
66
67#include <media/msm_camera.h>
68
69#include <camera.h>
70#include <camframe.h>
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +053071#include <liveshot.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080072#include <mm-still/jpeg/jpege.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080073#include <jpeg_encoder.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080074
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +053075#define DUMP_LIVESHOT_JPEG_FILE 0
76
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -080077#define DEFAULT_PICTURE_WIDTH 1024
78#define DEFAULT_PICTURE_HEIGHT 768
Priya Komarlingamb85535d2009-11-30 13:06:01 -080079#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
80#define MAX_ZOOM_LEVEL 5
81#define NOT_FOUND -1
Sravankb4f5f1c2010-01-21 11:06:17 +053082// Number of video buffers held by kernal (initially 1,2 &3)
83#define ACTIVE_VIDEO_BUFFERS 3
84
Nishant Panditc6fd2c22010-08-03 00:10:47 +053085#define PAD_TO_2K(x) (((x)+2047)& ~2047)
Nishant Panditbde07612010-07-28 00:16:28 +053086
Priya Komarlingamb85535d2009-11-30 13:06:01 -080087#if DLOPEN_LIBMMCAMERA
88#include <dlfcn.h>
89
90void* (*LINK_cam_conf)(void *data);
91void* (*LINK_cam_frame)(void *data);
92bool (*LINK_jpeg_encoder_init)();
93void (*LINK_jpeg_encoder_join)();
94bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
95 const uint8_t *thumbnailbuf, int thumbnailfd,
96 const uint8_t *snapshotbuf, int snapshotfd,
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080097 common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
Mohan Kandra1659b0c2010-07-18 16:36:25 -070098 int exif_table_numEntries, int jpegPadding, const int32_t cbcroffset);
Kiran Kumar H N7ac84e32010-02-01 10:58:47 -080099void (*LINK_camframe_terminate)(void);
Sravankb4f5f1c2010-01-21 11:06:17 +0530100//for 720p
101// Function to add a video buffer to free Q
102void (*LINK_camframe_free_video)(struct msm_frame *frame);
103// Function pointer , called by camframe when a video frame is available.
104void (**LINK_camframe_video_callback)(struct msm_frame * frame);
105// To flush free Q in cam frame.
106void (*LINK_cam_frame_flush_free_video)(void);
107
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800108int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
109int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
110int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
Mohan Kandra02486042010-06-18 16:49:43 -0700111int8_t (*LINK_jpeg_encoder_get_buffer_offset)(uint32_t width, uint32_t height,
112 uint32_t* p_y_offset,
113 uint32_t* p_cbcr_offset,
114 uint32_t* p_buf_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800115int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
116const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
117int (*LINK_launch_cam_conf_thread)(void);
118int (*LINK_release_cam_conf_thread)(void);
Nishant Pandit741742b2010-09-21 03:24:20 +0530119mm_camera_status_t (*LINK_mm_camera_config_init)(mm_camera_config *);
120mm_camera_status_t (*LINK_mm_camera_config_deinit)(mm_camera_config *);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800121int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
122 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
123
124// callbacks
125void (**LINK_mmcamera_camframe_callback)(struct msm_frame *frame);
Nishant Pandit741742b2010-09-21 03:24:20 +0530126void (**LINK_mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800127void (**LINK_mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
128 uint32_t buff_size);
129void (**LINK_mmcamera_jpeg_callback)(jpeg_event_t status);
130void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800131void (**LINK_camframe_timeout_callback)(void);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530132void (**LINK_mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
133void (**LINK_cancel_liveshot)(void);
134int8_t (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data,
135 int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800136#else
137#define LINK_cam_conf cam_conf
138#define LINK_cam_frame cam_frame
139#define LINK_jpeg_encoder_init jpeg_encoder_init
140#define LINK_jpeg_encoder_join jpeg_encoder_join
141#define LINK_jpeg_encoder_encode jpeg_encoder_encode
142#define LINK_camframe_terminate camframe_terminate
143#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
144#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
145#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
Mohan Kandra02486042010-06-18 16:49:43 -0700146#define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800147#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
148#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
149#define LINK_launch_cam_conf_thread launch_cam_conf_thread
150#define LINK_release_cam_conf_thread release_cam_conf_thread
151#define LINK_zoom_crop_upscale zoom_crop_upscale
Nishant Pandit741742b2010-09-21 03:24:20 +0530152#define LINK_mm_camera_config_init mm_camera_config_init
153#define LINK_mm_camera_config_deinit mm_camera_config_deinit
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800154extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
Nishant Pandit741742b2010-09-21 03:24:20 +0530155extern void (*mmcamera_camstats_callback)(camstats_type stype, camera_preview_histogram_info* histinfo);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800156extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
157 uint32_t buff_size);
158extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
159extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530160extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
161#define LINK_set_liveshot_params set_liveshot_params
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800162#endif
163
164} // extern "C"
165
166#ifndef HAVE_CAMERA_SIZE_TYPE
167struct camera_size_type {
168 int width;
169 int height;
170};
171#endif
172
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800173typedef struct crop_info_struct {
174 uint32_t x;
175 uint32_t y;
176 uint32_t w;
177 uint32_t h;
178} zoom_crop_info;
179
Mohan Kandra740cfce2010-01-07 12:58:24 -0800180union zoomimage
Mohan Kandra284966d2010-01-05 13:39:15 -0800181{
182 char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
183 struct mdp_blit_req_list list;
184} zoomImage;
185
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800186//Default to WVGA
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800187#define DEFAULT_PREVIEW_WIDTH 800
188#define DEFAULT_PREVIEW_HEIGHT 480
189
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700190//Default FPS
191#define MINIMUM_FPS 5
192#define MAXIMUM_FPS 30
193#define DEFAULT_FPS MAXIMUM_FPS
194
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800195/*
196 * Modifying preview size requires modification
197 * in bitmasks for boardproperties
198 */
199
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800200static const camera_size_type preview_sizes[] = {
Nishant Pandit2f7681e2010-08-18 02:44:54 +0530201 { 1920, 1088 }, //1080p
Srinivasan Kannanfa7edae2009-12-16 18:02:01 -0800202 { 1280, 720 }, // 720P, reserved
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800203 { 800, 480 }, // WVGA
Srinivasan Kannan613301c2010-02-10 17:08:53 -0800204 { 768, 432 },
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800205 { 720, 480 },
206 { 640, 480 }, // VGA
207 { 576, 432 },
208 { 480, 320 }, // HVGA
209 { 384, 288 },
210 { 352, 288 }, // CIF
211 { 320, 240 }, // QVGA
212 { 240, 160 }, // SQVGA
213 { 176, 144 }, // QCIF
214};
215#define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(camera_size_type))
216
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800217static camera_size_type supportedPreviewSizes[PREVIEW_SIZE_COUNT];
218static unsigned int previewSizeCount;
219
220board_property boardProperties[] = {
Apurva Rajgurue5965c42010-09-09 14:24:54 -0700221 {TARGET_MSM7625, 0x00000fff, false, false},
222 {TARGET_MSM7627, 0x000006ff, false, false},
223 {TARGET_MSM7630, 0x00000fff, true, true},
224 {TARGET_MSM8660, 0x00001fff, true, true},
225 {TARGET_QSD8250, 0x00000fff, false, false}
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800226};
227
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800228//static const camera_size_type* picture_sizes;
229//static int PICTURE_SIZE_COUNT;
230/* TODO
231 * Ideally this should be a populated by lower layers.
232 * But currently this is no API to do that at lower layer.
233 * Hence populating with default sizes for now. This needs
234 * to be changed once the API is supported.
235 */
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800236//sorted on column basis
Nishant Pandit741742b2010-09-21 03:24:20 +0530237static camera_size_type* picture_sizes;
238static unsigned int PICTURE_SIZE_COUNT;
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800239static const camera_size_type * picture_sizes_ptr;
240static int supportedPictureSizesCount;
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530241static liveshotState liveshot_state = LIVESHOT_DONE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800242
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800243#ifdef Q12
244#undef Q12
245#endif
246
247#define Q12 4096
248
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800249static const target_map targetList [] = {
250 { "msm7625", TARGET_MSM7625 },
251 { "msm7627", TARGET_MSM7627 },
252 { "qsd8250", TARGET_QSD8250 },
Nishant Pandit3c278cd2010-07-13 15:56:04 +0530253 { "msm7630", TARGET_MSM7630 },
254 { "msm8660", TARGET_MSM8660 }
255
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800256};
257static targetType mCurrentTarget = TARGET_MAX;
258
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800259typedef struct {
260 uint32_t aspect_ratio;
261 uint32_t width;
262 uint32_t height;
263} thumbnail_size_type;
264
265static thumbnail_size_type thumbnail_sizes[] = {
266 { 7281, 512, 288 }, //1.777778
267 { 6826, 480, 288 }, //1.666667
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
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800325
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800326namespace android {
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800327
328static const int PICTURE_FORMAT_JPEG = 1;
329static const int PICTURE_FORMAT_RAW = 2;
330
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800331// from aeecamera.h
332static const str_map whitebalance[] = {
333 { CameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
334 { CameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
335 { CameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
336 { CameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
337 { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
338};
339
340// from camera_effect_t. This list must match aeecamera.h
341static const str_map effects[] = {
342 { CameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
343 { CameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
344 { CameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
345 { CameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
346 { CameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
347 { CameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
348 { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
349 { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
350 { CameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA }
351};
352
353// from qcamera/common/camera.h
Apurva Rajguru55562b02009-12-03 12:25:35 -0800354static const str_map autoexposure[] = {
355 { CameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
356 { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
357 { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
358};
359
360// from qcamera/common/camera.h
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800361static const str_map antibanding[] = {
362 { CameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
363 { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
364 { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
365 { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
366};
367
368/* Mapping from MCC to antibanding type */
369struct country_map {
370 uint32_t country_code;
371 camera_antibanding_type type;
372};
373
374static struct country_map country_numeric[] = {
375 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
376 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
377 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
378 { 208, CAMERA_ANTIBANDING_50HZ }, // France
379 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
380 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
381 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
382 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
383 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
384 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
385 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
386 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
387 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
388 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
389 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
390 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
391 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
392 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
393 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
394 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
395 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
396 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
397 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
398 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
399 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
400 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
401 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
402 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
403 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
404 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
405 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
406 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
407 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
408 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
409 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
410 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
411 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
412 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
413 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
414 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
415 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
416 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
417 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
418 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
419 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
420 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
421 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
422 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
423 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
424 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
425 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
426 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
427 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
428 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
429 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
430 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
431 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
432 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
433 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
434 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
435 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
436 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
437 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
438 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
439 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
440 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
441 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
442 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
443 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
444 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
445 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
446 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
447 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
448 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
449 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
450 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
451 { 404, CAMERA_ANTIBANDING_50HZ }, // India
452 { 405, CAMERA_ANTIBANDING_50HZ }, // India
453 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
454 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
455 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
456 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
457 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
458 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
459 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
460 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
461 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
462 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
463 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
464 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
465 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
466 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
467 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
468 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
469 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
470 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
471 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
472 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
473 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
474 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
475 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
476 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
477 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
478 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
479 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
480 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
481 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
482 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
483 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
484 { 460, CAMERA_ANTIBANDING_50HZ }, // China
485 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
486 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
487 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
488 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
489 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
490 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
491 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
492 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
493 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
494 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
495 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
496 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
497 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
498 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
499 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
500 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
501 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
502 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
503 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
504 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
505 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
506 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
507 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
508 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
509 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
510 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
511 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
512 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
513 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
514 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
515 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
516 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
517 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
518 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
519 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
520 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
521 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
522 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
523 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
524 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
525 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
526 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
527 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
528 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
529 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
530 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
531 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
532 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
533 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
534 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
535 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
536 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
537 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
538 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
539 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
540 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
541 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
542 { 647, CAMERA_ANTIBANDING_50HZ }, // France
543 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
544 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
545 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
546 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
547 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
548 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
549 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
550 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
551 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
552 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
553 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
554 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
555 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
556 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
557 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
558 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
559 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
560 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
561 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
562 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
563 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
564 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
565 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
566 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
567 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
568 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
569 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
570 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
571 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
572};
573
Apurva Rajguru08383852010-05-17 14:25:39 -0700574static const str_map scenemode[] = {
575 { CameraParameters::SCENE_MODE_AUTO, CAMERA_BESTSHOT_OFF },
576 { CameraParameters::SCENE_MODE_ACTION, CAMERA_BESTSHOT_ACTION },
577 { CameraParameters::SCENE_MODE_PORTRAIT, CAMERA_BESTSHOT_PORTRAIT },
578 { CameraParameters::SCENE_MODE_LANDSCAPE, CAMERA_BESTSHOT_LANDSCAPE },
579 { CameraParameters::SCENE_MODE_NIGHT, CAMERA_BESTSHOT_NIGHT },
580 { CameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
581 { CameraParameters::SCENE_MODE_THEATRE, CAMERA_BESTSHOT_THEATRE },
582 { CameraParameters::SCENE_MODE_BEACH, CAMERA_BESTSHOT_BEACH },
583 { CameraParameters::SCENE_MODE_SNOW, CAMERA_BESTSHOT_SNOW },
584 { CameraParameters::SCENE_MODE_SUNSET, CAMERA_BESTSHOT_SUNSET },
585 { CameraParameters::SCENE_MODE_STEADYPHOTO, CAMERA_BESTSHOT_ANTISHAKE },
586 { CameraParameters::SCENE_MODE_FIREWORKS , CAMERA_BESTSHOT_FIREWORKS },
587 { CameraParameters::SCENE_MODE_SPORTS , CAMERA_BESTSHOT_SPORTS },
588 { CameraParameters::SCENE_MODE_PARTY, CAMERA_BESTSHOT_PARTY },
589 { CameraParameters::SCENE_MODE_CANDLELIGHT, CAMERA_BESTSHOT_CANDLELIGHT },
590 { CameraParameters::SCENE_MODE_BACKLIGHT, CAMERA_BESTSHOT_BACKLIGHT },
591 { CameraParameters::SCENE_MODE_FLOWERS, CAMERA_BESTSHOT_FLOWERS },
592};
593
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700594static const str_map scenedetect[] = {
595 { CameraParameters::SCENE_DETECT_OFF, FALSE },
596 { CameraParameters::SCENE_DETECT_ON, TRUE },
597};
598
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800599#define country_number (sizeof(country_numeric) / sizeof(country_map))
Srinivasan Kannan264376e2010-08-13 18:54:35 -0700600/* TODO : setting dummy values as of now, need to query for correct
601 * values from sensor in future
602 */
603#define CAMERA_FOCAL_LENGTH_DEFAULT 4.31
604#define CAMERA_HORIZONTAL_VIEW_ANGLE_DEFAULT 54.8
605#define CAMERA_VERTICAL_VIEW_ANGLE_DEFAULT 42.5
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800606
607/* Look up pre-sorted antibanding_type table by current MCC. */
608static camera_antibanding_type camera_get_location(void) {
609 char value[PROP_VALUE_MAX];
610 char country_value[PROP_VALUE_MAX];
611 uint32_t country_code, count;
612 memset(value, 0x00, sizeof(value));
613 memset(country_value, 0x00, sizeof(country_value));
614 if (!__system_property_get("gsm.operator.numeric", value)) {
615 return CAMERA_ANTIBANDING_60HZ;
616 }
617 memcpy(country_value, value, 3);
618 country_code = atoi(country_value);
619 LOGD("value:%s, country value:%s, country code:%d\n",
620 value, country_value, country_code);
621 int left = 0;
622 int right = country_number - 1;
623 while (left <= right) {
624 int index = (left + right) >> 1;
625 if (country_numeric[index].country_code == country_code)
626 return country_numeric[index].type;
627 else if (country_numeric[index].country_code > country_code)
628 right = index - 1;
629 else
630 left = index + 1;
631 }
632 return CAMERA_ANTIBANDING_60HZ;
633}
634
635// from camera.h, led_mode_t
636static const str_map flash[] = {
637 { CameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
638 { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
Srinivasan Kannanda9a7052010-07-09 10:12:31 -0700639 { CameraParameters::FLASH_MODE_ON, LED_MODE_ON },
640 { CameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800641};
642
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530643// from mm-camera/common/camera.h.
644static const str_map iso[] = {
645 { CameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
646 { CameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
647 { CameraParameters::ISO_100, CAMERA_ISO_100},
648 { CameraParameters::ISO_200, CAMERA_ISO_200},
649 { CameraParameters::ISO_400, CAMERA_ISO_400},
Mohan Kandra61db0d02010-04-28 18:28:30 -0700650 { CameraParameters::ISO_800, CAMERA_ISO_800 },
651 { CameraParameters::ISO_1600, CAMERA_ISO_1600 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530652};
653
654
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800655#define DONT_CARE 0
656static const str_map focus_modes[] = {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800657 { CameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
658 { CameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
659 { CameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL },
660 { CameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800661};
662
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530663static const str_map lensshade[] = {
664 { CameraParameters::LENSSHADE_ENABLE, TRUE },
665 { CameraParameters::LENSSHADE_DISABLE, FALSE }
666};
667
Nishant Pandit741742b2010-09-21 03:24:20 +0530668static const str_map histogram[] = {
669 { CameraParameters::HISTOGRAM_ENABLE, TRUE },
670 { CameraParameters::HISTOGRAM_DISABLE, FALSE }
671};
672
Apurva Rajguru7b949c92010-05-26 15:46:57 -0700673static const str_map continuous_af[] = {
674 { CameraParameters::CONTINUOUS_AF_OFF, FALSE },
675 { CameraParameters::CONTINUOUS_AF_ON, TRUE }
676};
677
Apurva Rajgurue5965c42010-09-09 14:24:54 -0700678static const str_map selectable_zone_af[] = {
679 { CameraParameters::SELECTABLE_ZONE_AF_AUTO, AUTO },
680 { CameraParameters::SELECTABLE_ZONE_AF_SPOT_METERING, SPOT },
681 { CameraParameters::SELECTABLE_ZONE_AF_CENTER_WEIGHTED, CENTER_WEIGHTED },
682 { CameraParameters::SELECTABLE_ZONE_AF_FRAME_AVERAGE, AVERAGE }
683};
684
Apurva Rajguru0a2cb922010-06-08 15:33:22 -0700685#define DONT_CARE_COORDINATE -1
686static const str_map touchafaec[] = {
687 { CameraParameters::TOUCH_AF_AEC_OFF, FALSE },
688 { CameraParameters::TOUCH_AF_AEC_ON, TRUE }
689};
690
Srinivasan Kannan71229622009-12-04 12:05:58 -0800691struct SensorType {
692 const char *name;
693 int rawPictureWidth;
694 int rawPictureHeight;
695 bool hasAutoFocusSupport;
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800696 int max_supported_snapshot_width;
697 int max_supported_snapshot_height;
Apurva Rajguruffe264a2010-03-09 13:50:53 -0800698 int bitMask;
Srinivasan Kannan71229622009-12-04 12:05:58 -0800699};
700
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -0700701
702/*
703 * Values based on aec.c
704 */
705
Nishant Pandit741742b2010-09-21 03:24:20 +0530706#define CAMERA_HISTOGRAM_ENABLE 1
707#define CAMERA_HISTOGRAM_DISABLE 0
708#define HISTOGRAM_STATS_SIZE 257
709
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -0700710#define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
711#define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
712#define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
713#define EXPOSURE_COMPENSATION_DENOMINATOR 6
714#define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
715
Srinivasan Kannan71229622009-12-04 12:05:58 -0800716static SensorType sensorTypes[] = {
Priyanka Kharat0fa7f9f2010-08-30 19:00:35 -0700717 { "12mp", 5464, 3120, true, 4000, 3000,0x00001fff },
Yen-Pin Hsiaoa6612f12010-07-19 15:17:21 -0700718 { "12mp_sn12m0pz",4032, 3024, true, 4000, 3000,0x00000fff },
Apurva Rajguruffe264a2010-03-09 13:50:53 -0800719 { "5mp", 2608, 1960, true, 2592, 1944,0x00000fff },
720 { "3mp", 2064, 1544, false, 2048, 1536,0x000007ff },
721 { "2mp", 3200, 1200, false, 1600, 1200,0x000007ff } };
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800722
Srinivasan Kannan71229622009-12-04 12:05:58 -0800723
724static SensorType * sensorType;
725
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800726static const str_map picture_formats[] = {
727 {CameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
728 {CameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
729};
730
Mohan Kandrabf6146d2010-07-20 18:48:37 -0700731static const str_map frame_rate_modes[] = {
732 {CameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
733 {CameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
734};
735
Mohan Kandra7110c242010-07-18 15:34:48 -0700736static int mPreviewFormat;
737static const str_map preview_formats[] = {
738 {CameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21},
739 {CameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO}
740};
741
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800742static bool parameter_string_initialized = false;
743static String8 preview_size_values;
744static String8 picture_size_values;
Srinivasan Kannan264376e2010-08-13 18:54:35 -0700745static String8 jpeg_thumbnail_size_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800746static String8 antibanding_values;
747static String8 effect_values;
Apurva Rajguru55562b02009-12-03 12:25:35 -0800748static String8 autoexposure_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800749static String8 whitebalance_values;
750static String8 flash_values;
751static String8 focus_mode_values;
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530752static String8 iso_values;
753static String8 lensshade_values;
Nishant Pandit741742b2010-09-21 03:24:20 +0530754static String8 histogram_values;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -0700755static String8 touchafaec_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800756static String8 picture_format_values;
Apurva Rajguru08383852010-05-17 14:25:39 -0700757static String8 scenemode_values;
Apurva Rajguru7b949c92010-05-26 15:46:57 -0700758static String8 continuous_af_values;
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700759static String8 zoom_ratio_values;
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700760static String8 preview_frame_rate_values;
Mohan Kandrabf6146d2010-07-20 18:48:37 -0700761static String8 frame_rate_mode_values;
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700762static String8 scenedetect_values;
Mohan Kandra7110c242010-07-18 15:34:48 -0700763static String8 preview_format_values;
Apurva Rajgurue5965c42010-09-09 14:24:54 -0700764static String8 selectable_zone_af_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800765
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800766static String8 create_sizes_str(const camera_size_type *sizes, int len) {
767 String8 str;
768 char buffer[32];
769
770 if (len > 0) {
771 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
772 str.append(buffer);
773 }
774 for (int i = 1; i < len; i++) {
775 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
776 str.append(buffer);
777 }
778 return str;
779}
780
781static String8 create_values_str(const str_map *values, int len) {
782 String8 str;
783
784 if (len > 0) {
785 str.append(values[0].desc);
786 }
787 for (int i = 1; i < len; i++) {
788 str.append(",");
789 str.append(values[i].desc);
790 }
791 return str;
792}
793
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700794
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700795static String8 create_str(int16_t *arr, int length){
796 String8 str;
797 char buffer[32];
798
799 if(length > 0){
800 snprintf(buffer, sizeof(buffer), "%d", arr[0]);
801 str.append(buffer);
802 }
803
804 for (int i =1;i<length;i++){
805 snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
806 str.append(buffer);
807 }
808 return str;
809}
810
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700811static String8 create_values_range_str(int min, int max){
812 String8 str;
813 char buffer[32];
814
815 if(min <= max){
816 snprintf(buffer, sizeof(buffer), "%d", min);
817 str.append(buffer);
818
819 for (int i = min + 1; i <= max; i++) {
820 snprintf(buffer, sizeof(buffer), ",%d", i);
821 str.append(buffer);
822 }
823 }
824 return str;
825}
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700826
Sravankb4f5f1c2010-01-21 11:06:17 +0530827extern "C" {
828//------------------------------------------------------------------------
829// : 720p busyQ funcitons
830// --------------------------------------------------------------------
831static struct fifo_queue g_busy_frame_queue =
832 {0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
833};
834/*===========================================================================
835 * FUNCTION cam_frame_wait_video
836 *
837 * DESCRIPTION this function waits a video in the busy queue
838 * ===========================================================================*/
839
840static void cam_frame_wait_video (void)
841{
842 LOGV("cam_frame_wait_video E ");
843 if ((g_busy_frame_queue.num_of_frames) <=0){
844 pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut));
845 }
846 LOGV("cam_frame_wait_video X");
847 return;
848}
849
850/*===========================================================================
851 * FUNCTION cam_frame_flush_video
852 *
853 * DESCRIPTION this function deletes all the buffers in busy queue
854 * ===========================================================================*/
855void cam_frame_flush_video (void)
856{
857 LOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames);
858 pthread_mutex_lock(&(g_busy_frame_queue.mut));
859
860 while (g_busy_frame_queue.front)
861 {
862 //dequeue from the busy queue
863 struct fifo_node *node = dequeue (&g_busy_frame_queue);
864 if(node)
865 free(node);
866
867 LOGV("cam_frame_flush_video: node \n");
868 }
869 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
870 LOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames);
871 return ;
872}
873/*===========================================================================
874 * FUNCTION cam_frame_get_video
875 *
876 * DESCRIPTION this function returns a video frame from the head
877 * ===========================================================================*/
878static struct msm_frame * cam_frame_get_video()
879{
880 struct msm_frame *p = NULL;
881 LOGV("cam_frame_get_video... in\n");
882 LOGV("cam_frame_get_video... got lock\n");
883 if (g_busy_frame_queue.front)
884 {
885 //dequeue
886 struct fifo_node *node = dequeue (&g_busy_frame_queue);
887 if (node)
888 {
889 p = (struct msm_frame *)node->f;
890 free (node);
891 }
892 LOGV("cam_frame_get_video... out = %x\n", p->buffer);
893 }
894 return p;
895}
896
897/*===========================================================================
898 * FUNCTION cam_frame_post_video
899 *
900 * DESCRIPTION this function add a busy video frame to the busy queue tails
901 * ===========================================================================*/
902static void cam_frame_post_video (struct msm_frame *p)
903{
904 if (!p)
905 {
906 LOGE("post video , buffer is null");
907 return;
908 }
909 LOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer));
910 pthread_mutex_lock(&(g_busy_frame_queue.mut));
911 LOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames);
912 //enqueue to busy queue
913 struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node));
914 if (node)
915 {
916 LOGV(" post video , enqueing in busy queue");
917 node->f = p;
918 node->next = NULL;
919 enqueue (&g_busy_frame_queue, node);
920 LOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames);
921 }
922 else
923 {
924 LOGE("cam_frame_post_video error... out of memory\n");
925 }
926
927 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
928 pthread_cond_signal(&(g_busy_frame_queue.wait));
929
930 LOGV("cam_frame_post_video... out = %x\n", p->buffer);
931
932 return;
933}
934
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800935void QualcommCameraHardware::storeTargetType(void) {
936 char mDeviceName[PROPERTY_VALUE_MAX];
937 property_get("ro.product.device",mDeviceName," ");
938 mCurrentTarget = TARGET_MAX;
939 for( int i = 0; i < TARGET_MAX ; i++) {
940 if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) {
941 mCurrentTarget = targetList[i].targetEnum;
942 break;
943 }
944 }
945 LOGV(" Storing the current target type as %d ", mCurrentTarget );
946 return;
947}
948
Sravankb4f5f1c2010-01-21 11:06:17 +0530949//-------------------------------------------------------------------------------------
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800950static Mutex singleton_lock;
951static bool singleton_releasing;
Srinivasan Kannan78444e42010-06-10 15:39:29 -0700952static nsecs_t singleton_releasing_start_time;
953static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5);
954static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800955static Condition singleton_wait;
956
957static void receive_camframe_callback(struct msm_frame *frame);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530958static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size);
Nishant Pandit741742b2010-09-21 03:24:20 +0530959static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo);
Sravankb4f5f1c2010-01-21 11:06:17 +0530960static void receive_camframe_video_callback(struct msm_frame *frame); // 720p
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800961static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size);
962static void receive_jpeg_callback(jpeg_event_t status);
963static void receive_shutter_callback(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800964static void receive_camframetimeout_callback(void);
Mohan Kandra284966d2010-01-05 13:39:15 -0800965static int fb_fd = -1;
966static int32_t mMaxZoom = 0;
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700967static bool zoomSupported = false;
Mohan Kandra284966d2010-01-05 13:39:15 -0800968static bool native_get_maxzoom(int camfd, void *pZm);
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700969static bool native_get_zoomratios(int camfd, void *pZr, int maxZoomLevel);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800970
Mohan Kandrad9efed92010-01-15 19:08:39 -0800971static int dstOffset = 0;
972
Brian Steuer07704892009-12-18 18:07:33 -0800973static int camerafd;
974pthread_t w_thread;
975
976void *opencamerafd(void *data) {
977 camerafd = open(MSM_CAMERA_CONTROL, O_RDWR);
978 return NULL;
979}
980
Mohan Kandrad9efed92010-01-15 19:08:39 -0800981/* When using MDP zoom, double the preview buffers. The usage of these
982 * buffers is as follows:
983 * 1. As all the buffers comes under a single FD, and at initial registration,
984 * this FD will be passed to surface flinger, surface flinger can have access
985 * to all the buffers when needed.
986 * 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the
987 * camera driver to receive preview frames. The remaining buffers (DstSet),
988 * will be used at HAL and by surface flinger only when crop information
989 * is present in the frame.
990 * 3. When there is no crop information, there will be no call to MDP zoom,
991 * and the buffers in SrcSet will be passed to surface flinger to display.
992 * 4. With crop information present, MDP zoom will be called, and the final
993 * data will be placed in a buffer from DstSet, and this buffer will be given
994 * to surface flinger to display.
995 */
996#define NUM_MORE_BUFS 2
997
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800998QualcommCameraHardware::QualcommCameraHardware()
999 : mParameters(),
1000 mCameraRunning(false),
1001 mPreviewInitialized(false),
1002 mFrameThreadRunning(false),
Mohan Kandra156d0ac2010-01-25 16:59:17 -08001003 mVideoThreadRunning(false),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001004 mSnapshotThreadRunning(false),
Mohan Kandra1659b0c2010-07-18 16:36:25 -07001005 mEncodePending(false),
Mohan Kandraca2e7a92010-06-21 15:48:45 -07001006 mJpegThreadRunning(false),
Mohan Kandra62429cc2010-07-19 10:21:05 -07001007 mInSnapshotMode(false),
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001008 mSnapshotFormat(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001009 mReleasedRecordingFrame(false),
1010 mPreviewFrameSize(0),
1011 mRawSize(0),
Mohan Kandra1659b0c2010-07-18 16:36:25 -07001012 mCbCrOffsetRaw(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001013 mCameraControlFd(-1),
1014 mAutoFocusThreadRunning(false),
1015 mAutoFocusFd(-1),
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001016 mBrightness(0),
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07001017 mHJR(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001018 mInPreviewCallback(false),
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001019 mUseOverlay(0),
1020 mOverlay(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001021 mMsgEnabled(0),
1022 mNotifyCallback(0),
1023 mDataCallback(0),
1024 mDataCallbackTimestamp(0),
Mohan Kandra740cfce2010-01-07 12:58:24 -08001025 mCallbackCookie(0),
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001026 mInitialized(false),
Apurva Rajguru3da1a702010-07-28 12:32:42 -07001027 mDebugFps(0),
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001028 mSnapshotDone(0),
1029 mDisEnabled(0),
Mohan Kandra9aff1f42010-09-02 19:00:41 -07001030 mRotation(0),
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07001031 mResetOverlayCrop(false),
1032 mThumbnailWidth(0),
1033 mThumbnailHeight(0)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001034{
Mohan Kandra0d115d12010-08-19 11:47:15 -07001035 LOGI("QualcommCameraHardware constructor E");
Brian Steuer07704892009-12-18 18:07:33 -08001036 // Start opening camera device in a separate thread/ Since this
1037 // initializes the sensor hardware, this can take a long time. So,
1038 // start the process here so it will be ready by the time it's
1039 // needed.
1040 if ((pthread_create(&w_thread, NULL, opencamerafd, NULL)) != 0) {
1041 LOGE("Camera open thread creation failed");
1042 }
1043
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001044 memset(&mDimension, 0, sizeof(mDimension));
1045 memset(&mCrop, 0, sizeof(mCrop));
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001046 memset(&zoomCropInfo, 0, sizeof(zoom_crop_info));
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08001047 storeTargetType();
Mohan Kandra740cfce2010-01-07 12:58:24 -08001048 char value[PROPERTY_VALUE_MAX];
1049 property_get("persist.debug.sf.showfps", value, "0");
1050 mDebugFps = atoi(value);
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301051 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) {
Sravankb4f5f1c2010-01-21 11:06:17 +05301052 kPreviewBufferCountActual = kPreviewBufferCount;
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301053 kRecordBufferCount = RECORD_BUFFERS;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001054 recordframes = new msm_frame[kRecordBufferCount];
Mohan Kandra1fd90f92010-06-17 14:54:17 -07001055 record_buffers_tracking_flag = new bool[kRecordBufferCount];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001056 }
1057 else {
Sravankb4f5f1c2010-01-21 11:06:17 +05301058 kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001059 if( mCurrentTarget == TARGET_QSD8250 ) {
1060 kRecordBufferCount = RECORD_BUFFERS_8x50;
1061 recordframes = new msm_frame[kRecordBufferCount];
Mohan Kandra1fd90f92010-06-17 14:54:17 -07001062 record_buffers_tracking_flag = new bool[kRecordBufferCount];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001063 }
1064 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001065
1066 switch(mCurrentTarget){
1067 case TARGET_MSM7627:
1068 jpegPadding = 8;
1069 break;
1070 case TARGET_QSD8250:
1071 case TARGET_MSM7630:
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301072 case TARGET_MSM8660:
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001073 jpegPadding = 0;
1074 break;
1075 default:
1076 jpegPadding = 0;
1077 break;
1078 }
Mohan Kandra7110c242010-07-18 15:34:48 -07001079 // Initialize with default format values. The format values can be
1080 // overriden when application requests.
1081 mDimension.prev_format = CAMERA_YUV_420_NV21;
1082 mPreviewFormat = CAMERA_YUV_420_NV21;
1083 mDimension.enc_format = CAMERA_YUV_420_NV21;
Mohan Kandra88db27a2010-08-22 12:33:36 -07001084 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
Mohan Kandra7110c242010-07-18 15:34:48 -07001085 mDimension.enc_format = CAMERA_YUV_420_NV12;
1086
1087 mDimension.main_img_format = CAMERA_YUV_420_NV21;
1088 mDimension.thumb_format = CAMERA_YUV_420_NV21;
1089
Mohan Kandrafdbc2192010-08-24 20:39:59 -07001090 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001091 /* DIS is enabled all the time in VPE support targets.
1092 * No provision for the user to control this.
1093 */
1094 mDisEnabled = 1;
Mohan Kandraec958742010-08-19 10:56:05 -07001095 /* Get the DIS value from properties, to check whether
1096 * DIS is disabled or not
1097 */
1098 property_get("persist.camera.hal.dis", value, "1");
1099 mDisEnabled = atoi(value);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001100 mVpeEnabled = 1;
1101 }
1102
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001103 LOGV("constructor EX");
1104}
1105
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001106void QualcommCameraHardware::filterPreviewSizes(){
1107
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001108 unsigned int boardMask = 0;
Mohan Kandra62429cc2010-07-19 10:21:05 -07001109 unsigned int prop = 0;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001110 for(prop=0;prop<sizeof(boardProperties)/sizeof(board_property);prop++){
1111 if(mCurrentTarget == boardProperties[prop].target){
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001112 boardMask = boardProperties[prop].previewSizeMask;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001113 break;
1114 }
1115 }
1116
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001117 int bitMask = boardMask & sensorType->bitMask;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001118 if(bitMask){
1119 unsigned int mask = 1<<(PREVIEW_SIZE_COUNT-1);
1120 previewSizeCount=0;
1121 unsigned int i = 0;
1122 while(mask){
1123 if(mask&bitMask)
1124 supportedPreviewSizes[previewSizeCount++] =
1125 preview_sizes[i];
1126 i++;
1127 mask = mask >> 1;
1128 }
1129 }
1130}
1131
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001132//filter Picture sizes based on max width and height
1133void QualcommCameraHardware::filterPictureSizes(){
1134 int i;
1135 for(i=0;i<PICTURE_SIZE_COUNT;i++){
1136 if(((picture_sizes[i].width <=
1137 sensorType->max_supported_snapshot_width) &&
1138 (picture_sizes[i].height <=
1139 sensorType->max_supported_snapshot_height))){
1140 picture_sizes_ptr = picture_sizes + i;
1141 supportedPictureSizesCount = PICTURE_SIZE_COUNT - i ;
1142 return ;
1143 }
1144 }
1145}
1146
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001147bool QualcommCameraHardware::supportsSceneDetection() {
1148 int prop = 0;
1149 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
1150 if((mCurrentTarget == boardProperties[prop].target)
1151 && boardProperties[prop].hasSceneDetect == true) {
1152 return true;
1153 break;
1154 }
1155 }
1156 return false;
1157}
1158
Apurva Rajgurue5965c42010-09-09 14:24:54 -07001159bool QualcommCameraHardware::supportsSelectableZoneAf() {
1160 int prop = 0;
1161 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
1162 if((mCurrentTarget == boardProperties[prop].target)
1163 && boardProperties[prop].hasSelectableZoneAf == true) {
1164 return true;
1165 break;
1166 }
1167 }
1168 return false;
1169}
1170
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001171void QualcommCameraHardware::initDefaultParameters()
1172{
Mohan Kandra0d115d12010-08-19 11:47:15 -07001173 LOGI("initDefaultParameters E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001174
Apurva Rajguru59ec7122010-08-25 13:03:30 -07001175 findSensorType();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001176 // Initialize constant parameter strings. This will happen only once in the
1177 // lifetime of the mediaserver process.
1178 if (!parameter_string_initialized) {
1179 antibanding_values = create_values_str(
1180 antibanding, sizeof(antibanding) / sizeof(str_map));
1181 effect_values = create_values_str(
1182 effects, sizeof(effects) / sizeof(str_map));
Apurva Rajguru55562b02009-12-03 12:25:35 -08001183 autoexposure_values = create_values_str(
1184 autoexposure, sizeof(autoexposure) / sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001185 whitebalance_values = create_values_str(
1186 whitebalance, sizeof(whitebalance) / sizeof(str_map));
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001187
1188 //filter preview sizes
1189 filterPreviewSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001190 preview_size_values = create_sizes_str(
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001191 supportedPreviewSizes, previewSizeCount);
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001192 //filter picture sizes
1193 filterPictureSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001194 picture_size_values = create_sizes_str(
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001195 picture_sizes_ptr, supportedPictureSizesCount);
1196
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001197 flash_values = create_values_str(
1198 flash, sizeof(flash) / sizeof(str_map));
Srinivasan Kannan71229622009-12-04 12:05:58 -08001199 if(sensorType->hasAutoFocusSupport){
1200 focus_mode_values = create_values_str(
1201 focus_modes, sizeof(focus_modes) / sizeof(str_map));
1202 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301203 iso_values = create_values_str(
1204 iso,sizeof(iso)/sizeof(str_map));
1205 lensshade_values = create_values_str(
1206 lensshade,sizeof(lensshade)/sizeof(str_map));
Nishant Pandit741742b2010-09-21 03:24:20 +05301207 //Currently Enabling Histogram for 8x60
1208 if(mCurrentTarget == TARGET_MSM8660) {
1209 histogram_values = create_values_str(
1210 histogram,sizeof(histogram)/sizeof(str_map));
1211 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07001212 if(sensorType->hasAutoFocusSupport){
1213 touchafaec_values = create_values_str(
1214 touchafaec,sizeof(touchafaec)/sizeof(str_map));
1215 }
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001216
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001217 picture_format_values = create_values_str(
1218 picture_formats, sizeof(picture_formats)/sizeof(str_map));
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001219
1220 if(sensorType->hasAutoFocusSupport){
1221 continuous_af_values = create_values_str(
1222 continuous_af, sizeof(continuous_af) / sizeof(str_map));
1223 }
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001224
1225 if(native_get_maxzoom(mCameraControlFd,
1226 (void *)&mMaxZoom) == true){
1227 LOGD("Maximum zoom value is %d", mMaxZoom);
1228 zoomSupported = true;
1229 if(mMaxZoom > 0){
1230 //if max zoom is available find the zoom ratios
1231 int16_t * zoomRatios = new int16_t[mMaxZoom+1];
1232 if(zoomRatios != NULL){
1233 if(native_get_zoomratios(mCameraControlFd,
1234 (void *)zoomRatios, mMaxZoom + 1) == true){
1235 zoom_ratio_values =
1236 create_str(zoomRatios, mMaxZoom + 1);
1237 }else {
1238 LOGE("Failed to get zoomratios...");
1239 }
1240 delete zoomRatios;
1241 } else {
1242 LOGE("zoom ratios failed to acquire memory");
1243 }
1244 }
1245 } else {
1246 zoomSupported = false;
1247 LOGE("Failed to get maximum zoom value...setting max "
1248 "zoom to zero");
1249 mMaxZoom = 0;
1250 }
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001251 preview_frame_rate_values = create_values_range_str(
1252 MINIMUM_FPS, MAXIMUM_FPS);
Apurva Rajguru08383852010-05-17 14:25:39 -07001253
1254 scenemode_values = create_values_str(
1255 scenemode, sizeof(scenemode) / sizeof(str_map));
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001256
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001257 if(supportsSceneDetection()) {
1258 scenedetect_values = create_values_str(
1259 scenedetect, sizeof(scenedetect) / sizeof(str_map));
1260 }
1261
Apurva Rajgurue5965c42010-09-09 14:24:54 -07001262 if(sensorType->hasAutoFocusSupport && supportsSelectableZoneAf()){
1263 selectable_zone_af_values = create_values_str(
1264 selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map));
1265 }
1266
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001267 parameter_string_initialized = true;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001268 }
1269
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001270 mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
1271 mDimension.display_width = DEFAULT_PREVIEW_WIDTH;
1272 mDimension.display_height = DEFAULT_PREVIEW_HEIGHT;
1273
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001274 mParameters.setPreviewFrameRate(DEFAULT_FPS);
Mohan Kandraf7341b92010-09-21 12:00:50 -07001275 if(strcmp(sensorType->name, "2mp")){
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07001276 mParameters.set(
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001277 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
1278 preview_frame_rate_values.string());
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001279 } else {
1280 mParameters.set(
1281 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
1282 DEFAULT_FPS);
1283 }
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001284 mParameters.setPreviewFrameRateMode("frame-rate-auto");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001285 mParameters.setPreviewFormat("yuv420sp"); // informative
1286
1287 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
1288 mParameters.setPictureFormat("jpeg"); // informative
1289
Mohan Kandra785619a2010-02-01 21:52:42 -08001290 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001291 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
1292 THUMBNAIL_WIDTH_STR); // informative
1293 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
1294 THUMBNAIL_HEIGHT_STR); // informative
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08001295 mDimension.ui_thumbnail_width =
1296 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
1297 mDimension.ui_thumbnail_height =
1298 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001299 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
1300
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001301 String8 valuesStr = create_sizes_str(jpeg_thumbnail_sizes, JPEG_THUMBNAIL_SIZE_COUNT);
1302 mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
1303 valuesStr.string());
1304
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001305 if(zoomSupported){
1306 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true");
1307 LOGV("max zoom is %d", mMaxZoom);
1308 mParameters.set("max-zoom",mMaxZoom);
1309 mParameters.set(CameraParameters::KEY_ZOOM_RATIOS,
1310 zoom_ratio_values);
1311 } else {
1312 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "false");
1313 }
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001314 /* Enable zoom support for video application if VPE enabled */
1315 if(zoomSupported && mVpeEnabled) {
1316 mParameters.set("video-zoom-support", "true");
1317 } else {
1318 mParameters.set("video-zoom-support", "false");
1319 }
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001320
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001321 mParameters.set(CameraParameters::KEY_ANTIBANDING,
Mohan Kandra785619a2010-02-01 21:52:42 -08001322 CameraParameters::ANTIBANDING_OFF);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001323 mParameters.set(CameraParameters::KEY_EFFECT,
1324 CameraParameters::EFFECT_NONE);
Apurva Rajguru55562b02009-12-03 12:25:35 -08001325 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
1326 CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001327 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
1328 CameraParameters::WHITE_BALANCE_AUTO);
1329 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
1330 CameraParameters::FOCUS_MODE_AUTO);
Mohan Kandra7110c242010-07-18 15:34:48 -07001331 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_QSD8250) ) {
Priya Komarlingam044c7b52010-01-22 18:21:23 -08001332 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1333 "yuv420sp");
Mohan Kandra7110c242010-07-18 15:34:48 -07001334 }
1335 else {
1336 preview_format_values = create_values_str(
1337 preview_formats, sizeof(preview_formats) / sizeof(str_map));
1338 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1339 preview_format_values.string());
1340 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001341
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001342 frame_rate_mode_values = create_values_str(
1343 frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
Mohan Kandraf7341b92010-09-21 12:00:50 -07001344 if(strcmp(sensorType->name, "2mp")){
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001345 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
1346 frame_rate_mode_values.string());
1347 }
1348
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001349 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
1350 preview_size_values.string());
1351 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
1352 picture_size_values.string());
1353 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
1354 antibanding_values);
1355 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
Apurva Rajguru55562b02009-12-03 12:25:35 -08001356 mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001357 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
1358 whitebalance_values);
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001359 if((strcmp(mSensorInfo.name, "vx6953")) &&
1360 (strcmp(mSensorInfo.name, "VX6953")))
1361
1362 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001363 focus_mode_values);
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001364 else
1365 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
1366 CameraParameters::FOCUS_MODE_INFINITY);
1367
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001368 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1369 picture_format_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001370
1371 if (mSensorInfo.flash_enabled) {
1372 mParameters.set(CameraParameters::KEY_FLASH_MODE,
1373 CameraParameters::FLASH_MODE_OFF);
1374 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
1375 flash_values);
1376 }
1377
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08001378 mParameters.set(CameraParameters::KEY_MAX_SHARPNESS,
1379 CAMERA_MAX_SHARPNESS);
1380 mParameters.set(CameraParameters::KEY_MAX_CONTRAST,
1381 CAMERA_MAX_CONTRAST);
1382 mParameters.set(CameraParameters::KEY_MAX_SATURATION,
1383 CAMERA_MAX_SATURATION);
1384
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07001385 mParameters.set(
1386 CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
1387 EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
1388 mParameters.set(
1389 CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
1390 EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
1391 mParameters.set(
1392 CameraParameters::KEY_EXPOSURE_COMPENSATION,
1393 EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
1394 mParameters.setFloat(
1395 CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
1396 EXPOSURE_COMPENSATION_STEP);
1397
Apurva Rajguru07185952010-01-22 15:40:07 -08001398 mParameters.set("luma-adaptation", "3");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001399 mParameters.set("zoom-supported", "true");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001400 mParameters.set("zoom", 0);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001401 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT,
1402 CameraParameters::PIXEL_FORMAT_JPEG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001403
Kiran Kumar H N595970b2010-01-12 10:41:09 -08001404 mParameters.set(CameraParameters::KEY_SHARPNESS,
1405 CAMERA_DEF_SHARPNESS);
1406 mParameters.set(CameraParameters::KEY_CONTRAST,
1407 CAMERA_DEF_CONTRAST);
1408 mParameters.set(CameraParameters::KEY_SATURATION,
1409 CAMERA_DEF_SATURATION);
1410
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301411 mParameters.set(CameraParameters::KEY_ISO_MODE,
1412 CameraParameters::ISO_AUTO);
1413 mParameters.set(CameraParameters::KEY_LENSSHADE,
1414 CameraParameters::LENSSHADE_ENABLE);
1415 mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
1416 iso_values);
1417 mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
1418 lensshade_values);
Nishant Pandit741742b2010-09-21 03:24:20 +05301419 mParameters.set(CameraParameters::KEY_HISTOGRAM,
1420 CameraParameters::HISTOGRAM_DISABLE);
1421 mParameters.set(CameraParameters::KEY_SUPPORTED_HISTOGRAM_MODES,
1422 histogram_values);
Apurva Rajguru08383852010-05-17 14:25:39 -07001423 mParameters.set(CameraParameters::KEY_SCENE_MODE,
1424 CameraParameters::SCENE_MODE_AUTO);
Mohan Kandra7110c242010-07-18 15:34:48 -07001425 mParameters.set("strtextures", "OFF");
1426
Apurva Rajguru08383852010-05-17 14:25:39 -07001427 mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
1428 scenemode_values);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001429 mParameters.set(CameraParameters::KEY_CONTINUOUS_AF,
1430 CameraParameters::CONTINUOUS_AF_OFF);
1431 mParameters.set(CameraParameters::KEY_SUPPORTED_CONTINUOUS_AF,
1432 continuous_af_values);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001433 mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC,
1434 CameraParameters::TOUCH_AF_AEC_OFF);
1435 mParameters.set(CameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
1436 touchafaec_values);
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07001437 mParameters.setTouchIndexAec(-1, -1);
1438 mParameters.setTouchIndexAf(-1, -1);
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001439 mParameters.set(CameraParameters::KEY_SCENE_DETECT,
1440 CameraParameters::SCENE_DETECT_OFF);
1441 mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_DETECT,
1442 scenedetect_values);
Srinivasan Kannan264376e2010-08-13 18:54:35 -07001443 mParameters.setFloat(CameraParameters::KEY_FOCAL_LENGTH,
1444 CAMERA_FOCAL_LENGTH_DEFAULT);
1445 mParameters.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
1446 CAMERA_HORIZONTAL_VIEW_ANGLE_DEFAULT);
1447 mParameters.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE,
1448 CAMERA_VERTICAL_VIEW_ANGLE_DEFAULT);
Apurva Rajgurue5965c42010-09-09 14:24:54 -07001449 mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF,
1450 CameraParameters::SELECTABLE_ZONE_AF_AUTO);
1451 mParameters.set(CameraParameters::KEY_SUPPORTED_SELECTABLE_ZONE_AF,
1452 selectable_zone_af_values);
Priyanka Kharat67cfe532010-03-29 17:28:22 -07001453 if (setParameters(mParameters) != NO_ERROR) {
1454 LOGE("Failed to set default parameters?!");
1455 }
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001456 mUseOverlay = useOverlay();
1457
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001458 /* Initialize the camframe_timeout_flag*/
1459 Mutex::Autolock l(&mCamframeTimeoutLock);
1460 camframe_timeout_flag = FALSE;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001461 mPostViewHeap = NULL;
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001462
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001463 mInitialized = true;
1464
Mohan Kandra0d115d12010-08-19 11:47:15 -07001465 LOGI("initDefaultParameters X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001466}
1467
Srinivasan Kannan71229622009-12-04 12:05:58 -08001468void QualcommCameraHardware::findSensorType(){
1469 mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
1470 mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
1471 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1472 sizeof(cam_ctrl_dimension_t), &mDimension);
1473 if (ret) {
1474 unsigned int i;
1475 for (i = 0; i < sizeof(sensorTypes) / sizeof(SensorType); i++) {
1476 if (sensorTypes[i].rawPictureHeight
1477 == mDimension.raw_picture_height) {
1478 sensorType = sensorTypes + i;
1479 return;
1480 }
1481 }
1482 }
1483 //default to 5 mp
1484 sensorType = sensorTypes;
1485 return;
1486}
1487
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001488#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
1489
1490bool QualcommCameraHardware::startCamera()
1491{
1492 LOGV("startCamera E");
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08001493 if( mCurrentTarget == TARGET_MAX ) {
1494 LOGE(" Unable to determine the target type. Camera will not work ");
1495 return false;
1496 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001497#if DLOPEN_LIBMMCAMERA
1498 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
Priya Komarlingam9bb2d492010-06-23 19:21:52 -07001499
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001500 LOGV("loading liboemcamera at %p", libmmcamera);
1501 if (!libmmcamera) {
1502 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1503 return false;
1504 }
1505
1506 *(void **)&LINK_cam_frame =
1507 ::dlsym(libmmcamera, "cam_frame");
1508 *(void **)&LINK_camframe_terminate =
1509 ::dlsym(libmmcamera, "camframe_terminate");
1510
1511 *(void **)&LINK_jpeg_encoder_init =
1512 ::dlsym(libmmcamera, "jpeg_encoder_init");
1513
1514 *(void **)&LINK_jpeg_encoder_encode =
1515 ::dlsym(libmmcamera, "jpeg_encoder_encode");
1516
1517 *(void **)&LINK_jpeg_encoder_join =
1518 ::dlsym(libmmcamera, "jpeg_encoder_join");
1519
1520 *(void **)&LINK_mmcamera_camframe_callback =
1521 ::dlsym(libmmcamera, "mmcamera_camframe_callback");
1522
1523 *LINK_mmcamera_camframe_callback = receive_camframe_callback;
1524
Nishant Pandit741742b2010-09-21 03:24:20 +05301525 *(void **)&LINK_mmcamera_camstats_callback =
1526 ::dlsym(libmmcamera, "mmcamera_camstats_callback");
1527
1528 *LINK_mmcamera_camstats_callback = receive_camstats_callback;
1529
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001530 *(void **)&LINK_mmcamera_jpegfragment_callback =
1531 ::dlsym(libmmcamera, "mmcamera_jpegfragment_callback");
1532
1533 *LINK_mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
1534
1535 *(void **)&LINK_mmcamera_jpeg_callback =
1536 ::dlsym(libmmcamera, "mmcamera_jpeg_callback");
1537
1538 *LINK_mmcamera_jpeg_callback = receive_jpeg_callback;
1539
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001540 *(void **)&LINK_camframe_timeout_callback =
1541 ::dlsym(libmmcamera, "camframe_timeout_callback");
1542
1543 *LINK_camframe_timeout_callback = receive_camframetimeout_callback;
1544
Sravankb4f5f1c2010-01-21 11:06:17 +05301545 // 720 p new recording functions
1546 *(void **)&LINK_cam_frame_flush_free_video = ::dlsym(libmmcamera, "cam_frame_flush_free_video");
1547
1548 *(void **)&LINK_camframe_free_video = ::dlsym(libmmcamera, "cam_frame_add_free_video");
1549
1550 *(void **)&LINK_camframe_video_callback = ::dlsym(libmmcamera, "mmcamera_camframe_videocallback");
1551 *LINK_camframe_video_callback = receive_camframe_video_callback;
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08001552
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001553 *(void **)&LINK_mmcamera_shutter_callback =
1554 ::dlsym(libmmcamera, "mmcamera_shutter_callback");
1555
1556 *LINK_mmcamera_shutter_callback = receive_shutter_callback;
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08001557
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001558 *(void**)&LINK_jpeg_encoder_setMainImageQuality =
1559 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
Kiran Kumar H N8861f302010-01-05 12:01:41 -08001560
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001561 *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
1562 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
1563
1564 *(void**)&LINK_jpeg_encoder_setRotation =
1565 ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
1566
Mohan Kandra02486042010-06-18 16:49:43 -07001567 *(void**)&LINK_jpeg_encoder_get_buffer_offset =
1568 ::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset");
1569
Kiran Kumar H N8861f302010-01-05 12:01:41 -08001570/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001571 *(void**)&LINK_jpeg_encoder_setLocation =
1572 ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001573*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001574 *(void **)&LINK_cam_conf =
1575 ::dlsym(libmmcamera, "cam_conf");
1576
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001577/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001578 *(void **)&LINK_default_sensor_get_snapshot_sizes =
1579 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001580*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001581 *(void **)&LINK_launch_cam_conf_thread =
1582 ::dlsym(libmmcamera, "launch_cam_conf_thread");
1583
1584 *(void **)&LINK_release_cam_conf_thread =
1585 ::dlsym(libmmcamera, "release_cam_conf_thread");
Nishant Pandit741742b2010-09-21 03:24:20 +05301586 *(void **)&LINK_mm_camera_config_init =
1587 ::dlsym(libmmcamera, "mm_camera_config_init");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001588
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301589 *(void **)&LINK_mmcamera_liveshot_callback =
1590 ::dlsym(libmmcamera, "mmcamera_liveshot_callback");
1591
1592 *LINK_mmcamera_liveshot_callback = receive_liveshot_callback;
1593
1594 *(void **)&LINK_cancel_liveshot =
1595 ::dlsym(libmmcamera, "cancel_liveshot");
1596
1597 *(void **)&LINK_set_liveshot_params =
1598 ::dlsym(libmmcamera, "set_liveshot_params");
1599
Nishant Pandit741742b2010-09-21 03:24:20 +05301600 *(void **)&LINK_mm_camera_config_deinit =
1601 ::dlsym(libmmcamera, "mm_camera_config_deinit");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001602/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001603 *(void **)&LINK_zoom_crop_upscale =
1604 ::dlsym(libmmcamera, "zoom_crop_upscale");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001605*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001606
1607#else
1608 mmcamera_camframe_callback = receive_camframe_callback;
Nishant Pandit741742b2010-09-21 03:24:20 +05301609 mmcamera_camstats_callback = receive_camstats_callback;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001610 mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
1611 mmcamera_jpeg_callback = receive_jpeg_callback;
1612 mmcamera_shutter_callback = receive_shutter_callback;
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301613 mmcamera_liveshot_callback = receive_liveshot_callback;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001614#endif // DLOPEN_LIBMMCAMERA
1615
1616 /* The control thread is in libcamera itself. */
Brian Steuer07704892009-12-18 18:07:33 -08001617 if (pthread_join(w_thread, NULL) != 0) {
1618 LOGE("Camera open thread exit failed");
1619 return false;
1620 }
1621 mCameraControlFd = camerafd;
1622
Kiran Kumar H N585bc362010-01-19 13:04:44 -08001623 if (mCameraControlFd < 0) {
1624 LOGE("startCamera X: %s open failed: %s!",
1625 MSM_CAMERA_CONTROL,
1626 strerror(errno));
1627 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001628 }
1629
Nishant Pandit741742b2010-09-21 03:24:20 +05301630 if (MM_CAMERA_STATUS_SUCCESS != LINK_mm_camera_config_init(&mCfgControl)) {
1631 LOGE("startCamera: mm_camera_config_init failed:");
1632 return FALSE;
1633 }
1634
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301635 if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){
Mohan Kandra284966d2010-01-05 13:39:15 -08001636 fb_fd = open("/dev/graphics/fb0", O_RDWR);
1637 if (fb_fd < 0) {
1638 LOGE("startCamera: fb0 open failed: %s!", strerror(errno));
1639 return FALSE;
1640 }
1641 }
1642
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001643 /* This will block until the control thread is launched. After that, sensor
1644 * information becomes available.
1645 */
1646
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001647 memset(&mSensorInfo, 0, sizeof(mSensorInfo));
1648 if (ioctl(mCameraControlFd,
1649 MSM_CAM_IOCTL_GET_SENSOR_INFO,
1650 &mSensorInfo) < 0)
1651 LOGW("%s: cannot retrieve sensor info!", __FUNCTION__);
1652 else
1653 LOGI("%s: camsensor name %s, flash %d", __FUNCTION__,
1654 mSensorInfo.name, mSensorInfo.flash_enabled);
Nishant Pandit741742b2010-09-21 03:24:20 +05301655
1656 mCfgControl.mm_camera_query_parms(CAMERA_PARM_PICT_SIZE, (void **)&picture_sizes, &PICTURE_SIZE_COUNT);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001657 if (!picture_sizes || !PICTURE_SIZE_COUNT) {
1658 LOGE("startCamera X: could not get snapshot sizes");
1659 return false;
1660 }
Nishant Pandit741742b2010-09-21 03:24:20 +05301661 LOGV("startCamera picture_sizes %p PICTURE_SIZE_COUNT %d", picture_sizes, PICTURE_SIZE_COUNT);
1662
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001663 LOGV("startCamera X");
1664 return true;
1665}
1666
1667status_t QualcommCameraHardware::dump(int fd,
1668 const Vector<String16>& args) const
1669{
1670 const size_t SIZE = 256;
1671 char buffer[SIZE];
1672 String8 result;
1673
1674 // Dump internal primitives.
1675 result.append("QualcommCameraHardware::dump");
1676 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
1677 result.append(buffer);
1678 int width, height;
1679 mParameters.getPreviewSize(&width, &height);
1680 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
1681 result.append(buffer);
1682 mParameters.getPictureSize(&width, &height);
1683 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
1684 result.append(buffer);
1685 snprintf(buffer, 255,
1686 "preview frame size(%d), raw size (%d), jpeg size (%d) "
1687 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
1688 mJpegSize, mJpegMaxSize);
1689 result.append(buffer);
1690 write(fd, result.string(), result.size());
1691
1692 // Dump internal objects.
Mohan Kandrad9efed92010-01-15 19:08:39 -08001693 if (mPreviewHeap != 0) {
1694 mPreviewHeap->dump(fd, args);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001695 }
1696 if (mRawHeap != 0) {
1697 mRawHeap->dump(fd, args);
1698 }
1699 if (mJpegHeap != 0) {
1700 mJpegHeap->dump(fd, args);
1701 }
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001702 if(mRawSnapshotAshmemHeap != 0 ){
1703 mRawSnapshotAshmemHeap->dump(fd, args);
1704 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001705 mParameters.dump(fd, args);
1706 return NO_ERROR;
1707}
1708
Mohan Kandra284966d2010-01-05 13:39:15 -08001709static bool native_get_maxzoom(int camfd, void *pZm)
1710{
1711 LOGV("native_get_maxzoom E");
1712
1713 struct msm_ctrl_cmd ctrlCmd;
1714 int32_t *pZoom = (int32_t *)pZm;
1715
1716 ctrlCmd.type = CAMERA_GET_PARM_MAXZOOM;
1717 ctrlCmd.timeout_ms = 5000;
1718 ctrlCmd.length = sizeof(int32_t);
1719 ctrlCmd.value = pZoom;
1720 ctrlCmd.resp_fd = camfd;
1721
1722 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1723 LOGE("native_get_maxzoom: ioctl fd %d error %s",
1724 camfd,
1725 strerror(errno));
1726 return false;
1727 }
Brian Steuerb62adbd2010-02-02 14:47:08 -08001728 LOGD("ctrlCmd.value = %d", *(int32_t *)ctrlCmd.value);
Mohan Kandra284966d2010-01-05 13:39:15 -08001729 memcpy(pZoom, (int32_t *)ctrlCmd.value, sizeof(int32_t));
1730
1731 LOGV("native_get_maxzoom X");
1732 return true;
1733}
1734
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001735static bool native_get_zoomratios(int camfd, void *pZr, int maxZoomSize)
1736{
1737 LOGV("native_get_zoomratios E");
1738 struct msm_ctrl_cmd ctrlCmd;
1739 int16_t *zoomRatios = (int16_t *)pZr;
1740
1741 if(maxZoomSize <= 0)
1742 return false;
1743
1744 ctrlCmd.type = CAMERA_GET_PARM_ZOOMRATIOS;
1745 ctrlCmd.timeout_ms = 5000;
1746 ctrlCmd.length = sizeof(int16_t)* (maxZoomSize);
1747 ctrlCmd.value = zoomRatios;
1748 ctrlCmd.resp_fd = camfd;
1749
1750 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1751 LOGE("native_get_zoomratios: ioctl fd %d error %s",
1752 camfd,
1753 strerror(errno));
1754 return false;
1755 }
1756 LOGV("native_get_zoomratios X");
1757 return true;
1758}
1759
1760
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001761static bool native_set_afmode(int camfd, isp3a_af_mode_t af_type)
1762{
1763 int rc;
1764 struct msm_ctrl_cmd ctrlCmd;
1765
1766 ctrlCmd.timeout_ms = 5000;
1767 ctrlCmd.type = CAMERA_SET_PARM_AUTO_FOCUS;
1768 ctrlCmd.length = sizeof(af_type);
1769 ctrlCmd.value = &af_type;
1770 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1771
1772 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0)
1773 LOGE("native_set_afmode: ioctl fd %d error %s\n",
1774 camfd,
1775 strerror(errno));
1776
1777 LOGV("native_set_afmode: ctrlCmd.status == %d\n", ctrlCmd.status);
1778 return rc >= 0 && ctrlCmd.status == CAMERA_EXIT_CB_DONE;
1779}
1780
1781static bool native_cancel_afmode(int camfd, int af_fd)
1782{
1783 int rc;
1784 struct msm_ctrl_cmd ctrlCmd;
1785
1786 ctrlCmd.timeout_ms = 0;
1787 ctrlCmd.type = CAMERA_AUTO_FOCUS_CANCEL;
1788 ctrlCmd.length = 0;
1789 ctrlCmd.value = NULL;
1790 ctrlCmd.resp_fd = -1; // there's no response fd
1791
1792 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd)) < 0)
1793 {
1794 LOGE("native_cancel_afmode: ioctl fd %d error %s\n",
1795 camfd,
1796 strerror(errno));
1797 return false;
1798 }
1799
1800 return true;
1801}
1802
1803static bool native_start_preview(int camfd)
1804{
1805 struct msm_ctrl_cmd ctrlCmd;
1806
1807 ctrlCmd.timeout_ms = 5000;
1808 ctrlCmd.type = CAMERA_START_PREVIEW;
1809 ctrlCmd.length = 0;
1810 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1811
1812 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1813 LOGE("native_start_preview: MSM_CAM_IOCTL_CTRL_COMMAND fd %d error %s",
1814 camfd,
1815 strerror(errno));
1816 return false;
1817 }
1818
1819 return true;
1820}
1821
1822static bool native_get_picture (int camfd, common_crop_t *crop)
1823{
1824 struct msm_ctrl_cmd ctrlCmd;
1825
1826 ctrlCmd.timeout_ms = 5000;
1827 ctrlCmd.length = sizeof(common_crop_t);
1828 ctrlCmd.value = crop;
1829
1830 if(ioctl(camfd, MSM_CAM_IOCTL_GET_PICTURE, &ctrlCmd) < 0) {
1831 LOGE("native_get_picture: MSM_CAM_IOCTL_GET_PICTURE fd %d error %s",
1832 camfd,
1833 strerror(errno));
1834 return false;
1835 }
1836
1837 LOGV("crop: in1_w %d", crop->in1_w);
1838 LOGV("crop: in1_h %d", crop->in1_h);
1839 LOGV("crop: out1_w %d", crop->out1_w);
1840 LOGV("crop: out1_h %d", crop->out1_h);
1841
1842 LOGV("crop: in2_w %d", crop->in2_w);
1843 LOGV("crop: in2_h %d", crop->in2_h);
1844 LOGV("crop: out2_w %d", crop->out2_w);
1845 LOGV("crop: out2_h %d", crop->out2_h);
1846
1847 LOGV("crop: update %d", crop->update_flag);
1848
1849 return true;
1850}
1851
1852static bool native_stop_preview(int camfd)
1853{
1854 struct msm_ctrl_cmd ctrlCmd;
1855 ctrlCmd.timeout_ms = 5000;
1856 ctrlCmd.type = CAMERA_STOP_PREVIEW;
1857 ctrlCmd.length = 0;
1858 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1859
1860 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1861 LOGE("native_stop_preview: ioctl fd %d error %s",
1862 camfd,
1863 strerror(errno));
1864 return false;
1865 }
1866
1867 return true;
1868}
1869
1870static bool native_prepare_snapshot(int camfd)
1871{
1872 int ioctlRetVal = true;
1873 struct msm_ctrl_cmd ctrlCmd;
1874
1875 ctrlCmd.timeout_ms = 1000;
1876 ctrlCmd.type = CAMERA_PREPARE_SNAPSHOT;
1877 ctrlCmd.length = 0;
1878 ctrlCmd.value = NULL;
1879 ctrlCmd.resp_fd = camfd;
1880
1881 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1882 LOGE("native_prepare_snapshot: ioctl fd %d error %s",
1883 camfd,
1884 strerror(errno));
1885 return false;
1886 }
1887 return true;
1888}
1889
1890static bool native_start_snapshot(int camfd)
1891{
1892 struct msm_ctrl_cmd ctrlCmd;
1893
1894 ctrlCmd.timeout_ms = 5000;
1895 ctrlCmd.type = CAMERA_START_SNAPSHOT;
1896 ctrlCmd.length = 0;
1897 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1898
1899 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1900 LOGE("native_start_snapshot: ioctl fd %d error %s",
1901 camfd,
1902 strerror(errno));
1903 return false;
1904 }
1905
1906 return true;
1907}
1908
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301909static bool native_start_liveshot(int camfd)
1910{
1911 int ret;
1912 struct msm_ctrl_cmd ctrlCmd;
1913 ctrlCmd.timeout_ms = 5000;
1914 ctrlCmd.type = CAMERA_START_LIVESHOT;
1915 ctrlCmd.length = 0;
1916 ctrlCmd.value = NULL;
1917 ctrlCmd.resp_fd = camfd;
1918 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1919 LOGE("native_start_liveshot: ioctl failed. ioctl return value is %d ", ret);
1920 return false;
1921 }
1922 return true;
1923}
1924
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001925static bool native_start_raw_snapshot(int camfd)
1926{
1927 int ret;
1928 struct msm_ctrl_cmd ctrlCmd;
1929
1930 ctrlCmd.timeout_ms = 1000;
1931 ctrlCmd.type = CAMERA_START_RAW_SNAPSHOT;
1932 ctrlCmd.length = 0;
1933 ctrlCmd.value = NULL;
1934 ctrlCmd.resp_fd = camfd;
1935
1936 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1937 LOGE("native_start_raw_snapshot: ioctl failed. ioctl return value "\
1938 "is %d \n", ret);
1939 return false;
1940 }
1941 return true;
1942}
1943
1944
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001945static bool native_stop_snapshot (int camfd)
1946{
1947 struct msm_ctrl_cmd ctrlCmd;
1948
1949 ctrlCmd.timeout_ms = 0;
1950 ctrlCmd.type = CAMERA_STOP_SNAPSHOT;
1951 ctrlCmd.length = 0;
1952 ctrlCmd.resp_fd = -1;
1953
1954 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd) < 0) {
1955 LOGE("native_stop_snapshot: ioctl fd %d error %s",
1956 camfd,
1957 strerror(errno));
1958 return false;
1959 }
1960
1961 return true;
1962}
Sravankb4f5f1c2010-01-21 11:06:17 +05301963/*===========================================================================
1964 * FUNCTION - native_start_recording -
1965 *
1966 * DESCRIPTION:
1967 *==========================================================================*/
1968static bool native_start_recording(int camfd)
1969{
1970 int ret;
1971 struct msm_ctrl_cmd ctrlCmd;
1972
1973 ctrlCmd.timeout_ms = 1000;
1974 ctrlCmd.type = CAMERA_START_RECORDING;
1975 ctrlCmd.length = 0;
1976 ctrlCmd.value = NULL;
1977 ctrlCmd.resp_fd = camfd;
1978
1979 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1980 LOGE("native_start_recording: ioctl failed. ioctl return value "\
1981 "is %d \n", ret);
1982 return false;
1983 }
Mohan Kandraf1ebf982010-02-02 15:25:43 -08001984 LOGV("native_start_recording: ioctl good. ioctl return value is %d \n",ret);
Sravankb4f5f1c2010-01-21 11:06:17 +05301985
1986 /* TODO: Check status of postprocessing if there is any,
1987 * PP status should be in ctrlCmd */
1988
1989 return true;
1990}
1991
1992/*===========================================================================
1993 * FUNCTION - native_stop_recording -
1994 *
1995 * DESCRIPTION:
1996 *==========================================================================*/
1997static bool native_stop_recording(int camfd)
1998{
1999 int ret;
2000 struct msm_ctrl_cmd ctrlCmd;
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002001 LOGV("in native_stop_recording ");
Sravankb4f5f1c2010-01-21 11:06:17 +05302002 ctrlCmd.timeout_ms = 1000;
2003 ctrlCmd.type = CAMERA_STOP_RECORDING;
2004 ctrlCmd.length = 0;
2005 ctrlCmd.value = NULL;
2006 ctrlCmd.resp_fd = camfd;
2007
2008 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
2009 LOGE("native_stop_video: ioctl failed. ioctl return value is %d \n",
2010 ret);
2011 return false;
2012 }
2013 LOGV("in native_stop_recording returned %d", ret);
2014 return true;
2015}
2016/*===========================================================================
2017 * FUNCTION - native_start_video -
2018 *
2019 * DESCRIPTION:
2020 *==========================================================================*/
2021static bool native_start_video(int camfd)
2022{
2023 int ret;
2024 struct msm_ctrl_cmd ctrlCmd;
2025
2026 ctrlCmd.timeout_ms = 1000;
2027 ctrlCmd.type = CAMERA_START_VIDEO;
2028 ctrlCmd.length = 0;
2029 ctrlCmd.value = NULL;
2030 ctrlCmd.resp_fd = camfd;
2031
2032 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
2033 LOGE("native_start_video: ioctl failed. ioctl return value is %d \n",
2034 ret);
2035 return false;
2036 }
2037
2038 /* TODO: Check status of postprocessing if there is any,
2039 * PP status should be in ctrlCmd */
2040
2041 return true;
2042}
2043
2044/*===========================================================================
2045 * FUNCTION - native_stop_video -
2046 *
2047 * DESCRIPTION:
2048 *==========================================================================*/
2049static bool native_stop_video(int camfd)
2050{
2051 int ret;
2052 struct msm_ctrl_cmd ctrlCmd;
2053
2054 ctrlCmd.timeout_ms = 1000;
2055 ctrlCmd.type = CAMERA_STOP_VIDEO;
2056 ctrlCmd.length = 0;
2057 ctrlCmd.value = NULL;
2058 ctrlCmd.resp_fd = camfd;
2059
2060 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
2061 LOGE("native_stop_video: ioctl failed. ioctl return value is %d \n",
2062 ret);
2063 return false;
2064 }
2065
2066 return true;
2067}
2068/*==========================================================================*/
2069
2070static cam_frame_start_parms frame_parms;
2071static int recordingState = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002072
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002073#define GPS_PROCESSING_METHOD_SIZE 101
2074#define FOCAL_LENGTH_DECIMAL_PRECISON 100
2075
2076static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
2077#define EXIF_ASCII_PREFIX_SIZE (sizeof(ExifAsciiPrefix))
2078
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002079static rat_t latitude[3];
2080static rat_t longitude[3];
2081static char lonref[2];
2082static char latref[2];
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002083static rat_t altitude;
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002084static rat_t gpsTimestamp[3];
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002085static char gpsDatestamp[20];
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002086static char dateTime[20];
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002087static rat_t focalLength;
2088static char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
2089
2090
2091
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002092static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
2093 uint32_t count, uint8_t copy, void *data) {
2094
2095 if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
2096 LOGE("Number of entries exceeded limit");
2097 return;
2098 }
2099
2100 int index = exif_table_numEntries;
2101 exif_data[index].tag_id = tagid;
2102 exif_data[index].tag_entry.type = type;
2103 exif_data[index].tag_entry.count = count;
2104 exif_data[index].tag_entry.copy = copy;
2105 if((type == EXIF_RATIONAL) && (count > 1))
2106 exif_data[index].tag_entry.data._rats = (rat_t *)data;
2107 if((type == EXIF_RATIONAL) && (count == 1))
2108 exif_data[index].tag_entry.data._rat = *(rat_t *)data;
2109 else if(type == EXIF_ASCII)
2110 exif_data[index].tag_entry.data._ascii = (char *)data;
2111 else if(type == EXIF_BYTE)
2112 exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
2113
2114 // Increase number of entries
2115 exif_table_numEntries++;
2116}
2117
2118static void parseLatLong(const char *latlonString, int *pDegrees,
2119 int *pMinutes, int *pSeconds ) {
2120
2121 double value = atof(latlonString);
2122 value = fabs(value);
2123 int degrees = (int) value;
2124
2125 double remainder = value - degrees;
2126 int minutes = (int) (remainder * 60);
2127 int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
2128
2129 *pDegrees = degrees;
2130 *pMinutes = minutes;
2131 *pSeconds = seconds;
2132}
2133
2134static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
2135
2136 int degrees, minutes, seconds;
2137
2138 parseLatLong(latlonString, &degrees, &minutes, &seconds);
2139
2140 rat_t value[3] = { {degrees, 1},
2141 {minutes, 1},
2142 {seconds, 1000} };
2143
2144 if(tag == EXIFTAGID_GPS_LATITUDE) {
2145 memcpy(latitude, value, sizeof(latitude));
2146 addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
2147 1, (void *)latitude);
2148 } else {
2149 memcpy(longitude, value, sizeof(longitude));
2150 addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
2151 1, (void *)longitude);
2152 }
2153}
2154
2155void QualcommCameraHardware::setGpsParameters() {
2156 const char *str = NULL;
2157
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002158 str = mParameters.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
2159
2160 if(str!=NULL ){
2161 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
2162 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str,
2163 GPS_PROCESSING_METHOD_SIZE-1);
2164 gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE-1] = '\0';
2165 addExifTag(EXIFTAGID_GPS_PROCESSINGMETHOD, EXIF_ASCII,
2166 EXIF_ASCII_PREFIX_SIZE + strlen(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE) + 1,
2167 1, (void *)gpsProcessingMethod);
2168 }
2169
2170 str = NULL;
2171
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002172 //Set Latitude
2173 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE);
2174 if(str != NULL) {
2175 setLatLon(EXIFTAGID_GPS_LATITUDE, str);
2176 //set Latitude Ref
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002177 float latitudeValue = mParameters.getFloat(CameraParameters::KEY_GPS_LATITUDE);
2178 latref[0] = 'N';
2179 if(latitudeValue < 0 ){
2180 latref[0] = 'S';
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002181 }
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002182 latref[1] = '\0';
2183 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latref);
2184 addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
2185 1, (void *)latref);
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002186 }
2187
2188 //set Longitude
2189 str = NULL;
2190 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE);
2191 if(str != NULL) {
2192 setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
2193 //set Longitude Ref
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002194 float longitudeValue = mParameters.getFloat(CameraParameters::KEY_GPS_LONGITUDE);
2195 lonref[0] = 'E';
2196 if(longitudeValue < 0){
2197 lonref[0] = 'W';
2198 }
2199 lonref[1] = '\0';
2200 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, lonref);
2201 addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
2202 1, (void *)lonref);
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002203 }
2204
2205 //set Altitude
2206 str = NULL;
2207 str = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE);
2208 if(str != NULL) {
2209 int value = atoi(str);
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002210 int ref = 0;
2211 if(value < 0){
2212 ref = 1;
2213 value = -value;
2214 }
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002215 rat_t alt_value = {value, 1000};
2216 memcpy(&altitude, &alt_value, sizeof(altitude));
2217 addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
2218 1, (void *)&altitude);
2219 //set AltitudeRef
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002220 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, ref);
2221 addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
2222 1, (void *)&ref);
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002223 }
2224
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002225 //set Gps TimeStamp
2226 str = NULL;
2227 str = mParameters.get(CameraParameters::KEY_GPS_TIMESTAMP);
2228 if(str != NULL) {
2229
2230 long value = atol(str);
2231 time_t unixTime;
2232 struct tm *UTCTimestamp;
2233
2234 unixTime = (time_t)value;
2235 UTCTimestamp = gmtime(&unixTime);
2236
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002237 strftime(gpsDatestamp, sizeof(gpsDatestamp), "%Y:%m:%d", UTCTimestamp);
2238 addExifTag(EXIFTAGID_GPS_DATESTAMP, EXIF_ASCII,
2239 strlen(gpsDatestamp)+1 , 1, (void *)&gpsDatestamp);
2240
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002241 rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1},
2242 {UTCTimestamp->tm_min, 1},
2243 {UTCTimestamp->tm_sec, 1} };
2244
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002245
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002246 memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp));
2247 addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
2248 3, 1, (void *)&gpsTimestamp);
2249 }
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002250
2251}
2252
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002253bool QualcommCameraHardware::native_jpeg_encode(void)
2254{
2255 int jpeg_quality = mParameters.getInt("jpeg-quality");
2256 if (jpeg_quality >= 0) {
2257 LOGV("native_jpeg_encode, current jpeg main img quality =%d",
2258 jpeg_quality);
2259 if(!LINK_jpeg_encoder_setMainImageQuality(jpeg_quality)) {
2260 LOGE("native_jpeg_encode set jpeg-quality failed");
2261 return false;
2262 }
2263 }
2264
2265 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
2266 if (thumbnail_quality >= 0) {
2267 LOGV("native_jpeg_encode, current jpeg thumbnail quality =%d",
2268 thumbnail_quality);
2269 if(!LINK_jpeg_encoder_setThumbnailQuality(thumbnail_quality)) {
2270 LOGE("native_jpeg_encode set thumbnail-quality failed");
2271 return false;
2272 }
2273 }
2274
Priyanka Kharat32409f72010-08-25 18:11:03 -07002275 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM7627) && (mCurrentTarget != TARGET_MSM8660) ) {
Mohan Kandra02486042010-06-18 16:49:43 -07002276 int rotation = mParameters.getInt("rotation");
2277 if (rotation >= 0) {
2278 LOGV("native_jpeg_encode, rotation = %d", rotation);
2279 if(!LINK_jpeg_encoder_setRotation(rotation)) {
2280 LOGE("native_jpeg_encode set rotation failed");
2281 return false;
2282 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002283 }
2284 }
2285
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002286 jpeg_set_location();
2287
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002288 //set TimeStamp
2289 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
2290 if(str != NULL) {
2291 strncpy(dateTime, str, 19);
2292 dateTime[19] = '\0';
2293 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
2294 20, 1, (void *)dateTime);
2295 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002296
Srinivasan Kannan09de3382010-08-16 16:42:00 -07002297 int focalLengthValue = (int) (mParameters.getFloat(
2298 CameraParameters::KEY_FOCAL_LENGTH) * FOCAL_LENGTH_DECIMAL_PRECISON);
2299 rat_t focalLengthRational = {focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISON};
2300 memcpy(&focalLength, &focalLengthRational, sizeof(focalLengthRational));
2301 addExifTag(EXIFTAGID_FOCAL_LENGTH, EXIF_RATIONAL, 1,
2302 1, (void *)&focalLength);
2303
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002304 uint8_t * thumbnailHeap = NULL;
2305 int thumbfd = -1;
2306
2307 int width = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
2308 int height = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
2309
2310 LOGV("width %d and height %d", width , height);
2311
2312 if(width != 0 && height != 0){
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002313 if((mCurrentTarget == TARGET_MSM7630) ||
2314 (mCurrentTarget == TARGET_MSM8660) ||
2315 (mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)) {
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002316 thumbnailHeap = (uint8_t *)mRawHeap->mHeap->base();
2317 thumbfd = mRawHeap->mHeap->getHeapID();
2318 } else {
2319 thumbnailHeap = (uint8_t *)mThumbnailHeap->mHeap->base();
2320 thumbfd = mThumbnailHeap->mHeap->getHeapID();
2321 }
2322 }else {
2323 thumbnailHeap = NULL;
2324 thumbfd = 0;
2325 }
2326
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002327 if( (mCurrentTarget == TARGET_MSM7630) ||
2328 (mCurrentTarget == TARGET_MSM8660) ||
2329 (mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) ) {
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002330 // Pass the main image as thumbnail buffer, so that jpeg encoder will
2331 // generate thumbnail based on main image.
2332 // Set the input and output dimensions for thumbnail generation to main
2333 // image dimensions and required thumbanail size repectively, for the
2334 // encoder to do downscaling of the main image accordingly.
2335 mCrop.in1_w = mDimension.orig_picture_dx;
2336 mCrop.in1_h = mDimension.orig_picture_dy;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002337 /* For Adreno format on targets that don't use VFE other output
2338 * for postView, thumbnail_width and thumbnail_height has the
2339 * actual thumbnail dimensions.
2340 */
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002341 mCrop.out1_w = mDimension.thumbnail_width;
2342 mCrop.out1_h = mDimension.thumbnail_height;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002343 /* For targets, that uses VFE other output for postview,
2344 * thumbnail_width and thumbnail_height has values based on postView
2345 * dimensions(mostly previewWidth X previewHeight), but not based on
2346 * required thumbnail dimensions. So, while downscaling, we need to
2347 * pass the actual thumbnail dimensions, not the postview dimensions.
2348 * mThumbnailWidth/Height has the required thumbnail dimensions, so
2349 * use them here.
2350 */
2351 if( (mCurrentTarget == TARGET_MSM7630)||
2352 (mCurrentTarget == TARGET_MSM8660)) {
2353 mCrop.out1_w = mThumbnailWidth;
2354 mCrop.out1_h = mThumbnailHeight;
2355 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002356 mDimension.thumbnail_width = mDimension.orig_picture_dx;
2357 mDimension.thumbnail_height = mDimension.orig_picture_dy;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002358 LOGV("mCrop.in1_w = %d, mCrop.in1_h = %d", mCrop.in1_w, mCrop.in1_h);
2359 LOGV("mCrop.out1_w = %d, mCrop.out1_h = %d", mCrop.out1_w, mCrop.out1_h);
2360 LOGV("mDimension.thumbnail_width = %d, mDimension.thumbnail_height = %d", mDimension.thumbnail_width, mDimension.thumbnail_height);
2361 int CbCrOffset = -1;
2362 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)
2363 CbCrOffset = mCbCrOffsetRaw;
2364
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002365 if (!LINK_jpeg_encoder_encode(&mDimension,
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002366 thumbnailHeap,
2367 thumbfd,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002368 (uint8_t *)mRawHeap->mHeap->base(),
2369 mRawHeap->mHeap->getHeapID(),
2370 &mCrop, exif_data, exif_table_numEntries,
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002371 jpegPadding/2, CbCrOffset)) {
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002372 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
2373 return false;
2374 }
2375 } else {
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002376 if (!LINK_jpeg_encoder_encode(&mDimension,
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002377 thumbnailHeap,
2378 thumbfd,
2379 (uint8_t *)mRawHeap->mHeap->base(),
2380 mRawHeap->mHeap->getHeapID(),
2381 &mCrop, exif_data, exif_table_numEntries,
2382 jpegPadding/2, -1)) {
Srinivasan Kannan264376e2010-08-13 18:54:35 -07002383 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
2384 return false;
2385 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002386 }
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002387
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002388 return true;
2389}
2390
2391bool QualcommCameraHardware::native_set_parm(
2392 cam_ctrl_type type, uint16_t length, void *value)
2393{
2394 struct msm_ctrl_cmd ctrlCmd;
2395
2396 ctrlCmd.timeout_ms = 5000;
2397 ctrlCmd.type = (uint16_t)type;
2398 ctrlCmd.length = length;
2399 // FIXME: this will be put in by the kernel
2400 ctrlCmd.resp_fd = mCameraControlFd;
2401 ctrlCmd.value = value;
2402
2403 LOGV("%s: fd %d, type %d, length %d", __FUNCTION__,
2404 mCameraControlFd, type, length);
2405 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0 ||
2406 ctrlCmd.status != CAM_CTRL_SUCCESS) {
2407 LOGE("%s: error (%s): fd %d, type %d, length %d, status %d",
2408 __FUNCTION__, strerror(errno),
2409 mCameraControlFd, type, length, ctrlCmd.status);
2410 return false;
2411 }
2412 return true;
2413}
2414
2415void QualcommCameraHardware::jpeg_set_location()
2416{
2417 bool encode_location = true;
2418 camera_position_type pt;
2419
2420#define PARSE_LOCATION(what,type,fmt,desc) do { \
2421 pt.what = 0; \
2422 const char *what##_str = mParameters.get("gps-"#what); \
2423 LOGV("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
2424 if (what##_str) { \
2425 type what = 0; \
2426 if (sscanf(what##_str, fmt, &what) == 1) \
2427 pt.what = what; \
2428 else { \
2429 LOGE("GPS " #what " %s could not" \
2430 " be parsed as a " #desc, what##_str); \
2431 encode_location = false; \
2432 } \
2433 } \
2434 else { \
2435 LOGV("GPS " #what " not specified: " \
2436 "defaulting to zero in EXIF header."); \
2437 encode_location = false; \
2438 } \
2439 } while(0)
2440
2441 PARSE_LOCATION(timestamp, long, "%ld", "long");
2442 if (!pt.timestamp) pt.timestamp = time(NULL);
2443 PARSE_LOCATION(altitude, short, "%hd", "short");
2444 PARSE_LOCATION(latitude, double, "%lf", "double float");
2445 PARSE_LOCATION(longitude, double, "%lf", "double float");
2446
2447#undef PARSE_LOCATION
2448
2449 if (encode_location) {
2450 LOGD("setting image location ALT %d LAT %lf LON %lf",
2451 pt.altitude, pt.latitude, pt.longitude);
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002452
2453 setGpsParameters();
2454 /* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002455 if (!LINK_jpeg_encoder_setLocation(&pt)) {
2456 LOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
2457 }
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002458 */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002459 }
2460 else LOGV("not setting image location");
2461}
2462
2463void QualcommCameraHardware::runFrameThread(void *data)
2464{
2465 LOGV("runFrameThread E");
2466
2467 int cnt;
2468
2469#if DLOPEN_LIBMMCAMERA
2470 // We need to maintain a reference to libqcamera.so for the duration of the
2471 // frame thread, because we do not know when it will exit relative to the
2472 // lifetime of this object. We do not want to dlclose() libqcamera while
2473 // LINK_cam_frame is still running.
2474 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
2475 LOGV("FRAME: loading libqcamera at %p", libhandle);
2476 if (!libhandle) {
2477 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
2478 }
2479 if (libhandle)
2480#endif
2481 {
2482 LINK_cam_frame(data);
2483 }
2484
Mohan Kandrad9efed92010-01-15 19:08:39 -08002485 mPreviewHeap.clear();
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302486 if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660))
Sravankb4f5f1c2010-01-21 11:06:17 +05302487 mRecordHeap.clear();
2488
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002489#if DLOPEN_LIBMMCAMERA
2490 if (libhandle) {
2491 ::dlclose(libhandle);
2492 LOGV("FRAME: dlclose(libqcamera)");
2493 }
2494#endif
2495
2496 mFrameThreadWaitLock.lock();
2497 mFrameThreadRunning = false;
2498 mFrameThreadWait.signal();
2499 mFrameThreadWaitLock.unlock();
2500
2501 LOGV("runFrameThread X");
2502}
2503
Sravankb4f5f1c2010-01-21 11:06:17 +05302504void QualcommCameraHardware::runVideoThread(void *data)
2505{
2506 LOGD("runVideoThread E");
2507 msm_frame* vframe = NULL;
2508
2509 while(true) {
2510 pthread_mutex_lock(&(g_busy_frame_queue.mut));
2511
Srinivasan Kannanfc3915c2010-03-18 10:54:40 -07002512 // Exit the thread , in case of stop recording..
2513 mVideoThreadWaitLock.lock();
2514 if(mVideoThreadExit){
2515 LOGV("Exiting video thread..");
2516 mVideoThreadWaitLock.unlock();
2517 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
2518 break;
2519 }
2520 mVideoThreadWaitLock.unlock();
2521
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002522 LOGV("in video_thread : wait for video frame ");
Sravankb4f5f1c2010-01-21 11:06:17 +05302523 // check if any frames are available in busyQ and give callback to
2524 // services/video encoder
2525 cam_frame_wait_video();
2526 LOGV("video_thread, wait over..");
2527
2528 // Exit the thread , in case of stop recording..
2529 mVideoThreadWaitLock.lock();
2530 if(mVideoThreadExit){
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002531 LOGV("Exiting video thread..");
Sravankb4f5f1c2010-01-21 11:06:17 +05302532 mVideoThreadWaitLock.unlock();
2533 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
2534 break;
2535 }
2536 mVideoThreadWaitLock.unlock();
2537
2538 // Get the video frame to be encoded
2539 vframe = cam_frame_get_video ();
Apurva Rajgurud9b0b302010-02-19 11:22:56 -08002540 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Sravankb4f5f1c2010-01-21 11:06:17 +05302541 LOGV("in video_thread : got video frame ");
2542
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08002543 if (UNLIKELY(mDebugFps)) {
2544 debugShowVideoFPS();
2545 }
2546
Sravankb4f5f1c2010-01-21 11:06:17 +05302547 if(vframe != NULL) {
2548 // Find the offset within the heap of the current buffer.
2549 LOGV("Got video frame : buffer %d base %d ", vframe->buffer, mRecordHeap->mHeap->base());
2550 ssize_t offset =
2551 (ssize_t)vframe->buffer - (ssize_t)mRecordHeap->mHeap->base();
2552 LOGV("offset = %d , alignsize = %d , offset later = %d", offset, mRecordHeap->mAlignedBufferSize, (offset / mRecordHeap->mAlignedBufferSize));
2553
2554 offset /= mRecordHeap->mAlignedBufferSize;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07002555
2556 //set the track flag to true for this video buffer
2557 record_buffers_tracking_flag[offset] = true;
2558
Mohan Kandra1307f312010-04-29 10:18:42 -07002559 /* Extract the timestamp of this frame */
2560 nsecs_t timeStamp = nsecs_t(vframe->ts.tv_sec)*1000000000LL + vframe->ts.tv_nsec;
Sravankb4f5f1c2010-01-21 11:06:17 +05302561
2562 // dump frames for test purpose
2563#ifdef DUMP_VIDEO_FRAMES
2564 static int frameCnt = 0;
2565 if (frameCnt >= 11 && frameCnt <= 13 ) {
2566 char buf[128];
2567 sprintf(buf, "/data/%d_v.yuv", frameCnt);
2568 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2569 LOGV("dumping video frame %d", frameCnt);
2570 if (file_fd < 0) {
2571 LOGE("cannot open file\n");
2572 }
2573 else
2574 {
2575 write(file_fd, (const void *)vframe->buffer,
2576 vframe->cbcr_off * 3 / 2);
2577 }
2578 close(file_fd);
2579 }
2580 frameCnt++;
2581#endif
2582 // Enable IF block to give frames to encoder , ELSE block for just simulation
2583#if 1
2584 LOGV("in video_thread : got video frame, before if check giving frame to services/encoder");
2585 mCallbackLock.lock();
2586 int msgEnabled = mMsgEnabled;
2587 data_callback_timestamp rcb = mDataCallbackTimestamp;
2588 void *rdata = mCallbackCookie;
2589 mCallbackLock.unlock();
2590
2591 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
2592 LOGV("in video_thread : got video frame, giving frame to services/encoder");
Mohan Kandra1307f312010-04-29 10:18:42 -07002593 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[offset], rdata);
Sravankb4f5f1c2010-01-21 11:06:17 +05302594 }
2595#else
2596 // 720p output2 : simulate release frame here:
2597 LOGE("in video_thread simulation , releasing the video frame");
2598 LINK_camframe_free_video(vframe);
2599#endif
2600
2601 } else LOGE("in video_thread get frame returned null");
2602
Sravankb4f5f1c2010-01-21 11:06:17 +05302603
2604 } // end of while loop
Mohan Kandra156d0ac2010-01-25 16:59:17 -08002605
2606 mVideoThreadWaitLock.lock();
2607 mVideoThreadRunning = false;
2608 mVideoThreadWait.signal();
2609 mVideoThreadWaitLock.unlock();
2610
Sravankb4f5f1c2010-01-21 11:06:17 +05302611 LOGV("runVideoThread X");
2612}
2613
2614void *video_thread(void *user)
2615{
2616 LOGV("video_thread E");
2617 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2618 if (obj != 0) {
2619 obj->runVideoThread(user);
2620 }
2621 else LOGE("not starting video thread: the object went away!");
2622 LOGV("video_thread X");
2623 return NULL;
2624}
2625
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002626void *frame_thread(void *user)
2627{
2628 LOGD("frame_thread E");
2629 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2630 if (obj != 0) {
2631 obj->runFrameThread(user);
2632 }
2633 else LOGW("not starting frame thread: the object went away!");
2634 LOGD("frame_thread X");
2635 return NULL;
2636}
2637
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002638static int parse_size(const char *str, int &width, int &height)
2639{
2640 // Find the width.
2641 char *end;
2642 int w = (int)strtol(str, &end, 10);
2643 // If an 'x' or 'X' does not immediately follow, give up.
2644 if ( (*end != 'x') && (*end != 'X') )
2645 return -1;
2646
2647 // Find the height, immediately after the 'x'.
2648 int h = (int)strtol(end+1, 0, 10);
2649
2650 width = w;
2651 height = h;
2652
2653 return 0;
2654}
2655
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002656bool QualcommCameraHardware::initPreview()
2657{
2658 // See comments in deinitPreview() for why we have to wait for the frame
2659 // thread here, and why we can't use pthread_join().
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302660 const char * pmem_region;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002661 mParameters.getPreviewSize(&previewWidth, &previewHeight);
Sravankb4f5f1c2010-01-21 11:06:17 +05302662
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002663 //Get the Record sizes
2664 const char *recordSize = NULL;
2665 recordSize = mParameters.get("record-size");
2666 if(!recordSize) {
2667 //If application didn't set this parameter string, use the values from
2668 //getPreviewSize() as video dimensions.
2669 LOGI("No Record Size requested, use the preview dimensions");
2670 videoWidth = previewWidth;
2671 videoHeight = previewHeight;
2672 } else {
2673 //Extract the record witdh and height that application requested.
2674 if(!parse_size(recordSize, videoWidth, videoHeight)) {
2675 //VFE output1 shouldn't be greater than VFE output2.
2676 if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) {
2677 //Set preview sizes as record sizes.
2678 LOGI("Preview size %dx%d is greater than record size %dx%d,\
2679 resetting preview size to record size",previewWidth,\
2680 previewHeight, videoWidth, videoHeight);
2681 previewWidth = videoWidth;
2682 previewHeight = videoHeight;
2683 mParameters.setPreviewSize(previewWidth, previewHeight);
2684 }
2685 if( (mCurrentTarget != TARGET_MSM7630)
2686 && (mCurrentTarget != TARGET_QSD8250)
2687 && (mCurrentTarget != TARGET_MSM8660) ) {
2688 //For Single VFE output targets, use record dimensions as preview dimensions.
2689 previewWidth = videoWidth;
2690 previewHeight = videoHeight;
2691 mParameters.setPreviewSize(previewWidth, previewHeight);
2692 }
2693 } else {
2694 LOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize);
2695 return false;
2696 }
2697 }
2698
Mohan Kandra0d115d12010-08-19 11:47:15 -07002699 mDimension.display_width = previewWidth;
2700 mDimension.display_height= previewHeight;
2701
Sravankb4f5f1c2010-01-21 11:06:17 +05302702 LOGV("initPreview E: preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, videoWidth, videoHeight );
2703
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302704 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07002705 mDimension.video_width = CEILING16(videoWidth);
2706 /* Backup the video dimensions, as video dimensions in mDimension
2707 * will be modified when DIS is supported. Need the actual values
2708 * to pass ap part of VPE config
2709 */
2710 videoWidth = mDimension.video_width;
Sravankb4f5f1c2010-01-21 11:06:17 +05302711 mDimension.video_height = videoHeight;
2712 LOGV("initPreview : preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, mDimension.video_width, mDimension.video_height );
2713 }
2714
2715
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002716 mFrameThreadWaitLock.lock();
2717 while (mFrameThreadRunning) {
2718 LOGV("initPreview: waiting for old frame thread to complete.");
2719 mFrameThreadWait.wait(mFrameThreadWaitLock);
2720 LOGV("initPreview: old frame thread completed.");
2721 }
2722 mFrameThreadWaitLock.unlock();
2723
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002724 mInSnapshotModeWaitLock.lock();
2725 while (mInSnapshotMode) {
2726 LOGV("initPreview: waiting for snapshot mode to complete.");
2727 mInSnapshotModeWait.wait(mInSnapshotModeWaitLock);
2728 LOGV("initPreview: snapshot mode completed.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002729 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002730 mInSnapshotModeWaitLock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002731
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302732 /*Temporary migrating the preview buffers to smi pool for 8x60 till the bug is resolved in the pmem_adsp pool*/
2733 if(mCurrentTarget == TARGET_MSM8660)
2734 pmem_region = "/dev/pmem_smipool";
2735 else
2736 pmem_region = "/dev/pmem_adsp";
2737
2738
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002739 int cnt = 0;
2740 mPreviewFrameSize = previewWidth * previewHeight * 3/2;
Mohan Kandra02486042010-06-18 16:49:43 -07002741 int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
Mohan Kandra7110c242010-07-18 15:34:48 -07002742
2743 //Pass the yuv formats, display dimensions,
2744 //so that vfe will be initialized accordingly.
2745 mDimension.display_luma_width = previewWidth;
2746 mDimension.display_luma_height = previewHeight;
2747 mDimension.display_chroma_width = previewWidth;
2748 mDimension.display_chroma_height = previewHeight;
2749 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
2750 mPreviewFrameSize = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)) +
2751 2 * (CEILING32(previewWidth/2) * CEILING32(previewHeight/2));
2752 CbCrOffset = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight));
2753 mDimension.prev_format = CAMERA_YUV_420_NV21_ADRENO;
2754 mDimension.display_luma_width = CEILING32(previewWidth);
2755 mDimension.display_luma_height = CEILING32(previewHeight);
2756 mDimension.display_chroma_width = 2 * CEILING32(previewWidth/2);
2757 //Chroma Height is not needed as of now. Just sending with other dimensions.
2758 mDimension.display_chroma_height = CEILING32(previewHeight/2);
2759 }
2760 LOGV("mDimension.prev_format = %d", mDimension.prev_format);
2761 LOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
2762 LOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
2763 LOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
2764 LOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
2765
Mohan Kandrad9efed92010-01-15 19:08:39 -08002766 dstOffset = 0;
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302767 mPreviewHeap = new PmemPool(pmem_region,
Mohan Kandra284966d2010-01-05 13:39:15 -08002768 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
2769 mCameraControlFd,
Sravankb4f5f1c2010-01-21 11:06:17 +05302770 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
Mohan Kandra284966d2010-01-05 13:39:15 -08002771 mPreviewFrameSize,
Mohan Kandrad9efed92010-01-15 19:08:39 -08002772 kPreviewBufferCountActual,
Mohan Kandra284966d2010-01-05 13:39:15 -08002773 mPreviewFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002774 CbCrOffset,
2775 0,
Mohan Kandrad9efed92010-01-15 19:08:39 -08002776 "preview");
Mohan Kandra284966d2010-01-05 13:39:15 -08002777
Mohan Kandrad9efed92010-01-15 19:08:39 -08002778 if (!mPreviewHeap->initialized()) {
2779 mPreviewHeap.clear();
Mohan Kandra284966d2010-01-05 13:39:15 -08002780 LOGE("initPreview X: could not initialize Camera preview heap.");
2781 return false;
2782 }
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002783 if(mCurrentTarget == TARGET_MSM7627) {
Srinivasan Kannan613301c2010-02-10 17:08:53 -08002784 mPostViewHeap.clear();
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002785 if(mPostViewHeap == NULL) {
2786 LOGV(" Allocating Postview heap ");
2787 /* mPostViewHeap should be declared only for 7630 target */
2788 mPostViewHeap =
2789 new PmemPool("/dev/pmem_adsp",
2790 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
2791 mCameraControlFd,
2792 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
2793 mPreviewFrameSize,
2794 1,
2795 mPreviewFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002796 CbCrOffset,
2797 0,
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002798 "postview");
Mohan Kandra284966d2010-01-05 13:39:15 -08002799
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002800 if (!mPostViewHeap->initialized()) {
2801 mPostViewHeap.clear();
2802 LOGE(" Failed to initialize Postview Heap");
2803 return false;
2804 }
2805 }
Mohan Kandraf1ebf982010-02-02 15:25:43 -08002806 }
2807
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002808
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002809 //set DIS value to get the updated video width and height to calculate
2810 //the required record buffer size
2811 if(mVpeEnabled) {
2812 bool status = setDIS();
2813 if(status) {
2814 LOGE("Failed to set DIS");
2815 return false;
2816 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002817 }
Sravankb4f5f1c2010-01-21 11:06:17 +05302818
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002819 //Pass the original video width and height and get the required width
2820 //and height for record buffer allocation
2821 mDimension.orig_video_width = videoWidth;
2822 mDimension.orig_video_height = videoHeight;
2823
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002824 // mDimension will be filled with thumbnail_width, thumbnail_height,
2825 // orig_picture_dx, and orig_picture_dy after this function call. We need to
2826 // keep it for jpeg_encoder_encode.
2827 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
2828 sizeof(cam_ctrl_dimension_t), &mDimension);
2829
Mohan Kandracedd6cc2010-09-14 14:37:08 -07002830 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
2831
2832 // Allocate video buffers after allocating preview buffers.
2833 initRecord();
2834 }
2835
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002836 if (ret) {
2837 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
Mohan Kandrad9efed92010-01-15 19:08:39 -08002838 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002839 frames[cnt].buffer =
Mohan Kandrad9efed92010-01-15 19:08:39 -08002840 (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002841 frames[cnt].y_off = 0;
Mohan Kandra02486042010-06-18 16:49:43 -07002842 frames[cnt].cbcr_off = CbCrOffset;
Sravankb4f5f1c2010-01-21 11:06:17 +05302843 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002844 }
2845
2846 mFrameThreadWaitLock.lock();
2847 pthread_attr_t attr;
2848 pthread_attr_init(&attr);
2849 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Sravankb4f5f1c2010-01-21 11:06:17 +05302850
2851 frame_parms.frame = frames[kPreviewBufferCount - 1];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002852
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302853 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660)
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002854 frame_parms.video_frame = recordframes[kPreviewBufferCount - 1];
2855 else
2856 frame_parms.video_frame = frames[kPreviewBufferCount - 1];
Sravankb4f5f1c2010-01-21 11:06:17 +05302857
2858 LOGV ("initpreview before cam_frame thread carete , video frame buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
2859 (unsigned long)frame_parms.video_frame.buffer, frame_parms.video_frame.fd, frame_parms.video_frame.y_off,
2860 frame_parms.video_frame.cbcr_off);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002861 mFrameThreadRunning = !pthread_create(&mFrameThread,
2862 &attr,
2863 frame_thread,
Sravankb4f5f1c2010-01-21 11:06:17 +05302864 (void*)&(frame_parms));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002865 ret = mFrameThreadRunning;
2866 mFrameThreadWaitLock.unlock();
2867 }
2868
2869 LOGV("initPreview X: %d", ret);
2870 return ret;
2871}
2872
2873void QualcommCameraHardware::deinitPreview(void)
2874{
2875 LOGI("deinitPreview E");
2876
2877 // When we call deinitPreview(), we signal to the frame thread that it
2878 // needs to exit, but we DO NOT WAIT for it to complete here. The problem
2879 // is that deinitPreview is sometimes called from the frame-thread's
2880 // callback, when the refcount on the Camera client reaches zero. If we
2881 // called pthread_join(), we would deadlock. So, we just call
2882 // LINK_camframe_terminate() in deinitPreview(), which makes sure that
2883 // after the preview callback returns, the camframe thread will exit. We
2884 // could call pthread_join() in initPreview() to join the last frame
2885 // thread. However, we would also have to call pthread_join() in release
2886 // as well, shortly before we destroy the object; this would cause the same
2887 // deadlock, since release(), like deinitPreview(), may also be called from
2888 // the frame-thread's callback. This we have to make the frame thread
2889 // detached, and use a separate mechanism to wait for it to complete.
2890
Kiran Kumar H N7ac84e32010-02-01 10:58:47 -08002891 LINK_camframe_terminate();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002892 LOGI("deinitPreview X");
2893}
2894
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002895bool QualcommCameraHardware::initRawSnapshot()
2896{
2897 LOGV("initRawSnapshot E");
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302898 const char * pmem_region;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002899
2900 //get width and height from Dimension Object
2901 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
2902 sizeof(cam_ctrl_dimension_t), &mDimension);
2903
2904 if(!ret){
2905 LOGE("initRawSnapshot X: failed to set dimension");
2906 return false;
2907 }
2908 int rawSnapshotSize = mDimension.raw_picture_height *
2909 mDimension.raw_picture_width;
2910
2911 LOGV("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
2912 "raw_picture_width = %d",
2913 rawSnapshotSize, mDimension.raw_picture_height,
2914 mDimension.raw_picture_width);
2915
2916 if (mRawSnapShotPmemHeap != NULL) {
2917 LOGV("initRawSnapshot: clearing old mRawSnapShotPmemHeap.");
2918 mRawSnapShotPmemHeap.clear();
2919 }
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302920 if(mCurrentTarget == TARGET_MSM8660)
2921 pmem_region = "/dev/pmem_smipool";
2922 else
2923 pmem_region = "/dev/pmem_adsp";
2924
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002925
2926 //Pmem based pool for Camera Driver
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302927 mRawSnapShotPmemHeap = new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002928 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002929 mCameraControlFd,
2930 MSM_PMEM_RAW_MAINIMG,
2931 rawSnapshotSize,
2932 1,
2933 rawSnapshotSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002934 0,
2935 0,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002936 "raw pmem snapshot camera");
2937
2938 if (!mRawSnapShotPmemHeap->initialized()) {
2939 mRawSnapShotPmemHeap.clear();
2940 LOGE("initRawSnapshot X: error initializing mRawSnapshotHeap");
2941 return false;
2942 }
2943 LOGV("initRawSnapshot X");
2944 return true;
2945
2946}
2947
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002948bool QualcommCameraHardware::initRaw(bool initJpegHeap)
2949{
2950 int rawWidth, rawHeight;
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302951 const char * pmem_region;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08002952
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002953 mParameters.getPictureSize(&rawWidth, &rawHeight);
2954 LOGV("initRaw E: picture size=%dx%d", rawWidth, rawHeight);
2955
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002956 int thumbnailBufferSize;
2957 //Thumbnail height should be smaller than Picture height
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002958 if (rawHeight > (int)thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height){
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002959 mDimension.ui_thumbnail_width =
2960 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
2961 mDimension.ui_thumbnail_height =
2962 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
2963 uint32_t pictureAspectRatio = (uint32_t)((rawWidth * Q12) / rawHeight);
2964 uint32_t i;
2965 for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ )
2966 {
2967 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio)
2968 {
2969 mDimension.ui_thumbnail_width = thumbnail_sizes[i].width;
2970 mDimension.ui_thumbnail_height = thumbnail_sizes[i].height;
2971 break;
2972 }
2973 }
2974 }
2975 else{
2976 mDimension.ui_thumbnail_height = THUMBNAIL_SMALL_HEIGHT;
2977 mDimension.ui_thumbnail_width =
2978 (THUMBNAIL_SMALL_HEIGHT * rawWidth)/ rawHeight;
2979 }
2980
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07002981 if((mCurrentTarget == TARGET_MSM7630) ||
2982 (mCurrentTarget == TARGET_MSM8660)) {
2983 if(rawHeight < previewHeight) {
2984 mDimension.ui_thumbnail_height = THUMBNAIL_SMALL_HEIGHT;
2985 mDimension.ui_thumbnail_width =
2986 (THUMBNAIL_SMALL_HEIGHT * rawWidth)/ rawHeight;
2987 }
2988 /* store the thumbanil dimensions which are needed
2989 * by the jpeg downscaler to generate thumbnails from
2990 * main YUV image.
2991 */
2992 mThumbnailWidth = mDimension.ui_thumbnail_width;
2993 mThumbnailHeight = mDimension.ui_thumbnail_height;
2994 /* As thumbnail is generated from main YUV image,
2995 * configure and use the VFE other output to get
2996 * an image of preview dimensions for postView use.
2997 * So, mThumbnailHeap will be used for postview rather than
2998 * as thumbnail(Not changing the terminology to keep changes minimum).
2999 */
3000 if(rawHeight >= previewHeight) {
3001 mDimension.ui_thumbnail_width = previewWidth;
3002 mDimension.ui_thumbnail_height = previewHeight;
3003 }
3004 }
3005
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08003006 LOGV("Thumbnail Size Width %d Height %d",
3007 mDimension.ui_thumbnail_width,
3008 mDimension.ui_thumbnail_height);
3009
3010 thumbnailBufferSize = mDimension.ui_thumbnail_width *
3011 mDimension.ui_thumbnail_height * 3 / 2;
Mohan Kandra02486042010-06-18 16:49:43 -07003012 int CbCrOffsetThumb = PAD_TO_WORD(mDimension.ui_thumbnail_width *
3013 mDimension.ui_thumbnail_height);
Mohan Kandra7110c242010-07-18 15:34:48 -07003014 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003015 mDimension.main_img_format = CAMERA_YUV_420_NV21_ADRENO;
3016 mDimension.thumb_format = CAMERA_YUV_420_NV21_ADRENO;
Mohan Kandra7110c242010-07-18 15:34:48 -07003017 thumbnailBufferSize = PAD_TO_4K(CEILING32(mDimension.ui_thumbnail_width) *
3018 CEILING32(mDimension.ui_thumbnail_height)) +
3019 2 * (CEILING32(mDimension.ui_thumbnail_width/2) *
3020 CEILING32(mDimension.ui_thumbnail_height/2));
3021 CbCrOffsetThumb = PAD_TO_4K(CEILING32(mDimension.ui_thumbnail_width) *
3022 CEILING32(mDimension.ui_thumbnail_height));
3023 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003024 // mDimension will be filled with thumbnail_width, thumbnail_height,
3025 // orig_picture_dx, and orig_picture_dy after this function call. We need to
3026 // keep it for jpeg_encoder_encode.
3027 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
3028 sizeof(cam_ctrl_dimension_t), &mDimension);
3029 if(!ret) {
3030 LOGE("initRaw X: failed to set dimension");
3031 return false;
3032 }
3033
3034 if (mJpegHeap != NULL) {
3035 LOGV("initRaw: clearing old mJpegHeap.");
3036 mJpegHeap.clear();
3037 }
3038
3039 // Snapshot
3040 mRawSize = rawWidth * rawHeight * 3 / 2;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003041 mCbCrOffsetRaw = PAD_TO_WORD(rawWidth * rawHeight);
Mohan Kandra7110c242010-07-18 15:34:48 -07003042 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
3043 mRawSize = PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight)) +
3044 2 * (CEILING32(rawWidth/2) * CEILING32(rawHeight/2));
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003045 mCbCrOffsetRaw = PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight));
Mohan Kandra7110c242010-07-18 15:34:48 -07003046 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08003047 if( mCurrentTarget == TARGET_MSM7627 )
Mohan Kandra7110c242010-07-18 15:34:48 -07003048 mJpegMaxSize = CEILING16(rawWidth) * CEILING16(rawHeight) * 3 / 2;
3049 else {
3050 mJpegMaxSize = rawWidth * rawHeight * 3 / 2;
3051 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
3052 mJpegMaxSize =
3053 PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight)) +
3054 2 * (CEILING32(rawWidth/2) * CEILING32(rawHeight/2));
3055 }
3056 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003057
Mohan Kandra02486042010-06-18 16:49:43 -07003058 //For offline jpeg hw encoder, jpeg encoder will provide us the
3059 //required offsets and buffer size depending on the rotation.
3060 int yOffset = 0;
Priyanka Kharat32409f72010-08-25 18:11:03 -07003061 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM7627) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra02486042010-06-18 16:49:43 -07003062 int rotation = mParameters.getInt("rotation");
3063 if (rotation >= 0) {
3064 LOGV("initRaw, jpeg_rotation = %d", rotation);
3065 if(!LINK_jpeg_encoder_setRotation(rotation)) {
3066 LOGE("native_jpeg_encode set rotation failed");
3067 return false;
3068 }
3069 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003070 //Don't call the get_buffer_offset() for ADRENO, as the width and height
3071 //for Adreno format will be of CEILING32.
3072 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07003073 LINK_jpeg_encoder_get_buffer_offset(rawWidth, rawHeight, (uint32_t *)&yOffset,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003074 (uint32_t *)&mCbCrOffsetRaw, (uint32_t *)&mRawSize);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07003075 mJpegMaxSize = mRawSize;
3076 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003077 LOGV("initRaw: yOffset = %d, mCbCrOffsetRaw = %d, mRawSize = %d",
3078 yOffset, mCbCrOffsetRaw, mRawSize);
3079 }
Mohan Kandra02486042010-06-18 16:49:43 -07003080
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05303081 if(mCurrentTarget == TARGET_MSM8660)
3082 pmem_region = "/dev/pmem_smipool";
3083 else
3084 pmem_region = "/dev/pmem_adsp";
3085
3086
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003087 LOGV("initRaw: initializing mRawHeap.");
3088 mRawHeap =
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05303089 new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07003090 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003091 mCameraControlFd,
3092 MSM_PMEM_MAINIMG,
3093 mJpegMaxSize,
3094 kRawBufferCount,
3095 mRawSize,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003096 mCbCrOffsetRaw,
Mohan Kandra02486042010-06-18 16:49:43 -07003097 yOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003098 "snapshot camera");
3099
3100 if (!mRawHeap->initialized()) {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08003101 LOGE("initRaw X failed ");
3102 mRawHeap.clear();
3103 LOGE("initRaw X: error initializing mRawHeap");
3104 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003105 }
3106
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003107 //This is kind of workaround for the GPU limitation, as it can't
3108 //output in line to correct NV21 adreno formula for some snapshot
3109 //sizes (like 3264x2448). This change of cbcr offset will ensure that
3110 //chroma plane always starts at the beginning of a row.
3111 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO)
3112 mCbCrOffsetRaw = CEILING32(rawWidth) * CEILING32(rawHeight);
3113
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003114 LOGV("do_mmap snapshot pbuf = %p, pmem_fd = %d",
3115 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mHeap->getHeapID());
3116
3117 // Jpeg
3118
3119 if (initJpegHeap) {
3120 LOGV("initRaw: initializing mJpegHeap.");
3121 mJpegHeap =
3122 new AshmemPool(mJpegMaxSize,
3123 kJpegBufferCount,
3124 0, // we do not know how big the picture will be
3125 "jpeg");
3126
3127 if (!mJpegHeap->initialized()) {
3128 mJpegHeap.clear();
3129 mRawHeap.clear();
3130 LOGE("initRaw X failed: error initializing mJpegHeap.");
3131 return false;
3132 }
3133
3134 // Thumbnails
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003135 mThumbnailHeap =
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05303136 new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07003137 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003138 mCameraControlFd,
3139 MSM_PMEM_THUMBNAIL,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08003140 thumbnailBufferSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003141 1,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08003142 thumbnailBufferSize,
Mohan Kandra02486042010-06-18 16:49:43 -07003143 CbCrOffsetThumb,
3144 0,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003145 "thumbnail");
3146
3147 if (!mThumbnailHeap->initialized()) {
3148 mThumbnailHeap.clear();
3149 mJpegHeap.clear();
3150 mRawHeap.clear();
3151 LOGE("initRaw X failed: error initializing mThumbnailHeap.");
3152 return false;
3153 }
3154 }
3155
3156 LOGV("initRaw X");
3157 return true;
3158}
3159
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003160
3161void QualcommCameraHardware::deinitRawSnapshot()
3162{
3163 LOGV("deinitRawSnapshot E");
3164 mRawSnapShotPmemHeap.clear();
3165 mRawSnapshotAshmemHeap.clear();
3166 LOGV("deinitRawSnapshot X");
3167}
3168
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003169void QualcommCameraHardware::deinitRaw()
3170{
3171 LOGV("deinitRaw E");
3172
3173 mThumbnailHeap.clear();
3174 mJpegHeap.clear();
3175 mRawHeap.clear();
3176 mDisplayHeap.clear();
3177
3178 LOGV("deinitRaw X");
3179}
3180
3181void QualcommCameraHardware::release()
3182{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003183 LOGI("release E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003184 Mutex::Autolock l(&mLock);
3185
3186#if DLOPEN_LIBMMCAMERA
3187 if (libmmcamera == NULL) {
3188 LOGE("ERROR: multiple release!");
3189 return;
3190 }
3191#else
3192#warning "Cannot detect multiple release when not dlopen()ing libqcamera!"
3193#endif
3194
3195 int cnt, rc;
3196 struct msm_ctrl_cmd ctrlCmd;
Mohan Kandra0d115d12010-08-19 11:47:15 -07003197 LOGI("release: mCameraRunning = %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003198 if (mCameraRunning) {
3199 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
3200 mRecordFrameLock.lock();
3201 mReleasedRecordingFrame = true;
3202 mRecordWait.signal();
3203 mRecordFrameLock.unlock();
3204 }
3205 stopPreviewInternal();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003206 LOGI("release: stopPreviewInternal done.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003207 }
3208
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07003209 if(mCurrentTarget == TARGET_MSM7627) {
3210 mPostViewHeap.clear();
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003211 mPostViewHeap = NULL;
3212 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003213 LINK_jpeg_encoder_join();
Srinivasan Kannan426cde72010-06-04 09:37:21 -07003214 {
3215 Mutex::Autolock l (&mRawPictureHeapLock);
3216 deinitRaw();
3217 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003218 //Signal the snapshot thread
3219 mJpegThreadWaitLock.lock();
3220 mJpegThreadRunning = false;
3221 mJpegThreadWait.signal();
3222 mJpegThreadWaitLock.unlock();
3223
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003224 deinitRawSnapshot();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003225 LOGI("release: clearing resources done.");
Srinivasan Kannan426cde72010-06-04 09:37:21 -07003226
Priyanka Kharat85cebed2010-05-12 14:57:57 -07003227
3228 ctrlCmd.timeout_ms = 5000;
3229 ctrlCmd.length = 0;
3230 ctrlCmd.type = (uint16_t)CAMERA_EXIT;
3231 ctrlCmd.resp_fd = mCameraControlFd; // FIXME: this will be put in by the kernel
3232 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0)
3233 LOGE("ioctl CAMERA_EXIT fd %d error %s",
3234 mCameraControlFd, strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003235
Nishant Pandit741742b2010-09-21 03:24:20 +05303236 LINK_mm_camera_config_deinit(&mCfgControl);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003237 close(mCameraControlFd);
3238 mCameraControlFd = -1;
Mohan Kandra284966d2010-01-05 13:39:15 -08003239 if(fb_fd >= 0) {
3240 close(fb_fd);
3241 fb_fd = -1;
3242 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003243#if DLOPEN_LIBMMCAMERA
3244 if (libmmcamera) {
3245 ::dlclose(libmmcamera);
3246 LOGV("dlclose(libqcamera)");
3247 libmmcamera = NULL;
3248 }
3249#endif
3250
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003251 singleton_lock.lock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003252 singleton_releasing = true;
Srinivasan Kannan78444e42010-06-10 15:39:29 -07003253 singleton_releasing_start_time = systemTime();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003254 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003255
Mohan Kandra0d115d12010-08-19 11:47:15 -07003256 LOGI("release X: mCameraRunning = %d, mFrameThreadRunning = %d", mCameraRunning, mFrameThreadRunning);
3257 LOGI("mVideoThreadRunning = %d, mSnapshotThreadRunning = %d, mJpegThreadRunning = %d", mVideoThreadRunning, mSnapshotThreadRunning, mJpegThreadRunning);
3258 LOGI("camframe_timeout_flag = %d, mAutoFocusThreadRunning = %d", camframe_timeout_flag, mAutoFocusThreadRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003259}
3260
3261QualcommCameraHardware::~QualcommCameraHardware()
3262{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003263 LOGI("~QualcommCameraHardware E");
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003264 singleton_lock.lock();
Apurva Rajguruc73c1722010-04-15 17:39:11 -07003265
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303266 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660 ) {
Apurva Rajguruc73c1722010-04-15 17:39:11 -07003267 delete [] recordframes;
3268 recordframes = NULL;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07003269 delete [] record_buffers_tracking_flag;
3270 record_buffers_tracking_flag = NULL;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07003271 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003272 singleton.clear();
3273 singleton_releasing = false;
Srinivasan Kannan78444e42010-06-10 15:39:29 -07003274 singleton_releasing_start_time = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003275 singleton_wait.signal();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003276 singleton_lock.unlock();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003277 LOGI("~QualcommCameraHardware X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003278}
3279
3280sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
3281{
3282 LOGV("getRawHeap");
3283 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
3284}
3285
3286sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
3287{
3288 LOGV("getPreviewHeap");
Mohan Kandrad9efed92010-01-15 19:08:39 -08003289 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003290}
3291
3292status_t QualcommCameraHardware::startPreviewInternal()
3293{
Sravankb4f5f1c2010-01-21 11:06:17 +05303294 LOGV("in startPreviewInternal : E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003295 if(mCameraRunning) {
3296 LOGV("startPreview X: preview already running.");
3297 return NO_ERROR;
3298 }
3299
3300 if (!mPreviewInitialized) {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08003301 mLastQueuedFrame = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003302 mPreviewInitialized = initPreview();
3303 if (!mPreviewInitialized) {
3304 LOGE("startPreview X initPreview failed. Not starting preview.");
3305 return UNKNOWN_ERROR;
3306 }
3307 }
3308
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003309 {
3310 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3311 if(( mCurrentTarget != TARGET_MSM7630 ) &&
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303312 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003313 mCameraRunning = native_start_preview(mCameraControlFd);
3314 else
3315 mCameraRunning = native_start_video(mCameraControlFd);
3316 }
Sravankb4f5f1c2010-01-21 11:06:17 +05303317
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003318 if(!mCameraRunning) {
3319 deinitPreview();
3320 mPreviewInitialized = false;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08003321 mOverlay = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003322 LOGE("startPreview X: native_start_preview failed!");
3323 return UNKNOWN_ERROR;
3324 }
3325
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08003326 //Reset the Gps Information
3327 exif_table_numEntries = 0;
Mohan Kandra284966d2010-01-05 13:39:15 -08003328
Sravankb4f5f1c2010-01-21 11:06:17 +05303329 LOGV("startPreviewInternal X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003330 return NO_ERROR;
3331}
3332
3333status_t QualcommCameraHardware::startPreview()
3334{
3335 LOGV("startPreview E");
3336 Mutex::Autolock l(&mLock);
3337 return startPreviewInternal();
3338}
3339
3340void QualcommCameraHardware::stopPreviewInternal()
3341{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003342 LOGI("stopPreviewInternal E: %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003343 if (mCameraRunning) {
3344 // Cancel auto focus.
3345 {
3346 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
3347 cancelAutoFocusInternal();
3348 }
3349 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003350
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003351 Mutex::Autolock l(&mCamframeTimeoutLock);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003352 {
3353 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3354 if(!camframe_timeout_flag) {
3355 if (( mCurrentTarget != TARGET_MSM7630 ) &&
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303356 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003357 mCameraRunning = !native_stop_preview(mCameraControlFd);
3358 else
3359 mCameraRunning = !native_stop_video(mCameraControlFd);
3360 } else {
3361 /* This means that the camframetimeout was issued.
3362 * But we did not issue native_stop_preview(), so we
3363 * need to update mCameraRunning to indicate that
3364 * Camera is no longer running. */
3365 mCameraRunning = 0;
3366 }
3367 }
Sravankb4f5f1c2010-01-21 11:06:17 +05303368
Kiran Kumar H Nac2f4952009-12-17 01:16:53 -08003369 if (!mCameraRunning && mPreviewInitialized) {
3370 deinitPreview();
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303371 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra156d0ac2010-01-25 16:59:17 -08003372 mVideoThreadWaitLock.lock();
3373 LOGV("in stopPreviewInternal: making mVideoThreadExit 1");
3374 mVideoThreadExit = 1;
3375 mVideoThreadWaitLock.unlock();
3376 // 720p : signal the video thread , and check in video thread if stop is called, if so exit video thread.
3377 pthread_mutex_lock(&(g_busy_frame_queue.mut));
3378 pthread_cond_signal(&(g_busy_frame_queue.wait));
3379 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Mohan Kandra1ade9a82010-03-02 10:11:26 -08003380 /* Flush the Busy Q */
3381 cam_frame_flush_video();
3382 /* Flush the Free Q */
3383 LINK_cam_frame_flush_free_video();
Mohan Kandra156d0ac2010-01-25 16:59:17 -08003384 }
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003385 mPreviewInitialized = false;
3386 }
Kiran Kumar H Nac2f4952009-12-17 01:16:53 -08003387 else LOGE("stopPreviewInternal: failed to stop preview");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003388 }
Mohan Kandra0d115d12010-08-19 11:47:15 -07003389 LOGI("stopPreviewInternal X: %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003390}
3391
3392void QualcommCameraHardware::stopPreview()
3393{
3394 LOGV("stopPreview: E");
3395 Mutex::Autolock l(&mLock);
3396 {
3397 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
3398 return;
3399 }
3400 stopPreviewInternal();
3401 LOGV("stopPreview: X");
3402}
3403
3404void QualcommCameraHardware::runAutoFocus()
3405{
3406 bool status = true;
3407 void *libhandle = NULL;
Srinivasan Kannan71229622009-12-04 12:05:58 -08003408 isp3a_af_mode_t afMode;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003409
3410 mAutoFocusThreadLock.lock();
3411 // Skip autofocus if focus mode is infinity.
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003412 if ((mParameters.get(CameraParameters::KEY_FOCUS_MODE) == 0)
3413 || (strcmp(mParameters.get(CameraParameters::KEY_FOCUS_MODE),
3414 CameraParameters::FOCUS_MODE_INFINITY) == 0)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003415 goto done;
3416 }
3417
3418 mAutoFocusFd = open(MSM_CAMERA_CONTROL, O_RDWR);
3419 if (mAutoFocusFd < 0) {
3420 LOGE("autofocus: cannot open %s: %s",
3421 MSM_CAMERA_CONTROL,
3422 strerror(errno));
3423 mAutoFocusThreadRunning = false;
3424 mAutoFocusThreadLock.unlock();
3425 return;
3426 }
3427
3428#if DLOPEN_LIBMMCAMERA
3429 // We need to maintain a reference to libqcamera.so for the duration of the
3430 // AF thread, because we do not know when it will exit relative to the
3431 // lifetime of this object. We do not want to dlclose() libqcamera while
3432 // LINK_cam_frame is still running.
3433 libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
3434 LOGV("AF: loading libqcamera at %p", libhandle);
3435 if (!libhandle) {
3436 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
3437 close(mAutoFocusFd);
3438 mAutoFocusFd = -1;
3439 mAutoFocusThreadRunning = false;
3440 mAutoFocusThreadLock.unlock();
3441 return;
3442 }
3443#endif
3444
Srinivasan Kannan71229622009-12-04 12:05:58 -08003445 afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
3446 sizeof(focus_modes) / sizeof(str_map),
3447 mParameters.get(CameraParameters::KEY_FOCUS_MODE));
3448
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003449 /* This will block until either AF completes or is cancelled. */
Srinivasan Kannan71229622009-12-04 12:05:58 -08003450 LOGV("af start (fd %d mode %d)", mAutoFocusFd, afMode);
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003451 status_t err;
3452 err = mAfLock.tryLock();
3453 if(err == NO_ERROR) {
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003454 {
3455 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3456 if(mCameraRunning){
3457 LOGV("Start AF");
3458 status = native_set_afmode(mAutoFocusFd, afMode);
3459 }else{
3460 LOGV("As Camera preview is not running, AF not issued");
3461 status = false;
3462 }
3463 }
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003464 mAfLock.unlock();
3465 }
3466 else{
3467 //AF Cancel would have acquired the lock,
3468 //so, no need to perform any AF
Srinivasan Kannan99e82422010-02-28 15:32:16 -08003469 LOGV("As Cancel auto focus is in progress, auto focus request "
3470 "is ignored");
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003471 status = FALSE;
3472 }
3473
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003474 LOGV("af done: %d", (int)status);
3475 close(mAutoFocusFd);
3476 mAutoFocusFd = -1;
3477
3478done:
3479 mAutoFocusThreadRunning = false;
3480 mAutoFocusThreadLock.unlock();
3481
3482 mCallbackLock.lock();
3483 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
3484 notify_callback cb = mNotifyCallback;
3485 void *data = mCallbackCookie;
3486 mCallbackLock.unlock();
3487 if (autoFocusEnabled)
3488 cb(CAMERA_MSG_FOCUS, status, 0, data);
3489
3490#if DLOPEN_LIBMMCAMERA
3491 if (libhandle) {
3492 ::dlclose(libhandle);
3493 LOGV("AF: dlclose(libqcamera)");
3494 }
3495#endif
3496}
3497
3498status_t QualcommCameraHardware::cancelAutoFocusInternal()
3499{
3500 LOGV("cancelAutoFocusInternal E");
3501
Srinivasan Kannan71229622009-12-04 12:05:58 -08003502 if(!sensorType->hasAutoFocusSupport){
3503 LOGV("cancelAutoFocusInternal X");
3504 return NO_ERROR;
3505 }
3506
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003507#if 0
3508 if (mAutoFocusFd < 0) {
3509 LOGV("cancelAutoFocusInternal X: not in progress");
3510 return NO_ERROR;
3511 }
3512#endif
3513
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003514 status_t rc = NO_ERROR;
3515 status_t err;
3516 err = mAfLock.tryLock();
3517 if(err == NO_ERROR) {
3518 //Got Lock, means either AF hasn't started or
3519 // AF is done. So no need to cancel it, just change the state
Srinivasan Kannan99e82422010-02-28 15:32:16 -08003520 LOGV("As Auto Focus is not in progress, Cancel Auto Focus "
3521 "is ignored");
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003522 mAfLock.unlock();
3523 }
3524 else {
3525 //AF is in Progess, So cancel it
3526 LOGV("Lock busy...cancel AF");
3527 rc = native_cancel_afmode(mCameraControlFd, mAutoFocusFd) ?
3528 NO_ERROR :
3529 UNKNOWN_ERROR;
3530 }
3531
3532
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003533
3534 LOGV("cancelAutoFocusInternal X: %d", rc);
3535 return rc;
3536}
3537
3538void *auto_focus_thread(void *user)
3539{
3540 LOGV("auto_focus_thread E");
3541 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3542 if (obj != 0) {
3543 obj->runAutoFocus();
3544 }
3545 else LOGW("not starting autofocus: the object went away!");
3546 LOGV("auto_focus_thread X");
3547 return NULL;
3548}
3549
3550status_t QualcommCameraHardware::autoFocus()
3551{
3552 LOGV("autoFocus E");
3553 Mutex::Autolock l(&mLock);
3554
Srinivasan Kannan71229622009-12-04 12:05:58 -08003555 if(!sensorType->hasAutoFocusSupport){
Srinivasan Kannandf085222009-12-09 18:31:00 -08003556 bool status = false;
3557 mCallbackLock.lock();
3558 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
3559 notify_callback cb = mNotifyCallback;
3560 void *data = mCallbackCookie;
3561 mCallbackLock.unlock();
3562 if (autoFocusEnabled)
3563 cb(CAMERA_MSG_FOCUS, status, 0, data);
Srinivasan Kannan71229622009-12-04 12:05:58 -08003564 LOGV("autoFocus X");
3565 return NO_ERROR;
3566 }
3567
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003568 if (mCameraControlFd < 0) {
3569 LOGE("not starting autofocus: main control fd %d", mCameraControlFd);
3570 return UNKNOWN_ERROR;
3571 }
3572
3573 {
3574 mAutoFocusThreadLock.lock();
3575 if (!mAutoFocusThreadRunning) {
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003576 if (native_prepare_snapshot(mCameraControlFd) == FALSE) {
3577 LOGE("native_prepare_snapshot failed!\n");
3578 mAutoFocusThreadLock.unlock();
3579 return UNKNOWN_ERROR;
3580 }
3581
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003582 // Create a detached thread here so that we don't have to wait
3583 // for it when we cancel AF.
3584 pthread_t thr;
3585 pthread_attr_t attr;
3586 pthread_attr_init(&attr);
3587 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3588 mAutoFocusThreadRunning =
3589 !pthread_create(&thr, &attr,
3590 auto_focus_thread, NULL);
3591 if (!mAutoFocusThreadRunning) {
3592 LOGE("failed to start autofocus thread");
3593 mAutoFocusThreadLock.unlock();
3594 return UNKNOWN_ERROR;
3595 }
3596 }
3597 mAutoFocusThreadLock.unlock();
3598 }
3599
3600 LOGV("autoFocus X");
3601 return NO_ERROR;
3602}
3603
3604status_t QualcommCameraHardware::cancelAutoFocus()
3605{
3606 LOGV("cancelAutoFocus E");
3607 Mutex::Autolock l(&mLock);
3608
3609 int rc = NO_ERROR;
3610 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
3611 rc = cancelAutoFocusInternal();
3612 }
3613
3614 LOGV("cancelAutoFocus X");
3615 return rc;
3616}
3617
3618void QualcommCameraHardware::runSnapshotThread(void *data)
3619{
3620 LOGV("runSnapshotThread E");
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003621#if DLOPEN_LIBMMCAMERA
3622 // We need to maintain a reference to libqcamera.so for the duration of the
3623 // Snapshot thread, because we do not know when it will exit relative to the
3624 // lifetime of this object. We do not want to dlclose() libqcamera while
3625 // LINK_cam_frame is still running.
3626 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
3627 LOGV("SNAPSHOT: loading libqcamera at %p", libhandle);
3628 if (!libhandle) {
3629 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
3630 }
3631#endif
3632
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003633 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3634 if (native_start_snapshot(mCameraControlFd))
3635 receiveRawPicture();
3636 else
3637 LOGE("main: native_start_snapshot failed!");
3638 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
3639 if(native_start_raw_snapshot(mCameraControlFd)){
3640 receiveRawSnapshot();
3641 } else {
3642 LOGE("main: native_start_raw_snapshot failed!");
3643 }
3644 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003645 mInSnapshotModeWaitLock.lock();
3646 mInSnapshotMode = false;
3647 mInSnapshotModeWait.signal();
3648 mInSnapshotModeWaitLock.unlock();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003649
3650 mSnapshotFormat = 0;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003651 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO ) {
3652 mJpegThreadWaitLock.lock();
3653 while (mJpegThreadRunning) {
3654 LOGV("runSnapshotThread: waiting for jpeg thread to complete.");
3655 mJpegThreadWait.wait(mJpegThreadWaitLock);
3656 LOGV("runSnapshotThread: jpeg thread completed.");
3657 }
3658 mJpegThreadWaitLock.unlock();
3659 //clear the resources
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003660#if DLOPEN_LIBMMCAMERA
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003661 if(libhandle)
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003662#endif
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003663 {
3664 LINK_jpeg_encoder_join();
3665 }
3666 deinitRaw();
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003667 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003668
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003669 mSnapshotThreadWaitLock.lock();
3670 mSnapshotThreadRunning = false;
3671 mSnapshotThreadWait.signal();
3672 mSnapshotThreadWaitLock.unlock();
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003673#if DLOPEN_LIBMMCAMERA
3674 if (libhandle) {
3675 ::dlclose(libhandle);
3676 LOGV("SNAPSHOT: dlclose(libqcamera)");
3677 }
3678#endif
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003679
3680 LOGV("runSnapshotThread X");
3681}
3682
3683void *snapshot_thread(void *user)
3684{
3685 LOGD("snapshot_thread E");
3686 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3687 if (obj != 0) {
3688 obj->runSnapshotThread(user);
3689 }
3690 else LOGW("not starting snapshot thread: the object went away!");
3691 LOGD("snapshot_thread X");
3692 return NULL;
3693}
3694
3695status_t QualcommCameraHardware::takePicture()
3696{
3697 LOGV("takePicture(%d)", mMsgEnabled);
3698 Mutex::Autolock l(&mLock);
3699
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003700 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
3701 mEncodePendingWaitLock.lock();
3702 while(mEncodePending) {
3703 LOGE("takePicture: Frame given to application, waiting for encode call");
3704 mEncodePendingWait.wait(mEncodePendingWaitLock);
3705 LOGE("takePicture: Encode of the application data is done");
3706 }
3707 mEncodePendingWaitLock.unlock();
3708 }
3709
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003710 // Wait for old snapshot thread to complete.
3711 mSnapshotThreadWaitLock.lock();
3712 while (mSnapshotThreadRunning) {
3713 LOGV("takePicture: waiting for old snapshot thread to complete.");
3714 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
3715 LOGV("takePicture: old snapshot thread completed.");
3716 }
3717
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07003718 if(mCurrentTarget == TARGET_MSM7627) {
3719 /* Store the last frame queued for preview. This
3720 * shall be used as postview */
3721 storePreviewFrameForPostview();
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003722 }
3723
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003724 //mSnapshotFormat is protected by mSnapshotThreadWaitLock
3725 if(mParameters.getPictureFormat() != 0 &&
3726 !strcmp(mParameters.getPictureFormat(),
3727 CameraParameters::PIXEL_FORMAT_RAW))
3728 mSnapshotFormat = PICTURE_FORMAT_RAW;
3729 else
3730 mSnapshotFormat = PICTURE_FORMAT_JPEG;
3731
3732 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3733 if(!native_prepare_snapshot(mCameraControlFd)) {
3734 mSnapshotThreadWaitLock.unlock();
3735 return UNKNOWN_ERROR;
3736 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003737 }
3738
3739 stopPreviewInternal();
3740
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003741 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3742 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
3743 LOGE("initRaw failed. Not taking picture.");
3744 mSnapshotThreadWaitLock.unlock();
3745 return UNKNOWN_ERROR;
3746 }
3747 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
3748 if(!initRawSnapshot()){
3749 LOGE("initRawSnapshot failed. Not taking picture.");
3750 mSnapshotThreadWaitLock.unlock();
3751 return UNKNOWN_ERROR;
3752 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003753 }
3754
3755 mShutterLock.lock();
3756 mShutterPending = true;
3757 mShutterLock.unlock();
3758
3759 pthread_attr_t attr;
3760 pthread_attr_init(&attr);
3761 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3762 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
3763 &attr,
3764 snapshot_thread,
3765 NULL);
3766 mSnapshotThreadWaitLock.unlock();
3767
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003768 mInSnapshotModeWaitLock.lock();
3769 mInSnapshotMode = true;
3770 mInSnapshotModeWaitLock.unlock();
3771
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003772 LOGV("takePicture: X");
3773 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
3774}
3775
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05303776void QualcommCameraHardware::set_liveshot_exifinfo()
3777{
3778 setGpsParameters();
3779 //set TimeStamp
3780 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
3781 if(str != NULL) {
3782 strncpy(dateTime, str, 19);
3783 dateTime[19] = '\0';
3784 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
3785 20, 1, (void *)dateTime);
3786 }
3787}
3788
3789status_t QualcommCameraHardware::takeLiveSnapshot()
3790{
3791 LOGV("takeLiveSnapshot: E ");
3792 Mutex::Autolock l(&mLock);
3793
3794 if(liveshot_state == LIVESHOT_IN_PROGRESS || !recordingState) {
3795 return NO_ERROR;
3796 }
3797
3798 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)) {
3799 LOGI("LiveSnapshot not supported on this target");
3800 liveshot_state = LIVESHOT_STOPPED;
3801 return NO_ERROR;
3802 }
3803
3804 liveshot_state = LIVESHOT_IN_PROGRESS;
3805
3806 if (!initLiveSnapshot(videoWidth, videoHeight)) {
3807 LOGE("takeLiveSnapshot: Jpeg Heap Memory allocation failed. Not taking Live Snapshot.");
3808 liveshot_state = LIVESHOT_STOPPED;
3809 return UNKNOWN_ERROR;
3810 }
3811
3812 uint32_t maxjpegsize = videoWidth * videoHeight *1.5;
3813 set_liveshot_exifinfo();
3814 if(!LINK_set_liveshot_params(videoWidth, videoHeight,
3815 exif_data, exif_table_numEntries,
3816 (uint8_t *)mJpegHeap->mHeap->base(), maxjpegsize)) {
3817 LOGE("Link_set_liveshot_params failed.");
3818 mJpegHeap.clear();
3819 return NO_ERROR;
3820 }
3821
3822 if(!native_start_liveshot(mCameraControlFd)) {
3823 LOGE("native_start_liveshot failed");
3824 liveshot_state = LIVESHOT_STOPPED;
3825 mJpegHeap.clear();
3826 return UNKNOWN_ERROR;
3827 }
3828
3829 LOGV("takeLiveSnapshot: X");
3830 return NO_ERROR;
3831}
3832
3833bool QualcommCameraHardware::initLiveSnapshot(int videowidth, int videoheight)
3834{
3835 LOGV("initLiveSnapshot E");
3836
3837 if (mJpegHeap != NULL) {
3838 LOGV("initLiveSnapshot: clearing old mJpegHeap.");
3839 mJpegHeap.clear();
3840 }
3841
3842 mJpegMaxSize = videowidth * videoheight * 1.5;
3843
3844 LOGV("initLiveSnapshot: initializing mJpegHeap.");
3845 mJpegHeap =
3846 new AshmemPool(mJpegMaxSize,
3847 kJpegBufferCount,
3848 0, // we do not know how big the picture will be
3849 "jpeg");
3850
3851 if (!mJpegHeap->initialized()) {
3852 mJpegHeap.clear();
3853 LOGE("initLiveSnapshot X failed: error initializing mJpegHeap.");
3854 return false;
3855 }
3856
3857 LOGV("initLiveSnapshot X");
3858 return true;
3859}
3860
3861
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003862status_t QualcommCameraHardware::cancelPicture()
3863{
3864 status_t rc;
3865 LOGV("cancelPicture: E");
Apurva Rajguru3da1a702010-07-28 12:32:42 -07003866 if (mCurrentTarget == TARGET_MSM7627) {
3867 mSnapshotDone = TRUE;
3868 mSnapshotThreadWaitLock.lock();
3869 while (mSnapshotThreadRunning) {
3870 LOGV("cancelPicture: waiting for snapshot thread to complete.");
3871 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
3872 LOGV("cancelPicture: snapshot thread completed.");
3873 }
3874 mSnapshotThreadWaitLock.unlock();
3875 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003876 rc = native_stop_snapshot(mCameraControlFd) ? NO_ERROR : UNKNOWN_ERROR;
Apurva Rajguru3da1a702010-07-28 12:32:42 -07003877 mSnapshotDone = FALSE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003878 LOGV("cancelPicture: X: %d", rc);
3879 return rc;
3880}
3881
3882status_t QualcommCameraHardware::setParameters(const CameraParameters& params)
3883{
3884 LOGV("setParameters: E params = %p", &params);
3885
3886 Mutex::Autolock l(&mLock);
3887 status_t rc, final_rc = NO_ERROR;
3888
3889 if ((rc = setPreviewSize(params))) final_rc = rc;
3890 if ((rc = setPictureSize(params))) final_rc = rc;
Srinivasan Kannan264376e2010-08-13 18:54:35 -07003891 if ((rc = setJpegThumbnailSize(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003892 if ((rc = setJpegQuality(params))) final_rc = rc;
Vamshidhar Kondrae7b9b5a2010-02-25 15:40:37 +05303893 if ((rc = setEffect(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003894 if ((rc = setGpsLocation(params))) final_rc = rc;
3895 if ((rc = setRotation(params))) final_rc = rc;
3896 if ((rc = setZoom(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003897 if ((rc = setOrientation(params))) final_rc = rc;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05303898 if ((rc = setLensshadeValue(params))) final_rc = rc;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003899 if ((rc = setPictureFormat(params))) final_rc = rc;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08003900 if ((rc = setSharpness(params))) final_rc = rc;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08003901 if ((rc = setSaturation(params))) final_rc = rc;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07003902 if ((rc = setContinuousAf(params))) final_rc = rc;
Apurva Rajgurue5965c42010-09-09 14:24:54 -07003903 if ((rc = setSelectableZoneAf(params))) final_rc = rc;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07003904 if ((rc = setTouchAfAec(params))) final_rc = rc;
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003905 if ((rc = setSceneMode(params))) final_rc = rc;
Apurva Rajguru08383852010-05-17 14:25:39 -07003906 if ((rc = setContrast(params))) final_rc = rc;
Mohan Kandra091d5ab2010-07-14 16:53:25 -07003907 if ((rc = setRecordSize(params))) final_rc = rc;
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07003908 if ((rc = setSceneDetect(params))) final_rc = rc;
Mohan Kandra7110c242010-07-18 15:34:48 -07003909 if ((rc = setStrTextures(params))) final_rc = rc;
3910 if ((rc = setPreviewFormat(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003911
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003912 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
3913 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
3914
3915 if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF)) {
3916 if ((rc = setPreviewFrameRate(params))) final_rc = rc;
3917 if ((rc = setPreviewFrameRateMode(params))) final_rc = rc;
3918 if ((rc = setAntibanding(params))) final_rc = rc;
3919 if ((rc = setAutoExposure(params))) final_rc = rc;
3920 if ((rc = setExposureCompensation(params))) final_rc = rc;
3921 if ((rc = setWhiteBalance(params))) final_rc = rc;
3922 if ((rc = setFlash(params))) final_rc = rc;
3923 if ((rc = setFocusMode(params))) final_rc = rc;
3924 if ((rc = setBrightness(params))) final_rc = rc;
3925 if ((rc = setISOValue(params))) final_rc = rc;
3926 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003927 LOGV("setParameters: X");
3928 return final_rc;
3929}
3930
3931CameraParameters QualcommCameraHardware::getParameters() const
3932{
3933 LOGV("getParameters: EX");
3934 return mParameters;
3935}
Nishant Pandit741742b2010-09-21 03:24:20 +05303936status_t QualcommCameraHardware::setHistogramOn()
3937{
3938 LOGV("setHistogramOn: EX");
3939
3940 mStatsWaitLock.lock();
3941 mSendData = true;
3942 if(mStatsOn == CAMERA_HISTOGRAM_ENABLE) {
3943 mStatsWaitLock.unlock();
3944 return NO_ERROR;
3945 }
3946
3947 if (mStatHeap != NULL) {
3948 LOGV("setHistogram on: clearing old mStatHeap.");
3949 mStatHeap.clear();
3950 }
3951
3952 mStatSize = sizeof(uint32_t)* HISTOGRAM_STATS_SIZE;
3953 mCurrent = -1;
3954 /*Currently the Ashmem is multiplying the buffer size with total number
3955 of buffers and page aligning. This causes a crash in JNI as each buffer
3956 individually expected to be page aligned */
3957 int page_size_minus_1 = getpagesize() - 1;
3958 int32_t mAlignedStatSize = ((mStatSize + page_size_minus_1) & (~page_size_minus_1));
3959
3960 mStatHeap =
3961 new AshmemPool(mAlignedStatSize,
3962 3,
3963 mStatSize,
3964 "stat");
3965 if (!mStatHeap->initialized()) {
3966 LOGE("Stat Heap X failed ");
3967 mStatHeap.clear();
3968 LOGE("setHistogramOn X: error initializing mStatHeap");
3969 mStatsWaitLock.unlock();
3970 return UNKNOWN_ERROR;
3971 }
3972 mStatsOn = CAMERA_HISTOGRAM_ENABLE;
3973
3974 mStatsWaitLock.unlock();
3975 mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn);
3976 return NO_ERROR;
3977
3978}
3979
3980status_t QualcommCameraHardware::setHistogramOff()
3981{
3982 LOGV("setHistogramOff: EX");
3983 mStatsWaitLock.lock();
3984 if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) {
3985 mStatsWaitLock.unlock();
3986 return NO_ERROR;
3987 }
3988 mStatsOn = CAMERA_HISTOGRAM_DISABLE;
3989 mStatsWaitLock.unlock();
3990
3991 mCfgControl.mm_camera_set_parm(CAMERA_PARM_HISTOGRAM, &mStatsOn);
3992
3993 mStatsWaitLock.lock();
3994 mStatHeap.clear();
3995 mStatsWaitLock.unlock();
3996
3997 return NO_ERROR;
3998}
3999
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004000
4001status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
4002 int32_t arg2)
4003{
4004 LOGV("sendCommand: EX");
Nishant Pandit741742b2010-09-21 03:24:20 +05304005 Mutex::Autolock l(&mLock);
4006
4007 switch(command) {
4008
4009 case CAMERA_CMD_HISTOGRAM_ON:
4010 LOGV("histogram set to on");
4011 return setHistogramOn();
4012 case CAMERA_CMD_HISTOGRAM_OFF:
4013 LOGV("histogram set to off");
4014 return setHistogramOff();
4015 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
4016 mStatsWaitLock.lock();
4017 if(mStatsOn == CAMERA_HISTOGRAM_ENABLE)
4018 mSendData = true;
4019 mStatsWaitLock.unlock();
4020 return NO_ERROR;
4021 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004022 return BAD_VALUE;
4023}
4024
4025extern "C" sp<CameraHardwareInterface> openCameraHardware()
4026{
Mohan Kandra0d115d12010-08-19 11:47:15 -07004027 LOGI("openCameraHardware: call createInstance");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004028 return QualcommCameraHardware::createInstance();
4029}
4030
4031wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
4032
4033// If the hardware already exists, return a strong pointer to the current
4034// object. If not, create a new hardware object, put it in the singleton,
4035// and return it.
4036sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
4037{
Mohan Kandra0d115d12010-08-19 11:47:15 -07004038 LOGI("createInstance: E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004039
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07004040 singleton_lock.lock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004041
4042 // Wait until the previous release is done.
4043 while (singleton_releasing) {
Srinivasan Kannan78444e42010-06-10 15:39:29 -07004044 if((singleton_releasing_start_time != 0) &&
4045 (systemTime() - singleton_releasing_start_time) > SINGLETON_RELEASING_WAIT_TIME){
4046 LOGV("in createinstance system time is %lld %lld %lld ",
4047 systemTime(), singleton_releasing_start_time, SINGLETON_RELEASING_WAIT_TIME);
4048 singleton_lock.unlock();
4049 LOGE("Previous singleton is busy and time out exceeded. Returning null");
4050 return NULL;
4051 }
4052 LOGI("Wait for previous release.");
4053 singleton_wait.waitRelative(singleton_lock, SINGLETON_RELEASING_RECHECK_TIMEOUT);
4054 LOGI("out of Wait for previous release.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004055 }
4056
4057 if (singleton != 0) {
4058 sp<CameraHardwareInterface> hardware = singleton.promote();
4059 if (hardware != 0) {
4060 LOGD("createInstance: X return existing hardware=%p", &(*hardware));
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07004061 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004062 return hardware;
4063 }
4064 }
4065
4066 {
4067 struct stat st;
4068 int rc = stat("/dev/oncrpc", &st);
4069 if (rc < 0) {
4070 LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07004071 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004072 return NULL;
4073 }
4074 }
4075
4076 QualcommCameraHardware *cam = new QualcommCameraHardware();
4077 sp<QualcommCameraHardware> hardware(cam);
4078 singleton = hardware;
4079
Mohan Kandra0d115d12010-08-19 11:47:15 -07004080 LOGI("createInstance: created hardware=%p", &(*hardware));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004081 if (!cam->startCamera()) {
4082 LOGE("%s: startCamera failed!", __FUNCTION__);
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07004083 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004084 return NULL;
4085 }
4086
4087 cam->initDefaultParameters();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07004088 singleton_lock.unlock();
Mohan Kandra0d115d12010-08-19 11:47:15 -07004089 LOGI("createInstance: X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004090 return hardware;
4091}
4092
4093// For internal use only, hence the strong pointer to the derived type.
4094sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
4095{
4096 sp<CameraHardwareInterface> hardware = singleton.promote();
4097 if (hardware != 0) {
4098 // LOGV("getInstance: X old instance of hardware");
4099 return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
4100 } else {
4101 LOGV("getInstance: X new instance of hardware");
4102 return sp<QualcommCameraHardware>();
4103 }
4104}
Sravankb4f5f1c2010-01-21 11:06:17 +05304105void QualcommCameraHardware::receiveRecordingFrame(struct msm_frame *frame)
4106{
4107 LOGV("receiveRecordingFrame E");
4108 // post busy frame
4109 if (frame)
4110 {
4111 cam_frame_post_video (frame);
4112 }
4113 else LOGE("in receiveRecordingFrame frame is NULL");
4114 LOGV("receiveRecordingFrame X");
4115}
4116
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004117
Mohan Kandrad9efed92010-01-15 19:08:39 -08004118bool QualcommCameraHardware::native_zoom_image(int fd, int srcOffset, int dstOffSet, common_crop_t *crop)
Mohan Kandra284966d2010-01-05 13:39:15 -08004119{
4120 int result = 0;
4121 struct mdp_blit_req *e;
4122 struct timeval td1, td2;
4123
Mohan Kandra284966d2010-01-05 13:39:15 -08004124 /* Initialize yuv structure */
4125 zoomImage.list.count = 1;
4126
4127 e = &zoomImage.list.req[0];
4128
4129 e->src.width = previewWidth;
4130 e->src.height = previewHeight;
4131 e->src.format = MDP_Y_CBCR_H2V2;
Mohan Kandrad9efed92010-01-15 19:08:39 -08004132 e->src.offset = srcOffset;
4133 e->src.memory_id = fd;
Mohan Kandra284966d2010-01-05 13:39:15 -08004134
4135 e->dst.width = previewWidth;
4136 e->dst.height = previewHeight;
4137 e->dst.format = MDP_Y_CBCR_H2V2;
Mohan Kandrad9efed92010-01-15 19:08:39 -08004138 e->dst.offset = dstOffSet;
4139 e->dst.memory_id = fd;
Mohan Kandra284966d2010-01-05 13:39:15 -08004140
4141 e->transp_mask = 0xffffffff;
4142 e->flags = 0;
4143 e->alpha = 0xff;
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07004144 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004145 e->src_rect.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
4146 e->src_rect.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
4147 e->src_rect.w = crop->in1_w;
4148 e->src_rect.h = crop->in1_h;
Mohan Kandra284966d2010-01-05 13:39:15 -08004149 } else {
4150 e->src_rect.x = 0;
4151 e->src_rect.y = 0;
4152 e->src_rect.w = previewWidth;
4153 e->src_rect.h = previewHeight;
4154 }
Mohan Kandrad9efed92010-01-15 19:08:39 -08004155 //LOGV(" native_zoom : SRC_RECT : x,y = %d,%d \t w,h = %d, %d",
4156 // e->src_rect.x, e->src_rect.y, e->src_rect.w, e->src_rect.h);
Mohan Kandra284966d2010-01-05 13:39:15 -08004157
4158 e->dst_rect.x = 0;
4159 e->dst_rect.y = 0;
4160 e->dst_rect.w = previewWidth;
4161 e->dst_rect.h = previewHeight;
4162
4163 result = ioctl(fb_fd, MSMFB_BLIT, &zoomImage.list);
4164 if (result < 0) {
4165 LOGE("MSM_FBIOBLT failed! line=%d\n", __LINE__);
4166 return FALSE;
4167 }
4168 return TRUE;
4169}
4170
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08004171void QualcommCameraHardware::debugShowPreviewFPS() const
Mohan Kandra740cfce2010-01-07 12:58:24 -08004172{
4173 static int mFrameCount;
4174 static int mLastFrameCount = 0;
4175 static nsecs_t mLastFpsTime = 0;
4176 static float mFps = 0;
4177 mFrameCount++;
4178 nsecs_t now = systemTime();
4179 nsecs_t diff = now - mLastFpsTime;
4180 if (diff > ms2ns(250)) {
4181 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08004182 LOGI("Preview Frames Per Second: %.4f", mFps);
Mohan Kandra740cfce2010-01-07 12:58:24 -08004183 mLastFpsTime = now;
4184 mLastFrameCount = mFrameCount;
4185 }
4186}
4187
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08004188void QualcommCameraHardware::debugShowVideoFPS() const
4189{
4190 static int mFrameCount;
4191 static int mLastFrameCount = 0;
4192 static nsecs_t mLastFpsTime = 0;
4193 static float mFps = 0;
4194 mFrameCount++;
4195 nsecs_t now = systemTime();
4196 nsecs_t diff = now - mLastFpsTime;
4197 if (diff > ms2ns(250)) {
4198 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
4199 LOGI("Video Frames Per Second: %.4f", mFps);
4200 mLastFpsTime = now;
4201 mLastFrameCount = mFrameCount;
4202 }
4203}
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05304204
4205void QualcommCameraHardware::receiveLiveSnapshot(uint32_t jpeg_size)
4206{
4207 LOGV("receiveLiveSnapshot E");
4208
4209#ifdef DUMP_LIVESHOT_JPEG_FILE
4210 int file_fd = open("/data/LiveSnapshot.jpg", O_RDWR | O_CREAT, 0777);
4211 LOGV("dumping live shot image in /data/LiveSnapshot.jpg");
4212 if (file_fd < 0) {
4213 LOGE("cannot open file\n");
4214 }
4215 else
4216 {
4217 write(file_fd, (uint8_t *)mJpegHeap->mHeap->base(),jpeg_size);
4218 }
4219 close(file_fd);
4220#endif
4221
4222 Mutex::Autolock cbLock(&mCallbackLock);
4223 if (mDataCallback && (mMsgEnabled & MEDIA_RECORDER_MSG_COMPRESSED_IMAGE)) {
4224 sp<MemoryBase> buffer = new
4225 MemoryBase(mJpegHeap->mHeap,
4226 0,
4227 jpeg_size);
4228 mDataCallback(MEDIA_RECORDER_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
4229 buffer = NULL;
4230 }
4231 else LOGV("JPEG callback was cancelled--not delivering image.");
4232
4233 //Reset the Gps Information & relieve memory
4234 exif_table_numEntries = 0;
4235 mJpegHeap.clear();
4236
4237 liveshot_state = LIVESHOT_DONE;
4238
4239 LOGV("receiveLiveSnapshot X");
4240}
4241
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004242void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
4243{
4244// LOGV("receivePreviewFrame E");
4245
4246 if (!mCameraRunning) {
4247 LOGE("ignoring preview callback--camera has been stopped");
4248 return;
4249 }
4250
Mohan Kandra740cfce2010-01-07 12:58:24 -08004251 if (UNLIKELY(mDebugFps)) {
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08004252 debugShowPreviewFPS();
Mohan Kandra740cfce2010-01-07 12:58:24 -08004253 }
4254
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004255 mCallbackLock.lock();
4256 int msgEnabled = mMsgEnabled;
4257 data_callback pcb = mDataCallback;
4258 void *pdata = mCallbackCookie;
4259 data_callback_timestamp rcb = mDataCallbackTimestamp;
4260 void *rdata = mCallbackCookie;
4261 mCallbackLock.unlock();
4262
4263 // Find the offset within the heap of the current buffer.
Mohan Kandra284966d2010-01-05 13:39:15 -08004264 ssize_t offset_addr =
Mohan Kandrad9efed92010-01-15 19:08:39 -08004265 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
4266 ssize_t offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
Mohan Kandra284966d2010-01-05 13:39:15 -08004267
4268 common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304269#ifdef DUMP_PREVIEW_FRAMES
4270 static int frameCnt = 0;
4271 int written;
4272 if (frameCnt >= 0 && frameCnt <= 10 ) {
4273 char buf[128];
4274 sprintf(buf, "/data/%d_preview.yuv", frameCnt);
4275 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
4276 LOGV("dumping preview frame %d", frameCnt);
4277 if (file_fd < 0) {
4278 LOGE("cannot open file\n");
4279 }
4280 else
4281 {
4282 LOGV("dumping data");
4283 written = write(file_fd, (uint8_t *)frame->buffer,
4284 mPreviewFrameSize );
4285 if(written < 0)
4286 LOGE("error in data write");
4287 }
4288 close(file_fd);
4289 }
4290 frameCnt++;
4291#endif
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004292 mInPreviewCallback = true;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08004293 if(mUseOverlay) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07004294 if(mOverlay != NULL) {
4295 mOverlayLock.lock();
Mohan Kandra54e2a022010-07-06 16:23:58 -07004296 mOverlay->setFd(mPreviewHeap->mHeap->getHeapID());
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07004297 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004298 zoomCropInfo.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
4299 zoomCropInfo.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
4300 zoomCropInfo.w = crop->in1_w;
4301 zoomCropInfo.h = crop->in1_h;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004302 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004303 zoomCropInfo.w, zoomCropInfo.h);
Mohan Kandra9aff1f42010-09-02 19:00:41 -07004304 /* Set mResetOverlayCrop to true, so that when there is
4305 * no crop information, setCrop will be called
4306 * with zero crop values.
4307 */
4308 mResetOverlayCrop = true;
4309
Apurva Rajguru905b8532010-08-02 18:29:38 -07004310 } else {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08004311 // Reset zoomCropInfo variables. This will ensure that
4312 // stale values wont be used for postview
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004313 zoomCropInfo.w = crop->in1_w;
4314 zoomCropInfo.h = crop->in1_h;
Mohan Kandra9aff1f42010-09-02 19:00:41 -07004315 /* This reset is required, if not, overlay driver continues
4316 * to use the old crop information for these preview
4317 * frames which is not the correct behavior. To avoid
4318 * multiple calls, reset once.
4319 */
4320 if(mResetOverlayCrop == true){
4321 mOverlay->setCrop(0, 0,previewWidth, previewHeight);
4322 mResetOverlayCrop = false;
4323 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08004324 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004325 mOverlay->queueBuffer((void *)offset_addr);
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08004326 mLastQueuedFrame = (void *)frame->buffer;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004327 mOverlayLock.unlock();
4328 }
Mohan Kandra284966d2010-01-05 13:39:15 -08004329 } else {
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07004330 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004331 dstOffset = (dstOffset + 1) % NUM_MORE_BUFS;
4332 offset = kPreviewBufferCount + dstOffset;
4333 ssize_t dstOffset_addr = offset * mPreviewHeap->mAlignedBufferSize;
4334 if( !native_zoom_image(mPreviewHeap->mHeap->getHeapID(),
4335 offset_addr, dstOffset_addr, crop)) {
4336 LOGE(" Error while doing MDP zoom ");
Kiran Kumar H N1ece71c2010-03-30 10:31:21 -07004337 offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004338 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004339 }
4340 if (mCurrentTarget == TARGET_MSM7627) {
4341 mLastQueuedFrame = (void *)mPreviewHeap->mBuffers[offset]->pointer();
4342 }
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08004343 }
Mohan Kandrad9efed92010-01-15 19:08:39 -08004344 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
4345 pcb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap->mBuffers[offset],
4346 pdata);
4347
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304348 // If output is NOT enabled (targets otherthan 7x30 , 8x50 and 8x60 currently..)
4349 if( (mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304350 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
4351 rcb(systemTime(), CAMERA_MSG_VIDEO_FRAME, mPreviewHeap->mBuffers[offset], rdata);
4352 Mutex::Autolock rLock(&mRecordFrameLock);
4353 if (mReleasedRecordingFrame != true) {
4354 LOGV("block waiting for frame release");
4355 mRecordWait.wait(mRecordFrameLock);
4356 LOGV("frame released, continuing");
4357 }
4358 mReleasedRecordingFrame = false;
4359 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004360 }
4361 mInPreviewCallback = false;
4362
4363// LOGV("receivePreviewFrame X");
4364}
Nishant Pandit741742b2010-09-21 03:24:20 +05304365void QualcommCameraHardware::receiveCameraStats(camstats_type stype, camera_preview_histogram_info* histinfo)
4366{
4367 // LOGV("receiveCameraStats E");
4368
4369 if (!mCameraRunning) {
4370 LOGE("ignoring stats callback--camera has been stopped");
4371 return;
4372 }
4373
4374 if(mOverlay == NULL) {
4375 return;
4376 }
4377 mCallbackLock.lock();
4378 int msgEnabled = mMsgEnabled;
4379 data_callback scb = mDataCallback;
4380 void *sdata = mCallbackCookie;
4381 mCallbackLock.unlock();
4382 mStatsWaitLock.lock();
4383 if(mStatsOn == CAMERA_HISTOGRAM_DISABLE) {
4384 mStatsWaitLock.unlock();
4385 return;
4386 }
4387 if(!mSendData) {
4388 mStatsWaitLock.unlock();
4389 } else {
4390 mSendData = false;
4391 mCurrent = (mCurrent+1)%3;
4392 // The first element of the array will contain the maximum hist value provided by driver.
4393 *(uint32_t *)(mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)) = histinfo->max_value;
4394 memcpy((uint32_t *)((unsigned int)mStatHeap->mHeap->base()+ (mStatHeap->mBufferSize * mCurrent)+ sizeof(int32_t)), (uint32_t *)histinfo->buffer,(sizeof(int32_t) * 256));
4395
4396 mStatsWaitLock.unlock();
4397
4398 if (scb != NULL && (msgEnabled & CAMERA_MSG_STATS_DATA))
4399 scb(CAMERA_MSG_STATS_DATA, mStatHeap->mBuffers[mCurrent],
4400 sdata);
4401 }
4402 // LOGV("receiveCameraStats X");
4403}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004404
Sravankb4f5f1c2010-01-21 11:06:17 +05304405
4406bool QualcommCameraHardware::initRecord()
4407{
Mohan Kandra62429cc2010-07-19 10:21:05 -07004408 const char *pmem_region;
Nishant Panditbde07612010-07-28 00:16:28 +05304409 int CbCrOffset;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004410 int recordBufferSize;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004411
Sravankb4f5f1c2010-01-21 11:06:17 +05304412 LOGV("initREcord E");
4413
Vinay Kaliaba3555f2010-07-21 11:37:36 -07004414 if(mCurrentTarget == TARGET_MSM8660)
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004415 pmem_region = "/dev/pmem_smipool";
4416 else
4417 pmem_region = "/dev/pmem_adsp";
4418
Nishant Panditbde07612010-07-28 00:16:28 +05304419 // for 8x60 the Encoder expects the CbCr offset should be aligned to 2K.
4420 if(mCurrentTarget == TARGET_MSM8660) {
4421 CbCrOffset = PAD_TO_2K(mDimension.video_width * mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004422 recordBufferSize = CbCrOffset + PAD_TO_2K((mDimension.video_width * mDimension.video_height)/2);
Nishant Panditbde07612010-07-28 00:16:28 +05304423 } else {
4424 CbCrOffset = PAD_TO_WORD(mDimension.video_width * mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004425 recordBufferSize = (mDimension.video_width * mDimension.video_height *3)/2;
Nishant Panditbde07612010-07-28 00:16:28 +05304426 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004427 LOGV("initRecord: mDimension.video_width = %d mDimension.video_height = %d",
4428 mDimension.video_width, mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004429
4430 /* Buffersize and frameSize will be different when DIS is ON.
4431 * We need to pass the actual framesize with video heap, as the same
4432 * is used at camera MIO when negotiating with encoder.
4433 */
4434 mRecordFrameSize = recordBufferSize;
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004435 if(mVpeEnabled && mDisEnabled){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004436 mRecordFrameSize = videoWidth * videoHeight * 3 / 2;
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004437 if(mCurrentTarget == TARGET_MSM8660){
4438 mRecordFrameSize = PAD_TO_2K(videoWidth * videoHeight)
4439 + PAD_TO_2K((videoWidth * videoHeight)/2);
4440 }
4441 }
4442 LOGV("mRecordFrameSize = %d", mRecordFrameSize);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004443
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004444 mRecordHeap = new PmemPool(pmem_region,
Sravankb4f5f1c2010-01-21 11:06:17 +05304445 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
4446 mCameraControlFd,
4447 MSM_PMEM_VIDEO,
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004448 recordBufferSize,
Sravankb4f5f1c2010-01-21 11:06:17 +05304449 kRecordBufferCount,
4450 mRecordFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07004451 CbCrOffset,
4452 0,
Sravankb4f5f1c2010-01-21 11:06:17 +05304453 "record");
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004454
Sravankb4f5f1c2010-01-21 11:06:17 +05304455 if (!mRecordHeap->initialized()) {
4456 mRecordHeap.clear();
4457 LOGE("initRecord X: could not initialize record heap.");
4458 return false;
4459 }
4460 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
4461 recordframes[cnt].fd = mRecordHeap->mHeap->getHeapID();
4462 recordframes[cnt].buffer =
4463 (uint32_t)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
4464 recordframes[cnt].y_off = 0;
Nishant Panditbde07612010-07-28 00:16:28 +05304465 recordframes[cnt].cbcr_off = CbCrOffset;
Sravankb4f5f1c2010-01-21 11:06:17 +05304466 recordframes[cnt].path = OUTPUT_TYPE_V;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004467 record_buffers_tracking_flag[cnt] = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304468 LOGV ("initRecord : record heap , video buffers buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
4469 (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
4470 recordframes[cnt].cbcr_off);
4471 }
4472
4473 // initial setup : buffers 1,2,3 with kernel , 4 with camframe , 5,6,7,8 in free Q
4474 // flush the busy Q
4475 cam_frame_flush_video();
4476
Mohan Kandra156d0ac2010-01-25 16:59:17 -08004477 mVideoThreadWaitLock.lock();
4478 while (mVideoThreadRunning) {
4479 LOGV("initRecord: waiting for old video thread to complete.");
4480 mVideoThreadWait.wait(mVideoThreadWaitLock);
4481 LOGV("initRecord : old video thread completed.");
4482 }
4483 mVideoThreadWaitLock.unlock();
4484
Sravankdf7a9202010-02-08 15:02:51 +05304485 // flush free queue and add 5,6,7,8 buffers.
4486 LINK_cam_frame_flush_free_video();
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004487 if(mVpeEnabled) {
4488 //If VPE is enabled, the VPE buffer shouldn't be added to Free Q initally.
4489 for(int i=ACTIVE_VIDEO_BUFFERS+1;i <kRecordBufferCount-1; i++)
4490 LINK_camframe_free_video(&recordframes[i]);
4491 } else {
4492 for(int i=ACTIVE_VIDEO_BUFFERS+1;i <kRecordBufferCount; i++)
4493 LINK_camframe_free_video(&recordframes[i]);
4494 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304495 LOGV("initREcord X");
4496
4497 return true;
4498}
4499
Mohan Kandracedd6cc2010-09-14 14:37:08 -07004500
4501status_t QualcommCameraHardware::setDIS() {
4502 LOGV("setDIS E");
4503
4504 video_dis_param_ctrl_t disCtrl;
4505 bool ret = true;
4506 LOGI("mDisEnabled = %d", mDisEnabled);
4507
4508 int video_frame_cbcroffset;
4509 video_frame_cbcroffset = PAD_TO_WORD(videoWidth * videoHeight);
4510 if(mCurrentTarget == TARGET_MSM8660)
4511 video_frame_cbcroffset = PAD_TO_2K(videoWidth * videoHeight);
4512
4513 disCtrl.dis_enable = mDisEnabled;
4514 disCtrl.video_rec_width = videoWidth;
4515 disCtrl.video_rec_height = videoHeight;
4516 disCtrl.output_cbcr_offset = video_frame_cbcroffset;
4517
4518 ret = native_set_parm(CAMERA_SET_VIDEO_DIS_PARAMS,
4519 sizeof(disCtrl), &disCtrl);
4520 LOGV("setDIS X (%d)", ret);
4521 return ret ? NO_ERROR : UNKNOWN_ERROR;
4522}
4523
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004524status_t QualcommCameraHardware::setVpeParameters()
4525{
4526 LOGV("setVpeParameters E");
4527
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004528 video_rotation_param_ctrl_t rotCtrl;
Mohan Kandraec958742010-08-19 10:56:05 -07004529 bool ret = true;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004530 LOGV("videoWidth = %d, videoHeight = %d", videoWidth, videoHeight);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004531 rotCtrl.rotation = (mRotation == 0) ? ROT_NONE :
4532 ((mRotation == 90) ? ROT_CLOCKWISE_90 :
4533 ((mRotation == 180) ? ROT_CLOCKWISE_180 : ROT_CLOCKWISE_270));
4534
Mohan Kandraec958742010-08-19 10:56:05 -07004535 if( ((videoWidth == 1280 && videoHeight == 720) || (videoWidth == 800 && videoHeight == 480))
4536 && (mRotation == 90 || mRotation == 270) ){
4537 /* Due to a limitation at video core to support heights greater than 720, adding this check.
4538 * This is a temporary hack, need to be removed once video core support is available
4539 */
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004540 LOGI("video resolution (%dx%d) with rotation (%d) is not supported, setting rotation to NONE",
Mohan Kandraec958742010-08-19 10:56:05 -07004541 videoWidth, videoHeight, mRotation);
4542 rotCtrl.rotation = ROT_NONE;
Mohan Kandraec958742010-08-19 10:56:05 -07004543 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004544 LOGV("rotCtrl.rotation = %d", rotCtrl.rotation);
4545
4546 ret = native_set_parm(CAMERA_SET_VIDEO_ROT_PARAMS,
4547 sizeof(rotCtrl), &rotCtrl);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004548
4549 LOGV("setVpeParameters X (%d)", ret);
4550 return ret ? NO_ERROR : UNKNOWN_ERROR;
4551}
4552
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004553status_t QualcommCameraHardware::startRecording()
4554{
4555 LOGV("startRecording E");
Sravankb4f5f1c2010-01-21 11:06:17 +05304556 int ret;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004557 Mutex::Autolock l(&mLock);
4558 mReleasedRecordingFrame = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304559 if( (ret=startPreviewInternal())== NO_ERROR){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004560 if(mVpeEnabled){
4561 LOGI("startRecording: VPE enabled, setting vpe parameters");
4562 bool status = setVpeParameters();
4563 if(status) {
4564 LOGE("Failed to set VPE parameters");
4565 return status;
4566 }
4567 }
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304568 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304569 LOGV(" in startREcording : calling native_start_recording");
4570 native_start_recording(mCameraControlFd);
4571 recordingState = 1;
Sravank64461e82010-02-25 15:10:09 +05304572 // Remove the left out frames in busy Q and them in free Q.
4573 // this should be done before starting video_thread so that,
4574 // frames in previous recording are flushed out.
4575 LOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames);
4576 while((g_busy_frame_queue.num_of_frames) >0){
4577 msm_frame* vframe = cam_frame_get_video ();
4578 LINK_camframe_free_video(vframe);
4579 }
4580 LOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames);
4581
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004582 //Clear the dangling buffers and put them in free queue
4583 for(int cnt = 0; cnt < kRecordBufferCount; cnt++) {
4584 if(record_buffers_tracking_flag[cnt] == true) {
Mohan Kandra62429cc2010-07-19 10:21:05 -07004585 LOGI("Dangling buffer: offset = %d, buffer = %d", cnt, (unsigned int)recordframes[cnt].buffer);
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004586 LINK_camframe_free_video(&recordframes[cnt]);
4587 record_buffers_tracking_flag[cnt] = false;
4588 }
4589 }
4590
Sravankdf7a9202010-02-08 15:02:51 +05304591 // Start video thread and wait for busy frames to be encoded, this thread
4592 // should be closed in stopRecording
4593 mVideoThreadWaitLock.lock();
4594 mVideoThreadExit = 0;
4595 pthread_attr_t attr;
4596 pthread_attr_init(&attr);
4597 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4598 mVideoThreadRunning = pthread_create(&mVideoThread,
4599 &attr,
4600 video_thread,
4601 NULL);
4602 mVideoThreadWaitLock.unlock();
4603 // Remove the left out frames in busy Q and them in free Q.
Sravankb4f5f1c2010-01-21 11:06:17 +05304604 }
4605 }
4606 return ret;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004607}
4608
4609void QualcommCameraHardware::stopRecording()
4610{
4611 LOGV("stopRecording: E");
4612 Mutex::Autolock l(&mLock);
4613 {
4614 mRecordFrameLock.lock();
4615 mReleasedRecordingFrame = true;
4616 mRecordWait.signal();
4617 mRecordFrameLock.unlock();
4618
Sravankdf7a9202010-02-08 15:02:51 +05304619 if(mDataCallback && !(mCurrentTarget == TARGET_QSD8250) &&
4620 (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004621 LOGV("stopRecording: X, preview still in progress");
4622 return;
4623 }
4624 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304625 // If output2 enabled, exit video thread, invoke stop recording ioctl
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304626 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304627 mVideoThreadWaitLock.lock();
4628 mVideoThreadExit = 1;
4629 mVideoThreadWaitLock.unlock();
4630 native_stop_recording(mCameraControlFd);
Srinivasan Kannanfc3915c2010-03-18 10:54:40 -07004631
4632 pthread_mutex_lock(&(g_busy_frame_queue.mut));
4633 pthread_cond_signal(&(g_busy_frame_queue.wait));
4634 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Sravankb4f5f1c2010-01-21 11:06:17 +05304635 }
4636 else // for other targets where output2 is not enabled
4637 stopPreviewInternal();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004638
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05304639 if (mJpegHeap != NULL) {
4640 LOGV("stopRecording: clearing old mJpegHeap.");
4641 mJpegHeap.clear();
4642 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304643 recordingState = 0; // recording not started
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004644 LOGV("stopRecording: X");
4645}
4646
4647void QualcommCameraHardware::releaseRecordingFrame(
4648 const sp<IMemory>& mem __attribute__((unused)))
4649{
4650 LOGV("releaseRecordingFrame E");
4651 Mutex::Autolock rLock(&mRecordFrameLock);
4652 mReleasedRecordingFrame = true;
4653 mRecordWait.signal();
Sravankb4f5f1c2010-01-21 11:06:17 +05304654
4655 // Ff 7x30 : add the frame to the free camframe queue
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304656 if( (mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304657 ssize_t offset;
4658 size_t size;
4659 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
4660 msm_frame* releaseframe = NULL;
4661 LOGV(" in release recording frame : heap base %d offset %d buffer %d ", heap->base(), offset, heap->base() + offset );
4662 int cnt;
4663 for (cnt = 0; cnt < kRecordBufferCount; cnt++) {
Mohan Kandra62429cc2010-07-19 10:21:05 -07004664 if((unsigned int)recordframes[cnt].buffer == ((unsigned int)heap->base()+ offset)){
Sravankb4f5f1c2010-01-21 11:06:17 +05304665 LOGV("in release recording frame found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer);
4666 releaseframe = &recordframes[cnt];
4667 break;
4668 }
4669 }
4670 if(cnt < kRecordBufferCount) {
4671 // do this only if frame thread is running
4672 mFrameThreadWaitLock.lock();
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004673 if(mFrameThreadRunning ) {
4674 //Reset the track flag for this frame buffer
4675 record_buffers_tracking_flag[cnt] = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304676 LINK_camframe_free_video(releaseframe);
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004677 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304678
4679 mFrameThreadWaitLock.unlock();
4680 } else {
4681 LOGE("in release recordingframe XXXXX error , buffer not found");
4682 for (int i=0; i< kRecordBufferCount; i++) {
4683 LOGE(" recordframes[%d].buffer = %d", i, (unsigned int)recordframes[i].buffer);
4684 }
4685 }
4686 }
4687
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004688 LOGV("releaseRecordingFrame X");
4689}
4690
4691bool QualcommCameraHardware::recordingEnabled()
4692{
4693 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
4694}
4695
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004696void QualcommCameraHardware::notifyShutter(common_crop_t *crop, bool mPlayShutterSoundOnly)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004697{
4698 mShutterLock.lock();
4699 image_rect_type size;
4700
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004701 if(mPlayShutterSoundOnly) {
4702 /* At this point, invoke Notify Callback to play shutter sound only.
4703 * We want to call notify callback again when we have the
4704 * yuv picture ready. This is to reduce blanking at the time
4705 * of displaying postview frame. Using ext2 to indicate whether
4706 * to play shutter sound only or register the postview buffers.
4707 */
4708 mNotifyCallback(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly,
4709 mCallbackCookie);
4710 mShutterLock.unlock();
4711 return;
4712 }
4713
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004714 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
4715 LOGV("out2_w=%d, out2_h=%d, in2_w=%d, in2_h=%d",
4716 crop->out2_w, crop->out2_h, crop->in2_w, crop->in2_h);
4717 LOGV("out1_w=%d, out1_h=%d, in1_w=%d, in1_h=%d",
4718 crop->out1_w, crop->out1_h, crop->in1_w, crop->in1_h);
4719
4720 // To workaround a bug in MDP which happens if either
4721 // dimension > 2048, we display the thumbnail instead.
Apurva Rajguru905b8532010-08-02 18:29:38 -07004722
4723 if (mCurrentTarget == TARGET_MSM7627)
4724 mDisplayHeap = mPostViewHeap;
4725 else
4726 mDisplayHeap = mRawHeap;
4727
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004728 if (crop->in1_w == 0 || crop->in1_h == 0) {
4729 // Full size
4730 size.width = mDimension.picture_width;
4731 size.height = mDimension.picture_height;
4732 if (size.width > 2048 || size.height > 2048) {
4733 size.width = mDimension.ui_thumbnail_width;
4734 size.height = mDimension.ui_thumbnail_height;
4735 mDisplayHeap = mThumbnailHeap;
4736 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004737 else {
4738 if (mCurrentTarget == TARGET_MSM7627) {
4739 size.width = previewWidth;
4740 size.height = previewHeight;
4741 }
4742 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004743 } else {
4744 // Cropped
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004745 size.width = (crop->in2_w + jpegPadding) & ~1;
4746 size.height = (crop->in2_h + jpegPadding) & ~1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004747 if (size.width > 2048 || size.height > 2048) {
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004748 size.width = (crop->in1_w + jpegPadding) & ~1;
4749 size.height = (crop->in1_h + jpegPadding) & ~1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004750 mDisplayHeap = mThumbnailHeap;
4751 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004752 else {
4753 if (mCurrentTarget == TARGET_MSM7627) {
4754 size.width = previewWidth;
4755 size.height = previewHeight;
4756 }
4757 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004758 }
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004759 //We need to create overlay with dimensions that the VFE output
4760 //is configured for post view.
4761 if((mCurrentTarget == TARGET_MSM7630) ||
4762 (mCurrentTarget == TARGET_MSM8660)) {
4763 size.width = mDimension.ui_thumbnail_width;
4764 size.height = mDimension.ui_thumbnail_height;
4765 //Make ThumbnailHeap as Displayheap for post view.
4766 mDisplayHeap = mThumbnailHeap;
4767 }
4768
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004769 //For Adreno format, we need to pass the main image in all the cases.
4770 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)
4771 mDisplayHeap = mRawHeap;
4772
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004773 /* Now, invoke Notify Callback to unregister preview buffer
4774 * and register postview buffer with surface flinger. Set ext2
4775 * as 0 to indicate not to play shutter sound.
4776 */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004777 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
4778 mCallbackCookie);
4779 mShutterPending = false;
4780 }
4781 mShutterLock.unlock();
4782}
4783
4784static void receive_shutter_callback(common_crop_t *crop)
4785{
4786 LOGV("receive_shutter_callback: E");
4787 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
4788 if (obj != 0) {
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004789 /* Just play shutter sound at this time */
4790 obj->notifyShutter(crop, TRUE);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004791 }
4792 LOGV("receive_shutter_callback: X");
4793}
4794
4795// Crop the picture in place.
4796static void crop_yuv420(uint32_t width, uint32_t height,
4797 uint32_t cropped_width, uint32_t cropped_height,
Apurva Rajguru905b8532010-08-02 18:29:38 -07004798 uint8_t *image, const char *name)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004799{
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004800 int32_t i;
4801 uint32_t x, y;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004802 uint8_t* chroma_src, *chroma_dst;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004803 int yOffsetSrc, yOffsetDst, CbCrOffsetSrc, CbCrOffsetDst;
4804 int mSrcSize, mDstSize;
4805
4806 //check if all fields needed eg. size and also how to set y offset. If condition for 7x27
4807 //and need to check if needed for 7x30.
4808
4809 LINK_jpeg_encoder_get_buffer_offset(width, height, (uint32_t *)&yOffsetSrc,
4810 (uint32_t *)&CbCrOffsetSrc, (uint32_t *)&mSrcSize);
4811
4812 LINK_jpeg_encoder_get_buffer_offset(cropped_width, cropped_height, (uint32_t *)&yOffsetDst,
4813 (uint32_t *)&CbCrOffsetDst, (uint32_t *)&mDstSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004814
4815 // Calculate the start position of the cropped area.
4816 x = (width - cropped_width) / 2;
4817 y = (height - cropped_height) / 2;
4818 x &= ~1;
4819 y &= ~1;
4820
Apurva Rajguru905b8532010-08-02 18:29:38 -07004821 if((mCurrentTarget == TARGET_MSM7627)
Priyanka Kharat32409f72010-08-25 18:11:03 -07004822 || (mCurrentTarget == TARGET_MSM7630)
4823 || (mCurrentTarget == TARGET_MSM8660)) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07004824 if (!strcmp("snapshot camera", name)) {
4825 chroma_src = image + CbCrOffsetSrc;
4826 chroma_dst = image + CbCrOffsetDst;
4827 } else {
4828 chroma_src = image + width * height;
4829 chroma_dst = image + cropped_width * cropped_height;
Apurva Rajgurubfc04522010-08-11 16:22:25 -07004830 yOffsetSrc = 0;
4831 yOffsetDst = 0;
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004832 CbCrOffsetSrc = width * height;
4833 CbCrOffsetDst = cropped_width * cropped_height;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004834 }
4835 } else {
4836 chroma_src = image + CbCrOffsetSrc;
4837 chroma_dst = image + CbCrOffsetDst;
4838 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004839
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004840 int32_t bufDst = yOffsetDst;
4841 int32_t bufSrc = yOffsetSrc + (width * y) + x;
4842
4843 if( bufDst > bufSrc ){
4844 LOGV("crop yuv Y destination position follows source position");
4845 /*
4846 * If buffer destination follows buffer source, memcpy
4847 * of lines will lead to overwriting subsequent lines. In order
4848 * to prevent this, reverse copying of lines is performed
4849 * for the set of lines where destination follows source and
4850 * forward copying of lines is performed for lines where source
4851 * follows destination. To calculate the position to switch,
4852 * the initial difference between source and destination is taken
4853 * and divided by difference between width and cropped width. For
4854 * every line copied the difference between source destination
4855 * drops by width - cropped width
4856 */
4857 //calculating inversion
4858 int position = ( bufDst - bufSrc ) / (width - cropped_width);
4859 // Copy luma component.
4860 for(i=position+1; i < cropped_height; i++){
4861 memmove(image + yOffsetDst + i * cropped_width,
4862 image + yOffsetSrc + width * (y + i) + x,
4863 cropped_width);
4864 }
4865 for(i=position; i>=0; i--){
4866 memmove(image + yOffsetDst + i * cropped_width,
4867 image + yOffsetSrc + width * (y + i) + x,
4868 cropped_width);
4869 }
4870 } else {
4871 // Copy luma component.
4872 for(i = 0; i < cropped_height; i++)
4873 memcpy(image + yOffsetDst + i * cropped_width,
4874 image + yOffsetSrc + width * (y + i) + x,
4875 cropped_width);
4876 }
4877
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004878 // Copy chroma components.
4879 cropped_height /= 2;
4880 y /= 2;
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004881
4882 bufDst = CbCrOffsetDst;
4883 bufSrc = CbCrOffsetSrc + (width * y) + x;
4884
4885 if( bufDst > bufSrc ) {
4886 LOGV("crop yuv Chroma destination position follows source position");
4887 /*
4888 * Similar to y
4889 */
4890 int position = ( bufDst - bufSrc ) / (width - cropped_width);
4891 for(i=position+1; i < cropped_height; i++){
4892 memmove(chroma_dst + i * cropped_width,
4893 chroma_src + width * (y + i) + x,
4894 cropped_width);
4895 }
4896 for(i=position; i >=0; i--){
4897 memmove(chroma_dst + i * cropped_width,
4898 chroma_src + width * (y + i) + x,
4899 cropped_width);
4900 }
4901 } else {
4902 for(i = 0; i < cropped_height; i++)
4903 memcpy(chroma_dst + i * cropped_width,
4904 chroma_src + width * (y + i) + x,
4905 cropped_width);
4906 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004907}
4908
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004909void QualcommCameraHardware::receiveRawSnapshot(){
4910 LOGV("receiveRawSnapshot E");
4911
4912 Mutex::Autolock cbLock(&mCallbackLock);
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004913 /* Issue notifyShutter with mPlayShutterSoundOnly as TRUE */
4914 notifyShutter(&mCrop, TRUE);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004915
4916 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4917
4918 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
4919 LOGE("receiveRawSnapshot X: native_get_picture failed!");
4920 return;
4921 }
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004922 /* Its necessary to issue another notifyShutter here with
4923 * mPlayShutterSoundOnly as FALSE, since that is when the
4924 * preview buffers are unregistered with the surface flinger.
4925 * That is necessary otherwise the preview memory wont be
4926 * deallocated.
4927 */
4928 notifyShutter(&mCrop, FALSE);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004929
4930 //Create a Ashmem heap to copy data from PMem heap for application layer
4931 if(mRawSnapshotAshmemHeap != NULL){
4932 LOGV("receiveRawSnapshot: clearing old mRawSnapShotAshmemHeap.");
4933 mRawSnapshotAshmemHeap.clear();
4934 }
4935 mRawSnapshotAshmemHeap = new AshmemPool(
4936 mRawSnapShotPmemHeap->mBufferSize,
4937 mRawSnapShotPmemHeap->mNumBuffers,
4938 mRawSnapShotPmemHeap->mFrameSize,
4939 "raw ashmem snapshot camera"
4940 );
4941
4942 if(!mRawSnapshotAshmemHeap->initialized()){
4943 LOGE("receiveRawSnapshot X: error initializing mRawSnapshotHeap");
4944 deinitRawSnapshot();
4945 return;
4946 }
4947
4948 memcpy(mRawSnapshotAshmemHeap->mHeap->base(),
4949 mRawSnapShotPmemHeap->mHeap->base(),
4950 mRawSnapShotPmemHeap->mHeap->getSize());
Nishant Panditb861be52010-03-02 16:43:49 +05304951 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))
4952 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mRawSnapshotAshmemHeap->mBuffers[0],
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004953 mCallbackCookie);
4954
4955 }
4956
4957 //cleanup
4958 deinitRawSnapshot();
4959
4960 LOGV("receiveRawSnapshot X");
4961}
4962
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004963void QualcommCameraHardware::receiveRawPicture()
4964{
4965 LOGV("receiveRawPicture: E");
4966
4967 Mutex::Autolock cbLock(&mCallbackLock);
Apurva Rajguru3da1a702010-07-28 12:32:42 -07004968 if (mDataCallback && ((mMsgEnabled & CAMERA_MSG_RAW_IMAGE) || mSnapshotDone)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004969 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
4970 LOGE("getPicture failed!");
4971 return;
4972 }
Apurva Rajguru3da1a702010-07-28 12:32:42 -07004973 mSnapshotDone = FALSE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004974 mCrop.in1_w &= ~1;
4975 mCrop.in1_h &= ~1;
4976 mCrop.in2_w &= ~1;
4977 mCrop.in2_h &= ~1;
4978
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004979
4980 // Crop the image if zoomed.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004981 if (mCrop.in2_w != 0 && mCrop.in2_h != 0 &&
4982 ((mCrop.in2_w + jpegPadding) < mCrop.out2_w) &&
4983 ((mCrop.in2_h + jpegPadding) < mCrop.out2_h) &&
4984 ((mCrop.in1_w + jpegPadding) < mCrop.out1_w) &&
4985 ((mCrop.in1_h + jpegPadding) < mCrop.out1_h) ) {
4986
4987 // By the time native_get_picture returns, picture is taken. Call
4988 // shutter callback if cam config thread has not done that.
4989 notifyShutter(&mCrop, FALSE);
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004990 {
4991 Mutex::Autolock l(&mRawPictureHeapLock);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004992 if(mRawHeap != NULL){
4993 crop_yuv420(mCrop.out2_w, mCrop.out2_h, (mCrop.in2_w + jpegPadding), (mCrop.in2_h + jpegPadding),
Apurva Rajguru905b8532010-08-02 18:29:38 -07004994 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mName);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07004995 }
4996 if( (mThumbnailHeap != NULL) &&
4997 (mCurrentTarget != TARGET_MSM7630) &&
4998 (mCurrentTarget != TARGET_MSM8660) ) {
4999 //Don't crop the mThumbnailHeap for 7630. As this heap
5000 //is used for postview rather than for thumbnail. (thumbnail is generated from main image).
5001 //overlay's setCrop will take of cropping while displaying postview.
Srinivasan Kannan426cde72010-06-04 09:37:21 -07005002 crop_yuv420(mCrop.out1_w, mCrop.out1_h, (mCrop.in1_w + jpegPadding), (mCrop.in1_h + jpegPadding),
Apurva Rajguru905b8532010-08-02 18:29:38 -07005003 (uint8_t *)mThumbnailHeap->mHeap->base(), mThumbnailHeap->mName);
5004 }
Srinivasan Kannan426cde72010-06-04 09:37:21 -07005005 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07005006
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005007 // We do not need jpeg encoder to upscale the image. Set the new
5008 // dimension for encoder.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07005009 mDimension.orig_picture_dx = mCrop.in2_w + jpegPadding;
5010 mDimension.orig_picture_dy = mCrop.in2_h + jpegPadding;
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07005011 /* Don't update the thumbnail_width/height, if jpeg downscaling
5012 * is used to generate thumbnail. These parameters should contain
5013 * the original thumbnail dimensions.
5014 */
5015 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
5016 mDimension.thumbnail_width = mCrop.in1_w + jpegPadding;
5017 mDimension.thumbnail_height = mCrop.in1_h + jpegPadding;
5018 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07005019 }else {
5020 memset(&mCrop, 0 ,sizeof(mCrop));
5021 // By the time native_get_picture returns, picture is taken. Call
5022 // shutter callback if cam config thread has not done that.
5023 notifyShutter(&mCrop, FALSE);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005024 }
5025
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07005026 if( mUseOverlay && (mOverlay != NULL) ) {
5027 mOverlay->setFd(mDisplayHeap->mHeap->getHeapID());
5028 int cropX = 0;
5029 int cropY = 0;
5030 int cropW = 0;
5031 int cropH = 0;
5032 //Caculate the crop dimensions from mCrop.
5033 //mCrop will have the crop dimensions for VFE's
5034 //postview output.
5035 if (mCrop.in1_w != 0 || mCrop.in1_h != 0) {
5036 cropX = (mCrop.out1_w - mCrop.in1_w + 1) / 2 - 1;
5037 cropY = (mCrop.out1_h - mCrop.in1_h + 1) / 2 - 1;
5038 cropW = mCrop.in1_w;
5039 cropH = mCrop.in1_h;
5040 mOverlay->setCrop(cropX, cropY, cropW, cropH);
5041 }
5042 LOGV(" Queueing Postview for display ");
5043 mOverlay->queueBuffer((void *)0);
5044 }
5045 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE))
5046 mDataCallback(CAMERA_MSG_RAW_IMAGE, mDisplayHeap->mBuffers[0],
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005047 mCallbackCookie);
Mohan Kandra5e4f9d92010-08-26 18:23:50 -07005048 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
5049 LOGI("Raw Data given to app for processing...will wait for jpeg encode call");
5050 mEncodePendingWaitLock.lock();
5051 mEncodePending = true;
5052 mEncodePendingWaitLock.unlock();
5053 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005054 }
5055 else LOGV("Raw-picture callback was canceled--skipping.");
5056
Mohan Kandra1659b0c2010-07-18 16:36:25 -07005057 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
5058 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
5059 mJpegSize = 0;
5060 mJpegThreadWaitLock.lock();
5061 if (LINK_jpeg_encoder_init()) {
5062 mJpegThreadRunning = true;
5063 mJpegThreadWaitLock.unlock();
5064 if(native_jpeg_encode()) {
5065 LOGV("receiveRawPicture: X (success)");
5066 return;
5067 }
5068 LOGE("jpeg encoding failed");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005069 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07005070 else {
5071 LOGE("receiveRawPicture X: jpeg_encoder_init failed.");
5072 mJpegThreadWaitLock.unlock();
5073 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005074 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07005075 else LOGV("JPEG callback is NULL, not encoding image.");
5076 deinitRaw();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005077 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005078 LOGV("receiveRawPicture: X");
5079}
5080
5081void QualcommCameraHardware::receiveJpegPictureFragment(
5082 uint8_t *buff_ptr, uint32_t buff_size)
5083{
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05305084 LOGV("receiveJpegPictureFragment size %d", buff_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005085 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
5086 remaining -= mJpegSize;
5087 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
5088
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005089 if (buff_size > remaining) {
5090 LOGE("receiveJpegPictureFragment: size %d exceeds what "
5091 "remains in JPEG heap (%d), truncating",
5092 buff_size,
5093 remaining);
5094 buff_size = remaining;
5095 }
5096 memcpy(base + mJpegSize, buff_ptr, buff_size);
5097 mJpegSize += buff_size;
5098}
5099
5100void QualcommCameraHardware::receiveJpegPicture(void)
5101{
5102 LOGV("receiveJpegPicture: E image (%d uint8_ts out of %d)",
5103 mJpegSize, mJpegHeap->mBufferSize);
5104 Mutex::Autolock cbLock(&mCallbackLock);
5105
5106 int index = 0, rc;
5107
5108 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
5109 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
5110 // that the JPEG image's size will probably change from one snapshot
5111 // to the next, so we cannot reuse the MemoryBase object.
5112 sp<MemoryBase> buffer = new
5113 MemoryBase(mJpegHeap->mHeap,
5114 index * mJpegHeap->mBufferSize +
5115 0,
5116 mJpegSize);
5117 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
5118 buffer = NULL;
5119 }
5120 else LOGV("JPEG callback was cancelled--not delivering image.");
5121
Mohan Kandraca2e7a92010-06-21 15:48:45 -07005122 mJpegThreadWaitLock.lock();
5123 mJpegThreadRunning = false;
5124 mJpegThreadWait.signal();
5125 mJpegThreadWaitLock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005126
5127 LOGV("receiveJpegPicture: X callback done.");
5128}
5129
5130bool QualcommCameraHardware::previewEnabled()
5131{
Kiran Kumar H N280d4de2010-05-05 13:40:15 -07005132 /* If overlay is used the message CAMERA_MSG_PREVIEW_FRAME would
5133 * be disabled at CameraService layer. Hence previewEnabled would
5134 * return FALSE even though preview is running. Hence check for
5135 * mOverlay not being NULL to ensure that previewEnabled returns
5136 * accurate information.
5137 */
5138 return mCameraRunning && mDataCallback &&
5139 ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) || (mOverlay != NULL));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005140}
Mohan Kandra091d5ab2010-07-14 16:53:25 -07005141status_t QualcommCameraHardware::setRecordSize(const CameraParameters& params)
5142{
5143 int width, height;
5144 const char *str = params.get("record-size");
5145 if(str) {
5146 LOGV("Requested Record size %s", str);
5147 mParameters.set("record-size" , str);
5148 } else {
5149 //set the record-size value to null.
5150 //This is required as the application can request
5151 //to reset this value, so that it won't be carried
5152 //when switched to camera.
5153 mParameters.set("record-size", "");
5154 }
5155 return NO_ERROR;
5156}
5157
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005158
5159status_t QualcommCameraHardware::setPreviewSize(const CameraParameters& params)
5160{
5161 int width, height;
5162 params.getPreviewSize(&width, &height);
5163 LOGV("requested preview size %d x %d", width, height);
5164
5165 // Validate the preview size
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08005166 for (size_t i = 0; i < previewSizeCount; ++i) {
5167 if (width == supportedPreviewSizes[i].width
5168 && height == supportedPreviewSizes[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005169 mParameters.setPreviewSize(width, height);
Mohan Kandra091d5ab2010-07-14 16:53:25 -07005170 mDimension.display_width = width;
5171 mDimension.display_height= height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005172 return NO_ERROR;
5173 }
5174 }
5175 LOGE("Invalid preview size requested: %dx%d", width, height);
5176 return BAD_VALUE;
5177}
5178
Srinivasan Kannana01751b2010-06-24 18:44:40 -07005179status_t QualcommCameraHardware::setPreviewFrameRate(const CameraParameters& params)
5180{
Mohan Kandraf7341b92010-09-21 12:00:50 -07005181 if(!strcmp(sensorType->name, "2mp")){
Srinivasan Kannan2c99dba2010-07-28 13:50:53 -07005182 LOGI("set fps is not supported for this sensor");
5183 return NO_ERROR;
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07005184 }
Srinivasan Kannana01751b2010-06-24 18:44:40 -07005185 uint16_t previousFps = (uint16_t)mParameters.getPreviewFrameRate();
5186 uint16_t fps = (uint16_t)params.getPreviewFrameRate();
5187 LOGV("requested preview frame rate is %u", fps);
5188
5189 if(mInitialized && (fps == previousFps)){
5190 LOGV("fps same as previous fps");
5191 return NO_ERROR;
5192 }
5193
5194 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
5195 mParameters.setPreviewFrameRate(fps);
5196 bool ret = native_set_parm(CAMERA_SET_PARM_FPS,
5197 sizeof(fps), (void *)&fps);
5198 return ret ? NO_ERROR : UNKNOWN_ERROR;
5199 }
5200 return BAD_VALUE;
Mohan Kandrabf6146d2010-07-20 18:48:37 -07005201}
Srinivasan Kannana01751b2010-06-24 18:44:40 -07005202
Mohan Kandrabf6146d2010-07-20 18:48:37 -07005203status_t QualcommCameraHardware::setPreviewFrameRateMode(const CameraParameters& params) {
Mohan Kandraf7341b92010-09-21 12:00:50 -07005204 if(!strcmp(sensorType->name, "2mp")){
Mohan Kandrabf6146d2010-07-20 18:48:37 -07005205 LOGI("set fps mode is not supported for this sensor");
5206 return NO_ERROR;
5207 }
5208 const char *previousMode = mParameters.getPreviewFrameRateMode();
5209 const char *str = params.getPreviewFrameRateMode();
5210 if( mInitialized && !strcmp(previousMode, str)) {
5211 LOGV("frame rate mode same as previous mode %s", previousMode);
5212 return NO_ERROR;
5213 }
5214 int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str);
5215 if(frameRateMode != NOT_FOUND) {
5216 LOGV("setPreviewFrameRateMode: %s ", str);
5217 mParameters.setPreviewFrameRateMode(str);
5218 bool ret = native_set_parm(CAMERA_SET_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode);
5219 if(!ret) return ret;
5220 //set the fps value when chaging modes
5221 int16_t fps = (uint16_t)params.getPreviewFrameRate();
5222 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
5223 mParameters.setPreviewFrameRate(fps);
5224 ret = native_set_parm(CAMERA_SET_PARM_FPS,
5225 sizeof(fps), (void *)&fps);
5226 return ret ? NO_ERROR : UNKNOWN_ERROR;
5227 }
5228 LOGI("Invalid preview frame rate value: %d", fps);
5229 return BAD_VALUE;
5230 }
5231 LOGI("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str);
5232 return BAD_VALUE;
Srinivasan Kannana01751b2010-06-24 18:44:40 -07005233}
5234
Srinivasan Kannan264376e2010-08-13 18:54:35 -07005235status_t QualcommCameraHardware::setJpegThumbnailSize(const CameraParameters& params){
5236 int width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
5237 int height = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
5238 LOGV("requested jpeg thumbnail size %d x %d", width, height);
5239
5240 // Validate the picture size
5241 for (int i = 0; i < JPEG_THUMBNAIL_SIZE_COUNT; ++i) {
5242 if (width == jpeg_thumbnail_sizes[i].width
5243 && height == jpeg_thumbnail_sizes[i].height) {
5244 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
5245 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
5246 return NO_ERROR;
5247 }
5248 }
5249 return BAD_VALUE;
5250}
5251
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005252status_t QualcommCameraHardware::setPictureSize(const CameraParameters& params)
5253{
5254 int width, height;
5255 params.getPictureSize(&width, &height);
5256 LOGV("requested picture size %d x %d", width, height);
5257
5258 // Validate the picture size
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08005259 for (int i = 0; i < supportedPictureSizesCount; ++i) {
5260 if (width == picture_sizes_ptr[i].width
5261 && height == picture_sizes_ptr[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005262 mParameters.setPictureSize(width, height);
5263 mDimension.picture_width = width;
5264 mDimension.picture_height = height;
5265 return NO_ERROR;
5266 }
5267 }
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08005268 /* Dimension not among the ones in the list. Check if
5269 * its a valid dimension, if it is, then configure the
5270 * camera accordingly. else reject it.
5271 */
5272 if( isValidDimension(width, height) ) {
5273 mParameters.setPictureSize(width, height);
5274 mDimension.picture_width = width;
5275 mDimension.picture_height = height;
5276 return NO_ERROR;
5277 } else
5278 LOGE("Invalid picture size requested: %dx%d", width, height);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005279 return BAD_VALUE;
5280}
5281
5282status_t QualcommCameraHardware::setJpegQuality(const CameraParameters& params) {
5283 status_t rc = NO_ERROR;
5284 int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
5285 if (quality > 0 && quality <= 100) {
5286 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
5287 } else {
5288 LOGE("Invalid jpeg quality=%d", quality);
5289 rc = BAD_VALUE;
5290 }
5291
5292 quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
5293 if (quality > 0 && quality <= 100) {
5294 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
5295 } else {
5296 LOGE("Invalid jpeg thumbnail quality=%d", quality);
5297 rc = BAD_VALUE;
5298 }
5299 return rc;
5300}
5301
5302status_t QualcommCameraHardware::setEffect(const CameraParameters& params)
5303{
Apurva Rajguru7360db42010-04-09 16:37:36 -07005304
5305 const char *str_wb = mParameters.get(CameraParameters::KEY_WHITE_BALANCE);
5306 int32_t value_wb = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str_wb);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005307 const char *str = params.get(CameraParameters::KEY_EFFECT);
Apurva Rajguru7360db42010-04-09 16:37:36 -07005308
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005309 if (str != NULL) {
5310 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
5311 if (value != NOT_FOUND) {
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005312 if(!strcmp(sensorType->name, "2mp") && (value != CAMERA_EFFECT_OFF)
5313 &&(value != CAMERA_EFFECT_MONO) && (value != CAMERA_EFFECT_NEGATIVE)
5314 &&(value != CAMERA_EFFECT_SOLARIZE) && (value != CAMERA_EFFECT_SEPIA)) {
5315 LOGE("Special effect parameter is not supported for this sensor");
5316 return NO_ERROR;
5317 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07005318
5319 if(((value == CAMERA_EFFECT_MONO) || (value == CAMERA_EFFECT_NEGATIVE)
5320 || (value == CAMERA_EFFECT_AQUA) || (value == CAMERA_EFFECT_SEPIA))
5321 && (value_wb != CAMERA_WB_AUTO)) {
5322 LOGE("Color Effect value will not be set " \
5323 "when the whitebalance selected is %s", str_wb);
5324 return NO_ERROR;
5325 }
5326 else {
5327 mParameters.set(CameraParameters::KEY_EFFECT, str);
5328 bool ret = native_set_parm(CAMERA_SET_PARM_EFFECT, sizeof(value),
5329 (void *)&value);
5330 return ret ? NO_ERROR : UNKNOWN_ERROR;
5331 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005332 }
5333 }
5334 LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
5335 return BAD_VALUE;
5336}
5337
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07005338status_t QualcommCameraHardware::setExposureCompensation(
5339 const CameraParameters & params){
5340
5341 if(!strcmp(sensorType->name, "2mp")) {
5342 LOGE("Exposure Compensation is not supported for this sensor");
5343 return NO_ERROR;
5344 }
5345
5346 int numerator = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
5347 if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator &&
5348 numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
5349 int16_t numerator16 = (int16_t)(numerator & 0x0000ffff);
5350 uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
5351 uint32_t value = 0;
5352 value = numerator16 << 16 | denominator16;
5353
5354 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
5355 numerator);
5356 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE_COMPENSATION,
5357 sizeof(value), (void *)&value);
5358 return ret ? NO_ERROR : UNKNOWN_ERROR;
5359 }
5360 return BAD_VALUE;
5361}
5362
Apurva Rajguru55562b02009-12-03 12:25:35 -08005363status_t QualcommCameraHardware::setAutoExposure(const CameraParameters& params)
5364{
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005365 if(!strcmp(sensorType->name, "2mp")) {
5366 LOGE("Auto Exposure not supported for this sensor");
5367 return NO_ERROR;
5368 }
Apurva Rajguru55562b02009-12-03 12:25:35 -08005369 const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
5370 if (str != NULL) {
5371 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
5372 if (value != NOT_FOUND) {
5373 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
5374 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE, sizeof(value),
5375 (void *)&value);
5376 return ret ? NO_ERROR : UNKNOWN_ERROR;
5377 }
5378 }
5379 LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
5380 return BAD_VALUE;
5381}
5382
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005383status_t QualcommCameraHardware::setSharpness(const CameraParameters& params)
5384{
5385 if(!strcmp(sensorType->name, "2mp")) {
5386 LOGE("Sharpness not supported for this sensor");
5387 return NO_ERROR;
5388 }
5389 int sharpness = params.getInt(CameraParameters::KEY_SHARPNESS);
5390 if((sharpness < CAMERA_MIN_SHARPNESS
5391 || sharpness > CAMERA_MAX_SHARPNESS))
5392 return UNKNOWN_ERROR;
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005393
5394 LOGV("setting sharpness %d", sharpness);
5395 mParameters.set(CameraParameters::KEY_SHARPNESS, sharpness);
5396 bool ret = native_set_parm(CAMERA_SET_PARM_SHARPNESS, sizeof(sharpness),
5397 (void *)&sharpness);
5398 return ret ? NO_ERROR : UNKNOWN_ERROR;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005399}
5400
5401status_t QualcommCameraHardware::setContrast(const CameraParameters& params)
5402{
5403 if(!strcmp(sensorType->name, "2mp")) {
5404 LOGE("Contrast not supported for this sensor");
5405 return NO_ERROR;
5406 }
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005407
Apurva Rajguru08383852010-05-17 14:25:39 -07005408 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
5409 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
5410
5411 if(value == CAMERA_BESTSHOT_OFF) {
5412 int contrast = params.getInt(CameraParameters::KEY_CONTRAST);
5413 if((contrast < CAMERA_MIN_CONTRAST)
5414 || (contrast > CAMERA_MAX_CONTRAST))
5415 return UNKNOWN_ERROR;
5416
5417 LOGV("setting contrast %d", contrast);
5418 mParameters.set(CameraParameters::KEY_CONTRAST, contrast);
5419 bool ret = native_set_parm(CAMERA_SET_PARM_CONTRAST, sizeof(contrast),
5420 (void *)&contrast);
5421 return ret ? NO_ERROR : UNKNOWN_ERROR;
5422 } else {
5423 LOGE(" Contrast value will not be set " \
5424 "when the scenemode selected is %s", str);
5425 return NO_ERROR;
5426 }
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005427}
5428
5429status_t QualcommCameraHardware::setSaturation(const CameraParameters& params)
5430{
5431 if(!strcmp(sensorType->name, "2mp")) {
5432 LOGE("Saturation not supported for this sensor");
5433 return NO_ERROR;
5434 }
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005435
Kiran Kumar H Nf87cf862010-01-27 14:34:34 -08005436 const char *str = params.get(CameraParameters::KEY_EFFECT);
5437 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
5438
5439 if( (value != CAMERA_EFFECT_MONO) && (value != CAMERA_EFFECT_NEGATIVE)
5440 && (value != CAMERA_EFFECT_AQUA) && (value != CAMERA_EFFECT_SEPIA)) {
5441
5442 int saturation = params.getInt(CameraParameters::KEY_SATURATION);
5443 if((saturation < CAMERA_MIN_SATURATION)
5444 || (saturation > CAMERA_MAX_SATURATION))
5445 return UNKNOWN_ERROR;
5446
Apurva Rajguru08383852010-05-17 14:25:39 -07005447 LOGV("Setting saturation %d", saturation);
Kiran Kumar H Nf87cf862010-01-27 14:34:34 -08005448 mParameters.set(CameraParameters::KEY_SATURATION, saturation);
5449 bool ret = native_set_parm(CAMERA_SET_PARM_SATURATION, sizeof(saturation),
5450 (void *)&saturation);
5451 return ret ? NO_ERROR : UNKNOWN_ERROR;
5452 } else {
5453 LOGE(" Saturation value will not be set " \
5454 "when the effect selected is %s", str);
5455 return NO_ERROR;
5456 }
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005457}
5458
Mohan Kandra7110c242010-07-18 15:34:48 -07005459status_t QualcommCameraHardware::setPreviewFormat(const CameraParameters& params) {
5460 const char *str = params.getPreviewFormat();
5461 int32_t previewFormat = attr_lookup(preview_formats, sizeof(preview_formats) / sizeof(str_map), str);
5462 if(previewFormat != NOT_FOUND) {
5463 mParameters.set(CameraParameters::KEY_PREVIEW_FORMAT, str);
5464 mPreviewFormat = previewFormat;
5465 return NO_ERROR;
5466 }
5467 LOGI("Invalid preview format value: %s", (str == NULL) ? "NULL" : str);
5468 return BAD_VALUE;
5469}
5470
5471status_t QualcommCameraHardware::setStrTextures(const CameraParameters& params) {
5472 const char *str = params.get("strtextures");
5473 if(str != NULL) {
5474 LOGI("strtextures = %s", str);
5475 mParameters.set("strtextures", str);
5476 if(mUseOverlay) {
5477 if(!strncmp(str, "on", 2) || !strncmp(str, "ON", 2)) {
5478 LOGI("Resetting mUseOverlay to false");
5479 mUseOverlay = false;
5480 }
5481 }
5482 }
5483 return NO_ERROR;
5484}
5485
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305486status_t QualcommCameraHardware::setBrightness(const CameraParameters& params) {
5487 int brightness = params.getInt("luma-adaptation");
5488 if (mBrightness != brightness) {
5489 LOGV(" new brightness value : %d ", brightness);
5490 mBrightness = brightness;
5491
5492 bool ret = native_set_parm(CAMERA_SET_PARM_BRIGHTNESS, sizeof(mBrightness),
5493 (void *)&mBrightness);
5494 return ret ? NO_ERROR : UNKNOWN_ERROR;
5495 } else {
5496 return NO_ERROR;
5497 }
5498}
5499
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005500status_t QualcommCameraHardware::setWhiteBalance(const CameraParameters& params)
5501{
Apurva Rajguru7360db42010-04-09 16:37:36 -07005502
5503 const char *str_effect = mParameters.get(CameraParameters::KEY_EFFECT);
5504 int32_t value_effect = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str_effect);
5505
5506 if( (value_effect != CAMERA_EFFECT_MONO) && (value_effect != CAMERA_EFFECT_NEGATIVE)
5507 && (value_effect != CAMERA_EFFECT_AQUA) && (value_effect != CAMERA_EFFECT_SEPIA)) {
5508 const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
5509
5510 if (str != NULL) {
5511 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
5512 if (value != NOT_FOUND) {
5513 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
5514 bool ret = native_set_parm(CAMERA_SET_PARM_WB, sizeof(value),
5515 (void *)&value);
5516 return ret ? NO_ERROR : UNKNOWN_ERROR;
5517 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005518 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07005519 LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
5520 return BAD_VALUE;
5521 } else {
5522 LOGE("Whitebalance value will not be set " \
5523 "when the effect selected is %s", str_effect);
5524 return NO_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005525 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005526}
5527
5528status_t QualcommCameraHardware::setFlash(const CameraParameters& params)
5529{
5530 if (!mSensorInfo.flash_enabled) {
5531 LOGV("%s: flash not supported", __FUNCTION__);
5532 return NO_ERROR;
5533 }
5534
5535 const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
5536 if (str != NULL) {
5537 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
5538 if (value != NOT_FOUND) {
5539 mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
5540 bool ret = native_set_parm(CAMERA_SET_PARM_LED_MODE,
5541 sizeof(value), (void *)&value);
5542 return ret ? NO_ERROR : UNKNOWN_ERROR;
5543 }
5544 }
5545 LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
5546 return BAD_VALUE;
5547}
5548
5549status_t QualcommCameraHardware::setAntibanding(const CameraParameters& params)
5550{
Srinivasan Kannan2229d272010-01-05 14:58:28 -08005551 if(!strcmp(sensorType->name, "2mp")) {
5552 LOGE("Parameter AntiBanding is not supported for this sensor");
5553 return NO_ERROR;
5554 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005555 const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
5556 if (str != NULL) {
5557 int value = (camera_antibanding_type)attr_lookup(
5558 antibanding, sizeof(antibanding) / sizeof(str_map), str);
5559 if (value != NOT_FOUND) {
5560 camera_antibanding_type temp = (camera_antibanding_type) value;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005561 mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
Srinivasan Kannan2229d272010-01-05 14:58:28 -08005562 bool ret;
5563 if (temp == CAMERA_ANTIBANDING_AUTO) {
5564 ret = native_set_parm(CAMERA_ENABLE_AFD,
5565 0, NULL);
5566 } else {
5567 ret = native_set_parm(CAMERA_SET_PARM_ANTIBANDING,
5568 sizeof(camera_antibanding_type), (void *)&temp);
5569 }
5570 return ret ? NO_ERROR : UNKNOWN_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005571 }
5572 }
5573 LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
5574 return BAD_VALUE;
5575}
5576
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305577status_t QualcommCameraHardware::setLensshadeValue(const CameraParameters& params)
5578{
Mohan Kandrace6bf562010-04-26 13:00:19 -07005579 if( (!strcmp(sensorType->name, "2mp")) ||
Nishant Pandit5ca94662010-09-15 03:25:09 +05305580 (!strcmp(sensorType->name, "12mp")) ||
Mohan Kandrace6bf562010-04-26 13:00:19 -07005581 (!strcmp(mSensorInfo.name, "vx6953")) ||
5582 (!strcmp(mSensorInfo.name, "VX6953")) ) {
Mohan Kandra1307f312010-04-29 10:18:42 -07005583 LOGI("Parameter Rolloff is not supported for this sensor");
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005584 return NO_ERROR;
5585 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305586 const char *str = params.get(CameraParameters::KEY_LENSSHADE);
5587 if (str != NULL) {
5588 int value = attr_lookup(lensshade,
5589 sizeof(lensshade) / sizeof(str_map), str);
5590 if (value != NOT_FOUND) {
5591 int8_t temp = (int8_t)value;
5592 mParameters.set(CameraParameters::KEY_LENSSHADE, str);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005593
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305594 native_set_parm(CAMERA_SET_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
5595 return NO_ERROR;
5596 }
5597 }
5598 LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
5599 return BAD_VALUE;
5600}
5601
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005602status_t QualcommCameraHardware::setContinuousAf(const CameraParameters& params)
5603{
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005604 if(sensorType->hasAutoFocusSupport){
5605 const char *str = params.get(CameraParameters::KEY_CONTINUOUS_AF);
5606 if (str != NULL) {
5607 int value = attr_lookup(continuous_af,
5608 sizeof(continuous_af) / sizeof(str_map), str);
5609 if (value != NOT_FOUND) {
5610 int8_t temp = (int8_t)value;
5611 mParameters.set(CameraParameters::KEY_CONTINUOUS_AF, str);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005612
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005613 native_set_parm(CAMERA_SET_CAF, sizeof(int8_t), (void *)&temp);
5614 return NO_ERROR;
5615 }
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005616 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005617 LOGE("Invalid continuous Af value: %s", (str == NULL) ? "NULL" : str);
5618 return BAD_VALUE;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005619 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005620 return NO_ERROR;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005621}
5622
Apurva Rajgurue5965c42010-09-09 14:24:54 -07005623status_t QualcommCameraHardware::setSelectableZoneAf(const CameraParameters& params)
5624{
5625 if(sensorType->hasAutoFocusSupport && supportsSelectableZoneAf()) {
5626 const char *str = params.get(CameraParameters::KEY_SELECTABLE_ZONE_AF);
5627 if (str != NULL) {
5628 int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str);
5629 if (value != NOT_FOUND) {
5630 mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF, str);
5631 bool ret = native_set_parm(CAMERA_SET_PARM_FOCUS_RECT, sizeof(value),
5632 (void *)&value);
5633 return ret ? NO_ERROR : UNKNOWN_ERROR;
5634 }
5635 }
5636 LOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str);
5637 return BAD_VALUE;
5638 }
5639 return NO_ERROR;
5640}
5641
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005642status_t QualcommCameraHardware::setTouchAfAec(const CameraParameters& params)
5643{
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005644 if(sensorType->hasAutoFocusSupport){
5645 int xAec, yAec, xAf, yAf;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005646
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005647 params.getTouchIndexAec(&xAec, &yAec);
5648 params.getTouchIndexAf(&xAf, &yAf);
5649 const char *str = params.get(CameraParameters::KEY_TOUCH_AF_AEC);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005650
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005651 if (str != NULL) {
5652 int value = attr_lookup(touchafaec,
5653 sizeof(touchafaec) / sizeof(str_map), str);
5654 if (value != NOT_FOUND) {
5655 mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC, str);
5656 mParameters.setTouchIndexAec(xAec, yAec);
5657 mParameters.setTouchIndexAf(xAf, yAf);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005658
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005659 cam_set_aec_roi_t aec_roi_value;
5660 roi_info_t af_roi_value;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005661
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005662 memset(&af_roi_value, 0, sizeof(roi_info_t));
5663
5664 //If touch AF/AEC is enabled and touch event has occured then
5665 //call the ioctl with valid values.
5666
5667 if (value == true
5668 && (xAec >= 0 && yAec >= 0)
5669 && (xAf >= 0 && yAf >= 0)) {
5670 //Set Touch AEC params
5671 aec_roi_value.aec_roi_enable = AEC_ROI_ON;
5672 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
5673 aec_roi_value.aec_roi_position.coordinate.x = xAec;
5674 aec_roi_value.aec_roi_position.coordinate.y = yAec;
5675
5676 //Set Touch AF params
5677 af_roi_value.num_roi = 1;
5678 af_roi_value.roi[0].x = xAf;
5679 af_roi_value.roi[0].y = yAf;
5680 af_roi_value.roi[0].dx = 100;
5681 af_roi_value.roi[0].dy = 100;
5682 }
5683 else {
5684 //Set Touch AEC params
5685 aec_roi_value.aec_roi_enable = AEC_ROI_OFF;
5686 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
5687 aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE;
5688 aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE;
5689
5690 //Set Touch AF params
5691 af_roi_value.num_roi = 0;
5692 }
5693 native_set_parm(CAMERA_SET_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value);
5694 native_set_parm(CAMERA_SET_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005695 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005696 return NO_ERROR;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005697 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005698 LOGE("Invalid Touch AF/AEC value: %s", (str == NULL) ? "NULL" : str);
5699 return BAD_VALUE;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005700 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005701 return NO_ERROR;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005702}
5703
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305704status_t QualcommCameraHardware::setISOValue(const CameraParameters& params) {
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005705 int8_t temp_hjr;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305706 const char *str = params.get(CameraParameters::KEY_ISO_MODE);
5707 if (str != NULL) {
5708 int value = (camera_iso_mode_type)attr_lookup(
5709 iso, sizeof(iso) / sizeof(str_map), str);
5710 if (value != NOT_FOUND) {
5711 camera_iso_mode_type temp = (camera_iso_mode_type) value;
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005712 if (value == CAMERA_ISO_DEBLUR) {
5713 temp_hjr = true;
5714 native_set_parm(CAMERA_SET_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
5715 mHJR = value;
5716 }
5717 else {
5718 if (mHJR == CAMERA_ISO_DEBLUR) {
5719 temp_hjr = false;
5720 native_set_parm(CAMERA_SET_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
5721 mHJR = value;
5722 }
5723 }
5724
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305725 mParameters.set(CameraParameters::KEY_ISO_MODE, str);
5726 native_set_parm(CAMERA_SET_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
5727 return NO_ERROR;
5728 }
5729 }
5730 LOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
5731 return BAD_VALUE;
5732}
5733
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005734status_t QualcommCameraHardware::setSceneDetect(const CameraParameters& params)
5735{
5736
5737 bool retParm1, retParm2;
5738 if (supportsSceneDetection()) {
Apurva Rajguru0d400562010-09-13 14:12:02 -07005739 if(!strcmp(sensorType->name, "2mp")) {
5740 LOGI("Parameter Auto Scene Detection is not supported for this sensor");
5741 return NO_ERROR;
5742 }
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005743 const char *str = params.get(CameraParameters::KEY_SCENE_DETECT);
5744 if (str != NULL) {
5745 int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str);
5746 if (value != NOT_FOUND) {
5747 mParameters.set(CameraParameters::KEY_SCENE_DETECT, str);
5748
5749 retParm1 = native_set_parm(CAMERA_SET_PARM_BL_DETECTION_ENABLE, sizeof(value),
5750 (void *)&value);
5751
5752 retParm2 = native_set_parm(CAMERA_SET_PARM_SNOW_DETECTION_ENABLE, sizeof(value),
5753 (void *)&value);
5754
5755 //All Auto Scene detection modes should be all ON or all OFF.
5756 if(retParm1 == false || retParm2 == false) {
5757 value = !value;
5758 retParm1 = native_set_parm(CAMERA_SET_PARM_BL_DETECTION_ENABLE, sizeof(value),
5759 (void *)&value);
5760
5761 retParm2 = native_set_parm(CAMERA_SET_PARM_SNOW_DETECTION_ENABLE, sizeof(value),
5762 (void *)&value);
5763 }
5764 return (retParm1 && retParm2) ? NO_ERROR : UNKNOWN_ERROR;
5765 }
5766 }
5767 LOGE("Invalid auto scene detection value: %s", (str == NULL) ? "NULL" : str);
5768 return BAD_VALUE;
5769 }
5770 return NO_ERROR;
5771}
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305772
Apurva Rajguru08383852010-05-17 14:25:39 -07005773status_t QualcommCameraHardware::setSceneMode(const CameraParameters& params)
5774{
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005775
5776 if(!strcmp(sensorType->name, "2mp")) {
5777 LOGI("Parameter Scenemode is not supported for this sensor");
5778 return NO_ERROR;
5779 }
5780
Apurva Rajguru08383852010-05-17 14:25:39 -07005781 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
5782
5783 if (str != NULL) {
5784 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
5785 if (value != NOT_FOUND) {
5786 mParameters.set(CameraParameters::KEY_SCENE_MODE, str);
5787 bool ret = native_set_parm(CAMERA_SET_PARM_BESTSHOT_MODE, sizeof(value),
5788 (void *)&value);
5789 return ret ? NO_ERROR : UNKNOWN_ERROR;
5790 }
5791 }
5792 LOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str);
5793 return BAD_VALUE;
5794}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005795status_t QualcommCameraHardware::setGpsLocation(const CameraParameters& params)
5796{
Srinivasan Kannan09de3382010-08-16 16:42:00 -07005797 const char *method = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
5798 if (method) {
5799 mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, method);
5800 }
5801
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005802 const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
5803 if (latitude) {
5804 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
5805 }
5806
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005807 const char *latitudeRef = params.get(CameraParameters::KEY_GPS_LATITUDE_REF);
5808 if (latitudeRef) {
5809 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
5810 }
5811
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005812 const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
5813 if (longitude) {
5814 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
5815 }
5816
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005817 const char *longitudeRef = params.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
5818 if (longitudeRef) {
5819 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
5820 }
5821
5822 const char *altitudeRef = params.get(CameraParameters::KEY_GPS_ALTITUDE_REF);
5823 if (altitudeRef) {
5824 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
5825 }
5826
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005827 const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
5828 if (altitude) {
5829 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
5830 }
5831
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005832 const char *status = params.get(CameraParameters::KEY_GPS_STATUS);
5833 if (status) {
5834 mParameters.set(CameraParameters::KEY_GPS_STATUS, status);
5835 }
5836
5837 const char *dateTime = params.get(CameraParameters::KEY_EXIF_DATETIME);
5838 if (dateTime) {
5839 mParameters.set(CameraParameters::KEY_EXIF_DATETIME, dateTime);
5840 }
5841
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005842 const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
5843 if (timestamp) {
5844 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
5845 }
5846 return NO_ERROR;
5847}
5848
5849status_t QualcommCameraHardware::setRotation(const CameraParameters& params)
5850{
5851 status_t rc = NO_ERROR;
5852 int rotation = params.getInt(CameraParameters::KEY_ROTATION);
5853 if (rotation != NOT_FOUND) {
5854 if (rotation == 0 || rotation == 90 || rotation == 180
5855 || rotation == 270) {
5856 mParameters.set(CameraParameters::KEY_ROTATION, rotation);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005857 mRotation = rotation;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005858 } else {
5859 LOGE("Invalid rotation value: %d", rotation);
5860 rc = BAD_VALUE;
5861 }
5862 }
5863 return rc;
5864}
5865
5866status_t QualcommCameraHardware::setZoom(const CameraParameters& params)
5867{
5868 status_t rc = NO_ERROR;
5869 // No matter how many different zoom values the driver can provide, HAL
5870 // provides applictations the same number of zoom levels. The maximum driver
5871 // zoom value depends on sensor output (VFE input) and preview size (VFE
5872 // output) because VFE can only crop and cannot upscale. If the preview size
5873 // is bigger, the maximum zoom ratio is smaller. However, we want the
5874 // zoom ratio of each zoom level is always the same whatever the preview
5875 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
5876 // we need to have a fixed maximum zoom value and do read it from the
5877 // driver.
Mohan Kandra284966d2010-01-05 13:39:15 -08005878 static const int ZOOM_STEP = 1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005879 int32_t zoom_level = params.getInt("zoom");
5880
Mohan Kandra284966d2010-01-05 13:39:15 -08005881 LOGV("Set zoom=%d", zoom_level);
5882 if(zoom_level >= 0 && zoom_level <= mMaxZoom) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005883 mParameters.set("zoom", zoom_level);
5884 int32_t zoom_value = ZOOM_STEP * zoom_level;
5885 bool ret = native_set_parm(CAMERA_SET_PARM_ZOOM,
5886 sizeof(zoom_value), (void *)&zoom_value);
5887 rc = ret ? NO_ERROR : UNKNOWN_ERROR;
5888 } else {
5889 rc = BAD_VALUE;
5890 }
5891
5892 return rc;
5893}
5894
5895status_t QualcommCameraHardware::setFocusMode(const CameraParameters& params)
5896{
5897 const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
5898 if (str != NULL) {
5899 int32_t value = attr_lookup(focus_modes,
5900 sizeof(focus_modes) / sizeof(str_map), str);
5901 if (value != NOT_FOUND) {
5902 mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
5903 // Focus step is reset to infinity when preview is started. We do
5904 // not need to do anything now.
5905 return NO_ERROR;
5906 }
5907 }
5908 LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
5909 return BAD_VALUE;
5910}
5911
5912status_t QualcommCameraHardware::setOrientation(const CameraParameters& params)
5913{
5914 const char *str = params.get("orientation");
5915
5916 if (str != NULL) {
5917 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
5918 // Camera service needs this to decide if the preview frames and raw
5919 // pictures should be rotated.
5920 mParameters.set("orientation", str);
5921 } else {
5922 LOGE("Invalid orientation value: %s", str);
5923 return BAD_VALUE;
5924 }
5925 }
5926 return NO_ERROR;
5927}
5928
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08005929status_t QualcommCameraHardware::setPictureFormat(const CameraParameters& params)
5930{
5931 const char * str = params.get(CameraParameters::KEY_PICTURE_FORMAT);
5932
5933 if(str != NULL){
5934 int32_t value = attr_lookup(picture_formats,
5935 sizeof(picture_formats) / sizeof(str_map), str);
5936 if(value != NOT_FOUND){
5937 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT, str);
5938 } else {
5939 LOGE("Invalid Picture Format value: %s", str);
5940 return BAD_VALUE;
5941 }
5942 }
5943 return NO_ERROR;
5944}
5945
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005946QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
5947 int frame_size,
5948 const char *name) :
5949 mBufferSize(buffer_size),
5950 mNumBuffers(num_buffers),
5951 mFrameSize(frame_size),
5952 mBuffers(NULL), mName(name)
5953{
5954 int page_size_minus_1 = getpagesize() - 1;
5955 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
5956}
5957
5958void QualcommCameraHardware::MemPool::completeInitialization()
5959{
5960 // If we do not know how big the frame will be, we wait to allocate
5961 // the buffers describing the individual frames until we do know their
5962 // size.
5963
5964 if (mFrameSize > 0) {
5965 mBuffers = new sp<MemoryBase>[mNumBuffers];
5966 for (int i = 0; i < mNumBuffers; i++) {
5967 mBuffers[i] = new
5968 MemoryBase(mHeap,
5969 i * mAlignedBufferSize,
5970 mFrameSize);
5971 }
5972 }
5973}
5974
5975QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
5976 int frame_size,
5977 const char *name) :
5978 QualcommCameraHardware::MemPool(buffer_size,
5979 num_buffers,
5980 frame_size,
5981 name)
5982{
5983 LOGV("constructing MemPool %s backed by ashmem: "
5984 "%d frames @ %d uint8_ts, "
5985 "buffer size %d",
5986 mName,
5987 num_buffers, frame_size, buffer_size);
5988
5989 int page_mask = getpagesize() - 1;
5990 int ashmem_size = buffer_size * num_buffers;
5991 ashmem_size += page_mask;
5992 ashmem_size &= ~page_mask;
5993
5994 mHeap = new MemoryHeapBase(ashmem_size);
5995
5996 completeInitialization();
5997}
5998
5999static bool register_buf(int camfd,
6000 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08006001 int frame_size,
Mohan Kandra02486042010-06-18 16:49:43 -07006002 int cbcr_offset,
6003 int yoffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006004 int pmempreviewfd,
6005 uint32_t offset,
6006 uint8_t *buf,
6007 int pmem_type,
6008 bool vfe_can_write,
6009 bool register_buffer = true);
6010
6011QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
6012 int flags,
6013 int camera_control_fd,
6014 int pmem_type,
6015 int buffer_size, int num_buffers,
Mohan Kandra02486042010-06-18 16:49:43 -07006016 int frame_size, int cbcr_offset,
6017 int yOffset, const char *name) :
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006018 QualcommCameraHardware::MemPool(buffer_size,
6019 num_buffers,
6020 frame_size,
6021 name),
6022 mPmemType(pmem_type),
Mohan Kandra02486042010-06-18 16:49:43 -07006023 mCbCrOffset(cbcr_offset),
6024 myOffset(yOffset),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006025 mCameraControlFd(dup(camera_control_fd))
6026{
6027 LOGV("constructing MemPool %s backed by pmem pool %s: "
6028 "%d frames @ %d bytes, buffer size %d",
6029 mName,
6030 pmem_pool, num_buffers, frame_size,
6031 buffer_size);
6032
6033 LOGV("%s: duplicating control fd %d --> %d",
6034 __FUNCTION__,
6035 camera_control_fd, mCameraControlFd);
6036
6037 // Make a new mmap'ed heap that can be shared across processes.
6038 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
6039 mAlignedSize = mAlignedBufferSize * num_buffers;
6040
6041 sp<MemoryHeapBase> masterHeap =
6042 new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
6043
6044 if (masterHeap->getHeapID() < 0) {
6045 LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
6046 masterHeap.clear();
6047 return;
6048 }
6049
6050 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
6051 if (pmemHeap->getHeapID() >= 0) {
6052 pmemHeap->slap();
6053 masterHeap.clear();
6054 mHeap = pmemHeap;
6055 pmemHeap.clear();
6056
6057 mFd = mHeap->getHeapID();
6058 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
6059 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
6060 pmem_pool,
6061 ::strerror(errno), errno);
6062 mHeap.clear();
6063 return;
6064 }
6065
6066 LOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
6067 pmem_pool,
6068 mFd,
6069 mSize.len);
Mohan Kandra284966d2010-01-05 13:39:15 -08006070 LOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006071 // Unregister preview buffers with the camera drivers. Allow the VFE to write
6072 // to all preview buffers except for the last one.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08006073 // Only Register the preview, snapshot and thumbnail buffers with the kernel.
Mohan Kandrad9efed92010-01-15 19:08:39 -08006074 if( (strcmp("postview", mName) != 0) ){
6075 int num_buf = num_buffers;
6076 if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount;
Brian Steuerb62adbd2010-02-02 14:47:08 -08006077 LOGD("num_buffers = %d", num_buf);
Mohan Kandrad9efed92010-01-15 19:08:39 -08006078 for (int cnt = 0; cnt < num_buf; ++cnt) {
Sravankb4f5f1c2010-01-21 11:06:17 +05306079 int active = 1;
6080 if(pmem_type == MSM_PMEM_VIDEO){
6081 active = (cnt<ACTIVE_VIDEO_BUFFERS);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07006082 //When VPE is enabled, set the last record
6083 //buffer as active and pmem type as PMEM_VIDEO_VPE
6084 //as this is a requirement from VPE operation.
Mohan Kandra88db27a2010-08-22 12:33:36 -07006085 //No need to set this pmem type to VIDEO_VPE while unregistering,
6086 //because as per camera stack design: "the VPE AXI is also configured
6087 //when VFE is configured for VIDEO, which is as part of preview
6088 //initialization/start. So during this VPE AXI config camera stack
6089 //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and
6090 //change it's type to PMEM_VIDEO".
Mohan Kandra39fad8d2010-07-15 12:29:19 -07006091 if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
6092 active = 1;
6093 pmem_type = MSM_PMEM_VIDEO_VPE;
6094 }
Sravankb4f5f1c2010-01-21 11:06:17 +05306095 LOGV(" pmempool creating video buffers : active %d ", active);
6096 }
6097 else if (pmem_type == MSM_PMEM_PREVIEW){
6098 active = (cnt < (num_buf-1));
6099 }
Mohan Kandra284966d2010-01-05 13:39:15 -08006100 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006101 mBufferSize,
Mohan Kandra02486042010-06-18 16:49:43 -07006102 mFrameSize, mCbCrOffset, myOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006103 mHeap->getHeapID(),
6104 mAlignedBufferSize * cnt,
6105 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
6106 pmem_type,
Sravankb4f5f1c2010-01-21 11:06:17 +05306107 active);
Mohan Kandra284966d2010-01-05 13:39:15 -08006108 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006109 }
6110
6111 completeInitialization();
6112 }
6113 else LOGE("pmem pool %s error: could not create master heap!",
6114 pmem_pool);
6115}
6116
6117QualcommCameraHardware::PmemPool::~PmemPool()
6118{
6119 LOGV("%s: %s E", __FUNCTION__, mName);
6120 if (mHeap != NULL) {
6121 // Unregister preview buffers with the camera drivers.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08006122 // Only Unregister the preview, snapshot and thumbnail
6123 // buffers with the kernel.
Mohan Kandrad9efed92010-01-15 19:08:39 -08006124 if( (strcmp("postview", mName) != 0) ){
6125 int num_buffers = mNumBuffers;
6126 if(!strcmp("preview", mName)) num_buffers = kPreviewBufferCount;
6127 for (int cnt = 0; cnt < num_buffers; ++cnt) {
Mohan Kandra284966d2010-01-05 13:39:15 -08006128 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006129 mBufferSize,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08006130 mFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07006131 mCbCrOffset,
6132 myOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006133 mHeap->getHeapID(),
6134 mAlignedBufferSize * cnt,
6135 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
6136 mPmemType,
6137 false,
6138 false /* unregister */);
Mohan Kandra284966d2010-01-05 13:39:15 -08006139 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006140 }
6141 }
6142 LOGV("destroying PmemPool %s: closing control fd %d",
6143 mName,
6144 mCameraControlFd);
6145 close(mCameraControlFd);
6146 LOGV("%s: %s X", __FUNCTION__, mName);
6147}
6148
6149QualcommCameraHardware::MemPool::~MemPool()
6150{
6151 LOGV("destroying MemPool %s", mName);
6152 if (mFrameSize > 0)
6153 delete [] mBuffers;
6154 mHeap.clear();
6155 LOGV("destroying MemPool %s completed", mName);
6156}
6157
6158static bool register_buf(int camfd,
6159 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08006160 int frame_size,
Mohan Kandra02486042010-06-18 16:49:43 -07006161 int cbcr_offset,
6162 int yoffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006163 int pmempreviewfd,
6164 uint32_t offset,
6165 uint8_t *buf,
6166 int pmem_type,
6167 bool vfe_can_write,
6168 bool register_buffer)
6169{
6170 struct msm_pmem_info pmemBuf;
6171
6172 pmemBuf.type = pmem_type;
6173 pmemBuf.fd = pmempreviewfd;
6174 pmemBuf.offset = offset;
6175 pmemBuf.len = size;
6176 pmemBuf.vaddr = buf;
Mohan Kandra02486042010-06-18 16:49:43 -07006177 pmemBuf.y_off = yoffset;
6178 pmemBuf.cbcr_off = cbcr_offset;
Srinivasan Kannanb36a4fe2010-01-29 19:34:09 -08006179
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006180 pmemBuf.active = vfe_can_write;
6181
6182 LOGV("register_buf: camfd = %d, reg = %d buffer = %p",
6183 camfd, !register_buffer, buf);
6184 if (ioctl(camfd,
6185 register_buffer ?
6186 MSM_CAM_IOCTL_REGISTER_PMEM :
6187 MSM_CAM_IOCTL_UNREGISTER_PMEM,
6188 &pmemBuf) < 0) {
6189 LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM fd %d error %s",
6190 camfd,
6191 strerror(errno));
6192 return false;
6193 }
6194 return true;
6195}
6196
6197status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
6198{
6199 const size_t SIZE = 256;
6200 char buffer[SIZE];
6201 String8 result;
6202 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
6203 result.append(buffer);
6204 if (mName) {
6205 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
6206 result.append(buffer);
6207 }
6208 if (mHeap != 0) {
6209 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
6210 mHeap->getBase(), mHeap->getSize(),
6211 mHeap->getFlags(), mHeap->getDevice());
6212 result.append(buffer);
6213 }
6214 snprintf(buffer, 255,
6215 "buffer size (%d), number of buffers (%d), frame size(%d)",
6216 mBufferSize, mNumBuffers, mFrameSize);
6217 result.append(buffer);
6218 write(fd, result.string(), result.size());
6219 return NO_ERROR;
6220}
6221
6222static void receive_camframe_callback(struct msm_frame *frame)
6223{
6224 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6225 if (obj != 0) {
6226 obj->receivePreviewFrame(frame);
6227 }
6228}
6229
Nishant Pandit741742b2010-09-21 03:24:20 +05306230static void receive_camstats_callback(camstats_type stype, camera_preview_histogram_info* histinfo)
6231{
6232 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6233 if (obj != 0) {
6234 obj->receiveCameraStats(stype,histinfo);
6235 }
6236}
6237
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05306238static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size)
6239{
6240 if(status == LIVESHOT_SUCCESS) {
6241 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6242 if (obj != 0) {
6243 obj->receiveLiveSnapshot(jpeg_size);
6244 }
6245 }
6246 else
6247 LOGE("Liveshot not succesful");
6248}
6249
6250
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006251static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size)
6252{
6253 LOGV("receive_jpeg_fragment_callback E");
6254 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6255 if (obj != 0) {
6256 obj->receiveJpegPictureFragment(buff_ptr, buff_size);
6257 }
6258 LOGV("receive_jpeg_fragment_callback X");
6259}
6260
6261static void receive_jpeg_callback(jpeg_event_t status)
6262{
6263 LOGV("receive_jpeg_callback E (completion status %d)", status);
6264 if (status == JPEG_EVENT_DONE) {
6265 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6266 if (obj != 0) {
6267 obj->receiveJpegPicture();
6268 }
6269 }
6270 LOGV("receive_jpeg_callback X");
6271}
Sravankb4f5f1c2010-01-21 11:06:17 +05306272// 720p : video frame calbback from camframe
6273static void receive_camframe_video_callback(struct msm_frame *frame)
6274{
6275 LOGV("receive_camframe_video_callback E");
6276 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6277 if (obj != 0) {
6278 obj->receiveRecordingFrame(frame);
6279 }
6280 LOGV("receive_camframe_video_callback X");
6281}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006282
6283void QualcommCameraHardware::setCallbacks(notify_callback notify_cb,
6284 data_callback data_cb,
6285 data_callback_timestamp data_cb_timestamp,
6286 void* user)
6287{
6288 Mutex::Autolock lock(mLock);
6289 mNotifyCallback = notify_cb;
6290 mDataCallback = data_cb;
6291 mDataCallbackTimestamp = data_cb_timestamp;
6292 mCallbackCookie = user;
6293}
6294
6295void QualcommCameraHardware::enableMsgType(int32_t msgType)
6296{
6297 Mutex::Autolock lock(mLock);
6298 mMsgEnabled |= msgType;
6299}
6300
6301void QualcommCameraHardware::disableMsgType(int32_t msgType)
6302{
6303 Mutex::Autolock lock(mLock);
6304 mMsgEnabled &= ~msgType;
6305}
6306
6307bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
6308{
6309 return (mMsgEnabled & msgType);
6310}
6311
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08006312bool QualcommCameraHardware::useOverlay(void)
6313{
Nishant Pandit3c278cd2010-07-13 15:56:04 +05306314 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) {
6315 /* 7x30 and 8x60 supports Overlay */
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08006316 mUseOverlay = TRUE;
6317 } else
6318 mUseOverlay = FALSE;
6319
6320 LOGV(" Using Overlay : %s ", mUseOverlay ? "YES" : "NO" );
6321 return mUseOverlay;
6322}
6323
6324status_t QualcommCameraHardware::setOverlay(const sp<Overlay> &Overlay)
6325{
6326 if( Overlay != NULL) {
6327 LOGV(" Valid overlay object ");
6328 mOverlayLock.lock();
6329 mOverlay = Overlay;
6330 mOverlayLock.unlock();
6331 } else {
Apurva Rajguruc73c1722010-04-15 17:39:11 -07006332 LOGV(" Overlay object NULL. returning ");
Mohan Kandrad9efed92010-01-15 19:08:39 -08006333 mOverlay = NULL;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08006334 return UNKNOWN_ERROR;
6335 }
6336 return NO_ERROR;
6337}
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006338
6339void QualcommCameraHardware::receive_camframetimeout(void) {
6340 LOGV("receive_camframetimeout: E");
6341 Mutex::Autolock l(&mCamframeTimeoutLock);
Mohan Kandra1307f312010-04-29 10:18:42 -07006342 LOGE(" Camframe timed out. Not receiving any frames from camera driver ");
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006343 camframe_timeout_flag = TRUE;
Priyanka Kharatae03c212010-05-19 15:32:50 -07006344 mNotifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_UKNOWN, 0,
6345 mCallbackCookie);
Kiran Kumar H N215cac42009-12-08 01:53:46 -08006346 LOGV("receive_camframetimeout: X");
6347}
6348
6349static void receive_camframetimeout_callback(void) {
6350 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
6351 if (obj != 0) {
6352 obj->receive_camframetimeout();
6353 }
6354}
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08006355
6356void QualcommCameraHardware::storePreviewFrameForPostview(void) {
6357 LOGV(" storePreviewFrameForPostview : E ");
6358
6359 /* Since there is restriction on the maximum overlay dimensions
6360 * that can be created, we use the last preview frame as postview
6361 * for 7x30. */
6362 LOGV(" Copying the preview buffer to postview buffer %d ",
6363 mPreviewFrameSize);
6364 if( mPostViewHeap != NULL && mLastQueuedFrame != NULL) {
6365 memcpy(mPostViewHeap->mHeap->base(),
6366 (uint8_t *)mLastQueuedFrame, mPreviewFrameSize );
6367 } else
6368 LOGE(" Failed to store Preview frame. No Postview ");
6369
6370 LOGV(" storePreviewFrameForPostview : X ");
6371}
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006372
6373bool QualcommCameraHardware::isValidDimension(int width, int height) {
6374 bool retVal = FALSE;
6375 /* This function checks if a given resolution is valid or not.
6376 * A particular resolution is considered valid if it satisfies
6377 * the following conditions:
6378 * 1. width & height should be multiple of 16.
6379 * 2. width & height should be less than/equal to the dimensions
6380 * supported by the camera sensor.
6381 * 3. the aspect ratio is a valid aspect ratio and is among the
6382 * commonly used aspect ratio as determined by the thumbnail_sizes
6383 * data structure.
6384 */
6385
6386 if( (width == CEILING16(width)) && (height == CEILING16(height))
6387 && (width <= sensorType->max_supported_snapshot_width)
6388 && (height <= sensorType->max_supported_snapshot_height) )
6389 {
6390 uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height);
Mohan Kandra62429cc2010-07-19 10:21:05 -07006391 for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) {
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006392 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) {
6393 retVal = TRUE;
6394 break;
6395 }
6396 }
6397 }
6398 return retVal;
6399}
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006400status_t QualcommCameraHardware::getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize) {
6401 status_t ret;
6402 LOGV(" getBufferInfo : E ");
Nishant Pandit3c278cd2010-07-13 15:56:04 +05306403 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660) )
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306404 {
6405 if( mRecordHeap != NULL){
6406 LOGV(" Setting valid buffer information ");
6407 Frame = mRecordHeap->mBuffers[0];
6408 if( alignedSize != NULL) {
6409 *alignedSize = mRecordHeap->mAlignedBufferSize;
6410 LOGV(" HAL : alignedSize = %d ", *alignedSize);
6411 ret = NO_ERROR;
6412 } else {
6413 LOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
6414 ret = UNKNOWN_ERROR;
6415 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006416 } else {
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306417 LOGE(" RecordHeap is null. Buffer information wont be updated ");
6418 Frame = NULL;
6419 ret = UNKNOWN_ERROR;
6420 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006421 } else {
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306422 if(mPreviewHeap != NULL) {
6423 LOGV(" Setting valid buffer information ");
6424 Frame = mPreviewHeap->mBuffers[0];
6425 if( alignedSize != NULL) {
6426 *alignedSize = mPreviewHeap->mAlignedBufferSize;
6427 LOGV(" HAL : alignedSize = %d ", *alignedSize);
6428 ret = NO_ERROR;
6429 } else {
6430 LOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
6431 ret = UNKNOWN_ERROR;
6432 }
6433 } else {
6434 LOGE(" PreviewHeap is null. Buffer information wont be updated ");
6435 Frame = NULL;
6436 ret = UNKNOWN_ERROR;
6437 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006438 }
6439 LOGV(" getBufferInfo : X ");
6440 return ret;
6441}
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006442
Mohan Kandra1659b0c2010-07-18 16:36:25 -07006443void QualcommCameraHardware::encodeData() {
6444 LOGV("encodeData: E");
6445
6446 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
6447 mJpegSize = 0;
6448 mJpegThreadWaitLock.lock();
6449 if (LINK_jpeg_encoder_init()) {
6450 mJpegThreadRunning = true;
6451 mJpegThreadWaitLock.unlock();
6452 if(native_jpeg_encode()) {
6453 LOGV("encodeData: X (success)");
6454 //Wait until jpeg encoding is done and call jpeg join
6455 //in this context. Also clear the resources.
6456 mJpegThreadWaitLock.lock();
6457 while (mJpegThreadRunning) {
6458 LOGV("encodeData: waiting for jpeg thread to complete.");
6459 mJpegThreadWait.wait(mJpegThreadWaitLock);
6460 LOGV("encodeData: jpeg thread completed.");
6461 }
6462 mJpegThreadWaitLock.unlock();
6463 //Call jpeg join in this thread context
6464 LINK_jpeg_encoder_join();
6465 }
6466 LOGE("encodeData: jpeg encoding failed");
6467 }
6468 else {
6469 LOGE("encodeData X: jpeg_encoder_init failed.");
6470 mJpegThreadWaitLock.unlock();
6471 }
6472 }
6473 else LOGV("encodeData: JPEG callback is NULL, not encoding image.");
6474 //clear the resources
6475 deinitRaw();
6476 //Encoding is done.
6477 mEncodePendingWaitLock.lock();
6478 mEncodePending = false;
6479 mEncodePendingWait.signal();
6480 mEncodePendingWaitLock.unlock();
6481
6482 LOGV("encodeData: X");
6483}
6484
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006485}; // namespace android
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05306486