[ACR-1619] Add media packet referencing APIs 25/253025/18 accepted/tizen/unified/20210312.142521 submit/tizen/20210311.030610
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 4 Feb 2021 03:20:59 +0000 (12:20 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 8 Mar 2021 10:50:49 +0000 (19:50 +0900)
[Version] 0.1.34
[Issue Type] New feature

Change-Id: Icdb1c28b14cbbeb59055213650bd4931bac0db1c
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
include/media_packet.h
include/media_packet_private.h
packaging/capi-media-tool.spec
src/media_packet.c
test/media_packet_test.c

index 209af2c5c972f78f26ba7e428812bb094260a5f3..bd4fb7a2fe393e5c16515ad167fedf175182c2bc 100644 (file)
@@ -69,6 +69,7 @@ typedef enum {
 } media_buffer_flags_e;
 
 /**
+ * @deprecated Deprecated since 6.5.
  * @brief Enumeration for the return values of media packet finalize call back functions.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @see media_packet_finalize_cb()
@@ -92,6 +93,7 @@ typedef enum {
 } media_packet_rotate_method_e;
 
 /**
+ * @deprecated Deprecated since 6.5.
  * @brief   Called when the media packet is destroyed.
  * @details It will be invoked when media_packet_destroy() is called.
  *
@@ -112,6 +114,25 @@ typedef enum {
 typedef int (*media_packet_finalize_cb) (media_packet_h packet, int error_code, void *user_data);
 
 /**
+ * @brief   Called when the media packet is disposed.
+ * @details It will be invoked when media_packet_unref() is called, \n
+ *          and reference count is decreased to 0.
+ * @since_tizen 6.5
+ * @remarks The media packet handle should not be released in this callback. \n
+ *          It will be released by the framework after return.
+ * @param[in] packet    The media packet handle
+ * @param[in] user_data The user data passed from the callback registration function
+ * @pre It will be invoked when media packet is being destroyed.
+ * @see media_packet_unref()
+ * @see media_packet_new()
+ * @see media_packet_new_alloc()
+ * @see media_packet_new_from_tbm_surface()
+ * @see media_packet_new_from_external_memory()
+ */
+typedef void (*media_packet_dispose_cb)(media_packet_h packet, void *user_data);
+
+/**
+ * @deprecated Deprecated since 6.5. Use media_packet_new_alloc() instead.
  * @brief    Creates a media packet handle and allocates buffer.
  * @details  The buffer will be allocated to heap or tbm_surface.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
@@ -164,9 +185,10 @@ typedef int (*media_packet_finalize_cb) (media_packet_h packet, int error_code,
 
    @endcode
  */
-int media_packet_create_alloc(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet);
+int media_packet_create_alloc(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet) TIZEN_DEPRECATED_API;
 
 /**
+ * @deprecated Deprecated since 6.5. Use media_packet_new() instead.
  * @brief    Creates a media packet handle.
  * @details  It creates only media packet handle without allocated buffer.
  *
@@ -221,15 +243,143 @@ int media_packet_create_alloc(media_format_h fmt, media_packet_finalize_cb fcb,
 
    @endcode
  */
-int media_packet_create(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet);
+int media_packet_create(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet) TIZEN_DEPRECATED_API;
+
+/**
+ * @brief Creates a media packet handle.
+ * @details It creates only media packet handle without allocated buffer.
+ * @since_tizen 6.5
+ * @remarks The @c packet must be released by using media_packet_unref().
+ * @param[in] fmt      The #media_format_h allocated by the caller
+ * @param[in] dcb      The media_packet_dispose_cb() to register. Use @c NULL to skip the callback.
+ * @param[in] dcb_data The user data to be passed to the media_packet_dispose_cb() function
+ * @param[out] packet  A new handle for media packet
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_PACKET_ERROR_NONE              Successful
+ * @retval #MEDIA_PACKET_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_PACKET_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Must have media_format_h instance by media_format_create()
+ * @post Must call media_format_unref()
+ * @see media_packet_ref()
+ * @see media_packet_unref()
+ * @see media_packet_dispose_cb()
+ */
+int media_packet_new(media_format_h fmt, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet);
+
+/**
+ * @brief Creates a media packet handle and allocates buffer.
+ * @details The buffer will be allocated to heap or tbm_surface.
+ * @since_tizen 6.5
+ * @remarks The @a packet should be released using media_packet_unref().
+ * @param[in]  fmt      The allocated #media_format_h by caller
+ * @param[in]  dcb      The media_packet_dispose_cb() to register. Use @c NULL to skip the callback.
+ * @param[in]  dcb_data The user data to be passed to the media_packet_dispose_cb() function
+ * @param[out] packet   A new handle for media packet
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_PACKET_ERROR_NONE              Successful
+ * @retval #MEDIA_PACKET_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_PACKET_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Must have media_format_h instance by media_format_create()
+ * @post Must do media_format_unref()
+ * @see media_packet_ref()
+ * @see media_packet_unref()
+ * @see media_packet_dispose_cb()
+ */
+int media_packet_new_alloc(media_format_h fmt, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet);
+
+/**
+ * @brief Creates media packet handle and allocates buffer with #tbm_surface_h.
+ * @since_tizen 6.5
+ * @remarks The @c packet must be released by using media_packet_unref().
+ * @param[in]  fmt      The #media_format_h allocated by caller
+ * @param[in]  surface  The #tbm_surface_h by caller
+ * @param[in]  dcb      The media_packet_dispose_cb() to register. Use @c NULL to skip the callback.
+ * @param[in]  dcb_data The user data to be passed to the media_packet_dispose_cb() function
+ * @param[out] packet   A new handle for media packet
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_PACKET_ERROR_NONE              Successful
+ * @retval #MEDIA_PACKET_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_PACKET_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Must have media_format_h instance by media_format_create()
+ * @post Must do media_format_unref()
+ * @see media_packet_ref()
+ * @see media_packet_unref()
+ * @see media_packet_dispose_cb()
+ */
+int media_packet_new_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet);
+
+/**
+ * @brief Creates media packet handle with already allocated buffer.
+ * @details It does not support video's #MEDIA_FORMAT_RAW type.
+ * @since_tizen 6.5
+ * @remarks The @c packet must be released by using media_packet_unref().
+ * @param[in]  fmt      The allocated #media_format_h by caller
+ * @param[in]  mem_ptr  The memory pointer which is created by external module
+ * @param[in]  size     The buffer size value to set
+ * @param[in]  dcb      The media_packet_dispose_cb() to register. Use @c NULL to skip the callback.
+ * @param[in]  dcb_data The user data to be passed to the media_packet_dispose_cb() function
+ * @param[out] packet   A new handle for media packet
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_PACKET_ERROR_NONE              Successful
+ * @retval #MEDIA_PACKET_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_PACKET_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
+ * @pre Must have media_format_h instance by media_format_create()
+ * @post Must do media_format_unref()
+ * @see media_packet_ref()
+ * @see media_packet_unref()
+ * @see media_packet_dispose_cb()
+ * @see media_format_unref()
+ */
+int media_packet_new_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet);
+
+/**
+ * @brief Increases reference count of a media packet handle.
+ * @since_tizen 6.5
+ * @remarks It will return #MEDIA_PACKET_ERROR_INVALID_OPERATION \n
+ *          if the media packet handle is from media_packet_create(), \n
+ *          media_packet_create_alloc(), media_packet_create_from_tbm_surface() \n
+ *          and media_packet_create_from_external_memory().
+ * @param[in] packet The media packet handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_PACKET_ERROR_NONE Successful
+ * @retval #MEDIA_PACKET_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_packet_unref()
+ */
+int media_packet_ref(media_packet_h packet);
 
 /**
+ * @brief Decreases reference count of a media packet handle.
+ * @since_tizen 6.5
+ * @remarks It will return #MEDIA_PACKET_ERROR_INVALID_OPERATION \n
+ *          if the media packet handle is from media_packet_create(), \n
+ *          media_packet_create_alloc(), media_packet_create_from_tbm_surface() \n
+ *          and media_packet_create_from_external_memory().
+ * @param[in] packet The media packet handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_PACKET_ERROR_NONE Successful
+ * @retval #MEDIA_PACKET_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
+ * @see media_packet_ref()
+ */
+int media_packet_unref(media_packet_h packet);
+
+/**
+ * @deprecated Deprecated since 6.5.
  * @brief    Copies a media packet handle.
  * @details  It re-creates only media packet handle with exist media packet handle.
  *
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  *
  * @remarks The @c new_packet must be released by using media_packet_destroy().
+ * @remarks It will return #MEDIA_PACKET_ERROR_INVALID_OPERATION \n
+ *          if the media packet handle is from media_packet_new(), \n
+ *          media_packet_new_alloc(), media_packet_new_from_tbm_surface() \n
+ *          and media_packet_new_from_external_memory(). (since 6.5)
  * @param[in]   org_packet   The existing media packet handle
  * @param[in]   fcb          The media_packet_finalize_cb() to register
  * @param[in]   fcb_data     The user data to be passed to the media_packet_finalize_cb() function
@@ -245,7 +395,7 @@ int media_packet_create(media_format_h fmt, media_packet_finalize_cb fcb, void *
  * @see media_packet_destroy()
  * @see media_packet_finalize_cb()
  */
