mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
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.
This commit is contained in:
parent
3f05db1828
commit
078d7c5e8c
4 changed files with 62 additions and 27 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2005-11-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* 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 <wim@fluendo.com>
|
2005-11-28 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst-libs/gst/audio/TODO:
|
* gst-libs/gst/audio/TODO:
|
||||||
|
|
|
@ -355,6 +355,7 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal, gboolean subtitle)
|
||||||
{
|
{
|
||||||
GstPlayBaseGroup *group;
|
GstPlayBaseGroup *group;
|
||||||
gboolean had_active_group;
|
gboolean had_active_group;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
GROUP_LOCK (play_base_bin);
|
GROUP_LOCK (play_base_bin);
|
||||||
group = play_base_bin->building_group;
|
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);
|
setup_substreams (play_base_bin);
|
||||||
GST_DEBUG ("Emitting signal");
|
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);
|
setup_output_pads (play_base_bin, group);
|
||||||
GST_DEBUG ("done");
|
GST_DEBUG ("done");
|
||||||
|
|
||||||
|
@ -782,6 +783,7 @@ probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data)
|
||||||
GstPlayBaseGroup *group;
|
GstPlayBaseGroup *group;
|
||||||
GstPlayBaseBin *play_base_bin;
|
GstPlayBaseBin *play_base_bin;
|
||||||
GstStreamInfo *info = GST_STREAM_INFO (user_data);
|
GstStreamInfo *info = GST_STREAM_INFO (user_data);
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group");
|
group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group");
|
||||||
play_base_bin = group->bin;
|
play_base_bin = group->bin;
|
||||||
|
@ -837,7 +839,7 @@ probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data)
|
||||||
setup_substreams (play_base_bin);
|
setup_substreams (play_base_bin);
|
||||||
GST_DEBUG ("switching to next group %p - emitting signal", group);
|
GST_DEBUG ("switching to next group %p - emitting signal", group);
|
||||||
/* and signal the new 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);
|
setup_output_pads (play_base_bin, group);
|
||||||
|
|
||||||
GROUP_UNLOCK (play_base_bin);
|
GROUP_UNLOCK (play_base_bin);
|
||||||
|
|
|
@ -92,7 +92,7 @@ struct _GstPlayBaseBinClass {
|
||||||
GstPipelineClass parent_class;
|
GstPipelineClass parent_class;
|
||||||
|
|
||||||
/* virtual fuctions */
|
/* virtual fuctions */
|
||||||
void (*setup_output_pads) (GstPlayBaseBin *play_base_bin,
|
gboolean (*setup_output_pads) (GstPlayBaseBin *play_base_bin,
|
||||||
GstPlayBaseGroup *group);
|
GstPlayBaseGroup *group);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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_init (GstPlayBin * play_bin);
|
||||||
static void gst_play_bin_dispose (GObject * object);
|
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);
|
GstPlayBaseGroup * group);
|
||||||
static void remove_sinks (GstPlayBin * play_bin);
|
static void remove_sinks (GstPlayBin * play_bin);
|
||||||
|
|
||||||
|
@ -762,15 +762,9 @@ static gboolean
|
||||||
add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad)
|
add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad)
|
||||||
{
|
{
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
GstPadLinkReturn res;
|
GstPadLinkReturn linkres;
|
||||||
GstElement *parent;
|
GstElement *parent;
|
||||||
|
GstStateChangeReturn stateret;
|
||||||
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);
|
|
||||||
|
|
||||||
/* this is only for debugging */
|
/* this is only for debugging */
|
||||||
parent = gst_pad_get_parent_element (srcpad);
|
parent = gst_pad_get_parent_element (srcpad);
|
||||||
|
@ -780,30 +774,56 @@ add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad)
|
||||||
gst_object_unref (parent);
|
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 */
|
/* try to link the pad of the sink to the stream */
|
||||||
if (res < 0) {
|
if (GST_PAD_LINK_FAILED (linkres))
|
||||||
gchar *capsstr;
|
goto link_failed;
|
||||||
|
|
||||||
/* could not link this stream */
|
|
||||||
capsstr = gst_caps_to_string (gst_pad_get_caps (srcpad));
|
|
||||||
g_warning ("could not link %s: %d", capsstr, res);
|
|
||||||
g_free (capsstr);
|
|
||||||
|
|
||||||
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
|
/* we got the sink succesfully linked, now keep the sink
|
||||||
* in out internal list */
|
* in out internal list */
|
||||||
play_bin->sinks = g_list_prepend (play_bin->sinks, sink);
|
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 res;
|
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 */
|
||||||
|
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);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group)
|
setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group)
|
||||||
{
|
{
|
||||||
GstPlayBin *play_bin = GST_PLAY_BIN (play_base_bin);
|
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;
|
gboolean need_text = FALSE;
|
||||||
GstPad *textsrcpad = NULL, *textsinkpad = NULL, *pad;
|
GstPad *textsrcpad = NULL, *textsinkpad = NULL, *pad;
|
||||||
GstElement *sink;
|
GstElement *sink;
|
||||||
|
gboolean res = TRUE;
|
||||||
|
|
||||||
/* get rid of existing sinks */
|
/* get rid of existing sinks */
|
||||||
if (play_bin->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,
|
pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
|
||||||
"src");
|
"src");
|
||||||
add_sink (play_bin, sink, pad);
|
res = add_sink (play_bin, sink, pad);
|
||||||
gst_object_unref (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,
|
pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
|
||||||
"src");
|
"src");
|
||||||
add_sink (play_bin, sink, pad);
|
res = add_sink (play_bin, sink, pad);
|
||||||
gst_object_unref (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);
|
gst_bin_remove (GST_BIN (play_bin), play_bin->fakesink);
|
||||||
play_bin->fakesink = NULL;
|
play_bin->fakesink = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send an event to our sinks until one of them works; don't then send to the
|
/* Send an event to our sinks until one of them works; don't then send to the
|
||||||
|
|
Loading…
Reference in a new issue