From 078d7c5e8cfe96cd26c36cf19722d3e25cd90832 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 28 Nov 2005 15:56:03 +0000 Subject: [PATCH] gst/playback/gstplaybasebin.*: Prepare to handle errors betters. Original commit message from CVS: * gst/playback/gstplaybasebin.c: (group_commit), (probe_triggered): * gst/playback/gstplaybasebin.h: Prepare to handle errors betters. * gst/playback/gstplaybin.c: (add_sink), (setup_sinks): Set sinks to PAUSED first before adding and linking them so that we don't interrupt dataflow. --- ChangeLog | 10 ++++++ gst/playback/gstplaybasebin.c | 6 ++-- gst/playback/gstplaybasebin.h | 2 +- gst/playback/gstplaybin.c | 71 ++++++++++++++++++++++++++++--------------- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13b29f3..0e69594 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2005-11-28 Wim Taymans + * gst/playback/gstplaybasebin.c: (group_commit), (probe_triggered): + * gst/playback/gstplaybasebin.h: + Prepare to handle errors betters. + + * gst/playback/gstplaybin.c: (add_sink), (setup_sinks): + Set sinks to PAUSED first before adding and linking them so that + we don't interrupt dataflow. + +2005-11-28 Wim Taymans + * gst-libs/gst/audio/TODO: Updated TODO diff --git a/gst/playback/gstplaybasebin.c b/gst/playback/gstplaybasebin.c index 3033c44..f1c431f 100644 --- a/gst/playback/gstplaybasebin.c +++ b/gst/playback/gstplaybasebin.c @@ -355,6 +355,7 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal, gboolean subtitle) { GstPlayBaseGroup *group; gboolean had_active_group; + gboolean res; GROUP_LOCK (play_base_bin); group = play_base_bin->building_group; @@ -408,7 +409,7 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal, gboolean subtitle) setup_substreams (play_base_bin); GST_DEBUG ("Emitting signal"); - GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)-> + res = GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)-> setup_output_pads (play_base_bin, group); GST_DEBUG ("done"); @@ -782,6 +783,7 @@ probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data) GstPlayBaseGroup *group; GstPlayBaseBin *play_base_bin; GstStreamInfo *info = GST_STREAM_INFO (user_data); + gboolean res; group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group"); play_base_bin = group->bin; @@ -837,7 +839,7 @@ probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data) setup_substreams (play_base_bin); GST_DEBUG ("switching to next group %p - emitting signal", group); /* and signal the new group */ - GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)-> + res = GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)-> setup_output_pads (play_base_bin, group); GROUP_UNLOCK (play_base_bin); diff --git a/gst/playback/gstplaybasebin.h b/gst/playback/gstplaybasebin.h index 32c511f..9576034 100644 --- a/gst/playback/gstplaybasebin.h +++ b/gst/playback/gstplaybasebin.h @@ -92,7 +92,7 @@ struct _GstPlayBaseBinClass { GstPipelineClass parent_class; /* virtual fuctions */ - void (*setup_output_pads) (GstPlayBaseBin *play_base_bin, + gboolean (*setup_output_pads) (GstPlayBaseBin *play_base_bin, GstPlayBaseGroup *group); }; diff --git a/gst/playback/gstplaybin.c b/gst/playback/gstplaybin.c index 1e119f4..389a228 100644 --- a/gst/playback/gstplaybin.c +++ b/gst/playback/gstplaybin.c @@ -95,7 +95,7 @@ static void gst_play_bin_class_init (GstPlayBinClass * klass); static void gst_play_bin_init (GstPlayBin * play_bin); static void gst_play_bin_dispose (GObject * object); -static void setup_sinks (GstPlayBaseBin * play_base_bin, +static gboolean setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group); static void remove_sinks (GstPlayBin * play_bin); @@ -762,15 +762,9 @@ static gboolean add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad) { GstPad *sinkpad; - GstPadLinkReturn res; + GstPadLinkReturn linkres; GstElement *parent; - - gst_bin_add (GST_BIN (play_bin), sink); - - /* we found a sink for this stream, now try to install it */ - sinkpad = gst_element_get_pad (sink, "sink"); - res = gst_pad_link (srcpad, sinkpad); - gst_object_unref (sinkpad); + GstStateChangeReturn stateret; /* this is only for debugging */ parent = gst_pad_get_parent_element (srcpad); @@ -780,30 +774,56 @@ add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad) gst_object_unref (parent); } + /* bring it to the PAUSED state so we can link to the peer without + * breaking the flow */ + if ((stateret = gst_element_set_state (sink, GST_STATE_PAUSED)) == + GST_STATE_CHANGE_FAILURE) + goto state_failed; + + gst_bin_add (GST_BIN (play_bin), sink); + + /* we found a sink for this stream, now try to install it */ + sinkpad = gst_element_get_pad (sink, "sink"); + linkres = gst_pad_link (srcpad, sinkpad); + gst_object_unref (sinkpad); + /* try to link the pad of the sink to the stream */ - if (res < 0) { + if (GST_PAD_LINK_FAILED (linkres)) + goto link_failed; + + /* we got the sink succesfully linked, now keep the sink + * in out internal list */ + play_bin->sinks = g_list_prepend (play_bin->sinks, sink); + + return TRUE; + + /* ERRORS */ +state_failed: + { + GST_DEBUG_OBJECT (play_bin, "state change failure when adding sink"); + return FALSE; + } +link_failed: + { gchar *capsstr; + GstCaps *caps; /* could not link this stream */ - capsstr = gst_caps_to_string (gst_pad_get_caps (srcpad)); - g_warning ("could not link %s: %d", capsstr, res); + caps = gst_pad_get_caps (srcpad); + capsstr = gst_caps_to_string (caps); + g_warning ("could not link %s: %d", capsstr, linkres); + GST_DEBUG_OBJECT (play_bin, + "link failed when adding sink, caps %s, reason %d", capsstr, linkres); g_free (capsstr); + g_free (caps); gst_element_set_state (sink, GST_STATE_NULL); gst_bin_remove (GST_BIN (play_bin), sink); - } else { - /* we got the sink succesfully linked, now keep the sink - * in out internal list */ - play_bin->sinks = g_list_prepend (play_bin->sinks, sink); - gst_element_set_state (sink, - (GST_STATE (play_bin) == GST_STATE_PLAYING) ? - GST_STATE_PLAYING : GST_STATE_PAUSED); + return FALSE; } - - return res; } -static void +static gboolean setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) { GstPlayBin *play_bin = GST_PLAY_BIN (play_base_bin); @@ -812,6 +832,7 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) gboolean need_text = FALSE; GstPad *textsrcpad = NULL, *textsinkpad = NULL, *pad; GstElement *sink; + gboolean res = TRUE; /* get rid of existing sinks */ if (play_bin->sinks) { @@ -849,7 +870,7 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) } pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, "src"); - add_sink (play_bin, sink, pad); + res = add_sink (play_bin, sink, pad); gst_object_unref (pad); } @@ -870,7 +891,7 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) } pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, "src"); - add_sink (play_bin, sink, pad); + res = add_sink (play_bin, sink, pad); gst_object_unref (pad); } @@ -881,6 +902,8 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group) gst_bin_remove (GST_BIN (play_bin), play_bin->fakesink); play_bin->fakesink = NULL; } + + return res; } /* Send an event to our sinks until one of them works; don't then send to the -- 2.7.4