-int media_packet_copy(media_packet_h org_packet, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * new_packet);
+int media_packet_copy(media_packet_h org_packet, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * new_packet) TIZEN_DEPRECATED_API;
 
 /**
  * @brief    Allocates buffer with media packet handle.
@@ -262,12 +412,13 @@ int media_packet_copy(media_packet_h org_packet, media_packet_finalize_cb fcb, v
  * @retval #MEDIA_PACKET_ERROR_OUT_OF_MEMORY     Out of memory
  * @retval #MEDIA_PACKET_ERROR_INVALID_OPERATION Invalid operation
  *
- * @see media_packet_create()
- * @see media_packet_destroy()
+ * @see media_packet_new()
+ * @see media_packet_unref()
  */
 int media_packet_alloc(media_packet_h packet);
 
 /**
+ * @deprecated Deprecated since 6.5. Use media_packet_new_from_tbm_surface() instead.
  * @brief    Creates media packet handle and allocates buffer with #tbm_surface_h.
  *
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
@@ -311,7 +462,7 @@ int media_packet_alloc(media_packet_h packet);
    media_format_unref(fmt);
 
    ...
-   media_pacekt_destory(packet);
+   media_packet_destroy(packet);
    }
 
    int _finalize_callback(media_packet_h packet, int err, void* userdata)
@@ -322,9 +473,10 @@ int media_packet_alloc(media_packet_h packet);
 
    @endcode
  */
-int media_packet_create_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet);
+int media_packet_create_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet) TIZEN_DEPRECATED_API;
 
 /**
+ * @deprecated Deprecated since 6.5. Use media_packet_new_from_external_memory() instead.
  * @brief    Creates media packet handle with already allocated external buffer.
  * @details It does not support video's #MEDIA_FORMAT_RAW type.
  *
@@ -381,7 +533,7 @@ int media_packet_create_from_tbm_surface(media_format_h fmt, tbm_surface_h surfa
 
    @endcode
  */
-int media_packet_create_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet);
+int media_packet_create_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h * packet) TIZEN_DEPRECATED_API;
 
 /**
  * @brief Gets #media_format_h of media packet.
@@ -494,8 +646,8 @@ int media_packet_set_duration(media_packet_h packet, uint64_t duration);
  * @brief Sets buffer size of media packet.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  *
- * @param[in]  packet   The media packet handle
- * @param[out] size     The buffer size value to set
+ * @param[in] packet   The media packet handle
+ * @param[in] size     The buffer size value to set
  *
  * @return @c 0 on success,
  *         otherwise a negative error value
@@ -912,7 +1064,7 @@ int media_packet_get_video_stride_height(media_packet_h packet, int plane_idx, i
  *
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
  *
- * @remarks The @c plane_data_ptr must not be released by using free(). Note that It is released by media_packet_destory() or tbm_surface_destroy().
+ * @remarks The @c plane_data_ptr must not be released by using free(). Note that It is released by media_packet_destroy() or tbm_surface_destroy().
  * @param[in]  packet   The media packet handle
  * @param[in]  plane_idx   The plane index value
  * @param[out] plane_data_ptr  The plane data pointer from tbm_surface
@@ -942,10 +1094,14 @@ int media_packet_get_video_plane_data_ptr(media_packet_h packet, int plane_idx,
 int media_packet_get_codec_data(media_packet_h packet, void **codec_data, unsigned int *codec_data_size);
 
 /**
+ * @deprecated Deprecated since 6.5. Use media_packet_unref() instead.
  * @brief Destroys the media packet handle.
- * @details  The registered finalize_callback() function will be invoked to destroy the media packet handle.
- *
+ * @details The registered finalize_callback() function will be invoked to destroy the media packet handle.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @remarks It will return #MEDIA_PACKET_ERROR_INVALID_OPERATION \n
+ *          if the media packet handle is from media_packet_new(), \n
+ *          media_packet_new_alloc(), media_packet_new_from_tbm_surface() \n
+ *          and media_packet_new_from_external_memory(). (since 6.5)
  *
  * @param[in] packet  The handle to media packet to be destroyed
  *
@@ -961,7 +1117,7 @@ int media_packet_get_codec_data(media_packet_h packet, void **codec_data, unsign
  * @see media_packet_create_from_tbm_surface()
  * @see media_packet_create_from_external_memory()
  */
