From b671551b85d05582d38b1d4a2103769ef4d42381 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Thu, 7 Jul 2016 17:21:27 +0900 Subject: [PATCH] add internal api for tbm surface pool Change-Id: I2b564c96ea331d4f2378f0baddbae58baca7d553 --- include/common/player_internal.h | 35 ++++++++++++++++++ include/player_private.h | 1 + include/wearable/player_internal.h | 35 ++++++++++++++++++ packaging/capi-media-player.spec | 2 +- src/player.c | 74 ++++++++++++++++++-------------------- src/player_internal.c | 36 +++++++++++++++++++ 6 files changed, 143 insertions(+), 40 deletions(-) diff --git a/include/common/player_internal.h b/include/common/player_internal.h index cfc73c0..2b84021 100644 --- a/include/common/player_internal.h +++ b/include/common/player_internal.h @@ -499,6 +499,41 @@ int player_set_gapless(player_h player, bool gapless); int player_is_gapless(player_h player, bool *gapless); /** + * @brief Enables the tbm surface pool. + * @since_tizen 3.0 + * @details If it is @c true, tbm surface will be enabled to share the video frame. + * If it is @c false, it won't. The default value is @c false. + * @param[in] player The handle to the media player + * @param[in] enable The new tbm surface status + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @pre The player state must be #PLAYER_STATE_IDLE. + * @see player_is_enabled_tsurf_pool() + */ +int player_enable_tsurf_pool(player_h player, bool enable); + +/** + * @brief Gets the player's tbm surface pool enable status. + * @since_tizen 3.0 + * @details If it is @c true, tbm surface pool is enabled to share the video frame. + * If it is @c false, it won't. The default value is @c false. + * @param[in] player The handle to the media player + * @param[out] enabled The tbm surface enable status + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_enable_tsurf_pool() + */ +int player_is_enabled_tsurf_pool(player_h player, bool *enabled); + +/** * @brief Gets the size of video frame pool. * @since_tizen 3.0 * @details App gets the video frame pool size which will be reused during playback. diff --git a/include/player_private.h b/include/player_private.h index 8e90bab..f5b7761 100644 --- a/include/player_private.h +++ b/include/player_private.h @@ -101,6 +101,7 @@ typedef struct _callback_cb_info { tbm_bufmgr bufmgr; GList *tsurf_list; /* player_tsurf_info_t */ int video_frame_pool_size; + bool use_tsurf_pool; } callback_cb_info_s; typedef struct { diff --git a/include/wearable/player_internal.h b/include/wearable/player_internal.h index 632d905..45722f9 100644 --- a/include/wearable/player_internal.h +++ b/include/wearable/player_internal.h @@ -275,6 +275,41 @@ int player_is_gapless(player_h player, bool *gapless); int player_set_ecore_wl_display(player_h player, player_display_type_e type, Ecore_Wl_Window *ecore_wl_window, int x, int y, int width, int height); /** + * @brief Enables the tbm surface pool. + * @since_tizen 3.0 + * @details If it is @c true, tbm surface will be enabled to share the video frame. + * If it is @c false, it won't. The default value is @c false. + * @param[in] player The handle to the media player + * @param[in] enable The new tbm surface status + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_STATE Invalid state + * @pre The player state must be #PLAYER_STATE_IDLE. + * @see player_is_enabled_tsurf_pool() + */ +int player_enable_tsurf_pool(player_h player, bool enable); + +/** + * @brief Gets the player's tbm surface pool enable status. + * @since_tizen 3.0 + * @details If it is @c true, tbm surface pool is enabled to share the video frame. + * If it is @c false, it won't. The default value is @c false. + * @param[in] player The handle to the media player + * @param[out] enabled The tbm surface enable status + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PLAYER_ERROR_NONE Successful + * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation + * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state + * @pre The player state must be one of these: #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED. + * @see player_enable_tsurf_pool() + */ +int player_is_enabled_tsurf_pool(player_h player, bool *enabled); + +/** * @brief Gets the size of video frame pool. * @since_tizen 3.0 * @details App gets the video frame pool size which will be reused during playback. diff --git a/packaging/capi-media-player.spec b/packaging/capi-media-player.spec index 4dc7804..a232a69 100644 --- a/packaging/capi-media-player.spec +++ b/packaging/capi-media-player.spec @@ -1,6 +1,6 @@ Name: capi-media-player Summary: A Media Player API -Version: 0.3.14 +Version: 0.3.15 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/player.c b/src/player.c index f82175a..7207966 100644 --- a/src/player.c +++ b/src/player.c @@ -53,8 +53,8 @@ typedef struct { typedef struct { intptr_t remote_pkt; - callback_cb_info_s *cb_info; /* to monitor the packet_list */ gint fd; + bool use_tsurf_pool; } _media_pkt_fin_data; /* @@ -85,29 +85,36 @@ int _player_media_packet_finalize(media_packet_h pkt, int error_code, void *user goto EXIT; } - /* Do not destroy tbm surface here to reuse during playback * - * they will be destroyed at player_unprepare() or player_destroy(). * - * ref: __player_remove_tsurf_list() */ + if (!fin_data->use_tsurf_pool) { + tbm_surface_h tsurf = NULL; + if (media_packet_get_tbm_surface(pkt, &tsurf) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_get_tbm_surface failed"); + /* continue the remained job */ + } + if (tsurf) { + LOGD("_player_media_packet_finalize tsurf destroy %p", tsurf); + tbm_surface_destroy(tsurf); + tsurf = NULL; + } + } else { + /* Do not destroy tbm surface here to reuse during playback * + * they will be destroyed at player_unprepare() or player_destroy(). * + * ref: __player_remove_tsurf_list() */ + + tbm_surface_h tsurf = NULL; + + if (media_packet_get_tbm_surface(pkt, &tsurf) == MEDIA_PACKET_ERROR_NONE) { + LOGD("tsurf set to null %p", tsurf); + tsurf = NULL; + } + } packet = fin_data->remote_pkt; snd_msg = muse_core_msg_json_factory_new(api, MUSE_TYPE_POINTER, "packet", packet, 0); snd_len = muse_core_ipc_send_msg(fin_data->fd, snd_msg); muse_core_msg_json_factory_free(snd_msg); - if (snd_len > 0) { - /* player handle is available. remove packet from the list */ - if (fin_data->cb_info->packet_list) { - g_mutex_lock(&fin_data->cb_info->data_mutex); - if (g_list_find(fin_data->cb_info->packet_list, pkt)) { - fin_data->cb_info->packet_list = g_list_remove(fin_data->cb_info->packet_list, pkt); - } else { - LOGW("there is no packet(%p) in exported list.", pkt); - } - g_mutex_unlock(&fin_data->cb_info->data_mutex); - } else { - LOGW("there is no packet list.", pkt); - } - } else { + if (snd_len <= 0) { LOGE("fail to send msg."); } @@ -653,12 +660,14 @@ static void __media_packet_video_frame_cb_handler(callback_cb_info_s * cb_info, } tsurf_data->key = key[0]; tsurf_data->tsurf = tsurf; - g_mutex_lock(&cb_info->data_mutex); - cb_info->tsurf_list = g_list_append(cb_info->tsurf_list, tsurf_data); - LOGD("key %d is added to the pool", key[0]); - if (cb_info->video_frame_pool_size < g_list_length(cb_info->tsurf_list)) - LOGE("need to check the pool size: %d < %d", cb_info->video_frame_pool_size, g_list_length(cb_info->tsurf_list)); - g_mutex_unlock(&cb_info->data_mutex); + if (cb_info->use_tsurf_pool) { + g_mutex_lock(&cb_info->data_mutex); + cb_info->tsurf_list = g_list_append(cb_info->tsurf_list, tsurf_data); + LOGD("key %d is added to the pool", key[0]); + if (cb_info->video_frame_pool_size < g_list_length(cb_info->tsurf_list)) + LOGE("need to check the pool size: %d < %d", cb_info->video_frame_pool_size, g_list_length(cb_info->tsurf_list)); + g_mutex_unlock(&cb_info->data_mutex); + } } else { if (tsurf_data->tsurf) { tsurf = tsurf_data->tsurf; @@ -704,19 +713,14 @@ static void __media_packet_video_frame_cb_handler(callback_cb_info_s * cb_info, goto ERROR; } fin_data->remote_pkt = packet; - fin_data->cb_info = cb_info; fin_data->fd = cb_info->fd; + fin_data->use_tsurf_pool = cb_info->use_tsurf_pool; ret = media_packet_create_from_tbm_surface(cb_info->pkt_fmt, tsurf, (media_packet_finalize_cb) _player_media_packet_finalize, (void *)fin_data, &pkt); if (ret != MEDIA_PACKET_ERROR_NONE || !pkt) { LOGE("media_packet_create_from_tbm_surface failed %d %p", ret, pkt); goto ERROR; } - /* keep the media packet to avoid mem leak. */ - g_mutex_lock(&cb_info->data_mutex); - cb_info->packet_list = g_list_append(cb_info->packet_list, pkt); - g_mutex_unlock(&cb_info->data_mutex); - if (pts != 0) { ret = media_packet_set_pts(pkt, (uint64_t) pts); if (ret != MEDIA_PACKET_ERROR_NONE) @@ -1428,14 +1432,6 @@ int player_destroy(player_h player) LOGW("fail to unset evas client"); } #endif - if (pc->cb_info && pc->cb_info->packet_list) { - g_mutex_lock(&pc->cb_info->data_mutex); - LOGW("num of remained packets : %d !!", g_list_length(pc->cb_info->packet_list)); - /* each media packet have to destroyed in application. */ - g_list_free(pc->cb_info->packet_list); - pc->cb_info->packet_list = NULL; - g_mutex_unlock(&pc->cb_info->data_mutex); - } if (_wl_window_evas_object_cb_del(player) != MM_ERROR_NONE) LOGW("fail to unset evas object callback"); @@ -2033,7 +2029,7 @@ int player_set_display(player_h player, player_display_type_e type, player_displ Ecore_Wl_Window *wl_window = NULL; Evas *e; - LOGD("ENTER"); + LOGD("ENTER type: %d", type); if (type != PLAYER_DISPLAY_TYPE_NONE) { obj = (Evas_Object *) display; diff --git a/src/player_internal.c b/src/player_internal.c index 1a44395..2bee55d 100644 --- a/src/player_internal.c +++ b/src/player_internal.c @@ -329,6 +329,42 @@ int player_is_gapless(player_h player, bool *gapless) return ret; } +int player_enable_tsurf_pool(player_h player, bool enable) +{ + PLAYER_INSTANCE_CHECK(player); + int ret = PLAYER_ERROR_NONE; + player_cli_s *pc = (player_cli_s *) player; + + LOGD("ENTER enable:%d", enable); + + if (pc && pc->cb_info) { + pc->cb_info->use_tsurf_pool = enable; + } else { + LOGE("failed to enable the tbm surf pool"); + ret = PLAYER_ERROR_INVALID_OPERATION; + } + + return ret; +} + +int player_is_enabled_tsurf_pool(player_h player, bool *enabled) +{ + PLAYER_INSTANCE_CHECK(player); + PLAYER_NULL_ARG_CHECK(enabled); + int ret = PLAYER_ERROR_NONE; + player_cli_s *pc = (player_cli_s *) player; + + LOGD("ENTER"); + if (pc && pc->cb_info) { + *enabled = pc->cb_info->use_tsurf_pool; + } else { + LOGE("failed to get the tbm surf pool state"); + ret = PLAYER_ERROR_INVALID_OPERATION; + } + + return ret; +} + int player_get_media_packet_video_frame_pool_size(player_h player, int *size) { PLAYER_INSTANCE_CHECK(player); -- 2.7.4