blob: ca905d0ace5d2f8654afd2718f59e17ebe4f8a74 [file] [log] [blame]
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001/*
2** Copyright 2008, Google Inc.
Nishant Panditc8c1ee72009-12-03 16:24:02 +05303** Copyright (c) 2009, 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
19#define LOG_TAG "QualcommCameraHardware"
20#include <utils/Log.h>
21
22#include "QualcommCameraHardware.h"
23
24#include <utils/Errors.h>
25#include <utils/threads.h>
26#include <binder/MemoryHeapPmem.h>
27#include <utils/String16.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <unistd.h>
Apurva Rajguru8d1773b2009-12-02 14:21:23 -080031#include <cutils/properties.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080032#include <math.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080033#if HAVE_ANDROID_OS
34#include <linux/android_pmem.h>
35#endif
36#include <linux/ioctl.h>
37#include <ui/CameraParameters.h>
38
Mohan Kandra284966d2010-01-05 13:39:15 -080039#include "linux/msm_mdp.h"
40#include <linux/fb.h>
41
Priya Komarlingamb85535d2009-11-30 13:06:01 -080042#define LIKELY(exp) __builtin_expect(!!(exp), 1)
43#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
44
45extern "C" {
46#include <fcntl.h>
47#include <time.h>
48#include <pthread.h>
49#include <stdio.h>
50#include <string.h>
51#include <unistd.h>
52#include <termios.h>
53#include <assert.h>
54#include <stdlib.h>
55#include <ctype.h>
56#include <signal.h>
57#include <errno.h>
58#include <sys/mman.h>
59#include <sys/system_properties.h>
60#include <sys/time.h>
61#include <stdlib.h>
62
63#include <media/msm_camera.h>
64
65#include <camera.h>
66#include <camframe.h>
67#include <mm-still/jpeg/jpege.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080068#include <jpeg_encoder.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080069
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -080070#define DEFAULT_PICTURE_WIDTH 1024
71#define DEFAULT_PICTURE_HEIGHT 768
Priya Komarlingamb85535d2009-11-30 13:06:01 -080072#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
73#define MAX_ZOOM_LEVEL 5
74#define NOT_FOUND -1
75
76#if DLOPEN_LIBMMCAMERA
77#include <dlfcn.h>
78
79void* (*LINK_cam_conf)(void *data);
80void* (*LINK_cam_frame)(void *data);
81bool (*LINK_jpeg_encoder_init)();
82void (*LINK_jpeg_encoder_join)();
83bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
84 const uint8_t *thumbnailbuf, int thumbnailfd,
85 const uint8_t *snapshotbuf, int snapshotfd,
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080086 common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
87 int exif_table_numEntries);
Priya Komarlingamb85535d2009-11-30 13:06:01 -080088int (*LINK_camframe_terminate)(void);
89int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
90int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
91int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
92int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
93const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
94int (*LINK_launch_cam_conf_thread)(void);
95int (*LINK_release_cam_conf_thread)(void);
96int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
97 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
98
99// callbacks
100void (**LINK_mmcamera_camframe_callback)(struct msm_frame *frame);
101void (**LINK_mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
102 uint32_t buff_size);
103void (**LINK_mmcamera_jpeg_callback)(jpeg_event_t status);
104void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800105void (**LINK_camframe_timeout_callback)(void);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800106#else
107#define LINK_cam_conf cam_conf
108#define LINK_cam_frame cam_frame
109#define LINK_jpeg_encoder_init jpeg_encoder_init
110#define LINK_jpeg_encoder_join jpeg_encoder_join
111#define LINK_jpeg_encoder_encode jpeg_encoder_encode
112#define LINK_camframe_terminate camframe_terminate
113#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
114#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
115#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
116#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
117#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
118#define LINK_launch_cam_conf_thread launch_cam_conf_thread
119#define LINK_release_cam_conf_thread release_cam_conf_thread
120#define LINK_zoom_crop_upscale zoom_crop_upscale
121extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
122extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
123 uint32_t buff_size);
124extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
125extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
126#endif
127
128} // extern "C"
129
130#ifndef HAVE_CAMERA_SIZE_TYPE
131struct camera_size_type {
132 int width;
133 int height;
134};
135#endif
136
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800137typedef struct crop_info_struct {
138 uint32_t x;
139 uint32_t y;
140 uint32_t w;
141 uint32_t h;
142} zoom_crop_info;
143
Mohan Kandra284966d2010-01-05 13:39:15 -0800144static char mDeviceName[PROPERTY_VALUE_MAX];
145union
146{
147 char d[sizeof(struct mdp_blit_req_list) + sizeof(struct mdp_blit_req) * 1];
148 struct mdp_blit_req_list list;
149} zoomImage;
150
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800151//Default to WVGA
Srinivasan Kannanfa7edae2009-12-16 18:02:01 -0800152#define DEFAULT_PREVIEW_SETTING 1
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800153static const camera_size_type preview_sizes[] = {
Srinivasan Kannanfa7edae2009-12-16 18:02:01 -0800154 { 1280, 720 }, // 720P, reserved
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800155 { 800, 480 }, // WVGA
156 { 720, 480 },
157 { 640, 480 }, // VGA
158 { 576, 432 },
159 { 480, 320 }, // HVGA
160 { 384, 288 },
161 { 352, 288 }, // CIF
162 { 320, 240 }, // QVGA
163 { 240, 160 }, // SQVGA
164 { 176, 144 }, // QCIF
165};
166#define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(camera_size_type))
167
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800168//static const camera_size_type* picture_sizes;
169//static int PICTURE_SIZE_COUNT;
170/* TODO
171 * Ideally this should be a populated by lower layers.
172 * But currently this is no API to do that at lower layer.
173 * Hence populating with default sizes for now. This needs
174 * to be changed once the API is supported.
175 */
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800176//sorted on column basis
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800177static const camera_size_type picture_sizes[] = {
178 { 2592, 1944 }, // 5MP
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800179 { 2048, 1536 }, // 3MP QXGA
180 { 1920, 1080 }, //HD1080
181 { 1600, 1200 }, // 2MP UXGA
182 { 1280, 768 }, //WXGA
183 { 1280, 720 }, //HD720
184 { 1024, 768}, // 1MP XGA
185 { 800, 600 }, //SVGA
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800186 { 800, 480 }, // WVGA
187 { 640, 480 }, // VGA
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800188 { 352, 288 }, //CIF
189 { 320, 240 }, // QVGA
190 { 176, 144 } // QCIF
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800191};
192static int PICTURE_SIZE_COUNT = sizeof(picture_sizes)/sizeof(camera_size_type);
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800193static const camera_size_type * picture_sizes_ptr;
194static int supportedPictureSizesCount;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800195
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800196#ifdef Q12
197#undef Q12
198#endif
199
200#define Q12 4096
201
202typedef struct {
203 uint32_t aspect_ratio;
204 uint32_t width;
205 uint32_t height;
206} thumbnail_size_type;
207
208static thumbnail_size_type thumbnail_sizes[] = {
209 { 7281, 512, 288 }, //1.777778
210 { 6826, 480, 288 }, //1.666667
211 { 5461, 512, 384 }, //1.333333
212 { 5006, 352, 288 }, //1.222222
213};
214#define THUMBNAIL_SIZE_COUNT (sizeof(thumbnail_sizes)/sizeof(thumbnail_size_type))
215#define DEFAULT_THUMBNAIL_SETTING 2
216#define THUMBNAIL_WIDTH_STR "512"
217#define THUMBNAIL_HEIGHT_STR "384"
218#define THUMBNAIL_SMALL_HEIGHT 144
219
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800220static int attr_lookup(const str_map arr[], int len, const char *name)
221{
222 if (name) {
223 for (int i = 0; i < len; i++) {
224 if (!strcmp(arr[i].desc, name))
225 return arr[i].val;
226 }
227 }
228 return NOT_FOUND;
229}
230
231// round to the next power of two
232static inline unsigned clp2(unsigned x)
233{
234 x = x - 1;
235 x = x | (x >> 1);
236 x = x | (x >> 2);
237 x = x | (x >> 4);
238 x = x | (x >> 8);
239 x = x | (x >>16);
240 return x + 1;
241}
242
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800243static int exif_table_numEntries = 0;
244#define MAX_EXIF_TABLE_ENTRIES 7
245exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800246static zoom_crop_info zoomCropInfo;
247static void *mLastQueuedFrame = NULL;
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800248
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800249namespace android {
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800250
251static const int PICTURE_FORMAT_JPEG = 1;
252static const int PICTURE_FORMAT_RAW = 2;
253
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800254// from aeecamera.h
255static const str_map whitebalance[] = {
256 { CameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
257 { CameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
258 { CameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
259 { CameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
260 { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
261};
262
263// from camera_effect_t. This list must match aeecamera.h
264static const str_map effects[] = {
265 { CameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
266 { CameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
267 { CameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
268 { CameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
269 { CameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
270 { CameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
271 { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
272 { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
273 { CameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA }
274};
275
276// from qcamera/common/camera.h
Apurva Rajguru55562b02009-12-03 12:25:35 -0800277static const str_map autoexposure[] = {
278 { CameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
279 { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
280 { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
281};
282
283// from qcamera/common/camera.h
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800284static const str_map antibanding[] = {
285 { CameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
286 { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
287 { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
288 { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
289};
290
291/* Mapping from MCC to antibanding type */
292struct country_map {
293 uint32_t country_code;
294 camera_antibanding_type type;
295};
296
297static struct country_map country_numeric[] = {
298 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
299 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
300 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
301 { 208, CAMERA_ANTIBANDING_50HZ }, // France
302 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
303 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
304 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
305 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
306 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
307 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
308 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
309 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
310 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
311 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
312 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
313 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
314 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
315 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
316 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
317 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
318 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
319 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
320 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
321 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
322 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
323 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
324 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
325 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
326 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
327 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
328 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
329 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
330 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
331 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
332 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
333 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
334 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
335 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
336 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
337 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
338 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
339 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
340 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
341 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
342 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
343 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
344 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
345 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
346 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
347 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
348 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
349 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
350 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
351 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
352 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
353 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
354 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
355 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
356 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
357 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
358 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
359 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
360 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
361 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
362 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
363 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
364 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
365 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
366 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
367 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
368 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
369 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
370 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
371 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
372 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
373 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
374 { 404, CAMERA_ANTIBANDING_50HZ }, // India
375 { 405, CAMERA_ANTIBANDING_50HZ }, // India
376 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
377 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
378 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
379 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
380 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
381 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
382 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
383 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
384 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
385 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
386 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
387 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
388 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
389 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
390 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
391 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
392 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
393 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
394 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
395 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
396 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
397 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
398 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
399 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
400 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
401 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
402 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
403 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
404 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
405 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
406 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
407 { 460, CAMERA_ANTIBANDING_50HZ }, // China
408 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
409 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
410 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
411 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
412 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
413 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
414 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
415 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
416 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
417 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
418 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
419 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
420 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
421 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
422 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
423 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
424 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
425 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
426 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
427 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
428 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
429 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
430 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
431 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
432 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
433 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
434 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
435 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
436 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
437 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
438 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
439 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
440 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
441 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
442 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
443 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
444 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
445 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
446 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
447 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
448 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
449 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
450 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
451 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
452 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
453 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
454 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
455 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
456 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
457 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
458 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
459 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
460 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
461 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
462 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
463 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
464 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
465 { 647, CAMERA_ANTIBANDING_50HZ }, // France
466 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
467 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
468 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
469 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
470 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
471 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
472 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
473 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
474 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
475 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
476 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
477 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
478 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
479 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
480 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
481 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
482 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
483 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
484 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
485 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
486 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
487 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
488 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
489 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
490 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
491 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
492 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
493 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
494 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
495};
496
497#define country_number (sizeof(country_numeric) / sizeof(country_map))
498
499/* Look up pre-sorted antibanding_type table by current MCC. */
500static camera_antibanding_type camera_get_location(void) {
501 char value[PROP_VALUE_MAX];
502 char country_value[PROP_VALUE_MAX];
503 uint32_t country_code, count;
504 memset(value, 0x00, sizeof(value));
505 memset(country_value, 0x00, sizeof(country_value));
506 if (!__system_property_get("gsm.operator.numeric", value)) {
507 return CAMERA_ANTIBANDING_60HZ;
508 }
509 memcpy(country_value, value, 3);
510 country_code = atoi(country_value);
511 LOGD("value:%s, country value:%s, country code:%d\n",
512 value, country_value, country_code);
513 int left = 0;
514 int right = country_number - 1;
515 while (left <= right) {
516 int index = (left + right) >> 1;
517 if (country_numeric[index].country_code == country_code)
518 return country_numeric[index].type;
519 else if (country_numeric[index].country_code > country_code)
520 right = index - 1;
521 else
522 left = index + 1;
523 }
524 return CAMERA_ANTIBANDING_60HZ;
525}
526
527// from camera.h, led_mode_t
528static const str_map flash[] = {
529 { CameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
530 { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
531 { CameraParameters::FLASH_MODE_ON, LED_MODE_ON }
532};
533
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530534// from mm-camera/common/camera.h.
535static const str_map iso[] = {
536 { CameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
537 { CameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
538 { CameraParameters::ISO_100, CAMERA_ISO_100},
539 { CameraParameters::ISO_200, CAMERA_ISO_200},
540 { CameraParameters::ISO_400, CAMERA_ISO_400},
541 { CameraParameters::ISO_800, CAMERA_ISO_800 }
542};
543
544
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800545#define DONT_CARE 0
546static const str_map focus_modes[] = {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800547 { CameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
548 { CameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
549 { CameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL },
550 { CameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800551};
552
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530553static const str_map lensshade[] = {
554 { CameraParameters::LENSSHADE_ENABLE, TRUE },
555 { CameraParameters::LENSSHADE_DISABLE, FALSE }
556};
557
Srinivasan Kannan71229622009-12-04 12:05:58 -0800558struct SensorType {
559 const char *name;
560 int rawPictureWidth;
561 int rawPictureHeight;
562 bool hasAutoFocusSupport;
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800563 int max_supported_snapshot_width;
564 int max_supported_snapshot_height;
Srinivasan Kannan71229622009-12-04 12:05:58 -0800565};
566
567static SensorType sensorTypes[] = {
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800568 { "5mp", 2608, 1960, true, 2592, 1944 },
569 { "3mp", 2064, 1544, false, 2048, 1536 },
570 { "2mp", 3200, 1200, false, 1600, 1200 } };
571
Srinivasan Kannan71229622009-12-04 12:05:58 -0800572
573static SensorType * sensorType;
574
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800575static const str_map picture_formats[] = {
576 {CameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
577 {CameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
578};
579
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800580static bool parameter_string_initialized = false;
581static String8 preview_size_values;
582static String8 picture_size_values;
583static String8 antibanding_values;
584static String8 effect_values;
Apurva Rajguru55562b02009-12-03 12:25:35 -0800585static String8 autoexposure_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800586static String8 whitebalance_values;
587static String8 flash_values;
588static String8 focus_mode_values;
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530589static String8 iso_values;
590static String8 lensshade_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800591static String8 picture_format_values;
592
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800593
594static String8 create_sizes_str(const camera_size_type *sizes, int len) {
595 String8 str;
596 char buffer[32];
597
598 if (len > 0) {
599 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
600 str.append(buffer);
601 }
602 for (int i = 1; i < len; i++) {
603 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
604 str.append(buffer);
605 }
606 return str;
607}
608
609static String8 create_values_str(const str_map *values, int len) {
610 String8 str;
611
612 if (len > 0) {
613 str.append(values[0].desc);
614 }
615 for (int i = 1; i < len; i++) {
616 str.append(",");
617 str.append(values[i].desc);
618 }
619 return str;
620}
621
622static Mutex singleton_lock;
623static bool singleton_releasing;
624static Condition singleton_wait;
625
626static void receive_camframe_callback(struct msm_frame *frame);
627static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size);
628static void receive_jpeg_callback(jpeg_event_t status);
629static void receive_shutter_callback(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800630static void receive_camframetimeout_callback(void);
Mohan Kandra284966d2010-01-05 13:39:15 -0800631static int fb_fd = -1;
632static int32_t mMaxZoom = 0;
633static bool native_get_maxzoom(int camfd, void *pZm);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800634
635QualcommCameraHardware::QualcommCameraHardware()
636 : mParameters(),
637 mCameraRunning(false),
638 mPreviewInitialized(false),
639 mFrameThreadRunning(false),
640 mSnapshotThreadRunning(false),
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800641 mSnapshotFormat(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800642 mReleasedRecordingFrame(false),
643 mPreviewFrameSize(0),
644 mRawSize(0),
645 mCameraControlFd(-1),
646 mAutoFocusThreadRunning(false),
647 mAutoFocusFd(-1),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800648 mBrightness(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800649 mInPreviewCallback(false),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800650 mUseOverlay(0),
651 mOverlay(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800652 mMsgEnabled(0),
653 mNotifyCallback(0),
654 mDataCallback(0),
655 mDataCallbackTimestamp(0),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800656 mCallbackCookie(0)
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800657{
658 memset(&mDimension, 0, sizeof(mDimension));
659 memset(&mCrop, 0, sizeof(mCrop));
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800660 memset(&zoomCropInfo, 0, sizeof(zoom_crop_info));
Mohan Kandra284966d2010-01-05 13:39:15 -0800661 property_get("ro.product.device",mDeviceName," ");
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800662 LOGV("constructor EX");
663}
664
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800665
666//filter Picture sizes based on max width and height
667void QualcommCameraHardware::filterPictureSizes(){
668 int i;
669 for(i=0;i<PICTURE_SIZE_COUNT;i++){
670 if(((picture_sizes[i].width <=
671 sensorType->max_supported_snapshot_width) &&
672 (picture_sizes[i].height <=
673 sensorType->max_supported_snapshot_height))){
674 picture_sizes_ptr = picture_sizes + i;
675 supportedPictureSizesCount = PICTURE_SIZE_COUNT - i ;
676 return ;
677 }
678 }
679}
680
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800681void QualcommCameraHardware::initDefaultParameters()
682{
683 LOGV("initDefaultParameters E");
684
685 // Initialize constant parameter strings. This will happen only once in the
686 // lifetime of the mediaserver process.
687 if (!parameter_string_initialized) {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800688 findSensorType();
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800689 antibanding_values = create_values_str(
690 antibanding, sizeof(antibanding) / sizeof(str_map));
691 effect_values = create_values_str(
692 effects, sizeof(effects) / sizeof(str_map));
Apurva Rajguru55562b02009-12-03 12:25:35 -0800693 autoexposure_values = create_values_str(
694 autoexposure, sizeof(autoexposure) / sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800695 whitebalance_values = create_values_str(
696 whitebalance, sizeof(whitebalance) / sizeof(str_map));
697 preview_size_values = create_sizes_str(
698 preview_sizes, PREVIEW_SIZE_COUNT);
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800699 //filter picture sizes
700 filterPictureSizes();
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800701 picture_size_values = create_sizes_str(
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -0800702 picture_sizes_ptr, supportedPictureSizesCount);
703
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800704 flash_values = create_values_str(
705 flash, sizeof(flash) / sizeof(str_map));
Srinivasan Kannan71229622009-12-04 12:05:58 -0800706 if(sensorType->hasAutoFocusSupport){
707 focus_mode_values = create_values_str(
708 focus_modes, sizeof(focus_modes) / sizeof(str_map));
709 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530710 iso_values = create_values_str(
711 iso,sizeof(iso)/sizeof(str_map));
712 lensshade_values = create_values_str(
713 lensshade,sizeof(lensshade)/sizeof(str_map));
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800714 picture_format_values = create_values_str(
715 picture_formats, sizeof(picture_formats)/sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800716 parameter_string_initialized = true;
717 }
718
719 const camera_size_type *ps = &preview_sizes[DEFAULT_PREVIEW_SETTING];
720 mParameters.setPreviewSize(ps->width, ps->height);
721 mDimension.display_width = ps->width;
722 mDimension.display_height = ps->height;
723 mParameters.setPreviewFrameRate(15);
724 mParameters.setPreviewFormat("yuv420sp"); // informative
725
726 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
727 mParameters.setPictureFormat("jpeg"); // informative
728
729 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // max quality
730 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
731 THUMBNAIL_WIDTH_STR); // informative
732 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
733 THUMBNAIL_HEIGHT_STR); // informative
Srinivasan Kannan80d878f2009-12-18 15:06:02 -0800734 mDimension.ui_thumbnail_width =
735 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
736 mDimension.ui_thumbnail_height =
737 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800738 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
739
740 mParameters.set(CameraParameters::KEY_ANTIBANDING,
741 CameraParameters::ANTIBANDING_AUTO);
742 mParameters.set(CameraParameters::KEY_EFFECT,
743 CameraParameters::EFFECT_NONE);
Apurva Rajguru55562b02009-12-03 12:25:35 -0800744 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
745 CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800746 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
747 CameraParameters::WHITE_BALANCE_AUTO);
748 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
749 CameraParameters::FOCUS_MODE_AUTO);
750
751 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
752 preview_size_values.string());
753 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
754 picture_size_values.string());
755 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
756 antibanding_values);
757 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
Apurva Rajguru55562b02009-12-03 12:25:35 -0800758 mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800759 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
760 whitebalance_values);
761 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
762 focus_mode_values);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800763 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
764 picture_format_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800765
766 if (mSensorInfo.flash_enabled) {
767 mParameters.set(CameraParameters::KEY_FLASH_MODE,
768 CameraParameters::FLASH_MODE_OFF);
769 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
770 flash_values);
771 }
772
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530773 mParameters.set("luma-adaptation", "18");
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800774 mParameters.set("zoom-supported", "true");
775 mParameters.set("max-zoom", MAX_ZOOM_LEVEL);
776 mParameters.set("zoom", 0);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800777 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT,
778 CameraParameters::PIXEL_FORMAT_JPEG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800779
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530780 mParameters.set(CameraParameters::KEY_ISO_MODE,
781 CameraParameters::ISO_AUTO);
782 mParameters.set(CameraParameters::KEY_LENSSHADE,
783 CameraParameters::LENSSHADE_ENABLE);
784 mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
785 iso_values);
786 mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
787 lensshade_values);
788
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800789 if (setParameters(mParameters) != NO_ERROR) {
790 LOGE("Failed to set default parameters?!");
791 }
792
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -0800793 mUseOverlay = useOverlay();
794
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800795 /* Initialize the camframe_timeout_flag*/
796 Mutex::Autolock l(&mCamframeTimeoutLock);
797 camframe_timeout_flag = FALSE;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -0800798 mPostViewHeap = NULL;
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800799
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800800 LOGV("initDefaultParameters X");
801}
802
Srinivasan Kannan71229622009-12-04 12:05:58 -0800803void QualcommCameraHardware::findSensorType(){
804 mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
805 mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
806 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
807 sizeof(cam_ctrl_dimension_t), &mDimension);
808 if (ret) {
809 unsigned int i;
810 for (i = 0; i < sizeof(sensorTypes) / sizeof(SensorType); i++) {
811 if (sensorTypes[i].rawPictureHeight
812 == mDimension.raw_picture_height) {
813 sensorType = sensorTypes + i;
814 return;
815 }
816 }
817 }
818 //default to 5 mp
819 sensorType = sensorTypes;
820 return;
821}
822
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800823#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
824
825bool QualcommCameraHardware::startCamera()
826{
827 LOGV("startCamera E");
828#if DLOPEN_LIBMMCAMERA
829 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
830 LOGV("loading liboemcamera at %p", libmmcamera);
831 if (!libmmcamera) {
832 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
833 return false;
834 }
835
836 *(void **)&LINK_cam_frame =
837 ::dlsym(libmmcamera, "cam_frame");
838 *(void **)&LINK_camframe_terminate =
839 ::dlsym(libmmcamera, "camframe_terminate");
840
841 *(void **)&LINK_jpeg_encoder_init =
842 ::dlsym(libmmcamera, "jpeg_encoder_init");
843
844 *(void **)&LINK_jpeg_encoder_encode =
845 ::dlsym(libmmcamera, "jpeg_encoder_encode");
846
847 *(void **)&LINK_jpeg_encoder_join =
848 ::dlsym(libmmcamera, "jpeg_encoder_join");
849
850 *(void **)&LINK_mmcamera_camframe_callback =
851 ::dlsym(libmmcamera, "mmcamera_camframe_callback");
852
853 *LINK_mmcamera_camframe_callback = receive_camframe_callback;
854
855 *(void **)&LINK_mmcamera_jpegfragment_callback =
856 ::dlsym(libmmcamera, "mmcamera_jpegfragment_callback");
857
858 *LINK_mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
859
860 *(void **)&LINK_mmcamera_jpeg_callback =
861 ::dlsym(libmmcamera, "mmcamera_jpeg_callback");
862
863 *LINK_mmcamera_jpeg_callback = receive_jpeg_callback;
864
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800865 *(void **)&LINK_camframe_timeout_callback =
866 ::dlsym(libmmcamera, "camframe_timeout_callback");
867
868 *LINK_camframe_timeout_callback = receive_camframetimeout_callback;
869
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800870/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800871 *(void **)&LINK_mmcamera_shutter_callback =
872 ::dlsym(libmmcamera, "mmcamera_shutter_callback");
873
874 *LINK_mmcamera_shutter_callback = receive_shutter_callback;
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800875*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800876 *(void**)&LINK_jpeg_encoder_setMainImageQuality =
877 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800878/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800879 *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
880 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
881
882 *(void**)&LINK_jpeg_encoder_setRotation =
883 ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
884
885 *(void**)&LINK_jpeg_encoder_setLocation =
886 ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800887*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800888 *(void **)&LINK_cam_conf =
889 ::dlsym(libmmcamera, "cam_conf");
890
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800891/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800892 *(void **)&LINK_default_sensor_get_snapshot_sizes =
893 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800894*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800895 *(void **)&LINK_launch_cam_conf_thread =
896 ::dlsym(libmmcamera, "launch_cam_conf_thread");
897
898 *(void **)&LINK_release_cam_conf_thread =
899 ::dlsym(libmmcamera, "release_cam_conf_thread");
900
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800901/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800902 *(void **)&LINK_zoom_crop_upscale =
903 ::dlsym(libmmcamera, "zoom_crop_upscale");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800904*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800905
906#else
907 mmcamera_camframe_callback = receive_camframe_callback;
908 mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
909 mmcamera_jpeg_callback = receive_jpeg_callback;
910 mmcamera_shutter_callback = receive_shutter_callback;
911#endif // DLOPEN_LIBMMCAMERA
912
913 /* The control thread is in libcamera itself. */
914 mCameraControlFd = open(MSM_CAMERA_CONTROL, O_RDWR);
915 if (mCameraControlFd < 0) {
916 LOGE("startCamera X: %s open failed: %s!",
917 MSM_CAMERA_CONTROL,
918 strerror(errno));
919 return false;
920 }
921
Mohan Kandra284966d2010-01-05 13:39:15 -0800922 if(strncmp(mDeviceName,"msm7630", 7)){
923 fb_fd = open("/dev/graphics/fb0", O_RDWR);
924 if (fb_fd < 0) {
925 LOGE("startCamera: fb0 open failed: %s!", strerror(errno));
926 return FALSE;
927 }
928 }
929
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800930 /* This will block until the control thread is launched. After that, sensor
931 * information becomes available.
932 */
933
934 if (LINK_launch_cam_conf_thread()) {
935 LOGE("failed to launch the camera config thread");
936 return false;
937 }
938
939 memset(&mSensorInfo, 0, sizeof(mSensorInfo));
940 if (ioctl(mCameraControlFd,
941 MSM_CAM_IOCTL_GET_SENSOR_INFO,
942 &mSensorInfo) < 0)
943 LOGW("%s: cannot retrieve sensor info!", __FUNCTION__);
944 else
945 LOGI("%s: camsensor name %s, flash %d", __FUNCTION__,
946 mSensorInfo.name, mSensorInfo.flash_enabled);
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800947/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800948 picture_sizes = LINK_default_sensor_get_snapshot_sizes(&PICTURE_SIZE_COUNT);
949 if (!picture_sizes || !PICTURE_SIZE_COUNT) {
950 LOGE("startCamera X: could not get snapshot sizes");
951 return false;
952 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800953*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800954 LOGV("startCamera X");
955 return true;
956}
957
958status_t QualcommCameraHardware::dump(int fd,
959 const Vector<String16>& args) const
960{
961 const size_t SIZE = 256;
962 char buffer[SIZE];
963 String8 result;
964
965 // Dump internal primitives.
966 result.append("QualcommCameraHardware::dump");
967 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
968 result.append(buffer);
969 int width, height;
970 mParameters.getPreviewSize(&width, &height);
971 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
972 result.append(buffer);
973 mParameters.getPictureSize(&width, &height);
974 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
975 result.append(buffer);
976 snprintf(buffer, 255,
977 "preview frame size(%d), raw size (%d), jpeg size (%d) "
978 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
979 mJpegSize, mJpegMaxSize);
980 result.append(buffer);
981 write(fd, result.string(), result.size());
982
983 // Dump internal objects.
Mohan Kandra284966d2010-01-05 13:39:15 -0800984 if (mCameraPreviewHeap != 0) {
985 mCameraPreviewHeap->dump(fd, args);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800986 }
987 if (mRawHeap != 0) {
988 mRawHeap->dump(fd, args);
989 }
990 if (mJpegHeap != 0) {
991 mJpegHeap->dump(fd, args);
992 }
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800993 if(mRawSnapshotAshmemHeap != 0 ){
994 mRawSnapshotAshmemHeap->dump(fd, args);
995 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800996 mParameters.dump(fd, args);
997 return NO_ERROR;
998}
999
Mohan Kandra284966d2010-01-05 13:39:15 -08001000static bool native_get_maxzoom(int camfd, void *pZm)
1001{
1002 LOGV("native_get_maxzoom E");
1003
1004 struct msm_ctrl_cmd ctrlCmd;
1005 int32_t *pZoom = (int32_t *)pZm;
1006
1007 ctrlCmd.type = CAMERA_GET_PARM_MAXZOOM;
1008 ctrlCmd.timeout_ms = 5000;
1009 ctrlCmd.length = sizeof(int32_t);
1010 ctrlCmd.value = pZoom;
1011 ctrlCmd.resp_fd = camfd;
1012
1013 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1014 LOGE("native_get_maxzoom: ioctl fd %d error %s",
1015 camfd,
1016 strerror(errno));
1017 return false;
1018 }
1019 LOGE("ctrlCmd.value = %d", *(int32_t *)ctrlCmd.value);
1020 memcpy(pZoom, (int32_t *)ctrlCmd.value, sizeof(int32_t));
1021
1022 LOGV("native_get_maxzoom X");
1023 return true;
1024}
1025
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001026static bool native_set_afmode(int camfd, isp3a_af_mode_t af_type)
1027{
1028 int rc;
1029 struct msm_ctrl_cmd ctrlCmd;
1030
1031 ctrlCmd.timeout_ms = 5000;
1032 ctrlCmd.type = CAMERA_SET_PARM_AUTO_FOCUS;
1033 ctrlCmd.length = sizeof(af_type);
1034 ctrlCmd.value = &af_type;
1035 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1036
1037 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0)
1038 LOGE("native_set_afmode: ioctl fd %d error %s\n",
1039 camfd,
1040 strerror(errno));
1041
1042 LOGV("native_set_afmode: ctrlCmd.status == %d\n", ctrlCmd.status);
1043 return rc >= 0 && ctrlCmd.status == CAMERA_EXIT_CB_DONE;
1044}
1045
1046static bool native_cancel_afmode(int camfd, int af_fd)
1047{
1048 int rc;
1049 struct msm_ctrl_cmd ctrlCmd;
1050
1051 ctrlCmd.timeout_ms = 0;
1052 ctrlCmd.type = CAMERA_AUTO_FOCUS_CANCEL;
1053 ctrlCmd.length = 0;
1054 ctrlCmd.value = NULL;
1055 ctrlCmd.resp_fd = -1; // there's no response fd
1056
1057 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd)) < 0)
1058 {
1059 LOGE("native_cancel_afmode: ioctl fd %d error %s\n",
1060 camfd,
1061 strerror(errno));
1062 return false;
1063 }
1064
1065 return true;
1066}
1067
1068static bool native_start_preview(int camfd)
1069{
1070 struct msm_ctrl_cmd ctrlCmd;
1071
1072 ctrlCmd.timeout_ms = 5000;
1073 ctrlCmd.type = CAMERA_START_PREVIEW;
1074 ctrlCmd.length = 0;
1075 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1076
1077 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1078 LOGE("native_start_preview: MSM_CAM_IOCTL_CTRL_COMMAND fd %d error %s",
1079 camfd,
1080 strerror(errno));
1081 return false;
1082 }
1083
1084 return true;
1085}
1086
1087static bool native_get_picture (int camfd, common_crop_t *crop)
1088{
1089 struct msm_ctrl_cmd ctrlCmd;
1090
1091 ctrlCmd.timeout_ms = 5000;
1092 ctrlCmd.length = sizeof(common_crop_t);
1093 ctrlCmd.value = crop;
1094
1095 if(ioctl(camfd, MSM_CAM_IOCTL_GET_PICTURE, &ctrlCmd) < 0) {
1096 LOGE("native_get_picture: MSM_CAM_IOCTL_GET_PICTURE fd %d error %s",
1097 camfd,
1098 strerror(errno));
1099 return false;
1100 }
1101
1102 LOGV("crop: in1_w %d", crop->in1_w);
1103 LOGV("crop: in1_h %d", crop->in1_h);
1104 LOGV("crop: out1_w %d", crop->out1_w);
1105 LOGV("crop: out1_h %d", crop->out1_h);
1106
1107 LOGV("crop: in2_w %d", crop->in2_w);
1108 LOGV("crop: in2_h %d", crop->in2_h);
1109 LOGV("crop: out2_w %d", crop->out2_w);
1110 LOGV("crop: out2_h %d", crop->out2_h);
1111
1112 LOGV("crop: update %d", crop->update_flag);
1113
1114 return true;
1115}
1116
1117static bool native_stop_preview(int camfd)
1118{
1119 struct msm_ctrl_cmd ctrlCmd;
1120 ctrlCmd.timeout_ms = 5000;
1121 ctrlCmd.type = CAMERA_STOP_PREVIEW;
1122 ctrlCmd.length = 0;
1123 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1124
1125 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1126 LOGE("native_stop_preview: ioctl fd %d error %s",
1127 camfd,
1128 strerror(errno));
1129 return false;
1130 }
1131
1132 return true;
1133}
1134
1135static bool native_prepare_snapshot(int camfd)
1136{
1137 int ioctlRetVal = true;
1138 struct msm_ctrl_cmd ctrlCmd;
1139
1140 ctrlCmd.timeout_ms = 1000;
1141 ctrlCmd.type = CAMERA_PREPARE_SNAPSHOT;
1142 ctrlCmd.length = 0;
1143 ctrlCmd.value = NULL;
1144 ctrlCmd.resp_fd = camfd;
1145
1146 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1147 LOGE("native_prepare_snapshot: ioctl fd %d error %s",
1148 camfd,
1149 strerror(errno));
1150 return false;
1151 }
1152 return true;
1153}
1154
1155static bool native_start_snapshot(int camfd)
1156{
1157 struct msm_ctrl_cmd ctrlCmd;
1158
1159 ctrlCmd.timeout_ms = 5000;
1160 ctrlCmd.type = CAMERA_START_SNAPSHOT;
1161 ctrlCmd.length = 0;
1162 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1163
1164 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1165 LOGE("native_start_snapshot: ioctl fd %d error %s",
1166 camfd,
1167 strerror(errno));
1168 return false;
1169 }
1170
1171 return true;
1172}
1173
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001174static bool native_start_raw_snapshot(int camfd)
1175{
1176 int ret;
1177 struct msm_ctrl_cmd ctrlCmd;
1178
1179 ctrlCmd.timeout_ms = 1000;
1180 ctrlCmd.type = CAMERA_START_RAW_SNAPSHOT;
1181 ctrlCmd.length = 0;
1182 ctrlCmd.value = NULL;
1183 ctrlCmd.resp_fd = camfd;
1184
1185 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1186 LOGE("native_start_raw_snapshot: ioctl failed. ioctl return value "\
1187 "is %d \n", ret);
1188 return false;
1189 }
1190 return true;
1191}
1192
1193
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001194static bool native_stop_snapshot (int camfd)
1195{
1196 struct msm_ctrl_cmd ctrlCmd;
1197
1198 ctrlCmd.timeout_ms = 0;
1199 ctrlCmd.type = CAMERA_STOP_SNAPSHOT;
1200 ctrlCmd.length = 0;
1201 ctrlCmd.resp_fd = -1;
1202
1203 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd) < 0) {
1204 LOGE("native_stop_snapshot: ioctl fd %d error %s",
1205 camfd,
1206 strerror(errno));
1207 return false;
1208 }
1209
1210 return true;
1211}
1212
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001213static rat_t latitude[3];
1214static rat_t longitude[3];
1215static char lonref[2];
1216static char latref[2];
1217static char dateTime[20];
1218static rat_t altitude;
1219
1220static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
1221 uint32_t count, uint8_t copy, void *data) {
1222
1223 if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
1224 LOGE("Number of entries exceeded limit");
1225 return;
1226 }
1227
1228 int index = exif_table_numEntries;
1229 exif_data[index].tag_id = tagid;
1230 exif_data[index].tag_entry.type = type;
1231 exif_data[index].tag_entry.count = count;
1232 exif_data[index].tag_entry.copy = copy;
1233 if((type == EXIF_RATIONAL) && (count > 1))
1234 exif_data[index].tag_entry.data._rats = (rat_t *)data;
1235 if((type == EXIF_RATIONAL) && (count == 1))
1236 exif_data[index].tag_entry.data._rat = *(rat_t *)data;
1237 else if(type == EXIF_ASCII)
1238 exif_data[index].tag_entry.data._ascii = (char *)data;
1239 else if(type == EXIF_BYTE)
1240 exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
1241
1242 // Increase number of entries
1243 exif_table_numEntries++;
1244}
1245
1246static void parseLatLong(const char *latlonString, int *pDegrees,
1247 int *pMinutes, int *pSeconds ) {
1248
1249 double value = atof(latlonString);
1250 value = fabs(value);
1251 int degrees = (int) value;
1252
1253 double remainder = value - degrees;
1254 int minutes = (int) (remainder * 60);
1255 int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
1256
1257 *pDegrees = degrees;
1258 *pMinutes = minutes;
1259 *pSeconds = seconds;
1260}
1261
1262static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
1263
1264 int degrees, minutes, seconds;
1265
1266 parseLatLong(latlonString, &degrees, &minutes, &seconds);
1267
1268 rat_t value[3] = { {degrees, 1},
1269 {minutes, 1},
1270 {seconds, 1000} };
1271
1272 if(tag == EXIFTAGID_GPS_LATITUDE) {
1273 memcpy(latitude, value, sizeof(latitude));
1274 addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
1275 1, (void *)latitude);
1276 } else {
1277 memcpy(longitude, value, sizeof(longitude));
1278 addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
1279 1, (void *)longitude);
1280 }
1281}
1282
1283void QualcommCameraHardware::setGpsParameters() {
1284 const char *str = NULL;
1285
1286 //Set Latitude
1287 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE);
1288 if(str != NULL) {
1289 setLatLon(EXIFTAGID_GPS_LATITUDE, str);
1290 //set Latitude Ref
1291 str = NULL;
1292 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE_REF);
1293 if(str != NULL) {
1294 strncpy(latref, str, 1);
1295 latref[1] = '\0';
1296 addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
1297 1, (void *)latref);
1298 }
1299 }
1300
1301 //set Longitude
1302 str = NULL;
1303 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE);
1304 if(str != NULL) {
1305 setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
1306 //set Longitude Ref
1307 str = NULL;
1308 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
1309 if(str != NULL) {
1310 strncpy(lonref, str, 1);
1311 lonref[1] = '\0';
1312 addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
1313 1, (void *)lonref);
1314 }
1315 }
1316
1317 //set Altitude
1318 str = NULL;
1319 str = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE);
1320 if(str != NULL) {
1321 int value = atoi(str);
1322 rat_t alt_value = {value, 1000};
1323 memcpy(&altitude, &alt_value, sizeof(altitude));
1324 addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
1325 1, (void *)&altitude);
1326 //set AltitudeRef
1327 int ref = mParameters.getInt(CameraParameters::KEY_GPS_ALTITUDE_REF);
1328 if( !(ref < 0 || ref > 1) )
1329 addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
1330 1, (void *)&ref);
1331 }
1332
1333
1334}
1335
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001336bool QualcommCameraHardware::native_jpeg_encode(void)
1337{
1338 int jpeg_quality = mParameters.getInt("jpeg-quality");
1339 if (jpeg_quality >= 0) {
1340 LOGV("native_jpeg_encode, current jpeg main img quality =%d",
1341 jpeg_quality);
1342 if(!LINK_jpeg_encoder_setMainImageQuality(jpeg_quality)) {
1343 LOGE("native_jpeg_encode set jpeg-quality failed");
1344 return false;
1345 }
1346 }
1347
1348 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
1349 if (thumbnail_quality >= 0) {
1350 LOGV("native_jpeg_encode, current jpeg thumbnail quality =%d",
1351 thumbnail_quality);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001352/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001353 if(!LINK_jpeg_encoder_setThumbnailQuality(thumbnail_quality)) {
1354 LOGE("native_jpeg_encode set thumbnail-quality failed");
1355 return false;
1356 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001357*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001358 }
1359
1360 int rotation = mParameters.getInt("rotation");
1361 if (rotation >= 0) {
1362 LOGV("native_jpeg_encode, rotation = %d", rotation);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001363/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001364 if(!LINK_jpeg_encoder_setRotation(rotation)) {
1365 LOGE("native_jpeg_encode set rotation failed");
1366 return false;
1367 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001368*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001369 }
1370
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001371// jpeg_set_location();
1372 if(mParameters.getInt(CameraParameters::KEY_GPS_STATUS) == 1) {
1373 setGpsParameters();
1374 }
1375 //set TimeStamp
1376 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
1377 if(str != NULL) {
1378 strncpy(dateTime, str, 19);
1379 dateTime[19] = '\0';
1380 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
1381 20, 1, (void *)dateTime);
1382 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001383
1384 if (!LINK_jpeg_encoder_encode(&mDimension,
1385 (uint8_t *)mThumbnailHeap->mHeap->base(),
1386 mThumbnailHeap->mHeap->getHeapID(),
1387 (uint8_t *)mRawHeap->mHeap->base(),
1388 mRawHeap->mHeap->getHeapID(),
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001389 &mCrop, exif_data, exif_table_numEntries)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001390 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
1391 return false;
1392 }
1393 return true;
1394}
1395
1396bool QualcommCameraHardware::native_set_parm(
1397 cam_ctrl_type type, uint16_t length, void *value)
1398{
1399 struct msm_ctrl_cmd ctrlCmd;
1400
1401 ctrlCmd.timeout_ms = 5000;
1402 ctrlCmd.type = (uint16_t)type;
1403 ctrlCmd.length = length;
1404 // FIXME: this will be put in by the kernel
1405 ctrlCmd.resp_fd = mCameraControlFd;
1406 ctrlCmd.value = value;
1407
1408 LOGV("%s: fd %d, type %d, length %d", __FUNCTION__,
1409 mCameraControlFd, type, length);
1410 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0 ||
1411 ctrlCmd.status != CAM_CTRL_SUCCESS) {
1412 LOGE("%s: error (%s): fd %d, type %d, length %d, status %d",
1413 __FUNCTION__, strerror(errno),
1414 mCameraControlFd, type, length, ctrlCmd.status);
1415 return false;
1416 }
1417 return true;
1418}
1419
1420void QualcommCameraHardware::jpeg_set_location()
1421{
1422 bool encode_location = true;
1423 camera_position_type pt;
1424
1425#define PARSE_LOCATION(what,type,fmt,desc) do { \
1426 pt.what = 0; \
1427 const char *what##_str = mParameters.get("gps-"#what); \
1428 LOGV("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
1429 if (what##_str) { \
1430 type what = 0; \
1431 if (sscanf(what##_str, fmt, &what) == 1) \
1432 pt.what = what; \
1433 else { \
1434 LOGE("GPS " #what " %s could not" \
1435 " be parsed as a " #desc, what##_str); \
1436 encode_location = false; \
1437 } \
1438 } \
1439 else { \
1440 LOGV("GPS " #what " not specified: " \
1441 "defaulting to zero in EXIF header."); \
1442 encode_location = false; \
1443 } \
1444 } while(0)
1445
1446 PARSE_LOCATION(timestamp, long, "%ld", "long");
1447 if (!pt.timestamp) pt.timestamp = time(NULL);
1448 PARSE_LOCATION(altitude, short, "%hd", "short");
1449 PARSE_LOCATION(latitude, double, "%lf", "double float");
1450 PARSE_LOCATION(longitude, double, "%lf", "double float");
1451
1452#undef PARSE_LOCATION
1453
1454 if (encode_location) {
1455 LOGD("setting image location ALT %d LAT %lf LON %lf",
1456 pt.altitude, pt.latitude, pt.longitude);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001457/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001458 if (!LINK_jpeg_encoder_setLocation(&pt)) {
1459 LOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
1460 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001461*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001462 }
1463 else LOGV("not setting image location");
1464}
1465
1466void QualcommCameraHardware::runFrameThread(void *data)
1467{
1468 LOGV("runFrameThread E");
1469
1470 int cnt;
1471
1472#if DLOPEN_LIBMMCAMERA
1473 // We need to maintain a reference to libqcamera.so for the duration of the
1474 // frame thread, because we do not know when it will exit relative to the
1475 // lifetime of this object. We do not want to dlclose() libqcamera while
1476 // LINK_cam_frame is still running.
1477 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
1478 LOGV("FRAME: loading libqcamera at %p", libhandle);
1479 if (!libhandle) {
1480 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1481 }
1482 if (libhandle)
1483#endif
1484 {
1485 LINK_cam_frame(data);
1486 }
1487
Mohan Kandra284966d2010-01-05 13:39:15 -08001488 mCameraPreviewHeap.clear();
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001489 if(strncmp(mDeviceName,"msm7630", 7)) {
1490 mPreviewHeap.clear();
1491 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001492#if DLOPEN_LIBMMCAMERA
1493 if (libhandle) {
1494 ::dlclose(libhandle);
1495 LOGV("FRAME: dlclose(libqcamera)");
1496 }
1497#endif
1498
1499 mFrameThreadWaitLock.lock();
1500 mFrameThreadRunning = false;
1501 mFrameThreadWait.signal();
1502 mFrameThreadWaitLock.unlock();
1503
1504 LOGV("runFrameThread X");
1505}
1506
1507void *frame_thread(void *user)
1508{
1509 LOGD("frame_thread E");
1510 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
1511 if (obj != 0) {
1512 obj->runFrameThread(user);
1513 }
1514 else LOGW("not starting frame thread: the object went away!");
1515 LOGD("frame_thread X");
1516 return NULL;
1517}
1518
1519bool QualcommCameraHardware::initPreview()
1520{
1521 // See comments in deinitPreview() for why we have to wait for the frame
1522 // thread here, and why we can't use pthread_join().
1523 int previewWidth, previewHeight;
1524 mParameters.getPreviewSize(&previewWidth, &previewHeight);
1525 LOGI("initPreview E: preview size=%dx%d", previewWidth, previewHeight);
1526 mFrameThreadWaitLock.lock();
1527 while (mFrameThreadRunning) {
1528 LOGV("initPreview: waiting for old frame thread to complete.");
1529 mFrameThreadWait.wait(mFrameThreadWaitLock);
1530 LOGV("initPreview: old frame thread completed.");
1531 }
1532 mFrameThreadWaitLock.unlock();
1533
1534 mSnapshotThreadWaitLock.lock();
1535 while (mSnapshotThreadRunning) {
1536 LOGV("initPreview: waiting for old snapshot thread to complete.");
1537 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
1538 LOGV("initPreview: old snapshot thread completed.");
1539 }
1540 mSnapshotThreadWaitLock.unlock();
1541
1542 int cnt = 0;
1543 mPreviewFrameSize = previewWidth * previewHeight * 3/2;
Mohan Kandra284966d2010-01-05 13:39:15 -08001544 mCameraPreviewHeap = new PmemPool("/dev/pmem_adsp",
1545 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
1546 mCameraControlFd,
1547 MSM_PMEM_OUTPUT2,
1548 mPreviewFrameSize,
1549 kPreviewBufferCount,
1550 mPreviewFrameSize,
1551 "Camera preview");
1552
1553 if (!mCameraPreviewHeap->initialized()) {
1554 mCameraPreviewHeap.clear();
1555 LOGE("initPreview X: could not initialize Camera preview heap.");
1556 return false;
1557 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001558 if( (!strncmp(mDeviceName,"msm7630", 7))
1559 && (mPostViewHeap == NULL)) {
1560 mPreviewHeap = NULL;
1561 LOGV(" Allocating Postview heap ");
1562 /* mPostViewHeap should be declared only for 7630 target */
1563 mPostViewHeap =
1564 new PmemPool("/dev/pmem_adsp",
1565 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
1566 mCameraControlFd,
1567 MSM_PMEM_OUTPUT2,
1568 mPreviewFrameSize,
1569 1,
1570 mPreviewFrameSize,
1571 "postview");
Mohan Kandra284966d2010-01-05 13:39:15 -08001572
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001573 if (!mPostViewHeap->initialized()) {
1574 mPostViewHeap.clear();
1575 LOGE(" Failed to initialize Postview Heap");
1576 return false;
1577 }
1578 } else {
1579 mPreviewHeap = new PmemPool("/dev/pmem_adsp",
1580 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
1581 mCameraControlFd,
1582 MSM_PMEM_OUTPUT2,
1583 mPreviewFrameSize,
1584 kPreviewBufferCount,
1585 mPreviewFrameSize,
1586 "preview");
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001587
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001588 if (!mPreviewHeap->initialized()) {
1589 mPreviewHeap.clear();
1590 LOGE("initPreview X: could not initialize preview heap.");
1591 return false;
1592 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001593 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001594 // mDimension will be filled with thumbnail_width, thumbnail_height,
1595 // orig_picture_dx, and orig_picture_dy after this function call. We need to
1596 // keep it for jpeg_encoder_encode.
1597 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1598 sizeof(cam_ctrl_dimension_t), &mDimension);
1599
1600 if (ret) {
1601 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
Mohan Kandra284966d2010-01-05 13:39:15 -08001602 frames[cnt].fd = mCameraPreviewHeap->mHeap->getHeapID();
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001603 frames[cnt].buffer =
Mohan Kandra284966d2010-01-05 13:39:15 -08001604 (uint32_t)mCameraPreviewHeap->mHeap->base() + mCameraPreviewHeap->mAlignedBufferSize * cnt;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001605 frames[cnt].y_off = 0;
1606 frames[cnt].cbcr_off = previewWidth * previewHeight;
1607 frames[cnt].path = MSM_FRAME_ENC;
1608 }
1609
1610 mFrameThreadWaitLock.lock();
1611 pthread_attr_t attr;
1612 pthread_attr_init(&attr);
1613 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1614 mFrameThreadRunning = !pthread_create(&mFrameThread,
1615 &attr,
1616 frame_thread,
1617 &frames[kPreviewBufferCount-1]);
1618 ret = mFrameThreadRunning;
1619 mFrameThreadWaitLock.unlock();
1620 }
1621
1622 LOGV("initPreview X: %d", ret);
1623 return ret;
1624}
1625
1626void QualcommCameraHardware::deinitPreview(void)
1627{
1628 LOGI("deinitPreview E");
1629
1630 // When we call deinitPreview(), we signal to the frame thread that it
1631 // needs to exit, but we DO NOT WAIT for it to complete here. The problem
1632 // is that deinitPreview is sometimes called from the frame-thread's
1633 // callback, when the refcount on the Camera client reaches zero. If we
1634 // called pthread_join(), we would deadlock. So, we just call
1635 // LINK_camframe_terminate() in deinitPreview(), which makes sure that
1636 // after the preview callback returns, the camframe thread will exit. We
1637 // could call pthread_join() in initPreview() to join the last frame
1638 // thread. However, we would also have to call pthread_join() in release
1639 // as well, shortly before we destroy the object; this would cause the same
1640 // deadlock, since release(), like deinitPreview(), may also be called from
1641 // the frame-thread's callback. This we have to make the frame thread
1642 // detached, and use a separate mechanism to wait for it to complete.
1643
1644 if (LINK_camframe_terminate() < 0)
1645 LOGE("failed to stop the camframe thread: %s",
1646 strerror(errno));
1647 LOGI("deinitPreview X");
1648}
1649
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001650bool QualcommCameraHardware::initRawSnapshot()
1651{
1652 LOGV("initRawSnapshot E");
1653
1654 //get width and height from Dimension Object
1655 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1656 sizeof(cam_ctrl_dimension_t), &mDimension);
1657
1658 if(!ret){
1659 LOGE("initRawSnapshot X: failed to set dimension");
1660 return false;
1661 }
1662 int rawSnapshotSize = mDimension.raw_picture_height *
1663 mDimension.raw_picture_width;
1664
1665 LOGV("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
1666 "raw_picture_width = %d",
1667 rawSnapshotSize, mDimension.raw_picture_height,
1668 mDimension.raw_picture_width);
1669
1670 if (mRawSnapShotPmemHeap != NULL) {
1671 LOGV("initRawSnapshot: clearing old mRawSnapShotPmemHeap.");
1672 mRawSnapShotPmemHeap.clear();
1673 }
1674
1675 //Pmem based pool for Camera Driver
1676 mRawSnapShotPmemHeap = new PmemPool("/dev/pmem_adsp",
1677 MemoryHeapBase::READ_ONLY,
1678 mCameraControlFd,
1679 MSM_PMEM_RAW_MAINIMG,
1680 rawSnapshotSize,
1681 1,
1682 rawSnapshotSize,
1683 "raw pmem snapshot camera");
1684
1685 if (!mRawSnapShotPmemHeap->initialized()) {
1686 mRawSnapShotPmemHeap.clear();
1687 LOGE("initRawSnapshot X: error initializing mRawSnapshotHeap");
1688 return false;
1689 }
1690 LOGV("initRawSnapshot X");
1691 return true;
1692
1693}
1694
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001695bool QualcommCameraHardware::initRaw(bool initJpegHeap)
1696{
1697 int rawWidth, rawHeight;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001698
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001699 mParameters.getPictureSize(&rawWidth, &rawHeight);
1700 LOGV("initRaw E: picture size=%dx%d", rawWidth, rawHeight);
1701
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08001702 int thumbnailBufferSize;
1703 //Thumbnail height should be smaller than Picture height
1704 if (rawHeight > thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height){
1705 mDimension.ui_thumbnail_width =
1706 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].width;
1707 mDimension.ui_thumbnail_height =
1708 thumbnail_sizes[DEFAULT_THUMBNAIL_SETTING].height;
1709 uint32_t pictureAspectRatio = (uint32_t)((rawWidth * Q12) / rawHeight);
1710 uint32_t i;
1711 for(i = 0; i < THUMBNAIL_SIZE_COUNT; i++ )
1712 {
1713 if(thumbnail_sizes[i].aspect_ratio == pictureAspectRatio)
1714 {
1715 mDimension.ui_thumbnail_width = thumbnail_sizes[i].width;
1716 mDimension.ui_thumbnail_height = thumbnail_sizes[i].height;
1717 break;
1718 }
1719 }
1720 }
1721 else{
1722 mDimension.ui_thumbnail_height = THUMBNAIL_SMALL_HEIGHT;
1723 mDimension.ui_thumbnail_width =
1724 (THUMBNAIL_SMALL_HEIGHT * rawWidth)/ rawHeight;
1725 }
1726
1727 LOGV("Thumbnail Size Width %d Height %d",
1728 mDimension.ui_thumbnail_width,
1729 mDimension.ui_thumbnail_height);
1730
1731 thumbnailBufferSize = mDimension.ui_thumbnail_width *
1732 mDimension.ui_thumbnail_height * 3 / 2;
1733
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001734 // mDimension will be filled with thumbnail_width, thumbnail_height,
1735 // orig_picture_dx, and orig_picture_dy after this function call. We need to
1736 // keep it for jpeg_encoder_encode.
1737 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1738 sizeof(cam_ctrl_dimension_t), &mDimension);
1739 if(!ret) {
1740 LOGE("initRaw X: failed to set dimension");
1741 return false;
1742 }
1743
1744 if (mJpegHeap != NULL) {
1745 LOGV("initRaw: clearing old mJpegHeap.");
1746 mJpegHeap.clear();
1747 }
1748
1749 // Snapshot
1750 mRawSize = rawWidth * rawHeight * 3 / 2;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001751
Mohan Kandra284966d2010-01-05 13:39:15 -08001752 if(!strcmp(mDeviceName,"msm7627_surf"))
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001753 mJpegMaxSize = CEILING16(rawWidth) * CEILING16(rawHeight) * 3 / 2;
1754 else
1755 mJpegMaxSize = rawWidth * rawHeight * 3 / 2;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001756
1757 LOGV("initRaw: initializing mRawHeap.");
1758 mRawHeap =
1759 new PmemPool("/dev/pmem_camera",
1760 MemoryHeapBase::READ_ONLY,
1761 mCameraControlFd,
1762 MSM_PMEM_MAINIMG,
1763 mJpegMaxSize,
1764 kRawBufferCount,
1765 mRawSize,
1766 "snapshot camera");
1767
1768 if (!mRawHeap->initialized()) {
1769 LOGE("initRaw X failed with pmem_camera, trying with pmem_adsp");
1770 mRawHeap =
1771 new PmemPool("/dev/pmem_adsp",
1772 MemoryHeapBase::READ_ONLY,
1773 mCameraControlFd,
1774 MSM_PMEM_MAINIMG,
1775 mJpegMaxSize,
1776 kRawBufferCount,
1777 mRawSize,
1778 "snapshot camera");
1779 if (!mRawHeap->initialized()) {
1780 mRawHeap.clear();
1781 LOGE("initRaw X: error initializing mRawHeap");
1782 return false;
1783 }
1784 }
1785
1786 LOGV("do_mmap snapshot pbuf = %p, pmem_fd = %d",
1787 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mHeap->getHeapID());
1788
1789 // Jpeg
1790
1791 if (initJpegHeap) {
1792 LOGV("initRaw: initializing mJpegHeap.");
1793 mJpegHeap =
1794 new AshmemPool(mJpegMaxSize,
1795 kJpegBufferCount,
1796 0, // we do not know how big the picture will be
1797 "jpeg");
1798
1799 if (!mJpegHeap->initialized()) {
1800 mJpegHeap.clear();
1801 mRawHeap.clear();
1802 LOGE("initRaw X failed: error initializing mJpegHeap.");
1803 return false;
1804 }
1805
1806 // Thumbnails
1807
1808 mThumbnailHeap =
1809 new PmemPool("/dev/pmem_adsp",
1810 MemoryHeapBase::READ_ONLY,
1811 mCameraControlFd,
1812 MSM_PMEM_THUMBNAIL,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08001813 thumbnailBufferSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001814 1,
Srinivasan Kannan80d878f2009-12-18 15:06:02 -08001815 thumbnailBufferSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001816 "thumbnail");
1817
1818 if (!mThumbnailHeap->initialized()) {
1819 mThumbnailHeap.clear();
1820 mJpegHeap.clear();
1821 mRawHeap.clear();
1822 LOGE("initRaw X failed: error initializing mThumbnailHeap.");
1823 return false;
1824 }
1825 }
1826
1827 LOGV("initRaw X");
1828 return true;
1829}
1830
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001831
1832void QualcommCameraHardware::deinitRawSnapshot()
1833{
1834 LOGV("deinitRawSnapshot E");
1835 mRawSnapShotPmemHeap.clear();
1836 mRawSnapshotAshmemHeap.clear();
1837 LOGV("deinitRawSnapshot X");
1838}
1839
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001840void QualcommCameraHardware::deinitRaw()
1841{
1842 LOGV("deinitRaw E");
1843
1844 mThumbnailHeap.clear();
1845 mJpegHeap.clear();
1846 mRawHeap.clear();
1847 mDisplayHeap.clear();
1848
1849 LOGV("deinitRaw X");
1850}
1851
1852void QualcommCameraHardware::release()
1853{
1854 LOGD("release E");
1855 Mutex::Autolock l(&mLock);
1856
1857#if DLOPEN_LIBMMCAMERA
1858 if (libmmcamera == NULL) {
1859 LOGE("ERROR: multiple release!");
1860 return;
1861 }
1862#else
1863#warning "Cannot detect multiple release when not dlopen()ing libqcamera!"
1864#endif
1865
1866 int cnt, rc;
1867 struct msm_ctrl_cmd ctrlCmd;
1868
1869 if (mCameraRunning) {
1870 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
1871 mRecordFrameLock.lock();
1872 mReleasedRecordingFrame = true;
1873 mRecordWait.signal();
1874 mRecordFrameLock.unlock();
1875 }
1876 stopPreviewInternal();
1877 }
1878
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08001879 if(!strncmp(mDeviceName,"msm7630", 7)) {
1880 mPostViewHeap.clear();
1881 mPostViewHeap = NULL;
1882 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001883 LINK_jpeg_encoder_join();
1884 deinitRaw();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001885 deinitRawSnapshot();
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001886 {
1887 Mutex::Autolock l(&mCamframeTimeoutLock);
1888 if(!camframe_timeout_flag) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001889
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001890 ctrlCmd.timeout_ms = 5000;
1891 ctrlCmd.length = 0;
1892 ctrlCmd.type = (uint16_t)CAMERA_EXIT;
1893 ctrlCmd.resp_fd = mCameraControlFd; // FIXME: this will be put in by the kernel
1894 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0)
1895 LOGE("ioctl CAMERA_EXIT fd %d error %s",
1896 mCameraControlFd, strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001897
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001898 LINK_release_cam_conf_thread();
1899 }
1900 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001901 close(mCameraControlFd);
1902 mCameraControlFd = -1;
Mohan Kandra284966d2010-01-05 13:39:15 -08001903 if(fb_fd >= 0) {
1904 close(fb_fd);
1905 fb_fd = -1;
1906 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001907#if DLOPEN_LIBMMCAMERA
1908 if (libmmcamera) {
1909 ::dlclose(libmmcamera);
1910 LOGV("dlclose(libqcamera)");
1911 libmmcamera = NULL;
1912 }
1913#endif
1914
1915 Mutex::Autolock lock(&singleton_lock);
1916 singleton_releasing = true;
1917
1918 LOGD("release X");
1919}
1920
1921QualcommCameraHardware::~QualcommCameraHardware()
1922{
1923 LOGD("~QualcommCameraHardware E");
1924 Mutex::Autolock lock(&singleton_lock);
1925 singleton.clear();
1926 singleton_releasing = false;
1927 singleton_wait.signal();
1928 LOGD("~QualcommCameraHardware X");
1929}
1930
1931sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
1932{
1933 LOGV("getRawHeap");
1934 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
1935}
1936
1937sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
1938{
1939 LOGV("getPreviewHeap");
1940 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
1941}
1942
1943status_t QualcommCameraHardware::startPreviewInternal()
1944{
1945 if(mCameraRunning) {
1946 LOGV("startPreview X: preview already running.");
1947 return NO_ERROR;
1948 }
1949
1950 if (!mPreviewInitialized) {
1951 mPreviewInitialized = initPreview();
1952 if (!mPreviewInitialized) {
1953 LOGE("startPreview X initPreview failed. Not starting preview.");
1954 return UNKNOWN_ERROR;
1955 }
1956 }
1957
1958 mCameraRunning = native_start_preview(mCameraControlFd);
1959 if(!mCameraRunning) {
1960 deinitPreview();
1961 mPreviewInitialized = false;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001962 mOverlay = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001963 LOGE("startPreview X: native_start_preview failed!");
1964 return UNKNOWN_ERROR;
1965 }
1966
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001967 //Reset the Gps Information
1968 exif_table_numEntries = 0;
Mohan Kandra284966d2010-01-05 13:39:15 -08001969
1970 if(native_get_maxzoom(mCameraControlFd, (void *)&mMaxZoom) == true){
1971 LOGE("Maximum zoom value is %d", mMaxZoom);
1972 mParameters.set("zoom-supported", "true");
1973 } else {
1974 LOGE("Failed to get maximum zoom value...setting max zoom to zero");
1975 mParameters.set("zoom-supported", "false");
1976 mMaxZoom = 0;
1977 }
1978 mParameters.set("max-zoom",mMaxZoom);
1979
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001980 LOGV("startPreview X");
1981 return NO_ERROR;
1982}
1983
1984status_t QualcommCameraHardware::startPreview()
1985{
1986 LOGV("startPreview E");
1987 Mutex::Autolock l(&mLock);
1988 return startPreviewInternal();
1989}
1990
1991void QualcommCameraHardware::stopPreviewInternal()
1992{
1993 LOGV("stopPreviewInternal E: %d", mCameraRunning);
1994 if (mCameraRunning) {
1995 // Cancel auto focus.
1996 {
1997 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
1998 cancelAutoFocusInternal();
1999 }
2000 }
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08002001
Kiran Kumar H N215cac42009-12-08 01:53:46 -08002002 Mutex::Autolock l(&mCamframeTimeoutLock);
2003 if(!camframe_timeout_flag) {
2004 mCameraRunning = !native_stop_preview(mCameraControlFd);
2005 if (!mCameraRunning && mPreviewInitialized) {
2006 deinitPreview();
2007 mPreviewInitialized = false;
2008 }
2009 else LOGE("stopPreviewInternal: failed to stop preview");
2010 } else {
2011 /* This means that the camframetimeout was issued.
2012 * But we did not issue native_stop_preview(), so we
2013 * need to update mCameraRunning & mPreviewInitialized
2014 * to indicate that Camera is no longer running.
2015 */
2016 mCameraRunning = 0;
2017 mPreviewInitialized = false;
2018 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002019 }
2020 LOGV("stopPreviewInternal X: %d", mCameraRunning);
2021}
2022
2023void QualcommCameraHardware::stopPreview()
2024{
2025 LOGV("stopPreview: E");
2026 Mutex::Autolock l(&mLock);
2027 {
2028 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
2029 return;
2030 }
2031 stopPreviewInternal();
2032 LOGV("stopPreview: X");
2033}
2034
2035void QualcommCameraHardware::runAutoFocus()
2036{
2037 bool status = true;
2038 void *libhandle = NULL;
Srinivasan Kannan71229622009-12-04 12:05:58 -08002039 isp3a_af_mode_t afMode;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002040
2041 mAutoFocusThreadLock.lock();
2042 // Skip autofocus if focus mode is infinity.
2043 if (strcmp(mParameters.get(CameraParameters::KEY_FOCUS_MODE),
2044 CameraParameters::FOCUS_MODE_INFINITY) == 0) {
2045 goto done;
2046 }
2047
2048 mAutoFocusFd = open(MSM_CAMERA_CONTROL, O_RDWR);
2049 if (mAutoFocusFd < 0) {
2050 LOGE("autofocus: cannot open %s: %s",
2051 MSM_CAMERA_CONTROL,
2052 strerror(errno));
2053 mAutoFocusThreadRunning = false;
2054 mAutoFocusThreadLock.unlock();
2055 return;
2056 }
2057
2058#if DLOPEN_LIBMMCAMERA
2059 // We need to maintain a reference to libqcamera.so for the duration of the
2060 // AF thread, because we do not know when it will exit relative to the
2061 // lifetime of this object. We do not want to dlclose() libqcamera while
2062 // LINK_cam_frame is still running.
2063 libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
2064 LOGV("AF: loading libqcamera at %p", libhandle);
2065 if (!libhandle) {
2066 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
2067 close(mAutoFocusFd);
2068 mAutoFocusFd = -1;
2069 mAutoFocusThreadRunning = false;
2070 mAutoFocusThreadLock.unlock();
2071 return;
2072 }
2073#endif
2074
Srinivasan Kannan71229622009-12-04 12:05:58 -08002075 afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
2076 sizeof(focus_modes) / sizeof(str_map),
2077 mParameters.get(CameraParameters::KEY_FOCUS_MODE));
2078
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002079 /* This will block until either AF completes or is cancelled. */
Srinivasan Kannan71229622009-12-04 12:05:58 -08002080 LOGV("af start (fd %d mode %d)", mAutoFocusFd, afMode);
2081 status = native_set_afmode(mAutoFocusFd, afMode);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002082 LOGV("af done: %d", (int)status);
2083 close(mAutoFocusFd);
2084 mAutoFocusFd = -1;
2085
2086done:
2087 mAutoFocusThreadRunning = false;
2088 mAutoFocusThreadLock.unlock();
2089
2090 mCallbackLock.lock();
2091 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
2092 notify_callback cb = mNotifyCallback;
2093 void *data = mCallbackCookie;
2094 mCallbackLock.unlock();
2095 if (autoFocusEnabled)
2096 cb(CAMERA_MSG_FOCUS, status, 0, data);
2097
2098#if DLOPEN_LIBMMCAMERA
2099 if (libhandle) {
2100 ::dlclose(libhandle);
2101 LOGV("AF: dlclose(libqcamera)");
2102 }
2103#endif
2104}
2105
2106status_t QualcommCameraHardware::cancelAutoFocusInternal()
2107{
2108 LOGV("cancelAutoFocusInternal E");
2109
Srinivasan Kannan71229622009-12-04 12:05:58 -08002110 if(!sensorType->hasAutoFocusSupport){
2111 LOGV("cancelAutoFocusInternal X");
2112 return NO_ERROR;
2113 }
2114
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002115#if 0
2116 if (mAutoFocusFd < 0) {
2117 LOGV("cancelAutoFocusInternal X: not in progress");
2118 return NO_ERROR;
2119 }
2120#endif
2121
2122 status_t rc = native_cancel_afmode(mCameraControlFd, mAutoFocusFd) ?
2123 NO_ERROR :
2124 UNKNOWN_ERROR;
2125
2126 LOGV("cancelAutoFocusInternal X: %d", rc);
2127 return rc;
2128}
2129
2130void *auto_focus_thread(void *user)
2131{
2132 LOGV("auto_focus_thread E");
2133 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2134 if (obj != 0) {
2135 obj->runAutoFocus();
2136 }
2137 else LOGW("not starting autofocus: the object went away!");
2138 LOGV("auto_focus_thread X");
2139 return NULL;
2140}
2141
2142status_t QualcommCameraHardware::autoFocus()
2143{
2144 LOGV("autoFocus E");
2145 Mutex::Autolock l(&mLock);
2146
Srinivasan Kannan71229622009-12-04 12:05:58 -08002147 if(!sensorType->hasAutoFocusSupport){
Srinivasan Kannandf085222009-12-09 18:31:00 -08002148 bool status = false;
2149 mCallbackLock.lock();
2150 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
2151 notify_callback cb = mNotifyCallback;
2152 void *data = mCallbackCookie;
2153 mCallbackLock.unlock();
2154 if (autoFocusEnabled)
2155 cb(CAMERA_MSG_FOCUS, status, 0, data);
Srinivasan Kannan71229622009-12-04 12:05:58 -08002156 LOGV("autoFocus X");
2157 return NO_ERROR;
2158 }
2159
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002160 if (mCameraControlFd < 0) {
2161 LOGE("not starting autofocus: main control fd %d", mCameraControlFd);
2162 return UNKNOWN_ERROR;
2163 }
2164
2165 {
2166 mAutoFocusThreadLock.lock();
2167 if (!mAutoFocusThreadRunning) {
2168 // Create a detached thread here so that we don't have to wait
2169 // for it when we cancel AF.
2170 pthread_t thr;
2171 pthread_attr_t attr;
2172 pthread_attr_init(&attr);
2173 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2174 mAutoFocusThreadRunning =
2175 !pthread_create(&thr, &attr,
2176 auto_focus_thread, NULL);
2177 if (!mAutoFocusThreadRunning) {
2178 LOGE("failed to start autofocus thread");
2179 mAutoFocusThreadLock.unlock();
2180 return UNKNOWN_ERROR;
2181 }
2182 }
2183 mAutoFocusThreadLock.unlock();
2184 }
2185
2186 LOGV("autoFocus X");
2187 return NO_ERROR;
2188}
2189
2190status_t QualcommCameraHardware::cancelAutoFocus()
2191{
2192 LOGV("cancelAutoFocus E");
2193 Mutex::Autolock l(&mLock);
2194
2195 int rc = NO_ERROR;
2196 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
2197 rc = cancelAutoFocusInternal();
2198 }
2199
2200 LOGV("cancelAutoFocus X");
2201 return rc;
2202}
2203
2204void QualcommCameraHardware::runSnapshotThread(void *data)
2205{
2206 LOGV("runSnapshotThread E");
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002207 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
2208 if (native_start_snapshot(mCameraControlFd))
2209 receiveRawPicture();
2210 else
2211 LOGE("main: native_start_snapshot failed!");
2212 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
2213 if(native_start_raw_snapshot(mCameraControlFd)){
2214 receiveRawSnapshot();
2215 } else {
2216 LOGE("main: native_start_raw_snapshot failed!");
2217 }
2218 }
2219
2220 mSnapshotFormat = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002221
2222 mSnapshotThreadWaitLock.lock();
2223 mSnapshotThreadRunning = false;
2224 mSnapshotThreadWait.signal();
2225 mSnapshotThreadWaitLock.unlock();
2226
2227 LOGV("runSnapshotThread X");
2228}
2229
2230void *snapshot_thread(void *user)
2231{
2232 LOGD("snapshot_thread E");
2233 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2234 if (obj != 0) {
2235 obj->runSnapshotThread(user);
2236 }
2237 else LOGW("not starting snapshot thread: the object went away!");
2238 LOGD("snapshot_thread X");
2239 return NULL;
2240}
2241
2242status_t QualcommCameraHardware::takePicture()
2243{
2244 LOGV("takePicture(%d)", mMsgEnabled);
2245 Mutex::Autolock l(&mLock);
2246
2247 // Wait for old snapshot thread to complete.
2248 mSnapshotThreadWaitLock.lock();
2249 while (mSnapshotThreadRunning) {
2250 LOGV("takePicture: waiting for old snapshot thread to complete.");
2251 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
2252 LOGV("takePicture: old snapshot thread completed.");
2253 }
2254
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08002255 if(!strcmp(mDeviceName,"msm7630_surf")) {
2256 /* Store the last frame queued for preview. This
2257 * shall be used as postview */
2258 storePreviewFrameForPostview();
2259 }
2260
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002261 //mSnapshotFormat is protected by mSnapshotThreadWaitLock
2262 if(mParameters.getPictureFormat() != 0 &&
2263 !strcmp(mParameters.getPictureFormat(),
2264 CameraParameters::PIXEL_FORMAT_RAW))
2265 mSnapshotFormat = PICTURE_FORMAT_RAW;
2266 else
2267 mSnapshotFormat = PICTURE_FORMAT_JPEG;
2268
2269 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
2270 if(!native_prepare_snapshot(mCameraControlFd)) {
2271 mSnapshotThreadWaitLock.unlock();
2272 return UNKNOWN_ERROR;
2273 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002274 }
2275
2276 stopPreviewInternal();
2277
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002278 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
2279 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
2280 LOGE("initRaw failed. Not taking picture.");
2281 mSnapshotThreadWaitLock.unlock();
2282 return UNKNOWN_ERROR;
2283 }
2284 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
2285 if(!initRawSnapshot()){
2286 LOGE("initRawSnapshot failed. Not taking picture.");
2287 mSnapshotThreadWaitLock.unlock();
2288 return UNKNOWN_ERROR;
2289 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002290 }
2291
2292 mShutterLock.lock();
2293 mShutterPending = true;
2294 mShutterLock.unlock();
2295
2296 pthread_attr_t attr;
2297 pthread_attr_init(&attr);
2298 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2299 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
2300 &attr,
2301 snapshot_thread,
2302 NULL);
2303 mSnapshotThreadWaitLock.unlock();
2304
2305 LOGV("takePicture: X");
2306 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
2307}
2308
2309status_t QualcommCameraHardware::cancelPicture()
2310{
2311 status_t rc;
2312 LOGV("cancelPicture: E");
2313 rc = native_stop_snapshot(mCameraControlFd) ? NO_ERROR : UNKNOWN_ERROR;
2314 LOGV("cancelPicture: X: %d", rc);
2315 return rc;
2316}
2317
2318status_t QualcommCameraHardware::setParameters(const CameraParameters& params)
2319{
2320 LOGV("setParameters: E params = %p", &params);
2321
2322 Mutex::Autolock l(&mLock);
2323 status_t rc, final_rc = NO_ERROR;
2324
2325 if ((rc = setPreviewSize(params))) final_rc = rc;
2326 if ((rc = setPictureSize(params))) final_rc = rc;
2327 if ((rc = setJpegQuality(params))) final_rc = rc;
2328 if ((rc = setAntibanding(params))) final_rc = rc;
2329 if ((rc = setEffect(params))) final_rc = rc;
Apurva Rajguru55562b02009-12-03 12:25:35 -08002330 if ((rc = setAutoExposure(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002331 if ((rc = setWhiteBalance(params))) final_rc = rc;
2332 if ((rc = setFlash(params))) final_rc = rc;
2333 if ((rc = setGpsLocation(params))) final_rc = rc;
2334 if ((rc = setRotation(params))) final_rc = rc;
2335 if ((rc = setZoom(params))) final_rc = rc;
2336 if ((rc = setFocusMode(params))) final_rc = rc;
2337 if ((rc = setOrientation(params))) final_rc = rc;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302338 if ((rc = setBrightness(params))) final_rc = rc;
2339 if ((rc = setLensshadeValue(params))) final_rc = rc;
2340 if ((rc = setISOValue(params))) final_rc = rc;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002341 if ((rc = setPictureFormat(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002342
2343 LOGV("setParameters: X");
2344 return final_rc;
2345}
2346
2347CameraParameters QualcommCameraHardware::getParameters() const
2348{
2349 LOGV("getParameters: EX");
2350 return mParameters;
2351}
2352
2353status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
2354 int32_t arg2)
2355{
2356 LOGV("sendCommand: EX");
2357 return BAD_VALUE;
2358}
2359
2360extern "C" sp<CameraHardwareInterface> openCameraHardware()
2361{
2362 LOGV("openCameraHardware: call createInstance");
2363 return QualcommCameraHardware::createInstance();
2364}
2365
2366wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
2367
2368// If the hardware already exists, return a strong pointer to the current
2369// object. If not, create a new hardware object, put it in the singleton,
2370// and return it.
2371sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
2372{
2373 LOGD("createInstance: E");
2374
2375 Mutex::Autolock lock(&singleton_lock);
2376
2377 // Wait until the previous release is done.
2378 while (singleton_releasing) {
2379 LOGD("Wait for previous release.");
2380 singleton_wait.wait(singleton_lock);
2381 }
2382
2383 if (singleton != 0) {
2384 sp<CameraHardwareInterface> hardware = singleton.promote();
2385 if (hardware != 0) {
2386 LOGD("createInstance: X return existing hardware=%p", &(*hardware));
2387 return hardware;
2388 }
2389 }
2390
2391 {
2392 struct stat st;
2393 int rc = stat("/dev/oncrpc", &st);
2394 if (rc < 0) {
2395 LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
2396 return NULL;
2397 }
2398 }
2399
2400 QualcommCameraHardware *cam = new QualcommCameraHardware();
2401 sp<QualcommCameraHardware> hardware(cam);
2402 singleton = hardware;
2403
2404 if (!cam->startCamera()) {
2405 LOGE("%s: startCamera failed!", __FUNCTION__);
2406 return NULL;
2407 }
2408
2409 cam->initDefaultParameters();
2410 LOGD("createInstance: X created hardware=%p", &(*hardware));
2411 return hardware;
2412}
2413
2414// For internal use only, hence the strong pointer to the derived type.
2415sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
2416{
2417 sp<CameraHardwareInterface> hardware = singleton.promote();
2418 if (hardware != 0) {
2419 // LOGV("getInstance: X old instance of hardware");
2420 return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
2421 } else {
2422 LOGV("getInstance: X new instance of hardware");
2423 return sp<QualcommCameraHardware>();
2424 }
2425}
2426
Mohan Kandra284966d2010-01-05 13:39:15 -08002427bool QualcommCameraHardware::native_zoom_image(int srcFd, int dstFd, int offSet, common_crop_t *crop)
2428{
2429 int result = 0;
2430 struct mdp_blit_req *e;
2431 struct timeval td1, td2;
2432
2433 int previewWidth, previewHeight;
2434 mParameters.getPreviewSize(&previewWidth, &previewHeight);
2435
2436 /* Initialize yuv structure */
2437 zoomImage.list.count = 1;
2438
2439 e = &zoomImage.list.req[0];
2440
2441 e->src.width = previewWidth;
2442 e->src.height = previewHeight;
2443 e->src.format = MDP_Y_CBCR_H2V2;
2444 e->src.offset = offSet;
2445 e->src.memory_id = srcFd;
2446
2447 e->dst.width = previewWidth;
2448 e->dst.height = previewHeight;
2449 e->dst.format = MDP_Y_CBCR_H2V2;
2450 e->dst.offset = offSet;
2451 e->dst.memory_id = dstFd;
2452
2453 LOGV(" Source FD = %d, Destination FD = %d offSet = %d",srcFd, dstFd, offSet);
2454
2455 e->transp_mask = 0xffffffff;
2456 e->flags = 0;
2457 e->alpha = 0xff;
2458 if (crop->in2_w != 0 || crop->in2_h != 0) {
2459 e->src_rect.x = (crop->out2_w - crop->in2_w + 1) / 2 - 1;
2460 e->src_rect.y = (crop->out2_h - crop->in2_h + 1) / 2 - 1;
2461 e->src_rect.w = crop->in2_w;
2462 e->src_rect.h = crop->in2_h;
2463 } else {
2464 e->src_rect.x = 0;
2465 e->src_rect.y = 0;
2466 e->src_rect.w = previewWidth;
2467 e->src_rect.h = previewHeight;
2468 }
2469 LOGV(" native_zoom : SRC_RECT : x,y = %d,%d \t w,h = %d, %d",
2470 e->src_rect.x, e->src_rect.y, e->src_rect.w, e->src_rect.h);
2471
2472 e->dst_rect.x = 0;
2473 e->dst_rect.y = 0;
2474 e->dst_rect.w = previewWidth;
2475 e->dst_rect.h = previewHeight;
2476
2477 result = ioctl(fb_fd, MSMFB_BLIT, &zoomImage.list);
2478 if (result < 0) {
2479 LOGE("MSM_FBIOBLT failed! line=%d\n", __LINE__);
2480 return FALSE;
2481 }
2482 return TRUE;
2483}
2484
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002485void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
2486{
2487// LOGV("receivePreviewFrame E");
2488
2489 if (!mCameraRunning) {
2490 LOGE("ignoring preview callback--camera has been stopped");
2491 return;
2492 }
2493
2494 mCallbackLock.lock();
2495 int msgEnabled = mMsgEnabled;
2496 data_callback pcb = mDataCallback;
2497 void *pdata = mCallbackCookie;
2498 data_callback_timestamp rcb = mDataCallbackTimestamp;
2499 void *rdata = mCallbackCookie;
2500 mCallbackLock.unlock();
2501
2502 // Find the offset within the heap of the current buffer.
Mohan Kandra284966d2010-01-05 13:39:15 -08002503 ssize_t offset_addr =
2504 (ssize_t)frame->buffer - (ssize_t)mCameraPreviewHeap->mHeap->base();
2505 ssize_t offset = offset_addr / mCameraPreviewHeap->mAlignedBufferSize;
2506
2507 common_crop_t *crop = (common_crop_t *) (frame->cropinfo);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002508
2509 mInPreviewCallback = true;
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08002510 if(mUseOverlay) {
2511 if(mOverlay != NULL) {
2512 mOverlayLock.lock();
2513 mOverlay->setFd(mCameraPreviewHeap->mHeap->getHeapID());
2514 if (crop->in2_w != 0 || crop->in2_h != 0) {
2515 zoomCropInfo.x = (crop->out2_w - crop->in2_w + 1) / 2 - 1;
2516 zoomCropInfo.y = (crop->out2_h - crop->in2_h + 1) / 2 - 1;
2517 zoomCropInfo.w = crop->in2_w;
2518 zoomCropInfo.h = crop->in2_h;
2519 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
2520 zoomCropInfo.w, zoomCropInfo.h);
2521 }
2522 mOverlay->queueBuffer((void *)offset_addr);
2523 mLastQueuedFrame = (void *)frame->buffer;
2524 mOverlayLock.unlock();
2525 }
Mohan Kandra284966d2010-01-05 13:39:15 -08002526 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
2527 pcb(CAMERA_MSG_PREVIEW_FRAME, mCameraPreviewHeap->mBuffers[offset],
2528 pdata);
2529 } else {
2530 if( !native_zoom_image(mCameraPreviewHeap->mHeap->getHeapID(),
2531 mPreviewHeap->mHeap->getHeapID(),
2532 offset_addr, crop)) {
2533 LOGE(" Error while doing MDP zoom ");
2534 }
2535 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
2536 pcb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap->mBuffers[offset],
2537 pdata);
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08002538 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002539 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
Mohan Kandra284966d2010-01-05 13:39:15 -08002540 rcb(systemTime(), CAMERA_MSG_VIDEO_FRAME, mCameraPreviewHeap->mBuffers[offset], rdata);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002541 Mutex::Autolock rLock(&mRecordFrameLock);
2542 if (mReleasedRecordingFrame != true) {
2543 LOGV("block waiting for frame release");
2544 mRecordWait.wait(mRecordFrameLock);
2545 LOGV("frame released, continuing");
2546 }
2547 mReleasedRecordingFrame = false;
2548 }
2549 mInPreviewCallback = false;
2550
2551// LOGV("receivePreviewFrame X");
2552}
2553
2554status_t QualcommCameraHardware::startRecording()
2555{
2556 LOGV("startRecording E");
2557 Mutex::Autolock l(&mLock);
2558 mReleasedRecordingFrame = false;
2559 return startPreviewInternal();
2560}
2561
2562void QualcommCameraHardware::stopRecording()
2563{
2564 LOGV("stopRecording: E");
2565 Mutex::Autolock l(&mLock);
2566 {
2567 mRecordFrameLock.lock();
2568 mReleasedRecordingFrame = true;
2569 mRecordWait.signal();
2570 mRecordFrameLock.unlock();
2571
2572 if(mDataCallback && (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
2573 LOGV("stopRecording: X, preview still in progress");
2574 return;
2575 }
2576 }
2577
2578 stopPreviewInternal();
2579 LOGV("stopRecording: X");
2580}
2581
2582void QualcommCameraHardware::releaseRecordingFrame(
2583 const sp<IMemory>& mem __attribute__((unused)))
2584{
2585 LOGV("releaseRecordingFrame E");
2586 Mutex::Autolock rLock(&mRecordFrameLock);
2587 mReleasedRecordingFrame = true;
2588 mRecordWait.signal();
2589 LOGV("releaseRecordingFrame X");
2590}
2591
2592bool QualcommCameraHardware::recordingEnabled()
2593{
2594 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
2595}
2596
2597void QualcommCameraHardware::notifyShutter(common_crop_t *crop)
2598{
2599 mShutterLock.lock();
2600 image_rect_type size;
2601
2602 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
2603 LOGV("out2_w=%d, out2_h=%d, in2_w=%d, in2_h=%d",
2604 crop->out2_w, crop->out2_h, crop->in2_w, crop->in2_h);
2605 LOGV("out1_w=%d, out1_h=%d, in1_w=%d, in1_h=%d",
2606 crop->out1_w, crop->out1_h, crop->in1_w, crop->in1_h);
2607
2608 // To workaround a bug in MDP which happens if either
2609 // dimension > 2048, we display the thumbnail instead.
2610 mDisplayHeap = mRawHeap;
2611 if (crop->in1_w == 0 || crop->in1_h == 0) {
2612 // Full size
2613 size.width = mDimension.picture_width;
2614 size.height = mDimension.picture_height;
2615 if (size.width > 2048 || size.height > 2048) {
2616 size.width = mDimension.ui_thumbnail_width;
2617 size.height = mDimension.ui_thumbnail_height;
2618 mDisplayHeap = mThumbnailHeap;
2619 }
2620 } else {
2621 // Cropped
2622 size.width = crop->in2_w & ~1;
2623 size.height = crop->in2_h & ~1;
2624 if (size.width > 2048 || size.height > 2048) {
2625 size.width = crop->in1_w & ~1;
2626 size.height = crop->in1_h & ~1;
2627 mDisplayHeap = mThumbnailHeap;
2628 }
2629 }
2630
2631 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
2632 mCallbackCookie);
2633 mShutterPending = false;
2634 }
2635 mShutterLock.unlock();
2636}
2637
2638static void receive_shutter_callback(common_crop_t *crop)
2639{
2640 LOGV("receive_shutter_callback: E");
2641 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2642 if (obj != 0) {
2643 obj->notifyShutter(crop);
2644 }
2645 LOGV("receive_shutter_callback: X");
2646}
2647
2648// Crop the picture in place.
2649static void crop_yuv420(uint32_t width, uint32_t height,
2650 uint32_t cropped_width, uint32_t cropped_height,
2651 uint8_t *image)
2652{
2653 uint32_t i, x, y;
2654 uint8_t* chroma_src, *chroma_dst;
2655
2656 // Calculate the start position of the cropped area.
2657 x = (width - cropped_width) / 2;
2658 y = (height - cropped_height) / 2;
2659 x &= ~1;
2660 y &= ~1;
2661
2662 // Copy luma component.
2663 for(i = 0; i < cropped_height; i++)
2664 memcpy(image + i * cropped_width,
2665 image + width * (y + i) + x,
2666 cropped_width);
2667
2668 chroma_src = image + width * height;
2669 chroma_dst = image + cropped_width * cropped_height;
2670
2671 // Copy chroma components.
2672 cropped_height /= 2;
2673 y /= 2;
2674 for(i = 0; i < cropped_height; i++)
2675 memcpy(chroma_dst + i * cropped_width,
2676 chroma_src + width * (y + i) + x,
2677 cropped_width);
2678}
2679
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002680
2681void QualcommCameraHardware::receiveRawSnapshot(){
2682 LOGV("receiveRawSnapshot E");
2683
2684 Mutex::Autolock cbLock(&mCallbackLock);
2685
2686 notifyShutter(&mCrop);
2687
2688 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2689
2690 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
2691 LOGE("receiveRawSnapshot X: native_get_picture failed!");
2692 return;
2693 }
2694
2695 //Create a Ashmem heap to copy data from PMem heap for application layer
2696 if(mRawSnapshotAshmemHeap != NULL){
2697 LOGV("receiveRawSnapshot: clearing old mRawSnapShotAshmemHeap.");
2698 mRawSnapshotAshmemHeap.clear();
2699 }
2700 mRawSnapshotAshmemHeap = new AshmemPool(
2701 mRawSnapShotPmemHeap->mBufferSize,
2702 mRawSnapShotPmemHeap->mNumBuffers,
2703 mRawSnapShotPmemHeap->mFrameSize,
2704 "raw ashmem snapshot camera"
2705 );
2706
2707 if(!mRawSnapshotAshmemHeap->initialized()){
2708 LOGE("receiveRawSnapshot X: error initializing mRawSnapshotHeap");
2709 deinitRawSnapshot();
2710 return;
2711 }
2712
2713 memcpy(mRawSnapshotAshmemHeap->mHeap->base(),
2714 mRawSnapShotPmemHeap->mHeap->base(),
2715 mRawSnapShotPmemHeap->mHeap->getSize());
2716
2717 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mRawSnapshotAshmemHeap->mBuffers[0],
2718 mCallbackCookie);
2719
2720 }
2721
2722 //cleanup
2723 deinitRawSnapshot();
2724
2725 LOGV("receiveRawSnapshot X");
2726}
2727
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002728void QualcommCameraHardware::receiveRawPicture()
2729{
2730 LOGV("receiveRawPicture: E");
2731
2732 Mutex::Autolock cbLock(&mCallbackLock);
2733 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)) {
2734 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
2735 LOGE("getPicture failed!");
2736 return;
2737 }
2738 mCrop.in1_w &= ~1;
2739 mCrop.in1_h &= ~1;
2740 mCrop.in2_w &= ~1;
2741 mCrop.in2_h &= ~1;
2742
2743 // By the time native_get_picture returns, picture is taken. Call
2744 // shutter callback if cam config thread has not done that.
2745 notifyShutter(&mCrop);
2746
2747 // Crop the image if zoomed.
2748 if (mCrop.in2_w != 0 && mCrop.in2_h != 0) {
2749 crop_yuv420(mCrop.out2_w, mCrop.out2_h, mCrop.in2_w, mCrop.in2_h,
2750 (uint8_t *)mRawHeap->mHeap->base());
2751 crop_yuv420(mCrop.out1_w, mCrop.out1_h, mCrop.in1_w, mCrop.in1_h,
2752 (uint8_t *)mThumbnailHeap->mHeap->base());
2753 // We do not need jpeg encoder to upscale the image. Set the new
2754 // dimension for encoder.
2755 mDimension.orig_picture_dx = mCrop.in2_w;
2756 mDimension.orig_picture_dy = mCrop.in2_h;
2757 mDimension.thumbnail_width = mCrop.in1_w;
2758 mDimension.thumbnail_height = mCrop.in1_h;
2759 memset(&mCrop, 0, sizeof(mCrop));
2760 }
2761
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08002762 if( mUseOverlay && (mOverlay != NULL) ) {
2763 mOverlay->setFd(mPostViewHeap->mHeap->getHeapID());
2764 if( zoomCropInfo.w !=0 && zoomCropInfo.h !=0) {
2765 LOGD(" zoomCropInfo non-zero, setting crop ");
2766 mOverlay->setCrop(zoomCropInfo.x, zoomCropInfo.y,
2767 zoomCropInfo.w, zoomCropInfo.h);
2768 }
2769 LOGD(" Queueing Postview for display ");
2770 mOverlay->queueBuffer((void *)0);
2771 }
2772
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002773 mDataCallback(CAMERA_MSG_RAW_IMAGE, mDisplayHeap->mBuffers[0],
2774 mCallbackCookie);
2775 }
2776 else LOGV("Raw-picture callback was canceled--skipping.");
2777
2778 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2779 mJpegSize = 0;
2780 if (LINK_jpeg_encoder_init()) {
2781 if(native_jpeg_encode()) {
2782 LOGV("receiveRawPicture: X (success)");
2783 return;
2784 }
2785 LOGE("jpeg encoding failed");
2786 }
2787 else LOGE("receiveRawPicture X: jpeg_encoder_init failed.");
2788 }
2789 else LOGV("JPEG callback is NULL, not encoding image.");
2790 deinitRaw();
2791 LOGV("receiveRawPicture: X");
2792}
2793
2794void QualcommCameraHardware::receiveJpegPictureFragment(
2795 uint8_t *buff_ptr, uint32_t buff_size)
2796{
2797 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
2798 remaining -= mJpegSize;
2799 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
2800
2801 LOGV("receiveJpegPictureFragment size %d", buff_size);
2802 if (buff_size > remaining) {
2803 LOGE("receiveJpegPictureFragment: size %d exceeds what "
2804 "remains in JPEG heap (%d), truncating",
2805 buff_size,
2806 remaining);
2807 buff_size = remaining;
2808 }
2809 memcpy(base + mJpegSize, buff_ptr, buff_size);
2810 mJpegSize += buff_size;
2811}
2812
2813void QualcommCameraHardware::receiveJpegPicture(void)
2814{
2815 LOGV("receiveJpegPicture: E image (%d uint8_ts out of %d)",
2816 mJpegSize, mJpegHeap->mBufferSize);
2817 Mutex::Autolock cbLock(&mCallbackLock);
2818
2819 int index = 0, rc;
2820
2821 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2822 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
2823 // that the JPEG image's size will probably change from one snapshot
2824 // to the next, so we cannot reuse the MemoryBase object.
2825 sp<MemoryBase> buffer = new
2826 MemoryBase(mJpegHeap->mHeap,
2827 index * mJpegHeap->mBufferSize +
2828 0,
2829 mJpegSize);
2830 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
2831 buffer = NULL;
2832 }
2833 else LOGV("JPEG callback was cancelled--not delivering image.");
2834
2835 LINK_jpeg_encoder_join();
2836 deinitRaw();
2837
2838 LOGV("receiveJpegPicture: X callback done.");
2839}
2840
2841bool QualcommCameraHardware::previewEnabled()
2842{
2843 return mCameraRunning && mDataCallback && (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME);
2844}
2845
2846status_t QualcommCameraHardware::setPreviewSize(const CameraParameters& params)
2847{
2848 int width, height;
2849 params.getPreviewSize(&width, &height);
2850 LOGV("requested preview size %d x %d", width, height);
2851
2852 // Validate the preview size
2853 for (size_t i = 0; i < PREVIEW_SIZE_COUNT; ++i) {
2854 if (width == preview_sizes[i].width
2855 && height == preview_sizes[i].height) {
2856 mParameters.setPreviewSize(width, height);
2857 mDimension.display_width = width;
2858 mDimension.display_height = height;
2859 return NO_ERROR;
2860 }
2861 }
2862 LOGE("Invalid preview size requested: %dx%d", width, height);
2863 return BAD_VALUE;
2864}
2865
2866status_t QualcommCameraHardware::setPictureSize(const CameraParameters& params)
2867{
2868 int width, height;
2869 params.getPictureSize(&width, &height);
2870 LOGV("requested picture size %d x %d", width, height);
2871
2872 // Validate the picture size
Srinivasan Kannan3b9e8df2009-12-05 12:21:46 -08002873 for (int i = 0; i < supportedPictureSizesCount; ++i) {
2874 if (width == picture_sizes_ptr[i].width
2875 && height == picture_sizes_ptr[i].height) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002876 mParameters.setPictureSize(width, height);
2877 mDimension.picture_width = width;
2878 mDimension.picture_height = height;
2879 return NO_ERROR;
2880 }
2881 }
2882 LOGE("Invalid picture size requested: %dx%d", width, height);
2883 return BAD_VALUE;
2884}
2885
2886status_t QualcommCameraHardware::setJpegQuality(const CameraParameters& params) {
2887 status_t rc = NO_ERROR;
2888 int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
2889 if (quality > 0 && quality <= 100) {
2890 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
2891 } else {
2892 LOGE("Invalid jpeg quality=%d", quality);
2893 rc = BAD_VALUE;
2894 }
2895
2896 quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
2897 if (quality > 0 && quality <= 100) {
2898 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
2899 } else {
2900 LOGE("Invalid jpeg thumbnail quality=%d", quality);
2901 rc = BAD_VALUE;
2902 }
2903 return rc;
2904}
2905
2906status_t QualcommCameraHardware::setEffect(const CameraParameters& params)
2907{
2908 const char *str = params.get(CameraParameters::KEY_EFFECT);
2909 if (str != NULL) {
2910 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
2911 if (value != NOT_FOUND) {
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08002912 if(!strcmp(sensorType->name, "2mp") && (value != CAMERA_EFFECT_OFF)
2913 &&(value != CAMERA_EFFECT_MONO) && (value != CAMERA_EFFECT_NEGATIVE)
2914 &&(value != CAMERA_EFFECT_SOLARIZE) && (value != CAMERA_EFFECT_SEPIA)) {
2915 LOGE("Special effect parameter is not supported for this sensor");
2916 return NO_ERROR;
2917 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002918 mParameters.set(CameraParameters::KEY_EFFECT, str);
2919 bool ret = native_set_parm(CAMERA_SET_PARM_EFFECT, sizeof(value),
2920 (void *)&value);
2921 return ret ? NO_ERROR : UNKNOWN_ERROR;
2922 }
2923 }
2924 LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
2925 return BAD_VALUE;
2926}
2927
Apurva Rajguru55562b02009-12-03 12:25:35 -08002928status_t QualcommCameraHardware::setAutoExposure(const CameraParameters& params)
2929{
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08002930 if(!strcmp(sensorType->name, "2mp")) {
2931 LOGE("Auto Exposure not supported for this sensor");
2932 return NO_ERROR;
2933 }
Apurva Rajguru55562b02009-12-03 12:25:35 -08002934 const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
2935 if (str != NULL) {
2936 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
2937 if (value != NOT_FOUND) {
2938 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
2939 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE, sizeof(value),
2940 (void *)&value);
2941 return ret ? NO_ERROR : UNKNOWN_ERROR;
2942 }
2943 }
2944 LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
2945 return BAD_VALUE;
2946}
2947
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302948status_t QualcommCameraHardware::setBrightness(const CameraParameters& params) {
2949 int brightness = params.getInt("luma-adaptation");
2950 if (mBrightness != brightness) {
2951 LOGV(" new brightness value : %d ", brightness);
2952 mBrightness = brightness;
2953
2954 bool ret = native_set_parm(CAMERA_SET_PARM_BRIGHTNESS, sizeof(mBrightness),
2955 (void *)&mBrightness);
2956 return ret ? NO_ERROR : UNKNOWN_ERROR;
2957 } else {
2958 return NO_ERROR;
2959 }
2960}
2961
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002962status_t QualcommCameraHardware::setWhiteBalance(const CameraParameters& params)
2963{
2964 const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
2965 if (str != NULL) {
2966 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
2967 if (value != NOT_FOUND) {
2968 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
2969 bool ret = native_set_parm(CAMERA_SET_PARM_WB, sizeof(value),
2970 (void *)&value);
2971 return ret ? NO_ERROR : UNKNOWN_ERROR;
2972 }
2973 }
2974 LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
2975 return BAD_VALUE;
2976}
2977
2978status_t QualcommCameraHardware::setFlash(const CameraParameters& params)
2979{
2980 if (!mSensorInfo.flash_enabled) {
2981 LOGV("%s: flash not supported", __FUNCTION__);
2982 return NO_ERROR;
2983 }
2984
2985 const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
2986 if (str != NULL) {
2987 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
2988 if (value != NOT_FOUND) {
2989 mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
2990 bool ret = native_set_parm(CAMERA_SET_PARM_LED_MODE,
2991 sizeof(value), (void *)&value);
2992 return ret ? NO_ERROR : UNKNOWN_ERROR;
2993 }
2994 }
2995 LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
2996 return BAD_VALUE;
2997}
2998
2999status_t QualcommCameraHardware::setAntibanding(const CameraParameters& params)
3000{
Srinivasan Kannan2229d272010-01-05 14:58:28 -08003001 if(!strcmp(sensorType->name, "2mp")) {
3002 LOGE("Parameter AntiBanding is not supported for this sensor");
3003 return NO_ERROR;
3004 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003005 const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
3006 if (str != NULL) {
3007 int value = (camera_antibanding_type)attr_lookup(
3008 antibanding, sizeof(antibanding) / sizeof(str_map), str);
3009 if (value != NOT_FOUND) {
3010 camera_antibanding_type temp = (camera_antibanding_type) value;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003011 mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
Srinivasan Kannan2229d272010-01-05 14:58:28 -08003012 bool ret;
3013 if (temp == CAMERA_ANTIBANDING_AUTO) {
3014 ret = native_set_parm(CAMERA_ENABLE_AFD,
3015 0, NULL);
3016 } else {
3017 ret = native_set_parm(CAMERA_SET_PARM_ANTIBANDING,
3018 sizeof(camera_antibanding_type), (void *)&temp);
3019 }
3020 return ret ? NO_ERROR : UNKNOWN_ERROR;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003021 }
3022 }
3023 LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
3024 return BAD_VALUE;
3025}
3026
Nishant Panditc8c1ee72009-12-03 16:24:02 +05303027status_t QualcommCameraHardware::setLensshadeValue(const CameraParameters& params)
3028{
Mohan Kandra93f1bfb2009-12-15 16:55:33 -08003029 if(!strcmp(sensorType->name, "2mp")) {
3030 LOGE("Parameter Rolloff is not supported for this sensor");
3031 return NO_ERROR;
3032 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +05303033 const char *str = params.get(CameraParameters::KEY_LENSSHADE);
3034 if (str != NULL) {
3035 int value = attr_lookup(lensshade,
3036 sizeof(lensshade) / sizeof(str_map), str);
3037 if (value != NOT_FOUND) {
3038 int8_t temp = (int8_t)value;
3039 mParameters.set(CameraParameters::KEY_LENSSHADE, str);
3040 native_set_parm(CAMERA_SET_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
3041 return NO_ERROR;
3042 }
3043 }
3044 LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
3045 return BAD_VALUE;
3046}
3047
3048status_t QualcommCameraHardware::setISOValue(const CameraParameters& params) {
3049 const char *str = params.get(CameraParameters::KEY_ISO_MODE);
3050 if (str != NULL) {
3051 int value = (camera_iso_mode_type)attr_lookup(
3052 iso, sizeof(iso) / sizeof(str_map), str);
3053 if (value != NOT_FOUND) {
3054 camera_iso_mode_type temp = (camera_iso_mode_type) value;
3055 mParameters.set(CameraParameters::KEY_ISO_MODE, str);
3056 native_set_parm(CAMERA_SET_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
3057 return NO_ERROR;
3058 }
3059 }
3060 LOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
3061 return BAD_VALUE;
3062}
3063
3064
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003065status_t QualcommCameraHardware::setGpsLocation(const CameraParameters& params)
3066{
3067 const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
3068 if (latitude) {
3069 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
3070 }
3071
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08003072 const char *latitudeRef = params.get(CameraParameters::KEY_GPS_LATITUDE_REF);
3073 if (latitudeRef) {
3074 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
3075 }
3076
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003077 const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
3078 if (longitude) {
3079 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
3080 }
3081
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08003082 const char *longitudeRef = params.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
3083 if (longitudeRef) {
3084 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
3085 }
3086
3087 const char *altitudeRef = params.get(CameraParameters::KEY_GPS_ALTITUDE_REF);
3088 if (altitudeRef) {
3089 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
3090 }
3091
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003092 const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
3093 if (altitude) {
3094 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
3095 }
3096
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08003097 const char *status = params.get(CameraParameters::KEY_GPS_STATUS);
3098 if (status) {
3099 mParameters.set(CameraParameters::KEY_GPS_STATUS, status);
3100 }
3101
3102 const char *dateTime = params.get(CameraParameters::KEY_EXIF_DATETIME);
3103 if (dateTime) {
3104 mParameters.set(CameraParameters::KEY_EXIF_DATETIME, dateTime);
3105 }
3106
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003107 const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
3108 if (timestamp) {
3109 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
3110 }
3111 return NO_ERROR;
3112}
3113
3114status_t QualcommCameraHardware::setRotation(const CameraParameters& params)
3115{
3116 status_t rc = NO_ERROR;
3117 int rotation = params.getInt(CameraParameters::KEY_ROTATION);
3118 if (rotation != NOT_FOUND) {
3119 if (rotation == 0 || rotation == 90 || rotation == 180
3120 || rotation == 270) {
3121 mParameters.set(CameraParameters::KEY_ROTATION, rotation);
3122 } else {
3123 LOGE("Invalid rotation value: %d", rotation);
3124 rc = BAD_VALUE;
3125 }
3126 }
3127 return rc;
3128}
3129
3130status_t QualcommCameraHardware::setZoom(const CameraParameters& params)
3131{
3132 status_t rc = NO_ERROR;
3133 // No matter how many different zoom values the driver can provide, HAL
3134 // provides applictations the same number of zoom levels. The maximum driver
3135 // zoom value depends on sensor output (VFE input) and preview size (VFE
3136 // output) because VFE can only crop and cannot upscale. If the preview size
3137 // is bigger, the maximum zoom ratio is smaller. However, we want the
3138 // zoom ratio of each zoom level is always the same whatever the preview
3139 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
3140 // we need to have a fixed maximum zoom value and do read it from the
3141 // driver.
Mohan Kandra284966d2010-01-05 13:39:15 -08003142 static const int ZOOM_STEP = 1;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003143 int32_t zoom_level = params.getInt("zoom");
3144
Mohan Kandra284966d2010-01-05 13:39:15 -08003145 LOGV("Set zoom=%d", zoom_level);
3146 if(zoom_level >= 0 && zoom_level <= mMaxZoom) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003147 mParameters.set("zoom", zoom_level);
3148 int32_t zoom_value = ZOOM_STEP * zoom_level;
3149 bool ret = native_set_parm(CAMERA_SET_PARM_ZOOM,
3150 sizeof(zoom_value), (void *)&zoom_value);
3151 rc = ret ? NO_ERROR : UNKNOWN_ERROR;
3152 } else {
3153 rc = BAD_VALUE;
3154 }
3155
3156 return rc;
3157}
3158
3159status_t QualcommCameraHardware::setFocusMode(const CameraParameters& params)
3160{
3161 const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
3162 if (str != NULL) {
3163 int32_t value = attr_lookup(focus_modes,
3164 sizeof(focus_modes) / sizeof(str_map), str);
3165 if (value != NOT_FOUND) {
3166 mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
3167 // Focus step is reset to infinity when preview is started. We do
3168 // not need to do anything now.
3169 return NO_ERROR;
3170 }
3171 }
3172 LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
3173 return BAD_VALUE;
3174}
3175
3176status_t QualcommCameraHardware::setOrientation(const CameraParameters& params)
3177{
3178 const char *str = params.get("orientation");
3179
3180 if (str != NULL) {
3181 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
3182 // Camera service needs this to decide if the preview frames and raw
3183 // pictures should be rotated.
3184 mParameters.set("orientation", str);
3185 } else {
3186 LOGE("Invalid orientation value: %s", str);
3187 return BAD_VALUE;
3188 }
3189 }
3190 return NO_ERROR;
3191}
3192
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08003193status_t QualcommCameraHardware::setPictureFormat(const CameraParameters& params)
3194{
3195 const char * str = params.get(CameraParameters::KEY_PICTURE_FORMAT);
3196
3197 if(str != NULL){
3198 int32_t value = attr_lookup(picture_formats,
3199 sizeof(picture_formats) / sizeof(str_map), str);
3200 if(value != NOT_FOUND){
3201 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT, str);
3202 } else {
3203 LOGE("Invalid Picture Format value: %s", str);
3204 return BAD_VALUE;
3205 }
3206 }
3207 return NO_ERROR;
3208}
3209
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003210QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
3211 int frame_size,
3212 const char *name) :
3213 mBufferSize(buffer_size),
3214 mNumBuffers(num_buffers),
3215 mFrameSize(frame_size),
3216 mBuffers(NULL), mName(name)
3217{
3218 int page_size_minus_1 = getpagesize() - 1;
3219 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
3220}
3221
3222void QualcommCameraHardware::MemPool::completeInitialization()
3223{
3224 // If we do not know how big the frame will be, we wait to allocate
3225 // the buffers describing the individual frames until we do know their
3226 // size.
3227
3228 if (mFrameSize > 0) {
3229 mBuffers = new sp<MemoryBase>[mNumBuffers];
3230 for (int i = 0; i < mNumBuffers; i++) {
3231 mBuffers[i] = new
3232 MemoryBase(mHeap,
3233 i * mAlignedBufferSize,
3234 mFrameSize);
3235 }
3236 }
3237}
3238
3239QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
3240 int frame_size,
3241 const char *name) :
3242 QualcommCameraHardware::MemPool(buffer_size,
3243 num_buffers,
3244 frame_size,
3245 name)
3246{
3247 LOGV("constructing MemPool %s backed by ashmem: "
3248 "%d frames @ %d uint8_ts, "
3249 "buffer size %d",
3250 mName,
3251 num_buffers, frame_size, buffer_size);
3252
3253 int page_mask = getpagesize() - 1;
3254 int ashmem_size = buffer_size * num_buffers;
3255 ashmem_size += page_mask;
3256 ashmem_size &= ~page_mask;
3257
3258 mHeap = new MemoryHeapBase(ashmem_size);
3259
3260 completeInitialization();
3261}
3262
3263static bool register_buf(int camfd,
3264 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08003265 int frame_size,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003266 int pmempreviewfd,
3267 uint32_t offset,
3268 uint8_t *buf,
3269 int pmem_type,
3270 bool vfe_can_write,
3271 bool register_buffer = true);
3272
3273QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
3274 int flags,
3275 int camera_control_fd,
3276 int pmem_type,
3277 int buffer_size, int num_buffers,
3278 int frame_size,
3279 const char *name) :
3280 QualcommCameraHardware::MemPool(buffer_size,
3281 num_buffers,
3282 frame_size,
3283 name),
3284 mPmemType(pmem_type),
3285 mCameraControlFd(dup(camera_control_fd))
3286{
3287 LOGV("constructing MemPool %s backed by pmem pool %s: "
3288 "%d frames @ %d bytes, buffer size %d",
3289 mName,
3290 pmem_pool, num_buffers, frame_size,
3291 buffer_size);
3292
3293 LOGV("%s: duplicating control fd %d --> %d",
3294 __FUNCTION__,
3295 camera_control_fd, mCameraControlFd);
3296
3297 // Make a new mmap'ed heap that can be shared across processes.
3298 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
3299 mAlignedSize = mAlignedBufferSize * num_buffers;
3300
3301 sp<MemoryHeapBase> masterHeap =
3302 new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
3303
3304 if (masterHeap->getHeapID() < 0) {
3305 LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
3306 masterHeap.clear();
3307 return;
3308 }
3309
3310 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
3311 if (pmemHeap->getHeapID() >= 0) {
3312 pmemHeap->slap();
3313 masterHeap.clear();
3314 mHeap = pmemHeap;
3315 pmemHeap.clear();
3316
3317 mFd = mHeap->getHeapID();
3318 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
3319 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
3320 pmem_pool,
3321 ::strerror(errno), errno);
3322 mHeap.clear();
3323 return;
3324 }
3325
3326 LOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
3327 pmem_pool,
3328 mFd,
3329 mSize.len);
Mohan Kandra284966d2010-01-05 13:39:15 -08003330 LOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003331 // Unregister preview buffers with the camera drivers. Allow the VFE to write
3332 // to all preview buffers except for the last one.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003333 // Only Register the preview, snapshot and thumbnail buffers with the kernel.
3334 if( (strcmp("preview", mName) != 0)
3335 && (strcmp("postview", mName) != 0) ){
Mohan Kandra284966d2010-01-05 13:39:15 -08003336 for (int cnt = 0; cnt < num_buffers; ++cnt) {
3337 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003338 mBufferSize,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08003339 mFrameSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003340 mHeap->getHeapID(),
3341 mAlignedBufferSize * cnt,
3342 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
3343 pmem_type,
3344 !(cnt == num_buffers - 1 && pmem_type == MSM_PMEM_OUTPUT2));
Mohan Kandra284966d2010-01-05 13:39:15 -08003345 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003346 }
3347
3348 completeInitialization();
3349 }
3350 else LOGE("pmem pool %s error: could not create master heap!",
3351 pmem_pool);
3352}
3353
3354QualcommCameraHardware::PmemPool::~PmemPool()
3355{
3356 LOGV("%s: %s E", __FUNCTION__, mName);
3357 if (mHeap != NULL) {
3358 // Unregister preview buffers with the camera drivers.
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003359 // Only Unregister the preview, snapshot and thumbnail
3360 // buffers with the kernel.
3361 if( (strcmp("preview", mName) != 0)
3362 && (strcmp("postview", mName) != 0) ){
Mohan Kandra284966d2010-01-05 13:39:15 -08003363 for (int cnt = 0; cnt < mNumBuffers; ++cnt) {
3364 register_buf(mCameraControlFd,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003365 mBufferSize,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08003366 mFrameSize,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003367 mHeap->getHeapID(),
3368 mAlignedBufferSize * cnt,
3369 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
3370 mPmemType,
3371 false,
3372 false /* unregister */);
Mohan Kandra284966d2010-01-05 13:39:15 -08003373 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003374 }
3375 }
3376 LOGV("destroying PmemPool %s: closing control fd %d",
3377 mName,
3378 mCameraControlFd);
3379 close(mCameraControlFd);
3380 LOGV("%s: %s X", __FUNCTION__, mName);
3381}
3382
3383QualcommCameraHardware::MemPool::~MemPool()
3384{
3385 LOGV("destroying MemPool %s", mName);
3386 if (mFrameSize > 0)
3387 delete [] mBuffers;
3388 mHeap.clear();
3389 LOGV("destroying MemPool %s completed", mName);
3390}
3391
3392static bool register_buf(int camfd,
3393 int size,
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08003394 int frame_size,
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003395 int pmempreviewfd,
3396 uint32_t offset,
3397 uint8_t *buf,
3398 int pmem_type,
3399 bool vfe_can_write,
3400 bool register_buffer)
3401{
3402 struct msm_pmem_info pmemBuf;
3403
3404 pmemBuf.type = pmem_type;
3405 pmemBuf.fd = pmempreviewfd;
3406 pmemBuf.offset = offset;
3407 pmemBuf.len = size;
3408 pmemBuf.vaddr = buf;
3409 pmemBuf.y_off = 0;
Srinivasan Kannan63bfcea2009-12-18 17:32:12 -08003410 pmemBuf.cbcr_off = PAD_TO_WORD(frame_size * 2 / 3);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003411 pmemBuf.active = vfe_can_write;
3412
3413 LOGV("register_buf: camfd = %d, reg = %d buffer = %p",
3414 camfd, !register_buffer, buf);
3415 if (ioctl(camfd,
3416 register_buffer ?
3417 MSM_CAM_IOCTL_REGISTER_PMEM :
3418 MSM_CAM_IOCTL_UNREGISTER_PMEM,
3419 &pmemBuf) < 0) {
3420 LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM fd %d error %s",
3421 camfd,
3422 strerror(errno));
3423 return false;
3424 }
3425 return true;
3426}
3427
3428status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
3429{
3430 const size_t SIZE = 256;
3431 char buffer[SIZE];
3432 String8 result;
3433 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
3434 result.append(buffer);
3435 if (mName) {
3436 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
3437 result.append(buffer);
3438 }
3439 if (mHeap != 0) {
3440 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
3441 mHeap->getBase(), mHeap->getSize(),
3442 mHeap->getFlags(), mHeap->getDevice());
3443 result.append(buffer);
3444 }
3445 snprintf(buffer, 255,
3446 "buffer size (%d), number of buffers (%d), frame size(%d)",
3447 mBufferSize, mNumBuffers, mFrameSize);
3448 result.append(buffer);
3449 write(fd, result.string(), result.size());
3450 return NO_ERROR;
3451}
3452
3453static void receive_camframe_callback(struct msm_frame *frame)
3454{
3455 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3456 if (obj != 0) {
3457 obj->receivePreviewFrame(frame);
3458 }
3459}
3460
3461static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size)
3462{
3463 LOGV("receive_jpeg_fragment_callback E");
3464 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3465 if (obj != 0) {
3466 obj->receiveJpegPictureFragment(buff_ptr, buff_size);
3467 }
3468 LOGV("receive_jpeg_fragment_callback X");
3469}
3470
3471static void receive_jpeg_callback(jpeg_event_t status)
3472{
3473 LOGV("receive_jpeg_callback E (completion status %d)", status);
3474 if (status == JPEG_EVENT_DONE) {
3475 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3476 if (obj != 0) {
3477 obj->receiveJpegPicture();
3478 }
3479 }
3480 LOGV("receive_jpeg_callback X");
3481}
3482
3483void QualcommCameraHardware::setCallbacks(notify_callback notify_cb,
3484 data_callback data_cb,
3485 data_callback_timestamp data_cb_timestamp,
3486 void* user)
3487{
3488 Mutex::Autolock lock(mLock);
3489 mNotifyCallback = notify_cb;
3490 mDataCallback = data_cb;
3491 mDataCallbackTimestamp = data_cb_timestamp;
3492 mCallbackCookie = user;
3493}
3494
3495void QualcommCameraHardware::enableMsgType(int32_t msgType)
3496{
3497 Mutex::Autolock lock(mLock);
3498 mMsgEnabled |= msgType;
3499}
3500
3501void QualcommCameraHardware::disableMsgType(int32_t msgType)
3502{
3503 Mutex::Autolock lock(mLock);
3504 mMsgEnabled &= ~msgType;
3505}
3506
3507bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
3508{
3509 return (mMsgEnabled & msgType);
3510}
3511
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08003512bool QualcommCameraHardware::useOverlay(void)
3513{
Mohan Kandra284966d2010-01-05 13:39:15 -08003514 if(!strcmp(mDeviceName,"msm7630_surf")) {
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08003515 /* Only 7x30 supports Overlay */
3516 mUseOverlay = TRUE;
3517 } else
3518 mUseOverlay = FALSE;
3519
3520 LOGV(" Using Overlay : %s ", mUseOverlay ? "YES" : "NO" );
3521 return mUseOverlay;
3522}
3523
3524status_t QualcommCameraHardware::setOverlay(const sp<Overlay> &Overlay)
3525{
3526 if( Overlay != NULL) {
3527 LOGV(" Valid overlay object ");
3528 mOverlayLock.lock();
3529 mOverlay = Overlay;
3530 mOverlayLock.unlock();
3531 } else {
3532 LOGE(" Overlay object NULL. returning ");
3533 return UNKNOWN_ERROR;
3534 }
3535 return NO_ERROR;
3536}
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003537
3538void QualcommCameraHardware::receive_camframetimeout(void) {
3539 LOGV("receive_camframetimeout: E");
3540 Mutex::Autolock l(&mCamframeTimeoutLock);
3541 camframe_timeout_flag = TRUE;
3542 LOGV("receive_camframetimeout: X");
3543}
3544
3545static void receive_camframetimeout_callback(void) {
3546 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3547 if (obj != 0) {
3548 obj->receive_camframetimeout();
3549 }
3550}
Kiran Kumar H N326cc4c2010-01-08 12:29:26 -08003551
3552void QualcommCameraHardware::storePreviewFrameForPostview(void) {
3553 LOGV(" storePreviewFrameForPostview : E ");
3554
3555 /* Since there is restriction on the maximum overlay dimensions
3556 * that can be created, we use the last preview frame as postview
3557 * for 7x30. */
3558 LOGV(" Copying the preview buffer to postview buffer %d ",
3559 mPreviewFrameSize);
3560 if( mPostViewHeap != NULL && mLastQueuedFrame != NULL) {
3561 memcpy(mPostViewHeap->mHeap->base(),
3562 (uint8_t *)mLastQueuedFrame, mPreviewFrameSize );
3563 } else
3564 LOGE(" Failed to store Preview frame. No Postview ");
3565
3566 LOGV(" storePreviewFrameForPostview : X ");
3567}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003568}; // namespace android