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);
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);
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);
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);
/* 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;
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");
/* 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);
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);
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) {
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;
}