From e734cb0b5d5b11a6f975d1c76388ae650a84d601 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Tue, 14 Jun 2016 20:00:47 +0900 Subject: [PATCH] add bo list to reuse it when send media packet to client in case of sw codec Change-Id: I1055472f3308f0f65c246b6e0cca21d635d0fc08 --- packaging/libmm-player.spec | 2 +- src/include/mm_player.h | 13 +++ src/include/mm_player_ini.h | 4 + src/include/mm_player_priv.h | 18 +++- src/mm_player.c | 13 +++ src/mm_player_ini.c | 6 ++ src/mm_player_priv.c | 169 +++++++++++++++++++++++++++++++---- 7 files changed, 204 insertions(+), 21 deletions(-) diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index 56ca6c7..6aa96af 100644 --- a/packaging/libmm-player.spec +++ b/packaging/libmm-player.spec @@ -1,6 +1,6 @@ Name: libmm-player Summary: Multimedia Framework Player Library -Version: 0.5.81 +Version: 0.5.82 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player.h b/src/include/mm_player.h index 693b4cf..10aca09 100644 --- a/src/include/mm_player.h +++ b/src/include/mm_player.h @@ -2313,6 +2313,19 @@ int mm_player_get_num_of_video_out_buffers(MMHandleType player, int *num, int *e */ int mm_player_set_media_stream_dynamic_resolution(MMHandleType player, bool drc); +/** + * This function is to release the video stream bo to reuse. \n + * It's only supported when sw codec is used to decode video stream. \n + * + * @param player [in] Handle of player. + * @param bo [in] bo address to be released + * + * @return This function returns zero on success, or negative value with error + * code. + * @since 3.0 + */ +int mm_player_release_video_stream_bo(MMHandleType player, void* bo); + /** @} */ diff --git a/src/include/mm_player_ini.h b/src/include/mm_player_ini.h index a9984de..99d6c3e 100644 --- a/src/include/mm_player_ini.h +++ b/src/include/mm_player_ini.h @@ -82,6 +82,8 @@ typedef struct __mm_player_ini gboolean async_start; gboolean disable_segtrap; gint pcm_buffer_size; + gint num_of_video_bo; + gint video_bo_timeout; /* http streaming */ gchar httpsrc_element[PLAYER_INI_MAX_STRLEN]; @@ -154,6 +156,8 @@ typedef struct __mm_player_ini #define DEFAULT_LIVE_STATE_CHANGE_TIMEOUT 30 /* sec */ #define DEFAULT_LOCALPLAYBACK_STATE_CHANGE_TIMEOUT 10 /* sec */ #define DEFAULT_PCM_BUFFER_SIZE 51200 /* bytes */ +#define DEFAULT_NUM_OF_VIDEO_BO 10 +#define DEFAULT_TIMEOUT_OF_VIDEO_BO 10 /* sec */ /* http streaming */ #define DEFAULT_HTTPSRC "souphttpsrc" diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index 2f4c501..1957aab 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -447,6 +447,16 @@ typedef struct { int buff_size; } mm_player_audio_stream_buff_t; +/** + * @brief data of video_bo_list + * @details this will be used when the sw codec is running. + * @since_tizen 3.0 + */ +typedef struct { + gboolean using; + void* bo; +} mm_player_video_bo_info_t; + typedef struct { /* STATE */ int state; // player current state @@ -536,12 +546,16 @@ typedef struct { mm_player_video_stream_callback video_stream_cb; void* video_stream_cb_user_param; int use_video_stream; + GCond video_bo_cond; + GMutex video_bo_mutex; + GList* video_bo_list; /* mm_player_video_bo_info_t, bo list for decoded video data by sw codec */ + int video_bo_size; /* audio stram callback */ mm_player_audio_stream_callback audio_stream_cb; void* audio_stream_cb_user_param; bool audio_stream_sink_sync; - GList* audio_stream_buff_list; /* buff list of extract pcm data */ + GList* audio_stream_buff_list; /* mm_player_audio_stream_buff_t, buff list of extract pcm data */ /* audio buffer callback */ mm_player_audio_stream_callback_ex audio_stream_render_cb_ex; @@ -876,6 +890,8 @@ gint __gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * int _mmplayer_sound_register_with_pid(MMHandleType hplayer, int pid); int _mmplayer_get_client_pid(MMHandleType hplayer, int* pid); int __mmplayer_get_video_angle(mm_player_t* player, int *user_angle, int *org_angle); +int _mmplayer_video_stream_release_bo(mm_player_t* player, void* bo); + #ifdef __cplusplus } #endif diff --git a/src/mm_player.c b/src/mm_player.c index a00c8ae..c48db33 100644 --- a/src/mm_player.c +++ b/src/mm_player.c @@ -1314,3 +1314,16 @@ int mm_player_set_media_stream_dynamic_resolution(MMHandleType player, bool drc) return result; } +int mm_player_release_video_stream_bo(MMHandleType player, void* bo) +{ + int result = MM_ERROR_NONE; + + MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED); + MMPLAYER_RETURN_VAL_IF_FAIL(bo, MM_ERROR_COMMON_INVALID_ARGUMENT); +// MMPLAYER_CMD_LOCK( player ); + + result = _mmplayer_video_stream_release_bo(player, bo); + +// MMPLAYER_CMD_UNLOCK( player ); + return result; +} \ No newline at end of file diff --git a/src/mm_player_ini.c b/src/mm_player_ini.c index 0d324e5..7ca5bd0 100644 --- a/src/mm_player_ini.c +++ b/src/mm_player_ini.c @@ -178,6 +178,8 @@ mm_player_ini_load(mm_player_ini_t* ini) ini->video_playback_supported = iniparser_getboolean(dict, "general:video playback supported", DEFAULT_VIDEO_PLAYBACK_SUPPORTED); ini->delay_before_repeat = iniparser_getint(dict, "general:delay before repeat", DEFAULT_DELAY_BEFORE_REPEAT); ini->pcm_buffer_size = iniparser_getint(dict, "general:pcm buffer size", DEFAULT_PCM_BUFFER_SIZE); + ini->num_of_video_bo = iniparser_getint(dict, "general:video bo max", DEFAULT_NUM_OF_VIDEO_BO); + ini->video_bo_timeout = iniparser_getint(dict, "general:video bo timeout", DEFAULT_TIMEOUT_OF_VIDEO_BO); MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_overlay, "general:videosink element x", DEFAULT_VIDEOSINK_OVERLAY); MMPLAYER_INI_GET_STRING(dict, ini->videosink_element_evas, "general:videosink element evas", DEFAULT_VIDEOSINK_EVAS); @@ -232,6 +234,8 @@ mm_player_ini_load(mm_player_ini_t* ini) ini->delay_before_repeat = DEFAULT_DELAY_BEFORE_REPEAT; ini->video_playback_supported = DEFAULT_VIDEO_PLAYBACK_SUPPORTED; ini->pcm_buffer_size = DEFAULT_PCM_BUFFER_SIZE; + ini->num_of_video_bo = DEFAULT_NUM_OF_VIDEO_BO; + ini->video_bo_timeout = DEFAULT_TIMEOUT_OF_VIDEO_BO; strncpy( ini->audioresampler_element, DEFAULT_AUDIORESAMPLER, PLAYER_INI_MAX_STRLEN -1 ); strncpy( ini->audiosink_element, DEFAULT_AUDIOSINK, PLAYER_INI_MAX_STRLEN -1 ); @@ -284,6 +288,8 @@ mm_player_ini_load(mm_player_ini_t* ini) LOGD("async_start : %d\n", ini->async_start); LOGD("video_playback_supported : %d\n", ini->video_playback_supported); LOGD("pcm buffer size(bytes) : %d\n", ini->pcm_buffer_size); + LOGD("num of video bo : %d\n", ini->num_of_video_bo); + LOGD("video bo timeout : %d\n", ini->video_bo_timeout); LOGD("gst param1 : %s\n", ini->gst_param[0]); LOGD("gst param2 : %s\n", ini->gst_param[1]); LOGD("gst param3 : %s\n", ini->gst_param[2]); diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index af5bbb3..d4c464c 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -5389,6 +5389,131 @@ static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar* format_name return format_name[0] | (format_name[1] << 8) | (format_name[2] << 16) | (format_name[3] << 24); } +int _mmplayer_video_stream_release_bo(mm_player_t* player, void* bo) +{ + int ret = MM_ERROR_NONE; + GList *l = NULL; + MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED); + MMPLAYER_RETURN_VAL_IF_FAIL(bo, MM_ERROR_INVALID_ARGUMENT); + + g_mutex_lock(&player->video_bo_mutex); + + if (player->video_bo_list) { + for (l=g_list_first(player->video_bo_list);l;l=g_list_next(l)) { + mm_player_video_bo_info_t* tmp = (mm_player_video_bo_info_t *)l->data; + if (tmp && tmp->bo == bo) { + tmp->using = FALSE; + LOGD("release bo %p", bo); + g_mutex_unlock(&player->video_bo_mutex); + g_cond_signal(&player->video_bo_cond); + return ret; + } + } + } else { + /* hw codec is running or the list was reset for DRC. */ + LOGW("there is no bo list."); + } + g_mutex_unlock(&player->video_bo_mutex); + + LOGW("failed to find bo %p", bo); + return ret; +} + +static void +__mmplayer_video_stream_destroy_bo_list(mm_player_t* player) +{ + GList *l = NULL; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player); + + g_mutex_lock(&player->video_bo_mutex); + if (player->video_bo_list) { + LOGD("destroy video_bo_list : %d", g_list_length(player->video_bo_list)); + for (l=g_list_first(player->video_bo_list);l;l=g_list_next(l)) { + mm_player_video_bo_info_t* tmp = (mm_player_video_bo_info_t *)l->data; + if (tmp) { + if (tmp->bo) + tbm_bo_unref(tmp->bo); + g_free(tmp); + } + } + g_list_free(player->video_bo_list); + player->video_bo_list = NULL; + } + player->video_bo_size = 0; + g_mutex_unlock(&player->video_bo_mutex); + + MMPLAYER_FLEAVE(); + return; +} + +static void* +__mmplayer_video_stream_get_bo(mm_player_t* player, int size) +{ + GList *l = NULL; + MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL); + gboolean ret = TRUE; + + /* check DRC, if it is, destroy the prev bo list to create again */ + if (player->video_bo_size != size) { + LOGD("video size is changed: %d -> %d", player->video_bo_size, size); + __mmplayer_video_stream_destroy_bo_list(player); + player->video_bo_size = size; + } + + g_mutex_lock(&player->video_bo_mutex); + + if (!player->video_bo_list) { + /* create bo list */ + int idx = 0; + LOGD("Create bo list for decoded video stream(num:%d)", player->ini.num_of_video_bo); + + for (idx=0 ; idxini.num_of_video_bo ; idx++) { + mm_player_video_bo_info_t* bo_info = g_new(mm_player_video_bo_info_t, 1); + bo_info->bo = tbm_bo_alloc(player->bufmgr, size, TBM_BO_DEFAULT); + if (!bo_info->bo) { + LOGE("Fail to tbm_bo_alloc."); + return NULL; + } + bo_info->using = FALSE; + player->video_bo_list = g_list_append(player->video_bo_list, bo_info); + } + + /* update video num buffers */ + player->video_num_buffers = player->ini.num_of_video_bo; + player->video_extra_num_buffers = (player->ini.num_of_video_bo)/2; + + LOGD("Num of video buffers(%d/%d)", player->video_num_buffers, player->video_extra_num_buffers); + } + + while (TRUE) { + /* get bo from list*/ + for (l=g_list_first(player->video_bo_list);l;l=g_list_next(l)){ + mm_player_video_bo_info_t* tmp = (mm_player_video_bo_info_t *)l->data; + if (tmp && (tmp->using == FALSE)) { + LOGD("found bo %p to use", tmp->bo); + tmp->using = TRUE; + g_mutex_unlock(&player->video_bo_mutex); + return tmp->bo; + } + } + if (!ret) { + LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout); + g_mutex_unlock(&player->video_bo_mutex); + return NULL; + } + + if (player->ini.video_bo_timeout <= 0) { + g_cond_wait(&player->video_bo_cond, &player->video_bo_mutex); + } else { + gint64 timeout = g_get_monotonic_time() + player->ini.video_bo_timeout*G_TIME_SPAN_SECOND; + ret = g_cond_wait_until(&player->video_bo_cond, &player->video_bo_mutex, timeout); + } + continue; + } +} + static GstPadProbeReturn __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user_data) { @@ -5453,14 +5578,14 @@ __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user video_buffer = (MMVideoBuffer *)mapinfo.data; } - if (video_buffer) { + if (video_buffer) { /* hw codec */ /* set tbm bo */ if (video_buffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { /* copy pointer of tbm bo, stride, elevation */ memcpy(stream.bo, video_buffer->handle.bo, sizeof(void *) * MM_VIDEO_BUFFER_PLANE_MAX); - } - else if (video_buffer->type == MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS) { + } else if (video_buffer->type == MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS) { + /* FIXME: need to check this path */ memcpy(stream.data, video_buffer->data, sizeof(void *) * MM_VIDEO_BUFFER_PLANE_MAX); } @@ -5470,7 +5595,7 @@ __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX); /* set gst buffer */ stream.internal_buffer = buffer; - } else { + } else { /* sw codec */ tbm_bo_handle thandle; int stride = GST_ROUND_UP_4 (stream.width); int elevation = stream.height; @@ -5478,25 +5603,24 @@ __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user gboolean gst_ret; gst_ret = gst_memory_map(dataBlock, &mapinfo, GST_MAP_READWRITE); - if(!gst_ret) { + if (!gst_ret) { LOGE("fail to gst_memory_map"); return GST_PAD_PROBE_OK; } stream.stride[0] = stride; stream.elevation[0] = elevation; - if(stream.format == MM_PIXEL_FORMAT_I420) { + if (stream.format == MM_PIXEL_FORMAT_I420) { stream.stride[1] = stream.stride[2] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (stream.width) / 2); stream.elevation[1] = stream.elevation[2] = elevation / 2; - } - else { + } else { LOGE("Not support format %d", stream.format); gst_memory_unmap(dataBlock, &mapinfo); return GST_PAD_PROBE_OK; } size = (stream.stride[0] + stream.stride[1]) * elevation; - stream.bo[0] = tbm_bo_alloc(player->bufmgr, size, TBM_BO_DEFAULT); + stream.bo[0] = __mmplayer_video_stream_get_bo(player, size); if(!stream.bo[0]) { LOGE("Fail to tbm_bo_alloc!!"); gst_memory_unmap(dataBlock, &mapinfo); @@ -5508,7 +5632,6 @@ __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user else LOGE("data pointer is wrong. dest : %p, src : %p", thandle.ptr, mapinfo.data); - tbm_bo_unmap(stream.bo[0]); } @@ -5518,9 +5641,8 @@ __mmplayer_video_stream_probe (GstPad *pad, GstPadProbeInfo *info, gpointer user if (metaBlock) { gst_memory_unmap(metaBlock, &mapinfo); - }else { + } else { gst_memory_unmap(dataBlock, &mapinfo); - tbm_bo_unref(stream.bo[0]); } return GST_PAD_PROBE_OK; @@ -9316,6 +9438,10 @@ _mmplayer_create_player(MMHandleType handle) // @ player->pd_file_save_path = NULL; } + /* create video bo lock and cond */ + g_mutex_init(&player->video_bo_mutex); + g_cond_init(&player->video_bo_cond); + player->streaming_type = STREAMING_SERVICE_NONE; /* give default value of audio effect setting */ @@ -9557,9 +9683,9 @@ _mmplayer_destroy(MMHandleType handle) // @ g_cond_signal( &player->repeat_thread_cond ); LOGD("waitting for repeat thread exit\n"); - g_thread_join ( player->repeat_thread ); - g_mutex_clear(&player->repeat_thread_mutex ); - g_cond_clear (&player->repeat_thread_cond ); + g_thread_join(player->repeat_thread); + g_mutex_clear(&player->repeat_thread_mutex); + g_cond_clear(&player->repeat_thread_cond); LOGD("repeat thread released\n"); } @@ -9653,6 +9779,10 @@ _mmplayer_destroy(MMHandleType handle) // @ g_mutex_clear(&player->msg_cb_lock ); + /* release video bo lock and cond */ + g_mutex_clear(&player->video_bo_mutex); + g_cond_clear(&player->video_bo_cond); + MMPLAYER_FLEAVE(); return MM_ERROR_NONE; @@ -13419,10 +13549,11 @@ __mmplayer_release_misc_post(mm_player_t* player) player->uri_info.uri_list = NULL; } - /* clean the audio stream buffer list */ - if (player->audio_stream_buff_list) { - __mmplayer_audio_stream_clear_buffer(player, FALSE); - } + /* clear the audio stream buffer list */ + __mmplayer_audio_stream_clear_buffer(player, FALSE); + + /* clear the video stream bo list */ + __mmplayer_video_stream_destroy_bo_list(player); player->uri_info.uri_idx = 0; MMPLAYER_FLEAVE(); -- 2.34.1