#include "gsttagdemux.h"
#include <gst/base/gsttypefindhelper.h>
+#include <gst/base/gstadapter.h>
#include <gst/gst-i18n-plugin.h>
#include <string.h>
gint64 upstream_size;
GstTagDemuxState state;
+ GstAdapter *adapter;
GstBuffer *collect;
gsize collect_size;
+ guint tagsize;
GstCaps *src_caps;
GstTagList *event_tags;
gst_buffer_replace (buffer_p, NULL);
tagdemux->priv->collect_size = 0;
+ tagdemux->priv->tagsize = 0;
+ gst_adapter_clear (tagdemux->priv->adapter);
gst_caps_replace (caps_p, NULL);
if (tagdemux->priv->event_tags) {
gst_pad_use_fixed_caps (demux->priv->srcpad);
gst_element_add_pad (GST_ELEMENT (demux), demux->priv->srcpad);
+ demux->priv->adapter = gst_adapter_new ();
gst_tag_demux_reset (demux);
}
GstTagDemux *tagdemux = GST_TAG_DEMUX (object);
gst_tag_demux_reset (tagdemux);
+ if (tagdemux->priv->adapter) {
+ g_object_unref (tagdemux->priv->adapter);
+ tagdemux->priv->adapter = NULL;
+ }
G_OBJECT_CLASS (parent_class)->dispose (object);
}
}
static void
-gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect)
+update_collected (GstTagDemux * demux)
{
+ guint avail;
+ GstBuffer *buf;
+
+ avail = gst_adapter_available (demux->priv->adapter);
+ if (avail == 0)
+ return;
+
+ buf = gst_adapter_take_buffer (demux->priv->adapter, avail);
+
+ if (demux->priv->collect == NULL) {
+ demux->priv->collect = buf;
+ } else {
+ demux->priv->collect = gst_buffer_append (demux->priv->collect, buf);
+ }
+ demux->priv->collect_size += avail;
+}
+
+static void
+gst_tag_demux_chain_parse_tag (GstTagDemux * demux)
+{
+ GstBuffer *collect;
GstTagDemuxResult parse_ret;
GstTagDemuxClass *klass;
guint tagsize = 0;
guint available;
- g_assert (gst_buffer_is_writable (collect));
+ available =
+ demux->priv->collect_size + gst_adapter_available (demux->priv->adapter);
klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
+ if (available < klass->min_start_size) {
+ GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
+ "to identify tag", available, klass->min_start_size);
+ return; /* wait for more data */
+ }
+
+ if (available < demux->priv->tagsize) {
+ GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
+ "to parse tag", available, demux->priv->tagsize);
+ return; /* wait for more data */
+ }
+
+ update_collected (demux);
+ demux->priv->collect = gst_buffer_make_writable (demux->priv->collect);
+ collect = demux->priv->collect;
+
+ g_assert (gst_buffer_is_writable (collect));
+
+
/* If we receive a buffer that's from the middle of the file,
* we can't read tags so move to typefinding */
if (GST_BUFFER_OFFSET_IS_VALID (collect) && GST_BUFFER_OFFSET (collect) != 0) {
g_assert (klass->identify_tag != NULL);
g_assert (klass->parse_tag != NULL);
- available = gst_buffer_get_size (collect);
-
- if (available < klass->min_start_size) {
- GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
- "to identify tag", available, klass->min_start_size);
- return; /* wait for more data */
- }
-
if (!klass->identify_tag (demux, collect, TRUE, &tagsize)) {
GST_DEBUG_OBJECT (demux, "Could not identify start tag");
demux->priv->state = GST_TAG_DEMUX_TYPEFINDING;
return;
}
+ demux->priv->tagsize = tagsize;
+
/* need to set offset of first buffer to 0 or trimming won't work */
if (!GST_BUFFER_OFFSET_IS_VALID (collect)) {
GST_WARNING_OBJECT (demux, "Fixing up first buffer without offset");
demux->priv->segment.position += GST_BUFFER_DURATION (buf);
}
- if (demux->priv->collect == NULL) {
- demux->priv->collect = buf;
- } else {
- demux->priv->collect = gst_buffer_append (demux->priv->collect, buf);
- }
- demux->priv->collect_size += size;
+ gst_adapter_push (demux->priv->adapter, buf);
buf = NULL;
switch (demux->priv->state) {
case GST_TAG_DEMUX_READ_START_TAG:
- demux->priv->collect = gst_buffer_make_writable (demux->priv->collect);
- gst_tag_demux_chain_parse_tag (demux, demux->priv->collect);
+ gst_tag_demux_chain_parse_tag (demux);
if (demux->priv->state != GST_TAG_DEMUX_TYPEFINDING)
break;
/* Fall-through */
gsize typefind_size;
GstCaps *caps;
+ update_collected (demux);
+
if (demux->priv->collect_size <
TYPE_FIND_MIN_SIZE + demux->priv->strip_start)
break; /* Go get more data first */
GstBuffer *outbuf = NULL;
gsize outbuf_size;
+ update_collected (demux);
+
/* Trim the buffer and adjust offset */
if (demux->priv->collect) {
outbuf = demux->priv->collect;