mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
gst/playback/gstdecodebin2.c (struct _GstDecodePad): Change to be a subclass of GstGhostPad.
Original commit message from CVS: 2008-10-08 Andy Wingo <wingo@pobox.com> * gst/playback/gstdecodebin2.c (struct _GstDecodePad): Change to be a subclass of GstGhostPad. (analyze_new_pad): So, when emitting the signals that determine how we do autoplugging, already create the ghost pad and use it as the pad in the signal arguments. This allows applications to make a connection between the pad passed in e.g. autoplug-continue, and the pad passed in new-decoded-pad. (connect_pad, expose_pad): Update to receive the ghosted decode pad in the args, retargetting it as necessary if we have to plug the target pad through a multiqueue. (gst_decode_group_control_source_pad): Adapt to receive an already-ghosted pad that just needs activation, blocking, and drain notification. (sort_end_pads): Adapt for decode pads actually being pads. (gst_decode_group_expose): Adapt for decode pads actually being pads. Rewrite the decode pad names so they appear in order. Adds a new error case if we couldn't set the name. (gst_decode_group_free, gst_decode_group_hide): Adapt cleanup logic. (gst_decode_pad_set_blocked, gst_decode_pad_add_drained_check): New API for the decode pad, needed because we shouldn't do these things inside gst_decode_pad_new(), but after. (gst_decode_pad_new): Change to actually make the real pad, and delay the blocking/drainage bits.
This commit is contained in:
parent
43e1dcbd18
commit
6c7e1c8a9b
2 changed files with 150 additions and 100 deletions
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
||||||
|
2008-10-08 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* gst/playback/gstdecodebin2.c (struct _GstDecodePad): Change to
|
||||||
|
be a subclass of GstGhostPad.
|
||||||
|
(analyze_new_pad): So, when emitting the signals that determine
|
||||||
|
how we do autoplugging, already create the ghost pad and use it as
|
||||||
|
the pad in the signal arguments. This allows applications to make
|
||||||
|
a connection between the pad passed in e.g. autoplug-continue, and
|
||||||
|
the pad passed in new-decoded-pad.
|
||||||
|
(connect_pad, expose_pad): Update to receive the ghosted decode
|
||||||
|
pad in the args, retargetting it as necessary if we have to plug
|
||||||
|
the target pad through a multiqueue.
|
||||||
|
(gst_decode_group_control_source_pad): Adapt to receive an
|
||||||
|
already-ghosted pad that just needs activation, blocking, and
|
||||||
|
drain notification.
|
||||||
|
(sort_end_pads): Adapt for decode pads actually being pads.
|
||||||
|
(gst_decode_group_expose): Adapt for decode pads actually being
|
||||||
|
pads. Rewrite the decode pad names so they appear in order. Adds a
|
||||||
|
new error case if we couldn't set the name.
|
||||||
|
(gst_decode_group_free, gst_decode_group_hide): Adapt cleanup
|
||||||
|
logic.
|
||||||
|
(gst_decode_pad_set_blocked, gst_decode_pad_add_drained_check):
|
||||||
|
New API for the decode pad, needed because we shouldn't do these
|
||||||
|
things inside gst_decode_pad_new(), but after.
|
||||||
|
(gst_decode_pad_new): Change to actually make the real pad, and
|
||||||
|
delay the blocking/drainage bits.
|
||||||
|
|
||||||
2008-10-08 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2008-10-08 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
Patch by: Daniel Drake <dsd at laptop dot org>
|
Patch by: Daniel Drake <dsd at laptop dot org>
|
||||||
|
|
|
@ -63,6 +63,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
|
||||||
|
|
||||||
typedef struct _GstDecodeGroup GstDecodeGroup;
|
typedef struct _GstDecodeGroup GstDecodeGroup;
|
||||||
typedef struct _GstDecodePad GstDecodePad;
|
typedef struct _GstDecodePad GstDecodePad;
|
||||||
|
typedef GstGhostPadClass GstDecodePadClass;
|
||||||
typedef struct _GstDecodeBin GstDecodeBin;
|
typedef struct _GstDecodeBin GstDecodeBin;
|
||||||
typedef struct _GstDecodeBin GstDecodeBin2;
|
typedef struct _GstDecodeBin GstDecodeBin2;
|
||||||
typedef struct _GstDecodeBinClass GstDecodeBinClass;
|
typedef struct _GstDecodeBinClass GstDecodeBinClass;
|
||||||
|
@ -234,7 +235,6 @@ struct _GstDecodeGroup
|
||||||
guint nbdynamic; /* number of dynamic pads in the group. */
|
guint nbdynamic; /* number of dynamic pads in the group. */
|
||||||
|
|
||||||
GList *endpads; /* List of GstDecodePad of source pads to be exposed */
|
GList *endpads; /* List of GstDecodePad of source pads to be exposed */
|
||||||
GList *ghosts; /* List of GstGhostPad for the endpads */
|
|
||||||
GList *reqpads; /* List of RequestPads for multiqueue. */
|
GList *reqpads; /* List of RequestPads for multiqueue. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ static GstDecodeGroup *gst_decode_group_new (GstDecodeBin * decode_bin,
|
||||||
static GstPad *gst_decode_group_control_demuxer_pad (GstDecodeGroup * group,
|
static GstPad *gst_decode_group_control_demuxer_pad (GstDecodeGroup * group,
|
||||||
GstPad * pad);
|
GstPad * pad);
|
||||||
static gboolean gst_decode_group_control_source_pad (GstDecodeGroup * group,
|
static gboolean gst_decode_group_control_source_pad (GstDecodeGroup * group,
|
||||||
GstPad * pad);
|
GstDecodePad * pad);
|
||||||
static gboolean gst_decode_group_expose (GstDecodeGroup * group);
|
static gboolean gst_decode_group_expose (GstDecodeGroup * group);
|
||||||
static void gst_decode_group_check_if_blocked (GstDecodeGroup * group);
|
static void gst_decode_group_check_if_blocked (GstDecodeGroup * group);
|
||||||
static void gst_decode_group_set_complete (GstDecodeGroup * group);
|
static void gst_decode_group_set_complete (GstDecodeGroup * group);
|
||||||
|
@ -275,16 +275,21 @@ static void gst_decode_group_free (GstDecodeGroup * group);
|
||||||
|
|
||||||
struct _GstDecodePad
|
struct _GstDecodePad
|
||||||
{
|
{
|
||||||
GstPad *pad;
|
GstGhostPad parent;
|
||||||
|
GstDecodeBin *dbin;
|
||||||
GstDecodeGroup *group;
|
GstDecodeGroup *group;
|
||||||
gboolean blocked;
|
gboolean blocked;
|
||||||
gboolean drained;
|
gboolean drained;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstDecodePad *gst_decode_pad_new (GstDecodeGroup * group, GstPad * pad,
|
G_DEFINE_TYPE (GstDecodePad, gst_decode_pad, GST_TYPE_GHOST_PAD);
|
||||||
gboolean block);
|
#define GST_TYPE_DECODE_PAD (gst_decode_pad_get_type ())
|
||||||
static void source_pad_blocked_cb (GstPad * pad, gboolean blocked,
|
#define GST_DECODE_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_PAD,GstDecodePad))
|
||||||
GstDecodePad * dpad);
|
|
||||||
|
static GstDecodePad *gst_decode_pad_new (GstDecodeBin * dbin, GstPad * pad,
|
||||||
|
GstDecodeGroup * group);
|
||||||
|
static void gst_decode_pad_set_blocked (GstDecodePad * pad, gboolean blocked);
|
||||||
|
static void gst_decode_pad_add_drained_check (GstDecodePad * dpad);
|
||||||
|
|
||||||
/* TempPadStruct
|
/* TempPadStruct
|
||||||
* Internal structure used for pads which have more than one structure.
|
* Internal structure used for pads which have more than one structure.
|
||||||
|
@ -895,12 +900,12 @@ static gboolean are_raw_caps (GstDecodeBin * dbin, GstCaps * caps);
|
||||||
static gboolean is_demuxer_element (GstElement * srcelement);
|
static gboolean is_demuxer_element (GstElement * srcelement);
|
||||||
|
|
||||||
static gboolean connect_pad (GstDecodeBin * dbin, GstElement * src,
|
static gboolean connect_pad (GstDecodeBin * dbin, GstElement * src,
|
||||||
GstPad * pad, GstCaps * caps, GValueArray * factories,
|
GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GValueArray * factories,
|
||||||
GstDecodeGroup * group);
|
GstDecodeGroup * group);
|
||||||
static gboolean connect_element (GstDecodeBin * dbin, GstElement * element,
|
static gboolean connect_element (GstDecodeBin * dbin, GstElement * element,
|
||||||
GstDecodeGroup * group);
|
GstDecodeGroup * group);
|
||||||
static void expose_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
static void expose_pad (GstDecodeBin * dbin, GstElement * src,
|
||||||
GstDecodeGroup * group);
|
GstDecodePad * dpad, GstPad * pad, GstDecodeGroup * group);
|
||||||
|
|
||||||
static void pad_added_group_cb (GstElement * element, GstPad * pad,
|
static void pad_added_group_cb (GstElement * element, GstPad * pad,
|
||||||
GstDecodeGroup * group);
|
GstDecodeGroup * group);
|
||||||
|
@ -934,6 +939,7 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
{
|
{
|
||||||
gboolean apcontinue = TRUE;
|
gboolean apcontinue = TRUE;
|
||||||
GValueArray *factories = NULL, *result = NULL;
|
GValueArray *factories = NULL, *result = NULL;
|
||||||
|
GstDecodePad *dpad;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dbin, "Pad %s:%s caps:%" GST_PTR_FORMAT,
|
GST_DEBUG_OBJECT (dbin, "Pad %s:%s caps:%" GST_PTR_FORMAT,
|
||||||
GST_DEBUG_PAD_NAME (pad), caps);
|
GST_DEBUG_PAD_NAME (pad), caps);
|
||||||
|
@ -944,10 +950,12 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
if (gst_caps_is_any (caps))
|
if (gst_caps_is_any (caps))
|
||||||
goto any_caps;
|
goto any_caps;
|
||||||
|
|
||||||
|
dpad = gst_decode_pad_new (dbin, pad, group);
|
||||||
|
|
||||||
/* 1. Emit 'autoplug-continue' the result will tell us if this pads needs
|
/* 1. Emit 'autoplug-continue' the result will tell us if this pads needs
|
||||||
* further autoplugging. */
|
* further autoplugging. */
|
||||||
g_signal_emit (G_OBJECT (dbin),
|
g_signal_emit (G_OBJECT (dbin),
|
||||||
gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, pad, caps,
|
gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, dpad, caps,
|
||||||
&apcontinue);
|
&apcontinue);
|
||||||
|
|
||||||
/* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
|
/* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
|
||||||
|
@ -962,7 +970,7 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
/* 1.c else get the factories and if there's no compatible factory goto
|
/* 1.c else get the factories and if there's no compatible factory goto
|
||||||
* unknown_type */
|
* unknown_type */
|
||||||
g_signal_emit (G_OBJECT (dbin),
|
g_signal_emit (G_OBJECT (dbin),
|
||||||
gst_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, pad, caps,
|
gst_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, dpad, caps,
|
||||||
&factories);
|
&factories);
|
||||||
|
|
||||||
/* NULL means that we can expose the pad */
|
/* NULL means that we can expose the pad */
|
||||||
|
@ -973,20 +981,22 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
if (factories->n_values == 0) {
|
if (factories->n_values == 0) {
|
||||||
/* no compatible factories */
|
/* no compatible factories */
|
||||||
g_value_array_free (factories);
|
g_value_array_free (factories);
|
||||||
|
gst_object_unref (dpad);
|
||||||
goto unknown_type;
|
goto unknown_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1.d sort some more. */
|
/* 1.d sort some more. */
|
||||||
g_signal_emit (G_OBJECT (dbin),
|
g_signal_emit (G_OBJECT (dbin),
|
||||||
gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, pad, caps, factories,
|
gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, dpad, caps, factories,
|
||||||
&result);
|
&result);
|
||||||
g_value_array_free (factories);
|
g_value_array_free (factories);
|
||||||
factories = result;
|
factories = result;
|
||||||
|
|
||||||
/* 1.e else continue autoplugging something from the list. */
|
/* 1.e else continue autoplugging something from the list. */
|
||||||
GST_LOG_OBJECT (pad, "Let's continue discovery on this pad");
|
GST_LOG_OBJECT (pad, "Let's continue discovery on this pad");
|
||||||
connect_pad (dbin, src, pad, caps, factories, group);
|
connect_pad (dbin, src, dpad, pad, caps, factories, group);
|
||||||
|
|
||||||
|
gst_object_unref (dpad);
|
||||||
g_value_array_free (factories);
|
g_value_array_free (factories);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -994,7 +1004,8 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
expose_pad:
|
expose_pad:
|
||||||
{
|
{
|
||||||
GST_LOG_OBJECT (dbin, "Pad is final. autoplug-continue:%d", apcontinue);
|
GST_LOG_OBJECT (dbin, "Pad is final. autoplug-continue:%d", apcontinue);
|
||||||
expose_pad (dbin, src, pad, group);
|
expose_pad (dbin, src, dpad, pad, group);
|
||||||
|
gst_object_unref (dpad);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unknown_type:
|
unknown_type:
|
||||||
|
@ -1027,6 +1038,7 @@ unknown_type:
|
||||||
non_fixed:
|
non_fixed:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");
|
GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");
|
||||||
|
gst_object_unref (dpad);
|
||||||
goto setup_caps_delay;
|
goto setup_caps_delay;
|
||||||
}
|
}
|
||||||
any_caps:
|
any_caps:
|
||||||
|
@ -1058,11 +1070,15 @@ setup_caps_delay:
|
||||||
* Try to connect the given pad to an element created from one of the factories,
|
* Try to connect the given pad to an element created from one of the factories,
|
||||||
* and recursively.
|
* and recursively.
|
||||||
*
|
*
|
||||||
|
* Note that dpad is ghosting pad, and so pad is linked; be sure to unset dpad's
|
||||||
|
* target before trying to link pad.
|
||||||
|
*
|
||||||
* Returns TRUE if an element was properly created and linked
|
* Returns TRUE if an element was properly created and linked
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
GstCaps * caps, GValueArray * factories, GstDecodeGroup * group)
|
GstPad * pad, GstCaps * caps, GValueArray * factories,
|
||||||
|
GstDecodeGroup * group)
|
||||||
{
|
{
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
GstPad *mqpad = NULL;
|
GstPad *mqpad = NULL;
|
||||||
|
@ -1086,10 +1102,12 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
DECODE_BIN_UNLOCK (dbin);
|
DECODE_BIN_UNLOCK (dbin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (dpad), NULL);
|
||||||
if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
|
if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
|
||||||
goto beach;
|
goto beach;
|
||||||
src = group->multiqueue;
|
src = group->multiqueue;
|
||||||
pad = mqpad;
|
pad = mqpad;
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (dpad), pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. Try to create an element and link to it */
|
/* 2. Try to create an element and link to it */
|
||||||
|
@ -1108,7 +1126,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
/* emit autoplug-select to see what we should do with it. */
|
/* emit autoplug-select to see what we should do with it. */
|
||||||
g_signal_emit (G_OBJECT (dbin),
|
g_signal_emit (G_OBJECT (dbin),
|
||||||
gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT],
|
gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT],
|
||||||
0, pad, caps, factory, &ret);
|
0, dpad, caps, factory, &ret);
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case GST_AUTOPLUG_SELECT_TRY:
|
case GST_AUTOPLUG_SELECT_TRY:
|
||||||
|
@ -1117,7 +1135,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
case GST_AUTOPLUG_SELECT_EXPOSE:
|
case GST_AUTOPLUG_SELECT_EXPOSE:
|
||||||
GST_DEBUG_OBJECT (dbin, "autoplug select requested expose");
|
GST_DEBUG_OBJECT (dbin, "autoplug select requested expose");
|
||||||
/* expose the pad, we don't have the source element */
|
/* expose the pad, we don't have the source element */
|
||||||
expose_pad (dbin, src, pad, group);
|
expose_pad (dbin, src, dpad, pad, group);
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
goto beach;
|
goto beach;
|
||||||
case GST_AUTOPLUG_SELECT_SKIP:
|
case GST_AUTOPLUG_SELECT_SKIP:
|
||||||
|
@ -1128,6 +1146,9 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 2.0. Unlink pad */
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (dpad), NULL);
|
||||||
|
|
||||||
/* 2.1. Try to create an element */
|
/* 2.1. Try to create an element */
|
||||||
if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
|
if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
|
||||||
GST_WARNING_OBJECT (dbin, "Could not create an element from %s",
|
GST_WARNING_OBJECT (dbin, "Could not create an element from %s",
|
||||||
|
@ -1339,8 +1360,8 @@ connect_element (GstDecodeBin * dbin, GstElement * element,
|
||||||
* If group is NULL, a GstDecodeGroup will be created and setup properly.
|
* If group is NULL, a GstDecodeGroup will be created and setup properly.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
expose_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
expose_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
GstDecodeGroup * group)
|
GstPad * pad, GstDecodeGroup * group)
|
||||||
{
|
{
|
||||||
gboolean newgroup = FALSE;
|
gboolean newgroup = FALSE;
|
||||||
gboolean isdemux;
|
gboolean isdemux;
|
||||||
|
@ -1364,12 +1385,14 @@ expose_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
if (isdemux) {
|
if (isdemux) {
|
||||||
GST_LOG_OBJECT (src, "connecting the pad through multiqueue");
|
GST_LOG_OBJECT (src, "connecting the pad through multiqueue");
|
||||||
|
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (dpad), pad);
|
||||||
if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
|
if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
|
||||||
goto beach;
|
goto beach;
|
||||||
pad = mqpad;
|
pad = mqpad;
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (dpad), pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_decode_group_control_source_pad (group, pad);
|
gst_decode_group_control_source_pad (group, dpad);
|
||||||
|
|
||||||
if (newgroup && !isdemux) {
|
if (newgroup && !isdemux) {
|
||||||
/* If we have discovered a raw pad and it doesn't belong to any group,
|
/* If we have discovered a raw pad and it doesn't belong to any group,
|
||||||
|
@ -1754,26 +1777,20 @@ beach:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_decode_group_control_source_pad (GstDecodeGroup * group, GstPad * pad)
|
gst_decode_group_control_source_pad (GstDecodeGroup * group,
|
||||||
|
GstDecodePad * dpad)
|
||||||
{
|
{
|
||||||
GstDecodePad *dpad;
|
|
||||||
|
|
||||||
g_return_val_if_fail (group != NULL, FALSE);
|
g_return_val_if_fail (group != NULL, FALSE);
|
||||||
|
|
||||||
GST_LOG ("group:%p , pad %s:%s", group, GST_DEBUG_PAD_NAME (pad));
|
GST_DEBUG_OBJECT (dpad, "adding decode pad to group %p", group);
|
||||||
|
|
||||||
/* FIXME : check if pad is already controlled */
|
/* FIXME : check if pad is already controlled */
|
||||||
|
gst_pad_set_active (GST_PAD (dpad), TRUE);
|
||||||
|
gst_decode_pad_set_blocked (dpad, TRUE);
|
||||||
|
gst_decode_pad_add_drained_check (dpad);
|
||||||
|
|
||||||
GROUP_MUTEX_LOCK (group);
|
GROUP_MUTEX_LOCK (group);
|
||||||
|
group->endpads = g_list_append (group->endpads, gst_object_ref (dpad));
|
||||||
/* Create GstDecodePad for the pad */
|
|
||||||
if ((dpad = gst_decode_pad_new (group, pad, TRUE))) {
|
|
||||||
GST_WARNING ("created decode pad %p in group %p", dpad, group);
|
|
||||||
group->endpads = g_list_append (group->endpads, dpad);
|
|
||||||
} else {
|
|
||||||
GST_WARNING ("could not create a decode pad in group %p", group);
|
|
||||||
}
|
|
||||||
|
|
||||||
GROUP_MUTEX_UNLOCK (group);
|
GROUP_MUTEX_UNLOCK (group);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1893,17 +1910,13 @@ done:
|
||||||
static gint
|
static gint
|
||||||
sort_end_pads (GstDecodePad * da, GstDecodePad * db)
|
sort_end_pads (GstDecodePad * da, GstDecodePad * db)
|
||||||
{
|
{
|
||||||
GstPad *a, *b;
|
|
||||||
gint va, vb;
|
gint va, vb;
|
||||||
GstCaps *capsa, *capsb;
|
GstCaps *capsa, *capsb;
|
||||||
GstStructure *sa, *sb;
|
GstStructure *sa, *sb;
|
||||||
const gchar *namea, *nameb;
|
const gchar *namea, *nameb;
|
||||||
|
|
||||||
a = da->pad;
|
capsa = gst_pad_get_caps (GST_PAD (da));
|
||||||
b = db->pad;
|
capsb = gst_pad_get_caps (GST_PAD (db));
|
||||||
|
|
||||||
capsa = gst_pad_get_caps (a);
|
|
||||||
capsb = gst_pad_get_caps (b);
|
|
||||||
|
|
||||||
sa = gst_caps_get_structure ((const GstCaps *) capsa, 0);
|
sa = gst_caps_get_structure ((const GstCaps *) capsa, 0);
|
||||||
sb = gst_caps_get_structure ((const GstCaps *) capsb, 0);
|
sb = gst_caps_get_structure ((const GstCaps *) capsb, 0);
|
||||||
|
@ -2005,35 +2018,28 @@ gst_decode_group_expose (GstDecodeGroup * group)
|
||||||
for (tmp = group->endpads; tmp; tmp = next) {
|
for (tmp = group->endpads; tmp; tmp = next) {
|
||||||
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
||||||
gchar *padname;
|
gchar *padname;
|
||||||
GstPad *ghost;
|
|
||||||
|
|
||||||
next = g_list_next (tmp);
|
next = g_list_next (tmp);
|
||||||
|
|
||||||
/* 1. ghost pad */
|
/* 1. rewrite name */
|
||||||
padname = g_strdup_printf ("src%d", dbin->nbpads);
|
padname = g_strdup_printf ("src%d", dbin->nbpads);
|
||||||
dbin->nbpads++;
|
dbin->nbpads++;
|
||||||
|
GST_DEBUG_OBJECT (dbin, "About to expose dpad %s as %s",
|
||||||
GST_LOG_OBJECT (dbin, "About to expose pad %s:%s",
|
GST_OBJECT_NAME (dpad), padname);
|
||||||
GST_DEBUG_PAD_NAME (dpad->pad));
|
gst_object_set_name (GST_OBJECT (dpad), padname);
|
||||||
|
|
||||||
ghost = gst_ghost_pad_new (padname, dpad->pad);
|
|
||||||
/* the ghostpad can be NULL when we failed to link or some other error
|
|
||||||
* occured */
|
|
||||||
if (ghost) {
|
|
||||||
gst_pad_set_active (ghost, TRUE);
|
|
||||||
gst_element_add_pad (GST_ELEMENT (dbin), ghost);
|
|
||||||
group->ghosts = g_list_append (group->ghosts, ghost);
|
|
||||||
|
|
||||||
/* 2. emit signal */
|
|
||||||
GST_DEBUG_OBJECT (dbin, "emitting new-decoded-pad");
|
|
||||||
g_signal_emit (G_OBJECT (dbin),
|
|
||||||
gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD], 0, ghost,
|
|
||||||
(next == NULL));
|
|
||||||
GST_DEBUG_OBJECT (dbin, "emitted new-decoded-pad");
|
|
||||||
} else {
|
|
||||||
GST_WARNING_OBJECT (dbin, "failed to create ghostpad");
|
|
||||||
}
|
|
||||||
g_free (padname);
|
g_free (padname);
|
||||||
|
|
||||||
|
/* 2. activate and add */
|
||||||
|
if (!gst_element_add_pad (GST_ELEMENT (dbin), GST_PAD (dpad)))
|
||||||
|
goto name_problem;
|
||||||
|
|
||||||
|
/* 3. emit signal */
|
||||||
|
GST_DEBUG_OBJECT (dbin, "emitting new-decoded-pad");
|
||||||
|
g_signal_emit (G_OBJECT (dbin),
|
||||||
|
gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD], 0, dpad,
|
||||||
|
(next == NULL));
|
||||||
|
GST_DEBUG_OBJECT (dbin, "emitted new-decoded-pad");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signal no-more-pads. This allows the application to hook stuff to the
|
/* signal no-more-pads. This allows the application to hook stuff to the
|
||||||
|
@ -2041,17 +2047,16 @@ gst_decode_group_expose (GstDecodeGroup * group)
|
||||||
GST_LOG_OBJECT (dbin, "signalling no-more-pads");
|
GST_LOG_OBJECT (dbin, "signalling no-more-pads");
|
||||||
gst_element_no_more_pads (GST_ELEMENT (dbin));
|
gst_element_no_more_pads (GST_ELEMENT (dbin));
|
||||||
|
|
||||||
/* 3. Unblock internal pads. The application should have connected stuff now
|
/* 4. Unblock internal pads. The application should have connected stuff now
|
||||||
* so that streaming can continue. */
|
* so that streaming can continue. */
|
||||||
for (tmp = group->endpads; tmp; tmp = next) {
|
for (tmp = group->endpads; tmp; tmp = next) {
|
||||||
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
||||||
|
|
||||||
next = g_list_next (tmp);
|
next = g_list_next (tmp);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dpad->pad, "unblocking");
|
GST_DEBUG_OBJECT (dpad, "unblocking");
|
||||||
gst_pad_set_blocked_async (dpad->pad, FALSE,
|
gst_decode_pad_set_blocked (dpad, FALSE);
|
||||||
(GstPadBlockCallback) source_pad_blocked_cb, dpad);
|
GST_DEBUG_OBJECT (dpad, "unblocked");
|
||||||
GST_DEBUG_OBJECT (dpad->pad, "unblocked");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dbin->activegroup = group;
|
dbin->activegroup = group;
|
||||||
|
@ -2070,6 +2075,10 @@ gst_decode_group_expose (GstDecodeGroup * group)
|
||||||
|
|
||||||
GST_LOG_OBJECT (dbin, "Group %p exposed", group);
|
GST_LOG_OBJECT (dbin, "Group %p exposed", group);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
name_problem:
|
||||||
|
g_warning ("error adding pad to decodebin2");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2087,11 +2096,8 @@ gst_decode_group_hide (GstDecodeGroup * group)
|
||||||
GROUP_MUTEX_LOCK (group);
|
GROUP_MUTEX_LOCK (group);
|
||||||
|
|
||||||
/* Remove ghost pads */
|
/* Remove ghost pads */
|
||||||
for (tmp = group->ghosts; tmp; tmp = g_list_next (tmp))
|
for (tmp = group->endpads; tmp; tmp = g_list_next (tmp))
|
||||||
gst_element_remove_pad (GST_ELEMENT (group->dbin), (GstPad *) tmp->data);
|
gst_element_remove_pad (GST_ELEMENT (group->dbin), GST_PAD (tmp->data));
|
||||||
|
|
||||||
g_list_free (group->ghosts);
|
|
||||||
group->ghosts = NULL;
|
|
||||||
|
|
||||||
group->exposed = FALSE;
|
group->exposed = FALSE;
|
||||||
|
|
||||||
|
@ -2178,21 +2184,14 @@ gst_decode_group_free (GstDecodeGroup * group)
|
||||||
|
|
||||||
GROUP_MUTEX_LOCK (group);
|
GROUP_MUTEX_LOCK (group);
|
||||||
|
|
||||||
/* free ghost pads */
|
/* remove exposed pads */
|
||||||
if (group == group->dbin->activegroup) {
|
if (group == group->dbin->activegroup)
|
||||||
for (tmp = group->ghosts; tmp; tmp = g_list_next (tmp))
|
for (tmp = group->endpads; tmp; tmp = g_list_next (tmp))
|
||||||
gst_element_remove_pad (GST_ELEMENT (group->dbin), (GstPad *) tmp->data);
|
gst_element_remove_pad (GST_ELEMENT (group->dbin), GST_PAD (tmp->data));
|
||||||
|
|
||||||
g_list_free (group->ghosts);
|
|
||||||
group->ghosts = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear all GstDecodePad */
|
/* Clear all GstDecodePad */
|
||||||
for (tmp = group->endpads; tmp; tmp = g_list_next (tmp)) {
|
for (tmp = group->endpads; tmp; tmp = g_list_next (tmp))
|
||||||
GstDecodePad *dpad = (GstDecodePad *) tmp->data;
|
gst_object_unref (tmp->data);
|
||||||
|
|
||||||
g_free (dpad);
|
|
||||||
}
|
|
||||||
g_list_free (group->endpads);
|
g_list_free (group->endpads);
|
||||||
group->endpads = NULL;
|
group->endpads = NULL;
|
||||||
|
|
||||||
|
@ -2243,10 +2242,24 @@ gst_decode_group_set_complete (GstDecodeGroup * group)
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
source_pad_blocked_cb (GstPad * pad, gboolean blocked, GstDecodePad * dpad)
|
gst_decode_pad_class_init (GstDecodePadClass * klass)
|
||||||
{
|
{
|
||||||
GST_LOG_OBJECT (pad, "blocked:%d , dpad:%p, dpad->group:%p",
|
}
|
||||||
blocked, dpad, dpad->group);
|
|
||||||
|
static void
|
||||||
|
gst_decode_pad_init (GstDecodePad * pad)
|
||||||
|
{
|
||||||
|
pad->group = NULL;
|
||||||
|
pad->blocked = FALSE;
|
||||||
|
pad->drained = TRUE;
|
||||||
|
gst_object_ref (pad);
|
||||||
|
gst_object_sink (pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
source_pad_blocked_cb (GstDecodePad * dpad, gboolean blocked, gpointer unused)
|
||||||
|
{
|
||||||
|
GST_LOG_OBJECT (dpad, "blocked:%d, dpad->group:%p", blocked, dpad->group);
|
||||||
|
|
||||||
/* Update this GstDecodePad status */
|
/* Update this GstDecodePad status */
|
||||||
dpad->blocked = blocked;
|
dpad->blocked = blocked;
|
||||||
|
@ -2278,26 +2291,36 @@ source_pad_event_probe (GstPad * pad, GstEvent * event, GstDecodePad * dpad)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked)
|
||||||
|
{
|
||||||
|
gst_pad_set_blocked_async (GST_PAD (dpad), blocked,
|
||||||
|
(GstPadBlockCallback) source_pad_blocked_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_decode_pad_add_drained_check (GstDecodePad * dpad)
|
||||||
|
{
|
||||||
|
gst_pad_add_event_probe (GST_PAD (dpad),
|
||||||
|
G_CALLBACK (source_pad_event_probe), dpad);
|
||||||
|
}
|
||||||
|
|
||||||
/*gst_decode_pad_new:
|
/*gst_decode_pad_new:
|
||||||
*
|
*
|
||||||
* Creates a new GstDecodePad for the given pad.
|
* Creates a new GstDecodePad for the given pad.
|
||||||
* If block is TRUE, Sets the pad blocking asynchronously
|
|
||||||
*/
|
*/
|
||||||
static GstDecodePad *
|
static GstDecodePad *
|
||||||
gst_decode_pad_new (GstDecodeGroup * group, GstPad * pad, gboolean block)
|
gst_decode_pad_new (GstDecodeBin * dbin, GstPad * pad, GstDecodeGroup * group)
|
||||||
{
|
{
|
||||||
GstDecodePad *dpad;
|
GstDecodePad *dpad;
|
||||||
|
|
||||||
dpad = g_new0 (GstDecodePad, 1);
|
dpad =
|
||||||
dpad->pad = pad;
|
g_object_new (GST_TYPE_DECODE_PAD, "direction", GST_PAD_DIRECTION (pad),
|
||||||
|
NULL);
|
||||||
|
gst_ghost_pad_construct (GST_GHOST_PAD (dpad));
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (dpad), pad);
|
||||||
dpad->group = group;
|
dpad->group = group;
|
||||||
dpad->blocked = FALSE;
|
|
||||||
dpad->drained = TRUE;
|
|
||||||
|
|
||||||
if (block)
|
|
||||||
gst_pad_set_blocked_async (pad, TRUE,
|
|
||||||
(GstPadBlockCallback) source_pad_blocked_cb, dpad);
|
|
||||||
gst_pad_add_event_probe (pad, G_CALLBACK (source_pad_event_probe), dpad);
|
|
||||||
return dpad;
|
return dpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue