mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-28 01:05:07 +00:00
gst/playback/gstdecodebin.c: Replace GstPadBlockCallback with pad probes that detect first buffer AND eos before remo...
Original commit message from CVS: * gst/playback/gstdecodebin.c: (gst_decode_bin_init), (free_pad_probes), (remove_fakesink), (pad_probe), (close_pad_link), (gst_decode_bin_change_state): Replace GstPadBlockCallback with pad probes that detect first buffer AND eos before removing fakesink. Fixes hang with demuxers doing EOS while pre-rolling. Solves #328279
This commit is contained in:
parent
6b153515b0
commit
e4aa8fcb19
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2006-01-23 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
|
* gst/playback/gstdecodebin.c: (gst_decode_bin_init),
|
||||||
|
(free_pad_probes), (remove_fakesink), (pad_probe),
|
||||||
|
(close_pad_link), (gst_decode_bin_change_state):
|
||||||
|
Replace GstPadBlockCallback with pad probes that detect
|
||||||
|
first buffer AND eos before removing fakesink.
|
||||||
|
Fixes hang with demuxers doing EOS while pre-rolling.
|
||||||
|
Solves #328279
|
||||||
|
|
||||||
2006-01-23 Andy Wingo <wingo@pobox.com>
|
2006-01-23 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
* ext/alsa/gstalsasink.c:
|
* ext/alsa/gstalsasink.c:
|
||||||
|
|
|
@ -62,6 +62,8 @@ struct _GstDecodeBin
|
||||||
|
|
||||||
GList *queues; /* list of demuxer-decoder queues */
|
GList *queues; /* list of demuxer-decoder queues */
|
||||||
|
|
||||||
|
GList *probes; /* list of PadProbeData */
|
||||||
|
|
||||||
GList *factories; /* factories we can use for selecting elements */
|
GList *factories; /* factories we can use for selecting elements */
|
||||||
gint numpads;
|
gint numpads;
|
||||||
gint numwaiting;
|
gint numwaiting;
|
||||||
|
@ -95,6 +97,14 @@ enum
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstPad *pad;
|
||||||
|
gulong sigid;
|
||||||
|
gboolean done;
|
||||||
|
} PadProbeData;
|
||||||
|
|
||||||
/* this structure is created for all dynamic pads that could get created
|
/* this structure is created for all dynamic pads that could get created
|
||||||
* at runtime */
|
* at runtime */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -336,6 +346,7 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
|
||||||
|
|
||||||
decode_bin->dynamics = NULL;
|
decode_bin->dynamics = NULL;
|
||||||
decode_bin->queues = NULL;
|
decode_bin->queues = NULL;
|
||||||
|
decode_bin->probes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dynamic_free (GstDynamic * dyn);
|
static void dynamic_free (GstDynamic * dyn);
|
||||||
|
@ -463,6 +474,22 @@ mimetype_is_raw (const gchar * mimetype)
|
||||||
g_str_has_prefix (mimetype, "text/plain");
|
g_str_has_prefix (mimetype, "text/plain");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_pad_probes (GstDecodeBin * decode_bin)
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
/* Remove pad probes */
|
||||||
|
for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) {
|
||||||
|
PadProbeData *data = (PadProbeData *) tmp->data;
|
||||||
|
|
||||||
|
gst_pad_remove_data_probe (data->pad, data->sigid);
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
g_list_free (decode_bin->probes);
|
||||||
|
decode_bin->probes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_fakesink (GstDecodeBin * decode_bin)
|
remove_fakesink (GstDecodeBin * decode_bin)
|
||||||
{
|
{
|
||||||
|
@ -477,22 +504,33 @@ remove_fakesink (GstDecodeBin * decode_bin)
|
||||||
gst_object_unref (decode_bin->fakesink);
|
gst_object_unref (decode_bin->fakesink);
|
||||||
decode_bin->fakesink = NULL;
|
decode_bin->fakesink = NULL;
|
||||||
|
|
||||||
|
free_pad_probes (decode_bin);
|
||||||
|
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (decode_bin),
|
gst_element_post_message (GST_ELEMENT_CAST (decode_bin),
|
||||||
gst_message_new_state_dirty (GST_OBJECT_CAST (decode_bin)));
|
gst_message_new_state_dirty (GST_OBJECT_CAST (decode_bin)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
pad_blocked (GstPad * pad, gboolean blocked, GstDecodeBin * decode_bin)
|
pad_probe (GstPad * pad, GstMiniObject * data, GstDecodeBin * decode_bin)
|
||||||
{
|
{
|
||||||
if (blocked) {
|
GList *tmp;
|
||||||
decode_bin->numwaiting--;
|
gboolean alldone = TRUE;
|
||||||
if (decode_bin->numwaiting == 0) {
|
|
||||||
remove_fakesink (decode_bin);
|
for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) {
|
||||||
}
|
PadProbeData *pdata = (PadProbeData *) tmp->data;
|
||||||
gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback) pad_blocked,
|
|
||||||
NULL);
|
if (pdata->pad == pad) {
|
||||||
|
if (GST_IS_BUFFER (data))
|
||||||
|
pdata->done = TRUE;
|
||||||
|
else if (GST_IS_EVENT (data) && (GST_EVENT_TYPE (data) == GST_EVENT_EOS))
|
||||||
|
pdata->done = TRUE;
|
||||||
|
} else if (!(pdata->done))
|
||||||
|
alldone = FALSE;
|
||||||
}
|
}
|
||||||
|
if (alldone)
|
||||||
|
remove_fakesink (decode_bin);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* given a pad and a caps from an element, find the list of elements
|
/* given a pad and a caps from an element, find the list of elements
|
||||||
|
@ -544,6 +582,7 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
if (mimetype_is_raw (mimetype)) {
|
if (mimetype_is_raw (mimetype)) {
|
||||||
gchar *padname;
|
gchar *padname;
|
||||||
GstPad *ghost;
|
GstPad *ghost;
|
||||||
|
PadProbeData *data;
|
||||||
|
|
||||||
/* make a unique name for this new pad */
|
/* make a unique name for this new pad */
|
||||||
padname = g_strdup_printf ("src%d", decode_bin->numpads);
|
padname = g_strdup_printf ("src%d", decode_bin->numpads);
|
||||||
|
@ -553,10 +592,15 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
ghost = gst_ghost_pad_new (padname, pad);
|
ghost = gst_ghost_pad_new (padname, pad);
|
||||||
gst_element_add_pad (GST_ELEMENT (decode_bin), ghost);
|
gst_element_add_pad (GST_ELEMENT (decode_bin), ghost);
|
||||||
|
|
||||||
if (gst_pad_set_blocked_async (pad, TRUE, (GstPadBlockCallback) pad_blocked,
|
data = g_new0 (PadProbeData, 1);
|
||||||
decode_bin)) {
|
data->pad = pad;
|
||||||
decode_bin->numwaiting++;
|
data->done = FALSE;
|
||||||
}
|
|
||||||
|
data->sigid = gst_pad_add_data_probe (pad, G_CALLBACK (pad_probe),
|
||||||
|
decode_bin);
|
||||||
|
decode_bin->numwaiting++;
|
||||||
|
|
||||||
|
decode_bin->probes = g_list_append (decode_bin->probes, data);
|
||||||
|
|
||||||
GST_LOG_OBJECT (element, "closed pad %s", padname);
|
GST_LOG_OBJECT (element, "closed pad %s", padname);
|
||||||
|
|
||||||
|
@ -1279,6 +1323,7 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
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);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue