Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28  /*#error uncomment this for compiler test!*/
     29 //#define ALOG_NDEBUG 0
     30 #define ALOG_NIDEBUG 0
     31 #define LOG_TAG "QualcommUsbCamera"
     32 
     33 #include <utils/Log.h>
     34 #include <utils/threads.h>
     35 #include <fcntl.h>
     36 #include <sys/mman.h>
     37 #include <sys/stat.h>
     38 #include <unistd.h>
     39 #include <sys/prctl.h>
     40 #include <sys/resource.h>
     41 #include <pthread.h>
     42 #include <linux/uvcvideo.h>
     43 
     44 #include "QCameraHAL.h"
     45 #include "QualcommUsbCamera.h"
     46 #include "QCameraUsbPriv.h"
     47 #include "QCameraMjpegDecode.h"
     48 #include "QCameraUsbParm.h"
     49 #include <gralloc_priv.h>
     50 #include <genlock.h>
     51 
     52 extern "C" {
     53 #include <sys/time.h>
     54 }
     55 
     56 camera_device_ops_t usbcam_camera_ops = {
     57   set_preview_window:         android::usbcam_set_preview_window,
     58   set_callbacks:              android::usbcam_set_CallBacks,
     59   enable_msg_type:            android::usbcam_enable_msg_type,
     60   disable_msg_type:           android::usbcam_disable_msg_type,
     61   msg_type_enabled:           android::usbcam_msg_type_enabled,
     62 
     63   start_preview:              android::usbcam_start_preview,
     64   stop_preview:               android::usbcam_stop_preview,
     65   preview_enabled:            android::usbcam_preview_enabled,
     66   store_meta_data_in_buffers: android::usbcam_store_meta_data_in_buffers,
     67 
     68   start_recording:            android::usbcam_start_recording,
     69   stop_recording:             android::usbcam_stop_recording,
     70   recording_enabled:          android::usbcam_recording_enabled,
     71   release_recording_frame:    android::usbcam_release_recording_frame,
     72 
     73   auto_focus:                 android::usbcam_auto_focus,
     74   cancel_auto_focus:          android::usbcam_cancel_auto_focus,
     75 
     76   take_picture:               android::usbcam_take_picture,
     77   cancel_picture:             android::usbcam_cancel_picture,
     78 
     79   set_parameters:             android::usbcam_set_parameters,
     80   get_parameters:             android::usbcam_get_parameters,
     81   put_parameters:             android::usbcam_put_parameters,
     82   send_command:               android::usbcam_send_command,
     83 
     84   release:                    android::usbcam_release,
     85   dump:                       android::usbcam_dump,
     86 };
     87 
     88 #define CAPTURE                 1
     89 #define DISPLAY                 1
     90 #define CALL_BACK               1
     91 #define MEMSET                  0
     92 #define FREAD_JPEG_PICTURE      0
     93 #define JPEG_ON_USB_CAMERA      1
     94 #define FILE_DUMP_CAMERA        0
     95 #define FILE_DUMP_B4_DISP       0
     96 
     97 namespace android {
     98 
     99 static int initUsbCamera(               camera_hardware_t *camHal,
    100                                         int width, int height,
    101                                         int pixelFormat);
    102 static int startUsbCamCapture(          camera_hardware_t *camHal);
    103 static int stopUsbCamCapture(           camera_hardware_t *camHal);
    104 static int initV4L2mmap(                camera_hardware_t *camHal);
    105 static int unInitV4L2mmap(              camera_hardware_t *camHal);
    106 static int launch_preview_thread(       camera_hardware_t *camHal);
    107 static int launchTakePictureThread(     camera_hardware_t *camHal);
    108 static int initDisplayBuffers(          camera_hardware_t *camHal);
    109 static int deInitDisplayBuffers(        camera_hardware_t *camHal);
    110 static int stopPreviewInternal(         camera_hardware_t *camHal);
    111 static int get_buf_from_cam(            camera_hardware_t *camHal);
    112 static int put_buf_to_cam(              camera_hardware_t *camHal);
    113 static int prvwThreadTakePictureInternal(camera_hardware_t *camHal);
    114 static int get_buf_from_display( camera_hardware_t *camHal, int *buffer_id);
    115 static int put_buf_to_display(   camera_hardware_t *camHal, int buffer_id);
    116 static int convert_data_frm_cam_to_disp(camera_hardware_t *camHal, int buffer_id);
    117 static void * previewloop(void *);
    118 static void * takePictureThread(void *);
    119 static int convert_YUYV_to_420_NV12(char *in_buf, char *out_buf, int wd, int ht);
    120 static int get_uvc_device(char *devname);
    121 static int getPreviewCaptureFmt(camera_hardware_t *camHal);
    122 static int allocate_ion_memory(QCameraHalMemInfo_t *mem_info, int ion_type);
    123 static int deallocate_ion_memory(QCameraHalMemInfo_t *mem_info);
    124 static int ioctlLoop(int fd, int ioctlCmd, void *args);
    125 static int readFromFile(char* fileName, char* buffer, int bufferSize);
    126 static int fileDump(const char* fileName, char* data, int length, int* frm_cnt);
    127 static int encodeJpeg(                  camera_hardware_t *camHal);
    128 void jpegEncodeCb   (jpeg_job_status_t status,
    129                        uint8_t thumbnailDroppedFlag,
    130                        uint32_t client_hdl,
    131                        uint32_t jobId,
    132                        uint8_t* out_data,
    133                        uint32_t data_size,
    134                        void *userData);
    135 
    136 /* HAL function implementation goes here*/
    137 
    138 /**
    139  * The functions need to be provided by the camera HAL.
    140  *
    141  * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
    142  * and openCameraHardware() is 0 to N-1.
    143  */
    144 
    145 extern "C" int usbcam_get_number_of_cameras()
    146 {
    147     /* TBR: This is hardcoded currently to 1 USB camera */
    148     int numCameras = 1;
    149     ALOGI("%s: E", __func__);
    150     ALOGI("%s: X", __func__);
    151 
    152     return numCameras;
    153 }
    154 
    155 extern "C" int usbcam_get_camera_info(int camera_id, struct camera_info *info)
    156 {
    157     int rc = -1;
    158     ALOGI("%s: E", __func__);
    159 
    160     /* TBR: This info is hardcoded currently irrespective of camera_id */
    161     if(info) {
    162         struct CameraInfo camInfo;
    163         memset(&camInfo, -1, sizeof (struct CameraInfo));
    164 
    165         info->facing = CAMERA_FACING_FRONT;//CAMERA_FACING_BACK;
    166         info->orientation = 0;
    167         rc = 0;
    168     }
    169     ALOGI("%s: X", __func__);
    170     return rc;
    171 }
    172 
    173 /* HAL should return NULL handle if it fails to open camera hardware. */
    174 extern "C" int  usbcam_camera_device_open(
    175   const struct hw_module_t* module, const char* id,
    176           struct hw_device_t** hw_device)
    177 {
    178     int rc = -1;
    179     camera_device       *device = NULL;
    180     camera_hardware_t   *camHal;
    181     char                *dev_name;
    182 
    183     ALOGI("%s: E", __func__);
    184 
    185     /* initialize return handle value to NULL */
    186     *hw_device = NULL;
    187 
    188     camHal = new camera_hardware_t();
    189     if(!camHal) {
    190 
    191             ALOGE("%s:  end in no mem", __func__);
    192             return -1;
    193     }
    194 
    195     rc = usbCamInitDefaultParameters(camHal);
    196     if(0 != rc)
    197     {
    198         ALOGE("%s: usbCamInitDefaultParameters error", __func__);
    199         return rc;
    200     }
    201 #if CAPTURE
    202 
    203     dev_name = camHal->dev_name;
    204 
    205     rc = get_uvc_device(dev_name);
    206     if(rc || *dev_name == '\0'){
    207         ALOGE("%s: No UVC node found \n", __func__);
    208         return -1;
    209     }
    210 
    211     camHal->fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
    212 
    213     if (camHal->fd <  0) {
    214         ALOGE("%s: Cannot open '%s'", __func__, dev_name);
    215         free(camHal);
    216         rc = -1;
    217     }else{
    218         rc = 0;
    219     }
    220 
    221 #else /* CAPTURE */
    222     rc = 0;
    223 #endif /* CAPTURE */
    224 
    225     device                  = &camHal->hw_dev;
    226     device->common.close    = usbcam_close_camera_device;
    227     device->ops             = &usbcam_camera_ops;
    228     device->priv            = (void *)camHal;
    229     *hw_device              = &(device->common);
    230 
    231     ALOGD("%s: camHal: %p", __func__, camHal);
    232     ALOGI("%s: X %d", __func__, rc);
    233 
    234     return rc;
    235 }
    236 
    237 extern "C"  int usbcam_close_camera_device( hw_device_t *hw_dev)
    238 {
    239     ALOGI("%s: device =%p E", __func__, hw_dev);
    240     int rc =  -1;
    241     camera_device_t *device     = (camera_device_t *)hw_dev;
    242 
    243     if(device) {
    244         camera_hardware_t *camHal   = (camera_hardware_t *)device->priv;
    245         if(camHal) {
    246             rc = close(camHal->fd);
    247             if(rc < 0) {
    248                 ALOGE("%s: close failed ", __func__);
    249             }
    250             camHal->fd = 0;
    251             delete camHal;
    252         }else{
    253                 ALOGE("%s: camHal is NULL pointer ", __func__);
    254         }
    255     }
    256     ALOGI("%s: X device =%p, rc = %d", __func__, hw_dev, rc);
    257     return rc;
    258 }
    259 
    260 int usbcam_set_preview_window(struct camera_device * device,
    261         struct preview_stream_ops *window)
    262 {
    263     ALOGI("%s: E", __func__);
    264     int rc = 0;
    265     camera_hardware_t *camHal;
    266 
    267     VALIDATE_DEVICE_HDL(camHal, device, -1);
    268     Mutex::Autolock autoLock(camHal->lock);
    269 
    270     /* if window is already set, then de-init previous buffers */
    271     if(camHal->window){
    272         rc = deInitDisplayBuffers(camHal);
    273         if(rc < 0) {
    274             ALOGE("%s: deInitDisplayBuffers returned error", __func__);
    275         }
    276     }
    277     camHal->window = window;
    278 
    279     if(camHal->window){
    280         rc = initDisplayBuffers(camHal);
    281         if(rc < 0) {
    282             ALOGE("%s: initDisplayBuffers returned error", __func__);
    283         }
    284     }
    285     ALOGI("%s: X. rc = %d", __func__, rc);
    286     return rc;
    287 }
    288 
    289 void usbcam_set_CallBacks(struct camera_device * device,
    290         camera_notify_callback notify_cb,
    291         camera_data_callback data_cb,
    292         camera_data_timestamp_callback data_cb_timestamp,
    293         camera_request_memory get_memory,
    294         void *user)
    295 {
    296     ALOGI("%s: E", __func__);
    297     camera_hardware_t *camHal;
    298 
    299     if(device && device->priv){
    300         camHal = (camera_hardware_t *)device->priv;
    301     }else{
    302         ALOGE("%s: Null device or device->priv", __func__);
    303         return;
    304     }
    305 
    306     Mutex::Autolock autoLock(camHal->lock);
    307 
    308     camHal->notify_cb           = notify_cb;
    309     camHal->data_cb             = data_cb;
    310     camHal->data_cb_timestamp   = data_cb_timestamp;
    311     camHal->get_memory          = get_memory;
    312     camHal->cb_ctxt             = user;
    313 
    314     ALOGI("%s: X", __func__);
    315 }
    316 
    317 void usbcam_enable_msg_type(struct camera_device * device, int32_t msg_type)
    318 {
    319     ALOGI("%s: E", __func__);
    320     ALOGI("%s: msg_type: %d", __func__, msg_type);
    321 
    322     camera_hardware_t *camHal;
    323 
    324     if(device && device->priv){
    325         camHal = (camera_hardware_t *)device->priv;
    326     }else{
    327         ALOGE("%s: Null device or device->priv", __func__);
    328         return;
    329     }
    330 
    331     Mutex::Autolock autoLock(camHal->lock);
    332 
    333     camHal->msgEnabledFlag |= msg_type;
    334 
    335     ALOGI("%s: X", __func__);
    336 }
    337 
    338 void usbcam_disable_msg_type(struct camera_device * device, int32_t msg_type)
    339 {
    340     ALOGI("%s: E", __func__);
    341     ALOGI("%s: msg_type: %d", __func__, msg_type);
    342 
    343     camera_hardware_t *camHal;
    344     if(device && device->priv){
    345         camHal = (camera_hardware_t *)device->priv;
    346     }else{
    347         ALOGE("%s: Null device or device->priv", __func__);
    348         return;
    349     }
    350 
    351     Mutex::Autolock autoLock(camHal->lock);
    352 
    353     camHal->msgEnabledFlag &= ~msg_type;
    354 
    355     ALOGI("%s: X", __func__);
    356 }
    357 
    358 int usbcam_msg_type_enabled(struct camera_device * device, int32_t msg_type)
    359 {
    360     ALOGI("%s: E", __func__);
    361 
    362     camera_hardware_t *camHal;
    363     if(device && device->priv){
    364         camHal = (camera_hardware_t *)device->priv;
    365     }else{
    366         ALOGE("%s: Null device or device->priv", __func__);
    367         return -1;
    368     }
    369 
    370     Mutex::Autolock autoLock(camHal->lock);
    371 
    372     ALOGI("%s: X", __func__);
    373     return (camHal->msgEnabledFlag & msg_type);
    374 }
    375 
    376 int usbcam_start_preview(struct camera_device * device)
    377 {
    378     ALOGI("%s: E", __func__);
    379 
    380     int rc = -1;
    381     camera_hardware_t *camHal = NULL;
    382 
    383     VALIDATE_DEVICE_HDL(camHal, device, -1);
    384     Mutex::Autolock autoLock(camHal->lock);
    385 
    386     /* If preivew is already running, nothing to be done */
    387     if(camHal->previewEnabledFlag){
    388         ALOGI("%s: Preview is already running", __func__);
    389         return 0;
    390     }
    391 
    392 #if CAPTURE
    393     rc = initUsbCamera(camHal, camHal->prevWidth,
    394                         camHal->prevHeight, getPreviewCaptureFmt(camHal));
    395     if(rc < 0) {
    396         ALOGE("%s: Failed to intialize the device", __func__);
    397     }else{
    398         rc = startUsbCamCapture(camHal);
    399         if(rc < 0) {
    400             ALOGE("%s: Failed to startUsbCamCapture", __func__);
    401         }else{
    402             rc = launch_preview_thread(camHal);
    403             if(rc < 0) {
    404                 ALOGE("%s: Failed to launch_preview_thread", __func__);
    405             }
    406         }
    407     }
    408 #else /* CAPTURE */
    409     rc = launch_preview_thread(camHal);
    410     if(rc < 0) {
    411         ALOGE("%s: Failed to launch_preview_thread", __func__);
    412     }
    413 #endif /* CAPTURE */
    414     /* if no errors, then set the flag */
    415     if(!rc)
    416         camHal->previewEnabledFlag = 1;
    417 
    418     ALOGD("%s: X", __func__);
    419     return rc;
    420 }
    421 
    422 void usbcam_stop_preview(struct camera_device * device)
    423 {
    424     ALOGD("%s: E", __func__);
    425 
    426     int rc = 0;
    427     camera_hardware_t *camHal;
    428 
    429     if(device && device->priv){
    430         camHal = (camera_hardware_t *)device->priv;
    431     }else{
    432         ALOGE("%s: Null device or device->priv", __func__);
    433         return;
    434     }
    435 
    436     Mutex::Autolock autoLock(camHal->lock);
    437 
    438     rc = stopPreviewInternal(camHal);
    439     if(rc)
    440         ALOGE("%s: stopPreviewInternal returned error", __func__);
    441 
    442     ALOGI("%s: X", __func__);
    443     return;
    444 }
    445 
    446 /* This function is equivalent to is_preview_enabled */
    447 int usbcam_preview_enabled(struct camera_device * device)
    448 {
    449     ALOGI("%s: E", __func__);
    450     camera_hardware_t *camHal;
    451 
    452     if(device && device->priv){
    453         camHal = (camera_hardware_t *)device->priv;
    454     }else{
    455         ALOGE("%s: Null device or device->priv", __func__);
    456         return -1;
    457     }
    458     Mutex::Autolock autoLock(camHal->lock);
    459 
    460     ALOGI("%s: X", __func__);
    461     return camHal->previewEnabledFlag;
    462 }
    463 
    464 /* TBD */
    465 int usbcam_store_meta_data_in_buffers(struct camera_device * device, int enable)
    466 {
    467     ALOGI("%s: E", __func__);
    468     int rc = 0;
    469 
    470     ALOGI("%s: X", __func__);
    471     return rc;
    472 }
    473 
    474 /* TBD */
    475 int usbcam_start_recording(struct camera_device * device)
    476 {
    477     int rc = 0;
    478     ALOGD("%s: E", __func__);
    479 
    480     ALOGD("%s: X", __func__);
    481 
    482     return rc;
    483 }
    484 
    485 /* TBD */
    486 void usbcam_stop_recording(struct camera_device * device)
    487 {
    488     ALOGD("%s: E", __func__);
    489 
    490     ALOGD("%s: X", __func__);
    491 }
    492 
    493 /* TBD */
    494 int usbcam_recording_enabled(struct camera_device * device)
    495 {
    496     int rc = 0;
    497     ALOGD("%s: E", __func__);
    498 
    499     ALOGD("%s: X", __func__);
    500     return rc;
    501 }
    502 
    503 /* TBD */
    504 void usbcam_release_recording_frame(struct camera_device * device,
    505                 const void *opaque)
    506 {
    507     ALOGV("%s: E", __func__);
    508 
    509     ALOGD("%s: X", __func__);
    510 }
    511 
    512 /* TBD */
    513 int usbcam_auto_focus(struct camera_device * device)
    514 {
    515     ALOGD("%s: E", __func__);
    516     int rc = 0;
    517 
    518     ALOGD("%s: X", __func__);
    519     return rc;
    520 }
    521 
    522 /* TBD */
    523 int usbcam_cancel_auto_focus(struct camera_device * device)
    524 {
    525     int rc = 0;
    526     ALOGD("%s: E", __func__);
    527 
    528     ALOGD("%s: X", __func__);
    529     return rc;
    530 }
    531 
    532 int usbcam_take_picture(struct camera_device * device)
    533 {
    534     ALOGI("%s: E", __func__);
    535     int rc = 0;
    536     camera_hardware_t *camHal;
    537 
    538     VALIDATE_DEVICE_HDL(camHal, device, -1);
    539 
    540     Mutex::Autolock autoLock(camHal->lock);
    541 
    542     /* If take picture is already in progress, nothing t be done */
    543     if(camHal->takePictInProgress){
    544         ALOGI("%s: Take picture already in progress", __func__);
    545         return 0;
    546     }
    547 
    548     if(camHal->previewEnabledFlag)
    549     {
    550         rc = stopPreviewInternal(camHal);
    551         if(rc){
    552             ALOGE("%s: stopPreviewInternal returned error", __func__);
    553         }
    554         USB_CAM_CLOSE(camHal);
    555         camHal->prvwStoppedForPicture = 1;
    556     }
    557     /* TBD: Need to handle any dependencies on video recording state */
    558     rc = launchTakePictureThread(camHal);
    559     if(rc)
    560         ALOGE("%s: launchTakePictureThread error", __func__);
    561 
    562 #if 0
    563     /* This implementation requests preview thread to take picture */
    564     if(camHal->previewEnabledFlag)
    565     {
    566         camHal->prvwCmdPending++;
    567         camHal->prvwCmd         = USB_CAM_PREVIEW_TAKEPIC;
    568         ALOGD("%s: Take picture command set ", __func__);
    569     }else{
    570         ALOGE("%s: Take picture without preview started!", __func__);
    571         rc = -1;
    572     }
    573 #endif
    574 
    575     if(!rc)
    576         camHal->takePictInProgress = 1;
    577 
    578     ALOGI("%s: X", __func__);
    579     return rc;
    580 }
    581 
    582 /* TBD */
    583 int usbcam_cancel_picture(struct camera_device * device)
    584 
    585 {
    586     ALOGI("%s: E", __func__);
    587     int rc = 0;
    588 
    589     ALOGI("%s: X", __func__);
    590     return rc;
    591 }
    592 
    593 int usbcam_set_parameters(struct camera_device * device, const char *params)
    594 
    595 {
    596     ALOGI("%s: E", __func__);
    597     int rc = 0;
    598     camera_hardware_t *camHal;
    599 
    600     VALIDATE_DEVICE_HDL(camHal, device, -1);
    601 
    602     Mutex::Autolock autoLock(camHal->lock);
    603 
    604     rc = usbCamSetParameters(camHal, params);
    605 
    606     ALOGI("%s: X", __func__);
    607     return rc;
    608 }
    609 
    610 char* usbcam_get_parameters(struct camera_device * device)
    611 {
    612     char *parms;
    613     ALOGI("%s: E", __func__);
    614 
    615     camera_hardware_t *camHal;
    616     VALIDATE_DEVICE_HDL(camHal, device, NULL);
    617 
    618     Mutex::Autolock autoLock(camHal->lock);
    619 
    620     parms = usbCamGetParameters(camHal);
    621 
    622     ALOGI("%s: X", __func__);
    623     return parms;
    624 }
    625 
    626 void usbcam_put_parameters(struct camera_device * device, char *parm)
    627 
    628 {
    629     ALOGI("%s: E", __func__);
    630 
    631     camera_hardware_t *camHal;
    632 
    633     if(device && device->priv){
    634         camHal = (camera_hardware_t *)device->priv;
    635     }else{
    636         ALOGE("%s: Null device or device->priv", __func__);
    637         return;
    638     }
    639 
    640     usbCamPutParameters(camHal, parm);
    641 
    642     ALOGI("%s: X", __func__);
    643     return;
    644 }
    645 
    646 /* TBD */
    647 int usbcam_send_command(struct camera_device * device,
    648             int32_t cmd, int32_t arg1, int32_t arg2)
    649 {
    650     int rc = 0;
    651     ALOGI("%s: E", __func__);
    652     ALOGI("%d", cmd);
    653 
    654     ALOGI("%s: X", __func__);
    655     return rc;
    656 }
    657 
    658 /* TBD */
    659 void usbcam_release(struct camera_device * device)
    660 {
    661     ALOGI("%s: E", __func__);
    662 #if 0
    663     Mutex::Autolock l(&mLock);
    664 
    665     switch(mPreviewState) {
    666     case QCAMERA_HAL_PREVIEW_STOPPED:
    667         break;
    668     case QCAMERA_HAL_PREVIEW_START:
    669         break;
    670     case QCAMERA_HAL_PREVIEW_STARTED:
    671         stopPreviewInternal();
    672     break;
    673     case QCAMERA_HAL_RECORDING_STARTED:
    674         stopRecordingInternal();
    675         stopPreviewInternal();
    676         break;
    677     case QCAMERA_HAL_TAKE_PICTURE:
    678         cancelPictureInternal();
    679         break;
    680     default:
    681         break;
    682     }
    683     mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
    684 #endif
    685     ALOGI("%s: X", __func__);
    686 }
    687 
    688 /* TBD */
    689 int usbcam_dump(struct camera_device * device, int fd)
    690 {
    691     ALOGI("%s: E", __func__);
    692     int rc = 0;
    693 
    694     ALOGI("%s: X", __func__);
    695     return rc;
    696 }
    697 /*****************************************************************************
    698 *  Static function definitions below
    699 *****************************************************************************/
    700 
    701 /******************************************************************************/
    702 /* No in place conversion supported. Output buffer and input MUST should be   */
    703 /* different input buffer for a 4x4 pixel video                             ***/
    704 /******                  YUYVYUYV          00 01 02 03 04 05 06 07 ************/
    705 /******                  YUYVYUYV          08 09 10 11 12 13 14 15 ************/
    706 /******                  YUYVYUYV          16 17 18 19 20 21 22 23 ************/
    707 /******                  YUYVYUYV          24 25 26 27 28 29 30 31 ************/
    708 /******************************************************************************/
    709 /* output generated by this function ******************************************/
    710 /************************** YYYY            00 02 04 06            ************/
    711 /************************** YYYY            08 10 12 14            ************/
    712 /************************** YYYY            16 18 20 22            ************/
    713 /************************** YYYY            24 26 28 30            ************/
    714 /************************** VUVU            03 01 07 05            ************/
    715 /************************** VUVU            19 17 23 21            ************/
    716 /******************************************************************************/
    717 
    718 static int convert_YUYV_to_420_NV12(char *in_buf, char *out_buf, int wd, int ht)
    719 {
    720     int rc =0;
    721     int row, col, uv_row;
    722 
    723     ALOGD("%s: E", __func__);
    724     /* Arrange Y */
    725     for(row = 0; row < ht; row++)
    726         for(col = 0; col < wd * 2; col += 2)
    727         {
    728             out_buf[row * wd + col / 2] = in_buf[row * wd * 2 + col];
    729         }
    730 
    731     /* Arrange UV */
    732     for(row = 0, uv_row = ht; row < ht; row += 2, uv_row++)
    733         for(col = 1; col < wd * 2; col += 4)
    734         {
    735             out_buf[uv_row * wd + col / 2]= in_buf[row * wd * 2 + col + 2];
    736             out_buf[uv_row * wd + col / 2 + 1]  = in_buf[row * wd * 2 + col];
    737         }
    738 
    739     ALOGD("%s: X", __func__);
    740     return rc;
    741 }
    742 
    743 /******************************************************************************
    744  * Function: initDisplayBuffers
    745  * Description: This function initializes the preview buffers
    746  *
    747  * Input parameters:
    748  *   camHal              - camera HAL handle
    749  *
    750  * Return values:
    751  *      0   Success
    752  *      -1  Error
    753  * Notes: none
    754  *****************************************************************************/
    755 static int initDisplayBuffers(camera_hardware_t *camHal)
    756 {
    757     preview_stream_ops    *mPreviewWindow;
    758     struct ion_fd_data    ion_info_fd;
    759     int                   numMinUndequeuedBufs = 0;
    760     int                   rc = 0;
    761     int                   gralloc_usage = 0;
    762     int                   err;
    763     int                   color=30;
    764 
    765     ALOGD("%s: E", __func__);
    766 
    767 #if DISPLAY
    768     if(camHal == NULL) {
    769         ALOGE("%s: camHal = NULL", __func__);
    770         return -1;
    771     }
    772 
    773     mPreviewWindow = camHal->window;
    774     if(!mPreviewWindow) {
    775         ALOGE("%s: mPreviewWindow = NULL", __func__);
    776         return -1;
    777     }
    778 
    779     /************************************************************************/
    780     /* - get_min_undequeued_buffer_count                                    */
    781     /* - set_buffer_count                                                   */
    782     /* - set_buffers_geometry                                               */
    783     /* - set_usage                                                          */
    784     /* - dequeue all the display buffers                                    */
    785     /* - cancel buffers: release w/o displaying                             */
    786     /************************************************************************/
    787 
    788     /************************************************************************/
    789     /* - get_min_undequeued_buffer_count                                    */
    790     /************************************************************************/
    791     if(mPreviewWindow->get_min_undequeued_buffer_count) {
    792         rc = mPreviewWindow->get_min_undequeued_buffer_count(
    793             mPreviewWindow, &numMinUndequeuedBufs);
    794         if (0 != rc) {
    795             ALOGE("%s: get_min_undequeued_buffer_count returned error", __func__);
    796         }
    797         else
    798             ALOGD("%s: get_min_undequeued_buffer_count returned: %d ",
    799                __func__, numMinUndequeuedBufs);
    800     }
    801     else
    802         ALOGE("%s: get_min_undequeued_buffer_count is NULL pointer", __func__);
    803 
    804     /************************************************************************/
    805     /* - set_buffer_count                                                   */
    806     /************************************************************************/
    807     if(mPreviewWindow->set_buffer_count) {
    808         camHal->previewMem.buffer_count = numMinUndequeuedBufs
    809                                             + PRVW_DISP_BUF_CNT;
    810         rc = mPreviewWindow->set_buffer_count(
    811             mPreviewWindow,
    812             camHal->previewMem.buffer_count);
    813         if (rc != 0) {
    814             ALOGE("%s: set_buffer_count returned error", __func__);
    815         }else
    816             ALOGD("%s: set_buffer_count returned success", __func__);
    817     }else
    818         ALOGE("%s: set_buffer_count is NULL pointer", __func__);
    819 
    820     /************************************************************************/
    821     /* - set_buffers_geometry                                               */
    822     /************************************************************************/
    823     if(mPreviewWindow->set_buffers_geometry) {
    824         rc = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
    825                                                 camHal->dispWidth,
    826                                                 camHal->dispHeight,
    827                                                 camHal->dispFormat);
    828         if (rc != 0) {
    829             ALOGE("%s: set_buffers_geometry returned error. %s (%d)",
    830                __func__, strerror(-rc), -rc);
    831         }else
    832             ALOGD("%s: set_buffers_geometry returned success", __func__);
    833     }else
    834         ALOGE("%s: set_buffers_geometry is NULL pointer", __func__);
    835 
    836     /************************************************************************/
    837     /* - set_usage                                                          */
    838     /************************************************************************/
    839     gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID |
    840                     GRALLOC_USAGE_PRIVATE_UNCACHED;
    841 
    842     if(mPreviewWindow->set_usage) {
    843         rc = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage);
    844         if (rc != 0) {
    845             ALOGE("%s: set_usage returned error", __func__);
    846         }else
    847             ALOGD("%s: set_usage returned success", __func__);
    848     }
    849     else
    850         ALOGE("%s: set_usage is NULL pointer", __func__);
    851 
    852     /************************************************************************/
    853     /* - dequeue all the display buffers                                    */
    854     /************************************************************************/
    855     for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) {
    856         int stride;
    857         err = mPreviewWindow->dequeue_buffer(
    858                 mPreviewWindow,
    859                 &camHal->previewMem.buffer_handle[cnt],
    860                 &camHal->previewMem.stride[cnt]);
    861         if(!err) {
    862             ALOGD("%s: dequeue buf: %p\n",
    863                  __func__, camHal->previewMem.buffer_handle[cnt]);
    864 
    865             if(mPreviewWindow->lock_buffer) {
    866                 err = mPreviewWindow->lock_buffer(
    867                     mPreviewWindow,
    868                     camHal->previewMem.buffer_handle[cnt]);
    869                 ALOGD("%s: mPreviewWindow->lock_buffer success",
    870                      __func__);
    871             }
    872 
    873             // lock the buffer using genlock
    874             ALOGD("%s: camera call genlock_lock, hdl=%p",
    875                 __func__, (*camHal->previewMem.buffer_handle[cnt]));
    876 
    877             if (GENLOCK_NO_ERROR !=
    878                 genlock_lock_buffer(
    879                     (native_handle_t *) (*camHal->previewMem.buffer_handle[cnt]),
    880                     GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT))
    881             {
    882                 ALOGE("%s: genlock_lock_buffer(WRITE) failed",
    883                     __func__);
    884                 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED;
    885             }else {
    886                 ALOGD("%s: genlock_lock_buffer hdl =%p",
    887                   __func__, *camHal->previewMem.buffer_handle[cnt]);
    888                 camHal->previewMem.local_flag[cnt] = BUFFER_LOCKED;
    889             }
    890 
    891             /* Store this buffer details in the context */
    892             camHal->previewMem.private_buffer_handle[cnt] =
    893                 (struct private_handle_t *) (*camHal->previewMem.buffer_handle[cnt]);
    894 
    895             ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
    896                 cnt, camHal->previewMem.private_buffer_handle[cnt]->fd,
    897                 camHal->previewMem.private_buffer_handle[cnt]->size,
    898                 camHal->previewMem.private_buffer_handle[cnt]->offset);
    899 
    900             camHal->previewMem.camera_memory[cnt] =
    901                 camHal->get_memory(
    902                     camHal->previewMem.private_buffer_handle[cnt]->fd,
    903                     camHal->previewMem.private_buffer_handle[cnt]->size,
    904                     1, camHal->cb_ctxt);
    905 
    906             ALOGD("%s: data = %p, size = %d, handle = %p", __func__,
    907                 camHal->previewMem.camera_memory[cnt]->data,
    908                 camHal->previewMem.camera_memory[cnt]->size,
    909                 camHal->previewMem.camera_memory[cnt]->handle);
    910 
    911 #ifdef USE_ION
    912             /* In case of ION usage, open ION fd */
    913             camHal->previewMem.mem_info[cnt].main_ion_fd =
    914                                                 open("/dev/ion", O_RDONLY);
    915             if (camHal->previewMem.mem_info[cnt].main_ion_fd < 0) {
    916                 ALOGE("%s: failed: could not open ion device\n", __func__);
    917             }else{
    918                 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    919                 ion_info_fd.fd =
    920                     camHal->previewMem.private_buffer_handle[cnt]->fd;
    921                 if (ioctl(camHal->previewMem.mem_info[cnt].main_ion_fd,
    922                           ION_IOC_IMPORT, &ion_info_fd) < 0) {
    923                     ALOGE("ION import failed\n");
    924                 }
    925             }
    926             camHal->previewMem.mem_info[cnt].fd =
    927                 camHal->previewMem.private_buffer_handle[cnt]->fd;
    928             camHal->previewMem.mem_info[cnt].size =
    929                 camHal->previewMem.private_buffer_handle[cnt]->size;
    930             camHal->previewMem.mem_info[cnt].handle = ion_info_fd.handle;
    931 
    932 #endif
    933         }
    934         else
    935             ALOGE("%s: dequeue buf %d failed \n", __func__, cnt);
    936     }
    937     /************************************************************************/
    938     /* - cancel buffers: queue w/o displaying                               */
    939     /************************************************************************/
    940     for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) {
    941         if (GENLOCK_FAILURE == genlock_unlock_buffer(
    942                 (native_handle_t *)(*(camHal->previewMem.buffer_handle[cnt])))){
    943             ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__,
    944                 (*(camHal->previewMem.buffer_handle[cnt])) );
    945         } else {
    946             camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED;
    947             ALOGD("%s: genlock_unlock_buffer success: hdl = %p",
    948                __func__, (*(camHal->previewMem.buffer_handle[cnt])));
    949         }
    950 
    951         err = mPreviewWindow->cancel_buffer(mPreviewWindow,
    952             (buffer_handle_t *)camHal->previewMem.buffer_handle[cnt]);
    953         if(!err) {
    954             ALOGD("%s: cancel_buffer successful: %p\n",
    955                  __func__, camHal->previewMem.buffer_handle[cnt]);
    956         }else
    957             ALOGE("%s: cancel_buffer failed: %p\n", __func__,
    958                  camHal->previewMem.buffer_handle[cnt]);
    959     }
    960 #else
    961     rc = 0;
    962 #endif /* #if DISPLAY */
    963     ALOGD("%s: X", __func__);
    964     return rc;
    965 }
    966 
    967 /******************************************************************************
    968  * Function: deInitDisplayBuffers
    969  * Description: This function de-initializes all the display buffers allocated
    970  *              in initDisplayBuffers
    971  *
    972  * Input parameters:
    973  *   camHal              - camera HAL handle
    974  *
    975  * Return values:
    976  *      0   Success
    977  *      -1  Error
    978  * Notes: none
    979  *****************************************************************************/
    980 static int deInitDisplayBuffers(camera_hardware_t *camHal)
    981 {
    982     int rc = 0;
    983     preview_stream_ops    *previewWindow;
    984 
    985     ALOGD("%s: E", __func__);
    986 
    987     if(!camHal || !camHal->window) {
    988       ALOGE("%s: camHal = NULL or window = NULL ", __func__);
    989       return -1;
    990     }
    991 
    992     previewWindow = camHal->window;
    993 
    994     /************************************************************************/
    995     /* - Release all buffers that were acquired using get_memory            */
    996     /* - If using ION memory, free ION related resources                    */
    997     /* - genUnlock if buffer is genLocked                                   */
    998     /* - Cancel buffers: queue w/o displaying                               */
    999     /************************************************************************/
   1000 
   1001 #if DISPLAY
   1002     for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) {
   1003 
   1004         /* Release all buffers that were acquired using get_memory */
   1005         camHal->previewMem.camera_memory[cnt]->release(
   1006                                 camHal->previewMem.camera_memory[cnt]);
   1007 
   1008 #ifdef USE_ION
   1009         /* If using ION memory, free ION related resources */
   1010         struct ion_handle_data ion_handle;
   1011         memset(&ion_handle, 0, sizeof(ion_handle));
   1012         ion_handle.handle = camHal->previewMem.mem_info[cnt].handle;
   1013         if (ioctl(camHal->previewMem.mem_info[cnt].main_ion_fd,
   1014             ION_IOC_FREE, &ion_handle) < 0) {
   1015             ALOGE("%s: ion free failed\n", __func__);
   1016         }
   1017         close(camHal->previewMem.mem_info[cnt].main_ion_fd);
   1018 #endif
   1019 
   1020         /* genUnlock if buffer is genLocked */
   1021         if(camHal->previewMem.local_flag[cnt] == BUFFER_LOCKED){
   1022             if (GENLOCK_FAILURE == genlock_unlock_buffer(
   1023                     (native_handle_t *)(*(camHal->previewMem.buffer_handle[cnt])))){
   1024                 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__,
   1025                     (*(camHal->previewMem.buffer_handle[cnt])) );
   1026             } else {
   1027                 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED;
   1028                 ALOGD("%s: genlock_unlock_buffer success: hdl = %p",
   1029                    __func__, (*(camHal->previewMem.buffer_handle[cnt])));
   1030             }
   1031         }
   1032         /* cancel buffers: enqueue w/o displaying */
   1033         rc = previewWindow->cancel_buffer(previewWindow,
   1034             (buffer_handle_t *)camHal->previewMem.buffer_handle[cnt]);
   1035         if(!rc) {
   1036             ALOGD("%s: cancel_buffer successful: %p\n",
   1037                  __func__, camHal->previewMem.buffer_handle[cnt]);
   1038         }else
   1039             ALOGE("%s: cancel_buffer failed: %p\n", __func__,
   1040                  camHal->previewMem.buffer_handle[cnt]);
   1041     }
   1042 #endif /* #if DISPLAY */
   1043     memset(&camHal->previewMem, 0, sizeof(camHal->previewMem));
   1044 
   1045     ALOGD("%s: X", __func__);
   1046     return rc;
   1047 }
   1048 
   1049 /******************************************************************************
   1050  * Function: getPreviewCaptureFmt
   1051  * Description: This function implements the logic to decide appropriate
   1052  *              capture format from the USB camera
   1053  *
   1054  * Input parameters:
   1055  *   camHal              - camera HAL handle
   1056  *
   1057  * Return values:
   1058  *      Capture format. Default (V4L2_PIX_FMT_MJPEG)
   1059  *
   1060  * Notes: none
   1061  *****************************************************************************/
   1062 static int getPreviewCaptureFmt(camera_hardware_t *camHal)
   1063 {
   1064     int     i = 0, mjpegSupported = 0, h264Supported = 0;
   1065     struct v4l2_fmtdesc fmtdesc;
   1066 
   1067     memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc));
   1068 
   1069     /************************************************************************/
   1070     /* - Query the camera for all supported formats                         */
   1071     /* - Based on the resolution, pick an apporpriate format                */
   1072     /************************************************************************/
   1073 
   1074     /************************************************************************/
   1075     /* - Query the camera for all supported formats                         */
   1076     /************************************************************************/
   1077     for(i = 0; ; i++) {
   1078         fmtdesc.index = i;
   1079         fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1080         if (-1 == ioctlLoop(camHal->fd, VIDIOC_ENUM_FMT, &fmtdesc)) {
   1081             if (EINVAL == errno) {
   1082                 ALOGI("%s: Queried all formats till index %d\n", __func__, i);
   1083                 break;
   1084             } else {
   1085                 ALOGE("%s: VIDIOC_ENUM_FMT failed", __func__);
   1086             }
   1087         }
   1088         if(V4L2_PIX_FMT_MJPEG == fmtdesc.pixelformat){
   1089             mjpegSupported = 1;
   1090             ALOGI("%s: V4L2_PIX_FMT_MJPEG is supported", __func__ );
   1091         }
   1092         if(V4L2_PIX_FMT_H264 == fmtdesc.pixelformat){
   1093             h264Supported = 1;
   1094             ALOGI("%s: V4L2_PIX_FMT_H264 is supported", __func__ );
   1095         }
   1096 
   1097     }
   1098 
   1099     /************************************************************************/
   1100     /* - Based on the resolution, pick an apporpriate format                */
   1101     /************************************************************************/
   1102     //V4L2_PIX_FMT_MJPEG; V4L2_PIX_FMT_YUYV; V4L2_PIX_FMT_H264 = 0x34363248;
   1103     camHal->captureFormat = V4L2_PIX_FMT_YUYV;
   1104     if(camHal->prevWidth > 640){
   1105         if(1 == mjpegSupported)
   1106             camHal->captureFormat = V4L2_PIX_FMT_MJPEG;
   1107         else if(1 == h264Supported)
   1108             camHal->captureFormat = V4L2_PIX_FMT_H264;
   1109     }
   1110     ALOGI("%s: Capture format chosen: 0x%x. 0x%x:YUYV. 0x%x:MJPEG. 0x%x: H264",
   1111         __func__, camHal->captureFormat, V4L2_PIX_FMT_YUYV,
   1112         V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_H264);
   1113 
   1114     return camHal->captureFormat;
   1115 }
   1116 
   1117 /******************************************************************************
   1118  * Function: getMjpegdOutputFormat
   1119  * Description: This function maps display pixel format enum to JPEG output
   1120  *              format enum
   1121  *
   1122  * Input parameters:
   1123  *   dispFormat              - Display pixel format
   1124  *
   1125  * Return values:
   1126  *      (int)mjpegOutputFormat
   1127  *
   1128  * Notes: none
   1129  *****************************************************************************/
   1130 static int getMjpegdOutputFormat(int dispFormat)
   1131 {
   1132     int mjpegOutputFormat = YCRCBLP_H2V2;
   1133 
   1134     if(HAL_PIXEL_FORMAT_YCrCb_420_SP == dispFormat)
   1135         mjpegOutputFormat = YCRCBLP_H2V2;
   1136 
   1137     return mjpegOutputFormat;
   1138 }
   1139 
   1140 /******************************************************************************
   1141  * Function: ioctlLoop
   1142  * Description: This function is a blocking call around ioctl
   1143  *
   1144  * Input parameters:
   1145  *   fd             - IOCTL fd
   1146  *   ioctlCmd       - IOCTL command
   1147  *   args           - IOCTL arguments
   1148  *
   1149  * Return values:
   1150  *      (int)mjpegOutputFormat
   1151  *
   1152  * Notes: none
   1153  *****************************************************************************/
   1154 static int ioctlLoop(int fd, int ioctlCmd, void *args)
   1155 {
   1156     int rc = -1;
   1157 
   1158     while(1)
   1159     {
   1160         rc = ioctl(fd, ioctlCmd, args);
   1161         if(!((-1 == rc) && (EINTR == errno)))
   1162             break;
   1163     }
   1164     return rc;
   1165 }
   1166 
   1167 /******************************************************************************
   1168  * Function: initV4L2mmap
   1169  * Description: This function requests for V4L2 driver allocated buffers
   1170  *
   1171  * Input parameters:
   1172  *   camHal              - camera HAL handle
   1173  *
   1174  * Return values:
   1175  *   0      No error
   1176  *   -1     Error
   1177  *
   1178  * Notes: none
   1179  *****************************************************************************/
   1180 static int initV4L2mmap(camera_hardware_t *camHal)
   1181 {
   1182     int rc = -1;
   1183     struct v4l2_requestbuffers  reqBufs;
   1184     struct v4l2_buffer          tempBuf;
   1185 
   1186     ALOGD("%s: E", __func__);
   1187     memset(&reqBufs, 0, sizeof(v4l2_requestbuffers));
   1188     reqBufs.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1189     reqBufs.memory  = V4L2_MEMORY_MMAP;
   1190     reqBufs.count   = PRVW_CAP_BUF_CNT;
   1191 
   1192     if (-1 == ioctlLoop(camHal->fd, VIDIOC_REQBUFS, &reqBufs)) {
   1193         if (EINVAL == errno) {
   1194             ALOGE("%s: does not support memory mapping\n", __func__);
   1195         } else {
   1196             ALOGE("%s: VIDIOC_REQBUFS failed", __func__);
   1197         }
   1198     }
   1199     ALOGD("%s: VIDIOC_REQBUFS success", __func__);
   1200 
   1201     if (reqBufs.count < PRVW_CAP_BUF_CNT) {
   1202         ALOGE("%s: Insufficient buffer memory on\n", __func__);
   1203     }
   1204 
   1205     camHal->buffers =
   1206         ( bufObj* ) calloc(reqBufs.count, sizeof(bufObj));
   1207 
   1208     if (!camHal->buffers) {
   1209         ALOGE("%s: Out of memory\n", __func__);
   1210     }
   1211 
   1212     /* Store the indexes in the context. Useful during releasing */
   1213     for (camHal->n_buffers = 0;
   1214          camHal->n_buffers < reqBufs.count;
   1215          camHal->n_buffers++) {
   1216 
   1217         memset(&tempBuf, 0, sizeof(tempBuf));
   1218 
   1219         tempBuf.index       = camHal->n_buffers;
   1220         tempBuf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1221         tempBuf.memory      = V4L2_MEMORY_MMAP;
   1222 
   1223         if (-1 == ioctlLoop(camHal->fd, VIDIOC_QUERYBUF, &tempBuf))
   1224             ALOGE("%s: VIDIOC_QUERYBUF failed", __func__);
   1225 
   1226         ALOGD("%s: VIDIOC_QUERYBUF success", __func__);
   1227 
   1228         camHal->buffers[camHal->n_buffers].len = tempBuf.length;
   1229         camHal->buffers[camHal->n_buffers].data =
   1230         mmap(NULL /* start anywhere */,
   1231                   tempBuf.length,
   1232                   PROT_READ | PROT_WRITE,
   1233                   MAP_SHARED,
   1234                   camHal->fd, tempBuf.m.offset);
   1235 
   1236         if (MAP_FAILED == camHal->buffers[camHal->n_buffers].data)
   1237             ALOGE("%s: mmap failed", __func__);
   1238     }
   1239     ALOGD("%s: X", __func__);
   1240     return 0;
   1241 }
   1242 
   1243 /******************************************************************************
   1244  * Function: unInitV4L2mmap
   1245  * Description: This function unmaps the V4L2 driver buffers
   1246  *
   1247  * Input parameters:
   1248  *   camHal              - camera HAL handle
   1249  *
   1250  * Return values:
   1251  *   0      No error
   1252  *   -1     Error
   1253  *
   1254  * Notes: none
   1255  *****************************************************************************/
   1256 static int unInitV4L2mmap(camera_hardware_t *camHal)
   1257 {
   1258     int i, rc = 0;
   1259     ALOGD("%s: E", __func__);
   1260 
   1261     for (i = 0; i < camHal->n_buffers; i++)
   1262         if (-1 == munmap(camHal->buffers[i].data, camHal->buffers[i].len)){
   1263             ALOGE("%s: munmap failed for buffer: %d", __func__, i);
   1264             rc = -1;
   1265         }
   1266 
   1267     ALOGD("%s: X", __func__);
   1268     return rc;
   1269 }
   1270 
   1271 /******************************************************************************
   1272  * Function: initUsbCamera
   1273  * Description: This function sets the resolution and pixel format of the
   1274  *              USB camera
   1275  *
   1276  * Input parameters:
   1277  *  camHal              - camera HAL handle
   1278  *  width               - picture width in pixels
   1279  *  height              - picture height in pixels
   1280  *  pixelFormat         - capture format for the camera
   1281  *
   1282  * Return values:
   1283  *   0      No error
   1284  *   -1     Error
   1285  *
   1286  * Notes: none
   1287  *****************************************************************************/
   1288 static int initUsbCamera(camera_hardware_t *camHal, int width, int height,
   1289                         int pixelFormat)
   1290 {
   1291     int     rc = -1;
   1292     struct  v4l2_capability     cap;
   1293     struct  v4l2_cropcap        cropcap;
   1294     struct  v4l2_crop           crop;
   1295     struct  v4l2_format         v4l2format;
   1296     unsigned int                min;
   1297 
   1298     ALOGI("%s: E", __func__);
   1299 
   1300     if (-1 == ioctlLoop(camHal->fd, VIDIOC_QUERYCAP, &cap)) {
   1301         if (EINVAL == errno) {
   1302             ALOGE( "%s: This is not V4L2 device\n", __func__);
   1303             return -1;
   1304         } else {
   1305             ALOGE("%s: VIDIOC_QUERYCAP errno: %d", __func__, errno);
   1306         }
   1307     }
   1308     ALOGD("%s: VIDIOC_QUERYCAP success", __func__);
   1309 
   1310     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
   1311         ALOGE("%s: This is not video capture device\n", __func__);
   1312         return -1;
   1313     }
   1314 
   1315     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
   1316         ALOGE("%s: This does not support streaming i/o\n", __func__);
   1317         return -1;
   1318     }
   1319 
   1320     /* Select video input, video standard and tune here. */
   1321     memset(&cropcap, 0, sizeof(cropcap));
   1322 
   1323     cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1324 
   1325     if (0 == ioctlLoop(camHal->fd, VIDIOC_CROPCAP, &cropcap)) {
   1326 
   1327         /* reset to default */
   1328         crop.c = cropcap.defrect;
   1329         crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1330 
   1331         ALOGD("%s: VIDIOC_CROPCAP success", __func__);
   1332         if (-1 == ioctlLoop(camHal->fd, VIDIOC_S_CROP, &crop)) {
   1333         switch (errno) {
   1334             case EINVAL:
   1335             /* Cropping not supported. */
   1336                 break;
   1337             default:
   1338             /* Errors ignored. */
   1339                 break;
   1340             }
   1341         }
   1342                 ALOGD("%s: VIDIOC_S_CROP success", __func__);
   1343 
   1344     } else {
   1345         /* Errors ignored. */
   1346                ALOGE("%s: VIDIOC_S_CROP failed", __func__);
   1347     }
   1348 
   1349 
   1350     memset(&v4l2format, 0, sizeof(v4l2format));
   1351 
   1352     v4l2format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1353     {
   1354         v4l2format.fmt.pix.field       = V4L2_FIELD_NONE;
   1355         v4l2format.fmt.pix.pixelformat = pixelFormat;
   1356         v4l2format.fmt.pix.width       = width;
   1357         v4l2format.fmt.pix.height      = height;
   1358 
   1359         if (-1 == ioctlLoop(camHal->fd, VIDIOC_S_FMT, &v4l2format))
   1360         {
   1361             ALOGE("%s: VIDIOC_S_FMT failed", __func__);
   1362             return -1;
   1363         }
   1364         ALOGD("%s: VIDIOC_S_FMT success", __func__);
   1365 
   1366         /* Note VIDIOC_S_FMT may change width and height. */
   1367     }
   1368 
   1369     /* TBR: In case of user pointer buffers, v4l2format.fmt.pix.sizeimage */
   1370     /* might have to be calculated as per V4L2 sample application due to */
   1371     /* open source driver bug */
   1372 
   1373     rc = initV4L2mmap(camHal);
   1374     ALOGI("%s: X", __func__);
   1375     return rc;
   1376 }
   1377 
   1378 /******************************************************************************
   1379  * Function: startUsbCamCapture
   1380  * Description: This function queues buffer objects to the driver and sends
   1381  *              STREAM ON command to the USB camera driver
   1382  *
   1383  * Input parameters:
   1384  *   camHal              - camera HAL handle
   1385  *
   1386  * Return values:
   1387  *   0      No error
   1388  *   -1     Error
   1389  *
   1390  * Notes: none
   1391  *****************************************************************************/
   1392 static int startUsbCamCapture(camera_hardware_t *camHal)
   1393 {
   1394     int         rc = -1;
   1395     unsigned    int i;
   1396     enum        v4l2_buf_type   v4l2BufType;
   1397     ALOGD("%s: E", __func__);
   1398 
   1399     for (i = 0; i < camHal->n_buffers; ++i) {
   1400         struct v4l2_buffer tempBuf;
   1401 
   1402         memset(&tempBuf, 0, sizeof(tempBuf));
   1403         tempBuf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1404         tempBuf.memory  = V4L2_MEMORY_MMAP;
   1405         tempBuf.index   = i;
   1406 
   1407         if (-1 == ioctlLoop(camHal->fd, VIDIOC_QBUF, &tempBuf))
   1408             ALOGE("%s: VIDIOC_QBUF for %d buffer failed", __func__, i);
   1409         else
   1410             ALOGD("%s: VIDIOC_QBUF for %d buffer success", __func__, i);
   1411     }
   1412 
   1413     v4l2BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1414     if (-1 == ioctlLoop(camHal->fd, VIDIOC_STREAMON, &v4l2BufType))
   1415         ALOGE("%s: VIDIOC_STREAMON failed", __func__);
   1416     else
   1417     {
   1418         ALOGD("%s: VIDIOC_STREAMON success", __func__);
   1419         rc = 0;
   1420     }
   1421 
   1422     ALOGD("%s: X", __func__);
   1423     return rc;
   1424 }
   1425 
   1426 /******************************************************************************
   1427  * Function: stopUsbCamCapture
   1428  * Description: This function sends STREAM OFF command to the USB camera driver
   1429  *
   1430  * Input parameters:
   1431  *   camHal              - camera HAL handle
   1432  *
   1433  * Return values:
   1434  *   0      No error
   1435  *   -1     Error
   1436  *
   1437  * Notes: none
   1438  *****************************************************************************/
   1439 static int stopUsbCamCapture(camera_hardware_t *camHal)
   1440 {
   1441     int         rc = -1;
   1442     unsigned    int i;
   1443     enum        v4l2_buf_type   v4l2BufType;
   1444     ALOGD("%s: E", __func__);
   1445 
   1446     if(!camHal->fd){
   1447         ALOGE("%s: camHal->fd = NULL ", __func__);
   1448         return -1;
   1449     }
   1450     v4l2BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1451     if (-1 == ioctlLoop(camHal->fd, VIDIOC_STREAMOFF, &v4l2BufType)){
   1452         ALOGE("%s: VIDIOC_STREAMOFF failed", __func__);
   1453         rc = -1;
   1454     }else{
   1455         ALOGD("%s: VIDIOC_STREAMOFF success", __func__);
   1456         rc = 0;
   1457     }
   1458 
   1459     ALOGD("%s: X", __func__);
   1460     return rc;
   1461 }
   1462 
   1463 /******************************************************************************
   1464  * Function: stopPreviewInternal
   1465  * Description: This function sends EXIT command to prview loop thread,
   1466  *              stops usb camera capture and uninitializes MMAP. This function
   1467  *              assumes that calling function has locked camHal->lock
   1468  *
   1469  * Input parameters:
   1470  *   camHal              - camera HAL handle
   1471  *
   1472  * Return values:
   1473  *   0      No error
   1474  *   -1     Error
   1475  *
   1476  * Notes: none
   1477  *****************************************************************************/
   1478 static int stopPreviewInternal(camera_hardware_t *camHal)
   1479 {
   1480     int rc = 0;
   1481     ALOGD("%s: E", __func__);
   1482 
   1483     if(camHal->previewEnabledFlag)
   1484     {
   1485         camHal->prvwCmdPending++;
   1486         camHal->prvwCmd         = USB_CAM_PREVIEW_EXIT;
   1487 
   1488         /* yield lock while waiting for the preview thread to exit */
   1489         camHal->lock.unlock();
   1490         if(pthread_join(camHal->previewThread, NULL)){
   1491             ALOGE("%s: Error in pthread_join preview thread", __func__);
   1492         }
   1493         camHal->lock.lock();
   1494 
   1495         if(stopUsbCamCapture(camHal)){
   1496             ALOGE("%s: Error in stopUsbCamCapture", __func__);
   1497             rc = -1;
   1498         }
   1499         if(unInitV4L2mmap(camHal)){
   1500             ALOGE("%s: Error in stopUsbCamCapture", __func__);
   1501             rc = -1;
   1502         }
   1503         camHal->previewEnabledFlag = 0;
   1504     }
   1505 
   1506     ALOGD("%s: X, rc: %d", __func__, rc);
   1507     return rc;
   1508 }
   1509 #if 1
   1510 /******************************************************************************
   1511  * Function: prvwThreadTakePictureInternal
   1512  * Description: This function processes one camera frame to get JPEG encoded
   1513  *              picture.
   1514  *
   1515  * Input parameters:
   1516  *   camHal              - camera HAL handle
   1517  *
   1518  * Return values:
   1519  *   0      No error
   1520  *   -1     Error
   1521  *
   1522  * Notes: none
   1523  *****************************************************************************/
   1524 static int prvwThreadTakePictureInternal(camera_hardware_t *camHal)
   1525 {
   1526     int     rc = 0;
   1527     QCameraHalMemInfo_t     *mem_info;
   1528     ALOGD("%s: E", __func__);
   1529 
   1530     /************************************************************************/
   1531     /* - If requested for shutter notfication, callback                     */
   1532     /* - Dequeue capture buffer from USB camera                             */
   1533     /* - Send capture buffer to JPEG encoder for JPEG compression           */
   1534     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
   1535     /* - Enqueue capture buffer back to USB camera                          */
   1536     /************************************************************************/
   1537 
   1538     /************************************************************************/
   1539     /* - If requested for shutter notfication, callback                     */
   1540     /************************************************************************/
   1541     if (camHal->msgEnabledFlag & CAMERA_MSG_SHUTTER){
   1542         camHal->lock.unlock();
   1543         camHal->notify_cb(CAMERA_MSG_SHUTTER, 0, 0, camHal->cb_ctxt);
   1544         camHal->lock.lock();
   1545     }
   1546 
   1547 #if CAPTURE
   1548     /************************************************************************/
   1549     /* - Dequeue capture buffer from USB camera                             */
   1550     /************************************************************************/
   1551     if (0 == get_buf_from_cam(camHal))
   1552         ALOGD("%s: get_buf_from_cam success", __func__);
   1553     else
   1554         ALOGE("%s: get_buf_from_cam error", __func__);
   1555 #endif
   1556 
   1557     /************************************************************************/
   1558     /* - Send capture buffer to JPEG encoder for JPEG compression           */
   1559     /************************************************************************/
   1560     /* Optimization: If camera capture is JPEG format, need not compress! */
   1561     /* instead, just data copy from capture buffer to picture buffer */
   1562     if(V4L2_PIX_FMT_MJPEG == camHal->captureFormat){
   1563         /* allocate heap memory for JPEG output */
   1564         mem_info = &camHal->pictMem.mem_info[0];
   1565         mem_info->size = camHal->curCaptureBuf.bytesused;
   1566         /* TBD: allocate_ion_memory
   1567         rc = QCameraHardwareInterface::allocate_ion_memory(mem_info,
   1568                             ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
   1569                             (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
   1570         */
   1571         if(rc)
   1572             ALOGE("%s: ION memory allocation failed", __func__);
   1573 
   1574         camHal->pictMem.camera_memory[0] = camHal->get_memory(
   1575                             mem_info->fd, mem_info->size, 1, camHal->cb_ctxt);
   1576         if(!camHal->pictMem.camera_memory[0])
   1577             ALOGE("%s: get_mem failed", __func__);
   1578 
   1579         memcpy( camHal->pictMem.camera_memory[0]->data,
   1580                 (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
   1581                 camHal->curCaptureBuf.bytesused);
   1582     }
   1583 
   1584     /************************************************************************/
   1585     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
   1586     /************************************************************************/
   1587     if ((camHal->msgEnabledFlag & CAMERA_MSG_COMPRESSED_IMAGE) &&
   1588             (camHal->data_cb)){
   1589         camHal->lock.unlock();
   1590         camHal->data_cb(CAMERA_MSG_COMPRESSED_IMAGE,
   1591                         camHal->pictMem.camera_memory[0],
   1592                         0, NULL, camHal->cb_ctxt);
   1593         camHal->lock.lock();
   1594     }
   1595     /* release heap memory after the call back */
   1596     if(camHal->pictMem.camera_memory[0])
   1597         camHal->pictMem.camera_memory[0]->release(
   1598             camHal->pictMem.camera_memory[0]);
   1599 
   1600     /* TBD: deallocate_ion_memory */
   1601     //rc = QCameraHardwareInterface::deallocate_ion_memory(mem_info);
   1602     if(rc)
   1603         ALOGE("%s: ION memory de-allocation failed", __func__);
   1604 
   1605 #if CAPTURE
   1606     /************************************************************************/
   1607     /* - Enqueue capture buffer back to USB camera                          */
   1608     /************************************************************************/
   1609        if(0 == put_buf_to_cam(camHal)) {
   1610             ALOGD("%s: put_buf_to_cam success", __func__);
   1611         }
   1612         else
   1613             ALOGE("%s: put_buf_to_cam error", __func__);
   1614 #endif
   1615 
   1616     ALOGD("%s: X, rc: %d", __func__, rc);
   1617     return rc;
   1618 }
   1619 #endif //#if 0
   1620 /******************************************************************************
   1621  * Function: cache_ops
   1622  * Description: This function calls ION ioctl for cache related operations
   1623  *
   1624  * Input parameters:
   1625  *  mem_info                - QCameraHalMemInfo_t structure with ION info
   1626  *  buf_ptr                 - Buffer pointer that needs to be cache operated
   1627  *  cmd                     - Cache command - clean/invalidate
   1628  *
   1629  * Return values:
   1630  *   MM_CAMERA_OK       No error
   1631  *   -1                 Error
   1632  *
   1633  * Notes: none
   1634  *****************************************************************************/
   1635 int cache_ops(QCameraHalMemInfo_t *mem_info,
   1636                                     void *buf_ptr,
   1637                                     unsigned int cmd)
   1638 {
   1639     struct ion_flush_data cache_inv_data;
   1640     struct ion_custom_data custom_data;
   1641     int ret = MM_CAMERA_OK;
   1642 
   1643 #ifdef USE_ION
   1644     if (NULL == mem_info) {
   1645         ALOGE("%s: mem_info is NULL, return here", __func__);
   1646         return -1;
   1647     }
   1648 
   1649     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
   1650     memset(&custom_data, 0, sizeof(custom_data));
   1651     cache_inv_data.vaddr = buf_ptr;
   1652     cache_inv_data.fd = mem_info->fd;
   1653     cache_inv_data.handle = mem_info->handle;
   1654     cache_inv_data.length = mem_info->size;
   1655     custom_data.cmd = cmd;
   1656     custom_data.arg = (unsigned long)&cache_inv_data;
   1657 
   1658     ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
   1659          __func__, cache_inv_data.vaddr, cache_inv_data.fd,
   1660          cache_inv_data.handle, cache_inv_data.length,
   1661          mem_info->main_ion_fd);
   1662     if(mem_info->main_ion_fd > 0) {
   1663         if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) {
   1664             ALOGE("%s: Cache Invalidate failed\n", __func__);
   1665             ret = -1;
   1666         }
   1667     }
   1668 #endif
   1669 
   1670     return ret;
   1671 }
   1672 
   1673 /******************************************************************************
   1674  * Function: get_buf_from_cam
   1675  * Description: This funtions gets/acquires 1 capture buffer from the camera
   1676  *              driver. The fetched buffer is stored in curCaptureBuf
   1677  *
   1678  * Input parameters:
   1679  *   camHal              - camera HAL handle
   1680  *
   1681  * Return values:
   1682  *   0      No error
   1683  *   -1     Error
   1684  *
   1685  * Notes: none
   1686  *****************************************************************************/
   1687 static int get_buf_from_cam(camera_hardware_t *camHal)
   1688 {
   1689     int rc = -1;
   1690 
   1691     ALOGD("%s: E", __func__);
   1692     {
   1693         memset(&camHal->curCaptureBuf, 0, sizeof(camHal->curCaptureBuf));
   1694 
   1695         camHal->curCaptureBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1696         camHal->curCaptureBuf.memory = V4L2_MEMORY_MMAP;
   1697 
   1698         if (-1 == ioctlLoop(camHal->fd, VIDIOC_DQBUF, &camHal->curCaptureBuf)){
   1699             switch (errno) {
   1700             case EAGAIN:
   1701                 ALOGE("%s: EAGAIN error", __func__);
   1702                 return 1;
   1703 
   1704             case EIO:
   1705             /* Could ignore EIO, see spec. */
   1706 
   1707             [[fallthrough]];
   1708 
   1709             default:
   1710             ALOGE("%s: VIDIOC_DQBUF error", __func__);
   1711             }
   1712         }
   1713         else
   1714         {
   1715             rc = 0;
   1716             ALOGD("%s: VIDIOC_DQBUF: %d successful, %d bytes",
   1717                  __func__, camHal->curCaptureBuf.index,
   1718                  camHal->curCaptureBuf.bytesused);
   1719         }
   1720     }
   1721     ALOGD("%s: X", __func__);
   1722     return rc;
   1723 }
   1724 
   1725 /******************************************************************************
   1726  * Function: put_buf_to_cam
   1727  * Description: This funtion puts/releases 1 capture buffer back to the camera
   1728  *              driver
   1729  *
   1730  * Input parameters:
   1731  *   camHal              - camera HAL handle
   1732  *
   1733  * Return values:
   1734  *   0      No error
   1735  *   -1     Error
   1736  *
   1737  * Notes: none
   1738  *****************************************************************************/
   1739 static int put_buf_to_cam(camera_hardware_t *camHal)
   1740 {
   1741     ALOGD("%s: E", __func__);
   1742 
   1743     camHal->curCaptureBuf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1744     camHal->curCaptureBuf.memory      = V4L2_MEMORY_MMAP;
   1745 
   1746 
   1747     if (-1 == ioctlLoop(camHal->fd, VIDIOC_QBUF, &camHal->curCaptureBuf))
   1748     {
   1749         ALOGE("%s: VIDIOC_QBUF failed ", __func__);
   1750         return 1;
   1751     }
   1752     ALOGD("%s: X", __func__);
   1753     return 0;
   1754 }
   1755 
   1756 /******************************************************************************
   1757  * Function: put_buf_to_cam
   1758  * Description: This funtion gets/acquires 1 display buffer from the display
   1759  *              window
   1760  *
   1761  * Input parameters:
   1762  *  camHal                  - camera HAL handle
   1763  *  buffer_id               - Buffer id pointer. The id of buffer obtained
   1764  *                              by this function is returned in this arg
   1765  *
   1766  * Return values:
   1767  *   0      No error
   1768  *   -1     Error
   1769  *
   1770  * Notes: none
   1771  *****************************************************************************/
   1772 static int get_buf_from_display(camera_hardware_t *camHal, int *buffer_id)
   1773 {
   1774     int                     err = 0;
   1775     preview_stream_ops      *mPreviewWindow = NULL;
   1776     int                     stride = 0, cnt = 0;
   1777     buffer_handle_t         *buffer_handle = NULL;
   1778     struct private_handle_t *private_buffer_handle = NULL;
   1779 
   1780     ALOGD("%s: E", __func__);
   1781 
   1782     if (camHal == NULL) {
   1783         ALOGE("%s: camHal = NULL", __func__);
   1784         return -1;
   1785     }
   1786 
   1787     mPreviewWindow = camHal->window;
   1788     if( mPreviewWindow == NULL) {
   1789         ALOGE("%s: mPreviewWindow = NULL", __func__);
   1790         return -1;
   1791     }
   1792     err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
   1793                                     &buffer_handle,
   1794                                     &stride);
   1795     if(!err) {
   1796         ALOGD("%s: dequeue buf buffer_handle: %p\n", __func__, buffer_handle);
   1797 
   1798         ALOGD("%s: mPreviewWindow->lock_buffer: %p",
   1799              __func__, mPreviewWindow->lock_buffer);
   1800         if(mPreviewWindow->lock_buffer) {
   1801             err = mPreviewWindow->lock_buffer(mPreviewWindow, buffer_handle);
   1802             ALOGD("%s: mPreviewWindow->lock_buffer success", __func__);
   1803         }
   1804         ALOGD("%s: camera call genlock_lock, hdl=%p",
   1805              __func__, (*buffer_handle));
   1806 
   1807         if (GENLOCK_NO_ERROR !=
   1808             genlock_lock_buffer((native_handle_t *)(*buffer_handle),
   1809                                 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
   1810            ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__);
   1811        } else {
   1812          ALOGD("%s: genlock_lock_buffer hdl =%p", __func__, *buffer_handle);
   1813        }
   1814 
   1815         private_buffer_handle = (struct private_handle_t *)(*buffer_handle);
   1816 
   1817         ALOGD("%s: fd = %d, size = %d, offset = %d, stride = %d",
   1818              __func__, private_buffer_handle->fd,
   1819         private_buffer_handle->size, private_buffer_handle->offset, stride);
   1820 
   1821         for(cnt = 0; cnt < camHal->previewMem.buffer_count + 2; cnt++) {
   1822             if(private_buffer_handle->fd ==
   1823                camHal->previewMem.private_buffer_handle[cnt]->fd) {
   1824                 *buffer_id = cnt;
   1825                 ALOGD("%s: deQueued fd = %d, index: %d",
   1826                      __func__, private_buffer_handle->fd, cnt);
   1827                 break;
   1828             }
   1829         }
   1830     }
   1831     else
   1832         ALOGE("%s: dequeue buf failed \n", __func__);
   1833 
   1834     ALOGD("%s: X", __func__);
   1835 
   1836     return err;
   1837 }
   1838 
   1839 /******************************************************************************
   1840  * Function: put_buf_to_display
   1841  * Description: This funtion puts/enqueues 1 buffer back to the display window
   1842  *
   1843  * Input parameters:
   1844  *  camHal                  - camera HAL handle
   1845  *  buffer_id               - id of the buffer that needs to be enqueued
   1846  *
   1847  * Return values:
   1848  *   0      No error
   1849  *   -1     Error
   1850  *
   1851  * Notes: none
   1852  *****************************************************************************/
   1853 static int put_buf_to_display(camera_hardware_t *camHal, int buffer_id)
   1854 {
   1855     int err = 0;
   1856     preview_stream_ops    *mPreviewWindow;
   1857 
   1858     ALOGD("%s: E", __func__);
   1859 
   1860     if (camHal == NULL) {
   1861         ALOGE("%s: camHal = NULL", __func__);
   1862         return -1;
   1863     }
   1864 
   1865     mPreviewWindow = camHal->window;
   1866     if( mPreviewWindow == NULL) {
   1867         ALOGE("%s: mPreviewWindow = NULL", __func__);
   1868         return -1;
   1869     }
   1870 
   1871     if (GENLOCK_FAILURE ==
   1872         genlock_unlock_buffer(
   1873             (native_handle_t *)
   1874             (*(camHal->previewMem.buffer_handle[buffer_id])))) {
   1875        ALOGE("%s: genlock_unlock_buffer failed: hdl =%p",
   1876             __func__, (*(camHal->previewMem.buffer_handle[buffer_id])) );
   1877     } else {
   1878       ALOGD("%s: genlock_unlock_buffer success: hdl =%p",
   1879            __func__, (*(camHal->previewMem.buffer_handle[buffer_id])) );
   1880     }
   1881 
   1882     /* Cache clean the output buffer so that cache is written back */
   1883     cache_ops(&camHal->previewMem.mem_info[buffer_id],
   1884                          (void *)camHal->previewMem.camera_memory[buffer_id]->data,
   1885                          ION_IOC_CLEAN_CACHES);
   1886                          /*
   1887     cache_ops(&camHal->previewMem.mem_info[buffer_id],
   1888                          (void *)camHal->previewMem.camera_memory[buffer_id]->data,
   1889                          ION_IOC_CLEAN_INV_CACHES);
   1890 */
   1891     err = mPreviewWindow->enqueue_buffer(mPreviewWindow,
   1892       (buffer_handle_t *)camHal->previewMem.buffer_handle[buffer_id]);
   1893     if(!err) {
   1894         ALOGD("%s: enqueue buf successful: %p\n",
   1895              __func__, camHal->previewMem.buffer_handle[buffer_id]);
   1896     }else
   1897         ALOGE("%s: enqueue buf failed: %p\n",
   1898              __func__, camHal->previewMem.buffer_handle[buffer_id]);
   1899 
   1900     ALOGD("%s: X", __func__);
   1901 
   1902     return err;
   1903 }
   1904 
   1905 /******************************************************************************
   1906  * Function: put_buf_to_display
   1907  * Description: This funtion transfers the content from capture buffer to
   1908  *              preiew display buffer after appropriate conversion
   1909  *
   1910  * Input parameters:
   1911  *  camHal                  - camera HAL handle
   1912  *  buffer_id               - id of the buffer that needs to be enqueued
   1913  *
   1914  * Return values:
   1915  *   0      No error
   1916  *   -1     Error
   1917  *
   1918  * Notes: none
   1919  *****************************************************************************/
   1920 static int convert_data_frm_cam_to_disp(camera_hardware_t *camHal, int buffer_id)
   1921 {
   1922     int rc = -1;
   1923 
   1924     if(!camHal) {
   1925         ALOGE("%s: camHal is NULL", __func__);
   1926         return -1;
   1927     }
   1928     /* If input and output are raw formats, but different color format, */
   1929     /* call color conversion routine                                    */
   1930     if( (V4L2_PIX_FMT_YUYV == camHal->captureFormat) &&
   1931         (HAL_PIXEL_FORMAT_YCrCb_420_SP == camHal->dispFormat))
   1932     {
   1933         convert_YUYV_to_420_NV12(
   1934             (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
   1935             (char *)camHal->previewMem.camera_memory[buffer_id]->data,
   1936             camHal->prevWidth,
   1937             camHal->prevHeight);
   1938         ALOGD("%s: Copied %d bytes from camera buffer %d to display buffer: %d",
   1939              __func__, camHal->curCaptureBuf.bytesused,
   1940              camHal->curCaptureBuf.index, buffer_id);
   1941         rc = 0;
   1942     }
   1943 
   1944     /* If camera buffer is MJPEG encoded, call mjpeg decode call */
   1945     if(V4L2_PIX_FMT_MJPEG == camHal->captureFormat)
   1946     {
   1947         if(NULL == camHal->mjpegd)
   1948         {
   1949             rc = mjpegDecoderInit(&camHal->mjpegd);
   1950             if(rc < 0)
   1951                 ALOGE("%s: mjpegDecoderInit Error: %d", __func__, rc);
   1952         }
   1953         if(camHal->mjpegd)
   1954         {
   1955             rc = mjpegDecode(
   1956                 (void*)camHal->mjpegd,
   1957                 (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
   1958                 camHal->curCaptureBuf.bytesused,
   1959                 (char *)camHal->previewMem.camera_memory[buffer_id]->data,
   1960                 (char *)camHal->previewMem.camera_memory[buffer_id]->data +
   1961                     camHal->prevWidth * camHal->prevHeight,
   1962                 getMjpegdOutputFormat(camHal->dispFormat));
   1963             if(rc < 0)
   1964                 ALOGE("%s: mjpegDecode Error: %d", __func__, rc);
   1965         }
   1966     }
   1967     return rc;
   1968 }
   1969 
   1970 /******************************************************************************
   1971  * Function: launch_preview_thread
   1972  * Description: This is a wrapper function to start preview thread
   1973  *
   1974  * Input parameters:
   1975  *  camHal                  - camera HAL handle
   1976  *
   1977  * Return values:
   1978  *   0      No error
   1979  *   -1     Error
   1980  *
   1981  * Notes: none
   1982  *****************************************************************************/
   1983 static int launch_preview_thread(camera_hardware_t *camHal)
   1984 {
   1985     ALOGD("%s: E", __func__);
   1986     int rc = 0;
   1987 
   1988     if(!camHal) {
   1989         ALOGE("%s: camHal is NULL", __func__);
   1990         return -1;
   1991     }
   1992 
   1993     pthread_attr_t attr;
   1994     pthread_attr_init(&attr);
   1995     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   1996     pthread_create(&camHal->previewThread, &attr, previewloop, camHal);
   1997 
   1998     ALOGD("%s: X", __func__);
   1999     return rc;
   2000 }
   2001 
   2002 /******************************************************************************
   2003  * Function: launch_preview_thread
   2004  * Description: This is thread funtion for preivew loop
   2005  *
   2006  * Input parameters:
   2007  *  hcamHal                 - camera HAL handle
   2008  *
   2009  * Return values:
   2010  *   0      No error
   2011  *   -1     Error
   2012  *
   2013  * Notes: none
   2014  *****************************************************************************/
   2015 static void * previewloop(void *hcamHal)
   2016 {
   2017     int                 rc;
   2018     int                 buffer_id   = 0;
   2019     pid_t               tid         = 0;
   2020     camera_hardware_t   *camHal     = NULL;
   2021     int                 msgType     = 0;
   2022     camera_memory_t     *data       = NULL;
   2023     camera_frame_metadata_t *metadata= NULL;
   2024     camera_memory_t     *previewMem = NULL;
   2025 
   2026     camHal = (camera_hardware_t *)hcamHal;
   2027     ALOGD("%s: E", __func__);
   2028 
   2029     if(!camHal) {
   2030         ALOGE("%s: camHal is NULL", __func__);
   2031         return NULL ;
   2032     }
   2033 
   2034     tid  = gettid();
   2035     /* TBR: Set appropriate thread priority */
   2036     androidSetThreadPriority(tid, ANDROID_PRIORITY_NORMAL);
   2037     prctl(PR_SET_NAME, (unsigned long)"Camera HAL preview thread", 0, 0, 0);
   2038 
   2039     /************************************************************************/
   2040     /* - Time wait (select) on camera fd for input read buffer              */
   2041     /* - Check if any preview thread commands are set. If set, process      */
   2042     /* - Dequeue display buffer from surface                                */
   2043     /* - Dequeue capture buffer from USB camera                             */
   2044     /* - Convert capture format to display format                           */
   2045     /* - If preview frames callback is requested, callback with prvw buffers*/
   2046     /* - Enqueue display buffer back to surface                             */
   2047     /* - Enqueue capture buffer back to USB camera                          */
   2048     /************************************************************************/
   2049     while(1) {
   2050         fd_set fds;
   2051         struct timeval tv;
   2052         int r = 0;
   2053 
   2054         FD_ZERO(&fds);
   2055 #if CAPTURE
   2056         FD_SET(camHal->fd, &fds);
   2057 #endif /* CAPTURE */
   2058 
   2059     /************************************************************************/
   2060     /* - Time wait (select) on camera fd for input read buffer              */
   2061     /************************************************************************/
   2062         tv.tv_sec = 0;
   2063         tv.tv_usec = 500000;
   2064 
   2065         ALOGD("%s: b4 select on camHal->fd + 1,fd: %d", __func__, camHal->fd);
   2066 #if CAPTURE
   2067         r = select(camHal->fd + 1, &fds, NULL, NULL, &tv);
   2068 #else
   2069         r = select(1, NULL, NULL, NULL, &tv);
   2070 #endif /* CAPTURE */
   2071         ALOGD("%s: after select : %d", __func__, camHal->fd);
   2072 
   2073         if (-1 == r) {
   2074             if (EINTR == errno)
   2075                 continue;
   2076             ALOGE("%s: FDSelect error: %d", __func__, errno);
   2077         }
   2078 
   2079         if (0 == r) {
   2080             ALOGD("%s: select timeout\n", __func__);
   2081         }
   2082 
   2083         /* Protect the context for one iteration of preview loop */
   2084         /* this gets unlocked at the end of the while */
   2085         Mutex::Autolock autoLock(camHal->lock);
   2086 
   2087     /************************************************************************/
   2088     /* - Check if any preview thread commands are set. If set, process      */
   2089     /************************************************************************/
   2090         if(camHal->prvwCmdPending)
   2091         {
   2092             /* command is serviced. Hence command pending = 0  */
   2093             camHal->prvwCmdPending--;
   2094             //sempost(ack)
   2095             if(USB_CAM_PREVIEW_EXIT == camHal->prvwCmd){
   2096                 /* unlock before exiting the thread */
   2097                 camHal->lock.unlock();
   2098                 ALOGI("%s: Exiting coz USB_CAM_PREVIEW_EXIT", __func__);
   2099                 return (void *)0;
   2100             }else if(USB_CAM_PREVIEW_TAKEPIC == camHal->prvwCmd){
   2101                 rc = prvwThreadTakePictureInternal(camHal);
   2102                 if(rc)
   2103                     ALOGE("%s: prvwThreadTakePictureInternal returned error",
   2104                     __func__);
   2105             }
   2106         }
   2107 
   2108         /* Null check on preview window. If null, sleep */
   2109         if(!camHal->window) {
   2110             ALOGD("%s: sleeping coz camHal->window = NULL",__func__);
   2111             camHal->lock.unlock();
   2112             sleep(2);
   2113             continue;
   2114         }
   2115 #if DISPLAY
   2116     /************************************************************************/
   2117     /* - Dequeue display buffer from surface                                */
   2118     /************************************************************************/
   2119         if(0 == get_buf_from_display(camHal, &buffer_id)) {
   2120             ALOGD("%s: get_buf_from_display success: %d",
   2121                  __func__, buffer_id);
   2122         }else{
   2123             ALOGE("%s: get_buf_from_display failed. Skipping the loop",
   2124                  __func__);
   2125             continue;
   2126         }
   2127 #endif
   2128 
   2129 #if CAPTURE
   2130     /************************************************************************/
   2131     /* - Dequeue capture buffer from USB camera                             */
   2132     /************************************************************************/
   2133         if (0 == get_buf_from_cam(camHal))
   2134             ALOGD("%s: get_buf_from_cam success", __func__);
   2135         else
   2136             ALOGE("%s: get_buf_from_cam error", __func__);
   2137 #endif
   2138 
   2139 #if FILE_DUMP_CAMERA
   2140         /* Debug code to dump frames from camera */
   2141         {
   2142             static int frame_cnt = 0;
   2143             /* currently hardcoded for Bytes-Per-Pixel = 1.5 */
   2144             fileDump("/data/USBcam.yuv",
   2145             (char*)camHal->buffers[camHal->curCaptureBuf.index].data,
   2146             camHal->prevWidth * camHal->prevHeight * 1.5,
   2147             &frame_cnt);
   2148         }
   2149 #endif
   2150 
   2151 #if MEMSET
   2152         static int color = 30;
   2153         color += 50;
   2154         if(color > 200) {
   2155             color = 30;
   2156         }
   2157         ALOGE("%s: Setting to the color: %d\n", __func__, color);
   2158         /* currently hardcoded for format of type Bytes-Per-Pixel = 1.5 */
   2159         memset(camHal->previewMem.camera_memory[buffer_id]->data,
   2160                color, camHal->dispWidth * camHal->dispHeight * 1.5 + 2 * 1024);
   2161 #else
   2162         convert_data_frm_cam_to_disp(camHal, buffer_id);
   2163         ALOGD("%s: Copied data to buffer_id: %d", __func__, buffer_id);
   2164 #endif
   2165 
   2166 #if FILE_DUMP_B4_DISP
   2167         /* Debug code to dump display buffers */
   2168         {
   2169             static int frame_cnt = 0;
   2170             /* currently hardcoded for Bytes-Per-Pixel = 1.5 */
   2171             fileDump("/data/display.yuv",
   2172                 (char*) camHal->previewMem.camera_memory[buffer_id]->data,
   2173                 camHal->dispWidth * camHal->dispHeight * 1.5,
   2174                 &frame_cnt);
   2175             ALOGD("%s: Written buf_index: %d ", __func__, buffer_id);
   2176         }
   2177 #endif
   2178 
   2179 #if DISPLAY
   2180     /************************************************************************/
   2181     /* - Enqueue display buffer back to surface                             */
   2182     /************************************************************************/
   2183        if(0 == put_buf_to_display(camHal, buffer_id)) {
   2184             ALOGD("%s: put_buf_to_display success: %d", __func__, buffer_id);
   2185         }
   2186         else
   2187             ALOGE("%s: put_buf_to_display error", __func__);
   2188 #endif
   2189 
   2190 #if CAPTURE
   2191      /************************************************************************/
   2192     /* - Enqueue capture buffer back to USB camera                          */
   2193     /************************************************************************/
   2194        if(0 == put_buf_to_cam(camHal)) {
   2195             ALOGD("%s: put_buf_to_cam success", __func__);
   2196         }
   2197         else
   2198             ALOGE("%s: put_buf_to_cam error", __func__);
   2199 #endif
   2200 
   2201 #if CALL_BACK
   2202     /************************************************************************/
   2203     /* - If preview frames callback is requested, callback with prvw buffers*/
   2204     /************************************************************************/
   2205         /* TBD: change the 1.5 hardcoding to Bytes Per Pixel */
   2206         int previewBufSize = camHal->prevWidth * camHal->prevHeight * 1.5;
   2207 
   2208         msgType |=  CAMERA_MSG_PREVIEW_FRAME;
   2209 
   2210         if(previewBufSize !=
   2211             camHal->previewMem.private_buffer_handle[buffer_id]->size) {
   2212 
   2213             previewMem = camHal->get_memory(
   2214                 camHal->previewMem.private_buffer_handle[buffer_id]->fd,
   2215                 previewBufSize,
   2216                 1,
   2217                 camHal->cb_ctxt);
   2218 
   2219               if (!previewMem || !previewMem->data) {
   2220                   ALOGE("%s: get_memory failed.\n", __func__);
   2221               }
   2222               else {
   2223                   data = previewMem;
   2224                   ALOGD("%s: GetMemory successful. data = %p",
   2225                             __func__, data);
   2226                   ALOGD("%s: previewBufSize = %d, priv_buf_size: %d",
   2227                     __func__, previewBufSize,
   2228                     camHal->previewMem.private_buffer_handle[buffer_id]->size);
   2229               }
   2230         }
   2231         else{
   2232             data =   camHal->previewMem.camera_memory[buffer_id];
   2233             ALOGD("%s: No GetMemory, no invalid fmt. data = %p, idx=%d",
   2234                 __func__, data, buffer_id);
   2235         }
   2236         /* Unlock and lock around the callback. */
   2237         /* Sometimes 'disable_msg' is issued in the callback context, */
   2238         /* leading to deadlock */
   2239         camHal->lock.unlock();
   2240         if((camHal->msgEnabledFlag & CAMERA_MSG_PREVIEW_FRAME) &&
   2241             camHal->data_cb){
   2242             ALOGD("%s: before data callback", __func__);
   2243             camHal->data_cb(msgType, data, 0,metadata, camHal->cb_ctxt);
   2244             ALOGD("%s: after data callback: %p", __func__, camHal->data_cb);
   2245         }
   2246         camHal->lock.lock();
   2247         if (previewMem)
   2248             previewMem->release(previewMem);
   2249 #endif
   2250 
   2251     }//while(1)
   2252     ALOGD("%s: X", __func__);
   2253     return (void *)0;
   2254 }
   2255 
   2256 /******************************************************************************
   2257  * Function: get_uvc_device
   2258  * Description: This function loops through /dev/video entries and probes with
   2259  *              UVCIOC query. If the device responds to the query, then it is
   2260  *              detected as UVC webcam
   2261  * Input parameters:
   2262  *   devname             - String pointer. The function return dev entry
   2263  *                          name in this string
   2264  * Return values:
   2265  *      0   Success
   2266  *      -1  Error
   2267  * Notes: none
   2268  *****************************************************************************/
   2269 static int get_uvc_device(char *devname)
   2270 {
   2271     char    temp_devname[FILENAME_LENGTH];
   2272     FILE    *fp = NULL;
   2273     int     i = 0, ret = 0, fd;
   2274 
   2275     ALOGD("%s: E", __func__);
   2276 #if 1
   2277     strncpy(devname, "/dev/video1", FILENAME_LENGTH);
   2278 
   2279 /*
   2280     struct          stat st;
   2281 
   2282     strncpy(dev_name, "/dev/video1", FILENAME_LENGTH);
   2283     if (-1 == stat(dev_name, &st)) {
   2284         ALOGE("%s: Cannot identify '%s': %d, %s\n",
   2285              __func__, dev_name, errno, strerror(errno));
   2286     }
   2287 
   2288     if (!S_ISCHR(st.st_mode)) {
   2289         ALOGE("%s: %s is no device\n", __func__, dev_name);
   2290         rc = -1;
   2291     }
   2292 */
   2293 
   2294 #else
   2295 
   2296     *devname = '\0';
   2297     /************************************************************************/
   2298     /* - List all /dev/video* entries to a file                             */
   2299     /* - Open the video list file and loop through the list                 */
   2300     /* - Send UVC specific control query and check the response             */
   2301     /* - If device responds to the query as success, device is UVC webcam   */
   2302     /************************************************************************/
   2303 
   2304     /************************************************************************/
   2305     /* - List all /dev/video* entries to a file                             */
   2306     /************************************************************************/
   2307     /* Temporarily commented out. This logic doesnt seem to be working */
   2308     //system("ls > /data/video_dev_list");
   2309 
   2310     /************************************************************************/
   2311     /* - Open the video list file and loop through the list                 */
   2312     /************************************************************************/
   2313 
   2314     /* Temporarily commented out. This logic doesnt seem to be working */
   2315     /*
   2316     fp = fopen("/data/video_dev_list", "rb");
   2317     if(!fp) {
   2318         ALOGE("%s: Error in opening /data/video_dev_list ", __func__);
   2319         return -1;
   2320     }
   2321     */
   2322 
   2323     /* Temporarily commented out. Looping logic changed due to issue in */
   2324     /* executing system("ls > /data/video_dev_list") */
   2325     //while(EOF != fscanf(fp, "%s", devname)){
   2326     while(1){
   2327         uvc_xu_control_query    xqry;
   2328 
   2329         sprintf(temp_devname, "/dev/video%d", i);
   2330         ALOGD("%s: Probing %s \n", __func__, temp_devname);
   2331 
   2332         fd = open(temp_devname, O_RDWR /* required */ | O_NONBLOCK, 0);
   2333         if(-1 != fd){
   2334             memset(&xqry, 0, sizeof(uvc_xu_control_query));
   2335             ret = ioctl(fd, UVCIOC_CTRL_QUERY, &xqry);
   2336             ALOGD("%s: UVCIOC ret: %d, errno: %d", __func__, ret, errno);
   2337             /****************************************************************/
   2338             /* if UVCIOC is executed successfully, ret = 0                  */
   2339             /* if UVCIOC is executed but Control Unit = 0 does not exist,   */
   2340             /*      ret = -1 and errno = ENOENT                             */
   2341             /* if UVCIOC doesnot execute, ret = -1 and errno = EINVAL       */
   2342             /****************************************************************/
   2343             if((0 == ret) || (ret && (ENOENT == errno))){
   2344                 ALOGD("%s: Found UVC node: %s\n", __func__, temp_devname);
   2345                 strncpy(devname, temp_devname, FILENAME_LENGTH);
   2346                 /* Exit the loop at the first UVC node detection */
   2347                 break;
   2348             }
   2349             close(fd);
   2350         }
   2351         /* Temporarily logic to probe video0 to video10 nodes */
   2352         if(i++ > 10)
   2353         {
   2354             if(fp)
   2355                 fclose(fp);
   2356             break;
   2357         }
   2358     }
   2359 #endif /* #if 0 */
   2360     ALOGD("%s: X", __func__);
   2361     return 0;
   2362 } /* get_uvc_device */
   2363 
   2364 /******************************************************************************
   2365  * Function: fileDump
   2366  * Description: This is a utility function to dump buffers into a file
   2367  *
   2368  * Input parameters:
   2369  *  fn              - File name string
   2370  *  data            - pointer to character buffer that needs to be dumped
   2371  *  length          - Length of the buffer to be dumped
   2372  *  frm_cnt         - Pointer to frame count. This count is incremented by this
   2373  *                      function on successful file write
   2374  * Return values:
   2375  *      0   Success
   2376  *      -1  Error
   2377  * Notes: none
   2378  *****************************************************************************/
   2379 static int fileDump(const char* fn, char* data, int length, int* frm_cnt)
   2380 {
   2381 
   2382     FILE *fp = NULL;
   2383     if (0 == *frm_cnt) {
   2384         fp = fopen(fn, "wb");
   2385         if (NULL == fp) {
   2386             ALOGE("%s: Error in opening %s", __func__, fn);
   2387         }
   2388         fclose(fp);
   2389     }
   2390     fp = fopen(fn, "ab");
   2391     if (NULL == fp) {
   2392         ALOGE("%s: Error in opening %s", __func__, fn);
   2393     }
   2394     fwrite(data, 1, length, fp);
   2395     fclose(fp);
   2396     (*frm_cnt)++;
   2397     ALOGD("%s: Written %d bytes for frame:%d, in %s",
   2398         __func__, length, *frm_cnt, fn);
   2399 
   2400     return 0;
   2401 }
   2402 
   2403 /******************************************************************************
   2404  * Function: launchTakePictureThread
   2405  * Description: This is a wrapper function to start take picture thread
   2406  *
   2407  * Input parameters:
   2408  *  camHal                  - camera HAL handle
   2409  *
   2410  * Return values:
   2411  *   0      No error
   2412  *   -1     Error
   2413  *
   2414  * Notes: none
   2415  *****************************************************************************/
   2416 static int launchTakePictureThread(camera_hardware_t *camHal)
   2417 {
   2418     ALOGD("%s: E", __func__);
   2419     int rc = 0;
   2420 
   2421     if(!camHal) {
   2422         ALOGE("%s: camHal is NULL", __func__);
   2423         return -1;
   2424     }
   2425 
   2426     pthread_attr_t attr;
   2427     pthread_attr_init(&attr);
   2428     /* create the thread in detatched state, when the thread exits all */
   2429     /* memory resources are freed up */
   2430     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   2431     pthread_create(&camHal->takePictureThread, &attr, takePictureThread, camHal);
   2432 
   2433     ALOGD("%s: X", __func__);
   2434     return rc;
   2435 }
   2436 
   2437 /******************************************************************************
   2438  * Function: takePictureThread
   2439  * Description: This function is associated with take picture thread
   2440  *
   2441  * Input parameters:
   2442  *  camHal                  - camera HAL handle
   2443  *
   2444  * Return values:
   2445  *   0      No error
   2446  *   -1     Error
   2447  *
   2448  * Notes: none
   2449  *****************************************************************************/
   2450 static void * takePictureThread(void *hcamHal)
   2451 {
   2452     int                 rc = 0;
   2453     int                 buffer_id   = 0;
   2454     pid_t               tid         = 0;
   2455     camera_hardware_t   *camHal     = NULL;
   2456     int                 msgType     = 0;
   2457     int                 jpegLength  = 0;
   2458     QCameraHalMemInfo_t *mem_info   = NULL;
   2459 
   2460     camHal = (camera_hardware_t *)hcamHal;
   2461     ALOGI("%s: E", __func__);
   2462 
   2463     if(!camHal) {
   2464         ALOGE("%s: camHal is NULL", __func__);
   2465         return NULL ;
   2466     }
   2467 
   2468     tid  = gettid();
   2469     /* TBR: Set appropriate thread priority */
   2470     androidSetThreadPriority(tid, ANDROID_PRIORITY_NORMAL);
   2471     prctl(PR_SET_NAME, (unsigned long)"Camera HAL preview thread", 0, 0, 0);
   2472 
   2473     /************************************************************************/
   2474     /* - If requested for shutter notfication, notify                       */
   2475     /* - Initialize USB camera with snapshot parameters                     */
   2476     /* - Time wait (select) on camera fd for camera frame availability      */
   2477     /* - Dequeue capture buffer from USB camera                             */
   2478     /* - Send capture buffer to JPEG encoder for JPEG compression           */
   2479     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
   2480     /* - Enqueue capture buffer back to USB camera                          */
   2481     /* - Free USB camera resources and close camera                         */
   2482     /* - If preview was stopped for taking picture, restart the preview     */
   2483     /************************************************************************/
   2484 
   2485     Mutex::Autolock autoLock(camHal->lock);
   2486     /************************************************************************/
   2487     /* - If requested for shutter notfication, notify                       */
   2488     /************************************************************************/
   2489 #if 0 /* TBD: Temporarily commented out due to an issue. Sometimes it takes */
   2490     /* long time to get back the lock once unlocked and notify callback */
   2491     if (camHal->msgEnabledFlag & CAMERA_MSG_SHUTTER){
   2492         camHal->lock.unlock();
   2493         camHal->notify_cb(CAMERA_MSG_SHUTTER, 0, 0, camHal->cb_ctxt);
   2494         camHal->lock.lock();
   2495     }
   2496 #endif
   2497     /************************************************************************/
   2498     /* - Initialize USB camera with snapshot parameters                     */
   2499     /************************************************************************/
   2500     USB_CAM_OPEN(camHal);
   2501 
   2502 #if JPEG_ON_USB_CAMERA
   2503     rc = initUsbCamera(camHal, camHal->pictWidth, camHal->pictHeight,
   2504                         V4L2_PIX_FMT_MJPEG);
   2505 #else
   2506     rc = initUsbCamera(camHal, camHal->pictWidth, camHal->pictHeight,
   2507                         V4L2_PIX_FMT_YUYV);
   2508 #endif
   2509     ERROR_CHECK_EXIT_THREAD(rc, "initUsbCamera");
   2510 
   2511     rc = startUsbCamCapture(camHal);
   2512     ERROR_CHECK_EXIT_THREAD(rc, "startUsbCamCapture");
   2513 
   2514     /************************************************************************/
   2515     /* - Time wait (select) on camera fd for camera frame availability      */
   2516     /************************************************************************/
   2517     {
   2518         fd_set fds;
   2519         struct timeval tv;
   2520         int r = 0;
   2521 
   2522         FD_ZERO(&fds);
   2523         FD_SET(camHal->fd, &fds);
   2524 
   2525         tv.tv_sec = 1;
   2526         tv.tv_usec = 0;
   2527 
   2528         do{
   2529             ALOGD("%s: b4 select on camHal->fd : %d", __func__, camHal->fd);
   2530             r = select(camHal->fd + 1, &fds, NULL, NULL, &tv);
   2531             ALOGD("%s: after select", __func__);
   2532         }while((0 == r) || ((-1 == r) && (EINTR == errno)));
   2533 
   2534         if ((-1 == r) && (EINTR != errno)){
   2535             ALOGE("%s: FDSelect ret = %d error: %d", __func__, r, errno);
   2536             return (void *)-1;
   2537         }
   2538 
   2539     }
   2540     /************************************************************************/
   2541     /* - Dequeue capture buffer from USB camera                             */
   2542     /************************************************************************/
   2543     if (0 == get_buf_from_cam(camHal))
   2544         ALOGD("%s: get_buf_from_cam success", __func__);
   2545     else
   2546         ALOGE("%s: get_buf_from_cam error", __func__);
   2547 
   2548     /************************************************************************/
   2549     /* - Send capture buffer to JPEG encoder for JPEG compression           */
   2550     /************************************************************************/
   2551     mem_info = &camHal->pictMem.mem_info[0];
   2552     mem_info->size = MAX_JPEG_BUFFER_SIZE;
   2553 
   2554     rc = allocate_ion_memory(mem_info,
   2555                         ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
   2556                         (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
   2557     if(rc)
   2558         ALOGE("%s: ION memory allocation failed", __func__);
   2559 
   2560     camHal->pictMem.camera_memory[0] = camHal->get_memory(
   2561                         mem_info->fd, mem_info->size, 1, camHal->cb_ctxt);
   2562     if(!camHal->pictMem.camera_memory[0])
   2563         ALOGE("%s: get_mem failed", __func__);
   2564 
   2565 #if FREAD_JPEG_PICTURE
   2566     jpegLength = readFromFile("/data/tempVGA.jpeg",
   2567                     (char*)camHal->pictMem.camera_memory[0]->data,
   2568                     camHal->pictMem.camera_memory[0]->size);
   2569     camHal->pictMem.camera_memory[0]->size = jpegLength;
   2570 
   2571 #elif JPEG_ON_USB_CAMERA
   2572     memcpy((char*)camHal->pictMem.camera_memory[0]->data,
   2573             (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
   2574             camHal->curCaptureBuf.bytesused);
   2575     camHal->pictMem.camera_memory[0]->size = camHal->curCaptureBuf.bytesused;
   2576     jpegLength = camHal->curCaptureBuf.bytesused;
   2577 
   2578 #else
   2579     rc = encodeJpeg(camHal);
   2580     ERROR_CHECK_EXIT_THREAD(rc, "jpeg_encode");
   2581 #endif
   2582     if(jpegLength <= 0)
   2583         ALOGI("%s: jpegLength : %d", __func__, jpegLength);
   2584 
   2585      ALOGD("%s: jpegLength : %d", __func__, jpegLength);
   2586     /************************************************************************/
   2587     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
   2588     /************************************************************************/
   2589     /* TBD: CAMERA_MSG_RAW_IMAGE data call back */
   2590 
   2591     if ((camHal->msgEnabledFlag & CAMERA_MSG_COMPRESSED_IMAGE) &&
   2592             (camHal->data_cb)){
   2593         /* Unlock temporarily, callback might call HAL api in turn */
   2594         camHal->lock.unlock();
   2595 
   2596         camHal->data_cb(CAMERA_MSG_COMPRESSED_IMAGE,
   2597                         camHal->pictMem.camera_memory[0],
   2598                         0, NULL, camHal->cb_ctxt);
   2599         camHal->lock.lock();
   2600     }
   2601 
   2602     /* release heap memory after the call back */
   2603     if(camHal->pictMem.camera_memory[0])
   2604         camHal->pictMem.camera_memory[0]->release(
   2605             camHal->pictMem.camera_memory[0]);
   2606 
   2607     rc = deallocate_ion_memory(mem_info);
   2608     if(rc)
   2609         ALOGE("%s: ION memory de-allocation failed", __func__);
   2610 
   2611     /************************************************************************/
   2612     /* - Enqueue capture buffer back to USB camera                          */
   2613     /************************************************************************/
   2614     if(0 == put_buf_to_cam(camHal)) {
   2615         ALOGD("%s: put_buf_to_cam success", __func__);
   2616     }
   2617     else
   2618         ALOGE("%s: put_buf_to_cam error", __func__);
   2619 
   2620     /************************************************************************/
   2621     /* - Free USB camera resources and close camera                         */
   2622     /************************************************************************/
   2623     rc = stopUsbCamCapture(camHal);
   2624     ERROR_CHECK_EXIT_THREAD(rc, "stopUsbCamCapture");
   2625 
   2626     rc = unInitV4L2mmap(camHal);
   2627     ERROR_CHECK_EXIT_THREAD(rc, "unInitV4L2mmap");
   2628 
   2629     USB_CAM_CLOSE(camHal);
   2630     /************************************************************************/
   2631     /* - If preview was stopped for taking picture, restart the preview     */
   2632     /************************************************************************/
   2633     if(camHal->prvwStoppedForPicture)
   2634     {
   2635         struct camera_device    device;
   2636         device.priv = (void *)camHal;
   2637 
   2638         USB_CAM_OPEN(camHal);
   2639         /* Unlock temporarily coz usbcam_start_preview has a lock */
   2640         camHal->lock.unlock();
   2641         rc = usbcam_start_preview(&device);
   2642         if(rc)
   2643             ALOGE("%s: start_preview error after take picture", __func__);
   2644         camHal->lock.lock();
   2645         camHal->prvwStoppedForPicture = 0;
   2646     }
   2647 
   2648     /* take picture activity is done */
   2649     camHal->takePictInProgress = 0;
   2650 
   2651     ALOGI("%s: X", __func__);
   2652     return (void *)0;
   2653 }
   2654 
   2655 /******************************************************************************
   2656  * Function: allocate_ion_memory
   2657  * Description: This function is allocates ION memory
   2658  *
   2659  * Input parameters:
   2660  *  camHal                  - camera HAL handle
   2661  *
   2662  * Return values:
   2663  *   0      No error
   2664  *   -1     Error
   2665  *
   2666  * Notes: none
   2667  *****************************************************************************/
   2668 static int allocate_ion_memory(QCameraHalMemInfo_t *mem_info, int ion_type)
   2669 {
   2670     int                         rc = 0;
   2671     struct ion_handle_data      handle_data;
   2672     struct ion_allocation_data  alloc;
   2673     struct ion_fd_data          ion_info_fd;
   2674     int                         main_ion_fd = 0;
   2675 
   2676     main_ion_fd = open("/dev/ion", O_RDONLY);
   2677     if (main_ion_fd <= 0) {
   2678         ALOGE("Ion dev open failed %s\n", strerror(errno));
   2679         goto ION_OPEN_FAILED;
   2680     }
   2681 
   2682     memset(&alloc, 0, sizeof(alloc));
   2683     alloc.len = mem_info->size;
   2684     /* to make it page size aligned */
   2685     alloc.len = (alloc.len + 4095) & (~4095);
   2686     alloc.align = 4096;
   2687     alloc.flags = ION_FLAG_CACHED;
   2688     alloc.heap_id_mask = ion_type;
   2689     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
   2690     if (rc < 0) {
   2691         ALOGE("ION allocation failed\n");
   2692         goto ION_ALLOC_FAILED;
   2693     }
   2694 
   2695     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
   2696     ion_info_fd.handle = alloc.handle;
   2697     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
   2698     if (rc < 0) {
   2699         ALOGE("ION map failed %s\n", strerror(errno));
   2700         goto ION_MAP_FAILED;
   2701     }
   2702 
   2703     mem_info->main_ion_fd = main_ion_fd;
   2704     mem_info->fd = ion_info_fd.fd;
   2705     mem_info->handle = ion_info_fd.handle;
   2706     mem_info->size = alloc.len;
   2707     return 0;
   2708 
   2709 ION_MAP_FAILED:
   2710     memset(&handle_data, 0, sizeof(handle_data));
   2711     handle_data.handle = ion_info_fd.handle;
   2712     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
   2713 ION_ALLOC_FAILED:
   2714     close(main_ion_fd);
   2715 ION_OPEN_FAILED:
   2716     return -1;
   2717 }
   2718 
   2719 /******************************************************************************
   2720  * Function: deallocate_ion_memory
   2721  * Description: This function de allocates ION memory
   2722  *
   2723  * Input parameters:
   2724  *  camHal                  - camera HAL handle
   2725  *
   2726  * Return values:
   2727  *   0      No error
   2728  *   -1     Error
   2729  *
   2730  * Notes: none
   2731  *****************************************************************************/
   2732 static int deallocate_ion_memory(QCameraHalMemInfo_t *mem_info)
   2733 {
   2734   struct ion_handle_data handle_data;
   2735   int rc = 0;
   2736 
   2737   if (mem_info->fd > 0) {
   2738       close(mem_info->fd);
   2739       mem_info->fd = 0;
   2740   }
   2741 
   2742   if (mem_info->main_ion_fd > 0) {
   2743       memset(&handle_data, 0, sizeof(handle_data));
   2744       handle_data.handle = mem_info->handle;
   2745       ioctl(mem_info->main_ion_fd, ION_IOC_FREE, &handle_data);
   2746       close(mem_info->main_ion_fd);
   2747       mem_info->main_ion_fd = 0;
   2748   }
   2749   return rc;
   2750 }
   2751 
   2752 /******************************************************************************
   2753  * Function: readFromFile
   2754  * Description: This function reads data from the given file into given buffer
   2755  *
   2756  * Input parameters:
   2757  *  camHal                  - camera HAL handle
   2758  *
   2759  * Return values:
   2760  *   int    bytesRead
   2761  *
   2762  * Notes: none
   2763  *****************************************************************************/
   2764 static int readFromFile(char* fileName, char* buffer, int bufferSize)
   2765 {
   2766     int bytesRead = 0, fileSize = 0;
   2767     FILE *fp;
   2768 
   2769     fp = fopen(fileName, "rb");
   2770     if(!fp){
   2771         ALOGE("%s: Error in opening %s ", __func__, fileName);
   2772         return bytesRead;
   2773     }
   2774 
   2775     /* If file is bigger for given buffer, exit */
   2776     if (fileSize > bufferSize){
   2777         ALOGE("%s: Error %d > %d", __func__, fileSize, bufferSize);
   2778         return bytesRead;
   2779     }
   2780 
   2781     bytesRead = fread(buffer, 1, bufferSize, fp);
   2782     ALOGD(" %s: bytesRead: %d", __func__, bytesRead);
   2783 
   2784     return bytesRead;
   2785 }
   2786 
   2787 /******************************************************************************
   2788  * Function: encodeJpeg
   2789  * Description: This function initializes Jpeg encoder and calls jpeg encoder
   2790  *              call and waits for the encode to complete
   2791  *
   2792  * Input parameters:
   2793  *  camHal                  - camera HAL handle
   2794  *
   2795  * Return values:
   2796  *   0  No Error
   2797  *  -1  Error
   2798  *
   2799  * Notes: none
   2800  *****************************************************************************/
   2801 int encodeJpeg(camera_hardware_t *camHal)
   2802 {
   2803     int                 rc = 0;
   2804     mm_jpeg_ops_t       mmJpegOps;
   2805     int                 jpegEncHdl  = 0;
   2806     mm_jpeg_job         mmJpegJob;
   2807     src_image_buffer_info   *srcBuf = NULL;
   2808     QCameraHalMemInfo_t jpegInMemInfo;
   2809     camera_memory_t*    jpegInMem;
   2810     uint32_t            jobId;
   2811 
   2812     ALOGI("%s: E", __func__);
   2813 
   2814     /************************************************************************/
   2815     /* - Allocate Jpeg input buffer from ION memory                         */
   2816     /************************************************************************/
   2817     jpegInMemInfo.size = camHal->pictWidth * camHal->pictHeight * 2;
   2818     rc = allocate_ion_memory(&jpegInMemInfo,
   2819                         ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
   2820                         (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
   2821     ERROR_CHECK_EXIT(rc, "allocate_ion_memory");
   2822 
   2823     jpegInMem = camHal->get_memory(
   2824                         jpegInMemInfo.fd, jpegInMemInfo.size, 1, camHal->cb_ctxt);
   2825     if(!jpegInMem){
   2826         ALOGE("%s: get_mem failed", __func__);
   2827         return -1;
   2828     }
   2829 
   2830     rc = convert_YUYV_to_420_NV12(
   2831         (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
   2832         (char *)jpegInMem->data, camHal->pictWidth, camHal->pictHeight);
   2833     ERROR_CHECK_EXIT(rc, "convert_YUYV_to_420_NV12");
   2834     /************************************************************************/
   2835     /* - Populate JPEG encoding parameters from the camHal context          */
   2836     /************************************************************************/
   2837     memset(&mmJpegJob, 0, sizeof(mmJpegJob));
   2838 
   2839     mmJpegJob.job_type              = JPEG_JOB_TYPE_ENCODE;
   2840     mmJpegJob.encode_job.jpeg_cb    = jpegEncodeCb;
   2841     mmJpegJob.encode_job.userdata   = (void *)camHal;
   2842     /* TBD: Rotation to be set from settings sent from app */
   2843     mmJpegJob.encode_job.encode_parm.rotation           = 0;
   2844     mmJpegJob.encode_job.encode_parm.exif_numEntries    = 0;
   2845     mmJpegJob.encode_job.encode_parm.exif_data          = NULL;
   2846 
   2847     /* TBD: Add thumbnail support */
   2848     mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.src_img_num = 1;
   2849     mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.is_video_frame = 0;
   2850 
   2851     /* Fill main image information */
   2852     srcBuf = &mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.src_img[0];
   2853     srcBuf->type                = JPEG_SRC_IMAGE_TYPE_MAIN;
   2854     srcBuf->img_fmt             = JPEG_SRC_IMAGE_FMT_YUV;
   2855     /* TBD: convert from YUYV to CRCBH2V2 */
   2856     srcBuf->color_format        = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
   2857     srcBuf->num_bufs            = 1;
   2858     srcBuf->src_image[0].fd        = jpegInMemInfo.fd;
   2859     srcBuf->src_image[0].buf_vaddr = (uint8_t*)jpegInMem->data;
   2860     //srcBuf->src_image[0].offset    = 0;
   2861     srcBuf->src_dim.width       = camHal->pictWidth;
   2862     srcBuf->src_dim.height      = camHal->pictHeight;
   2863     srcBuf->out_dim.width       = camHal->pictWidth;
   2864     srcBuf->out_dim.height      = camHal->pictHeight;
   2865     srcBuf->crop.offset_x       = 0;
   2866     srcBuf->crop.offset_y       = 0;
   2867     srcBuf->crop.width          = srcBuf->src_dim.width;
   2868     srcBuf->crop.height         = srcBuf->src_dim.height;
   2869     srcBuf->quality             = camHal->pictJpegQlty;
   2870 
   2871     /* TBD:Fill thumbnail image information */
   2872 
   2873     /* Fill out buf information */
   2874     mmJpegJob.encode_job.encode_parm.buf_info.sink_img.buf_vaddr =
   2875                             (uint8_t*)camHal->pictMem.camera_memory[0]->data;
   2876     mmJpegJob.encode_job.encode_parm.buf_info.sink_img.fd = 0;
   2877     /* TBD: hard coded for 1.5 bytes per pixel */
   2878     mmJpegJob.encode_job.encode_parm.buf_info.sink_img.buf_len =
   2879                             camHal->pictWidth * camHal->pictHeight * 1.5;
   2880 
   2881     /************************************************************************/
   2882     /* - Initialize jpeg encoder and call Jpeg encoder start                */
   2883     /************************************************************************/
   2884     memset(&mmJpegOps, 0, sizeof(mm_jpeg_ops_t));
   2885     jpegEncHdl = jpeg_open(&mmJpegOps);
   2886     if(!jpegEncHdl){
   2887         ALOGE("%s: Failed to open Jpeg Encoder instance", __func__);
   2888     }else
   2889         ALOGD("%s: jpegEncHdl = %d", __func__, jpegEncHdl);
   2890 
   2891     camHal->jpegEncInProgress = 1;
   2892     rc = mmJpegOps.start_job(jpegEncHdl, &mmJpegJob, &jobId);
   2893 
   2894     /************************************************************************/
   2895     /* - Wait for JPEG encoder to complete encoding                         */
   2896     /************************************************************************/
   2897     pthread_mutex_init(&camHal->jpegEncMutex, NULL);
   2898     pthread_cond_init(&camHal->jpegEncCond, NULL);
   2899 
   2900     pthread_mutex_lock(&camHal->jpegEncMutex);
   2901     while(camHal->jpegEncInProgress)
   2902         pthread_cond_wait(&camHal->jpegEncCond, &camHal->jpegEncMutex);
   2903     pthread_mutex_unlock(&camHal->jpegEncMutex);
   2904 
   2905     /************************************************************************/
   2906     /* - De-allocate Jpeg input buffer from ION memory                      */
   2907     /************************************************************************/
   2908     if(jpegInMem)
   2909         jpegInMem->release(jpegInMem);
   2910 
   2911     rc = deallocate_ion_memory(&jpegInMemInfo);
   2912     if(rc)
   2913         ALOGE("%s: ION memory de-allocation failed", __func__);
   2914 
   2915     ALOGI("%s: X rc = %d", __func__, rc);
   2916     return rc;
   2917 }
   2918 
   2919 /******************************************************************************
   2920  * Function: jpegEncodeCb
   2921  * Description: This is a call back function registered with JPEG encoder.
   2922  *              Jpeg encoder calls this function on completion of encoding
   2923  *
   2924  * Input parameters:
   2925  *  camHal                  - camera HAL handle
   2926  *
   2927  * Return values:
   2928  *   0  No Error
   2929  *  -1  Error
   2930  *
   2931  * Notes: none
   2932  *****************************************************************************/
   2933 void jpegEncodeCb   (jpeg_job_status_t status,
   2934                        uint8_t thumbnailDroppedFlag,
   2935                        uint32_t client_hdl,
   2936                        uint32_t jobId,
   2937                        uint8_t* out_data,
   2938                        uint32_t data_size,
   2939                        void *userData)
   2940 {
   2941     int rc = 0;
   2942     camera_hardware_t *camHal = NULL;
   2943 
   2944     ALOGI("%s: E status = %d", __func__, status);
   2945 
   2946     camHal = (camera_hardware_t*) userData;
   2947 
   2948     if(JPEG_JOB_STATUS_DONE == status){
   2949         ALOGD("%s: JPEG encode successful. out_data:%p, size: %d", __func__,
   2950             out_data, data_size);
   2951         camHal->jpegEncInProgress = 0;
   2952     }
   2953 
   2954     pthread_mutex_lock(&camHal->jpegEncMutex);
   2955     pthread_cond_signal(&camHal->jpegEncCond);
   2956     pthread_mutex_unlock(&camHal->jpegEncMutex);
   2957 
   2958     ALOGI("%s: X", __func__);
   2959     return;
   2960 }
   2961 
   2962 /******************************************************************************/
   2963 }; // namespace android
   2964