Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 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 <dlfcn.h>
     39 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
     40 #include IOCTL_H
     41 
     42 // Camera dependencies
     43 #include "cam_semaphore.h"
     44 #include "mm_camera_dbg.h"
     45 #include "mm_camera_sock.h"
     46 #include "mm_camera_interface.h"
     47 #include "mm_camera_muxer.h"
     48 
     49 #define MAX_UNMATCHED_FOR_FRAME_SYNC 0
     50 
     51 extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler);
     52 extern mm_channel_t * mm_camera_util_get_channel_by_handler(mm_camera_obj_t *cam_obj,
     53         uint32_t handler);
     54 extern mm_stream_t *mm_channel_util_get_stream_by_handler(mm_channel_t *ch_obj,
     55         uint32_t handler);
     56 extern int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj);
     57 
     58 
     59 /*===========================================================================
     60  * FUNCTION   : mm_camera_util_get_index_by_num
     61  *
     62  * DESCRIPTION: utility function to get index from handle
     63  *
     64  * PARAMETERS :
     65  *   @cam_num : Camera number
     66  *   @handler: object handle
     67  *
     68  * RETURN     : uint8_t type of index derived from handle
     69  *==========================================================================*/
     70 uint8_t mm_camera_util_get_index_by_num(uint8_t cam_num, uint32_t handler)
     71 {
     72     uint8_t idx = 0;
     73     idx = ((mm_camera_util_get_handle_by_num(cam_num, handler) >>
     74             (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num))
     75             & 0x000000ff);
     76     return idx;
     77 }
     78 
     79 /*===========================================================================
     80  * FUNCTION   : mm_camera_util_get_handle_by_num
     81  *
     82  * DESCRIPTION: utility function to get handle for specific camera
     83  *
     84  * PARAMETERS :
     85  *   @cam_num : Camera number
     86  *   @handler : object handle
     87  *
     88  * RETURN     : return proper handle based on the object num
     89  *==========================================================================*/
     90 uint32_t mm_camera_util_get_handle_by_num(uint8_t cam_num, uint32_t handler)
     91 {
     92     return (handler & (MM_CAMERA_HANDLE_BIT_MASK <<
     93             (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num)));
     94 }
     95 
     96 /*===========================================================================
     97  * FUNCTION   : mm_camera_util_generate_handler_by_num
     98  *
     99  * DESCRIPTION: utility function to generate handler for camera/channel/stream
    100  *
    101  * PARAMETERS :
    102  *   @cam_num : Camera number
    103  *   @index   : index of the object to have handler
    104  *
    105  * RETURN     : uint32_t type of handle that uniquely identify the object
    106  *==========================================================================*/
    107 uint32_t mm_camera_util_generate_handler_by_num(uint8_t cam_num, uint8_t index)
    108 {
    109     uint32_t handler = mm_camera_util_generate_handler(index);
    110     handler = (handler << (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num));
    111     return handler;
    112 }
    113 
    114 /*===========================================================================
    115  * FUNCTION   : mm_camera_util_get_dev_name_by_num
    116  *
    117  * DESCRIPTION: utility function to get device name from camera handle
    118  *
    119  * PARAMETERS :
    120  *   @cam_handle: camera handle
    121  *
    122  * RETURN     : char ptr to the device name stored in global variable
    123  * NOTE       : caller should not free the char ptr
    124  *==========================================================================*/
    125 const char *mm_camera_util_get_dev_name_by_num(uint8_t cam_num, uint32_t cam_handle)
    126 {
    127     uint32_t handle = (cam_handle >> (cam_num * MM_CAMERA_HANDLE_SHIFT_MASK));
    128     return mm_camera_util_get_dev_name(handle);
    129 }
    130 
    131 /*===========================================================================
    132  * FUNCTION   : mm_muxer_util_get_camera_by_obj
    133  *
    134  * DESCRIPTION: utility function to get camera object from object list
    135  *
    136  * PARAMETERS :
    137  *   @cam_handle: camera handle
    138  *   @cam_obj     : ptr to a Parent camera object
    139  *
    140  * RETURN     : ptr to the camera object stored in global variable
    141  * NOTE       : caller should not free the camera object ptr
    142  *==========================================================================*/
    143 mm_camera_obj_t* mm_muxer_util_get_camera_by_obj(uint32_t cam_handle,
    144         mm_camera_obj_t *cam_obj)
    145 {
    146     mm_camera_obj_t *obj = cam_obj;
    147     uint8_t i = 0;
    148 
    149     if (cam_handle == cam_obj->my_hdl) {
    150         return cam_obj;
    151     }
    152 
    153     if (obj->master_cam_obj != NULL) {
    154         obj = obj->master_cam_obj;
    155     }
    156     for (i = 0; i < obj->num_s_cnt; i++) {
    157         if (cam_handle == obj->aux_cam_obj[i]->my_hdl) {
    158             obj = obj->aux_cam_obj[i];
    159             break;
    160         }
    161     }
    162     return obj;
    163 }
    164 
    165 /*===========================================================================
    166  * FUNCTION   : mm_muxer_util_get_channel_by_obj
    167  *
    168  * DESCRIPTION: utility function to get channel object from camera
    169  *
    170  * PARAMETERS :
    171  *   @ch_id: channel handle
    172  *   @cam_obj     : ptr to a Parent camera object
    173  *
    174  * RETURN     : ptr to the camera object stored in global variable
    175  * NOTE       : caller should not free the camera object ptr
    176  *==========================================================================*/
    177 mm_channel_t *mm_muxer_util_get_channel_by_obj(uint32_t ch_id,
    178         mm_camera_obj_t *cam_obj)
    179 {
    180     mm_camera_obj_t *obj = cam_obj;
    181     mm_channel_t *ch_obj = NULL;
    182     uint8_t i = 0;
    183 
    184     if (obj->master_cam_obj != NULL) {
    185         obj = obj->master_cam_obj;
    186     }
    187     while (obj != NULL) {
    188         ch_obj = mm_camera_util_get_channel_by_handler(obj, ch_id);
    189         if (ch_obj != NULL) {
    190             break;
    191         }
    192         obj = obj->aux_cam_obj[i++];
    193     }
    194     return ch_obj;
    195 }
    196 
    197 /*===========================================================================
    198  * FUNCTION   : mm_muxer_util_get_stream_by_obj
    199  *
    200  * DESCRIPTION: utility function to get stream object from camera
    201  *
    202  * PARAMETERS :
    203  *   @stream_id: stream handle
    204  *   @cam_obj     : ptr to a Parent camera object
    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_stream_t *mm_muxer_util_get_stream_by_obj(uint32_t stream_id,
    210         mm_camera_obj_t *cam_obj)
    211 {
    212     mm_camera_obj_t *obj = cam_obj;
    213     mm_stream_t *stream_obj = NULL;
    214     uint8_t i = 0, j = 0;
    215 
    216     if (obj->master_cam_obj != NULL) {
    217         obj = obj->master_cam_obj;
    218     }
    219 
    220     while ((obj != NULL) && (stream_obj == NULL)) {
    221         for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
    222             stream_obj = mm_channel_util_get_stream_by_handler(
    223                     &cam_obj->ch[i], stream_id);
    224             if (stream_obj == NULL) {
    225                 break;
    226             }
    227         }
    228         obj = obj->aux_cam_obj[j++];
    229     }
    230     return stream_obj;
    231 }
    232 
    233 /*===========================================================================
    234  * FUNCTION   : mm_camera_muxer_camera_open
    235  *
    236  * DESCRIPTION: open a supporting camera by camera index
    237  *
    238  * PARAMETERS :
    239  *   @cam_idx  : camera index. should within range of 0 to num_of_cameras
    240  *   @cam_obj     : ptr to a Parent camera object
    241  *
    242  * RETURN     : int32_t type of status
    243  *              0  -- success
    244  *              non-zero error code -- failure
    245  *==========================================================================*/
    246 int32_t mm_camera_muxer_camera_open(uint8_t cam_idx,
    247         mm_camera_obj_t *cam_obj)
    248 {
    249     int32_t rc = 0;
    250     mm_camera_obj_t *my_obj = NULL;
    251     uint8_t my_num = 1;
    252 
    253     my_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
    254     if(NULL == my_obj) {
    255         pthread_mutex_unlock(&cam_obj->muxer_lock);
    256         LOGE("no mem");
    257         return -EINVAL;
    258     }
    259 
    260     /* initialize camera obj */
    261     memset(my_obj, 0, sizeof(mm_camera_obj_t));
    262     my_obj->ctrl_fd = -1;
    263     my_obj->ds_fd = -1;
    264     my_obj->ref_count++;
    265     my_obj->my_num = my_num;
    266     my_obj->my_hdl = mm_camera_util_generate_handler_by_num(my_num, cam_idx);
    267     pthread_mutex_init(&my_obj->cam_lock, NULL);
    268     /* unlock global interface lock, if not, in dual camera use case,
    269       * current open will block operation of another opened camera obj*/
    270     pthread_mutex_lock(&my_obj->cam_lock);
    271     pthread_mutex_unlock(&cam_obj->muxer_lock);
    272 
    273     rc = mm_camera_open(my_obj);
    274     pthread_mutex_lock(&cam_obj->muxer_lock);
    275     if (rc != 0) {
    276         LOGE("mm_camera_open err = %d", rc);
    277         pthread_mutex_destroy(&my_obj->cam_lock);
    278         free(my_obj);
    279         my_obj = NULL;
    280         pthread_mutex_unlock(&cam_obj->muxer_lock);
    281         return rc;
    282     } else {
    283         LOGD("Open succeded\n");
    284         rc  = mm_camera_util_set_camera_object(cam_idx, my_obj);
    285         my_obj->vtbl.camera_handle = (cam_obj->my_hdl | my_obj->my_hdl);
    286         cam_obj->vtbl.camera_handle = my_obj->vtbl.camera_handle;
    287         cam_obj->aux_cam_obj[cam_obj->num_s_cnt++] = my_obj;
    288         my_obj->master_cam_obj = cam_obj;
    289         cam_obj->master_cam_obj = NULL;
    290         pthread_mutex_unlock(&cam_obj->muxer_lock);
    291         return rc;
    292     }
    293 }
    294 
    295 /*===========================================================================
    296  * FUNCTION   : mm_camera_muxer_query_capability
    297  *
    298  * DESCRIPTION: query camera capability
    299  *
    300  * PARAMETERS :
    301  *   @camera_handle: camera handle
    302  *   @cam_obj     : ptr to a Parent camera object
    303  *
    304  * RETURN     : int32_t type of status
    305  *              0  -- success
    306  *              -1 -- failure
    307  *==========================================================================*/
    308 int32_t mm_camera_muxer_query_capability(uint32_t camera_handle,
    309         mm_camera_obj_t *cam_obj)
    310 {
    311     int32_t rc = 0;
    312     mm_camera_obj_t *my_obj = NULL;
    313 
    314     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    315     if(my_obj) {
    316         pthread_mutex_lock(&my_obj->cam_lock);
    317         pthread_mutex_unlock(&cam_obj->muxer_lock);
    318         rc = mm_camera_query_capability(my_obj);
    319     } else {
    320         pthread_mutex_unlock(&cam_obj->muxer_lock);
    321     }
    322     LOGD(" rc = %d", rc);
    323     return rc;
    324 }
    325 
    326 /*===========================================================================
    327  * FUNCTION   : mm_camera_muxer_register_event_notify
    328  *
    329  * DESCRIPTION: register for event notify
    330  *
    331  * PARAMETERS :
    332  *   @camera_handle: camera handle
    333  *   @evt_cb       : callback for event notify
    334  *   @user_data    : user data ptr
    335  *   @cam_obj     : ptr to a Parent camera object
    336  *
    337  * RETURN     : int32_t type of status
    338  *              0  -- success
    339  *              -1 -- failure
    340  *==========================================================================*/
    341 int32_t mm_camera_muxer_register_event_notify(uint32_t camera_handle,
    342         mm_camera_event_notify_t evt_cb,
    343         void *user_data, mm_camera_obj_t *cam_obj)
    344 {
    345     int32_t rc = 0;
    346     mm_camera_obj_t *my_obj = NULL;
    347 
    348     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    349     if(my_obj) {
    350         pthread_mutex_lock(&my_obj->cam_lock);
    351         pthread_mutex_unlock(&cam_obj->muxer_lock);
    352         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
    353     } else {
    354         pthread_mutex_unlock(&cam_obj->muxer_lock);
    355     }
    356     return rc;
    357 }
    358 
    359 /*===========================================================================
    360  * FUNCTION   : mm_camera_muxer_close_camera
    361  *
    362  * DESCRIPTION: close a camera by its handle
    363  *
    364  * PARAMETERS :
    365  *   @camera_handle: camera handle
    366  *   @cam_obj     : ptr to a Parent camera object
    367  *
    368  * RETURN     : int32_t type of status
    369  *              0  -- success
    370  *              -1 -- failure
    371  *==========================================================================*/
    372 int32_t mm_camera_muxer_close_camera(uint32_t camera_handle,
    373         mm_camera_obj_t *cam_obj)
    374 {
    375     int32_t rc = 0;
    376     mm_camera_obj_t *my_obj = NULL;
    377 
    378     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    379     if (my_obj){
    380         uint8_t cam_idx = mm_camera_util_get_index_by_num(
    381                 my_obj->my_num, my_obj->my_hdl);
    382         my_obj->ref_count--;
    383         if(my_obj->ref_count > 0) {
    384             LOGD("ref_count=%d\n", my_obj->ref_count);
    385             pthread_mutex_unlock(&cam_obj->muxer_lock);
    386             rc = 0;
    387         } else {
    388             rc  = mm_camera_util_set_camera_object(cam_idx, NULL);
    389             pthread_mutex_lock(&my_obj->cam_lock);
    390             pthread_mutex_unlock(&cam_obj->muxer_lock);
    391             rc = mm_camera_close(my_obj);
    392             pthread_mutex_destroy(&my_obj->cam_lock);
    393             free(my_obj);
    394             my_obj = NULL;
    395         }
    396     } else {
    397         pthread_mutex_unlock(&cam_obj->muxer_lock);
    398     }
    399     return rc;
    400 }
    401 
    402 /*===========================================================================
    403  * FUNCTION   : mm_camera_muxer_map_buf
    404  *
    405  * DESCRIPTION: mapping camera buffer via domain socket to server
    406  *
    407  * PARAMETERS :
    408  *   @camera_handle: camera handle
    409  *   @buf_type     : type of buffer to be mapped. could be following values:
    410  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
    411  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
    412  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
    413  *   @fd           : file descriptor of the buffer
    414  *   @size         : size of the buffer
    415  *   @cam_obj     : ptr to a Parent camera object
    416  *
    417  * RETURN     : int32_t type of status
    418  *              0  -- success
    419  *              -1 -- failure
    420  *==========================================================================*/
    421 int32_t mm_camera_muxer_map_buf(uint32_t camera_handle, uint8_t buf_type,
    422         int fd, size_t size, void *buffer, mm_camera_obj_t *cam_obj)
    423 {
    424     int32_t rc = -1;
    425     mm_camera_obj_t * my_obj = NULL;
    426     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    427 
    428     if(my_obj) {
    429         pthread_mutex_lock(&my_obj->cam_lock);
    430         pthread_mutex_unlock(&cam_obj->muxer_lock);
    431         rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
    432     }else{
    433         pthread_mutex_unlock(&cam_obj->muxer_lock);
    434     }
    435     return rc;
    436 }
    437 
    438 /*===========================================================================
    439  * FUNCTION   : mm_camera_muxer_map_bufs
    440  *
    441  * DESCRIPTION: mapping camera buffer via domain socket to server
    442  *
    443  * PARAMETERS :
    444  *   @camera_handle: camera handle
    445  *   @buf_type     : type of buffer to be mapped. could be following values:
    446  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
    447  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
    448  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
    449  *   @cam_obj     : ptr to a Parent camera object
    450  *
    451  * RETURN     : int32_t type of status
    452  *              0  -- success
    453  *              -1 -- failure
    454  *==========================================================================*/
    455 int32_t mm_camera_muxer_map_bufs(uint32_t camera_handle,
    456         const cam_buf_map_type_list *buf_map_list,
    457         mm_camera_obj_t *cam_obj)
    458 {
    459     int32_t rc = -1;
    460     mm_camera_obj_t * my_obj = NULL;
    461     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    462 
    463     if(my_obj) {
    464         pthread_mutex_lock(&my_obj->cam_lock);
    465         pthread_mutex_unlock(&cam_obj->muxer_lock);
    466         rc = mm_camera_map_bufs(my_obj, buf_map_list);
    467     }else{
    468         pthread_mutex_unlock(&cam_obj->muxer_lock);
    469     }
    470     return rc;
    471 }
    472 
    473 /*===========================================================================
    474  * FUNCTION   : mm_camera_muxer_unmap_buf
    475  *
    476  * DESCRIPTION: unmapping camera buffer via domain socket to server
    477  *
    478  * PARAMETERS :
    479  *   @camera_handle: camera handle
    480  *   @buf_type     : type of buffer to be unmapped. could be following values:
    481  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
    482  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
    483  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
    484  *   @cam_obj     : ptr to a Parent camera object
    485  *
    486  * RETURN     : int32_t type of status
    487  *              0  -- success
    488  *              -1 -- failure
    489  *==========================================================================*/
    490 int32_t mm_camera_muxer_unmap_buf(uint32_t camera_handle,
    491         uint8_t buf_type, mm_camera_obj_t *cam_obj)
    492 {
    493     int32_t rc = -1;
    494     mm_camera_obj_t * my_obj = NULL;
    495     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    496 
    497     if(my_obj) {
    498         pthread_mutex_lock(&my_obj->cam_lock);
    499         pthread_mutex_unlock(&cam_obj->muxer_lock);
    500         rc = mm_camera_unmap_buf(my_obj, buf_type);
    501     }else{
    502         pthread_mutex_unlock(&cam_obj->muxer_lock);
    503     }
    504     return rc;
    505 }
    506 
    507 /*===========================================================================
    508  * FUNCTION   : mm_camera_muxer_set_parms
    509  *
    510  * DESCRIPTION: set parameters per camera
    511  *
    512  * PARAMETERS :
    513  *   @camera_handle: camera handle
    514  *   @parms        : ptr to a param struct to be set to server
    515  *   @cam_obj     : ptr to a Parent camera object
    516  *
    517  * RETURN     : int32_t type of status
    518  *              0  -- success
    519  *              -1 -- failure
    520  *==========================================================================*/
    521 int32_t mm_camera_muxer_set_parms(uint32_t camera_handle,
    522         parm_buffer_t *parms, mm_camera_obj_t *cam_obj)
    523 {
    524     int32_t rc = 0;
    525     mm_camera_obj_t *my_obj = NULL;
    526 
    527     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    528     if(my_obj) {
    529         pthread_mutex_lock(&my_obj->cam_lock);
    530         pthread_mutex_unlock(&cam_obj->muxer_lock);
    531         rc = mm_camera_set_parms(my_obj, parms);
    532     } else {
    533         pthread_mutex_unlock(&cam_obj->muxer_lock);
    534     }
    535     return rc;
    536 }
    537 
    538 /*===========================================================================
    539  * FUNCTION   : mm_camera_muxer_get_parms
    540  *
    541  * DESCRIPTION: get parameters per camera
    542  *
    543  * PARAMETERS :
    544  *   @camera_handle: camera handle
    545  *   @parms        : ptr to a param struct to be get from server
    546  *   @cam_obj     : ptr to a Parent camera object
    547  *
    548  * RETURN     : int32_t type of status
    549  *              0  -- success
    550  *              -1 -- failure
    551  *==========================================================================*/
    552 int32_t mm_camera_muxer_get_parms(uint32_t camera_handle,
    553         parm_buffer_t *parms, mm_camera_obj_t *cam_obj)
    554 {
    555     int32_t rc = 0;
    556     mm_camera_obj_t *my_obj = NULL;
    557 
    558     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    559     if(my_obj) {
    560         pthread_mutex_lock(&my_obj->cam_lock);
    561         pthread_mutex_unlock(&cam_obj->muxer_lock);
    562         rc = mm_camera_get_parms(my_obj, parms);
    563     } else {
    564         pthread_mutex_unlock(&cam_obj->muxer_lock);
    565     }
    566     return rc;
    567 }
    568 
    569 /*===========================================================================
    570  * FUNCTION   : mm_camera_muxer_do_auto_focus
    571  *
    572  * DESCRIPTION: performing auto focus
    573  *
    574  * PARAMETERS :
    575  *   @camera_handle: camera handle
    576  *   @cam_obj     : ptr to a Parent camera object
    577  *
    578  * RETURN     : int32_t type of status
    579  *              0  -- success
    580  *              -1 -- failure
    581  *==========================================================================*/
    582 int32_t mm_camera_muxer_do_auto_focus(uint32_t camera_handle,
    583         mm_camera_obj_t *cam_obj)
    584 {
    585     int32_t rc = 0;
    586     mm_camera_obj_t *my_obj = NULL;
    587 
    588     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    589     if(my_obj) {
    590         pthread_mutex_lock(&my_obj->cam_lock);
    591         pthread_mutex_unlock(&cam_obj->muxer_lock);
    592         rc = mm_camera_do_auto_focus(my_obj);
    593     } else {
    594         pthread_mutex_unlock(&cam_obj->muxer_lock);
    595     }
    596     return rc;
    597 }
    598 
    599 /*===========================================================================
    600  * FUNCTION   : mm_camera_muxer_cancel_auto_focus
    601  *
    602  * DESCRIPTION: cancel auto focus
    603  *
    604  * PARAMETERS :
    605  *   @camera_handle: camera handle
    606  *   @cam_obj     : ptr to a Parent camera object
    607  *
    608  * RETURN     : int32_t type of status
    609  *              0  -- success
    610  *              -1 -- failure
    611  *==========================================================================*/
    612 int32_t mm_camera_muxer_cancel_auto_focus(uint32_t camera_handle,
    613         mm_camera_obj_t *cam_obj)
    614 {
    615     int32_t rc = 0;
    616     mm_camera_obj_t *my_obj = NULL;
    617 
    618     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    619     if(my_obj) {
    620         pthread_mutex_lock(&my_obj->cam_lock);
    621         pthread_mutex_unlock(&cam_obj->muxer_lock);
    622         rc = mm_camera_cancel_auto_focus(my_obj);
    623     } else {
    624         pthread_mutex_unlock(&cam_obj->muxer_lock);
    625     }
    626     return rc;
    627 }
    628 
    629 /*===========================================================================
    630  * FUNCTION   : mm_camera_muxer_prepare_snapshot
    631  *
    632  * DESCRIPTION: prepare hardware for snapshot
    633  *
    634  * PARAMETERS :
    635  *   @camera_handle: camera handle
    636  *   @do_af_flag   : flag indicating if AF is needed
    637  *   @cam_obj     : ptr to a Parent camera object
    638  *
    639  * RETURN     : int32_t type of status
    640  *              0  -- success
    641  *              -1 -- failure
    642  *==========================================================================*/
    643 int32_t mm_camera_muxer_prepare_snapshot(uint32_t camera_handle,
    644         int32_t do_af_flag, mm_camera_obj_t *cam_obj)
    645 {
    646     int32_t rc = 0;
    647     mm_camera_obj_t *my_obj = NULL;
    648 
    649     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    650     if(my_obj) {
    651         pthread_mutex_lock(&my_obj->cam_lock);
    652         pthread_mutex_unlock(&cam_obj->muxer_lock);
    653         rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
    654     } else {
    655         pthread_mutex_unlock(&cam_obj->muxer_lock);
    656     }
    657     return rc;
    658 }
    659 
    660 /*===========================================================================
    661  * FUNCTION   : mm_camera_muxer_start_zsl_snapshot
    662  *
    663  * DESCRIPTION: Starts zsl snapshot
    664  *
    665  * PARAMETERS :
    666  *   @camera_handle: camera handle
    667  *   @ch_id        : channel handle
    668  *   @cam_obj     : ptr to a Parent camera object
    669  *
    670  * RETURN     : int32_t type of status
    671  *              0  -- success
    672  *              -1 -- failure
    673  *==========================================================================*/
    674 int32_t mm_camera_muxer_start_zsl_snapshot(uint32_t camera_handle,
    675         uint32_t ch_id, mm_camera_obj_t *cam_obj)
    676 {
    677     int32_t rc = 0;
    678     mm_camera_obj_t *my_obj = NULL;
    679 
    680     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    681     if(my_obj) {
    682         uint32_t my_ch_id = mm_camera_util_get_handle_by_num(my_obj->my_num, ch_id);
    683         pthread_mutex_lock(&my_obj->cam_lock);
    684         pthread_mutex_unlock(&cam_obj->muxer_lock);
    685         rc = mm_camera_start_zsl_snapshot_ch(my_obj, my_ch_id);
    686     } else {
    687         pthread_mutex_unlock(&cam_obj->muxer_lock);
    688     }
    689     return rc;
    690 }
    691 
    692 /*===========================================================================
    693  * FUNCTION   : mm_camera_muxer_stop_zsl_snapshot
    694  *
    695  * DESCRIPTION: Starts zsl snapshot
    696  *
    697  * PARAMETERS :
    698  *   @camera_handle: camera handle
    699  *   @ch_id        : channel handle
    700  *   @cam_obj     : ptr to a Parent camera object
    701  *
    702  * RETURN     : int32_t type of status
    703  *              0  -- success
    704  *              -1 -- failure
    705  *==========================================================================*/
    706 int32_t mm_camera_muxer_stop_zsl_snapshot(uint32_t camera_handle,
    707         uint32_t ch_id, mm_camera_obj_t *cam_obj)
    708 {
    709     int32_t rc = 0;
    710     mm_camera_obj_t *my_obj = NULL;
    711 
    712     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    713     if(my_obj) {
    714         uint32_t my_ch_id = mm_camera_util_get_handle_by_num(my_obj->my_num, ch_id);
    715         pthread_mutex_lock(&my_obj->cam_lock);
    716         pthread_mutex_unlock(&cam_obj->muxer_lock);
    717         rc = mm_camera_stop_zsl_snapshot_ch(my_obj, my_ch_id);
    718     } else {
    719         pthread_mutex_unlock(&cam_obj->muxer_lock);
    720     }
    721     return rc;
    722 }
    723 
    724 /*===========================================================================
    725  * FUNCTION   : mm_camera_muxer_add_channel
    726  *
    727  * DESCRIPTION: add a channel
    728  *
    729  * PARAMETERS :
    730  *   @camera_handle: camera handle
    731  *   @attr         : bundle attribute of the channel if needed
    732  *   @channel_cb   : callback function for bundle data notify
    733  *   @userdata     : user data ptr
    734  *   @cam_obj     : ptr to a Parent camera object
    735  *
    736  * RETURN     : uint32_t type of channel handle
    737  *              0  -- invalid channel handle, meaning the op failed
    738  *              >0 -- successfully added a channel with a valid handle
    739  *==========================================================================*/
    740 uint32_t mm_camera_muxer_add_channel(uint32_t camera_handle,
    741         mm_camera_channel_attr_t *attr, mm_camera_buf_notify_t channel_cb,
    742         void *userdata, uint32_t m_ch_id, mm_camera_obj_t *cam_obj)
    743 {
    744     int32_t ch_id = 0;
    745     mm_camera_obj_t *my_obj = NULL;
    746 
    747     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    748     if(my_obj) {
    749         pthread_mutex_lock(&my_obj->cam_lock);
    750         pthread_mutex_unlock(&cam_obj->muxer_lock);
    751         ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
    752 
    753         if (ch_id > 0 && m_ch_id > 0) {
    754             mm_camera_frame_sync_t frame_sync;
    755             memset(&frame_sync, 0, sizeof(frame_sync));
    756             frame_sync.a_cam_obj = my_obj;
    757             frame_sync.a_ch_id = ch_id;
    758             frame_sync.userdata = userdata;
    759             frame_sync.a_stream_id = 0;
    760             frame_sync.is_res_shared = 1;
    761             if (attr != NULL) {
    762                 frame_sync.attr = *attr;
    763                 frame_sync.is_active = 1;
    764             }
    765             pthread_mutex_lock(&cam_obj->cam_lock);
    766             mm_camera_reg_frame_sync(cam_obj, m_ch_id,
    767                     0, &frame_sync);
    768         }
    769     } else {
    770         pthread_mutex_unlock(&cam_obj->muxer_lock);
    771     }
    772     return ch_id;
    773 }
    774 
    775 /*===========================================================================
    776  * FUNCTION   : mm_camera_muxer_delete_channel
    777  *
    778  * DESCRIPTION: delete a channel by its handle
    779  *
    780  * PARAMETERS :
    781  *   @camera_handle: camera handle
    782  *   @ch_id        : channel handle
    783  *   @cam_obj     : ptr to a Parent camera object
    784  *
    785  * RETURN     : int32_t type of status
    786  *              0  -- success
    787  *              -1 -- failure
    788  *==========================================================================*/
    789 int32_t mm_camera_muxer_delete_channel(uint32_t camera_handle, uint32_t ch_id,
    790         mm_camera_obj_t *cam_obj)
    791 {
    792     int32_t rc = -1;
    793     mm_camera_obj_t *my_obj = NULL;
    794 
    795     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    796     if(my_obj) {
    797         pthread_mutex_lock(&my_obj->cam_lock);
    798         pthread_mutex_unlock(&cam_obj->muxer_lock);
    799         rc = mm_camera_del_channel(my_obj, ch_id);
    800     } else {
    801         pthread_mutex_unlock(&cam_obj->muxer_lock);
    802     }
    803     return rc;
    804 }
    805 
    806 /*===========================================================================
    807  * FUNCTION   : mm_camera_muxer_get_bundle_info
    808  *
    809  * DESCRIPTION: query bundle info of the channel
    810  *
    811  * PARAMETERS :
    812  *   @camera_handle: camera handle
    813  *   @ch_id        : channel handle
    814  *   @bundle_info  : bundle info to be filled in
    815  *   @cam_obj     : ptr to a Parent camera object
    816  *
    817  * RETURN     : int32_t type of status
    818  *              0  -- success
    819  *              -1 -- failure
    820  *==========================================================================*/
    821 int32_t mm_camera_muxer_get_bundle_info(uint32_t camera_handle, uint32_t ch_id,
    822         cam_bundle_config_t *bundle_info, mm_camera_obj_t *cam_obj)
    823 {
    824     int32_t rc = -1;
    825     mm_camera_obj_t *my_obj = NULL;
    826 
    827     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    828     if(my_obj) {
    829         pthread_mutex_lock(&my_obj->cam_lock);
    830         pthread_mutex_unlock(&cam_obj->muxer_lock);
    831         rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
    832     } else {
    833         pthread_mutex_unlock(&cam_obj->muxer_lock);
    834     }
    835     return rc;
    836 }
    837 /*===========================================================================
    838  * FUNCTION   : mm_camera_muxer_add_stream
    839  *
    840  * DESCRIPTION: add a stream into a channel
    841  *
    842  * PARAMETERS :
    843  *   @camera_handle: camera handle
    844  *   @ch_id        : channel handle
    845  *   @src__ch_id        : src channel handle
    846  *   @src_stream_id     :  src stream handle
    847  *   @cam_obj     : ptr to a Parent camera object
    848  *
    849  * RETURN     : uint32_t type of stream handle
    850  *              0  -- invalid stream handle, meaning the op failed
    851  *              >0 -- successfully added a stream with a valid handle
    852  *==========================================================================*/
    853 uint32_t mm_camera_muxer_add_stream(uint32_t camera_handle,
    854         uint32_t ch_id, uint32_t src__ch_id, uint32_t src_stream_id, mm_camera_obj_t *cam_obj)
    855 {
    856     uint32_t stream_id = 0;
    857     int32_t rc = 0;
    858     mm_camera_obj_t *my_obj = NULL;
    859 
    860     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    861     if(my_obj) {
    862         pthread_mutex_lock(&my_obj->cam_lock);
    863         pthread_mutex_unlock(&cam_obj->muxer_lock);
    864         stream_id = mm_camera_add_stream(my_obj, ch_id);
    865         if (stream_id > 0 && src_stream_id > 0) {
    866             mm_camera_frame_sync_t frame_sync;
    867             memset(&frame_sync, 0, sizeof(frame_sync));
    868             frame_sync.a_cam_obj = my_obj;
    869             frame_sync.a_ch_id = ch_id;
    870             frame_sync.userdata = NULL;
    871             frame_sync.a_stream_id = stream_id;
    872             frame_sync.buf_cb = NULL;
    873             frame_sync.is_res_shared = 1;
    874             frame_sync.is_active = 0;
    875             pthread_mutex_lock(&cam_obj->cam_lock);
    876             rc = mm_camera_reg_frame_sync(cam_obj, src__ch_id,
    877                     src_stream_id, &frame_sync);
    878             LOGH("Stream frame sync = %d and %d rc = %d",
    879                     src_stream_id, stream_id, rc);
    880         }
    881     } else {
    882         pthread_mutex_unlock(&cam_obj->muxer_lock);
    883     }
    884     return stream_id;
    885 }
    886 
    887 /*===========================================================================
    888  * FUNCTION   : mm_camera_muxer_delete_stream
    889  *
    890  * DESCRIPTION: delete a stream by its handle
    891  *
    892  * PARAMETERS :
    893  *   @camera_handle: camera handle
    894  *   @ch_id        : channel handle
    895  *   @stream_id    : stream handle
    896  *
    897  * RETURN     : int32_t type of status
    898  *              0  -- success
    899  *              -1 -- failure
    900  *==========================================================================*/
    901 int32_t mm_camera_muxer_delete_stream(uint32_t camera_handle,
    902         uint32_t ch_id, uint32_t stream_id,
    903         mm_camera_obj_t *cam_obj)
    904 {
    905     mm_camera_obj_t *my_obj = NULL;
    906     int32_t rc = 0;
    907 
    908     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    909     if(my_obj) {
    910         pthread_mutex_lock(&my_obj->cam_lock);
    911         pthread_mutex_unlock(&cam_obj->muxer_lock);
    912         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    913     } else {
    914         pthread_mutex_unlock(&cam_obj->muxer_lock);
    915     }
    916     return rc;
    917 }
    918 
    919 /*===========================================================================
    920  * FUNCTION   : mm_camera_muxer_link_stream
    921  *
    922  * DESCRIPTION: link a stream into a new channel
    923  *
    924  * PARAMETERS :
    925  *   @camera_handle: camera handle
    926  *   @ch_id        : channel handle
    927  *   @stream_id    : stream id
    928  *   @linked_ch_id : channel in which the stream will be linked
    929  *
    930  * RETURN     : int32_t type of stream handle
    931  *              0  -- invalid stream handle, meaning the op failed
    932  *              >0 -- successfully linked a stream with a valid handle
    933  *==========================================================================*/
    934 int32_t mm_camera_muxer_link_stream(uint32_t camera_handle,
    935         uint32_t ch_id, uint32_t stream_id, uint32_t linked_ch_id,
    936         mm_camera_obj_t *cam_obj)
    937 {
    938     uint32_t id = 0;
    939     mm_camera_obj_t *my_obj = NULL;
    940     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    941 
    942     if(my_obj) {
    943         pthread_mutex_lock(&my_obj->cam_lock);
    944         pthread_mutex_unlock(&cam_obj->muxer_lock);
    945         id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
    946     } else {
    947         pthread_mutex_unlock(&cam_obj->muxer_lock);
    948     }
    949     return id;
    950 }
    951 
    952 /*===========================================================================
    953  * FUNCTION   : mm_camera_muxer_config_stream
    954  *
    955  * DESCRIPTION: configure a stream
    956  *
    957  * PARAMETERS :
    958  *   @camera_handle: camera handle
    959  *   @ch_id        : channel handle
    960  *   @stream_id    : stream handle
    961  *   @config       : stream configuration
    962  *
    963  * RETURN     : int32_t type of status
    964  *              0  -- success
    965  *              -1 -- failure
    966  *==========================================================================*/
    967 int32_t mm_camera_muxer_config_stream(uint32_t camera_handle,
    968         uint32_t ch_id, uint32_t stream_id, mm_camera_stream_config_t *config,
    969         mm_camera_obj_t *cam_obj)
    970 {
    971     int32_t rc = -1;
    972     mm_camera_obj_t * my_obj = NULL;
    973     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    974     mm_camera_stream_config_t aux_config = *config;
    975     LOGD("mm_camera_intf_config_stream stream_id = %d",stream_id);
    976 
    977     if(my_obj) {
    978         pthread_mutex_lock(&my_obj->cam_lock);
    979         pthread_mutex_unlock(&cam_obj->muxer_lock);
    980         if (config->stream_info->aux_str_info != NULL) {
    981             aux_config.stream_info = config->stream_info->aux_str_info;
    982             aux_config.mem_vtbl.get_bufs = NULL;
    983             aux_config.mem_vtbl.put_bufs = NULL;
    984             aux_config.mem_vtbl.set_config_ops = NULL;
    985         }
    986         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, &aux_config);
    987     } else {
    988         pthread_mutex_unlock(&cam_obj->muxer_lock);
    989     }
    990     return rc;
    991 }
    992 
    993 /*===========================================================================
    994  * FUNCTION   : mm_camera_muxer_map_stream_buf
    995  *
    996  * DESCRIPTION: mapping stream buffer via domain socket to server
    997  *
    998  * PARAMETERS :
    999  *   @camera_handle: camera handle
   1000  *   @ch_id        : channel handle
   1001  *   @s_id         : stream handle
   1002  *   @buf_type     : type of buffer to be mapped. could be following values:
   1003  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1004  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1005  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1006  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1007  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1008  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1009  *   @plane_idx    : plane index. If all planes share the same fd,
   1010  *                   plane_idx = -1; otherwise, plean_idx is the
   1011  *                   index to plane (0..num_of_planes)
   1012  *   @fd           : file descriptor of the buffer
   1013  *   @size         : size of the buffer
   1014  *
   1015  * RETURN     : int32_t type of status
   1016  *              0  -- success
   1017  *              -1 -- failure
   1018  *==========================================================================*/
   1019 int32_t mm_camera_muxer_map_stream_buf(uint32_t camera_handle,
   1020         uint32_t ch_id, uint32_t stream_id,
   1021         uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, int fd,
   1022         size_t size, void *buffer, mm_camera_obj_t *cam_obj)
   1023 {
   1024     int32_t rc = -1;
   1025     mm_camera_obj_t * my_obj = NULL;
   1026     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1027 
   1028     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1029 
   1030     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1031           camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1032 
   1033     if(my_obj) {
   1034         pthread_mutex_lock(&my_obj->cam_lock);
   1035         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1036         rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
   1037                                   buf_type, buf_idx, plane_idx,
   1038                                   fd, size, buffer);
   1039     }else{
   1040         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1041     }
   1042     return rc;
   1043 }
   1044 
   1045 /*===========================================================================
   1046  * FUNCTION   : mm_camera_muxer_map_stream_bufs
   1047  *
   1048  * DESCRIPTION: mapping stream buffers via domain socket to server
   1049  *
   1050  * PARAMETERS :
   1051  *   @camera_handle: camera handle
   1052  *   @ch_id        : channel handle
   1053  *   @buf_map_list : list of buffers to be mapped
   1054  *
   1055  * RETURN     : int32_t type of status
   1056  *              0  -- success
   1057  *              -1 -- failure
   1058  *==========================================================================*/
   1059 int32_t mm_camera_muxer_map_stream_bufs(uint32_t camera_handle,
   1060         uint32_t ch_id, const cam_buf_map_type_list *buf_map_list,
   1061         mm_camera_obj_t *cam_obj)
   1062 {
   1063     int32_t rc = -1;
   1064     mm_camera_obj_t *my_obj = NULL;
   1065     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1066 
   1067     LOGD("E camera_handle = %d, ch_id = %d",
   1068           camera_handle, ch_id);
   1069 
   1070     if(my_obj) {
   1071         pthread_mutex_lock(&my_obj->cam_lock);
   1072         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1073         rc = mm_camera_map_stream_bufs(my_obj, ch_id, buf_map_list);
   1074     }else{
   1075         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1076     }
   1077     return rc;
   1078 }
   1079 
   1080 /*===========================================================================
   1081  * FUNCTION   : mm_camera_muxer_unmap_stream_buf
   1082  *
   1083  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1084  *
   1085  * PARAMETERS :
   1086  *   @camera_handle: camera handle
   1087  *   @ch_id        : channel handle
   1088  *   @s_id         : stream handle
   1089  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1090  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1091  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1092  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1093  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1094  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1095  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1096  *   @plane_idx    : plane index. If all planes share the same fd,
   1097  *                   plane_idx = -1; otherwise, plean_idx is the
   1098  *                   index to plane (0..num_of_planes)
   1099  *
   1100  * RETURN     : int32_t type of status
   1101  *              0  -- success
   1102  *              -1 -- failure
   1103  *==========================================================================*/
   1104 int32_t mm_camera_muxer_unmap_stream_buf(uint32_t camera_handle,
   1105         uint32_t ch_id, uint32_t stream_id,
   1106         uint8_t buf_type, uint32_t buf_idx,
   1107         int32_t plane_idx, mm_camera_obj_t *cam_obj)
   1108 {
   1109     int32_t rc = -1;
   1110     mm_camera_obj_t * my_obj = NULL;
   1111     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1112 
   1113     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1114           camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1115 
   1116     if(my_obj) {
   1117         pthread_mutex_lock(&my_obj->cam_lock);
   1118         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1119         rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
   1120                 buf_type, buf_idx, plane_idx);
   1121     } else{
   1122         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1123     }
   1124     return rc;
   1125 }
   1126 
   1127 /*===========================================================================
   1128  * FUNCTION   : mm_camera_muxer_set_stream_parms
   1129  *
   1130  * DESCRIPTION: set parameters per stream
   1131  *
   1132  * PARAMETERS :
   1133  *   @camera_handle: camera handle
   1134  *   @ch_id        : channel handle
   1135  *   @s_id         : stream handle
   1136  *   @parms        : ptr to a param struct to be set to server
   1137  *
   1138  * RETURN     : int32_t type of status
   1139  *              0  -- success
   1140  *              -1 -- failure
   1141  *==========================================================================*/
   1142 int32_t mm_camera_muxer_set_stream_parms(uint32_t camera_handle,
   1143         uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
   1144         mm_camera_obj_t *cam_obj)
   1145 {
   1146     int32_t rc = 0;
   1147     mm_camera_obj_t * my_obj = NULL;
   1148     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1149 
   1150     if(my_obj) {
   1151         pthread_mutex_lock(&my_obj->cam_lock);
   1152         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1153         rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
   1154     } else{
   1155         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1156     }
   1157     return rc;
   1158 }
   1159 
   1160 /*===========================================================================
   1161  * FUNCTION   : mm_camera_muxer_get_stream_parms
   1162  *
   1163  * DESCRIPTION: get parameters per stream
   1164  *
   1165  * PARAMETERS :
   1166  *   @camera_handle: camera handle
   1167  *   @ch_id        : channel handle
   1168  *   @s_id         : stream handle
   1169  *   @parms        : ptr to a param struct to be get from server
   1170  *
   1171  * RETURN     : int32_t type of status
   1172  *              0  -- success
   1173  *              -1 -- failure
   1174  *==========================================================================*/
   1175 int32_t mm_camera_muxer_get_stream_parms(uint32_t camera_handle,
   1176         uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
   1177         mm_camera_obj_t *cam_obj)
   1178 {
   1179     int32_t rc = 0;
   1180     mm_camera_obj_t * my_obj = NULL;
   1181     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1182 
   1183     if(my_obj) {
   1184         pthread_mutex_lock(&my_obj->cam_lock);
   1185         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1186         rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
   1187     } else{
   1188         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1189     }
   1190     return rc;
   1191 }
   1192 
   1193 /*===========================================================================
   1194  * FUNCTION   : mm_camera_muxer_start_channel
   1195  *
   1196  * DESCRIPTION: start a channel, which will start all streams in the channel
   1197  *
   1198  * PARAMETERS :
   1199  *   @camera_handle: camera handle
   1200  *   @ch_id        : channel handle
   1201  *
   1202  * RETURN     : int32_t type of status
   1203  *              0  -- success
   1204  *              -1 -- failure
   1205  *==========================================================================*/
   1206 int32_t mm_camera_muxer_start_channel(uint32_t camera_handle,
   1207         uint32_t ch_id, mm_camera_obj_t *cam_obj)
   1208 {
   1209     int32_t rc = 0;
   1210     mm_camera_obj_t * my_obj = NULL;
   1211     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1212 
   1213     if(my_obj) {
   1214         pthread_mutex_lock(&my_obj->cam_lock);
   1215         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1216         rc = mm_camera_start_channel(my_obj, ch_id);
   1217         if (rc == 0) {
   1218             rc = mm_camera_start_sensor_stream_on(my_obj, ch_id);
   1219         }
   1220     } else{
   1221         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1222     }
   1223     return rc;
   1224 }
   1225 
   1226 /*===========================================================================
   1227  * FUNCTION   : mm_camera_muxer_stop_channel
   1228  *
   1229  * DESCRIPTION: stop a channel, which will stop all streams in the channel
   1230  *
   1231  * PARAMETERS :
   1232  *   @camera_handle: camera handle
   1233  *   @ch_id        : channel handle
   1234  *
   1235  * RETURN     : int32_t type of status
   1236  *              0  -- success
   1237  *              -1 -- failure
   1238  *==========================================================================*/
   1239 int32_t mm_camera_muxer_stop_channel(uint32_t camera_handle,
   1240         uint32_t ch_id, mm_camera_obj_t *cam_obj)
   1241 {
   1242     int32_t rc = 0;
   1243     mm_camera_obj_t * my_obj = NULL;
   1244     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1245 
   1246     if(my_obj) {
   1247         pthread_mutex_lock(&my_obj->cam_lock);
   1248         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1249         rc = mm_camera_stop_channel(my_obj, ch_id, /*stop_immediately*/FALSE);
   1250     } else{
   1251         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1252     }
   1253     return rc;
   1254 }
   1255 
   1256 /*===========================================================================
   1257  * FUNCTION   : mm_camera_intf_qbuf
   1258  *
   1259  * DESCRIPTION: enqueue buffer back to kernel
   1260  *
   1261  * PARAMETERS :
   1262  *   @camera_handle: camera handle
   1263  *   @ch_id        : channel handle
   1264  *   @buf          : buf ptr to be enqueued
   1265  *
   1266  * RETURN     : int32_t type of status
   1267  *              0  -- success
   1268  *              -1 -- failure
   1269  *==========================================================================*/
   1270 int32_t mm_camera_muxer_qbuf(uint32_t camera_handle, uint32_t ch_id,
   1271         mm_camera_buf_def_t *buf, mm_camera_obj_t *cam_obj)
   1272 {
   1273     int32_t rc = 0;
   1274     mm_camera_obj_t * my_obj = NULL;
   1275 
   1276     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1277     if(my_obj) {
   1278         pthread_mutex_lock(&my_obj->cam_lock);
   1279         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1280         rc = mm_camera_qbuf(my_obj, ch_id, buf);
   1281     } else {
   1282         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1283     }
   1284     return rc;
   1285 }
   1286 
   1287 /*===========================================================================
   1288  * FUNCTION   : mm_camera_muxer_get_queued_buf_count
   1289  *
   1290  * DESCRIPTION: returns the queued buffer count
   1291  *
   1292  * PARAMETERS :
   1293  *   @camera_handle: camera handle
   1294  *   @ch_id        : channel handle
   1295  *   @stream_id : stream id
   1296  *
   1297  * RETURN     : int32_t - queued buffer count
   1298  *
   1299  *==========================================================================*/
   1300 int32_t mm_camera_muxer_get_queued_buf_count(uint32_t camera_handle,
   1301         uint32_t ch_id, uint32_t stream_id,
   1302         mm_camera_obj_t *cam_obj)
   1303 {
   1304     int32_t rc = 0;
   1305     mm_camera_obj_t * my_obj = NULL;
   1306 
   1307     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1308     if(my_obj) {
   1309         pthread_mutex_lock(&my_obj->cam_lock);
   1310         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1311         rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
   1312     } else {
   1313         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1314     }
   1315     return rc;
   1316 }
   1317 
   1318 /*===========================================================================
   1319  * FUNCTION   : mm_camera_muxer_request_super_buf
   1320  *
   1321  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1322  *              frames from superbuf queue
   1323  *
   1324  * PARAMETERS :
   1325  *   @ch_id             : channel handle
   1326  *   @buf                : request buffer info
   1327  *
   1328  * RETURN     : int32_t type of status
   1329  *              0  -- success
   1330  *              -1 -- failure
   1331  *==========================================================================*/
   1332 int32_t mm_camera_muxer_request_super_buf(uint32_t ch_id,
   1333         mm_camera_req_buf_t *buf, mm_camera_obj_t *cam_obj)
   1334 {
   1335     int32_t rc = 0;
   1336     mm_camera_obj_t * my_obj = cam_obj;
   1337     uint32_t chID = get_main_camera_handle(ch_id);
   1338 
   1339     if(my_obj && buf) {
   1340         pthread_mutex_lock(&my_obj->cam_lock);
   1341         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1342         buf->type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
   1343         rc = mm_camera_request_super_buf (my_obj, chID, buf);
   1344     } else {
   1345         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1346     }
   1347     return rc;
   1348 }
   1349 
   1350 /*===========================================================================
   1351  * FUNCTION   : mm_camera_muxer_cancel_super_buf_request
   1352  *
   1353  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1354  *              frames from superbuf queue
   1355  *
   1356  * PARAMETERS :
   1357  *   @camera_handle: camera handle
   1358  *   @ch_id             : channel handle
   1359  *   @buf                : request buffer info
   1360  *
   1361  * RETURN     : int32_t type of status
   1362  *              0  -- success
   1363  *              -1 -- failure
   1364  *==========================================================================*/
   1365 int32_t mm_camera_muxer_cancel_super_buf_request(uint32_t camera_handle,
   1366         uint32_t ch_id,
   1367         mm_camera_obj_t *cam_obj)
   1368 {
   1369     int32_t rc = 0;
   1370     mm_camera_obj_t * my_obj = NULL;
   1371     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1372     uint32_t aux_chID = get_main_camera_handle(ch_id);
   1373 
   1374     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1375     if(my_obj) {
   1376         pthread_mutex_lock(&my_obj->cam_lock);
   1377         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1378         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
   1379     } else {
   1380         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1381     }
   1382 
   1383     my_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
   1384     if(my_obj) {
   1385         pthread_mutex_lock(&my_obj->cam_lock);
   1386         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1387         rc = mm_camera_cancel_super_buf_request(my_obj, aux_chID);
   1388     } else {
   1389         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1390     }
   1391     return rc;
   1392 }
   1393 
   1394 /*===========================================================================
   1395  * FUNCTION   : mm_camera_muxer_flush_super_buf_queue
   1396  *
   1397  * DESCRIPTION: flush out all frames in the superbuf queue
   1398  *
   1399  * PARAMETERS :
   1400  *   @camera_handle: camera handle
   1401  *   @ch_id        : channel handle
   1402  *   @frame_idx    : frame index
   1403  *
   1404  * RETURN     : int32_t type of status
   1405  *              0  -- success
   1406  *              -1 -- failure
   1407  *==========================================================================*/
   1408 int32_t mm_camera_muxer_flush_super_buf_queue(uint32_t camera_handle,
   1409         uint32_t ch_id,
   1410         uint32_t frame_idx, mm_camera_obj_t *cam_obj)
   1411 {
   1412     int32_t rc = 0;
   1413     mm_camera_obj_t * my_obj = NULL;
   1414     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1415 
   1416     if(my_obj) {
   1417             pthread_mutex_lock(&my_obj->cam_lock);
   1418             pthread_mutex_unlock(&cam_obj->muxer_lock);
   1419             rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
   1420     } else {
   1421         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1422     }
   1423     return rc;
   1424 }
   1425 
   1426 /*===========================================================================
   1427  * FUNCTION   : mm_camera_muxer_configure_notify_mode
   1428  *
   1429  * DESCRIPTION: Configures channel notification mode
   1430  *
   1431  * PARAMETERS :
   1432  *   @camera_handle: camera handle
   1433  *   @ch_id        : channel handle
   1434  *   @notify_mode  : notification mode
   1435  *
   1436  * RETURN     : int32_t type of status
   1437  *              0  -- success
   1438  *              -1 -- failure
   1439  *==========================================================================*/
   1440 int32_t mm_camera_muxer_configure_notify_mode(uint32_t camera_handle,
   1441         uint32_t ch_id, mm_camera_super_buf_notify_mode_t notify_mode,
   1442         mm_camera_obj_t *cam_obj)
   1443 {
   1444     int32_t rc = 0;
   1445     mm_camera_obj_t * my_obj = NULL;
   1446     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1447 
   1448     if(my_obj) {
   1449             pthread_mutex_lock(&my_obj->cam_lock);
   1450             pthread_mutex_unlock(&cam_obj->muxer_lock);
   1451             rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
   1452     } else {
   1453         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1454     }
   1455     return rc;
   1456 }
   1457 
   1458 /*===========================================================================
   1459  * FUNCTION   : mm_camera_muxer_process_advanced_capture
   1460  *
   1461  * DESCRIPTION: Configures channel advanced capture mode
   1462  *
   1463  * PARAMETERS :
   1464  *   @camera_handle: camera handle
   1465  *   @type : advanced capture type
   1466  *   @ch_id        : channel handle
   1467  *   @trigger  : 1 for start and 0 for cancel/stop
   1468  *   @value  : input capture configaration
   1469  *
   1470  * RETURN     : int32_t type of status
   1471  *              0  -- success
   1472  *              -1 -- failure
   1473  *==========================================================================*/
   1474 int32_t mm_camera_muxer_process_advanced_capture(uint32_t camera_handle,
   1475          uint32_t ch_id, mm_camera_advanced_capture_t type,
   1476          int8_t start_flag, void *in_value, mm_camera_obj_t *cam_obj)
   1477 {
   1478     int32_t rc = 0;
   1479     mm_camera_obj_t * my_obj = NULL;
   1480 
   1481     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1482     if(my_obj) {
   1483         pthread_mutex_lock(&my_obj->cam_lock);
   1484         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1485         rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
   1486                 (uint32_t)start_flag, in_value);
   1487     } else {
   1488         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1489     }
   1490     return rc;
   1491 }
   1492 
   1493 /*===========================================================================
   1494  * FUNCTION   : mm_camera_muxer_get_session_id
   1495  *
   1496  * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
   1497  *
   1498  * PARAMETERS :
   1499  *   @camera_handle: camera handle
   1500  *   @sessionid: session id to be retrieved from server
   1501  *
   1502  * RETURN     : int32_t type of status
   1503  *              0  -- success
   1504  *              -1 -- failure
   1505  *==========================================================================*/
   1506 int32_t mm_camera_muxer_get_session_id(uint32_t camera_handle,
   1507         uint32_t* sessionid, mm_camera_obj_t *cam_obj)
   1508 {
   1509     int32_t rc = 0;
   1510     mm_camera_obj_t * my_obj = NULL;
   1511     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1512 
   1513     if(my_obj) {
   1514         pthread_mutex_lock(&my_obj->cam_lock);
   1515         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1516         *sessionid = my_obj->sessionid;
   1517         pthread_mutex_unlock(&my_obj->cam_lock);
   1518         rc = 0;
   1519     } else {
   1520         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1521     }
   1522     return rc;
   1523 }
   1524 
   1525  /*===========================================================================
   1526  * FUNCTION   : mm_camera_muxer_flush
   1527  *
   1528  * DESCRIPTION: flush the current camera state and buffers
   1529  *
   1530  * PARAMETERS :
   1531  *   @camera_handle: camera handle
   1532  *
   1533  * RETURN     : int32_t type of status
   1534  *              0  -- success
   1535  *              -1 -- failure
   1536  *==========================================================================*/
   1537 int32_t mm_camera_muxer_flush(uint32_t camera_handle, mm_camera_obj_t *cam_obj)
   1538 {
   1539     int32_t rc = 0;
   1540     mm_camera_obj_t * my_obj = NULL;
   1541     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1542 
   1543     if(my_obj) {
   1544         pthread_mutex_lock(&my_obj->cam_lock);
   1545         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1546         rc = mm_camera_flush(my_obj);
   1547     } else {
   1548         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1549     }
   1550     return rc;
   1551 }
   1552 
   1553 /*===========================================================================
   1554  * FUNCTION   : mm_camera_muxer_register_stream_buf_cb
   1555  *
   1556  * DESCRIPTION: Register special callback for stream buffer
   1557  *
   1558  * PARAMETERS :
   1559  *   @camera_handle: camera handle
   1560  *   @ch_id        : channel handle
   1561  *   @stream_id    : stream handle
   1562  *   @buf_cb       : callback function
   1563  *   @buf_type     :SYNC/ASYNC
   1564  *   @userdata     : userdata pointer
   1565  *
   1566  * RETURN     : int32_t type of status
   1567  *              0  -- success
   1568  *              1 -- failure
   1569  *==========================================================================*/
   1570 int32_t mm_camera_muxer_register_stream_buf_cb(uint32_t camera_handle,
   1571         uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
   1572         mm_camera_stream_cb_type cb_type, void *userdata, mm_camera_obj_t *cam_obj)
   1573 {
   1574     int32_t rc = 0;
   1575     mm_camera_obj_t * my_obj = NULL;
   1576     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1577 
   1578     if(my_obj) {
   1579         pthread_mutex_lock(&my_obj->cam_lock);
   1580         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1581         rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
   1582                 buf_cb, cb_type, userdata);
   1583     } else {
   1584         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1585     }
   1586     return rc;
   1587 }
   1588 
   1589 /*===========================================================================
   1590  * FUNCTION   : mm_camera_muxer_reg_frame_sync
   1591  *
   1592  * DESCRIPTION: Configure for frame sync.
   1593  *
   1594  * PARAMETERS :
   1595  *   @camera_handle: camera handle
   1596  *   @ch_id        : channel handle
   1597  *   @stream_id    : stream handle
   1598  *   @sync_attr    : Attributes for frame sync
   1599  *
   1600  * RETURN     : int32_t type of status
   1601  *              0  -- success
   1602  *              1 -- failure
   1603  *==========================================================================*/
   1604 int32_t mm_camera_muxer_reg_frame_sync(mm_camera_obj_t *cam_obj,
   1605         uint32_t ch_id, uint32_t stream_id,
   1606         mm_camera_intf_frame_sync_t *sync_attr)
   1607 {
   1608     int32_t rc = 0;
   1609     mm_camera_obj_t *a_cam_obj = NULL;
   1610 
   1611     mm_camera_frame_sync_t frame_sync;
   1612     if (sync_attr == NULL || cam_obj == NULL) {
   1613         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1614         return rc;
   1615     }
   1616 
   1617     uint32_t chid = get_main_camera_handle(ch_id);
   1618     uint32_t aux_handle = get_aux_camera_handle(sync_attr->camera_handle);
   1619     uint32_t aux_chid = get_aux_camera_handle(sync_attr->ch_id);
   1620     uint32_t strid = 0;
   1621     uint32_t aux_strid = 0;
   1622     if (stream_id) {
   1623         LOGD("Stream frame sync enabled");
   1624         strid = get_main_camera_handle(stream_id);
   1625         aux_strid = get_aux_camera_handle(sync_attr->stream_id);
   1626         if(aux_strid == 0) {
   1627             aux_handle = get_main_camera_handle(sync_attr->camera_handle);
   1628             aux_chid = get_main_camera_handle(sync_attr->ch_id);
   1629             aux_strid = get_main_camera_handle(sync_attr->stream_id);
   1630         }
   1631     } else {
   1632         LOGD("Channel frame sync enabled");
   1633         if(aux_chid == 0) {
   1634             aux_chid = get_main_camera_handle(sync_attr->ch_id);
   1635         }
   1636     }
   1637     a_cam_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
   1638 
   1639     if(a_cam_obj) {
   1640         memset(&frame_sync, 0, sizeof(frame_sync));
   1641         frame_sync.a_cam_obj = a_cam_obj;
   1642         frame_sync.a_stream_id = aux_strid;
   1643         frame_sync.a_ch_id = aux_chid;
   1644         frame_sync.userdata = sync_attr->userdata;
   1645         frame_sync.buf_cb = sync_attr->buf_cb;
   1646         frame_sync.attr = sync_attr->attr;
   1647         pthread_mutex_lock(&cam_obj->cam_lock);
   1648         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1649         rc = mm_camera_reg_frame_sync(cam_obj, chid, strid, &frame_sync);
   1650     } else {
   1651         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1652     }
   1653     return rc;
   1654 }
   1655 
   1656 /*===========================================================================
   1657  * FUNCTION   : mm_camera_muxer_set_dual_cam_cmd
   1658  *
   1659  * DESCRIPTION: send event to trigger read on dual camera cmd buffer
   1660  *
   1661  * PARAMETERS :
   1662  *   @camera_handle: camera handle
   1663  *   @cam_obj        : header object
   1664  *
   1665  * RETURN     : int32_t type of status
   1666  *              0  -- success
   1667  *              1 -- failure
   1668  *==========================================================================*/
   1669 int32_t mm_camera_muxer_set_dual_cam_cmd(uint32_t camera_handle,
   1670         mm_camera_obj_t *cam_obj)
   1671 {
   1672     int32_t rc = 0;
   1673     mm_camera_obj_t * my_obj = NULL;
   1674     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1675 
   1676     if(my_obj) {
   1677         pthread_mutex_lock(&my_obj->cam_lock);
   1678         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1679         rc = mm_camera_set_dual_cam_cmd(my_obj);
   1680     } else {
   1681         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1682     }
   1683     return rc;
   1684 }
   1685 
   1686 /*===========================================================================
   1687  * FUNCTION   : mm_camera_muxer_stream_frame_sync
   1688  *
   1689  * DESCRIPTION: Handle stream buffers for frame sync
   1690  *
   1691  * PARAMETERS :
   1692  *   @super_buf: Stream buffers
   1693  *   @user_data        : Stream object
   1694  *
   1695  * RETURN     : none
   1696  *==========================================================================*/
   1697 void mm_camera_muxer_stream_frame_sync(mm_camera_super_buf_t *super_buf,
   1698         void *user_data)
   1699 {
   1700     int32_t rc = 0, i = 0;
   1701     mm_stream_t *my_obj = (mm_stream_t *)user_data;
   1702     mm_frame_sync_queue_node_t dispatch_buf;
   1703 
   1704     if ((super_buf == NULL) || (super_buf->num_bufs == 0)) {
   1705         return;
   1706     }
   1707 
   1708     if (my_obj->master_str_obj != NULL) {
   1709         my_obj = my_obj->master_str_obj;
   1710     }
   1711 
   1712     memset(&dispatch_buf, 0, sizeof(dispatch_buf));
   1713     rc = mm_camera_muxer_do_frame_sync(&my_obj->frame_sync.superbuf_queue,
   1714             super_buf, &dispatch_buf);
   1715     if (rc < 0) {
   1716         LOGE("frame sync failed");
   1717         return;
   1718     }
   1719 
   1720     if (my_obj->frame_sync.super_buf_notify_cb && dispatch_buf.num_objs > 0) {
   1721         mm_camera_super_buf_t super_buf;
   1722         memset(&super_buf, 0, sizeof(super_buf));
   1723         for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   1724             if (dispatch_buf.super_buf[i].num_bufs == 1) {
   1725                 super_buf.bufs[super_buf.num_bufs++] =
   1726                         dispatch_buf.super_buf[i].bufs[0];
   1727                 super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
   1728                 super_buf.ch_id = my_obj->ch_obj->my_hdl;
   1729             }
   1730         }
   1731         pthread_mutex_lock(&my_obj->cb_lock);
   1732         my_obj->frame_sync.super_buf_notify_cb(&super_buf,
   1733                 my_obj->frame_sync.user_data);
   1734         pthread_mutex_unlock(&my_obj->cb_lock);
   1735     }
   1736 }
   1737 
   1738 /*===========================================================================
   1739  * FUNCTION   : mm_camera_muxer_channel_frame_sync
   1740  *
   1741  * DESCRIPTION: Handle channel super buffers for frame sync
   1742  *
   1743  * PARAMETERS :
   1744  *   @super_buf: channel buffers
   1745  *   @user_data        : channel object
   1746  *
   1747  * RETURN     : none
   1748  *==========================================================================*/
   1749 void mm_camera_muxer_channel_frame_sync(mm_camera_super_buf_t *super_buf,
   1750         void *user_data)
   1751 {
   1752     int32_t rc = 0;
   1753     mm_channel_t *ch_obj = (mm_channel_t *)user_data;
   1754     mm_channel_t *m_obj = ch_obj;
   1755 
   1756     if ((super_buf == NULL) || (super_buf->num_bufs == 0)) {
   1757         return;
   1758     }
   1759 
   1760     if (m_obj->master_ch_obj != NULL) {
   1761         m_obj = m_obj->master_ch_obj;
   1762     }
   1763 
   1764     rc = mm_camera_muxer_do_frame_sync(&m_obj->frame_sync.superbuf_queue,
   1765             super_buf, NULL);
   1766     mm_camera_muxer_channel_req_data_cb(NULL,
   1767                 ch_obj);
   1768 }
   1769 
   1770 
   1771 /*===========================================================================
   1772  * FUNCTION   : mm_camera_muxer_channel_req_data_cb
   1773  *
   1774  * DESCRIPTION: Issue super buffer callback based on request setting
   1775  *
   1776  * PARAMETERS :
   1777  *   @req_buf: buffer request setting
   1778  *   @ch_obj        : channel object
   1779  *
   1780  * RETURN     : none
   1781  *==========================================================================*/
   1782 int32_t mm_camera_muxer_channel_req_data_cb(mm_camera_req_buf_t *req_buf,
   1783         mm_channel_t *ch_obj)
   1784 {
   1785     int32_t rc = 0, i;
   1786     mm_channel_t *m_obj = (mm_channel_t *)ch_obj;
   1787     mm_frame_sync_queue_node_t* super_obj = NULL;
   1788     mm_frame_sync_t *frame_sync = NULL;
   1789     uint8_t trigger_cb = 0;
   1790 
   1791     if (m_obj->master_ch_obj != NULL) {
   1792         m_obj = m_obj->master_ch_obj;
   1793     }
   1794 
   1795     frame_sync = &m_obj->frame_sync;
   1796     if (req_buf != NULL) {
   1797         frame_sync->req_buf.num_buf_requested +=
   1798                 req_buf->num_buf_requested;
   1799         frame_sync->req_buf.type = req_buf->type;
   1800     }
   1801 
   1802     while ((frame_sync->req_buf.num_buf_requested > 0)
   1803             || (frame_sync->superbuf_queue.attr.notify_mode ==
   1804             MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS)) {
   1805         super_obj = mm_camera_muxer_frame_sync_dequeue(
   1806                 &frame_sync->superbuf_queue, frame_sync->req_buf.type);
   1807         if (super_obj == NULL) {
   1808             break;
   1809         }
   1810         if (frame_sync->super_buf_notify_cb && super_obj->num_objs != 0) {
   1811             if (frame_sync->req_buf.type == MM_CAMERA_REQ_FRAME_SYNC_BUF) {
   1812                 for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   1813                     if (super_obj->super_buf[i].num_bufs != 0) {
   1814                         frame_sync->super_buf_notify_cb(
   1815                                 &super_obj->super_buf[i],
   1816                                 frame_sync->user_data);
   1817                     }
   1818                 }
   1819                 trigger_cb = 1;
   1820             } else {
   1821                 for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   1822                     if (super_obj->super_buf[i].num_bufs != 0) {
   1823                         if (super_obj->super_buf[i].ch_id ==
   1824                                 ch_obj->my_hdl) {
   1825                             frame_sync->super_buf_notify_cb(
   1826                                     &super_obj->super_buf[i],
   1827                                     frame_sync->user_data);
   1828                             trigger_cb = 1;
   1829                         } else {
   1830                             mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
   1831                         }
   1832                     }
   1833                 }
   1834             }
   1835             if ((m_obj->frame_sync.req_buf.num_buf_requested > 0)
   1836                     && trigger_cb) {
   1837                 m_obj->frame_sync.req_buf.num_buf_requested--;
   1838             }
   1839         }
   1840         free(super_obj);
   1841     }
   1842     return rc;
   1843 }
   1844 
   1845 /*===========================================================================
   1846  * FUNCTION   : mm_camera_muxer_frame_sync_dequeue
   1847  *
   1848  * DESCRIPTION: dequeue object from frame sync queue
   1849  *
   1850  * PARAMETERS :
   1851  *   @queue: ptr to queue to dequeue object
   1852  *
   1853  * RETURN     : ptr to a node from superbuf queue
   1854  *==========================================================================*/
   1855 mm_frame_sync_queue_node_t *mm_camera_muxer_frame_sync_dequeue(
   1856         mm_frame_sync_queue_t *queue, uint8_t matched_only)
   1857 {
   1858     cam_node_t* node = NULL;
   1859     struct cam_list *head = NULL;
   1860     struct cam_list *pos = NULL;
   1861     mm_frame_sync_queue_node_t* super_buf = NULL;
   1862 
   1863     pthread_mutex_lock(&queue->que.lock);
   1864     head = &queue->que.head.list;
   1865     pos = head->next;
   1866     if (pos != head) {
   1867         /* get the first node */
   1868         node = member_of(pos, cam_node_t, list);
   1869         super_buf = (mm_frame_sync_queue_node_t*)node->data;
   1870         if ( (NULL != super_buf) &&
   1871              (matched_only == TRUE) &&
   1872              (super_buf->matched == FALSE) ) {
   1873             super_buf = NULL;
   1874         }
   1875 
   1876         if (NULL != super_buf) {
   1877             queue->que.size--;
   1878             cam_list_del_node(&node->list);
   1879             free(node);
   1880             if (super_buf->matched) {
   1881                 queue->match_cnt--;
   1882             }
   1883         }
   1884     }
   1885     pthread_mutex_unlock(&queue->que.lock);
   1886     return super_buf;
   1887 }
   1888 
   1889 /*===========================================================================
   1890  * FUNCTION   : mm_camera_muxer_do_frame_sync
   1891  *
   1892  * DESCRIPTION: function to process object buffers and match with existing frames.
   1893  *
   1894  * PARAMETERS :
   1895  *   @queue: ptr to queue to dequeue object
   1896  *   @buffer: Input buffer to match and insert
   1897  *   @dispatch_buf        : Ptr to carry matched node
   1898  *
   1899  * RETURN     : int32_t type of status
   1900  *              0  -- success
   1901  *              1 -- failure
   1902  *==========================================================================*/
   1903 int32_t mm_camera_muxer_do_frame_sync(
   1904         mm_frame_sync_queue_t *queue, mm_camera_super_buf_t *buffer,
   1905         mm_frame_sync_queue_node_t *dispatch_buf)
   1906 {
   1907     cam_node_t* node = NULL;
   1908     uint8_t buf_s_idx, i, found_super_buf, unmatched_bundles;
   1909     struct cam_list *head = NULL;
   1910     struct cam_list *pos = NULL;
   1911     mm_frame_sync_queue_node_t* super_obj = NULL;
   1912     struct cam_list *last_buf = NULL, *insert_before_buf = NULL;
   1913 
   1914     if (buffer == NULL || buffer->num_bufs == 0) {
   1915         LOGW("Ivalid Argument");
   1916         return -1;
   1917     }
   1918 
   1919     for (buf_s_idx = 0; buf_s_idx < queue->num_objs; buf_s_idx++) {
   1920         if ((buffer->ch_id == queue->bundled_objs[buf_s_idx]) ||
   1921                 (buffer->bufs[0]->stream_id == queue->bundled_objs[buf_s_idx])) {
   1922             break;
   1923         }
   1924     }
   1925     if (buf_s_idx == queue->num_objs) {
   1926         LOGE("buf from stream (%d) not bundled", buffer->bufs[0]->stream_id);
   1927         mm_camera_muxer_buf_done(buffer);
   1928         return -1;
   1929     }
   1930 
   1931     if (buffer->bufs[0]->frame_idx <= queue->expected_frame_id) {
   1932         LOGD("old frame. Need to release");
   1933         mm_camera_muxer_buf_done(buffer);
   1934         return 0;
   1935     }
   1936 
   1937     pthread_mutex_lock(&queue->que.lock);
   1938     head = &queue->que.head.list;
   1939     pos = head->next;
   1940     found_super_buf = 0;
   1941     unmatched_bundles = 0;
   1942     last_buf = NULL;
   1943     insert_before_buf = NULL;
   1944 
   1945     while (pos != head) {
   1946         node = member_of(pos, cam_node_t, list);
   1947         super_obj = (mm_frame_sync_queue_node_t *)node->data;
   1948         if (NULL != super_obj) {
   1949             if (super_obj->matched == 1) {
   1950                 /* find a matched super buf, move to next one */
   1951                 pos = pos->next;
   1952                 continue;
   1953             } else if (buffer->bufs[0]->frame_idx == super_obj->frame_idx) {
   1954                 found_super_buf = 1;
   1955                 break;
   1956             } else if ((buffer->bufs[0]->frame_idx >= super_obj->frame_idx)
   1957                     && (queue->attr.priority ==
   1958                     MM_CAMERA_SUPER_BUF_PRIORITY_LOW)) {
   1959                 found_super_buf = 1;
   1960                 break;
   1961             } else {
   1962                 unmatched_bundles++;
   1963                 if ( NULL == last_buf ) {
   1964                     if ( super_obj->frame_idx < buffer->bufs[0]->frame_idx) {
   1965                         last_buf = pos;
   1966                     }
   1967                 }
   1968                 if ( NULL == insert_before_buf ) {
   1969                     if ( super_obj->frame_idx > buffer->bufs[0]->frame_idx) {
   1970                         insert_before_buf = pos;
   1971                     }
   1972                 }
   1973                 pos = pos->next;
   1974             }
   1975         }
   1976     }
   1977 
   1978     LOGD("found_super_buf = %d id = %d unmatched cnt = %d match cnt = %d expected = %d max = %d",
   1979             found_super_buf,
   1980             buffer->bufs[0]->frame_idx, unmatched_bundles,
   1981             queue->match_cnt, queue->expected_frame_id,
   1982             queue->attr.max_unmatched_frames);
   1983     if (found_super_buf) {
   1984         super_obj->super_buf[buf_s_idx] = *buffer;
   1985         super_obj->num_objs++;
   1986         if (super_obj->num_objs == queue->num_objs) {
   1987             super_obj->matched = 1;
   1988             queue->expected_frame_id = super_obj->frame_idx;
   1989             if (dispatch_buf != NULL) {
   1990                 *dispatch_buf = *super_obj;
   1991                 queue->que.size--;
   1992                 cam_list_del_node(&node->list);
   1993                 free(node);
   1994                 free(super_obj);
   1995             } else {
   1996                 queue->match_cnt++;
   1997             }
   1998         }
   1999         /* Any older unmatched buffer need to be released */
   2000         if ( last_buf ) {
   2001             while (last_buf != pos ) {
   2002                 node = member_of(last_buf, cam_node_t, list);
   2003                 super_obj = (mm_frame_sync_queue_node_t*)node->data;
   2004                 if (NULL != super_obj) {
   2005                     for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   2006                         if (super_obj->super_buf[i].num_bufs != 0) {
   2007                             mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
   2008                         }
   2009                     }
   2010                     queue->que.size--;
   2011                     last_buf = last_buf->next;
   2012                     cam_list_del_node(&node->list);
   2013                     free(node);
   2014                     free(super_obj);
   2015                 }
   2016             }
   2017         }
   2018     } else {
   2019         if ((queue->attr.max_unmatched_frames < unmatched_bundles)
   2020                 && (NULL == last_buf)) {
   2021             //incoming frame is older than the last bundled one
   2022             mm_camera_muxer_buf_done(buffer);
   2023             pthread_mutex_unlock(&queue->que.lock);
   2024             return 0;
   2025         } else if (queue->attr.max_unmatched_frames < unmatched_bundles) {
   2026             //dispatch old buffer. Cannot sync for configured unmatch value
   2027             node = member_of(last_buf, cam_node_t, list);
   2028             super_obj = (mm_frame_sync_queue_node_t*)node->data;
   2029             if (super_obj != NULL) {
   2030                 queue->expected_frame_id = super_obj->frame_idx;
   2031                 if (dispatch_buf != NULL) {
   2032                     //Dispatch unmatched buffer
   2033                     *dispatch_buf = *super_obj;
   2034                 } else {
   2035                     //release unmatched buffers
   2036                     for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   2037                         if (super_obj->super_buf[i].num_bufs != 0) {
   2038                             mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
   2039                         }
   2040                     }
   2041                 }
   2042             }
   2043             queue->que.size--;
   2044             cam_list_del_node(&node->list);
   2045             free(node);
   2046             free(super_obj);
   2047             super_obj = NULL;
   2048         }
   2049 
   2050         //insert the new frame at the appropriate position.
   2051         mm_frame_sync_queue_node_t *new_buf = NULL;
   2052         cam_node_t* new_node = NULL;
   2053         new_buf = (mm_frame_sync_queue_node_t *)
   2054                 malloc(sizeof(mm_frame_sync_queue_node_t));
   2055         if (NULL != new_buf) {
   2056             memset(new_buf, 0, sizeof(mm_frame_sync_queue_node_t));
   2057             new_buf->super_buf[buf_s_idx] = *buffer;
   2058             new_buf->num_objs++;
   2059             new_buf->frame_idx = buffer->bufs[0]->frame_idx;
   2060             new_buf->matched = 0;
   2061             if (new_buf->num_objs == queue->num_objs && super_obj) {
   2062                 new_buf->matched = 1;
   2063                 queue->expected_frame_id = super_obj->frame_idx;
   2064                 if (dispatch_buf != NULL) {
   2065                     *dispatch_buf = *new_buf;
   2066                     queue->que.size--;
   2067                     free(new_buf);
   2068                     free(new_node);
   2069                 } else {
   2070                     queue->match_cnt++;
   2071                 }
   2072             } else {
   2073                 /* enqueue */
   2074                 new_node = (cam_node_t *)malloc(sizeof(cam_node_t));
   2075                 if (new_node != NULL) {
   2076                     memset(new_node, 0, sizeof(cam_node_t));
   2077                     new_node->data = (void *)new_buf;
   2078                     if ( insert_before_buf ) {
   2079                         cam_list_insert_before_node(&new_node->list, insert_before_buf);
   2080                     } else {
   2081                         cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
   2082                     }
   2083                     queue->que.size++;
   2084                 } else {
   2085                     LOGE("Out of memory");
   2086                     free(new_buf);
   2087                     mm_camera_muxer_buf_done(buffer);
   2088                 }
   2089             }
   2090         } else {
   2091             if (NULL != new_buf) {
   2092                 free(new_buf);
   2093             }
   2094             mm_camera_muxer_buf_done(buffer);
   2095         }
   2096     }
   2097     pthread_mutex_unlock(&queue->que.lock);
   2098 
   2099     /* bufdone overflowed bufs */
   2100     while (queue->match_cnt > queue->attr.water_mark) {
   2101         super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
   2102         if (NULL != super_obj) {
   2103             for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   2104                 if (super_obj->super_buf[i].num_bufs != 0) {
   2105                     mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
   2106                 }
   2107             }
   2108             free(super_obj);
   2109         }
   2110     }
   2111     return 0;
   2112 }
   2113 
   2114 /*===========================================================================
   2115  * FUNCTION   : mm_camera_muxer_buf_done
   2116  *
   2117  * DESCRIPTION: function release super buffer.
   2118  *
   2119  * PARAMETERS :
   2120  *   @buffer: ptr to super buffer to release.
   2121  *
   2122  * RETURN     : int32_t type of status
   2123  *              0  -- success
   2124  *              1 -- failure
   2125  *==========================================================================*/
   2126 void mm_camera_muxer_buf_done(mm_camera_super_buf_t *buffer)
   2127 {
   2128     uint8_t i;
   2129     mm_camera_obj_t *my_obj = NULL;
   2130 
   2131     if (buffer == NULL) {
   2132         LOGW("Null buffer");
   2133         return;
   2134     }
   2135 
   2136     my_obj = mm_camera_util_get_camera_by_handler(buffer->camera_handle);
   2137     if (my_obj != NULL) {
   2138         for (i=0; i < buffer->num_bufs; i++) {
   2139             if (buffer->bufs[i] != NULL) {
   2140                 pthread_mutex_lock(&my_obj->cam_lock);
   2141                 mm_camera_qbuf(my_obj, buffer->ch_id, buffer->bufs[i]);
   2142             }
   2143         }
   2144     }
   2145 }
   2146 
   2147 /*===========================================================================
   2148  * FUNCTION   : mm_muxer_frame_sync_queue_init
   2149  *
   2150  * DESCRIPTION: Inittialize frame sync queue
   2151  *
   2152  * PARAMETERS :
   2153  *   @queue: ptr to frame sync queue
   2154  *
   2155  * RETURN     : int32_t type of status
   2156  *              0  -- success
   2157  *              1 -- failure
   2158  *==========================================================================*/
   2159 int32_t mm_muxer_frame_sync_queue_init(mm_frame_sync_queue_t *queue)
   2160 {
   2161     int32_t rc = 0;
   2162     queue->expected_frame_id = 0;
   2163     queue->match_cnt = 0;
   2164     queue->num_objs = 0;
   2165     memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
   2166     rc = cam_queue_init(&queue->que);
   2167     return rc;
   2168 }
   2169 
   2170 /*===========================================================================
   2171  * FUNCTION   : mm_muxer_frame_sync_queue_deinit
   2172  *
   2173  * DESCRIPTION: Inittialize frame sync queue
   2174  *
   2175  * PARAMETERS :
   2176  *   @queue: ptr to frame sync queue
   2177  *
   2178  * RETURN     : int32_t type of status
   2179  *              0  -- success
   2180  *              1 -- failure
   2181  *==========================================================================*/
   2182 int32_t mm_muxer_frame_sync_queue_deinit(mm_frame_sync_queue_t *queue)
   2183 {
   2184     int32_t rc = 0;
   2185     rc = cam_queue_deinit(&queue->que);
   2186     return rc;
   2187 }
   2188 
   2189 /*===========================================================================
   2190  * FUNCTION   : mm_camera_muxer_frame_sync_flush
   2191  *
   2192  * DESCRIPTION: function to flush frame sync queue
   2193  *
   2194  * PARAMETERS :
   2195  *   @queue: ptr to frame sync queue
   2196  *
   2197  * RETURN     : int32_t type of status
   2198  *              0  -- success
   2199  *              1 -- failure
   2200  *==========================================================================*/
   2201 int32_t mm_camera_muxer_frame_sync_flush(mm_frame_sync_queue_t *queue)
   2202 {
   2203     int32_t rc = 0, i = 0;
   2204     mm_frame_sync_queue_node_t *super_obj = NULL;
   2205 
   2206     super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
   2207     while (super_obj != NULL) {
   2208         for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   2209             if (super_obj->super_buf[i].num_bufs != 0) {
   2210                 mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
   2211             }
   2212         }
   2213         free(super_obj);
   2214         super_obj = NULL;
   2215         super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
   2216     }
   2217     return rc;
   2218 }
   2219 
   2220 /*===========================================================================
   2221  * FUNCTION   : mm_camera_muxer_stream_frame_sync_flush
   2222  *
   2223  * DESCRIPTION: function to flush frame sync queue
   2224  *
   2225  * PARAMETERS :
   2226  *   @queue: ptr to frame sync queue
   2227  *
   2228  * RETURN     : int32_t type of status
   2229  *              0  -- success
   2230  *              1 -- failure
   2231  *==========================================================================*/
   2232 int32_t mm_camera_muxer_stream_frame_sync_flush(mm_stream_t *str_obj)
   2233 {
   2234     int32_t rc = 0;
   2235     mm_stream_t *my_obj = str_obj;
   2236 
   2237     if (my_obj->master_str_obj) {
   2238         my_obj = my_obj->master_str_obj;
   2239     }
   2240 
   2241     rc = mm_camera_muxer_frame_sync_flush(&my_obj->frame_sync.superbuf_queue);
   2242     return rc;
   2243 }
   2244 
   2245 /*===========================================================================
   2246  * FUNCTION   : mm_camera_muxer_channel_frame_sync_flush
   2247  *
   2248  * DESCRIPTION: function to flush frame sync queue
   2249  *
   2250  * PARAMETERS :
   2251  *   @queue: ptr to frame sync queue
   2252  *
   2253  * RETURN     : int32_t type of status
   2254  *              0  -- success
   2255  *              1 -- failure
   2256  *==========================================================================*/
   2257 int32_t mm_camera_muxer_channel_frame_sync_flush(mm_channel_t *ch_obj)
   2258 {
   2259     int32_t rc = 0;
   2260     mm_channel_t *my_obj = ch_obj;
   2261 
   2262     if (ch_obj->master_ch_obj != NULL) {
   2263         my_obj = ch_obj->master_ch_obj;
   2264     }
   2265 
   2266     rc = mm_camera_muxer_frame_sync_flush(&my_obj->frame_sync.superbuf_queue);
   2267     return rc;
   2268 }
   2269 
   2270 /*===========================================================================
   2271  * FUNCTION   : mm_camera_muxer_get_stream_buf_cnt
   2272  *
   2273  * DESCRIPTION: function to calculate buffer count for auxillary streams.
   2274  *
   2275  * PARAMETERS :
   2276  *   @queue: ptr to frame sync queue
   2277  *
   2278  * RETURN     : int32_t type of status
   2279  *              0  -- success
   2280  *              1 -- failure
   2281  *==========================================================================*/
   2282 uint32_t mm_camera_muxer_get_stream_buf_cnt(mm_stream_t *str_obj)
   2283 {
   2284     uint32_t buf_cnt = 0;
   2285     uint8_t i = 0;
   2286     mm_stream_t *my_obj = str_obj;
   2287 
   2288     if (str_obj->master_str_obj != NULL) {
   2289         my_obj = str_obj->master_str_obj;
   2290     }
   2291 
   2292     buf_cnt = my_obj->buf_num;
   2293     for (i = 0; i < my_obj->num_s_cnt; i++) {
   2294         if (my_obj->aux_str_obj[i]->is_res_shared) {
   2295             buf_cnt += my_obj->aux_str_obj[i]->buf_num;
   2296         }
   2297     }
   2298     if (buf_cnt > CAM_MAX_NUM_BUFS_PER_STREAM) {
   2299         buf_cnt = CAM_MAX_NUM_BUFS_PER_STREAM;
   2300     }
   2301     return buf_cnt;
   2302 }
   2303 
   2304 /*===========================================================================
   2305  * FUNCTION   : mm_camera_muxer_get_stream_bufs
   2306  *
   2307  * DESCRIPTION: function to assign buffers for auxillary streams.
   2308  *
   2309  * PARAMETERS :
   2310  *   @queue: ptr to frame sync queue
   2311  *
   2312  * RETURN     : int32_t type of status
   2313  *              0  -- success
   2314  *              1 -- failure
   2315  *==========================================================================*/
   2316 int32_t mm_camera_muxer_get_stream_bufs(mm_stream_t *my_obj)
   2317 {
   2318     int32_t rc = 0;
   2319     uint32_t i = 0;
   2320     mm_stream_t *master_obj = NULL;
   2321 
   2322     if (my_obj == NULL || my_obj->master_str_obj == NULL
   2323             || !my_obj->is_res_shared) {
   2324         LOGE("Invalid argument");
   2325         return rc;
   2326     }
   2327     master_obj = my_obj->master_str_obj;
   2328 
   2329     if (master_obj->total_buf_cnt == 0) {
   2330         my_obj->buf_idx = 0;
   2331         return rc;
   2332     }
   2333 
   2334     if ((master_obj->total_buf_cnt -
   2335             (master_obj->buf_idx + master_obj->buf_num))
   2336             <= 0) {
   2337         LOGE("No enough buffer available %d num_bufs = %d",
   2338                 master_obj->total_buf_cnt, master_obj->buf_num);
   2339         return rc;
   2340     }
   2341 
   2342     my_obj->total_buf_cnt = master_obj->total_buf_cnt;
   2343     my_obj->buf_idx = master_obj->buf_idx + master_obj->buf_num;
   2344     if ((my_obj->buf_idx + my_obj->buf_num) > my_obj->total_buf_cnt) {
   2345         my_obj->buf_num = my_obj->total_buf_cnt - my_obj->buf_idx;
   2346     }
   2347 
   2348     my_obj->buf = master_obj->buf;
   2349     for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
   2350         my_obj->buf_status[i].initial_reg_flag =
   2351                 master_obj->buf_status[i].initial_reg_flag;
   2352     }
   2353     LOGH("Buffer total = %d buf_cnt = %d offsset = %d",my_obj->total_buf_cnt,
   2354             my_obj->buf_num, my_obj->buf_idx);
   2355     return 0;
   2356 }
   2357 
   2358 /*===========================================================================
   2359  * FUNCTION   : mm_camera_muxer_put_stream_bufs
   2360  *
   2361  * DESCRIPTION: function to release buffers for auxillary streams.
   2362  *
   2363  * PARAMETERS :
   2364  *   @queue: ptr to frame sync queue
   2365  *
   2366  * RETURN     : int32_t type of status
   2367  *              0  -- success
   2368  *              1 -- failure
   2369  *==========================================================================*/
   2370 int32_t mm_camera_muxer_put_stream_bufs(mm_stream_t *my_obj)
   2371 {
   2372     int32_t rc = -1;
   2373 
   2374     if (my_obj == NULL || !my_obj->is_res_shared) {
   2375         LOGE("Invalid argument");
   2376         return rc;
   2377     }
   2378     my_obj->total_buf_cnt = 0;
   2379     return 0;
   2380 }
   2381 
   2382 /*===========================================================================
   2383  * FUNCTION   : mm_camera_map_stream_buf_ops
   2384  *
   2385  * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
   2386  *              This function will be passed to upper layer as part of ops table
   2387  *              to be used by upper layer when allocating stream buffers and mapping
   2388  *              buffers to server via domain socket.
   2389  *
   2390  * PARAMETERS :
   2391  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   2392  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2393  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2394  *   @plane_idx    : plane index. If all planes share the same fd,
   2395  *                   plane_idx = -1; otherwise, plean_idx is the
   2396  *                   index to plane (0..num_of_planes)
   2397  *   @fd           : file descriptor of the buffer
   2398  *   @size         : size of the buffer
   2399  *   @userdata     : user data ptr (stream object)
   2400  *
   2401  * RETURN     : int32_t type of status
   2402  *              0  -- success
   2403  *              -1 -- failure
   2404  *==========================================================================*/
   2405 int32_t mm_camera_map_stream_buf_ops(uint32_t buf_idx,
   2406         int32_t plane_idx, int fd, size_t size,
   2407         void *buffer, cam_mapping_buf_type type,
   2408         void *userdata)
   2409 {
   2410     int32_t rc = 0;
   2411     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   2412     int32_t i = 0;
   2413 
   2414     switch (type) {
   2415         case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
   2416         case CAM_MAPPING_BUF_TYPE_MISC_BUF:
   2417             if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
   2418                 my_obj = my_obj->aux_str_obj[buf_idx];
   2419             }
   2420             break;
   2421         case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
   2422         case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
   2423         case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
   2424         case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
   2425             for(i = 0; i < my_obj->num_s_cnt; i++) {
   2426                 if (my_obj->aux_str_obj[i] != NULL) {
   2427                     rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
   2428                             type, buf_idx, plane_idx, fd, size, buffer);
   2429                 }
   2430             }
   2431             break;
   2432         default:
   2433             LOGE("Not buffer for stream : %d", type);
   2434             rc = -1;
   2435             break;
   2436     }
   2437 
   2438     if (rc == 0) {
   2439         rc = mm_stream_map_buf(my_obj,
   2440                 type, buf_idx, plane_idx, fd, size, buffer);
   2441     }
   2442     return rc;
   2443 }
   2444 
   2445 /*===========================================================================
   2446  * FUNCTION   : mm_camera_muxer_bundled_map_buf_ops
   2447  *
   2448  * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
   2449  *              This function will be passed to upper layer as part of ops table
   2450  *              to be used by upper layer when allocating stream buffers and mapping
   2451  *              buffers to server via domain socket.
   2452  *
   2453  * PARAMETERS :
   2454  *   @buf_map_list : list of buffer mapping information
   2455  *   @userdata     : user data ptr (stream object)
   2456  *
   2457  * RETURN     : int32_t type of status
   2458  *              0  -- success
   2459  *              -1 -- failure
   2460  *==========================================================================*/
   2461 int32_t mm_camera_bundled_map_stream_buf_ops(
   2462         const cam_buf_map_type_list *buf_map_list,
   2463         void *userdata)
   2464 {
   2465     int32_t rc = 0;
   2466     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   2467     uint32_t i = 0;
   2468 
   2469     if (buf_map_list == NULL || buf_map_list->length == 0) {
   2470         LOGW("Invalid argument");
   2471         return rc;
   2472     }
   2473 
   2474     uint32_t buf_idx;
   2475     cam_mapping_buf_type type = buf_map_list->buf_maps[0].type;
   2476     switch (type) {
   2477         case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
   2478         case CAM_MAPPING_BUF_TYPE_MISC_BUF:
   2479             buf_idx = buf_map_list->buf_maps[0].frame_idx;
   2480             if (buf_idx == 0) {
   2481                 rc = mm_stream_map_buf(my_obj,
   2482                         type, buf_idx,
   2483                         buf_map_list->buf_maps[0].plane_idx,
   2484                         buf_map_list->buf_maps[0].fd,
   2485                         buf_map_list->buf_maps[0].size,
   2486                         buf_map_list->buf_maps[0].buffer);
   2487                 if (rc != 0) {
   2488                     LOGE("Failed rc = %d", rc);
   2489                 }
   2490             }
   2491             for (i = 1; i < buf_map_list->length; i++) {
   2492                 buf_idx = buf_map_list->buf_maps[i].frame_idx;
   2493                 if ((i == buf_idx)
   2494                         && (my_obj->aux_str_obj[i] != NULL)) {
   2495                     rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
   2496                             type, buf_idx,
   2497                             buf_map_list->buf_maps[i].plane_idx,
   2498                             buf_map_list->buf_maps[i].fd,
   2499                             buf_map_list->buf_maps[i].size,
   2500                             buf_map_list->buf_maps[i].buffer);
   2501                 }
   2502             }
   2503             break;
   2504         case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
   2505         case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
   2506         case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
   2507         case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
   2508             rc = mm_stream_map_bufs(my_obj, buf_map_list);
   2509             for(i = 0; i < my_obj->num_s_cnt; i++) {
   2510                 if (my_obj->aux_str_obj[i] != NULL) {
   2511                     rc = mm_stream_map_bufs(my_obj->aux_str_obj[i],
   2512                             buf_map_list);
   2513                 }
   2514             }
   2515             break;
   2516         default:
   2517             LOGE("Not buffer for stream : %d", type);
   2518             rc = -1;
   2519             break;
   2520     }
   2521     return rc;
   2522 }
   2523 
   2524 /*===========================================================================
   2525  * FUNCTION   : mm_camera_muxer_unmap_buf_ops
   2526  *
   2527  * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
   2528  *              This function will be passed to upper layer as part of ops table
   2529  *              to be used by upper layer when allocating stream buffers and unmapping
   2530  *              buffers to server via domain socket.
   2531  *
   2532  * PARAMETERS :
   2533  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   2534  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2535  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2536  *   @plane_idx    : plane index. If all planes share the same fd,
   2537  *                   plane_idx = -1; otherwise, plean_idx is the
   2538  *                   index to plane (0..num_of_planes)
   2539  *   @userdata     : user data ptr (stream object)
   2540  *
   2541  * RETURN     : int32_t type of status
   2542  *              0  -- success
   2543  *              -1 -- failure
   2544  *==========================================================================*/
   2545 int32_t mm_camera_unmap_stream_buf_ops(uint32_t buf_idx,
   2546            int32_t plane_idx, cam_mapping_buf_type type, void *userdata)
   2547 {
   2548     int32_t rc = 0;
   2549     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   2550     int32_t i = 0;
   2551 
   2552     switch (type) {
   2553         case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
   2554         case CAM_MAPPING_BUF_TYPE_MISC_BUF:
   2555             if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
   2556                 my_obj = my_obj->aux_str_obj[buf_idx];
   2557             }
   2558             break;
   2559         case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
   2560         case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
   2561         case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
   2562         case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
   2563             for(i = 0; i < my_obj->num_s_cnt; i++) {
   2564                 if (my_obj->aux_str_obj[i] != NULL) {
   2565                     rc = mm_stream_unmap_buf(my_obj->aux_str_obj[i],
   2566                             type, buf_idx, plane_idx);
   2567                 }
   2568             }
   2569             break;
   2570         default:
   2571             LOGE("Not buffer for stream : %d", type);
   2572             rc = -1;
   2573             break;
   2574     }
   2575 
   2576     if (rc == 0) {
   2577         rc = mm_stream_unmap_buf(my_obj,
   2578                 type, buf_idx, plane_idx);
   2579     }
   2580     return rc;
   2581 }
   2582 
   2583 
   2584