rtph264depay: Fix handling or marker on STAP-A
[platform/upstream/gst-plugins-good.git] / gst / matroska / matroska-read-common.c
1 /* GStreamer Matroska muxer/demuxer
2  * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  * (c) 2006 Tim-Philipp Müller <tim centricular net>
4  * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5  * (c) 2011 Debarshi Ray <rishi@gnu.org>
6  *
7  * matroska-read-common.c: shared by matroska file/stream demuxer and parser
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <string.h>
31
32 #ifdef HAVE_ZLIB
33 #include <zlib.h>
34 #endif
35
36 #ifdef HAVE_BZ2
37 #include <bzlib.h>
38 #endif
39
40 #include <gst/tag/tag.h>
41 #include <gst/base/gsttypefindhelper.h>
42 #include <gst/base/gstbytewriter.h>
43
44 #include "lzo.h"
45
46 #include "ebml-read.h"
47 #include "matroska-read-common.h"
48 #include "matroska-ids.h"
49
50 GST_DEBUG_CATEGORY (matroskareadcommon_debug);
51 #define GST_CAT_DEFAULT matroskareadcommon_debug
52
53 #define DEBUG_ELEMENT_START(common, ebml, element) \
54     GST_DEBUG_OBJECT (common->sinkpad, "Parsing " element " element at offset %" \
55         G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
56
57 #define DEBUG_ELEMENT_STOP(common, ebml, element, ret) \
58     GST_DEBUG_OBJECT (common->sinkpad, "Parsing " element " element " \
59         " finished with '%s'", gst_flow_get_name (ret))
60
61 #define GST_MATROSKA_TOC_UID_CHAPTER "chapter"
62 #define GST_MATROSKA_TOC_UID_EDITION "edition"
63 #define GST_MATROSKA_TOC_UID_EMPTY "empty"
64
65 typedef struct
66 {
67   GstTagList *result;
68   guint64 target_type_value;
69   gchar *target_type;
70   gboolean audio_only;
71 } TargetTypeContext;
72
73
74 static gboolean
75 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
76     gpointer * data_out, gsize * size_out,
77     GstMatroskaTrackCompressionAlgorithm algo)
78 {
79   guint8 *new_data = NULL;
80   guint new_size = 0;
81   guint8 *data = *data_out;
82   guint size = *size_out;
83   gboolean ret = TRUE;
84
85   if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
86 #ifdef HAVE_ZLIB
87     /* zlib encoded data */
88     z_stream zstream;
89     guint orig_size;
90     int result;
91
92     orig_size = size;
93     zstream.zalloc = (alloc_func) 0;
94     zstream.zfree = (free_func) 0;
95     zstream.opaque = (voidpf) 0;
96     if (inflateInit (&zstream) != Z_OK) {
97       GST_WARNING ("zlib initialization failed.");
98       ret = FALSE;
99       goto out;
100     }
101     zstream.next_in = (Bytef *) data;
102     zstream.avail_in = orig_size;
103     new_size = orig_size;
104     new_data = g_malloc (new_size);
105     zstream.avail_out = new_size;
106     zstream.next_out = (Bytef *) new_data;
107
108     do {
109       result = inflate (&zstream, Z_NO_FLUSH);
110       if (result == Z_STREAM_END) {
111         break;
112       } else if (result != Z_OK) {
113         GST_WARNING ("inflate() returned %d", result);
114         break;
115       }
116
117       new_size += 4096;
118       new_data = g_realloc (new_data, new_size);
119       zstream.next_out = (Bytef *) (new_data + zstream.total_out);
120       zstream.avail_out += 4096;
121     } while (zstream.avail_in > 0);
122
123     if (result != Z_STREAM_END) {
124       ret = FALSE;
125       g_free (new_data);
126     } else {
127       new_size = zstream.total_out;
128     }
129     inflateEnd (&zstream);
130
131 #else
132     GST_WARNING ("zlib encoded tracks not supported.");
133     ret = FALSE;
134     goto out;
135 #endif
136   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
137 #ifdef HAVE_BZ2
138     /* bzip2 encoded data */
139     bz_stream bzstream;
140     guint orig_size;
141     int result;
142
143     bzstream.bzalloc = NULL;
144     bzstream.bzfree = NULL;
145     bzstream.opaque = NULL;
146     orig_size = size;
147
148     if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
149       GST_WARNING ("bzip2 initialization failed.");
150       ret = FALSE;
151       goto out;
152     }
153
154     bzstream.next_in = (char *) data;
155     bzstream.avail_in = orig_size;
156     new_size = orig_size;
157     new_data = g_malloc (new_size);
158     bzstream.avail_out = new_size;
159     bzstream.next_out = (char *) new_data;
160
161     do {
162       result = BZ2_bzDecompress (&bzstream);
163       if (result == BZ_STREAM_END) {
164         break;
165       } else if (result != BZ_OK) {
166         GST_WARNING ("BZ2_bzDecompress() returned %d", result);
167         break;
168       }
169
170       new_size += 4096;
171       new_data = g_realloc (new_data, new_size);
172       bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
173       bzstream.avail_out += 4096;
174     } while (bzstream.avail_in > 0);
175
176     if (result != BZ_STREAM_END) {
177       ret = FALSE;
178       g_free (new_data);
179     } else {
180       new_size = bzstream.total_out_lo32;
181     }
182     BZ2_bzDecompressEnd (&bzstream);
183
184 #else
185     GST_WARNING ("bzip2 encoded tracks not supported.");
186     ret = FALSE;
187     goto out;
188 #endif
189   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
190     /* lzo encoded data */
191     int result;
192     int orig_size, out_size;
193
194     orig_size = size;
195     out_size = size;
196     new_size = size;
197     new_data = g_malloc (new_size);
198
199     do {
200       orig_size = size;
201       out_size = new_size;
202
203       result = lzo1x_decode (new_data, &out_size, data, &orig_size);
204
205       if (orig_size > 0) {
206         new_size += 4096;
207         new_data = g_realloc (new_data, new_size);
208       }
209     } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
210
211     new_size -= out_size;
212
213     if (result != LZO_OUTPUT_FULL) {
214       GST_WARNING ("lzo decompression failed");
215       g_free (new_data);
216
217       ret = FALSE;
218       goto out;
219     }
220
221   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
222     /* header stripped encoded data */
223     if (enc->comp_settings_length > 0) {
224       new_data = g_malloc (size + enc->comp_settings_length);
225       new_size = size + enc->comp_settings_length;
226
227       memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
228       memcpy (new_data + enc->comp_settings_length, data, size);
229     }
230   } else {
231     GST_ERROR ("invalid compression algorithm %d", algo);
232     ret = FALSE;
233   }
234
235 out:
236
237   if (!ret) {
238     *data_out = NULL;
239     *size_out = 0;
240   } else {
241     *data_out = new_data;
242     *size_out = new_size;
243   }
244
245   return ret;
246 }
247
248 GstFlowReturn
249 gst_matroska_decode_content_encodings (GArray * encodings)
250 {
251   gint i;
252
253   if (encodings == NULL)
254     return GST_FLOW_OK;
255
256   for (i = 0; i < encodings->len; i++) {
257     GstMatroskaTrackEncoding *enc =
258         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
259     gpointer data = NULL;
260     gsize size;
261
262     if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
263         == 0)
264       continue;
265
266     /* Other than ENCODING_COMPRESSION not handled here */
267     if (enc->type != GST_MATROSKA_ENCODING_COMPRESSION)
268       continue;
269
270     if (i + 1 >= encodings->len)
271       return GST_FLOW_ERROR;
272
273     if (enc->comp_settings_length == 0)
274       continue;
275
276     data = enc->comp_settings;
277     size = enc->comp_settings_length;
278
279     if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
280       return GST_FLOW_ERROR;
281
282     g_free (enc->comp_settings);
283
284     enc->comp_settings = data;
285     enc->comp_settings_length = size;
286   }
287
288   return GST_FLOW_OK;
289 }
290
291 gboolean
292 gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
293     gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
294 {
295   gpointer data;
296   gsize size;
297   gboolean ret = TRUE;
298   gint i;
299
300   g_return_val_if_fail (encodings != NULL, FALSE);
301   g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
302   g_return_val_if_fail (size_out != NULL, FALSE);
303
304   data = *data_out;
305   size = *size_out;
306
307   for (i = 0; i < encodings->len; i++) {
308     GstMatroskaTrackEncoding *enc =
309         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
310     gpointer new_data = NULL;
311     gsize new_size = 0;
312
313     if ((enc->scope & scope) == 0)
314       continue;
315
316     /* Encryption not handled here */
317     if (enc->type != GST_MATROSKA_ENCODING_COMPRESSION) {
318       ret = TRUE;
319       break;
320     }
321
322     new_data = data;
323     new_size = size;
324
325     ret =
326         gst_matroska_decompress_data (enc, &new_data, &new_size,
327         enc->comp_algo);
328
329     if (!ret)
330       break;
331
332     if ((data == *data_out && free) || (data != *data_out))
333       g_free (data);
334
335     data = new_data;
336     size = new_size;
337   }
338
339   if (!ret) {
340     if ((data == *data_out && free) || (data != *data_out))
341       g_free (data);
342
343     *data_out = NULL;
344     *size_out = 0;
345   } else {
346     *data_out = data;
347     *size_out = size;
348   }
349
350   return ret;
351 }
352
353 /* This function parses the protection info of Block/SimpleBlock and extracts the
354  * IV and partitioning format (subsample) information.
355  * Set those parsed information into protection info structure @info_protect which
356  * will be added in protection metadata of the Gstbuffer.
357  * The subsamples format follows the same pssh box format in Common Encryption spec:
358  * subsample number + clear subsample size (16bit bigendian) | encrypted subsample size (32bit bigendian) | ...
359  * @encrypted is an output argument: TRUE if the current Block/SimpleBlock is encrypted else FALSE
360  */
361 gboolean
362 gst_matroska_parse_protection_meta (gpointer * data_out, gsize * size_out,
363     GstStructure * info_protect, gboolean * encrypted)
364 {
365   guint8 *data;
366   GstBuffer *buf_iv;
367   guint8 *data_iv;
368   guint8 *subsamples;
369   guint8 signal_byte;
370   gint i;
371   GstByteReader reader;
372
373   g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
374   g_return_val_if_fail (size_out != NULL, FALSE);
375   g_return_val_if_fail (info_protect != NULL, FALSE);
376   g_return_val_if_fail (encrypted != NULL, FALSE);
377
378   *encrypted = FALSE;
379   data = *data_out;
380   gst_byte_reader_init (&reader, data, *size_out);
381
382   /* WebM spec:
383    * 4.7 Signal Byte Format
384    *  0 1 2 3 4 5 6 7
385    * +-+-+-+-+-+-+-+-+
386    * |X|   RSV   |P|E|
387    * +-+-+-+-+-+-+-+-+
388    *
389    * Extension bit (X)
390    * If set, another signal byte will follow this byte. Reserved for future expansion (currently MUST be set to 0).
391    * RSV bits (RSV)
392    * Bits reserved for future use. MUST be set to 0 and MUST be ignored.
393    * Encrypted bit (E)
394    * If set, the Block MUST contain an IV immediately followed by an encrypted frame. If not set, the Block MUST NOT include an IV and the frame MUST be unencrypted. The unencrypted frame MUST immediately follow the Signal Byte.
395    * Partitioned bit (P)
396    * Used to indicate that the sample has subsample partitions. If set, the IV will be followed by a num_partitions byte, and num_partitions * 32-bit partition offsets. This bit can only be set if the E bit is also set.
397    */
398   if (!gst_byte_reader_get_uint8 (&reader, &signal_byte)) {
399     GST_ERROR ("Error reading the signal byte");
400     return FALSE;
401   }
402
403   /* Unencrypted buffer */
404   if (!(signal_byte & GST_MATROSKA_BLOCK_ENCRYPTED)) {
405     return TRUE;
406   }
407
408   /* Encrypted buffer */
409   *encrypted = TRUE;
410   /* Create IV buffer */
411   if (!gst_byte_reader_dup_data (&reader, sizeof (guint64), &data_iv)) {
412     GST_ERROR ("Error reading the IV data");
413     return FALSE;
414   }
415   buf_iv = gst_buffer_new_wrapped ((gpointer) data_iv, sizeof (guint64));
416   gst_structure_set (info_protect, "iv", GST_TYPE_BUFFER, buf_iv, NULL);
417   gst_buffer_unref (buf_iv);
418
419   /* Partitioned in subsample */
420   if (signal_byte & GST_MATROSKA_BLOCK_PARTITIONED) {
421     guint nb_subsample;
422     guint32 offset = 0;
423     guint32 offset_prev;
424     guint32 encrypted_bytes = 0;
425     guint16 clear_bytes = 0;
426     GstBuffer *buf_sub_sample;
427     guint8 nb_part;
428     GstByteWriter writer;
429
430     /* Read the number of partitions (1 byte) */
431     if (!gst_byte_reader_get_uint8 (&reader, &nb_part)) {
432       GST_ERROR ("Error reading the partition number");
433       return FALSE;
434     }
435
436     if (nb_part == 0) {
437       GST_ERROR ("Partitioned, but the subsample number equal to zero");
438       return FALSE;
439     }
440
441     nb_subsample = (nb_part + 2) >> 1;
442
443     gst_structure_set (info_protect, "subsample_count", G_TYPE_UINT,
444         nb_subsample, NULL);
445
446     /* WebM Spec:
447      *
448      * 4.6 Subsample Encrypted Block Format
449      *
450      * The Subsample Encrypted Block format extends the Full-sample format by setting a "partitioned" (P) bit in the Signal Byte.
451      * If this bit is set, the EncryptedBlock header shall include an
452      * 8-bit integer indicating the number of sample partitions (dividers between clear/encrypted sections),
453      * and a series of 32-bit integers in big-endian encoding indicating the byte offsets of such partitions.
454      *
455      *  0                   1                   2                   3
456      *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
457      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
458      * |  Signal Byte  |                                               |
459      * +-+-+-+-+-+-+-+-+             IV                                |
460      * |                                                               |
461      * |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
462      * |               | num_partition |     Partition 0 offset ->     |
463      * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
464      * |     -> Partition 0 offset     |              ...              |
465      * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
466      * |             ...               |     Partition n-1 offset ->   |
467      * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
468      * |     -> Partition n-1 offset   |                               |
469      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
470      * |                    Clear/encrypted sample data                |
471      * |                                                               |
472      * |                                                               |
473      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
474      *
475      * 4.6.1 SAMPLE PARTITIONS
476      *
477      * The samples shall be partitioned into alternating clear and encrypted sections,
478      * always starting with a clear section.
479      * Generally for n clear/encrypted sections there shall be n-1 partition offsets.
480      * However, if it is required that the first section be encrypted, then the first partition shall be at byte offset 0
481      * (indicating a zero-size clear section), and there shall be n partition offsets.
482      * Please refer to the "Sample Encryption" description of the "Common Encryption"
483      * section of the VP Codec ISO Media File Format Binding Specification for more
484      * detail on how subsample encryption is implemented.
485      */
486     subsamples =
487         g_malloc (nb_subsample * (sizeof (guint16) + sizeof (guint32)));
488
489     gst_byte_writer_init_with_data (&writer, subsamples,
490         nb_subsample * (sizeof (guint16) + sizeof (guint32)), FALSE);
491
492     for (i = 0; i <= nb_part; i++) {
493       offset_prev = offset;
494       if (i == nb_part) {
495         offset = gst_byte_reader_get_remaining (&reader);
496       } else {
497         if (!gst_byte_reader_get_uint32_be (&reader, &offset)) {
498           GST_ERROR ("Error reading the partition offset");
499           goto release_err;
500         }
501       }
502
503       if (offset < offset_prev) {
504         GST_ERROR ("Partition offsets should not decrease");
505         goto release_err;
506       }
507
508       if (i % 2 == 0) {
509         if ((offset - offset_prev) & 0xFFFF0000) {
510           GST_ERROR
511               ("The Clear Partition exceed 64KB in encrypted subsample format");
512           goto release_err;
513         }
514         /* We set the Clear partition size in 16 bits, in order to
515          * follow the same format of the box PSSH in CENC spec */
516         clear_bytes = offset - offset_prev;
517         if (i == nb_part)
518           encrypted_bytes = 0;
519       } else {
520         encrypted_bytes = offset - offset_prev;
521       }
522
523       if ((i % 2 == 1) || (i == nb_part)) {
524         if (clear_bytes == 0 && encrypted_bytes == 0) {
525           GST_ERROR ("Found 2 partitions with the same offsets.");
526           goto release_err;
527         }
528         if (!gst_byte_writer_put_uint16_be (&writer, clear_bytes)) {
529           GST_ERROR ("Error writing the number of clear bytes");
530           goto release_err;
531         }
532         if (!gst_byte_writer_put_uint32_be (&writer, encrypted_bytes)) {
533           GST_ERROR ("Error writing the number of encrypted bytes");
534           goto release_err;
535         }
536       }
537     }
538
539     buf_sub_sample =
540         gst_buffer_new_wrapped (subsamples,
541         nb_subsample * (sizeof (guint16) + sizeof (guint32)));
542     gst_structure_set (info_protect, "subsamples", GST_TYPE_BUFFER,
543         buf_sub_sample, NULL);
544     gst_buffer_unref (buf_sub_sample);
545   } else {
546     gst_structure_set (info_protect, "subsample_count", G_TYPE_UINT, 0, NULL);
547   }
548
549   gst_byte_reader_get_data (&reader, 0, (const guint8 **) data_out);
550   *size_out = gst_byte_reader_get_remaining (&reader);
551   return TRUE;
552
553 release_err:
554   g_free (subsamples);
555   return FALSE;
556 }
557
558 static gint
559 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
560 {
561   if (i1->time < i2->time)
562     return -1;
563   else if (i1->time > i2->time)
564     return 1;
565   else if (i1->block < i2->block)
566     return -1;
567   else if (i1->block > i2->block)
568     return 1;
569   else
570     return 0;
571 }
572
573 gint
574 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
575     gpointer user_data)
576 {
577   if (i1->time < *time)
578     return -1;
579   else if (i1->time > *time)
580     return 1;
581   else
582     return 0;
583 }
584
585 GstMatroskaIndex *
586 gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
587     GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
588     gint * _entry_index, GstSearchMode snap_dir)
589 {
590   GstMatroskaIndex *entry = NULL;
591   GArray *index;
592
593   /* find entry just before or at the requested position */
594   if (track && track->index_table)
595     index = track->index_table;
596   else
597     index = common->index;
598
599   if (!index || !index->len)
600     return NULL;
601
602   entry =
603       gst_util_array_binary_search (index->data, index->len,
604       sizeof (GstMatroskaIndex),
605       (GCompareDataFunc) gst_matroska_index_seek_find, snap_dir, &seek_pos,
606       NULL);
607
608   if (entry == NULL) {
609     if (snap_dir == GST_SEARCH_MODE_AFTER) {
610       /* Can only happen with a reverse seek past the end */
611       entry = &g_array_index (index, GstMatroskaIndex, index->len - 1);
612     } else {
613       /* Can only happen with a forward seek before the start */
614       entry = &g_array_index (index, GstMatroskaIndex, 0);
615     }
616   }
617
618   if (_index)
619     *_index = index;
620   if (_entry_index)
621     *_entry_index = entry - (GstMatroskaIndex *) index->data;
622
623   return entry;
624 }
625
626 static gint
627 gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
628     GstMatroskaTrackEncoding * b)
629 {
630   if (b->order > a->order)
631     return 1;
632   else if (b->order < a->order)
633     return -1;
634   else
635     return 0;
636 }
637
638 static gboolean
639 gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
640     order)
641 {
642   gint i;
643
644   if (encodings == NULL || encodings->len == 0)
645     return TRUE;
646
647   for (i = 0; i < encodings->len; i++)
648     if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
649       return FALSE;
650
651   return TRUE;
652 }
653
654 /* takes ownership of taglist */
655 void
656 gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
657     GstElement * el, GstTagList * taglist)
658 {
659   if (common->global_tags) {
660     gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
661     gst_tag_list_unref (taglist);
662   } else {
663     common->global_tags = taglist;
664   }
665   common->global_tags_changed = TRUE;
666 }
667
668 gint64
669 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
670 {
671   gint64 end = -1;
672
673   if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
674           &end) || end < 0)
675     GST_DEBUG_OBJECT (common->sinkpad, "no upstream length");
676
677   return end;
678 }
679
680 /* determine track to seek in */
681 GstMatroskaTrackContext *
682 gst_matroska_read_common_get_seek_track (GstMatroskaReadCommon * common,
683     GstMatroskaTrackContext * track)
684 {
685   gint i;
686
687   if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
688     return track;
689
690   for (i = 0; i < common->src->len; i++) {
691     GstMatroskaTrackContext *stream;
692
693     stream = g_ptr_array_index (common->src, i);
694     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
695       track = stream;
696   }
697
698   return track;
699 }
700
701 /* skip unknown or alike element */
702 GstFlowReturn
703 gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
704     GstEbmlRead * ebml, const gchar * parent_name, guint id)
705 {
706   if (id == GST_EBML_ID_VOID) {
707     GST_DEBUG_OBJECT (common->sinkpad, "Skipping EBML Void element");
708   } else if (id == GST_EBML_ID_CRC32) {
709     GST_DEBUG_OBJECT (common->sinkpad, "Skipping EBML CRC32 element");
710   } else {
711     GST_WARNING_OBJECT (common->sinkpad,
712         "Unknown %s subelement 0x%x - ignoring", parent_name, id);
713   }
714
715   return gst_ebml_read_skip (ebml);
716 }
717
718 static GstFlowReturn
719 gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common,
720     GstEbmlRead * ebml, GstTagList * taglist)
721 {
722   guint32 id;
723   GstFlowReturn ret;
724   gchar *description = NULL;
725   gchar *filename = NULL;
726   gchar *mimetype = NULL;
727   guint8 *data = NULL;
728   guint64 datalen = 0;
729
730   DEBUG_ELEMENT_START (common, ebml, "AttachedFile");
731
732   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
733     DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
734     return ret;
735   }
736
737   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
738     /* read all sub-entries */
739
740     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
741       break;
742
743     switch (id) {
744       case GST_MATROSKA_ID_FILEDESCRIPTION:
745         if (description) {
746           GST_WARNING_OBJECT (common->sinkpad,
747               "FileDescription can only appear once");
748           break;
749         }
750
751         ret = gst_ebml_read_utf8 (ebml, &id, &description);
752         GST_DEBUG_OBJECT (common->sinkpad, "FileDescription: %s",
753             GST_STR_NULL (description));
754         break;
755       case GST_MATROSKA_ID_FILENAME:
756         if (filename) {
757           GST_WARNING_OBJECT (common->sinkpad, "FileName can only appear once");
758           break;
759         }
760
761         ret = gst_ebml_read_utf8 (ebml, &id, &filename);
762
763         GST_DEBUG_OBJECT (common->sinkpad, "FileName: %s",
764             GST_STR_NULL (filename));
765         break;
766       case GST_MATROSKA_ID_FILEMIMETYPE:
767         if (mimetype) {
768           GST_WARNING_OBJECT (common->sinkpad,
769               "FileMimeType can only appear once");
770           break;
771         }
772
773         ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
774         GST_DEBUG_OBJECT (common->sinkpad, "FileMimeType: %s",
775             GST_STR_NULL (mimetype));
776         break;
777       case GST_MATROSKA_ID_FILEDATA:
778         if (data) {
779           GST_WARNING_OBJECT (common->sinkpad, "FileData can only appear once");
780           break;
781         }
782
783         ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
784         GST_DEBUG_OBJECT (common->sinkpad,
785             "FileData of size %" G_GUINT64_FORMAT, datalen);
786         break;
787
788       default:
789         ret = gst_matroska_read_common_parse_skip (common, ebml,
790             "AttachedFile", id);
791         break;
792       case GST_MATROSKA_ID_FILEUID:
793         ret = gst_ebml_read_skip (ebml);
794         break;
795     }
796   }
797
798   DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
799
800   if (filename && mimetype && data && datalen > 0) {
801     GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
802     GstBuffer *tagbuffer = NULL;
803     GstSample *tagsample = NULL;
804     GstStructure *info = NULL;
805     GstCaps *caps = NULL;
806     gchar *filename_lc = g_utf8_strdown (filename, -1);
807
808     GST_DEBUG_OBJECT (common->sinkpad, "Creating tag for attachment with "
809         "filename '%s', mimetype '%s', description '%s', "
810         "size %" G_GUINT64_FORMAT, filename, mimetype,
811         GST_STR_NULL (description), datalen);
812
813     /* TODO: better heuristics for different image types */
814     if (strstr (filename_lc, "cover")) {
815       if (strstr (filename_lc, "back"))
816         image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
817       else
818         image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
819     } else if (g_str_has_prefix (mimetype, "image/") ||
820         g_str_has_suffix (filename_lc, "png") ||
821         g_str_has_suffix (filename_lc, "jpg") ||
822         g_str_has_suffix (filename_lc, "jpeg") ||
823         g_str_has_suffix (filename_lc, "gif") ||
824         g_str_has_suffix (filename_lc, "bmp")) {
825       image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
826     }
827     g_free (filename_lc);
828
829     /* First try to create an image tag buffer from this */
830     if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
831       tagsample =
832           gst_tag_image_data_to_image_sample (data, datalen, image_type);
833
834       if (!tagsample) {
835         image_type = GST_TAG_IMAGE_TYPE_NONE;
836       } else {
837         tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample));
838         caps = gst_caps_ref (gst_sample_get_caps (tagsample));
839         info = gst_structure_copy (gst_sample_get_info (tagsample));
840         gst_sample_unref (tagsample);
841       }
842     }
843
844     /* if this failed create an attachment buffer */
845     if (!tagbuffer) {
846       tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);
847
848       caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
849       if (caps == NULL)
850         caps = gst_caps_new_empty_simple (mimetype);
851     }
852
853     /* Set filename and description in the info */
854     if (info == NULL)
855       info = gst_structure_new_empty ("GstTagImageInfo");
856
857     gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL);
858     if (description)
859       gst_structure_set (info, "description", G_TYPE_STRING, description, NULL);
860
861     tagsample = gst_sample_new (tagbuffer, caps, NULL, info);
862
863     gst_buffer_unref (tagbuffer);
864     gst_caps_unref (caps);
865
866     GST_DEBUG_OBJECT (common->sinkpad,
867         "Created attachment sample: %" GST_PTR_FORMAT, tagsample);
868
869     /* and append to the tag list */
870     if (image_type != GST_TAG_IMAGE_TYPE_NONE)
871       gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample,
872           NULL);
873     else
874       gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
875           tagsample, NULL);
876
877     /* the list adds it own ref */
878     gst_sample_unref (tagsample);
879   }
880
881   g_free (filename);
882   g_free (mimetype);
883   g_free (data);
884   g_free (description);
885
886   return ret;
887 }
888
889 GstFlowReturn
890 gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common,
891     GstElement * el, GstEbmlRead * ebml)
892 {
893   guint32 id;
894   GstFlowReturn ret = GST_FLOW_OK;
895   GstTagList *taglist;
896
897   DEBUG_ELEMENT_START (common, ebml, "Attachments");
898
899   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
900     DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
901     return ret;
902   }
903
904   taglist = gst_tag_list_new_empty ();
905   gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
906
907   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
908     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
909       break;
910
911     switch (id) {
912       case GST_MATROSKA_ID_ATTACHEDFILE:
913         ret = gst_matroska_read_common_parse_attached_file (common, ebml,
914             taglist);
915         break;
916
917       default:
918         ret = gst_matroska_read_common_parse_skip (common, ebml,
919             "Attachments", id);
920         break;
921     }
922   }
923   DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
924
925   if (gst_tag_list_n_tags (taglist) > 0) {
926     GST_DEBUG_OBJECT (common->sinkpad, "Storing attachment tags");
927     gst_matroska_read_common_found_global_tag (common, el, taglist);
928   } else {
929     GST_DEBUG_OBJECT (common->sinkpad, "No valid attachments found");
930     gst_tag_list_unref (taglist);
931   }
932
933   common->attachments_parsed = TRUE;
934
935   return ret;
936 }
937
938 static void
939 gst_matroska_read_common_parse_toc_tag (GstTocEntry * entry,
940     GstTocEntry * internal_entry, GArray * edition_targets,
941     GArray * chapter_targets, GstTagList * tags)
942 {
943   gchar *uid;
944   guint i;
945   guint64 tgt;
946   GArray *targets;
947   GList *cur, *internal_cur;
948   GstTagList *etags;
949
950   targets =
951       (gst_toc_entry_get_entry_type (entry) ==
952       GST_TOC_ENTRY_TYPE_EDITION) ? edition_targets : chapter_targets;
953
954   etags = gst_tag_list_new_empty ();
955
956   for (i = 0; i < targets->len; ++i) {
957     tgt = g_array_index (targets, guint64, i);
958
959     if (tgt == 0)
960       gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
961     else {
962       uid = g_strdup_printf ("%" G_GUINT64_FORMAT, tgt);
963       if (g_strcmp0 (gst_toc_entry_get_uid (internal_entry), uid) == 0)
964         gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
965       g_free (uid);
966     }
967   }
968
969   gst_toc_entry_merge_tags (entry, etags, GST_TAG_MERGE_APPEND);
970   gst_tag_list_unref (etags);
971
972   cur = gst_toc_entry_get_sub_entries (entry);
973   internal_cur = gst_toc_entry_get_sub_entries (internal_entry);
974   while (cur != NULL && internal_cur != NULL) {
975     gst_matroska_read_common_parse_toc_tag (cur->data, internal_cur->data,
976         edition_targets, chapter_targets, tags);
977     cur = cur->next;
978     internal_cur = internal_cur->next;
979   }
980 }
981
982 static GstFlowReturn
983 gst_matroska_read_common_parse_metadata_targets (GstMatroskaReadCommon * common,
984     GstEbmlRead * ebml, GArray * edition_targets, GArray * chapter_targets,
985     GArray * track_targets, guint64 * target_type_value, gchar ** target_type)
986 {
987   GstFlowReturn ret = GST_FLOW_OK;
988   guint32 id;
989   guint64 uid;
990   guint64 tmp;
991   gchar *str;
992
993   DEBUG_ELEMENT_START (common, ebml, "TagTargets");
994
995   *target_type_value = 50;
996   *target_type = NULL;
997
998   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
999     DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
1000     return ret;
1001   }
1002
1003   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1004     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1005       break;
1006
1007     switch (id) {
1008       case GST_MATROSKA_ID_TARGETCHAPTERUID:
1009         if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
1010           g_array_append_val (chapter_targets, uid);
1011         break;
1012
1013       case GST_MATROSKA_ID_TARGETEDITIONUID:
1014         if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
1015           g_array_append_val (edition_targets, uid);
1016         break;
1017
1018       case GST_MATROSKA_ID_TARGETTRACKUID:
1019         if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
1020           g_array_append_val (track_targets, uid);
1021         break;
1022
1023       case GST_MATROSKA_ID_TARGETTYPEVALUE:
1024         if ((ret = gst_ebml_read_uint (ebml, &id, &tmp)) == GST_FLOW_OK)
1025           *target_type_value = tmp;
1026         break;
1027
1028       case GST_MATROSKA_ID_TARGETTYPE:
1029         if ((ret = gst_ebml_read_ascii (ebml, &id, &str)) == GST_FLOW_OK) {
1030           g_free (*target_type);
1031           *target_type = str;
1032         }
1033         break;
1034
1035       default:
1036         ret =
1037             gst_matroska_read_common_parse_skip (common, ebml, "TagTargets",
1038             id);
1039         break;
1040     }
1041   }
1042
1043   DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
1044
1045   return ret;
1046 }
1047
1048 static void
1049 gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries,
1050     guint64 max, const gchar * parent_uid)
1051 {
1052   GstTocEntry *cur_info, *prev_info, *next_info;
1053   GList *cur_list, *prev_list, *next_list;
1054   gint64 cur_start, prev_start, stop;
1055
1056   cur_list = toc_entries;
1057   while (cur_list != NULL) {
1058     cur_info = cur_list->data;
1059
1060     switch (gst_toc_entry_get_entry_type (cur_info)) {
1061       case GST_TOC_ENTRY_TYPE_ANGLE:
1062       case GST_TOC_ENTRY_TYPE_VERSION:
1063       case GST_TOC_ENTRY_TYPE_EDITION:
1064         /* in Matroska terms edition has duration of full track */
1065         gst_toc_entry_set_start_stop_times (cur_info, 0, max);
1066
1067         gst_matroska_read_common_postprocess_toc_entries
1068             (gst_toc_entry_get_sub_entries (cur_info), max,
1069             gst_toc_entry_get_uid (cur_info));
1070         break;
1071
1072       case GST_TOC_ENTRY_TYPE_TITLE:
1073       case GST_TOC_ENTRY_TYPE_TRACK:
1074       case GST_TOC_ENTRY_TYPE_CHAPTER:
1075         prev_list = cur_list->prev;
1076         next_list = cur_list->next;
1077
1078         if (prev_list != NULL)
1079           prev_info = prev_list->data;
1080         else
1081           prev_info = NULL;
1082
1083         if (next_list != NULL)
1084           next_info = next_list->data;
1085         else
1086           next_info = NULL;
1087
1088         /* updated stop time in previous chapter and it's subchapters */
1089         if (prev_info != NULL) {
1090           gst_toc_entry_get_start_stop_times (prev_info, &prev_start, &stop);
1091           gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);
1092
1093           stop = cur_start;
1094           gst_toc_entry_set_start_stop_times (prev_info, prev_start, stop);
1095
1096           gst_matroska_read_common_postprocess_toc_entries
1097               (gst_toc_entry_get_sub_entries (prev_info), cur_start,
1098               gst_toc_entry_get_uid (prev_info));
1099         }
1100
1101         /* updated stop time in current chapter and it's subchapters */
1102         if (next_info == NULL) {
1103           gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);
1104
1105           if (stop == -1) {
1106             stop = max;
1107             gst_toc_entry_set_start_stop_times (cur_info, cur_start, stop);
1108           }
1109
1110           gst_matroska_read_common_postprocess_toc_entries
1111               (gst_toc_entry_get_sub_entries (cur_info), stop,
1112               gst_toc_entry_get_uid (cur_info));
1113         }
1114         break;
1115       case GST_TOC_ENTRY_TYPE_INVALID:
1116         break;
1117     }
1118     cur_list = cur_list->next;
1119   }
1120 }
1121
1122 static GstFlowReturn
1123 gst_matroska_read_common_parse_chapter_titles (GstMatroskaReadCommon * common,
1124     GstEbmlRead * ebml, GstTagList * titles)
1125 {
1126   guint32 id;
1127   gchar *title = NULL;
1128   GstFlowReturn ret = GST_FLOW_OK;
1129
1130   DEBUG_ELEMENT_START (common, ebml, "ChaptersTitles");
1131
1132
1133   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1134     DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
1135     return ret;
1136   }
1137
1138   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1139     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1140       break;
1141
1142     switch (id) {
1143       case GST_MATROSKA_ID_CHAPSTRING:
1144         ret = gst_ebml_read_utf8 (ebml, &id, &title);
1145         break;
1146
1147       default:
1148         ret =
1149             gst_matroska_read_common_parse_skip (common, ebml, "ChaptersTitles",
1150             id);
1151         break;
1152     }
1153   }
1154
1155   DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
1156
1157   if (title != NULL && ret == GST_FLOW_OK)
1158     gst_tag_list_add (titles, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, title, NULL);
1159
1160   g_free (title);
1161   return ret;
1162 }
1163
1164 static GstFlowReturn
1165 gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common,
1166     GstEbmlRead * ebml, GList ** subentries, GList ** internal_subentries)
1167 {
1168   guint32 id;
1169   guint64 start_time = -1, stop_time = -1;
1170   guint64 is_hidden = 0, is_enabled = 1, uid = 0;
1171   GstFlowReturn ret = GST_FLOW_OK;
1172   GstTocEntry *chapter_info, *internal_chapter_info;
1173   GstTagList *tags;
1174   gchar *uid_str, *string_uid = NULL;
1175   GList *subsubentries = NULL, *internal_subsubentries = NULL, *l, *il;
1176
1177   DEBUG_ELEMENT_START (common, ebml, "ChaptersElement");
1178
1179   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1180     DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
1181     return ret;
1182   }
1183
1184   tags = gst_tag_list_new_empty ();
1185
1186   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1187     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1188       break;
1189
1190     switch (id) {
1191       case GST_MATROSKA_ID_CHAPTERUID:
1192         ret = gst_ebml_read_uint (ebml, &id, &uid);
1193         break;
1194
1195       case GST_MATROSKA_ID_CHAPTERSTRINGUID:
1196         ret = gst_ebml_read_utf8 (ebml, &id, &string_uid);
1197         break;
1198
1199       case GST_MATROSKA_ID_CHAPTERTIMESTART:
1200         ret = gst_ebml_read_uint (ebml, &id, &start_time);
1201         break;
1202
1203       case GST_MATROSKA_ID_CHAPTERTIMESTOP:
1204         ret = gst_ebml_read_uint (ebml, &id, &stop_time);
1205         break;
1206
1207       case GST_MATROSKA_ID_CHAPTERATOM:
1208         ret = gst_matroska_read_common_parse_chapter_element (common, ebml,
1209             &subsubentries, &internal_subsubentries);
1210         break;
1211
1212       case GST_MATROSKA_ID_CHAPTERDISPLAY:
1213         ret =
1214             gst_matroska_read_common_parse_chapter_titles (common, ebml, tags);
1215         break;
1216
1217       case GST_MATROSKA_ID_CHAPTERFLAGHIDDEN:
1218         ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1219         break;
1220
1221       case GST_MATROSKA_ID_CHAPTERFLAGENABLED:
1222         ret = gst_ebml_read_uint (ebml, &id, &is_enabled);
1223         break;
1224
1225       default:
1226         ret =
1227             gst_matroska_read_common_parse_skip (common, ebml,
1228             "ChaptersElement", id);
1229         break;
1230     }
1231   }
1232
1233   if (uid == 0)
1234     uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
1235   uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1236   if (string_uid != NULL) {
1237     /* init toc with provided String UID */
1238     chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, string_uid);
1239     g_free (string_uid);
1240   } else {
1241     /* No String UID provided => use the internal UID instead */
1242     chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid_str);
1243   }
1244   /* init internal toc with internal UID */
1245   internal_chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER,
1246       uid_str);
1247   g_free (uid_str);
1248
1249   gst_toc_entry_set_tags (chapter_info, tags);
1250   gst_toc_entry_set_start_stop_times (chapter_info, start_time, stop_time);
1251
1252   for (l = subsubentries, il = internal_subsubentries;
1253       l && il; l = l->next, il = il->next) {
1254     gst_toc_entry_append_sub_entry (chapter_info, l->data);
1255     gst_toc_entry_append_sub_entry (internal_chapter_info, il->data);
1256   }
1257   g_list_free (subsubentries);
1258   g_list_free (internal_subsubentries);
1259
1260   DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
1261
1262   /* start time is mandatory and has no default value,
1263    * so we should skip chapters without it */
1264   if (is_hidden == 0 && is_enabled > 0 &&
1265       start_time != -1 && ret == GST_FLOW_OK) {
1266     *subentries = g_list_append (*subentries, chapter_info);
1267     *internal_subentries = g_list_append (*internal_subentries,
1268         internal_chapter_info);
1269   } else {
1270     gst_toc_entry_unref (chapter_info);
1271     gst_toc_entry_unref (internal_chapter_info);
1272   }
1273
1274   return ret;
1275 }
1276
1277 static GstFlowReturn
1278 gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common,
1279     GstEbmlRead * ebml, GstToc * toc, GstToc * internal_toc)
1280 {
1281   guint32 id;
1282   guint64 is_hidden = 0, uid = 0;
1283   GstFlowReturn ret = GST_FLOW_OK;
1284   GstTocEntry *edition_info, *internal_edition_info;
1285   GList *subentries = NULL, *internal_subentries = NULL, *l, *il;
1286   gchar *uid_str;
1287
1288   DEBUG_ELEMENT_START (common, ebml, "ChaptersEdition");
1289
1290   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1291     DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1292     return ret;
1293   }
1294
1295   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1296     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1297       break;
1298
1299     switch (id) {
1300       case GST_MATROSKA_ID_EDITIONUID:
1301         ret = gst_ebml_read_uint (ebml, &id, &uid);
1302         break;
1303
1304       case GST_MATROSKA_ID_CHAPTERATOM:
1305         ret = gst_matroska_read_common_parse_chapter_element (common, ebml,
1306             &subentries, &internal_subentries);
1307         break;
1308
1309       case GST_MATROSKA_ID_EDITIONFLAGHIDDEN:
1310         ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1311         break;
1312
1313       default:
1314         ret =
1315             gst_matroska_read_common_parse_skip (common, ebml,
1316             "ChaptersEdition", id);
1317         break;
1318     }
1319   }
1320
1321   DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1322
1323   if (uid == 0)
1324     uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
1325   uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1326   edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, uid_str);
1327   gst_toc_entry_set_start_stop_times (edition_info, -1, -1);
1328   internal_edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION,
1329       uid_str);
1330   g_free (uid_str);
1331
1332   for (l = subentries, il = internal_subentries; l && il;
1333       l = l->next, il = il->next) {
1334     gst_toc_entry_append_sub_entry (edition_info, l->data);
1335     gst_toc_entry_append_sub_entry (internal_edition_info, il->data);
1336   }
1337   g_list_free (subentries);
1338   g_list_free (internal_subentries);
1339
1340   if (is_hidden == 0 && subentries != NULL && ret == GST_FLOW_OK) {
1341     gst_toc_append_entry (toc, edition_info);
1342     gst_toc_append_entry (internal_toc, internal_edition_info);
1343   } else {
1344     GST_DEBUG_OBJECT (common->sinkpad,
1345         "Skipping empty or hidden edition in the chapters TOC");
1346     gst_toc_entry_unref (edition_info);
1347     gst_toc_entry_unref (internal_edition_info);
1348   }
1349
1350   return ret;
1351 }
1352
1353 GstFlowReturn
1354 gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common,
1355     GstEbmlRead * ebml)
1356 {
1357   guint32 id;
1358   GstFlowReturn ret = GST_FLOW_OK;
1359   GstToc *toc, *internal_toc;
1360
1361   DEBUG_ELEMENT_START (common, ebml, "Chapters");
1362
1363   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1364     DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1365     return ret;
1366   }
1367
1368   /* FIXME: create CURRENT toc as well */
1369   toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1370   internal_toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1371
1372   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1373     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1374       break;
1375
1376     switch (id) {
1377       case GST_MATROSKA_ID_EDITIONENTRY:
1378         ret = gst_matroska_read_common_parse_chapter_edition (common, ebml,
1379             toc, internal_toc);
1380         break;
1381
1382       default:
1383         ret =
1384             gst_matroska_read_common_parse_skip (common, ebml, "Chapters", id);
1385         break;
1386     }
1387   }
1388
1389   if (gst_toc_get_entries (toc) != NULL) {
1390     gst_matroska_read_common_postprocess_toc_entries (gst_toc_get_entries (toc),
1391         common->segment.duration, "");
1392     /* no need to postprocess internal_toc as we don't need to keep track
1393      * of start / end and tags (only UIDs) */
1394
1395     common->toc = toc;
1396     common->internal_toc = internal_toc;
1397   } else {
1398     gst_toc_unref (toc);
1399     gst_toc_unref (internal_toc);
1400   }
1401
1402   common->chapters_parsed = TRUE;
1403
1404   DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1405   return ret;
1406 }
1407
1408 GstFlowReturn
1409 gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
1410     GstEbmlRead * ebml)
1411 {
1412   GstFlowReturn ret;
1413   gchar *doctype;
1414   guint version;
1415   guint32 id;
1416
1417   /* this function is the first to be called */
1418
1419   /* default init */
1420   doctype = NULL;
1421   version = 1;
1422
1423   ret = gst_ebml_peek_id (ebml, &id);
1424   if (ret != GST_FLOW_OK)
1425     return ret;
1426
1427   GST_DEBUG_OBJECT (common->sinkpad, "id: %08x", id);
1428
1429   if (id != GST_EBML_ID_HEADER) {
1430     GST_ERROR_OBJECT (common->sinkpad, "Failed to read header");
1431     goto exit;
1432   }
1433
1434   ret = gst_ebml_read_master (ebml, &id);
1435   if (ret != GST_FLOW_OK)
1436     return ret;
1437
1438   while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1439     ret = gst_ebml_peek_id (ebml, &id);
1440     if (ret != GST_FLOW_OK)
1441       goto exit_error;
1442
1443     switch (id) {
1444         /* is our read version uptodate? */
1445       case GST_EBML_ID_EBMLREADVERSION:{
1446         guint64 num;
1447
1448         ret = gst_ebml_read_uint (ebml, &id, &num);
1449         if (ret != GST_FLOW_OK)
1450           goto exit_error;
1451         if (num != GST_EBML_VERSION) {
1452           GST_ERROR_OBJECT (common->sinkpad,
1453               "Unsupported EBML version %" G_GUINT64_FORMAT, num);
1454           goto exit_error;
1455         }
1456
1457         GST_DEBUG_OBJECT (common->sinkpad,
1458             "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1459         break;
1460       }
1461
1462         /* we only handle 8 byte lengths at max */
1463       case GST_EBML_ID_EBMLMAXSIZELENGTH:{
1464         guint64 num;
1465
1466         ret = gst_ebml_read_uint (ebml, &id, &num);
1467         if (ret != GST_FLOW_OK)
1468           goto exit_error;
1469         if (num > sizeof (guint64)) {
1470           GST_ERROR_OBJECT (common->sinkpad,
1471               "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
1472           return GST_FLOW_ERROR;
1473         }
1474         GST_DEBUG_OBJECT (common->sinkpad,
1475             "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
1476         break;
1477       }
1478
1479         /* we handle 4 byte IDs at max */
1480       case GST_EBML_ID_EBMLMAXIDLENGTH:{
1481         guint64 num;
1482
1483         ret = gst_ebml_read_uint (ebml, &id, &num);
1484         if (ret != GST_FLOW_OK)
1485           goto exit_error;
1486         if (num > sizeof (guint32)) {
1487           GST_ERROR_OBJECT (common->sinkpad,
1488               "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
1489           return GST_FLOW_ERROR;
1490         }
1491         GST_DEBUG_OBJECT (common->sinkpad,
1492             "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
1493         break;
1494       }
1495
1496       case GST_EBML_ID_DOCTYPE:{
1497         gchar *text;
1498
1499         ret = gst_ebml_read_ascii (ebml, &id, &text);
1500         if (ret != GST_FLOW_OK)
1501           goto exit_error;
1502
1503         GST_DEBUG_OBJECT (common->sinkpad, "EbmlDocType: %s",
1504             GST_STR_NULL (text));
1505
1506         g_free (doctype);
1507         doctype = text;
1508         break;
1509       }
1510
1511       case GST_EBML_ID_DOCTYPEREADVERSION:{
1512         guint64 num;
1513
1514         ret = gst_ebml_read_uint (ebml, &id, &num);
1515         if (ret != GST_FLOW_OK)
1516           goto exit_error;
1517         version = num;
1518         GST_DEBUG_OBJECT (common->sinkpad,
1519             "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1520         break;
1521       }
1522
1523       default:
1524         ret = gst_matroska_read_common_parse_skip (common, ebml,
1525             "EBML header", id);
1526         if (ret != GST_FLOW_OK)
1527           goto exit_error;
1528         break;
1529
1530         /* we ignore these two, as they don't tell us anything we care about */
1531       case GST_EBML_ID_EBMLVERSION:
1532       case GST_EBML_ID_DOCTYPEVERSION:
1533         ret = gst_ebml_read_skip (ebml);
1534         if (ret != GST_FLOW_OK)
1535           goto exit_error;
1536         break;
1537     }
1538   }
1539
1540 exit:
1541
1542   if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
1543       (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
1544       (doctype == NULL)) {
1545     if (version <= 2) {
1546       if (doctype) {
1547         GST_INFO_OBJECT (common->sinkpad, "Input is %s version %d", doctype,
1548             version);
1549         if (!strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM))
1550           common->is_webm = TRUE;
1551       } else {
1552         GST_WARNING_OBJECT (common->sinkpad,
1553             "Input is EBML without doctype, assuming " "matroska (version %d)",
1554             version);
1555       }
1556       ret = GST_FLOW_OK;
1557     } else {
1558       GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
1559           ("Demuxer version (2) is too old to read %s version %d",
1560               GST_STR_NULL (doctype), version));
1561       ret = GST_FLOW_ERROR;
1562     }
1563   } else {
1564     GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
1565         ("Input is not a matroska stream (doctype=%s)", doctype));
1566     ret = GST_FLOW_ERROR;
1567   }
1568
1569 exit_error:
1570
1571   g_free (doctype);
1572
1573   return ret;
1574 }
1575
1576 static GstFlowReturn
1577 gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
1578     GstEbmlRead * ebml, guint * nentries)
1579 {
1580   guint32 id;
1581   GstFlowReturn ret;
1582   GstMatroskaIndex idx;
1583
1584   idx.pos = (guint64) - 1;
1585   idx.track = 0;
1586   idx.time = GST_CLOCK_TIME_NONE;
1587   idx.block = 1;
1588
1589   DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");
1590
1591   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1592     DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1593     return ret;
1594   }
1595
1596   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1597     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1598       break;
1599
1600     switch (id) {
1601         /* track number */
1602       case GST_MATROSKA_ID_CUETRACK:
1603       {
1604         guint64 num;
1605
1606         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1607           break;
1608
1609         if (num == 0) {
1610           idx.track = 0;
1611           GST_WARNING_OBJECT (common->sinkpad, "Invalid CueTrack 0");
1612           break;
1613         }
1614
1615         GST_DEBUG_OBJECT (common->sinkpad, "CueTrack: %" G_GUINT64_FORMAT, num);
1616         idx.track = num;
1617         break;
1618       }
1619
1620         /* position in file */
1621       case GST_MATROSKA_ID_CUECLUSTERPOSITION:
1622       {
1623         guint64 num;
1624
1625         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1626           break;
1627
1628         if (num > G_MAXINT64) {
1629           GST_WARNING_OBJECT (common->sinkpad,
1630               "CueClusterPosition %" G_GUINT64_FORMAT " too large", num);
1631           break;
1632         }
1633
1634         idx.pos = num;
1635         break;
1636       }
1637
1638         /* number of block in the cluster */
1639       case GST_MATROSKA_ID_CUEBLOCKNUMBER:
1640       {
1641         guint64 num;
1642
1643         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1644           break;
1645
1646         if (num == 0) {
1647           GST_WARNING_OBJECT (common->sinkpad, "Invalid CueBlockNumber 0");
1648           break;
1649         }
1650
1651         GST_DEBUG_OBJECT (common->sinkpad, "CueBlockNumber: %" G_GUINT64_FORMAT,
1652             num);
1653         idx.block = num;
1654
1655         /* mild sanity check, disregard strange cases ... */
1656         if (idx.block > G_MAXUINT16) {
1657           GST_DEBUG_OBJECT (common->sinkpad, "... looks suspicious, ignoring");
1658           idx.block = 1;
1659         }
1660         break;
1661       }
1662
1663       default:
1664         ret = gst_matroska_read_common_parse_skip (common, ebml,
1665             "CueTrackPositions", id);
1666         break;
1667
1668       case GST_MATROSKA_ID_CUECODECSTATE:
1669       case GST_MATROSKA_ID_CUEREFERENCE:
1670         ret = gst_ebml_read_skip (ebml);
1671         break;
1672     }
1673   }
1674
1675   DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1676
1677   /* (e.g.) lavf typically creates entries without a block number,
1678    * which is bogus and leads to contradictory information */
1679   if (common->index->len) {
1680     GstMatroskaIndex *last_idx;
1681
1682     last_idx = &g_array_index (common->index, GstMatroskaIndex,
1683         common->index->len - 1);
1684     if (last_idx->block == idx.block && last_idx->pos == idx.pos &&
1685         last_idx->track == idx.track && idx.time > last_idx->time) {
1686       GST_DEBUG_OBJECT (common->sinkpad, "Cue entry refers to same location, "
1687           "but has different time than previous entry; discarding");
1688       idx.track = 0;
1689     }
1690   }
1691
1692   if ((ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1693       && idx.pos != (guint64) - 1 && idx.track > 0) {
1694     g_array_append_val (common->index, idx);
1695     (*nentries)++;
1696   } else if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) {
1697     GST_DEBUG_OBJECT (common->sinkpad,
1698         "CueTrackPositions without valid content");
1699   }
1700
1701   return ret;
1702 }
1703
1704 static GstFlowReturn
1705 gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
1706     common, GstEbmlRead * ebml)
1707 {
1708   guint32 id;
1709   GstFlowReturn ret;
1710   GstClockTime time = GST_CLOCK_TIME_NONE;
1711   guint nentries = 0;
1712
1713   DEBUG_ELEMENT_START (common, ebml, "CuePoint");
1714
1715   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1716     DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1717     return ret;
1718   }
1719
1720   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1721     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1722       break;
1723
1724     switch (id) {
1725         /* one single index entry ('point') */
1726       case GST_MATROSKA_ID_CUETIME:
1727       {
1728         if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
1729           break;
1730
1731         GST_DEBUG_OBJECT (common->sinkpad, "CueTime: %" G_GUINT64_FORMAT, time);
1732         time = time * common->time_scale;
1733         break;
1734       }
1735
1736         /* position in the file + track to which it belongs */
1737       case GST_MATROSKA_ID_CUETRACKPOSITIONS:
1738       {
1739         ret = gst_matroska_read_common_parse_index_cuetrack (common, ebml,
1740             &nentries);
1741         break;
1742       }
1743
1744       default:
1745         ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
1746             id);
1747         break;
1748     }
1749   }
1750
1751   DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1752
1753   if (nentries > 0) {
1754     if (time == GST_CLOCK_TIME_NONE) {
1755       GST_WARNING_OBJECT (common->sinkpad, "CuePoint without valid time");
1756       g_array_remove_range (common->index, common->index->len - nentries,
1757           nentries);
1758     } else {
1759       gint i;
1760
1761       for (i = common->index->len - nentries; i < common->index->len; i++) {
1762         GstMatroskaIndex *idx =
1763             &g_array_index (common->index, GstMatroskaIndex, i);
1764
1765         idx->time = time;
1766         GST_DEBUG_OBJECT (common->sinkpad, "Index entry: pos=%" G_GUINT64_FORMAT
1767             ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
1768             GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
1769       }
1770     }
1771   } else {
1772     GST_DEBUG_OBJECT (common->sinkpad, "Empty CuePoint");
1773   }
1774
1775   return ret;
1776 }
1777
1778 gint
1779 gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
1780     guint track_num)
1781 {
1782   guint n;
1783
1784   g_assert (common->src->len == common->num_streams);
1785   for (n = 0; n < common->src->len; n++) {
1786     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);
1787
1788     if (context->num == track_num) {
1789       return n;
1790     }
1791   }
1792
1793   if (n == common->num_streams)
1794     GST_WARNING_OBJECT (common->sinkpad,
1795         "Failed to find corresponding pad for tracknum %d", track_num);
1796
1797   return -1;
1798 }
1799
1800 GstFlowReturn
1801 gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
1802     GstEbmlRead * ebml)
1803 {
1804   guint32 id;
1805   GstFlowReturn ret = GST_FLOW_OK;
1806   guint i;
1807
1808   if (common->index)
1809     g_array_free (common->index, TRUE);
1810   common->index =
1811       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1812
1813   DEBUG_ELEMENT_START (common, ebml, "Cues");
1814
1815   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1816     DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1817     return ret;
1818   }
1819
1820   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1821     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1822       break;
1823
1824     switch (id) {
1825         /* one single index entry ('point') */
1826       case GST_MATROSKA_ID_POINTENTRY:
1827         ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
1828         break;
1829
1830       default:
1831         ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
1832         break;
1833     }
1834   }
1835   DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1836
1837   /* Sort index by time, smallest time first, for easier searching */
1838   g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);
1839
1840   /* Now sort the track specific index entries into their own arrays */
1841   for (i = 0; i < common->index->len; i++) {
1842     GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
1843         i);
1844     gint track_num;
1845     GstMatroskaTrackContext *ctx;
1846
1847 #if 0
1848     if (common->element_index) {
1849       gint writer_id;
1850
1851       if (idx->track != 0 &&
1852           (track_num =
1853               gst_matroska_read_common_stream_from_num (common,
1854                   idx->track)) != -1) {
1855         ctx = g_ptr_array_index (common->src, track_num);
1856
1857         if (ctx->index_writer_id == -1)
1858           gst_index_get_writer_id (common->element_index,
1859               GST_OBJECT (ctx->pad), &ctx->index_writer_id);
1860         writer_id = ctx->index_writer_id;
1861       } else {
1862         if (common->element_index_writer_id == -1)
1863           gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
1864               &common->element_index_writer_id);
1865         writer_id = common->element_index_writer_id;
1866       }
1867
1868       GST_LOG_OBJECT (common->sinkpad,
1869           "adding association %" GST_TIME_FORMAT "-> %" G_GUINT64_FORMAT
1870           " for writer id %d", GST_TIME_ARGS (idx->time), idx->pos, writer_id);
1871       gst_index_add_association (common->element_index, writer_id,
1872           GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
1873           GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
1874     }
1875 #endif
1876
1877     if (idx->track == 0)
1878       continue;
1879
1880     track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
1881     if (track_num == -1)
1882       continue;
1883
1884     ctx = g_ptr_array_index (common->src, track_num);
1885
1886     if (ctx->index_table == NULL)
1887       ctx->index_table =
1888           g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1889
1890     g_array_append_vals (ctx->index_table, idx, 1);
1891   }
1892
1893   common->index_parsed = TRUE;
1894
1895   /* sanity check; empty index normalizes to no index */
1896   if (common->index->len == 0) {
1897     g_array_free (common->index, TRUE);
1898     common->index = NULL;
1899   }
1900
1901   return ret;
1902 }
1903
1904 GstFlowReturn
1905 gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common,
1906     GstElement * el, GstEbmlRead * ebml)
1907 {
1908   GstFlowReturn ret = GST_FLOW_OK;
1909   gdouble dur_f = -1.0;
1910   guint32 id;
1911
1912   DEBUG_ELEMENT_START (common, ebml, "SegmentInfo");
1913
1914   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1915     DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1916     return ret;
1917   }
1918
1919   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1920     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1921       break;
1922
1923     switch (id) {
1924         /* cluster timecode */
1925       case GST_MATROSKA_ID_TIMECODESCALE:{
1926         guint64 num;
1927
1928         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1929           break;
1930
1931
1932         GST_DEBUG_OBJECT (common->sinkpad, "TimeCodeScale: %" G_GUINT64_FORMAT,
1933             num);
1934         common->time_scale = num;
1935         break;
1936       }
1937
1938       case GST_MATROSKA_ID_DURATION:{
1939         if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
1940           break;
1941
1942         if (dur_f <= 0.0) {
1943           GST_WARNING_OBJECT (common->sinkpad, "Invalid duration %lf", dur_f);
1944           break;
1945         }
1946
1947         GST_DEBUG_OBJECT (common->sinkpad, "Duration: %lf", dur_f);
1948         break;
1949       }
1950
1951       case GST_MATROSKA_ID_WRITINGAPP:{
1952         gchar *text;
1953
1954         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1955           break;
1956
1957         GST_DEBUG_OBJECT (common->sinkpad, "WritingApp: %s",
1958             GST_STR_NULL (text));
1959         common->writing_app = text;
1960         break;
1961       }
1962
1963       case GST_MATROSKA_ID_MUXINGAPP:{
1964         gchar *text;
1965
1966         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1967           break;
1968
1969         GST_DEBUG_OBJECT (common->sinkpad, "MuxingApp: %s",
1970             GST_STR_NULL (text));
1971         common->muxing_app = text;
1972         break;
1973       }
1974
1975       case GST_MATROSKA_ID_DATEUTC:{
1976         gint64 time;
1977
1978         if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
1979           break;
1980
1981         GST_DEBUG_OBJECT (common->sinkpad, "DateUTC: %" G_GINT64_FORMAT, time);
1982         common->created = time;
1983         break;
1984       }
1985
1986       case GST_MATROSKA_ID_TITLE:{
1987         gchar *text;
1988         GstTagList *taglist;
1989
1990         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1991           break;
1992
1993         GST_DEBUG_OBJECT (common->sinkpad, "Title: %s", GST_STR_NULL (text));
1994         taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
1995         gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
1996         gst_matroska_read_common_found_global_tag (common, el, taglist);
1997         g_free (text);
1998         break;
1999       }
2000
2001       default:
2002         ret = gst_matroska_read_common_parse_skip (common, ebml,
2003             "SegmentInfo", id);
2004         break;
2005
2006         /* fall through */
2007       case GST_MATROSKA_ID_SEGMENTUID:
2008       case GST_MATROSKA_ID_SEGMENTFILENAME:
2009       case GST_MATROSKA_ID_PREVUID:
2010       case GST_MATROSKA_ID_PREVFILENAME:
2011       case GST_MATROSKA_ID_NEXTUID:
2012       case GST_MATROSKA_ID_NEXTFILENAME:
2013       case GST_MATROSKA_ID_SEGMENTFAMILY:
2014       case GST_MATROSKA_ID_CHAPTERTRANSLATE:
2015         ret = gst_ebml_read_skip (ebml);
2016         break;
2017     }
2018   }
2019
2020   if (dur_f > 0.0) {
2021     GstClockTime dur_u;
2022
2023     dur_u = gst_gdouble_to_guint64 (dur_f *
2024         gst_guint64_to_gdouble (common->time_scale));
2025     if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
2026       common->segment.duration = dur_u;
2027   }
2028
2029   DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
2030
2031   common->segmentinfo_parsed = TRUE;
2032
2033   return ret;
2034 }
2035
2036 static GstFlowReturn
2037 gst_matroska_read_common_parse_metadata_id_simple_tag (GstMatroskaReadCommon *
2038     common, GstEbmlRead * ebml, GstTagList ** p_taglist, gchar * parent)
2039 {
2040   /* FIXME: check if there are more useful mappings */
2041   static const struct
2042   {
2043     const gchar *matroska_tagname;
2044     const gchar *gstreamer_tagname;
2045   }
2046
2047   /* *INDENT-OFF* */
2048   tag_conv[] = {
2049     {
2050       /* The following list has the _same_ order as the one in Matroska spec. Please, don't mess it up. */
2051       /* TODO: Nesting information:
2052          ORIGINAL A special tag that is meant to have other tags inside (using nested tags) to describe the original work of art that this item is based on. All tags in this list can be used "under" the ORIGINAL tag like LYRICIST, PERFORMER, etc.
2053          SAMPLE A tag that contains other tags to describe a sample used in the targeted item taken from another work of art. All tags in this list can be used "under" the SAMPLE tag like TITLE, ARTIST, DATE_RELEASED, etc.
2054          COUNTRY The name of the country (biblio ISO-639-2) that is meant to have other tags inside (using nested tags) to country specific information about the item. All tags in this list can be used "under" the COUNTRY_SPECIFIC tag like LABEL, PUBLISH_RATING, etc.
2055        */
2056
2057       /* Organizational Information */
2058     GST_MATROSKA_TAG_ID_TOTAL_PARTS, GST_TAG_TRACK_COUNT}, {
2059     GST_MATROSKA_TAG_ID_PART_NUMBER, GST_TAG_TRACK_NUMBER}, {
2060       /* TODO: PART_OFFSET A number to add to PART_NUMBER when the parts at that level don't start at 1. (e.g. if TargetType is TRACK, the track number of the second audio CD) */
2061
2062       /* Titles */
2063     GST_MATROSKA_TAG_ID_SUBTITLE, GST_TAG_TITLE}, {     /* Sub Title of the entity. Since we're concat'ing all title-like entities anyway, might as well add the sub-title. */
2064     GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
2065     GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {        /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2066
2067       /* TODO: Nested Information:
2068          URL URL corresponding to the tag it's included in.
2069          SORT_WITH A child element to indicate what alternative value the parent tag can have to be sorted, for example "Pet Shop Boys" instead of "The Pet Shop Boys". Or "Marley Bob" and "Marley Ziggy" (no comma needed).
2070          INSTRUMENTS The instruments that are being used/played, separated by a comma. It should be a child of the following tags: ARTIST, LEAD_PERFORMER or ACCOMPANIMENT.
2071          EMAIL Email corresponding to the tag it's included in.
2072          ADDRESS The physical address of the entity. The address should include a country code. It can be useful for a recording label.
2073          FAX The fax number corresponding to the tag it's included in. It can be useful for a recording label.
2074          PHONE The phone number corresponding to the tag it's included in. It can be useful for a recording label.
2075        */
2076
2077       /* Entities */
2078     GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
2079     GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
2080     GST_MATROSKA_TAG_ID_ACCOMPANIMENT, GST_TAG_PERFORMER}, {    /* Band/orchestra/accompaniment/musician. This is akin to the TPE2 tag in ID3. */
2081     GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
2082       /* ARRANGER The person who arranged the piece, e.g., Ravel. */
2083     GST_MATROSKA_TAG_ID_LYRICS, GST_TAG_LYRICS}, {      /* The lyrics corresponding to a song (in case audio synchronization is not known or as a doublon to a subtitle track). Editing this value when subtitles are found should also result in editing the subtitle track for more consistency. */
2084       /* LYRICIST The person who wrote the lyrics for a musical item. This is akin to the TEXT tag in ID3. */
2085     GST_MATROSKA_TAG_ID_CONDUCTOR, GST_TAG_PERFORMER}, {        /* Conductor/performer refinement. This is akin to the TPE3 tag in ID3. */
2086       /* DIRECTOR This is akin to the IART tag in RIFF. */
2087     GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
2088       /* ASSISTANT_DIRECTOR The name of the assistant director. */
2089       /* DIRECTOR_OF_PHOTOGRAPHY The name of the director of photography, also known as cinematographer. This is akin to the ICNM tag in Extended RIFF. */
2090       /* SOUND_ENGINEER The name of the sound engineer or sound recordist. */
2091       /* ART_DIRECTOR The person who oversees the artists and craftspeople who build the sets. */
2092       /* PRODUCTION_DESIGNER Artist responsible for designing the overall visual appearance of a movie. */
2093       /* CHOREGRAPHER The name of the choregrapher */
2094       /* COSTUME_DESIGNER The name of the costume designer */
2095       /* ACTOR An actor or actress playing a role in this movie. This is the person's real name, not the character's name the person is playing. */
2096       /* CHARACTER The name of the character an actor or actress plays in this movie. This should be a sub-tag of an ACTOR tag in order not to cause ambiguities. */
2097       /* WRITTEN_BY The author of the story or script (used for movies and TV shows). */
2098       /* SCREENPLAY_BY The author of the screenplay or scenario (used for movies and TV shows). */
2099       /* EDITED_BY This is akin to the IEDT tag in Extended RIFF. */
2100       /* PRODUCER Produced by. This is akin to the IPRO tag in Extended RIFF. */
2101       /* COPRODUCER The name of a co-producer. */
2102       /* EXECUTIVE_PRODUCER The name of an executive producer. */
2103       /* DISTRIBUTED_BY This is akin to the IDST tag in Extended RIFF. */
2104       /* MASTERED_BY The engineer who mastered the content for a physical medium or for digital distribution. */
2105     GST_MATROSKA_TAG_ID_ENCODED_BY, GST_TAG_ENCODED_BY}, {      /* This is akin to the TENC tag in ID3. */
2106       /* MIXED_BY DJ mix by the artist specified */
2107       /* REMIXED_BY Interpreted, remixed, or otherwise modified by. This is akin to the TPE4 tag in ID3. */
2108       /* PRODUCTION_STUDIO This is akin to the ISTD tag in Extended RIFF. */
2109       /* THANKS_TO A very general tag for everyone else that wants to be listed. */
2110       /* PUBLISHER This is akin to the TPUB tag in ID3. */
2111       /* LABEL The record label or imprint on the disc. */
2112       /* Search / Classification */
2113     GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}, {
2114       /* MOOD Intended to reflect the mood of the item with a few keywords, e.g. "Romantic", "Sad" or "Uplifting". The format follows that of the TMOO tag in ID3. */
2115       /* ORIGINAL_MEDIA_TYPE Describes the original type of the media, such as, "DVD", "CD", "computer image," "drawing," "lithograph," and so forth. This is akin to the TMED tag in ID3. */
2116       /* CONTENT_TYPE The type of the item. e.g. Documentary, Feature Film, Cartoon, Music Video, Music, Sound FX, ... */
2117       /* SUBJECT Describes the topic of the file, such as "Aerial view of Seattle." */
2118     GST_MATROSKA_TAG_ID_DESCRIPTION, GST_TAG_DESCRIPTION}, {    /* A short description of the content, such as "Two birds flying." */
2119     GST_MATROSKA_TAG_ID_KEYWORDS, GST_TAG_KEYWORDS}, {  /* Keywords to the item separated by a comma, used for searching. */
2120       /* SUMMARY A plot outline or a summary of the story. */
2121       /* SYNOPSIS A description of the story line of the item. */
2122       /* INITIAL_KEY The initial key that a musical track starts in. The format is identical to ID3. */
2123       /* PERIOD Describes the period that the piece is from or about. For example, "Renaissance". */
2124       /* LAW_RATING Depending on the country it's the format of the rating of a movie (P, R, X in the USA, an age in other countries or a URI defining a logo). */
2125       /* ICRA The ICRA content rating for parental control. (Previously RSACi) */
2126
2127       /* Temporal Information */
2128     GST_MATROSKA_TAG_ID_DATE_RELEASED, GST_TAG_DATE}, { /* The time that the item was originaly released. This is akin to the TDRL tag in ID3. */
2129     GST_MATROSKA_TAG_ID_DATE_RECORDED, GST_TAG_DATE}, { /* The time that the recording began. This is akin to the TDRC tag in ID3. */
2130     GST_MATROSKA_TAG_ID_DATE_ENCODED, GST_TAG_DATE}, {  /* The time that the encoding of this item was completed began. This is akin to the TDEN tag in ID3. */
2131     GST_MATROSKA_TAG_ID_DATE_TAGGED, GST_TAG_DATE}, {   /* The time that the tags were done for this item. This is akin to the TDTG tag in ID3. */
2132     GST_MATROSKA_TAG_ID_DATE_DIGITIZED, GST_TAG_DATE}, {        /* The time that the item was tranfered to a digital medium. This is akin to the IDIT tag in RIFF. */
2133     GST_MATROSKA_TAG_ID_DATE_WRITTEN, GST_TAG_DATE}, {  /* The time that the writing of the music/script began. */
2134     GST_MATROSKA_TAG_ID_DATE_PURCHASED, GST_TAG_DATE}, {        /* Information on when the file was purchased (see also purchase tags). */
2135     GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {  /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2136
2137       /* Spacial Information */
2138     GST_MATROSKA_TAG_ID_RECORDING_LOCATION, GST_TAG_GEO_LOCATION_NAME}, {       /* The location where the item was recorded. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. This code is followed by a comma, then more detailed information such as state/province, another comma, and then city. For example, "US, Texas, Austin". This will allow for easy sorting. It is okay to only store the country, or the country and the state/province. More detailed information can be added after the city through the use of additional commas. In cases where the province/state is unknown, but you want to store the city, simply leave a space between the two commas. For example, "US, , Austin". */
2139       /* COMPOSITION_LOCATION Location that the item was originaly designed/written. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. This code is followed by a comma, then more detailed information such as state/province, another comma, and then city. For example, "US, Texas, Austin". This will allow for easy sorting. It is okay to only store the country, or the country and the state/province. More detailed information can be added after the city through the use of additional commas. In cases where the province/state is unknown, but you want to store the city, simply leave a space between the two commas. For example, "US, , Austin". */
2140       /* COMPOSER_NATIONALITY Nationality of the main composer of the item, mostly for classical music. The countries corresponding to the string, same 2 octets as in Internet domains, or possibly ISO-3166. */
2141
2142       /* Personal */
2143     GST_MATROSKA_TAG_ID_COMMENT, GST_TAG_COMMENT}, {    /* Any comment related to the content. */
2144     GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {   /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2145       /* PLAY_COUNTER The number of time the item has been played. */
2146       /* TODO: RATING A numeric value defining how much a person likes the song/movie. The number is between 0 and 5 with decimal values possible (e.g. 2.7), 5(.0) being the highest possible rating. Other rating systems with different ranges will have to be scaled. */
2147
2148       /* Technical Information */
2149     GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
2150       /* ENCODER_SETTINGS A list of the settings used for encoding this item. No specific format. */
2151     GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
2152     GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {     /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
2153       /* WONTFIX (already handled in another way): FPS The average frames per second of the specified item. This is typically the average number of Blocks per second. In the event that lacing is used, each laced chunk is to be counted as a seperate frame. */
2154     GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
2155       /* MEASURE In music, a measure is a unit of time in Western music like "4/4". It represents a regular grouping of beats, a meter, as indicated in musical notation by the time signature.. The majority of the contemporary rock and pop music you hear on the radio these days is written in the 4/4 time signature. */
2156       /* TUNING It is saved as a frequency in hertz to allow near-perfect tuning of instruments to the same tone as the musical piece (e.g. "441.34" in Hertz). The default value is 440.0 Hz. */
2157       /* TODO: REPLAYGAIN_GAIN The gain to apply to reach 89dB SPL on playback. This is based on the Replay Gain standard. Note that ReplayGain information can be found at all TargetType levels (track, album, etc). */
2158       /* TODO: REPLAYGAIN_PEAK The maximum absolute peak value of the item. This is based on the Replay Gain standard. */
2159
2160       /* Identifiers */
2161     GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
2162       /* MCDI This is a binary dump of the TOC of the CDROM that this item was taken from. This holds the same information as the MCDI in ID3. */
2163       /* ISBN International Standard Book Number */
2164       /* BARCODE EAN-13 (European Article Numbering) or UPC-A (Universal Product Code) bar code identifier */
2165       /* CATALOG_NUMBER A label-specific string used to identify the release (TIC 01 for example). */
2166       /* LABEL_CODE A 4-digit or 5-digit number to identify the record label, typically printed as (LC) xxxx or (LC) 0xxxx on CDs medias or covers (only the number is stored). */
2167       /* LCCN Library of Congress Control Number */
2168
2169       /* Commercial */
2170       /* PURCHASE_ITEM URL to purchase this file. This is akin to the WPAY tag in ID3. */
2171       /* PURCHASE_INFO Information on where to purchase this album. This is akin to the WCOM tag in ID3. */
2172       /* PURCHASE_OWNER Information on the person who purchased the file. This is akin to the TOWN tag in ID3. */
2173       /* PURCHASE_PRICE The amount paid for entity. There should only be a numeric value in here. Only numbers, no letters or symbols other than ".". For instance, you would store "15.59" instead of "$15.59USD". */
2174       /* PURCHASE_CURRENCY The currency type used to pay for the entity. Use ISO-4217 for the 3 letter currency code. */
2175
2176       /* Legal */
2177     GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
2178     GST_MATROSKA_TAG_ID_PRODUCTION_COPYRIGHT, GST_TAG_COPYRIGHT}, {     /* The copyright information as per the production copyright holder. This is akin to the TPRO tag in ID3. */
2179     GST_MATROSKA_TAG_ID_LICENSE, GST_TAG_LICENSE}, {    /* The license applied to the content (like Creative Commons variants). */
2180     GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}
2181   };
2182   /* *INDENT-ON* */
2183   static const struct
2184   {
2185     const gchar *matroska_tagname;
2186     const gchar *gstreamer_tagname;
2187   }
2188
2189   /* *INDENT-OFF* */
2190   child_tag_conv[] = {
2191     {
2192     "TITLE/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
2193     "ARTIST/SORT_WITH=", GST_TAG_ARTIST_SORTNAME}, {
2194       /* ALBUM-stuff is handled elsewhere */
2195     "COMPOSER/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
2196     "ORIGINAL/URL=", GST_TAG_LOCATION}, {
2197       /* EMAIL, PHONE, FAX all can be mapped to GST_TAG_CONTACT, there is special
2198        * code for that later.
2199        */
2200     "TITLE/URL=", GST_TAG_HOMEPAGE}, {
2201     "ARTIST/URL=", GST_TAG_HOMEPAGE}, {
2202     "COPYRIGHT/URL=", GST_TAG_COPYRIGHT_URI}, {
2203     "LICENSE/URL=", GST_TAG_LICENSE_URI}, {
2204     "LICENSE/URL=", GST_TAG_LICENSE_URI}
2205   };
2206   /* *INDENT-ON* */
2207   GstFlowReturn ret;
2208   guint32 id;
2209   gchar *value = NULL;
2210   gchar *tag = NULL;
2211   gchar *name_with_parent = NULL;
2212   GstTagList *child_taglist = NULL;
2213
2214   DEBUG_ELEMENT_START (common, ebml, "SimpleTag");
2215
2216   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2217     DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
2218     return ret;
2219   }
2220
2221   if (parent)
2222     child_taglist = *p_taglist;
2223   else
2224     child_taglist = gst_tag_list_new_empty ();
2225
2226   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2227     /* read all sub-entries */
2228
2229     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2230       break;
2231
2232     switch (id) {
2233       case GST_MATROSKA_ID_TAGNAME:
2234         g_free (tag);
2235         tag = NULL;
2236         ret = gst_ebml_read_ascii (ebml, &id, &tag);
2237         GST_DEBUG_OBJECT (common->sinkpad, "TagName: %s", GST_STR_NULL (tag));
2238         g_free (name_with_parent);
2239         if (parent != NULL)
2240           name_with_parent = g_strdup_printf ("%s/%s", parent, tag);
2241         else
2242           name_with_parent = g_strdup (tag);
2243         break;
2244
2245       case GST_MATROSKA_ID_TAGSTRING:
2246         g_free (value);
2247         value = NULL;
2248         ret = gst_ebml_read_utf8 (ebml, &id, &value);
2249         GST_DEBUG_OBJECT (common->sinkpad, "TagString: %s",
2250             GST_STR_NULL (value));
2251         break;
2252
2253       case GST_MATROSKA_ID_SIMPLETAG:
2254         /* Recursive SimpleTag */
2255         /* This implementation requires tag name of _this_ tag to be known
2256          * in order to read its children. It's not in the spec, just the way
2257          * the code is written.
2258          */
2259         if (name_with_parent != NULL) {
2260           ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
2261               ebml, &child_taglist, name_with_parent);
2262           break;
2263         }
2264         /* fall-through */
2265
2266       default:
2267         ret = gst_matroska_read_common_parse_skip (common, ebml, "SimpleTag",
2268             id);
2269         break;
2270
2271       case GST_MATROSKA_ID_TAGLANGUAGE:
2272       case GST_MATROSKA_ID_TAGDEFAULT:
2273       case GST_MATROSKA_ID_TAGBINARY:
2274         ret = gst_ebml_read_skip (ebml);
2275         break;
2276     }
2277   }
2278
2279   DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
2280
2281   if (parent && tag && value && *value != '\0') {
2282     /* Don't bother mapping children tags - parent will do that */
2283     gchar *key_val;
2284     /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
2285     key_val = g_strdup_printf ("%s=%s", name_with_parent, value);
2286     gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2287         GST_TAG_EXTENDED_COMMENT, key_val, NULL);
2288     g_free (key_val);
2289   } else if (tag && value && *value != '\0') {
2290     gboolean matched = FALSE;
2291     guint i;
2292
2293     for (i = 0; !matched && i < G_N_ELEMENTS (tag_conv); i++) {
2294       const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
2295
2296       const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
2297
2298       if (strcmp (tagname_mkv, tag) == 0) {
2299         GValue dest = { 0, };
2300         GType dest_type = gst_tag_get_type (tagname_gst);
2301
2302         /* Ensure that any date string is complete */
2303         if (dest_type == G_TYPE_DATE) {
2304           guint year = 1901, month = 1, day = 1;
2305
2306           /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
2307            * the first type */
2308           if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
2309             g_free (value);
2310             value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
2311           }
2312         }
2313
2314         g_value_init (&dest, dest_type);
2315         if (gst_value_deserialize (&dest, value)) {
2316           gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2317               tagname_gst, &dest, NULL);
2318         } else {
2319           GST_WARNING_OBJECT (common->sinkpad, "Can't transform tag '%s' with "
2320               "value '%s' to target type '%s'", tag, value,
2321               g_type_name (dest_type));
2322         }
2323         g_value_unset (&dest);
2324         matched = TRUE;
2325       }
2326     }
2327     if (!matched) {
2328       gchar *key_val;
2329       /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
2330       key_val = g_strdup_printf ("%s=%s", tag, value);
2331       gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2332           GST_TAG_EXTENDED_COMMENT, key_val, NULL);
2333       g_free (key_val);
2334     }
2335   }
2336
2337   if (!parent) {
2338     /* Map children tags. This only supports top-anchored mapping. That is,
2339      * we start at toplevel tag (this tag), and see how its combinations
2340      * with its children can be mapped. Which means that grandchildren
2341      * are also combined here, with _this_ tag taken into consideration.
2342      * If grandchildren can be combined only with children, that combination
2343      * will not happen.
2344      */
2345     gint child_tags_n = gst_tag_list_n_tags (child_taglist);
2346     if (child_tags_n > 0) {
2347       gint i;
2348       for (i = 0; i < child_tags_n; i++) {
2349         gint j;
2350         const gchar *child_name = gst_tag_list_nth_tag_name (child_taglist, i);
2351         guint taglen = gst_tag_list_get_tag_size (child_taglist, child_name);
2352         for (j = 0; j < taglen; j++) {
2353           gchar *val;
2354           gboolean matched = FALSE;
2355           gchar *val_pre, *val_post;
2356           gint k;
2357
2358           if (!gst_tag_list_get_string_index (child_taglist, child_name,
2359                   j, &val))
2360             continue;
2361           if (!strchr (val, '=')) {
2362             g_free (val);
2363             continue;
2364           }
2365           val_post = g_strdup (strchr (val, '=') + 1);
2366           val_pre = g_strdup (val);
2367           *(strchr (val_pre, '=') + 1) = '\0';
2368
2369           for (k = 0; !matched && k < G_N_ELEMENTS (child_tag_conv); k++) {
2370             const gchar *tagname_gst = child_tag_conv[k].gstreamer_tagname;
2371
2372             const gchar *tagname_mkv = child_tag_conv[k].matroska_tagname;
2373
2374             /* TODO: Once "key[lc]=value" form support is implemented,
2375              * strip [lc] here. It can't be used in combined tags.
2376              * If a tag is not combined, leave [lc] as it is.
2377              */
2378             if (strcmp (tagname_mkv, val_pre) == 0) {
2379               GValue dest = { 0, };
2380               GType dest_type = gst_tag_get_type (tagname_gst);
2381
2382               g_value_init (&dest, dest_type);
2383               if (gst_value_deserialize (&dest, val_post)) {
2384                 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2385                     tagname_gst, &dest, NULL);
2386               } else {
2387                 GST_WARNING_OBJECT (common->sinkpad,
2388                     "Can't transform complex tag '%s' " "to target type '%s'",
2389                     val, g_type_name (dest_type));
2390               }
2391               g_value_unset (&dest);
2392               matched = TRUE;
2393             }
2394           }
2395           if (!matched) {
2396             gchar *last_slash = strrchr (val_pre, '/');
2397             if (last_slash) {
2398               last_slash++;
2399               if (strcmp (last_slash, "EMAIL=") == 0 ||
2400                   strcmp (last_slash, "PHONE=") == 0 ||
2401                   strcmp (last_slash, "ADDRESS=") == 0 ||
2402                   strcmp (last_slash, "FAX=") == 0) {
2403                 gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2404                     GST_TAG_CONTACT, val_post, NULL);
2405                 matched = TRUE;
2406               }
2407             }
2408           }
2409           if (!matched)
2410             gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2411                 GST_TAG_EXTENDED_COMMENT, val, NULL);
2412           g_free (val_post);
2413           g_free (val_pre);
2414           g_free (val);
2415         }
2416       }
2417     }
2418     gst_tag_list_unref (child_taglist);
2419   }
2420
2421   g_free (tag);
2422   g_free (value);
2423   g_free (name_with_parent);
2424
2425   return ret;
2426 }
2427
2428
2429 static void
2430 gst_matroska_read_common_count_streams (GstMatroskaReadCommon * common,
2431     gint * a, gint * v, gint * s)
2432 {
2433   gint i;
2434   gint video_streams = 0, audio_streams = 0, subtitle_streams = 0;
2435
2436   for (i = 0; i < common->src->len; i++) {
2437     GstMatroskaTrackContext *stream;
2438
2439     stream = g_ptr_array_index (common->src, i);
2440     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2441       video_streams += 1;
2442     else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
2443       audio_streams += 1;
2444     else if (stream->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2445       subtitle_streams += 1;
2446   }
2447   *v = video_streams;
2448   *a = audio_streams;
2449   *s = subtitle_streams;
2450 }
2451
2452
2453 static void
2454 gst_matroska_read_common_apply_target_type_foreach (const GstTagList * list,
2455     const gchar * tag, gpointer user_data)
2456 {
2457   guint vallen;
2458   guint i;
2459   TargetTypeContext *ctx = (TargetTypeContext *) user_data;
2460
2461   vallen = gst_tag_list_get_tag_size (list, tag);
2462   if (vallen == 0)
2463     return;
2464
2465   for (i = 0; i < vallen; i++) {
2466     const GValue *val_ref;
2467
2468     val_ref = gst_tag_list_get_value_index (list, tag, i);
2469     if (val_ref == NULL)
2470       continue;
2471
2472     /* TODO: use the optional ctx->target_type somehow */
2473     if (strcmp (tag, GST_TAG_TITLE) == 0) {
2474       if (ctx->target_type_value >= 70 && !ctx->audio_only) {
2475         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2476             GST_TAG_SHOW_NAME, val_ref);
2477         continue;
2478       } else if (ctx->target_type_value >= 50) {
2479         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2480             GST_TAG_TITLE, val_ref);
2481         continue;
2482       }
2483     } else if (strcmp (tag, GST_TAG_TITLE_SORTNAME) == 0) {
2484       if (ctx->target_type_value >= 70 && !ctx->audio_only) {
2485         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2486             GST_TAG_SHOW_SORTNAME, val_ref);
2487         continue;
2488       } else if (ctx->target_type_value >= 50) {
2489         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2490             GST_TAG_TITLE_SORTNAME, val_ref);
2491         continue;
2492       }
2493     } else if (strcmp (tag, GST_TAG_ARTIST) == 0) {
2494       if (ctx->target_type_value >= 50) {
2495         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2496             GST_TAG_ARTIST, val_ref);
2497         continue;
2498       }
2499     } else if (strcmp (tag, GST_TAG_ARTIST_SORTNAME) == 0) {
2500       if (ctx->target_type_value >= 50) {
2501         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2502             GST_TAG_ARTIST_SORTNAME, val_ref);
2503         continue;
2504       }
2505     } else if (strcmp (tag, GST_TAG_TRACK_COUNT) == 0) {
2506       if (ctx->target_type_value >= 60) {
2507         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2508             GST_TAG_ALBUM_VOLUME_COUNT, val_ref);
2509         continue;
2510       }
2511     } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) {
2512       if (ctx->target_type_value >= 60 && !ctx->audio_only) {
2513         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2514             GST_TAG_SHOW_SEASON_NUMBER, val_ref);
2515         continue;
2516       } else if (ctx->target_type_value >= 50 && !ctx->audio_only) {
2517         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2518             GST_TAG_SHOW_EPISODE_NUMBER, val_ref);
2519         continue;
2520       } else if (ctx->target_type_value >= 50) {
2521         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2522             GST_TAG_ALBUM_VOLUME_NUMBER, val_ref);
2523         continue;
2524       }
2525     }
2526     gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND, tag, val_ref);
2527   }
2528 }
2529
2530
2531 static GstTagList *
2532 gst_matroska_read_common_apply_target_type (GstMatroskaReadCommon * common,
2533     GstTagList * taglist, guint64 target_type_value, gchar * target_type)
2534 {
2535   TargetTypeContext ctx;
2536   gint a = 0;
2537   gint v = 0;
2538   gint s = 0;
2539
2540   gst_matroska_read_common_count_streams (common, &a, &v, &s);
2541
2542   ctx.audio_only = (a > 0 && v == 0 && s == 0);
2543   ctx.result = gst_tag_list_new_empty ();
2544   ctx.target_type_value = target_type_value;
2545   ctx.target_type = target_type;
2546
2547   gst_tag_list_foreach (taglist,
2548       gst_matroska_read_common_apply_target_type_foreach, &ctx);
2549
2550   gst_tag_list_unref (taglist);
2551   return ctx.result;
2552 }
2553
2554
2555 static GstFlowReturn
2556 gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
2557     GstEbmlRead * ebml, GstTagList ** p_taglist)
2558 {
2559   guint32 id;
2560   GstFlowReturn ret;
2561   GArray *chapter_targets, *edition_targets, *track_targets;
2562   GstTagList *taglist;
2563   GList *cur, *internal_cur;
2564   guint64 target_type_value = 50;
2565   gchar *target_type = NULL;
2566
2567   DEBUG_ELEMENT_START (common, ebml, "Tag");
2568
2569   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2570     DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
2571     return ret;
2572   }
2573
2574   edition_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2575   chapter_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2576   track_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2577   taglist = gst_tag_list_new_empty ();
2578   target_type = NULL;
2579
2580   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2581     /* read all sub-entries */
2582
2583     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2584       break;
2585
2586     switch (id) {
2587       case GST_MATROSKA_ID_SIMPLETAG:
2588         ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
2589             ebml, &taglist, NULL);
2590         break;
2591
2592       case GST_MATROSKA_ID_TARGETS:
2593         g_free (target_type);
2594         target_type = NULL;
2595         target_type_value = 50;
2596         ret = gst_matroska_read_common_parse_metadata_targets (common, ebml,
2597             edition_targets, chapter_targets, track_targets,
2598             &target_type_value, &target_type);
2599         break;
2600
2601       default:
2602         ret = gst_matroska_read_common_parse_skip (common, ebml, "Tag", id);
2603         break;
2604     }
2605   }
2606
2607   DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
2608
2609   taglist = gst_matroska_read_common_apply_target_type (common, taglist,
2610       target_type_value, target_type);
2611   g_free (target_type);
2612
2613   /* if tag is chapter/edition specific - try to find that entry */
2614   if (G_UNLIKELY (chapter_targets->len > 0 || edition_targets->len > 0 ||
2615           track_targets->len > 0)) {
2616     gint i;
2617     if (chapter_targets->len > 0 || edition_targets->len > 0) {
2618       if (common->toc == NULL)
2619         GST_WARNING_OBJECT (common->sinkpad,
2620             "Found chapter/edition specific tag, but TOC is not present");
2621       else {
2622         cur = gst_toc_get_entries (common->toc);
2623         internal_cur = gst_toc_get_entries (common->internal_toc);
2624         while (cur != NULL && internal_cur != NULL) {
2625           gst_matroska_read_common_parse_toc_tag (cur->data, internal_cur->data,
2626               edition_targets, chapter_targets, taglist);
2627           cur = cur->next;
2628           internal_cur = internal_cur->next;
2629         }
2630         common->toc_updated = TRUE;
2631       }
2632     }
2633     for (i = 0; i < track_targets->len; i++) {
2634       gint j;
2635       gboolean found = FALSE;
2636       guint64 tgt = g_array_index (track_targets, guint64, i);
2637
2638       for (j = 0; j < common->src->len; j++) {
2639         GstMatroskaTrackContext *stream = g_ptr_array_index (common->src, j);
2640
2641         if (stream->uid == tgt) {
2642           gst_tag_list_insert (stream->tags, taglist, GST_TAG_MERGE_REPLACE);
2643           stream->tags_changed = TRUE;
2644           found = TRUE;
2645         }
2646       }
2647       if (!found) {
2648         /* Cache the track taglist: possibly belongs to a track that will be parsed
2649            later in gst_matroska_demux.c:gst_matroska_demux_add_stream (...) */
2650         gpointer track_uid = GUINT_TO_POINTER (tgt);
2651         GstTagList *cached_taglist =
2652             g_hash_table_lookup (common->cached_track_taglists, track_uid);
2653         if (cached_taglist)
2654           gst_tag_list_insert (cached_taglist, taglist, GST_TAG_MERGE_REPLACE);
2655         else {
2656           gst_tag_list_ref (taglist);
2657           g_hash_table_insert (common->cached_track_taglists, track_uid,
2658               taglist);
2659         }
2660         GST_DEBUG_OBJECT (common->sinkpad,
2661             "Found track-specific tag(s), but track %" G_GUINT64_FORMAT
2662             " is not known yet, caching", tgt);
2663       }
2664     }
2665   } else
2666     gst_tag_list_insert (*p_taglist, taglist, GST_TAG_MERGE_APPEND);
2667
2668   gst_tag_list_unref (taglist);
2669   g_array_unref (chapter_targets);
2670   g_array_unref (edition_targets);
2671   g_array_unref (track_targets);
2672
2673   return ret;
2674 }
2675
2676 GstFlowReturn
2677 gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common,
2678     GstElement * el, GstEbmlRead * ebml)
2679 {
2680   GstTagList *taglist;
2681   GstFlowReturn ret = GST_FLOW_OK;
2682   guint32 id;
2683   GList *l;
2684   guint64 curpos;
2685
2686   /* Make sure we don't parse a tags element twice and
2687    * post it's tags twice */
2688   curpos = gst_ebml_read_get_pos (ebml);
2689   for (l = common->tags_parsed; l; l = l->next) {
2690     guint64 *pos = l->data;
2691
2692     if (*pos == curpos) {
2693       GST_DEBUG_OBJECT (common->sinkpad,
2694           "Skipping already parsed Tags at offset %" G_GUINT64_FORMAT, curpos);
2695       return GST_FLOW_OK;
2696     }
2697   }
2698
2699   common->tags_parsed =
2700       g_list_prepend (common->tags_parsed, g_slice_new (guint64));
2701   *((guint64 *) common->tags_parsed->data) = curpos;
2702   /* fall-through */
2703
2704   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2705     DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
2706     return ret;
2707   }
2708
2709   taglist = gst_tag_list_new_empty ();
2710   gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
2711   common->toc_updated = FALSE;
2712
2713   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2714     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2715       break;
2716
2717     switch (id) {
2718       case GST_MATROSKA_ID_TAG:
2719         ret = gst_matroska_read_common_parse_metadata_id_tag (common, ebml,
2720             &taglist);
2721         break;
2722
2723       default:
2724         ret = gst_matroska_read_common_parse_skip (common, ebml, "Tags", id);
2725         break;
2726         /* FIXME: Use to limit the tags to specific pads */
2727     }
2728   }
2729
2730   DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
2731
2732   if (G_LIKELY (!gst_tag_list_is_empty (taglist)))
2733     gst_matroska_read_common_found_global_tag (common, el, taglist);
2734   else
2735     gst_tag_list_unref (taglist);
2736
2737   return ret;
2738 }
2739
2740 static GstFlowReturn
2741 gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
2742     peek, const guint8 ** data)
2743 {
2744   /* Caller needs to gst_adapter_unmap. */
2745   *data = gst_adapter_map (common->adapter, peek);
2746   if (*data == NULL)
2747     return GST_FLOW_EOS;
2748
2749   return GST_FLOW_OK;
2750 }
2751
2752 /*
2753  * Calls pull_range for (offset,size) without advancing our offset
2754  */
2755 GstFlowReturn
2756 gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
2757     offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
2758 {
2759   GstFlowReturn ret;
2760
2761   /* Caching here actually makes much less difference than one would expect.
2762    * We do it mainly to avoid pulling buffers of 1 byte all the time */
2763   if (common->cached_buffer) {
2764     guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
2765     gsize cache_size = gst_buffer_get_size (common->cached_buffer);
2766
2767     if (cache_offset <= common->offset &&
2768         (common->offset + size) <= (cache_offset + cache_size)) {
2769       if (p_buf)
2770         *p_buf = gst_buffer_copy_region (common->cached_buffer,
2771             GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
2772       if (bytes) {
2773         if (!common->cached_data) {
2774           gst_buffer_map (common->cached_buffer, &common->cached_map,
2775               GST_MAP_READ);
2776           common->cached_data = common->cached_map.data;
2777         }
2778         *bytes = common->cached_data + common->offset - cache_offset;
2779       }
2780       return GST_FLOW_OK;
2781     }
2782     /* not enough data in the cache, free cache and get a new one */
2783     if (common->cached_data) {
2784       gst_buffer_unmap (common->cached_buffer, &common->cached_map);
2785       common->cached_data = NULL;
2786     }
2787     gst_buffer_unref (common->cached_buffer);
2788     common->cached_buffer = NULL;
2789   }
2790
2791   /* refill the cache */
2792   ret = gst_pad_pull_range (common->sinkpad, common->offset,
2793       MAX (size, 64 * 1024), &common->cached_buffer);
2794   if (ret != GST_FLOW_OK) {
2795     common->cached_buffer = NULL;
2796     return ret;
2797   }
2798
2799   if (gst_buffer_get_size (common->cached_buffer) >= size) {
2800     if (p_buf)
2801       *p_buf = gst_buffer_copy_region (common->cached_buffer,
2802           GST_BUFFER_COPY_ALL, 0, size);
2803     if (bytes) {
2804       gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2805       common->cached_data = common->cached_map.data;
2806       *bytes = common->cached_data;
2807     }
2808     return GST_FLOW_OK;
2809   }
2810
2811   /* Not possible to get enough data, try a last time with
2812    * requesting exactly the size we need */
2813   gst_buffer_unref (common->cached_buffer);
2814   common->cached_buffer = NULL;
2815
2816   ret =
2817       gst_pad_pull_range (common->sinkpad, common->offset, size,
2818       &common->cached_buffer);
2819   if (ret != GST_FLOW_OK) {
2820     GST_DEBUG_OBJECT (common->sinkpad, "pull_range returned %d", ret);
2821     if (p_buf)
2822       *p_buf = NULL;
2823     if (bytes)
2824       *bytes = NULL;
2825     return ret;
2826   }
2827
2828   if (gst_buffer_get_size (common->cached_buffer) < size) {
2829     GST_WARNING_OBJECT (common->sinkpad, "Dropping short buffer at offset %"
2830         G_GUINT64_FORMAT ": wanted %u bytes, got %" G_GSIZE_FORMAT " bytes",
2831         common->offset, size, gst_buffer_get_size (common->cached_buffer));
2832
2833     gst_buffer_unref (common->cached_buffer);
2834     common->cached_buffer = NULL;
2835     if (p_buf)
2836       *p_buf = NULL;
2837     if (bytes)
2838       *bytes = NULL;
2839     return GST_FLOW_EOS;
2840   }
2841
2842   if (p_buf)
2843     *p_buf = gst_buffer_copy_region (common->cached_buffer,
2844         GST_BUFFER_COPY_ALL, 0, size);
2845   if (bytes) {
2846     gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2847     common->cached_data = common->cached_map.data;
2848     *bytes = common->cached_data;
2849   }
2850
2851   return GST_FLOW_OK;
2852 }
2853
2854 static GstFlowReturn
2855 gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek,
2856     guint8 ** data)
2857 {
2858   return gst_matroska_read_common_peek_bytes (common, common->offset, peek,
2859       NULL, data);
2860 }
2861
2862 GstFlowReturn
2863 gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
2864     GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2865 {
2866   return gst_ebml_peek_id_length (_id, _length, _needed,
2867       (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
2868       common->offset);
2869 }
2870
2871 GstFlowReturn
2872 gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
2873     GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2874 {
2875   GstFlowReturn ret;
2876
2877   ret = gst_ebml_peek_id_length (_id, _length, _needed,
2878       (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
2879       el, common->offset);
2880
2881   gst_adapter_unmap (common->adapter);
2882
2883   return ret;
2884 }
2885
2886 static GstFlowReturn
2887 gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
2888     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
2889 {
2890   GstMatroskaTrackEncoding enc = { 0, };
2891   GstFlowReturn ret;
2892   guint32 id;
2893
2894   DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
2895   /* Set default values */
2896   enc.scope = 1;
2897   /* All other default values are 0 */
2898
2899   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2900     DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
2901     return ret;
2902   }
2903
2904   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2905     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2906       break;
2907
2908     switch (id) {
2909       case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
2910         guint64 num;
2911
2912         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2913           break;
2914
2915         if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
2916                 num)) {
2917           GST_ERROR_OBJECT (common->sinkpad,
2918               "ContentEncodingOrder %" G_GUINT64_FORMAT
2919               "is not unique for track %" G_GUINT64_FORMAT, num, context->num);
2920           ret = GST_FLOW_ERROR;
2921           break;
2922         }
2923
2924         GST_DEBUG_OBJECT (common->sinkpad,
2925             "ContentEncodingOrder: %" G_GUINT64_FORMAT, num);
2926         enc.order = num;
2927         break;
2928       }
2929       case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
2930         guint64 num;
2931
2932         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2933           break;
2934
2935         if (num > 7 || num == 0) {
2936           GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncodingScope %"
2937               G_GUINT64_FORMAT, num);
2938           ret = GST_FLOW_ERROR;
2939           break;
2940         }
2941
2942         GST_DEBUG_OBJECT (common->sinkpad,
2943             "ContentEncodingScope: %" G_GUINT64_FORMAT, num);
2944         enc.scope = num;
2945
2946         break;
2947       }
2948       case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
2949         guint64 num;
2950
2951         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2952           break;
2953
2954         if (num > 1) {
2955           GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncodingType %"
2956               G_GUINT64_FORMAT, num);
2957           ret = GST_FLOW_ERROR;
2958           break;
2959         }
2960
2961         if ((!common->is_webm) && (num == GST_MATROSKA_ENCODING_ENCRYPTION)) {
2962           GST_ERROR_OBJECT (common->sinkpad,
2963               "Encrypted tracks are supported only in WebM");
2964           ret = GST_FLOW_ERROR;
2965           break;
2966         }
2967         GST_DEBUG_OBJECT (common->sinkpad,
2968             "ContentEncodingType: %" G_GUINT64_FORMAT, num);
2969         enc.type = num;
2970         break;
2971       }
2972       case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
2973
2974         DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
2975
2976         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
2977           break;
2978
2979         while (ret == GST_FLOW_OK &&
2980             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2981           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2982             break;
2983
2984           switch (id) {
2985             case GST_MATROSKA_ID_CONTENTCOMPALGO:{
2986               guint64 num;
2987
2988               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
2989                 break;
2990               }
2991               if (num > 3) {
2992                 GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentCompAlgo %"
2993                     G_GUINT64_FORMAT, num);
2994                 ret = GST_FLOW_ERROR;
2995                 break;
2996               }
2997               GST_DEBUG_OBJECT (common->sinkpad,
2998                   "ContentCompAlgo: %" G_GUINT64_FORMAT, num);
2999               enc.comp_algo = num;
3000
3001               break;
3002             }
3003             case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
3004               guint8 *data;
3005               guint64 size;
3006
3007               if ((ret =
3008                       gst_ebml_read_binary (ebml, &id, &data,
3009                           &size)) != GST_FLOW_OK) {
3010                 break;
3011               }
3012               enc.comp_settings = data;
3013               enc.comp_settings_length = size;
3014               GST_DEBUG_OBJECT (common->sinkpad,
3015                   "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
3016               break;
3017             }
3018             default:
3019               GST_WARNING_OBJECT (common->sinkpad,
3020                   "Unknown ContentCompression subelement 0x%x - ignoring", id);
3021               ret = gst_ebml_read_skip (ebml);
3022               break;
3023           }
3024         }
3025         DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
3026         break;
3027       }
3028
3029       case GST_MATROSKA_ID_CONTENTENCRYPTION:{
3030
3031         DEBUG_ELEMENT_START (common, ebml, "ContentEncryption");
3032
3033         if (enc.type != GST_MATROSKA_ENCODING_ENCRYPTION) {
3034           GST_WARNING_OBJECT (common->sinkpad,
3035               "Unexpected to have Content Encryption because it isn't encryption type");
3036           ret = GST_FLOW_ERROR;
3037           break;
3038         }
3039
3040         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
3041           break;
3042
3043         while (ret == GST_FLOW_OK &&
3044             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3045           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3046             break;
3047
3048           switch (id) {
3049             case GST_MATROSKA_ID_CONTENTENCALGO:{
3050               guint64 num;
3051
3052               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
3053                 break;
3054               }
3055
3056               if (num > GST_MATROSKA_TRACK_ENCRYPTION_ALGORITHM_AES) {
3057                 GST_ERROR_OBJECT (common->sinkpad, "Invalid ContentEncAlgo %"
3058                     G_GUINT64_FORMAT, num);
3059                 ret = GST_FLOW_ERROR;
3060                 break;
3061               }
3062               GST_DEBUG_OBJECT (common->sinkpad,
3063                   "ContentEncAlgo: %" G_GUINT64_FORMAT, num);
3064               enc.enc_algo = num;
3065
3066               break;
3067             }
3068             case GST_MATROSKA_ID_CONTENTENCAESSETTINGS:{
3069
3070               DEBUG_ELEMENT_START (common, ebml, "ContentEncAESSettings");
3071
3072               if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
3073                 break;
3074
3075               while (ret == GST_FLOW_OK &&
3076                   gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3077                 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3078                   break;
3079
3080                 switch (id) {
3081                   case GST_MATROSKA_ID_AESSETTINGSCIPHERMODE:{
3082                     guint64 num;
3083
3084                     if ((ret =
3085                             gst_ebml_read_uint (ebml, &id,
3086                                 &num)) != GST_FLOW_OK) {
3087                       break;
3088                     }
3089                     if (num > 3) {
3090                       GST_ERROR_OBJECT (common->sinkpad, "Invalid Cipher Mode %"
3091                           G_GUINT64_FORMAT, num);
3092                       ret = GST_FLOW_ERROR;
3093                       break;
3094                     }
3095                     GST_DEBUG_OBJECT (common->sinkpad,
3096                         "ContentEncAESSettings: %" G_GUINT64_FORMAT, num);
3097                     enc.enc_cipher_mode = num;
3098                     break;
3099                   }
3100                   default:
3101                     GST_WARNING_OBJECT (common->sinkpad,
3102                         "Unknown ContentEncAESSettings subelement 0x%x - ignoring",
3103                         id);
3104                     ret = gst_ebml_read_skip (ebml);
3105                     break;
3106                 }
3107               }
3108               DEBUG_ELEMENT_STOP (common, ebml, "ContentEncAESSettings", ret);
3109               break;
3110             }
3111
3112             case GST_MATROSKA_ID_CONTENTENCKEYID:{
3113               guint8 *data;
3114               guint64 size;
3115               GstBuffer *keyId_buf;
3116               GstEvent *event;
3117
3118               if ((ret =
3119                       gst_ebml_read_binary (ebml, &id, &data,
3120                           &size)) != GST_FLOW_OK) {
3121                 break;
3122               }
3123               GST_DEBUG_OBJECT (common->sinkpad,
3124                   "ContentEncrypt KeyID length : %" G_GUINT64_FORMAT, size);
3125               keyId_buf = gst_buffer_new_wrapped (data, size);
3126
3127               /* Push an event containing the Key ID into the queues of all streams. */
3128               /* system_id field is set to GST_PROTECTION_UNSPECIFIED_SYSTEM_ID because it isn't specified neither in WebM nor in Matroska spec. */
3129               event =
3130                   gst_event_new_protection
3131                   (GST_PROTECTION_UNSPECIFIED_SYSTEM_ID, keyId_buf,
3132                   "matroskademux");
3133               GST_TRACE_OBJECT (common->sinkpad,
3134                   "adding protection event for stream %d", context->index);
3135               g_queue_push_tail (&context->protection_event_queue, event);
3136
3137               context->protection_info =
3138                   gst_structure_new ("application/x-cenc", "iv_size",
3139                   G_TYPE_UINT, 8, "encrypted", G_TYPE_BOOLEAN, TRUE, "kid",
3140                   GST_TYPE_BUFFER, keyId_buf, NULL);
3141
3142               gst_buffer_unref (keyId_buf);
3143               break;
3144             }
3145             default:
3146               GST_WARNING_OBJECT (common->sinkpad,
3147                   "Unknown ContentEncryption subelement 0x%x - ignoring", id);
3148               ret = gst_ebml_read_skip (ebml);
3149               break;
3150           }
3151         }
3152         DEBUG_ELEMENT_STOP (common, ebml, "ContentEncryption", ret);
3153         break;
3154       }
3155       default:
3156         GST_WARNING_OBJECT (common->sinkpad,
3157             "Unknown ContentEncoding subelement 0x%x - ignoring", id);
3158         ret = gst_ebml_read_skip (ebml);
3159         break;
3160     }
3161   }
3162
3163   DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
3164   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3165     return ret;
3166
3167   /* TODO: Check if the combination of values is valid */
3168
3169   g_array_append_val (context->encodings, enc);
3170
3171   return ret;
3172 }
3173
3174 GstFlowReturn
3175 gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
3176     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
3177 {
3178   GstFlowReturn ret;
3179   guint32 id;
3180
3181   DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");
3182
3183   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3184     DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
3185     return ret;
3186   }
3187
3188   context->encodings =
3189       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
3190
3191   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3192     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3193       break;
3194
3195     switch (id) {
3196       case GST_MATROSKA_ID_CONTENTENCODING:
3197         ret = gst_matroska_read_common_read_track_encoding (common, ebml,
3198             context);
3199         break;
3200       default:
3201         GST_WARNING_OBJECT (common->sinkpad,
3202             "Unknown ContentEncodings subelement 0x%x - ignoring", id);
3203         ret = gst_ebml_read_skip (ebml);
3204         break;
3205     }
3206   }
3207
3208   DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
3209   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3210     return ret;
3211
3212   /* Sort encodings according to their order */
3213   g_array_sort (context->encodings,
3214       (GCompareFunc) gst_matroska_read_common_encoding_cmp);
3215
3216   return gst_matroska_decode_content_encodings (context->encodings);
3217 }
3218
3219 void
3220 gst_matroska_read_common_free_parsed_el (gpointer mem, gpointer user_data)
3221 {
3222   g_slice_free (guint64, mem);
3223 }
3224
3225 void
3226 gst_matroska_read_common_init (GstMatroskaReadCommon * ctx)
3227 {
3228   ctx->src = NULL;
3229   ctx->writing_app = NULL;
3230   ctx->muxing_app = NULL;
3231   ctx->index = NULL;
3232   ctx->global_tags = NULL;
3233   ctx->adapter = gst_adapter_new ();
3234   ctx->toc = NULL;
3235   ctx->internal_toc = NULL;
3236   ctx->toc_updated = FALSE;
3237   ctx->cached_track_taglists =
3238       g_hash_table_new_full (NULL, NULL, NULL,
3239       (GDestroyNotify) gst_tag_list_unref);
3240 }
3241
3242 void
3243 gst_matroska_read_common_finalize (GstMatroskaReadCommon * ctx)
3244 {
3245   if (ctx->src) {
3246     g_ptr_array_free (ctx->src, TRUE);
3247     ctx->src = NULL;
3248   }
3249
3250   if (ctx->global_tags) {
3251     gst_tag_list_unref (ctx->global_tags);
3252     ctx->global_tags = NULL;
3253   }
3254
3255   if (ctx->toc) {
3256     gst_toc_unref (ctx->toc);
3257     ctx->toc = NULL;
3258   }
3259   if (ctx->internal_toc) {
3260     gst_toc_unref (ctx->internal_toc);
3261     ctx->internal_toc = NULL;
3262   }
3263
3264   ctx->toc_updated = FALSE;
3265
3266   g_object_unref (ctx->adapter);
3267   g_hash_table_remove_all (ctx->cached_track_taglists);
3268   g_hash_table_unref (ctx->cached_track_taglists);
3269
3270 }
3271
3272 void
3273 gst_matroska_read_common_reset (GstElement * element,
3274     GstMatroskaReadCommon * ctx)
3275 {
3276   guint i;
3277
3278   GST_LOG_OBJECT (ctx->sinkpad, "resetting read context");
3279
3280   /* reset input */
3281   ctx->state = GST_MATROSKA_READ_STATE_START;
3282
3283   /* clean up existing streams if any */
3284   if (ctx->src) {
3285     g_assert (ctx->src->len == ctx->num_streams);
3286     for (i = 0; i < ctx->src->len; i++) {
3287       GstMatroskaTrackContext *context = g_ptr_array_index (ctx->src, i);
3288
3289       if (context->pad != NULL)
3290         gst_element_remove_pad (element, context->pad);
3291
3292       gst_matroska_track_free (context);
3293     }
3294     g_ptr_array_free (ctx->src, TRUE);
3295   }
3296   ctx->src = g_ptr_array_new ();
3297   ctx->num_streams = 0;
3298
3299   /* reset media info */
3300   g_free (ctx->writing_app);
3301   ctx->writing_app = NULL;
3302   g_free (ctx->muxing_app);
3303   ctx->muxing_app = NULL;
3304
3305   /* reset stream type */
3306   ctx->is_webm = FALSE;
3307   ctx->has_video = FALSE;
3308
3309   /* reset indexes */
3310   if (ctx->index) {
3311     g_array_free (ctx->index, TRUE);
3312     ctx->index = NULL;
3313   }
3314
3315   /* reset timers */
3316   ctx->time_scale = 1000000;
3317   ctx->created = G_MININT64;
3318
3319   /* cues/tracks/segmentinfo */
3320   ctx->index_parsed = FALSE;
3321   ctx->segmentinfo_parsed = FALSE;
3322   ctx->attachments_parsed = FALSE;
3323   ctx->chapters_parsed = FALSE;
3324
3325   /* tags */
3326   ctx->global_tags_changed = FALSE;
3327   g_list_foreach (ctx->tags_parsed,
3328       (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
3329   g_list_free (ctx->tags_parsed);
3330   ctx->tags_parsed = NULL;
3331   if (ctx->global_tags) {
3332     gst_tag_list_unref (ctx->global_tags);
3333   }
3334   ctx->global_tags = gst_tag_list_new_empty ();
3335   gst_tag_list_set_scope (ctx->global_tags, GST_TAG_SCOPE_GLOBAL);
3336
3337   gst_segment_init (&ctx->segment, GST_FORMAT_TIME);
3338   ctx->offset = 0;
3339   ctx->start_resync_offset = -1;
3340   ctx->state_to_restore = -1;
3341
3342   if (ctx->cached_buffer) {
3343     if (ctx->cached_data) {
3344       gst_buffer_unmap (ctx->cached_buffer, &ctx->cached_map);
3345       ctx->cached_data = NULL;
3346     }
3347     gst_buffer_unref (ctx->cached_buffer);
3348     ctx->cached_buffer = NULL;
3349   }
3350
3351   /* free chapters TOC if any */
3352   if (ctx->toc) {
3353     gst_toc_unref (ctx->toc);
3354     ctx->toc = NULL;
3355   }
3356   if (ctx->internal_toc) {
3357     gst_toc_unref (ctx->internal_toc);
3358     ctx->internal_toc = NULL;
3359   }
3360   ctx->toc_updated = FALSE;
3361 }
3362
3363 /* call with object lock held */
3364 void
3365 gst_matroska_read_common_reset_streams (GstMatroskaReadCommon * common,
3366     GstClockTime time, gboolean full)
3367 {
3368   gint i;
3369
3370   GST_DEBUG_OBJECT (common->sinkpad, "resetting stream state");
3371
3372   g_assert (common->src->len == common->num_streams);
3373   for (i = 0; i < common->src->len; i++) {
3374     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
3375     context->pos = time;
3376     context->set_discont = TRUE;
3377     context->eos = FALSE;
3378     context->from_time = GST_CLOCK_TIME_NONE;
3379     if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3380       GstMatroskaTrackVideoContext *videocontext =
3381           (GstMatroskaTrackVideoContext *) context;
3382       /* demux object lock held by caller */
3383       videocontext->earliest_time = GST_CLOCK_TIME_NONE;
3384     }
3385   }
3386 }
3387
3388 gboolean
3389 gst_matroska_read_common_tracknumber_unique (GstMatroskaReadCommon * common,
3390     guint64 num)
3391 {
3392   gint i;
3393
3394   g_assert (common->src->len == common->num_streams);
3395   for (i = 0; i < common->src->len; i++) {
3396     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
3397
3398     if (context->num == num)
3399       return FALSE;
3400   }
3401
3402   return TRUE;
3403 }