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