Change to resize image with mm_util_image_h
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_util.c
index cfcaa2d..5fb7c21 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <inttypes.h>
 #include <sys/vfs.h> /* struct statfs */
 #include <sys/time.h> /* gettimeofday */
 #include <sys/stat.h>
@@ -34,6 +35,7 @@
 #include "mm_camcorder_internal.h"
 #include "mm_camcorder_util.h"
 #include "mm_camcorder_sound.h"
+#include <mm_util_image.h>
 #include <mm_util_imgp.h>
 #include <mm_util_jpeg.h>
 
@@ -46,6 +48,8 @@
 -----------------------------------------------------------------------*/
 #define TIME_STRING_MAX_LEN                     64
 #define __MMCAMCORDER_CAPTURE_WAIT_TIMEOUT      5
+#define __MMCAMCORDER_MAX_WIDTH                 8192
+#define __MMCAMCORDER_MAX_HEIGHT                8192
 
 #define FPUTC_CHECK(x_char, x_file) \
 { \
@@ -75,9 +79,6 @@ static inline gboolean   write_tag(FILE *f, const gchar *tag);
 static inline gboolean   write_to_32(FILE *f, guint val);
 static inline gboolean   write_to_16(FILE *f, guint val);
 static inline gboolean   write_to_24(FILE *f, guint val);
-#ifdef _USE_YUV_TO_RGB888_
-static gboolean _mmcamcorder_convert_YUV_to_RGB888(unsigned char *src, int src_fmt, guint width, guint height, unsigned char **dst, unsigned int *dst_len);
-#endif /* _USE_YUV_TO_RGB888_ */
 static gboolean _mmcamcorder_convert_YUYV_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len);
 static gboolean _mmcamcorder_convert_UYVY_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len);
 static gboolean _mmcamcorder_convert_NV12_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len);
@@ -256,7 +257,7 @@ gint _mmcamcorder_find_tag(FILE *f, guint32 tag_fourcc, gboolean do_rewind)
                uint32_t buf_fourcc = 0;
 
                if (read_item < 8) {
-                       _mmcam_dbg_err("fread failed : %d", read_item);
+                       _mmcam_dbg_err("fread failed : %zu", read_item);
                        break;
                }
 
@@ -285,7 +286,7 @@ gint _mmcamcorder_find_tag(FILE *f, guint32 tag_fourcc, gboolean do_rewind)
                                buf_size = buf_size - 8; /* include tag */
                        }
 
-                       _mmcam_dbg_log("seek %llu", buf_size);
+                       _mmcam_dbg_log("seek %"PRIu64, buf_size);
                        if (fseeko(f, (off_t)buf_size, SEEK_CUR) != 0) {
                                _mmcam_dbg_err("fseeko() fail");
                                return FALSE;
@@ -311,7 +312,7 @@ gboolean _mmcamcorder_find_fourcc(FILE *f, guint32 tag_fourcc, gboolean do_rewin
                uint32_t buf_fourcc = 0;
 
                if (read_item < 8) {
-                       _mmcam_dbg_err("fread failed : %d", read_item);
+                       _mmcam_dbg_err("fread failed : %zu", read_item);
                        break;
                }
 
@@ -346,7 +347,7 @@ gboolean _mmcamcorder_find_fourcc(FILE *f, guint32 tag_fourcc, gboolean do_rewin
                                buf_size = buf_size - 8; /* include tag */
                        }
 
-                       _mmcam_dbg_log("seek %llu", buf_size);
+                       _mmcam_dbg_log("seek %"PRIu64, buf_size);
                        if (fseeko(f, (off_t)buf_size, SEEK_CUR) != 0) {
                                _mmcam_dbg_err("fseeko() fail");
                                return FALSE;
@@ -604,7 +605,7 @@ guint64 _mmcamcorder_get_container_size(const guchar *size)
        result = result | (temp << 8);
        result = result | size[3];
 
-       _mmcam_dbg_log("result : %llu", result);
+       _mmcam_dbg_log("result : %"G_GUINT64_FORMAT, result);
 
        return result;
 }
@@ -631,7 +632,7 @@ guint64 _mmcamcorder_get_container_size64(const guchar *size)
        result = result | (temp << 8);
        result = result | size[7];
 
-       _mmcam_dbg_log("result : %llu", result);
+       _mmcam_dbg_log("result : %"G_GUINT64_FORMAT, result);
 
        return result;
 }
@@ -765,7 +766,7 @@ int _mmcamcorder_get_freespace(storage_type_e type, guint64 *free_space)
        *free_space = vfs.f_bsize * vfs.f_bavail;
        /*
        _mmcam_dbg_log("vfs.f_bsize [%lu], vfs.f_bavail [%lu]", vfs.f_bsize, vfs.f_bavail);
-       _mmcam_dbg_log("memory size %llu [%s]", *free_space, path);
+       _mmcam_dbg_log("memory size %"G_GUINT64_FORMAT" [%s]", *free_space, path);
        */
        return 0;
 }