-int media_packet_destroy(media_packet_h packet);
+int media_packet_destroy(media_packet_h packet) TIZEN_DEPRECATED_API;
 
 /**
  * @brief Sets the rotation method.
index 11dc2e98771f3b0b15d6b4fb1d38b5cd2257a646..7c3e820e5f90a24afbfc1d0764c8ac664e93504f 100644 (file)
@@ -104,6 +104,12 @@ do { \
  */
 #define MEDIA_PACKET_CODEC_SYNC_FRAME(arg) (((MEDIA_PACKET_CAST(arg)->flags) >> 2) & 0x001)
 
+/**
+ * @brief Gets the reference count of media packet_h
+ * @since_tizen 6.5
+ */
+#define MEDIA_PACKET_GET_REFCOUNT(arg) (g_atomic_int_get(&(MEDIA_PACKET_CAST(arg))->ref_count))
+
 /**
  * @brief Casting to media_packet_s
  * @since_tizen 2.3
@@ -124,7 +130,8 @@ typedef struct _media_packet_s {
        size_t size;
        void *data;
        void *surface_data;
-       media_packet_finalize_cb finalizecb_func;
+       media_packet_finalize_cb finalize_cb;
+       media_packet_dispose_cb dispose_cb;
        void *userdata;
        bool is_allocated;
        bool using_pool;
@@ -137,7 +144,10 @@ typedef struct _media_packet_s {
        media_buffer_flags_e flags;
        media_packet_rotate_method_e method;
 
+       /* reference count */
        int ref_count;
+       GMutex ref_lock;
+       bool is_from_new;
 } media_packet_s;
 
 #ifdef __cplusplus
index ce92630c97d01190f1948942f5a023472167eec2..e7e10cacbebf90f83247c29a1279dc1961add21a 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-media-tool
 Summary:    A Core API media tool library in Tizen Native API
-Version:    0.1.33
+Version:    0.1.34
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 8674775893717ea79b86a124b82e56b61a8f00a9..b6a4ff2eebe76f0814518a86385d5f0e73f4fd60 100644 (file)
 #include <media_packet_private.h>
 #include <media_format_private.h>
 
-/* NOTE : static internal functions does not check anything on incoming parameters
- * Caller should takecare it
- */
-static int  __pkt_init(media_buffer_type_e type, media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_s **handle);
+static int  __pkt_init(media_buffer_type_e type, media_format_h fmt, void *cb, void *cb_data, bool is_from_new, media_packet_s **handle);
 static void __pkt_deinit(media_packet_s *handle);
+static int  __pkt_alloc_buffer(media_packet_s *handle);
+static int  __pkt_dealloc_buffer(media_packet_s *handle);
+static int  __pkt_create_alloc(media_format_h fmt, void *cb, void *cb_data, media_packet_h *packet, bool is_from_new);
+static int  __pkt_create_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, void *cb, void *cb_data, media_packet_h *packet, bool is_from_new);
+static int  __pkt_create_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, void *cb, void *cb_data, media_packet_h *packet, bool is_from_new);
+static int  __pkt_destroy(media_packet_s *handle);
 static size_t __pkt_calculate_video_buffer_size(media_packet_s *pkt);
 static size_t __pkt_calculate_audio_buffer_size(media_packet_s *pkt);
 static size_t __pkt_calculate_text_buffer_size(media_packet_s *pkt);
-static uint32_t _convert_to_tbm_surface_format(media_format_mimetype_e format_type);
 static void *__aligned_malloc_normal_buffer_type(size_t size, int alignment);
-static void __aligned_free_normal_buffer_type(void *buffer_ptr);
-static int __pkt_alloc_buffer(media_packet_s *handle);
-static int __pkt_dealloc_buffer(media_packet_s *handle);
+static void  __aligned_free_normal_buffer_type(void *buffer_ptr);
+static uint32_t __convert_to_tbm_surface_format(media_format_mimetype_e format_type);
+
 
 static int __pkt_init(media_buffer_type_e type, media_format_h fmt,
-       media_packet_finalize_cb fcb, void *fcb_data, media_packet_s **handle)
+       void *cb, void *cb_data, bool is_from_new, media_packet_s **handle)
 {
        media_packet_s *new_handle = NULL;
 
@@ -62,20 +64,29 @@ static int __pkt_init(media_buffer_type_e type, media_format_h fmt,
                return MEDIA_PACKET_ERROR_OUT_OF_MEMORY;
        }
 
-       g_atomic_int_set(&new_handle->ref_count, 1);
+       g_mutex_init(&new_handle->ref_lock);
+
+       new_handle->ref_count = 1;
        new_handle->type = type;
        new_handle->format = MEDIA_FORMAT_CAST(fmt);
-       new_handle->finalizecb_func = fcb;
-       new_handle->userdata = fcb_data;
+       new_handle->is_from_new = is_from_new;
+       new_handle->userdata = cb_data;
+       if (is_from_new)
+               new_handle->dispose_cb = cb;
+       else
+               new_handle->finalize_cb = cb;
+
        media_format_ref((media_format_h)new_handle->format);
 
        *handle = new_handle;
 
-       LOGI("new packet[type:%d] %p", type, *handle);
+       LOGI("new packet[%p] - type[%d], from_new[%d]",
+               new_handle, new_handle->type, new_handle->is_from_new);
 
        return MEDIA_PACKET_ERROR_NONE;
 }
 
