Support zero-copy with encoded format 23/273423/5 accepted/tizen/unified/20220428.162729 submit/tizen/20220427.095935
authorJeongmo Yang <jm80.yang@samsung.com>
Tue, 5 Apr 2022 12:10:42 +0000 (21:10 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Fri, 8 Apr 2022 00:52:56 +0000 (09:52 +0900)
[Version] 0.4.76
[Issue Type] New feature

Change-Id: Ibaee3a220365656f943907cc14d150e3e401ecd8
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/capi-media-camera.spec
src/camera.c
src/camera_internal.c
test/camera_test.c
test_headless/camera_test_headless.c

index 3947dec..66bd4ec 100644 (file)
@@ -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
index c3f50cc..787aff8 100644 (file)
@@ -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) {
index 6618838..9259298 100644 (file)
@@ -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:
index 98dfdbb..a60ef02 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include <glib.h>
 #include <sys/time.h>
 #include <dlog.h>
@@ -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;
index aa4ac0f..8695fc1 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include <glib.h>
 #include <sys/time.h>
 #include <dlog.h>
@@ -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);
 }