[0.6.98] Add gst bus watcher for using msg queue 85/179185/3
authorGilbok Lee <gilbok.lee@samsung.com>
Mon, 14 May 2018 11:00:16 +0000 (20:00 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Fri, 18 May 2018 01:54:33 +0000 (10:54 +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 e8e941e46a51b6707c9542dc8a8542e9d31b6a84..58588018fa296e79c33cef334c7b8f11defe331b 100644 (file)
@@ -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
index a05586ca607122fdf902233f7446a5c82e6ff32a..7df59c07a649e879b5b00b317e5098a5378a5b3b 100644 (file)
@@ -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;
index f9f2c3c05255ba576597c854d5977f448df28b23..af6d32ea5103cf70b6f9149b57ef055a2fd10f07 100644 (file)
@@ -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;
        }