mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
gst/playback/gstdecodebin.c: Make decodebin reusable by fixing remove_element_chain first and then introduce a cleane...
Original commit message from CVS: * gst/playback/gstdecodebin.c: (get_our_ghost_pad), (remove_element_chain), (cleanup_decodebin), (gst_decode_bin_change_state): Make decodebin reusable by fixing remove_element_chain first and then introduce a cleaner in state change to ->NULL. (Closes #331678) ------------------------------------------------------
This commit is contained in:
parent
5e42c46657
commit
6f9edeac69
2 changed files with 136 additions and 36 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2006-02-20 Julien MOUTTE <julien@moutte.net>
|
||||||
|
|
||||||
|
* gst/playback/gstdecodebin.c: (get_our_ghost_pad),
|
||||||
|
(remove_element_chain), (cleanup_decodebin),
|
||||||
|
(gst_decode_bin_change_state): Make decodebin reusable by
|
||||||
|
fixing remove_element_chain first and then introduce a
|
||||||
|
cleaner in state change to ->NULL. (Closes #331678)
|
||||||
|
|
||||||
2006-02-19 Wim Taymans <wim@fluendo.com>
|
2006-02-19 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* ext/gnomevfs/gstgnomevfssink.c: (gst_gnome_vfs_sink_open_file):
|
* ext/gnomevfs/gstgnomevfssink.c: (gst_gnome_vfs_sink_open_file):
|
||||||
|
|
|
@ -853,45 +853,55 @@ done:
|
||||||
static GstPad *
|
static GstPad *
|
||||||
get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
|
get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
|
||||||
{
|
{
|
||||||
#if 0
|
GstIterator *pad_it = NULL;
|
||||||
GList *ghostpads;
|
GstPad *db_pad = NULL;
|
||||||
|
gboolean done = FALSE;
|
||||||
|
|
||||||
if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
|
if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
|
||||||
GST_DEBUG_OBJECT (decode_bin, "pad NULL or not SRC pad");
|
GST_DEBUG_OBJECT (decode_bin, "pad NULL or not SRC pad");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_IS_GHOST_PAD (pad)) {
|
pad_it = gst_element_iterate_pads (GST_ELEMENT (decode_bin));
|
||||||
GstElement *parent = gst_pad_get_parent (pad);
|
while (!done) {
|
||||||
|
switch (gst_iterator_next (pad_it, (gpointer) & db_pad)) {
|
||||||
|
case GST_ITERATOR_OK:
|
||||||
|
GST_DEBUG_OBJECT (decode_bin, "looking at pad %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (db_pad));
|
||||||
|
if (GST_IS_GHOST_PAD (db_pad) && GST_PAD_IS_SRC (db_pad)) {
|
||||||
|
GstPad *target_pad = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (decode_bin, "pad parent %s", GST_ELEMENT_NAME (parent));
|
target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (db_pad));
|
||||||
|
|
||||||
if (parent == GST_ELEMENT (decode_bin)) {
|
if (target_pad == pad) { /* Found our ghost pad */
|
||||||
GST_DEBUG_OBJECT (decode_bin, "pad is our ghostpad");
|
GST_DEBUG_OBJECT (decode_bin, "found ghostpad %s:%s for pad %s:%s",
|
||||||
gst_object_unref (parent);
|
GST_DEBUG_PAD_NAME (db_pad), GST_DEBUG_PAD_NAME (pad));
|
||||||
return pad;
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
} else { /* Not the right one */
|
||||||
|
gst_object_unref (db_pad);
|
||||||
|
db_pad = NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (decode_bin, "pad is ghostpad but not ours");
|
gst_object_unref (db_pad);
|
||||||
gst_object_unref (parent);
|
db_pad = NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (decode_bin, "looping over ghostpads");
|
break;
|
||||||
ghostpads = GST_REAL_PAD (pad)->ghostpads;
|
case GST_ITERATOR_RESYNC:
|
||||||
while (ghostpads) {
|
gst_iterator_resync (pad_it);
|
||||||
GstPad *ghostpad;
|
break;
|
||||||
|
case GST_ITERATOR_ERROR:
|
||||||
ghostpad = get_our_ghost_pad (decode_bin, GST_PAD (ghostpads->data));
|
done = TRUE;
|
||||||
if (ghostpad)
|
break;
|
||||||
return ghostpad;
|
case GST_ITERATOR_DONE:
|
||||||
|
done = TRUE;
|
||||||
ghostpads = g_list_next (ghostpads);
|
break;
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (decode_bin, "done looping over ghostpads, nothing found");
|
}
|
||||||
#endif
|
gst_iterator_free (pad_it);
|
||||||
|
|
||||||
return NULL;
|
return db_pad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove all downstream elements starting from the given pad.
|
/* remove all downstream elements starting from the given pad.
|
||||||
|
@ -937,6 +947,7 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
|
||||||
gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, ghostpad);
|
gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, ghostpad);
|
||||||
|
|
||||||
gst_element_remove_pad (GST_ELEMENT (decode_bin), ghostpad);
|
gst_element_remove_pad (GST_ELEMENT (decode_bin), ghostpad);
|
||||||
|
gst_object_unref (ghostpad);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (decode_bin, "not one of our ghostpads");
|
GST_DEBUG_OBJECT (decode_bin, "not one of our ghostpads");
|
||||||
|
@ -950,17 +961,22 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
|
||||||
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
|
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
|
||||||
|
|
||||||
{
|
{
|
||||||
GstElement *parent = gst_pad_get_parent_element (peer);
|
GstObject *parent = gst_pad_get_parent (peer);
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if (parent != GST_ELEMENT (decode_bin)) {
|
GstElement *grandparent = GST_ELEMENT (gst_object_get_parent (parent));
|
||||||
GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s",
|
|
||||||
GST_DEBUG_PAD_NAME (peer));
|
if (grandparent) {
|
||||||
|
if (grandparent != GST_ELEMENT (decode_bin)) {
|
||||||
|
GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s parent %s",
|
||||||
|
GST_DEBUG_PAD_NAME (peer), GST_OBJECT_NAME (grandparent));
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
|
GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
|
||||||
GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
|
GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
|
||||||
remove_element_chain (decode_bin, peer);
|
remove_element_chain (decode_bin, peer);
|
||||||
}
|
}
|
||||||
|
gst_object_unref (grandparent);
|
||||||
|
}
|
||||||
gst_object_unref (parent);
|
gst_object_unref (parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1296,6 +1312,81 @@ shutting_down:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup_decodebin (GstDecodeBin * decode_bin)
|
||||||
|
{
|
||||||
|
GstIterator *elem_it = NULL, *gpad_it = NULL;
|
||||||
|
GstPad *typefind_pad = NULL;
|
||||||
|
gboolean done = FALSE;
|
||||||
|
|
||||||
|
g_return_if_fail (GST_IS_DECODE_BIN (decode_bin));
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (decode_bin, "cleaning up decodebin");
|
||||||
|
|
||||||
|
typefind_pad = gst_element_get_pad (decode_bin->typefind, "src");
|
||||||
|
if (GST_IS_PAD (typefind_pad)) {
|
||||||
|
g_signal_handlers_block_by_func (typefind_pad, unlinked, decode_bin);
|
||||||
|
}
|
||||||
|
|
||||||
|
elem_it = gst_bin_iterate_elements (GST_BIN (decode_bin));
|
||||||
|
while (!done) {
|
||||||
|
GstElement *element = NULL;
|
||||||
|
|
||||||
|
switch (gst_iterator_next (elem_it, (gpointer) & element)) {
|
||||||
|
case GST_ITERATOR_OK:
|
||||||
|
if (element != decode_bin->typefind && element != decode_bin->fakesink) {
|
||||||
|
GST_DEBUG_OBJECT (element, "removing autoplugged element");
|
||||||
|
g_signal_handlers_disconnect_by_func (element, unlinked, decode_bin);
|
||||||
|
gst_bin_remove (GST_BIN (decode_bin), element);
|
||||||
|
}
|
||||||
|
gst_object_unref (element);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_RESYNC:
|
||||||
|
gst_iterator_resync (elem_it);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_ERROR:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_DONE:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_iterator_free (elem_it);
|
||||||
|
|
||||||
|
gpad_it = gst_element_iterate_pads (GST_ELEMENT (decode_bin));
|
||||||
|
while (!done) {
|
||||||
|
GstPad *pad = NULL;
|
||||||
|
|
||||||
|
switch (gst_iterator_next (gpad_it, (gpointer) & pad)) {
|
||||||
|
case GST_ITERATOR_OK:
|
||||||
|
GST_DEBUG_OBJECT (pad, "inspecting pad %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
if (GST_IS_GHOST_PAD (pad) && GST_PAD_IS_SRC (pad)) {
|
||||||
|
GST_DEBUG_OBJECT (pad, "removing ghost pad");
|
||||||
|
gst_element_remove_pad (GST_ELEMENT (decode_bin), pad);
|
||||||
|
}
|
||||||
|
gst_object_unref (pad);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_RESYNC:
|
||||||
|
gst_iterator_resync (gpad_it);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_ERROR:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_DONE:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_iterator_free (gpad_it);
|
||||||
|
|
||||||
|
if (GST_IS_PAD (typefind_pad)) {
|
||||||
|
g_signal_handlers_unblock_by_func (typefind_pad, unlinked, decode_bin);
|
||||||
|
gst_object_unref (typefind_pad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
|
gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
|
@ -1336,6 +1427,7 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
free_dynamics (decode_bin);
|
free_dynamics (decode_bin);
|
||||||
free_pad_probes (decode_bin);
|
free_pad_probes (decode_bin);
|
||||||
|
cleanup_decodebin (decode_bin);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue