blob: 0746de1a6a00ae7531cad4485ea7ed2a86422f66 [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
39#define LIKELY(exp) __builtin_expect(!!(exp), 1)
40#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
41
42extern "C" {
43#include <fcntl.h>
44#include <time.h>
45#include <pthread.h>
46#include <stdio.h>
47#include <string.h>
48#include <unistd.h>
49#include <termios.h>
50#include <assert.h>
51#include <stdlib.h>
52#include <ctype.h>
53#include <signal.h>
54#include <errno.h>
55#include <sys/mman.h>
56#include <sys/system_properties.h>
57#include <sys/time.h>
58#include <stdlib.h>
59
60#include <media/msm_camera.h>
61
62#include <camera.h>
63#include <camframe.h>
64#include <mm-still/jpeg/jpege.h>
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080065#include <jpeg_encoder.h>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080066
67#define THUMBNAIL_WIDTH 512
68#define THUMBNAIL_HEIGHT 384
69#define THUMBNAIL_WIDTH_STR "512"
70#define THUMBNAIL_HEIGHT_STR "384"
71#define DEFAULT_PICTURE_WIDTH 2048
72#define DEFAULT_PICTURE_HEIGHT 1536
73#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
74#define MAX_ZOOM_LEVEL 5
75#define NOT_FOUND -1
76
77#if DLOPEN_LIBMMCAMERA
78#include <dlfcn.h>
79
80void* (*LINK_cam_conf)(void *data);
81void* (*LINK_cam_frame)(void *data);
82bool (*LINK_jpeg_encoder_init)();
83void (*LINK_jpeg_encoder_join)();
84bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
85 const uint8_t *thumbnailbuf, int thumbnailfd,
86 const uint8_t *snapshotbuf, int snapshotfd,
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -080087 common_crop_t *scaling_parms, exif_tags_info_t *exif_data,
88 int exif_table_numEntries);
Priya Komarlingamb85535d2009-11-30 13:06:01 -080089int (*LINK_camframe_terminate)(void);
90int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
91int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
92int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
93int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
94const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
95int (*LINK_launch_cam_conf_thread)(void);
96int (*LINK_release_cam_conf_thread)(void);
97int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
98 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
99
100// callbacks
101void (**LINK_mmcamera_camframe_callback)(struct msm_frame *frame);
102void (**LINK_mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
103 uint32_t buff_size);
104void (**LINK_mmcamera_jpeg_callback)(jpeg_event_t status);
105void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800106void (**LINK_camframe_timeout_callback)(void);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800107#else
108#define LINK_cam_conf cam_conf
109#define LINK_cam_frame cam_frame
110#define LINK_jpeg_encoder_init jpeg_encoder_init
111#define LINK_jpeg_encoder_join jpeg_encoder_join
112#define LINK_jpeg_encoder_encode jpeg_encoder_encode
113#define LINK_camframe_terminate camframe_terminate
114#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
115#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
116#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
117#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
118#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
119#define LINK_launch_cam_conf_thread launch_cam_conf_thread
120#define LINK_release_cam_conf_thread release_cam_conf_thread
121#define LINK_zoom_crop_upscale zoom_crop_upscale
122extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
123extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
124 uint32_t buff_size);
125extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
126extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
127#endif
128
129} // extern "C"
130
131#ifndef HAVE_CAMERA_SIZE_TYPE
132struct camera_size_type {
133 int width;
134 int height;
135};
136#endif
137
138#define DEFAULT_PREVIEW_SETTING 2
139static const camera_size_type preview_sizes[] = {
140 { 1280, 720 }, // 720P, reserved
141 { 800, 480 }, // WVGA
142 { 720, 480 },
143 { 640, 480 }, // VGA
144 { 576, 432 },
145 { 480, 320 }, // HVGA
146 { 384, 288 },
147 { 352, 288 }, // CIF
148 { 320, 240 }, // QVGA
149 { 240, 160 }, // SQVGA
150 { 176, 144 }, // QCIF
151};
152#define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(camera_size_type))
153
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800154//static const camera_size_type* picture_sizes;
155//static int PICTURE_SIZE_COUNT;
156/* TODO
157 * Ideally this should be a populated by lower layers.
158 * But currently this is no API to do that at lower layer.
159 * Hence populating with default sizes for now. This needs
160 * to be changed once the API is supported.
161 */
162static const camera_size_type picture_sizes[] = {
163 { 2592, 1944 }, // 5MP
164 { 2048, 1536 }, // 3MP
165 { 1600, 1200 }, // 2MP
166 { 800, 480 }, // WVGA
167 { 640, 480 }, // VGA
168 { 320, 240 } // QVGA
169};
170static int PICTURE_SIZE_COUNT = sizeof(picture_sizes)/sizeof(camera_size_type);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800171
172static int attr_lookup(const str_map arr[], int len, const char *name)
173{
174 if (name) {
175 for (int i = 0; i < len; i++) {
176 if (!strcmp(arr[i].desc, name))
177 return arr[i].val;
178 }
179 }
180 return NOT_FOUND;
181}
182
183// round to the next power of two
184static inline unsigned clp2(unsigned x)
185{
186 x = x - 1;
187 x = x | (x >> 1);
188 x = x | (x >> 2);
189 x = x | (x >> 4);
190 x = x | (x >> 8);
191 x = x | (x >>16);
192 return x + 1;
193}
194
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -0800195static int exif_table_numEntries = 0;
196#define MAX_EXIF_TABLE_ENTRIES 7
197exif_tags_info_t exif_data[MAX_EXIF_TABLE_ENTRIES];
198
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800199namespace android {
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800200
201static const int PICTURE_FORMAT_JPEG = 1;
202static const int PICTURE_FORMAT_RAW = 2;
203
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800204// from aeecamera.h
205static const str_map whitebalance[] = {
206 { CameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
207 { CameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
208 { CameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
209 { CameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
210 { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
211};
212
213// from camera_effect_t. This list must match aeecamera.h
214static const str_map effects[] = {
215 { CameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
216 { CameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
217 { CameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
218 { CameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
219 { CameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
220 { CameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
221 { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
222 { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
223 { CameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA }
224};
225
226// from qcamera/common/camera.h
Apurva Rajguru55562b02009-12-03 12:25:35 -0800227static const str_map autoexposure[] = {
228 { CameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
229 { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
230 { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
231};
232
233// from qcamera/common/camera.h
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800234static const str_map antibanding[] = {
235 { CameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
236 { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
237 { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
238 { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
239};
240
241/* Mapping from MCC to antibanding type */
242struct country_map {
243 uint32_t country_code;
244 camera_antibanding_type type;
245};
246
247static struct country_map country_numeric[] = {
248 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
249 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
250 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
251 { 208, CAMERA_ANTIBANDING_50HZ }, // France
252 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
253 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
254 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
255 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
256 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
257 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
258 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
259 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
260 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
261 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
262 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
263 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
264 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
265 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
266 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
267 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
268 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
269 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
270 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
271 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
272 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
273 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
274 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
275 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
276 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
277 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
278 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
279 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
280 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
281 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
282 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
283 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
284 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
285 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
286 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
287 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
288 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
289 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
290 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
291 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
292 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
293 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
294 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
295 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
296 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
297 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
298 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
299 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
300 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
301 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
302 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
303 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
304 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
305 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
306 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
307 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
308 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
309 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
310 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
311 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
312 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
313 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
314 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
315 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
316 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
317 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
318 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
319 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
320 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
321 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
322 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
323 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
324 { 404, CAMERA_ANTIBANDING_50HZ }, // India
325 { 405, CAMERA_ANTIBANDING_50HZ }, // India
326 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
327 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
328 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
329 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
330 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
331 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
332 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
333 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
334 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
335 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
336 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
337 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
338 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
339 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
340 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
341 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
342 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
343 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
344 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
345 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
346 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
347 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
348 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
349 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
350 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
351 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
352 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
353 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
354 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
355 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
356 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
357 { 460, CAMERA_ANTIBANDING_50HZ }, // China
358 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
359 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
360 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
361 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
362 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
363 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
364 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
365 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
366 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
367 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
368 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
369 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
370 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
371 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
372 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
373 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
374 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
375 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
376 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
377 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
378 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
379 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
380 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
381 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
382 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
383 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
384 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
385 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
386 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
387 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
388 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
389 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
390 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
391 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
392 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
393 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
394 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
395 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
396 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
397 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
398 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
399 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
400 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
401 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
402 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
403 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
404 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
405 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
406 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
407 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
408 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
409 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
410 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
411 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
412 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
413 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
414 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
415 { 647, CAMERA_ANTIBANDING_50HZ }, // France
416 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
417 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
418 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
419 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
420 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
421 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
422 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
423 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
424 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
425 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
426 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
427 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
428 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
429 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
430 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
431 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
432 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
433 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
434 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
435 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
436 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
437 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
438 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
439 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
440 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
441 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
442 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
443 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
444 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
445};
446
447#define country_number (sizeof(country_numeric) / sizeof(country_map))
448
449/* Look up pre-sorted antibanding_type table by current MCC. */
450static camera_antibanding_type camera_get_location(void) {
451 char value[PROP_VALUE_MAX];
452 char country_value[PROP_VALUE_MAX];
453 uint32_t country_code, count;
454 memset(value, 0x00, sizeof(value));
455 memset(country_value, 0x00, sizeof(country_value));
456 if (!__system_property_get("gsm.operator.numeric", value)) {
457 return CAMERA_ANTIBANDING_60HZ;
458 }
459 memcpy(country_value, value, 3);
460 country_code = atoi(country_value);
461 LOGD("value:%s, country value:%s, country code:%d\n",
462 value, country_value, country_code);
463 int left = 0;
464 int right = country_number - 1;
465 while (left <= right) {
466 int index = (left + right) >> 1;
467 if (country_numeric[index].country_code == country_code)
468 return country_numeric[index].type;
469 else if (country_numeric[index].country_code > country_code)
470 right = index - 1;
471 else
472 left = index + 1;
473 }
474 return CAMERA_ANTIBANDING_60HZ;
475}
476
477// from camera.h, led_mode_t
478static const str_map flash[] = {
479 { CameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
480 { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
481 { CameraParameters::FLASH_MODE_ON, LED_MODE_ON }
482};
483
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530484// from mm-camera/common/camera.h.
485static const str_map iso[] = {
486 { CameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
487 { CameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
488 { CameraParameters::ISO_100, CAMERA_ISO_100},
489 { CameraParameters::ISO_200, CAMERA_ISO_200},
490 { CameraParameters::ISO_400, CAMERA_ISO_400},
491 { CameraParameters::ISO_800, CAMERA_ISO_800 }
492};
493
494
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800495#define DONT_CARE 0
496static const str_map focus_modes[] = {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800497 { CameraParameters::FOCUS_MODE_AUTO, AF_MODE_AUTO},
498 { CameraParameters::FOCUS_MODE_INFINITY, DONT_CARE },
499 { CameraParameters::FOCUS_MODE_NORMAL, AF_MODE_NORMAL },
500 { CameraParameters::FOCUS_MODE_MACRO, AF_MODE_MACRO }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800501};
502
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530503static const str_map lensshade[] = {
504 { CameraParameters::LENSSHADE_ENABLE, TRUE },
505 { CameraParameters::LENSSHADE_DISABLE, FALSE }
506};
507
Srinivasan Kannan71229622009-12-04 12:05:58 -0800508struct SensorType {
509 const char *name;
510 int rawPictureWidth;
511 int rawPictureHeight;
512 bool hasAutoFocusSupport;
513};
514
515static SensorType sensorTypes[] = {
516 { "5mp", 2608, 1960, true },
517 { "3mp", 2064, 1544, false },
518 { "2mp", 3200, 1200, false } };
519
520static SensorType * sensorType;
521
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800522static const str_map picture_formats[] = {
523 {CameraParameters::PIXEL_FORMAT_JPEG, PICTURE_FORMAT_JPEG},
524 {CameraParameters::PIXEL_FORMAT_RAW, PICTURE_FORMAT_RAW}
525};
526
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800527static bool parameter_string_initialized = false;
528static String8 preview_size_values;
529static String8 picture_size_values;
530static String8 antibanding_values;
531static String8 effect_values;
Apurva Rajguru55562b02009-12-03 12:25:35 -0800532static String8 autoexposure_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800533static String8 whitebalance_values;
534static String8 flash_values;
535static String8 focus_mode_values;
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530536static String8 iso_values;
537static String8 lensshade_values;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800538static String8 picture_format_values;
539
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800540
541static String8 create_sizes_str(const camera_size_type *sizes, int len) {
542 String8 str;
543 char buffer[32];
544
545 if (len > 0) {
546 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
547 str.append(buffer);
548 }
549 for (int i = 1; i < len; i++) {
550 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
551 str.append(buffer);
552 }
553 return str;
554}
555
556static String8 create_values_str(const str_map *values, int len) {
557 String8 str;
558
559 if (len > 0) {
560 str.append(values[0].desc);
561 }
562 for (int i = 1; i < len; i++) {
563 str.append(",");
564 str.append(values[i].desc);
565 }
566 return str;
567}
568
569static Mutex singleton_lock;
570static bool singleton_releasing;
571static Condition singleton_wait;
572
573static void receive_camframe_callback(struct msm_frame *frame);
574static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size);
575static void receive_jpeg_callback(jpeg_event_t status);
576static void receive_shutter_callback(common_crop_t *crop);
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800577static void receive_camframetimeout_callback(void);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800578
579QualcommCameraHardware::QualcommCameraHardware()
580 : mParameters(),
581 mCameraRunning(false),
582 mPreviewInitialized(false),
583 mFrameThreadRunning(false),
584 mSnapshotThreadRunning(false),
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800585 mSnapshotFormat(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800586 mReleasedRecordingFrame(false),
587 mPreviewFrameSize(0),
588 mRawSize(0),
589 mCameraControlFd(-1),
590 mAutoFocusThreadRunning(false),
591 mAutoFocusFd(-1),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800592 mBrightness(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800593 mInPreviewCallback(false),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800594 mUseOverlay(0),
595 mOverlay(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800596 mMsgEnabled(0),
597 mNotifyCallback(0),
598 mDataCallback(0),
599 mDataCallbackTimestamp(0),
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800600 mCallbackCookie(0)
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800601{
602 memset(&mDimension, 0, sizeof(mDimension));
603 memset(&mCrop, 0, sizeof(mCrop));
604 LOGV("constructor EX");
605}
606
607void QualcommCameraHardware::initDefaultParameters()
608{
609 LOGV("initDefaultParameters E");
610
611 // Initialize constant parameter strings. This will happen only once in the
612 // lifetime of the mediaserver process.
613 if (!parameter_string_initialized) {
Srinivasan Kannan71229622009-12-04 12:05:58 -0800614 findSensorType();
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800615 antibanding_values = create_values_str(
616 antibanding, sizeof(antibanding) / sizeof(str_map));
617 effect_values = create_values_str(
618 effects, sizeof(effects) / sizeof(str_map));
Apurva Rajguru55562b02009-12-03 12:25:35 -0800619 autoexposure_values = create_values_str(
620 autoexposure, sizeof(autoexposure) / sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800621 whitebalance_values = create_values_str(
622 whitebalance, sizeof(whitebalance) / sizeof(str_map));
623 preview_size_values = create_sizes_str(
624 preview_sizes, PREVIEW_SIZE_COUNT);
625 picture_size_values = create_sizes_str(
626 picture_sizes, PICTURE_SIZE_COUNT);
627 flash_values = create_values_str(
628 flash, sizeof(flash) / sizeof(str_map));
Srinivasan Kannan71229622009-12-04 12:05:58 -0800629 if(sensorType->hasAutoFocusSupport){
630 focus_mode_values = create_values_str(
631 focus_modes, sizeof(focus_modes) / sizeof(str_map));
632 }
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530633 iso_values = create_values_str(
634 iso,sizeof(iso)/sizeof(str_map));
635 lensshade_values = create_values_str(
636 lensshade,sizeof(lensshade)/sizeof(str_map));
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800637 picture_format_values = create_values_str(
638 picture_formats, sizeof(picture_formats)/sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800639 parameter_string_initialized = true;
640 }
641
642 const camera_size_type *ps = &preview_sizes[DEFAULT_PREVIEW_SETTING];
643 mParameters.setPreviewSize(ps->width, ps->height);
644 mDimension.display_width = ps->width;
645 mDimension.display_height = ps->height;
646 mParameters.setPreviewFrameRate(15);
647 mParameters.setPreviewFormat("yuv420sp"); // informative
648
649 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
650 mParameters.setPictureFormat("jpeg"); // informative
651
652 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // max quality
653 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
654 THUMBNAIL_WIDTH_STR); // informative
655 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
656 THUMBNAIL_HEIGHT_STR); // informative
657 mDimension.ui_thumbnail_width = THUMBNAIL_WIDTH;
658 mDimension.ui_thumbnail_height = THUMBNAIL_HEIGHT;
659 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
660
661 mParameters.set(CameraParameters::KEY_ANTIBANDING,
662 CameraParameters::ANTIBANDING_AUTO);
663 mParameters.set(CameraParameters::KEY_EFFECT,
664 CameraParameters::EFFECT_NONE);
Apurva Rajguru55562b02009-12-03 12:25:35 -0800665 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
666 CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800667 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
668 CameraParameters::WHITE_BALANCE_AUTO);
669 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
670 CameraParameters::FOCUS_MODE_AUTO);
671
672 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
673 preview_size_values.string());
674 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
675 picture_size_values.string());
676 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
677 antibanding_values);
678 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
Apurva Rajguru55562b02009-12-03 12:25:35 -0800679 mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800680 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
681 whitebalance_values);
682 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
683 focus_mode_values);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800684 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
685 picture_format_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800686
687 if (mSensorInfo.flash_enabled) {
688 mParameters.set(CameraParameters::KEY_FLASH_MODE,
689 CameraParameters::FLASH_MODE_OFF);
690 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
691 flash_values);
692 }
693
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530694 mParameters.set("luma-adaptation", "18");
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800695 mParameters.set("zoom-supported", "true");
696 mParameters.set("max-zoom", MAX_ZOOM_LEVEL);
697 mParameters.set("zoom", 0);
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800698 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT,
699 CameraParameters::PIXEL_FORMAT_JPEG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800700
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530701 mParameters.set(CameraParameters::KEY_ISO_MODE,
702 CameraParameters::ISO_AUTO);
703 mParameters.set(CameraParameters::KEY_LENSSHADE,
704 CameraParameters::LENSSHADE_ENABLE);
705 mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
706 iso_values);
707 mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
708 lensshade_values);
709
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800710 if (setParameters(mParameters) != NO_ERROR) {
711 LOGE("Failed to set default parameters?!");
712 }
713
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -0800714 mUseOverlay = useOverlay();
715
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800716 /* Initialize the camframe_timeout_flag*/
717 Mutex::Autolock l(&mCamframeTimeoutLock);
718 camframe_timeout_flag = FALSE;
719
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800720 LOGV("initDefaultParameters X");
721}
722
Srinivasan Kannan71229622009-12-04 12:05:58 -0800723void QualcommCameraHardware::findSensorType(){
724 mDimension.picture_width = DEFAULT_PICTURE_WIDTH;
725 mDimension.picture_height = DEFAULT_PICTURE_HEIGHT;
726 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
727 sizeof(cam_ctrl_dimension_t), &mDimension);
728 if (ret) {
729 unsigned int i;
730 for (i = 0; i < sizeof(sensorTypes) / sizeof(SensorType); i++) {
731 if (sensorTypes[i].rawPictureHeight
732 == mDimension.raw_picture_height) {
733 sensorType = sensorTypes + i;
734 return;
735 }
736 }
737 }
738 //default to 5 mp
739 sensorType = sensorTypes;
740 return;
741}
742
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800743#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
744
745bool QualcommCameraHardware::startCamera()
746{
747 LOGV("startCamera E");
748#if DLOPEN_LIBMMCAMERA
749 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
750 LOGV("loading liboemcamera at %p", libmmcamera);
751 if (!libmmcamera) {
752 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
753 return false;
754 }
755
756 *(void **)&LINK_cam_frame =
757 ::dlsym(libmmcamera, "cam_frame");
758 *(void **)&LINK_camframe_terminate =
759 ::dlsym(libmmcamera, "camframe_terminate");
760
761 *(void **)&LINK_jpeg_encoder_init =
762 ::dlsym(libmmcamera, "jpeg_encoder_init");
763
764 *(void **)&LINK_jpeg_encoder_encode =
765 ::dlsym(libmmcamera, "jpeg_encoder_encode");
766
767 *(void **)&LINK_jpeg_encoder_join =
768 ::dlsym(libmmcamera, "jpeg_encoder_join");
769
770 *(void **)&LINK_mmcamera_camframe_callback =
771 ::dlsym(libmmcamera, "mmcamera_camframe_callback");
772
773 *LINK_mmcamera_camframe_callback = receive_camframe_callback;
774
775 *(void **)&LINK_mmcamera_jpegfragment_callback =
776 ::dlsym(libmmcamera, "mmcamera_jpegfragment_callback");
777
778 *LINK_mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
779
780 *(void **)&LINK_mmcamera_jpeg_callback =
781 ::dlsym(libmmcamera, "mmcamera_jpeg_callback");
782
783 *LINK_mmcamera_jpeg_callback = receive_jpeg_callback;
784
Kiran Kumar H N215cac42009-12-08 01:53:46 -0800785 *(void **)&LINK_camframe_timeout_callback =
786 ::dlsym(libmmcamera, "camframe_timeout_callback");
787
788 *LINK_camframe_timeout_callback = receive_camframetimeout_callback;
789
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800790/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800791 *(void **)&LINK_mmcamera_shutter_callback =
792 ::dlsym(libmmcamera, "mmcamera_shutter_callback");
793
794 *LINK_mmcamera_shutter_callback = receive_shutter_callback;
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800795*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800796 *(void**)&LINK_jpeg_encoder_setMainImageQuality =
797 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800798/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800799 *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
800 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
801
802 *(void**)&LINK_jpeg_encoder_setRotation =
803 ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
804
805 *(void**)&LINK_jpeg_encoder_setLocation =
806 ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800807*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800808 *(void **)&LINK_cam_conf =
809 ::dlsym(libmmcamera, "cam_conf");
810
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800811/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800812 *(void **)&LINK_default_sensor_get_snapshot_sizes =
813 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800814*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800815 *(void **)&LINK_launch_cam_conf_thread =
816 ::dlsym(libmmcamera, "launch_cam_conf_thread");
817
818 *(void **)&LINK_release_cam_conf_thread =
819 ::dlsym(libmmcamera, "release_cam_conf_thread");
820
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800821/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800822 *(void **)&LINK_zoom_crop_upscale =
823 ::dlsym(libmmcamera, "zoom_crop_upscale");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800824*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800825
826#else
827 mmcamera_camframe_callback = receive_camframe_callback;
828 mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
829 mmcamera_jpeg_callback = receive_jpeg_callback;
830 mmcamera_shutter_callback = receive_shutter_callback;
831#endif // DLOPEN_LIBMMCAMERA
832
833 /* The control thread is in libcamera itself. */
834 mCameraControlFd = open(MSM_CAMERA_CONTROL, O_RDWR);
835 if (mCameraControlFd < 0) {
836 LOGE("startCamera X: %s open failed: %s!",
837 MSM_CAMERA_CONTROL,
838 strerror(errno));
839 return false;
840 }
841
842 /* This will block until the control thread is launched. After that, sensor
843 * information becomes available.
844 */
845
846 if (LINK_launch_cam_conf_thread()) {
847 LOGE("failed to launch the camera config thread");
848 return false;
849 }
850
851 memset(&mSensorInfo, 0, sizeof(mSensorInfo));
852 if (ioctl(mCameraControlFd,
853 MSM_CAM_IOCTL_GET_SENSOR_INFO,
854 &mSensorInfo) < 0)
855 LOGW("%s: cannot retrieve sensor info!", __FUNCTION__);
856 else
857 LOGI("%s: camsensor name %s, flash %d", __FUNCTION__,
858 mSensorInfo.name, mSensorInfo.flash_enabled);
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800859/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800860 picture_sizes = LINK_default_sensor_get_snapshot_sizes(&PICTURE_SIZE_COUNT);
861 if (!picture_sizes || !PICTURE_SIZE_COUNT) {
862 LOGE("startCamera X: could not get snapshot sizes");
863 return false;
864 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800865*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800866 LOGV("startCamera X");
867 return true;
868}
869
870status_t QualcommCameraHardware::dump(int fd,
871 const Vector<String16>& args) const
872{
873 const size_t SIZE = 256;
874 char buffer[SIZE];
875 String8 result;
876
877 // Dump internal primitives.
878 result.append("QualcommCameraHardware::dump");
879 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
880 result.append(buffer);
881 int width, height;
882 mParameters.getPreviewSize(&width, &height);
883 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
884 result.append(buffer);
885 mParameters.getPictureSize(&width, &height);
886 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
887 result.append(buffer);
888 snprintf(buffer, 255,
889 "preview frame size(%d), raw size (%d), jpeg size (%d) "
890 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
891 mJpegSize, mJpegMaxSize);
892 result.append(buffer);
893 write(fd, result.string(), result.size());
894
895 // Dump internal objects.
896 if (mPreviewHeap != 0) {
897 mPreviewHeap->dump(fd, args);
898 }
899 if (mRawHeap != 0) {
900 mRawHeap->dump(fd, args);
901 }
902 if (mJpegHeap != 0) {
903 mJpegHeap->dump(fd, args);
904 }
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -0800905 if(mRawSnapshotAshmemHeap != 0 ){
906 mRawSnapshotAshmemHeap->dump(fd, args);
907 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800908 mParameters.dump(fd, args);
909 return NO_ERROR;
910}
911
912static bool native_set_afmode(int camfd, isp3a_af_mode_t af_type)
913{
914 int rc;
915 struct msm_ctrl_cmd ctrlCmd;
916
917 ctrlCmd.timeout_ms = 5000;
918 ctrlCmd.type = CAMERA_SET_PARM_AUTO_FOCUS;
919 ctrlCmd.length = sizeof(af_type);
920 ctrlCmd.value = &af_type;
921 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
922
923 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0)
924 LOGE("native_set_afmode: ioctl fd %d error %s\n",
925 camfd,
926 strerror(errno));
927
928 LOGV("native_set_afmode: ctrlCmd.status == %d\n", ctrlCmd.status);
929 return rc >= 0 && ctrlCmd.status == CAMERA_EXIT_CB_DONE;
930}
931
932static bool native_cancel_afmode(int camfd, int af_fd)
933{
934 int rc;
935 struct msm_ctrl_cmd ctrlCmd;
936
937 ctrlCmd.timeout_ms = 0;
938 ctrlCmd.type = CAMERA_AUTO_FOCUS_CANCEL;
939 ctrlCmd.length = 0;
940 ctrlCmd.value = NULL;
941 ctrlCmd.resp_fd = -1; // there's no response fd
942
943 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd)) < 0)
944 {
945 LOGE("native_cancel_afmode: ioctl fd %d error %s\n",
946 camfd,
947 strerror(errno));
948 return false;
949 }
950
951 return true;
952}
953
954static bool native_start_preview(int camfd)
955{
956 struct msm_ctrl_cmd ctrlCmd;
957
958 ctrlCmd.timeout_ms = 5000;
959 ctrlCmd.type = CAMERA_START_PREVIEW;
960 ctrlCmd.length = 0;
961 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
962
963 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
964 LOGE("native_start_preview: MSM_CAM_IOCTL_CTRL_COMMAND fd %d error %s",
965 camfd,
966 strerror(errno));
967 return false;
968 }
969
970 return true;
971}
972
973static bool native_get_picture (int camfd, common_crop_t *crop)
974{
975 struct msm_ctrl_cmd ctrlCmd;
976
977 ctrlCmd.timeout_ms = 5000;
978 ctrlCmd.length = sizeof(common_crop_t);
979 ctrlCmd.value = crop;
980
981 if(ioctl(camfd, MSM_CAM_IOCTL_GET_PICTURE, &ctrlCmd) < 0) {
982 LOGE("native_get_picture: MSM_CAM_IOCTL_GET_PICTURE fd %d error %s",
983 camfd,
984 strerror(errno));
985 return false;
986 }
987
988 LOGV("crop: in1_w %d", crop->in1_w);
989 LOGV("crop: in1_h %d", crop->in1_h);
990 LOGV("crop: out1_w %d", crop->out1_w);
991 LOGV("crop: out1_h %d", crop->out1_h);
992
993 LOGV("crop: in2_w %d", crop->in2_w);
994 LOGV("crop: in2_h %d", crop->in2_h);
995 LOGV("crop: out2_w %d", crop->out2_w);
996 LOGV("crop: out2_h %d", crop->out2_h);
997
998 LOGV("crop: update %d", crop->update_flag);
999
1000 return true;
1001}
1002
1003static bool native_stop_preview(int camfd)
1004{
1005 struct msm_ctrl_cmd ctrlCmd;
1006 ctrlCmd.timeout_ms = 5000;
1007 ctrlCmd.type = CAMERA_STOP_PREVIEW;
1008 ctrlCmd.length = 0;
1009 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1010
1011 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1012 LOGE("native_stop_preview: ioctl fd %d error %s",
1013 camfd,
1014 strerror(errno));
1015 return false;
1016 }
1017
1018 return true;
1019}
1020
1021static bool native_prepare_snapshot(int camfd)
1022{
1023 int ioctlRetVal = true;
1024 struct msm_ctrl_cmd ctrlCmd;
1025
1026 ctrlCmd.timeout_ms = 1000;
1027 ctrlCmd.type = CAMERA_PREPARE_SNAPSHOT;
1028 ctrlCmd.length = 0;
1029 ctrlCmd.value = NULL;
1030 ctrlCmd.resp_fd = camfd;
1031
1032 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1033 LOGE("native_prepare_snapshot: ioctl fd %d error %s",
1034 camfd,
1035 strerror(errno));
1036 return false;
1037 }
1038 return true;
1039}
1040
1041static bool native_start_snapshot(int camfd)
1042{
1043 struct msm_ctrl_cmd ctrlCmd;
1044
1045 ctrlCmd.timeout_ms = 5000;
1046 ctrlCmd.type = CAMERA_START_SNAPSHOT;
1047 ctrlCmd.length = 0;
1048 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
1049
1050 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
1051 LOGE("native_start_snapshot: ioctl fd %d error %s",
1052 camfd,
1053 strerror(errno));
1054 return false;
1055 }
1056
1057 return true;
1058}
1059
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001060static bool native_start_raw_snapshot(int camfd)
1061{
1062 int ret;
1063 struct msm_ctrl_cmd ctrlCmd;
1064
1065 ctrlCmd.timeout_ms = 1000;
1066 ctrlCmd.type = CAMERA_START_RAW_SNAPSHOT;
1067 ctrlCmd.length = 0;
1068 ctrlCmd.value = NULL;
1069 ctrlCmd.resp_fd = camfd;
1070
1071 if ((ret = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0) {
1072 LOGE("native_start_raw_snapshot: ioctl failed. ioctl return value "\
1073 "is %d \n", ret);
1074 return false;
1075 }
1076 return true;
1077}
1078
1079
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001080static bool native_stop_snapshot (int camfd)
1081{
1082 struct msm_ctrl_cmd ctrlCmd;
1083
1084 ctrlCmd.timeout_ms = 0;
1085 ctrlCmd.type = CAMERA_STOP_SNAPSHOT;
1086 ctrlCmd.length = 0;
1087 ctrlCmd.resp_fd = -1;
1088
1089 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd) < 0) {
1090 LOGE("native_stop_snapshot: ioctl fd %d error %s",
1091 camfd,
1092 strerror(errno));
1093 return false;
1094 }
1095
1096 return true;
1097}
1098
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001099static rat_t latitude[3];
1100static rat_t longitude[3];
1101static char lonref[2];
1102static char latref[2];
1103static char dateTime[20];
1104static rat_t altitude;
1105
1106static void addExifTag(exif_tag_id_t tagid, exif_tag_type_t type,
1107 uint32_t count, uint8_t copy, void *data) {
1108
1109 if(exif_table_numEntries == MAX_EXIF_TABLE_ENTRIES) {
1110 LOGE("Number of entries exceeded limit");
1111 return;
1112 }
1113
1114 int index = exif_table_numEntries;
1115 exif_data[index].tag_id = tagid;
1116 exif_data[index].tag_entry.type = type;
1117 exif_data[index].tag_entry.count = count;
1118 exif_data[index].tag_entry.copy = copy;
1119 if((type == EXIF_RATIONAL) && (count > 1))
1120 exif_data[index].tag_entry.data._rats = (rat_t *)data;
1121 if((type == EXIF_RATIONAL) && (count == 1))
1122 exif_data[index].tag_entry.data._rat = *(rat_t *)data;
1123 else if(type == EXIF_ASCII)
1124 exif_data[index].tag_entry.data._ascii = (char *)data;
1125 else if(type == EXIF_BYTE)
1126 exif_data[index].tag_entry.data._byte = *(uint8_t *)data;
1127
1128 // Increase number of entries
1129 exif_table_numEntries++;
1130}
1131
1132static void parseLatLong(const char *latlonString, int *pDegrees,
1133 int *pMinutes, int *pSeconds ) {
1134
1135 double value = atof(latlonString);
1136 value = fabs(value);
1137 int degrees = (int) value;
1138
1139 double remainder = value - degrees;
1140 int minutes = (int) (remainder * 60);
1141 int seconds = (int) (((remainder * 60) - minutes) * 60 * 1000);
1142
1143 *pDegrees = degrees;
1144 *pMinutes = minutes;
1145 *pSeconds = seconds;
1146}
1147
1148static void setLatLon(exif_tag_id_t tag, const char *latlonString) {
1149
1150 int degrees, minutes, seconds;
1151
1152 parseLatLong(latlonString, &degrees, &minutes, &seconds);
1153
1154 rat_t value[3] = { {degrees, 1},
1155 {minutes, 1},
1156 {seconds, 1000} };
1157
1158 if(tag == EXIFTAGID_GPS_LATITUDE) {
1159 memcpy(latitude, value, sizeof(latitude));
1160 addExifTag(EXIFTAGID_GPS_LATITUDE, EXIF_RATIONAL, 3,
1161 1, (void *)latitude);
1162 } else {
1163 memcpy(longitude, value, sizeof(longitude));
1164 addExifTag(EXIFTAGID_GPS_LONGITUDE, EXIF_RATIONAL, 3,
1165 1, (void *)longitude);
1166 }
1167}
1168
1169void QualcommCameraHardware::setGpsParameters() {
1170 const char *str = NULL;
1171
1172 //Set Latitude
1173 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE);
1174 if(str != NULL) {
1175 setLatLon(EXIFTAGID_GPS_LATITUDE, str);
1176 //set Latitude Ref
1177 str = NULL;
1178 str = mParameters.get(CameraParameters::KEY_GPS_LATITUDE_REF);
1179 if(str != NULL) {
1180 strncpy(latref, str, 1);
1181 latref[1] = '\0';
1182 addExifTag(EXIFTAGID_GPS_LATITUDE_REF, EXIF_ASCII, 2,
1183 1, (void *)latref);
1184 }
1185 }
1186
1187 //set Longitude
1188 str = NULL;
1189 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE);
1190 if(str != NULL) {
1191 setLatLon(EXIFTAGID_GPS_LONGITUDE, str);
1192 //set Longitude Ref
1193 str = NULL;
1194 str = mParameters.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
1195 if(str != NULL) {
1196 strncpy(lonref, str, 1);
1197 lonref[1] = '\0';
1198 addExifTag(EXIFTAGID_GPS_LONGITUDE_REF, EXIF_ASCII, 2,
1199 1, (void *)lonref);
1200 }
1201 }
1202
1203 //set Altitude
1204 str = NULL;
1205 str = mParameters.get(CameraParameters::KEY_GPS_ALTITUDE);
1206 if(str != NULL) {
1207 int value = atoi(str);
1208 rat_t alt_value = {value, 1000};
1209 memcpy(&altitude, &alt_value, sizeof(altitude));
1210 addExifTag(EXIFTAGID_GPS_ALTITUDE, EXIF_RATIONAL, 1,
1211 1, (void *)&altitude);
1212 //set AltitudeRef
1213 int ref = mParameters.getInt(CameraParameters::KEY_GPS_ALTITUDE_REF);
1214 if( !(ref < 0 || ref > 1) )
1215 addExifTag(EXIFTAGID_GPS_ALTITUDE_REF, EXIF_BYTE, 1,
1216 1, (void *)&ref);
1217 }
1218
1219
1220}
1221
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001222bool QualcommCameraHardware::native_jpeg_encode(void)
1223{
1224 int jpeg_quality = mParameters.getInt("jpeg-quality");
1225 if (jpeg_quality >= 0) {
1226 LOGV("native_jpeg_encode, current jpeg main img quality =%d",
1227 jpeg_quality);
1228 if(!LINK_jpeg_encoder_setMainImageQuality(jpeg_quality)) {
1229 LOGE("native_jpeg_encode set jpeg-quality failed");
1230 return false;
1231 }
1232 }
1233
1234 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
1235 if (thumbnail_quality >= 0) {
1236 LOGV("native_jpeg_encode, current jpeg thumbnail quality =%d",
1237 thumbnail_quality);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001238/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001239 if(!LINK_jpeg_encoder_setThumbnailQuality(thumbnail_quality)) {
1240 LOGE("native_jpeg_encode set thumbnail-quality failed");
1241 return false;
1242 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001243*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001244 }
1245
1246 int rotation = mParameters.getInt("rotation");
1247 if (rotation >= 0) {
1248 LOGV("native_jpeg_encode, rotation = %d", rotation);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001249/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001250 if(!LINK_jpeg_encoder_setRotation(rotation)) {
1251 LOGE("native_jpeg_encode set rotation failed");
1252 return false;
1253 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001254*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001255 }
1256
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001257// jpeg_set_location();
1258 if(mParameters.getInt(CameraParameters::KEY_GPS_STATUS) == 1) {
1259 setGpsParameters();
1260 }
1261 //set TimeStamp
1262 const char *str = mParameters.get(CameraParameters::KEY_EXIF_DATETIME);
1263 if(str != NULL) {
1264 strncpy(dateTime, str, 19);
1265 dateTime[19] = '\0';
1266 addExifTag(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
1267 20, 1, (void *)dateTime);
1268 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001269
1270 if (!LINK_jpeg_encoder_encode(&mDimension,
1271 (uint8_t *)mThumbnailHeap->mHeap->base(),
1272 mThumbnailHeap->mHeap->getHeapID(),
1273 (uint8_t *)mRawHeap->mHeap->base(),
1274 mRawHeap->mHeap->getHeapID(),
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001275 &mCrop, exif_data, exif_table_numEntries)) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001276 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
1277 return false;
1278 }
1279 return true;
1280}
1281
1282bool QualcommCameraHardware::native_set_parm(
1283 cam_ctrl_type type, uint16_t length, void *value)
1284{
1285 struct msm_ctrl_cmd ctrlCmd;
1286
1287 ctrlCmd.timeout_ms = 5000;
1288 ctrlCmd.type = (uint16_t)type;
1289 ctrlCmd.length = length;
1290 // FIXME: this will be put in by the kernel
1291 ctrlCmd.resp_fd = mCameraControlFd;
1292 ctrlCmd.value = value;
1293
1294 LOGV("%s: fd %d, type %d, length %d", __FUNCTION__,
1295 mCameraControlFd, type, length);
1296 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0 ||
1297 ctrlCmd.status != CAM_CTRL_SUCCESS) {
1298 LOGE("%s: error (%s): fd %d, type %d, length %d, status %d",
1299 __FUNCTION__, strerror(errno),
1300 mCameraControlFd, type, length, ctrlCmd.status);
1301 return false;
1302 }
1303 return true;
1304}
1305
1306void QualcommCameraHardware::jpeg_set_location()
1307{
1308 bool encode_location = true;
1309 camera_position_type pt;
1310
1311#define PARSE_LOCATION(what,type,fmt,desc) do { \
1312 pt.what = 0; \
1313 const char *what##_str = mParameters.get("gps-"#what); \
1314 LOGV("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
1315 if (what##_str) { \
1316 type what = 0; \
1317 if (sscanf(what##_str, fmt, &what) == 1) \
1318 pt.what = what; \
1319 else { \
1320 LOGE("GPS " #what " %s could not" \
1321 " be parsed as a " #desc, what##_str); \
1322 encode_location = false; \
1323 } \
1324 } \
1325 else { \
1326 LOGV("GPS " #what " not specified: " \
1327 "defaulting to zero in EXIF header."); \
1328 encode_location = false; \
1329 } \
1330 } while(0)
1331
1332 PARSE_LOCATION(timestamp, long, "%ld", "long");
1333 if (!pt.timestamp) pt.timestamp = time(NULL);
1334 PARSE_LOCATION(altitude, short, "%hd", "short");
1335 PARSE_LOCATION(latitude, double, "%lf", "double float");
1336 PARSE_LOCATION(longitude, double, "%lf", "double float");
1337
1338#undef PARSE_LOCATION
1339
1340 if (encode_location) {
1341 LOGD("setting image location ALT %d LAT %lf LON %lf",
1342 pt.altitude, pt.latitude, pt.longitude);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001343/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001344 if (!LINK_jpeg_encoder_setLocation(&pt)) {
1345 LOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
1346 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001347*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001348 }
1349 else LOGV("not setting image location");
1350}
1351
1352void QualcommCameraHardware::runFrameThread(void *data)
1353{
1354 LOGV("runFrameThread E");
1355
1356 int cnt;
1357
1358#if DLOPEN_LIBMMCAMERA
1359 // We need to maintain a reference to libqcamera.so for the duration of the
1360 // frame thread, because we do not know when it will exit relative to the
1361 // lifetime of this object. We do not want to dlclose() libqcamera while
1362 // LINK_cam_frame is still running.
1363 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
1364 LOGV("FRAME: loading libqcamera at %p", libhandle);
1365 if (!libhandle) {
1366 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1367 }
1368 if (libhandle)
1369#endif
1370 {
1371 LINK_cam_frame(data);
1372 }
1373
1374 mPreviewHeap.clear();
1375
1376#if DLOPEN_LIBMMCAMERA
1377 if (libhandle) {
1378 ::dlclose(libhandle);
1379 LOGV("FRAME: dlclose(libqcamera)");
1380 }
1381#endif
1382
1383 mFrameThreadWaitLock.lock();
1384 mFrameThreadRunning = false;
1385 mFrameThreadWait.signal();
1386 mFrameThreadWaitLock.unlock();
1387
1388 LOGV("runFrameThread X");
1389}
1390
1391void *frame_thread(void *user)
1392{
1393 LOGD("frame_thread E");
1394 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
1395 if (obj != 0) {
1396 obj->runFrameThread(user);
1397 }
1398 else LOGW("not starting frame thread: the object went away!");
1399 LOGD("frame_thread X");
1400 return NULL;
1401}
1402
1403bool QualcommCameraHardware::initPreview()
1404{
1405 // See comments in deinitPreview() for why we have to wait for the frame
1406 // thread here, and why we can't use pthread_join().
1407 int previewWidth, previewHeight;
1408 mParameters.getPreviewSize(&previewWidth, &previewHeight);
1409 LOGI("initPreview E: preview size=%dx%d", previewWidth, previewHeight);
1410 mFrameThreadWaitLock.lock();
1411 while (mFrameThreadRunning) {
1412 LOGV("initPreview: waiting for old frame thread to complete.");
1413 mFrameThreadWait.wait(mFrameThreadWaitLock);
1414 LOGV("initPreview: old frame thread completed.");
1415 }
1416 mFrameThreadWaitLock.unlock();
1417
1418 mSnapshotThreadWaitLock.lock();
1419 while (mSnapshotThreadRunning) {
1420 LOGV("initPreview: waiting for old snapshot thread to complete.");
1421 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
1422 LOGV("initPreview: old snapshot thread completed.");
1423 }
1424 mSnapshotThreadWaitLock.unlock();
1425
1426 int cnt = 0;
1427 mPreviewFrameSize = previewWidth * previewHeight * 3/2;
1428 mPreviewHeap = new PmemPool("/dev/pmem_adsp",
1429 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
1430 mCameraControlFd,
1431 MSM_PMEM_OUTPUT2,
1432 mPreviewFrameSize,
1433 kPreviewBufferCount,
1434 mPreviewFrameSize,
1435 "preview");
1436
1437 if (!mPreviewHeap->initialized()) {
1438 mPreviewHeap.clear();
1439 LOGE("initPreview X: could not initialize preview heap.");
1440 return false;
1441 }
1442
1443 // mDimension will be filled with thumbnail_width, thumbnail_height,
1444 // orig_picture_dx, and orig_picture_dy after this function call. We need to
1445 // keep it for jpeg_encoder_encode.
1446 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1447 sizeof(cam_ctrl_dimension_t), &mDimension);
1448
1449 if (ret) {
1450 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
1451 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
1452 frames[cnt].buffer =
1453 (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
1454 frames[cnt].y_off = 0;
1455 frames[cnt].cbcr_off = previewWidth * previewHeight;
1456 frames[cnt].path = MSM_FRAME_ENC;
1457 }
1458
1459 mFrameThreadWaitLock.lock();
1460 pthread_attr_t attr;
1461 pthread_attr_init(&attr);
1462 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1463 mFrameThreadRunning = !pthread_create(&mFrameThread,
1464 &attr,
1465 frame_thread,
1466 &frames[kPreviewBufferCount-1]);
1467 ret = mFrameThreadRunning;
1468 mFrameThreadWaitLock.unlock();
1469 }
1470
1471 LOGV("initPreview X: %d", ret);
1472 return ret;
1473}
1474
1475void QualcommCameraHardware::deinitPreview(void)
1476{
1477 LOGI("deinitPreview E");
1478
1479 // When we call deinitPreview(), we signal to the frame thread that it
1480 // needs to exit, but we DO NOT WAIT for it to complete here. The problem
1481 // is that deinitPreview is sometimes called from the frame-thread's
1482 // callback, when the refcount on the Camera client reaches zero. If we
1483 // called pthread_join(), we would deadlock. So, we just call
1484 // LINK_camframe_terminate() in deinitPreview(), which makes sure that
1485 // after the preview callback returns, the camframe thread will exit. We
1486 // could call pthread_join() in initPreview() to join the last frame
1487 // thread. However, we would also have to call pthread_join() in release
1488 // as well, shortly before we destroy the object; this would cause the same
1489 // deadlock, since release(), like deinitPreview(), may also be called from
1490 // the frame-thread's callback. This we have to make the frame thread
1491 // detached, and use a separate mechanism to wait for it to complete.
1492
1493 if (LINK_camframe_terminate() < 0)
1494 LOGE("failed to stop the camframe thread: %s",
1495 strerror(errno));
1496 LOGI("deinitPreview X");
1497}
1498
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001499bool QualcommCameraHardware::initRawSnapshot()
1500{
1501 LOGV("initRawSnapshot E");
1502
1503 //get width and height from Dimension Object
1504 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1505 sizeof(cam_ctrl_dimension_t), &mDimension);
1506
1507 if(!ret){
1508 LOGE("initRawSnapshot X: failed to set dimension");
1509 return false;
1510 }
1511 int rawSnapshotSize = mDimension.raw_picture_height *
1512 mDimension.raw_picture_width;
1513
1514 LOGV("raw_snapshot_buffer_size = %d, raw_picture_height = %d, "\
1515 "raw_picture_width = %d",
1516 rawSnapshotSize, mDimension.raw_picture_height,
1517 mDimension.raw_picture_width);
1518
1519 if (mRawSnapShotPmemHeap != NULL) {
1520 LOGV("initRawSnapshot: clearing old mRawSnapShotPmemHeap.");
1521 mRawSnapShotPmemHeap.clear();
1522 }
1523
1524 //Pmem based pool for Camera Driver
1525 mRawSnapShotPmemHeap = new PmemPool("/dev/pmem_adsp",
1526 MemoryHeapBase::READ_ONLY,
1527 mCameraControlFd,
1528 MSM_PMEM_RAW_MAINIMG,
1529 rawSnapshotSize,
1530 1,
1531 rawSnapshotSize,
1532 "raw pmem snapshot camera");
1533
1534 if (!mRawSnapShotPmemHeap->initialized()) {
1535 mRawSnapShotPmemHeap.clear();
1536 LOGE("initRawSnapshot X: error initializing mRawSnapshotHeap");
1537 return false;
1538 }
1539 LOGV("initRawSnapshot X");
1540 return true;
1541
1542}
1543
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001544bool QualcommCameraHardware::initRaw(bool initJpegHeap)
1545{
1546 int rawWidth, rawHeight;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001547 char value[PROPERTY_VALUE_MAX];
1548
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001549 mParameters.getPictureSize(&rawWidth, &rawHeight);
1550 LOGV("initRaw E: picture size=%dx%d", rawWidth, rawHeight);
1551
1552 // mDimension will be filled with thumbnail_width, thumbnail_height,
1553 // orig_picture_dx, and orig_picture_dy after this function call. We need to
1554 // keep it for jpeg_encoder_encode.
1555 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1556 sizeof(cam_ctrl_dimension_t), &mDimension);
1557 if(!ret) {
1558 LOGE("initRaw X: failed to set dimension");
1559 return false;
1560 }
1561
1562 if (mJpegHeap != NULL) {
1563 LOGV("initRaw: clearing old mJpegHeap.");
1564 mJpegHeap.clear();
1565 }
1566
1567 // Snapshot
1568 mRawSize = rawWidth * rawHeight * 3 / 2;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001569 property_get("ro.product.device",value," ");
1570
1571 if(!strcmp(value,"msm7627_surf"))
1572 mJpegMaxSize = CEILING16(rawWidth) * CEILING16(rawHeight) * 3 / 2;
1573 else
1574 mJpegMaxSize = rawWidth * rawHeight * 3 / 2;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001575
1576 LOGV("initRaw: initializing mRawHeap.");
1577 mRawHeap =
1578 new PmemPool("/dev/pmem_camera",
1579 MemoryHeapBase::READ_ONLY,
1580 mCameraControlFd,
1581 MSM_PMEM_MAINIMG,
1582 mJpegMaxSize,
1583 kRawBufferCount,
1584 mRawSize,
1585 "snapshot camera");
1586
1587 if (!mRawHeap->initialized()) {
1588 LOGE("initRaw X failed with pmem_camera, trying with pmem_adsp");
1589 mRawHeap =
1590 new PmemPool("/dev/pmem_adsp",
1591 MemoryHeapBase::READ_ONLY,
1592 mCameraControlFd,
1593 MSM_PMEM_MAINIMG,
1594 mJpegMaxSize,
1595 kRawBufferCount,
1596 mRawSize,
1597 "snapshot camera");
1598 if (!mRawHeap->initialized()) {
1599 mRawHeap.clear();
1600 LOGE("initRaw X: error initializing mRawHeap");
1601 return false;
1602 }
1603 }
1604
1605 LOGV("do_mmap snapshot pbuf = %p, pmem_fd = %d",
1606 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mHeap->getHeapID());
1607
1608 // Jpeg
1609
1610 if (initJpegHeap) {
1611 LOGV("initRaw: initializing mJpegHeap.");
1612 mJpegHeap =
1613 new AshmemPool(mJpegMaxSize,
1614 kJpegBufferCount,
1615 0, // we do not know how big the picture will be
1616 "jpeg");
1617
1618 if (!mJpegHeap->initialized()) {
1619 mJpegHeap.clear();
1620 mRawHeap.clear();
1621 LOGE("initRaw X failed: error initializing mJpegHeap.");
1622 return false;
1623 }
1624
1625 // Thumbnails
1626
1627 mThumbnailHeap =
1628 new PmemPool("/dev/pmem_adsp",
1629 MemoryHeapBase::READ_ONLY,
1630 mCameraControlFd,
1631 MSM_PMEM_THUMBNAIL,
1632 THUMBNAIL_BUFFER_SIZE,
1633 1,
1634 THUMBNAIL_BUFFER_SIZE,
1635 "thumbnail");
1636
1637 if (!mThumbnailHeap->initialized()) {
1638 mThumbnailHeap.clear();
1639 mJpegHeap.clear();
1640 mRawHeap.clear();
1641 LOGE("initRaw X failed: error initializing mThumbnailHeap.");
1642 return false;
1643 }
1644 }
1645
1646 LOGV("initRaw X");
1647 return true;
1648}
1649
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001650
1651void QualcommCameraHardware::deinitRawSnapshot()
1652{
1653 LOGV("deinitRawSnapshot E");
1654 mRawSnapShotPmemHeap.clear();
1655 mRawSnapshotAshmemHeap.clear();
1656 LOGV("deinitRawSnapshot X");
1657}
1658
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001659void QualcommCameraHardware::deinitRaw()
1660{
1661 LOGV("deinitRaw E");
1662
1663 mThumbnailHeap.clear();
1664 mJpegHeap.clear();
1665 mRawHeap.clear();
1666 mDisplayHeap.clear();
1667
1668 LOGV("deinitRaw X");
1669}
1670
1671void QualcommCameraHardware::release()
1672{
1673 LOGD("release E");
1674 Mutex::Autolock l(&mLock);
1675
1676#if DLOPEN_LIBMMCAMERA
1677 if (libmmcamera == NULL) {
1678 LOGE("ERROR: multiple release!");
1679 return;
1680 }
1681#else
1682#warning "Cannot detect multiple release when not dlopen()ing libqcamera!"
1683#endif
1684
1685 int cnt, rc;
1686 struct msm_ctrl_cmd ctrlCmd;
1687
1688 if (mCameraRunning) {
1689 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
1690 mRecordFrameLock.lock();
1691 mReleasedRecordingFrame = true;
1692 mRecordWait.signal();
1693 mRecordFrameLock.unlock();
1694 }
1695 stopPreviewInternal();
1696 }
1697
1698 LINK_jpeg_encoder_join();
1699 deinitRaw();
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08001700 deinitRawSnapshot();
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001701 {
1702 Mutex::Autolock l(&mCamframeTimeoutLock);
1703 if(!camframe_timeout_flag) {
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001704
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001705 ctrlCmd.timeout_ms = 5000;
1706 ctrlCmd.length = 0;
1707 ctrlCmd.type = (uint16_t)CAMERA_EXIT;
1708 ctrlCmd.resp_fd = mCameraControlFd; // FIXME: this will be put in by the kernel
1709 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0)
1710 LOGE("ioctl CAMERA_EXIT fd %d error %s",
1711 mCameraControlFd, strerror(errno));
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001712
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001713 LINK_release_cam_conf_thread();
1714 }
1715 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001716 close(mCameraControlFd);
1717 mCameraControlFd = -1;
1718
1719#if DLOPEN_LIBMMCAMERA
1720 if (libmmcamera) {
1721 ::dlclose(libmmcamera);
1722 LOGV("dlclose(libqcamera)");
1723 libmmcamera = NULL;
1724 }
1725#endif
1726
1727 Mutex::Autolock lock(&singleton_lock);
1728 singleton_releasing = true;
1729
1730 LOGD("release X");
1731}
1732
1733QualcommCameraHardware::~QualcommCameraHardware()
1734{
1735 LOGD("~QualcommCameraHardware E");
1736 Mutex::Autolock lock(&singleton_lock);
1737 singleton.clear();
1738 singleton_releasing = false;
1739 singleton_wait.signal();
1740 LOGD("~QualcommCameraHardware X");
1741}
1742
1743sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
1744{
1745 LOGV("getRawHeap");
1746 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
1747}
1748
1749sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
1750{
1751 LOGV("getPreviewHeap");
1752 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
1753}
1754
1755status_t QualcommCameraHardware::startPreviewInternal()
1756{
1757 if(mCameraRunning) {
1758 LOGV("startPreview X: preview already running.");
1759 return NO_ERROR;
1760 }
1761
1762 if (!mPreviewInitialized) {
1763 mPreviewInitialized = initPreview();
1764 if (!mPreviewInitialized) {
1765 LOGE("startPreview X initPreview failed. Not starting preview.");
1766 return UNKNOWN_ERROR;
1767 }
1768 }
1769
1770 mCameraRunning = native_start_preview(mCameraControlFd);
1771 if(!mCameraRunning) {
1772 deinitPreview();
1773 mPreviewInitialized = false;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001774 mOverlay = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001775 LOGE("startPreview X: native_start_preview failed!");
1776 return UNKNOWN_ERROR;
1777 }
1778
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08001779 //Reset the Gps Information
1780 exif_table_numEntries = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001781 LOGV("startPreview X");
1782 return NO_ERROR;
1783}
1784
1785status_t QualcommCameraHardware::startPreview()
1786{
1787 LOGV("startPreview E");
1788 Mutex::Autolock l(&mLock);
1789 return startPreviewInternal();
1790}
1791
1792void QualcommCameraHardware::stopPreviewInternal()
1793{
1794 LOGV("stopPreviewInternal E: %d", mCameraRunning);
1795 if (mCameraRunning) {
1796 // Cancel auto focus.
1797 {
1798 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
1799 cancelAutoFocusInternal();
1800 }
1801 }
Kiran Kumar H N215cac42009-12-08 01:53:46 -08001802 Mutex::Autolock l(&mCamframeTimeoutLock);
1803 if(!camframe_timeout_flag) {
1804 mCameraRunning = !native_stop_preview(mCameraControlFd);
1805 if (!mCameraRunning && mPreviewInitialized) {
1806 deinitPreview();
1807 mPreviewInitialized = false;
1808 }
1809 else LOGE("stopPreviewInternal: failed to stop preview");
1810 } else {
1811 /* This means that the camframetimeout was issued.
1812 * But we did not issue native_stop_preview(), so we
1813 * need to update mCameraRunning & mPreviewInitialized
1814 * to indicate that Camera is no longer running.
1815 */
1816 mCameraRunning = 0;
1817 mPreviewInitialized = false;
1818 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001819 }
1820 LOGV("stopPreviewInternal X: %d", mCameraRunning);
1821}
1822
1823void QualcommCameraHardware::stopPreview()
1824{
1825 LOGV("stopPreview: E");
1826 Mutex::Autolock l(&mLock);
1827 {
1828 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
1829 return;
1830 }
1831 stopPreviewInternal();
1832 LOGV("stopPreview: X");
1833}
1834
1835void QualcommCameraHardware::runAutoFocus()
1836{
1837 bool status = true;
1838 void *libhandle = NULL;
Srinivasan Kannan71229622009-12-04 12:05:58 -08001839 isp3a_af_mode_t afMode;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001840
1841 mAutoFocusThreadLock.lock();
1842 // Skip autofocus if focus mode is infinity.
1843 if (strcmp(mParameters.get(CameraParameters::KEY_FOCUS_MODE),
1844 CameraParameters::FOCUS_MODE_INFINITY) == 0) {
1845 goto done;
1846 }
1847
1848 mAutoFocusFd = open(MSM_CAMERA_CONTROL, O_RDWR);
1849 if (mAutoFocusFd < 0) {
1850 LOGE("autofocus: cannot open %s: %s",
1851 MSM_CAMERA_CONTROL,
1852 strerror(errno));
1853 mAutoFocusThreadRunning = false;
1854 mAutoFocusThreadLock.unlock();
1855 return;
1856 }
1857
1858#if DLOPEN_LIBMMCAMERA
1859 // We need to maintain a reference to libqcamera.so for the duration of the
1860 // AF thread, because we do not know when it will exit relative to the
1861 // lifetime of this object. We do not want to dlclose() libqcamera while
1862 // LINK_cam_frame is still running.
1863 libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
1864 LOGV("AF: loading libqcamera at %p", libhandle);
1865 if (!libhandle) {
1866 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1867 close(mAutoFocusFd);
1868 mAutoFocusFd = -1;
1869 mAutoFocusThreadRunning = false;
1870 mAutoFocusThreadLock.unlock();
1871 return;
1872 }
1873#endif
1874
Srinivasan Kannan71229622009-12-04 12:05:58 -08001875 afMode = (isp3a_af_mode_t)attr_lookup(focus_modes,
1876 sizeof(focus_modes) / sizeof(str_map),
1877 mParameters.get(CameraParameters::KEY_FOCUS_MODE));
1878
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001879 /* This will block until either AF completes or is cancelled. */
Srinivasan Kannan71229622009-12-04 12:05:58 -08001880 LOGV("af start (fd %d mode %d)", mAutoFocusFd, afMode);
1881 status = native_set_afmode(mAutoFocusFd, afMode);
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001882 LOGV("af done: %d", (int)status);
1883 close(mAutoFocusFd);
1884 mAutoFocusFd = -1;
1885
1886done:
1887 mAutoFocusThreadRunning = false;
1888 mAutoFocusThreadLock.unlock();
1889
1890 mCallbackLock.lock();
1891 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
1892 notify_callback cb = mNotifyCallback;
1893 void *data = mCallbackCookie;
1894 mCallbackLock.unlock();
1895 if (autoFocusEnabled)
1896 cb(CAMERA_MSG_FOCUS, status, 0, data);
1897
1898#if DLOPEN_LIBMMCAMERA
1899 if (libhandle) {
1900 ::dlclose(libhandle);
1901 LOGV("AF: dlclose(libqcamera)");
1902 }
1903#endif
1904}
1905
1906status_t QualcommCameraHardware::cancelAutoFocusInternal()
1907{
1908 LOGV("cancelAutoFocusInternal E");
1909
Srinivasan Kannan71229622009-12-04 12:05:58 -08001910 if(!sensorType->hasAutoFocusSupport){
1911 LOGV("cancelAutoFocusInternal X");
1912 return NO_ERROR;
1913 }
1914
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001915#if 0
1916 if (mAutoFocusFd < 0) {
1917 LOGV("cancelAutoFocusInternal X: not in progress");
1918 return NO_ERROR;
1919 }
1920#endif
1921
1922 status_t rc = native_cancel_afmode(mCameraControlFd, mAutoFocusFd) ?
1923 NO_ERROR :
1924 UNKNOWN_ERROR;
1925
1926 LOGV("cancelAutoFocusInternal X: %d", rc);
1927 return rc;
1928}
1929
1930void *auto_focus_thread(void *user)
1931{
1932 LOGV("auto_focus_thread E");
1933 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
1934 if (obj != 0) {
1935 obj->runAutoFocus();
1936 }
1937 else LOGW("not starting autofocus: the object went away!");
1938 LOGV("auto_focus_thread X");
1939 return NULL;
1940}
1941
1942status_t QualcommCameraHardware::autoFocus()
1943{
1944 LOGV("autoFocus E");
1945 Mutex::Autolock l(&mLock);
1946
Srinivasan Kannan71229622009-12-04 12:05:58 -08001947 if(!sensorType->hasAutoFocusSupport){
Srinivasan Kannandf085222009-12-09 18:31:00 -08001948 bool status = false;
1949 mCallbackLock.lock();
1950 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
1951 notify_callback cb = mNotifyCallback;
1952 void *data = mCallbackCookie;
1953 mCallbackLock.unlock();
1954 if (autoFocusEnabled)
1955 cb(CAMERA_MSG_FOCUS, status, 0, data);
Srinivasan Kannan71229622009-12-04 12:05:58 -08001956 LOGV("autoFocus X");
1957 return NO_ERROR;
1958 }
1959
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001960 if (mCameraControlFd < 0) {
1961 LOGE("not starting autofocus: main control fd %d", mCameraControlFd);
1962 return UNKNOWN_ERROR;
1963 }
1964
1965 {
1966 mAutoFocusThreadLock.lock();
1967 if (!mAutoFocusThreadRunning) {
1968 // Create a detached thread here so that we don't have to wait
1969 // for it when we cancel AF.
1970 pthread_t thr;
1971 pthread_attr_t attr;
1972 pthread_attr_init(&attr);
1973 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1974 mAutoFocusThreadRunning =
1975 !pthread_create(&thr, &attr,
1976 auto_focus_thread, NULL);
1977 if (!mAutoFocusThreadRunning) {
1978 LOGE("failed to start autofocus thread");
1979 mAutoFocusThreadLock.unlock();
1980 return UNKNOWN_ERROR;
1981 }
1982 }
1983 mAutoFocusThreadLock.unlock();
1984 }
1985
1986 LOGV("autoFocus X");
1987 return NO_ERROR;
1988}
1989
1990status_t QualcommCameraHardware::cancelAutoFocus()
1991{
1992 LOGV("cancelAutoFocus E");
1993 Mutex::Autolock l(&mLock);
1994
1995 int rc = NO_ERROR;
1996 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
1997 rc = cancelAutoFocusInternal();
1998 }
1999
2000 LOGV("cancelAutoFocus X");
2001 return rc;
2002}
2003
2004void QualcommCameraHardware::runSnapshotThread(void *data)
2005{
2006 LOGV("runSnapshotThread E");
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002007 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
2008 if (native_start_snapshot(mCameraControlFd))
2009 receiveRawPicture();
2010 else
2011 LOGE("main: native_start_snapshot failed!");
2012 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW){
2013 if(native_start_raw_snapshot(mCameraControlFd)){
2014 receiveRawSnapshot();
2015 } else {
2016 LOGE("main: native_start_raw_snapshot failed!");
2017 }
2018 }
2019
2020 mSnapshotFormat = 0;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002021
2022 mSnapshotThreadWaitLock.lock();
2023 mSnapshotThreadRunning = false;
2024 mSnapshotThreadWait.signal();
2025 mSnapshotThreadWaitLock.unlock();
2026
2027 LOGV("runSnapshotThread X");
2028}
2029
2030void *snapshot_thread(void *user)
2031{
2032 LOGD("snapshot_thread E");
2033 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2034 if (obj != 0) {
2035 obj->runSnapshotThread(user);
2036 }
2037 else LOGW("not starting snapshot thread: the object went away!");
2038 LOGD("snapshot_thread X");
2039 return NULL;
2040}
2041
2042status_t QualcommCameraHardware::takePicture()
2043{
2044 LOGV("takePicture(%d)", mMsgEnabled);
2045 Mutex::Autolock l(&mLock);
2046
2047 // Wait for old snapshot thread to complete.
2048 mSnapshotThreadWaitLock.lock();
2049 while (mSnapshotThreadRunning) {
2050 LOGV("takePicture: waiting for old snapshot thread to complete.");
2051 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
2052 LOGV("takePicture: old snapshot thread completed.");
2053 }
2054
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002055 //mSnapshotFormat is protected by mSnapshotThreadWaitLock
2056 if(mParameters.getPictureFormat() != 0 &&
2057 !strcmp(mParameters.getPictureFormat(),
2058 CameraParameters::PIXEL_FORMAT_RAW))
2059 mSnapshotFormat = PICTURE_FORMAT_RAW;
2060 else
2061 mSnapshotFormat = PICTURE_FORMAT_JPEG;
2062
2063 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
2064 if(!native_prepare_snapshot(mCameraControlFd)) {
2065 mSnapshotThreadWaitLock.unlock();
2066 return UNKNOWN_ERROR;
2067 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002068 }
2069
2070 stopPreviewInternal();
2071
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002072 if(mSnapshotFormat == PICTURE_FORMAT_JPEG){
2073 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
2074 LOGE("initRaw failed. Not taking picture.");
2075 mSnapshotThreadWaitLock.unlock();
2076 return UNKNOWN_ERROR;
2077 }
2078 } else if(mSnapshotFormat == PICTURE_FORMAT_RAW ){
2079 if(!initRawSnapshot()){
2080 LOGE("initRawSnapshot failed. Not taking picture.");
2081 mSnapshotThreadWaitLock.unlock();
2082 return UNKNOWN_ERROR;
2083 }
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002084 }
2085
2086 mShutterLock.lock();
2087 mShutterPending = true;
2088 mShutterLock.unlock();
2089
2090 pthread_attr_t attr;
2091 pthread_attr_init(&attr);
2092 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2093 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
2094 &attr,
2095 snapshot_thread,
2096 NULL);
2097 mSnapshotThreadWaitLock.unlock();
2098
2099 LOGV("takePicture: X");
2100 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
2101}
2102
2103status_t QualcommCameraHardware::cancelPicture()
2104{
2105 status_t rc;
2106 LOGV("cancelPicture: E");
2107 rc = native_stop_snapshot(mCameraControlFd) ? NO_ERROR : UNKNOWN_ERROR;
2108 LOGV("cancelPicture: X: %d", rc);
2109 return rc;
2110}
2111
2112status_t QualcommCameraHardware::setParameters(const CameraParameters& params)
2113{
2114 LOGV("setParameters: E params = %p", &params);
2115
2116 Mutex::Autolock l(&mLock);
2117 status_t rc, final_rc = NO_ERROR;
2118
2119 if ((rc = setPreviewSize(params))) final_rc = rc;
2120 if ((rc = setPictureSize(params))) final_rc = rc;
2121 if ((rc = setJpegQuality(params))) final_rc = rc;
2122 if ((rc = setAntibanding(params))) final_rc = rc;
2123 if ((rc = setEffect(params))) final_rc = rc;
Apurva Rajguru55562b02009-12-03 12:25:35 -08002124 if ((rc = setAutoExposure(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002125 if ((rc = setWhiteBalance(params))) final_rc = rc;
2126 if ((rc = setFlash(params))) final_rc = rc;
2127 if ((rc = setGpsLocation(params))) final_rc = rc;
2128 if ((rc = setRotation(params))) final_rc = rc;
2129 if ((rc = setZoom(params))) final_rc = rc;
2130 if ((rc = setFocusMode(params))) final_rc = rc;
2131 if ((rc = setOrientation(params))) final_rc = rc;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302132 if ((rc = setBrightness(params))) final_rc = rc;
2133 if ((rc = setLensshadeValue(params))) final_rc = rc;
2134 if ((rc = setISOValue(params))) final_rc = rc;
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002135 if ((rc = setPictureFormat(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002136
2137 LOGV("setParameters: X");
2138 return final_rc;
2139}
2140
2141CameraParameters QualcommCameraHardware::getParameters() const
2142{
2143 LOGV("getParameters: EX");
2144 return mParameters;
2145}
2146
2147status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
2148 int32_t arg2)
2149{
2150 LOGV("sendCommand: EX");
2151 return BAD_VALUE;
2152}
2153
2154extern "C" sp<CameraHardwareInterface> openCameraHardware()
2155{
2156 LOGV("openCameraHardware: call createInstance");
2157 return QualcommCameraHardware::createInstance();
2158}
2159
2160wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
2161
2162// If the hardware already exists, return a strong pointer to the current
2163// object. If not, create a new hardware object, put it in the singleton,
2164// and return it.
2165sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
2166{
2167 LOGD("createInstance: E");
2168
2169 Mutex::Autolock lock(&singleton_lock);
2170
2171 // Wait until the previous release is done.
2172 while (singleton_releasing) {
2173 LOGD("Wait for previous release.");
2174 singleton_wait.wait(singleton_lock);
2175 }
2176
2177 if (singleton != 0) {
2178 sp<CameraHardwareInterface> hardware = singleton.promote();
2179 if (hardware != 0) {
2180 LOGD("createInstance: X return existing hardware=%p", &(*hardware));
2181 return hardware;
2182 }
2183 }
2184
2185 {
2186 struct stat st;
2187 int rc = stat("/dev/oncrpc", &st);
2188 if (rc < 0) {
2189 LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
2190 return NULL;
2191 }
2192 }
2193
2194 QualcommCameraHardware *cam = new QualcommCameraHardware();
2195 sp<QualcommCameraHardware> hardware(cam);
2196 singleton = hardware;
2197
2198 if (!cam->startCamera()) {
2199 LOGE("%s: startCamera failed!", __FUNCTION__);
2200 return NULL;
2201 }
2202
2203 cam->initDefaultParameters();
2204 LOGD("createInstance: X created hardware=%p", &(*hardware));
2205 return hardware;
2206}
2207
2208// For internal use only, hence the strong pointer to the derived type.
2209sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
2210{
2211 sp<CameraHardwareInterface> hardware = singleton.promote();
2212 if (hardware != 0) {
2213 // LOGV("getInstance: X old instance of hardware");
2214 return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
2215 } else {
2216 LOGV("getInstance: X new instance of hardware");
2217 return sp<QualcommCameraHardware>();
2218 }
2219}
2220
2221void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
2222{
2223// LOGV("receivePreviewFrame E");
2224
2225 if (!mCameraRunning) {
2226 LOGE("ignoring preview callback--camera has been stopped");
2227 return;
2228 }
2229
2230 mCallbackLock.lock();
2231 int msgEnabled = mMsgEnabled;
2232 data_callback pcb = mDataCallback;
2233 void *pdata = mCallbackCookie;
2234 data_callback_timestamp rcb = mDataCallbackTimestamp;
2235 void *rdata = mCallbackCookie;
2236 mCallbackLock.unlock();
2237
2238 // Find the offset within the heap of the current buffer.
2239 ssize_t offset =
2240 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
2241 offset /= mPreviewHeap->mAlignedBufferSize;
2242
2243 mInPreviewCallback = true;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08002244 if((mUseOverlay == true) && (mOverlay != NULL) ) {
2245 ssize_t offset_addr =
2246 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
2247 mOverlayLock.lock();
2248 mOverlay->setFd(mPreviewHeap->mHeap->getHeapID());
2249 mOverlay->queueBuffer((void *)offset_addr);
2250 mOverlayLock.unlock();
2251 LOGV(" Queueing buffer %x from HAL for display ", offset_addr );
2252 }
2253 /* In case of Overlay, the MSG_PREVIEW_FRAME will be disabled
2254 * second frame onwards. Hence we can keep this piece of code
2255 * in overlay case as well. */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002256 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
2257 pcb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap->mBuffers[offset],
2258 pdata);
2259
2260 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
2261 rcb(systemTime(), CAMERA_MSG_VIDEO_FRAME, mPreviewHeap->mBuffers[offset], rdata);
2262 Mutex::Autolock rLock(&mRecordFrameLock);
2263 if (mReleasedRecordingFrame != true) {
2264 LOGV("block waiting for frame release");
2265 mRecordWait.wait(mRecordFrameLock);
2266 LOGV("frame released, continuing");
2267 }
2268 mReleasedRecordingFrame = false;
2269 }
2270 mInPreviewCallback = false;
2271
2272// LOGV("receivePreviewFrame X");
2273}
2274
2275status_t QualcommCameraHardware::startRecording()
2276{
2277 LOGV("startRecording E");
2278 Mutex::Autolock l(&mLock);
2279 mReleasedRecordingFrame = false;
2280 return startPreviewInternal();
2281}
2282
2283void QualcommCameraHardware::stopRecording()
2284{
2285 LOGV("stopRecording: E");
2286 Mutex::Autolock l(&mLock);
2287 {
2288 mRecordFrameLock.lock();
2289 mReleasedRecordingFrame = true;
2290 mRecordWait.signal();
2291 mRecordFrameLock.unlock();
2292
2293 if(mDataCallback && (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
2294 LOGV("stopRecording: X, preview still in progress");
2295 return;
2296 }
2297 }
2298
2299 stopPreviewInternal();
2300 LOGV("stopRecording: X");
2301}
2302
2303void QualcommCameraHardware::releaseRecordingFrame(
2304 const sp<IMemory>& mem __attribute__((unused)))
2305{
2306 LOGV("releaseRecordingFrame E");
2307 Mutex::Autolock rLock(&mRecordFrameLock);
2308 mReleasedRecordingFrame = true;
2309 mRecordWait.signal();
2310 LOGV("releaseRecordingFrame X");
2311}
2312
2313bool QualcommCameraHardware::recordingEnabled()
2314{
2315 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
2316}
2317
2318void QualcommCameraHardware::notifyShutter(common_crop_t *crop)
2319{
2320 mShutterLock.lock();
2321 image_rect_type size;
2322
2323 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
2324 LOGV("out2_w=%d, out2_h=%d, in2_w=%d, in2_h=%d",
2325 crop->out2_w, crop->out2_h, crop->in2_w, crop->in2_h);
2326 LOGV("out1_w=%d, out1_h=%d, in1_w=%d, in1_h=%d",
2327 crop->out1_w, crop->out1_h, crop->in1_w, crop->in1_h);
2328
2329 // To workaround a bug in MDP which happens if either
2330 // dimension > 2048, we display the thumbnail instead.
2331 mDisplayHeap = mRawHeap;
2332 if (crop->in1_w == 0 || crop->in1_h == 0) {
2333 // Full size
2334 size.width = mDimension.picture_width;
2335 size.height = mDimension.picture_height;
2336 if (size.width > 2048 || size.height > 2048) {
2337 size.width = mDimension.ui_thumbnail_width;
2338 size.height = mDimension.ui_thumbnail_height;
2339 mDisplayHeap = mThumbnailHeap;
2340 }
2341 } else {
2342 // Cropped
2343 size.width = crop->in2_w & ~1;
2344 size.height = crop->in2_h & ~1;
2345 if (size.width > 2048 || size.height > 2048) {
2346 size.width = crop->in1_w & ~1;
2347 size.height = crop->in1_h & ~1;
2348 mDisplayHeap = mThumbnailHeap;
2349 }
2350 }
2351
2352 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
2353 mCallbackCookie);
2354 mShutterPending = false;
2355 }
2356 mShutterLock.unlock();
2357}
2358
2359static void receive_shutter_callback(common_crop_t *crop)
2360{
2361 LOGV("receive_shutter_callback: E");
2362 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2363 if (obj != 0) {
2364 obj->notifyShutter(crop);
2365 }
2366 LOGV("receive_shutter_callback: X");
2367}
2368
2369// Crop the picture in place.
2370static void crop_yuv420(uint32_t width, uint32_t height,
2371 uint32_t cropped_width, uint32_t cropped_height,
2372 uint8_t *image)
2373{
2374 uint32_t i, x, y;
2375 uint8_t* chroma_src, *chroma_dst;
2376
2377 // Calculate the start position of the cropped area.
2378 x = (width - cropped_width) / 2;
2379 y = (height - cropped_height) / 2;
2380 x &= ~1;
2381 y &= ~1;
2382
2383 // Copy luma component.
2384 for(i = 0; i < cropped_height; i++)
2385 memcpy(image + i * cropped_width,
2386 image + width * (y + i) + x,
2387 cropped_width);
2388
2389 chroma_src = image + width * height;
2390 chroma_dst = image + cropped_width * cropped_height;
2391
2392 // Copy chroma components.
2393 cropped_height /= 2;
2394 y /= 2;
2395 for(i = 0; i < cropped_height; i++)
2396 memcpy(chroma_dst + i * cropped_width,
2397 chroma_src + width * (y + i) + x,
2398 cropped_width);
2399}
2400
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002401
2402void QualcommCameraHardware::receiveRawSnapshot(){
2403 LOGV("receiveRawSnapshot E");
2404
2405 Mutex::Autolock cbLock(&mCallbackLock);
2406
2407 notifyShutter(&mCrop);
2408
2409 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2410
2411 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
2412 LOGE("receiveRawSnapshot X: native_get_picture failed!");
2413 return;
2414 }
2415
2416 //Create a Ashmem heap to copy data from PMem heap for application layer
2417 if(mRawSnapshotAshmemHeap != NULL){
2418 LOGV("receiveRawSnapshot: clearing old mRawSnapShotAshmemHeap.");
2419 mRawSnapshotAshmemHeap.clear();
2420 }
2421 mRawSnapshotAshmemHeap = new AshmemPool(
2422 mRawSnapShotPmemHeap->mBufferSize,
2423 mRawSnapShotPmemHeap->mNumBuffers,
2424 mRawSnapShotPmemHeap->mFrameSize,
2425 "raw ashmem snapshot camera"
2426 );
2427
2428 if(!mRawSnapshotAshmemHeap->initialized()){
2429 LOGE("receiveRawSnapshot X: error initializing mRawSnapshotHeap");
2430 deinitRawSnapshot();
2431 return;
2432 }
2433
2434 memcpy(mRawSnapshotAshmemHeap->mHeap->base(),
2435 mRawSnapShotPmemHeap->mHeap->base(),
2436 mRawSnapShotPmemHeap->mHeap->getSize());
2437
2438 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mRawSnapshotAshmemHeap->mBuffers[0],
2439 mCallbackCookie);
2440
2441 }
2442
2443 //cleanup
2444 deinitRawSnapshot();
2445
2446 LOGV("receiveRawSnapshot X");
2447}
2448
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002449void QualcommCameraHardware::receiveRawPicture()
2450{
2451 LOGV("receiveRawPicture: E");
2452
2453 Mutex::Autolock cbLock(&mCallbackLock);
2454 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)) {
2455 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
2456 LOGE("getPicture failed!");
2457 return;
2458 }
2459 mCrop.in1_w &= ~1;
2460 mCrop.in1_h &= ~1;
2461 mCrop.in2_w &= ~1;
2462 mCrop.in2_h &= ~1;
2463
2464 // By the time native_get_picture returns, picture is taken. Call
2465 // shutter callback if cam config thread has not done that.
2466 notifyShutter(&mCrop);
2467
2468 // Crop the image if zoomed.
2469 if (mCrop.in2_w != 0 && mCrop.in2_h != 0) {
2470 crop_yuv420(mCrop.out2_w, mCrop.out2_h, mCrop.in2_w, mCrop.in2_h,
2471 (uint8_t *)mRawHeap->mHeap->base());
2472 crop_yuv420(mCrop.out1_w, mCrop.out1_h, mCrop.in1_w, mCrop.in1_h,
2473 (uint8_t *)mThumbnailHeap->mHeap->base());
2474 // We do not need jpeg encoder to upscale the image. Set the new
2475 // dimension for encoder.
2476 mDimension.orig_picture_dx = mCrop.in2_w;
2477 mDimension.orig_picture_dy = mCrop.in2_h;
2478 mDimension.thumbnail_width = mCrop.in1_w;
2479 mDimension.thumbnail_height = mCrop.in1_h;
2480 memset(&mCrop, 0, sizeof(mCrop));
2481 }
2482
2483 mDataCallback(CAMERA_MSG_RAW_IMAGE, mDisplayHeap->mBuffers[0],
2484 mCallbackCookie);
2485 }
2486 else LOGV("Raw-picture callback was canceled--skipping.");
2487
2488 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2489 mJpegSize = 0;
2490 if (LINK_jpeg_encoder_init()) {
2491 if(native_jpeg_encode()) {
2492 LOGV("receiveRawPicture: X (success)");
2493 return;
2494 }
2495 LOGE("jpeg encoding failed");
2496 }
2497 else LOGE("receiveRawPicture X: jpeg_encoder_init failed.");
2498 }
2499 else LOGV("JPEG callback is NULL, not encoding image.");
2500 deinitRaw();
2501 LOGV("receiveRawPicture: X");
2502}
2503
2504void QualcommCameraHardware::receiveJpegPictureFragment(
2505 uint8_t *buff_ptr, uint32_t buff_size)
2506{
2507 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
2508 remaining -= mJpegSize;
2509 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
2510
2511 LOGV("receiveJpegPictureFragment size %d", buff_size);
2512 if (buff_size > remaining) {
2513 LOGE("receiveJpegPictureFragment: size %d exceeds what "
2514 "remains in JPEG heap (%d), truncating",
2515 buff_size,
2516 remaining);
2517 buff_size = remaining;
2518 }
2519 memcpy(base + mJpegSize, buff_ptr, buff_size);
2520 mJpegSize += buff_size;
2521}
2522
2523void QualcommCameraHardware::receiveJpegPicture(void)
2524{
2525 LOGV("receiveJpegPicture: E image (%d uint8_ts out of %d)",
2526 mJpegSize, mJpegHeap->mBufferSize);
2527 Mutex::Autolock cbLock(&mCallbackLock);
2528
2529 int index = 0, rc;
2530
2531 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2532 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
2533 // that the JPEG image's size will probably change from one snapshot
2534 // to the next, so we cannot reuse the MemoryBase object.
2535 sp<MemoryBase> buffer = new
2536 MemoryBase(mJpegHeap->mHeap,
2537 index * mJpegHeap->mBufferSize +
2538 0,
2539 mJpegSize);
2540 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
2541 buffer = NULL;
2542 }
2543 else LOGV("JPEG callback was cancelled--not delivering image.");
2544
2545 LINK_jpeg_encoder_join();
2546 deinitRaw();
2547
2548 LOGV("receiveJpegPicture: X callback done.");
2549}
2550
2551bool QualcommCameraHardware::previewEnabled()
2552{
2553 return mCameraRunning && mDataCallback && (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME);
2554}
2555
2556status_t QualcommCameraHardware::setPreviewSize(const CameraParameters& params)
2557{
2558 int width, height;
2559 params.getPreviewSize(&width, &height);
2560 LOGV("requested preview size %d x %d", width, height);
2561
2562 // Validate the preview size
2563 for (size_t i = 0; i < PREVIEW_SIZE_COUNT; ++i) {
2564 if (width == preview_sizes[i].width
2565 && height == preview_sizes[i].height) {
2566 mParameters.setPreviewSize(width, height);
2567 mDimension.display_width = width;
2568 mDimension.display_height = height;
2569 return NO_ERROR;
2570 }
2571 }
2572 LOGE("Invalid preview size requested: %dx%d", width, height);
2573 return BAD_VALUE;
2574}
2575
2576status_t QualcommCameraHardware::setPictureSize(const CameraParameters& params)
2577{
2578 int width, height;
2579 params.getPictureSize(&width, &height);
2580 LOGV("requested picture size %d x %d", width, height);
2581
2582 // Validate the picture size
2583 for (int i = 0; i < PICTURE_SIZE_COUNT; ++i) {
2584 if (width == picture_sizes[i].width
2585 && height == picture_sizes[i].height) {
2586 mParameters.setPictureSize(width, height);
2587 mDimension.picture_width = width;
2588 mDimension.picture_height = height;
2589 return NO_ERROR;
2590 }
2591 }
2592 LOGE("Invalid picture size requested: %dx%d", width, height);
2593 return BAD_VALUE;
2594}
2595
2596status_t QualcommCameraHardware::setJpegQuality(const CameraParameters& params) {
2597 status_t rc = NO_ERROR;
2598 int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
2599 if (quality > 0 && quality <= 100) {
2600 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
2601 } else {
2602 LOGE("Invalid jpeg quality=%d", quality);
2603 rc = BAD_VALUE;
2604 }
2605
2606 quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
2607 if (quality > 0 && quality <= 100) {
2608 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
2609 } else {
2610 LOGE("Invalid jpeg thumbnail quality=%d", quality);
2611 rc = BAD_VALUE;
2612 }
2613 return rc;
2614}
2615
2616status_t QualcommCameraHardware::setEffect(const CameraParameters& params)
2617{
2618 const char *str = params.get(CameraParameters::KEY_EFFECT);
2619 if (str != NULL) {
2620 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
2621 if (value != NOT_FOUND) {
2622 mParameters.set(CameraParameters::KEY_EFFECT, str);
2623 bool ret = native_set_parm(CAMERA_SET_PARM_EFFECT, sizeof(value),
2624 (void *)&value);
2625 return ret ? NO_ERROR : UNKNOWN_ERROR;
2626 }
2627 }
2628 LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
2629 return BAD_VALUE;
2630}
2631
Apurva Rajguru55562b02009-12-03 12:25:35 -08002632status_t QualcommCameraHardware::setAutoExposure(const CameraParameters& params)
2633{
2634 const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
2635 if (str != NULL) {
2636 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
2637 if (value != NOT_FOUND) {
2638 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
2639 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE, sizeof(value),
2640 (void *)&value);
2641 return ret ? NO_ERROR : UNKNOWN_ERROR;
2642 }
2643 }
2644 LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
2645 return BAD_VALUE;
2646}
2647
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302648status_t QualcommCameraHardware::setBrightness(const CameraParameters& params) {
2649 int brightness = params.getInt("luma-adaptation");
2650 if (mBrightness != brightness) {
2651 LOGV(" new brightness value : %d ", brightness);
2652 mBrightness = brightness;
2653
2654 bool ret = native_set_parm(CAMERA_SET_PARM_BRIGHTNESS, sizeof(mBrightness),
2655 (void *)&mBrightness);
2656 return ret ? NO_ERROR : UNKNOWN_ERROR;
2657 } else {
2658 return NO_ERROR;
2659 }
2660}
2661
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002662status_t QualcommCameraHardware::setWhiteBalance(const CameraParameters& params)
2663{
2664 const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
2665 if (str != NULL) {
2666 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
2667 if (value != NOT_FOUND) {
2668 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
2669 bool ret = native_set_parm(CAMERA_SET_PARM_WB, sizeof(value),
2670 (void *)&value);
2671 return ret ? NO_ERROR : UNKNOWN_ERROR;
2672 }
2673 }
2674 LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
2675 return BAD_VALUE;
2676}
2677
2678status_t QualcommCameraHardware::setFlash(const CameraParameters& params)
2679{
2680 if (!mSensorInfo.flash_enabled) {
2681 LOGV("%s: flash not supported", __FUNCTION__);
2682 return NO_ERROR;
2683 }
2684
2685 const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
2686 if (str != NULL) {
2687 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
2688 if (value != NOT_FOUND) {
2689 mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
2690 bool ret = native_set_parm(CAMERA_SET_PARM_LED_MODE,
2691 sizeof(value), (void *)&value);
2692 return ret ? NO_ERROR : UNKNOWN_ERROR;
2693 }
2694 }
2695 LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
2696 return BAD_VALUE;
2697}
2698
2699status_t QualcommCameraHardware::setAntibanding(const CameraParameters& params)
2700{
2701 const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
2702 if (str != NULL) {
2703 int value = (camera_antibanding_type)attr_lookup(
2704 antibanding, sizeof(antibanding) / sizeof(str_map), str);
2705 if (value != NOT_FOUND) {
2706 camera_antibanding_type temp = (camera_antibanding_type) value;
2707 // We don't have auto antibanding now, and simply set the frequency by country.
2708 if (temp == CAMERA_ANTIBANDING_AUTO) {
2709 temp = camera_get_location();
2710 }
2711 mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
2712 native_set_parm(CAMERA_SET_PARM_ANTIBANDING, sizeof(camera_antibanding_type), (void *)&temp);
2713 return NO_ERROR;
2714 }
2715 }
2716 LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
2717 return BAD_VALUE;
2718}
2719
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302720status_t QualcommCameraHardware::setLensshadeValue(const CameraParameters& params)
2721{
2722 const char *str = params.get(CameraParameters::KEY_LENSSHADE);
2723 if (str != NULL) {
2724 int value = attr_lookup(lensshade,
2725 sizeof(lensshade) / sizeof(str_map), str);
2726 if (value != NOT_FOUND) {
2727 int8_t temp = (int8_t)value;
2728 mParameters.set(CameraParameters::KEY_LENSSHADE, str);
2729 native_set_parm(CAMERA_SET_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
2730 return NO_ERROR;
2731 }
2732 }
2733 LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
2734 return BAD_VALUE;
2735}
2736
2737status_t QualcommCameraHardware::setISOValue(const CameraParameters& params) {
2738 const char *str = params.get(CameraParameters::KEY_ISO_MODE);
2739 if (str != NULL) {
2740 int value = (camera_iso_mode_type)attr_lookup(
2741 iso, sizeof(iso) / sizeof(str_map), str);
2742 if (value != NOT_FOUND) {
2743 camera_iso_mode_type temp = (camera_iso_mode_type) value;
2744 mParameters.set(CameraParameters::KEY_ISO_MODE, str);
2745 native_set_parm(CAMERA_SET_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
2746 return NO_ERROR;
2747 }
2748 }
2749 LOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
2750 return BAD_VALUE;
2751}
2752
2753
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002754status_t QualcommCameraHardware::setGpsLocation(const CameraParameters& params)
2755{
2756 const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
2757 if (latitude) {
2758 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
2759 }
2760
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002761 const char *latitudeRef = params.get(CameraParameters::KEY_GPS_LATITUDE_REF);
2762 if (latitudeRef) {
2763 mParameters.set(CameraParameters::KEY_GPS_LATITUDE_REF, latitudeRef);
2764 }
2765
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002766 const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
2767 if (longitude) {
2768 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
2769 }
2770
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002771 const char *longitudeRef = params.get(CameraParameters::KEY_GPS_LONGITUDE_REF);
2772 if (longitudeRef) {
2773 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE_REF, longitudeRef);
2774 }
2775
2776 const char *altitudeRef = params.get(CameraParameters::KEY_GPS_ALTITUDE_REF);
2777 if (altitudeRef) {
2778 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE_REF, altitudeRef);
2779 }
2780
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002781 const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
2782 if (altitude) {
2783 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
2784 }
2785
Apurva Rajguru66bdd7f2009-12-10 19:28:02 -08002786 const char *status = params.get(CameraParameters::KEY_GPS_STATUS);
2787 if (status) {
2788 mParameters.set(CameraParameters::KEY_GPS_STATUS, status);
2789 }
2790
2791 const char *dateTime = params.get(CameraParameters::KEY_EXIF_DATETIME);
2792 if (dateTime) {
2793 mParameters.set(CameraParameters::KEY_EXIF_DATETIME, dateTime);
2794 }
2795
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002796 const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
2797 if (timestamp) {
2798 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
2799 }
2800 return NO_ERROR;
2801}
2802
2803status_t QualcommCameraHardware::setRotation(const CameraParameters& params)
2804{
2805 status_t rc = NO_ERROR;
2806 int rotation = params.getInt(CameraParameters::KEY_ROTATION);
2807 if (rotation != NOT_FOUND) {
2808 if (rotation == 0 || rotation == 90 || rotation == 180
2809 || rotation == 270) {
2810 mParameters.set(CameraParameters::KEY_ROTATION, rotation);
2811 } else {
2812 LOGE("Invalid rotation value: %d", rotation);
2813 rc = BAD_VALUE;
2814 }
2815 }
2816 return rc;
2817}
2818
2819status_t QualcommCameraHardware::setZoom(const CameraParameters& params)
2820{
2821 status_t rc = NO_ERROR;
2822 // No matter how many different zoom values the driver can provide, HAL
2823 // provides applictations the same number of zoom levels. The maximum driver
2824 // zoom value depends on sensor output (VFE input) and preview size (VFE
2825 // output) because VFE can only crop and cannot upscale. If the preview size
2826 // is bigger, the maximum zoom ratio is smaller. However, we want the
2827 // zoom ratio of each zoom level is always the same whatever the preview
2828 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
2829 // we need to have a fixed maximum zoom value and do read it from the
2830 // driver.
2831 static const int ZOOM_STEP = 6;
2832 int32_t zoom_level = params.getInt("zoom");
2833
2834 LOGI("Set zoom=%d", zoom_level);
2835 if(zoom_level >= 0 && zoom_level <= MAX_ZOOM_LEVEL) {
2836 mParameters.set("zoom", zoom_level);
2837 int32_t zoom_value = ZOOM_STEP * zoom_level;
2838 bool ret = native_set_parm(CAMERA_SET_PARM_ZOOM,
2839 sizeof(zoom_value), (void *)&zoom_value);
2840 rc = ret ? NO_ERROR : UNKNOWN_ERROR;
2841 } else {
2842 rc = BAD_VALUE;
2843 }
2844
2845 return rc;
2846}
2847
2848status_t QualcommCameraHardware::setFocusMode(const CameraParameters& params)
2849{
2850 const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
2851 if (str != NULL) {
2852 int32_t value = attr_lookup(focus_modes,
2853 sizeof(focus_modes) / sizeof(str_map), str);
2854 if (value != NOT_FOUND) {
2855 mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
2856 // Focus step is reset to infinity when preview is started. We do
2857 // not need to do anything now.
2858 return NO_ERROR;
2859 }
2860 }
2861 LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
2862 return BAD_VALUE;
2863}
2864
2865status_t QualcommCameraHardware::setOrientation(const CameraParameters& params)
2866{
2867 const char *str = params.get("orientation");
2868
2869 if (str != NULL) {
2870 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
2871 // Camera service needs this to decide if the preview frames and raw
2872 // pictures should be rotated.
2873 mParameters.set("orientation", str);
2874 } else {
2875 LOGE("Invalid orientation value: %s", str);
2876 return BAD_VALUE;
2877 }
2878 }
2879 return NO_ERROR;
2880}
2881
Srinivasan Kannan39dae8e2009-12-03 15:52:34 -08002882status_t QualcommCameraHardware::setPictureFormat(const CameraParameters& params)
2883{
2884 const char * str = params.get(CameraParameters::KEY_PICTURE_FORMAT);
2885
2886 if(str != NULL){
2887 int32_t value = attr_lookup(picture_formats,
2888 sizeof(picture_formats) / sizeof(str_map), str);
2889 if(value != NOT_FOUND){
2890 mParameters.set(CameraParameters::KEY_PICTURE_FORMAT, str);
2891 } else {
2892 LOGE("Invalid Picture Format value: %s", str);
2893 return BAD_VALUE;
2894 }
2895 }
2896 return NO_ERROR;
2897}
2898
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002899QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
2900 int frame_size,
2901 const char *name) :
2902 mBufferSize(buffer_size),
2903 mNumBuffers(num_buffers),
2904 mFrameSize(frame_size),
2905 mBuffers(NULL), mName(name)
2906{
2907 int page_size_minus_1 = getpagesize() - 1;
2908 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
2909}
2910
2911void QualcommCameraHardware::MemPool::completeInitialization()
2912{
2913 // If we do not know how big the frame will be, we wait to allocate
2914 // the buffers describing the individual frames until we do know their
2915 // size.
2916
2917 if (mFrameSize > 0) {
2918 mBuffers = new sp<MemoryBase>[mNumBuffers];
2919 for (int i = 0; i < mNumBuffers; i++) {
2920 mBuffers[i] = new
2921 MemoryBase(mHeap,
2922 i * mAlignedBufferSize,
2923 mFrameSize);
2924 }
2925 }
2926}
2927
2928QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
2929 int frame_size,
2930 const char *name) :
2931 QualcommCameraHardware::MemPool(buffer_size,
2932 num_buffers,
2933 frame_size,
2934 name)
2935{
2936 LOGV("constructing MemPool %s backed by ashmem: "
2937 "%d frames @ %d uint8_ts, "
2938 "buffer size %d",
2939 mName,
2940 num_buffers, frame_size, buffer_size);
2941
2942 int page_mask = getpagesize() - 1;
2943 int ashmem_size = buffer_size * num_buffers;
2944 ashmem_size += page_mask;
2945 ashmem_size &= ~page_mask;
2946
2947 mHeap = new MemoryHeapBase(ashmem_size);
2948
2949 completeInitialization();
2950}
2951
2952static bool register_buf(int camfd,
2953 int size,
2954 int pmempreviewfd,
2955 uint32_t offset,
2956 uint8_t *buf,
2957 int pmem_type,
2958 bool vfe_can_write,
2959 bool register_buffer = true);
2960
2961QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
2962 int flags,
2963 int camera_control_fd,
2964 int pmem_type,
2965 int buffer_size, int num_buffers,
2966 int frame_size,
2967 const char *name) :
2968 QualcommCameraHardware::MemPool(buffer_size,
2969 num_buffers,
2970 frame_size,
2971 name),
2972 mPmemType(pmem_type),
2973 mCameraControlFd(dup(camera_control_fd))
2974{
2975 LOGV("constructing MemPool %s backed by pmem pool %s: "
2976 "%d frames @ %d bytes, buffer size %d",
2977 mName,
2978 pmem_pool, num_buffers, frame_size,
2979 buffer_size);
2980
2981 LOGV("%s: duplicating control fd %d --> %d",
2982 __FUNCTION__,
2983 camera_control_fd, mCameraControlFd);
2984
2985 // Make a new mmap'ed heap that can be shared across processes.
2986 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
2987 mAlignedSize = mAlignedBufferSize * num_buffers;
2988
2989 sp<MemoryHeapBase> masterHeap =
2990 new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
2991
2992 if (masterHeap->getHeapID() < 0) {
2993 LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
2994 masterHeap.clear();
2995 return;
2996 }
2997
2998 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
2999 if (pmemHeap->getHeapID() >= 0) {
3000 pmemHeap->slap();
3001 masterHeap.clear();
3002 mHeap = pmemHeap;
3003 pmemHeap.clear();
3004
3005 mFd = mHeap->getHeapID();
3006 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
3007 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
3008 pmem_pool,
3009 ::strerror(errno), errno);
3010 mHeap.clear();
3011 return;
3012 }
3013
3014 LOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
3015 pmem_pool,
3016 mFd,
3017 mSize.len);
3018 LOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
3019 // Unregister preview buffers with the camera drivers. Allow the VFE to write
3020 // to all preview buffers except for the last one.
3021 for (int cnt = 0; cnt < num_buffers; ++cnt) {
3022 register_buf(mCameraControlFd,
3023 mBufferSize,
3024 mHeap->getHeapID(),
3025 mAlignedBufferSize * cnt,
3026 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
3027 pmem_type,
3028 !(cnt == num_buffers - 1 && pmem_type == MSM_PMEM_OUTPUT2));
3029 }
3030
3031 completeInitialization();
3032 }
3033 else LOGE("pmem pool %s error: could not create master heap!",
3034 pmem_pool);
3035}
3036
3037QualcommCameraHardware::PmemPool::~PmemPool()
3038{
3039 LOGV("%s: %s E", __FUNCTION__, mName);
3040 if (mHeap != NULL) {
3041 // Unregister preview buffers with the camera drivers.
3042 for (int cnt = 0; cnt < mNumBuffers; ++cnt) {
3043 register_buf(mCameraControlFd,
3044 mBufferSize,
3045 mHeap->getHeapID(),
3046 mAlignedBufferSize * cnt,
3047 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
3048 mPmemType,
3049 false,
3050 false /* unregister */);
3051 }
3052 }
3053 LOGV("destroying PmemPool %s: closing control fd %d",
3054 mName,
3055 mCameraControlFd);
3056 close(mCameraControlFd);
3057 LOGV("%s: %s X", __FUNCTION__, mName);
3058}
3059
3060QualcommCameraHardware::MemPool::~MemPool()
3061{
3062 LOGV("destroying MemPool %s", mName);
3063 if (mFrameSize > 0)
3064 delete [] mBuffers;
3065 mHeap.clear();
3066 LOGV("destroying MemPool %s completed", mName);
3067}
3068
3069static bool register_buf(int camfd,
3070 int size,
3071 int pmempreviewfd,
3072 uint32_t offset,
3073 uint8_t *buf,
3074 int pmem_type,
3075 bool vfe_can_write,
3076 bool register_buffer)
3077{
3078 struct msm_pmem_info pmemBuf;
3079
3080 pmemBuf.type = pmem_type;
3081 pmemBuf.fd = pmempreviewfd;
3082 pmemBuf.offset = offset;
3083 pmemBuf.len = size;
3084 pmemBuf.vaddr = buf;
3085 pmemBuf.y_off = 0;
3086 pmemBuf.cbcr_off = PAD_TO_WORD(size * 2 / 3);
3087 pmemBuf.active = vfe_can_write;
3088
3089 LOGV("register_buf: camfd = %d, reg = %d buffer = %p",
3090 camfd, !register_buffer, buf);
3091 if (ioctl(camfd,
3092 register_buffer ?
3093 MSM_CAM_IOCTL_REGISTER_PMEM :
3094 MSM_CAM_IOCTL_UNREGISTER_PMEM,
3095 &pmemBuf) < 0) {
3096 LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM fd %d error %s",
3097 camfd,
3098 strerror(errno));
3099 return false;
3100 }
3101 return true;
3102}
3103
3104status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
3105{
3106 const size_t SIZE = 256;
3107 char buffer[SIZE];
3108 String8 result;
3109 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
3110 result.append(buffer);
3111 if (mName) {
3112 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
3113 result.append(buffer);
3114 }
3115 if (mHeap != 0) {
3116 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
3117 mHeap->getBase(), mHeap->getSize(),
3118 mHeap->getFlags(), mHeap->getDevice());
3119 result.append(buffer);
3120 }
3121 snprintf(buffer, 255,
3122 "buffer size (%d), number of buffers (%d), frame size(%d)",
3123 mBufferSize, mNumBuffers, mFrameSize);
3124 result.append(buffer);
3125 write(fd, result.string(), result.size());
3126 return NO_ERROR;
3127}
3128
3129static void receive_camframe_callback(struct msm_frame *frame)
3130{
3131 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3132 if (obj != 0) {
3133 obj->receivePreviewFrame(frame);
3134 }
3135}
3136
3137static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size)
3138{
3139 LOGV("receive_jpeg_fragment_callback E");
3140 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3141 if (obj != 0) {
3142 obj->receiveJpegPictureFragment(buff_ptr, buff_size);
3143 }
3144 LOGV("receive_jpeg_fragment_callback X");
3145}
3146
3147static void receive_jpeg_callback(jpeg_event_t status)
3148{
3149 LOGV("receive_jpeg_callback E (completion status %d)", status);
3150 if (status == JPEG_EVENT_DONE) {
3151 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3152 if (obj != 0) {
3153 obj->receiveJpegPicture();
3154 }
3155 }
3156 LOGV("receive_jpeg_callback X");
3157}
3158
3159void QualcommCameraHardware::setCallbacks(notify_callback notify_cb,
3160 data_callback data_cb,
3161 data_callback_timestamp data_cb_timestamp,
3162 void* user)
3163{
3164 Mutex::Autolock lock(mLock);
3165 mNotifyCallback = notify_cb;
3166 mDataCallback = data_cb;
3167 mDataCallbackTimestamp = data_cb_timestamp;
3168 mCallbackCookie = user;
3169}
3170
3171void QualcommCameraHardware::enableMsgType(int32_t msgType)
3172{
3173 Mutex::Autolock lock(mLock);
3174 mMsgEnabled |= msgType;
3175}
3176
3177void QualcommCameraHardware::disableMsgType(int32_t msgType)
3178{
3179 Mutex::Autolock lock(mLock);
3180 mMsgEnabled &= ~msgType;
3181}
3182
3183bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
3184{
3185 return (mMsgEnabled & msgType);
3186}
3187
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08003188bool QualcommCameraHardware::useOverlay(void)
3189{
3190 char value[PROPERTY_VALUE_MAX];
3191 property_get("ro.product.device",value," ");
3192
3193 if(!strcmp(value,"msm7630_surf")) {
3194 /* Only 7x30 supports Overlay */
3195 mUseOverlay = TRUE;
3196 } else
3197 mUseOverlay = FALSE;
3198
3199 LOGV(" Using Overlay : %s ", mUseOverlay ? "YES" : "NO" );
3200 return mUseOverlay;
3201}
3202
3203status_t QualcommCameraHardware::setOverlay(const sp<Overlay> &Overlay)
3204{
3205 if( Overlay != NULL) {
3206 LOGV(" Valid overlay object ");
3207 mOverlayLock.lock();
3208 mOverlay = Overlay;
3209 mOverlayLock.unlock();
3210 } else {
3211 LOGE(" Overlay object NULL. returning ");
3212 return UNKNOWN_ERROR;
3213 }
3214 return NO_ERROR;
3215}
Kiran Kumar H N215cac42009-12-08 01:53:46 -08003216
3217void QualcommCameraHardware::receive_camframetimeout(void) {
3218 LOGV("receive_camframetimeout: E");
3219 Mutex::Autolock l(&mCamframeTimeoutLock);
3220 camframe_timeout_flag = TRUE;
3221 LOGV("receive_camframetimeout: X");
3222}
3223
3224static void receive_camframetimeout_callback(void) {
3225 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
3226 if (obj != 0) {
3227 obj->receive_camframetimeout();
3228 }
3229}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08003230}; // namespace android