Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2013, 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  */
     29 
     30 #include <pthread.h>
     31 #include <errno.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <fcntl.h>
     36 #include <poll.h>
     37 #include <linux/media.h>
     38 
     39 #include "mm_camera_dbg.h"
     40 #include "mm_camera_interface.h"
     41 #include "mm_camera_sock.h"
     42 #include "mm_camera.h"
     43 
     44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
     45 
     46 static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}};
     47 
     48 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
     49 static uint16_t g_handler_history_count = 0; /* history count for handler */
     50 
     51 /*===========================================================================
     52  * FUNCTION   : mm_camera_util_generate_handler
     53  *
     54  * DESCRIPTION: utility function to generate handler for camera/channel/stream
     55  *
     56  * PARAMETERS :
     57  *   @index: index of the object to have handler
     58  *
     59  * RETURN     : uint32_t type of handle that uniquely identify the object
     60  *==========================================================================*/
     61 uint32_t mm_camera_util_generate_handler(uint8_t index)
     62 {
     63     uint32_t handler = 0;
     64     pthread_mutex_lock(&g_handler_lock);
     65     g_handler_history_count++;
     66     if (0 == g_handler_history_count) {
     67         g_handler_history_count++;
     68     }
     69     handler = g_handler_history_count;
     70     handler = (handler<<8) | index;
     71     pthread_mutex_unlock(&g_handler_lock);
     72     return handler;
     73 }
     74 
     75 /*===========================================================================
     76  * FUNCTION   : mm_camera_util_get_index_by_handler
     77  *
     78  * DESCRIPTION: utility function to get index from handle
     79  *
     80  * PARAMETERS :
     81  *   @handler: object handle
     82  *
     83  * RETURN     : uint8_t type of index derived from handle
     84  *==========================================================================*/
     85 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
     86 {
     87     return (handler&0x000000ff);
     88 }
     89 
     90 /*===========================================================================
     91  * FUNCTION   : mm_camera_util_get_dev_name
     92  *
     93  * DESCRIPTION: utility function to get device name from camera handle
     94  *
     95  * PARAMETERS :
     96  *   @cam_handle: camera handle
     97  *
     98  * RETURN     : char ptr to the device name stored in global variable
     99  * NOTE       : caller should not free the char ptr
    100  *==========================================================================*/
    101 const char *mm_camera_util_get_dev_name(uint32_t cam_handle)
    102 {
    103     char *dev_name = NULL;
    104     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
    105     if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
    106         dev_name = g_cam_ctrl.video_dev_name[cam_idx];
    107     }
    108     return dev_name;
    109 }
    110 
    111 /*===========================================================================
    112  * FUNCTION   : mm_camera_util_get_camera_by_handler
    113  *
    114  * DESCRIPTION: utility function to get camera object from camera handle
    115  *
    116  * PARAMETERS :
    117  *   @cam_handle: camera handle
    118  *
    119  * RETURN     : ptr to the camera object stored in global variable
    120  * NOTE       : caller should not free the camera object ptr
    121  *==========================================================================*/
    122 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
    123 {
    124     mm_camera_obj_t *cam_obj = NULL;
    125     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
    126 
    127     if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS &&
    128         (NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
    129         (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
    130         cam_obj = g_cam_ctrl.cam_obj[cam_idx];
    131     }
    132     return cam_obj;
    133 }
    134 
    135 /*===========================================================================
    136  * FUNCTION   : mm_camera_intf_query_capability
    137  *
    138  * DESCRIPTION: query camera capability
    139  *
    140  * PARAMETERS :
    141  *   @camera_handle: camera handle
    142  *
    143  * RETURN     : int32_t type of status
    144  *              0  -- success
    145  *              -1 -- failure
    146  *==========================================================================*/
    147 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
    148 {
    149     int32_t rc = -1;
    150     mm_camera_obj_t * my_obj = NULL;
    151 
    152     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
    153 
    154     pthread_mutex_lock(&g_intf_lock);
    155     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    156 
    157     if(my_obj) {
    158         pthread_mutex_lock(&my_obj->cam_lock);
    159         pthread_mutex_unlock(&g_intf_lock);
    160         rc = mm_camera_query_capability(my_obj);
    161     } else {
    162         pthread_mutex_unlock(&g_intf_lock);
    163     }
    164     CDBG("%s :X rc = %d", __func__, rc);
    165     return rc;
    166 }
    167 
    168 /*===========================================================================
    169  * FUNCTION   : mm_camera_intf_set_parms
    170  *
    171  * DESCRIPTION: set parameters per camera
    172  *
    173  * PARAMETERS :
    174  *   @camera_handle: camera handle
    175  *   @parms        : ptr to a param struct to be set to server
    176  *
    177  * RETURN     : int32_t type of status
    178  *              0  -- success
    179  *              -1 -- failure
    180  * NOTE       : Assume the parms struct buf is already mapped to server via
    181  *              domain socket. Corresponding fields of parameters to be set
    182  *              are already filled in by upper layer caller.
    183  *==========================================================================*/
    184 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle,
    185                                         parm_buffer_t *parms)
    186 {
    187     int32_t rc = -1;
    188     mm_camera_obj_t * my_obj = NULL;
    189 
    190     pthread_mutex_lock(&g_intf_lock);
    191     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    192 
    193     if(my_obj) {
    194         pthread_mutex_lock(&my_obj->cam_lock);
    195         pthread_mutex_unlock(&g_intf_lock);
    196         rc = mm_camera_set_parms(my_obj, parms);
    197     } else {
    198         pthread_mutex_unlock(&g_intf_lock);
    199     }
    200     return rc;
    201 }
    202 
    203 /*===========================================================================
    204  * FUNCTION   : mm_camera_intf_get_parms
    205  *
    206  * DESCRIPTION: get parameters per camera
    207  *
    208  * PARAMETERS :
    209  *   @camera_handle: camera handle
    210  *   @parms        : ptr to a param struct to be get from server
    211  *
    212  * RETURN     : int32_t type of status
    213  *              0  -- success
    214  *              -1 -- failure
    215  * NOTE       : Assume the parms struct buf is already mapped to server via
    216  *              domain socket. Parameters to be get from server are already
    217  *              filled in by upper layer caller. After this call, corresponding
    218  *              fields of requested parameters will be filled in by server with
    219  *              detailed information.
    220  *==========================================================================*/
    221 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle,
    222                                         parm_buffer_t *parms)
    223 {
    224     int32_t rc = -1;
    225     mm_camera_obj_t * my_obj = NULL;
    226 
    227     pthread_mutex_lock(&g_intf_lock);
    228     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    229 
    230     if(my_obj) {
    231         pthread_mutex_lock(&my_obj->cam_lock);
    232         pthread_mutex_unlock(&g_intf_lock);
    233         rc = mm_camera_get_parms(my_obj, parms);
    234     } else {
    235         pthread_mutex_unlock(&g_intf_lock);
    236     }
    237     return rc;
    238 }
    239 
    240 /*===========================================================================
    241  * FUNCTION   : mm_camera_intf_do_auto_focus
    242  *
    243  * DESCRIPTION: performing auto focus
    244  *
    245  * PARAMETERS :
    246  *   @camera_handle: camera handle
    247  *
    248  * RETURN     : int32_t type of status
    249  *              0  -- success
    250  *              -1 -- failure
    251  * NOTE       : if this call success, we will always assume there will
    252  *              be an auto_focus event following up.
    253  *==========================================================================*/
    254 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle)
    255 {
    256     int32_t rc = -1;
    257     mm_camera_obj_t * my_obj = NULL;
    258 
    259     pthread_mutex_lock(&g_intf_lock);
    260     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    261 
    262     if(my_obj) {
    263         pthread_mutex_lock(&my_obj->cam_lock);
    264         pthread_mutex_unlock(&g_intf_lock);
    265         rc = mm_camera_do_auto_focus(my_obj);
    266     } else {
    267         pthread_mutex_unlock(&g_intf_lock);
    268     }
    269     return rc;
    270 }
    271 
    272 /*===========================================================================
    273  * FUNCTION   : mm_camera_intf_cancel_auto_focus
    274  *
    275  * DESCRIPTION: cancel auto focus
    276  *
    277  * PARAMETERS :
    278  *   @camera_handle: camera handle
    279  *
    280  * RETURN     : int32_t type of status
    281  *              0  -- success
    282  *              -1 -- failure
    283  *==========================================================================*/
    284 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)
    285 {
    286     int32_t rc = -1;
    287     mm_camera_obj_t * my_obj = NULL;
    288 
    289     pthread_mutex_lock(&g_intf_lock);
    290     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    291 
    292     if(my_obj) {
    293         pthread_mutex_lock(&my_obj->cam_lock);
    294         pthread_mutex_unlock(&g_intf_lock);
    295         rc = mm_camera_cancel_auto_focus(my_obj);
    296     } else {
    297         pthread_mutex_unlock(&g_intf_lock);
    298     }
    299     return rc;
    300 }
    301 
    302 /*===========================================================================
    303  * FUNCTION   : mm_camera_intf_prepare_snapshot
    304  *
    305  * DESCRIPTION: prepare hardware for snapshot
    306  *
    307  * PARAMETERS :
    308  *   @camera_handle: camera handle
    309  *   @do_af_flag   : flag indicating if AF is needed
    310  *
    311  * RETURN     : int32_t type of status
    312  *              0  -- success
    313  *              -1 -- failure
    314  *==========================================================================*/
    315 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle,
    316                                                int32_t do_af_flag)
    317 {
    318     int32_t rc = -1;
    319     mm_camera_obj_t * my_obj = NULL;
    320 
    321     pthread_mutex_lock(&g_intf_lock);
    322     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    323 
    324     if(my_obj) {
    325         pthread_mutex_lock(&my_obj->cam_lock);
    326         pthread_mutex_unlock(&g_intf_lock);
    327         rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
    328     } else {
    329         pthread_mutex_unlock(&g_intf_lock);
    330     }
    331     return rc;
    332 }
    333 
    334 /*===========================================================================
    335  * FUNCTION   : mm_camera_intf_start_zsl_snapshot
    336  *
    337  * DESCRIPTION: start zsl snapshot
    338  *
    339  * PARAMETERS :
    340  *   @camera_handle: camera handle
    341  *
    342  * RETURN     : int32_t type of status
    343  *              0  -- success
    344  *              -1 -- failure
    345  *==========================================================================*/
    346 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle)
    347 {
    348     int32_t rc = -1;
    349     mm_camera_obj_t * my_obj = NULL;
    350 
    351     pthread_mutex_lock(&g_intf_lock);
    352     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    353 
    354     if(my_obj) {
    355         pthread_mutex_lock(&my_obj->cam_lock);
    356         pthread_mutex_unlock(&g_intf_lock);
    357         rc = mm_camera_start_zsl_snapshot(my_obj);
    358     } else {
    359         pthread_mutex_unlock(&g_intf_lock);
    360     }
    361     return rc;
    362 }
    363 
    364 /*===========================================================================
    365  * FUNCTION   : mm_camera_intf_stop_zsl_snapshot
    366  *
    367  * DESCRIPTION: stop zsl snapshot
    368  *
    369  * PARAMETERS :
    370  *   @camera_handle: camera handle
    371  *
    372  * RETURN     : int32_t type of status
    373  *              0  -- success
    374  *              -1 -- failure
    375  *==========================================================================*/
    376 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle)
    377 {
    378     int32_t rc = -1;
    379     mm_camera_obj_t * my_obj = NULL;
    380 
    381     pthread_mutex_lock(&g_intf_lock);
    382     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    383 
    384     if(my_obj) {
    385         pthread_mutex_lock(&my_obj->cam_lock);
    386         pthread_mutex_unlock(&g_intf_lock);
    387         rc = mm_camera_stop_zsl_snapshot(my_obj);
    388     } else {
    389         pthread_mutex_unlock(&g_intf_lock);
    390     }
    391     return rc;
    392 }
    393 
    394 /*===========================================================================
    395  * FUNCTION   : mm_camera_intf_close
    396  *
    397  * DESCRIPTION: close a camera by its handle
    398  *
    399  * PARAMETERS :
    400  *   @camera_handle: camera handle
    401  *
    402  * RETURN     : int32_t type of status
    403  *              0  -- success
    404  *              -1 -- failure
    405  *==========================================================================*/
    406 static int32_t mm_camera_intf_close(uint32_t camera_handle)
    407 {
    408     int32_t rc = -1;
    409     uint8_t cam_idx = camera_handle & 0x00ff;
    410     mm_camera_obj_t * my_obj = NULL;
    411 
    412     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
    413 
    414     pthread_mutex_lock(&g_intf_lock);
    415     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    416 
    417     if (my_obj){
    418         my_obj->ref_count--;
    419 
    420         if(my_obj->ref_count > 0) {
    421             /* still have reference to obj, return here */
    422             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    423             pthread_mutex_unlock(&g_intf_lock);
    424             rc = 0;
    425         } else {
    426             /* need close camera here as no other reference
    427              * first empty g_cam_ctrl's referent to cam_obj */
    428             g_cam_ctrl.cam_obj[cam_idx] = NULL;
    429 
    430             pthread_mutex_lock(&my_obj->cam_lock);
    431             pthread_mutex_unlock(&g_intf_lock);
    432 
    433             rc = mm_camera_close(my_obj);
    434 
    435             pthread_mutex_destroy(&my_obj->cam_lock);
    436             free(my_obj);
    437         }
    438     } else {
    439         pthread_mutex_unlock(&g_intf_lock);
    440     }
    441 
    442     return rc;
    443 }
    444 
    445 /*===========================================================================
    446  * FUNCTION   : mm_camera_intf_add_channel
    447  *
    448  * DESCRIPTION: add a channel
    449  *
    450  * PARAMETERS :
    451  *   @camera_handle: camera handle
    452  *   @attr         : bundle attribute of the channel if needed
    453  *   @channel_cb   : callback function for bundle data notify
    454  *   @userdata     : user data ptr
    455  *
    456  * RETURN     : uint32_t type of channel handle
    457  *              0  -- invalid channel handle, meaning the op failed
    458  *              >0 -- successfully added a channel with a valid handle
    459  * NOTE       : if no bundle data notify is needed, meaning each stream in the
    460  *              channel will have its own stream data notify callback, then
    461  *              attr, channel_cb, and userdata can be NULL. In this case,
    462  *              no matching logic will be performed in channel for the bundling.
    463  *==========================================================================*/
    464 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
    465                                            mm_camera_channel_attr_t *attr,
    466                                            mm_camera_buf_notify_t channel_cb,
    467                                            void *userdata)
    468 {
    469     uint32_t ch_id = 0;
    470     mm_camera_obj_t * my_obj = NULL;
    471 
    472     CDBG("%s :E camera_handler = %d", __func__, camera_handle);
    473     pthread_mutex_lock(&g_intf_lock);
    474     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    475 
    476     if(my_obj) {
    477         pthread_mutex_lock(&my_obj->cam_lock);
    478         pthread_mutex_unlock(&g_intf_lock);
    479         ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
    480     } else {
    481         pthread_mutex_unlock(&g_intf_lock);
    482     }
    483     CDBG("%s :X ch_id = %d", __func__, ch_id);
    484     return ch_id;
    485 }
    486 
    487 /*===========================================================================
    488  * FUNCTION   : mm_camera_intf_del_channel
    489  *
    490  * DESCRIPTION: delete a channel by its handle
    491  *
    492  * PARAMETERS :
    493  *   @camera_handle: camera handle
    494  *   @ch_id        : channel handle
    495  *
    496  * RETURN     : int32_t type of status
    497  *              0  -- success
    498  *              -1 -- failure
    499  * NOTE       : all streams in the channel should be stopped already before
    500  *              this channel can be deleted.
    501  *==========================================================================*/
    502 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
    503                                           uint32_t ch_id)
    504 {
    505     int32_t rc = -1;
    506     mm_camera_obj_t * my_obj = NULL;
    507 
    508     CDBG("%s :E ch_id = %d", __func__, ch_id);
    509     pthread_mutex_lock(&g_intf_lock);
    510     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    511 
    512     if(my_obj) {
    513         pthread_mutex_lock(&my_obj->cam_lock);
    514         pthread_mutex_unlock(&g_intf_lock);
    515         rc = mm_camera_del_channel(my_obj, ch_id);
    516     } else {
    517         pthread_mutex_unlock(&g_intf_lock);
    518     }
    519     CDBG("%s :X", __func__);
    520     return rc;
    521 }
    522 
    523 /*===========================================================================
    524  * FUNCTION   : mm_camera_intf_get_bundle_info
    525  *
    526  * DESCRIPTION: query bundle info of the channel
    527  *
    528  * PARAMETERS :
    529  *   @camera_handle: camera handle
    530  *   @ch_id        : channel handle
    531  *   @bundle_info  : bundle info to be filled in
    532  *
    533  * RETURN     : int32_t type of status
    534  *              0  -- success
    535  *              -1 -- failure
    536  * NOTE       : all streams in the channel should be stopped already before
    537  *              this channel can be deleted.
    538  *==========================================================================*/
    539 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
    540                                               uint32_t ch_id,
    541                                               cam_bundle_config_t *bundle_info)
    542 {
    543     int32_t rc = -1;
    544     mm_camera_obj_t * my_obj = NULL;
    545 
    546     CDBG("%s :E ch_id = %d", __func__, ch_id);
    547     pthread_mutex_lock(&g_intf_lock);
    548     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    549 
    550     if(my_obj) {
    551         pthread_mutex_lock(&my_obj->cam_lock);
    552         pthread_mutex_unlock(&g_intf_lock);
    553         rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
    554     } else {
    555         pthread_mutex_unlock(&g_intf_lock);
    556     }
    557     CDBG("%s :X", __func__);
    558     return rc;
    559 }
    560 
    561 /*===========================================================================
    562  * FUNCTION   : mm_camera_intf_register_event_notify
    563  *
    564  * DESCRIPTION: register for event notify
    565  *
    566  * PARAMETERS :
    567  *   @camera_handle: camera handle
    568  *   @evt_cb       : callback for event notify
    569  *   @user_data    : user data ptr
    570  *
    571  * RETURN     : int32_t type of status
    572  *              0  -- success
    573  *              -1 -- failure
    574  *==========================================================================*/
    575 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
    576                                                     mm_camera_event_notify_t evt_cb,
    577                                                     void * user_data)
    578 {
    579     int32_t rc = -1;
    580     mm_camera_obj_t * my_obj = NULL;
    581 
    582     CDBG("%s :E ", __func__);
    583     pthread_mutex_lock(&g_intf_lock);
    584     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    585 
    586     if(my_obj) {
    587         pthread_mutex_lock(&my_obj->cam_lock);
    588         pthread_mutex_unlock(&g_intf_lock);
    589         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
    590     } else {
    591         pthread_mutex_unlock(&g_intf_lock);
    592     }
    593     CDBG("%s :E rc = %d", __func__, rc);
    594     return rc;
    595 }
    596 
    597 /*===========================================================================
    598  * FUNCTION   : mm_camera_intf_qbuf
    599  *
    600  * DESCRIPTION: enqueue buffer back to kernel
    601  *
    602  * PARAMETERS :
    603  *   @camera_handle: camera handle
    604  *   @ch_id        : channel handle
    605  *   @buf          : buf ptr to be enqueued
    606  *
    607  * RETURN     : int32_t type of status
    608  *              0  -- success
    609  *              -1 -- failure
    610  *==========================================================================*/
    611 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
    612                                     uint32_t ch_id,
    613                                     mm_camera_buf_def_t *buf)
    614 {
    615     int32_t rc = -1;
    616     mm_camera_obj_t * my_obj = NULL;
    617 
    618     pthread_mutex_lock(&g_intf_lock);
    619     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    620 
    621     if(my_obj) {
    622         pthread_mutex_lock(&my_obj->cam_lock);
    623         pthread_mutex_unlock(&g_intf_lock);
    624         rc = mm_camera_qbuf(my_obj, ch_id, buf);
    625     } else {
    626         pthread_mutex_unlock(&g_intf_lock);
    627     }
    628     CDBG("%s :X evt_type = %d",__func__,rc);
    629     return rc;
    630 }
    631 
    632 /*===========================================================================
    633  * FUNCTION   : mm_camera_intf_add_stream
    634  *
    635  * DESCRIPTION: add a stream into a channel
    636  *
    637  * PARAMETERS :
    638  *   @camera_handle: camera handle
    639  *   @ch_id        : channel handle
    640  *
    641  * RETURN     : uint32_t type of stream handle
    642  *              0  -- invalid stream handle, meaning the op failed
    643  *              >0 -- successfully added a stream with a valid handle
    644  *==========================================================================*/
    645 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
    646                                           uint32_t ch_id)
    647 {
    648     uint32_t stream_id = 0;
    649     mm_camera_obj_t * my_obj = NULL;
    650 
    651     CDBG("%s : E handle = %d ch_id = %d",
    652          __func__, camera_handle, ch_id);
    653 
    654     pthread_mutex_lock(&g_intf_lock);
    655     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    656 
    657     if(my_obj) {
    658         pthread_mutex_lock(&my_obj->cam_lock);
    659         pthread_mutex_unlock(&g_intf_lock);
    660         stream_id = mm_camera_add_stream(my_obj, ch_id);
    661     } else {
    662         pthread_mutex_unlock(&g_intf_lock);
    663     }
    664     CDBG("%s :X stream_id = %d", __func__, stream_id);
    665     return stream_id;
    666 }
    667 
    668 /*===========================================================================
    669  * FUNCTION   : mm_camera_intf_del_stream
    670  *
    671  * DESCRIPTION: delete a stream by its handle
    672  *
    673  * PARAMETERS :
    674  *   @camera_handle: camera handle
    675  *   @ch_id        : channel handle
    676  *   @stream_id    : stream handle
    677  *
    678  * RETURN     : int32_t type of status
    679  *              0  -- success
    680  *              -1 -- failure
    681  * NOTE       : stream should be stopped already before it can be deleted.
    682  *==========================================================================*/
    683 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
    684                                          uint32_t ch_id,
    685                                          uint32_t stream_id)
    686 {
    687     int32_t rc = -1;
    688     mm_camera_obj_t * my_obj = NULL;
    689 
    690     CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
    691          __func__, camera_handle, ch_id, stream_id);
    692 
    693     pthread_mutex_lock(&g_intf_lock);
    694     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    695 
    696     if(my_obj) {
    697         pthread_mutex_lock(&my_obj->cam_lock);
    698         pthread_mutex_unlock(&g_intf_lock);
    699         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    700     } else {
    701         pthread_mutex_unlock(&g_intf_lock);
    702     }
    703     CDBG("%s :X rc = %d", __func__, rc);
    704     return rc;
    705 }
    706 
    707 /*===========================================================================
    708  * FUNCTION   : mm_camera_intf_config_stream
    709  *
    710  * DESCRIPTION: configure a stream
    711  *
    712  * PARAMETERS :
    713  *   @camera_handle: camera handle
    714  *   @ch_id        : channel handle
    715  *   @stream_id    : stream handle
    716  *   @config       : stream configuration
    717  *
    718  * RETURN     : int32_t type of status
    719  *              0  -- success
    720  *              -1 -- failure
    721  *==========================================================================*/
    722 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
    723                                             uint32_t ch_id,
    724                                             uint32_t stream_id,
    725                                             mm_camera_stream_config_t *config)
    726 {
    727     int32_t rc = -1;
    728     mm_camera_obj_t * my_obj = NULL;
    729 
    730     CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
    731          __func__, camera_handle, ch_id, stream_id);
    732 
    733     pthread_mutex_lock(&g_intf_lock);
    734     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    735 
    736     CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
    737 
    738     if(my_obj) {
    739         pthread_mutex_lock(&my_obj->cam_lock);
    740         pthread_mutex_unlock(&g_intf_lock);
    741         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
    742     } else {
    743         pthread_mutex_unlock(&g_intf_lock);
    744     }
    745     CDBG("%s :X rc = %d", __func__, rc);
    746     return rc;
    747 }
    748 
    749 /*===========================================================================
    750  * FUNCTION   : mm_camera_intf_start_channel
    751  *
    752  * DESCRIPTION: start a channel, which will start all streams in the channel
    753  *
    754  * PARAMETERS :
    755  *   @camera_handle: camera handle
    756  *   @ch_id        : channel handle
    757  *
    758  * RETURN     : int32_t type of status
    759  *              0  -- success
    760  *              -1 -- failure
    761  *==========================================================================*/
    762 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
    763                                             uint32_t ch_id)
    764 {
    765     int32_t rc = -1;
    766     mm_camera_obj_t * my_obj = NULL;
    767 
    768     pthread_mutex_lock(&g_intf_lock);
    769     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    770 
    771     if(my_obj) {
    772         pthread_mutex_lock(&my_obj->cam_lock);
    773         pthread_mutex_unlock(&g_intf_lock);
    774         rc = mm_camera_start_channel(my_obj, ch_id);
    775     } else {
    776         pthread_mutex_unlock(&g_intf_lock);
    777     }
    778     CDBG("%s :X rc = %d", __func__, rc);
    779     return rc;
    780 }
    781 
    782 /*===========================================================================
    783  * FUNCTION   : mm_camera_intf_stop_channel
    784  *
    785  * DESCRIPTION: stop a channel, which will stop all streams in the channel
    786  *
    787  * PARAMETERS :
    788  *   @camera_handle: camera handle
    789  *   @ch_id        : channel handle
    790  *
    791  * RETURN     : int32_t type of status
    792  *              0  -- success
    793  *              -1 -- failure
    794  *==========================================================================*/
    795 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
    796                                            uint32_t ch_id)
    797 {
    798     int32_t rc = -1;
    799     mm_camera_obj_t * my_obj = NULL;
    800 
    801     pthread_mutex_lock(&g_intf_lock);
    802     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    803 
    804     if(my_obj) {
    805         pthread_mutex_lock(&my_obj->cam_lock);
    806         pthread_mutex_unlock(&g_intf_lock);
    807         rc = mm_camera_stop_channel(my_obj, ch_id);
    808     } else {
    809         pthread_mutex_unlock(&g_intf_lock);
    810     }
    811     CDBG("%s :X rc = %d", __func__, rc);
    812     return rc;
    813 }
    814 
    815 /*===========================================================================
    816  * FUNCTION   : mm_camera_intf_request_super_buf
    817  *
    818  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
    819  *              frames from superbuf queue
    820  *
    821  * PARAMETERS :
    822  *   @camera_handle: camera handle
    823  *   @ch_id        : channel handle
    824  *   @num_buf_requested : number of matched frames needed
    825  *
    826  * RETURN     : int32_t type of status
    827  *              0  -- success
    828  *              -1 -- failure
    829  *==========================================================================*/
    830 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
    831                                                 uint32_t ch_id,
    832                                                 uint32_t num_buf_requested)
    833 {
    834     int32_t rc = -1;
    835     CDBG("%s :E camera_handler = %d,ch_id = %d",
    836          __func__, camera_handle, ch_id);
    837     mm_camera_obj_t * my_obj = NULL;
    838 
    839     pthread_mutex_lock(&g_intf_lock);
    840     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    841 
    842     if(my_obj) {
    843         pthread_mutex_lock(&my_obj->cam_lock);
    844         pthread_mutex_unlock(&g_intf_lock);
    845         rc = mm_camera_request_super_buf(my_obj, ch_id, num_buf_requested);
    846     } else {
    847         pthread_mutex_unlock(&g_intf_lock);
    848     }
    849     CDBG("%s :X rc = %d", __func__, rc);
    850     return rc;
    851 }
    852 
    853 /*===========================================================================
    854  * FUNCTION   : mm_camera_intf_cancel_super_buf_request
    855  *
    856  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
    857  *              of matched frames from superbuf queue
    858  *
    859  * PARAMETERS :
    860  *   @camera_handle: camera handle
    861  *   @ch_id        : channel handle
    862  *
    863  * RETURN     : int32_t type of status
    864  *              0  -- success
    865  *              -1 -- failure
    866  *==========================================================================*/
    867 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
    868                                                        uint32_t ch_id)
    869 {
    870     int32_t rc = -1;
    871     mm_camera_obj_t * my_obj = NULL;
    872 
    873     CDBG("%s :E camera_handler = %d,ch_id = %d",
    874          __func__, camera_handle, ch_id);
    875     pthread_mutex_lock(&g_intf_lock);
    876     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    877 
    878     if(my_obj) {
    879         pthread_mutex_lock(&my_obj->cam_lock);
    880         pthread_mutex_unlock(&g_intf_lock);
    881         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
    882     } else {
    883         pthread_mutex_unlock(&g_intf_lock);
    884     }
    885     CDBG("%s :X rc = %d", __func__, rc);
    886     return rc;
    887 }
    888 
    889 /*===========================================================================
    890  * FUNCTION   : mm_camera_intf_flush_super_buf_queue
    891  *
    892  * DESCRIPTION: flush out all frames in the superbuf queue
    893  *
    894  * PARAMETERS :
    895  *   @camera_handle: camera handle
    896  *   @ch_id        : channel handle
    897  *   @frame_idx    : frame index
    898  *
    899  * RETURN     : int32_t type of status
    900  *              0  -- success
    901  *              -1 -- failure
    902  *==========================================================================*/
    903 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
    904                                                     uint32_t ch_id, uint32_t frame_idx)
    905 {
    906     int32_t rc = -1;
    907     mm_camera_obj_t * my_obj = NULL;
    908 
    909     CDBG("%s :E camera_handler = %d,ch_id = %d",
    910          __func__, camera_handle, ch_id);
    911     pthread_mutex_lock(&g_intf_lock);
    912     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    913 
    914     if(my_obj) {
    915         pthread_mutex_lock(&my_obj->cam_lock);
    916         pthread_mutex_unlock(&g_intf_lock);
    917         rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
    918     } else {
    919         pthread_mutex_unlock(&g_intf_lock);
    920     }
    921     CDBG("%s :X rc = %d", __func__, rc);
    922     return rc;
    923 }
    924 
    925 /*===========================================================================
    926  * FUNCTION   : mm_camera_intf_configure_notify_mode
    927  *
    928  * DESCRIPTION: Configures channel notification mode
    929  *
    930  * PARAMETERS :
    931  *   @camera_handle: camera handle
    932  *   @ch_id        : channel handle
    933  *   @notify_mode  : notification mode
    934  *
    935  * RETURN     : int32_t type of status
    936  *              0  -- success
    937  *              -1 -- failure
    938  *==========================================================================*/
    939 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
    940                                                     uint32_t ch_id,
    941                                                     mm_camera_super_buf_notify_mode_t notify_mode)
    942 {
    943     int32_t rc = -1;
    944     mm_camera_obj_t * my_obj = NULL;
    945 
    946     CDBG("%s :E camera_handler = %d,ch_id = %d",
    947          __func__, camera_handle, ch_id);
    948     pthread_mutex_lock(&g_intf_lock);
    949     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    950 
    951     if(my_obj) {
    952         pthread_mutex_lock(&my_obj->cam_lock);
    953         pthread_mutex_unlock(&g_intf_lock);
    954         rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
    955     } else {
    956         pthread_mutex_unlock(&g_intf_lock);
    957     }
    958     CDBG("%s :X rc = %d", __func__, rc);
    959     return rc;
    960 }
    961 
    962 /*===========================================================================
    963  * FUNCTION   : mm_camera_intf_map_buf
    964  *
    965  * DESCRIPTION: mapping camera buffer via domain socket to server
    966  *
    967  * PARAMETERS :
    968  *   @camera_handle: camera handle
    969  *   @buf_type     : type of buffer to be mapped. could be following values:
    970  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
    971  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
    972  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
    973  *   @fd           : file descriptor of the buffer
    974  *   @size         : size of the buffer
    975  *
    976  * RETURN     : int32_t type of status
    977  *              0  -- success
    978  *              -1 -- failure
    979  *==========================================================================*/
    980 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
    981                                       uint8_t buf_type,
    982                                       int fd,
    983                                       uint32_t size)
    984 {
    985     int32_t rc = -1;
    986     mm_camera_obj_t * my_obj = NULL;
    987 
    988     pthread_mutex_lock(&g_intf_lock);
    989     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    990 
    991     if(my_obj) {
    992         pthread_mutex_lock(&my_obj->cam_lock);
    993         pthread_mutex_unlock(&g_intf_lock);
    994         rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
    995     } else {
    996         pthread_mutex_unlock(&g_intf_lock);
    997     }
    998     return rc;
    999 }
   1000 
   1001 /*===========================================================================
   1002  * FUNCTION   : mm_camera_intf_unmap_buf
   1003  *
   1004  * DESCRIPTION: unmapping camera buffer via domain socket to server
   1005  *
   1006  * PARAMETERS :
   1007  *   @camera_handle: camera handle
   1008  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1009  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1010  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1011  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1012  *
   1013  * RETURN     : int32_t type of status
   1014  *              0  -- success
   1015  *              -1 -- failure
   1016  *==========================================================================*/
   1017 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
   1018                                         uint8_t buf_type)
   1019 {
   1020     int32_t rc = -1;
   1021     mm_camera_obj_t * my_obj = NULL;
   1022 
   1023     pthread_mutex_lock(&g_intf_lock);
   1024     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1025 
   1026     if(my_obj) {
   1027         pthread_mutex_lock(&my_obj->cam_lock);
   1028         pthread_mutex_unlock(&g_intf_lock);
   1029         rc = mm_camera_unmap_buf(my_obj, buf_type);
   1030     } else {
   1031         pthread_mutex_unlock(&g_intf_lock);
   1032     }
   1033     return rc;
   1034 }
   1035 
   1036 /*===========================================================================
   1037  * FUNCTION   : mm_camera_intf_set_stream_parms
   1038  *
   1039  * DESCRIPTION: set parameters per stream
   1040  *
   1041  * PARAMETERS :
   1042  *   @camera_handle: camera handle
   1043  *   @ch_id        : channel handle
   1044  *   @s_id         : stream handle
   1045  *   @parms        : ptr to a param struct to be set to server
   1046  *
   1047  * RETURN     : int32_t type of status
   1048  *              0  -- success
   1049  *              -1 -- failure
   1050  * NOTE       : Assume the parms struct buf is already mapped to server via
   1051  *              domain socket. Corresponding fields of parameters to be set
   1052  *              are already filled in by upper layer caller.
   1053  *==========================================================================*/
   1054 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
   1055                                                uint32_t ch_id,
   1056                                                uint32_t s_id,
   1057                                                cam_stream_parm_buffer_t *parms)
   1058 {
   1059     int32_t rc = -1;
   1060     mm_camera_obj_t * my_obj = NULL;
   1061 
   1062     pthread_mutex_lock(&g_intf_lock);
   1063     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1064 
   1065     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
   1066          __func__, camera_handle, ch_id, s_id);
   1067 
   1068     if(my_obj) {
   1069         pthread_mutex_lock(&my_obj->cam_lock);
   1070         pthread_mutex_unlock(&g_intf_lock);
   1071         rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
   1072     }else{
   1073         pthread_mutex_unlock(&g_intf_lock);
   1074     }
   1075     CDBG("%s :X rc = %d", __func__, rc);
   1076     return rc;
   1077 }
   1078 
   1079 /*===========================================================================
   1080  * FUNCTION   : mm_camera_intf_get_stream_parms
   1081  *
   1082  * DESCRIPTION: get parameters per stream
   1083  *
   1084  * PARAMETERS :
   1085  *   @camera_handle: camera handle
   1086  *   @ch_id        : channel handle
   1087  *   @s_id         : stream handle
   1088  *   @parms        : ptr to a param struct to be get from server
   1089  *
   1090  * RETURN     : int32_t type of status
   1091  *              0  -- success
   1092  *              -1 -- failure
   1093  * NOTE       : Assume the parms struct buf is already mapped to server via
   1094  *              domain socket. Parameters to be get from server are already
   1095  *              filled in by upper layer caller. After this call, corresponding
   1096  *              fields of requested parameters will be filled in by server with
   1097  *              detailed information.
   1098  *==========================================================================*/
   1099 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
   1100                                                uint32_t ch_id,
   1101                                                uint32_t s_id,
   1102                                                cam_stream_parm_buffer_t *parms)
   1103 {
   1104     int32_t rc = -1;
   1105     mm_camera_obj_t * my_obj = NULL;
   1106 
   1107     pthread_mutex_lock(&g_intf_lock);
   1108     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1109 
   1110     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
   1111          __func__, camera_handle, ch_id, s_id);
   1112 
   1113     if(my_obj) {
   1114         pthread_mutex_lock(&my_obj->cam_lock);
   1115         pthread_mutex_unlock(&g_intf_lock);
   1116         rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
   1117     }else{
   1118         pthread_mutex_unlock(&g_intf_lock);
   1119     }
   1120 
   1121     CDBG("%s :X rc = %d", __func__, rc);
   1122     return rc;
   1123 }
   1124 
   1125 /*===========================================================================
   1126  * FUNCTION   : mm_camera_intf_map_stream_buf
   1127  *
   1128  * DESCRIPTION: mapping stream buffer via domain socket to server
   1129  *
   1130  * PARAMETERS :
   1131  *   @camera_handle: camera handle
   1132  *   @ch_id        : channel handle
   1133  *   @s_id         : stream handle
   1134  *   @buf_type     : type of buffer to be mapped. could be following values:
   1135  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1136  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1137  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1138  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1139  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1140  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1141  *   @plane_idx    : plane index. If all planes share the same fd,
   1142  *                   plane_idx = -1; otherwise, plean_idx is the
   1143  *                   index to plane (0..num_of_planes)
   1144  *   @fd           : file descriptor of the buffer
   1145  *   @size         : size of the buffer
   1146  *
   1147  * RETURN     : int32_t type of status
   1148  *              0  -- success
   1149  *              -1 -- failure
   1150  *==========================================================================*/
   1151 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
   1152                                              uint32_t ch_id,
   1153                                              uint32_t stream_id,
   1154                                              uint8_t buf_type,
   1155                                              uint32_t buf_idx,
   1156                                              int32_t plane_idx,
   1157                                              int fd,
   1158                                              uint32_t size)
   1159 {
   1160     int32_t rc = -1;
   1161     mm_camera_obj_t * my_obj = NULL;
   1162 
   1163     pthread_mutex_lock(&g_intf_lock);
   1164     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1165 
   1166     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1167          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1168 
   1169     if(my_obj) {
   1170         pthread_mutex_lock(&my_obj->cam_lock);
   1171         pthread_mutex_unlock(&g_intf_lock);
   1172         rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
   1173                                       buf_type, buf_idx, plane_idx,
   1174                                       fd, size);
   1175     }else{
   1176         pthread_mutex_unlock(&g_intf_lock);
   1177     }
   1178 
   1179     CDBG("%s :X rc = %d", __func__, rc);
   1180     return rc;
   1181 }
   1182 
   1183 /*===========================================================================
   1184  * FUNCTION   : mm_camera_intf_unmap_stream_buf
   1185  *
   1186  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1187  *
   1188  * PARAMETERS :
   1189  *   @camera_handle: camera handle
   1190  *   @ch_id        : channel handle
   1191  *   @s_id         : stream handle
   1192  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1193  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1194  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1195  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1196  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1197  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1198  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1199  *   @plane_idx    : plane index. If all planes share the same fd,
   1200  *                   plane_idx = -1; otherwise, plean_idx is the
   1201  *                   index to plane (0..num_of_planes)
   1202  *
   1203  * RETURN     : int32_t type of status
   1204  *              0  -- success
   1205  *              -1 -- failure
   1206  *==========================================================================*/
   1207 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
   1208                                                uint32_t ch_id,
   1209                                                uint32_t stream_id,
   1210                                                uint8_t buf_type,
   1211                                                uint32_t buf_idx,
   1212                                                int32_t plane_idx)
   1213 {
   1214     int32_t rc = -1;
   1215     mm_camera_obj_t * my_obj = NULL;
   1216 
   1217     pthread_mutex_lock(&g_intf_lock);
   1218     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1219 
   1220     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1221          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1222 
   1223     if(my_obj) {
   1224         pthread_mutex_lock(&my_obj->cam_lock);
   1225         pthread_mutex_unlock(&g_intf_lock);
   1226         rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
   1227                                         buf_type, buf_idx, plane_idx);
   1228     }else{
   1229         pthread_mutex_unlock(&g_intf_lock);
   1230     }
   1231 
   1232     CDBG("%s :X rc = %d", __func__, rc);
   1233     return rc;
   1234 }
   1235 
   1236 /*===========================================================================
   1237  * FUNCTION   : get_num_of_cameras
   1238  *
   1239  * DESCRIPTION: get number of cameras
   1240  *
   1241  * PARAMETERS :
   1242  *
   1243  * RETURN     : number of cameras supported
   1244  *==========================================================================*/
   1245 uint8_t get_num_of_cameras()
   1246 {
   1247     int rc = 0;
   1248     int dev_fd = 0;
   1249     struct media_device_info mdev_info;
   1250     int num_media_devices = 0;
   1251     uint8_t num_cameras = 0;
   1252 
   1253     CDBG("%s : E", __func__);
   1254     /* lock the mutex */
   1255     pthread_mutex_lock(&g_intf_lock);
   1256     while (1) {
   1257         char dev_name[32];
   1258         int num_entities;
   1259         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1260         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1261         if (dev_fd <= 0) {
   1262             CDBG("Done discovering media devices\n");
   1263             break;
   1264         }
   1265         num_media_devices++;
   1266         memset(&mdev_info, 0, sizeof(mdev_info));
   1267         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1268         if (rc < 0) {
   1269             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1270             close(dev_fd);
   1271             dev_fd = 0;
   1272             num_cameras = 0;
   1273             break;
   1274         }
   1275 
   1276         if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
   1277             close(dev_fd);
   1278             dev_fd = 0;
   1279             continue;
   1280         }
   1281 
   1282         num_entities = 1;
   1283         while (1) {
   1284             struct media_entity_desc entity;
   1285             memset(&entity, 0, sizeof(entity));
   1286             entity.id = num_entities++;
   1287             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1288             if (rc < 0) {
   1289                 CDBG("Done enumerating media entities\n");
   1290                 rc = 0;
   1291                 break;
   1292             }
   1293             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
   1294                 strncpy(g_cam_ctrl.video_dev_name[num_cameras],
   1295                      entity.name, sizeof(entity.name));
   1296                 break;
   1297             }
   1298         }
   1299 
   1300         CDBG("%s: dev_info[id=%d,name='%s']\n",
   1301             __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
   1302 
   1303         num_cameras++;
   1304         close(dev_fd);
   1305         dev_fd = 0;
   1306     }
   1307     g_cam_ctrl.num_cam = num_cameras;
   1308 
   1309     /* unlock the mutex */
   1310     pthread_mutex_unlock(&g_intf_lock);
   1311     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
   1312     return g_cam_ctrl.num_cam;
   1313 }
   1314 
   1315 /* camera ops v-table */
   1316 static mm_camera_ops_t mm_camera_ops = {
   1317     .query_capability = mm_camera_intf_query_capability,
   1318     .register_event_notify = mm_camera_intf_register_event_notify,
   1319     .close_camera = mm_camera_intf_close,
   1320     .set_parms = mm_camera_intf_set_parms,
   1321     .get_parms = mm_camera_intf_get_parms,
   1322     .do_auto_focus = mm_camera_intf_do_auto_focus,
   1323     .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
   1324     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
   1325     .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
   1326     .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
   1327     .map_buf = mm_camera_intf_map_buf,
   1328     .unmap_buf = mm_camera_intf_unmap_buf,
   1329     .add_channel = mm_camera_intf_add_channel,
   1330     .delete_channel = mm_camera_intf_del_channel,
   1331     .get_bundle_info = mm_camera_intf_get_bundle_info,
   1332     .add_stream = mm_camera_intf_add_stream,
   1333     .delete_stream = mm_camera_intf_del_stream,
   1334     .config_stream = mm_camera_intf_config_stream,
   1335     .qbuf = mm_camera_intf_qbuf,
   1336     .map_stream_buf = mm_camera_intf_map_stream_buf,
   1337     .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
   1338     .set_stream_parms = mm_camera_intf_set_stream_parms,
   1339     .get_stream_parms = mm_camera_intf_get_stream_parms,
   1340     .start_channel = mm_camera_intf_start_channel,
   1341     .stop_channel = mm_camera_intf_stop_channel,
   1342     .request_super_buf = mm_camera_intf_request_super_buf,
   1343     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
   1344     .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
   1345     .configure_notify_mode = mm_camera_intf_configure_notify_mode
   1346 };
   1347 
   1348 /*===========================================================================
   1349  * FUNCTION   : camera_open
   1350  *
   1351  * DESCRIPTION: open a camera by camera index
   1352  *
   1353  * PARAMETERS :
   1354  *   @camera_idx : camera index. should within range of 0 to num_of_cameras
   1355  *
   1356  * RETURN     : ptr to a virtual table containing camera handle and operation table.
   1357  *              NULL if failed.
   1358  *==========================================================================*/
   1359 mm_camera_vtbl_t * camera_open(uint8_t camera_idx)
   1360 {
   1361     int32_t rc = 0;
   1362     mm_camera_obj_t* cam_obj = NULL;
   1363 
   1364     CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
   1365     if (camera_idx >= g_cam_ctrl.num_cam) {
   1366         CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
   1367         return NULL;
   1368     }
   1369 
   1370     pthread_mutex_lock(&g_intf_lock);
   1371     /* opened already */
   1372     if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
   1373         /* Add reference */
   1374         g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
   1375         pthread_mutex_unlock(&g_intf_lock);
   1376         CDBG("%s:  opened alreadyn", __func__);
   1377         return &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
   1378     }
   1379 
   1380     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
   1381     if(NULL == cam_obj) {
   1382         pthread_mutex_unlock(&g_intf_lock);
   1383         CDBG("%s:  no mem", __func__);
   1384         return NULL;
   1385     }
   1386 
   1387     /* initialize camera obj */
   1388     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
   1389     cam_obj->ref_count++;
   1390     cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
   1391     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
   1392     cam_obj->vtbl.ops = &mm_camera_ops;
   1393     pthread_mutex_init(&cam_obj->cam_lock, NULL);
   1394 
   1395     rc = mm_camera_open(cam_obj);
   1396     if(rc != 0) {
   1397         CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
   1398         pthread_mutex_destroy(&cam_obj->cam_lock);
   1399         g_cam_ctrl.cam_obj[camera_idx] = NULL;
   1400         free(cam_obj);
   1401         cam_obj = NULL;
   1402         pthread_mutex_unlock(&g_intf_lock);
   1403         return NULL;
   1404     }else{
   1405         CDBG("%s: Open succeded\n", __func__);
   1406         g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
   1407         pthread_mutex_unlock(&g_intf_lock);
   1408         return &cam_obj->vtbl;
   1409     }
   1410 }
   1411