gst/playback/gsturidecodebin.c: Add a readonly source property and notify.

Original commit message from CVS:
* gst/playback/gsturidecodebin.c:
(gst_uri_decode_bin_autoplug_factories),
(gst_uri_decode_bin_class_init), (gst_uri_decode_bin_init),
(gst_uri_decode_bin_finalize), (gst_uri_decode_bin_set_encoding),
(gst_uri_decode_bin_set_property),
(gst_uri_decode_bin_get_property), (no_more_pads_full),
(new_decoded_pad_cb), (gen_source_element), (remove_decoders),
(proxy_autoplug_factories_signal), (make_decoder),
(source_new_pad), (setup_source):
Add a readonly source property and notify.
Add new lock for protecting the construction of the pipeline.
Keep track of the decodebins we plugged.
Correctly proxy the autoplug signal so that it actually continues.
Proxy subtitle-encoding to the decodebins.
This commit is contained in:
Wim Taymans 2008-03-24 11:54:02 +00:00
parent f7d8a9a68c
commit 3640ae2d36
2 changed files with 114 additions and 10 deletions

View file

@ -1,3 +1,20 @@
2008-03-24 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/playback/gsturidecodebin.c:
(gst_uri_decode_bin_autoplug_factories),
(gst_uri_decode_bin_class_init), (gst_uri_decode_bin_init),
(gst_uri_decode_bin_finalize), (gst_uri_decode_bin_set_encoding),
(gst_uri_decode_bin_set_property),
(gst_uri_decode_bin_get_property), (no_more_pads_full),
(new_decoded_pad_cb), (gen_source_element), (remove_decoders),
(proxy_autoplug_factories_signal), (make_decoder),
(source_new_pad), (setup_source):
Add a readonly source property and notify.
Add new lock for protecting the construction of the pipeline.
Keep track of the decodebins we plugged.
Correctly proxy the autoplug signal so that it actually continues.
Proxy subtitle-encoding to the decodebins.
2008-03-24 Wim Taymans <wim.taymans@collabora.co.uk>
* tests/examples/seek/seek.c: (audio_toggle_cb), (video_toggle_cb),

View file

