From 475f56e0dc3abc3f34d7f323aa804dbff808b5d2 Mon Sep 17 00:00:00 2001 From: Julien Moutte Date: Sun, 20 Apr 2003 21:06:55 +0000 Subject: [PATCH] Made a theorical libgstplay which refs/unrefs elements before putting them in AsyncQueue. Original commit message from CVS: Made a theorical libgstplay which refs/unrefs elements before putting them in AsyncQueue. Added a "pipeline_error" signal which will later allow the player and apps to detect that pipeline was unable to play and why... This version is NOT STABLE AT ALL. it will need fixes in core but i commit it as is so that we fix those problems --- gst-libs/gst/play/play.old.c | 44 ++++++++++++++++++++++++++++++++---- gst-libs/gst/play/play.old.h | 3 +++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/play/play.old.c b/gst-libs/gst/play/play.old.c index 1becf29236..3be0998239 100644 --- a/gst-libs/gst/play/play.old.c +++ b/gst-libs/gst/play/play.old.c @@ -34,6 +34,7 @@ enum { HAVE_VIS_XID, HAVE_VIDEO_SIZE, LAST_SIGNAL, + PIPELINE_ERROR, }; /* this struct is used to decouple signals coming out of threaded pipelines */ @@ -59,6 +60,10 @@ struct _GstPlaySignal GstElement* element; GParamSpec* param; } info; + struct { + GstElement* element; + gchar* error; + } error; } signal_data; }; @@ -338,6 +343,14 @@ gst_play_idle_signal (GstPlay *play) case INFORMATION: g_signal_emit (G_OBJECT (play), gst_play_signals[INFORMATION], 0, signal->signal_data.info.element, signal->signal_data.info.param); + gst_object_unref (GST_OBJECT(signal->signal_data.info.element)); + break; + case PIPELINE_ERROR: + if (gst_element_get_state(play->pipeline) == GST_STATE_PLAYING) + gst_element_set_state(play->pipeline, GST_STATE_READY); + g_signal_emit (G_OBJECT (play), gst_play_signals[PIPELINE_ERROR], 0, + signal->signal_data.error.element, signal->signal_data.error.error); + gst_object_unref (GST_OBJECT(signal->signal_data.error.element)); break; default: break; @@ -428,14 +441,23 @@ callback_bin_post_iterate ( GstBin *bin, } static void -callback_pipeline_error ( GObject *object, - GstObject *orig, +callback_pipeline_error ( GstElement *object, + GstElement *orig, gchar *error, GstPlay* play) { - g_print ("Pipeline error: %s\n", error); - if (gst_element_get_state(play->pipeline) == GST_STATE_PLAYING) - gst_element_set_state(play->pipeline, GST_STATE_READY); + GstPlaySignal *signal; + + signal = g_new0(GstPlaySignal, 1); + signal->signal_id = PIPELINE_ERROR; + signal->signal_data.error.element = orig; + signal->signal_data.error.error = error; + + gst_object_ref (GST_OBJECT(orig)); + + g_async_queue_push(play->signal_queue, signal); + + play->idle_add_func ((GSourceFunc) gst_play_idle_signal, play); } static void @@ -450,6 +472,8 @@ callback_pipeline_deep_notify ( GstElement *element, signal->signal_id = INFORMATION; signal->signal_data.info.element = orig; signal->signal_data.info.param = param; + + gst_object_ref (GST_OBJECT(orig)); g_async_queue_push(play->signal_queue, signal); @@ -577,6 +601,16 @@ gst_play_class_init (GstPlayClass *klass) G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_PARAM); + gst_play_signals [PIPELINE_ERROR] = + g_signal_new ("pipeline_error", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstPlayClass, pipeline_error), + NULL, NULL, + gst_marshal_VOID__OBJECT_PARAM, + G_TYPE_NONE, 2, + G_TYPE_OBJECT, G_TYPE_PARAM); + gst_play_signals [STATE_CHANGE] = g_signal_new ("state_change", G_TYPE_FROM_CLASS (klass), diff --git a/gst-libs/gst/play/play.old.h b/gst-libs/gst/play/play.old.h index 90f9a5ce71..6851b11e34 100644 --- a/gst-libs/gst/play/play.old.h +++ b/gst-libs/gst/play/play.old.h @@ -142,6 +142,9 @@ struct _GstPlayClass void (*information) ( GstPlay* play, GstElement* element, GParamSpec *param); + void (*pipeline_error) ( GstPlay* play, + GstElement* element, + gchar *error); void (*state_changed) ( GstPlay* play, GstElementState old_state, GstElementState new_state);