| /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of The Linux Foundation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| */ |
| |
| // To remove |
| #include <cutils/properties.h> |
| |
| // System dependencies |
| #include <pthread.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdlib.h> |
| #include <linux/media.h> |
| #include <media/msm_cam_sensor.h> |
| #include <dlfcn.h> |
| |
| #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h> |
| #include IOCTL_H |
| |
| // Camera dependencies |
| #include "mm_camera_dbg.h" |
| #include "mm_camera_interface.h" |
| #include "mm_camera.h" |
| #include "mm_camera_muxer.h" |
| |
| static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; |
| static mm_camera_ctrl_t g_cam_ctrl; |
| |
| static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; |
| static uint8_t g_handler_history_count = 0; /* history count for handler */ |
| |
| // 16th (starting from 0) bit tells its a BACK or FRONT camera |
| #define CAM_SENSOR_FACING_MASK (1U<<16) |
| |
| #ifdef DUAL_CAM_TEST //Temporary macro. Will be removed once we finalize sensor change. |
| // 24th (starting from 0) bit tells its a MAIN or AUX camera |
| #define CAM_SENSOR_MODE_MASK_MAIN (1U<<24) |
| #define CAM_SENSOR_MODE_MASK_AUX (1U<<25) |
| #define CAM_SENSOR_MODE_MASK_SECURE (1U<<26) |
| |
| // 28th (starting from 0) bit tells its YUV sensor or not |
| #define CAM_SENSOR_FORMAT_MASK (1U<<28) |
| #else |
| #define CAM_SENSOR_TYPE_MASK (1U<<24) |
| #define CAM_SENSOR_FORMAT_MASK (1U<<25) |
| #endif |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_generate_handler |
| * |
| * DESCRIPTION: utility function to generate handler for camera/channel/stream |
| * |
| * PARAMETERS : |
| * @index: index of the object to have handler |
| * |
| * RETURN : uint32_t type of handle that uniquely identify the object |
| *==========================================================================*/ |
| uint32_t mm_camera_util_generate_handler(uint8_t index) |
| { |
| uint32_t handler = 0; |
| pthread_mutex_lock(&g_handler_lock); |
| g_handler_history_count++; |
| if (0 == g_handler_history_count) { |
| g_handler_history_count++; |
| } |
| handler = g_handler_history_count; |
| handler = (handler<<8) | index; |
| pthread_mutex_unlock(&g_handler_lock); |
| return handler; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_get_index_by_handler |
| * |
| * DESCRIPTION: utility function to get index from handle |
| * |
| * PARAMETERS : |
| * @handler: object handle |
| * |
| * RETURN : uint8_t type of index derived from handle |
| *==========================================================================*/ |
| uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) |
| { |
| return (handler & 0x000000ff); |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_get_dev_name |
| * |
| * DESCRIPTION: utility function to get device name from camera handle |
| * |
| * PARAMETERS : |
| * @cam_handle: camera handle |
| * |
| * RETURN : char ptr to the device name stored in global variable |
| * NOTE : caller should not free the char ptr |
| *==========================================================================*/ |
| const char *mm_camera_util_get_dev_name(uint32_t cam_handle) |
| { |
| char *dev_name = NULL; |
| uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); |
| if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { |
| dev_name = g_cam_ctrl.video_dev_name[cam_idx]; |
| } |
| return dev_name; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_get_camera_by_handler |
| * |
| * DESCRIPTION: utility function to get camera object from camera handle |
| * |
| * PARAMETERS : |
| * @cam_handle: camera handle |
| * |
| * RETURN : ptr to the camera object stored in global variable |
| * NOTE : caller should not free the camera object ptr |
| *==========================================================================*/ |
| mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle) |
| { |
| mm_camera_obj_t *cam_obj = NULL; |
| uint8_t cam_idx = 0; |
| |
| for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) { |
| if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) && |
| (cam_handle == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { |
| cam_obj = g_cam_ctrl.cam_obj[cam_idx]; |
| break; |
| } |
| } |
| return cam_obj; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_set_camera_object |
| * |
| * DESCRIPTION: utility function to set camera object to global structure |
| * |
| * PARAMETERS : |
| * @cam_idx : index to store cambera object |
| * @obj : Camera object to store |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj) |
| { |
| int32_t rc = 0; |
| pthread_mutex_lock(&g_intf_lock); |
| if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { |
| g_cam_ctrl.cam_obj[cam_idx] = obj; |
| } else { |
| rc = -1; |
| } |
| pthread_mutex_unlock(&g_intf_lock); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_get_camera_head_obj |
| * |
| * DESCRIPTION: utility function to get camera object from camera handle |
| * |
| * PARAMETERS : |
| * @cam_handle: camera handle |
| * |
| * RETURN : ptr to the master/primary camera object |
| *==========================================================================*/ |
| mm_camera_obj_t* mm_camera_util_get_camera_head(uint32_t cam_handle) |
| { |
| mm_camera_obj_t *cam_obj = NULL; |
| |
| cam_obj = mm_camera_util_get_camera_by_handler(cam_handle); |
| if (cam_obj != NULL && cam_obj->master_cam_obj != NULL) { |
| cam_obj = cam_obj->master_cam_obj; |
| } |
| return cam_obj; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_util_get_camera_by_session_id |
| * |
| * DESCRIPTION: utility function to get camera object from camera sessionID |
| * |
| * PARAMETERS : |
| * @session_id: sessionid for which cam obj mapped |
| * |
| * RETURN : ptr to the camera object stored in global variable |
| * NOTE : caller should not free the camera object ptr |
| *==========================================================================*/ |
| mm_camera_obj_t* mm_camera_util_get_camera_by_session_id(uint32_t session_id) |
| { |
| int cam_idx = 0; |
| mm_camera_obj_t *cam_obj = NULL; |
| for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) { |
| if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) && |
| (session_id == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->sessionid)) { |
| LOGD("session id:%d match idx:%d\n", session_id, cam_idx); |
| cam_obj = g_cam_ctrl.cam_obj[cam_idx]; |
| } |
| } |
| return cam_obj; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_query_capability |
| * |
| * DESCRIPTION: query camera capability |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_query_capability(uint32_t camera_handle) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t *my_obj = NULL; |
| uint32_t handle = 0; |
| uint32_t aux_handle = 0; |
| |
| LOGD("E: camera_handler = %d ", camera_handle); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| handle = get_main_camera_handle(camera_handle); |
| aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (handle) { |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_query_capability(my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_query_capability(aux_handle, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGH("camera_handle = %d rc = %d X", camera_handle, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_set_parms |
| * |
| * DESCRIPTION: set parameters per camera |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @parms : ptr to a param struct to be set to server |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : Assume the parms struct buf is already mapped to server via |
| * domain socket. Corresponding fields of parameters to be set |
| * are already filled in by upper layer caller. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_set_parms(uint32_t camera_handle, |
| parm_buffer_t *parms) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_set_parms(aux_handle, |
| parms, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_set_parms(my_obj, parms); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_get_parms |
| * |
| * DESCRIPTION: get parameters per camera |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @parms : ptr to a param struct to be get from server |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : Assume the parms struct buf is already mapped to server via |
| * domain socket. Parameters to be get from server are already |
| * filled in by upper layer caller. After this call, corresponding |
| * fields of requested parameters will be filled in by server with |
| * detailed information. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_get_parms(uint32_t camera_handle, |
| parm_buffer_t *parms) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_get_parms(aux_handle, |
| parms, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_get_parms(my_obj, parms); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_do_auto_focus |
| * |
| * DESCRIPTION: performing auto focus |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : if this call success, we will always assume there will |
| * be an auto_focus event following up. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_do_auto_focus(aux_handle, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_do_auto_focus(my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("rc = %d camera_handle = %d X", rc, camera_handle); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_cancel_auto_focus |
| * |
| * DESCRIPTION: cancel auto focus |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_cancel_auto_focus(aux_handle, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_cancel_auto_focus(my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("rc = %d camera_handle = %d X", rc, camera_handle); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_prepare_snapshot |
| * |
| * DESCRIPTION: prepare hardware for snapshot |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @do_af_flag : flag indicating if AF is needed |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle, |
| int32_t do_af_flag) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_prepare_snapshot(aux_handle, |
| do_af_flag, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| |
| rc = mm_camera_prepare_snapshot(my_obj, do_af_flag); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| return rc; |
| } |
| LOGH("rc = %d camera_handle = %d X", rc, camera_handle); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_flush |
| * |
| * DESCRIPTION: flush the current camera state and buffers |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_flush(uint32_t camera_handle) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_flush(aux_handle, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(camera_handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_flush(my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_close |
| * |
| * DESCRIPTION: close a camera by its handle |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_close(uint32_t camera_handle) |
| { |
| int32_t rc = -1; |
| uint8_t cam_idx = -1; |
| mm_camera_obj_t *my_obj = NULL; |
| |
| LOGD("E: camera_handler = %d ", camera_handle); |
| |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_close_camera(aux_handle, my_obj); |
| } |
| } |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if (my_obj){ |
| if (my_obj->aux_cam_obj[0] != NULL) { |
| /*Close aux cameras*/ |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_close_camera( |
| my_obj->aux_cam_obj[0]->my_hdl, my_obj); |
| pthread_mutex_lock(&g_intf_lock); |
| } |
| |
| cam_idx = mm_camera_util_get_index_by_num( |
| my_obj->my_num, my_obj->my_hdl); |
| my_obj->ref_count--; |
| if(my_obj->ref_count > 0) { |
| /* still have reference to obj, return here */ |
| LOGD("ref_count=%d\n", my_obj->ref_count); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = 0; |
| } else { |
| /* need close camera here as no other reference |
| * first empty g_cam_ctrl's referent to cam_obj */ |
| g_cam_ctrl.cam_obj[cam_idx] = NULL; |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_close(my_obj); |
| pthread_mutex_destroy(&my_obj->cam_lock); |
| pthread_mutex_destroy(&my_obj->muxer_lock); |
| free(my_obj); |
| my_obj = NULL; |
| } |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| |
| LOGH("camera_handler = %d rc = %d", camera_handle, rc); |
| #ifdef QCAMERA_REDEFINE_LOG |
| mm_camera_debug_close(); |
| #endif |
| |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_add_channel |
| * |
| * DESCRIPTION: add a channel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @attr : bundle attribute of the channel if needed |
| * @channel_cb : callback function for bundle data notify |
| * @userdata : user data ptr |
| * |
| * RETURN : uint32_t type of channel handle |
| * 0 -- invalid channel handle, meaning the op failed |
| * >0 -- successfully added a channel with a valid handle |
| * NOTE : if no bundle data notify is needed, meaning each stream in the |
| * channel will have its own stream data notify callback, then |
| * attr, channel_cb, and userdata can be NULL. In this case, |
| * no matching logic will be performed in channel for the bundling. |
| *==========================================================================*/ |
| static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle, |
| mm_camera_channel_attr_t *attr, |
| mm_camera_buf_notify_t channel_cb, |
| void *userdata) |
| { |
| uint32_t ch_id = 0, aux_ch_id = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| LOGD("E camera_handler = %d", camera_handle); |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| aux_ch_id = mm_camera_muxer_add_channel(aux_handle, attr, |
| channel_cb, userdata, ch_id, my_obj); |
| if (aux_ch_id <= 0) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| mm_camera_del_channel(my_obj, ch_id); |
| } else { |
| ch_id |= aux_ch_id; |
| } |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("camera_handle = %d ch_id = %d X", ch_id); |
| return ch_id; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_del_channel |
| * |
| * DESCRIPTION: delete a channel by its handle |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : all streams in the channel should be stopped already before |
| * this channel can be deleted. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_del_channel(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| LOGD("E ch_id = %d", ch_id); |
| |
| if (aux_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| mm_camera_muxer_delete_channel(aux_handle, aux_chid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (m_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_del_channel(my_obj, m_chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("rc = %d ch_id = %d X", rc, ch_id); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_get_bundle_info |
| * |
| * DESCRIPTION: query bundle info of the channel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @bundle_info : bundle info to be filled in |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : all streams in the channel should be stopped already before |
| * this channel can be deleted. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle, |
| uint32_t ch_id, |
| cam_bundle_config_t *bundle_info) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| LOGD("E ch_id = %d", ch_id); |
| |
| if (aux_chid && m_chid) { |
| LOGE("Does not support 2 channels for bundle info"); |
| return rc; |
| } |
| |
| if (aux_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_get_bundle_info(aux_handle, aux_chid, |
| bundle_info, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (m_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_get_bundle_info(my_obj, m_chid, bundle_info); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("rc = %d ch_id = %d X", rc, ch_id); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_register_event_notify |
| * |
| * DESCRIPTION: register for event notify |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @evt_cb : callback for event notify |
| * @user_data : user data ptr |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle, |
| mm_camera_event_notify_t evt_cb, |
| void * user_data) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t *my_obj = NULL; |
| LOGD("E "); |
| |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_register_event_notify(aux_handle, |
| evt_cb, user_data, my_obj); |
| } |
| } |
| LOGD("E rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_qbuf |
| * |
| * DESCRIPTION: enqueue buffer back to kernel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @buf : buf ptr to be enqueued |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_qbuf(uint32_t camera_handle, |
| uint32_t ch_id, |
| mm_camera_buf_def_t *buf) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t *my_obj = NULL; |
| uint32_t strid = 0; |
| uint32_t aux_strid = 0; |
| |
| if (buf != NULL) { |
| strid = get_main_camera_handle(buf->stream_id); |
| aux_strid = get_aux_camera_handle(buf->stream_id); |
| } |
| |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_qbuf(my_obj, chid, buf); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_qbuf(aux_handle, aux_chid, buf, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X evt_type = %d",rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_get_queued_buf_count |
| * |
| * DESCRIPTION: returns the queued buffer count |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream id |
| * |
| * RETURN : int32_t - queued buffer count |
| * |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_get_queued_buf_count(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_main_camera_handle(stream_id); |
| |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_get_queued_buf_count(my_obj, chid, stream_id); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_get_queued_buf_count(aux_handle, |
| aux_chid, aux_strid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X queued buffer count = %d",rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_link_stream |
| * |
| * DESCRIPTION: link a stream into a new channel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream id |
| * @linked_ch_id : channel in which the stream will be linked |
| * |
| * RETURN : int32_t type of stream handle |
| * 0 -- invalid stream handle, meaning the op failed |
| * >0 -- successfully linked a stream with a valid handle |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_link_stream(uint32_t camera_handle, |
| uint32_t ch_id, |
| uint32_t stream_id, |
| uint32_t linked_ch_id) |
| { |
| uint32_t id = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(stream_id); |
| uint32_t linked_chid = get_main_camera_handle(linked_ch_id); |
| uint32_t aux_linked_chid = get_aux_camera_handle(linked_ch_id); |
| |
| LOGD("E handle = %u ch_id = %u", |
| camera_handle, ch_id); |
| |
| if (strid && linked_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| id = mm_camera_link_stream(my_obj, m_chid, strid, linked_chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid && aux_linked_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| id = mm_camera_muxer_link_stream(aux_handle, aux_chid, |
| aux_strid, aux_linked_chid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGH("X ch_id = %d stream_id = %d linked_ch_id = %d id = %d", |
| ch_id, stream_id, linked_ch_id, id); |
| return (int32_t)id; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_add_stream |
| * |
| * DESCRIPTION: add a stream into a channel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : uint32_t type of stream handle |
| * 0 -- invalid stream handle, meaning the op failed |
| * >0 -- successfully added a stream with a valid handle |
| *==========================================================================*/ |
| static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| uint32_t stream_id = 0, aux_stream_id; |
| mm_camera_obj_t *my_obj = NULL; |
| uint32_t m_ch_id = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| LOGD("E handle = %d ch_id = %d", |
| camera_handle, ch_id); |
| if (m_ch_id) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| stream_id = mm_camera_add_stream(my_obj, m_ch_id); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| aux_stream_id = mm_camera_muxer_add_stream(aux_handle, aux_chid, |
| m_ch_id, stream_id, my_obj); |
| if (aux_stream_id <= 0) { |
| LOGE("Failed to add stream"); |
| pthread_mutex_lock(&my_obj->cam_lock); |
| mm_camera_del_stream(my_obj, m_ch_id, stream_id); |
| } else { |
| stream_id = stream_id | aux_stream_id; |
| } |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("X ch_id = %d stream_id = %d", ch_id, stream_id); |
| return stream_id; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_del_stream |
| * |
| * DESCRIPTION: delete a stream by its handle |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : stream should be stopped already before it can be deleted. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_del_stream(uint32_t camera_handle, |
| uint32_t ch_id, |
| uint32_t stream_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t m_strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(stream_id); |
| |
| LOGD("E handle = %d ch_id = %d stream_id = %d", |
| camera_handle, ch_id, stream_id); |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| mm_camera_muxer_delete_stream(aux_handle, aux_chid, |
| aux_strid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (m_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_del_stream(my_obj, m_chid, m_strid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("X stream_id = %d rc = %d", stream_id, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_config_stream |
| * |
| * DESCRIPTION: configure a stream |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * @config : stream configuration |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_config_stream(uint32_t camera_handle, |
| uint32_t ch_id, |
| uint32_t stream_id, |
| mm_camera_stream_config_t *config) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(stream_id); |
| |
| LOGD("E handle = %d, ch_id = %d,stream_id = %d", |
| camera_handle, ch_id, stream_id); |
| |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_config_stream(my_obj, chid, strid, config); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid && rc == 0) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_config_stream(aux_handle, |
| aux_chid, aux_strid, config, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("X stream_id = %d rc = %d", stream_id, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_start_channel |
| * |
| * DESCRIPTION: start a channel, which will start all streams in the channel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_start_channel(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| if (chid) { |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| pthread_mutex_lock(&g_intf_lock); |
| |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_start_channel(my_obj, chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_chid && rc == 0) { |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| pthread_mutex_lock(&g_intf_lock); |
| |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_start_channel(aux_handle, aux_chid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("X ch_id = %d rc = %d", ch_id, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_stop_channel |
| * |
| * DESCRIPTION: stop a channel, which will stop all streams in the channel |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| if (aux_chid) { |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| pthread_mutex_lock(&g_intf_lock); |
| |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_stop_channel(aux_handle, aux_chid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (chid) { |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| pthread_mutex_lock(&g_intf_lock); |
| |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_stop_channel(my_obj, chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("X ch_id = %d rc = %d", ch_id, rc); |
| return rc; |
| |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_request_super_buf |
| * |
| * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched |
| * frames from superbuf queue |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @buf : request buffer info |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle, |
| uint32_t ch_id, mm_camera_req_buf_t *buf) |
| { |
| int32_t rc = -1; |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| if (aux_chid && chid) { |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if (my_obj && buf) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_request_super_buf( |
| ch_id, buf, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (chid) { |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj && buf) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_request_super_buf (my_obj, chid, buf); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (aux_chid) { |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(aux_handle); |
| |
| if(my_obj && buf) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_request_super_buf (my_obj, aux_chid, buf); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGH("X ch_id = %d rc = %d", ch_id, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_cancel_super_buf_request |
| * |
| * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount |
| * of matched frames from superbuf queue |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| int32_t rc = -1; |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| if (aux_chid && chid) { |
| my_obj = mm_camera_util_get_camera_head(camera_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_cancel_super_buf_request( |
| camera_handle, ch_id, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (aux_chid) { |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(aux_handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_cancel_super_buf_request(my_obj, chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (chid) { |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_cancel_super_buf_request(my_obj, chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGH("X ch_id = %d rc = %d", ch_id, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_flush_super_buf_queue |
| * |
| * DESCRIPTION: flush out all frames in the superbuf queue |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @frame_idx : frame index |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t frame_idx) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| if (chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_flush_super_buf_queue(my_obj, chid, frame_idx); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_flush_super_buf_queue(aux_handle, |
| aux_chid, frame_idx, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGH("X ch_id = %d rc = %d", ch_id, rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_start_zsl_snapshot |
| * |
| * DESCRIPTION: Starts zsl snapshot |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t *my_obj = NULL; |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t aux_ch_id = get_aux_camera_handle(ch_id); |
| |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| |
| if (aux_ch_id) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_start_zsl_snapshot(aux_handle, |
| aux_ch_id, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (m_chid) { |
| uint32_t m_handle = get_main_camera_handle(camera_handle); |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(m_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_start_zsl_snapshot_ch(my_obj, m_chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_stop_zsl_snapshot |
| * |
| * DESCRIPTION: Stops zsl snapshot |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle, |
| uint32_t ch_id) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t aux_ch_id = get_aux_camera_handle(ch_id); |
| |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| |
| if (aux_ch_id) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_stop_zsl_snapshot(aux_handle, aux_ch_id, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (ch_id) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_stop_zsl_snapshot_ch(my_obj, m_chid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_configure_notify_mode |
| * |
| * DESCRIPTION: Configures channel notification mode |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @notify_mode : notification mode |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle, |
| uint32_t ch_id, |
| mm_camera_super_buf_notify_mode_t notify_mode) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_ch_id = get_aux_camera_handle(ch_id); |
| |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| |
| if (aux_ch_id) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_configure_notify_mode(aux_handle, aux_ch_id, |
| notify_mode, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_config_channel_notify(my_obj, chid, |
| notify_mode); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_map_buf |
| * |
| * DESCRIPTION: mapping camera buffer via domain socket to server |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @buf_type : type of buffer to be mapped. could be following values: |
| * CAM_MAPPING_BUF_TYPE_CAPABILITY |
| * CAM_MAPPING_BUF_TYPE_SETPARM_BUF |
| * CAM_MAPPING_BUF_TYPE_GETPARM_BUF |
| * @fd : file descriptor of the buffer |
| * @size : size of the buffer |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_map_buf(uint32_t camera_handle, |
| uint8_t buf_type, int fd, size_t size, void *buffer) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t *my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_map_buf(aux_handle, buf_type, |
| fd, size, buffer, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_map_bufs |
| * |
| * DESCRIPTION: mapping camera buffer via domain socket to server |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @buf_type : type of buffer to be mapped. could be following values: |
| * CAM_MAPPING_BUF_TYPE_CAPABILITY |
| * CAM_MAPPING_BUF_TYPE_SETPARM_BUF |
| * CAM_MAPPING_BUF_TYPE_GETPARM_BUF |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_map_bufs(uint32_t camera_handle, |
| const cam_buf_map_type_list *buf_map_list) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_map_bufs(my_obj, buf_map_list); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_map_bufs(aux_handle, buf_map_list, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_unmap_buf |
| * |
| * DESCRIPTION: unmapping camera buffer via domain socket to server |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @buf_type : type of buffer to be unmapped. could be following values: |
| * CAM_MAPPING_BUF_TYPE_CAPABILITY |
| * CAM_MAPPING_BUF_TYPE_SETPARM_BUF |
| * CAM_MAPPING_BUF_TYPE_GETPARM_BUF |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle, |
| uint8_t buf_type) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_unmap_buf(my_obj, buf_type); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_unmap_buf(aux_handle, buf_type, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_set_stream_parms |
| * |
| * DESCRIPTION: set parameters per stream |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @s_id : stream handle |
| * @parms : ptr to a param struct to be set to server |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : Assume the parms struct buf is already mapped to server via |
| * domain socket. Corresponding fields of parameters to be set |
| * are already filled in by upper layer caller. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle, |
| uint32_t ch_id, |
| uint32_t s_id, |
| cam_stream_parm_buffer_t *parms) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(s_id); |
| uint32_t aux_strid = get_aux_camera_handle(s_id); |
| |
| LOGD("E camera_handle = %d,ch_id = %d,s_id = %d", |
| camera_handle, ch_id, s_id); |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_set_stream_parms(my_obj, chid, strid, parms); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_set_stream_parms(aux_handle, aux_chid, |
| aux_strid, parms, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_get_stream_parms |
| * |
| * DESCRIPTION: get parameters per stream |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @s_id : stream handle |
| * @parms : ptr to a param struct to be get from server |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : Assume the parms struct buf is already mapped to server via |
| * domain socket. Parameters to be get from server are already |
| * filled in by upper layer caller. After this call, corresponding |
| * fields of requested parameters will be filled in by server with |
| * detailed information. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle, |
| uint32_t ch_id, |
| uint32_t s_id, |
| cam_stream_parm_buffer_t *parms) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(s_id); |
| uint32_t aux_strid = get_aux_camera_handle(s_id); |
| |
| LOGD("E camera_handle = %d,ch_id = %d,s_id = %d", |
| camera_handle, ch_id, s_id); |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_get_stream_parms(my_obj, chid, strid, parms); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_get_stream_parms(aux_handle, aux_chid, |
| aux_strid, parms, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_map_stream_buf |
| * |
| * DESCRIPTION: mapping stream buffer via domain socket to server |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @s_id : stream handle |
| * @buf_type : type of buffer to be mapped. could be following values: |
| * CAM_MAPPING_BUF_TYPE_STREAM_BUF |
| * CAM_MAPPING_BUF_TYPE_STREAM_INFO |
| * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF |
| * @buf_idx : index of buffer within the stream buffers, only valid if |
| * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or |
| * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF |
| * @plane_idx : plane index. If all planes share the same fd, |
| * plane_idx = -1; otherwise, plean_idx is the |
| * index to plane (0..num_of_planes) |
| * @fd : file descriptor of the buffer |
| * @size : size of the buffer |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id, uint8_t buf_type, |
| uint32_t buf_idx, int32_t plane_idx, int fd, |
| size_t size, void *buffer) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(stream_id); |
| |
| LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", |
| camera_handle, ch_id, stream_id, buf_idx, plane_idx); |
| |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_map_stream_buf(my_obj, chid, strid, |
| buf_type, buf_idx, plane_idx, |
| fd, size, buffer); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_map_stream_buf(aux_handle, aux_chid, |
| aux_strid, buf_type, buf_idx, plane_idx, fd, size, |
| buffer, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_map_stream_bufs |
| * |
| * DESCRIPTION: mapping stream buffers via domain socket to server |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @buf_map_list : list of buffers to be mapped |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_map_stream_bufs(uint32_t camera_handle, |
| uint32_t ch_id, |
| const cam_buf_map_type_list *buf_map_list) |
| { |
| int32_t rc = -1; |
| uint32_t i; |
| mm_camera_obj_t * my_obj = NULL; |
| cam_buf_map_type_list m_buf_list, aux_buf_list; |
| |
| LOGD("E camera_handle = %d, ch_id = %d", |
| camera_handle, ch_id); |
| |
| memset(&m_buf_list, 0, sizeof(m_buf_list)); |
| memset(&aux_buf_list, 0, sizeof(m_buf_list)); |
| for (i = 0; i < buf_map_list->length; i++) { |
| uint32_t strid = get_main_camera_handle(buf_map_list->buf_maps[i].stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(buf_map_list->buf_maps[i].stream_id); |
| if (strid) { |
| m_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i]; |
| m_buf_list.buf_maps[aux_buf_list.length].stream_id = strid; |
| m_buf_list.length++; |
| } |
| if (aux_strid) { |
| aux_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i]; |
| aux_buf_list.buf_maps[aux_buf_list.length].stream_id = aux_strid; |
| aux_buf_list.length++; |
| } |
| } |
| |
| if(m_buf_list.length != 0) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_map_stream_bufs(my_obj, chid, &m_buf_list); |
| }else{ |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if(aux_buf_list.length != 0) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj != NULL) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_map_stream_bufs(aux_handle,aux_chid, |
| &aux_buf_list, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_unmap_stream_buf |
| * |
| * DESCRIPTION: unmapping stream buffer via domain socket to server |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @s_id : stream handle |
| * @buf_type : type of buffer to be unmapped. could be following values: |
| * CAM_MAPPING_BUF_TYPE_STREAM_BUF |
| * CAM_MAPPING_BUF_TYPE_STREAM_INFO |
| * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF |
| * @buf_idx : index of buffer within the stream buffers, only valid if |
| * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or |
| * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF |
| * @plane_idx : plane index. If all planes share the same fd, |
| * plane_idx = -1; otherwise, plean_idx is the |
| * index to plane (0..num_of_planes) |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle, |
| uint32_t ch_id, |
| uint32_t stream_id, |
| uint8_t buf_type, |
| uint32_t buf_idx, |
| int32_t plane_idx) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(stream_id); |
| |
| |
| LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", |
| camera_handle, ch_id, stream_id, buf_idx, plane_idx); |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_unmap_stream_buf(aux_handle, aux_chid, |
| aux_strid, buf_type, buf_idx, |
| plane_idx, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_unmap_stream_buf(my_obj, chid, strid, |
| buf_type, buf_idx, plane_idx); |
| }else{ |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| LOGD("X rc = %d", rc); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_get_session_id |
| * |
| * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @sessionid: session id to be retrieved from server |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : if this call succeeds, we will get a valid session id. |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_get_session_id(uint32_t camera_handle, |
| uint32_t* sessionid) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| |
| if (handle) { |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| *sessionid = my_obj->sessionid; |
| pthread_mutex_unlock(&my_obj->cam_lock); |
| rc = 0; |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } else if (aux_handle){ |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_get_session_id(aux_handle, sessionid, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_sync_related_sensors |
| * |
| * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @related_cam_info: pointer to the related cam info to be sent to the server |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| * NOTE : if this call succeeds, we will get linking established in back end |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_sync_related_sensors(uint32_t camera_handle, |
| cam_sync_related_sensors_event_info_t* related_cam_info) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(camera_handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_sync_related_sensors(my_obj, related_cam_info); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : get_sensor_info |
| * |
| * DESCRIPTION: get sensor info like facing(back/front) and mount angle |
| * |
| * PARAMETERS : |
| * |
| * RETURN : |
| *==========================================================================*/ |
| void get_sensor_info() |
| { |
| int rc = 0; |
| int dev_fd = -1; |
| struct media_device_info mdev_info; |
| int num_media_devices = 0; |
| size_t num_cameras = 0; |
| |
| LOGD("E"); |
| while (1) { |
| char dev_name[32]; |
| snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); |
| dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); |
| if (dev_fd < 0) { |
| LOGD("Done discovering media devices\n"); |
| break; |
| } |
| num_media_devices++; |
| memset(&mdev_info, 0, sizeof(mdev_info)); |
| rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); |
| if (rc < 0) { |
| LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno)); |
| close(dev_fd); |
| dev_fd = -1; |
| num_cameras = 0; |
| break; |
| } |
| |
| if(strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) { |
| close(dev_fd); |
| dev_fd = -1; |
| continue; |
| } |
| |
| unsigned int num_entities = 1; |
| while (1) { |
| struct media_entity_desc entity; |
| uint32_t temp; |
| uint32_t mount_angle; |
| uint32_t facing; |
| int32_t type = 0; |
| uint8_t is_yuv; |
| |
| memset(&entity, 0, sizeof(entity)); |
| entity.id = num_entities++; |
| rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); |
| if (rc < 0) { |
| LOGD("Done enumerating media entities\n"); |
| rc = 0; |
| break; |
| } |
| if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV && |
| entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) { |
| temp = entity.flags >> 8; |
| mount_angle = (temp & 0xFF) * 90; |
| facing = ((entity.flags & CAM_SENSOR_FACING_MASK) ? |
| CAMERA_FACING_FRONT:CAMERA_FACING_BACK); |
| |
| /* TODO: Need to revisit this logic if front AUX is available. */ |
| if ((unsigned int)facing == CAMERA_FACING_FRONT) { |
| type = CAM_TYPE_STANDALONE; |
| } else if (entity.flags & CAM_SENSOR_TYPE_MASK) { |
| type = CAM_TYPE_AUX; |
| } else { |
| type = CAM_TYPE_MAIN; |
| } |
| |
| is_yuv = ((entity.flags & CAM_SENSOR_FORMAT_MASK) ? |
| CAM_SENSOR_YUV:CAM_SENSOR_RAW); |
| LOGL("index = %u flag = %x mount_angle = %u " |
| "facing = %u type: %u is_yuv = %u\n", |
| (unsigned int)num_cameras, (unsigned int)temp, |
| (unsigned int)mount_angle, (unsigned int)facing, |
| (unsigned int)type, (uint8_t)is_yuv); |
| g_cam_ctrl.info[num_cameras].facing = (int)facing; |
| g_cam_ctrl.info[num_cameras].orientation = (int)mount_angle; |
| g_cam_ctrl.cam_type[num_cameras] = type; |
| g_cam_ctrl.is_yuv[num_cameras] = is_yuv; |
| LOGD("dev_info[id=%zu,name='%s']\n", |
| num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); |
| num_cameras++; |
| continue; |
| } |
| } |
| close(dev_fd); |
| dev_fd = -1; |
| } |
| |
| LOGD("num_cameras=%d\n", g_cam_ctrl.num_cam); |
| return; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : sort_camera_info |
| * |
| * DESCRIPTION: sort camera info to keep back cameras idx is smaller than front cameras idx |
| * |
| * PARAMETERS : number of cameras |
| * |
| * RETURN : |
| *==========================================================================*/ |
| void sort_camera_info(int num_cam) |
| { |
| int idx = 0, i; |
| int8_t is_yuv_aux_cam_exposed = 0; |
| char prop[PROPERTY_VALUE_MAX]; |
| struct camera_info temp_info[MM_CAMERA_MAX_NUM_SENSORS]; |
| cam_sync_type_t temp_type[MM_CAMERA_MAX_NUM_SENSORS]; |
| cam_sync_mode_t temp_mode[MM_CAMERA_MAX_NUM_SENSORS]; |
| uint8_t temp_is_yuv[MM_CAMERA_MAX_NUM_SENSORS]; |
| char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN]; |
| uint32_t cam_idx[MM_CAMERA_MAX_NUM_SENSORS] = {0}; |
| uint8_t prime_cam_idx = 0, aux_cam_idx = 0; |
| |
| memset(temp_info, 0, sizeof(temp_info)); |
| memset(temp_dev_name, 0, sizeof(temp_dev_name)); |
| memset(temp_type, 0, sizeof(temp_type)); |
| memset(temp_mode, 0, sizeof(temp_mode)); |
| memset(temp_is_yuv, 0, sizeof(temp_is_yuv)); |
| |
| // Signifies whether YUV AUX camera has to be exposed as physical camera |
| memset(prop, 0, sizeof(prop)); |
| property_get("persist.camera.aux.yuv", prop, "0"); |
| is_yuv_aux_cam_exposed = atoi(prop); |
| LOGI("YUV Aux camera exposed %d",is_yuv_aux_cam_exposed); |
| |
| /* Order of the camera exposed is |
| Back main, Front main, Back Aux and then Front Aux. |
| It is because that lot of 3rd party cameras apps |
| blindly assume 0th is Back and 1st is front */ |
| |
| /* Firstly save the main back cameras info */ |
| for (i = 0; i < num_cam; i++) { |
| if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) && |
| !(g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) |
| && ((g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) |
| || (g_cam_ctrl.cam_type[i] == CAM_TYPE_STANDALONE))) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_MAIN; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| cam_idx[idx] = idx; |
| prime_cam_idx = idx; |
| LOGD("Found Back Main Camera: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| /* Save the main front cameras info */ |
| for (i = 0; i < num_cam; i++) { |
| if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) && |
| !(g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) |
| && ((g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) |
| || (g_cam_ctrl.cam_type[i] == CAM_TYPE_STANDALONE))) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_MAIN; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| cam_idx[idx] = idx; |
| LOGD("Found Front Main Camera: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| /*Expose Bayer Aux as a valid sensor*/ |
| for (i = 0; i < num_cam; i++) { |
| if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_MAIN; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| cam_idx[idx] = idx; |
| LOGD("Found Bayer + Aux: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| for (i = 0; i < num_cam; i++) { |
| if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_MAIN; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| cam_idx[idx] = idx; |
| aux_cam_idx = idx; |
| LOGD("Found Bayer + Aux: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| /* Expose YUV AUX camera if persist.camera.aux.yuv is set to 1. |
| Otherwsie expose AUX camera if it is not YUV. */ |
| for (i = 0; i < num_cam; i++) { |
| if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && |
| !(g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) && |
| (is_yuv_aux_cam_exposed || !(g_cam_ctrl.is_yuv[i]))) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_AUX; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| cam_idx[idx] = idx; |
| LOGD("Found back Aux Camera: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| /* Expose YUV AUX camera if persist.camera.aux.yuv is set to 1. |
| Otherwsie expose AUX camera if it is not YUV. */ |
| for (i = 0; i < num_cam; i++) { |
| if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && |
| !(g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) && |
| (is_yuv_aux_cam_exposed || !(g_cam_ctrl.is_yuv[i]))) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_AUX; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| cam_idx[idx] = idx; |
| LOGD("Found Front Aux Camera: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| /*Expose AUX + MAIN camera*/ |
| for (i = 0; i < num_cam; i++) { |
| if (((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) || |
| (g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT)) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) && |
| (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) { |
| temp_info[idx] = g_cam_ctrl.info[i]; |
| temp_type[idx] = CAM_TYPE_AUX | CAM_TYPE_MAIN; |
| temp_mode[idx] = g_cam_ctrl.cam_mode[i]; |
| temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i]; |
| //Assuming primary is back |
| cam_idx[idx] = (aux_cam_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | prime_cam_idx; |
| LOGD("Add additional Bayer + Aux: i: %d idx: %d", i, idx); |
| memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i], |
| MM_CAMERA_DEV_NAME_LEN); |
| } |
| } |
| |
| if (idx != 0) { |
| memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info)); |
| memcpy(g_cam_ctrl.cam_type, temp_type, sizeof(temp_type)); |
| memcpy(g_cam_ctrl.cam_mode, temp_mode, sizeof(temp_mode)); |
| memcpy(g_cam_ctrl.is_yuv, temp_is_yuv, sizeof(temp_is_yuv)); |
| memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name)); |
| memcpy(g_cam_ctrl.cam_index, cam_idx, (sizeof(uint32_t) * MM_CAMERA_MAX_NUM_SENSORS)); |
| //Set num cam based on the cameras exposed finally via dual/aux properties. |
| g_cam_ctrl.num_cam = idx; |
| for (i = 0; i < idx; i++) { |
| LOGI("Camera id: %d facing: %d, type: %d is_yuv: %d", |
| i, g_cam_ctrl.info[i].facing, g_cam_ctrl.cam_type[i], g_cam_ctrl.is_yuv[i]); |
| } |
| } |
| LOGI("Number of cameras %d sorted %d", num_cam, idx); |
| return; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : get_num_of_cameras |
| * |
| * DESCRIPTION: get number of cameras |
| * |
| * PARAMETERS : |
| * |
| * RETURN : number of cameras supported |
| *==========================================================================*/ |
| uint8_t get_num_of_cameras() |
| { |
| int rc = 0; |
| int dev_fd = -1; |
| struct media_device_info mdev_info; |
| int num_media_devices = 0; |
| int8_t num_cameras = 0; |
| char subdev_name[32]; |
| int32_t sd_fd = -1; |
| struct sensor_init_cfg_data cfg; |
| char prop[PROPERTY_VALUE_MAX]; |
| |
| LOGD("E"); |
| |
| property_get("vold.decrypt", prop, "0"); |
| int decrypt = atoi(prop); |
| if (decrypt == 1) |
| return 0; |
| pthread_mutex_lock(&g_intf_lock); |
| |
| memset (&g_cam_ctrl, 0, sizeof (g_cam_ctrl)); |
| #ifndef DAEMON_PRESENT |
| if (mm_camera_load_shim_lib() < 0) { |
| LOGE ("Failed to module shim library"); |
| return 0; |
| } |
| #endif /* DAEMON_PRESENT */ |
| |
| while (1) { |
| uint32_t num_entities = 1U; |
| char dev_name[32]; |
| |
| snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); |
| dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); |
| if (dev_fd < 0) { |
| LOGD("Done discovering media devices\n"); |
| break; |
| } |
| num_media_devices++; |
| rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); |
| if (rc < 0) { |
| LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno)); |
| close(dev_fd); |
| dev_fd = -1; |
| break; |
| } |
| |
| if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, |
| sizeof(mdev_info.model)) != 0) { |
| close(dev_fd); |
| dev_fd = -1; |
| continue; |
| } |
| |
| while (1) { |
| struct media_entity_desc entity; |
| memset(&entity, 0, sizeof(entity)); |
| entity.id = num_entities++; |
| LOGD("entity id %d", entity.id); |
| rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); |
| if (rc < 0) { |
| LOGD("Done enumerating media entities"); |
| rc = 0; |
| break; |
| } |
| LOGD("entity name %s type %d group id %d", |
| entity.name, entity.type, entity.group_id); |
| if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV && |
| entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) { |
| snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name); |
| break; |
| } |
| } |
| close(dev_fd); |
| dev_fd = -1; |
| } |
| |
| /* Open sensor_init subdev */ |
| sd_fd = open(subdev_name, O_RDWR); |
| if (sd_fd < 0) { |
| LOGE("Open sensor_init subdev failed"); |
| return FALSE; |
| } |
| |
| cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE; |
| cfg.cfg.setting = NULL; |
| if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) { |
| LOGE("failed"); |
| } |
| close(sd_fd); |
| dev_fd = -1; |
| |
| num_media_devices = 0; |
| while (1) { |
| uint32_t num_entities = 1U; |
| char dev_name[32]; |
| |
| snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); |
| dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); |
| if (dev_fd < 0) { |
| LOGD("Done discovering media devices: %s\n", strerror(errno)); |
| break; |
| } |
| num_media_devices++; |
| memset(&mdev_info, 0, sizeof(mdev_info)); |
| rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); |
| if (rc < 0) { |
| LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno)); |
| close(dev_fd); |
| dev_fd = -1; |
| num_cameras = 0; |
| break; |
| } |
| |
| if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) { |
| close(dev_fd); |
| dev_fd = -1; |
| continue; |
| } |
| |
| while (1) { |
| struct media_entity_desc entity; |
| memset(&entity, 0, sizeof(entity)); |
| entity.id = num_entities++; |
| rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); |
| if (rc < 0) { |
| LOGD("Done enumerating media entities\n"); |
| rc = 0; |
| break; |
| } |
| if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { |
| strlcpy(g_cam_ctrl.video_dev_name[num_cameras], |
| entity.name, sizeof(entity.name)); |
| LOGI("dev_info[id=%d,name='%s']\n", |
| (int)num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); |
| num_cameras++; |
| break; |
| } |
| } |
| close(dev_fd); |
| dev_fd = -1; |
| if (num_cameras >= MM_CAMERA_MAX_NUM_SENSORS) { |
| LOGW("Maximum number of camera reached %d", num_cameras); |
| break; |
| } |
| } |
| g_cam_ctrl.num_cam = num_cameras; |
| |
| get_sensor_info(); |
| sort_camera_info(g_cam_ctrl.num_cam); |
| /* unlock the mutex */ |
| pthread_mutex_unlock(&g_intf_lock); |
| LOGI("num_cameras=%d\n", (int)g_cam_ctrl.num_cam); |
| return(uint8_t)g_cam_ctrl.num_cam; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_process_advanced_capture |
| * |
| * DESCRIPTION: Configures channel advanced capture mode |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @type : advanced capture type |
| * @ch_id : channel handle |
| * @trigger : 1 for start and 0 for cancel/stop |
| * @value : input capture configaration |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * -1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle, |
| uint32_t ch_id, mm_camera_advanced_capture_t type, |
| int8_t trigger, void *in_value) |
| { |
| int32_t rc = -1; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t chid = get_main_camera_handle(ch_id); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| |
| LOGD("E camera_handler = %d,ch_id = %d", |
| camera_handle, ch_id); |
| |
| if (chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_channel_advanced_capture(my_obj, chid, type, |
| (uint32_t)trigger, in_value); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_chid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_process_advanced_capture(aux_handle, |
| aux_chid, type, (uint32_t)trigger, in_value, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| LOGH("X rc = %d ch_id = %d", rc, ch_id); |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_register_stream_buf_cb |
| * |
| * DESCRIPTION: Register special callback for stream buffer |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * @buf_cb : callback function |
| * @buf_type :SYNC/ASYNC |
| * @userdata : userdata pointer |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * 1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_register_stream_buf_cb(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb, |
| mm_camera_stream_cb_type cb_type, void *userdata) |
| { |
| int32_t rc = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| uint32_t strid = get_main_camera_handle(stream_id); |
| uint32_t aux_strid = get_aux_camera_handle(stream_id); |
| |
| LOGD("E handle = %u ch_id = %u", |
| camera_handle, ch_id); |
| |
| if (strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t chid = get_main_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_reg_stream_buf_cb(my_obj, chid, strid, |
| buf_cb, cb_type, userdata); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| |
| if (aux_strid) { |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t aux_handle = get_aux_camera_handle(camera_handle); |
| uint32_t aux_chid = get_aux_camera_handle(ch_id); |
| my_obj = mm_camera_util_get_camera_head(aux_handle); |
| |
| if (my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_register_stream_buf_cb(aux_handle, |
| aux_chid, aux_strid, |
| buf_cb, cb_type, userdata, my_obj); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| } |
| return (int32_t)rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_register_frame_sync |
| * |
| * DESCRIPTION: start frame buffer sync for the stream |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * @sync_attr : frame sync attr |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * 1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_reg_frame_sync(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id, |
| mm_camera_intf_frame_sync_t *sync_attr) |
| { |
| int32_t rc = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| |
| LOGD("E handle = %u ch_id = %u stream_id = %u", camera_handle, ch_id, stream_id); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_reg_frame_sync(my_obj, |
| ch_id, stream_id, sync_attr); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| return (int32_t)rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_start_stream_frame_sync |
| * |
| * DESCRIPTION: start frame buffer sync for the stream |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * 1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_start_stream_frame_sync(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id) |
| { |
| int32_t rc = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| |
| LOGD("E handle = %u ch_id = %u stream_id = %u", |
| camera_handle, ch_id, stream_id); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t m_stream = get_main_camera_handle(stream_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_start_frame_sync(my_obj, |
| m_chid, m_stream); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| LOGH("stream_id = %d rc = %d", stream_id, rc); |
| return (int32_t)rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_stop_stream_frame_sync |
| * |
| * DESCRIPTION: stop frame buffer sync for the stream |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * 1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_stop_stream_frame_sync(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id) |
| { |
| int32_t rc = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| |
| LOGD("E handle = %u ch_id = %u stream_id = %u", |
| camera_handle, ch_id, stream_id); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t m_stream = get_main_camera_handle(stream_id); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_stop_frame_sync(my_obj, |
| m_chid, m_stream); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| LOGH("stream_id = %d rc = %d", stream_id, rc); |
| return (int32_t)rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_intf_switch_stream |
| * |
| * DESCRIPTION: switch between stream in case of multi streams |
| * |
| * PARAMETERS : |
| * @camera_handle: camera handle |
| * @ch_id : channel handle |
| * @stream_id : stream handle |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * 1 -- failure |
| *==========================================================================*/ |
| static int32_t mm_camera_intf_switch_stream_cb(uint32_t camera_handle, |
| uint32_t ch_id, uint32_t stream_id) |
| { |
| int32_t rc = 0; |
| mm_camera_obj_t * my_obj = NULL; |
| |
| uint32_t handle = get_main_camera_handle(camera_handle); |
| uint32_t m_chid = get_main_camera_handle(ch_id); |
| uint32_t m_strid = get_main_camera_handle(stream_id); |
| LOGD("E handle = %u ch_id = %u stream_id = %u", |
| camera_handle, ch_id, stream_id); |
| |
| pthread_mutex_lock(&g_intf_lock); |
| my_obj = mm_camera_util_get_camera_by_handler(handle); |
| if(my_obj) { |
| pthread_mutex_lock(&my_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_switch_stream_cb(my_obj, m_chid, m_strid); |
| } else { |
| pthread_mutex_unlock(&g_intf_lock); |
| } |
| LOGH("stream_id = %d rc = %d", stream_id, rc); |
| return (int32_t)rc; |
| } |
| |
| struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType) |
| { |
| *pCamType = g_cam_ctrl.cam_type[camera_id]; |
| return &g_cam_ctrl.info[camera_id]; |
| } |
| |
| uint8_t is_dual_camera_by_idx(uint32_t camera_id) |
| { |
| return ((g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_MAIN) |
| && (g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_AUX)); |
| } |
| |
| uint8_t is_dual_camera_by_handle(uint32_t handle) |
| { |
| return ((handle >> MM_CAMERA_HANDLE_SHIFT_MASK) |
| ? 1 : 0); |
| } |
| |
| uint32_t get_aux_camera_handle(uint32_t handle) |
| { |
| return mm_camera_util_get_handle_by_num(1, handle); |
| } |
| |
| uint32_t get_main_camera_handle(uint32_t handle) |
| { |
| return mm_camera_util_get_handle_by_num(0, handle); |
| } |
| |
| uint8_t is_yuv_sensor(uint32_t camera_id) |
| { |
| return g_cam_ctrl.is_yuv[camera_id]; |
| } |
| |
| uint8_t validate_handle(uint32_t src_handle, uint32_t handle) |
| { |
| return ((src_handle == handle) |
| || (get_main_camera_handle(src_handle) == handle) |
| || (get_aux_camera_handle(src_handle) == handle) |
| || (get_main_camera_handle(handle) == src_handle) |
| || (get_aux_camera_handle(handle) == src_handle)); |
| } |
| |
| /* camera ops v-table */ |
| static mm_camera_ops_t mm_camera_ops = { |
| .query_capability = mm_camera_intf_query_capability, |
| .register_event_notify = mm_camera_intf_register_event_notify, |
| .close_camera = mm_camera_intf_close, |
| .set_parms = mm_camera_intf_set_parms, |
| .get_parms = mm_camera_intf_get_parms, |
| .do_auto_focus = mm_camera_intf_do_auto_focus, |
| .cancel_auto_focus = mm_camera_intf_cancel_auto_focus, |
| .prepare_snapshot = mm_camera_intf_prepare_snapshot, |
| .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot, |
| .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot, |
| .map_buf = mm_camera_intf_map_buf, |
| .map_bufs = mm_camera_intf_map_bufs, |
| .unmap_buf = mm_camera_intf_unmap_buf, |
| .add_channel = mm_camera_intf_add_channel, |
| .delete_channel = mm_camera_intf_del_channel, |
| .get_bundle_info = mm_camera_intf_get_bundle_info, |
| .add_stream = mm_camera_intf_add_stream, |
| .link_stream = mm_camera_intf_link_stream, |
| .delete_stream = mm_camera_intf_del_stream, |
| .config_stream = mm_camera_intf_config_stream, |
| .qbuf = mm_camera_intf_qbuf, |
| .get_queued_buf_count = mm_camera_intf_get_queued_buf_count, |
| .map_stream_buf = mm_camera_intf_map_stream_buf, |
| .map_stream_bufs = mm_camera_intf_map_stream_bufs, |
| .unmap_stream_buf = mm_camera_intf_unmap_stream_buf, |
| .set_stream_parms = mm_camera_intf_set_stream_parms, |
| .get_stream_parms = mm_camera_intf_get_stream_parms, |
| .start_channel = mm_camera_intf_start_channel, |
| .stop_channel = mm_camera_intf_stop_channel, |
| .request_super_buf = mm_camera_intf_request_super_buf, |
| .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, |
| .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue, |
| .configure_notify_mode = mm_camera_intf_configure_notify_mode, |
| .process_advanced_capture = mm_camera_intf_process_advanced_capture, |
| .get_session_id = mm_camera_intf_get_session_id, |
| .sync_related_sensors = mm_camera_intf_sync_related_sensors, |
| .flush = mm_camera_intf_flush, |
| .register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb, |
| .register_frame_sync = mm_camera_intf_reg_frame_sync, |
| .start_stream_frame_sync = mm_camera_intf_start_stream_frame_sync, |
| .stop_stream_frame_sync = mm_camera_intf_stop_stream_frame_sync, |
| .switch_stream_callback = mm_camera_intf_switch_stream_cb |
| }; |
| |
| /*=========================================================================== |
| * FUNCTION : camera_open |
| * |
| * DESCRIPTION: open a camera by camera index |
| * |
| * PARAMETERS : |
| * @camera_idx : camera index. should within range of 0 to num_of_cameras |
| * @camera_vtbl : ptr to a virtual table containing camera handle and operation table. |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * non-zero error code -- failure |
| *==========================================================================*/ |
| int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl) |
| { |
| int32_t rc = 0; |
| mm_camera_obj_t *cam_obj = NULL; |
| uint32_t cam_idx = camera_idx; |
| uint32_t aux_idx = 0; |
| uint8_t is_multi_camera = 0; |
| |
| #ifdef QCAMERA_REDEFINE_LOG |
| mm_camera_debug_open(); |
| #endif |
| |
| LOGD("E camera_idx = %d\n", camera_idx); |
| if (is_dual_camera_by_idx(camera_idx)) { |
| is_multi_camera = 1; |
| cam_idx = mm_camera_util_get_handle_by_num(0, |
| g_cam_ctrl.cam_index[camera_idx]); |
| aux_idx = (get_aux_camera_handle(g_cam_ctrl.cam_index[camera_idx]) |
| >> MM_CAMERA_HANDLE_SHIFT_MASK); |
| LOGH("Dual Camera: Main ID = %d Aux ID = %d", cam_idx, aux_idx); |
| } |
| |
| if (cam_idx >= (uint32_t)g_cam_ctrl.num_cam) { |
| LOGE("Invalid camera_idx (%d)", cam_idx); |
| return -EINVAL; |
| } |
| |
| pthread_mutex_lock(&g_intf_lock); |
| /* opened already */ |
| if(NULL != g_cam_ctrl.cam_obj[cam_idx] && |
| g_cam_ctrl.cam_obj[cam_idx]->ref_count != 0) { |
| pthread_mutex_unlock(&g_intf_lock); |
| LOGE("Camera %d is already open", cam_idx); |
| return -EBUSY; |
| } |
| |
| cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); |
| if(NULL == cam_obj) { |
| pthread_mutex_unlock(&g_intf_lock); |
| LOGE("no mem"); |
| return -EINVAL; |
| } |
| |
| /* initialize camera obj */ |
| memset(cam_obj, 0, sizeof(mm_camera_obj_t)); |
| cam_obj->ctrl_fd = -1; |
| cam_obj->ds_fd = -1; |
| cam_obj->ref_count++; |
| cam_obj->my_num = 0; |
| cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx); |
| cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ |
| cam_obj->vtbl.ops = &mm_camera_ops; |
| pthread_mutex_init(&cam_obj->cam_lock, NULL); |
| pthread_mutex_init(&cam_obj->muxer_lock, NULL); |
| /* unlock global interface lock, if not, in dual camera use case, |
| * current open will block operation of another opened camera obj*/ |
| pthread_mutex_lock(&cam_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| |
| rc = mm_camera_open(cam_obj); |
| if (rc != 0) { |
| LOGE("mm_camera_open err = %d", rc); |
| pthread_mutex_destroy(&cam_obj->cam_lock); |
| pthread_mutex_lock(&g_intf_lock); |
| g_cam_ctrl.cam_obj[cam_idx] = NULL; |
| free(cam_obj); |
| cam_obj = NULL; |
| pthread_mutex_unlock(&g_intf_lock); |
| *camera_vtbl = NULL; |
| return rc; |
| } |
| |
| if (is_multi_camera) { |
| /*Open Aux camer's*/ |
| pthread_mutex_lock(&g_intf_lock); |
| if(NULL != g_cam_ctrl.cam_obj[aux_idx] && |
| g_cam_ctrl.cam_obj[aux_idx]->ref_count != 0) { |
| pthread_mutex_unlock(&g_intf_lock); |
| LOGE("Camera %d is already open", aux_idx); |
| rc = -EBUSY; |
| } else { |
| pthread_mutex_lock(&cam_obj->muxer_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_muxer_camera_open(aux_idx, cam_obj); |
| } |
| if (rc != 0) { |
| LOGE("muxer open err = %d", rc); |
| pthread_mutex_lock(&g_intf_lock); |
| g_cam_ctrl.cam_obj[cam_idx] = NULL; |
| pthread_mutex_lock(&cam_obj->cam_lock); |
| pthread_mutex_unlock(&g_intf_lock); |
| rc = mm_camera_close(cam_obj); |
| pthread_mutex_destroy(&cam_obj->cam_lock); |
| pthread_mutex_destroy(&cam_obj->muxer_lock); |
| free(cam_obj); |
| cam_obj = NULL; |
| *camera_vtbl = NULL; |
| return rc; |
| } |
| } |
| |
| LOGH("Open succeded: handle = %d", cam_obj->vtbl.camera_handle); |
| g_cam_ctrl.cam_obj[cam_idx] = cam_obj; |
| *camera_vtbl = &cam_obj->vtbl; |
| return 0; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_load_shim_lib |
| * |
| * DESCRIPTION: Load shim layer library |
| * |
| * PARAMETERS : |
| * |
| * RETURN : status of load shim library |
| *==========================================================================*/ |
| int32_t mm_camera_load_shim_lib() |
| { |
| const char* error = NULL; |
| void *qdaemon_lib = NULL; |
| |
| LOGD("E"); |
| qdaemon_lib = dlopen(SHIMLAYER_LIB, RTLD_NOW); |
| if (!qdaemon_lib) { |
| error = dlerror(); |
| LOGE("dlopen failed with error %s", error ? error : ""); |
| return -1; |
| } |
| |
| *(void **)&mm_camera_shim_module_init = |
| dlsym(qdaemon_lib, "mct_shimlayer_process_module_init"); |
| if (!mm_camera_shim_module_init) { |
| error = dlerror(); |
| LOGE("dlsym failed with error code %s", error ? error: ""); |
| dlclose(qdaemon_lib); |
| return -1; |
| } |
| |
| return mm_camera_shim_module_init(&g_cam_ctrl.cam_shim_ops); |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_module_open_session |
| * |
| * DESCRIPTION: wrapper function to call shim layer API to open session. |
| * |
| * PARAMETERS : |
| * @sessionid : sessionID to open session |
| * @evt_cb : Event callback function |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * non-zero error code -- failure |
| *==========================================================================*/ |
| cam_status_t mm_camera_module_open_session(int sessionid, |
| mm_camera_shim_event_handler_func evt_cb) |
| { |
| cam_status_t rc = -1; |
| if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session) { |
| rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session( |
| sessionid, evt_cb); |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_module_close_session |
| * |
| * DESCRIPTION: wrapper function to call shim layer API to close session |
| * |
| * PARAMETERS : |
| * @sessionid : sessionID to open session |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * non-zero error code -- failure |
| *==========================================================================*/ |
| int32_t mm_camera_module_close_session(int session) |
| { |
| int32_t rc = -1; |
| if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session) { |
| rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session(session); |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_module_open_session |
| * |
| * DESCRIPTION: wrapper function to call shim layer API |
| * |
| * PARAMETERS : |
| * @sessionid : sessionID to open session |
| * @evt_cb : Event callback function |
| * |
| * RETURN : int32_t type of status |
| * 0 -- success |
| * non-zero error code -- failure |
| *==========================================================================*/ |
| int32_t mm_camera_module_send_cmd(cam_shim_packet_t *event) |
| { |
| int32_t rc = -1; |
| if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd) { |
| rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd(event); |
| } |
| return rc; |
| } |
| |
| /*=========================================================================== |
| * FUNCTION : mm_camera_module_event_handler |
| * |
| * DESCRIPTION: call back function for shim layer |
| * |
| * PARAMETERS : |
| * |
| * RETURN : status of call back function |
| *==========================================================================*/ |
| int mm_camera_module_event_handler(uint32_t session_id, cam_event_t *event) |
| { |
| if (!event) { |
| LOGE("null event"); |
| return FALSE; |
| } |
| mm_camera_event_t evt; |
| |
| LOGD("session_id:%d, cmd:0x%x", session_id, event->server_event_type); |
| memset(&evt, 0, sizeof(mm_camera_event_t)); |
| |
| evt = *event; |
| mm_camera_obj_t *my_obj = |
| mm_camera_util_get_camera_by_session_id(session_id); |
| if (!my_obj) { |
| LOGE("my_obj:%p", my_obj); |
| return FALSE; |
| } |
| switch( evt.server_event_type) { |
| case CAM_EVENT_TYPE_DAEMON_PULL_REQ: |
| case CAM_EVENT_TYPE_CAC_DONE: |
| case CAM_EVENT_TYPE_DAEMON_DIED: |
| case CAM_EVENT_TYPE_INT_TAKE_JPEG: |
| case CAM_EVENT_TYPE_INT_TAKE_RAW: |
| mm_camera_enqueue_evt(my_obj, &evt); |
| break; |
| default: |
| LOGE("cmd:%x from shim layer is not handled", evt.server_event_type); |
| break; |
| } |
| return TRUE; |
| } |
| |