@@ -1216,6 +1217,7 @@ gboolean _mmcamcorder_msg_callback(void *data)
 
        /* remove item from msg data */
        if (hcamcorder->msg_data) {
+               /*_mmcam_dbg_log("remove item %p", item);*/
                hcamcorder->msg_data = g_list_remove(hcamcorder->msg_data, item);
        } else {
                _mmcam_dbg_warn("msg_data is NULL but item[%p] will be removed", item);
@@ -1276,7 +1278,6 @@ gboolean _mmcamcorder_send_message(MMHandleType handle, _MMCamcorderMsgItem *dat
 
        switch (data->id) {
        case MM_MESSAGE_CAMCORDER_STATE_CHANGED:
-       case MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM:
        case MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_RM:
                data->param.union_type = MM_MSG_UNION_STATE;
                break;
@@ -1336,16 +1337,16 @@ gboolean _mmcamcorder_send_message(MMHandleType handle, _MMCamcorderMsgItem *dat
                MMCamFaceDetectInfo *cam_fd_info = (MMCamFaceDetectInfo *)data->param.data;
                if (cam_fd_info) {
                        SAFE_G_FREE(cam_fd_info->face_info);
-                       SAFE_G_FREE(cam_fd_info);
-                       data->param.size = 0;
+                       data->param.data = NULL;
+                       g_free(cam_fd_info);
                }
        } else if (data->id == MM_MESSAGE_CAMCORDER_VIDEO_CAPTURED || data->id == MM_MESSAGE_CAMCORDER_AUDIO_CAPTURED) {
                MMCamRecordingReport *report = (MMCamRecordingReport *)data->param.data;
                if (report) {
                        SAFE_G_FREE(report->recording_filename);
                        data->param.data = NULL;
+                       g_free(report);
                }
-               SAFE_G_FREE(report);
        }
 #endif /* _MMCAMCORDER_ENABLE_IDLE_MESSAGE_CALLBACK */
 
@@ -1547,6 +1548,12 @@ unsigned int _mmcamcorder_get_fourcc(int pixtype, int codectype, int use_zero_co
        case MM_PIXEL_FORMAT_RGB888:
                fourcc = GST_MAKE_FOURCC('R', 'G', 'B', ' ');
                break;
+       case MM_PIXEL_FORMAT_RGBA:
+               fourcc = GST_MAKE_FOURCC('B', 'G', 'R', 'x');
+               break;
+       case MM_PIXEL_FORMAT_ARGB:
+               fourcc = GST_MAKE_FOURCC('x', 'R', 'G', 'B');
+               break;
        case MM_PIXEL_FORMAT_ENCODED:
                if (codectype == MM_IMAGE_CODEC_JPEG) {
                        fourcc = GST_MAKE_FOURCC('J', 'P', 'E', 'G');
@@ -1567,6 +1574,9 @@ unsigned int _mmcamcorder_get_fourcc(int pixtype, int codectype, int use_zero_co
        case MM_PIXEL_FORMAT_ENCODED_H264:
                fourcc = GST_MAKE_FOURCC('H', '2', '6', '4');
                break;
+       case MM_PIXEL_FORMAT_INVZ:
+               fourcc = GST_MAKE_FOURCC('I', 'N', 'V', 'Z');
+               break;
        default:
                _mmcam_dbg_log("Not proper pixel type[%d]. Set default - I420", pixtype);
                if (use_zero_copy_format)
@@ -1645,6 +1655,9 @@ int _mmcamcorder_get_pixtype(unsigned int fourcc)
        case GST_MAKE_FOURCC('H', '2', '6', '4'):
                pixtype = MM_PIXEL_FORMAT_ENCODED_H264;
                break;
+       case GST_MAKE_FOURCC('I', 'N', 'V', 'Z'):
+               pixtype = MM_PIXEL_FORMAT_INVZ;
+               break;
        default:
                _mmcam_dbg_log("Not supported fourcc type(%c%c%c%c)", fourcc, fourcc>>8, fourcc>>16, fourcc>>24);
                pixtype = MM_PIXEL_FORMAT_INVALID;
@@ -1716,71 +1729,69 @@ gboolean _mmcamcorder_link_elements(GList *element_list)
 }
 
 gboolean _mmcamcorder_resize_frame(unsigned char *src_data, unsigned int src_width, unsigned int src_height, unsigned int src_length, int src_format,
-       unsigned char **dst_data, unsigned int *dst_width, unsigned int *dst_height, unsigned int *dst_length)
+       unsigned char **dst_data, unsigned int *dst_width, unsigned int *dst_height, size_t *dst_length)
 {
        int ret = TRUE;
        int mm_ret = MM_ERROR_NONE;
-       int input_format = MM_UTIL_IMG_FMT_YUV420;
-       unsigned char *dst_tmp_data = NULL;
+       int input_format = MM_UTIL_COLOR_YUV420;
+       mm_util_image_h src_image = NULL;
+       mm_util_image_h dst_image = NULL;
 
        if (!src_data || !dst_data || !dst_width || !dst_height || !dst_length) {
-               _mmcam_dbg_err("something is NULL %p,%p,%p,%p,%p", src_data, dst_data, dst_width, dst_height, dst_length);
+               _mmcam_dbg_err("something is NULL %p,%p,%p,%p,%p",
+                       src_data, dst_data, dst_width, dst_height, dst_length);
                return FALSE;
        }
 
        /* set input format for mm-util */
        switch (src_format) {
        case MM_PIXEL_FORMAT_I420:
-               input_format = MM_UTIL_IMG_FMT_I420;
+               input_format = MM_UTIL_COLOR_I420;
                break;
        case MM_PIXEL_FORMAT_YV12:
-               input_format = MM_UTIL_IMG_FMT_YUV420;
+               input_format = MM_UTIL_COLOR_YUV420;
                break;
        case MM_PIXEL_FORMAT_NV12:
-               input_format = MM_UTIL_IMG_FMT_NV12;
+               input_format = MM_UTIL_COLOR_NV12;
                break;
        case MM_PIXEL_FORMAT_YUYV:
-               input_format = MM_UTIL_IMG_FMT_YUYV;
+               input_format = MM_UTIL_COLOR_YUYV;
                break;
        case MM_PIXEL_FORMAT_UYVY:
-               input_format = MM_UTIL_IMG_FMT_UYVY;
+               input_format = MM_UTIL_COLOR_UYVY;
                break;
        case MM_PIXEL_FORMAT_RGB888:
-               input_format = MM_UTIL_IMG_FMT_RGB888;
+               input_format = MM_UTIL_COLOR_RGB24;
                break;
        default:
-               _mmcam_dbg_err("NOT supported format", src_format);
+               _mmcam_dbg_err("NOT supported format [%d]", src_format);
                return FALSE;
        }
 
        _mmcam_dbg_log("src size %dx%d -> dst size %dx%d", src_width, src_height, *dst_width, *dst_height);
 
-       /* get length of resized image */
-       mm_ret = mm_util_get_image_size(input_format, *dst_width, *dst_height, dst_length);
+       mm_ret = mm_image_create_image(src_width, src_height, input_format, src_data, (size_t)src_length, &src_image);
        if (mm_ret != MM_ERROR_NONE) {
-               GST_ERROR("mm_util_get_image_size failed 0x%x", ret);
+               GST_ERROR("mm_image_create_image failed 0x%x", ret);
                return FALSE;
        }
 
-       _mmcam_dbg_log("dst_length : %d", *dst_length);
-
-       dst_tmp_data = (unsigned char *)malloc(*dst_length);
-       if (dst_tmp_data == NULL) {
-               _mmcam_dbg_err("failed to alloc dst_thumb_size(size %d)", *dst_length);
+       mm_ret = mm_util_resize_image(src_image, *dst_width, *dst_height, &dst_image);
+       mm_image_destroy_image(src_image);
+       if (mm_ret != MM_ERROR_NONE) {
+               GST_ERROR("mm_util_resize_image failed 0x%x", ret);
                return FALSE;
        }
 
-       mm_ret = mm_util_resize_image(src_data, src_width, src_height, input_format, dst_tmp_data, dst_width, dst_height);
-
+       mm_ret = mm_image_get_image(dst_image, dst_width, dst_height, NULL, dst_data, dst_length);
+       mm_image_destroy_image(dst_image);
        if (mm_ret != MM_ERROR_NONE) {
-               GST_ERROR("mm_util_resize_image failed 0x%x", ret);
-               free(dst_tmp_data);
+               GST_ERROR("mm_image_get_image failed 0x%x", ret);
                return FALSE;
        }
 
-       *dst_data = dst_tmp_data;
-
-       _mmcam_dbg_log("resize done %p, %dx%d", *dst_data, *dst_width, *dst_height);
+       _mmcam_dbg_log("resize done %dx%d -> %dx%d, %p, length %zu",
+               src_width, src_height, *dst_width, *dst_height, *dst_data, *dst_length);
 
        return TRUE;
 }
@@ -1800,46 +1811,46 @@ gboolean _mmcamcorder_encode_jpeg(void *src_data, unsigned int src_width, unsign
 
        switch (src_format) {
        case MM_PIXEL_FORMAT_NV12:
-               //jpeg_format = MM_UTIL_JPEG_FMT_NV12;
+               //jpeg_format = MM_UTIL_COLOR_NV12;
                ret_conv = _mmcamcorder_convert_NV12_to_I420(src_data, src_width, src_height, &converted_src, &converted_src_size);
-               jpeg_format = MM_UTIL_JPEG_FMT_YUV420;
+               jpeg_format = MM_UTIL_COLOR_YUV420;
                break;
        case MM_PIXEL_FORMAT_NV16:
-               jpeg_format = MM_UTIL_JPEG_FMT_NV16;
+               jpeg_format = MM_UTIL_COLOR_NV16;
                converted_src = src_data;
                break;
        case MM_PIXEL_FORMAT_NV21:
-               jpeg_format = MM_UTIL_JPEG_FMT_NV21;
+               jpeg_format = MM_UTIL_COLOR_NV21;
                converted_src = src_data;
                break;
        case MM_PIXEL_FORMAT_YUYV:
-               //jpeg_format = MM_UTIL_JPEG_FMT_YUYV;
+               //jpeg_format = MM_UTIL_COLOR_YUYV;
                ret_conv = _mmcamcorder_convert_YUYV_to_I420(src_data, src_width, src_height, &converted_src, &converted_src_size);
-               jpeg_format = MM_UTIL_JPEG_FMT_YUV420;
+               jpeg_format = MM_UTIL_COLOR_YUV420;
                break;
        case MM_PIXEL_FORMAT_UYVY:
-               //jpeg_format = MM_UTIL_JPEG_FMT_UYVY;
+               //jpeg_format = MM_UTIL_COLOR_UYVY;
                ret_conv = _mmcamcorder_convert_UYVY_to_I420(src_data, src_width, src_height, &converted_src, &converted_src_size);
-               jpeg_format = MM_UTIL_JPEG_FMT_YUV420;
+               jpeg_format = MM_UTIL_COLOR_YUV420;
                break;
        case MM_PIXEL_FORMAT_I420:
-               jpeg_format = MM_UTIL_JPEG_FMT_YUV420;
+               jpeg_format = MM_UTIL_COLOR_YUV420;
                converted_src = src_data;
                break;
        case MM_PIXEL_FORMAT_RGB888:
-               jpeg_format = MM_UTIL_JPEG_FMT_RGB888;
+               jpeg_format = MM_UTIL_COLOR_RGB24;
                converted_src = src_data;
                break;
        case MM_PIXEL_FORMAT_RGBA:
-               jpeg_format = MM_UTIL_JPEG_FMT_RGBA8888;
+               jpeg_format = MM_UTIL_COLOR_RGBA;
                converted_src = src_data;
                break;
        case MM_PIXEL_FORMAT_ARGB:
-               jpeg_format = MM_UTIL_JPEG_FMT_ARGB8888;
+               jpeg_format = MM_UTIL_COLOR_ARGB;
                converted_src = src_data;
                break;
        case MM_PIXEL_FORMAT_422P:
-               jpeg_format = MM_UTIL_JPEG_FMT_YUV422;  // not supported
+               jpeg_format = MM_UTIL_COLOR_YUV422;     // not supported
                return FALSE;
        case MM_PIXEL_FORMAT_NV12T:
        case MM_PIXEL_FORMAT_YV12:
@@ -1860,7 +1871,7 @@ gboolean _mmcamcorder_encode_jpeg(void *src_data, unsigned int src_width, unsign
                return FALSE;
        }
 
-       ret = mm_util_jpeg_encode_to_memory(result_data, (int *)result_length,
+       ret = mm_util_jpeg_encode_to_memory(result_data, result_length,
                converted_src, src_width, src_height, jpeg_format, jpeg_quality);
 
        if (converted_src && (converted_src != src_data)) {
@@ -2058,56 +2069,6 @@ void *_mmcamcorder_util_task_thread_func(void *data)
        return NULL;
 }
 
-#ifdef _USE_YUV_TO_RGB888_
-static gboolean
-_mmcamcorder_convert_YUV_to_RGB888(unsigned char *src, int src_fmt, guint width, guint height, unsigned char **dst, unsigned int *dst_len)
-{
-       int ret = 0;
-       int src_cs = MM_UTIL_IMG_FMT_UYVY;
-       int dst_cs = MM_UTIL_IMG_FMT_RGB888;
-       unsigned int dst_size = 0;
-
-       if (src_fmt == COLOR_FORMAT_YUYV) {
-               _mmcam_dbg_log("Convert YUYV to RGB888\n");
-               src_cs = MM_UTIL_IMG_FMT_YUYV;
-       } else if (src_fmt == COLOR_FORMAT_UYVY) {
-               _mmcam_dbg_log("Convert UYVY to RGB888\n");
-               src_cs = MM_UTIL_IMG_FMT_UYVY;
-       } else if (src_fmt == COLOR_FORMAT_NV12) {
-               _mmcam_dbg_log("Convert NV12 to RGB888\n");
-               src_cs = MM_UTIL_IMG_FMT_NV12;
-       } else {
-               _mmcam_dbg_err("NOT supported format [%d]\n", src_fmt);
-               return FALSE;
-       }
-
-       ret = mm_util_get_image_size(dst_cs, width, height, &dst_size);
-       if (ret != 0) {
-               _mmcam_dbg_err("mm_util_get_image_size failed [%x]\n", ret);
-               return FALSE;
-       }
-
-       *dst = malloc(dst_size);
-       if (*dst == NULL) {
-               _mmcam_dbg_err("malloc failed\n");
-               return FALSE;
-       }
-
-       *dst_len = dst_size;
-       ret = mm_util_convert_colorspace(src, width, height, src_cs, *dst, dst_cs);
-       if (ret == 0) {
-               _mmcam_dbg_log("Convert [dst_size:%d] OK.\n", dst_size);
-               return TRUE;
-       } else {
-               free(*dst);
-               *dst = NULL;
-
-               _mmcam_dbg_err("Convert [size:%d] FAILED.\n", dst_size);
-               return FALSE;
-       }
-}
-#endif /* _USE_YUV_TO_RGB888_ */
-
 
 static gboolean _mmcamcorder_convert_YUYV_to_I420(unsigned char *src, guint width, guint height, unsigned char **dst, unsigned int *dst_len)
 {
@@ -2239,6 +2200,12 @@ static gboolean _mmcamcorder_convert_NV12_to_I420(unsigned char *src, guint widt
                return FALSE;
        }
 
+       /* buffer overflow prevention check */
+       if (width > __MMCAMCORDER_MAX_WIDTH || height > __MMCAMCORDER_MAX_HEIGHT) {
+               _mmcam_dbg_err("too large size %d x %d", width, height);
+               return FALSE;
+       }
+
        dst_size = (width * height * 3) >> 1;
 
        _mmcam_dbg_log("NV12 -> I420 : %dx%d, dst size %d", width, height, dst_size);