tagdemux: ensure tags have been fetched before pulling data

Otherwise upstream can get confused about offsets as there will
be a jump once the tags have been parsed due to the stripped area.

If upstream pulls from 0 to 100, and then tagdemux does the
tag reading and finds out that the first 200 bytes are the tag, the
next pull from upstream will have an offset of 200 bytes. So
upstream will get the following data:

0 - 100, 300 - (EOS), as it will continue requesting from where
it has last stopped, but tagdemux will add an offset to skip the
tags.

This patch makes sure that the tags have been parsed and skipped
since the first pull range call.

https://bugzilla.gnome.org/show_bug.cgi?id=744580
This commit is contained in:
Thiago Santos 2015-02-18 20:58:15 -03:00
parent 2813e08210
commit cd07101420

View file

@ -1614,6 +1614,20 @@ gst_tag_demux_src_activate_mode (GstPad * pad, GstObject * parent,
return res;
}
static inline GstFlowReturn
gst_tag_demux_ensure_tags (GstTagDemux * demux)
{
GstFlowReturn flow = GST_FLOW_OK;
if (G_UNLIKELY (demux->priv->state == GST_TAG_DEMUX_READ_START_TAG &&
GST_PAD_MODE (demux->priv->srcpad) == GST_PAD_MODE_PULL)) {
flow = gst_tag_demux_element_find (demux);
GST_INFO_OBJECT (demux, "pulled tags: %s", gst_flow_get_name (flow));
}
return flow;
}
static GstFlowReturn
gst_tag_demux_read_range (GstTagDemux * demux, GstObject * parent,
guint64 offset, guint length, GstBuffer ** buffer)
@ -1625,6 +1639,12 @@ gst_tag_demux_read_range (GstTagDemux * demux, GstObject * parent,
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
/* Ensure we already have computed our tags to properly use the offsets
* below */
ret = gst_tag_demux_ensure_tags (demux);
if (ret != GST_FLOW_OK)
return ret;
/* Adjust offset and length of the request to trim off tag information.
* For the returned buffer, adjust the output offset to match what downstream
* should see */
@ -1741,13 +1761,7 @@ gst_tag_demux_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
* filesrc ! id3demux ! xyzparse ! .., read tags here, since we don't
* have a streaming thread of our own to do that. We do it here and
* not in get_range(), so we can return the right size in bytes.. */
if (demux->priv->state == GST_TAG_DEMUX_READ_START_TAG &&
GST_PAD_MODE (demux->priv->srcpad) == GST_PAD_MODE_PULL) {
GstFlowReturn flow G_GNUC_UNUSED;
flow = gst_tag_demux_element_find (demux);
GST_INFO_OBJECT (demux, "pulled tags: %s", gst_flow_get_name (flow));
}
gst_tag_demux_ensure_tags (demux);
result -= demux->priv->strip_start + demux->priv->strip_end;
if (result < 0)
result = 0;