+
 static void __pkt_deinit(media_packet_s *handle)
 {
        if (!handle) {
@@ -85,6 +96,7 @@ static void __pkt_deinit(media_packet_s *handle)
 
        media_format_unref(handle->format);
        handle->format = NULL;
+       g_mutex_clear(&handle->ref_lock);
 
        memset(handle, 0x0, sizeof(media_packet_s));
 
@@ -92,45 +104,248 @@ static void __pkt_deinit(media_packet_s *handle)
 }
 
 
-int media_packet_create(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *packet)
+static int __pkt_create_alloc(media_format_h fmt, void *cb, void *cb_data, media_packet_h *packet, bool is_from_new)
 {
-       MEDIA_PACKET_INSTANCE_CHECK(fmt);
+       media_packet_s *handle = NULL;
+       int ret = MEDIA_PACKET_ERROR_NONE;
 
-       if (MEDIA_FORMAT_IS_VIDEO(fmt) && MEDIA_FORMAT_IS_RAW(fmt))
-               return __pkt_init(MEDIA_BUFFER_TYPE_TBM_SURFACE, fmt, fcb, fcb_data, packet);
+       if (is_from_new)
+               ret = media_packet_new(fmt, cb, cb_data, (media_packet_h)&handle);
        else
-               return __pkt_init(MEDIA_BUFFER_TYPE_NORMAL, fmt, fcb, fcb_data, packet);
+               ret = media_packet_create(fmt, cb, cb_data, (media_packet_h)&handle);
+
+       if (ret != MEDIA_PACKET_ERROR_NONE) {
+               LOGE("failed[0x%x]", ret);
+               return ret;
+       }
+
+       /* alloc buffer */
+       ret = __pkt_alloc_buffer(handle);
+       if (ret != MEDIA_PACKET_ERROR_NONE) {
+               LOGE("__pkt_alloc_buffer() failed[0x%x]", ret); //LCOV_EXCL_LINE
+               __pkt_deinit(handle);   //LCOV_EXCL_LINE
+               return ret;
+       }
+
+       /* take handle */
+       *packet = (media_packet_h)handle;
+
+       LOGI("new packet[%p]", *packet);
+
+       return MEDIA_PACKET_ERROR_NONE;
 }
 
 
-int media_packet_create_alloc(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *packet)
+static int __pkt_create_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, void *cb, void *cb_data, media_packet_h *packet, bool is_from_new)
 {
        media_packet_s *handle = NULL;
+       tbm_surface_info_s surface_info;
        int ret = MEDIA_PACKET_ERROR_NONE;
+       int tbm_ret = TBM_SURFACE_ERROR_NONE;
 
-       ret = media_packet_create(fmt, fcb, fcb_data, (media_packet_h)&handle);
+       MEDIA_PACKET_INSTANCE_CHECK(surface);
+
+       tbm_ret = tbm_surface_get_info(surface, &surface_info);
+       if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
+               LOGE("tbm surface[%p] info failed[0x%x]", surface, tbm_ret);
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
+       }
+
+       ret = __pkt_init(MEDIA_BUFFER_TYPE_EXTERNAL_TBM_SURFACE, fmt, cb, cb_data, is_from_new, &handle);
        if (ret != MEDIA_PACKET_ERROR_NONE) {
-               LOGE("failed 0x%x", ret);
+               LOGE("handle init failed[0x%x]", ret);
                return ret;
        }
 
-       /* alloc buffer */
-       ret = __pkt_alloc_buffer(handle);
+       handle->surface_data = (void *)surface;
+       handle->data = surface_info.planes[0].ptr;
+       handle->size = (uint64_t)surface_info.size;
+       handle->is_allocated = true;
+
+       *packet = (media_packet_h)handle;
+
+       LOGI("data[%p], size[%zu], surface[%p]", handle->data, handle->size, handle->surface_data);
+
+       return MEDIA_PACKET_ERROR_NONE;
+}
+
+
+static int __pkt_create_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, void *cb, void *cb_data, media_packet_h *packet, bool is_from_new)
+{
+       media_packet_s *handle = NULL;
+       int ret = MEDIA_PACKET_ERROR_NONE;
+
+       MEDIA_PACKET_INSTANCE_CHECK(fmt);
+       MEDIA_PACKET_NULL_ARG_CHECK(mem_ptr);
+       MEDIA_PACKET_NULL_ARG_CHECK(packet);
+       MEDIA_PACKET_CHECK_CONDITION(size > 0, "invalid size", MEDIA_PACKET_ERROR_INVALID_PARAMETER);
+
+       if (MEDIA_FORMAT_IS_RAW(fmt) && MEDIA_FORMAT_IS_VIDEO(fmt)) {
+               LOGE("failed!. it supports only 'MEDIA_FORMAT_ENCODED' type."); //LCOV_EXCL_LINE
+               return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = __pkt_init(MEDIA_BUFFER_TYPE_EXTERNAL_MEMORY, fmt, cb, cb_data, is_from_new, &handle);
        if (ret != MEDIA_PACKET_ERROR_NONE) {
-               LOGE("failed __pkt_alloc_buffer(), err = (0x%08x)", ret);       //LCOV_EXCL_LINE
-               __pkt_deinit(handle);   //LCOV_EXCL_LINE
+               LOGE("handle init failed[0x%x]", ret);
                return ret;
        }
 
-       /* take handle */
+       handle->size = size;
+       handle->data = mem_ptr;
+       handle->is_allocated = true;
+
        *packet = (media_packet_h)handle;
 
-       LOGI("new handle : %p", *packet);
+       LOGI("data[%p], size[%zu]", handle->data, handle->size);
+
+       return MEDIA_PACKET_ERROR_NONE;
+}
+
+
+static int __pkt_destroy(media_packet_s *handle)
+{
+       int ret = MEDIA_PACKET_ERROR_NONE;
+       media_packet_finalize_cb_ret_t finalize_ret = MEDIA_PACKET_FINALIZE;
+       bool release_handle = false;
+
+       MEDIA_PACKET_INSTANCE_CHECK(handle);
+
+       g_mutex_lock(&handle->ref_lock);
+
+       if (handle->ref_count < 1) {
+               LOGE("invalid ref count[%d]", handle->ref_count);
+               g_mutex_unlock(&handle->ref_lock);
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
+       }
+
+       LOGD("[%p] unref [%d] -> [%d]",
+               handle, handle->ref_count, handle->ref_count - 1);
+
+       if (--handle->ref_count == 0)
+               release_handle = true;
+
+       g_mutex_unlock(&handle->ref_lock);
+
+       if (release_handle) {
+               /* release callback */
+               if (handle->is_from_new) {
+                       if (handle->dispose_cb)
+                               handle->dispose_cb((media_packet_h)handle, handle->userdata);
+               } else {
+                       if (handle->finalize_cb)
+                               finalize_ret = handle->finalize_cb((media_packet_h)handle, MEDIA_PACKET_ERROR_NONE, handle->userdata);
+
+                       if (finalize_ret == MEDIA_PACKET_REUSE) {
+                               LOGI("the media packet handle will be reused.");
+                               g_atomic_int_set(&handle->ref_count, 1);
+                               return MEDIA_PACKET_ERROR_NONE;
+                       }
+               }
+
+               ret = __pkt_dealloc_buffer(handle);
+               if (ret != MEDIA_PACKET_ERROR_NONE)
+                       LOGW("failed __pkt_dealloc_buffer()[0x%x]", ret);       //LCOV_EXCL_LINE
+
+               __pkt_deinit(handle);
+       }
+
+       return MEDIA_PACKET_ERROR_NONE;
+}
+
+
+int media_packet_create(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *packet)
+{
+       MEDIA_PACKET_INSTANCE_CHECK(fmt);
+
+       if (MEDIA_FORMAT_IS_VIDEO(fmt) && MEDIA_FORMAT_IS_RAW(fmt))
+               return __pkt_init(MEDIA_BUFFER_TYPE_TBM_SURFACE, fmt, fcb, fcb_data, false, packet);
+       else
+               return __pkt_init(MEDIA_BUFFER_TYPE_NORMAL, fmt, fcb, fcb_data, false, packet);
+}
+
+
+int media_packet_create_alloc(media_format_h fmt, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *packet)
+{
+       return __pkt_create_alloc(fmt, fcb, fcb_data, packet, false);
+}
+
+
+int media_packet_new(media_format_h fmt, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h * packet)
+{
+       MEDIA_PACKET_INSTANCE_CHECK(fmt);
+
+       if (MEDIA_FORMAT_IS_VIDEO(fmt) && MEDIA_FORMAT_IS_RAW(fmt))
+               return __pkt_init(MEDIA_BUFFER_TYPE_TBM_SURFACE, fmt, dcb, dcb_data, true, packet);
+       else
+               return __pkt_init(MEDIA_BUFFER_TYPE_NORMAL, fmt, dcb, dcb_data, true, packet);
+}
+
+
+int media_packet_new_alloc(media_format_h fmt, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet)
+{
+       return __pkt_create_alloc(fmt, dcb, dcb_data, packet, true);
+}
+
+
+int media_packet_new_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet)
+{
+       return __pkt_create_from_tbm_surface(fmt, surface, dcb, dcb_data, packet, true);
+}
+
+
+int media_packet_new_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, media_packet_dispose_cb dcb, void *dcb_data, media_packet_h *packet)
+{
+       return __pkt_create_from_external_memory(fmt, mem_ptr, size, dcb, dcb_data, packet, true);
+}
+
+
+int media_packet_ref(media_packet_h packet)
+{
+       int ret = MEDIA_PACKET_ERROR_NONE;
+       media_packet_s *handle = (media_packet_s *)packet;
+
+       MEDIA_PACKET_INSTANCE_CHECK(handle);
+
+       if (!handle->is_from_new) {
+               LOGE("It's from media_packet_create(), it should be from media_packet_new()");
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
+       }
+
+       g_mutex_lock(&handle->ref_lock);
+
+       if (handle->ref_count < 1) {
+               LOGE("invalid ref count[%d]", handle->ref_count);
+               g_mutex_unlock(&handle->ref_lock);
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
+       }
+
+       LOGD("[%p] ref [%d] -> [%d]",
+               handle, handle->ref_count, handle->ref_count + 1);
+
+       handle->ref_count++;
+
+       g_mutex_unlock(&handle->ref_lock);
 
        return MEDIA_PACKET_ERROR_NONE;
 }
 
 