@ -33,6 +33,7 @@
#include <gst/gst.h>
#include <gst/gst-i18n-plugin.h>
#include "gstfactorylists.h"
#include "gstplay-marshal.h"
#include "gstplay-enum.h"
@ -46,14 +47,23 @@
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_URI_DECODE_BIN))
#define GST_IS_URI_DECODE_BIN_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_URI_DECODE_BIN))
#define GST_URI_DECODE_BIN_CAST(obj) ((GstURIDecodeBin *) (obj))
typedef struct _GstURIDecodeBin GstURIDecodeBin;
typedef struct _GstURIDecodeBinClass GstURIDecodeBinClass;
#define GST_URI_DECODE_BIN_GET_LOCK(dec) (((GstURIDecodeBin*)(dec))->lock)
#define GST_URI_DECODE_BIN_LOCK(dec) (g_mutex_lock(GST_URI_DECODE_BIN_GET_LOCK(dec)))
#define GST_URI_DECODE_BIN_UNLOCK(dec) (g_mutex_unlock(GST_URI_DECODE_BIN_GET_LOCK(dec)))
struct _GstURIDecodeBin
{
GstBin parent_instance;
GMutex *lock; /* lock for constructing */
GValueArray *factories; /* factories we can use for selecting elements */
gchar *uri;
guint connection_speed;
GstCaps *caps;
@ -63,6 +73,7 @@ struct _GstURIDecodeBin
GstElement *source;
GstElement *queue;
GSList *decoders;
GSList *decodebins;
GSList *srcpads;
gint numpads;
@ -120,6 +131,7 @@ enum
/* properties */
#define DEFAULT_PROP_URI NULL
#define DEFAULT_PROP_SOURCE NULL
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_CAPS NULL
#define DEFAULT_SUBTITLE_ENCODING NULL
@ -128,6 +140,7 @@ enum
{
PROP_0,
PROP_URI,
PROP_SOURCE,
PROP_CONNECTION_SPEED,
PROP_CAPS,
PROP_SUBTITLE_ENCODING,
@ -209,6 +222,25 @@ gst_uri_decode_bin_autoplug_continue (GstElement * element, GstPad * pad,
return TRUE;
}
static GValueArray *
gst_uri_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
GstCaps * caps)
{
GValueArray *result;
GST_DEBUG_OBJECT (element, "finding factories");
/* return all compatible factories for caps */
result =
gst_factory_list_filter (GST_URI_DECODE_BIN_CAST (element)->factories,
caps);
GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
return result;
}
static void
gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
{
@ -228,6 +260,10 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
g_param_spec_string ("uri", "URI", "URI to decode",
DEFAULT_PROP_URI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_SOURCE,
g_param_spec_object ("source", "Source", "Source object used",
GST_TYPE_ELEMENT, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_CONNECTION_SPEED,
g_param_spec_uint ("connection-speed", "Connection Speed",
"Network connection speed in kbps (0 = unknown)",
@ -342,11 +378,18 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
klass->autoplug_continue =
GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_continue);
klass->autoplug_factories =
GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_factories);
}
static void
gst_uri_decode_bin_init (GstURIDecodeBin * dec, GstURIDecodeBinClass * klass)
{
/* first filter out the interesting element factories */
dec->factories = gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
dec->lock = g_mutex_new ();
dec->uri = g_strdup (DEFAULT_PROP_URI);
dec->connection_speed = DEFAULT_CONNECTION_SPEED;
dec->caps = DEFAULT_CAPS;
@ -358,12 +401,35 @@ gst_uri_decode_bin_finalize (GObject * obj)
{
GstURIDecodeBin *dec = GST_URI_DECODE_BIN (obj);
g_mutex_free (dec->lock);
g_free (dec->uri);
g_free (dec->encoding);
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
static void
gst_uri_decode_bin_set_encoding (GstURIDecodeBin * dec, const gchar * encoding)
{
GSList *walk;
GST_URI_DECODE_BIN_LOCK (dec);
/* set property first */
GST_OBJECT_LOCK (dec);
g_free (dec->encoding);
dec->encoding = g_strdup (encoding);
GST_OBJECT_UNLOCK (dec);
/* set the property on all decodebins now */
for (walk = dec->decodebins; walk; walk = g_slist_next (walk)) {
GObject *decodebin = G_OBJECT (walk->data);
g_object_set (decodebin, "subtitle-encoding", encoding, NULL);
}
GST_URI_DECODE_BIN_UNLOCK (dec);
}
static void
gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
@ -390,10 +456,7 @@ gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
GST_OBJECT_UNLOCK (dec);
break;
case PROP_SUBTITLE_ENCODING:
GST_OBJECT_LOCK (dec);
g_free (dec->encoding);
dec->encoding = g_value_dup_string (value);
GST_OBJECT_UNLOCK (dec);
gst_uri_decode_bin_set_encoding (dec, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -413,6 +476,11 @@ gst_uri_decode_bin_get_property (GObject * object, guint prop_id,
g_value_set_string (value, dec->uri);
GST_OBJECT_UNLOCK (dec);
break;
case PROP_SOURCE:
GST_OBJECT_LOCK (dec);
g_value_set_object (value, dec->source);
GST_OBJECT_UNLOCK (dec);
break;
case PROP_CONNECTION_SPEED:
GST_OBJECT_LOCK (dec);
g_value_set_uint (value, dec->connection_speed / 1000);
@ -473,7 +541,7 @@ no_more_pads_full (GstElement * element, gboolean subs,
/* setup phase */
GST_DEBUG_OBJECT (element, "no more pads, %d pending", decoder->pending);
GST_OBJECT_LOCK (decoder);
GST_URI_DECODE_BIN_LOCK (decoder);
final = (decoder->pending == 0);
/* nothing pending, we can exit */
@ -489,7 +557,7 @@ no_more_pads_full (GstElement * element, gboolean subs,
final = (decoder->pending == 0);
done:
GST_OBJECT_UNLOCK (decoder);
GST_URI_DECODE_BIN_UNLOCK (decoder);
if (final)
gst_element_no_more_pads (GST_ELEMENT_CAST (decoder));
@ -530,10 +598,10 @@ new_decoded_pad_cb (GstElement * element, GstPad * pad, gboolean last,
GST_DEBUG_OBJECT (element, "new decoded pad, name: <%s>. Last: %d",
GST_PAD_NAME (pad), last);
GST_OBJECT_LOCK (decoder);
GST_URI_DECODE_BIN_LOCK (decoder);
padname = g_strdup_printf ("src%d", decoder->numpads);
decoder->numpads++;
GST_OBJECT_UNLOCK (decoder);
GST_URI_DECODE_BIN_UNLOCK (decoder);
newpad = gst_ghost_pad_new (padname, pad);
g_free (padname);
@ -652,7 +720,13 @@ gen_source_element (GstURIDecodeBin * decoder)
g_object_set (source, "connection-speed",
decoder->connection_speed / 1000, NULL);
}
if (g_object_class_find_property (G_OBJECT_GET_CLASS (source),
"subtitle-encoding")) {
GST_DEBUG_OBJECT (decoder,
"setting subtitle-encoding=%s to source element", decoder->encoding);
g_object_set (G_OBJECT (source), "subtitle-encoding", decoder->encoding,
NULL);
}
return source;
/* ERRORS */
@ -842,7 +916,9 @@ remove_decoders (GstURIDecodeBin * bin)
gst_bin_remove (GST_BIN_CAST (bin), decoder);
}
g_slist_free (bin->decoders);
g_slist_free (bin->decodebins);
bin->decoders = NULL;
bin->decodebins = NULL;
}
static void
@ -890,7 +966,7 @@ static GValueArray *
proxy_autoplug_factories_signal (GstElement * element, GstPad * pad,
GstCaps * caps, GstURIDecodeBin * dec)
{
GValueArray *result = NULL;
GValueArray *result;
g_signal_emit (G_OBJECT (dec),
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, pad, caps,
@ -986,11 +1062,14 @@ make_decoder (GstURIDecodeBin * decoder, gboolean use_queue)
g_signal_connect (G_OBJECT (decodebin),
"unknown-type", G_CALLBACK (unknown_type_cb), decoder);
g_object_set_data (G_OBJECT (decodebin), "pending", "1");
g_object_set (G_OBJECT (decodebin), "subtitle-encoding", decoder->encoding,
NULL);
decoder->pending++;
gst_bin_add (GST_BIN_CAST (decoder), result);
decoder->decoders = g_slist_prepend (decoder->decoders, result);
decoder->decodebins = g_slist_prepend (decoder->decodebins, decodebin);
return result;
@ -1038,12 +1117,14 @@ source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin)
GstElement *decoder;
gboolean is_raw;
GST_URI_DECODE_BIN_LOCK (bin);
GST_DEBUG_OBJECT (bin, "Found new pad %s.%s in source element %s",
GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
/* if this is a pad with all raw caps, we can expose it */
if (has_all_raw_caps (pad, &is_raw) && is_raw) {
/* it's all raw, create output pads. */
GST_URI_DECODE_BIN_UNLOCK (bin);
new_decoded_pad_cb (element, pad, FALSE, bin);
return;
}
@ -1060,6 +1141,7 @@ source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin)
GST_DEBUG_OBJECT (bin, "linked decoder to new pad");
gst_element_set_state (decoder, GST_STATE_PLAYING);
GST_URI_DECODE_BIN_UNLOCK (bin);
return;
@ -1067,12 +1149,14 @@ source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin)
no_decodebin:
{
/* error was posted */
GST_URI_DECODE_BIN_UNLOCK (bin);
return;
}
could_not_link:
{
GST_ELEMENT_ERROR (bin, CORE, NEGOTIATION,
(NULL), ("Can't link source to decoder element"));
GST_URI_DECODE_BIN_UNLOCK (bin);
return;
}
}
@ -1098,6 +1182,9 @@ setup_source (GstURIDecodeBin * decoder)
* handled by the application right after. */
gst_bin_add (GST_BIN_CAST (decoder), decoder->source);
/* notify of the new source used */
g_object_notify (G_OBJECT (decoder), "source");
/* remove the old decoders now, if any */
remove_decoders (decoder);