From: Sejun Park Date: Wed, 25 May 2016 06:43:14 +0000 (+0900) Subject: release packet to the pool when user call media_packet_destroy() X-Git-Tag: submit/tizen/20160603.021103^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f72d246295cd69a8cf26ab69d3ab81aa7721924d;p=platform%2Fcore%2Fapi%2Fmediatool.git release packet to the pool when user call media_packet_destroy() Change-Id: I7cee76e6975b6b8fbff7947e80679ad4aa861476 --- diff --git a/include/media_packet_pool_private.h b/include/media_packet_pool_private.h index e58a150..92e679e 100755 --- a/include/media_packet_pool_private.h +++ b/include/media_packet_pool_private.h @@ -17,12 +17,29 @@ #define __TIZEN_MEDIA_PACKET_POOL_PRIVATE_H__ #include +#include #include #ifdef __cplusplus extern "C" { #endif +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "TIZEN_MEDIA_TOOL" + +#define MAX_PACKET 25 + +#define MEDIA_PACKET_POOL_CHECK_CONDITION(condition, error, msg) \ + if (condition) {} else \ + { LOGE("[%s] %s(0x%08x)", __FUNCTION__, msg, error); return error; }; \ + +#define MEDIA_PACKET_POOL_INSTANCE_CHECK(pool) \ + MEDIA_PACKET_POOL_CHECK_CONDITION(pool != NULL, MEDIA_PACKET_ERROR_INVALID_PARAMETER, "MEDIA_PACKET_ERROR_INVALID_PARAMETER") + +#define MEDIA_PACKET_POOL_NULL_ARG_CHECK(arg) \ + MEDIA_PACKET_POOL_CHECK_CONDITION(arg != NULL, MEDIA_PACKET_ERROR_INVALID_PARAMETER, "MEDIA_PACKET_ERROR_INVALID_PARAMETER") /** * @brief The Media Packet Pool structure. * @since_tizen 3.0 @@ -34,9 +51,10 @@ typedef struct _media_packet_pool_s { unsigned int curr_pool_size; unsigned int min_pool_size; unsigned int max_pool_size; - bool pool_created; - bool pool_allocated; + gboolean pool_created; + gboolean pool_allocated; media_format_h fmt_h; + media_packet_h packet[MAX_PACKET]; } media_packet_pool_s; #ifdef __cplusplus diff --git a/include/media_packet_private.h b/include/media_packet_private.h index c77545d..94b262d 100755 --- a/include/media_packet_private.h +++ b/include/media_packet_private.h @@ -132,6 +132,7 @@ typedef struct _media_packet_s { int _pkt_alloc_buffer(media_packet_s *pkt); int _pkt_reset_buffer(media_packet_h packet); +int _pkt_dealloc_buffer(media_packet_s *pkt); void _aligned_free_normal_buffer_type(void *buffer_ptr); #ifdef __cplusplus diff --git a/packaging/capi-media-tool.spec b/packaging/capi-media-tool.spec index 0ade31c..00d3194 100755 --- a/packaging/capi-media-tool.spec +++ b/packaging/capi-media-tool.spec @@ -1,7 +1,7 @@ Name: capi-media-tool Summary: A Core API media tool library in Tizen Native API -Version: 0.1.1 -Release: 3 +Version: 0.1.2 +Release: 0 Group: Multimedia/API License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/src/media_packet.c b/src/media_packet.c index 74317cb..95bda58 100755 --- a/src/media_packet.c +++ b/src/media_packet.c @@ -336,6 +336,33 @@ int _pkt_alloc_buffer(media_packet_s *pkt) return MEDIA_PACKET_ERROR_NONE; } +int _pkt_dealloc_buffer(media_packet_s *handle) +{ + if (handle->type == 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) { + 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) { + /* there is nothing to do, Do not free the buffer which is created by external module. */ + } else { + LOGE("Invalied buffer type"); + return MEDIA_PACKET_ERROR_INVALID_OPERATION; + } + + /* free codec_data if it is allocated */ + if (handle->codec_data) { + free(handle->codec_data); + handle->codec_data = NULL; + handle->codec_data_size = 0; + } + + return MEDIA_PACKET_ERROR_NONE; +} + int _pkt_reset_buffer(media_packet_h packet) { int i; @@ -354,9 +381,8 @@ int _pkt_reset_buffer(media_packet_h packet) tbm_surface_info_s surface_info; int err = tbm_surface_get_info((tbm_surface_h)handle->surface_data, &surface_info); if (err == TBM_SURFACE_ERROR_NONE) { - for (i = 0; i < surface_info.num_planes; i++) { + for (i = 0; i < surface_info.num_planes; i++) memset(surface_info.planes[i].ptr, 0x0, surface_info.planes[i].size); - } } } else { LOGE("tbm_surface_get_info() is failed."); @@ -1305,11 +1331,6 @@ int media_packet_destroy(media_packet_h packet) handle = (media_packet_s *)packet; - if (handle->using_pool) { - LOGE("packet is being used by pool, release can be done by pool only"); - return MEDIA_PACKET_ERROR_INVALID_OPERATION; - } - /* finailize callback */ if (handle->finalizecb_func) { int finalize_cb_ret; @@ -1322,25 +1343,11 @@ int media_packet_destroy(media_packet_h packet) } } - if (handle->type == 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) { - 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) { - /* there is nothing to do, Do not free the buffer which is created by external module. */ + ret = _pkt_dealloc_buffer(handle); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGE("[%s] failed _pkt_dealloc_buffer(), err = (0x%08x)", __FUNCTION__, ret); + return ret; } - - /* free codec_data if it is allocated */ - if (handle->codec_data) { - free(handle->codec_data); - handle->codec_data = NULL; - handle->codec_data_size = 0; - } - /* unreference media_format */ media_format_unref(handle->format); diff --git a/src/media_packet_pool.c b/src/media_packet_pool.c index 19db6f8..4ca5f56 100755 --- a/src/media_packet_pool.c +++ b/src/media_packet_pool.c @@ -18,19 +18,20 @@ #include #include #include -#include #include #include -#include +#include #include -#include + +static gboolean _is_packet_in_queue(media_packet_pool_s *pool_handle, media_packet_h packet); +static int _packet_finalize_cb(media_packet_h packet, int error_code, void *user_data); int media_packet_pool_create(media_packet_pool_h * pool) { int ret = MEDIA_PACKET_ERROR_NONE; media_packet_pool_s *pool_handle = NULL; - MEDIA_PACKET_INSTANCE_CHECK(pool) + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) malloc(sizeof(media_packet_pool_s)); if (pool_handle != NULL) @@ -60,26 +61,22 @@ int media_packet_pool_set_media_format(media_packet_pool_h pool, media_format_h { int ret = MEDIA_PACKET_ERROR_NONE; media_packet_pool_s *pool_handle = NULL; + gboolean is_writable = false; - MEDIA_PACKET_INSTANCE_CHECK(pool); - MEDIA_PACKET_NULL_ARG_CHECK(fmt); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_NULL_ARG_CHECK(fmt); - if (MEDIA_FORMAT_GET_REFCOUNT(fmt) < 1) { + media_format_is_writable(fmt, &is_writable); + if (!is_writable) { LOGE("The media format handle is corrupted or Not set media info"); return MEDIA_PACKET_ERROR_INVALID_PARAMETER; } - - if (!MEDIA_FORMAT_IS_VIDEO(fmt) && !MEDIA_FORMAT_IS_AUDIO(fmt)) { - LOGE("The media format handle is not specified. set video info or audio info..."); - return MEDIA_PACKET_ERROR_INVALID_OPERATION; - } - pool_handle = (media_packet_pool_s *) pool; /* increase format reference count */ media_format_ref(fmt); - pool_handle->fmt_h = MEDIA_FORMAT_CAST(fmt); + pool_handle->fmt_h = fmt; return ret; } @@ -88,7 +85,7 @@ int media_packet_pool_set_size(media_packet_pool_h pool, int min_buffers, int ma int ret = MEDIA_PACKET_ERROR_NONE; media_packet_pool_s *pool_handle = NULL; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; if (max_buffers < 0 || min_buffers < 0 || min_buffers > max_buffers) @@ -105,7 +102,7 @@ int media_packet_pool_get_size(media_packet_pool_h pool, int *min_size, int *max int ret = MEDIA_PACKET_ERROR_NONE; media_packet_pool_s *pool_handle = NULL; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; *curr_size = pool_handle->curr_pool_size; @@ -115,78 +112,24 @@ int media_packet_pool_get_size(media_packet_pool_h pool, int *min_size, int *max } -int _allocate_pkt(media_packet_pool_h pool) +int _packet_finalize_cb(media_packet_h packet, int error_code, void *user_data) { int ret = MEDIA_PACKET_ERROR_NONE; - int i, num_pkts = 0; - + media_packet_pool_h pool = NULL; media_packet_pool_s *pool_handle = NULL; - media_packet_s *pkt_handle = NULL; - media_format_s *fmt_handle = NULL; - - MEDIA_PACKET_INSTANCE_CHECK(pool); - pool_handle = (media_packet_pool_s *) pool; - fmt_handle = (media_format_s *) pool_handle->fmt_h; - MEDIA_PACKET_NULL_ARG_CHECK(fmt_handle); - - if (pool_handle->curr_pool_size >= pool_handle->max_pool_size) { - LOGE("The media packet pool is full.."); - return MEDIA_PACKET_ERROR_INVALID_OPERATION; - - } - pkt_handle = (media_packet_s *) malloc(sizeof(media_packet_s)); + pool = (media_packet_pool_h)user_data; + pool_handle = (media_packet_pool_s *)pool; - if (pkt_handle != NULL) - memset(pkt_handle, 0, sizeof(media_packet_s)); - else { - LOGE("out of memory"); - ret = MEDIA_PACKET_ERROR_OUT_OF_MEMORY; - goto fail; - } - - if (MEDIA_FORMAT_IS_VIDEO(fmt_handle) && MEDIA_FORMAT_IS_RAW(fmt_handle)) - pkt_handle->type = MEDIA_BUFFER_TYPE_TBM_SURFACE; - else - pkt_handle->type = MEDIA_BUFFER_TYPE_NORMAL; - - LOGI("The created packet handle(%p) is..", pkt_handle); - - /* take fmt */ - pkt_handle->format = MEDIA_FORMAT_CAST(fmt_handle); - - /* alloc buffer */ - int err = _pkt_alloc_buffer(pkt_handle); - if (err != MEDIA_PACKET_ERROR_NONE) { - LOGE("failed _pkt_alloc_buffer(), err = (0x%08x)", err); - ret = err; - goto fail; - } - - /* allocated buffer */ - pkt_handle->is_allocated = true; - - /* set finalized callback and user data */ - pkt_handle->finalizecb_func = NULL; - pkt_handle->userdata = NULL; - - /* increase format reference count */ - media_format_ref((media_format_h) pkt_handle->format); - - pkt_handle->using_pool = true; - /* push the packet handle into queue */ - g_queue_push_tail(pool_handle->queue, pkt_handle); - pool_handle->curr_pool_size++; - - return ret; + if (g_atomic_int_get(&pool_handle->pool_allocated)) { + if (media_packet_pool_release_packet(pool, packet) != MEDIA_PACKET_ERROR_NONE) { + LOGW("media packet couldn't be released. packet(%p) might be in queue", packet); + } + return MEDIA_PACKET_REUSE; - fail: - if (pkt_handle) { - free(pkt_handle); - pkt_handle = NULL; + } else { + return MEDIA_PACKET_FINALIZE; } - - return ret; } int media_packet_pool_allocate(media_packet_pool_h pool) @@ -195,13 +138,9 @@ int media_packet_pool_allocate(media_packet_pool_h pool) int i, num_pkts = 0; media_packet_pool_s *pool_handle = NULL; - media_packet_s *pkt_handle = NULL; - media_format_s *fmt_handle = NULL; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; - fmt_handle = (media_format_s *) pool_handle->fmt_h; - MEDIA_PACKET_NULL_ARG_CHECK(fmt_handle); if (!(pool_handle->pool_created)) { LOGE("The media packet pool is not created.."); @@ -220,35 +159,24 @@ int media_packet_pool_allocate(media_packet_pool_h pool) } - if ((pool_handle->pool_allocated)) { + if (g_atomic_int_get(&pool_handle->pool_allocated)) { LOGE("The media packet is already allocated. set media format size..."); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } - for (i = pool_handle->curr_pool_size; i < pool_handle->min_pool_size; i++) { - if (_allocate_pkt(pool_handle) != MEDIA_PACKET_ERROR_NONE) { + + for (i = 0; i < pool_handle->min_pool_size; i++) { + if (media_packet_create_alloc(pool_handle->fmt_h, _packet_finalize_cb, pool_handle, &pool_handle->packet[i]) != MEDIA_PACKET_ERROR_NONE) { LOGE("The media packet pool is full or out of memory..."); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } + g_queue_push_tail(pool_handle->queue, pool_handle->packet[i]); + LOGD("[%d]%p queued", i, pool_handle->packet[i]); + pool_handle->curr_pool_size++; - } - pool_handle->pool_allocated = true; - return ret; - - fail: - if (pkt_handle) { - free(pkt_handle); - pkt_handle = NULL; - } - - while (!g_queue_is_empty(pool_handle->queue)) { - - pkt_handle = g_queue_pop_head(pool_handle->queue); - if (pkt_handle) { - free(pkt_handle); - pkt_handle = NULL; } - } + g_atomic_int_set(&pool_handle->pool_allocated, 1); + return ret; } @@ -256,9 +184,9 @@ int media_packet_pool_acquire_packet(media_packet_pool_h pool, media_packet_h * { int ret = MEDIA_PACKET_ERROR_NONE; media_packet_pool_s *pool_handle = NULL; - media_packet_s *pkt_handle = NULL; + media_packet_h packet = NULL; gint64 wait_until = -1; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; if (timeout != -1) { @@ -266,45 +194,47 @@ int media_packet_pool_acquire_packet(media_packet_pool_h pool, media_packet_h * wait_until = g_get_monotonic_time() + add; } - if (!(pool_handle->pool_allocated)) { + if (!g_atomic_int_get(&pool_handle->pool_allocated)) { LOGE("The media packet pool is not allocated..."); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } + g_mutex_lock(&pool_handle->mutex); if (!(pool_handle->curr_pool_size)) { + g_mutex_unlock(&pool_handle->mutex); LOGE("The media packet pool size is not set. set pool size..."); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } - g_mutex_lock(&pool_handle->mutex); while (TRUE) { - pkt_handle = g_queue_pop_head(pool_handle->queue); + packet = g_queue_pop_head(pool_handle->queue); - if (pkt_handle) + if (packet) break; if (pool_handle->curr_pool_size < pool_handle->max_pool_size) { - LOGI("no buffer, trying to allocate"); + LOGD("no buffer, trying to allocate"); - if (_allocate_pkt(pool_handle) != MEDIA_PACKET_ERROR_NONE) { - LOGE("failed in _allocate_pkt "); - g_mutex_unlock(&pool_handle->mutex); + if (media_packet_create_alloc(pool_handle->fmt_h, _packet_finalize_cb, pool_handle, &pool_handle->packet[pool_handle->curr_pool_size]) != MEDIA_PACKET_ERROR_NONE) { + LOGE("The media packet pool is full or out of memory..."); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } - pkt_handle = g_queue_pop_head(pool_handle->queue); + packet = pool_handle->packet[pool_handle->curr_pool_size]; + pool_handle->curr_pool_size++; + break; } else if (timeout == -1) { - LOGE("Queue is empty, waiting for till release is done"); + LOGD("Queue is empty, waiting for till release is done"); g_cond_wait(&pool_handle->queue_cond, &pool_handle->mutex); - pkt_handle = g_queue_pop_head(pool_handle->queue); + packet = g_queue_pop_head(pool_handle->queue); break; } else { g_cond_wait_until(&pool_handle->queue_cond, &pool_handle->mutex, wait_until); - LOGI("Queue is Empty, waiting for timeout %" G_GSIZE_FORMAT "", wait_until); - pkt_handle = g_queue_pop_head(pool_handle->queue); - if (!pkt_handle) { + LOGD("Queue is Empty, waiting for timeout %" G_GSIZE_FORMAT "", wait_until); + packet = g_queue_pop_head(pool_handle->queue); + if (!packet) { LOGE("pkt is null"); ret = MEDIA_PACKET_ERROR_NO_AVAILABLE_PACKET; } @@ -312,29 +242,36 @@ int media_packet_pool_acquire_packet(media_packet_pool_h pool, media_packet_h * } } - *pkt = (media_packet_h) pkt_handle; + *pkt = (media_packet_h) packet; g_mutex_unlock(&pool_handle->mutex); - LOGI("The packet handle aquired from pool is %p..", pkt_handle); + LOGD("The packet handle aquired from pool is %p..", packet); return ret; } +gboolean _is_packet_in_queue(media_packet_pool_s *pool_handle, media_packet_h packet) +{ + int i; + for (i = 0; i < pool_handle->curr_pool_size; i++) { + if (pool_handle->packet[i] == packet) + return true; + } + return false; +} int media_packet_pool_release_packet(media_packet_pool_h pool, media_packet_h pkt) { int ret = MEDIA_PACKET_ERROR_NONE; int num_pkts = 0; media_packet_pool_s *pool_handle = NULL; - media_packet_s *pkt_handle = NULL; + GList *find; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; - pkt_handle = (media_packet_s*) pkt; - ret = _pkt_reset_buffer(pkt); - if (ret != MEDIA_PACKET_ERROR_NONE) { - LOGE("[%s] failed _pkt_alloc_buffer(), err = (0x%08x)", __FUNCTION__, ret); - return ret; + if ((find = g_queue_find (pool_handle->queue, pkt))) { + LOGE("unable to release '%p' to the pool. Already released", pkt); + return MEDIA_PACKET_ERROR_INVALID_OPERATION; } g_mutex_lock(&pool_handle->mutex); @@ -346,17 +283,22 @@ int media_packet_pool_release_packet(media_packet_pool_h pool, media_packet_h pk return MEDIA_PACKET_ERROR_INVALID_OPERATION; } - if (pkt_handle->using_pool) { - LOGI("The packet released to pool is %p..\n", pkt_handle); + if (_is_packet_in_queue(pool_handle, pkt)) { g_mutex_lock(&pool_handle->mutex); - g_queue_push_tail(pool_handle->queue, pkt_handle); + g_queue_push_tail(pool_handle->queue, pkt); g_mutex_unlock(&pool_handle->mutex); g_cond_signal(&pool_handle->queue_cond); + LOGD("The packet released to pool is %p..\n", pkt); } else { - LOGE("packet is not aquired from pool"); + LOGE("packet is not aquired from pool %p", pkt); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } + /* reset flags of media packet */ + media_packet_unset_flags(pkt, MEDIA_PACKET_CODEC_CONFIG); + media_packet_unset_flags(pkt, MEDIA_PACKET_END_OF_STREAM); + media_packet_unset_flags(pkt, MEDIA_PACKET_SYNC_FRAME); + return ret; } @@ -365,9 +307,9 @@ int media_packet_pool_deallocate(media_packet_pool_h pool) int ret = MEDIA_PACKET_ERROR_NONE; int i, num_pkts = 0; media_packet_pool_s *pool_handle = NULL; - media_packet_s *pkt_handle = NULL; + media_packet_h packet = NULL; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; if (!(pool_handle->pool_created)) @@ -375,29 +317,31 @@ int media_packet_pool_deallocate(media_packet_pool_h pool) g_mutex_lock(&pool_handle->mutex); num_pkts = g_queue_get_length(pool_handle->queue); - g_mutex_unlock(&pool_handle->mutex); if (num_pkts < pool_handle->curr_pool_size) { LOGE("packet is being used, release the packet before deallocate"); + g_mutex_unlock(&pool_handle->mutex); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } - g_mutex_lock(&pool_handle->mutex); + g_atomic_int_set(&pool_handle->pool_allocated, 0); + while (!g_queue_is_empty(pool_handle->queue)) { - pkt_handle = g_queue_pop_head(pool_handle->queue); - g_mutex_unlock(&pool_handle->mutex); - if (pkt_handle == NULL) { + packet = g_queue_pop_head(pool_handle->queue); + if (packet == NULL) { LOGE("Failed to get packet handle from Queue "); return MEDIA_PACKET_ERROR_INVALID_OPERATION; } - pkt_handle = (media_packet_h) pkt_handle; - pkt_handle->using_pool = false; - LOGI("The packet handle(%p) will be deallocated..", pkt_handle); - ret = media_packet_destroy(pkt_handle); - g_mutex_lock(&pool_handle->mutex); + ret = media_packet_destroy(packet); + LOGI("The packet handle(%p) will be deallocated..", packet); + if (ret != MEDIA_PACKET_ERROR_NONE) { + g_mutex_unlock(&pool_handle->mutex); + return ret; + } } g_mutex_unlock(&pool_handle->mutex); + return ret; } @@ -407,9 +351,8 @@ int media_packet_pool_destroy(media_packet_pool_h pool) int num_pkts = 0; media_packet_pool_s *pool_handle = NULL; - media_packet_s *pkt_handle = NULL; - MEDIA_PACKET_INSTANCE_CHECK(pool); + MEDIA_PACKET_POOL_INSTANCE_CHECK(pool); pool_handle = (media_packet_pool_s *) pool; if (!(pool_handle->pool_created)) @@ -424,6 +367,7 @@ int media_packet_pool_destroy(media_packet_pool_h pool) return MEDIA_PACKET_ERROR_INVALID_OPERATION; } + /* unreference media_format */ media_format_unref(pool_handle->fmt_h); g_queue_free(pool_handle->queue);