matroskademux: configurable timestamp gap handling
[platform/upstream/gstreamer.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 /* NAN is supposed to be in math.h, Microsoft defines it in xmath.h */
34 #ifdef _MSC_VER
35 #include <xmath.h>
36 #endif
37
38 /* If everything goes wrong try 0.0/0.0 which should be NAN */
39 #ifndef NAN
40 #define NAN (0.0 / 0.0)
41 #endif
42
43 GST_DEBUG_CATEGORY (ebmlread_debug);
44 #define GST_CAT_DEFAULT ebmlread_debug
45
46 /* Peeks following element id and element length in datastream provided
47  * by @peek with @ctx as user data.
48  * Returns GST_FLOW_UNEXPECTED if not enough data to read id and length.
49  * Otherwise, @needed provides the prefix length (id + length), and
50  * @length provides element length.
51  *
52  * @object and @offset are provided for informative messaging/debug purposes.
53  */
54 GstFlowReturn
55 gst_ebml_peek_id_length (guint32 * _id, guint64 * _length, guint * _needed,
56     GstPeekData peek, gpointer * ctx, GstElement * el, guint64 offset)
57 {
58   guint needed;
59   const guint8 *buf;
60   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
61   guint64 total;
62   guint8 b;
63
64   g_return_val_if_fail (_id != NULL, GST_FLOW_ERROR);
65   g_return_val_if_fail (_length != NULL, GST_FLOW_ERROR);
66   g_return_val_if_fail (_needed != NULL, GST_FLOW_ERROR);
67
68   /* well ... */
69   *_id = (guint32) GST_EBML_SIZE_UNKNOWN;
70   *_length = GST_EBML_SIZE_UNKNOWN;
71
72   /* read element id */
73   needed = 2;
74   buf = peek (ctx, needed);
75   if (!buf)
76     goto not_enough_data;
77
78   b = GST_READ_UINT8 (buf);
79   total = (guint64) b;
80   while (read <= 4 && !(total & len_mask)) {
81     read++;
82     len_mask >>= 1;
83   }
84   if (G_UNLIKELY (read > 4))
85     goto invalid_id;
86
87   /* need id and at least something for subsequent length */
88   needed = read + 1;
89   buf = peek (ctx, needed);
90   if (!buf)
91     goto not_enough_data;
92
93   while (n < read) {
94     b = GST_READ_UINT8 (buf + n);
95     total = (total << 8) | b;
96     ++n;
97   }
98   *_id = (guint32) total;
99
100   /* read element length */
101   b = GST_READ_UINT8 (buf + n);
102   total = (guint64) b;
103   len_mask = 0x80;
104   read = 1;
105   while (read <= 8 && !(total & len_mask)) {
106     read++;
107     len_mask >>= 1;
108   }
109   if (G_UNLIKELY (read > 8))
110     goto invalid_length;
111   if ((total &= (len_mask - 1)) == len_mask - 1)
112     num_ffs++;
113
114   needed += read - 1;
115   buf = peek (ctx, needed);
116   if (!buf)
117     goto not_enough_data;
118
119   buf += (needed - read);
120   n = 1;
121   while (n < read) {
122     guint8 b = GST_READ_UINT8 (buf + n);
123
124     if (G_UNLIKELY (b == 0xff))
125       num_ffs++;
126     total = (total << 8) | b;
127     ++n;
128   }
129
130   if (G_UNLIKELY (read == num_ffs))
131     *_length = G_MAXUINT64;
132   else
133     *_length = total;
134
135   *_needed = needed;
136
137   return GST_FLOW_OK;
138
139   /* ERRORS */
140 not_enough_data:
141   {
142     *_needed = needed;
143     return GST_FLOW_UNEXPECTED;
144   }
145 invalid_id:
146   {
147     GST_ERROR_OBJECT (el,
148         "Invalid EBML ID size tag (0x%x) at position %" G_GUINT64_FORMAT " (0x%"
149         G_GINT64_MODIFIER "x)", (guint) b, offset, offset);
150     return GST_FLOW_ERROR;
151   }
152 invalid_length:
153   {
154     GST_ERROR_OBJECT (el,
155         "Invalid EBML length size tag (0x%x) at position %" G_GUINT64_FORMAT
156         " (0x%" G_GINT64_MODIFIER "x)", (guint) b, offset, offset);
157     return GST_FLOW_ERROR;
158   }
159 }
160
161 /* setup for parsing @buf at position @offset on behalf of @el.
162  * Takes ownership of @buf. */
163 void
164 gst_ebml_read_init (GstEbmlRead * ebml, GstElement * el, GstBuffer * buf,
165     guint64 offset)
166 {
167   GstEbmlMaster m;
168
169   g_return_if_fail (el);
170   g_return_if_fail (buf);
171
172   ebml->el = el;
173   ebml->offset = offset;
174   ebml->buf = buf;
175   ebml->readers = g_array_sized_new (FALSE, FALSE, sizeof (GstEbmlMaster), 10);
176   m.offset = ebml->offset;
177   gst_byte_reader_init (&m.br, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
178   g_array_append_val (ebml->readers, m);
179 }
180
181 void
182 gst_ebml_read_clear (GstEbmlRead * ebml)
183 {
184   if (ebml->readers)
185     g_array_free (ebml->readers, TRUE);
186   ebml->readers = NULL;
187   if (ebml->buf)
188     gst_buffer_unref (ebml->buf);
189   ebml->buf = NULL;
190   ebml->el = NULL;
191 }
192
193 static const guint8 *
194 gst_ebml_read_peek (GstByteReader * br, guint peek)
195 {
196   const guint8 *data = NULL;
197
198   if (G_LIKELY (gst_byte_reader_peek_data (br, peek, &data)))
199     return data;
200   else
201     return NULL;
202 }
203
204 static GstFlowReturn
205 gst_ebml_peek_id_full (GstEbmlRead * ebml, guint32 * id, guint64 * length,
206     guint * prefix)
207 {
208   GstFlowReturn ret;
209
210   ret = gst_ebml_peek_id_length (id, length, prefix,
211       (GstPeekData) gst_ebml_read_peek, (gpointer) gst_ebml_read_br (ebml),
212       ebml->el, gst_ebml_read_get_pos (ebml));
213   if (ret != GST_FLOW_OK)
214     return ret;
215
216   GST_LOG_OBJECT (ebml->el, "id 0x%x at offset 0x%" G_GINT64_MODIFIER "x"
217       " of length %" G_GUINT64_FORMAT ", prefix %d", *id,
218       gst_ebml_read_get_pos (ebml), *length, *prefix);
219
220 #ifndef GST_DISABLE_GST_DEBUG
221   {
222     const guint8 *data = NULL;
223     GstByteReader *br = gst_ebml_read_br (ebml);
224     guint size = gst_byte_reader_get_remaining (br);
225
226     gst_byte_reader_peek_data (br, size, &data);
227
228     GST_LOG_OBJECT (ebml->el, "current br %p; remaining %d", br, size);
229     if (data)
230       GST_MEMDUMP_OBJECT (ebml->el, "element", data, MIN (size, *length));
231   }
232 #endif
233
234   return ret;
235 }
236
237 GstFlowReturn
238 gst_ebml_peek_id (GstEbmlRead * ebml, guint32 * id)
239 {
240   guint64 length;
241   guint needed;
242
243   return gst_ebml_peek_id_full (ebml, id, &length, &needed);
244 }
245
246 /*
247  * Read the next element, the contents are supposed to be sub-elements which
248  * can be read separately.  A new bytereader is setup for doing so.
249  */
250 GstFlowReturn
251 gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
252 {
253   guint64 length;
254   guint prefix;
255   const guint8 *data = NULL;
256   GstFlowReturn ret;
257   GstEbmlMaster m;
258
259   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
260   if (ret != GST_FLOW_OK)
261     return ret;
262
263   /* we just at least peeked the id */
264   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
265     return GST_FLOW_ERROR;      /* FIXME: do proper error handling */
266
267   m.offset = gst_ebml_read_get_pos (ebml);
268   if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, &data))
269     return GST_FLOW_PARSE;
270
271   GST_LOG_OBJECT (ebml->el, "pushing level %d at offset %" G_GUINT64_FORMAT,
272       ebml->readers->len, m.offset);
273   gst_byte_reader_init (&m.br, data, length);
274   g_array_append_val (ebml->readers, m);
275
276   return GST_FLOW_OK;
277 }
278
279 /* explicitly pop a bytereader from stack.  Usually invoked automagically. */
280 GstFlowReturn
281 gst_ebml_read_pop_master (GstEbmlRead * ebml)
282 {
283   g_return_val_if_fail (ebml->readers, GST_FLOW_ERROR);
284
285   /* never remove initial bytereader */
286   if (ebml->readers->len > 1) {
287     GST_LOG_OBJECT (ebml->el, "popping level %d", ebml->readers->len - 1);
288     g_array_remove_index (ebml->readers, ebml->readers->len - 1);
289   }
290
291   return GST_FLOW_OK;
292 }
293
294 /*
295  * Skip the next element.
296  */
297
298 GstFlowReturn
299 gst_ebml_read_skip (GstEbmlRead * ebml)
300 {
301   guint64 length;
302   guint32 id;
303   guint prefix;
304   GstFlowReturn ret;
305
306   ret = gst_ebml_peek_id_full (ebml, &id, &length, &prefix);
307   if (ret != GST_FLOW_OK)
308     return ret;
309
310   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), length + prefix))
311     return GST_FLOW_PARSE;
312
313   return ret;
314 }
315
316 /*
317  * Read the next element as a GstBuffer (binary).
318  */
319
320 GstFlowReturn
321 gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
322 {
323   guint64 length;
324   guint prefix;
325   GstFlowReturn ret;
326
327   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
328   if (ret != GST_FLOW_OK)
329     return ret;
330
331   /* we just at least peeked the id */
332   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
333     return GST_FLOW_ERROR;      /* FIXME: do proper error handling */
334
335   if (G_LIKELY (length > 0)) {
336     guint offset;
337
338     offset = gst_ebml_read_get_pos (ebml) - ebml->offset;
339     if (G_LIKELY (gst_byte_reader_skip (gst_ebml_read_br (ebml), length))) {
340       *buf = gst_buffer_create_sub (ebml->buf, offset, length);
341     } else {
342       *buf = NULL;
343       return GST_FLOW_PARSE;
344     }
345   } else {
346     *buf = gst_buffer_new ();
347   }
348
349   return ret;
350 }
351
352 /*
353  * Read the next element, return a pointer to it and its size.
354  */
355
356 static GstFlowReturn
357 gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, const guint8 ** data,
358     guint * size)
359 {
360   guint64 length;
361   guint prefix;
362   GstFlowReturn ret;
363
364   *size = 0;
365
366   ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
367   if (ret != GST_FLOW_OK)
368     return ret;
369
370   /* we just at least peeked the id */
371   if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
372     return GST_FLOW_ERROR;      /* FIXME: do proper error handling */
373
374   *data = NULL;
375   if (G_LIKELY (length >= 0)) {
376     if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, data))
377       return GST_FLOW_PARSE;
378   }
379
380   *size = length;
381
382   return ret;
383 }
384
385 /*
386  * Read the next element as an unsigned int.
387  */
388
389 GstFlowReturn
390 gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
391 {
392   const guint8 *data;
393   guint size;
394   GstFlowReturn ret;
395
396   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
397   if (ret != GST_FLOW_OK)
398     return ret;
399
400   if (size > 8) {
401     GST_ERROR_OBJECT (ebml->el,
402         "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
403         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
404         gst_ebml_read_get_pos (ebml) - size);
405     return GST_FLOW_ERROR;
406   }
407
408   if (size == 0) {
409     *num = 0;
410     return ret;
411   }
412
413   *num = 0;
414   while (size > 0) {
415     *num = (*num << 8) | *data;
416     size--;
417     data++;
418   }
419
420   return ret;
421 }
422
423 /*
424  * Read the next element as a signed int.
425  */
426
427 GstFlowReturn
428 gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
429 {
430   const guint8 *data;
431   guint size;
432   gboolean negative = 0;
433   GstFlowReturn ret;
434
435   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
436   if (ret != GST_FLOW_OK)
437     return ret;
438
439   if (size > 8) {
440     GST_ERROR_OBJECT (ebml->el,
441         "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
442         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
443         gst_ebml_read_get_pos (ebml) - size);
444     return GST_FLOW_ERROR;
445   }
446
447   if (size == 0) {
448     *num = 0;
449     return ret;
450   }
451
452   *num = 0;
453   if (*data & 0x80) {
454     negative = 1;
455     *num = *data & ~0x80;
456     size--;
457     data++;
458   }
459
460   while (size > 0) {
461     *num = (*num << 8) | *data;
462     size--;
463     data++;
464   }
465
466   /* make signed */
467   if (negative) {
468     *num = 0 - *num;
469   }
470
471   return ret;
472 }
473
474 /* Convert 80 bit extended precision float in big endian format to double.
475  * Code taken from libavutil/intfloat_readwrite.c from ffmpeg,
476  * licensed under LGPL */
477
478 struct _ext_float
479 {
480   guint8 exponent[2];
481   guint8 mantissa[8];
482 };
483
484 static gdouble
485 _ext2dbl (const guint8 * data)
486 {
487   struct _ext_float ext;
488   guint64 m = 0;
489   gint e, i;
490
491   memcpy (&ext.exponent, data, 2);
492   memcpy (&ext.mantissa, data + 2, 8);
493
494   for (i = 0; i < 8; i++)
495     m = (m << 8) + ext.mantissa[i];
496   e = (((gint) ext.exponent[0] & 0x7f) << 8) | ext.exponent[1];
497   if (e == 0x7fff && m)
498     return NAN;
499   e -= 16383 + 63;              /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
500                                  * mantissa bit is written as opposed to the
501                                  * single and double precision formats */
502   if (ext.exponent[0] & 0x80)
503     m = -m;
504   return ldexp (m, e);
505 }
506
507 /*
508  * Read the next element as a float.
509  */
510
511 GstFlowReturn
512 gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
513 {
514   const guint8 *data;
515   guint size;
516   GstFlowReturn ret;
517
518   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
519   if (ret != GST_FLOW_OK)
520     return ret;
521
522   if (size != 0 && size != 4 && size != 8 && size != 10) {
523     GST_ERROR_OBJECT (ebml->el,
524         "Invalid float element size %d at position %" G_GUINT64_FORMAT " (0x%"
525         G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
526         gst_ebml_read_get_pos (ebml) - size);
527     return GST_FLOW_ERROR;
528   }
529
530   if (size == 4) {
531     gfloat f;
532
533     memcpy (&f, data, 4);
534     f = GFLOAT_FROM_BE (f);
535
536     *num = f;
537   } else if (size == 8) {
538     gdouble d;
539
540     memcpy (&d, data, 8);
541     d = GDOUBLE_FROM_BE (d);
542
543     *num = d;
544   } else if (size == 10) {
545     *num = _ext2dbl (data);
546   } else {
547     /* size == 0 means a value of 0.0 */
548     *num = 0.0;
549   }
550
551   return ret;
552 }
553
554 /*
555  * Read the next element as a C string.
556  */
557
558 static GstFlowReturn
559 gst_ebml_read_string (GstEbmlRead * ebml, guint32 * id, gchar ** str)
560 {
561   const guint8 *data;
562   guint size;
563   GstFlowReturn ret;
564
565   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
566   if (ret != GST_FLOW_OK)
567     return ret;
568
569   *str = g_malloc (size + 1);
570   memcpy (*str, data, size);
571   (*str)[size] = '\0';
572
573   return ret;
574 }
575
576 /*
577  * Read the next element as an ASCII string.
578  */
579
580 GstFlowReturn
581 gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str_out)
582 {
583   GstFlowReturn ret;
584   gchar *str;
585   gchar *iter;
586
587 #ifndef GST_DISABLE_GST_DEBUG
588   guint64 oldoff = ebml->offset;
589 #endif
590
591   ret = gst_ebml_read_string (ebml, id, &str);
592   if (ret != GST_FLOW_OK)
593     return ret;
594
595   for (iter = str; *iter != '\0'; iter++) {
596     if (G_UNLIKELY (*iter & 0x80)) {
597       GST_ERROR_OBJECT (ebml,
598           "Invalid ASCII string at offset %" G_GUINT64_FORMAT, oldoff);
599       g_free (str);
600       return GST_FLOW_ERROR;
601     }
602   }
603
604   *str_out = str;
605   return ret;
606 }
607
608 /*
609  * Read the next element as a UTF-8 string.
610  */
611
612 GstFlowReturn
613 gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
614 {
615   GstFlowReturn ret;
616
617 #ifndef GST_DISABLE_GST_DEBUG
618   guint64 oldoff = gst_ebml_read_get_pos (ebml);
619 #endif
620
621   ret = gst_ebml_read_string (ebml, id, str);
622   if (ret != GST_FLOW_OK)
623     return ret;
624
625   if (str != NULL && *str != NULL && **str != '\0' &&
626       !g_utf8_validate (*str, -1, NULL)) {
627     GST_WARNING_OBJECT (ebml->el,
628         "Invalid UTF-8 string at offset %" G_GUINT64_FORMAT, oldoff);
629   }
630
631   return ret;
632 }
633
634 /*
635  * Read the next element as a date.
636  * Returns the seconds since the unix epoch.
637  */
638
639 GstFlowReturn
640 gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
641 {
642   gint64 ebml_date;
643   GstFlowReturn ret;
644
645   ret = gst_ebml_read_sint (ebml, id, &ebml_date);
646   if (ret != GST_FLOW_OK)
647     return ret;
648
649   *date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;
650
651   return ret;
652 }
653
654 /*
655  * Read the next element as binary data.
656  */
657
658 GstFlowReturn
659 gst_ebml_read_binary (GstEbmlRead * ebml,
660     guint32 * id, guint8 ** binary, guint64 * length)
661 {
662   const guint8 *data;
663   guint size;
664   GstFlowReturn ret;
665
666   ret = gst_ebml_read_bytes (ebml, id, &data, &size);
667   if (ret != GST_FLOW_OK)
668     return ret;
669
670   *length = size;
671   *binary = g_memdup (data, size);
672
673   return GST_FLOW_OK;
674 }