blob: 0da585f35d7c5e094e2b19ceeec3d8b96d3cfd84 [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>
Priya Komarlingamb85535d2009-11-30 13:06:01 -080032#if HAVE_ANDROID_OS
33#include <linux/android_pmem.h>
34#endif
35#include <linux/ioctl.h>
36#include <ui/CameraParameters.h>
37
38#define LIKELY(exp) __builtin_expect(!!(exp), 1)
39#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
40
41extern "C" {
42#include <fcntl.h>
43#include <time.h>
44#include <pthread.h>
45#include <stdio.h>
46#include <string.h>
47#include <unistd.h>
48#include <termios.h>
49#include <assert.h>
50#include <stdlib.h>
51#include <ctype.h>
52#include <signal.h>
53#include <errno.h>
54#include <sys/mman.h>
55#include <sys/system_properties.h>
56#include <sys/time.h>
57#include <stdlib.h>
58
59#include <media/msm_camera.h>
60
61#include <camera.h>
62#include <camframe.h>
63#include <mm-still/jpeg/jpege.h>
64
65#define THUMBNAIL_WIDTH 512
66#define THUMBNAIL_HEIGHT 384
67#define THUMBNAIL_WIDTH_STR "512"
68#define THUMBNAIL_HEIGHT_STR "384"
69#define DEFAULT_PICTURE_WIDTH 2048
70#define DEFAULT_PICTURE_HEIGHT 1536
71#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
72#define MAX_ZOOM_LEVEL 5
73#define NOT_FOUND -1
74
75#if DLOPEN_LIBMMCAMERA
76#include <dlfcn.h>
77
78void* (*LINK_cam_conf)(void *data);
79void* (*LINK_cam_frame)(void *data);
80bool (*LINK_jpeg_encoder_init)();
81void (*LINK_jpeg_encoder_join)();
82bool (*LINK_jpeg_encoder_encode)(const cam_ctrl_dimension_t *dimen,
83 const uint8_t *thumbnailbuf, int thumbnailfd,
84 const uint8_t *snapshotbuf, int snapshotfd,
85 common_crop_t *scaling_parms);
86int (*LINK_camframe_terminate)(void);
87int8_t (*LINK_jpeg_encoder_setMainImageQuality)(uint32_t quality);
88int8_t (*LINK_jpeg_encoder_setThumbnailQuality)(uint32_t quality);
89int8_t (*LINK_jpeg_encoder_setRotation)(uint32_t rotation);
90int8_t (*LINK_jpeg_encoder_setLocation)(const camera_position_type *location);
91const struct camera_size_type *(*LINK_default_sensor_get_snapshot_sizes)(int *len);
92int (*LINK_launch_cam_conf_thread)(void);
93int (*LINK_release_cam_conf_thread)(void);
94int8_t (*LINK_zoom_crop_upscale)(uint32_t width, uint32_t height,
95 uint32_t cropped_width, uint32_t cropped_height, uint8_t *img_buf);
96
97// callbacks
98void (**LINK_mmcamera_camframe_callback)(struct msm_frame *frame);
99void (**LINK_mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
100 uint32_t buff_size);
101void (**LINK_mmcamera_jpeg_callback)(jpeg_event_t status);
102void (**LINK_mmcamera_shutter_callback)(common_crop_t *crop);
103#else
104#define LINK_cam_conf cam_conf
105#define LINK_cam_frame cam_frame
106#define LINK_jpeg_encoder_init jpeg_encoder_init
107#define LINK_jpeg_encoder_join jpeg_encoder_join
108#define LINK_jpeg_encoder_encode jpeg_encoder_encode
109#define LINK_camframe_terminate camframe_terminate
110#define LINK_jpeg_encoder_setMainImageQuality jpeg_encoder_setMainImageQuality
111#define LINK_jpeg_encoder_setThumbnailQuality jpeg_encoder_setThumbnailQuality
112#define LINK_jpeg_encoder_setRotation jpeg_encoder_setRotation
113#define LINK_jpeg_encoder_setLocation jpeg_encoder_setLocation
114#define LINK_default_sensor_get_snapshot_sizes default_sensor_get_snapshot_sizes
115#define LINK_launch_cam_conf_thread launch_cam_conf_thread
116#define LINK_release_cam_conf_thread release_cam_conf_thread
117#define LINK_zoom_crop_upscale zoom_crop_upscale
118extern void (*mmcamera_camframe_callback)(struct msm_frame *frame);
119extern void (*mmcamera_jpegfragment_callback)(uint8_t *buff_ptr,
120 uint32_t buff_size);
121extern void (*mmcamera_jpeg_callback)(jpeg_event_t status);
122extern void (*mmcamera_shutter_callback)(common_crop_t *crop);
123#endif
124
125} // extern "C"
126
127#ifndef HAVE_CAMERA_SIZE_TYPE
128struct camera_size_type {
129 int width;
130 int height;
131};
132#endif
133
134#define DEFAULT_PREVIEW_SETTING 2
135static const camera_size_type preview_sizes[] = {
136 { 1280, 720 }, // 720P, reserved
137 { 800, 480 }, // WVGA
138 { 720, 480 },
139 { 640, 480 }, // VGA
140 { 576, 432 },
141 { 480, 320 }, // HVGA
142 { 384, 288 },
143 { 352, 288 }, // CIF
144 { 320, 240 }, // QVGA
145 { 240, 160 }, // SQVGA
146 { 176, 144 }, // QCIF
147};
148#define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(camera_size_type))
149
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800150//static const camera_size_type* picture_sizes;
151//static int PICTURE_SIZE_COUNT;
152/* TODO
153 * Ideally this should be a populated by lower layers.
154 * But currently this is no API to do that at lower layer.
155 * Hence populating with default sizes for now. This needs
156 * to be changed once the API is supported.
157 */
158static const camera_size_type picture_sizes[] = {
159 { 2592, 1944 }, // 5MP
160 { 2048, 1536 }, // 3MP
161 { 1600, 1200 }, // 2MP
162 { 800, 480 }, // WVGA
163 { 640, 480 }, // VGA
164 { 320, 240 } // QVGA
165};
166static int PICTURE_SIZE_COUNT = sizeof(picture_sizes)/sizeof(camera_size_type);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800167
168static int attr_lookup(const str_map arr[], int len, const char *name)
169{
170 if (name) {
171 for (int i = 0; i < len; i++) {
172 if (!strcmp(arr[i].desc, name))
173 return arr[i].val;
174 }
175 }
176 return NOT_FOUND;
177}
178
179// round to the next power of two
180static inline unsigned clp2(unsigned x)
181{
182 x = x - 1;
183 x = x | (x >> 1);
184 x = x | (x >> 2);
185 x = x | (x >> 4);
186 x = x | (x >> 8);
187 x = x | (x >>16);
188 return x + 1;
189}
190
191namespace android {
192// from aeecamera.h
193static const str_map whitebalance[] = {
194 { CameraParameters::WHITE_BALANCE_AUTO, CAMERA_WB_AUTO },
195 { CameraParameters::WHITE_BALANCE_INCANDESCENT, CAMERA_WB_INCANDESCENT },
196 { CameraParameters::WHITE_BALANCE_FLUORESCENT, CAMERA_WB_FLUORESCENT },
197 { CameraParameters::WHITE_BALANCE_DAYLIGHT, CAMERA_WB_DAYLIGHT },
198 { CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, CAMERA_WB_CLOUDY_DAYLIGHT }
199};
200
201// from camera_effect_t. This list must match aeecamera.h
202static const str_map effects[] = {
203 { CameraParameters::EFFECT_NONE, CAMERA_EFFECT_OFF },
204 { CameraParameters::EFFECT_MONO, CAMERA_EFFECT_MONO },
205 { CameraParameters::EFFECT_NEGATIVE, CAMERA_EFFECT_NEGATIVE },
206 { CameraParameters::EFFECT_SOLARIZE, CAMERA_EFFECT_SOLARIZE },
207 { CameraParameters::EFFECT_SEPIA, CAMERA_EFFECT_SEPIA },
208 { CameraParameters::EFFECT_POSTERIZE, CAMERA_EFFECT_POSTERIZE },
209 { CameraParameters::EFFECT_WHITEBOARD, CAMERA_EFFECT_WHITEBOARD },
210 { CameraParameters::EFFECT_BLACKBOARD, CAMERA_EFFECT_BLACKBOARD },
211 { CameraParameters::EFFECT_AQUA, CAMERA_EFFECT_AQUA }
212};
213
214// from qcamera/common/camera.h
Apurva Rajguru55562b02009-12-03 12:25:35 -0800215static const str_map autoexposure[] = {
216 { CameraParameters::AUTO_EXPOSURE_FRAME_AVG, CAMERA_AEC_FRAME_AVERAGE },
217 { CameraParameters::AUTO_EXPOSURE_CENTER_WEIGHTED, CAMERA_AEC_CENTER_WEIGHTED },
218 { CameraParameters::AUTO_EXPOSURE_SPOT_METERING, CAMERA_AEC_SPOT_METERING }
219};
220
221// from qcamera/common/camera.h
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800222static const str_map antibanding[] = {
223 { CameraParameters::ANTIBANDING_OFF, CAMERA_ANTIBANDING_OFF },
224 { CameraParameters::ANTIBANDING_50HZ, CAMERA_ANTIBANDING_50HZ },
225 { CameraParameters::ANTIBANDING_60HZ, CAMERA_ANTIBANDING_60HZ },
226 { CameraParameters::ANTIBANDING_AUTO, CAMERA_ANTIBANDING_AUTO }
227};
228
229/* Mapping from MCC to antibanding type */
230struct country_map {
231 uint32_t country_code;
232 camera_antibanding_type type;
233};
234
235static struct country_map country_numeric[] = {
236 { 202, CAMERA_ANTIBANDING_50HZ }, // Greece
237 { 204, CAMERA_ANTIBANDING_50HZ }, // Netherlands
238 { 206, CAMERA_ANTIBANDING_50HZ }, // Belgium
239 { 208, CAMERA_ANTIBANDING_50HZ }, // France
240 { 212, CAMERA_ANTIBANDING_50HZ }, // Monaco
241 { 213, CAMERA_ANTIBANDING_50HZ }, // Andorra
242 { 214, CAMERA_ANTIBANDING_50HZ }, // Spain
243 { 216, CAMERA_ANTIBANDING_50HZ }, // Hungary
244 { 219, CAMERA_ANTIBANDING_50HZ }, // Croatia
245 { 220, CAMERA_ANTIBANDING_50HZ }, // Serbia
246 { 222, CAMERA_ANTIBANDING_50HZ }, // Italy
247 { 226, CAMERA_ANTIBANDING_50HZ }, // Romania
248 { 228, CAMERA_ANTIBANDING_50HZ }, // Switzerland
249 { 230, CAMERA_ANTIBANDING_50HZ }, // Czech Republic
250 { 231, CAMERA_ANTIBANDING_50HZ }, // Slovakia
251 { 232, CAMERA_ANTIBANDING_50HZ }, // Austria
252 { 234, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
253 { 235, CAMERA_ANTIBANDING_50HZ }, // United Kingdom
254 { 238, CAMERA_ANTIBANDING_50HZ }, // Denmark
255 { 240, CAMERA_ANTIBANDING_50HZ }, // Sweden
256 { 242, CAMERA_ANTIBANDING_50HZ }, // Norway
257 { 244, CAMERA_ANTIBANDING_50HZ }, // Finland
258 { 246, CAMERA_ANTIBANDING_50HZ }, // Lithuania
259 { 247, CAMERA_ANTIBANDING_50HZ }, // Latvia
260 { 248, CAMERA_ANTIBANDING_50HZ }, // Estonia
261 { 250, CAMERA_ANTIBANDING_50HZ }, // Russian Federation
262 { 255, CAMERA_ANTIBANDING_50HZ }, // Ukraine
263 { 257, CAMERA_ANTIBANDING_50HZ }, // Belarus
264 { 259, CAMERA_ANTIBANDING_50HZ }, // Moldova
265 { 260, CAMERA_ANTIBANDING_50HZ }, // Poland
266 { 262, CAMERA_ANTIBANDING_50HZ }, // Germany
267 { 266, CAMERA_ANTIBANDING_50HZ }, // Gibraltar
268 { 268, CAMERA_ANTIBANDING_50HZ }, // Portugal
269 { 270, CAMERA_ANTIBANDING_50HZ }, // Luxembourg
270 { 272, CAMERA_ANTIBANDING_50HZ }, // Ireland
271 { 274, CAMERA_ANTIBANDING_50HZ }, // Iceland
272 { 276, CAMERA_ANTIBANDING_50HZ }, // Albania
273 { 278, CAMERA_ANTIBANDING_50HZ }, // Malta
274 { 280, CAMERA_ANTIBANDING_50HZ }, // Cyprus
275 { 282, CAMERA_ANTIBANDING_50HZ }, // Georgia
276 { 283, CAMERA_ANTIBANDING_50HZ }, // Armenia
277 { 284, CAMERA_ANTIBANDING_50HZ }, // Bulgaria
278 { 286, CAMERA_ANTIBANDING_50HZ }, // Turkey
279 { 288, CAMERA_ANTIBANDING_50HZ }, // Faroe Islands
280 { 290, CAMERA_ANTIBANDING_50HZ }, // Greenland
281 { 293, CAMERA_ANTIBANDING_50HZ }, // Slovenia
282 { 294, CAMERA_ANTIBANDING_50HZ }, // Macedonia
283 { 295, CAMERA_ANTIBANDING_50HZ }, // Liechtenstein
284 { 297, CAMERA_ANTIBANDING_50HZ }, // Montenegro
285 { 302, CAMERA_ANTIBANDING_60HZ }, // Canada
286 { 310, CAMERA_ANTIBANDING_60HZ }, // United States of America
287 { 311, CAMERA_ANTIBANDING_60HZ }, // United States of America
288 { 312, CAMERA_ANTIBANDING_60HZ }, // United States of America
289 { 313, CAMERA_ANTIBANDING_60HZ }, // United States of America
290 { 314, CAMERA_ANTIBANDING_60HZ }, // United States of America
291 { 315, CAMERA_ANTIBANDING_60HZ }, // United States of America
292 { 316, CAMERA_ANTIBANDING_60HZ }, // United States of America
293 { 330, CAMERA_ANTIBANDING_60HZ }, // Puerto Rico
294 { 334, CAMERA_ANTIBANDING_60HZ }, // Mexico
295 { 338, CAMERA_ANTIBANDING_50HZ }, // Jamaica
296 { 340, CAMERA_ANTIBANDING_50HZ }, // Martinique
297 { 342, CAMERA_ANTIBANDING_50HZ }, // Barbados
298 { 346, CAMERA_ANTIBANDING_60HZ }, // Cayman Islands
299 { 350, CAMERA_ANTIBANDING_60HZ }, // Bermuda
300 { 352, CAMERA_ANTIBANDING_50HZ }, // Grenada
301 { 354, CAMERA_ANTIBANDING_60HZ }, // Montserrat
302 { 362, CAMERA_ANTIBANDING_50HZ }, // Netherlands Antilles
303 { 363, CAMERA_ANTIBANDING_60HZ }, // Aruba
304 { 364, CAMERA_ANTIBANDING_60HZ }, // Bahamas
305 { 365, CAMERA_ANTIBANDING_60HZ }, // Anguilla
306 { 366, CAMERA_ANTIBANDING_50HZ }, // Dominica
307 { 368, CAMERA_ANTIBANDING_60HZ }, // Cuba
308 { 370, CAMERA_ANTIBANDING_60HZ }, // Dominican Republic
309 { 372, CAMERA_ANTIBANDING_60HZ }, // Haiti
310 { 401, CAMERA_ANTIBANDING_50HZ }, // Kazakhstan
311 { 402, CAMERA_ANTIBANDING_50HZ }, // Bhutan
312 { 404, CAMERA_ANTIBANDING_50HZ }, // India
313 { 405, CAMERA_ANTIBANDING_50HZ }, // India
314 { 410, CAMERA_ANTIBANDING_50HZ }, // Pakistan
315 { 413, CAMERA_ANTIBANDING_50HZ }, // Sri Lanka
316 { 414, CAMERA_ANTIBANDING_50HZ }, // Myanmar
317 { 415, CAMERA_ANTIBANDING_50HZ }, // Lebanon
318 { 416, CAMERA_ANTIBANDING_50HZ }, // Jordan
319 { 417, CAMERA_ANTIBANDING_50HZ }, // Syria
320 { 418, CAMERA_ANTIBANDING_50HZ }, // Iraq
321 { 419, CAMERA_ANTIBANDING_50HZ }, // Kuwait
322 { 420, CAMERA_ANTIBANDING_60HZ }, // Saudi Arabia
323 { 421, CAMERA_ANTIBANDING_50HZ }, // Yemen
324 { 422, CAMERA_ANTIBANDING_50HZ }, // Oman
325 { 424, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
326 { 425, CAMERA_ANTIBANDING_50HZ }, // Israel
327 { 426, CAMERA_ANTIBANDING_50HZ }, // Bahrain
328 { 427, CAMERA_ANTIBANDING_50HZ }, // Qatar
329 { 428, CAMERA_ANTIBANDING_50HZ }, // Mongolia
330 { 429, CAMERA_ANTIBANDING_50HZ }, // Nepal
331 { 430, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
332 { 431, CAMERA_ANTIBANDING_50HZ }, // United Arab Emirates
333 { 432, CAMERA_ANTIBANDING_50HZ }, // Iran
334 { 434, CAMERA_ANTIBANDING_50HZ }, // Uzbekistan
335 { 436, CAMERA_ANTIBANDING_50HZ }, // Tajikistan
336 { 437, CAMERA_ANTIBANDING_50HZ }, // Kyrgyz Rep
337 { 438, CAMERA_ANTIBANDING_50HZ }, // Turkmenistan
338 { 440, CAMERA_ANTIBANDING_60HZ }, // Japan
339 { 441, CAMERA_ANTIBANDING_60HZ }, // Japan
340 { 452, CAMERA_ANTIBANDING_50HZ }, // Vietnam
341 { 454, CAMERA_ANTIBANDING_50HZ }, // Hong Kong
342 { 455, CAMERA_ANTIBANDING_50HZ }, // Macao
343 { 456, CAMERA_ANTIBANDING_50HZ }, // Cambodia
344 { 457, CAMERA_ANTIBANDING_50HZ }, // Laos
345 { 460, CAMERA_ANTIBANDING_50HZ }, // China
346 { 466, CAMERA_ANTIBANDING_60HZ }, // Taiwan
347 { 470, CAMERA_ANTIBANDING_50HZ }, // Bangladesh
348 { 472, CAMERA_ANTIBANDING_50HZ }, // Maldives
349 { 502, CAMERA_ANTIBANDING_50HZ }, // Malaysia
350 { 505, CAMERA_ANTIBANDING_50HZ }, // Australia
351 { 510, CAMERA_ANTIBANDING_50HZ }, // Indonesia
352 { 514, CAMERA_ANTIBANDING_50HZ }, // East Timor
353 { 515, CAMERA_ANTIBANDING_60HZ }, // Philippines
354 { 520, CAMERA_ANTIBANDING_50HZ }, // Thailand
355 { 525, CAMERA_ANTIBANDING_50HZ }, // Singapore
356 { 530, CAMERA_ANTIBANDING_50HZ }, // New Zealand
357 { 535, CAMERA_ANTIBANDING_60HZ }, // Guam
358 { 536, CAMERA_ANTIBANDING_50HZ }, // Nauru
359 { 537, CAMERA_ANTIBANDING_50HZ }, // Papua New Guinea
360 { 539, CAMERA_ANTIBANDING_50HZ }, // Tonga
361 { 541, CAMERA_ANTIBANDING_50HZ }, // Vanuatu
362 { 542, CAMERA_ANTIBANDING_50HZ }, // Fiji
363 { 544, CAMERA_ANTIBANDING_60HZ }, // American Samoa
364 { 545, CAMERA_ANTIBANDING_50HZ }, // Kiribati
365 { 546, CAMERA_ANTIBANDING_50HZ }, // New Caledonia
366 { 548, CAMERA_ANTIBANDING_50HZ }, // Cook Islands
367 { 602, CAMERA_ANTIBANDING_50HZ }, // Egypt
368 { 603, CAMERA_ANTIBANDING_50HZ }, // Algeria
369 { 604, CAMERA_ANTIBANDING_50HZ }, // Morocco
370 { 605, CAMERA_ANTIBANDING_50HZ }, // Tunisia
371 { 606, CAMERA_ANTIBANDING_50HZ }, // Libya
372 { 607, CAMERA_ANTIBANDING_50HZ }, // Gambia
373 { 608, CAMERA_ANTIBANDING_50HZ }, // Senegal
374 { 609, CAMERA_ANTIBANDING_50HZ }, // Mauritania
375 { 610, CAMERA_ANTIBANDING_50HZ }, // Mali
376 { 611, CAMERA_ANTIBANDING_50HZ }, // Guinea
377 { 613, CAMERA_ANTIBANDING_50HZ }, // Burkina Faso
378 { 614, CAMERA_ANTIBANDING_50HZ }, // Niger
379 { 616, CAMERA_ANTIBANDING_50HZ }, // Benin
380 { 617, CAMERA_ANTIBANDING_50HZ }, // Mauritius
381 { 618, CAMERA_ANTIBANDING_50HZ }, // Liberia
382 { 619, CAMERA_ANTIBANDING_50HZ }, // Sierra Leone
383 { 620, CAMERA_ANTIBANDING_50HZ }, // Ghana
384 { 621, CAMERA_ANTIBANDING_50HZ }, // Nigeria
385 { 622, CAMERA_ANTIBANDING_50HZ }, // Chad
386 { 623, CAMERA_ANTIBANDING_50HZ }, // Central African Republic
387 { 624, CAMERA_ANTIBANDING_50HZ }, // Cameroon
388 { 625, CAMERA_ANTIBANDING_50HZ }, // Cape Verde
389 { 627, CAMERA_ANTIBANDING_50HZ }, // Equatorial Guinea
390 { 631, CAMERA_ANTIBANDING_50HZ }, // Angola
391 { 633, CAMERA_ANTIBANDING_50HZ }, // Seychelles
392 { 634, CAMERA_ANTIBANDING_50HZ }, // Sudan
393 { 636, CAMERA_ANTIBANDING_50HZ }, // Ethiopia
394 { 637, CAMERA_ANTIBANDING_50HZ }, // Somalia
395 { 638, CAMERA_ANTIBANDING_50HZ }, // Djibouti
396 { 639, CAMERA_ANTIBANDING_50HZ }, // Kenya
397 { 640, CAMERA_ANTIBANDING_50HZ }, // Tanzania
398 { 641, CAMERA_ANTIBANDING_50HZ }, // Uganda
399 { 642, CAMERA_ANTIBANDING_50HZ }, // Burundi
400 { 643, CAMERA_ANTIBANDING_50HZ }, // Mozambique
401 { 645, CAMERA_ANTIBANDING_50HZ }, // Zambia
402 { 646, CAMERA_ANTIBANDING_50HZ }, // Madagascar
403 { 647, CAMERA_ANTIBANDING_50HZ }, // France
404 { 648, CAMERA_ANTIBANDING_50HZ }, // Zimbabwe
405 { 649, CAMERA_ANTIBANDING_50HZ }, // Namibia
406 { 650, CAMERA_ANTIBANDING_50HZ }, // Malawi
407 { 651, CAMERA_ANTIBANDING_50HZ }, // Lesotho
408 { 652, CAMERA_ANTIBANDING_50HZ }, // Botswana
409 { 653, CAMERA_ANTIBANDING_50HZ }, // Swaziland
410 { 654, CAMERA_ANTIBANDING_50HZ }, // Comoros
411 { 655, CAMERA_ANTIBANDING_50HZ }, // South Africa
412 { 657, CAMERA_ANTIBANDING_50HZ }, // Eritrea
413 { 702, CAMERA_ANTIBANDING_60HZ }, // Belize
414 { 704, CAMERA_ANTIBANDING_60HZ }, // Guatemala
415 { 706, CAMERA_ANTIBANDING_60HZ }, // El Salvador
416 { 708, CAMERA_ANTIBANDING_60HZ }, // Honduras
417 { 710, CAMERA_ANTIBANDING_60HZ }, // Nicaragua
418 { 712, CAMERA_ANTIBANDING_60HZ }, // Costa Rica
419 { 714, CAMERA_ANTIBANDING_60HZ }, // Panama
420 { 722, CAMERA_ANTIBANDING_50HZ }, // Argentina
421 { 724, CAMERA_ANTIBANDING_60HZ }, // Brazil
422 { 730, CAMERA_ANTIBANDING_50HZ }, // Chile
423 { 732, CAMERA_ANTIBANDING_60HZ }, // Colombia
424 { 734, CAMERA_ANTIBANDING_60HZ }, // Venezuela
425 { 736, CAMERA_ANTIBANDING_50HZ }, // Bolivia
426 { 738, CAMERA_ANTIBANDING_60HZ }, // Guyana
427 { 740, CAMERA_ANTIBANDING_60HZ }, // Ecuador
428 { 742, CAMERA_ANTIBANDING_50HZ }, // French Guiana
429 { 744, CAMERA_ANTIBANDING_50HZ }, // Paraguay
430 { 746, CAMERA_ANTIBANDING_60HZ }, // Suriname
431 { 748, CAMERA_ANTIBANDING_50HZ }, // Uruguay
432 { 750, CAMERA_ANTIBANDING_50HZ }, // Falkland Islands
433};
434
435#define country_number (sizeof(country_numeric) / sizeof(country_map))
436
437/* Look up pre-sorted antibanding_type table by current MCC. */
438static camera_antibanding_type camera_get_location(void) {
439 char value[PROP_VALUE_MAX];
440 char country_value[PROP_VALUE_MAX];
441 uint32_t country_code, count;
442 memset(value, 0x00, sizeof(value));
443 memset(country_value, 0x00, sizeof(country_value));
444 if (!__system_property_get("gsm.operator.numeric", value)) {
445 return CAMERA_ANTIBANDING_60HZ;
446 }
447 memcpy(country_value, value, 3);
448 country_code = atoi(country_value);
449 LOGD("value:%s, country value:%s, country code:%d\n",
450 value, country_value, country_code);
451 int left = 0;
452 int right = country_number - 1;
453 while (left <= right) {
454 int index = (left + right) >> 1;
455 if (country_numeric[index].country_code == country_code)
456 return country_numeric[index].type;
457 else if (country_numeric[index].country_code > country_code)
458 right = index - 1;
459 else
460 left = index + 1;
461 }
462 return CAMERA_ANTIBANDING_60HZ;
463}
464
465// from camera.h, led_mode_t
466static const str_map flash[] = {
467 { CameraParameters::FLASH_MODE_OFF, LED_MODE_OFF },
468 { CameraParameters::FLASH_MODE_AUTO, LED_MODE_AUTO },
469 { CameraParameters::FLASH_MODE_ON, LED_MODE_ON }
470};
471
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530472// from mm-camera/common/camera.h.
473static const str_map iso[] = {
474 { CameraParameters::ISO_AUTO, CAMERA_ISO_AUTO},
475 { CameraParameters::ISO_HJR, CAMERA_ISO_DEBLUR},
476 { CameraParameters::ISO_100, CAMERA_ISO_100},
477 { CameraParameters::ISO_200, CAMERA_ISO_200},
478 { CameraParameters::ISO_400, CAMERA_ISO_400},
479 { CameraParameters::ISO_800, CAMERA_ISO_800 }
480};
481
482
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800483#define DONT_CARE 0
484static const str_map focus_modes[] = {
485 { CameraParameters::FOCUS_MODE_AUTO, DONT_CARE },
486 { CameraParameters::FOCUS_MODE_INFINITY, DONT_CARE }
487};
488
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530489static const str_map lensshade[] = {
490 { CameraParameters::LENSSHADE_ENABLE, TRUE },
491 { CameraParameters::LENSSHADE_DISABLE, FALSE }
492};
493
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800494static bool parameter_string_initialized = false;
495static String8 preview_size_values;
496static String8 picture_size_values;
497static String8 antibanding_values;
498static String8 effect_values;
Apurva Rajguru55562b02009-12-03 12:25:35 -0800499static String8 autoexposure_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800500static String8 whitebalance_values;
501static String8 flash_values;
502static String8 focus_mode_values;
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530503static String8 iso_values;
504static String8 lensshade_values;
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800505
506static String8 create_sizes_str(const camera_size_type *sizes, int len) {
507 String8 str;
508 char buffer[32];
509
510 if (len > 0) {
511 sprintf(buffer, "%dx%d", sizes[0].width, sizes[0].height);
512 str.append(buffer);
513 }
514 for (int i = 1; i < len; i++) {
515 sprintf(buffer, ",%dx%d", sizes[i].width, sizes[i].height);
516 str.append(buffer);
517 }
518 return str;
519}
520
521static String8 create_values_str(const str_map *values, int len) {
522 String8 str;
523
524 if (len > 0) {
525 str.append(values[0].desc);
526 }
527 for (int i = 1; i < len; i++) {
528 str.append(",");
529 str.append(values[i].desc);
530 }
531 return str;
532}
533
534static Mutex singleton_lock;
535static bool singleton_releasing;
536static Condition singleton_wait;
537
538static void receive_camframe_callback(struct msm_frame *frame);
539static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size);
540static void receive_jpeg_callback(jpeg_event_t status);
541static void receive_shutter_callback(common_crop_t *crop);
542
543QualcommCameraHardware::QualcommCameraHardware()
544 : mParameters(),
545 mCameraRunning(false),
546 mPreviewInitialized(false),
547 mFrameThreadRunning(false),
548 mSnapshotThreadRunning(false),
549 mReleasedRecordingFrame(false),
550 mPreviewFrameSize(0),
551 mRawSize(0),
552 mCameraControlFd(-1),
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530553 mBrightness(0),
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800554 mAutoFocusThreadRunning(false),
555 mAutoFocusFd(-1),
556 mInPreviewCallback(false),
557 mMsgEnabled(0),
558 mNotifyCallback(0),
559 mDataCallback(0),
560 mDataCallbackTimestamp(0),
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -0800561 mCallbackCookie(0),
562 mOverlay(0),
563 mUseOverlay(0)
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800564{
565 memset(&mDimension, 0, sizeof(mDimension));
566 memset(&mCrop, 0, sizeof(mCrop));
567 LOGV("constructor EX");
568}
569
570void QualcommCameraHardware::initDefaultParameters()
571{
572 LOGV("initDefaultParameters E");
573
574 // Initialize constant parameter strings. This will happen only once in the
575 // lifetime of the mediaserver process.
576 if (!parameter_string_initialized) {
577 antibanding_values = create_values_str(
578 antibanding, sizeof(antibanding) / sizeof(str_map));
579 effect_values = create_values_str(
580 effects, sizeof(effects) / sizeof(str_map));
Apurva Rajguru55562b02009-12-03 12:25:35 -0800581 autoexposure_values = create_values_str(
582 autoexposure, sizeof(autoexposure) / sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800583 whitebalance_values = create_values_str(
584 whitebalance, sizeof(whitebalance) / sizeof(str_map));
585 preview_size_values = create_sizes_str(
586 preview_sizes, PREVIEW_SIZE_COUNT);
587 picture_size_values = create_sizes_str(
588 picture_sizes, PICTURE_SIZE_COUNT);
589 flash_values = create_values_str(
590 flash, sizeof(flash) / sizeof(str_map));
591 focus_mode_values = create_values_str(
592 focus_modes, sizeof(focus_modes) / sizeof(str_map));
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530593 iso_values = create_values_str(
594 iso,sizeof(iso)/sizeof(str_map));
595 lensshade_values = create_values_str(
596 lensshade,sizeof(lensshade)/sizeof(str_map));
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800597 parameter_string_initialized = true;
598 }
599
600 const camera_size_type *ps = &preview_sizes[DEFAULT_PREVIEW_SETTING];
601 mParameters.setPreviewSize(ps->width, ps->height);
602 mDimension.display_width = ps->width;
603 mDimension.display_height = ps->height;
604 mParameters.setPreviewFrameRate(15);
605 mParameters.setPreviewFormat("yuv420sp"); // informative
606
607 mParameters.setPictureSize(DEFAULT_PICTURE_WIDTH, DEFAULT_PICTURE_HEIGHT);
608 mParameters.setPictureFormat("jpeg"); // informative
609
610 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // max quality
611 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
612 THUMBNAIL_WIDTH_STR); // informative
613 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
614 THUMBNAIL_HEIGHT_STR); // informative
615 mDimension.ui_thumbnail_width = THUMBNAIL_WIDTH;
616 mDimension.ui_thumbnail_height = THUMBNAIL_HEIGHT;
617 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
618
619 mParameters.set(CameraParameters::KEY_ANTIBANDING,
620 CameraParameters::ANTIBANDING_AUTO);
621 mParameters.set(CameraParameters::KEY_EFFECT,
622 CameraParameters::EFFECT_NONE);
Apurva Rajguru55562b02009-12-03 12:25:35 -0800623 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE,
624 CameraParameters::AUTO_EXPOSURE_FRAME_AVG);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800625 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
626 CameraParameters::WHITE_BALANCE_AUTO);
627 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
628 CameraParameters::FOCUS_MODE_AUTO);
629
630 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
631 preview_size_values.string());
632 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
633 picture_size_values.string());
634 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
635 antibanding_values);
636 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, effect_values);
Apurva Rajguru55562b02009-12-03 12:25:35 -0800637 mParameters.set(CameraParameters::KEY_SUPPORTED_AUTO_EXPOSURE, autoexposure_values);
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800638 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
639 whitebalance_values);
640 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
641 focus_mode_values);
642
643 if (mSensorInfo.flash_enabled) {
644 mParameters.set(CameraParameters::KEY_FLASH_MODE,
645 CameraParameters::FLASH_MODE_OFF);
646 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
647 flash_values);
648 }
649
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530650 mParameters.set("luma-adaptation", "18");
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800651 mParameters.set("zoom-supported", "true");
652 mParameters.set("max-zoom", MAX_ZOOM_LEVEL);
653 mParameters.set("zoom", 0);
654
Nishant Panditc8c1ee72009-12-03 16:24:02 +0530655 mParameters.set(CameraParameters::KEY_ISO_MODE,
656 CameraParameters::ISO_AUTO);
657 mParameters.set(CameraParameters::KEY_LENSSHADE,
658 CameraParameters::LENSSHADE_ENABLE);
659 mParameters.set(CameraParameters::KEY_SUPPORTED_ISO_MODES,
660 iso_values);
661 mParameters.set(CameraParameters::KEY_SUPPORTED_LENSSHADE_MODES,
662 lensshade_values);
663
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800664 if (setParameters(mParameters) != NO_ERROR) {
665 LOGE("Failed to set default parameters?!");
666 }
667
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -0800668 mUseOverlay = useOverlay();
669
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800670 LOGV("initDefaultParameters X");
671}
672
673#define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
674
675bool QualcommCameraHardware::startCamera()
676{
677 LOGV("startCamera E");
678#if DLOPEN_LIBMMCAMERA
679 libmmcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
680 LOGV("loading liboemcamera at %p", libmmcamera);
681 if (!libmmcamera) {
682 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
683 return false;
684 }
685
686 *(void **)&LINK_cam_frame =
687 ::dlsym(libmmcamera, "cam_frame");
688 *(void **)&LINK_camframe_terminate =
689 ::dlsym(libmmcamera, "camframe_terminate");
690
691 *(void **)&LINK_jpeg_encoder_init =
692 ::dlsym(libmmcamera, "jpeg_encoder_init");
693
694 *(void **)&LINK_jpeg_encoder_encode =
695 ::dlsym(libmmcamera, "jpeg_encoder_encode");
696
697 *(void **)&LINK_jpeg_encoder_join =
698 ::dlsym(libmmcamera, "jpeg_encoder_join");
699
700 *(void **)&LINK_mmcamera_camframe_callback =
701 ::dlsym(libmmcamera, "mmcamera_camframe_callback");
702
703 *LINK_mmcamera_camframe_callback = receive_camframe_callback;
704
705 *(void **)&LINK_mmcamera_jpegfragment_callback =
706 ::dlsym(libmmcamera, "mmcamera_jpegfragment_callback");
707
708 *LINK_mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
709
710 *(void **)&LINK_mmcamera_jpeg_callback =
711 ::dlsym(libmmcamera, "mmcamera_jpeg_callback");
712
713 *LINK_mmcamera_jpeg_callback = receive_jpeg_callback;
714
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800715/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800716 *(void **)&LINK_mmcamera_shutter_callback =
717 ::dlsym(libmmcamera, "mmcamera_shutter_callback");
718
719 *LINK_mmcamera_shutter_callback = receive_shutter_callback;
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800720*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800721 *(void**)&LINK_jpeg_encoder_setMainImageQuality =
722 ::dlsym(libmmcamera, "jpeg_encoder_setMainImageQuality");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800723/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800724 *(void**)&LINK_jpeg_encoder_setThumbnailQuality =
725 ::dlsym(libmmcamera, "jpeg_encoder_setThumbnailQuality");
726
727 *(void**)&LINK_jpeg_encoder_setRotation =
728 ::dlsym(libmmcamera, "jpeg_encoder_setRotation");
729
730 *(void**)&LINK_jpeg_encoder_setLocation =
731 ::dlsym(libmmcamera, "jpeg_encoder_setLocation");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800732*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800733 *(void **)&LINK_cam_conf =
734 ::dlsym(libmmcamera, "cam_conf");
735
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800736/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800737 *(void **)&LINK_default_sensor_get_snapshot_sizes =
738 ::dlsym(libmmcamera, "default_sensor_get_snapshot_sizes");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800739*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800740 *(void **)&LINK_launch_cam_conf_thread =
741 ::dlsym(libmmcamera, "launch_cam_conf_thread");
742
743 *(void **)&LINK_release_cam_conf_thread =
744 ::dlsym(libmmcamera, "release_cam_conf_thread");
745
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800746/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800747 *(void **)&LINK_zoom_crop_upscale =
748 ::dlsym(libmmcamera, "zoom_crop_upscale");
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800749*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800750
751#else
752 mmcamera_camframe_callback = receive_camframe_callback;
753 mmcamera_jpegfragment_callback = receive_jpeg_fragment_callback;
754 mmcamera_jpeg_callback = receive_jpeg_callback;
755 mmcamera_shutter_callback = receive_shutter_callback;
756#endif // DLOPEN_LIBMMCAMERA
757
758 /* The control thread is in libcamera itself. */
759 mCameraControlFd = open(MSM_CAMERA_CONTROL, O_RDWR);
760 if (mCameraControlFd < 0) {
761 LOGE("startCamera X: %s open failed: %s!",
762 MSM_CAMERA_CONTROL,
763 strerror(errno));
764 return false;
765 }
766
767 /* This will block until the control thread is launched. After that, sensor
768 * information becomes available.
769 */
770
771 if (LINK_launch_cam_conf_thread()) {
772 LOGE("failed to launch the camera config thread");
773 return false;
774 }
775
776 memset(&mSensorInfo, 0, sizeof(mSensorInfo));
777 if (ioctl(mCameraControlFd,
778 MSM_CAM_IOCTL_GET_SENSOR_INFO,
779 &mSensorInfo) < 0)
780 LOGW("%s: cannot retrieve sensor info!", __FUNCTION__);
781 else
782 LOGI("%s: camsensor name %s, flash %d", __FUNCTION__,
783 mSensorInfo.name, mSensorInfo.flash_enabled);
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800784/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800785 picture_sizes = LINK_default_sensor_get_snapshot_sizes(&PICTURE_SIZE_COUNT);
786 if (!picture_sizes || !PICTURE_SIZE_COUNT) {
787 LOGE("startCamera X: could not get snapshot sizes");
788 return false;
789 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -0800790*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -0800791 LOGV("startCamera X");
792 return true;
793}
794
795status_t QualcommCameraHardware::dump(int fd,
796 const Vector<String16>& args) const
797{
798 const size_t SIZE = 256;
799 char buffer[SIZE];
800 String8 result;
801
802 // Dump internal primitives.
803 result.append("QualcommCameraHardware::dump");
804 snprintf(buffer, 255, "mMsgEnabled (%d)\n", mMsgEnabled);
805 result.append(buffer);
806 int width, height;
807 mParameters.getPreviewSize(&width, &height);
808 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", width, height);
809 result.append(buffer);
810 mParameters.getPictureSize(&width, &height);
811 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", width, height);
812 result.append(buffer);
813 snprintf(buffer, 255,
814 "preview frame size(%d), raw size (%d), jpeg size (%d) "
815 "and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize,
816 mJpegSize, mJpegMaxSize);
817 result.append(buffer);
818 write(fd, result.string(), result.size());
819
820 // Dump internal objects.
821 if (mPreviewHeap != 0) {
822 mPreviewHeap->dump(fd, args);
823 }
824 if (mRawHeap != 0) {
825 mRawHeap->dump(fd, args);
826 }
827 if (mJpegHeap != 0) {
828 mJpegHeap->dump(fd, args);
829 }
830 mParameters.dump(fd, args);
831 return NO_ERROR;
832}
833
834static bool native_set_afmode(int camfd, isp3a_af_mode_t af_type)
835{
836 int rc;
837 struct msm_ctrl_cmd ctrlCmd;
838
839 ctrlCmd.timeout_ms = 5000;
840 ctrlCmd.type = CAMERA_SET_PARM_AUTO_FOCUS;
841 ctrlCmd.length = sizeof(af_type);
842 ctrlCmd.value = &af_type;
843 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
844
845 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd)) < 0)
846 LOGE("native_set_afmode: ioctl fd %d error %s\n",
847 camfd,
848 strerror(errno));
849
850 LOGV("native_set_afmode: ctrlCmd.status == %d\n", ctrlCmd.status);
851 return rc >= 0 && ctrlCmd.status == CAMERA_EXIT_CB_DONE;
852}
853
854static bool native_cancel_afmode(int camfd, int af_fd)
855{
856 int rc;
857 struct msm_ctrl_cmd ctrlCmd;
858
859 ctrlCmd.timeout_ms = 0;
860 ctrlCmd.type = CAMERA_AUTO_FOCUS_CANCEL;
861 ctrlCmd.length = 0;
862 ctrlCmd.value = NULL;
863 ctrlCmd.resp_fd = -1; // there's no response fd
864
865 if ((rc = ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd)) < 0)
866 {
867 LOGE("native_cancel_afmode: ioctl fd %d error %s\n",
868 camfd,
869 strerror(errno));
870 return false;
871 }
872
873 return true;
874}
875
876static bool native_start_preview(int camfd)
877{
878 struct msm_ctrl_cmd ctrlCmd;
879
880 ctrlCmd.timeout_ms = 5000;
881 ctrlCmd.type = CAMERA_START_PREVIEW;
882 ctrlCmd.length = 0;
883 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
884
885 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
886 LOGE("native_start_preview: MSM_CAM_IOCTL_CTRL_COMMAND fd %d error %s",
887 camfd,
888 strerror(errno));
889 return false;
890 }
891
892 return true;
893}
894
895static bool native_get_picture (int camfd, common_crop_t *crop)
896{
897 struct msm_ctrl_cmd ctrlCmd;
898
899 ctrlCmd.timeout_ms = 5000;
900 ctrlCmd.length = sizeof(common_crop_t);
901 ctrlCmd.value = crop;
902
903 if(ioctl(camfd, MSM_CAM_IOCTL_GET_PICTURE, &ctrlCmd) < 0) {
904 LOGE("native_get_picture: MSM_CAM_IOCTL_GET_PICTURE fd %d error %s",
905 camfd,
906 strerror(errno));
907 return false;
908 }
909
910 LOGV("crop: in1_w %d", crop->in1_w);
911 LOGV("crop: in1_h %d", crop->in1_h);
912 LOGV("crop: out1_w %d", crop->out1_w);
913 LOGV("crop: out1_h %d", crop->out1_h);
914
915 LOGV("crop: in2_w %d", crop->in2_w);
916 LOGV("crop: in2_h %d", crop->in2_h);
917 LOGV("crop: out2_w %d", crop->out2_w);
918 LOGV("crop: out2_h %d", crop->out2_h);
919
920 LOGV("crop: update %d", crop->update_flag);
921
922 return true;
923}
924
925static bool native_stop_preview(int camfd)
926{
927 struct msm_ctrl_cmd ctrlCmd;
928 ctrlCmd.timeout_ms = 5000;
929 ctrlCmd.type = CAMERA_STOP_PREVIEW;
930 ctrlCmd.length = 0;
931 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
932
933 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
934 LOGE("native_stop_preview: ioctl fd %d error %s",
935 camfd,
936 strerror(errno));
937 return false;
938 }
939
940 return true;
941}
942
943static bool native_prepare_snapshot(int camfd)
944{
945 int ioctlRetVal = true;
946 struct msm_ctrl_cmd ctrlCmd;
947
948 ctrlCmd.timeout_ms = 1000;
949 ctrlCmd.type = CAMERA_PREPARE_SNAPSHOT;
950 ctrlCmd.length = 0;
951 ctrlCmd.value = NULL;
952 ctrlCmd.resp_fd = camfd;
953
954 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
955 LOGE("native_prepare_snapshot: ioctl fd %d error %s",
956 camfd,
957 strerror(errno));
958 return false;
959 }
960 return true;
961}
962
963static bool native_start_snapshot(int camfd)
964{
965 struct msm_ctrl_cmd ctrlCmd;
966
967 ctrlCmd.timeout_ms = 5000;
968 ctrlCmd.type = CAMERA_START_SNAPSHOT;
969 ctrlCmd.length = 0;
970 ctrlCmd.resp_fd = camfd; // FIXME: this will be put in by the kernel
971
972 if(ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0) {
973 LOGE("native_start_snapshot: ioctl fd %d error %s",
974 camfd,
975 strerror(errno));
976 return false;
977 }
978
979 return true;
980}
981
982static bool native_stop_snapshot (int camfd)
983{
984 struct msm_ctrl_cmd ctrlCmd;
985
986 ctrlCmd.timeout_ms = 0;
987 ctrlCmd.type = CAMERA_STOP_SNAPSHOT;
988 ctrlCmd.length = 0;
989 ctrlCmd.resp_fd = -1;
990
991 if (ioctl(camfd, MSM_CAM_IOCTL_CTRL_COMMAND_2, &ctrlCmd) < 0) {
992 LOGE("native_stop_snapshot: ioctl fd %d error %s",
993 camfd,
994 strerror(errno));
995 return false;
996 }
997
998 return true;
999}
1000
1001bool QualcommCameraHardware::native_jpeg_encode(void)
1002{
1003 int jpeg_quality = mParameters.getInt("jpeg-quality");
1004 if (jpeg_quality >= 0) {
1005 LOGV("native_jpeg_encode, current jpeg main img quality =%d",
1006 jpeg_quality);
1007 if(!LINK_jpeg_encoder_setMainImageQuality(jpeg_quality)) {
1008 LOGE("native_jpeg_encode set jpeg-quality failed");
1009 return false;
1010 }
1011 }
1012
1013 int thumbnail_quality = mParameters.getInt("jpeg-thumbnail-quality");
1014 if (thumbnail_quality >= 0) {
1015 LOGV("native_jpeg_encode, current jpeg thumbnail quality =%d",
1016 thumbnail_quality);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001017/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001018 if(!LINK_jpeg_encoder_setThumbnailQuality(thumbnail_quality)) {
1019 LOGE("native_jpeg_encode set thumbnail-quality failed");
1020 return false;
1021 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001022*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001023 }
1024
1025 int rotation = mParameters.getInt("rotation");
1026 if (rotation >= 0) {
1027 LOGV("native_jpeg_encode, rotation = %d", rotation);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001028/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001029 if(!LINK_jpeg_encoder_setRotation(rotation)) {
1030 LOGE("native_jpeg_encode set rotation failed");
1031 return false;
1032 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001033*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001034 }
1035
1036 jpeg_set_location();
1037
1038 if (!LINK_jpeg_encoder_encode(&mDimension,
1039 (uint8_t *)mThumbnailHeap->mHeap->base(),
1040 mThumbnailHeap->mHeap->getHeapID(),
1041 (uint8_t *)mRawHeap->mHeap->base(),
1042 mRawHeap->mHeap->getHeapID(),
1043 &mCrop)) {
1044 LOGE("native_jpeg_encode: jpeg_encoder_encode failed.");
1045 return false;
1046 }
1047 return true;
1048}
1049
1050bool QualcommCameraHardware::native_set_parm(
1051 cam_ctrl_type type, uint16_t length, void *value)
1052{
1053 struct msm_ctrl_cmd ctrlCmd;
1054
1055 ctrlCmd.timeout_ms = 5000;
1056 ctrlCmd.type = (uint16_t)type;
1057 ctrlCmd.length = length;
1058 // FIXME: this will be put in by the kernel
1059 ctrlCmd.resp_fd = mCameraControlFd;
1060 ctrlCmd.value = value;
1061
1062 LOGV("%s: fd %d, type %d, length %d", __FUNCTION__,
1063 mCameraControlFd, type, length);
1064 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0 ||
1065 ctrlCmd.status != CAM_CTRL_SUCCESS) {
1066 LOGE("%s: error (%s): fd %d, type %d, length %d, status %d",
1067 __FUNCTION__, strerror(errno),
1068 mCameraControlFd, type, length, ctrlCmd.status);
1069 return false;
1070 }
1071 return true;
1072}
1073
1074void QualcommCameraHardware::jpeg_set_location()
1075{
1076 bool encode_location = true;
1077 camera_position_type pt;
1078
1079#define PARSE_LOCATION(what,type,fmt,desc) do { \
1080 pt.what = 0; \
1081 const char *what##_str = mParameters.get("gps-"#what); \
1082 LOGV("GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
1083 if (what##_str) { \
1084 type what = 0; \
1085 if (sscanf(what##_str, fmt, &what) == 1) \
1086 pt.what = what; \
1087 else { \
1088 LOGE("GPS " #what " %s could not" \
1089 " be parsed as a " #desc, what##_str); \
1090 encode_location = false; \
1091 } \
1092 } \
1093 else { \
1094 LOGV("GPS " #what " not specified: " \
1095 "defaulting to zero in EXIF header."); \
1096 encode_location = false; \
1097 } \
1098 } while(0)
1099
1100 PARSE_LOCATION(timestamp, long, "%ld", "long");
1101 if (!pt.timestamp) pt.timestamp = time(NULL);
1102 PARSE_LOCATION(altitude, short, "%hd", "short");
1103 PARSE_LOCATION(latitude, double, "%lf", "double float");
1104 PARSE_LOCATION(longitude, double, "%lf", "double float");
1105
1106#undef PARSE_LOCATION
1107
1108 if (encode_location) {
1109 LOGD("setting image location ALT %d LAT %lf LON %lf",
1110 pt.altitude, pt.latitude, pt.longitude);
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001111/* Disabling until support is available.
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001112 if (!LINK_jpeg_encoder_setLocation(&pt)) {
1113 LOGE("jpeg_set_location: LINK_jpeg_encoder_setLocation failed.");
1114 }
Apurva Rajguru1db0c392009-11-30 21:39:04 -08001115*/
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001116 }
1117 else LOGV("not setting image location");
1118}
1119
1120void QualcommCameraHardware::runFrameThread(void *data)
1121{
1122 LOGV("runFrameThread E");
1123
1124 int cnt;
1125
1126#if DLOPEN_LIBMMCAMERA
1127 // We need to maintain a reference to libqcamera.so for the duration of the
1128 // frame thread, because we do not know when it will exit relative to the
1129 // lifetime of this object. We do not want to dlclose() libqcamera while
1130 // LINK_cam_frame is still running.
1131 void *libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
1132 LOGV("FRAME: loading libqcamera at %p", libhandle);
1133 if (!libhandle) {
1134 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1135 }
1136 if (libhandle)
1137#endif
1138 {
1139 LINK_cam_frame(data);
1140 }
1141
1142 mPreviewHeap.clear();
1143
1144#if DLOPEN_LIBMMCAMERA
1145 if (libhandle) {
1146 ::dlclose(libhandle);
1147 LOGV("FRAME: dlclose(libqcamera)");
1148 }
1149#endif
1150
1151 mFrameThreadWaitLock.lock();
1152 mFrameThreadRunning = false;
1153 mFrameThreadWait.signal();
1154 mFrameThreadWaitLock.unlock();
1155
1156 LOGV("runFrameThread X");
1157}
1158
1159void *frame_thread(void *user)
1160{
1161 LOGD("frame_thread E");
1162 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
1163 if (obj != 0) {
1164 obj->runFrameThread(user);
1165 }
1166 else LOGW("not starting frame thread: the object went away!");
1167 LOGD("frame_thread X");
1168 return NULL;
1169}
1170
1171bool QualcommCameraHardware::initPreview()
1172{
1173 // See comments in deinitPreview() for why we have to wait for the frame
1174 // thread here, and why we can't use pthread_join().
1175 int previewWidth, previewHeight;
1176 mParameters.getPreviewSize(&previewWidth, &previewHeight);
1177 LOGI("initPreview E: preview size=%dx%d", previewWidth, previewHeight);
1178 mFrameThreadWaitLock.lock();
1179 while (mFrameThreadRunning) {
1180 LOGV("initPreview: waiting for old frame thread to complete.");
1181 mFrameThreadWait.wait(mFrameThreadWaitLock);
1182 LOGV("initPreview: old frame thread completed.");
1183 }
1184 mFrameThreadWaitLock.unlock();
1185
1186 mSnapshotThreadWaitLock.lock();
1187 while (mSnapshotThreadRunning) {
1188 LOGV("initPreview: waiting for old snapshot thread to complete.");
1189 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
1190 LOGV("initPreview: old snapshot thread completed.");
1191 }
1192 mSnapshotThreadWaitLock.unlock();
1193
1194 int cnt = 0;
1195 mPreviewFrameSize = previewWidth * previewHeight * 3/2;
1196 mPreviewHeap = new PmemPool("/dev/pmem_adsp",
1197 MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
1198 mCameraControlFd,
1199 MSM_PMEM_OUTPUT2,
1200 mPreviewFrameSize,
1201 kPreviewBufferCount,
1202 mPreviewFrameSize,
1203 "preview");
1204
1205 if (!mPreviewHeap->initialized()) {
1206 mPreviewHeap.clear();
1207 LOGE("initPreview X: could not initialize preview heap.");
1208 return false;
1209 }
1210
1211 // mDimension will be filled with thumbnail_width, thumbnail_height,
1212 // orig_picture_dx, and orig_picture_dy after this function call. We need to
1213 // keep it for jpeg_encoder_encode.
1214 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1215 sizeof(cam_ctrl_dimension_t), &mDimension);
1216
1217 if (ret) {
1218 for (cnt = 0; cnt < kPreviewBufferCount; cnt++) {
1219 frames[cnt].fd = mPreviewHeap->mHeap->getHeapID();
1220 frames[cnt].buffer =
1221 (uint32_t)mPreviewHeap->mHeap->base() + mPreviewHeap->mAlignedBufferSize * cnt;
1222 frames[cnt].y_off = 0;
1223 frames[cnt].cbcr_off = previewWidth * previewHeight;
1224 frames[cnt].path = MSM_FRAME_ENC;
1225 }
1226
1227 mFrameThreadWaitLock.lock();
1228 pthread_attr_t attr;
1229 pthread_attr_init(&attr);
1230 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1231 mFrameThreadRunning = !pthread_create(&mFrameThread,
1232 &attr,
1233 frame_thread,
1234 &frames[kPreviewBufferCount-1]);
1235 ret = mFrameThreadRunning;
1236 mFrameThreadWaitLock.unlock();
1237 }
1238
1239 LOGV("initPreview X: %d", ret);
1240 return ret;
1241}
1242
1243void QualcommCameraHardware::deinitPreview(void)
1244{
1245 LOGI("deinitPreview E");
1246
1247 // When we call deinitPreview(), we signal to the frame thread that it
1248 // needs to exit, but we DO NOT WAIT for it to complete here. The problem
1249 // is that deinitPreview is sometimes called from the frame-thread's
1250 // callback, when the refcount on the Camera client reaches zero. If we
1251 // called pthread_join(), we would deadlock. So, we just call
1252 // LINK_camframe_terminate() in deinitPreview(), which makes sure that
1253 // after the preview callback returns, the camframe thread will exit. We
1254 // could call pthread_join() in initPreview() to join the last frame
1255 // thread. However, we would also have to call pthread_join() in release
1256 // as well, shortly before we destroy the object; this would cause the same
1257 // deadlock, since release(), like deinitPreview(), may also be called from
1258 // the frame-thread's callback. This we have to make the frame thread
1259 // detached, and use a separate mechanism to wait for it to complete.
1260
1261 if (LINK_camframe_terminate() < 0)
1262 LOGE("failed to stop the camframe thread: %s",
1263 strerror(errno));
1264 LOGI("deinitPreview X");
1265}
1266
1267bool QualcommCameraHardware::initRaw(bool initJpegHeap)
1268{
1269 int rawWidth, rawHeight;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001270 char value[PROPERTY_VALUE_MAX];
1271
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001272 mParameters.getPictureSize(&rawWidth, &rawHeight);
1273 LOGV("initRaw E: picture size=%dx%d", rawWidth, rawHeight);
1274
1275 // mDimension will be filled with thumbnail_width, thumbnail_height,
1276 // orig_picture_dx, and orig_picture_dy after this function call. We need to
1277 // keep it for jpeg_encoder_encode.
1278 bool ret = native_set_parm(CAMERA_SET_PARM_DIMENSION,
1279 sizeof(cam_ctrl_dimension_t), &mDimension);
1280 if(!ret) {
1281 LOGE("initRaw X: failed to set dimension");
1282 return false;
1283 }
1284
1285 if (mJpegHeap != NULL) {
1286 LOGV("initRaw: clearing old mJpegHeap.");
1287 mJpegHeap.clear();
1288 }
1289
1290 // Snapshot
1291 mRawSize = rawWidth * rawHeight * 3 / 2;
Apurva Rajguru8d1773b2009-12-02 14:21:23 -08001292 property_get("ro.product.device",value," ");
1293
1294 if(!strcmp(value,"msm7627_surf"))
1295 mJpegMaxSize = CEILING16(rawWidth) * CEILING16(rawHeight) * 3 / 2;
1296 else
1297 mJpegMaxSize = rawWidth * rawHeight * 3 / 2;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001298
1299 LOGV("initRaw: initializing mRawHeap.");
1300 mRawHeap =
1301 new PmemPool("/dev/pmem_camera",
1302 MemoryHeapBase::READ_ONLY,
1303 mCameraControlFd,
1304 MSM_PMEM_MAINIMG,
1305 mJpegMaxSize,
1306 kRawBufferCount,
1307 mRawSize,
1308 "snapshot camera");
1309
1310 if (!mRawHeap->initialized()) {
1311 LOGE("initRaw X failed with pmem_camera, trying with pmem_adsp");
1312 mRawHeap =
1313 new PmemPool("/dev/pmem_adsp",
1314 MemoryHeapBase::READ_ONLY,
1315 mCameraControlFd,
1316 MSM_PMEM_MAINIMG,
1317 mJpegMaxSize,
1318 kRawBufferCount,
1319 mRawSize,
1320 "snapshot camera");
1321 if (!mRawHeap->initialized()) {
1322 mRawHeap.clear();
1323 LOGE("initRaw X: error initializing mRawHeap");
1324 return false;
1325 }
1326 }
1327
1328 LOGV("do_mmap snapshot pbuf = %p, pmem_fd = %d",
1329 (uint8_t *)mRawHeap->mHeap->base(), mRawHeap->mHeap->getHeapID());
1330
1331 // Jpeg
1332
1333 if (initJpegHeap) {
1334 LOGV("initRaw: initializing mJpegHeap.");
1335 mJpegHeap =
1336 new AshmemPool(mJpegMaxSize,
1337 kJpegBufferCount,
1338 0, // we do not know how big the picture will be
1339 "jpeg");
1340
1341 if (!mJpegHeap->initialized()) {
1342 mJpegHeap.clear();
1343 mRawHeap.clear();
1344 LOGE("initRaw X failed: error initializing mJpegHeap.");
1345 return false;
1346 }
1347
1348 // Thumbnails
1349
1350 mThumbnailHeap =
1351 new PmemPool("/dev/pmem_adsp",
1352 MemoryHeapBase::READ_ONLY,
1353 mCameraControlFd,
1354 MSM_PMEM_THUMBNAIL,
1355 THUMBNAIL_BUFFER_SIZE,
1356 1,
1357 THUMBNAIL_BUFFER_SIZE,
1358 "thumbnail");
1359
1360 if (!mThumbnailHeap->initialized()) {
1361 mThumbnailHeap.clear();
1362 mJpegHeap.clear();
1363 mRawHeap.clear();
1364 LOGE("initRaw X failed: error initializing mThumbnailHeap.");
1365 return false;
1366 }
1367 }
1368
1369 LOGV("initRaw X");
1370 return true;
1371}
1372
1373void QualcommCameraHardware::deinitRaw()
1374{
1375 LOGV("deinitRaw E");
1376
1377 mThumbnailHeap.clear();
1378 mJpegHeap.clear();
1379 mRawHeap.clear();
1380 mDisplayHeap.clear();
1381
1382 LOGV("deinitRaw X");
1383}
1384
1385void QualcommCameraHardware::release()
1386{
1387 LOGD("release E");
1388 Mutex::Autolock l(&mLock);
1389
1390#if DLOPEN_LIBMMCAMERA
1391 if (libmmcamera == NULL) {
1392 LOGE("ERROR: multiple release!");
1393 return;
1394 }
1395#else
1396#warning "Cannot detect multiple release when not dlopen()ing libqcamera!"
1397#endif
1398
1399 int cnt, rc;
1400 struct msm_ctrl_cmd ctrlCmd;
1401
1402 if (mCameraRunning) {
1403 if(mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
1404 mRecordFrameLock.lock();
1405 mReleasedRecordingFrame = true;
1406 mRecordWait.signal();
1407 mRecordFrameLock.unlock();
1408 }
1409 stopPreviewInternal();
1410 }
1411
1412 LINK_jpeg_encoder_join();
1413 deinitRaw();
1414
1415 ctrlCmd.timeout_ms = 5000;
1416 ctrlCmd.length = 0;
1417 ctrlCmd.type = (uint16_t)CAMERA_EXIT;
1418 ctrlCmd.resp_fd = mCameraControlFd; // FIXME: this will be put in by the kernel
1419 if (ioctl(mCameraControlFd, MSM_CAM_IOCTL_CTRL_COMMAND, &ctrlCmd) < 0)
1420 LOGE("ioctl CAMERA_EXIT fd %d error %s",
1421 mCameraControlFd, strerror(errno));
1422
1423 LINK_release_cam_conf_thread();
1424
1425 close(mCameraControlFd);
1426 mCameraControlFd = -1;
1427
1428#if DLOPEN_LIBMMCAMERA
1429 if (libmmcamera) {
1430 ::dlclose(libmmcamera);
1431 LOGV("dlclose(libqcamera)");
1432 libmmcamera = NULL;
1433 }
1434#endif
1435
1436 Mutex::Autolock lock(&singleton_lock);
1437 singleton_releasing = true;
1438
1439 LOGD("release X");
1440}
1441
1442QualcommCameraHardware::~QualcommCameraHardware()
1443{
1444 LOGD("~QualcommCameraHardware E");
1445 Mutex::Autolock lock(&singleton_lock);
1446 singleton.clear();
1447 singleton_releasing = false;
1448 singleton_wait.signal();
1449 LOGD("~QualcommCameraHardware X");
1450}
1451
1452sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
1453{
1454 LOGV("getRawHeap");
1455 return mDisplayHeap != NULL ? mDisplayHeap->mHeap : NULL;
1456}
1457
1458sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
1459{
1460 LOGV("getPreviewHeap");
1461 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
1462}
1463
1464status_t QualcommCameraHardware::startPreviewInternal()
1465{
1466 if(mCameraRunning) {
1467 LOGV("startPreview X: preview already running.");
1468 return NO_ERROR;
1469 }
1470
1471 if (!mPreviewInitialized) {
1472 mPreviewInitialized = initPreview();
1473 if (!mPreviewInitialized) {
1474 LOGE("startPreview X initPreview failed. Not starting preview.");
1475 return UNKNOWN_ERROR;
1476 }
1477 }
1478
1479 mCameraRunning = native_start_preview(mCameraControlFd);
1480 if(!mCameraRunning) {
1481 deinitPreview();
1482 mPreviewInitialized = false;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001483 mOverlay = NULL;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001484 LOGE("startPreview X: native_start_preview failed!");
1485 return UNKNOWN_ERROR;
1486 }
1487
1488 LOGV("startPreview X");
1489 return NO_ERROR;
1490}
1491
1492status_t QualcommCameraHardware::startPreview()
1493{
1494 LOGV("startPreview E");
1495 Mutex::Autolock l(&mLock);
1496 return startPreviewInternal();
1497}
1498
1499void QualcommCameraHardware::stopPreviewInternal()
1500{
1501 LOGV("stopPreviewInternal E: %d", mCameraRunning);
1502 if (mCameraRunning) {
1503 // Cancel auto focus.
1504 {
1505 if (mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
1506 cancelAutoFocusInternal();
1507 }
1508 }
1509
1510 mCameraRunning = !native_stop_preview(mCameraControlFd);
1511 if (!mCameraRunning && mPreviewInitialized) {
1512 deinitPreview();
1513 mPreviewInitialized = false;
1514 }
1515 else LOGE("stopPreviewInternal: failed to stop preview");
1516 }
1517 LOGV("stopPreviewInternal X: %d", mCameraRunning);
1518}
1519
1520void QualcommCameraHardware::stopPreview()
1521{
1522 LOGV("stopPreview: E");
1523 Mutex::Autolock l(&mLock);
1524 {
1525 if (mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
1526 return;
1527 }
1528 stopPreviewInternal();
1529 LOGV("stopPreview: X");
1530}
1531
1532void QualcommCameraHardware::runAutoFocus()
1533{
1534 bool status = true;
1535 void *libhandle = NULL;
1536
1537 mAutoFocusThreadLock.lock();
1538 // Skip autofocus if focus mode is infinity.
1539 if (strcmp(mParameters.get(CameraParameters::KEY_FOCUS_MODE),
1540 CameraParameters::FOCUS_MODE_INFINITY) == 0) {
1541 goto done;
1542 }
1543
1544 mAutoFocusFd = open(MSM_CAMERA_CONTROL, O_RDWR);
1545 if (mAutoFocusFd < 0) {
1546 LOGE("autofocus: cannot open %s: %s",
1547 MSM_CAMERA_CONTROL,
1548 strerror(errno));
1549 mAutoFocusThreadRunning = false;
1550 mAutoFocusThreadLock.unlock();
1551 return;
1552 }
1553
1554#if DLOPEN_LIBMMCAMERA
1555 // We need to maintain a reference to libqcamera.so for the duration of the
1556 // AF thread, because we do not know when it will exit relative to the
1557 // lifetime of this object. We do not want to dlclose() libqcamera while
1558 // LINK_cam_frame is still running.
1559 libhandle = ::dlopen("liboemcamera.so", RTLD_NOW);
1560 LOGV("AF: loading libqcamera at %p", libhandle);
1561 if (!libhandle) {
1562 LOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
1563 close(mAutoFocusFd);
1564 mAutoFocusFd = -1;
1565 mAutoFocusThreadRunning = false;
1566 mAutoFocusThreadLock.unlock();
1567 return;
1568 }
1569#endif
1570
1571 /* This will block until either AF completes or is cancelled. */
1572 LOGV("af start (fd %d)", mAutoFocusFd);
1573 status = native_set_afmode(mAutoFocusFd, AF_MODE_AUTO);
1574 LOGV("af done: %d", (int)status);
1575 close(mAutoFocusFd);
1576 mAutoFocusFd = -1;
1577
1578done:
1579 mAutoFocusThreadRunning = false;
1580 mAutoFocusThreadLock.unlock();
1581
1582 mCallbackLock.lock();
1583 bool autoFocusEnabled = mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS);
1584 notify_callback cb = mNotifyCallback;
1585 void *data = mCallbackCookie;
1586 mCallbackLock.unlock();
1587 if (autoFocusEnabled)
1588 cb(CAMERA_MSG_FOCUS, status, 0, data);
1589
1590#if DLOPEN_LIBMMCAMERA
1591 if (libhandle) {
1592 ::dlclose(libhandle);
1593 LOGV("AF: dlclose(libqcamera)");
1594 }
1595#endif
1596}
1597
1598status_t QualcommCameraHardware::cancelAutoFocusInternal()
1599{
1600 LOGV("cancelAutoFocusInternal E");
1601
1602#if 0
1603 if (mAutoFocusFd < 0) {
1604 LOGV("cancelAutoFocusInternal X: not in progress");
1605 return NO_ERROR;
1606 }
1607#endif
1608
1609 status_t rc = native_cancel_afmode(mCameraControlFd, mAutoFocusFd) ?
1610 NO_ERROR :
1611 UNKNOWN_ERROR;
1612
1613 LOGV("cancelAutoFocusInternal X: %d", rc);
1614 return rc;
1615}
1616
1617void *auto_focus_thread(void *user)
1618{
1619 LOGV("auto_focus_thread E");
1620 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
1621 if (obj != 0) {
1622 obj->runAutoFocus();
1623 }
1624 else LOGW("not starting autofocus: the object went away!");
1625 LOGV("auto_focus_thread X");
1626 return NULL;
1627}
1628
1629status_t QualcommCameraHardware::autoFocus()
1630{
1631 LOGV("autoFocus E");
1632 Mutex::Autolock l(&mLock);
1633
1634 if (mCameraControlFd < 0) {
1635 LOGE("not starting autofocus: main control fd %d", mCameraControlFd);
1636 return UNKNOWN_ERROR;
1637 }
1638
1639 {
1640 mAutoFocusThreadLock.lock();
1641 if (!mAutoFocusThreadRunning) {
1642 // Create a detached thread here so that we don't have to wait
1643 // for it when we cancel AF.
1644 pthread_t thr;
1645 pthread_attr_t attr;
1646 pthread_attr_init(&attr);
1647 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1648 mAutoFocusThreadRunning =
1649 !pthread_create(&thr, &attr,
1650 auto_focus_thread, NULL);
1651 if (!mAutoFocusThreadRunning) {
1652 LOGE("failed to start autofocus thread");
1653 mAutoFocusThreadLock.unlock();
1654 return UNKNOWN_ERROR;
1655 }
1656 }
1657 mAutoFocusThreadLock.unlock();
1658 }
1659
1660 LOGV("autoFocus X");
1661 return NO_ERROR;
1662}
1663
1664status_t QualcommCameraHardware::cancelAutoFocus()
1665{
1666 LOGV("cancelAutoFocus E");
1667 Mutex::Autolock l(&mLock);
1668
1669 int rc = NO_ERROR;
1670 if (mCameraRunning && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_FOCUS)) {
1671 rc = cancelAutoFocusInternal();
1672 }
1673
1674 LOGV("cancelAutoFocus X");
1675 return rc;
1676}
1677
1678void QualcommCameraHardware::runSnapshotThread(void *data)
1679{
1680 LOGV("runSnapshotThread E");
1681 if (native_start_snapshot(mCameraControlFd))
1682 receiveRawPicture();
1683 else
1684 LOGE("main: native_start_snapshot failed!");
1685
1686 mSnapshotThreadWaitLock.lock();
1687 mSnapshotThreadRunning = false;
1688 mSnapshotThreadWait.signal();
1689 mSnapshotThreadWaitLock.unlock();
1690
1691 LOGV("runSnapshotThread X");
1692}
1693
1694void *snapshot_thread(void *user)
1695{
1696 LOGD("snapshot_thread E");
1697 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
1698 if (obj != 0) {
1699 obj->runSnapshotThread(user);
1700 }
1701 else LOGW("not starting snapshot thread: the object went away!");
1702 LOGD("snapshot_thread X");
1703 return NULL;
1704}
1705
1706status_t QualcommCameraHardware::takePicture()
1707{
1708 LOGV("takePicture(%d)", mMsgEnabled);
1709 Mutex::Autolock l(&mLock);
1710
1711 // Wait for old snapshot thread to complete.
1712 mSnapshotThreadWaitLock.lock();
1713 while (mSnapshotThreadRunning) {
1714 LOGV("takePicture: waiting for old snapshot thread to complete.");
1715 mSnapshotThreadWait.wait(mSnapshotThreadWaitLock);
1716 LOGV("takePicture: old snapshot thread completed.");
1717 }
1718
1719 if(!native_prepare_snapshot(mCameraControlFd)) {
1720 mSnapshotThreadWaitLock.unlock();
1721 return UNKNOWN_ERROR;
1722 }
1723
1724 stopPreviewInternal();
1725
1726 if (!initRaw(mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE))) {
1727 LOGE("initRaw failed. Not taking picture.");
1728 mSnapshotThreadWaitLock.unlock();
1729 return UNKNOWN_ERROR;
1730 }
1731
1732 mShutterLock.lock();
1733 mShutterPending = true;
1734 mShutterLock.unlock();
1735
1736 pthread_attr_t attr;
1737 pthread_attr_init(&attr);
1738 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1739 mSnapshotThreadRunning = !pthread_create(&mSnapshotThread,
1740 &attr,
1741 snapshot_thread,
1742 NULL);
1743 mSnapshotThreadWaitLock.unlock();
1744
1745 LOGV("takePicture: X");
1746 return mSnapshotThreadRunning ? NO_ERROR : UNKNOWN_ERROR;
1747}
1748
1749status_t QualcommCameraHardware::cancelPicture()
1750{
1751 status_t rc;
1752 LOGV("cancelPicture: E");
1753 rc = native_stop_snapshot(mCameraControlFd) ? NO_ERROR : UNKNOWN_ERROR;
1754 LOGV("cancelPicture: X: %d", rc);
1755 return rc;
1756}
1757
1758status_t QualcommCameraHardware::setParameters(const CameraParameters& params)
1759{
1760 LOGV("setParameters: E params = %p", &params);
1761
1762 Mutex::Autolock l(&mLock);
1763 status_t rc, final_rc = NO_ERROR;
1764
1765 if ((rc = setPreviewSize(params))) final_rc = rc;
1766 if ((rc = setPictureSize(params))) final_rc = rc;
1767 if ((rc = setJpegQuality(params))) final_rc = rc;
1768 if ((rc = setAntibanding(params))) final_rc = rc;
1769 if ((rc = setEffect(params))) final_rc = rc;
Apurva Rajguru55562b02009-12-03 12:25:35 -08001770 if ((rc = setAutoExposure(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001771 if ((rc = setWhiteBalance(params))) final_rc = rc;
1772 if ((rc = setFlash(params))) final_rc = rc;
1773 if ((rc = setGpsLocation(params))) final_rc = rc;
1774 if ((rc = setRotation(params))) final_rc = rc;
1775 if ((rc = setZoom(params))) final_rc = rc;
1776 if ((rc = setFocusMode(params))) final_rc = rc;
1777 if ((rc = setOrientation(params))) final_rc = rc;
Nishant Panditc8c1ee72009-12-03 16:24:02 +05301778 if ((rc = setBrightness(params))) final_rc = rc;
1779 if ((rc = setLensshadeValue(params))) final_rc = rc;
1780 if ((rc = setISOValue(params))) final_rc = rc;
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001781
1782 LOGV("setParameters: X");
1783 return final_rc;
1784}
1785
1786CameraParameters QualcommCameraHardware::getParameters() const
1787{
1788 LOGV("getParameters: EX");
1789 return mParameters;
1790}
1791
1792status_t QualcommCameraHardware::sendCommand(int32_t command, int32_t arg1,
1793 int32_t arg2)
1794{
1795 LOGV("sendCommand: EX");
1796 return BAD_VALUE;
1797}
1798
1799extern "C" sp<CameraHardwareInterface> openCameraHardware()
1800{
1801 LOGV("openCameraHardware: call createInstance");
1802 return QualcommCameraHardware::createInstance();
1803}
1804
1805wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
1806
1807// If the hardware already exists, return a strong pointer to the current
1808// object. If not, create a new hardware object, put it in the singleton,
1809// and return it.
1810sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
1811{
1812 LOGD("createInstance: E");
1813
1814 Mutex::Autolock lock(&singleton_lock);
1815
1816 // Wait until the previous release is done.
1817 while (singleton_releasing) {
1818 LOGD("Wait for previous release.");
1819 singleton_wait.wait(singleton_lock);
1820 }
1821
1822 if (singleton != 0) {
1823 sp<CameraHardwareInterface> hardware = singleton.promote();
1824 if (hardware != 0) {
1825 LOGD("createInstance: X return existing hardware=%p", &(*hardware));
1826 return hardware;
1827 }
1828 }
1829
1830 {
1831 struct stat st;
1832 int rc = stat("/dev/oncrpc", &st);
1833 if (rc < 0) {
1834 LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
1835 return NULL;
1836 }
1837 }
1838
1839 QualcommCameraHardware *cam = new QualcommCameraHardware();
1840 sp<QualcommCameraHardware> hardware(cam);
1841 singleton = hardware;
1842
1843 if (!cam->startCamera()) {
1844 LOGE("%s: startCamera failed!", __FUNCTION__);
1845 return NULL;
1846 }
1847
1848 cam->initDefaultParameters();
1849 LOGD("createInstance: X created hardware=%p", &(*hardware));
1850 return hardware;
1851}
1852
1853// For internal use only, hence the strong pointer to the derived type.
1854sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
1855{
1856 sp<CameraHardwareInterface> hardware = singleton.promote();
1857 if (hardware != 0) {
1858 // LOGV("getInstance: X old instance of hardware");
1859 return sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>(hardware.get()));
1860 } else {
1861 LOGV("getInstance: X new instance of hardware");
1862 return sp<QualcommCameraHardware>();
1863 }
1864}
1865
1866void QualcommCameraHardware::receivePreviewFrame(struct msm_frame *frame)
1867{
1868// LOGV("receivePreviewFrame E");
1869
1870 if (!mCameraRunning) {
1871 LOGE("ignoring preview callback--camera has been stopped");
1872 return;
1873 }
1874
1875 mCallbackLock.lock();
1876 int msgEnabled = mMsgEnabled;
1877 data_callback pcb = mDataCallback;
1878 void *pdata = mCallbackCookie;
1879 data_callback_timestamp rcb = mDataCallbackTimestamp;
1880 void *rdata = mCallbackCookie;
1881 mCallbackLock.unlock();
1882
1883 // Find the offset within the heap of the current buffer.
1884 ssize_t offset =
1885 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
1886 offset /= mPreviewHeap->mAlignedBufferSize;
1887
1888 mInPreviewCallback = true;
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08001889 if((mUseOverlay == true) && (mOverlay != NULL) ) {
1890 ssize_t offset_addr =
1891 (ssize_t)frame->buffer - (ssize_t)mPreviewHeap->mHeap->base();
1892 mOverlayLock.lock();
1893 mOverlay->setFd(mPreviewHeap->mHeap->getHeapID());
1894 mOverlay->queueBuffer((void *)offset_addr);
1895 mOverlayLock.unlock();
1896 LOGV(" Queueing buffer %x from HAL for display ", offset_addr );
1897 }
1898 /* In case of Overlay, the MSG_PREVIEW_FRAME will be disabled
1899 * second frame onwards. Hence we can keep this piece of code
1900 * in overlay case as well. */
Priya Komarlingamb85535d2009-11-30 13:06:01 -08001901 if (pcb != NULL && (msgEnabled & CAMERA_MSG_PREVIEW_FRAME))
1902 pcb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap->mBuffers[offset],
1903 pdata);
1904
1905 if(rcb != NULL && (msgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
1906 rcb(systemTime(), CAMERA_MSG_VIDEO_FRAME, mPreviewHeap->mBuffers[offset], rdata);
1907 Mutex::Autolock rLock(&mRecordFrameLock);
1908 if (mReleasedRecordingFrame != true) {
1909 LOGV("block waiting for frame release");
1910 mRecordWait.wait(mRecordFrameLock);
1911 LOGV("frame released, continuing");
1912 }
1913 mReleasedRecordingFrame = false;
1914 }
1915 mInPreviewCallback = false;
1916
1917// LOGV("receivePreviewFrame X");
1918}
1919
1920status_t QualcommCameraHardware::startRecording()
1921{
1922 LOGV("startRecording E");
1923 Mutex::Autolock l(&mLock);
1924 mReleasedRecordingFrame = false;
1925 return startPreviewInternal();
1926}
1927
1928void QualcommCameraHardware::stopRecording()
1929{
1930 LOGV("stopRecording: E");
1931 Mutex::Autolock l(&mLock);
1932 {
1933 mRecordFrameLock.lock();
1934 mReleasedRecordingFrame = true;
1935 mRecordWait.signal();
1936 mRecordFrameLock.unlock();
1937
1938 if(mDataCallback && (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)) {
1939 LOGV("stopRecording: X, preview still in progress");
1940 return;
1941 }
1942 }
1943
1944 stopPreviewInternal();
1945 LOGV("stopRecording: X");
1946}
1947
1948void QualcommCameraHardware::releaseRecordingFrame(
1949 const sp<IMemory>& mem __attribute__((unused)))
1950{
1951 LOGV("releaseRecordingFrame E");
1952 Mutex::Autolock rLock(&mRecordFrameLock);
1953 mReleasedRecordingFrame = true;
1954 mRecordWait.signal();
1955 LOGV("releaseRecordingFrame X");
1956}
1957
1958bool QualcommCameraHardware::recordingEnabled()
1959{
1960 return mCameraRunning && mDataCallbackTimestamp && (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME);
1961}
1962
1963void QualcommCameraHardware::notifyShutter(common_crop_t *crop)
1964{
1965 mShutterLock.lock();
1966 image_rect_type size;
1967
1968 if (mShutterPending && mNotifyCallback && (mMsgEnabled & CAMERA_MSG_SHUTTER)) {
1969 LOGV("out2_w=%d, out2_h=%d, in2_w=%d, in2_h=%d",
1970 crop->out2_w, crop->out2_h, crop->in2_w, crop->in2_h);
1971 LOGV("out1_w=%d, out1_h=%d, in1_w=%d, in1_h=%d",
1972 crop->out1_w, crop->out1_h, crop->in1_w, crop->in1_h);
1973
1974 // To workaround a bug in MDP which happens if either
1975 // dimension > 2048, we display the thumbnail instead.
1976 mDisplayHeap = mRawHeap;
1977 if (crop->in1_w == 0 || crop->in1_h == 0) {
1978 // Full size
1979 size.width = mDimension.picture_width;
1980 size.height = mDimension.picture_height;
1981 if (size.width > 2048 || size.height > 2048) {
1982 size.width = mDimension.ui_thumbnail_width;
1983 size.height = mDimension.ui_thumbnail_height;
1984 mDisplayHeap = mThumbnailHeap;
1985 }
1986 } else {
1987 // Cropped
1988 size.width = crop->in2_w & ~1;
1989 size.height = crop->in2_h & ~1;
1990 if (size.width > 2048 || size.height > 2048) {
1991 size.width = crop->in1_w & ~1;
1992 size.height = crop->in1_h & ~1;
1993 mDisplayHeap = mThumbnailHeap;
1994 }
1995 }
1996
1997 mNotifyCallback(CAMERA_MSG_SHUTTER, (int32_t)&size, 0,
1998 mCallbackCookie);
1999 mShutterPending = false;
2000 }
2001 mShutterLock.unlock();
2002}
2003
2004static void receive_shutter_callback(common_crop_t *crop)
2005{
2006 LOGV("receive_shutter_callback: E");
2007 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2008 if (obj != 0) {
2009 obj->notifyShutter(crop);
2010 }
2011 LOGV("receive_shutter_callback: X");
2012}
2013
2014// Crop the picture in place.
2015static void crop_yuv420(uint32_t width, uint32_t height,
2016 uint32_t cropped_width, uint32_t cropped_height,
2017 uint8_t *image)
2018{
2019 uint32_t i, x, y;
2020 uint8_t* chroma_src, *chroma_dst;
2021
2022 // Calculate the start position of the cropped area.
2023 x = (width - cropped_width) / 2;
2024 y = (height - cropped_height) / 2;
2025 x &= ~1;
2026 y &= ~1;
2027
2028 // Copy luma component.
2029 for(i = 0; i < cropped_height; i++)
2030 memcpy(image + i * cropped_width,
2031 image + width * (y + i) + x,
2032 cropped_width);
2033
2034 chroma_src = image + width * height;
2035 chroma_dst = image + cropped_width * cropped_height;
2036
2037 // Copy chroma components.
2038 cropped_height /= 2;
2039 y /= 2;
2040 for(i = 0; i < cropped_height; i++)
2041 memcpy(chroma_dst + i * cropped_width,
2042 chroma_src + width * (y + i) + x,
2043 cropped_width);
2044}
2045
2046void QualcommCameraHardware::receiveRawPicture()
2047{
2048 LOGV("receiveRawPicture: E");
2049
2050 Mutex::Autolock cbLock(&mCallbackLock);
2051 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)) {
2052 if(native_get_picture(mCameraControlFd, &mCrop) == false) {
2053 LOGE("getPicture failed!");
2054 return;
2055 }
2056 mCrop.in1_w &= ~1;
2057 mCrop.in1_h &= ~1;
2058 mCrop.in2_w &= ~1;
2059 mCrop.in2_h &= ~1;
2060
2061 // By the time native_get_picture returns, picture is taken. Call
2062 // shutter callback if cam config thread has not done that.
2063 notifyShutter(&mCrop);
2064
2065 // Crop the image if zoomed.
2066 if (mCrop.in2_w != 0 && mCrop.in2_h != 0) {
2067 crop_yuv420(mCrop.out2_w, mCrop.out2_h, mCrop.in2_w, mCrop.in2_h,
2068 (uint8_t *)mRawHeap->mHeap->base());
2069 crop_yuv420(mCrop.out1_w, mCrop.out1_h, mCrop.in1_w, mCrop.in1_h,
2070 (uint8_t *)mThumbnailHeap->mHeap->base());
2071 // We do not need jpeg encoder to upscale the image. Set the new
2072 // dimension for encoder.
2073 mDimension.orig_picture_dx = mCrop.in2_w;
2074 mDimension.orig_picture_dy = mCrop.in2_h;
2075 mDimension.thumbnail_width = mCrop.in1_w;
2076 mDimension.thumbnail_height = mCrop.in1_h;
2077 memset(&mCrop, 0, sizeof(mCrop));
2078 }
2079
2080 mDataCallback(CAMERA_MSG_RAW_IMAGE, mDisplayHeap->mBuffers[0],
2081 mCallbackCookie);
2082 }
2083 else LOGV("Raw-picture callback was canceled--skipping.");
2084
2085 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2086 mJpegSize = 0;
2087 if (LINK_jpeg_encoder_init()) {
2088 if(native_jpeg_encode()) {
2089 LOGV("receiveRawPicture: X (success)");
2090 return;
2091 }
2092 LOGE("jpeg encoding failed");
2093 }
2094 else LOGE("receiveRawPicture X: jpeg_encoder_init failed.");
2095 }
2096 else LOGV("JPEG callback is NULL, not encoding image.");
2097 deinitRaw();
2098 LOGV("receiveRawPicture: X");
2099}
2100
2101void QualcommCameraHardware::receiveJpegPictureFragment(
2102 uint8_t *buff_ptr, uint32_t buff_size)
2103{
2104 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
2105 remaining -= mJpegSize;
2106 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
2107
2108 LOGV("receiveJpegPictureFragment size %d", buff_size);
2109 if (buff_size > remaining) {
2110 LOGE("receiveJpegPictureFragment: size %d exceeds what "
2111 "remains in JPEG heap (%d), truncating",
2112 buff_size,
2113 remaining);
2114 buff_size = remaining;
2115 }
2116 memcpy(base + mJpegSize, buff_ptr, buff_size);
2117 mJpegSize += buff_size;
2118}
2119
2120void QualcommCameraHardware::receiveJpegPicture(void)
2121{
2122 LOGV("receiveJpegPicture: E image (%d uint8_ts out of %d)",
2123 mJpegSize, mJpegHeap->mBufferSize);
2124 Mutex::Autolock cbLock(&mCallbackLock);
2125
2126 int index = 0, rc;
2127
2128 if (mDataCallback && (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE)) {
2129 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
2130 // that the JPEG image's size will probably change from one snapshot
2131 // to the next, so we cannot reuse the MemoryBase object.
2132 sp<MemoryBase> buffer = new
2133 MemoryBase(mJpegHeap->mHeap,
2134 index * mJpegHeap->mBufferSize +
2135 0,
2136 mJpegSize);
2137 mDataCallback(CAMERA_MSG_COMPRESSED_IMAGE, buffer, mCallbackCookie);
2138 buffer = NULL;
2139 }
2140 else LOGV("JPEG callback was cancelled--not delivering image.");
2141
2142 LINK_jpeg_encoder_join();
2143 deinitRaw();
2144
2145 LOGV("receiveJpegPicture: X callback done.");
2146}
2147
2148bool QualcommCameraHardware::previewEnabled()
2149{
2150 return mCameraRunning && mDataCallback && (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME);
2151}
2152
2153status_t QualcommCameraHardware::setPreviewSize(const CameraParameters& params)
2154{
2155 int width, height;
2156 params.getPreviewSize(&width, &height);
2157 LOGV("requested preview size %d x %d", width, height);
2158
2159 // Validate the preview size
2160 for (size_t i = 0; i < PREVIEW_SIZE_COUNT; ++i) {
2161 if (width == preview_sizes[i].width
2162 && height == preview_sizes[i].height) {
2163 mParameters.setPreviewSize(width, height);
2164 mDimension.display_width = width;
2165 mDimension.display_height = height;
2166 return NO_ERROR;
2167 }
2168 }
2169 LOGE("Invalid preview size requested: %dx%d", width, height);
2170 return BAD_VALUE;
2171}
2172
2173status_t QualcommCameraHardware::setPictureSize(const CameraParameters& params)
2174{
2175 int width, height;
2176 params.getPictureSize(&width, &height);
2177 LOGV("requested picture size %d x %d", width, height);
2178
2179 // Validate the picture size
2180 for (int i = 0; i < PICTURE_SIZE_COUNT; ++i) {
2181 if (width == picture_sizes[i].width
2182 && height == picture_sizes[i].height) {
2183 mParameters.setPictureSize(width, height);
2184 mDimension.picture_width = width;
2185 mDimension.picture_height = height;
2186 return NO_ERROR;
2187 }
2188 }
2189 LOGE("Invalid picture size requested: %dx%d", width, height);
2190 return BAD_VALUE;
2191}
2192
2193status_t QualcommCameraHardware::setJpegQuality(const CameraParameters& params) {
2194 status_t rc = NO_ERROR;
2195 int quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
2196 if (quality > 0 && quality <= 100) {
2197 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, quality);
2198 } else {
2199 LOGE("Invalid jpeg quality=%d", quality);
2200 rc = BAD_VALUE;
2201 }
2202
2203 quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
2204 if (quality > 0 && quality <= 100) {
2205 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, quality);
2206 } else {
2207 LOGE("Invalid jpeg thumbnail quality=%d", quality);
2208 rc = BAD_VALUE;
2209 }
2210 return rc;
2211}
2212
2213status_t QualcommCameraHardware::setEffect(const CameraParameters& params)
2214{
2215 const char *str = params.get(CameraParameters::KEY_EFFECT);
2216 if (str != NULL) {
2217 int32_t value = attr_lookup(effects, sizeof(effects) / sizeof(str_map), str);
2218 if (value != NOT_FOUND) {
2219 mParameters.set(CameraParameters::KEY_EFFECT, str);
2220 bool ret = native_set_parm(CAMERA_SET_PARM_EFFECT, sizeof(value),
2221 (void *)&value);
2222 return ret ? NO_ERROR : UNKNOWN_ERROR;
2223 }
2224 }
2225 LOGE("Invalid effect value: %s", (str == NULL) ? "NULL" : str);
2226 return BAD_VALUE;
2227}
2228
Apurva Rajguru55562b02009-12-03 12:25:35 -08002229status_t QualcommCameraHardware::setAutoExposure(const CameraParameters& params)
2230{
2231 const char *str = params.get(CameraParameters::KEY_AUTO_EXPOSURE);
2232 if (str != NULL) {
2233 int32_t value = attr_lookup(autoexposure, sizeof(autoexposure) / sizeof(str_map), str);
2234 if (value != NOT_FOUND) {
2235 mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE, str);
2236 bool ret = native_set_parm(CAMERA_SET_PARM_EXPOSURE, sizeof(value),
2237 (void *)&value);
2238 return ret ? NO_ERROR : UNKNOWN_ERROR;
2239 }
2240 }
2241 LOGE("Invalid auto exposure value: %s", (str == NULL) ? "NULL" : str);
2242 return BAD_VALUE;
2243}
2244
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302245status_t QualcommCameraHardware::setBrightness(const CameraParameters& params) {
2246 int brightness = params.getInt("luma-adaptation");
2247 if (mBrightness != brightness) {
2248 LOGV(" new brightness value : %d ", brightness);
2249 mBrightness = brightness;
2250
2251 bool ret = native_set_parm(CAMERA_SET_PARM_BRIGHTNESS, sizeof(mBrightness),
2252 (void *)&mBrightness);
2253 return ret ? NO_ERROR : UNKNOWN_ERROR;
2254 } else {
2255 return NO_ERROR;
2256 }
2257}
2258
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002259status_t QualcommCameraHardware::setWhiteBalance(const CameraParameters& params)
2260{
2261 const char *str = params.get(CameraParameters::KEY_WHITE_BALANCE);
2262 if (str != NULL) {
2263 int32_t value = attr_lookup(whitebalance, sizeof(whitebalance) / sizeof(str_map), str);
2264 if (value != NOT_FOUND) {
2265 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, str);
2266 bool ret = native_set_parm(CAMERA_SET_PARM_WB, sizeof(value),
2267 (void *)&value);
2268 return ret ? NO_ERROR : UNKNOWN_ERROR;
2269 }
2270 }
2271 LOGE("Invalid whitebalance value: %s", (str == NULL) ? "NULL" : str);
2272 return BAD_VALUE;
2273}
2274
2275status_t QualcommCameraHardware::setFlash(const CameraParameters& params)
2276{
2277 if (!mSensorInfo.flash_enabled) {
2278 LOGV("%s: flash not supported", __FUNCTION__);
2279 return NO_ERROR;
2280 }
2281
2282 const char *str = params.get(CameraParameters::KEY_FLASH_MODE);
2283 if (str != NULL) {
2284 int32_t value = attr_lookup(flash, sizeof(flash) / sizeof(str_map), str);
2285 if (value != NOT_FOUND) {
2286 mParameters.set(CameraParameters::KEY_FLASH_MODE, str);
2287 bool ret = native_set_parm(CAMERA_SET_PARM_LED_MODE,
2288 sizeof(value), (void *)&value);
2289 return ret ? NO_ERROR : UNKNOWN_ERROR;
2290 }
2291 }
2292 LOGE("Invalid flash mode value: %s", (str == NULL) ? "NULL" : str);
2293 return BAD_VALUE;
2294}
2295
2296status_t QualcommCameraHardware::setAntibanding(const CameraParameters& params)
2297{
2298 const char *str = params.get(CameraParameters::KEY_ANTIBANDING);
2299 if (str != NULL) {
2300 int value = (camera_antibanding_type)attr_lookup(
2301 antibanding, sizeof(antibanding) / sizeof(str_map), str);
2302 if (value != NOT_FOUND) {
2303 camera_antibanding_type temp = (camera_antibanding_type) value;
2304 // We don't have auto antibanding now, and simply set the frequency by country.
2305 if (temp == CAMERA_ANTIBANDING_AUTO) {
2306 temp = camera_get_location();
2307 }
2308 mParameters.set(CameraParameters::KEY_ANTIBANDING, str);
2309 native_set_parm(CAMERA_SET_PARM_ANTIBANDING, sizeof(camera_antibanding_type), (void *)&temp);
2310 return NO_ERROR;
2311 }
2312 }
2313 LOGE("Invalid antibanding value: %s", (str == NULL) ? "NULL" : str);
2314 return BAD_VALUE;
2315}
2316
Nishant Panditc8c1ee72009-12-03 16:24:02 +05302317status_t QualcommCameraHardware::setLensshadeValue(const CameraParameters& params)
2318{
2319 const char *str = params.get(CameraParameters::KEY_LENSSHADE);
2320 if (str != NULL) {
2321 int value = attr_lookup(lensshade,
2322 sizeof(lensshade) / sizeof(str_map), str);
2323 if (value != NOT_FOUND) {
2324 int8_t temp = (int8_t)value;
2325 mParameters.set(CameraParameters::KEY_LENSSHADE, str);
2326 native_set_parm(CAMERA_SET_PARM_ROLLOFF, sizeof(int8_t), (void *)&temp);
2327 return NO_ERROR;
2328 }
2329 }
2330 LOGE("Invalid lensShade value: %s", (str == NULL) ? "NULL" : str);
2331 return BAD_VALUE;
2332}
2333
2334status_t QualcommCameraHardware::setISOValue(const CameraParameters& params) {
2335 const char *str = params.get(CameraParameters::KEY_ISO_MODE);
2336 if (str != NULL) {
2337 int value = (camera_iso_mode_type)attr_lookup(
2338 iso, sizeof(iso) / sizeof(str_map), str);
2339 if (value != NOT_FOUND) {
2340 camera_iso_mode_type temp = (camera_iso_mode_type) value;
2341 mParameters.set(CameraParameters::KEY_ISO_MODE, str);
2342 native_set_parm(CAMERA_SET_PARM_ISO, sizeof(camera_iso_mode_type), (void *)&temp);
2343 return NO_ERROR;
2344 }
2345 }
2346 LOGE("Invalid Iso value: %s", (str == NULL) ? "NULL" : str);
2347 return BAD_VALUE;
2348}
2349
2350
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002351status_t QualcommCameraHardware::setGpsLocation(const CameraParameters& params)
2352{
2353 const char *latitude = params.get(CameraParameters::KEY_GPS_LATITUDE);
2354 if (latitude) {
2355 mParameters.set(CameraParameters::KEY_GPS_LATITUDE, latitude);
2356 }
2357
2358 const char *longitude = params.get(CameraParameters::KEY_GPS_LONGITUDE);
2359 if (longitude) {
2360 mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, longitude);
2361 }
2362
2363 const char *altitude = params.get(CameraParameters::KEY_GPS_ALTITUDE);
2364 if (altitude) {
2365 mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, altitude);
2366 }
2367
2368 const char *timestamp = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
2369 if (timestamp) {
2370 mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, timestamp);
2371 }
2372 return NO_ERROR;
2373}
2374
2375status_t QualcommCameraHardware::setRotation(const CameraParameters& params)
2376{
2377 status_t rc = NO_ERROR;
2378 int rotation = params.getInt(CameraParameters::KEY_ROTATION);
2379 if (rotation != NOT_FOUND) {
2380 if (rotation == 0 || rotation == 90 || rotation == 180
2381 || rotation == 270) {
2382 mParameters.set(CameraParameters::KEY_ROTATION, rotation);
2383 } else {
2384 LOGE("Invalid rotation value: %d", rotation);
2385 rc = BAD_VALUE;
2386 }
2387 }
2388 return rc;
2389}
2390
2391status_t QualcommCameraHardware::setZoom(const CameraParameters& params)
2392{
2393 status_t rc = NO_ERROR;
2394 // No matter how many different zoom values the driver can provide, HAL
2395 // provides applictations the same number of zoom levels. The maximum driver
2396 // zoom value depends on sensor output (VFE input) and preview size (VFE
2397 // output) because VFE can only crop and cannot upscale. If the preview size
2398 // is bigger, the maximum zoom ratio is smaller. However, we want the
2399 // zoom ratio of each zoom level is always the same whatever the preview
2400 // size is. Ex: zoom level 1 is always 1.2x, zoom level 2 is 1.44x, etc. So,
2401 // we need to have a fixed maximum zoom value and do read it from the
2402 // driver.
2403 static const int ZOOM_STEP = 6;
2404 int32_t zoom_level = params.getInt("zoom");
2405
2406 LOGI("Set zoom=%d", zoom_level);
2407 if(zoom_level >= 0 && zoom_level <= MAX_ZOOM_LEVEL) {
2408 mParameters.set("zoom", zoom_level);
2409 int32_t zoom_value = ZOOM_STEP * zoom_level;
2410 bool ret = native_set_parm(CAMERA_SET_PARM_ZOOM,
2411 sizeof(zoom_value), (void *)&zoom_value);
2412 rc = ret ? NO_ERROR : UNKNOWN_ERROR;
2413 } else {
2414 rc = BAD_VALUE;
2415 }
2416
2417 return rc;
2418}
2419
2420status_t QualcommCameraHardware::setFocusMode(const CameraParameters& params)
2421{
2422 const char *str = params.get(CameraParameters::KEY_FOCUS_MODE);
2423 if (str != NULL) {
2424 int32_t value = attr_lookup(focus_modes,
2425 sizeof(focus_modes) / sizeof(str_map), str);
2426 if (value != NOT_FOUND) {
2427 mParameters.set(CameraParameters::KEY_FOCUS_MODE, str);
2428 // Focus step is reset to infinity when preview is started. We do
2429 // not need to do anything now.
2430 return NO_ERROR;
2431 }
2432 }
2433 LOGE("Invalid focus mode value: %s", (str == NULL) ? "NULL" : str);
2434 return BAD_VALUE;
2435}
2436
2437status_t QualcommCameraHardware::setOrientation(const CameraParameters& params)
2438{
2439 const char *str = params.get("orientation");
2440
2441 if (str != NULL) {
2442 if (strcmp(str, "portrait") == 0 || strcmp(str, "landscape") == 0) {
2443 // Camera service needs this to decide if the preview frames and raw
2444 // pictures should be rotated.
2445 mParameters.set("orientation", str);
2446 } else {
2447 LOGE("Invalid orientation value: %s", str);
2448 return BAD_VALUE;
2449 }
2450 }
2451 return NO_ERROR;
2452}
2453
2454QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
2455 int frame_size,
2456 const char *name) :
2457 mBufferSize(buffer_size),
2458 mNumBuffers(num_buffers),
2459 mFrameSize(frame_size),
2460 mBuffers(NULL), mName(name)
2461{
2462 int page_size_minus_1 = getpagesize() - 1;
2463 mAlignedBufferSize = (buffer_size + page_size_minus_1) & (~page_size_minus_1);
2464}
2465
2466void QualcommCameraHardware::MemPool::completeInitialization()
2467{
2468 // If we do not know how big the frame will be, we wait to allocate
2469 // the buffers describing the individual frames until we do know their
2470 // size.
2471
2472 if (mFrameSize > 0) {
2473 mBuffers = new sp<MemoryBase>[mNumBuffers];
2474 for (int i = 0; i < mNumBuffers; i++) {
2475 mBuffers[i] = new
2476 MemoryBase(mHeap,
2477 i * mAlignedBufferSize,
2478 mFrameSize);
2479 }
2480 }
2481}
2482
2483QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
2484 int frame_size,
2485 const char *name) :
2486 QualcommCameraHardware::MemPool(buffer_size,
2487 num_buffers,
2488 frame_size,
2489 name)
2490{
2491 LOGV("constructing MemPool %s backed by ashmem: "
2492 "%d frames @ %d uint8_ts, "
2493 "buffer size %d",
2494 mName,
2495 num_buffers, frame_size, buffer_size);
2496
2497 int page_mask = getpagesize() - 1;
2498 int ashmem_size = buffer_size * num_buffers;
2499 ashmem_size += page_mask;
2500 ashmem_size &= ~page_mask;
2501
2502 mHeap = new MemoryHeapBase(ashmem_size);
2503
2504 completeInitialization();
2505}
2506
2507static bool register_buf(int camfd,
2508 int size,
2509 int pmempreviewfd,
2510 uint32_t offset,
2511 uint8_t *buf,
2512 int pmem_type,
2513 bool vfe_can_write,
2514 bool register_buffer = true);
2515
2516QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
2517 int flags,
2518 int camera_control_fd,
2519 int pmem_type,
2520 int buffer_size, int num_buffers,
2521 int frame_size,
2522 const char *name) :
2523 QualcommCameraHardware::MemPool(buffer_size,
2524 num_buffers,
2525 frame_size,
2526 name),
2527 mPmemType(pmem_type),
2528 mCameraControlFd(dup(camera_control_fd))
2529{
2530 LOGV("constructing MemPool %s backed by pmem pool %s: "
2531 "%d frames @ %d bytes, buffer size %d",
2532 mName,
2533 pmem_pool, num_buffers, frame_size,
2534 buffer_size);
2535
2536 LOGV("%s: duplicating control fd %d --> %d",
2537 __FUNCTION__,
2538 camera_control_fd, mCameraControlFd);
2539
2540 // Make a new mmap'ed heap that can be shared across processes.
2541 // mAlignedBufferSize is already in 4k aligned. (do we need total size necessary to be in power of 2??)
2542 mAlignedSize = mAlignedBufferSize * num_buffers;
2543
2544 sp<MemoryHeapBase> masterHeap =
2545 new MemoryHeapBase(pmem_pool, mAlignedSize, flags);
2546
2547 if (masterHeap->getHeapID() < 0) {
2548 LOGE("failed to construct master heap for pmem pool %s", pmem_pool);
2549 masterHeap.clear();
2550 return;
2551 }
2552
2553 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
2554 if (pmemHeap->getHeapID() >= 0) {
2555 pmemHeap->slap();
2556 masterHeap.clear();
2557 mHeap = pmemHeap;
2558 pmemHeap.clear();
2559
2560 mFd = mHeap->getHeapID();
2561 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
2562 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
2563 pmem_pool,
2564 ::strerror(errno), errno);
2565 mHeap.clear();
2566 return;
2567 }
2568
2569 LOGV("pmem pool %s ioctl(fd = %d, PMEM_GET_SIZE) is %ld",
2570 pmem_pool,
2571 mFd,
2572 mSize.len);
2573 LOGD("mBufferSize=%d, mAlignedBufferSize=%d\n", mBufferSize, mAlignedBufferSize);
2574 // Unregister preview buffers with the camera drivers. Allow the VFE to write
2575 // to all preview buffers except for the last one.
2576 for (int cnt = 0; cnt < num_buffers; ++cnt) {
2577 register_buf(mCameraControlFd,
2578 mBufferSize,
2579 mHeap->getHeapID(),
2580 mAlignedBufferSize * cnt,
2581 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
2582 pmem_type,
2583 !(cnt == num_buffers - 1 && pmem_type == MSM_PMEM_OUTPUT2));
2584 }
2585
2586 completeInitialization();
2587 }
2588 else LOGE("pmem pool %s error: could not create master heap!",
2589 pmem_pool);
2590}
2591
2592QualcommCameraHardware::PmemPool::~PmemPool()
2593{
2594 LOGV("%s: %s E", __FUNCTION__, mName);
2595 if (mHeap != NULL) {
2596 // Unregister preview buffers with the camera drivers.
2597 for (int cnt = 0; cnt < mNumBuffers; ++cnt) {
2598 register_buf(mCameraControlFd,
2599 mBufferSize,
2600 mHeap->getHeapID(),
2601 mAlignedBufferSize * cnt,
2602 (uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
2603 mPmemType,
2604 false,
2605 false /* unregister */);
2606 }
2607 }
2608 LOGV("destroying PmemPool %s: closing control fd %d",
2609 mName,
2610 mCameraControlFd);
2611 close(mCameraControlFd);
2612 LOGV("%s: %s X", __FUNCTION__, mName);
2613}
2614
2615QualcommCameraHardware::MemPool::~MemPool()
2616{
2617 LOGV("destroying MemPool %s", mName);
2618 if (mFrameSize > 0)
2619 delete [] mBuffers;
2620 mHeap.clear();
2621 LOGV("destroying MemPool %s completed", mName);
2622}
2623
2624static bool register_buf(int camfd,
2625 int size,
2626 int pmempreviewfd,
2627 uint32_t offset,
2628 uint8_t *buf,
2629 int pmem_type,
2630 bool vfe_can_write,
2631 bool register_buffer)
2632{
2633 struct msm_pmem_info pmemBuf;
2634
2635 pmemBuf.type = pmem_type;
2636 pmemBuf.fd = pmempreviewfd;
2637 pmemBuf.offset = offset;
2638 pmemBuf.len = size;
2639 pmemBuf.vaddr = buf;
2640 pmemBuf.y_off = 0;
2641 pmemBuf.cbcr_off = PAD_TO_WORD(size * 2 / 3);
2642 pmemBuf.active = vfe_can_write;
2643
2644 LOGV("register_buf: camfd = %d, reg = %d buffer = %p",
2645 camfd, !register_buffer, buf);
2646 if (ioctl(camfd,
2647 register_buffer ?
2648 MSM_CAM_IOCTL_REGISTER_PMEM :
2649 MSM_CAM_IOCTL_UNREGISTER_PMEM,
2650 &pmemBuf) < 0) {
2651 LOGE("register_buf: MSM_CAM_IOCTL_(UN)REGISTER_PMEM fd %d error %s",
2652 camfd,
2653 strerror(errno));
2654 return false;
2655 }
2656 return true;
2657}
2658
2659status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
2660{
2661 const size_t SIZE = 256;
2662 char buffer[SIZE];
2663 String8 result;
2664 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
2665 result.append(buffer);
2666 if (mName) {
2667 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
2668 result.append(buffer);
2669 }
2670 if (mHeap != 0) {
2671 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
2672 mHeap->getBase(), mHeap->getSize(),
2673 mHeap->getFlags(), mHeap->getDevice());
2674 result.append(buffer);
2675 }
2676 snprintf(buffer, 255,
2677 "buffer size (%d), number of buffers (%d), frame size(%d)",
2678 mBufferSize, mNumBuffers, mFrameSize);
2679 result.append(buffer);
2680 write(fd, result.string(), result.size());
2681 return NO_ERROR;
2682}
2683
2684static void receive_camframe_callback(struct msm_frame *frame)
2685{
2686 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2687 if (obj != 0) {
2688 obj->receivePreviewFrame(frame);
2689 }
2690}
2691
2692static void receive_jpeg_fragment_callback(uint8_t *buff_ptr, uint32_t buff_size)
2693{
2694 LOGV("receive_jpeg_fragment_callback E");
2695 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2696 if (obj != 0) {
2697 obj->receiveJpegPictureFragment(buff_ptr, buff_size);
2698 }
2699 LOGV("receive_jpeg_fragment_callback X");
2700}
2701
2702static void receive_jpeg_callback(jpeg_event_t status)
2703{
2704 LOGV("receive_jpeg_callback E (completion status %d)", status);
2705 if (status == JPEG_EVENT_DONE) {
2706 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2707 if (obj != 0) {
2708 obj->receiveJpegPicture();
2709 }
2710 }
2711 LOGV("receive_jpeg_callback X");
2712}
2713
2714void QualcommCameraHardware::setCallbacks(notify_callback notify_cb,
2715 data_callback data_cb,
2716 data_callback_timestamp data_cb_timestamp,
2717 void* user)
2718{
2719 Mutex::Autolock lock(mLock);
2720 mNotifyCallback = notify_cb;
2721 mDataCallback = data_cb;
2722 mDataCallbackTimestamp = data_cb_timestamp;
2723 mCallbackCookie = user;
2724}
2725
2726void QualcommCameraHardware::enableMsgType(int32_t msgType)
2727{
2728 Mutex::Autolock lock(mLock);
2729 mMsgEnabled |= msgType;
2730}
2731
2732void QualcommCameraHardware::disableMsgType(int32_t msgType)
2733{
2734 Mutex::Autolock lock(mLock);
2735 mMsgEnabled &= ~msgType;
2736}
2737
2738bool QualcommCameraHardware::msgTypeEnabled(int32_t msgType)
2739{
2740 return (mMsgEnabled & msgType);
2741}
2742
Kiran Kumar H N5efb3ff2009-12-07 01:02:44 -08002743bool QualcommCameraHardware::useOverlay(void)
2744{
2745 char value[PROPERTY_VALUE_MAX];
2746 property_get("ro.product.device",value," ");
2747
2748 if(!strcmp(value,"msm7630_surf")) {
2749 /* Only 7x30 supports Overlay */
2750 mUseOverlay = TRUE;
2751 } else
2752 mUseOverlay = FALSE;
2753
2754 LOGV(" Using Overlay : %s ", mUseOverlay ? "YES" : "NO" );
2755 return mUseOverlay;
2756}
2757
2758status_t QualcommCameraHardware::setOverlay(const sp<Overlay> &Overlay)
2759{
2760 if( Overlay != NULL) {
2761 LOGV(" Valid overlay object ");
2762 mOverlayLock.lock();
2763 mOverlay = Overlay;
2764 mOverlayLock.unlock();
2765 } else {
2766 LOGE(" Overlay object NULL. returning ");
2767 return UNKNOWN_ERROR;
2768 }
2769 return NO_ERROR;
2770}
Priya Komarlingamb85535d2009-11-30 13:06:01 -08002771}; // namespace android