1 /*
2 ** Copyright 2008, Google Inc.
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 LOGV("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 LOGV("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 LOGE("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 LOGV("loading libqcamera");
379 libqcamera = ::dlopen("liboemcamera.so", RTLD_NOW);
380 if (!libqcamera) {
381 LOGE("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 LOGV("waiting for REX to initialize.");
456 rex_init_wait.wait(rex_init_lock);
457 LOGV("REX is ready.");
458 rex_init_lock.unlock();
459
460 LINK_camera_init();
461
462 LOGV("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 LOGV("init camera: waiting for QCS_IDLE");
469 mStateWait.wait(mStateLock);
470 LOGV("init camera: woke up");
471 }
472 LOGV("init camera: initializing parameters");
473 }
474 else LOGV("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 LOGV("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 LOGV("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 LOGV("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 LOGD("initRaw: clearing old mJpegHeap.");
575 mJpegHeap = NULL;
576
577 LOGV("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 LOGE("initRaw X failed: error initializing mRawHeap");
588 mRawHeap = NULL;
589 return false;
590 }
591
592 if (initJpegHeap) {
593 LOGV("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 LOGE("initRaw X failed: error initializing mJpegHeap.");
602 mJpegHeap = NULL;
603 mRawHeap = NULL;
604 return false;
605 }
606 }
607
608 LOGV("initRaw X success");
609 return true;
610 }
611
release()612 void QualcommCameraHardware::release()
613 {
614 LOGV("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 LOGE("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 LOGV("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 LOGV("stopping camera: waiting for QCS_INIT");
646 mStateWait.wait(mStateLock);
647 }
648 }
649
650 LOGV("Shutting REX down.");
651 LINK_rex_shutdown();
652 LOGV("REX has shut down.");
653 #if DLOPEN_LIBQCAMERA
654 if (libqcamera) {
655 unsigned ref = ::dlclose(libqcamera);
656 LOGV("dlclose(libqcamera) refcount %d", ref);
657 }
658 #endif
659 mCameraState = QCS_INIT;
660 }
661 mStateLock.unlock();
662
663 LOGV("release X");
664 }
665
~QualcommCameraHardware()666 QualcommCameraHardware::~QualcommCameraHardware()
667 {
668 LOGV("~QualcommCameraHardware E");
669 Mutex::Autolock singletonLock(&singleton_lock);
670 singleton.clear();
671 LOGV("~QualcommCameraHardware X");
672 }
673
getPreviewHeap() const674 sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
675 {
676 LOGV("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 LOGV("startPreview E");
703
704 if (mCameraState == QCS_PREVIEW_IN_PROGRESS) {
705 LOGE("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 LOGV("waiting for QCS_IDLE");
724 mStateWait.wait(mStateLock);
725 }
726 }
727
728 if (mCameraState != QCS_IDLE) {
729 LOGE("startPreview X Camera state is %s, expecting QCS_IDLE!",
730 getCameraStateStr(mCameraState));
731 return INVALID_OPERATION;
732 }
733
734 if (!initPreview()) {
735 LOGE("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 LOGV("waiting for QCS_PREVIEW_IN_PROGRESS");
751 mStateWait.wait(mStateLock);
752 }
753 }
754 else {
755 LOGE("startPreview failed: sensor error.");
756 mCameraState = QCS_ERROR;
757 }
758
759 LOGV("startPreview X");
760 return mCameraState == QCS_PREVIEW_IN_PROGRESS ?
761 NO_ERROR : UNKNOWN_ERROR;
762 }
763
stopPreviewInternal()764 void QualcommCameraHardware::stopPreviewInternal()
765 {
766 LOGV("stopPreviewInternal E");
767
768 if (mCameraState != QCS_PREVIEW_IN_PROGRESS) {
769 LOGE("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 LOGV("waiting for QCS_IDLE");
792 mStateWait.wait(mStateLock);
793 }
794
795 LOGV("stopPreviewInternal: Freeing preview heap.");
796 mPreviewHeap = NULL;
797 mPreviewCallback = NULL;
798
799 LOGV("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 LOGV("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 LOGV("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 LOGV("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 LOGV("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 LOGV("Starting auto focus.");
869 Mutex::Autolock l(&mLock);
870 Mutex::Autolock lock(&mStateLock);
871
872 if (mCameraState != QCS_PREVIEW_IN_PROGRESS) {
873 LOGE("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 LOGV("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 LOGV("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 LOGV("waiting for QCS_IDLE");
919 mStateWait.wait(mStateLock);
920 }
921 }
922
923 if (mCameraState != QCS_IDLE) {
924 LOGE("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 LOGE("initRaw failed. Not taking picture.");
938 return UNKNOWN_ERROR;
939 }
940
941 if (mCameraState != QCS_IDLE) {
942 LOGE("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 LOGV("takePicture: waiting for QCS_WAITING_RAW or QCS_WAITING_JPEG");
974 mStateWait.wait(mStateLock);
975 LOGV("takePicture: woke up, state is %s",
976 getCameraStateStr(mCameraState));
977 }
978
979 LOGV("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 LOGV("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 LOGD("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 LOGV("cancelPicture: waiting for QCS_IDLE");
1010 mStateWait.wait(mStateLock);
1011 }
1012 break;
1013 default:
1014 LOGV("not taking a picture (state %s)",
1015 getCameraStateStr(mCameraState));
1016 }
1017
1018 LOGV("cancelPicture: X");
1019 return NO_ERROR;
1020 }
1021
setParameters(const CameraParameters & params)1022 status_t QualcommCameraHardware::setParameters(
1023 const CameraParameters& params)
1024 {
1025 LOGV("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 LOGE("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 LOGV("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 LOGV("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 LOGV("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 LOGV("getParameters: EX");
1078 return mParameters;
1079 }
1080
openCameraHardware()1081 extern "C" sp<CameraHardwareInterface> openCameraHardware()
1082 {
1083 LOGV("openCameraHardware: call createInstance");
1084 return QualcommCameraHardware::createInstance();
1085 }
1086
1087 wp<QualcommCameraHardware> QualcommCameraHardware::singleton;
1088
1089 // If the hardware already exists, return a strong pointer to the current
1090 // object. If not, create a new hardware object, put it in the singleton,
1091 // and return it.
createInstance()1092 sp<CameraHardwareInterface> QualcommCameraHardware::createInstance()
1093 {
1094 LOGV("createInstance: E");
1095
1096 singleton_lock.lock();
1097 if (singleton != 0) {
1098 sp<CameraHardwareInterface> hardware = singleton.promote();
1099 if (hardware != 0) {
1100 LOGV("createInstance: X return existing hardware=%p",
1101 &(*hardware));
1102 singleton_lock.unlock();
1103 return hardware;
1104 }
1105 }
1106
1107 {
1108 struct stat st;
1109 int rc = stat("/dev/oncrpc", &st);
1110 if (rc < 0) {
1111 LOGV("createInstance: X failed to create hardware: %s",
1112 strerror(errno));
1113 singleton_lock.unlock();
1114 return NULL;
1115 }
1116 }
1117
1118 QualcommCameraHardware *cam = new QualcommCameraHardware();
1119 sp<QualcommCameraHardware> hardware(cam);
1120 singleton = hardware;
1121 singleton_lock.unlock();
1122
1123 // initDefaultParameters() will cause the camera_cb() to be called.
1124 // Since the latter tries to promote the singleton object to make sure
1125 // it still exists, we need to call this function after we have set the
1126 // singleton.
1127 cam->initDefaultParameters();
1128 LOGV("createInstance: X created hardware=%p", &(*hardware));
1129 return hardware;
1130 }
1131
1132 // For internal use only, hence the strong pointer to the derived type.
getInstance()1133 sp<QualcommCameraHardware> QualcommCameraHardware::getInstance()
1134 {
1135 Mutex::Autolock singletonLock(&singleton_lock);
1136 sp<CameraHardwareInterface> hardware = singleton.promote();
1137 return (hardware != 0) ?
1138 sp<QualcommCameraHardware>(static_cast<QualcommCameraHardware*>
1139 (hardware.get())) :
1140 NULL;
1141 }
1142
get_preview_mem(uint32_t size,uint32_t * phy_addr,uint32_t index)1143 void* QualcommCameraHardware::get_preview_mem(uint32_t size,
1144 uint32_t *phy_addr,
1145 uint32_t index)
1146 {
1147 if (mPreviewHeap != NULL && mPreviewHeap->mHeap != NULL) {
1148 uint8_t *base = (uint8_t *)mPreviewHeap->mHeap->base();
1149 if (base && size <= mPreviewHeap->mSize.len) {
1150 // For preview, associate the memory with the VFE task in the
1151 // DSP. This way, when the DSP gets a command that has a
1152 // physical address, it knows which pmem region to patch it
1153 // against.
1154 uint32_t vaddr = (uint32_t)(base + size*index);
1155
1156 LOGV("get_preview_mem: base %p MALLOC size %d index %d --> %p",
1157 base, size, index, (void *)vaddr);
1158 *phy_addr = vaddr;
1159 return (void *)vaddr;
1160 }
1161 }
1162 LOGV("get_preview_mem: X NULL");
1163 return NULL;
1164 }
1165
free_preview_mem(uint32_t * phy_addr,uint32_t size,uint32_t index)1166 void QualcommCameraHardware::free_preview_mem(uint32_t *phy_addr,
1167 uint32_t size,
1168 uint32_t index)
1169 {
1170 LOGV("free_preview_mem: EX NOP");
1171 return;
1172 }
1173
get_raw_mem(uint32_t size,uint32_t * phy_addr,uint32_t index)1174 void* QualcommCameraHardware::get_raw_mem(uint32_t size,
1175 uint32_t *phy_addr,
1176 uint32_t index)
1177 {
1178 if (mRawHeap != NULL && mRawHeap->mHeap != NULL) {
1179 uint8_t *base = (uint8_t *)mRawHeap->mHeap->base();
1180 if (base && size <= mRawHeap->mSize.len) {
1181 // For raw snapshot, associate the memory with the VFE and LPM
1182 // tasks in the DSP. This way, when the DSP gets a command
1183 // that has a physical address, it knows which pmem region to
1184 // patch it against.
1185 uint32_t vaddr = (uint32_t)(base + size*index);
1186
1187 LOGV("get_raw_mem: base %p MALLOC size %d index %d --> %p",
1188 base, size, index, (void *)vaddr);
1189 *phy_addr = vaddr;
1190 return (void *)vaddr;
1191 }
1192 }
1193 LOGV("get_raw_mem: X NULL");
1194 return NULL;
1195 }
1196
free_raw_mem(uint32_t * phy_addr,uint32_t size,uint32_t index)1197 void QualcommCameraHardware::free_raw_mem(uint32_t *phy_addr,
1198 uint32_t size,
1199 uint32_t index)
1200 {
1201 LOGV("free_raw_mem: EX NOP");
1202 return;
1203 }
1204
receivePreviewFrame(camera_frame_type * frame)1205 void QualcommCameraHardware::receivePreviewFrame(camera_frame_type *frame)
1206 {
1207 Mutex::Autolock cbLock(&mCallbackLock);
1208
1209 // Ignore the first frame--there is a bug in the VFE pipeline and that
1210 // frame may be bad.
1211 if (++mPreviewCount == 1) {
1212 LINK_camera_release_frame();
1213 return;
1214 }
1215
1216 // Find the offset within the heap of the current buffer.
1217 ssize_t offset = (uint32_t)frame->buf_Virt_Addr;
1218 offset -= (uint32_t)mPreviewHeap->mHeap->base();
1219 ssize_t frame_size = kRawFrameHeaderSize + frame->dx * frame->dy * 2;
1220 if (offset + frame_size <=
1221 (ssize_t)mPreviewHeap->mHeap->virtualSize()) {
1222 #if 0
1223 // frame->buffer includes the header, frame->buf_Virt_Addr skips it
1224 LOGV("PREVIEW FRAME CALLBACK "
1225 "base %p addr %p offset %ld "
1226 "framesz %dx%d=%ld (expect %d) rotation %d "
1227 "(index %ld) size %d header_size 0x%x",
1228 mPreviewHeap->mHeap->base(),
1229 frame->buf_Virt_Addr,
1230 offset,
1231 frame->dx, frame->dy,
1232 frame_size,
1233 mPreviewFrameSize,
1234 frame->rotation,
1235 offset / frame_size,
1236 mPreviewFrameSize, frame->header_size);
1237 #endif
1238 offset /= frame_size;
1239 if (mPreviewCallback != NULL)
1240 mPreviewCallback(mPreviewHeap->mBuffers[offset],
1241 mPreviewCallbackCookie);
1242 if (mRecordingCallback != NULL)
1243 mRecordingCallback(mPreviewHeap->mBuffers[offset],
1244 mRecordingCallbackCookie);
1245 else {
1246 // When we are doing preview but not recording, we need to
1247 // release every preview frame immediately so that the next
1248 // preview frame is delivered. However, when we are recording
1249 // (whether or not we are also streaming the preview frames to
1250 // the screen), we have the user explicitly release a preview
1251 // frame via method releaseRecordingFrame(). In this way we
1252 // allow a video encoder which is potentially slower than the
1253 // preview stream to skip frames. Note that we call
1254 // LINK_camera_release_frame() in this method because we first
1255 // need to check to see if mPreviewCallback != NULL, which
1256 // requires holding mCallbackLock.
1257 LINK_camera_release_frame();
1258 }
1259 }
1260 else LOGE("Preview frame virtual address %p is out of range!",
1261 frame->buf_Virt_Addr);
1262 }
1263
1264 void
notifyShutter()1265 QualcommCameraHardware::notifyShutter()
1266 {
1267 LOGV("notifyShutter: E");
1268 print_time();
1269 Mutex::Autolock lock(&mStateLock);
1270 if (mShutterCallback)
1271 mShutterCallback(mPictureCallbackCookie);
1272 print_time();
1273 LOGV("notifyShutter: X");
1274 }
1275
1276 // Pass the pre-LPM raw picture to raw picture callback.
1277 // This method is called by a libqcamera thread, different from the one on
1278 // which startPreview() or takePicture() are called.
receiveRawPicture(camera_frame_type * frame)1279 void QualcommCameraHardware::receiveRawPicture(camera_frame_type *frame)
1280 {
1281 LOGV("receiveRawPicture: E");
1282 print_time();
1283
1284 Mutex::Autolock cbLock(&mCallbackLock);
1285
1286 if (mRawPictureCallback != NULL) {
1287 // FIXME: WHY IS buf_Virt_Addr ZERO??
1288 frame->buf_Virt_Addr = (uint32_t*)frame->buffer;
1289
1290 // Find the offset within the heap of the current buffer.
1291 ssize_t offset = (uint32_t)frame->buf_Virt_Addr;
1292 offset -= (uint32_t)mRawHeap->mHeap->base();
1293 ssize_t frame_size = kRawFrameHeaderSize +
1294 frame->captured_dx * frame->captured_dy * 2;
1295
1296 if (offset + frame_size <=
1297 (ssize_t)mRawHeap->mHeap->virtualSize()) {
1298 #if 0
1299 // frame->buffer includes the header, frame->buf_Virt_Addr
1300 // skips it.
1301 LOGV("receiveRawPicture: RAW CALLBACK (CB %p) "
1302 "base %p addr %p buffer %p offset %ld "
1303 "framesz %dx%d=%ld (expect %d) rotation %d "
1304 "(index %ld) size %d header_size 0x%x",
1305 mRawPictureCallback,
1306 mRawHeap->mHeap->base(),
1307 frame->buf_Virt_Addr,
1308 frame->buffer,
1309 offset,
1310 frame->captured_dx, frame->captured_dy,
1311 frame_size,
1312 mRawSize,
1313 frame->rotation,
1314 offset / frame_size,
1315 mRawSize, frame->header_size);
1316 #endif
1317 offset /= frame_size;
1318 mRawPictureCallback(mRawHeap->mBuffers[offset],
1319 mPictureCallbackCookie);
1320 }
1321 else LOGE("receiveRawPicture: virtual address %p is out of range!",
1322 frame->buf_Virt_Addr);
1323 }
1324 else LOGV("Raw-picture callback was canceled--skipping.");
1325
1326 print_time();
1327 LOGV("receiveRawPicture: X");
1328 }
1329
1330 // Encode the post-LPM raw picture.
1331 // This method is called by a libqcamera thread, different from the one on
1332 // which startPreview() or takePicture() are called.
1333
1334 void
receivePostLpmRawPicture(camera_frame_type * frame)1335 QualcommCameraHardware::receivePostLpmRawPicture(camera_frame_type *frame)
1336 {
1337 LOGV("receivePostLpmRawPicture: E");
1338 print_time();
1339 qualcomm_camera_state new_state = QCS_ERROR;
1340
1341 Mutex::Autolock cbLock(&mCallbackLock);
1342
1343 if (mJpegPictureCallback != NULL) {
1344
1345 bool encode_location = true;
1346
1347 #define PARSE_LOCATION(what,type,fmt,desc) do { \
1348 pt.what = 0; \
1349 const char *what##_str = mParameters.get("gps-"#what); \
1350 LOGV("receiveRawPicture: GPS PARM %s --> [%s]", "gps-"#what, what##_str); \
1351 if (what##_str) { \
1352 type what = 0; \
1353 if (sscanf(what##_str, fmt, &what) == 1) \
1354 pt.what = what; \
1355 else { \
1356 LOGE("GPS " #what " %s could not" \
1357 " be parsed as a " #desc, \
1358 what##_str); \
1359 encode_location = false; \
1360 } \
1361 } \
1362 else { \
1363 LOGW("receiveRawPicture: GPS " #what " not specified: " \
1364 "defaulting to zero in EXIF header."); \
1365 encode_location = false; \
1366 } \
1367 } while(0)
1368
1369 PARSE_LOCATION(timestamp, long, "%ld", "long");
1370 if (!pt.timestamp) pt.timestamp = time(NULL);
1371 PARSE_LOCATION(altitude, short, "%hd", "short");
1372 PARSE_LOCATION(latitude, double, "%lf", "double float");
1373 PARSE_LOCATION(longitude, double, "%lf", "double float");
1374
1375 #undef PARSE_LOCATION
1376
1377 if (encode_location) {
1378 LOGV("receiveRawPicture: setting image location ALT %d LAT %lf LON %lf",
1379 pt.altitude, pt.latitude, pt.longitude);
1380 if (LINK_camera_set_position(&pt, NULL, NULL) != CAMERA_SUCCESS) {
1381 LOGE("receiveRawPicture: camera_set_position: error");
1382 /* return; */ // not a big deal
1383 }
1384 }
1385 else LOGV("receiveRawPicture: not setting image location");
1386
1387 mJpegSize = 0;
1388 camera_handle.device = CAMERA_DEVICE_MEM;
1389 camera_handle.mem.encBuf_num = MAX_JPEG_ENCODE_BUF_NUM;
1390
1391 for (int cnt = 0; cnt < MAX_JPEG_ENCODE_BUF_NUM; cnt++) {
1392 camera_handle.mem.encBuf[cnt].buffer = (uint8_t *)
1393 malloc(MAX_JPEG_ENCODE_BUF_LEN);
1394 camera_handle.mem.encBuf[cnt].buf_len =
1395 MAX_JPEG_ENCODE_BUF_LEN;
1396 camera_handle.mem.encBuf[cnt].used_len = 0;
1397 } /* for */
1398
1399 LINK_camera_encode_picture(frame, &camera_handle, camera_cb, this);
1400 }
1401 else {
1402 LOGV("JPEG callback was cancelled--not encoding image.");
1403 // We need to keep the raw heap around until the JPEG is fully
1404 // encoded, because the JPEG encode uses the raw image contained in
1405 // that heap.
1406 mRawHeap = NULL;
1407 }
1408 print_time();
1409 LOGV("receivePostLpmRawPicture: X");
1410 }
1411
1412 void
receiveJpegPictureFragment(JPEGENC_CBrtnType * encInfo)1413 QualcommCameraHardware::receiveJpegPictureFragment(
1414 JPEGENC_CBrtnType *encInfo)
1415 {
1416 camera_encode_mem_type *enc =
1417 (camera_encode_mem_type *)encInfo->outPtr;
1418 int index = enc - camera_handle.mem.encBuf;
1419 uint8_t *base = (uint8_t *)mJpegHeap->mHeap->base();
1420 uint32_t size = encInfo->size;
1421 uint32_t remaining = mJpegHeap->mHeap->virtualSize();
1422 remaining -= mJpegSize;
1423
1424 LOGV("receiveJpegPictureFragment: (index %d status %d size %d)",
1425 index,
1426 encInfo->status,
1427 size);
1428
1429 if (size > remaining) {
1430 LOGE("receiveJpegPictureFragment: size %d exceeds what "
1431 "remains in JPEG heap (%d), truncating",
1432 size,
1433 remaining);
1434 size = remaining;
1435 }
1436
1437 camera_handle.mem.encBuf[index].used_len = 0;
1438 memcpy(base + mJpegSize, enc->buffer, size);
1439 mJpegSize += size;
1440 }
1441
1442 // This method is called by a libqcamera thread, different from the one on
1443 // which startPreview() or takePicture() are called.
1444
1445 void
receiveJpegPicture(void)1446 QualcommCameraHardware::receiveJpegPicture(void)
1447 {
1448 LOGV("receiveJpegPicture: E image (%d bytes out of %d)",
1449 mJpegSize, mJpegHeap->mBufferSize);
1450 print_time();
1451 Mutex::Autolock cbLock(&mCallbackLock);
1452
1453 int index = 0;
1454
1455 if (mJpegPictureCallback) {
1456 // The reason we do not allocate into mJpegHeap->mBuffers[offset] is
1457 // that the JPEG image's size will probably change from one snapshot
1458 // to the next, so we cannot reuse the MemoryBase object.
1459 sp<MemoryBase> buffer = new
1460 MemoryBase(mJpegHeap->mHeap,
1461 index * mJpegHeap->mBufferSize +
1462 mJpegHeap->mFrameOffset,
1463 mJpegSize);
1464
1465 mJpegPictureCallback(buffer, mPictureCallbackCookie);
1466 buffer = NULL;
1467 }
1468 else LOGV("JPEG callback was cancelled--not delivering image.");
1469
1470 // NOTE: the JPEG encoder uses the raw image contained in mRawHeap, so we need
1471 // to keep the heap around until the encoding is complete.
1472 mJpegHeap = NULL;
1473 mRawHeap = NULL;
1474
1475 for (int cnt = 0; cnt < MAX_JPEG_ENCODE_BUF_NUM; cnt++) {
1476 if (camera_handle.mem.encBuf[cnt].buffer != NULL) {
1477 free(camera_handle.mem.encBuf[cnt].buffer);
1478 memset(camera_handle.mem.encBuf + cnt, 0,
1479 sizeof(camera_encode_mem_type));
1480 }
1481 } /* for */
1482
1483 print_time();
1484 LOGV("receiveJpegPicture: X callback done.");
1485 }
1486
1487 struct str_map {
1488 const char *const desc;
1489 int val;
1490 };
1491
1492 static const struct str_map wb_map[] = {
1493 { "auto", CAMERA_WB_AUTO },
1494 { "custom", CAMERA_WB_CUSTOM },
1495 { "incandescent", CAMERA_WB_INCANDESCENT },
1496 { "fluorescent", CAMERA_WB_FLUORESCENT },
1497 { "daylight", CAMERA_WB_DAYLIGHT },
1498 { "cloudy", CAMERA_WB_CLOUDY_DAYLIGHT },
1499 { "twilight", CAMERA_WB_TWILIGHT },
1500 { "shade", CAMERA_WB_SHADE },
1501 { NULL, 0 }
1502 };
1503
1504 static const struct str_map effect_map[] = {
1505 { "off", CAMERA_EFFECT_OFF },
1506 { "mono", CAMERA_EFFECT_MONO },
1507 { "negative", CAMERA_EFFECT_NEGATIVE },
1508 { "solarize", CAMERA_EFFECT_SOLARIZE },
1509 { "pastel", CAMERA_EFFECT_PASTEL },
1510 { "mosaic", CAMERA_EFFECT_MOSAIC },
1511 { "resize", CAMERA_EFFECT_RESIZE },
1512 { "sepia", CAMERA_EFFECT_SEPIA },
1513 { "posterize", CAMERA_EFFECT_POSTERIZE },
1514 { "whiteboard", CAMERA_EFFECT_WHITEBOARD },
1515 { "blackboard", CAMERA_EFFECT_BLACKBOARD },
1516 { "aqua", CAMERA_EFFECT_AQUA },
1517 { NULL, 0 }
1518 };
1519
1520 static const struct str_map brightness_map[] = {
1521 { "0", CAMERA_BRIGHTNESS_0 },
1522 { "1", CAMERA_BRIGHTNESS_1 },
1523 { "2", CAMERA_BRIGHTNESS_2 },
1524 { "3", CAMERA_BRIGHTNESS_3 },
1525 { "4", CAMERA_BRIGHTNESS_4 },
1526 { "5", CAMERA_BRIGHTNESS_5 },
1527 { "6", CAMERA_BRIGHTNESS_6 },
1528 { "7", CAMERA_BRIGHTNESS_7 },
1529 { "8", CAMERA_BRIGHTNESS_8 },
1530 { "9", CAMERA_BRIGHTNESS_9 },
1531 { "10", CAMERA_BRIGHTNESS_10 },
1532 { NULL, 0 }
1533 };
1534
1535 static const struct str_map antibanding_map[] = {
1536 { "off", CAMERA_ANTIBANDING_OFF },
1537 { "50hz", CAMERA_ANTIBANDING_50HZ },
1538 { "60hz", CAMERA_ANTIBANDING_60HZ },
1539 { "auto", CAMERA_ANTIBANDING_AUTO },
1540 { NULL, 0 }
1541 };
1542
1543 static const struct str_map iso_map[] = {
1544 { "auto", CAMERA_ISO_AUTO },
1545 { "high", CAMERA_ISO_HIGH },
1546 { NULL, 0 }
1547 };
1548
lookup(const struct str_map * const arr,const char * name,int def)1549 static int lookup(const struct str_map *const arr, const char *name, int def)
1550 {
1551 if (name) {
1552 const struct str_map * trav = arr;
1553 while (trav->desc) {
1554 if (!strcmp(trav->desc, name))
1555 return trav->val;
1556 trav++;
1557 }
1558 }
1559 return def;
1560 }
1561
initCameraParameters()1562 void QualcommCameraHardware::initCameraParameters()
1563 {
1564 LOGV("initCameraParameters: E");
1565
1566 // Because libqcamera is broken, for the camera_set_parm() calls
1567 // QualcommCameraHardware camera_cb() is called synchronously,
1568 // so we cannot wait on a state change. Also, we have to unlock
1569 // the mStateLock, because camera_cb() acquires it.
1570
1571 startCameraIfNecessary();
1572
1573 #define SET_PARM(x,y) do { \
1574 LOGV("initCameraParameters: set parm: %s, %d", #x, y); \
1575 LINK_camera_set_parm (x, y, NULL, NULL); \
1576 } while(0)
1577
1578 /* Preview Mode: snapshot or movie */
1579 SET_PARM(CAMERA_PARM_PREVIEW_MODE, CAMERA_PREVIEW_MODE_SNAPSHOT);
1580
1581 /* Default Rotation - none */
1582 int rotation = mParameters.getInt("rotation");
1583
1584 // Rotation may be negative, but may not be -1, because it has to be a
1585 // multiple of 90. That's why we can still interpret -1 as an error,
1586 if (rotation == -1) {
1587 LOGV("rotation not specified or is invalid, defaulting to 0");
1588 rotation = 0;
1589 }
1590 else if (rotation % 90) {
1591 LOGE("rotation %d is not a multiple of 90 degrees! Defaulting to zero.",
1592 rotation);
1593 rotation = 0;
1594 }
1595 else {
1596 // normalize to [0 - 270] degrees
1597 rotation %= 360;
1598 if (rotation < 0) rotation += 360;
1599 }
1600
1601 SET_PARM(CAMERA_PARM_ENCODE_ROTATION, rotation);
1602
1603 SET_PARM(CAMERA_PARM_WB,
1604 lookup(wb_map,
1605 mParameters.get("whitebalance"),
1606 CAMERA_WB_AUTO));
1607
1608 SET_PARM(CAMERA_PARM_EFFECT,
1609 lookup(effect_map,
1610 mParameters.get("effect"),
1611 CAMERA_EFFECT_OFF));
1612
1613 SET_PARM(CAMERA_PARM_BRIGHTNESS,
1614 lookup(brightness_map,
1615 mParameters.get("exposure-offset"),
1616 CAMERA_BRIGHTNESS_DEFAULT));
1617
1618 SET_PARM(CAMERA_PARM_ISO,
1619 lookup(iso_map,
1620 mParameters.get("iso"),
1621 CAMERA_ISO_AUTO));
1622
1623 SET_PARM(CAMERA_PARM_ANTIBANDING,
1624 lookup(antibanding_map,
1625 mParameters.get("antibanding"),
1626 CAMERA_ANTIBANDING_AUTO));
1627
1628 int ns_mode = mParameters.getInt("nightshot-mode");
1629 if (ns_mode < 0) ns_mode = 0;
1630 SET_PARM(CAMERA_PARM_NIGHTSHOT_MODE, ns_mode);
1631
1632 int luma_adaptation = mParameters.getInt("luma-adaptation");
1633 if (luma_adaptation < 0) luma_adaptation = 0;
1634 SET_PARM(CAMERA_PARM_LUMA_ADAPTATION, luma_adaptation);
1635
1636 #undef SET_PARM
1637
1638 #if 0
1639 /* Default Auto FPS: 30 (maximum) */
1640 LINK_camera_set_parm_2 (CAMERA_PARM_PREVIEW_FPS,
1641 (1<<16|20), // max frame rate 30
1642 (4<<16|20), // min frame rate 5
1643 NULL,
1644 NULL);
1645 #endif
1646
1647 int th_w, th_h, th_q;
1648 th_w = mParameters.getInt("jpeg-thumbnail-width");
1649 if (th_w < 0) LOGW("property jpeg-thumbnail-width not specified");
1650
1651 th_h = mParameters.getInt("jpeg-thumbnail-height");
1652 if (th_h < 0) LOGW("property jpeg-thumbnail-height not specified");
1653
1654 th_q = mParameters.getInt("jpeg-thumbnail-quality");
1655 if (th_q < 0) LOGW("property jpeg-thumbnail-quality not specified");
1656
1657 if (th_w > 0 && th_h > 0 && th_q > 0) {
1658 LOGI("setting thumbnail dimensions to %dx%d, quality %d",
1659 th_w, th_h, th_q);
1660 int ret = LINK_camera_set_thumbnail_properties(th_w, th_h, th_q);
1661 if (ret != CAMERA_SUCCESS) {
1662 LOGE("LINK_camera_set_thumbnail_properties returned %d", ret);
1663 }
1664 }
1665
1666 #if defined FEATURE_CAMERA_ENCODE_PROPERTIES
1667 /* Set Default JPEG encoding--this does not cause a callback */
1668 encode_properties.quality = mParameters.getInt("jpeg-quality");
1669 if (encode_properties.quality < 0) {
1670 LOGW("JPEG-image quality is not specified "
1671 "or is negative, defaulting to %d",
1672 encode_properties.quality);
1673 encode_properties.quality = 100;
1674 }
1675 else LOGV("Setting JPEG-image quality to %d",
1676 encode_properties.quality);
1677 encode_properties.format = CAMERA_JPEG;
1678 encode_properties.file_size = 0x0;
1679 LINK_camera_set_encode_properties(&encode_properties);
1680 #else
1681 #warning 'FEATURE_CAMERA_ENCODE_PROPERTIES should be enabled!'
1682 #endif
1683
1684
1685 LOGV("initCameraParameters: X");
1686 }
1687
1688 // Called with mStateLock held!
setCameraDimensions()1689 void QualcommCameraHardware::setCameraDimensions()
1690 {
1691 if (mCameraState != QCS_IDLE) {
1692 LOGE("set camera dimensions: expecting state QCS_IDLE, not %s",
1693 getCameraStateStr(mCameraState));
1694 return;
1695 }
1696
1697 LINK_camera_set_dimensions(mRawWidth,
1698 mRawHeight,
1699 mPreviewWidth,
1700 mPreviewHeight,
1701 NULL,
1702 NULL);
1703 }
1704
1705 QualcommCameraHardware::qualcomm_camera_state
change_state(qualcomm_camera_state new_state,bool lock)1706 QualcommCameraHardware::change_state(qualcomm_camera_state new_state,
1707 bool lock)
1708 {
1709 if (lock) mStateLock.lock();
1710 if (new_state != mCameraState) {
1711 // Due to the fact that we allow only one thread at a time to call
1712 // startPreview(), stopPreview(), or takePicture(), we know that
1713 // only one thread at a time may be blocked waiting for a state
1714 // transition on mStateWait. That's why we signal(), not
1715 // broadcast().
1716
1717 LOGV("state transition %s --> %s",
1718 getCameraStateStr(mCameraState),
1719 getCameraStateStr(new_state));
1720
1721 mCameraState = new_state;
1722 mStateWait.signal();
1723 }
1724 if (lock) mStateLock.unlock();
1725 return new_state;
1726 }
1727
1728 #define CAMERA_STATE(n) case n: if(n != CAMERA_FUNC_START_PREVIEW || cb != CAMERA_EVT_CB_FRAME) LOGV("STATE %s // STATUS %d", #n, cb);
1729 #define TRANSITION(e,s) do { \
1730 obj->change_state(obj->mCameraState == e ? s : QCS_ERROR); \
1731 } while(0)
1732 #define TRANSITION_LOCKED(e,s) do { \
1733 obj->change_state((obj->mCameraState == e ? s : QCS_ERROR), false); \
1734 } while(0)
1735 #define TRANSITION_ALWAYS(s) obj->change_state(s)
1736
1737
1738 // 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)1739 void QualcommCameraHardware::stop_camera_cb(camera_cb_type cb,
1740 const void *client_data,
1741 camera_func_type func,
1742 int32_t parm4)
1743 {
1744 QualcommCameraHardware *obj =
1745 (QualcommCameraHardware *)client_data;
1746 switch(func) {
1747 CAMERA_STATE(CAMERA_FUNC_STOP)
1748 TRANSITION(QCS_INTERNAL_STOPPING, QCS_INIT);
1749 break;
1750 default:
1751 break;
1752 }
1753 }
1754
camera_cb(camera_cb_type cb,const void * client_data,camera_func_type func,int32_t parm4)1755 void QualcommCameraHardware::camera_cb(camera_cb_type cb,
1756 const void *client_data,
1757 camera_func_type func,
1758 int32_t parm4)
1759 {
1760 QualcommCameraHardware *obj =
1761 (QualcommCameraHardware *)client_data;
1762
1763 // Promote the singleton to make sure that we do not get destroyed
1764 // while this callback is executing.
1765 if (UNLIKELY(getInstance() == NULL)) {
1766 LOGE("camera object has been destroyed--returning immediately");
1767 return;
1768 }
1769
1770 if (cb == CAMERA_EXIT_CB_ABORT || /* Function aborted */
1771 cb == CAMERA_EXIT_CB_DSP_ABORT || /* Abort due to DSP failure */
1772 cb == CAMERA_EXIT_CB_ERROR || /* Failed due to resource */
1773 cb == CAMERA_EXIT_CB_FAILED) /* Execution failed or rejected */
1774 {
1775 // Autofocus failures occur relatively often and are not fatal, so
1776 // we do not transition to QCS_ERROR for them.
1777 if (func != CAMERA_FUNC_START_FOCUS) {
1778 LOGE("QualcommCameraHardware::camera_cb: @CAMERA_EXIT_CB_FAILURE(%d) in state %s.",
1779 parm4,
1780 obj->getCameraStateStr(obj->mCameraState));
1781 TRANSITION_ALWAYS(QCS_ERROR);
1782 }
1783 }
1784
1785 switch(func) {
1786 // This is the commonest case.
1787 CAMERA_STATE(CAMERA_FUNC_START_PREVIEW)
1788 switch(cb) {
1789 case CAMERA_RSP_CB_SUCCESS:
1790 TRANSITION(QCS_INTERNAL_PREVIEW_REQUESTED,
1791 QCS_PREVIEW_IN_PROGRESS);
1792 break;
1793 case CAMERA_EVT_CB_FRAME:
1794 switch (obj->mCameraState) {
1795 case QCS_PREVIEW_IN_PROGRESS:
1796 if (parm4)
1797 obj->receivePreviewFrame((camera_frame_type *)parm4);
1798 break;
1799 case QCS_INTERNAL_PREVIEW_STOPPING:
1800 LOGE("camera cb: discarding preview frame "
1801 "while stopping preview");
1802 break;
1803 default:
1804 // transition to QCS_ERROR
1805 LOGE("camera cb: invalid state %s for preview!",
1806 obj->getCameraStateStr(obj->mCameraState));
1807 break;
1808 }
1809 /* -- this function is called now inside of receivePreviewFrame.
1810 LINK_camera_release_frame();
1811 */
1812 break;
1813 default:
1814 // transition to QCS_ERROR
1815 LOGE("unexpected cb %d for CAMERA_FUNC_START_PREVIEW.",
1816 cb);
1817 }
1818 break;
1819 CAMERA_STATE(CAMERA_FUNC_START)
1820 TRANSITION(QCS_INIT, QCS_IDLE);
1821 break;
1822 /* -- this case handled in stop_camera_cb() now.
1823 CAMERA_STATE(CAMERA_FUNC_STOP)
1824 TRANSITION(QCS_INTERNAL_STOPPING, QCS_INIT);
1825 break;
1826 */
1827 CAMERA_STATE(CAMERA_FUNC_STOP_PREVIEW)
1828 TRANSITION(QCS_INTERNAL_PREVIEW_STOPPING,
1829 QCS_IDLE);
1830 break;
1831 CAMERA_STATE(CAMERA_FUNC_TAKE_PICTURE)
1832 if (cb == CAMERA_RSP_CB_SUCCESS) {
1833 TRANSITION(QCS_INTERNAL_RAW_REQUESTED,
1834 QCS_WAITING_RAW);
1835 }
1836 else if (cb == CAMERA_EVT_CB_SNAPSHOT_DONE) {
1837 obj->notifyShutter();
1838 // Received pre-LPM raw picture. Notify callback now.
1839 obj->receiveRawPicture((camera_frame_type *)parm4);
1840 }
1841 else if (cb == CAMERA_EXIT_CB_DONE) {
1842 // It's important that we call receiveRawPicture() before
1843 // we transition the state because another thread may be
1844 // waiting in cancelPicture(), and then delete this object.
1845 // If the order were reversed, we might call
1846 // receiveRawPicture on a dead object.
1847 LOGV("Receiving post LPM raw picture.");
1848 obj->receivePostLpmRawPicture((camera_frame_type *)parm4);
1849 {
1850 Mutex::Autolock lock(&obj->mStateLock);
1851 TRANSITION_LOCKED(QCS_WAITING_RAW,
1852 obj->mJpegPictureCallback != NULL ?
1853 QCS_WAITING_JPEG :
1854 QCS_IDLE);
1855 }
1856 } else { // transition to QCS_ERROR
1857 if (obj->mCameraState == QCS_ERROR) {
1858 LOGE("camera cb: invalid state %s for taking a picture!",
1859 obj->getCameraStateStr(obj->mCameraState));
1860 obj->mRawPictureCallback(NULL, obj->mPictureCallbackCookie);
1861 obj->mJpegPictureCallback(NULL, obj->mPictureCallbackCookie);
1862 TRANSITION_ALWAYS(QCS_IDLE);
1863 }
1864 }
1865 break;
1866 CAMERA_STATE(CAMERA_FUNC_ENCODE_PICTURE)
1867 switch (cb) {
1868 case CAMERA_RSP_CB_SUCCESS:
1869 // We already transitioned the camera state to
1870 // QCS_WAITING_JPEG when we called
1871 // camera_encode_picture().
1872 break;
1873 case CAMERA_EXIT_CB_BUFFER:
1874 if (obj->mCameraState == QCS_WAITING_JPEG) {
1875 obj->receiveJpegPictureFragment(
1876 (JPEGENC_CBrtnType *)parm4);
1877 }
1878 else LOGE("camera cb: invalid state %s for receiving "
1879 "JPEG fragment!",
1880 obj->getCameraStateStr(obj->mCameraState));
1881 break;
1882 case CAMERA_EXIT_CB_DONE:
1883 if (obj->mCameraState == QCS_WAITING_JPEG) {
1884 // Receive the last fragment of the image.
1885 obj->receiveJpegPictureFragment(
1886 (JPEGENC_CBrtnType *)parm4);
1887
1888 // The size of the complete JPEG image is in
1889 // mJpegSize.
1890
1891 // It's important that we call receiveJpegPicture()
1892 // before we transition the state because another
1893 // thread may be waiting in cancelPicture(), and then
1894 // delete this object. If the order were reversed, we
1895 // might call receiveRawPicture on a dead object.
1896
1897 obj->receiveJpegPicture();
1898
1899 TRANSITION(QCS_WAITING_JPEG, QCS_IDLE);
1900 }
1901 // transition to QCS_ERROR
1902 else LOGE("camera cb: invalid state %s for "
1903 "receiving JPEG!",
1904 obj->getCameraStateStr(obj->mCameraState));
1905 break;
1906 default:
1907 // transition to QCS_ERROR
1908 LOGE("camera cb: unknown cb %d for JPEG!", cb);
1909 }
1910 break;
1911 CAMERA_STATE(CAMERA_FUNC_START_FOCUS) {
1912 // NO TRANSITION HERE. We acquire mStateLock here because it is
1913 // possible for ::autoFocus to be called after the call to
1914 // mAutoFocusCallback() but before we set mAutoFocusCallback
1915 // to NULL.
1916 if (obj->mAutoFocusCallback) {
1917 switch (cb) {
1918 case CAMERA_RSP_CB_SUCCESS:
1919 LOGV("camera cb: autofocus has started.");
1920 break;
1921 case CAMERA_EXIT_CB_DONE: {
1922 LOGV("camera cb: autofocus succeeded.");
1923 Mutex::Autolock lock(&obj->mStateLock);
1924 if (obj->mAutoFocusCallback) {
1925 obj->mAutoFocusCallback(true,
1926 obj->mAutoFocusCallbackCookie);
1927 obj->mAutoFocusCallback = NULL;
1928 }
1929 }
1930 break;
1931 case CAMERA_EXIT_CB_ABORT:
1932 LOGE("camera cb: autofocus aborted");
1933 break;
1934 case CAMERA_EXIT_CB_FAILED: {
1935 LOGE("camera cb: autofocus failed");
1936 Mutex::Autolock lock(&obj->mStateLock);
1937 if (obj->mAutoFocusCallback) {
1938 obj->mAutoFocusCallback(false,
1939 obj->mAutoFocusCallbackCookie);
1940 obj->mAutoFocusCallback = NULL;
1941 }
1942 }
1943 break;
1944 default:
1945 LOGE("camera cb: unknown cb %d for "
1946 "CAMERA_FUNC_START_FOCUS!", cb);
1947 }
1948 }
1949 } break;
1950 default:
1951 // transition to QCS_ERROR
1952 LOGE("Unknown camera-callback status %d", cb);
1953 }
1954 }
1955
1956 #undef TRANSITION
1957 #undef TRANSITION_LOCKED
1958 #undef TRANSITION_ALWAYS
1959 #undef CAMERA_STATE
1960
clp2(unsigned x)1961 static unsigned clp2(unsigned x) {
1962 x = x - 1;
1963 x = x | (x >> 1);
1964 x = x | (x >> 2);
1965 x = x | (x >> 4);
1966 x = x | (x >> 8);
1967 x = x | (x >>16);
1968 return x + 1;
1969 }
1970
MemPool(int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)1971 QualcommCameraHardware::MemPool::MemPool(int buffer_size, int num_buffers,
1972 int frame_size,
1973 int frame_offset,
1974 const char *name) :
1975 mBufferSize(buffer_size),
1976 mNumBuffers(num_buffers),
1977 mFrameSize(frame_size),
1978 mFrameOffset(frame_offset),
1979 mBuffers(NULL), mName(name)
1980 {
1981 // empty
1982 }
1983
completeInitialization()1984 void QualcommCameraHardware::MemPool::completeInitialization()
1985 {
1986 // If we do not know how big the frame will be, we wait to allocate
1987 // the buffers describing the individual frames until we do know their
1988 // size.
1989
1990 if (mFrameSize > 0) {
1991 mBuffers = new sp<MemoryBase>[mNumBuffers];
1992 for (int i = 0; i < mNumBuffers; i++) {
1993 mBuffers[i] = new
1994 MemoryBase(mHeap,
1995 i * mBufferSize + mFrameOffset,
1996 mFrameSize);
1997 }
1998 }
1999 }
2000
AshmemPool(int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2001 QualcommCameraHardware::AshmemPool::AshmemPool(int buffer_size, int num_buffers,
2002 int frame_size,
2003 int frame_offset,
2004 const char *name) :
2005 QualcommCameraHardware::MemPool(buffer_size,
2006 num_buffers,
2007 frame_size,
2008 frame_offset,
2009 name)
2010 {
2011 LOGV("constructing MemPool %s backed by ashmem: "
2012 "%d frames @ %d bytes, offset %d, "
2013 "buffer size %d",
2014 mName,
2015 num_buffers, frame_size, frame_offset, buffer_size);
2016
2017 int page_mask = getpagesize() - 1;
2018 int ashmem_size = buffer_size * num_buffers;
2019 ashmem_size += page_mask;
2020 ashmem_size &= ~page_mask;
2021
2022 mHeap = new MemoryHeapBase(ashmem_size);
2023
2024 completeInitialization();
2025 }
2026
PmemPool(const char * pmem_pool,int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2027 QualcommCameraHardware::PmemPool::PmemPool(const char *pmem_pool,
2028 int buffer_size, int num_buffers,
2029 int frame_size,
2030 int frame_offset,
2031 const char *name) :
2032 QualcommCameraHardware::MemPool(buffer_size,
2033 num_buffers,
2034 frame_size,
2035 frame_offset,
2036 name)
2037 {
2038 LOGV("constructing MemPool %s backed by pmem pool %s: "
2039 "%d frames @ %d bytes, offset %d, buffer size %d",
2040 mName,
2041 pmem_pool, num_buffers, frame_size, frame_offset,
2042 buffer_size);
2043
2044 // Make a new mmap'ed heap that can be shared across processes.
2045
2046 mAlignedSize = clp2(buffer_size * num_buffers);
2047
2048 sp<MemoryHeapBase> masterHeap =
2049 new MemoryHeapBase(pmem_pool, mAlignedSize, 0);
2050 sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, 0);
2051 if (pmemHeap->getHeapID() >= 0) {
2052 pmemHeap->slap();
2053 masterHeap.clear();
2054 mHeap = pmemHeap;
2055 pmemHeap.clear();
2056
2057 mFd = mHeap->getHeapID();
2058 if (::ioctl(mFd, PMEM_GET_SIZE, &mSize)) {
2059 LOGE("pmem pool %s ioctl(PMEM_GET_SIZE) error %s (%d)",
2060 pmem_pool,
2061 ::strerror(errno), errno);
2062 mHeap.clear();
2063 return;
2064 }
2065
2066 LOGV("pmem pool %s ioctl(PMEM_GET_SIZE) is %ld",
2067 pmem_pool,
2068 mSize.len);
2069
2070 completeInitialization();
2071 }
2072 else LOGE("pmem pool %s error: could not create master heap!",
2073 pmem_pool);
2074 }
2075
PreviewPmemPool(int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2076 QualcommCameraHardware::PreviewPmemPool::PreviewPmemPool(
2077 int buffer_size, int num_buffers,
2078 int frame_size,
2079 int frame_offset,
2080 const char *name) :
2081 QualcommCameraHardware::PmemPool("/dev/pmem_adsp",
2082 buffer_size,
2083 num_buffers,
2084 frame_size,
2085 frame_offset,
2086 name)
2087 {
2088 LOGV("constructing PreviewPmemPool");
2089 if (initialized()) {
2090 LINK_camera_assoc_pmem(QDSP_MODULE_VFETASK,
2091 mFd,
2092 mHeap->base(),
2093 mAlignedSize,
2094 0); // external
2095 }
2096 }
2097
~PreviewPmemPool()2098 QualcommCameraHardware::PreviewPmemPool::~PreviewPmemPool()
2099 {
2100 LOGV("destroying PreviewPmemPool");
2101 if(initialized()) {
2102 void *base = mHeap->base();
2103 LOGV("releasing PreviewPmemPool memory %p from module %d",
2104 base, QDSP_MODULE_VFETASK);
2105 LINK_camera_release_pmem(QDSP_MODULE_VFETASK, base,
2106 mAlignedSize,
2107 true);
2108 }
2109 }
2110
RawPmemPool(const char * pmem_pool,int buffer_size,int num_buffers,int frame_size,int frame_offset,const char * name)2111 QualcommCameraHardware::RawPmemPool::RawPmemPool(
2112 const char *pmem_pool,
2113 int buffer_size, int num_buffers,
2114 int frame_size,
2115 int frame_offset,
2116 const char *name) :
2117 QualcommCameraHardware::PmemPool(pmem_pool,
2118 buffer_size,
2119 num_buffers,
2120 frame_size,
2121 frame_offset,
2122 name)
2123 {
2124 LOGV("constructing RawPmemPool");
2125
2126 if (initialized()) {
2127 LINK_camera_assoc_pmem(QDSP_MODULE_VFETASK,
2128 mFd,
2129 mHeap->base(),
2130 mAlignedSize,
2131 0); // do not free, main module
2132 LINK_camera_assoc_pmem(QDSP_MODULE_LPMTASK,
2133 mFd,
2134 mHeap->base(),
2135 mAlignedSize,
2136 2); // do not free, dependent module
2137 LINK_camera_assoc_pmem(QDSP_MODULE_JPEGTASK,
2138 mFd,
2139 mHeap->base(),
2140 mAlignedSize,
2141 2); // do not free, dependent module
2142 }
2143 }
2144
~RawPmemPool()2145 QualcommCameraHardware::RawPmemPool::~RawPmemPool()
2146 {
2147 LOGV("destroying RawPmemPool");
2148 if(initialized()) {
2149 void *base = mHeap->base();
2150 LOGV("releasing RawPmemPool memory %p from modules %d, %d, and %d",
2151 base, QDSP_MODULE_VFETASK, QDSP_MODULE_LPMTASK,
2152 QDSP_MODULE_JPEGTASK);
2153 LINK_camera_release_pmem(QDSP_MODULE_VFETASK,
2154 base, mAlignedSize, true);
2155 LINK_camera_release_pmem(QDSP_MODULE_LPMTASK,
2156 base, mAlignedSize, true);
2157 LINK_camera_release_pmem(QDSP_MODULE_JPEGTASK,
2158 base, mAlignedSize, true);
2159 }
2160 }
2161
~MemPool()2162 QualcommCameraHardware::MemPool::~MemPool()
2163 {
2164 LOGV("destroying MemPool %s", mName);
2165 if (mFrameSize > 0)
2166 delete [] mBuffers;
2167 mHeap.clear();
2168 LOGV("destroying MemPool %s completed", mName);
2169 }
2170
dump(int fd,const Vector<String16> & args) const2171 status_t QualcommCameraHardware::MemPool::dump(int fd, const Vector<String16>& args) const
2172 {
2173 const size_t SIZE = 256;
2174 char buffer[SIZE];
2175 String8 result;
2176 snprintf(buffer, 255, "QualcommCameraHardware::AshmemPool::dump\n");
2177 result.append(buffer);
2178 if (mName) {
2179 snprintf(buffer, 255, "mem pool name (%s)\n", mName);
2180 result.append(buffer);
2181 }
2182 if (mHeap != 0) {
2183 snprintf(buffer, 255, "heap base(%p), size(%d), flags(%d), device(%s)\n",
2184 mHeap->getBase(), mHeap->getSize(),
2185 mHeap->getFlags(), mHeap->getDevice());
2186 result.append(buffer);
2187 }
2188 snprintf(buffer, 255, "buffer size (%d), number of buffers (%d),"
2189 " frame size(%d), and frame offset(%d)\n",
2190 mBufferSize, mNumBuffers, mFrameSize, mFrameOffset);
2191 result.append(buffer);
2192 write(fd, result.string(), result.size());
2193 return NO_ERROR;
2194 }
2195
malloc_preview(uint32_t size,uint32_t * phy_addr,uint32_t index)2196 static uint8_t* malloc_preview(uint32_t size,
2197 uint32_t *phy_addr, uint32_t index)
2198 {
2199 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2200 if (obj != 0) {
2201 return (uint8_t *)obj->get_preview_mem(size, phy_addr, index);
2202 }
2203 return NULL;
2204 }
2205
free_preview(uint32_t * phy_addr,uint32_t size,uint32_t index)2206 static int free_preview(uint32_t *phy_addr, uint32_t size,
2207 uint32_t index)
2208 {
2209 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2210 if (obj != 0) {
2211 obj->free_preview_mem(phy_addr, size, index);
2212 }
2213 return 0;
2214 }
2215
malloc_raw(uint32_t size,uint32_t * phy_addr,uint32_t index)2216 static uint8_t* malloc_raw(uint32_t size,
2217 uint32_t *phy_addr,
2218 uint32_t index)
2219 {
2220 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2221 if (obj != 0) {
2222 return (uint8_t *)obj->get_raw_mem(size, phy_addr, index);
2223 }
2224 return NULL;
2225 }
2226
free_raw(uint32_t * phy_addr,uint32_t size,uint32_t index)2227 static int free_raw(uint32_t *phy_addr,
2228 uint32_t size,
2229 uint32_t index)
2230 {
2231 sp<QualcommCameraHardware> obj = QualcommCameraHardware::getInstance();
2232 if (obj != 0) {
2233 obj->free_raw_mem(phy_addr, size, index);
2234 }
2235 return 0;
2236 }
2237
cb_rex_signal_ready(void)2238 static void cb_rex_signal_ready(void)
2239 {
2240 LOGV("Received REX-ready signal.");
2241 rex_init_lock.lock();
2242 rex_init_wait.broadcast();
2243 rex_init_lock.unlock();
2244 }
2245
getCameraStateStr(QualcommCameraHardware::qualcomm_camera_state s)2246 const char* const QualcommCameraHardware::getCameraStateStr(
2247 QualcommCameraHardware::qualcomm_camera_state s)
2248 {
2249 static const char* states[] = {
2250 #define STATE_STR(x) #x
2251 STATE_STR(QCS_INIT),
2252 STATE_STR(QCS_IDLE),
2253 STATE_STR(QCS_ERROR),
2254 STATE_STR(QCS_PREVIEW_IN_PROGRESS),
2255 STATE_STR(QCS_WAITING_RAW),
2256 STATE_STR(QCS_WAITING_JPEG),
2257 STATE_STR(QCS_INTERNAL_PREVIEW_STOPPING),
2258 STATE_STR(QCS_INTERNAL_PREVIEW_REQUESTED),
2259 STATE_STR(QCS_INTERNAL_RAW_REQUESTED),
2260 STATE_STR(QCS_INTERNAL_STOPPING),
2261 #undef STATE_STR
2262 };
2263 return states[s];
2264 }
2265
2266 }; // namespace android
2267