+int media_packet_unref(media_packet_h packet)
+{
+       media_packet_s *handle = (media_packet_s *)packet;
+
+       MEDIA_PACKET_INSTANCE_CHECK(handle);
+
+       if (!handle->is_from_new) {
+               LOGE("It's from media_packet_create(), it should be from media_packet_new()");
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
+       }
+
+       return __pkt_destroy(handle);
+}
+
+
 int media_packet_copy(media_packet_h org_packet, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *new_packet)
 {
        media_packet_s *handle;
@@ -141,6 +356,11 @@ int media_packet_copy(media_packet_h org_packet, media_packet_finalize_cb fcb, v
 
        org_handle = (media_packet_s *)org_packet;
 
+       if (org_handle->is_from_new) {
+               LOGE("It's from media_packet_new() APIs, it should not be copied");
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
+       }
+
        handle = calloc(1, sizeof(media_packet_s));
        if (!handle) {
                LOGE("MEDIA_PACKET_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIA_PACKET_ERROR_OUT_OF_MEMORY);     //LCOV_EXCL_LINE
@@ -157,12 +377,16 @@ int media_packet_copy(media_packet_h org_packet, media_packet_finalize_cb fcb, v
        handle->size = 0;
 
        /* set finalized callback and user data */
-       handle->finalizecb_func = fcb;
+       handle->finalize_cb = fcb;
        handle->userdata = fcb_data;
 
        /* increase format reference count */
        media_format_ref((media_format_h)handle->format);
 
+       /* ref count */
+       handle->ref_count = 1;
+       g_mutex_init(&handle->ref_lock);
+
        /* take handle */
        *new_packet = (media_packet_h)handle;
 
@@ -220,7 +444,7 @@ static int __pkt_alloc_buffer(media_packet_s *handle)
        } else if (handle->type == MEDIA_BUFFER_TYPE_TBM_SURFACE) {
                /*create tbm_surface */
                handle->surface_data = (void *)tbm_surface_create(handle->format->detail.video.width,
-                       handle->format->detail.video.height, _convert_to_tbm_surface_format(handle->format->mimetype));
+                       handle->format->detail.video.height, __convert_to_tbm_surface_format(handle->format->mimetype));
                if (handle->surface_data == NULL) {
                        LOGE("tbm_surface_create() is failed!!");       //LCOV_EXCL_LINE
                        return MEDIA_PACKET_ERROR_INVALID_OPERATION;
@@ -250,18 +474,28 @@ static int __pkt_alloc_buffer(media_packet_s *handle)
 
 static int __pkt_dealloc_buffer(media_packet_s *handle)
 {
-       if (handle->type == MEDIA_BUFFER_TYPE_TBM_SURFACE) {
-               if (handle->surface_data)
+       MEDIA_PACKET_NULL_ARG_CHECK(handle);
+
+       switch (handle->type) {
+       case MEDIA_BUFFER_TYPE_TBM_SURFACE:
+               if (handle->surface_data) {
                        tbm_surface_destroy((tbm_surface_h)handle->surface_data);
-       } else if (handle->type == MEDIA_BUFFER_TYPE_NORMAL) {
+                       handle->surface_data = NULL;
+               }
+               break;
+       case MEDIA_BUFFER_TYPE_NORMAL:
                if (handle->data) {
                        __aligned_free_normal_buffer_type(handle->data);
                        handle->data = NULL;
                }
-       } else if (handle->type == MEDIA_BUFFER_TYPE_EXTERNAL_TBM_SURFACE || handle->type == MEDIA_BUFFER_TYPE_EXTERNAL_MEMORY) {
+               break;
+       case MEDIA_BUFFER_TYPE_EXTERNAL_TBM_SURFACE:
+                /* fall through */
+       case MEDIA_BUFFER_TYPE_EXTERNAL_MEMORY:
                /* there is nothing to do, Do not free the buffer which is created by external module. */
-       } else {
-               LOGE("Invalid buffer type");    //LCOV_EXCL_LINE
+               break;
+       default:
+               LOGE("Invalid buffer type[%d]", handle->type);  //LCOV_EXCL_LINE
                return MEDIA_PACKET_ERROR_INVALID_OPERATION;
        }
 
@@ -483,67 +717,12 @@ static size_t __pkt_calculate_text_buffer_size(media_packet_s *pkt)
 
 int media_packet_create_from_tbm_surface(media_format_h fmt, tbm_surface_h surface, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *packet)
 {
-       media_packet_s *handle = NULL;
-       tbm_surface_info_s surface_info;
-       int ret = MEDIA_PACKET_ERROR_NONE;
-       int tbm_ret = TBM_SURFACE_ERROR_NONE;
-
-       MEDIA_PACKET_INSTANCE_CHECK(surface);
-
-       tbm_ret = tbm_surface_get_info(surface, &surface_info);
-       if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
-               LOGE("tbm surface[%p] info failed 0x%x", surface, tbm_ret);
-               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
-       }
-
-       ret = __pkt_init(MEDIA_BUFFER_TYPE_EXTERNAL_TBM_SURFACE, fmt, fcb, fcb_data, &handle);
-       if (ret != MEDIA_PACKET_ERROR_NONE) {
-               LOGE("handle init failed 0x%x", ret);
-               return ret;
-       }
-
-       handle->surface_data = (void *)surface;
-       handle->data = surface_info.planes[0].ptr;
-       handle->size = (uint64_t)surface_info.size;
-       handle->is_allocated = true;
-
-       *packet = (media_packet_h)handle;
-
-       LOGI("surface %p, data %p, size %zu", handle->surface_data, handle->data, handle->size);
-
-       return ret;
+       return __pkt_create_from_tbm_surface(fmt, surface, fcb, fcb_data, packet, false);
 }
 
 int media_packet_create_from_external_memory(media_format_h fmt, void *mem_ptr, uint64_t size, media_packet_finalize_cb fcb, void *fcb_data, media_packet_h *packet)
 {
-       media_packet_s *handle = NULL;
-       int ret = MEDIA_PACKET_ERROR_NONE;
-
-       MEDIA_PACKET_INSTANCE_CHECK(fmt);
-       MEDIA_PACKET_NULL_ARG_CHECK(mem_ptr);
-       MEDIA_PACKET_NULL_ARG_CHECK(packet);
-       MEDIA_PACKET_CHECK_CONDITION(size > 0, "invalid size", MEDIA_PACKET_ERROR_INVALID_PARAMETER);
-
-       if (MEDIA_FORMAT_IS_RAW(fmt) && MEDIA_FORMAT_IS_VIDEO(fmt)) {
-               LOGE("failed!. it supports only 'MEDIA_FORMAT_ENCODED' type."); //LCOV_EXCL_LINE
-               return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = __pkt_init(MEDIA_BUFFER_TYPE_EXTERNAL_MEMORY, fmt, fcb, fcb_data, &handle);
-       if (ret != MEDIA_PACKET_ERROR_NONE) {
-               LOGE("handle init failed 0x%x", ret);
-               return ret;
-       }
-
-       handle->size = size;
-       handle->data = mem_ptr;
-       handle->is_allocated = true;
-
-       *packet = (media_packet_h)handle;
-
-       LOGI("data %p, size %zu", handle->data, handle->size);
-
-       return ret;
+       return __pkt_create_from_external_memory(fmt, mem_ptr,size, fcb, fcb_data, packet, false);
 }
 
 int media_packet_get_buffer_data_ptr(media_packet_h packet, void **data)
@@ -1139,45 +1318,19 @@ int media_packet_get_codec_data(media_packet_h packet, void **codec_data, unsign
 
 int media_packet_destroy(media_packet_h packet)
 {
-       media_packet_s *handle;
-       int ret = MEDIA_PACKET_ERROR_NONE;
-
-       MEDIA_PACKET_INSTANCE_CHECK(packet);
+       media_packet_s *handle = (media_packet_s *)packet;
 
-       handle = (media_packet_s *)packet;
-
-       if (!g_atomic_int_dec_and_test(&handle->ref_count)) {
-               LOGD("ref count %d", g_atomic_int_get(&handle->ref_count));
-               return MEDIA_PACKET_ERROR_NONE;
-       }
-
-       /* finalize callback */
-       if (handle->finalizecb_func) {
-               int finalize_cb_ret;
-               finalize_cb_ret = handle->finalizecb_func((media_packet_h)handle, MEDIA_PACKET_ERROR_NONE, handle->userdata);
-
-               /* creator do not want to destroy media packet handle */
-               if (finalize_cb_ret == MEDIA_PACKET_REUSE) {
-                       LOGI("the media packet handle will be reused.");        //LCOV_EXCL_LINE
-                       g_atomic_int_set(&handle->ref_count, 1);
-                       return MEDIA_PACKET_ERROR_NONE;
-               }
-       }
+       MEDIA_PACKET_INSTANCE_CHECK(handle);
 
-       ret = __pkt_dealloc_buffer(handle);
-       if (ret != MEDIA_PACKET_ERROR_NONE) {
-               LOGE("failed __pkt_dealloc_buffer(), err = (0x%08x)", ret);     //LCOV_EXCL_LINE
-               return ret;
+       if (handle->is_from_new) {
+               LOGE("It's from media_packet_new() APIs, so should be released with media_packet_unref()");
+               return MEDIA_PACKET_ERROR_INVALID_OPERATION;
        }
 
-       LOGI("The packet handle(%p) will be destroyed", handle);        //LCOV_EXCL_LINE
-
-       __pkt_deinit(handle);
-
-       return ret;
+       return __pkt_destroy(handle);
 }
 
-static uint32_t _convert_to_tbm_surface_format(media_format_mimetype_e format_type)
+static uint32_t __convert_to_tbm_surface_format(media_format_mimetype_e format_type)
 {
        uint32_t tbm_format;
 
index ed013cd3c12d5eabab08a236aab815681387767d..4b2b51f3cb7e23942816e7a683a9edfae200ab77 100644 (file)
@@ -347,13 +347,12 @@ static void _create_format_raw(void)
 
 }
 
-static int _finalize_callback(media_packet_h packet, int err, void *userdata)
+static int _dispose_callback(media_packet_h packet, void *userdata)
 {
-       g_print("==> finalize callback func is called\n");
-       return MEDIA_PACKET_FINALIZE;
+       g_print("==> dispose callback func is called\n");
 }
 
-static void _media_packet_create_alloc(void)
+static void _media_packet_new_alloc(void)
 {
        g_print("=== create_and_alloc!!\n");
        int i;
@@ -361,7 +360,7 @@ static void _media_packet_create_alloc(void)
        for (i = 0; i < g_handle_num; i++) {
                if (g_media_packet[i] != NULL) {
                        int ref_count = MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]);
-                       media_packet_destroy(g_media_packet[i]);
+                       media_packet_unref(g_media_packet[i]);
                        if (ref_count == 1) {
                                g_media_format[media_format_idx] = NULL;
                                g_print("media_format_h[%d] is destroyed...\n", media_format_idx);
@@ -374,11 +373,11 @@ static void _media_packet_create_alloc(void)
                        break;
                }
 
-               if (media_packet_create_alloc(g_media_format[0], _finalize_callback, NULL, &g_media_packet[i]) != MEDIA_PACKET_ERROR_NONE) {
+               if (media_packet_new_alloc(g_media_format[0], _dispose_callback, NULL, &g_media_packet[i]) != MEDIA_PACKET_ERROR_NONE) {
                        g_print("media_packet create is failed\n");
                } else {
                        media_format_idx = 0;
-                       g_print("succeeded media_packet_create_alloc !!\n");
+                       g_print("succeeded media_packet_new_alloc !!\n");
                        g_print(" ==> media_format_h[0] ref_count =%d\n", MEDIA_FORMAT_GET_REFCOUNT(g_media_format[0]));
                        media_format_unref(g_media_format[0]);
                        g_print(" ====> media_format_unref, media_format_h[0] ref_count = %d\n", MEDIA_FORMAT_GET_REFCOUNT(g_media_format[0]));
@@ -388,7 +387,7 @@ static void _media_packet_create_alloc(void)
        }
 }
 
-static void _media_packet_create(void)
+static void _media_packet_new(void)
 {
        g_print("=== create!!\n");
        is_only_created_handle = true;
@@ -397,7 +396,7 @@ static void _media_packet_create(void)
        for (i = 0; i < g_handle_num; i++) {
                if (g_media_packet[i] != NULL) {
                        int ref_count = MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]);
-                       media_packet_destroy(g_media_packet[i]);
+                       media_packet_unref(g_media_packet[i]);
                        if (ref_count == 1) {
                                g_media_format[media_format_idx] = NULL;
                                g_print("media_format_h[%d] is destroyed...\n", media_format_idx);
@@ -411,11 +410,11 @@ static void _media_packet_create(void)
                }
 
                /* only ES format , if you want to another format, see _create_format_es() */
-               if (media_packet_create(g_media_format[0], _finalize_callback, NULL, &g_media_packet[i]) != MEDIA_PACKET_ERROR_NONE) {
+               if (media_packet_new(g_media_format[0], _dispose_callback, NULL, &g_media_packet[i]) != MEDIA_PACKET_ERROR_NONE) {
                        g_print("media_packet create is failed\n");
                } else {
                        media_format_idx = 0;
-                       g_print("media_packet_create is sucess!!\n");
+                       g_print("media_packet_new is sucess!!\n");
                        g_print(" ==> media_format_h[0] ref_count =%d\n", MEDIA_FORMAT_GET_REFCOUNT(g_media_format[0]));
                        media_format_unref(g_media_format[0]);
                        g_print(" ====> media_format_unref, media_format_h[0] ref_count = %d\n", MEDIA_FORMAT_GET_REFCOUNT(g_media_format[0]));
@@ -433,11 +432,11 @@ static void _media_packet_alloc(void)
                else
                        g_print("media_packet_alloc is failed\n");
        } else {
-               g_print("*** can not excute!! fisrt excute media_packet_create() before this alloc. \n");
+               g_print("*** can not excute!! fisrt excute media_packet_new() before this alloc. \n");
        }
 }
 
-static void _media_packet_create_from_tbm_surface(void)
+static void _media_packet_new_from_tbm_surface(void)
 {
        g_print("=== create_from_tbm_surface!!\n");
 
@@ -450,7 +449,7 @@ static void _media_packet_create_from_tbm_surface(void)
                for (i = 0; i < g_handle_num; i++) {
                        if (g_media_packet[i] != NULL) {
                                int ref_count = MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]);
-                               media_packet_destroy(g_media_packet[i]);
+                               media_packet_unref(g_media_packet[i]);
 
                                if (ref_count == 1) {
                                        g_media_format[media_format_idx] = NULL;
@@ -466,10 +465,10 @@ static void _media_packet_create_from_tbm_surface(void)
                        }
 
                        /* only RAW format , if you want to another format, see _create_format_raw() */
-                       if (media_packet_create_from_tbm_surface(g_media_format[2], surface, _finalize_callback, NULL, &g_media_packet[i]) != MEDIA_PACKET_ERROR_NONE) {
-                               g_print("media_packet_create_from_tbm_surface is failed\n");
+                       if (media_packet_new_from_tbm_surface(g_media_format[2], surface, _dispose_callback, NULL, &g_media_packet[i]) != MEDIA_PACKET_ERROR_NONE) {
+                               g_print("media_packet_new_from_tbm_surface is failed\n");
                        } else {
-                               g_print("media_packet_create_from_tbm_surface is sucess!!\n");
+                               g_print("media_packet_new_from_tbm_surface is sucess!!\n");
                                g_print(" ==> media_format_h[2] ref_count =%d\n", MEDIA_FORMAT_GET_REFCOUNT(g_media_format[2]));
                                media_format_unref(g_media_format[2]);
                                g_print(" ====> media_format_unref, media_format_h[2] ref_count = %d\n", MEDIA_FORMAT_GET_REFCOUNT(g_media_format[2]));
@@ -483,61 +482,73 @@ static void _media_packet_create_from_tbm_surface(void)
        }
 }
 
-static void _media_packet_copy(void)
+
+static void _media_packet_ref()
 {
-       g_print("=== copy!!\n");
-
-       if (is_excute_create) {
-               if (media_packet_copy(g_media_packet[0], _finalize_callback, NULL, &g_media_packet[1]) == MEDIA_PACKET_ERROR_NONE) {
-                       g_print("media_packet_copy sucess !!");
-                       is_only_created_handle = true;
-                       memset(g_media_packet[0], 0, sizeof(media_packet_s));
-                       if (!g_media_packet[1]) {
-                               g_print("g_media_packet[1] is NULL\n");
-                               return;
-                       }
-                       memcpy(g_media_packet[0], g_media_packet[1], sizeof(media_packet_s));
-                       free(g_media_packet[1]);
-                       g_media_packet[1] = NULL;
-               } else {
-                       g_print("media_packet_copy failed");
+       g_print("=== ref!!\n");
+       int i;
+       int ret;
+
+       int ref_count = 0;
+
+       for (i = 0; i < g_handle_num; i++) {
+               if (!g_media_packet[i]) {
+                       g_print("There is nothing to ref packet[%d] handle...\n", i);
+                       continue;
+               }
+
+               ref_count = MEDIA_PACKET_GET_REFCOUNT(g_media_packet[i]);
+
+               g_print("ref count[%d] -> ", ref_count);
+
+               ret = media_packet_ref(g_media_packet[i]);
+               if (ret != MEDIA_PACKET_ERROR_NONE) {
+                       g_print("media_packet_ref failed[0x%x]\n", ret);
+                       continue;
                }
-       } else {
-               g_print("denied... excute create or create_alloc or create_from_surface");
-       }
 
+               ref_count = MEDIA_PACKET_GET_REFCOUNT(g_media_packet[i]);
+               g_print("[%d]\n", ref_count);
+       }
 }
 
-static void _media_packet_destroy()
+
+static void _media_packet_unref()
 {
-       g_print("=== destroy!!\n");
+       g_print("=== unref!!\n");
        int i;
        int ret;
 
-       int ref_count;
+       int ref_count_fmt = 0;
+       int ref_count_pkt = 0;
 
        for (i = 0; i < g_handle_num; i++) {
-               if (g_media_packet[i] != NULL) {
-                       if (g_media_format[media_format_idx])
-                               ref_count = MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]);
-                       else
-                               ref_count = -1;
-                       ret = media_packet_destroy(g_media_packet[i]);
-                       g_media_packet[i] = NULL;
+               if (!g_media_packet[i]) {
+                       g_print("There is nothing to unref packet[%d] handle...\n", i);
+                       continue;
+               }
 
-                       if (ref_count == 1) {
-                               g_media_format[media_format_idx] = NULL;
-                               g_print("media_format_h[%d] is destroyed...\n", media_format_idx);
-                       }
+               if (g_media_format[media_format_idx])
+                       ref_count_fmt = MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]);
+               else
+                       ref_count_fmt = -1;
 
-                       if (ret == MEDIA_PACKET_ERROR_NONE) {
-                               g_print("media_packet_destroy is succeeded!!\n");
-                               if (g_media_format[media_format_idx] != NULL)
-                                       g_print(" ==> media_format_h[%d] ref_count = %d\n", media_format_idx, MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]));
-                       } else
-                               g_print("media_packet_destroy is failed...\n");
-               } else
-                       g_print("There is nothing to destroy media_packet_h[%d] handle...\n", i);
+               ref_count_pkt = MEDIA_PACKET_GET_REFCOUNT(g_media_packet[i]);
+
+               ret = media_packet_unref(g_media_packet[i]);
+               if (ret != MEDIA_PACKET_ERROR_NONE) {
+                       g_print("unref for packet[%d] failed[0x%x]\n", i, ret);
+                       continue;
+               }
+
+               if (ref_count_pkt == 1 && ref_count_fmt == 1) {
+                       g_media_packet[i] = NULL;
+                       g_media_format[media_format_idx] = NULL;
+                       g_print("media_format_h[%d] is destroyed...\n", media_format_idx);
+                       g_print("media_packet_unref is succeeded!!\n");
+               } else {
+                       g_print("packet[%d][ref:%d] is still alive after unref\n", i, ref_count_pkt - 1);
+               }
        }
 }
 
@@ -890,7 +901,7 @@ void quit_program(void)
                                ref_count = MEDIA_FORMAT_GET_REFCOUNT(g_media_format[media_format_idx]);
                        else
                                ref_count = -1;
-                       media_packet_destroy(g_media_packet[i]);
+                       media_packet_unref(g_media_packet[i]);
                        g_media_packet[i] = NULL;
                        if (ref_count == 1) {
                                g_media_format[media_format_idx] = NULL;
@@ -930,18 +941,18 @@ void _interpret_main_menu(char *cmd)
        int len = strlen(cmd);
        if (len == 1) {
                if (strncmp(cmd, "a", 1) == 0)
-                       _media_packet_create_alloc();
-               else if (strncmp(cmd, "d", 1) == 0)
-                       _media_packet_destroy();
+                       _media_packet_new_alloc();
+               else if (strncmp(cmd, "r", 1) == 0)
+                       _media_packet_ref();
+               else if (strncmp(cmd, "u", 1) == 0)
+                       _media_packet_unref();
                else if (strncmp(cmd, "b", 1) == 0)
-                       _media_packet_create_from_tbm_surface();
-               else if (strncmp(cmd, "c", 1) == 0)
-                       _media_packet_copy();
+                       _media_packet_new_from_tbm_surface();
                else if (strncmp(cmd, "q", 1) == 0)
                        quit_program();
        } else if (len == 2) {
                if (strncmp(cmd, "aa", 2) == 0)
-                       _media_packet_create();
+                       _media_packet_new();
                else if (strncmp(cmd, "ab", 2) == 0)
                        _media_packet_alloc();
                else if (strncmp(cmd, "iv", 2) == 0)
@@ -1252,10 +1263,10 @@ void display_sub_basic()
        g_print("-----------------------------------------------------------------------------------------\n");
        g_print(" *** How to use ***\n");
        g_print(" : You can create 1 media_format_h handle by 'cf' and 1 media_packet_handle \n");
-       g_print(" : ex) cf > svm > svw > svh > svab > svmb >fgv > > a > iv > ir ...> d\n");
+       g_print(" : ex) cf > svm > svw > svh > svab > svmb > fgv > a > iv > ir ...> d\n");
        g_print(" : media_format_create is set to 'media_format_h[0]' \n");
-       g_print(" : media_packet_create_alloc & media_packet_create use 'media_format_h[0]' \n");
-       g_print(" : media_packet_create_from_tbm_surface use 'media_format_h[2]' \n");
+       g_print(" : media_packet_new_alloc & media_packet_new use 'media_format_h[0]' \n");
+       g_print(" : media_packet_new_from_tbm_surface use 'media_format_h[2]' \n");
        g_print("\n");
        g_print("cf. media_format_create\t\t");
        g_print("\n");
@@ -1283,11 +1294,10 @@ void display_sub_basic()
        g_print("fgaaht. media_format_get_audio_aac_header_type \t");
        g_print("\n");
        g_print("\n");
-       g_print("a. media_packet_create_alloc(+media_format_unref)  \t");
-       g_print("aa. media_packet_create(+media_format_unref) \t");
-       g_print("b. media_packet_create_from_tbm_surface(+media_format_unref) \n");
+       g_print("a. media_packet_new_alloc(+media_format_unref)  \t");
+       g_print("aa. media_packet_new(+media_format_unref) \t");
+       g_print("b. media_packet_new_from_tbm_surface(+media_format_unref) \n");
        g_print("ab. media_packet_alloc \t\t");
-       g_print("c. media_packet_copy  \t");
        g_print("\n");
        g_print("\n");
        g_print("iv. media_packet_is_video \t");
@@ -1317,7 +1327,8 @@ void display_sub_basic()
        g_print("scd. media_packet_set_codec_data\t");
        g_print("gcd. media_packet_get_codec_data\t");
        g_print("\n");
-       g_print("d. media_packet_destroy \n");
+       g_print("r. media_packet_ref\t");
+       g_print("u. media_packet_unref \n");
        g_print("q. quit test suite(if exist alive media_format, do media_format_unref)");
        g_print("\n");
        g_print("=========================================================================================\n");