gst/playback/gstdecodebin2.c: Add support for delayed caps fixation when autoplugging.
Original commit message from CVS: * gst/playback/gstdecodebin2.c: (gst_decode_bin_factory_filter), (analyze_new_pad), (connect_pad), (expose_pad), (caps_notify_cb), (caps_notify_group_cb), (gst_decode_group_new), (gst_decode_group_free): Add support for delayed caps fixation when autoplugging. Optimize cases where a multiqueue is not needed/wanted, like right after anything that is not a demuxer.
This commit is contained in:
parent
c6ecd5bec8
commit
3840b5a20f
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
2007-06-05 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/playback/gstdecodebin2.c: (gst_decode_bin_factory_filter),
|
||||||
|
(analyze_new_pad), (connect_pad), (expose_pad), (caps_notify_cb),
|
||||||
|
(caps_notify_group_cb), (gst_decode_group_new),
|
||||||
|
(gst_decode_group_free):
|
||||||
|
Add support for delayed caps fixation when autoplugging.
|
||||||
|
Optimize cases where a multiqueue is not needed/wanted, like right after
|
||||||
|
anything that is not a demuxer.
|
||||||
|
|
||||||
2007-06-05 Wim Taymans <wim@fluendo.com>
|
2007-06-05 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_parse_skeleton_fisbone),
|
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_parse_skeleton_fisbone),
|
||||||
|
@ -158,6 +158,10 @@ static void gst_decode_bin_get_property (GObject * object, guint prop_id,
|
|||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static void gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps);
|
static void gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps);
|
||||||
static GstCaps *gst_decode_bin_get_caps (GstDecodeBin * dbin);
|
static GstCaps *gst_decode_bin_get_caps (GstDecodeBin * dbin);
|
||||||
|
static void caps_notify_group_cb (GstPad * pad, GParamSpec * unused,
|
||||||
|
GstDecodeGroup * group);
|
||||||
|
static void caps_notify_cb (GstPad * pad, GParamSpec * unused,
|
||||||
|
GstDecodeBin * dbin);
|
||||||
|
|
||||||
static GstPad *find_sink_pad (GstElement * element);
|
static GstPad *find_sink_pad (GstElement * element);
|
||||||
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
||||||
@ -222,7 +226,8 @@ struct _GstDecodeGroup
|
|||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
|
|
||||||
static GstDecodeGroup *gst_decode_group_new (GstDecodeBin * decode_bin);
|
static GstDecodeGroup *gst_decode_group_new (GstDecodeBin * decode_bin,
|
||||||
|
gboolean use_queue);
|
||||||
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,
|
||||||
@ -762,7 +767,12 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
|||||||
if ((!apcontinue) || are_raw_caps (dbin, caps))
|
if ((!apcontinue) || are_raw_caps (dbin, caps))
|
||||||
goto expose_pad;
|
goto expose_pad;
|
||||||
|
|
||||||
/* 1.b else if there's no compatible factory or 'autoplug-sort' returned FALSE, goto pad_not_used */
|
/* 1.b when the caps are not fixed yet, we can't be sure what element to
|
||||||
|
* connect. We delay autoplugging until the caps are fixed */
|
||||||
|
if (!gst_caps_is_fixed (caps))
|
||||||
|
goto non_fixed;
|
||||||
|
|
||||||
|
/* 1.c else if there's no compatible factory or 'autoplug-sort' returned FALSE, goto pad_not_used */
|
||||||
if ((factories = find_compatibles (dbin, caps))) {
|
if ((factories = find_compatibles (dbin, caps))) {
|
||||||
/* emit autoplug-sort */
|
/* emit autoplug-sort */
|
||||||
g_signal_emit (G_OBJECT (dbin),
|
g_signal_emit (G_OBJECT (dbin),
|
||||||
@ -778,7 +788,7 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
|||||||
goto unknown_type;
|
goto unknown_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1.c else goto pad_is_valid */
|
/* 1.d else goto pad_is_valid */
|
||||||
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, factories, group);
|
connect_pad (dbin, src, pad, factories, group);
|
||||||
@ -814,11 +824,26 @@ unknown_type:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
non_fixed:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");
|
||||||
|
goto setup_caps_delay;
|
||||||
|
}
|
||||||
any_caps:
|
any_caps:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (pad,
|
GST_WARNING_OBJECT (pad,
|
||||||
"pad has ANY caps, not able to autoplug to anything");
|
"pad has ANY caps, not able to autoplug to anything");
|
||||||
/* FIXME : connect to caps notification */
|
goto setup_caps_delay;
|
||||||
|
}
|
||||||
|
setup_caps_delay:
|
||||||
|
{
|
||||||
|
/* connect to caps notification */
|
||||||
|
if (group)
|
||||||
|
g_signal_connect (G_OBJECT (pad), "notify::caps",
|
||||||
|
G_CALLBACK (caps_notify_group_cb), group);
|
||||||
|
else
|
||||||
|
g_signal_connect (G_OBJECT (pad), "notify::caps",
|
||||||
|
G_CALLBACK (caps_notify_cb), dbin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -850,7 +875,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
|||||||
|
|
||||||
if (!group)
|
if (!group)
|
||||||
if (!(group = get_current_group (dbin))) {
|
if (!(group = get_current_group (dbin))) {
|
||||||
group = gst_decode_group_new (dbin);
|
group = gst_decode_group_new (dbin, TRUE);
|
||||||
DECODE_BIN_LOCK (dbin);
|
DECODE_BIN_LOCK (dbin);
|
||||||
dbin->groups = g_list_append (dbin->groups, group);
|
dbin->groups = g_list_append (dbin->groups, group);
|
||||||
DECODE_BIN_UNLOCK (dbin);
|
DECODE_BIN_UNLOCK (dbin);
|
||||||
@ -1067,19 +1092,19 @@ expose_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
|||||||
GST_DEBUG_OBJECT (dbin, "pad %s:%s, group:%p",
|
GST_DEBUG_OBJECT (dbin, "pad %s:%s, group:%p",
|
||||||
GST_DEBUG_PAD_NAME (pad), group);
|
GST_DEBUG_PAD_NAME (pad), group);
|
||||||
|
|
||||||
|
isdemux = is_demuxer_element (src);
|
||||||
|
|
||||||
if (!group)
|
if (!group)
|
||||||
if (!(group = get_current_group (dbin))) {
|
if (!(group = get_current_group (dbin))) {
|
||||||
group = gst_decode_group_new (dbin);
|
group = gst_decode_group_new (dbin, isdemux);
|
||||||
DECODE_BIN_LOCK (dbin);
|
DECODE_BIN_LOCK (dbin);
|
||||||
dbin->groups = g_list_append (dbin->groups, group);
|
dbin->groups = g_list_append (dbin->groups, group);
|
||||||
DECODE_BIN_UNLOCK (dbin);
|
DECODE_BIN_UNLOCK (dbin);
|
||||||
newgroup = TRUE;
|
newgroup = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
isdemux = is_demuxer_element (src);
|
if (isdemux) {
|
||||||
|
GST_LOG_OBJECT (src, "connecting the pad through multiqueue");
|
||||||
if (isdemux || newgroup) {
|
|
||||||
GST_LOG_OBJECT (src, "is a demuxer, connecting the pad through multiqueue");
|
|
||||||
|
|
||||||
if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
|
if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
|
||||||
goto beach;
|
goto beach;
|
||||||
@ -1208,6 +1233,35 @@ no_group:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
caps_notify_cb (GstPad * pad, GParamSpec * unused, GstDecodeBin * dbin)
|
||||||
|
{
|
||||||
|
GstElement *element;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (dbin, "Notified caps for pad %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
|
||||||
|
element = GST_ELEMENT_CAST (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
pad_added_cb (element, pad, dbin);
|
||||||
|
|
||||||
|
gst_object_unref (element);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
caps_notify_group_cb (GstPad * pad, GParamSpec * unused, GstDecodeGroup * group)
|
||||||
|
{
|
||||||
|
GstElement *element;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (pad, "Notified caps for pad %s:%s", GST_DEBUG_PAD_NAME (pad));
|
||||||
|
|
||||||
|
element = GST_ELEMENT_CAST (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
pad_added_group_cb (element, pad, group);
|
||||||
|
|
||||||
|
gst_object_unref (element);
|
||||||
|
}
|
||||||
|
|
||||||
/* this function runs through the element factories and returns a list
|
/* this function runs through the element factories and returns a list
|
||||||
* of all elements that are able to sink the given caps
|
* of all elements that are able to sink the given caps
|
||||||
*/
|
*/
|
||||||
@ -1372,22 +1426,22 @@ multi_queue_underrun_cb (GstElement * queue, GstDecodeGroup * group)
|
|||||||
* of groups.
|
* of groups.
|
||||||
*/
|
*/
|
||||||
static GstDecodeGroup *
|
static GstDecodeGroup *
|
||||||
gst_decode_group_new (GstDecodeBin * dbin)
|
gst_decode_group_new (GstDecodeBin * dbin, gboolean use_queue)
|
||||||
{
|
{
|
||||||
GstDecodeGroup *group;
|
GstDecodeGroup *group;
|
||||||
GstElement *mq;
|
GstElement *mq;
|
||||||
|
|
||||||
GST_LOG_OBJECT (dbin, "Creating new group");
|
GST_LOG_OBJECT (dbin, "Creating new group");
|
||||||
|
|
||||||
if (!(mq = gst_element_factory_make ("multiqueue", NULL))) {
|
if (use_queue) {
|
||||||
GST_WARNING ("Couldn't create multiqueue element");
|
if (!(mq = gst_element_factory_make ("multiqueue", NULL))) {
|
||||||
return NULL;
|
GST_WARNING ("Couldn't create multiqueue element");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mq = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_set (G_OBJECT (mq),
|
|
||||||
"max-size-bytes", 2 * 1024 * 1024,
|
|
||||||
"max-size-time", 5 * GST_SECOND, "max-size-buffers", 0, NULL);
|
|
||||||
|
|
||||||
group = g_new0 (GstDecodeGroup, 1);
|
group = g_new0 (GstDecodeGroup, 1);
|
||||||
group->lock = g_mutex_new ();
|
group->lock = g_mutex_new ();
|
||||||
group->dbin = dbin;
|
group->dbin = dbin;
|
||||||
@ -1398,13 +1452,18 @@ gst_decode_group_new (GstDecodeBin * dbin)
|
|||||||
group->complete = FALSE;
|
group->complete = FALSE;
|
||||||
group->endpads = NULL;
|
group->endpads = NULL;
|
||||||
|
|
||||||
group->overrunsig = g_signal_connect (G_OBJECT (mq), "overrun",
|
if (mq) {
|
||||||
G_CALLBACK (multi_queue_overrun_cb), group);
|
g_object_set (G_OBJECT (mq),
|
||||||
group->underrunsig = g_signal_connect (G_OBJECT (mq), "underrun",
|
"max-size-bytes", 2 * 1024 * 1024,
|
||||||
G_CALLBACK (multi_queue_underrun_cb), group);
|
"max-size-time", 5 * GST_SECOND, "max-size-buffers", 0, NULL);
|
||||||
|
group->overrunsig = g_signal_connect (G_OBJECT (mq), "overrun",
|
||||||
|
G_CALLBACK (multi_queue_overrun_cb), group);
|
||||||
|
group->underrunsig = g_signal_connect (G_OBJECT (mq), "underrun",
|
||||||
|
G_CALLBACK (multi_queue_underrun_cb), group);
|
||||||
|
|
||||||
gst_bin_add (GST_BIN (dbin), group->multiqueue);
|
gst_bin_add (GST_BIN (dbin), mq);
|
||||||
gst_element_set_state (group->multiqueue, GST_STATE_PAUSED);
|
gst_element_set_state (mq, GST_STATE_PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (dbin, "Returning new group %p", group);
|
GST_LOG_OBJECT (dbin, "Returning new group %p", group);
|
||||||
|
|
||||||
@ -1874,11 +1933,13 @@ gst_decode_group_free (GstDecodeGroup * group)
|
|||||||
group->endpads = NULL;
|
group->endpads = NULL;
|
||||||
|
|
||||||
/* disconnect signal handlers on multiqueue */
|
/* disconnect signal handlers on multiqueue */
|
||||||
g_signal_handler_disconnect (group->multiqueue, group->underrunsig);
|
if (group->multiqueue) {
|
||||||
g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
|
g_signal_handler_disconnect (group->multiqueue, group->underrunsig);
|
||||||
|
g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
|
||||||
|
deactivate_free_recursive (group, group->multiqueue);
|
||||||
|
}
|
||||||
|
|
||||||
/* remove all elements */
|
/* remove all elements */
|
||||||
deactivate_free_recursive (group, group->multiqueue);
|
|
||||||
|
|
||||||
GROUP_MUTEX_UNLOCK (group);
|
GROUP_MUTEX_UNLOCK (group);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user