Home | History | Annotate | Download | only in mm-camera-interface
      1 /*
      2 Copyright (c) 2011-2012,2015, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <pthread.h>
     31 #include "mm_camera_dbg.h"
     32 #include <errno.h>
     33 #include <sys/ioctl.h>
     34 #include <sys/types.h>
     35 #include <sys/stat.h>
     36 #include <fcntl.h>
     37 #include <stddef.h>
     38 #include <poll.h>
     39 #include <linux/media.h>
     40 
     41 #include "mm_camera_interface2.h"
     42 #include "mm_camera.h"
     43 
     44 #define SET_PARM_BIT32(parm, parm_arr) \
     45     (parm_arr[parm/32] |= (1<<(parm%32)))
     46 
     47 #define GET_PARM_BIT32(parm, parm_arr) \
     48     ((parm_arr[parm/32]>>(parm%32))& 0x1)
     49 
     50 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
     51 
     52 static mm_camera_ctrl_t g_cam_ctrl;
     53 
     54 static int mm_camera_util_opcode_2_ch_type(mm_camera_obj_t *my_obj,
     55                                         mm_camera_ops_type_t opcode)
     56 {
     57     switch(opcode) {
     58     case MM_CAMERA_OPS_PREVIEW:
     59         return MM_CAMERA_CH_PREVIEW;
     60     case MM_CAMERA_OPS_ZSL:
     61     case MM_CAMERA_OPS_SNAPSHOT:
     62         return MM_CAMERA_CH_SNAPSHOT;
     63     case MM_CAMERA_OPS_PREPARE_SNAPSHOT:
     64         return MM_CAMERA_CH_SNAPSHOT;
     65     case MM_CAMERA_OPS_RAW:
     66         return MM_CAMERA_CH_RAW;
     67     default:
     68         break;
     69     }
     70     return -1;
     71 }
     72 
     73 const char *mm_camera_util_get_dev_name(mm_camera_obj_t * my_obj)
     74 {
     75     CDBG("%s: Returning %s at index :%d\n",
     76         __func__,g_cam_ctrl.camera[my_obj->my_id].video_dev_name,my_obj->my_id);
     77     return g_cam_ctrl.camera[my_obj->my_id].video_dev_name;
     78 }
     79 
     80 /* used for querying the camera_info of the given camera_id */
     81 static const qcamera_info_t * mm_camera_cfg_query_camera_info (int8_t camera_id)
     82 {
     83     if(camera_id >= MSM_MAX_CAMERA_SENSORS)
     84         return NULL;
     85     return &g_cam_ctrl.camera[camera_id].camera_info;
     86 }
     87 /* check if the parm is supported */
     88 static uint8_t mm_camera_cfg_is_parm_supported (mm_camera_t * camera,
     89                                                 mm_camera_parm_type_t parm_type)
     90 {
     91     int is_parm_supported = 0;
     92     mm_camera_obj_t * my_obj = NULL;
     93 
     94     pthread_mutex_lock(&g_mutex);
     95     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
     96     pthread_mutex_unlock(&g_mutex);
     97     if(my_obj) {
     98         pthread_mutex_lock(&my_obj->mutex);
     99         is_parm_supported = GET_PARM_BIT32(parm_type,
    100                                            my_obj->properties.parm);
    101         pthread_mutex_unlock(&my_obj->mutex);
    102     }
    103 
    104     return is_parm_supported;
    105 }
    106 
    107 /* check if the channel is supported */
    108 static uint8_t mm_camera_cfg_is_ch_supported (mm_camera_t * camera,
    109                                   mm_camera_channel_type_t ch_type)
    110 {
    111     switch(ch_type) {
    112     case MM_CAMERA_CH_PREVIEW:
    113     case MM_CAMERA_CH_VIDEO:
    114     case MM_CAMERA_CH_SNAPSHOT:
    115     case MM_CAMERA_CH_RAW:
    116         return TRUE;
    117     case MM_CAMERA_CH_MAX:
    118     default:
    119         return FALSE;
    120     }
    121     return FALSE;
    122 }
    123 
    124 /* set a parms current value */
    125 static int32_t mm_camera_cfg_set_parm (mm_camera_t * camera,
    126                                        mm_camera_parm_type_t parm_type,
    127                                        void *p_value)
    128 {
    129     int32_t rc = -MM_CAMERA_E_GENERAL;
    130     uint32_t tmp;
    131     mm_camera_obj_t * my_obj = NULL;
    132     mm_camera_parm_t parm = {.parm_type = parm_type, .p_value = p_value};
    133 
    134     pthread_mutex_lock(&g_mutex);
    135     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    136     pthread_mutex_unlock(&g_mutex);
    137     if(my_obj) {
    138         pthread_mutex_lock(&my_obj->mutex);
    139         rc = mm_camera_set_parm(my_obj, &parm);
    140         pthread_mutex_unlock(&my_obj->mutex);
    141     }
    142     return rc;
    143 }
    144 
    145 /* get a parms current value */
    146 static int32_t mm_camera_cfg_get_parm (mm_camera_t * camera,
    147                                        mm_camera_parm_type_t parm_type,
    148                                        void* p_value)
    149 {
    150     int32_t rc = -MM_CAMERA_E_GENERAL;
    151     uint32_t tmp;
    152     mm_camera_obj_t * my_obj = NULL;
    153     mm_camera_parm_t parm = {.parm_type = parm_type, .p_value = p_value};
    154 
    155     pthread_mutex_lock(&g_mutex);
    156     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    157     pthread_mutex_unlock(&g_mutex);
    158     if(my_obj) {
    159         pthread_mutex_lock(&my_obj->mutex);
    160         rc =  mm_camera_get_parm(my_obj, &parm);
    161         pthread_mutex_unlock(&my_obj->mutex);
    162     }
    163     return rc;
    164 }
    165 
    166 static int32_t mm_camera_cfg_request_buf(mm_camera_t * camera,
    167                                          mm_camera_reg_buf_t *buf)
    168 {
    169     int32_t rc = -MM_CAMERA_E_GENERAL;
    170     uint32_t tmp;
    171     mm_camera_obj_t * my_obj = NULL;
    172 
    173     pthread_mutex_lock(&g_mutex);
    174     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    175     pthread_mutex_unlock(&g_mutex);
    176     if(my_obj) {
    177         pthread_mutex_lock(&my_obj->mutex);
    178         rc =  mm_camera_request_buf(my_obj, buf);
    179         pthread_mutex_unlock(&my_obj->mutex);
    180     }
    181     return rc;
    182 }
    183 
    184 static int32_t mm_camera_cfg_prepare_buf(mm_camera_t * camera,
    185                                          mm_camera_reg_buf_t *buf)
    186 {
    187     int32_t rc = -MM_CAMERA_E_GENERAL;
    188     uint32_t tmp;
    189     mm_camera_obj_t * my_obj = NULL;
    190 
    191     pthread_mutex_lock(&g_mutex);
    192     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    193     pthread_mutex_unlock(&g_mutex);
    194     if(my_obj) {
    195         pthread_mutex_lock(&my_obj->mutex);
    196         rc =  mm_camera_prepare_buf(my_obj, buf);
    197         pthread_mutex_unlock(&my_obj->mutex);
    198     }
    199     return rc;
    200 }
    201 static int32_t mm_camera_cfg_unprepare_buf(mm_camera_t * camera,
    202                                            mm_camera_channel_type_t ch_type)
    203 {
    204     int32_t rc = -MM_CAMERA_E_GENERAL;
    205     uint32_t tmp;
    206     mm_camera_obj_t * my_obj = NULL;
    207 
    208     pthread_mutex_lock(&g_mutex);
    209     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    210     pthread_mutex_unlock(&g_mutex);
    211     if(my_obj) {
    212         pthread_mutex_lock(&my_obj->mutex);
    213         rc =  mm_camera_unprepare_buf(my_obj,ch_type);
    214         pthread_mutex_unlock(&my_obj->mutex);
    215     }
    216     return rc;
    217 }
    218 
    219 static mm_camera_config_t mm_camera_cfg = {
    220   .is_parm_supported = mm_camera_cfg_is_parm_supported,
    221   .is_ch_supported = mm_camera_cfg_is_ch_supported,
    222   .set_parm = mm_camera_cfg_set_parm,
    223   .get_parm = mm_camera_cfg_get_parm,
    224   .request_buf = mm_camera_cfg_request_buf,
    225   .prepare_buf = mm_camera_cfg_prepare_buf,
    226   .unprepare_buf = mm_camera_cfg_unprepare_buf
    227 };
    228 
    229 static uint8_t mm_camera_ops_is_op_supported (mm_camera_t * camera,
    230                                               mm_camera_ops_type_t opcode)
    231 {
    232     uint8_t is_ops_supported;
    233     mm_camera_obj_t * my_obj = NULL;
    234     int index = 0;
    235     mm_camera_legacy_ops_type_t legacy_opcode = CAMERA_OPS_MAX;
    236 
    237     /* Temp: We will be translating our new opcode
    238        to legacy ops type. This is just a hack to
    239        temporarily unblock APT team. New design is
    240        under discussion */
    241     switch (opcode) {
    242     case MM_CAMERA_OPS_PREVIEW:
    243         legacy_opcode = CAMERA_OPS_STREAMING_PREVIEW;
    244         break;
    245     case MM_CAMERA_OPS_VIDEO:
    246         legacy_opcode = CAMERA_OPS_STREAMING_VIDEO;
    247         break;
    248     case MM_CAMERA_OPS_PREPARE_SNAPSHOT:
    249         legacy_opcode = CAMERA_OPS_PREPARE_SNAPSHOT;
    250         break;
    251     case MM_CAMERA_OPS_SNAPSHOT:
    252         legacy_opcode = CAMERA_OPS_SNAPSHOT;
    253         break;
    254     case MM_CAMERA_OPS_RAW:
    255         legacy_opcode = CAMERA_OPS_RAW_CAPTURE;
    256         break;
    257     case MM_CAMERA_OPS_ZSL:
    258         legacy_opcode = CAMERA_OPS_STREAMING_ZSL;
    259         break;
    260     case MM_CAMERA_OPS_FOCUS:
    261         legacy_opcode = CAMERA_OPS_FOCUS;
    262         break;
    263     case MM_CAMERA_OPS_GET_BUFFERED_FRAME:
    264       legacy_opcode = CAMERA_OPS_LOCAL;
    265       is_ops_supported = TRUE;
    266       CDBG("MM_CAMERA_OPS_GET_BUFFERED_FRAME not handled");
    267       break;
    268     default:
    269       CDBG_ERROR("%s: case %d not handled", __func__, opcode);
    270       legacy_opcode = CAMERA_OPS_LOCAL;
    271       is_ops_supported = FALSE;
    272       break;
    273     }
    274     if (legacy_opcode != CAMERA_OPS_LOCAL) {
    275     pthread_mutex_lock(&g_mutex);
    276     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    277     pthread_mutex_unlock(&g_mutex);
    278     if(my_obj) {
    279         pthread_mutex_lock(&my_obj->mutex);
    280         index = legacy_opcode/32;  /* 32 bits */
    281         is_ops_supported = ((my_obj->properties.ops[index] &
    282             (1<<legacy_opcode)) != 0);
    283         pthread_mutex_unlock(&my_obj->mutex);
    284       } else {
    285         is_ops_supported = FALSE;
    286       }
    287     }
    288 
    289     return is_ops_supported;
    290 }
    291 
    292 static int32_t mm_camera_ops_action (mm_camera_t * camera, uint8_t start,
    293                                     mm_camera_ops_type_t opcode, void *val)
    294 {
    295     int32_t rc = -MM_CAMERA_E_GENERAL;
    296     mm_camera_obj_t * my_obj = NULL;
    297     pthread_mutex_lock(&g_mutex);
    298     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    299     pthread_mutex_unlock(&g_mutex);
    300     if(my_obj) {
    301         pthread_mutex_lock(&my_obj->mutex);
    302         rc = mm_camera_action(my_obj, start, opcode, val);
    303         pthread_mutex_unlock(&my_obj->mutex);
    304     }
    305     return rc;
    306 }
    307 
    308 /* open uses flags to optionally disable jpeg/vpe interface. */
    309 static int32_t mm_camera_ops_open (mm_camera_t * camera,
    310                                    mm_camera_op_mode_type_t op_mode)
    311 {
    312     int8_t camera_id = camera->camera_info.camera_id;
    313     int32_t rc = MM_CAMERA_OK;
    314 
    315     CDBG("%s: BEGIN\n", __func__);
    316     pthread_mutex_lock(&g_mutex);
    317     /* not first open */
    318     if(g_cam_ctrl.cam_obj[camera_id]) {
    319         g_cam_ctrl.cam_obj[camera_id]->ref_count++;
    320     CDBG("%s:  opened alreadyn", __func__);
    321         goto end;
    322     }
    323     g_cam_ctrl.cam_obj[camera_id] =
    324     (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
    325     if(!g_cam_ctrl.cam_obj[camera_id]) {
    326         rc = -MM_CAMERA_E_NO_MEMORY;
    327      CDBG("%s:  no mem", __func__);
    328        goto end;
    329     }
    330     memset(g_cam_ctrl.cam_obj[camera_id], 0,
    331                  sizeof(mm_camera_obj_t));
    332     //g_cam_ctrl.cam_obj[camera_id]->ctrl_fd = -1;
    333     g_cam_ctrl.cam_obj[camera_id]->ref_count++;
    334     g_cam_ctrl.cam_obj[camera_id]->my_id=camera_id;
    335 
    336     pthread_mutex_init(&g_cam_ctrl.cam_obj[camera_id]->mutex, NULL);
    337     rc = mm_camera_open(g_cam_ctrl.cam_obj[camera_id], op_mode);
    338     if(rc < 0) {
    339         CDBG("%s: open failed, rc = %d\n", __func__, rc);
    340         pthread_mutex_destroy(&g_cam_ctrl.cam_obj[camera_id]->mutex);
    341         g_cam_ctrl.cam_obj[camera_id]->ref_count--;
    342         free(g_cam_ctrl.cam_obj[camera_id]);
    343         g_cam_ctrl.cam_obj[camera_id]=NULL;
    344     CDBG("%s: mm_camera_open err = %d", __func__, rc);
    345         goto end;
    346     }else{
    347         CDBG("%s: open succeded\n", __func__);
    348     }
    349 end:
    350     pthread_mutex_unlock(&g_mutex);
    351     CDBG("%s: END, rc=%d\n", __func__, rc);
    352     return rc;
    353 }
    354 
    355 static void mm_camera_ops_close (mm_camera_t * camera)
    356 {
    357     mm_camera_obj_t * my_obj;
    358     int i;
    359     int8_t camera_id = camera->camera_info.camera_id;
    360 
    361     pthread_mutex_lock(&g_mutex);
    362     my_obj = g_cam_ctrl.cam_obj[camera_id];
    363     if(my_obj) {
    364       my_obj->ref_count--;
    365       if(my_obj->ref_count > 0) {
    366         CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    367       } else {
    368         // mm_camera_poll_thread_release(my_obj, MM_CAMERA_CH_MAX);
    369         (void)mm_camera_close(g_cam_ctrl.cam_obj[camera_id]);
    370         pthread_mutex_destroy(&my_obj->mutex);
    371         free(my_obj);
    372         g_cam_ctrl.cam_obj[camera_id] = NULL;
    373       }
    374     }
    375     pthread_mutex_unlock(&g_mutex);
    376 }
    377 
    378 static void mm_camera_ops_stop (mm_camera_t * camera)
    379 {
    380     mm_camera_obj_t * my_obj;
    381     int i;
    382     int8_t camera_id = camera->camera_info.camera_id;
    383 
    384     pthread_mutex_lock(&g_mutex);
    385     my_obj = g_cam_ctrl.cam_obj[camera_id];
    386     if(my_obj) {
    387         CDBG("%s : Close Threads in mm_camera_ops_stop",__func__);
    388         for(i = 0; i <= MM_CAMERA_CH_MAX; i++) {
    389             mm_camera_poll_thread_release(my_obj,(mm_camera_channel_type_t)i);
    390         }
    391         mm_camera_poll_threads_deinit(my_obj);
    392     }
    393     pthread_mutex_unlock(&g_mutex);
    394 }
    395 
    396 
    397 static int32_t mm_camera_ops_ch_acquire(mm_camera_t * camera,
    398                                         mm_camera_channel_type_t ch_type)
    399 {
    400     int32_t rc = -MM_CAMERA_E_GENERAL;
    401     mm_camera_obj_t * my_obj = NULL;
    402     pthread_mutex_lock(&g_mutex);
    403     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    404     pthread_mutex_unlock(&g_mutex);
    405     if(my_obj) {
    406         pthread_mutex_lock(&my_obj->mutex);
    407         rc = mm_camera_ch_acquire(my_obj, ch_type);
    408         pthread_mutex_unlock(&my_obj->mutex);
    409     }
    410     return rc;
    411 
    412 }
    413 static void mm_camera_ops_ch_release(mm_camera_t * camera, mm_camera_channel_type_t ch_type)
    414 {
    415     mm_camera_obj_t * my_obj = NULL;
    416     pthread_mutex_lock(&g_mutex);
    417     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    418     pthread_mutex_unlock(&g_mutex);
    419     if(my_obj) {
    420         pthread_mutex_lock(&my_obj->mutex);
    421         mm_camera_ch_release(my_obj, ch_type);
    422         pthread_mutex_unlock(&my_obj->mutex);
    423     }
    424 }
    425 
    426 static int32_t mm_camera_ops_ch_attr(mm_camera_t * camera,
    427                                      mm_camera_channel_type_t ch_type,
    428                                      mm_camera_channel_attr_t *attr)
    429 {
    430     mm_camera_obj_t * my_obj = NULL;
    431     int32_t rc = -MM_CAMERA_E_GENERAL;
    432     pthread_mutex_lock(&g_mutex);
    433     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    434     pthread_mutex_unlock(&g_mutex);
    435     if(my_obj) {
    436         pthread_mutex_lock(&my_obj->mutex);
    437         rc = mm_camera_ch_fn(my_obj, ch_type, MM_CAMERA_STATE_EVT_ATTR,
    438                             (void *)attr);
    439         pthread_mutex_unlock(&my_obj->mutex);
    440     }
    441     return rc;
    442 }
    443 
    444 static int32_t mm_camera_ops_sendmsg(mm_camera_t * camera,
    445                                      void *msg,
    446                                      uint32_t buf_size,
    447                                      int sendfd)
    448 {
    449     int32_t rc = -MM_CAMERA_E_GENERAL;
    450     mm_camera_obj_t * my_obj = NULL;
    451     pthread_mutex_lock(&g_mutex);
    452     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    453     pthread_mutex_unlock(&g_mutex);
    454     if(my_obj) {
    455         pthread_mutex_lock(&my_obj->mutex);
    456         rc = mm_camera_sendmsg(my_obj, msg, buf_size, sendfd);
    457         pthread_mutex_unlock(&my_obj->mutex);
    458     }
    459     return rc;
    460 }
    461 
    462 static mm_camera_ops_t mm_camera_ops = {
    463   .is_op_supported = mm_camera_ops_is_op_supported,
    464     .action = mm_camera_ops_action,
    465     .open = mm_camera_ops_open,
    466     .close = mm_camera_ops_close,
    467     .stop = mm_camera_ops_stop,
    468     .ch_acquire = mm_camera_ops_ch_acquire,
    469     .ch_release = mm_camera_ops_ch_release,
    470     .ch_set_attr = mm_camera_ops_ch_attr,
    471     .sendmsg = mm_camera_ops_sendmsg
    472 };
    473 
    474 static uint8_t mm_camera_notify_is_event_supported(mm_camera_t * camera,
    475                                 mm_camera_event_type_t evt_type)
    476 {
    477   switch(evt_type) {
    478   case MM_CAMERA_EVT_TYPE_CH:
    479   case MM_CAMERA_EVT_TYPE_CTRL:
    480   case MM_CAMERA_EVT_TYPE_STATS:
    481   case MM_CAMERA_EVT_TYPE_INFO:
    482     return 1;
    483   default:
    484     return 0;
    485   }
    486   return 0;
    487 }
    488 
    489 static int32_t mm_camera_notify_register_event_cb(mm_camera_t * camera,
    490                                    mm_camera_event_notify_t evt_cb,
    491                                     void * user_data,
    492                                    mm_camera_event_type_t evt_type)
    493 {
    494   mm_camera_obj_t * my_obj = NULL;
    495   mm_camera_buf_cb_t reg ;
    496   int rc = -1;
    497 
    498   pthread_mutex_lock(&g_mutex);
    499   my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    500   pthread_mutex_unlock(&g_mutex);
    501   if(my_obj) {
    502       pthread_mutex_lock(&my_obj->mutex);
    503       rc = mm_camera_reg_event(my_obj, evt_cb, user_data, evt_type);
    504       pthread_mutex_unlock(&my_obj->mutex);
    505   }
    506   return rc;
    507 }
    508 
    509 static int32_t mm_camera_register_buf_notify (
    510           mm_camera_t * camera,
    511           mm_camera_channel_type_t ch_type,
    512           mm_camera_buf_notify_t  buf_cb,
    513           mm_camera_register_buf_cb_type_t cb_type,
    514           uint32_t cb_count,
    515           void * user_data)
    516 {
    517     mm_camera_obj_t * my_obj = NULL;
    518     mm_camera_buf_cb_t reg ;
    519     int rc = -1;
    520 
    521     reg.cb = buf_cb;
    522     reg.user_data = user_data;
    523     reg.cb_type=cb_type;
    524     reg.cb_count=cb_count;
    525     pthread_mutex_lock(&g_mutex);
    526     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    527     pthread_mutex_unlock(&g_mutex);
    528     if(my_obj) {
    529         pthread_mutex_lock(&my_obj->mutex);
    530         rc = mm_camera_ch_fn(my_obj,ch_type,
    531                             MM_CAMERA_STATE_EVT_REG_BUF_CB, (void *)&reg);
    532         pthread_mutex_unlock(&my_obj->mutex);
    533     }
    534     return rc;
    535 }
    536 static int32_t mm_camera_buf_done(mm_camera_t * camera, mm_camera_ch_data_buf_t * bufs)
    537 {
    538     mm_camera_obj_t * my_obj = NULL;
    539     int rc = -1;
    540     my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
    541     if(my_obj) {
    542         /*pthread_mutex_lock(&my_obj->mutex);*/
    543         rc = mm_camera_ch_fn(my_obj, bufs->type,
    544                  MM_CAMERA_STATE_EVT_QBUF,   (void *)bufs);
    545         /*pthread_mutex_unlock(&my_obj->mutex);*/
    546     }
    547     return rc;
    548 }
    549 
    550 static mm_camera_notify_t mm_camera_notify = {
    551     .is_event_supported = mm_camera_notify_is_event_supported,
    552     .register_event_notify = mm_camera_notify_register_event_cb,
    553     .register_buf_notify = mm_camera_register_buf_notify,
    554     .buf_done = mm_camera_buf_done
    555 };
    556 
    557 static uint8_t mm_camera_jpeg_is_jpeg_supported (mm_camera_t * camera)
    558 {
    559     return FALSE;
    560 }
    561 static int32_t mm_camera_jpeg_set_parm (mm_camera_t * camera,
    562                     mm_camera_jpeg_parm_type_t parm_type,
    563                     void* p_value)
    564 {
    565     return -1;
    566 }
    567 static int32_t mm_camera_jpeg_get_parm (mm_camera_t * camera,
    568                     mm_camera_jpeg_parm_type_t parm_type,
    569                     void* p_value)
    570 {
    571     return -1;
    572 }
    573 static int32_t mm_camera_jpeg_register_event_cb(mm_camera_t * camera,
    574                     mm_camera_jpeg_cb_t * evt_cb,
    575                     void * user_data)
    576 {
    577     return -1;
    578 }
    579 static int32_t mm_camera_jpeg_encode (mm_camera_t * camera, uint8_t start,
    580                     mm_camera_jpeg_encode_t *data)
    581 {
    582     return -1;
    583 }
    584 
    585 static mm_camera_jpeg_t mm_camera_jpeg =  {
    586     .is_jpeg_supported = mm_camera_jpeg_is_jpeg_supported,
    587     .set_parm = mm_camera_jpeg_set_parm,
    588     .get_parm = mm_camera_jpeg_get_parm,
    589     .register_event_cb = mm_camera_jpeg_register_event_cb,
    590     .encode = mm_camera_jpeg_encode,
    591 };
    592 
    593 extern mm_camera_t * mm_camera_query (uint8_t *num_cameras)
    594 {
    595     int i = 0, rc = MM_CAMERA_OK;
    596     int dev_fd = 0;
    597     struct media_device_info mdev_info;
    598     int num_media_devices = 0;
    599     if (!num_cameras)
    600       return NULL;
    601     /* lock the mutex */
    602     pthread_mutex_lock(&g_mutex);
    603     *num_cameras = 0;
    604     while (1) {
    605       char dev_name[32];
    606       snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
    607       dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    608       if (dev_fd < 0) {
    609         CDBG("Done discovering media devices\n");
    610         break;
    611       }
    612       num_media_devices++;
    613       rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
    614       if (rc < 0) {
    615         CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
    616         close(dev_fd);
    617         break;
    618       }
    619 
    620       if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) {
    621         close(dev_fd);
    622         continue;
    623       }
    624 
    625       char * mdev_cfg;
    626       int cam_type = 0, mount_angle = 0, info_index = 0;
    627       mdev_cfg = strtok(mdev_info.serial, "-");
    628       while(mdev_cfg != NULL) {
    629           if(info_index == 0) {
    630               if(strcmp(mdev_cfg, QCAMERA_NAME))
    631                   break;
    632           } else if(info_index == 1) {
    633               mount_angle = atoi(mdev_cfg);
    634           } else if(info_index == 2) {
    635               cam_type = atoi(mdev_cfg);
    636           }
    637           mdev_cfg = strtok(NULL, "-");
    638           info_index++;
    639       }
    640 
    641       if(info_index == 0) {
    642           close(dev_fd);
    643           continue;
    644       }
    645 
    646       int num_entities = 1;
    647       while (1) {
    648         struct media_entity_desc entity;
    649         memset(&entity, 0, sizeof(entity));
    650         entity.id = num_entities++;
    651         rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
    652         if (rc < 0) {
    653             CDBG("Done enumerating media entities\n");
    654             rc = 0;
    655             break;
    656         }
    657         if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
    658              strncpy(g_cam_ctrl.camera[*num_cameras].video_dev_name,
    659                      entity.name, sizeof(entity.name));
    660              break;
    661         }
    662       }
    663 
    664       g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras;
    665 
    666       g_cam_ctrl.camera[*num_cameras].
    667           camera_info.modes_supported = CAMERA_MODE_2D;
    668       if(cam_type > 1)
    669         g_cam_ctrl.camera[*num_cameras].
    670           camera_info.modes_supported |= CAMERA_MODE_3D;
    671 
    672       g_cam_ctrl.camera[*num_cameras].camera_info.position =
    673         (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA;
    674       g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle =
    675           mount_angle;
    676       g_cam_ctrl.camera[*num_cameras].sensor_type = 0;
    677       g_cam_ctrl.camera[*num_cameras].cfg = &mm_camera_cfg;
    678       g_cam_ctrl.camera[*num_cameras].ops = &mm_camera_ops;
    679       g_cam_ctrl.camera[*num_cameras].evt = &mm_camera_notify;
    680       g_cam_ctrl.camera[*num_cameras].jpeg_ops = NULL;
    681 
    682       CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d]\n",
    683         __func__, *num_cameras,
    684         g_cam_ctrl.camera[*num_cameras].video_dev_name,
    685         g_cam_ctrl.camera[*num_cameras].camera_info.position,
    686         g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported,
    687         g_cam_ctrl.camera[*num_cameras].sensor_type);
    688 
    689       *num_cameras+=1;
    690       if (dev_fd > 0) {
    691           close(dev_fd);
    692       }
    693     }
    694     *num_cameras = *num_cameras;
    695     g_cam_ctrl.num_cam = *num_cameras;
    696 end:
    697     /* unlock the mutex */
    698     pthread_mutex_unlock(&g_mutex);
    699     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
    700     if(rc == 0)
    701         return &g_cam_ctrl.camera[0];
    702     else
    703         return NULL;
    704 }
    705 
    706 
    707 static mm_camera_t * get_camera_by_id( int cam_id)
    708 {
    709   mm_camera_t * mm_cam;
    710   if( cam_id < 0 || cam_id >= g_cam_ctrl.num_cam) {
    711      mm_cam = NULL;
    712   } else {
    713     mm_cam = & g_cam_ctrl.camera[cam_id];
    714   }
    715   return mm_cam;
    716 }
    717 
    718 /*configure methods*/
    719 uint8_t cam_config_is_parm_supported(
    720   int cam_id,
    721   mm_camera_parm_type_t parm_type)
    722 {
    723   uint8_t rc = 0;
    724   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    725   if (mm_cam && mm_cam->cfg) {
    726     rc = mm_cam->cfg->is_parm_supported(mm_cam, parm_type);
    727   }
    728   return rc;
    729 }
    730 
    731 uint8_t cam_config_is_ch_supported(
    732   int cam_id,
    733   mm_camera_channel_type_t ch_type)
    734 {
    735   uint8_t rc = 0;
    736   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    737   if (mm_cam) {
    738     rc = mm_cam->cfg->is_ch_supported(mm_cam, ch_type);
    739   }
    740   return rc;
    741 
    742 }
    743 
    744 /* set a parms current value */
    745 int32_t cam_config_set_parm(
    746   int cam_id,
    747   mm_camera_parm_type_t parm_type,
    748   void* p_value)
    749 {
    750   int32_t rc = -1;
    751   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    752   if (mm_cam) {
    753     rc = mm_cam->cfg->set_parm(mm_cam, parm_type, p_value);
    754   }
    755   return rc;
    756 }
    757 
    758 /* get a parms current value */
    759 int32_t cam_config_get_parm(
    760   int cam_id,
    761   mm_camera_parm_type_t parm_type,
    762   void* p_value)
    763 {
    764   int32_t rc = -1;
    765   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    766   if (mm_cam) {
    767     rc = mm_cam->cfg->get_parm(mm_cam, parm_type, p_value);
    768   }
    769   return rc;
    770 }
    771 
    772 int32_t cam_config_request_buf(int cam_id, mm_camera_reg_buf_t *buf)
    773 {
    774 
    775   int32_t rc = -1;
    776   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    777   if (mm_cam) {
    778     rc = mm_cam->cfg->request_buf(mm_cam, buf);
    779   }
    780   return rc;
    781 }
    782 
    783 int32_t cam_config_prepare_buf(int cam_id, mm_camera_reg_buf_t *buf)
    784 {
    785 
    786   int32_t rc = -1;
    787   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    788   if (mm_cam) {
    789     rc = mm_cam->cfg->prepare_buf(mm_cam, buf);
    790   }
    791   return rc;
    792 }
    793 int32_t cam_config_unprepare_buf(int cam_id, mm_camera_channel_type_t ch_type)
    794 {
    795   int32_t rc = -1;
    796   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    797   if (mm_cam) {
    798     rc = mm_cam->cfg->unprepare_buf(mm_cam, ch_type);
    799   }
    800   return rc;
    801 }
    802 
    803 /*operation methods*/
    804 uint8_t cam_ops_is_op_supported(int cam_id, mm_camera_ops_type_t opcode)
    805 {
    806   uint8_t rc = 0;
    807   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    808   if (mm_cam) {
    809     rc = mm_cam->ops->is_op_supported(mm_cam, opcode);
    810   }
    811   return rc;
    812 }
    813 /* val is reserved for some action such as MM_CAMERA_OPS_FOCUS */
    814 int32_t cam_ops_action(int cam_id, uint8_t start,
    815   mm_camera_ops_type_t opcode, void *val)
    816 {
    817   int32_t rc = -1;
    818   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    819   if (mm_cam) {
    820     rc = mm_cam->ops->action(mm_cam, start, opcode, val);
    821   }
    822   return rc;
    823 }
    824 
    825 int32_t cam_ops_open(int cam_id, mm_camera_op_mode_type_t op_mode)
    826 {
    827   int32_t rc = -1;
    828   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    829   if (mm_cam) {
    830     rc = mm_cam->ops->open(mm_cam, op_mode);
    831   }
    832   return rc;
    833 }
    834 
    835 void cam_ops_close(int cam_id)
    836 {
    837   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    838   if (mm_cam) {
    839     mm_cam->ops->close(mm_cam);
    840   }
    841 }
    842 
    843 void cam_ops_stop(int cam_id)
    844 {
    845   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    846   if (mm_cam) {
    847     mm_cam->ops->stop(mm_cam);
    848   }
    849 }
    850 
    851 int32_t cam_ops_ch_acquire(int cam_id, mm_camera_channel_type_t ch_type)
    852 {
    853   int32_t rc = -1;
    854   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    855   if (mm_cam) {
    856     rc = mm_cam->ops->ch_acquire(mm_cam, ch_type);
    857   }
    858   return rc;
    859 }
    860 
    861 void cam_ops_ch_release(int cam_id, mm_camera_channel_type_t ch_type)
    862 {
    863   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    864   if (mm_cam) {
    865     mm_cam->ops->ch_release(mm_cam, ch_type);
    866   }
    867 }
    868 
    869 int32_t cam_ops_ch_set_attr(int cam_id, mm_camera_channel_type_t ch_type,
    870   mm_camera_channel_attr_t *attr)
    871 {
    872   int32_t rc = -1;
    873   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    874   if (mm_cam) {
    875     rc = mm_cam->ops->ch_set_attr(mm_cam, ch_type, attr);
    876   }
    877   return rc;
    878 }
    879 
    880 int32_t cam_ops_sendmsg(int cam_id, void *msg, uint32_t buf_size, int sendfd)
    881 {
    882     int32_t rc = -1;
    883     mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    884     if (mm_cam) {
    885       rc = mm_cam->ops->sendmsg(mm_cam, msg, buf_size, sendfd);
    886     }
    887     return rc;
    888 }
    889 
    890 /*call-back notify methods*/
    891 uint8_t cam_evt_is_event_supported(int cam_id, mm_camera_event_type_t evt_type)
    892 {
    893   uint8_t rc = 0;
    894   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    895   if (mm_cam) {
    896     rc = mm_cam->evt->is_event_supported(mm_cam, evt_type);
    897   }
    898   return rc;
    899 }
    900 
    901 int32_t cam_evt_register_event_notify(int cam_id,
    902   mm_camera_event_notify_t evt_cb,
    903   void * user_data,
    904   mm_camera_event_type_t evt_type)
    905 {
    906   int32_t rc = -1;
    907   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    908   if (mm_cam) {
    909     rc = mm_cam->evt->register_event_notify(
    910       mm_cam, evt_cb, user_data, evt_type);
    911   }
    912   return rc;
    913 }
    914 
    915 int32_t cam_evt_register_buf_notify(int cam_id,
    916   mm_camera_channel_type_t ch_type,
    917   mm_camera_buf_notify_t buf_cb,
    918   mm_camera_register_buf_cb_type_t cb_type,
    919   uint32_t cb_count,
    920   void * user_data)
    921 {
    922   int32_t rc = -1;
    923   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    924   if (mm_cam) {
    925     rc = mm_cam->evt->register_buf_notify(
    926       mm_cam, ch_type, buf_cb, cb_type,
    927       cb_count, user_data);
    928   }
    929   return rc;
    930 }
    931 
    932 int32_t cam_evt_buf_done(int cam_id, mm_camera_ch_data_buf_t *bufs)
    933 {
    934   int32_t rc = -1;
    935   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    936   if (mm_cam) {
    937     rc = mm_cam->evt->buf_done(mm_cam, bufs);
    938   }
    939   return rc;
    940 }
    941 
    942 /*camera JPEG methods*/
    943 uint8_t cam_jpeg_is_jpeg_supported(int cam_id)
    944 {
    945   uint8_t rc = 0;
    946   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    947   if (mm_cam) {
    948     rc = mm_cam->jpeg_ops->is_jpeg_supported(mm_cam);
    949   }
    950   return rc;
    951 }
    952 
    953 int32_t cam_jpeg_set_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type,
    954   void* p_value)
    955 {
    956   int32_t rc = -1;
    957   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    958   if (mm_cam) {
    959     rc = mm_cam->jpeg_ops->set_parm(mm_cam, parm_type, p_value);
    960   }
    961   return rc;
    962 }
    963 
    964 int32_t cam_jpeg_get_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type,
    965   void* p_value)
    966 {
    967   int32_t rc = -1;
    968   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    969   if (mm_cam) {
    970     rc = mm_cam->jpeg_ops->get_parm(mm_cam, parm_type, p_value);
    971   }
    972   return rc;
    973 }
    974 int32_t cam_jpeg_register_event_cb(int cam_id, mm_camera_jpeg_cb_t * evt_cb,
    975   void * user_data)
    976 {
    977   int32_t rc = -1;
    978   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    979   if (mm_cam) {
    980     rc = mm_cam->jpeg_ops->register_event_cb(mm_cam, evt_cb, user_data);
    981   }
    982   return rc;
    983 }
    984 int32_t cam_jpeg_encode(int cam_id, uint8_t start,
    985   mm_camera_jpeg_encode_t *data)
    986 {
    987   int32_t rc = -1;
    988   mm_camera_t * mm_cam = get_camera_by_id(cam_id);
    989   if (mm_cam) {
    990     rc = mm_cam->jpeg_ops->encode(mm_cam, start, data);
    991   }
    992   return rc;
    993 }
    994 
    995