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