rtph264pay: avoid double buffer unmap on error
[platform/upstream/gstreamer.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
43 #include "lzo.h"
44
45 #include "ebml-read.h"
46 #include "matroska-read-common.h"
47
48 GST_DEBUG_CATEGORY (matroskareadcommon_debug);
49 #define GST_CAT_DEFAULT matroskareadcommon_debug
50
51 #define DEBUG_ELEMENT_START(common, ebml, element) \
52     GST_DEBUG_OBJECT (common, "Parsing " element " element at offset %" \
53         G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
54
55 #define DEBUG_ELEMENT_STOP(common, ebml, element, ret) \
56     GST_DEBUG_OBJECT (common, "Parsing " element " element " \
57         " finished with '%s'", gst_flow_get_name (ret))
58
59 #define GST_MATROSKA_TOC_UID_CHAPTER "chapter"
60 #define GST_MATROSKA_TOC_UID_EDITION "edition"
61 #define GST_MATROSKA_TOC_UID_EMPTY "empty"
62
63 typedef struct
64 {
65   GstTagList *result;
66   guint64 target_type_value;
67   gchar *target_type;
68   gboolean audio_only;
69 } TargetTypeContext;
70
71
72 static gboolean
73 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
74     gpointer * data_out, gsize * size_out,
75     GstMatroskaTrackCompressionAlgorithm algo)
76 {
77   guint8 *new_data = NULL;
78   guint new_size = 0;
79   guint8 *data = *data_out;
80   guint size = *size_out;
81   gboolean ret = TRUE;
82
83   if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
84 #ifdef HAVE_ZLIB
85     /* zlib encoded data */
86     z_stream zstream;
87     guint orig_size;
88     int result;
89
90     orig_size = size;
91     zstream.zalloc = (alloc_func) 0;
92     zstream.zfree = (free_func) 0;
93     zstream.opaque = (voidpf) 0;
94     if (inflateInit (&zstream) != Z_OK) {
95       GST_WARNING ("zlib initialization failed.");
96       ret = FALSE;
97       goto out;
98     }
99     zstream.next_in = (Bytef *) data;
100     zstream.avail_in = orig_size;
101     new_size = orig_size;
102     new_data = g_malloc (new_size);
103     zstream.avail_out = new_size;
104     zstream.next_out = (Bytef *) new_data;
105
106     do {
107       result = inflate (&zstream, Z_NO_FLUSH);
108       if (result != Z_OK && result != Z_STREAM_END) {
109         GST_WARNING ("zlib decompression failed.");
110         g_free (new_data);
111         inflateEnd (&zstream);
112         break;
113       }
114       new_size += 4000;
115       new_data = g_realloc (new_data, new_size);
116       zstream.next_out = (Bytef *) (new_data + zstream.total_out);
117       zstream.avail_out += 4000;
118     } while (zstream.avail_in != 0 && result != Z_STREAM_END);
119
120     if (result != Z_STREAM_END) {
121       ret = FALSE;
122       goto out;
123     } else {
124       new_size = zstream.total_out;
125       inflateEnd (&zstream);
126     }
127 #else
128     GST_WARNING ("zlib encoded tracks not supported.");
129     ret = FALSE;
130     goto out;
131 #endif
132   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
133 #ifdef HAVE_BZ2
134     /* bzip2 encoded data */
135     bz_stream bzstream;
136     guint orig_size;
137     int result;
138
139     bzstream.bzalloc = NULL;
140     bzstream.bzfree = NULL;
141     bzstream.opaque = NULL;
142     orig_size = size;
143
144     if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
145       GST_WARNING ("bzip2 initialization failed.");
146       ret = FALSE;
147       goto out;
148     }
149
150     bzstream.next_in = (char *) data;
151     bzstream.avail_in = orig_size;
152     new_size = orig_size;
153     new_data = g_malloc (new_size);
154     bzstream.avail_out = new_size;
155     bzstream.next_out = (char *) new_data;
156
157     do {
158       result = BZ2_bzDecompress (&bzstream);
159       if (result != BZ_OK && result != BZ_STREAM_END) {
160         GST_WARNING ("bzip2 decompression failed.");
161         g_free (new_data);
162         BZ2_bzDecompressEnd (&bzstream);
163         break;
164       }
165       new_size += 4000;
166       new_data = g_realloc (new_data, new_size);
167       bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
168       bzstream.avail_out += 4000;
169     } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
170
171     if (result != BZ_STREAM_END) {
172       ret = FALSE;
173       goto out;
174     } else {
175       new_size = bzstream.total_out_lo32;
176       BZ2_bzDecompressEnd (&bzstream);
177     }
178 #else
179     GST_WARNING ("bzip2 encoded tracks not supported.");
180     ret = FALSE;
181     goto out;
182 #endif
183   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
184     /* lzo encoded data */
185     int result;
186     int orig_size, out_size;
187
188     orig_size = size;
189     out_size = size;
190     new_size = size;
191     new_data = g_malloc (new_size);
192
193     do {
194       orig_size = size;
195       out_size = new_size;
196
197       result = lzo1x_decode (new_data, &out_size, data, &orig_size);
198
199       if (orig_size > 0) {
200         new_size += 4000;
201         new_data = g_realloc (new_data, new_size);
202       }
203     } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
204
205     new_size -= out_size;
206
207     if (result != LZO_OUTPUT_FULL) {
208       GST_WARNING ("lzo decompression failed");
209       g_free (new_data);
210
211       ret = FALSE;
212       goto out;
213     }
214
215   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
216     /* header stripped encoded data */
217     if (enc->comp_settings_length > 0) {
218       new_data = g_malloc (size + enc->comp_settings_length);
219       new_size = size + enc->comp_settings_length;
220
221       memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
222       memcpy (new_data + enc->comp_settings_length, data, size);
223     }
224   } else {
225     GST_ERROR ("invalid compression algorithm %d", algo);
226     ret = FALSE;
227   }
228
229 out:
230
231   if (!ret) {
232     *data_out = NULL;
233     *size_out = 0;
234   } else {
235     *data_out = new_data;
236     *size_out = new_size;
237   }
238
239   return ret;
240 }
241
242 GstFlowReturn
243 gst_matroska_decode_content_encodings (GArray * encodings)
244 {
245   gint i;
246
247   if (encodings == NULL)
248     return GST_FLOW_OK;
249
250   for (i = 0; i < encodings->len; i++) {
251     GstMatroskaTrackEncoding *enc =
252         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
253     gpointer data = NULL;
254     gsize size;
255
256     if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
257         == 0)
258       continue;
259
260     /* Encryption not supported yet */
261     if (enc->type != 0)
262       return GST_FLOW_ERROR;
263
264     if (i + 1 >= encodings->len)
265       return GST_FLOW_ERROR;
266
267     if (enc->comp_settings_length == 0)
268       continue;
269
270     data = enc->comp_settings;
271     size = enc->comp_settings_length;
272
273     if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
274       return GST_FLOW_ERROR;
275
276     g_free (enc->comp_settings);
277
278     enc->comp_settings = data;
279     enc->comp_settings_length = size;
280   }
281
282   return GST_FLOW_OK;
283 }
284
285 gboolean
286 gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
287     gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
288 {
289   gpointer data;
290   gsize size;
291   gboolean ret = TRUE;
292   gint i;
293
294   g_return_val_if_fail (encodings != NULL, FALSE);
295   g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
296   g_return_val_if_fail (size_out != NULL, FALSE);
297
298   data = *data_out;
299   size = *size_out;
300
301   for (i = 0; i < encodings->len; i++) {
302     GstMatroskaTrackEncoding *enc =
303         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
304     gpointer new_data = NULL;
305     gsize new_size = 0;
306
307     if ((enc->scope & scope) == 0)
308       continue;
309
310     /* Encryption not supported yet */
311     if (enc->type != 0) {
312       ret = FALSE;
313       break;
314     }
315
316     new_data = data;
317     new_size = size;
318
319     ret =
320         gst_matroska_decompress_data (enc, &new_data, &new_size,
321         enc->comp_algo);
322
323     if (!ret)
324       break;
325
326     if ((data == *data_out && free) || (data != *data_out))
327       g_free (data);
328
329     data = new_data;
330     size = new_size;
331   }
332
333   if (!ret) {
334     if ((data == *data_out && free) || (data != *data_out))
335       g_free (data);
336
337     *data_out = NULL;
338     *size_out = 0;
339   } else {
340     *data_out = data;
341     *size_out = size;
342   }
343
344   return ret;
345 }
346
347 static gint
348 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
349 {
350   if (i1->time < i2->time)
351     return -1;
352   else if (i1->time > i2->time)
353     return 1;
354   else if (i1->block < i2->block)
355     return -1;
356   else if (i1->block > i2->block)
357     return 1;
358   else
359     return 0;
360 }
361
362 gint
363 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
364     gpointer user_data)
365 {
366   if (i1->time < *time)
367     return -1;
368   else if (i1->time > *time)
369     return 1;
370   else
371     return 0;
372 }
373
374 GstMatroskaIndex *
375 gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
376     GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
377     gint * _entry_index, gboolean next)
378 {
379   GstMatroskaIndex *entry = NULL;
380   GArray *index;
381
382   if (!common->index || !common->index->len)
383     return NULL;
384
385   /* find entry just before or at the requested position */
386   if (track && track->index_table)
387     index = track->index_table;
388   else
389     index = common->index;
390
391   entry =
392       gst_util_array_binary_search (index->data, index->len,
393       sizeof (GstMatroskaIndex),
394       (GCompareDataFunc) gst_matroska_index_seek_find,
395       next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, &seek_pos, NULL);
396
397   if (entry == NULL) {
398     if (next) {
399       return NULL;
400     } else {
401       entry = &g_array_index (index, GstMatroskaIndex, 0);
402     }
403   }
404
405   if (_index)
406     *_index = index;
407   if (_entry_index)
408     *_entry_index = entry - (GstMatroskaIndex *) index->data;
409
410   return entry;
411 }
412
413 static gint
414 gst_matroska_read_common_encoding_cmp (GstMatroskaTrackEncoding * a,
415     GstMatroskaTrackEncoding * b)
416 {
417   if (b->order > a->order)
418     return 1;
419   else if (b->order < a->order)
420     return -1;
421   else
422     return 0;
423 }
424
425 static gboolean
426 gst_matroska_read_common_encoding_order_unique (GArray * encodings, guint64
427     order)
428 {
429   gint i;
430
431   if (encodings == NULL || encodings->len == 0)
432     return TRUE;
433
434   for (i = 0; i < encodings->len; i++)
435     if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
436       return FALSE;
437
438   return TRUE;
439 }
440
441 /* takes ownership of taglist */
442 void
443 gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
444     GstElement * el, GstTagList * taglist)
445 {
446   if (common->global_tags) {
447     /* nothing sent yet, add to cache */
448     gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
449     gst_tag_list_unref (taglist);
450   } else {
451     GstEvent *tag_event = gst_event_new_tag (taglist);
452     gint i;
453
454     /* hm, already sent, no need to cache and wait anymore */
455     GST_DEBUG_OBJECT (common, "Sending late global tags %" GST_PTR_FORMAT,
456         taglist);
457
458     for (i = 0; i < common->src->len; i++) {
459       GstMatroskaTrackContext *stream;
460
461       stream = g_ptr_array_index (common->src, i);
462       gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
463     }
464
465     gst_event_unref (tag_event);
466   }
467 }
468
469 gint64
470 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
471 {
472   gint64 end = -1;
473
474   if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
475           &end) || end < 0)
476     GST_DEBUG_OBJECT (common, "no upstream length");
477
478   return end;
479 }
480
481 /* determine track to seek in */
482 GstMatroskaTrackContext *
483 gst_matroska_read_common_get_seek_track (GstMatroskaReadCommon * common,
484     GstMatroskaTrackContext * track)
485 {
486   gint i;
487
488   if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
489     return track;
490
491   for (i = 0; i < common->src->len; i++) {
492     GstMatroskaTrackContext *stream;
493
494     stream = g_ptr_array_index (common->src, i);
495     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
496       track = stream;
497   }
498
499   return track;
500 }
501
502 /* skip unknown or alike element */
503 GstFlowReturn
504 gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common,
505     GstEbmlRead * ebml, const gchar * parent_name, guint id)
506 {
507   if (id == GST_EBML_ID_VOID) {
508     GST_DEBUG_OBJECT (common, "Skipping EBML Void element");
509   } else if (id == GST_EBML_ID_CRC32) {
510     GST_DEBUG_OBJECT (common, "Skipping EBML CRC32 element");
511   } else {
512     GST_WARNING_OBJECT (common,
513         "Unknown %s subelement 0x%x - ignoring", parent_name, id);
514   }
515
516   return gst_ebml_read_skip (ebml);
517 }
518
519 static GstFlowReturn
520 gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common,
521     GstEbmlRead * ebml, GstTagList * taglist)
522 {
523   guint32 id;
524   GstFlowReturn ret;
525   gchar *description = NULL;
526   gchar *filename = NULL;
527   gchar *mimetype = NULL;
528   guint8 *data = NULL;
529   guint64 datalen = 0;
530
531   DEBUG_ELEMENT_START (common, ebml, "AttachedFile");
532
533   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
534     DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
535     return ret;
536   }
537
538   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
539     /* read all sub-entries */
540
541     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
542       break;
543
544     switch (id) {
545       case GST_MATROSKA_ID_FILEDESCRIPTION:
546         if (description) {
547           GST_WARNING_OBJECT (common, "FileDescription can only appear once");
548           break;
549         }
550
551         ret = gst_ebml_read_utf8 (ebml, &id, &description);
552         GST_DEBUG_OBJECT (common, "FileDescription: %s",
553             GST_STR_NULL (description));
554         break;
555       case GST_MATROSKA_ID_FILENAME:
556         if (filename) {
557           GST_WARNING_OBJECT (common, "FileName can only appear once");
558           break;
559         }
560
561         ret = gst_ebml_read_utf8 (ebml, &id, &filename);
562
563         GST_DEBUG_OBJECT (common, "FileName: %s", GST_STR_NULL (filename));
564         break;
565       case GST_MATROSKA_ID_FILEMIMETYPE:
566         if (mimetype) {
567           GST_WARNING_OBJECT (common, "FileMimeType can only appear once");
568           break;
569         }
570
571         ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
572         GST_DEBUG_OBJECT (common, "FileMimeType: %s", GST_STR_NULL (mimetype));
573         break;
574       case GST_MATROSKA_ID_FILEDATA:
575         if (data) {
576           GST_WARNING_OBJECT (common, "FileData can only appear once");
577           break;
578         }
579
580         ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
581         GST_DEBUG_OBJECT (common, "FileData of size %" G_GUINT64_FORMAT,
582             datalen);
583         break;
584
585       default:
586         ret = gst_matroska_read_common_parse_skip (common, ebml,
587             "AttachedFile", id);
588         break;
589       case GST_MATROSKA_ID_FILEUID:
590         ret = gst_ebml_read_skip (ebml);
591         break;
592     }
593   }
594
595   DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret);
596
597   if (filename && mimetype && data && datalen > 0) {
598     GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
599     GstBuffer *tagbuffer = NULL;
600     GstSample *tagsample = NULL;
601     GstStructure *info = NULL;
602     GstCaps *caps = NULL;
603     gchar *filename_lc = g_utf8_strdown (filename, -1);
604
605     GST_DEBUG_OBJECT (common, "Creating tag for attachment with "
606         "filename '%s', mimetype '%s', description '%s', "
607         "size %" G_GUINT64_FORMAT, filename, mimetype,
608         GST_STR_NULL (description), datalen);
609
610     /* TODO: better heuristics for different image types */
611     if (strstr (filename_lc, "cover")) {
612       if (strstr (filename_lc, "back"))
613         image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
614       else
615         image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
616     } else if (g_str_has_prefix (mimetype, "image/") ||
617         g_str_has_suffix (filename_lc, "png") ||
618         g_str_has_suffix (filename_lc, "jpg") ||
619         g_str_has_suffix (filename_lc, "jpeg") ||
620         g_str_has_suffix (filename_lc, "gif") ||
621         g_str_has_suffix (filename_lc, "bmp")) {
622       image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
623     }
624     g_free (filename_lc);
625
626     /* First try to create an image tag buffer from this */
627     if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
628       tagsample =
629           gst_tag_image_data_to_image_sample (data, datalen, image_type);
630
631       if (!tagsample)
632         image_type = GST_TAG_IMAGE_TYPE_NONE;
633       else {
634         data = NULL;
635         tagbuffer = gst_buffer_ref (gst_sample_get_buffer (tagsample));
636         caps = gst_caps_ref (gst_sample_get_caps (tagsample));
637         info = gst_structure_copy (gst_sample_get_info (tagsample));
638         gst_sample_unref (tagsample);
639       }
640     }
641
642     /* if this failed create an attachment buffer */
643     if (!tagbuffer) {
644       tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);
645
646       caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
647       if (caps == NULL)
648         caps = gst_caps_new_empty_simple (mimetype);
649     }
650
651     /* Set filename and description in the info */
652     if (info == NULL)
653       info = gst_structure_new_empty ("GstTagImageInfo");
654
655     gst_structure_set (info, "filename", G_TYPE_STRING, filename, NULL);
656     if (description)
657       gst_structure_set (info, "description", G_TYPE_STRING, description, NULL);
658
659     tagsample = gst_sample_new (tagbuffer, caps, NULL, info);
660
661     GST_DEBUG_OBJECT (common,
662         "Created attachment sample: %" GST_PTR_FORMAT, tagsample);
663
664     /* and append to the tag list */
665     if (image_type != GST_TAG_IMAGE_TYPE_NONE)
666       gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagsample,
667           NULL);
668     else
669       gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
670           tagsample, NULL);
671
672     /* the list adds it own ref */
673     gst_sample_unref (tagsample);
674   }
675
676   g_free (filename);
677   g_free (mimetype);
678   g_free (data);
679   g_free (description);
680
681   return ret;
682 }
683
684 GstFlowReturn
685 gst_matroska_read_common_parse_attachments (GstMatroskaReadCommon * common,
686     GstElement * el, GstEbmlRead * ebml)
687 {
688   guint32 id;
689   GstFlowReturn ret = GST_FLOW_OK;
690   GstTagList *taglist;
691
692   DEBUG_ELEMENT_START (common, ebml, "Attachments");
693
694   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
695     DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
696     return ret;
697   }
698
699   taglist = gst_tag_list_new_empty ();
700   gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
701
702   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
703     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
704       break;
705
706     switch (id) {
707       case GST_MATROSKA_ID_ATTACHEDFILE:
708         ret = gst_matroska_read_common_parse_attached_file (common, ebml,
709             taglist);
710         break;
711
712       default:
713         ret = gst_matroska_read_common_parse_skip (common, ebml,
714             "Attachments", id);
715         break;
716     }
717   }
718   DEBUG_ELEMENT_STOP (common, ebml, "Attachments", ret);
719
720   if (gst_tag_list_n_tags (taglist) > 0) {
721     GST_DEBUG_OBJECT (common, "Storing attachment tags");
722     gst_matroska_read_common_found_global_tag (common, el, taglist);
723   } else {
724     GST_DEBUG_OBJECT (common, "No valid attachments found");
725     gst_tag_list_unref (taglist);
726   }
727
728   common->attachments_parsed = TRUE;
729
730   return ret;
731 }
732
733 static void
734 gst_matroska_read_common_parse_toc_tag (GstTocEntry * entry,
735     GArray * edition_targets, GArray * chapter_targtes, GstTagList * tags)
736 {
737   gchar *uid;
738   guint i;
739   guint64 tgt;
740   GArray *targets;
741   GList *cur;
742   GstTagList *etags;
743
744   targets =
745       (gst_toc_entry_get_entry_type (entry) ==
746       GST_TOC_ENTRY_TYPE_EDITION) ? edition_targets : chapter_targtes;
747
748   etags = gst_tag_list_new_empty ();
749
750   for (i = 0; i < targets->len; ++i) {
751     tgt = g_array_index (targets, guint64, i);
752
753     if (tgt == 0)
754       gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
755     else {
756       uid = g_strdup_printf ("%" G_GUINT64_FORMAT, tgt);
757       if (g_strcmp0 (gst_toc_entry_get_uid (entry), uid) == 0)
758         gst_tag_list_insert (etags, tags, GST_TAG_MERGE_APPEND);
759       g_free (uid);
760     }
761   }
762
763   gst_toc_entry_merge_tags (entry, etags, GST_TAG_MERGE_APPEND);
764
765   cur = gst_toc_entry_get_sub_entries (entry);
766   while (cur != NULL) {
767     gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets,
768         chapter_targtes, tags);
769     cur = cur->next;
770   }
771 }
772
773 static GstFlowReturn
774 gst_matroska_read_common_parse_metadata_targets (GstMatroskaReadCommon * common,
775     GstEbmlRead * ebml, GArray * edition_targets, GArray * chapter_targets,
776     GArray * track_targets, guint64 * target_type_value, gchar ** target_type)
777 {
778   GstFlowReturn ret = GST_FLOW_OK;
779   guint32 id;
780   guint64 uid;
781   guint64 tmp;
782   gchar *str;
783
784   DEBUG_ELEMENT_START (common, ebml, "TagTargets");
785
786   *target_type_value = 50;
787   *target_type = NULL;
788
789   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
790     DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
791     return ret;
792   }
793
794   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
795     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
796       break;
797
798     switch (id) {
799       case GST_MATROSKA_ID_TARGETCHAPTERUID:
800         if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
801           g_array_append_val (chapter_targets, uid);
802         break;
803
804       case GST_MATROSKA_ID_TARGETEDITIONUID:
805         if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
806           g_array_append_val (edition_targets, uid);
807         break;
808
809       case GST_MATROSKA_ID_TARGETTRACKUID:
810         if ((ret = gst_ebml_read_uint (ebml, &id, &uid)) == GST_FLOW_OK)
811           g_array_append_val (track_targets, uid);
812         break;
813
814       case GST_MATROSKA_ID_TARGETTYPEVALUE:
815         if ((ret = gst_ebml_read_uint (ebml, &id, &tmp)) == GST_FLOW_OK)
816           *target_type_value = tmp;
817         break;
818
819       case GST_MATROSKA_ID_TARGETTYPE:
820         if ((ret = gst_ebml_read_ascii (ebml, &id, &str)) == GST_FLOW_OK) {
821           if (*target_type != NULL)
822             g_free (*target_type);
823           *target_type = str;
824         }
825         break;
826
827       default:
828         ret =
829             gst_matroska_read_common_parse_skip (common, ebml, "TagTargets",
830             id);
831         break;
832     }
833   }
834
835   DEBUG_ELEMENT_STOP (common, ebml, "TagTargets", ret);
836
837   return ret;
838 }
839
840 static void
841 gst_matroska_read_common_postprocess_toc_entries (GList * toc_entries,
842     guint64 max, const gchar * parent_uid)
843 {
844   GstTocEntry *cur_info, *prev_info, *next_info;
845   GList *cur_list, *prev_list, *next_list;
846   gint64 cur_start, prev_start, stop;
847
848   cur_list = toc_entries;
849   while (cur_list != NULL) {
850     cur_info = cur_list->data;
851
852     switch (gst_toc_entry_get_entry_type (cur_info)) {
853       case GST_TOC_ENTRY_TYPE_ANGLE:
854       case GST_TOC_ENTRY_TYPE_VERSION:
855       case GST_TOC_ENTRY_TYPE_EDITION:
856         /* in Matroska terms edition has duration of full track */
857         gst_toc_entry_set_start_stop_times (cur_info, 0, max);
858
859         gst_matroska_read_common_postprocess_toc_entries
860             (gst_toc_entry_get_sub_entries (cur_info), max,
861             gst_toc_entry_get_uid (cur_info));
862         break;
863
864       case GST_TOC_ENTRY_TYPE_TITLE:
865       case GST_TOC_ENTRY_TYPE_TRACK:
866       case GST_TOC_ENTRY_TYPE_CHAPTER:
867         prev_list = cur_list->prev;
868         next_list = cur_list->next;
869
870         if (prev_list != NULL)
871           prev_info = prev_list->data;
872         else
873           prev_info = NULL;
874
875         if (next_list != NULL)
876           next_info = next_list->data;
877         else
878           next_info = NULL;
879
880         /* updated stop time in previous chapter and it's subchapters */
881         if (prev_info != NULL) {
882           gst_toc_entry_get_start_stop_times (prev_info, &prev_start, &stop);
883           gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);
884
885           stop = cur_start;
886           gst_toc_entry_set_start_stop_times (prev_info, prev_start, stop);
887
888           gst_matroska_read_common_postprocess_toc_entries
889               (gst_toc_entry_get_sub_entries (prev_info), cur_start,
890               gst_toc_entry_get_uid (prev_info));
891         }
892
893         /* updated stop time in current chapter and it's subchapters */
894         if (next_info == NULL) {
895           gst_toc_entry_get_start_stop_times (cur_info, &cur_start, &stop);
896
897           if (stop == -1) {
898             stop = max;
899             gst_toc_entry_set_start_stop_times (cur_info, cur_start, stop);
900           }
901
902           gst_matroska_read_common_postprocess_toc_entries
903               (gst_toc_entry_get_sub_entries (cur_info), stop,
904               gst_toc_entry_get_uid (cur_info));
905         }
906         break;
907       case GST_TOC_ENTRY_TYPE_INVALID:
908         break;
909     }
910     cur_list = cur_list->next;
911   }
912 }
913
914 static GstFlowReturn
915 gst_matroska_read_common_parse_chapter_titles (GstMatroskaReadCommon * common,
916     GstEbmlRead * ebml, GstTagList * titles)
917 {
918   guint32 id;
919   gchar *title = NULL;
920   GstFlowReturn ret = GST_FLOW_OK;
921
922   DEBUG_ELEMENT_START (common, ebml, "ChaptersTitles");
923
924
925   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
926     DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
927     return ret;
928   }
929
930   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
931     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
932       break;
933
934     switch (id) {
935       case GST_MATROSKA_ID_CHAPSTRING:
936         ret = gst_ebml_read_utf8 (ebml, &id, &title);
937         break;
938
939       default:
940         ret =
941             gst_matroska_read_common_parse_skip (common, ebml, "ChaptersTitles",
942             id);
943         break;
944     }
945   }
946
947   DEBUG_ELEMENT_STOP (common, ebml, "ChaptersTitles", ret);
948
949   if (title != NULL && ret == GST_FLOW_OK)
950     gst_tag_list_add (titles, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, title, NULL);
951
952   g_free (title);
953   return ret;
954 }
955
956 static GstFlowReturn
957 gst_matroska_read_common_parse_chapter_element (GstMatroskaReadCommon * common,
958     GstEbmlRead * ebml, GList ** subentries)
959 {
960   guint32 id;
961   guint64 start_time = -1, stop_time = -1;
962   guint64 is_hidden = 0, is_enabled = 1, uid = 0;
963   GstFlowReturn ret = GST_FLOW_OK;
964   GstTocEntry *chapter_info;
965   GstTagList *tags;
966   gchar *uid_str;
967   GList *subsubentries = NULL, *l;
968
969   DEBUG_ELEMENT_START (common, ebml, "ChaptersElement");
970
971   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
972     DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
973     return ret;
974   }
975
976   tags = gst_tag_list_new_empty ();
977
978   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
979     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
980       break;
981
982     switch (id) {
983       case GST_MATROSKA_ID_CHAPTERUID:
984         ret = gst_ebml_read_uint (ebml, &id, &uid);
985         break;
986
987       case GST_MATROSKA_ID_CHAPTERTIMESTART:
988         ret = gst_ebml_read_uint (ebml, &id, &start_time);
989         break;
990
991       case GST_MATROSKA_ID_CHAPTERTIMESTOP:
992         ret = gst_ebml_read_uint (ebml, &id, &stop_time);
993         break;
994
995       case GST_MATROSKA_ID_CHAPTERATOM:
996         ret =
997             gst_matroska_read_common_parse_chapter_element (common, ebml,
998             &subsubentries);
999         break;
1000
1001       case GST_MATROSKA_ID_CHAPTERDISPLAY:
1002         ret =
1003             gst_matroska_read_common_parse_chapter_titles (common, ebml, tags);
1004         break;
1005
1006       case GST_MATROSKA_ID_CHAPTERFLAGHIDDEN:
1007         ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1008         break;
1009
1010       case GST_MATROSKA_ID_CHAPTERFLAGENABLED:
1011         ret = gst_ebml_read_uint (ebml, &id, &is_enabled);
1012         break;
1013
1014       default:
1015         ret =
1016             gst_matroska_read_common_parse_skip (common, ebml,
1017             "ChaptersElement", id);
1018         break;
1019     }
1020   }
1021
1022   if (uid == 0)
1023     uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
1024   uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1025   chapter_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid_str);
1026   g_free (uid_str);
1027
1028   gst_toc_entry_set_tags (chapter_info, tags);
1029   gst_toc_entry_set_start_stop_times (chapter_info, start_time, stop_time);
1030
1031   for (l = subsubentries; l; l = l->next)
1032     gst_toc_entry_append_sub_entry (chapter_info, l->data);
1033   g_list_free (subsubentries);
1034
1035   DEBUG_ELEMENT_STOP (common, ebml, "ChaptersElement", ret);
1036
1037   /* start time is mandatory and has no default value,
1038    * so we should skip chapters without it */
1039   if (is_hidden == 0 && is_enabled > 0 &&
1040       start_time != -1 && ret == GST_FLOW_OK) {
1041     *subentries = g_list_append (*subentries, chapter_info);
1042   } else
1043     gst_toc_entry_unref (chapter_info);
1044
1045   return ret;
1046 }
1047
1048 static GstFlowReturn
1049 gst_matroska_read_common_parse_chapter_edition (GstMatroskaReadCommon * common,
1050     GstEbmlRead * ebml, GstToc * toc)
1051 {
1052   guint32 id;
1053   guint64 is_hidden = 0, uid = 0;
1054   GstFlowReturn ret = GST_FLOW_OK;
1055   GstTocEntry *edition_info;
1056   GList *subentries = NULL, *l;
1057   gchar *uid_str;
1058
1059   DEBUG_ELEMENT_START (common, ebml, "ChaptersEdition");
1060
1061   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1062     DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1063     return ret;
1064   }
1065
1066   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1067     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1068       break;
1069
1070     switch (id) {
1071       case GST_MATROSKA_ID_EDITIONUID:
1072         ret = gst_ebml_read_uint (ebml, &id, &uid);
1073         break;
1074
1075       case GST_MATROSKA_ID_CHAPTERATOM:
1076         ret =
1077             gst_matroska_read_common_parse_chapter_element (common, ebml,
1078             &subentries);
1079         break;
1080
1081       case GST_MATROSKA_ID_EDITIONFLAGHIDDEN:
1082         ret = gst_ebml_read_uint (ebml, &id, &is_hidden);
1083         break;
1084
1085       default:
1086         ret =
1087             gst_matroska_read_common_parse_skip (common, ebml,
1088             "ChaptersEdition", id);
1089         break;
1090     }
1091   }
1092
1093   DEBUG_ELEMENT_STOP (common, ebml, "ChaptersEdition", ret);
1094
1095   if (uid == 0)
1096     uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
1097   uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
1098   edition_info = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, uid_str);
1099   gst_toc_entry_set_start_stop_times (edition_info, -1, -1);
1100   g_free (uid_str);
1101
1102   for (l = subentries; l; l = l->next)
1103     gst_toc_entry_append_sub_entry (edition_info, l->data);
1104
1105   if (is_hidden == 0 && subentries != NULL && ret == GST_FLOW_OK)
1106     gst_toc_append_entry (toc, edition_info);
1107   else {
1108     GST_DEBUG_OBJECT (common,
1109         "Skipping empty or hidden edition in the chapters TOC");
1110     gst_toc_entry_unref (edition_info);
1111   }
1112
1113   return ret;
1114 }
1115
1116 GstFlowReturn
1117 gst_matroska_read_common_parse_chapters (GstMatroskaReadCommon * common,
1118     GstEbmlRead * ebml)
1119 {
1120   guint32 id;
1121   GstFlowReturn ret = GST_FLOW_OK;
1122   GstToc *toc;
1123
1124   DEBUG_ELEMENT_START (common, ebml, "Chapters");
1125
1126   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1127     DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1128     return ret;
1129   }
1130
1131   /* FIXME: create CURRENT toc as well */
1132   toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1133
1134   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1135     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1136       break;
1137
1138     switch (id) {
1139       case GST_MATROSKA_ID_EDITIONENTRY:
1140         ret =
1141             gst_matroska_read_common_parse_chapter_edition (common, ebml, toc);
1142         break;
1143
1144       default:
1145         ret =
1146             gst_matroska_read_common_parse_skip (common, ebml, "Chapters", id);
1147         break;
1148     }
1149   }
1150
1151   if (gst_toc_get_entries (toc) != NULL) {
1152     gst_matroska_read_common_postprocess_toc_entries (gst_toc_get_entries (toc),
1153         common->segment.duration, "");
1154
1155     common->toc = toc;
1156   } else
1157     gst_toc_unref (toc);
1158
1159   common->chapters_parsed = TRUE;
1160
1161   DEBUG_ELEMENT_STOP (common, ebml, "Chapters", ret);
1162   return ret;
1163 }
1164
1165 GstFlowReturn
1166 gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common,
1167     GstEbmlRead * ebml)
1168 {
1169   GstFlowReturn ret;
1170   gchar *doctype;
1171   guint version;
1172   guint32 id;
1173
1174   /* this function is the first to be called */
1175
1176   /* default init */
1177   doctype = NULL;
1178   version = 1;
1179
1180   ret = gst_ebml_peek_id (ebml, &id);
1181   if (ret != GST_FLOW_OK)
1182     return ret;
1183
1184   GST_DEBUG_OBJECT (common, "id: %08x", id);
1185
1186   if (id != GST_EBML_ID_HEADER) {
1187     GST_ERROR_OBJECT (common, "Failed to read header");
1188     goto exit;
1189   }
1190
1191   ret = gst_ebml_read_master (ebml, &id);
1192   if (ret != GST_FLOW_OK)
1193     return ret;
1194
1195   while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1196     ret = gst_ebml_peek_id (ebml, &id);
1197     if (ret != GST_FLOW_OK)
1198       return ret;
1199
1200     switch (id) {
1201         /* is our read version uptodate? */
1202       case GST_EBML_ID_EBMLREADVERSION:{
1203         guint64 num;
1204
1205         ret = gst_ebml_read_uint (ebml, &id, &num);
1206         if (ret != GST_FLOW_OK)
1207           return ret;
1208         if (num != GST_EBML_VERSION) {
1209           GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
1210               num);
1211           return GST_FLOW_ERROR;
1212         }
1213
1214         GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1215         break;
1216       }
1217
1218         /* we only handle 8 byte lengths at max */
1219       case GST_EBML_ID_EBMLMAXSIZELENGTH:{
1220         guint64 num;
1221
1222         ret = gst_ebml_read_uint (ebml, &id, &num);
1223         if (ret != GST_FLOW_OK)
1224           return ret;
1225         if (num > sizeof (guint64)) {
1226           GST_ERROR_OBJECT (ebml,
1227               "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
1228           return GST_FLOW_ERROR;
1229         }
1230         GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
1231         break;
1232       }
1233
1234         /* we handle 4 byte IDs at max */
1235       case GST_EBML_ID_EBMLMAXIDLENGTH:{
1236         guint64 num;
1237
1238         ret = gst_ebml_read_uint (ebml, &id, &num);
1239         if (ret != GST_FLOW_OK)
1240           return ret;
1241         if (num > sizeof (guint32)) {
1242           GST_ERROR_OBJECT (ebml,
1243               "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
1244           return GST_FLOW_ERROR;
1245         }
1246         GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
1247         break;
1248       }
1249
1250       case GST_EBML_ID_DOCTYPE:{
1251         gchar *text;
1252
1253         ret = gst_ebml_read_ascii (ebml, &id, &text);
1254         if (ret != GST_FLOW_OK)
1255           return ret;
1256
1257         GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
1258
1259         if (doctype)
1260           g_free (doctype);
1261         doctype = text;
1262         break;
1263       }
1264
1265       case GST_EBML_ID_DOCTYPEREADVERSION:{
1266         guint64 num;
1267
1268         ret = gst_ebml_read_uint (ebml, &id, &num);
1269         if (ret != GST_FLOW_OK)
1270           return ret;
1271         version = num;
1272         GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
1273         break;
1274       }
1275
1276       default:
1277         ret = gst_matroska_read_common_parse_skip (common, ebml,
1278             "EBML header", id);
1279         if (ret != GST_FLOW_OK)
1280           return ret;
1281         break;
1282
1283         /* we ignore these two, as they don't tell us anything we care about */
1284       case GST_EBML_ID_EBMLVERSION:
1285       case GST_EBML_ID_DOCTYPEVERSION:
1286         ret = gst_ebml_read_skip (ebml);
1287         if (ret != GST_FLOW_OK)
1288           return ret;
1289         break;
1290     }
1291   }
1292
1293 exit:
1294
1295   if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
1296       (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
1297       (doctype == NULL)) {
1298     if (version <= 2) {
1299       if (doctype) {
1300         GST_INFO_OBJECT (common, "Input is %s version %d", doctype, version);
1301       } else {
1302         GST_WARNING_OBJECT (common, "Input is EBML without doctype, assuming "
1303             "matroska (version %d)", version);
1304       }
1305       ret = GST_FLOW_OK;
1306     } else {
1307       GST_ELEMENT_ERROR (common, STREAM, DEMUX, (NULL),
1308           ("Demuxer version (2) is too old to read %s version %d",
1309               GST_STR_NULL (doctype), version));
1310       ret = GST_FLOW_ERROR;
1311     }
1312     g_free (doctype);
1313   } else {
1314     GST_ELEMENT_ERROR (common, STREAM, WRONG_TYPE, (NULL),
1315         ("Input is not a matroska stream (doctype=%s)", doctype));
1316     ret = GST_FLOW_ERROR;
1317     g_free (doctype);
1318   }
1319
1320   return ret;
1321 }
1322
1323 static GstFlowReturn
1324 gst_matroska_read_common_parse_index_cuetrack (GstMatroskaReadCommon * common,
1325     GstEbmlRead * ebml, guint * nentries)
1326 {
1327   guint32 id;
1328   GstFlowReturn ret;
1329   GstMatroskaIndex idx;
1330
1331   idx.pos = (guint64) - 1;
1332   idx.track = 0;
1333   idx.time = GST_CLOCK_TIME_NONE;
1334   idx.block = 1;
1335
1336   DEBUG_ELEMENT_START (common, ebml, "CueTrackPositions");
1337
1338   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1339     DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1340     return ret;
1341   }
1342
1343   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1344     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1345       break;
1346
1347     switch (id) {
1348         /* track number */
1349       case GST_MATROSKA_ID_CUETRACK:
1350       {
1351         guint64 num;
1352
1353         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1354           break;
1355
1356         if (num == 0) {
1357           idx.track = 0;
1358           GST_WARNING_OBJECT (common, "Invalid CueTrack 0");
1359           break;
1360         }
1361
1362         GST_DEBUG_OBJECT (common, "CueTrack: %" G_GUINT64_FORMAT, num);
1363         idx.track = num;
1364         break;
1365       }
1366
1367         /* position in file */
1368       case GST_MATROSKA_ID_CUECLUSTERPOSITION:
1369       {
1370         guint64 num;
1371
1372         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1373           break;
1374
1375         if (num > G_MAXINT64) {
1376           GST_WARNING_OBJECT (common, "CueClusterPosition %" G_GUINT64_FORMAT
1377               " too large", num);
1378           break;
1379         }
1380
1381         idx.pos = num;
1382         break;
1383       }
1384
1385         /* number of block in the cluster */
1386       case GST_MATROSKA_ID_CUEBLOCKNUMBER:
1387       {
1388         guint64 num;
1389
1390         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1391           break;
1392
1393         if (num == 0) {
1394           GST_WARNING_OBJECT (common, "Invalid CueBlockNumber 0");
1395           break;
1396         }
1397
1398         GST_DEBUG_OBJECT (common, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
1399         idx.block = num;
1400
1401         /* mild sanity check, disregard strange cases ... */
1402         if (idx.block > G_MAXUINT16) {
1403           GST_DEBUG_OBJECT (common, "... looks suspicious, ignoring");
1404           idx.block = 1;
1405         }
1406         break;
1407       }
1408
1409       default:
1410         ret = gst_matroska_read_common_parse_skip (common, ebml,
1411             "CueTrackPositions", id);
1412         break;
1413
1414       case GST_MATROSKA_ID_CUECODECSTATE:
1415       case GST_MATROSKA_ID_CUEREFERENCE:
1416         ret = gst_ebml_read_skip (ebml);
1417         break;
1418     }
1419   }
1420
1421   DEBUG_ELEMENT_STOP (common, ebml, "CueTrackPositions", ret);
1422
1423   /* (e.g.) lavf typically creates entries without a block number,
1424    * which is bogus and leads to contradictory information */
1425   if (common->index->len) {
1426     GstMatroskaIndex *last_idx;
1427
1428     last_idx = &g_array_index (common->index, GstMatroskaIndex,
1429         common->index->len - 1);
1430     if (last_idx->block == idx.block && last_idx->pos == idx.pos &&
1431         last_idx->track == idx.track && idx.time > last_idx->time) {
1432       GST_DEBUG_OBJECT (common, "Cue entry refers to same location, "
1433           "but has different time than previous entry; discarding");
1434       idx.track = 0;
1435     }
1436   }
1437
1438   if ((ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1439       && idx.pos != (guint64) - 1 && idx.track > 0) {
1440     g_array_append_val (common->index, idx);
1441     (*nentries)++;
1442   } else if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS) {
1443     GST_DEBUG_OBJECT (common, "CueTrackPositions without valid content");
1444   }
1445
1446   return ret;
1447 }
1448
1449 static GstFlowReturn
1450 gst_matroska_read_common_parse_index_pointentry (GstMatroskaReadCommon *
1451     common, GstEbmlRead * ebml)
1452 {
1453   guint32 id;
1454   GstFlowReturn ret;
1455   GstClockTime time = GST_CLOCK_TIME_NONE;
1456   guint nentries = 0;
1457
1458   DEBUG_ELEMENT_START (common, ebml, "CuePoint");
1459
1460   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1461     DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1462     return ret;
1463   }
1464
1465   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1466     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1467       break;
1468
1469     switch (id) {
1470         /* one single index entry ('point') */
1471       case GST_MATROSKA_ID_CUETIME:
1472       {
1473         if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
1474           break;
1475
1476         GST_DEBUG_OBJECT (common, "CueTime: %" G_GUINT64_FORMAT, time);
1477         time = time * common->time_scale;
1478         break;
1479       }
1480
1481         /* position in the file + track to which it belongs */
1482       case GST_MATROSKA_ID_CUETRACKPOSITIONS:
1483       {
1484         if ((ret =
1485                 gst_matroska_read_common_parse_index_cuetrack (common, ebml,
1486                     &nentries)) != GST_FLOW_OK)
1487           break;
1488         break;
1489       }
1490
1491       default:
1492         ret = gst_matroska_read_common_parse_skip (common, ebml, "CuePoint",
1493             id);
1494         break;
1495     }
1496   }
1497
1498   DEBUG_ELEMENT_STOP (common, ebml, "CuePoint", ret);
1499
1500   if (nentries > 0) {
1501     if (time == GST_CLOCK_TIME_NONE) {
1502       GST_WARNING_OBJECT (common, "CuePoint without valid time");
1503       g_array_remove_range (common->index, common->index->len - nentries,
1504           nentries);
1505     } else {
1506       gint i;
1507
1508       for (i = common->index->len - nentries; i < common->index->len; i++) {
1509         GstMatroskaIndex *idx =
1510             &g_array_index (common->index, GstMatroskaIndex, i);
1511
1512         idx->time = time;
1513         GST_DEBUG_OBJECT (common, "Index entry: pos=%" G_GUINT64_FORMAT
1514             ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
1515             GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
1516       }
1517     }
1518   } else {
1519     GST_DEBUG_OBJECT (common, "Empty CuePoint");
1520   }
1521
1522   return ret;
1523 }
1524
1525 gint
1526 gst_matroska_read_common_stream_from_num (GstMatroskaReadCommon * common,
1527     guint track_num)
1528 {
1529   guint n;
1530
1531   g_assert (common->src->len == common->num_streams);
1532   for (n = 0; n < common->src->len; n++) {
1533     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, n);
1534
1535     if (context->num == track_num) {
1536       return n;
1537     }
1538   }
1539
1540   if (n == common->num_streams)
1541     GST_WARNING_OBJECT (common,
1542         "Failed to find corresponding pad for tracknum %d", track_num);
1543
1544   return -1;
1545 }
1546
1547 GstFlowReturn
1548 gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common,
1549     GstEbmlRead * ebml)
1550 {
1551   guint32 id;
1552   GstFlowReturn ret = GST_FLOW_OK;
1553   guint i;
1554
1555   if (common->index)
1556     g_array_free (common->index, TRUE);
1557   common->index =
1558       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1559
1560   DEBUG_ELEMENT_START (common, ebml, "Cues");
1561
1562   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1563     DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1564     return ret;
1565   }
1566
1567   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1568     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1569       break;
1570
1571     switch (id) {
1572         /* one single index entry ('point') */
1573       case GST_MATROSKA_ID_POINTENTRY:
1574         ret = gst_matroska_read_common_parse_index_pointentry (common, ebml);
1575         break;
1576
1577       default:
1578         ret = gst_matroska_read_common_parse_skip (common, ebml, "Cues", id);
1579         break;
1580     }
1581   }
1582   DEBUG_ELEMENT_STOP (common, ebml, "Cues", ret);
1583
1584   /* Sort index by time, smallest time first, for easier searching */
1585   g_array_sort (common->index, (GCompareFunc) gst_matroska_index_compare);
1586
1587   /* Now sort the track specific index entries into their own arrays */
1588   for (i = 0; i < common->index->len; i++) {
1589     GstMatroskaIndex *idx = &g_array_index (common->index, GstMatroskaIndex,
1590         i);
1591     gint track_num;
1592     GstMatroskaTrackContext *ctx;
1593
1594 #if 0
1595     if (common->element_index) {
1596       gint writer_id;
1597
1598       if (idx->track != 0 &&
1599           (track_num =
1600               gst_matroska_read_common_stream_from_num (common,
1601                   idx->track)) != -1) {
1602         ctx = g_ptr_array_index (common->src, track_num);
1603
1604         if (ctx->index_writer_id == -1)
1605           gst_index_get_writer_id (common->element_index,
1606               GST_OBJECT (ctx->pad), &ctx->index_writer_id);
1607         writer_id = ctx->index_writer_id;
1608       } else {
1609         if (common->element_index_writer_id == -1)
1610           gst_index_get_writer_id (common->element_index, GST_OBJECT (common),
1611               &common->element_index_writer_id);
1612         writer_id = common->element_index_writer_id;
1613       }
1614
1615       GST_LOG_OBJECT (common, "adding association %" GST_TIME_FORMAT "-> %"
1616           G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
1617           idx->pos, writer_id);
1618       gst_index_add_association (common->element_index, writer_id,
1619           GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
1620           GST_FORMAT_BYTES, idx->pos + common->ebml_segment_start, NULL);
1621     }
1622 #endif
1623
1624     if (idx->track == 0)
1625       continue;
1626
1627     track_num = gst_matroska_read_common_stream_from_num (common, idx->track);
1628     if (track_num == -1)
1629       continue;
1630
1631     ctx = g_ptr_array_index (common->src, track_num);
1632
1633     if (ctx->index_table == NULL)
1634       ctx->index_table =
1635           g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
1636
1637     g_array_append_vals (ctx->index_table, idx, 1);
1638   }
1639
1640   common->index_parsed = TRUE;
1641
1642   /* sanity check; empty index normalizes to no index */
1643   if (common->index->len == 0) {
1644     g_array_free (common->index, TRUE);
1645     common->index = NULL;
1646   }
1647
1648   return ret;
1649 }
1650
1651 GstFlowReturn
1652 gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common,
1653     GstElement * el, GstEbmlRead * ebml)
1654 {
1655   GstFlowReturn ret = GST_FLOW_OK;
1656   gdouble dur_f = -1.0;
1657   guint32 id;
1658
1659   DEBUG_ELEMENT_START (common, ebml, "SegmentInfo");
1660
1661   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1662     DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1663     return ret;
1664   }
1665
1666   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1667     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1668       break;
1669
1670     switch (id) {
1671         /* cluster timecode */
1672       case GST_MATROSKA_ID_TIMECODESCALE:{
1673         guint64 num;
1674
1675         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1676           break;
1677
1678
1679         GST_DEBUG_OBJECT (common, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
1680         common->time_scale = num;
1681         break;
1682       }
1683
1684       case GST_MATROSKA_ID_DURATION:{
1685         if ((ret = gst_ebml_read_float (ebml, &id, &dur_f)) != GST_FLOW_OK)
1686           break;
1687
1688         if (dur_f <= 0.0) {
1689           GST_WARNING_OBJECT (common, "Invalid duration %lf", dur_f);
1690           break;
1691         }
1692
1693         GST_DEBUG_OBJECT (common, "Duration: %lf", dur_f);
1694         break;
1695       }
1696
1697       case GST_MATROSKA_ID_WRITINGAPP:{
1698         gchar *text;
1699
1700         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1701           break;
1702
1703         GST_DEBUG_OBJECT (common, "WritingApp: %s", GST_STR_NULL (text));
1704         common->writing_app = text;
1705         break;
1706       }
1707
1708       case GST_MATROSKA_ID_MUXINGAPP:{
1709         gchar *text;
1710
1711         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1712           break;
1713
1714         GST_DEBUG_OBJECT (common, "MuxingApp: %s", GST_STR_NULL (text));
1715         common->muxing_app = text;
1716         break;
1717       }
1718
1719       case GST_MATROSKA_ID_DATEUTC:{
1720         gint64 time;
1721
1722         if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
1723           break;
1724
1725         GST_DEBUG_OBJECT (common, "DateUTC: %" G_GINT64_FORMAT, time);
1726         common->created = time;
1727         break;
1728       }
1729
1730       case GST_MATROSKA_ID_TITLE:{
1731         gchar *text;
1732         GstTagList *taglist;
1733
1734         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1735           break;
1736
1737         GST_DEBUG_OBJECT (common, "Title: %s", GST_STR_NULL (text));
1738         taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
1739         gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
1740         gst_matroska_read_common_found_global_tag (common, el, taglist);
1741         g_free (text);
1742         break;
1743       }
1744
1745       default:
1746         ret = gst_matroska_read_common_parse_skip (common, ebml,
1747             "SegmentInfo", id);
1748         break;
1749
1750         /* fall through */
1751       case GST_MATROSKA_ID_SEGMENTUID:
1752       case GST_MATROSKA_ID_SEGMENTFILENAME:
1753       case GST_MATROSKA_ID_PREVUID:
1754       case GST_MATROSKA_ID_PREVFILENAME:
1755       case GST_MATROSKA_ID_NEXTUID:
1756       case GST_MATROSKA_ID_NEXTFILENAME:
1757       case GST_MATROSKA_ID_SEGMENTFAMILY:
1758       case GST_MATROSKA_ID_CHAPTERTRANSLATE:
1759         ret = gst_ebml_read_skip (ebml);
1760         break;
1761     }
1762   }
1763
1764   if (dur_f > 0.0) {
1765     GstClockTime dur_u;
1766
1767     dur_u = gst_gdouble_to_guint64 (dur_f *
1768         gst_guint64_to_gdouble (common->time_scale));
1769     if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
1770       common->segment.duration = dur_u;
1771   }
1772
1773   DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
1774
1775   common->segmentinfo_parsed = TRUE;
1776
1777   return ret;
1778 }
1779
1780 static GstFlowReturn
1781 gst_matroska_read_common_parse_metadata_id_simple_tag (GstMatroskaReadCommon *
1782     common, GstEbmlRead * ebml, GstTagList ** p_taglist, gchar * parent)
1783 {
1784   /* FIXME: check if there are more useful mappings */
1785   static const struct
1786   {
1787     const gchar *matroska_tagname;
1788     const gchar *gstreamer_tagname;
1789   }
1790   tag_conv[] = {
1791     {
1792       /* The following list has the _same_ order as the one in Matroska spec. Please, don't mess it up. */
1793       /* TODO: Nesting information:
1794          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.
1795          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.
1796          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.
1797        */
1798
1799       /* Organizational Information */
1800     GST_MATROSKA_TAG_ID_TOTAL_PARTS, GST_TAG_TRACK_COUNT}, {
1801     GST_MATROSKA_TAG_ID_PART_NUMBER, GST_TAG_TRACK_NUMBER}, {
1802       /* 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) */
1803
1804       /* Titles */
1805     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. */
1806     GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
1807     GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {        /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
1808
1809       /* TODO: Nested Information:
1810          URL URL corresponding to the tag it's included in.
1811          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).
1812          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.
1813          EMAIL Email corresponding to the tag it's included in.
1814          ADDRESS The physical address of the entity. The address should include a country code. It can be useful for a recording label.
1815          FAX The fax number corresponding to the tag it's included in. It can be useful for a recording label.
1816          PHONE The phone number corresponding to the tag it's included in. It can be useful for a recording label.
1817        */
1818
1819       /* Entities */
1820     GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
1821     GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
1822     GST_MATROSKA_TAG_ID_ACCOMPANIMENT, GST_TAG_PERFORMER}, {    /* Band/orchestra/accompaniment/musician. This is akin to the TPE2 tag in ID3. */
1823     GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
1824       /* ARRANGER The person who arranged the piece, e.g., Ravel. */
1825     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. */
1826       /* LYRICIST The person who wrote the lyrics for a musical item. This is akin to the TEXT tag in ID3. */
1827     GST_MATROSKA_TAG_ID_CONDUCTOR, GST_TAG_PERFORMER}, {        /* Conductor/performer refinement. This is akin to the TPE3 tag in ID3. */
1828       /* DIRECTOR This is akin to the IART tag in RIFF. */
1829     GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
1830       /* ASSISTANT_DIRECTOR The name of the assistant director. */
1831       /* DIRECTOR_OF_PHOTOGRAPHY The name of the director of photography, also known as cinematographer. This is akin to the ICNM tag in Extended RIFF. */
1832       /* SOUND_ENGINEER The name of the sound engineer or sound recordist. */
1833       /* ART_DIRECTOR The person who oversees the artists and craftspeople who build the sets. */
1834       /* PRODUCTION_DESIGNER Artist responsible for designing the overall visual appearance of a movie. */
1835       /* CHOREGRAPHER The name of the choregrapher */
1836       /* COSTUME_DESIGNER The name of the costume designer */
1837       /* 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. */
1838       /* 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. */
1839       /* WRITTEN_BY The author of the story or script (used for movies and TV shows). */
1840       /* SCREENPLAY_BY The author of the screenplay or scenario (used for movies and TV shows). */
1841       /* EDITED_BY This is akin to the IEDT tag in Extended RIFF. */
1842       /* PRODUCER Produced by. This is akin to the IPRO tag in Extended RIFF. */
1843       /* COPRODUCER The name of a co-producer. */
1844       /* EXECUTIVE_PRODUCER The name of an executive producer. */
1845       /* DISTRIBUTED_BY This is akin to the IDST tag in Extended RIFF. */
1846       /* MASTERED_BY The engineer who mastered the content for a physical medium or for digital distribution. */
1847     GST_MATROSKA_TAG_ID_ENCODED_BY, GST_TAG_ENCODED_BY}, {      /* This is akin to the TENC tag in ID3. */
1848       /* MIXED_BY DJ mix by the artist specified */
1849       /* REMIXED_BY Interpreted, remixed, or otherwise modified by. This is akin to the TPE4 tag in ID3. */
1850       /* PRODUCTION_STUDIO This is akin to the ISTD tag in Extended RIFF. */
1851       /* THANKS_TO A very general tag for everyone else that wants to be listed. */
1852       /* PUBLISHER This is akin to the TPUB tag in ID3. */
1853       /* LABEL The record label or imprint on the disc. */
1854       /* Search / Classification */
1855     GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}, {
1856       /* 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. */
1857       /* 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. */
1858       /* CONTENT_TYPE The type of the item. e.g. Documentary, Feature Film, Cartoon, Music Video, Music, Sound FX, ... */
1859       /* SUBJECT Describes the topic of the file, such as "Aerial view of Seattle." */
1860     GST_MATROSKA_TAG_ID_DESCRIPTION, GST_TAG_DESCRIPTION}, {    /* A short description of the content, such as "Two birds flying." */
1861     GST_MATROSKA_TAG_ID_KEYWORDS, GST_TAG_KEYWORDS}, {  /* Keywords to the item separated by a comma, used for searching. */
1862       /* SUMMARY A plot outline or a summary of the story. */
1863       /* SYNOPSIS A description of the story line of the item. */
1864       /* INITIAL_KEY The initial key that a musical track starts in. The format is identical to ID3. */
1865       /* PERIOD Describes the period that the piece is from or about. For example, "Renaissance". */
1866       /* 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). */
1867       /* ICRA The ICRA content rating for parental control. (Previously RSACi) */
1868
1869       /* Temporal Information */
1870     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. */
1871     GST_MATROSKA_TAG_ID_DATE_RECORDED, GST_TAG_DATE}, { /* The time that the recording began. This is akin to the TDRC tag in ID3. */
1872     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. */
1873     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. */
1874     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. */
1875     GST_MATROSKA_TAG_ID_DATE_WRITTEN, GST_TAG_DATE}, {  /* The time that the writing of the music/script began. */
1876     GST_MATROSKA_TAG_ID_DATE_PURCHASED, GST_TAG_DATE}, {        /* Information on when the file was purchased (see also purchase tags). */
1877     GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {  /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
1878
1879       /* Spacial Information */
1880     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". */
1881       /* 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". */
1882       /* 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. */
1883
1884       /* Personal */
1885     GST_MATROSKA_TAG_ID_COMMENT, GST_TAG_COMMENT}, {    /* Any comment related to the content. */
1886     GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {   /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
1887       /* PLAY_COUNTER The number of time the item has been played. */
1888       /* 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. */
1889
1890       /* Technical Information */
1891     GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
1892       /* ENCODER_SETTINGS A list of the settings used for encoding this item. No specific format. */
1893     GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
1894     GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {     /* Matroska spec does NOT have this tag! Dunno what it was doing here, probably for compatibility. */
1895       /* 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. */
1896     GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
1897       /* 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. */
1898       /* 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. */
1899       /* 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). */
1900       /* TODO: REPLAYGAIN_PEAK The maximum absolute peak value of the item. This is based on the Replay Gain standard. */
1901
1902       /* Identifiers */
1903     GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
1904       /* 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. */
1905       /* ISBN International Standard Book Number */
1906       /* BARCODE EAN-13 (European Article Numbering) or UPC-A (Universal Product Code) bar code identifier */
1907       /* CATALOG_NUMBER A label-specific string used to identify the release (TIC 01 for example). */
1908       /* 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). */
1909       /* LCCN Library of Congress Control Number */
1910
1911       /* Commercial */
1912       /* PURCHASE_ITEM URL to purchase this file. This is akin to the WPAY tag in ID3. */
1913       /* PURCHASE_INFO Information on where to purchase this album. This is akin to the WCOM tag in ID3. */
1914       /* PURCHASE_OWNER Information on the person who purchased the file. This is akin to the TOWN tag in ID3. */
1915       /* 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". */
1916       /* PURCHASE_CURRENCY The currency type used to pay for the entity. Use ISO-4217 for the 3 letter currency code. */
1917
1918       /* Legal */
1919     GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
1920     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. */
1921     GST_MATROSKA_TAG_ID_LICENSE, GST_TAG_LICENSE}, {    /* The license applied to the content (like Creative Commons variants). */
1922     GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}
1923   };
1924   static const struct
1925   {
1926     const gchar *matroska_tagname;
1927     const gchar *gstreamer_tagname;
1928   }
1929   child_tag_conv[] = {
1930     {
1931     "TITLE/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
1932     "ARTIST/SORT_WITH=", GST_TAG_ARTIST_SORTNAME}, {
1933       /* ALBUM-stuff is handled elsewhere */
1934     "COMPOSER/SORT_WITH=", GST_TAG_TITLE_SORTNAME}, {
1935     "ORIGINAL/URL=", GST_TAG_LOCATION}, {
1936       /* EMAIL, PHONE, FAX all can be mapped to GST_TAG_CONTACT, there is special
1937        * code for that later.
1938        */
1939     "TITLE/URL=", GST_TAG_HOMEPAGE}, {
1940     "ARTIST/URL=", GST_TAG_HOMEPAGE}, {
1941     "COPYRIGHT/URL=", GST_TAG_COPYRIGHT_URI}, {
1942     "LICENSE/URL=", GST_TAG_LICENSE_URI}, {
1943     "LICENSE/URL=", GST_TAG_LICENSE_URI}
1944   };
1945   GstFlowReturn ret;
1946   guint32 id;
1947   gchar *value = NULL;
1948   gchar *tag = NULL;
1949   gchar *name_with_parent = NULL;
1950   GstTagList *child_taglist = NULL;
1951
1952   DEBUG_ELEMENT_START (common, ebml, "SimpleTag");
1953
1954   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1955     DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
1956     return ret;
1957   }
1958
1959   if (parent)
1960     child_taglist = *p_taglist;
1961   else
1962     child_taglist = gst_tag_list_new_empty ();
1963
1964   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1965     /* read all sub-entries */
1966
1967     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1968       break;
1969
1970     switch (id) {
1971       case GST_MATROSKA_ID_TAGNAME:
1972         g_free (tag);
1973         tag = NULL;
1974         ret = gst_ebml_read_ascii (ebml, &id, &tag);
1975         GST_DEBUG_OBJECT (common, "TagName: %s", GST_STR_NULL (tag));
1976         g_free (name_with_parent);
1977         if (parent != NULL)
1978           name_with_parent = g_strdup_printf ("%s/%s", parent, tag);
1979         else
1980           name_with_parent = g_strdup (tag);
1981         break;
1982
1983       case GST_MATROSKA_ID_TAGSTRING:
1984         g_free (value);
1985         value = NULL;
1986         ret = gst_ebml_read_utf8 (ebml, &id, &value);
1987         GST_DEBUG_OBJECT (common, "TagString: %s", GST_STR_NULL (value));
1988         break;
1989
1990       case GST_MATROSKA_ID_SIMPLETAG:
1991         /* Recursive SimpleTag */
1992         /* This implementation requires tag name of _this_ tag to be known
1993          * in order to read its children. It's not in the spec, just the way
1994          * the code is written.
1995          */
1996         if (name_with_parent != NULL) {
1997           ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
1998               ebml, &child_taglist, name_with_parent);
1999           break;
2000         }
2001         /* fall-through */
2002
2003       default:
2004         ret = gst_matroska_read_common_parse_skip (common, ebml, "SimpleTag",
2005             id);
2006         break;
2007
2008       case GST_MATROSKA_ID_TAGLANGUAGE:
2009       case GST_MATROSKA_ID_TAGDEFAULT:
2010       case GST_MATROSKA_ID_TAGBINARY:
2011         ret = gst_ebml_read_skip (ebml);
2012         break;
2013     }
2014   }
2015
2016   DEBUG_ELEMENT_STOP (common, ebml, "SimpleTag", ret);
2017
2018   if (parent && tag && value && *value != '\0') {
2019     /* Don't bother mapping children tags - parent will do that */
2020     gchar *key_val;
2021     /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
2022     key_val = g_strdup_printf ("%s=%s", name_with_parent, value);
2023     gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2024         GST_TAG_EXTENDED_COMMENT, key_val, NULL);
2025   } else if (tag && value && *value != '\0') {
2026     gboolean matched = FALSE;
2027     guint i;
2028
2029     for (i = 0; !matched && i < G_N_ELEMENTS (tag_conv); i++) {
2030       const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
2031
2032       const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
2033
2034       if (strcmp (tagname_mkv, tag) == 0) {
2035         GValue dest = { 0, };
2036         GType dest_type = gst_tag_get_type (tagname_gst);
2037
2038         /* Ensure that any date string is complete */
2039         if (dest_type == G_TYPE_DATE) {
2040           guint year = 1901, month = 1, day = 1;
2041
2042           /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
2043            * the first type */
2044           if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
2045             g_free (value);
2046             value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
2047           }
2048         }
2049
2050         g_value_init (&dest, dest_type);
2051         if (gst_value_deserialize (&dest, value)) {
2052           gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2053               tagname_gst, &dest, NULL);
2054         } else {
2055           GST_WARNING_OBJECT (common, "Can't transform tag '%s' with "
2056               "value '%s' to target type '%s'", tag, value,
2057               g_type_name (dest_type));
2058         }
2059         g_value_unset (&dest);
2060         matched = TRUE;
2061       }
2062     }
2063     if (!matched) {
2064       gchar *key_val;
2065       /* TODO: read LANGUAGE sub-tag, and use "key[lc]=val" form */
2066       key_val = g_strdup_printf ("%s=%s", tag, value);
2067       gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2068           GST_TAG_EXTENDED_COMMENT, key_val, NULL);
2069     }
2070   }
2071
2072   if (!parent) {
2073     /* Map children tags. This only supports top-anchored mapping. That is,
2074      * we start at toplevel tag (this tag), and see how its combinations
2075      * with its children can be mapped. Which means that grandchildren
2076      * are also combined here, with _this_ tag taken into consideration.
2077      * If grandchildren can be combined only with children, that combination
2078      * will not happen.
2079      */
2080     gint child_tags_n = gst_tag_list_n_tags (child_taglist);
2081     if (child_tags_n > 0) {
2082       gint i;
2083       for (i = 0; i < child_tags_n; i++) {
2084         gint j;
2085         const gchar *child_name = gst_tag_list_nth_tag_name (child_taglist, i);
2086         guint taglen = gst_tag_list_get_tag_size (child_taglist, child_name);
2087         for (j = 0; j < taglen; j++) {
2088           gchar *val;
2089           gboolean matched = FALSE;
2090           gchar *val_pre, *val_post;
2091           gint k;
2092
2093           if (!gst_tag_list_get_string_index (child_taglist, child_name,
2094                   j, &val))
2095             continue;
2096           if (!strchr (val, '=')) {
2097             g_free (val);
2098             continue;
2099           }
2100           val_post = g_strdup (strchr (val, '=') + 1);
2101           val_pre = g_strdup (val);
2102           *(strchr (val_pre, '=') + 1) = '\0';
2103
2104           for (k = 0; !matched && k < G_N_ELEMENTS (child_tag_conv); k++) {
2105             const gchar *tagname_gst = child_tag_conv[k].gstreamer_tagname;
2106
2107             const gchar *tagname_mkv = child_tag_conv[k].matroska_tagname;
2108
2109             /* TODO: Once "key[lc]=value" form support is implemented,
2110              * strip [lc] here. It can't be used in combined tags.
2111              * If a tag is not combined, leave [lc] as it is.
2112              */
2113             if (strcmp (tagname_mkv, val_pre) == 0) {
2114               GValue dest = { 0, };
2115               GType dest_type = gst_tag_get_type (tagname_gst);
2116
2117               g_value_init (&dest, dest_type);
2118               if (gst_value_deserialize (&dest, val_post)) {
2119                 gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
2120                     tagname_gst, &dest, NULL);
2121               } else {
2122                 GST_WARNING_OBJECT (common, "Can't transform complex tag '%s' "
2123                     "to target type '%s'", val, g_type_name (dest_type));
2124               }
2125               g_value_unset (&dest);
2126               matched = TRUE;
2127             }
2128           }
2129           if (!matched) {
2130             gchar *last_slash = strrchr (val_pre, '/');
2131             if (last_slash) {
2132               last_slash++;
2133               if (strcmp (last_slash, "EMAIL=") == 0 ||
2134                   strcmp (last_slash, "PHONE=") == 0 ||
2135                   strcmp (last_slash, "ADDRESS=") == 0 ||
2136                   strcmp (last_slash, "FAX=") == 0) {
2137                 gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2138                     GST_TAG_CONTACT, val_post, NULL);
2139                 matched = TRUE;
2140               }
2141             }
2142           }
2143           if (!matched)
2144             gst_tag_list_add (*p_taglist, GST_TAG_MERGE_APPEND,
2145                 GST_TAG_EXTENDED_COMMENT, val, NULL);
2146           g_free (val_post);
2147           g_free (val_pre);
2148           g_free (val);
2149         }
2150       }
2151     }
2152     gst_tag_list_unref (child_taglist);
2153   }
2154
2155   g_free (tag);
2156   g_free (value);
2157   g_free (name_with_parent);
2158
2159   return ret;
2160 }
2161
2162
2163 static void
2164 gst_matroska_read_common_count_streams (GstMatroskaReadCommon * common,
2165     gint * a, gint * v, gint * s)
2166 {
2167   gint i;
2168   gint video_streams = 0, audio_streams = 0, subtitle_streams = 0;
2169
2170   for (i = 0; i < common->src->len; i++) {
2171     GstMatroskaTrackContext *stream;
2172
2173     stream = g_ptr_array_index (common->src, i);
2174     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2175       video_streams += 1;
2176     else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
2177       audio_streams += 1;
2178     else if (stream->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2179       subtitle_streams += 1;
2180   }
2181   *v = video_streams;
2182   *a = audio_streams;
2183   *v = subtitle_streams;
2184 }
2185
2186
2187 static void
2188 gst_matroska_read_common_apply_target_type_foreach (const GstTagList * list,
2189     const gchar * tag, gpointer user_data)
2190 {
2191   guint vallen;
2192   guint i;
2193   TargetTypeContext *ctx = (TargetTypeContext *) user_data;
2194
2195   vallen = gst_tag_list_get_tag_size (list, tag);
2196   if (vallen == 0)
2197     return;
2198
2199   for (i = 0; i < vallen; i++) {
2200     GValue val = { 0 };
2201     const GValue *val_ref;
2202
2203     val_ref = gst_tag_list_get_value_index (list, tag, i);
2204     if (val_ref == NULL)
2205       continue;
2206     g_value_init (&val, G_VALUE_TYPE (val_ref));
2207     g_value_copy (val_ref, &val);
2208
2209     /* TODO: use the optional ctx->target_type somehow */
2210     if (strcmp (tag, GST_TAG_TITLE) == 0) {
2211       if (ctx->target_type_value >= 70 && !ctx->audio_only) {
2212         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2213             GST_TAG_SHOW_NAME, &val);
2214         continue;
2215       } else if (ctx->target_type_value >= 50) {
2216         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2217             GST_TAG_ALBUM, &val);
2218         continue;
2219       }
2220     } else if (strcmp (tag, GST_TAG_TITLE_SORTNAME) == 0) {
2221       if (ctx->target_type_value >= 70 && !ctx->audio_only) {
2222         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2223             GST_TAG_SHOW_SORTNAME, &val);
2224         continue;
2225       } else if (ctx->target_type_value >= 50) {
2226         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2227             GST_TAG_ALBUM_SORTNAME, &val);
2228         continue;
2229       }
2230     } else if (strcmp (tag, GST_TAG_ARTIST) == 0) {
2231       if (ctx->target_type_value >= 50) {
2232         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2233             GST_TAG_ALBUM_ARTIST, &val);
2234         continue;
2235       }
2236     } else if (strcmp (tag, GST_TAG_ARTIST_SORTNAME) == 0) {
2237       if (ctx->target_type_value >= 50) {
2238         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2239             GST_TAG_ALBUM_ARTIST_SORTNAME, &val);
2240         continue;
2241       }
2242     } else if (strcmp (tag, GST_TAG_TRACK_COUNT) == 0) {
2243       if (ctx->target_type_value >= 60) {
2244         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2245             GST_TAG_ALBUM_VOLUME_COUNT, &val);
2246         continue;
2247       }
2248     } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) {
2249       if (ctx->target_type_value >= 60 && !ctx->audio_only) {
2250         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2251             GST_TAG_SHOW_SEASON_NUMBER, &val);
2252         continue;
2253       } else if (ctx->target_type_value >= 50 && !ctx->audio_only) {
2254         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2255             GST_TAG_SHOW_EPISODE_NUMBER, &val);
2256         continue;
2257       } else if (ctx->target_type_value >= 50) {
2258         gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND,
2259             GST_TAG_ALBUM_VOLUME_NUMBER, &val);
2260         continue;
2261       }
2262     }
2263     gst_tag_list_add_value (ctx->result, GST_TAG_MERGE_APPEND, tag, &val);
2264     g_value_unset (&val);
2265   }
2266 }
2267
2268
2269 static GstTagList *
2270 gst_matroska_read_common_apply_target_type (GstMatroskaReadCommon * common,
2271     GstTagList * taglist, guint64 target_type_value, gchar * target_type)
2272 {
2273   TargetTypeContext ctx;
2274   gint a = 0;
2275   gint v = 0;
2276   gint s = 0;
2277
2278   gst_matroska_read_common_count_streams (common, &a, &v, &s);
2279
2280   ctx.audio_only = (a > 0 && v == 0 && s == 0);
2281   ctx.result = gst_tag_list_new_empty ();
2282   ctx.target_type_value = target_type_value;
2283   ctx.target_type = target_type;
2284
2285   gst_tag_list_foreach (taglist,
2286       gst_matroska_read_common_apply_target_type_foreach, &ctx);
2287
2288   gst_tag_list_unref (taglist);
2289   return ctx.result;
2290 }
2291
2292
2293 static GstFlowReturn
2294 gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
2295     GstEbmlRead * ebml, GstTagList ** p_taglist)
2296 {
2297   guint32 id;
2298   GstFlowReturn ret;
2299   GArray *chapter_targets, *edition_targets, *track_targets;
2300   GstTagList *taglist;
2301   GList *cur;
2302   guint64 target_type_value = 50;
2303   gchar *target_type = NULL;
2304
2305   DEBUG_ELEMENT_START (common, ebml, "Tag");
2306
2307   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2308     DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
2309     return ret;
2310   }
2311
2312   edition_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2313   chapter_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2314   track_targets = g_array_new (FALSE, FALSE, sizeof (guint64));
2315   taglist = gst_tag_list_new_empty ();
2316   target_type = NULL;
2317
2318   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2319     /* read all sub-entries */
2320
2321     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2322       break;
2323
2324     switch (id) {
2325       case GST_MATROSKA_ID_SIMPLETAG:
2326         ret = gst_matroska_read_common_parse_metadata_id_simple_tag (common,
2327             ebml, &taglist, NULL);
2328         break;
2329
2330       case GST_MATROSKA_ID_TARGETS:
2331         g_free (target_type);
2332         target_type = NULL;
2333         target_type_value = 50;
2334         ret = gst_matroska_read_common_parse_metadata_targets (common, ebml,
2335             edition_targets, chapter_targets, track_targets,
2336             &target_type_value, &target_type);
2337         break;
2338
2339       default:
2340         ret = gst_matroska_read_common_parse_skip (common, ebml, "Tag", id);
2341         break;
2342     }
2343   }
2344
2345   DEBUG_ELEMENT_STOP (common, ebml, "Tag", ret);
2346
2347   taglist = gst_matroska_read_common_apply_target_type (common, taglist,
2348       target_type_value, target_type);
2349   g_free (target_type);
2350
2351   /* if tag is chapter/edition specific - try to find that entry */
2352   if (G_UNLIKELY (chapter_targets->len > 0 || edition_targets->len > 0 ||
2353           track_targets->len > 0)) {
2354     gint i;
2355     if (chapter_targets->len > 0 || edition_targets->len > 0) {
2356       if (common->toc == NULL)
2357         GST_WARNING_OBJECT (common,
2358             "Found chapter/edition specific tag, but TOC is not present");
2359       else {
2360         cur = gst_toc_get_entries (common->toc);
2361         while (cur != NULL) {
2362           gst_matroska_read_common_parse_toc_tag (cur->data, edition_targets,
2363               chapter_targets, taglist);
2364           cur = cur->next;
2365         }
2366         common->toc_updated = TRUE;
2367       }
2368     }
2369     for (i = 0; i < track_targets->len; i++) {
2370       gint j;
2371       gboolean found = FALSE;
2372       guint64 tgt = g_array_index (track_targets, guint64, i);
2373
2374       for (j = 0; j < common->src->len; j++) {
2375         GstMatroskaTrackContext *stream = g_ptr_array_index (common->src, j);
2376
2377         if (stream->uid == tgt) {
2378           gst_tag_list_insert (stream->pending_tags, taglist,
2379               GST_TAG_MERGE_REPLACE);
2380           found = TRUE;
2381         }
2382       }
2383       if (!found) {
2384         GST_WARNING_OBJECT (common,
2385             "Found track-specific tag(s), but track %" G_GUINT64_FORMAT
2386             " is not known (yet?)", tgt);
2387       }
2388     }
2389   } else
2390     gst_tag_list_insert (*p_taglist, taglist, GST_TAG_MERGE_APPEND);
2391
2392   gst_tag_list_unref (taglist);
2393   g_array_unref (chapter_targets);
2394   g_array_unref (edition_targets);
2395   g_array_unref (track_targets);
2396
2397   return ret;
2398 }
2399
2400 GstFlowReturn
2401 gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon * common,
2402     GstElement * el, GstEbmlRead * ebml)
2403 {
2404   GstTagList *taglist;
2405   GstFlowReturn ret = GST_FLOW_OK;
2406   guint32 id;
2407   GList *l;
2408   guint64 curpos;
2409
2410   curpos = gst_ebml_read_get_pos (ebml);
2411
2412   /* Make sure we don't parse a tags element twice and
2413    * post it's tags twice */
2414   curpos = gst_ebml_read_get_pos (ebml);
2415   for (l = common->tags_parsed; l; l = l->next) {
2416     guint64 *pos = l->data;
2417
2418     if (*pos == curpos) {
2419       GST_DEBUG_OBJECT (common, "Skipping already parsed Tags at offset %"
2420           G_GUINT64_FORMAT, curpos);
2421       return GST_FLOW_OK;
2422     }
2423   }
2424
2425   common->tags_parsed =
2426       g_list_prepend (common->tags_parsed, g_slice_new (guint64));
2427   *((guint64 *) common->tags_parsed->data) = curpos;
2428   /* fall-through */
2429
2430   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2431     DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
2432     return ret;
2433   }
2434
2435   taglist = gst_tag_list_new_empty ();
2436   gst_tag_list_set_scope (taglist, GST_TAG_SCOPE_GLOBAL);
2437   common->toc_updated = FALSE;
2438
2439   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2440     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2441       break;
2442
2443     switch (id) {
2444       case GST_MATROSKA_ID_TAG:
2445         ret = gst_matroska_read_common_parse_metadata_id_tag (common, ebml,
2446             &taglist);
2447         break;
2448
2449       default:
2450         ret = gst_matroska_read_common_parse_skip (common, ebml, "Tags", id);
2451         break;
2452         /* FIXME: Use to limit the tags to specific pads */
2453     }
2454   }
2455
2456   DEBUG_ELEMENT_STOP (common, ebml, "Tags", ret);
2457
2458   if (G_LIKELY (!gst_tag_list_is_empty (taglist)))
2459     gst_matroska_read_common_found_global_tag (common, el, taglist);
2460   else
2461     gst_tag_list_unref (taglist);
2462
2463   return ret;
2464 }
2465
2466 static GstFlowReturn
2467 gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
2468     peek, const guint8 ** data)
2469 {
2470   /* Caller needs to gst_adapter_unmap. */
2471   *data = gst_adapter_map (common->adapter, peek);
2472   if (*data == NULL)
2473     return GST_FLOW_EOS;
2474
2475   return GST_FLOW_OK;
2476 }
2477
2478 /*
2479  * Calls pull_range for (offset,size) without advancing our offset
2480  */
2481 GstFlowReturn
2482 gst_matroska_read_common_peek_bytes (GstMatroskaReadCommon * common, guint64
2483     offset, guint size, GstBuffer ** p_buf, guint8 ** bytes)
2484 {
2485   GstFlowReturn ret;
2486
2487   /* Caching here actually makes much less difference than one would expect.
2488    * We do it mainly to avoid pulling buffers of 1 byte all the time */
2489   if (common->cached_buffer) {
2490     guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
2491     gsize cache_size = gst_buffer_get_size (common->cached_buffer);
2492
2493     if (cache_offset <= common->offset &&
2494         (common->offset + size) <= (cache_offset + cache_size)) {
2495       if (p_buf)
2496         *p_buf = gst_buffer_copy_region (common->cached_buffer,
2497             GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
2498       if (bytes) {
2499         if (!common->cached_data) {
2500           gst_buffer_map (common->cached_buffer, &common->cached_map,
2501               GST_MAP_READ);
2502           common->cached_data = common->cached_map.data;
2503         }
2504         *bytes = common->cached_data + common->offset - cache_offset;
2505       }
2506       return GST_FLOW_OK;
2507     }
2508     /* not enough data in the cache, free cache and get a new one */
2509     if (common->cached_data) {
2510       gst_buffer_unmap (common->cached_buffer, &common->cached_map);
2511       common->cached_data = NULL;
2512     }
2513     gst_buffer_unref (common->cached_buffer);
2514     common->cached_buffer = NULL;
2515   }
2516
2517   /* refill the cache */
2518   ret = gst_pad_pull_range (common->sinkpad, common->offset,
2519       MAX (size, 64 * 1024), &common->cached_buffer);
2520   if (ret != GST_FLOW_OK) {
2521     common->cached_buffer = NULL;
2522     return ret;
2523   }
2524
2525   if (gst_buffer_get_size (common->cached_buffer) >= size) {
2526     if (p_buf)
2527       *p_buf = gst_buffer_copy_region (common->cached_buffer,
2528           GST_BUFFER_COPY_ALL, 0, size);
2529     if (bytes) {
2530       gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2531       common->cached_data = common->cached_map.data;
2532       *bytes = common->cached_data;
2533     }
2534     return GST_FLOW_OK;
2535   }
2536
2537   /* Not possible to get enough data, try a last time with
2538    * requesting exactly the size we need */
2539   gst_buffer_unref (common->cached_buffer);
2540   common->cached_buffer = NULL;
2541
2542   ret =
2543       gst_pad_pull_range (common->sinkpad, common->offset, size,
2544       &common->cached_buffer);
2545   if (ret != GST_FLOW_OK) {
2546     GST_DEBUG_OBJECT (common, "pull_range returned %d", ret);
2547     if (p_buf)
2548       *p_buf = NULL;
2549     if (bytes)
2550       *bytes = NULL;
2551     return ret;
2552   }
2553
2554   if (gst_buffer_get_size (common->cached_buffer) < size) {
2555     GST_WARNING_OBJECT (common, "Dropping short buffer at offset %"
2556         G_GUINT64_FORMAT ": wanted %u bytes, got %" G_GSIZE_FORMAT " bytes",
2557         common->offset, size, gst_buffer_get_size (common->cached_buffer));
2558
2559     gst_buffer_unref (common->cached_buffer);
2560     common->cached_buffer = NULL;
2561     if (p_buf)
2562       *p_buf = NULL;
2563     if (bytes)
2564       *bytes = NULL;
2565     return GST_FLOW_EOS;
2566   }
2567
2568   if (p_buf)
2569     *p_buf = gst_buffer_copy_region (common->cached_buffer,
2570         GST_BUFFER_COPY_ALL, 0, size);
2571   if (bytes) {
2572     gst_buffer_map (common->cached_buffer, &common->cached_map, GST_MAP_READ);
2573     common->cached_data = common->cached_map.data;
2574     *bytes = common->cached_data;
2575   }
2576
2577   return GST_FLOW_OK;
2578 }
2579
2580 static GstFlowReturn
2581 gst_matroska_read_common_peek_pull (GstMatroskaReadCommon * common, guint peek,
2582     guint8 ** data)
2583 {
2584   return gst_matroska_read_common_peek_bytes (common, common->offset, peek,
2585       NULL, data);
2586 }
2587
2588 GstFlowReturn
2589 gst_matroska_read_common_peek_id_length_pull (GstMatroskaReadCommon * common,
2590     GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2591 {
2592   return gst_ebml_peek_id_length (_id, _length, _needed,
2593       (GstPeekData) gst_matroska_read_common_peek_pull, (gpointer) common, el,
2594       common->offset);
2595 }
2596
2597 GstFlowReturn
2598 gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
2599     GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
2600 {
2601   GstFlowReturn ret;
2602
2603   ret = gst_ebml_peek_id_length (_id, _length, _needed,
2604       (GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
2605       el, common->offset);
2606
2607   gst_adapter_unmap (common->adapter);
2608
2609   return ret;
2610 }
2611
2612 static GstFlowReturn
2613 gst_matroska_read_common_read_track_encoding (GstMatroskaReadCommon * common,
2614     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
2615 {
2616   GstMatroskaTrackEncoding enc = { 0, };
2617   GstFlowReturn ret;
2618   guint32 id;
2619
2620   DEBUG_ELEMENT_START (common, ebml, "ContentEncoding");
2621   /* Set default values */
2622   enc.scope = 1;
2623   /* All other default values are 0 */
2624
2625   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2626     DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
2627     return ret;
2628   }
2629
2630   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2631     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2632       break;
2633
2634     switch (id) {
2635       case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
2636         guint64 num;
2637
2638         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2639           break;
2640
2641         if (!gst_matroska_read_common_encoding_order_unique (context->encodings,
2642                 num)) {
2643           GST_ERROR_OBJECT (common, "ContentEncodingOrder %" G_GUINT64_FORMAT
2644               "is not unique for track %" G_GUINT64_FORMAT, num, context->num);
2645           ret = GST_FLOW_ERROR;
2646           break;
2647         }
2648
2649         GST_DEBUG_OBJECT (common, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
2650             num);
2651         enc.order = num;
2652         break;
2653       }
2654       case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
2655         guint64 num;
2656
2657         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2658           break;
2659
2660         if (num > 7 && num == 0) {
2661           GST_ERROR_OBJECT (common, "Invalid ContentEncodingScope %"
2662               G_GUINT64_FORMAT, num);
2663           ret = GST_FLOW_ERROR;
2664           break;
2665         }
2666
2667         GST_DEBUG_OBJECT (common, "ContentEncodingScope: %" G_GUINT64_FORMAT,
2668             num);
2669         enc.scope = num;
2670
2671         break;
2672       }
2673       case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
2674         guint64 num;
2675
2676         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
2677           break;
2678
2679         if (num > 1) {
2680           GST_ERROR_OBJECT (common, "Invalid ContentEncodingType %"
2681               G_GUINT64_FORMAT, num);
2682           ret = GST_FLOW_ERROR;
2683           break;
2684         } else if (num != 0) {
2685           GST_ERROR_OBJECT (common, "Encrypted tracks are not supported yet");
2686           ret = GST_FLOW_ERROR;
2687           break;
2688         }
2689         GST_DEBUG_OBJECT (common, "ContentEncodingType: %" G_GUINT64_FORMAT,
2690             num);
2691         enc.type = num;
2692         break;
2693       }
2694       case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
2695
2696         DEBUG_ELEMENT_START (common, ebml, "ContentCompression");
2697
2698         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
2699           break;
2700
2701         while (ret == GST_FLOW_OK &&
2702             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2703           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2704             break;
2705
2706           switch (id) {
2707             case GST_MATROSKA_ID_CONTENTCOMPALGO:{
2708               guint64 num;
2709
2710               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
2711                 break;
2712               }
2713               if (num > 3) {
2714                 GST_ERROR_OBJECT (common, "Invalid ContentCompAlgo %"
2715                     G_GUINT64_FORMAT, num);
2716                 ret = GST_FLOW_ERROR;
2717                 break;
2718               }
2719               GST_DEBUG_OBJECT (common, "ContentCompAlgo: %" G_GUINT64_FORMAT,
2720                   num);
2721               enc.comp_algo = num;
2722
2723               break;
2724             }
2725             case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
2726               guint8 *data;
2727               guint64 size;
2728
2729               if ((ret =
2730                       gst_ebml_read_binary (ebml, &id, &data,
2731                           &size)) != GST_FLOW_OK) {
2732                 break;
2733               }
2734               enc.comp_settings = data;
2735               enc.comp_settings_length = size;
2736               GST_DEBUG_OBJECT (common,
2737                   "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
2738               break;
2739             }
2740             default:
2741               GST_WARNING_OBJECT (common,
2742                   "Unknown ContentCompression subelement 0x%x - ignoring", id);
2743               ret = gst_ebml_read_skip (ebml);
2744               break;
2745           }
2746         }
2747         DEBUG_ELEMENT_STOP (common, ebml, "ContentCompression", ret);
2748         break;
2749       }
2750
2751       case GST_MATROSKA_ID_CONTENTENCRYPTION:
2752         GST_ERROR_OBJECT (common, "Encrypted tracks not yet supported");
2753         gst_ebml_read_skip (ebml);
2754         ret = GST_FLOW_ERROR;
2755         break;
2756       default:
2757         GST_WARNING_OBJECT (common,
2758             "Unknown ContentEncoding subelement 0x%x - ignoring", id);
2759         ret = gst_ebml_read_skip (ebml);
2760         break;
2761     }
2762   }
2763
2764   DEBUG_ELEMENT_STOP (common, ebml, "ContentEncoding", ret);
2765   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2766     return ret;
2767
2768   /* TODO: Check if the combination of values is valid */
2769
2770   g_array_append_val (context->encodings, enc);
2771
2772   return ret;
2773 }
2774
2775 GstFlowReturn
2776 gst_matroska_read_common_read_track_encodings (GstMatroskaReadCommon * common,
2777     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
2778 {
2779   GstFlowReturn ret;
2780   guint32 id;
2781
2782   DEBUG_ELEMENT_START (common, ebml, "ContentEncodings");
2783
2784   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2785     DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
2786     return ret;
2787   }
2788
2789   context->encodings =
2790       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
2791
2792   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2793     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2794       break;
2795
2796     switch (id) {
2797       case GST_MATROSKA_ID_CONTENTENCODING:
2798         ret = gst_matroska_read_common_read_track_encoding (common, ebml,
2799             context);
2800         break;
2801       default:
2802         GST_WARNING_OBJECT (common,
2803             "Unknown ContentEncodings subelement 0x%x - ignoring", id);
2804         ret = gst_ebml_read_skip (ebml);
2805         break;
2806     }
2807   }
2808
2809   DEBUG_ELEMENT_STOP (common, ebml, "ContentEncodings", ret);
2810   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2811     return ret;
2812
2813   /* Sort encodings according to their order */
2814   g_array_sort (context->encodings,
2815       (GCompareFunc) gst_matroska_read_common_encoding_cmp);
2816
2817   return gst_matroska_decode_content_encodings (context->encodings);
2818 }
2819
2820 /* call with object lock held */
2821 void
2822 gst_matroska_read_common_reset_streams (GstMatroskaReadCommon * common,
2823     GstClockTime time, gboolean full)
2824 {
2825   gint i;
2826
2827   GST_DEBUG_OBJECT (common, "resetting stream state");
2828
2829   g_assert (common->src->len == common->num_streams);
2830   for (i = 0; i < common->src->len; i++) {
2831     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
2832     context->pos = time;
2833     context->set_discont = TRUE;
2834     context->eos = FALSE;
2835     context->from_time = GST_CLOCK_TIME_NONE;
2836     if (full)
2837       context->last_flow = GST_FLOW_OK;
2838     if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2839       GstMatroskaTrackVideoContext *videocontext =
2840           (GstMatroskaTrackVideoContext *) context;
2841       /* demux object lock held by caller */
2842       videocontext->earliest_time = GST_CLOCK_TIME_NONE;
2843     }
2844   }
2845 }
2846
2847 gboolean
2848 gst_matroska_read_common_tracknumber_unique (GstMatroskaReadCommon * common,
2849     guint64 num)
2850 {
2851   gint i;
2852
2853   g_assert (common->src->len == common->num_streams);
2854   for (i = 0; i < common->src->len; i++) {
2855     GstMatroskaTrackContext *context = g_ptr_array_index (common->src, i);
2856
2857     if (context->num == num)
2858       return FALSE;
2859   }
2860
2861   return TRUE;
2862 }