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