Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2016, 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 // To remove
     31 #include <cutils/properties.h>
     32 
     33 // System dependencies
     34 #include <pthread.h>
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <stdlib.h>
     38 #include <linux/media.h>
     39 #include <media/msm_cam_sensor.h>
     40 #include <dlfcn.h>
     41 #include <unistd.h>
     42 
     43 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
     44 #include IOCTL_H
     45 
     46 // Camera dependencies
     47 #include "mm_camera_dbg.h"
     48 #include "mm_camera_interface.h"
     49 #include "mm_camera.h"
     50 #include "mm_camera_muxer.h"
     51 
     52 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
     53 static mm_camera_ctrl_t g_cam_ctrl;
     54 
     55 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
     56 static uint8_t g_handler_history_count = 0; /* history count for handler */
     57 
     58 // 16th (starting from 0) bit tells its a BACK or FRONT camera
     59 #define CAM_SENSOR_FACING_MASK       (1U<<16)
     60 #define CAM_SENSOR_TYPE_MASK         (1U<<24)
     61 #define CAM_SENSOR_FORMAT_MASK       (1U<<25)
     62 #define CAM_SENSOR_SECURE_MASK       (1U<<26)
     63 
     64 /*===========================================================================
     65  * FUNCTION   : mm_camera_util_generate_handler
     66  *
     67  * DESCRIPTION: utility function to generate handler for camera/channel/stream
     68  *
     69  * PARAMETERS :
     70  *   @index: index of the object to have handler
     71  *
     72  * RETURN     : uint32_t type of handle that uniquely identify the object
     73  *==========================================================================*/
     74 uint32_t mm_camera_util_generate_handler(uint8_t index)
     75 {
     76     uint32_t handler = 0;
     77     pthread_mutex_lock(&g_handler_lock);
     78     g_handler_history_count++;
     79     if (0 == g_handler_history_count) {
     80         g_handler_history_count++;
     81     }
     82     handler = g_handler_history_count;
     83     handler = (handler<<8) | index;
     84     pthread_mutex_unlock(&g_handler_lock);
     85     return handler;
     86 }
     87 
     88 /*===========================================================================
     89  * FUNCTION   : mm_camera_util_get_index_by_handler
     90  *
     91  * DESCRIPTION: utility function to get index from handle
     92  *
     93  * PARAMETERS :
     94  *   @handler: object handle
     95  *
     96  * RETURN     : uint8_t type of index derived from handle
     97  *==========================================================================*/
     98 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
     99 {
    100     return (handler & 0x000000ff);
    101 }
    102 
    103 /*===========================================================================
    104  * FUNCTION   : mm_camera_util_get_dev_name
    105  *
    106  * DESCRIPTION: utility function to get device name from camera handle
    107  *
    108  * PARAMETERS :
    109  *   @cam_handle: camera handle
    110  *
    111  * RETURN     : char ptr to the device name stored in global variable
    112  * NOTE       : caller should not free the char ptr
    113  *==========================================================================*/
    114 const char *mm_camera_util_get_dev_name(uint32_t cam_handle)
    115 {
    116     char *dev_name = NULL;
    117     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
    118     if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
    119         dev_name = g_cam_ctrl.video_dev_name[cam_idx];
    120     }
    121     return dev_name;
    122 }
    123 
    124 /*===========================================================================
    125  * FUNCTION   : mm_camera_util_get_camera_by_handler
    126  *
    127  * DESCRIPTION: utility function to get camera object from camera handle
    128  *
    129  * PARAMETERS :
    130  *   @cam_handle: camera handle
    131  *
    132  * RETURN     : ptr to the camera object stored in global variable
    133  * NOTE       : caller should not free the camera object ptr
    134  *==========================================================================*/
    135 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
    136 {
    137     mm_camera_obj_t *cam_obj = NULL;
    138     uint8_t cam_idx = 0;
    139 
    140     for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) {
    141          if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
    142                 (cam_handle == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
    143             cam_obj = g_cam_ctrl.cam_obj[cam_idx];
    144             break;
    145         }
    146     }
    147     return cam_obj;
    148 }
    149 
    150 
    151 /*===========================================================================
    152  * FUNCTION   : mm_camera_util_set_camera_object
    153  *
    154  * DESCRIPTION: utility function to set camera object to global structure
    155  *
    156  * PARAMETERS :
    157  *   @cam_idx : index to store cambera object
    158  *   @obj     : Camera object to store
    159  *
    160  * RETURN     : int32_t type of status
    161  *              0  -- success
    162  *              -1 -- failure
    163  *==========================================================================*/
    164 int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj)
    165 {
    166     int32_t rc = 0;
    167     pthread_mutex_lock(&g_intf_lock);
    168     if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
    169         g_cam_ctrl.cam_obj[cam_idx] = obj;
    170     } else {
    171         rc = -1;
    172     }
    173     pthread_mutex_unlock(&g_intf_lock);
    174     return rc;
    175 }
    176 
    177 /*===========================================================================
    178  * FUNCTION   : mm_camera_util_get_camera_head_obj
    179  *
    180  * DESCRIPTION: utility function to get camera object from camera handle
    181  *
    182  * PARAMETERS :
    183  *   @cam_handle: camera handle
    184  *
    185  * RETURN     : ptr to the master/primary camera object
    186  *==========================================================================*/
    187 mm_camera_obj_t* mm_camera_util_get_camera_head(uint32_t cam_handle)
    188 {
    189     mm_camera_obj_t *cam_obj = NULL;
    190 
    191     cam_obj = mm_camera_util_get_camera_by_handler(cam_handle);
    192     if (cam_obj != NULL && cam_obj->master_cam_obj != NULL) {
    193         cam_obj = cam_obj->master_cam_obj;
    194     }
    195     return cam_obj;
    196 }
    197 
    198 /*===========================================================================
    199  * FUNCTION   : mm_camera_util_get_camera_by_session_id
    200  *
    201  * DESCRIPTION: utility function to get camera object from camera sessionID
    202  *
    203  * PARAMETERS :
    204  *   @session_id: sessionid for which cam obj mapped
    205  *
    206  * RETURN     : ptr to the camera object stored in global variable
    207  * NOTE       : caller should not free the camera object ptr
    208  *==========================================================================*/
    209 mm_camera_obj_t* mm_camera_util_get_camera_by_session_id(uint32_t session_id)
    210 {
    211    int cam_idx = 0;
    212    mm_camera_obj_t *cam_obj = NULL;
    213    for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) {
    214         if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
    215                 (session_id == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->sessionid)) {
    216             LOGD("session id:%d match idx:%d\n", session_id, cam_idx);
    217             cam_obj = g_cam_ctrl.cam_obj[cam_idx];
    218         }
    219     }
    220     return cam_obj;
    221 }
    222 
    223 /*===========================================================================
    224  * FUNCTION   : mm_camera_intf_query_capability
    225  *
    226  * DESCRIPTION: query camera capability
    227  *
    228  * PARAMETERS :
    229  *   @camera_handle: camera handle
    230  *
    231  * RETURN     : int32_t type of status
    232  *              0  -- success
    233  *              -1 -- failure
    234  *==========================================================================*/
    235 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
    236 {
    237     int32_t rc = -1;
    238     mm_camera_obj_t *my_obj = NULL;
    239     uint32_t handle = 0;
    240     uint32_t aux_handle = 0;
    241 
    242     LOGD("E: camera_handler = %d ", camera_handle);
    243 
    244     pthread_mutex_lock(&g_intf_lock);
    245     handle = get_main_camera_handle(camera_handle);
    246     aux_handle = get_aux_camera_handle(camera_handle);
    247 
    248     if (handle) {
    249         my_obj = mm_camera_util_get_camera_by_handler(handle);
    250 
    251         if(my_obj) {
    252             pthread_mutex_lock(&my_obj->cam_lock);
    253             pthread_mutex_unlock(&g_intf_lock);
    254             rc = mm_camera_query_capability(my_obj);
    255         } else {
    256             pthread_mutex_unlock(&g_intf_lock);
    257         }
    258     } else {
    259         pthread_mutex_unlock(&g_intf_lock);
    260     }
    261 
    262     if (aux_handle) {
    263         pthread_mutex_lock(&g_intf_lock);
    264         my_obj = mm_camera_util_get_camera_head(aux_handle);
    265         if (my_obj) {
    266             pthread_mutex_lock(&my_obj->muxer_lock);
    267             pthread_mutex_unlock(&g_intf_lock);
    268             rc = mm_camera_muxer_query_capability(aux_handle, my_obj);
    269         } else {
    270             pthread_mutex_unlock(&g_intf_lock);
    271         }
    272     }
    273 
    274     LOGH("camera_handle = %u rc = %u X", camera_handle, rc);
    275     return rc;
    276 }
    277 
    278 /*===========================================================================
    279  * FUNCTION   : mm_camera_intf_set_parms
    280  *
    281  * DESCRIPTION: set parameters per camera
    282  *
    283  * PARAMETERS :
    284  *   @camera_handle: camera handle
    285  *   @parms        : ptr to a param struct to be set to server
    286  *
    287  * RETURN     : int32_t type of status
    288  *              0  -- success
    289  *              -1 -- failure
    290  * NOTE       : Assume the parms struct buf is already mapped to server via
    291  *              domain socket. Corresponding fields of parameters to be set
    292  *              are already filled in by upper layer caller.
    293  *==========================================================================*/
    294 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle,
    295                                         parm_buffer_t *parms)
    296 {
    297     int32_t rc = -1;
    298     mm_camera_obj_t * my_obj = NULL;
    299 
    300     uint32_t handle = get_main_camera_handle(camera_handle);
    301     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    302 
    303     if (aux_handle) {
    304         pthread_mutex_lock(&g_intf_lock);
    305         my_obj = mm_camera_util_get_camera_head(aux_handle);
    306         if (my_obj) {
    307             pthread_mutex_lock(&my_obj->muxer_lock);
    308             pthread_mutex_unlock(&g_intf_lock);
    309             rc = mm_camera_muxer_set_parms(aux_handle,
    310                     parms, my_obj);
    311         } else {
    312             pthread_mutex_unlock(&g_intf_lock);
    313         }
    314     }
    315 
    316     if (handle) {
    317         pthread_mutex_lock(&g_intf_lock);
    318         my_obj = mm_camera_util_get_camera_by_handler(handle);
    319 
    320         if(my_obj) {
    321             pthread_mutex_lock(&my_obj->cam_lock);
    322             pthread_mutex_unlock(&g_intf_lock);
    323             rc = mm_camera_set_parms(my_obj, parms);
    324         } else {
    325             pthread_mutex_unlock(&g_intf_lock);
    326         }
    327     }
    328     return rc;
    329 }
    330 
    331 /*===========================================================================
    332  * FUNCTION   : mm_camera_intf_get_parms
    333  *
    334  * DESCRIPTION: get parameters per camera
    335  *
    336  * PARAMETERS :
    337  *   @camera_handle: camera handle
    338  *   @parms        : ptr to a param struct to be get from server
    339  *
    340  * RETURN     : int32_t type of status
    341  *              0  -- success
    342  *              -1 -- failure
    343  * NOTE       : Assume the parms struct buf is already mapped to server via
    344  *              domain socket. Parameters to be get from server are already
    345  *              filled in by upper layer caller. After this call, corresponding
    346  *              fields of requested parameters will be filled in by server with
    347  *              detailed information.
    348  *==========================================================================*/
    349 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle,
    350                                         parm_buffer_t *parms)
    351 {
    352     int32_t rc = -1;
    353     mm_camera_obj_t * my_obj = NULL;
    354     uint32_t handle = get_main_camera_handle(camera_handle);
    355     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    356 
    357     if (aux_handle) {
    358         pthread_mutex_lock(&g_intf_lock);
    359         my_obj = mm_camera_util_get_camera_head(aux_handle);
    360         if (my_obj) {
    361             pthread_mutex_lock(&my_obj->muxer_lock);
    362             pthread_mutex_unlock(&g_intf_lock);
    363             rc = mm_camera_muxer_get_parms(aux_handle,
    364                     parms, my_obj);
    365         } else {
    366             pthread_mutex_unlock(&g_intf_lock);
    367         }
    368     }
    369 
    370     if (handle) {
    371         pthread_mutex_lock(&g_intf_lock);
    372         my_obj = mm_camera_util_get_camera_by_handler(handle);
    373 
    374         if(my_obj) {
    375             pthread_mutex_lock(&my_obj->cam_lock);
    376             pthread_mutex_unlock(&g_intf_lock);
    377             rc = mm_camera_get_parms(my_obj, parms);
    378         } else {
    379             pthread_mutex_unlock(&g_intf_lock);
    380         }
    381     }
    382     return rc;
    383 
    384 }
    385 
    386 /*===========================================================================
    387  * FUNCTION   : mm_camera_intf_do_auto_focus
    388  *
    389  * DESCRIPTION: performing auto focus
    390  *
    391  * PARAMETERS :
    392  *   @camera_handle: camera handle
    393  *
    394  * RETURN     : int32_t type of status
    395  *              0  -- success
    396  *              -1 -- failure
    397  * NOTE       : if this call success, we will always assume there will
    398  *              be an auto_focus event following up.
    399  *==========================================================================*/
    400 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle)
    401 {
    402     int32_t rc = -1;
    403     mm_camera_obj_t * my_obj = NULL;
    404     uint32_t handle = get_main_camera_handle(camera_handle);
    405     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    406 
    407     if (aux_handle) {
    408         pthread_mutex_lock(&g_intf_lock);
    409         my_obj = mm_camera_util_get_camera_head(aux_handle);
    410         if (my_obj) {
    411             pthread_mutex_lock(&my_obj->muxer_lock);
    412             pthread_mutex_unlock(&g_intf_lock);
    413             rc = mm_camera_muxer_do_auto_focus(aux_handle, my_obj);
    414         } else {
    415             pthread_mutex_unlock(&g_intf_lock);
    416         }
    417     }
    418 
    419     if (handle) {
    420         pthread_mutex_lock(&g_intf_lock);
    421         my_obj = mm_camera_util_get_camera_by_handler(handle);
    422 
    423         if(my_obj) {
    424             pthread_mutex_lock(&my_obj->cam_lock);
    425             pthread_mutex_unlock(&g_intf_lock);
    426             rc = mm_camera_do_auto_focus(my_obj);
    427         } else {
    428             pthread_mutex_unlock(&g_intf_lock);
    429         }
    430     }
    431     LOGH("rc = %d camera_handle = %u X", rc, camera_handle);
    432     return rc;
    433 }
    434 
    435 /*===========================================================================
    436  * FUNCTION   : mm_camera_intf_cancel_auto_focus
    437  *
    438  * DESCRIPTION: cancel auto focus
    439  *
    440  * PARAMETERS :
    441  *   @camera_handle: camera handle
    442  *
    443  * RETURN     : int32_t type of status
    444  *              0  -- success
    445  *              -1 -- failure
    446  *==========================================================================*/
    447 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)
    448 {
    449     int32_t rc = -1;
    450     mm_camera_obj_t * my_obj = NULL;
    451     uint32_t handle = get_main_camera_handle(camera_handle);
    452     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    453 
    454     if (aux_handle) {
    455         pthread_mutex_lock(&g_intf_lock);
    456         my_obj = mm_camera_util_get_camera_head(aux_handle);
    457         if (my_obj) {
    458             pthread_mutex_lock(&my_obj->muxer_lock);
    459             pthread_mutex_unlock(&g_intf_lock);
    460             rc = mm_camera_muxer_cancel_auto_focus(aux_handle, my_obj);
    461         } else {
    462             pthread_mutex_unlock(&g_intf_lock);
    463         }
    464     }
    465 
    466     if (handle) {
    467         pthread_mutex_lock(&g_intf_lock);
    468         my_obj = mm_camera_util_get_camera_by_handler(handle);
    469         if(my_obj) {
    470             pthread_mutex_lock(&my_obj->cam_lock);
    471             pthread_mutex_unlock(&g_intf_lock);
    472             rc = mm_camera_cancel_auto_focus(my_obj);
    473         } else {
    474             pthread_mutex_unlock(&g_intf_lock);
    475         }
    476     }
    477     LOGH("rc = %d camera_handle = %u X", rc, camera_handle);
    478     return rc;
    479 }
    480 
    481 /*===========================================================================
    482  * FUNCTION   : mm_camera_intf_prepare_snapshot
    483  *
    484  * DESCRIPTION: prepare hardware for snapshot
    485  *
    486  * PARAMETERS :
    487  *   @camera_handle: camera handle
    488  *   @do_af_flag   : flag indicating if AF is needed
    489  *
    490  * RETURN     : int32_t type of status
    491  *              0  -- success
    492  *              -1 -- failure
    493  *==========================================================================*/
    494 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle,
    495                                                int32_t do_af_flag)
    496 {
    497     int32_t rc = -1;
    498     mm_camera_obj_t * my_obj = NULL;
    499     uint32_t handle = get_main_camera_handle(camera_handle);
    500     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    501 
    502     if (aux_handle) {
    503         pthread_mutex_lock(&g_intf_lock);
    504         my_obj = mm_camera_util_get_camera_head(aux_handle);
    505         if (my_obj) {
    506             pthread_mutex_lock(&my_obj->muxer_lock);
    507             pthread_mutex_unlock(&g_intf_lock);
    508             rc = mm_camera_muxer_prepare_snapshot(aux_handle,
    509                     do_af_flag, my_obj);
    510         } else {
    511             pthread_mutex_unlock(&g_intf_lock);
    512         }
    513     }
    514 
    515     if (handle) {
    516         pthread_mutex_lock(&g_intf_lock);
    517         my_obj = mm_camera_util_get_camera_by_handler(handle);
    518 
    519         if(my_obj) {
    520             pthread_mutex_lock(&my_obj->cam_lock);
    521             pthread_mutex_unlock(&g_intf_lock);
    522 
    523             rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
    524         } else {
    525             pthread_mutex_unlock(&g_intf_lock);
    526         }
    527         return rc;
    528     }
    529     LOGH("rc = %d camera_handle = %u X", rc, camera_handle);
    530     return rc;
    531 }
    532 
    533 /*===========================================================================
    534  * FUNCTION   : mm_camera_intf_flush
    535  *
    536  * DESCRIPTION: flush the current camera state and buffers
    537  *
    538  * PARAMETERS :
    539  *   @camera_handle: camera handle
    540  *
    541  * RETURN     : int32_t type of status
    542  *              0  -- success
    543  *              -1 -- failure
    544  *==========================================================================*/
    545 static int32_t mm_camera_intf_flush(uint32_t camera_handle)
    546 {
    547     int32_t rc = -1;
    548     mm_camera_obj_t * my_obj = NULL;
    549     uint32_t handle = get_main_camera_handle(camera_handle);
    550     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    551 
    552     if (aux_handle) {
    553         pthread_mutex_lock(&g_intf_lock);
    554         my_obj = mm_camera_util_get_camera_head(aux_handle);
    555 
    556         if (my_obj) {
    557             pthread_mutex_lock(&my_obj->muxer_lock);
    558             pthread_mutex_unlock(&g_intf_lock);
    559             rc = mm_camera_muxer_flush(aux_handle, my_obj);
    560         } else {
    561             pthread_mutex_unlock(&g_intf_lock);
    562         }
    563     }
    564 
    565     if (handle) {
    566         pthread_mutex_lock(&g_intf_lock);
    567         my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    568 
    569         if(my_obj) {
    570             pthread_mutex_lock(&my_obj->cam_lock);
    571             pthread_mutex_unlock(&g_intf_lock);
    572             rc = mm_camera_flush(my_obj);
    573         } else {
    574             pthread_mutex_unlock(&g_intf_lock);
    575         }
    576     }
    577     return rc;
    578 }
    579 
    580 /*===========================================================================
    581  * FUNCTION   : mm_camera_intf_close
    582  *
    583  * DESCRIPTION: close a camera by its handle
    584  *
    585  * PARAMETERS :
    586  *   @camera_handle: camera handle
    587  *
    588  * RETURN     : int32_t type of status
    589  *              0  -- success
    590  *              -1 -- failure
    591  *==========================================================================*/
    592 static int32_t mm_camera_intf_close(uint32_t camera_handle)
    593 {
    594     int32_t rc = -1;
    595     uint8_t cam_idx = -1;
    596     mm_camera_obj_t *my_obj = NULL;
    597 
    598     LOGD("E: camera_handler = %d ", camera_handle);
    599 
    600     uint32_t handle = get_main_camera_handle(camera_handle);
    601     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    602     if (aux_handle) {
    603         pthread_mutex_lock(&g_intf_lock);
    604         my_obj = mm_camera_util_get_camera_head(aux_handle);
    605         if (my_obj) {
    606             pthread_mutex_lock(&my_obj->muxer_lock);
    607             pthread_mutex_unlock(&g_intf_lock);
    608             rc = mm_camera_muxer_close_camera(aux_handle, my_obj);
    609         }
    610     }
    611 
    612     if (handle) {
    613         pthread_mutex_lock(&g_intf_lock);
    614         my_obj = mm_camera_util_get_camera_by_handler(handle);
    615 
    616         if (my_obj){
    617             if (my_obj->aux_cam_obj[0] != NULL) {
    618                 /*Close aux cameras*/
    619                 pthread_mutex_lock(&my_obj->muxer_lock);
    620                 pthread_mutex_unlock(&g_intf_lock);
    621                 rc = mm_camera_muxer_close_camera(
    622                         my_obj->aux_cam_obj[0]->my_hdl, my_obj);
    623                 pthread_mutex_lock(&g_intf_lock);
    624             }
    625 
    626             cam_idx = mm_camera_util_get_index_by_num(
    627                     my_obj->my_num, my_obj->my_hdl);
    628             my_obj->ref_count--;
    629             if(my_obj->ref_count > 0) {
    630                 /* still have reference to obj, return here */
    631                 LOGD("ref_count=%d\n", my_obj->ref_count);
    632                 pthread_mutex_unlock(&g_intf_lock);
    633                 rc = 0;
    634             } else {
    635                 /* need close camera here as no other reference
    636                  * first empty g_cam_ctrl's referent to cam_obj */
    637                 g_cam_ctrl.cam_obj[cam_idx] = NULL;
    638                 pthread_mutex_lock(&my_obj->cam_lock);
    639                 pthread_mutex_unlock(&g_intf_lock);
    640                 rc = mm_camera_close(my_obj);
    641                 pthread_mutex_destroy(&my_obj->cam_lock);
    642                 pthread_mutex_destroy(&my_obj->muxer_lock);
    643                 free(my_obj);
    644                 my_obj = NULL;
    645             }
    646         } else {
    647              pthread_mutex_unlock(&g_intf_lock);
    648         }
    649     } else {
    650         pthread_mutex_unlock(&g_intf_lock);
    651     }
    652 
    653     LOGH("camera_handler = %u rc = %d", camera_handle, rc);
    654 #ifdef QCAMERA_REDEFINE_LOG
    655     mm_camera_debug_close();
    656 #endif
    657 
    658     return rc;
    659 }
    660 
    661 /*===========================================================================
    662  * FUNCTION   : mm_camera_intf_add_channel
    663  *
    664  * DESCRIPTION: add a channel
    665  *
    666  * PARAMETERS :
    667  *   @camera_handle: camera handle
    668  *   @attr         : bundle attribute of the channel if needed
    669  *   @channel_cb   : callback function for bundle data notify
    670  *   @userdata     : user data ptr
    671  *
    672  * RETURN     : uint32_t type of channel handle
    673  *              0  -- invalid channel handle, meaning the op failed
    674  *              >0 -- successfully added a channel with a valid handle
    675  * NOTE       : if no bundle data notify is needed, meaning each stream in the
    676  *              channel will have its own stream data notify callback, then
    677  *              attr, channel_cb, and userdata can be NULL. In this case,
    678  *              no matching logic will be performed in channel for the bundling.
    679  *==========================================================================*/
    680 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
    681                                            mm_camera_channel_attr_t *attr,
    682                                            mm_camera_buf_notify_t channel_cb,
    683                                            void *userdata)
    684 {
    685     uint32_t ch_id = 0, aux_ch_id = 0;
    686     mm_camera_obj_t * my_obj = NULL;
    687     uint32_t handle = get_main_camera_handle(camera_handle);
    688     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    689 
    690     LOGD("E camera_handler = %d", camera_handle);
    691     if (handle) {
    692         pthread_mutex_lock(&g_intf_lock);
    693         my_obj = mm_camera_util_get_camera_by_handler(handle);
    694         if(my_obj) {
    695             pthread_mutex_lock(&my_obj->cam_lock);
    696             pthread_mutex_unlock(&g_intf_lock);
    697             ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
    698         } else {
    699             pthread_mutex_unlock(&g_intf_lock);
    700         }
    701     }
    702 
    703     if (aux_handle) {
    704         pthread_mutex_lock(&g_intf_lock);
    705         my_obj = mm_camera_util_get_camera_head(aux_handle);
    706         if (my_obj) {
    707             pthread_mutex_lock(&my_obj->muxer_lock);
    708             pthread_mutex_unlock(&g_intf_lock);
    709             aux_ch_id = mm_camera_muxer_add_channel(aux_handle, attr,
    710                     channel_cb, userdata, ch_id, my_obj);
    711             if (aux_ch_id <= 0) {
    712                 pthread_mutex_lock(&my_obj->cam_lock);
    713                 mm_camera_del_channel(my_obj, ch_id);
    714             } else {
    715                 ch_id |= aux_ch_id;
    716            }
    717         } else {
    718             pthread_mutex_unlock(&g_intf_lock);
    719         }
    720     }
    721     LOGH("camera_handle = %u ch_id = %u X", camera_handle, ch_id);
    722     return ch_id;
    723 }
    724 
    725 /*===========================================================================
    726  * FUNCTION   : mm_camera_intf_del_channel
    727  *
    728  * DESCRIPTION: delete a channel by its handle
    729  *
    730  * PARAMETERS :
    731  *   @camera_handle: camera handle
    732  *   @ch_id        : channel handle
    733  *
    734  * RETURN     : int32_t type of status
    735  *              0  -- success
    736  *              -1 -- failure
    737  * NOTE       : all streams in the channel should be stopped already before
    738  *              this channel can be deleted.
    739  *==========================================================================*/
    740 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
    741                                           uint32_t ch_id)
    742 {
    743     int32_t rc = -1;
    744     mm_camera_obj_t * my_obj = NULL;
    745     uint32_t m_chid = get_main_camera_handle(ch_id);
    746     uint32_t aux_chid = get_aux_camera_handle(ch_id);
    747 
    748     LOGD("E ch_id = %d", ch_id);
    749 
    750     if (aux_chid) {
    751         pthread_mutex_lock(&g_intf_lock);
    752         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    753         my_obj = mm_camera_util_get_camera_head(aux_handle);
    754         if (my_obj) {
    755             pthread_mutex_lock(&my_obj->muxer_lock);
    756             pthread_mutex_unlock(&g_intf_lock);
    757             mm_camera_muxer_delete_channel(aux_handle, aux_chid, my_obj);
    758         } else {
    759             pthread_mutex_unlock(&g_intf_lock);
    760         }
    761     }
    762 
    763     if (m_chid) {
    764         pthread_mutex_lock(&g_intf_lock);
    765         uint32_t handle = get_main_camera_handle(camera_handle);
    766         my_obj = mm_camera_util_get_camera_by_handler(handle);
    767 
    768         if(my_obj) {
    769             pthread_mutex_lock(&my_obj->cam_lock);
    770             pthread_mutex_unlock(&g_intf_lock);
    771             rc = mm_camera_del_channel(my_obj, m_chid);
    772         } else {
    773             pthread_mutex_unlock(&g_intf_lock);
    774         }
    775     }
    776     LOGH("rc = %d ch_id = %u X", rc, ch_id);
    777     return rc;
    778 }
    779 
    780 /*===========================================================================
    781  * FUNCTION   : mm_camera_intf_get_bundle_info
    782  *
    783  * DESCRIPTION: query bundle info of the channel
    784  *
    785  * PARAMETERS :
    786  *   @camera_handle: camera handle
    787  *   @ch_id        : channel handle
    788  *   @bundle_info  : bundle info to be filled in
    789  *
    790  * RETURN     : int32_t type of status
    791  *              0  -- success
    792  *              -1 -- failure
    793  * NOTE       : all streams in the channel should be stopped already before
    794  *              this channel can be deleted.
    795  *==========================================================================*/
    796 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
    797                                               uint32_t ch_id,
    798                                               cam_bundle_config_t *bundle_info)
    799 {
    800     int32_t rc = -1;
    801     mm_camera_obj_t * my_obj = NULL;
    802     uint32_t m_chid = get_main_camera_handle(ch_id);
    803     uint32_t aux_chid = get_aux_camera_handle(ch_id);
    804 
    805     LOGD("E ch_id = %d", ch_id);
    806 
    807     if (aux_chid && m_chid) {
    808         LOGE("Does not support 2 channels for bundle info");
    809         return rc;
    810     }
    811 
    812     if (aux_chid) {
    813         pthread_mutex_lock(&g_intf_lock);
    814         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    815         my_obj = mm_camera_util_get_camera_head(aux_handle);
    816         if (my_obj) {
    817             pthread_mutex_lock(&my_obj->muxer_lock);
    818             pthread_mutex_unlock(&g_intf_lock);
    819             rc = mm_camera_muxer_get_bundle_info(aux_handle, aux_chid,
    820                     bundle_info, my_obj);
    821         } else {
    822             pthread_mutex_unlock(&g_intf_lock);
    823         }
    824     } else if (m_chid) {
    825         pthread_mutex_lock(&g_intf_lock);
    826         uint32_t handle = get_main_camera_handle(camera_handle);
    827         my_obj = mm_camera_util_get_camera_by_handler(handle);
    828         if(my_obj) {
    829             pthread_mutex_lock(&my_obj->cam_lock);
    830             pthread_mutex_unlock(&g_intf_lock);
    831             rc = mm_camera_get_bundle_info(my_obj, m_chid, bundle_info);
    832         } else {
    833             pthread_mutex_unlock(&g_intf_lock);
    834         }
    835     }
    836     LOGD("rc = %d ch_id = %d X", rc, ch_id);
    837     return rc;
    838 }
    839 
    840 /*===========================================================================
    841  * FUNCTION   : mm_camera_intf_register_event_notify
    842  *
    843  * DESCRIPTION: register for event notify
    844  *
    845  * PARAMETERS :
    846  *   @camera_handle: camera handle
    847  *   @evt_cb       : callback for event notify
    848  *   @user_data    : user data ptr
    849  *
    850  * RETURN     : int32_t type of status
    851  *              0  -- success
    852  *              -1 -- failure
    853  *==========================================================================*/
    854 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
    855                                                     mm_camera_event_notify_t evt_cb,
    856                                                     void * user_data)
    857 {
    858     int32_t rc = -1;
    859     mm_camera_obj_t *my_obj = NULL;
    860     LOGD("E ");
    861 
    862     uint32_t handle = get_main_camera_handle(camera_handle);
    863     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    864 
    865     if (handle) {
    866         pthread_mutex_lock(&g_intf_lock);
    867         my_obj = mm_camera_util_get_camera_by_handler(handle);
    868 
    869         if(my_obj) {
    870             pthread_mutex_lock(&my_obj->cam_lock);
    871             pthread_mutex_unlock(&g_intf_lock);
    872             rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
    873         } else {
    874             pthread_mutex_unlock(&g_intf_lock);
    875         }
    876     }
    877 
    878     if (aux_handle) {
    879         pthread_mutex_lock(&g_intf_lock);
    880         my_obj = mm_camera_util_get_camera_head(aux_handle);
    881         if (my_obj) {
    882             pthread_mutex_lock(&my_obj->muxer_lock);
    883             pthread_mutex_unlock(&g_intf_lock);
    884             rc = mm_camera_muxer_register_event_notify(aux_handle,
    885                     evt_cb, user_data, my_obj);
    886         }
    887     }
    888     LOGD("E rc = %d", rc);
    889     return rc;
    890 }
    891 
    892 /*===========================================================================
    893  * FUNCTION   : mm_camera_intf_qbuf
    894  *
    895  * DESCRIPTION: enqueue buffer back to kernel
    896  *
    897  * PARAMETERS :
    898  *   @camera_handle: camera handle
    899  *   @ch_id        : channel handle
    900  *   @buf          : buf ptr to be enqueued
    901  *
    902  * RETURN     : int32_t type of status
    903  *              0  -- success
    904  *              -1 -- failure
    905  *==========================================================================*/
    906 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
    907                                     uint32_t ch_id,
    908                                     mm_camera_buf_def_t *buf)
    909 {
    910     int32_t rc = -1;
    911     mm_camera_obj_t *my_obj = NULL;
    912     uint32_t strid = 0;
    913     uint32_t aux_strid = 0;
    914 
    915     if (buf != NULL) {
    916         strid = get_main_camera_handle(buf->stream_id);
    917         aux_strid = get_aux_camera_handle(buf->stream_id);
    918     }
    919 
    920     if (strid) {
    921         pthread_mutex_lock(&g_intf_lock);
    922         uint32_t handle = get_main_camera_handle(camera_handle);
    923         uint32_t chid = get_main_camera_handle(ch_id);
    924         my_obj = mm_camera_util_get_camera_by_handler(handle);
    925         if(my_obj) {
    926             pthread_mutex_lock(&my_obj->cam_lock);
    927             pthread_mutex_unlock(&g_intf_lock);
    928             rc = mm_camera_qbuf(my_obj, chid, buf);
    929         } else {
    930             pthread_mutex_unlock(&g_intf_lock);
    931         }
    932     }
    933 
    934     if (aux_strid) {
    935         pthread_mutex_lock(&g_intf_lock);
    936         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
    937         uint32_t aux_chid = get_aux_camera_handle(ch_id);
    938         my_obj = mm_camera_util_get_camera_head(aux_handle);
    939         if (my_obj) {
    940             pthread_mutex_lock(&my_obj->muxer_lock);
    941             pthread_mutex_unlock(&g_intf_lock);
    942             rc = mm_camera_muxer_qbuf(aux_handle, aux_chid, buf, my_obj);
    943         } else {
    944             pthread_mutex_unlock(&g_intf_lock);
    945         }
    946     }
    947     LOGD("X evt_type = %d",rc);
    948     return rc;
    949 }
    950 
    951 /*===========================================================================
    952  * FUNCTION   : mm_camera_intf_qbuf
    953  *
    954  * DESCRIPTION: enqueue buffer back to kernel
    955  *
    956  * PARAMETERS :
    957  *   @camera_handle: camera handle
    958  *   @ch_id        : channel handle
    959  *   @buf          : buf ptr to be enqueued
    960  *
    961  * RETURN     : int32_t type of status
    962  *              0  -- success
    963  *              -1 -- failure
    964  *==========================================================================*/
    965 static int32_t mm_camera_intf_cancel_buf(uint32_t camera_handle, uint32_t ch_id, uint32_t stream_id,
    966                      uint32_t buf_idx)
    967 {
    968     int32_t rc = -1;
    969     mm_camera_obj_t * my_obj = NULL;
    970 
    971     pthread_mutex_lock(&g_intf_lock);
    972     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    973 
    974     if(my_obj) {
    975         pthread_mutex_lock(&my_obj->cam_lock);
    976         pthread_mutex_unlock(&g_intf_lock);
    977         rc = mm_camera_cancel_buf(my_obj, ch_id, stream_id, buf_idx);
    978     } else {
    979         pthread_mutex_unlock(&g_intf_lock);
    980     }
    981     LOGD("X evt_type = %d",rc);
    982     return rc;
    983 }
    984 
    985 
    986 /*===========================================================================
    987  * FUNCTION   : mm_camera_intf_get_queued_buf_count
    988  *
    989  * DESCRIPTION: returns the queued buffer count
    990  *
    991  * PARAMETERS :
    992  *   @camera_handle: camera handle
    993  *   @ch_id        : channel handle
    994  *   @stream_id : stream id
    995  *
    996  * RETURN     : int32_t - queued buffer count
    997  *
    998  *==========================================================================*/
    999 static int32_t mm_camera_intf_get_queued_buf_count(uint32_t camera_handle,
   1000         uint32_t ch_id, uint32_t stream_id)
   1001 {
   1002     int32_t rc = -1;
   1003     mm_camera_obj_t * my_obj = NULL;
   1004     uint32_t strid = get_main_camera_handle(stream_id);
   1005     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   1006 
   1007     if (strid) {
   1008         pthread_mutex_lock(&g_intf_lock);
   1009         uint32_t handle = get_main_camera_handle(camera_handle);
   1010         uint32_t chid = get_main_camera_handle(ch_id);
   1011         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1012         if(my_obj) {
   1013             pthread_mutex_lock(&my_obj->cam_lock);
   1014             pthread_mutex_unlock(&g_intf_lock);
   1015             rc = mm_camera_get_queued_buf_count(my_obj, chid, strid);
   1016         } else {
   1017             pthread_mutex_unlock(&g_intf_lock);
   1018         }
   1019     } else if (aux_strid) {
   1020         pthread_mutex_lock(&g_intf_lock);
   1021         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1022         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1023         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1024         if (my_obj) {
   1025             pthread_mutex_lock(&my_obj->muxer_lock);
   1026             pthread_mutex_unlock(&g_intf_lock);
   1027             rc = mm_camera_muxer_get_queued_buf_count(aux_handle,
   1028                     aux_chid, aux_strid, my_obj);
   1029         } else {
   1030             pthread_mutex_unlock(&g_intf_lock);
   1031         }
   1032     }
   1033     LOGD("X queued buffer count = %d",rc);
   1034     return rc;
   1035 }
   1036 
   1037 /*===========================================================================
   1038  * FUNCTION   : mm_camera_intf_link_stream
   1039  *
   1040  * DESCRIPTION: link a stream into a new channel
   1041  *
   1042  * PARAMETERS :
   1043  *   @camera_handle: camera handle
   1044  *   @ch_id        : channel handle
   1045  *   @stream_id    : stream id
   1046  *   @linked_ch_id : channel in which the stream will be linked
   1047  *
   1048  * RETURN     : int32_t type of stream handle
   1049  *              0  -- invalid stream handle, meaning the op failed
   1050  *              >0 -- successfully linked a stream with a valid handle
   1051  *==========================================================================*/
   1052 static int32_t mm_camera_intf_link_stream(uint32_t camera_handle,
   1053         uint32_t ch_id,
   1054         uint32_t stream_id,
   1055         uint32_t linked_ch_id)
   1056 {
   1057     uint32_t id = 0;
   1058     mm_camera_obj_t * my_obj = NULL;
   1059     uint32_t strid = get_main_camera_handle(stream_id);
   1060     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   1061     uint32_t linked_chid = get_main_camera_handle(linked_ch_id);
   1062     uint32_t aux_linked_chid = get_aux_camera_handle(linked_ch_id);
   1063 
   1064     LOGD("E handle = %u ch_id = %u",
   1065           camera_handle, ch_id);
   1066 
   1067     if (strid && linked_chid) {
   1068         pthread_mutex_lock(&g_intf_lock);
   1069         uint32_t handle = get_main_camera_handle(camera_handle);
   1070         uint32_t m_chid = get_main_camera_handle(ch_id);
   1071         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1072 
   1073         if(my_obj) {
   1074             pthread_mutex_lock(&my_obj->cam_lock);
   1075             pthread_mutex_unlock(&g_intf_lock);
   1076             id = mm_camera_link_stream(my_obj, m_chid, strid, linked_chid);
   1077         } else {
   1078             pthread_mutex_unlock(&g_intf_lock);
   1079         }
   1080     }
   1081 
   1082     if (aux_strid && aux_linked_chid) {
   1083         pthread_mutex_lock(&g_intf_lock);
   1084         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1085         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1086         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1087         if (my_obj) {
   1088             pthread_mutex_lock(&my_obj->muxer_lock);
   1089             pthread_mutex_unlock(&g_intf_lock);
   1090             id = mm_camera_muxer_link_stream(aux_handle, aux_chid,
   1091                     aux_strid, aux_linked_chid, my_obj);
   1092         } else {
   1093             pthread_mutex_unlock(&g_intf_lock);
   1094         }
   1095     }
   1096 
   1097     LOGH("X ch_id = %u stream_id = %u linked_ch_id = %u id = %u",
   1098             ch_id, stream_id, linked_ch_id, id);
   1099     return (int32_t)id;
   1100 }
   1101 
   1102 /*===========================================================================
   1103  * FUNCTION   : mm_camera_intf_add_stream
   1104  *
   1105  * DESCRIPTION: add a stream into a channel
   1106  *
   1107  * PARAMETERS :
   1108  *   @camera_handle: camera handle
   1109  *   @ch_id        : channel handle
   1110  *
   1111  * RETURN     : uint32_t type of stream handle
   1112  *              0  -- invalid stream handle, meaning the op failed
   1113  *              >0 -- successfully added a stream with a valid handle
   1114  *==========================================================================*/
   1115 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
   1116                                           uint32_t ch_id)
   1117 {
   1118     uint32_t stream_id = 0, aux_stream_id;
   1119     mm_camera_obj_t *my_obj = NULL;
   1120     uint32_t m_ch_id = get_main_camera_handle(ch_id);
   1121     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1122 
   1123     LOGD("E handle = %d ch_id = %d",
   1124           camera_handle, ch_id);
   1125     if (m_ch_id) {
   1126         pthread_mutex_lock(&g_intf_lock);
   1127         uint32_t handle = get_main_camera_handle(camera_handle);
   1128         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1129         if(my_obj) {
   1130             pthread_mutex_lock(&my_obj->cam_lock);
   1131             pthread_mutex_unlock(&g_intf_lock);
   1132             stream_id = mm_camera_add_stream(my_obj, m_ch_id);
   1133        } else {
   1134             pthread_mutex_unlock(&g_intf_lock);
   1135        }
   1136     }
   1137 
   1138     if (aux_chid) {
   1139         pthread_mutex_lock(&g_intf_lock);
   1140         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1141         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1142         if (my_obj) {
   1143             pthread_mutex_lock(&my_obj->muxer_lock);
   1144             pthread_mutex_unlock(&g_intf_lock);
   1145             aux_stream_id = mm_camera_muxer_add_stream(aux_handle, aux_chid,
   1146                     m_ch_id, stream_id, my_obj);
   1147             if (aux_stream_id <= 0) {
   1148                 LOGE("Failed to add stream");
   1149                 pthread_mutex_lock(&my_obj->cam_lock);
   1150                 mm_camera_del_stream(my_obj, m_ch_id, stream_id);
   1151             } else {
   1152                 stream_id = stream_id | aux_stream_id;
   1153             }
   1154         } else {
   1155             pthread_mutex_unlock(&g_intf_lock);
   1156         }
   1157     }
   1158     LOGH("X ch_id = %u stream_id = %u", ch_id, stream_id);
   1159     return stream_id;
   1160 }
   1161 
   1162 /*===========================================================================
   1163  * FUNCTION   : mm_camera_intf_del_stream
   1164  *
   1165  * DESCRIPTION: delete a stream by its handle
   1166  *
   1167  * PARAMETERS :
   1168  *   @camera_handle: camera handle
   1169  *   @ch_id        : channel handle
   1170  *   @stream_id    : stream handle
   1171  *
   1172  * RETURN     : int32_t type of status
   1173  *              0  -- success
   1174  *              -1 -- failure
   1175  * NOTE       : stream should be stopped already before it can be deleted.
   1176  *==========================================================================*/
   1177 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
   1178                                          uint32_t ch_id,
   1179                                          uint32_t stream_id)
   1180 {
   1181     int32_t rc = -1;
   1182     mm_camera_obj_t * my_obj = NULL;
   1183     uint32_t m_strid = get_main_camera_handle(stream_id);
   1184     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   1185 
   1186     LOGD("E handle = %d ch_id = %d stream_id = %d",
   1187           camera_handle, ch_id, stream_id);
   1188 
   1189     if (aux_strid) {
   1190         pthread_mutex_lock(&g_intf_lock);
   1191         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1192         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1193         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1194         if (my_obj) {
   1195             pthread_mutex_lock(&my_obj->muxer_lock);
   1196             pthread_mutex_unlock(&g_intf_lock);
   1197             mm_camera_muxer_delete_stream(aux_handle, aux_chid,
   1198                     aux_strid, my_obj);
   1199         } else {
   1200             pthread_mutex_unlock(&g_intf_lock);
   1201         }
   1202     }
   1203 
   1204     if (m_strid) {
   1205         pthread_mutex_lock(&g_intf_lock);
   1206         uint32_t handle = get_main_camera_handle(camera_handle);
   1207         uint32_t m_chid = get_main_camera_handle(ch_id);
   1208 
   1209         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1210         if(my_obj) {
   1211             pthread_mutex_lock(&my_obj->cam_lock);
   1212             pthread_mutex_unlock(&g_intf_lock);
   1213             rc = mm_camera_del_stream(my_obj, m_chid, m_strid);
   1214         } else {
   1215             pthread_mutex_unlock(&g_intf_lock);
   1216         }
   1217     }
   1218     LOGH("X stream_id = %u rc = %d", stream_id, rc);
   1219     return rc;
   1220 }
   1221 
   1222 /*===========================================================================
   1223  * FUNCTION   : mm_camera_intf_config_stream
   1224  *
   1225  * DESCRIPTION: configure a stream
   1226  *
   1227  * PARAMETERS :
   1228  *   @camera_handle: camera handle
   1229  *   @ch_id        : channel handle
   1230  *   @stream_id    : stream handle
   1231  *   @config       : stream configuration
   1232  *
   1233  * RETURN     : int32_t type of status
   1234  *              0  -- success
   1235  *              -1 -- failure
   1236  *==========================================================================*/
   1237 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
   1238                                             uint32_t ch_id,
   1239                                             uint32_t stream_id,
   1240                                             mm_camera_stream_config_t *config)
   1241 {
   1242     int32_t rc = 0;
   1243     mm_camera_obj_t * my_obj = NULL;
   1244     uint32_t strid = get_main_camera_handle(stream_id);
   1245     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   1246 
   1247     LOGD("E handle = %d, ch_id = %d,stream_id = %d",
   1248           camera_handle, ch_id, stream_id);
   1249 
   1250     if (strid) {
   1251         pthread_mutex_lock(&g_intf_lock);
   1252         uint32_t handle = get_main_camera_handle(camera_handle);
   1253         uint32_t chid = get_main_camera_handle(ch_id);
   1254 
   1255         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1256         if(my_obj) {
   1257             pthread_mutex_lock(&my_obj->cam_lock);
   1258             pthread_mutex_unlock(&g_intf_lock);
   1259             rc = mm_camera_config_stream(my_obj, chid, strid, config);
   1260         } else {
   1261             pthread_mutex_unlock(&g_intf_lock);
   1262         }
   1263     }
   1264 
   1265     if (aux_strid && rc == 0) {
   1266         pthread_mutex_lock(&g_intf_lock);
   1267         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1268         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1269 
   1270         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1271         if (my_obj) {
   1272             pthread_mutex_lock(&my_obj->muxer_lock);
   1273             pthread_mutex_unlock(&g_intf_lock);
   1274             rc = mm_camera_muxer_config_stream(aux_handle,
   1275                     aux_chid, aux_strid, config, my_obj);
   1276         } else {
   1277             pthread_mutex_unlock(&g_intf_lock);
   1278         }
   1279     }
   1280     LOGH("X stream_id = %u rc = %d", stream_id, rc);
   1281     return rc;
   1282 }
   1283 
   1284 /*===========================================================================
   1285  * FUNCTION   : mm_camera_intf_start_channel
   1286  *
   1287  * DESCRIPTION: start a channel, which will start all streams in the channel
   1288  *
   1289  * PARAMETERS :
   1290  *   @camera_handle: camera handle
   1291  *   @ch_id        : channel handle
   1292  *   @start_sensor_streaming: whether to start sensor streaming.
   1293  *                            If false, start_sensor_streaming() must be
   1294  *                            called to start sensor streaming.
   1295  *
   1296  * RETURN     : int32_t type of status
   1297  *              0  -- success
   1298  *              -1 -- failure
   1299  *==========================================================================*/
   1300 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
   1301                                             uint32_t ch_id,
   1302                                             bool start_sensor_streaming)
   1303 {
   1304     int32_t rc = -1;
   1305     mm_camera_obj_t * my_obj = NULL;
   1306     uint32_t chid = get_main_camera_handle(ch_id);
   1307     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1308 
   1309     if (chid) {
   1310         uint32_t handle = get_main_camera_handle(camera_handle);
   1311         pthread_mutex_lock(&g_intf_lock);
   1312 
   1313         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1314         if(my_obj) {
   1315             pthread_mutex_lock(&my_obj->cam_lock);
   1316             pthread_mutex_unlock(&g_intf_lock);
   1317             rc = mm_camera_start_channel(my_obj, chid);
   1318             // Start sensor streaming now if needed.
   1319             if (rc == 0 && start_sensor_streaming) {
   1320                 rc = mm_camera_start_sensor_stream_on(my_obj, ch_id);
   1321             }
   1322         } else {
   1323             pthread_mutex_unlock(&g_intf_lock);
   1324         }
   1325     }
   1326 
   1327     if (aux_chid && rc == 0) {
   1328         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1329         pthread_mutex_lock(&g_intf_lock);
   1330 
   1331         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1332         if(my_obj) {
   1333             pthread_mutex_lock(&my_obj->muxer_lock);
   1334             pthread_mutex_unlock(&g_intf_lock);
   1335             rc = mm_camera_muxer_start_channel(aux_handle, aux_chid, my_obj);
   1336         } else {
   1337             pthread_mutex_unlock(&g_intf_lock);
   1338         }
   1339     }
   1340     LOGH("X ch_id = %u rc = %d", ch_id, rc);
   1341     return rc;
   1342 }
   1343 
   1344 static int32_t mm_camera_intf_start_sensor_streaming(uint32_t camera_handle,
   1345                                             uint32_t ch_id)
   1346 {
   1347     int32_t rc = -1;
   1348     mm_camera_obj_t * my_obj = NULL;
   1349     uint32_t chid = get_main_camera_handle(ch_id);
   1350 
   1351     if (chid) {
   1352         uint32_t handle = get_main_camera_handle(camera_handle);
   1353         pthread_mutex_lock(&g_intf_lock);
   1354 
   1355         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1356         if(my_obj) {
   1357             pthread_mutex_lock(&my_obj->cam_lock);
   1358             pthread_mutex_unlock(&g_intf_lock);
   1359             rc = mm_camera_start_sensor_stream_on(my_obj, ch_id);
   1360         } else {
   1361             pthread_mutex_unlock(&g_intf_lock);
   1362         }
   1363     }
   1364 
   1365     LOGH("X ch_id = %u rc = %d", ch_id, rc);
   1366     return rc;
   1367 }
   1368 
   1369 /*===========================================================================
   1370  * FUNCTION   : mm_camera_intf_stop_channel
   1371  *
   1372  * DESCRIPTION: stop a channel, which will stop all streams in the channel
   1373  *
   1374  * PARAMETERS :
   1375  *   @camera_handle   : camera handle
   1376  *   @ch_id           : channel handle
   1377  *   @stop_immediately: stop immediately without waiting for frame boundary.
   1378  *
   1379  * RETURN     : int32_t type of status
   1380  *              0  -- success
   1381  *              -1 -- failure
   1382  *==========================================================================*/
   1383 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
   1384                                            uint32_t ch_id,
   1385                                            bool stop_immediately)
   1386 {
   1387     int32_t rc = -1;
   1388     mm_camera_obj_t * my_obj = NULL;
   1389     uint32_t chid = get_main_camera_handle(ch_id);
   1390     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1391 
   1392     if (aux_chid) {
   1393         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1394         pthread_mutex_lock(&g_intf_lock);
   1395 
   1396         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1397         if(my_obj) {
   1398             pthread_mutex_lock(&my_obj->muxer_lock);
   1399             pthread_mutex_unlock(&g_intf_lock);
   1400             rc = mm_camera_muxer_stop_channel(aux_handle, aux_chid, my_obj);
   1401         } else {
   1402             pthread_mutex_unlock(&g_intf_lock);
   1403         }
   1404     }
   1405     if (chid) {
   1406         uint32_t handle = get_main_camera_handle(camera_handle);
   1407         pthread_mutex_lock(&g_intf_lock);
   1408 
   1409         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1410         if(my_obj) {
   1411             pthread_mutex_lock(&my_obj->cam_lock);
   1412             pthread_mutex_unlock(&g_intf_lock);
   1413             rc = mm_camera_stop_channel(my_obj, chid, stop_immediately);
   1414         } else {
   1415             pthread_mutex_unlock(&g_intf_lock);
   1416         }
   1417     }
   1418     LOGH("X ch_id = %u rc = %d", ch_id, rc);
   1419     return rc;
   1420 
   1421 }
   1422 
   1423 /*===========================================================================
   1424  * FUNCTION   : mm_camera_intf_request_super_buf
   1425  *
   1426  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1427  *              frames from superbuf queue
   1428  *
   1429  * PARAMETERS :
   1430  *   @camera_handle: camera handle
   1431  *   @ch_id             : channel handle
   1432  *   @buf                : request buffer info
   1433  *
   1434  * RETURN     : int32_t type of status
   1435  *              0  -- success
   1436  *              -1 -- failure
   1437  *==========================================================================*/
   1438 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
   1439         uint32_t ch_id, mm_camera_req_buf_t *buf)
   1440 {
   1441     int32_t rc = -1;
   1442     LOGD("E camera_handler = %d,ch_id = %d",
   1443           camera_handle, ch_id);
   1444     mm_camera_obj_t * my_obj = NULL;
   1445     uint32_t chid = get_main_camera_handle(ch_id);
   1446     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1447 
   1448     pthread_mutex_lock(&g_intf_lock);
   1449     if (aux_chid && chid) {
   1450         uint32_t handle = get_main_camera_handle(camera_handle);
   1451         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1452         if (my_obj && buf) {
   1453             pthread_mutex_lock(&my_obj->muxer_lock);
   1454             pthread_mutex_unlock(&g_intf_lock);
   1455             rc = mm_camera_muxer_request_super_buf(
   1456                     ch_id, buf, my_obj);
   1457         } else {
   1458             pthread_mutex_unlock(&g_intf_lock);
   1459         }
   1460     } else if (chid) {
   1461         uint32_t handle = get_main_camera_handle(camera_handle);
   1462         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1463 
   1464         if(my_obj && buf) {
   1465             pthread_mutex_lock(&my_obj->cam_lock);
   1466             pthread_mutex_unlock(&g_intf_lock);
   1467             rc = mm_camera_request_super_buf (my_obj, chid, buf);
   1468         } else {
   1469             pthread_mutex_unlock(&g_intf_lock);
   1470         }
   1471     } else if (aux_chid) {
   1472         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1473         my_obj = mm_camera_util_get_camera_by_handler(aux_handle);
   1474 
   1475         if(my_obj && buf) {
   1476             pthread_mutex_lock(&my_obj->cam_lock);
   1477             pthread_mutex_unlock(&g_intf_lock);
   1478             rc = mm_camera_request_super_buf (my_obj, aux_chid, buf);
   1479         } else {
   1480             pthread_mutex_unlock(&g_intf_lock);
   1481         }
   1482     }
   1483 
   1484     LOGH("X ch_id = %u rc = %d", ch_id, rc);
   1485     return rc;
   1486 }
   1487 
   1488 /*===========================================================================
   1489  * FUNCTION   : mm_camera_intf_cancel_super_buf_request
   1490  *
   1491  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
   1492  *              of matched frames from superbuf queue
   1493  *
   1494  * PARAMETERS :
   1495  *   @camera_handle: camera handle
   1496  *   @ch_id        : channel handle
   1497  *
   1498  * RETURN     : int32_t type of status
   1499  *              0  -- success
   1500  *              -1 -- failure
   1501  *==========================================================================*/
   1502 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
   1503                                                        uint32_t ch_id)
   1504 {
   1505     int32_t rc = -1;
   1506     LOGD("E camera_handler = %d,ch_id = %d",
   1507           camera_handle, ch_id);
   1508     mm_camera_obj_t * my_obj = NULL;
   1509     uint32_t chid = get_main_camera_handle(ch_id);
   1510     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1511 
   1512     pthread_mutex_lock(&g_intf_lock);
   1513     if (aux_chid && chid) {
   1514         my_obj = mm_camera_util_get_camera_head(camera_handle);
   1515         if (my_obj) {
   1516             pthread_mutex_lock(&my_obj->muxer_lock);
   1517             pthread_mutex_unlock(&g_intf_lock);
   1518             rc = mm_camera_muxer_cancel_super_buf_request(
   1519                     camera_handle, ch_id, my_obj);
   1520         } else {
   1521             pthread_mutex_unlock(&g_intf_lock);
   1522         }
   1523     } else if (aux_chid) {
   1524         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1525         my_obj = mm_camera_util_get_camera_by_handler(aux_handle);
   1526 
   1527         if(my_obj) {
   1528             pthread_mutex_lock(&my_obj->cam_lock);
   1529             pthread_mutex_unlock(&g_intf_lock);
   1530             rc = mm_camera_cancel_super_buf_request(my_obj, chid);
   1531         } else {
   1532             pthread_mutex_unlock(&g_intf_lock);
   1533         }
   1534     } else if (chid) {
   1535         uint32_t handle = get_main_camera_handle(camera_handle);
   1536         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1537 
   1538         if(my_obj) {
   1539             pthread_mutex_lock(&my_obj->cam_lock);
   1540             pthread_mutex_unlock(&g_intf_lock);
   1541             rc = mm_camera_cancel_super_buf_request(my_obj, chid);
   1542         } else {
   1543             pthread_mutex_unlock(&g_intf_lock);
   1544         }
   1545     }
   1546 
   1547     LOGH("X ch_id = %u rc = %d", ch_id, rc);
   1548     return rc;
   1549 }
   1550 
   1551 /*===========================================================================
   1552  * FUNCTION   : mm_camera_intf_flush_super_buf_queue
   1553  *
   1554  * DESCRIPTION: flush out all frames in the superbuf queue
   1555  *
   1556  * PARAMETERS :
   1557  *   @camera_handle: camera handle
   1558  *   @ch_id        : channel handle
   1559  *   @frame_idx    : frame index
   1560  *
   1561  * RETURN     : int32_t type of status
   1562  *              0  -- success
   1563  *              -1 -- failure
   1564  *==========================================================================*/
   1565 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
   1566                                                     uint32_t ch_id, uint32_t frame_idx)
   1567 {
   1568     int32_t rc = -1;
   1569     mm_camera_obj_t * my_obj = NULL;
   1570     uint32_t chid = get_main_camera_handle(ch_id);
   1571     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1572 
   1573     LOGD("E camera_handler = %d,ch_id = %d",
   1574           camera_handle, ch_id);
   1575     if (chid) {
   1576         pthread_mutex_lock(&g_intf_lock);
   1577         uint32_t handle = get_main_camera_handle(camera_handle);
   1578         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1579         if(my_obj) {
   1580             pthread_mutex_lock(&my_obj->cam_lock);
   1581             pthread_mutex_unlock(&g_intf_lock);
   1582             rc = mm_camera_flush_super_buf_queue(my_obj, chid, frame_idx);
   1583         } else {
   1584             pthread_mutex_unlock(&g_intf_lock);
   1585         }
   1586     }
   1587 
   1588     if (aux_chid) {
   1589         pthread_mutex_lock(&g_intf_lock);
   1590         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1591         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1592         if (my_obj) {
   1593             pthread_mutex_lock(&my_obj->muxer_lock);
   1594             pthread_mutex_unlock(&g_intf_lock);
   1595             rc = mm_camera_muxer_flush_super_buf_queue(aux_handle,
   1596                     aux_chid, frame_idx, my_obj);
   1597         } else {
   1598             pthread_mutex_unlock(&g_intf_lock);
   1599         }
   1600     }
   1601 
   1602     LOGH("X ch_id = %u rc = %d", ch_id, rc);
   1603     return rc;
   1604 }
   1605 
   1606 /*===========================================================================
   1607  * FUNCTION   : mm_camera_intf_start_zsl_snapshot
   1608  *
   1609  * DESCRIPTION: Starts zsl snapshot
   1610  *
   1611  * PARAMETERS :
   1612  *   @camera_handle: camera handle
   1613  *   @ch_id        : channel handle
   1614  *
   1615  * RETURN     : int32_t type of status
   1616  *              0  -- success
   1617  *              -1 -- failure
   1618  *==========================================================================*/
   1619 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
   1620         uint32_t ch_id)
   1621 {
   1622     int32_t rc = -1;
   1623     mm_camera_obj_t *my_obj = NULL;
   1624     uint32_t m_chid = get_main_camera_handle(ch_id);
   1625     uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
   1626 
   1627     LOGD("E camera_handler = %d,ch_id = %d",
   1628           camera_handle, ch_id);
   1629 
   1630     if (aux_ch_id) {
   1631         pthread_mutex_lock(&g_intf_lock);
   1632         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1633         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1634         if(my_obj) {
   1635             pthread_mutex_lock(&my_obj->muxer_lock);
   1636             pthread_mutex_unlock(&g_intf_lock);
   1637             rc = mm_camera_muxer_start_zsl_snapshot(aux_handle,
   1638                     aux_ch_id, my_obj);
   1639         } else {
   1640             pthread_mutex_unlock(&g_intf_lock);
   1641         }
   1642     }
   1643 
   1644     if (m_chid) {
   1645         uint32_t m_handle = get_main_camera_handle(camera_handle);
   1646         pthread_mutex_lock(&g_intf_lock);
   1647         my_obj = mm_camera_util_get_camera_by_handler(m_handle);
   1648         if(my_obj) {
   1649             pthread_mutex_lock(&my_obj->cam_lock);
   1650             pthread_mutex_unlock(&g_intf_lock);
   1651             rc = mm_camera_start_zsl_snapshot_ch(my_obj, m_chid);
   1652         } else {
   1653             pthread_mutex_unlock(&g_intf_lock);
   1654         }
   1655     }
   1656     LOGD("X rc = %d", rc);
   1657     return rc;
   1658 }
   1659 
   1660 /*===========================================================================
   1661  * FUNCTION   : mm_camera_intf_stop_zsl_snapshot
   1662  *
   1663  * DESCRIPTION: Stops zsl snapshot
   1664  *
   1665  * PARAMETERS :
   1666  *   @camera_handle: camera handle
   1667  *   @ch_id        : channel handle
   1668  *
   1669  * RETURN     : int32_t type of status
   1670  *              0  -- success
   1671  *              -1 -- failure
   1672  *==========================================================================*/
   1673 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
   1674         uint32_t ch_id)
   1675 {
   1676     int32_t rc = -1;
   1677     mm_camera_obj_t * my_obj = NULL;
   1678     uint32_t m_chid = get_main_camera_handle(ch_id);
   1679     uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
   1680 
   1681     LOGD("E camera_handler = %d,ch_id = %d",
   1682           camera_handle, ch_id);
   1683 
   1684     if (aux_ch_id) {
   1685         pthread_mutex_lock(&g_intf_lock);
   1686         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1687         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1688         if(my_obj) {
   1689             pthread_mutex_lock(&my_obj->muxer_lock);
   1690             pthread_mutex_unlock(&g_intf_lock);
   1691             rc = mm_camera_muxer_stop_zsl_snapshot(aux_handle, aux_ch_id, my_obj);
   1692         } else {
   1693             pthread_mutex_unlock(&g_intf_lock);
   1694         }
   1695     }
   1696 
   1697     if (ch_id) {
   1698         pthread_mutex_lock(&g_intf_lock);
   1699         uint32_t handle = get_main_camera_handle(camera_handle);
   1700         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1701         if(my_obj) {
   1702             pthread_mutex_lock(&my_obj->cam_lock);
   1703             pthread_mutex_unlock(&g_intf_lock);
   1704             rc = mm_camera_stop_zsl_snapshot_ch(my_obj, m_chid);
   1705         } else {
   1706             pthread_mutex_unlock(&g_intf_lock);
   1707         }
   1708     }
   1709 
   1710     LOGD("X rc = %d", rc);
   1711     return rc;
   1712 }
   1713 
   1714 /*===========================================================================
   1715  * FUNCTION   : mm_camera_intf_configure_notify_mode
   1716  *
   1717  * DESCRIPTION: Configures channel notification mode
   1718  *
   1719  * PARAMETERS :
   1720  *   @camera_handle: camera handle
   1721  *   @ch_id        : channel handle
   1722  *   @notify_mode  : notification mode
   1723  *
   1724  * RETURN     : int32_t type of status
   1725  *              0  -- success
   1726  *              -1 -- failure
   1727  *==========================================================================*/
   1728 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
   1729                                                     uint32_t ch_id,
   1730                                                     mm_camera_super_buf_notify_mode_t notify_mode)
   1731 {
   1732     int32_t rc = -1;
   1733     mm_camera_obj_t * my_obj = NULL;
   1734     uint32_t chid = get_main_camera_handle(ch_id);
   1735     uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
   1736 
   1737     LOGD("E camera_handler = %d,ch_id = %d",
   1738           camera_handle, ch_id);
   1739 
   1740     if (aux_ch_id) {
   1741         pthread_mutex_lock(&g_intf_lock);
   1742         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1743         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1744         if(my_obj) {
   1745             pthread_mutex_lock(&my_obj->muxer_lock);
   1746             pthread_mutex_unlock(&g_intf_lock);
   1747             rc = mm_camera_muxer_configure_notify_mode(aux_handle, aux_ch_id,
   1748                     notify_mode, my_obj);
   1749         } else {
   1750             pthread_mutex_unlock(&g_intf_lock);
   1751         }
   1752     }
   1753 
   1754     if (chid) {
   1755         pthread_mutex_lock(&g_intf_lock);
   1756         uint32_t handle = get_main_camera_handle(camera_handle);
   1757         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1758         if(my_obj) {
   1759             pthread_mutex_lock(&my_obj->cam_lock);
   1760             pthread_mutex_unlock(&g_intf_lock);
   1761             rc = mm_camera_config_channel_notify(my_obj, chid,
   1762                     notify_mode);
   1763         } else {
   1764             pthread_mutex_unlock(&g_intf_lock);
   1765         }
   1766     }
   1767     LOGD("X rc = %d", rc);
   1768     return rc;
   1769 }
   1770 
   1771 /*===========================================================================
   1772  * FUNCTION   : mm_camera_intf_map_buf
   1773  *
   1774  * DESCRIPTION: mapping camera buffer via domain socket to server
   1775  *
   1776  * PARAMETERS :
   1777  *   @camera_handle: camera handle
   1778  *   @buf_type     : type of buffer to be mapped. could be following values:
   1779  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1780  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1781  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1782  *   @fd           : file descriptor of the buffer
   1783  *   @size         : size of the buffer
   1784  *
   1785  * RETURN     : int32_t type of status
   1786  *              0  -- success
   1787  *              -1 -- failure
   1788  *==========================================================================*/
   1789 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
   1790     uint8_t buf_type, int fd, size_t size, void *buffer)
   1791 {
   1792     int32_t rc = -1;
   1793     mm_camera_obj_t *my_obj = NULL;
   1794     uint32_t handle = get_main_camera_handle(camera_handle);
   1795     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1796 
   1797     if (handle) {
   1798         pthread_mutex_lock(&g_intf_lock);
   1799         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1800 
   1801         if(my_obj) {
   1802             pthread_mutex_lock(&my_obj->cam_lock);
   1803             pthread_mutex_unlock(&g_intf_lock);
   1804             rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
   1805         } else {
   1806             pthread_mutex_unlock(&g_intf_lock);
   1807         }
   1808     } else if (aux_handle) {
   1809         pthread_mutex_lock(&g_intf_lock);
   1810         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1811         if(my_obj) {
   1812             pthread_mutex_lock(&my_obj->muxer_lock);
   1813             pthread_mutex_unlock(&g_intf_lock);
   1814             rc = mm_camera_muxer_map_buf(aux_handle, buf_type,
   1815                     fd, size, buffer, my_obj);
   1816         } else {
   1817             pthread_mutex_unlock(&g_intf_lock);
   1818         }
   1819     }
   1820     return rc;
   1821 }
   1822 
   1823 /*===========================================================================
   1824  * FUNCTION   : mm_camera_intf_map_bufs
   1825  *
   1826  * DESCRIPTION: mapping camera buffer via domain socket to server
   1827  *
   1828  * PARAMETERS :
   1829  *   @camera_handle: camera handle
   1830  *   @buf_type     : type of buffer to be mapped. could be following values:
   1831  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1832  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1833  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1834  *
   1835  * RETURN     : int32_t type of status
   1836  *              0  -- success
   1837  *              -1 -- failure
   1838  *==========================================================================*/
   1839 static int32_t mm_camera_intf_map_bufs(uint32_t camera_handle,
   1840         const cam_buf_map_type_list *buf_map_list)
   1841 {
   1842     int32_t rc = -1;
   1843     mm_camera_obj_t * my_obj = NULL;
   1844     uint32_t handle = get_main_camera_handle(camera_handle);
   1845     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1846 
   1847     if (handle) {
   1848         pthread_mutex_lock(&g_intf_lock);
   1849         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1850         if(my_obj) {
   1851             pthread_mutex_lock(&my_obj->cam_lock);
   1852             pthread_mutex_unlock(&g_intf_lock);
   1853             rc = mm_camera_map_bufs(my_obj, buf_map_list);
   1854         } else {
   1855             pthread_mutex_unlock(&g_intf_lock);
   1856         }
   1857     } else if (aux_handle) {
   1858         pthread_mutex_lock(&g_intf_lock);
   1859         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1860         if(my_obj) {
   1861             pthread_mutex_lock(&my_obj->muxer_lock);
   1862             pthread_mutex_unlock(&g_intf_lock);
   1863             rc = mm_camera_muxer_map_bufs(aux_handle, buf_map_list, my_obj);
   1864         } else {
   1865             pthread_mutex_unlock(&g_intf_lock);
   1866         }
   1867     }
   1868     return rc;
   1869 }
   1870 
   1871 /*===========================================================================
   1872  * FUNCTION   : mm_camera_intf_unmap_buf
   1873  *
   1874  * DESCRIPTION: unmapping camera buffer via domain socket to server
   1875  *
   1876  * PARAMETERS :
   1877  *   @camera_handle: camera handle
   1878  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1879  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1880  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1881  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1882  *
   1883  * RETURN     : int32_t type of status
   1884  *              0  -- success
   1885  *              -1 -- failure
   1886  *==========================================================================*/
   1887 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
   1888                                         uint8_t buf_type)
   1889 {
   1890     int32_t rc = -1;
   1891     mm_camera_obj_t * my_obj = NULL;
   1892     uint32_t handle = get_main_camera_handle(camera_handle);
   1893     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1894 
   1895     if (handle) {
   1896         pthread_mutex_lock(&g_intf_lock);
   1897         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1898 
   1899         if(my_obj) {
   1900             pthread_mutex_lock(&my_obj->cam_lock);
   1901             pthread_mutex_unlock(&g_intf_lock);
   1902             rc = mm_camera_unmap_buf(my_obj, buf_type);
   1903         } else {
   1904             pthread_mutex_unlock(&g_intf_lock);
   1905         }
   1906     }
   1907 
   1908     if (aux_handle) {
   1909         pthread_mutex_lock(&g_intf_lock);
   1910         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1911         if(my_obj) {
   1912             pthread_mutex_lock(&my_obj->muxer_lock);
   1913             pthread_mutex_unlock(&g_intf_lock);
   1914             rc = mm_camera_muxer_unmap_buf(aux_handle, buf_type, my_obj);
   1915         } else {
   1916             pthread_mutex_unlock(&g_intf_lock);
   1917         }
   1918     }
   1919     return rc;
   1920 }
   1921 
   1922 /*===========================================================================
   1923  * FUNCTION   : mm_camera_intf_set_stream_parms
   1924  *
   1925  * DESCRIPTION: set parameters per stream
   1926  *
   1927  * PARAMETERS :
   1928  *   @camera_handle: camera handle
   1929  *   @ch_id        : channel handle
   1930  *   @s_id         : stream handle
   1931  *   @parms        : ptr to a param struct to be set to server
   1932  *
   1933  * RETURN     : int32_t type of status
   1934  *              0  -- success
   1935  *              -1 -- failure
   1936  * NOTE       : Assume the parms struct buf is already mapped to server via
   1937  *              domain socket. Corresponding fields of parameters to be set
   1938  *              are already filled in by upper layer caller.
   1939  *==========================================================================*/
   1940 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
   1941                                                uint32_t ch_id,
   1942                                                uint32_t s_id,
   1943                                                cam_stream_parm_buffer_t *parms)
   1944 {
   1945     int32_t rc = -1;
   1946     mm_camera_obj_t * my_obj = NULL;
   1947     uint32_t strid = get_main_camera_handle(s_id);
   1948     uint32_t aux_strid = get_aux_camera_handle(s_id);
   1949 
   1950     LOGD("E camera_handle = %d,ch_id = %d,s_id = %d",
   1951           camera_handle, ch_id, s_id);
   1952     if (strid) {
   1953         pthread_mutex_lock(&g_intf_lock);
   1954         uint32_t handle = get_main_camera_handle(camera_handle);
   1955         uint32_t chid = get_main_camera_handle(ch_id);
   1956 
   1957         my_obj = mm_camera_util_get_camera_by_handler(handle);
   1958         if(my_obj) {
   1959             pthread_mutex_lock(&my_obj->cam_lock);
   1960             pthread_mutex_unlock(&g_intf_lock);
   1961             rc = mm_camera_set_stream_parms(my_obj, chid, strid, parms);
   1962         } else {
   1963             pthread_mutex_unlock(&g_intf_lock);
   1964         }
   1965     }
   1966 
   1967     if (aux_strid) {
   1968         pthread_mutex_lock(&g_intf_lock);
   1969         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1970         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   1971         my_obj = mm_camera_util_get_camera_head(aux_handle);
   1972 
   1973         if (my_obj) {
   1974             pthread_mutex_lock(&my_obj->muxer_lock);
   1975             pthread_mutex_unlock(&g_intf_lock);
   1976             rc = mm_camera_muxer_set_stream_parms(aux_handle, aux_chid,
   1977                     aux_strid, parms, my_obj);
   1978         } else {
   1979             pthread_mutex_unlock(&g_intf_lock);
   1980         }
   1981     }
   1982     LOGD("X rc = %d", rc);
   1983     return rc;
   1984 }
   1985 
   1986 /*===========================================================================
   1987  * FUNCTION   : mm_camera_intf_get_stream_parms
   1988  *
   1989  * DESCRIPTION: get parameters per stream
   1990  *
   1991  * PARAMETERS :
   1992  *   @camera_handle: camera handle
   1993  *   @ch_id        : channel handle
   1994  *   @s_id         : stream handle
   1995  *   @parms        : ptr to a param struct to be get from server
   1996  *
   1997  * RETURN     : int32_t type of status
   1998  *              0  -- success
   1999  *              -1 -- failure
   2000  * NOTE       : Assume the parms struct buf is already mapped to server via
   2001  *              domain socket. Parameters to be get from server are already
   2002  *              filled in by upper layer caller. After this call, corresponding
   2003  *              fields of requested parameters will be filled in by server with
   2004  *              detailed information.
   2005  *==========================================================================*/
   2006 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
   2007                                                uint32_t ch_id,
   2008                                                uint32_t s_id,
   2009                                                cam_stream_parm_buffer_t *parms)
   2010 {
   2011     int32_t rc = -1;
   2012     mm_camera_obj_t * my_obj = NULL;
   2013     uint32_t strid = get_main_camera_handle(s_id);
   2014     uint32_t aux_strid = get_aux_camera_handle(s_id);
   2015 
   2016     LOGD("E camera_handle = %d,ch_id = %d,s_id = %d",
   2017           camera_handle, ch_id, s_id);
   2018     if (strid) {
   2019         pthread_mutex_lock(&g_intf_lock);
   2020         uint32_t handle = get_main_camera_handle(camera_handle);
   2021         uint32_t chid = get_main_camera_handle(ch_id);
   2022 
   2023         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2024         if(my_obj) {
   2025             pthread_mutex_lock(&my_obj->cam_lock);
   2026             pthread_mutex_unlock(&g_intf_lock);
   2027             rc = mm_camera_get_stream_parms(my_obj, chid, strid, parms);
   2028         } else {
   2029             pthread_mutex_unlock(&g_intf_lock);
   2030         }
   2031     }
   2032 
   2033     if (aux_strid) {
   2034         pthread_mutex_lock(&g_intf_lock);
   2035         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2036         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   2037 
   2038         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2039         if (my_obj) {
   2040             pthread_mutex_lock(&my_obj->muxer_lock);
   2041             pthread_mutex_unlock(&g_intf_lock);
   2042             rc = mm_camera_muxer_get_stream_parms(aux_handle, aux_chid,
   2043                     aux_strid, parms, my_obj);
   2044         } else {
   2045             pthread_mutex_unlock(&g_intf_lock);
   2046         }
   2047     }
   2048     LOGD("X rc = %d", rc);
   2049     return rc;
   2050 }
   2051 
   2052 /*===========================================================================
   2053  * FUNCTION   : mm_camera_intf_map_stream_buf
   2054  *
   2055  * DESCRIPTION: mapping stream buffer via domain socket to server
   2056  *
   2057  * PARAMETERS :
   2058  *   @camera_handle: camera handle
   2059  *   @ch_id        : channel handle
   2060  *   @s_id         : stream handle
   2061  *   @buf_type     : type of buffer to be mapped. could be following values:
   2062  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   2063  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   2064  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2065  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   2066  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2067  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2068  *   @plane_idx    : plane index. If all planes share the same fd,
   2069  *                   plane_idx = -1; otherwise, plean_idx is the
   2070  *                   index to plane (0..num_of_planes)
   2071  *   @fd           : file descriptor of the buffer
   2072  *   @size         : size of the buffer
   2073  *
   2074  * RETURN     : int32_t type of status
   2075  *              0  -- success
   2076  *              -1 -- failure
   2077  *==========================================================================*/
   2078 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
   2079         uint32_t ch_id, uint32_t stream_id, uint8_t buf_type,
   2080         uint32_t buf_idx, int32_t plane_idx, int fd,
   2081         size_t size, void *buffer)
   2082 {
   2083     int32_t rc = -1;
   2084     mm_camera_obj_t * my_obj = NULL;
   2085     uint32_t strid = get_main_camera_handle(stream_id);
   2086     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   2087 
   2088     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   2089             camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   2090 
   2091     if (strid) {
   2092         pthread_mutex_lock(&g_intf_lock);
   2093         uint32_t handle = get_main_camera_handle(camera_handle);
   2094         uint32_t chid = get_main_camera_handle(ch_id);
   2095         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2096 
   2097         if(my_obj) {
   2098             pthread_mutex_lock(&my_obj->cam_lock);
   2099             pthread_mutex_unlock(&g_intf_lock);
   2100             rc = mm_camera_map_stream_buf(my_obj, chid, strid,
   2101                     buf_type, buf_idx, plane_idx,
   2102                     fd, size, buffer);
   2103         } else {
   2104             pthread_mutex_unlock(&g_intf_lock);
   2105         }
   2106     }
   2107 
   2108     if (aux_strid) {
   2109         pthread_mutex_lock(&g_intf_lock);
   2110         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2111         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   2112         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2113         if (my_obj) {
   2114             pthread_mutex_lock(&my_obj->muxer_lock);
   2115             pthread_mutex_unlock(&g_intf_lock);
   2116             rc = mm_camera_muxer_map_stream_buf(aux_handle, aux_chid,
   2117                     aux_strid, buf_type, buf_idx, plane_idx, fd, size,
   2118                     buffer, my_obj);
   2119         } else {
   2120             pthread_mutex_unlock(&g_intf_lock);
   2121         }
   2122     }
   2123 
   2124     LOGD("X rc = %d", rc);
   2125     return rc;
   2126 }
   2127 
   2128 /*===========================================================================
   2129  * FUNCTION   : mm_camera_intf_map_stream_bufs
   2130  *
   2131  * DESCRIPTION: mapping stream buffers via domain socket to server
   2132  *
   2133  * PARAMETERS :
   2134  *   @camera_handle: camera handle
   2135  *   @ch_id        : channel handle
   2136  *   @buf_map_list : list of buffers to be mapped
   2137  *
   2138  * RETURN     : int32_t type of status
   2139  *              0  -- success
   2140  *              -1 -- failure
   2141  *==========================================================================*/
   2142 static int32_t mm_camera_intf_map_stream_bufs(uint32_t camera_handle,
   2143                                               uint32_t ch_id,
   2144                                               const cam_buf_map_type_list *buf_map_list)
   2145 {
   2146     int32_t rc = -1;
   2147     uint32_t i;
   2148     mm_camera_obj_t * my_obj = NULL;
   2149     cam_buf_map_type_list m_buf_list, aux_buf_list;
   2150 
   2151     LOGD("E camera_handle = %d, ch_id = %d",
   2152           camera_handle, ch_id);
   2153 
   2154     memset(&m_buf_list, 0, sizeof(m_buf_list));
   2155     memset(&aux_buf_list, 0, sizeof(m_buf_list));
   2156     for (i = 0; i < buf_map_list->length; i++) {
   2157         uint32_t strid = get_main_camera_handle(buf_map_list->buf_maps[i].stream_id);
   2158         uint32_t aux_strid = get_aux_camera_handle(buf_map_list->buf_maps[i].stream_id);
   2159         if (strid) {
   2160             m_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i];
   2161             m_buf_list.buf_maps[aux_buf_list.length].stream_id = strid;
   2162             m_buf_list.length++;
   2163         }
   2164         if (aux_strid) {
   2165             aux_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i];
   2166             aux_buf_list.buf_maps[aux_buf_list.length].stream_id = aux_strid;
   2167             aux_buf_list.length++;
   2168         }
   2169     }
   2170 
   2171     if(m_buf_list.length != 0) {
   2172         pthread_mutex_lock(&g_intf_lock);
   2173         uint32_t handle = get_main_camera_handle(camera_handle);
   2174         uint32_t chid = get_main_camera_handle(ch_id);
   2175         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2176         if(my_obj) {
   2177             pthread_mutex_lock(&my_obj->cam_lock);
   2178             pthread_mutex_unlock(&g_intf_lock);
   2179             rc = mm_camera_map_stream_bufs(my_obj, chid, &m_buf_list);
   2180         }else{
   2181             pthread_mutex_unlock(&g_intf_lock);
   2182         }
   2183     }
   2184 
   2185     if(aux_buf_list.length != 0) {
   2186         pthread_mutex_lock(&g_intf_lock);
   2187         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2188         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   2189         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2190         if (my_obj != NULL) {
   2191             pthread_mutex_lock(&my_obj->muxer_lock);
   2192             pthread_mutex_unlock(&g_intf_lock);
   2193             rc = mm_camera_muxer_map_stream_bufs(aux_handle,aux_chid,
   2194                     &aux_buf_list, my_obj);
   2195         } else {
   2196             pthread_mutex_unlock(&g_intf_lock);
   2197         }
   2198     }
   2199     LOGD("X rc = %d", rc);
   2200     return rc;
   2201 }
   2202 
   2203 /*===========================================================================
   2204  * FUNCTION   : mm_camera_intf_unmap_stream_buf
   2205  *
   2206  * DESCRIPTION: unmapping stream buffer via domain socket to server
   2207  *
   2208  * PARAMETERS :
   2209  *   @camera_handle: camera handle
   2210  *   @ch_id        : channel handle
   2211  *   @s_id         : stream handle
   2212  *   @buf_type     : type of buffer to be unmapped. could be following values:
   2213  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   2214  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   2215  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2216  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   2217  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2218  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2219  *   @plane_idx    : plane index. If all planes share the same fd,
   2220  *                   plane_idx = -1; otherwise, plean_idx is the
   2221  *                   index to plane (0..num_of_planes)
   2222  *
   2223  * RETURN     : int32_t type of status
   2224  *              0  -- success
   2225  *              -1 -- failure
   2226  *==========================================================================*/
   2227 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
   2228                                                uint32_t ch_id,
   2229                                                uint32_t stream_id,
   2230                                                uint8_t buf_type,
   2231                                                uint32_t buf_idx,
   2232                                                int32_t plane_idx)
   2233 {
   2234     int32_t rc = -1;
   2235     mm_camera_obj_t * my_obj = NULL;
   2236     uint32_t strid = get_main_camera_handle(stream_id);
   2237     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   2238 
   2239 
   2240     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   2241               camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   2242 
   2243     if (aux_strid) {
   2244         pthread_mutex_lock(&g_intf_lock);
   2245         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2246         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   2247         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2248         if (my_obj) {
   2249             pthread_mutex_lock(&my_obj->muxer_lock);
   2250             pthread_mutex_unlock(&g_intf_lock);
   2251             rc = mm_camera_muxer_unmap_stream_buf(aux_handle, aux_chid,
   2252                    aux_strid, buf_type, buf_idx,
   2253                    plane_idx, my_obj);
   2254         } else {
   2255             pthread_mutex_unlock(&g_intf_lock);
   2256         }
   2257     }
   2258 
   2259     if (strid) {
   2260         pthread_mutex_lock(&g_intf_lock);
   2261         uint32_t handle = get_main_camera_handle(camera_handle);
   2262         uint32_t chid = get_main_camera_handle(ch_id);
   2263         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2264         if(my_obj) {
   2265             pthread_mutex_lock(&my_obj->cam_lock);
   2266             pthread_mutex_unlock(&g_intf_lock);
   2267             rc = mm_camera_unmap_stream_buf(my_obj, chid, strid,
   2268                     buf_type, buf_idx, plane_idx);
   2269         }else{
   2270             pthread_mutex_unlock(&g_intf_lock);
   2271         }
   2272     }
   2273 
   2274     LOGD("X rc = %d", rc);
   2275     return rc;
   2276 }
   2277 
   2278 /*===========================================================================
   2279  * FUNCTION   : mm_camera_intf_get_session_id
   2280  *
   2281  * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
   2282  *
   2283  * PARAMETERS :
   2284  *   @camera_handle: camera handle
   2285  *   @sessionid: session id to be retrieved from server
   2286  *
   2287  * RETURN     : int32_t type of status
   2288  *              0  -- success
   2289  *              -1 -- failure
   2290  * NOTE       : if this call succeeds, we will get a valid session id.
   2291  *==========================================================================*/
   2292 static int32_t mm_camera_intf_get_session_id(uint32_t camera_handle,
   2293                                                        uint32_t* sessionid)
   2294 {
   2295     int32_t rc = -1;
   2296     mm_camera_obj_t * my_obj = NULL;
   2297     uint32_t handle = get_main_camera_handle(camera_handle);
   2298     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2299 
   2300     if (handle) {
   2301         pthread_mutex_lock(&g_intf_lock);
   2302         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2303 
   2304         if(my_obj) {
   2305             pthread_mutex_lock(&my_obj->cam_lock);
   2306             pthread_mutex_unlock(&g_intf_lock);
   2307             *sessionid = my_obj->sessionid;
   2308             pthread_mutex_unlock(&my_obj->cam_lock);
   2309             rc = 0;
   2310         } else {
   2311             pthread_mutex_unlock(&g_intf_lock);
   2312         }
   2313     } else if (aux_handle){
   2314         pthread_mutex_lock(&g_intf_lock);
   2315         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2316         if (my_obj) {
   2317             pthread_mutex_lock(&my_obj->muxer_lock);
   2318             pthread_mutex_unlock(&g_intf_lock);
   2319             rc = mm_camera_muxer_get_session_id(aux_handle, sessionid, my_obj);
   2320         } else {
   2321             pthread_mutex_unlock(&g_intf_lock);
   2322         }
   2323     }
   2324     return rc;
   2325 }
   2326 
   2327 /*===========================================================================
   2328  * FUNCTION   : mm_camera_intf_set_dual_cam_cmd
   2329  *
   2330  * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
   2331  *
   2332  * PARAMETERS :
   2333  *   @camera_handle: camera handle
   2334  *   @related_cam_info: pointer to the related cam info to be sent to the server
   2335  *
   2336  * RETURN     : int32_t type of status
   2337  *              0  -- success
   2338  *              -1 -- failure
   2339  * NOTE       : if this call succeeds, we will get linking established in back end
   2340  *==========================================================================*/
   2341 static int32_t mm_camera_intf_set_dual_cam_cmd(uint32_t camera_handle)
   2342 {
   2343     int32_t rc = -1;
   2344     mm_camera_obj_t * my_obj = NULL;
   2345     uint32_t handle = get_main_camera_handle(camera_handle);
   2346     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2347 
   2348     if (handle) {
   2349         pthread_mutex_lock(&g_intf_lock);
   2350         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2351 
   2352         if(my_obj) {
   2353             pthread_mutex_lock(&my_obj->cam_lock);
   2354             pthread_mutex_unlock(&g_intf_lock);
   2355             rc = mm_camera_set_dual_cam_cmd(my_obj);
   2356         } else {
   2357             pthread_mutex_unlock(&g_intf_lock);
   2358         }
   2359     }
   2360 
   2361     if (aux_handle) {
   2362         pthread_mutex_lock(&g_intf_lock);
   2363         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2364         if (my_obj) {
   2365             pthread_mutex_lock(&my_obj->muxer_lock);
   2366             pthread_mutex_unlock(&g_intf_lock);
   2367             rc = mm_camera_muxer_set_dual_cam_cmd(
   2368                     aux_handle, my_obj);
   2369         } else {
   2370             pthread_mutex_unlock(&g_intf_lock);
   2371         }
   2372     }
   2373     return rc;
   2374 }
   2375 
   2376 /*===========================================================================
   2377  * FUNCTION   : get_sensor_info
   2378  *
   2379  * DESCRIPTION: get sensor info like facing(back/front) and mount angle
   2380  *
   2381  * PARAMETERS :
   2382  *
   2383  * RETURN     :
   2384  *==========================================================================*/
   2385 void get_sensor_info()
   2386 {
   2387     int rc = 0;
   2388     int dev_fd = -1;
   2389     struct media_device_info mdev_info;
   2390     int num_media_devices = 0;
   2391     size_t num_cameras = 0;
   2392 
   2393     LOGD("E");
   2394     while (1) {
   2395         char dev_name[32];
   2396         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   2397         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   2398         if (dev_fd < 0) {
   2399             LOGD("Done discovering media devices\n");
   2400             break;
   2401         }
   2402         num_media_devices++;
   2403         memset(&mdev_info, 0, sizeof(mdev_info));
   2404         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   2405         if (rc < 0) {
   2406             LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno));
   2407             close(dev_fd);
   2408             dev_fd = -1;
   2409             num_cameras = 0;
   2410             break;
   2411         }
   2412 
   2413         if(strncmp(mdev_info.model,  MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
   2414             close(dev_fd);
   2415             dev_fd = -1;
   2416             continue;
   2417         }
   2418 
   2419         unsigned int num_entities = 1;
   2420         while (1) {
   2421             struct media_entity_desc entity;
   2422             uint32_t temp;
   2423             uint32_t mount_angle;
   2424             uint32_t facing;
   2425             int32_t type = 0;
   2426             uint8_t is_yuv;
   2427             uint8_t is_secure;
   2428 
   2429             memset(&entity, 0, sizeof(entity));
   2430             entity.id = num_entities++;
   2431             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   2432             if (rc < 0) {
   2433                 LOGD("Done enumerating media entities\n");
   2434                 rc = 0;
   2435                 break;
   2436             }
   2437             if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
   2438                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
   2439                 temp = entity.flags >> 8;
   2440                 mount_angle = (temp & 0xFF) * 90;
   2441                 facing = ((entity.flags & CAM_SENSOR_FACING_MASK) ?
   2442                         CAMERA_FACING_FRONT:CAMERA_FACING_BACK);
   2443 
   2444                 if (entity.flags & CAM_SENSOR_TYPE_MASK) {
   2445                     type = CAM_TYPE_AUX;
   2446                 } else {
   2447                     type = CAM_TYPE_MAIN;
   2448                 }
   2449 
   2450                 is_yuv = ((entity.flags & CAM_SENSOR_FORMAT_MASK) ?
   2451                         CAM_SENSOR_YUV:CAM_SENSOR_RAW);
   2452                 is_secure = ((entity.flags & CAM_SENSOR_SECURE_MASK) ?
   2453                         CAM_TYPE_SECURE:0);
   2454                 LOGL("index = %u flag = %x mount_angle = %u "
   2455                         "facing = %u type: %u is_yuv = %u\n",
   2456                         (unsigned int)num_cameras, (unsigned int)temp,
   2457                         (unsigned int)mount_angle, (unsigned int)facing,
   2458                         (unsigned int)type, (uint8_t)is_yuv);
   2459                 g_cam_ctrl.info[num_cameras].facing = (int)facing;
   2460                 g_cam_ctrl.info[num_cameras].orientation = (int)mount_angle;
   2461                 g_cam_ctrl.cam_type[num_cameras] = type | is_secure;
   2462                 g_cam_ctrl.is_yuv[num_cameras] = is_yuv;
   2463                 LOGD("dev_info[id=%zu,name='%s', facing = %d, angle = %d type = %d]\n",
   2464                          num_cameras, g_cam_ctrl.video_dev_name[num_cameras],
   2465                          g_cam_ctrl.info[num_cameras].facing,
   2466                          g_cam_ctrl.info[num_cameras].orientation,
   2467                          g_cam_ctrl.cam_type[num_cameras]);
   2468                 num_cameras++;
   2469                 continue;
   2470             }
   2471         }
   2472         close(dev_fd);
   2473         dev_fd = -1;
   2474     }
   2475 
   2476     LOGD("num_cameras=%d\n", g_cam_ctrl.num_cam);
   2477     return;
   2478 }
   2479 
   2480 /*===========================================================================
   2481  * FUNCTION   : sort_camera_info
   2482  *
   2483  * DESCRIPTION: sort camera info to keep back cameras idx is smaller than front cameras idx
   2484  *
   2485  * PARAMETERS : number of cameras
   2486  *
   2487  * RETURN     :
   2488  *==========================================================================*/
   2489 void sort_camera_info(int num_cam)
   2490 {
   2491     int idx = 0, i;
   2492     int8_t is_secure = 0;
   2493     struct camera_info temp_info[MM_CAMERA_MAX_NUM_SENSORS];
   2494     cam_sync_type_t temp_type[MM_CAMERA_MAX_NUM_SENSORS];
   2495     cam_sync_mode_t temp_mode[MM_CAMERA_MAX_NUM_SENSORS];
   2496     uint8_t temp_is_yuv[MM_CAMERA_MAX_NUM_SENSORS];
   2497     char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];
   2498     uint32_t cam_idx[MM_CAMERA_MAX_NUM_SENSORS] = {0};
   2499     uint8_t b_prime_idx = 0, b_aux_idx = 0, f_prime_idx = 0, f_aux_idx = 0;
   2500     int8_t expose_aux = 0;
   2501     char prop[PROPERTY_VALUE_MAX];
   2502 
   2503     memset(temp_info, 0, sizeof(temp_info));
   2504     memset(temp_dev_name, 0, sizeof(temp_dev_name));
   2505     memset(temp_type, 0, sizeof(temp_type));
   2506     memset(temp_mode, 0, sizeof(temp_mode));
   2507     memset(temp_is_yuv, 0, sizeof(temp_is_yuv));
   2508 
   2509     memset(prop, 0, sizeof(prop));
   2510     property_get("persist.camera.expose.aux", prop, "0");
   2511     expose_aux = atoi(prop);
   2512 
   2513     /* Order of the camera exposed is
   2514         0  - Back Main Camera
   2515         1  - Front Main Camera
   2516         ++  - Back Aux Camera
   2517         ++  - Front Aux Camera
   2518         ++  - Back Main + Back Aux camera
   2519         ++  - Front Main + Front Aux camera
   2520         ++  - Secure Camera
   2521        */
   2522     for (i = 0; i < num_cam; i++) {
   2523         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
   2524             (g_cam_ctrl.cam_type[i] == CAM_TYPE_MAIN)) {
   2525             temp_info[idx] = g_cam_ctrl.info[i];
   2526             temp_type[idx] = CAM_TYPE_MAIN;
   2527             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2528             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2529             cam_idx[idx] = idx;
   2530             b_prime_idx = idx;
   2531             LOGH("Found Back Main Camera: i: %d idx: %d", i, idx);
   2532             memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
   2533                 MM_CAMERA_DEV_NAME_LEN);
   2534             idx++;
   2535         }
   2536     }
   2537 
   2538     for (i = 0; i < num_cam; i++) {
   2539         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
   2540             (g_cam_ctrl.cam_type[i] == CAM_TYPE_MAIN)) {
   2541             temp_info[idx] = g_cam_ctrl.info[i];
   2542             temp_type[idx] = CAM_TYPE_MAIN;
   2543             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2544             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2545             cam_idx[idx] = idx;
   2546             f_prime_idx = idx;
   2547             LOGH("Found Front Main Camera: i: %d idx: %d", i, idx);
   2548             memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
   2549                 MM_CAMERA_DEV_NAME_LEN);
   2550             idx++;
   2551         }
   2552     }
   2553 
   2554     for (i = 0; i < num_cam; i++) {
   2555         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
   2556             (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
   2557             && expose_aux) {
   2558             temp_info[idx] = g_cam_ctrl.info[i];
   2559             temp_type[idx] = CAM_TYPE_MAIN;
   2560             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2561             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2562             cam_idx[idx] = idx;
   2563             b_aux_idx = idx;
   2564             LOGH("Found Back Aux Camera: i: %d idx: %d", i, idx);
   2565             memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
   2566                 MM_CAMERA_DEV_NAME_LEN);
   2567             idx++;
   2568         }
   2569     }
   2570 
   2571     for (i = 0; i < num_cam; i++) {
   2572         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
   2573             (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
   2574             && expose_aux) {
   2575             temp_info[idx] = g_cam_ctrl.info[i];
   2576             temp_type[idx] = CAM_TYPE_MAIN;
   2577             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2578             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2579             cam_idx[idx] = idx;
   2580             f_aux_idx = idx;
   2581             LOGH("Found front Aux Camera: i: %d idx: %d", i, idx);
   2582             memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
   2583                 MM_CAMERA_DEV_NAME_LEN);
   2584             idx++;
   2585         }
   2586     }
   2587 
   2588     for (i = 0; i < num_cam; i++) {
   2589         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
   2590             (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
   2591             && expose_aux) { // Need Main check here after sensor change
   2592             temp_info[idx] = g_cam_ctrl.info[i];
   2593             temp_type[idx] = CAM_TYPE_MAIN | CAM_TYPE_AUX;
   2594             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2595             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2596             cam_idx[idx] = (b_aux_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | b_prime_idx;
   2597             LOGH("Found Back Main+AUX Camera: i: %d idx: %d", i, idx);
   2598             memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
   2599                 MM_CAMERA_DEV_NAME_LEN);
   2600             idx++;
   2601         }
   2602     }
   2603 
   2604     for (i = 0; i < num_cam; i++) {
   2605         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
   2606             (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
   2607             &&expose_aux) { // Need Main check here after sensor change
   2608             temp_info[idx] = g_cam_ctrl.info[i];
   2609             temp_type[idx] = CAM_TYPE_MAIN | CAM_TYPE_AUX;
   2610             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2611             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2612             cam_idx[idx] = (f_aux_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | f_prime_idx;
   2613             LOGH("Found Back Main Camera: i: %d idx: %d", i, idx);
   2614             memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
   2615                 MM_CAMERA_DEV_NAME_LEN);
   2616             idx++;
   2617         }
   2618     }
   2619 
   2620    /*secure camera*/
   2621    for (i = 0; i < num_cam; i++) {
   2622        if (g_cam_ctrl.cam_type[i] & CAM_TYPE_SECURE) {
   2623            temp_info[idx] = g_cam_ctrl.info[i];
   2624            temp_type[idx] = g_cam_ctrl.cam_type[i];
   2625            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
   2626            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
   2627            LOGD("Found Secure Camera: i: %d idx: %d", i, idx);
   2628            memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
   2629                MM_CAMERA_DEV_NAME_LEN);
   2630            is_secure++;
   2631        }
   2632    }
   2633 
   2634     /*NOTE: Add logic here to modify cameraID again here*/
   2635 
   2636     if (idx != 0) {
   2637         memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info));
   2638         memcpy(g_cam_ctrl.cam_type, temp_type, sizeof(temp_type));
   2639         memcpy(g_cam_ctrl.cam_mode, temp_mode, sizeof(temp_mode));
   2640         memcpy(g_cam_ctrl.is_yuv, temp_is_yuv, sizeof(temp_is_yuv));
   2641         memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name));
   2642         memcpy(g_cam_ctrl.cam_index, cam_idx, (sizeof(uint32_t) * MM_CAMERA_MAX_NUM_SENSORS));
   2643         //Set num cam based on the cameras exposed finally via dual/aux properties.
   2644         g_cam_ctrl.num_cam = idx;
   2645         for (i = 0; i < idx; i++) {
   2646             LOGI("Camera id: %d facing: %d, type: %d is_yuv: %d",
   2647                 i, g_cam_ctrl.info[i].facing, g_cam_ctrl.cam_type[i], g_cam_ctrl.is_yuv[i]);
   2648         }
   2649 
   2650         //control camera exposing here.
   2651         g_cam_ctrl.num_cam_to_expose = g_cam_ctrl.num_cam - is_secure;
   2652     }
   2653     LOGI("Number of cameras %d sorted %d", num_cam, idx);
   2654     return;
   2655 }
   2656 
   2657 /*===========================================================================
   2658  * FUNCTION   : get_num_of_cameras
   2659  *
   2660  * DESCRIPTION: get number of cameras
   2661  *
   2662  * PARAMETERS :
   2663  *
   2664  * RETURN     : number of cameras supported
   2665  *==========================================================================*/
   2666 uint8_t get_num_of_cameras()
   2667 {
   2668     int rc = 0;
   2669     int dev_fd = -1;
   2670     struct media_device_info mdev_info;
   2671     int num_media_devices = 0;
   2672     int8_t num_cameras = 0;
   2673     char subdev_name[32];
   2674     char prop[PROPERTY_VALUE_MAX];
   2675 #ifdef DAEMON_PRESENT
   2676     int32_t sd_fd = -1;
   2677     struct sensor_init_cfg_data cfg;
   2678 #endif
   2679 
   2680     LOGD("E");
   2681 
   2682     property_get("vold.decrypt", prop, "0");
   2683     int decrypt = atoi(prop);
   2684     if (decrypt == 1)
   2685      return 0;
   2686     pthread_mutex_lock(&g_intf_lock);
   2687 
   2688     memset (&g_cam_ctrl, 0, sizeof (g_cam_ctrl));
   2689 #ifndef DAEMON_PRESENT
   2690     if (mm_camera_load_shim_lib() < 0) {
   2691         LOGE ("Failed to module shim library");
   2692         return 0;
   2693     }
   2694 #endif /* DAEMON_PRESENT */
   2695 
   2696     while (1) {
   2697         uint32_t num_entities = 1U;
   2698         char dev_name[32];
   2699 
   2700         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   2701         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   2702         if (dev_fd < 0) {
   2703             LOGD("Done discovering media devices\n");
   2704             break;
   2705         }
   2706         num_media_devices++;
   2707         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   2708         if (rc < 0) {
   2709             LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno));
   2710             close(dev_fd);
   2711             dev_fd = -1;
   2712             break;
   2713         }
   2714 
   2715         if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
   2716           sizeof(mdev_info.model)) != 0) {
   2717             close(dev_fd);
   2718             dev_fd = -1;
   2719             continue;
   2720         }
   2721 
   2722         while (1) {
   2723             struct media_entity_desc entity;
   2724             memset(&entity, 0, sizeof(entity));
   2725             entity.id = num_entities++;
   2726             LOGD("entity id %d", entity.id);
   2727             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   2728             if (rc < 0) {
   2729                 LOGD("Done enumerating media entities");
   2730                 rc = 0;
   2731                 break;
   2732             }
   2733             LOGD("entity name %s type %d group id %d",
   2734                 entity.name, entity.type, entity.group_id);
   2735             if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
   2736                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
   2737                 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
   2738                 break;
   2739             }
   2740         }
   2741         close(dev_fd);
   2742         dev_fd = -1;
   2743     }
   2744 
   2745 #ifdef DAEMON_PRESENT
   2746     /* Open sensor_init subdev */
   2747     sd_fd = open(subdev_name, O_RDWR);
   2748     if (sd_fd < 0) {
   2749         LOGE("Open sensor_init subdev failed");
   2750         return FALSE;
   2751     }
   2752 
   2753     cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
   2754     cfg.cfg.setting = NULL;
   2755     if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
   2756         LOGE("failed");
   2757     }
   2758     close(sd_fd);
   2759 #endif
   2760 
   2761     num_media_devices = 0;
   2762     while (1) {
   2763         uint32_t num_entities = 1U;
   2764         char dev_name[32];
   2765 
   2766         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   2767         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   2768         if (dev_fd < 0) {
   2769             LOGD("Done discovering media devices: %s\n", strerror(errno));
   2770             break;
   2771         }
   2772         num_media_devices++;
   2773         memset(&mdev_info, 0, sizeof(mdev_info));
   2774         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   2775         if (rc < 0) {
   2776             LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno));
   2777             close(dev_fd);
   2778             dev_fd = -1;
   2779             num_cameras = 0;
   2780             break;
   2781         }
   2782 
   2783         if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
   2784             close(dev_fd);
   2785             dev_fd = -1;
   2786             continue;
   2787         }
   2788 
   2789         while (1) {
   2790             struct media_entity_desc entity;
   2791             memset(&entity, 0, sizeof(entity));
   2792             entity.id = num_entities++;
   2793             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   2794             if (rc < 0) {
   2795                 LOGD("Done enumerating media entities\n");
   2796                 rc = 0;
   2797                 break;
   2798             }
   2799             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
   2800                 strlcpy(g_cam_ctrl.video_dev_name[num_cameras],
   2801                      entity.name, sizeof(entity.name));
   2802                 LOGI("dev_info[id=%d,name='%s']\n",
   2803                     (int)num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
   2804                 num_cameras++;
   2805                 break;
   2806             }
   2807         }
   2808         close(dev_fd);
   2809         dev_fd = -1;
   2810         if (num_cameras >= MM_CAMERA_MAX_NUM_SENSORS) {
   2811             LOGW("Maximum number of camera reached %d", num_cameras);
   2812             break;
   2813         }
   2814     }
   2815     g_cam_ctrl.num_cam = num_cameras;
   2816 
   2817     get_sensor_info();
   2818     sort_camera_info(g_cam_ctrl.num_cam);
   2819     /* unlock the mutex */
   2820     pthread_mutex_unlock(&g_intf_lock);
   2821     LOGI("num_cameras=%d\n", (int)g_cam_ctrl.num_cam);
   2822     return(uint8_t)g_cam_ctrl.num_cam;
   2823 }
   2824 
   2825 /*===========================================================================
   2826  * FUNCTION   : get_num_of_cameras_to_expose
   2827  *
   2828  * DESCRIPTION: get number of cameras to expose
   2829  *
   2830  * PARAMETERS :
   2831  *
   2832  * RETURN     : number of cameras to expose to application
   2833  *==========================================================================*/
   2834 uint8_t get_num_of_cameras_to_expose()
   2835 {
   2836     if (g_cam_ctrl.num_cam == 0) {
   2837         get_num_of_cameras();
   2838     }
   2839     return g_cam_ctrl.num_cam_to_expose;
   2840 }
   2841 
   2842 /*===========================================================================
   2843  * FUNCTION   : mm_camera_intf_process_advanced_capture
   2844  *
   2845  * DESCRIPTION: Configures channel advanced capture mode
   2846  *
   2847  * PARAMETERS :
   2848  *   @camera_handle: camera handle
   2849  *   @type : advanced capture type
   2850  *   @ch_id        : channel handle
   2851  *   @trigger  : 1 for start and 0 for cancel/stop
   2852  *   @value  : input capture configaration
   2853  *
   2854  * RETURN     : int32_t type of status
   2855  *              0  -- success
   2856  *              -1 -- failure
   2857  *==========================================================================*/
   2858 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
   2859         uint32_t ch_id, mm_camera_advanced_capture_t type,
   2860         int8_t trigger, void *in_value)
   2861 {
   2862     int32_t rc = -1;
   2863     mm_camera_obj_t * my_obj = NULL;
   2864     uint32_t chid = get_main_camera_handle(ch_id);
   2865     uint32_t aux_chid = get_aux_camera_handle(ch_id);
   2866 
   2867     LOGD("E camera_handler = %d,ch_id = %d",
   2868           camera_handle, ch_id);
   2869 
   2870     if (chid) {
   2871         pthread_mutex_lock(&g_intf_lock);
   2872         uint32_t handle = get_main_camera_handle(camera_handle);
   2873         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2874 
   2875         if(my_obj) {
   2876             pthread_mutex_lock(&my_obj->cam_lock);
   2877             pthread_mutex_unlock(&g_intf_lock);
   2878             rc = mm_camera_channel_advanced_capture(my_obj, chid, type,
   2879                     (uint32_t)trigger, in_value);
   2880         } else {
   2881             pthread_mutex_unlock(&g_intf_lock);
   2882         }
   2883     }
   2884 
   2885     if (aux_chid) {
   2886         pthread_mutex_lock(&g_intf_lock);
   2887         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2888         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2889         if (my_obj) {
   2890             pthread_mutex_lock(&my_obj->muxer_lock);
   2891             pthread_mutex_unlock(&g_intf_lock);
   2892             rc = mm_camera_muxer_process_advanced_capture(aux_handle,
   2893                     aux_chid, type, (uint32_t)trigger, in_value, my_obj);
   2894         } else {
   2895             pthread_mutex_unlock(&g_intf_lock);
   2896         }
   2897     }
   2898     LOGH("X rc = %d ch_id = %u", rc, ch_id);
   2899     return rc;
   2900 }
   2901 
   2902 /*===========================================================================
   2903  * FUNCTION   : mm_camera_intf_register_stream_buf_cb
   2904  *
   2905  * DESCRIPTION: Register special callback for stream buffer
   2906  *
   2907  * PARAMETERS :
   2908  *   @camera_handle: camera handle
   2909  *   @ch_id        : channel handle
   2910  *   @stream_id    : stream handle
   2911  *   @buf_cb       : callback function
   2912  *   @buf_type     :SYNC/ASYNC
   2913  *   @userdata     : userdata pointer
   2914  *
   2915  * RETURN     : int32_t type of status
   2916  *              0  -- success
   2917  *              1 -- failure
   2918  *==========================================================================*/
   2919 static int32_t mm_camera_intf_register_stream_buf_cb(uint32_t camera_handle,
   2920         uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
   2921         mm_camera_stream_cb_type cb_type, void *userdata)
   2922 {
   2923     int32_t rc = 0;
   2924     mm_camera_obj_t * my_obj = NULL;
   2925     uint32_t strid = get_main_camera_handle(stream_id);
   2926     uint32_t aux_strid = get_aux_camera_handle(stream_id);
   2927 
   2928     LOGD("E handle = %u ch_id = %u",
   2929           camera_handle, ch_id);
   2930 
   2931     if (strid) {
   2932         pthread_mutex_lock(&g_intf_lock);
   2933         uint32_t handle = get_main_camera_handle(camera_handle);
   2934         uint32_t chid = get_main_camera_handle(ch_id);
   2935         my_obj = mm_camera_util_get_camera_by_handler(handle);
   2936 
   2937         if(my_obj) {
   2938             pthread_mutex_lock(&my_obj->cam_lock);
   2939             pthread_mutex_unlock(&g_intf_lock);
   2940             rc = mm_camera_reg_stream_buf_cb(my_obj, chid, strid,
   2941                     buf_cb, cb_type, userdata);
   2942         } else {
   2943             pthread_mutex_unlock(&g_intf_lock);
   2944         }
   2945     }
   2946 
   2947     if (aux_strid) {
   2948         pthread_mutex_lock(&g_intf_lock);
   2949         uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   2950         uint32_t aux_chid = get_aux_camera_handle(ch_id);
   2951         my_obj = mm_camera_util_get_camera_head(aux_handle);
   2952 
   2953         if (my_obj) {
   2954             pthread_mutex_lock(&my_obj->muxer_lock);
   2955             pthread_mutex_unlock(&g_intf_lock);
   2956             rc = mm_camera_muxer_register_stream_buf_cb(aux_handle,
   2957                     aux_chid, aux_strid,
   2958                     buf_cb, cb_type, userdata, my_obj);
   2959         } else {
   2960             pthread_mutex_unlock(&g_intf_lock);
   2961         }
   2962     }
   2963     return (int32_t)rc;
   2964 }
   2965 
   2966 /*===========================================================================
   2967  * FUNCTION   : mm_camera_intf_register_frame_sync
   2968  *
   2969  * DESCRIPTION: start frame buffer sync for the stream
   2970  *
   2971  * PARAMETERS :
   2972  *   @camera_handle: camera handle
   2973  *   @ch_id        : channel handle
   2974  *   @stream_id    : stream handle
   2975  *   @sync_attr     : frame sync attr
   2976  *
   2977  * RETURN     : int32_t type of status
   2978  *              0  -- success
   2979  *              1 -- failure
   2980  *==========================================================================*/
   2981 static int32_t mm_camera_intf_reg_frame_sync(uint32_t camera_handle,
   2982             uint32_t ch_id, uint32_t stream_id,
   2983             mm_camera_intf_frame_sync_t *sync_attr)
   2984 {
   2985     int32_t rc = 0;
   2986     mm_camera_obj_t * my_obj = NULL;
   2987 
   2988     LOGD("E handle = %u ch_id = %u stream_id = %u", camera_handle, ch_id, stream_id);
   2989 
   2990     pthread_mutex_lock(&g_intf_lock);
   2991     uint32_t handle = get_main_camera_handle(camera_handle);
   2992     my_obj = mm_camera_util_get_camera_by_handler(handle);
   2993     if(my_obj) {
   2994         pthread_mutex_lock(&my_obj->muxer_lock);
   2995         pthread_mutex_unlock(&g_intf_lock);
   2996         rc = mm_camera_muxer_reg_frame_sync(my_obj,
   2997                  ch_id, stream_id, sync_attr);
   2998     } else {
   2999         pthread_mutex_unlock(&g_intf_lock);
   3000     }
   3001     return (int32_t)rc;
   3002 }
   3003 
   3004 /*===========================================================================
   3005  * FUNCTION   : mm_camera_intf_handle_frame_sync_cb
   3006  *
   3007  * DESCRIPTION: Handle callback request type incase of frame sync mode
   3008  *
   3009  * PARAMETERS :
   3010  *   @camera_handle: camera handle
   3011  *   @ch_id        : channel handle
   3012  *   @stream_id    : stream handle
   3013  *   @req_type    : callback request type
   3014  *
   3015  * RETURN     : int32_t type of status
   3016  *              0  -- success
   3017  *              1 -- failure
   3018  *==========================================================================*/
   3019 static int32_t mm_camera_intf_handle_frame_sync_cb(uint32_t camera_handle,
   3020         uint32_t ch_id, uint32_t stream_id, mm_camera_cb_req_type req_type)
   3021 {
   3022     int32_t rc = 0;
   3023     mm_camera_obj_t * my_obj = NULL;
   3024 
   3025     uint32_t handle = get_main_camera_handle(camera_handle);
   3026     uint32_t m_chid = get_main_camera_handle(ch_id);
   3027     uint32_t m_strid = get_main_camera_handle(stream_id);
   3028     LOGD("E handle = %u ch_id = %u stream_id = %u",
   3029             camera_handle, ch_id, stream_id);
   3030 
   3031     pthread_mutex_lock(&g_intf_lock);
   3032     my_obj = mm_camera_util_get_camera_by_handler(handle);
   3033     if(my_obj) {
   3034         pthread_mutex_lock(&my_obj->cam_lock);
   3035         pthread_mutex_unlock(&g_intf_lock);
   3036         rc = mm_camera_handle_frame_sync_cb(my_obj, m_chid, m_strid, req_type);
   3037     } else {
   3038         pthread_mutex_unlock(&g_intf_lock);
   3039     }
   3040     LOGH("stream_id = %u rc = %d", stream_id, rc);
   3041     return (int32_t)rc;
   3042 }
   3043 
   3044 struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType)
   3045 {
   3046     *pCamType = g_cam_ctrl.cam_type[camera_id];
   3047     return &g_cam_ctrl.info[camera_id];
   3048 }
   3049 
   3050 uint8_t is_dual_camera_by_idx(uint32_t camera_id)
   3051 {
   3052     return ((g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_MAIN)
   3053             && (g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_AUX));
   3054 }
   3055 
   3056 uint8_t is_dual_camera_by_handle(uint32_t handle)
   3057 {
   3058     return ((handle >> MM_CAMERA_HANDLE_SHIFT_MASK) &&
   3059             (handle & (MM_CAMERA_HANDLE_BIT_MASK)) ? 1 : 0);
   3060 }
   3061 
   3062 uint32_t get_aux_camera_handle(uint32_t handle)
   3063 {
   3064     return mm_camera_util_get_handle_by_num(1, handle);
   3065 }
   3066 
   3067 uint32_t get_main_camera_handle(uint32_t handle)
   3068 {
   3069     return mm_camera_util_get_handle_by_num(0, handle);
   3070 }
   3071 
   3072 cam_sync_type_t get_cam_type(uint32_t camera_id)
   3073 {
   3074     return  g_cam_ctrl.cam_type[camera_id];
   3075 }
   3076 
   3077 uint8_t is_yuv_sensor(uint32_t camera_id)
   3078 {
   3079     return g_cam_ctrl.is_yuv[camera_id];
   3080 }
   3081 
   3082 uint8_t validate_handle(uint32_t src_handle, uint32_t handle)
   3083 {
   3084     if ((src_handle == 0) || (handle == 0)) {
   3085         return 0;
   3086     }
   3087     return ((src_handle == handle)
   3088             || (get_main_camera_handle(src_handle) == handle)
   3089             || (get_aux_camera_handle(src_handle) == handle)
   3090             || (get_main_camera_handle(handle) == src_handle)
   3091             || (get_aux_camera_handle(handle) == src_handle));
   3092 }
   3093 
   3094 /* camera ops v-table */
   3095 static mm_camera_ops_t mm_camera_ops = {
   3096     .query_capability = mm_camera_intf_query_capability,
   3097     .register_event_notify = mm_camera_intf_register_event_notify,
   3098     .close_camera = mm_camera_intf_close,
   3099     .set_parms = mm_camera_intf_set_parms,
   3100     .get_parms = mm_camera_intf_get_parms,
   3101     .do_auto_focus = mm_camera_intf_do_auto_focus,
   3102     .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
   3103     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
   3104     .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
   3105     .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
   3106     .map_buf = mm_camera_intf_map_buf,
   3107     .map_bufs = mm_camera_intf_map_bufs,
   3108     .unmap_buf = mm_camera_intf_unmap_buf,
   3109     .add_channel = mm_camera_intf_add_channel,
   3110     .delete_channel = mm_camera_intf_del_channel,
   3111     .get_bundle_info = mm_camera_intf_get_bundle_info,
   3112     .add_stream = mm_camera_intf_add_stream,
   3113     .link_stream = mm_camera_intf_link_stream,
   3114     .delete_stream = mm_camera_intf_del_stream,
   3115     .config_stream = mm_camera_intf_config_stream,
   3116     .qbuf = mm_camera_intf_qbuf,
   3117     .cancel_buffer = mm_camera_intf_cancel_buf,
   3118     .get_queued_buf_count = mm_camera_intf_get_queued_buf_count,
   3119     .map_stream_buf = mm_camera_intf_map_stream_buf,
   3120     .map_stream_bufs = mm_camera_intf_map_stream_bufs,
   3121     .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
   3122     .set_stream_parms = mm_camera_intf_set_stream_parms,
   3123     .get_stream_parms = mm_camera_intf_get_stream_parms,
   3124     .start_channel = mm_camera_intf_start_channel,
   3125     .start_sensor_streaming = mm_camera_intf_start_sensor_streaming,
   3126     .stop_channel = mm_camera_intf_stop_channel,
   3127     .request_super_buf = mm_camera_intf_request_super_buf,
   3128     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
   3129     .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
   3130     .configure_notify_mode = mm_camera_intf_configure_notify_mode,
   3131     .process_advanced_capture = mm_camera_intf_process_advanced_capture,
   3132     .get_session_id = mm_camera_intf_get_session_id,
   3133     .set_dual_cam_cmd = mm_camera_intf_set_dual_cam_cmd,
   3134     .flush = mm_camera_intf_flush,
   3135     .register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb,
   3136     .register_frame_sync = mm_camera_intf_reg_frame_sync,
   3137     .handle_frame_sync_cb = mm_camera_intf_handle_frame_sync_cb
   3138 };
   3139 
   3140 /*===========================================================================
   3141  * FUNCTION   : camera_open
   3142  *
   3143  * DESCRIPTION: open a camera by camera index
   3144  *
   3145  * PARAMETERS :
   3146  *   @camera_idx  : camera index. should within range of 0 to num_of_cameras
   3147  *   @camera_vtbl : ptr to a virtual table containing camera handle and operation table.
   3148  *
   3149  * RETURN     : int32_t type of status
   3150  *              0  -- success
   3151  *              non-zero error code -- failure
   3152  *==========================================================================*/
   3153 int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl)
   3154 {
   3155     int32_t rc = 0;
   3156     mm_camera_obj_t *cam_obj = NULL;
   3157     uint32_t cam_idx = camera_idx;
   3158     uint32_t aux_idx = 0;
   3159     uint8_t is_multi_camera = 0;
   3160 
   3161 #ifdef QCAMERA_REDEFINE_LOG
   3162     mm_camera_debug_open();
   3163 #endif
   3164 
   3165     LOGD("E camera_idx = %d\n", camera_idx);
   3166     if (is_dual_camera_by_idx(camera_idx)) {
   3167         is_multi_camera = 1;
   3168         cam_idx = mm_camera_util_get_handle_by_num(0,
   3169                 g_cam_ctrl.cam_index[camera_idx]);
   3170         aux_idx = (get_aux_camera_handle(g_cam_ctrl.cam_index[camera_idx])
   3171                 >> MM_CAMERA_HANDLE_SHIFT_MASK);
   3172         LOGH("Dual Camera: Main ID = %d Aux ID = %d", cam_idx, aux_idx);
   3173     }
   3174 
   3175     if (cam_idx >= (uint32_t)g_cam_ctrl.num_cam || cam_idx >=
   3176         MM_CAMERA_MAX_NUM_SENSORS || aux_idx >= MM_CAMERA_MAX_NUM_SENSORS) {
   3177         LOGE("Invalid camera_idx (%d)", cam_idx);
   3178         return -EINVAL;
   3179     }
   3180 
   3181     pthread_mutex_lock(&g_intf_lock);
   3182     /* opened already */
   3183     if(NULL != g_cam_ctrl.cam_obj[cam_idx] &&
   3184             g_cam_ctrl.cam_obj[cam_idx]->ref_count != 0) {
   3185         pthread_mutex_unlock(&g_intf_lock);
   3186         LOGE("Camera %d is already open", cam_idx);
   3187         return -EBUSY;
   3188     }
   3189 
   3190     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
   3191     if(NULL == cam_obj) {
   3192         pthread_mutex_unlock(&g_intf_lock);
   3193         LOGE("no mem");
   3194         return -EINVAL;
   3195     }
   3196 
   3197     /* initialize camera obj */
   3198     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
   3199     cam_obj->ctrl_fd = -1;
   3200     cam_obj->ds_fd = -1;
   3201     cam_obj->ref_count++;
   3202     cam_obj->my_num = 0;
   3203     cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx);
   3204     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
   3205     cam_obj->vtbl.ops = &mm_camera_ops;
   3206     pthread_mutex_init(&cam_obj->cam_lock, NULL);
   3207     pthread_mutex_init(&cam_obj->muxer_lock, NULL);
   3208     /* unlock global interface lock, if not, in dual camera use case,
   3209       * current open will block operation of another opened camera obj*/
   3210     pthread_mutex_lock(&cam_obj->cam_lock);
   3211     pthread_mutex_unlock(&g_intf_lock);
   3212 
   3213     rc = mm_camera_open(cam_obj);
   3214     if (rc != 0) {
   3215         LOGE("mm_camera_open err = %d", rc);
   3216         pthread_mutex_destroy(&cam_obj->cam_lock);
   3217         pthread_mutex_lock(&g_intf_lock);
   3218         g_cam_ctrl.cam_obj[cam_idx] = NULL;
   3219         free(cam_obj);
   3220         cam_obj = NULL;
   3221         pthread_mutex_unlock(&g_intf_lock);
   3222         *camera_vtbl = NULL;
   3223         return rc;
   3224     }
   3225 
   3226     if (is_multi_camera) {
   3227         /*Open Aux camer's*/
   3228         pthread_mutex_lock(&g_intf_lock);
   3229         if(NULL != g_cam_ctrl.cam_obj[aux_idx] &&
   3230                 g_cam_ctrl.cam_obj[aux_idx]->ref_count != 0) {
   3231             pthread_mutex_unlock(&g_intf_lock);
   3232             LOGE("Camera %d is already open", aux_idx);
   3233             rc = -EBUSY;
   3234         } else {
   3235             pthread_mutex_lock(&cam_obj->muxer_lock);
   3236             pthread_mutex_unlock(&g_intf_lock);
   3237             rc = mm_camera_muxer_camera_open(aux_idx, cam_obj);
   3238         }
   3239         if (rc != 0) {
   3240             int32_t temp_rc = 0;
   3241             LOGE("muxer open err = %d", rc);
   3242             pthread_mutex_lock(&g_intf_lock);
   3243             g_cam_ctrl.cam_obj[cam_idx] = NULL;
   3244             pthread_mutex_lock(&cam_obj->cam_lock);
   3245             pthread_mutex_unlock(&g_intf_lock);
   3246             temp_rc = mm_camera_close(cam_obj);
   3247             pthread_mutex_destroy(&cam_obj->cam_lock);
   3248             pthread_mutex_destroy(&cam_obj->muxer_lock);
   3249             free(cam_obj);
   3250             cam_obj = NULL;
   3251             *camera_vtbl = NULL;
   3252             // Propagate the original error to caller
   3253             return rc;
   3254         }
   3255     }
   3256 
   3257     LOGH("Open succeded: handle = %d", cam_obj->vtbl.camera_handle);
   3258     g_cam_ctrl.cam_obj[cam_idx] = cam_obj;
   3259     *camera_vtbl = &cam_obj->vtbl;
   3260     return 0;
   3261 }
   3262 
   3263 /*===========================================================================
   3264  * FUNCTION   : mm_camera_load_shim_lib
   3265  *
   3266  * DESCRIPTION: Load shim layer library
   3267  *
   3268  * PARAMETERS :
   3269  *
   3270  * RETURN     : status of load shim library
   3271  *==========================================================================*/
   3272 int32_t mm_camera_load_shim_lib()
   3273 {
   3274     const char* error = NULL;
   3275     void *qdaemon_lib = NULL;
   3276 
   3277     LOGD("E");
   3278     qdaemon_lib = dlopen(SHIMLAYER_LIB, RTLD_NOW);
   3279     if (!qdaemon_lib) {
   3280         error = dlerror();
   3281         LOGE("dlopen failed with error %s", error ? error : "");
   3282         return -1;
   3283     }
   3284 
   3285     *(void **)&mm_camera_shim_module_init =
   3286             dlsym(qdaemon_lib, "mct_shimlayer_process_module_init");
   3287     if (!mm_camera_shim_module_init) {
   3288         error = dlerror();
   3289         LOGE("dlsym failed with error code %s", error ? error: "");
   3290         dlclose(qdaemon_lib);
   3291         return -1;
   3292     }
   3293 
   3294     return mm_camera_shim_module_init(&g_cam_ctrl.cam_shim_ops);
   3295 }
   3296 
   3297 /*===========================================================================
   3298  * FUNCTION   : mm_camera_module_open_session
   3299  *
   3300  * DESCRIPTION: wrapper function to call shim layer API to open session.
   3301  *
   3302  * PARAMETERS :
   3303  *   @sessionid  : sessionID to open session
   3304  *   @evt_cb     : Event callback function
   3305  *
   3306  * RETURN     : int32_t type of status
   3307  *              0  -- success
   3308  *              non-zero error code -- failure
   3309  *==========================================================================*/
   3310 cam_status_t mm_camera_module_open_session(int sessionid,
   3311         mm_camera_shim_event_handler_func evt_cb)
   3312 {
   3313     cam_status_t rc = -1;
   3314     if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session) {
   3315         rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session(
   3316                 sessionid, evt_cb);
   3317     }
   3318     return rc;
   3319 }
   3320 
   3321 /*===========================================================================
   3322  * FUNCTION   : mm_camera_module_close_session
   3323  *
   3324  * DESCRIPTION: wrapper function to call shim layer API to close session
   3325  *
   3326  * PARAMETERS :
   3327  *   @sessionid  : sessionID to open session
   3328  *
   3329  * RETURN     : int32_t type of status
   3330  *              0  -- success
   3331  *              non-zero error code -- failure
   3332  *==========================================================================*/
   3333 int32_t mm_camera_module_close_session(int session)
   3334 {
   3335     int32_t rc = -1;
   3336     if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session) {
   3337         rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session(session);
   3338     }
   3339     return rc;
   3340 }
   3341 
   3342 /*===========================================================================
   3343  * FUNCTION   : mm_camera_module_open_session
   3344  *
   3345  * DESCRIPTION: wrapper function to call shim layer API
   3346  *
   3347  * PARAMETERS :
   3348  *   @sessionid  : sessionID to open session
   3349  *   @evt_cb     : Event callback function
   3350  *
   3351  * RETURN     : int32_t type of status
   3352  *              0  -- success
   3353  *              non-zero error code -- failure
   3354  *==========================================================================*/
   3355 int32_t mm_camera_module_send_cmd(cam_shim_packet_t *event)
   3356 {
   3357     int32_t rc = -1;
   3358     if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd) {
   3359         rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd(event);
   3360     }
   3361     return rc;
   3362 }
   3363 
   3364 /*===========================================================================
   3365  * FUNCTION   : mm_camera_module_event_handler
   3366  *
   3367  * DESCRIPTION: call back function for shim layer
   3368  *
   3369  * PARAMETERS :
   3370  *
   3371  * RETURN     : status of call back function
   3372  *==========================================================================*/
   3373 int mm_camera_module_event_handler(uint32_t session_id, cam_event_t *event)
   3374 {
   3375     if (!event) {
   3376         LOGE("null event");
   3377         return FALSE;
   3378     }
   3379     mm_camera_event_t evt;
   3380 
   3381     LOGD("session_id:%d, cmd:0x%x", session_id, event->server_event_type);
   3382     memset(&evt, 0, sizeof(mm_camera_event_t));
   3383 
   3384     evt = *event;
   3385     mm_camera_obj_t *my_obj =
   3386          mm_camera_util_get_camera_by_session_id(session_id);
   3387     if (!my_obj) {
   3388         LOGE("my_obj:%p", my_obj);
   3389         return FALSE;
   3390     }
   3391     switch( evt.server_event_type) {
   3392        case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
   3393        case CAM_EVENT_TYPE_CAC_DONE:
   3394        case CAM_EVENT_TYPE_DAEMON_DIED:
   3395        case CAM_EVENT_TYPE_INT_TAKE_JPEG:
   3396        case CAM_EVENT_TYPE_INT_TAKE_RAW:
   3397            mm_camera_enqueue_evt(my_obj, &evt);
   3398            break;
   3399        default:
   3400            LOGE("cmd:%x from shim layer is not handled", evt.server_event_type);
   3401            break;
   3402    }
   3403    return TRUE;
   3404 }
   3405 
   3406