Merge branch 'upstream/1.16' into tizen_gst_1.16.2
[platform/upstream/gst-plugins-base.git] / gst-libs / gst / tag / gsttagdemux.c
1 /* GStreamer Base Class for Tag Demuxing
2  * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3  * Copyright (C) 2006-2007 Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * SECTION:gsttagdemux
23  * @title: GstTagDemux
24  * @see_also: GstApeDemux, GstID3Demux
25  * @short_description: Base class for demuxing tags that are in chunks
26  *                     directly at the beginning or at the end of a file
27  *
28  * Provides a base class for demuxing tags at the beginning or end of a
29  * stream and handles things like typefinding, querying, seeking, and
30  * different modes of operation (chain-based, pull_range-based, and providing
31  * downstream elements with random access if upstream supports that). The tag
32  * is stripped from the output, and all offsets are adjusted for the tag
33  * sizes, so that to the downstream element the stream will appear as if
34  * there was no tag at all. Also, once the tag has been parsed, GstTagDemux
35  * will try to determine the media type of the resulting stream and add a
36  * source pad with the appropriate caps in order to facilitate auto-plugging.
37  *
38  * ## Deriving from GstTagDemux
39  *
40  * Subclasses have to do four things:
41  *
42  *  * In their base init function, they must add a pad template for the sink
43  *    pad to the element class, describing the media type they can parse in
44  *    the caps of the pad template.
45  *  * In their class init function, they must override
46  *    GST_TAG_DEMUX_CLASS(demux_klass)->identify_tag with their own identify
47  *    function.
48  *  * In their class init function, they must override
49  *  GST_TAG_DEMUX_CLASS(demux_klass)->parse_tag with their own parse
50  *  function.
51  *  * In their class init function, they must also set
52  *    GST_TAG_DEMUX_CLASS(demux_klass)->min_start_size and/or
53  *  GST_TAG_DEMUX_CLASS(demux_klass)->min_end_size to the minimum size required
54  *  for the identify function to decide whether the stream has a supported tag
55  *  or not. A class parsing ID3v1 tags, for example, would set min_end_size to
56  *  128 bytes.
57  */
58
59 #ifdef HAVE_CONFIG_H
60 #include "config.h"
61 #endif
62
63 #include "gsttagdemux.h"
64
65 #include <gst/base/gsttypefindhelper.h>
66 #include <gst/base/gstadapter.h>
67 #include <gst/gst-i18n-plugin.h>
68 #include <string.h>
69
70 typedef enum
71 {
72   GST_TAG_DEMUX_READ_START_TAG,
73   GST_TAG_DEMUX_TYPEFINDING,
74   GST_TAG_DEMUX_STREAMING
75 } GstTagDemuxState;
76
77 struct _GstTagDemuxPrivate
78 {
79   GstPad *srcpad;
80   GstPad *sinkpad;
81
82   /* Number of bytes to remove from the
83    * start of file (tag at beginning) */
84   guint strip_start;
85
86   /* Number of bytes to remove from the
87    * end of file (tag at end) */
88   guint strip_end;
89
90   gint64 upstream_size;
91
92   GstTagDemuxState state;
93   GstAdapter *adapter;
94   GstBuffer *collect;
95   gsize collect_size;
96   guint tagsize;
97   GstCaps *src_caps;
98
99   GstTagList *event_tags;
100   GstTagList *parsed_tags;
101   gboolean send_tag_event;
102
103   GstSegment segment;
104   gboolean need_newseg;
105
106   guint64 offset;
107
108   GList *pending_events;
109 };
110
111 /* Require at least 8kB of data before we attempt typefind.
112  * Seems a decent value based on test files
113  * 40kB is massive overkill for the maximum, I think, but it
114  * doesn't do any harm (tpm: increased to 64kB after watching
115  * typefinding fail on a wavpack file that needed 42kB to succeed) */
116 #ifdef TIZEN_PROFILE_TV
117 #define TYPE_FIND_MIN_SIZE 2048
118 #else
119 #define TYPE_FIND_MIN_SIZE 8192
120 #endif
121
122 #define TYPE_FIND_MAX_SIZE 65536
123
124 #define DEFAULT_PULL_BLOCKSIZE 4096
125
126 GST_DEBUG_CATEGORY_STATIC (tagdemux_debug);
127 #define GST_CAT_DEFAULT (tagdemux_debug)
128
129 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
130     GST_PAD_SRC,
131     GST_PAD_ALWAYS,
132     GST_STATIC_CAPS ("ANY")
133     );
134
135 static void gst_tag_demux_element_loop (GstTagDemux * demux);
136
137 static void gst_tag_demux_dispose (GObject * object);
138
139 static GstFlowReturn gst_tag_demux_chain (GstPad * pad, GstObject * parent,
140     GstBuffer * buf);
141 static gboolean gst_tag_demux_sink_event (GstPad * pad, GstObject * parent,
142     GstEvent * event);
143
144 static gboolean gst_tag_demux_sink_activate_mode (GstPad * pad,
145     GstObject * parent, GstPadMode mode, gboolean active);
146 static gboolean gst_tag_demux_src_activate_mode (GstPad * pad,
147     GstObject * parent, GstPadMode mode, gboolean active);
148 static GstFlowReturn gst_tag_demux_read_range (GstTagDemux * tagdemux,
149     GstObject * parent, guint64 offset, guint length, GstBuffer ** buffer);
150
151 static GstFlowReturn gst_tag_demux_src_getrange (GstPad * srcpad,
152     GstObject * parent, guint64 offset, guint length, GstBuffer ** buffer);
153
154 static void gst_tag_demux_set_src_caps (GstTagDemux * tagdemux,
155     GstCaps * new_caps);
156
157 static gboolean gst_tag_demux_srcpad_event (GstPad * pad, GstObject * parent,
158     GstEvent * event);
159 static gboolean gst_tag_demux_sink_activate (GstPad * sinkpad,
160     GstObject * parent);
161 static GstStateChangeReturn gst_tag_demux_change_state (GstElement * element,
162     GstStateChange transition);
163 static gboolean gst_tag_demux_pad_query (GstPad * pad, GstObject * parent,
164     GstQuery * query);
165 static gboolean gst_tag_demux_get_upstream_size (GstTagDemux * tagdemux);
166 static void gst_tag_demux_send_pending_events (GstTagDemux * tagdemux);
167 static void gst_tag_demux_send_tag_event (GstTagDemux * tagdemux);
168 static gboolean gst_tag_demux_send_new_segment (GstTagDemux * tagdemux);
169
170 static void gst_tag_demux_base_init (gpointer g_class);
171 static void gst_tag_demux_class_init (gpointer g_class, gpointer d);
172 static void gst_tag_demux_init (GstTagDemux * obj, GstTagDemuxClass * klass);
173
174 static gpointer parent_class;   /* NULL */
175 static gint private_offset = 0;
176
177 /* Cannot use boilerplate macros here because we want the abstract flag */
178 GType
179 gst_tag_demux_get_type (void)
180 {
181   static GType object_type;     /* 0 */
182
183   if (object_type == 0) {
184     static const GTypeInfo object_info = {
185       sizeof (GstTagDemuxClass),
186       gst_tag_demux_base_init,
187       NULL,                     /* base_finalize */
188       gst_tag_demux_class_init,
189       NULL,                     /* class_finalize */
190       NULL,                     /* class_data */
191       sizeof (GstTagDemux),
192       0,                        /* n_preallocs */
193       (GInstanceInitFunc) gst_tag_demux_init
194     };
195
196     object_type = g_type_register_static (GST_TYPE_ELEMENT,
197         "GstTagDemux", &object_info, G_TYPE_FLAG_ABSTRACT);
198
199     private_offset =
200         g_type_add_instance_private (object_type, sizeof (GstTagDemuxPrivate));
201   }
202
203   return object_type;
204 }
205
206 static inline GstTagDemuxPrivate *
207 gst_tag_demux_get_instance_private (GstTagDemux * self)
208 {
209   return (G_STRUCT_MEMBER_P (self, private_offset));
210 }
211
212 static void
213 gst_tag_demux_base_init (gpointer klass)
214 {
215   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
216
217   gst_element_class_add_static_pad_template (element_class, &src_factory);
218
219   GST_DEBUG_CATEGORY_INIT (tagdemux_debug, "tagdemux", 0,
220       "tag demux base class");
221 }
222
223 static void
224 gst_tag_demux_class_init (gpointer klass, gpointer d)
225 {
226   GstTagDemuxClass *tagdemux_class = GST_TAG_DEMUX_CLASS (klass);
227   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
228   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
229
230   parent_class = g_type_class_peek_parent (klass);
231
232   gobject_class->dispose = gst_tag_demux_dispose;
233
234   element_class->change_state = GST_DEBUG_FUNCPTR (gst_tag_demux_change_state);
235
236   if (private_offset != 0)
237     g_type_class_adjust_private_offset (klass, &private_offset);
238
239   /* subclasses must set at least one of these */
240   tagdemux_class->min_start_size = 0;
241   tagdemux_class->min_end_size = 0;
242 }
243
244 static void
245 gst_tag_demux_reset (GstTagDemux * tagdemux)
246 {
247   GstBuffer **buffer_p = &tagdemux->priv->collect;
248   GstCaps **caps_p = &tagdemux->priv->src_caps;
249
250   tagdemux->priv->strip_start = 0;
251   tagdemux->priv->strip_end = 0;
252   tagdemux->priv->upstream_size = -1;
253   tagdemux->priv->state = GST_TAG_DEMUX_READ_START_TAG;
254   tagdemux->priv->send_tag_event = FALSE;
255
256   gst_buffer_replace (buffer_p, NULL);
257   tagdemux->priv->collect_size = 0;
258   tagdemux->priv->tagsize = 0;
259   gst_adapter_clear (tagdemux->priv->adapter);
260   gst_caps_replace (caps_p, NULL);
261
262   if (tagdemux->priv->event_tags) {
263     gst_tag_list_unref (tagdemux->priv->event_tags);
264     tagdemux->priv->event_tags = NULL;
265   }
266   if (tagdemux->priv->parsed_tags) {
267     gst_tag_list_unref (tagdemux->priv->parsed_tags);
268     tagdemux->priv->parsed_tags = NULL;
269   }
270
271   gst_segment_init (&tagdemux->priv->segment, GST_FORMAT_UNDEFINED);
272   tagdemux->priv->need_newseg = TRUE;
273
274   g_list_foreach (tagdemux->priv->pending_events,
275       (GFunc) gst_mini_object_unref, NULL);
276   g_list_free (tagdemux->priv->pending_events);
277   tagdemux->priv->pending_events = NULL;
278 }
279
280 static void
281 gst_tag_demux_init (GstTagDemux * demux, GstTagDemuxClass * gclass)
282 {
283   GstElementClass *element_klass = GST_ELEMENT_CLASS (gclass);
284   GstPadTemplate *tmpl;
285
286   demux->priv = gst_tag_demux_get_instance_private (demux);
287
288   /* sink pad */
289   tmpl = gst_element_class_get_pad_template (element_klass, "sink");
290   if (tmpl) {
291     demux->priv->sinkpad = gst_pad_new_from_template (tmpl, "sink");
292
293     gst_pad_set_activatemode_function (demux->priv->sinkpad,
294         GST_DEBUG_FUNCPTR (gst_tag_demux_sink_activate_mode));
295     gst_pad_set_activate_function (demux->priv->sinkpad,
296         GST_DEBUG_FUNCPTR (gst_tag_demux_sink_activate));
297     gst_pad_set_event_function (demux->priv->sinkpad,
298         GST_DEBUG_FUNCPTR (gst_tag_demux_sink_event));
299     gst_pad_set_chain_function (demux->priv->sinkpad,
300         GST_DEBUG_FUNCPTR (gst_tag_demux_chain));
301     gst_element_add_pad (GST_ELEMENT (demux), demux->priv->sinkpad);
302   } else {
303     g_warning ("GstTagDemux subclass %s must provide a sink pad template",
304         G_OBJECT_TYPE_NAME (demux));
305   }
306
307   /* source pad */
308   tmpl = gst_element_class_get_pad_template (element_klass, "src");
309   demux->priv->srcpad = gst_pad_new_from_template (tmpl, "src");
310   gst_pad_set_query_function (demux->priv->srcpad,
311       GST_DEBUG_FUNCPTR (gst_tag_demux_pad_query));
312   gst_pad_set_event_function (demux->priv->srcpad,
313       GST_DEBUG_FUNCPTR (gst_tag_demux_srcpad_event));
314   gst_pad_set_activatemode_function (demux->priv->srcpad,
315       GST_DEBUG_FUNCPTR (gst_tag_demux_src_activate_mode));
316   gst_pad_set_getrange_function (demux->priv->srcpad,
317       GST_DEBUG_FUNCPTR (gst_tag_demux_src_getrange));
318   gst_pad_use_fixed_caps (demux->priv->srcpad);
319   gst_element_add_pad (GST_ELEMENT (demux), demux->priv->srcpad);
320
321   demux->priv->adapter = gst_adapter_new ();
322   gst_tag_demux_reset (demux);
323 }
324
325 static void
326 gst_tag_demux_dispose (GObject * object)
327 {
328   GstTagDemux *tagdemux = GST_TAG_DEMUX (object);
329
330   gst_tag_demux_reset (tagdemux);
331   if (tagdemux->priv->adapter) {
332     g_object_unref (tagdemux->priv->adapter);
333     tagdemux->priv->adapter = NULL;
334   }
335
336   G_OBJECT_CLASS (parent_class)->dispose (object);
337 }
338
339 // FIXME: convert to set_caps / sending a caps event
340 static void
341 gst_tag_demux_set_src_caps (GstTagDemux * tagdemux, GstCaps * new_caps)
342 {
343   GstCaps *old_caps = tagdemux->priv->src_caps;
344
345   if (old_caps == NULL || !gst_caps_is_equal (new_caps, old_caps)) {
346     GstEvent *event;
347
348     gst_caps_replace (&tagdemux->priv->src_caps, new_caps);
349
350     GST_DEBUG_OBJECT (tagdemux, "Changing src pad caps to %" GST_PTR_FORMAT,
351         tagdemux->priv->src_caps);
352
353     event =
354         gst_pad_get_sticky_event (tagdemux->priv->sinkpad,
355         GST_EVENT_STREAM_START, 0);
356     if (!event) {
357       gchar *stream_id = gst_pad_create_stream_id (tagdemux->priv->srcpad,
358           GST_ELEMENT_CAST (tagdemux), NULL);
359       GST_DEBUG_OBJECT (tagdemux, "Creating new STREAM_START event");
360       event = gst_event_new_stream_start (stream_id);
361       g_free (stream_id);
362       gst_event_set_group_id (event, gst_util_group_id_next ());
363     }
364     gst_pad_push_event (tagdemux->priv->srcpad, event);
365
366     gst_pad_set_caps (tagdemux->priv->srcpad, tagdemux->priv->src_caps);
367   } else {
368     /* Caps never changed */
369   }
370 }
371
372 /* will return FALSE if buffer is beyond end of data; will return TRUE
373  * if buffer was trimmed successfully or didn't need trimming, but may
374  * also return TRUE and set *buf_ref to NULL if the buffer was before
375  * the start of the data */
376 static gboolean
377 gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref,
378     gsize * buf_size)
379 {
380   GstBuffer *buf = *buf_ref;
381
382   guint trim_start = 0;
383   guint out_size, bsize;
384   guint64 out_offset, boffset;
385   gboolean need_sub = FALSE;
386
387   bsize = out_size = gst_buffer_get_size (buf);
388   boffset = out_offset = GST_BUFFER_OFFSET (buf);
389
390   /* Adjust offset and length */
391   if (!GST_BUFFER_OFFSET_IS_VALID (buf)) {
392     /* Can't change anything without an offset */
393     *buf_size = bsize;
394     return TRUE;
395   }
396
397   /* If the buffer crosses the tag at the end of file, trim it */
398   if (tagdemux->priv->strip_end > 0) {
399     if (gst_tag_demux_get_upstream_size (tagdemux)) {
400       guint64 v1tag_offset =
401           tagdemux->priv->upstream_size - tagdemux->priv->strip_end;
402
403       if (out_offset >= v1tag_offset) {
404         GST_DEBUG_OBJECT (tagdemux, "Buffer is past the end of the data");
405         goto no_out_buffer_end;
406       }
407
408       if (out_offset + out_size > v1tag_offset) {
409         out_size = v1tag_offset - out_offset;
410         need_sub = TRUE;
411       }
412     }
413   }
414
415   if (tagdemux->priv->strip_start > 0) {
416     /* If the buffer crosses the tag at the start of file, trim it */
417     if (out_offset <= tagdemux->priv->strip_start) {
418       if (out_offset + out_size <= tagdemux->priv->strip_start) {
419         GST_DEBUG_OBJECT (tagdemux, "Buffer is before the start of the data");
420         goto no_out_buffer_start;
421       }
422
423       trim_start = tagdemux->priv->strip_start - out_offset;
424       out_size -= trim_start;
425       out_offset = 0;
426     } else {
427       out_offset -= tagdemux->priv->strip_start;
428     }
429     need_sub = TRUE;
430   }
431
432   if (need_sub) {
433     if (out_size != bsize || !gst_buffer_is_writable (buf)) {
434       GstBuffer *sub;
435
436       GST_DEBUG_OBJECT (tagdemux, "Sub-buffering to trim size %d offset %"
437           G_GINT64_FORMAT " to %d offset %" G_GINT64_FORMAT,
438           bsize, boffset, out_size, out_offset);
439
440       sub =
441           gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, trim_start,
442           out_size);
443       g_return_val_if_fail (sub != NULL, FALSE);
444       if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
445         GST_BUFFER_TIMESTAMP (sub) = GST_BUFFER_TIMESTAMP (buf);
446       if (GST_BUFFER_DURATION_IS_VALID (buf))
447         GST_BUFFER_DURATION (sub) = GST_BUFFER_DURATION (buf);
448       gst_buffer_unref (buf);
449       *buf_ref = buf = sub;
450       *buf_size = out_size;
451     } else {
452       GST_DEBUG_OBJECT (tagdemux, "Adjusting buffer from size %d offset %"
453           G_GINT64_FORMAT " to %d offset %" G_GINT64_FORMAT,
454           bsize, boffset, out_size, out_offset);
455     }
456
457     GST_BUFFER_OFFSET (buf) = out_offset;
458     GST_BUFFER_OFFSET_END (buf) = out_offset + out_size;
459   }
460
461   return TRUE;
462
463 no_out_buffer_end:
464   {
465     gst_buffer_unref (buf);
466     *buf_ref = NULL;
467     return FALSE;
468   }
469 no_out_buffer_start:
470   {
471     gst_buffer_unref (buf);
472     *buf_ref = NULL;
473     return TRUE;
474   }
475 }
476
477 static void
478 update_collected (GstTagDemux * demux)
479 {
480   guint avail;
481   GstBuffer *buf;
482
483   avail = gst_adapter_available (demux->priv->adapter);
484   if (avail == 0)
485     return;
486
487   buf = gst_adapter_take_buffer (demux->priv->adapter, avail);
488
489   if (demux->priv->collect == NULL) {
490     demux->priv->collect = buf;
491   } else {
492     demux->priv->collect = gst_buffer_append (demux->priv->collect, buf);
493   }
494   demux->priv->collect_size += avail;
495 }
496
497 static void
498 gst_tag_demux_chain_parse_tag (GstTagDemux * demux)
499 {
500   GstBuffer *collect;
501   GstTagDemuxResult parse_ret;
502   GstTagDemuxClass *klass;
503   guint tagsize = 0;
504   guint available;
505
506   available =
507       demux->priv->collect_size + gst_adapter_available (demux->priv->adapter);
508
509   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
510
511   if (available < klass->min_start_size) {
512     GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
513         "to identify tag", available, klass->min_start_size);
514     return;                     /* wait for more data */
515   }
516
517   if (available < demux->priv->tagsize) {
518     GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
519         "to parse tag", available, demux->priv->tagsize);
520     return;                     /* wait for more data */
521   }
522
523   update_collected (demux);
524   demux->priv->collect = gst_buffer_make_writable (demux->priv->collect);
525   collect = demux->priv->collect;
526
527   g_assert (gst_buffer_is_writable (collect));
528
529
530   /* If we receive a buffer that's from the middle of the file,
531    * we can't read tags so move to typefinding */
532   if (GST_BUFFER_OFFSET_IS_VALID (collect) && GST_BUFFER_OFFSET (collect) != 0) {
533     GST_DEBUG_OBJECT (demux, "Received buffer from non-zero offset %"
534         G_GINT64_FORMAT ". Can't read tags", GST_BUFFER_OFFSET (collect));
535     demux->priv->state = GST_TAG_DEMUX_TYPEFINDING;
536     return;
537   }
538
539   g_assert (klass->identify_tag != NULL);
540   g_assert (klass->parse_tag != NULL);
541
542   if (!klass->identify_tag (demux, collect, TRUE, &tagsize)) {
543     GST_DEBUG_OBJECT (demux, "Could not identify start tag");
544     demux->priv->state = GST_TAG_DEMUX_TYPEFINDING;
545     return;
546   }
547
548   demux->priv->tagsize = tagsize;
549
550   /* need to set offset of first buffer to 0 or trimming won't work */
551   if (!GST_BUFFER_OFFSET_IS_VALID (collect)) {
552     GST_WARNING_OBJECT (demux, "Fixing up first buffer without offset");
553     GST_BUFFER_OFFSET (collect) = 0;
554   }
555
556   GST_DEBUG_OBJECT (demux, "Identified tag, size = %u bytes", tagsize);
557
558   do {
559     GstTagList *tags = NULL;
560     guint newsize, saved_size;
561
562     demux->priv->strip_start = tagsize;
563
564     if (available < tagsize) {
565       GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
566           "to parse tag", available, tagsize);
567       return;                   /* wait for more data */
568     }
569
570     saved_size = gst_buffer_get_size (collect);
571     gst_buffer_set_size (collect, tagsize);
572     newsize = tagsize;
573
574     parse_ret = klass->parse_tag (demux, collect, TRUE, &newsize, &tags);
575
576     gst_buffer_set_size (collect, saved_size);
577
578     switch (parse_ret) {
579       case GST_TAG_DEMUX_RESULT_OK:
580         demux->priv->strip_start = newsize;
581         demux->priv->parsed_tags = tags;
582         GST_DEBUG_OBJECT (demux, "Read start tag of size %u", newsize);
583         break;
584       case GST_TAG_DEMUX_RESULT_BROKEN_TAG:
585         demux->priv->strip_start = newsize;
586         demux->priv->parsed_tags = tags;
587         GST_WARNING_OBJECT (demux, "Ignoring broken start tag of size %d",
588             demux->priv->strip_start);
589         break;
590       case GST_TAG_DEMUX_RESULT_AGAIN:
591         GST_DEBUG_OBJECT (demux, "Re-parse, this time with %u bytes", newsize);
592         g_assert (newsize != tagsize);
593         tagsize = newsize;
594         break;
595     }
596   } while (parse_ret == GST_TAG_DEMUX_RESULT_AGAIN);
597
598   GST_LOG_OBJECT (demux, "Parsed tag. Proceeding to typefinding");
599   demux->priv->state = GST_TAG_DEMUX_TYPEFINDING;
600   demux->priv->send_tag_event = TRUE;
601 }
602
603 static GstFlowReturn
604 gst_tag_demux_chain_buffer (GstTagDemux * demux, GstBuffer * buf,
605     gboolean at_eos)
606 {
607   gsize size;
608
609   size = gst_buffer_get_size (buf);
610
611   /* Update our segment position info */
612   if (demux->priv->segment.format == GST_FORMAT_BYTES) {
613     if (GST_BUFFER_OFFSET_IS_VALID (buf))
614       demux->priv->segment.position = GST_BUFFER_OFFSET (buf);
615     demux->priv->segment.position += size;
616   } else if (demux->priv->segment.format == GST_FORMAT_TIME) {
617     if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
618       demux->priv->segment.position = GST_BUFFER_TIMESTAMP (buf);
619     if (GST_BUFFER_DURATION_IS_VALID (buf))
620       demux->priv->segment.position += GST_BUFFER_DURATION (buf);
621   }
622
623   gst_adapter_push (demux->priv->adapter, buf);
624   buf = NULL;
625
626   switch (demux->priv->state) {
627     case GST_TAG_DEMUX_READ_START_TAG:
628       gst_tag_demux_chain_parse_tag (demux);
629       if (demux->priv->state != GST_TAG_DEMUX_TYPEFINDING)
630         break;
631       /* Fall-through */
632     case GST_TAG_DEMUX_TYPEFINDING:{
633       GstTypeFindProbability probability = 0;
634       GstBuffer *typefind_buf = NULL;
635       gsize typefind_size;
636       GstCaps *caps;
637
638       update_collected (demux);
639
640       if (!at_eos && demux->priv->collect_size <
641           TYPE_FIND_MIN_SIZE + demux->priv->strip_start)
642         break;                  /* Go get more data first */
643
644       GST_DEBUG_OBJECT (demux, "Typefinding with size %" G_GSIZE_FORMAT,
645           demux->priv->collect_size);
646
647       /* Trim the buffer and adjust offset for typefinding */
648       typefind_buf = demux->priv->collect;
649       gst_buffer_ref (typefind_buf);
650       if (!gst_tag_demux_trim_buffer (demux, &typefind_buf, &typefind_size))
651         return GST_FLOW_EOS;
652
653       if (typefind_buf == NULL)
654         break;                  /* Still need more data */
655
656       caps = gst_type_find_helper_for_buffer (GST_OBJECT (demux),
657           typefind_buf, &probability);
658
659       if (caps == NULL) {
660         if (typefind_size < TYPE_FIND_MAX_SIZE) {
661           /* Just break for more data */
662           gst_buffer_unref (typefind_buf);
663           return GST_FLOW_OK;
664         }
665
666         /* We failed typefind */
667         GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
668             ("Could not detect type for contents within tag"));
669         gst_buffer_unref (typefind_buf);
670         gst_buffer_unref (demux->priv->collect);
671         demux->priv->collect = NULL;
672         demux->priv->collect_size = 0;
673         return GST_FLOW_ERROR;
674       }
675       gst_buffer_unref (typefind_buf);
676
677       GST_DEBUG_OBJECT (demux, "Found type %" GST_PTR_FORMAT " with a "
678           "probability of %u", caps, probability);
679
680       gst_tag_demux_set_src_caps (demux, caps);
681       gst_caps_unref (caps);
682
683       /* Move onto streaming and fall-through to push out existing
684        * data */
685       demux->priv->state = GST_TAG_DEMUX_STREAMING;
686       /* fall-through */
687     }
688     case GST_TAG_DEMUX_STREAMING:{
689       GstBuffer *outbuf = NULL;
690       gsize outbuf_size;
691
692       update_collected (demux);
693
694       /* Trim the buffer and adjust offset */
695       if (demux->priv->collect) {
696         outbuf = demux->priv->collect;
697         demux->priv->collect = NULL;
698         demux->priv->collect_size = 0;
699         if (!gst_tag_demux_trim_buffer (demux, &outbuf, &outbuf_size))
700           return GST_FLOW_EOS;
701       }
702       if (outbuf) {
703         /* Might need a new segment before the buffer */
704         if (demux->priv->need_newseg) {
705           if (!gst_tag_demux_send_new_segment (demux)) {
706             GST_WARNING_OBJECT (demux, "Downstream did not handle newsegment "
707                 "event as it should");
708           }
709           demux->priv->need_newseg = FALSE;
710         }
711
712         /* send any pending events we cached */
713         gst_tag_demux_send_pending_events (demux);
714
715         /* Send our own pending tag event */
716         if (demux->priv->send_tag_event) {
717           gst_tag_demux_send_tag_event (demux);
718           demux->priv->send_tag_event = FALSE;
719         }
720
721         GST_LOG_OBJECT (demux, "Pushing buffer %" GST_PTR_FORMAT, outbuf);
722
723         return gst_pad_push (demux->priv->srcpad, outbuf);
724       }
725     }
726   }
727   return GST_FLOW_OK;
728 }
729
730 static GstFlowReturn
731 gst_tag_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
732 {
733   return gst_tag_demux_chain_buffer (GST_TAG_DEMUX (parent), buf, FALSE);
734 }
735
736 static gboolean
737 gst_tag_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
738 {
739   GstTagDemux *demux;
740   gboolean ret;
741
742   demux = GST_TAG_DEMUX (parent);
743
744   switch (GST_EVENT_TYPE (event)) {
745     case GST_EVENT_EOS:
746       if (!gst_pad_has_current_caps (demux->priv->srcpad)) {
747         GST_INFO_OBJECT (demux, "EOS before we found a type");
748
749         /* push final buffer with eos indication to force typefinding */
750         gst_tag_demux_chain_buffer (demux, gst_buffer_new (), TRUE);
751
752         if (!gst_pad_has_current_caps (demux->priv->srcpad)) {
753           GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
754         }
755       }
756       ret = gst_pad_event_default (pad, parent, event);
757       break;
758     case GST_EVENT_SEGMENT:
759     {
760       gst_event_copy_segment (event, &demux->priv->segment);
761
762       demux->priv->need_newseg = TRUE;
763       gst_event_unref (event);
764       ret = TRUE;
765       break;
766     }
767     case GST_EVENT_FLUSH_STOP:
768     case GST_EVENT_FLUSH_START:
769       ret = gst_pad_event_default (pad, parent, event);
770       break;
771     case GST_EVENT_CAPS:
772       /* we drop the caps event. We do typefind and push a new caps event. */
773       ret = gst_pad_event_default (pad, parent, event);
774       break;
775     default:
776       if (demux->priv->need_newseg && GST_EVENT_IS_SERIALIZED (event)) {
777         /* Cache all events if we have a pending segment, so they don't get
778          * lost (esp. tag events) */
779         GST_INFO_OBJECT (demux, "caching event: %" GST_PTR_FORMAT, event);
780         GST_OBJECT_LOCK (demux);
781         demux->priv->pending_events =
782             g_list_append (demux->priv->pending_events, event);
783         GST_OBJECT_UNLOCK (demux);
784         ret = TRUE;
785       } else {
786         ret = gst_pad_event_default (pad, parent, event);
787       }
788       break;
789   }
790
791   return ret;
792 }
793
794 static gboolean
795 gst_tag_demux_get_upstream_size (GstTagDemux * tagdemux)
796 {
797   gint64 len;
798
799   /* Short-cut if we already queried upstream */
800   if (tagdemux->priv->upstream_size > 0)
801     return TRUE;
802
803   if (!gst_pad_peer_query_duration (tagdemux->priv->sinkpad, GST_FORMAT_BYTES,
804           &len) || len <= 0) {
805     return FALSE;
806   }
807
808   tagdemux->priv->upstream_size = len;
809   return TRUE;
810 }
811
812 static gboolean
813 gst_tag_demux_seek_pull (GstTagDemux * tagdemux, GstEvent * event)
814 {
815   GstSeekFlags flags;
816   GstSeekType start_type, stop_type;
817   GstFormat format;
818   gboolean flush;
819   gdouble rate;
820   gint64 start, stop;
821   GstSegment seeksegment = { 0, };
822
823   gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
824       &stop_type, &stop);
825
826   /* we can only seek on bytes */
827   if (format != GST_FORMAT_BYTES) {
828     GST_DEBUG_OBJECT (tagdemux, "Can only seek on BYTES");
829     return FALSE;
830   }
831
832   if (tagdemux->priv->state != GST_TAG_DEMUX_STREAMING) {
833     GST_DEBUG_OBJECT (tagdemux, "Can only seek if streaming already");
834     return FALSE;
835   }
836
837   switch (start_type) {
838     case GST_SEEK_TYPE_SET:
839       if (start == -1)
840         start = 0;
841       start += tagdemux->priv->strip_start;
842       break;
843     case GST_SEEK_TYPE_END:
844       /* Adjust the seek to be relative to the start of any end tag
845        * (note: 10 bytes before end is represented by stop=-10) */
846       if (start > 0)
847         start = 0;
848       start -= tagdemux->priv->strip_end;
849       break;
850     case GST_SEEK_TYPE_NONE:
851     default:
852       break;
853   }
854   switch (stop_type) {
855     case GST_SEEK_TYPE_SET:
856       if (stop != -1) {
857         /* -1 means the end of the file, pass it upstream intact */
858         stop += tagdemux->priv->strip_start;
859       }
860       break;
861     case GST_SEEK_TYPE_END:
862       /* Adjust the seek to be relative to the start of any end tag
863        * (note: 10 bytes before end is represented by stop=-10) */
864       if (stop > 0)
865         stop = 0;
866       stop -= tagdemux->priv->strip_end;
867       break;
868     case GST_SEEK_TYPE_NONE:
869     default:
870       break;
871   }
872
873   /* copy segment, we need this because we still need the old
874    * segment when we close the current segment. */
875   memcpy (&seeksegment, &tagdemux->priv->segment, sizeof (GstSegment));
876
877   GST_DEBUG_OBJECT (tagdemux, "configuring seek");
878   gst_segment_do_seek (&seeksegment, rate, format, flags,
879       start_type, start, stop_type, stop, NULL);
880
881   flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
882
883   GST_DEBUG_OBJECT (tagdemux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
884
885   if (flush) {
886     GST_DEBUG_OBJECT (tagdemux, "Starting flush");
887     gst_pad_push_event (tagdemux->priv->sinkpad, gst_event_new_flush_start ());
888     gst_pad_push_event (tagdemux->priv->srcpad, gst_event_new_flush_start ());
889   } else {
890     GST_DEBUG_OBJECT (tagdemux, "Non-flushing seek, pausing task");
891     gst_pad_pause_task (tagdemux->priv->sinkpad);
892   }
893
894   /* now grab the stream lock so that streaming cannot continue, for
895    * non flushing seeks when the element is in PAUSED this could block
896    * forever. */
897   GST_DEBUG_OBJECT (tagdemux, "Waiting for streaming to stop");
898   GST_PAD_STREAM_LOCK (tagdemux->priv->sinkpad);
899
900   if (flush) {
901     GST_DEBUG_OBJECT (tagdemux, "Stopping flush");
902     gst_pad_push_event (tagdemux->priv->sinkpad,
903         gst_event_new_flush_stop (TRUE));
904     gst_pad_push_event (tagdemux->priv->srcpad,
905         gst_event_new_flush_stop (TRUE));
906   }
907
908   /* now update the real segment info */
909   GST_DEBUG_OBJECT (tagdemux, "Committing new seek segment");
910   memcpy (&tagdemux->priv->segment, &seeksegment, sizeof (GstSegment));
911   tagdemux->priv->offset = tagdemux->priv->segment.start;
912
913   /* notify start of new segment */
914   if (tagdemux->priv->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
915     GstMessage *msg;
916
917     msg = gst_message_new_segment_start (GST_OBJECT (tagdemux),
918         GST_FORMAT_BYTES, tagdemux->priv->segment.start);
919     gst_element_post_message (GST_ELEMENT (tagdemux), msg);
920   }
921
922   tagdemux->priv->need_newseg = TRUE;
923
924   /* restart our task since it might have been stopped when we did the
925    * flush. */
926   gst_pad_start_task (tagdemux->priv->sinkpad,
927       (GstTaskFunction) gst_tag_demux_element_loop, tagdemux, NULL);
928
929   /* streaming can continue now */
930   GST_PAD_STREAM_UNLOCK (tagdemux->priv->sinkpad);
931
932   return TRUE;
933 }
934
935 static gboolean
936 gst_tag_demux_seek_push (GstTagDemux * tagdemux, GstEvent * event)
937 {
938   gboolean res = FALSE;
939   gdouble rate;
940   GstFormat format;
941   GstSeekType start_type, stop_type;
942   GstSeekFlags flags;
943   gint64 start, stop;
944
945   gst_event_parse_seek (event, &rate, &format, &flags,
946       &start_type, &start, &stop_type, &stop);
947
948   if (format == GST_FORMAT_BYTES &&
949       tagdemux->priv->state == GST_TAG_DEMUX_STREAMING &&
950       gst_pad_is_linked (tagdemux->priv->sinkpad)) {
951     GstEvent *upstream;
952
953     switch (start_type) {
954       case GST_SEEK_TYPE_SET:
955         if (start == -1)
956           start = 0;
957         start += tagdemux->priv->strip_start;
958         break;
959       case GST_SEEK_TYPE_END:
960         /* Adjust the seek to be relative to the start of any end tag
961          * (note: 10 bytes before end is represented by stop=-10) */
962         if (start > 0)
963           start = 0;
964         start -= tagdemux->priv->strip_end;
965         break;
966       case GST_SEEK_TYPE_NONE:
967       default:
968         break;
969     }
970     switch (stop_type) {
971       case GST_SEEK_TYPE_SET:
972         if (stop != -1) {
973           /* -1 means the end of the file, pass it upstream intact */
974           stop += tagdemux->priv->strip_start;
975         }
976         break;
977       case GST_SEEK_TYPE_END:
978         /* Adjust the seek to be relative to the start of any end tag
979          * (note: 10 bytes before end is represented by stop=-10) */
980         if (stop > 0)
981           stop = 0;
982         stop -= tagdemux->priv->strip_end;
983         break;
984       case GST_SEEK_TYPE_NONE:
985       default:
986         break;
987     }
988     upstream = gst_event_new_seek (rate, format, flags,
989         start_type, start, stop_type, stop);
990     res = gst_pad_push_event (tagdemux->priv->sinkpad, upstream);
991   } else if (format == GST_FORMAT_TIME &&
992       tagdemux->priv->state == GST_TAG_DEMUX_STREAMING &&
993       gst_pad_is_linked (tagdemux->priv->sinkpad)) {
994     res = gst_pad_push_event (tagdemux->priv->sinkpad, gst_event_ref (event));
995   }
996
997   return res;
998 }
999
1000 static gboolean
1001 gst_tag_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
1002 {
1003   GstTagDemux *tagdemux;
1004   gboolean res = FALSE;
1005
1006   tagdemux = GST_TAG_DEMUX (parent);
1007
1008   /* Handle SEEK events, with adjusted byte offsets and sizes. */
1009
1010   switch (GST_EVENT_TYPE (event)) {
1011     case GST_EVENT_SEEK:
1012     {
1013       if (GST_PAD_MODE (tagdemux->priv->sinkpad) == GST_PAD_MODE_PUSH)
1014         res = gst_tag_demux_seek_push (tagdemux, event);
1015       else
1016         res = gst_tag_demux_seek_pull (tagdemux, event);
1017       break;
1018     }
1019     default:
1020       res = gst_pad_push_event (tagdemux->priv->sinkpad, event);
1021       event = NULL;
1022       break;
1023   }
1024
1025   if (event)
1026     gst_event_unref (event);
1027
1028   return res;
1029 }
1030
1031 /* Read and interpret any end tag when activating in pull_range.
1032  * Returns FALSE if pad activation should fail. */
1033 static GstFlowReturn
1034 gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags)
1035 {
1036   GstTagDemuxResult parse_ret;
1037   GstTagDemuxClass *klass;
1038   GstFlowReturn flow_ret;
1039   GstTagList *new_tags = NULL;
1040   GstBuffer *buffer = NULL;
1041   gboolean have_tag;
1042   guint64 offset;
1043   guint tagsize;
1044   gsize bsize;
1045
1046   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
1047
1048   g_assert (klass->identify_tag != NULL);
1049   g_assert (klass->parse_tag != NULL);
1050
1051   if (klass->min_end_size == 0) {
1052     GST_DEBUG_OBJECT (demux, "Not looking for tag at the end");
1053     return GST_FLOW_OK;
1054   }
1055
1056   if (demux->priv->upstream_size < klass->min_end_size) {
1057     GST_DEBUG_OBJECT (demux, "File too small");
1058     return GST_FLOW_OK;
1059   }
1060
1061   /* Pull enough to identify the tag and retrieve its total size */
1062   offset = demux->priv->upstream_size - klass->min_end_size;
1063
1064   flow_ret = gst_pad_pull_range (demux->priv->sinkpad, offset,
1065       klass->min_end_size, &buffer);
1066
1067   if (flow_ret != GST_FLOW_OK) {
1068     GST_DEBUG_OBJECT (demux, "Could not read tag header from end of file, "
1069         "ret = %s", gst_flow_get_name (flow_ret));
1070     goto done;
1071   }
1072
1073   bsize = gst_buffer_get_size (buffer);
1074
1075   if (bsize < klass->min_end_size) {
1076     GST_DEBUG_OBJECT (demux, "Only managed to read %" G_GSIZE_FORMAT " bytes"
1077         "from file (required: %u bytes)", bsize, klass->min_end_size);
1078     flow_ret = GST_FLOW_EOS;
1079     goto done;
1080   }
1081
1082   have_tag = klass->identify_tag (demux, buffer, FALSE, &tagsize);
1083
1084   if (!have_tag) {
1085     GST_DEBUG_OBJECT (demux, "Could not find tag at end");
1086     flow_ret = GST_FLOW_OK;
1087     goto done;
1088   }
1089
1090   /* Now pull the entire tag */
1091   do {
1092     guint newsize, saved_size;
1093
1094     GST_DEBUG_OBJECT (demux, "Identified tag at end, size=%u bytes", tagsize);
1095
1096     demux->priv->strip_end = tagsize;
1097
1098     g_assert (tagsize >= klass->min_end_size);
1099
1100     /* Get buffer that's exactly the requested size */
1101     if (bsize != tagsize) {
1102       gst_buffer_unref (buffer);
1103       buffer = NULL;
1104
1105       offset = demux->priv->upstream_size - tagsize;
1106
1107       flow_ret = gst_pad_pull_range (demux->priv->sinkpad, offset,
1108           tagsize, &buffer);
1109
1110       if (flow_ret != GST_FLOW_OK) {
1111         GST_DEBUG_OBJECT (demux, "Could not read data from end of file at "
1112             "offset %" G_GUINT64_FORMAT ". ret = %s", offset,
1113             gst_flow_get_name (flow_ret));
1114         goto done;
1115       }
1116
1117       bsize = gst_buffer_get_size (buffer);
1118
1119       if (bsize < tagsize) {
1120         GST_DEBUG_OBJECT (demux, "Only managed to read %" G_GSIZE_FORMAT
1121             " bytes from file", bsize);
1122         flow_ret = GST_FLOW_EOS;
1123         goto done;
1124       }
1125     }
1126
1127     GST_BUFFER_OFFSET (buffer) = offset;
1128
1129     saved_size = bsize;
1130     gst_buffer_set_size (buffer, tagsize);
1131     newsize = tagsize;
1132
1133     parse_ret = klass->parse_tag (demux, buffer, FALSE, &newsize, &new_tags);
1134
1135     gst_buffer_set_size (buffer, saved_size);
1136
1137     switch (parse_ret) {
1138       case GST_TAG_DEMUX_RESULT_OK:
1139         flow_ret = GST_FLOW_OK;
1140         demux->priv->strip_end = newsize;
1141         GST_DEBUG_OBJECT (demux, "Read tag at end, size %d",
1142             demux->priv->strip_end);
1143         break;
1144       case GST_TAG_DEMUX_RESULT_BROKEN_TAG:
1145         flow_ret = GST_FLOW_OK;
1146         demux->priv->strip_end = newsize;
1147         GST_WARNING_OBJECT (demux, "Ignoring broken tag at end, size %d",
1148             demux->priv->strip_end);
1149         break;
1150       case GST_TAG_DEMUX_RESULT_AGAIN:
1151         GST_DEBUG_OBJECT (demux, "Re-parse, this time with %d bytes", newsize);
1152         g_assert (newsize != tagsize);
1153         tagsize = newsize;
1154         break;
1155     }
1156   } while (parse_ret == GST_TAG_DEMUX_RESULT_AGAIN);
1157
1158   *tags = new_tags;
1159   new_tags = NULL;
1160
1161 done:
1162   if (new_tags)
1163     gst_tag_list_unref (new_tags);
1164   if (buffer)
1165     gst_buffer_unref (buffer);
1166   return flow_ret;
1167 }
1168
1169 /* Read and interpret any tag at the start when activating in
1170  * pull_range. Returns FALSE if pad activation should fail. */
1171 static GstFlowReturn
1172 gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags)
1173 {
1174   GstTagDemuxResult parse_ret;
1175   GstTagDemuxClass *klass;
1176   GstFlowReturn flow_ret;
1177   GstTagList *new_tags = NULL;
1178   GstBuffer *buffer = NULL;
1179   gboolean have_tag;
1180   guint req, tagsize;
1181   gsize bsize;
1182
1183   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
1184
1185   g_assert (klass->identify_tag != NULL);
1186   g_assert (klass->parse_tag != NULL);
1187
1188   if (klass->min_start_size == 0) {
1189     GST_DEBUG_OBJECT (demux, "Not looking for tag at the beginning");
1190     return GST_FLOW_OK;
1191   }
1192
1193   /* Handle tag at start. Try with 4kB to start with */
1194   req = MAX (klass->min_start_size, 4096);
1195
1196   /* Pull enough to identify the tag and retrieve its total size */
1197   flow_ret = gst_pad_pull_range (demux->priv->sinkpad, 0, req, &buffer);
1198   if (flow_ret != GST_FLOW_OK) {
1199     GST_DEBUG_OBJECT (demux, "Could not read data from start of file ret=%s",
1200         gst_flow_get_name (flow_ret));
1201     goto done;
1202   }
1203
1204   bsize = gst_buffer_get_size (buffer);
1205
1206   if (bsize < klass->min_start_size) {
1207     GST_DEBUG_OBJECT (demux, "Only managed to read %" G_GSIZE_FORMAT
1208         " bytes from file - no tag in this file", bsize);
1209     flow_ret = GST_FLOW_EOS;
1210     goto done;
1211   }
1212
1213   have_tag = klass->identify_tag (demux, buffer, TRUE, &tagsize);
1214
1215   if (!have_tag) {
1216     GST_DEBUG_OBJECT (demux, "Could not find start tag");
1217     flow_ret = GST_FLOW_OK;
1218     goto done;
1219   }
1220
1221   GST_DEBUG_OBJECT (demux, "Identified start tag, size = %u bytes", tagsize);
1222
1223   do {
1224     guint newsize, saved_size;
1225
1226     demux->priv->strip_start = tagsize;
1227
1228     /* Now pull the entire tag */
1229     g_assert (tagsize >= klass->min_start_size);
1230
1231     if (bsize < tagsize) {
1232       gst_buffer_unref (buffer);
1233       buffer = NULL;
1234
1235       flow_ret = gst_pad_pull_range (demux->priv->sinkpad, 0, tagsize, &buffer);
1236       if (flow_ret != GST_FLOW_OK) {
1237         GST_DEBUG_OBJECT (demux, "Could not read data from start of file, "
1238             "ret = %s", gst_flow_get_name (flow_ret));
1239         goto done;
1240       }
1241
1242       bsize = gst_buffer_get_size (buffer);
1243
1244       if (bsize < tagsize) {
1245         GST_DEBUG_OBJECT (demux, "Only managed to read %" G_GSIZE_FORMAT
1246             " bytes from file", bsize);
1247         GST_ELEMENT_ERROR (demux, STREAM, DECODE,
1248             (_("Failed to read tag: not enough data")), (NULL));
1249         flow_ret = GST_FLOW_EOS;
1250         goto done;
1251       }
1252     }
1253
1254     saved_size = bsize;
1255     gst_buffer_set_size (buffer, tagsize);
1256     newsize = tagsize;
1257     parse_ret = klass->parse_tag (demux, buffer, TRUE, &newsize, &new_tags);
1258
1259     gst_buffer_set_size (buffer, saved_size);
1260
1261     switch (parse_ret) {
1262       case GST_TAG_DEMUX_RESULT_OK:
1263         flow_ret = GST_FLOW_OK;
1264         demux->priv->strip_start = newsize;
1265         GST_DEBUG_OBJECT (demux, "Read start tag of size %d", newsize);
1266         break;
1267       case GST_TAG_DEMUX_RESULT_BROKEN_TAG:
1268         flow_ret = GST_FLOW_OK;
1269         demux->priv->strip_start = newsize;
1270         GST_WARNING_OBJECT (demux, "Ignoring broken start tag of size %d",
1271             demux->priv->strip_start);
1272         break;
1273       case GST_TAG_DEMUX_RESULT_AGAIN:
1274         GST_DEBUG_OBJECT (demux, "Re-parse, this time with %d bytes", newsize);
1275         g_assert (newsize != tagsize);
1276         tagsize = newsize;
1277         break;
1278     }
1279   } while (parse_ret == GST_TAG_DEMUX_RESULT_AGAIN);
1280
1281   *tags = new_tags;
1282   new_tags = NULL;
1283
1284 done:
1285   if (new_tags)
1286     gst_tag_list_unref (new_tags);
1287   if (buffer)
1288     gst_buffer_unref (buffer);
1289   return flow_ret;
1290 }
1291
1292 /* This function operates similarly to gst_type_find_element_loop
1293  * in the typefind element
1294  * 1. try to read tags in pull mode
1295  * 2. typefind the contents
1296  * 3. if we didn't find any caps, fail.
1297  * 4. set caps on srcpad
1298  */
1299 static GstFlowReturn
1300 gst_tag_demux_element_find (GstTagDemux * demux)
1301 {
1302   GstTagDemuxClass *klass;
1303   GstTypeFindProbability probability = 0;
1304   GstFlowReturn ret = GST_FLOW_OK;
1305   GstTagList *start_tags = NULL;
1306   GstTagList *end_tags = NULL;
1307   gboolean e_tag_ok, s_tag_ok;
1308   GstCaps *caps = NULL;
1309
1310   /* Look for tags at start and end of file */
1311   GST_DEBUG_OBJECT (demux, "Activated pull mode. Looking for tags");
1312   if (!gst_tag_demux_get_upstream_size (demux))
1313     goto no_size;
1314
1315   demux->priv->strip_start = 0;
1316   demux->priv->strip_end = 0;
1317
1318   /* 1 - Read tags */
1319   ret = gst_tag_demux_pull_start_tag (demux, &start_tags);
1320   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
1321     goto read_tag_error;
1322   s_tag_ok = ret == GST_FLOW_OK;
1323   ret = gst_tag_demux_pull_end_tag (demux, &end_tags);
1324   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
1325     goto read_tag_error;
1326   e_tag_ok = ret == GST_FLOW_OK;
1327   ret = GST_FLOW_OK;
1328
1329   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
1330
1331   if (klass->merge_tags != NULL) {
1332     demux->priv->parsed_tags = klass->merge_tags (demux, start_tags, end_tags);
1333   } else {
1334     /* we merge in REPLACE mode, so put the less important tags first, which
1335      * we'll just assume is the end tag (subclasses may change this behaviour
1336      * or make it configurable by overriding the merge_tags vfunc) */
1337     demux->priv->parsed_tags =
1338         gst_tag_list_merge (end_tags, start_tags, GST_TAG_MERGE_REPLACE);
1339   }
1340
1341   if (start_tags)
1342     gst_tag_list_unref (start_tags);
1343   if (end_tags)
1344     gst_tag_list_unref (end_tags);
1345
1346   /* Only happens if both are EOS, i.e. not enough data could be read */
1347   if (!e_tag_ok && !s_tag_ok)
1348     goto no_tags;
1349
1350   if (demux->priv->parsed_tags != NULL) {
1351     demux->priv->send_tag_event = TRUE;
1352   }
1353
1354   if (demux->priv->upstream_size <=
1355       demux->priv->strip_start + demux->priv->strip_end)
1356     goto no_data;
1357
1358   /* 2 - Do typefinding on data, but not if downstream is in charge */
1359   if (GST_PAD_MODE (demux->priv->srcpad) == GST_PAD_MODE_PULL)
1360     goto skip_typefinding;
1361
1362   ret = gst_type_find_helper_get_range_full (GST_OBJECT (demux), NULL,
1363       (GstTypeFindHelperGetRangeFunction) gst_tag_demux_read_range,
1364       demux->priv->upstream_size
1365       - (demux->priv->strip_start + demux->priv->strip_end), NULL,
1366       &caps, &probability);
1367   if (ret != GST_FLOW_OK)
1368     goto read_tag_error;
1369
1370   GST_INFO_OBJECT (demux, "Found type %" GST_PTR_FORMAT " with a "
1371       "probability of %u", caps, probability);
1372
1373   /* 3 - If we didn't find the caps, fail */
1374   if (caps == NULL)
1375     goto no_caps;
1376
1377   /* tag reading and typefinding were already done, don't do them again in
1378    * the chain function if we end up in push mode */
1379   demux->priv->state = GST_TAG_DEMUX_STREAMING;
1380
1381   /* 6 Set the srcpad caps now that we know them */
1382   gst_tag_demux_set_src_caps (demux, caps);
1383   gst_caps_unref (caps);
1384
1385 skip_typefinding:
1386
1387   /* set it again, in case we skipped typefinding */
1388   demux->priv->state = GST_TAG_DEMUX_STREAMING;
1389   demux->priv->offset += demux->priv->strip_start;
1390
1391   return ret;
1392
1393   /* ERRORS */
1394 no_size:
1395   {
1396     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND,
1397         ("Could not get stream size"), (NULL));
1398     return GST_FLOW_ERROR;
1399   }
1400 read_tag_error:
1401   {
1402     if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS)
1403       GST_ELEMENT_FLOW_ERROR (demux, ret);
1404     return ret;
1405   }
1406 no_tags:
1407   {
1408     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND,
1409         ("Could not get start and/or end tag"), (NULL));
1410     return GST_FLOW_ERROR;
1411   }
1412 no_data:
1413   {
1414     /* There was no data (probably due to a truncated file) */
1415     /* so we don't know about type either */
1416     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, ("No data in file"),
1417         (NULL));
1418     return GST_FLOW_ERROR;
1419   }
1420 no_caps:
1421   {
1422     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND,
1423         ("Could not detect type of contents"), (NULL));
1424     return GST_FLOW_ERROR;
1425   }
1426 }
1427
1428 /* This function operates similarly to gst_type_find_element_loop
1429  * in the typefind element
1430  * 1. try to read tags in pull mode
1431  * 2. typefind the contents
1432  * 3. if we didn't find any caps, fail.
1433  * 4. set caps on srcpad
1434  */
1435 static void
1436 gst_tag_demux_element_loop (GstTagDemux * demux)
1437 {
1438   GstFlowReturn ret;
1439
1440   switch (demux->priv->state) {
1441     case GST_TAG_DEMUX_READ_START_TAG:
1442     case GST_TAG_DEMUX_TYPEFINDING:
1443       ret = gst_tag_demux_element_find (demux);
1444       break;
1445     case GST_TAG_DEMUX_STREAMING:
1446     {
1447       GstBuffer *outbuf = NULL;
1448
1449       if (demux->priv->need_newseg) {
1450         demux->priv->need_newseg = FALSE;
1451         /* FIXME: check segment, should be 0-N for downstream */
1452         gst_tag_demux_send_new_segment (demux);
1453       }
1454
1455       /* Send our own pending tag event */
1456       if (demux->priv->send_tag_event) {
1457         gst_tag_demux_send_tag_event (demux);
1458         demux->priv->send_tag_event = FALSE;
1459       }
1460
1461       /* Pull data and push it downstream */
1462       ret = gst_pad_pull_range (demux->priv->sinkpad, demux->priv->offset,
1463           DEFAULT_PULL_BLOCKSIZE, &outbuf);
1464
1465       if (ret != GST_FLOW_OK)
1466         break;
1467
1468       GST_BUFFER_OFFSET (outbuf) =
1469           demux->priv->offset - demux->priv->strip_start;
1470       demux->priv->offset += gst_buffer_get_size (outbuf);
1471       GST_BUFFER_OFFSET_END (outbuf) =
1472           demux->priv->offset - demux->priv->strip_start;
1473
1474       ret = gst_pad_push (demux->priv->srcpad, outbuf);
1475       break;
1476     }
1477     default:
1478       ret = GST_FLOW_ERROR;
1479       break;
1480   }
1481   if (ret != GST_FLOW_OK)
1482     goto pause;
1483
1484   return;
1485
1486   /* ERRORS */
1487 pause:
1488   {
1489     const gchar *reason = gst_flow_get_name (ret);
1490     gboolean push_eos = FALSE;
1491
1492     GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
1493     gst_pad_pause_task (demux->priv->sinkpad);
1494
1495     if (ret == GST_FLOW_EOS) {
1496       /* perform EOS logic */
1497
1498       if (demux->priv->segment.flags & GST_SEEK_FLAG_SEGMENT) {
1499         gint64 stop;
1500
1501         /* for segment playback we need to post when (in stream time)
1502          * we stopped, this is either stop (when set) or the duration. */
1503         if ((stop = demux->priv->segment.stop) == -1)
1504           stop = demux->priv->offset;
1505
1506         GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
1507         gst_element_post_message (GST_ELEMENT_CAST (demux),
1508             gst_message_new_segment_done (GST_OBJECT_CAST (demux),
1509                 GST_FORMAT_BYTES, stop));
1510         gst_pad_push_event (demux->priv->srcpad,
1511             gst_event_new_segment_done (GST_FORMAT_BYTES, stop));
1512       } else {
1513         push_eos = TRUE;
1514       }
1515     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
1516       /* for fatal errors we post an error message */
1517       GST_ELEMENT_FLOW_ERROR (demux, ret);
1518       push_eos = TRUE;
1519     }
1520     if (push_eos) {
1521       /* send EOS, and prevent hanging if no streams yet */
1522       GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
1523       gst_pad_push_event (demux->priv->srcpad, gst_event_new_eos ());
1524     }
1525     return;
1526   }
1527 }
1528
1529 static gboolean
1530 gst_tag_demux_sink_activate_mode (GstPad * pad, GstObject * parent,
1531     GstPadMode mode, gboolean active)
1532 {
1533   GstTagDemux *demux = GST_TAG_DEMUX (parent);
1534   gboolean res;
1535
1536   switch (mode) {
1537     case GST_PAD_MODE_PULL:
1538       if (active) {
1539         demux->priv->need_newseg = TRUE;
1540         demux->priv->offset = 0;
1541         res = TRUE;
1542       } else {
1543         res = gst_pad_stop_task (pad);
1544       }
1545       break;
1546     default:
1547       res = TRUE;
1548       break;
1549   }
1550
1551   if (active)
1552     GST_TAG_DEMUX (parent)->priv->state = GST_TAG_DEMUX_READ_START_TAG;
1553
1554   return res;
1555 }
1556
1557 static gboolean
1558 gst_tag_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
1559 {
1560   GstTagDemux *demux;
1561   GstQuery *query;
1562   gboolean pull_mode;
1563
1564   demux = GST_TAG_DEMUX (parent);
1565
1566   /* 1: */
1567   /* If we can activate pull_range upstream, then read any end and start
1568    * tags, otherwise activate in push mode and the chain function will
1569    * collect buffers, read the start tag and output a buffer to end
1570    * preroll.
1571    */
1572   query = gst_query_new_scheduling ();
1573
1574   if (!gst_pad_peer_query (sinkpad, query)) {
1575     gst_query_unref (query);
1576     goto activate_push;
1577   }
1578
1579   pull_mode = gst_query_has_scheduling_mode_with_flags (query,
1580       GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
1581   gst_query_unref (query);
1582
1583   if (!pull_mode)
1584     goto activate_push;
1585
1586   if (!gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE))
1587     goto activate_push;
1588
1589   /* only start our task if we ourselves decide to start in pull mode */
1590   return gst_pad_start_task (sinkpad,
1591       (GstTaskFunction) gst_tag_demux_element_loop, demux, NULL);
1592
1593 activate_push:
1594   {
1595     GST_DEBUG_OBJECT (demux, "No pull mode. Changing to push, but won't be "
1596         "able to read end tags");
1597     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
1598   }
1599 }
1600
1601 static gboolean
1602 gst_tag_demux_src_activate_mode (GstPad * pad, GstObject * parent,
1603     GstPadMode mode, gboolean active)
1604 {
1605   gboolean res;
1606   GstTagDemux *demux = GST_TAG_DEMUX (parent);
1607
1608   switch (mode) {
1609     case GST_PAD_MODE_PULL:
1610       /* make sure our task stops pushing, we can't call _stop here
1611        * because this activation might happen from the streaming thread. */
1612       gst_pad_pause_task (demux->priv->sinkpad);
1613       res = gst_pad_activate_mode (demux->priv->sinkpad, mode, active);
1614       break;
1615     default:
1616       res = TRUE;
1617       break;
1618   }
1619   return res;
1620 }
1621
1622 static inline GstFlowReturn
1623 gst_tag_demux_ensure_tags (GstTagDemux * demux)
1624 {
1625   GstFlowReturn flow = GST_FLOW_OK;
1626
1627   if (G_UNLIKELY (demux->priv->state == GST_TAG_DEMUX_READ_START_TAG &&
1628           GST_PAD_MODE (demux->priv->srcpad) == GST_PAD_MODE_PULL)) {
1629
1630     flow = gst_tag_demux_element_find (demux);
1631     GST_INFO_OBJECT (demux, "pulled tags: %s", gst_flow_get_name (flow));
1632   }
1633   return flow;
1634 }
1635
1636 static GstFlowReturn
1637 gst_tag_demux_read_range (GstTagDemux * demux, GstObject * parent,
1638     guint64 offset, guint length, GstBuffer ** buffer)
1639 {
1640   GstFlowReturn ret;
1641   guint64 in_offset;
1642   guint in_length;
1643   gsize size;
1644
1645   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
1646
1647   /* Ensure we already have computed our tags to properly use the offsets
1648    * below */
1649   ret = gst_tag_demux_ensure_tags (demux);
1650   if (ret != GST_FLOW_OK)
1651     return ret;
1652
1653   /* Adjust offset and length of the request to trim off tag information.
1654    * For the returned buffer, adjust the output offset to match what downstream
1655    * should see */
1656   in_offset = offset + demux->priv->strip_start;
1657
1658   if (!gst_tag_demux_get_upstream_size (demux))
1659     return GST_FLOW_ERROR;
1660
1661   if (in_offset + length >= demux->priv->upstream_size - demux->priv->strip_end) {
1662     if (in_offset + demux->priv->strip_end >= demux->priv->upstream_size)
1663       return GST_FLOW_EOS;
1664     in_length = demux->priv->upstream_size - demux->priv->strip_end - in_offset;
1665   } else {
1666     in_length = length;
1667   }
1668
1669   ret = gst_pad_pull_range (demux->priv->sinkpad, in_offset, in_length, buffer);
1670
1671   if (ret == GST_FLOW_OK && *buffer) {
1672     if (!gst_tag_demux_trim_buffer (demux, buffer, &size))
1673       goto read_beyond_end;
1674
1675     /* this should only happen in streaming mode */
1676     g_assert (*buffer != NULL);
1677   }
1678
1679   return ret;
1680
1681 read_beyond_end:
1682   {
1683     GST_DEBUG_OBJECT (demux, "attempted read beyond end of file");
1684     if (*buffer != NULL) {
1685       gst_buffer_unref (*buffer);
1686       *buffer = NULL;
1687     }
1688     return GST_FLOW_EOS;
1689   }
1690 }
1691
1692 static GstFlowReturn
1693 gst_tag_demux_src_getrange (GstPad * srcpad, GstObject * parent,
1694     guint64 offset, guint length, GstBuffer ** buffer)
1695 {
1696   GstTagDemux *demux = GST_TAG_DEMUX (parent);
1697
1698   /* downstream in pull mode won't miss a newsegment event,
1699    * but it likely appreciates other (tag) events */
1700   if (demux->priv->need_newseg) {
1701     gst_tag_demux_send_pending_events (demux);
1702     demux->priv->need_newseg = FALSE;
1703   }
1704
1705   if (demux->priv->send_tag_event) {
1706     gst_tag_demux_send_tag_event (demux);
1707     demux->priv->send_tag_event = FALSE;
1708   }
1709
1710   return gst_tag_demux_read_range (demux, NULL, offset, length, buffer);
1711 }
1712
1713 static GstStateChangeReturn
1714 gst_tag_demux_change_state (GstElement * element, GstStateChange transition)
1715 {
1716   GstStateChangeReturn ret;
1717   GstTagDemux *demux = GST_TAG_DEMUX (element);
1718
1719   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1720
1721   switch (transition) {
1722     case GST_STATE_CHANGE_PAUSED_TO_READY:
1723       /* Ensure that nothing is in any of the streaming thread functions
1724        * anymore. While the above has deactivated all pads, there is nothing
1725        * preventing downstream from activating our srcpad again and calling the
1726        * getrange() function. Although we're in READY!
1727        */
1728       GST_PAD_STREAM_LOCK (demux->priv->srcpad);
1729       gst_tag_demux_reset (demux);
1730       GST_PAD_STREAM_UNLOCK (demux->priv->srcpad);
1731       break;
1732     default:
1733       break;
1734   }
1735
1736   return ret;
1737 }
1738
1739 static gboolean
1740 gst_tag_demux_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
1741 {
1742   /* For a position or duration query, adjust the returned
1743    * bytes to strip off the end and start areas */
1744   GstTagDemux *demux = GST_TAG_DEMUX (parent);
1745   GstFormat format;
1746   gint64 result;
1747   gboolean res = TRUE;
1748
1749   /* FIXME: locking ? */
1750   switch (GST_QUERY_TYPE (query)) {
1751     case GST_QUERY_SCHEDULING:
1752       res = gst_pad_peer_query (demux->priv->sinkpad, query);
1753       break;
1754     case GST_QUERY_POSITION:
1755     {
1756       if (!(res = gst_pad_peer_query (demux->priv->sinkpad, query)))
1757         goto done;
1758
1759       gst_query_parse_position (query, &format, &result);
1760       if (format == GST_FORMAT_BYTES) {
1761         result -= demux->priv->strip_start;
1762         gst_query_set_position (query, format, result);
1763       }
1764       break;
1765     }
1766     case GST_QUERY_DURATION:
1767     {
1768       if (!(res = gst_pad_peer_query (demux->priv->sinkpad, query)))
1769         goto done;
1770
1771       gst_query_parse_duration (query, &format, &result);
1772       if (format == GST_FORMAT_BYTES) {
1773         /* if downstream activated us in pull mode right away, e.g. in case of
1774          * filesrc ! id3demux ! xyzparse ! .., read tags here, since we don't
1775          * have a streaming thread of our own to do that. We do it here and
1776          * not in get_range(), so we can return the right size in bytes.. */
1777         gst_tag_demux_ensure_tags (demux);
1778         result -= demux->priv->strip_start + demux->priv->strip_end;
1779         if (result < 0)
1780           result = 0;
1781         gst_query_set_duration (query, format, result);
1782       }
1783       break;
1784     }
1785     default:
1786       res = gst_pad_query_default (pad, parent, query);
1787       break;
1788   }
1789 done:
1790   return res;
1791 }
1792
1793 static void
1794 gst_tag_demux_send_pending_events (GstTagDemux * demux)
1795 {
1796   GList *events;
1797
1798   /* send any pending events we cached */
1799   GST_OBJECT_LOCK (demux);
1800   events = demux->priv->pending_events;
1801   demux->priv->pending_events = NULL;
1802   GST_OBJECT_UNLOCK (demux);
1803
1804   while (events != NULL) {
1805     GST_DEBUG_OBJECT (demux->priv->srcpad, "sending cached %s event: %"
1806         GST_PTR_FORMAT, GST_EVENT_TYPE_NAME (events->data), events->data);
1807     gst_pad_push_event (demux->priv->srcpad, GST_EVENT (events->data));
1808     events = g_list_delete_link (events, events);
1809   }
1810 }
1811
1812 static void
1813 gst_tag_demux_send_tag_event (GstTagDemux * demux)
1814 {
1815   /* FIXME: what's the correct merge mode? Docs need to tell... */
1816   GstTagList *merged = gst_tag_list_merge (demux->priv->event_tags,
1817       demux->priv->parsed_tags, GST_TAG_MERGE_KEEP);
1818
1819   if (merged) {
1820     GstEvent *event = gst_event_new_tag (merged);
1821
1822     GST_DEBUG_OBJECT (demux, "Sending tag event on src pad");
1823     gst_pad_push_event (demux->priv->srcpad, event);
1824   }
1825 }
1826
1827 static gboolean
1828 gst_tag_demux_send_new_segment (GstTagDemux * tagdemux)
1829 {
1830   GstEvent *event;
1831   gint64 start, stop, time;
1832   GstSegment *seg = &tagdemux->priv->segment;
1833   GstSegment newseg;
1834
1835   if (seg->format == GST_FORMAT_UNDEFINED) {
1836     GST_LOG_OBJECT (tagdemux,
1837         "No new segment received before first buffer. Using default");
1838     gst_segment_init (seg, GST_FORMAT_BYTES);
1839     seg->start = tagdemux->priv->strip_start;
1840     seg->time = tagdemux->priv->strip_start;
1841   }
1842
1843   /* Can't adjust segments in non-BYTES formats */
1844   if (tagdemux->priv->segment.format != GST_FORMAT_BYTES) {
1845     event = gst_event_new_segment (seg);
1846     return gst_pad_push_event (tagdemux->priv->srcpad, event);
1847   }
1848
1849   start = seg->start;
1850   stop = seg->stop;
1851   time = seg->time;
1852
1853   g_return_val_if_fail (start != -1, FALSE);
1854   g_return_val_if_fail (time != -1, FALSE);
1855
1856   if (tagdemux->priv->strip_end > 0) {
1857     if (gst_tag_demux_get_upstream_size (tagdemux)) {
1858       guint64 v1tag_offset =
1859           tagdemux->priv->upstream_size - tagdemux->priv->strip_end;
1860
1861       if (start >= v1tag_offset) {
1862         /* Segment is completely within the end tag, output an open-ended
1863          * segment, even though all the buffers will get trimmed away */
1864         start = v1tag_offset;
1865         stop = -1;
1866       }
1867
1868       if (stop != -1 && stop >= v1tag_offset) {
1869         GST_DEBUG_OBJECT (tagdemux,
1870             "Segment crosses the end tag. Trimming end");
1871         stop = v1tag_offset;
1872       }
1873     }
1874   }
1875
1876   if (tagdemux->priv->strip_start > 0) {
1877     if (start > tagdemux->priv->strip_start)
1878       start -= tagdemux->priv->strip_start;
1879     else
1880       start = 0;
1881
1882     if (time > tagdemux->priv->strip_start)
1883       time -= tagdemux->priv->strip_start;
1884     else
1885       time = 0;
1886
1887     if (stop != -1) {
1888       if (stop > tagdemux->priv->strip_start)
1889         stop -= tagdemux->priv->strip_start;
1890       else
1891         stop = 0;
1892     }
1893   }
1894
1895   GST_DEBUG_OBJECT (tagdemux, "Sending segment %" GST_SEGMENT_FORMAT, seg);
1896
1897   gst_segment_copy_into (seg, &newseg);
1898   newseg.start = start;
1899   newseg.stop = stop;
1900   newseg.time = time;
1901   event = gst_event_new_segment (&newseg);
1902
1903   return gst_pad_push_event (tagdemux->priv->srcpad, event);
1904 }