+2005-05-25 Wim Taymans <wim@fluendo.com>
+
+ * gst/playback/gstdecodebin.c: (gst_decode_bin_init),
+ (gst_decode_bin_dispose), (try_to_link_1), (get_our_ghost_pad),
+ (remove_element_chain), (no_more_pads), (unlinked), (close_link),
+ (type_found):
+ * gst/playback/gstplaybasebin.c: (gst_play_base_bin_dispose),
+ (group_destroy), (group_commit), (queue_overrun),
+ (gen_preroll_element), (no_more_pads), (preroll_unlinked),
+ (mute_stream), (new_decoded_pad), (setup_substreams),
+ (setup_source), (mute_group_type), (set_active_source),
+ (gst_play_base_bin_change_state):
+ * gst/playback/gstplaybin.c: (gst_play_bin_dispose),
+ (gen_video_element), (gen_text_element), (gen_audio_element),
+ (gen_vis_element), (remove_sinks), (add_sink), (setup_sinks):
+ * gst/playback/gststreaminfo.c: (gst_stream_info_new),
+ (gst_stream_info_dispose), (gst_stream_info_set_mute):
+ * gst/playback/gststreamselector.c: (gst_stream_selector_chain):
+ Some playbin cleanups mostly refcounting sloppyness.
+
2005-05-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet):
if (!decode_bin->typefind) {
g_warning ("can't find typefind element, decodebin will not work");
} else {
+ GstPad *pad;
+
/* add the typefind element */
gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind);
+
+ /* get the sinkpad */
+ pad = gst_element_get_pad (decode_bin->typefind, "sink");
+
/* ghost the sink pad to ourself */
- gst_element_add_ghost_pad (GST_ELEMENT (decode_bin),
- gst_element_get_pad (decode_bin->typefind, "sink"), "sink");
+ gst_element_add_ghost_pad (GST_ELEMENT (decode_bin), pad, "sink");
+
+ gst_object_unref (GST_OBJECT_CAST (pad));
/* connect a signal to find out when the typefind element found
* a type */
decode_bin->dynamics = NULL;
}
+static void dynamic_free (GstDynamic * dyn);
+
static void
gst_decode_bin_dispose (GObject * object)
{
for (dyns = decode_bin->dynamics; dyns; dyns = g_list_next (dyns)) {
GstDynamic *dynamic = (GstDynamic *) dyns->data;
- g_free (dynamic);
+ dynamic_free (dynamic);
}
g_list_free (decode_bin->dynamics);
decode_bin->dynamics = NULL;
- if (G_OBJECT_CLASS (parent_class)->dispose) {
- G_OBJECT_CLASS (parent_class)->dispose (object);
- }
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static GstDynamic *
try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
{
GList *walk;
+ GstElement *result = NULL;
/* loop over the factories */
for (walk = factories; walk; walk = g_list_next (walk)) {
GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
GstElement *element;
GstPadLinkReturn ret;
+ GstPad *sinkpad;
GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
/* make an element from the factory first */
- element = gst_element_factory_create (factory, NULL);
- if (element == NULL) {
+ if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
/* hmm, strange. Like with all things in live, let's move on.. */
GST_WARNING_OBJECT (decode_bin, "could not create an element from %s",
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
continue;
}
+ /* try to link the given pad to a sinkpad */
+ /* FIXME, find the sinkpad by looping over the pads instead of
+ * looking it up by name */
+ if ((sinkpad = gst_element_get_pad (element, "sink")) == NULL) {
+ /* if no pad is found we can't do anything */
+ GST_WARNING_OBJECT (decode_bin, "could not find sinkpad in element");
+ continue;
+ }
+
/* now add the element to the bin first */
- GST_DEBUG_OBJECT (decode_bin, "adding %s", gst_element_get_name (element));
+ GST_DEBUG_OBJECT (decode_bin, "adding %s", GST_OBJECT_NAME (element));
gst_bin_add (GST_BIN (decode_bin), element);
/* set to ready first so it is ready */
/* keep our own list of elements */
decode_bin->elements = g_list_prepend (decode_bin->elements, element);
- /* try to link the given pad to a sinkpad */
- /* FIXME, find the sinkpad by looping over the pads instead of
- * looking it up by name */
- ret = gst_pad_link (pad, gst_element_get_pad (element, "sink"));
- if (ret == GST_PAD_LINK_OK) {
+ if ((ret = gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
+ GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s, reason %d",
+ GST_DEBUG_PAD_NAME (pad), ret);
+ /* get rid of the sinkpad */
+ gst_object_unref (GST_OBJECT_CAST (sinkpad));
+ /* this element did not work, remove it again and continue trying
+ * other elements, the element will be disposed. */
+ gst_bin_remove (GST_BIN (decode_bin), element);
+ } else {
const gchar *klass;
GstElementFactory *factory;
guint sig;
/* The link worked, now figure out what it was that we connected */
factory = gst_element_get_factory (element);
klass = gst_element_factory_get_klass (factory);
+
/* check if we can use threads */
if (decode_bin->threaded) {
if (strstr (klass, "Demux") != NULL) {
}
/* make sure we catch unlink signals */
- sig = g_signal_connect (G_OBJECT (GST_PAD_REALIZE (pad)), "unlinked",
+ sig = g_signal_connect (G_OBJECT (pad), "unlinked",
G_CALLBACK (unlinked), decode_bin);
+
/* keep a ref to the signal id so that we can disconnect the signal callback */
g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (sig));
close_link (element, decode_bin);
/* change the state of the element to that of the parent */
gst_element_set_state (element, GST_STATE_PAUSED);
- return element;
- } else {
- GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s",
- GST_DEBUG_PAD_NAME (pad));
- /* this element did not work, remove it again and continue trying
- * other elements */
- gst_bin_remove (GST_BIN (decode_bin), element);
+
+ result = element;
+
+ /* get rid of the sinkpad now */
+ gst_object_unref (GST_OBJECT_CAST (sinkpad));
+
+ /* and exit */
+ goto done;
}
}
- return NULL;
+done:
+ return result;
}
static GstPad *
get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
{
+#if 0
GList *ghostpads;
if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
if (GST_IS_GHOST_PAD (pad)) {
GstElement *parent = gst_pad_get_parent (pad);
- GST_DEBUG_OBJECT (decode_bin, "pad parent %s",
- gst_element_get_name (parent));
+ GST_DEBUG_OBJECT (decode_bin, "pad parent %s", GST_ELEMENT_NAME (parent));
if (parent == GST_ELEMENT (decode_bin)) {
GST_DEBUG_OBJECT (decode_bin, "pad is our ghostpad");
ghostpads = g_list_next (ghostpads);
}
GST_DEBUG_OBJECT (decode_bin, "done looping over ghostpads, nothing found");
+#endif
return NULL;
}
static void
remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
{
- GList *int_links;
+ GList *int_links, *walk;
GstElement *elem = GST_ELEMENT (GST_OBJECT_PARENT (pad));
while (GST_OBJECT_PARENT (elem) &&
elem = GST_ELEMENT (GST_OBJECT_PARENT (elem));
GST_DEBUG_OBJECT (decode_bin, "%s:%s", GST_DEBUG_PAD_NAME (pad));
+ int_links = gst_pad_get_internal_links (pad);
/* remove all elements linked to this pad up to the ghostpad
* that we created for this stream */
- for (int_links = gst_pad_get_internal_links (pad);
- int_links; int_links = g_list_next (int_links)) {
+ for (walk = int_links; walk; walk = g_list_next (walk)) {
GstPad *pad;
GstPad *ghostpad;
GstPad *peer;
- pad = GST_PAD (int_links->data);
+ pad = GST_PAD (walk->data);
GST_DEBUG_OBJECT (decode_bin, "inspecting internal pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
{
- GstElement *parent = gst_pad_get_real_parent (peer);
+ GstElement *parent = gst_pad_get_parent (peer);
if (parent != GST_ELEMENT (decode_bin)) {
GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s",
GST_DEBUG_PAD_NAME (peer));
} else {
GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
- gst_element_get_name (elem), GST_DEBUG_PAD_NAME (pad));
+ GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
remove_element_chain (decode_bin, peer);
}
gst_object_unref (GST_OBJECT_CAST (parent));
}
+ gst_object_unref (GST_OBJECT_CAST (peer));
}
- GST_DEBUG_OBJECT (decode_bin, "removing %s", gst_element_get_name (elem));
+ GST_DEBUG_OBJECT (decode_bin, "removing %s", GST_ELEMENT_NAME (elem));
+
+ g_list_free (int_links);
+
gst_bin_remove (GST_BIN (decode_bin), elem);
}
GstDecodeBin *decode_bin = dynamic->decode_bin;
GST_DEBUG_OBJECT (decode_bin, "no more pads on element %s",
- gst_element_get_name (element));
+ GST_ELEMENT_NAME (element));
/* remove the element from the list of dynamic elements */
decode_bin->dynamics = g_list_remove (decode_bin->dynamics, dynamic);
GstElement *element;
/* inactivate pad */
- gst_pad_set_active (pad, FALSE);
+ gst_pad_set_active (pad, GST_ACTIVATE_NONE);
/* remove all elements linked to the peerpad */
remove_element_chain (decode_bin, peerpad);
gboolean more;
GST_DEBUG_OBJECT (decode_bin, "closing links with element %s",
- gst_element_get_name (element));
+ GST_ELEMENT_NAME (element));
/* loop over all the padtemplates */
for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
/* now loop over all the pads we need to connect */
for (pads = to_connect; pads; pads = g_list_next (pads)) {
- GstPad *pad = GST_PAD (pads->data);
+ GstPad *pad = GST_PAD_CAST (pads->data);
GstCaps *caps;
/* we have more pads if we have more than 1 pad to connect or
more |= gst_decode_bin_is_dynamic (decode_bin);
GST_DEBUG_OBJECT (decode_bin, "closing pad link for %s",
- gst_pad_get_name (pad));
+ GST_OBJECT_NAME (pad));
/* continue autoplugging on the pads */
caps = gst_pad_get_caps (pad);
close_pad_link (element, pad, caps, decode_bin, more);
if (caps)
gst_caps_unref (caps);
- }
+ gst_object_unref (GST_OBJECT_CAST (pad));
+ }
g_list_free (to_connect);
}
/* autoplug the new pad with the caps that the signal gave us. */
pad = gst_element_get_pad (typefind, "src");
close_pad_link (typefind, pad, caps, decode_bin, FALSE);
- gst_object_unref (GST_OBJECT (pad));
+ gst_object_unref (GST_OBJECT_CAST (pad));
dynamic = gst_decode_bin_is_dynamic (decode_bin);
if (dynamic == FALSE) {
g_free (play_base_bin->suburi);
play_base_bin->suburi = NULL;
- if (G_OBJECT_CLASS (parent_class)->dispose) {
- G_OBJECT_CLASS (parent_class)->dispose (object);
- }
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
fakesrc = (GstElement *) g_object_get_data (G_OBJECT (pad), "fakesrc");
if (fakesrc != NULL) {
GST_LOG ("removing fakesrc from %s:%s",
- gst_pad_get_name (pad),
- GST_ELEMENT_NAME (gst_pad_get_parent (pad)));
+ GST_PAD_NAME (pad), GST_ELEMENT_NAME (gst_pad_get_parent (pad)));
gst_bin_remove (GST_BIN (play_base_bin), fakesrc);
}
}
/* if the group is currently being played, we have to remove the element
* from the thread */
if (get_active_group (play_base_bin) == group) {
- GST_LOG ("removing preroll element %s", gst_element_get_name (element));
+ GST_LOG ("removing preroll element %s", GST_ELEMENT_NAME (element));
gst_bin_remove (group->type[n].bin, element);
gst_bin_remove (group->type[n].bin, group->type[n].selector);
} else {
sig_id =
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (element), "signal_id"));
- GST_LOG ("removing preroll signal %s", gst_element_get_name (element));
+ GST_LOG ("removing preroll signal %s", GST_ELEMENT_NAME (element));
g_signal_handler_disconnect (G_OBJECT (element), sig_id);
}
}
static void
queue_overrun (GstElement * element, GstPlayBaseBin * play_base_bin)
{
- GST_DEBUG ("queue %s overrun", gst_element_get_name (element));
+ GST_DEBUG ("queue %s overrun", GST_ELEMENT_NAME (element));
group_commit (play_base_bin, FALSE, FALSE);
GstStreamInfo * info)
{
GstElement *selector, *preroll;
- gchar *name;
+ gchar *name, *padname;
const gchar *prename;
guint sig;
GstPad *preroll_pad;
g_return_if_reached ();
/* create stream selector */
- name = g_strdup_printf ("selector_%s_%s", prename, gst_pad_get_name (pad));
+ padname = gst_pad_get_name (pad);
+ name = g_strdup_printf ("selector_%s_%s", prename, padname);
selector = g_object_new (GST_TYPE_STREAM_SELECTOR, NULL);
gst_object_set_name (GST_OBJECT (selector), name);
g_free (name);
/* create preroll queue */
- name = g_strdup_printf ("preroll_%s_%s", prename, gst_pad_get_name (pad));
+ name = g_strdup_printf ("preroll_%s_%s", prename, padname);
preroll = gst_element_factory_make ("queue", name);
+ g_free (padname);
+ g_free (name);
+
g_object_set (G_OBJECT (preroll),
"max-size-buffers", 0, "max-size-bytes",
((type == GST_STREAM_TYPE_VIDEO) ? 25 : 1) * 1024 * 1024,
"max-size-time", play_base_bin->queue_size, NULL);
+
sig = g_signal_connect (G_OBJECT (preroll), "overrun",
G_CALLBACK (queue_overrun), play_base_bin);
+
if (play_base_bin->is_stream &&
((type == GST_STREAM_TYPE_VIDEO &&
group->type[GST_STREAM_TYPE_AUDIO - 1].npads == 0) ||
/* keep a ref to the signal id so that we can disconnect the signal callback
* when we are done with the preroll */
g_object_set_data (G_OBJECT (preroll), "signal_id", GINT_TO_POINTER (sig));
- g_free (name);
/* listen for EOS */
preroll_pad = gst_element_get_pad (preroll, "src");
probe = gst_probe_new (FALSE, probe_triggered, info);
/* have to REALIZE the pad as we cannot attach a padprobe to a ghostpad */
gst_pad_add_probe (preroll_pad, probe);
+ gst_object_unref (GST_OBJECT_CAST (preroll_pad));
/* add to group list */
- gst_element_link (selector, preroll);
+ /* FIXME refcount elements */
group->type[type - 1].selector = selector;
group->type[type - 1].preroll = preroll;
if (type == GST_STREAM_TYPE_TEXT && play_base_bin->subtitle) {
group->type[type - 1].bin = GST_BIN (play_base_bin->subtitle);
gst_bin_add (GST_BIN (play_base_bin->subtitle), selector);
gst_bin_add (GST_BIN (play_base_bin->subtitle), preroll);
- gst_element_set_state (selector,
- GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
- GST_STATE_PLAYING : GST_STATE_PAUSED);
} else {
group->type[type - 1].bin = GST_BIN (play_base_bin);
gst_bin_add (GST_BIN (play_base_bin), selector);
gst_bin_add (GST_BIN (play_base_bin), preroll);
- gst_element_set_state (selector,
- GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
- GST_STATE_PLAYING : GST_STATE_PAUSED);
}
+ gst_element_link (selector, preroll);
+ gst_element_set_state (selector,
+ GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
+ GST_STATE_PLAYING : GST_STATE_PAUSED);
gst_element_set_state (preroll,
GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
GST_STATE_PLAYING : GST_STATE_PAUSED);
/* we can commit this group for playback now */
group_commit (play_base_bin, play_base_bin->is_stream,
- gst_object_get_parent (GST_OBJECT (element)) ==
+ GST_OBJECT_PARENT (GST_OBJECT_CAST (element)) ==
GST_OBJECT (play_base_bin->subtitle));
}
{
GstElement *fakesrc;
guint sig_id;
+ GstPad *srcpad;
/* make a fakesrc that will just emit one EOS */
fakesrc = gst_element_factory_make ("fakesrc", NULL);
GST_DEBUG ("patching unlinked pad %s:%s", GST_DEBUG_PAD_NAME (pad));
- gst_pad_link (gst_element_get_pad (fakesrc, "src"), pad);
+ srcpad = gst_element_get_pad (fakesrc, "src");
gst_bin_add (GST_BIN (play_base_bin), fakesrc);
+ gst_pad_link (srcpad, pad);
+ gst_object_unref (GST_OBJECT_CAST (srcpad));
/* keep track of these patch elements */
g_object_set_data (G_OBJECT (pad), "fakesrc", fakesrc);
if (GST_IS_BUFFER (*d)) {
g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
- gst_pad_remove_probe ((GstPad *) GST_PAD_REALIZE (info->object), probe);
+ gst_pad_remove_probe (GST_PAD_CAST (info->object), probe);
gst_probe_destroy (probe);
}
GstPlayBaseGroup *group;
GstProbe *probe;
guint sig;
+ GstObject *parent;
GST_DEBUG ("play base: new decoded pad %d", last);
/* first see if this pad has interesting caps */
caps = gst_pad_get_caps (pad);
- if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
- g_warning ("no type on pad %s:%s",
- GST_DEBUG_PAD_NAME (GST_PAD_REALIZE (pad)));
- if (caps)
- gst_caps_unref (caps);
- return;
- }
+ if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
+ goto no_type;
/* get the mime type */
structure = gst_caps_get_structure (caps, 0);
group->nstreams++;
+ parent = gst_object_get_parent (GST_OBJECT (element));
if (g_str_has_prefix (mimetype, "audio/") &&
- gst_object_get_parent (GST_OBJECT (element)) !=
- GST_OBJECT (play_base_bin->subtitle)) {
+ parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
type = GST_STREAM_TYPE_AUDIO;
} else if (g_str_has_prefix (mimetype, "video/") &&
- gst_object_get_parent (GST_OBJECT (element)) !=
- GST_OBJECT (play_base_bin->subtitle)) {
+ parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
type = GST_STREAM_TYPE_VIDEO;
} else if (g_str_has_prefix (mimetype, "text/")) {
type = GST_STREAM_TYPE_TEXT;
} else {
type = GST_STREAM_TYPE_UNKNOWN;
}
+ gst_object_unref (parent);
info = gst_stream_info_new (GST_OBJECT (pad), type, NULL, caps);
if (type > 0 && type <= NUM_TYPES) {
/* select 1st for now - we'll select a preferred one after preroll */
if (type == GST_STREAM_TYPE_UNKNOWN || group->type[type - 1].npads > 0) {
probe = gst_probe_new (FALSE, silence_stream, info);
- gst_pad_add_probe (GST_PAD_REALIZE (pad), probe);
+ gst_pad_add_probe (GST_PAD_CAST (pad), probe);
g_object_set_data (G_OBJECT (pad), "eat_probe", probe);
}
/* signal the no more pads after adding the stream */
if (last)
no_more_pads (element, play_base_bin);
+
+ return;
+
+no_type:
+ {
+ g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+ if (caps)
+ gst_caps_unref (caps);
+ return;
+ }
}
probe = g_object_get_data (G_OBJECT (info->object), "eat_probe");
if (probe) {
- gst_pad_remove_probe (GST_PAD_REALIZE (info->object), probe);
+ gst_pad_remove_probe (GST_PAD_CAST (info->object), probe);
gst_probe_destroy (probe);
}
GstProbe *probe;
probe = gst_probe_new (FALSE, mute_stream, info);
- gst_pad_add_probe (GST_PAD_REALIZE (info->object), probe);
+ gst_pad_add_probe (GST_PAD_CAST (info->object), probe);
}
}
}
/* create and configure an element that can handle the uri */
- play_base_bin->source = gen_source_element (play_base_bin, &subbin);
- if (!play_base_bin->source) {
- gchar *prot;
-
- /* whoops, could not create the source element */
- prot = gst_uri_get_protocol (play_base_bin->uri);
- if (prot) {
- g_set_error (error, 0, 0, "No URI handler implemented for \"%s\"", prot);
- g_free (prot);
- } else {
- g_set_error (error, 0, 0, "Invalid URI \"%s\"", play_base_bin->uri);
- }
- GST_WARNING ("don't know how to read %s", play_base_bin->uri);
- return FALSE;
- }
+ if (!(play_base_bin->source = gen_source_element (play_base_bin, &subbin)))
+ goto no_source;
gst_bin_add (GST_BIN (play_base_bin), play_base_bin->source);
g_object_notify (G_OBJECT (play_base_bin), "source");
+
/* state will be merged later - if file is not found, error will be
* handled by the application right after. */
}
/* now create the decoder element */
- play_base_bin->decoder = gst_element_factory_make ("decodebin", "decoder");
- if (!play_base_bin->decoder) {
- g_set_error (error, 0, 0, "Could not create autoplugger element");
- GST_WARNING ("can't find decoder element");
- return FALSE;
- }
+ if (!(play_base_bin->decoder =
+ gst_element_factory_make ("decodebin", "decoder")))
+ goto no_decodebin;
+
gst_bin_add (GST_BIN (play_base_bin), play_base_bin->decoder);
- if (!gst_element_link (play_base_bin->source, play_base_bin->decoder)) {
- g_set_error (error, 0, 0, "Could not link source and autoplugger");
- GST_WARNING ("can't link source to decoder element");
- return FALSE;
- }
+
+ if (!gst_element_link (play_base_bin->source, play_base_bin->decoder))
+ goto could_not_link;
/* set up callbacks to create the links between decoded data
* and video/audio/subtitle rendering/output. */
play_base_bin->need_rebuild = FALSE;
return TRUE;
+
+ /* ERRORS */
+no_source:
+ {
+ gchar *prot;
+
+ /* whoops, could not create the source element */
+ prot = gst_uri_get_protocol (play_base_bin->uri);
+ if (prot) {
+ g_set_error (error, 0, 0, "No URI handler implemented for \"%s\"", prot);
+ g_free (prot);
+ } else {
+ g_set_error (error, 0, 0, "Invalid URI \"%s\"", play_base_bin->uri);
+ }
+ GST_WARNING ("don't know how to read %s", play_base_bin->uri);
+ return FALSE;
+ }
+no_decodebin:
+ {
+ g_set_error (error, 0, 0, "Could not create autoplugger element");
+ GST_WARNING ("can't find decoder element");
+ return FALSE;
+ }
+could_not_link:
+ {
+ g_set_error (error, 0, 0, "Could not link source and autoplugger");
+ GST_WARNING ("can't link source to decoder element");
+ return FALSE;
+ }
}
static void
mute_group_type (GstPlayBaseGroup * group, GstStreamType type, gboolean mute)
{
gboolean active = !mute;
-
- gst_pad_set_active (gst_element_get_pad (group->type[type - 1].preroll,
- "src"), active);
- gst_pad_set_active (gst_element_get_pad (group->type[type - 1].preroll,
- "sink"), active);
- gst_pad_set_active (gst_element_get_pad (group->type[type - 1].selector,
- "src"), active);
+ GstPad *pad;
+
+ pad = gst_element_get_pad (group->type[type - 1].preroll, "src");
+ gst_pad_set_active (pad, active);
+ gst_object_unref (GST_OBJECT_CAST (pad));
+ pad = gst_element_get_pad (group->type[type - 1].preroll, "sink");
+ gst_pad_set_active (pad, active);
+ gst_object_unref (GST_OBJECT_CAST (pad));
+ pad = gst_element_get_pad (group->type[type - 1].selector, "src");
+ gst_pad_set_active (pad, active);
+ gst_object_unref (GST_OBJECT_CAST (pad));
if (mute) {
g_signal_connect (group->type[type - 1].preroll, "state-change",
GstProbe *probe;
probe = gst_probe_new (FALSE, mute_stream, info);
- gst_pad_add_probe (GST_PAD_REALIZE (info->object), probe);
+ gst_pad_add_probe (GST_PAD_CAST (info->object), probe);
}
num++;
}
static GstElementStateReturn
gst_play_base_bin_change_state (GstElement * element)
{
- GstElementStateReturn ret = GST_STATE_SUCCESS;
+ GstElementStateReturn ret;
GstPlayBaseBin *play_base_bin;
gint transition = GST_STATE_TRANSITION (element);
gchar *new_location = NULL;
+ GError *error = NULL;
play_base_bin = GST_PLAY_BASE_BIN (element);
switch (transition) {
case GST_STATE_READY_TO_PAUSED:
- {
- GError *error = NULL;
-
- if (!setup_source (play_base_bin, &new_location, &error) || error != NULL) {
- if (!error) {
- /* opening failed but no error - hellup */
- GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM,
- NOT_IMPLEMENTED,
- ("cannot open file \"%s\"", play_base_bin->uri), (NULL));
- } else {
- /* just copy the cached error - type doesn't matter */
- GST_ELEMENT_ERROR (play_base_bin, STREAM, TOO_LAZY,
- (error->message), (NULL));
- g_error_free (error);
- }
- ret = GST_STATE_FAILURE;
- play_base_bin->need_rebuild = TRUE;
- }
+ if (!setup_source (play_base_bin, &new_location, &error) || error != NULL)
+ goto source_failed;
break;
- }
default:
break;
}
- if (ret != GST_STATE_SUCCESS) {
- return ret;
- } else {
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
- }
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
switch (transition) {
case GST_STATE_READY_TO_PAUSED:
default:
break;
}
-
return ret;
+
+ /* ERRORS */
+source_failed:
+ {
+ if (!error) {
+ /* opening failed but no error - hellup */
+ GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM,
+ NOT_IMPLEMENTED,
+ ("cannot open file \"%s\"", play_base_bin->uri), (NULL));
+ } else {
+ /* just copy the cached error - type doesn't matter */
+ GST_ELEMENT_ERROR (play_base_bin, STREAM, TOO_LAZY,
+ (error->message), (NULL));
+ g_error_free (error);
+ }
+ play_base_bin->need_rebuild = TRUE;
+
+ return GST_STATE_FAILURE;
+ }
}
const GList *
g_free (play_bin->font_desc);
play_bin->font_desc = NULL;
- if (G_OBJECT_CLASS (parent_class)->dispose) {
- G_OBJECT_CLASS (parent_class)->dispose (object);
- }
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
pad = gst_element_get_pad (identity, "sink");
gst_element_add_ghost_pad (element, pad, "sink");
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
gst_element_set_state (element, GST_STATE_READY);
pad = gst_element_get_pad (overlay, "text_sink");
gst_element_add_ghost_pad (element, pad, "text_sink");
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
pad = gst_element_get_pad (csp, "sink");
gst_element_add_ghost_pad (element, pad, "sink");
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
return element;
}
pad = gst_element_get_pad (conv, "sink");
gst_element_add_ghost_pad (element, pad, "sink");
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
gst_element_set_state (element, GST_STATE_READY);
pad = gst_element_get_pad (aqueue, "sink");
rpad = gst_element_get_request_pad (tee, "src%d");
gst_pad_link (rpad, pad);
- g_object_unref (G_OBJECT (rpad));
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (rpad));
+ gst_object_unref (GST_OBJECT (pad));
gst_element_link_pads (aqueue, "src", asink, "sink");
pad = gst_element_get_pad (conv, "sink");
rpad = gst_element_get_request_pad (tee, "src%d");
gst_pad_link (rpad, pad);
- g_object_unref (G_OBJECT (rpad));
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (rpad));
+ gst_object_unref (GST_OBJECT (pad));
pad = gst_element_get_pad (tee, "sink");
gst_element_add_ghost_pad (element, pad, "sink");
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
return element;
}
/* we remove the element from the parent so that
* there is no unwanted state change when the parent
* is disposed */
+ play_bin->sinks = g_list_remove (play_bin->sinks, element);
gst_bin_remove (GST_BIN (parent), element);
- g_object_unref (G_OBJECT (parent));
+ gst_object_unref (GST_OBJECT (parent));
}
}
element = g_hash_table_lookup (play_bin->cache, "vbin");
if (element != NULL) {
parent = gst_element_get_parent (element);
if (parent != NULL) {
+ play_bin->sinks = g_list_remove (play_bin->sinks, element);
gst_bin_remove (GST_BIN (parent), element);
- g_object_unref (G_OBJECT (parent));
+ gst_object_unref (GST_OBJECT (parent));
}
}
for (sinks = play_bin->sinks; sinks; sinks = g_list_next (sinks)) {
GstElement *element = GST_ELEMENT (sinks->data);
- GstPad *pad = gst_element_get_pad (element, "sink");
+ GstPad *pad;
+ GstPad *peer;
+
+ pad = gst_element_get_pad (element, "sink");
GST_LOG ("removing sink %p", element);
- if (GST_PAD_PEER (pad))
- gst_pad_unlink (GST_PAD_PEER (pad), pad);
- g_object_unref (G_OBJECT (pad));
+
+ peer = gst_pad_get_peer (pad);
+ if (peer) {
+ gst_pad_unlink (peer, pad);
+ gst_object_unref (GST_OBJECT (peer));
+ }
+ gst_object_unref (GST_OBJECT (pad));
+
gst_bin_remove (GST_BIN (play_bin), element);
}
g_list_free (play_bin->sinks);
/* 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);
- g_object_unref (G_OBJECT (sinkpad));
+ gst_object_unref (GST_OBJECT (sinkpad));
parent = gst_pad_get_parent (srcpad);
GST_DEBUG ("Adding sink with state %d (parent: %d, peer: %d)\n",
GST_STATE (sink), GST_STATE (play_bin), GST_STATE (parent));
- g_object_unref (G_OBJECT (parent));
+ gst_object_unref (GST_OBJECT (parent));
/* try to link the pad of the sink to the stream */
if (res < 0) {
pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
"src");
add_sink (play_bin, sink, pad);
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
}
/* link video */
gst_element_get_pad (group->type[GST_STREAM_TYPE_TEXT - 1].preroll,
"src");
gst_pad_link (textsrcpad, textsinkpad);
- g_object_unref (G_OBJECT (textsinkpad));
- g_object_unref (G_OBJECT (textsrcpad));
+ gst_object_unref (GST_OBJECT (textsinkpad));
+ gst_object_unref (GST_OBJECT (textsrcpad));
} else {
sink = gen_video_element (play_bin);
}
pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
"src");
add_sink (play_bin, sink, pad);
- g_object_unref (G_OBJECT (pad));
+ gst_object_unref (GST_OBJECT (pad));
}
if (play_bin->fakesink) {
GstProbe *probe;
probe = gst_probe_new (FALSE, cb_probe, info);
- gst_pad_add_probe (GST_PAD_REALIZE (object), probe);
+ gst_pad_add_probe (GST_PAD_CAST (object), probe);
}
info->object = object;
info->type = type;
GstElement *parent;
parent = gst_pad_get_parent ((GstPad *)
- GST_PAD_REALIZE (stream_info->object));
+ GST_PAD_CAST (stream_info->object));
if (parent != NULL) {
g_signal_handlers_disconnect_by_func (parent,
G_CALLBACK (stream_info_change_state), stream_info);
stream_info->mute = mute;
//gst_pad_set_active_recursive ((GstPad *)
- //GST_PAD_REALIZE (stream_info->object), !mute);
+ //GST_PAD_CAST (stream_info->object), !mute);
g_warning ("FIXME");
element = gst_pad_get_parent ((GstPad *)
- GST_PAD_REALIZE (stream_info->object));
+ GST_PAD_CAST (stream_info->object));
if (mute) {
g_signal_connect (element, "state-change",
G_CALLBACK (stream_info_change_state), stream_info);
GstStreamSelector *sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
GstFlowReturn res;
- GST_STREAM_LOCK (pad);
-
/* first, check if the active pad changed. If so, redo
* negotiation and fail if that fails. */
if (pad != sel->last_active_sinkpad) {
"buf", gst_pad_get_name (pad));
res = gst_pad_push (sel->srcpad, buf);
- GST_STREAM_UNLOCK (pad);
-
return res;
}