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