From: Jiyong Date: Fri, 8 Dec 2023 08:19:30 +0000 (+0900) Subject: [ACR-1815] Add image_util_create_image_from_media_packet() X-Git-Tag: accepted/tizen/unified/20240129.163411^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32c6666469b97384cf035eb3933709ef99fc8755;p=platform%2Fcore%2Fapi%2Fimage-util.git [ACR-1815] Add image_util_create_image_from_media_packet() Change-Id: I4439958c2f4d79bc3ab309de35abcf97477f7577 --- diff --git a/include/image_util.h b/include/image_util.h index d55c4a3..b7f6f4c 100644 --- a/include/image_util.h +++ b/include/image_util.h @@ -465,6 +465,28 @@ int image_util_transform_destroy(transformation_h handle); */ int image_util_create_image(unsigned int width, unsigned int height, image_util_colorspace_e colorspace, const unsigned char *data, size_t data_size, image_util_image_h *image); +/** +* @brief Creates an image handle from media packet. +* @since_tizen 7.0 +* +* @remarks The @a image should be released using image_util_destroy_image(). +* +* @param[in] media_packet The media_packet +* @param[out] image A handle of image +* +* @return @c 0 on success, +* otherwise a negative error value +* +* @retval #IMAGE_UTIL_ERROR_NONE Successful +* @retval #IMAGE_UTIL_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #IMAGE_UTIL_ERROR_OUT_OF_MEMORY Out of memory +* +* @see image_util_destroy_image() +* @see image_util_get_image() +* @see image_util_clone_image() +*/ +int image_util_create_image_from_media_packet(media_packet_h media_packet, image_util_image_h *image); + /** * @brief Clones an image handle. * @since_tizen 5.5 diff --git a/packaging/capi-media-image-util.spec b/packaging/capi-media-image-util.spec index 50b25f2..36e0821 100644 --- a/packaging/capi-media-image-util.spec +++ b/packaging/capi-media-image-util.spec @@ -1,6 +1,6 @@ Name: capi-media-image-util Summary: A Image Utility library in Tizen Native API -Version: 0.4.3 +Version: 0.4.4 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/image_util.c b/src/image_util.c index 0ea1c4c..2eca6bc 100644 --- a/src/image_util.c +++ b/src/image_util.c @@ -465,6 +465,11 @@ int image_util_create_image(unsigned int width, unsigned int height, image_util_ return _image_error_capi(ret); } +int image_util_create_image_from_media_packet(media_packet_h media_packet, image_util_image_h *image) +{ + return _image_util_packet_to_image(media_packet, image); +} + int image_util_clone_image(image_util_image_h src, image_util_image_h *dst) { int ret = IMAGE_UTIL_ERROR_NONE; diff --git a/src/image_util_private.c b/src/image_util_private.c index 53171a5..21c93f3 100644 --- a/src/image_util_private.c +++ b/src/image_util_private.c @@ -494,6 +494,238 @@ ERROR: return IMAGE_UTIL_ERROR_INVALID_OPERATION; } +static int __get_video_info_from_packet(media_packet_h packet, int *width, int *height, mm_util_color_format_e *color_format, uint32_t *plane_num) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + media_format_h fmt = NULL; + media_format_mimetype_e mimetype = 0; + + ret = media_packet_get_format(packet, &fmt); + image_util_retvm_if((ret != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, + "media_packet_get_format failed (%d)", ret); + + ret = media_format_get_video_info(fmt, &mimetype, width, height, NULL, NULL); + media_format_unref(fmt); + if (ret != MEDIA_FORMAT_ERROR_NONE) { + image_util_error("media_packet_get_format failed (%d)", ret); + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + } + + ret = media_packet_get_number_of_video_planes(packet, plane_num); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("media_packet_get_number_of_video_plances failed (%d)", ret); + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + } + + *color_format = __mimetype_to_image_format(mimetype); + + image_util_debug("width: %d, hiehgt: %d, color_format: %d, plane_num: %u", *width, *height, *color_format, *plane_num); + + return IMAGE_UTIL_ERROR_NONE; +} + +static int __get_video_plane_from_packet(media_packet_h packet, int plane_index, int *stride_width, int *stride_height, void **data_ptr) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + + if (stride_width) { + ret = media_packet_get_video_stride_width(packet, plane_index, stride_width); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("media_packet_get_video_stride_width failed (%d)", ret); + return ret; + } + } + + if (stride_height) { + ret = media_packet_get_video_stride_height(packet, plane_index, stride_height); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("media_packet_get_video_stride_height failed (%d)", ret); + return ret; + } + } + + if (data_ptr) { + ret = media_packet_get_video_plane_data_ptr(packet, plane_index, data_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("media_packet_get_video_plane_data_ptr failed (%d)", ret); + return ret; + } + } + + image_util_debug("stride_width: %d, stride_height: %d, data_ptr: %p", + stride_width ? *stride_width : 0, stride_height ? *stride_height : 0, + data_ptr ? *data_ptr : NULL); + + return MEDIA_PACKET_ERROR_NONE; +} + +static int __get_video_data_from_420p(media_packet_h packet, uint32_t plane_num, int width, int height, void **data, size_t *size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + int i = 0; + int stride_width = 0; + int uv_width = width / 2, uv_height = height / 2; + void *src_ptr = NULL; + size_t dst_size = (width * height * 3) >> 1; + void *dst_data = NULL; + void *dst_ptr = NULL; + + image_util_retvm_if(plane_num != 3, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid plane_num"); + image_util_retvm_if(width <= 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width"); + image_util_retvm_if(height <= 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid height"); + image_util_retvm_if(!data, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid data"); + image_util_retvm_if(size == 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid size"); + + image_util_debug("width: %d, height: %d, size: %zu", width, height, dst_size); + + dst_data = g_malloc0(dst_size); + dst_ptr = dst_data; + + // y data + ret = __get_video_plane_from_packet(packet, 0, &stride_width, NULL, &src_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("__get_videodst_data_from_packet failed (%d)", ret); + goto ERROR; + } + + for (i = 0; i < height; i++) { + memcpy(dst_ptr, src_ptr, width); + dst_ptr += width; + src_ptr += stride_width; + } + + // u data + ret = __get_video_plane_from_packet(packet, 1, &stride_width, NULL, &src_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("__get_videodst_data_from_packet failed (%d)", ret); + goto ERROR; + } + + for (i = 0; i < uv_height; i++) { + memcpy(dst_ptr, src_ptr, uv_width); + dst_ptr += uv_width; + src_ptr += stride_width; + } + + // v data + ret = __get_video_plane_from_packet(packet, 2, &stride_width, NULL, &src_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("__get_videodst_data_from_packet failed (%d)", ret); + goto ERROR; + } + + for (i = 0; i < uv_height; i++) { + memcpy(dst_ptr, src_ptr, uv_width); + dst_ptr += uv_width; + src_ptr += stride_width; + } + + *data = dst_data; + *size = dst_size; + + return IMAGE_UTIL_ERROR_NONE; + +ERROR: + g_free(dst_data); + return IMAGE_UTIL_ERROR_INVALID_OPERATION; +} + +static int __get_video_data_from_420sp(media_packet_h packet, uint32_t plane_num, int width, int height, void **data, size_t *size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + int i = 0; + int stride_width = 0; + int uv_height = height / 2; + void *src_ptr = NULL; + size_t dst_size = (width * height * 3) >> 1; + void *dst_data = NULL; + void *dst_ptr = NULL; + + image_util_retvm_if(plane_num != 2, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid plane_num"); + image_util_retvm_if(width <= 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width"); + image_util_retvm_if(height <= 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid height"); + image_util_retvm_if(!data, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid data"); + image_util_retvm_if(size == 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid size"); + + image_util_debug("width: %d, height: %d, size: %zu", width, height, dst_size); + + dst_data = g_malloc0(dst_size); + dst_ptr = dst_data; + + // y data + ret = __get_video_plane_from_packet(packet, 0, &stride_width, NULL, &src_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("__get_video_data_from_packet failed (%d)", ret); + goto ERROR; + } + + for (i = 0; i < height; i++) { + memcpy(dst_ptr, src_ptr, width); + dst_ptr += width; + src_ptr += stride_width; + } + + // uv data + ret = __get_video_plane_from_packet(packet, 1, &stride_width, NULL, &src_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("__get_video_data_from_packet failed (%d)", ret); + goto ERROR; + } + + for (i = 0; i < uv_height; i++) { + memcpy(dst_ptr, src_ptr, width); + dst_ptr += width; + src_ptr += stride_width; + } + + *data = dst_data; + *size = dst_size; + + return IMAGE_UTIL_ERROR_NONE; + +ERROR: + g_free(dst_data); + return IMAGE_UTIL_ERROR_INVALID_OPERATION; +} + +static int __get_video_data_from_packet(media_packet_h packet, uint32_t plane_num, void **data, size_t *size) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + unsigned int i = 0; + int stride_width = 0, stride_height = 0; + void *src_ptr = NULL; + size_t src_size = 0; + size_t dst_size = 0; + void *dst_data = NULL; + + image_util_retvm_if(plane_num == 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid plane_num"); + image_util_retvm_if(!data, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid data"); + image_util_retvm_if(size == 0, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid size"); + + for (i = 0; i < plane_num; i++) { + ret = __get_video_plane_from_packet(packet, i, &stride_width, &stride_height, &src_ptr); + if (ret != MEDIA_PACKET_ERROR_NONE) { + image_util_error("__get_video_data_from_packet failed (%d)", ret); + goto ERROR; + } + + src_size = (size_t)(stride_width) * stride_height; + dst_data = g_realloc(dst_data, dst_size + src_size); + + memcpy(dst_data + dst_size, src_ptr, src_size); + dst_size += src_size; + } + + *data = dst_data; + *size = dst_size; + + return IMAGE_UTIL_ERROR_NONE; + +ERROR: + g_free(dst_data); + return IMAGE_UTIL_ERROR_INVALID_OPERATION; +} + int _image_util_image_to_packet(image_util_image_h image, media_packet_h *packet) { int ret = IMAGE_UTIL_ERROR_NONE; @@ -535,15 +767,10 @@ int _image_util_image_to_packet(image_util_image_h image, media_packet_h *packet int _image_util_packet_to_image(media_packet_h packet, image_util_image_h *image) { int ret = IMAGE_UTIL_ERROR_NONE; - media_format_mimetype_e mimetype = 0; int width = 0, height = 0; - media_format_h fmt = NULL; - unsigned int i = 0; + mm_util_color_format_e color_format; uint32_t plane_num = 0; - int stride_width = 0, stride_height = 0; - void *plane_ptr = NULL; - size_t plane_size = 0; - void *ptr = NULL; + void *data = NULL; size_t size = 0; image_util_fenter(); @@ -551,68 +778,45 @@ int _image_util_packet_to_image(media_packet_h packet, image_util_image_h *image image_util_retvm_if(!packet, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid packet"); image_util_retvm_if(!image, IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid image"); - ret = media_packet_get_format(packet, &fmt); - image_util_retvm_if((ret != MEDIA_PACKET_ERROR_NONE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "media_packet_get_format failed (%d)", ret); - - ret = media_format_get_video_info(fmt, &mimetype, &width, &height, NULL, NULL); - if (ret != MEDIA_FORMAT_ERROR_NONE) { - image_util_error("media_packet_get_format failed (%d)", ret); - media_format_unref(fmt); - return IMAGE_UTIL_ERROR_INVALID_PARAMETER; + ret = __get_video_info_from_packet(packet, &width, &height, &color_format, &plane_num); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_error("__get_video_info_from_packet failed (%d)", ret); + return ret; } - media_format_unref(fmt); - ret = media_packet_get_number_of_video_planes(packet, &plane_num); - if (ret != MEDIA_PACKET_ERROR_NONE) { - image_util_error("media_packet_get_number_of_video_plances failed (%d)", ret); - goto ERROR; + if (width <= 0 || height <= 0 || color_format == MM_UTIL_COLOR_NUM) { + image_util_error("invalid image width: %d height: %d color_format: %d", width, height, color_format); + return IMAGE_UTIL_ERROR_INVALID_PARAMETER; } - image_util_debug("plane_num: %u", plane_num); - - for (i = 0; i < plane_num; i++) { - ret = media_packet_get_video_stride_width(packet, i, &stride_width); - if (ret != MEDIA_PACKET_ERROR_NONE) { - image_util_error("media_packet_get_video_stride_width failed (%d)", ret); - goto ERROR; + if ((color_format == MM_UTIL_COLOR_YUV420 || color_format == MM_UTIL_COLOR_I420) && (plane_num == 3)) { + ret = __get_video_data_from_420p(packet, plane_num, width, height, &data, &size); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_error("__get_video_data_from_i420 failed (%d)", ret); + return ret; } - - ret = media_packet_get_video_stride_height(packet, i, &stride_height); - if (ret != MEDIA_PACKET_ERROR_NONE) { - image_util_error("media_packet_get_video_stride_height failed (%d)", ret); - goto ERROR; + } else if ((color_format == MM_UTIL_COLOR_NV12) && (plane_num == 2)) { + ret = __get_video_data_from_420sp(packet, plane_num, width, height, &data, &size); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_error("__get_video_data_from_nv12 failed (%d)", ret); + return ret; } - - plane_size = (size_t)(stride_width) * stride_height; - - ret = media_packet_get_video_plane_data_ptr(packet, i, &plane_ptr); - if (ret != MEDIA_PACKET_ERROR_NONE) { - image_util_error("media_packet_get_video_plane_data_ptr failed (%d)", ret); - goto ERROR; + } else { + ret = __get_video_data_from_packet(packet, plane_num, &data, &size); + if (ret != IMAGE_UTIL_ERROR_NONE) { + image_util_error("__get_video_data_from_packet failed (%d)", ret); + return ret; } - - image_util_debug("stride_width: %d, stride_height: %d, plane_ptr: %p, plane_size: %zu", - stride_width, stride_height, plane_ptr,plane_size); - - ptr = g_realloc(ptr, size + plane_size); - - memcpy(ptr + size, plane_ptr, plane_size); - size += plane_size; } - image_util_debug("[Fotmat: %u] W x H : %d x %d buffer(size) : %p(%zu)", mimetype, width, height, ptr, size); + image_util_debug("w: %d h: %d format: %u buffer: %p size: %zu", width, height, color_format, data, size); - ret = mm_image_create_image(width, height, __mimetype_to_image_format(mimetype), ptr, size, image); - g_free(ptr); - image_util_retvm_if((ret != IMAGE_UTIL_ERROR_NONE), ret, "mm_image_create_image failed (%d)", ret); + ret = mm_image_create_image2((unsigned int)(width), (unsigned int)(height), color_format, data, size, image); + image_util_retvm_if((ret != IMAGE_UTIL_ERROR_NONE), ret, "mm_image_create_image2 failed (%d)", ret); image_util_fleave(); return IMAGE_UTIL_ERROR_NONE; - -ERROR: - g_free(ptr); - return IMAGE_UTIL_ERROR_INVALID_OPERATION; } int _check_colorspace(image_util_type_e image_type, image_util_colorspace_e colorspace)