gst/playback/gstdecodebin2.c: Move subtitle encoding property to decodebin2 so that it can set the property value on ...

Original commit message from CVS:
* gst/playback/gstdecodebin2.c: (gst_decode_bin_class_init),
(gst_decode_bin_dispose), (gst_decode_bin_set_caps),
(gst_decode_bin_set_subs_encoding),
(gst_decode_bin_get_subs_encoding), (gst_decode_bin_set_property),
(gst_decode_bin_get_property), (analyze_new_pad):
Move subtitle encoding property to decodebin2 so that it can set the
property value on all elements that it autoplugs and that require it.
Make caps refcounting more consistent in get/set.
* gst/playback/gsturidecodebin.c: (_gst_boolean_accumulator),
(gst_uri_decode_bin_class_init), (gst_uri_decode_bin_init),
(gst_uri_decode_bin_finalize), (gst_uri_decode_bin_set_property),
(gst_uri_decode_bin_get_property), (proxy_unknown_type_signal),
(proxy_autoplug_continue_signal),
(proxy_autoplug_factories_signal), (proxy_autoplug_select_signal),
(make_decoder):
Proxy properties and relevant signals from the internal decodebin.
Make properties MT safe.
This commit is contained in:
Wim Taymans 2007-10-25 17:36:49 +00:00
parent 698e4050b3
commit 8c20347774
3 changed files with 333 additions and 45 deletions

View file

@ -1,3 +1,24 @@
2007-10-25 Wim Taymans <wim.taymans@gmail.com>
* gst/playback/gstdecodebin2.c: (gst_decode_bin_class_init),
(gst_decode_bin_dispose), (gst_decode_bin_set_caps),
(gst_decode_bin_set_subs_encoding),
(gst_decode_bin_get_subs_encoding), (gst_decode_bin_set_property),
(gst_decode_bin_get_property), (analyze_new_pad):
Move subtitle encoding property to decodebin2 so that it can set the
property value on all elements that it autoplugs and that require it.
Make caps refcounting more consistent in get/set.
* gst/playback/gsturidecodebin.c: (_gst_boolean_accumulator),
(gst_uri_decode_bin_class_init), (gst_uri_decode_bin_init),
(gst_uri_decode_bin_finalize), (gst_uri_decode_bin_set_property),
(gst_uri_decode_bin_get_property), (proxy_unknown_type_signal),
(proxy_autoplug_continue_signal),
(proxy_autoplug_factories_signal), (proxy_autoplug_select_signal),
(make_decoder):
Proxy properties and relevant signals from the internal decodebin.
Make properties MT safe.
2007-10-25 Tim-Philipp Müller <tim at centricular dot net>
* gst-libs/gst/tag/tag.h: (GST_TAG_MUSICBRAINZ_SORTNAME):

View file

