Commit 91ee7188 authored by Jan Schmidt's avatar Jan Schmidt
Browse files

gst/playback/gstdecodebin.c: Protect remove_fakesink using a mutex, so that we...

gst/playback/gstdecodebin.c: Protect remove_fakesink using a mutex, so that we don't try and remove the fakesink simu...

Original commit message from CVS:
* gst/playback/gstdecodebin.c: (gst_decode_bin_class_init),
(gst_decode_bin_init), (gst_decode_bin_finalize), (add_fakesink),
(remove_fakesink), (pad_probe), (gst_decode_bin_change_state):
Protect remove_fakesink using a mutex, so that we don't try and
remove the fakesink simultaneously from multiple threads.
When going from READY to PAUSED, restore the fakesink, so that
it is there when decodebin gets reused.
parent 114a273f
2006-06-23 Jan Schmidt <thaytan@mad.scientist.com>
* gst/playback/gstdecodebin.c: (gst_decode_bin_class_init),
(gst_decode_bin_init), (gst_decode_bin_finalize), (add_fakesink),
(remove_fakesink), (pad_probe), (gst_decode_bin_change_state):
Protect remove_fakesink using a mutex, so that we don't try and
remove the fakesink simultaneously from multiple threads.
When going from READY to PAUSED, restore the fakesink, so that
it is there when decodebin gets reused.
2006-06-23 Tim-Philipp Müller <tim at centricular dot net>
 
* gst-libs/gst/rtp/gstbasertpaudiopayload.c:
......
......@@ -73,6 +73,8 @@ struct _GstDecodeBin
gboolean shutting_down; /* stop pluggin if we're shutting down */
GType queue_type; /* store the GType of queues, to aid in recognising them */
GMutex *cb_mutex; /* Mutex for multi-threaded callbacks, such as removing the fakesink */
};
struct _GstDecodeBinClass
......@@ -120,10 +122,14 @@ GstDynamic;
static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
static void gst_decode_bin_init (GstDecodeBin * decode_bin);
static void gst_decode_bin_dispose (GObject * object);
static void gst_decode_bin_finalize (GObject * object);
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
GstStateChange transition);
static void add_fakesink (GstDecodeBin * decode_bin);
static void remove_fakesink (GstDecodeBin * decode_bin);
static void free_dynamics (GstDecodeBin * decode_bin);
static void type_found (GstElement * typefind, guint probability,
GstCaps * caps, GstDecodeBin * decode_bin);
......@@ -208,6 +214,7 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
GST_TYPE_PAD, GST_TYPE_CAPS);
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_decode_bin_finalize);
gst_element_class_add_pad_template (gstelement_klass,
gst_static_pad_template_get (&decoder_bin_sink_template));
......@@ -293,6 +300,8 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
{
GList *factories;
decode_bin->cb_mutex = g_mutex_new ();
/* first filter out the interesting element factories */
factories = gst_default_registry_feature_filter (
(GstPluginFeatureFilter) gst_decode_bin_factory_filter,
......@@ -332,17 +341,7 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
G_CALLBACK (type_found), decode_bin);
}
decode_bin->fakesink = gst_element_factory_make ("fakesink", "fakesink");
if (!decode_bin->fakesink) {
g_warning ("can't find fakesink element, decodebin will not work");
} else {
GST_OBJECT_FLAG_UNSET (decode_bin->fakesink, GST_ELEMENT_IS_SINK);
if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->fakesink)) {
g_warning ("Could not add fakesink element, decodebin will not work");
gst_object_unref (decode_bin->fakesink);
decode_bin->fakesink = NULL;
}
}
add_fakesink (decode_bin);
decode_bin->dynamics = NULL;
decode_bin->queues = NULL;
......@@ -370,6 +369,16 @@ gst_decode_bin_dispose (GObject * object)
free_dynamics (decode_bin);
}
static void
gst_decode_bin_finalize (GObject * object)
{
GstDecodeBin *decode_bin = GST_DECODE_BIN (object);
g_mutex_free (decode_bin->cb_mutex);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GstDynamic *
dynamic_create (GstElement * element, GstDecodeBin * decode_bin)
{
......@@ -491,9 +500,37 @@ free_pad_probes (GstDecodeBin * decode_bin)
decode_bin->probes = NULL;
}
static void
add_fakesink (GstDecodeBin * decode_bin)
{
if (decode_bin->fakesink != NULL)
return;
g_mutex_lock (decode_bin->cb_mutex);
decode_bin->fakesink = gst_element_factory_make ("fakesink", "fakesink");
if (!decode_bin->fakesink) {
g_warning ("can't find fakesink element, decodebin will not work");
} else {
GST_OBJECT_FLAG_UNSET (decode_bin->fakesink, GST_ELEMENT_IS_SINK);
if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->fakesink)) {
g_warning ("Could not add fakesink element, decodebin will not work");
gst_object_unref (decode_bin->fakesink);
decode_bin->fakesink = NULL;
}
}
g_mutex_unlock (decode_bin->cb_mutex);
}
static void
remove_fakesink (GstDecodeBin * decode_bin)
{
gboolean removed_fakesink = FALSE;
if (decode_bin->fakesink == NULL)
return;
g_mutex_lock (decode_bin->cb_mutex);
if (decode_bin->fakesink) {
GST_DEBUG_OBJECT (decode_bin, "Removing fakesink and marking state dirty");
gst_object_ref (decode_bin->fakesink);
......@@ -506,6 +543,11 @@ remove_fakesink (GstDecodeBin * decode_bin)
gst_object_unref (decode_bin->fakesink);
decode_bin->fakesink = NULL;
removed_fakesink = TRUE;
}
g_mutex_unlock (decode_bin->cb_mutex);
if (removed_fakesink) {
free_pad_probes (decode_bin);
gst_element_post_message (GST_ELEMENT_CAST (decode_bin),
......@@ -1462,6 +1504,9 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
GST_OBJECT_LOCK (decode_bin);
decode_bin->shutting_down = FALSE;
GST_OBJECT_UNLOCK (decode_bin);
add_fakesink (decode_bin);
break;
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment