tag: convert GstTagDemux's sometimes source pad to an always source pad

Originally decodebin couldn't deal with that in 0.10, but now simply
setting the caps when we know them should be enough. Pad activation
mode switching might need some more testing/tweaking with the new
arrangement.
This commit is contained in:
Tim-Philipp Müller 2011-11-14 09:59:36 +00:00
parent fc04bcecbe
commit 046dc1097c

View file

@ -128,7 +128,7 @@ GST_DEBUG_CATEGORY_STATIC (tagdemux_debug);
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_SOMETIMES, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("ANY") GST_STATIC_CAPS ("ANY")
); );
@ -144,9 +144,8 @@ static GstFlowReturn gst_tag_demux_read_range (GstTagDemux * tagdemux,
static GstFlowReturn gst_tag_demux_src_getrange (GstPad * srcpad, static GstFlowReturn gst_tag_demux_src_getrange (GstPad * srcpad,
guint64 offset, guint length, GstBuffer ** buffer); guint64 offset, guint length, GstBuffer ** buffer);
static gboolean gst_tag_demux_add_srcpad (GstTagDemux * tagdemux, static void gst_tag_demux_set_src_caps (GstTagDemux * tagdemux,
GstCaps * new_caps); GstCaps * new_caps);
static gboolean gst_tag_demux_remove_srcpad (GstTagDemux * tagdemux);
static gboolean gst_tag_demux_srcpad_event (GstPad * pad, GstEvent * event); static gboolean gst_tag_demux_srcpad_event (GstPad * pad, GstEvent * event);
static gboolean gst_tag_demux_sink_activate (GstPad * sinkpad); static gboolean gst_tag_demux_sink_activate (GstPad * sinkpad);
@ -255,8 +254,6 @@ gst_tag_demux_reset (GstTagDemux * tagdemux)
tagdemux->priv->collect_size = 0; tagdemux->priv->collect_size = 0;
gst_caps_replace (caps_p, NULL); gst_caps_replace (caps_p, NULL);
gst_tag_demux_remove_srcpad (tagdemux);
if (tagdemux->priv->event_tags) { if (tagdemux->priv->event_tags) {
gst_tag_list_free (tagdemux->priv->event_tags); gst_tag_list_free (tagdemux->priv->event_tags);
tagdemux->priv->event_tags = NULL; tagdemux->priv->event_tags = NULL;
@ -284,6 +281,7 @@ gst_tag_demux_init (GstTagDemux * demux, GstTagDemuxClass * gclass)
demux->priv = g_type_instance_get_private ((GTypeInstance *) demux, demux->priv = g_type_instance_get_private ((GTypeInstance *) demux,
GST_TYPE_TAG_DEMUX); GST_TYPE_TAG_DEMUX);
/* sink pad */
tmpl = gst_element_class_get_pad_template (element_klass, "sink"); tmpl = gst_element_class_get_pad_template (element_klass, "sink");
if (tmpl) { if (tmpl) {
demux->priv->sinkpad = gst_pad_new_from_template (tmpl, "sink"); demux->priv->sinkpad = gst_pad_new_from_template (tmpl, "sink");
@ -295,8 +293,25 @@ gst_tag_demux_init (GstTagDemux * demux, GstTagDemuxClass * gclass)
gst_pad_set_chain_function (demux->priv->sinkpad, gst_pad_set_chain_function (demux->priv->sinkpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_chain)); GST_DEBUG_FUNCPTR (gst_tag_demux_chain));
gst_element_add_pad (GST_ELEMENT (demux), demux->priv->sinkpad); gst_element_add_pad (GST_ELEMENT (demux), demux->priv->sinkpad);
} else {
g_warning ("GstTagDemux subclass %s must provide a sink pad template",
G_OBJECT_TYPE_NAME (demux));
} }
/* source pad */
tmpl = gst_element_class_get_pad_template (element_klass, "src");
demux->priv->srcpad = gst_pad_new_from_template (tmpl, "src");
gst_pad_set_query_function (demux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_pad_query));
gst_pad_set_event_function (demux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_srcpad_event));
gst_pad_set_activatepull_function (demux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_src_activate_pull));
gst_pad_set_getrange_function (demux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_src_getrange));
gst_pad_use_fixed_caps (demux->priv->srcpad);
gst_element_add_pad (GST_ELEMENT (demux), demux->priv->srcpad);
gst_tag_demux_reset (demux); gst_tag_demux_reset (demux);
} }
@ -310,73 +325,25 @@ gst_tag_demux_dispose (GObject * object)
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
static gboolean // FIXME: convert to set_caps / sending a caps event
gst_tag_demux_add_srcpad (GstTagDemux * tagdemux, GstCaps * new_caps) static void
gst_tag_demux_set_src_caps (GstTagDemux * tagdemux, GstCaps * new_caps)
{ {
if (tagdemux->priv->src_caps == NULL || GstCaps *old_caps = tagdemux->priv->src_caps;
!gst_caps_is_equal (new_caps, tagdemux->priv->src_caps)) {
if (old_caps == NULL || !gst_caps_is_equal (new_caps, old_caps)) {
gst_caps_replace (&tagdemux->priv->src_caps, new_caps); gst_caps_replace (&tagdemux->priv->src_caps, new_caps);
if (tagdemux->priv->srcpad != NULL) {
GST_DEBUG_OBJECT (tagdemux, "Changing src pad caps to %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (tagdemux, "Changing src pad caps to %" GST_PTR_FORMAT,
tagdemux->priv->src_caps); tagdemux->priv->src_caps);
gst_pad_set_caps (tagdemux->priv->srcpad, tagdemux->priv->src_caps); gst_pad_set_caps (tagdemux->priv->srcpad, tagdemux->priv->src_caps);
}
} else { } else {
/* Caps never changed */ /* Caps never changed */
} }
if (tagdemux->priv->srcpad == NULL) {
tagdemux->priv->srcpad =
gst_pad_new_from_template (gst_element_class_get_pad_template
(GST_ELEMENT_GET_CLASS (tagdemux), "src"), "src");
g_return_val_if_fail (tagdemux->priv->srcpad != NULL, FALSE);
gst_pad_set_query_function (tagdemux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_pad_query));
gst_pad_set_event_function (tagdemux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_srcpad_event));
gst_pad_set_activatepull_function (tagdemux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_src_activate_pull));
gst_pad_set_getrange_function (tagdemux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_src_getrange));
gst_pad_use_fixed_caps (tagdemux->priv->srcpad);
if (tagdemux->priv->src_caps)
gst_pad_set_caps (tagdemux->priv->srcpad, tagdemux->priv->src_caps);
GST_DEBUG_OBJECT (tagdemux, "Adding src pad with caps %" GST_PTR_FORMAT,
tagdemux->priv->src_caps);
gst_object_ref (tagdemux->priv->srcpad);
gst_pad_set_active (tagdemux->priv->srcpad, TRUE);
if (!gst_element_add_pad (GST_ELEMENT (tagdemux), tagdemux->priv->srcpad))
return FALSE;
gst_element_no_more_pads (GST_ELEMENT (tagdemux));
}
return TRUE;
} }
static gboolean
gst_tag_demux_remove_srcpad (GstTagDemux * demux)
{
gboolean res = TRUE;
if (demux->priv->srcpad != NULL) {
GST_DEBUG_OBJECT (demux, "Removing src pad");
res = gst_element_remove_pad (GST_ELEMENT (demux), demux->priv->srcpad);
g_return_val_if_fail (res != FALSE, FALSE);
gst_object_unref (demux->priv->srcpad);
demux->priv->srcpad = NULL;
}
return res;
};
/* will return FALSE if buffer is beyond end of data; will return TRUE /* will return FALSE if buffer is beyond end of data; will return TRUE
* if buffer was trimmed successfully or didn't need trimming, but may * if buffer was trimmed successfully or didn't need trimming, but may
* also return TRUE and set *buf_ref to NULL if the buffer was before * also return TRUE and set *buf_ref to NULL if the buffer was before
@ -652,11 +619,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
GST_DEBUG_OBJECT (demux, "Found type %" GST_PTR_FORMAT " with a " GST_DEBUG_OBJECT (demux, "Found type %" GST_PTR_FORMAT " with a "
"probability of %u", caps, probability); "probability of %u", caps, probability);
if (!gst_tag_demux_add_srcpad (demux, caps)) { gst_tag_demux_set_src_caps (demux, caps);
GST_DEBUG_OBJECT (demux, "Failed to add srcpad");
gst_caps_unref (caps);
goto error;
}
gst_caps_unref (caps); gst_caps_unref (caps);
/* Move onto streaming and fall-through to push out existing /* Move onto streaming and fall-through to push out existing
@ -707,11 +670,6 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
} }
} }
return GST_FLOW_OK; return GST_FLOW_OK;
error:
GST_DEBUG_OBJECT (demux, "error in chain function");
return GST_FLOW_ERROR;
} }
static gboolean static gboolean
@ -1239,11 +1197,8 @@ gst_tag_demux_sink_activate (GstPad * sinkpad)
* the chain function if we end up in push mode */ * the chain function if we end up in push mode */
demux->priv->state = GST_TAG_DEMUX_STREAMING; demux->priv->state = GST_TAG_DEMUX_STREAMING;
/* 6 Add the srcpad for output now we know caps. */ /* 6 Set the srcpad caps now we know them */
if (!gst_tag_demux_add_srcpad (demux, caps)) { gst_tag_demux_set_src_caps (demux, caps);
GST_DEBUG_OBJECT (demux, "Could not add source pad");
goto done_activate;
}
/* 7 - if the sinkpad is active, it was done by downstream so we're /* 7 - if the sinkpad is active, it was done by downstream so we're
* done, otherwise switch to push */ * done, otherwise switch to push */