• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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", &params);
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