gst/matroska/: Reverse the level list as we usually are only interested in the first...
[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 static 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   GstFlowReturn ret;
436
437   g_assert (level_up);
438
439   off = ebml->offset;           /* save offset */
440
441   if ((ret = gst_ebml_read_element_id (ebml, id, level_up)) != GST_FLOW_OK)
442     return ret;
443
444   ebml->offset = off;           /* restore offset */
445   return ret;
446 }
447
448 /*
449  * Return the length of the stream in bytes
450  */
451
452 gint64
453 gst_ebml_read_get_length (GstEbmlRead * ebml)
454 {
455   GstFormat fmt = GST_FORMAT_BYTES;
456
457   gint64 end;
458
459   /* FIXME: what to do if we don't get the upstream length */
460   if (!gst_pad_query_peer_duration (ebml->sinkpad, &fmt, &end) ||
461       fmt != GST_FORMAT_BYTES || end < 0)
462     g_return_val_if_reached (0);
463
464   return end;
465 }
466
467 /*
468  * Seek to a given offset.
469  */
470
471 GstFlowReturn
472 gst_ebml_read_seek (GstEbmlRead * ebml, guint64 offset)
473 {
474   if (offset >= gst_ebml_read_get_length (ebml))
475     return GST_FLOW_UNEXPECTED;
476
477   ebml->offset = offset;
478
479   return GST_FLOW_OK;
480 }
481
482 /*
483  * Skip the next element.
484  */
485
486 GstFlowReturn
487 gst_ebml_read_skip (GstEbmlRead * ebml)
488 {
489   guint64 length;
490
491   guint32 id;
492
493   GstFlowReturn ret;
494
495   ret = gst_ebml_read_element_id (ebml, &id, NULL);
496   if (ret != GST_FLOW_OK)
497     return ret;
498
499   ret = gst_ebml_read_element_length (ebml, &length, NULL);
500   if (ret != GST_FLOW_OK)
501     return ret;
502
503   ebml->offset += length;
504   return ret;
505 }
506
507 /*
508  * Read the next element as a GstBuffer (binary).
509  */
510
511 GstFlowReturn
512 gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
513 {
514   guint64 length;
515
516   GstFlowReturn ret;
517
518   ret = gst_ebml_read_element_id (ebml, id, NULL);
519   if (ret != GST_FLOW_OK)
520     return ret;
521
522   ret = gst_ebml_read_element_length (ebml, &length, NULL);
523   if (ret != GST_FLOW_OK)
524     return ret;
525
526   if (length == 0) {
527     *buf = gst_buffer_new ();
528     return GST_FLOW_OK;
529   }
530
531   *buf = NULL;
532   ret = gst_ebml_read_pull_bytes (ebml, (guint) length, buf, NULL);
533
534   return ret;
535 }
536
537 /*
538  * Read the next element, return a pointer to it and its size.
539  */
540
541 static GstFlowReturn
542 gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, guint8 ** data,
543     guint * size)
544 {
545   guint64 length;
546
547   GstFlowReturn ret;
548
549   *size = 0;
550
551   ret = gst_ebml_read_element_id (ebml, id, NULL);
552   if (ret != GST_FLOW_OK)
553     return ret;
554
555   ret = gst_ebml_read_element_length (ebml, &length, NULL);
556   if (ret != GST_FLOW_OK)
557     return ret;
558
559   if (length == 0) {
560     *data = NULL;
561     return ret;
562   }
563
564   *data = NULL;
565   ret = gst_ebml_read_pull_bytes (ebml, (guint) length, NULL, data);
566   if (ret != GST_FLOW_OK)
567     return ret;
568
569   *size = (guint) length;
570
571   return ret;
572 }
573
574 /*
575  * Read the next element as an unsigned int.
576  */
577
578 GstFlowReturn
579 gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
580 {
581   guint8 *data;
582
583   guint size;
584
585   GstFlowReturn ret;
586
587   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
588   if (ret != GST_FLOW_OK)
589     return ret;
590
591   if (size < 1 || size > 8) {
592     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
593         ("Invalid integer element size %d at position %" G_GUINT64_FORMAT
594             " (0x%" G_GINT64_MODIFIER "x)",
595             size, ebml->offset - size, ebml->offset - size));
596     return GST_FLOW_ERROR;
597   }
598   *num = 0;
599   while (size > 0) {
600     *num = (*num << 8) | *data;
601     size--;
602     data++;
603   }
604
605   return ret;
606 }
607
608 /*
609  * Read the next element as a signed int.
610  */
611
612 GstFlowReturn
613 gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
614 {
615   guint8 *data;
616
617   guint size;
618
619   gboolean negative = 0;
620
621   GstFlowReturn ret;
622
623   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
624   if (ret != GST_FLOW_OK)
625     return ret;
626
627   if (size < 1 || size > 8) {
628     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
629         ("Invalid integer element size %d at position %" G_GUINT64_FORMAT
630             " (0x%" G_GINT64_MODIFIER "x)", size, ebml->offset - size,
631             ebml->offset - size));
632     return GST_FLOW_ERROR;
633   }
634
635   *num = 0;
636   if (*data & 0x80) {
637     negative = 1;
638     *num = *data & ~0x80;
639     size--;
640     data++;
641   }
642
643   while (size > 0) {
644     *num = (*num << 8) | *data;
645     size--;
646     data++;
647   }
648
649   /* make signed */
650   if (negative) {
651     *num = 0 - *num;
652   }
653
654   return ret;
655 }
656
657 /* Convert 80 bit extended precision float in big endian format to double.
658  * Code taken from libavutil/intfloat_readwrite.c from ffmpeg,
659  * licensed under LGPL */
660
661 struct _ext_float
662 {
663   guint8 exponent[2];
664   guint8 mantissa[8];
665 };
666
667 static gdouble
668 _ext2dbl (guint8 * data)
669 {
670   struct _ext_float *ext = (struct _ext_float *) data;
671
672   guint64 m = 0;
673
674   gint e, i;
675
676   for (i = 0; i < 8; i++)
677     m = (m << 8) + ext->mantissa[i];
678   e = (((gint) ext->exponent[0] & 0x7f) << 8) | ext->exponent[1];
679   if (e == 0x7fff && m)
680     return 0.0 / 0.0;
681   e -= 16383 + 63;              /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
682                                  * mantissa bit is written as opposed to the
683                                  * single and double precision formats */
684   if (ext->exponent[0] & 0x80)
685     m = -m;
686   return ldexp (m, e);
687 }
688
689 /*
690  * Read the next element as a float.
691  */
692
693 GstFlowReturn
694 gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
695 {
696   guint8 *data;
697
698   guint size;
699
700   GstFlowReturn ret;
701
702   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
703   if (ret != GST_FLOW_OK)
704     return ret;
705
706   if (size != 4 && size != 8 && size != 10) {
707     GST_ELEMENT_ERROR (ebml, STREAM, DEMUX, (NULL),
708         ("Invalid float element size %d at position %" G_GUINT64_FORMAT
709             " (0x%" G_GINT64_MODIFIER "x)", size, ebml->offset - size,
710             ebml->offset - size));
711     return GST_FLOW_ERROR;
712   }
713
714   if (size == 4) {
715     gfloat f;
716
717 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
718     f = *(gfloat *) data;
719 #else
720     while (size > 0) {
721       ((guint8 *) & f)[size - 1] = data[4 - size];
722       size--;
723     }
724 #endif
725
726     *num = f;
727   } else if (size == 8) {
728     gdouble d;
729
730 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
731     d = *(gdouble *) data;
732 #else
733     while (size > 0) {
734       ((guint8 *) & d)[size - 1] = data[8 - size];
735       size--;
736     }
737 #endif
738
739     *num = d;
740   } else {
741     *num = _ext2dbl (data);
742   }
743
744   return ret;
745 }
746
747 /*
748  * Read the next element as an ASCII string.
749  */
750
751 GstFlowReturn
752 gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str)
753 {
754   guint8 *data;
755
756   guint size;
757
758   GstFlowReturn ret;
759
760   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
761   if (ret != GST_FLOW_OK)
762     return ret;
763
764   *str = g_malloc (size + 1);
765   memcpy (*str, data, size);
766   (*str)[size] = '\0';
767
768   return ret;
769 }
770
771 /*
772  * Read the next element as a UTF-8 string.
773  */
774
775 GstFlowReturn
776 gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
777 {
778   GstFlowReturn ret;
779
780 #ifndef GST_DISABLE_GST_DEBUG
781   guint64 oldoff = ebml->offset;
782 #endif
783
784   ret = gst_ebml_read_ascii (ebml, id, str);
785   if (ret != GST_FLOW_OK)
786     return ret;
787
788   if (str != NULL && *str != NULL && **str != '\0' &&
789       !g_utf8_validate (*str, -1, NULL)) {
790     GST_WARNING ("Invalid UTF-8 string at offset %" G_GUINT64_FORMAT, oldoff);
791   }
792
793   return ret;
794 }
795
796 /*
797  * Read the next element as a date.
798  * Returns the seconds since the unix epoch.
799  */
800
801 GstFlowReturn
802 gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
803 {
804   gint64 ebml_date;
805
806   GstFlowReturn ret;
807
808   ret = gst_ebml_read_sint (ebml, id, &ebml_date);
809   if (ret != GST_FLOW_OK)
810     return ret;
811
812   *date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;
813
814   return ret;
815 }
816
817 /*
818  * Read the next element, but only the header. The contents
819  * are supposed to be sub-elements which can be read separately.
820  */
821
822 GstFlowReturn
823 gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
824 {
825   GstEbmlLevel *level;
826
827   guint64 length;
828
829   GstFlowReturn ret;
830
831   ret = gst_ebml_read_element_id (ebml, id, NULL);
832   if (ret != GST_FLOW_OK)
833     return ret;
834
835   ret = gst_ebml_read_element_length (ebml, &length, NULL);
836   if (ret != GST_FLOW_OK)
837     return ret;
838
839   /* remember level */
840   level = g_slice_new (GstEbmlLevel);
841   level->start = ebml->offset;
842   level->length = length;
843   ebml->level = g_list_prepend (ebml->level, level);
844
845   return GST_FLOW_OK;
846 }
847
848 /*
849  * Read the next element as binary data.
850  */
851
852 GstFlowReturn
853 gst_ebml_read_binary (GstEbmlRead * ebml,
854     guint32 * id, guint8 ** binary, guint64 * length)
855 {
856   guint8 *data;
857
858   guint size;
859
860   GstFlowReturn ret;
861
862   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
863   if (ret != GST_FLOW_OK)
864     return ret;
865
866   *length = size;
867   *binary = g_memdup (data, size);
868
869   return GST_FLOW_OK;
870 }
871
872 /*
873  * Read an EBML header.
874  */
875
876 GstFlowReturn
877 gst_ebml_read_header (GstEbmlRead * ebml, gchar ** doctype, guint * version)
878 {
879   /* this function is the first to be called */
880   guint32 id;
881
882   guint level_up;
883
884   GstFlowReturn ret;
885
886   /* default init */
887   if (doctype)
888     *doctype = NULL;
889   if (version)
890     *version = 1;
891
892   ret = gst_ebml_peek_id (ebml, &level_up, &id);
893   if (ret != GST_FLOW_OK)
894     return ret;
895
896   GST_DEBUG_OBJECT (ebml, "id: %08x", GST_READ_UINT32_BE (&id));
897
898   if (level_up != 0 || id != GST_EBML_ID_HEADER) {
899     GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
900     return GST_FLOW_ERROR;
901   }
902   ret = gst_ebml_read_master (ebml, &id);
903   if (ret != GST_FLOW_OK)
904     return ret;
905
906   while (TRUE) {
907     ret = gst_ebml_peek_id (ebml, &level_up, &id);
908     if (ret != GST_FLOW_OK)
909       return ret;
910
911     /* end-of-header */
912     if (level_up)
913       break;
914
915     switch (id) {
916         /* is our read version uptodate? */
917       case GST_EBML_ID_EBMLREADVERSION:{
918         guint64 num;
919
920         ret = gst_ebml_read_uint (ebml, &id, &num);
921         if (ret != GST_FLOW_OK)
922           return ret;
923         g_assert (id == GST_EBML_ID_EBMLREADVERSION);
924         if (num != GST_EBML_VERSION) {
925           GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
926           return GST_FLOW_ERROR;
927         }
928         break;
929       }
930
931         /* we only handle 8 byte lengths at max */
932       case GST_EBML_ID_EBMLMAXSIZELENGTH:{
933         guint64 num;
934
935         ret = gst_ebml_read_uint (ebml, &id, &num);
936         if (ret != GST_FLOW_OK)
937           return ret;
938         g_assert (id == GST_EBML_ID_EBMLMAXSIZELENGTH);
939         if (num > sizeof (guint64)) {
940           GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
941           return GST_FLOW_ERROR;
942         }
943         break;
944       }
945
946         /* we handle 4 byte IDs at max */
947       case GST_EBML_ID_EBMLMAXIDLENGTH:{
948         guint64 num;
949
950         ret = gst_ebml_read_uint (ebml, &id, &num);
951         if (ret != GST_FLOW_OK)
952           return ret;
953         g_assert (id == GST_EBML_ID_EBMLMAXIDLENGTH);
954         if (num > sizeof (guint32)) {
955           GST_ELEMENT_ERROR (ebml, STREAM, WRONG_TYPE, (NULL), (NULL));
956           return GST_FLOW_ERROR;
957         }
958         break;
959       }
960
961       case GST_EBML_ID_DOCTYPE:{
962         gchar *text;
963
964         ret = gst_ebml_read_ascii (ebml, &id, &text);
965         if (ret != GST_FLOW_OK)
966           return ret;
967         g_assert (id == GST_EBML_ID_DOCTYPE);
968         if (doctype) {
969           g_free (*doctype);
970           *doctype = text;
971         } else
972           g_free (text);
973         break;
974       }
975
976       case GST_EBML_ID_DOCTYPEREADVERSION:{
977         guint64 num;
978
979         ret = gst_ebml_read_uint (ebml, &id, &num);
980         if (ret != GST_FLOW_OK)
981           return ret;
982         g_assert (id == GST_EBML_ID_DOCTYPEREADVERSION);
983         if (version)
984           *version = num;
985         break;
986       }
987
988       default:
989         GST_WARNING ("Unknown data type 0x%x in EBML header (ignored)", id);
990         /* pass-through */
991
992         /* we ignore these two, as they don't tell us anything we care about */
993       case GST_EBML_ID_VOID:
994       case GST_EBML_ID_EBMLVERSION:
995       case GST_EBML_ID_DOCTYPEVERSION:
996         ret = gst_ebml_read_skip (ebml);
997         if (ret != GST_FLOW_OK)
998           return ret;
999         break;
1000     }
1001   }
1002
1003   return GST_FLOW_OK;
1004 }