uridecodebin: Store unused decodebin2 instances for further usage.

This allows faster re-use of uridecodebin.

https://bugzilla.gnome.org/show_bug.cgi?id=599471
This commit is contained in:
Edward Hervey 2009-10-18 17:28:22 +02:00
parent 61d08884d3
commit 80b37c614a

View file

@ -84,6 +84,7 @@ struct _GstURIDecodeBin
GstElement *typefind;
guint have_type_id; /* have-type signal id from typefind */
GSList *decodebins;
GSList *pending_decodebins;
GSList *srcpads;
gint numpads;
@ -169,6 +170,7 @@ static guint gst_uri_decode_bin_signals[LAST_SIGNAL] = { 0 };
GST_BOILERPLATE (GstURIDecodeBin, gst_uri_decode_bin, GstBin, GST_TYPE_BIN);
static void remove_decoders (GstURIDecodeBin * bin, gboolean force);
static void gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_uri_decode_bin_get_property (GObject * object, guint prop_id,
@ -460,6 +462,7 @@ gst_uri_decode_bin_finalize (GObject * obj)
{
GstURIDecodeBin *dec = GST_URI_DECODE_BIN (obj);
remove_decoders (dec, TRUE);
g_mutex_free (dec->lock);
g_free (dec->uri);
g_free (dec->encoding);
@ -1078,8 +1081,13 @@ analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw,
return res;
}
/* Remove all decodebin2 from ourself
* If force is FALSE, then the decodebin2 instances will be stored in
* pending_decodebins for re-use later on.
* If force is TRUE, then all decodebin2 instances will be unreferenced
* and cleared, including the pending ones. */
static void
remove_decoders (GstURIDecodeBin * bin)
remove_decoders (GstURIDecodeBin * bin, gboolean force)
{
GSList *walk;
@ -1087,11 +1095,31 @@ remove_decoders (GstURIDecodeBin * bin)
GstElement *decoder = GST_ELEMENT_CAST (walk->data);
GST_DEBUG_OBJECT (bin, "removing old decoder element");
if (force) {
gst_element_set_state (decoder, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (bin), decoder);
} else {
gst_element_set_state (decoder, GST_STATE_READY);
/* add it to our list of pending decodebins */
g_object_ref (decoder);
gst_bin_remove (GST_BIN_CAST (bin), decoder);
bin->pending_decodebins =
g_slist_prepend (bin->pending_decodebins, decoder);
}
}
g_slist_free (bin->decodebins);
bin->decodebins = NULL;
if (force) {
GSList *tmp;
for (tmp = bin->pending_decodebins; tmp; tmp = tmp->next) {
gst_element_set_state ((GstElement *) tmp->data, GST_STATE_NULL);
gst_object_unref ((GstElement *) tmp->data);
}
g_slist_free (bin->pending_decodebins);
bin->pending_decodebins = NULL;
}
}
static void
@ -1180,17 +1208,21 @@ make_decoder (GstURIDecodeBin * decoder)
{
GstElement *decodebin;
/* re-use pending decodebin2 */
if (decoder->pending_decodebins) {
GSList *first = decoder->pending_decodebins;
GST_LOG_OBJECT (decoder, "re-using pending decodebin2");
decodebin = (GstElement *) first->data;
decoder->pending_decodebins =
g_slist_delete_link (decoder->pending_decodebins, first);
} else {
GST_LOG_OBJECT (decoder, "making new decodebin2");
/* now create the decoder element */
decodebin = gst_element_factory_make ("decodebin2", NULL);
if (!decodebin)
goto no_decodebin;
/* configure caps if we have any */
if (decoder->caps)
g_object_set (decodebin, "caps", decoder->caps, NULL);
/* connect signals to proxy */
g_signal_connect (G_OBJECT (decodebin), "unknown-type",
G_CALLBACK (proxy_unknown_type_signal), decoder);
@ -1213,6 +1245,12 @@ make_decoder (GstURIDecodeBin * decoder)
G_CALLBACK (no_more_pads), decoder);
g_signal_connect (G_OBJECT (decodebin),
"unknown-type", G_CALLBACK (unknown_type_cb), decoder);
}
/* configure caps if we have any */
if (decoder->caps)
g_object_set (decodebin, "caps", decoder->caps, NULL);
g_object_set_data (G_OBJECT (decodebin), "pending", "1");
g_object_set (G_OBJECT (decodebin), "subtitle-encoding", decoder->encoding,
NULL);
@ -1480,7 +1518,7 @@ setup_source (GstURIDecodeBin * decoder)
g_object_notify (G_OBJECT (decoder), "source");
/* remove the old decoders now, if any */
remove_decoders (decoder);
remove_decoders (decoder, FALSE);
/* see if the source element emits raw audio/video all by itself,
* if so, we can create streams for the pads and be done with it.
@ -1965,14 +2003,14 @@ gst_uri_decode_bin_change_state (GstElement * element,
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_DEBUG ("paused to ready");
remove_decoders (decoder);
remove_decoders (decoder, FALSE);
remove_pads (decoder);
remove_source (decoder);
do_async_done (decoder);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
GST_DEBUG ("ready to null");
remove_decoders (decoder);
remove_decoders (decoder, TRUE);
remove_pads (decoder);
remove_source (decoder);
break;