1 /*
2 ** Copyright 2008, The Android Open-Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 // TODO
18 // -- replace Condition::wait with Condition::waitRelative
19 // -- use read/write locks
20
21 #define LOG_NDEBUG 0
22 #define LOG_TAG "QualcommCameraHardware"
23 #include <utils/Log.h>
24 #include <utils/threads.h>
25 #include <binder/MemoryHeapPmem.h>
26 #include <utils/String16.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/ioctl.h>
30 #include <sys/mman.h>
31 #include <sys/time.h>
32 #include <time.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #if HAVE_ANDROID_OS
36 #include <linux/android_pmem.h>
37 #endif
38 #include <camera_ifc.h>
39 #if DLOPEN_LIBQCAMERA
40 #include <dlfcn.h>
41 #endif
42
43 #define PRINT_TIME 0
44
45 extern "C" {
46
print_time()47 static inline void print_time()
48 {
49 #if PRINT_TIME
50 struct timeval time;
51 gettimeofday(&time, NULL);
52 ALOGV("time: %lld us.", time.tv_sec * 1000000LL + time.tv_usec);
53 #endif
54 }
55
56 typedef struct {
57 int width;
58 int height;
59 } preview_size_type;
60
61 // These sizes have to be a multiple of 16 in each dimension
62 static preview_size_type preview_sizes[] = {
63 { 480, 320 }, // HVGA
64 { 432, 320 }, // 1.35-to-1, for photos. (Rounded up from 1.3333 to 1)
65 { 352, 288 }, // CIF
66 { 320, 240 }, // QVGA
67 { 240, 160 }, // SQVGA
68 { 176, 144 }, // QCIF
69 };
70 #define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(preview_size_type))
71
72 // default preview size is QVGA
73 #define DEFAULT_PREVIEW_SETTING 0
74
75 #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
76 #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
77
78 /* some functions we need from libqcamera */
79 extern void rex_start();
80 extern void rex_shutdown();
81
82 /* callbacks */
83 #if DLOPEN_LIBQCAMERA == 0
84 extern void (*rex_signal_ready)();
85 extern uint8_t* (*cam_mmap_preview)(uint32_t size,
86 uint32_t *phy_addr,
87 uint32_t index);
88 extern uint8_t* (*cam_mmap_snapshot)(uint32_t size,
89 uint32_t *phy_addr,
90 uint32_t index);
91 extern int (*cam_munmap_preview)(uint32_t *phy_addr,
92 uint32_t size,
93 uint32_t index);
94 extern int (*cam_munmap_snapshot)(uint32_t *phy_addr,
95 uint32_t size,
96 uint32_t index);
97
98 extern clear_module_pmem(qdsp_module_type module);
99
100 extern void camera_assoc_pmem(qdsp_module_type module,
101 int pmem_fd,
102 void *addr,
103 uint32_t length,
104 int external);
105
106 extern int camera_release_pmem(qdsp_module_type module,
107 void *addr,
108 uint32_t size,
109 uint32_t force);
110
111 #define LINK_camera_assoc_pmem camera_assoc_pmem
112 #define LINK_clear_module_pmem clear_module_pmem
113 #define LINK_camera_release_pmem camera_release_pmem
114 #define LINK_camera_encode_picture camera_encode_picture
115 #define LINK_camera_init camera_init
116 #define LINK_camera_af_init camera_af_init
117 #define LINK_camera_release_frame camera_release_frame
118 #define LINK_camera_set_dimensions camera_set_dimensions
119 #define LINK_camera_set_encode_properties camera_set_encode_properties
120 #define LINK_camera_set_parm camera_set_parm
121 #define LINK_camera_set_parm_2 camera_set_parm_2
122 #define LINK_camera_set_position camera_set_position
123 #define LINK_camera_set_thumbnail_properties camera_set_thumbnail_properties
124 #define LINK_camera_start camera_start
125 #define LINK_camera_start_preview camera_start_preview
126 #define LINK_camera_start_focus camera_start_focus
127 #define LINK_camera_stop_focus camera_stop_focus
128 #define LINK_camera_stop camera_stop
129 #define LINK_camera_stop_preview camera_stop_preview
130 #define LINK_camera_take_picture camera_take_picture
131 #define LINK_rex_shutdown rex_shutdown
132 #define LINK_rex_start rex_start
133 #define LINK_rex_signal_ready rex_signal_ready
134
135 #define LINK_cam_mmap_preview cam_mmap_preview
136 #define LINK_cam_munmap_preview cam_munmap_preview
137 #define LINK_cam_mmap_snapshot cam_mmap_snapshot
138 #define LINK_cam_munmap_snapshot cam_munmap_snapshot
139
140 #else
141
142 /* Function pointers to assign to */
143
144 void (**LINK_rex_signal_ready)();
145
146 uint8_t* (**LINK_cam_mmap_preview)(
147 uint32_t size,
148 uint32_t *phy_addr,
149 uint32_t index);
150
151 int (**LINK_cam_munmap_preview)(
152 uint32_t *phy_addr,
153 uint32_t size,
154 uint32_t index);
155
156 uint8_t* (**LINK_cam_mmap_snapshot)(
157 uint32_t size,
158 uint32_t *phy_addr,
159 uint32_t index);
160
161 int (**LINK_cam_munmap_snapshot)(
162 uint32_t *phy_addr,
163 uint32_t size,
164 uint32_t index);
165
166 /* Function pointers to resolve */
167
168 void (*LINK_camera_assoc_pmem)(qdsp_module_type module,
169 int pmem_fd,
170 void *addr,
171 uint32_t length,
172 int external);
173
174 void (*LINK_clear_module_pmem)(qdsp_module_type module);
175
176 int (*LINK_camera_release_pmem)(qdsp_module_type module,
177 void *addr,
178 uint32_t size,
179 uint32_t force);
180
181 camera_ret_code_type (*LINK_camera_encode_picture) (
182 camera_frame_type *frame,
183 camera_handle_type *handle,
184 camera_cb_f_type callback,
185 void *client_data);
186
187 void (*LINK_camera_init)(void);
188
189 void (*LINK_camera_af_init)(void);
190
191 camera_ret_code_type (*LINK_camera_release_frame)(void);
192
193 camera_ret_code_type (*LINK_camera_set_dimensions) (
194 uint16_t picture_width,
195 uint16_t picture_height,
196 uint16_t display_width,
197 #ifdef FEATURE_CAMERA_V7
198 uint16_t display_height,
199 #endif
200 camera_cb_f_type callback,
201 void *client_data);
202
203 camera_ret_code_type (*LINK_camera_set_encode_properties)(
204 camera_encode_properties_type *encode_properties);
205
206 camera_ret_code_type (*LINK_camera_set_parm) (
207 camera_parm_type id,
208 int32_t parm,
209 camera_cb_f_type callback,
210 void *client_data);
211
212 camera_ret_code_type (*LINK_camera_set_parm_2) (
213 camera_parm_type id,
214 int32_t parm1,
215 int32_t parm2,
216 camera_cb_f_type callback,
217 void *client_data);
218
219 camera_ret_code_type (*LINK_camera_set_position) (
220 camera_position_type *position,
221 camera_cb_f_type callback,
222 void *client_data);
223
224 camera_ret_code_type (*LINK_camera_set_thumbnail_properties) (
225 uint32_t width,
226 uint32_t height,
227 uint32_t quality);
228
229 camera_ret_code_type (*LINK_camera_start) (
230 camera_cb_f_type callback,
231 void *client_data
232 #ifdef FEATURE_NATIVELINUX
233 ,int display_height,
234 int display_width
235 #endif /* FEATURE_NATIVELINUX */
236 );
237
238 camera_ret_code_type (*LINK_camera_start_preview) (
239 camera_cb_f_type callback,
240 void *client_data);
241
242 camera_ret_code_type (*LINK_camera_start_focus) (
243 camera_focus_e_type focus,
244 camera_cb_f_type callback,
245 void *client_data);
246
247 camera_ret_code_type (*LINK_camera_stop_focus) (void);
248
249 camera_ret_code_type (*LINK_camera_stop) (
250 camera_cb_f_type callback,
251 void *client_data);
252
253 camera_ret_code_type (*LINK_camera_stop_preview) (void);
254
255 camera_ret_code_type (*LINK_camera_take_picture) (
256 camera_cb_f_type callback,
257 void *client_data
258 #if !defined FEATURE_CAMERA_ENCODE_PROPERTIES && defined FEATURE_CAMERA_V7
259 ,camera_raw_type camera_raw_mode
260 #endif /* nFEATURE_CAMERA_ENCODE_PROPERTIES && FEATURE_CAMERA_V7 */
261 );
262
263 int (*LINK_rex_start)(void);
264
265 int (*LINK_rex_shutdown)(void);
266
267 #endif
268
269 }
270
271 #include "QualcommCameraHardware.h"
272
273 namespace android {
274
275 static Mutex singleton_lock;
276 static Mutex rex_init_lock;
277 static Condition rex_init_wait;
278
279 static uint8_t* malloc_preview(uint32_t, uint32_t *, uint32_t);
280 static uint8_t* malloc_raw(uint32_t, uint32_t *, uint32_t);
281 static int free_preview(uint32_t *, uint32_t , uint32_t);
282 static int free_raw(uint32_t *, uint32_t , uint32_t);
283 static int reassoc(qdsp_module_type module);
284 static void cb_rex_signal_ready(void);
285
QualcommCameraHardware()286 QualcommCameraHardware::QualcommCameraHardware()
287 : mParameters(),
288 mPreviewHeight(-1),
289 mPreviewWidth(-1),
290 mRawHeight(-1),
291 mRawWidth(-1),
292 mCameraState(QCS_INIT),
293 mShutterCallback(0),
294 mRawPictureCallback(0),
295 mJpegPictureCallback(0),
296 mPictureCallbackCookie(0),
297 mAutoFocusCallback(0),
298 mAutoFocusCallbackCookie(0),
299 mPreviewCallback(0),
300 mPreviewCallbackCookie(0),
301 mRecordingCallback(0),
302 mRecordingCallbackCookie(0),
303 mPreviewFrameSize(0),
304 mRawSize(0),
305 mPreviewCount(0)
306 {
307 ALOGV("constructor EX");
308 }
309
initDefaultParameters()310 void QualcommCameraHardware::initDefaultParameters()
311 {
312 CameraParameters p;
313
314 preview_size_type* ps = &preview_sizes[DEFAULT_PREVIEW_SETTING];
315 p.setPreviewSize(ps->width, ps->height);
316 p.setPreviewFrameRate(15);
317 p.setPreviewFormat("yuv420sp");
318 p.setPictureFormat("jpeg"); // we do not look at this currently
319 p.setPictureSize(2048, 1536);
320 p.set("jpeg-quality", "100"); // maximum quality
321
322 // These values must be multiples of 16, so we can't do 427x320, which is the exact size on
323 // screen we want to display at. 480x360 doesn't work either since it's a multiple of 8.
324 p.set("jpeg-thumbnail-width", "512");
325 p.set("jpeg-thumbnail-height", "384");
326 p.set("jpeg-thumbnail-quality", "90");
327
328 p.set("nightshot-mode", "0"); // off
329 p.set("luma-adaptation", "0"); // FIXME: turning it on causes a crash
330 p.set("antibanding", "auto"); // flicker detection and elimination
331 p.set("whitebalance", "auto");
332 p.set("rotation", "0");
333
334 #if 0
335 p.set("gps-timestamp", "1199145600"); // Jan 1, 2008, 00:00:00
336 p.set("gps-latitude", "37.736071"); // A little house in San Francisco
337 p.set("gps-longitude", "-122.441983");
338 p.set("gps-altitude", "21"); // meters
339 #endif
340
341 // List supported picture size values
342 p.set("picture-size-values", "2048x1536,1600x1200,1024x768");
343
344 // List supported antibanding values
345 p.set("antibanding-values",
346 "off,50hz,60hz,auto");
347
348 // List supported effects:
349 p.set("effect-values",
350 "off,mono,negative,solarize,sepia,posterize,whiteboard,"\
351 "blackboard,aqua");
352
353 // List supported exposure-offset:
354 p.set("exposure-offset-values",
355 "0,1,2,3,4,5,6,7,8,9,10");
356
357 // List of whitebalance values
358 p.set("whitebalance-values",
359 "auto,incandescent,fluorescent,daylight,cloudy");
360
361 // List of ISO values
362 p.set("iso-values", "auto,high");
363
364 if (setParameters(p) != NO_ERROR) {
365 ALOGE("Failed to set default parameters?!");
366 }
367 }
368
369 #define ROUND_TO_PAGE(x) (((x)+0xfff)&~0xfff)
370
371 // Called with mStateLock held!
startCameraIfNecessary()372 void QualcommCameraHardware::startCameraIfNecessary()
373 {
374 if (mCameraState == QCS_INIT) {
375
376 #if DLOPEN_LIBQCAMERA == 1
377
378 ALOGV("loading libqcamera");
379 libqcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
380 if (!libqcamera) {
381 ALOGE("FATAL ERROR: could not dlopen liboemcamera.so: %s", dlerror());
382 return;
383 }
384
385 *(void **)&LINK_camera_assoc_pmem =
386 ::dlsym(libqcamera, "camera_assoc_pmem");
387 *(void **)&LINK_clear_module_pmem =
388 ::dlsym(libqcamera, "clear_module_pmem");
389 *(void **)&LINK_camera_release_pmem =
390 ::dlsym(libqcamera, "camera_release_pmem");
391 *(void **)&LINK_camera_encode_picture =
392 ::dlsym(libqcamera, "camera_encode_picture");
393 *(void **)&LINK_camera_init =
394 ::dlsym(libqcamera, "camera_init");
395 *(void **)&LINK_camera_af_init =
396 ::dlsym(libqcamera, "camera_af_init");
397 *(void **)&LINK_camera_release_frame =
398 ::dlsym(libqcamera, "camera_release_frame");
399 *(void **)&LINK_camera_set_dimensions =
400 ::dlsym(libqcamera, "camera_set_dimensions");
401 *(void **)&LINK_camera_set_encode_properties =
402 ::dlsym(libqcamera, "camera_set_encode_properties");
403 *(void **)&LINK_camera_set_parm =
404 ::dlsym(libqcamera, "camera_set_parm");
405 *(void **)&LINK_camera_set_parm_2 =
406 ::dlsym(libqcamera, "camera_set_parm_2");
407 *(void **)&LINK_camera_set_position =
408 ::dlsym(libqcamera, "camera_set_position");
409 *(void **)&LINK_camera_set_thumbnail_properties =
410 ::dlsym(libqcamera, "camera_set_thumbnail_properties");
411 *(void **)&LINK_camera_start =
412 ::dlsym(libqcamera, "camera_start");
413 *(void **)&LINK_camera_start_preview =
414 ::dlsym(libqcamera, "camera_start_preview");
415 *(void **)&LINK_camera_start_focus =
416 ::dlsym(libqcamera, "camera_start_focus");
417 *(void **)&LINK_camera_stop_focus =
418 ::dlsym(libqcamera, "camera_stop_focus");
419 *(void **)&LINK_camera_stop =
420 ::dlsym(libqcamera, "camera_stop");
421 *(void **)&LINK_camera_stop_preview =
422 ::dlsym(libqcamera, "camera_stop_preview");
423 *(void **)&LINK_camera_take_picture =
424 ::dlsym(libqcamera, "camera_take_picture");
425 *(void **)&LINK_rex_shutdown =
426 ::dlsym(libqcamera, "rex_shutdown");
427 *(void **)&LINK_rex_start =
428 ::dlsym(libqcamera, "rex_start");
429 *(void **)&LINK_rex_signal_ready =
430 ::dlsym(libqcamera, "rex_signal_ready");
431 *(void **)&LINK_cam_mmap_preview =
432 ::dlsym(libqcamera, "cam_mmap_preview");
433 *(void **)&LINK_cam_munmap_preview =
434 ::dlsym(libqcamera, "cam_munmap_preview");
435 *(void **)&LINK_cam_mmap_snapshot =
436 ::dlsym(libqcamera, "cam_mmap_snapshot");
437 *(void **)&LINK_cam_munmap_snapshot =
438 ::dlsym(libqcamera, "cam_munmap_snapshot");
439
440 *LINK_rex_signal_ready = cb_rex_signal_ready;
441 *LINK_cam_mmap_preview = malloc_preview;
442 *LINK_cam_munmap_preview = free_preview;
443 *LINK_cam_mmap_snapshot = malloc_raw;
444 *LINK_cam_munmap_snapshot = free_raw;
445 #else
446 LINK_rex_signal_ready = cb_rex_signal_ready;
447 LINK_cam_mmap_preview = malloc_preview;
448 LINK_cam_munmap_preview = free_preview;
449 LINK_cam_mmap_snapshot = malloc_raw;
450 LINK_cam_munmap_snapshot = free_raw;
451 #endif // DLOPEN_LIBQCAMERA == 1
452
453 rex_init_lock.lock();
454 LINK_rex_start();
455 ALOGV("waiting for REX to initialize.");
456 rex_init_wait.wait(rex_init_lock);
457 ALOGV("REX is ready.");
458 rex_init_lock.unlock();
459
460 LINK_camera_init();
461
462 ALOGV("starting REX emulation");
463 // NOTE: camera_start() takes (height, width), not (width, height).
464 LINK_camera_start(camera_cb, this,
465 mPreviewHeight, mPreviewWidth);
466 while(mCameraState != QCS_IDLE &&
467 mCameraState != QCS_ERROR) {
468 ALOGV("init camera: waiting for QCS_IDLE");
469 mStateWait.wait(mStateLock);
470 ALOGV("init camera: woke up");
471 }
472 ALOGV("init camera: initializing parameters");
473 }
474 else ALOGV("camera hardware has been started already");
475 }
476
dump(int fd,const Vector<String16> & args) const477 status_t QualcommCameraHardware::dump(int fd, const Vector<String16>& args) const
478 {
479 const size_t SIZE = 256;
480 char buffer[SIZE];
481 String8 result;
482
483 // Dump internal primitives.
484 snprintf(buffer, 255, "QualcommCameraHardware::dump: state (%d)\n", mCameraState);
485 result.append(buffer);
486 snprintf(buffer, 255, "preview width(%d) x height (%d)\n", mPreviewWidth, mPreviewHeight);
487 result.append(buffer);
488 snprintf(buffer, 255, "raw width(%d) x height (%d)\n", mRawWidth, mRawHeight);
489 result.append(buffer);
490 snprintf(buffer, 255, "preview frame size(%d), raw size (%d), jpeg size (%d) and jpeg max size (%d)\n", mPreviewFrameSize, mRawSize, mJpegSize, mJpegMaxSize);
491 result.append(buffer);
492 write(fd, result.string(), result.size());
493
494 // Dump internal objects.
495 if (mPreviewHeap != 0) {
496 mPreviewHeap->dump(fd, args);
497 }
498 if (mRawHeap != 0) {
499 mRawHeap->dump(fd, args);
500 }
501 if (mJpegHeap != 0) {
502 mJpegHeap->dump(fd, args);
503 }
504 mParameters.dump(fd, args);
505 return NO_ERROR;
506 }
507
initPreview()508 bool QualcommCameraHardware::initPreview()
509 {
510 // LINK_clear_module_pmem(QDSP_MODULE_VFETASK);
511
512 startCameraIfNecessary();
513
514 // Tell libqcamera what the preview and raw dimensions are. We
515 // call this method even if the preview dimensions have not changed,
516 // because the picture ones may have.
517 //
518 // NOTE: if this errors out, mCameraState != QCS_IDLE, which will be
519 // checked by the caller of this method.
520
521 setCameraDimensions();
522
523 ALOGV("initPreview: preview size=%dx%d", mPreviewWidth, mPreviewHeight);
524
525 mPreviewFrameSize = mPreviewWidth * mPreviewHeight * 3 / 2; // reality
526 mPreviewHeap =
527 new PreviewPmemPool(kRawFrameHeaderSize +
528 mPreviewWidth * mPreviewHeight * 2, // worst
529 kPreviewBufferCount,
530 mPreviewFrameSize,
531 kRawFrameHeaderSize,
532 "preview");
533
534 if (!mPreviewHeap->initialized()) {
535 mPreviewHeap = NULL;
536 return false;
537 }
538
539 // LINK_camera_af_init();
540
541 return true;
542 }
543
deinitPreview()544 void QualcommCameraHardware::deinitPreview()
545 {
546 mPreviewHeap = NULL;
547 }
548
549 // Called with mStateLock held!
initRaw(bool initJpegHeap)550 bool QualcommCameraHardware::initRaw(bool initJpegHeap)
551 {
552 ALOGV("initRaw E");
553 startCameraIfNecessary();
554
555 // Tell libqcamera what the preview and raw dimensions are. We
556 // call this method even if the preview dimensions have not changed,
557 // because the picture ones may have.
558 //
559 // NOTE: if this errors out, mCameraState != QCS_IDLE, which will be
560 // checked by the caller of this method.
561
562 setCameraDimensions();
563
564 ALOGV("initRaw: picture size=%dx%d",
565 mRawWidth, mRawHeight);
566
567 // Note that we enforce yuv420 in setParameters().
568
569 mRawSize =
570 mRawWidth * mRawHeight * 3 / 2; /* reality */
571
572 mJpegMaxSize = mRawWidth * mRawHeight * 2;
573
574 ALOGV("initRaw: clearing old mJpegHeap.");
575 mJpegHeap = NULL;
576
577 ALOGV("initRaw: initializing mRawHeap.");
578 mRawHeap =
579 new RawPmemPool("/dev/pmem_camera",
580 kRawFrameHeaderSize + mJpegMaxSize, /* worst */
581 kRawBufferCount,
582 mRawSize,
583 kRawFrameHeaderSize,
584 "snapshot camera");
585
586 if (!mRawHeap->initialized()) {
587 ALOGE("initRaw X failed: error initializing mRawHeap");
588 mRawHeap = NULL;
589 return false;
590 }
591
592 if (initJpegHeap) {
593 ALOGV("initRaw: initializing mJpegHeap.");
594 mJpegHeap =
595 new AshmemPool(mJpegMaxSize,
596 kJpegBufferCount,
597 0, // we do not know how big the picture wil be
598 0,
599 "jpeg");
600 if (!mJpegHeap->initialized()) {
601 ALOGE("initRaw X failed: error initializing mJpegHeap.");
602 mJpegHeap = NULL;
603 mRawHeap = NULL;
604 return false;
605 }
606 }
607
608 ALOGV("initRaw X success");
609 return true;
610 }
611
release()612 void QualcommCameraHardware::release()
613 {
614 ALOGV("release E");
615
616 Mutex::Autolock l(&mLock);
617
618 // Either preview was ongoing, or we are in the middle or taking a
619 // picture. It's the caller's responsibility to make sure the camera
620 // is in the idle or init state before destroying this object.
621
622 if (mCameraState != QCS_IDLE && mCameraState != QCS_INIT) {
623 ALOGE("Serious error: the camera state is %s, "
624 "not QCS_IDLE or QCS_INIT!",
625 getCameraStateStr(mCameraState));
626 }
627
628 mStateLock.lock();
629 if (mCameraState != QCS_INIT) {
630 // When libqcamera detects an error, it calls camera_cb from the
631 // call to LINK_camera_stop, which would cause a deadlock if we
632 // held the mStateLock. For this reason, we have an intermediate
633 // state QCS_INTERNAL_STOPPING, which we use to check to see if the
634 // camera_cb was called inline.
635 mCameraState = QCS_INTERNAL_STOPPING;
636 mStateLock.unlock();
637
638 ALOGV("stopping camera.");
639 LINK_camera_stop(stop_camera_cb, this);
640
641 mStateLock.lock();
642 if (mCameraState == QCS_INTERNAL_STOPPING) {
643 while (mCameraState != QCS_INIT &&
644 mCameraState != QCS_ERROR) {
645 ALOGV("stopping camera: waiting for QCS_INIT");
646 mStateWait.wait(mStateLock);
647 }
648 }
649
650 ALOGV("Shutting REX down.");
651 LINK_rex_shutdown();
652 ALOGV("REX has shut down.");
653 #if DLOPEN_LIBQCAMERA
654 if (libqcamera) {
655 unsigned ref = ::dlclose(libqcamera);
656 ALOGV("dlclose(libqcamera) refcount %d", ref);
657 }
658 #endif
659 mCameraState = QCS_INIT;
660 }
661 mStateLock.unlock();
662
663 ALOGV("release X");
664 }
665
~QualcommCameraHardware()666 QualcommCameraHardware::~QualcommCameraHardware()
667 {
668 ALOGV("~QualcommCameraHardware E");
669 Mutex::Autolock singletonLock(&singleton_lock);
670 singleton.clear();
671 ALOGV("~QualcommCameraHardware X");
672 }
673
getPreviewHeap() const674 sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
675 {
676 ALOGV("getPreviewHeap");
677 return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
678 }
679
getRawHeap() const680 sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
681 {
682 return mRawHeap != NULL ? mRawHeap->mHeap : NULL;
683 }
684
setCallbacks(preview_callback pcb,void * puser,recording_callback rcb,void * ruser)685 bool QualcommCameraHardware::setCallbacks(
686 preview_callback pcb, void *puser,
687 recording_callback rcb, void *ruser)
688 {
689 Mutex::Autolock cbLock(&mCallbackLock);
690 mPreviewCallback = pcb;
691 mPreviewCallbackCookie = puser;
692 mRecordingCallback = rcb;
693 mRecordingCallbackCookie = ruser;
694 return mPreviewCallback != NULL ||
695 mRecordingCallback != NULL;
696 }
697
startPreviewInternal(preview_callback pcb,void * puser,recording_callback rcb,void * ruser)698 status_t QualcommCameraHardware::startPreviewInternal(
699 preview_callback pcb, void *puser,
700 recording_callback rcb, void *ruser)
701 {
702 ALOGV("startPreview E");
703
704 if (mCameraState == QCS_PREVIEW_IN_PROGRESS) {
705 ALOGE("startPreview is already in progress, doing nothing.");
706 // We might want to change the callback functions while preview is
707 // streaming, for example to enable or disable recording.
708 setCallbacks(pcb, puser, rcb, ruser);
709 return NO_ERROR;
710 }
711
712 // We check for these two states explicitly because it is possible
713 // for startPreview() to be called in response to a raw or JPEG
714 // callback, but before we've updated the state from QCS_WAITING_RAW
715 // or QCS_WAITING_JPEG to QCS_IDLE. This is because in camera_cb(),
716 // we update the state *after* we've made the callback. See that
717 // function for an explanation.
718
719 if (mCameraState == QCS_WAITING_RAW ||
720 mCameraState == QCS_WAITING_JPEG) {
721 while (mCameraState != QCS_IDLE &&
722 mCameraState != QCS_ERROR) {
723 ALOGV("waiting for QCS_IDLE");
724 mStateWait.wait(mStateLock);
725 }
726 }
727
728 if (mCameraState != QCS_IDLE) {
729 ALOGE("startPreview X Camera state is %s, expecting QCS_IDLE!",
730 getCameraStateStr(mCameraState));
731 return INVALID_OPERATION;
732 }
733
734 if (!initPreview()) {
735 ALOGE("startPreview X initPreview failed. Not starting preview.");
736 return UNKNOWN_ERROR;
737 }
738
739 setCallbacks(pcb, puser, rcb, ruser);
740
741 // hack to prevent first preview frame from being black
742 mPreviewCount = 0;
743
744 mCameraState = QCS_INTERNAL_PREVIEW_REQUESTED;
745 camera_ret_code_type qret =
746 LINK_camera_start_preview(camera_cb, this);
747 if (qret == CAMERA_SUCCESS) {
748 while(mCameraState != QCS_PREVIEW_IN_PROGRESS &&
749 mCameraState != QCS_ERROR) {
750 ALOGV("waiting for QCS_PREVIEW_IN_PROGRESS");
751 mStateWait.wait(mStateLock);
752 }
753 }
754 else {
755 ALOGE("startPreview failed: sensor error.");
756 mCameraState = QCS_ERROR;
757 }
758
759 ALOGV("startPreview X");
760 return mCameraState == QCS_PREVIEW_IN_PROGRESS ?
761 NO_ERROR : UNKNOWN_ERROR;
762 }
763
stopPreviewInternal()764 void QualcommCameraHardware::stopPreviewInternal()
765 {
766 ALOGV("stopPreviewInternal E");
767
768 if (mCameraState != QCS_PREVIEW_IN_PROGRESS) {
769 ALOGE("Preview not in progress!");
770 return;
771 }
772
773 if (mAutoFocusCallback != NULL) {
774 // WARNING: clear mAutoFocusCallback BEFORE you call
775 // camera_stop_focus. The CAMERA_EXIT_CB_ABORT is (erroneously)
776 // delivered inline camera_stop_focus(), and we cannot acquire
777 // mStateLock, because that would cause a deadlock. In any case,
778 // CAMERA_EXIT_CB_ABORT is delivered only when we call
779 // camera_stop_focus.
780 mAutoFocusCallback = NULL;
781 LINK_camera_stop_focus();
782 }
783
784 setCallbacks(NULL, NULL, NULL, NULL);
785
786 mCameraState = QCS_INTERNAL_PREVIEW_STOPPING;
787
788 LINK_camera_stop_preview();
789 while (mCameraState != QCS_IDLE &&
790 mCameraState != QCS_ERROR) {
791 ALOGV("waiting for QCS_IDLE");
792 mStateWait.wait(mStateLock);
793 }
794
795 ALOGV("stopPreviewInternal: Freeing preview heap.");
796 mPreviewHeap = NULL;
797 mPreviewCallback = NULL;
798
799 ALOGV("stopPreviewInternal: X Preview has stopped.");
800 }
801
startPreview(preview_callback pcb,void * puser)802 status_t QualcommCameraHardware::startPreview(
803 preview_callback pcb, void *puser)
804 {
805 Mutex::Autolock l(&mLock);
806 Mutex::Autolock stateLock(&mStateLock);
807 return startPreviewInternal(pcb, puser,
808 mRecordingCallback,
809 mRecordingCallbackCookie);
810 }
811
stopPreview()812 void QualcommCameraHardware::stopPreview() {
813 ALOGV("stopPreview: E");
814 Mutex::Autolock l(&mLock);
815 if (!setCallbacks(NULL, NULL,
816 mRecordingCallback,
817 mRecordingCallbackCookie)) {
818 Mutex::Autolock statelock(&mStateLock);
819 stopPreviewInternal();
820 }
821 ALOGV("stopPreview: X");
822 }
823
previewEnabled()824 bool QualcommCameraHardware::previewEnabled() {
825 Mutex::Autolock l(&mLock);
826 return mCameraState == QCS_PREVIEW_IN_PROGRESS;
827 }
828
startRecording(recording_callback rcb,void * ruser)829 status_t QualcommCameraHardware::startRecording(
830 recording_callback rcb, void *ruser)
831 {
832 Mutex::Autolock l(&mLock);
833 Mutex::Autolock stateLock(&mStateLock);
834 return startPreviewInternal(mPreviewCallback,
835 mPreviewCallbackCookie,
836 rcb, ruser);
837 }
838
stopRecording()839 void QualcommCameraHardware::stopRecording() {
840 ALOGV("stopRecording: E");
841 Mutex::Autolock l(&mLock);
842 if (!setCallbacks(mPreviewCallback,
843 mPreviewCallbackCookie,
844 NULL, NULL)) {
845 Mutex::Autolock statelock(&mStateLock);
846 stopPreviewInternal();
847 }
848 ALOGV("stopRecording: X");
849 }
850
recordingEnabled()851 bool QualcommCameraHardware::recordingEnabled() {
852 Mutex::Autolock l(&mLock);
853 Mutex::Autolock stateLock(&mStateLock);
854 return mCameraState == QCS_PREVIEW_IN_PROGRESS &&
855 mRecordingCallback != NULL;
856 }
857
releaseRecordingFrame(const sp<IMemory> & mem)858 void QualcommCameraHardware::releaseRecordingFrame(
859 const sp<IMemory>& mem __attribute__((unused)))
860 {
861 Mutex::Autolock l(&mLock);
862 LINK_camera_release_frame();
863 }
864
autoFocus(autofocus_callback af_cb,void * user)865 status_t QualcommCameraHardware::autoFocus(autofocus_callback af_cb,
866 void *user)
867 {
868 ALOGV("Starting auto focus.");
869 Mutex::Autolock l(&mLock);
870 Mutex::Autolock lock(&mStateLock);
871
872 if (mCameraState != QCS_PREVIEW_IN_PROGRESS) {
873 ALOGE("Invalid camera state %s: expecting QCS_PREVIEW_IN_PROGRESS,"
874 " cannot start autofocus!",
875 getCameraStateStr(mCameraState));
876 return INVALID_OPERATION;
877 }
878
879 if (mAutoFocusCallback != NULL) {
880 ALOGV("Auto focus is already in progress");
881 return mAutoFocusCallback == af_cb ? NO_ERROR : INVALID_OPERATION;
882 }
883
884 mAutoFocusCallback = af_cb;
885 mAutoFocusCallbackCookie = user;
886 LINK_camera_start_focus(CAMERA_AUTO_FOCUS, camera_cb, this);
887 return NO_ERROR;
888 }
889
takePicture(shutter_callback shutter_cb,raw_callback raw_cb,jpeg_callback jpeg_cb,void * user)890 status_t QualcommCameraHardware::takePicture(shutter_callback shutter_cb,
891 raw_callback raw_cb,
892 jpeg_callback jpeg_cb,
893 void* user)
894 {
895 ALOGV("takePicture: E raw_cb = %p, jpeg_cb = %p",
896 raw_cb, jpeg_cb);
897 print_time();
898
899 Mutex::Autolock l(&mLock);
900 Mutex::Autolock stateLock(&mStateLock);
901
902 qualcomm_camera_state last_state = mCameraState;
903 if (mCameraState == QCS_PREVIEW_IN_PROGRESS) {
904 stopPreviewInternal();
905 }
906
907 // We check for these two states explicitly because it is possible
908 // for takePicture() to be called in response to a raw or JPEG
909 // callback, but before we've updated the state from QCS_WAITING_RAW
910 // or QCS_WAITING_JPEG to QCS_IDLE. This is because in camera_cb(),
911 // we update the state *after* we've made the callback. See that
912 // function for an explanation why.
913
914 if (mCameraState == QCS_WAITING_RAW ||
915 mCameraState == QCS_WAITING_JPEG) {
916 while (mCameraState != QCS_IDLE &&
917 mCameraState != QCS_ERROR) {
918 ALOGV("waiting for QCS_IDLE");
919 mStateWait.wait(mStateLock);
920 }
921 }
922
923 if (mCameraState != QCS_IDLE) {
924 ALOGE("takePicture: %sunexpected state %d, expecting QCS_IDLE",
925 (last_state == QCS_PREVIEW_IN_PROGRESS ?
926 "(stop preview) " : ""),
927 mCameraState);
928 // If we had to stop preview in order to take a picture, and
929 // we failed to transition to a QCS_IDLE state, that's because
930 // of an internal error.
931 return last_state == QCS_PREVIEW_IN_PROGRESS ?
932 UNKNOWN_ERROR :
933 INVALID_OPERATION;
934 }
935
936 if (!initRaw(jpeg_cb != NULL)) {
937 ALOGE("initRaw failed. Not taking picture.");
938 return UNKNOWN_ERROR;
939 }
940
941 if (mCameraState != QCS_IDLE) {
942 ALOGE("takePicture: (init raw) "
943 "unexpected state %d, expecting QCS_IDLE",
944 mCameraState);
945 // If we had to stop preview in order to take a picture, and
946 // we failed to transition to a QCS_IDLE state, that's because
947 // of an internal error.
948 return last_state == QCS_PREVIEW_IN_PROGRESS ?
949 UNKNOWN_ERROR :
950 INVALID_OPERATION;
951 }
952
953 {
954 Mutex::Autolock cbLock(&mCallbackLock);
955 mShutterCallback = shutter_cb;
956 mRawPictureCallback = raw_cb;
957 mJpegPictureCallback = jpeg_cb;
958 mPictureCallbackCookie = user;
959 }
960
961 mCameraState = QCS_INTERNAL_RAW_REQUESTED;
962
963 LINK_camera_take_picture(camera_cb, this);
964
965 // It's possible for the YUV callback as well as the JPEG callbacks
966 // to be invoked before we even make it here, so we check for all
967 // possible result states from takePicture.
968
969 while (mCameraState != QCS_WAITING_RAW &&
970 mCameraState != QCS_WAITING_JPEG &&
971 mCameraState != QCS_IDLE &&
972 mCameraState != QCS_ERROR) {
973 ALOGV("takePicture: waiting for QCS_WAITING_RAW or QCS_WAITING_JPEG");
974 mStateWait.wait(mStateLock);
975 ALOGV("takePicture: woke up, state is %s",
976 getCameraStateStr(mCameraState));
977 }
978
979 ALOGV("takePicture: X");
980 print_time();
981 return mCameraState != QCS_ERROR ?
982 NO_ERROR : UNKNOWN_ERROR;
983 }
984
cancelPicture(bool cancel_shutter,bool cancel_raw,bool cancel_jpeg)985 status_t QualcommCameraHardware::cancelPicture(
986 bool cancel_shutter, bool cancel_raw, bool cancel_jpeg)
987 {
988 ALOGV("cancelPicture: E cancel_shutter = %d, cancel_raw = %d, cancel_jpeg = %d",
989 cancel_shutter, cancel_raw, cancel_jpeg);
990 Mutex::Autolock l(&mLock);
991 Mutex::Autolock stateLock(&mStateLock);
992
993 switch (mCameraState) {
994 case QCS_INTERNAL_RAW_REQUESTED:
995 case QCS_WAITING_RAW:
996 case QCS_WAITING_JPEG:
997 ALOGV("camera state is %s, stopping picture.",
998 getCameraStateStr(mCameraState));
999
1000 {
1001 Mutex::Autolock cbLock(&mCallbackLock);
1002 if (cancel_shutter) mShutterCallback = NULL;
1003 if (cancel_raw) mRawPictureCallback = NULL;
1004 if (cancel_jpeg) mJpegPictureCallback = NULL;
1005 }
1006
1007 while (mCameraState != QCS_IDLE &&
1008 mCameraState != QCS_ERROR) {
1009 ALOGV("cancelPicture: waiting for QCS_IDLE");
1010 mStateWait.wait(mStateLock);
1011 }
1012 break;
1013 default:
1014 ALOGV("not taking a picture (state %s)",
1015 getCameraStateStr(mCameraState));
1016 }
1017
1018 ALOGV("cancelPicture: X");
1019 return NO_ERROR;
1020 }
1021
setParameters(const CameraParameters & params)1022 status_t QualcommCameraHardware::setParameters(
1023 const CameraParameters& params)
1024 {
1025 ALOGV("setParameters: E params = %p", ¶ms);
1026
1027 Mutex::Autolock l(&mLock);
1028 Mutex::Autolock lock(&mStateLock);
1029
1030 // FIXME: verify params
1031 // yuv422sp is here only for legacy reason. Unfortunately, we release
1032 // the code with yuv422sp as the default and enforced setting. The
1033 // correct setting is yuv420sp.
1034 if ((strcmp(params.getPreviewFormat(), "yuv420sp") != 0) &&
1035 (strcmp(params.getPreviewFormat(), "yuv422sp") != 0)) {
1036 ALOGE("Only yuv420sp preview is supported");
1037 return INVALID_OPERATION;
1038 }
1039
1040 // FIXME: will this make a deep copy/do the right thing? String8 i
1041 // should handle it
1042
1043 mParameters = params;
1044
1045 // libqcamera only supports certain size/aspect ratios
1046 // find closest match that doesn't exceed app's request
1047 int width, height;
1048 params.getPreviewSize(&width, &height);
1049 ALOGV("requested size %d x %d", width, height);
1050 preview_size_type* ps = preview_sizes;
1051 size_t i;
1052 for (i = 0; i < PREVIEW_SIZE_COUNT; ++i, ++ps) {
1053 if (width >= ps->width && height >= ps->height) break;
1054 }
1055 // app requested smaller size than supported, use smallest size
1056 if (i == PREVIEW_SIZE_COUNT) ps--;
1057 ALOGV("actual size %d x %d", ps->width, ps->height);
1058 mParameters.setPreviewSize(ps->width, ps->height);
1059
1060 mParameters.getPreviewSize(&mPreviewWidth, &mPreviewHeight);
1061 mParameters.getPictureSize(&mRawWidth, &mRawHeight);
1062
1063 mPreviewWidth = (mPreviewWidth + 1) & ~1;
1064 mPreviewHeight = (mPreviewHeight + 1) & ~1;
1065 mRawHeight = (mRawHeight + 1) & ~1;
1066 mRawWidth = (mRawWidth + 1) & ~1;
1067
1068 initCameraParameters();
1069
1070 ALOGV("setParameters: X mCameraState=%d", mCameraState);
1071 return mCameraState == QCS_IDLE ?
1072 NO_ERROR : UNKNOWN_ERROR;
1073 }
1074
getParameters() const1075 CameraParameters QualcommCameraHardware::getParameters() const
1076 {
1077 ALOGV("getParameters: EX");
1078 return mParameters;
1079 }
1080
1081 static CameraInfo sCameraInfo[] = {
1082 {
1083 CAMERA_FACING_BACK,
1084 90, /* orientation */
1085 }
1086 };
1087
HAL_getNumberOfCameras()1088 extern "C" int HAL_getNumberOfCameras()
1089 {
1090 return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
1091 }
1092
HAL_getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)1093 extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
1094 {
1095 memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
1096 }
1097
HAL_openCameraHardware(int cameraId)1098 extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
1099 {
1100 ALOGV("openCameraHardware: call createInstance");
1101 return QualcommCameraHardware::createInstance();
1102 }
1103
1104 wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
1105
1106 // If the hardware already exists, return a strong pointer to the current
1107 // object. If not, create a new hardware object, put it in the singleton,
1108 // and return it.
createInstance()1109 sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
1110 {
1111 ALOGV("createInstance: E");
1112
1113 singleton_lock.lock();
1114 if (singleton != 0) {
1115 sp<CameraHardwareInterface> hardware = singleton.promote();
1116 if (hardware != 0) {
1117 ALOGV("createInstance: X return existing hardware=%p",
1118 &(*hardware));
1119 singleton_lock.unlock();
1120 return hardware;
1121 }
1122 }
1123
1124 {
1125 struct stat st;
1126 int rc = stat("/dev/oncrpc", &st);
1127 if (rc < 0) {
1128 ALOGV("createInstance: X failed to create hardware: %s",
1129 strerror(errno));
1130 singleton_lock.unlock();
1131 return NULL;
1132 }
1133 }
1134
1135 QualcommCameraHardware *cam = new QualcommCameraHardware();
1136 sp<QualcommCameraHardware> hardware(cam);
1137 singleton = hardware;
1138 singleton_lock.unlock();
1139
1140 // initDefaultParameters() will cause the camera_cb() to be called.
1141 // Since the latter tries to promote the singleton object to make sure
1142 // it still exists, we need to call this function after we have set the
1143 // singleton.
1144 cam->initDefaultParameters();
1145 ALOGV("createInstance: X created hardware=%p", &(*hardware));
1146 return hardware;
1147 }
1148
1149 // For internal use only, hence the strong pointer to the derived type.
getInstance()1150 sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
1151 {
1152 Mutex::Autolock singletonLock(&singleton_lock);
1153 sp<CameraHardwareInterface> hardware = singleton.promote();
1154 return (hardware != 0) ?
1155 sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>
1156 (hardware.get())) :
1157 NULL;
1158 }
1159
get_preview_mem(uint32_t size,uint32_t * phy_addr,uint32_t index)1160 void* QualcommCameraHardware::get_preview_mem(uint32_t size,
1161 uint32_t *phy_addr,
1162 uint32_t index)
1163 {
1164 if (mPreviewHeap != NULL && mPreviewHeap->mHeap != NULL) {
1165 uint8_t *base = (uint8_t *)mPreviewHeap->mHeap->base();
1166 if (base && size <= mPreviewHeap->mSize.len) {
1167 // For preview, associate the memory with the VFE task in the
1168 // DSP. This way, when the DSP gets a command that has a
1169 // physical address, it knows which pmem region to patch it
1170 // against.
1171 uint32_t vaddr = (uint32_t)(base + size*index);
1172
1173 ALOGV("get_preview_mem: base %p MALLOC size %d index %d --> %p",
1174 base, size, index, (void *)vaddr);
1175 *phy_addr = vaddr;
1176 return (void *)vaddr;
1177 }
1178 }
1179 ALOGV("get_preview_mem: X NULL");
1180 return NULL;
1181 }
1182
free_preview_mem(uint32_t * phy_addr,uint32_t size,uint32_t index)1183 void QualcommCameraHardware::free_preview_mem(uint32_t *phy_addr,
1184 uint32_t size,
1185 uint32_t index)
1186 {
1187 ALOGV("free_preview_mem: EX NOP");
1188 return;
1189 }
1190
get_raw_mem(uint32_t size,uint32_t * phy_addr,uint32_t index)1191 void* QualcommCameraHardware::get_raw_mem(uint32_t size,
1192 uint32_t *phy_addr,
1193 uint32_t index)
1194 {
1195 if (mRawHeap != NULL && mRawHeap->mHeap != NULL) {
1196 uint8_t *base = (uint8_t *)mRawHeap->mHeap->base();
1197 if (base && size <= mRawHeap->mSize.len) {
1198 // For raw snapshot, associate the memory with the VFE and LPM
1199 // tasks in the DSP. This way, when the DSP gets a command
1200 // that has a physical address, it knows which pmem region to
1201 // patch it against.
1202 uint32_t vaddr = (uint32_t)(base + size*index);
1203
1204 ALOGV("get_raw_mem: base %p MALLOC size %d index %d --> %p",
1205 base, size, index, (void *)vaddr);
1206 *phy_addr = vaddr;
1207 return (void *)vaddr;
1208 }
1209 }
1210 ALOGV("get_raw_mem: X NULL");
1211 return NULL;
1212 }
1213
free_raw_mem(uint32_t * phy_addr,uint32_t size,uint32_t index)1214 void QualcommCameraHardware::free_raw_mem(uint32_t *phy_addr,
1215 uint32_t size,
1216 uint32_t index)
1217 {
1218 ALOGV("free_raw_mem: EX NOP");
1219 return;
1220 }
1221
receivePreviewFrame(camera_frame_type * frame)1222 void QualcommCameraHardware::receivePreviewFrame(camera_frame_type *frame)
1223 {
1224 Mutex::Autolock cbLock(&mCallbackLock);
1225
1226 // Ignore the first frame--there is a bug in the VFE pipeline and that
1227 // frame may be bad.
1228 if (++mPreviewCount == 1) {
1229 LINK_camera_release_frame();
1230 return;
1231 }
1232
1233 // Find the offset within the heap of the current buffer.
1234 ssize_t offset = (uint32_t)frame->buf_Virt_Addr;
1235 offset -= (uint32_t)mPreviewHeap->mHeap->base();
1236 ssize_t frame_size = kRawFrameHeaderSize + frame->dx * frame->dy * 2;
1237 if (offset + frame_size <=
1238 (ssize_t)mPreviewHeap->mHeap->virtualSize()) {
1239 #if 0
1240 // frame->buffer includes the header, frame->buf_Virt_Addr skips it
1241 ALOGV("PREVIEW FRAME CALLBACK "
1242 "base %p addr %p offset %ld "
1243 "framesz %dx%d=%ld (expect %d) rotation %d "
1244 "(index %ld) size %d header_size 0x%x",
1245 mPreviewHeap->mHeap->base(),
1246 frame->buf_Virt_Addr,
1247 offset,
1248 frame->dx, frame->dy,
1249 frame_size,
1250 mPreviewFrameSize,
1251 frame->rotation,
1252 offset / frame_size,
1253 mPreviewFrameSize, frame->header_size);
1254 #endif
1255 offset /= frame_size;
1256 if (mPreviewCallback != NULL)
1257 mPreviewCallback(mPreviewHeap->mBuffers[offset],
1258 mPreviewCallbackCookie);
1259 if (mRecordingCallback != NULL)
1260 mRecordingCallback(mPreviewHeap->mBuffers[offset],
1261 mRecordingCallbackCookie);
1262 else {
1263 // When we are doing preview but not recording, we need to
1264 // release every preview frame immediately so that the next
1265 // preview frame is delivered. However, when we are recording
1266 // (whether or not we are also streaming the preview frames to
1267 // the screen), we have the user explicitly release a preview
1268 // frame via method releaseRecordingFrame(). In this way we
1269 // allow a video encoder which is potentially slower than the
1270 // preview stream to skip frames. Note that we call
1271 // LINK_camera_release_frame() in this method because we first
1272 // need to check to see if mPreviewCallback != NULL, which
1273 // requires holding mCallbackLock.
1274 LINK_camera_release_frame();
1275 }
1276 }
1277 else ALOGE("Preview frame virtual address %p is out of range!",
1278 frame->buf_Virt_Addr);
1279 }
1280
1281 void
notifyShutter()1282 QualcommCameraHardware::notifyShutter()
1283 {
1284 ALOGV("notifyShutter: E");
1285 print_time();
1286 Mutex::Autolock lock(&mStateLock);
1287 if (mShutterCallback)
1288 mShutterCallback(mPictureCallbackCookie);
1289 print_time();
1290 ALOGV("notifyShutter: X");
1291 }
1292
1293 // Pass the pre-LPM raw picture to raw picture callback.
1294 // This method is called by a libqcamera thread, different from the one on
1295 // which startPreview() or takePicture() are called.
receiveRawPicture(camera_frame_type * frame)1296 void QualcommCameraHardware::receiveRawPicture(camera_frame_type *frame)
1297 {
1298 ALOGV("receiveRawPicture: E");
1299 print_time();
1300
1301 Mutex::Autolock cbLock(&mCallbackLock);
1302
1303 if (mRawPictureCallback != NULL) {
1304 // FIXME: WHY IS buf_Virt_Addr ZERO??
1305 frame->buf_Virt_Addr = (uint32_t*)frame->buffer;
1306
1307 // Find the offset within the heap of the current buffer.
1308 ssize_t offset = (uint32_t)frame->buf_Virt_Addr;
1309 offset -= (uint32_t)mRawHeap->mHeap->base();
1310 ssize_t frame_size = kRawFrameHeaderSize +
1311 frame->captured_dx * frame->captured_dy * 2;
1312
1313 if (offset + frame_size <=
1314 (ssize_t)mRawHeap->mHeap->virtualSize()) {
1315 #if 0
1316 // frame->buffer includes the header, frame->buf_Virt_Addr
1317 // skips it.
1318 ALOGV("receiveRawPicture: RAW CALLBACK (CB %p) "
1319 "base %p addr %p buffer %p offset %ld "
1320 "framesz %dx%d=%ld (expect %d) rotation %d "
1321 "(index %ld) size %d header_size 0x%x",
1322 mRawPictureCallback,
1323 mRawHeap->mHeap->base(),
1324 frame->buf_Virt_Addr,
1325 frame->buffer,
1326 offset,
1327 frame->captured_dx, frame->captured_dy,
1328 frame_size,
1329 mRawSize,
1330 frame->rotation,
1331 offset / frame_size,
1332 mRawSize, frame->header_size);
1333 #endif
1334 offset /= frame_size;
1335 mRawPictureCallback(mRawHeap->mBuffers[offset],
1336 mPictureCallbackCookie);
1337 }
1338 else ALOGE("receiveRawPicture: virtual address %p is out of range!",
1339 frame->buf_Virt_Addr);
1340 }
1341 else ALOGV("Raw-picture callback was canceled--skipping.");
1342
1343 print_time();
1344 ALOGV("receiveRawPicture: X");
1345 }
1346
1347 // Encode the post-LPM raw picture.
1348 // This method is called by a libqcamera thread, different from the one on
1349 // which startPreview() or takePicture() are called.
1350
1351 void
receivePostLpmRawPicture(camera_frame_type * frame)1352 QualcommCameraHardware::receivePostLpmRawPicture(camera_frame_type *frame)
1353 {
1354 ALOGV("receivePostLpmRawPicture: E");
1355 print_time();
1356 qualcomm_camera_state new_state = QCS_ERROR;
1357
1358 Mutex::Autolock cbLock(&mCallbackLock);
1359
1360 if (mJpegPictureCallback != NULL) {
1361
1362 bool encode_location = true;
1363
1364 #define PARSE_LOCATION(what,type,fmt,desc) do { \
1365 pt.what = 0; \
1366 const char *what##_str = mParameters.get("gps-"#what); \
1367 ALOGV("receiveRawPicture: GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
1368 if (what##_str) { \
1369 type what = 0; \
1370 if (sscanf(what##_str, fmt, &what) == 1) \
1371 pt.what = what; \
1372 else { \
1373 ALOGE("GPS " #what " %s could not" \
1374 " be parsed as a " #desc, \
1375 what##_str); \
1376 encode_location = false; \
1377 } \
1378 } \
1379 else { \
1380 ALOGW("receiveRawPicture: GPS " #what " not specified: " \
1381 "defaulting to zero in EXIF header."); \
1382 encode_location = false; \
1383 } \
1384 } while(0)
1385
1386 PARSE_LOCATION(timestamp, long, "%ld", "long");
1387 if (!pt.timestamp) pt.timestamp = time(NULL);
1388 PARSE_LOCATION(altitude, short, "%hd", "short");
1389 PARSE_LOCATION(latitude, double, "%lf", "double float");
1390 PARSE_LOCATION(longitude, double, "%lf", "double float");
1391
1392 #undef PARSE_LOCATION
1393
1394 if (encode_location) {
1395 ALOGV("receiveRawPicture: setting image location ALT %d LAT %lf LON %lf",
1396 pt.altitude, pt.latitude, pt.longitude);
1397 if (LINK_camera_set_position(&pt, NULL, NULL) != CAMERA_SUCCESS) {
1398 ALOGE("receiveRawPicture: camera_set_position: error");
1399 /* return; */ // not a big deal
1400 }
1401 }
1402 else ALOGV("receiveRawPicture: not setting image location");
1403
1404 mJpegSize = 0;
1405 camera_handle.device = CAMERA_DEVICE_MEM;
1406 camera_handle.mem.encBuf_num = MAX_JPEG_ENCODE_BUF_NUM;
1407
1408 for (int cnt = 0; cnt < MAX_JPEG_ENCODE_BUF_NUM; cnt++) {
1409 camera_handle.mem.encBuf[cnt].buffer = (uint8_t *)
1410 malloc(MAX_JPEG_ENCODE_BUF_LEN);
1411 camera_handle.mem.encBuf[cnt].buf_len =
1412 MAX_JPEG_ENCODE_BUF_LEN;
1413 camera_handle.mem.encBuf[cnt].used_len = 0;
1414 } /* for */
1415
1416 LINK_camera_encode_picture(frame, &camera_handle, camera_cb, this);
1417 }
1418 else {
1419 ALOGV("JPEG callback was cancelled--not encoding image.");
1420 // We need to keep the raw heap around until the JPEG is fully
1421 // encoded, because the JPEG encode uses the raw image contained in
1422 // that heap.
1423 mRawHeap = NULL;
1424 }
1425 print_time();
1426 ALOGV("receivePostLpmRawPicture: X");
1427 }
1428
1429 void
receiveJpegPictureFragment(JPEGENC_CBrtnType * encInfo)1430 QualcommCameraHardware::receiveJpegPictureFragment(
1431 JPEGENC_CBrtnType *encInfo)
1432 {
1433 camera_encode_mem_type *enc =
1434 (camera_encode_mem_type *)encInfo->outPtr;
1435 int index = enc - camera_handle.mem.encBuf;
1436 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
1437 uint32_t size = encInfo->size;
1438 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
1439 remaining -= mJpegSize;
1440
1441 ALOGV("receiveJpegPictureFragment: (index %d status %d size %d)",
1442 index,
1443 encInfo->status,
1444 size);
1445
1446 if (size > remaining) {
1447 ALOGE("receiveJpegPictureFragment: size %d exceeds what "
1448 "remains in JPEG heap (%d), truncating",
1449 size,
1450 remaining);
1451 size = remaining;
1452 }
1453
1454 camera_handle.mem.encBuf[index].used_len = 0;
1455 memcpy(base + mJpegSize, enc->buffer, size);
1456 mJpegSize += size;
1457 }
1458
1459 // This method is called by a libqcamera thread, different from the one on
1460 // which startPreview() or takePicture() are called.
1461
1462 void
receiveJpegPicture(void)1463 QualcommCameraHardware::receiveJpegPicture(void)
1464 {
1465 ALOGV("receiveJpegPicture: E image (%d bytes out of %d)",
1466 mJpegSize, mJpegHeap->mBufferSize);
1467 print_time();
1468 Mutex::Autolock cbLock(&mCallbackLock);
1469
1470 int index = 0;
1471
1472 if (mJpegPictureCallback) {
1473 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
1474 // that the JPEG image's size will probably change from one snapshot
1475 // to the next, so we cannot reuse the MemoryBase object.
1476 sp<MemoryBase> buffer = new
1477 MemoryBase(mJpegHeap->mHeap,
1478 index * mJpegHeap->mBufferSize +
1479 mJpegHeap->mFrameOffset,
1480 mJpegSize);
1481
1482 mJpegPictureCallback(buffer, mPictureCallbackCookie);
1483 buffer = NULL;
1484 }
1485 else ALOGV("JPEG callback was cancelled--not delivering image.");
1486
1487 // NOTE: the JPEG encoder uses the raw image contained in mRawHeap, so we need
1488 // to keep the heap around until the encoding is complete.
1489 mJpegHeap = NULL;
1490 mRawHeap = NULL;
1491
1492 for (int cnt = 0; cnt < MAX_JPEG_ENCODE_BUF_NUM; cnt++) {
1493 if (camera_handle.mem.encBuf[cnt].buffer != NULL) {
1494 free(camera_handle.mem.encBuf[cnt].buffer);
1495 memset(camera_handle.mem.encBuf + cnt, 0,
1496 sizeof(camera_encode_mem_type));
1497 }
1498 } /* for */
1499
1500 print_time();
1501 ALOGV("receiveJpegPicture: X callback done.");
1502 }
1503
1504 struct str_map {
1505 const char *const desc;
1506 int val;
1507 };
1508
1509 static const struct str_map wb_map[] = {
1510 { "auto", CAMERA_WB_AUTO },
1511 { "custom", CAMERA_WB_CUSTOM },
1512 { "incandescent", CAMERA_WB_INCANDESCENT },
1513 { "fluorescent", CAMERA_WB_FLUORESCENT },
1514 { "daylight", CAMERA_WB_DAYLIGHT },
1515 { "cloudy", CAMERA_WB_CLOUDY_DAYLIGHT },
1516 { "twilight", CAMERA_WB_TWILIGHT },
1517 { "shade", CAMERA_WB_SHADE },
1518 { NULL, 0 }
1519 };
1520
1521 static const struct str_map effect_map[] = {
1522 { "off", CAMERA_EFFECT_OFF },
1523 { "mono", CAMERA_EFFECT_MONO },
1524 { "negative", CAMERA_EFFECT_NEGATIVE },
1525 { "solarize", CAMERA_EFFECT_SOLARIZE },
1526 { "pastel", CAMERA_EFFECT_PASTEL },
1527 { "mosaic", CAMERA_EFFECT_MOSAIC },
1528 { "resize", CAMERA_EFFECT_RESIZE },
1529 { "sepia", CAMERA_EFFECT_SEPIA },
1530 { "posterize", CAMERA_EFFECT_POSTERIZE },
1531 { "whiteboard", CAMERA_EFFECT_WHITEBOARD },
1532 { "blackboard", CAMERA_EFFECT_BLACKBOARD },
1533 { "aqua", CAMERA_EFFECT_AQUA },
1534 { NULL, 0 }
1535 };
1536
1537 static const struct str_map brightness_map[] = {
1538 { "0", CAMERA_BRIGHTNESS_0 },
1539 { "1", CAMERA_BRIGHTNESS_1 },
1540 { "2", CAMERA_BRIGHTNESS_2 },
1541 { "3", CAMERA_BRIGHTNESS_3 },
1542 { "4", CAMERA_BRIGHTNESS_4 },
1543 { "5", CAMERA_BRIGHTNESS_5 },
1544 { "6", CAMERA_BRIGHTNESS_6 },
1545 { "7", CAMERA_BRIGHTNESS_7 },
1546 { "8", CAMERA_BRIGHTNESS_8 },
1547 { "9", CAMERA_BRIGHTNESS_9 },
1548 { "10", CAMERA_BRIGHTNESS_10 },
1549 { NULL, 0 }
1550 };
1551
1552 static const struct str_map antibanding_map[] = {
1553 { "off", CAMERA_ANTIBANDING_OFF },
1554 { "50hz", CAMERA_ANTIBANDING_50HZ },
1555 { "60hz", CAMERA_ANTIBANDING_60HZ },
1556 { "auto", CAMERA_ANTIBANDING_AUTO },
1557 { NULL, 0 }
1558 };
1559
1560 static const struct str_map iso_map[] = {
1561 { "auto", CAMERA_ISO_AUTO },
1562 { "high", CAMERA_ISO_HIGH },
1563 { NULL, 0 }
1564 };
1565
lookup(const struct str_map * const arr,const char * name,int def)1566 static int lookup(const struct str_map *const arr, const char *name, int def)
1567 {
1568 if (name) {
1569 const struct str_map * trav = arr;
1570 while (trav->desc) {
1571 if (!strcmp(trav->desc, name))
1572 return trav->val;
1573 trav++;
1574 }
1575 }
1576 return def;
1577 }
1578
initCameraParameters()1579 void QualcommCameraHardware::initCameraParameters()
1580 {
1581 ALOGV("initCameraParameters: E");
1582
1583 // Because libqcamera is broken, for the camera_set_parm() calls
1584 // QualcommCameraHardware camera_cb() is called synchronously,
1585 // so we cannot wait on a state change. Also, we have to unlock
1586 // the mStateLock, because camera_cb() acquires it.
1587
1588 startCameraIfNecessary();
1589
1590 #define SET_PARM(x,y) do { \
1591 ALOGV("initCameraParameters: set parm: %s, %d", #x, y); \
1592 LINK_camera_set_parm (x, y, NULL, NULL); \
1593 } while(0)
1594
1595 /* Preview Mode: snapshot or movie */
1596 SET_PARM(CAMERA_PARM_PREVIEW_MODE, CAMERA_PREVIEW_MODE_SNAPSHOT);
1597
1598 /* Default Rotation - none */
1599 int rotation = mParameters.getInt("rotation");
1600
1601 // Rotation may be negative, but may not be -1, because it has to be a
1602 // multiple of 90. That's why we can still interpret -1 as an error,
1603 if (rotation == -1) {
1604 ALOGV("rotation not specified or is invalid, defaulting to 0");
1605 rotation = 0;
1606 }
1607 else if (rotation % 90) {
1608 ALOGE("rotation %d is not a multiple of 90 degrees! Defaulting to zero.",
1609 rotation);
1610 rotation = 0;
1611 }
1612 else {
1613 // normalize to [0 - 270] degrees
1614 rotation %= 360;
1615 if (rotation < 0) rotation += 360;
1616 }
1617
1618 SET_PARM(CAMERA_PARM_ENCODE_ROTATION, rotation);
1619
1620 SET_PARM(CAMERA_PARM_WB,
1621 lookup(wb_map,
1622 mParameters.get("whitebalance"),
1623 CAMERA_WB_AUTO));
1624
1625 SET_PARM(CAMERA_PARM_EFFECT,
1626 lookup(effect_map,
1627 mParameters.get("effect"),
1628 CAMERA_EFFECT_OFF));
1629
1630 SET_PARM(CAMERA_PARM_BRIGHTNESS,
1631 lookup(brightness_map,
1632 mParameters.get("exposure-offset"),
1633 CAMERA_BRIGHTNESS_DEFAULT));
1634
1635 SET_PARM(CAMERA_PARM_ISO,
1636 lookup(iso_map,
1637 mParameters.get("iso"),
1638 CAMERA_ISO_AUTO));
1639
1640 SET_PARM(CAMERA_PARM_ANTIBANDING,
1641 lookup(antibanding_map,
1642 mParameters.get("antibanding"),
1643 CAMERA_ANTIBANDING_AUTO));
1644
1645 int ns_mode = mParameters.getInt("nightshot-mode");
1646 if (ns_mode < 0) ns_mode = 0;
1647 SET_PARM(CAMERA_PARM_NIGHTSHOT_MODE, ns_mode);
1648
1649 int luma_adaptation = mParameters.getInt("luma-adaptation");
1650 if (luma_adaptation < 0) luma_adaptation = 0;
1651 SET_PARM(CAMERA_PARM_LUMA_ADAPTATION, luma_adaptation);
1652
1653 #undef SET_PARM
1654
1655 #if 0
1656 /* Default Auto FPS: 30 (maximum) */
1657 LINK_camera_set_parm_2 (CAMERA_PARM_PREVIEW_FPS,
1658 (1<<16|20), // max frame rate 30
1659 (4<<16|20), // min frame rate 5
1660 NULL,
1661 NULL);
1662 #endif
1663
1664 int th_w, th_h, th_q;
1665 th_w = mParameters.getInt("jpeg-thumbnail-width");
1666 if (th_w < 0) ALOGW("property jpeg-thumbnail-width not specified");
1667
1668 th_h = mParameters.getInt("jpeg-thumbnail-height");
1669 if (th_h < 0) ALOGW("property jpeg-thumbnail-height not specified");
1670
1671 th_q = mParameters.getInt("jpeg-thumbnail-quality");
1672 if (th_q < 0) ALOGW("property jpeg-thumbnail-quality not specified");
1673
1674 if (th_w > 0 && th_h > 0 && th_q > 0) {
1675 ALOGI("setting thumbnail dimensions to %dx%d, quality %d",
1676 th_w, th_h, th_q);
1677 int ret = LINK_camera_set_thumbnail_properties(th_w, th_h, th_q);
1678 if (ret != CAMERA_SUCCESS) {
1679 ALOGE("LINK_camera_set_thumbnail_properties returned %d", ret);
1680 }
1681 }
1682
1683 #if defined FEATURE_CAMERA_ENCODE_PROPERTIES
1684 /* Set Default JPEG encoding--this does not cause a callback */
1685 encode_properties.quality = mParameters.getInt("jpeg-quality");
1686 if (encode_properties.quality < 0) {
1687 ALOGW("JPEG-image quality is not specified "
1688 "or is negative, defaulting to %d",
1689 encode_properties.quality);
1690 encode_properties.quality = 100;
1691 }
1692 else ALOGV("Setting JPEG-image quality to %d",
1693 encode_properties.quality);
1694 encode_properties.format = CAMERA_JPEG;
1695 encode_properties.file_size = 0x0;
1696 LINK_camera_set_encode_properties(&encode_properties);
1697 #else
1698 #warning 'FEATURE_CAMERA_ENCODE_PROPERTIES should be enabled!'
1699 #endif
1700
1701
1702 ALOGV("initCameraParameters: X");
1703 }
1704
1705 // Called with mStateLock held!
setCameraDimensions()1706 void QualcommCameraHardware::setCameraDimensions()
1707 {
1708 if (mCameraState != QCS_IDLE) {
1709 ALOGE("set camera dimensions: expecting state QCS_IDLE, not %s",
1710 getCameraStateStr(mCameraState));
1711 return;
1712 }
1713
1714 LINK_camera_set_dimensions(mRawWidth,
1715 mRawHeight,
1716 mPreviewWidth,
1717 mPreviewHeight,
1718 NULL,
1719 NULL);
1720 }
1721
1722 QualcommCameraHardware::qualcomm_camera_state
change_state(qualcomm_camera_state new_state,bool lock)1723 QualcommCameraHardware::change_state(qualcomm_camera_state new_state,
1724 bool lock)
1725 {
1726 if (lock) mStateLock.lock();
1727 if (new_state != mCameraState) {
1728 // Due to the fact that we allow only one thread at a time to call
1729 // startPreview(), stopPreview(), or takePicture(), we know that
1730 // only one thread at a time may be blocked waiting for a state
1731 // transition on mStateWait. That's why we signal(), not
1732 // broadcast().
1733
1734 ALOGV("state transition %s --> %s",
1735 getCameraStateStr(mCameraState),
1736 getCameraStateStr(new_state));
1737
1738 mCameraState = new_state;
1739 mStateWait.signal();
1740 }
1741 if (lock) mStateLock.unlock();
1742 return new_state;
1743 }
1744
1745 #define CAMERA_STATE(n) case n: if(n != CAMERA_FUNC_START_PREVIEW || cb != CAMERA_EVT_CB_FRAME) ALOGV("STATE %s // STATUS %d", #n, cb);
1746 #define TRANSITION(e,s) do { \
1747 obj->change_state(obj->mCameraState == e ? s : QCS_ERROR); \
1748 } while(0)
1749 #define TRANSITION_LOCKED(e,s) do { \
1750 obj->change_state((obj->mCameraState == e ? s : QCS_ERROR), false); \
1751 } while(0)
1752 #define TRANSITION_ALWAYS(s) obj->change_state(s)
1753
1754
1755 // This callback is called from the destructor.
stop_camera_cb(camera_cb_type cb,const void * client_data,camera_func_type func,int32_t parm4)1756 void QualcommCameraHardware::stop_camera_cb(camera_cb_type cb,
1757 const void *client_data,
1758 camera_func_type func,
1759 int32_t parm4)
1760 {
1761 QualcommCameraHardware *obj =
1762 (QualcommCameraHardware *)client_data;
1763 switch(func) {
1764 CAMERA_STATE(CAMERA_FUNC_STOP)
1765 TRANSITION(QCS_INTERNAL_STOPPING, QCS_INIT);
1766 break;
1767 default:
1768 break;
1769 }
1770 }
1771
camera_cb(camera_cb_type cb,const void * client_data,camera_func_type func,int32_t parm4)1772 void QualcommCameraHardware::camera_cb(camera_cb_type cb,
1773 const void *client_data,
1774 camera_func_type func,
1775 int32_t parm4)
1776 {
1777 QualcommCameraHardware *obj =
1778 (QualcommCameraHardware *)client_data;
1779
1780 // Promote the singleton to make sure that we do not get destroyed
1781 // while this callback is executing.
1782 if (UNLIKELY(getInstance() == NULL)) {
1783 ALOGE("camera object has been destroyed--returning immediately");
1784 return;
1785 }
1786
1787 if (cb == CAMERA_EXIT_CB_ABORT || /* Function aborted */
1788 cb == CAMERA_EXIT_CB_DSP_ABORT || /* Abort due to DSP failure */
1789 cb == CAMERA_EXIT_CB_ERROR || /* Failed due to resource */
1790 cb == CAMERA_EXIT_CB_FAILED) /* Execution failed or rejected */
1791 {
1792 // Autofocus failures occur relatively often and are not fatal, so
1793 // we do not transition to QCS_ERROR for them.
1794 if (func != CAMERA_FUNC_START_FOCUS) {
1795 ALOGE("QualcommCameraHardware::camera_cb: @CAMERA_EXIT_CB_FAILURE(%d) in state %s.",
1796 parm4,
1797 obj->getCameraStateStr(obj->mCameraState));
1798 TRANSITION_ALWAYS(QCS_ERROR);
1799 }
1800 }
1801
1802 switch(func) {
1803 // This is the commonest case.
1804 CAMERA_STATE(CAMERA_FUNC_START_PREVIEW)
1805 switch(cb) {
1806 case CAMERA_RSP_CB_SUCCESS:
1807 TRANSITION(QCS_INTERNAL_PREVIEW_REQUESTED,
1808 QCS_PREVIEW_IN_PROGRESS);
1809 break;
1810 case CAMERA_EVT_CB_FRAME:
1811 switch (obj->mCameraState) {
1812 case QCS_PREVIEW_IN_PROGRESS:
1813 if (parm4)
1814 obj->receivePreviewFrame((camera_frame_type *)parm4);
1815 break;
1816 case QCS_INTERNAL_PREVIEW_STOPPING:
1817 ALOGE("camera cb: discarding preview frame "
1818 "while stopping preview");
1819 break;
1820 default:
1821 // transition to QCS_ERROR
1822 ALOGE("camera cb: invalid state %s for preview!",
1823 obj->getCameraStateStr(obj->mCameraState));
1824 break;
1825 }
1826 /* -- this function is called now inside of receivePreviewFrame.
1827 LINK_camera_release_frame();
1828 */
1829 break;
1830 default:
1831 // transition to QCS_ERROR
1832 ALOGE("unexpected cb %d for CAMERA_FUNC_START_PREVIEW.",
1833 cb);
1834 }
1835 break;
1836 CAMERA_STATE(CAMERA_FUNC_START)
1837 TRANSITION(QCS_INIT, QCS_IDLE);
1838 break;
1839 /* -- this case handled in stop_camera_cb() now.
1840 CAMERA_STATE(CAMERA_FUNC_STOP)
1841 TRANSITION(QCS_INTERNAL_STOPPING, QCS_INIT);
1842 break;
1843 */
1844 CAMERA_STATE(CAMERA_FUNC_STOP_PREVIEW)
1845 TRANSITION(QCS_INTERNAL_PREVIEW_STOPPING,
1846 QCS_IDLE);
1847 break;
1848 CAMERA_STATE(CAMERA_FUNC_TAKE_PICTURE)
1849 if (cb == CAMERA_RSP_CB_SUCCESS) {
1850 TRANSITION(QCS_INTERNAL_RAW_REQUESTED,
1851 QCS_WAITING_RAW);
1852 }
1853 else if (cb == CAMERA_EVT_CB_SNAPSHOT_DONE) {
1854 obj->notifyShutter();
1855 // Received pre-LPM raw picture. Notify callback now.
1856 obj->receiveRawPicture((camera_frame_type *)parm4);
1857 }
1858 else if (cb == CAMERA_EXIT_CB_DONE) {
1859 // It's important that we call receiveRawPicture() before
1860 // we transition the state because another thread may be
1861 // waiting in cancelPicture(), and then delete this object.
1862 // If the order were reversed, we might call
1863 // receiveRawPicture on a dead object.
1864 ALOGV("Receiving post LPM raw picture.");
1865 obj->receivePostLpmRawPicture((camera_frame_type *)parm4);
1866 {
1867 Mutex::Autolock lock(&obj->mStateLock);
1868 TRANSITION_LOCKED(QCS_WAITING_RAW,
1869 obj->mJpegPictureCallback != NULL ?
1870 QCS_WAITING_JPEG :
1871 QCS_IDLE);
1872 }
1873 } else { // transition to QCS_ERROR
1874 if (obj->mCameraState == QCS_ERROR) {
1875 ALOGE("camera cb: invalid state %s for taking a picture!",
1876 obj->getCameraStateStr(obj->mCameraState));
1877 obj->mRawPictureCallback(NULL, obj->mPictureCallbackCookie);
1878 obj->mJpegPictureCallback(NULL, obj->mPictureCallbackCookie);
1879 TRANSITION_ALWAYS(QCS_IDLE);
1880 }
1881 }
1882 break;
1883 CAMERA_STATE(CAMERA_FUNC_ENCODE_PICTURE)
1884 switch (cb) {
1885 case CAMERA_RSP_CB_SUCCESS:
1886 // We already transitioned the camera state to
1887 // QCS_WAITING_JPEG when we called
1888 // camera_encode_picture().
1889 break;
1890 case CAMERA_EXIT_CB_BUFFER:
1891 if (obj->mCameraState == QCS_WAITING_JPEG) {
1892 obj->receiveJpegPictureFragment(
1893 (JPEGENC_CBrtnType *)parm4);
1894 }
1895 else ALOGE("camera cb: invalid state %s for receiving "
1896 "JPEG fragment!",
1897 obj->getCameraStateStr(obj->mCameraState));
1898 break;
1899 case CAMERA_EXIT_CB_DONE:
1900 if (obj->mCameraState == QCS_WAITING_JPEG) {
1901 // Receive the last fragment of the image.
1902 obj->receiveJpegPictureFragment(
1903 (JPEGENC_CBrtnType *)parm4);
1904
1905 // The size of the complete JPEG image is in
1906 // mJpegSize.
1907
1908 // It's important that we call receiveJpegPicture()
1909 // before we transition the state because another
1910 // thread may be waiting in cancelPicture(), and then
1911 // delete this object. If the order were reversed, we
1912 // might call receiveRawPicture on a dead object.
1913
1914 obj->receiveJpegPicture();
1915
1916 TRANSITION(QCS_WAITING_JPEG, QCS_IDLE);
1917 }
1918 // transition to QCS_ERROR
1919 else ALOGE("camera cb: invalid state %s for "
1920 "receiving JPEG!",
1921 obj->getCameraStateStr(obj->mCameraState));
1922 break;
1923 default:
1924 // transition to QCS_ERROR
1925 ALOGE("camera cb: unknown cb %d for JPEG!", cb);
1926 }
1927 break;
1928 CAMERA_STATE(CAMERA_FUNC_START_FOCUS) {
1929 // NO TRANSITION HERE. We acquire mStateLock here because it is
1930 // possible for ::autoFocus to be called after the call to
1931 // mAutoFocusCallback() but before we set mAutoFocusCallback
1932 // to NULL.
1933 if (obj->mAutoFocusCallback) {
1934 switch (cb) {
1935 case CAMERA_RSP_CB_SUCCESS:
1936 ALOGV("camera cb: autofocus has started.");
1937 break;
1938 case CAMERA_EXIT_CB_DONE: {
1939 ALOGV("camera cb: autofocus succeeded.");
1940 Mutex::Autolock lock(&obj->mStateLock);
1941 if (obj->mAutoFocusCallback) {
1942 obj->mAutoFocusCallback(true,
1943 obj->mAutoFocusCallbackCookie);
1944 obj->mAutoFocusCallback = NULL;
1945 }
1946 }
1947 break;
1948 case CAMERA_EXIT_CB_ABORT:
1949 ALOGE("camera cb: autofocus aborted");
1950 break;
1951 case CAMERA_EXIT_CB_FAILED: {
1952 ALOGE("camera cb: autofocus failed");
1953 Mutex::Autolock lock(&obj->mStateLock);
1954 if (obj->mAutoFocusCallback) {
1955 obj->mAutoFocusCallback(false,
1956 obj->mAutoFocusCallbackCookie);
1957 obj->mAutoFocusCallback = NULL;
1958 }
1959 }
1960 break;
1961 default:
1962 ALOGE("camera cb: unknown cb %d for "
1963 "CAMERA_FUNC_START_FOCUS!", cb);
1964 }
1965 }
1966 } break;
1967 default:
1968 // transition to QCS_ERROR
1969 ALOGE("Unknown camera-callback status %d", cb);
1970 }
1971 }
1972
1973 #undef TRANSITION
1974 #undef TRANSITION_LOCKED
1975 #undef TRANSITION_ALWAYS
1976 #undef CAMERA_STATE
1977
clp2(unsigned x)1978 static unsigned clp2(unsigned x) {
1979 x = x - 1;
1980 x = x | (x >> 1);
1981 x = x | (x >> 2);
1982 x = x | (x >> 4);
1983 x = x | (x >> 8);
1984 x = x | (x >>16);
1985 return x + 1;
1986 }
1987
MemPool(int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)1988 QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
1989 int frame_size,
1990 int frame_offset,
1991 const char *name) :
1992 mBufferSize(buffer_size),
1993 mNumBuffers(num_buffers),
1994 mFrameSize(frame_size),
1995 mFrameOffset(frame_offset),
1996 mBuffers(NULL), mName(name)
1997 {
1998 // empty
1999 }
2000
completeInitialization()2001 void QualcommCameraHardware::MemPool::completeInitialization()
2002 {
2003 // If we do not know how big the frame will be, we wait to allocate
2004 // the buffers describing the individual frames until we do know their
2005 // size.
2006
2007 if (mFrameSize > 0) {
2008 mBuffers = new sp<MemoryBase>[mNumBuffers];
2009 for (int i = 0; i < mNumBuffers; i++) {
2010 mBuffers[i] = new
2011 MemoryBase(mHeap,
2012 i * mBufferSize + mFrameOffset,
2013 mFrameSize);
2014 }
2015 }
2016 }
2017
AshmemPool(int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2018 QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
2019 int frame_size,
2020 int frame_offset,
2021 const char *name) :
2022 QualcommCameraHardware::MemPool(buffer_size,
2023 num_buffers,
2024 frame_size,
2025 frame_offset,
2026 name)
2027 {
2028 ALOGV("constructing MemPool %s backed by ashmem: "
2029 "%d frames @ %d bytes, offset %d, "
2030 "buffer size %d",
2031 mName,
2032 num_buffers, frame_size, frame_offset, buffer_size);
2033
2034 int page_mask = getpagesize() - 1;
2035 int ashmem_size = buffer_size * num_buffers;
2036 ashmem_size += page_mask;
2037 ashmem_size &= ~page_mask;
2038
2039 mHeap = new MemoryHeapBase(ashmem_size);
2040
2041 completeInitialization();
2042 }
2043
PmemPool(const char * pmem_pool,int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2044 QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
2045 int buffer_size, int num_buffers,
2046 int frame_size,
2047 int frame_offset,
2048 const char *name) :
2049 QualcommCameraHardware::MemPool(buffer_size,
2050 num_buffers,
2051 frame_size,
2052 frame_offset,
2053 name)
2054 {
2055 ALOGV("constructing MemPool %s backed by pmem pool %s: "
2056 "%d frames @ %d bytes, offset %d, buffer size %d",
2057 mName,
2058 pmem_pool, num_buffers, frame_size, frame_offset,
2059 buffer_size);
2060
2061 // Make a new mmap'ed heap that can be shared across processes.
2062
2063 mAlignedSize = clp2(buffer_size * num_buffers);
2064
2065 sp<MemoryHeapBase> masterHeap =
2066 new MemoryHeapBase(pmem_pool, mAlignedSize, 0);
2067 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, 0);
2068 if (pmemHeap->getHeapID() >= 0) {
2069 pmemHeap->slap();
2070 masterHeap.clear();
2071 mHeap = pmemHeap;
2072 pmemHeap.clear();
2073
2074 mFd = mHeap->getHeapID();
2075 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
2076 ALOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
2077 pmem_pool,
2078 ::strerror(errno), errno);
2079 mHeap.clear();
2080 return;
2081 }
2082
2083 ALOGV("pmem pool %s ioctl(PMEM_GET_SIZE) is %ld",
2084 pmem_pool,
2085 mSize.len);
2086
2087 completeInitialization();
2088 }
2089 else ALOGE("pmem pool %s error: could not create master heap!",
2090 pmem_pool);
2091 }
2092
PreviewPmemPool(int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2093 QualcommCameraHardware::PreviewPmemPool::PreviewPmemPool(
2094 int buffer_size, int num_buffers,
2095 int frame_size,
2096 int frame_offset,
2097 const char *name) :
2098 QualcommCameraHardware::PmemPool("/dev/pmem_adsp",
2099 buffer_size,
2100 num_buffers,
2101 frame_size,
2102 frame_offset,
2103 name)
2104 {
2105 ALOGV("constructing PreviewPmemPool");
2106 if (initialized()) {
2107 LINK_camera_assoc_pmem(QDSP_MODULE_VFETASK,
2108 mFd,
2109 mHeap->base(),
2110 mAlignedSize,
2111 0); // external
2112 }
2113 }
2114
~PreviewPmemPool()2115 QualcommCameraHardware::PreviewPmemPool::~PreviewPmemPool()
2116 {
2117 ALOGV("destroying PreviewPmemPool");
2118 if(initialized()) {
2119 void *base = mHeap->base();
2120 ALOGV("releasing PreviewPmemPool memory %p from module %d",
2121 base, QDSP_MODULE_VFETASK);
2122 LINK_camera_release_pmem(QDSP_MODULE_VFETASK, base,
2123 mAlignedSize,
2124 true);
2125 }
2126 }
2127
RawPmemPool(const char * pmem_pool,int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2128 QualcommCameraHardware::RawPmemPool::RawPmemPool(
2129 const char *pmem_pool,
2130 int buffer_size, int num_buffers,
2131 int frame_size,
2132 int frame_offset,
2133 const char *name) :
2134 QualcommCameraHardware::PmemPool(pmem_pool,
2135 buffer_size,
2136 num_buffers,
2137 frame_size,
2138 frame_offset,
2139 name)
2140 {
2141 ALOGV("constructing RawPmemPool");
2142
2143 if (initialized()) {
2144 LINK_camera_assoc_pmem(QDSP_MODULE_VFETASK,
2145 mFd,
2146 mHeap->base(),
2147 mAlignedSize,
2148 0); // do not free, main module
2149 LINK_camera_assoc_pmem(QDSP_MODULE_LPMTASK,
2150 mFd,
2151 mHeap->base(),
2152 mAlignedSize,
2153 2); // do not free, dependent module
2154 LINK_camera_assoc_pmem(QDSP_MODULE_JPEGTASK,
2155 mFd,
2156 mHeap->base(),
2157 mAlignedSize,
2158 2); // do not free, dependent module
2159 }
2160 }
2161
~RawPmemPool()2162 QualcommCameraHardware::RawPmemPool::~RawPmemPool()
2163 {
2164 ALOGV("destroying RawPmemPool");
2165 if(initialized()) {
2166 void *base = mHeap->base();
2167 ALOGV("releasing RawPmemPool memory %p from modules %d, %d, and %d",
2168 base, QDSP_MODULE_VFETASK, QDSP_MODULE_LPMTASK,
2169 QDSP_MODULE_JPEGTASK);
2170 LINK_camera_release_pmem(QDSP_MODULE_VFETASK,
2171 base, mAlignedSize, true);
2172 LINK_camera_release_pmem(QDSP_MODULE_LPMTASK,
2173 base, mAlignedSize, true);
2174 LINK_camera_release_pmem(QDSP_MODULE_JPEGTASK,
2175 base, mAlignedSize, true);
2176 }
2177 }
2178
~MemPool()2179 QualcommCameraHardware::MemPool::~MemPool()
2180 {
2181 ALOGV("destroying MemPool %s", mName);
2182 if (mFrameSize > 0)
2183 delete [] mBuffers;
2184 mHeap.clear();
2185 ALOGV("destroying MemPool %s completed", mName);
2186 }
2187
dump(int fd,const Vector<String16> & args) const2188 status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
2189 {
2190 const size_t SIZE = 256;
2191 char buffer[SIZE];
2192 String8 result;
2193 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
2194 result.append(buffer);
2195 if (mName) {
2196 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
2197 result.append(buffer);
2198 }
2199 if (mHeap != 0) {
2200 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
2201 mHeap->getBase(), mHeap->getSize(),
2202 mHeap->getFlags(), mHeap->getDevice());
2203 result.append(buffer);
2204 }
2205 snprintf(buffer, 255, "buffer size (%d), number of buffers (%d),"
2206 " frame size(%d), and frame offset(%d)\n",
2207 mBufferSize, mNumBuffers, mFrameSize, mFrameOffset);
2208 result.append(buffer);
2209 write(fd, result.string(), result.size());
2210 return NO_ERROR;
2211 }
2212
malloc_preview(uint32_t size,uint32_t * phy_addr,uint32_t index)2213 static uint8_t* malloc_preview(uint32_t size,
2214 uint32_t *phy_addr, uint32_t index)
2215 {
2216 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2217 if (obj != 0) {
2218 return (uint8_t *)obj->get_preview_mem(size, phy_addr, index);
2219 }
2220 return NULL;
2221 }
2222
free_preview(uint32_t * phy_addr,uint32_t size,uint32_t index)2223 static int free_preview(uint32_t *phy_addr, uint32_t size,
2224 uint32_t index)
2225 {
2226 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2227 if (obj != 0) {
2228 obj->free_preview_mem(phy_addr, size, index);
2229 }
2230 return 0;
2231 }
2232
malloc_raw(uint32_t size,uint32_t * phy_addr,uint32_t index)2233 static uint8_t* malloc_raw(uint32_t size,
2234 uint32_t *phy_addr,
2235 uint32_t index)
2236 {
2237 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2238 if (obj != 0) {
2239 return (uint8_t *)obj->get_raw_mem(size, phy_addr, index);
2240 }
2241 return NULL;
2242 }
2243
free_raw(uint32_t * phy_addr,uint32_t size,uint32_t index)2244 static int free_raw(uint32_t *phy_addr,
2245 uint32_t size,
2246 uint32_t index)
2247 {
2248 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2249 if (obj != 0) {
2250 obj->free_raw_mem(phy_addr, size, index);
2251 }
2252 return 0;
2253 }
2254
cb_rex_signal_ready(void)2255 static void cb_rex_signal_ready(void)
2256 {
2257 ALOGV("Received REX-ready signal.");
2258 rex_init_lock.lock();
2259 rex_init_wait.broadcast();
2260 rex_init_lock.unlock();
2261 }
2262
getCameraStateStr(QualcommCameraHardware::qualcomm_camera_state s)2263 const char* const QualcommCameraHardware::getCameraStateStr(
2264 QualcommCameraHardware::qualcomm_camera_state s)
2265 {
2266 static const char* states[] = {
2267 #define STATE_STR(x) #x
2268 STATE_STR(QCS_INIT),
2269 STATE_STR(QCS_IDLE),
2270 STATE_STR(QCS_ERROR),
2271 STATE_STR(QCS_PREVIEW_IN_PROGRESS),
2272 STATE_STR(QCS_WAITING_RAW),
2273 STATE_STR(QCS_WAITING_JPEG),
2274 STATE_STR(QCS_INTERNAL_PREVIEW_STOPPING),
2275 STATE_STR(QCS_INTERNAL_PREVIEW_REQUESTED),
2276 STATE_STR(QCS_INTERNAL_RAW_REQUESTED),
2277 STATE_STR(QCS_INTERNAL_STOPPING),
2278 #undef STATE_STR
2279 };
2280 return states[s];
2281 }
2282
2283 }; // namespace android
2284