From: Jeongmo Yang Date: Fri, 8 Feb 2019 05:17:14 +0000 (+0900) Subject: Replace tbm_key by tbm_fd for buffer protection X-Git-Tag: accepted/tizen/unified/20190221.084210^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8fa781a4f95a91d2b07c70bf8ce490f9190bfd18;p=platform%2Fcore%2Fapi%2Fcamera.git Replace tbm_key by tbm_fd for buffer protection - Any other process can access buffer if it knows its tbm_key, but, there is no way to access if it's replaced by tbm_fd. [Version] 0.4.21 [Profile] Common [Issue Type] Update [Dependency module] mmsvc-camera Change-Id: I18c4560901ec097374854c94c262f6bad7730742 Signed-off-by: Jeongmo Yang --- diff --git a/include/camera_private.h b/include/camera_private.h index 4f24b7c..e3603de 100644 --- a/include/camera_private.h +++ b/include/camera_private.h @@ -167,12 +167,14 @@ typedef struct _camera_message_s { muse_camera_api_e api; muse_camera_event_e event; muse_camera_event_class_e event_class; + int tfd[MUSE_NUM_FD]; } camera_message_s; typedef struct _camera_idle_event_s { camera_cb_info_s *cb_info; gchar recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH + 1]; muse_camera_event_e event; + int tfd[MUSE_NUM_FD]; } camera_idle_event_s; typedef struct _camera_cli_s { @@ -181,10 +183,13 @@ typedef struct _camera_cli_s { } camera_cli_s; typedef struct _camera_media_packet_data { - int tbm_key; + int ret_fd; + tbm_fd fd; + tbm_fd data_fd; + tbm_fd buffer_fd[MUSE_NUM_FD]; tbm_bo bo; tbm_bo buffer_bo[BUFFER_MAX_PLANE_NUM]; - int num_buffer_key; + int num_buffer_fd; tbm_bo data_bo; int ref_cnt; } camera_media_packet_data; diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 875c42e..46ca000 100644 --- a/packaging/capi-media-camera.spec +++ b/packaging/capi-media-camera.spec @@ -1,6 +1,6 @@ Name: capi-media-camera Summary: A Camera API -Version: 0.4.20 +Version: 0.4.21 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index 4237161..1971fe6 100644 --- a/src/camera.c +++ b/src/camera.c @@ -50,13 +50,14 @@ static void _camera_msg_send_param1(int api, camera_cb_info_s *cb_info, int *ret, camera_msg_param *param, int timeout); static void _camera_msg_send_param2_int(int api, camera_cb_info_s *cb_info, int *ret, camera_msg_param *param0, camera_msg_param *param1, int timeout); -static int _camera_import_tbm_key(tbm_bufmgr bufmgr, unsigned int tbm_key, tbm_bo *bo, tbm_bo_handle *bo_handle); +static void _camera_msg_return_buffer(int ret_fd, camera_cb_info_s *cb_info); +static bool _camera_import_tbm_fd(tbm_bufmgr bufmgr, int fd, tbm_bo *bo, tbm_bo_handle *bo_handle); static void _camera_release_imported_bo(tbm_bo *bo); -static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_buffer_key, +static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_buffer_fd, tbm_bo_handle *buffer_bo_handle, tbm_bo_handle *data_bo_handle, camera_preview_data_s *frame); static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_data_s *stream, camera_media_packet_data *mp_data, media_packet_h *packet); -static int _camera_media_packet_data_create(int tbm_key, int num_buffer_key, tbm_bo bo, +static int _camera_media_packet_data_create(int ret_fd, int *tfd, int num_buffer_fd, tbm_bo bo, tbm_bo *buffer_bo, tbm_bo data_bo, camera_media_packet_data **mp_data); static void _camera_media_packet_data_release(camera_media_packet_data *mp_data, camera_cb_info_s *cb_info); @@ -130,16 +131,14 @@ _DONE: } -static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv_msg) +static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv_msg, int *tfd) { int i = 0; int ret = 0; - int num_buffer_key = 0; - int buffer_key[BUFFER_MAX_PLANE_NUM] = {0, }; - int tbm_key = 0; - int data_key = 0; + int ret_fd = -1; + int preview_fd = -1; + int num_buffer_fd = 0; unsigned char *buf_pos = NULL; - camera_msg_param param; tbm_bo bo = NULL; tbm_bo buffer_bo[BUFFER_MAX_PLANE_NUM] = {NULL, }; @@ -148,47 +147,54 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv tbm_bo data_bo = NULL; tbm_bo_handle data_bo_handle = {.ptr = NULL}; + camera_msg_param param; camera_preview_data_s frame; camera_stream_data_s *stream = NULL; camera_media_packet_data *mp_data = NULL; media_packet_h pkt = NULL; media_packet_h pkt_evas = NULL; - if (!cb_info || !recv_msg) { - LOGE("invalid param %p %p", cb_info, recv_msg); + /* tfd[0]: MMCamcorderVideoStreamDataType + tfd[1]: data_bo or zero copy bo[0] + tfd[2]: zero copy bo[1] + tfd[3]: zero copy bo[2] */ + + if (!cb_info || !recv_msg || !tfd) { + LOGE("invalid param %p %p %p", cb_info, recv_msg, tfd); return; } - muse_camera_msg_get(tbm_key, recv_msg); - muse_camera_msg_get(num_buffer_key, recv_msg); - muse_camera_msg_get_array(buffer_key, recv_msg); - muse_camera_msg_get(data_key, recv_msg); + muse_camera_msg_get(preview_fd, recv_msg); + muse_camera_msg_get(num_buffer_fd, recv_msg); + + /*LOGD("preview_fd %d, num_buffer_fd %d", preview_fd, num_buffer_fd);*/ memset(&frame, 0x0, sizeof(camera_preview_data_s)); - if (tbm_key <= 0) { - LOGE("invalid key %d", tbm_key); + if (tfd[0] < 0) { + LOGE("invalid fd %d", tfd[0]); return; } - CAMERA_MSG_PARAM_SET(param, INT, tbm_key); + ret_fd = preview_fd; + CAMERA_MSG_PARAM_SET(param, INT, ret_fd); - if (num_buffer_key < 0 || num_buffer_key > BUFFER_MAX_PLANE_NUM) { - LOGE("invalid num buffer key %d", num_buffer_key); + if (num_buffer_fd < 0 || num_buffer_fd > BUFFER_MAX_PLANE_NUM) { + LOGE("invalid num buffer fd %d", num_buffer_fd); goto _PREVIEW_CB_HANDLER_DONE; } - if (data_key > 0) { + if (num_buffer_fd == 0 && tfd[1] >= 0) { /* import tbm data_bo and get virtual address */ - if (!_camera_import_tbm_key(cb_info->bufmgr, data_key, &data_bo, &data_bo_handle)) { - LOGE("failed to import data key %d", data_key); + if (!_camera_import_tbm_fd(cb_info->bufmgr, tfd[1], &data_bo, &data_bo_handle)) { + LOGE("failed to import data fd %d", tfd[1]); goto _PREVIEW_CB_HANDLER_DONE; } } /* import tbm bo and get virtual address */ - if (!_camera_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) { - LOGE("failed to import key %d", tbm_key); + if (!_camera_import_tbm_fd(cb_info->bufmgr, tfd[0], &bo, &bo_handle)) { + LOGE("failed to import fd %d", tfd[0]); goto _PREVIEW_CB_HANDLER_DONE; } @@ -197,24 +203,24 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv /* get stream info */ stream = (camera_stream_data_s *)buf_pos; - for (i = 0 ; i < num_buffer_key ; i++) { + for (i = 0 ; i < num_buffer_fd ; i++) { /* import buffer bo and get virtual address */ - if (!_camera_import_tbm_key(cb_info->bufmgr, buffer_key[i], &buffer_bo[i], &buffer_bo_handle[i])) { - LOGE("failed to import buffer key %d", buffer_key[i]); + if (!_camera_import_tbm_fd(cb_info->bufmgr, tfd[i + 1], &buffer_bo[i], &buffer_bo_handle[i])) { + LOGE("failed to import buffer fd %d", tfd[i + 1]); goto _PREVIEW_CB_HANDLER_DONE; } } /* call preview callback */ if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW]) { - _camera_preview_frame_create(stream, num_buffer_key, buffer_bo_handle, &data_bo_handle, &frame); + _camera_preview_frame_create(stream, num_buffer_fd, buffer_bo_handle, &data_bo_handle, &frame); ((camera_preview_cb)cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW])(&frame, cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW]); } if (CHECK_PREVIEW_CB(cb_info, PREVIEW_CB_TYPE_EVAS)) { - ret = _camera_media_packet_data_create(tbm_key, num_buffer_key, bo, buffer_bo, data_bo, &mp_data); + ret = _camera_media_packet_data_create(ret_fd, tfd, num_buffer_fd, bo, buffer_bo, data_bo, &mp_data); if (ret == CAMERA_ERROR_NONE) { ret = _camera_media_packet_create(cb_info, stream, mp_data, &pkt_evas); @@ -228,7 +234,7 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv /* call media packet callback */ if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW]) { - ret = _camera_media_packet_data_create(tbm_key, num_buffer_key, bo, buffer_bo, data_bo, &mp_data); + ret = _camera_media_packet_data_create(ret_fd, tfd, num_buffer_fd, bo, buffer_bo, data_bo, &mp_data); if (ret == CAMERA_ERROR_NONE) { ret = _camera_media_packet_create(cb_info, stream, mp_data, &pkt); @@ -261,13 +267,23 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv _PREVIEW_CB_HANDLER_DONE: if (mp_data == NULL) { /* release imported bo */ - for (i = 0 ; i < num_buffer_key && i < BUFFER_MAX_PLANE_NUM ; i++) + for (i = 0 ; i < num_buffer_fd && i < BUFFER_MAX_PLANE_NUM ; i++) _camera_release_imported_bo(&buffer_bo[i]); /* unmap and unref tbm bo */ _camera_release_imported_bo(&data_bo); _camera_release_imported_bo(&bo); + /* close imported fd */ + for (i = 0 ; i < MUSE_NUM_FD ; i++) { + if (tfd[i] >= 0) { + close(tfd[i]); + tfd[i] = -1; + } else { + break; + } + } + /* return buffer */ _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); @@ -278,15 +294,15 @@ _PREVIEW_CB_HANDLER_DONE: } -static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv_msg) +static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv_msg, int *tfd) { - int tbm_key = 0; - int tbm_key_main = 0; - int tbm_key_post = 0; - int tbm_key_thumb = 0; + int i = 0; + int tfd_index = 0; + int capture_fd_main = 0; + int capture_fd_post = 0; + int capture_fd_thumb = 0; unsigned char *buf_pos = NULL; - camera_msg_param param; camera_image_data_s *rImage = NULL; camera_image_data_s *rPostview = NULL; camera_image_data_s *rThumbnail = NULL; @@ -298,22 +314,21 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv tbm_bo_handle bo_post_handle = {.ptr = NULL}; tbm_bo_handle bo_thumb_handle = {.ptr = NULL}; - if (!cb_info || !recv_msg) { - LOGE("invalid param %p %p", cb_info, recv_msg); + if (!cb_info || !recv_msg || !tfd) { + LOGE("invalid param %p %p %p", cb_info, recv_msg, tfd); return; } - muse_camera_msg_get(tbm_key_main, recv_msg); - muse_camera_msg_get(tbm_key_post, recv_msg); - muse_camera_msg_get(tbm_key_thumb, recv_msg); + muse_camera_msg_get(capture_fd_main, recv_msg); + muse_camera_msg_get(capture_fd_post, recv_msg); + muse_camera_msg_get(capture_fd_thumb, recv_msg); - /* - LOGD("camera capture callback came in. tbm_key_main %d, tbm_key_post %d, tbm_key_thumb %d", - tbm_key_main, tbm_key_post, tbm_key_thumb); - */ + LOGD("capture fd %d %d %d, received fd %d %d %d", + capture_fd_main, capture_fd_post, capture_fd_thumb, + tfd[0], tfd[1], tfd[2]); - if (tbm_key_main <= 0) { - LOGE("invalid key %d", tbm_key_main); + if (capture_fd_main < 0 || tfd[tfd_index] < 0) { + LOGE("invalid main fd %d %d", capture_fd_main, tfd[tfd_index]); goto _CAPTURE_CB_HANDLER_DONE; } @@ -323,8 +338,8 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv } /* import tbm bo and get virtual address */ - if (!_camera_import_tbm_key(cb_info->bufmgr, tbm_key_main, &bo_main, &bo_main_handle)) { - LOGE("failed to import key [%d] for main", tbm_key_main); + if (!_camera_import_tbm_fd(cb_info->bufmgr, tfd[tfd_index], &bo_main, &bo_main_handle)) { + LOGE("failed to import fd [%d] for main", tfd[tfd_index]); goto _CAPTURE_CB_HANDLER_DONE; } @@ -341,27 +356,29 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv LOGD("image info %dx%d, size %d, EXIF info %p, size %d", rImage->width, rImage->height, rImage->size, rImage->exif, rImage->exif_size); - if (tbm_key_post > 0) { + if (capture_fd_post >= 0) { /* import tbm bo and get virtual address */ - if (_camera_import_tbm_key(cb_info->bufmgr, tbm_key_post, &bo_post, &bo_post_handle)) { + tfd_index++; + if (_camera_import_tbm_fd(cb_info->bufmgr, tfd[tfd_index], &bo_post, &bo_post_handle)) { buf_pos = (unsigned char *)bo_post_handle.ptr; rPostview = (camera_image_data_s *)buf_pos; LOGD("rPostview->size : %d", rPostview->size); rPostview->data = buf_pos + sizeof(camera_image_data_s); } else { - LOGE("failed to import key [%d] for postview", tbm_key_post); + LOGE("failed to import fd [i:%d][%d] for postview", tfd_index, tfd[tfd_index]); } } - if (tbm_key_thumb > 0) { + if (capture_fd_thumb >= 0) { /* import tbm bo and get virtual address */ - if (_camera_import_tbm_key(cb_info->bufmgr, tbm_key_thumb, &bo_thumb, &bo_thumb_handle)) { + tfd_index++; + if (_camera_import_tbm_fd(cb_info->bufmgr, tfd[tfd_index], &bo_thumb, &bo_thumb_handle)) { buf_pos = (unsigned char *)bo_thumb_handle.ptr; rThumbnail = (camera_image_data_s *)buf_pos; LOGD("rThumbnail->size : %d", rThumbnail->size); rThumbnail->data = buf_pos + sizeof(camera_image_data_s); } else { - LOGE("failed to import key [%d] for thumbnail", tbm_key_thumb); + LOGE("failed to import fd [%d] for thumbnail", tfd[tfd_index]); } } @@ -370,31 +387,29 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv _CAPTURE_CB_HANDLER_DONE: /* return buffer */ - if (tbm_key_main > 0) { + if (capture_fd_main >= 0) { _camera_release_imported_bo(&bo_main); - - tbm_key = tbm_key_main; - CAMERA_MSG_PARAM_SET(param, INT, tbm_key); - - _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); + _camera_msg_return_buffer(capture_fd_main, cb_info); } - if (tbm_key_post > 0) { + if (capture_fd_post >= 0) { _camera_release_imported_bo(&bo_post); - - tbm_key = tbm_key_post; - CAMERA_MSG_PARAM_SET(param, INT, tbm_key); - - _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); + _camera_msg_return_buffer(capture_fd_post, cb_info); } - if (tbm_key_thumb > 0) { + if (capture_fd_thumb >= 0) { _camera_release_imported_bo(&bo_thumb); + _camera_msg_return_buffer(capture_fd_thumb, cb_info); + } - tbm_key = tbm_key_thumb; - CAMERA_MSG_PARAM_SET(param, INT, tbm_key); - - _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); + for (i = 0 ; i < MUSE_NUM_FD ; i++) { + if (tfd[i] >= 0) { + LOGD("close %d", tfd[i]); + close(tfd[i]); + tfd[i] = -1; + } else { + break; + } } LOGD("return buffer done"); @@ -403,33 +418,34 @@ _CAPTURE_CB_HANDLER_DONE: } -static void __camera_event_handler_face_detection(camera_cb_info_s *cb_info, char *recv_msg) +static void __camera_event_handler_face_detection(camera_cb_info_s *cb_info, char *recv_msg, int *tfd) { int count = 0; - int tbm_key = 0; + int face_fd = -1; camera_detected_face_s *faces = NULL; - camera_msg_param param; tbm_bo bo = NULL; tbm_bo_handle bo_handle = {.ptr = NULL}; - if (!cb_info || !recv_msg) { - LOGE("invalid param %p %p", cb_info, recv_msg); + if (!cb_info || !recv_msg || !tfd) { + LOGE("invalid param %p %p %p", cb_info, recv_msg, tfd); return; } muse_camera_msg_get(count, recv_msg); - muse_camera_msg_get(tbm_key, recv_msg); + muse_camera_msg_get(face_fd, recv_msg); if (count >= 0 && cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION]) { - LOGD("FACE_DETECTION - count %d, tbm_key %d", count, tbm_key); + LOGD("FACE_DETECTION - count %d, fd %d", count, tfd[0]); - if (tbm_key > 0) { - - if (_camera_import_tbm_key(cb_info->bufmgr, tbm_key, &bo, &bo_handle)) { + if (tfd[0] >= 0) { + if (_camera_import_tbm_fd(cb_info->bufmgr, tfd[0], &bo, &bo_handle)) { /* set face info */ faces = bo_handle.ptr; } + + close(tfd[0]); + tfd[0] = -1; } ((camera_face_detected_cb)cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION])(faces, @@ -438,35 +454,31 @@ static void __camera_event_handler_face_detection(camera_cb_info_s *cb_info, cha /* release bo */ _camera_release_imported_bo(&bo); } else { - LOGW("skip face detection message [count %d, key %d, cb %p", - count, tbm_key, cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION]); + LOGW("skip face detection message [count %d, fd %d, cb %p]", + count, tfd[0], cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION]); } /* return buffer */ - if (tbm_key > 0) { - CAMERA_MSG_PARAM_SET(param, INT, tbm_key); - _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); - /*LOGD("return buffer done");*/ - } + _camera_msg_return_buffer(face_fd, cb_info); return; } -static int _camera_import_tbm_key(tbm_bufmgr bufmgr, unsigned int tbm_key, tbm_bo *bo, tbm_bo_handle *bo_handle) +static bool _camera_import_tbm_fd(tbm_bufmgr bufmgr, int fd, tbm_bo *bo, tbm_bo_handle *bo_handle) { tbm_bo tmp_bo = NULL; tbm_bo_handle tmp_bo_handle = {NULL, }; - if (!bufmgr || !bo || !bo_handle || !tbm_key) { - LOGE("invalid parameter - %p %p %p, key %d", - bufmgr, bo, bo_handle, tbm_key); + if (!bufmgr || !bo || !bo_handle || fd < 0) { + LOGE("invalid parameter - %p %p %p, fd %d", + bufmgr, bo, bo_handle, fd); return false; } - tmp_bo = tbm_bo_import(bufmgr, tbm_key); + tmp_bo = tbm_bo_import_fd(bufmgr, (tbm_fd)fd); if (tmp_bo == NULL) { - LOGE("import failed - key %d", tbm_key); + LOGE("import failed - fd %d", fd); return false; } @@ -729,6 +741,23 @@ _SEND_PARAM2_INT_DONE: } +static void _camera_msg_return_buffer(int ret_fd, camera_cb_info_s *cb_info) +{ + camera_msg_param param; + + if (ret_fd < 0) { + LOGW("invalid fd %d", ret_fd); + return; + } + + CAMERA_MSG_PARAM_SET(param, INT, ret_fd); + + _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); + + return; +} + + int _camera_get_tbm_surface_format(int in_format, uint32_t *out_format) { if (in_format <= MM_PIXEL_FORMAT_INVALID || @@ -842,7 +871,7 @@ int _camera_get_media_packet_mimetype(int in_format, media_format_mimetype_e *mi return CAMERA_ERROR_NONE; } -static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_buffer_key, +static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_buffer_fd, tbm_bo_handle *buffer_bo_handle, tbm_bo_handle *data_bo_handle, camera_preview_data_s *frame) { int total_size = 0; @@ -864,7 +893,7 @@ static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_b frame->timestamp = stream->timestamp; frame->num_of_planes = stream->num_planes; - if (num_buffer_key == 0) { + if (num_buffer_fd == 0) { /* non-zero copy */ if (!data_bo_handle || !data_bo_handle->ptr) { LOGE("NULL pointer"); @@ -929,7 +958,7 @@ static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_b break; case 2: frame->data.double_plane.y = buffer_bo_handle[0].ptr; - if (stream->num_planes == (unsigned int)num_buffer_key) + if (stream->num_planes == (unsigned int)num_buffer_fd) frame->data.double_plane.uv = buffer_bo_handle[1].ptr; else frame->data.double_plane.uv = buffer_bo_handle[0].ptr + stream->data.yuv420sp.length_y; @@ -940,7 +969,7 @@ static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_b break; case 3: frame->data.triple_plane.y = buffer_bo_handle[0].ptr; - if (stream->num_planes == (unsigned int)num_buffer_key) { + if (stream->num_planes == (unsigned int)num_buffer_fd) { frame->data.triple_plane.u = buffer_bo_handle[1].ptr; frame->data.triple_plane.v = buffer_bo_handle[2].ptr; } else { @@ -967,24 +996,39 @@ static void _camera_preview_frame_create(camera_stream_data_s *stream, int num_b return; } -static int _camera_media_packet_data_create(int tbm_key, int num_buffer_key, tbm_bo bo, +static int _camera_media_packet_data_create(int ret_fd, int *tfd, int num_buffer_fd, tbm_bo bo, tbm_bo *buffer_bo, tbm_bo data_bo, camera_media_packet_data **mp_data) { int i = 0; int ret = CAMERA_ERROR_NONE; camera_media_packet_data *tmp_mp_data = NULL; + if (!tfd) { + LOGE("NULL tfd"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + if (*mp_data == NULL) { tmp_mp_data = g_new0(camera_media_packet_data, 1); if (tmp_mp_data) { - tmp_mp_data->tbm_key = tbm_key; - tmp_mp_data->num_buffer_key = num_buffer_key; + tmp_mp_data->ret_fd = ret_fd; + tmp_mp_data->fd = tfd[0]; + tmp_mp_data->num_buffer_fd = num_buffer_fd; tmp_mp_data->bo = bo; - tmp_mp_data->data_bo = data_bo; - tmp_mp_data->ref_cnt++; - for (i = 0 ; i < num_buffer_key ; i++) - tmp_mp_data->buffer_bo[i] = buffer_bo[i]; + if (data_bo) { + /* non-zero copy */ + tmp_mp_data->data_bo = data_bo; + tmp_mp_data->data_fd = tfd[1]; + } else { + /* zero copy */ + for (i = 0 ; i < num_buffer_fd ; i++) { + tmp_mp_data->buffer_bo[i] = buffer_bo[i]; + tmp_mp_data->buffer_fd[i] = (tbm_fd)tfd[i + 1]; + } + } + + tmp_mp_data->ref_cnt++; *mp_data = tmp_mp_data; /*LOGD("mp_data %p", tmp_mp_data);*/ @@ -1002,8 +1046,6 @@ static int _camera_media_packet_data_create(int tbm_key, int num_buffer_key, tbm static void _camera_media_packet_data_release(camera_media_packet_data *mp_data, camera_cb_info_s *cb_info) { int i = 0; - int tbm_key = 0; - camera_msg_param param; if (!mp_data || !cb_info) { LOGE("NULL pointer %p %p", mp_data, cb_info); @@ -1014,22 +1056,28 @@ static void _camera_media_packet_data_release(camera_media_packet_data *mp_data, mp_data->ref_cnt--; LOGD("ref count %d", mp_data->ref_cnt); } else { - /* release imported bo */ - for (i = 0 ; i < mp_data->num_buffer_key ; i++) { + /* release imported bo and close imported fd */ + for (i = 0 ; i < mp_data->num_buffer_fd ; i++) { tbm_bo_unref(mp_data->buffer_bo[i]); mp_data->buffer_bo[i] = NULL; + + close(mp_data->buffer_fd[i]); + mp_data->buffer_fd[i] = -1; } - /* unref tbm bo */ + /* unref tbm bo and close imported fd */ + close(mp_data->fd); + mp_data->fd = -1; _camera_release_imported_bo(&mp_data->bo); + + if (mp_data->data_bo && mp_data->data_fd >= 0) { + close(mp_data->data_fd); + mp_data->data_fd = -1; + } _camera_release_imported_bo(&mp_data->data_bo); /* return buffer */ - tbm_key = mp_data->tbm_key; - - CAMERA_MSG_PARAM_SET(param, INT, tbm_key); - - _camera_msg_send_param1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info, NULL, ¶m, 0); + _camera_msg_return_buffer(mp_data->ret_fd, cb_info); g_free(mp_data); mp_data = NULL; @@ -1049,7 +1097,7 @@ static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_ uint32_t bo_format = 0; int ret = 0; int i = 0; - int num_buffer_key = 0; + int num_buffer_fd = 0; tbm_bo *buffer_bo = NULL; if (cb_info == NULL || stream == NULL || mp_data == NULL || packet == NULL) { @@ -1060,7 +1108,7 @@ static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_ memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); buffer_bo = mp_data->buffer_bo; - num_buffer_key = mp_data->num_buffer_key; + num_buffer_fd = mp_data->num_buffer_fd; /* create tbm surface */ for (i = 0 ; i < BUFFER_MAX_PLANE_NUM ; i++) @@ -1077,14 +1125,14 @@ static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_ tsurf_info.bpp = tbm_surface_internal_get_bpp(bo_format); tsurf_info.num_planes = tbm_surface_internal_get_num_planes(bo_format); - if (num_buffer_key > 0) { + if (num_buffer_fd > 0) { switch (bo_format) { case TBM_FORMAT_NV12: case TBM_FORMAT_NV21: tsurf_info.planes[0].size = stream->stride[0] * stream->elevation[0]; tsurf_info.planes[1].size = stream->stride[1] * stream->elevation[1]; tsurf_info.planes[0].offset = 0; - if (num_buffer_key == 1) + if (num_buffer_fd == 1) tsurf_info.planes[1].offset = tsurf_info.planes[0].size; tsurf_info.size = tsurf_info.planes[0].size + tsurf_info.planes[1].size; break; @@ -1094,7 +1142,7 @@ static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_ tsurf_info.planes[1].size = stream->stride[1] * stream->elevation[1]; tsurf_info.planes[2].size = stream->stride[2] * stream->elevation[2]; tsurf_info.planes[0].offset = 0; - if (num_buffer_key == 1) { + if (num_buffer_fd == 1) { tsurf_info.planes[1].offset = tsurf_info.planes[0].size; tsurf_info.planes[2].offset = tsurf_info.planes[0].size + tsurf_info.planes[1].size; } @@ -1110,7 +1158,7 @@ static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_ break; } - tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, buffer_bo, num_buffer_key); + tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, buffer_bo, num_buffer_fd); } else if (mp_data->data_bo) { switch (bo_format) { case TBM_FORMAT_NV12: @@ -1191,8 +1239,8 @@ static int _camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream_ tsurf = NULL; } } else { - LOGE("tbm surface failed. %dx%d, format %d, num_buffer_key %d, data_bo %p", - stream->width, stream->height, stream->format, num_buffer_key, mp_data->data_bo); + LOGE("tbm surface failed. %dx%d, format %d, num_buffer_fd %d, data_bo %p", + stream->width, stream->height, stream->format, num_buffer_fd, mp_data->data_bo); } if (pkt) { @@ -1258,7 +1306,7 @@ int _camera_media_packet_finalize(media_packet_h pkt, int error_code, void *user return MEDIA_PACKET_FINALIZE; } -static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_msg, muse_camera_event_e event) +static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_msg, muse_camera_event_e event, int *tfd) { int param1 = 0; int param2 = 0; @@ -1325,7 +1373,7 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m break; case MUSE_CAMERA_EVENT_TYPE_PREVIEW: case MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW: - __camera_event_handler_preview(cb_info, recv_msg); + __camera_event_handler_preview(cb_info, recv_msg, tfd); break; case MUSE_CAMERA_EVENT_TYPE_HDR_PROGRESS: { @@ -1369,7 +1417,7 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m } break; case MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION: - __camera_event_handler_face_detection(cb_info, recv_msg); + __camera_event_handler_face_detection(cb_info, recv_msg, tfd); break; case MUSE_CAMERA_EVENT_TYPE_ERROR: { @@ -1439,7 +1487,7 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m } break; case MUSE_CAMERA_EVENT_TYPE_CAPTURE: - __camera_event_handler_capture(cb_info, recv_msg); + __camera_event_handler_capture(cb_info, recv_msg, tfd); break; default: LOGW("unhandled event %d", event); @@ -1478,7 +1526,7 @@ static gboolean _camera_idle_event_callback(gpointer data) g_mutex_unlock(&g_cam_idle_event_lock); /* user callback */ - _camera_client_user_callback(cb_info, cam_idle_event->recv_msg, cam_idle_event->event); + _camera_client_user_callback(cb_info, cam_idle_event->recv_msg, cam_idle_event->event, cam_idle_event->tfd); IDLE_EVENT_CALLBACK_DONE: /* release event */ @@ -1557,7 +1605,7 @@ static void *_camera_msg_handler_func(gpointer data) } else if (api == MUSE_CAMERA_CB_EVENT) { switch (cam_msg->event_class) { case MUSE_CAMERA_EVENT_CLASS_THREAD_SUB: - _camera_client_user_callback(cb_info, cam_msg->recv_msg, cam_msg->event); + _camera_client_user_callback(cb_info, cam_msg->recv_msg, cam_msg->event, cam_msg->tfd); break; case MUSE_CAMERA_EVENT_CLASS_THREAD_MAIN: cam_idle_event = g_new0(camera_idle_event_s, 1); @@ -1570,6 +1618,7 @@ static void *_camera_msg_handler_func(gpointer data) cam_idle_event->cb_info = cb_info; strncpy(cam_idle_event->recv_msg, cam_msg->recv_msg, sizeof(cam_idle_event->recv_msg) - 1); + memcpy(cam_idle_event->tfd, cam_msg->tfd, sizeof(cam_idle_event->tfd)); /*LOGD("t:%d add camera event[%d, %p] to IDLE", type, cam_msg->event, cam_idle_event);*/ @@ -1673,7 +1722,7 @@ static void _camera_deactivate_idle_event_all(camera_cb_info_s *cb_info) } -static void __camera_add_msg_to_queue(camera_cb_info_s *cb_info, int api, int event, int event_class, char *msg) +static void __camera_add_msg_to_queue(camera_cb_info_s *cb_info, int api, int event, int event_class, char *msg, int *tfd) { camera_message_s *cam_msg = NULL; @@ -1692,6 +1741,9 @@ static void __camera_add_msg_to_queue(camera_cb_info_s *cb_info, int api, int ev cam_msg->event = event; cam_msg->event_class = event_class; + if (tfd && tfd[0] >= 0) + memcpy(cam_msg->tfd, tfd, sizeof(cam_msg->tfd)); + strncpy(cam_msg->recv_msg, msg, sizeof(cam_msg->recv_msg) - 1); /*LOGD("add camera message to queue : api %d, event %d, event_class %d", api, event, event_class);*/ @@ -1719,7 +1771,7 @@ static void __camera_add_msg_to_queue(camera_cb_info_s *cb_info, int api, int ev } -static void __camera_process_msg(camera_cb_info_s *cb_info, char *msg) +static void __camera_process_msg(camera_cb_info_s *cb_info, char *msg, int *tfd) { int ret = CAMERA_ERROR_NONE; int api = -1; @@ -1832,7 +1884,7 @@ static void __camera_process_msg(camera_cb_info_s *cb_info, char *msg) g_mutex_unlock(&cb_info->api_mutex[api]); } else if (api_class == MUSE_CAMERA_API_CLASS_THREAD_SUB || api == MUSE_CAMERA_CB_EVENT) { - __camera_add_msg_to_queue(cb_info, api, event, event_class, msg); + __camera_add_msg_to_queue(cb_info, api, event, event_class, msg, tfd); } else { LOGW("unknown camera api %d, class %d", api, api_class); } @@ -1843,15 +1895,10 @@ static void __camera_process_msg(camera_cb_info_s *cb_info, char *msg) static void *_camera_msg_recv_func(gpointer data) { + int i = 0; int recv_length = 0; - int single_length = 0; - int remained_length = 0; + int tfd[MUSE_NUM_FD] = {-1, -1, -1, -1}; char *recv_msg = NULL; - char *single_msg = NULL; - char *remained_msg = NULL; - int num_msg = 0; - int cur_pos = 0; - int prev_pos = 0; camera_cb_info_s *cb_info = (camera_cb_info_s *)data; if (!cb_info) { @@ -1861,92 +1908,29 @@ static void *_camera_msg_recv_func(gpointer data) LOGD("start - fd : %d", cb_info->fd); - single_msg = (char *)malloc(sizeof(char) * MUSE_CAMERA_MSG_MAX_LENGTH); - if (!single_msg) { - LOGE("single_msg malloc failed"); - return NULL; - } - recv_msg = cb_info->recv_msg; while (g_atomic_int_get(&cb_info->msg_recv_running)) { - recv_length = muse_core_msg_recv(cb_info->fd, recv_msg, MUSE_MSG_MAX_LENGTH); + for (i = 0 ; i < MUSE_NUM_FD ; i++) + tfd[i] = -1; + + recv_length = muse_core_msg_recv_fd(cb_info->fd, recv_msg, MUSE_MSG_MAX_LENGTH, tfd); if (recv_length <= 0) { cb_info->is_server_connected = FALSE; LOGE("receive msg failed - server disconnected"); break; } - cur_pos = 0; - prev_pos = 0; - num_msg = 0; - - /*LOGD("recv msg : %s, length : %d", recv_msg, recv_length);*/ - - /* Need to split the combined entering msgs */ - for (cur_pos = 0 ; cur_pos < recv_length ; cur_pos++) { - if (recv_msg[cur_pos] == '}') { - single_length = cur_pos - prev_pos + 1; - - if (single_length < MUSE_CAMERA_MSG_MAX_LENGTH) { - /* check remained msg */ - if (remained_length > 0) { - if (remained_msg) { - strncpy(single_msg, remained_msg, remained_length); - strncpy(single_msg + remained_length, recv_msg + prev_pos, single_length); - single_msg[remained_length + single_length] = '\0'; - - free(remained_msg); - remained_msg = NULL; - } else { - strncpy(single_msg, recv_msg + prev_pos, single_length); - single_msg[single_length] = '\0'; - LOGE("lost msg [%s], skip...", single_msg); - } - - remained_length = 0; - } else { - strncpy(single_msg, recv_msg + prev_pos, single_length); - single_msg[single_length] = '\0'; - } - - if (single_msg[0] == '{') { - num_msg++; - /*LOGD("splitted msg : [%s], Index : %d", single_msg, num_msg);*/ - /* process each message */ - __camera_process_msg(cb_info, single_msg); - } else { - LOGE("invalid msg [%s]", single_msg); - } - } else { - LOGE("too long message [len %d] skip...", single_length); - } - - prev_pos = cur_pos + 1; - } - } - - /* check incompleted message */ - if (recv_msg[recv_length - 1] != '}') { - remained_length = recv_length - prev_pos; + /* + if (tfd[0] >= 0) + LOGD("%d %d %d %d", tfd[0], tfd[1], tfd[2], tfd[3]); + */ - LOGW("incompleted message [len %d]", remained_length); + recv_msg[recv_length] = '\0'; - if (remained_msg) { - free(remained_msg); - remained_msg = NULL; - } + /*LOGD("recv msg : %s, length : %d", recv_msg, recv_length);*/ - remained_msg = (char *)malloc(remained_length + 1); - if (remained_msg) { - strncpy(remained_msg, recv_msg + prev_pos, remained_length); - remained_msg[remained_length] = '\0'; - } else { - LOGE("failed to alloc for remained msg"); - } - } else { - remained_length = 0; - } + __camera_process_msg(cb_info, recv_msg, tfd); } LOGD("client cb exit - server connected %d", cb_info->is_server_connected); @@ -1974,7 +1958,8 @@ static void *_camera_msg_recv_func(gpointer data) MUSE_CAMERA_CB_EVENT, MUSE_CAMERA_EVENT_TYPE_ERROR, MUSE_CAMERA_EVENT_CLASS_THREAD_MAIN, - error_msg); + error_msg, + NULL); muse_core_msg_free(error_msg); error_msg = NULL; @@ -1983,16 +1968,6 @@ static void *_camera_msg_recv_func(gpointer data) } CB_HANDLER_EXIT: - if (single_msg) { - free(single_msg); - single_msg = NULL; - } - - if (remained_msg) { - free(remained_msg); - remained_msg = NULL; - } - return NULL; }