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.max_unmatched_frames = 0;
    761             frame_sync.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
    762             frame_sync.buf_cb = channel_cb;
    763             pthread_mutex_lock(&cam_obj->cam_lock);
    764             mm_camera_reg_frame_sync(cam_obj, m_ch_id,
    765                     0, &frame_sync);
    766         }
    767     } else {
    768         pthread_mutex_unlock(&cam_obj->muxer_lock);
    769     }
    770     return ch_id;
    771 }
    772 
    773 /*===========================================================================
    774  * FUNCTION   : mm_camera_muxer_delete_channel
    775  *
    776  * DESCRIPTION: delete a channel by its handle
    777  *
    778  * PARAMETERS :
    779  *   @camera_handle: camera handle
    780  *   @ch_id        : channel handle
    781  *   @cam_obj     : ptr to a Parent camera object
    782  *
    783  * RETURN     : int32_t type of status
    784  *              0  -- success
    785  *              -1 -- failure
    786  *==========================================================================*/
    787 int32_t mm_camera_muxer_delete_channel(uint32_t camera_handle, uint32_t ch_id,
    788         mm_camera_obj_t *cam_obj)
    789 {
    790     int32_t rc = -1;
    791     mm_camera_obj_t *my_obj = NULL;
    792 
    793     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    794     if(my_obj) {
    795         pthread_mutex_lock(&my_obj->cam_lock);
    796         pthread_mutex_unlock(&cam_obj->muxer_lock);
    797         rc = mm_camera_del_channel(my_obj, ch_id);
    798     } else {
    799         pthread_mutex_unlock(&cam_obj->muxer_lock);
    800     }
    801     return rc;
    802 }
    803 
    804 /*===========================================================================
    805  * FUNCTION   : mm_camera_muxer_get_bundle_info
    806  *
    807  * DESCRIPTION: query bundle info of the channel
    808  *
    809  * PARAMETERS :
    810  *   @camera_handle: camera handle
    811  *   @ch_id        : channel handle
    812  *   @bundle_info  : bundle info to be filled in
    813  *   @cam_obj     : ptr to a Parent camera object
    814  *
    815  * RETURN     : int32_t type of status
    816  *              0  -- success
    817  *              -1 -- failure
    818  *==========================================================================*/
    819 int32_t mm_camera_muxer_get_bundle_info(uint32_t camera_handle, uint32_t ch_id,
    820         cam_bundle_config_t *bundle_info, mm_camera_obj_t *cam_obj)
    821 {
    822     int32_t rc = -1;
    823     mm_camera_obj_t *my_obj = NULL;
    824 
    825     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    826     if(my_obj) {
    827         pthread_mutex_lock(&my_obj->cam_lock);
    828         pthread_mutex_unlock(&cam_obj->muxer_lock);
    829         rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
    830     } else {
    831         pthread_mutex_unlock(&cam_obj->muxer_lock);
    832     }
    833     return rc;
    834 }
    835 /*===========================================================================
    836  * FUNCTION   : mm_camera_muxer_add_stream
    837  *
    838  * DESCRIPTION: add a stream into a channel
    839  *
    840  * PARAMETERS :
    841  *   @camera_handle: camera handle
    842  *   @ch_id        : channel handle
    843  *   @src__ch_id        : src channel handle
    844  *   @src_stream_id     :  src stream handle
    845  *   @cam_obj     : ptr to a Parent camera object
    846  *
    847  * RETURN     : uint32_t type of stream handle
    848  *              0  -- invalid stream handle, meaning the op failed
    849  *              >0 -- successfully added a stream with a valid handle
    850  *==========================================================================*/
    851 uint32_t mm_camera_muxer_add_stream(uint32_t camera_handle,
    852         uint32_t ch_id, uint32_t src__ch_id, uint32_t src_stream_id, mm_camera_obj_t *cam_obj)
    853 {
    854     int32_t stream_id = 0;
    855     int32_t rc = 0;
    856     mm_camera_obj_t *my_obj = NULL;
    857 
    858     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    859     if(my_obj) {
    860         pthread_mutex_lock(&my_obj->cam_lock);
    861         pthread_mutex_unlock(&cam_obj->muxer_lock);
    862         stream_id = mm_camera_add_stream(my_obj, ch_id);
    863         if (stream_id > 0 && src_stream_id > 0) {
    864             mm_camera_frame_sync_t frame_sync;
    865             memset(&frame_sync, 0, sizeof(frame_sync));
    866             frame_sync.a_cam_obj = my_obj;
    867             frame_sync.a_ch_id = ch_id;
    868             frame_sync.userdata = NULL;
    869             frame_sync.a_stream_id = stream_id;
    870             frame_sync.max_unmatched_frames = 0;
    871             frame_sync.buf_cb = NULL;
    872             frame_sync.is_res_shared = 1;
    873             pthread_mutex_lock(&cam_obj->cam_lock);
    874             rc = mm_camera_reg_frame_sync(cam_obj, src__ch_id,
    875                     src_stream_id, &frame_sync);
    876             LOGH("Stream frame sync = %d and %d rc = %d",
    877                     src_stream_id, stream_id, rc);
    878         }
    879     } else {
    880         pthread_mutex_unlock(&cam_obj->muxer_lock);
    881     }
    882     return stream_id;
    883 }
    884 
    885 /*===========================================================================
    886  * FUNCTION   : mm_camera_muxer_delete_stream
    887  *
    888  * DESCRIPTION: delete a stream by its handle
    889  *
    890  * PARAMETERS :
    891  *   @camera_handle: camera handle
    892  *   @ch_id        : channel handle
    893  *   @stream_id    : stream handle
    894  *
    895  * RETURN     : int32_t type of status
    896  *              0  -- success
    897  *              -1 -- failure
    898  *==========================================================================*/
    899 int32_t mm_camera_muxer_delete_stream(uint32_t camera_handle,
    900         uint32_t ch_id, uint32_t stream_id,
    901         mm_camera_obj_t *cam_obj)
    902 {
    903     mm_camera_obj_t *my_obj = NULL;
    904     int32_t rc = 0;
    905 
    906     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    907     if(my_obj) {
    908         pthread_mutex_lock(&my_obj->cam_lock);
    909         pthread_mutex_unlock(&cam_obj->muxer_lock);
    910         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    911     } else {
    912         pthread_mutex_unlock(&cam_obj->muxer_lock);
    913     }
    914     return rc;
    915 }
    916 
    917 /*===========================================================================
    918  * FUNCTION   : mm_camera_muxer_link_stream
    919  *
    920  * DESCRIPTION: link a stream into a new channel
    921  *
    922  * PARAMETERS :
    923  *   @camera_handle: camera handle
    924  *   @ch_id        : channel handle
    925  *   @stream_id    : stream id
    926  *   @linked_ch_id : channel in which the stream will be linked
    927  *
    928  * RETURN     : int32_t type of stream handle
    929  *              0  -- invalid stream handle, meaning the op failed
    930  *              >0 -- successfully linked a stream with a valid handle
    931  *==========================================================================*/
    932 int32_t mm_camera_muxer_link_stream(uint32_t camera_handle,
    933         uint32_t ch_id, uint32_t stream_id, uint32_t linked_ch_id,
    934         mm_camera_obj_t *cam_obj)
    935 {
    936     uint32_t id = 0;
    937     mm_camera_obj_t *my_obj = NULL;
    938     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    939 
    940     if(my_obj) {
    941         pthread_mutex_lock(&my_obj->cam_lock);
    942         pthread_mutex_unlock(&cam_obj->muxer_lock);
    943         id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
    944     } else {
    945         pthread_mutex_unlock(&cam_obj->muxer_lock);
    946     }
    947     return id;
    948 }
    949 
    950 /*===========================================================================
    951  * FUNCTION   : mm_camera_muxer_config_stream
    952  *
    953  * DESCRIPTION: configure a stream
    954  *
    955  * PARAMETERS :
    956  *   @camera_handle: camera handle
    957  *   @ch_id        : channel handle
    958  *   @stream_id    : stream handle
    959  *   @config       : stream configuration
    960  *
    961  * RETURN     : int32_t type of status
    962  *              0  -- success
    963  *              -1 -- failure
    964  *==========================================================================*/
    965 int32_t mm_camera_muxer_config_stream(uint32_t camera_handle,
    966         uint32_t ch_id, uint32_t stream_id, mm_camera_stream_config_t *config,
    967         mm_camera_obj_t *cam_obj)
    968 {
    969     int32_t rc = -1;
    970     mm_camera_obj_t * my_obj = NULL;
    971     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
    972     mm_camera_stream_config_t aux_config = *config;
    973     LOGD("mm_camera_intf_config_stream stream_id = %d",stream_id);
    974 
    975     if(my_obj) {
    976         pthread_mutex_lock(&my_obj->cam_lock);
    977         pthread_mutex_unlock(&cam_obj->muxer_lock);
    978         if (config->stream_info->aux_str_info != NULL) {
    979             aux_config.stream_info = config->stream_info->aux_str_info;
    980         }
    981         aux_config.mem_vtbl.get_bufs = NULL;
    982         aux_config.mem_vtbl.put_bufs = NULL;
    983         aux_config.mem_vtbl.set_config_ops = NULL;
    984         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, &aux_config);
    985     } else {
    986         pthread_mutex_unlock(&cam_obj->muxer_lock);
    987     }
    988     return rc;
    989 }
    990 
    991 /*===========================================================================
    992  * FUNCTION   : mm_camera_muxer_map_stream_buf
    993  *
    994  * DESCRIPTION: mapping stream buffer via domain socket to server
    995  *
    996  * PARAMETERS :
    997  *   @camera_handle: camera handle
    998  *   @ch_id        : channel handle
    999  *   @s_id         : stream handle
   1000  *   @buf_type     : type of buffer to be mapped. could be following values:
   1001  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1002  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1003  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1004  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1005  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1006  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1007  *   @plane_idx    : plane index. If all planes share the same fd,
   1008  *                   plane_idx = -1; otherwise, plean_idx is the
   1009  *                   index to plane (0..num_of_planes)
   1010  *   @fd           : file descriptor of the buffer
   1011  *   @size         : size of the buffer
   1012  *
   1013  * RETURN     : int32_t type of status
   1014  *              0  -- success
   1015  *              -1 -- failure
   1016  *==========================================================================*/
   1017 int32_t mm_camera_muxer_map_stream_buf(uint32_t camera_handle,
   1018         uint32_t ch_id, uint32_t stream_id,
   1019         uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, int fd,
   1020         size_t size, void *buffer, mm_camera_obj_t *cam_obj)
   1021 {
   1022     int32_t rc = -1;
   1023     mm_camera_obj_t * my_obj = NULL;
   1024     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1025 
   1026     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1027 
   1028     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1029           camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1030 
   1031     if(my_obj) {
   1032         pthread_mutex_lock(&my_obj->cam_lock);
   1033         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1034         rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
   1035                                   buf_type, buf_idx, plane_idx,
   1036                                   fd, size, buffer);
   1037     }else{
   1038         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1039     }
   1040     return rc;
   1041 }
   1042 
   1043 /*===========================================================================
   1044  * FUNCTION   : mm_camera_muxer_map_stream_bufs
   1045  *
   1046  * DESCRIPTION: mapping stream buffers via domain socket to server
   1047  *
   1048  * PARAMETERS :
   1049  *   @camera_handle: camera handle
   1050  *   @ch_id        : channel handle
   1051  *   @buf_map_list : list of buffers to be mapped
   1052  *
   1053  * RETURN     : int32_t type of status
   1054  *              0  -- success
   1055  *              -1 -- failure
   1056  *==========================================================================*/
   1057 int32_t mm_camera_muxer_map_stream_bufs(uint32_t camera_handle,
   1058         uint32_t ch_id, const cam_buf_map_type_list *buf_map_list,
   1059         mm_camera_obj_t *cam_obj)
   1060 {
   1061     int32_t rc = -1;
   1062     mm_camera_obj_t *my_obj = NULL;
   1063     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1064 
   1065     LOGD("E camera_handle = %d, ch_id = %d",
   1066           camera_handle, ch_id);
   1067 
   1068     if(my_obj) {
   1069         pthread_mutex_lock(&my_obj->cam_lock);
   1070         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1071         rc = mm_camera_map_stream_bufs(my_obj, ch_id, buf_map_list);
   1072     }else{
   1073         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1074     }
   1075     return rc;
   1076 }
   1077 
   1078 /*===========================================================================
   1079  * FUNCTION   : mm_camera_muxer_unmap_stream_buf
   1080  *
   1081  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1082  *
   1083  * PARAMETERS :
   1084  *   @camera_handle: camera handle
   1085  *   @ch_id        : channel handle
   1086  *   @s_id         : stream handle
   1087  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1088  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1089  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1090  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1091  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1092  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1093  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1094  *   @plane_idx    : plane index. If all planes share the same fd,
   1095  *                   plane_idx = -1; otherwise, plean_idx is the
   1096  *                   index to plane (0..num_of_planes)
   1097  *
   1098  * RETURN     : int32_t type of status
   1099  *              0  -- success
   1100  *              -1 -- failure
   1101  *==========================================================================*/
   1102 int32_t mm_camera_muxer_unmap_stream_buf(uint32_t camera_handle,
   1103         uint32_t ch_id, uint32_t stream_id,
   1104         uint8_t buf_type, uint32_t buf_idx,
   1105         int32_t plane_idx, mm_camera_obj_t *cam_obj)
   1106 {
   1107     int32_t rc = -1;
   1108     mm_camera_obj_t * my_obj = NULL;
   1109     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1110 
   1111     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1112           camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1113 
   1114     if(my_obj) {
   1115         pthread_mutex_lock(&my_obj->cam_lock);
   1116         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1117         rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
   1118                 buf_type, buf_idx, plane_idx);
   1119     } else{
   1120         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1121     }
   1122     return rc;
   1123 }
   1124 
   1125 /*===========================================================================
   1126  * FUNCTION   : mm_camera_muxer_set_stream_parms
   1127  *
   1128  * DESCRIPTION: set parameters per stream
   1129  *
   1130  * PARAMETERS :
   1131  *   @camera_handle: camera handle
   1132  *   @ch_id        : channel handle
   1133  *   @s_id         : stream handle
   1134  *   @parms        : ptr to a param struct to be set to server
   1135  *
   1136  * RETURN     : int32_t type of status
   1137  *              0  -- success
   1138  *              -1 -- failure
   1139  *==========================================================================*/
   1140 int32_t mm_camera_muxer_set_stream_parms(uint32_t camera_handle,
   1141         uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
   1142         mm_camera_obj_t *cam_obj)
   1143 {
   1144     int32_t rc = 0;
   1145     mm_camera_obj_t * my_obj = NULL;
   1146     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1147 
   1148     if(my_obj) {
   1149         pthread_mutex_lock(&my_obj->cam_lock);
   1150         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1151         rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
   1152     } else{
   1153         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1154     }
   1155     return rc;
   1156 }
   1157 
   1158 /*===========================================================================
   1159  * FUNCTION   : mm_camera_muxer_get_stream_parms
   1160  *
   1161  * DESCRIPTION: get parameters per stream
   1162  *
   1163  * PARAMETERS :
   1164  *   @camera_handle: camera handle
   1165  *   @ch_id        : channel handle
   1166  *   @s_id         : stream handle
   1167  *   @parms        : ptr to a param struct to be get from server
   1168  *
   1169  * RETURN     : int32_t type of status
   1170  *              0  -- success
   1171  *              -1 -- failure
   1172  *==========================================================================*/
   1173 int32_t mm_camera_muxer_get_stream_parms(uint32_t camera_handle,
   1174         uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
   1175         mm_camera_obj_t *cam_obj)
   1176 {
   1177     int32_t rc = 0;
   1178     mm_camera_obj_t * my_obj = NULL;
   1179     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1180 
   1181     if(my_obj) {
   1182         pthread_mutex_lock(&my_obj->cam_lock);
   1183         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1184         rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
   1185     } else{
   1186         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1187     }
   1188     return rc;
   1189 }
   1190 
   1191 /*===========================================================================
   1192  * FUNCTION   : mm_camera_muxer_start_channel
   1193  *
   1194  * DESCRIPTION: start a channel, which will start all streams in the channel
   1195  *
   1196  * PARAMETERS :
   1197  *   @camera_handle: camera handle
   1198  *   @ch_id        : channel handle
   1199  *
   1200  * RETURN     : int32_t type of status
   1201  *              0  -- success
   1202  *              -1 -- failure
   1203  *==========================================================================*/
   1204 int32_t mm_camera_muxer_start_channel(uint32_t camera_handle,
   1205         uint32_t ch_id, mm_camera_obj_t *cam_obj)
   1206 {
   1207     int32_t rc = 0;
   1208     mm_camera_obj_t * my_obj = NULL;
   1209     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1210 
   1211     if(my_obj) {
   1212         pthread_mutex_lock(&my_obj->cam_lock);
   1213         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1214         rc = mm_camera_start_channel(my_obj, ch_id);
   1215     } else{
   1216         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1217     }
   1218     return rc;
   1219 }
   1220 
   1221 /*===========================================================================
   1222  * FUNCTION   : mm_camera_muxer_stop_channel
   1223  *
   1224  * DESCRIPTION: stop a channel, which will stop all streams in the channel
   1225  *
   1226  * PARAMETERS :
   1227  *   @camera_handle: camera handle
   1228  *   @ch_id        : channel handle
   1229  *
   1230  * RETURN     : int32_t type of status
   1231  *              0  -- success
   1232  *              -1 -- failure
   1233  *==========================================================================*/
   1234 int32_t mm_camera_muxer_stop_channel(uint32_t camera_handle,
   1235         uint32_t ch_id, mm_camera_obj_t *cam_obj)
   1236 {
   1237     int32_t rc = 0;
   1238     mm_camera_obj_t * my_obj = NULL;
   1239     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1240 
   1241     if(my_obj) {
   1242         pthread_mutex_lock(&my_obj->cam_lock);
   1243         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1244         rc = mm_camera_stop_channel(my_obj, ch_id);
   1245     } else{
   1246         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1247     }
   1248     return rc;
   1249 }
   1250 
   1251 /*===========================================================================
   1252  * FUNCTION   : mm_camera_intf_qbuf
   1253  *
   1254  * DESCRIPTION: enqueue buffer back to kernel
   1255  *
   1256  * PARAMETERS :
   1257  *   @camera_handle: camera handle
   1258  *   @ch_id        : channel handle
   1259  *   @buf          : buf ptr to be enqueued
   1260  *
   1261  * RETURN     : int32_t type of status
   1262  *              0  -- success
   1263  *              -1 -- failure
   1264  *==========================================================================*/
   1265 int32_t mm_camera_muxer_qbuf(uint32_t camera_handle, uint32_t ch_id,
   1266         mm_camera_buf_def_t *buf, mm_camera_obj_t *cam_obj)
   1267 {
   1268     int32_t rc = 0;
   1269     mm_camera_obj_t * my_obj = NULL;
   1270 
   1271     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1272     if(my_obj) {
   1273         pthread_mutex_lock(&my_obj->cam_lock);
   1274         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1275         rc = mm_camera_qbuf(my_obj, ch_id, buf);
   1276     } else {
   1277         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1278     }
   1279     return rc;
   1280 }
   1281 
   1282 /*===========================================================================
   1283  * FUNCTION   : mm_camera_muxer_get_queued_buf_count
   1284  *
   1285  * DESCRIPTION: returns the queued buffer count
   1286  *
   1287  * PARAMETERS :
   1288  *   @camera_handle: camera handle
   1289  *   @ch_id        : channel handle
   1290  *   @stream_id : stream id
   1291  *
   1292  * RETURN     : int32_t - queued buffer count
   1293  *
   1294  *==========================================================================*/
   1295 int32_t mm_camera_muxer_get_queued_buf_count(uint32_t camera_handle,
   1296         uint32_t ch_id, uint32_t stream_id,
   1297         mm_camera_obj_t *cam_obj)
   1298 {
   1299     int32_t rc = 0;
   1300     mm_camera_obj_t * my_obj = NULL;
   1301 
   1302     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1303     if(my_obj) {
   1304         pthread_mutex_lock(&my_obj->cam_lock);
   1305         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1306         rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
   1307     } else {
   1308         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1309     }
   1310     return rc;
   1311 }
   1312 
   1313 /*===========================================================================
   1314  * FUNCTION   : mm_camera_muxer_request_super_buf
   1315  *
   1316  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1317  *              frames from superbuf queue
   1318  *
   1319  * PARAMETERS :
   1320  *   @ch_id             : channel handle
   1321  *   @buf                : request buffer info
   1322  *
   1323  * RETURN     : int32_t type of status
   1324  *              0  -- success
   1325  *              -1 -- failure
   1326  *==========================================================================*/
   1327 int32_t mm_camera_muxer_request_super_buf(uint32_t ch_id,
   1328         mm_camera_req_buf_t *buf, mm_camera_obj_t *cam_obj)
   1329 {
   1330     int32_t rc = 0;
   1331     mm_camera_obj_t * my_obj = cam_obj;
   1332     uint32_t chID = get_main_camera_handle(ch_id);
   1333 
   1334     if(my_obj && buf) {
   1335         pthread_mutex_lock(&my_obj->cam_lock);
   1336         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1337         rc = mm_camera_start_frame_sync(my_obj,
   1338                 chID, 0);
   1339         LOGH("Start Frame Sync chid = %d rc = %d", chID, rc);
   1340         pthread_mutex_lock(&my_obj->cam_lock);
   1341         rc = mm_camera_request_super_buf (my_obj, chID, buf);
   1342     } else {
   1343         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1344     }
   1345     return rc;
   1346 }
   1347 
   1348 /*===========================================================================
   1349  * FUNCTION   : mm_camera_muxer_cancel_super_buf_request
   1350  *
   1351  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1352  *              frames from superbuf queue
   1353  *
   1354  * PARAMETERS :
   1355  *   @camera_handle: camera handle
   1356  *   @ch_id             : channel handle
   1357  *   @buf                : request buffer info
   1358  *
   1359  * RETURN     : int32_t type of status
   1360  *              0  -- success
   1361  *              -1 -- failure
   1362  *==========================================================================*/
   1363 int32_t mm_camera_muxer_cancel_super_buf_request(uint32_t camera_handle,
   1364         uint32_t ch_id,
   1365         mm_camera_obj_t *cam_obj)
   1366 {
   1367     int32_t rc = 0;
   1368     mm_camera_obj_t * my_obj = NULL;
   1369     uint32_t aux_handle = get_aux_camera_handle(camera_handle);
   1370     uint32_t aux_chID = get_main_camera_handle(ch_id);
   1371 
   1372     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1373     if(my_obj) {
   1374         pthread_mutex_lock(&my_obj->cam_lock);
   1375         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1376         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
   1377         pthread_mutex_lock(&my_obj->cam_lock);
   1378         mm_camera_stop_frame_sync(my_obj,
   1379                 ch_id, 0);
   1380 
   1381     } else {
   1382         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1383     }
   1384 
   1385     my_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
   1386     if(my_obj) {
   1387         pthread_mutex_lock(&my_obj->cam_lock);
   1388         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1389         rc = mm_camera_cancel_super_buf_request(my_obj, aux_chID);
   1390     } else {
   1391         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1392     }
   1393     return rc;
   1394 }
   1395 
   1396 /*===========================================================================
   1397  * FUNCTION   : mm_camera_muxer_flush_super_buf_queue
   1398  *
   1399  * DESCRIPTION: flush out all frames in the superbuf queue
   1400  *
   1401  * PARAMETERS :
   1402  *   @camera_handle: camera handle
   1403  *   @ch_id        : channel handle
   1404  *   @frame_idx    : frame index
   1405  *
   1406  * RETURN     : int32_t type of status
   1407  *              0  -- success
   1408  *              -1 -- failure
   1409  *==========================================================================*/
   1410 int32_t mm_camera_muxer_flush_super_buf_queue(uint32_t camera_handle,
   1411         uint32_t ch_id,
   1412         uint32_t frame_idx, mm_camera_obj_t *cam_obj)
   1413 {
   1414     int32_t rc = 0;
   1415     mm_camera_obj_t * my_obj = NULL;
   1416     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1417 
   1418     if(my_obj) {
   1419             pthread_mutex_lock(&my_obj->cam_lock);
   1420             pthread_mutex_unlock(&cam_obj->muxer_lock);
   1421             rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
   1422     } else {
   1423         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1424     }
   1425     return rc;
   1426 }
   1427 
   1428 /*===========================================================================
   1429  * FUNCTION   : mm_camera_muxer_configure_notify_mode
   1430  *
   1431  * DESCRIPTION: Configures channel notification mode
   1432  *
   1433  * PARAMETERS :
   1434  *   @camera_handle: camera handle
   1435  *   @ch_id        : channel handle
   1436  *   @notify_mode  : notification mode
   1437  *
   1438  * RETURN     : int32_t type of status
   1439  *              0  -- success
   1440  *              -1 -- failure
   1441  *==========================================================================*/
   1442 int32_t mm_camera_muxer_configure_notify_mode(uint32_t camera_handle,
   1443         uint32_t ch_id, mm_camera_super_buf_notify_mode_t notify_mode,
   1444         mm_camera_obj_t *cam_obj)
   1445 {
   1446     int32_t rc = 0;
   1447     mm_camera_obj_t * my_obj = NULL;
   1448     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1449 
   1450     if(my_obj) {
   1451             pthread_mutex_lock(&my_obj->cam_lock);
   1452             pthread_mutex_unlock(&cam_obj->muxer_lock);
   1453             rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
   1454     } else {
   1455         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1456     }
   1457     return rc;
   1458 }
   1459 
   1460 /*===========================================================================
   1461  * FUNCTION   : mm_camera_muxer_process_advanced_capture
   1462  *
   1463  * DESCRIPTION: Configures channel advanced capture mode
   1464  *
   1465  * PARAMETERS :
   1466  *   @camera_handle: camera handle
   1467  *   @type : advanced capture type
   1468  *   @ch_id        : channel handle
   1469  *   @trigger  : 1 for start and 0 for cancel/stop
   1470  *   @value  : input capture configaration
   1471  *
   1472  * RETURN     : int32_t type of status
   1473  *              0  -- success
   1474  *              -1 -- failure
   1475  *==========================================================================*/
   1476 int32_t mm_camera_muxer_process_advanced_capture(uint32_t camera_handle,
   1477          uint32_t ch_id, mm_camera_advanced_capture_t type,
   1478          int8_t start_flag, void *in_value, mm_camera_obj_t *cam_obj)
   1479 {
   1480     int32_t rc = 0;
   1481     mm_camera_obj_t * my_obj = NULL;
   1482 
   1483     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1484     if(my_obj) {
   1485         pthread_mutex_lock(&my_obj->cam_lock);
   1486         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1487         rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
   1488                 (uint32_t)start_flag, in_value);
   1489     } else {
   1490         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1491     }
   1492     return rc;
   1493 }
   1494 
   1495 /*===========================================================================
   1496  * FUNCTION   : mm_camera_muxer_get_session_id
   1497  *
   1498  * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
   1499  *
   1500  * PARAMETERS :
   1501  *   @camera_handle: camera handle
   1502  *   @sessionid: session id to be retrieved from server
   1503  *
   1504  * RETURN     : int32_t type of status
   1505  *              0  -- success
   1506  *              -1 -- failure
   1507  *==========================================================================*/
   1508 int32_t mm_camera_muxer_get_session_id(uint32_t camera_handle,
   1509         uint32_t* sessionid, mm_camera_obj_t *cam_obj)
   1510 {
   1511     int32_t rc = 0;
   1512     mm_camera_obj_t * my_obj = NULL;
   1513     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1514 
   1515     if(my_obj) {
   1516         pthread_mutex_lock(&my_obj->cam_lock);
   1517         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1518         *sessionid = my_obj->sessionid;
   1519         pthread_mutex_unlock(&my_obj->cam_lock);
   1520         rc = 0;
   1521     } else {
   1522         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1523     }
   1524     return rc;
   1525 }
   1526 
   1527  /*===========================================================================
   1528  * FUNCTION   : mm_camera_muxer_flush
   1529  *
   1530  * DESCRIPTION: flush the current camera state and buffers
   1531  *
   1532  * PARAMETERS :
   1533  *   @camera_handle: camera handle
   1534  *
   1535  * RETURN     : int32_t type of status
   1536  *              0  -- success
   1537  *              -1 -- failure
   1538  *==========================================================================*/
   1539 int32_t mm_camera_muxer_flush(uint32_t camera_handle, mm_camera_obj_t *cam_obj)
   1540 {
   1541     int32_t rc = 0;
   1542     mm_camera_obj_t * my_obj = NULL;
   1543     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1544 
   1545     if(my_obj) {
   1546         pthread_mutex_lock(&my_obj->cam_lock);
   1547         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1548         rc = mm_camera_flush(my_obj);
   1549     } else {
   1550         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1551     }
   1552     return rc;
   1553 }
   1554 
   1555 /*===========================================================================
   1556  * FUNCTION   : mm_camera_muxer_register_stream_buf_cb
   1557  *
   1558  * DESCRIPTION: Register special callback for stream buffer
   1559  *
   1560  * PARAMETERS :
   1561  *   @camera_handle: camera handle
   1562  *   @ch_id        : channel handle
   1563  *   @stream_id    : stream handle
   1564  *   @buf_cb       : callback function
   1565  *   @buf_type     :SYNC/ASYNC
   1566  *   @userdata     : userdata pointer
   1567  *
   1568  * RETURN     : int32_t type of status
   1569  *              0  -- success
   1570  *              1 -- failure
   1571  *==========================================================================*/
   1572 int32_t mm_camera_muxer_register_stream_buf_cb(uint32_t camera_handle,
   1573         uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
   1574         mm_camera_stream_cb_type cb_type, void *userdata, mm_camera_obj_t *cam_obj)
   1575 {
   1576     int32_t rc = 0;
   1577     mm_camera_obj_t * my_obj = NULL;
   1578     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1579 
   1580     if(my_obj) {
   1581         pthread_mutex_lock(&my_obj->cam_lock);
   1582         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1583         rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
   1584                 buf_cb, cb_type, userdata);
   1585     } else {
   1586         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1587     }
   1588     return rc;
   1589 }
   1590 
   1591 /*===========================================================================
   1592  * FUNCTION   : mm_camera_muxer_reg_frame_sync
   1593  *
   1594  * DESCRIPTION: Configure for frame sync.
   1595  *
   1596  * PARAMETERS :
   1597  *   @camera_handle: camera handle
   1598  *   @ch_id        : channel handle
   1599  *   @stream_id    : stream handle
   1600  *   @sync_attr    : Attributes for frame sync
   1601  *
   1602  * RETURN     : int32_t type of status
   1603  *              0  -- success
   1604  *              1 -- failure
   1605  *==========================================================================*/
   1606 int32_t mm_camera_muxer_reg_frame_sync(mm_camera_obj_t *cam_obj,
   1607         uint32_t ch_id, uint32_t stream_id,
   1608         mm_camera_intf_frame_sync_t *sync_attr)
   1609 {
   1610     int32_t rc = 0;
   1611     mm_camera_obj_t *a_cam_obj = NULL;
   1612 
   1613     mm_camera_frame_sync_t frame_sync;
   1614     if (sync_attr == NULL || cam_obj == NULL) {
   1615         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1616         return rc;
   1617     }
   1618 
   1619     uint32_t chid = get_main_camera_handle(ch_id);
   1620     uint32_t aux_handle = get_aux_camera_handle(sync_attr->camera_handle);
   1621     uint32_t aux_chid = get_aux_camera_handle(sync_attr->ch_id);
   1622     uint32_t strid = 0;
   1623     uint32_t aux_strid = 0;
   1624     if (stream_id) {
   1625         LOGD("Stream frame sync enabled");
   1626         strid = get_main_camera_handle(stream_id);
   1627         aux_strid = get_aux_camera_handle(sync_attr->stream_id);
   1628         if(aux_strid == 0) {
   1629             aux_handle = get_main_camera_handle(sync_attr->camera_handle);
   1630             aux_chid = get_main_camera_handle(sync_attr->ch_id);
   1631             aux_strid = get_main_camera_handle(sync_attr->stream_id);
   1632         }
   1633     } else {
   1634         LOGD("Channel frame sync enabled");
   1635         if(aux_chid == 0) {
   1636             aux_chid = get_main_camera_handle(sync_attr->ch_id);
   1637         }
   1638     }
   1639     a_cam_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
   1640 
   1641     if(a_cam_obj) {
   1642         memset(&frame_sync, 0, sizeof(frame_sync));
   1643         frame_sync.a_cam_obj = a_cam_obj;
   1644         frame_sync.a_stream_id = aux_strid;
   1645         frame_sync.a_ch_id = aux_chid;
   1646         frame_sync.userdata = sync_attr->userdata;
   1647         frame_sync.buf_cb = sync_attr->buf_cb;
   1648         frame_sync.max_unmatched_frames = sync_attr->max_unmatched_frames;
   1649         frame_sync.is_res_shared = 1;
   1650         pthread_mutex_lock(&cam_obj->cam_lock);
   1651         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1652         rc = mm_camera_reg_frame_sync(cam_obj, chid, strid, &frame_sync);
   1653     } else {
   1654         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1655     }
   1656     return rc;
   1657 }
   1658 
   1659 /*===========================================================================
   1660  * FUNCTION   : mm_camera_muxer_start_frame_sync
   1661  *
   1662  * DESCRIPTION: start frame buffer sync for the stream
   1663  *
   1664  * PARAMETERS :
   1665  *   @camera_handle: camera handle
   1666  *   @ch_id        : channel handle
   1667  *   @stream_id    : stream handle
   1668  *
   1669  * RETURN     : int32_t type of status
   1670  *              0  -- success
   1671  *              1 -- failure
   1672  *==========================================================================*/
   1673 int32_t mm_camera_muxer_start_frame_sync(mm_camera_obj_t *my_obj,
   1674         uint32_t ch_id, uint32_t stream_id)
   1675 {
   1676     int32_t rc = 0;
   1677 
   1678     if(my_obj) {
   1679         pthread_mutex_lock(&my_obj->cam_lock);
   1680         pthread_mutex_unlock(&my_obj->muxer_lock);
   1681         LOGD("ch_id = %d stream_id = %d", ch_id, stream_id);
   1682         rc = mm_camera_start_frame_sync(my_obj,
   1683                 ch_id, stream_id);
   1684     } else {
   1685         pthread_mutex_unlock(&my_obj->muxer_lock);
   1686     }
   1687     return rc;
   1688 }
   1689 
   1690 /*===========================================================================
   1691  * FUNCTION   : mm_camera_muxer_stop_frame_sync
   1692  *
   1693  * DESCRIPTION: stop frame buffer sync for the stream
   1694  *
   1695  * PARAMETERS :
   1696  *   @camera_handle: camera handle
   1697  *   @ch_id        : channel handle
   1698  *   @stream_id    : stream handle
   1699  *
   1700  * RETURN     : int32_t type of status
   1701  *              0  -- success
   1702  *              1 -- failure
   1703  *==========================================================================*/
   1704 int32_t mm_camera_muxer_stop_frame_sync(mm_camera_obj_t *my_obj,
   1705         uint32_t ch_id, uint32_t stream_id)
   1706 {
   1707     int32_t rc = 0;
   1708 
   1709     if(my_obj) {
   1710         pthread_mutex_lock(&my_obj->cam_lock);
   1711         pthread_mutex_unlock(&my_obj->muxer_lock);
   1712         LOGD("ch_id = %d stream_id = %d", ch_id, stream_id);
   1713         rc = mm_camera_stop_frame_sync(my_obj,
   1714                 ch_id, stream_id);
   1715     } else {
   1716         pthread_mutex_unlock(&my_obj->muxer_lock);
   1717     }
   1718     return rc;
   1719 }
   1720 
   1721 /*===========================================================================
   1722  * FUNCTION   : mm_camera_muxer_switch_stream
   1723  *
   1724  * DESCRIPTION: switch between stream in case of multi streams
   1725  *
   1726  * PARAMETERS :
   1727  *   @camera_handle: camera handle
   1728  *   @ch_id        : channel handle
   1729  *   @stream_id    : stream handle
   1730  *
   1731  * RETURN     : int32_t type of status
   1732  *              0  -- success
   1733  *              1 -- failure
   1734  *==========================================================================*/
   1735 int32_t mm_camera_muxer_switch_stream(uint32_t camera_handle,
   1736         uint32_t ch_id, uint32_t stream_id,
   1737         mm_camera_obj_t *cam_obj)
   1738 {
   1739     int32_t rc = 0;
   1740     mm_camera_obj_t * my_obj = NULL;
   1741     my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
   1742 
   1743     if(my_obj) {
   1744         pthread_mutex_lock(&my_obj->cam_lock);
   1745         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1746         LOGD("ch_id = %d stream_id = %d", ch_id, stream_id);
   1747         //TODO
   1748         //rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
   1749         //        buf_cb, cb_type, userdata);
   1750     } else {
   1751         pthread_mutex_unlock(&cam_obj->muxer_lock);
   1752     }
   1753     return rc;
   1754 }
   1755 
   1756 /*===========================================================================
   1757  * FUNCTION   : mm_camera_muxer_stream_frame_sync
   1758  *
   1759  * DESCRIPTION: Handle stream buffers for frame sync
   1760  *
   1761  * PARAMETERS :
   1762  *   @super_buf: Stream buffers
   1763  *   @user_data        : Stream object
   1764  *
   1765  * RETURN     : none
   1766  *==========================================================================*/
   1767 void mm_camera_muxer_stream_frame_sync(mm_camera_super_buf_t *super_buf,
   1768         void *user_data)
   1769 {
   1770     int32_t rc = 0, i = 0;
   1771     mm_stream_t *my_obj = (mm_stream_t *)user_data;
   1772     mm_frame_sync_queue_node_t dispatch_buf;
   1773 
   1774     if (my_obj->master_str_obj != NULL) {
   1775         my_obj = my_obj->master_str_obj;
   1776     }
   1777 
   1778     memset(&dispatch_buf, 0, sizeof(dispatch_buf));
   1779     rc = mm_camera_muxer_do_frame_sync(&my_obj->frame_sync.superbuf_queue,
   1780             super_buf, &dispatch_buf);
   1781     if (rc < 0) {
   1782         LOGE("frame sync failed");
   1783         return;
   1784     }
   1785 
   1786     if (my_obj->frame_sync.super_buf_notify_cb && dispatch_buf.num_objs > 0) {
   1787         mm_camera_super_buf_t super_buf;
   1788         memset(&super_buf, 0, sizeof(super_buf));
   1789         for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   1790             if (dispatch_buf.super_buf[i].num_bufs == 1) {
   1791                 super_buf.bufs[super_buf.num_bufs++] =
   1792                         dispatch_buf.super_buf[i].bufs[0];
   1793                 super_buf.camera_handle |= dispatch_buf.super_buf[i].camera_handle;
   1794                 super_buf.ch_id |= dispatch_buf.super_buf[i].ch_id;
   1795             }
   1796         }
   1797         my_obj->frame_sync.super_buf_notify_cb(&super_buf,
   1798                 my_obj->frame_sync.user_data);
   1799 
   1800         if (my_obj->frame_sync.num_buf_requested != 0) {
   1801             my_obj->frame_sync.num_buf_requested--;
   1802             if (my_obj->frame_sync.num_buf_requested == 0) {
   1803                 my_obj->frame_sync.is_active = 0;
   1804             }
   1805         }
   1806     }
   1807 }
   1808 
   1809 /*===========================================================================
   1810  * FUNCTION   : mm_camera_muxer_channel_frame_sync
   1811  *
   1812  * DESCRIPTION: Handle channel super buffers for frame sync
   1813  *
   1814  * PARAMETERS :
   1815  *   @super_buf: channel buffers
   1816  *   @user_data        : channel object
   1817  *
   1818  * RETURN     : none
   1819  *==========================================================================*/
   1820 void mm_camera_muxer_channel_frame_sync(mm_camera_super_buf_t *super_buf,
   1821         void *user_data)
   1822 {
   1823     int32_t rc = 0, i = 0;
   1824     mm_camera_super_buf_notify_mode_t notify_mode;
   1825     mm_channel_t *m_obj = (mm_channel_t *)user_data;
   1826     mm_channel_t *s_obj = m_obj;
   1827     mm_frame_sync_queue_node_t dispatch_buf;
   1828 
   1829     if ((super_buf == NULL) && (super_buf->num_bufs == 0)) {
   1830         return;
   1831     }
   1832 
   1833     if (m_obj->master_ch_obj != NULL) {
   1834         m_obj = m_obj->master_ch_obj;
   1835     }
   1836 
   1837     notify_mode = m_obj->bundle.superbuf_queue.attr.notify_mode;
   1838     if (notify_mode == MM_CAMERA_SUPER_BUF_NOTIFY_BURST
   1839             && (super_buf->ch_id == m_obj->my_hdl)) {
   1840         mm_camera_req_buf_t req_buf;
   1841         memset(&req_buf, 0, sizeof(req_buf));
   1842         req_buf.num_buf_requested = 1;
   1843         req_buf.frame_idx = super_buf->bufs[0]->frame_idx;
   1844         s_obj = m_obj->aux_ch_obj[0];
   1845         pthread_mutex_lock(&s_obj->cam_obj->cam_lock);
   1846         mm_camera_request_super_buf(s_obj->cam_obj,
   1847                 s_obj->my_hdl, &req_buf);
   1848     }
   1849 
   1850     memset(&dispatch_buf, 0, sizeof(dispatch_buf));
   1851     rc = mm_camera_muxer_do_frame_sync(&m_obj->frame_sync.superbuf_queue,
   1852             super_buf, &dispatch_buf);
   1853 
   1854     if (m_obj->frame_sync.super_buf_notify_cb && rc == 0 && dispatch_buf.num_objs > 1) {
   1855         for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   1856             if (dispatch_buf.super_buf[i].num_bufs != 0) {
   1857                 LOGH("Super buffer frameID : %d",
   1858                         dispatch_buf.super_buf[i].bufs[0]->frame_idx);
   1859                 m_obj->frame_sync.super_buf_notify_cb(&dispatch_buf.super_buf[i],
   1860                         m_obj->frame_sync.user_data);
   1861             }
   1862         }
   1863         if (m_obj->frame_sync.num_buf_requested > 0) {
   1864             m_obj->frame_sync.num_buf_requested--;
   1865             if (m_obj->frame_sync.num_buf_requested == 0) {
   1866                 LOGH("Stop Frame Sync chid = %d", m_obj->my_hdl);
   1867                 m_obj->frame_sync.is_active = 0;
   1868             }
   1869         }
   1870     }
   1871 }
   1872 
   1873 /*===========================================================================
   1874  * FUNCTION   : mm_camera_muxer_frame_sync_dequeue
   1875  *
   1876  * DESCRIPTION: dequeue object from frame sync queue
   1877  *
   1878  * PARAMETERS :
   1879  *   @queue: ptr to queue to dequeue object
   1880  *   @dispatch_buf        : Ptr to carry dequeued node
   1881  *
   1882  * RETURN     : int32_t type of status
   1883  *              0  -- success
   1884  *              1 -- failure
   1885  *==========================================================================*/
   1886 int32_t mm_camera_muxer_frame_sync_dequeue(
   1887         mm_frame_sync_queue_t *queue, mm_frame_sync_queue_node_t *dispatch_buf)
   1888 {
   1889     int32_t rc = 0;
   1890     cam_node_t* node = NULL;
   1891     struct cam_list *head = NULL;
   1892     struct cam_list *pos = NULL;
   1893     mm_frame_sync_queue_node_t* super_buf = NULL;
   1894 
   1895     pthread_mutex_lock(&queue->que.lock);
   1896     head = &queue->que.head.list;
   1897     pos = head->next;
   1898     if (pos != head) {
   1899         /* get the first node */
   1900         node = member_of(pos, cam_node_t, list);
   1901         super_buf = (mm_frame_sync_queue_node_t*)node->data;
   1902         if (NULL != super_buf) {
   1903             *dispatch_buf = *super_buf;
   1904             queue->que.size--;
   1905             cam_list_del_node(&node->list);
   1906             free(node);
   1907             free(super_buf);
   1908         }
   1909     }
   1910     pthread_mutex_unlock(&queue->que.lock);
   1911     return rc;
   1912 }
   1913 
   1914 /*===========================================================================
   1915  * FUNCTION   : mm_camera_muxer_do_frame_sync
   1916  *
   1917  * DESCRIPTION: function to process object buffers and match with existing frames.
   1918  *
   1919  * PARAMETERS :
   1920  *   @queue: ptr to queue to dequeue object
   1921  *   @buffer: Input buffer to match and insert
   1922  *   @dispatch_buf        : Ptr to carry matched node
   1923  *
   1924  * RETURN     : int32_t type of status
   1925  *              0  -- success
   1926  *              1 -- failure
   1927  *==========================================================================*/
   1928 int32_t mm_camera_muxer_do_frame_sync(
   1929         mm_frame_sync_queue_t *queue, mm_camera_super_buf_t *buffer,
   1930         mm_frame_sync_queue_node_t *dispatch_buf)
   1931 {
   1932     cam_node_t* node = NULL;
   1933     uint8_t buf_s_idx, found_super_buf, unmatched_bundles;
   1934     struct cam_list *head = NULL;
   1935     struct cam_list *pos = NULL;
   1936     mm_frame_sync_queue_node_t* super_buf = NULL;
   1937     struct cam_list *last_buf = NULL, *insert_before_buf = NULL;
   1938 
   1939     if (buffer == NULL || buffer->num_bufs == 0) {
   1940         LOGW("Ivalid Argument");
   1941         return -1;
   1942     }
   1943 
   1944     for (buf_s_idx = 0; buf_s_idx < queue->num_objs; buf_s_idx++) {
   1945         if ((buffer->ch_id == queue->bundled_objs[buf_s_idx]) ||
   1946                 (buffer->bufs[0]->stream_id == queue->bundled_objs[buf_s_idx])) {
   1947             break;
   1948         }
   1949     }
   1950     if (buf_s_idx == queue->num_objs) {
   1951         LOGE("buf from stream (%d) not bundled", buffer->bufs[0]->stream_id);
   1952         mm_camera_muxer_buf_done(buffer);
   1953         return -1;
   1954     }
   1955 
   1956     if (buffer->bufs[0]->frame_idx <= queue->expected_frame_id) {
   1957         LOGD("old frame. Need to release");
   1958         mm_camera_muxer_buf_done(buffer);
   1959         return 0;
   1960     }
   1961 
   1962     pthread_mutex_lock(&queue->que.lock);
   1963     head = &queue->que.head.list;
   1964     pos = head->next;
   1965     found_super_buf = 0;
   1966     unmatched_bundles = 0;
   1967     last_buf = NULL;
   1968     insert_before_buf = NULL;
   1969 
   1970     while (pos != head) {
   1971         node = member_of(pos, cam_node_t, list);
   1972         super_buf = (mm_frame_sync_queue_node_t *)node->data;
   1973 
   1974         if (NULL != super_buf) {
   1975             if (buffer->bufs[0]->frame_idx == super_buf->frame_idx) {
   1976                 found_super_buf = 1;
   1977                 break;
   1978             } else if ((buffer->bufs[0]->frame_idx >= super_buf->frame_idx)
   1979                     && (queue->priority == MM_CAMERA_SUPER_BUF_PRIORITY_LOW)) {
   1980                 found_super_buf = 1;
   1981                 break;
   1982             } else {
   1983                 unmatched_bundles++;
   1984                 if ( NULL == last_buf ) {
   1985                     if ( super_buf->frame_idx < buffer->bufs[0]->frame_idx) {
   1986                         last_buf = pos;
   1987                     }
   1988                 }
   1989                 if ( NULL == insert_before_buf ) {
   1990                     if ( super_buf->frame_idx > buffer->bufs[0]->frame_idx) {
   1991                         insert_before_buf = pos;
   1992                     }
   1993                 }
   1994                 pos = pos->next;
   1995             }
   1996         }
   1997     }
   1998 
   1999     LOGD("found_super_buf = %d id = %d unmatched = %d max = %d", found_super_buf,
   2000             buffer->bufs[0]->frame_idx, unmatched_bundles,
   2001             queue->max_unmatched_frames);
   2002     if ( found_super_buf ) {
   2003         super_buf->super_buf[buf_s_idx] = *buffer;
   2004         super_buf->num_objs++;
   2005         if (super_buf->num_objs == queue->num_objs) {
   2006             super_buf->matched = 1;
   2007             *dispatch_buf = *super_buf;
   2008             queue->que.size--;
   2009             cam_list_del_node(&node->list);
   2010             free(node);
   2011             free(super_buf);
   2012         }
   2013     } else {
   2014         if ((queue->max_unmatched_frames < unmatched_bundles)
   2015                 && (NULL == last_buf)) {
   2016             //incoming frame is older than the last bundled one
   2017             mm_camera_muxer_buf_done(buffer);
   2018         } else if (queue->max_unmatched_frames < unmatched_bundles) {
   2019             //dispatch old buffer. Cannot sync for configured unmatch value
   2020             node = member_of(last_buf, cam_node_t, list);
   2021             super_buf = (mm_frame_sync_queue_node_t*)node->data;
   2022             *dispatch_buf = *super_buf;
   2023             queue->que.size--;
   2024             cam_list_del_node(&node->list);
   2025             free(node);
   2026             free(super_buf);
   2027         }
   2028 
   2029         //insert the new frame at the appropriate position.
   2030         mm_frame_sync_queue_node_t *new_buf = NULL;
   2031         cam_node_t* new_node = NULL;
   2032 
   2033         new_buf = (mm_frame_sync_queue_node_t *)malloc(sizeof(mm_frame_sync_queue_node_t));
   2034         if (NULL != new_buf) {
   2035             memset(new_buf, 0, sizeof(mm_channel_queue_node_t));
   2036             new_buf->super_buf[buf_s_idx] = *buffer;
   2037             new_buf->num_objs++;
   2038             new_buf->frame_idx = buffer->bufs[0]->frame_idx;
   2039             if (new_buf->num_objs == queue->num_objs) {
   2040                 new_buf->matched = 1;
   2041                 *dispatch_buf = *new_buf;
   2042                 queue->que.size--;
   2043                 free(new_buf);
   2044                 free(new_node);
   2045             } else {
   2046                 /* enqueue */
   2047                 new_node = (cam_node_t *)malloc(sizeof(cam_node_t));
   2048                 memset(new_node, 0, sizeof(cam_node_t));
   2049                 new_node->data = (void *)new_buf;
   2050                 if ( insert_before_buf ) {
   2051                     cam_list_insert_before_node(&new_node->list, insert_before_buf);
   2052                 } else {
   2053                     cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
   2054                 }
   2055                 queue->que.size++;
   2056             }
   2057         } else {
   2058             if (NULL != new_buf) {
   2059                 free(new_buf);
   2060             }
   2061             mm_camera_muxer_buf_done(buffer);
   2062         }
   2063     }
   2064 
   2065     if (dispatch_buf != NULL && dispatch_buf->num_objs != 0) {
   2066        queue->expected_frame_id = queue->expected_frame_id;
   2067     }
   2068     pthread_mutex_unlock(&queue->que.lock);
   2069     return 0;
   2070 }
   2071 
   2072 /*===========================================================================
   2073  * FUNCTION   : mm_camera_muxer_buf_done
   2074  *
   2075  * DESCRIPTION: function release super buffer.
   2076  *
   2077  * PARAMETERS :
   2078  *   @buffer: ptr to super buffer to release.
   2079  *
   2080  * RETURN     : int32_t type of status
   2081  *              0  -- success
   2082  *              1 -- failure
   2083  *==========================================================================*/
   2084 void mm_camera_muxer_buf_done(mm_camera_super_buf_t *buffer)
   2085 {
   2086     uint8_t i;
   2087     mm_camera_obj_t *my_obj = NULL;
   2088 
   2089     if (buffer == NULL) {
   2090         LOGW("Null buffer");
   2091         return;
   2092     }
   2093 
   2094     my_obj = mm_camera_util_get_camera_by_handler(buffer->camera_handle);
   2095     for (i=0; i < buffer->num_bufs; i++) {
   2096         if (buffer->bufs[i] != NULL) {
   2097             mm_camera_qbuf(my_obj, buffer->ch_id, buffer->bufs[i]);
   2098         }
   2099     }
   2100 }
   2101 
   2102 /*===========================================================================
   2103  * FUNCTION   : mm_muxer_frame_sync_queue_init
   2104  *
   2105  * DESCRIPTION: Inittialize frame sync queue
   2106  *
   2107  * PARAMETERS :
   2108  *   @queue: ptr to frame sync queue
   2109  *
   2110  * RETURN     : int32_t type of status
   2111  *              0  -- success
   2112  *              1 -- failure
   2113  *==========================================================================*/
   2114 int32_t mm_muxer_frame_sync_queue_init(mm_frame_sync_queue_t *queue)
   2115 {
   2116     int32_t rc = 0;
   2117     queue->expected_frame_id = 0;
   2118     queue->num_objs = 0;
   2119     memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
   2120     rc = cam_queue_init(&queue->que);
   2121     return rc;
   2122 }
   2123 
   2124 /*===========================================================================
   2125  * FUNCTION   : mm_muxer_frame_sync_queue_deinit
   2126  *
   2127  * DESCRIPTION: Inittialize frame sync queue
   2128  *
   2129  * PARAMETERS :
   2130  *   @queue: ptr to frame sync queue
   2131  *
   2132  * RETURN     : int32_t type of status
   2133  *              0  -- success
   2134  *              1 -- failure
   2135  *==========================================================================*/
   2136 int32_t mm_muxer_frame_sync_queue_deinit(mm_frame_sync_queue_t *queue)
   2137 {
   2138     int32_t rc = 0;
   2139     rc = cam_queue_deinit(&queue->que);
   2140     return rc;
   2141 }
   2142 
   2143 /*===========================================================================
   2144  * FUNCTION   : mm_camera_muxer_stream_frame_sync_flush
   2145  *
   2146  * DESCRIPTION: function to flush frame sync queue
   2147  *
   2148  * PARAMETERS :
   2149  *   @queue: ptr to frame sync queue
   2150  *
   2151  * RETURN     : int32_t type of status
   2152  *              0  -- success
   2153  *              1 -- failure
   2154  *==========================================================================*/
   2155 int32_t mm_camera_muxer_stream_frame_sync_flush(mm_stream_t *str_obj)
   2156 {
   2157     int32_t rc = 0, i = 0;
   2158     mm_stream_t *my_obj = str_obj;
   2159     mm_frame_sync_queue_node_t super_buf;
   2160     memset(&super_buf, 0, sizeof(super_buf));
   2161 
   2162     if (my_obj->master_str_obj) {
   2163         my_obj = my_obj->master_str_obj;
   2164     }
   2165 
   2166     rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
   2167     while (super_buf.num_objs != 0 && rc != 0) {
   2168         for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   2169             mm_camera_super_buf_t dispatch_buf;
   2170             memset(&dispatch_buf, 0, sizeof(dispatch_buf));
   2171             if (super_buf.super_buf[i].num_bufs == 1) {
   2172                 dispatch_buf.bufs[dispatch_buf.num_bufs++] =
   2173                         super_buf.super_buf[i].bufs[0];
   2174                 dispatch_buf.camera_handle |= super_buf.super_buf[i].camera_handle;
   2175                 dispatch_buf.ch_id |= super_buf.super_buf[i].ch_id;
   2176                 my_obj->frame_sync.super_buf_notify_cb(&dispatch_buf,
   2177                         my_obj->frame_sync.user_data);
   2178             }
   2179         }
   2180         rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
   2181     }
   2182     return rc;
   2183 }
   2184 
   2185 /*===========================================================================
   2186  * FUNCTION   : mm_camera_muxer_channel_frame_sync_flush
   2187  *
   2188  * DESCRIPTION: function to flush frame sync queue
   2189  *
   2190  * PARAMETERS :
   2191  *   @queue: ptr to frame sync queue
   2192  *
   2193  * RETURN     : int32_t type of status
   2194  *              0  -- success
   2195  *              1 -- failure
   2196  *==========================================================================*/
   2197 int32_t mm_camera_muxer_channel_frame_sync_flush(mm_channel_t *my_obj)
   2198 {
   2199     int32_t rc = 0, i = 0;
   2200     mm_frame_sync_queue_node_t super_buf;
   2201     memset(&super_buf, 0, sizeof(super_buf));
   2202 
   2203     if (my_obj->master_ch_obj) {
   2204         my_obj = my_obj->master_ch_obj;
   2205     }
   2206 
   2207     rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
   2208     while (super_buf.num_objs != 0 && rc != 0) {
   2209         for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
   2210             if (super_buf.super_buf[i].num_bufs == 1) {
   2211                 mm_camera_muxer_buf_done(&super_buf.super_buf[i]);
   2212             }
   2213         }
   2214         rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
   2215     }
   2216 
   2217     return rc;
   2218 }
   2219 
   2220 /*===========================================================================
   2221  * FUNCTION   : mm_camera_muxer_get_stream_buf_cnt
   2222  *
   2223  * DESCRIPTION: function to calculate buffer count for auxillary streams.
   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 uint32_t mm_camera_muxer_get_stream_buf_cnt(mm_stream_t *str_obj)
   2233 {
   2234     uint32_t buf_cnt = 0;
   2235     uint8_t i = 0;
   2236     mm_stream_t *my_obj = str_obj;
   2237 
   2238     if (str_obj->master_str_obj != NULL) {
   2239         my_obj = str_obj->master_str_obj;
   2240     }
   2241 
   2242     buf_cnt = my_obj->buf_num;
   2243     for (i = 0; i < my_obj->num_s_cnt; i++) {
   2244         if (my_obj->aux_str_obj[i]->is_res_shared) {
   2245             buf_cnt += my_obj->aux_str_obj[i]->buf_num;
   2246         }
   2247     }
   2248     if (buf_cnt > CAM_MAX_NUM_BUFS_PER_STREAM) {
   2249         buf_cnt = CAM_MAX_NUM_BUFS_PER_STREAM;
   2250     }
   2251     return buf_cnt;
   2252 }
   2253 
   2254 /*===========================================================================
   2255  * FUNCTION   : mm_camera_muxer_get_stream_bufs
   2256  *
   2257  * DESCRIPTION: function to assign buffers for auxillary streams.
   2258  *
   2259  * PARAMETERS :
   2260  *   @queue: ptr to frame sync queue
   2261  *
   2262  * RETURN     : int32_t type of status
   2263  *              0  -- success
   2264  *              1 -- failure
   2265  *==========================================================================*/
   2266 int32_t mm_camera_muxer_get_stream_bufs(mm_stream_t *my_obj)
   2267 {
   2268     int32_t rc = 0;
   2269     uint32_t i = 0;
   2270     mm_stream_t *master_obj = NULL;
   2271 
   2272     if (my_obj == NULL || my_obj->master_str_obj == NULL
   2273             || !my_obj->is_res_shared) {
   2274         LOGE("Invalid argument");
   2275         return rc;
   2276     }
   2277     master_obj = my_obj->master_str_obj;
   2278 
   2279     if (master_obj->total_buf_cnt == 0) {
   2280         my_obj->buf_idx = 0;
   2281         return rc;
   2282     }
   2283 
   2284     if ((master_obj->total_buf_cnt -
   2285             (master_obj->buf_idx + master_obj->buf_num))
   2286             <= 0) {
   2287         LOGE("No enough buffer available %d num_bufs = %d",
   2288                 master_obj->total_buf_cnt, master_obj->buf_num);
   2289         return rc;
   2290     }
   2291 
   2292     my_obj->total_buf_cnt = master_obj->total_buf_cnt;
   2293     my_obj->buf_idx = master_obj->buf_idx + master_obj->buf_num;
   2294     if ((my_obj->buf_idx + my_obj->buf_num) > my_obj->total_buf_cnt) {
   2295         my_obj->buf_num = my_obj->total_buf_cnt - my_obj->buf_idx;
   2296     }
   2297 
   2298     my_obj->buf = master_obj->buf;
   2299     for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
   2300         my_obj->buf_status[i].initial_reg_flag =
   2301                 master_obj->buf_status[i].initial_reg_flag;
   2302     }
   2303     LOGH("Buffer total = %d buf_cnt = %d offsset = %d",my_obj->total_buf_cnt,
   2304             my_obj->buf_num, my_obj->buf_idx);
   2305     return 0;
   2306 }
   2307 
   2308 /*===========================================================================
   2309  * FUNCTION   : mm_camera_muxer_put_stream_bufs
   2310  *
   2311  * DESCRIPTION: function to release buffers for auxillary streams.
   2312  *
   2313  * PARAMETERS :
   2314  *   @queue: ptr to frame sync queue
   2315  *
   2316  * RETURN     : int32_t type of status
   2317  *              0  -- success
   2318  *              1 -- failure
   2319  *==========================================================================*/
   2320 int32_t mm_camera_muxer_put_stream_bufs(mm_stream_t *my_obj)
   2321 {
   2322     int32_t rc = -1;
   2323 
   2324     if (my_obj == NULL || !my_obj->is_res_shared) {
   2325         LOGE("Invalid argument");
   2326         return rc;
   2327     }
   2328     my_obj->total_buf_cnt = 0;
   2329     return 0;
   2330 }
   2331 
   2332 /*===========================================================================
   2333  * FUNCTION   : mm_camera_map_stream_buf_ops
   2334  *
   2335  * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
   2336  *              This function will be passed to upper layer as part of ops table
   2337  *              to be used by upper layer when allocating stream buffers and mapping
   2338  *              buffers to server via domain socket.
   2339  *
   2340  * PARAMETERS :
   2341  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   2342  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2343  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2344  *   @plane_idx    : plane index. If all planes share the same fd,
   2345  *                   plane_idx = -1; otherwise, plean_idx is the
   2346  *                   index to plane (0..num_of_planes)
   2347  *   @fd           : file descriptor of the buffer
   2348  *   @size         : size of the buffer
   2349  *   @userdata     : user data ptr (stream object)
   2350  *
   2351  * RETURN     : int32_t type of status
   2352  *              0  -- success
   2353  *              -1 -- failure
   2354  *==========================================================================*/
   2355 int32_t mm_camera_map_stream_buf_ops(uint32_t buf_idx,
   2356         int32_t plane_idx, int fd, size_t size,
   2357         void *buffer, cam_mapping_buf_type type,
   2358         void *userdata)
   2359 {
   2360     int32_t rc = 0;
   2361     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   2362     int32_t i = 0;
   2363 
   2364     switch (type) {
   2365         case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
   2366         case CAM_MAPPING_BUF_TYPE_MISC_BUF:
   2367             if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
   2368                 my_obj = my_obj->aux_str_obj[buf_idx];
   2369             }
   2370             break;
   2371         case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
   2372         case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
   2373         case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
   2374         case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
   2375             for(i = 0; i < my_obj->num_s_cnt; i++) {
   2376                 if (my_obj->aux_str_obj[i] != NULL) {
   2377                     rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
   2378                             type, buf_idx, plane_idx, fd, size, buffer);
   2379                 }
   2380             }
   2381             break;
   2382         default:
   2383             LOGE("Not buffer for stream : %d", type);
   2384             rc = -1;
   2385             break;
   2386     }
   2387 
   2388     if (rc == 0) {
   2389         rc = mm_stream_map_buf(my_obj,
   2390                 type, buf_idx, plane_idx, fd, size, buffer);
   2391     }
   2392     return rc;
   2393 }
   2394 
   2395 /*===========================================================================
   2396  * FUNCTION   : mm_camera_muxer_bundled_map_buf_ops
   2397  *
   2398  * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
   2399  *              This function will be passed to upper layer as part of ops table
   2400  *              to be used by upper layer when allocating stream buffers and mapping
   2401  *              buffers to server via domain socket.
   2402  *
   2403  * PARAMETERS :
   2404  *   @buf_map_list : list of buffer mapping information
   2405  *   @userdata     : user data ptr (stream object)
   2406  *
   2407  * RETURN     : int32_t type of status
   2408  *              0  -- success
   2409  *              -1 -- failure
   2410  *==========================================================================*/
   2411 int32_t mm_camera_bundled_map_stream_buf_ops(
   2412         const cam_buf_map_type_list *buf_map_list,
   2413         void *userdata)
   2414 {
   2415     int32_t rc = 0;
   2416     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   2417     uint32_t i = 0;
   2418 
   2419     if (buf_map_list == NULL || buf_map_list->length == 0) {
   2420         LOGW("Invalid argument");
   2421         return rc;
   2422     }
   2423 
   2424     uint32_t buf_idx;
   2425     cam_mapping_buf_type type = buf_map_list->buf_maps[0].type;
   2426     switch (type) {
   2427         case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
   2428         case CAM_MAPPING_BUF_TYPE_MISC_BUF:
   2429             buf_idx = buf_map_list->buf_maps[0].frame_idx;
   2430             if (buf_idx == 0) {
   2431                 rc = mm_stream_map_buf(my_obj,
   2432                         type, buf_idx,
   2433                         buf_map_list->buf_maps[0].plane_idx,
   2434                         buf_map_list->buf_maps[0].fd,
   2435                         buf_map_list->buf_maps[0].size,
   2436                         buf_map_list->buf_maps[0].buffer);
   2437                 if (rc != 0) {
   2438                     LOGE("Failed rc = %d", rc);
   2439                 }
   2440             }
   2441             for (i = 1; i < buf_map_list->length; i++) {
   2442                 buf_idx = buf_map_list->buf_maps[i].frame_idx;
   2443                 if ((i == buf_idx)
   2444                         && (my_obj->aux_str_obj[i] != NULL)) {
   2445                     rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
   2446                             type, buf_idx,
   2447                             buf_map_list->buf_maps[i].plane_idx,
   2448                             buf_map_list->buf_maps[i].fd,
   2449                             buf_map_list->buf_maps[i].size,
   2450                             buf_map_list->buf_maps[i].buffer);
   2451                 }
   2452             }
   2453             break;
   2454         case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
   2455         case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
   2456         case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
   2457         case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
   2458             rc = mm_stream_map_bufs(my_obj, buf_map_list);
   2459             for(i = 0; i < my_obj->num_s_cnt; i++) {
   2460                 if (my_obj->aux_str_obj[i] != NULL) {
   2461                     rc = mm_stream_map_bufs(my_obj->aux_str_obj[i],
   2462                             buf_map_list);
   2463                 }
   2464             }
   2465             break;
   2466         default:
   2467             LOGE("Not buffer for stream : %d", type);
   2468             rc = -1;
   2469             break;
   2470     }
   2471     return rc;
   2472 }
   2473 
   2474 /*===========================================================================
   2475  * FUNCTION   : mm_camera_muxer_unmap_buf_ops
   2476  *
   2477  * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
   2478  *              This function will be passed to upper layer as part of ops table
   2479  *              to be used by upper layer when allocating stream buffers and unmapping
   2480  *              buffers to server via domain socket.
   2481  *
   2482  * PARAMETERS :
   2483  *   @frame_idx    : index of buffer within the stream buffers, only valid if
   2484  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   2485  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   2486  *   @plane_idx    : plane index. If all planes share the same fd,
   2487  *                   plane_idx = -1; otherwise, plean_idx is the
   2488  *                   index to plane (0..num_of_planes)
   2489  *   @userdata     : user data ptr (stream object)
   2490  *
   2491  * RETURN     : int32_t type of status
   2492  *              0  -- success
   2493  *              -1 -- failure
   2494  *==========================================================================*/
   2495 int32_t mm_camera_unmap_stream_buf_ops(uint32_t buf_idx,
   2496            int32_t plane_idx, cam_mapping_buf_type type, void *userdata)
   2497 {
   2498     int32_t rc = 0;
   2499     mm_stream_t *my_obj = (mm_stream_t *)userdata;
   2500     int32_t i = 0;
   2501 
   2502     switch (type) {
   2503         case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
   2504         case CAM_MAPPING_BUF_TYPE_MISC_BUF:
   2505             if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
   2506                 my_obj = my_obj->aux_str_obj[buf_idx];
   2507             }
   2508             break;
   2509         case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
   2510         case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
   2511         case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
   2512         case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
   2513             for(i = 0; i < my_obj->num_s_cnt; i++) {
   2514                 if (my_obj->aux_str_obj[i] != NULL) {
   2515                     rc = mm_stream_unmap_buf(my_obj->aux_str_obj[i],
   2516                             type, buf_idx, plane_idx);
   2517                 }
   2518             }
   2519             break;
   2520         default:
   2521             LOGE("Not buffer for stream : %d", type);
   2522             rc = -1;
   2523             break;
   2524     }
   2525 
   2526     if (rc == 0) {
   2527         rc = mm_stream_unmap_buf(my_obj,
   2528                 type, buf_idx, plane_idx);
   2529     }
   2530     return rc;
   2531 }
   2532 
   2533 
   2534