Home | History | Annotate | Download | only in libcamera
      1 /*
      2 ** Copyright 2008, The Android Open-Source Project
      3 **
      4 ** Licensed under the Apache License, Version 2.0 (the "License");
      5 ** you may not use this file except in compliance with the License.
      6 ** You may obtain a copy of the License at
      7 **
      8 **     http://www.apache.org/licenses/LICENSE-2.0
      9 **
     10 ** Unless required by applicable law or agreed to in writing, software
     11 ** distributed under the License is distributed on an "AS IS" BASIS,
     12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ** See the License for the specific language governing permissions and
     14 ** limitations under the License.
     15 */
     16 
     17 // TODO
     18 // -- replace Condition::wait with Condition::waitRelative
     19 // -- use read/write locks
     20 
     21 #define LOG_NDEBUG 0
     22 #define LOG_TAG "QualcommCameraHardware"
     23 #include <utils/Log.h>
     24 #include <utils/threads.h>
     25 #include <binder/MemoryHeapPmem.h>
     26 #include <utils/String16.h>
     27 #include <sys/types.h>
     28 #include <sys/stat.h>
     29 #include <sys/ioctl.h>
     30 #include <sys/mman.h>
     31 #include <sys/time.h>
     32 #include <time.h>
     33 #include <fcntl.h>
     34 #include <unistd.h>
     35 #if HAVE_ANDROID_OS
     36 #include <linux/android_pmem.h>
     37 #endif
     38 #include <camera_ifc.h>
     39 #if DLOPEN_LIBQCAMERA
     40 #include <dlfcn.h>
     41 #endif
     42 
     43 #define PRINT_TIME 0
     44 
     45 extern "C" {
     46 
     47 static inline void print_time()
     48 {
     49 #if PRINT_TIME
     50     struct timeval time;
     51     gettimeofday(&time, NULL);
     52     ALOGV("time: %lld us.", time.tv_sec * 1000000LL + time.tv_usec);
     53 #endif
     54 }
     55 
     56 typedef struct {
     57     int width;
     58     int height;
     59 } preview_size_type;
     60 
     61 // These sizes have to be a multiple of 16 in each dimension
     62 static preview_size_type preview_sizes[] = {
     63     { 480, 320 }, // HVGA
     64     { 432, 320 }, // 1.35-to-1, for photos. (Rounded up from 1.3333 to 1)
     65     { 352, 288 }, // CIF
     66     { 320, 240 }, // QVGA
     67     { 240, 160 }, // SQVGA
     68     { 176, 144 }, // QCIF
     69 };
     70 #define PREVIEW_SIZE_COUNT (sizeof(preview_sizes)/sizeof(preview_size_type))
     71 
     72 // default preview size is QVGA
     73 #define DEFAULT_PREVIEW_SETTING 0
     74 
     75 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
     76 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
     77 
     78     /* some functions we need from libqcamera */
     79     extern void rex_start();
     80     extern void rex_shutdown();
     81 
     82     /* callbacks */
     83 #if DLOPEN_LIBQCAMERA == 0
     84     extern void (*rex_signal_ready)();
     85     extern uint8_t* (*cam_mmap_preview)(uint32_t size,
     86                                                  uint32_t *phy_addr,
     87                                                  uint32_t index);
     88     extern uint8_t* (*cam_mmap_snapshot)(uint32_t size,
     89                                                  uint32_t *phy_addr,
     90                                                  uint32_t index);
     91     extern int (*cam_munmap_preview)(uint32_t *phy_addr,
     92                                      uint32_t size,
     93                                      uint32_t index);
     94     extern int (*cam_munmap_snapshot)(uint32_t *phy_addr,
     95                                       uint32_t size,
     96                                       uint32_t index);
     97 
     98     extern clear_module_pmem(qdsp_module_type module);
     99 
    100     extern void camera_assoc_pmem(qdsp_module_type module,
    101                                   int pmem_fd,
    102                                   void *addr,
    103                                   uint32_t length,
    104                                   int external);
    105 
    106     extern int camera_release_pmem(qdsp_module_type module,
    107                                    void *addr,
    108                                    uint32_t size,
    109                                    uint32_t force);
    110 
    111 #define LINK_camera_assoc_pmem             camera_assoc_pmem
    112 #define LINK_clear_module_pmem             clear_module_pmem
    113 #define LINK_camera_release_pmem           camera_release_pmem
    114 #define LINK_camera_encode_picture         camera_encode_picture
    115 #define LINK_camera_init                   camera_init
    116 #define LINK_camera_af_init                camera_af_init
    117 #define LINK_camera_release_frame          camera_release_frame
    118 #define LINK_camera_set_dimensions         camera_set_dimensions
    119 #define LINK_camera_set_encode_properties  camera_set_encode_properties
    120 #define LINK_camera_set_parm               camera_set_parm
    121 #define LINK_camera_set_parm_2             camera_set_parm_2
    122 #define LINK_camera_set_position           camera_set_position
    123 #define LINK_camera_set_thumbnail_properties camera_set_thumbnail_properties
    124 #define LINK_camera_start                  camera_start
    125 #define LINK_camera_start_preview          camera_start_preview
    126 #define LINK_camera_start_focus            camera_start_focus
    127 #define LINK_camera_stop_focus             camera_stop_focus
    128 #define LINK_camera_stop                   camera_stop
    129 #define LINK_camera_stop_preview           camera_stop_preview
    130 #define LINK_camera_take_picture           camera_take_picture
    131 #define LINK_rex_shutdown                  rex_shutdown
    132 #define LINK_rex_start                     rex_start
    133 #define LINK_rex_signal_ready              rex_signal_ready
    134 
    135 #define LINK_cam_mmap_preview   cam_mmap_preview
    136 #define LINK_cam_munmap_preview cam_munmap_preview
    137 #define LINK_cam_mmap_snapshot  cam_mmap_snapshot
    138 #define LINK_cam_munmap_snapshot cam_munmap_snapshot
    139 
    140 #else
    141 
    142     /* Function pointers to assign to */
    143 
    144     void (**LINK_rex_signal_ready)();
    145 
    146     uint8_t* (**LINK_cam_mmap_preview)(
    147         uint32_t size,
    148         uint32_t *phy_addr,
    149         uint32_t index);
    150 
    151     int (**LINK_cam_munmap_preview)(
    152         uint32_t *phy_addr,
    153         uint32_t size,
    154         uint32_t index);
    155 
    156     uint8_t* (**LINK_cam_mmap_snapshot)(
    157         uint32_t size,
    158         uint32_t *phy_addr,
    159         uint32_t index);
    160 
    161     int (**LINK_cam_munmap_snapshot)(
    162         uint32_t *phy_addr,
    163         uint32_t size,
    164         uint32_t index);
    165 
    166     /* Function pointers to resolve */
    167 
    168     void (*LINK_camera_assoc_pmem)(qdsp_module_type module,
    169                                    int pmem_fd,
    170                                    void *addr,
    171                                    uint32_t length,
    172                                    int external);
    173 
    174     void (*LINK_clear_module_pmem)(qdsp_module_type module);
    175 
    176     int (*LINK_camera_release_pmem)(qdsp_module_type module,
    177                                     void *addr,
    178                                     uint32_t size,
    179                                     uint32_t force);
    180 
    181     camera_ret_code_type (*LINK_camera_encode_picture) (
    182         camera_frame_type *frame,
    183         camera_handle_type *handle,
    184         camera_cb_f_type callback,
    185         void *client_data);
    186 
    187     void (*LINK_camera_init)(void);
    188 
    189     void (*LINK_camera_af_init)(void);
    190 
    191     camera_ret_code_type (*LINK_camera_release_frame)(void);
    192 
    193     camera_ret_code_type (*LINK_camera_set_dimensions) (
    194         uint16_t picture_width,
    195         uint16_t picture_height,
    196         uint16_t display_width,
    197 #ifdef FEATURE_CAMERA_V7
    198         uint16_t display_height,
    199 #endif
    200         camera_cb_f_type callback,
    201         void *client_data);
    202 
    203     camera_ret_code_type (*LINK_camera_set_encode_properties)(
    204         camera_encode_properties_type *encode_properties);
    205 
    206     camera_ret_code_type (*LINK_camera_set_parm) (
    207         camera_parm_type id,
    208         int32_t          parm,
    209         camera_cb_f_type callback,
    210         void            *client_data);
    211 
    212     camera_ret_code_type (*LINK_camera_set_parm_2) (
    213         camera_parm_type id,
    214         int32_t          parm1,
    215         int32_t          parm2,
    216         camera_cb_f_type callback,
    217         void            *client_data);
    218 
    219     camera_ret_code_type (*LINK_camera_set_position) (
    220         camera_position_type *position,
    221         camera_cb_f_type      callback,
    222         void                 *client_data);
    223 
    224     camera_ret_code_type (*LINK_camera_set_thumbnail_properties) (
    225                               uint32_t width,
    226                               uint32_t height,
    227                               uint32_t quality);
    228 
    229     camera_ret_code_type (*LINK_camera_start) (
    230         camera_cb_f_type callback,
    231         void *client_data
    232 #ifdef FEATURE_NATIVELINUX
    233         ,int  display_height,
    234         int  display_width
    235 #endif /* FEATURE_NATIVELINUX */
    236         );
    237 
    238     camera_ret_code_type (*LINK_camera_start_preview) (
    239         camera_cb_f_type callback,
    240         void *client_data);
    241 
    242     camera_ret_code_type (*LINK_camera_start_focus) (
    243         camera_focus_e_type focus,
    244         camera_cb_f_type callback,
    245         void *client_data);
    246 
    247     camera_ret_code_type (*LINK_camera_stop_focus) (void);
    248 
    249     camera_ret_code_type (*LINK_camera_stop) (
    250         camera_cb_f_type callback,
    251         void *client_data);
    252 
    253     camera_ret_code_type (*LINK_camera_stop_preview) (void);
    254 
    255     camera_ret_code_type (*LINK_camera_take_picture) (
    256         camera_cb_f_type    callback,
    257         void               *client_data
    258 #if !defined FEATURE_CAMERA_ENCODE_PROPERTIES && defined FEATURE_CAMERA_V7
    259         ,camera_raw_type camera_raw_mode
    260 #endif /* nFEATURE_CAMERA_ENCODE_PROPERTIES && FEATURE_CAMERA_V7 */
    261         );
    262 
    263     int (*LINK_rex_start)(void);
    264 
    265     int (*LINK_rex_shutdown)(void);
    266 
    267 #endif
    268 
    269 }
    270 
    271 #include "QualcommCameraHardware.h"
    272 
    273 namespace android {
    274 
    275     static Mutex singleton_lock;
    276     static Mutex rex_init_lock;
    277     static Condition rex_init_wait;
    278 
    279     static uint8_t* malloc_preview(uint32_t, uint32_t *, uint32_t);
    280     static uint8_t* malloc_raw(uint32_t, uint32_t *, uint32_t);
    281     static int free_preview(uint32_t *, uint32_t , uint32_t);
    282     static int free_raw(uint32_t *, uint32_t , uint32_t);
    283     static int reassoc(qdsp_module_type module);
    284     static void cb_rex_signal_ready(void);
    285 
    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