From: Gilbok Lee Date: Mon, 14 May 2018 11:00:16 +0000 (+0900) Subject: [0.6.98] Add gst bus watcher for using msg queue X-Git-Tag: submit/tizen_4.0/20180523.102543~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4030253113ea9d6bda8afd562aed68b89f64b09;p=platform%2Fcore%2Fmultimedia%2Flibmm-player.git [0.6.98] Add gst bus watcher for using msg queue reduces msg handling delays in msg thread Change-Id: Ia1dbac8687d6cd70a533e5d2a0600726f0515632 --- diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index e8e941e..5858801 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.6.97 +Version: 0.6.98 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index a05586c..7df59c0 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -449,6 +449,11 @@ typedef struct { bool media_packet_video_stream; } MMPlayerSetMode; +typedef struct { + GMainContext *global_default; + GMainContext *thread_default; +} MMPlayerGMainContext; + typedef struct { gint uri_idx; GList *uri_list; @@ -739,7 +744,10 @@ typedef struct { /* signal notifiers */ GList* signals[MM_PLAYER_SIGNAL_TYPE_MAX]; - GMainContext *global_default; + guint bus_watcher; + GQueue *bus_msg_q; + GMutex bus_msg_q_lock; + MMPlayerGMainContext context; MMPlayerUriList uri_info; gboolean is_sound_extraction; diff --git a/src/mm_player_priv.c b/src/mm_player_priv.c index f9f2c3c..af6d32e 100644 --- a/src/mm_player_priv.c +++ b/src/mm_player_priv.c @@ -1094,6 +1094,8 @@ __mmplayer_adaptive_var_info(const VariantData *self, gpointer user_data) void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer) { mm_player_t* player = (mm_player_t*)hplayer; + GstMessage *msg = NULL; + GQueue *queue = NULL; MMPLAYER_FENTER(); MMPLAYER_RETURN_IF_FAIL(player); @@ -1115,9 +1117,37 @@ void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer) g_cond_clear(&player->bus_msg_thread_cond); } + g_mutex_lock(&player->bus_msg_q_lock); + queue = player->bus_msg_q; + while (!g_queue_is_empty(queue)) { + msg = (GstMessage *)g_queue_pop_head(queue); + LOGW("remove remained %s msg", GST_MESSAGE_TYPE_NAME(msg)); + gst_message_unref(msg); + } + g_mutex_unlock(&player->bus_msg_q_lock); + MMPLAYER_FLEAVE(); } +gboolean __mmplayer_gst_msg_push(GstBus *bus, GstMessage *msg, gpointer data) +{ + mm_player_t *player = (mm_player_t *) data; + + g_return_val_if_fail(player, FALSE); + g_return_val_if_fail(msg && GST_IS_MESSAGE(msg), FALSE); + + gst_message_ref(msg); + + g_mutex_lock(&player->bus_msg_q_lock); + g_queue_push_tail(player->bus_msg_q, msg); + g_mutex_unlock(&player->bus_msg_q_lock); + + MMPLAYER_BUS_MSG_THREAD_LOCK(player); + MMPLAYER_BUS_MSG_THREAD_SIGNAL(player); + MMPLAYER_BUS_MSG_THREAD_UNLOCK(player); + return TRUE; +} + static gpointer __mmplayer_gst_bus_msg_thread(gpointer data) { mm_player_t *player = (mm_player_t*)(data); @@ -1141,13 +1171,13 @@ static gpointer __mmplayer_gst_bus_msg_thread(gpointer data) LOGD("[handle: %p] gst bus msg thread will be started.", player); while (!player->bus_msg_thread_exit) { - msg = gst_bus_pop(bus); + g_mutex_lock(&player->bus_msg_q_lock); + msg = g_queue_pop_head(player->bus_msg_q); + g_mutex_unlock(&player->bus_msg_q_lock); if (msg == NULL) { - int timeout = (player->bus_msg_timeout > 0) ? (player->bus_msg_timeout) : (PLAYER_BUS_MSG_DEFAULT_TIMEOUT); - MMPLAYER_BUS_MSG_THREAD_WAIT_UNTIL(player, (g_get_monotonic_time() + timeout * G_TIME_SPAN_MILLISECOND)); + MMPLAYER_BUS_MSG_THREAD_WAIT(player); continue; } - MMPLAYER_BUS_MSG_THREAD_UNLOCK(player); /* handle the gst msg */ __mmplayer_gst_callback(msg, player); @@ -6997,6 +7027,16 @@ __mmplayer_gst_create_pipeline(mm_player_t* player) goto INIT_ERROR; } + player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_msg_push, player); + + player->context.thread_default = g_main_context_get_thread_default(); + + if (player->context.thread_default == NULL) { + player->context.thread_default = g_main_context_default(); + LOGD("thread-default context is the global default context"); + } + LOGW("bus watcher thread context = %p, watcher : %d", player->context.thread_default, player->bus_watcher); + /* set sync handler to get tag synchronously */ gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player, NULL); @@ -7118,6 +7158,10 @@ __mmplayer_gst_destroy_pipeline(mm_player_t* player) /* first we need to disconnect all signal hander */ __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_ALL); + if (player->bus_watcher) + __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher); + player->bus_watcher = 0; + if (mainbin) { MMPlayerGstElement* audiobin = player->pipeline->audiobin; MMPlayerGstElement* videobin = player->pipeline->videobin; @@ -8661,6 +8705,13 @@ _mmplayer_create_player(MMHandleType handle) goto ERROR; } + player->bus_msg_q = g_queue_new(); + if (!player->bus_msg_q) { + LOGE("failed to create queue for bus_msg"); + ret = MM_ERROR_PLAYER_RESOURCE_LIMIT; + goto ERROR; + } + ret = _mmplayer_initialize_video_capture(player); if (ret != MM_ERROR_NONE) { LOGE("failed to initialize video capture\n"); @@ -8761,6 +8812,8 @@ ERROR: g_cond_clear(&player->repeat_thread_cond); } + g_queue_free(player->bus_msg_q); + /* free next play thread */ if (player->next_play_thread) { MMPLAYER_NEXT_PLAY_THREAD_LOCK(player); @@ -9032,6 +9085,8 @@ _mmplayer_destroy(MMHandleType handle) return MM_ERROR_PLAYER_INTERNAL; } + g_queue_free(player->bus_msg_q); + /* release subtitle info lock and cond */ g_mutex_clear(&player->subtitle_info_mutex); g_cond_clear(&player->subtitle_info_cond); @@ -12460,8 +12515,8 @@ __mmplayer_handle_eos_delay(mm_player_t* player, int delay_in_ms) player->eos_timer = g_timeout_add(delay_in_ms, __mmplayer_eos_timer_cb, player); - player->global_default = g_main_context_default(); - LOGD("global default context = %p, eos timer id = %d", player->global_default, player->eos_timer); + player->context.global_default = g_main_context_default(); + LOGD("global default context = %p, eos timer id = %d", player->context.global_default, player->eos_timer); /* check timer is valid. if not, send EOS now */ if (player->eos_timer == 0) { @@ -12477,7 +12532,7 @@ __mmplayer_cancel_eos_timer(mm_player_t* player) if (player->eos_timer) { LOGD("cancel eos timer"); - __mmplayer_remove_g_source_from_context(player->global_default, player->eos_timer); + __mmplayer_remove_g_source_from_context(player->context.global_default, player->eos_timer); player->eos_timer = 0; }