From e0d104327e827d34ceba7d6af58a212c8c9274af Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Tue, 5 Apr 2022 21:10:42 +0900 Subject: [PATCH] Support zero-copy with encoded format [Version] 0.4.76 [Issue Type] New feature Change-Id: Ibaee3a220365656f943907cc14d150e3e401ecd8 Signed-off-by: Jeongmo Yang --- packaging/capi-media-camera.spec | 2 +- src/camera.c | 63 ++++++++----------- src/camera_internal.c | 13 +++- test/camera_test.c | 118 ++++++++++++++++++++++++----------- test_headless/camera_test_headless.c | 117 +++++++++++++++++++++++----------- 5 files changed, 197 insertions(+), 116 deletions(-) diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 3947dec..66bd4ec 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.75 +Version: 0.4.76 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index c3f50cc..787aff8 100644 --- a/src/camera.c +++ b/src/camera.c @@ -334,14 +334,17 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv if (stream->data_type == MM_CAM_STREAM_DATA_ENCODED) stream->data.encoded.data = data_bo_handle.ptr; - } - - for (i = 0 ; i < num_buffer_fd ; i++) { - /* import buffer bo and get virtual address */ - if (!__camera_import_tbm_fd(cb_info->bufmgr, tfd[i + 1], &buffer_bo[i], &buffer_bo_handle[i])) { - CAM_LOG_ERROR("failed to import buffer fd %d", tfd[i + 1]); - goto _PREVIEW_CB_HANDLER_DONE; + } else { + for (i = 0 ; i < num_buffer_fd ; i++) { + /* import buffer bo and get virtual address */ + if (!__camera_import_tbm_fd(cb_info->bufmgr, tfd[i + 1], &buffer_bo[i], &buffer_bo_handle[i])) { + CAM_LOG_ERROR("failed to import buffer fd %d", tfd[i + 1]); + goto _PREVIEW_CB_HANDLER_DONE; + } } + + if (stream->data_type == MM_CAM_STREAM_DATA_ENCODED) + stream->data.encoded.data = buffer_bo_handle[0].ptr; } /* preview callback */ @@ -1025,8 +1028,8 @@ int _camera_get_media_packet_mimetype(int in_format, media_format_mimetype_e *mi *mimetype = MEDIA_FORMAT_VP9; break; default: - CAM_LOG_ERROR("invalid in_format %d", in_format); - return CAMERA_ERROR_INVALID_PARAMETER; + CAM_LOG_ERROR("unsupported format[%d]", in_format); + return CAMERA_ERROR_NOT_SUPPORTED; //LCOV_EXCL_STOP } @@ -1175,16 +1178,11 @@ static tbm_surface_h __camera_get_tbm_surface(MMCamcorderVideoStreamDataType *st tsurf_info.num_planes = tbm_surface_internal_get_num_planes(tbm_format); switch (tbm_format) { - case TBM_FORMAT_NV12: - /* fall through */ - case TBM_FORMAT_NV21: - /* fall through */ - case TBM_FORMAT_YUV420: - /* fall through */ - case TBM_FORMAT_YVU420: - /* fall through */ - case TBM_FORMAT_UYVY: - /* fall through */ + case TBM_FORMAT_NV12: /* fall through */ + case TBM_FORMAT_NV21: /* fall through */ + case TBM_FORMAT_YUV420: /* fall through */ + case TBM_FORMAT_YVU420: /* fall through */ + case TBM_FORMAT_UYVY: /* fall through */ case TBM_FORMAT_YUYV: for (i = 0 ; i < (int)tsurf_info.num_planes ; i++) { tsurf_info.planes[i].stride = stream->stride[i]; @@ -1198,12 +1196,9 @@ static tbm_surface_h __camera_get_tbm_surface(MMCamcorderVideoStreamDataType *st } break; //LCOV_EXCL_START - case TBM_FORMAT_RGB565: - /* fall through */ - case TBM_FORMAT_RGB888: - /* fall through */ - case TBM_FORMAT_RGBA8888: - /* fall through */ + case TBM_FORMAT_RGB565: /* fall through */ + case TBM_FORMAT_RGB888: /* fall through */ + case TBM_FORMAT_RGBA8888: /* fall through */ case TBM_FORMAT_ARGB8888: tsurf_info.planes[0].size = stream->data.rgb.length_data; tsurf_info.planes[0].offset = 0; @@ -1289,7 +1284,7 @@ static int __camera_create_media_packet(camera_cb_info_s *cb_info, MMCamcorderVi { media_packet_h pkt = NULL; tbm_surface_h tsurf = NULL; - int ret = 0; + int ret = CAMERA_ERROR_NONE; if (!cb_info || !stream || !mp_data || !packet) { CAM_LOG_ERROR("invalid parameter - %p, %p, %p, %p", @@ -1301,28 +1296,22 @@ static int __camera_create_media_packet(camera_cb_info_s *cb_info, MMCamcorderVi if (ret != CAMERA_ERROR_NONE) return ret; - switch (stream->data_type) { - case MM_CAM_STREAM_DATA_ENCODED: + if (stream->data_type == MM_CAM_STREAM_DATA_ENCODED) { ret = media_packet_new_from_external_memory(cb_info->pkt_fmt, stream->data.encoded.data, stream->data.encoded.length_data, (media_packet_dispose_cb)_camera_media_packet_dispose, (void *)cb_info, &pkt); - break; - case MM_CAM_STREAM_DATA_DEPTH: - CAM_LOG_ERROR("DEPTH type is not supported"); - return CAMERA_ERROR_NOT_SUPPORTED; - default: /* YUV and RGB */ + } else { tsurf = __camera_get_tbm_surface(stream, mp_data); if (!tsurf) { - CAM_LOG_ERROR("tbm surface failed. %dx%d, format %d, num_buffer_fd %d, data_bo %p", - stream->width, stream->height, stream->format, mp_data->num_buffer_fd, mp_data->data_bo); - return CAMERA_ERROR_INVALID_OPERATION; + CAM_LOG_ERROR("get tbm surface failed"); + ret = CAMERA_ERROR_INVALID_OPERATION; + goto _PACKET_CREATE_FAILED; } ret = media_packet_new_from_tbm_surface(cb_info->pkt_fmt, tsurf, (media_packet_dispose_cb)_camera_media_packet_dispose, (void *)cb_info, &pkt); - break; } if (ret != MEDIA_PACKET_ERROR_NONE) { diff --git a/src/camera_internal.c b/src/camera_internal.c index 6618838..9259298 100644 --- a/src/camera_internal.c +++ b/src/camera_internal.c @@ -158,9 +158,16 @@ void camera_create_preview_frame(MMCamcorderVideoStreamDataType *stream, int num switch (stream->num_planes) { //LCOV_EXCL_START case 1: - frame->data.single_plane.yuv = buffer_bo_handle[0].ptr; - frame->data.single_plane.size = stream->data.yuv420.length_yuv; - total_size = stream->data.yuv420.length_yuv; + if (stream->data_type == MM_CAM_STREAM_DATA_ENCODED) { + frame->data.encoded_plane.data = buffer_bo_handle[0].ptr; + frame->data.encoded_plane.size = stream->data.encoded.length_data; + frame->data.encoded_plane.is_delta_frame = (bool)stream->data.encoded.is_delta_frame; + total_size = stream->data.encoded.length_data; + } else { + frame->data.single_plane.yuv = buffer_bo_handle[0].ptr; + frame->data.single_plane.size = stream->data.yuv420.length_yuv; + total_size = stream->data.yuv420.length_yuv; + } break; //LCOV_EXCL_STOP case 2: diff --git a/test/camera_test.c b/test/camera_test.c index 98dfdbb..a60ef02 100644 --- a/test/camera_test.c +++ b/test/camera_test.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -618,19 +619,87 @@ static void _camera_extra_preview_cb(camera_preview_data_s *frame, int stream_id _dump_preview_data(frame, EXTRA_PREVIEW_CB_DUMP_FILE_NAME); } +static void _dump_media_packet_data(media_packet_h pkt, const char *file_name) +{ + int ret = 0; + unsigned int i = 0; + bool has_surface = false; + FILE *fp = NULL; + char dump_path[MAX_FILE_NAME_LENGTH] = {'\0',}; + tbm_surface_h surface = NULL; + tbm_surface_info_s s_info; + void *data = NULL; + uint64_t data_size = 0; + + if (!pkt) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] NULL packet\n"); + return; + } + + snprintf(dump_path, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, file_name); + fp = fopen(dump_path, "a"); + if (fp == NULL) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] file[%s] open failed ====\n", dump_path); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + ret = media_packet_has_tbm_surface_buffer(pkt, &has_surface); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] has tbm surface failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + if (has_surface) { + ret = media_packet_get_tbm_surface(pkt, &surface); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get tbm surface failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + ret = tbm_surface_get_info(surface, &s_info); + if (ret != TBM_SURFACE_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get tbm surface info failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + g_print(" tbm surface [%dx%d], total size[%u]\n", + s_info.width, s_info.height, s_info.size); + + for (i = 0 ; i < s_info.num_planes ; i++) { + g_print(" plane[%d][%p] stride[%u] size[%u]\n", + i, s_info.planes[i].ptr, s_info.planes[i].stride, s_info.planes[i].size); + fwrite(s_info.planes[i].ptr, 1, s_info.planes[i].size, fp); + } + } else { + ret = media_packet_get_buffer_data_ptr(pkt, &data); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get data ptr failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + ret = media_packet_get_buffer_size(pkt, &data_size); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get data size failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + g_print(" no tbm surface, data[%p], size[%"PRIu64"]\n", data, data_size); + + fwrite(data, 1, data_size, fp); + } + +_DUMP_MEDIA_PACKET_DATA_OUT: + if (fp) + fclose(fp); +} static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) { int ret = 0; int width = 0; int height = 0; - unsigned int i = 0; - char mp_dump_path[MAX_FILE_NAME_LENGTH] = {'\0',}; - FILE *fp = NULL; media_format_h fmt = NULL; media_format_mimetype_e type = MEDIA_FORMAT_I420; - tbm_surface_h surface = NULL; - tbm_surface_info_s s_info; if (!pkt) { g_print("\n[MP_PREVIEW_CB] NULL packet!\n"); @@ -651,45 +720,18 @@ static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) g_print("[MP_PREVIEW_CB] media_packet_preview_cb[mimetype:0x%x, %dx%d]\n", type, width, height); - ret = media_packet_get_tbm_surface(pkt, &surface); - if (ret != MEDIA_PACKET_ERROR_NONE) { - g_print("\n[MP_PREVIEW_CB] get tbm surface failed[0x%x] ====\n", ret); - goto _MEDIA_PACKET_PREVIEW_CB_OUT; - } - - ret = tbm_surface_get_info(surface, &s_info); - if (ret != TBM_SURFACE_ERROR_NONE) { - g_print("\n[MP_PREVIEW_CB] get tbm surface info failed[0x%x] ====\n", ret); - goto _MEDIA_PACKET_PREVIEW_CB_OUT; - } - - g_print(" tbm surface [%dx%d], total size[%u]\n", - s_info.width, s_info.height, s_info.size); - - if (g_camera_mp_preview_cb_dump) { - snprintf(mp_dump_path, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, MP_PREVIEW_CB_DUMP_FILE_NAME); - fp = fopen(mp_dump_path, "a"); - if (fp == NULL) { - g_print("\n[MP_PREVIEW_CB] file[%s] open failed ====\n", mp_dump_path); - goto _MEDIA_PACKET_PREVIEW_CB_OUT; - } - } - - for (i = 0 ; i < s_info.num_planes ; i++) { - g_print(" plane[%d][%p] stride[%u] size[%u]\n", - i, s_info.planes[i].ptr, s_info.planes[i].stride, s_info.planes[i].size); - if (fp) - fwrite(s_info.planes[i].ptr, 1, s_info.planes[i].size, fp); - } + if (g_camera_mp_preview_cb_dump) + _dump_media_packet_data(pkt, MP_PREVIEW_CB_DUMP_FILE_NAME); _MEDIA_PACKET_PREVIEW_CB_OUT: - if (fp) - fclose(fp); + if (fmt) { + media_format_unref(fmt); + fmt = NULL; + } media_packet_unref(pkt); } - static bool preview_resolution_cb(int width, int height, void *user_data) { resolution_stack *data = (resolution_stack *)user_data; diff --git a/test_headless/camera_test_headless.c b/test_headless/camera_test_headless.c index aa4ac0f..8695fc1 100644 --- a/test_headless/camera_test_headless.c +++ b/test_headless/camera_test_headless.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -598,19 +599,87 @@ static void _camera_extra_preview_cb(camera_preview_data_s *frame, int stream_id _dump_preview_data(frame, EXTRA_PREVIEW_CB_DUMP_FILE_NAME); } +static void _dump_media_packet_data(media_packet_h pkt, const char *file_name) +{ + int ret = 0; + unsigned int i = 0; + bool has_surface = false; + FILE *fp = NULL; + char dump_path[MAX_FILE_NAME_LENGTH] = {'\0',}; + tbm_surface_h surface = NULL; + tbm_surface_info_s s_info; + void *data = NULL; + uint64_t data_size = 0; + + if (!pkt) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] NULL packet\n"); + return; + } + + snprintf(dump_path, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, file_name); + fp = fopen(dump_path, "a"); + if (fp == NULL) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] file[%s] open failed ====\n", dump_path); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + ret = media_packet_has_tbm_surface_buffer(pkt, &has_surface); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] has tbm surface failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + if (has_surface) { + ret = media_packet_get_tbm_surface(pkt, &surface); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get tbm surface failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + ret = tbm_surface_get_info(surface, &s_info); + if (ret != TBM_SURFACE_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get tbm surface info failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + g_print(" tbm surface [%dx%d], total size[%u]\n", + s_info.width, s_info.height, s_info.size); + + for (i = 0 ; i < s_info.num_planes ; i++) { + g_print(" plane[%d][%p] stride[%u] size[%u]\n", + i, s_info.planes[i].ptr, s_info.planes[i].stride, s_info.planes[i].size); + fwrite(s_info.planes[i].ptr, 1, s_info.planes[i].size, fp); + } + } else { + ret = media_packet_get_buffer_data_ptr(pkt, &data); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get data ptr failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + ret = media_packet_get_buffer_size(pkt, &data_size); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_print("\n[DUMP_MEDIA_PACKET_DATA] get data size failed[0x%x] ====\n", ret); + goto _DUMP_MEDIA_PACKET_DATA_OUT; + } + + g_print(" no tbm surface, data[%p], size[%"PRIu64"]\n", data, data_size); + + fwrite(data, 1, data_size, fp); + } + +_DUMP_MEDIA_PACKET_DATA_OUT: + if (fp) + fclose(fp); +} static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) { int ret = 0; int width = 0; int height = 0; - unsigned int i = 0; - char mp_dump_path[MAX_FILE_NAME_LENGTH] = {'\0',}; - FILE *fp = NULL; media_format_h fmt = NULL; media_format_mimetype_e type = MEDIA_FORMAT_I420; - tbm_surface_h surface = NULL; - tbm_surface_info_s s_info; if (!pkt) { g_print("\n[MP_PREVIEW_CB] NULL packet!\n"); @@ -631,40 +700,14 @@ static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) g_print("[MP_PREVIEW_CB] media_packet_preview_cb[mimetype:0x%x, %dx%d]\n", type, width, height); - ret = media_packet_get_tbm_surface(pkt, &surface); - if (ret != MEDIA_PACKET_ERROR_NONE) { - g_print("\n[MP_PREVIEW_CB] get tbm surface failed[0x%x] ====\n", ret); - goto _MEDIA_PACKET_PREVIEW_CB_OUT; - } - - ret = tbm_surface_get_info(surface, &s_info); - if (ret != TBM_SURFACE_ERROR_NONE) { - g_print("\n[MP_PREVIEW_CB] get tbm surface info failed[0x%x] ====\n", ret); - goto _MEDIA_PACKET_PREVIEW_CB_OUT; - } - - g_print(" tbm surface [%dx%d], total size[%u]\n", - s_info.width, s_info.height, s_info.size); - - if (g_camera_mp_preview_cb_dump) { - snprintf(mp_dump_path, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, MP_PREVIEW_CB_DUMP_FILE_NAME); - fp = fopen(mp_dump_path, "a"); - if (fp == NULL) { - g_print("\n[MP_PREVIEW_CB] file[%s] open failed ====\n", mp_dump_path); - goto _MEDIA_PACKET_PREVIEW_CB_OUT; - } - } - - for (i = 0 ; i < s_info.num_planes ; i++) { - g_print(" plane[%d][%p] stride[%u] size[%u]\n", - i, s_info.planes[i].ptr, s_info.planes[i].stride, s_info.planes[i].size); - if (fp) - fwrite(s_info.planes[i].ptr, 1, s_info.planes[i].size, fp); - } + if (g_camera_mp_preview_cb_dump) + _dump_media_packet_data(pkt, MP_PREVIEW_CB_DUMP_FILE_NAME); _MEDIA_PACKET_PREVIEW_CB_OUT: - if (fp) - fclose(fp); + if (fmt) { + media_format_unref(fmt); + fmt = NULL; + } media_packet_unref(pkt); } -- 2.7.4