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
45extern "C" {
46
47static 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
56typedef 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
62static 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
273namespace 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
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
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!
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
477    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
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
544    void QualcommCameraHardware::deinitPreview()
545    {
546        mPreviewHeap = NULL;
547    }
548
549    // Called with mStateLock held!
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
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
666    QualcommCameraHardware::~QualcommCameraHardware()
667    {
668        ALOGV("~QualcommCameraHardware E");
669        Mutex::Autolock singletonLock(&singleton_lock);
670        singleton.clear();
671        ALOGV("~QualcommCameraHardware X");
672    }
673
674    sp<IMemoryHeap> QualcommCameraHardware::getPreviewHeap() const
675    {
676        ALOGV("getPreviewHeap");
677        return mPreviewHeap != NULL ? mPreviewHeap->mHeap : NULL;
678    }
679
680    sp<IMemoryHeap> QualcommCameraHardware::getRawHeap() const
681    {
682        return mRawHeap != NULL ? mRawHeap->mHeap : NULL;
683    }
684
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
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
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
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
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
824    bool QualcommCameraHardware::previewEnabled() {
825        Mutex::Autolock l(&mLock);
826        return mCameraState == QCS_PREVIEW_IN_PROGRESS;
827    }
828
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
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
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
858    void QualcommCameraHardware::releaseRecordingFrame(
859        const sp<IMemory>& mem __attribute__((unused)))
860    {
861        Mutex::Autolock l(&mLock);
862        LINK_camera_release_frame();
863    }
864
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
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
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
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
1075    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
1088    extern "C" int HAL_getNumberOfCameras()
1089    {
1090        return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
1091    }
1092
1093    extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
1094    {
1095        memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
1096    }
1097
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.
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.
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
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
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
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
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
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
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.
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
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
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
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
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
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!
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
2188    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
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
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
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
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
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
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