gst/matroska/: Make sure that every Tags element is only parsed once and it's contain...
[platform/upstream/gst-plugins-good.git] / gst / matroska / ebml-read.c
1 /* GStreamer EBML I/O
2  * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  *
4  * ebml-read.c: read EBML data from file/stream
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include "ebml-read.h"
29 #include "ebml-ids.h"
30
31 #include <math.h>
32
33 GST_DEBUG_CATEGORY_STATIC (ebmlread_debug);
34 #define GST_CAT_DEFAULT ebmlread_debug
35
36 static void gst_ebml_read_class_init (GstEbmlReadClass * klass);
37
38 static void gst_ebml_read_init (GstEbmlRead * ebml);
39
40 static GstStateChangeReturn gst_ebml_read_change_state (GstElement * element,
41     GstStateChange transition);
42
43 /* convenience functions */
44 static GstFlowReturn gst_ebml_read_peek_bytes (GstEbmlRead * ebml, guint size,
45     GstBuffer ** p_buf, guint8 ** bytes);
46 static GstFlowReturn gst_ebml_read_pull_bytes (GstEbmlRead * ebml, guint size,
47     GstBuffer ** p_buf, guint8 ** bytes);
48
49
50 static GstElementClass *parent_class;   /* NULL */
51
52 GType
53 gst_ebml_read_get_type (void)
54 {
55   static GType gst_ebml_read_type;      /* 0 */
56
57   if (!gst_ebml_read_type) {
58     static const GTypeInfo gst_ebml_read_info = {
59       sizeof (GstEbmlReadClass),
60       NULL,
61       NULL,
62       (GClassInitFunc) gst_ebml_read_class_init,
63       NULL,
64       NULL,
65       sizeof (GstEbmlRead),
66       0,
67       (GInstanceInitFunc) gst_ebml_read_init,
68     };
69
70     gst_ebml_read_type =
71         g_type_register_static (GST_TYPE_ELEMENT, "GstEbmlRead",
72         &gst_ebml_read_info, 0);
73   }
74
75   return gst_ebml_read_type;
76 }
77
78 void
79 gst_ebml_level_free (GstEbmlLevel * level)
80 {
81   g_slice_free (GstEbmlLevel, level);
82 }
83
84 static void
85 gst_ebml_finalize (GObject * obj)
86 {
87   GstEbmlRead *ebml = GST_EBML_READ (obj);
88
89   g_list_foreach (ebml->level, (GFunc) gst_ebml_level_free, NULL);
90   g_list_free (ebml->level);
91   ebml->level = NULL;
92   if (ebml->cached_buffer) {
93     gst_buffer_unref (ebml->cached_buffer);
94     ebml->cached_buffer = NULL;
95   }
96
97   G_OBJECT_CLASS (parent_class)->finalize (obj);
98 }
99
100 static void
101 gst_ebml_read_class_init (GstEbmlReadClass * klass)
102 {
103   GstElementClass *gstelement_class = (GstElementClass *) klass;
104
105   GObjectClass *gobject_class = (GObjectClass *) klass;
106
107   parent_class = g_type_class_peek_parent (klass);
108
109   GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
110       0, "EBML stream helper class");
111
112   gobject_class->finalize = gst_ebml_finalize;
113
114   gstelement_class->change_state =
115       GST_DEBUG_FUNCPTR (gst_ebml_read_change_state);
116 }
117
118 static void
119 gst_ebml_read_init (GstEbmlRead * ebml)
120 {
121   ebml->sinkpad = NULL;
122   ebml->level = NULL;
123 }
124
125 static GstStateChangeReturn
126 gst_ebml_read_change_state (GstElement * element, GstStateChange transition)
127 {
128   GstStateChangeReturn ret;
129
130   GstEbmlRead *ebml = GST_EBML_READ (element);
131
132   switch (transition) {
133     case GST_STATE_CHANGE_READY_TO_PAUSED:
134       if (!ebml->sinkpad) {
135         g_return_val_if_reached (GST_STATE_CHANGE_FAILURE);
136       }
137       break;
138     default:
139       break;
140   }
141
142   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
143
144   switch (transition) {
145     case GST_STATE_CHANGE_PAUSED_TO_READY:
146     {
147       g_list_foreach (ebml->level, (GFunc) gst_ebml_level_free, NULL);
148       g_list_free (ebml->level);
149       ebml->level = NULL;
150       if (ebml->cached_buffer) {
151         gst_buffer_unref (ebml->cached_buffer);
152         ebml->cached_buffer = NULL;
153       }
154       ebml->offset = 0;
155       break;
156     }
157     default:
158       break;
159   }
160
161   return ret;
162 }
163
164 /*
165  * Return: the amount of levels in the hierarchy that the
166  * current element lies higher than the previous one.
167  * The opposite isn't done - that's auto-done using master
168  * element reading.
169  */
170
171 static guint
172 gst_ebml_read_element_level_up (GstEbmlRead * ebml)
173 {
174   guint num = 0;
175
176   guint64 pos = ebml->offset;
177
178   while (ebml->level != NULL) {
179     GstEbmlLevel *level = ebml->level->data;
180
181     if (pos >= level->start + level->length) {
182       ebml->level = g_list_delete_link (ebml->level, ebml->level);
183       gst_ebml_level_free (level);
184       num++;
185     } else {
186       break;
187     }
188   }
189
190   return num;
191 }
192
193 /*
194  * Calls pull_range for (offset,size) without advancing our offset
195  */
196 static GstFlowReturn
197 gst_ebml_read_peek_bytes (GstEbmlRead * ebml, guint size, GstBuffer ** p_buf,
198     guint8 ** bytes)
199 {
200   GstFlowReturn ret;
201
202   /* Caching here actually makes much less difference than one would expect.
203    * We do it mainly to avoid pulling buffers of 1 byte all the time */
204   if (ebml->cached_buffer) {
205     guint64 cache_offset = GST_BUFFER_OFFSET (ebml->cached_buffer);
206
207     guint cache_size = GST_BUFFER_SIZE (ebml->cached_buffer);
208
209     if (cache_offset <= ebml->offset &&
210         (ebml->offset + size) < (cache_offset + cache_size)) {
211       if (p_buf)
212         *p_buf = gst_buffer_create_sub (ebml->cached_buffer,
213             ebml->offset - cache_offset, size);
214       if (bytes)
215         *bytes =
216             GST_BUFFER_DATA (ebml->cached_buffer) + ebml->offset - cache_offset;
217       return GST_FLOW_OK;
218     }
219     /* not enough data in the cache, free cache and get a new one */
220     gst_buffer_unref (ebml->cached_buffer);
221     ebml->cached_buffer = NULL;
222   }
223
224   /* refill the cache */
225   ret = gst_pad_pull_range (ebml->sinkpad, ebml->offset, MAX (size, 64 * 1024),
226       &ebml->cached_buffer);
227   if (ret != GST_FLOW_OK) {
228     ebml->cached_buffer = NULL;
229     return ret;
230   }
231
232   if (GST_BUFFER_SIZE (ebml->cached_buffer) >= size) {
233     if (p_buf)
234       *p_buf = gst_buffer_create_sub (ebml->cached_buffer, 0, size);
235     if (bytes)
236       *bytes = GST_BUFFER_DATA (ebml->cached_buffer);
237     return GST_FLOW_OK;
238   }
239
240   /* Not possible to get enough data, try a last time with
241    * requesting exactly the size we need */
242   gst_buffer_unref (ebml->cached_buffer);
243   ebml->cached_buffer = NULL;
244
245   ret =
246       gst_pad_pull_range (ebml->sinkpad, ebml->offset, size,
247       &ebml->cached_buffer);
248   if (ret != GST_FLOW_OK) {
249     GST_DEBUG ("pull_range returned %d", ret);
250     if (p_buf)
251       *p_buf = NULL;
252     if (bytes)
253       *bytes = NULL;
254     return ret;
255   }
256
257   if (GST_BUFFER_SIZE (ebml->cached_buffer) < size) {
258     GST_WARNING_OBJECT (ebml, "Dropping short buffer at offset %"
259         G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", ebml->offset,
260         size, GST_BUFFER_SIZE (ebml->cached_buffer));
261
262     gst_buffer_unref (ebml->cached_buffer);
263     ebml->cached_buffer = NULL;
264     if (p_buf)
265       *p_buf = NULL;
266     if (bytes)
267       *bytes = NULL;
268     return GST_FLOW_ERROR;
269   }
270
271   if (p_buf)
272     *p_buf = gst_buffer_create_sub (ebml->cached_buffer, 0, size);
273   if (bytes)
274     *bytes = GST_BUFFER_DATA (*p_buf);
275
276   return GST_FLOW_OK;
277 }
278
279 /*
280  * Calls pull_range for (offset,size) and advances our offset by size
281  */
282 static GstFlowReturn
283 gst_ebml_read_pull_bytes (GstEbmlRead * ebml, guint size, GstBuffer ** p_buf,
284     guint8 ** bytes)
285 {
286   GstFlowReturn ret;
287
288   ret = gst_ebml_read_peek_bytes (ebml, size, p_buf, bytes);
289   if (ret != GST_FLOW_OK)
290     return ret;
291
292   ebml->offset += size;
293   return GST_FLOW_OK;
294 }
295
296 /*
297  * Read: the element content data ID.
298  * Return: FALSE on error.
299  */
300
301 static GstFlowReturn
302 gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
303 {
304   guint8 *buf;
305
306   gint len_mask = 0x80, read = 1, n = 1;
307
308   guint32 total;
309
310   guint8 b;
311
312   GstFlowReturn ret;
313
314   ret = gst_ebml_read_peek_bytes (ebml, 1, NULL, &buf);
315   if (ret != GST_FLOW_OK)
316     return ret;
317
318   b = GST_READ_UINT8 (buf);
319
320   total = (guint32) b;
321
322   while (read <= 4 && !(total & len_mask)) {
323     read++;
324     len_mask >>= 1;
325   }
326   if (read > 4) {
327     guint64 pos = ebml->offset;
328
329     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
330         ("Invalid EBML ID size tag (0x%x) at position %" G_GUINT64_FORMAT
331             " (0x%" G_GINT64_MODIFIER "x)", (guint) b, pos, pos));
332     return GST_FLOW_ERROR;
333   }
334
335   ret = gst_ebml_read_peek_bytes (ebml, read, NULL, &buf);
336   if (ret != GST_FLOW_OK)
337     return ret;
338
339   while (n < read) {
340     b = GST_READ_UINT8 (buf + n);
341     total = (total << 8) | b;
342     ++n;
343   }
344
345   *id = total;
346
347   /* level */
348   if (level_up)
349     *level_up = gst_ebml_read_element_level_up (ebml);
350
351   ebml->offset += read;
352   return GST_FLOW_OK;
353 }
354
355 /*
356  * Read: element content length.
357  * Return: the number of bytes read or -1 on error.
358  */
359
360 static GstFlowReturn
361 gst_ebml_read_element_length (GstEbmlRead * ebml, guint64 * length,
362     gint * rread)
363 {
364   GstFlowReturn ret;
365
366   guint8 *buf;
367
368   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
369
370   guint64 total;
371
372   guint8 b;
373
374   ret = gst_ebml_read_peek_bytes (ebml, 1, NULL, &buf);
375   if (ret != GST_FLOW_OK)
376     return ret;
377
378   b = GST_READ_UINT8 (buf);
379
380   total = (guint64) b;
381
382   while (read <= 8 && !(total & len_mask)) {
383     read++;
384     len_mask >>= 1;
385   }
386   if (read > 8) {
387     guint64 pos = ebml->offset;
388
389     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
390         ("Invalid EBML length size tag (0x%x) at position %" G_GUINT64_FORMAT
391             " (0x%" G_GINT64_MODIFIER "x)", (guint) b, pos, pos));
392     return GST_FLOW_ERROR;
393   }
394
395   if ((total &= (len_mask - 1)) == len_mask - 1)
396     num_ffs++;
397
398   ret = gst_ebml_read_peek_bytes (ebml, read, NULL, &buf);
399   if (ret != GST_FLOW_OK)
400     return ret;
401
402   while (n < read) {
403     guint8 b = GST_READ_UINT8 (buf + n);
404
405     if (b == 0xff)
406       num_ffs++;
407     total = (total << 8) | b;
408     ++n;
409   }
410
411   if (read == num_ffs)
412     *length = G_MAXUINT64;
413   else
414     *length = total;
415
416   if (rread)
417     *rread = read;
418
419   ebml->offset += read;
420
421   return GST_FLOW_OK;
422 }
423
424 /*
425  * Return: the ID of the next element.
426  * Level_up contains the amount of levels that this
427  * next element lies higher than the previous one.
428  */
429
430 GstFlowReturn
431 gst_ebml_peek_id (GstEbmlRead * ebml, guint * level_up, guint32 * id)
432 {
433   guint64 off;
434
435   guint level_up_tmp = 0;
436
437   GstFlowReturn ret;
438
439   g_assert (level_up);
440   g_assert (id);
441
442   *level_up = 0;
443
444 next:
445   off = ebml->offset;           /* save offset */
446
447   if ((ret = gst_ebml_read_element_id (ebml, id, &level_up_tmp)) != GST_FLOW_OK)
448     return ret;
449
450   ebml->offset = off;           /* restore offset */
451
452   *level_up += level_up_tmp;
453   level_up_tmp = 0;
454
455   switch (*id) {
456     case GST_EBML_ID_VOID:
457       GST_DEBUG_OBJECT (ebml, "Skipping EBML Void element");
458       if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
459         return ret;
460       goto next;
461       break;
462     case GST_EBML_ID_CRC32:
463       GST_DEBUG_OBJECT (ebml, "Skipping EBML CRC32 element");
464       if ((ret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK)
465         return ret;
466       goto next;
467       break;
468   }
469
470   return ret;
471 }
472
473 /*
474  * Return the length of the stream in bytes
475  */
476
477 gint64
478 gst_ebml_read_get_length (GstEbmlRead * ebml)
479 {
480   GstFormat fmt = GST_FORMAT_BYTES;
481
482   gint64 end;
483
484   /* FIXME: what to do if we don't get the upstream length */
485   if (!gst_pad_query_peer_duration (ebml->sinkpad, &fmt, &end) ||
486       fmt != GST_FORMAT_BYTES || end < 0)
487     g_return_val_if_reached (0);
488
489   return end;
490 }
491
492 /*
493  * Seek to a given offset.
494  */
495
496 GstFlowReturn
497 gst_ebml_read_seek (GstEbmlRead * ebml, guint64 offset)
498 {
499   if (offset >= gst_ebml_read_get_length (ebml))
500     return GST_FLOW_UNEXPECTED;
501
502   ebml->offset = offset;
503
504   return GST_FLOW_OK;
505 }
506
507 /*
508  * Skip the next element.
509  */
510
511 GstFlowReturn
512 gst_ebml_read_skip (GstEbmlRead * ebml)
513 {
514   guint64 length;
515
516   guint32 id;
517
518   GstFlowReturn ret;
519
520   ret = gst_ebml_read_element_id (ebml, &id, NULL);
521   if (ret != GST_FLOW_OK)
522     return ret;
523
524   ret = gst_ebml_read_element_length (ebml, &length, NULL);
525   if (ret != GST_FLOW_OK)
526     return ret;
527
528   ebml->offset += length;
529   return ret;
530 }
531
532 /*
533  * Read the next element as a GstBuffer (binary).
534  */
535
536 GstFlowReturn
537 gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
538 {
539   guint64 length;
540
541   GstFlowReturn ret;
542
543   ret = gst_ebml_read_element_id (ebml, id, NULL);
544   if (ret != GST_FLOW_OK)
545     return ret;
546
547   ret = gst_ebml_read_element_length (ebml, &length, NULL);
548   if (ret != GST_FLOW_OK)
549     return ret;
550
551   if (length == 0) {
552     *buf = gst_buffer_new ();
553     return GST_FLOW_OK;
554   }
555
556   *buf = NULL;
557   ret = gst_ebml_read_pull_bytes (ebml, (guint) length, buf, NULL);
558
559   return ret;
560 }
561
562 /*
563  * Read the next element, return a pointer to it and its size.
564  */
565
566 static GstFlowReturn
567 gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, guint8 ** data,
568     guint * size)
569 {
570   guint64 length;
571
572   GstFlowReturn ret;
573
574   *size = 0;
575
576   ret = gst_ebml_read_element_id (ebml, id, NULL);
577   if (ret != GST_FLOW_OK)
578     return ret;
579
580   ret = gst_ebml_read_element_length (ebml, &length, NULL);
581   if (ret != GST_FLOW_OK)
582     return ret;
583
584   if (length == 0) {
585     *data = NULL;
586     return ret;
587   }
588
589   *data = NULL;
590   ret = gst_ebml_read_pull_bytes (ebml, (guint) length, NULL, data);
591   if (ret != GST_FLOW_OK)
592     return ret;
593
594   *size = (guint) length;
595
596   return ret;
597 }
598
599 /*
600  * Read the next element as an unsigned int.
601  */
602
603 GstFlowReturn
604 gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
605 {
606   guint8 *data;
607
608   guint size;
609
610   GstFlowReturn ret;
611
612   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
613   if (ret != GST_FLOW_OK)
614     return ret;
615
616   if (size < 1 || size > 8) {
617     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
618         ("Invalid integer element size %d at position %" G_GUINT64_FORMAT
619             " (0x%" G_GINT64_MODIFIER "x)",
620             size, ebml->offset - size, ebml->offset - size));
621     return GST_FLOW_ERROR;
622   }
623   *num = 0;
624   while (size > 0) {
625     *num = (*num << 8) | *data;
626     size--;
627     data++;
628   }
629
630   return ret;
631 }
632
633 /*
634  * Read the next element as a signed int.
635  */
636
637 GstFlowReturn
638 gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
639 {
640   guint8 *data;
641
642   guint size;
643
644   gboolean negative = 0;
645
646   GstFlowReturn ret;
647
648   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
649   if (ret != GST_FLOW_OK)
650     return ret;
651
652   if (size < 1 || size > 8) {
653     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
654         ("Invalid integer element size %d at position %" G_GUINT64_FORMAT
655             " (0x%" G_GINT64_MODIFIER "x)", size, ebml->offset - size,
656             ebml->offset - size));
657     return GST_FLOW_ERROR;
658   }
659
660   *num = 0;
661   if (*data & 0x80) {
662     negative = 1;
663     *num = *data & ~0x80;
664     size--;
665     data++;
666   }
667
668   while (size > 0) {
669     *num = (*num << 8) | *data;
670     size--;
671     data++;
672   }
673
674   /* make signed */
675   if (negative) {
676     *num = 0 - *num;
677   }
678
679   return ret;
680 }
681
682 /* Convert 80 bit extended precision float in big endian format to double.
683  * Code taken from libavutil/intfloat_readwrite.c from ffmpeg,
684  * licensed under LGPL */
685
686 struct _ext_float
687 {
688   guint8 exponent[2];
689   guint8 mantissa[8];
690 };
691
692 static gdouble
693 _ext2dbl (guint8 * data)
694 {
695   struct _ext_float *ext = (struct _ext_float *) data;
696
697   guint64 m = 0;
698
699   gint e, i;
700
701   for (i = 0; i < 8; i++)
702     m = (m << 8) + ext->mantissa[i];
703   e = (((gint) ext->exponent[0] & 0x7f) << 8) | ext->exponent[1];
704   if (e == 0x7fff && m)
705     return 0.0 / 0.0;
706   e -= 16383 + 63;              /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
707                                  * mantissa bit is written as opposed to the
708                                  * single and double precision formats */
709   if (ext->exponent[0] & 0x80)
710     m = -m;
711   return ldexp (m, e);
712 }
713
714 /*
715  * Read the next element as a float.
716  */
717
718 GstFlowReturn
719 gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
720 {
721   guint8 *data;
722
723   guint size;
724
725   GstFlowReturn ret;
726
727   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
728   if (ret != GST_FLOW_OK)
729     return ret;
730
731   if (size != 4 && size != 8 && size != 10) {
732     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
733         ("Invalid float element size %d at position %" G_GUINT64_FORMAT
734             " (0x%" G_GINT64_MODIFIER "x)", size, ebml->offset - size,
735             ebml->offset - size));
736     return GST_FLOW_ERROR;
737   }
738
739   if (size == 4) {
740     gfloat f;
741
742 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
743     f = *(gfloat *) data;
744 #else
745     while (size > 0) {
746       ((guint8 *) & f)[size - 1] = data[4 - size];
747       size--;
748     }
749 #endif
750
751     *num = f;
752   } else if (size == 8) {
753     gdouble d;
754
755 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
756     d = *(gdouble *) data;
757 #else
758     while (size > 0) {
759       ((guint8 *) & d)[size - 1] = data[8 - size];
760       size--;
761     }
762 #endif
763
764     *num = d;
765   } else {
766     *num = _ext2dbl (data);
767   }
768
769   return ret;
770 }
771
772 /*
773  * Read the next element as an ASCII string.
774  */
775
776 GstFlowReturn
777 gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str)
778 {
779   guint8 *data;
780
781   guint size;
782
783   GstFlowReturn ret;
784
785   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
786   if (ret != GST_FLOW_OK)
787     return ret;
788
789   *str = g_malloc (size + 1);
790   memcpy (*str, data, size);
791   (*str)[size] = '\0';
792
793   return ret;
794 }
795
796 /*
797  * Read the next element as a UTF-8 string.
798  */
799
800 GstFlowReturn
801 gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
802 {
803   GstFlowReturn ret;
804
805 #ifndef GST_DISABLE_GST_DEBUG
806   guint64 oldoff = ebml->offset;
807 #endif
808
809   ret = gst_ebml_read_ascii (ebml, id, str);
810   if (ret != GST_FLOW_OK)
811     return ret;
812
813   if (str != NULL && *str != NULL && **str != '\0' &&
814       !g_utf8_validate (*str, -1, NULL)) {
815     GST_WARNING ("Invalid UTF-8 string at offset %" G_GUINT64_FORMAT, oldoff);
816   }
817
818   return ret;
819 }
820
821 /*
822  * Read the next element as a date.
823  * Returns the seconds since the unix epoch.
824  */
825
826 GstFlowReturn
827 gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
828 {
829   gint64 ebml_date;
830
831   GstFlowReturn ret;
832
833   ret = gst_ebml_read_sint (ebml, id, &ebml_date);
834   if (ret != GST_FLOW_OK)
835     return ret;
836
837   *date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;
838
839   return ret;
840 }
841
842 /*
843  * Read the next element, but only the header. The contents
844  * are supposed to be sub-elements which can be read separately.
845  */
846
847 GstFlowReturn
848 gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
849 {
850   GstEbmlLevel *level;
851
852   guint64 length;
853
854   GstFlowReturn ret;
855
856   ret = gst_ebml_read_element_id (ebml, id, NULL);
857   if (ret != GST_FLOW_OK)
858     return ret;
859
860   ret = gst_ebml_read_element_length (ebml, &length, NULL);
861   if (ret != GST_FLOW_OK)
862     return ret;
863
864   /* remember level */
865   level = g_slice_new (GstEbmlLevel);
866   level->start = ebml->offset;
867   level->length = length;
868   ebml->level = g_list_prepend (ebml->level, level);
869
870   return GST_FLOW_OK;
871 }
872
873 /*
874  * Read the next element as binary data.
875  */
876
877 GstFlowReturn
878 gst_ebml_read_binary (GstEbmlRead * ebml,
879     guint32 * id, guint8 ** binary, guint64 * length)
880 {
881   guint8 *data;
882
883   guint size;
884
885   GstFlowReturn ret;
886
887   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
888   if (ret != GST_FLOW_OK)
889     return ret;
890
891   *length = size;
892   *binary = g_memdup (data, size);
893
894   return GST_FLOW_OK;
895 }
896
897 /*
898  * Read an EBML header.
899  */
900
901 GstFlowReturn
902 gst_ebml_read_header (GstEbmlRead * ebml, gchar ** doctype, guint * version)
903 {
904   /* this function is the first to be called */
905   guint32 id;
906
907   guint level_up;
908
909   GstFlowReturn ret;
910
911   /* default init */
912   if (doctype)
913     *doctype = NULL;
914   if (version)
915     *version = 1;
916
917   ret = gst_ebml_peek_id (ebml, &level_up, &id);
918   if (ret != GST_FLOW_OK)
919     return ret;
920
921   GST_DEBUG_OBJECT (ebml, "id: %08x", GST_READ_UINT32_BE (&id));
922
923   if (level_up != 0 || id != GST_EBML_ID_HEADER) {
924     GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
925     return GST_FLOW_ERROR;
926   }
927   ret = gst_ebml_read_master (ebml, &id);
928   if (ret != GST_FLOW_OK)
929     return ret;
930
931   while (TRUE) {
932     ret = gst_ebml_peek_id (ebml, &level_up, &id);
933     if (ret != GST_FLOW_OK)
934       return ret;
935
936     /* end-of-header */
937     if (level_up)
938       break;
939
940     switch (id) {
941         /* is our read version uptodate? */
942       case GST_EBML_ID_EBMLREADVERSION:{
943         guint64 num;
944
945         ret = gst_ebml_read_uint (ebml, &id, &num);
946         if (ret != GST_FLOW_OK)
947           return ret;
948         g_assert (id == GST_EBML_ID_EBMLREADVERSION);
949         if (num != GST_EBML_VERSION) {
950           GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
951           return GST_FLOW_ERROR;
952         }
953         break;
954       }
955
956         /* we only handle 8 byte lengths at max */
957       case GST_EBML_ID_EBMLMAXSIZELENGTH:{
958         guint64 num;
959
960         ret = gst_ebml_read_uint (ebml, &id, &num);
961         if (ret != GST_FLOW_OK)
962           return ret;
963         g_assert (id == GST_EBML_ID_EBMLMAXSIZELENGTH);
964         if (num > sizeof (guint64)) {
965           GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
966           return GST_FLOW_ERROR;
967         }
968         break;
969       }
970
971         /* we handle 4 byte IDs at max */
972       case GST_EBML_ID_EBMLMAXIDLENGTH:{
973         guint64 num;
974
975         ret = gst_ebml_read_uint (ebml, &id, &num);
976         if (ret != GST_FLOW_OK)
977           return ret;
978         g_assert (id == GST_EBML_ID_EBMLMAXIDLENGTH);
979         if (num > sizeof (guint32)) {
980           GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
981           return GST_FLOW_ERROR;
982         }
983         break;
984       }
985
986       case GST_EBML_ID_DOCTYPE:{
987         gchar *text;
988
989         ret = gst_ebml_read_ascii (ebml, &id, &text);
990         if (ret != GST_FLOW_OK)
991           return ret;
992         g_assert (id == GST_EBML_ID_DOCTYPE);
993         if (doctype) {
994           g_free (*doctype);
995           *doctype = text;
996         } else
997           g_free (text);
998         break;
999       }
1000
1001       case GST_EBML_ID_DOCTYPEREADVERSION:{
1002         guint64 num;
1003
1004         ret = gst_ebml_read_uint (ebml, &id, &num);
1005         if (ret != GST_FLOW_OK)
1006           return ret;
1007         g_assert (id == GST_EBML_ID_DOCTYPEREADVERSION);
1008         if (version)
1009           *version = num;
1010         break;
1011       }
1012
1013       default:
1014         GST_WARNING ("Unknown data type 0x%x in EBML header (ignored)", id);
1015         /* pass-through */
1016
1017         /* we ignore these two, as they don't tell us anything we care about */
1018       case GST_EBML_ID_EBMLVERSION:
1019       case GST_EBML_ID_DOCTYPEVERSION:
1020         ret = gst_ebml_read_skip (ebml);
1021         if (ret != GST_FLOW_OK)
1022           return ret;
1023         break;
1024     }
1025   }
1026
1027   return GST_FLOW_OK;
1028 }