blob: c93c4e3a6f45e7dfe4e80a4b682bb61b926344c5 [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);
119int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
120 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
121
122// callbacks
123void (**LINK_mmcamera_camframe_callback)(struct msm_frame *frame);
124void (**LINK_mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
125 uint32_t buff_size);
126void (**LINK_mmcamera_jpeg_callback)(jpeg_event_t status);
127void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800128void (**LINK_camframe_timeout_callback)(void);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530129void (**LINK_mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
130void (**LINK_cancel_liveshot)(void);
131int8_t (*LINK_set_liveshot_params)(uint32_t a_width, uint32_t a_height, exif_tags_info_t *a_exif_data,
132 int a_exif_numEntries, uint8_t* a_out_buffer, uint32_t a_outbuffer_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800133#else
134#define LINK_cam_conf cam_conf
135#define LINK_cam_frame cam_frame
136#define LINK_jpeg_encoder_init jpeg_encoder_init
137#define LINK_jpeg_encoder_join jpeg_encoder_join
138#define LINK_jpeg_encoder_encode jpeg_encoder_encode
139#define LINK_camframe_terminate camframe_terminate
140#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
141#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
142#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
Mohan Kandra02486042010-06-18 16:49:43 -0700143#define LINK_jpeg_encoder_get_buffer_offset jpeg_encoder_get_buffer_offset
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800144#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
145#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
146#define LINK_launch_cam_conf_thread launch_cam_conf_thread
147#define LINK_release_cam_conf_thread release_cam_conf_thread
148#define LINK_zoom_crop_upscale zoom_crop_upscale
149extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
150extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
151 uint32_t buff_size);
152extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
153extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530154extern void (*mmcamera_liveshot_callback)(liveshot_status status, uint32_t jpeg_size);
155#define LINK_set_liveshot_params set_liveshot_params
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800156#endif
157
158} // extern "C"
159
160#ifndef HAVE_CAMERA_SIZE_TYPE
161struct camera_size_type {
162 int width;
163 int height;
164};
165#endif
166
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800167typedef struct crop_info_struct {
168 uint32_t x;
169 uint32_t y;
170 uint32_t w;
171 uint32_t h;
172} zoom_crop_info;
173
Mohan Kandra740cfce2010-01-07 12:58:24 -0800174union zoomimage
Mohan Kandra284966d2010-01-05 13:39:15 -0800175{
176 char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
177 struct mdp_blit_req_list list;
178} zoomImage;
179
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800180//Default to WVGA
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800181#define DEFAULT_PREVIEW_WIDTH 800
182#define DEFAULT_PREVIEW_HEIGHT 480
183
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700184//Default FPS
185#define MINIMUM_FPS 5
186#define MAXIMUM_FPS 30
187#define DEFAULT_FPS MAXIMUM_FPS
188
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800189/*
190 * Modifying preview size requires modification
191 * in bitmasks for boardproperties
192 */
193
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800194static const camera_size_type preview_sizes[] = {
Nishant Pandit2f7681e2010-08-18 02:44:54 +0530195 { 1920, 1088 }, //1080p
Srinivasan Kannanfa7edae2009-12-16 18:02:01 -0800196 { 1280, 720 }, // 720P, reserved
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800197 { 800, 480 }, // WVGA
Srinivasan Kannan613301c2010-02-10 17:08:53 -0800198 { 768, 432 },
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800199 { 720, 480 },
200 { 640, 480 }, // VGA
201 { 576, 432 },
202 { 480, 320 }, // HVGA
203 { 384, 288 },
204 { 352, 288 }, // CIF
205 { 320, 240 }, // QVGA
206 { 240, 160 }, // SQVGA
207 { 176, 144 }, // QCIF
208};
209#define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(camera_size_type))
210
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800211static camera_size_type supportedPreviewSizes[PREVIEW_SIZE_COUNT];
212static unsigned int previewSizeCount;
213
214board_property boardProperties[] = {
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700215 {TARGET_MSM7625, 0x00000fff, false},
216 {TARGET_MSM7627, 0x000006ff, false},
217 {TARGET_MSM7630, 0x00000fff, true},
Nishant Pandit2f7681e2010-08-18 02:44:54 +0530218 {TARGET_MSM8660, 0x00001fff, true},
Apurva Rajguru0d400562010-09-13 14:12:02 -0700219 {TARGET_QSD8250, 0x00000fff, false}
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -0800220};
221
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800222//static const camera_size_type* picture_sizes;
223//static int PICTURE_SIZE_COUNT;
224/* TODO
225 * Ideally this should be a populated by lower layers.
226 * But currently this is no API to do that at lower layer.
227 * Hence populating with default sizes for now. This needs
228 * to be changed once the API is supported.
229 */
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800230//sorted on column basis
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800231static const camera_size_type picture_sizes[] = {
Yen-Pin Hsiaoa6612f12010-07-19 15:17:21 -0700232 { 4000, 3000 }, // 12MP
233 { 3200, 2400 }, // 8MP
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800234 { 2592, 1944 }, // 5MP
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800235 { 2048, 1536 }, // 3MP QXGA
236 { 1920, 1080 }, //HD1080
237 { 1600, 1200 }, // 2MP UXGA
238 { 1280, 768 }, //WXGA
239 { 1280, 720 }, //HD720
240 { 1024, 768}, // 1MP XGA
241 { 800, 600 }, //SVGA
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800242 { 800, 480 }, // WVGA
243 { 640, 480 }, // VGA
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800244 { 352, 288 }, //CIF
245 { 320, 240 }, // QVGA
246 { 176, 144 } // QCIF
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800247};
248static int PICTURE_SIZE_COUNT = sizeof(picture_sizes)/sizeof(camera_size_type);
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800249static const camera_size_type * picture_sizes_ptr;
250static int supportedPictureSizesCount;
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530251static liveshotState liveshot_state = LIVESHOT_DONE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800252
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800253#ifdef Q12
254#undef Q12
255#endif
256
257#define Q12 4096
258
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800259static const target_map targetList [] = {
260 { "msm7625", TARGET_MSM7625 },
261 { "msm7627", TARGET_MSM7627 },
262 { "qsd8250", TARGET_QSD8250 },
Nishant Pandit3c278cd2010-07-13 15:56:04 +0530263 { "msm7630", TARGET_MSM7630 },
264 { "msm8660", TARGET_MSM8660 }
265
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800266};
267static targetType mCurrentTarget = TARGET_MAX;
268
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800269typedef struct {
270 uint32_t aspect_ratio;
271 uint32_t width;
272 uint32_t height;
273} thumbnail_size_type;
274
275static thumbnail_size_type thumbnail_sizes[] = {
276 { 7281, 512, 288 }, //1.777778
277 { 6826, 480, 288 }, //1.666667
Kiran Kumar H Nb49af212010-02-17 15:12:17 -0800278 { 6144, 432, 288 }, //1.5
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800279 { 5461, 512, 384 }, //1.333333
280 { 5006, 352, 288 }, //1.222222
281};
282#define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
283#define DEFAULT_THUMBNAIL_SETTING 2
284#define THUMBNAIL_WIDTH_STR "512"
285#define THUMBNAIL_HEIGHT_STR "384"
286#define THUMBNAIL_SMALL_HEIGHT 144
287
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800288static int attr_lookup(const str_map arr[], int len, const char *name)
289{
290 if (name) {
291 for (int i = 0; i < len; i++) {
292 if (!strcmp(arr[i].desc, name))
293 return arr[i].val;
294 }
295 }
296 return NOT_FOUND;
297}
298
299// round to the next power of two
300static inline unsigned clp2(unsigned x)
301{
302 x = x - 1;
303 x = x | (x >> 1);
304 x = x | (x >> 2);
305 x = x | (x >> 4);
306 x = x | (x >> 8);
307 x = x | (x >>16);
308 return x + 1;
309}
310
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800311static int exif_table_numEntries = 0;
Apurva Rajguru5ec76132010-06-16 17:43:46 -0700312#define MAX_EXIF_TABLE_ENTRIES 8
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800313exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800314static zoom_crop_info zoomCropInfo;
315static void *mLastQueuedFrame = NULL;
Haynes George7dbe49d2010-08-09 12:33:12 -0700316#define RECORD_BUFFERS 9
Vinay Kaliaba3555f2010-07-21 11:37:36 -0700317#define RECORD_BUFFERS_8x50 8
Apurva Rajguruc73c1722010-04-15 17:39:11 -0700318static int kRecordBufferCount;
Mohan Kandra39fad8d2010-07-15 12:29:19 -0700319/* controls whether VPE is avialable for the target
320 * under consideration.
321 * 1: VPE support is available
322 * 0: VPE support is not available (default)
323 */
324static bool mVpeEnabled;
Apurva Rajguruc73c1722010-04-15 17:39:11 -0700325
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800326
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800327namespace android {
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800328
329static const int PICTURE_FORMAT_JPEG = 1;
330static const int PICTURE_FORMAT_RAW = 2;
331
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800332// from aeecamera.h
333static const str_map whitebalance[] = {
334 { CameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
335 { CameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
336 { CameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
337 { CameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
338 { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
339};
340
341// from camera_effect_t. This list must match aeecamera.h
342static const str_map effects[] = {
343 { CameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
344 { CameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
345 { CameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
346 { CameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
347 { CameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
348 { CameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
349 { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
350 { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
351 { CameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA }
352};
353
354// from qcamera/common/camera.h
Apurva Rajguru55562b02009-12-03 12:25:35 -0800355static const str_map autoexposure[] = {
356 { CameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
357 { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
358 { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
359};
360
361// from qcamera/common/camera.h
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800362static const str_map antibanding[] = {
363 { CameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
364 { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
365 { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
366 { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
367};
368
369/* Mapping from MCC to antibanding type */
370struct country_map {
371 uint32_t country_code;
372 camera_antibanding_type type;
373};
374
375static struct country_map country_numeric[] = {
376 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
377 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
378 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
379 { 208, CAMERA_ANTIBANDING_50HZ }, // France
380 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
381 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
382 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
383 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
384 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
385 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
386 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
387 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
388 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
389 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
390 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
391 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
392 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
393 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
394 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
395 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
396 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
397 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
398 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
399 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
400 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
401 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
402 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
403 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
404 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
405 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
406 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
407 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
408 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
409 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
410 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
411 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
412 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
413 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
414 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
415 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
416 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
417 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
418 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
419 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
420 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
421 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
422 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
423 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
424 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
425 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
426 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
427 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
428 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
429 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
430 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
431 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
432 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
433 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
434 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
435 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
436 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
437 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
438 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
439 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
440 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
441 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
442 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
443 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
444 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
445 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
446 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
447 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
448 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
449 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
450 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
451 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
452 { 404, CAMERA_ANTIBANDING_50HZ }, // India
453 { 405, CAMERA_ANTIBANDING_50HZ }, // India
454 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
455 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
456 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
457 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
458 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
459 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
460 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
461 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
462 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
463 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
464 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
465 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
466 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
467 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
468 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
469 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
470 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
471 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
472 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
473 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
474 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
475 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
476 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
477 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
478 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
479 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
480 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
481 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
482 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
483 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
484 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
485 { 460, CAMERA_ANTIBANDING_50HZ }, // China
486 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
487 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
488 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
489 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
490 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
491 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
492 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
493 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
494 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
495 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
496 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
497 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
498 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
499 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
500 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
501 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
502 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
503 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
504 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
505 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
506 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
507 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
508 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
509 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
510 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
511 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
512 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
513 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
514 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
515 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
516 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
517 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
518 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
519 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
520 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
521 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
522 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
523 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
524 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
525 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
526 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
527 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
528 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
529 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
530 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
531 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
532 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
533 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
534 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
535 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
536 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
537 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
538 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
539 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
540 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
541 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
542 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
543 { 647, CAMERA_ANTIBANDING_50HZ }, // France
544 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
545 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
546 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
547 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
548 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
549 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
550 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
551 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
552 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
553 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
554 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
555 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
556 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
557 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
558 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
559 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
560 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
561 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
562 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
563 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
564 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
565 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
566 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
567 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
568 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
569 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
570 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
571 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
572 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
573};
574
Apurva Rajguru08383852010-05-17 14:25:39 -0700575static const str_map scenemode[] = {
576 { CameraParameters::SCENE_MODE_AUTO, CAMERA_BESTSHOT_OFF },
577 { CameraParameters::SCENE_MODE_ACTION, CAMERA_BESTSHOT_ACTION },
578 { CameraParameters::SCENE_MODE_PORTRAIT, CAMERA_BESTSHOT_PORTRAIT },
579 { CameraParameters::SCENE_MODE_LANDSCAPE, CAMERA_BESTSHOT_LANDSCAPE },
580 { CameraParameters::SCENE_MODE_NIGHT, CAMERA_BESTSHOT_NIGHT },
581 { CameraParameters::SCENE_MODE_NIGHT_PORTRAIT, CAMERA_BESTSHOT_NIGHT_PORTRAIT },
582 { CameraParameters::SCENE_MODE_THEATRE, CAMERA_BESTSHOT_THEATRE },
583 { CameraParameters::SCENE_MODE_BEACH, CAMERA_BESTSHOT_BEACH },
584 { CameraParameters::SCENE_MODE_SNOW, CAMERA_BESTSHOT_SNOW },
585 { CameraParameters::SCENE_MODE_SUNSET, CAMERA_BESTSHOT_SUNSET },
586 { CameraParameters::SCENE_MODE_STEADYPHOTO, CAMERA_BESTSHOT_ANTISHAKE },
587 { CameraParameters::SCENE_MODE_FIREWORKS , CAMERA_BESTSHOT_FIREWORKS },
588 { CameraParameters::SCENE_MODE_SPORTS , CAMERA_BESTSHOT_SPORTS },
589 { CameraParameters::SCENE_MODE_PARTY, CAMERA_BESTSHOT_PARTY },
590 { CameraParameters::SCENE_MODE_CANDLELIGHT, CAMERA_BESTSHOT_CANDLELIGHT },
591 { CameraParameters::SCENE_MODE_BACKLIGHT, CAMERA_BESTSHOT_BACKLIGHT },
592 { CameraParameters::SCENE_MODE_FLOWERS, CAMERA_BESTSHOT_FLOWERS },
593};
594
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700595static const str_map scenedetect[] = {
596 { CameraParameters::SCENE_DETECT_OFF, FALSE },
597 { CameraParameters::SCENE_DETECT_ON, TRUE },
598};
599
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800600#define country_number (sizeof(country_numeric) / sizeof(country_map))
601
602/* Look up pre-sorted antibanding_type table by current MCC. */
603static camera_antibanding_type camera_get_location(void) {
604 char value[PROP_VALUE_MAX];
605 char country_value[PROP_VALUE_MAX];
606 uint32_t country_code, count;
607 memset(value, 0x00, sizeof(value));
608 memset(country_value, 0x00, sizeof(country_value));
609 if (!__system_property_get("gsm.operator.numeric", value)) {
610 return CAMERA_ANTIBANDING_60HZ;
611 }
612 memcpy(country_value, value, 3);
613 country_code = atoi(country_value);
614 LOGD("value:%s, country value:%s, country code:%d\n",
615 value, country_value, country_code);
616 int left = 0;
617 int right = country_number - 1;
618 while (left <= right) {
619 int index = (left + right) >> 1;
620 if (country_numeric[index].country_code == country_code)
621 return country_numeric[index].type;
622 else if (country_numeric[index].country_code > country_code)
623 right = index - 1;
624 else
625 left = index + 1;
626 }
627 return CAMERA_ANTIBANDING_60HZ;
628}
629
630// from camera.h, led_mode_t
631static const str_map flash[] = {
632 { CameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
633 { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
Srinivasan Kannanda9a7052010-07-09 10:12:31 -0700634 { CameraParameters::FLASH_MODE_ON, LED_MODE_ON },
635 { CameraParameters::FLASH_MODE_TORCH, LED_MODE_TORCH}
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800636};
637
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530638// from mm-camera/common/camera.h.
639static const str_map iso[] = {
640 { CameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
641 { CameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
642 { CameraParameters::ISO_100, CAMERA_ISO_100},
643 { CameraParameters::ISO_200, CAMERA_ISO_200},
644 { CameraParameters::ISO_400, CAMERA_ISO_400},
Mohan Kandra61db0d02010-04-28 18:28:30 -0700645 { CameraParameters::ISO_800, CAMERA_ISO_800 },
646 { CameraParameters::ISO_1600, CAMERA_ISO_1600 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530647};
648
649
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800650#define DONT_CARE 0
651static const str_map focus_modes[] = {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800652 { CameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
653 { CameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
654 { CameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL },
655 { CameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800656};
657
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530658static const str_map lensshade[] = {
659 { CameraParameters::LENSSHADE_ENABLE, TRUE },
660 { CameraParameters::LENSSHADE_DISABLE, FALSE }
661};
662
Apurva Rajguru7b949c92010-05-26 15:46:57 -0700663static const str_map continuous_af[] = {
664 { CameraParameters::CONTINUOUS_AF_OFF, FALSE },
665 { CameraParameters::CONTINUOUS_AF_ON, TRUE }
666};
667
Apurva Rajguru0a2cb922010-06-08 15:33:22 -0700668#define DONT_CARE_COORDINATE -1
669static const str_map touchafaec[] = {
670 { CameraParameters::TOUCH_AF_AEC_OFF, FALSE },
671 { CameraParameters::TOUCH_AF_AEC_ON, TRUE }
672};
673
Srinivasan Kannan71229622009-12-04 12:05:58 -0800674struct SensorType {
675 const char *name;
676 int rawPictureWidth;
677 int rawPictureHeight;
678 bool hasAutoFocusSupport;
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800679 int max_supported_snapshot_width;
680 int max_supported_snapshot_height;
Apurva Rajguruffe264a2010-03-09 13:50:53 -0800681 int bitMask;
Srinivasan Kannan71229622009-12-04 12:05:58 -0800682};
683
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -0700684
685/*
686 * Values based on aec.c
687 */
688
689#define EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR 12
690#define EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR -12
691#define EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR 0
692#define EXPOSURE_COMPENSATION_DENOMINATOR 6
693#define EXPOSURE_COMPENSATION_STEP ((float (1))/EXPOSURE_COMPENSATION_DENOMINATOR)
694
Srinivasan Kannan71229622009-12-04 12:05:58 -0800695static SensorType sensorTypes[] = {
Priyanka Kharat0fa7f9f2010-08-30 19:00:35 -0700696 { "12mp", 5464, 3120, true, 4000, 3000,0x00001fff },
Yen-Pin Hsiaoa6612f12010-07-19 15:17:21 -0700697 { "12mp_sn12m0pz",4032, 3024, true, 4000, 3000,0x00000fff },
Apurva Rajguruffe264a2010-03-09 13:50:53 -0800698 { "5mp", 2608, 1960, true, 2592, 1944,0x00000fff },
699 { "3mp", 2064, 1544, false, 2048, 1536,0x000007ff },
700 { "2mp", 3200, 1200, false, 1600, 1200,0x000007ff } };
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800701
Srinivasan Kannan71229622009-12-04 12:05:58 -0800702
703static SensorType * sensorType;
704
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800705static const str_map picture_formats[] = {
706 {CameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
707 {CameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
708};
709
Mohan Kandrabf6146d2010-07-20 18:48:37 -0700710static const str_map frame_rate_modes[] = {
711 {CameraParameters::KEY_PREVIEW_FRAME_RATE_AUTO_MODE, FPS_MODE_AUTO},
712 {CameraParameters::KEY_PREVIEW_FRAME_RATE_FIXED_MODE, FPS_MODE_FIXED}
713};
714
Mohan Kandra7110c242010-07-18 15:34:48 -0700715static int mPreviewFormat;
716static const str_map preview_formats[] = {
717 {CameraParameters::PIXEL_FORMAT_YUV420SP, CAMERA_YUV_420_NV21},
718 {CameraParameters::PIXEL_FORMAT_YUV420SP_ADRENO, CAMERA_YUV_420_NV21_ADRENO}
719};
720
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800721static bool parameter_string_initialized = false;
722static String8 preview_size_values;
723static String8 picture_size_values;
724static String8 antibanding_values;
725static String8 effect_values;
Apurva Rajguru55562b02009-12-03 12:25:35 -0800726static String8 autoexposure_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800727static String8 whitebalance_values;
728static String8 flash_values;
729static String8 focus_mode_values;
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530730static String8 iso_values;
731static String8 lensshade_values;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -0700732static String8 touchafaec_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800733static String8 picture_format_values;
Apurva Rajguru08383852010-05-17 14:25:39 -0700734static String8 scenemode_values;
Apurva Rajguru7b949c92010-05-26 15:46:57 -0700735static String8 continuous_af_values;
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700736static String8 zoom_ratio_values;
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700737static String8 preview_frame_rate_values;
Mohan Kandrabf6146d2010-07-20 18:48:37 -0700738static String8 frame_rate_mode_values;
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -0700739static String8 scenedetect_values;
Mohan Kandra7110c242010-07-18 15:34:48 -0700740static String8 preview_format_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800741
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800742static String8 create_sizes_str(const camera_size_type *sizes, int len) {
743 String8 str;
744 char buffer[32];
745
746 if (len > 0) {
747 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
748 str.append(buffer);
749 }
750 for (int i = 1; i < len; i++) {
751 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
752 str.append(buffer);
753 }
754 return str;
755}
756
757static String8 create_values_str(const str_map *values, int len) {
758 String8 str;
759
760 if (len > 0) {
761 str.append(values[0].desc);
762 }
763 for (int i = 1; i < len; i++) {
764 str.append(",");
765 str.append(values[i].desc);
766 }
767 return str;
768}
769
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700770
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700771static String8 create_str(int16_t *arr, int length){
772 String8 str;
773 char buffer[32];
774
775 if(length > 0){
776 snprintf(buffer, sizeof(buffer), "%d", arr[0]);
777 str.append(buffer);
778 }
779
780 for (int i =1;i<length;i++){
781 snprintf(buffer, sizeof(buffer), ",%d",arr[i]);
782 str.append(buffer);
783 }
784 return str;
785}
786
Srinivasan Kannana01751b2010-06-24 18:44:40 -0700787static String8 create_values_range_str(int min, int max){
788 String8 str;
789 char buffer[32];
790
791 if(min <= max){
792 snprintf(buffer, sizeof(buffer), "%d", min);
793 str.append(buffer);
794
795 for (int i = min + 1; i <= max; i++) {
796 snprintf(buffer, sizeof(buffer), ",%d", i);
797 str.append(buffer);
798 }
799 }
800 return str;
801}
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700802
Sravankb4f5f1c2010-01-21 11:06:17 +0530803extern "C" {
804//------------------------------------------------------------------------
805// : 720p busyQ funcitons
806// --------------------------------------------------------------------
807static struct fifo_queue g_busy_frame_queue =
808 {0, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
809};
810/*===========================================================================
811 * FUNCTION cam_frame_wait_video
812 *
813 * DESCRIPTION this function waits a video in the busy queue
814 * ===========================================================================*/
815
816static void cam_frame_wait_video (void)
817{
818 LOGV("cam_frame_wait_video E ");
819 if ((g_busy_frame_queue.num_of_frames) <=0){
820 pthread_cond_wait(&(g_busy_frame_queue.wait), &(g_busy_frame_queue.mut));
821 }
822 LOGV("cam_frame_wait_video X");
823 return;
824}
825
826/*===========================================================================
827 * FUNCTION cam_frame_flush_video
828 *
829 * DESCRIPTION this function deletes all the buffers in busy queue
830 * ===========================================================================*/
831void cam_frame_flush_video (void)
832{
833 LOGV("cam_frame_flush_video: in n = %d\n", g_busy_frame_queue.num_of_frames);
834 pthread_mutex_lock(&(g_busy_frame_queue.mut));
835
836 while (g_busy_frame_queue.front)
837 {
838 //dequeue from the busy queue
839 struct fifo_node *node = dequeue (&g_busy_frame_queue);
840 if(node)
841 free(node);
842
843 LOGV("cam_frame_flush_video: node \n");
844 }
845 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
846 LOGV("cam_frame_flush_video: out n = %d\n", g_busy_frame_queue.num_of_frames);
847 return ;
848}
849/*===========================================================================
850 * FUNCTION cam_frame_get_video
851 *
852 * DESCRIPTION this function returns a video frame from the head
853 * ===========================================================================*/
854static struct msm_frame * cam_frame_get_video()
855{
856 struct msm_frame *p = NULL;
857 LOGV("cam_frame_get_video... in\n");
858 LOGV("cam_frame_get_video... got lock\n");
859 if (g_busy_frame_queue.front)
860 {
861 //dequeue
862 struct fifo_node *node = dequeue (&g_busy_frame_queue);
863 if (node)
864 {
865 p = (struct msm_frame *)node->f;
866 free (node);
867 }
868 LOGV("cam_frame_get_video... out = %x\n", p->buffer);
869 }
870 return p;
871}
872
873/*===========================================================================
874 * FUNCTION cam_frame_post_video
875 *
876 * DESCRIPTION this function add a busy video frame to the busy queue tails
877 * ===========================================================================*/
878static void cam_frame_post_video (struct msm_frame *p)
879{
880 if (!p)
881 {
882 LOGE("post video , buffer is null");
883 return;
884 }
885 LOGV("cam_frame_post_video... in = %x\n", (unsigned int)(p->buffer));
886 pthread_mutex_lock(&(g_busy_frame_queue.mut));
887 LOGV("post_video got lock. q count before enQ %d", g_busy_frame_queue.num_of_frames);
888 //enqueue to busy queue
889 struct fifo_node *node = (struct fifo_node *)malloc (sizeof (struct fifo_node));
890 if (node)
891 {
892 LOGV(" post video , enqueing in busy queue");
893 node->f = p;
894 node->next = NULL;
895 enqueue (&g_busy_frame_queue, node);
896 LOGV("post_video got lock. q count after enQ %d", g_busy_frame_queue.num_of_frames);
897 }
898 else
899 {
900 LOGE("cam_frame_post_video error... out of memory\n");
901 }
902
903 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
904 pthread_cond_signal(&(g_busy_frame_queue.wait));
905
906 LOGV("cam_frame_post_video... out = %x\n", p->buffer);
907
908 return;
909}
910
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -0800911void QualcommCameraHardware::storeTargetType(void) {
912 char mDeviceName[PROPERTY_VALUE_MAX];
913 property_get("ro.product.device",mDeviceName," ");
914 mCurrentTarget = TARGET_MAX;
915 for( int i = 0; i < TARGET_MAX ; i++) {
916 if( !strncmp(mDeviceName, targetList[i].targetStr, 7)) {
917 mCurrentTarget = targetList[i].targetEnum;
918 break;
919 }
920 }
921 LOGV(" Storing the current target type as %d ", mCurrentTarget );
922 return;
923}
924
Sravankb4f5f1c2010-01-21 11:06:17 +0530925//-------------------------------------------------------------------------------------
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800926static Mutex singleton_lock;
927static bool singleton_releasing;
Srinivasan Kannan78444e42010-06-10 15:39:29 -0700928static nsecs_t singleton_releasing_start_time;
929static const nsecs_t SINGLETON_RELEASING_WAIT_TIME = seconds_to_nanoseconds(5);
930static const nsecs_t SINGLETON_RELEASING_RECHECK_TIMEOUT = seconds_to_nanoseconds(1);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800931static Condition singleton_wait;
932
933static void receive_camframe_callback(struct msm_frame *frame);
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +0530934static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size);
Sravankb4f5f1c2010-01-21 11:06:17 +0530935static void receive_camframe_video_callback(struct msm_frame *frame); // 720p
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800936static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size);
937static void receive_jpeg_callback(jpeg_event_t status);
938static void receive_shutter_callback(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800939static void receive_camframetimeout_callback(void);
Mohan Kandra284966d2010-01-05 13:39:15 -0800940static int fb_fd = -1;
941static int32_t mMaxZoom = 0;
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700942static bool zoomSupported = false;
Mohan Kandra284966d2010-01-05 13:39:15 -0800943static bool native_get_maxzoom(int camfd, void *pZm);
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -0700944static bool native_get_zoomratios(int camfd, void *pZr, int maxZoomLevel);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800945
Mohan Kandrad9efed92010-01-15 19:08:39 -0800946static int dstOffset = 0;
947
Brian Steuer07704892009-12-18 18:07:33 -0800948static int camerafd;
949pthread_t w_thread;
950
951void *opencamerafd(void *data) {
952 camerafd = open(MSM_CAMERA_CONTROL, O_RDWR);
953 return NULL;
954}
955
Mohan Kandrad9efed92010-01-15 19:08:39 -0800956/* When using MDP zoom, double the preview buffers. The usage of these
957 * buffers is as follows:
958 * 1. As all the buffers comes under a single FD, and at initial registration,
959 * this FD will be passed to surface flinger, surface flinger can have access
960 * to all the buffers when needed.
961 * 2. Only "kPreviewBufferCount" buffers (SrcSet) will be registered with the
962 * camera driver to receive preview frames. The remaining buffers (DstSet),
963 * will be used at HAL and by surface flinger only when crop information
964 * is present in the frame.
965 * 3. When there is no crop information, there will be no call to MDP zoom,
966 * and the buffers in SrcSet will be passed to surface flinger to display.
967 * 4. With crop information present, MDP zoom will be called, and the final
968 * data will be placed in a buffer from DstSet, and this buffer will be given
969 * to surface flinger to display.
970 */
971#define NUM_MORE_BUFS 2
972
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800973QualcommCameraHardware::QualcommCameraHardware()
974 : mParameters(),
975 mCameraRunning(false),
976 mPreviewInitialized(false),
977 mFrameThreadRunning(false),
Mohan Kandra156d0ac2010-01-25 16:59:17 -0800978 mVideoThreadRunning(false),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800979 mSnapshotThreadRunning(false),
Mohan Kandra1659b0c2010-07-18 16:36:25 -0700980 mEncodePending(false),
Mohan Kandraca2e7a92010-06-21 15:48:45 -0700981 mJpegThreadRunning(false),
Mohan Kandra62429cc2010-07-19 10:21:05 -0700982 mInSnapshotMode(false),
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800983 mSnapshotFormat(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800984 mReleasedRecordingFrame(false),
985 mPreviewFrameSize(0),
986 mRawSize(0),
Mohan Kandra1659b0c2010-07-18 16:36:25 -0700987 mCbCrOffsetRaw(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800988 mCameraControlFd(-1),
989 mAutoFocusThreadRunning(false),
990 mAutoFocusFd(-1),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800991 mBrightness(0),
Apurva Rajguruf12d9d22010-04-05 16:47:12 -0700992 mHJR(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800993 mInPreviewCallback(false),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800994 mUseOverlay(0),
995 mOverlay(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800996 mMsgEnabled(0),
997 mNotifyCallback(0),
998 mDataCallback(0),
999 mDataCallbackTimestamp(0),
Mohan Kandra740cfce2010-01-07 12:58:24 -08001000 mCallbackCookie(0),
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001001 mInitialized(false),
Apurva Rajguru3da1a702010-07-28 12:32:42 -07001002 mDebugFps(0),
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001003 mSnapshotDone(0),
1004 mDisEnabled(0),
Mohan Kandra9aff1f42010-09-02 19:00:41 -07001005 mRotation(0),
1006 mResetOverlayCrop(false)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001007{
Mohan Kandra0d115d12010-08-19 11:47:15 -07001008 LOGI("QualcommCameraHardware constructor E");
Brian Steuer07704892009-12-18 18:07:33 -08001009 // Start opening camera device in a separate thread/ Since this
1010 // initializes the sensor hardware, this can take a long time. So,
1011 // start the process here so it will be ready by the time it's
1012 // needed.
1013 if ((pthread_create(&w_thread, NULL, opencamerafd, NULL)) != 0) {
1014 LOGE("Camera open thread creation failed");
1015 }
1016
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001017 memset(&mDimension, 0, sizeof(mDimension));
1018 memset(&mCrop, 0, sizeof(mCrop));
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001019 memset(&zoomCropInfo, 0, sizeof(zoom_crop_info));
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08001020 storeTargetType();
Mohan Kandra740cfce2010-01-07 12:58:24 -08001021 char value[PROPERTY_VALUE_MAX];
1022 property_get("persist.debug.sf.showfps", value, "0");
1023 mDebugFps = atoi(value);
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301024 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_MSM8660 ) {
Sravankb4f5f1c2010-01-21 11:06:17 +05301025 kPreviewBufferCountActual = kPreviewBufferCount;
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301026 kRecordBufferCount = RECORD_BUFFERS;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001027 recordframes = new msm_frame[kRecordBufferCount];
Mohan Kandra1fd90f92010-06-17 14:54:17 -07001028 record_buffers_tracking_flag = new bool[kRecordBufferCount];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001029 }
1030 else {
Sravankb4f5f1c2010-01-21 11:06:17 +05301031 kPreviewBufferCountActual = kPreviewBufferCount + NUM_MORE_BUFS;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001032 if( mCurrentTarget == TARGET_QSD8250 ) {
1033 kRecordBufferCount = RECORD_BUFFERS_8x50;
1034 recordframes = new msm_frame[kRecordBufferCount];
Mohan Kandra1fd90f92010-06-17 14:54:17 -07001035 record_buffers_tracking_flag = new bool[kRecordBufferCount];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07001036 }
1037 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001038
1039 switch(mCurrentTarget){
1040 case TARGET_MSM7627:
1041 jpegPadding = 8;
1042 break;
1043 case TARGET_QSD8250:
1044 case TARGET_MSM7630:
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301045 case TARGET_MSM8660:
Srinivasan Kannan5701a942010-04-15 16:17:21 -07001046 jpegPadding = 0;
1047 break;
1048 default:
1049 jpegPadding = 0;
1050 break;
1051 }
Mohan Kandra7110c242010-07-18 15:34:48 -07001052 // Initialize with default format values. The format values can be
1053 // overriden when application requests.
1054 mDimension.prev_format = CAMERA_YUV_420_NV21;
1055 mPreviewFormat = CAMERA_YUV_420_NV21;
1056 mDimension.enc_format = CAMERA_YUV_420_NV21;
Mohan Kandra88db27a2010-08-22 12:33:36 -07001057 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660))
Mohan Kandra7110c242010-07-18 15:34:48 -07001058 mDimension.enc_format = CAMERA_YUV_420_NV12;
1059
1060 mDimension.main_img_format = CAMERA_YUV_420_NV21;
1061 mDimension.thumb_format = CAMERA_YUV_420_NV21;
1062
Mohan Kandrafdbc2192010-08-24 20:39:59 -07001063 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660) ){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001064 /* DIS is enabled all the time in VPE support targets.
1065 * No provision for the user to control this.
1066 */
1067 mDisEnabled = 1;
Mohan Kandraec958742010-08-19 10:56:05 -07001068 /* Get the DIS value from properties, to check whether
1069 * DIS is disabled or not
1070 */
1071 property_get("persist.camera.hal.dis", value, "1");
1072 mDisEnabled = atoi(value);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001073 mVpeEnabled = 1;
1074 }
1075
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001076 LOGV("constructor EX");
1077}
1078
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001079void QualcommCameraHardware::filterPreviewSizes(){
1080
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001081 unsigned int boardMask = 0;
Mohan Kandra62429cc2010-07-19 10:21:05 -07001082 unsigned int prop = 0;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001083 for(prop=0;prop<sizeof(boardProperties)/sizeof(board_property);prop++){
1084 if(mCurrentTarget == boardProperties[prop].target){
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001085 boardMask = boardProperties[prop].previewSizeMask;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001086 break;
1087 }
1088 }
1089
Apurva Rajguruffe264a2010-03-09 13:50:53 -08001090 int bitMask = boardMask & sensorType->bitMask;
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001091 if(bitMask){
1092 unsigned int mask = 1<<(PREVIEW_SIZE_COUNT-1);
1093 previewSizeCount=0;
1094 unsigned int i = 0;
1095 while(mask){
1096 if(mask&bitMask)
1097 supportedPreviewSizes[previewSizeCount++] =
1098 preview_sizes[i];
1099 i++;
1100 mask = mask >> 1;
1101 }
1102 }
1103}
1104
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001105//filter Picture sizes based on max width and height
1106void QualcommCameraHardware::filterPictureSizes(){
1107 int i;
1108 for(i=0;i<PICTURE_SIZE_COUNT;i++){
1109 if(((picture_sizes[i].width <=
1110 sensorType->max_supported_snapshot_width) &&
1111 (picture_sizes[i].height <=
1112 sensorType->max_supported_snapshot_height))){
1113 picture_sizes_ptr = picture_sizes + i;
1114 supportedPictureSizesCount = PICTURE_SIZE_COUNT - i ;
1115 return ;
1116 }
1117 }
1118}
1119
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001120bool QualcommCameraHardware::supportsSceneDetection() {
1121 int prop = 0;
1122 for(prop=0; prop<sizeof(boardProperties)/sizeof(board_property); prop++) {
1123 if((mCurrentTarget == boardProperties[prop].target)
1124 && boardProperties[prop].hasSceneDetect == true) {
1125 return true;
1126 break;
1127 }
1128 }
1129 return false;
1130}
1131
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001132void QualcommCameraHardware::initDefaultParameters()
1133{
Mohan Kandra0d115d12010-08-19 11:47:15 -07001134 LOGI("initDefaultParameters E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001135
Apurva Rajguru59ec7122010-08-25 13:03:30 -07001136 findSensorType();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001137 // Initialize constant parameter strings. This will happen only once in the
1138 // lifetime of the mediaserver process.
1139 if (!parameter_string_initialized) {
1140 antibanding_values = create_values_str(
1141 antibanding, sizeof(antibanding) / sizeof(str_map));
1142 effect_values = create_values_str(
1143 effects, sizeof(effects) / sizeof(str_map));
Apurva Rajguru55562b02009-12-03 12:25:35 -08001144 autoexposure_values = create_values_str(
1145 autoexposure, sizeof(autoexposure) / sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001146 whitebalance_values = create_values_str(
1147 whitebalance, sizeof(whitebalance) / sizeof(str_map));
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001148
1149 //filter preview sizes
1150 filterPreviewSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001151 preview_size_values = create_sizes_str(
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001152 supportedPreviewSizes, previewSizeCount);
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001153 //filter picture sizes
1154 filterPictureSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001155 picture_size_values = create_sizes_str(
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08001156 picture_sizes_ptr, supportedPictureSizesCount);
1157
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001158 flash_values = create_values_str(
1159 flash, sizeof(flash) / sizeof(str_map));
Srinivasan Kannan71229622009-12-04 12:05:58 -08001160 if(sensorType->hasAutoFocusSupport){
1161 focus_mode_values = create_values_str(
1162 focus_modes, sizeof(focus_modes) / sizeof(str_map));
1163 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301164 iso_values = create_values_str(
1165 iso,sizeof(iso)/sizeof(str_map));
1166 lensshade_values = create_values_str(
1167 lensshade,sizeof(lensshade)/sizeof(str_map));
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001168
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07001169 if(sensorType->hasAutoFocusSupport){
1170 touchafaec_values = create_values_str(
1171 touchafaec,sizeof(touchafaec)/sizeof(str_map));
1172 }
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001173
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001174 picture_format_values = create_values_str(
1175 picture_formats, sizeof(picture_formats)/sizeof(str_map));
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001176
1177 if(sensorType->hasAutoFocusSupport){
1178 continuous_af_values = create_values_str(
1179 continuous_af, sizeof(continuous_af) / sizeof(str_map));
1180 }
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001181
1182 if(native_get_maxzoom(mCameraControlFd,
1183 (void *)&mMaxZoom) == true){
1184 LOGD("Maximum zoom value is %d", mMaxZoom);
1185 zoomSupported = true;
1186 if(mMaxZoom > 0){
1187 //if max zoom is available find the zoom ratios
1188 int16_t * zoomRatios = new int16_t[mMaxZoom+1];
1189 if(zoomRatios != NULL){
1190 if(native_get_zoomratios(mCameraControlFd,
1191 (void *)zoomRatios, mMaxZoom + 1) == true){
1192 zoom_ratio_values =
1193 create_str(zoomRatios, mMaxZoom + 1);
1194 }else {
1195 LOGE("Failed to get zoomratios...");
1196 }
1197 delete zoomRatios;
1198 } else {
1199 LOGE("zoom ratios failed to acquire memory");
1200 }
1201 }
1202 } else {
1203 zoomSupported = false;
1204 LOGE("Failed to get maximum zoom value...setting max "
1205 "zoom to zero");
1206 mMaxZoom = 0;
1207 }
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001208 preview_frame_rate_values = create_values_range_str(
1209 MINIMUM_FPS, MAXIMUM_FPS);
Apurva Rajguru08383852010-05-17 14:25:39 -07001210
1211 scenemode_values = create_values_str(
1212 scenemode, sizeof(scenemode) / sizeof(str_map));
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001213 if(supportsSceneDetection()) {
1214 scenedetect_values = create_values_str(
1215 scenedetect, sizeof(scenedetect) / sizeof(str_map));
1216 }
1217
1218 parameter_string_initialized = true;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001219 }
1220
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08001221 mParameters.setPreviewSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
1222 mDimension.display_width = DEFAULT_PREVIEW_WIDTH;
1223 mDimension.display_height = DEFAULT_PREVIEW_HEIGHT;
1224
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001225 mParameters.setPreviewFrameRate(DEFAULT_FPS);
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07001226 if((strcmp(mSensorInfo.name, "vx6953")) &&
Srinivasan Kannan2c99dba2010-07-28 13:50:53 -07001227 (strcmp(mSensorInfo.name, "VX6953")) &&
1228 (strcmp(sensorType->name, "2mp"))){
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07001229 mParameters.set(
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001230 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
1231 preview_frame_rate_values.string());
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07001232 }
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001233 mParameters.setPreviewFrameRateMode("frame-rate-auto");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001234 mParameters.setPreviewFormat("yuv420sp"); // informative
1235
1236 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
1237 mParameters.setPictureFormat("jpeg"); // informative
1238
Mohan Kandra785619a2010-02-01 21:52:42 -08001239 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "85"); // max quality
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001240 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
1241 THUMBNAIL_WIDTH_STR); // informative
1242 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
1243 THUMBNAIL_HEIGHT_STR); // informative
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08001244 mDimension.ui_thumbnail_width =
1245 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
1246 mDimension.ui_thumbnail_height =
1247 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001248 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
1249
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001250 if(zoomSupported){
1251 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true");
1252 LOGV("max zoom is %d", mMaxZoom);
1253 mParameters.set("max-zoom",mMaxZoom);
1254 mParameters.set(CameraParameters::KEY_ZOOM_RATIOS,
1255 zoom_ratio_values);
1256 } else {
1257 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, "false");
1258 }
Mohan Kandra39fad8d2010-07-15 12:29:19 -07001259 /* Enable zoom support for video application if VPE enabled */
1260 if(zoomSupported && mVpeEnabled) {
1261 mParameters.set("video-zoom-support", "true");
1262 } else {
1263 mParameters.set("video-zoom-support", "false");
1264 }
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001265
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001266 mParameters.set(CameraParameters::KEY_ANTIBANDING,
Mohan Kandra785619a2010-02-01 21:52:42 -08001267 CameraParameters::ANTIBANDING_OFF);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001268 mParameters.set(CameraParameters::KEY_EFFECT,
1269 CameraParameters::EFFECT_NONE);
Apurva Rajguru55562b02009-12-03 12:25:35 -08001270 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
1271 CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001272 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
1273 CameraParameters::WHITE_BALANCE_AUTO);
1274 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
1275 CameraParameters::FOCUS_MODE_AUTO);
Mohan Kandra7110c242010-07-18 15:34:48 -07001276 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_QSD8250) ) {
Priya Komarlingam044c7b52010-01-22 18:21:23 -08001277 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1278 "yuv420sp");
Mohan Kandra7110c242010-07-18 15:34:48 -07001279 }
1280 else {
1281 preview_format_values = create_values_str(
1282 preview_formats, sizeof(preview_formats) / sizeof(str_map));
1283 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1284 preview_format_values.string());
1285 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001286
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001287 frame_rate_mode_values = create_values_str(
1288 frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map));
1289 if((strcmp(mSensorInfo.name, "vx6953")) &&
Srinivasan Kannan2c99dba2010-07-28 13:50:53 -07001290 (strcmp(mSensorInfo.name, "VX6953")) &&
1291 (strcmp(sensorType->name, "2mp"))){
Mohan Kandrabf6146d2010-07-20 18:48:37 -07001292 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATE_MODES,
1293 frame_rate_mode_values.string());
1294 }
1295
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001296 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
1297 preview_size_values.string());
1298 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
1299 picture_size_values.string());
1300 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
1301 antibanding_values);
1302 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
Apurva Rajguru55562b02009-12-03 12:25:35 -08001303 mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001304 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
1305 whitebalance_values);
1306 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
1307 focus_mode_values);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001308 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1309 picture_format_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001310
1311 if (mSensorInfo.flash_enabled) {
1312 mParameters.set(CameraParameters::KEY_FLASH_MODE,
1313 CameraParameters::FLASH_MODE_OFF);
1314 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
1315 flash_values);
1316 }
1317
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08001318 mParameters.set(CameraParameters::KEY_MAX_SHARPNESS,
1319 CAMERA_MAX_SHARPNESS);
1320 mParameters.set(CameraParameters::KEY_MAX_CONTRAST,
1321 CAMERA_MAX_CONTRAST);
1322 mParameters.set(CameraParameters::KEY_MAX_SATURATION,
1323 CAMERA_MAX_SATURATION);
1324
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07001325 mParameters.set(
1326 CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
1327 EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR);
1328 mParameters.set(
1329 CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
1330 EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR);
1331 mParameters.set(
1332 CameraParameters::KEY_EXPOSURE_COMPENSATION,
1333 EXPOSURE_COMPENSATION_DEFAULT_NUMERATOR);
1334 mParameters.setFloat(
1335 CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
1336 EXPOSURE_COMPENSATION_STEP);
1337
Apurva Rajguru07185952010-01-22 15:40:07 -08001338 mParameters.set("luma-adaptation", "3");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001339 mParameters.set("zoom-supported", "true");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001340 mParameters.set("zoom", 0);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001341 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT,
1342 CameraParameters::PIXEL_FORMAT_JPEG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001343
Kiran Kumar H N595970b2010-01-12 10:41:09 -08001344 mParameters.set(CameraParameters::KEY_SHARPNESS,
1345 CAMERA_DEF_SHARPNESS);
1346 mParameters.set(CameraParameters::KEY_CONTRAST,
1347 CAMERA_DEF_CONTRAST);
1348 mParameters.set(CameraParameters::KEY_SATURATION,
1349 CAMERA_DEF_SATURATION);
1350
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301351 mParameters.set(CameraParameters::KEY_ISO_MODE,
1352 CameraParameters::ISO_AUTO);
1353 mParameters.set(CameraParameters::KEY_LENSSHADE,
1354 CameraParameters::LENSSHADE_ENABLE);
1355 mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
1356 iso_values);
1357 mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
1358 lensshade_values);
Apurva Rajguru08383852010-05-17 14:25:39 -07001359 mParameters.set(CameraParameters::KEY_SCENE_MODE,
1360 CameraParameters::SCENE_MODE_AUTO);
Mohan Kandra7110c242010-07-18 15:34:48 -07001361 mParameters.set("strtextures", "OFF");
1362
Apurva Rajguru08383852010-05-17 14:25:39 -07001363 mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
1364 scenemode_values);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07001365 mParameters.set(CameraParameters::KEY_CONTINUOUS_AF,
1366 CameraParameters::CONTINUOUS_AF_OFF);
1367 mParameters.set(CameraParameters::KEY_SUPPORTED_CONTINUOUS_AF,
1368 continuous_af_values);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07001369 mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC,
1370 CameraParameters::TOUCH_AF_AEC_OFF);
1371 mParameters.set(CameraParameters::KEY_SUPPORTED_TOUCH_AF_AEC,
1372 touchafaec_values);
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07001373 mParameters.setTouchIndexAec(-1, -1);
1374 mParameters.setTouchIndexAf(-1, -1);
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07001375 mParameters.set(CameraParameters::KEY_SCENE_DETECT,
1376 CameraParameters::SCENE_DETECT_OFF);
1377 mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_DETECT,
1378 scenedetect_values);
Priyanka Kharat67cfe532010-03-29 17:28:22 -07001379 if (setParameters(mParameters) != NO_ERROR) {
1380 LOGE("Failed to set default parameters?!");
1381 }
1382
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001383 mUseOverlay = useOverlay();
1384
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001385 /* Initialize the camframe_timeout_flag*/
1386 Mutex::Autolock l(&mCamframeTimeoutLock);
1387 camframe_timeout_flag = FALSE;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001388 mPostViewHeap = NULL;
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001389
Srinivasan Kannana01751b2010-06-24 18:44:40 -07001390 mInitialized = true;
1391
Mohan Kandra0d115d12010-08-19 11:47:15 -07001392 LOGI("initDefaultParameters X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001393}
1394
Srinivasan Kannan71229622009-12-04 12:05:58 -08001395void QualcommCameraHardware::findSensorType(){
1396 mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
1397 mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
1398 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1399 sizeof(cam_ctrl_dimension_t), &mDimension);
1400 if (ret) {
1401 unsigned int i;
1402 for (i = 0; i < sizeof(sensorTypes) / sizeof(SensorType); i++) {
1403 if (sensorTypes[i].rawPictureHeight
1404 == mDimension.raw_picture_height) {
1405 sensorType = sensorTypes + i;
1406 return;
1407 }
1408 }
1409 }
1410 //default to 5 mp
1411 sensorType = sensorTypes;
1412 return;
1413}
1414
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001415#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
1416
1417bool QualcommCameraHardware::startCamera()
1418{
1419 LOGV("startCamera E");
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08001420 if( mCurrentTarget == TARGET_MAX ) {
1421 LOGE(" Unable to determine the target type. Camera will not work ");
1422 return false;
1423 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001424#if DLOPEN_LIBMMCAMERA
1425 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
Priya Komarlingam9bb2d492010-06-23 19:21:52 -07001426
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001427 LOGV("loading liboemcamera at %p", libmmcamera);
1428 if (!libmmcamera) {
1429 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1430 return false;
1431 }
1432
1433 *(void **)&LINK_cam_frame =
1434 ::dlsym(libmmcamera, "cam_frame");
1435 *(void **)&LINK_camframe_terminate =
1436 ::dlsym(libmmcamera, "camframe_terminate");
1437
1438 *(void **)&LINK_jpeg_encoder_init =
1439 ::dlsym(libmmcamera, "jpeg_encoder_init");
1440
1441 *(void **)&LINK_jpeg_encoder_encode =
1442 ::dlsym(libmmcamera, "jpeg_encoder_encode");
1443
1444 *(void **)&LINK_jpeg_encoder_join =
1445 ::dlsym(libmmcamera, "jpeg_encoder_join");
1446
1447 *(void **)&LINK_mmcamera_camframe_callback =
1448 ::dlsym(libmmcamera, "mmcamera_camframe_callback");
1449
1450 *LINK_mmcamera_camframe_callback = receive_camframe_callback;
1451
1452 *(void **)&LINK_mmcamera_jpegfragment_callback =
1453 ::dlsym(libmmcamera, "mmcamera_jpegfragment_callback");
1454
1455 *LINK_mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
1456
1457 *(void **)&LINK_mmcamera_jpeg_callback =
1458 ::dlsym(libmmcamera, "mmcamera_jpeg_callback");
1459
1460 *LINK_mmcamera_jpeg_callback = receive_jpeg_callback;
1461
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001462 *(void **)&LINK_camframe_timeout_callback =
1463 ::dlsym(libmmcamera, "camframe_timeout_callback");
1464
1465 *LINK_camframe_timeout_callback = receive_camframetimeout_callback;
1466
Sravankb4f5f1c2010-01-21 11:06:17 +05301467 // 720 p new recording functions
1468 *(void **)&LINK_cam_frame_flush_free_video = ::dlsym(libmmcamera, "cam_frame_flush_free_video");
1469
1470 *(void **)&LINK_camframe_free_video = ::dlsym(libmmcamera, "cam_frame_add_free_video");
1471
1472 *(void **)&LINK_camframe_video_callback = ::dlsym(libmmcamera, "mmcamera_camframe_videocallback");
1473 *LINK_camframe_video_callback = receive_camframe_video_callback;
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08001474
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001475 *(void **)&LINK_mmcamera_shutter_callback =
1476 ::dlsym(libmmcamera, "mmcamera_shutter_callback");
1477
1478 *LINK_mmcamera_shutter_callback = receive_shutter_callback;
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08001479
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001480 *(void**)&LINK_jpeg_encoder_setMainImageQuality =
1481 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
Kiran Kumar H N8861f302010-01-05 12:01:41 -08001482
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001483 *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
1484 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
1485
1486 *(void**)&LINK_jpeg_encoder_setRotation =
1487 ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
1488
Mohan Kandra02486042010-06-18 16:49:43 -07001489 *(void**)&LINK_jpeg_encoder_get_buffer_offset =
1490 ::dlsym(libmmcamera, "jpeg_encoder_get_buffer_offset");
1491
Kiran Kumar H N8861f302010-01-05 12:01:41 -08001492/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001493 *(void**)&LINK_jpeg_encoder_setLocation =
1494 ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001495*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001496 *(void **)&LINK_cam_conf =
1497 ::dlsym(libmmcamera, "cam_conf");
1498
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001499/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001500 *(void **)&LINK_default_sensor_get_snapshot_sizes =
1501 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001502*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001503 *(void **)&LINK_launch_cam_conf_thread =
1504 ::dlsym(libmmcamera, "launch_cam_conf_thread");
1505
1506 *(void **)&LINK_release_cam_conf_thread =
1507 ::dlsym(libmmcamera, "release_cam_conf_thread");
1508
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301509 *(void **)&LINK_mmcamera_liveshot_callback =
1510 ::dlsym(libmmcamera, "mmcamera_liveshot_callback");
1511
1512 *LINK_mmcamera_liveshot_callback = receive_liveshot_callback;
1513
1514 *(void **)&LINK_cancel_liveshot =
1515 ::dlsym(libmmcamera, "cancel_liveshot");
1516
1517 *(void **)&LINK_set_liveshot_params =
1518 ::dlsym(libmmcamera, "set_liveshot_params");
1519
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001520/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001521 *(void **)&LINK_zoom_crop_upscale =
1522 ::dlsym(libmmcamera, "zoom_crop_upscale");
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001523*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001524
1525#else
1526 mmcamera_camframe_callback = receive_camframe_callback;
1527 mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
1528 mmcamera_jpeg_callback = receive_jpeg_callback;
1529 mmcamera_shutter_callback = receive_shutter_callback;
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301530 mmcamera_liveshot_callback = receive_liveshot_callback;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001531#endif // DLOPEN_LIBMMCAMERA
1532
1533 /* The control thread is in libcamera itself. */
Brian Steuer07704892009-12-18 18:07:33 -08001534 if (pthread_join(w_thread, NULL) != 0) {
1535 LOGE("Camera open thread exit failed");
1536 return false;
1537 }
1538 mCameraControlFd = camerafd;
1539
Kiran Kumar H N585bc362010-01-19 13:04:44 -08001540 if (mCameraControlFd < 0) {
1541 LOGE("startCamera X: %s open failed: %s!",
1542 MSM_CAMERA_CONTROL,
1543 strerror(errno));
1544 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001545 }
1546
Nishant Pandit3c278cd2010-07-13 15:56:04 +05301547 if((mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)){
Mohan Kandra284966d2010-01-05 13:39:15 -08001548 fb_fd = open("/dev/graphics/fb0", O_RDWR);
1549 if (fb_fd < 0) {
1550 LOGE("startCamera: fb0 open failed: %s!", strerror(errno));
1551 return FALSE;
1552 }
1553 }
1554
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001555 /* This will block until the control thread is launched. After that, sensor
1556 * information becomes available.
1557 */
1558
1559 if (LINK_launch_cam_conf_thread()) {
1560 LOGE("failed to launch the camera config thread");
1561 return false;
1562 }
1563
1564 memset(&mSensorInfo, 0, sizeof(mSensorInfo));
1565 if (ioctl(mCameraControlFd,
1566 MSM_CAM_IOCTL_GET_SENSOR_INFO,
1567 &mSensorInfo) < 0)
1568 LOGW("%s: cannot retrieve sensor info!", __FUNCTION__);
1569 else
1570 LOGI("%s: camsensor name %s, flash %d", __FUNCTION__,
1571 mSensorInfo.name, mSensorInfo.flash_enabled);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001572/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001573 picture_sizes = LINK_default_sensor_get_snapshot_sizes(&PICTURE_SIZE_COUNT);
1574 if (!picture_sizes || !PICTURE_SIZE_COUNT) {
1575 LOGE("startCamera X: could not get snapshot sizes");
1576 return false;
1577 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001578*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001579 LOGV("startCamera X");
1580 return true;
1581}
1582
1583status_t QualcommCameraHardware::dump(int fd,
1584 const Vector<String16>& args) const
1585{
1586 const size_t SIZE = 256;
1587 char buffer[SIZE];
1588 String8 result;
1589
1590 // Dump internal primitives.
1591 result.append("QualcommCameraHardware::dump");
1592 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
1593 result.append(buffer);
1594 int width, height;
1595 mParameters.getPreviewSize(&width, &height);
1596 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
1597 result.append(buffer);
1598 mParameters.getPictureSize(&width, &height);
1599 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
1600 result.append(buffer);
1601 snprintf(buffer, 255,
1602 "preview frame size(%d), raw size (%d), jpeg size (%d) "
1603 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
1604 mJpegSize, mJpegMaxSize);
1605 result.append(buffer);
1606 write(fd, result.string(), result.size());
1607
1608 // Dump internal objects.
Mohan Kandrad9efed92010-01-15 19:08:39 -08001609 if (mPreviewHeap != 0) {
1610 mPreviewHeap->dump(fd, args);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001611 }
1612 if (mRawHeap != 0) {
1613 mRawHeap->dump(fd, args);
1614 }
1615 if (mJpegHeap != 0) {
1616 mJpegHeap->dump(fd, args);
1617 }
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001618 if(mRawSnapshotAshmemHeap != 0 ){
1619 mRawSnapshotAshmemHeap->dump(fd, args);
1620 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001621 mParameters.dump(fd, args);
1622 return NO_ERROR;
1623}
1624
Mohan Kandra284966d2010-01-05 13:39:15 -08001625static bool native_get_maxzoom(int camfd, void *pZm)
1626{
1627 LOGV("native_get_maxzoom E");
1628
1629 struct msm_ctrl_cmd ctrlCmd;
1630 int32_t *pZoom = (int32_t *)pZm;
1631
1632 ctrlCmd.type = CAMERA_GET_PARM_MAXZOOM;
1633 ctrlCmd.timeout_ms = 5000;
1634 ctrlCmd.length = sizeof(int32_t);
1635 ctrlCmd.value = pZoom;
1636 ctrlCmd.resp_fd = camfd;
1637
1638 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1639 LOGE("native_get_maxzoom: ioctl fd %d error %s",
1640 camfd,
1641 strerror(errno));
1642 return false;
1643 }
Brian Steuerb62adbd2010-02-02 14:47:08 -08001644 LOGD("ctrlCmd.value = %d", *(int32_t *)ctrlCmd.value);
Mohan Kandra284966d2010-01-05 13:39:15 -08001645 memcpy(pZoom, (int32_t *)ctrlCmd.value, sizeof(int32_t));
1646
1647 LOGV("native_get_maxzoom X");
1648 return true;
1649}
1650
Srinivasan Kannan6bce42b2010-07-12 19:10:08 -07001651static bool native_get_zoomratios(int camfd, void *pZr, int maxZoomSize)
1652{
1653 LOGV("native_get_zoomratios E");
1654 struct msm_ctrl_cmd ctrlCmd;
1655 int16_t *zoomRatios = (int16_t *)pZr;
1656
1657 if(maxZoomSize <= 0)
1658 return false;
1659
1660 ctrlCmd.type = CAMERA_GET_PARM_ZOOMRATIOS;
1661 ctrlCmd.timeout_ms = 5000;
1662 ctrlCmd.length = sizeof(int16_t)* (maxZoomSize);
1663 ctrlCmd.value = zoomRatios;
1664 ctrlCmd.resp_fd = camfd;
1665
1666 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1667 LOGE("native_get_zoomratios: ioctl fd %d error %s",
1668 camfd,
1669 strerror(errno));
1670 return false;
1671 }
1672 LOGV("native_get_zoomratios X");
1673 return true;
1674}
1675
1676
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001677static bool native_set_afmode(int camfd, isp3a_af_mode_t af_type)
1678{
1679 int rc;
1680 struct msm_ctrl_cmd ctrlCmd;
1681
1682 ctrlCmd.timeout_ms = 5000;
1683 ctrlCmd.type = CAMERA_SET_PARM_AUTO_FOCUS;
1684 ctrlCmd.length = sizeof(af_type);
1685 ctrlCmd.value = &af_type;
1686 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1687
1688 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0)
1689 LOGE("native_set_afmode: ioctl fd %d error %s\n",
1690 camfd,
1691 strerror(errno));
1692
1693 LOGV("native_set_afmode: ctrlCmd.status == %d\n", ctrlCmd.status);
1694 return rc >= 0 && ctrlCmd.status == CAMERA_EXIT_CB_DONE;
1695}
1696
1697static bool native_cancel_afmode(int camfd, int af_fd)
1698{
1699 int rc;
1700 struct msm_ctrl_cmd ctrlCmd;
1701
1702 ctrlCmd.timeout_ms = 0;
1703 ctrlCmd.type = CAMERA_AUTO_FOCUS_CANCEL;
1704 ctrlCmd.length = 0;
1705 ctrlCmd.value = NULL;
1706 ctrlCmd.resp_fd = -1; // there's no response fd
1707
1708 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd)) < 0)
1709 {
1710 LOGE("native_cancel_afmode: ioctl fd %d error %s\n",
1711 camfd,
1712 strerror(errno));
1713 return false;
1714 }
1715
1716 return true;
1717}
1718
1719static bool native_start_preview(int camfd)
1720{
1721 struct msm_ctrl_cmd ctrlCmd;
1722
1723 ctrlCmd.timeout_ms = 5000;
1724 ctrlCmd.type = CAMERA_START_PREVIEW;
1725 ctrlCmd.length = 0;
1726 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1727
1728 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1729 LOGE("native_start_preview: MSM_CAM_IOCTL_CTRL_COMMAND fd %d error %s",
1730 camfd,
1731 strerror(errno));
1732 return false;
1733 }
1734
1735 return true;
1736}
1737
1738static bool native_get_picture (int camfd, common_crop_t *crop)
1739{
1740 struct msm_ctrl_cmd ctrlCmd;
1741
1742 ctrlCmd.timeout_ms = 5000;
1743 ctrlCmd.length = sizeof(common_crop_t);
1744 ctrlCmd.value = crop;
1745
1746 if(ioctl(camfd, MSM_CAM_IOCTL_GET_PICTURE, &ctrlCmd) < 0) {
1747 LOGE("native_get_picture: MSM_CAM_IOCTL_GET_PICTURE fd %d error %s",
1748 camfd,
1749 strerror(errno));
1750 return false;
1751 }
1752
1753 LOGV("crop: in1_w %d", crop->in1_w);
1754 LOGV("crop: in1_h %d", crop->in1_h);
1755 LOGV("crop: out1_w %d", crop->out1_w);
1756 LOGV("crop: out1_h %d", crop->out1_h);
1757
1758 LOGV("crop: in2_w %d", crop->in2_w);
1759 LOGV("crop: in2_h %d", crop->in2_h);
1760 LOGV("crop: out2_w %d", crop->out2_w);
1761 LOGV("crop: out2_h %d", crop->out2_h);
1762
1763 LOGV("crop: update %d", crop->update_flag);
1764
1765 return true;
1766}
1767
1768static bool native_stop_preview(int camfd)
1769{
1770 struct msm_ctrl_cmd ctrlCmd;
1771 ctrlCmd.timeout_ms = 5000;
1772 ctrlCmd.type = CAMERA_STOP_PREVIEW;
1773 ctrlCmd.length = 0;
1774 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1775
1776 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1777 LOGE("native_stop_preview: ioctl fd %d error %s",
1778 camfd,
1779 strerror(errno));
1780 return false;
1781 }
1782
1783 return true;
1784}
1785
1786static bool native_prepare_snapshot(int camfd)
1787{
1788 int ioctlRetVal = true;
1789 struct msm_ctrl_cmd ctrlCmd;
1790
1791 ctrlCmd.timeout_ms = 1000;
1792 ctrlCmd.type = CAMERA_PREPARE_SNAPSHOT;
1793 ctrlCmd.length = 0;
1794 ctrlCmd.value = NULL;
1795 ctrlCmd.resp_fd = camfd;
1796
1797 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1798 LOGE("native_prepare_snapshot: ioctl fd %d error %s",
1799 camfd,
1800 strerror(errno));
1801 return false;
1802 }
1803 return true;
1804}
1805
1806static bool native_start_snapshot(int camfd)
1807{
1808 struct msm_ctrl_cmd ctrlCmd;
1809
1810 ctrlCmd.timeout_ms = 5000;
1811 ctrlCmd.type = CAMERA_START_SNAPSHOT;
1812 ctrlCmd.length = 0;
1813 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1814
1815 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1816 LOGE("native_start_snapshot: ioctl fd %d error %s",
1817 camfd,
1818 strerror(errno));
1819 return false;
1820 }
1821
1822 return true;
1823}
1824
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05301825static bool native_start_liveshot(int camfd)
1826{
1827 int ret;
1828 struct msm_ctrl_cmd ctrlCmd;
1829 ctrlCmd.timeout_ms = 5000;
1830 ctrlCmd.type = CAMERA_START_LIVESHOT;
1831 ctrlCmd.length = 0;
1832 ctrlCmd.value = NULL;
1833 ctrlCmd.resp_fd = camfd;
1834 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1835 LOGE("native_start_liveshot: ioctl failed. ioctl return value is %d ", ret);
1836 return false;
1837 }
1838 return true;
1839}
1840
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001841static bool native_start_raw_snapshot(int camfd)
1842{
1843 int ret;
1844 struct msm_ctrl_cmd ctrlCmd;
1845
1846 ctrlCmd.timeout_ms = 1000;
1847 ctrlCmd.type = CAMERA_START_RAW_SNAPSHOT;
1848 ctrlCmd.length = 0;
1849 ctrlCmd.value = NULL;
1850 ctrlCmd.resp_fd = camfd;
1851
1852 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1853 LOGE("native_start_raw_snapshot: ioctl failed. ioctl return value "\
1854 "is %d \n", ret);
1855 return false;
1856 }
1857 return true;
1858}
1859
1860
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001861static bool native_stop_snapshot (int camfd)
1862{
1863 struct msm_ctrl_cmd ctrlCmd;
1864
1865 ctrlCmd.timeout_ms = 0;
1866 ctrlCmd.type = CAMERA_STOP_SNAPSHOT;
1867 ctrlCmd.length = 0;
1868 ctrlCmd.resp_fd = -1;
1869
1870 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd) < 0) {
1871 LOGE("native_stop_snapshot: ioctl fd %d error %s",
1872 camfd,
1873 strerror(errno));
1874 return false;
1875 }
1876
1877 return true;
1878}
Sravankb4f5f1c2010-01-21 11:06:17 +05301879/*===========================================================================
1880 * FUNCTION - native_start_recording -
1881 *
1882 * DESCRIPTION:
1883 *==========================================================================*/
1884static bool native_start_recording(int camfd)
1885{
1886 int ret;
1887 struct msm_ctrl_cmd ctrlCmd;
1888
1889 ctrlCmd.timeout_ms = 1000;
1890 ctrlCmd.type = CAMERA_START_RECORDING;
1891 ctrlCmd.length = 0;
1892 ctrlCmd.value = NULL;
1893 ctrlCmd.resp_fd = camfd;
1894
1895 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1896 LOGE("native_start_recording: ioctl failed. ioctl return value "\
1897 "is %d \n", ret);
1898 return false;
1899 }
Mohan Kandraf1ebf982010-02-02 15:25:43 -08001900 LOGV("native_start_recording: ioctl good. ioctl return value is %d \n",ret);
Sravankb4f5f1c2010-01-21 11:06:17 +05301901
1902 /* TODO: Check status of postprocessing if there is any,
1903 * PP status should be in ctrlCmd */
1904
1905 return true;
1906}
1907
1908/*===========================================================================
1909 * FUNCTION - native_stop_recording -
1910 *
1911 * DESCRIPTION:
1912 *==========================================================================*/
1913static bool native_stop_recording(int camfd)
1914{
1915 int ret;
1916 struct msm_ctrl_cmd ctrlCmd;
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08001917 LOGV("in native_stop_recording ");
Sravankb4f5f1c2010-01-21 11:06:17 +05301918 ctrlCmd.timeout_ms = 1000;
1919 ctrlCmd.type = CAMERA_STOP_RECORDING;
1920 ctrlCmd.length = 0;
1921 ctrlCmd.value = NULL;
1922 ctrlCmd.resp_fd = camfd;
1923
1924 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1925 LOGE("native_stop_video: ioctl failed. ioctl return value is %d \n",
1926 ret);
1927 return false;
1928 }
1929 LOGV("in native_stop_recording returned %d", ret);
1930 return true;
1931}
1932/*===========================================================================
1933 * FUNCTION - native_start_video -
1934 *
1935 * DESCRIPTION:
1936 *==========================================================================*/
1937static bool native_start_video(int camfd)
1938{
1939 int ret;
1940 struct msm_ctrl_cmd ctrlCmd;
1941
1942 ctrlCmd.timeout_ms = 1000;
1943 ctrlCmd.type = CAMERA_START_VIDEO;
1944 ctrlCmd.length = 0;
1945 ctrlCmd.value = NULL;
1946 ctrlCmd.resp_fd = camfd;
1947
1948 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1949 LOGE("native_start_video: ioctl failed. ioctl return value is %d \n",
1950 ret);
1951 return false;
1952 }
1953
1954 /* TODO: Check status of postprocessing if there is any,
1955 * PP status should be in ctrlCmd */
1956
1957 return true;
1958}
1959
1960/*===========================================================================
1961 * FUNCTION - native_stop_video -
1962 *
1963 * DESCRIPTION:
1964 *==========================================================================*/
1965static bool native_stop_video(int camfd)
1966{
1967 int ret;
1968 struct msm_ctrl_cmd ctrlCmd;
1969
1970 ctrlCmd.timeout_ms = 1000;
1971 ctrlCmd.type = CAMERA_STOP_VIDEO;
1972 ctrlCmd.length = 0;
1973 ctrlCmd.value = NULL;
1974 ctrlCmd.resp_fd = camfd;
1975
1976 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1977 LOGE("native_stop_video: ioctl failed. ioctl return value is %d \n",
1978 ret);
1979 return false;
1980 }
1981
1982 return true;
1983}
1984/*==========================================================================*/
1985
1986static cam_frame_start_parms frame_parms;
1987static int recordingState = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001988
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001989static rat_t latitude[3];
1990static rat_t longitude[3];
1991static char lonref[2];
1992static char latref[2];
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001993static rat_t altitude;
Apurva Rajguru5ec76132010-06-16 17:43:46 -07001994static rat_t gpsTimestamp[3];
1995static char dateTime[20];
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001996static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
1997 uint32_t count, uint8_t copy, void *data) {
1998
1999 if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
2000 LOGE("Number of entries exceeded limit");
2001 return;
2002 }
2003
2004 int index = exif_table_numEntries;
2005 exif_data[index].tag_id = tagid;
2006 exif_data[index].tag_entry.type = type;
2007 exif_data[index].tag_entry.count = count;
2008 exif_data[index].tag_entry.copy = copy;
2009 if((type == EXIF_RATIONAL) && (count > 1))
2010 exif_data[index].tag_entry.data._rats = (rat_t *)data;
2011 if((type == EXIF_RATIONAL) && (count == 1))
2012 exif_data[index].tag_entry.data._rat = *(rat_t *)data;
2013 else if(type == EXIF_ASCII)
2014 exif_data[index].tag_entry.data._ascii = (char *)data;
2015 else if(type == EXIF_BYTE)
2016 exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
2017
2018 // Increase number of entries
2019 exif_table_numEntries++;
2020}
2021
2022static void parseLatLong(const char *latlonString, int *pDegrees,
2023 int *pMinutes, int *pSeconds ) {
2024
2025 double value = atof(latlonString);
2026 value = fabs(value);
2027 int degrees = (int) value;
2028
2029 double remainder = value - degrees;
2030 int minutes = (int) (remainder * 60);
2031 int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
2032
2033 *pDegrees = degrees;
2034 *pMinutes = minutes;
2035 *pSeconds = seconds;
2036}
2037
2038static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
2039
2040 int degrees, minutes, seconds;
2041
2042 parseLatLong(latlonString, &degrees, &minutes, &seconds);
2043
2044 rat_t value[3] = { {degrees, 1},
2045 {minutes, 1},
2046 {seconds, 1000} };
2047
2048 if(tag == EXIFTAGID_GPS_LATITUDE) {
2049 memcpy(latitude, value, sizeof(latitude));
2050 addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
2051 1, (void *)latitude);
2052 } else {
2053 memcpy(longitude, value, sizeof(longitude));
2054 addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
2055 1, (void *)longitude);
2056 }
2057}
2058
2059void QualcommCameraHardware::setGpsParameters() {
2060 const char *str = NULL;
2061
2062 //Set Latitude
2063 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE);
2064 if(str != NULL) {
2065 setLatLon(EXIFTAGID_GPS_LATITUDE, str);
2066 //set Latitude Ref
2067 str = NULL;
2068 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE_REF);
2069 if(str != NULL) {
2070 strncpy(latref, str, 1);
2071 latref[1] = '\0';
2072 addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
2073 1, (void *)latref);
2074 }
2075 }
2076
2077 //set Longitude
2078 str = NULL;
2079 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE);
2080 if(str != NULL) {
2081 setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
2082 //set Longitude Ref
2083 str = NULL;
2084 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
2085 if(str != NULL) {
2086 strncpy(lonref, str, 1);
2087 lonref[1] = '\0';
2088 addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
2089 1, (void *)lonref);
2090 }
2091 }
2092
2093 //set Altitude
2094 str = NULL;
2095 str = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE);
2096 if(str != NULL) {
2097 int value = atoi(str);
2098 rat_t alt_value = {value, 1000};
2099 memcpy(&altitude, &alt_value, sizeof(altitude));
2100 addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
2101 1, (void *)&altitude);
2102 //set AltitudeRef
2103 int ref = mParameters.getInt(CameraParameters::KEY_GPS_ALTITUDE_REF);
2104 if( !(ref < 0 || ref > 1) )
2105 addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
2106 1, (void *)&ref);
2107 }
2108
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002109 //set Gps TimeStamp
2110 str = NULL;
2111 str = mParameters.get(CameraParameters::KEY_GPS_TIMESTAMP);
2112 if(str != NULL) {
2113
2114 long value = atol(str);
2115 time_t unixTime;
2116 struct tm *UTCTimestamp;
2117
2118 unixTime = (time_t)value;
2119 UTCTimestamp = gmtime(&unixTime);
2120
2121 rat_t time_value[3] = { {UTCTimestamp->tm_hour, 1},
2122 {UTCTimestamp->tm_min, 1},
2123 {UTCTimestamp->tm_sec, 1} };
2124
2125 memcpy(&gpsTimestamp, &time_value, sizeof(gpsTimestamp));
2126 addExifTag(EXIFTAGID_GPS_TIMESTAMP, EXIF_RATIONAL,
2127 3, 1, (void *)&gpsTimestamp);
2128 }
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002129
2130}
2131
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002132bool QualcommCameraHardware::native_jpeg_encode(void)
2133{
2134 int jpeg_quality = mParameters.getInt("jpeg-quality");
2135 if (jpeg_quality >= 0) {
2136 LOGV("native_jpeg_encode, current jpeg main img quality =%d",
2137 jpeg_quality);
2138 if(!LINK_jpeg_encoder_setMainImageQuality(jpeg_quality)) {
2139 LOGE("native_jpeg_encode set jpeg-quality failed");
2140 return false;
2141 }
2142 }
2143
2144 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
2145 if (thumbnail_quality >= 0) {
2146 LOGV("native_jpeg_encode, current jpeg thumbnail quality =%d",
2147 thumbnail_quality);
2148 if(!LINK_jpeg_encoder_setThumbnailQuality(thumbnail_quality)) {
2149 LOGE("native_jpeg_encode set thumbnail-quality failed");
2150 return false;
2151 }
2152 }
2153
Priyanka Kharat32409f72010-08-25 18:11:03 -07002154 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM7627) && (mCurrentTarget != TARGET_MSM8660) ) {
Mohan Kandra02486042010-06-18 16:49:43 -07002155 int rotation = mParameters.getInt("rotation");
2156 if (rotation >= 0) {
2157 LOGV("native_jpeg_encode, rotation = %d", rotation);
2158 if(!LINK_jpeg_encoder_setRotation(rotation)) {
2159 LOGE("native_jpeg_encode set rotation failed");
2160 return false;
2161 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002162 }
2163 }
2164
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002165 jpeg_set_location();
2166
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002167 //set TimeStamp
2168 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
2169 if(str != NULL) {
2170 strncpy(dateTime, str, 19);
2171 dateTime[19] = '\0';
2172 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
2173 20, 1, (void *)dateTime);
2174 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002175
2176 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
2177 // Pass the main image as thumbnail buffer, so that jpeg encoder will
2178 // generate thumbnail based on main image.
2179 // Set the input and output dimensions for thumbnail generation to main
2180 // image dimensions and required thumbanail size repectively, for the
2181 // encoder to do downscaling of the main image accordingly.
2182 mCrop.in1_w = mDimension.orig_picture_dx;
2183 mCrop.in1_h = mDimension.orig_picture_dy;
2184 mCrop.out1_w = mDimension.thumbnail_width;
2185 mCrop.out1_h = mDimension.thumbnail_height;
2186 mDimension.thumbnail_width = mDimension.orig_picture_dx;
2187 mDimension.thumbnail_height = mDimension.orig_picture_dy;
2188 if (!LINK_jpeg_encoder_encode(&mDimension,
2189 (uint8_t *)mRawHeap->mHeap->base(),
2190 mRawHeap->mHeap->getHeapID(),
2191 (uint8_t *)mRawHeap->mHeap->base(),
2192 mRawHeap->mHeap->getHeapID(),
2193 &mCrop, exif_data, exif_table_numEntries,
2194 jpegPadding/2, mCbCrOffsetRaw)) {
2195 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
2196 return false;
2197 }
2198 } else {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002199 if (!LINK_jpeg_encoder_encode(&mDimension,
2200 (uint8_t *)mThumbnailHeap->mHeap->base(),
2201 mThumbnailHeap->mHeap->getHeapID(),
2202 (uint8_t *)mRawHeap->mHeap->base(),
2203 mRawHeap->mHeap->getHeapID(),
Srinivasan Kannan5701a942010-04-15 16:17:21 -07002204 &mCrop, exif_data, exif_table_numEntries,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002205 jpegPadding/2, -1)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002206 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
2207 return false;
2208 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002209 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002210 return true;
2211}
2212
2213bool QualcommCameraHardware::native_set_parm(
2214 cam_ctrl_type type, uint16_t length, void *value)
2215{
2216 struct msm_ctrl_cmd ctrlCmd;
2217
2218 ctrlCmd.timeout_ms = 5000;
2219 ctrlCmd.type = (uint16_t)type;
2220 ctrlCmd.length = length;
2221 // FIXME: this will be put in by the kernel
2222 ctrlCmd.resp_fd = mCameraControlFd;
2223 ctrlCmd.value = value;
2224
2225 LOGV("%s: fd %d, type %d, length %d", __FUNCTION__,
2226 mCameraControlFd, type, length);
2227 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0 ||
2228 ctrlCmd.status != CAM_CTRL_SUCCESS) {
2229 LOGE("%s: error (%s): fd %d, type %d, length %d, status %d",
2230 __FUNCTION__, strerror(errno),
2231 mCameraControlFd, type, length, ctrlCmd.status);
2232 return false;
2233 }
2234 return true;
2235}
2236
2237void QualcommCameraHardware::jpeg_set_location()
2238{
2239 bool encode_location = true;
2240 camera_position_type pt;
2241
2242#define PARSE_LOCATION(what,type,fmt,desc) do { \
2243 pt.what = 0; \
2244 const char *what##_str = mParameters.get("gps-"#what); \
2245 LOGV("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
2246 if (what##_str) { \
2247 type what = 0; \
2248 if (sscanf(what##_str, fmt, &what) == 1) \
2249 pt.what = what; \
2250 else { \
2251 LOGE("GPS " #what " %s could not" \
2252 " be parsed as a " #desc, what##_str); \
2253 encode_location = false; \
2254 } \
2255 } \
2256 else { \
2257 LOGV("GPS " #what " not specified: " \
2258 "defaulting to zero in EXIF header."); \
2259 encode_location = false; \
2260 } \
2261 } while(0)
2262
2263 PARSE_LOCATION(timestamp, long, "%ld", "long");
2264 if (!pt.timestamp) pt.timestamp = time(NULL);
2265 PARSE_LOCATION(altitude, short, "%hd", "short");
2266 PARSE_LOCATION(latitude, double, "%lf", "double float");
2267 PARSE_LOCATION(longitude, double, "%lf", "double float");
2268
2269#undef PARSE_LOCATION
2270
2271 if (encode_location) {
2272 LOGD("setting image location ALT %d LAT %lf LON %lf",
2273 pt.altitude, pt.latitude, pt.longitude);
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002274
2275 setGpsParameters();
2276 /* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002277 if (!LINK_jpeg_encoder_setLocation(&pt)) {
2278 LOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
2279 }
Apurva Rajguru5ec76132010-06-16 17:43:46 -07002280 */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002281 }
2282 else LOGV("not setting image location");
2283}
2284
2285void QualcommCameraHardware::runFrameThread(void *data)
2286{
2287 LOGV("runFrameThread E");
2288
2289 int cnt;
2290
2291#if DLOPEN_LIBMMCAMERA
2292 // We need to maintain a reference to libqcamera.so for the duration of the
2293 // frame thread, because we do not know when it will exit relative to the
2294 // lifetime of this object. We do not want to dlclose() libqcamera while
2295 // LINK_cam_frame is still running.
2296 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
2297 LOGV("FRAME: loading libqcamera at %p", libhandle);
2298 if (!libhandle) {
2299 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
2300 }
2301 if (libhandle)
2302#endif
2303 {
2304 LINK_cam_frame(data);
2305 }
2306
Mohan Kandrad9efed92010-01-15 19:08:39 -08002307 mPreviewHeap.clear();
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302308 if(( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660))
Sravankb4f5f1c2010-01-21 11:06:17 +05302309 mRecordHeap.clear();
2310
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002311#if DLOPEN_LIBMMCAMERA
2312 if (libhandle) {
2313 ::dlclose(libhandle);
2314 LOGV("FRAME: dlclose(libqcamera)");
2315 }
2316#endif
2317
2318 mFrameThreadWaitLock.lock();
2319 mFrameThreadRunning = false;
2320 mFrameThreadWait.signal();
2321 mFrameThreadWaitLock.unlock();
2322
2323 LOGV("runFrameThread X");
2324}
2325
Sravankb4f5f1c2010-01-21 11:06:17 +05302326void QualcommCameraHardware::runVideoThread(void *data)
2327{
2328 LOGD("runVideoThread E");
2329 msm_frame* vframe = NULL;
2330
2331 while(true) {
2332 pthread_mutex_lock(&(g_busy_frame_queue.mut));
2333
Srinivasan Kannanfc3915c2010-03-18 10:54:40 -07002334 // Exit the thread , in case of stop recording..
2335 mVideoThreadWaitLock.lock();
2336 if(mVideoThreadExit){
2337 LOGV("Exiting video thread..");
2338 mVideoThreadWaitLock.unlock();
2339 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
2340 break;
2341 }
2342 mVideoThreadWaitLock.unlock();
2343
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002344 LOGV("in video_thread : wait for video frame ");
Sravankb4f5f1c2010-01-21 11:06:17 +05302345 // check if any frames are available in busyQ and give callback to
2346 // services/video encoder
2347 cam_frame_wait_video();
2348 LOGV("video_thread, wait over..");
2349
2350 // Exit the thread , in case of stop recording..
2351 mVideoThreadWaitLock.lock();
2352 if(mVideoThreadExit){
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08002353 LOGV("Exiting video thread..");
Sravankb4f5f1c2010-01-21 11:06:17 +05302354 mVideoThreadWaitLock.unlock();
2355 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
2356 break;
2357 }
2358 mVideoThreadWaitLock.unlock();
2359
2360 // Get the video frame to be encoded
2361 vframe = cam_frame_get_video ();
Apurva Rajgurud9b0b302010-02-19 11:22:56 -08002362 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Sravankb4f5f1c2010-01-21 11:06:17 +05302363 LOGV("in video_thread : got video frame ");
2364
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08002365 if (UNLIKELY(mDebugFps)) {
2366 debugShowVideoFPS();
2367 }
2368
Sravankb4f5f1c2010-01-21 11:06:17 +05302369 if(vframe != NULL) {
2370 // Find the offset within the heap of the current buffer.
2371 LOGV("Got video frame : buffer %d base %d ", vframe->buffer, mRecordHeap->mHeap->base());
2372 ssize_t offset =
2373 (ssize_t)vframe->buffer - (ssize_t)mRecordHeap->mHeap->base();
2374 LOGV("offset = %d , alignsize = %d , offset later = %d", offset, mRecordHeap->mAlignedBufferSize, (offset / mRecordHeap->mAlignedBufferSize));
2375
2376 offset /= mRecordHeap->mAlignedBufferSize;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07002377
2378 //set the track flag to true for this video buffer
2379 record_buffers_tracking_flag[offset] = true;
2380
Mohan Kandra1307f312010-04-29 10:18:42 -07002381 /* Extract the timestamp of this frame */
2382 nsecs_t timeStamp = nsecs_t(vframe->ts.tv_sec)*1000000000LL + vframe->ts.tv_nsec;
Sravankb4f5f1c2010-01-21 11:06:17 +05302383
2384 // dump frames for test purpose
2385#ifdef DUMP_VIDEO_FRAMES
2386 static int frameCnt = 0;
2387 if (frameCnt >= 11 && frameCnt <= 13 ) {
2388 char buf[128];
2389 sprintf(buf, "/data/%d_v.yuv", frameCnt);
2390 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
2391 LOGV("dumping video frame %d", frameCnt);
2392 if (file_fd < 0) {
2393 LOGE("cannot open file\n");
2394 }
2395 else
2396 {
2397 write(file_fd, (const void *)vframe->buffer,
2398 vframe->cbcr_off * 3 / 2);
2399 }
2400 close(file_fd);
2401 }
2402 frameCnt++;
2403#endif
2404 // Enable IF block to give frames to encoder , ELSE block for just simulation
2405#if 1
2406 LOGV("in video_thread : got video frame, before if check giving frame to services/encoder");
2407 mCallbackLock.lock();
2408 int msgEnabled = mMsgEnabled;
2409 data_callback_timestamp rcb = mDataCallbackTimestamp;
2410 void *rdata = mCallbackCookie;
2411 mCallbackLock.unlock();
2412
2413 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME) ) {
2414 LOGV("in video_thread : got video frame, giving frame to services/encoder");
Mohan Kandra1307f312010-04-29 10:18:42 -07002415 rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[offset], rdata);
Sravankb4f5f1c2010-01-21 11:06:17 +05302416 }
2417#else
2418 // 720p output2 : simulate release frame here:
2419 LOGE("in video_thread simulation , releasing the video frame");
2420 LINK_camframe_free_video(vframe);
2421#endif
2422
2423 } else LOGE("in video_thread get frame returned null");
2424
Sravankb4f5f1c2010-01-21 11:06:17 +05302425
2426 } // end of while loop
Mohan Kandra156d0ac2010-01-25 16:59:17 -08002427
2428 mVideoThreadWaitLock.lock();
2429 mVideoThreadRunning = false;
2430 mVideoThreadWait.signal();
2431 mVideoThreadWaitLock.unlock();
2432
Sravankb4f5f1c2010-01-21 11:06:17 +05302433 LOGV("runVideoThread X");
2434}
2435
2436void *video_thread(void *user)
2437{
2438 LOGV("video_thread E");
2439 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2440 if (obj != 0) {
2441 obj->runVideoThread(user);
2442 }
2443 else LOGE("not starting video thread: the object went away!");
2444 LOGV("video_thread X");
2445 return NULL;
2446}
2447
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002448void *frame_thread(void *user)
2449{
2450 LOGD("frame_thread E");
2451 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2452 if (obj != 0) {
2453 obj->runFrameThread(user);
2454 }
2455 else LOGW("not starting frame thread: the object went away!");
2456 LOGD("frame_thread X");
2457 return NULL;
2458}
2459
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002460static int parse_size(const char *str, int &width, int &height)
2461{
2462 // Find the width.
2463 char *end;
2464 int w = (int)strtol(str, &end, 10);
2465 // If an 'x' or 'X' does not immediately follow, give up.
2466 if ( (*end != 'x') && (*end != 'X') )
2467 return -1;
2468
2469 // Find the height, immediately after the 'x'.
2470 int h = (int)strtol(end+1, 0, 10);
2471
2472 width = w;
2473 height = h;
2474
2475 return 0;
2476}
2477
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002478bool QualcommCameraHardware::initPreview()
2479{
2480 // See comments in deinitPreview() for why we have to wait for the frame
2481 // thread here, and why we can't use pthread_join().
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302482 const char * pmem_region;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002483 mParameters.getPreviewSize(&previewWidth, &previewHeight);
Sravankb4f5f1c2010-01-21 11:06:17 +05302484
Mohan Kandra091d5ab2010-07-14 16:53:25 -07002485 //Get the Record sizes
2486 const char *recordSize = NULL;
2487 recordSize = mParameters.get("record-size");
2488 if(!recordSize) {
2489 //If application didn't set this parameter string, use the values from
2490 //getPreviewSize() as video dimensions.
2491 LOGI("No Record Size requested, use the preview dimensions");
2492 videoWidth = previewWidth;
2493 videoHeight = previewHeight;
2494 } else {
2495 //Extract the record witdh and height that application requested.
2496 if(!parse_size(recordSize, videoWidth, videoHeight)) {
2497 //VFE output1 shouldn't be greater than VFE output2.
2498 if( (previewWidth > videoWidth) || (previewHeight > videoHeight)) {
2499 //Set preview sizes as record sizes.
2500 LOGI("Preview size %dx%d is greater than record size %dx%d,\
2501 resetting preview size to record size",previewWidth,\
2502 previewHeight, videoWidth, videoHeight);
2503 previewWidth = videoWidth;
2504 previewHeight = videoHeight;
2505 mParameters.setPreviewSize(previewWidth, previewHeight);
2506 }
2507 if( (mCurrentTarget != TARGET_MSM7630)
2508 && (mCurrentTarget != TARGET_QSD8250)
2509 && (mCurrentTarget != TARGET_MSM8660) ) {
2510 //For Single VFE output targets, use record dimensions as preview dimensions.
2511 previewWidth = videoWidth;
2512 previewHeight = videoHeight;
2513 mParameters.setPreviewSize(previewWidth, previewHeight);
2514 }
2515 } else {
2516 LOGE("initPreview X: failed to parse parameter record-size (%s)", recordSize);
2517 return false;
2518 }
2519 }
2520
Mohan Kandra0d115d12010-08-19 11:47:15 -07002521 mDimension.display_width = previewWidth;
2522 mDimension.display_height= previewHeight;
2523
Sravankb4f5f1c2010-01-21 11:06:17 +05302524 LOGV("initPreview E: preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, videoWidth, videoHeight );
2525
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302526 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07002527 mDimension.video_width = CEILING16(videoWidth);
2528 /* Backup the video dimensions, as video dimensions in mDimension
2529 * will be modified when DIS is supported. Need the actual values
2530 * to pass ap part of VPE config
2531 */
2532 videoWidth = mDimension.video_width;
Sravankb4f5f1c2010-01-21 11:06:17 +05302533 mDimension.video_height = videoHeight;
2534 LOGV("initPreview : preview size=%dx%d videosize = %d x %d", previewWidth, previewHeight, mDimension.video_width, mDimension.video_height );
2535 }
2536
2537
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002538 mFrameThreadWaitLock.lock();
2539 while (mFrameThreadRunning) {
2540 LOGV("initPreview: waiting for old frame thread to complete.");
2541 mFrameThreadWait.wait(mFrameThreadWaitLock);
2542 LOGV("initPreview: old frame thread completed.");
2543 }
2544 mFrameThreadWaitLock.unlock();
2545
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002546 mInSnapshotModeWaitLock.lock();
2547 while (mInSnapshotMode) {
2548 LOGV("initPreview: waiting for snapshot mode to complete.");
2549 mInSnapshotModeWait.wait(mInSnapshotModeWaitLock);
2550 LOGV("initPreview: snapshot mode completed.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002551 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07002552 mInSnapshotModeWaitLock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002553
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302554 /*Temporary migrating the preview buffers to smi pool for 8x60 till the bug is resolved in the pmem_adsp pool*/
2555 if(mCurrentTarget == TARGET_MSM8660)
2556 pmem_region = "/dev/pmem_smipool";
2557 else
2558 pmem_region = "/dev/pmem_adsp";
2559
2560
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002561 int cnt = 0;
2562 mPreviewFrameSize = previewWidth * previewHeight * 3/2;
Mohan Kandra02486042010-06-18 16:49:43 -07002563 int CbCrOffset = PAD_TO_WORD(previewWidth * previewHeight);
Mohan Kandra7110c242010-07-18 15:34:48 -07002564
2565 //Pass the yuv formats, display dimensions,
2566 //so that vfe will be initialized accordingly.
2567 mDimension.display_luma_width = previewWidth;
2568 mDimension.display_luma_height = previewHeight;
2569 mDimension.display_chroma_width = previewWidth;
2570 mDimension.display_chroma_height = previewHeight;
2571 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
2572 mPreviewFrameSize = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight)) +
2573 2 * (CEILING32(previewWidth/2) * CEILING32(previewHeight/2));
2574 CbCrOffset = PAD_TO_4K(CEILING32(previewWidth) * CEILING32(previewHeight));
2575 mDimension.prev_format = CAMERA_YUV_420_NV21_ADRENO;
2576 mDimension.display_luma_width = CEILING32(previewWidth);
2577 mDimension.display_luma_height = CEILING32(previewHeight);
2578 mDimension.display_chroma_width = 2 * CEILING32(previewWidth/2);
2579 //Chroma Height is not needed as of now. Just sending with other dimensions.
2580 mDimension.display_chroma_height = CEILING32(previewHeight/2);
2581 }
2582 LOGV("mDimension.prev_format = %d", mDimension.prev_format);
2583 LOGV("mDimension.display_luma_width = %d", mDimension.display_luma_width);
2584 LOGV("mDimension.display_luma_height = %d", mDimension.display_luma_height);
2585 LOGV("mDimension.display_chroma_width = %d", mDimension.display_chroma_width);
2586 LOGV("mDimension.display_chroma_height = %d", mDimension.display_chroma_height);
2587
Mohan Kandrad9efed92010-01-15 19:08:39 -08002588 dstOffset = 0;
Nishant Pandit2cc7a4b2010-08-10 00:13:15 +05302589 mPreviewHeap = new PmemPool(pmem_region,
Mohan Kandra284966d2010-01-05 13:39:15 -08002590 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
2591 mCameraControlFd,
Sravankb4f5f1c2010-01-21 11:06:17 +05302592 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
Mohan Kandra284966d2010-01-05 13:39:15 -08002593 mPreviewFrameSize,
Mohan Kandrad9efed92010-01-15 19:08:39 -08002594 kPreviewBufferCountActual,
Mohan Kandra284966d2010-01-05 13:39:15 -08002595 mPreviewFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002596 CbCrOffset,
2597 0,
Mohan Kandrad9efed92010-01-15 19:08:39 -08002598 "preview");
Mohan Kandra284966d2010-01-05 13:39:15 -08002599
Mohan Kandrad9efed92010-01-15 19:08:39 -08002600 if (!mPreviewHeap->initialized()) {
2601 mPreviewHeap.clear();
Mohan Kandra284966d2010-01-05 13:39:15 -08002602 LOGE("initPreview X: could not initialize Camera preview heap.");
2603 return false;
2604 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07002605 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)
2606 || (mCurrentTarget == TARGET_MSM7627) ) {
Srinivasan Kannan613301c2010-02-10 17:08:53 -08002607 mPostViewHeap.clear();
Kiran Kumar H N595970b2010-01-12 10:41:09 -08002608 if(mPostViewHeap == NULL) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07002609 LOGV(" Allocating Postview heap ");
2610 /* mPostViewHeap should be declared only for 7630 target */
Kiran Kumar H N595970b2010-01-12 10:41:09 -08002611 mPostViewHeap =
2612 new PmemPool("/dev/pmem_adsp",
2613 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
2614 mCameraControlFd,
Sravankb4f5f1c2010-01-21 11:06:17 +05302615 MSM_PMEM_PREVIEW, //MSM_PMEM_OUTPUT2,
Kiran Kumar H N595970b2010-01-12 10:41:09 -08002616 mPreviewFrameSize,
2617 1,
2618 mPreviewFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002619 CbCrOffset,
2620 0,
Kiran Kumar H N595970b2010-01-12 10:41:09 -08002621 "postview");
Mohan Kandra284966d2010-01-05 13:39:15 -08002622
Kiran Kumar H N595970b2010-01-12 10:41:09 -08002623 if (!mPostViewHeap->initialized()) {
2624 mPostViewHeap.clear();
2625 LOGE(" Failed to initialize Postview Heap");
2626 return false;
2627 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08002628 }
Mohan Kandraf1ebf982010-02-02 15:25:43 -08002629 }
2630
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302631 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002632
2633 // Allocate video buffers after allocating preview buffers.
Sravankb4f5f1c2010-01-21 11:06:17 +05302634 initRecord();
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002635 }
Sravankb4f5f1c2010-01-21 11:06:17 +05302636
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002637 // mDimension will be filled with thumbnail_width, thumbnail_height,
2638 // orig_picture_dx, and orig_picture_dy after this function call. We need to
2639 // keep it for jpeg_encoder_encode.
2640 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
2641 sizeof(cam_ctrl_dimension_t), &mDimension);
2642
2643 if (ret) {
2644 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
Mohan Kandrad9efed92010-01-15 19:08:39 -08002645 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002646 frames[cnt].buffer =
Mohan Kandrad9efed92010-01-15 19:08:39 -08002647 (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002648 frames[cnt].y_off = 0;
Mohan Kandra02486042010-06-18 16:49:43 -07002649 frames[cnt].cbcr_off = CbCrOffset;
Sravankb4f5f1c2010-01-21 11:06:17 +05302650 frames[cnt].path = OUTPUT_TYPE_P; // MSM_FRAME_ENC;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002651 }
2652
2653 mFrameThreadWaitLock.lock();
2654 pthread_attr_t attr;
2655 pthread_attr_init(&attr);
2656 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Sravankb4f5f1c2010-01-21 11:06:17 +05302657
2658 frame_parms.frame = frames[kPreviewBufferCount - 1];
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002659
Nishant Pandit3c278cd2010-07-13 15:56:04 +05302660 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660)
Apurva Rajguruc73c1722010-04-15 17:39:11 -07002661 frame_parms.video_frame = recordframes[kPreviewBufferCount - 1];
2662 else
2663 frame_parms.video_frame = frames[kPreviewBufferCount - 1];
Sravankb4f5f1c2010-01-21 11:06:17 +05302664
2665 LOGV ("initpreview before cam_frame thread carete , video frame buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
2666 (unsigned long)frame_parms.video_frame.buffer, frame_parms.video_frame.fd, frame_parms.video_frame.y_off,
2667 frame_parms.video_frame.cbcr_off);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002668 mFrameThreadRunning = !pthread_create(&mFrameThread,
2669 &attr,
2670 frame_thread,
Sravankb4f5f1c2010-01-21 11:06:17 +05302671 (void*)&(frame_parms));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002672 ret = mFrameThreadRunning;
2673 mFrameThreadWaitLock.unlock();
2674 }
2675
2676 LOGV("initPreview X: %d", ret);
2677 return ret;
2678}
2679
2680void QualcommCameraHardware::deinitPreview(void)
2681{
2682 LOGI("deinitPreview E");
2683
2684 // When we call deinitPreview(), we signal to the frame thread that it
2685 // needs to exit, but we DO NOT WAIT for it to complete here. The problem
2686 // is that deinitPreview is sometimes called from the frame-thread's
2687 // callback, when the refcount on the Camera client reaches zero. If we
2688 // called pthread_join(), we would deadlock. So, we just call
2689 // LINK_camframe_terminate() in deinitPreview(), which makes sure that
2690 // after the preview callback returns, the camframe thread will exit. We
2691 // could call pthread_join() in initPreview() to join the last frame
2692 // thread. However, we would also have to call pthread_join() in release
2693 // as well, shortly before we destroy the object; this would cause the same
2694 // deadlock, since release(), like deinitPreview(), may also be called from
2695 // the frame-thread's callback. This we have to make the frame thread
2696 // detached, and use a separate mechanism to wait for it to complete.
2697
Kiran Kumar H N7ac84e32010-02-01 10:58:47 -08002698 LINK_camframe_terminate();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002699 LOGI("deinitPreview X");
2700}
2701
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002702bool QualcommCameraHardware::initRawSnapshot()
2703{
2704 LOGV("initRawSnapshot E");
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302705 const char * pmem_region;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002706
2707 //get width and height from Dimension Object
2708 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
2709 sizeof(cam_ctrl_dimension_t), &mDimension);
2710
2711 if(!ret){
2712 LOGE("initRawSnapshot X: failed to set dimension");
2713 return false;
2714 }
2715 int rawSnapshotSize = mDimension.raw_picture_height *
2716 mDimension.raw_picture_width;
2717
2718 LOGV("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
2719 "raw_picture_width = %d",
2720 rawSnapshotSize, mDimension.raw_picture_height,
2721 mDimension.raw_picture_width);
2722
2723 if (mRawSnapShotPmemHeap != NULL) {
2724 LOGV("initRawSnapshot: clearing old mRawSnapShotPmemHeap.");
2725 mRawSnapShotPmemHeap.clear();
2726 }
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302727 if(mCurrentTarget == TARGET_MSM8660)
2728 pmem_region = "/dev/pmem_smipool";
2729 else
2730 pmem_region = "/dev/pmem_adsp";
2731
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002732
2733 //Pmem based pool for Camera Driver
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302734 mRawSnapShotPmemHeap = new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002735 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002736 mCameraControlFd,
2737 MSM_PMEM_RAW_MAINIMG,
2738 rawSnapshotSize,
2739 1,
2740 rawSnapshotSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002741 0,
2742 0,
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002743 "raw pmem snapshot camera");
2744
2745 if (!mRawSnapShotPmemHeap->initialized()) {
2746 mRawSnapShotPmemHeap.clear();
2747 LOGE("initRawSnapshot X: error initializing mRawSnapshotHeap");
2748 return false;
2749 }
2750 LOGV("initRawSnapshot X");
2751 return true;
2752
2753}
2754
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002755bool QualcommCameraHardware::initRaw(bool initJpegHeap)
2756{
2757 int rawWidth, rawHeight;
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302758 const char * pmem_region;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08002759
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002760 mParameters.getPictureSize(&rawWidth, &rawHeight);
2761 LOGV("initRaw E: picture size=%dx%d", rawWidth, rawHeight);
2762
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002763 int thumbnailBufferSize;
2764 //Thumbnail height should be smaller than Picture height
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002765 if (rawHeight > (int)thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height){
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002766 mDimension.ui_thumbnail_width =
2767 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
2768 mDimension.ui_thumbnail_height =
2769 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
2770 uint32_t pictureAspectRatio = (uint32_t)((rawWidth * Q12) / rawHeight);
2771 uint32_t i;
2772 for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ )
2773 {
2774 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio)
2775 {
2776 mDimension.ui_thumbnail_width = thumbnail_sizes[i].width;
2777 mDimension.ui_thumbnail_height = thumbnail_sizes[i].height;
2778 break;
2779 }
2780 }
2781 }
2782 else{
2783 mDimension.ui_thumbnail_height = THUMBNAIL_SMALL_HEIGHT;
2784 mDimension.ui_thumbnail_width =
2785 (THUMBNAIL_SMALL_HEIGHT * rawWidth)/ rawHeight;
2786 }
2787
2788 LOGV("Thumbnail Size Width %d Height %d",
2789 mDimension.ui_thumbnail_width,
2790 mDimension.ui_thumbnail_height);
2791
2792 thumbnailBufferSize = mDimension.ui_thumbnail_width *
2793 mDimension.ui_thumbnail_height * 3 / 2;
Mohan Kandra02486042010-06-18 16:49:43 -07002794 int CbCrOffsetThumb = PAD_TO_WORD(mDimension.ui_thumbnail_width *
2795 mDimension.ui_thumbnail_height);
Mohan Kandra7110c242010-07-18 15:34:48 -07002796 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002797 mDimension.main_img_format = CAMERA_YUV_420_NV21_ADRENO;
2798 mDimension.thumb_format = CAMERA_YUV_420_NV21_ADRENO;
Mohan Kandra7110c242010-07-18 15:34:48 -07002799 thumbnailBufferSize = PAD_TO_4K(CEILING32(mDimension.ui_thumbnail_width) *
2800 CEILING32(mDimension.ui_thumbnail_height)) +
2801 2 * (CEILING32(mDimension.ui_thumbnail_width/2) *
2802 CEILING32(mDimension.ui_thumbnail_height/2));
2803 CbCrOffsetThumb = PAD_TO_4K(CEILING32(mDimension.ui_thumbnail_width) *
2804 CEILING32(mDimension.ui_thumbnail_height));
2805 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002806 // mDimension will be filled with thumbnail_width, thumbnail_height,
2807 // orig_picture_dx, and orig_picture_dy after this function call. We need to
2808 // keep it for jpeg_encoder_encode.
2809 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
2810 sizeof(cam_ctrl_dimension_t), &mDimension);
2811 if(!ret) {
2812 LOGE("initRaw X: failed to set dimension");
2813 return false;
2814 }
2815
2816 if (mJpegHeap != NULL) {
2817 LOGV("initRaw: clearing old mJpegHeap.");
2818 mJpegHeap.clear();
2819 }
2820
2821 // Snapshot
2822 mRawSize = rawWidth * rawHeight * 3 / 2;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002823 mCbCrOffsetRaw = PAD_TO_WORD(rawWidth * rawHeight);
Mohan Kandra7110c242010-07-18 15:34:48 -07002824 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
2825 mRawSize = PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight)) +
2826 2 * (CEILING32(rawWidth/2) * CEILING32(rawHeight/2));
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002827 mCbCrOffsetRaw = PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight));
Mohan Kandra7110c242010-07-18 15:34:48 -07002828 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002829 if( mCurrentTarget == TARGET_MSM7627 )
Mohan Kandra7110c242010-07-18 15:34:48 -07002830 mJpegMaxSize = CEILING16(rawWidth) * CEILING16(rawHeight) * 3 / 2;
2831 else {
2832 mJpegMaxSize = rawWidth * rawHeight * 3 / 2;
2833 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
2834 mJpegMaxSize =
2835 PAD_TO_4K(CEILING32(rawWidth) * CEILING32(rawHeight)) +
2836 2 * (CEILING32(rawWidth/2) * CEILING32(rawHeight/2));
2837 }
2838 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002839
Mohan Kandra02486042010-06-18 16:49:43 -07002840 //For offline jpeg hw encoder, jpeg encoder will provide us the
2841 //required offsets and buffer size depending on the rotation.
2842 int yOffset = 0;
Priyanka Kharat32409f72010-08-25 18:11:03 -07002843 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM7627) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra02486042010-06-18 16:49:43 -07002844 int rotation = mParameters.getInt("rotation");
2845 if (rotation >= 0) {
2846 LOGV("initRaw, jpeg_rotation = %d", rotation);
2847 if(!LINK_jpeg_encoder_setRotation(rotation)) {
2848 LOGE("native_jpeg_encode set rotation failed");
2849 return false;
2850 }
2851 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002852 //Don't call the get_buffer_offset() for ADRENO, as the width and height
2853 //for Adreno format will be of CEILING32.
2854 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
Mohan Kandra02486042010-06-18 16:49:43 -07002855 LINK_jpeg_encoder_get_buffer_offset(rawWidth, rawHeight, (uint32_t *)&yOffset,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002856 (uint32_t *)&mCbCrOffsetRaw, (uint32_t *)&mRawSize);
Mohan Kandra02486042010-06-18 16:49:43 -07002857 mJpegMaxSize = mRawSize;
2858 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002859 LOGV("initRaw: yOffset = %d, mCbCrOffsetRaw = %d, mRawSize = %d",
2860 yOffset, mCbCrOffsetRaw, mRawSize);
2861 }
Mohan Kandra02486042010-06-18 16:49:43 -07002862
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302863 if(mCurrentTarget == TARGET_MSM8660)
2864 pmem_region = "/dev/pmem_smipool";
2865 else
2866 pmem_region = "/dev/pmem_adsp";
2867
2868
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002869 LOGV("initRaw: initializing mRawHeap.");
2870 mRawHeap =
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302871 new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002872 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002873 mCameraControlFd,
2874 MSM_PMEM_MAINIMG,
2875 mJpegMaxSize,
2876 kRawBufferCount,
2877 mRawSize,
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002878 mCbCrOffsetRaw,
Mohan Kandra02486042010-06-18 16:49:43 -07002879 yOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002880 "snapshot camera");
2881
2882 if (!mRawHeap->initialized()) {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08002883 LOGE("initRaw X failed ");
2884 mRawHeap.clear();
2885 LOGE("initRaw X: error initializing mRawHeap");
2886 return false;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002887 }
2888
Mohan Kandra1659b0c2010-07-18 16:36:25 -07002889 //This is kind of workaround for the GPU limitation, as it can't
2890 //output in line to correct NV21 adreno formula for some snapshot
2891 //sizes (like 3264x2448). This change of cbcr offset will ensure that
2892 //chroma plane always starts at the beginning of a row.
2893 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO)
2894 mCbCrOffsetRaw = CEILING32(rawWidth) * CEILING32(rawHeight);
2895
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002896 LOGV("do_mmap snapshot pbuf = %p, pmem_fd = %d",
2897 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mHeap->getHeapID());
2898
2899 // Jpeg
2900
2901 if (initJpegHeap) {
2902 LOGV("initRaw: initializing mJpegHeap.");
2903 mJpegHeap =
2904 new AshmemPool(mJpegMaxSize,
2905 kJpegBufferCount,
2906 0, // we do not know how big the picture will be
2907 "jpeg");
2908
2909 if (!mJpegHeap->initialized()) {
2910 mJpegHeap.clear();
2911 mRawHeap.clear();
2912 LOGE("initRaw X failed: error initializing mJpegHeap.");
2913 return false;
2914 }
2915
2916 // Thumbnails
2917
2918 mThumbnailHeap =
Nishant Pandit62fe9aa2010-07-27 04:23:17 +05302919 new PmemPool(pmem_region,
Dinesh Gargeecf1a62010-04-19 16:31:30 -07002920 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002921 mCameraControlFd,
2922 MSM_PMEM_THUMBNAIL,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002923 thumbnailBufferSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002924 1,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08002925 thumbnailBufferSize,
Mohan Kandra02486042010-06-18 16:49:43 -07002926 CbCrOffsetThumb,
2927 0,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002928 "thumbnail");
2929
2930 if (!mThumbnailHeap->initialized()) {
2931 mThumbnailHeap.clear();
2932 mJpegHeap.clear();
2933 mRawHeap.clear();
2934 LOGE("initRaw X failed: error initializing mThumbnailHeap.");
2935 return false;
2936 }
2937 }
2938
2939 LOGV("initRaw X");
2940 return true;
2941}
2942
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002943
2944void QualcommCameraHardware::deinitRawSnapshot()
2945{
2946 LOGV("deinitRawSnapshot E");
2947 mRawSnapShotPmemHeap.clear();
2948 mRawSnapshotAshmemHeap.clear();
2949 LOGV("deinitRawSnapshot X");
2950}
2951
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002952void QualcommCameraHardware::deinitRaw()
2953{
2954 LOGV("deinitRaw E");
2955
2956 mThumbnailHeap.clear();
2957 mJpegHeap.clear();
2958 mRawHeap.clear();
2959 mDisplayHeap.clear();
2960
2961 LOGV("deinitRaw X");
2962}
2963
2964void QualcommCameraHardware::release()
2965{
Mohan Kandra0d115d12010-08-19 11:47:15 -07002966 LOGI("release E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002967 Mutex::Autolock l(&mLock);
2968
2969#if DLOPEN_LIBMMCAMERA
2970 if (libmmcamera == NULL) {
2971 LOGE("ERROR: multiple release!");
2972 return;
2973 }
2974#else
2975#warning "Cannot detect multiple release when not dlopen()ing libqcamera!"
2976#endif
2977
2978 int cnt, rc;
2979 struct msm_ctrl_cmd ctrlCmd;
Mohan Kandra0d115d12010-08-19 11:47:15 -07002980 LOGI("release: mCameraRunning = %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002981 if (mCameraRunning) {
2982 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
2983 mRecordFrameLock.lock();
2984 mReleasedRecordingFrame = true;
2985 mRecordWait.signal();
2986 mRecordFrameLock.unlock();
2987 }
2988 stopPreviewInternal();
Mohan Kandra0d115d12010-08-19 11:47:15 -07002989 LOGI("release: stopPreviewInternal done.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002990 }
2991
Apurva Rajguru905b8532010-08-02 18:29:38 -07002992 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)
2993 || (mCurrentTarget == TARGET_MSM7627) ) {
2994 mPostViewHeap.clear();
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08002995 mPostViewHeap = NULL;
2996 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002997 LINK_jpeg_encoder_join();
Srinivasan Kannan426cde72010-06-04 09:37:21 -07002998 {
2999 Mutex::Autolock l (&mRawPictureHeapLock);
3000 deinitRaw();
3001 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003002 //Signal the snapshot thread
3003 mJpegThreadWaitLock.lock();
3004 mJpegThreadRunning = false;
3005 mJpegThreadWait.signal();
3006 mJpegThreadWaitLock.unlock();
3007
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003008 deinitRawSnapshot();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003009 LOGI("release: clearing resources done.");
Srinivasan Kannan426cde72010-06-04 09:37:21 -07003010
Priyanka Kharat85cebed2010-05-12 14:57:57 -07003011
3012 ctrlCmd.timeout_ms = 5000;
3013 ctrlCmd.length = 0;
3014 ctrlCmd.type = (uint16_t)CAMERA_EXIT;
3015 ctrlCmd.resp_fd = mCameraControlFd; // FIXME: this will be put in by the kernel
3016 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0)
3017 LOGE("ioctl CAMERA_EXIT fd %d error %s",
3018 mCameraControlFd, strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003019
Mohan Kandra0d115d12010-08-19 11:47:15 -07003020 LOGI("release: CAMERA_EXIT done.");
Kiran Kumar H N7ac84e32010-02-01 10:58:47 -08003021 LINK_release_cam_conf_thread();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003022 close(mCameraControlFd);
3023 mCameraControlFd = -1;
Mohan Kandra284966d2010-01-05 13:39:15 -08003024 if(fb_fd >= 0) {
3025 close(fb_fd);
3026 fb_fd = -1;
3027 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003028#if DLOPEN_LIBMMCAMERA
3029 if (libmmcamera) {
3030 ::dlclose(libmmcamera);
3031 LOGV("dlclose(libqcamera)");
3032 libmmcamera = NULL;
3033 }
3034#endif
3035
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003036 singleton_lock.lock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003037 singleton_releasing = true;
Srinivasan Kannan78444e42010-06-10 15:39:29 -07003038 singleton_releasing_start_time = systemTime();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003039 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003040
Mohan Kandra0d115d12010-08-19 11:47:15 -07003041 LOGI("release X: mCameraRunning = %d, mFrameThreadRunning = %d", mCameraRunning, mFrameThreadRunning);
3042 LOGI("mVideoThreadRunning = %d, mSnapshotThreadRunning = %d, mJpegThreadRunning = %d", mVideoThreadRunning, mSnapshotThreadRunning, mJpegThreadRunning);
3043 LOGI("camframe_timeout_flag = %d, mAutoFocusThreadRunning = %d", camframe_timeout_flag, mAutoFocusThreadRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003044}
3045
3046QualcommCameraHardware::~QualcommCameraHardware()
3047{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003048 LOGI("~QualcommCameraHardware E");
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003049 singleton_lock.lock();
Apurva Rajguruc73c1722010-04-15 17:39:11 -07003050
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303051 if( mCurrentTarget == TARGET_MSM7630 || mCurrentTarget == TARGET_QSD8250 || mCurrentTarget == TARGET_MSM8660 ) {
Apurva Rajguruc73c1722010-04-15 17:39:11 -07003052 delete [] recordframes;
3053 recordframes = NULL;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07003054 delete [] record_buffers_tracking_flag;
3055 record_buffers_tracking_flag = NULL;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07003056 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003057 singleton.clear();
3058 singleton_releasing = false;
Srinivasan Kannan78444e42010-06-10 15:39:29 -07003059 singleton_releasing_start_time = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003060 singleton_wait.signal();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003061 singleton_lock.unlock();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003062 LOGI("~QualcommCameraHardware X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003063}
3064
3065sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
3066{
3067 LOGV("getRawHeap");
3068 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
3069}
3070
3071sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
3072{
3073 LOGV("getPreviewHeap");
Mohan Kandrad9efed92010-01-15 19:08:39 -08003074 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003075}
3076
3077status_t QualcommCameraHardware::startPreviewInternal()
3078{
Sravankb4f5f1c2010-01-21 11:06:17 +05303079 LOGV("in startPreviewInternal : E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003080 if(mCameraRunning) {
3081 LOGV("startPreview X: preview already running.");
3082 return NO_ERROR;
3083 }
3084
3085 if (!mPreviewInitialized) {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08003086 mLastQueuedFrame = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003087 mPreviewInitialized = initPreview();
3088 if (!mPreviewInitialized) {
3089 LOGE("startPreview X initPreview failed. Not starting preview.");
3090 return UNKNOWN_ERROR;
3091 }
3092 }
3093
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003094 {
3095 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3096 if(( mCurrentTarget != TARGET_MSM7630 ) &&
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303097 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003098 mCameraRunning = native_start_preview(mCameraControlFd);
3099 else
3100 mCameraRunning = native_start_video(mCameraControlFd);
3101 }
Sravankb4f5f1c2010-01-21 11:06:17 +05303102
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003103 if(!mCameraRunning) {
3104 deinitPreview();
3105 mPreviewInitialized = false;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08003106 mOverlay = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003107 LOGE("startPreview X: native_start_preview failed!");
3108 return UNKNOWN_ERROR;
3109 }
3110
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08003111 //Reset the Gps Information
3112 exif_table_numEntries = 0;
Mohan Kandra284966d2010-01-05 13:39:15 -08003113
Sravankb4f5f1c2010-01-21 11:06:17 +05303114 LOGV("startPreviewInternal X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003115 return NO_ERROR;
3116}
3117
3118status_t QualcommCameraHardware::startPreview()
3119{
3120 LOGV("startPreview E");
3121 Mutex::Autolock l(&mLock);
3122 return startPreviewInternal();
3123}
3124
3125void QualcommCameraHardware::stopPreviewInternal()
3126{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003127 LOGI("stopPreviewInternal E: %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003128 if (mCameraRunning) {
3129 // Cancel auto focus.
3130 {
3131 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
3132 cancelAutoFocusInternal();
3133 }
3134 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003135
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003136 Mutex::Autolock l(&mCamframeTimeoutLock);
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003137 {
3138 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3139 if(!camframe_timeout_flag) {
3140 if (( mCurrentTarget != TARGET_MSM7630 ) &&
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303141 (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660))
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003142 mCameraRunning = !native_stop_preview(mCameraControlFd);
3143 else
3144 mCameraRunning = !native_stop_video(mCameraControlFd);
3145 } else {
3146 /* This means that the camframetimeout was issued.
3147 * But we did not issue native_stop_preview(), so we
3148 * need to update mCameraRunning to indicate that
3149 * Camera is no longer running. */
3150 mCameraRunning = 0;
3151 }
3152 }
Sravankb4f5f1c2010-01-21 11:06:17 +05303153
Kiran Kumar H Nac2f4952009-12-17 01:16:53 -08003154 if (!mCameraRunning && mPreviewInitialized) {
3155 deinitPreview();
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303156 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Mohan Kandra156d0ac2010-01-25 16:59:17 -08003157 mVideoThreadWaitLock.lock();
3158 LOGV("in stopPreviewInternal: making mVideoThreadExit 1");
3159 mVideoThreadExit = 1;
3160 mVideoThreadWaitLock.unlock();
3161 // 720p : signal the video thread , and check in video thread if stop is called, if so exit video thread.
3162 pthread_mutex_lock(&(g_busy_frame_queue.mut));
3163 pthread_cond_signal(&(g_busy_frame_queue.wait));
3164 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Mohan Kandra1ade9a82010-03-02 10:11:26 -08003165 /* Flush the Busy Q */
3166 cam_frame_flush_video();
3167 /* Flush the Free Q */
3168 LINK_cam_frame_flush_free_video();
Mohan Kandra156d0ac2010-01-25 16:59:17 -08003169 }
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003170 mPreviewInitialized = false;
3171 }
Kiran Kumar H Nac2f4952009-12-17 01:16:53 -08003172 else LOGE("stopPreviewInternal: failed to stop preview");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003173 }
Mohan Kandra0d115d12010-08-19 11:47:15 -07003174 LOGI("stopPreviewInternal X: %d", mCameraRunning);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003175}
3176
3177void QualcommCameraHardware::stopPreview()
3178{
3179 LOGV("stopPreview: E");
3180 Mutex::Autolock l(&mLock);
3181 {
3182 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
3183 return;
3184 }
3185 stopPreviewInternal();
3186 LOGV("stopPreview: X");
3187}
3188
3189void QualcommCameraHardware::runAutoFocus()
3190{
3191 bool status = true;
3192 void *libhandle = NULL;
Srinivasan Kannan71229622009-12-04 12:05:58 -08003193 isp3a_af_mode_t afMode;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003194
3195 mAutoFocusThreadLock.lock();
3196 // Skip autofocus if focus mode is infinity.
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003197 if ((mParameters.get(CameraParameters::KEY_FOCUS_MODE) == 0)
3198 || (strcmp(mParameters.get(CameraParameters::KEY_FOCUS_MODE),
3199 CameraParameters::FOCUS_MODE_INFINITY) == 0)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003200 goto done;
3201 }
3202
3203 mAutoFocusFd = open(MSM_CAMERA_CONTROL, O_RDWR);
3204 if (mAutoFocusFd < 0) {
3205 LOGE("autofocus: cannot open %s: %s",
3206 MSM_CAMERA_CONTROL,
3207 strerror(errno));
3208 mAutoFocusThreadRunning = false;
3209 mAutoFocusThreadLock.unlock();
3210 return;
3211 }
3212
3213#if DLOPEN_LIBMMCAMERA
3214 // We need to maintain a reference to libqcamera.so for the duration of the
3215 // AF thread, because we do not know when it will exit relative to the
3216 // lifetime of this object. We do not want to dlclose() libqcamera while
3217 // LINK_cam_frame is still running.
3218 libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
3219 LOGV("AF: loading libqcamera at %p", libhandle);
3220 if (!libhandle) {
3221 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
3222 close(mAutoFocusFd);
3223 mAutoFocusFd = -1;
3224 mAutoFocusThreadRunning = false;
3225 mAutoFocusThreadLock.unlock();
3226 return;
3227 }
3228#endif
3229
Srinivasan Kannan71229622009-12-04 12:05:58 -08003230 afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
3231 sizeof(focus_modes) / sizeof(str_map),
3232 mParameters.get(CameraParameters::KEY_FOCUS_MODE));
3233
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003234 /* This will block until either AF completes or is cancelled. */
Srinivasan Kannan71229622009-12-04 12:05:58 -08003235 LOGV("af start (fd %d mode %d)", mAutoFocusFd, afMode);
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003236 status_t err;
3237 err = mAfLock.tryLock();
3238 if(err == NO_ERROR) {
Srinivasan Kannan74712c92010-04-07 13:36:48 -07003239 {
3240 Mutex::Autolock cameraRunningLock(&mCameraRunningLock);
3241 if(mCameraRunning){
3242 LOGV("Start AF");
3243 status = native_set_afmode(mAutoFocusFd, afMode);
3244 }else{
3245 LOGV("As Camera preview is not running, AF not issued");
3246 status = false;
3247 }
3248 }
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003249 mAfLock.unlock();
3250 }
3251 else{
3252 //AF Cancel would have acquired the lock,
3253 //so, no need to perform any AF
Srinivasan Kannan99e82422010-02-28 15:32:16 -08003254 LOGV("As Cancel auto focus is in progress, auto focus request "
3255 "is ignored");
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003256 status = FALSE;
3257 }
3258
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003259 LOGV("af done: %d", (int)status);
3260 close(mAutoFocusFd);
3261 mAutoFocusFd = -1;
3262
3263done:
3264 mAutoFocusThreadRunning = false;
3265 mAutoFocusThreadLock.unlock();
3266
3267 mCallbackLock.lock();
3268 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
3269 notify_callback cb = mNotifyCallback;
3270 void *data = mCallbackCookie;
3271 mCallbackLock.unlock();
3272 if (autoFocusEnabled)
3273 cb(CAMERA_MSG_FOCUS, status, 0, data);
3274
3275#if DLOPEN_LIBMMCAMERA
3276 if (libhandle) {
3277 ::dlclose(libhandle);
3278 LOGV("AF: dlclose(libqcamera)");
3279 }
3280#endif
3281}
3282
3283status_t QualcommCameraHardware::cancelAutoFocusInternal()
3284{
3285 LOGV("cancelAutoFocusInternal E");
3286
Srinivasan Kannan71229622009-12-04 12:05:58 -08003287 if(!sensorType->hasAutoFocusSupport){
3288 LOGV("cancelAutoFocusInternal X");
3289 return NO_ERROR;
3290 }
3291
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003292#if 0
3293 if (mAutoFocusFd < 0) {
3294 LOGV("cancelAutoFocusInternal X: not in progress");
3295 return NO_ERROR;
3296 }
3297#endif
3298
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003299 status_t rc = NO_ERROR;
3300 status_t err;
3301 err = mAfLock.tryLock();
3302 if(err == NO_ERROR) {
3303 //Got Lock, means either AF hasn't started or
3304 // AF is done. So no need to cancel it, just change the state
Srinivasan Kannan99e82422010-02-28 15:32:16 -08003305 LOGV("As Auto Focus is not in progress, Cancel Auto Focus "
3306 "is ignored");
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003307 mAfLock.unlock();
3308 }
3309 else {
3310 //AF is in Progess, So cancel it
3311 LOGV("Lock busy...cancel AF");
3312 rc = native_cancel_afmode(mCameraControlFd, mAutoFocusFd) ?
3313 NO_ERROR :
3314 UNKNOWN_ERROR;
3315 }
3316
3317
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003318
3319 LOGV("cancelAutoFocusInternal X: %d", rc);
3320 return rc;
3321}
3322
3323void *auto_focus_thread(void *user)
3324{
3325 LOGV("auto_focus_thread E");
3326 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3327 if (obj != 0) {
3328 obj->runAutoFocus();
3329 }
3330 else LOGW("not starting autofocus: the object went away!");
3331 LOGV("auto_focus_thread X");
3332 return NULL;
3333}
3334
3335status_t QualcommCameraHardware::autoFocus()
3336{
3337 LOGV("autoFocus E");
3338 Mutex::Autolock l(&mLock);
3339
Srinivasan Kannan71229622009-12-04 12:05:58 -08003340 if(!sensorType->hasAutoFocusSupport){
Srinivasan Kannandf085222009-12-09 18:31:00 -08003341 bool status = false;
3342 mCallbackLock.lock();
3343 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
3344 notify_callback cb = mNotifyCallback;
3345 void *data = mCallbackCookie;
3346 mCallbackLock.unlock();
3347 if (autoFocusEnabled)
3348 cb(CAMERA_MSG_FOCUS, status, 0, data);
Srinivasan Kannan71229622009-12-04 12:05:58 -08003349 LOGV("autoFocus X");
3350 return NO_ERROR;
3351 }
3352
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003353 if (mCameraControlFd < 0) {
3354 LOGE("not starting autofocus: main control fd %d", mCameraControlFd);
3355 return UNKNOWN_ERROR;
3356 }
3357
3358 {
3359 mAutoFocusThreadLock.lock();
3360 if (!mAutoFocusThreadRunning) {
Srinivasan Kannan572e25c2010-02-01 16:04:37 -08003361 if (native_prepare_snapshot(mCameraControlFd) == FALSE) {
3362 LOGE("native_prepare_snapshot failed!\n");
3363 mAutoFocusThreadLock.unlock();
3364 return UNKNOWN_ERROR;
3365 }
3366
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003367 // Create a detached thread here so that we don't have to wait
3368 // for it when we cancel AF.
3369 pthread_t thr;
3370 pthread_attr_t attr;
3371 pthread_attr_init(&attr);
3372 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3373 mAutoFocusThreadRunning =
3374 !pthread_create(&thr, &attr,
3375 auto_focus_thread, NULL);
3376 if (!mAutoFocusThreadRunning) {
3377 LOGE("failed to start autofocus thread");
3378 mAutoFocusThreadLock.unlock();
3379 return UNKNOWN_ERROR;
3380 }
3381 }
3382 mAutoFocusThreadLock.unlock();
3383 }
3384
3385 LOGV("autoFocus X");
3386 return NO_ERROR;
3387}
3388
3389status_t QualcommCameraHardware::cancelAutoFocus()
3390{
3391 LOGV("cancelAutoFocus E");
3392 Mutex::Autolock l(&mLock);
3393
3394 int rc = NO_ERROR;
3395 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
3396 rc = cancelAutoFocusInternal();
3397 }
3398
3399 LOGV("cancelAutoFocus X");
3400 return rc;
3401}
3402
3403void QualcommCameraHardware::runSnapshotThread(void *data)
3404{
3405 LOGV("runSnapshotThread E");
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003406#if DLOPEN_LIBMMCAMERA
3407 // We need to maintain a reference to libqcamera.so for the duration of the
3408 // Snapshot thread, because we do not know when it will exit relative to the
3409 // lifetime of this object. We do not want to dlclose() libqcamera while
3410 // LINK_cam_frame is still running.
3411 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
3412 LOGV("SNAPSHOT: loading libqcamera at %p", libhandle);
3413 if (!libhandle) {
3414 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
3415 }
3416#endif
3417
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003418 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3419 if (native_start_snapshot(mCameraControlFd))
3420 receiveRawPicture();
3421 else
3422 LOGE("main: native_start_snapshot failed!");
3423 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
3424 if(native_start_raw_snapshot(mCameraControlFd)){
3425 receiveRawSnapshot();
3426 } else {
3427 LOGE("main: native_start_raw_snapshot failed!");
3428 }
3429 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003430 mInSnapshotModeWaitLock.lock();
3431 mInSnapshotMode = false;
3432 mInSnapshotModeWait.signal();
3433 mInSnapshotModeWaitLock.unlock();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003434
3435 mSnapshotFormat = 0;
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003436 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO ) {
3437 mJpegThreadWaitLock.lock();
3438 while (mJpegThreadRunning) {
3439 LOGV("runSnapshotThread: waiting for jpeg thread to complete.");
3440 mJpegThreadWait.wait(mJpegThreadWaitLock);
3441 LOGV("runSnapshotThread: jpeg thread completed.");
3442 }
3443 mJpegThreadWaitLock.unlock();
3444 //clear the resources
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003445#if DLOPEN_LIBMMCAMERA
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003446 if(libhandle)
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003447#endif
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003448 {
3449 LINK_jpeg_encoder_join();
3450 }
3451 deinitRaw();
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003452 }
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003453
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003454 mSnapshotThreadWaitLock.lock();
3455 mSnapshotThreadRunning = false;
3456 mSnapshotThreadWait.signal();
3457 mSnapshotThreadWaitLock.unlock();
Deepak Kurien74b2cca2010-07-28 16:32:55 -07003458#if DLOPEN_LIBMMCAMERA
3459 if (libhandle) {
3460 ::dlclose(libhandle);
3461 LOGV("SNAPSHOT: dlclose(libqcamera)");
3462 }
3463#endif
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003464
3465 LOGV("runSnapshotThread X");
3466}
3467
3468void *snapshot_thread(void *user)
3469{
3470 LOGD("snapshot_thread E");
3471 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3472 if (obj != 0) {
3473 obj->runSnapshotThread(user);
3474 }
3475 else LOGW("not starting snapshot thread: the object went away!");
3476 LOGD("snapshot_thread X");
3477 return NULL;
3478}
3479
3480status_t QualcommCameraHardware::takePicture()
3481{
3482 LOGV("takePicture(%d)", mMsgEnabled);
3483 Mutex::Autolock l(&mLock);
3484
Mohan Kandra1659b0c2010-07-18 16:36:25 -07003485 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO){
3486 mEncodePendingWaitLock.lock();
3487 while(mEncodePending) {
3488 LOGE("takePicture: Frame given to application, waiting for encode call");
3489 mEncodePendingWait.wait(mEncodePendingWaitLock);
3490 LOGE("takePicture: Encode of the application data is done");
3491 }
3492 mEncodePendingWaitLock.unlock();
3493 }
3494
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003495 // Wait for old snapshot thread to complete.
3496 mSnapshotThreadWaitLock.lock();
3497 while (mSnapshotThreadRunning) {
3498 LOGV("takePicture: waiting for old snapshot thread to complete.");
3499 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
3500 LOGV("takePicture: old snapshot thread completed.");
3501 }
3502
Apurva Rajguru905b8532010-08-02 18:29:38 -07003503 if( (mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)
3504 || (mCurrentTarget == TARGET_MSM7627) ) {
3505 /* Store the last frame queued for preview. This
3506 * shall be used as postview */
3507 storePreviewFrameForPostview();
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003508 }
3509
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003510 //mSnapshotFormat is protected by mSnapshotThreadWaitLock
3511 if(mParameters.getPictureFormat() != 0 &&
3512 !strcmp(mParameters.getPictureFormat(),
3513 CameraParameters::PIXEL_FORMAT_RAW))
3514 mSnapshotFormat = PICTURE_FORMAT_RAW;
3515 else
3516 mSnapshotFormat = PICTURE_FORMAT_JPEG;
3517
3518 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3519 if(!native_prepare_snapshot(mCameraControlFd)) {
3520 mSnapshotThreadWaitLock.unlock();
3521 return UNKNOWN_ERROR;
3522 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003523 }
3524
3525 stopPreviewInternal();
3526
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003527 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
3528 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
3529 LOGE("initRaw failed. Not taking picture.");
3530 mSnapshotThreadWaitLock.unlock();
3531 return UNKNOWN_ERROR;
3532 }
3533 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
3534 if(!initRawSnapshot()){
3535 LOGE("initRawSnapshot failed. Not taking picture.");
3536 mSnapshotThreadWaitLock.unlock();
3537 return UNKNOWN_ERROR;
3538 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003539 }
3540
3541 mShutterLock.lock();
3542 mShutterPending = true;
3543 mShutterLock.unlock();
3544
3545 pthread_attr_t attr;
3546 pthread_attr_init(&attr);
3547 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3548 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
3549 &attr,
3550 snapshot_thread,
3551 NULL);
3552 mSnapshotThreadWaitLock.unlock();
3553
Mohan Kandraca2e7a92010-06-21 15:48:45 -07003554 mInSnapshotModeWaitLock.lock();
3555 mInSnapshotMode = true;
3556 mInSnapshotModeWaitLock.unlock();
3557
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003558 LOGV("takePicture: X");
3559 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
3560}
3561
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05303562void QualcommCameraHardware::set_liveshot_exifinfo()
3563{
3564 setGpsParameters();
3565 //set TimeStamp
3566 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
3567 if(str != NULL) {
3568 strncpy(dateTime, str, 19);
3569 dateTime[19] = '\0';
3570 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
3571 20, 1, (void *)dateTime);
3572 }
3573}
3574
3575status_t QualcommCameraHardware::takeLiveSnapshot()
3576{
3577 LOGV("takeLiveSnapshot: E ");
3578 Mutex::Autolock l(&mLock);
3579
3580 if(liveshot_state == LIVESHOT_IN_PROGRESS || !recordingState) {
3581 return NO_ERROR;
3582 }
3583
3584 if( (mCurrentTarget != TARGET_MSM7630) && (mCurrentTarget != TARGET_MSM8660)) {
3585 LOGI("LiveSnapshot not supported on this target");
3586 liveshot_state = LIVESHOT_STOPPED;
3587 return NO_ERROR;
3588 }
3589
3590 liveshot_state = LIVESHOT_IN_PROGRESS;
3591
3592 if (!initLiveSnapshot(videoWidth, videoHeight)) {
3593 LOGE("takeLiveSnapshot: Jpeg Heap Memory allocation failed. Not taking Live Snapshot.");
3594 liveshot_state = LIVESHOT_STOPPED;
3595 return UNKNOWN_ERROR;
3596 }
3597
3598 uint32_t maxjpegsize = videoWidth * videoHeight *1.5;
3599 set_liveshot_exifinfo();
3600 if(!LINK_set_liveshot_params(videoWidth, videoHeight,
3601 exif_data, exif_table_numEntries,
3602 (uint8_t *)mJpegHeap->mHeap->base(), maxjpegsize)) {
3603 LOGE("Link_set_liveshot_params failed.");
3604 mJpegHeap.clear();
3605 return NO_ERROR;
3606 }
3607
3608 if(!native_start_liveshot(mCameraControlFd)) {
3609 LOGE("native_start_liveshot failed");
3610 liveshot_state = LIVESHOT_STOPPED;
3611 mJpegHeap.clear();
3612 return UNKNOWN_ERROR;
3613 }
3614
3615 LOGV("takeLiveSnapshot: X");
3616 return NO_ERROR;
3617}
3618
3619bool QualcommCameraHardware::initLiveSnapshot(int videowidth, int videoheight)
3620{
3621 LOGV("initLiveSnapshot E");
3622
3623 if (mJpegHeap != NULL) {
3624 LOGV("initLiveSnapshot: clearing old mJpegHeap.");
3625 mJpegHeap.clear();
3626 }
3627
3628 mJpegMaxSize = videowidth * videoheight * 1.5;
3629
3630 LOGV("initLiveSnapshot: initializing mJpegHeap.");
3631 mJpegHeap =
3632 new AshmemPool(mJpegMaxSize,
3633 kJpegBufferCount,
3634 0, // we do not know how big the picture will be
3635 "jpeg");
3636
3637 if (!mJpegHeap->initialized()) {
3638 mJpegHeap.clear();
3639 LOGE("initLiveSnapshot X failed: error initializing mJpegHeap.");
3640 return false;
3641 }
3642
3643 LOGV("initLiveSnapshot X");
3644 return true;
3645}
3646
3647
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003648status_t QualcommCameraHardware::cancelPicture()
3649{
3650 status_t rc;
3651 LOGV("cancelPicture: E");
Apurva Rajguru3da1a702010-07-28 12:32:42 -07003652 if (mCurrentTarget == TARGET_MSM7627) {
3653 mSnapshotDone = TRUE;
3654 mSnapshotThreadWaitLock.lock();
3655 while (mSnapshotThreadRunning) {
3656 LOGV("cancelPicture: waiting for snapshot thread to complete.");
3657 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
3658 LOGV("cancelPicture: snapshot thread completed.");
3659 }
3660 mSnapshotThreadWaitLock.unlock();
3661 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003662 rc = native_stop_snapshot(mCameraControlFd) ? NO_ERROR : UNKNOWN_ERROR;
Apurva Rajguru3da1a702010-07-28 12:32:42 -07003663 mSnapshotDone = FALSE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003664 LOGV("cancelPicture: X: %d", rc);
3665 return rc;
3666}
3667
3668status_t QualcommCameraHardware::setParameters(const CameraParameters& params)
3669{
3670 LOGV("setParameters: E params = %p", &params);
3671
3672 Mutex::Autolock l(&mLock);
3673 status_t rc, final_rc = NO_ERROR;
3674
3675 if ((rc = setPreviewSize(params))) final_rc = rc;
3676 if ((rc = setPictureSize(params))) final_rc = rc;
3677 if ((rc = setJpegQuality(params))) final_rc = rc;
Vamshidhar Kondrae7b9b5a2010-02-25 15:40:37 +05303678 if ((rc = setEffect(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003679 if ((rc = setGpsLocation(params))) final_rc = rc;
3680 if ((rc = setRotation(params))) final_rc = rc;
3681 if ((rc = setZoom(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003682 if ((rc = setOrientation(params))) final_rc = rc;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05303683 if ((rc = setLensshadeValue(params))) final_rc = rc;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003684 if ((rc = setPictureFormat(params))) final_rc = rc;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08003685 if ((rc = setSharpness(params))) final_rc = rc;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08003686 if ((rc = setSaturation(params))) final_rc = rc;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07003687 if ((rc = setContinuousAf(params))) final_rc = rc;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07003688 if ((rc = setTouchAfAec(params))) final_rc = rc;
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003689 if ((rc = setSceneMode(params))) final_rc = rc;
Apurva Rajguru08383852010-05-17 14:25:39 -07003690 if ((rc = setContrast(params))) final_rc = rc;
Mohan Kandra091d5ab2010-07-14 16:53:25 -07003691 if ((rc = setRecordSize(params))) final_rc = rc;
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07003692 if ((rc = setSceneDetect(params))) final_rc = rc;
Mohan Kandra7110c242010-07-18 15:34:48 -07003693 if ((rc = setStrTextures(params))) final_rc = rc;
3694 if ((rc = setPreviewFormat(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003695
Apurva Rajgurua5e7a6e2010-08-10 19:22:44 -07003696 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
3697 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
3698
3699 if((value != NOT_FOUND) && (value == CAMERA_BESTSHOT_OFF)) {
3700 if ((rc = setPreviewFrameRate(params))) final_rc = rc;
3701 if ((rc = setPreviewFrameRateMode(params))) final_rc = rc;
3702 if ((rc = setAntibanding(params))) final_rc = rc;
3703 if ((rc = setAutoExposure(params))) final_rc = rc;
3704 if ((rc = setExposureCompensation(params))) final_rc = rc;
3705 if ((rc = setWhiteBalance(params))) final_rc = rc;
3706 if ((rc = setFlash(params))) final_rc = rc;
3707 if ((rc = setFocusMode(params))) final_rc = rc;
3708 if ((rc = setBrightness(params))) final_rc = rc;
3709 if ((rc = setISOValue(params))) final_rc = rc;
3710 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003711 LOGV("setParameters: X");
3712 return final_rc;
3713}
3714
3715CameraParameters QualcommCameraHardware::getParameters() const
3716{
3717 LOGV("getParameters: EX");
3718 return mParameters;
3719}
3720
3721status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
3722 int32_t arg2)
3723{
3724 LOGV("sendCommand: EX");
3725 return BAD_VALUE;
3726}
3727
3728extern "C" sp<CameraHardwareInterface> openCameraHardware()
3729{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003730 LOGI("openCameraHardware: call createInstance");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003731 return QualcommCameraHardware::createInstance();
3732}
3733
3734wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
3735
3736// If the hardware already exists, return a strong pointer to the current
3737// object. If not, create a new hardware object, put it in the singleton,
3738// and return it.
3739sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
3740{
Mohan Kandra0d115d12010-08-19 11:47:15 -07003741 LOGI("createInstance: E");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003742
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003743 singleton_lock.lock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003744
3745 // Wait until the previous release is done.
3746 while (singleton_releasing) {
Srinivasan Kannan78444e42010-06-10 15:39:29 -07003747 if((singleton_releasing_start_time != 0) &&
3748 (systemTime() - singleton_releasing_start_time) > SINGLETON_RELEASING_WAIT_TIME){
3749 LOGV("in createinstance system time is %lld %lld %lld ",
3750 systemTime(), singleton_releasing_start_time, SINGLETON_RELEASING_WAIT_TIME);
3751 singleton_lock.unlock();
3752 LOGE("Previous singleton is busy and time out exceeded. Returning null");
3753 return NULL;
3754 }
3755 LOGI("Wait for previous release.");
3756 singleton_wait.waitRelative(singleton_lock, SINGLETON_RELEASING_RECHECK_TIMEOUT);
3757 LOGI("out of Wait for previous release.");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003758 }
3759
3760 if (singleton != 0) {
3761 sp<CameraHardwareInterface> hardware = singleton.promote();
3762 if (hardware != 0) {
3763 LOGD("createInstance: X return existing hardware=%p", &(*hardware));
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003764 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003765 return hardware;
3766 }
3767 }
3768
3769 {
3770 struct stat st;
3771 int rc = stat("/dev/oncrpc", &st);
3772 if (rc < 0) {
3773 LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003774 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003775 return NULL;
3776 }
3777 }
3778
3779 QualcommCameraHardware *cam = new QualcommCameraHardware();
3780 sp<QualcommCameraHardware> hardware(cam);
3781 singleton = hardware;
3782
Mohan Kandra0d115d12010-08-19 11:47:15 -07003783 LOGI("createInstance: created hardware=%p", &(*hardware));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003784 if (!cam->startCamera()) {
3785 LOGE("%s: startCamera failed!", __FUNCTION__);
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003786 singleton_lock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003787 return NULL;
3788 }
3789
3790 cam->initDefaultParameters();
Priyanka Kharatf2deffb2010-05-17 18:11:31 -07003791 singleton_lock.unlock();
Mohan Kandra0d115d12010-08-19 11:47:15 -07003792 LOGI("createInstance: X");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003793 return hardware;
3794}
3795
3796// For internal use only, hence the strong pointer to the derived type.
3797sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
3798{
3799 sp<CameraHardwareInterface> hardware = singleton.promote();
3800 if (hardware != 0) {
3801 // LOGV("getInstance: X old instance of hardware");
3802 return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
3803 } else {
3804 LOGV("getInstance: X new instance of hardware");
3805 return sp<QualcommCameraHardware>();
3806 }
3807}
Sravankb4f5f1c2010-01-21 11:06:17 +05303808void QualcommCameraHardware::receiveRecordingFrame(struct msm_frame *frame)
3809{
3810 LOGV("receiveRecordingFrame E");
3811 // post busy frame
3812 if (frame)
3813 {
3814 cam_frame_post_video (frame);
3815 }
3816 else LOGE("in receiveRecordingFrame frame is NULL");
3817 LOGV("receiveRecordingFrame X");
3818}
3819
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003820
Mohan Kandrad9efed92010-01-15 19:08:39 -08003821bool QualcommCameraHardware::native_zoom_image(int fd, int srcOffset, int dstOffSet, common_crop_t *crop)
Mohan Kandra284966d2010-01-05 13:39:15 -08003822{
3823 int result = 0;
3824 struct mdp_blit_req *e;
3825 struct timeval td1, td2;
3826
Mohan Kandra284966d2010-01-05 13:39:15 -08003827 /* Initialize yuv structure */
3828 zoomImage.list.count = 1;
3829
3830 e = &zoomImage.list.req[0];
3831
3832 e->src.width = previewWidth;
3833 e->src.height = previewHeight;
3834 e->src.format = MDP_Y_CBCR_H2V2;
Mohan Kandrad9efed92010-01-15 19:08:39 -08003835 e->src.offset = srcOffset;
3836 e->src.memory_id = fd;
Mohan Kandra284966d2010-01-05 13:39:15 -08003837
3838 e->dst.width = previewWidth;
3839 e->dst.height = previewHeight;
3840 e->dst.format = MDP_Y_CBCR_H2V2;
Mohan Kandrad9efed92010-01-15 19:08:39 -08003841 e->dst.offset = dstOffSet;
3842 e->dst.memory_id = fd;
Mohan Kandra284966d2010-01-05 13:39:15 -08003843
3844 e->transp_mask = 0xffffffff;
3845 e->flags = 0;
3846 e->alpha = 0xff;
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07003847 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07003848 e->src_rect.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
3849 e->src_rect.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
3850 e->src_rect.w = crop->in1_w;
3851 e->src_rect.h = crop->in1_h;
Mohan Kandra284966d2010-01-05 13:39:15 -08003852 } else {
3853 e->src_rect.x = 0;
3854 e->src_rect.y = 0;
3855 e->src_rect.w = previewWidth;
3856 e->src_rect.h = previewHeight;
3857 }
Mohan Kandrad9efed92010-01-15 19:08:39 -08003858 //LOGV(" native_zoom : SRC_RECT : x,y = %d,%d \t w,h = %d, %d",
3859 // e->src_rect.x, e->src_rect.y, e->src_rect.w, e->src_rect.h);
Mohan Kandra284966d2010-01-05 13:39:15 -08003860
3861 e->dst_rect.x = 0;
3862 e->dst_rect.y = 0;
3863 e->dst_rect.w = previewWidth;
3864 e->dst_rect.h = previewHeight;
3865
3866 result = ioctl(fb_fd, MSMFB_BLIT, &zoomImage.list);
3867 if (result < 0) {
3868 LOGE("MSM_FBIOBLT failed! line=%d\n", __LINE__);
3869 return FALSE;
3870 }
3871 return TRUE;
3872}
3873
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003874void QualcommCameraHardware::debugShowPreviewFPS() const
Mohan Kandra740cfce2010-01-07 12:58:24 -08003875{
3876 static int mFrameCount;
3877 static int mLastFrameCount = 0;
3878 static nsecs_t mLastFpsTime = 0;
3879 static float mFps = 0;
3880 mFrameCount++;
3881 nsecs_t now = systemTime();
3882 nsecs_t diff = now - mLastFpsTime;
3883 if (diff > ms2ns(250)) {
3884 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003885 LOGI("Preview Frames Per Second: %.4f", mFps);
Mohan Kandra740cfce2010-01-07 12:58:24 -08003886 mLastFpsTime = now;
3887 mLastFrameCount = mFrameCount;
3888 }
3889}
3890
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003891void QualcommCameraHardware::debugShowVideoFPS() const
3892{
3893 static int mFrameCount;
3894 static int mLastFrameCount = 0;
3895 static nsecs_t mLastFpsTime = 0;
3896 static float mFps = 0;
3897 mFrameCount++;
3898 nsecs_t now = systemTime();
3899 nsecs_t diff = now - mLastFpsTime;
3900 if (diff > ms2ns(250)) {
3901 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
3902 LOGI("Video Frames Per Second: %.4f", mFps);
3903 mLastFpsTime = now;
3904 mLastFrameCount = mFrameCount;
3905 }
3906}
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05303907
3908void QualcommCameraHardware::receiveLiveSnapshot(uint32_t jpeg_size)
3909{
3910 LOGV("receiveLiveSnapshot E");
3911
3912#ifdef DUMP_LIVESHOT_JPEG_FILE
3913 int file_fd = open("/data/LiveSnapshot.jpg", O_RDWR | O_CREAT, 0777);
3914 LOGV("dumping live shot image in /data/LiveSnapshot.jpg");
3915 if (file_fd < 0) {
3916 LOGE("cannot open file\n");
3917 }
3918 else
3919 {
3920 write(file_fd, (uint8_t *)mJpegHeap->mHeap->base(),jpeg_size);
3921 }
3922 close(file_fd);
3923#endif
3924
3925 Mutex::Autolock cbLock(&mCallbackLock);
3926 if (mDataCallback && (mMsgEnabled & MEDIA_RECORDER_MSG_COMPRESSED_IMAGE)) {
3927 sp<MemoryBase> buffer = new
3928 MemoryBase(mJpegHeap->mHeap,
3929 0,
3930 jpeg_size);
3931 mDataCallback(MEDIA_RECORDER_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
3932 buffer = NULL;
3933 }
3934 else LOGV("JPEG callback was cancelled--not delivering image.");
3935
3936 //Reset the Gps Information & relieve memory
3937 exif_table_numEntries = 0;
3938 mJpegHeap.clear();
3939
3940 liveshot_state = LIVESHOT_DONE;
3941
3942 LOGV("receiveLiveSnapshot X");
3943}
3944
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003945void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
3946{
3947// LOGV("receivePreviewFrame E");
3948
3949 if (!mCameraRunning) {
3950 LOGE("ignoring preview callback--camera has been stopped");
3951 return;
3952 }
3953
Mohan Kandra740cfce2010-01-07 12:58:24 -08003954 if (UNLIKELY(mDebugFps)) {
Mohan Kandrabad0eaa2010-02-04 15:11:54 -08003955 debugShowPreviewFPS();
Mohan Kandra740cfce2010-01-07 12:58:24 -08003956 }
3957
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003958 mCallbackLock.lock();
3959 int msgEnabled = mMsgEnabled;
3960 data_callback pcb = mDataCallback;
3961 void *pdata = mCallbackCookie;
3962 data_callback_timestamp rcb = mDataCallbackTimestamp;
3963 void *rdata = mCallbackCookie;
3964 mCallbackLock.unlock();
3965
3966 // Find the offset within the heap of the current buffer.
Mohan Kandra284966d2010-01-05 13:39:15 -08003967 ssize_t offset_addr =
Mohan Kandrad9efed92010-01-15 19:08:39 -08003968 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
3969 ssize_t offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
Mohan Kandra284966d2010-01-05 13:39:15 -08003970
3971 common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
Nishant Pandit3c278cd2010-07-13 15:56:04 +05303972#ifdef DUMP_PREVIEW_FRAMES
3973 static int frameCnt = 0;
3974 int written;
3975 if (frameCnt >= 0 && frameCnt <= 10 ) {
3976 char buf[128];
3977 sprintf(buf, "/data/%d_preview.yuv", frameCnt);
3978 int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
3979 LOGV("dumping preview frame %d", frameCnt);
3980 if (file_fd < 0) {
3981 LOGE("cannot open file\n");
3982 }
3983 else
3984 {
3985 LOGV("dumping data");
3986 written = write(file_fd, (uint8_t *)frame->buffer,
3987 mPreviewFrameSize );
3988 if(written < 0)
3989 LOGE("error in data write");
3990 }
3991 close(file_fd);
3992 }
3993 frameCnt++;
3994#endif
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003995 mInPreviewCallback = true;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003996 if(mUseOverlay) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07003997 if(mOverlay != NULL) {
3998 mOverlayLock.lock();
Mohan Kandra54e2a022010-07-06 16:23:58 -07003999 mOverlay->setFd(mPreviewHeap->mHeap->getHeapID());
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07004000 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004001 zoomCropInfo.x = (crop->out1_w - crop->in1_w + 1) / 2 - 1;
4002 zoomCropInfo.y = (crop->out1_h - crop->in1_h + 1) / 2 - 1;
4003 zoomCropInfo.w = crop->in1_w;
4004 zoomCropInfo.h = crop->in1_h;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004005 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004006 zoomCropInfo.w, zoomCropInfo.h);
Mohan Kandra9aff1f42010-09-02 19:00:41 -07004007 /* Set mResetOverlayCrop to true, so that when there is
4008 * no crop information, setCrop will be called
4009 * with zero crop values.
4010 */
4011 mResetOverlayCrop = true;
4012
Apurva Rajguru905b8532010-08-02 18:29:38 -07004013 } else {
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08004014 // Reset zoomCropInfo variables. This will ensure that
4015 // stale values wont be used for postview
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004016 zoomCropInfo.w = crop->in1_w;
4017 zoomCropInfo.h = crop->in1_h;
Mohan Kandra9aff1f42010-09-02 19:00:41 -07004018 /* This reset is required, if not, overlay driver continues
4019 * to use the old crop information for these preview
4020 * frames which is not the correct behavior. To avoid
4021 * multiple calls, reset once.
4022 */
4023 if(mResetOverlayCrop == true){
4024 mOverlay->setCrop(0, 0,previewWidth, previewHeight);
4025 mResetOverlayCrop = false;
4026 }
Kiran Kumar H N8ff7b982010-01-25 13:54:39 -08004027 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004028 mOverlay->queueBuffer((void *)offset_addr);
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08004029 mLastQueuedFrame = (void *)frame->buffer;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004030 mOverlayLock.unlock();
4031 }
Mohan Kandra284966d2010-01-05 13:39:15 -08004032 } else {
Apurva Rajguru4ffd6cb2010-08-30 18:57:41 -07004033 if (crop->in1_w != 0 && crop->in1_h != 0) {
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004034 dstOffset = (dstOffset + 1) % NUM_MORE_BUFS;
4035 offset = kPreviewBufferCount + dstOffset;
4036 ssize_t dstOffset_addr = offset * mPreviewHeap->mAlignedBufferSize;
4037 if( !native_zoom_image(mPreviewHeap->mHeap->getHeapID(),
4038 offset_addr, dstOffset_addr, crop)) {
4039 LOGE(" Error while doing MDP zoom ");
Kiran Kumar H N1ece71c2010-03-30 10:31:21 -07004040 offset = offset_addr / mPreviewHeap->mAlignedBufferSize;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004041 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004042 }
4043 if (mCurrentTarget == TARGET_MSM7627) {
4044 mLastQueuedFrame = (void *)mPreviewHeap->mBuffers[offset]->pointer();
4045 }
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08004046 }
Mohan Kandrad9efed92010-01-15 19:08:39 -08004047 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
4048 pcb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap->mBuffers[offset],
4049 pdata);
4050
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304051 // If output is NOT enabled (targets otherthan 7x30 , 8x50 and 8x60 currently..)
4052 if( (mCurrentTarget != TARGET_MSM7630 ) && (mCurrentTarget != TARGET_QSD8250) && (mCurrentTarget != TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304053 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
4054 rcb(systemTime(), CAMERA_MSG_VIDEO_FRAME, mPreviewHeap->mBuffers[offset], rdata);
4055 Mutex::Autolock rLock(&mRecordFrameLock);
4056 if (mReleasedRecordingFrame != true) {
4057 LOGV("block waiting for frame release");
4058 mRecordWait.wait(mRecordFrameLock);
4059 LOGV("frame released, continuing");
4060 }
4061 mReleasedRecordingFrame = false;
4062 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004063 }
4064 mInPreviewCallback = false;
4065
4066// LOGV("receivePreviewFrame X");
4067}
4068
Sravankb4f5f1c2010-01-21 11:06:17 +05304069
4070bool QualcommCameraHardware::initRecord()
4071{
Mohan Kandra62429cc2010-07-19 10:21:05 -07004072 const char *pmem_region;
Nishant Panditbde07612010-07-28 00:16:28 +05304073 int CbCrOffset;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004074 int recordBufferSize;
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004075
Sravankb4f5f1c2010-01-21 11:06:17 +05304076 LOGV("initREcord E");
4077
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004078 /* when DIS is ON, video dimensions should be increased,
4079 * as a requirement from VFE-VPE operations. This logic will be
4080 * moved down to camera stack coming forward.
4081 */
4082 if(mVpeEnabled && mDisEnabled) {
Mohan Kandraec958742010-08-19 10:56:05 -07004083 /* As 5MP sensor, in QTR mode can't output frame of size greater than 1280,
4084 * don't request for bigger buffer
4085 */
Nishant Pandit5fc64d42010-08-31 09:13:03 +05304086 if(((mDimension.video_width == 1280 && mDimension.video_height == 720)
4087 && !strcmp(sensorType->name, "5mp")) || (mDimension.video_width == 1920 && mDimension.video_height == 1088)) {
Mohan Kandraec958742010-08-19 10:56:05 -07004088 LOGI("video resolution (%dx%d) is not supported for sensor (%s) when DIS is ON",
4089 mDimension.video_width, mDimension.video_height, sensorType->name);
4090 } else {
4091 int width = mDimension.video_width *1.1;
4092 mDimension.video_width = CEILING32(width);
4093 int height = mDimension.video_height *1.1;
4094 mDimension.video_height = CEILING32(height);
4095 }
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004096 }
4097
Vinay Kaliaba3555f2010-07-21 11:37:36 -07004098 if(mCurrentTarget == TARGET_MSM8660)
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004099 pmem_region = "/dev/pmem_smipool";
4100 else
4101 pmem_region = "/dev/pmem_adsp";
4102
Nishant Panditbde07612010-07-28 00:16:28 +05304103 // for 8x60 the Encoder expects the CbCr offset should be aligned to 2K.
4104 if(mCurrentTarget == TARGET_MSM8660) {
4105 CbCrOffset = PAD_TO_2K(mDimension.video_width * mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004106 recordBufferSize = CbCrOffset + PAD_TO_2K((mDimension.video_width * mDimension.video_height)/2);
Nishant Panditbde07612010-07-28 00:16:28 +05304107 } else {
4108 CbCrOffset = PAD_TO_WORD(mDimension.video_width * mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004109 recordBufferSize = (mDimension.video_width * mDimension.video_height *3)/2;
Nishant Panditbde07612010-07-28 00:16:28 +05304110 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004111 LOGV("initRecord: mDimension.video_width = %d mDimension.video_height = %d",
4112 mDimension.video_width, mDimension.video_height);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004113
4114 /* Buffersize and frameSize will be different when DIS is ON.
4115 * We need to pass the actual framesize with video heap, as the same
4116 * is used at camera MIO when negotiating with encoder.
4117 */
4118 mRecordFrameSize = recordBufferSize;
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004119 if(mVpeEnabled && mDisEnabled){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004120 mRecordFrameSize = videoWidth * videoHeight * 3 / 2;
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004121 if(mCurrentTarget == TARGET_MSM8660){
4122 mRecordFrameSize = PAD_TO_2K(videoWidth * videoHeight)
4123 + PAD_TO_2K((videoWidth * videoHeight)/2);
4124 }
4125 }
4126 LOGV("mRecordFrameSize = %d", mRecordFrameSize);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004127
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004128 mRecordHeap = new PmemPool(pmem_region,
Sravankb4f5f1c2010-01-21 11:06:17 +05304129 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
4130 mCameraControlFd,
4131 MSM_PMEM_VIDEO,
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004132 recordBufferSize,
Sravankb4f5f1c2010-01-21 11:06:17 +05304133 kRecordBufferCount,
4134 mRecordFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07004135 CbCrOffset,
4136 0,
Sravankb4f5f1c2010-01-21 11:06:17 +05304137 "record");
Apurva Rajguruc73c1722010-04-15 17:39:11 -07004138
Sravankb4f5f1c2010-01-21 11:06:17 +05304139 if (!mRecordHeap->initialized()) {
4140 mRecordHeap.clear();
4141 LOGE("initRecord X: could not initialize record heap.");
4142 return false;
4143 }
4144 for (int cnt = 0; cnt < kRecordBufferCount; cnt++) {
4145 recordframes[cnt].fd = mRecordHeap->mHeap->getHeapID();
4146 recordframes[cnt].buffer =
4147 (uint32_t)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
4148 recordframes[cnt].y_off = 0;
Nishant Panditbde07612010-07-28 00:16:28 +05304149 recordframes[cnt].cbcr_off = CbCrOffset;
Sravankb4f5f1c2010-01-21 11:06:17 +05304150 recordframes[cnt].path = OUTPUT_TYPE_V;
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004151 record_buffers_tracking_flag[cnt] = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304152 LOGV ("initRecord : record heap , video buffers buffer=%lu fd=%d y_off=%d cbcr_off=%d \n",
4153 (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
4154 recordframes[cnt].cbcr_off);
4155 }
4156
4157 // initial setup : buffers 1,2,3 with kernel , 4 with camframe , 5,6,7,8 in free Q
4158 // flush the busy Q
4159 cam_frame_flush_video();
4160
Mohan Kandra156d0ac2010-01-25 16:59:17 -08004161 mVideoThreadWaitLock.lock();
4162 while (mVideoThreadRunning) {
4163 LOGV("initRecord: waiting for old video thread to complete.");
4164 mVideoThreadWait.wait(mVideoThreadWaitLock);
4165 LOGV("initRecord : old video thread completed.");
4166 }
4167 mVideoThreadWaitLock.unlock();
4168
Sravankdf7a9202010-02-08 15:02:51 +05304169 // flush free queue and add 5,6,7,8 buffers.
4170 LINK_cam_frame_flush_free_video();
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004171 if(mVpeEnabled) {
4172 //If VPE is enabled, the VPE buffer shouldn't be added to Free Q initally.
4173 for(int i=ACTIVE_VIDEO_BUFFERS+1;i <kRecordBufferCount-1; i++)
4174 LINK_camframe_free_video(&recordframes[i]);
4175 } else {
4176 for(int i=ACTIVE_VIDEO_BUFFERS+1;i <kRecordBufferCount; i++)
4177 LINK_camframe_free_video(&recordframes[i]);
4178 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304179 LOGV("initREcord X");
4180
4181 return true;
4182}
4183
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004184status_t QualcommCameraHardware::setVpeParameters()
4185{
4186 LOGV("setVpeParameters E");
4187
4188 video_dis_param_ctrl_t disCtrl;
4189 video_rotation_param_ctrl_t rotCtrl;
Mohan Kandraec958742010-08-19 10:56:05 -07004190 bool ret = true;
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004191 LOGV("mDisEnabled = %d", mDisEnabled);
4192 LOGV("videoWidth = %d, videoHeight = %d", videoWidth, videoHeight);
4193 if(mDisEnabled) {
Mohan Kandraec958742010-08-19 10:56:05 -07004194 /* As 5MP sensor, in QTR mode can't output frame of size greater than 1280,
4195 * don't set DIS to ON.
4196 */
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004197 int video_frame_cbcroffset;
4198 video_frame_cbcroffset = PAD_TO_WORD(videoWidth * videoHeight);
4199 if(mCurrentTarget == TARGET_MSM8660)
4200 video_frame_cbcroffset = PAD_TO_2K(videoWidth * videoHeight);
4201
4202 disCtrl.dis_enable = mDisEnabled;
4203 disCtrl.video_rec_width = videoWidth;
4204 disCtrl.video_rec_height = videoHeight;
4205 disCtrl.output_cbcr_offset = video_frame_cbcroffset;
4206
Nishant Pandit5fc64d42010-08-31 09:13:03 +05304207 if(((videoWidth == 1280 && videoHeight == 720)
4208 && !strcmp(sensorType->name, "5mp"))||(videoWidth == 1920 && videoHeight == 1088)) {
Mohan Kandraec958742010-08-19 10:56:05 -07004209 LOGI("video resolution (%dx%d) is not supported for sensor (%s) when DIS is ON",
4210 mDimension.video_width, mDimension.video_height, sensorType->name);
4211 disCtrl.dis_enable = 0;
Mohan Kandraec958742010-08-19 10:56:05 -07004212 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004213 ret = native_set_parm(CAMERA_SET_VIDEO_DIS_PARAMS,
4214 sizeof(disCtrl), &disCtrl);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004215 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004216
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004217 rotCtrl.rotation = (mRotation == 0) ? ROT_NONE :
4218 ((mRotation == 90) ? ROT_CLOCKWISE_90 :
4219 ((mRotation == 180) ? ROT_CLOCKWISE_180 : ROT_CLOCKWISE_270));
4220
Mohan Kandraec958742010-08-19 10:56:05 -07004221 if( ((videoWidth == 1280 && videoHeight == 720) || (videoWidth == 800 && videoHeight == 480))
4222 && (mRotation == 90 || mRotation == 270) ){
4223 /* Due to a limitation at video core to support heights greater than 720, adding this check.
4224 * This is a temporary hack, need to be removed once video core support is available
4225 */
4226 LOGI("video resolution (%dx%d) with rotation (%d) is not supported",
4227 videoWidth, videoHeight, mRotation);
4228 rotCtrl.rotation = ROT_NONE;
Mohan Kandraec958742010-08-19 10:56:05 -07004229 }
Mohan Kandrafdbc2192010-08-24 20:39:59 -07004230 LOGV("rotCtrl.rotation = %d", rotCtrl.rotation);
4231
4232 ret = native_set_parm(CAMERA_SET_VIDEO_ROT_PARAMS,
4233 sizeof(rotCtrl), &rotCtrl);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004234
4235 LOGV("setVpeParameters X (%d)", ret);
4236 return ret ? NO_ERROR : UNKNOWN_ERROR;
4237}
4238
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004239status_t QualcommCameraHardware::startRecording()
4240{
4241 LOGV("startRecording E");
Sravankb4f5f1c2010-01-21 11:06:17 +05304242 int ret;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004243 Mutex::Autolock l(&mLock);
4244 mReleasedRecordingFrame = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304245 if( (ret=startPreviewInternal())== NO_ERROR){
Mohan Kandra39fad8d2010-07-15 12:29:19 -07004246 if(mVpeEnabled){
4247 LOGI("startRecording: VPE enabled, setting vpe parameters");
4248 bool status = setVpeParameters();
4249 if(status) {
4250 LOGE("Failed to set VPE parameters");
4251 return status;
4252 }
4253 }
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304254 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304255 LOGV(" in startREcording : calling native_start_recording");
4256 native_start_recording(mCameraControlFd);
4257 recordingState = 1;
Sravank64461e82010-02-25 15:10:09 +05304258 // Remove the left out frames in busy Q and them in free Q.
4259 // this should be done before starting video_thread so that,
4260 // frames in previous recording are flushed out.
4261 LOGV("frames in busy Q = %d", g_busy_frame_queue.num_of_frames);
4262 while((g_busy_frame_queue.num_of_frames) >0){
4263 msm_frame* vframe = cam_frame_get_video ();
4264 LINK_camframe_free_video(vframe);
4265 }
4266 LOGV("frames in busy Q = %d after deQueing", g_busy_frame_queue.num_of_frames);
4267
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004268 //Clear the dangling buffers and put them in free queue
4269 for(int cnt = 0; cnt < kRecordBufferCount; cnt++) {
4270 if(record_buffers_tracking_flag[cnt] == true) {
Mohan Kandra62429cc2010-07-19 10:21:05 -07004271 LOGI("Dangling buffer: offset = %d, buffer = %d", cnt, (unsigned int)recordframes[cnt].buffer);
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004272 LINK_camframe_free_video(&recordframes[cnt]);
4273 record_buffers_tracking_flag[cnt] = false;
4274 }
4275 }
4276
Sravankdf7a9202010-02-08 15:02:51 +05304277 // Start video thread and wait for busy frames to be encoded, this thread
4278 // should be closed in stopRecording
4279 mVideoThreadWaitLock.lock();
4280 mVideoThreadExit = 0;
4281 pthread_attr_t attr;
4282 pthread_attr_init(&attr);
4283 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4284 mVideoThreadRunning = pthread_create(&mVideoThread,
4285 &attr,
4286 video_thread,
4287 NULL);
4288 mVideoThreadWaitLock.unlock();
4289 // Remove the left out frames in busy Q and them in free Q.
Sravankb4f5f1c2010-01-21 11:06:17 +05304290 }
4291 }
4292 return ret;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004293}
4294
4295void QualcommCameraHardware::stopRecording()
4296{
4297 LOGV("stopRecording: E");
4298 Mutex::Autolock l(&mLock);
4299 {
4300 mRecordFrameLock.lock();
4301 mReleasedRecordingFrame = true;
4302 mRecordWait.signal();
4303 mRecordFrameLock.unlock();
4304
Sravankdf7a9202010-02-08 15:02:51 +05304305 if(mDataCallback && !(mCurrentTarget == TARGET_QSD8250) &&
4306 (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004307 LOGV("stopRecording: X, preview still in progress");
4308 return;
4309 }
4310 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304311 // If output2 enabled, exit video thread, invoke stop recording ioctl
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304312 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304313 mVideoThreadWaitLock.lock();
4314 mVideoThreadExit = 1;
4315 mVideoThreadWaitLock.unlock();
4316 native_stop_recording(mCameraControlFd);
Srinivasan Kannanfc3915c2010-03-18 10:54:40 -07004317
4318 pthread_mutex_lock(&(g_busy_frame_queue.mut));
4319 pthread_cond_signal(&(g_busy_frame_queue.wait));
4320 pthread_mutex_unlock(&(g_busy_frame_queue.mut));
Sravankb4f5f1c2010-01-21 11:06:17 +05304321 }
4322 else // for other targets where output2 is not enabled
4323 stopPreviewInternal();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004324
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05304325 if (mJpegHeap != NULL) {
4326 LOGV("stopRecording: clearing old mJpegHeap.");
4327 mJpegHeap.clear();
4328 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304329 recordingState = 0; // recording not started
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004330 LOGV("stopRecording: X");
4331}
4332
4333void QualcommCameraHardware::releaseRecordingFrame(
4334 const sp<IMemory>& mem __attribute__((unused)))
4335{
4336 LOGV("releaseRecordingFrame E");
4337 Mutex::Autolock rLock(&mRecordFrameLock);
4338 mReleasedRecordingFrame = true;
4339 mRecordWait.signal();
Sravankb4f5f1c2010-01-21 11:06:17 +05304340
4341 // Ff 7x30 : add the frame to the free camframe queue
Nishant Pandit3c278cd2010-07-13 15:56:04 +05304342 if( (mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660)) {
Sravankb4f5f1c2010-01-21 11:06:17 +05304343 ssize_t offset;
4344 size_t size;
4345 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
4346 msm_frame* releaseframe = NULL;
4347 LOGV(" in release recording frame : heap base %d offset %d buffer %d ", heap->base(), offset, heap->base() + offset );
4348 int cnt;
4349 for (cnt = 0; cnt < kRecordBufferCount; cnt++) {
Mohan Kandra62429cc2010-07-19 10:21:05 -07004350 if((unsigned int)recordframes[cnt].buffer == ((unsigned int)heap->base()+ offset)){
Sravankb4f5f1c2010-01-21 11:06:17 +05304351 LOGV("in release recording frame found match , releasing buffer %d", (unsigned int)recordframes[cnt].buffer);
4352 releaseframe = &recordframes[cnt];
4353 break;
4354 }
4355 }
4356 if(cnt < kRecordBufferCount) {
4357 // do this only if frame thread is running
4358 mFrameThreadWaitLock.lock();
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004359 if(mFrameThreadRunning ) {
4360 //Reset the track flag for this frame buffer
4361 record_buffers_tracking_flag[cnt] = false;
Sravankb4f5f1c2010-01-21 11:06:17 +05304362 LINK_camframe_free_video(releaseframe);
Mohan Kandra1fd90f92010-06-17 14:54:17 -07004363 }
Sravankb4f5f1c2010-01-21 11:06:17 +05304364
4365 mFrameThreadWaitLock.unlock();
4366 } else {
4367 LOGE("in release recordingframe XXXXX error , buffer not found");
4368 for (int i=0; i< kRecordBufferCount; i++) {
4369 LOGE(" recordframes[%d].buffer = %d", i, (unsigned int)recordframes[i].buffer);
4370 }
4371 }
4372 }
4373
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004374 LOGV("releaseRecordingFrame X");
4375}
4376
4377bool QualcommCameraHardware::recordingEnabled()
4378{
4379 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
4380}
4381
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004382void QualcommCameraHardware::notifyShutter(common_crop_t *crop, bool mPlayShutterSoundOnly)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004383{
4384 mShutterLock.lock();
4385 image_rect_type size;
4386
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004387 if(mPlayShutterSoundOnly) {
4388 /* At this point, invoke Notify Callback to play shutter sound only.
4389 * We want to call notify callback again when we have the
4390 * yuv picture ready. This is to reduce blanking at the time
4391 * of displaying postview frame. Using ext2 to indicate whether
4392 * to play shutter sound only or register the postview buffers.
4393 */
4394 mNotifyCallback(CAMERA_MSG_SHUTTER, 0, mPlayShutterSoundOnly,
4395 mCallbackCookie);
4396 mShutterLock.unlock();
4397 return;
4398 }
4399
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004400 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
4401 LOGV("out2_w=%d, out2_h=%d, in2_w=%d, in2_h=%d",
4402 crop->out2_w, crop->out2_h, crop->in2_w, crop->in2_h);
4403 LOGV("out1_w=%d, out1_h=%d, in1_w=%d, in1_h=%d",
4404 crop->out1_w, crop->out1_h, crop->in1_w, crop->in1_h);
4405
4406 // To workaround a bug in MDP which happens if either
4407 // dimension > 2048, we display the thumbnail instead.
Apurva Rajguru905b8532010-08-02 18:29:38 -07004408
4409 if (mCurrentTarget == TARGET_MSM7627)
4410 mDisplayHeap = mPostViewHeap;
4411 else
4412 mDisplayHeap = mRawHeap;
4413
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004414 if (crop->in1_w == 0 || crop->in1_h == 0) {
4415 // Full size
4416 size.width = mDimension.picture_width;
4417 size.height = mDimension.picture_height;
4418 if (size.width > 2048 || size.height > 2048) {
4419 size.width = mDimension.ui_thumbnail_width;
4420 size.height = mDimension.ui_thumbnail_height;
4421 mDisplayHeap = mThumbnailHeap;
4422 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004423 else {
4424 if (mCurrentTarget == TARGET_MSM7627) {
4425 size.width = previewWidth;
4426 size.height = previewHeight;
4427 }
4428 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004429 } else {
4430 // Cropped
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004431 size.width = (crop->in2_w + jpegPadding) & ~1;
4432 size.height = (crop->in2_h + jpegPadding) & ~1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004433 if (size.width > 2048 || size.height > 2048) {
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004434 size.width = (crop->in1_w + jpegPadding) & ~1;
4435 size.height = (crop->in1_h + jpegPadding) & ~1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004436 mDisplayHeap = mThumbnailHeap;
4437 }
Apurva Rajguru905b8532010-08-02 18:29:38 -07004438 else {
4439 if (mCurrentTarget == TARGET_MSM7627) {
4440 size.width = previewWidth;
4441 size.height = previewHeight;
4442 }
4443 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004444 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004445 //For Adreno format, we need to pass the main image in all the cases.
4446 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO)
4447 mDisplayHeap = mRawHeap;
4448
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004449 /* Now, invoke Notify Callback to unregister preview buffer
4450 * and register postview buffer with surface flinger. Set ext2
4451 * as 0 to indicate not to play shutter sound.
4452 */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004453 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
4454 mCallbackCookie);
4455 mShutterPending = false;
4456 }
4457 mShutterLock.unlock();
4458}
4459
4460static void receive_shutter_callback(common_crop_t *crop)
4461{
4462 LOGV("receive_shutter_callback: E");
4463 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
4464 if (obj != 0) {
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004465 /* Just play shutter sound at this time */
4466 obj->notifyShutter(crop, TRUE);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004467 }
4468 LOGV("receive_shutter_callback: X");
4469}
4470
4471// Crop the picture in place.
4472static void crop_yuv420(uint32_t width, uint32_t height,
4473 uint32_t cropped_width, uint32_t cropped_height,
Apurva Rajguru905b8532010-08-02 18:29:38 -07004474 uint8_t *image, const char *name)
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004475{
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004476 int32_t i;
4477 uint32_t x, y;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004478 uint8_t* chroma_src, *chroma_dst;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004479 int yOffsetSrc, yOffsetDst, CbCrOffsetSrc, CbCrOffsetDst;
4480 int mSrcSize, mDstSize;
4481
4482 //check if all fields needed eg. size and also how to set y offset. If condition for 7x27
4483 //and need to check if needed for 7x30.
4484
4485 LINK_jpeg_encoder_get_buffer_offset(width, height, (uint32_t *)&yOffsetSrc,
4486 (uint32_t *)&CbCrOffsetSrc, (uint32_t *)&mSrcSize);
4487
4488 LINK_jpeg_encoder_get_buffer_offset(cropped_width, cropped_height, (uint32_t *)&yOffsetDst,
4489 (uint32_t *)&CbCrOffsetDst, (uint32_t *)&mDstSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004490
4491 // Calculate the start position of the cropped area.
4492 x = (width - cropped_width) / 2;
4493 y = (height - cropped_height) / 2;
4494 x &= ~1;
4495 y &= ~1;
4496
Apurva Rajguru905b8532010-08-02 18:29:38 -07004497 if((mCurrentTarget == TARGET_MSM7627)
Priyanka Kharat32409f72010-08-25 18:11:03 -07004498 || (mCurrentTarget == TARGET_MSM7630)
4499 || (mCurrentTarget == TARGET_MSM8660)) {
Apurva Rajguru905b8532010-08-02 18:29:38 -07004500 if (!strcmp("snapshot camera", name)) {
4501 chroma_src = image + CbCrOffsetSrc;
4502 chroma_dst = image + CbCrOffsetDst;
4503 } else {
4504 chroma_src = image + width * height;
4505 chroma_dst = image + cropped_width * cropped_height;
Apurva Rajgurubfc04522010-08-11 16:22:25 -07004506 yOffsetSrc = 0;
4507 yOffsetDst = 0;
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004508 CbCrOffsetSrc = width * height;
4509 CbCrOffsetDst = cropped_width * cropped_height;
Apurva Rajguru905b8532010-08-02 18:29:38 -07004510 }
4511 } else {
4512 chroma_src = image + CbCrOffsetSrc;
4513 chroma_dst = image + CbCrOffsetDst;
4514 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004515
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004516 int32_t bufDst = yOffsetDst;
4517 int32_t bufSrc = yOffsetSrc + (width * y) + x;
4518
4519 if( bufDst > bufSrc ){
4520 LOGV("crop yuv Y destination position follows source position");
4521 /*
4522 * If buffer destination follows buffer source, memcpy
4523 * of lines will lead to overwriting subsequent lines. In order
4524 * to prevent this, reverse copying of lines is performed
4525 * for the set of lines where destination follows source and
4526 * forward copying of lines is performed for lines where source
4527 * follows destination. To calculate the position to switch,
4528 * the initial difference between source and destination is taken
4529 * and divided by difference between width and cropped width. For
4530 * every line copied the difference between source destination
4531 * drops by width - cropped width
4532 */
4533 //calculating inversion
4534 int position = ( bufDst - bufSrc ) / (width - cropped_width);
4535 // Copy luma component.
4536 for(i=position+1; i < cropped_height; i++){
4537 memmove(image + yOffsetDst + i * cropped_width,
4538 image + yOffsetSrc + width * (y + i) + x,
4539 cropped_width);
4540 }
4541 for(i=position; i>=0; i--){
4542 memmove(image + yOffsetDst + i * cropped_width,
4543 image + yOffsetSrc + width * (y + i) + x,
4544 cropped_width);
4545 }
4546 } else {
4547 // Copy luma component.
4548 for(i = 0; i < cropped_height; i++)
4549 memcpy(image + yOffsetDst + i * cropped_width,
4550 image + yOffsetSrc + width * (y + i) + x,
4551 cropped_width);
4552 }
4553
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004554 // Copy chroma components.
4555 cropped_height /= 2;
4556 y /= 2;
Srinivasan Kannan970bb4f2010-09-08 20:08:16 -07004557
4558 bufDst = CbCrOffsetDst;
4559 bufSrc = CbCrOffsetSrc + (width * y) + x;
4560
4561 if( bufDst > bufSrc ) {
4562 LOGV("crop yuv Chroma destination position follows source position");
4563 /*
4564 * Similar to y
4565 */
4566 int position = ( bufDst - bufSrc ) / (width - cropped_width);
4567 for(i=position+1; i < cropped_height; i++){
4568 memmove(chroma_dst + i * cropped_width,
4569 chroma_src + width * (y + i) + x,
4570 cropped_width);
4571 }
4572 for(i=position; i >=0; i--){
4573 memmove(chroma_dst + i * cropped_width,
4574 chroma_src + width * (y + i) + x,
4575 cropped_width);
4576 }
4577 } else {
4578 for(i = 0; i < cropped_height; i++)
4579 memcpy(chroma_dst + i * cropped_width,
4580 chroma_src + width * (y + i) + x,
4581 cropped_width);
4582 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004583}
4584
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004585void QualcommCameraHardware::receiveRawSnapshot(){
4586 LOGV("receiveRawSnapshot E");
4587
4588 Mutex::Autolock cbLock(&mCallbackLock);
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004589 /* Issue notifyShutter with mPlayShutterSoundOnly as TRUE */
4590 notifyShutter(&mCrop, TRUE);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004591
4592 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4593
4594 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
4595 LOGE("receiveRawSnapshot X: native_get_picture failed!");
4596 return;
4597 }
Kiran Kumar H Ncb54ba82010-03-09 10:27:38 -08004598 /* Its necessary to issue another notifyShutter here with
4599 * mPlayShutterSoundOnly as FALSE, since that is when the
4600 * preview buffers are unregistered with the surface flinger.
4601 * That is necessary otherwise the preview memory wont be
4602 * deallocated.
4603 */
4604 notifyShutter(&mCrop, FALSE);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004605
4606 //Create a Ashmem heap to copy data from PMem heap for application layer
4607 if(mRawSnapshotAshmemHeap != NULL){
4608 LOGV("receiveRawSnapshot: clearing old mRawSnapShotAshmemHeap.");
4609 mRawSnapshotAshmemHeap.clear();
4610 }
4611 mRawSnapshotAshmemHeap = new AshmemPool(
4612 mRawSnapShotPmemHeap->mBufferSize,
4613 mRawSnapShotPmemHeap->mNumBuffers,
4614 mRawSnapShotPmemHeap->mFrameSize,
4615 "raw ashmem snapshot camera"
4616 );
4617
4618 if(!mRawSnapshotAshmemHeap->initialized()){
4619 LOGE("receiveRawSnapshot X: error initializing mRawSnapshotHeap");
4620 deinitRawSnapshot();
4621 return;
4622 }
4623
4624 memcpy(mRawSnapshotAshmemHeap->mHeap->base(),
4625 mRawSnapShotPmemHeap->mHeap->base(),
4626 mRawSnapShotPmemHeap->mHeap->getSize());
Nishant Panditb861be52010-03-02 16:43:49 +05304627 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))
4628 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mRawSnapshotAshmemHeap->mBuffers[0],
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08004629 mCallbackCookie);
4630
4631 }
4632
4633 //cleanup
4634 deinitRawSnapshot();
4635
4636 LOGV("receiveRawSnapshot X");
4637}
4638
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004639void QualcommCameraHardware::receiveRawPicture()
4640{
4641 LOGV("receiveRawPicture: E");
4642
4643 Mutex::Autolock cbLock(&mCallbackLock);
Apurva Rajguru3da1a702010-07-28 12:32:42 -07004644 if (mDataCallback && ((mMsgEnabled & CAMERA_MSG_RAW_IMAGE) || mSnapshotDone)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004645 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
4646 LOGE("getPicture failed!");
4647 return;
4648 }
Apurva Rajguru3da1a702010-07-28 12:32:42 -07004649 mSnapshotDone = FALSE;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004650 mCrop.in1_w &= ~1;
4651 mCrop.in1_h &= ~1;
4652 mCrop.in2_w &= ~1;
4653 mCrop.in2_h &= ~1;
4654
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004655
4656 // Crop the image if zoomed.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004657 if (mCrop.in2_w != 0 && mCrop.in2_h != 0 &&
4658 ((mCrop.in2_w + jpegPadding) < mCrop.out2_w) &&
4659 ((mCrop.in2_h + jpegPadding) < mCrop.out2_h) &&
4660 ((mCrop.in1_w + jpegPadding) < mCrop.out1_w) &&
4661 ((mCrop.in1_h + jpegPadding) < mCrop.out1_h) ) {
4662
4663 // By the time native_get_picture returns, picture is taken. Call
4664 // shutter callback if cam config thread has not done that.
4665 notifyShutter(&mCrop, FALSE);
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004666 {
4667 Mutex::Autolock l(&mRawPictureHeapLock);
4668 if(mRawHeap != NULL)
4669 crop_yuv420(mCrop.out2_w, mCrop.out2_h, (mCrop.in2_w + jpegPadding), (mCrop.in2_h + jpegPadding),
Apurva Rajguru905b8532010-08-02 18:29:38 -07004670 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mName);
4671 if(mThumbnailHeap != NULL) {
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004672 crop_yuv420(mCrop.out1_w, mCrop.out1_h, (mCrop.in1_w + jpegPadding), (mCrop.in1_h + jpegPadding),
Apurva Rajguru905b8532010-08-02 18:29:38 -07004673 (uint8_t *)mThumbnailHeap->mHeap->base(), mThumbnailHeap->mName);
4674 }
Srinivasan Kannan426cde72010-06-04 09:37:21 -07004675 }
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004676
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004677 // We do not need jpeg encoder to upscale the image. Set the new
4678 // dimension for encoder.
Srinivasan Kannan5701a942010-04-15 16:17:21 -07004679 mDimension.orig_picture_dx = mCrop.in2_w + jpegPadding;
4680 mDimension.orig_picture_dy = mCrop.in2_h + jpegPadding;
4681 mDimension.thumbnail_width = mCrop.in1_w + jpegPadding;
4682 mDimension.thumbnail_height = mCrop.in1_h + jpegPadding;
4683 }else {
4684 memset(&mCrop, 0 ,sizeof(mCrop));
4685 // By the time native_get_picture returns, picture is taken. Call
4686 // shutter callback if cam config thread has not done that.
4687 notifyShutter(&mCrop, FALSE);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004688 }
4689
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08004690 if( mUseOverlay && (mOverlay != NULL) ) {
Mohan Kandra54e2a022010-07-06 16:23:58 -07004691 mOverlay->setFd(mPostViewHeap->mHeap->getHeapID());
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08004692 if( zoomCropInfo.w !=0 && zoomCropInfo.h !=0) {
4693 LOGD(" zoomCropInfo non-zero, setting crop ");
4694 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
4695 zoomCropInfo.w, zoomCropInfo.h);
4696 }
4697 LOGD(" Queueing Postview for display ");
4698 mOverlay->queueBuffer((void *)0);
4699 }
Nishant Panditb861be52010-03-02 16:43:49 +05304700 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE))
4701 mDataCallback(CAMERA_MSG_RAW_IMAGE, mDisplayHeap->mBuffers[0],
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004702 mCallbackCookie);
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004703 if(mPreviewFormat == CAMERA_YUV_420_NV21_ADRENO) {
4704 LOGE("Raw Data given to app for processing...will wait for jpeg encode call");
4705 mEncodePendingWaitLock.lock();
4706 mEncodePending = true;
4707 mEncodePendingWaitLock.unlock();
4708 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004709 }
4710 else LOGV("Raw-picture callback was canceled--skipping.");
4711
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004712 if(mPreviewFormat != CAMERA_YUV_420_NV21_ADRENO) {
4713 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4714 mJpegSize = 0;
4715 mJpegThreadWaitLock.lock();
4716 if (LINK_jpeg_encoder_init()) {
4717 mJpegThreadRunning = true;
4718 mJpegThreadWaitLock.unlock();
4719 if(native_jpeg_encode()) {
4720 LOGV("receiveRawPicture: X (success)");
4721 return;
4722 }
4723 LOGE("jpeg encoding failed");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004724 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004725 else {
4726 LOGE("receiveRawPicture X: jpeg_encoder_init failed.");
4727 mJpegThreadWaitLock.unlock();
4728 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004729 }
Mohan Kandra1659b0c2010-07-18 16:36:25 -07004730 else LOGV("JPEG callback is NULL, not encoding image.");
4731 deinitRaw();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004732 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004733 LOGV("receiveRawPicture: X");
4734}
4735
4736void QualcommCameraHardware::receiveJpegPictureFragment(
4737 uint8_t *buff_ptr, uint32_t buff_size)
4738{
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05304739 LOGV("receiveJpegPictureFragment size %d", buff_size);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004740 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
4741 remaining -= mJpegSize;
4742 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
4743
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004744 if (buff_size > remaining) {
4745 LOGE("receiveJpegPictureFragment: size %d exceeds what "
4746 "remains in JPEG heap (%d), truncating",
4747 buff_size,
4748 remaining);
4749 buff_size = remaining;
4750 }
4751 memcpy(base + mJpegSize, buff_ptr, buff_size);
4752 mJpegSize += buff_size;
4753}
4754
4755void QualcommCameraHardware::receiveJpegPicture(void)
4756{
4757 LOGV("receiveJpegPicture: E image (%d uint8_ts out of %d)",
4758 mJpegSize, mJpegHeap->mBufferSize);
4759 Mutex::Autolock cbLock(&mCallbackLock);
4760
4761 int index = 0, rc;
4762
4763 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
4764 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
4765 // that the JPEG image's size will probably change from one snapshot
4766 // to the next, so we cannot reuse the MemoryBase object.
4767 sp<MemoryBase> buffer = new
4768 MemoryBase(mJpegHeap->mHeap,
4769 index * mJpegHeap->mBufferSize +
4770 0,
4771 mJpegSize);
4772 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
4773 buffer = NULL;
4774 }
4775 else LOGV("JPEG callback was cancelled--not delivering image.");
4776
Mohan Kandraca2e7a92010-06-21 15:48:45 -07004777 mJpegThreadWaitLock.lock();
4778 mJpegThreadRunning = false;
4779 mJpegThreadWait.signal();
4780 mJpegThreadWaitLock.unlock();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004781
4782 LOGV("receiveJpegPicture: X callback done.");
4783}
4784
4785bool QualcommCameraHardware::previewEnabled()
4786{
Kiran Kumar H N280d4de2010-05-05 13:40:15 -07004787 /* If overlay is used the message CAMERA_MSG_PREVIEW_FRAME would
4788 * be disabled at CameraService layer. Hence previewEnabled would
4789 * return FALSE even though preview is running. Hence check for
4790 * mOverlay not being NULL to ensure that previewEnabled returns
4791 * accurate information.
4792 */
4793 return mCameraRunning && mDataCallback &&
4794 ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) || (mOverlay != NULL));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004795}
Mohan Kandra091d5ab2010-07-14 16:53:25 -07004796status_t QualcommCameraHardware::setRecordSize(const CameraParameters& params)
4797{
4798 int width, height;
4799 const char *str = params.get("record-size");
4800 if(str) {
4801 LOGV("Requested Record size %s", str);
4802 mParameters.set("record-size" , str);
4803 } else {
4804 //set the record-size value to null.
4805 //This is required as the application can request
4806 //to reset this value, so that it won't be carried
4807 //when switched to camera.
4808 mParameters.set("record-size", "");
4809 }
4810 return NO_ERROR;
4811}
4812
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004813
4814status_t QualcommCameraHardware::setPreviewSize(const CameraParameters& params)
4815{
4816 int width, height;
4817 params.getPreviewSize(&width, &height);
4818 LOGV("requested preview size %d x %d", width, height);
4819
4820 // Validate the preview size
Srinivasan Kannan9c14ead2010-02-22 17:15:58 -08004821 for (size_t i = 0; i < previewSizeCount; ++i) {
4822 if (width == supportedPreviewSizes[i].width
4823 && height == supportedPreviewSizes[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004824 mParameters.setPreviewSize(width, height);
Mohan Kandra091d5ab2010-07-14 16:53:25 -07004825 mDimension.display_width = width;
4826 mDimension.display_height= height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004827 return NO_ERROR;
4828 }
4829 }
4830 LOGE("Invalid preview size requested: %dx%d", width, height);
4831 return BAD_VALUE;
4832}
4833
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004834status_t QualcommCameraHardware::setPreviewFrameRate(const CameraParameters& params)
4835{
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07004836 //Temporary check for mipi sensor
4837 if((!strcmp(mSensorInfo.name, "vx6953")) ||
Srinivasan Kannan2c99dba2010-07-28 13:50:53 -07004838 (!strcmp(mSensorInfo.name, "VX6953")) ||
4839 (!strcmp(sensorType->name, "2mp"))){
4840 LOGI("set fps is not supported for this sensor");
4841 return NO_ERROR;
Srinivasan Kannanf01d8592010-07-25 13:47:08 -07004842 }
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004843 uint16_t previousFps = (uint16_t)mParameters.getPreviewFrameRate();
4844 uint16_t fps = (uint16_t)params.getPreviewFrameRate();
4845 LOGV("requested preview frame rate is %u", fps);
4846
4847 if(mInitialized && (fps == previousFps)){
4848 LOGV("fps same as previous fps");
4849 return NO_ERROR;
4850 }
4851
4852 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
4853 mParameters.setPreviewFrameRate(fps);
4854 bool ret = native_set_parm(CAMERA_SET_PARM_FPS,
4855 sizeof(fps), (void *)&fps);
4856 return ret ? NO_ERROR : UNKNOWN_ERROR;
4857 }
4858 return BAD_VALUE;
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004859}
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004860
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004861status_t QualcommCameraHardware::setPreviewFrameRateMode(const CameraParameters& params) {
4862 //Temporary check for mipi sensor
4863 if((!strcmp(mSensorInfo.name, "vx6953")) ||
Srinivasan Kannan2c99dba2010-07-28 13:50:53 -07004864 (!strcmp(mSensorInfo.name, "VX6953")) ||
4865 (!strcmp(sensorType->name, "2mp"))){
Mohan Kandrabf6146d2010-07-20 18:48:37 -07004866 LOGI("set fps mode is not supported for this sensor");
4867 return NO_ERROR;
4868 }
4869 const char *previousMode = mParameters.getPreviewFrameRateMode();
4870 const char *str = params.getPreviewFrameRateMode();
4871 if( mInitialized && !strcmp(previousMode, str)) {
4872 LOGV("frame rate mode same as previous mode %s", previousMode);
4873 return NO_ERROR;
4874 }
4875 int32_t frameRateMode = attr_lookup(frame_rate_modes, sizeof(frame_rate_modes) / sizeof(str_map),str);
4876 if(frameRateMode != NOT_FOUND) {
4877 LOGV("setPreviewFrameRateMode: %s ", str);
4878 mParameters.setPreviewFrameRateMode(str);
4879 bool ret = native_set_parm(CAMERA_SET_FPS_MODE, sizeof(frameRateMode), (void *)&frameRateMode);
4880 if(!ret) return ret;
4881 //set the fps value when chaging modes
4882 int16_t fps = (uint16_t)params.getPreviewFrameRate();
4883 if(MINIMUM_FPS <= fps && fps <=MAXIMUM_FPS){
4884 mParameters.setPreviewFrameRate(fps);
4885 ret = native_set_parm(CAMERA_SET_PARM_FPS,
4886 sizeof(fps), (void *)&fps);
4887 return ret ? NO_ERROR : UNKNOWN_ERROR;
4888 }
4889 LOGI("Invalid preview frame rate value: %d", fps);
4890 return BAD_VALUE;
4891 }
4892 LOGI("Invalid preview frame rate mode value: %s", (str == NULL) ? "NULL" : str);
4893 return BAD_VALUE;
Srinivasan Kannana01751b2010-06-24 18:44:40 -07004894}
4895
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004896status_t QualcommCameraHardware::setPictureSize(const CameraParameters& params)
4897{
4898 int width, height;
4899 params.getPictureSize(&width, &height);
4900 LOGV("requested picture size %d x %d", width, height);
4901
4902 // Validate the picture size
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08004903 for (int i = 0; i < supportedPictureSizesCount; ++i) {
4904 if (width == picture_sizes_ptr[i].width
4905 && height == picture_sizes_ptr[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004906 mParameters.setPictureSize(width, height);
4907 mDimension.picture_width = width;
4908 mDimension.picture_height = height;
4909 return NO_ERROR;
4910 }
4911 }
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08004912 /* Dimension not among the ones in the list. Check if
4913 * its a valid dimension, if it is, then configure the
4914 * camera accordingly. else reject it.
4915 */
4916 if( isValidDimension(width, height) ) {
4917 mParameters.setPictureSize(width, height);
4918 mDimension.picture_width = width;
4919 mDimension.picture_height = height;
4920 return NO_ERROR;
4921 } else
4922 LOGE("Invalid picture size requested: %dx%d", width, height);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004923 return BAD_VALUE;
4924}
4925
4926status_t QualcommCameraHardware::setJpegQuality(const CameraParameters& params) {
4927 status_t rc = NO_ERROR;
4928 int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
4929 if (quality > 0 && quality <= 100) {
4930 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
4931 } else {
4932 LOGE("Invalid jpeg quality=%d", quality);
4933 rc = BAD_VALUE;
4934 }
4935
4936 quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
4937 if (quality > 0 && quality <= 100) {
4938 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
4939 } else {
4940 LOGE("Invalid jpeg thumbnail quality=%d", quality);
4941 rc = BAD_VALUE;
4942 }
4943 return rc;
4944}
4945
4946status_t QualcommCameraHardware::setEffect(const CameraParameters& params)
4947{
Apurva Rajguru7360db42010-04-09 16:37:36 -07004948
4949 const char *str_wb = mParameters.get(CameraParameters::KEY_WHITE_BALANCE);
4950 int32_t value_wb = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str_wb);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004951 const char *str = params.get(CameraParameters::KEY_EFFECT);
Apurva Rajguru7360db42010-04-09 16:37:36 -07004952
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004953 if (str != NULL) {
4954 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
4955 if (value != NOT_FOUND) {
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08004956 if(!strcmp(sensorType->name, "2mp") && (value != CAMERA_EFFECT_OFF)
4957 &&(value != CAMERA_EFFECT_MONO) && (value != CAMERA_EFFECT_NEGATIVE)
4958 &&(value != CAMERA_EFFECT_SOLARIZE) && (value != CAMERA_EFFECT_SEPIA)) {
4959 LOGE("Special effect parameter is not supported for this sensor");
4960 return NO_ERROR;
4961 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07004962
4963 if(((value == CAMERA_EFFECT_MONO) || (value == CAMERA_EFFECT_NEGATIVE)
4964 || (value == CAMERA_EFFECT_AQUA) || (value == CAMERA_EFFECT_SEPIA))
4965 && (value_wb != CAMERA_WB_AUTO)) {
4966 LOGE("Color Effect value will not be set " \
4967 "when the whitebalance selected is %s", str_wb);
4968 return NO_ERROR;
4969 }
4970 else {
4971 mParameters.set(CameraParameters::KEY_EFFECT, str);
4972 bool ret = native_set_parm(CAMERA_SET_PARM_EFFECT, sizeof(value),
4973 (void *)&value);
4974 return ret ? NO_ERROR : UNKNOWN_ERROR;
4975 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08004976 }
4977 }
4978 LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
4979 return BAD_VALUE;
4980}
4981
Srinivasan Kannan4cc4b862010-06-30 14:22:26 -07004982status_t QualcommCameraHardware::setExposureCompensation(
4983 const CameraParameters & params){
4984
4985 if(!strcmp(sensorType->name, "2mp")) {
4986 LOGE("Exposure Compensation is not supported for this sensor");
4987 return NO_ERROR;
4988 }
4989
4990 int numerator = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
4991 if(EXPOSURE_COMPENSATION_MINIMUM_NUMERATOR <= numerator &&
4992 numerator <= EXPOSURE_COMPENSATION_MAXIMUM_NUMERATOR){
4993 int16_t numerator16 = (int16_t)(numerator & 0x0000ffff);
4994 uint16_t denominator16 = EXPOSURE_COMPENSATION_DENOMINATOR;
4995 uint32_t value = 0;
4996 value = numerator16 << 16 | denominator16;
4997
4998 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
4999 numerator);
5000 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE_COMPENSATION,
5001 sizeof(value), (void *)&value);
5002 return ret ? NO_ERROR : UNKNOWN_ERROR;
5003 }
5004 return BAD_VALUE;
5005}
5006
Apurva Rajguru55562b02009-12-03 12:25:35 -08005007status_t QualcommCameraHardware::setAutoExposure(const CameraParameters& params)
5008{
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005009 if(!strcmp(sensorType->name, "2mp")) {
5010 LOGE("Auto Exposure not supported for this sensor");
5011 return NO_ERROR;
5012 }
Apurva Rajguru55562b02009-12-03 12:25:35 -08005013 const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
5014 if (str != NULL) {
5015 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
5016 if (value != NOT_FOUND) {
5017 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
5018 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE, sizeof(value),
5019 (void *)&value);
5020 return ret ? NO_ERROR : UNKNOWN_ERROR;
5021 }
5022 }
5023 LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
5024 return BAD_VALUE;
5025}
5026
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005027status_t QualcommCameraHardware::setSharpness(const CameraParameters& params)
5028{
5029 if(!strcmp(sensorType->name, "2mp")) {
5030 LOGE("Sharpness not supported for this sensor");
5031 return NO_ERROR;
5032 }
5033 int sharpness = params.getInt(CameraParameters::KEY_SHARPNESS);
5034 if((sharpness < CAMERA_MIN_SHARPNESS
5035 || sharpness > CAMERA_MAX_SHARPNESS))
5036 return UNKNOWN_ERROR;
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005037
5038 LOGV("setting sharpness %d", sharpness);
5039 mParameters.set(CameraParameters::KEY_SHARPNESS, sharpness);
5040 bool ret = native_set_parm(CAMERA_SET_PARM_SHARPNESS, sizeof(sharpness),
5041 (void *)&sharpness);
5042 return ret ? NO_ERROR : UNKNOWN_ERROR;
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005043}
5044
5045status_t QualcommCameraHardware::setContrast(const CameraParameters& params)
5046{
5047 if(!strcmp(sensorType->name, "2mp")) {
5048 LOGE("Contrast not supported for this sensor");
5049 return NO_ERROR;
5050 }
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005051
Apurva Rajguru08383852010-05-17 14:25:39 -07005052 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
5053 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
5054
5055 if(value == CAMERA_BESTSHOT_OFF) {
5056 int contrast = params.getInt(CameraParameters::KEY_CONTRAST);
5057 if((contrast < CAMERA_MIN_CONTRAST)
5058 || (contrast > CAMERA_MAX_CONTRAST))
5059 return UNKNOWN_ERROR;
5060
5061 LOGV("setting contrast %d", contrast);
5062 mParameters.set(CameraParameters::KEY_CONTRAST, contrast);
5063 bool ret = native_set_parm(CAMERA_SET_PARM_CONTRAST, sizeof(contrast),
5064 (void *)&contrast);
5065 return ret ? NO_ERROR : UNKNOWN_ERROR;
5066 } else {
5067 LOGE(" Contrast value will not be set " \
5068 "when the scenemode selected is %s", str);
5069 return NO_ERROR;
5070 }
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005071}
5072
5073status_t QualcommCameraHardware::setSaturation(const CameraParameters& params)
5074{
5075 if(!strcmp(sensorType->name, "2mp")) {
5076 LOGE("Saturation not supported for this sensor");
5077 return NO_ERROR;
5078 }
Srinivasan Kannan551fd262010-01-14 17:48:30 -08005079
Kiran Kumar H Nf87cf862010-01-27 14:34:34 -08005080 const char *str = params.get(CameraParameters::KEY_EFFECT);
5081 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
5082
5083 if( (value != CAMERA_EFFECT_MONO) && (value != CAMERA_EFFECT_NEGATIVE)
5084 && (value != CAMERA_EFFECT_AQUA) && (value != CAMERA_EFFECT_SEPIA)) {
5085
5086 int saturation = params.getInt(CameraParameters::KEY_SATURATION);
5087 if((saturation < CAMERA_MIN_SATURATION)
5088 || (saturation > CAMERA_MAX_SATURATION))
5089 return UNKNOWN_ERROR;
5090
Apurva Rajguru08383852010-05-17 14:25:39 -07005091 LOGV("Setting saturation %d", saturation);
Kiran Kumar H Nf87cf862010-01-27 14:34:34 -08005092 mParameters.set(CameraParameters::KEY_SATURATION, saturation);
5093 bool ret = native_set_parm(CAMERA_SET_PARM_SATURATION, sizeof(saturation),
5094 (void *)&saturation);
5095 return ret ? NO_ERROR : UNKNOWN_ERROR;
5096 } else {
5097 LOGE(" Saturation value will not be set " \
5098 "when the effect selected is %s", str);
5099 return NO_ERROR;
5100 }
Srinivasan Kannanbddfd502010-01-03 17:27:36 -08005101}
5102
Mohan Kandra7110c242010-07-18 15:34:48 -07005103status_t QualcommCameraHardware::setPreviewFormat(const CameraParameters& params) {
5104 const char *str = params.getPreviewFormat();
5105 int32_t previewFormat = attr_lookup(preview_formats, sizeof(preview_formats) / sizeof(str_map), str);
5106 if(previewFormat != NOT_FOUND) {
5107 mParameters.set(CameraParameters::KEY_PREVIEW_FORMAT, str);
5108 mPreviewFormat = previewFormat;
5109 return NO_ERROR;
5110 }
5111 LOGI("Invalid preview format value: %s", (str == NULL) ? "NULL" : str);
5112 return BAD_VALUE;
5113}
5114
5115status_t QualcommCameraHardware::setStrTextures(const CameraParameters& params) {
5116 const char *str = params.get("strtextures");
5117 if(str != NULL) {
5118 LOGI("strtextures = %s", str);
5119 mParameters.set("strtextures", str);
5120 if(mUseOverlay) {
5121 if(!strncmp(str, "on", 2) || !strncmp(str, "ON", 2)) {
5122 LOGI("Resetting mUseOverlay to false");
5123 mUseOverlay = false;
5124 }
5125 }
5126 }
5127 return NO_ERROR;
5128}
5129
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305130status_t QualcommCameraHardware::setBrightness(const CameraParameters& params) {
5131 int brightness = params.getInt("luma-adaptation");
5132 if (mBrightness != brightness) {
5133 LOGV(" new brightness value : %d ", brightness);
5134 mBrightness = brightness;
5135
5136 bool ret = native_set_parm(CAMERA_SET_PARM_BRIGHTNESS, sizeof(mBrightness),
5137 (void *)&mBrightness);
5138 return ret ? NO_ERROR : UNKNOWN_ERROR;
5139 } else {
5140 return NO_ERROR;
5141 }
5142}
5143
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005144status_t QualcommCameraHardware::setWhiteBalance(const CameraParameters& params)
5145{
Apurva Rajguru7360db42010-04-09 16:37:36 -07005146
5147 const char *str_effect = mParameters.get(CameraParameters::KEY_EFFECT);
5148 int32_t value_effect = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str_effect);
5149
5150 if( (value_effect != CAMERA_EFFECT_MONO) && (value_effect != CAMERA_EFFECT_NEGATIVE)
5151 && (value_effect != CAMERA_EFFECT_AQUA) && (value_effect != CAMERA_EFFECT_SEPIA)) {
5152 const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
5153
5154 if (str != NULL) {
5155 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
5156 if (value != NOT_FOUND) {
5157 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
5158 bool ret = native_set_parm(CAMERA_SET_PARM_WB, sizeof(value),
5159 (void *)&value);
5160 return ret ? NO_ERROR : UNKNOWN_ERROR;
5161 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005162 }
Apurva Rajguru7360db42010-04-09 16:37:36 -07005163 LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
5164 return BAD_VALUE;
5165 } else {
5166 LOGE("Whitebalance value will not be set " \
5167 "when the effect selected is %s", str_effect);
5168 return NO_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005169 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005170}
5171
5172status_t QualcommCameraHardware::setFlash(const CameraParameters& params)
5173{
5174 if (!mSensorInfo.flash_enabled) {
5175 LOGV("%s: flash not supported", __FUNCTION__);
5176 return NO_ERROR;
5177 }
5178
5179 const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
5180 if (str != NULL) {
5181 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
5182 if (value != NOT_FOUND) {
5183 mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
5184 bool ret = native_set_parm(CAMERA_SET_PARM_LED_MODE,
5185 sizeof(value), (void *)&value);
5186 return ret ? NO_ERROR : UNKNOWN_ERROR;
5187 }
5188 }
5189 LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
5190 return BAD_VALUE;
5191}
5192
5193status_t QualcommCameraHardware::setAntibanding(const CameraParameters& params)
5194{
Srinivasan Kannan2229d272010-01-05 14:58:28 -08005195 if(!strcmp(sensorType->name, "2mp")) {
5196 LOGE("Parameter AntiBanding is not supported for this sensor");
5197 return NO_ERROR;
5198 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005199 const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
5200 if (str != NULL) {
5201 int value = (camera_antibanding_type)attr_lookup(
5202 antibanding, sizeof(antibanding) / sizeof(str_map), str);
5203 if (value != NOT_FOUND) {
5204 camera_antibanding_type temp = (camera_antibanding_type) value;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005205 mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
Srinivasan Kannan2229d272010-01-05 14:58:28 -08005206 bool ret;
5207 if (temp == CAMERA_ANTIBANDING_AUTO) {
5208 ret = native_set_parm(CAMERA_ENABLE_AFD,
5209 0, NULL);
5210 } else {
5211 ret = native_set_parm(CAMERA_SET_PARM_ANTIBANDING,
5212 sizeof(camera_antibanding_type), (void *)&temp);
5213 }
5214 return ret ? NO_ERROR : UNKNOWN_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005215 }
5216 }
5217 LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
5218 return BAD_VALUE;
5219}
5220
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305221status_t QualcommCameraHardware::setLensshadeValue(const CameraParameters& params)
5222{
Mohan Kandrace6bf562010-04-26 13:00:19 -07005223 if( (!strcmp(sensorType->name, "2mp")) ||
5224 (!strcmp(mSensorInfo.name, "vx6953")) ||
5225 (!strcmp(mSensorInfo.name, "VX6953")) ) {
Mohan Kandra1307f312010-04-29 10:18:42 -07005226 LOGI("Parameter Rolloff is not supported for this sensor");
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08005227 return NO_ERROR;
5228 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305229 const char *str = params.get(CameraParameters::KEY_LENSSHADE);
5230 if (str != NULL) {
5231 int value = attr_lookup(lensshade,
5232 sizeof(lensshade) / sizeof(str_map), str);
5233 if (value != NOT_FOUND) {
5234 int8_t temp = (int8_t)value;
5235 mParameters.set(CameraParameters::KEY_LENSSHADE, str);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005236
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305237 native_set_parm(CAMERA_SET_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
5238 return NO_ERROR;
5239 }
5240 }
5241 LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
5242 return BAD_VALUE;
5243}
5244
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005245status_t QualcommCameraHardware::setContinuousAf(const CameraParameters& params)
5246{
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005247 if(sensorType->hasAutoFocusSupport){
5248 const char *str = params.get(CameraParameters::KEY_CONTINUOUS_AF);
5249 if (str != NULL) {
5250 int value = attr_lookup(continuous_af,
5251 sizeof(continuous_af) / sizeof(str_map), str);
5252 if (value != NOT_FOUND) {
5253 int8_t temp = (int8_t)value;
5254 mParameters.set(CameraParameters::KEY_CONTINUOUS_AF, str);
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005255
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005256 native_set_parm(CAMERA_SET_CAF, sizeof(int8_t), (void *)&temp);
5257 return NO_ERROR;
5258 }
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005259 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005260 LOGE("Invalid continuous Af value: %s", (str == NULL) ? "NULL" : str);
5261 return BAD_VALUE;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005262 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005263 return NO_ERROR;
Apurva Rajguru7b949c92010-05-26 15:46:57 -07005264}
5265
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005266status_t QualcommCameraHardware::setTouchAfAec(const CameraParameters& params)
5267{
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005268 if(sensorType->hasAutoFocusSupport){
5269 int xAec, yAec, xAf, yAf;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005270
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005271 params.getTouchIndexAec(&xAec, &yAec);
5272 params.getTouchIndexAf(&xAf, &yAf);
5273 const char *str = params.get(CameraParameters::KEY_TOUCH_AF_AEC);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005274
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005275 if (str != NULL) {
5276 int value = attr_lookup(touchafaec,
5277 sizeof(touchafaec) / sizeof(str_map), str);
5278 if (value != NOT_FOUND) {
5279 mParameters.set(CameraParameters::KEY_TOUCH_AF_AEC, str);
5280 mParameters.setTouchIndexAec(xAec, yAec);
5281 mParameters.setTouchIndexAf(xAf, yAf);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005282
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005283 cam_set_aec_roi_t aec_roi_value;
5284 roi_info_t af_roi_value;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005285
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005286 memset(&af_roi_value, 0, sizeof(roi_info_t));
5287
5288 //If touch AF/AEC is enabled and touch event has occured then
5289 //call the ioctl with valid values.
5290
5291 if (value == true
5292 && (xAec >= 0 && yAec >= 0)
5293 && (xAf >= 0 && yAf >= 0)) {
5294 //Set Touch AEC params
5295 aec_roi_value.aec_roi_enable = AEC_ROI_ON;
5296 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
5297 aec_roi_value.aec_roi_position.coordinate.x = xAec;
5298 aec_roi_value.aec_roi_position.coordinate.y = yAec;
5299
5300 //Set Touch AF params
5301 af_roi_value.num_roi = 1;
5302 af_roi_value.roi[0].x = xAf;
5303 af_roi_value.roi[0].y = yAf;
5304 af_roi_value.roi[0].dx = 100;
5305 af_roi_value.roi[0].dy = 100;
5306 }
5307 else {
5308 //Set Touch AEC params
5309 aec_roi_value.aec_roi_enable = AEC_ROI_OFF;
5310 aec_roi_value.aec_roi_type = AEC_ROI_BY_COORDINATE;
5311 aec_roi_value.aec_roi_position.coordinate.x = DONT_CARE_COORDINATE;
5312 aec_roi_value.aec_roi_position.coordinate.y = DONT_CARE_COORDINATE;
5313
5314 //Set Touch AF params
5315 af_roi_value.num_roi = 0;
5316 }
5317 native_set_parm(CAMERA_SET_PARM_AEC_ROI, sizeof(cam_set_aec_roi_t), (void *)&aec_roi_value);
5318 native_set_parm(CAMERA_SET_PARM_AF_ROI, sizeof(roi_info_t), (void*)&af_roi_value);
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005319 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005320 return NO_ERROR;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005321 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005322 LOGE("Invalid Touch AF/AEC value: %s", (str == NULL) ? "NULL" : str);
5323 return BAD_VALUE;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005324 }
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005325 return NO_ERROR;
Apurva Rajguru0a2cb922010-06-08 15:33:22 -07005326}
5327
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305328status_t QualcommCameraHardware::setISOValue(const CameraParameters& params) {
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005329 int8_t temp_hjr;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305330 const char *str = params.get(CameraParameters::KEY_ISO_MODE);
5331 if (str != NULL) {
5332 int value = (camera_iso_mode_type)attr_lookup(
5333 iso, sizeof(iso) / sizeof(str_map), str);
5334 if (value != NOT_FOUND) {
5335 camera_iso_mode_type temp = (camera_iso_mode_type) value;
Apurva Rajguruf12d9d22010-04-05 16:47:12 -07005336 if (value == CAMERA_ISO_DEBLUR) {
5337 temp_hjr = true;
5338 native_set_parm(CAMERA_SET_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
5339 mHJR = value;
5340 }
5341 else {
5342 if (mHJR == CAMERA_ISO_DEBLUR) {
5343 temp_hjr = false;
5344 native_set_parm(CAMERA_SET_PARM_HJR, sizeof(int8_t), (void*)&temp_hjr);
5345 mHJR = value;
5346 }
5347 }
5348
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305349 mParameters.set(CameraParameters::KEY_ISO_MODE, str);
5350 native_set_parm(CAMERA_SET_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
5351 return NO_ERROR;
5352 }
5353 }
5354 LOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
5355 return BAD_VALUE;
5356}
5357
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005358status_t QualcommCameraHardware::setSceneDetect(const CameraParameters& params)
5359{
5360
5361 bool retParm1, retParm2;
5362 if (supportsSceneDetection()) {
Apurva Rajguru0d400562010-09-13 14:12:02 -07005363 if(!strcmp(sensorType->name, "2mp")) {
5364 LOGI("Parameter Auto Scene Detection is not supported for this sensor");
5365 return NO_ERROR;
5366 }
Apurva Rajguru8e0a8da2010-06-02 11:26:36 -07005367 const char *str = params.get(CameraParameters::KEY_SCENE_DETECT);
5368 if (str != NULL) {
5369 int32_t value = attr_lookup(scenedetect, sizeof(scenedetect) / sizeof(str_map), str);
5370 if (value != NOT_FOUND) {
5371 mParameters.set(CameraParameters::KEY_SCENE_DETECT, str);
5372
5373 retParm1 = native_set_parm(CAMERA_SET_PARM_BL_DETECTION_ENABLE, sizeof(value),
5374 (void *)&value);
5375
5376 retParm2 = native_set_parm(CAMERA_SET_PARM_SNOW_DETECTION_ENABLE, sizeof(value),
5377 (void *)&value);
5378
5379 //All Auto Scene detection modes should be all ON or all OFF.
5380 if(retParm1 == false || retParm2 == false) {
5381 value = !value;
5382 retParm1 = native_set_parm(CAMERA_SET_PARM_BL_DETECTION_ENABLE, sizeof(value),
5383 (void *)&value);
5384
5385 retParm2 = native_set_parm(CAMERA_SET_PARM_SNOW_DETECTION_ENABLE, sizeof(value),
5386 (void *)&value);
5387 }
5388 return (retParm1 && retParm2) ? NO_ERROR : UNKNOWN_ERROR;
5389 }
5390 }
5391 LOGE("Invalid auto scene detection value: %s", (str == NULL) ? "NULL" : str);
5392 return BAD_VALUE;
5393 }
5394 return NO_ERROR;
5395}
Nishant Panditc8c1ee72009-12-03 16:24:02 +05305396
Apurva Rajguru08383852010-05-17 14:25:39 -07005397status_t QualcommCameraHardware::setSceneMode(const CameraParameters& params)
5398{
Apurva Rajguruf0593dd2010-07-27 17:50:23 -07005399
5400 if(!strcmp(sensorType->name, "2mp")) {
5401 LOGI("Parameter Scenemode is not supported for this sensor");
5402 return NO_ERROR;
5403 }
5404
Apurva Rajguru08383852010-05-17 14:25:39 -07005405 const char *str = params.get(CameraParameters::KEY_SCENE_MODE);
5406
5407 if (str != NULL) {
5408 int32_t value = attr_lookup(scenemode, sizeof(scenemode) / sizeof(str_map), str);
5409 if (value != NOT_FOUND) {
5410 mParameters.set(CameraParameters::KEY_SCENE_MODE, str);
5411 bool ret = native_set_parm(CAMERA_SET_PARM_BESTSHOT_MODE, sizeof(value),
5412 (void *)&value);
5413 return ret ? NO_ERROR : UNKNOWN_ERROR;
5414 }
5415 }
5416 LOGE("Invalid scenemode value: %s", (str == NULL) ? "NULL" : str);
5417 return BAD_VALUE;
5418}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005419status_t QualcommCameraHardware::setGpsLocation(const CameraParameters& params)
5420{
5421 const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
5422 if (latitude) {
5423 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
5424 }
5425
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005426 const char *latitudeRef = params.get(CameraParameters::KEY_GPS_LATITUDE_REF);
5427 if (latitudeRef) {
5428 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
5429 }
5430
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005431 const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
5432 if (longitude) {
5433 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
5434 }
5435
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005436 const char *longitudeRef = params.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
5437 if (longitudeRef) {
5438 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
5439 }
5440
5441 const char *altitudeRef = params.get(CameraParameters::KEY_GPS_ALTITUDE_REF);
5442 if (altitudeRef) {
5443 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
5444 }
5445
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005446 const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
5447 if (altitude) {
5448 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
5449 }
5450
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08005451 const char *status = params.get(CameraParameters::KEY_GPS_STATUS);
5452 if (status) {
5453 mParameters.set(CameraParameters::KEY_GPS_STATUS, status);
5454 }
5455
5456 const char *dateTime = params.get(CameraParameters::KEY_EXIF_DATETIME);
5457 if (dateTime) {
5458 mParameters.set(CameraParameters::KEY_EXIF_DATETIME, dateTime);
5459 }
5460
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005461 const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
5462 if (timestamp) {
5463 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
5464 }
5465 return NO_ERROR;
5466}
5467
5468status_t QualcommCameraHardware::setRotation(const CameraParameters& params)
5469{
5470 status_t rc = NO_ERROR;
5471 int rotation = params.getInt(CameraParameters::KEY_ROTATION);
5472 if (rotation != NOT_FOUND) {
5473 if (rotation == 0 || rotation == 90 || rotation == 180
5474 || rotation == 270) {
5475 mParameters.set(CameraParameters::KEY_ROTATION, rotation);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005476 mRotation = rotation;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005477 } else {
5478 LOGE("Invalid rotation value: %d", rotation);
5479 rc = BAD_VALUE;
5480 }
5481 }
5482 return rc;
5483}
5484
5485status_t QualcommCameraHardware::setZoom(const CameraParameters& params)
5486{
5487 status_t rc = NO_ERROR;
5488 // No matter how many different zoom values the driver can provide, HAL
5489 // provides applictations the same number of zoom levels. The maximum driver
5490 // zoom value depends on sensor output (VFE input) and preview size (VFE
5491 // output) because VFE can only crop and cannot upscale. If the preview size
5492 // is bigger, the maximum zoom ratio is smaller. However, we want the
5493 // zoom ratio of each zoom level is always the same whatever the preview
5494 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
5495 // we need to have a fixed maximum zoom value and do read it from the
5496 // driver.
Mohan Kandra284966d2010-01-05 13:39:15 -08005497 static const int ZOOM_STEP = 1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005498 int32_t zoom_level = params.getInt("zoom");
5499
Mohan Kandra284966d2010-01-05 13:39:15 -08005500 LOGV("Set zoom=%d", zoom_level);
5501 if(zoom_level >= 0 && zoom_level <= mMaxZoom) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005502 mParameters.set("zoom", zoom_level);
5503 int32_t zoom_value = ZOOM_STEP * zoom_level;
5504 bool ret = native_set_parm(CAMERA_SET_PARM_ZOOM,
5505 sizeof(zoom_value), (void *)&zoom_value);
5506 rc = ret ? NO_ERROR : UNKNOWN_ERROR;
5507 } else {
5508 rc = BAD_VALUE;
5509 }
5510
5511 return rc;
5512}
5513
5514status_t QualcommCameraHardware::setFocusMode(const CameraParameters& params)
5515{
5516 const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
5517 if (str != NULL) {
5518 int32_t value = attr_lookup(focus_modes,
5519 sizeof(focus_modes) / sizeof(str_map), str);
5520 if (value != NOT_FOUND) {
5521 mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
5522 // Focus step is reset to infinity when preview is started. We do
5523 // not need to do anything now.
5524 return NO_ERROR;
5525 }
5526 }
5527 LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
5528 return BAD_VALUE;
5529}
5530
5531status_t QualcommCameraHardware::setOrientation(const CameraParameters& params)
5532{
5533 const char *str = params.get("orientation");
5534
5535 if (str != NULL) {
5536 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
5537 // Camera service needs this to decide if the preview frames and raw
5538 // pictures should be rotated.
5539 mParameters.set("orientation", str);
5540 } else {
5541 LOGE("Invalid orientation value: %s", str);
5542 return BAD_VALUE;
5543 }
5544 }
5545 return NO_ERROR;
5546}
5547
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08005548status_t QualcommCameraHardware::setPictureFormat(const CameraParameters& params)
5549{
5550 const char * str = params.get(CameraParameters::KEY_PICTURE_FORMAT);
5551
5552 if(str != NULL){
5553 int32_t value = attr_lookup(picture_formats,
5554 sizeof(picture_formats) / sizeof(str_map), str);
5555 if(value != NOT_FOUND){
5556 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT, str);
5557 } else {
5558 LOGE("Invalid Picture Format value: %s", str);
5559 return BAD_VALUE;
5560 }
5561 }
5562 return NO_ERROR;
5563}
5564
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005565QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
5566 int frame_size,
5567 const char *name) :
5568 mBufferSize(buffer_size),
5569 mNumBuffers(num_buffers),
5570 mFrameSize(frame_size),
5571 mBuffers(NULL), mName(name)
5572{
5573 int page_size_minus_1 = getpagesize() - 1;
5574 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
5575}
5576
5577void QualcommCameraHardware::MemPool::completeInitialization()
5578{
5579 // If we do not know how big the frame will be, we wait to allocate
5580 // the buffers describing the individual frames until we do know their
5581 // size.
5582
5583 if (mFrameSize > 0) {
5584 mBuffers = new sp<MemoryBase>[mNumBuffers];
5585 for (int i = 0; i < mNumBuffers; i++) {
5586 mBuffers[i] = new
5587 MemoryBase(mHeap,
5588 i * mAlignedBufferSize,
5589 mFrameSize);
5590 }
5591 }
5592}
5593
5594QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
5595 int frame_size,
5596 const char *name) :
5597 QualcommCameraHardware::MemPool(buffer_size,
5598 num_buffers,
5599 frame_size,
5600 name)
5601{
5602 LOGV("constructing MemPool %s backed by ashmem: "
5603 "%d frames @ %d uint8_ts, "
5604 "buffer size %d",
5605 mName,
5606 num_buffers, frame_size, buffer_size);
5607
5608 int page_mask = getpagesize() - 1;
5609 int ashmem_size = buffer_size * num_buffers;
5610 ashmem_size += page_mask;
5611 ashmem_size &= ~page_mask;
5612
5613 mHeap = new MemoryHeapBase(ashmem_size);
5614
5615 completeInitialization();
5616}
5617
5618static bool register_buf(int camfd,
5619 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08005620 int frame_size,
Mohan Kandra02486042010-06-18 16:49:43 -07005621 int cbcr_offset,
5622 int yoffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005623 int pmempreviewfd,
5624 uint32_t offset,
5625 uint8_t *buf,
5626 int pmem_type,
5627 bool vfe_can_write,
5628 bool register_buffer = true);
5629
5630QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
5631 int flags,
5632 int camera_control_fd,
5633 int pmem_type,
5634 int buffer_size, int num_buffers,
Mohan Kandra02486042010-06-18 16:49:43 -07005635 int frame_size, int cbcr_offset,
5636 int yOffset, const char *name) :
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005637 QualcommCameraHardware::MemPool(buffer_size,
5638 num_buffers,
5639 frame_size,
5640 name),
5641 mPmemType(pmem_type),
Mohan Kandra02486042010-06-18 16:49:43 -07005642 mCbCrOffset(cbcr_offset),
5643 myOffset(yOffset),
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005644 mCameraControlFd(dup(camera_control_fd))
5645{
5646 LOGV("constructing MemPool %s backed by pmem pool %s: "
5647 "%d frames @ %d bytes, buffer size %d",
5648 mName,
5649 pmem_pool, num_buffers, frame_size,
5650 buffer_size);
5651
5652 LOGV("%s: duplicating control fd %d --> %d",
5653 __FUNCTION__,
5654 camera_control_fd, mCameraControlFd);
5655
5656 // Make a new mmap'ed heap that can be shared across processes.
5657 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
5658 mAlignedSize = mAlignedBufferSize * num_buffers;
5659
5660 sp<MemoryHeapBase> masterHeap =
5661 new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
5662
5663 if (masterHeap->getHeapID() < 0) {
5664 LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
5665 masterHeap.clear();
5666 return;
5667 }
5668
5669 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
5670 if (pmemHeap->getHeapID() >= 0) {
5671 pmemHeap->slap();
5672 masterHeap.clear();
5673 mHeap = pmemHeap;
5674 pmemHeap.clear();
5675
5676 mFd = mHeap->getHeapID();
5677 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
5678 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
5679 pmem_pool,
5680 ::strerror(errno), errno);
5681 mHeap.clear();
5682 return;
5683 }
5684
5685 LOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
5686 pmem_pool,
5687 mFd,
5688 mSize.len);
Mohan Kandra284966d2010-01-05 13:39:15 -08005689 LOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005690 // Unregister preview buffers with the camera drivers. Allow the VFE to write
5691 // to all preview buffers except for the last one.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08005692 // Only Register the preview, snapshot and thumbnail buffers with the kernel.
Mohan Kandrad9efed92010-01-15 19:08:39 -08005693 if( (strcmp("postview", mName) != 0) ){
5694 int num_buf = num_buffers;
5695 if(!strcmp("preview", mName)) num_buf = kPreviewBufferCount;
Brian Steuerb62adbd2010-02-02 14:47:08 -08005696 LOGD("num_buffers = %d", num_buf);
Mohan Kandrad9efed92010-01-15 19:08:39 -08005697 for (int cnt = 0; cnt < num_buf; ++cnt) {
Sravankb4f5f1c2010-01-21 11:06:17 +05305698 int active = 1;
5699 if(pmem_type == MSM_PMEM_VIDEO){
5700 active = (cnt<ACTIVE_VIDEO_BUFFERS);
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005701 //When VPE is enabled, set the last record
5702 //buffer as active and pmem type as PMEM_VIDEO_VPE
5703 //as this is a requirement from VPE operation.
Mohan Kandra88db27a2010-08-22 12:33:36 -07005704 //No need to set this pmem type to VIDEO_VPE while unregistering,
5705 //because as per camera stack design: "the VPE AXI is also configured
5706 //when VFE is configured for VIDEO, which is as part of preview
5707 //initialization/start. So during this VPE AXI config camera stack
5708 //will lookup the PMEM_VIDEO_VPE buffer and give it as o/p of VPE and
5709 //change it's type to PMEM_VIDEO".
Mohan Kandra39fad8d2010-07-15 12:29:19 -07005710 if( (mVpeEnabled) && (cnt == kRecordBufferCount-1)) {
5711 active = 1;
5712 pmem_type = MSM_PMEM_VIDEO_VPE;
5713 }
Sravankb4f5f1c2010-01-21 11:06:17 +05305714 LOGV(" pmempool creating video buffers : active %d ", active);
5715 }
5716 else if (pmem_type == MSM_PMEM_PREVIEW){
5717 active = (cnt < (num_buf-1));
5718 }
Mohan Kandra284966d2010-01-05 13:39:15 -08005719 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005720 mBufferSize,
Mohan Kandra02486042010-06-18 16:49:43 -07005721 mFrameSize, mCbCrOffset, myOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005722 mHeap->getHeapID(),
5723 mAlignedBufferSize * cnt,
5724 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
5725 pmem_type,
Sravankb4f5f1c2010-01-21 11:06:17 +05305726 active);
Mohan Kandra284966d2010-01-05 13:39:15 -08005727 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005728 }
5729
5730 completeInitialization();
5731 }
5732 else LOGE("pmem pool %s error: could not create master heap!",
5733 pmem_pool);
5734}
5735
5736QualcommCameraHardware::PmemPool::~PmemPool()
5737{
5738 LOGV("%s: %s E", __FUNCTION__, mName);
5739 if (mHeap != NULL) {
5740 // Unregister preview buffers with the camera drivers.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08005741 // Only Unregister the preview, snapshot and thumbnail
5742 // buffers with the kernel.
Mohan Kandrad9efed92010-01-15 19:08:39 -08005743 if( (strcmp("postview", mName) != 0) ){
5744 int num_buffers = mNumBuffers;
5745 if(!strcmp("preview", mName)) num_buffers = kPreviewBufferCount;
5746 for (int cnt = 0; cnt < num_buffers; ++cnt) {
Mohan Kandra284966d2010-01-05 13:39:15 -08005747 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005748 mBufferSize,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08005749 mFrameSize,
Mohan Kandra02486042010-06-18 16:49:43 -07005750 mCbCrOffset,
5751 myOffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005752 mHeap->getHeapID(),
5753 mAlignedBufferSize * cnt,
5754 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
5755 mPmemType,
5756 false,
5757 false /* unregister */);
Mohan Kandra284966d2010-01-05 13:39:15 -08005758 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005759 }
5760 }
5761 LOGV("destroying PmemPool %s: closing control fd %d",
5762 mName,
5763 mCameraControlFd);
5764 close(mCameraControlFd);
5765 LOGV("%s: %s X", __FUNCTION__, mName);
5766}
5767
5768QualcommCameraHardware::MemPool::~MemPool()
5769{
5770 LOGV("destroying MemPool %s", mName);
5771 if (mFrameSize > 0)
5772 delete [] mBuffers;
5773 mHeap.clear();
5774 LOGV("destroying MemPool %s completed", mName);
5775}
5776
5777static bool register_buf(int camfd,
5778 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08005779 int frame_size,
Mohan Kandra02486042010-06-18 16:49:43 -07005780 int cbcr_offset,
5781 int yoffset,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005782 int pmempreviewfd,
5783 uint32_t offset,
5784 uint8_t *buf,
5785 int pmem_type,
5786 bool vfe_can_write,
5787 bool register_buffer)
5788{
5789 struct msm_pmem_info pmemBuf;
5790
5791 pmemBuf.type = pmem_type;
5792 pmemBuf.fd = pmempreviewfd;
5793 pmemBuf.offset = offset;
5794 pmemBuf.len = size;
5795 pmemBuf.vaddr = buf;
Mohan Kandra02486042010-06-18 16:49:43 -07005796 pmemBuf.y_off = yoffset;
5797 pmemBuf.cbcr_off = cbcr_offset;
Srinivasan Kannanb36a4fe2010-01-29 19:34:09 -08005798
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005799 pmemBuf.active = vfe_can_write;
5800
5801 LOGV("register_buf: camfd = %d, reg = %d buffer = %p",
5802 camfd, !register_buffer, buf);
5803 if (ioctl(camfd,
5804 register_buffer ?
5805 MSM_CAM_IOCTL_REGISTER_PMEM :
5806 MSM_CAM_IOCTL_UNREGISTER_PMEM,
5807 &pmemBuf) < 0) {
5808 LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM fd %d error %s",
5809 camfd,
5810 strerror(errno));
5811 return false;
5812 }
5813 return true;
5814}
5815
5816status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
5817{
5818 const size_t SIZE = 256;
5819 char buffer[SIZE];
5820 String8 result;
5821 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
5822 result.append(buffer);
5823 if (mName) {
5824 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
5825 result.append(buffer);
5826 }
5827 if (mHeap != 0) {
5828 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
5829 mHeap->getBase(), mHeap->getSize(),
5830 mHeap->getFlags(), mHeap->getDevice());
5831 result.append(buffer);
5832 }
5833 snprintf(buffer, 255,
5834 "buffer size (%d), number of buffers (%d), frame size(%d)",
5835 mBufferSize, mNumBuffers, mFrameSize);
5836 result.append(buffer);
5837 write(fd, result.string(), result.size());
5838 return NO_ERROR;
5839}
5840
5841static void receive_camframe_callback(struct msm_frame *frame)
5842{
5843 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5844 if (obj != 0) {
5845 obj->receivePreviewFrame(frame);
5846 }
5847}
5848
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05305849static void receive_liveshot_callback(liveshot_status status, uint32_t jpeg_size)
5850{
5851 if(status == LIVESHOT_SUCCESS) {
5852 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5853 if (obj != 0) {
5854 obj->receiveLiveSnapshot(jpeg_size);
5855 }
5856 }
5857 else
5858 LOGE("Liveshot not succesful");
5859}
5860
5861
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005862static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size)
5863{
5864 LOGV("receive_jpeg_fragment_callback E");
5865 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5866 if (obj != 0) {
5867 obj->receiveJpegPictureFragment(buff_ptr, buff_size);
5868 }
5869 LOGV("receive_jpeg_fragment_callback X");
5870}
5871
5872static void receive_jpeg_callback(jpeg_event_t status)
5873{
5874 LOGV("receive_jpeg_callback E (completion status %d)", status);
5875 if (status == JPEG_EVENT_DONE) {
5876 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5877 if (obj != 0) {
5878 obj->receiveJpegPicture();
5879 }
5880 }
5881 LOGV("receive_jpeg_callback X");
5882}
Sravankb4f5f1c2010-01-21 11:06:17 +05305883// 720p : video frame calbback from camframe
5884static void receive_camframe_video_callback(struct msm_frame *frame)
5885{
5886 LOGV("receive_camframe_video_callback E");
5887 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5888 if (obj != 0) {
5889 obj->receiveRecordingFrame(frame);
5890 }
5891 LOGV("receive_camframe_video_callback X");
5892}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08005893
5894void QualcommCameraHardware::setCallbacks(notify_callback notify_cb,
5895 data_callback data_cb,
5896 data_callback_timestamp data_cb_timestamp,
5897 void* user)
5898{
5899 Mutex::Autolock lock(mLock);
5900 mNotifyCallback = notify_cb;
5901 mDataCallback = data_cb;
5902 mDataCallbackTimestamp = data_cb_timestamp;
5903 mCallbackCookie = user;
5904}
5905
5906void QualcommCameraHardware::enableMsgType(int32_t msgType)
5907{
5908 Mutex::Autolock lock(mLock);
5909 mMsgEnabled |= msgType;
5910}
5911
5912void QualcommCameraHardware::disableMsgType(int32_t msgType)
5913{
5914 Mutex::Autolock lock(mLock);
5915 mMsgEnabled &= ~msgType;
5916}
5917
5918bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
5919{
5920 return (mMsgEnabled & msgType);
5921}
5922
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08005923bool QualcommCameraHardware::useOverlay(void)
5924{
Nishant Pandit3c278cd2010-07-13 15:56:04 +05305925 if((mCurrentTarget == TARGET_MSM7630) || (mCurrentTarget == TARGET_MSM8660)) {
5926 /* 7x30 and 8x60 supports Overlay */
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08005927 mUseOverlay = TRUE;
5928 } else
5929 mUseOverlay = FALSE;
5930
5931 LOGV(" Using Overlay : %s ", mUseOverlay ? "YES" : "NO" );
5932 return mUseOverlay;
5933}
5934
5935status_t QualcommCameraHardware::setOverlay(const sp<Overlay> &Overlay)
5936{
5937 if( Overlay != NULL) {
5938 LOGV(" Valid overlay object ");
5939 mOverlayLock.lock();
5940 mOverlay = Overlay;
5941 mOverlayLock.unlock();
5942 } else {
Apurva Rajguruc73c1722010-04-15 17:39:11 -07005943 LOGV(" Overlay object NULL. returning ");
Mohan Kandrad9efed92010-01-15 19:08:39 -08005944 mOverlay = NULL;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08005945 return UNKNOWN_ERROR;
5946 }
5947 return NO_ERROR;
5948}
Kiran Kumar H N215cac42009-12-08 01:53:46 -08005949
5950void QualcommCameraHardware::receive_camframetimeout(void) {
5951 LOGV("receive_camframetimeout: E");
5952 Mutex::Autolock l(&mCamframeTimeoutLock);
Mohan Kandra1307f312010-04-29 10:18:42 -07005953 LOGE(" Camframe timed out. Not receiving any frames from camera driver ");
Kiran Kumar H N215cac42009-12-08 01:53:46 -08005954 camframe_timeout_flag = TRUE;
Priyanka Kharatae03c212010-05-19 15:32:50 -07005955 mNotifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_UKNOWN, 0,
5956 mCallbackCookie);
Kiran Kumar H N215cac42009-12-08 01:53:46 -08005957 LOGV("receive_camframetimeout: X");
5958}
5959
5960static void receive_camframetimeout_callback(void) {
5961 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
5962 if (obj != 0) {
5963 obj->receive_camframetimeout();
5964 }
5965}
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08005966
5967void QualcommCameraHardware::storePreviewFrameForPostview(void) {
5968 LOGV(" storePreviewFrameForPostview : E ");
5969
5970 /* Since there is restriction on the maximum overlay dimensions
5971 * that can be created, we use the last preview frame as postview
5972 * for 7x30. */
5973 LOGV(" Copying the preview buffer to postview buffer %d ",
5974 mPreviewFrameSize);
5975 if( mPostViewHeap != NULL && mLastQueuedFrame != NULL) {
5976 memcpy(mPostViewHeap->mHeap->base(),
5977 (uint8_t *)mLastQueuedFrame, mPreviewFrameSize );
5978 } else
5979 LOGE(" Failed to store Preview frame. No Postview ");
5980
5981 LOGV(" storePreviewFrameForPostview : X ");
5982}
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08005983
5984bool QualcommCameraHardware::isValidDimension(int width, int height) {
5985 bool retVal = FALSE;
5986 /* This function checks if a given resolution is valid or not.
5987 * A particular resolution is considered valid if it satisfies
5988 * the following conditions:
5989 * 1. width & height should be multiple of 16.
5990 * 2. width & height should be less than/equal to the dimensions
5991 * supported by the camera sensor.
5992 * 3. the aspect ratio is a valid aspect ratio and is among the
5993 * commonly used aspect ratio as determined by the thumbnail_sizes
5994 * data structure.
5995 */
5996
5997 if( (width == CEILING16(width)) && (height == CEILING16(height))
5998 && (width <= sensorType->max_supported_snapshot_width)
5999 && (height <= sensorType->max_supported_snapshot_height) )
6000 {
6001 uint32_t pictureAspectRatio = (uint32_t)((width * Q12)/height);
Mohan Kandra62429cc2010-07-19 10:21:05 -07006002 for(uint32_t i = 0; i < THUMBNAIL_SIZE_COUNT; i++ ) {
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006003 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio) {
6004 retVal = TRUE;
6005 break;
6006 }
6007 }
6008 }
6009 return retVal;
6010}
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006011status_t QualcommCameraHardware::getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize) {
6012 status_t ret;
6013 LOGV(" getBufferInfo : E ");
Nishant Pandit3c278cd2010-07-13 15:56:04 +05306014 if( ( mCurrentTarget == TARGET_MSM7630 ) || (mCurrentTarget == TARGET_QSD8250) || (mCurrentTarget == TARGET_MSM8660) )
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306015 {
6016 if( mRecordHeap != NULL){
6017 LOGV(" Setting valid buffer information ");
6018 Frame = mRecordHeap->mBuffers[0];
6019 if( alignedSize != NULL) {
6020 *alignedSize = mRecordHeap->mAlignedBufferSize;
6021 LOGV(" HAL : alignedSize = %d ", *alignedSize);
6022 ret = NO_ERROR;
6023 } else {
6024 LOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
6025 ret = UNKNOWN_ERROR;
6026 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006027 } else {
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306028 LOGE(" RecordHeap is null. Buffer information wont be updated ");
6029 Frame = NULL;
6030 ret = UNKNOWN_ERROR;
6031 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006032 } else {
Vamshidhar Kondrab362be62010-03-22 19:07:29 +05306033 if(mPreviewHeap != NULL) {
6034 LOGV(" Setting valid buffer information ");
6035 Frame = mPreviewHeap->mBuffers[0];
6036 if( alignedSize != NULL) {
6037 *alignedSize = mPreviewHeap->mAlignedBufferSize;
6038 LOGV(" HAL : alignedSize = %d ", *alignedSize);
6039 ret = NO_ERROR;
6040 } else {
6041 LOGE(" HAL : alignedSize is NULL. Cannot update alignedSize ");
6042 ret = UNKNOWN_ERROR;
6043 }
6044 } else {
6045 LOGE(" PreviewHeap is null. Buffer information wont be updated ");
6046 Frame = NULL;
6047 ret = UNKNOWN_ERROR;
6048 }
Kiran Kumar H N4dd45a62010-02-26 15:56:33 -08006049 }
6050 LOGV(" getBufferInfo : X ");
6051 return ret;
6052}
Kiran Kumar H Nb49af212010-02-17 15:12:17 -08006053
Mohan Kandra1659b0c2010-07-18 16:36:25 -07006054void QualcommCameraHardware::encodeData() {
6055 LOGV("encodeData: E");
6056
6057 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
6058 mJpegSize = 0;
6059 mJpegThreadWaitLock.lock();
6060 if (LINK_jpeg_encoder_init()) {
6061 mJpegThreadRunning = true;
6062 mJpegThreadWaitLock.unlock();
6063 if(native_jpeg_encode()) {
6064 LOGV("encodeData: X (success)");
6065 //Wait until jpeg encoding is done and call jpeg join
6066 //in this context. Also clear the resources.
6067 mJpegThreadWaitLock.lock();
6068 while (mJpegThreadRunning) {
6069 LOGV("encodeData: waiting for jpeg thread to complete.");
6070 mJpegThreadWait.wait(mJpegThreadWaitLock);
6071 LOGV("encodeData: jpeg thread completed.");
6072 }
6073 mJpegThreadWaitLock.unlock();
6074 //Call jpeg join in this thread context
6075 LINK_jpeg_encoder_join();
6076 }
6077 LOGE("encodeData: jpeg encoding failed");
6078 }
6079 else {
6080 LOGE("encodeData X: jpeg_encoder_init failed.");
6081 mJpegThreadWaitLock.unlock();
6082 }
6083 }
6084 else LOGV("encodeData: JPEG callback is NULL, not encoding image.");
6085 //clear the resources
6086 deinitRaw();
6087 //Encoding is done.
6088 mEncodePendingWaitLock.lock();
6089 mEncodePending = false;
6090 mEncodePendingWait.signal();
6091 mEncodePendingWaitLock.unlock();
6092
6093 LOGV("encodeData: X");
6094}
6095
Priya Komarlingamb85535d2009-11-30 13:06:01 -08006096}; // namespace android
Vamshidhar Kondra92ce9142010-09-03 18:22:08 +05306097