@ -82,6 +82,10 @@ struct _GstDecodeBin
{
GstBin bin; /* we extend GstBin */
/* properties */
GstCaps *caps; /* caps on which to stop decoding */
gchar *encoding; /* encoding of subtitles */
GstElement *typefind; /* this holds the typefind object */
GstElement *fakesink;
@ -92,7 +96,6 @@ struct _GstDecodeBin
GList *oldgroups; /* List of no-longer-used GstDecodeGroups.
* Should be freed in dispose */
gint nbpads; /* unique identifier for source pads */
GstCaps *caps; /* caps on which to stop decoding */
GList *factories; /* factories we can use for selecting elements */
@ -139,6 +142,7 @@ enum
{
PROP_0,
PROP_CAPS,
PROP_SUBTITLE_ENCODING
};
static GstBinClass *parent_class;
@ -451,6 +455,13 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
g_param_spec_boxed ("caps", "Caps", "The caps on which to stop decoding.",
GST_TYPE_CAPS, G_PARAM_READWRITE));
g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
g_param_spec_string ("subtitle-encoding", "subtitle encoding",
"Encoding to assume if input subtitles are not in UTF-8 encoding. "
"If not set, the GST_SUBTITLE_ENCODING environment variable will "
"be checked for an encoding to use. If that is not set either, "
"ISO-8859-15 will be assumed.", NULL, G_PARAM_READWRITE));
klass->autoplug_continue =
GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_continue);
klass->autoplug_factories =
@ -625,6 +636,10 @@ gst_decode_bin_dispose (GObject * object)
if (decode_bin->caps)
gst_caps_unref (decode_bin->caps);
decode_bin->caps = NULL;
g_free (decode_bin->encoding);
decode_bin->encoding = NULL;
remove_fakesink (decode_bin);
G_OBJECT_CLASS (parent_class)->dispose (object);
@ -645,52 +660,14 @@ gst_decode_bin_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_decode_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDecodeBin *dbin;
dbin = GST_DECODE_BIN (object);
switch (prop_id) {
case PROP_CAPS:
gst_decode_bin_set_caps (dbin, (GstCaps *) g_value_dup_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_decode_bin_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstDecodeBin *dbin;
dbin = GST_DECODE_BIN (object);
switch (prop_id) {
case PROP_CAPS:{
g_value_take_boxed (value, gst_decode_bin_get_caps (dbin));
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/* _set_caps
* Changes the caps on which decodebin will stop decoding.
* Will unref the previously set one. The refcount of the given caps will be
* taken.
* increased.
* @caps can be NULL.
*
* MT-safe
*/
static void
gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps)
{
@ -699,6 +676,8 @@ gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps)
DECODE_BIN_LOCK (dbin);
if (dbin->caps)
gst_caps_unref (dbin->caps);
if (caps)
gst_caps_ref (caps);
dbin->caps = caps;
DECODE_BIN_UNLOCK (dbin);
}
@ -726,6 +705,73 @@ gst_decode_bin_get_caps (GstDecodeBin * dbin)
return caps;
}
static void
gst_decode_bin_set_subs_encoding (GstDecodeBin * dbin, const gchar * encoding)
{
GST_DEBUG_OBJECT (dbin, "Setting new encoding: %s", GST_STR_NULL (encoding));
DECODE_BIN_LOCK (dbin);
g_free (dbin->encoding);
dbin->encoding = g_strdup (encoding);
DECODE_BIN_UNLOCK (dbin);
}
static gchar *
gst_decode_bin_get_subs_encoding (GstDecodeBin * dbin)
{
gchar *encoding;
GST_DEBUG_OBJECT (dbin, "Getting currently set encoding");
DECODE_BIN_LOCK (dbin);
encoding = g_strdup (dbin->encoding);
DECODE_BIN_UNLOCK (dbin);
return encoding;
}
static void
gst_decode_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstDecodeBin *dbin;
dbin = GST_DECODE_BIN (object);
switch (prop_id) {
case PROP_CAPS:
gst_decode_bin_set_caps (dbin, g_value_get_boxed (value));
break;
case PROP_SUBTITLE_ENCODING:
gst_decode_bin_set_subs_encoding (dbin, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_decode_bin_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstDecodeBin *dbin;
dbin = GST_DECODE_BIN (object);
switch (prop_id) {
case PROP_CAPS:
g_value_take_boxed (value, gst_decode_bin_get_caps (dbin));
break;
case PROP_SUBTITLE_ENCODING:
g_value_take_string (value, gst_decode_bin_get_subs_encoding (dbin));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GValueArray *find_compatibles (GstDecodeBin * decode_bin,
GstPad * pad, const GstCaps * caps);
@ -846,7 +892,6 @@ expose_pad:
expose_pad (dbin, src, pad, group);
return;
}
unknown_type:
{
GST_LOG_OBJECT (pad, "Unknown type, firing signal");
@ -861,7 +906,6 @@ unknown_type:
gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
return;
}
non_fixed:
{
GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");

View file

@ -33,6 +33,8 @@
#include <gst/gst.h>
#include <gst/gst-i18n-plugin.h>
#include "gstplay-marshal.h"
#define GST_TYPE_URI_DECODE_BIN \
(gst_uri_decode_bin_get_type())
#define GST_URI_DECODE_BIN(obj) \
@ -53,6 +55,8 @@ struct _GstURIDecodeBin
gchar *uri;
guint connection_speed;
GstCaps *caps;
gchar *encoding;
gboolean is_stream;
GstElement *source;
@ -70,6 +74,19 @@ struct _GstURIDecodeBin
struct _GstURIDecodeBinClass
{
GstBinClass parent_class;
/* signal fired when we found a pad that we cannot decode */
void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
/* signal fired to know if we continue trying to decode the given caps */
gboolean (*autoplug_continue) (GstElement * element, GstPad * pad,
GstCaps * caps);
/* signal fired to get a list of factories to try to autoplug */
GValueArray *(*autoplug_factories) (GstElement * element, GstPad * pad,
GstCaps * caps);
/* signal fired to select from the proposed list of factories */
gint (*autoplug_select) (GstElement * element, GstPad * pad, GstCaps * caps,
GValueArray * factories);
};
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src%d",
@ -86,16 +103,34 @@ GST_ELEMENT_DETAILS ("URI Decoder",
"Autoplug and decode an URI to raw media",
"Wim Taymans <wim@fluendo.com>");
/* signals */
enum
{
SIGNAL_UNKNOWN_TYPE,
SIGNAL_AUTOPLUG_CONTINUE,
SIGNAL_AUTOPLUG_FACTORIES,
SIGNAL_AUTOPLUG_SELECT,
LAST_SIGNAL
};
/* properties */
#define DEFAULT_PROP_URI NULL
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_CAPS NULL
#define DEFAULT_SUBTITLE_ENCODING NULL
enum
{
PROP_0,
PROP_URI,
PROP_CONNECTION_SPEED,
PROP_CAPS,
PROP_SUBTITLE_ENCODING,
PROP_LAST
};
static guint gst_uri_decode_bin_signals[LAST_SIGNAL] = { 0 };
GST_BOILERPLATE (GstURIDecodeBin, gst_uri_decode_bin, GstBin, GST_TYPE_BIN);
static void gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
@ -119,6 +154,20 @@ gst_uri_decode_bin_base_init (gpointer g_class)
gst_element_class_set_details (gstelement_class, &gst_uri_decode_bin_details);
}
static gboolean
_gst_boolean_accumulator (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer dummy)
{
gboolean myboolean;
myboolean = g_value_get_boolean (handler_return);
if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
g_value_set_boolean (return_accu, myboolean);
/* stop emission if FALSE */
return myboolean;
}
static void
gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
{
@ -143,6 +192,93 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
"Network connection speed in kbps (0 = unknown)",
0, G_MAXUINT, DEFAULT_CONNECTION_SPEED, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_CAPS,
g_param_spec_boxed ("caps", "Caps",
"The caps on which to stop decoding. (NULL = default)",
GST_TYPE_CAPS, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_SUBTITLE_ENCODING,
g_param_spec_string ("subtitle-encoding", "subtitle encoding",
"Encoding to assume if input subtitles are not in UTF-8 encoding. "
"If not set, the GST_SUBTITLE_ENCODING environment variable will "
"be checked for an encoding to use. If that is not set either, "
"ISO-8859-15 will be assumed.", NULL, G_PARAM_READWRITE));
/**
* GstURIDecodeBin::unknown-type:
* @pad: the new pad containing caps that cannot be resolved to a 'final' stream type.
* @caps: the #GstCaps of the pad that cannot be resolved.
*
* This signal is emitted when a pad for which there is no further possible
* decoding is added to the uridecodebin.
*/
gst_uri_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass, unknown_type),
NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_PAD, GST_TYPE_CAPS);
/**
* GstURIDecodeBin::autoplug-continue:
* @pad: The #GstPad.
* @caps: The #GstCaps found.
*
* This signal is emitted whenever uridecodebin finds a new stream. It is
* emitted before looking for any elements that can handle that stream.
*
* Returns: #TRUE if you wish uridecodebin to look for elements that can
* handle the given @caps. If #FALSE, those caps will be considered as
* final and the pad will be exposed as such (see 'new-decoded-pad'
* signal).
*/
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass,
autoplug_continue), _gst_boolean_accumulator, NULL,
gst_play_marshal_BOOLEAN__OBJECT_OBJECT, G_TYPE_BOOLEAN, 2, GST_TYPE_PAD,
GST_TYPE_CAPS);
/**
* GstURIDecodeBin::autoplug-factories:
* @pad: The #GstPad.
* @caps: The #GstCaps found.
*
* This function is emited when an array of possible factories for @caps on
* @pad is needed. Decodebin2 will by default return
*
* Returns: a #GValueArray* with a list of factories to try. The factories are
* by default tried in the returned order or based on the index returned by
* "autoplug-select".
*/
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES] =
g_signal_new ("autoplug-factories", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass,
autoplug_factories), NULL, NULL,
gst_play_marshal_BOXED__OBJECT_OBJECT, G_TYPE_VALUE_ARRAY, 2,
GST_TYPE_PAD, GST_TYPE_CAPS);
/**
* GstURIDecodeBin::autoplug-select:
* @pad: The #GstPad.
* @caps: The #GstCaps.
* @factories: A #GValueArray of possible #GstElementFactory to use, sorted by
* rank (higher ranks come first).
*
* This signal is emitted once uridecodebin has found all the possible
* #GstElementFactory that can be used to handle the given @caps.
*
* Returns: A #gint indicating what factory index from the @factories array
* that you wish uridecodebin to use for trying to decode the given @caps.
* -1 to stop selection of a factory. The default handler always
* returns the first possible factory.
*/
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass,
autoplug_select), NULL, NULL,
gst_play_marshal_INT__OBJECT_OBJECT_BOXED, G_TYPE_INT, 3, GST_TYPE_PAD,
GST_TYPE_CAPS, G_TYPE_VALUE_ARRAY);
gstelement_class->query = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_query);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_uri_decode_bin_change_state);
@ -152,7 +288,9 @@ static void
gst_uri_decode_bin_init (GstURIDecodeBin * dec, GstURIDecodeBinClass * klass)
{
dec->uri = g_strdup (DEFAULT_PROP_URI);
dec->uri = DEFAULT_CONNECTION_SPEED;
dec->connection_speed = DEFAULT_CONNECTION_SPEED;
dec->caps = DEFAULT_CAPS;
dec->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);
}
static void
@ -161,7 +299,7 @@ gst_uri_decode_bin_finalize (GObject * obj)
GstURIDecodeBin *dec = GST_URI_DECODE_BIN (obj);
g_free (dec->uri);
dec->uri = NULL;
g_free (dec->encoding);
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@ -174,11 +312,28 @@ gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_URI:
GST_OBJECT_LOCK (dec);
g_free (dec->uri);
dec->uri = g_value_dup_string (value);
GST_OBJECT_UNLOCK (dec);
break;
case PROP_CONNECTION_SPEED:
GST_OBJECT_LOCK (dec);
dec->connection_speed = g_value_get_uint (value) * 1000;
GST_OBJECT_UNLOCK (dec);
break;
case PROP_CAPS:
GST_OBJECT_LOCK (dec);
if (dec->caps)
gst_caps_unref (dec->caps);
dec->caps = g_value_dup_boxed (value);
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);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -194,10 +349,24 @@ gst_uri_decode_bin_get_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_URI:
GST_OBJECT_LOCK (dec);
g_value_set_string (value, dec->uri);
GST_OBJECT_UNLOCK (dec);
break;
case PROP_CONNECTION_SPEED:
GST_OBJECT_LOCK (dec);
g_value_set_uint (value, dec->connection_speed / 1000);
GST_OBJECT_UNLOCK (dec);
break;
case PROP_CAPS:
GST_OBJECT_LOCK (dec);
g_value_set_boxed (value, dec->caps);
GST_OBJECT_UNLOCK (dec);
break;
case PROP_SUBTITLE_ENCODING:
GST_OBJECT_LOCK (dec);
g_value_set_string (value, dec->encoding);
GST_OBJECT_UNLOCK (dec);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -602,6 +771,50 @@ remove_pads (GstURIDecodeBin * bin)
bin->srcpads = NULL;
}
static void
proxy_unknown_type_signal (GstElement * element, GstPad * pad, GstCaps * caps,
GstURIDecodeBin * dec)
{
g_signal_emit (G_OBJECT (dec),
gst_uri_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
}
static gboolean
proxy_autoplug_continue_signal (GstElement * element, GstPad * pad,
GstCaps * caps, GstURIDecodeBin * dec)
{
gboolean result;
g_signal_emit (G_OBJECT (dec),
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, pad, caps,
&result);
return result;
}
static GValueArray *
proxy_autoplug_factories_signal (GstElement * element, GstPad * pad,
GstCaps * caps, GstURIDecodeBin * dec)
{
GValueArray *result;
g_signal_emit (G_OBJECT (dec),
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, pad, caps,
&result);
return result;
}
static gint
proxy_autoplug_select_signal (GstElement * element, GstPad * pad,
GstCaps * caps, GValueArray * array, GstURIDecodeBin * dec)
{
gint result;
g_signal_emit (G_OBJECT (dec),
gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT], 0, pad, caps, array,
&result);
return result;
}
static GstElement *
make_decoder (GstURIDecodeBin * decoder, gboolean use_queue)
{
@ -612,6 +825,16 @@ make_decoder (GstURIDecodeBin * decoder, gboolean use_queue)
if (!decodebin)
goto no_decodebin;
/* connect signals to proxy */
g_signal_connect (G_OBJECT (decodebin), "unknown-type",
G_CALLBACK (proxy_unknown_type_signal), decoder);
g_signal_connect (G_OBJECT (decodebin), "autoplug-continue",
G_CALLBACK (proxy_autoplug_continue_signal), decoder);
g_signal_connect (G_OBJECT (decodebin), "autoplug-factories",
G_CALLBACK (proxy_autoplug_factories_signal), decoder);
g_signal_connect (G_OBJECT (decodebin), "autoplug-select",
G_CALLBACK (proxy_autoplug_select_signal), decoder);
if (use_queue) {
GstElement *queue;
GstPad *gpad, *pad;