[0.6.112] Add gst bus watcher for using msg queue 85/178885/5
authorGilbok Lee <gilbok.lee@samsung.com>
Mon, 14 May 2018 11:00:16 +0000 (20:00 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Wed, 23 May 2018 10:14:09 +0000 (19:14 +0900)
reduces msg handling delays in msg thread

Change-Id: Ia1dbac8687d6cd70a533e5d2a0600726f0515632

packaging/libmm-player.spec
src/include/mm_player_priv.h
src/mm_player_priv.c

index 5e0af8a..f0c1fc3 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.111
+Version:    0.6.112
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index e98fd76..1e58ffa 100644 (file)
@@ -450,6 +450,11 @@ typedef struct {
 } MMPlayerSetMode;
 
 typedef struct {
+       GMainContext *global_default;
+       GMainContext *thread_default;
+} MMPlayerGMainContext;
+
+typedef struct {
        gint uri_idx;
        GList *uri_list;
 } MMPlayerUriList;
@@ -725,7 +730,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;
index c1554b6..3bba785 100755 (executable)
@@ -961,6 +961,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);
@@ -982,9 +984,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);
@@ -1008,13 +1038,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);
@@ -6847,6 +6877,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);
 
@@ -6968,6 +7008,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;
@@ -8209,6 +8253,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");
@@ -8299,6 +8350,8 @@ ERROR:
        /* free update tag lock */
        g_mutex_clear(&player->update_tag_lock);
 
+       g_queue_free(player->bus_msg_q);
+
        /* free next play thread */
        if (player->next_play_thread) {
                MMPLAYER_NEXT_PLAY_THREAD_LOCK(player);
@@ -8528,6 +8581,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);
@@ -11760,8 +11815,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) {
@@ -11777,7 +11832,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;
        }